From noreply at buildbot.pypy.org Fri Feb 1 01:47:01 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Fri, 1 Feb 2013 01:47:01 +0100 (CET) Subject: [pypy-commit] pypy default: backout b366d0104c42, breaks many things, apparently not tested Message-ID: <20130201004701.9B2A51C009B@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r60799:b7ad84866494 Date: 2013-01-31 19:46 -0500 http://bitbucket.org/pypy/pypy/changeset/b7ad84866494/ Log: backout b366d0104c42, breaks many things, apparently not tested diff --git a/rpython/translator/c/genc.py b/rpython/translator/c/genc.py --- a/rpython/translator/c/genc.py +++ b/rpython/translator/c/genc.py @@ -761,6 +761,7 @@ srcdir / 'exception.c', srcdir / 'rtyper.c', # ifdef HAVE_RTYPER srcdir / 'support.c', + srcdir / 'profiling.c', srcdir / 'debug_print.c', srcdir / 'debug_traceback.c', # ifdef HAVE_RTYPER srcdir / 'asm.c', From noreply at buildbot.pypy.org Fri Feb 1 02:54:34 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Fri, 1 Feb 2013 02:54:34 +0100 (CET) Subject: [pypy-commit] pypy default: hidden frames are fairly rare, it's ok to unroll this Message-ID: <20130201015434.63E7E1C009B@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r60800:9aeefdb4841d Date: 2013-01-31 17:54 -0800 http://bitbucket.org/pypy/pypy/changeset/9aeefdb4841d/ Log: hidden frames are fairly rare, it's ok to unroll this diff --git a/pypy/interpreter/executioncontext.py b/pypy/interpreter/executioncontext.py --- a/pypy/interpreter/executioncontext.py +++ b/pypy/interpreter/executioncontext.py @@ -40,6 +40,7 @@ def gettopframe(self): return self.topframeref() + @jit.unroll_safe def gettopframe_nohidden(self): frame = self.topframeref() while frame and frame.hide(): From noreply at buildbot.pypy.org Fri Feb 1 02:54:44 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Fri, 1 Feb 2013 02:54:44 +0100 (CET) Subject: [pypy-commit] pypy py3k: merge default Message-ID: <20130201015444.04F401C009B@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r60801:3f146e453ff5 Date: 2013-01-31 17:52 -0800 http://bitbucket.org/pypy/pypy/changeset/3f146e453ff5/ Log: merge default diff --git a/lib-python/2.7/sysconfig.py b/lib-python/2.7/sysconfig.py --- a/lib-python/2.7/sysconfig.py +++ b/lib-python/2.7/sysconfig.py @@ -27,10 +27,10 @@ 'data' : '{base}', }, 'pypy': { - 'stdlib': '{base}/lib-python', - 'platstdlib': '{base}/lib-python', - 'purelib': '{base}/lib-python', - 'platlib': '{base}/lib-python', + 'stdlib': '{base}/lib-python/{py_version_short}', + 'platstdlib': '{base}/lib-python/{py_version_short}', + 'purelib': '{base}/lib-python/{py_version_short}', + 'platlib': '{base}/lib-python/{py_version_short}', 'include': '{base}/include', 'platinclude': '{base}/include', 'scripts': '{base}/bin', diff --git a/lib-python/2.7/test/test_capi.py b/lib-python/2.7/test/test_capi.py --- a/lib-python/2.7/test/test_capi.py +++ b/lib-python/2.7/test/test_capi.py @@ -13,6 +13,17 @@ threading = None import _testcapi +skips = [] +if test_support.check_impl_detail(pypy=True): + skips += [ + 'test_broken_memoryview', + 'test_capsule', + 'test_lazy_hash_inheritance', + 'test_widechar', + 'TestThreadState', + 'TestPendingCalls', + ] + @unittest.skipUnless(threading, 'Threading required for this test.') class TestPendingCalls(unittest.TestCase): @@ -99,7 +110,7 @@ def test_main(): for name in dir(_testcapi): - if name.startswith('test_'): + if name.startswith('test_') and name not in skips: test = getattr(_testcapi, name) if test_support.verbose: print "internal", name @@ -126,7 +137,7 @@ raise test_support.TestFailed, \ "Couldn't find main thread correctly in the list" - if threading: + if threading and 'TestThreadState' not in skips: import thread import time TestThreadState() @@ -134,7 +145,8 @@ t.start() t.join() - test_support.run_unittest(TestPendingCalls) + if 'TestPendingCalls' not in skips: + test_support.run_unittest(TestPendingCalls) if __name__ == "__main__": test_main() diff --git a/lib-python/2.7/test/test_multiprocessing.py b/lib-python/2.7/test/test_multiprocessing.py --- a/lib-python/2.7/test/test_multiprocessing.py +++ b/lib-python/2.7/test/test_multiprocessing.py @@ -1343,7 +1343,7 @@ # Because we are using xmlrpclib for serialization instead of # pickle this will cause a serialization error. - self.assertRaises(Exception, queue.put, time.sleep) + self.assertRaises(Exception, queue.put, object) # Make queue finalizer run before the server is stopped del queue @@ -1800,9 +1800,9 @@ if not gc.isenabled(): gc.enable() self.addCleanup(gc.disable) - thresholds = gc.get_threshold() - self.addCleanup(gc.set_threshold, *thresholds) - gc.set_threshold(10) + #thresholds = gc.get_threshold() + #self.addCleanup(gc.set_threshold, *thresholds) + #gc.set_threshold(10) # perform numerous block allocations, with cyclic references to make # sure objects are collected asynchronously by the gc @@ -1865,6 +1865,7 @@ def test_synchronize(self): self.test_sharedctypes(lock=True) + @unittest.skipUnless(test_support.check_impl_detail(pypy=False), "pypy ctypes differences") def test_copy(self): foo = _Foo(2, 5.0) bar = copy(foo) diff --git a/lib-python/2.7/test/test_zipfile.py b/lib-python/2.7/test/test_zipfile.py --- a/lib-python/2.7/test/test_zipfile.py +++ b/lib-python/2.7/test/test_zipfile.py @@ -1213,6 +1213,17 @@ self.assertEqual(data1, '1'*FIXEDTEST_SIZE) self.assertEqual(data2, '2'*FIXEDTEST_SIZE) + def test_many_opens(self): + # Verify that read() and open() promptly close the file descriptor, + # and don't rely on the garbage collector to free resources. + with zipfile.ZipFile(TESTFN2, mode="r") as zipf: + for x in range(100): + zipf.read('ones') + with zipf.open('ones') as zopen1: + pass + for x in range(10): + self.assertLess(open('/dev/null').fileno(), 100) + def tearDown(self): unlink(TESTFN2) diff --git a/lib-python/2.7/zipfile.py b/lib-python/2.7/zipfile.py --- a/lib-python/2.7/zipfile.py +++ b/lib-python/2.7/zipfile.py @@ -475,9 +475,11 @@ # Search for universal newlines or line chunks. PATTERN = re.compile(r'^(?P[^\r\n]+)|(?P\n|\r\n?)') - def __init__(self, fileobj, mode, zipinfo, decrypter=None): + def __init__(self, fileobj, mode, zipinfo, decrypter=None, + close_fileobj=False): self._fileobj = fileobj self._decrypter = decrypter + self._close_fileobj = close_fileobj self._compress_type = zipinfo.compress_type self._compress_size = zipinfo.compress_size @@ -649,6 +651,12 @@ self._offset += len(data) return data + def close(self): + try: + if self._close_fileobj: + self._fileobj.close() + finally: + super(ZipExtFile, self).close() class ZipFile: @@ -866,7 +874,8 @@ def read(self, name, pwd=None): """Return file bytes (as a string) for name.""" - return self.open(name, "r", pwd).read() + with self.open(name, "r", pwd) as fp: + return fp.read() def open(self, name, mode="r", pwd=None): """Return file-like object for 'name'.""" @@ -889,8 +898,12 @@ zinfo = name else: # Get info object for name - zinfo = self.getinfo(name) - + try: + zinfo = self.getinfo(name) + except KeyError: + if not self._filePassed: + zef_file.close() + raise zef_file.seek(zinfo.header_offset, 0) # Skip the file header: @@ -904,6 +917,8 @@ zef_file.read(fheader[_FH_EXTRA_FIELD_LENGTH]) if fname != zinfo.orig_filename: + if not self._filePassed: + zef_file.close() raise BadZipfile, \ 'File name in directory "%s" and header "%s" differ.' % ( zinfo.orig_filename, fname) @@ -915,6 +930,8 @@ if not pwd: pwd = self.pwd if not pwd: + if not self._filePassed: + zef_file.close() raise RuntimeError, "File %s is encrypted, " \ "password required for extraction" % name @@ -933,9 +950,12 @@ # compare against the CRC otherwise check_byte = (zinfo.CRC >> 24) & 0xff if ord(h[11]) != check_byte: + if not self._filePassed: + zef_file.close() raise RuntimeError("Bad password for file", name) - return ZipExtFile(zef_file, mode, zinfo, zd) + return ZipExtFile(zef_file, mode, zinfo, zd, + close_fileobj=not self._filePassed) def extract(self, member, path=None, pwd=None): """Extract a member from the archive to the current working directory, @@ -993,7 +1013,7 @@ return targetpath source = self.open(member, pwd=pwd) - target = file(targetpath, "wb") + target = open(targetpath, "wb") shutil.copyfileobj(source, target) source.close() target.close() diff --git a/lib-python/conftest.py b/lib-python/conftest.py --- a/lib-python/conftest.py +++ b/lib-python/conftest.py @@ -123,7 +123,7 @@ RegrTest('test_bz2.py', usemodules='bz2'), RegrTest('test_calendar.py'), RegrTest('test_call.py', core=True), - RegrTest('test_capi.py', skip="not applicable"), + RegrTest('test_capi.py'), RegrTest('test_cfgparser.py'), RegrTest('test_cgi.py'), RegrTest('test_charmapcodec.py', core=True), @@ -280,7 +280,7 @@ RegrTest('test_modulefinder.py'), RegrTest('test_msilib.py'), RegrTest('test_multibytecodec.py', usemodules='_multibytecodec'), - RegrTest('test_multiprocessing.py', skip=True), + RegrTest('test_multiprocessing.py'), RegrTest('test_mutants.py', core="possibly"), RegrTest('test_netrc.py'), RegrTest('test_nis.py'), diff --git a/lib_pypy/_ctypes_test.py b/lib_pypy/_ctypes_test.py --- a/lib_pypy/_ctypes_test.py +++ b/lib_pypy/_ctypes_test.py @@ -1,6 +1,5 @@ import os, sys import tempfile -import gc def compile_shared(): """Compile '_ctypes_test.c' into an extension module, and import it @@ -19,7 +18,7 @@ if sys.platform == 'win32': ccflags = ['-D_CRT_SECURE_NO_WARNINGS'] else: - ccflags = ['-fPIC'] + ccflags = ['-fPIC', '-Wimplicit-function-declaration'] res = compiler.compile([os.path.join(thisdir, '_ctypes_test.c')], include_dirs=[include_dir], extra_preargs=ccflags) @@ -35,10 +34,10 @@ library = os.path.join(thisdir, '..', 'include', 'python27') if not os.path.exists(library + '.lib'): # For a local translation - library = os.path.join(thisdir, '..', 'pypy', 'translator', - 'goal', 'libpypy-c') + library = os.path.join(thisdir, '..', 'pypy', 'goal', 'libpypy-c') libraries = [library, 'oleaut32'] - extra_ldargs = ['/MANIFEST'] # needed for VC10 + extra_ldargs = ['/MANIFEST', # needed for VC10 + '/EXPORT:init_ctypes_test'] else: libraries = [] extra_ldargs = [] diff --git a/lib_pypy/_testcapi.py b/lib_pypy/_testcapi.py --- a/lib_pypy/_testcapi.py +++ b/lib_pypy/_testcapi.py @@ -34,8 +34,7 @@ library = os.path.join(thisdir, '..', 'include', 'python27') if not os.path.exists(library + '.lib'): # For a local translation - library = os.path.join(thisdir, '..', 'pypy', 'translator', - 'goal', 'libpypy-c') + library = os.path.join(thisdir, '..', 'pypy', 'goal', 'libpypy-c') libraries = [library, 'oleaut32'] extra_ldargs = ['/MANIFEST', # needed for VC10 '/EXPORT:init_testcapi'] diff --git a/pypy/bin/checkmodule.py b/pypy/bin/checkmodule.py --- a/pypy/bin/checkmodule.py +++ b/pypy/bin/checkmodule.py @@ -8,6 +8,8 @@ """ import sys, os +sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', '..')) + from pypy.objspace.fake.checkmodule import checkmodule def main(argv): diff --git a/pypy/doc/cpython_differences.rst b/pypy/doc/cpython_differences.rst --- a/pypy/doc/cpython_differences.rst +++ b/pypy/doc/cpython_differences.rst @@ -318,10 +318,5 @@ type and vice versa. For builtin types, a dictionary will be returned that cannot be changed (but still looks and behaves like a normal dictionary). -* the ``__len__`` or ``__length_hint__`` special methods are sometimes - called by CPython to get a length estimate to preallocate internal arrays. - So far, PyPy never calls ``__len__`` for this purpose, and never calls - ``__length_hint__`` at all. - .. include:: _ref.txt diff --git a/pypy/doc/discussion/improve-rpython.rst b/pypy/doc/discussion/improve-rpython.rst --- a/pypy/doc/discussion/improve-rpython.rst +++ b/pypy/doc/discussion/improve-rpython.rst @@ -15,7 +15,7 @@ from pypy.interpreter.typedef import interp_attrproperty, interp_attrproperty_w from pypy.interpreter.gateway import interp2app from pypy.interpreter.error import OperationError - from pypy.rpython.lltypesystem import rffi, lltype + from rpython.rtyper.lltypesystem import rffi, lltype - A more direct declarative way to write Typedef:: diff --git a/pypy/doc/faq.rst b/pypy/doc/faq.rst --- a/pypy/doc/faq.rst +++ b/pypy/doc/faq.rst @@ -300,12 +300,26 @@ Do I have to rewrite my programs in RPython? -------------------------------------------- -No. And you shouldn't try. PyPy always runs your code in its own interpreter, which is a -full and compliant Python 2.7 interpreter. RPython is only the -language in which parts of PyPy itself are written and extension -modules for it. Not only is it not necessary for you to rewrite your -code in RPython, it probably won't give you any speed improvements if you -try. +No. And you shouldn't try. First and foremost, RPython is a language +that is designed to write interpreters in. It is a restricted subset of +Python. If you program is not an interpreter but tries to do "real +things", like use *any* part of the standard Python library or *any* +3rd-party library, then it is not RPython to start with. You should +only look at RPython if you try to `write your own interpreter`__. + +.. __: `how do I compile my own interpreters`_ + +If your goal is to speed up Python code, then look at the regular PyPy, +which is a full and compliant Python 2.7 interpreter (which happens to +be written in RPython). Not only is it not necessary for you to rewrite +your code in RPython, it might not give you any speed improvements even +if you manage to. + +Yes, it is possible with enough effort to compile small self-contained +pieces of RPython code doing a few performance-sensitive things. But +this case is not interesting for us. If you needed to rewrite the code +in RPython, you could as well have rewritten it in C for example. The +latter is a much more supported, much more documented language `:-)` --------------------------------------------------- Which backends are there for the RPython toolchain? diff --git a/pypy/doc/rffi.rst b/pypy/doc/rffi.rst --- a/pypy/doc/rffi.rst +++ b/pypy/doc/rffi.rst @@ -17,7 +17,7 @@ lltype.Signed or lltype.Array) and memory management must be done by hand. To declare a function, we write:: - from pypy.rpython.lltypesystem import rffi + from rpython.rtyper.lltypesystem import rffi external_function = rffi.llexternal(name, args, result) @@ -31,7 +31,7 @@ libraries and sources by passing in the optional ``compilation_info`` parameter:: - from pypy.rpython.lltypesystem import rffi + from rpython.rtyper.lltypesystem import rffi from rpython.translator.tool.cbuild import ExternalCompilationInfo info = ExternalCompilationInfo(includes=[], libraries=[]) diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -1508,9 +1508,10 @@ ) raise w_fd = self.call_function(w_fileno) - if not self.isinstance_w(w_fd, self.w_int): + if (not self.isinstance_w(w_fd, self.w_int) and + not self.isinstance_w(w_fd, self.w_long)): raise OperationError(self.w_TypeError, - self.wrap("fileno() must return an integer") + self.wrap("fileno() returned a non-integer") ) fd = self.int_w(w_fd) if fd < 0: diff --git a/pypy/interpreter/miscutils.py b/pypy/interpreter/miscutils.py --- a/pypy/interpreter/miscutils.py +++ b/pypy/interpreter/miscutils.py @@ -17,9 +17,8 @@ def setvalue(self, value): self._value = value - def getmainthreadvalue(self): - return self._value + def ismainthread(self): + return True def getallvalues(self): return {0: self._value} - diff --git a/pypy/module/_bisect/interp_bisect.py b/pypy/module/_bisect/interp_bisect.py --- a/pypy/module/_bisect/interp_bisect.py +++ b/pypy/module/_bisect/interp_bisect.py @@ -1,5 +1,6 @@ from pypy.interpreter.error import OperationError from pypy.interpreter.gateway import unwrap_spec +from rpython.rlib.rarithmetic import intmask, r_uint @unwrap_spec(lo=int, hi=int) @@ -18,7 +19,7 @@ if hi == -1: hi = space.len_w(w_a) while lo < hi: - mid = (lo + hi) >> 1 + mid = intmask((r_uint(lo) + r_uint(hi)) >> 1) w_litem = space.getitem(w_a, space.wrap(mid)) if space.is_true(space.lt(w_litem, w_x)): lo = mid + 1 @@ -43,7 +44,7 @@ if hi == -1: hi = space.len_w(w_a) while lo < hi: - mid = (lo + hi) >> 1 + mid = intmask((r_uint(lo) + r_uint(hi)) >> 1) w_litem = space.getitem(w_a, space.wrap(mid)) if space.is_true(space.lt(w_x, w_litem)): hi = mid diff --git a/pypy/module/_bisect/test/test_bisect.py b/pypy/module/_bisect/test/test_bisect.py --- a/pypy/module/_bisect/test/test_bisect.py +++ b/pypy/module/_bisect/test/test_bisect.py @@ -87,3 +87,12 @@ insort_right(a, 6.0) assert a == [0, 5, 6, 6, 6, 6.0, 7] assert list(map(type, a)) == [int, int, int, int, int, float, int] + + def test_bisect_overflow(self): + from _bisect import bisect_left, bisect_right + import sys + + size = sys.maxsize + data = range(size - 1) + assert bisect_left(data, size - 3) == size - 3 + assert bisect_right(data, size - 3) == size - 2 diff --git a/pypy/module/_io/interp_fileio.py b/pypy/module/_io/interp_fileio.py --- a/pypy/module/_io/interp_fileio.py +++ b/pypy/module/_io/interp_fileio.py @@ -153,41 +153,49 @@ self.readable, self.writable, append, flags = decode_mode(space, mode) - if fd >= 0: - verify_fd(fd) - try: - os.fstat(fd) - except OSError, e: - if e.errno == errno.EBADF: - raise wrap_oserror(space, e) - # else: pass - self.fd = fd - self.closefd = bool(closefd) - else: - if not closefd: - raise OperationError(space.w_ValueError, space.wrap( - "Cannot use closefd=False with file name")) - self.closefd = True + fd_is_own = False + try: + if fd >= 0: + verify_fd(fd) + try: + os.fstat(fd) + except OSError, e: + if e.errno == errno.EBADF: + raise wrap_oserror(space, e) + # else: pass + self.fd = fd + self.closefd = bool(closefd) + else: + self.closefd = True + if not closefd: + raise OperationError(space.w_ValueError, space.wrap( + "Cannot use closefd=False with file name")) - from pypy.module.posix.interp_posix import ( - dispatch_filename, rposix) - try: - self.fd = dispatch_filename(rposix.open)( - space, w_name, flags, 0666) - except OSError, e: - raise wrap_oserror2(space, e, w_name, - exception_name='w_IOError') + from pypy.module.posix.interp_posix import ( + dispatch_filename, rposix) + try: + self.fd = dispatch_filename(rposix.open)( + space, w_name, flags, 0666) + except OSError, e: + raise wrap_oserror2(space, e, w_name, + exception_name='w_IOError') + finally: + fd_is_own = True self._dircheck(space, w_name) - self.w_name = w_name + self.w_name = w_name - if append: - # For consistent behaviour, we explicitly seek to the end of file - # (otherwise, it might be done only on the first write()). - try: - os.lseek(self.fd, 0, os.SEEK_END) - except OSError, e: - raise wrap_oserror(space, e, exception_name='w_IOError') + if append: + # For consistent behaviour, we explicitly seek to the end of file + # (otherwise, it might be done only on the first write()). + try: + os.lseek(self.fd, 0, os.SEEK_END) + except OSError, e: + raise wrap_oserror(space, e, exception_name='w_IOError') + except: + if not fd_is_own: + self.fd = -1 + raise def _mode(self): if self.readable: @@ -249,7 +257,6 @@ except OSError: return if stat.S_ISDIR(st.st_mode): - self._close(space) raise wrap_oserror2(space, OSError(errno.EISDIR, "fstat"), w_filename, exception_name='w_IOError') diff --git a/pypy/module/_io/test/test_fileio.py b/pypy/module/_io/test/test_fileio.py --- a/pypy/module/_io/test/test_fileio.py +++ b/pypy/module/_io/test/test_fileio.py @@ -41,7 +41,12 @@ def test_open_directory(self): import _io + import os raises(IOError, _io.FileIO, self.tmpdir, "rb") + if os.name != 'nt': + fd = os.open(self.tmpdir, os.O_RDONLY) + raises(IOError, _io.FileIO, fd, "rb") + os.close(fd) def test_readline(self): import _io diff --git a/pypy/module/cpyext/longobject.py b/pypy/module/cpyext/longobject.py --- a/pypy/module/cpyext/longobject.py +++ b/pypy/module/cpyext/longobject.py @@ -47,7 +47,12 @@ Return a C unsigned long representation of the contents of pylong. If pylong is greater than ULONG_MAX, an OverflowError is raised.""" - return rffi.cast(rffi.ULONG, space.uint_w(w_long)) + try: + return rffi.cast(rffi.ULONG, space.uint_w(w_long)) + except OperationError, e: + if e.match(space, space.w_ValueError): + e.w_type = space.w_OverflowError + raise @cpython_api([PyObject], rffi.ULONG, error=-1) def PyLong_AsUnsignedLongMask(space, w_long): @@ -86,7 +91,12 @@ Return a C unsigned long representation of the contents of pylong. If pylong is greater than ULONG_MAX, an OverflowError is raised.""" - return rffi.cast(rffi.ULONGLONG, space.r_ulonglong_w(w_long)) + try: + return rffi.cast(rffi.ULONGLONG, space.r_ulonglong_w(w_long)) + except OperationError, e: + if e.match(space, space.w_ValueError): + e.w_type = space.w_OverflowError + raise @cpython_api([PyObject], rffi.ULONGLONG, error=-1) def PyLong_AsUnsignedLongLongMask(space, w_long): diff --git a/pypy/module/cpyext/object.py b/pypy/module/cpyext/object.py --- a/pypy/module/cpyext/object.py +++ b/pypy/module/cpyext/object.py @@ -226,6 +226,8 @@ @cpython_api([PyObject], PyObject) def PyObject_Str(space, w_obj): + if w_obj is None: + return space.wrap("") return space.str(w_obj) @cpython_api([PyObject], PyObject) @@ -234,6 +236,8 @@ representation on success, NULL on failure. This is the equivalent of the Python expression repr(o). Called by the repr() built-in function and by reverse quotes.""" + if w_obj is None: + return space.wrap("") return space.repr(w_obj) @cpython_api([PyObject], PyObject) @@ -251,6 +255,8 @@ string representation on success, NULL on failure. This is the equivalent of the Python expression unicode(o). Called by the unicode() built-in function.""" + if w_obj is None: + return space.wrap(u"") return space.call_function(space.w_unicode, w_obj) @cpython_api([PyObject, PyObject, rffi.INT_real], PyObject) diff --git a/pypy/module/cpyext/test/test_longobject.py b/pypy/module/cpyext/test/test_longobject.py --- a/pypy/module/cpyext/test/test_longobject.py +++ b/pypy/module/cpyext/test/test_longobject.py @@ -31,6 +31,8 @@ value = api.PyLong_AsUnsignedLong(w_value) assert value == (sys.maxint - 1) * 2 + self.raises(space, api, OverflowError, api.PyLong_AsUnsignedLong, space.wrap(-1)) + def test_as_ssize_t(self, space, api): w_value = space.newlong(2) value = api.PyLong_AsSsize_t(w_value) @@ -46,11 +48,11 @@ w_l = space.wrap(sys.maxint + 1) assert api.PyLong_Check(w_l) assert api.PyLong_CheckExact(w_l) - + w_i = space.wrap(sys.maxint) assert not api.PyLong_Check(w_i) assert not api.PyLong_CheckExact(w_i) - + L = space.appexec([], """(): class L(long): pass @@ -73,6 +75,8 @@ assert api.PyLong_AsUnsignedLongLongMask( space.wrap(1<<64)) == 0 + self.raises(space, api, OverflowError, api.PyLong_AsUnsignedLongLong, space.wrap(-1)) + def test_as_long_and_overflow(self, space, api): overflow = lltype.malloc(rffi.CArrayPtr(rffi.INT_real).TO, 1, flavor='raw') assert api.PyLong_AsLongAndOverflow( diff --git a/pypy/module/cpyext/test/test_object.py b/pypy/module/cpyext/test/test_object.py --- a/pypy/module/cpyext/test/test_object.py +++ b/pypy/module/cpyext/test/test_object.py @@ -95,15 +95,18 @@ def test_size(self, space, api): assert api.PyObject_Size(space.newlist([space.w_None])) == 1 + def test_str(self, space, api): + w_list = space.newlist([space.w_None, space.wrap(42)]) + assert space.str_w(api.PyObject_Str(None)) == "" + assert space.str_w(api.PyObject_Str(w_list)) == "[None, 42]" + assert space.str_w(api.PyObject_Str(space.wrap("a"))) == "a" + def test_repr(self, space, api): w_list = space.newlist([space.w_None, space.wrap(42)]) + assert space.str_w(api.PyObject_Repr(None)) == "" assert space.str_w(api.PyObject_Repr(w_list)) == "[None, 42]" assert space.str_w(api.PyObject_Repr(space.wrap("a"))) == "'a'" - w_list = space.newlist([space.w_None, space.wrap(42)]) - assert space.str_w(api.PyObject_Str(w_list)) == "[None, 42]" - assert space.str_w(api.PyObject_Str(space.wrap("a"))) == "a" - def test_RichCompare(self, space, api): def compare(w_o1, w_o2, opid): res = api.PyObject_RichCompareBool(w_o1, w_o2, opid) diff --git a/pypy/module/fcntl/test/test_fcntl.py b/pypy/module/fcntl/test/test_fcntl.py --- a/pypy/module/fcntl/test/test_fcntl.py +++ b/pypy/module/fcntl/test/test_fcntl.py @@ -22,13 +22,23 @@ import sys import struct + class F: + def __init__(self, fn): + self.fn = fn + def fileno(self): + return self.fn + f = open(self.tmp + "b", "w+") fcntl.fcntl(f, 1, 0) fcntl.fcntl(f, 1) + fcntl.fcntl(F(long(f.fileno())), 1) raises(TypeError, fcntl.fcntl, "foo") raises(TypeError, fcntl.fcntl, f, "foo") - raises((IOError, ValueError), fcntl.fcntl, -1, 1, 0) + raises(TypeError, fcntl.fcntl, F("foo"), 1) + raises(ValueError, fcntl.fcntl, -1, 1, 0) + raises(ValueError, fcntl.fcntl, F(-1), 1, 0) + raises(ValueError, fcntl.fcntl, F(long(-1)), 1, 0) assert fcntl.fcntl(f, 1, 0) == 0 assert fcntl.fcntl(f, 2, "foo") == b"foo" assert fcntl.fcntl(f, 2, memoryview(b"foo")) == b"foo" diff --git a/pypy/module/signal/interp_signal.py b/pypy/module/signal/interp_signal.py --- a/pypy/module/signal/interp_signal.py +++ b/pypy/module/signal/interp_signal.py @@ -198,15 +198,12 @@ A signal handler function is called with two arguments: the first is the signal number, the second is the interrupted stack frame. """ - ec = space.getexecutioncontext() - main_ec = space.threadlocals.getmainthreadvalue() - - old_handler = getsignal(space, signum) - - if ec is not main_ec: + if not space.threadlocals.ismainthread(): raise OperationError(space.w_ValueError, space.wrap("signal() must be called from the " "main thread")) + old_handler = getsignal(space, signum) + action = space.check_signal_action if space.eq_w(w_handler, space.wrap(SIG_DFL)): pypysig_default(signum) @@ -231,13 +228,10 @@ The fd must be non-blocking. """ - if space.config.objspace.usemodules.thread: - main_ec = space.threadlocals.getmainthreadvalue() - ec = space.getexecutioncontext() - if ec is not main_ec: - raise OperationError( - space.w_ValueError, - space.wrap("set_wakeup_fd only works in main thread")) + if not space.threadlocals.ismainthread(): + raise OperationError( + space.w_ValueError, + space.wrap("set_wakeup_fd only works in main thread")) old_fd = pypysig_set_wakeup_fd(fd) return space.wrap(intmask(old_fd)) diff --git a/pypy/module/thread/test/support.py b/pypy/module/thread/test/support.py --- a/pypy/module/thread/test/support.py +++ b/pypy/module/thread/test/support.py @@ -2,6 +2,7 @@ import time import thread import os +import errno from pypy.interpreter.gateway import interp2app, unwrap_spec from pypy.module.thread import gil @@ -28,7 +29,12 @@ def kill(): for x in range(delay * 10): time.sleep(0.1) - os.kill(pid, 0) + try: + os.kill(pid, 0) + except OSError, e: + if e.errno == errno.ESRCH: # no such process + return + raise os.kill(pid, 9) print "process %s killed!" % (pid,) thread.start_new_thread(kill, ()) diff --git a/pypy/module/thread/test/test_fork.py b/pypy/module/thread/test/test_fork.py --- a/pypy/module/thread/test/test_fork.py +++ b/pypy/module/thread/test/test_fork.py @@ -1,7 +1,7 @@ from pypy.module.thread.test.support import GenericTestThread class AppTestFork(GenericTestThread): - def test_fork(self): + def test_fork_with_thread(self): # XXX This test depends on a multicore machine, as busy_thread must # aquire the GIL the instant that the main thread releases it. # It will incorrectly pass if the GIL is not grabbed in time. @@ -12,45 +12,48 @@ if not hasattr(os, 'fork'): skip("No fork on this platform") - run = True - done = [] def busy_thread(): while run: time.sleep(0) done.append(None) - try: - _thread.start_new(busy_thread, ()) + for i in range(1): + run = True + done = [] + try: + thread.start_new(busy_thread, ()) + print('sleep') - pid = os.fork() - - if pid == 0: - os._exit(0) - - else: - time.sleep(1) - spid, status = os.waitpid(pid, os.WNOHANG) - assert spid == pid - finally: - run = False - self.waitfor(lambda: done) + pid = os.fork() + if pid == 0: + os._exit(0) + else: + self.timeout_killer(pid, 5) + exitcode = os.waitpid(pid, 0)[1] + assert exitcode == 0 # if 9, process was killed by timer! + finally: + run = False + self.waitfor(lambda: done) + assert done def test_forked_can_thread(self): "Checks that a forked interpreter can start a thread" - import os, _thread, time + import _thread + import os if not hasattr(os, 'fork'): skip("No fork on this platform") - # pre-allocate some locks - _thread.start_new_thread(lambda: None, ()) + for i in range(10): + # pre-allocate some locks + _thread.start_new_thread(lambda: None, ()) + print('sleep') - pid = os.fork() - if pid == 0: - print('in child') - _thread.start_new_thread(lambda: None, ()) - os._exit(0) - else: - self.timeout_killer(pid, 5) - exitcode = os.waitpid(pid, 0)[1] - assert exitcode == 0 # if 9, process was killed by timer! + pid = os.fork() + if pid == 0: + _thread.start_new_thread(lambda: None, ()) + os._exit(0) + else: + self.timeout_killer(pid, 5) + exitcode = os.waitpid(pid, 0)[1] + assert exitcode == 0 # if 9, process was killed by timer! diff --git a/pypy/module/thread/test/test_lock.py b/pypy/module/thread/test/test_lock.py --- a/pypy/module/thread/test/test_lock.py +++ b/pypy/module/thread/test/test_lock.py @@ -12,7 +12,10 @@ assert lock.locked() is False raises(_thread.error, lock.release) assert lock.locked() is False - lock.acquire() + r = lock.acquire() + assert r is True + r = lock.acquire(False) + assert r is False assert lock.locked() is True lock.release() assert lock.locked() is False diff --git a/pypy/module/thread/threadlocals.py b/pypy/module/thread/threadlocals.py --- a/pypy/module/thread/threadlocals.py +++ b/pypy/module/thread/threadlocals.py @@ -44,10 +44,6 @@ self._mostrecentkey = ident self._mostrecentvalue = value - def getmainthreadvalue(self): - ident = self._mainthreadident - return self._valuedict.get(ident, None) - def ismainthread(self): return thread.get_ident() == self._mainthreadident diff --git a/rpython/flowspace/framestate.py b/rpython/flowspace/framestate.py --- a/rpython/flowspace/framestate.py +++ b/rpython/flowspace/framestate.py @@ -1,5 +1,6 @@ +from rpython.flowspace.model import Variable, Constant from rpython.rlib.unroll import SpecTag -from rpython.flowspace.model import * + class FrameState: def __init__(self, mergeable, blocklist, next_instr): @@ -86,6 +87,7 @@ raise TypeError('union of %r and %r' % (w1.__class__.__name__, w2.__class__.__name__)) + # ____________________________________________________________ # # We have to flatten out the state of the frame into a list of @@ -102,6 +104,7 @@ PICKLE_TAGS = {} UNPICKLE_TAGS = {} + def recursively_flatten(space, lst): from rpython.flowspace.flowcontext import SuspendedUnroller i = 0 @@ -117,14 +120,15 @@ except: tag = PICKLE_TAGS[key] = Constant(PickleTag()) UNPICKLE_TAGS[tag] = key - lst[i:i+1] = [tag] + vars + lst[i:i + 1] = [tag] + vars + def recursively_unflatten(space, lst): - for i in xrange(len(lst)-1, -1, -1): + for i in xrange(len(lst) - 1, -1, -1): item = lst[i] if item in UNPICKLE_TAGS: unrollerclass, argcount = UNPICKLE_TAGS[item] - arguments = lst[i+1: i+1+argcount] - del lst[i+1: i+1+argcount] + arguments = lst[i + 1:i + 1 + argcount] + del lst[i + 1:i + 1 + argcount] unroller = unrollerclass.state_pack_variables(space, *arguments) lst[i] = unroller diff --git a/rpython/jit/metainterp/optimizeopt/unroll.py b/rpython/jit/metainterp/optimizeopt/unroll.py --- a/rpython/jit/metainterp/optimizeopt/unroll.py +++ b/rpython/jit/metainterp/optimizeopt/unroll.py @@ -1,16 +1,16 @@ -from rpython.jit.codewriter.effectinfo import EffectInfo +import sys + +from rpython.jit.metainterp.compile import ResumeGuardDescr +from rpython.jit.metainterp.history import TargetToken, JitCellToken, Const +from rpython.jit.metainterp.inliner import Inliner +from rpython.jit.metainterp.optimize import InvalidLoop +from rpython.jit.metainterp.optimizeopt.generalize import KillHugeIntBounds +from rpython.jit.metainterp.optimizeopt.optimizer import Optimizer, Optimization from rpython.jit.metainterp.optimizeopt.virtualstate import VirtualStateAdder, ShortBoxes, BadVirtualState -from rpython.jit.metainterp.compile import ResumeGuardDescr -from rpython.jit.metainterp.history import TreeLoop, TargetToken, JitCellToken -from rpython.jit.metainterp.jitexc import JitException -from rpython.jit.metainterp.optimize import InvalidLoop -from rpython.rlib.debug import debug_print, debug_start, debug_stop -from rpython.jit.metainterp.optimizeopt.optimizer import * -from rpython.jit.metainterp.optimizeopt.generalize import KillHugeIntBounds -from rpython.jit.metainterp.inliner import Inliner from rpython.jit.metainterp.resoperation import rop, ResOperation from rpython.jit.metainterp.resume import Snapshot -import sys, os +from rpython.rlib.debug import debug_print, debug_start, debug_stop + # FIXME: Introduce some VirtualOptimizer super class instead @@ -19,6 +19,7 @@ opt.inline_short_preamble = inline_short_preamble opt.propagate_all_forward() + class UnrollableOptimizer(Optimizer): def setup(self): self.importable_values = {} @@ -51,7 +52,7 @@ distinction anymore)""" inline_short_preamble = True - + def __init__(self, metainterp_sd, loop, optimizations): self.optimizer = UnrollableOptimizer(metainterp_sd, loop, optimizations) self.boxes_created_this_iteration = None @@ -59,14 +60,14 @@ def fix_snapshot(self, jump_args, snapshot): if snapshot is None: return None - snapshot_args = snapshot.boxes + snapshot_args = snapshot.boxes new_snapshot_args = [] for a in snapshot_args: a = self.getvalue(a).get_key_box() new_snapshot_args.append(a) prev = self.fix_snapshot(jump_args, snapshot.prev) return Snapshot(prev, new_snapshot_args) - + def propagate_all_forward(self): loop = self.optimizer.loop self.optimizer.clear_newoperations() @@ -78,7 +79,7 @@ # will clear heap caches self.optimizer.send_extra_operation(start_label) else: - start_label = None + start_label = None jumpop = loop.operations[-1] if jumpop.getopnum() == rop.JUMP or jumpop.getopnum() == rop.LABEL: @@ -96,7 +97,6 @@ assert isinstance(cell_token, JitCellToken) stop_label = ResOperation(rop.LABEL, jumpop.getarglist(), None, TargetToken(cell_token)) - if jumpop.getopnum() == rop.JUMP: if self.jump_to_already_compiled_trace(jumpop): # Found a compiled trace to jump to @@ -130,7 +130,7 @@ return # Found nothing to jump to, emit a label instead - + if self.short: # Construct our short preamble assert start_label @@ -146,7 +146,7 @@ def jump_to_start_label(self, start_label, stop_label): if not start_label or not stop_label: return False - + stop_target = stop_label.getdescr() start_target = start_label.getdescr() assert isinstance(stop_target, TargetToken) @@ -161,7 +161,6 @@ #virtual_state = modifier.get_virtual_state(args) #if self.initial_virtual_state.generalization_of(virtual_state): # return True - def export_state(self, targetop): original_jump_args = targetop.getarglist() @@ -174,12 +173,11 @@ modifier = VirtualStateAdder(self.optimizer) virtual_state = modifier.get_virtual_state(jump_args) - + values = [self.getvalue(arg) for arg in jump_args] inputargs = virtual_state.make_inputargs(values, self.optimizer) short_inputargs = virtual_state.make_inputargs(values, self.optimizer, keyboxes=True) - if self.boxes_created_this_iteration is not None: for box in self.inputargs: self.boxes_created_this_iteration[box] = True @@ -210,7 +208,7 @@ if op and op.result: box = op.result exported_values[box] = self.optimizer.getvalue(box) - + target_token.exported_state = ExportedState(short_boxes, inputarg_setup_ops, exported_values) @@ -232,7 +230,7 @@ virtual_state = modifier.get_virtual_state(self.inputargs) self.initial_virtual_state = virtual_state return - + self.short = target_token.short_preamble[:] self.short_seen = {} self.short_boxes = exported_state.short_boxes @@ -276,7 +274,7 @@ #if self.optimizer.loop.logops: # debug_print(' Falling back to add extra: ' + # self.optimizer.loop.logops.repr_of_resop(op)) - + self.optimizer.flush() self.optimizer.emitting_dissabled = False @@ -287,7 +285,7 @@ # We dont need to inline the short preamble we are creating as we are conneting # the bridge to a different trace with a different short preamble self.short_inliner = None - + newoperations = self.optimizer.get_newoperations() self.boxes_created_this_iteration = {} i = 0 @@ -333,7 +331,7 @@ 'same box passed to multiple of its ' + 'inputargs, but the jump at the ' + 'end of this bridge does not do that.') - + args[short_inputargs[i]] = jmp_to_short_args[i] self.short_inliner = Inliner(short_inputargs, jmp_to_short_args) i = 1 @@ -400,7 +398,7 @@ 'loop is not compatible with the virtual ' + 'state at the start of the loop which makes ' + 'it impossible to close the loop') - + #debug_stop('jit-log-virtualstate') maxguards = self.optimizer.metainterp_sd.warmrunnerdesc.memory_manager.max_retrace_guards @@ -408,9 +406,9 @@ target_token = jumpop.getdescr() assert isinstance(target_token, TargetToken) target_token.targeting_jitcell_token.retraced_count = sys.maxint - + self.finilize_short_preamble(start_label) - + def finilize_short_preamble(self, start_label): short = self.short assert short[-1].getopnum() == rop.JUMP @@ -482,11 +480,11 @@ if op is None: return None if op.result is not None and op.result in self.short_seen: - if emit and self.short_inliner: + if emit and self.short_inliner: return self.short_inliner.inline_arg(op.result) else: return None - + for a in op.getarglist(): if not isinstance(a, Const) and a not in self.short_seen: self.add_op_to_short(self.short_boxes.producer(a), emit, guards_needed) @@ -497,7 +495,7 @@ if guards_needed and self.short_boxes.has_producer(op.result): value_guards = self.getvalue(op.result).make_guards(op.result) else: - value_guards = [] + value_guards = [] self.short.append(op) self.short_seen[op.result] = True @@ -517,7 +515,7 @@ if newop: return newop.result return None - + def import_box(self, box, inputargs, short_jumpargs, jumpargs): if isinstance(box, Const) or box in inputargs: return @@ -603,7 +601,7 @@ classbox = self.getvalue(newop.result).get_constant_class(self.optimizer.cpu) if not classbox or not classbox.same_constant(target.assumed_classes[shop.result]): raise InvalidLoop('The class of an opaque pointer at the end ' + - 'of the bridge does not mach the class ' + + 'of the bridge does not mach the class ' + 'it has at the start of the target loop') except InvalidLoop: #debug_print("Inlining failed unexpectedly", @@ -615,6 +613,7 @@ debug_stop('jit-log-virtualstate') return False + class ValueImporter(object): def __init__(self, unroll, value, op): self.unroll = unroll @@ -623,7 +622,8 @@ def import_value(self, value): value.import_from(self.preamble_value, self.unroll.optimizer) - self.unroll.add_op_to_short(self.op, False, True) + self.unroll.add_op_to_short(self.op, False, True) + class ExportedState(object): def __init__(self, short_boxes, inputarg_setup_ops, exported_values): diff --git a/rpython/jit/metainterp/test/test_ajit.py b/rpython/jit/metainterp/test/test_ajit.py --- a/rpython/jit/metainterp/test/test_ajit.py +++ b/rpython/jit/metainterp/test/test_ajit.py @@ -1694,14 +1694,13 @@ assert res == -2 def test_guard_always_changing_value(self): - myjitdriver = JitDriver(greens = [], reds = ['x']) - class A: - pass + myjitdriver = JitDriver(greens = [], reds = ['x', 'a']) def f(x): + a = 0 while x > 0: - myjitdriver.can_enter_jit(x=x) - myjitdriver.jit_merge_point(x=x) - a = A() + myjitdriver.can_enter_jit(x=x, a=a) + myjitdriver.jit_merge_point(x=x, a=a) + a += 1 promote(a) x -= 1 self.meta_interp(f, [50]) diff --git a/rpython/jit/metainterp/virtualizable.py b/rpython/jit/metainterp/virtualizable.py --- a/rpython/jit/metainterp/virtualizable.py +++ b/rpython/jit/metainterp/virtualizable.py @@ -1,14 +1,12 @@ +from rpython.jit.metainterp import history +from rpython.jit.metainterp.typesystem import deref, fieldType, arrayItem +from rpython.jit.metainterp.warmstate import wrap, unwrap +from rpython.rlib.unroll import unrolling_iterable +from rpython.rtyper import rvirtualizable2 from rpython.rtyper.lltypesystem import lltype, llmemory from rpython.rtyper.ootypesystem import ootype -from rpython.rtyper.annlowlevel import cast_base_ptr_to_instance from rpython.rtyper.rclass import IR_IMMUTABLE_ARRAY, IR_IMMUTABLE -from rpython.rtyper import rvirtualizable2 -from rpython.rlib.unroll import unrolling_iterable -from rpython.rlib.nonconst import NonConstant -from rpython.jit.metainterp.typesystem import deref, fieldType, arrayItem -from rpython.jit.metainterp import history -from rpython.jit.metainterp.warmstate import wrap, unwrap -from rpython.rlib.objectmodel import specialize + class VirtualizableInfo(object): TOKEN_NONE = 0 # must be 0 -- see also x86.call_assembler @@ -76,7 +74,7 @@ getlength = cpu.ts.getlength getarrayitem = cpu.ts.getarrayitem setarrayitem = cpu.ts.setarrayitem - # + def read_boxes(cpu, virtualizable): assert lltype.typeOf(virtualizable) == llmemory.GCREF virtualizable = cast_gcref_to_vtype(virtualizable) @@ -89,7 +87,7 @@ for i in range(getlength(lst)): boxes.append(wrap(cpu, getarrayitem(lst, i))) return boxes - # + def write_boxes(virtualizable, boxes): virtualizable = cast_gcref_to_vtype(virtualizable) i = 0 @@ -104,7 +102,7 @@ setarrayitem(lst, j, x) i = i + 1 assert len(boxes) == i + 1 - # + def write_from_resume_data_partial(virtualizable, reader, numb): virtualizable = cast_gcref_to_vtype(virtualizable) # Load values from the reader (see resume.py) described by @@ -117,7 +115,7 @@ assert i >= 0 for ARRAYITEMTYPE, fieldname in unroll_array_fields_rev: lst = getattr(virtualizable, fieldname) - for j in range(getlength(lst)-1, -1, -1): + for j in range(getlength(lst) - 1, -1, -1): i -= 1 assert i >= 0 x = reader.load_value_of_type(ARRAYITEMTYPE, numb.nums[i]) @@ -128,7 +126,7 @@ x = reader.load_value_of_type(FIELDTYPE, numb.nums[i]) setattr(virtualizable, fieldname, x) return i - # + def load_list_of_boxes(virtualizable, reader, numb): virtualizable = cast_gcref_to_vtype(virtualizable) # Uses 'virtualizable' only to know the length of the arrays; @@ -140,10 +138,10 @@ boxes = [reader.decode_box_of_type(self.VTYPEPTR, numb.nums[i])] for ARRAYITEMTYPE, fieldname in unroll_array_fields_rev: lst = getattr(virtualizable, fieldname) - for j in range(getlength(lst)-1, -1, -1): + for j in range(getlength(lst) - 1, -1, -1): i -= 1 assert i >= 0 - box = reader.decode_box_of_type(ARRAYITEMTYPE,numb.nums[i]) + box = reader.decode_box_of_type(ARRAYITEMTYPE, numb.nums[i]) boxes.append(box) for FIELDTYPE, fieldname in unroll_static_fields_rev: i -= 1 @@ -152,7 +150,7 @@ boxes.append(box) boxes.reverse() return boxes - # + def check_boxes(virtualizable, boxes): virtualizable = cast_gcref_to_vtype(virtualizable) # for debugging @@ -168,7 +166,7 @@ assert getarrayitem(lst, j) == x i = i + 1 assert len(boxes) == i + 1 - # + def get_index_in_array(virtualizable, arrayindex, index): virtualizable = cast_gcref_to_vtype(virtualizable) index += self.num_static_extra_boxes @@ -180,7 +178,7 @@ index += getlength(lst) j = j + 1 assert False, "invalid arrayindex" - # + def get_array_length(virtualizable, arrayindex): virtualizable = cast_gcref_to_vtype(virtualizable) j = 0 @@ -188,16 +186,16 @@ if arrayindex == j: lst = getattr(virtualizable, fieldname) return getlength(lst) - j = j + 1 + j += 1 assert False, "invalid arrayindex" - # + unroll_static_fields = unrolling_iterable(zip(FIELDTYPES, static_fields)) unroll_array_fields = unrolling_iterable(zip(ARRAYITEMTYPES, array_fields)) unroll_static_fields_rev = unrolling_iterable( reversed(list(unroll_static_fields))) - unroll_array_fields_rev = unrolling_iterable( + unroll_array_fields_rev = unrolling_iterable( reversed(list(unroll_array_fields))) self.read_boxes = read_boxes self.write_boxes = write_boxes @@ -291,7 +289,7 @@ def unwrap_virtualizable_box(self, virtualizable_box): return virtualizable_box.getref(llmemory.GCREF) - + def is_vtypeptr(self, TYPE): return rvirtualizable2.match_virtualizable_type(TYPE, self.VTYPEPTR) diff --git a/rpython/rlib/rthread.py b/rpython/rlib/rthread.py --- a/rpython/rlib/rthread.py +++ b/rpython/rlib/rthread.py @@ -126,10 +126,11 @@ return bool(res) def acquire_timed(self, timeout): - "timeout is in microseconds." + """Timeout is in microseconds. Returns 0 in case of failure, + 1 in case it works, 2 if interrupted by a signal.""" res = c_thread_acquirelock_timed(self._lock, timeout, 1) res = rffi.cast(lltype.Signed, res) - return bool(res) + return res def release(self): # Sanity check: the lock must be locked diff --git a/rpython/rlib/test/test_rpath.py b/rpython/rlib/test/test_rpath.py --- a/rpython/rlib/test/test_rpath.py +++ b/rpython/rlib/test/test_rpath.py @@ -6,7 +6,7 @@ def test_rabspath_relative(tmpdir): tmpdir.chdir() - assert rpath.rabspath('foo') == tmpdir.join('foo') + assert rpath.rabspath('foo') == os.path.realpath(str(tmpdir.join('foo'))) @py.test.mark.skipif("IS_WINDOWS") def test_rabspath_absolute_posix(): diff --git a/rpython/rlib/test/test_rthread.py b/rpython/rlib/test/test_rthread.py --- a/rpython/rlib/test/test_rthread.py +++ b/rpython/rlib/test/test_rthread.py @@ -159,17 +159,46 @@ l = allocate_lock() l.acquire(True) t1 = time.time() - ok = l.acquire_timed(1000000) + ok = l.acquire_timed(1000001) t2 = time.time() delay = t2 - t1 - if ok: + if ok == 0: # RPY_LOCK_FAILURE + return -delay + elif ok == 2: # RPY_LOCK_INTR return delay - else: - return -delay + else: # RPY_LOCK_ACQUIRED + return 0.0 fn = self.getcompiled(f, []) res = fn() assert res < -1.0 + def test_acquire_timed_alarm(self): + import sys + if not sys.platform.startswith('linux'): + py.test.skip("skipped on non-linux") + import time + from rpython.rlib import rsignal + def f(): + l = allocate_lock() + l.acquire(True) + # + rsignal.pypysig_setflag(rsignal.SIGALRM) + rsignal.c_alarm(1) + # + t1 = time.time() + ok = l.acquire_timed(2500000) + t2 = time.time() + delay = t2 - t1 + if ok == 0: # RPY_LOCK_FAILURE + return -delay + elif ok == 2: # RPY_LOCK_INTR + return delay + else: # RPY_LOCK_ACQUIRED + return 0.0 + fn = self.getcompiled(f, []) + res = fn() + assert res >= 0.95 + #class TestRunDirectly(AbstractThreadTests): # def getcompiled(self, f, argtypes): # return f diff --git a/rpython/rtyper/memory/gc/minimark.py b/rpython/rtyper/memory/gc/minimark.py --- a/rpython/rtyper/memory/gc/minimark.py +++ b/rpython/rtyper/memory/gc/minimark.py @@ -47,7 +47,7 @@ from rpython.rtyper.lltypesystem.lloperation import llop from rpython.rtyper.lltypesystem.llmemory import raw_malloc_usage from rpython.rtyper.memory.gc.base import GCBase, MovingGCBase -from rpython.rtyper.memory.gc import minimarkpage, env +from rpython.rtyper.memory.gc import env from rpython.rtyper.memory.support import mangle_hash from rpython.rlib.rarithmetic import ovfcheck, LONG_BIT, intmask, r_uint from rpython.rlib.rarithmetic import LONG_BIT_SHIFT @@ -254,6 +254,7 @@ # # The ArenaCollection() handles the nonmovable objects allocation. if ArenaCollectionClass is None: + from rpython.rtyper.memory.gc import minimarkpage ArenaCollectionClass = minimarkpage.ArenaCollection self.ac = ArenaCollectionClass(arena_size, page_size, small_request_threshold) @@ -2033,43 +2034,3 @@ (obj + offset).address[0] = llmemory.NULL self.old_objects_with_weakrefs.delete() self.old_objects_with_weakrefs = new_with_weakref - - -# ____________________________________________________________ - -# For testing, a simple implementation of ArenaCollection. -# This version could be used together with obmalloc.c, but -# it requires an extra word per object in the 'all_objects' -# list. - -class SimpleArenaCollection(object): - - def __init__(self, arena_size, page_size, small_request_threshold): - self.arena_size = arena_size # ignored - self.page_size = page_size - self.small_request_threshold = small_request_threshold - self.all_objects = [] - self.total_memory_used = 0 - - def malloc(self, size): - nsize = raw_malloc_usage(size) - ll_assert(nsize > 0, "malloc: size is null or negative") - ll_assert(nsize <= self.small_request_threshold,"malloc: size too big") - ll_assert((nsize & (WORD-1)) == 0, "malloc: size is not aligned") - # - result = llarena.arena_malloc(nsize, False) - llarena.arena_reserve(result, size) - self.all_objects.append((result, nsize)) - self.total_memory_used += nsize - return result - - def mass_free(self, ok_to_free_func): - objs = self.all_objects - self.all_objects = [] - self.total_memory_used = 0 - for rawobj, nsize in objs: - if ok_to_free_func(rawobj): - llarena.arena_free(rawobj) - else: - self.all_objects.append((rawobj, nsize)) - self.total_memory_used += nsize diff --git a/rpython/rtyper/memory/gc/minimarktest.py b/rpython/rtyper/memory/gc/minimarktest.py new file mode 100644 --- /dev/null +++ b/rpython/rtyper/memory/gc/minimarktest.py @@ -0,0 +1,44 @@ +from rpython.rtyper.lltypesystem import llarena +from rpython.rtyper.lltypesystem.llmemory import raw_malloc_usage +from rpython.rlib.debug import ll_assert +from rpython.rlib.rarithmetic import LONG_BIT + +# For testing, a simple implementation of ArenaCollection. +# This version could be used together with obmalloc.c, but +# it requires an extra word per object in the 'all_objects' +# list. + +WORD = LONG_BIT // 8 + + +class SimpleArenaCollection(object): + + def __init__(self, arena_size, page_size, small_request_threshold): + self.arena_size = arena_size # ignored + self.page_size = page_size + self.small_request_threshold = small_request_threshold + self.all_objects = [] + self.total_memory_used = 0 + + def malloc(self, size): + nsize = raw_malloc_usage(size) + ll_assert(nsize > 0, "malloc: size is null or negative") + ll_assert(nsize <= self.small_request_threshold,"malloc: size too big") + ll_assert((nsize & (WORD-1)) == 0, "malloc: size is not aligned") + # + result = llarena.arena_malloc(nsize, False) + llarena.arena_reserve(result, size) + self.all_objects.append((result, nsize)) + self.total_memory_used += nsize + return result + + def mass_free(self, ok_to_free_func): + objs = self.all_objects + self.all_objects = [] + self.total_memory_used = 0 + for rawobj, nsize in objs: + if ok_to_free_func(rawobj): + llarena.arena_free(rawobj) + else: + self.all_objects.append((rawobj, nsize)) + self.total_memory_used += nsize diff --git a/rpython/rtyper/memory/gc/test/test_direct.py b/rpython/rtyper/memory/gc/test/test_direct.py --- a/rpython/rtyper/memory/gc/test/test_direct.py +++ b/rpython/rtyper/memory/gc/test/test_direct.py @@ -481,7 +481,7 @@ class TestMiniMarkGCSimple(DirectGCTest): from rpython.rtyper.memory.gc.minimark import MiniMarkGC as GCClass - from rpython.rtyper.memory.gc.minimark import SimpleArenaCollection + from rpython.rtyper.memory.gc.minimarktest import SimpleArenaCollection # test the GC itself, providing a simple class for ArenaCollection GC_PARAMS = {'ArenaCollectionClass': SimpleArenaCollection} diff --git a/rpython/rtyper/memory/gc/test/test_inspector.py b/rpython/rtyper/memory/gc/test/test_inspector.py --- a/rpython/rtyper/memory/gc/test/test_inspector.py +++ b/rpython/rtyper/memory/gc/test/test_inspector.py @@ -43,6 +43,6 @@ class TestMiniMarkGCSimple(InspectorTest): from rpython.rtyper.memory.gc.minimark import MiniMarkGC as GCClass - from rpython.rtyper.memory.gc.minimark import SimpleArenaCollection + from rpython.rtyper.memory.gc.minimarktest import SimpleArenaCollection GC_PARAMS = {'ArenaCollectionClass': SimpleArenaCollection, "card_page_indices": 4} diff --git a/rpython/translator/c/genc.py b/rpython/translator/c/genc.py --- a/rpython/translator/c/genc.py +++ b/rpython/translator/c/genc.py @@ -761,7 +761,6 @@ srcdir / 'exception.c', srcdir / 'rtyper.c', # ifdef HAVE_RTYPER srcdir / 'support.c', - srcdir / 'profiling.c', srcdir / 'debug_print.c', srcdir / 'debug_traceback.c', # ifdef HAVE_RTYPER srcdir / 'asm.c', diff --git a/rpython/translator/c/src/profiling.c b/rpython/translator/c/src/profiling.c --- a/rpython/translator/c/src/profiling.c +++ b/rpython/translator/c/src/profiling.c @@ -8,8 +8,8 @@ #include #endif -cpu_set_t base_cpu_set; -int profiling_setup = 0; +static cpu_set_t base_cpu_set; +static int profiling_setup = 0; void pypy_setup_profiling() { @@ -37,8 +37,8 @@ #include -DWORD_PTR base_affinity_mask; -int profiling_setup = 0; +static DWORD_PTR base_affinity_mask; +static int profiling_setup = 0; void pypy_setup_profiling() { if (!profiling_setup) { diff --git a/rpython/translator/c/src/thread.h b/rpython/translator/c/src/thread.h --- a/rpython/translator/c/src/thread.h +++ b/rpython/translator/c/src/thread.h @@ -7,7 +7,7 @@ typedef enum RPyLockStatus { RPY_LOCK_FAILURE = 0, RPY_LOCK_ACQUIRED = 1, - RPY_LOCK_INTR + RPY_LOCK_INTR = 2 } RPyLockStatus; #ifdef _WIN32 From noreply at buildbot.pypy.org Fri Feb 1 02:54:45 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Fri, 1 Feb 2013 02:54:45 +0100 (CET) Subject: [pypy-commit] pypy py3k: silly import test fixes Message-ID: <20130201015445.46FB11C009B@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r60802:998e471748b9 Date: 2013-01-31 17:53 -0800 http://bitbucket.org/pypy/pypy/changeset/998e471748b9/ Log: silly import test fixes diff --git a/pypy/module/imp/test/test_import.py b/pypy/module/imp/test/test_import.py --- a/pypy/module/imp/test/test_import.py +++ b/pypy/module/imp/test/test_import.py @@ -422,7 +422,7 @@ def imp(): import pkg.i_am_not_here.neither_am_i exc = raises(ImportError, imp) - assert exc.value.args[0] == "No module named i_am_not_here.neither_am_i" + assert exc.value.args[0] == "No module named pkg.i_am_not_here" def test_future_relative_import_level_1(self): from pkg import relative_c @@ -1094,6 +1094,12 @@ (mydir): import sys sys.path.append(mydir) + + # Obscure: manually bootstrap the utf-8 codec for + # TextIOs opened by imp.find_module. It's not otherwise + # loaded by the test infrastructure but would have been + # in any other situation + import encodings.utf_8 """) def teardown_class(cls): From noreply at buildbot.pypy.org Fri Feb 1 08:26:09 2013 From: noreply at buildbot.pypy.org (mattip) Date: Fri, 1 Feb 2013 08:26:09 +0100 (CET) Subject: [pypy-commit] pypy missing-ndarray-attributes: revert to fijal's version, add failing zjit test Message-ID: <20130201072609.DF39B1C009B@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: missing-ndarray-attributes Changeset: r60803:39993e6bef4a Date: 2013-02-01 09:23 +0200 http://bitbucket.org/pypy/pypy/changeset/39993e6bef4a/ Log: revert to fijal's version, add failing zjit test diff --git a/pypy/module/micronumpy/arrayimpl/sort.py b/pypy/module/micronumpy/arrayimpl/sort.py --- a/pypy/module/micronumpy/arrayimpl/sort.py +++ b/pypy/module/micronumpy/arrayimpl/sort.py @@ -82,14 +82,14 @@ def argsort_array(arr, space, w_axis): itemtype = arr.dtype.itemtype - ok_to_continue = isinstance(itemtype, types.Float) - if isinstance(itemtype, types.Integer): - ok_to_continue = True - if isinstance(itemtype, types.ComplexFloating): - ok_to_continue = True - if not ok_to_continue: - space.wrap("sorting of non-numeric types " + \ - "'%s' is not implemented" % arr.dtype.get_name() )) + if (not isinstance(itemtype, types.Float) and + not isinstance(itemtype, types.Integer) and + not isinstance(itemtype, types.ComplexFloating) + ): + # XXX this should probably be changed + raise OperationError(space.w_NotImplementedError, + space.wrap("sorting of non-numeric types " + \ + "'%s' is not implemented" % arr.dtype.get_name(), )) if w_axis is space.w_None: # note that it's fine ot pass None here as we're not going # to pass the result around (None is the link to base in slices) diff --git a/pypy/module/micronumpy/compile.py b/pypy/module/micronumpy/compile.py --- a/pypy/module/micronumpy/compile.py +++ b/pypy/module/micronumpy/compile.py @@ -35,7 +35,8 @@ pass SINGLE_ARG_FUNCTIONS = ["sum", "prod", "max", "min", "all", "any", - "unegative", "flat", "tostring","count_nonzero"] + "unegative", "flat", "tostring","count_nonzero", + "argsort"] TWO_ARG_FUNCTIONS = ["dot", 'take'] THREE_ARG_FUNCTIONS = ['where'] @@ -482,6 +483,8 @@ w_res = cos.call(interp.space, [arr]) elif self.name == "flat": w_res = arr.descr_get_flatiter(interp.space) + elif self.name == "argsort": + w_res = arr.descr_argsort(interp.space) elif self.name == "tostring": arr.descr_tostring(interp.space) w_res = None diff --git a/pypy/module/micronumpy/test/test_zjit.py b/pypy/module/micronumpy/test/test_zjit.py --- a/pypy/module/micronumpy/test/test_zjit.py +++ b/pypy/module/micronumpy/test/test_zjit.py @@ -493,3 +493,14 @@ 'new_with_vtable': 1, 'int_add': 2, 'float_ne': 1}) + + def define_argsort(): + return """ + a = |30| + argsort(a) + a->6 + """ + + def test_argsort(self): + result = self.run("argsort") + assert result == 6 From noreply at buildbot.pypy.org Fri Feb 1 09:54:40 2013 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 1 Feb 2013 09:54:40 +0100 (CET) Subject: [pypy-commit] pypy default: Trying out a different fix for b366d0104c42... Hard to test Message-ID: <20130201085440.64BA41C009B@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r60804:09417d729a67 Date: 2013-02-01 09:54 +0100 http://bitbucket.org/pypy/pypy/changeset/09417d729a67/ Log: Trying out a different fix for b366d0104c42... Hard to test diff --git a/rpython/translator/platform/__init__.py b/rpython/translator/platform/__init__.py --- a/rpython/translator/platform/__init__.py +++ b/rpython/translator/platform/__init__.py @@ -53,9 +53,18 @@ ofiles = self._compile_o_files(cfiles, eci, standalone) return self._finish_linking(ofiles, eci, outputfilename, standalone) + def _all_cfiles(self, cfiles, eci): + seen = set() + result = [] + for cfile in list(cfiles) + list(eci.separate_module_files): + cfile = py.path.local(cfile) + if cfile not in seen: + seen.add(cfile) + result.append(cfile) + return result + def _compile_o_files(self, cfiles, eci, standalone=True): - cfiles = [py.path.local(f) for f in cfiles] - cfiles += [py.path.local(f) for f in eci.separate_module_files] + cfiles = self._all_cfiles(cfiles, eci) compile_args = self._compile_args_from_eci(eci, standalone) ofiles = [] for cfile in cfiles: diff --git a/rpython/translator/platform/posix.py b/rpython/translator/platform/posix.py --- a/rpython/translator/platform/posix.py +++ b/rpython/translator/platform/posix.py @@ -84,8 +84,7 @@ def gen_makefile(self, cfiles, eci, exe_name=None, path=None, shared=False): - cfiles = [py.path.local(f) for f in cfiles] - cfiles += [py.path.local(f) for f in eci.separate_module_files] + cfiles = self._all_cfiles(cfiles, eci) if path is None: path = cfiles[0].dirpath() diff --git a/rpython/translator/platform/windows.py b/rpython/translator/platform/windows.py --- a/rpython/translator/platform/windows.py +++ b/rpython/translator/platform/windows.py @@ -248,8 +248,7 @@ def gen_makefile(self, cfiles, eci, exe_name=None, path=None, shared=False): - cfiles = [py.path.local(f) for f in cfiles] - cfiles += [py.path.local(f) for f in eci.separate_module_files] + cfiles = self._all_cfiles(cfiles, eci) if path is None: path = cfiles[0].dirpath() From noreply at buildbot.pypy.org Fri Feb 1 13:04:30 2013 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 1 Feb 2013 13:04:30 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: remove this hack Message-ID: <20130201120430.C1D341C0246@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r60806:8634f509f474 Date: 2013-01-31 13:14 +0200 http://bitbucket.org/pypy/pypy/changeset/8634f509f474/ Log: remove this hack diff --git a/rpython/jit/backend/llsupport/llmodel.py b/rpython/jit/backend/llsupport/llmodel.py --- a/rpython/jit/backend/llsupport/llmodel.py +++ b/rpython/jit/backend/llsupport/llmodel.py @@ -72,16 +72,6 @@ llop.gc_assume_young_pointers(lltype.Void, new_frame) return lltype.cast_opaque_ptr(llmemory.GCREF, new_frame) - def realloc_frame_check(frame, size): - frame = lltype.cast_opaque_ptr(jitframe.JITFRAMEPTR, frame) - if size > len(frame.jf_frame) or size > frame.jf_frame_info.jfi_frame_depth: - print "CHECK FAILED" - import pdb - pdb.set_trace() - assert False - print "SOMETHING INCREDIBLY FISHY" - return lltype.cast_opaque_ptr(llmemory.GCREF, frame) - if not translate_support_code: fptr = llhelper(FUNC_TP, realloc_frame) else: @@ -94,18 +84,6 @@ mixlevelann.finish() self.realloc_frame = heaptracker.adr2int(llmemory.cast_ptr_to_adr(fptr)) - if not translate_support_code: - fptr = llhelper(FUNC_TP, realloc_frame_check) - else: - FUNC = FUNC_TP.TO - args_s = [annmodel.lltype_to_annotation(ARG) for ARG in FUNC.ARGS] - s_result = annmodel.lltype_to_annotation(FUNC.RESULT) - mixlevelann = MixLevelHelperAnnotator(self.rtyper) - graph = mixlevelann.getgraph(realloc_frame, args_s, s_result) - fptr = mixlevelann.graph2delayed(graph, FUNC) - mixlevelann.finish() - self.realloc_frame_check = heaptracker.adr2int(llmemory.cast_ptr_to_adr(fptr)) - def _setup_exception_handling_untranslated(self): # for running un-translated only, all exceptions occurring in the # llinterpreter are stored in '_exception_emulator', which is then diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -226,34 +226,6 @@ mc.RET() self._stack_check_failure = mc.materialize(self.cpu.asmmemmgr, []) - # XXX an almost identical copy for debugging, remove - - mc = codebuf.MachineCodeBlockWrapper() - self._push_all_regs_to_frame(mc, [], self.cpu.supports_floats) - assert not IS_X86_32 - # this is the gcmap stored by push_gcmap(mov=True) in _check_stack_frame - mc.MOV_rs(ecx.value, WORD) - gcmap_ofs = self.cpu.get_ofs_of_frame_field('jf_gcmap') - mc.MOV_br(gcmap_ofs, ecx.value) - # this is size that we're after, sanity checking only - mc.MOV_rs(esi.value, WORD*2) - # push first arg - mc.LEA_rb(edi.value, -base_ofs) - # align - mc.SUB_ri(esp.value, WORD) - mc.CALL(imm(self.cpu.realloc_frame_check)) - mc.ADD_ri(esp.value, WORD) - mc.LEA_rm(ebp.value, (eax.value, base_ofs)) - - gcrootmap = self.cpu.gc_ll_descr.gcrootmap - if gcrootmap and gcrootmap.is_shadow_stack: - self._load_shadowstack_top_in_ebx(mc, gcrootmap) - mc.MOV_mr((ebx.value, -WORD), eax.value) - mc.MOV_bi(gcmap_ofs, 0) - self._pop_all_regs_from_frame(mc, [], self.cpu.supports_floats) - mc.RET() - self._stack_check_failure_2 = mc.materialize(self.cpu.asmmemmgr, []) - def _build_malloc_slowpath(self): """ While arriving on slowpath, we have a gcpattern on stack, nursery_head in eax and the size in edi - eax @@ -580,10 +552,6 @@ looptoken._x86_fullsize = full_size looptoken._x86_ops_offset = ops_offset looptoken._x86_function_addr = rawstart - for label in self.labels_to_patch: - self._patch_stackadjust(label + rawstart, frame_depth_no_fixed_size - + JITFRAME_FIXED_SIZE) - self.labels_to_patch = None self.fixup_target_tokens(rawstart) self.teardown() @@ -634,9 +602,6 @@ frame_depth_no_fixed_size + JITFRAME_FIXED_SIZE) self._patch_stackadjust(stack_check_patch_ofs + rawstart, frame_depth) self._patch_stackadjust(ofs2 + rawstart, frame_depth) - for label in self.labels_to_patch: - self._patch_stackadjust(label + rawstart, frame_depth) - self.labels_to_patch = None self.fixup_target_tokens(rawstart) self.update_frame_depth(frame_depth) self.teardown() @@ -701,7 +666,7 @@ baseofs = self.cpu.get_baseofs_of_frame_field() self.current_clt.frame_info.set_frame_depth(baseofs, frame_depth) - def _check_frame_depth(self, mc, gcmap, expected_size=-1, check_only=False): + def _check_frame_depth(self, mc, gcmap, expected_size=-1): """ check if the frame is of enough depth to follow this bridge. Otherwise reallocate the frame in a helper. There are other potential solutions @@ -724,10 +689,7 @@ mc.MOV_si(WORD, expected_size) ofs2 = mc.get_relative_pos() - 4 self.push_gcmap(mc, gcmap, mov=True) - if check_only: - mc.CALL(imm(self._stack_check_failure_2)) - else: - mc.CALL(imm(self._stack_check_failure)) + mc.CALL(imm(self._stack_check_failure)) # patch the JG above offset = mc.get_relative_pos() - jg_location assert 0 < offset <= 127 @@ -829,7 +791,6 @@ def _assemble(self, regalloc, inputargs, operations): self._regalloc = regalloc - self.labels_to_patch = [] regalloc.compute_hint_frame_locations(operations) regalloc.walk_operations(inputargs, operations) if we_are_translated() or self.cpu.dont_keepalive_stuff: @@ -2546,10 +2507,7 @@ self.mc.JMP(imm(target)) def label(self): - ofs, ofs2 = self._check_frame_depth(self.mc, self._regalloc.get_gcmap(), - check_only=True) - self.labels_to_patch.append(ofs) - self.labels_to_patch.append(ofs2) + pass def malloc_cond(self, nursery_free_adr, nursery_top_adr, size, gcmap): assert size & (WORD-1) == 0 # must be correctly aligned From noreply at buildbot.pypy.org Fri Feb 1 13:04:29 2013 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 1 Feb 2013 13:04:29 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: runner tests fixes Message-ID: <20130201120429.6E1A41C0134@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r60805:b2af635e45dc Date: 2013-01-31 13:12 +0200 http://bitbucket.org/pypy/pypy/changeset/b2af635e45dc/ Log: runner tests fixes diff --git a/rpython/jit/backend/arm/test/test_runner.py b/rpython/jit/backend/arm/test/test_runner.py --- a/rpython/jit/backend/arm/test/test_runner.py +++ b/rpython/jit/backend/arm/test/test_runner.py @@ -30,9 +30,10 @@ 'adds', 'cmp', 'beq', 'b'] bridge_loop_instructions = ['movw', 'movt', 'bx'] - def setup_method(self, meth): - self.cpu = CPU(rtyper=None, stats=FakeStats()) - self.cpu.setup_once() + def get_cpu(self): + cpu = CPU(rtyper=None, stats=FakeStats()) + cpu.setup_once() + return cpu def test_result_is_spilled(self): cpu = self.cpu diff --git a/rpython/jit/backend/llgraph/runner.py b/rpython/jit/backend/llgraph/runner.py --- a/rpython/jit/backend/llgraph/runner.py +++ b/rpython/jit/backend/llgraph/runner.py @@ -885,13 +885,13 @@ if faildescr == self.cpu.done_with_this_frame_descr_int: reset_vable(jd, vable) return self.cpu.get_int_value(pframe, 0) - if faildescr == self.cpu.done_with_this_frame_descr_ref: + elif faildescr == self.cpu.done_with_this_frame_descr_ref: reset_vable(jd, vable) return self.cpu.get_ref_value(pframe, 0) - if faildescr == self.cpu.done_with_this_frame_descr_float: + elif faildescr == self.cpu.done_with_this_frame_descr_float: reset_vable(jd, vable) return self.cpu.get_float_value(pframe, 0) - if faildescr == self.cpu.done_with_this_frame_descr_void: + elif faildescr == self.cpu.done_with_this_frame_descr_void: reset_vable(jd, vable) return None # diff --git a/rpython/jit/backend/llgraph/test/test_llgraph.py b/rpython/jit/backend/llgraph/test/test_llgraph.py --- a/rpython/jit/backend/llgraph/test/test_llgraph.py +++ b/rpython/jit/backend/llgraph/test/test_llgraph.py @@ -1,23 +1,16 @@ import py -from rpython.rtyper.lltypesystem import lltype, llmemory, rstr, rclass -from rpython.rtyper.test.test_llinterp import interpret -from rpython.rlib.unroll import unrolling_iterable - -from rpython.jit.metainterp.history import BoxInt, BoxPtr, Const, ConstInt,\ - TreeLoop -from rpython.jit.metainterp.resoperation import ResOperation, rop -from rpython.jit.metainterp.executor import execute +from rpython.rtyper.lltypesystem import lltype, llmemory from rpython.jit.codewriter import heaptracker from rpython.jit.backend.test.runner_test import LLtypeBackendTest +from rpython.jit.backend.llgraph.runner import LLGraphCPU class TestLLTypeLLGraph(LLtypeBackendTest): # for individual tests see: # ====> ../../test/runner_test.py - from rpython.jit.backend.llgraph.runner import LLGraphCPU as cpu_type - def setup_method(self, _): - self.cpu = self.cpu_type(None) + def get_cpu(self): + return LLGraphCPU(None) def test_memoryerror(self): py.test.skip("does not make much sense on the llgraph backend") diff --git a/rpython/jit/backend/test/runner_test.py b/rpython/jit/backend/test/runner_test.py --- a/rpython/jit/backend/test/runner_test.py +++ b/rpython/jit/backend/test/runner_test.py @@ -112,6 +112,13 @@ avoid_instances = False + def setup_method(self, _): + self.cpu = self.get_cpu() + self.cpu.done_with_this_frame_descr_int = None + self.cpu.done_with_this_frame_descr_ref = None + self.cpu.done_with_this_frame_descr_float = None + self.cpu.done_with_this_frame_descr_void = None + def test_compile_linear_loop(self): i0 = BoxInt() i1 = BoxInt() @@ -2816,17 +2823,13 @@ # test the fast path, which should not call assembler_helper() del called[:] - prev_descr = self.cpu.done_with_this_frame_descr_int self.cpu.done_with_this_frame_descr_int = finish_descr - try: - othertoken = JitCellToken() - self.cpu.compile_loop(loop.inputargs, loop.operations, othertoken) - args = [i+1 for i in range(10)] - deadframe = self.cpu.execute_token(othertoken, *args) - assert self.cpu.get_int_value(deadframe, 0) == 97 - assert not called - finally: - self.cpu.done_with_this_frame_int_v = prev_descr + othertoken = JitCellToken() + self.cpu.compile_loop(loop.inputargs, loop.operations, othertoken) + args = [i+1 for i in range(10)] + deadframe = self.cpu.execute_token(othertoken, *args) + assert self.cpu.get_int_value(deadframe, 0) == 97 + assert not called def test_assembler_call_float(self): if not self.cpu.supports_floats: @@ -2886,19 +2889,15 @@ # test the fast path, which should not call assembler_helper() del called[:] - prev_descr = self.cpu.done_with_this_frame_descr_float self.cpu.done_with_this_frame_descr_float = finish_descr - try: - othertoken = JitCellToken() - self.cpu.compile_loop(loop.inputargs, loop.operations, othertoken) - args = [longlong.getfloatstorage(1.2), - longlong.getfloatstorage(4.2)] - deadframe = self.cpu.execute_token(othertoken, *args) - x = self.cpu.get_float_value(deadframe, 0) - assert longlong.getrealfloat(x) == 1.2 + 4.2 - assert not called - finally: - self.cpu.done_with_this_frame_descr_float = prev_descr + othertoken = JitCellToken() + self.cpu.compile_loop(loop.inputargs, loop.operations, othertoken) + args = [longlong.getfloatstorage(1.2), + longlong.getfloatstorage(4.2)] + deadframe = self.cpu.execute_token(othertoken, *args) + x = self.cpu.get_float_value(deadframe, 0) + assert longlong.getrealfloat(x) == 1.2 + 4.2 + assert not called def test_raw_malloced_getarrayitem(self): ARRAY = rffi.CArray(lltype.Signed) diff --git a/rpython/jit/backend/x86/test/test_runner.py b/rpython/jit/backend/x86/test/test_runner.py --- a/rpython/jit/backend/x86/test/test_runner.py +++ b/rpython/jit/backend/x86/test/test_runner.py @@ -34,9 +34,10 @@ bridge_loop_instructions = ['cmp', 'jge', 'mov', 'mov', 'mov', 'mov', 'call', 'mov', 'jmp'] - def setup_method(self, meth): - self.cpu = CPU(rtyper=None, stats=FakeStats()) - self.cpu.setup_once() + def get_cpu(self): + cpu = CPU(rtyper=None, stats=FakeStats()) + cpu.setup_once() + return cpu def test_execute_ptr_operation(self): cpu = self.cpu From noreply at buildbot.pypy.org Fri Feb 1 13:04:32 2013 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 1 Feb 2013 13:04:32 +0100 (CET) Subject: [pypy-commit] pypy missing-ndarray-attributes: explode when trying to create a PBC of a mixin class (it won't work) Message-ID: <20130201120432.0DA841C0134@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: missing-ndarray-attributes Changeset: r60807:fc4b0f0d3af8 Date: 2013-02-01 14:00 +0200 http://bitbucket.org/pypy/pypy/changeset/fc4b0f0d3af8/ Log: explode when trying to create a PBC of a mixin class (it won't work) diff --git a/pypy/module/micronumpy/arrayimpl/sort.py b/pypy/module/micronumpy/arrayimpl/sort.py --- a/pypy/module/micronumpy/arrayimpl/sort.py +++ b/pypy/module/micronumpy/arrayimpl/sort.py @@ -84,8 +84,7 @@ itemtype = arr.dtype.itemtype if (not isinstance(itemtype, types.Float) and not isinstance(itemtype, types.Integer) and - not isinstance(itemtype, types.ComplexFloating) - ): + not isinstance(itemtype, types.ComplexFloating)): # XXX this should probably be changed raise OperationError(space.w_NotImplementedError, space.wrap("sorting of non-numeric types " + \ diff --git a/rpython/annotator/bookkeeper.py b/rpython/annotator/bookkeeper.py --- a/rpython/annotator/bookkeeper.py +++ b/rpython/annotator/bookkeeper.py @@ -447,6 +447,8 @@ if (x is type(None) or # add cases here if needed x.__module__ == 'rpython.rtyper.lltypesystem.lltype'): result = SomeType() + elif getattr(x, '_mixin_', False): + raise Exception("Creating a PBC of a mixin class is not RPython") else: result = SomePBC([self.getdesc(x)]) elif callable(x): From noreply at buildbot.pypy.org Fri Feb 1 13:04:33 2013 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 1 Feb 2013 13:04:33 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: merge Message-ID: <20130201120433.53FD71C0134@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r60808:d9931f21e284 Date: 2013-02-01 14:03 +0200 http://bitbucket.org/pypy/pypy/changeset/d9931f21e284/ Log: merge diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -874,10 +874,10 @@ xxx self.mc.ADD_ri(ebx.value, WORD) if rx86.fits_in_32bits(rst): - self.mc.MOV_jr(rst, ebx.value) # MOV [rootstacktop], edx + self.mc.MOV_jr(rst, ebx.value) # MOV [rootstacktop], ebx else: self.mc.MOV_mr((X86_64_SCRATCH_REG.value, 0), - ebx.value) # MOV [r11], edx + ebx.value) # MOV [r11], ebx def _call_footer_shadowstack(self, gcrootmap): rst = gcrootmap.get_root_stack_top_addr() From noreply at buildbot.pypy.org Fri Feb 1 19:09:53 2013 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 1 Feb 2013 19:09:53 +0100 (CET) Subject: [pypy-commit] pypy default: No-op clean-up: detach 'handlers_w' from the classes. Message-ID: <20130201180953.C288D1C009B@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r60809:ee3ed0285605 Date: 2013-02-01 16:28 +0100 http://bitbucket.org/pypy/pypy/changeset/ee3ed0285605/ Log: No-op clean-up: detach 'handlers_w' from the classes. diff --git a/pypy/module/signal/interp_signal.py b/pypy/module/signal/interp_signal.py --- a/pypy/module/signal/interp_signal.py +++ b/pypy/module/signal/interp_signal.py @@ -60,7 +60,6 @@ def __init__(self, space): "NOT_RPYTHON" AsyncAction.__init__(self, space) - self.handlers_w = {} self.pending_signal = -1 self.fire_in_main_thread = False if self.space.config.objspace.usemodules.thread: @@ -91,7 +90,7 @@ # If we are in the main thread, report the signal now, # and poll more self.pending_signal = -1 - self._report_signal(n) + report_signal(self.space, n) n = self.pending_signal if n < 0: n = pypysig_poll() else: @@ -110,20 +109,31 @@ pypysig_pushback(cpy_signal.SIGINT) self.fire_in_main_thread = True - def _report_signal(self, n): - try: - w_handler = self.handlers_w[n] - except KeyError: - return # no handler, ignore signal - space = self.space - if not space.is_true(space.callable(w_handler)): - return # w_handler is SIG_IGN or SIG_DFL? - # re-install signal handler, for OSes that clear it - pypysig_reinstall(n) - # invoke the app-level handler - ec = space.getexecutioncontext() - w_frame = space.wrap(ec.gettopframe_nohidden()) - space.call_function(w_handler, space.wrap(n), w_frame) +# ____________________________________________________________ + + +class Handlers: + def __init__(self, space): + self.handlers_w = {} + +def _get_handlers(space): + return space.fromcache(Handlers).handlers_w + + +def report_signal(space, n): + handlers_w = _get_handlers(space) + try: + w_handler = handlers_w[n] + except KeyError: + return # no handler, ignore signal + if not space.is_true(space.callable(w_handler)): + return # w_handler is SIG_IGN or SIG_DFL? + # re-install signal handler, for OSes that clear it + pypysig_reinstall(n) + # invoke the app-level handler + ec = space.getexecutioncontext() + w_frame = space.wrap(ec.gettopframe_nohidden()) + space.call_function(w_handler, space.wrap(n), w_frame) @unwrap_spec(signum=int) @@ -141,9 +151,9 @@ check_signum_exists(space, signum) else: check_signum_in_range(space, signum) - action = space.check_signal_action - if signum in action.handlers_w: - return action.handlers_w[signum] + handlers_w = _get_handlers(space) + if signum in handlers_w: + return handlers_w[signum] return space.wrap(SIG_DFL) @@ -204,7 +214,6 @@ "main thread")) old_handler = getsignal(space, signum) - action = space.check_signal_action if space.eq_w(w_handler, space.wrap(SIG_DFL)): pypysig_default(signum) elif space.eq_w(w_handler, space.wrap(SIG_IGN)): @@ -215,7 +224,8 @@ space.wrap("'handler' must be a callable " "or SIG_DFL or SIG_IGN")) pypysig_setflag(signum) - action.handlers_w[signum] = w_handler + handlers_w = _get_handlers(space) + handlers_w[signum] = w_handler return old_handler From noreply at buildbot.pypy.org Fri Feb 1 19:09:55 2013 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 1 Feb 2013 19:09:55 +0100 (CET) Subject: [pypy-commit] pypy stm-thread-2: hg merge default Message-ID: <20130201180955.135A91C0134@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stm-thread-2 Changeset: r60810:fe07a7c23088 Date: 2013-02-01 16:29 +0100 http://bitbucket.org/pypy/pypy/changeset/fe07a7c23088/ Log: hg merge default diff --git a/lib-python/2.7/test/test_zipfile.py b/lib-python/2.7/test/test_zipfile.py --- a/lib-python/2.7/test/test_zipfile.py +++ b/lib-python/2.7/test/test_zipfile.py @@ -1213,6 +1213,17 @@ self.assertEqual(data1, '1'*FIXEDTEST_SIZE) self.assertEqual(data2, '2'*FIXEDTEST_SIZE) + def test_many_opens(self): + # Verify that read() and open() promptly close the file descriptor, + # and don't rely on the garbage collector to free resources. + with zipfile.ZipFile(TESTFN2, mode="r") as zipf: + for x in range(100): + zipf.read('ones') + with zipf.open('ones') as zopen1: + pass + for x in range(10): + self.assertLess(open('/dev/null').fileno(), 100) + def tearDown(self): unlink(TESTFN2) diff --git a/lib-python/2.7/zipfile.py b/lib-python/2.7/zipfile.py --- a/lib-python/2.7/zipfile.py +++ b/lib-python/2.7/zipfile.py @@ -475,9 +475,11 @@ # Search for universal newlines or line chunks. PATTERN = re.compile(r'^(?P[^\r\n]+)|(?P\n|\r\n?)') - def __init__(self, fileobj, mode, zipinfo, decrypter=None): + def __init__(self, fileobj, mode, zipinfo, decrypter=None, + close_fileobj=False): self._fileobj = fileobj self._decrypter = decrypter + self._close_fileobj = close_fileobj self._compress_type = zipinfo.compress_type self._compress_size = zipinfo.compress_size @@ -649,6 +651,12 @@ self._offset += len(data) return data + def close(self): + try: + if self._close_fileobj: + self._fileobj.close() + finally: + super(ZipExtFile, self).close() class ZipFile: @@ -866,7 +874,8 @@ def read(self, name, pwd=None): """Return file bytes (as a string) for name.""" - return self.open(name, "r", pwd).read() + with self.open(name, "r", pwd) as fp: + return fp.read() def open(self, name, mode="r", pwd=None): """Return file-like object for 'name'.""" @@ -889,8 +898,12 @@ zinfo = name else: # Get info object for name - zinfo = self.getinfo(name) - + try: + zinfo = self.getinfo(name) + except KeyError: + if not self._filePassed: + zef_file.close() + raise zef_file.seek(zinfo.header_offset, 0) # Skip the file header: @@ -904,6 +917,8 @@ zef_file.read(fheader[_FH_EXTRA_FIELD_LENGTH]) if fname != zinfo.orig_filename: + if not self._filePassed: + zef_file.close() raise BadZipfile, \ 'File name in directory "%s" and header "%s" differ.' % ( zinfo.orig_filename, fname) @@ -915,6 +930,8 @@ if not pwd: pwd = self.pwd if not pwd: + if not self._filePassed: + zef_file.close() raise RuntimeError, "File %s is encrypted, " \ "password required for extraction" % name @@ -933,9 +950,12 @@ # compare against the CRC otherwise check_byte = (zinfo.CRC >> 24) & 0xff if ord(h[11]) != check_byte: + if not self._filePassed: + zef_file.close() raise RuntimeError("Bad password for file", name) - return ZipExtFile(zef_file, mode, zinfo, zd) + return ZipExtFile(zef_file, mode, zinfo, zd, + close_fileobj=not self._filePassed) def extract(self, member, path=None, pwd=None): """Extract a member from the archive to the current working directory, @@ -993,7 +1013,7 @@ return targetpath source = self.open(member, pwd=pwd) - target = file(targetpath, "wb") + target = open(targetpath, "wb") shutil.copyfileobj(source, target) source.close() target.close() diff --git a/pypy/interpreter/executioncontext.py b/pypy/interpreter/executioncontext.py --- a/pypy/interpreter/executioncontext.py +++ b/pypy/interpreter/executioncontext.py @@ -45,6 +45,7 @@ def gettopframe(self): return self.topframeref() + @jit.unroll_safe def gettopframe_nohidden(self): frame = self.topframeref() while frame and frame.hide(): diff --git a/pypy/module/signal/interp_signal.py b/pypy/module/signal/interp_signal.py --- a/pypy/module/signal/interp_signal.py +++ b/pypy/module/signal/interp_signal.py @@ -60,7 +60,6 @@ def __init__(self, space): "NOT_RPYTHON" AsyncAction.__init__(self, space) - self.handlers_w = {} self.pending_signal = -1 self.fire_in_main_thread = False if self.space.config.objspace.usemodules.thread: @@ -91,7 +90,7 @@ # If we are in the main thread, report the signal now, # and poll more self.pending_signal = -1 - self._report_signal(n) + report_signal(self.space, n) n = self.pending_signal if n < 0: n = pypysig_poll() else: @@ -110,20 +109,31 @@ pypysig_pushback(cpy_signal.SIGINT) self.fire_in_main_thread = True - def _report_signal(self, n): - try: - w_handler = self.handlers_w[n] - except KeyError: - return # no handler, ignore signal - space = self.space - if not space.is_true(space.callable(w_handler)): - return # w_handler is SIG_IGN or SIG_DFL? - # re-install signal handler, for OSes that clear it - pypysig_reinstall(n) - # invoke the app-level handler - ec = space.getexecutioncontext() - w_frame = space.wrap(ec.gettopframe_nohidden()) - space.call_function(w_handler, space.wrap(n), w_frame) +# ____________________________________________________________ + + +class Handlers: + def __init__(self, space): + self.handlers_w = {} + +def _get_handlers(space): + return space.fromcache(Handlers).handlers_w + + +def report_signal(space, n): + handlers_w = _get_handlers(space) + try: + w_handler = handlers_w[n] + except KeyError: + return # no handler, ignore signal + if not space.is_true(space.callable(w_handler)): + return # w_handler is SIG_IGN or SIG_DFL? + # re-install signal handler, for OSes that clear it + pypysig_reinstall(n) + # invoke the app-level handler + ec = space.getexecutioncontext() + w_frame = space.wrap(ec.gettopframe_nohidden()) + space.call_function(w_handler, space.wrap(n), w_frame) @unwrap_spec(signum=int) @@ -141,9 +151,9 @@ check_signum_exists(space, signum) else: check_signum_in_range(space, signum) - action = space.check_signal_action - if signum in action.handlers_w: - return action.handlers_w[signum] + handlers_w = _get_handlers(space) + if signum in handlers_w: + return handlers_w[signum] return space.wrap(SIG_DFL) @@ -204,7 +214,6 @@ "main thread")) old_handler = getsignal(space, signum) - action = space.check_signal_action if space.eq_w(w_handler, space.wrap(SIG_DFL)): pypysig_default(signum) elif space.eq_w(w_handler, space.wrap(SIG_IGN)): @@ -215,7 +224,8 @@ space.wrap("'handler' must be a callable " "or SIG_DFL or SIG_IGN")) pypysig_setflag(signum) - action.handlers_w[signum] = w_handler + handlers_w = _get_handlers(space) + handlers_w[signum] = w_handler return old_handler diff --git a/rpython/translator/c/src/profiling.c b/rpython/translator/c/src/profiling.c --- a/rpython/translator/c/src/profiling.c +++ b/rpython/translator/c/src/profiling.c @@ -8,8 +8,8 @@ #include #endif -cpu_set_t base_cpu_set; -int profiling_setup = 0; +static cpu_set_t base_cpu_set; +static int profiling_setup = 0; void pypy_setup_profiling() { @@ -37,8 +37,8 @@ #include -DWORD_PTR base_affinity_mask; -int profiling_setup = 0; +static DWORD_PTR base_affinity_mask; +static int profiling_setup = 0; void pypy_setup_profiling() { if (!profiling_setup) { diff --git a/rpython/translator/platform/__init__.py b/rpython/translator/platform/__init__.py --- a/rpython/translator/platform/__init__.py +++ b/rpython/translator/platform/__init__.py @@ -53,9 +53,18 @@ ofiles = self._compile_o_files(cfiles, eci, standalone) return self._finish_linking(ofiles, eci, outputfilename, standalone) + def _all_cfiles(self, cfiles, eci): + seen = set() + result = [] + for cfile in list(cfiles) + list(eci.separate_module_files): + cfile = py.path.local(cfile) + if cfile not in seen: + seen.add(cfile) + result.append(cfile) + return result + def _compile_o_files(self, cfiles, eci, standalone=True): - cfiles = [py.path.local(f) for f in cfiles] - cfiles += [py.path.local(f) for f in eci.separate_module_files] + cfiles = self._all_cfiles(cfiles, eci) compile_args = self._compile_args_from_eci(eci, standalone) ofiles = [] for cfile in cfiles: diff --git a/rpython/translator/platform/posix.py b/rpython/translator/platform/posix.py --- a/rpython/translator/platform/posix.py +++ b/rpython/translator/platform/posix.py @@ -84,8 +84,7 @@ def gen_makefile(self, cfiles, eci, exe_name=None, path=None, shared=False): - cfiles = [py.path.local(f) for f in cfiles] - cfiles += [py.path.local(f) for f in eci.separate_module_files] + cfiles = self._all_cfiles(cfiles, eci) if path is None: path = cfiles[0].dirpath() diff --git a/rpython/translator/platform/windows.py b/rpython/translator/platform/windows.py --- a/rpython/translator/platform/windows.py +++ b/rpython/translator/platform/windows.py @@ -248,8 +248,7 @@ def gen_makefile(self, cfiles, eci, exe_name=None, path=None, shared=False): - cfiles = [py.path.local(f) for f in cfiles] - cfiles += [py.path.local(f) for f in eci.separate_module_files] + cfiles = self._all_cfiles(cfiles, eci) if path is None: path = cfiles[0].dirpath() From noreply at buildbot.pypy.org Fri Feb 1 19:09:56 2013 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 1 Feb 2013 19:09:56 +0100 (CET) Subject: [pypy-commit] pypy default: Test and fix for trying to iterate over __pypy__.identity_dict() and Message-ID: <20130201180956.5B0061C009B@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r60811:d80baf6feebf Date: 2013-02-01 19:09 +0100 http://bitbucket.org/pypy/pypy/changeset/d80baf6feebf/ Log: Test and fix for trying to iterate over __pypy__.identity_dict() and getting strange results. diff --git a/pypy/module/__pypy__/interp_identitydict.py b/pypy/module/__pypy__/interp_identitydict.py --- a/pypy/module/__pypy__/interp_identitydict.py +++ b/pypy/module/__pypy__/interp_identitydict.py @@ -33,6 +33,11 @@ except KeyError: raise OperationError(space.w_KeyError, w_key) + def descr_iter(self, space): + raise OperationError(space.w_TypeError, + space.wrap("'identity_dict' object does not support iteration; " + "iterate over x.keys()")) + def get(self, space, w_key, w_default=None): if w_default is None: w_default = space.w_None @@ -50,8 +55,11 @@ W_IdentityDict.typedef = TypeDef("identity_dict", __doc__="""\ A dictionary that considers keys by object identity. -Distinct objects that compare equal will have separate entries. -All objects can be used as keys, even non-hashable ones. +Distinct objects will have separate entries even if they +compare equal. All objects can be used as keys, even +non-hashable ones --- but avoid using immutable objects +like integers: two int objects 42 may or may not be +internally the same object. """, __new__ = interp2app(W_IdentityDict.descr_new.im_func), __len__ = interp2app(W_IdentityDict.descr_len), @@ -59,6 +67,7 @@ __setitem__ = interp2app(W_IdentityDict.descr_setitem), __getitem__ = interp2app(W_IdentityDict.descr_getitem), __delitem__ = interp2app(W_IdentityDict.descr_delitem), + __iter__ = interp2app(W_IdentityDict.descr_iter), get = interp2app(W_IdentityDict.get), keys = interp2app(W_IdentityDict.keys), values = interp2app(W_IdentityDict.values), diff --git a/pypy/module/__pypy__/test/test_identitydict.py b/pypy/module/__pypy__/test/test_identitydict.py --- a/pypy/module/__pypy__/test/test_identitydict.py +++ b/pypy/module/__pypy__/test/test_identitydict.py @@ -56,3 +56,10 @@ assert None in d assert [] not in d + + def test_iterate(self): + from __pypy__ import identity_dict + d = identity_dict() + d[None] = 1 + raises(TypeError, iter, d) + raises(TypeError, list, d) From noreply at buildbot.pypy.org Fri Feb 1 20:46:59 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Fri, 1 Feb 2013 20:46:59 +0100 (CET) Subject: [pypy-commit] pypy py3k: translation fix Message-ID: <20130201194659.544A81C009B@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r60812:bed57119d110 Date: 2013-02-01 11:46 -0800 http://bitbucket.org/pypy/pypy/changeset/bed57119d110/ Log: translation fix diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -1508,8 +1508,7 @@ ) raise w_fd = self.call_function(w_fileno) - if (not self.isinstance_w(w_fd, self.w_int) and - not self.isinstance_w(w_fd, self.w_long)): + if not self.isinstance_w(w_fd, self.w_int): raise OperationError(self.w_TypeError, self.wrap("fileno() returned a non-integer") ) From noreply at buildbot.pypy.org Fri Feb 1 21:05:05 2013 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 1 Feb 2013 21:05:05 +0100 (CET) Subject: [pypy-commit] pypy missing-ndarray-attributes: make those staticmethods again Message-ID: <20130201200505.2CE591C009B@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: missing-ndarray-attributes Changeset: r60813:8f8c69368f76 Date: 2013-02-01 22:04 +0200 http://bitbucket.org/pypy/pypy/changeset/8f8c69368f76/ Log: make those staticmethods again diff --git a/pypy/module/micronumpy/types.py b/pypy/module/micronumpy/types.py --- a/pypy/module/micronumpy/types.py +++ b/pypy/module/micronumpy/types.py @@ -383,7 +383,7 @@ def str_format(self, box): return str(self.for_computation(self.unbox(box))) - #@staticmethod #v can be all kinds of int + @staticmethod def for_computation(self, v): return widen(v) @@ -649,7 +649,7 @@ return float2string(self.for_computation(self.unbox(box)), "g", rfloat.DTSF_STR_PRECISION) - #@staticmethod #v can be a longfloat + @staticmethod def for_computation(self, v): return float(v) @@ -966,6 +966,7 @@ fval = unpack_float(s, native_is_bigendian) return self.box(fval) + @staticmethod def for_computation(self, v): return float(v) @@ -1070,6 +1071,7 @@ op = '+' if imag >= 0 else '' return ''.join(['(', real_str, op, imag_str, ')']) + @staticmethod def for_computation(self, v): return float(v[0]), float(v[1]) From noreply at buildbot.pypy.org Sat Feb 2 14:09:13 2013 From: noreply at buildbot.pypy.org (fijal) Date: Sat, 2 Feb 2013 14:09:13 +0100 (CET) Subject: [pypy-commit] pypy missing-ndarray-attributes: * support staticmethods on mixins Message-ID: <20130202130913.9E1B01C018D@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: missing-ndarray-attributes Changeset: r60814:ea7b827e513f Date: 2013-02-02 15:08 +0200 http://bitbucket.org/pypy/pypy/changeset/ea7b827e513f/ Log: * support staticmethods on mixins * make sure sorting is RPython diff --git a/pypy/module/micronumpy/arrayimpl/sort.py b/pypy/module/micronumpy/arrayimpl/sort.py --- a/pypy/module/micronumpy/arrayimpl/sort.py +++ b/pypy/module/micronumpy/arrayimpl/sort.py @@ -5,7 +5,6 @@ from rpython.rtyper.lltypesystem import rffi, lltype from rpython.rlib.listsort import make_timsort_class -from rpython.rlib.objectmodel import specialize from rpython.rlib.rawstorage import raw_storage_getitem, raw_storage_setitem, \ free_raw_storage, alloc_raw_storage from pypy.interpreter.error import OperationError @@ -15,7 +14,6 @@ INT_SIZE = rffi.sizeof(lltype.Signed) - at specialize.memo() def make_sort_classes(space, itemtype): TP = itemtype.T @@ -81,10 +79,9 @@ return ArgArrayRepresentation, ArgSort def argsort_array(arr, space, w_axis): + space.fromcache(SortCache) # that populates SortClasses itemtype = arr.dtype.itemtype - if (not isinstance(itemtype, types.Float) and - not isinstance(itemtype, types.Integer) and - not isinstance(itemtype, types.ComplexFloating)): + if itemtype.Sort is None: # XXX this should probably be changed raise OperationError(space.w_NotImplementedError, space.wrap("sorting of non-numeric types " + \ @@ -98,6 +95,8 @@ axis = -1 else: axis = space.int_w(w_axis) + Repr = itemtype.SortRepr + Sort = itemtype.Sort itemsize = itemtype.get_element_size() # create array of indexes dtype = interp_dtype.get_dtype_cache(space).w_longdtype @@ -106,7 +105,6 @@ if len(arr.get_shape()) == 1: for i in range(arr.get_size()): raw_storage_setitem(storage, i * INT_SIZE, i) - Repr, Sort = make_sort_classes(space, itemtype) r = Repr(INT_SIZE, itemsize, arr.get_size(), arr.get_storage(), storage, 0, arr.start) Sort(r).sort() @@ -124,7 +122,6 @@ stride_size = arr.strides[axis] index_stride_size = index_impl.strides[axis] axis_size = arr.shape[axis] - Repr, Sort = make_sort_classes(space, itemtype) while not iter.done(): for i in range(axis_size): raw_storage_setitem(storage, i * index_stride_size + @@ -135,3 +132,16 @@ iter.next() index_iter.next() return index_arr + +class SortCache(object): + built = False + + def __init__(self, space): + if self.built: + return + for cls in types.all_float_types: + cls.SortRepr, cls.Sort = make_sort_classes(space, cls) + for cls in types.all_int_types: + cls.SortRepr, cls.Sort = make_sort_classes(space, cls) + for cls in types.all_complex_types: + cls.SortRepr, cls.Sort = make_sort_classes(space, cls) diff --git a/pypy/module/micronumpy/types.py b/pypy/module/micronumpy/types.py --- a/pypy/module/micronumpy/types.py +++ b/pypy/module/micronumpy/types.py @@ -115,6 +115,9 @@ class BaseType(object): _attrs_ = () + SortRepr = None # placeholders for sorting classes, overloaded in sort.py + Sort = None + def _unimplemented_ufunc(self, *args): raise NotImplementedError @@ -384,7 +387,7 @@ return str(self.for_computation(self.unbox(box))) @staticmethod - def for_computation(self, v): + def for_computation(v): return widen(v) def default_fromstring(self, space): @@ -650,7 +653,7 @@ rfloat.DTSF_STR_PRECISION) @staticmethod - def for_computation(self, v): + def for_computation(v): return float(v) def default_fromstring(self, space): @@ -951,7 +954,9 @@ swapped_value = byteswap(rffi.cast(self.T, value)) raw_storage_setitem(storage, i + offset, swapped_value) -class Float16(BaseType, Float): +class BaseFloat16(Float): + _mixin_ = True + _attrs_ = () _STORAGE_T = rffi.USHORT T = rffi.DOUBLE @@ -966,13 +971,16 @@ fval = unpack_float(s, native_is_bigendian) return self.box(fval) - @staticmethod - def for_computation(self, v): - return float(v) - def default_fromstring(self, space): return self.box(-1.0) + def byteswap(self, w_v): + value = self.unbox(w_v) + hbits = float_pack(value,2) + swapped = byteswap(rffi.cast(self._STORAGE_T, hbits)) + return self.box(float_unpack(r_ulonglong(swapped), 2)) + +class Float16(BaseType, BaseFloat16): def _read(self, storage, i, offset): hbits = raw_storage_getitem(self._STORAGE_T, storage, i + offset) return float_unpack(r_ulonglong(hbits), 2) @@ -980,18 +988,9 @@ def _write(self, storage, i, offset, value): hbits = float_pack(value,2) raw_storage_setitem(storage, i + offset, - rffi.cast(self._STORAGE_T, hbits)) + rffi.cast(self._STORAGE_T, hbits)) - def byteswap(self, w_v): - value = self.unbox(w_v) - hbits = float_pack(value,2) - swapped = byteswap(rffi.cast(self._STORAGE_T, hbits)) - return self.box(float_unpack(r_ulonglong(swapped), 2)) - -class NonNativeFloat16(Float16): - _attrs_ = () - BoxType = interp_boxes.W_Float16Box - +class NonNativeFloat16(BaseType, BaseFloat16): def _read(self, storage, i, offset): hbits = raw_storage_getitem(self._STORAGE_T, storage, i + offset) return float_unpack(r_ulonglong(byteswap(hbits)), 2) @@ -1072,7 +1071,7 @@ return ''.join(['(', real_str, op, imag_str, ')']) @staticmethod - def for_computation(self, v): + def for_computation(v): return float(v[0]), float(v[1]) def read_bool(self, arr, i, offset): @@ -1607,8 +1606,7 @@ pack_float80(result, value, 16, not native_is_bigendian) return self.box(unpack_float128(result.build(), native_is_bigendian)) - class NonNativeFloat128(Float128): - pass + NonNativeFloat128 = Float128 class Complex256(ComplexFloating, BaseType): _attrs_ = () @@ -1756,10 +1754,20 @@ break del tp +all_float_types = [] +all_int_types = [] +all_complex_types = [] + def _setup(): # compute alignment for tp in globals().values(): if isinstance(tp, type) and hasattr(tp, 'T'): tp.alignment = clibffi.cast_type_to_ffitype(tp.T).c_alignment + if issubclass(tp, Float): + all_float_types.append(tp) + if issubclass(tp, Integer): + all_int_types.append(tp) + if issubclass(tp, ComplexFloating): + all_complex_types.append(tp) _setup() del _setup diff --git a/rpython/annotator/bookkeeper.py b/rpython/annotator/bookkeeper.py --- a/rpython/annotator/bookkeeper.py +++ b/rpython/annotator/bookkeeper.py @@ -447,7 +447,7 @@ if (x is type(None) or # add cases here if needed x.__module__ == 'rpython.rtyper.lltypesystem.lltype'): result = SomeType() - elif getattr(x, '_mixin_', False): + elif x.__dict__.get('_mixin_', False): raise Exception("Creating a PBC of a mixin class is not RPython") else: result = SomePBC([self.getdesc(x)]) diff --git a/rpython/annotator/description.py b/rpython/annotator/description.py --- a/rpython/annotator/description.py +++ b/rpython/annotator/description.py @@ -4,7 +4,7 @@ from rpython.flowspace.model import Constant, FunctionGraph from rpython.flowspace.bytecode import cpython_code_signature from rpython.flowspace.argument import rawshape, ArgErr -from rpython.tool.sourcetools import valid_identifier +from rpython.tool.sourcetools import valid_identifier, func_with_new_name from rpython.tool.pairtype import extendabletype class CallFamily(object): @@ -495,6 +495,10 @@ # that the py lib has its own AssertionError.__init__ which # is of type FunctionType. But bookkeeper.immutablevalue() # will do the right thing in s_get_value(). + if isinstance(value, staticmethod) and mixin: + # make a new copy of staticmethod + value = staticmethod(func_with_new_name(value.__func__, + value.__func__.__name__)) if type(value) in MemberDescriptorTypes: # skip __slots__, showing up in the class as 'member' objects diff --git a/rpython/annotator/test/test_annrpython.py b/rpython/annotator/test/test_annrpython.py --- a/rpython/annotator/test/test_annrpython.py +++ b/rpython/annotator/test/test_annrpython.py @@ -2359,6 +2359,41 @@ assert isinstance(s.items[1], annmodel.SomeChar) assert isinstance(s.items[2], annmodel.SomeChar) + def test_mixin_staticmethod(self): + class Mixin(object): + _mixin_ = True + + @staticmethod + def m(v): + return v + + class Base(object): + pass + + class A(Base, Mixin): + pass + + class B(Base, Mixin): + pass + + class C(B): + pass + + def f(): + a = A() + v0 = a.m(2) + b = B() + v1 = b.m('x') + c = C() + v2 = c.m('y') + return v0, v1, v2 + + a = self.RPythonAnnotator() + s = a.build_types(f, []) + assert isinstance(s.items[0], annmodel.SomeInteger) + assert isinstance(s.items[1], annmodel.SomeChar) + assert isinstance(s.items[2], annmodel.SomeChar) + def test_mixin_first(self): class Mixin(object): _mixin_ = True From noreply at buildbot.pypy.org Sat Feb 2 14:59:44 2013 From: noreply at buildbot.pypy.org (fijal) Date: Sat, 2 Feb 2013 14:59:44 +0100 (CET) Subject: [pypy-commit] pypy missing-ndarray-attributes: some fight with RPython Message-ID: <20130202135944.070301C0246@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: missing-ndarray-attributes Changeset: r60815:a719407593e5 Date: 2013-02-02 15:59 +0200 http://bitbucket.org/pypy/pypy/changeset/a719407593e5/ Log: some fight with RPython diff --git a/pypy/module/micronumpy/arrayimpl/sort.py b/pypy/module/micronumpy/arrayimpl/sort.py --- a/pypy/module/micronumpy/arrayimpl/sort.py +++ b/pypy/module/micronumpy/arrayimpl/sort.py @@ -7,6 +7,8 @@ from rpython.rlib.listsort import make_timsort_class from rpython.rlib.rawstorage import raw_storage_getitem, raw_storage_setitem, \ free_raw_storage, alloc_raw_storage +from rpython.rlib.unroll import unrolling_iterable +from rpython.rlib.objectmodel import specialize from pypy.interpreter.error import OperationError from pypy.module.micronumpy.base import W_NDimArray from pypy.module.micronumpy import interp_dtype, types @@ -14,10 +16,10 @@ INT_SIZE = rffi.sizeof(lltype.Signed) -def make_sort_classes(space, itemtype): +def make_sort_function(space, itemtype): TP = itemtype.T - class ArgArrayRepresentation(object): + class Repr(object): def __init__(self, index_stride_size, stride_size, size, values, indexes, index_start, start): self.index_stride_size = index_stride_size @@ -41,14 +43,15 @@ self.start, rffi.cast(TP, item[0])) raw_storage_setitem(self.indexes, idx * self.index_stride_size + self.index_start, item[1]) - class ArgArrayRepWithStorage(ArgArrayRepresentation): + + class ArgArrayRepWithStorage(Repr): def __init__(self, index_stride_size, stride_size, size): start = 0 dtype = interp_dtype.get_dtype_cache(space).w_longdtype self.indexes = dtype.itemtype.malloc(size*dtype.get_size()) self.values = alloc_raw_storage(size*rffi.sizeof(TP), track_allocation=False) - ArgArrayRepresentation.__init__(self, index_stride_size, stride_size, - size, self.values, self.indexes, start, start) + Repr.__init__(self, index_stride_size, stride_size, + size, self.values, self.indexes, start, start) def __del__(self): free_raw_storage(self.indexes, track_allocation=False) @@ -76,62 +79,69 @@ ArgSort = make_timsort_class(arg_getitem, arg_setitem, arg_length, arg_getitem_slice, arg_lt) - return ArgArrayRepresentation, ArgSort + def argsort(arr, space, w_axis, itemsize): + if w_axis is space.w_None: + # note that it's fine ot pass None here as we're not going + # to pass the result around (None is the link to base in slices) + arr = arr.reshape(space, None, [arr.get_size()]) + axis = 0 + elif w_axis is None: + axis = -1 + else: + axis = space.int_w(w_axis) + # create array of indexes + dtype = interp_dtype.get_dtype_cache(space).w_longdtype + index_arr = W_NDimArray.from_shape(arr.get_shape(), dtype) + storage = index_arr.implementation.get_storage() + if len(arr.get_shape()) == 1: + for i in range(arr.get_size()): + raw_storage_setitem(storage, i * INT_SIZE, i) + r = Repr(INT_SIZE, itemsize, arr.get_size(), arr.get_storage(), + storage, 0, arr.start) + ArgSort(r).sort() + else: + shape = arr.get_shape() + if axis < 0: + axis = len(shape) + axis - 1 + if axis < 0 or axis > len(shape): + raise OperationError(space.w_IndexError, space.wrap( + "Wrong axis %d" % axis)) + iterable_shape = shape[:axis] + [0] + shape[axis + 1:] + iter = AxisIterator(arr, iterable_shape, axis, False) + index_impl = index_arr.implementation + index_iter = AxisIterator(index_impl, iterable_shape, axis, False) + stride_size = arr.strides[axis] + index_stride_size = index_impl.strides[axis] + axis_size = arr.shape[axis] + while not iter.done(): + for i in range(axis_size): + raw_storage_setitem(storage, i * index_stride_size + + index_iter.offset, i) + r = Repr(index_stride_size, stride_size, axis_size, + arr.get_storage(), storage, index_iter.offset, iter.offset) + ArgSort(r).sort() + iter.next() + index_iter.next() + return index_arr + + return argsort def argsort_array(arr, space, w_axis): - space.fromcache(SortCache) # that populates SortClasses + cache = space.fromcache(SortCache) # that populates SortClasses itemtype = arr.dtype.itemtype - if itemtype.Sort is None: - # XXX this should probably be changed - raise OperationError(space.w_NotImplementedError, - space.wrap("sorting of non-numeric types " + \ - "'%s' is not implemented" % arr.dtype.get_name(), )) - if w_axis is space.w_None: - # note that it's fine ot pass None here as we're not going - # to pass the result around (None is the link to base in slices) - arr = arr.reshape(space, None, [arr.get_size()]) - axis = 0 - elif w_axis is None: - axis = -1 - else: - axis = space.int_w(w_axis) - Repr = itemtype.SortRepr - Sort = itemtype.Sort - itemsize = itemtype.get_element_size() - # create array of indexes - dtype = interp_dtype.get_dtype_cache(space).w_longdtype - index_arr = W_NDimArray.from_shape(arr.get_shape(), dtype) - storage = index_arr.implementation.get_storage() - if len(arr.get_shape()) == 1: - for i in range(arr.get_size()): - raw_storage_setitem(storage, i * INT_SIZE, i) - r = Repr(INT_SIZE, itemsize, arr.get_size(), arr.get_storage(), - storage, 0, arr.start) - Sort(r).sort() - else: - shape = arr.get_shape() - if axis < 0: - axis = len(shape) + axis - 1 - if axis < 0 or axis > len(shape): - raise OperationError(space.w_IndexError, space.wrap( - "Wrong axis %d" % axis)) - iterable_shape = shape[:axis] + [0] + shape[axis + 1:] - iter = AxisIterator(arr, iterable_shape, axis, False) - index_impl = index_arr.implementation - index_iter = AxisIterator(index_impl, iterable_shape, axis, False) - stride_size = arr.strides[axis] - index_stride_size = index_impl.strides[axis] - axis_size = arr.shape[axis] - while not iter.done(): - for i in range(axis_size): - raw_storage_setitem(storage, i * index_stride_size + - index_iter.offset, i) - r = Repr(index_stride_size, stride_size, axis_size, - arr.get_storage(), storage, index_iter.offset, iter.offset) - Sort(r).sort() - iter.next() - index_iter.next() - return index_arr + for tp in all_types: + if isinstance(itemtype, tp): + return cache._lookup(tp)(arr, space, w_axis, + itemtype.get_element_size()) + # XXX this should probably be changed + raise OperationError(space.w_NotImplementedError, + space.wrap("sorting of non-numeric types " + \ + "'%s' is not implemented" % arr.dtype.get_name(), )) + +all_types = (types.all_int_types + types.all_complex_types + + types.all_float_types) +all_types = [i for i in all_types if not '_mixin_' in i.__dict__] +all_types = unrolling_iterable(all_types) class SortCache(object): built = False @@ -139,9 +149,9 @@ def __init__(self, space): if self.built: return - for cls in types.all_float_types: - cls.SortRepr, cls.Sort = make_sort_classes(space, cls) - for cls in types.all_int_types: - cls.SortRepr, cls.Sort = make_sort_classes(space, cls) - for cls in types.all_complex_types: - cls.SortRepr, cls.Sort = make_sort_classes(space, cls) + self.built = True + cache = {} + for cls in all_types._items: + cache[cls] = make_sort_function(space, cls) + self.cache = cache + self._lookup = specialize.memo()(lambda tp : cache[tp]) diff --git a/pypy/module/micronumpy/test/test_zjit.py b/pypy/module/micronumpy/test/test_zjit.py --- a/pypy/module/micronumpy/test/test_zjit.py +++ b/pypy/module/micronumpy/test/test_zjit.py @@ -476,24 +476,6 @@ 'jump': 1, 'raw_store': 1}) - def define_count_nonzero(): - return """ - a = [[0, 2, 3, 4], [5, 6, 0, 8], [9, 10, 11, 0]] - count_nonzero(a) - """ - - def test_count_nonzero(self): - result = self.run("count_nonzero") - assert result == 9 - self.check_simple_loop({'setfield_gc': 3, - 'raw_load': 1, - 'guard_false': 1, - 'jump': 1, - 'int_ge': 1, - 'new_with_vtable': 1, - 'int_add': 2, - 'float_ne': 1}) - def define_argsort(): return """ a = |30| From noreply at buildbot.pypy.org Sat Feb 2 15:26:51 2013 From: noreply at buildbot.pypy.org (fijal) Date: Sat, 2 Feb 2013 15:26:51 +0100 (CET) Subject: [pypy-commit] pypy default: kill few lines of hacks here - net result named tuple >2x faster Message-ID: <20130202142651.D70371C009B@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r60816:4237a1dca2e8 Date: 2013-02-02 16:25 +0200 http://bitbucket.org/pypy/pypy/changeset/4237a1dca2e8/ Log: kill few lines of hacks here - net result named tuple >2x faster diff --git a/lib-python/2.7/collections.py b/lib-python/2.7/collections.py --- a/lib-python/2.7/collections.py +++ b/lib-python/2.7/collections.py @@ -6,7 +6,6 @@ __all__ += _abcoll.__all__ from _collections import deque, defaultdict -from operator import itemgetter as _itemgetter from keyword import iskeyword as _iskeyword import sys as _sys import heapq as _heapq @@ -298,7 +297,7 @@ _fields = %(field_names)r \n def __new__(_cls, %(argtxt)s): 'Create new instance of %(typename)s(%(argtxt)s)' - return _tuple.__new__(_cls, (%(argtxt)s)) \n + return tuple.__new__(_cls, (%(argtxt)s)) \n @classmethod def _make(cls, iterable, new=tuple.__new__, len=len): 'Make a new %(typename)s object from a sequence or iterable' @@ -323,14 +322,13 @@ 'Return self as a plain tuple. Used by copy and pickle.' return tuple(self) \n\n''' % locals() for i, name in enumerate(field_names): - template += " %s = _property(_itemgetter(%d), doc='Alias for field number %d')\n" % (name, i, i) + template += " %s = property(lambda self: self[%d], doc='Alias for field number %d')\n" % (name, i, i) if verbose: print template # Execute the template string in a temporary namespace and # support tracing utilities by setting a value for frame.f_globals['__name__'] - namespace = dict(_itemgetter=_itemgetter, __name__='namedtuple_%s' % typename, - OrderedDict=OrderedDict, _property=property, _tuple=tuple) + namespace = {'__name__': 'namedtuple_%s' % typename} try: exec template in namespace except SyntaxError, e: From noreply at buildbot.pypy.org Sat Feb 2 16:29:15 2013 From: noreply at buildbot.pypy.org (hakanardo) Date: Sat, 2 Feb 2013 16:29:15 +0100 (CET) Subject: [pypy-commit] benchmarks default: reenable the scimark benchmarks and lower their cycle count to give resonable runtimes without the jit Message-ID: <20130202152915.9D4D31C0246@cobra.cs.uni-duesseldorf.de> Author: Hakan Ardo Branch: Changeset: r195:2aeb622f9679 Date: 2013-02-02 16:26 +0100 http://bitbucket.org/pypy/benchmarks/changeset/2aeb622f9679/ Log: reenable the scimark benchmarks and lower their cycle count to give resonable runtimes without the jit diff --git a/benchmarks.py b/benchmarks.py --- a/benchmarks.py +++ b/benchmarks.py @@ -186,22 +186,22 @@ BM_cpython_doc.benchmark_name = 'sphinx' -if 0: +if 1: _register_new_bm('scimark', 'scimark_SOR', globals(), - extra_args=['--benchmark=SOR', '100', '3276', 'Array2D']) + extra_args=['--benchmark=SOR', '100', '50', 'Array2D']) #_register_new_bm('scimark', 'scimark_SOR_large', globals(), # extra_args=['--benchmark=SOR', '1000', '25', 'Array2D']) _register_new_bm('scimark', 'scimark_SparseMatMult', globals(), - extra_args=['--benchmark=SparseMatMult', '1000', '50000', '26214']) + extra_args=['--benchmark=SparseMatMult', '1000', '50000', '200']) #_register_new_bm('scimark', 'scimark_SparseMatMult_large', globals(), # extra_args=['--benchmark=SparseMatMult', '100000', '1000000', '102']) _register_new_bm('scimark', 'scimark_MonteCarlo', globals(), - extra_args=['--benchmark=MonteCarlo', '26843545']) + extra_args=['--benchmark=MonteCarlo', '500000']) _register_new_bm('scimark', 'scimark_LU', globals(), - extra_args=['--benchmark=LU', '100', '409']) + extra_args=['--benchmark=LU', '100', '5']) #_register_new_bm('scimark', 'scimark_LU_large', globals(), # extra_args=['--benchmark=LU', '1000', '1']) _register_new_bm('scimark', 'scimark_FFT', globals(), - extra_args=['--benchmark=FFT', '1024', '3276']) + extra_args=['--benchmark=FFT', '1024', '100']) #_register_new_bm('scimark', 'scimark_FFT_large', globals(), # extra_args=['--benchmark=FFT', '1048576', '1']) From noreply at buildbot.pypy.org Sat Feb 2 16:35:02 2013 From: noreply at buildbot.pypy.org (fijal) Date: Sat, 2 Feb 2013 16:35:02 +0100 (CET) Subject: [pypy-commit] pypy incremental-nursery-cleanup: oops Message-ID: <20130202153502.2DF9C1C0250@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: incremental-nursery-cleanup Changeset: r60817:041883f05de2 Date: 2013-02-02 17:34 +0200 http://bitbucket.org/pypy/pypy/changeset/041883f05de2/ Log: oops diff --git a/rpython/rtyper/memory/gc/minimark.py b/rpython/rtyper/memory/gc/minimark.py --- a/rpython/rtyper/memory/gc/minimark.py +++ b/rpython/rtyper/memory/gc/minimark.py @@ -1298,6 +1298,7 @@ self.debug_rotate_nursery() self.nursery_free = self.nursery self.nursery_top = self.nursery + self.nursery_cleanup + self.nursery_real_top = self.nursery + self.nursery_size # debug_print("minor collect, total memory used:", self.get_total_memory_used()) From noreply at buildbot.pypy.org Sat Feb 2 16:53:16 2013 From: noreply at buildbot.pypy.org (fijal) Date: Sat, 2 Feb 2013 16:53:16 +0100 (CET) Subject: [pypy-commit] pypy incremental-nursery-cleanup: a seriou soops Message-ID: <20130202155316.24D711C018D@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: incremental-nursery-cleanup Changeset: r60818:23f2ba42a953 Date: 2013-02-02 17:52 +0200 http://bitbucket.org/pypy/pypy/changeset/23f2ba42a953/ Log: a seriou soops diff --git a/rpython/rtyper/memory/gc/minimark.py b/rpython/rtyper/memory/gc/minimark.py --- a/rpython/rtyper/memory/gc/minimark.py +++ b/rpython/rtyper/memory/gc/minimark.py @@ -356,7 +356,7 @@ newsize = minsize nursery_cleanup = env.read_from_env('PYPY_GC_NURSERY_CLEANUP') - if nursery_cleanup >= 0: + if nursery_cleanup > 0: self.nursery_cleanup = nursery_cleanup # major_coll = env.read_float_from_env('PYPY_GC_MAJOR_COLLECT') @@ -410,8 +410,8 @@ self.nursery = self._alloc_nursery() # the current position in the nursery: self.nursery_free = self.nursery + self.nursery_top = self.nursery + self.nursery_cleanup # the end of the nursery: - self.nursery_top = self.nursery + self.nursery_cleanup self.nursery_real_top = self.nursery + self.nursery_size # initialize the threshold self.min_heap_size = max(self.min_heap_size, self.nursery_size * @@ -598,7 +598,7 @@ if gen > 0: self.major_collection() - def move_nursery_top_and_malloc(self, totalsize): + def move_nursery_top(self, totalsize): llarena.arena_reset(self.nursery_top, self.nursery_cleanup, 2) self.nursery_top += self.nursery_cleanup @@ -611,8 +611,9 @@ and finally reserve 'totalsize' bytes at the start of the now-empty nursery. """ - if self.nursery_top < self.nursery_real_top: - self.move_nursery_top_and_malloc(totalsize) + if (self.nursery_top < self.nursery_real_top and + self.nursery_free < self.nursery_real_top): + self.move_nursery_top(totalsize) return prev_result self.minor_collection() # From noreply at buildbot.pypy.org Sat Feb 2 17:25:05 2013 From: noreply at buildbot.pypy.org (fijal) Date: Sat, 2 Feb 2013 17:25:05 +0100 (CET) Subject: [pypy-commit] pypy incremental-nursery-cleanup: fixes for set_extra_threshold and env handline Message-ID: <20130202162505.6429C1C018D@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: incremental-nursery-cleanup Changeset: r60819:3f4784f0a11a Date: 2013-02-02 18:24 +0200 http://bitbucket.org/pypy/pypy/changeset/3f4784f0a11a/ Log: fixes for set_extra_threshold and env handline diff --git a/rpython/rtyper/memory/gc/minimark.py b/rpython/rtyper/memory/gc/minimark.py --- a/rpython/rtyper/memory/gc/minimark.py +++ b/rpython/rtyper/memory/gc/minimark.py @@ -357,6 +357,8 @@ nursery_cleanup = env.read_from_env('PYPY_GC_NURSERY_CLEANUP') if nursery_cleanup > 0: + if nursery_cleanup < self.nonlarge_max + 1: + nursery_cleanup = self.nonlarge_max + 1 self.nursery_cleanup = nursery_cleanup # major_coll = env.read_float_from_env('PYPY_GC_MAJOR_COLLECT') @@ -599,8 +601,10 @@ self.major_collection() def move_nursery_top(self, totalsize): - llarena.arena_reset(self.nursery_top, self.nursery_cleanup, 2) - self.nursery_top += self.nursery_cleanup + size = min(self.nursery_real_top - self.nursery_top, + self.nursery_cleanup) + llarena.arena_reset(self.nursery_top, size, 2) + self.nursery_top += size def collect_and_reserve(self, prev_result, totalsize): """To call when nursery_free overflows nursery_top. @@ -611,8 +615,7 @@ and finally reserve 'totalsize' bytes at the start of the now-empty nursery. """ - if (self.nursery_top < self.nursery_real_top and - self.nursery_free < self.nursery_real_top): + if self.nursery_top < self.nursery_real_top: self.move_nursery_top(totalsize) return prev_result self.minor_collection() @@ -623,7 +626,7 @@ # The nursery might not be empty now, because of # execute_finalizers(). If it is almost full again, # we need to fix it with another call to minor_collection(). - if self.nursery_free + totalsize > self.nursery_top: + if self.nursery_free + totalsize > self.nursery_real_top: self.minor_collection() # result = self.nursery_free @@ -786,6 +789,7 @@ if self.next_major_collection_threshold < 0: # cannot trigger a full collection now, but we can ensure # that one will occur very soon + self.nursery_top = self.nursery_real_top self.nursery_free = self.nursery_real_top def can_malloc_nonmovable(self): @@ -1859,10 +1863,13 @@ ll_assert(reserved_size <= self.nonlarge_max, "set_extra_threshold: too big!") diff = reserved_size - self.extra_threshold - if diff > 0 and self.nursery_free + diff > self.nursery_real_top: + if (diff > 0 and self.nursery_free + diff > self.nursery_real_top and + self.nursery_top == self.nursery_real_top): self.minor_collection() self.nursery_size -= diff self.nursery_real_top -= diff + ll_assert(self.nursery_cleanup >= diff, "set_extra_threshold: too big!") + self.nursery_top -= diff self.extra_threshold += diff From noreply at buildbot.pypy.org Sat Feb 2 18:21:27 2013 From: noreply at buildbot.pypy.org (rlamy) Date: Sat, 2 Feb 2013 18:21:27 +0100 (CET) Subject: [pypy-commit] pypy kill-flowobjspace: make .flatten() and .match_signature() nondestructive Message-ID: <20130202172127.ABA611C009B@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: kill-flowobjspace Changeset: r60820:5cce25c6328c Date: 2013-01-31 05:39 +0000 http://bitbucket.org/pypy/pypy/changeset/5cce25c6328c/ Log: make .flatten() and .match_signature() nondestructive diff --git a/rpython/annotator/argument.py b/rpython/annotator/argument.py --- a/rpython/annotator/argument.py +++ b/rpython/annotator/argument.py @@ -33,11 +33,11 @@ pass class ArgumentsForTranslation(object): + w_starstararg = None def __init__(self, space, args_w, keywords=None, keywords_w=None, w_stararg=None, w_starstararg=None): self.w_stararg = w_stararg - self.w_starstararg = w_starstararg - self.combine_has_happened = False + assert w_starstararg is None self.space = space assert isinstance(args_w, list) self.arguments_w = args_w @@ -54,17 +54,13 @@ return '%s(%s, %s, %s)' % (name, self.arguments_w, self.keywords, self.keywords_w) - def _combine_wrapped(self, w_stararg, w_starstararg): - "unpack the *arg and **kwd into arguments_w and keywords_w" - if w_stararg is not None: - self._combine_starargs_wrapped(w_stararg) - assert w_starstararg is None - - def _combine_starargs_wrapped(self, w_stararg): - # unpack the * arguments - space = self.space - args_w = space.unpackiterable(w_stararg) - self.arguments_w = self.arguments_w + args_w + @property + def positional_args(self): + if self.w_stararg is not None: + args_w = self.space.unpackiterable(self.w_stararg) + return self.arguments_w + args_w + else: + return self.arguments_w def fixedunpack(self, argcount): """The simplest argument parsing: get the 'argcount' arguments, @@ -77,12 +73,6 @@ raise ValueError, "not enough arguments (%d expected)" % argcount return self.arguments_w - def combine_if_necessary(self): - if self.combine_has_happened: - return - self._combine_wrapped(self.w_stararg, self.w_starstararg) - self.combine_has_happened = True - def prepend(self, w_firstarg): # used often "Return a new Arguments with a new argument inserted first." return ArgumentsForTranslation(self.space, [w_firstarg] + self.arguments_w, @@ -101,10 +91,9 @@ # args_w = list of the normal actual parameters, wrapped # scope_w = resulting list of wrapped values # - self.combine_if_necessary() co_argcount = signature.num_argnames() # expected formal arguments, without */** - args_w = self.arguments_w + args_w = self.positional_args num_args = len(args_w) keywords = self.keywords or [] num_kwds = len(keywords) @@ -186,12 +175,11 @@ def unpack(self): "Return a ([w1,w2...], {'kw':w3...}) pair." - self.combine_if_necessary() kwds_w = {} if self.keywords: for i in range(len(self.keywords)): kwds_w[self.keywords[i]] = self.keywords_w[i] - return self.arguments_w, kwds_w + return self.positional_args, kwds_w def match_signature(self, signature, defaults_w): @@ -282,7 +270,6 @@ return (shape_cnt, shape_keys, shape_star, shape_stst), data_w def _rawshape(self, nextra=0): - assert not self.combine_has_happened shape_cnt = len(self.arguments_w)+nextra # Number of positional args if self.keywords: shape_keys = self.keywords[:] # List of keywords (strings) diff --git a/rpython/annotator/test/test_argument.py b/rpython/annotator/test/test_argument.py --- a/rpython/annotator/test/test_argument.py +++ b/rpython/annotator/test/test_argument.py @@ -104,16 +104,6 @@ args = make_arguments_for_translation(space, [1,2,3,4,5], {'e': 5, 'd': 7}) assert rawshape(args) == (5, ('d', 'e'), False, False) - args = make_arguments_for_translation(space, [], {}, - w_stararg=[1], - w_starstararg={'c': 5, 'd': 7}) - assert rawshape(args) == (0, (), True, True) - - args = make_arguments_for_translation(space, [1,2], {'g': 9}, - w_stararg=[3,4,5], - w_starstararg={'e': 5, 'd': 7}) - assert rawshape(args) == (2, ('g', ), True, True) - def test_flatten(self): space = DummySpace() @@ -138,16 +128,6 @@ args = make_arguments_for_translation(space, [1,2,3,4,5], {'e': 5, 'd': 7}) assert args.flatten() == ((5, ('d', 'e'), False, False), [1, 2, 3, 4, 5, 7, 5]) - args = make_arguments_for_translation(space, [], {}, - w_stararg=[1], - w_starstararg={'c': 5, 'd': 7}) - assert args.flatten() == ((0, (), True, True), [[1], {'c': 5, 'd': 7}]) - - args = make_arguments_for_translation(space, [1,2], {'g': 9}, - w_stararg=[3,4,5], - w_starstararg={'e': 5, 'd': 7}) - assert args.flatten() == ((2, ('g', ), True, True), [1, 2, 9, [3, 4, 5], {'e': 5, 'd': 7}]) - def test_stararg_flowspace_variable(self): space = DummySpace() var = object() @@ -189,12 +169,3 @@ shape = ((5, ('d', 'e'), False, False), [1, 2, 3, 4, 5, 7, 5]) args = ArgumentsForTranslation.fromshape(space, *shape) assert args.flatten() == shape - - shape = ((0, (), True, True), [[1], {'c': 5, 'd': 7}]) - args = ArgumentsForTranslation.fromshape(space, *shape) - assert args.flatten() == shape - - shape = ((2, ('g', ), True, True), [1, 2, 9, [3, 4, 5], {'e': 5, 'd': 7}]) - args = ArgumentsForTranslation.fromshape(space, *shape) - assert args.flatten() == shape - diff --git a/rpython/flowspace/argument.py b/rpython/flowspace/argument.py --- a/rpython/flowspace/argument.py +++ b/rpython/flowspace/argument.py @@ -81,7 +81,6 @@ w_starstararg=None): self.w_stararg = w_stararg assert w_starstararg is None, "No **-unpacking in RPython" - self.combine_has_happened = False self.space = space assert isinstance(args_w, list) self.arguments_w = args_w From noreply at buildbot.pypy.org Sat Feb 2 18:21:29 2013 From: noreply at buildbot.pypy.org (rlamy) Date: Sat, 2 Feb 2013 18:21:29 +0100 (CET) Subject: [pypy-commit] pypy kill-flowobjspace: simplify code Message-ID: <20130202172129.038BF1C009B@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: kill-flowobjspace Changeset: r60821:fe8750e5f988 Date: 2013-01-31 23:37 +0000 http://bitbucket.org/pypy/pypy/changeset/fe8750e5f988/ Log: simplify code diff --git a/rpython/annotator/argument.py b/rpython/annotator/argument.py --- a/rpython/annotator/argument.py +++ b/rpython/annotator/argument.py @@ -175,10 +175,7 @@ def unpack(self): "Return a ([w1,w2...], {'kw':w3...}) pair." - kwds_w = {} - if self.keywords: - for i in range(len(self.keywords)): - kwds_w[self.keywords[i]] = self.keywords_w[i] + kwds_w = dict(zip(self.keywords, self.keywords_w)) if self.keywords else {} return self.positional_args, kwds_w @@ -193,9 +190,8 @@ def unmatch_signature(self, signature, data_w): """kind of inverse of match_signature""" - args_w, kwds_w = self.unpack() - need_cnt = len(args_w) - need_kwds = kwds_w.keys() + need_cnt = len(self.positional_args) + need_kwds = self.keywords or [] space = self.space argnames, varargname, kwargname = signature cnt = len(argnames) @@ -216,20 +212,14 @@ cnt += 1 assert len(data_w) == cnt - ndata_args_w = len(data_args_w) - if ndata_args_w >= need_cnt: + if len(data_args_w) >= need_cnt: args_w = data_args_w[:need_cnt] for argname, w_arg in zip(argnames[need_cnt:], data_args_w[need_cnt:]): unfiltered_kwds_w[argname] = w_arg assert not space.is_true(data_w_stararg) else: stararg_w = space.unpackiterable(data_w_stararg) - datalen = len(data_args_w) - args_w = [None] * (datalen + len(stararg_w)) - for i in range(0, datalen): - args_w[i] = data_args_w[i] - for i in range(0, len(stararg_w)): - args_w[i + datalen] = stararg_w[i] + args_w = data_args_w + stararg_w assert len(args_w) == need_cnt keywords = [] From noreply at buildbot.pypy.org Sat Feb 2 18:21:30 2013 From: noreply at buildbot.pypy.org (rlamy) Date: Sat, 2 Feb 2013 18:21:30 +0100 (CET) Subject: [pypy-commit] pypy kill-flowobjspace: merge default Message-ID: <20130202172130.B8E971C009B@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: kill-flowobjspace Changeset: r60822:634f56eec5d6 Date: 2013-02-02 16:47 +0000 http://bitbucket.org/pypy/pypy/changeset/634f56eec5d6/ Log: merge default diff --git a/lib-python/2.7/collections.py b/lib-python/2.7/collections.py --- a/lib-python/2.7/collections.py +++ b/lib-python/2.7/collections.py @@ -6,7 +6,6 @@ __all__ += _abcoll.__all__ from _collections import deque, defaultdict -from operator import itemgetter as _itemgetter from keyword import iskeyword as _iskeyword import sys as _sys import heapq as _heapq @@ -298,7 +297,7 @@ _fields = %(field_names)r \n def __new__(_cls, %(argtxt)s): 'Create new instance of %(typename)s(%(argtxt)s)' - return _tuple.__new__(_cls, (%(argtxt)s)) \n + return tuple.__new__(_cls, (%(argtxt)s)) \n @classmethod def _make(cls, iterable, new=tuple.__new__, len=len): 'Make a new %(typename)s object from a sequence or iterable' @@ -323,14 +322,13 @@ 'Return self as a plain tuple. Used by copy and pickle.' return tuple(self) \n\n''' % locals() for i, name in enumerate(field_names): - template += " %s = _property(_itemgetter(%d), doc='Alias for field number %d')\n" % (name, i, i) + template += " %s = property(lambda self: self[%d], doc='Alias for field number %d')\n" % (name, i, i) if verbose: print template # Execute the template string in a temporary namespace and # support tracing utilities by setting a value for frame.f_globals['__name__'] - namespace = dict(_itemgetter=_itemgetter, __name__='namedtuple_%s' % typename, - OrderedDict=OrderedDict, _property=property, _tuple=tuple) + namespace = {'__name__': 'namedtuple_%s' % typename} try: exec template in namespace except SyntaxError, e: diff --git a/lib-python/2.7/sysconfig.py b/lib-python/2.7/sysconfig.py --- a/lib-python/2.7/sysconfig.py +++ b/lib-python/2.7/sysconfig.py @@ -27,10 +27,10 @@ 'data' : '{base}', }, 'pypy': { - 'stdlib': '{base}/lib-python', - 'platstdlib': '{base}/lib-python', - 'purelib': '{base}/lib-python', - 'platlib': '{base}/lib-python', + 'stdlib': '{base}/lib-python/{py_version_short}', + 'platstdlib': '{base}/lib-python/{py_version_short}', + 'purelib': '{base}/lib-python/{py_version_short}', + 'platlib': '{base}/lib-python/{py_version_short}', 'include': '{base}/include', 'platinclude': '{base}/include', 'scripts': '{base}/bin', diff --git a/lib-python/2.7/test/test_capi.py b/lib-python/2.7/test/test_capi.py --- a/lib-python/2.7/test/test_capi.py +++ b/lib-python/2.7/test/test_capi.py @@ -19,9 +19,6 @@ 'test_broken_memoryview', 'test_capsule', 'test_lazy_hash_inheritance', - 'test_long_api', - 'test_longlong_api', - 'test_null_strings', 'test_widechar', 'TestThreadState', 'TestPendingCalls', diff --git a/lib-python/2.7/test/test_multiprocessing.py b/lib-python/2.7/test/test_multiprocessing.py --- a/lib-python/2.7/test/test_multiprocessing.py +++ b/lib-python/2.7/test/test_multiprocessing.py @@ -1343,7 +1343,7 @@ # Because we are using xmlrpclib for serialization instead of # pickle this will cause a serialization error. - self.assertRaises(Exception, queue.put, time.sleep) + self.assertRaises(Exception, queue.put, object) # Make queue finalizer run before the server is stopped del queue @@ -1800,9 +1800,9 @@ if not gc.isenabled(): gc.enable() self.addCleanup(gc.disable) - thresholds = gc.get_threshold() - self.addCleanup(gc.set_threshold, *thresholds) - gc.set_threshold(10) + #thresholds = gc.get_threshold() + #self.addCleanup(gc.set_threshold, *thresholds) + #gc.set_threshold(10) # perform numerous block allocations, with cyclic references to make # sure objects are collected asynchronously by the gc @@ -1865,6 +1865,7 @@ def test_synchronize(self): self.test_sharedctypes(lock=True) + @unittest.skipUnless(test_support.check_impl_detail(pypy=False), "pypy ctypes differences") def test_copy(self): foo = _Foo(2, 5.0) bar = copy(foo) diff --git a/lib-python/2.7/test/test_zipfile.py b/lib-python/2.7/test/test_zipfile.py --- a/lib-python/2.7/test/test_zipfile.py +++ b/lib-python/2.7/test/test_zipfile.py @@ -1213,6 +1213,17 @@ self.assertEqual(data1, '1'*FIXEDTEST_SIZE) self.assertEqual(data2, '2'*FIXEDTEST_SIZE) + def test_many_opens(self): + # Verify that read() and open() promptly close the file descriptor, + # and don't rely on the garbage collector to free resources. + with zipfile.ZipFile(TESTFN2, mode="r") as zipf: + for x in range(100): + zipf.read('ones') + with zipf.open('ones') as zopen1: + pass + for x in range(10): + self.assertLess(open('/dev/null').fileno(), 100) + def tearDown(self): unlink(TESTFN2) diff --git a/lib-python/2.7/zipfile.py b/lib-python/2.7/zipfile.py --- a/lib-python/2.7/zipfile.py +++ b/lib-python/2.7/zipfile.py @@ -475,9 +475,11 @@ # Search for universal newlines or line chunks. PATTERN = re.compile(r'^(?P[^\r\n]+)|(?P\n|\r\n?)') - def __init__(self, fileobj, mode, zipinfo, decrypter=None): + def __init__(self, fileobj, mode, zipinfo, decrypter=None, + close_fileobj=False): self._fileobj = fileobj self._decrypter = decrypter + self._close_fileobj = close_fileobj self._compress_type = zipinfo.compress_type self._compress_size = zipinfo.compress_size @@ -649,6 +651,12 @@ self._offset += len(data) return data + def close(self): + try: + if self._close_fileobj: + self._fileobj.close() + finally: + super(ZipExtFile, self).close() class ZipFile: @@ -866,7 +874,8 @@ def read(self, name, pwd=None): """Return file bytes (as a string) for name.""" - return self.open(name, "r", pwd).read() + with self.open(name, "r", pwd) as fp: + return fp.read() def open(self, name, mode="r", pwd=None): """Return file-like object for 'name'.""" @@ -889,8 +898,12 @@ zinfo = name else: # Get info object for name - zinfo = self.getinfo(name) - + try: + zinfo = self.getinfo(name) + except KeyError: + if not self._filePassed: + zef_file.close() + raise zef_file.seek(zinfo.header_offset, 0) # Skip the file header: @@ -904,6 +917,8 @@ zef_file.read(fheader[_FH_EXTRA_FIELD_LENGTH]) if fname != zinfo.orig_filename: + if not self._filePassed: + zef_file.close() raise BadZipfile, \ 'File name in directory "%s" and header "%s" differ.' % ( zinfo.orig_filename, fname) @@ -915,6 +930,8 @@ if not pwd: pwd = self.pwd if not pwd: + if not self._filePassed: + zef_file.close() raise RuntimeError, "File %s is encrypted, " \ "password required for extraction" % name @@ -933,9 +950,12 @@ # compare against the CRC otherwise check_byte = (zinfo.CRC >> 24) & 0xff if ord(h[11]) != check_byte: + if not self._filePassed: + zef_file.close() raise RuntimeError("Bad password for file", name) - return ZipExtFile(zef_file, mode, zinfo, zd) + return ZipExtFile(zef_file, mode, zinfo, zd, + close_fileobj=not self._filePassed) def extract(self, member, path=None, pwd=None): """Extract a member from the archive to the current working directory, @@ -993,7 +1013,7 @@ return targetpath source = self.open(member, pwd=pwd) - target = file(targetpath, "wb") + target = open(targetpath, "wb") shutil.copyfileobj(source, target) source.close() target.close() diff --git a/lib-python/conftest.py b/lib-python/conftest.py --- a/lib-python/conftest.py +++ b/lib-python/conftest.py @@ -310,7 +310,7 @@ RegrTest('test_msilib.py'), RegrTest('test_multibytecodec.py', usemodules='_multibytecodec'), RegrTest('test_multifile.py'), - RegrTest('test_multiprocessing.py', skip=True), + RegrTest('test_multiprocessing.py'), RegrTest('test_mutants.py', core="possibly"), RegrTest('test_mutex.py'), RegrTest('test_netrc.py'), diff --git a/lib_pypy/_ctypes_test.py b/lib_pypy/_ctypes_test.py --- a/lib_pypy/_ctypes_test.py +++ b/lib_pypy/_ctypes_test.py @@ -1,6 +1,5 @@ import os, sys import tempfile -import gc def compile_shared(): """Compile '_ctypes_test.c' into an extension module, and import it @@ -19,7 +18,7 @@ if sys.platform == 'win32': ccflags = ['-D_CRT_SECURE_NO_WARNINGS'] else: - ccflags = ['-fPIC'] + ccflags = ['-fPIC', '-Wimplicit-function-declaration'] res = compiler.compile([os.path.join(thisdir, '_ctypes_test.c')], include_dirs=[include_dir], extra_preargs=ccflags) @@ -35,10 +34,10 @@ library = os.path.join(thisdir, '..', 'include', 'python27') if not os.path.exists(library + '.lib'): # For a local translation - library = os.path.join(thisdir, '..', 'pypy', 'translator', - 'goal', 'libpypy-c') + library = os.path.join(thisdir, '..', 'pypy', 'goal', 'libpypy-c') libraries = [library, 'oleaut32'] - extra_ldargs = ['/MANIFEST'] # needed for VC10 + extra_ldargs = ['/MANIFEST', # needed for VC10 + '/EXPORT:init_ctypes_test'] else: libraries = [] extra_ldargs = [] diff --git a/lib_pypy/_testcapi.py b/lib_pypy/_testcapi.py --- a/lib_pypy/_testcapi.py +++ b/lib_pypy/_testcapi.py @@ -34,8 +34,7 @@ library = os.path.join(thisdir, '..', 'include', 'python27') if not os.path.exists(library + '.lib'): # For a local translation - library = os.path.join(thisdir, '..', 'pypy', 'translator', - 'goal', 'libpypy-c') + library = os.path.join(thisdir, '..', 'pypy', 'goal', 'libpypy-c') libraries = [library, 'oleaut32'] extra_ldargs = ['/MANIFEST', # needed for VC10 '/EXPORT:init_testcapi'] diff --git a/pypy/bin/checkmodule.py b/pypy/bin/checkmodule.py --- a/pypy/bin/checkmodule.py +++ b/pypy/bin/checkmodule.py @@ -8,6 +8,8 @@ """ import sys, os +sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', '..')) + from pypy.objspace.fake.checkmodule import checkmodule def main(argv): diff --git a/pypy/doc/cpython_differences.rst b/pypy/doc/cpython_differences.rst --- a/pypy/doc/cpython_differences.rst +++ b/pypy/doc/cpython_differences.rst @@ -318,10 +318,5 @@ type and vice versa. For builtin types, a dictionary will be returned that cannot be changed (but still looks and behaves like a normal dictionary). -* the ``__len__`` or ``__length_hint__`` special methods are sometimes - called by CPython to get a length estimate to preallocate internal arrays. - So far, PyPy never calls ``__len__`` for this purpose, and never calls - ``__length_hint__`` at all. - .. include:: _ref.txt diff --git a/pypy/doc/discussion/improve-rpython.rst b/pypy/doc/discussion/improve-rpython.rst --- a/pypy/doc/discussion/improve-rpython.rst +++ b/pypy/doc/discussion/improve-rpython.rst @@ -15,7 +15,7 @@ from pypy.interpreter.typedef import interp_attrproperty, interp_attrproperty_w from pypy.interpreter.gateway import interp2app from pypy.interpreter.error import OperationError - from pypy.rpython.lltypesystem import rffi, lltype + from rpython.rtyper.lltypesystem import rffi, lltype - A more direct declarative way to write Typedef:: diff --git a/pypy/doc/rffi.rst b/pypy/doc/rffi.rst --- a/pypy/doc/rffi.rst +++ b/pypy/doc/rffi.rst @@ -17,7 +17,7 @@ lltype.Signed or lltype.Array) and memory management must be done by hand. To declare a function, we write:: - from pypy.rpython.lltypesystem import rffi + from rpython.rtyper.lltypesystem import rffi external_function = rffi.llexternal(name, args, result) @@ -31,7 +31,7 @@ libraries and sources by passing in the optional ``compilation_info`` parameter:: - from pypy.rpython.lltypesystem import rffi + from rpython.rtyper.lltypesystem import rffi from rpython.translator.tool.cbuild import ExternalCompilationInfo info = ExternalCompilationInfo(includes=[], libraries=[]) diff --git a/pypy/interpreter/executioncontext.py b/pypy/interpreter/executioncontext.py --- a/pypy/interpreter/executioncontext.py +++ b/pypy/interpreter/executioncontext.py @@ -40,6 +40,7 @@ def gettopframe(self): return self.topframeref() + @jit.unroll_safe def gettopframe_nohidden(self): frame = self.topframeref() while frame and frame.hide(): diff --git a/pypy/interpreter/miscutils.py b/pypy/interpreter/miscutils.py --- a/pypy/interpreter/miscutils.py +++ b/pypy/interpreter/miscutils.py @@ -17,9 +17,8 @@ def setvalue(self, value): self._value = value - def getmainthreadvalue(self): - return self._value + def ismainthread(self): + return True def getallvalues(self): return {0: self._value} - diff --git a/pypy/module/__pypy__/interp_identitydict.py b/pypy/module/__pypy__/interp_identitydict.py --- a/pypy/module/__pypy__/interp_identitydict.py +++ b/pypy/module/__pypy__/interp_identitydict.py @@ -33,6 +33,11 @@ except KeyError: raise OperationError(space.w_KeyError, w_key) + def descr_iter(self, space): + raise OperationError(space.w_TypeError, + space.wrap("'identity_dict' object does not support iteration; " + "iterate over x.keys()")) + def get(self, space, w_key, w_default=None): if w_default is None: w_default = space.w_None @@ -50,8 +55,11 @@ W_IdentityDict.typedef = TypeDef("identity_dict", __doc__="""\ A dictionary that considers keys by object identity. -Distinct objects that compare equal will have separate entries. -All objects can be used as keys, even non-hashable ones. +Distinct objects will have separate entries even if they +compare equal. All objects can be used as keys, even +non-hashable ones --- but avoid using immutable objects +like integers: two int objects 42 may or may not be +internally the same object. """, __new__ = interp2app(W_IdentityDict.descr_new.im_func), __len__ = interp2app(W_IdentityDict.descr_len), @@ -59,6 +67,7 @@ __setitem__ = interp2app(W_IdentityDict.descr_setitem), __getitem__ = interp2app(W_IdentityDict.descr_getitem), __delitem__ = interp2app(W_IdentityDict.descr_delitem), + __iter__ = interp2app(W_IdentityDict.descr_iter), get = interp2app(W_IdentityDict.get), keys = interp2app(W_IdentityDict.keys), values = interp2app(W_IdentityDict.values), diff --git a/pypy/module/__pypy__/test/test_identitydict.py b/pypy/module/__pypy__/test/test_identitydict.py --- a/pypy/module/__pypy__/test/test_identitydict.py +++ b/pypy/module/__pypy__/test/test_identitydict.py @@ -56,3 +56,10 @@ assert None in d assert [] not in d + + def test_iterate(self): + from __pypy__ import identity_dict + d = identity_dict() + d[None] = 1 + raises(TypeError, iter, d) + raises(TypeError, list, d) diff --git a/pypy/module/_io/interp_fileio.py b/pypy/module/_io/interp_fileio.py --- a/pypy/module/_io/interp_fileio.py +++ b/pypy/module/_io/interp_fileio.py @@ -153,41 +153,49 @@ self.readable, self.writable, append, flags = decode_mode(space, mode) - if fd >= 0: - verify_fd(fd) - try: - os.fstat(fd) - except OSError, e: - if e.errno == errno.EBADF: - raise wrap_oserror(space, e) - # else: pass - self.fd = fd - self.closefd = bool(closefd) - else: - if not closefd: - raise OperationError(space.w_ValueError, space.wrap( - "Cannot use closefd=False with file name")) - self.closefd = True + fd_is_own = False + try: + if fd >= 0: + verify_fd(fd) + try: + os.fstat(fd) + except OSError, e: + if e.errno == errno.EBADF: + raise wrap_oserror(space, e) + # else: pass + self.fd = fd + self.closefd = bool(closefd) + else: + self.closefd = True + if not closefd: + raise OperationError(space.w_ValueError, space.wrap( + "Cannot use closefd=False with file name")) - from pypy.module.posix.interp_posix import ( - dispatch_filename, rposix) - try: - self.fd = dispatch_filename(rposix.open)( - space, w_name, flags, 0666) - except OSError, e: - raise wrap_oserror2(space, e, w_name, - exception_name='w_IOError') + from pypy.module.posix.interp_posix import ( + dispatch_filename, rposix) + try: + self.fd = dispatch_filename(rposix.open)( + space, w_name, flags, 0666) + except OSError, e: + raise wrap_oserror2(space, e, w_name, + exception_name='w_IOError') + finally: + fd_is_own = True self._dircheck(space, w_name) - self.w_name = w_name + self.w_name = w_name - if append: - # For consistent behaviour, we explicitly seek to the end of file - # (otherwise, it might be done only on the first write()). - try: - os.lseek(self.fd, 0, os.SEEK_END) - except OSError, e: - raise wrap_oserror(space, e, exception_name='w_IOError') + if append: + # For consistent behaviour, we explicitly seek to the end of file + # (otherwise, it might be done only on the first write()). + try: + os.lseek(self.fd, 0, os.SEEK_END) + except OSError, e: + raise wrap_oserror(space, e, exception_name='w_IOError') + except: + if not fd_is_own: + self.fd = -1 + raise def _mode(self): if self.readable: @@ -253,7 +261,6 @@ except OSError: return if stat.S_ISDIR(st.st_mode): - self._close(space) raise wrap_oserror2(space, OSError(errno.EISDIR, "fstat"), w_filename, exception_name='w_IOError') diff --git a/pypy/module/_io/test/test_fileio.py b/pypy/module/_io/test/test_fileio.py --- a/pypy/module/_io/test/test_fileio.py +++ b/pypy/module/_io/test/test_fileio.py @@ -41,7 +41,12 @@ def test_open_directory(self): import _io + import os raises(IOError, _io.FileIO, self.tmpdir, "rb") + if os.name != 'nt': + fd = os.open(self.tmpdir, os.O_RDONLY) + raises(IOError, _io.FileIO, fd, "rb") + os.close(fd) def test_readline(self): import _io diff --git a/pypy/module/cpyext/longobject.py b/pypy/module/cpyext/longobject.py --- a/pypy/module/cpyext/longobject.py +++ b/pypy/module/cpyext/longobject.py @@ -47,7 +47,12 @@ Return a C unsigned long representation of the contents of pylong. If pylong is greater than ULONG_MAX, an OverflowError is raised.""" - return rffi.cast(rffi.ULONG, space.uint_w(w_long)) + try: + return rffi.cast(rffi.ULONG, space.uint_w(w_long)) + except OperationError, e: + if e.match(space, space.w_ValueError): + e.w_type = space.w_OverflowError + raise @cpython_api([PyObject], rffi.ULONG, error=-1) def PyLong_AsUnsignedLongMask(space, w_long): @@ -86,7 +91,12 @@ Return a C unsigned long representation of the contents of pylong. If pylong is greater than ULONG_MAX, an OverflowError is raised.""" - return rffi.cast(rffi.ULONGLONG, space.r_ulonglong_w(w_long)) + try: + return rffi.cast(rffi.ULONGLONG, space.r_ulonglong_w(w_long)) + except OperationError, e: + if e.match(space, space.w_ValueError): + e.w_type = space.w_OverflowError + raise @cpython_api([PyObject], rffi.ULONGLONG, error=-1) def PyLong_AsUnsignedLongLongMask(space, w_long): diff --git a/pypy/module/cpyext/object.py b/pypy/module/cpyext/object.py --- a/pypy/module/cpyext/object.py +++ b/pypy/module/cpyext/object.py @@ -218,6 +218,8 @@ @cpython_api([PyObject], PyObject) def PyObject_Str(space, w_obj): + if w_obj is None: + return space.wrap("") return space.str(w_obj) @cpython_api([PyObject], PyObject) @@ -226,6 +228,8 @@ representation on success, NULL on failure. This is the equivalent of the Python expression repr(o). Called by the repr() built-in function and by reverse quotes.""" + if w_obj is None: + return space.wrap("") return space.repr(w_obj) @cpython_api([PyObject], PyObject) @@ -234,6 +238,8 @@ string representation on success, NULL on failure. This is the equivalent of the Python expression unicode(o). Called by the unicode() built-in function.""" + if w_obj is None: + return space.wrap(u"") return space.call_function(space.w_unicode, w_obj) @cpython_api([PyObject, PyObject], rffi.INT_real, error=-1) diff --git a/pypy/module/cpyext/test/test_longobject.py b/pypy/module/cpyext/test/test_longobject.py --- a/pypy/module/cpyext/test/test_longobject.py +++ b/pypy/module/cpyext/test/test_longobject.py @@ -31,6 +31,8 @@ value = api.PyLong_AsUnsignedLong(w_value) assert value == (sys.maxint - 1) * 2 + self.raises(space, api, OverflowError, api.PyLong_AsUnsignedLong, space.wrap(-1)) + def test_as_ssize_t(self, space, api): w_value = space.newlong(2) value = api.PyLong_AsSsize_t(w_value) @@ -46,11 +48,11 @@ w_l = space.wrap(sys.maxint + 1) assert api.PyLong_Check(w_l) assert api.PyLong_CheckExact(w_l) - + w_i = space.wrap(sys.maxint) assert not api.PyLong_Check(w_i) assert not api.PyLong_CheckExact(w_i) - + L = space.appexec([], """(): class L(long): pass @@ -73,6 +75,8 @@ assert api.PyLong_AsUnsignedLongLongMask( space.wrap(1<<64)) == 0 + self.raises(space, api, OverflowError, api.PyLong_AsUnsignedLongLong, space.wrap(-1)) + def test_as_long_and_overflow(self, space, api): overflow = lltype.malloc(rffi.CArrayPtr(rffi.INT_real).TO, 1, flavor='raw') assert api.PyLong_AsLongAndOverflow( diff --git a/pypy/module/cpyext/test/test_object.py b/pypy/module/cpyext/test/test_object.py --- a/pypy/module/cpyext/test/test_object.py +++ b/pypy/module/cpyext/test/test_object.py @@ -94,27 +94,30 @@ def test_size(self, space, api): assert api.PyObject_Size(space.newlist([space.w_None])) == 1 - + + def test_str(self, space, api): + w_list = space.newlist([space.w_None, space.wrap(42)]) + assert space.str_w(api.PyObject_Str(None)) == "" + assert space.str_w(api.PyObject_Str(w_list)) == "[None, 42]" + assert space.str_w(api.PyObject_Str(space.wrap("a"))) == "a" + def test_repr(self, space, api): w_list = space.newlist([space.w_None, space.wrap(42)]) + assert space.str_w(api.PyObject_Repr(None)) == "" assert space.str_w(api.PyObject_Repr(w_list)) == "[None, 42]" assert space.str_w(api.PyObject_Repr(space.wrap("a"))) == "'a'" - - w_list = space.newlist([space.w_None, space.wrap(42)]) - assert space.str_w(api.PyObject_Str(w_list)) == "[None, 42]" - assert space.str_w(api.PyObject_Str(space.wrap("a"))) == "a" - + def test_RichCompare(self, space, api): def compare(w_o1, w_o2, opid): res = api.PyObject_RichCompareBool(w_o1, w_o2, opid) w_res = api.PyObject_RichCompare(w_o1, w_o2, opid) assert space.is_true(w_res) == res return res - + def test_compare(o1, o2): w_o1 = space.wrap(o1) w_o2 = space.wrap(o2) - + for opid, expected in [ (Py_LT, o1 < o2), (Py_LE, o1 <= o2), (Py_NE, o1 != o2), (Py_EQ, o1 == o2), @@ -190,6 +193,7 @@ api.PyErr_Clear() def test_unicode(self, space, api): + assert space.unwrap(api.PyObject_Unicode(None)) == u"" assert space.unwrap(api.PyObject_Unicode(space.wrap([]))) == u"[]" assert space.unwrap(api.PyObject_Unicode(space.wrap("e"))) == u"e" assert api.PyObject_Unicode(space.wrap("\xe9")) is None diff --git a/pypy/module/signal/interp_signal.py b/pypy/module/signal/interp_signal.py --- a/pypy/module/signal/interp_signal.py +++ b/pypy/module/signal/interp_signal.py @@ -60,7 +60,6 @@ def __init__(self, space): "NOT_RPYTHON" AsyncAction.__init__(self, space) - self.handlers_w = {} self.pending_signal = -1 self.fire_in_main_thread = False if self.space.config.objspace.usemodules.thread: @@ -91,7 +90,7 @@ # If we are in the main thread, report the signal now, # and poll more self.pending_signal = -1 - self._report_signal(n) + report_signal(self.space, n) n = self.pending_signal if n < 0: n = pypysig_poll() else: @@ -110,20 +109,31 @@ pypysig_pushback(cpy_signal.SIGINT) self.fire_in_main_thread = True - def _report_signal(self, n): - try: - w_handler = self.handlers_w[n] - except KeyError: - return # no handler, ignore signal - space = self.space - if not space.is_true(space.callable(w_handler)): - return # w_handler is SIG_IGN or SIG_DFL? - # re-install signal handler, for OSes that clear it - pypysig_reinstall(n) - # invoke the app-level handler - ec = space.getexecutioncontext() - w_frame = space.wrap(ec.gettopframe_nohidden()) - space.call_function(w_handler, space.wrap(n), w_frame) +# ____________________________________________________________ + + +class Handlers: + def __init__(self, space): + self.handlers_w = {} + +def _get_handlers(space): + return space.fromcache(Handlers).handlers_w + + +def report_signal(space, n): + handlers_w = _get_handlers(space) + try: + w_handler = handlers_w[n] + except KeyError: + return # no handler, ignore signal + if not space.is_true(space.callable(w_handler)): + return # w_handler is SIG_IGN or SIG_DFL? + # re-install signal handler, for OSes that clear it + pypysig_reinstall(n) + # invoke the app-level handler + ec = space.getexecutioncontext() + w_frame = space.wrap(ec.gettopframe_nohidden()) + space.call_function(w_handler, space.wrap(n), w_frame) @unwrap_spec(signum=int) @@ -141,9 +151,9 @@ check_signum_exists(space, signum) else: check_signum_in_range(space, signum) - action = space.check_signal_action - if signum in action.handlers_w: - return action.handlers_w[signum] + handlers_w = _get_handlers(space) + if signum in handlers_w: + return handlers_w[signum] return space.wrap(SIG_DFL) @@ -198,16 +208,12 @@ A signal handler function is called with two arguments: the first is the signal number, the second is the interrupted stack frame. """ - ec = space.getexecutioncontext() - main_ec = space.threadlocals.getmainthreadvalue() - - old_handler = getsignal(space, signum) - - if ec is not main_ec: + if not space.threadlocals.ismainthread(): raise OperationError(space.w_ValueError, space.wrap("signal() must be called from the " "main thread")) - action = space.check_signal_action + old_handler = getsignal(space, signum) + if space.eq_w(w_handler, space.wrap(SIG_DFL)): pypysig_default(signum) elif space.eq_w(w_handler, space.wrap(SIG_IGN)): @@ -218,7 +224,8 @@ space.wrap("'handler' must be a callable " "or SIG_DFL or SIG_IGN")) pypysig_setflag(signum) - action.handlers_w[signum] = w_handler + handlers_w = _get_handlers(space) + handlers_w[signum] = w_handler return old_handler @@ -231,13 +238,10 @@ The fd must be non-blocking. """ - if space.config.objspace.usemodules.thread: - main_ec = space.threadlocals.getmainthreadvalue() - ec = space.getexecutioncontext() - if ec is not main_ec: - raise OperationError( - space.w_ValueError, - space.wrap("set_wakeup_fd only works in main thread")) + if not space.threadlocals.ismainthread(): + raise OperationError( + space.w_ValueError, + space.wrap("set_wakeup_fd only works in main thread")) old_fd = pypysig_set_wakeup_fd(fd) return space.wrap(intmask(old_fd)) diff --git a/pypy/module/thread/os_lock.py b/pypy/module/thread/os_lock.py --- a/pypy/module/thread/os_lock.py +++ b/pypy/module/thread/os_lock.py @@ -38,10 +38,10 @@ @unwrap_spec(waitflag=int) def descr_lock_acquire(self, space, waitflag=1): - """Lock the lock. Without argument, this blocks if the lock is already -locked (even by the same thread), waiting for another thread to release -the lock, and return None once the lock is acquired. -With an argument, this will only block if the argument is true, + """Lock the lock. With the default argument of True, this blocks +if the lock is already locked (even by the same thread), waiting for +another thread to release the lock, and returns True once the lock is +acquired. With an argument of False, this will always return immediately and the return value reflects whether the lock is acquired. The blocking operation is not interruptible.""" mylock = self.lock @@ -113,4 +113,4 @@ def allocate_lock(space): """Create a new lock object. (allocate() is an obsolete synonym.) See LockType.__doc__ for information about locks.""" - return space.wrap(Lock(space)) \ No newline at end of file + return space.wrap(Lock(space)) diff --git a/pypy/module/thread/test/test_lock.py b/pypy/module/thread/test/test_lock.py --- a/pypy/module/thread/test/test_lock.py +++ b/pypy/module/thread/test/test_lock.py @@ -12,7 +12,10 @@ assert lock.locked() is False raises(thread.error, lock.release) assert lock.locked() is False - lock.acquire() + r = lock.acquire() + assert r is True + r = lock.acquire(False) + assert r is False assert lock.locked() is True lock.release() assert lock.locked() is False diff --git a/pypy/module/thread/threadlocals.py b/pypy/module/thread/threadlocals.py --- a/pypy/module/thread/threadlocals.py +++ b/pypy/module/thread/threadlocals.py @@ -44,10 +44,6 @@ self._mostrecentkey = ident self._mostrecentvalue = value - def getmainthreadvalue(self): - ident = self._mainthreadident - return self._valuedict.get(ident, None) - def ismainthread(self): return thread.get_ident() == self._mainthreadident diff --git a/rpython/rlib/rthread.py b/rpython/rlib/rthread.py --- a/rpython/rlib/rthread.py +++ b/rpython/rlib/rthread.py @@ -126,10 +126,11 @@ return bool(res) def acquire_timed(self, timeout): - "timeout is in microseconds." + """Timeout is in microseconds. Returns 0 in case of failure, + 1 in case it works, 2 if interrupted by a signal.""" res = c_thread_acquirelock_timed(self._lock, timeout, 1) res = rffi.cast(lltype.Signed, res) - return bool(res) + return res def release(self): # Sanity check: the lock must be locked diff --git a/rpython/rlib/test/test_rpath.py b/rpython/rlib/test/test_rpath.py --- a/rpython/rlib/test/test_rpath.py +++ b/rpython/rlib/test/test_rpath.py @@ -6,7 +6,7 @@ def test_rabspath_relative(tmpdir): tmpdir.chdir() - assert rpath.rabspath('foo') == tmpdir.join('foo') + assert rpath.rabspath('foo') == os.path.realpath(str(tmpdir.join('foo'))) @py.test.mark.skipif("IS_WINDOWS") def test_rabspath_absolute_posix(): diff --git a/rpython/rlib/test/test_rthread.py b/rpython/rlib/test/test_rthread.py --- a/rpython/rlib/test/test_rthread.py +++ b/rpython/rlib/test/test_rthread.py @@ -159,17 +159,46 @@ l = allocate_lock() l.acquire(True) t1 = time.time() - ok = l.acquire_timed(1000000) + ok = l.acquire_timed(1000001) t2 = time.time() delay = t2 - t1 - if ok: + if ok == 0: # RPY_LOCK_FAILURE + return -delay + elif ok == 2: # RPY_LOCK_INTR return delay - else: - return -delay + else: # RPY_LOCK_ACQUIRED + return 0.0 fn = self.getcompiled(f, []) res = fn() assert res < -1.0 + def test_acquire_timed_alarm(self): + import sys + if not sys.platform.startswith('linux'): + py.test.skip("skipped on non-linux") + import time + from rpython.rlib import rsignal + def f(): + l = allocate_lock() + l.acquire(True) + # + rsignal.pypysig_setflag(rsignal.SIGALRM) + rsignal.c_alarm(1) + # + t1 = time.time() + ok = l.acquire_timed(2500000) + t2 = time.time() + delay = t2 - t1 + if ok == 0: # RPY_LOCK_FAILURE + return -delay + elif ok == 2: # RPY_LOCK_INTR + return delay + else: # RPY_LOCK_ACQUIRED + return 0.0 + fn = self.getcompiled(f, []) + res = fn() + assert res >= 0.95 + #class TestRunDirectly(AbstractThreadTests): # def getcompiled(self, f, argtypes): # return f diff --git a/rpython/rtyper/memory/gc/minimark.py b/rpython/rtyper/memory/gc/minimark.py --- a/rpython/rtyper/memory/gc/minimark.py +++ b/rpython/rtyper/memory/gc/minimark.py @@ -47,7 +47,7 @@ from rpython.rtyper.lltypesystem.lloperation import llop from rpython.rtyper.lltypesystem.llmemory import raw_malloc_usage from rpython.rtyper.memory.gc.base import GCBase, MovingGCBase -from rpython.rtyper.memory.gc import minimarkpage, env +from rpython.rtyper.memory.gc import env from rpython.rtyper.memory.support import mangle_hash from rpython.rlib.rarithmetic import ovfcheck, LONG_BIT, intmask, r_uint from rpython.rlib.rarithmetic import LONG_BIT_SHIFT @@ -254,6 +254,7 @@ # # The ArenaCollection() handles the nonmovable objects allocation. if ArenaCollectionClass is None: + from rpython.rtyper.memory.gc import minimarkpage ArenaCollectionClass = minimarkpage.ArenaCollection self.ac = ArenaCollectionClass(arena_size, page_size, small_request_threshold) @@ -2033,43 +2034,3 @@ (obj + offset).address[0] = llmemory.NULL self.old_objects_with_weakrefs.delete() self.old_objects_with_weakrefs = new_with_weakref - - -# ____________________________________________________________ - -# For testing, a simple implementation of ArenaCollection. -# This version could be used together with obmalloc.c, but -# it requires an extra word per object in the 'all_objects' -# list. - -class SimpleArenaCollection(object): - - def __init__(self, arena_size, page_size, small_request_threshold): - self.arena_size = arena_size # ignored - self.page_size = page_size - self.small_request_threshold = small_request_threshold - self.all_objects = [] - self.total_memory_used = 0 - - def malloc(self, size): - nsize = raw_malloc_usage(size) - ll_assert(nsize > 0, "malloc: size is null or negative") - ll_assert(nsize <= self.small_request_threshold,"malloc: size too big") - ll_assert((nsize & (WORD-1)) == 0, "malloc: size is not aligned") - # - result = llarena.arena_malloc(nsize, False) - llarena.arena_reserve(result, size) - self.all_objects.append((result, nsize)) - self.total_memory_used += nsize - return result - - def mass_free(self, ok_to_free_func): - objs = self.all_objects - self.all_objects = [] - self.total_memory_used = 0 - for rawobj, nsize in objs: - if ok_to_free_func(rawobj): - llarena.arena_free(rawobj) - else: - self.all_objects.append((rawobj, nsize)) - self.total_memory_used += nsize diff --git a/rpython/rtyper/memory/gc/minimarktest.py b/rpython/rtyper/memory/gc/minimarktest.py new file mode 100644 --- /dev/null +++ b/rpython/rtyper/memory/gc/minimarktest.py @@ -0,0 +1,44 @@ +from rpython.rtyper.lltypesystem import llarena +from rpython.rtyper.lltypesystem.llmemory import raw_malloc_usage +from rpython.rlib.debug import ll_assert +from rpython.rlib.rarithmetic import LONG_BIT + +# For testing, a simple implementation of ArenaCollection. +# This version could be used together with obmalloc.c, but +# it requires an extra word per object in the 'all_objects' +# list. + +WORD = LONG_BIT // 8 + + +class SimpleArenaCollection(object): + + def __init__(self, arena_size, page_size, small_request_threshold): + self.arena_size = arena_size # ignored + self.page_size = page_size + self.small_request_threshold = small_request_threshold + self.all_objects = [] + self.total_memory_used = 0 + + def malloc(self, size): + nsize = raw_malloc_usage(size) + ll_assert(nsize > 0, "malloc: size is null or negative") + ll_assert(nsize <= self.small_request_threshold,"malloc: size too big") + ll_assert((nsize & (WORD-1)) == 0, "malloc: size is not aligned") + # + result = llarena.arena_malloc(nsize, False) + llarena.arena_reserve(result, size) + self.all_objects.append((result, nsize)) + self.total_memory_used += nsize + return result + + def mass_free(self, ok_to_free_func): + objs = self.all_objects + self.all_objects = [] + self.total_memory_used = 0 + for rawobj, nsize in objs: + if ok_to_free_func(rawobj): + llarena.arena_free(rawobj) + else: + self.all_objects.append((rawobj, nsize)) + self.total_memory_used += nsize diff --git a/rpython/rtyper/memory/gc/test/test_direct.py b/rpython/rtyper/memory/gc/test/test_direct.py --- a/rpython/rtyper/memory/gc/test/test_direct.py +++ b/rpython/rtyper/memory/gc/test/test_direct.py @@ -481,7 +481,7 @@ class TestMiniMarkGCSimple(DirectGCTest): from rpython.rtyper.memory.gc.minimark import MiniMarkGC as GCClass - from rpython.rtyper.memory.gc.minimark import SimpleArenaCollection + from rpython.rtyper.memory.gc.minimarktest import SimpleArenaCollection # test the GC itself, providing a simple class for ArenaCollection GC_PARAMS = {'ArenaCollectionClass': SimpleArenaCollection} diff --git a/rpython/rtyper/memory/gc/test/test_inspector.py b/rpython/rtyper/memory/gc/test/test_inspector.py --- a/rpython/rtyper/memory/gc/test/test_inspector.py +++ b/rpython/rtyper/memory/gc/test/test_inspector.py @@ -43,6 +43,6 @@ class TestMiniMarkGCSimple(InspectorTest): from rpython.rtyper.memory.gc.minimark import MiniMarkGC as GCClass - from rpython.rtyper.memory.gc.minimark import SimpleArenaCollection + from rpython.rtyper.memory.gc.minimarktest import SimpleArenaCollection GC_PARAMS = {'ArenaCollectionClass': SimpleArenaCollection, "card_page_indices": 4} diff --git a/rpython/translator/c/src/profiling.c b/rpython/translator/c/src/profiling.c --- a/rpython/translator/c/src/profiling.c +++ b/rpython/translator/c/src/profiling.c @@ -8,8 +8,8 @@ #include #endif -cpu_set_t base_cpu_set; -int profiling_setup = 0; +static cpu_set_t base_cpu_set; +static int profiling_setup = 0; void pypy_setup_profiling() { @@ -37,8 +37,8 @@ #include -DWORD_PTR base_affinity_mask; -int profiling_setup = 0; +static DWORD_PTR base_affinity_mask; +static int profiling_setup = 0; void pypy_setup_profiling() { if (!profiling_setup) { diff --git a/rpython/translator/c/src/thread.h b/rpython/translator/c/src/thread.h --- a/rpython/translator/c/src/thread.h +++ b/rpython/translator/c/src/thread.h @@ -7,7 +7,7 @@ typedef enum RPyLockStatus { RPY_LOCK_FAILURE = 0, RPY_LOCK_ACQUIRED = 1, - RPY_LOCK_INTR + RPY_LOCK_INTR = 2 } RPyLockStatus; #ifdef _WIN32 diff --git a/rpython/translator/platform/__init__.py b/rpython/translator/platform/__init__.py --- a/rpython/translator/platform/__init__.py +++ b/rpython/translator/platform/__init__.py @@ -53,9 +53,18 @@ ofiles = self._compile_o_files(cfiles, eci, standalone) return self._finish_linking(ofiles, eci, outputfilename, standalone) + def _all_cfiles(self, cfiles, eci): + seen = set() + result = [] + for cfile in list(cfiles) + list(eci.separate_module_files): + cfile = py.path.local(cfile) + if cfile not in seen: + seen.add(cfile) + result.append(cfile) + return result + def _compile_o_files(self, cfiles, eci, standalone=True): - cfiles = [py.path.local(f) for f in cfiles] - cfiles += [py.path.local(f) for f in eci.separate_module_files] + cfiles = self._all_cfiles(cfiles, eci) compile_args = self._compile_args_from_eci(eci, standalone) ofiles = [] for cfile in cfiles: diff --git a/rpython/translator/platform/posix.py b/rpython/translator/platform/posix.py --- a/rpython/translator/platform/posix.py +++ b/rpython/translator/platform/posix.py @@ -84,8 +84,7 @@ def gen_makefile(self, cfiles, eci, exe_name=None, path=None, shared=False): - cfiles = [py.path.local(f) for f in cfiles] - cfiles += [py.path.local(f) for f in eci.separate_module_files] + cfiles = self._all_cfiles(cfiles, eci) if path is None: path = cfiles[0].dirpath() diff --git a/rpython/translator/platform/windows.py b/rpython/translator/platform/windows.py --- a/rpython/translator/platform/windows.py +++ b/rpython/translator/platform/windows.py @@ -248,8 +248,7 @@ def gen_makefile(self, cfiles, eci, exe_name=None, path=None, shared=False): - cfiles = [py.path.local(f) for f in cfiles] - cfiles += [py.path.local(f) for f in eci.separate_module_files] + cfiles = self._all_cfiles(cfiles, eci) if path is None: path = cfiles[0].dirpath() From noreply at buildbot.pypy.org Sat Feb 2 18:21:32 2013 From: noreply at buildbot.pypy.org (rlamy) Date: Sat, 2 Feb 2013 18:21:32 +0100 (CET) Subject: [pypy-commit] pypy kill-flowobjspace: kill dead support for **-param in unmatch_signature() Message-ID: <20130202172132.04F4E1C009B@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: kill-flowobjspace Changeset: r60823:658fbbcfcafa Date: 2013-02-02 17:20 +0000 http://bitbucket.org/pypy/pypy/changeset/658fbbcfcafa/ Log: kill dead support for **-param in unmatch_signature() diff --git a/rpython/annotator/argument.py b/rpython/annotator/argument.py --- a/rpython/annotator/argument.py +++ b/rpython/annotator/argument.py @@ -194,6 +194,7 @@ need_kwds = self.keywords or [] space = self.space argnames, varargname, kwargname = signature + assert kwargname is None cnt = len(argnames) data_args_w = data_w[:cnt] if varargname: @@ -201,17 +202,9 @@ cnt += 1 else: data_w_stararg = space.newtuple([]) + assert len(data_w) == cnt unfiltered_kwds_w = {} - if kwargname: - data_w_starargarg = data_w[cnt] - for w_key in space.unpackiterable(data_w_starargarg): - key = space.str_w(w_key) - w_value = space.getitem(data_w_starargarg, w_key) - unfiltered_kwds_w[key] = w_value - cnt += 1 - assert len(data_w) == cnt - if len(data_args_w) >= need_cnt: args_w = data_args_w[:need_cnt] for argname, w_arg in zip(argnames[need_cnt:], data_args_w[need_cnt:]): From noreply at buildbot.pypy.org Sat Feb 2 19:32:13 2013 From: noreply at buildbot.pypy.org (rlamy) Date: Sat, 2 Feb 2013 19:32:13 +0100 (CET) Subject: [pypy-commit] pypy kill-flowobjspace: make Constant-ness checks more explicit Message-ID: <20130202183213.D92721C018D@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: kill-flowobjspace Changeset: r60824:ee4ada92b3a3 Date: 2013-02-02 18:31 +0000 http://bitbucket.org/pypy/pypy/changeset/ee4ada92b3a3/ Log: make Constant-ness checks more explicit diff --git a/rpython/flowspace/flowcontext.py b/rpython/flowspace/flowcontext.py --- a/rpython/flowspace/flowcontext.py +++ b/rpython/flowspace/flowcontext.py @@ -9,7 +9,7 @@ from rpython.tool.stdlib_opcode import host_bytecode_spec from rpython.flowspace.argument import CallSpec from rpython.flowspace.model import (Constant, Variable, Block, Link, - UnwrapException, c_last_exception, SpaceOperation) + c_last_exception, SpaceOperation) from rpython.flowspace.framestate import (FrameState, recursively_unflatten, recursively_flatten) from rpython.flowspace.specialcase import (rpython_print_item, diff --git a/rpython/flowspace/objspace.py b/rpython/flowspace/objspace.py --- a/rpython/flowspace/objspace.py +++ b/rpython/flowspace/objspace.py @@ -97,12 +97,11 @@ return self.frame.do_operation('newdict') def newtuple(self, args_w): - try: - content = [self.unwrap(w_arg) for w_arg in args_w] - except UnwrapException: + if all(isinstance(w_arg, Constant) for w_arg in args_w): + content = [w_arg.value for w_arg in args_w] + return Constant(tuple(content)) + else: return self.frame.do_operation('newtuple', *args_w) - else: - return Constant(tuple(content)) def newlist(self, args_w, sizehint=None): return self.frame.do_operation('newlist', *args_w) @@ -298,11 +297,8 @@ return self.frame.guessbool(w_truthvalue) def iter(self, w_iterable): - try: - iterable = self.unwrap(w_iterable) - except UnwrapException: - pass - else: + if isinstance(w_iterable, Constant): + iterable = w_iterable.value if isinstance(iterable, unrolling_iterable): return self.wrap(iterable.get_unroller()) w_iter = self.frame.do_operation("iter", w_iterable) @@ -310,11 +306,8 @@ def next(self, w_iter): frame = self.frame - try: - it = self.unwrap(w_iter) - except UnwrapException: - pass - else: + if isinstance(w_iter, Constant): + it = w_iter.value if isinstance(it, _unroller): try: v, next_unroller = it.step() @@ -405,16 +398,17 @@ return self.frame.do_operation('simple_call', w_func, *args_w) def call_args(self, w_callable, args): - try: - fn = self.unwrap(w_callable) + if isinstance(w_callable, Constant): + fn = w_callable.value if hasattr(fn, "_flowspace_rewrite_directly_as_"): fn = fn._flowspace_rewrite_directly_as_ w_callable = self.wrap(fn) - sc = self.specialcases[fn] # TypeError if 'fn' not hashable - except (UnwrapException, KeyError, TypeError): - pass - else: - return sc(self, fn, args) + try: + sc = self.specialcases[fn] # TypeError if 'fn' not hashable + except (KeyError, TypeError): + pass + else: + return sc(self, fn, args) try: args_w, kwds_w = args.unpack() From noreply at buildbot.pypy.org Sat Feb 2 20:50:24 2013 From: noreply at buildbot.pypy.org (rlamy) Date: Sat, 2 Feb 2013 20:50:24 +0100 (CET) Subject: [pypy-commit] pypy kill-flowobjspace: split FlowObjSpace.unpackiterable() Message-ID: <20130202195024.9BC491C0134@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: kill-flowobjspace Changeset: r60825:c108ebf1f83e Date: 2013-02-02 19:49 +0000 http://bitbucket.org/pypy/pypy/changeset/c108ebf1f83e/ Log: split FlowObjSpace.unpackiterable() diff --git a/rpython/flowspace/flowcontext.py b/rpython/flowspace/flowcontext.py --- a/rpython/flowspace/flowcontext.py +++ b/rpython/flowspace/flowcontext.py @@ -1019,7 +1019,7 @@ def UNPACK_SEQUENCE(self, itemcount, next_instr): w_iterable = self.popvalue() - items = self.space.unpackiterable(w_iterable, itemcount) + items = self.space.unpacksequence(w_iterable, itemcount) self.pushrevvalues(itemcount, items) def slice(self, w_start, w_end): diff --git a/rpython/flowspace/objspace.py b/rpython/flowspace/objspace.py --- a/rpython/flowspace/objspace.py +++ b/rpython/flowspace/objspace.py @@ -264,15 +264,19 @@ w_type = w_instclass return FSException(w_type, w_value) - def unpackiterable(self, w_iterable, expected_length=None): - if not isinstance(w_iterable, Variable): + def unpackiterable(self, w_iterable): + if isinstance(w_iterable, Constant): + l = w_iterable.value + return [self.wrap(x) for x in l] + else: + raise UnwrapException("cannot unpack a Variable iterable ") + + def unpacksequence(self, w_iterable, expected_length): + if isinstance(w_iterable, Constant): l = list(self.unwrap(w_iterable)) - if expected_length is not None and len(l) != expected_length: + if len(l) != expected_length: raise ValueError return [self.wrap(x) for x in l] - elif expected_length is None: - raise UnwrapException("cannot unpack a Variable iterable " - "without knowing its length") else: w_len = self.len(w_iterable) w_correct = self.eq(w_len, self.wrap(expected_length)) From noreply at buildbot.pypy.org Sat Feb 2 23:36:54 2013 From: noreply at buildbot.pypy.org (fijal) Date: Sat, 2 Feb 2013 23:36:54 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: merge incremental-nursery-cleanup Message-ID: <20130202223654.ED05A1C018D@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r60827:74a3226a59c6 Date: 2013-02-03 00:35 +0200 http://bitbucket.org/pypy/pypy/changeset/74a3226a59c6/ Log: merge incremental-nursery-cleanup diff --git a/rpython/rtyper/memory/gc/minimark.py b/rpython/rtyper/memory/gc/minimark.py --- a/rpython/rtyper/memory/gc/minimark.py +++ b/rpython/rtyper/memory/gc/minimark.py @@ -2,41 +2,45 @@ Environment variables can be used to fine-tune the following parameters: - PYPY_GC_NURSERY The nursery size. Defaults to '4MB'. Small values - (like 1 or 1KB) are useful for debugging. + PYPY_GC_NURSERY The nursery size. Defaults to '4MB'. Small values + (like 1 or 1KB) are useful for debugging. - PYPY_GC_MAJOR_COLLECT Major collection memory factor. Default is '1.82', - which means trigger a major collection when the - memory consumed equals 1.82 times the memory - really used at the end of the previous major - collection. + PYPY_GC_NURSERY_CLEANUP The interval at which nursery is cleaned up. Must + be smaller than the nursery size and bigger than the + biggest object we can allotate in the nursery. - PYPY_GC_GROWTH Major collection threshold's max growth rate. - Default is '1.4'. Useful to collect more often - than normally on sudden memory growth, e.g. when - there is a temporary peak in memory usage. + PYPY_GC_MAJOR_COLLECT Major collection memory factor. Default is '1.82', + which means trigger a major collection when the + memory consumed equals 1.82 times the memory + really used at the end of the previous major + collection. - PYPY_GC_MAX The max heap size. If coming near this limit, it - will first collect more often, then raise an - RPython MemoryError, and if that is not enough, - crash the program with a fatal error. Try values - like '1.6GB'. + PYPY_GC_GROWTH Major collection threshold's max growth rate. + Default is '1.4'. Useful to collect more often + than normally on sudden memory growth, e.g. when + there is a temporary peak in memory usage. - PYPY_GC_MAX_DELTA The major collection threshold will never be set - to more than PYPY_GC_MAX_DELTA the amount really - used after a collection. Defaults to 1/8th of the - total RAM size (which is constrained to be at most - 2/3/4GB on 32-bit systems). Try values like '200MB'. + PYPY_GC_MAX The max heap size. If coming near this limit, it + will first collect more often, then raise an + RPython MemoryError, and if that is not enough, + crash the program with a fatal error. Try values + like '1.6GB'. - PYPY_GC_MIN Don't collect while the memory size is below this - limit. Useful to avoid spending all the time in - the GC in very small programs. Defaults to 8 - times the nursery. + PYPY_GC_MAX_DELTA The major collection threshold will never be set + to more than PYPY_GC_MAX_DELTA the amount really + used after a collection. Defaults to 1/8th of the + total RAM size (which is constrained to be at most + 2/3/4GB on 32-bit systems). Try values like '200MB'. - PYPY_GC_DEBUG Enable extra checks around collections that are - too slow for normal use. Values are 0 (off), - 1 (on major collections) or 2 (also on minor - collections). + PYPY_GC_MIN Don't collect while the memory size is below this + limit. Useful to avoid spending all the time in + the GC in very small programs. Defaults to 8 + times the nursery. + + PYPY_GC_DEBUG Enable extra checks around collections that are + too slow for normal use. Values are 0 (off), + 1 (on major collections) or 2 (also on minor + collections). """ # XXX Should find a way to bound the major collection threshold by the # XXX total addressable size. Maybe by keeping some minimarkpage arenas @@ -208,11 +212,18 @@ # minimal allocated size of the nursery is 2x the following # number (by default, at least 132KB on 32-bit and 264KB on 64-bit). "large_object": (16384+512)*WORD, + + # This is the chunk that we cleanup in the nursery. The point is + # to avoid having to trash all the caches just to zero the nursery, + # so we trade it by cleaning it bit-by-bit, as we progress through + # nursery. Has to fit at least one large object + "nursery_cleanup": 32768 * WORD, } def __init__(self, config, read_from_env=False, nursery_size=32*WORD, + nursery_cleanup=8*WORD, page_size=16*WORD, arena_size=64*WORD, small_request_threshold=5*WORD, @@ -226,6 +237,7 @@ assert small_request_threshold % WORD == 0 self.read_from_env = read_from_env self.nursery_size = nursery_size + self.nursery_cleanup = nursery_cleanup self.small_request_threshold = small_request_threshold self.major_collection_threshold = major_collection_threshold self.growth_rate_max = growth_rate_max @@ -248,6 +260,7 @@ self.nursery = NULL self.nursery_free = NULL self.nursery_top = NULL + self.nursery_real_top = NULL self.debug_tiny_nursery = -1 self.debug_rotating_nurseries = None self.extra_threshold = 0 @@ -342,6 +355,12 @@ if newsize < minsize: self.debug_tiny_nursery = newsize & ~(WORD-1) newsize = minsize + + nursery_cleanup = env.read_from_env('PYPY_GC_NURSERY_CLEANUP') + if nursery_cleanup > 0: + if nursery_cleanup < self.nonlarge_max + 1: + nursery_cleanup = self.nonlarge_max + 1 + self.nursery_cleanup = nursery_cleanup # major_coll = env.read_float_from_env('PYPY_GC_MAJOR_COLLECT') if major_coll > 1.0: @@ -394,8 +413,9 @@ self.nursery = self._alloc_nursery() # the current position in the nursery: self.nursery_free = self.nursery + self.nursery_top = self.nursery + self.nursery_cleanup # the end of the nursery: - self.nursery_top = self.nursery + self.nursery_size + self.nursery_real_top = self.nursery + self.nursery_size # initialize the threshold self.min_heap_size = max(self.min_heap_size, self.nursery_size * self.major_collection_threshold) @@ -459,7 +479,8 @@ newnurs = self.debug_rotating_nurseries.pop(0) llarena.arena_protect(newnurs, self._nursery_memory_size(), False) self.nursery = newnurs - self.nursery_top = self.nursery + self.nursery_size + self.nursery_top = self.nursery + self.nursery_cleanup + self.nursery_real_top = self.nursery + self.nursery_size debug_print("switching from nursery", oldnurs, "to nursery", self.nursery, "size", self.nursery_size) @@ -502,7 +523,7 @@ result = self.nursery_free self.nursery_free = result + totalsize if self.nursery_free > self.nursery_top: - result = self.collect_and_reserve(totalsize) + result = self.collect_and_reserve(result, totalsize) # # Build the object. llarena.arena_reserve(result, totalsize) @@ -561,7 +582,7 @@ result = self.nursery_free self.nursery_free = result + totalsize if self.nursery_free > self.nursery_top: - result = self.collect_and_reserve(totalsize) + result = self.collect_and_reserve(result, totalsize) # # Build the object. llarena.arena_reserve(result, totalsize) @@ -580,12 +601,24 @@ if gen > 0: self.major_collection() - def collect_and_reserve(self, totalsize): + def move_nursery_top(self, totalsize): + size = min(self.nursery_real_top - self.nursery_top, + self.nursery_cleanup) + llarena.arena_reset(self.nursery_top, size, 2) + self.nursery_top += size + + def collect_and_reserve(self, prev_result, totalsize): """To call when nursery_free overflows nursery_top. + First check if the nursery_top is the real top, otherwise we + can just move the top of one cleanup and continue + Do a minor collection, and possibly also a major collection, and finally reserve 'totalsize' bytes at the start of the now-empty nursery. """ + if self.nursery_top < self.nursery_real_top: + self.move_nursery_top(totalsize) + return prev_result self.minor_collection() # if self.get_total_memory_used() > self.next_major_collection_threshold: @@ -594,7 +627,7 @@ # The nursery might not be empty now, because of # execute_finalizers(). If it is almost full again, # we need to fix it with another call to minor_collection(). - if self.nursery_free + totalsize > self.nursery_top: + if self.nursery_free + totalsize > self.nursery_real_top: self.minor_collection() # result = self.nursery_free @@ -757,7 +790,8 @@ if self.next_major_collection_threshold < 0: # cannot trigger a full collection now, but we can ensure # that one will occur very soon - self.nursery_free = self.nursery_top + self.nursery_top = self.nursery_real_top + self.nursery_free = self.nursery_real_top def can_malloc_nonmovable(self): return True @@ -837,7 +871,7 @@ def is_in_nursery(self, addr): ll_assert(llmemory.cast_adr_to_int(addr) & 1 == 0, "odd-valued (i.e. tagged) pointer unexpected here") - return self.nursery <= addr < self.nursery_top + return self.nursery <= addr < self.nursery_real_top def appears_to_be_young(self, addr): # "is a valid addr to a young object?" @@ -857,7 +891,7 @@ if not self.is_valid_gc_object(addr): return False - if self.nursery <= addr < self.nursery_top: + if self.nursery <= addr < self.nursery_real_top: return True # addr is in the nursery # # Else, it may be in the set 'young_rawmalloced_objects' @@ -1264,10 +1298,13 @@ self.free_young_rawmalloced_objects() # # All live nursery objects are out, and the rest dies. Fill - # the whole nursery with zero and reset the current nursery pointer. - llarena.arena_reset(self.nursery, self.nursery_size, 2) + # the nursery up to the cleanup point with zeros + llarena.arena_reset(self.nursery, self.nursery_size, 0) + llarena.arena_reset(self.nursery, self.nursery_cleanup, 2) self.debug_rotate_nursery() self.nursery_free = self.nursery + self.nursery_top = self.nursery + self.nursery_cleanup + self.nursery_real_top = self.nursery + self.nursery_size # debug_print("minor collect, total memory used:", self.get_total_memory_used()) From noreply at buildbot.pypy.org Sat Feb 2 23:36:53 2013 From: noreply at buildbot.pypy.org (fijal) Date: Sat, 2 Feb 2013 23:36:53 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: merge default Message-ID: <20130202223653.7C0941C0134@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r60826:c6306eb9a5b0 Date: 2013-02-03 00:35 +0200 http://bitbucket.org/pypy/pypy/changeset/c6306eb9a5b0/ Log: merge default diff too long, truncating to 2000 out of 147210 lines diff --git a/lib-python/2.7/collections.py b/lib-python/2.7/collections.py --- a/lib-python/2.7/collections.py +++ b/lib-python/2.7/collections.py @@ -6,7 +6,6 @@ __all__ += _abcoll.__all__ from _collections import deque, defaultdict -from operator import itemgetter as _itemgetter from keyword import iskeyword as _iskeyword import sys as _sys import heapq as _heapq @@ -298,7 +297,7 @@ _fields = %(field_names)r \n def __new__(_cls, %(argtxt)s): 'Create new instance of %(typename)s(%(argtxt)s)' - return _tuple.__new__(_cls, (%(argtxt)s)) \n + return tuple.__new__(_cls, (%(argtxt)s)) \n @classmethod def _make(cls, iterable, new=tuple.__new__, len=len): 'Make a new %(typename)s object from a sequence or iterable' @@ -323,14 +322,13 @@ 'Return self as a plain tuple. Used by copy and pickle.' return tuple(self) \n\n''' % locals() for i, name in enumerate(field_names): - template += " %s = _property(_itemgetter(%d), doc='Alias for field number %d')\n" % (name, i, i) + template += " %s = property(lambda self: self[%d], doc='Alias for field number %d')\n" % (name, i, i) if verbose: print template # Execute the template string in a temporary namespace and # support tracing utilities by setting a value for frame.f_globals['__name__'] - namespace = dict(_itemgetter=_itemgetter, __name__='namedtuple_%s' % typename, - OrderedDict=OrderedDict, _property=property, _tuple=tuple) + namespace = {'__name__': 'namedtuple_%s' % typename} try: exec template in namespace except SyntaxError, e: diff --git a/lib-python/2.7/inspect.py b/lib-python/2.7/inspect.py --- a/lib-python/2.7/inspect.py +++ b/lib-python/2.7/inspect.py @@ -960,7 +960,7 @@ raise TypeError('%s() takes exactly 0 arguments ' '(%d given)' % (f_name, num_total)) else: - raise TypeError('%s() takes no argument (%d given)' % + raise TypeError('%s() takes no arguments (%d given)' % (f_name, num_total)) for arg in args: if isinstance(arg, str) and arg in named: diff --git a/lib-python/2.7/site.py b/lib-python/2.7/site.py --- a/lib-python/2.7/site.py +++ b/lib-python/2.7/site.py @@ -75,6 +75,7 @@ USER_SITE = None USER_BASE = None + def makepath(*paths): dir = os.path.join(*paths) try: diff --git a/lib-python/2.7/sysconfig.py b/lib-python/2.7/sysconfig.py --- a/lib-python/2.7/sysconfig.py +++ b/lib-python/2.7/sysconfig.py @@ -27,10 +27,10 @@ 'data' : '{base}', }, 'pypy': { - 'stdlib': '{base}/lib-python', - 'platstdlib': '{base}/lib-python', - 'purelib': '{base}/lib-python', - 'platlib': '{base}/lib-python', + 'stdlib': '{base}/lib-python/{py_version_short}', + 'platstdlib': '{base}/lib-python/{py_version_short}', + 'purelib': '{base}/lib-python/{py_version_short}', + 'platlib': '{base}/lib-python/{py_version_short}', 'include': '{base}/include', 'platinclude': '{base}/include', 'scripts': '{base}/bin', diff --git a/lib-python/2.7/test/test_capi.py b/lib-python/2.7/test/test_capi.py --- a/lib-python/2.7/test/test_capi.py +++ b/lib-python/2.7/test/test_capi.py @@ -13,6 +13,17 @@ threading = None import _testcapi +skips = [] +if test_support.check_impl_detail(pypy=True): + skips += [ + 'test_broken_memoryview', + 'test_capsule', + 'test_lazy_hash_inheritance', + 'test_widechar', + 'TestThreadState', + 'TestPendingCalls', + ] + @unittest.skipUnless(threading, 'Threading required for this test.') class TestPendingCalls(unittest.TestCase): @@ -99,7 +110,7 @@ def test_main(): for name in dir(_testcapi): - if name.startswith('test_'): + if name.startswith('test_') and name not in skips: test = getattr(_testcapi, name) if test_support.verbose: print "internal", name @@ -126,7 +137,7 @@ raise test_support.TestFailed, \ "Couldn't find main thread correctly in the list" - if threading: + if threading and 'TestThreadState' not in skips: import thread import time TestThreadState() @@ -134,7 +145,8 @@ t.start() t.join() - test_support.run_unittest(TestPendingCalls) + if 'TestPendingCalls' not in skips: + test_support.run_unittest(TestPendingCalls) if __name__ == "__main__": test_main() diff --git a/lib-python/2.7/test/test_itertools.py b/lib-python/2.7/test/test_itertools.py --- a/lib-python/2.7/test/test_itertools.py +++ b/lib-python/2.7/test/test_itertools.py @@ -533,11 +533,11 @@ self.assertEqual(list(izip()), zip()) self.assertRaises(TypeError, izip, 3) self.assertRaises(TypeError, izip, range(3), 3) - self.assertEqual([tuple(list(pair)) for pair in izip('abc', 'def')], zip('abc', 'def')) self.assertEqual([pair for pair in izip('abc', 'def')], zip('abc', 'def')) + @test_support.impl_detail("tuple reuse is specific to CPython") def test_izip_tuple_reuse(self): ids = map(id, izip('abc', 'def')) @@ -588,6 +588,7 @@ zip('abc', 'def')) self.assertEqual([pair for pair in izip_longest('abc', 'def')], zip('abc', 'def')) + @test_support.impl_detail("tuple reuse is specific to CPython") def test_izip_longest_tuple_reuse(self): ids = map(id, izip_longest('abc', 'def')) diff --git a/lib-python/2.7/test/test_multiprocessing.py b/lib-python/2.7/test/test_multiprocessing.py --- a/lib-python/2.7/test/test_multiprocessing.py +++ b/lib-python/2.7/test/test_multiprocessing.py @@ -1343,7 +1343,7 @@ # Because we are using xmlrpclib for serialization instead of # pickle this will cause a serialization error. - self.assertRaises(Exception, queue.put, time.sleep) + self.assertRaises(Exception, queue.put, object) # Make queue finalizer run before the server is stopped del queue @@ -1800,9 +1800,9 @@ if not gc.isenabled(): gc.enable() self.addCleanup(gc.disable) - thresholds = gc.get_threshold() - self.addCleanup(gc.set_threshold, *thresholds) - gc.set_threshold(10) + #thresholds = gc.get_threshold() + #self.addCleanup(gc.set_threshold, *thresholds) + #gc.set_threshold(10) # perform numerous block allocations, with cyclic references to make # sure objects are collected asynchronously by the gc @@ -1865,6 +1865,7 @@ def test_synchronize(self): self.test_sharedctypes(lock=True) + @unittest.skipUnless(test_support.check_impl_detail(pypy=False), "pypy ctypes differences") def test_copy(self): foo = _Foo(2, 5.0) bar = copy(foo) diff --git a/lib-python/2.7/test/test_support.py b/lib-python/2.7/test/test_support.py --- a/lib-python/2.7/test/test_support.py +++ b/lib-python/2.7/test/test_support.py @@ -1085,7 +1085,6 @@ else: runner = BasicTestRunner() - result = runner.run(suite) if not result.wasSuccessful(): if len(result.errors) == 1 and not result.failures: diff --git a/lib-python/2.7/test/test_zipfile.py b/lib-python/2.7/test/test_zipfile.py --- a/lib-python/2.7/test/test_zipfile.py +++ b/lib-python/2.7/test/test_zipfile.py @@ -1213,6 +1213,17 @@ self.assertEqual(data1, '1'*FIXEDTEST_SIZE) self.assertEqual(data2, '2'*FIXEDTEST_SIZE) + def test_many_opens(self): + # Verify that read() and open() promptly close the file descriptor, + # and don't rely on the garbage collector to free resources. + with zipfile.ZipFile(TESTFN2, mode="r") as zipf: + for x in range(100): + zipf.read('ones') + with zipf.open('ones') as zopen1: + pass + for x in range(10): + self.assertLess(open('/dev/null').fileno(), 100) + def tearDown(self): unlink(TESTFN2) diff --git a/lib-python/2.7/zipfile.py b/lib-python/2.7/zipfile.py --- a/lib-python/2.7/zipfile.py +++ b/lib-python/2.7/zipfile.py @@ -475,9 +475,11 @@ # Search for universal newlines or line chunks. PATTERN = re.compile(r'^(?P[^\r\n]+)|(?P\n|\r\n?)') - def __init__(self, fileobj, mode, zipinfo, decrypter=None): + def __init__(self, fileobj, mode, zipinfo, decrypter=None, + close_fileobj=False): self._fileobj = fileobj self._decrypter = decrypter + self._close_fileobj = close_fileobj self._compress_type = zipinfo.compress_type self._compress_size = zipinfo.compress_size @@ -649,6 +651,12 @@ self._offset += len(data) return data + def close(self): + try: + if self._close_fileobj: + self._fileobj.close() + finally: + super(ZipExtFile, self).close() class ZipFile: @@ -866,7 +874,8 @@ def read(self, name, pwd=None): """Return file bytes (as a string) for name.""" - return self.open(name, "r", pwd).read() + with self.open(name, "r", pwd) as fp: + return fp.read() def open(self, name, mode="r", pwd=None): """Return file-like object for 'name'.""" @@ -889,8 +898,12 @@ zinfo = name else: # Get info object for name - zinfo = self.getinfo(name) - + try: + zinfo = self.getinfo(name) + except KeyError: + if not self._filePassed: + zef_file.close() + raise zef_file.seek(zinfo.header_offset, 0) # Skip the file header: @@ -904,6 +917,8 @@ zef_file.read(fheader[_FH_EXTRA_FIELD_LENGTH]) if fname != zinfo.orig_filename: + if not self._filePassed: + zef_file.close() raise BadZipfile, \ 'File name in directory "%s" and header "%s" differ.' % ( zinfo.orig_filename, fname) @@ -915,6 +930,8 @@ if not pwd: pwd = self.pwd if not pwd: + if not self._filePassed: + zef_file.close() raise RuntimeError, "File %s is encrypted, " \ "password required for extraction" % name @@ -933,9 +950,12 @@ # compare against the CRC otherwise check_byte = (zinfo.CRC >> 24) & 0xff if ord(h[11]) != check_byte: + if not self._filePassed: + zef_file.close() raise RuntimeError("Bad password for file", name) - return ZipExtFile(zef_file, mode, zinfo, zd) + return ZipExtFile(zef_file, mode, zinfo, zd, + close_fileobj=not self._filePassed) def extract(self, member, path=None, pwd=None): """Extract a member from the archive to the current working directory, @@ -993,7 +1013,7 @@ return targetpath source = self.open(member, pwd=pwd) - target = file(targetpath, "wb") + target = open(targetpath, "wb") shutil.copyfileobj(source, target) source.close() target.close() diff --git a/lib-python/conftest.py b/lib-python/conftest.py --- a/lib-python/conftest.py +++ b/lib-python/conftest.py @@ -61,7 +61,7 @@ usemodules = '', skip=None): self.basename = basename - self._usemodules = usemodules.split() + ['signal'] + self._usemodules = usemodules.split() + ['signal', 'rctime', 'itertools', '_socket'] self._compiler = compiler self.core = core self.skip = skip @@ -93,63 +93,57 @@ m.test_main() ''' % locals()) -if sys.platform == 'win32': - skip_win32 = "Not supported on Windows" - only_win32 = False -else: - skip_win32 = False - only_win32 = "Only on Windows" - testmap = [ RegrTest('test___all__.py', core=True), RegrTest('test___future__.py', core=True), - RegrTest('test__locale.py', skip=skip_win32), + RegrTest('test__locale.py', usemodules='_locale'), RegrTest('test_abc.py'), RegrTest('test_abstract_numbers.py'), - RegrTest('test_aepack.py', skip=True), + RegrTest('test_aepack.py'), RegrTest('test_aifc.py'), - RegrTest('test_argparse.py'), - RegrTest('test_al.py', skip=True), - RegrTest('test_ast.py', core=True), - RegrTest('test_anydbm.py'), - RegrTest('test_applesingle.py', skip=True), - RegrTest('test_array.py', core=True, usemodules='struct array'), + RegrTest('test_al.py'), + RegrTest('test_anydbm.py', usemodules='struct'), + RegrTest('test_applesingle.py'), + RegrTest('test_argparse.py', usemodules='binascii'), + RegrTest('test_array.py', core=True, usemodules='struct array binascii'), RegrTest('test_ascii_formatd.py'), - RegrTest('test_asynchat.py', usemodules='thread'), - RegrTest('test_asyncore.py'), + RegrTest('test_ast.py', core=True, usemodules='struct'), + RegrTest('test_asynchat.py', usemodules='select fcntl'), + RegrTest('test_asyncore.py', usemodules='select fcntl'), RegrTest('test_atexit.py', core=True), - RegrTest('test_audioop.py', skip=True), + RegrTest('test_audioop.py', skip="unsupported extension module"), RegrTest('test_augassign.py', core=True), - RegrTest('test_base64.py'), + RegrTest('test_base64.py', usemodules='struct'), RegrTest('test_bastion.py'), + RegrTest('test_bigaddrspace.py'), + RegrTest('test_bigmem.py'), RegrTest('test_binascii.py', usemodules='binascii'), - RegrTest('test_binhex.py'), - RegrTest('test_binop.py', core=True), RegrTest('test_bisect.py', core=True, usemodules='_bisect'), RegrTest('test_bool.py', core=True), - RegrTest('test_bsddb.py', skip="unsupported extension module"), - RegrTest('test_bsddb185.py', skip="unsupported extension module"), - RegrTest('test_bsddb3.py', skip="unsupported extension module"), + RegrTest('test_bsddb.py'), + RegrTest('test_bsddb185.py'), + RegrTest('test_bsddb3.py'), RegrTest('test_buffer.py'), RegrTest('test_bufio.py', core=True), - RegrTest('test_builtin.py', core=True), - RegrTest('test_bytes.py'), + RegrTest('test_builtin.py', core=True, usemodules='binascii'), + RegrTest('test_bytes.py', usemodules='struct binascii'), RegrTest('test_bz2.py', usemodules='bz2'), RegrTest('test_calendar.py'), RegrTest('test_call.py', core=True), - RegrTest('test_capi.py', skip="not applicable"), - RegrTest('test_cd.py', skip=True), + RegrTest('test_capi.py'), + RegrTest('test_cd.py'), RegrTest('test_cfgparser.py'), - RegrTest('test_cgi.py'), RegrTest('test_charmapcodec.py', core=True), - RegrTest('test_cl.py', skip=True), + RegrTest('test_cl.py'), RegrTest('test_class.py', core=True), RegrTest('test_cmath.py', core=True), RegrTest('test_cmd.py'), + RegrTest('test_cmd_line.py'), RegrTest('test_cmd_line_script.py'), + RegrTest('test_code.py', core=True), RegrTest('test_codeccallbacks.py', core=True), RegrTest('test_codecencodings_cn.py', usemodules='_multibytecodec'), RegrTest('test_codecencodings_hk.py', usemodules='_multibytecodec'), @@ -157,7 +151,6 @@ RegrTest('test_codecencodings_jp.py', usemodules='_multibytecodec'), RegrTest('test_codecencodings_kr.py', usemodules='_multibytecodec'), RegrTest('test_codecencodings_tw.py', usemodules='_multibytecodec'), - RegrTest('test_codecmaps_cn.py', usemodules='_multibytecodec'), RegrTest('test_codecmaps_hk.py', usemodules='_multibytecodec'), RegrTest('test_codecmaps_jp.py', usemodules='_multibytecodec'), @@ -165,6 +158,7 @@ RegrTest('test_codecmaps_tw.py', usemodules='_multibytecodec'), RegrTest('test_codecs.py', core=True, usemodules='_multibytecodec'), RegrTest('test_codeop.py', core=True), + RegrTest('test_coding.py', core=True), RegrTest('test_coercion.py', core=True), RegrTest('test_collections.py'), RegrTest('test_colorsys.py'), @@ -174,22 +168,24 @@ RegrTest('test_compileall.py'), RegrTest('test_compiler.py', core=False, skip="slowly deprecating compiler"), RegrTest('test_complex.py', core=True), - + RegrTest('test_complex_args.py'), RegrTest('test_contains.py', core=True), + RegrTest('test_contextlib.py', usemodules="thread"), RegrTest('test_cookie.py'), RegrTest('test_cookielib.py'), RegrTest('test_copy.py', core=True), RegrTest('test_copy_reg.py', core=True), RegrTest('test_cpickle.py', core=True), - RegrTest('test_cprofile.py'), - RegrTest('test_crypt.py', usemodules='crypt', skip=skip_win32), + RegrTest('test_cprofile.py'), + RegrTest('test_crypt.py', usemodules='crypt'), RegrTest('test_csv.py', usemodules='_csv'), - - RegrTest('test_curses.py', skip="unsupported extension module"), + RegrTest('test_ctypes.py', usemodules="_rawffi thread"), + RegrTest('test_curses.py'), RegrTest('test_datetime.py'), RegrTest('test_dbm.py'), RegrTest('test_decimal.py'), RegrTest('test_decorators.py', core=True), + RegrTest('test_defaultdict.py', usemodules='_collections'), RegrTest('test_deque.py', core=True, usemodules='_collections'), RegrTest('test_descr.py', core=True, usemodules='_weakref'), RegrTest('test_descrtut.py', core=True), @@ -200,7 +196,7 @@ RegrTest('test_dircache.py', core=True), RegrTest('test_dis.py'), RegrTest('test_distutils.py', skip=True), - RegrTest('test_dl.py', skip=True), + RegrTest('test_dl.py'), RegrTest('test_doctest.py', usemodules="thread"), RegrTest('test_doctest2.py'), RegrTest('test_docxmlrpc.py'), @@ -208,20 +204,22 @@ RegrTest('test_dummy_thread.py', core=True), RegrTest('test_dummy_threading.py', core=True), RegrTest('test_email.py'), - RegrTest('test_email_codecs.py'), + RegrTest('test_email_renamed.py'), RegrTest('test_enumerate.py', core=True), RegrTest('test_eof.py', core=True), RegrTest('test_epoll.py'), RegrTest('test_errno.py', usemodules="errno"), + RegrTest('test_exception_variations.py'), RegrTest('test_exceptions.py', core=True), RegrTest('test_extcall.py', core=True), - RegrTest('test_fcntl.py', usemodules='fcntl', skip=skip_win32), + RegrTest('test_fcntl.py', usemodules='fcntl'), RegrTest('test_file.py', usemodules="posix", core=True), RegrTest('test_file2k.py', usemodules="posix", core=True), RegrTest('test_filecmp.py', core=True), RegrTest('test_fileinput.py', core=True), RegrTest('test_fileio.py'), + RegrTest('test_float.py', core=True), RegrTest('test_fnmatch.py', core=True), RegrTest('test_fork1.py', usemodules="thread"), RegrTest('test_format.py', core=True), @@ -230,6 +228,7 @@ RegrTest('test_frozen.py', skip="unsupported extension module"), RegrTest('test_ftplib.py'), RegrTest('test_funcattrs.py', core=True), + RegrTest('test_functools.py'), RegrTest('test_future.py', core=True), RegrTest('test_future1.py', core=True), RegrTest('test_future2.py', core=True), @@ -239,41 +238,37 @@ RegrTest('test_future_builtins.py'), RegrTest('test_gc.py', usemodules='_weakref', skip="implementation detail"), RegrTest('test_gdb.py', skip="not applicable"), - RegrTest('test_gdbm.py', skip="unsupported extension module"), + RegrTest('test_gdbm.py'), RegrTest('test_generators.py', core=True, usemodules='thread _weakref'), RegrTest('test_genericpath.py'), RegrTest('test_genexps.py', core=True, usemodules='_weakref'), - RegrTest('test_getargs.py', skip="unsupported extension module"), - RegrTest('test_getargs2.py', skip="unsupported extension module"), - + RegrTest('test_getargs.py'), + RegrTest('test_getargs2.py', usemodules='binascii', skip=True), RegrTest('test_getopt.py', core=True), RegrTest('test_gettext.py'), - - RegrTest('test_gl.py', skip=True), + RegrTest('test_gl.py'), RegrTest('test_glob.py', core=True), RegrTest('test_global.py', core=True), RegrTest('test_grammar.py', core=True), - RegrTest('test_grp.py', skip=skip_win32), - - RegrTest('test_gzip.py'), + RegrTest('test_grp.py'), + RegrTest('test_gzip.py', usemodules='zlib'), RegrTest('test_hash.py', core=True), RegrTest('test_hashlib.py', core=True), - RegrTest('test_heapq.py', core=True), RegrTest('test_hmac.py'), RegrTest('test_hotshot.py', skip="unsupported extension module"), - RegrTest('test_htmllib.py'), RegrTest('test_htmlparser.py'), RegrTest('test_httplib.py'), RegrTest('test_httpservers.py'), - RegrTest('test_imageop.py', skip="unsupported extension module"), + RegrTest('test_imageop.py'), RegrTest('test_imaplib.py'), - RegrTest('test_imgfile.py', skip="unsupported extension module"), + RegrTest('test_imgfile.py'), RegrTest('test_imp.py', core=True, usemodules='thread'), RegrTest('test_import.py', core=True), RegrTest('test_importhooks.py', core=True), RegrTest('test_importlib.py'), + RegrTest('test_index.py'), RegrTest('test_inspect.py'), RegrTest('test_int.py', core=True), RegrTest('test_int_literal.py', core=True), @@ -296,7 +291,7 @@ RegrTest('test_long_future.py', core=True), RegrTest('test_longexp.py', core=True), RegrTest('test_macos.py'), - RegrTest('test_macostools.py', skip=True), + RegrTest('test_macostools.py'), RegrTest('test_macpath.py'), RegrTest('test_mailbox.py'), RegrTest('test_marshal.py', core=True), @@ -307,30 +302,29 @@ RegrTest('test_mhlib.py'), RegrTest('test_mimetools.py'), RegrTest('test_mimetypes.py'), - RegrTest('test_MimeWriter.py', core=False), + RegrTest('test_MimeWriter.py', core=False, usemodules='binascii'), RegrTest('test_minidom.py'), RegrTest('test_mmap.py', usemodules="mmap"), RegrTest('test_module.py', core=True), RegrTest('test_modulefinder.py'), - RegrTest('test_msilib.py', skip=only_win32), + RegrTest('test_msilib.py'), RegrTest('test_multibytecodec.py', usemodules='_multibytecodec'), - RegrTest('test_multibytecodec_support.py', skip="not a test"), RegrTest('test_multifile.py'), - RegrTest('test_multiprocessing.py', skip="FIXME leaves subprocesses"), + RegrTest('test_multiprocessing.py'), RegrTest('test_mutants.py', core="possibly"), RegrTest('test_mutex.py'), RegrTest('test_netrc.py'), RegrTest('test_new.py', core=True), - RegrTest('test_nis.py', skip="unsupported extension module"), + RegrTest('test_nis.py'), RegrTest('test_normalization.py'), RegrTest('test_ntpath.py'), + RegrTest('test_old_mailbox.py'), RegrTest('test_opcodes.py', core=True), RegrTest('test_openpty.py'), RegrTest('test_operator.py', core=True), RegrTest('test_optparse.py'), - RegrTest('test_os.py', core=True), - RegrTest('test_ossaudiodev.py', skip="unsupported extension module"), + RegrTest('test_ossaudiodev.py'), RegrTest('test_parser.py', skip="slowly deprecating compiler"), RegrTest('test_pdb.py'), RegrTest('test_peepholer.py'), @@ -338,14 +332,16 @@ RegrTest('test_pep263.py'), RegrTest('test_pep277.py'), RegrTest('test_pep292.py'), + RegrTest('test_pep352.py'), RegrTest('test_pickle.py', core=True), RegrTest('test_pickletools.py', core=False), RegrTest('test_pipes.py'), RegrTest('test_pkg.py', core=True), RegrTest('test_pkgimport.py', core=True), RegrTest('test_pkgutil.py'), - RegrTest('test_plistlib.py', skip="unsupported module"), - RegrTest('test_poll.py', skip=skip_win32), + RegrTest('test_platform.py'), + RegrTest('test_plistlib.py'), + RegrTest('test_poll.py'), RegrTest('test_popen.py'), RegrTest('test_popen2.py'), RegrTest('test_poplib.py'), @@ -357,8 +353,8 @@ RegrTest('test_profile.py'), RegrTest('test_property.py', core=True), RegrTest('test_pstats.py'), - RegrTest('test_pty.py', skip="unsupported extension module"), - RegrTest('test_pwd.py', usemodules="pwd", skip=skip_win32), + RegrTest('test_pty.py', usemodules='fcntl termios select'), + RegrTest('test_pwd.py', usemodules="pwd"), RegrTest('test_py3kwarn.py'), RegrTest('test_py_compile.py'), RegrTest('test_pyclbr.py'), @@ -370,15 +366,15 @@ RegrTest('test_re.py', core=True), RegrTest('test_readline.py'), RegrTest('test_repr.py', core=True), - RegrTest('test_resource.py', skip=skip_win32), + RegrTest('test_resource.py'), RegrTest('test_rfc822.py'), RegrTest('test_richcmp.py', core=True), RegrTest('test_rlcompleter.py'), - RegrTest('test_robotparser.py'), + RegrTest('test_runpy.py'), RegrTest('test_sax.py'), RegrTest('test_scope.py', core=True), - RegrTest('test_scriptpackages.py', skip="unsupported extension module"), + RegrTest('test_scriptpackages.py'), RegrTest('test_select.py'), RegrTest('test_set.py', core=True), RegrTest('test_sets.py'), @@ -389,64 +385,59 @@ RegrTest('test_shlex.py'), RegrTest('test_shutil.py'), RegrTest('test_signal.py'), - RegrTest('test_SimpleHTTPServer.py'), + RegrTest('test_SimpleHTTPServer.py', usemodules='binascii'), RegrTest('test_site.py', core=False), RegrTest('test_slice.py', core=True), RegrTest('test_smtplib.py'), RegrTest('test_smtpnet.py'), RegrTest('test_socket.py', usemodules='thread _weakref'), - RegrTest('test_socketserver.py', usemodules='thread'), - RegrTest('test_softspace.py', core=True), RegrTest('test_sort.py', core=True), + RegrTest('test_sqlite.py', usemodules="thread _rawffi zlib"), RegrTest('test_ssl.py', usemodules='_ssl _socket select'), + RegrTest('test_startfile.py'), RegrTest('test_str.py', core=True), - RegrTest('test_strftime.py'), RegrTest('test_string.py', core=True), - RegrTest('test_StringIO.py', core=True, usemodules='cStringIO'), + RegrTest('test_StringIO.py', core=True, usemodules='cStringIO array'), RegrTest('test_stringprep.py'), RegrTest('test_strop.py', skip="deprecated"), - RegrTest('test_strptime.py'), RegrTest('test_strtod.py'), RegrTest('test_struct.py', usemodules='struct'), RegrTest('test_structmembers.py', skip="CPython specific"), RegrTest('test_structseq.py'), RegrTest('test_subprocess.py', usemodules='signal'), - RegrTest('test_sunaudiodev.py', skip=True), + RegrTest('test_sunaudiodev.py'), RegrTest('test_sundry.py'), RegrTest('test_symtable.py', skip="implementation detail"), RegrTest('test_syntax.py', core=True), RegrTest('test_sys.py', core=True, usemodules='struct'), + RegrTest('test_sys_setprofile.py', core=True), RegrTest('test_sys_settrace.py', core=True), - RegrTest('test_sys_setprofile.py', core=True), RegrTest('test_sysconfig.py'), - RegrTest('test_tcl.py', skip="unsupported extension module"), RegrTest('test_tarfile.py'), + RegrTest('test_tcl.py'), RegrTest('test_telnetlib.py'), RegrTest('test_tempfile.py'), - RegrTest('test_textwrap.py'), RegrTest('test_thread.py', usemodules="thread", core=True), RegrTest('test_threaded_import.py', usemodules="thread", core=True), RegrTest('test_threadedtempfile.py', usemodules="thread", core=False), - RegrTest('test_threading.py', usemodules="thread", core=True), RegrTest('test_threading_local.py', usemodules="thread", core=True), RegrTest('test_threadsignals.py', usemodules="thread"), - RegrTest('test_time.py', core=True), RegrTest('test_timeout.py'), RegrTest('test_tk.py'), - RegrTest('test_ttk_guionly.py'), - RegrTest('test_ttk_textonly.py'), RegrTest('test_tokenize.py'), RegrTest('test_trace.py'), RegrTest('test_traceback.py', core=True), RegrTest('test_transformer.py', core=True), + RegrTest('test_ttk_guionly.py'), + RegrTest('test_ttk_textonly.py'), RegrTest('test_tuple.py', core=True), RegrTest('test_typechecks.py'), RegrTest('test_types.py', core=True), @@ -462,6 +453,7 @@ RegrTest('test_unpack.py', core=True), RegrTest('test_urllib.py'), RegrTest('test_urllib2.py'), + RegrTest('test_urllib2_localnet.py', usemodules="thread"), RegrTest('test_urllib2net.py'), RegrTest('test_urllibnet.py'), RegrTest('test_urlparse.py'), @@ -469,61 +461,38 @@ RegrTest('test_userlist.py', core=True), RegrTest('test_userstring.py', core=True), RegrTest('test_uu.py'), - - RegrTest('test_warnings.py', core=True), - RegrTest('test_wave.py', skip="unsupported extension module"), - RegrTest('test_weakref.py', core=True, usemodules='_weakref'), - RegrTest('test_weakset.py'), - - RegrTest('test_whichdb.py'), - RegrTest('test_winreg.py', skip=only_win32), - RegrTest('test_winsound.py', skip="unsupported extension module"), - RegrTest('test_xmllib.py'), - RegrTest('test_xmlrpc.py'), - - RegrTest('test_xpickle.py'), - RegrTest('test_xrange.py', core=True), - RegrTest('test_zipfile.py'), - RegrTest('test_zipimport.py', usemodules='zlib zipimport'), - RegrTest('test_zipimport_support.py', usemodules='zlib zipimport'), - RegrTest('test_zlib.py', usemodules='zlib'), - - RegrTest('test_bigaddrspace.py'), - RegrTest('test_bigmem.py'), - RegrTest('test_cmd_line.py'), - RegrTest('test_code.py'), - RegrTest('test_coding.py'), - RegrTest('test_complex_args.py'), - RegrTest('test_contextlib.py', usemodules="thread"), - RegrTest('test_ctypes.py', usemodules="_rawffi thread"), - RegrTest('test_defaultdict.py', usemodules='_collections'), - RegrTest('test_email_renamed.py'), - RegrTest('test_exception_variations.py'), - RegrTest('test_float.py'), - RegrTest('test_functools.py'), - RegrTest('test_index.py'), - RegrTest('test_old_mailbox.py'), - RegrTest('test_pep352.py'), - RegrTest('test_platform.py'), - RegrTest('test_runpy.py'), - RegrTest('test_sqlite.py', usemodules="thread _rawffi zlib"), - RegrTest('test_startfile.py', skip="bogus test"), - RegrTest('test_structmembers.py', skip="depends on _testcapi"), - RegrTest('test_urllib2_localnet.py', usemodules="thread"), RegrTest('test_uuid.py'), RegrTest('test_wait3.py', usemodules="thread"), RegrTest('test_wait4.py', usemodules="thread"), + RegrTest('test_warnings.py', core=True), + RegrTest('test_wave.py'), + RegrTest('test_weakref.py', core=True, usemodules='_weakref'), + RegrTest('test_weakset.py'), + RegrTest('test_whichdb.py'), + RegrTest('test_winreg.py'), + RegrTest('test_winsound.py'), RegrTest('test_with.py'), RegrTest('test_wsgiref.py'), RegrTest('test_xdrlib.py'), RegrTest('test_xml_etree.py'), RegrTest('test_xml_etree_c.py'), + RegrTest('test_xmllib.py'), + RegrTest('test_xmlrpc.py'), + RegrTest('test_xpickle.py'), + RegrTest('test_xrange.py', core=True), + RegrTest('test_zipfile.py'), RegrTest('test_zipfile64.py'), + RegrTest('test_zipimport.py', usemodules='zlib zipimport'), + RegrTest('test_zipimport_support.py', usemodules='zlib zipimport'), + RegrTest('test_zlib.py', usemodules='zlib'), ] def check_testmap_complete(): listed_names = dict.fromkeys([regrtest.basename for regrtest in testmap]) - listed_names['test_support.py'] = True # ignore this + assert len(listed_names) == len(testmap) + # names to ignore + listed_names['test_support.py'] = True + listed_names['test_multibytecodec_support.py'] = True missing = [] for path in testdir.listdir(fil='test_*.py'): name = path.basename @@ -578,7 +547,7 @@ def getinvocation(self, regrtest): fspath = regrtest.getfspath() python = sys.executable - pypy_script = pypydir.join('bin', 'py.py') + pypy_script = pypydir.join('bin', 'pyinteractive.py') alarm_script = pypydir.join('tool', 'alarm.py') if sys.platform == 'win32': watchdog_name = 'watchdog_nt.py' diff --git a/lib_pypy/_ctypes_test.py b/lib_pypy/_ctypes_test.py --- a/lib_pypy/_ctypes_test.py +++ b/lib_pypy/_ctypes_test.py @@ -1,6 +1,5 @@ import os, sys import tempfile -import gc def compile_shared(): """Compile '_ctypes_test.c' into an extension module, and import it @@ -19,7 +18,7 @@ if sys.platform == 'win32': ccflags = ['-D_CRT_SECURE_NO_WARNINGS'] else: - ccflags = ['-fPIC'] + ccflags = ['-fPIC', '-Wimplicit-function-declaration'] res = compiler.compile([os.path.join(thisdir, '_ctypes_test.c')], include_dirs=[include_dir], extra_preargs=ccflags) @@ -35,10 +34,10 @@ library = os.path.join(thisdir, '..', 'include', 'python27') if not os.path.exists(library + '.lib'): # For a local translation - library = os.path.join(thisdir, '..', 'pypy', 'translator', - 'goal', 'libpypy-c') + library = os.path.join(thisdir, '..', 'pypy', 'goal', 'libpypy-c') libraries = [library, 'oleaut32'] - extra_ldargs = ['/MANIFEST'] # needed for VC10 + extra_ldargs = ['/MANIFEST', # needed for VC10 + '/EXPORT:init_ctypes_test'] else: libraries = [] extra_ldargs = [] diff --git a/lib_pypy/_testcapi.py b/lib_pypy/_testcapi.py --- a/lib_pypy/_testcapi.py +++ b/lib_pypy/_testcapi.py @@ -34,8 +34,7 @@ library = os.path.join(thisdir, '..', 'include', 'python27') if not os.path.exists(library + '.lib'): # For a local translation - library = os.path.join(thisdir, '..', 'pypy', 'translator', - 'goal', 'libpypy-c') + library = os.path.join(thisdir, '..', 'pypy', 'goal', 'libpypy-c') libraries = [library, 'oleaut32'] extra_ldargs = ['/MANIFEST', # needed for VC10 '/EXPORT:init_testcapi'] diff --git a/pypy/bin/checkmodule.py b/pypy/bin/checkmodule.py --- a/pypy/bin/checkmodule.py +++ b/pypy/bin/checkmodule.py @@ -8,6 +8,8 @@ """ import sys, os +sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', '..')) + from pypy.objspace.fake.checkmodule import checkmodule def main(argv): diff --git a/pypy/doc/cpython_differences.rst b/pypy/doc/cpython_differences.rst --- a/pypy/doc/cpython_differences.rst +++ b/pypy/doc/cpython_differences.rst @@ -318,10 +318,5 @@ type and vice versa. For builtin types, a dictionary will be returned that cannot be changed (but still looks and behaves like a normal dictionary). -* the ``__len__`` or ``__length_hint__`` special methods are sometimes - called by CPython to get a length estimate to preallocate internal arrays. - So far, PyPy never calls ``__len__`` for this purpose, and never calls - ``__length_hint__`` at all. - .. include:: _ref.txt diff --git a/pypy/doc/discussion/improve-rpython.rst b/pypy/doc/discussion/improve-rpython.rst --- a/pypy/doc/discussion/improve-rpython.rst +++ b/pypy/doc/discussion/improve-rpython.rst @@ -15,7 +15,7 @@ from pypy.interpreter.typedef import interp_attrproperty, interp_attrproperty_w from pypy.interpreter.gateway import interp2app from pypy.interpreter.error import OperationError - from pypy.rpython.lltypesystem import rffi, lltype + from rpython.rtyper.lltypesystem import rffi, lltype - A more direct declarative way to write Typedef:: diff --git a/pypy/doc/faq.rst b/pypy/doc/faq.rst --- a/pypy/doc/faq.rst +++ b/pypy/doc/faq.rst @@ -300,12 +300,26 @@ Do I have to rewrite my programs in RPython? -------------------------------------------- -No. And you shouldn't try. PyPy always runs your code in its own interpreter, which is a -full and compliant Python 2.7 interpreter. RPython is only the -language in which parts of PyPy itself are written and extension -modules for it. Not only is it not necessary for you to rewrite your -code in RPython, it probably won't give you any speed improvements if you -try. +No. And you shouldn't try. First and foremost, RPython is a language +that is designed to write interpreters in. It is a restricted subset of +Python. If you program is not an interpreter but tries to do "real +things", like use *any* part of the standard Python library or *any* +3rd-party library, then it is not RPython to start with. You should +only look at RPython if you try to `write your own interpreter`__. + +.. __: `how do I compile my own interpreters`_ + +If your goal is to speed up Python code, then look at the regular PyPy, +which is a full and compliant Python 2.7 interpreter (which happens to +be written in RPython). Not only is it not necessary for you to rewrite +your code in RPython, it might not give you any speed improvements even +if you manage to. + +Yes, it is possible with enough effort to compile small self-contained +pieces of RPython code doing a few performance-sensitive things. But +this case is not interesting for us. If you needed to rewrite the code +in RPython, you could as well have rewritten it in C for example. The +latter is a much more supported, much more documented language `:-)` --------------------------------------------------- Which backends are there for the RPython toolchain? diff --git a/pypy/doc/rffi.rst b/pypy/doc/rffi.rst --- a/pypy/doc/rffi.rst +++ b/pypy/doc/rffi.rst @@ -17,7 +17,7 @@ lltype.Signed or lltype.Array) and memory management must be done by hand. To declare a function, we write:: - from pypy.rpython.lltypesystem import rffi + from rpython.rtyper.lltypesystem import rffi external_function = rffi.llexternal(name, args, result) @@ -31,7 +31,7 @@ libraries and sources by passing in the optional ``compilation_info`` parameter:: - from pypy.rpython.lltypesystem import rffi + from rpython.rtyper.lltypesystem import rffi from rpython.translator.tool.cbuild import ExternalCompilationInfo info = ExternalCompilationInfo(includes=[], libraries=[]) diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst --- a/pypy/doc/whatsnew-head.rst +++ b/pypy/doc/whatsnew-head.rst @@ -34,6 +34,9 @@ .. branch: kill-faking .. branch: improved_ebnfparse_error .. branch: task-decorator +.. branch: fix-e4fa0b2 +.. branch: win32-fixes +.. branch: fix-version-tool .. branch: release-2.0-beta1 diff --git a/pypy/interpreter/app_main.py b/pypy/interpreter/app_main.py --- a/pypy/interpreter/app_main.py +++ b/pypy/interpreter/app_main.py @@ -713,13 +713,13 @@ def pypy_find_stdlib(s): from os.path import abspath, join, dirname as dn thisfile = abspath(__file__) - root = dn(dn(dn(dn(thisfile)))) + root = dn(dn(dn(thisfile))) return [join(root, 'lib-python', '2.7'), join(root, 'lib_pypy')] def pypy_resolvedirof(s): # we ignore the issue of symlinks; for tests, the executable is always - # translator/goal/app_main.py anyway + # interpreter/app_main.py anyway import os return os.path.abspath(os.path.join(s, '..')) diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -1482,9 +1482,10 @@ ) raise w_fd = self.call_function(w_fileno) - if not self.isinstance_w(w_fd, self.w_int): + if (not self.isinstance_w(w_fd, self.w_int) and + not self.isinstance_w(w_fd, self.w_long)): raise OperationError(self.w_TypeError, - self.wrap("fileno() must return an integer") + self.wrap("fileno() returned a non-integer") ) fd = self.int_w(w_fd) if fd < 0: diff --git a/pypy/interpreter/executioncontext.py b/pypy/interpreter/executioncontext.py --- a/pypy/interpreter/executioncontext.py +++ b/pypy/interpreter/executioncontext.py @@ -40,6 +40,7 @@ def gettopframe(self): return self.topframeref() + @jit.unroll_safe def gettopframe_nohidden(self): frame = self.topframeref() while frame and frame.hide(): @@ -343,9 +344,13 @@ signal, the tick counter is set to -1 by C code in signals.h. """ assert isinstance(action, PeriodicAsyncAction) - self._periodic_actions.append(action) + # hack to put the release-the-GIL one at the end of the list, + # and the report-the-signals one at the start of the list. if use_bytecode_counter: + self._periodic_actions.append(action) self.has_bytecode_counter = True + else: + self._periodic_actions.insert(0, action) self._rebuild_action_dispatcher() def getcheckinterval(self): @@ -419,15 +424,6 @@ The action must have been registered at space initalization time.""" self.space.actionflag.fire(self) - def fire_after_thread_switch(self): - """Bit of a hack: fire() the action but only the next time the GIL - is released and re-acquired (i.e. after a potential thread switch). - Don't call this if threads are not enabled. Currently limited to - one action (i.e. reserved for CheckSignalAction from module/signal). - """ - from pypy.module.thread.gil import spacestate - spacestate.action_after_thread_switch = self - def perform(self, executioncontext, frame): """To be overridden.""" diff --git a/pypy/interpreter/miscutils.py b/pypy/interpreter/miscutils.py --- a/pypy/interpreter/miscutils.py +++ b/pypy/interpreter/miscutils.py @@ -17,9 +17,8 @@ def setvalue(self, value): self._value = value - def getmainthreadvalue(self): - return self._value + def ismainthread(self): + return True def getallvalues(self): return {0: self._value} - diff --git a/pypy/interpreter/test2/test_app_main.py b/pypy/interpreter/test2/test_app_main.py --- a/pypy/interpreter/test2/test_app_main.py +++ b/pypy/interpreter/test2/test_app_main.py @@ -547,7 +547,7 @@ assert line.rstrip() == 'Not at all. They could be carried.' print 'A five ounce bird could not carry a one pound coconut.' """) - py_py = os.path.join(pypydir, 'bin', 'py.py') + py_py = os.path.join(pypydir, 'bin', 'pyinteractive.py') child = self._spawn(sys.executable, [py_py, '-S', path]) child.expect('Are you suggesting coconuts migrate?', timeout=120) child.sendline('Not at all. They could be carried.') @@ -774,7 +774,7 @@ assert data == p + os.sep + '\n' def test_getfilesystemencoding(self): - py.test.skip("this has been failing since forever, but it's not tested nightly because buildbot uses python2.6 :-(") + py.test.skip("encoding is only set if stdout.isatty(), test is flawed") if sys.version_info < (2, 7): skip("test requires Python >= 2.7") p = getscript_in_dir(""" @@ -881,7 +881,6 @@ def test_setup_bootstrap_path(self): import sys - import os old_sys_path = sys.path[:] sys.path.append(self.goal_dir) try: @@ -907,7 +906,7 @@ sys.path.append(self.goal_dir) try: import app_main - pypy_c = os.path.join(self.trunkdir, 'pypy', 'translator', 'goal', 'pypy-c') + pypy_c = os.path.join(self.trunkdir, 'pypy', 'goal', 'pypy-c') app_main.setup_bootstrap_path(pypy_c) newpath = sys.path[:] # we get at least lib_pypy @@ -925,7 +924,7 @@ sys.path.append(self.goal_dir) try: import app_main - pypy_c = os.path.join(self.trunkdir, 'pypy', 'translator', 'goal', 'pypy-c') + pypy_c = os.path.join(self.trunkdir, 'pypy', 'goal', 'pypy-c') app_main.entry_point(pypy_c, [self.foo_py]) # assert it did not crash finally: diff --git a/pypy/interpreter/test2/test_targetpypy.py b/pypy/interpreter/test2/test_targetpypy.py --- a/pypy/interpreter/test2/test_targetpypy.py +++ b/pypy/interpreter/test2/test_targetpypy.py @@ -1,5 +1,3 @@ - -import py from pypy.goal.targetpypystandalone import get_entry_point from pypy.config.pypyoption import get_pypy_config @@ -7,6 +5,4 @@ def test_run(self): config = get_pypy_config(translating=False) entry_point = get_entry_point(config)[0] - space = self.space - py.test.skip("not working so far") entry_point(['pypy-c' , '-S', '-c', 'print 3']) diff --git a/pypy/module/__pypy__/interp_identitydict.py b/pypy/module/__pypy__/interp_identitydict.py --- a/pypy/module/__pypy__/interp_identitydict.py +++ b/pypy/module/__pypy__/interp_identitydict.py @@ -33,6 +33,11 @@ except KeyError: raise OperationError(space.w_KeyError, w_key) + def descr_iter(self, space): + raise OperationError(space.w_TypeError, + space.wrap("'identity_dict' object does not support iteration; " + "iterate over x.keys()")) + def get(self, space, w_key, w_default=None): if w_default is None: w_default = space.w_None @@ -50,8 +55,11 @@ W_IdentityDict.typedef = TypeDef("identity_dict", __doc__="""\ A dictionary that considers keys by object identity. -Distinct objects that compare equal will have separate entries. -All objects can be used as keys, even non-hashable ones. +Distinct objects will have separate entries even if they +compare equal. All objects can be used as keys, even +non-hashable ones --- but avoid using immutable objects +like integers: two int objects 42 may or may not be +internally the same object. """, __new__ = interp2app(W_IdentityDict.descr_new.im_func), __len__ = interp2app(W_IdentityDict.descr_len), @@ -59,6 +67,7 @@ __setitem__ = interp2app(W_IdentityDict.descr_setitem), __getitem__ = interp2app(W_IdentityDict.descr_getitem), __delitem__ = interp2app(W_IdentityDict.descr_delitem), + __iter__ = interp2app(W_IdentityDict.descr_iter), get = interp2app(W_IdentityDict.get), keys = interp2app(W_IdentityDict.keys), values = interp2app(W_IdentityDict.values), diff --git a/pypy/module/__pypy__/test/test_identitydict.py b/pypy/module/__pypy__/test/test_identitydict.py --- a/pypy/module/__pypy__/test/test_identitydict.py +++ b/pypy/module/__pypy__/test/test_identitydict.py @@ -56,3 +56,10 @@ assert None in d assert [] not in d + + def test_iterate(self): + from __pypy__ import identity_dict + d = identity_dict() + d[None] = 1 + raises(TypeError, iter, d) + raises(TypeError, list, d) diff --git a/pypy/module/_bisect/interp_bisect.py b/pypy/module/_bisect/interp_bisect.py --- a/pypy/module/_bisect/interp_bisect.py +++ b/pypy/module/_bisect/interp_bisect.py @@ -1,5 +1,6 @@ from pypy.interpreter.error import OperationError from pypy.interpreter.gateway import unwrap_spec +from rpython.rlib.rarithmetic import intmask, r_uint @unwrap_spec(lo=int, hi=int) @@ -18,7 +19,7 @@ if hi == -1: hi = space.len_w(w_a) while lo < hi: - mid = (lo + hi) >> 1 + mid = intmask((r_uint(lo) + r_uint(hi)) >> 1) w_litem = space.getitem(w_a, space.wrap(mid)) if space.is_true(space.lt(w_litem, w_x)): lo = mid + 1 @@ -43,7 +44,7 @@ if hi == -1: hi = space.len_w(w_a) while lo < hi: - mid = (lo + hi) >> 1 + mid = intmask((r_uint(lo) + r_uint(hi)) >> 1) w_litem = space.getitem(w_a, space.wrap(mid)) if space.is_true(space.lt(w_x, w_litem)): hi = mid diff --git a/pypy/module/_bisect/test/test_bisect.py b/pypy/module/_bisect/test/test_bisect.py --- a/pypy/module/_bisect/test/test_bisect.py +++ b/pypy/module/_bisect/test/test_bisect.py @@ -89,3 +89,12 @@ insort_right(a, 6.0) assert a == [0, 5, 6, 6, 6, 6.0, 7] assert map(type, a) == [int, int, int, int, int, float, int] + + def test_bisect_overflow(self): + from _bisect import bisect_left, bisect_right + import sys + + size = sys.maxsize + data = xrange(size - 1) + assert bisect_left(data, size - 3) == size - 3 + assert bisect_right(data, size - 3) == size - 2 diff --git a/pypy/module/_ffi/test/test_funcptr.py b/pypy/module/_ffi/test/test_funcptr.py --- a/pypy/module/_ffi/test/test_funcptr.py +++ b/pypy/module/_ffi/test/test_funcptr.py @@ -96,7 +96,7 @@ libm = CDLL(self.libm_name) pow_addr = libm.getaddressindll('pow') fff = sys.maxint*2-1 - if sys.platform == 'win32': + if sys.platform == 'win32' or sys.platform == 'darwin': fff = sys.maxint*2+1 assert pow_addr == self.pow_addr & fff diff --git a/pypy/module/_file/test/test_file.py b/pypy/module/_file/test/test_file.py --- a/pypy/module/_file/test/test_file.py +++ b/pypy/module/_file/test/test_file.py @@ -430,15 +430,15 @@ assert f.subclass_closed def test_readline_unbuffered_should_read_one_line_only(self): - import posix + import os - with self.file(self.temppath, 'w') as f: + with self.file(self.temppath, 'wb') as f: f.write('foo\nbar\n') - with self.file(self.temppath, 'r', 0) as f: + with self.file(self.temppath, 'rb', 0) as f: s = f.readline() assert s == 'foo\n' - s = posix.read(f.fileno(), 10) + s = os.read(f.fileno(), 10) assert s == 'bar\n' def test_flush_at_exit(): diff --git a/pypy/module/_file/test/test_file_extra.py b/pypy/module/_file/test/test_file_extra.py --- a/pypy/module/_file/test/test_file_extra.py +++ b/pypy/module/_file/test/test_file_extra.py @@ -612,6 +612,7 @@ repr(unicode(self.temptestfile))) f.close() + @py.test.mark.skipif("os.name != 'posix'") def test_EAGAIN(self): import _socket, posix s1, s2 = _socket.socketpair() diff --git a/pypy/module/_io/interp_fileio.py b/pypy/module/_io/interp_fileio.py --- a/pypy/module/_io/interp_fileio.py +++ b/pypy/module/_io/interp_fileio.py @@ -153,41 +153,49 @@ self.readable, self.writable, append, flags = decode_mode(space, mode) - if fd >= 0: - verify_fd(fd) - try: - os.fstat(fd) - except OSError, e: - if e.errno == errno.EBADF: - raise wrap_oserror(space, e) - # else: pass - self.fd = fd - self.closefd = bool(closefd) - else: - if not closefd: - raise OperationError(space.w_ValueError, space.wrap( - "Cannot use closefd=False with file name")) - self.closefd = True + fd_is_own = False + try: + if fd >= 0: + verify_fd(fd) + try: + os.fstat(fd) + except OSError, e: + if e.errno == errno.EBADF: + raise wrap_oserror(space, e) + # else: pass + self.fd = fd + self.closefd = bool(closefd) + else: + self.closefd = True + if not closefd: + raise OperationError(space.w_ValueError, space.wrap( + "Cannot use closefd=False with file name")) - from pypy.module.posix.interp_posix import ( - dispatch_filename, rposix) - try: - self.fd = dispatch_filename(rposix.open)( - space, w_name, flags, 0666) - except OSError, e: - raise wrap_oserror2(space, e, w_name, - exception_name='w_IOError') + from pypy.module.posix.interp_posix import ( + dispatch_filename, rposix) + try: + self.fd = dispatch_filename(rposix.open)( + space, w_name, flags, 0666) + except OSError, e: + raise wrap_oserror2(space, e, w_name, + exception_name='w_IOError') + finally: + fd_is_own = True self._dircheck(space, w_name) - self.w_name = w_name + self.w_name = w_name - if append: - # For consistent behaviour, we explicitly seek to the end of file - # (otherwise, it might be done only on the first write()). - try: - os.lseek(self.fd, 0, os.SEEK_END) - except OSError, e: - raise wrap_oserror(space, e, exception_name='w_IOError') + if append: + # For consistent behaviour, we explicitly seek to the end of file + # (otherwise, it might be done only on the first write()). + try: + os.lseek(self.fd, 0, os.SEEK_END) + except OSError, e: + raise wrap_oserror(space, e, exception_name='w_IOError') + except: + if not fd_is_own: + self.fd = -1 + raise def _mode(self): if self.readable: @@ -253,7 +261,6 @@ except OSError: return if stat.S_ISDIR(st.st_mode): - self._close(space) raise wrap_oserror2(space, OSError(errno.EISDIR, "fstat"), w_filename, exception_name='w_IOError') diff --git a/pypy/module/_io/test/test_fileio.py b/pypy/module/_io/test/test_fileio.py --- a/pypy/module/_io/test/test_fileio.py +++ b/pypy/module/_io/test/test_fileio.py @@ -2,7 +2,7 @@ import os class AppTestFileIO: - spaceconfig = dict(usemodules=['_io']) + spaceconfig = dict(usemodules=['_io'] + (['fcntl'] if os.name != 'nt' else [])) def setup_class(cls): tmpfile = udir.join('tmpfile') @@ -41,7 +41,12 @@ def test_open_directory(self): import _io + import os raises(IOError, _io.FileIO, self.tmpdir, "rb") + if os.name != 'nt': + fd = os.open(self.tmpdir, os.O_RDONLY) + raises(IOError, _io.FileIO, fd, "rb") + os.close(fd) def test_readline(self): import _io diff --git a/pypy/module/_multiprocessing/test/test_connection.py b/pypy/module/_multiprocessing/test/test_connection.py --- a/pypy/module/_multiprocessing/test/test_connection.py +++ b/pypy/module/_multiprocessing/test/test_connection.py @@ -68,7 +68,7 @@ assert rhandle.readable class AppTestWinpipeConnection(BaseConnectionTest): - spaceconfig = dict(usemodules=('_multiprocessing', 'thread')) + spaceconfig = dict(usemodules=('_multiprocessing', 'thread', 'signal')) def setup_class(cls): if sys.platform != "win32": diff --git a/pypy/module/_socket/interp_socket.py b/pypy/module/_socket/interp_socket.py --- a/pypy/module/_socket/interp_socket.py +++ b/pypy/module/_socket/interp_socket.py @@ -181,7 +181,8 @@ try: self.close() except SocketError, e: - raise converted_error(space, e) + # cpython doesn't return any errors on close + pass def connect_w(self, space, w_addr): """connect(address) @@ -448,7 +449,7 @@ w_addr = space.w_None return space.newtuple([space.wrap(readlgt), w_addr]) except SocketError, e: - raise converted_error(space, e) + raise converted_error(space, e) @unwrap_spec(cmd=int) def ioctl_w(self, space, cmd, w_option): diff --git a/pypy/module/_socket/test/test_sock_app.py b/pypy/module/_socket/test/test_sock_app.py --- a/pypy/module/_socket/test/test_sock_app.py +++ b/pypy/module/_socket/test/test_sock_app.py @@ -362,13 +362,15 @@ assert isinstance(s.fileno(), int) def test_socket_close(self): - import _socket + import _socket, os s = _socket.socket(_socket.AF_INET, _socket.SOCK_STREAM, 0) fileno = s.fileno() assert s.fileno() >= 0 s.close() assert s.fileno() < 0 s.close() + if os.name != 'nt': + raises(OSError, os.close, fileno) def test_socket_close_error(self): import _socket, os @@ -376,7 +378,7 @@ skip("Windows sockets are not files") s = _socket.socket(_socket.AF_INET, _socket.SOCK_STREAM, 0) os.close(s.fileno()) - raises(_socket.error, s.close) + s.close() def test_socket_connect(self): import _socket, os diff --git a/pypy/module/cpyext/api.py b/pypy/module/cpyext/api.py --- a/pypy/module/cpyext/api.py +++ b/pypy/module/cpyext/api.py @@ -922,8 +922,8 @@ kwds["link_extra"] = ["msvcrt.lib"] elif sys.platform.startswith('linux'): compile_extra.append("-Werror=implicit-function-declaration") + compile_extra.append('-g') export_symbols_eci.append('pypyAPI') - compile_extra.append('-g') else: kwds["includes"] = ['Python.h'] # this is our Python.h diff --git a/pypy/module/cpyext/longobject.py b/pypy/module/cpyext/longobject.py --- a/pypy/module/cpyext/longobject.py +++ b/pypy/module/cpyext/longobject.py @@ -47,7 +47,12 @@ Return a C unsigned long representation of the contents of pylong. If pylong is greater than ULONG_MAX, an OverflowError is raised.""" - return rffi.cast(rffi.ULONG, space.uint_w(w_long)) + try: + return rffi.cast(rffi.ULONG, space.uint_w(w_long)) + except OperationError, e: + if e.match(space, space.w_ValueError): + e.w_type = space.w_OverflowError + raise @cpython_api([PyObject], rffi.ULONG, error=-1) def PyLong_AsUnsignedLongMask(space, w_long): @@ -86,7 +91,12 @@ Return a C unsigned long representation of the contents of pylong. If pylong is greater than ULONG_MAX, an OverflowError is raised.""" - return rffi.cast(rffi.ULONGLONG, space.r_ulonglong_w(w_long)) + try: + return rffi.cast(rffi.ULONGLONG, space.r_ulonglong_w(w_long)) + except OperationError, e: + if e.match(space, space.w_ValueError): + e.w_type = space.w_OverflowError + raise @cpython_api([PyObject], rffi.ULONGLONG, error=-1) def PyLong_AsUnsignedLongLongMask(space, w_long): diff --git a/pypy/module/cpyext/object.py b/pypy/module/cpyext/object.py --- a/pypy/module/cpyext/object.py +++ b/pypy/module/cpyext/object.py @@ -218,6 +218,8 @@ @cpython_api([PyObject], PyObject) def PyObject_Str(space, w_obj): + if w_obj is None: + return space.wrap("") return space.str(w_obj) @cpython_api([PyObject], PyObject) @@ -226,6 +228,8 @@ representation on success, NULL on failure. This is the equivalent of the Python expression repr(o). Called by the repr() built-in function and by reverse quotes.""" + if w_obj is None: + return space.wrap("") return space.repr(w_obj) @cpython_api([PyObject], PyObject) @@ -234,6 +238,8 @@ string representation on success, NULL on failure. This is the equivalent of the Python expression unicode(o). Called by the unicode() built-in function.""" + if w_obj is None: + return space.wrap(u"") return space.call_function(space.w_unicode, w_obj) @cpython_api([PyObject, PyObject], rffi.INT_real, error=-1) diff --git a/pypy/module/cpyext/test/test_cpyext.py b/pypy/module/cpyext/test/test_cpyext.py --- a/pypy/module/cpyext/test/test_cpyext.py +++ b/pypy/module/cpyext/test/test_cpyext.py @@ -49,6 +49,8 @@ kwds["libraries"] = [api_library] # '%s' undefined; assuming extern returning int kwds["compile_extra"] = ["/we4013"] + elif sys.platform == 'darwin': + kwds["link_files"] = [str(api_library + '.dylib')] else: kwds["link_files"] = [str(api_library + '.so')] if sys.platform.startswith('linux'): diff --git a/pypy/module/cpyext/test/test_longobject.py b/pypy/module/cpyext/test/test_longobject.py --- a/pypy/module/cpyext/test/test_longobject.py +++ b/pypy/module/cpyext/test/test_longobject.py @@ -31,6 +31,8 @@ value = api.PyLong_AsUnsignedLong(w_value) assert value == (sys.maxint - 1) * 2 + self.raises(space, api, OverflowError, api.PyLong_AsUnsignedLong, space.wrap(-1)) + def test_as_ssize_t(self, space, api): w_value = space.newlong(2) value = api.PyLong_AsSsize_t(w_value) @@ -46,11 +48,11 @@ w_l = space.wrap(sys.maxint + 1) assert api.PyLong_Check(w_l) assert api.PyLong_CheckExact(w_l) - + w_i = space.wrap(sys.maxint) assert not api.PyLong_Check(w_i) assert not api.PyLong_CheckExact(w_i) - + L = space.appexec([], """(): class L(long): pass @@ -73,6 +75,8 @@ assert api.PyLong_AsUnsignedLongLongMask( space.wrap(1<<64)) == 0 + self.raises(space, api, OverflowError, api.PyLong_AsUnsignedLongLong, space.wrap(-1)) + def test_as_long_and_overflow(self, space, api): overflow = lltype.malloc(rffi.CArrayPtr(rffi.INT_real).TO, 1, flavor='raw') assert api.PyLong_AsLongAndOverflow( diff --git a/pypy/module/cpyext/test/test_object.py b/pypy/module/cpyext/test/test_object.py --- a/pypy/module/cpyext/test/test_object.py +++ b/pypy/module/cpyext/test/test_object.py @@ -94,27 +94,30 @@ def test_size(self, space, api): assert api.PyObject_Size(space.newlist([space.w_None])) == 1 - + + def test_str(self, space, api): + w_list = space.newlist([space.w_None, space.wrap(42)]) + assert space.str_w(api.PyObject_Str(None)) == "" + assert space.str_w(api.PyObject_Str(w_list)) == "[None, 42]" + assert space.str_w(api.PyObject_Str(space.wrap("a"))) == "a" + def test_repr(self, space, api): w_list = space.newlist([space.w_None, space.wrap(42)]) + assert space.str_w(api.PyObject_Repr(None)) == "" assert space.str_w(api.PyObject_Repr(w_list)) == "[None, 42]" assert space.str_w(api.PyObject_Repr(space.wrap("a"))) == "'a'" - - w_list = space.newlist([space.w_None, space.wrap(42)]) - assert space.str_w(api.PyObject_Str(w_list)) == "[None, 42]" - assert space.str_w(api.PyObject_Str(space.wrap("a"))) == "a" - + def test_RichCompare(self, space, api): def compare(w_o1, w_o2, opid): res = api.PyObject_RichCompareBool(w_o1, w_o2, opid) w_res = api.PyObject_RichCompare(w_o1, w_o2, opid) assert space.is_true(w_res) == res return res - + def test_compare(o1, o2): w_o1 = space.wrap(o1) w_o2 = space.wrap(o2) - + for opid, expected in [ (Py_LT, o1 < o2), (Py_LE, o1 <= o2), (Py_NE, o1 != o2), (Py_EQ, o1 == o2), @@ -190,6 +193,7 @@ api.PyErr_Clear() def test_unicode(self, space, api): + assert space.unwrap(api.PyObject_Unicode(None)) == u"" assert space.unwrap(api.PyObject_Unicode(space.wrap([]))) == u"[]" assert space.unwrap(api.PyObject_Unicode(space.wrap("e"))) == u"e" assert api.PyObject_Unicode(space.wrap("\xe9")) is None diff --git a/pypy/module/crypt/test/test_crypt.py b/pypy/module/crypt/test/test_crypt.py --- a/pypy/module/crypt/test/test_crypt.py +++ b/pypy/module/crypt/test/test_crypt.py @@ -1,6 +1,12 @@ +import os +import py + +if os.name != 'posix': + py.test.skip('crypt module only available on unix') + class AppTestCrypt: spaceconfig = dict(usemodules=['crypt']) - + def test_crypt(self): import crypt res = crypt.crypt("pass", "ab") diff --git a/pypy/module/fcntl/test/test_fcntl.py b/pypy/module/fcntl/test/test_fcntl.py --- a/pypy/module/fcntl/test/test_fcntl.py +++ b/pypy/module/fcntl/test/test_fcntl.py @@ -1,9 +1,9 @@ import os +import py from rpython.tool.udir import udir -if os.name == "nt": - from py.test import skip - skip("fcntl module is not available on Windows") +if os.name != 'posix': + py.test.skip("fcntl module only available on unix") def teardown_module(mod): for i in "abcde": @@ -22,13 +22,23 @@ import sys import struct + class F: + def __init__(self, fn): + self.fn = fn + def fileno(self): + return self.fn + f = open(self.tmp + "b", "w+") fcntl.fcntl(f, 1, 0) fcntl.fcntl(f, 1) + fcntl.fcntl(F(long(f.fileno())), 1) raises(TypeError, fcntl.fcntl, "foo") raises(TypeError, fcntl.fcntl, f, "foo") - raises((IOError, ValueError), fcntl.fcntl, -1, 1, 0) + raises(TypeError, fcntl.fcntl, F("foo"), 1) + raises(ValueError, fcntl.fcntl, -1, 1, 0) + raises(ValueError, fcntl.fcntl, F(-1), 1, 0) + raises(ValueError, fcntl.fcntl, F(long(-1)), 1, 0) assert fcntl.fcntl(f, 1, 0) == 0 assert fcntl.fcntl(f, 2, "foo") == "foo" assert fcntl.fcntl(f, 2, buffer("foo")) == "foo" diff --git a/pypy/module/posix/test/test_posix2.py b/pypy/module/posix/test/test_posix2.py --- a/pypy/module/posix/test/test_posix2.py +++ b/pypy/module/posix/test/test_posix2.py @@ -823,14 +823,19 @@ if hasattr(os, 'chmod'): def test_chmod(self): + import sys os = self.posix os.unlink(self.path) raises(OSError, os.chmod, self.path, 0600) f = open(self.path, "w") f.write("this is a test") f.close() - os.chmod(self.path, 0200) - assert (os.stat(self.path).st_mode & 0777) == 0200 + if sys.platform == 'win32': + os.chmod(self.path, 0400) + assert (os.stat(self.path).st_mode & 0600) == 0400 + else: + os.chmod(self.path, 0200) + assert (os.stat(self.path).st_mode & 0777) == 0200 if hasattr(os, 'fchmod'): def test_fchmod(self): diff --git a/pypy/module/pwd/test/test_pwd.py b/pypy/module/pwd/test/test_pwd.py --- a/pypy/module/pwd/test/test_pwd.py +++ b/pypy/module/pwd/test/test_pwd.py @@ -1,3 +1,9 @@ +import os +import py + +if os.name != 'posix': + py.test.skip('pwd module only available on unix') + class AppTestPwd: spaceconfig = dict(usemodules=['pwd']) diff --git a/pypy/module/rctime/test/test_rctime.py b/pypy/module/rctime/test/test_rctime.py --- a/pypy/module/rctime/test/test_rctime.py +++ b/pypy/module/rctime/test/test_rctime.py @@ -114,7 +114,10 @@ assert rctime.mktime(rctime.localtime(-1)) == -1 res = rctime.mktime((2000, 1, 1, 0, 0, 0, -1, -1, -1)) - assert rctime.ctime(res) == 'Sat Jan 1 00:00:00 2000' + if os.name == 'nt': + assert rctime.ctime(res) == 'Sat Jan 01 00:00:00 2000' + else: + assert rctime.ctime(res) == 'Sat Jan 1 00:00:00 2000' def test_asctime(self): import time as rctime @@ -213,7 +216,7 @@ def test_strftime(self): import time as rctime - import os + import os, sys t = rctime.time() tt = rctime.gmtime(t) @@ -234,6 +237,10 @@ # input to [w]strftime is not kosher. if os.name == 'nt': raises(ValueError, rctime.strftime, '%f') + elif sys.platform == 'darwin': + # darwin strips % of unknown format codes + # http://bugs.python.org/issue9811 + assert rctime.strftime('%f') == 'f' else: assert rctime.strftime('%f') == '%f' diff --git a/pypy/module/signal/__init__.py b/pypy/module/signal/__init__.py --- a/pypy/module/signal/__init__.py +++ b/pypy/module/signal/__init__.py @@ -30,9 +30,10 @@ } def buildloaders(cls): - from pypy.module.signal import interp_signal - for name in interp_signal.signal_names: - signum = getattr(interp_signal, name) + from rpython.rlib import rsignal + + for name in rsignal.signal_names: + signum = getattr(rsignal, name) if signum is not None: Module.interpleveldefs[name] = 'space.wrap(%d)' % (signum,) super(Module, cls).buildloaders() diff --git a/pypy/module/signal/interp_signal.py b/pypy/module/signal/interp_signal.py --- a/pypy/module/signal/interp_signal.py +++ b/pypy/module/signal/interp_signal.py @@ -1,25 +1,28 @@ from __future__ import with_statement + +import signal as cpy_signal +import sys + from pypy.interpreter.error import OperationError, exception_from_errno -from pypy.interpreter.executioncontext import AsyncAction, AbstractActionFlag -from pypy.interpreter.executioncontext import PeriodicAsyncAction +from pypy.interpreter.executioncontext import (AsyncAction, AbstractActionFlag, + PeriodicAsyncAction) from pypy.interpreter.gateway import unwrap_spec -import signal as cpy_signal -from rpython.rtyper.lltypesystem import lltype, rffi -from rpython.rtyper.tool import rffi_platform -from rpython.translator.tool.cbuild import ExternalCompilationInfo -from rpython.conftest import cdir -import py -import sys -from rpython.rlib import jit, rposix + +from rpython.rlib import jit, rposix, rgc +from rpython.rlib.objectmodel import we_are_translated from rpython.rlib.rarithmetic import intmask from rpython.rlib.rsignal import * +from rpython.rtyper.lltypesystem import lltype, rffi + WIN32 = sys.platform == 'win32' + class SignalActionFlag(AbstractActionFlag): # This class uses the C-level pypysig_counter variable as the tick # counter. The C-level signal handler will reset it to -1 whenever - # a signal is received. + # a signal is received. This causes CheckSignalAction.perform() to + # be called. def get_ticker(self): p = pypysig_getaddr_occurred() @@ -29,6 +32,11 @@ p = pypysig_getaddr_occurred() p.c_value = value + @staticmethod + def rearm_ticker(): + p = pypysig_getaddr_occurred() + p.c_value = -1 + def decrement_ticker(self, by): p = pypysig_getaddr_occurred() value = p.c_value @@ -44,94 +52,88 @@ class CheckSignalAction(PeriodicAsyncAction): """An action that is automatically invoked when a signal is received.""" + # Note that this is a PeriodicAsyncAction: it means more precisely + # that it is called whenever the C-level ticker becomes < 0. + # Without threads, it is only ever set to -1 when we receive a + # signal. With threads, it also decrements steadily (but slowly). + def __init__(self, space): + "NOT_RPYTHON" AsyncAction.__init__(self, space) - self.handlers_w = {} - if space.config.objspace.usemodules.thread: - # need a helper action in case signals arrive in a non-main thread - self.pending_signals = {} - self.reissue_signal_action = ReissueSignalAction(space) - else: - self.reissue_signal_action = None + self.pending_signal = -1 + self.fire_in_main_thread = False + if self.space.config.objspace.usemodules.thread: + from pypy.module.thread import gil + gil.after_thread_switch = self._after_thread_switch + + @rgc.no_collect + def _after_thread_switch(self): + if self.fire_in_main_thread: + if self.space.threadlocals.ismainthread(): + self.fire_in_main_thread = False + SignalActionFlag.rearm_ticker() + # this occurs when we just switched to the main thread + # and there is a signal pending: we force the ticker to + # -1, which should ensure perform() is called quickly. @jit.dont_look_inside def perform(self, executioncontext, frame): - while True: - n = pypysig_poll() - if n < 0: + # Poll for the next signal, if any + n = self.pending_signal + if n < 0: n = pypysig_poll() + while n >= 0: + if self.space.config.objspace.usemodules.thread: + in_main = self.space.threadlocals.ismainthread() + else: + in_main = True + if in_main: + # If we are in the main thread, report the signal now, + # and poll more + self.pending_signal = -1 + report_signal(self.space, n) + n = self.pending_signal + if n < 0: n = pypysig_poll() + else: + # Otherwise, arrange for perform() to be called again + # after we switch to the main thread. + self.pending_signal = n + self.fire_in_main_thread = True break - self.perform_signal(executioncontext, n) - @jit.dont_look_inside - def perform_signal(self, executioncontext, n): - if self.reissue_signal_action is None: - # no threads: we can report the signal immediately - self.report_signal(n) - else: - main_ec = self.space.threadlocals.getmainthreadvalue() - if executioncontext is main_ec: - # running in the main thread: we can report the - # signal immediately - self.report_signal(n) - else: - # running in another thread: we need to hack a bit - self.pending_signals[n] = None - self.reissue_signal_action.fire_after_thread_switch() - - @jit.dont_look_inside def set_interrupt(self): "Simulates the effect of a SIGINT signal arriving" - ec = self.space.getexecutioncontext() - self.perform_signal(ec, cpy_signal.SIGINT) + if not we_are_translated(): + self.pending_signal = cpy_signal.SIGINT + # ^^^ may override another signal, but it's just for testing + else: + pypysig_pushback(cpy_signal.SIGINT) + self.fire_in_main_thread = True - @jit.dont_look_inside - def report_signal(self, n): - try: - w_handler = self.handlers_w[n] - except KeyError: - return # no handler, ignore signal - space = self.space - if not space.is_true(space.callable(w_handler)): - return # w_handler is SIG_IGN or SIG_DFL? - # re-install signal handler, for OSes that clear it - pypysig_reinstall(n) - # invoke the app-level handler - ec = space.getexecutioncontext() - w_frame = space.wrap(ec.gettopframe_nohidden()) - space.call_function(w_handler, space.wrap(n), w_frame) +# ____________________________________________________________ - @jit.dont_look_inside - def report_pending_signals(self): - # XXX this logic isn't so complicated but I have no clue how - # to test it :-( - pending_signals = self.pending_signals.keys() - self.pending_signals.clear() - try: - while pending_signals: - self.report_signal(pending_signals.pop()) - finally: - # in case of exception, put the undelivered signals back - # into the dict instead of silently swallowing them - if pending_signals: - for n in pending_signals: - self.pending_signals[n] = None - self.reissue_signal_action.fire() +class Handlers: + def __init__(self, space): + self.handlers_w = {} -class ReissueSignalAction(AsyncAction): - """A special action to help deliver signals to the main thread. If - a non-main thread caught a signal, this action fires after every - thread switch until we land in the main thread. - """ +def _get_handlers(space): + return space.fromcache(Handlers).handlers_w - def perform(self, executioncontext, frame): - main_ec = self.space.threadlocals.getmainthreadvalue() - if executioncontext is main_ec: - # now running in the main thread: we can really report the signals - self.space.check_signal_action.report_pending_signals() - else: - # still running in some other thread: try again later - self.fire_after_thread_switch() + +def report_signal(space, n): + handlers_w = _get_handlers(space) + try: + w_handler = handlers_w[n] + except KeyError: + return # no handler, ignore signal + if not space.is_true(space.callable(w_handler)): + return # w_handler is SIG_IGN or SIG_DFL? + # re-install signal handler, for OSes that clear it + pypysig_reinstall(n) + # invoke the app-level handler + ec = space.getexecutioncontext() + w_frame = space.wrap(ec.gettopframe_nohidden()) + space.call_function(w_handler, space.wrap(n), w_frame) @unwrap_spec(signum=int) @@ -149,11 +151,12 @@ check_signum_exists(space, signum) else: check_signum_in_range(space, signum) - action = space.check_signal_action - if signum in action.handlers_w: - return action.handlers_w[signum] + handlers_w = _get_handlers(space) + if signum in handlers_w: + return handlers_w[signum] return space.wrap(SIG_DFL) + def default_int_handler(space, w_signum, w_frame): """ default_int_handler(...) From noreply at buildbot.pypy.org Sat Feb 2 23:53:23 2013 From: noreply at buildbot.pypy.org (mattip) Date: Sat, 2 Feb 2013 23:53:23 +0100 (CET) Subject: [pypy-commit] pypy missing-ndarray-attributes: unify argsort tests Message-ID: <20130202225323.394431C0134@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: missing-ndarray-attributes Changeset: r60828:d0088c2ebfd8 Date: 2013-02-02 19:02 +0200 http://bitbucket.org/pypy/pypy/changeset/d0088c2ebfd8/ Log: unify argsort tests diff --git a/pypy/module/micronumpy/test/test_numarray.py b/pypy/module/micronumpy/test/test_numarray.py --- a/pypy/module/micronumpy/test/test_numarray.py +++ b/pypy/module/micronumpy/test/test_numarray.py @@ -1639,17 +1639,6 @@ a = array(42) assert _weakref.ref(a) - def test_argsort(self): - from _numpypy import array, arange - assert array(2.0).argsort() == 0 - for dtype in ['int', 'float', 'int8', 'int16', 'float32']: - a = array([6, 4, 1, 3, 8, 3], dtype=dtype) - res = a.argsort() - assert (res == [2, 3, 5, 1, 0, 4]).all() - assert (a == [6, 4, 1, 3, 8, 3]).all() # not modified - a = arange(100) - assert (a.argsort() == a).all() - def test_astype(self): from _numpypy import array b = array(1).astype(float) @@ -2263,7 +2252,7 @@ def test_fromstring(self): import sys - from _numpypy import fromstring, array, uint8, float32, int32 + from _numpypy import fromstring, uint8, float32, int32 a = fromstring(self.data) for i in range(4): @@ -2380,7 +2369,18 @@ assert array([1, 2, 3], 'i2')[::2].tostring() == '\x00\x01\x00\x03' - def test_argsort(self): + def test_argsort_dtypes(self): + from _numpypy import array, arange + assert array(2.0).argsort() == 0 + for dtype in ['int', 'float', 'int8', 'int16', 'float32']: + a = array([6, 4, 1, 3, 8, 3], dtype=dtype) + res = a.argsort() + assert (res == [2, 3, 5, 1, 0, 4]).all() + assert (a == [6, 4, 1, 3, 8, 3]).all() # not modified + a = arange(100) + assert (a.argsort() == a).all() + + def test_argsort_nd(self): from _numpypy import array a = array([[4, 2], [1, 3]]) assert (a.argsort() == [[1, 0], [0, 1]]).all() @@ -2405,7 +2405,7 @@ class AppTestRanges(BaseNumpyAppTest): def test_arange(self): - from _numpypy import arange, array, dtype + from _numpypy import arange, dtype a = arange(3) assert (a == [0, 1, 2]).all() assert a.dtype is dtype(int) From noreply at buildbot.pypy.org Sat Feb 2 23:53:24 2013 From: noreply at buildbot.pypy.org (mattip) Date: Sat, 2 Feb 2013 23:53:24 +0100 (CET) Subject: [pypy-commit] pypy missing-ndarray-attributes: * repace _read, _write with static methods Message-ID: <20130202225324.BA0241C0134@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: missing-ndarray-attributes Changeset: r60829:849864c9f43a Date: 2013-02-03 00:49 +0200 http://bitbucket.org/pypy/pypy/changeset/849864c9f43a/ Log: * repace _read, _write with static methods * unify T, _COMPONENT_T, _STORAGE_T * adapt argsort to use new static methods diff --git a/pypy/module/micronumpy/arrayimpl/sort.py b/pypy/module/micronumpy/arrayimpl/sort.py --- a/pypy/module/micronumpy/arrayimpl/sort.py +++ b/pypy/module/micronumpy/arrayimpl/sort.py @@ -31,16 +31,20 @@ self.indexes = indexes def getitem(self, item): - v = raw_storage_getitem(TP, self.values, item * self.stride_size - + self.start) + #v = raw_storage_getitem(TP, self.values, item * self.stride_size + # + self.start) + v = itemtype.read_from_storage(TP, self.values, self.start, + item*self.stride_size) v = itemtype.for_computation(v) return (v, raw_storage_getitem(lltype.Signed, self.indexes, item * self.index_stride_size + self.index_start)) def setitem(self, idx, item): - raw_storage_setitem(self.values, idx * self.stride_size + - self.start, rffi.cast(TP, item[0])) + #raw_storage_setitem(self.values, idx * self.stride_size + + # self.start, rffi.cast(TP, item[0])) + itemtype.write_to_storage(TP, self.values, self.start, + idx * self.stride_size, item[0]) raw_storage_setitem(self.indexes, idx * self.index_stride_size + self.index_start, item[1]) diff --git a/pypy/module/micronumpy/test/test_numarray.py b/pypy/module/micronumpy/test/test_numarray.py --- a/pypy/module/micronumpy/test/test_numarray.py +++ b/pypy/module/micronumpy/test/test_numarray.py @@ -2371,13 +2371,17 @@ def test_argsort_dtypes(self): from _numpypy import array, arange + nnp = self.non_native_prefix assert array(2.0).argsort() == 0 - for dtype in ['int', 'float', 'int8', 'int16', 'float32']: - a = array([6, 4, 1, 3, 8, 3], dtype=dtype) + for dtype in ['int', 'float', 'int8', 'int16', 'float32', + nnp + 'i2']: + print dtype + a = array([6, 4, 1, 3, 8, 4, 20, 100, 101], dtype=dtype) + c = a.copy() res = a.argsort() - assert (res == [2, 3, 5, 1, 0, 4]).all() - assert (a == [6, 4, 1, 3, 8, 3]).all() # not modified - a = arange(100) + assert (res == [2, 3, 1, 5, 0, 4, 6, 7, 8]).all() + assert (a == c).all() # not modified + a = arange(100, dtype=dtype) assert (a.argsort() == a).all() def test_argsort_nd(self): diff --git a/pypy/module/micronumpy/types.py b/pypy/module/micronumpy/types.py --- a/pypy/module/micronumpy/types.py +++ b/pypy/module/micronumpy/types.py @@ -135,6 +135,7 @@ @specialize.argtype(1) def box(self, value): + # assumes T is both the storage type and the value type return self.BoxType(rffi.cast(self.T, value)) @specialize.argtype(1, 2) @@ -167,25 +168,31 @@ def default_fromstring(self, space): raise NotImplementedError - def _read(self, storage, i, offset): - return raw_storage_getitem(self.T, storage, i + offset) + @staticmethod + def read_from_storage(ST, storage, i, offset): + ret = raw_storage_getitem(ST, storage, i + offset) + return ret def read(self, arr, i, offset, dtype=None): - return self.box(self._read(arr.storage, i, offset)) + return self.box(self.read_from_storage(self.T, + arr.storage, i, offset)) def read_bool(self, arr, i, offset): - return bool(self.for_computation(self._read(arr.storage, i, offset))) + return bool(self.for_computation(self.read_from_storage(self.T, + arr.storage, i, offset))) - def _write(self, storage, i, offset, value): - raw_storage_setitem(storage, i + offset, value) + @staticmethod + def write_to_storage(ST, storage, i, offset, value): + raw_storage_setitem(storage, i + offset, rffi.cast(ST,value)) def store(self, arr, i, offset, box): - self._write(arr.storage, i, offset, self.unbox(box)) + self.write_to_storage(self.T, arr.storage, i, offset, + self.unbox(box)) def fill(self, storage, width, box, start, stop, offset): value = self.unbox(box) for i in xrange(start, stop, width): - self._write(storage, i, offset, value) + self.write_to_storage(self.T, storage, i, offset, value) def runpack_str(self, s): v = runpack(self.format_code, s) @@ -301,13 +308,16 @@ class NonNativePrimitive(Primitive): _mixin_ = True - def _read(self, storage, i, offset): - res = raw_storage_getitem(self.T, storage, i + offset) - return byteswap(res) + @staticmethod + def read_from_storage(ST, storage, i, offset): + res = raw_storage_getitem(ST, storage, i + offset) + res = rffi.cast(ST, res) # create a copy for inplace byteswap + return rffi.cast(ST, byteswap(res)) - def _write(self, storage, i, offset, value): - value = byteswap(value) - raw_storage_setitem(storage, i + offset, value) + @staticmethod + def write_to_storage(ST, storage, i, offset, value): + h = byteswap(rffi.cast(ST, value)) + raw_storage_setitem(storage, i + offset, h) class Bool(BaseType, Primitive): _attrs_ = () @@ -946,26 +956,27 @@ class NonNativeFloat(NonNativePrimitive, Float): _mixin_ = True - def _read(self, storage, i, offset): - res = raw_storage_getitem(self.T, storage, i + offset) - return rffi.cast(lltype.Float, byteswap(res)) + @staticmethod + def read_from_storage(ST, storage, i, offset): + res = raw_storage_getitem(ST, storage, i + offset) + return byteswap(res) - def _write(self, storage, i, offset, value): - swapped_value = byteswap(rffi.cast(self.T, value)) - raw_storage_setitem(storage, i + offset, swapped_value) + @staticmethod + def write_to_storage(ST, storage, i, offset, value): + swapped_value = byteswap(value) + raw_storage_setitem(storage, i + offset, rffi.cast(ST, swapped_value)) class BaseFloat16(Float): + '''This is the only class where the storage type is different from + the underlying ideal type, since C has no 16 bit float + ''' _mixin_ = True _attrs_ = () - _STORAGE_T = rffi.USHORT - T = rffi.DOUBLE + T = rffi.USHORT BoxType = interp_boxes.W_Float16Box - def get_element_size(self): - return rffi.sizeof(self._STORAGE_T) - def runpack_str(self, s): assert len(s) == 2 fval = unpack_float(s, native_is_bigendian) @@ -976,29 +987,50 @@ def byteswap(self, w_v): value = self.unbox(w_v) - hbits = float_pack(value,2) - swapped = byteswap(rffi.cast(self._STORAGE_T, hbits)) + hbits = float_pack(float(value),2) + swapped = byteswap(rffi.cast(self.T, hbits)) return self.box(float_unpack(r_ulonglong(swapped), 2)) + @staticmethod + def for_computation(v): + return rffi.cast(rffi.DOUBLE, v) + + @specialize.argtype(1) + def box(self, value): + # stored as a USHORT, boxed into a DOUBLE + return self.BoxType(rffi.cast(rffi.DOUBLE, value)) + + @specialize.argtype(1, 2) + def box_complex(self, real, imag): + #XXX this is the place to display a warning + return self.BoxType(rffi.cast(rffi.DOUBLE, real)) + + class Float16(BaseType, BaseFloat16): - def _read(self, storage, i, offset): - hbits = raw_storage_getitem(self._STORAGE_T, storage, i + offset) + @staticmethod + def read_from_storage(ST, storage, i, offset): + hbits = raw_storage_getitem(ST, storage, i + offset) return float_unpack(r_ulonglong(hbits), 2) - def _write(self, storage, i, offset, value): - hbits = float_pack(value,2) + @staticmethod + def write_to_storage(ST, storage, i, offset, value): + # value can be a r_singlefloat + hbits = float_pack(float(value),2) raw_storage_setitem(storage, i + offset, - rffi.cast(self._STORAGE_T, hbits)) + rffi.cast(ST, hbits)) class NonNativeFloat16(BaseType, BaseFloat16): - def _read(self, storage, i, offset): - hbits = raw_storage_getitem(self._STORAGE_T, storage, i + offset) - return float_unpack(r_ulonglong(byteswap(hbits)), 2) + @staticmethod + def read_from_storage(ST, storage, i, offset): + hbits = raw_storage_getitem(ST, storage, i + offset) + r = float_unpack(r_ulonglong(byteswap(hbits)), 2) + return r - def _write(self, storage, i, offset, value): - hbits = float_pack(value,2) + @staticmethod + def write_to_storage(ST, storage, i, offset, value): + hbits = float_pack(float(value),2) raw_storage_setitem(storage, i + offset, - byteswap(rffi.cast(self._STORAGE_T, hbits))) + byteswap(rffi.cast(ST, hbits))) class Float32(BaseType, Float): @@ -1015,13 +1047,10 @@ BoxType = interp_boxes.W_Float32Box format_code = "f" - def read_bool(self, arr, i, offset): - # it's not clear to me why this is needed - # but a hint might be that calling for_computation(v) - # causes translation to fail, and the assert is necessary - v = self._read(arr.storage, i, offset) - assert isinstance(v, float) - return bool(v) + #def read_bool(self, arr, i, offset): + # v = self.for_computation(self.read_from_storage(self.STORAGE_T, + # arr.storage, i, offset)) + # return bool(v) class Float64(BaseType, Float): _attrs_ = () @@ -1075,11 +1104,11 @@ return float(v[0]), float(v[1]) def read_bool(self, arr, i, offset): - v = self.for_computation(self._read(arr.storage, i, offset)) + v = self.for_computation(self.read_from_storage(self.T, arr.storage, i, offset)) return bool(v[0]) or bool(v[1]) def get_element_size(self): - return 2 * rffi.sizeof(self._COMPONENTS_T) + return 2 * rffi.sizeof(self.T) def byteswap(self, w_v): real, imag = self.unbox(w_v) @@ -1088,19 +1117,19 @@ @specialize.argtype(1) def box(self, value): return self.BoxType( - rffi.cast(self._COMPONENTS_T, value), - rffi.cast(self._COMPONENTS_T, 0.0)) + rffi.cast(self.T, value), + rffi.cast(self.T, 0.0)) @specialize.argtype(1) def box_component(self, value): return self.ComponentBoxType( - rffi.cast(self._COMPONENTS_T, value)) + rffi.cast(self.T, value)) @specialize.argtype(1, 2) def box_complex(self, real, imag): return self.BoxType( - rffi.cast(self._COMPONENTS_T, real), - rffi.cast(self._COMPONENTS_T, imag)) + rffi.cast(self.T, real), + rffi.cast(self.T, imag)) def unbox(self, box): assert isinstance(box, self.BoxType) @@ -1112,16 +1141,18 @@ real, imag = self.unbox(box) raw_storage_setitem(arr.storage, i+offset, real) raw_storage_setitem(arr.storage, - i+offset+rffi.sizeof(self._COMPONENTS_T), imag) + i+offset+rffi.sizeof(self.T), imag) - def _read(self, storage, i, offset): - real = raw_storage_getitem(self._COMPONENTS_T, storage, i + offset) - imag = raw_storage_getitem(self._COMPONENTS_T, storage, - i + offset + rffi.sizeof(self._COMPONENTS_T)) + @staticmethod + def read_from_storage(ST, storage, i, offset): + real = raw_storage_getitem(ST, storage, i + offset) + imag = raw_storage_getitem(ST, storage, + i + offset + rffi.sizeof(ST)) return real, imag def read(self, arr, i, offset, dtype=None): - real, imag = self._read(arr.storage, i, offset) + real, imag = self.read_from_storage(self.T, arr.storage, i, + offset) return self.box_complex(real, imag) @complex_binary_op @@ -1535,8 +1566,7 @@ class Complex64(ComplexFloating, BaseType): _attrs_ = () - T = rffi.CHAR - _COMPONENTS_T = rffi.FLOAT + T = rffi.FLOAT BoxType = interp_boxes.W_Complex64Box ComponentBoxType = interp_boxes.W_Float32Box @@ -1546,8 +1576,7 @@ class Complex128(ComplexFloating, BaseType): _attrs_ = () - T = rffi.CHAR - _COMPONENTS_T = rffi.DOUBLE + T = rffi.DOUBLE BoxType = interp_boxes.W_Complex128Box ComponentBoxType = interp_boxes.W_Float64Box @@ -1579,8 +1608,7 @@ class Complex192(ComplexFloating, BaseType): _attrs_ = () - T = rffi.CHAR - _COMPONENTS_T = rffi.LONGDOUBLE + T = rffi.LONGDOUBLE BoxType = interp_boxes.W_Complex192Box ComponentBoxType = interp_boxes.W_Float96Box @@ -1611,8 +1639,7 @@ class Complex256(ComplexFloating, BaseType): _attrs_ = () - T = rffi.CHAR - _COMPONENTS_T = rffi.LONGDOUBLE + T = rffi.LONGDOUBLE BoxType = interp_boxes.W_Complex256Box ComponentBoxType = interp_boxes.W_Float128Box From noreply at buildbot.pypy.org Sun Feb 3 00:54:31 2013 From: noreply at buildbot.pypy.org (fijal) Date: Sun, 3 Feb 2013 00:54:31 +0100 (CET) Subject: [pypy-commit] pypy incremental-nursery-cleanup: This branch has been merged to jitframe-on-heap. Reopen if you want to fight Message-ID: <20130202235431.07A141C009B@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: incremental-nursery-cleanup Changeset: r60830:19668005fd05 Date: 2013-02-03 01:53 +0200 http://bitbucket.org/pypy/pypy/changeset/19668005fd05/ Log: This branch has been merged to jitframe-on-heap. Reopen if you want to fight set_extra_threshold and merge to default. From noreply at buildbot.pypy.org Sun Feb 3 01:03:18 2013 From: noreply at buildbot.pypy.org (fijal) Date: Sun, 3 Feb 2013 01:03:18 +0100 (CET) Subject: [pypy-commit] pypy default: put OrderedDict back in the namespace Message-ID: <20130203000318.3EBF71C009B@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r60831:babd551bbacd Date: 2013-02-03 02:02 +0200 http://bitbucket.org/pypy/pypy/changeset/babd551bbacd/ Log: put OrderedDict back in the namespace diff --git a/lib-python/2.7/collections.py b/lib-python/2.7/collections.py --- a/lib-python/2.7/collections.py +++ b/lib-python/2.7/collections.py @@ -328,7 +328,8 @@ # Execute the template string in a temporary namespace and # support tracing utilities by setting a value for frame.f_globals['__name__'] - namespace = {'__name__': 'namedtuple_%s' % typename} + namespace = {'__name__': 'namedtuple_%s' % typename, + 'OrderedDict': OrderedDict} try: exec template in namespace except SyntaxError, e: From noreply at buildbot.pypy.org Sun Feb 3 01:13:39 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Sun, 3 Feb 2013 01:13:39 +0100 (CET) Subject: [pypy-commit] pypy jit-sys-exc-info: Unroll this. Not a generally safe solution, but demonstrates the concept. Message-ID: <20130203001339.B09741C009B@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: jit-sys-exc-info Changeset: r60832:c16f1d159c6e Date: 2013-02-02 16:13 -0800 http://bitbucket.org/pypy/pypy/changeset/c16f1d159c6e/ Log: Unroll this. Not a generally safe solution, but demonstrates the concept. diff --git a/pypy/interpreter/executioncontext.py b/pypy/interpreter/executioncontext.py --- a/pypy/interpreter/executioncontext.py +++ b/pypy/interpreter/executioncontext.py @@ -157,9 +157,12 @@ self._trace(frame, 'exception', None, operationerr) #operationerr.print_detailed_traceback(self.space) - def sys_exc_info(self): # attn: the result is not the wrapped sys.exc_info() !!! - """Implements sys.exc_info(). - Return an OperationError instance or None.""" + @jit.unroll_safe + def sys_exc_info(self): + """ + Implements sys.exc_info(). It does not have the same return type as + sys.exc_info(). Return an OperationError instance or None. + """ frame = self.gettopframe_nohidden() while frame: if frame.last_exception is not None: From noreply at buildbot.pypy.org Sun Feb 3 03:21:40 2013 From: noreply at buildbot.pypy.org (rlamy) Date: Sun, 3 Feb 2013 03:21:40 +0100 (CET) Subject: [pypy-commit] pypy kill-flowobjspace: pass already unpacked args to special cases Message-ID: <20130203022140.67B1A1C009B@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: kill-flowobjspace Changeset: r60833:97725c1effff Date: 2013-02-02 20:02 +0000 http://bitbucket.org/pypy/pypy/changeset/97725c1effff/ Log: pass already unpacked args to special cases diff --git a/rpython/flowspace/flowcontext.py b/rpython/flowspace/flowcontext.py --- a/rpython/flowspace/flowcontext.py +++ b/rpython/flowspace/flowcontext.py @@ -1019,7 +1019,7 @@ def UNPACK_SEQUENCE(self, itemcount, next_instr): w_iterable = self.popvalue() - items = self.space.unpacksequence(w_iterable, itemcount) + items = self.space.unpack_sequence(w_iterable, itemcount) self.pushrevvalues(itemcount, items) def slice(self, w_start, w_end): diff --git a/rpython/flowspace/objspace.py b/rpython/flowspace/objspace.py --- a/rpython/flowspace/objspace.py +++ b/rpython/flowspace/objspace.py @@ -271,7 +271,7 @@ else: raise UnwrapException("cannot unpack a Variable iterable ") - def unpacksequence(self, w_iterable, expected_length): + def unpack_sequence(self, w_iterable, expected_length): if isinstance(w_iterable, Constant): l = list(self.unwrap(w_iterable)) if len(l) != expected_length: @@ -412,7 +412,9 @@ except (KeyError, TypeError): pass else: - return sc(self, fn, args) + args_w, kwds_w = args.unpack() + assert kwds_w == {}, "should not call %r with keyword arguments" % (fn,) + return sc(self, fn, args_w) try: args_w, kwds_w = args.unpack() diff --git a/rpython/flowspace/specialcase.py b/rpython/flowspace/specialcase.py --- a/rpython/flowspace/specialcase.py +++ b/rpython/flowspace/specialcase.py @@ -3,16 +3,12 @@ from rpython.rlib.rarithmetic import r_uint from rpython.rlib.objectmodel import we_are_translated -def sc_import(space, fn, args): - args_w, kwds_w = args.unpack() - assert kwds_w == {}, "should not call %r with keyword arguments" % (fn,) +def sc_import(space, fn, args_w): assert len(args_w) > 0 and len(args_w) <= 5, 'import needs 1 to 5 arguments' args = [space.unwrap(arg) for arg in args_w] return space.import_name(*args) -def sc_operator(space, fn, args): - args_w, kwds_w = args.unpack() - assert kwds_w == {}, "should not call %r with keyword arguments" % (fn,) +def sc_operator(space, fn, args_w): opname = OperationName[fn] if len(args_w) != Arity[opname]: if opname == 'pow' and len(args_w) == 2: @@ -51,18 +47,16 @@ # _________________________________________________________________________ -def sc_r_uint(space, r_uint, args): +def sc_r_uint(space, r_uint, args_w): # special case to constant-fold r_uint(32-bit-constant) # (normally, the 32-bit constant is a long, and is not allowed to # show up in the flow graphs at all) - args_w, kwds_w = args.unpack() - assert not kwds_w [w_value] = args_w if isinstance(w_value, Constant): return Constant(r_uint(w_value.value)) return space.frame.do_operation('simple_call', space.wrap(r_uint), w_value) -def sc_we_are_translated(space, we_are_translated, args): +def sc_we_are_translated(space, we_are_translated, args_w): return Constant(True) SPECIAL_CASES = {__import__: sc_import, r_uint: sc_r_uint, From noreply at buildbot.pypy.org Sun Feb 3 03:21:41 2013 From: noreply at buildbot.pypy.org (rlamy) Date: Sun, 3 Feb 2013 03:21:41 +0100 (CET) Subject: [pypy-commit] pypy kill-flowobjspace: kill CallSpec.unpack() Message-ID: <20130203022141.CA04E1C009B@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: kill-flowobjspace Changeset: r60834:f84990947cae Date: 2013-02-03 01:48 +0000 http://bitbucket.org/pypy/pypy/changeset/f84990947cae/ Log: kill CallSpec.unpack() diff --git a/rpython/flowspace/argument.py b/rpython/flowspace/argument.py --- a/rpython/flowspace/argument.py +++ b/rpython/flowspace/argument.py @@ -86,15 +86,6 @@ self.arguments_w = args_w self.keywords = keywords or {} - def unpack(self): - "Return a ([w1,w2...], {'kw':w3...}) pair." - if self.w_stararg is not None: - stargs_w = self.space.unpackiterable(self.w_stararg) - args_w = self.arguments_w + stargs_w - else: - args_w = self.arguments_w - return args_w, self.keywords - def flatten(self): """ Argument <-> list of w_objects together with "shape" information """ shape_cnt = len(self.arguments_w) # Number of positional args diff --git a/rpython/flowspace/objspace.py b/rpython/flowspace/objspace.py --- a/rpython/flowspace/objspace.py +++ b/rpython/flowspace/objspace.py @@ -412,23 +412,23 @@ except (KeyError, TypeError): pass else: - args_w, kwds_w = args.unpack() - assert kwds_w == {}, "should not call %r with keyword arguments" % (fn,) + assert args.keywords == {}, "should not call %r with keyword arguments" % (fn,) + if args.w_stararg is not None: + args_w = args.arguments_w + self.unpackiterable(args.w_stararg) + else: + args_w = args.arguments_w return sc(self, fn, args_w) - try: - args_w, kwds_w = args.unpack() - except UnwrapException: - args_w, kwds_w = '?', '?' - # NOTE: annrpython needs to know about the following two operations! - if not kwds_w: - # simple case + if args.keywords or isinstance(args.w_stararg, Variable): + shape, args_w = args.flatten() + w_res = self.frame.do_operation('call_args', w_callable, + Constant(shape), *args_w) + else: + if args.w_stararg is not None: + args_w = args.arguments_w + self.unpackiterable(args.w_stararg) + else: + args_w = args.arguments_w w_res = self.frame.do_operation('simple_call', w_callable, *args_w) - else: - # general case - shape, args_w = args.flatten() - w_res = self.frame.do_operation('call_args', w_callable, Constant(shape), - *args_w) # maybe the call has generated an exception (any one) # but, let's say, not if we are calling a built-in class or function From noreply at buildbot.pypy.org Sun Feb 3 03:21:43 2013 From: noreply at buildbot.pypy.org (rlamy) Date: Sun, 3 Feb 2013 03:21:43 +0100 (CET) Subject: [pypy-commit] pypy kill-flowobjspace: rm useless space attr from CallSpec Message-ID: <20130203022143.0F7851C009B@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: kill-flowobjspace Changeset: r60835:2e055d6595a3 Date: 2013-02-03 02:14 +0000 http://bitbucket.org/pypy/pypy/changeset/2e055d6595a3/ Log: rm useless space attr from CallSpec diff --git a/rpython/flowspace/argument.py b/rpython/flowspace/argument.py --- a/rpython/flowspace/argument.py +++ b/rpython/flowspace/argument.py @@ -77,11 +77,10 @@ """Represents the arguments passed into a function call, i.e. the `a, b, *c, **d` part in `return func(a, b, *c, **d)`. """ - def __init__(self, space, args_w, keywords=None, w_stararg=None, + def __init__(self, args_w, keywords=None, w_stararg=None, w_starstararg=None): self.w_stararg = w_stararg assert w_starstararg is None, "No **-unpacking in RPython" - self.space = space assert isinstance(args_w, list) self.arguments_w = args_w self.keywords = keywords or {} diff --git a/rpython/flowspace/flowcontext.py b/rpython/flowspace/flowcontext.py --- a/rpython/flowspace/flowcontext.py +++ b/rpython/flowspace/flowcontext.py @@ -982,7 +982,7 @@ key = self.space.str_w(w_key) keywords[key] = w_value arguments = self.popvalues(n_arguments) - args = CallSpec(self.space, arguments, keywords, w_star, w_starstar) + args = CallSpec(arguments, keywords, w_star, w_starstar) w_function = self.popvalue() w_result = self.space.call_args(w_function, args) self.pushvalue(w_result) diff --git a/rpython/flowspace/objspace.py b/rpython/flowspace/objspace.py --- a/rpython/flowspace/objspace.py +++ b/rpython/flowspace/objspace.py @@ -393,7 +393,7 @@ return self.call_function(w_meth, *arg_w) def call_function(self, w_func, *args_w): - args = CallSpec(self, list(args_w)) + args = CallSpec(list(args_w)) return self.call_args(w_func, args) def appcall(self, func, *args_w): From noreply at buildbot.pypy.org Sun Feb 3 13:32:19 2013 From: noreply at buildbot.pypy.org (fijal) Date: Sun, 3 Feb 2013 13:32:19 +0100 (CET) Subject: [pypy-commit] pypy default: unroll contains__Tuple in case we know the length (tuples are immutable) Message-ID: <20130203123219.EEE091C0183@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r60836:c915d5e1101c Date: 2013-02-03 14:31 +0200 http://bitbucket.org/pypy/pypy/changeset/c915d5e1101c/ Log: unroll contains__Tuple in case we know the length (tuples are immutable) diff --git a/pypy/objspace/std/tupleobject.py b/pypy/objspace/std/tupleobject.py --- a/pypy/objspace/std/tupleobject.py +++ b/pypy/objspace/std/tupleobject.py @@ -85,6 +85,15 @@ start, stop = normalize_simple_slice(space, length, w_start, w_stop) return space.newtuple(w_tuple.wrappeditems[start:stop]) +THRESHOLD = 7 + +def unroll_tuple_contains(space, w_tuple, w_obj): + if (jit.isconstant(w_tuple) or jit.isvirtual(w_tuple) and + len(w_tuple.wrappeditems) < THRESHOLD): + return True + return False + + at jit.look_inside_iff(unroll_tuple_contains) def contains__Tuple_ANY(space, w_tuple, w_obj): for w_item in w_tuple.wrappeditems: if space.eq_w(w_item, w_obj): From noreply at buildbot.pypy.org Sun Feb 3 14:27:43 2013 From: noreply at buildbot.pypy.org (hakanardo) Date: Sun, 3 Feb 2013 14:27:43 +0100 (CET) Subject: [pypy-commit] benchmarks default: cleanup Message-ID: <20130203132743.75E871C02AF@cobra.cs.uni-duesseldorf.de> Author: Hakan Ardo Branch: Changeset: r197:a65e277ad75c Date: 2013-02-03 14:25 +0100 http://bitbucket.org/pypy/benchmarks/changeset/a65e277ad75c/ Log: cleanup diff --git a/benchmarks.py b/benchmarks.py --- a/benchmarks.py +++ b/benchmarks.py @@ -202,22 +202,14 @@ BM_cpython_doc.benchmark_name = 'sphinx' -if 1: - _register_new_bm_base_only('scimark', 'scimark_SOR', globals(), - extra_args=['--benchmark=SOR', '100', '5000', 'Array2D']) - #_register_new_bm('scimark', 'scimark_SOR_large', globals(), - # extra_args=['--benchmark=SOR', '1000', '25', 'Array2D']) - _register_new_bm_base_only('scimark', 'scimark_SparseMatMult', globals(), - extra_args=['--benchmark=SparseMatMult', '1000', '50000', '2000']) - #_register_new_bm('scimark', 'scimark_SparseMatMult_large', globals(), - # extra_args=['--benchmark=SparseMatMult', '100000', '1000000', '102']) - _register_new_bm_base_only('scimark', 'scimark_MonteCarlo', globals(), - extra_args=['--benchmark=MonteCarlo', '5000000']) - _register_new_bm_base_only('scimark', 'scimark_LU', globals(), - extra_args=['--benchmark=LU', '100', '200']) - #_register_new_bm('scimark', 'scimark_LU_large', globals(), - # extra_args=['--benchmark=LU', '1000', '1']) - _register_new_bm_base_only('scimark', 'scimark_FFT', globals(), - extra_args=['--benchmark=FFT', '1024', '1000']) - #_register_new_bm('scimark', 'scimark_FFT_large', globals(), - # extra_args=['--benchmark=FFT', '1048576', '1']) +# Scimark +_register_new_bm_base_only('scimark', 'scimark_SOR', globals(), + extra_args=['--benchmark=SOR', '100', '5000', 'Array2D']) +_register_new_bm_base_only('scimark', 'scimark_SparseMatMult', globals(), + extra_args=['--benchmark=SparseMatMult', '1000', '50000', '2000']) +_register_new_bm_base_only('scimark', 'scimark_MonteCarlo', globals(), + extra_args=['--benchmark=MonteCarlo', '5000000']) +_register_new_bm_base_only('scimark', 'scimark_LU', globals(), + extra_args=['--benchmark=LU', '100', '200']) +_register_new_bm_base_only('scimark', 'scimark_FFT', globals(), + extra_args=['--benchmark=FFT', '1024', '1000']) From noreply at buildbot.pypy.org Sun Feb 3 14:27:42 2013 From: noreply at buildbot.pypy.org (hakanardo) Date: Sun, 3 Feb 2013 14:27:42 +0100 (CET) Subject: [pypy-commit] benchmarks default: increase the scimark cycle count again and dont run it without the jit Message-ID: <20130203132742.26D491C0183@cobra.cs.uni-duesseldorf.de> Author: Hakan Ardo Branch: Changeset: r196:3017c914934a Date: 2013-02-03 14:23 +0100 http://bitbucket.org/pypy/benchmarks/changeset/3017c914934a/ Log: increase the scimark cycle count again and dont run it without the jit diff --git a/benchmarks.py b/benchmarks.py --- a/benchmarks.py +++ b/benchmarks.py @@ -1,6 +1,8 @@ import os import logging from unladen_swallow.perf import SimpleBenchmark, MeasureGeneric +from unladen_swallow.perf import RawResult, SimpleComparisonResult, avg, ResultError +import subprocess def relative(*args): return os.path.join(os.path.dirname(os.path.abspath(__file__)), *args) @@ -36,6 +38,22 @@ BM.func_name = 'BM_' + bm_name d[BM.func_name] = BM + +def _register_new_bm_base_only(name, bm_name, d, **opts): + def benchmark_function(python, options): + bm_path = relative('own', name + '.py') + return MeasureGeneric(python, options, bm_path, **opts) + + def BM(base_python, changed_python, options, *args, **kwargs): + try: + base_data = benchmark_function(base_python, options, + *args, **kwargs) + except subprocess.CalledProcessError, e: + return ResultError(e) + return SimpleComparisonResult(avg(base_data[0]), -1, -1) + BM.func_name = 'BM_' + bm_name + + d[BM.func_name] = BM TWISTED = [relative('lib/twisted-trunk'), relative('lib/zope.interface-3.5.3/src'), relative('own/twisted')] @@ -130,8 +148,6 @@ pypy-c-jit in the nightly benchmarks, we are not interested in ``changed_python`` (aka pypy-c-nojit) right now. """ - from unladen_swallow.perf import RawResult - import subprocess translate_py = relative('lib/pypy/pypy/translator/goal/translate.py') #targetnop = relative('lib/pypy/pypy/translator/goal/targetnopstandalone.py') @@ -187,21 +203,21 @@ BM_cpython_doc.benchmark_name = 'sphinx' if 1: - _register_new_bm('scimark', 'scimark_SOR', globals(), - extra_args=['--benchmark=SOR', '100', '50', 'Array2D']) + _register_new_bm_base_only('scimark', 'scimark_SOR', globals(), + extra_args=['--benchmark=SOR', '100', '5000', 'Array2D']) #_register_new_bm('scimark', 'scimark_SOR_large', globals(), # extra_args=['--benchmark=SOR', '1000', '25', 'Array2D']) - _register_new_bm('scimark', 'scimark_SparseMatMult', globals(), - extra_args=['--benchmark=SparseMatMult', '1000', '50000', '200']) + _register_new_bm_base_only('scimark', 'scimark_SparseMatMult', globals(), + extra_args=['--benchmark=SparseMatMult', '1000', '50000', '2000']) #_register_new_bm('scimark', 'scimark_SparseMatMult_large', globals(), # extra_args=['--benchmark=SparseMatMult', '100000', '1000000', '102']) - _register_new_bm('scimark', 'scimark_MonteCarlo', globals(), - extra_args=['--benchmark=MonteCarlo', '500000']) - _register_new_bm('scimark', 'scimark_LU', globals(), - extra_args=['--benchmark=LU', '100', '5']) + _register_new_bm_base_only('scimark', 'scimark_MonteCarlo', globals(), + extra_args=['--benchmark=MonteCarlo', '5000000']) + _register_new_bm_base_only('scimark', 'scimark_LU', globals(), + extra_args=['--benchmark=LU', '100', '200']) #_register_new_bm('scimark', 'scimark_LU_large', globals(), # extra_args=['--benchmark=LU', '1000', '1']) - _register_new_bm('scimark', 'scimark_FFT', globals(), - extra_args=['--benchmark=FFT', '1024', '100']) + _register_new_bm_base_only('scimark', 'scimark_FFT', globals(), + extra_args=['--benchmark=FFT', '1024', '1000']) #_register_new_bm('scimark', 'scimark_FFT_large', globals(), # extra_args=['--benchmark=FFT', '1048576', '1']) From noreply at buildbot.pypy.org Sun Feb 3 16:08:09 2013 From: noreply at buildbot.pypy.org (fijal) Date: Sun, 3 Feb 2013 16:08:09 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: Try to fix the problem with redirect_call_assembler Message-ID: <20130203150809.7242E1C009B@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r60837:9e0fcf9d51a9 Date: 2013-02-03 17:03 +0200 http://bitbucket.org/pypy/pypy/changeset/9e0fcf9d51a9/ Log: Try to fix the problem with redirect_call_assembler diff --git a/rpython/jit/backend/arm/opassembler.py b/rpython/jit/backend/arm/opassembler.py --- a/rpython/jit/backend/arm/opassembler.py +++ b/rpython/jit/backend/arm/opassembler.py @@ -1294,6 +1294,8 @@ # we overwrite the instructions at the old _arm_func_adddr # to start with a JMP to the new _arm_func_addr. # Ideally we should rather patch all existing CALLs, but well. + XXX # this is wrong, copy the logic from x86, but also, shouldn't + # it live on a base class instead? oldadr = oldlooptoken._arm_func_addr target = newlooptoken._arm_func_addr mc = ARMv7Builder() diff --git a/rpython/jit/backend/model.py b/rpython/jit/backend/model.py --- a/rpython/jit/backend/model.py +++ b/rpython/jit/backend/model.py @@ -1,3 +1,4 @@ +import weakref from rpython.rlib.debug import debug_start, debug_print, debug_stop from rpython.rtyper.lltypesystem import lltype @@ -293,25 +294,14 @@ self.cpu = cpu self.number = number self.bridges_count = 0 - # This growing list gives the 'descr_number' of all fail descrs - # that belong to this loop or to a bridge attached to it. - # Filled by the frontend calling record_faildescr_index(). - self.faildescr_indices = [] self.invalidate_positions = [] + # a list of weakrefs to looptokens that has been redirected to + # this one + self.looptokens_redirected_to = [] debug_start("jit-mem-looptoken-alloc") debug_print("allocating Loop #", self.number) debug_stop("jit-mem-looptoken-alloc") - def record_faildescr_index(self, n): - self.faildescr_indices.append(n) - - def reserve_and_record_some_faildescr_index(self): - # like record_faildescr_index(), but invent and return a new, - # unused faildescr index - n = self.cpu.reserve_some_free_fail_descr_number() - self.record_faildescr_index(n) - return n - def compiling_a_bridge(self): self.cpu.tracker.total_compiled_bridges += 1 self.bridges_count += 1 @@ -319,6 +309,19 @@ debug_print("allocating Bridge #", self.bridges_count, "of Loop #", self.number) debug_stop("jit-mem-looptoken-alloc") + def update_frame_info(self, oldlooptoken, baseofs): + new_fi = self.frame_info + new_loop_tokens = [] + for ref in oldlooptoken.looptokens_redirected_to: + looptoken = ref() + if looptoken: + looptoken.frame_info.set_frame_depth(baseofs, + new_fi.jfi_frame_depth) + new_loop_tokens.append(ref) + oldlooptoken.frame_info.set_frame_depth(baseofs, new_fi.jfi_frame_depth) + new_loop_tokens.append(weakref.ref(oldlooptoken)) + self.looptokens_redirected_to = new_loop_tokens + def __del__(self): #debug_start("jit-mem-looptoken-free") #debug_print("freeing Loop #", self.number, 'with', diff --git a/rpython/jit/backend/test/test_model.py b/rpython/jit/backend/test/test_model.py --- a/rpython/jit/backend/test/test_model.py +++ b/rpython/jit/backend/test/test_model.py @@ -1,21 +1,32 @@ -from rpython.jit.metainterp.history import AbstractFailDescr -from rpython.jit.backend.model import AbstractCPU +from rpython.jit.backend.model import CompiledLoopToken +class FakeCPU(object): + class tracker: + total_compiled_loops = 0 + total_freed_loops = 0 + total_freed_bridges = 0 -def test_faildescr_numbering(): - cpu = AbstractCPU() - fail_descr1 = AbstractFailDescr() - fail_descr2 = AbstractFailDescr() + def free_loop_and_bridges(self, *args): + pass - n1 = cpu.get_fail_descr_number(fail_descr1) - n2 = cpu.get_fail_descr_number(fail_descr2) - assert n1 != n2 +class FrameInfo(object): + def __init__(self, depth): + self.jfi_frame_depth = depth - fail_descr = cpu.get_fail_descr_from_number(n1) - assert fail_descr is fail_descr1 - fail_descr = cpu.get_fail_descr_from_number(n2) - assert fail_descr is fail_descr2 + def set_frame_depth(self, baseofs, newdepth): + self.jfi_frame_depth = newdepth - # provides interning on its own - n1_1 = cpu.get_fail_descr_number(fail_descr1) - assert n1_1 == n1 +def test_redirect_loop_token(): + cpu = FakeCPU() + c = CompiledLoopToken(cpu, 0) + c2 = CompiledLoopToken(cpu, 0) + c.frame_info = FrameInfo(1) + c2.frame_info = FrameInfo(2) + c2.update_frame_info(c, 0) + assert c.frame_info.jfi_frame_depth == 2 + c3 = CompiledLoopToken(cpu, 0) + c3.frame_info = FrameInfo(3) + c3.update_frame_info(c2, 0) + assert c.frame_info.jfi_frame_depth == 3 + assert c2.frame_info.jfi_frame_depth == 3 + diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -892,16 +892,15 @@ old_nbargs = oldlooptoken.compiled_loop_token._debug_nbargs new_nbargs = newlooptoken.compiled_loop_token._debug_nbargs assert old_nbargs == new_nbargs - # we overwrite the instructions at the old _x86_direct_bootstrap_code - # to start with a JMP to the new _x86_direct_bootstrap_code. + # we overwrite the instructions at the old _x86_function_addr + # to start with a JMP to the new _x86_function_addr. # Ideally we should rather patch all existing CALLs, but well. oldadr = oldlooptoken._x86_function_addr target = newlooptoken._x86_function_addr # copy frame-info data - old_fi = oldlooptoken.compiled_loop_token.frame_info - new_fi = newlooptoken.compiled_loop_token.frame_info baseofs = self.cpu.get_baseofs_of_frame_field() - old_fi.set_frame_depth(baseofs, new_fi.jfi_frame_depth) + newlooptoken.compiled_loop_token.update_frame_info( + oldlooptoken.compiled_loop_token, baseofs) mc = codebuf.MachineCodeBlockWrapper() mc.JMP(imm(target)) if WORD == 4: # keep in sync with prepare_loop() From noreply at buildbot.pypy.org Sun Feb 3 17:12:32 2013 From: noreply at buildbot.pypy.org (fijal) Date: Sun, 3 Feb 2013 17:12:32 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: Fix the comments and some basics for 32bit support Message-ID: <20130203161232.0553D1C0183@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r60838:ce5c46a90939 Date: 2013-02-03 18:12 +0200 http://bitbucket.org/pypy/pypy/changeset/ce5c46a90939/ Log: Fix the comments and some basics for 32bit support diff --git a/rpython/jit/backend/x86/arch.py b/rpython/jit/backend/x86/arch.py --- a/rpython/jit/backend/x86/arch.py +++ b/rpython/jit/backend/x86/arch.py @@ -1,9 +1,6 @@ # Constants that depend on whether we are on 32-bit or 64-bit - -# The frame size gives the standard fixed part at the start of -# every assembler frame: the saved value of some registers, -# one word for the force_index, and some extra space used only -# during a malloc that needs to go via its slow path. +# the frame is absolutely standard. Stores callee-saved registers, +# return address and some scratch space for arguments. import sys if sys.maxint == (2**31 - 1): @@ -15,50 +12,31 @@ IS_X86_32 = False IS_X86_64 = True -# The stack for a JIT call is fixed, but it contains only scratch space -# used e.g. for storing arguments to further calls: # # +--------------------+ <== aligned to 16 bytes # | return address | # +--------------------+ +# | saved regs | +# +--------------------+ # | scratch | # | space | # +--------------------+ <== aligned to 16 bytes -if WORD == 4: - SCRATCH_SIZE = 7 # total size: 32 bytes -else: - SCRATCH_SIZE = 3 # total size: 32 bytes - # All the rest of the data is in a GC-managed variable-size "frame". # This frame object's address is always stored in the register EBP/RBP. # A frame is a jit.backend.llsupport.llmodel.JITFRAME = GcArray(Signed). -# The following locations are indices in this array. # The frame's fixed size gives the standard fixed part at the -# start of every frame: the saved value of some registers, -# one word for the force_index, and some extra space used only -# during a malloc that needs to go via its slow path. +# start of every frame: the saved value of some registers if WORD == 4: - # XXX rethink the fixed size - # ebp + ebx + esi + edi + 4 extra words + force_index = 9 words - XX - FRAME_FIXED_SIZE = 6 - SAVED_REGISTERS = 1 # range(1, 5) - MY_COPY_OF_REGS = 5 # range(5, 9) - XXX + # ebp + ebx + esi + edi + 6 extra words + return address = 9 words + FRAME_FIXED_SIZE = 11 + PASS_ON_MY_FRAME = 6 JITFRAME_FIXED_SIZE = 28 # 13 GPR + 15 XMM else: # rbp + rbx + r12 + r13 + r14 + r15 + 12 extra words + return address = 19 FRAME_FIXED_SIZE = 19 PASS_ON_MY_FRAME = 12 - JITFRAME_FIXED_SIZE = 28 # 13 GPR + 15 XMM - -# "My copy of regs" has room for almost all registers, apart from eax and edx -# which are used in the malloc itself. They are: -# ecx, ebx, esi, edi [32 and 64 bits] -# r8, r9, r10, r12, r13, r14, r15 [64 bits only] -# -# Note that with asmgcc, the locations corresponding to callee-save registers -# are never used. + JITFRAME_FIXED_SIZE = 6 + 8 # 6 GPR + 8 XMM + diff --git a/rpython/jit/backend/x86/regalloc.py b/rpython/jit/backend/x86/regalloc.py --- a/rpython/jit/backend/x86/regalloc.py +++ b/rpython/jit/backend/x86/regalloc.py @@ -17,7 +17,6 @@ from rpython.jit.codewriter import longlong from rpython.jit.codewriter.effectinfo import EffectInfo from rpython.jit.metainterp.resoperation import rop -from rpython.jit.backend.llsupport.jitframe import NULLGCMAP, GCMAP from rpython.jit.backend.llsupport.descr import ArrayDescr from rpython.jit.backend.llsupport.descr import CallDescr from rpython.jit.backend.llsupport.descr import unpack_arraydescr @@ -29,8 +28,7 @@ from rpython.jit.backend.x86.arch import IS_X86_32, IS_X86_64 from rpython.jit.backend.x86 import rx86 from rpython.rlib.rarithmetic import r_longlong, r_uint -from rpython.rlib.debug import (debug_print, debug_start, debug_stop, - have_debug_prints) +from rpython.rlib.debug import debug_print, debug_start, debug_stop class X86RegisterManager(RegisterManager): @@ -129,9 +127,6 @@ for _i, _reg in enumerate(gpr_reg_mgr_cls.all_regs): gpr_reg_mgr_cls.all_reg_indexes[_reg.value] = _i -if __name__ == '__main__': - print gpr_reg_mgr_cls.all_reg_indexes - class RegAlloc(object): def __init__(self, assembler, translate_support_code=False): From noreply at buildbot.pypy.org Sun Feb 3 17:38:30 2013 From: noreply at buildbot.pypy.org (stepahn) Date: Sun, 3 Feb 2013 17:38:30 +0100 (CET) Subject: [pypy-commit] lang-js default: moved reference code into separate file Message-ID: <20130203163830.E3F0E1C1065@cobra.cs.uni-duesseldorf.de> Author: Stephan Branch: Changeset: r342:50d27cfd406a Date: 2013-01-18 14:17 +0100 http://bitbucket.org/pypy/lang-js/changeset/50d27cfd406a/ Log: moved reference code into separate file diff --git a/js/lexical_environment.py b/js/lexical_environment.py --- a/js/lexical_environment.py +++ b/js/lexical_environment.py @@ -1,4 +1,5 @@ -from js.execution import JsReferenceError +from pypy.rlib import jit +from js.reference import Reference def get_identifier_reference(lex, identifier, strict=False): @@ -9,7 +10,9 @@ envRec = lex.environment_record exists = envRec.has_binding(identifier) if exists: - return Reference(base_env=envRec, referenced=identifier, strict=strict) + ref = Reference(base_env=envRec, referenced=identifier, strict=strict) + jit.promote(ref) + return ref else: outer = lex.outer_environment return get_identifier_reference(outer, identifier, strict) @@ -39,96 +42,3 @@ LexicalEnvironment.__init__(self, outer_environment) from js.environment_record import ObjectEnvironmentRecord self.environment_record = ObjectEnvironmentRecord(obj) - - -class Reference(object): - _immutable_fields_ = ['base_env', 'base_value', 'referenced', 'strict'] - - def __init__(self, base_value=None, base_env=None, referenced=None, strict=False): - self.base_env = base_env - self.base_value = base_value - self.referenced = referenced - self.strict = strict - - def get_base(self): - return self.base_value - - # XXX passing identifier is a obscure hack but cfbolz sayz so! - def get_referenced_name(self, identifier=None): - if identifier is not None: - return identifier - return self.referenced - - def is_strict_reference(self): - return self.strict is True - - def has_primitive_base(self): - b = self.base_value - from js.jsobj import W_Boolean, W_String, W_Number - if isinstance(b, W_Boolean) or isinstance(b, W_String) or isinstance(b, W_Number): - return True - return False - - def is_property_reference(self): - from js.jsobj import W_BasicObject - if isinstance(self.base_value, W_BasicObject) or self.has_primitive_base() is True: - return True - return False - - def is_unresolvable_reference(self): - if self.base_value is None and self.base_env is None: - return True - return False - - def get_value(self, identifier=None): - return get_value(self, identifier) - - def put_value(self, value, identifier=None): - put_value(self, value, identifier) - - -# 8.7.1 -def get_value(v, identifier=None): - if not isinstance(v, Reference): - return v - - if v.is_unresolvable_reference(): - referenced = v.get_referenced_name() - raise JsReferenceError(referenced) - - if v.is_property_reference(): - raise NotImplementedError('8.7.1 4.') - else: - base_env = v.base_env - from js.environment_record import EnvironmentRecord - assert isinstance(base_env, EnvironmentRecord) - name = v.get_referenced_name(identifier) - strict = v.is_strict_reference() - return base_env.get_binding_value(name, strict) - - -# 8.7.2 -def put_value(v, w, identifier): - if not isinstance(v, Reference): - raise JsReferenceError('unresolvable reference') - - if v.is_unresolvable_reference(): - if v.is_strict_reference(): - referenced = v.get_referenced_name() - raise JsReferenceError(referenced) - else: - name = v.get_referenced_name(identifier) - # TODO how to solve this ???? - from js.object_space import object_space - global_object = object_space.global_object - - global_object.put(name, w, throw=False) - elif v.is_property_reference(): - raise NotImplementedError('8.7.2 4.') - else: - base_env = v.base_env - from js.environment_record import EnvironmentRecord - assert isinstance(base_env, EnvironmentRecord) - name = v.get_referenced_name(identifier) - strict = v.is_strict_reference() - base_env.set_mutable_binding(name, w, strict) diff --git a/js/opcodes.py b/js/opcodes.py --- a/js/opcodes.py +++ b/js/opcodes.py @@ -893,7 +893,7 @@ self.index = index def eval(self, ctx): - from js.lexical_environment import Reference + from js.reference import Reference from js.execution import JsSyntaxError # 11.4.1 diff --git a/js/reference.py b/js/reference.py new file mode 100644 --- /dev/null +++ b/js/reference.py @@ -0,0 +1,95 @@ +from js.execution import JsReferenceError +#from pypy.rlib import jit + + +class Reference(object): + _immutable_fields_ = ['base_env', 'base_value', 'referenced', 'strict'] + + def __init__(self, base_value=None, base_env=None, referenced=None, strict=False): + self.base_env = base_env + self.base_value = base_value + self.referenced = referenced + self.strict = strict + + def get_base(self): + return self.base_value + + # XXX passing identifier is a obscure hack but cfbolz sayz so! + def get_referenced_name(self, identifier=None): + if identifier is not None: + return identifier + return self.referenced + + def is_strict_reference(self): + return self.strict is True + + def has_primitive_base(self): + b = self.base_value + from js.jsobj import W_Boolean, W_String, W_Number + if isinstance(b, W_Boolean) or isinstance(b, W_String) or isinstance(b, W_Number): + return True + return False + + def is_property_reference(self): + from js.jsobj import W_BasicObject + if isinstance(self.base_value, W_BasicObject) or self.has_primitive_base() is True: + return True + return False + + def is_unresolvable_reference(self): + if self.base_value is None and self.base_env is None: + return True + return False + + def get_value(self, identifier=None): + return get_value(self, identifier) + + def put_value(self, value, identifier=None): + put_value(self, value, identifier) + + +# 8.7.1 +def get_value(v, identifier=None): + if not isinstance(v, Reference): + return v + + if v.is_unresolvable_reference(): + referenced = v.get_referenced_name() + raise JsReferenceError(referenced) + + if v.is_property_reference(): + raise NotImplementedError('8.7.1 4.') + else: + base_env = v.base_env + from js.environment_record import EnvironmentRecord + assert isinstance(base_env, EnvironmentRecord) + name = v.get_referenced_name(identifier) + strict = v.is_strict_reference() + return base_env.get_binding_value(name, strict) + + +# 8.7.2 +def put_value(v, w, identifier): + if not isinstance(v, Reference): + raise JsReferenceError('unresolvable reference') + + if v.is_unresolvable_reference(): + if v.is_strict_reference(): + referenced = v.get_referenced_name() + raise JsReferenceError(referenced) + else: + name = v.get_referenced_name(identifier) + # TODO how to solve this ???? + from js.object_space import object_space + global_object = object_space.global_object + + global_object.put(name, w, throw=False) + elif v.is_property_reference(): + raise NotImplementedError('8.7.2 4.') + else: + base_env = v.base_env + from js.environment_record import EnvironmentRecord + assert isinstance(base_env, EnvironmentRecord) + name = v.get_referenced_name(identifier) + strict = v.is_strict_reference() + base_env.set_mutable_binding(name, w, strict) From noreply at buildbot.pypy.org Sun Feb 3 17:38:32 2013 From: noreply at buildbot.pypy.org (stepahn) Date: Sun, 3 Feb 2013 17:38:32 +0100 (CET) Subject: [pypy-commit] lang-js default: renamed js.execution to js.exception Message-ID: <20130203163832.4223C1C1065@cobra.cs.uni-duesseldorf.de> Author: Stephan Branch: Changeset: r343:ede3ac137de0 Date: 2013-01-18 14:28 +0100 http://bitbucket.org/pypy/lang-js/changeset/ede3ac137de0/ Log: renamed js.execution to js.exception diff --git a/js/builtins/array.py b/js/builtins/array.py --- a/js/builtins/array.py +++ b/js/builtins/array.py @@ -218,7 +218,7 @@ if not isundefined(comparefn): if not comparefn.is_callable(): - from js.execution import JsTypeError + from js.exception import JsTypeError raise JsTypeError(u'') from js.jsobj import W_BasicFunction diff --git a/js/builtins/boolean.py b/js/builtins/boolean.py --- a/js/builtins/boolean.py +++ b/js/builtins/boolean.py @@ -1,5 +1,5 @@ from js.jsobj import W_Boolean, W_BooleanObject -from js.execution import JsTypeError +from js.exception import JsTypeError from js.object_space import w_return, _w diff --git a/js/builtins/function.py b/js/builtins/function.py --- a/js/builtins/function.py +++ b/js/builtins/function.py @@ -1,4 +1,4 @@ -from js.execution import JsTypeError +from js.exception import JsTypeError from js.builtins import get_arg from js.completion import NormalCompletion from js.object_space import w_return, _w diff --git a/js/builtins/js_global.py b/js/builtins/js_global.py --- a/js/builtins/js_global.py +++ b/js/builtins/js_global.py @@ -344,7 +344,7 @@ from pypy.rlib.parsing.parsing import ParseError from pypy.rlib.parsing.deterministic import LexerError from js.astbuilder import FakeParseError - from js.execution import JsSyntaxError + from js.exception import JsSyntaxError args = ctx.argv() x = get_arg(args, 0) diff --git a/js/builtins/number.py b/js/builtins/number.py --- a/js/builtins/number.py +++ b/js/builtins/number.py @@ -1,5 +1,5 @@ from pypy.rlib.rfloat import NAN, INFINITY -from js.execution import JsRangeError, JsTypeError +from js.exception import JsRangeError, JsTypeError from js.jsobj import W_Number, W_NumericObject from js.object_space import w_return, _w diff --git a/js/builtins/string.py b/js/builtins/string.py --- a/js/builtins/string.py +++ b/js/builtins/string.py @@ -1,6 +1,6 @@ from js.jsobj import W_String, W_StringObject from pypy.rlib.rfloat import NAN -from js.execution import JsTypeError +from js.exception import JsTypeError from js.builtins import get_arg from js.object_space import w_return, _w from pypy.rlib.rstring import UnicodeBuilder diff --git a/js/environment_record.py b/js/environment_record.py --- a/js/environment_record.py +++ b/js/environment_record.py @@ -101,7 +101,7 @@ assert identifier is not None and isinstance(identifier, unicode) assert self.has_binding(identifier) if not self._is_mutable_binding(identifier): - from js.execution import JsTypeError + from js.exception import JsTypeError raise JsTypeError(u'immutable binding') self._set_binding(identifier, value) @@ -111,7 +111,7 @@ assert identifier is not None and isinstance(identifier, unicode) if not self.has_binding(identifier): if strict: - from js.execution import JsReferenceError + from js.exception import JsReferenceError raise JsReferenceError(identifier) else: return newundefined() @@ -191,7 +191,7 @@ if s is False: return newundefined() else: - from execution import JsReferenceError + from js.exception import JsReferenceError raise JsReferenceError(self.__class__) return bindings.get(n) diff --git a/js/execution.py b/js/exception.py rename from js/execution.py rename to js/exception.py diff --git a/js/jscode.py b/js/jscode.py --- a/js/jscode.py +++ b/js/jscode.py @@ -3,7 +3,7 @@ from pypy.rlib.jit import JitDriver from pypy.rlib import jit -from js.execution import JsThrowException +from js.exception import JsThrowException from js.opcodes import opcodes, LABEL, BaseJump from js.jsobj import W_String from js.astbuilder import empty_symbols diff --git a/js/jsobj.py b/js/jsobj.py --- a/js/jsobj.py +++ b/js/jsobj.py @@ -1,7 +1,7 @@ # encoding: utf-8 from pypy.rlib.rarithmetic import intmask from pypy.rlib.rfloat import isnan, isinf, NAN, formatd, INFINITY -from js.execution import JsTypeError, JsRangeError +from js.exception import JsTypeError, JsRangeError from pypy.rlib.objectmodel import enforceargs from pypy.rlib import jit diff --git a/js/opcodes.py b/js/opcodes.py --- a/js/opcodes.py +++ b/js/opcodes.py @@ -1,5 +1,5 @@ from js.object_space import _w -from js.execution import JsTypeError +from js.exception import JsTypeError from js.baseop import plus, sub, compare, AbstractEC, StrictEC,\ compare_e, increment, decrement, mult, division, uminus, mod from pypy.rlib.rarithmetic import intmask @@ -686,7 +686,7 @@ def eval(self, ctx): val = ctx.stack_pop() - from js.execution import JsThrowException + from js.exception import JsThrowException raise JsThrowException(val) @@ -715,7 +715,7 @@ def eval(self, ctx): from js.completion import is_return_completion, is_completion, NormalCompletion - from js.execution import JsException + from js.exception import JsException tryexec = self.tryexec catchexec = self.catchexec @@ -894,7 +894,7 @@ def eval(self, ctx): from js.reference import Reference - from js.execution import JsSyntaxError + from js.exception import JsSyntaxError # 11.4.1 ref = ctx.get_ref(self.name, self.index) diff --git a/js/operations.py b/js/operations.py --- a/js/operations.py +++ b/js/operations.py @@ -4,7 +4,7 @@ Implements the javascript operations nodes for the interpretation tree """ -from js.execution import JsTypeError, JsException +from js.exception import JsTypeError, JsException from pypy.rlib.unroll import unrolling_iterable from pypy.rlib.objectmodel import enforceargs diff --git a/js/reference.py b/js/reference.py --- a/js/reference.py +++ b/js/reference.py @@ -1,4 +1,4 @@ -from js.execution import JsReferenceError +from js.exception import JsReferenceError #from pypy.rlib import jit diff --git a/js/runistr.py b/js/runistr.py --- a/js/runistr.py +++ b/js/runistr.py @@ -56,7 +56,7 @@ pos += 1 if pos >= size: message = u"\\ at end of string" - from js.execution import JsSyntaxError + from js.exception import JsSyntaxError raise JsSyntaxError(message) ch = s[pos] diff --git a/py-js.py b/py-js.py --- a/py-js.py +++ b/py-js.py @@ -1,7 +1,7 @@ #!/usr/bin/env python import os -from js.execution import JsException +from js.exception import JsException from pypy.rlib.objectmodel import enforceargs from pypy.rlib.parsing.parsing import ParseError from pypy.rlib.parsing.deterministic import LexerError diff --git a/test/ecma/conftest.py b/test/ecma/conftest.py --- a/test/ecma/conftest.py +++ b/test/ecma/conftest.py @@ -4,7 +4,7 @@ from js.interpreter import Interpreter, load_file from _pytest.runner import Failed from js.object_space import _w -from js.execution import JsException +from js.exception import JsException from pypy.rlib.parsing.parsing import ParseError EXCLUSIONLIST = ['shell.js', 'browser.js'] diff --git a/test/test_interp.py b/test/test_interp.py --- a/test/test_interp.py +++ b/test/test_interp.py @@ -236,7 +236,7 @@ def test_throw(capsys): - from js.execution import JsThrowException + from js.exception import JsThrowException asserte("throw(3);", JsThrowException) @@ -413,7 +413,7 @@ def test_eval_syntax_error(): - from js.execution import JsSyntaxError + from js.exception import JsSyntaxError asserte("eval('var do =true;');", JsSyntaxError) From noreply at buildbot.pypy.org Sun Feb 3 17:38:33 2013 From: noreply at buildbot.pypy.org (stepahn) Date: Sun, 3 Feb 2013 17:38:33 +0100 (CET) Subject: [pypy-commit] lang-js default: removed resizable stack code Message-ID: <20130203163833.688CB1C1065@cobra.cs.uni-duesseldorf.de> Author: Stephan Branch: Changeset: r344:2990200ab3f0 Date: 2013-01-19 14:28 +0100 http://bitbucket.org/pypy/lang-js/changeset/2990200ab3f0/ Log: removed resizable stack code diff --git a/js/execution_context.py b/js/execution_context.py --- a/js/execution_context.py +++ b/js/execution_context.py @@ -11,7 +11,7 @@ self._variable_environment_ = None self._this_binding_ = None self._refs_ = [None] * refs_size - self._init_stack_(size=stack_size, resize=False) + self._init_stack_(stack_size) def stack_append(self, value): self._stack_append(value) diff --git a/js/utils.py b/js/utils.py --- a/js/utils.py +++ b/js/utils.py @@ -9,10 +9,9 @@ def __init__(self): self._init_stack_() - def _init_stack_(self, size=1, resize=True): + def _init_stack_(self, size=1): self._stack_ = [None] * size self._stack_pointer_ = 0 - self._stack_resize_ = resize def _stack_pointer(self): return jit.promote(self._stack_pointer_) @@ -35,11 +34,7 @@ i = self._stack_pointer() len_stack = len(self._stack_) - assert i >= 0 - if len_stack <= i and self._stack_resize_ is True: - self._stack_ += [None] - else: - assert len_stack > i + assert i >= 0 and len_stack > i self._stack_[i] = element self._stack_pointer_ = i + 1 diff --git a/test/test_stack.py b/test/test_stack.py --- a/test/test_stack.py +++ b/test/test_stack.py @@ -1,10 +1,10 @@ import py - from js.utils import StackMixin + class Stack(StackMixin): - def __init__(self, size, resize = True): - self._init_stack_(size, resize) + def __init__(self, size): + self._init_stack_(size) def pop(self): return self._stack_pop() @@ -18,6 +18,7 @@ def pop_n(self, n): return self._stack_pop_n(n) + class TestStack(object): def test_stack_push(self): s = Stack(99) @@ -45,7 +46,7 @@ s.append(3) assert s.pop() == 3 assert s._stack_pointer_ == 2 - assert s._stack_[2] == None + assert s._stack_[2] is None s = Stack(99) s.append(1) @@ -74,18 +75,11 @@ x = s.pop_n(2) assert x == [2, 3] assert s._stack_pointer_ == 1 - assert s._stack_[1] == None - assert s._stack_[2] == None + assert s._stack_[1] is None + assert s._stack_[2] is None def test_stack_no_resize(self): - s = Stack(2, False) + s = Stack(2) s.append(1) s.append(1) - py.test.raises(AssertionError, s.append,1) - - def test_stack_resize(self): - s = Stack(0) - s.append(1) - s.append(2) - s.append(3) - assert len(s._stack_) == 3 + py.test.raises(AssertionError, s.append, 1) From noreply at buildbot.pypy.org Sun Feb 3 17:38:34 2013 From: noreply at buildbot.pypy.org (stepahn) Date: Sun, 3 Feb 2013 17:38:34 +0100 (CET) Subject: [pypy-commit] lang-js default: assert date Message-ID: <20130203163834.8DC561C1065@cobra.cs.uni-duesseldorf.de> Author: Stephan Branch: Changeset: r345:1ea736642e6a Date: 2013-01-30 16:27 +0100 http://bitbucket.org/pypy/lang-js/changeset/1ea736642e6a/ Log: assert date diff --git a/js/builtins/date.py b/js/builtins/date.py --- a/js/builtins/date.py +++ b/js/builtins/date.py @@ -270,9 +270,19 @@ return offset +def _assert_date(obj): + if obj.klass() != 'date': + from js.exception import JsTypeError + msg = '%s is not an instnace of Date' + raise JsTypeError(unicode(msg)) + + # 15.9.5.27 @w_return def set_time(this, args): + _assert_date(this) + from js.jsobj import W_DateObject + assert isinstance(this, W_DateObject) arg0 = get_arg(args, 0) this._primitive_value_ = arg0 return arg0 From noreply at buildbot.pypy.org Sun Feb 3 17:38:35 2013 From: noreply at buildbot.pypy.org (stepahn) Date: Sun, 3 Feb 2013 17:38:35 +0100 (CET) Subject: [pypy-commit] lang-js default: removed dead code Message-ID: <20130203163835.9E9601C1065@cobra.cs.uni-duesseldorf.de> Author: Stephan Branch: Changeset: r346:f558b5dab11a Date: 2013-02-01 13:19 +0100 http://bitbucket.org/pypy/lang-js/changeset/f558b5dab11a/ Log: removed dead code diff --git a/js/jscode.py b/js/jscode.py --- a/js/jscode.py +++ b/js/jscode.py @@ -167,33 +167,7 @@ if self.has_labels: self.remove_labels() - def unpop_or_undefined(self): - if not self.unpop(): - self.emit('LOAD_UNDEFINED') - #elif not self.returns(): - #self.emit('LOAD_UNDEFINED') - - def to_function_opcodes(self): self.unlabel() - #self.unpop() - #self.unpop#_or_undefined() - #self.emit('LOAD_UNDEFINED') - return self.opcodes - - def to_eval_opcodes(self): - self.unlabel() - #self.unpop#_or_undefined() - return self.opcodes - - def to_global_opcodes(self): - self.unlabel() - #self.unpop#_or_undefined() - return self.opcodes - - def to_executable_opcodes(self): - self.unlabel() - #self.unpop#_or_undefined() - return self.opcodes def remove_labels(self): """ Basic optimization to remove all labels and change diff --git a/js/operations.py b/js/operations.py --- a/js/operations.py +++ b/js/operations.py @@ -907,7 +907,6 @@ class EmptyExpression(Expression): def emit(self, bytecode): - #bytecode.unpop_or_undefined() bytecode.emit('LOAD_UNDEFINED') diff --git a/js/utils.py b/js/utils.py --- a/js/utils.py +++ b/js/utils.py @@ -41,11 +41,3 @@ def _set_stack_pointer(self, p): self._stack_pointer_ = p - - #@jit.unroll_safe - def _stack_pop_n(self, n): - l = [None] * n - for i in range(n - 1, -1, -1): - l[i] = self._stack_pop() - #debug.make_sure_not_resized(l) - return l diff --git a/test/test_stack.py b/test/test_stack.py --- a/test/test_stack.py +++ b/test/test_stack.py @@ -67,17 +67,6 @@ s.append(3) assert s.top() == 3 - def test_stack_popn(self): - s = Stack(99) - s.append(1) - s.append(2) - s.append(3) - x = s.pop_n(2) - assert x == [2, 3] - assert s._stack_pointer_ == 1 - assert s._stack_[1] is None - assert s._stack_[2] is None - def test_stack_no_resize(self): s = Stack(2) s.append(1) From noreply at buildbot.pypy.org Sun Feb 3 17:38:36 2013 From: noreply at buildbot.pypy.org (stepahn) Date: Sun, 3 Feb 2013 17:38:36 +0100 (CET) Subject: [pypy-commit] lang-js default: re-enabled and fixed virtualizables Message-ID: <20130203163836.C323F1C1065@cobra.cs.uni-duesseldorf.de> Author: Stephan Branch: Changeset: r347:4d28120584cd Date: 2013-02-01 13:20 +0100 http://bitbucket.org/pypy/lang-js/changeset/4d28120584cd/ Log: re-enabled and fixed virtualizables diff --git a/js/completion.py b/js/completion.py --- a/js/completion.py +++ b/js/completion.py @@ -2,6 +2,8 @@ # 8.9 class Completion(object): + _immutable_fields_ = ['value', 'target'] + def __init__(self, value=None, target=None): self.value = value self.target = target diff --git a/js/environment_record.py b/js/environment_record.py --- a/js/environment_record.py +++ b/js/environment_record.py @@ -83,7 +83,11 @@ if self._binding_map_.not_found(idx): return - del(self._binding_slots_[idx]) + assert idx >= 0 + i = (idx + 1) + assert i >= 0 + + self._binding_slots_ = self._binding_slots_[:idx] + self._binding_slots_[i:] #len(self._binding_slots_)] self._binding_map_ = self._binding_map_.delete(name) # 10.2.1.1.2 @@ -126,7 +130,7 @@ return False if self._is_deletable_binding(identifier) is False: return False - self._deletable_bindings_map__ = self._deletable_bindings_map_.delete(identifier) + self._deletable_bindings_map_ = self._deletable_bindings_map_.delete(identifier) self._mutable_bindings_map_ = self._mutable_bindings_map_.delete(identifier) self._del_binding(identifier) return False diff --git a/js/execution_context.py b/js/execution_context.py --- a/js/execution_context.py +++ b/js/execution_context.py @@ -1,12 +1,15 @@ from js.utils import StackMixin from js.object_space import newundefined +from pypy.rlib import jit class ExecutionContext(StackMixin): - _immutable_fields_ = ['_stack_', '_stack_resize_', '_this_binding_', '_lexical_environment_', '_variable_environment_'] - _refs_resizable_ = True + _immutable_fields_ = ['_stack_', '_this_binding_', '_lexical_environment_', '_variable_environment_', '_refs_', '_code_', '_formal_parameters_', '_argument_values_', '_w_func_'] # TODO why are _formal_parameters_, _w_func_ etc. required here? + _virtualizable2_ = ['_stack_[*]', '_stack_pointer_', '_refs_[*]'] + _settled_ = True def __init__(self, stack_size=1, refs_size=1): + self = jit.hint(self, access_directly=True, fresh_virtualizable=True) self._lexical_environment_ = None self._variable_environment_ = None self._this_binding_ = None @@ -22,6 +25,7 @@ def stack_top(self): return self._stack_top() + @jit.unroll_safe def stack_pop_n(self, n): if n < 1: return [] @@ -51,12 +55,13 @@ self._lexical_environment_ = lex_env # 10.5 + @jit.unroll_safe def declaration_binding_initialization(self): from js.object_space import newundefined env = self._variable_environment_.environment_record strict = self._strict_ - code = self._code_ + code = jit.promote(self._code_) if code.is_eval_code(): configurable_bindings = True @@ -65,7 +70,7 @@ # 4. if code.is_function_code(): - names = self._formal_parameters_ + names = code.params() #_formal_parameters_ n = 0 args = self._argument_values_ @@ -99,7 +104,7 @@ # TODO get calling W_Function func = self._w_func_ arguments = self._argument_values_ - names = self._formal_parameters_ + names = code.params() #_formal_parameters_ args_obj = W_Arguments(func, names, arguments, env, strict) if strict is True: @@ -118,41 +123,60 @@ env.set_mutable_binding(dn, newundefined(), False) def _get_refs(self, index): - assert index <= len(self._refs_) + assert index < len(self._refs_) + assert index >= 0 return self._refs_[index] def _set_refs(self, index, value): - assert index <= len(self._refs_) + assert index < len(self._refs_) + assert index >= 0 self._refs_[index] = value def get_ref(self, symbol, index=-1): ## TODO pre-bind symbols, work with idndex, does not work, see test_foo19 - if index == -1: + if index < 0: lex_env = self.lexical_environment() ref = lex_env.get_identifier_reference(symbol) return ref - if self._refs_resizable_ is True and index >= len(self._refs_): - self._refs_ += ([None] * (1 + index - len(self._refs_))) + ref = self._get_refs(index) - if self._get_refs(index) is None: + if ref is None: lex_env = self.lexical_environment() ref = lex_env.get_identifier_reference(symbol) if ref.is_unresolvable_reference() is True: return ref self._set_refs(index, ref) - return self._get_refs(index) + return ref def forget_ref(self, symbol, index): self._set_refs(index, None) -class GlobalExecutionContext(ExecutionContext): +class _DynamicExecutionContext(ExecutionContext): + def __init__(self, stack_size): + ExecutionContext.__init__(self, stack_size) + self._dyn_refs_ = [None] + + def _get_refs(self, index): + self._resize_refs(index) + return self._dyn_refs_[index] + + def _set_refs(self, index, value): + self._resize_refs(index) + self._dyn_refs_[index] = value + + def _resize_refs(self, index): + if index >= len(self._dyn_refs_): + self._dyn_refs_ += ([None] * (1 + index - len(self._dyn_refs_))) + + +class GlobalExecutionContext(_DynamicExecutionContext): def __init__(self, code, global_object, strict=False): stack_size = code.estimated_stack_size() - ExecutionContext.__init__(self, stack_size) + _DynamicExecutionContext.__init__(self, stack_size) self._code_ = code self._strict_ = strict @@ -166,11 +190,11 @@ self.declaration_binding_initialization() -class EvalExecutionContext(ExecutionContext): +class EvalExecutionContext(_DynamicExecutionContext): def __init__(self, code, calling_context=None): stack_size = code.estimated_stack_size() - ExecutionContext.__init__(self, stack_size) + _DynamicExecutionContext.__init__(self, stack_size) self._code_ = code self._strict_ = code.strict @@ -191,7 +215,6 @@ class FunctionExecutionContext(ExecutionContext): _immutable_fields_ = ['_scope_', '_calling_context_'] - _refs_resizable_ = False def __init__(self, code, formal_parameters=[], argv=[], this=newundefined(), strict=False, scope=None, w_func=None): from js.jsobj import W_BasicObject @@ -203,7 +226,6 @@ ExecutionContext.__init__(self, stack_size, env_size) self._code_ = code - self._formal_parameters_ = formal_parameters self._argument_values_ = argv self._strict_ = strict self._scope_ = scope @@ -234,9 +256,9 @@ return self._argument_values_ -class SubExecutionContext(ExecutionContext): +class SubExecutionContext(_DynamicExecutionContext): def __init__(self, parent): - ExecutionContext.__init__(self) + _DynamicExecutionContext.__init__(self, 0) self._parent_context_ = parent def stack_append(self, value): @@ -261,6 +283,7 @@ self._code_ = code self._strict_ = code.strict self._expr_obj_ = expr_obj + self._dynamic_refs = [] from js.lexical_environment import ObjectEnvironment parent_environment = parent_context.lexical_environment() @@ -273,16 +296,16 @@ self.declaration_binding_initialization() -class CatchExecutionContext(ExecutionContext): +class CatchExecutionContext(_DynamicExecutionContext): def __init__(self, code, catchparam, exception_value, parent_context): self._code_ = code self._strict_ = code.strict self._parent_context_ = parent_context stack_size = code.estimated_stack_size() - env_size = code.env_size() + 1 # neet do add one for the arguments object + #env_size = code.env_size() + 1 # neet do add one for the arguments object - ExecutionContext.__init__(self, stack_size, env_size) + _DynamicExecutionContext.__init__(self, stack_size) parent_env = parent_context.lexical_environment() diff --git a/js/functions.py b/js/functions.py --- a/js/functions.py +++ b/js/functions.py @@ -2,6 +2,7 @@ class JsBaseFunction(object): + _settled_ = True eval_code = False function_code = False configurable_bindings = False @@ -63,6 +64,7 @@ args = ctx.argv() this = ctx.this_binding() + assert isinstance(self, JsNativeFunction) res = self._function_(this, args) w_res = _w(res) compl = ReturnCompletion(value=w_res) @@ -98,6 +100,7 @@ from js.jscode import JsCode assert isinstance(js_code, JsCode) self._js_code_ = js_code + self._js_code_.compile() self._stack_size_ = js_code.estimated_stack_size() self._symbol_size_ = js_code.symbol_size() @@ -122,8 +125,10 @@ return code.variables() def functions(self): + # XXX tuning code = self.get_js_code() - return code.functions() + functions = code.functions() + return functions def params(self): code = self.get_js_code() diff --git a/js/jscode.py b/js/jscode.py --- a/js/jscode.py +++ b/js/jscode.py @@ -16,8 +16,7 @@ else: return '%d: %s' % (pc, 'end of opcodes') -#jitdriver = JitDriver(greens=['pc', 'self'], reds=['ctx'], get_printable_location = get_printable_location, virtualizables=['ctx']) -jitdriver = JitDriver(greens=['pc', 'debug', 'self'], reds=['result', 'ctx'], get_printable_location=get_printable_location) +jitdriver = JitDriver(greens=['pc', 'debug', 'self'], reds=['result', 'ctx'], get_printable_location=get_printable_location, virtualizables=['ctx']) def ast_to_bytecode(ast, symbol_map): @@ -32,7 +31,7 @@ class JsCode(object): - _immutable_fields_ = ['_oppcodes_', '_symbols_'] + _immutable_fields_ = ['compiled_opcodes[*]', '_symbols', 'parameters[*]'] """ That object stands for code of a single javascript function """ @@ -46,6 +45,7 @@ self.updatelooplabel = [] self._estimated_stack_size = -1 self._symbols = symbol_map + self.parameters = symbol_map.parameters[:] def variables(self): return self._symbols.variables @@ -62,8 +62,9 @@ def symbol_for_index(self, index): return self._symbols.get_symbol(index) + @jit.unroll_safe def params(self): - return self._symbols.parameters + return [p for p in self.parameters] #@jit.elidable def estimated_stack_size(self): @@ -71,7 +72,7 @@ if self._estimated_stack_size == -1: max_size = 0 moving_size = 0 - for opcode in self.opcodes: + for opcode in self.compiled_opcodes: moving_size += opcode.stack_change() max_size = max(moving_size, max_size) assert max_size >= 0 @@ -167,7 +168,9 @@ if self.has_labels: self.remove_labels() + def compile(self): self.unlabel() + self.compiled_opcodes = [o for o in self.opcodes] def remove_labels(self): """ Basic optimization to remove all labels and change @@ -192,10 +195,11 @@ @jit.elidable def _get_opcode(self, pc): assert pc >= 0 - return self.opcodes[pc] + return self.compiled_opcodes[pc] + @jit.elidable def _opcode_count(self): - return len(self.opcodes) + return len(self.compiled_opcodes) def run(self, ctx): from js.object_space import object_space @@ -203,8 +207,6 @@ from js.completion import NormalCompletion, is_completion, is_return_completion, is_empty_completion from js.opcodes import BaseJump - self.unlabel() - if self._opcode_count() == 0: return NormalCompletion() diff --git a/js/jsobj.py b/js/jsobj.py --- a/js/jsobj.py +++ b/js/jsobj.py @@ -179,7 +179,7 @@ _type_ = 'object' _class_ = 'Object' _extensible_ = True - _immutable_fields_ = ['_type_', '_class_', '_extensible_'] + _immutable_fields_ = ['_type_', '_class_'] # TODO why need _primitive_value_ here??? def __init__(self): from js.object_space import newnull @@ -532,6 +532,8 @@ class W__PrimitiveObject(W_BasicObject): + _immutable_fields_ = ['_primitive_value_'] + def __init__(self, primitive_value): W_BasicObject.__init__(self) self.set_primitive_value(primitive_value) @@ -832,7 +834,7 @@ class W__Function(W_BasicFunction): - _immutable_fields_ = ['_type_', '_class_', '_extensible_', '_scope_', '_params_', '_strict_', '_function_'] + _immutable_fields_ = ['_type_', '_class_', '_extensible_', '_scope_', '_params_[*]', '_strict_', '_function_'] def __init__(self, function_body, formal_parameter_list=[], scope=None, strict=False): W_BasicFunction.__init__(self) @@ -874,12 +876,11 @@ from js.completion import Completion code = self.code() - argn = self.formal_parameters() + jit.promote(code) strict = self._strict_ scope = self.scope() ctx = FunctionExecutionContext(code, - formal_parameters=argn, argv=args, this=this, strict=strict, @@ -910,6 +911,7 @@ class W_Arguments(W__Object): _class_ = 'Arguments' + @jit.unroll_safe def __init__(self, func, names, args, env, strict=False): from js.object_space import _w W__Object.__init__(self) @@ -919,22 +921,22 @@ from js.object_space import object_space _map = object_space.new_obj() - mapped_names = [] + mapped_names = _new_map() indx = _len - 1 while indx >= 0: val = args[indx] put_property(self, unicode(str(indx)), val, writable=True, enumerable=True, configurable=True) if indx < len(names): name = names[indx] - if strict is False and name not in mapped_names: - mapped_names.append(name) + if strict is False and not mapped_names.contains(name): + mapped_names = mapped_names.add(name) g = make_arg_getter(name, env) p = make_arg_setter(name, env) desc = PropertyDescriptor(setter=p, getter=g, configurable=True) _map.define_own_property(unicode(str(indx)), desc, False) indx = indx - 1 - if len(mapped_names) > 0: + if not mapped_names.empty(): self._paramenter_map_ = _map if strict is False: diff --git a/js/lexical_environment.py b/js/lexical_environment.py --- a/js/lexical_environment.py +++ b/js/lexical_environment.py @@ -11,7 +11,6 @@ exists = envRec.has_binding(identifier) if exists: ref = Reference(base_env=envRec, referenced=identifier, strict=strict) - jit.promote(ref) return ref else: outer = lex.outer_environment diff --git a/js/object_map.py b/js/object_map.py --- a/js/object_map.py +++ b/js/object_map.py @@ -3,7 +3,7 @@ class Map(object): NOT_FOUND = -1 - _immutable_fields_ = ['index', 'back', 'name', 'forward_pointers'] + _immutable_fields_ = ['index', 'back', 'name'] def __init__(self): self.index = self.NOT_FOUND @@ -40,6 +40,12 @@ def _key(self): return (self.name) + def empty(self): + return True + + def len(self): + return self.index + @jit.elidable def add(self, name): assert self.lookup(name) == self.NOT_FOUND @@ -84,6 +90,9 @@ n = self.back.delete(name) return n.add(self.name) + def empty(self): + return False + ROOT_MAP = MapRoot() diff --git a/js/opcodes.py b/js/opcodes.py --- a/js/opcodes.py +++ b/js/opcodes.py @@ -5,11 +5,12 @@ from pypy.rlib.rarithmetic import intmask from js.jsobj import put_property +from pypy.rlib import jit class Opcode(object): _settled_ = True - _immutable_fields_ = ['_stack_change'] + _immutable_fields_ = ['_stack_change', 'funcobj'] _stack_change = 1 def __init__(self): @@ -171,6 +172,7 @@ def __init__(self, counter): self.counter = counter + @jit.unroll_safe def eval(self, ctx): from js.object_space import object_space array = object_space.new_array() @@ -206,7 +208,7 @@ class LOAD_FUNCTION(Opcode): - #_immutable_fields_ = ['funcobj'] + _immutable_fields_ = ['funcobj'] def __init__(self, funcobj): self.funcobj = funcobj @@ -233,11 +235,13 @@ def __init__(self, counter): self.counter = counter + @jit.unroll_safe def eval(self, ctx): from js.object_space import object_space w_obj = object_space.new_obj() for _ in range(self.counter): - name = ctx.stack_pop().to_string() + top = ctx.stack_pop() + name = top.to_string() w_elem = ctx.stack_pop() put_property(w_obj, name, w_elem, writable=True, configurable=True, enumerable=True) ctx.stack_append(w_obj) @@ -307,7 +311,7 @@ def eval(self, ctx): from js.object_space import newstring - ref = ctx.get_ref(self.name) + ref = ctx.get_ref(self.name, self.index) if ref.is_unresolvable_reference(): var_type = u'undefined' else: @@ -800,14 +804,9 @@ class LOAD_ITERATOR(Opcode): _stack_change = 0 - def eval(self, ctx): - exper_value = ctx.stack_pop() - obj = exper_value.ToObject() + # separate function because jit should trace eval but not iterator creation. + def _make_iterator(self, obj): props = [] - - from js.jsobj import W_BasicObject - assert isinstance(obj, W_BasicObject) - properties = obj.named_properties() TimSort(properties).sort() @@ -817,8 +816,19 @@ props.append(_w(key)) props.reverse() + from js.jsobj import W_Iterator iterator = W_Iterator(props) + return iterator + + def eval(self, ctx): + exper_value = ctx.stack_pop() + obj = exper_value.ToObject() + + from js.jsobj import W_BasicObject + assert isinstance(obj, W_BasicObject) + + iterator = self._make_iterator(obj) ctx.stack_append(iterator) diff --git a/test/test_environment_record.py b/test/test_environment_record.py --- a/test/test_environment_record.py +++ b/test/test_environment_record.py @@ -4,12 +4,12 @@ class TestDeclarativeEnvironmentRecord(object): def test_create_mutable_binding(self): - env_rec = DeclarativeEnvironmentRecord() + env_rec = DeclarativeEnvironmentRecord(size=1) env_rec.create_mutuable_binding(u'foo', True) assert env_rec.has_binding(u'foo') is True def test_set_and_get_mutable_binding(self): - env_rec = DeclarativeEnvironmentRecord() + env_rec = DeclarativeEnvironmentRecord(size=1) env_rec.create_mutuable_binding(u'foo', True) env_rec.set_mutable_binding(u'foo', 42, False) assert env_rec.get_binding_value(u'foo') == 42 diff --git a/test/test_jsfunction.py b/test/test_jsfunction.py --- a/test/test_jsfunction.py +++ b/test/test_jsfunction.py @@ -50,11 +50,12 @@ var_idx = symbol_map.add_variable(u'a') code = JsCode(symbol_map) + code.parameters = [u'a'] code.emit('LOAD_VARIABLE', var_idx, u'a') code.emit('RETURN') f = JsFunction(u'foo', code) - ctx = FunctionExecutionContext(f, argv=[_w(42)], formal_parameters=[u'a']) + ctx = FunctionExecutionContext(f, argv=[_w(42)]) res = f.run(ctx) assert res.value == _w(42) From noreply at buildbot.pypy.org Sun Feb 3 17:38:38 2013 From: noreply at buildbot.pypy.org (stepahn) Date: Sun, 3 Feb 2013 17:38:38 +0100 (CET) Subject: [pypy-commit] lang-js default: jit tuning Message-ID: <20130203163838.045B51C1065@cobra.cs.uni-duesseldorf.de> Author: Stephan Branch: Changeset: r348:83da05a4775d Date: 2013-02-03 17:37 +0100 http://bitbucket.org/pypy/lang-js/changeset/83da05a4775d/ Log: jit tuning diff --git a/js/jscode.py b/js/jscode.py --- a/js/jscode.py +++ b/js/jscode.py @@ -1,6 +1,5 @@ #from pypy.rlib.jit import hint #from pypy.rlib.objectmodel import we_are_translated -from pypy.rlib.jit import JitDriver from pypy.rlib import jit from js.exception import JsThrowException @@ -16,7 +15,7 @@ else: return '%d: %s' % (pc, 'end of opcodes') -jitdriver = JitDriver(greens=['pc', 'debug', 'self'], reds=['result', 'ctx'], get_printable_location=get_printable_location, virtualizables=['ctx']) +jitdriver = jit.JitDriver(greens=['pc', 'debug', 'self'], reds=['result', 'ctx'], get_printable_location=get_printable_location, virtualizables=['ctx']) def ast_to_bytecode(ast, symbol_map): @@ -66,9 +65,8 @@ def params(self): return [p for p in self.parameters] - #@jit.elidable + @jit.elidable def estimated_stack_size(self): - # TODO: compute only once if self._estimated_stack_size == -1: max_size = 0 moving_size = 0 @@ -78,7 +76,7 @@ assert max_size >= 0 self._estimated_stack_size = max_size - return self._estimated_stack_size + return jit.promote(self._estimated_stack_size) def symbol_size(self): return self._symbols.len() @@ -171,6 +169,7 @@ def compile(self): self.unlabel() self.compiled_opcodes = [o for o in self.opcodes] + self.estimated_stack_size() def remove_labels(self): """ Basic optimization to remove all labels and change From noreply at buildbot.pypy.org Sun Feb 3 17:38:39 2013 From: noreply at buildbot.pypy.org (stepahn) Date: Sun, 3 Feb 2013 17:38:39 +0100 (CET) Subject: [pypy-commit] lang-js default: added more jit viewer test cases Message-ID: <20130203163839.24F901C1065@cobra.cs.uni-duesseldorf.de> Author: Stephan Branch: Changeset: r349:a907889d585c Date: 2013-02-03 17:37 +0100 http://bitbucket.org/pypy/lang-js/changeset/a907889d585c/ Log: added more jit viewer test cases diff --git a/test/jit_view.py b/test/jit_view.py --- a/test/jit_view.py +++ b/test/jit_view.py @@ -7,11 +7,22 @@ conftest.option = o from pypy.jit.metainterp.test.support import LLJitMixin +from pypy.rlib import jit from js import interpreter class TestJtTrace(LLJitMixin): + def run(self, code, expected): + jsint = interpreter.Interpreter() + + def interp_w(): + jit.set_param(None, "inlining", True) + code_val = jsint.run_src(code) + return code_val.ToNumber() + + assert self.meta_interp(interp_w, [], listcomp=True, backendopt=True, listops=True) == expected + def test_simple_loop(self): code = """ var i = 0; @@ -20,12 +31,8 @@ } return i; """ - jsint = interpreter.Interpreter() - def interp_w(): - code_val = jsint.run_src(code) - return code_val.ToNumber() - assert self.meta_interp(interp_w, [], listcomp=True, backendopt=True, listops=True) == 100 + self.run(code, 100) def test_loop_in_func(self): code = """ @@ -38,12 +45,8 @@ } return f(); """ - jsint = interpreter.Interpreter() - def interp_w(): - code_val = jsint.run_src(code) - return code_val.ToNumber() - assert self.meta_interp(interp_w, [], listcomp=True, backendopt=True, listops=True) == 100 + self.run(code, 100) def test_prop_loop_in_func(self): code = """ @@ -56,12 +59,8 @@ } return f(); """ - jsint = interpreter.Interpreter() - def interp_w(): - code_val = jsint.run_src(code) - return code_val.ToNumber() - assert self.meta_interp(interp_w, [], listcomp=True, backendopt=True, listops=True) == 100 + self.run(code, 100) def test_object_alloc_loop_in_func_loop(self): code = """ @@ -74,12 +73,8 @@ } return f(); """ - jsint = interpreter.Interpreter() - def interp_w(): - code_val = jsint.run_src(code) - return code_val.ToNumber() - assert self.meta_interp(interp_w, [], listcomp=True, backendopt=True, listops=True) == 100 + self.run(code, 100) def test_func_call_in_loop(self): code = """ @@ -92,12 +87,98 @@ } return i; """ - jsint = interpreter.Interpreter() - def interp_w(): - code_val = jsint.run_src(code) - return code_val.ToNumber() - assert self.meta_interp(interp_w, [], listcomp=True, backendopt=True, listops=True) == 100 + self.run(code, 100) + + def test_local_func_call_in_loop(self): + code = """ + (function () { + var i = 0; + function f(a) { + return a + 1; + } + while(i < 100) { + i = f(i); + } + return i; + })(); + """ + + self.run(code, 100) + + def test_double_func_call_in_loop(self): + code = """ + (function () { + var i = 0; + function f(a) { + function g(b) { + return b + 1; + } + return g(a); + } + while(i < 100) { + i = f(i); + } + return i; + })(); + """ + + self.run(code, 100) + + def test_double_func_call_in_loop_no_arg(self): + code = """ + (function () { + var i = 0; + function f() { + function g() { + return i + 1; + } + return g(); + } + while(i < 100) { + i = f(); + } + return i; + })(); + """ + + self.run(code, 100) + + def test_recursive_func_call(self): + code = """ + (function () { + var i = 0; + function f(a) { + if (a < 100) { + return f(a+1); + } + return a; + } + return f(0); + })(); + """ + + self.run(code, 100) + + def test_loop_recursive_func_call(self): + code = """ + (function () { + function f(a) { + if (a < 10) { + return f(a+1); + } + return a; + } + + var i = 0; + while(i < 100) { + i = i + f(i); + } + return i; + })(); + """ + + self.run(code, 100) def test_loop_not_escapeing(self): code = """ @@ -109,13 +190,10 @@ return a; } f(); + 1; """ - jsint = interpreter.Interpreter() - def interp_w(): - code_val = jsint.run_src(code) - return code_val.ToNumber() - assert self.meta_interp(interp_w, [], listcomp=True, backendopt=True, listops=True) == 100 + self.run(code, 1) def test_loop_little_escapeing(self): code = """ @@ -128,17 +206,13 @@ } f(); """ - jsint = interpreter.Interpreter() - def interp_w(): - code_val = jsint.run_src(code) - return code_val.ToNumber() - assert self.meta_interp(interp_w, [], listcomp=True, backendopt=True, listops=True) == 100 + self.run(code, 100) def test_bitwise_and(self): code = """ function f() { - bitwiseAndValue = 4294967296; + var bitwiseAndValue = 4294967296; for (var i = 0; i < 600000; i++) { bitwiseAndValue = bitwiseAndValue & i; } @@ -146,9 +220,5 @@ f(); 1; """ - jsint = interpreter.Interpreter() - def interp_w(): - code_val = jsint.run_src(code) - return code_val.ToNumber() - assert self.meta_interp(interp_w, [], listcomp=True, backendopt=True, listops=True) == 1 + self.run(code, 1) From noreply at buildbot.pypy.org Sun Feb 3 20:56:58 2013 From: noreply at buildbot.pypy.org (fijal) Date: Sun, 3 Feb 2013 20:56:58 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: Start moving frame to ebp (instead of ebp + 0x40) Message-ID: <20130203195658.61B3B1C1384@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r60839:05bcee86f659 Date: 2013-02-03 21:56 +0200 http://bitbucket.org/pypy/pypy/changeset/05bcee86f659/ Log: Start moving frame to ebp (instead of ebp + 0x40) diff --git a/rpython/jit/backend/llsupport/llmodel.py b/rpython/jit/backend/llsupport/llmodel.py --- a/rpython/jit/backend/llsupport/llmodel.py +++ b/rpython/jit/backend/llsupport/llmodel.py @@ -356,12 +356,8 @@ @specialize.arg(1) def get_ofs_of_frame_field(self, name): descrs = self.gc_ll_descr.getframedescrs(self) - if name.startswith('jfi_'): - base_ofs = 0 # not relative to frame - else: - base_ofs = self.unpack_arraydescr(descrs.arraydescr) ofs = self.unpack_fielddescr(getattr(descrs, name)) - return ofs - base_ofs + return ofs def get_baseofs_of_frame_field(self): descrs = self.gc_ll_descr.getframedescrs(self) diff --git a/rpython/jit/backend/llsupport/regalloc.py b/rpython/jit/backend/llsupport/regalloc.py --- a/rpython/jit/backend/llsupport/regalloc.py +++ b/rpython/jit/backend/llsupport/regalloc.py @@ -241,15 +241,18 @@ lst.append(var) # abstract methods that need to be overwritten for specific assemblers - @staticmethod + def frame_pos(loc, type): raise NotImplementedError("Purely abstract") + @staticmethod def frame_size(type): return 1 + @staticmethod def get_loc_index(loc): raise NotImplementedError("Purely abstract") + @staticmethod def newloc(pos, size, tp): """ Reverse of get_loc_index diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -1,5 +1,4 @@ -import weakref import sys, os from rpython.jit.backend.llsupport import symbolic, jitframe from rpython.jit.backend.llsupport.asmmemmgr import MachineDataBlockWrapper @@ -199,7 +198,6 @@ def _build_stack_check_failure(self): mc = codebuf.MachineCodeBlockWrapper() - base_ofs = self.cpu.get_baseofs_of_frame_field() self._push_all_regs_to_frame(mc, [], self.cpu.supports_floats) assert not IS_X86_32 # this is the gcmap stored by push_gcmap(mov=True) in _check_stack_frame @@ -209,12 +207,12 @@ # this is size that we're after, sanity checking only mc.MOV_rs(esi.value, WORD*2) # push first arg - mc.LEA_rb(edi.value, -base_ofs) + mc.MOV_rr(edi.value, ebp.value) # align mc.SUB_ri(esp.value, WORD) mc.CALL(imm(self.cpu.realloc_frame)) mc.ADD_ri(esp.value, WORD) - mc.LEA_rm(ebp.value, (eax.value, base_ofs)) + mc.MOV_rr(ebp.value, eax.value) gcrootmap = self.cpu.gc_ll_descr.gcrootmap if gcrootmap and gcrootmap.is_shadow_stack: @@ -287,9 +285,8 @@ propagate_exception_descr = rffi.cast(lltype.Signed, cast_instance_to_gcref(self.cpu.propagate_exception_descr)) ofs = self.cpu.get_ofs_of_frame_field('jf_descr') - base_ofs = self.cpu.get_baseofs_of_frame_field() self.mc.MOV_bi(ofs, propagate_exception_descr) - self.mc.LEA_rb(eax.value, -base_ofs) + self.mc.MOV_rr(eax.value, ebp.value) # self._call_footer() rawstart = self.mc.materialize(self.cpu.asmmemmgr, []) @@ -395,8 +392,7 @@ # one extra CALL on the stack, but one less PUSH, # save to store stuff 2 locations away on the stack. mc.MOV_sr(3*WORD, eax.value) - base_ofs = self.cpu.get_baseofs_of_frame_field() - mc.LEA_rb(edi.value, -base_ofs) + mc.MOV_rr(edi.value, ebp.value) mc.CALL(imm(func)) # @@ -674,11 +670,10 @@ """ descrs = self.cpu.gc_ll_descr.getframedescrs(self.cpu) ofs = self.cpu.unpack_fielddescr(descrs.arraydescr.lendescr) - base_ofs = self.cpu.get_baseofs_of_frame_field() if expected_size == -1: - mc.CMP_bi(ofs - base_ofs, 0xffffff) + mc.CMP_bi(ofs, 0xffffff) else: - mc.CMP_bi(ofs - base_ofs, expected_size) + mc.CMP_bi(ofs, expected_size) stack_check_cmp_ofs = mc.get_relative_pos() - 4 assert not IS_X86_32 mc.J_il8(rx86.Conditions['GE'], 0) @@ -808,8 +803,7 @@ self.mc.SUB_ri(esp.value, FRAME_FIXED_SIZE * WORD) self.mc.MOV_sr(PASS_ON_MY_FRAME * WORD, ebp.value) if IS_X86_64: - ofs = self.cpu.get_baseofs_of_frame_field() - self.mc.LEA_rm(ebp.value, (edi.value, ofs)) + self.mc.MOV_rr(ebp.value, edi.value) else: xxx @@ -1260,8 +1254,6 @@ rst = gcrootmap.get_root_stack_top_addr() mc.MOV(edx, heap(rst)) mc.MOV(ebp, mem(edx, -WORD)) - base_ofs = self.cpu.get_baseofs_of_frame_field() - mc.ADD_ri(ebp.value, base_ofs) wbdescr = self.cpu.gc_ll_descr.write_barrier_descr if gcrootmap and wbdescr: # frame never uses card marking, so we enforce this is not @@ -1899,12 +1891,13 @@ target = self.failure_recovery_code[exc + 2 * withfloats] fail_descr = cast_instance_to_gcref(guardtok.faildescr) fail_descr = rffi.cast(lltype.Signed, fail_descr) + base_ofs = self.cpu.get_baseofs_of_frame_field() positions = [0] * len(guardtok.fail_locs) for i, loc in enumerate(guardtok.fail_locs): if loc is None: positions[i] = -1 elif isinstance(loc, StackLoc): - positions[i] = loc.value + positions[i] = loc.value - base_ofs else: assert isinstance(loc, RegLoc) assert loc is not ebp # for now @@ -1969,18 +1962,19 @@ def _push_all_regs_to_frame(self, mc, ignored_regs, withfloats, callee_only=False): # Push all general purpose registers + base_ofs = self.cpu.get_baseofs_of_frame_field() if callee_only: regs = gpr_reg_mgr_cls.save_around_call_regs else: regs = gpr_reg_mgr_cls.all_regs for i, gpr in enumerate(regs): if gpr not in ignored_regs: - mc.MOV_br(i * WORD, gpr.value) + mc.MOV_br(i * WORD + base_ofs, gpr.value) if withfloats: # Push all XMM regs ofs = len(gpr_reg_mgr_cls.all_regs) for i in range(len(xmm_reg_mgr_cls.all_regs)): - mc.MOVSD_bx((ofs + i) * WORD, i) + mc.MOVSD_bx((ofs + i) * WORD + base_ofs, i) def _pop_all_regs_from_frame(self, mc, ignored_regs, withfloats, callee_only=False): @@ -2020,13 +2014,12 @@ # did just above. ofs = self.cpu.get_ofs_of_frame_field('jf_descr') ofs2 = self.cpu.get_ofs_of_frame_field('jf_gcmap') - base_ofs = self.cpu.get_baseofs_of_frame_field() mc.POP(eax) mc.MOV_br(ofs2, eax.value) mc.POP(eax) mc.MOV_br(ofs, eax.value) # store the gc pattern - mc.LEA_rb(eax.value, -base_ofs) + mc.MOV_rr(eax.value, ebp.value) self._call_footer() rawstart = mc.materialize(self.cpu.asmmemmgr, []) @@ -2034,17 +2027,17 @@ self.mc = None def genop_finish(self, op, arglocs, result_loc): + base_ofs = self.cpu.get_baseofs_of_frame_field() if len(arglocs) == 2: [return_val, fail_descr_loc] = arglocs if op.getarg(0).type == FLOAT and not IS_X86_64: size = WORD * 2 else: size = WORD - self.save_into_mem(raw_stack(0), return_val, imm(size)) + self.save_into_mem(raw_stack(base_ofs), return_val, imm(size)) else: [fail_descr_loc] = arglocs ofs = self.cpu.get_ofs_of_frame_field('jf_descr') - base_ofs = self.cpu.get_baseofs_of_frame_field() self.mov(fail_descr_loc, RawStackLoc(ofs)) arglist = op.getarglist() if arglist and arglist[0].type == REF: @@ -2055,7 +2048,7 @@ # keep that one and kill all the others ofs = self.cpu.get_ofs_of_frame_field('jf_gcmap') self.mc.MOV_bi(ofs, 0) - self.mc.LEA_rb(eax.value, -base_ofs) + self.mc.MOV_rr(eax.value, ebp.value) # exit function self._call_footer() @@ -2297,9 +2290,8 @@ gcref = cast_instance_to_gcref(value) rgc._make_sure_does_not_move(gcref) value = rffi.cast(lltype.Signed, gcref) - base_ofs = self.cpu.get_baseofs_of_frame_field() ofs = self.cpu.get_ofs_of_frame_field('jf_descr') - self.mc.CMP_mi((eax.value, base_ofs + ofs), value) + self.mc.CMP_mi((eax.value, ofs), value) # patched later self.mc.J_il8(rx86.Conditions['E'], 0) # goto B if we get 'done_with_this_frame' je_location = self.mc.get_relative_pos() @@ -2375,8 +2367,7 @@ loc_base = arglocs[0] if is_frame: assert loc_base is ebp - extra_ofs = self.cpu.get_baseofs_of_frame_field() - loc = raw_stack(descr.jit_wb_if_flag_byteofs - extra_ofs) + loc = raw_stack(descr.jit_wb_if_flag_byteofs) else: loc = addr_add_const(loc_base, descr.jit_wb_if_flag_byteofs) mc.TEST8(loc, imm(mask)) @@ -2540,9 +2531,9 @@ self.mc.MOV(heap(nursery_free_adr), edi) def force_token(self, reg): - base_ofs = self.cpu.get_baseofs_of_frame_field() + # XXX kill me assert isinstance(reg, RegLoc) - self.mc.LEA_rb(reg.value, -base_ofs) + self.mc.MOV_rr(reg.value, ebp.value) genop_discard_list = [Assembler386.not_implemented_op_discard] * rop._LAST genop_list = [Assembler386.not_implemented_op] * rop._LAST @@ -2585,9 +2576,6 @@ def raw_stack(offset, type=INT): return RawStackLoc(offset, type) -def stack(index, type): - return StackLoc(index, get_ebp_ofs(index), type) - def heap(addr): return AddressLoc(ImmedLoc(addr), imm0, 0, 0) diff --git a/rpython/jit/backend/x86/regalloc.py b/rpython/jit/backend/x86/regalloc.py --- a/rpython/jit/backend/x86/regalloc.py +++ b/rpython/jit/backend/x86/regalloc.py @@ -100,15 +100,20 @@ return RegisterManager.after_call(self, v) class X86FrameManager(FrameManager): - @staticmethod - def frame_pos(i, box_type): - return StackLoc(i, get_ebp_ofs(i), box_type) + def __init__(self, base_ofs): + FrameManager.__init__(self) + self.base_ofs = base_ofs + + def frame_pos(self, i, box_type): + return StackLoc(i, get_ebp_ofs(self.base_ofs, i), box_type) + @staticmethod def frame_size(box_type): if IS_X86_32 and box_type == FLOAT: return 2 else: return 1 + @staticmethod def get_loc_index(loc): assert isinstance(loc, StackLoc) @@ -140,8 +145,8 @@ self.final_jump_op = None def _prepare(self, inputargs, operations, allgcrefs): - self.fm = X86FrameManager() cpu = self.assembler.cpu + self.fm = X86FrameManager(cpu.get_baseofs_of_frame_field()) operations = cpu.gc_ll_descr.rewrite_assembler(cpu, operations, allgcrefs) # compute longevity of variables @@ -1367,11 +1372,11 @@ else: oplist[num] = value -def get_ebp_ofs(position): +def get_ebp_ofs(base_ofs, position): # Argument is a frame position (0, 1, 2...). # Returns (ebp+20), (ebp+24), (ebp+28)... # i.e. the n'th word beyond the fixed frame size. - return WORD * (position + JITFRAME_FIXED_SIZE) + return base_ofs + WORD * (position + JITFRAME_FIXED_SIZE) def _valid_addressing_size(size): return size == 1 or size == 2 or size == 4 or size == 8 diff --git a/rpython/jit/backend/x86/regloc.py b/rpython/jit/backend/x86/regloc.py --- a/rpython/jit/backend/x86/regloc.py +++ b/rpython/jit/backend/x86/regloc.py @@ -101,16 +101,14 @@ _immutable_ = True def __init__(self, position, ebp_offset, type): - from rpython.jit.backend.x86.arch import JITFRAME_FIXED_SIZE, WORD - # _getregkey() returns self.value; the value returned must not # conflict with RegLoc._getregkey(). It doesn't a bit by chance, # so let it fail the following assert if it no longer does. assert ebp_offset >= 0 #assert not (0 <= ebp_offset < 8 + 8 * IS_X86_64) self.position = position - if position != 9999: - assert (position + JITFRAME_FIXED_SIZE) * WORD == ebp_offset + #if position != 9999: + # assert (position + JITFRAME_FIXED_SIZE) * WORD == ebp_offset self.value = ebp_offset # One of INT, REF, FLOAT self.type = type diff --git a/rpython/jit/backend/x86/runner.py b/rpython/jit/backend/x86/runner.py --- a/rpython/jit/backend/x86/runner.py +++ b/rpython/jit/backend/x86/runner.py @@ -48,6 +48,23 @@ self.profile_agent = profile_agent + ad = self.gc_ll_descr.getframedescrs(self).arraydescr + self.signedarraydescr = ad + # the same as normal JITFRAME, however with an array of pointers + self.refarraydescr = ArrayDescr(ad.basesize, ad.itemsize, ad.lendescr, + FLAG_POINTER) + self.floatarraydescr = ArrayDescr(ad.basesize, ad.itemsize, ad.lendescr, + FLAG_FLOAT) + + def getarraydescr_for_frame(self, type, index): + if type == history.FLOAT: + descr = self.floatarraydescr + elif type == history.REF: + descr = self.refarraydescr + else: + descr = self.signedarraydescr + return JITFRAME_FIXED_SIZE + index, descr + def set_debug(self, flag): return self.assembler.set_debug(flag) @@ -202,25 +219,4 @@ NUM_REGS = 16 CALLEE_SAVE_REGISTERS = [regloc.ebx, regloc.r12, regloc.r13, regloc.r14, regloc.r15] - def __init__(self, *args, **kwargs): - assert sys.maxint == (2**63 - 1) - super(CPU_X86_64, self).__init__(*args, **kwargs) - descrs = self.gc_ll_descr.getframedescrs(self) - ad = descrs.arraydescr - # the same as normal JITFRAME, however with an array of pointers - self.signedarraydescr = ad - self.refarraydescr = ArrayDescr(ad.basesize, ad.itemsize, ad.lendescr, - FLAG_POINTER) - self.floatarraydescr = ArrayDescr(ad.basesize, ad.itemsize, ad.lendescr, - FLAG_FLOAT) - - def getarraydescr_for_frame(self, type, index): - if type == history.FLOAT: - descr = self.floatarraydescr - elif type == history.REF: - descr = self.refarraydescr - else: - descr = self.signedarraydescr - return JITFRAME_FIXED_SIZE + index, descr - CPU = CPU386 From noreply at buildbot.pypy.org Sun Feb 3 21:10:58 2013 From: noreply at buildbot.pypy.org (mattip) Date: Sun, 3 Feb 2013 21:10:58 +0100 (CET) Subject: [pypy-commit] pypy missing-ndarray-attributes: back out changeset 849864c9f43a Message-ID: <20130203201058.43B221C009B@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: missing-ndarray-attributes Changeset: r60840:1c8ab37095aa Date: 2013-02-03 16:28 +0200 http://bitbucket.org/pypy/pypy/changeset/1c8ab37095aa/ Log: back out changeset 849864c9f43a diff --git a/pypy/module/micronumpy/arrayimpl/sort.py b/pypy/module/micronumpy/arrayimpl/sort.py --- a/pypy/module/micronumpy/arrayimpl/sort.py +++ b/pypy/module/micronumpy/arrayimpl/sort.py @@ -31,20 +31,16 @@ self.indexes = indexes def getitem(self, item): - #v = raw_storage_getitem(TP, self.values, item * self.stride_size - # + self.start) - v = itemtype.read_from_storage(TP, self.values, self.start, - item*self.stride_size) + v = raw_storage_getitem(TP, self.values, item * self.stride_size + + self.start) v = itemtype.for_computation(v) return (v, raw_storage_getitem(lltype.Signed, self.indexes, item * self.index_stride_size + self.index_start)) def setitem(self, idx, item): - #raw_storage_setitem(self.values, idx * self.stride_size + - # self.start, rffi.cast(TP, item[0])) - itemtype.write_to_storage(TP, self.values, self.start, - idx * self.stride_size, item[0]) + raw_storage_setitem(self.values, idx * self.stride_size + + self.start, rffi.cast(TP, item[0])) raw_storage_setitem(self.indexes, idx * self.index_stride_size + self.index_start, item[1]) diff --git a/pypy/module/micronumpy/test/test_numarray.py b/pypy/module/micronumpy/test/test_numarray.py --- a/pypy/module/micronumpy/test/test_numarray.py +++ b/pypy/module/micronumpy/test/test_numarray.py @@ -2371,17 +2371,13 @@ def test_argsort_dtypes(self): from _numpypy import array, arange - nnp = self.non_native_prefix assert array(2.0).argsort() == 0 - for dtype in ['int', 'float', 'int8', 'int16', 'float32', - nnp + 'i2']: - print dtype - a = array([6, 4, 1, 3, 8, 4, 20, 100, 101], dtype=dtype) - c = a.copy() + for dtype in ['int', 'float', 'int8', 'int16', 'float32']: + a = array([6, 4, 1, 3, 8, 3], dtype=dtype) res = a.argsort() - assert (res == [2, 3, 1, 5, 0, 4, 6, 7, 8]).all() - assert (a == c).all() # not modified - a = arange(100, dtype=dtype) + assert (res == [2, 3, 5, 1, 0, 4]).all() + assert (a == [6, 4, 1, 3, 8, 3]).all() # not modified + a = arange(100) assert (a.argsort() == a).all() def test_argsort_nd(self): diff --git a/pypy/module/micronumpy/types.py b/pypy/module/micronumpy/types.py --- a/pypy/module/micronumpy/types.py +++ b/pypy/module/micronumpy/types.py @@ -135,7 +135,6 @@ @specialize.argtype(1) def box(self, value): - # assumes T is both the storage type and the value type return self.BoxType(rffi.cast(self.T, value)) @specialize.argtype(1, 2) @@ -168,31 +167,25 @@ def default_fromstring(self, space): raise NotImplementedError - @staticmethod - def read_from_storage(ST, storage, i, offset): - ret = raw_storage_getitem(ST, storage, i + offset) - return ret + def _read(self, storage, i, offset): + return raw_storage_getitem(self.T, storage, i + offset) def read(self, arr, i, offset, dtype=None): - return self.box(self.read_from_storage(self.T, - arr.storage, i, offset)) + return self.box(self._read(arr.storage, i, offset)) def read_bool(self, arr, i, offset): - return bool(self.for_computation(self.read_from_storage(self.T, - arr.storage, i, offset))) + return bool(self.for_computation(self._read(arr.storage, i, offset))) - @staticmethod - def write_to_storage(ST, storage, i, offset, value): - raw_storage_setitem(storage, i + offset, rffi.cast(ST,value)) + def _write(self, storage, i, offset, value): + raw_storage_setitem(storage, i + offset, value) def store(self, arr, i, offset, box): - self.write_to_storage(self.T, arr.storage, i, offset, - self.unbox(box)) + self._write(arr.storage, i, offset, self.unbox(box)) def fill(self, storage, width, box, start, stop, offset): value = self.unbox(box) for i in xrange(start, stop, width): - self.write_to_storage(self.T, storage, i, offset, value) + self._write(storage, i, offset, value) def runpack_str(self, s): v = runpack(self.format_code, s) @@ -308,16 +301,13 @@ class NonNativePrimitive(Primitive): _mixin_ = True - @staticmethod - def read_from_storage(ST, storage, i, offset): - res = raw_storage_getitem(ST, storage, i + offset) - res = rffi.cast(ST, res) # create a copy for inplace byteswap - return rffi.cast(ST, byteswap(res)) + def _read(self, storage, i, offset): + res = raw_storage_getitem(self.T, storage, i + offset) + return byteswap(res) - @staticmethod - def write_to_storage(ST, storage, i, offset, value): - h = byteswap(rffi.cast(ST, value)) - raw_storage_setitem(storage, i + offset, h) + def _write(self, storage, i, offset, value): + value = byteswap(value) + raw_storage_setitem(storage, i + offset, value) class Bool(BaseType, Primitive): _attrs_ = () @@ -956,27 +946,26 @@ class NonNativeFloat(NonNativePrimitive, Float): _mixin_ = True - @staticmethod - def read_from_storage(ST, storage, i, offset): - res = raw_storage_getitem(ST, storage, i + offset) - return byteswap(res) + def _read(self, storage, i, offset): + res = raw_storage_getitem(self.T, storage, i + offset) + return rffi.cast(lltype.Float, byteswap(res)) - @staticmethod - def write_to_storage(ST, storage, i, offset, value): - swapped_value = byteswap(value) - raw_storage_setitem(storage, i + offset, rffi.cast(ST, swapped_value)) + def _write(self, storage, i, offset, value): + swapped_value = byteswap(rffi.cast(self.T, value)) + raw_storage_setitem(storage, i + offset, swapped_value) class BaseFloat16(Float): - '''This is the only class where the storage type is different from - the underlying ideal type, since C has no 16 bit float - ''' _mixin_ = True _attrs_ = () - T = rffi.USHORT + _STORAGE_T = rffi.USHORT + T = rffi.DOUBLE BoxType = interp_boxes.W_Float16Box + def get_element_size(self): + return rffi.sizeof(self._STORAGE_T) + def runpack_str(self, s): assert len(s) == 2 fval = unpack_float(s, native_is_bigendian) @@ -987,50 +976,29 @@ def byteswap(self, w_v): value = self.unbox(w_v) - hbits = float_pack(float(value),2) - swapped = byteswap(rffi.cast(self.T, hbits)) + hbits = float_pack(value,2) + swapped = byteswap(rffi.cast(self._STORAGE_T, hbits)) return self.box(float_unpack(r_ulonglong(swapped), 2)) - @staticmethod - def for_computation(v): - return rffi.cast(rffi.DOUBLE, v) - - @specialize.argtype(1) - def box(self, value): - # stored as a USHORT, boxed into a DOUBLE - return self.BoxType(rffi.cast(rffi.DOUBLE, value)) - - @specialize.argtype(1, 2) - def box_complex(self, real, imag): - #XXX this is the place to display a warning - return self.BoxType(rffi.cast(rffi.DOUBLE, real)) - - class Float16(BaseType, BaseFloat16): - @staticmethod - def read_from_storage(ST, storage, i, offset): - hbits = raw_storage_getitem(ST, storage, i + offset) + def _read(self, storage, i, offset): + hbits = raw_storage_getitem(self._STORAGE_T, storage, i + offset) return float_unpack(r_ulonglong(hbits), 2) - @staticmethod - def write_to_storage(ST, storage, i, offset, value): - # value can be a r_singlefloat - hbits = float_pack(float(value),2) + def _write(self, storage, i, offset, value): + hbits = float_pack(value,2) raw_storage_setitem(storage, i + offset, - rffi.cast(ST, hbits)) + rffi.cast(self._STORAGE_T, hbits)) class NonNativeFloat16(BaseType, BaseFloat16): - @staticmethod - def read_from_storage(ST, storage, i, offset): - hbits = raw_storage_getitem(ST, storage, i + offset) - r = float_unpack(r_ulonglong(byteswap(hbits)), 2) - return r + def _read(self, storage, i, offset): + hbits = raw_storage_getitem(self._STORAGE_T, storage, i + offset) + return float_unpack(r_ulonglong(byteswap(hbits)), 2) - @staticmethod - def write_to_storage(ST, storage, i, offset, value): - hbits = float_pack(float(value),2) + def _write(self, storage, i, offset, value): + hbits = float_pack(value,2) raw_storage_setitem(storage, i + offset, - byteswap(rffi.cast(ST, hbits))) + byteswap(rffi.cast(self._STORAGE_T, hbits))) class Float32(BaseType, Float): @@ -1047,10 +1015,13 @@ BoxType = interp_boxes.W_Float32Box format_code = "f" - #def read_bool(self, arr, i, offset): - # v = self.for_computation(self.read_from_storage(self.STORAGE_T, - # arr.storage, i, offset)) - # return bool(v) + def read_bool(self, arr, i, offset): + # it's not clear to me why this is needed + # but a hint might be that calling for_computation(v) + # causes translation to fail, and the assert is necessary + v = self._read(arr.storage, i, offset) + assert isinstance(v, float) + return bool(v) class Float64(BaseType, Float): _attrs_ = () @@ -1104,11 +1075,11 @@ return float(v[0]), float(v[1]) def read_bool(self, arr, i, offset): - v = self.for_computation(self.read_from_storage(self.T, arr.storage, i, offset)) + v = self.for_computation(self._read(arr.storage, i, offset)) return bool(v[0]) or bool(v[1]) def get_element_size(self): - return 2 * rffi.sizeof(self.T) + return 2 * rffi.sizeof(self._COMPONENTS_T) def byteswap(self, w_v): real, imag = self.unbox(w_v) @@ -1117,19 +1088,19 @@ @specialize.argtype(1) def box(self, value): return self.BoxType( - rffi.cast(self.T, value), - rffi.cast(self.T, 0.0)) + rffi.cast(self._COMPONENTS_T, value), + rffi.cast(self._COMPONENTS_T, 0.0)) @specialize.argtype(1) def box_component(self, value): return self.ComponentBoxType( - rffi.cast(self.T, value)) + rffi.cast(self._COMPONENTS_T, value)) @specialize.argtype(1, 2) def box_complex(self, real, imag): return self.BoxType( - rffi.cast(self.T, real), - rffi.cast(self.T, imag)) + rffi.cast(self._COMPONENTS_T, real), + rffi.cast(self._COMPONENTS_T, imag)) def unbox(self, box): assert isinstance(box, self.BoxType) @@ -1141,18 +1112,16 @@ real, imag = self.unbox(box) raw_storage_setitem(arr.storage, i+offset, real) raw_storage_setitem(arr.storage, - i+offset+rffi.sizeof(self.T), imag) + i+offset+rffi.sizeof(self._COMPONENTS_T), imag) - @staticmethod - def read_from_storage(ST, storage, i, offset): - real = raw_storage_getitem(ST, storage, i + offset) - imag = raw_storage_getitem(ST, storage, - i + offset + rffi.sizeof(ST)) + def _read(self, storage, i, offset): + real = raw_storage_getitem(self._COMPONENTS_T, storage, i + offset) + imag = raw_storage_getitem(self._COMPONENTS_T, storage, + i + offset + rffi.sizeof(self._COMPONENTS_T)) return real, imag def read(self, arr, i, offset, dtype=None): - real, imag = self.read_from_storage(self.T, arr.storage, i, - offset) + real, imag = self._read(arr.storage, i, offset) return self.box_complex(real, imag) @complex_binary_op @@ -1566,7 +1535,8 @@ class Complex64(ComplexFloating, BaseType): _attrs_ = () - T = rffi.FLOAT + T = rffi.CHAR + _COMPONENTS_T = rffi.FLOAT BoxType = interp_boxes.W_Complex64Box ComponentBoxType = interp_boxes.W_Float32Box @@ -1576,7 +1546,8 @@ class Complex128(ComplexFloating, BaseType): _attrs_ = () - T = rffi.DOUBLE + T = rffi.CHAR + _COMPONENTS_T = rffi.DOUBLE BoxType = interp_boxes.W_Complex128Box ComponentBoxType = interp_boxes.W_Float64Box @@ -1608,7 +1579,8 @@ class Complex192(ComplexFloating, BaseType): _attrs_ = () - T = rffi.LONGDOUBLE + T = rffi.CHAR + _COMPONENTS_T = rffi.LONGDOUBLE BoxType = interp_boxes.W_Complex192Box ComponentBoxType = interp_boxes.W_Float96Box @@ -1639,7 +1611,8 @@ class Complex256(ComplexFloating, BaseType): _attrs_ = () - T = rffi.LONGDOUBLE + T = rffi.CHAR + _COMPONENTS_T = rffi.LONGDOUBLE BoxType = interp_boxes.W_Complex256Box ComponentBoxType = interp_boxes.W_Float128Box From noreply at buildbot.pypy.org Sun Feb 3 21:10:59 2013 From: noreply at buildbot.pypy.org (mattip) Date: Sun, 3 Feb 2013 21:10:59 +0100 (CET) Subject: [pypy-commit] pypy missing-ndarray-attributes: add a failing test Message-ID: <20130203201059.B6BC41C009B@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: missing-ndarray-attributes Changeset: r60841:fc95c2315476 Date: 2013-02-03 22:10 +0200 http://bitbucket.org/pypy/pypy/changeset/fc95c2315476/ Log: add a failing test diff --git a/pypy/module/micronumpy/test/test_numarray.py b/pypy/module/micronumpy/test/test_numarray.py --- a/pypy/module/micronumpy/test/test_numarray.py +++ b/pypy/module/micronumpy/test/test_numarray.py @@ -2372,11 +2372,14 @@ def test_argsort_dtypes(self): from _numpypy import array, arange assert array(2.0).argsort() == 0 - for dtype in ['int', 'float', 'int8', 'int16', 'float32']: - a = array([6, 4, 1, 3, 8, 3], dtype=dtype) + nnp = self.non_native_prefix + for dtype in ['int', 'float', 'int8', 'int16', 'float32', + nnp + 'i2']: + a = array([6, 4, -1, 3, 8, 3, 256+20, 100, 101], dtype=dtype) + c = a.copy() res = a.argsort() - assert (res == [2, 3, 5, 1, 0, 4]).all() - assert (a == [6, 4, 1, 3, 8, 3]).all() # not modified + assert (res == [2, 3, 5, 1, 0, 4, 7, 8, 6]).all() + assert (a == c).all() # not modified a = arange(100) assert (a.argsort() == a).all() From noreply at buildbot.pypy.org Sun Feb 3 22:05:39 2013 From: noreply at buildbot.pypy.org (mattip) Date: Sun, 3 Feb 2013 22:05:39 +0100 (CET) Subject: [pypy-commit] pypy missing-ndarray-attributes: complex fails Message-ID: <20130203210539.927CD1C1440@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: missing-ndarray-attributes Changeset: r60843:6de4c9815dae Date: 2013-02-03 23:00 +0200 http://bitbucket.org/pypy/pypy/changeset/6de4c9815dae/ Log: complex fails diff --git a/pypy/module/micronumpy/test/test_numarray.py b/pypy/module/micronumpy/test/test_numarray.py --- a/pypy/module/micronumpy/test/test_numarray.py +++ b/pypy/module/micronumpy/test/test_numarray.py @@ -2374,7 +2374,7 @@ assert array(2.0).argsort() == 0 nnp = self.non_native_prefix for dtype in ['int', 'float', 'int16', 'float32', - nnp + 'i2']: + nnp + 'i2', complex]: a = array([6, 4, -1, 3, 8, 3, 256+20, 100, 101], dtype=dtype) c = a.copy() res = a.argsort() From noreply at buildbot.pypy.org Sun Feb 3 22:05:38 2013 From: noreply at buildbot.pypy.org (mattip) Date: Sun, 3 Feb 2013 22:05:38 +0100 (CET) Subject: [pypy-commit] pypy missing-ndarray-attributes: fix test to fail for the right reason, avoid non-native argsort via astype() rather than copy() Message-ID: <20130203210538.420251C143F@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: missing-ndarray-attributes Changeset: r60842:7f5153135ef0 Date: 2013-02-03 22:57 +0200 http://bitbucket.org/pypy/pypy/changeset/7f5153135ef0/ Log: fix test to fail for the right reason, avoid non-native argsort via astype() rather than copy() diff --git a/pypy/module/micronumpy/interp_numarray.py b/pypy/module/micronumpy/interp_numarray.py --- a/pypy/module/micronumpy/interp_numarray.py +++ b/pypy/module/micronumpy/interp_numarray.py @@ -420,8 +420,13 @@ # happily ignore the kind # create a contiguous copy of the array # we must do that, because we need a working set. otherwise - # we would modify the array in-place - contig = self.descr_copy(space) + # we would modify the array in-place. Use this to our advantage + # by converting nonnative byte order. + s = self.get_dtype().name + if not self.get_dtype().native: + s = s[1:] + dtype = interp_dtype.get_dtype_cache(space).dtypes_by_name[s] + contig = self.implementation.astype(space, dtype) return contig.implementation.argsort(space, w_axis) def descr_astype(self, space, w_dtype): diff --git a/pypy/module/micronumpy/test/test_numarray.py b/pypy/module/micronumpy/test/test_numarray.py --- a/pypy/module/micronumpy/test/test_numarray.py +++ b/pypy/module/micronumpy/test/test_numarray.py @@ -2373,7 +2373,7 @@ from _numpypy import array, arange assert array(2.0).argsort() == 0 nnp = self.non_native_prefix - for dtype in ['int', 'float', 'int8', 'int16', 'float32', + for dtype in ['int', 'float', 'int16', 'float32', nnp + 'i2']: a = array([6, 4, -1, 3, 8, 3, 256+20, 100, 101], dtype=dtype) c = a.copy() From noreply at buildbot.pypy.org Sun Feb 3 23:04:39 2013 From: noreply at buildbot.pypy.org (fijal) Date: Sun, 3 Feb 2013 23:04:39 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: more fixes Message-ID: <20130203220439.3DDA01C0183@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r60844:2f6015f5228e Date: 2013-02-04 00:04 +0200 http://bitbucket.org/pypy/pypy/changeset/2f6015f5228e/ Log: more fixes diff --git a/rpython/jit/backend/x86/arch.py b/rpython/jit/backend/x86/arch.py --- a/rpython/jit/backend/x86/arch.py +++ b/rpython/jit/backend/x86/arch.py @@ -33,10 +33,10 @@ # ebp + ebx + esi + edi + 6 extra words + return address = 9 words FRAME_FIXED_SIZE = 11 PASS_ON_MY_FRAME = 6 - JITFRAME_FIXED_SIZE = 28 # 13 GPR + 15 XMM + JITFRAME_FIXED_SIZE = 6 + 8 # 6 GPR + 8 XMM else: # rbp + rbx + r12 + r13 + r14 + r15 + 12 extra words + return address = 19 FRAME_FIXED_SIZE = 19 PASS_ON_MY_FRAME = 12 - JITFRAME_FIXED_SIZE = 6 + 8 # 6 GPR + 8 XMM + JITFRAME_FIXED_SIZE = 28 # 13 GPR + 15 XMM diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -70,7 +70,7 @@ if isinstance(loc, RegLoc): val = gpr_reg_mgr_cls.all_reg_indexes[loc.value] else: - val = loc.value // WORD + val = loc.position + JITFRAME_FIXED_SIZE gcmap[val // WORD // 8] |= r_uint(1) << (val % (WORD * 8)) return gcmap @@ -1939,6 +1939,7 @@ locs = [] GPR_REGS = len(gpr_reg_mgr_cls.all_regs) XMM_REGS = len(xmm_reg_mgr_cls.all_regs) + base_ofs = self.cpu.get_baseofs_of_frame_field() input_i = 0 for pos in descr.rd_locs: if pos == -1: @@ -1952,7 +1953,7 @@ i = pos // WORD - JITFRAME_FIXED_SIZE assert i >= 0 tp = inputargs[input_i].type - locs.append(StackLoc(i, pos, tp)) + locs.append(StackLoc(i, get_ebp_ofs(base_ofs, i), tp)) input_i += 1 return locs diff --git a/rpython/jit/backend/x86/regalloc.py b/rpython/jit/backend/x86/regalloc.py --- a/rpython/jit/backend/x86/regalloc.py +++ b/rpython/jit/backend/x86/regalloc.py @@ -910,7 +910,7 @@ for box, loc in self.fm.bindings.iteritems(): if box.type == REF: assert isinstance(loc, StackLoc) - val = loc.value // WORD + val = loc.position + JITFRAME_FIXED_SIZE gcmap[val // WORD // 8] |= r_uint(1) << (val % (WORD * 8)) for i in range(len(gcmap)): debug_print(str(gcmap[i])) From noreply at buildbot.pypy.org Sun Feb 3 23:13:48 2013 From: noreply at buildbot.pypy.org (fijal) Date: Sun, 3 Feb 2013 23:13:48 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: 2.6 compat Message-ID: <20130203221348.8F5691C009B@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r60845:06fccd6b6d76 Date: 2013-02-04 00:13 +0200 http://bitbucket.org/pypy/pypy/changeset/06fccd6b6d76/ Log: 2.6 compat diff --git a/rpython/jit/backend/llsupport/regalloc.py b/rpython/jit/backend/llsupport/regalloc.py --- a/rpython/jit/backend/llsupport/regalloc.py +++ b/rpython/jit/backend/llsupport/regalloc.py @@ -2,7 +2,10 @@ from rpython.jit.metainterp.history import Const, Box, REF, INT from rpython.rlib.objectmodel import we_are_translated, specialize from rpython.jit.metainterp.resoperation import rop -from collections import OrderedDict +try: + from collections import OrderedDict +except ImportError: + OrderedDict = dict # too bad class TempBox(Box): def __init__(self): From noreply at buildbot.pypy.org Sun Feb 3 23:20:35 2013 From: noreply at buildbot.pypy.org (fijal) Date: Sun, 3 Feb 2013 23:20:35 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: 32bit alignment fixes Message-ID: <20130203222035.B1C4D1C009B@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r60846:4ccd13403a61 Date: 2013-02-04 00:20 +0200 http://bitbucket.org/pypy/pypy/changeset/4ccd13403a61/ Log: 32bit alignment fixes diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -199,7 +199,6 @@ def _build_stack_check_failure(self): mc = codebuf.MachineCodeBlockWrapper() self._push_all_regs_to_frame(mc, [], self.cpu.supports_floats) - assert not IS_X86_32 # this is the gcmap stored by push_gcmap(mov=True) in _check_stack_frame mc.MOV_rs(ecx.value, WORD) gcmap_ofs = self.cpu.get_ofs_of_frame_field('jf_gcmap') @@ -209,9 +208,11 @@ # push first arg mc.MOV_rr(edi.value, ebp.value) # align - mc.SUB_ri(esp.value, WORD) + align = align_stack_words(1) + mc.SUB_ri(esp.value, (align - 1) * WORD) + mc.CALL(imm(self.cpu.realloc_frame)) - mc.ADD_ri(esp.value, WORD) + mc.ADD_ri(esp.value, (align - 1) * WORD) mc.MOV_rr(ebp.value, eax.value) gcrootmap = self.cpu.gc_ll_descr.gcrootmap From noreply at buildbot.pypy.org Sun Feb 3 23:21:14 2013 From: noreply at buildbot.pypy.org (fijal) Date: Sun, 3 Feb 2013 23:21:14 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: fix the test Message-ID: <20130203222114.3946B1C009B@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r60847:a2b22f5fb5a8 Date: 2013-02-04 00:20 +0200 http://bitbucket.org/pypy/pypy/changeset/a2b22f5fb5a8/ Log: fix the test diff --git a/rpython/jit/backend/x86/test/test_assembler.py b/rpython/jit/backend/x86/test/test_assembler.py --- a/rpython/jit/backend/x86/test/test_assembler.py +++ b/rpython/jit/backend/x86/test/test_assembler.py @@ -55,7 +55,7 @@ asm = cpu.assembler asm.setup_once() asm.setup(looptoken) - self.fm = X86FrameManager() + self.fm = X86FrameManager(0) self.xrm = X86XMMRegisterManager(None, frame_manager=self.fm, assembler=asm) callback(asm) From noreply at buildbot.pypy.org Sun Feb 3 23:22:59 2013 From: noreply at buildbot.pypy.org (fijal) Date: Sun, 3 Feb 2013 23:22:59 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: remove specialcases Message-ID: <20130203222259.B7E931C009B@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r60848:6b93c6fc5780 Date: 2013-02-04 00:22 +0200 http://bitbucket.org/pypy/pypy/changeset/6b93c6fc5780/ Log: remove specialcases diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -800,13 +800,9 @@ return frame_depth def _call_header(self): - # XXX should be LEA? self.mc.SUB_ri(esp.value, FRAME_FIXED_SIZE * WORD) self.mc.MOV_sr(PASS_ON_MY_FRAME * WORD, ebp.value) - if IS_X86_64: - self.mc.MOV_rr(ebp.value, edi.value) - else: - xxx + self.mc.MOV_rr(ebp.value, edi.value) for i, loc in enumerate(self.cpu.CALLEE_SAVE_REGISTERS): self.mc.MOV_sr((PASS_ON_MY_FRAME + i + 1) * WORD, loc.value) @@ -863,10 +859,7 @@ # to provide a place where we can read the frame from, in case # we need to reload it after a collection rst = self._load_shadowstack_top_in_ebx(self.mc, gcrootmap) - if IS_X86_64: - self.mc.MOV_mr((ebx.value, 0), edi.value) # MOV [ebx], edi - else: - xxx + self.mc.MOV_mr((ebx.value, 0), edi.value) # MOV [ebx], edi self.mc.ADD_ri(ebx.value, WORD) if rx86.fits_in_32bits(rst): self.mc.MOV_jr(rst, ebx.value) # MOV [rootstacktop], ebx From noreply at buildbot.pypy.org Mon Feb 4 01:10:08 2013 From: noreply at buildbot.pypy.org (mattip) Date: Mon, 4 Feb 2013 01:10:08 +0100 (CET) Subject: [pypy-commit] pypy missing-ndarray-attributes: cannot stop in pdb on failing assert, print instead Message-ID: <20130204001008.20CB01C02AF@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: missing-ndarray-attributes Changeset: r60850:1c94dc8e7e8d Date: 2013-02-03 23:12 +0200 http://bitbucket.org/pypy/pypy/changeset/1c94dc8e7e8d/ Log: cannot stop in pdb on failing assert, print instead diff --git a/pypy/module/micronumpy/test/test_numarray.py b/pypy/module/micronumpy/test/test_numarray.py --- a/pypy/module/micronumpy/test/test_numarray.py +++ b/pypy/module/micronumpy/test/test_numarray.py @@ -2378,7 +2378,8 @@ a = array([6, 4, -1, 3, 8, 3, 256+20, 100, 101], dtype=dtype) c = a.copy() res = a.argsort() - assert (res == [2, 3, 5, 1, 0, 4, 7, 8, 6]).all() + assert (res == [2, 3, 5, 1, 0, 4, 7, 8, 6]).all(), \ + 'a,res,dtype %r,%r,%r' % (a,res,dtype) assert (a == c).all() # not modified a = arange(100) assert (a.argsort() == a).all() From noreply at buildbot.pypy.org Mon Feb 4 01:10:06 2013 From: noreply at buildbot.pypy.org (mattip) Date: Mon, 4 Feb 2013 01:10:06 +0100 (CET) Subject: [pypy-commit] pypy missing-ndarray-attributes: float16 fails argsort Message-ID: <20130204001006.D0DFC1C0183@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: missing-ndarray-attributes Changeset: r60849:41f4d672d338 Date: 2013-02-03 23:09 +0200 http://bitbucket.org/pypy/pypy/changeset/41f4d672d338/ Log: float16 fails argsort diff --git a/pypy/module/micronumpy/test/test_numarray.py b/pypy/module/micronumpy/test/test_numarray.py --- a/pypy/module/micronumpy/test/test_numarray.py +++ b/pypy/module/micronumpy/test/test_numarray.py @@ -2373,7 +2373,7 @@ from _numpypy import array, arange assert array(2.0).argsort() == 0 nnp = self.non_native_prefix - for dtype in ['int', 'float', 'int16', 'float32', + for dtype in ['int', 'float', 'int16', 'float32', 'float16', nnp + 'i2', complex]: a = array([6, 4, -1, 3, 8, 3, 256+20, 100, 101], dtype=dtype) c = a.copy() From noreply at buildbot.pypy.org Mon Feb 4 01:10:09 2013 From: noreply at buildbot.pypy.org (mattip) Date: Mon, 4 Feb 2013 01:10:09 +0100 (CET) Subject: [pypy-commit] pypy missing-ndarray-attributes: argsort for Float16, but rely on lexical identity of float16 and signed short Message-ID: <20130204001009.5F64C1C0183@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: missing-ndarray-attributes Changeset: r60851:530f3bab420e Date: 2013-02-04 00:35 +0200 http://bitbucket.org/pypy/pypy/changeset/530f3bab420e/ Log: argsort for Float16, but rely on lexical identity of float16 and signed short diff --git a/pypy/module/micronumpy/test/test_numarray.py b/pypy/module/micronumpy/test/test_numarray.py --- a/pypy/module/micronumpy/test/test_numarray.py +++ b/pypy/module/micronumpy/test/test_numarray.py @@ -1688,7 +1688,7 @@ assert s1[39:31:-1] == s2[32:40] assert s1[:39:-1] == s2[40:] - a = array([1, -1, 10000], dtype='float16') + a = array([3.14, -1.5, 10000], dtype='float16') s1 = map(ord,a.tostring()) s2 = map(ord, a.byteswap().tostring()) s3 = [s1[1], s1[0],s1[3], s1[2], s1[5], s1[4]] diff --git a/pypy/module/micronumpy/types.py b/pypy/module/micronumpy/types.py --- a/pypy/module/micronumpy/types.py +++ b/pypy/module/micronumpy/types.py @@ -959,12 +959,13 @@ _attrs_ = () _STORAGE_T = rffi.USHORT - T = rffi.DOUBLE + T = rffi.SHORT BoxType = interp_boxes.W_Float16Box - def get_element_size(self): - return rffi.sizeof(self._STORAGE_T) + @specialize.argtype(1) + def box(self, value): + return self.BoxType(rffi.cast(rffi.DOUBLE, value)) def runpack_str(self, s): assert len(s) == 2 From noreply at buildbot.pypy.org Mon Feb 4 01:10:10 2013 From: noreply at buildbot.pypy.org (mattip) Date: Mon, 4 Feb 2013 01:10:10 +0100 (CET) Subject: [pypy-commit] pypy missing-ndarray-attributes: simplify complex, extend argsort to work for complex Message-ID: <20130204001010.9D7401C0183@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: missing-ndarray-attributes Changeset: r60852:33c8a9999dba Date: 2013-02-04 01:08 +0200 http://bitbucket.org/pypy/pypy/changeset/33c8a9999dba/ Log: simplify complex, extend argsort to work for complex diff --git a/pypy/module/micronumpy/arrayimpl/sort.py b/pypy/module/micronumpy/arrayimpl/sort.py --- a/pypy/module/micronumpy/arrayimpl/sort.py +++ b/pypy/module/micronumpy/arrayimpl/sort.py @@ -16,8 +16,9 @@ INT_SIZE = rffi.sizeof(lltype.Signed) -def make_sort_function(space, itemtype): +def make_sort_function(space, itemtype, count=1): TP = itemtype.T + step = rffi.sizeof(TP) class Repr(object): def __init__(self, index_stride_size, stride_size, size, values, @@ -31,16 +32,29 @@ self.indexes = indexes def getitem(self, item): - v = raw_storage_getitem(TP, self.values, item * self.stride_size + if count < 2: + v = raw_storage_getitem(TP, self.values, item * self.stride_size + self.start) - v = itemtype.for_computation(v) + v = itemtype.for_computation(v) + else: + v = [] + for i in range(count): + _v = raw_storage_getitem(TP, self.values, item * self.stride_size + + self.start + step * i) + v.append(_v) + v = itemtype.for_computation(v) return (v, raw_storage_getitem(lltype.Signed, self.indexes, item * self.index_stride_size + self.index_start)) def setitem(self, idx, item): - raw_storage_setitem(self.values, idx * self.stride_size + + if count < 2: + raw_storage_setitem(self.values, idx * self.stride_size + self.start, rffi.cast(TP, item[0])) + else: + for i in range(count): + raw_storage_setitem(self.values, idx * self.stride_size + + self.start + i*step, rffi.cast(TP, item[0][i])) raw_storage_setitem(self.indexes, idx * self.index_stride_size + self.index_start, item[1]) @@ -49,7 +63,8 @@ start = 0 dtype = interp_dtype.get_dtype_cache(space).w_longdtype self.indexes = dtype.itemtype.malloc(size*dtype.get_size()) - self.values = alloc_raw_storage(size*rffi.sizeof(TP), track_allocation=False) + self.values = alloc_raw_storage(size * stride_size, + track_allocation=False) Repr.__init__(self, index_stride_size, stride_size, size, self.values, self.indexes, start, start) @@ -152,6 +167,9 @@ self.built = True cache = {} for cls in all_types._items: - cache[cls] = make_sort_function(space, cls) + if cls in types.all_complex_types: + cache[cls] = make_sort_function(space, cls, 2) + else: + cache[cls] = make_sort_function(space, cls) self.cache = cache self._lookup = specialize.memo()(lambda tp : cache[tp]) diff --git a/pypy/module/micronumpy/types.py b/pypy/module/micronumpy/types.py --- a/pypy/module/micronumpy/types.py +++ b/pypy/module/micronumpy/types.py @@ -1080,7 +1080,7 @@ return bool(v[0]) or bool(v[1]) def get_element_size(self): - return 2 * rffi.sizeof(self._COMPONENTS_T) + return 2 * rffi.sizeof(self.T) def byteswap(self, w_v): real, imag = self.unbox(w_v) @@ -1089,19 +1089,19 @@ @specialize.argtype(1) def box(self, value): return self.BoxType( - rffi.cast(self._COMPONENTS_T, value), - rffi.cast(self._COMPONENTS_T, 0.0)) + rffi.cast(self.T, value), + rffi.cast(self.T, 0.0)) @specialize.argtype(1) def box_component(self, value): return self.ComponentBoxType( - rffi.cast(self._COMPONENTS_T, value)) + rffi.cast(self.T, value)) @specialize.argtype(1, 2) def box_complex(self, real, imag): return self.BoxType( - rffi.cast(self._COMPONENTS_T, real), - rffi.cast(self._COMPONENTS_T, imag)) + rffi.cast(self.T, real), + rffi.cast(self.T, imag)) def unbox(self, box): assert isinstance(box, self.BoxType) @@ -1113,12 +1113,12 @@ real, imag = self.unbox(box) raw_storage_setitem(arr.storage, i+offset, real) raw_storage_setitem(arr.storage, - i+offset+rffi.sizeof(self._COMPONENTS_T), imag) + i+offset+rffi.sizeof(self.T), imag) def _read(self, storage, i, offset): - real = raw_storage_getitem(self._COMPONENTS_T, storage, i + offset) - imag = raw_storage_getitem(self._COMPONENTS_T, storage, - i + offset + rffi.sizeof(self._COMPONENTS_T)) + real = raw_storage_getitem(self.T, storage, i + offset) + imag = raw_storage_getitem(self.T, storage, + i + offset + rffi.sizeof(self.T)) return real, imag def read(self, arr, i, offset, dtype=None): @@ -1536,8 +1536,7 @@ class Complex64(ComplexFloating, BaseType): _attrs_ = () - T = rffi.CHAR - _COMPONENTS_T = rffi.FLOAT + T = rffi.FLOAT BoxType = interp_boxes.W_Complex64Box ComponentBoxType = interp_boxes.W_Float32Box @@ -1547,8 +1546,7 @@ class Complex128(ComplexFloating, BaseType): _attrs_ = () - T = rffi.CHAR - _COMPONENTS_T = rffi.DOUBLE + T = rffi.DOUBLE BoxType = interp_boxes.W_Complex128Box ComponentBoxType = interp_boxes.W_Float64Box @@ -1580,8 +1578,7 @@ class Complex192(ComplexFloating, BaseType): _attrs_ = () - T = rffi.CHAR - _COMPONENTS_T = rffi.LONGDOUBLE + T = rffi.LONGDOUBLE BoxType = interp_boxes.W_Complex192Box ComponentBoxType = interp_boxes.W_Float96Box @@ -1612,8 +1609,7 @@ class Complex256(ComplexFloating, BaseType): _attrs_ = () - T = rffi.CHAR - _COMPONENTS_T = rffi.LONGDOUBLE + T = rffi.LONGDOUBLE BoxType = interp_boxes.W_Complex256Box ComponentBoxType = interp_boxes.W_Float128Box From noreply at buildbot.pypy.org Mon Feb 4 01:10:13 2013 From: noreply at buildbot.pypy.org (mattip) Date: Mon, 4 Feb 2013 01:10:13 +0100 (CET) Subject: [pypy-commit] pypy missing-ndarray-attributes: merge default into branch Message-ID: <20130204001013.53F411C0183@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: missing-ndarray-attributes Changeset: r60853:09e6ceb774df Date: 2013-02-04 01:08 +0200 http://bitbucket.org/pypy/pypy/changeset/09e6ceb774df/ Log: merge default into branch diff too long, truncating to 2000 out of 3014 lines diff --git a/lib-python/2.7/collections.py b/lib-python/2.7/collections.py --- a/lib-python/2.7/collections.py +++ b/lib-python/2.7/collections.py @@ -6,7 +6,6 @@ __all__ += _abcoll.__all__ from _collections import deque, defaultdict -from operator import itemgetter as _itemgetter from keyword import iskeyword as _iskeyword import sys as _sys import heapq as _heapq @@ -298,7 +297,7 @@ _fields = %(field_names)r \n def __new__(_cls, %(argtxt)s): 'Create new instance of %(typename)s(%(argtxt)s)' - return _tuple.__new__(_cls, (%(argtxt)s)) \n + return tuple.__new__(_cls, (%(argtxt)s)) \n @classmethod def _make(cls, iterable, new=tuple.__new__, len=len): 'Make a new %(typename)s object from a sequence or iterable' @@ -323,14 +322,14 @@ 'Return self as a plain tuple. Used by copy and pickle.' return tuple(self) \n\n''' % locals() for i, name in enumerate(field_names): - template += " %s = _property(_itemgetter(%d), doc='Alias for field number %d')\n" % (name, i, i) + template += " %s = property(lambda self: self[%d], doc='Alias for field number %d')\n" % (name, i, i) if verbose: print template # Execute the template string in a temporary namespace and # support tracing utilities by setting a value for frame.f_globals['__name__'] - namespace = dict(_itemgetter=_itemgetter, __name__='namedtuple_%s' % typename, - OrderedDict=OrderedDict, _property=property, _tuple=tuple) + namespace = {'__name__': 'namedtuple_%s' % typename, + 'OrderedDict': OrderedDict} try: exec template in namespace except SyntaxError, e: diff --git a/lib-python/2.7/inspect.py b/lib-python/2.7/inspect.py --- a/lib-python/2.7/inspect.py +++ b/lib-python/2.7/inspect.py @@ -960,7 +960,7 @@ raise TypeError('%s() takes exactly 0 arguments ' '(%d given)' % (f_name, num_total)) else: - raise TypeError('%s() takes no argument (%d given)' % + raise TypeError('%s() takes no arguments (%d given)' % (f_name, num_total)) for arg in args: if isinstance(arg, str) and arg in named: diff --git a/lib-python/2.7/site.py b/lib-python/2.7/site.py --- a/lib-python/2.7/site.py +++ b/lib-python/2.7/site.py @@ -75,6 +75,7 @@ USER_SITE = None USER_BASE = None + def makepath(*paths): dir = os.path.join(*paths) try: diff --git a/lib-python/2.7/sysconfig.py b/lib-python/2.7/sysconfig.py --- a/lib-python/2.7/sysconfig.py +++ b/lib-python/2.7/sysconfig.py @@ -27,10 +27,10 @@ 'data' : '{base}', }, 'pypy': { - 'stdlib': '{base}/lib-python', - 'platstdlib': '{base}/lib-python', - 'purelib': '{base}/lib-python', - 'platlib': '{base}/lib-python', + 'stdlib': '{base}/lib-python/{py_version_short}', + 'platstdlib': '{base}/lib-python/{py_version_short}', + 'purelib': '{base}/lib-python/{py_version_short}', + 'platlib': '{base}/lib-python/{py_version_short}', 'include': '{base}/include', 'platinclude': '{base}/include', 'scripts': '{base}/bin', diff --git a/lib-python/2.7/test/test_capi.py b/lib-python/2.7/test/test_capi.py --- a/lib-python/2.7/test/test_capi.py +++ b/lib-python/2.7/test/test_capi.py @@ -13,6 +13,17 @@ threading = None import _testcapi +skips = [] +if test_support.check_impl_detail(pypy=True): + skips += [ + 'test_broken_memoryview', + 'test_capsule', + 'test_lazy_hash_inheritance', + 'test_widechar', + 'TestThreadState', + 'TestPendingCalls', + ] + @unittest.skipUnless(threading, 'Threading required for this test.') class TestPendingCalls(unittest.TestCase): @@ -99,7 +110,7 @@ def test_main(): for name in dir(_testcapi): - if name.startswith('test_'): + if name.startswith('test_') and name not in skips: test = getattr(_testcapi, name) if test_support.verbose: print "internal", name @@ -126,7 +137,7 @@ raise test_support.TestFailed, \ "Couldn't find main thread correctly in the list" - if threading: + if threading and 'TestThreadState' not in skips: import thread import time TestThreadState() @@ -134,7 +145,8 @@ t.start() t.join() - test_support.run_unittest(TestPendingCalls) + if 'TestPendingCalls' not in skips: + test_support.run_unittest(TestPendingCalls) if __name__ == "__main__": test_main() diff --git a/lib-python/2.7/test/test_itertools.py b/lib-python/2.7/test/test_itertools.py --- a/lib-python/2.7/test/test_itertools.py +++ b/lib-python/2.7/test/test_itertools.py @@ -533,11 +533,11 @@ self.assertEqual(list(izip()), zip()) self.assertRaises(TypeError, izip, 3) self.assertRaises(TypeError, izip, range(3), 3) - self.assertEqual([tuple(list(pair)) for pair in izip('abc', 'def')], zip('abc', 'def')) self.assertEqual([pair for pair in izip('abc', 'def')], zip('abc', 'def')) + @test_support.impl_detail("tuple reuse is specific to CPython") def test_izip_tuple_reuse(self): ids = map(id, izip('abc', 'def')) @@ -588,6 +588,7 @@ zip('abc', 'def')) self.assertEqual([pair for pair in izip_longest('abc', 'def')], zip('abc', 'def')) + @test_support.impl_detail("tuple reuse is specific to CPython") def test_izip_longest_tuple_reuse(self): ids = map(id, izip_longest('abc', 'def')) diff --git a/lib-python/2.7/test/test_multiprocessing.py b/lib-python/2.7/test/test_multiprocessing.py --- a/lib-python/2.7/test/test_multiprocessing.py +++ b/lib-python/2.7/test/test_multiprocessing.py @@ -1343,7 +1343,7 @@ # Because we are using xmlrpclib for serialization instead of # pickle this will cause a serialization error. - self.assertRaises(Exception, queue.put, time.sleep) + self.assertRaises(Exception, queue.put, object) # Make queue finalizer run before the server is stopped del queue @@ -1800,9 +1800,9 @@ if not gc.isenabled(): gc.enable() self.addCleanup(gc.disable) - thresholds = gc.get_threshold() - self.addCleanup(gc.set_threshold, *thresholds) - gc.set_threshold(10) + #thresholds = gc.get_threshold() + #self.addCleanup(gc.set_threshold, *thresholds) + #gc.set_threshold(10) # perform numerous block allocations, with cyclic references to make # sure objects are collected asynchronously by the gc @@ -1865,6 +1865,7 @@ def test_synchronize(self): self.test_sharedctypes(lock=True) + @unittest.skipUnless(test_support.check_impl_detail(pypy=False), "pypy ctypes differences") def test_copy(self): foo = _Foo(2, 5.0) bar = copy(foo) diff --git a/lib-python/2.7/test/test_support.py b/lib-python/2.7/test/test_support.py --- a/lib-python/2.7/test/test_support.py +++ b/lib-python/2.7/test/test_support.py @@ -1085,7 +1085,6 @@ else: runner = BasicTestRunner() - result = runner.run(suite) if not result.wasSuccessful(): if len(result.errors) == 1 and not result.failures: diff --git a/lib-python/2.7/test/test_zipfile.py b/lib-python/2.7/test/test_zipfile.py --- a/lib-python/2.7/test/test_zipfile.py +++ b/lib-python/2.7/test/test_zipfile.py @@ -1213,6 +1213,17 @@ self.assertEqual(data1, '1'*FIXEDTEST_SIZE) self.assertEqual(data2, '2'*FIXEDTEST_SIZE) + def test_many_opens(self): + # Verify that read() and open() promptly close the file descriptor, + # and don't rely on the garbage collector to free resources. + with zipfile.ZipFile(TESTFN2, mode="r") as zipf: + for x in range(100): + zipf.read('ones') + with zipf.open('ones') as zopen1: + pass + for x in range(10): + self.assertLess(open('/dev/null').fileno(), 100) + def tearDown(self): unlink(TESTFN2) diff --git a/lib-python/2.7/zipfile.py b/lib-python/2.7/zipfile.py --- a/lib-python/2.7/zipfile.py +++ b/lib-python/2.7/zipfile.py @@ -475,9 +475,11 @@ # Search for universal newlines or line chunks. PATTERN = re.compile(r'^(?P[^\r\n]+)|(?P\n|\r\n?)') - def __init__(self, fileobj, mode, zipinfo, decrypter=None): + def __init__(self, fileobj, mode, zipinfo, decrypter=None, + close_fileobj=False): self._fileobj = fileobj self._decrypter = decrypter + self._close_fileobj = close_fileobj self._compress_type = zipinfo.compress_type self._compress_size = zipinfo.compress_size @@ -649,6 +651,12 @@ self._offset += len(data) return data + def close(self): + try: + if self._close_fileobj: + self._fileobj.close() + finally: + super(ZipExtFile, self).close() class ZipFile: @@ -866,7 +874,8 @@ def read(self, name, pwd=None): """Return file bytes (as a string) for name.""" - return self.open(name, "r", pwd).read() + with self.open(name, "r", pwd) as fp: + return fp.read() def open(self, name, mode="r", pwd=None): """Return file-like object for 'name'.""" @@ -889,8 +898,12 @@ zinfo = name else: # Get info object for name - zinfo = self.getinfo(name) - + try: + zinfo = self.getinfo(name) + except KeyError: + if not self._filePassed: + zef_file.close() + raise zef_file.seek(zinfo.header_offset, 0) # Skip the file header: @@ -904,6 +917,8 @@ zef_file.read(fheader[_FH_EXTRA_FIELD_LENGTH]) if fname != zinfo.orig_filename: + if not self._filePassed: + zef_file.close() raise BadZipfile, \ 'File name in directory "%s" and header "%s" differ.' % ( zinfo.orig_filename, fname) @@ -915,6 +930,8 @@ if not pwd: pwd = self.pwd if not pwd: + if not self._filePassed: + zef_file.close() raise RuntimeError, "File %s is encrypted, " \ "password required for extraction" % name @@ -933,9 +950,12 @@ # compare against the CRC otherwise check_byte = (zinfo.CRC >> 24) & 0xff if ord(h[11]) != check_byte: + if not self._filePassed: + zef_file.close() raise RuntimeError("Bad password for file", name) - return ZipExtFile(zef_file, mode, zinfo, zd) + return ZipExtFile(zef_file, mode, zinfo, zd, + close_fileobj=not self._filePassed) def extract(self, member, path=None, pwd=None): """Extract a member from the archive to the current working directory, @@ -993,7 +1013,7 @@ return targetpath source = self.open(member, pwd=pwd) - target = file(targetpath, "wb") + target = open(targetpath, "wb") shutil.copyfileobj(source, target) source.close() target.close() diff --git a/lib-python/conftest.py b/lib-python/conftest.py --- a/lib-python/conftest.py +++ b/lib-python/conftest.py @@ -61,7 +61,7 @@ usemodules = '', skip=None): self.basename = basename - self._usemodules = usemodules.split() + ['signal'] + self._usemodules = usemodules.split() + ['signal', 'rctime', 'itertools', '_socket'] self._compiler = compiler self.core = core self.skip = skip @@ -93,63 +93,57 @@ m.test_main() ''' % locals()) -if sys.platform == 'win32': - skip_win32 = "Not supported on Windows" - only_win32 = False -else: - skip_win32 = False - only_win32 = "Only on Windows" - testmap = [ RegrTest('test___all__.py', core=True), RegrTest('test___future__.py', core=True), - RegrTest('test__locale.py', skip=skip_win32), + RegrTest('test__locale.py', usemodules='_locale'), RegrTest('test_abc.py'), RegrTest('test_abstract_numbers.py'), - RegrTest('test_aepack.py', skip=True), + RegrTest('test_aepack.py'), RegrTest('test_aifc.py'), - RegrTest('test_argparse.py'), - RegrTest('test_al.py', skip=True), - RegrTest('test_ast.py', core=True), - RegrTest('test_anydbm.py'), - RegrTest('test_applesingle.py', skip=True), - RegrTest('test_array.py', core=True, usemodules='struct array'), + RegrTest('test_al.py'), + RegrTest('test_anydbm.py', usemodules='struct'), + RegrTest('test_applesingle.py'), + RegrTest('test_argparse.py', usemodules='binascii'), + RegrTest('test_array.py', core=True, usemodules='struct array binascii'), RegrTest('test_ascii_formatd.py'), - RegrTest('test_asynchat.py', usemodules='thread'), - RegrTest('test_asyncore.py'), + RegrTest('test_ast.py', core=True, usemodules='struct'), + RegrTest('test_asynchat.py', usemodules='select fcntl'), + RegrTest('test_asyncore.py', usemodules='select fcntl'), RegrTest('test_atexit.py', core=True), - RegrTest('test_audioop.py', skip=True), + RegrTest('test_audioop.py', skip="unsupported extension module"), RegrTest('test_augassign.py', core=True), - RegrTest('test_base64.py'), + RegrTest('test_base64.py', usemodules='struct'), RegrTest('test_bastion.py'), + RegrTest('test_bigaddrspace.py'), + RegrTest('test_bigmem.py'), RegrTest('test_binascii.py', usemodules='binascii'), - RegrTest('test_binhex.py'), - RegrTest('test_binop.py', core=True), RegrTest('test_bisect.py', core=True, usemodules='_bisect'), RegrTest('test_bool.py', core=True), - RegrTest('test_bsddb.py', skip="unsupported extension module"), - RegrTest('test_bsddb185.py', skip="unsupported extension module"), - RegrTest('test_bsddb3.py', skip="unsupported extension module"), + RegrTest('test_bsddb.py'), + RegrTest('test_bsddb185.py'), + RegrTest('test_bsddb3.py'), RegrTest('test_buffer.py'), RegrTest('test_bufio.py', core=True), - RegrTest('test_builtin.py', core=True), - RegrTest('test_bytes.py'), + RegrTest('test_builtin.py', core=True, usemodules='binascii'), + RegrTest('test_bytes.py', usemodules='struct binascii'), RegrTest('test_bz2.py', usemodules='bz2'), RegrTest('test_calendar.py'), RegrTest('test_call.py', core=True), - RegrTest('test_capi.py', skip="not applicable"), - RegrTest('test_cd.py', skip=True), + RegrTest('test_capi.py'), + RegrTest('test_cd.py'), RegrTest('test_cfgparser.py'), - RegrTest('test_cgi.py'), RegrTest('test_charmapcodec.py', core=True), - RegrTest('test_cl.py', skip=True), + RegrTest('test_cl.py'), RegrTest('test_class.py', core=True), RegrTest('test_cmath.py', core=True), RegrTest('test_cmd.py'), + RegrTest('test_cmd_line.py'), RegrTest('test_cmd_line_script.py'), + RegrTest('test_code.py', core=True), RegrTest('test_codeccallbacks.py', core=True), RegrTest('test_codecencodings_cn.py', usemodules='_multibytecodec'), RegrTest('test_codecencodings_hk.py', usemodules='_multibytecodec'), @@ -157,7 +151,6 @@ RegrTest('test_codecencodings_jp.py', usemodules='_multibytecodec'), RegrTest('test_codecencodings_kr.py', usemodules='_multibytecodec'), RegrTest('test_codecencodings_tw.py', usemodules='_multibytecodec'), - RegrTest('test_codecmaps_cn.py', usemodules='_multibytecodec'), RegrTest('test_codecmaps_hk.py', usemodules='_multibytecodec'), RegrTest('test_codecmaps_jp.py', usemodules='_multibytecodec'), @@ -165,6 +158,7 @@ RegrTest('test_codecmaps_tw.py', usemodules='_multibytecodec'), RegrTest('test_codecs.py', core=True, usemodules='_multibytecodec'), RegrTest('test_codeop.py', core=True), + RegrTest('test_coding.py', core=True), RegrTest('test_coercion.py', core=True), RegrTest('test_collections.py'), RegrTest('test_colorsys.py'), @@ -174,22 +168,24 @@ RegrTest('test_compileall.py'), RegrTest('test_compiler.py', core=False, skip="slowly deprecating compiler"), RegrTest('test_complex.py', core=True), - + RegrTest('test_complex_args.py'), RegrTest('test_contains.py', core=True), + RegrTest('test_contextlib.py', usemodules="thread"), RegrTest('test_cookie.py'), RegrTest('test_cookielib.py'), RegrTest('test_copy.py', core=True), RegrTest('test_copy_reg.py', core=True), RegrTest('test_cpickle.py', core=True), - RegrTest('test_cprofile.py'), - RegrTest('test_crypt.py', usemodules='crypt', skip=skip_win32), + RegrTest('test_cprofile.py'), + RegrTest('test_crypt.py', usemodules='crypt'), RegrTest('test_csv.py', usemodules='_csv'), - - RegrTest('test_curses.py', skip="unsupported extension module"), + RegrTest('test_ctypes.py', usemodules="_rawffi thread"), + RegrTest('test_curses.py'), RegrTest('test_datetime.py'), RegrTest('test_dbm.py'), RegrTest('test_decimal.py'), RegrTest('test_decorators.py', core=True), + RegrTest('test_defaultdict.py', usemodules='_collections'), RegrTest('test_deque.py', core=True, usemodules='_collections'), RegrTest('test_descr.py', core=True, usemodules='_weakref'), RegrTest('test_descrtut.py', core=True), @@ -200,7 +196,7 @@ RegrTest('test_dircache.py', core=True), RegrTest('test_dis.py'), RegrTest('test_distutils.py', skip=True), - RegrTest('test_dl.py', skip=True), + RegrTest('test_dl.py'), RegrTest('test_doctest.py', usemodules="thread"), RegrTest('test_doctest2.py'), RegrTest('test_docxmlrpc.py'), @@ -208,20 +204,22 @@ RegrTest('test_dummy_thread.py', core=True), RegrTest('test_dummy_threading.py', core=True), RegrTest('test_email.py'), - RegrTest('test_email_codecs.py'), + RegrTest('test_email_renamed.py'), RegrTest('test_enumerate.py', core=True), RegrTest('test_eof.py', core=True), RegrTest('test_epoll.py'), RegrTest('test_errno.py', usemodules="errno"), + RegrTest('test_exception_variations.py'), RegrTest('test_exceptions.py', core=True), RegrTest('test_extcall.py', core=True), - RegrTest('test_fcntl.py', usemodules='fcntl', skip=skip_win32), + RegrTest('test_fcntl.py', usemodules='fcntl'), RegrTest('test_file.py', usemodules="posix", core=True), RegrTest('test_file2k.py', usemodules="posix", core=True), RegrTest('test_filecmp.py', core=True), RegrTest('test_fileinput.py', core=True), RegrTest('test_fileio.py'), + RegrTest('test_float.py', core=True), RegrTest('test_fnmatch.py', core=True), RegrTest('test_fork1.py', usemodules="thread"), RegrTest('test_format.py', core=True), @@ -230,6 +228,7 @@ RegrTest('test_frozen.py', skip="unsupported extension module"), RegrTest('test_ftplib.py'), RegrTest('test_funcattrs.py', core=True), + RegrTest('test_functools.py'), RegrTest('test_future.py', core=True), RegrTest('test_future1.py', core=True), RegrTest('test_future2.py', core=True), @@ -239,41 +238,37 @@ RegrTest('test_future_builtins.py'), RegrTest('test_gc.py', usemodules='_weakref', skip="implementation detail"), RegrTest('test_gdb.py', skip="not applicable"), - RegrTest('test_gdbm.py', skip="unsupported extension module"), + RegrTest('test_gdbm.py'), RegrTest('test_generators.py', core=True, usemodules='thread _weakref'), RegrTest('test_genericpath.py'), RegrTest('test_genexps.py', core=True, usemodules='_weakref'), - RegrTest('test_getargs.py', skip="unsupported extension module"), - RegrTest('test_getargs2.py', skip="unsupported extension module"), - + RegrTest('test_getargs.py'), + RegrTest('test_getargs2.py', usemodules='binascii', skip=True), RegrTest('test_getopt.py', core=True), RegrTest('test_gettext.py'), - - RegrTest('test_gl.py', skip=True), + RegrTest('test_gl.py'), RegrTest('test_glob.py', core=True), RegrTest('test_global.py', core=True), RegrTest('test_grammar.py', core=True), - RegrTest('test_grp.py', skip=skip_win32), - - RegrTest('test_gzip.py'), + RegrTest('test_grp.py'), + RegrTest('test_gzip.py', usemodules='zlib'), RegrTest('test_hash.py', core=True), RegrTest('test_hashlib.py', core=True), - RegrTest('test_heapq.py', core=True), RegrTest('test_hmac.py'), RegrTest('test_hotshot.py', skip="unsupported extension module"), - RegrTest('test_htmllib.py'), RegrTest('test_htmlparser.py'), RegrTest('test_httplib.py'), RegrTest('test_httpservers.py'), - RegrTest('test_imageop.py', skip="unsupported extension module"), + RegrTest('test_imageop.py'), RegrTest('test_imaplib.py'), - RegrTest('test_imgfile.py', skip="unsupported extension module"), + RegrTest('test_imgfile.py'), RegrTest('test_imp.py', core=True, usemodules='thread'), RegrTest('test_import.py', core=True), RegrTest('test_importhooks.py', core=True), RegrTest('test_importlib.py'), + RegrTest('test_index.py'), RegrTest('test_inspect.py'), RegrTest('test_int.py', core=True), RegrTest('test_int_literal.py', core=True), @@ -296,7 +291,7 @@ RegrTest('test_long_future.py', core=True), RegrTest('test_longexp.py', core=True), RegrTest('test_macos.py'), - RegrTest('test_macostools.py', skip=True), + RegrTest('test_macostools.py'), RegrTest('test_macpath.py'), RegrTest('test_mailbox.py'), RegrTest('test_marshal.py', core=True), @@ -307,30 +302,29 @@ RegrTest('test_mhlib.py'), RegrTest('test_mimetools.py'), RegrTest('test_mimetypes.py'), - RegrTest('test_MimeWriter.py', core=False), + RegrTest('test_MimeWriter.py', core=False, usemodules='binascii'), RegrTest('test_minidom.py'), RegrTest('test_mmap.py', usemodules="mmap"), RegrTest('test_module.py', core=True), RegrTest('test_modulefinder.py'), - RegrTest('test_msilib.py', skip=only_win32), + RegrTest('test_msilib.py'), RegrTest('test_multibytecodec.py', usemodules='_multibytecodec'), - RegrTest('test_multibytecodec_support.py', skip="not a test"), RegrTest('test_multifile.py'), - RegrTest('test_multiprocessing.py', skip="FIXME leaves subprocesses"), + RegrTest('test_multiprocessing.py'), RegrTest('test_mutants.py', core="possibly"), RegrTest('test_mutex.py'), RegrTest('test_netrc.py'), RegrTest('test_new.py', core=True), - RegrTest('test_nis.py', skip="unsupported extension module"), + RegrTest('test_nis.py'), RegrTest('test_normalization.py'), RegrTest('test_ntpath.py'), + RegrTest('test_old_mailbox.py'), RegrTest('test_opcodes.py', core=True), RegrTest('test_openpty.py'), RegrTest('test_operator.py', core=True), RegrTest('test_optparse.py'), - RegrTest('test_os.py', core=True), - RegrTest('test_ossaudiodev.py', skip="unsupported extension module"), + RegrTest('test_ossaudiodev.py'), RegrTest('test_parser.py', skip="slowly deprecating compiler"), RegrTest('test_pdb.py'), RegrTest('test_peepholer.py'), @@ -338,14 +332,16 @@ RegrTest('test_pep263.py'), RegrTest('test_pep277.py'), RegrTest('test_pep292.py'), + RegrTest('test_pep352.py'), RegrTest('test_pickle.py', core=True), RegrTest('test_pickletools.py', core=False), RegrTest('test_pipes.py'), RegrTest('test_pkg.py', core=True), RegrTest('test_pkgimport.py', core=True), RegrTest('test_pkgutil.py'), - RegrTest('test_plistlib.py', skip="unsupported module"), - RegrTest('test_poll.py', skip=skip_win32), + RegrTest('test_platform.py'), + RegrTest('test_plistlib.py'), + RegrTest('test_poll.py'), RegrTest('test_popen.py'), RegrTest('test_popen2.py'), RegrTest('test_poplib.py'), @@ -357,8 +353,8 @@ RegrTest('test_profile.py'), RegrTest('test_property.py', core=True), RegrTest('test_pstats.py'), - RegrTest('test_pty.py', skip="unsupported extension module"), - RegrTest('test_pwd.py', usemodules="pwd", skip=skip_win32), + RegrTest('test_pty.py', usemodules='fcntl termios select'), + RegrTest('test_pwd.py', usemodules="pwd"), RegrTest('test_py3kwarn.py'), RegrTest('test_py_compile.py'), RegrTest('test_pyclbr.py'), @@ -370,15 +366,15 @@ RegrTest('test_re.py', core=True), RegrTest('test_readline.py'), RegrTest('test_repr.py', core=True), - RegrTest('test_resource.py', skip=skip_win32), + RegrTest('test_resource.py'), RegrTest('test_rfc822.py'), RegrTest('test_richcmp.py', core=True), RegrTest('test_rlcompleter.py'), - RegrTest('test_robotparser.py'), + RegrTest('test_runpy.py'), RegrTest('test_sax.py'), RegrTest('test_scope.py', core=True), - RegrTest('test_scriptpackages.py', skip="unsupported extension module"), + RegrTest('test_scriptpackages.py'), RegrTest('test_select.py'), RegrTest('test_set.py', core=True), RegrTest('test_sets.py'), @@ -389,64 +385,59 @@ RegrTest('test_shlex.py'), RegrTest('test_shutil.py'), RegrTest('test_signal.py'), - RegrTest('test_SimpleHTTPServer.py'), + RegrTest('test_SimpleHTTPServer.py', usemodules='binascii'), RegrTest('test_site.py', core=False), RegrTest('test_slice.py', core=True), RegrTest('test_smtplib.py'), RegrTest('test_smtpnet.py'), RegrTest('test_socket.py', usemodules='thread _weakref'), - RegrTest('test_socketserver.py', usemodules='thread'), - RegrTest('test_softspace.py', core=True), RegrTest('test_sort.py', core=True), + RegrTest('test_sqlite.py', usemodules="thread _rawffi zlib"), RegrTest('test_ssl.py', usemodules='_ssl _socket select'), + RegrTest('test_startfile.py'), RegrTest('test_str.py', core=True), - RegrTest('test_strftime.py'), RegrTest('test_string.py', core=True), - RegrTest('test_StringIO.py', core=True, usemodules='cStringIO'), + RegrTest('test_StringIO.py', core=True, usemodules='cStringIO array'), RegrTest('test_stringprep.py'), RegrTest('test_strop.py', skip="deprecated"), - RegrTest('test_strptime.py'), RegrTest('test_strtod.py'), RegrTest('test_struct.py', usemodules='struct'), RegrTest('test_structmembers.py', skip="CPython specific"), RegrTest('test_structseq.py'), RegrTest('test_subprocess.py', usemodules='signal'), - RegrTest('test_sunaudiodev.py', skip=True), + RegrTest('test_sunaudiodev.py'), RegrTest('test_sundry.py'), RegrTest('test_symtable.py', skip="implementation detail"), RegrTest('test_syntax.py', core=True), RegrTest('test_sys.py', core=True, usemodules='struct'), + RegrTest('test_sys_setprofile.py', core=True), RegrTest('test_sys_settrace.py', core=True), - RegrTest('test_sys_setprofile.py', core=True), RegrTest('test_sysconfig.py'), - RegrTest('test_tcl.py', skip="unsupported extension module"), RegrTest('test_tarfile.py'), + RegrTest('test_tcl.py'), RegrTest('test_telnetlib.py'), RegrTest('test_tempfile.py'), - RegrTest('test_textwrap.py'), RegrTest('test_thread.py', usemodules="thread", core=True), RegrTest('test_threaded_import.py', usemodules="thread", core=True), RegrTest('test_threadedtempfile.py', usemodules="thread", core=False), - RegrTest('test_threading.py', usemodules="thread", core=True), RegrTest('test_threading_local.py', usemodules="thread", core=True), RegrTest('test_threadsignals.py', usemodules="thread"), - RegrTest('test_time.py', core=True), RegrTest('test_timeout.py'), RegrTest('test_tk.py'), - RegrTest('test_ttk_guionly.py'), - RegrTest('test_ttk_textonly.py'), RegrTest('test_tokenize.py'), RegrTest('test_trace.py'), RegrTest('test_traceback.py', core=True), RegrTest('test_transformer.py', core=True), + RegrTest('test_ttk_guionly.py'), + RegrTest('test_ttk_textonly.py'), RegrTest('test_tuple.py', core=True), RegrTest('test_typechecks.py'), RegrTest('test_types.py', core=True), @@ -462,6 +453,7 @@ RegrTest('test_unpack.py', core=True), RegrTest('test_urllib.py'), RegrTest('test_urllib2.py'), + RegrTest('test_urllib2_localnet.py', usemodules="thread"), RegrTest('test_urllib2net.py'), RegrTest('test_urllibnet.py'), RegrTest('test_urlparse.py'), @@ -469,61 +461,38 @@ RegrTest('test_userlist.py', core=True), RegrTest('test_userstring.py', core=True), RegrTest('test_uu.py'), - - RegrTest('test_warnings.py', core=True), - RegrTest('test_wave.py', skip="unsupported extension module"), - RegrTest('test_weakref.py', core=True, usemodules='_weakref'), - RegrTest('test_weakset.py'), - - RegrTest('test_whichdb.py'), - RegrTest('test_winreg.py', skip=only_win32), - RegrTest('test_winsound.py', skip="unsupported extension module"), - RegrTest('test_xmllib.py'), - RegrTest('test_xmlrpc.py'), - - RegrTest('test_xpickle.py'), - RegrTest('test_xrange.py', core=True), - RegrTest('test_zipfile.py'), - RegrTest('test_zipimport.py', usemodules='zlib zipimport'), - RegrTest('test_zipimport_support.py', usemodules='zlib zipimport'), - RegrTest('test_zlib.py', usemodules='zlib'), - - RegrTest('test_bigaddrspace.py'), - RegrTest('test_bigmem.py'), - RegrTest('test_cmd_line.py'), - RegrTest('test_code.py'), - RegrTest('test_coding.py'), - RegrTest('test_complex_args.py'), - RegrTest('test_contextlib.py', usemodules="thread"), - RegrTest('test_ctypes.py', usemodules="_rawffi thread"), - RegrTest('test_defaultdict.py', usemodules='_collections'), - RegrTest('test_email_renamed.py'), - RegrTest('test_exception_variations.py'), - RegrTest('test_float.py'), - RegrTest('test_functools.py'), - RegrTest('test_index.py'), - RegrTest('test_old_mailbox.py'), - RegrTest('test_pep352.py'), - RegrTest('test_platform.py'), - RegrTest('test_runpy.py'), - RegrTest('test_sqlite.py', usemodules="thread _rawffi zlib"), - RegrTest('test_startfile.py', skip="bogus test"), - RegrTest('test_structmembers.py', skip="depends on _testcapi"), - RegrTest('test_urllib2_localnet.py', usemodules="thread"), RegrTest('test_uuid.py'), RegrTest('test_wait3.py', usemodules="thread"), RegrTest('test_wait4.py', usemodules="thread"), + RegrTest('test_warnings.py', core=True), + RegrTest('test_wave.py'), + RegrTest('test_weakref.py', core=True, usemodules='_weakref'), + RegrTest('test_weakset.py'), + RegrTest('test_whichdb.py'), + RegrTest('test_winreg.py'), + RegrTest('test_winsound.py'), RegrTest('test_with.py'), RegrTest('test_wsgiref.py'), RegrTest('test_xdrlib.py'), RegrTest('test_xml_etree.py'), RegrTest('test_xml_etree_c.py'), + RegrTest('test_xmllib.py'), + RegrTest('test_xmlrpc.py'), + RegrTest('test_xpickle.py'), + RegrTest('test_xrange.py', core=True), + RegrTest('test_zipfile.py'), RegrTest('test_zipfile64.py'), + RegrTest('test_zipimport.py', usemodules='zlib zipimport'), + RegrTest('test_zipimport_support.py', usemodules='zlib zipimport'), + RegrTest('test_zlib.py', usemodules='zlib'), ] def check_testmap_complete(): listed_names = dict.fromkeys([regrtest.basename for regrtest in testmap]) - listed_names['test_support.py'] = True # ignore this + assert len(listed_names) == len(testmap) + # names to ignore + listed_names['test_support.py'] = True + listed_names['test_multibytecodec_support.py'] = True missing = [] for path in testdir.listdir(fil='test_*.py'): name = path.basename @@ -578,7 +547,7 @@ def getinvocation(self, regrtest): fspath = regrtest.getfspath() python = sys.executable - pypy_script = pypydir.join('bin', 'py.py') + pypy_script = pypydir.join('bin', 'pyinteractive.py') alarm_script = pypydir.join('tool', 'alarm.py') if sys.platform == 'win32': watchdog_name = 'watchdog_nt.py' diff --git a/lib_pypy/_ctypes_test.py b/lib_pypy/_ctypes_test.py --- a/lib_pypy/_ctypes_test.py +++ b/lib_pypy/_ctypes_test.py @@ -1,6 +1,5 @@ import os, sys import tempfile -import gc def compile_shared(): """Compile '_ctypes_test.c' into an extension module, and import it @@ -19,7 +18,7 @@ if sys.platform == 'win32': ccflags = ['-D_CRT_SECURE_NO_WARNINGS'] else: - ccflags = ['-fPIC'] + ccflags = ['-fPIC', '-Wimplicit-function-declaration'] res = compiler.compile([os.path.join(thisdir, '_ctypes_test.c')], include_dirs=[include_dir], extra_preargs=ccflags) @@ -35,10 +34,10 @@ library = os.path.join(thisdir, '..', 'include', 'python27') if not os.path.exists(library + '.lib'): # For a local translation - library = os.path.join(thisdir, '..', 'pypy', 'translator', - 'goal', 'libpypy-c') + library = os.path.join(thisdir, '..', 'pypy', 'goal', 'libpypy-c') libraries = [library, 'oleaut32'] - extra_ldargs = ['/MANIFEST'] # needed for VC10 + extra_ldargs = ['/MANIFEST', # needed for VC10 + '/EXPORT:init_ctypes_test'] else: libraries = [] extra_ldargs = [] diff --git a/lib_pypy/_testcapi.py b/lib_pypy/_testcapi.py --- a/lib_pypy/_testcapi.py +++ b/lib_pypy/_testcapi.py @@ -34,8 +34,7 @@ library = os.path.join(thisdir, '..', 'include', 'python27') if not os.path.exists(library + '.lib'): # For a local translation - library = os.path.join(thisdir, '..', 'pypy', 'translator', - 'goal', 'libpypy-c') + library = os.path.join(thisdir, '..', 'pypy', 'goal', 'libpypy-c') libraries = [library, 'oleaut32'] extra_ldargs = ['/MANIFEST', # needed for VC10 '/EXPORT:init_testcapi'] diff --git a/pypy/bin/checkmodule.py b/pypy/bin/checkmodule.py --- a/pypy/bin/checkmodule.py +++ b/pypy/bin/checkmodule.py @@ -8,6 +8,8 @@ """ import sys, os +sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', '..')) + from pypy.objspace.fake.checkmodule import checkmodule def main(argv): diff --git a/pypy/doc/cpython_differences.rst b/pypy/doc/cpython_differences.rst --- a/pypy/doc/cpython_differences.rst +++ b/pypy/doc/cpython_differences.rst @@ -318,10 +318,5 @@ type and vice versa. For builtin types, a dictionary will be returned that cannot be changed (but still looks and behaves like a normal dictionary). -* the ``__len__`` or ``__length_hint__`` special methods are sometimes - called by CPython to get a length estimate to preallocate internal arrays. - So far, PyPy never calls ``__len__`` for this purpose, and never calls - ``__length_hint__`` at all. - .. include:: _ref.txt diff --git a/pypy/doc/discussion/improve-rpython.rst b/pypy/doc/discussion/improve-rpython.rst --- a/pypy/doc/discussion/improve-rpython.rst +++ b/pypy/doc/discussion/improve-rpython.rst @@ -15,7 +15,7 @@ from pypy.interpreter.typedef import interp_attrproperty, interp_attrproperty_w from pypy.interpreter.gateway import interp2app from pypy.interpreter.error import OperationError - from pypy.rpython.lltypesystem import rffi, lltype + from rpython.rtyper.lltypesystem import rffi, lltype - A more direct declarative way to write Typedef:: diff --git a/pypy/doc/faq.rst b/pypy/doc/faq.rst --- a/pypy/doc/faq.rst +++ b/pypy/doc/faq.rst @@ -300,12 +300,26 @@ Do I have to rewrite my programs in RPython? -------------------------------------------- -No. And you shouldn't try. PyPy always runs your code in its own interpreter, which is a -full and compliant Python 2.7 interpreter. RPython is only the -language in which parts of PyPy itself are written and extension -modules for it. Not only is it not necessary for you to rewrite your -code in RPython, it probably won't give you any speed improvements if you -try. +No. And you shouldn't try. First and foremost, RPython is a language +that is designed to write interpreters in. It is a restricted subset of +Python. If you program is not an interpreter but tries to do "real +things", like use *any* part of the standard Python library or *any* +3rd-party library, then it is not RPython to start with. You should +only look at RPython if you try to `write your own interpreter`__. + +.. __: `how do I compile my own interpreters`_ + +If your goal is to speed up Python code, then look at the regular PyPy, +which is a full and compliant Python 2.7 interpreter (which happens to +be written in RPython). Not only is it not necessary for you to rewrite +your code in RPython, it might not give you any speed improvements even +if you manage to. + +Yes, it is possible with enough effort to compile small self-contained +pieces of RPython code doing a few performance-sensitive things. But +this case is not interesting for us. If you needed to rewrite the code +in RPython, you could as well have rewritten it in C for example. The +latter is a much more supported, much more documented language `:-)` --------------------------------------------------- Which backends are there for the RPython toolchain? diff --git a/pypy/doc/rffi.rst b/pypy/doc/rffi.rst --- a/pypy/doc/rffi.rst +++ b/pypy/doc/rffi.rst @@ -17,7 +17,7 @@ lltype.Signed or lltype.Array) and memory management must be done by hand. To declare a function, we write:: - from pypy.rpython.lltypesystem import rffi + from rpython.rtyper.lltypesystem import rffi external_function = rffi.llexternal(name, args, result) @@ -31,7 +31,7 @@ libraries and sources by passing in the optional ``compilation_info`` parameter:: - from pypy.rpython.lltypesystem import rffi + from rpython.rtyper.lltypesystem import rffi from rpython.translator.tool.cbuild import ExternalCompilationInfo info = ExternalCompilationInfo(includes=[], libraries=[]) diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -1482,9 +1482,10 @@ ) raise w_fd = self.call_function(w_fileno) - if not self.isinstance_w(w_fd, self.w_int): + if (not self.isinstance_w(w_fd, self.w_int) and + not self.isinstance_w(w_fd, self.w_long)): raise OperationError(self.w_TypeError, - self.wrap("fileno() must return an integer") + self.wrap("fileno() returned a non-integer") ) fd = self.int_w(w_fd) if fd < 0: diff --git a/pypy/interpreter/executioncontext.py b/pypy/interpreter/executioncontext.py --- a/pypy/interpreter/executioncontext.py +++ b/pypy/interpreter/executioncontext.py @@ -40,6 +40,7 @@ def gettopframe(self): return self.topframeref() + @jit.unroll_safe def gettopframe_nohidden(self): frame = self.topframeref() while frame and frame.hide(): diff --git a/pypy/interpreter/miscutils.py b/pypy/interpreter/miscutils.py --- a/pypy/interpreter/miscutils.py +++ b/pypy/interpreter/miscutils.py @@ -17,9 +17,8 @@ def setvalue(self, value): self._value = value - def getmainthreadvalue(self): - return self._value + def ismainthread(self): + return True def getallvalues(self): return {0: self._value} - diff --git a/pypy/module/__pypy__/interp_identitydict.py b/pypy/module/__pypy__/interp_identitydict.py --- a/pypy/module/__pypy__/interp_identitydict.py +++ b/pypy/module/__pypy__/interp_identitydict.py @@ -33,6 +33,11 @@ except KeyError: raise OperationError(space.w_KeyError, w_key) + def descr_iter(self, space): + raise OperationError(space.w_TypeError, + space.wrap("'identity_dict' object does not support iteration; " + "iterate over x.keys()")) + def get(self, space, w_key, w_default=None): if w_default is None: w_default = space.w_None @@ -50,8 +55,11 @@ W_IdentityDict.typedef = TypeDef("identity_dict", __doc__="""\ A dictionary that considers keys by object identity. -Distinct objects that compare equal will have separate entries. -All objects can be used as keys, even non-hashable ones. +Distinct objects will have separate entries even if they +compare equal. All objects can be used as keys, even +non-hashable ones --- but avoid using immutable objects +like integers: two int objects 42 may or may not be +internally the same object. """, __new__ = interp2app(W_IdentityDict.descr_new.im_func), __len__ = interp2app(W_IdentityDict.descr_len), @@ -59,6 +67,7 @@ __setitem__ = interp2app(W_IdentityDict.descr_setitem), __getitem__ = interp2app(W_IdentityDict.descr_getitem), __delitem__ = interp2app(W_IdentityDict.descr_delitem), + __iter__ = interp2app(W_IdentityDict.descr_iter), get = interp2app(W_IdentityDict.get), keys = interp2app(W_IdentityDict.keys), values = interp2app(W_IdentityDict.values), diff --git a/pypy/module/__pypy__/test/test_identitydict.py b/pypy/module/__pypy__/test/test_identitydict.py --- a/pypy/module/__pypy__/test/test_identitydict.py +++ b/pypy/module/__pypy__/test/test_identitydict.py @@ -56,3 +56,10 @@ assert None in d assert [] not in d + + def test_iterate(self): + from __pypy__ import identity_dict + d = identity_dict() + d[None] = 1 + raises(TypeError, iter, d) + raises(TypeError, list, d) diff --git a/pypy/module/_bisect/interp_bisect.py b/pypy/module/_bisect/interp_bisect.py --- a/pypy/module/_bisect/interp_bisect.py +++ b/pypy/module/_bisect/interp_bisect.py @@ -1,5 +1,6 @@ from pypy.interpreter.error import OperationError from pypy.interpreter.gateway import unwrap_spec +from rpython.rlib.rarithmetic import intmask, r_uint @unwrap_spec(lo=int, hi=int) @@ -18,7 +19,7 @@ if hi == -1: hi = space.len_w(w_a) while lo < hi: - mid = (lo + hi) >> 1 + mid = intmask((r_uint(lo) + r_uint(hi)) >> 1) w_litem = space.getitem(w_a, space.wrap(mid)) if space.is_true(space.lt(w_litem, w_x)): lo = mid + 1 @@ -43,7 +44,7 @@ if hi == -1: hi = space.len_w(w_a) while lo < hi: - mid = (lo + hi) >> 1 + mid = intmask((r_uint(lo) + r_uint(hi)) >> 1) w_litem = space.getitem(w_a, space.wrap(mid)) if space.is_true(space.lt(w_x, w_litem)): hi = mid diff --git a/pypy/module/_bisect/test/test_bisect.py b/pypy/module/_bisect/test/test_bisect.py --- a/pypy/module/_bisect/test/test_bisect.py +++ b/pypy/module/_bisect/test/test_bisect.py @@ -89,3 +89,12 @@ insort_right(a, 6.0) assert a == [0, 5, 6, 6, 6, 6.0, 7] assert map(type, a) == [int, int, int, int, int, float, int] + + def test_bisect_overflow(self): + from _bisect import bisect_left, bisect_right + import sys + + size = sys.maxsize + data = xrange(size - 1) + assert bisect_left(data, size - 3) == size - 3 + assert bisect_right(data, size - 3) == size - 2 diff --git a/pypy/module/_io/interp_fileio.py b/pypy/module/_io/interp_fileio.py --- a/pypy/module/_io/interp_fileio.py +++ b/pypy/module/_io/interp_fileio.py @@ -153,41 +153,49 @@ self.readable, self.writable, append, flags = decode_mode(space, mode) - if fd >= 0: - verify_fd(fd) - try: - os.fstat(fd) - except OSError, e: - if e.errno == errno.EBADF: - raise wrap_oserror(space, e) - # else: pass - self.fd = fd - self.closefd = bool(closefd) - else: - if not closefd: - raise OperationError(space.w_ValueError, space.wrap( - "Cannot use closefd=False with file name")) - self.closefd = True + fd_is_own = False + try: + if fd >= 0: + verify_fd(fd) + try: + os.fstat(fd) + except OSError, e: + if e.errno == errno.EBADF: + raise wrap_oserror(space, e) + # else: pass + self.fd = fd + self.closefd = bool(closefd) + else: + self.closefd = True + if not closefd: + raise OperationError(space.w_ValueError, space.wrap( + "Cannot use closefd=False with file name")) - from pypy.module.posix.interp_posix import ( - dispatch_filename, rposix) - try: - self.fd = dispatch_filename(rposix.open)( - space, w_name, flags, 0666) - except OSError, e: - raise wrap_oserror2(space, e, w_name, - exception_name='w_IOError') + from pypy.module.posix.interp_posix import ( + dispatch_filename, rposix) + try: + self.fd = dispatch_filename(rposix.open)( + space, w_name, flags, 0666) + except OSError, e: + raise wrap_oserror2(space, e, w_name, + exception_name='w_IOError') + finally: + fd_is_own = True self._dircheck(space, w_name) - self.w_name = w_name + self.w_name = w_name - if append: - # For consistent behaviour, we explicitly seek to the end of file - # (otherwise, it might be done only on the first write()). - try: - os.lseek(self.fd, 0, os.SEEK_END) - except OSError, e: - raise wrap_oserror(space, e, exception_name='w_IOError') + if append: + # For consistent behaviour, we explicitly seek to the end of file + # (otherwise, it might be done only on the first write()). + try: + os.lseek(self.fd, 0, os.SEEK_END) + except OSError, e: + raise wrap_oserror(space, e, exception_name='w_IOError') + except: + if not fd_is_own: + self.fd = -1 + raise def _mode(self): if self.readable: @@ -253,7 +261,6 @@ except OSError: return if stat.S_ISDIR(st.st_mode): - self._close(space) raise wrap_oserror2(space, OSError(errno.EISDIR, "fstat"), w_filename, exception_name='w_IOError') diff --git a/pypy/module/_io/test/test_fileio.py b/pypy/module/_io/test/test_fileio.py --- a/pypy/module/_io/test/test_fileio.py +++ b/pypy/module/_io/test/test_fileio.py @@ -41,7 +41,12 @@ def test_open_directory(self): import _io + import os raises(IOError, _io.FileIO, self.tmpdir, "rb") + if os.name != 'nt': + fd = os.open(self.tmpdir, os.O_RDONLY) + raises(IOError, _io.FileIO, fd, "rb") + os.close(fd) def test_readline(self): import _io diff --git a/pypy/module/_multiprocessing/test/test_connection.py b/pypy/module/_multiprocessing/test/test_connection.py --- a/pypy/module/_multiprocessing/test/test_connection.py +++ b/pypy/module/_multiprocessing/test/test_connection.py @@ -68,7 +68,7 @@ assert rhandle.readable class AppTestWinpipeConnection(BaseConnectionTest): - spaceconfig = dict(usemodules=('_multiprocessing', 'thread')) + spaceconfig = dict(usemodules=('_multiprocessing', 'thread', 'signal')) def setup_class(cls): if sys.platform != "win32": diff --git a/pypy/module/_socket/interp_socket.py b/pypy/module/_socket/interp_socket.py --- a/pypy/module/_socket/interp_socket.py +++ b/pypy/module/_socket/interp_socket.py @@ -181,7 +181,8 @@ try: self.close() except SocketError, e: - raise converted_error(space, e) + # cpython doesn't return any errors on close + pass def connect_w(self, space, w_addr): """connect(address) @@ -448,7 +449,7 @@ w_addr = space.w_None return space.newtuple([space.wrap(readlgt), w_addr]) except SocketError, e: - raise converted_error(space, e) + raise converted_error(space, e) @unwrap_spec(cmd=int) def ioctl_w(self, space, cmd, w_option): diff --git a/pypy/module/_socket/test/test_sock_app.py b/pypy/module/_socket/test/test_sock_app.py --- a/pypy/module/_socket/test/test_sock_app.py +++ b/pypy/module/_socket/test/test_sock_app.py @@ -362,13 +362,15 @@ assert isinstance(s.fileno(), int) def test_socket_close(self): - import _socket + import _socket, os s = _socket.socket(_socket.AF_INET, _socket.SOCK_STREAM, 0) fileno = s.fileno() assert s.fileno() >= 0 s.close() assert s.fileno() < 0 s.close() + if os.name != 'nt': + raises(OSError, os.close, fileno) def test_socket_close_error(self): import _socket, os @@ -376,7 +378,7 @@ skip("Windows sockets are not files") s = _socket.socket(_socket.AF_INET, _socket.SOCK_STREAM, 0) os.close(s.fileno()) - raises(_socket.error, s.close) + s.close() def test_socket_connect(self): import _socket, os diff --git a/pypy/module/cpyext/api.py b/pypy/module/cpyext/api.py --- a/pypy/module/cpyext/api.py +++ b/pypy/module/cpyext/api.py @@ -922,8 +922,8 @@ kwds["link_extra"] = ["msvcrt.lib"] elif sys.platform.startswith('linux'): compile_extra.append("-Werror=implicit-function-declaration") + compile_extra.append('-g') export_symbols_eci.append('pypyAPI') - compile_extra.append('-g') else: kwds["includes"] = ['Python.h'] # this is our Python.h diff --git a/pypy/module/cpyext/longobject.py b/pypy/module/cpyext/longobject.py --- a/pypy/module/cpyext/longobject.py +++ b/pypy/module/cpyext/longobject.py @@ -47,7 +47,12 @@ Return a C unsigned long representation of the contents of pylong. If pylong is greater than ULONG_MAX, an OverflowError is raised.""" - return rffi.cast(rffi.ULONG, space.uint_w(w_long)) + try: + return rffi.cast(rffi.ULONG, space.uint_w(w_long)) + except OperationError, e: + if e.match(space, space.w_ValueError): + e.w_type = space.w_OverflowError + raise @cpython_api([PyObject], rffi.ULONG, error=-1) def PyLong_AsUnsignedLongMask(space, w_long): @@ -86,7 +91,12 @@ Return a C unsigned long representation of the contents of pylong. If pylong is greater than ULONG_MAX, an OverflowError is raised.""" - return rffi.cast(rffi.ULONGLONG, space.r_ulonglong_w(w_long)) + try: + return rffi.cast(rffi.ULONGLONG, space.r_ulonglong_w(w_long)) + except OperationError, e: + if e.match(space, space.w_ValueError): + e.w_type = space.w_OverflowError + raise @cpython_api([PyObject], rffi.ULONGLONG, error=-1) def PyLong_AsUnsignedLongLongMask(space, w_long): diff --git a/pypy/module/cpyext/object.py b/pypy/module/cpyext/object.py --- a/pypy/module/cpyext/object.py +++ b/pypy/module/cpyext/object.py @@ -218,6 +218,8 @@ @cpython_api([PyObject], PyObject) def PyObject_Str(space, w_obj): + if w_obj is None: + return space.wrap("") return space.str(w_obj) @cpython_api([PyObject], PyObject) @@ -226,6 +228,8 @@ representation on success, NULL on failure. This is the equivalent of the Python expression repr(o). Called by the repr() built-in function and by reverse quotes.""" + if w_obj is None: + return space.wrap("") return space.repr(w_obj) @cpython_api([PyObject], PyObject) @@ -234,6 +238,8 @@ string representation on success, NULL on failure. This is the equivalent of the Python expression unicode(o). Called by the unicode() built-in function.""" + if w_obj is None: + return space.wrap(u"") return space.call_function(space.w_unicode, w_obj) @cpython_api([PyObject, PyObject], rffi.INT_real, error=-1) diff --git a/pypy/module/cpyext/test/test_longobject.py b/pypy/module/cpyext/test/test_longobject.py --- a/pypy/module/cpyext/test/test_longobject.py +++ b/pypy/module/cpyext/test/test_longobject.py @@ -31,6 +31,8 @@ value = api.PyLong_AsUnsignedLong(w_value) assert value == (sys.maxint - 1) * 2 + self.raises(space, api, OverflowError, api.PyLong_AsUnsignedLong, space.wrap(-1)) + def test_as_ssize_t(self, space, api): w_value = space.newlong(2) value = api.PyLong_AsSsize_t(w_value) @@ -46,11 +48,11 @@ w_l = space.wrap(sys.maxint + 1) assert api.PyLong_Check(w_l) assert api.PyLong_CheckExact(w_l) - + w_i = space.wrap(sys.maxint) assert not api.PyLong_Check(w_i) assert not api.PyLong_CheckExact(w_i) - + L = space.appexec([], """(): class L(long): pass @@ -73,6 +75,8 @@ assert api.PyLong_AsUnsignedLongLongMask( space.wrap(1<<64)) == 0 + self.raises(space, api, OverflowError, api.PyLong_AsUnsignedLongLong, space.wrap(-1)) + def test_as_long_and_overflow(self, space, api): overflow = lltype.malloc(rffi.CArrayPtr(rffi.INT_real).TO, 1, flavor='raw') assert api.PyLong_AsLongAndOverflow( diff --git a/pypy/module/cpyext/test/test_object.py b/pypy/module/cpyext/test/test_object.py --- a/pypy/module/cpyext/test/test_object.py +++ b/pypy/module/cpyext/test/test_object.py @@ -94,27 +94,30 @@ def test_size(self, space, api): assert api.PyObject_Size(space.newlist([space.w_None])) == 1 - + + def test_str(self, space, api): + w_list = space.newlist([space.w_None, space.wrap(42)]) + assert space.str_w(api.PyObject_Str(None)) == "" + assert space.str_w(api.PyObject_Str(w_list)) == "[None, 42]" + assert space.str_w(api.PyObject_Str(space.wrap("a"))) == "a" + def test_repr(self, space, api): w_list = space.newlist([space.w_None, space.wrap(42)]) + assert space.str_w(api.PyObject_Repr(None)) == "" assert space.str_w(api.PyObject_Repr(w_list)) == "[None, 42]" assert space.str_w(api.PyObject_Repr(space.wrap("a"))) == "'a'" - - w_list = space.newlist([space.w_None, space.wrap(42)]) - assert space.str_w(api.PyObject_Str(w_list)) == "[None, 42]" - assert space.str_w(api.PyObject_Str(space.wrap("a"))) == "a" - + def test_RichCompare(self, space, api): def compare(w_o1, w_o2, opid): res = api.PyObject_RichCompareBool(w_o1, w_o2, opid) w_res = api.PyObject_RichCompare(w_o1, w_o2, opid) assert space.is_true(w_res) == res return res - + def test_compare(o1, o2): w_o1 = space.wrap(o1) w_o2 = space.wrap(o2) - + for opid, expected in [ (Py_LT, o1 < o2), (Py_LE, o1 <= o2), (Py_NE, o1 != o2), (Py_EQ, o1 == o2), @@ -190,6 +193,7 @@ api.PyErr_Clear() def test_unicode(self, space, api): + assert space.unwrap(api.PyObject_Unicode(None)) == u"" assert space.unwrap(api.PyObject_Unicode(space.wrap([]))) == u"[]" assert space.unwrap(api.PyObject_Unicode(space.wrap("e"))) == u"e" assert api.PyObject_Unicode(space.wrap("\xe9")) is None diff --git a/pypy/module/crypt/test/test_crypt.py b/pypy/module/crypt/test/test_crypt.py --- a/pypy/module/crypt/test/test_crypt.py +++ b/pypy/module/crypt/test/test_crypt.py @@ -1,6 +1,12 @@ +import os +import py + +if os.name != 'posix': + py.test.skip('crypt module only available on unix') + class AppTestCrypt: spaceconfig = dict(usemodules=['crypt']) - + def test_crypt(self): import crypt res = crypt.crypt("pass", "ab") diff --git a/pypy/module/fcntl/test/test_fcntl.py b/pypy/module/fcntl/test/test_fcntl.py --- a/pypy/module/fcntl/test/test_fcntl.py +++ b/pypy/module/fcntl/test/test_fcntl.py @@ -1,9 +1,9 @@ import os +import py from rpython.tool.udir import udir -if os.name == "nt": - from py.test import skip - skip("fcntl module is not available on Windows") +if os.name != 'posix': + py.test.skip("fcntl module only available on unix") def teardown_module(mod): for i in "abcde": @@ -22,13 +22,23 @@ import sys import struct + class F: + def __init__(self, fn): + self.fn = fn + def fileno(self): + return self.fn + f = open(self.tmp + "b", "w+") fcntl.fcntl(f, 1, 0) fcntl.fcntl(f, 1) + fcntl.fcntl(F(long(f.fileno())), 1) raises(TypeError, fcntl.fcntl, "foo") raises(TypeError, fcntl.fcntl, f, "foo") - raises((IOError, ValueError), fcntl.fcntl, -1, 1, 0) + raises(TypeError, fcntl.fcntl, F("foo"), 1) + raises(ValueError, fcntl.fcntl, -1, 1, 0) + raises(ValueError, fcntl.fcntl, F(-1), 1, 0) + raises(ValueError, fcntl.fcntl, F(long(-1)), 1, 0) assert fcntl.fcntl(f, 1, 0) == 0 assert fcntl.fcntl(f, 2, "foo") == "foo" assert fcntl.fcntl(f, 2, buffer("foo")) == "foo" diff --git a/pypy/module/posix/test/test_posix2.py b/pypy/module/posix/test/test_posix2.py --- a/pypy/module/posix/test/test_posix2.py +++ b/pypy/module/posix/test/test_posix2.py @@ -823,14 +823,19 @@ if hasattr(os, 'chmod'): def test_chmod(self): + import sys os = self.posix os.unlink(self.path) raises(OSError, os.chmod, self.path, 0600) f = open(self.path, "w") f.write("this is a test") f.close() - os.chmod(self.path, 0200) - assert (os.stat(self.path).st_mode & 0777) == 0200 + if sys.platform == 'win32': + os.chmod(self.path, 0400) + assert (os.stat(self.path).st_mode & 0600) == 0400 + else: + os.chmod(self.path, 0200) + assert (os.stat(self.path).st_mode & 0777) == 0200 if hasattr(os, 'fchmod'): def test_fchmod(self): diff --git a/pypy/module/pwd/test/test_pwd.py b/pypy/module/pwd/test/test_pwd.py --- a/pypy/module/pwd/test/test_pwd.py +++ b/pypy/module/pwd/test/test_pwd.py @@ -1,3 +1,9 @@ +import os +import py + +if os.name != 'posix': + py.test.skip('pwd module only available on unix') + class AppTestPwd: spaceconfig = dict(usemodules=['pwd']) diff --git a/pypy/module/signal/interp_signal.py b/pypy/module/signal/interp_signal.py --- a/pypy/module/signal/interp_signal.py +++ b/pypy/module/signal/interp_signal.py @@ -60,7 +60,6 @@ def __init__(self, space): "NOT_RPYTHON" AsyncAction.__init__(self, space) - self.handlers_w = {} self.pending_signal = -1 self.fire_in_main_thread = False if self.space.config.objspace.usemodules.thread: @@ -91,7 +90,7 @@ # If we are in the main thread, report the signal now, # and poll more self.pending_signal = -1 - self._report_signal(n) + report_signal(self.space, n) n = self.pending_signal if n < 0: n = pypysig_poll() else: @@ -110,20 +109,31 @@ pypysig_pushback(cpy_signal.SIGINT) self.fire_in_main_thread = True - def _report_signal(self, n): - try: - w_handler = self.handlers_w[n] - except KeyError: - return # no handler, ignore signal - space = self.space - if not space.is_true(space.callable(w_handler)): - return # w_handler is SIG_IGN or SIG_DFL? - # re-install signal handler, for OSes that clear it - pypysig_reinstall(n) - # invoke the app-level handler - ec = space.getexecutioncontext() - w_frame = space.wrap(ec.gettopframe_nohidden()) - space.call_function(w_handler, space.wrap(n), w_frame) +# ____________________________________________________________ + + +class Handlers: + def __init__(self, space): + self.handlers_w = {} + +def _get_handlers(space): + return space.fromcache(Handlers).handlers_w + + +def report_signal(space, n): + handlers_w = _get_handlers(space) + try: + w_handler = handlers_w[n] + except KeyError: + return # no handler, ignore signal + if not space.is_true(space.callable(w_handler)): + return # w_handler is SIG_IGN or SIG_DFL? + # re-install signal handler, for OSes that clear it + pypysig_reinstall(n) + # invoke the app-level handler + ec = space.getexecutioncontext() + w_frame = space.wrap(ec.gettopframe_nohidden()) + space.call_function(w_handler, space.wrap(n), w_frame) @unwrap_spec(signum=int) @@ -141,9 +151,9 @@ check_signum_exists(space, signum) else: check_signum_in_range(space, signum) - action = space.check_signal_action - if signum in action.handlers_w: - return action.handlers_w[signum] + handlers_w = _get_handlers(space) + if signum in handlers_w: + return handlers_w[signum] return space.wrap(SIG_DFL) @@ -198,16 +208,12 @@ A signal handler function is called with two arguments: the first is the signal number, the second is the interrupted stack frame. """ - ec = space.getexecutioncontext() - main_ec = space.threadlocals.getmainthreadvalue() - - old_handler = getsignal(space, signum) - - if ec is not main_ec: + if not space.threadlocals.ismainthread(): raise OperationError(space.w_ValueError, space.wrap("signal() must be called from the " "main thread")) - action = space.check_signal_action + old_handler = getsignal(space, signum) + if space.eq_w(w_handler, space.wrap(SIG_DFL)): pypysig_default(signum) elif space.eq_w(w_handler, space.wrap(SIG_IGN)): @@ -218,7 +224,8 @@ space.wrap("'handler' must be a callable " "or SIG_DFL or SIG_IGN")) pypysig_setflag(signum) - action.handlers_w[signum] = w_handler + handlers_w = _get_handlers(space) + handlers_w[signum] = w_handler return old_handler @@ -231,13 +238,10 @@ The fd must be non-blocking. """ - if space.config.objspace.usemodules.thread: - main_ec = space.threadlocals.getmainthreadvalue() - ec = space.getexecutioncontext() - if ec is not main_ec: - raise OperationError( - space.w_ValueError, - space.wrap("set_wakeup_fd only works in main thread")) + if not space.threadlocals.ismainthread(): + raise OperationError( + space.w_ValueError, + space.wrap("set_wakeup_fd only works in main thread")) old_fd = pypysig_set_wakeup_fd(fd) return space.wrap(intmask(old_fd)) diff --git a/pypy/module/termios/test/test_termios.py b/pypy/module/termios/test/test_termios.py --- a/pypy/module/termios/test/test_termios.py +++ b/pypy/module/termios/test/test_termios.py @@ -1,9 +1,12 @@ - +import os +import sys import py -import sys from pypy.conftest import pypydir from rpython.tool.udir import udir +if os.name != 'posix': + py.test.skip('termios module only available on unix') + class TestTermios(object): def setup_class(cls): try: diff --git a/pypy/module/thread/os_lock.py b/pypy/module/thread/os_lock.py --- a/pypy/module/thread/os_lock.py +++ b/pypy/module/thread/os_lock.py @@ -38,10 +38,10 @@ @unwrap_spec(waitflag=int) def descr_lock_acquire(self, space, waitflag=1): - """Lock the lock. Without argument, this blocks if the lock is already -locked (even by the same thread), waiting for another thread to release -the lock, and return None once the lock is acquired. -With an argument, this will only block if the argument is true, + """Lock the lock. With the default argument of True, this blocks +if the lock is already locked (even by the same thread), waiting for +another thread to release the lock, and returns True once the lock is +acquired. With an argument of False, this will always return immediately and the return value reflects whether the lock is acquired. The blocking operation is not interruptible.""" mylock = self.lock @@ -113,4 +113,4 @@ def allocate_lock(space): """Create a new lock object. (allocate() is an obsolete synonym.) See LockType.__doc__ for information about locks.""" - return space.wrap(Lock(space)) \ No newline at end of file + return space.wrap(Lock(space)) diff --git a/pypy/module/thread/test/support.py b/pypy/module/thread/test/support.py --- a/pypy/module/thread/test/support.py +++ b/pypy/module/thread/test/support.py @@ -2,6 +2,7 @@ import time import thread import os +import errno from pypy.interpreter.gateway import interp2app, unwrap_spec from pypy.module.thread import gil @@ -28,7 +29,12 @@ def kill(): for x in range(delay * 10): time.sleep(0.1) - os.kill(pid, 0) + try: + os.kill(pid, 0) + except OSError, e: + if e.errno == errno.ESRCH: # no such process + return + raise os.kill(pid, 9) print "process %s killed!" % (pid,) thread.start_new_thread(kill, ()) diff --git a/pypy/module/thread/test/test_fork.py b/pypy/module/thread/test/test_fork.py --- a/pypy/module/thread/test/test_fork.py +++ b/pypy/module/thread/test/test_fork.py @@ -1,7 +1,7 @@ from pypy.module.thread.test.support import GenericTestThread class AppTestFork(GenericTestThread): - def test_fork(self): + def test_fork_with_thread(self): # XXX This test depends on a multicore machine, as busy_thread must # aquire the GIL the instant that the main thread releases it. # It will incorrectly pass if the GIL is not grabbed in time. @@ -12,45 +12,48 @@ if not hasattr(os, 'fork'): skip("No fork on this platform") - run = True - done = [] def busy_thread(): while run: time.sleep(0) done.append(None) - try: - thread.start_new(busy_thread, ()) + for i in range(1): + run = True + done = [] + try: + thread.start_new(busy_thread, ()) + print 'sleep' - pid = os.fork() - - if pid == 0: - os._exit(0) - - else: - time.sleep(1) - spid, status = os.waitpid(pid, os.WNOHANG) - assert spid == pid - finally: - run = False - self.waitfor(lambda: done) + pid = os.fork() + if pid == 0: + os._exit(0) + else: + self.timeout_killer(pid, 5) + exitcode = os.waitpid(pid, 0)[1] + assert exitcode == 0 # if 9, process was killed by timer! + finally: + run = False + self.waitfor(lambda: done) + assert done def test_forked_can_thread(self): "Checks that a forked interpreter can start a thread" - import os, thread, time + import thread + import os if not hasattr(os, 'fork'): skip("No fork on this platform") - # pre-allocate some locks - thread.start_new_thread(lambda: None, ()) + for i in range(10): + # pre-allocate some locks + thread.start_new_thread(lambda: None, ()) + print 'sleep' - pid = os.fork() - if pid == 0: - print 'in child' - thread.start_new_thread(lambda: None, ()) - os._exit(0) - else: - self.timeout_killer(pid, 5) - exitcode = os.waitpid(pid, 0)[1] - assert exitcode == 0 # if 9, process was killed by timer! + pid = os.fork() + if pid == 0: + thread.start_new_thread(lambda: None, ()) + os._exit(0) + else: + self.timeout_killer(pid, 5) + exitcode = os.waitpid(pid, 0)[1] + assert exitcode == 0 # if 9, process was killed by timer! diff --git a/pypy/module/thread/test/test_lock.py b/pypy/module/thread/test/test_lock.py --- a/pypy/module/thread/test/test_lock.py +++ b/pypy/module/thread/test/test_lock.py @@ -12,7 +12,10 @@ assert lock.locked() is False raises(thread.error, lock.release) assert lock.locked() is False - lock.acquire() + r = lock.acquire() + assert r is True + r = lock.acquire(False) + assert r is False assert lock.locked() is True lock.release() assert lock.locked() is False diff --git a/pypy/module/thread/threadlocals.py b/pypy/module/thread/threadlocals.py --- a/pypy/module/thread/threadlocals.py +++ b/pypy/module/thread/threadlocals.py @@ -44,10 +44,6 @@ self._mostrecentkey = ident self._mostrecentvalue = value - def getmainthreadvalue(self): - ident = self._mainthreadident - return self._valuedict.get(ident, None) - def ismainthread(self): return thread.get_ident() == self._mainthreadident diff --git a/pypy/objspace/std/tupleobject.py b/pypy/objspace/std/tupleobject.py --- a/pypy/objspace/std/tupleobject.py +++ b/pypy/objspace/std/tupleobject.py @@ -85,6 +85,15 @@ start, stop = normalize_simple_slice(space, length, w_start, w_stop) return space.newtuple(w_tuple.wrappeditems[start:stop]) +THRESHOLD = 7 + +def unroll_tuple_contains(space, w_tuple, w_obj): + if (jit.isconstant(w_tuple) or jit.isvirtual(w_tuple) and + len(w_tuple.wrappeditems) < THRESHOLD): + return True + return False + + at jit.look_inside_iff(unroll_tuple_contains) def contains__Tuple_ANY(space, w_tuple, w_obj): for w_item in w_tuple.wrappeditems: if space.eq_w(w_item, w_obj): diff --git a/rpython/annotator/annrpython.py b/rpython/annotator/annrpython.py --- a/rpython/annotator/annrpython.py +++ b/rpython/annotator/annrpython.py @@ -113,6 +113,9 @@ if policy is None: from rpython.annotator.policy import AnnotatorPolicy policy = AnnotatorPolicy() + # XXX hack + annmodel.TLS.check_str_without_nul = ( + self.translator.config.translation.check_str_without_nul) graph, inputcells = self.get_call_parameters(function, args_s, policy) self.build_graph_types(graph, inputcells, complete_now=False) self.complete_helpers(policy) diff --git a/rpython/annotator/binaryop.py b/rpython/annotator/binaryop.py --- a/rpython/annotator/binaryop.py +++ b/rpython/annotator/binaryop.py @@ -446,7 +446,8 @@ class __extend__(pairtype(SomeChar, SomeChar)): def union((chr1, chr2)): - return SomeChar() + no_nul = chr1.no_nul and chr2.no_nul + return SomeChar(no_nul=no_nul) class __extend__(pairtype(SomeChar, SomeUnicodeCodePoint), @@ -664,14 +665,14 @@ def getitem((str1, int2)): getbookkeeper().count("str_getitem", int2) - return SomeChar() + return SomeChar(no_nul=str1.no_nul) getitem.can_only_throw = [] getitem_key = getitem def getitem_idx((str1, int2)): getbookkeeper().count("str_getitem", int2) - return SomeChar() + return SomeChar(no_nul=str1.no_nul) getitem_idx.can_only_throw = [IndexError] getitem_idx_key = getitem_idx diff --git a/rpython/annotator/test/test_annrpython.py b/rpython/annotator/test/test_annrpython.py --- a/rpython/annotator/test/test_annrpython.py +++ b/rpython/annotator/test/test_annrpython.py @@ -2068,7 +2068,23 @@ s = a.build_types(f, [annmodel.SomeString(no_nul=True)]) assert isinstance(s, annmodel.SomeString) assert s.no_nul - + + def test_getitem_str0(self): + def f(s, n): + if n == 1: + return s[0] + elif n == 2: + return s[1] + elif n == 3: + return s[1:] + return s + a = self.RPythonAnnotator() + a.translator.config.translation.check_str_without_nul = True + + s = a.build_types(f, [annmodel.SomeString(no_nul=True), + annmodel.SomeInteger()]) + assert isinstance(s, annmodel.SomeString) + assert s.no_nul def test_non_none_and_none_with_isinstance(self): class A(object): diff --git a/rpython/flowspace/framestate.py b/rpython/flowspace/framestate.py --- a/rpython/flowspace/framestate.py +++ b/rpython/flowspace/framestate.py @@ -1,5 +1,6 @@ +from rpython.flowspace.model import Variable, Constant from rpython.rlib.unroll import SpecTag -from rpython.flowspace.model import * + class FrameState: def __init__(self, mergeable, blocklist, next_instr): @@ -86,6 +87,7 @@ raise TypeError('union of %r and %r' % (w1.__class__.__name__, w2.__class__.__name__)) + # ____________________________________________________________ # # We have to flatten out the state of the frame into a list of @@ -102,6 +104,7 @@ PICKLE_TAGS = {} UNPICKLE_TAGS = {} + def recursively_flatten(space, lst): from rpython.flowspace.flowcontext import SuspendedUnroller i = 0 @@ -117,14 +120,15 @@ except: tag = PICKLE_TAGS[key] = Constant(PickleTag()) UNPICKLE_TAGS[tag] = key - lst[i:i+1] = [tag] + vars + lst[i:i + 1] = [tag] + vars + def recursively_unflatten(space, lst): - for i in xrange(len(lst)-1, -1, -1): + for i in xrange(len(lst) - 1, -1, -1): item = lst[i] if item in UNPICKLE_TAGS: unrollerclass, argcount = UNPICKLE_TAGS[item] - arguments = lst[i+1: i+1+argcount] - del lst[i+1: i+1+argcount] + arguments = lst[i + 1:i + 1 + argcount] + del lst[i + 1:i + 1 + argcount] unroller = unrollerclass.state_pack_variables(space, *arguments) lst[i] = unroller diff --git a/rpython/jit/metainterp/optimizeopt/rewrite.py b/rpython/jit/metainterp/optimizeopt/rewrite.py --- a/rpython/jit/metainterp/optimizeopt/rewrite.py +++ b/rpython/jit/metainterp/optimizeopt/rewrite.py @@ -239,6 +239,8 @@ def optimize_GUARD_VALUE(self, op): value = self.getvalue(op.getarg(0)) + if value.is_virtual(): + raise InvalidLoop('A promote of a virtual (a recently allocated object) never makes sense!') if value.last_guard: # there already has been a guard_nonnull or guard_class or # guard_nonnull_class on this value, which is rather silly. diff --git a/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py b/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py --- a/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py +++ b/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py @@ -2623,7 +2623,7 @@ jump(p2) """ self.raises(InvalidLoop, self.optimize_loop, - ops, ops) + ops, "crash!") def test_invalid_loop_2(self): ops = """ @@ -2635,7 +2635,7 @@ jump(p2) """ self.raises(InvalidLoop, self.optimize_loop, From noreply at buildbot.pypy.org Mon Feb 4 01:10:14 2013 From: noreply at buildbot.pypy.org (mattip) Date: Mon, 4 Feb 2013 01:10:14 +0100 (CET) Subject: [pypy-commit] pypy missing-ndarray-attributes: fix one translation error Message-ID: <20130204001014.97CA21C0183@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: missing-ndarray-attributes Changeset: r60854:90c5f3f0ef1b Date: 2013-02-04 02:09 +0200 http://bitbucket.org/pypy/pypy/changeset/90c5f3f0ef1b/ Log: fix one translation error diff --git a/pypy/module/micronumpy/types.py b/pypy/module/micronumpy/types.py --- a/pypy/module/micronumpy/types.py +++ b/pypy/module/micronumpy/types.py @@ -140,7 +140,7 @@ @specialize.argtype(1, 2) def box_complex(self, real, imag): #XXX this is the place to display a warning - return self.BoxType(rffi.cast(self.T, real)) + return self.box(real) def unbox(self, box): assert isinstance(box, self.BoxType) From noreply at buildbot.pypy.org Mon Feb 4 01:41:33 2013 From: noreply at buildbot.pypy.org (rlamy) Date: Mon, 4 Feb 2013 01:41:33 +0100 (CET) Subject: [pypy-commit] pypy kill-flowobjspace: kill FSFrame.pushrevvalues() and .peekvalues() Message-ID: <20130204004133.D298E1C009B@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: kill-flowobjspace Changeset: r60855:1edcfb140754 Date: 2013-02-04 00:00 +0000 http://bitbucket.org/pypy/pypy/changeset/1edcfb140754/ Log: kill FSFrame.pushrevvalues() and .peekvalues() diff --git a/rpython/flowspace/flowcontext.py b/rpython/flowspace/flowcontext.py --- a/rpython/flowspace/flowcontext.py +++ b/rpython/flowspace/flowcontext.py @@ -360,11 +360,6 @@ "peek past the bottom of the stack") return self.locals_stack_w[index] - def pushrevvalues(self, n, values_w): # n should be len(values_w) - assert len(values_w) == n - for i in range(n - 1, -1, -1): - self.pushvalue(values_w[i]) - def settopvalue(self, w_object, index_from_top=0): index = self.valuestackdepth + ~index_from_top assert index >= self.pycode.co_nlocals, ( @@ -376,16 +371,6 @@ values_w.reverse() return values_w - def peekvalues(self, n): - values_w = [None] * n - base = self.valuestackdepth - n - while True: - n -= 1 - if n < 0: - break - values_w[n] = self.locals_stack_w[base+n] - return values_w - def dropvalues(self, n): finaldepth = self.valuestackdepth - n for n in range(finaldepth, self.valuestackdepth): @@ -1020,7 +1005,8 @@ def UNPACK_SEQUENCE(self, itemcount, next_instr): w_iterable = self.popvalue() items = self.space.unpack_sequence(w_iterable, itemcount) - self.pushrevvalues(itemcount, items) + for w_item in reversed(items): + self.pushvalue(w_item) def slice(self, w_start, w_end): w_obj = self.popvalue() From noreply at buildbot.pypy.org Mon Feb 4 02:06:12 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Mon, 4 Feb 2013 02:06:12 +0100 (CET) Subject: [pypy-commit] pypy default: some random cleanups Message-ID: <20130204010612.DFF401C02AF@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r60856:6614966cafa4 Date: 2013-02-03 17:06 -0800 http://bitbucket.org/pypy/pypy/changeset/6614966cafa4/ Log: some random cleanups diff --git a/pypy/interpreter/typedef.py b/pypy/interpreter/typedef.py --- a/pypy/interpreter/typedef.py +++ b/pypy/interpreter/typedef.py @@ -1,18 +1,17 @@ -""" +import py - -""" -import py -from pypy.interpreter.gateway import interp2app, BuiltinCode, unwrap_spec,\ - WrappedDefault from pypy.interpreter.argument import Arguments from pypy.interpreter.baseobjspace import Wrappable, DescrMismatch from pypy.interpreter.error import OperationError, operationerrfmt +from pypy.interpreter.gateway import (interp2app, BuiltinCode, unwrap_spec, + WrappedDefault) + +from rpython.rlib.jit import promote +from rpython.rlib.objectmodel import compute_identity_hash, specialize from rpython.tool.sourcetools import compile2, func_with_new_name -from rpython.rlib.objectmodel import instantiate, compute_identity_hash, specialize -from rpython.rlib.jit import promote -class TypeDef: + +class TypeDef(object): def __init__(self, __name, __base=None, __total_ordering__=None, **rawdict): "NOT_RPYTHON: initialization-time only" self.name = __name @@ -27,7 +26,7 @@ self.weakrefable = '__weakref__' in rawdict self.doc = rawdict.pop('__doc__', None) for base in bases: - self.hasdict |= base.hasdict + self.hasdict |= base.hasdict self.weakrefable |= base.weakrefable self.rawdict = {} self.acceptable_as_base_class = '__new__' in rawdict @@ -426,7 +425,7 @@ return unknown_objclass_getter, cls miniglobals = {} if isinstance(cls, str): - assert cls.startswith('<'),"pythontype typecheck should begin with <" + assert cls.startswith('<'), "pythontype typecheck should begin with <" cls_name = cls[1:] typeexpr = "space.w_%s" % cls_name else: @@ -474,7 +473,7 @@ else: try: return self.fget(self, space, w_obj) - except DescrMismatch, e: + except DescrMismatch: return w_obj.descr_call_mismatch( space, '__getattribute__', self.reqcls, Arguments(space, [w_obj, @@ -489,7 +488,7 @@ space.wrap("readonly attribute")) try: fset(self, space, w_obj, w_value) - except DescrMismatch, e: + except DescrMismatch: w_obj.descr_call_mismatch( space, '__setattr__', self.reqcls, Arguments(space, [w_obj, @@ -505,7 +504,7 @@ space.wrap("cannot delete attribute")) try: fdel(self, space, w_obj) - except DescrMismatch, e: + except DescrMismatch: w_obj.descr_call_mismatch( space, '__delattr__', self.reqcls, Arguments(space, [w_obj, @@ -546,6 +545,7 @@ class Member(Wrappable): """For slots.""" _immutable_ = True + def __init__(self, index, name, w_cls): self.index = index self.name = name @@ -617,9 +617,8 @@ from pypy.interpreter.pyframe import PyFrame from pypy.interpreter.pyopcode import SuspendedUnroller from pypy.interpreter.module import Module -from pypy.interpreter.function import Function, Method, StaticMethod -from pypy.interpreter.function import ClassMethod -from pypy.interpreter.function import BuiltinFunction, descr_function_get +from pypy.interpreter.function import (Function, Method, StaticMethod, + ClassMethod, BuiltinFunction, descr_function_get) from pypy.interpreter.pytraceback import PyTraceback from pypy.interpreter.generator import GeneratorIterator from pypy.interpreter.nestedscope import Cell @@ -663,8 +662,10 @@ def fget_co_flags(space, code): # unwrapping through unwrap_spec sig = code.signature() flags = 0 - if sig.has_vararg(): flags |= CO_VARARGS - if sig.has_kwarg(): flags |= CO_VARKEYWORDS + if sig.has_vararg(): + flags |= CO_VARARGS + if sig.has_kwarg(): + flags |= CO_VARKEYWORDS return space.wrap(flags) def fget_co_consts(space, code): # unwrapping through unwrap_spec @@ -728,7 +729,7 @@ __eq__ = interp2app(PyCode.descr_code__eq__), __ne__ = descr_generic_ne, __hash__ = interp2app(PyCode.descr_code__hash__), - __reduce__ = interp2app(PyCode.descr__reduce__), + __reduce__ = interp2app(PyCode.descr__reduce__), __repr__ = interp2app(PyCode.repr), co_argcount = interp_attrproperty('co_argcount', cls=PyCode), co_nlocals = interp_attrproperty('co_nlocals', cls=PyCode), @@ -737,9 +738,9 @@ co_code = interp_attrproperty('co_code', cls=PyCode), co_consts = GetSetProperty(PyCode.fget_co_consts), co_names = GetSetProperty(PyCode.fget_co_names), - co_varnames = GetSetProperty(PyCode.fget_co_varnames), - co_freevars = GetSetProperty(PyCode.fget_co_freevars), - co_cellvars = GetSetProperty(PyCode.fget_co_cellvars), + co_varnames = GetSetProperty(PyCode.fget_co_varnames), + co_freevars = GetSetProperty(PyCode.fget_co_freevars), + co_cellvars = GetSetProperty(PyCode.fget_co_cellvars), co_filename = interp_attrproperty('co_filename', cls=PyCode), co_name = interp_attrproperty('co_name', cls=PyCode), co_firstlineno = interp_attrproperty('co_firstlineno', cls=PyCode), @@ -749,7 +750,7 @@ PyCode.typedef.acceptable_as_base_class = False PyFrame.typedef = TypeDef('frame', - __reduce__ = interp2app(PyFrame.descr__reduce__), + __reduce__ = interp2app(PyFrame.descr__reduce__), __setstate__ = interp2app(PyFrame.descr__setstate__), f_builtins = GetSetProperty(PyFrame.fget_f_builtins), f_lineno = GetSetProperty(PyFrame.fget_f_lineno, PyFrame.fset_f_lineno), @@ -827,9 +828,9 @@ __new__ = interp2app(Method.descr_method__new__.im_func), __call__ = interp2app(Method.descr_method_call), __get__ = interp2app(Method.descr_method_get), - im_func = interp_attrproperty_w('w_function', cls=Method), + im_func = interp_attrproperty_w('w_function', cls=Method), __func__ = interp_attrproperty_w('w_function', cls=Method), - im_self = interp_attrproperty_w('w_instance', cls=Method), + im_self = interp_attrproperty_w('w_instance', cls=Method), __self__ = interp_attrproperty_w('w_instance', cls=Method), im_class = interp_attrproperty_w('w_class', cls=Method), __getattribute__ = interp2app(Method.descr_method_getattribute), @@ -886,7 +887,7 @@ def always_none(self, obj): return None -BuiltinFunction.typedef = TypeDef("builtin_function",**Function.typedef.rawdict) +BuiltinFunction.typedef = TypeDef("builtin_function", **Function.typedef.rawdict) BuiltinFunction.typedef.rawdict.update({ '__new__': interp2app(BuiltinFunction.descr_builtinfunction__new__.im_func), '__self__': GetSetProperty(always_none, cls=BuiltinFunction), @@ -897,12 +898,12 @@ BuiltinFunction.typedef.acceptable_as_base_class = False PyTraceback.typedef = TypeDef("traceback", - __reduce__ = interp2app(PyTraceback.descr__reduce__), + __reduce__ = interp2app(PyTraceback.descr__reduce__), __setstate__ = interp2app(PyTraceback.descr__setstate__), - tb_frame = interp_attrproperty('frame', cls=PyTraceback), - tb_lasti = interp_attrproperty('lasti', cls=PyTraceback), + tb_frame = interp_attrproperty('frame', cls=PyTraceback), + tb_lasti = interp_attrproperty('lasti', cls=PyTraceback), tb_lineno = GetSetProperty(PyTraceback.descr_tb_lineno), - tb_next = interp_attrproperty('next', cls=PyTraceback), + tb_next = interp_attrproperty('next', cls=PyTraceback), ) PyTraceback.typedef.acceptable_as_base_class = False @@ -937,12 +938,12 @@ Cell.typedef.acceptable_as_base_class = False Ellipsis.typedef = TypeDef("Ellipsis", - __repr__ = interp2app(Ellipsis.descr__repr__), + __repr__ = interp2app(Ellipsis.descr__repr__), ) Ellipsis.typedef.acceptable_as_base_class = False NotImplemented.typedef = TypeDef("NotImplemented", - __repr__ = interp2app(NotImplemented.descr__repr__), + __repr__ = interp2app(NotImplemented.descr__repr__), ) NotImplemented.typedef.acceptable_as_base_class = False From noreply at buildbot.pypy.org Mon Feb 4 03:03:39 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Mon, 4 Feb 2013 03:03:39 +0100 (CET) Subject: [pypy-commit] pypy default: General cleanups, switch something to use a better API Message-ID: <20130204020339.5BB301C0183@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r60857:4ec167bb30f5 Date: 2013-02-03 18:03 -0800 http://bitbucket.org/pypy/pypy/changeset/4ec167bb30f5/ Log: General cleanups, switch something to use a better API diff --git a/pypy/interpreter/pytraceback.py b/pypy/interpreter/pytraceback.py --- a/pypy/interpreter/pytraceback.py +++ b/pypy/interpreter/pytraceback.py @@ -1,5 +1,6 @@ from pypy.interpreter import baseobjspace from pypy.interpreter.error import OperationError + from rpython.tool.error import offset2lineno @@ -27,10 +28,10 @@ def descr__reduce__(self, space): from pypy.interpreter.mixedmodule import MixedModule - w_mod = space.getbuiltinmodule('_pickle_support') - mod = space.interp_w(MixedModule, w_mod) + w_mod = space.getbuiltinmodule('_pickle_support') + mod = space.interp_w(MixedModule, w_mod) new_inst = mod.get('traceback_new') - w = space.wrap + w = space.wrap tup_base = [] tup_state = [ @@ -49,6 +50,7 @@ self.lasti = space.int_w(w_lasti) self.next = space.interp_w(PyTraceback, w_next, can_be_None=True) + def record_application_traceback(space, operror, frame, last_instruction): if frame.pycode.hidden_applevel: return @@ -56,10 +58,11 @@ tb = PyTraceback(space, frame, last_instruction, tb) operror.set_traceback(tb) + def check_traceback(space, w_tb, msg): from pypy.interpreter.typedef import PyTraceback tb = space.interpclass_w(w_tb) - if tb is None or not space.is_true(space.isinstance(tb, + if tb is None or not space.is_true(space.isinstance(tb, space.gettypeobject(PyTraceback.typedef))): raise OperationError(space.w_TypeError, space.wrap(msg)) return tb diff --git a/pypy/objspace/std/typeobject.py b/pypy/objspace/std/typeobject.py --- a/pypy/objspace/std/typeobject.py +++ b/pypy/objspace/std/typeobject.py @@ -1,24 +1,23 @@ +from pypy.interpreter import gateway +from pypy.interpreter.baseobjspace import W_Root +from pypy.interpreter.error import OperationError, operationerrfmt +from pypy.interpreter.function import Function, StaticMethod +from pypy.interpreter.typedef import weakref_descr from pypy.objspace.std.model import W_Object from pypy.objspace.std.register_all import register_all -from pypy.interpreter.function import Function, StaticMethod -from pypy.interpreter import gateway -from pypy.interpreter.error import OperationError, operationerrfmt -from pypy.interpreter.typedef import weakref_descr -from pypy.interpreter.baseobjspace import W_Root from pypy.objspace.std.stdtypedef import std_dict_descr, issubtypedef, Member -from pypy.objspace.std.objecttype import object_typedef -from pypy.objspace.std import identitydict -from rpython.rlib.objectmodel import we_are_translated + +from rpython.rlib.jit import (promote, elidable_promote, we_are_jitted, + promote_string, elidable, dont_look_inside, unroll_safe) from rpython.rlib.objectmodel import current_object_addr_as_int, compute_hash -from rpython.rlib.jit import promote, elidable_promote, we_are_jitted,\ - promote_string -from rpython.rlib.jit import elidable, dont_look_inside, unroll_safe from rpython.rlib.rarithmetic import intmask, r_uint + class TypeCell(W_Root): def __init__(self, w_value=None): self.w_value = w_value + def unwrap_cell(space, w_value): if (space.config.objspace.std.withtypeversion and isinstance(w_value, TypeCell)): @@ -278,7 +277,7 @@ if attr in w_self.lazyloaders: # very clever next line: it forces the attr string # to be interned. - w_attr = space.new_interned_str(attr) + space.new_interned_str(attr) loader = w_self.lazyloaders[attr] del w_self.lazyloaders[attr] w_value = loader() @@ -497,7 +496,7 @@ def get_module(w_self): space = w_self.space - if w_self.is_heaptype() and '__module__' in w_self.dict_w: + if w_self.is_heaptype() and w_self.getdictvalue(space, '__module__') is not None: return w_self.getdictvalue(space, '__module__') else: # for non-heap types, CPython checks for a module.name in the @@ -516,7 +515,7 @@ mod = '__builtin__' else: mod = space.str_w(w_mod) - if mod !='__builtin__': + if mod != '__builtin__': return '%s.%s' % (mod, w_self.name) else: return w_self.name @@ -560,13 +559,15 @@ subclasses_w.append(w_ob) return subclasses_w - # for now, weakref support for W_TypeObject is hard to get automatically _lifeline_ = None + def getweakref(self): return self._lifeline_ + def setweakref(self, space, weakreflifeline): self._lifeline_ = weakreflifeline + def delweakref(self): self._lifeline_ = None @@ -693,9 +694,12 @@ else: create_slot(w_self, slot_name) wantdict = wantdict or hasoldstylebase - if wantdict: create_dict_slot(w_self) - if wantweakref: create_weakref_slot(w_self) - if '__del__' in dict_w: w_self.needsdel = True + if wantdict: + create_dict_slot(w_self) + if wantweakref: + create_weakref_slot(w_self) + if '__del__' in dict_w: + w_self.needsdel = True def create_slot(w_self, slot_name): space = w_self.space @@ -868,7 +872,7 @@ kind = 'type' else: kind = 'class' - if mod is not None and mod !='__builtin__': + if mod is not None and mod != '__builtin__': return space.wrap("<%s '%s.%s'>" % (kind, mod, w_obj.name)) else: return space.wrap("<%s '%s'>" % (kind, w_obj.name)) @@ -887,7 +891,7 @@ # __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) + return space.get(w_descr, w_type) raise operationerrfmt(space.w_AttributeError, "type object '%s' has no attribute '%s'", w_type.name, name) @@ -933,7 +937,7 @@ return mro_error(space, orderlists) # no candidate found assert candidate not in order order.append(candidate) - for i in range(len(orderlists)-1, -1, -1): + for i in range(len(orderlists) - 1, -1, -1): if orderlists[i][0] is candidate: del orderlists[i][0] if len(orderlists[i]) == 0: From noreply at buildbot.pypy.org Mon Feb 4 03:29:10 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Mon, 4 Feb 2013 03:29:10 +0100 (CET) Subject: [pypy-commit] pypy default: randome pep8 cleanups Message-ID: <20130204022910.A47C51C02AF@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r60858:42afcd013e8d Date: 2013-02-03 18:28 -0800 http://bitbucket.org/pypy/pypy/changeset/42afcd013e8d/ Log: randome pep8 cleanups diff --git a/pypy/objspace/std/typetype.py b/pypy/objspace/std/typetype.py --- a/pypy/objspace/std/typetype.py +++ b/pypy/objspace/std/typetype.py @@ -1,5 +1,4 @@ from pypy.interpreter import gateway -from pypy.interpreter.argument import Arguments from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.typedef import (GetSetProperty, descr_get_dict, weakref_descr) @@ -90,9 +89,9 @@ return space.wrap(w_type.name) def descr_set__name__(space, w_type, w_value): - w_type = _check(space, w_type) + w_type = _check(space, w_type) if not w_type.is_heaptype(): - raise operationerrfmt(space.w_TypeError, + raise operationerrfmt(space.w_TypeError, "can't set %s.__name__", w_type.name) w_type.name = space.str_w(w_value) @@ -119,10 +118,9 @@ def descr_set__bases__(space, w_type, w_value): # this assumes all app-level type objects are W_TypeObject - from pypy.objspace.std.typeobject import W_TypeObject - from pypy.objspace.std.typeobject import check_and_find_best_base - from pypy.objspace.std.typeobject import get_parent_layout - from pypy.objspace.std.typeobject import is_mro_purely_of_types + from pypy.objspace.std.typeobject import (W_TypeObject, get_parent_layout, + check_and_find_best_base, is_mro_purely_of_types) + w_type = _check(space, w_type) if not w_type.is_heaptype(): raise operationerrfmt(space.w_TypeError, @@ -213,9 +211,12 @@ # w_type = _check(space, w_type) flags = 0 - if w_type.flag_heaptype: flags |= _HEAPTYPE - if w_type.flag_cpytype: flags |= _CPYTYPE - if w_type.flag_abstract: flags |= _ABSTRACT + if w_type.flag_heaptype: + flags |= _HEAPTYPE + if w_type.flag_cpytype: + flags |= _CPYTYPE + if w_type.flag_abstract: + flags |= _ABSTRACT return space.wrap(flags) def descr_get__module(space, w_type): From noreply at buildbot.pypy.org Mon Feb 4 10:17:21 2013 From: noreply at buildbot.pypy.org (fijal) Date: Mon, 4 Feb 2013 10:17:21 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: fix the assertion Message-ID: <20130204091721.BA8521C047D@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r60859:906f8afffa8b Date: 2013-02-04 11:16 +0200 http://bitbucket.org/pypy/pypy/changeset/906f8afffa8b/ Log: fix the assertion diff --git a/rpython/jit/backend/llsupport/gc.py b/rpython/jit/backend/llsupport/gc.py --- a/rpython/jit/backend/llsupport/gc.py +++ b/rpython/jit/backend/llsupport/gc.py @@ -159,6 +159,9 @@ unicode_type_id = 0 get_malloc_slowpath_addr = None + def is_shadow_stack(self): + return False + @classmethod def configure_boehm_once(cls): """ Configure boehm only once, since we don't cache failures @@ -319,6 +322,9 @@ kind = 'framework' round_up = True + def is_shadow_stack(self): + return self.gcrootmap.is_shadow_stack + def __init__(self, gcdescr, translator, rtyper, llop1=llop, really_not_translated=False): GcLLDescription.__init__(self, gcdescr, translator, rtyper) diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -1232,8 +1232,9 @@ x = r10 remap_frame_layout(self, src_locs, dst_locs, X86_64_SCRATCH_REG) if can_collect: - self.push_gcmap(self.mc, self._regalloc.get_gcmap([eax], noregs=True), - store=True) + noregs = self.cpu.gc_ll_descr.is_shadow_stack() + gcmap = self._regalloc.get_gcmap([eax], noregs=noregs) + self.push_gcmap(self.mc, gcmap, store=True) self.mc.CALL(x) if can_collect: self._reload_frame_if_necessary(self.mc) From noreply at buildbot.pypy.org Mon Feb 4 10:44:38 2013 From: noreply at buildbot.pypy.org (fijal) Date: Mon, 4 Feb 2013 10:44:38 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: one fix Message-ID: <20130204094438.B19451C009B@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r60860:a0fb5ba3e4c2 Date: 2013-02-04 11:44 +0200 http://bitbucket.org/pypy/pypy/changeset/a0fb5ba3e4c2/ Log: one fix diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -243,8 +243,7 @@ # the arg is already in edi if hasattr(self.cpu.gc_ll_descr, 'passes_frame'): # for tests only - base_ofs = self.cpu.get_baseofs_of_frame_field() - mc.LEA_rb(esi.value, -base_ofs) + mc.MOV_rr(esi.value, ebp.value) mc.SUB_ri(esp.value, 16 - WORD) mc.CALL(imm(addr)) mc.ADD_ri(esp.value, 16 - WORD) From noreply at buildbot.pypy.org Mon Feb 4 11:09:24 2013 From: noreply at buildbot.pypy.org (fijal) Date: Mon, 4 Feb 2013 11:09:24 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: fix Message-ID: <20130204100924.2D82A1C02AF@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r60861:3b602954cad4 Date: 2013-02-04 12:09 +0200 http://bitbucket.org/pypy/pypy/changeset/3b602954cad4/ Log: fix diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -1974,18 +1974,19 @@ def _pop_all_regs_from_frame(self, mc, ignored_regs, withfloats, callee_only=False): # Pop all general purpose registers + base_ofs = self.cpu.get_baseofs_of_frame_field() if callee_only: regs = gpr_reg_mgr_cls.save_around_call_regs else: regs = gpr_reg_mgr_cls.all_regs for i, gpr in enumerate(regs): if gpr not in ignored_regs: - mc.MOV_rb(gpr.value, i * WORD) + mc.MOV_rb(gpr.value, i * WORD + base_ofs) if withfloats: # Pop all XMM regs ofs = len(gpr_reg_mgr_cls.all_regs) for i in range(len(xmm_reg_mgr_cls.all_regs)): - mc.MOVSD_xb(i, (ofs + i) * WORD) + mc.MOVSD_xb(i, (ofs + i) * WORD + base_ofs) def _build_failure_recovery(self, exc, withfloats=False): mc = codebuf.MachineCodeBlockWrapper() From noreply at buildbot.pypy.org Mon Feb 4 11:16:05 2013 From: noreply at buildbot.pypy.org (mattip) Date: Mon, 4 Feb 2013 11:16:05 +0100 (CET) Subject: [pypy-commit] pypy missing-ndarray-attributes: hack around seemingly nonfunctional @staticmethod Message-ID: <20130204101605.E44AD1C02AF@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: missing-ndarray-attributes Changeset: r60862:72bf13db5cf2 Date: 2013-02-04 12:11 +0200 http://bitbucket.org/pypy/pypy/changeset/72bf13db5cf2/ Log: hack around seemingly nonfunctional @staticmethod diff --git a/pypy/module/micronumpy/arrayimpl/sort.py b/pypy/module/micronumpy/arrayimpl/sort.py --- a/pypy/module/micronumpy/arrayimpl/sort.py +++ b/pypy/module/micronumpy/arrayimpl/sort.py @@ -16,9 +16,10 @@ INT_SIZE = rffi.sizeof(lltype.Signed) -def make_sort_function(space, itemtype, count=1): +def make_sort_function(space, itemtype, comp_type, count=1): TP = itemtype.T step = rffi.sizeof(TP) + print itemtype class Repr(object): def __init__(self, index_stride_size, stride_size, size, values, @@ -35,14 +36,21 @@ if count < 2: v = raw_storage_getitem(TP, self.values, item * self.stride_size + self.start) - v = itemtype.for_computation(v) + if comp_type=='int': + v = int(v) + elif comp_type=='float': + v = float(v) + elif comp_type=='complex': + v = float(v[0]),float(v[1]) + else: + raise NotImplementedError('cannot reach') else: v = [] for i in range(count): _v = raw_storage_getitem(TP, self.values, item * self.stride_size + self.start + step * i) v.append(_v) - v = itemtype.for_computation(v) + v = for_computation(v) return (v, raw_storage_getitem(lltype.Signed, self.indexes, item * self.index_stride_size + self.index_start)) @@ -145,7 +153,7 @@ cache = space.fromcache(SortCache) # that populates SortClasses itemtype = arr.dtype.itemtype for tp in all_types: - if isinstance(itemtype, tp): + if isinstance(itemtype, tp[0]): return cache._lookup(tp)(arr, space, w_axis, itemtype.get_element_size()) # XXX this should probably be changed @@ -153,9 +161,10 @@ space.wrap("sorting of non-numeric types " + \ "'%s' is not implemented" % arr.dtype.get_name(), )) -all_types = (types.all_int_types + types.all_complex_types + - types.all_float_types) -all_types = [i for i in all_types if not '_mixin_' in i.__dict__] +all_types = (types.all_float_types) # + types.all_complex_types + + # types.all_int_types) +all_types = [i for i in all_types if not '_mixin_' in i[0].__dict__] +all_types = [i for i in all_types if not 'NonNative' in str(i[0])] all_types = unrolling_iterable(all_types) class SortCache(object): @@ -166,10 +175,10 @@ return self.built = True cache = {} - for cls in all_types._items: + for cls, it in all_types._items: if cls in types.all_complex_types: - cache[cls] = make_sort_function(space, cls, 2) + cache[cls] = make_sort_function(space, cls, it, 2) else: - cache[cls] = make_sort_function(space, cls) + cache[cls] = make_sort_function(space, cls, it) self.cache = cache - self._lookup = specialize.memo()(lambda tp : cache[tp]) + self._lookup = specialize.memo()(lambda tp : cache[tp[0]]) diff --git a/pypy/module/micronumpy/types.py b/pypy/module/micronumpy/types.py --- a/pypy/module/micronumpy/types.py +++ b/pypy/module/micronumpy/types.py @@ -31,10 +31,11 @@ specialize.argtype(1)(func) @functools.wraps(func) def dispatcher(self, v): + raw = self.unbox(v) return self.box( func( self, - self.for_computation(self.unbox(v)) + self.for_computation(raw) ) ) return dispatcher @@ -142,6 +143,7 @@ #XXX this is the place to display a warning return self.box(real) + @specialize.argtype(1) def unbox(self, box): assert isinstance(box, self.BoxType) return box.value @@ -954,53 +956,6 @@ swapped_value = byteswap(rffi.cast(self.T, value)) raw_storage_setitem(storage, i + offset, swapped_value) -class BaseFloat16(Float): - _mixin_ = True - - _attrs_ = () - _STORAGE_T = rffi.USHORT - T = rffi.SHORT - - BoxType = interp_boxes.W_Float16Box - - @specialize.argtype(1) - def box(self, value): - return self.BoxType(rffi.cast(rffi.DOUBLE, value)) - - def runpack_str(self, s): - assert len(s) == 2 - fval = unpack_float(s, native_is_bigendian) - return self.box(fval) - - def default_fromstring(self, space): - return self.box(-1.0) - - def byteswap(self, w_v): - value = self.unbox(w_v) - hbits = float_pack(value,2) - swapped = byteswap(rffi.cast(self._STORAGE_T, hbits)) - return self.box(float_unpack(r_ulonglong(swapped), 2)) - -class Float16(BaseType, BaseFloat16): - def _read(self, storage, i, offset): - hbits = raw_storage_getitem(self._STORAGE_T, storage, i + offset) - return float_unpack(r_ulonglong(hbits), 2) - - def _write(self, storage, i, offset, value): - hbits = float_pack(value,2) - raw_storage_setitem(storage, i + offset, - rffi.cast(self._STORAGE_T, hbits)) - -class NonNativeFloat16(BaseType, BaseFloat16): - def _read(self, storage, i, offset): - hbits = raw_storage_getitem(self._STORAGE_T, storage, i + offset) - return float_unpack(r_ulonglong(byteswap(hbits)), 2) - - def _write(self, storage, i, offset, value): - hbits = float_pack(value,2) - raw_storage_setitem(storage, i + offset, - byteswap(rffi.cast(self._STORAGE_T, hbits))) - class Float32(BaseType, Float): _attrs_ = () @@ -1755,16 +1710,74 @@ all_int_types = [] all_complex_types = [] +def for_int_computation(v): + return widen(v) + +def for_float_computation(v): + return float(v) + +def for_complex_computation(v): + return float(v[0]), float(v[1]) + def _setup(): # compute alignment for tp in globals().values(): if isinstance(tp, type) and hasattr(tp, 'T'): tp.alignment = clibffi.cast_type_to_ffitype(tp.T).c_alignment if issubclass(tp, Float): - all_float_types.append(tp) + all_float_types.append((tp, 'float')) if issubclass(tp, Integer): - all_int_types.append(tp) + all_int_types.append((tp, 'int')) if issubclass(tp, ComplexFloating): - all_complex_types.append(tp) + all_complex_types.append((tp, 'complex')) _setup() del _setup + +class BaseFloat16(Float): + _mixin_ = True + + _attrs_ = () + _STORAGE_T = rffi.USHORT + T = rffi.SHORT + + BoxType = interp_boxes.W_Float16Box + + @specialize.argtype(1) + def box(self, value): + return self.BoxType(rffi.cast(rffi.DOUBLE, value)) + + def runpack_str(self, s): + assert len(s) == 2 + fval = unpack_float(s, native_is_bigendian) + return self.box(fval) + + def default_fromstring(self, space): + return self.box(-1.0) + + def byteswap(self, w_v): + value = self.unbox(w_v) + hbits = float_pack(value,2) + swapped = byteswap(rffi.cast(self._STORAGE_T, hbits)) + return self.box(float_unpack(r_ulonglong(swapped), 2)) + +class Float16(BaseType, BaseFloat16): + def _read(self, storage, i, offset): + hbits = raw_storage_getitem(self._STORAGE_T, storage, i + offset) + return float_unpack(r_ulonglong(hbits), 2) + + def _write(self, storage, i, offset, value): + hbits = float_pack(value,2) + raw_storage_setitem(storage, i + offset, + rffi.cast(self._STORAGE_T, hbits)) + +class NonNativeFloat16(BaseType, BaseFloat16): + def _read(self, storage, i, offset): + hbits = raw_storage_getitem(self._STORAGE_T, storage, i + offset) + return float_unpack(r_ulonglong(byteswap(hbits)), 2) + + def _write(self, storage, i, offset, value): + hbits = float_pack(value,2) + raw_storage_setitem(storage, i + offset, + byteswap(rffi.cast(self._STORAGE_T, hbits))) + + From noreply at buildbot.pypy.org Mon Feb 4 11:16:07 2013 From: noreply at buildbot.pypy.org (mattip) Date: Mon, 4 Feb 2013 11:16:07 +0100 (CET) Subject: [pypy-commit] pypy missing-ndarray-attributes: allow PBC of mixin class until fixed in default Message-ID: <20130204101607.3FEE51C02AF@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: missing-ndarray-attributes Changeset: r60863:75789571ec61 Date: 2013-02-04 12:13 +0200 http://bitbucket.org/pypy/pypy/changeset/75789571ec61/ Log: allow PBC of mixin class until fixed in default diff --git a/rpython/annotator/bookkeeper.py b/rpython/annotator/bookkeeper.py --- a/rpython/annotator/bookkeeper.py +++ b/rpython/annotator/bookkeeper.py @@ -447,8 +447,9 @@ if (x is type(None) or # add cases here if needed x.__module__ == 'rpython.rtyper.lltypesystem.lltype'): result = SomeType() - elif x.__dict__.get('_mixin_', False): - raise Exception("Creating a PBC of a mixin class is not RPython") + #elif x.__dict__.get('_mixin_', False): + # raise Exception("Creating a PBC of a mixin class is " + # "not RPython for class %r" % x) else: result = SomePBC([self.getdesc(x)]) elif callable(x): From noreply at buildbot.pypy.org Mon Feb 4 11:19:00 2013 From: noreply at buildbot.pypy.org (fijal) Date: Mon, 4 Feb 2013 11:19:00 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: fix this test Message-ID: <20130204101900.82F131C02AF@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r60864:06378d25473b Date: 2013-02-04 12:18 +0200 http://bitbucket.org/pypy/pypy/changeset/06378d25473b/ Log: fix this test diff --git a/rpython/jit/backend/x86/test/test_jump.py b/rpython/jit/backend/x86/test/test_jump.py --- a/rpython/jit/backend/x86/test/test_jump.py +++ b/rpython/jit/backend/x86/test/test_jump.py @@ -5,7 +5,8 @@ from rpython.jit.backend.x86.jump import remap_frame_layout_mixed from rpython.jit.metainterp.history import INT -frame_pos = X86FrameManager.frame_pos +fm = X86FrameManager(0) +frame_pos = fm.frame_pos class MockAssembler: def __init__(self): From noreply at buildbot.pypy.org Mon Feb 4 11:36:19 2013 From: noreply at buildbot.pypy.org (fijal) Date: Mon, 4 Feb 2013 11:36:19 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: fix RPython Message-ID: <20130204103619.CB1211C02AF@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r60865:3c3d5eecdffd Date: 2013-02-04 12:35 +0200 http://bitbucket.org/pypy/pypy/changeset/3c3d5eecdffd/ Log: fix RPython diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -70,6 +70,7 @@ if isinstance(loc, RegLoc): val = gpr_reg_mgr_cls.all_reg_indexes[loc.value] else: + assert isinstance(loc, StackLoc) val = loc.position + JITFRAME_FIXED_SIZE gcmap[val // WORD // 8] |= r_uint(1) << (val % (WORD * 8)) return gcmap From noreply at buildbot.pypy.org Mon Feb 4 11:42:05 2013 From: noreply at buildbot.pypy.org (fijal) Date: Mon, 4 Feb 2013 11:42:05 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: one more rpython fix Message-ID: <20130204104205.228111C0183@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r60866:a57462c3eb97 Date: 2013-02-04 12:41 +0200 http://bitbucket.org/pypy/pypy/changeset/a57462c3eb97/ Log: one more rpython fix diff --git a/rpython/jit/backend/model.py b/rpython/jit/backend/model.py --- a/rpython/jit/backend/model.py +++ b/rpython/jit/backend/model.py @@ -319,6 +319,7 @@ new_fi.jfi_frame_depth) new_loop_tokens.append(ref) oldlooptoken.frame_info.set_frame_depth(baseofs, new_fi.jfi_frame_depth) + assert oldlooptoken is not None new_loop_tokens.append(weakref.ref(oldlooptoken)) self.looptokens_redirected_to = new_loop_tokens From noreply at buildbot.pypy.org Mon Feb 4 13:38:40 2013 From: noreply at buildbot.pypy.org (mattip) Date: Mon, 4 Feb 2013 13:38:40 +0100 (CET) Subject: [pypy-commit] pypy missing-ndarray-attributes: remove debug cruft Message-ID: <20130204123840.CE45B1C1053@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: missing-ndarray-attributes Changeset: r60867:d8a4df50c05a Date: 2013-02-04 12:22 +0200 http://bitbucket.org/pypy/pypy/changeset/d8a4df50c05a/ Log: remove debug cruft diff --git a/pypy/module/micronumpy/arrayimpl/sort.py b/pypy/module/micronumpy/arrayimpl/sort.py --- a/pypy/module/micronumpy/arrayimpl/sort.py +++ b/pypy/module/micronumpy/arrayimpl/sort.py @@ -19,7 +19,6 @@ def make_sort_function(space, itemtype, comp_type, count=1): TP = itemtype.T step = rffi.sizeof(TP) - print itemtype class Repr(object): def __init__(self, index_stride_size, stride_size, size, values, @@ -164,7 +163,6 @@ all_types = (types.all_float_types) # + types.all_complex_types + # types.all_int_types) all_types = [i for i in all_types if not '_mixin_' in i[0].__dict__] -all_types = [i for i in all_types if not 'NonNative' in str(i[0])] all_types = unrolling_iterable(all_types) class SortCache(object): From noreply at buildbot.pypy.org Mon Feb 4 13:38:42 2013 From: noreply at buildbot.pypy.org (mattip) Date: Mon, 4 Feb 2013 13:38:42 +0100 (CET) Subject: [pypy-commit] pypy missing-ndarray-attributes: remove debug cruft Message-ID: <20130204123842.0501C1C1065@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: missing-ndarray-attributes Changeset: r60868:001aced635a1 Date: 2013-02-04 14:38 +0200 http://bitbucket.org/pypy/pypy/changeset/001aced635a1/ Log: remove debug cruft diff --git a/pypy/module/micronumpy/arrayimpl/sort.py b/pypy/module/micronumpy/arrayimpl/sort.py --- a/pypy/module/micronumpy/arrayimpl/sort.py +++ b/pypy/module/micronumpy/arrayimpl/sort.py @@ -160,8 +160,8 @@ space.wrap("sorting of non-numeric types " + \ "'%s' is not implemented" % arr.dtype.get_name(), )) -all_types = (types.all_float_types) # + types.all_complex_types + - # types.all_int_types) +all_types = (types.all_float_types + types.all_complex_types + + types.all_int_types) all_types = [i for i in all_types if not '_mixin_' in i[0].__dict__] all_types = unrolling_iterable(all_types) From noreply at buildbot.pypy.org Mon Feb 4 18:21:42 2013 From: noreply at buildbot.pypy.org (mattip) Date: Mon, 4 Feb 2013 18:21:42 +0100 (CET) Subject: [pypy-commit] pypy missing-ndarray-attributes: test that float16 is not argsortable, fix argsort for ints and complex Message-ID: <20130204172142.0A0BA1C047D@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: missing-ndarray-attributes Changeset: r60869:593666df7502 Date: 2013-02-04 19:21 +0200 http://bitbucket.org/pypy/pypy/changeset/593666df7502/ Log: test that float16 is not argsortable, fix argsort for ints and complex diff --git a/pypy/module/micronumpy/arrayimpl/sort.py b/pypy/module/micronumpy/arrayimpl/sort.py --- a/pypy/module/micronumpy/arrayimpl/sort.py +++ b/pypy/module/micronumpy/arrayimpl/sort.py @@ -8,6 +8,7 @@ from rpython.rlib.rawstorage import raw_storage_getitem, raw_storage_setitem, \ free_raw_storage, alloc_raw_storage from rpython.rlib.unroll import unrolling_iterable +from rpython.rlib.rarithmetic import intmask from rpython.rlib.objectmodel import specialize from pypy.interpreter.error import OperationError from pypy.module.micronumpy.base import W_NDimArray @@ -35,21 +36,20 @@ if count < 2: v = raw_storage_getitem(TP, self.values, item * self.stride_size + self.start) - if comp_type=='int': - v = int(v) - elif comp_type=='float': - v = float(v) - elif comp_type=='complex': - v = float(v[0]),float(v[1]) - else: - raise NotImplementedError('cannot reach') else: v = [] for i in range(count): _v = raw_storage_getitem(TP, self.values, item * self.stride_size + self.start + step * i) v.append(_v) - v = for_computation(v) + if comp_type=='int': + v = intmask(v) + elif comp_type=='float': + v = float(v) + elif comp_type=='complex': + v = [float(v[0]),float(v[1])] + else: + raise NotImplementedError('cannot reach') return (v, raw_storage_getitem(lltype.Signed, self.indexes, item * self.index_stride_size + self.index_start)) @@ -59,9 +59,11 @@ raw_storage_setitem(self.values, idx * self.stride_size + self.start, rffi.cast(TP, item[0])) else: - for i in range(count): + i = 0 + for val in item[0]: raw_storage_setitem(self.values, idx * self.stride_size + - self.start + i*step, rffi.cast(TP, item[0][i])) + self.start + i*step, rffi.cast(TP, val)) + i += 1 raw_storage_setitem(self.indexes, idx * self.index_stride_size + self.index_start, item[1]) @@ -94,9 +96,20 @@ for i in range(stop-start): retval.setitem(i, lst.getitem(i+start)) return retval - - def arg_lt(a, b): - return a[0] < b[0] + + if count < 2: + def arg_lt(a, b): + # Does numpy do <= ? + return a[0] < b[0] + else: + def arg_lt(a, b): + for i in range(count): + if a[0][i] < b[0][i]: + return True + elif a[0][i] > b[0][i]: + return False + # Does numpy do True? + return False ArgSort = make_timsort_class(arg_getitem, arg_setitem, arg_length, arg_getitem_slice, arg_lt) @@ -174,7 +187,7 @@ self.built = True cache = {} for cls, it in all_types._items: - if cls in types.all_complex_types: + if it == 'complex': cache[cls] = make_sort_function(space, cls, it, 2) else: cache[cls] = make_sort_function(space, cls, it) diff --git a/pypy/module/micronumpy/test/test_numarray.py b/pypy/module/micronumpy/test/test_numarray.py --- a/pypy/module/micronumpy/test/test_numarray.py +++ b/pypy/module/micronumpy/test/test_numarray.py @@ -2373,7 +2373,7 @@ from _numpypy import array, arange assert array(2.0).argsort() == 0 nnp = self.non_native_prefix - for dtype in ['int', 'float', 'int16', 'float32', 'float16', + for dtype in ['int', 'float', 'int16', 'float32', 'uint64', nnp + 'i2', complex]: a = array([6, 4, -1, 3, 8, 3, 256+20, 100, 101], dtype=dtype) c = a.copy() @@ -2383,6 +2383,7 @@ assert (a == c).all() # not modified a = arange(100) assert (a.argsort() == a).all() + raises(NotImplementedError, 'arange(10,dtype="float16").argsort()') def test_argsort_nd(self): from _numpypy import array From noreply at buildbot.pypy.org Mon Feb 4 18:24:15 2013 From: noreply at buildbot.pypy.org (mattip) Date: Mon, 4 Feb 2013 18:24:15 +0100 (CET) Subject: [pypy-commit] pypy missing-ndarray-attributes: reanable exception for PBC of mixin Message-ID: <20130204172415.C67211C047D@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: missing-ndarray-attributes Changeset: r60870:17baab38318a Date: 2013-02-04 19:23 +0200 http://bitbucket.org/pypy/pypy/changeset/17baab38318a/ Log: reanable exception for PBC of mixin diff --git a/rpython/annotator/bookkeeper.py b/rpython/annotator/bookkeeper.py --- a/rpython/annotator/bookkeeper.py +++ b/rpython/annotator/bookkeeper.py @@ -447,9 +447,9 @@ if (x is type(None) or # add cases here if needed x.__module__ == 'rpython.rtyper.lltypesystem.lltype'): result = SomeType() - #elif x.__dict__.get('_mixin_', False): - # raise Exception("Creating a PBC of a mixin class is " - # "not RPython for class %r" % x) + elif x.__dict__.get('_mixin_', False): + raise Exception("Creating a PBC of a mixin class is " + "not RPython for class %r" % x) else: result = SomePBC([self.getdesc(x)]) elif callable(x): From noreply at buildbot.pypy.org Mon Feb 4 21:13:41 2013 From: noreply at buildbot.pypy.org (fijal) Date: Mon, 4 Feb 2013 21:13:41 +0100 (CET) Subject: [pypy-commit] pypy missing-ndarray-attributes: PEP 8 Message-ID: <20130204201341.1E0D81C009B@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: missing-ndarray-attributes Changeset: r60871:e4169d00a88f Date: 2013-02-04 22:13 +0200 http://bitbucket.org/pypy/pypy/changeset/e4169d00a88f/ Log: PEP 8 diff --git a/pypy/module/micronumpy/arrayimpl/sort.py b/pypy/module/micronumpy/arrayimpl/sort.py --- a/pypy/module/micronumpy/arrayimpl/sort.py +++ b/pypy/module/micronumpy/arrayimpl/sort.py @@ -42,11 +42,11 @@ _v = raw_storage_getitem(TP, self.values, item * self.stride_size + self.start + step * i) v.append(_v) - if comp_type=='int': + if comp_type == 'int': v = intmask(v) - elif comp_type=='float': + elif comp_type == 'float': v = float(v) - elif comp_type=='complex': + elif comp_type == 'complex': v = [float(v[0]),float(v[1])] else: raise NotImplementedError('cannot reach') From noreply at buildbot.pypy.org Mon Feb 4 21:52:46 2013 From: noreply at buildbot.pypy.org (mattip) Date: Mon, 4 Feb 2013 21:52:46 +0100 (CET) Subject: [pypy-commit] pypy missing-ndarray-attributes: change socket type to socket s_type, 'type' should never be used as variable name Message-ID: <20130204205246.35AB01C0239@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: missing-ndarray-attributes Changeset: r60872:81d15ae6c6bc Date: 2013-02-04 20:50 +0200 http://bitbucket.org/pypy/pypy/changeset/81d15ae6c6bc/ Log: change socket type to socket s_type, 'type' should never be used as variable name diff --git a/pypy/module/_socket/interp_func.py b/pypy/module/_socket/interp_func.py --- a/pypy/module/_socket/interp_func.py +++ b/pypy/module/_socket/interp_func.py @@ -126,24 +126,24 @@ raise converted_error(space, e) return space.newtuple([space.wrap(host), space.wrap(servport)]) - at unwrap_spec(fd=int, family=int, type=int, proto=int) -def fromfd(space, fd, family, type, proto=0): - """fromfd(fd, family, type[, proto]) -> socket object + at unwrap_spec(fd=int, family=int, s_type=int, proto=int) +def fromfd(space, fd, family, s_type, proto=0): + """fromfd(fd, family, s_type[, proto]) -> socket object Create a socket object from the given file descriptor. The remaining arguments are the same as for socket(). """ try: - sock = rsocket.fromfd(fd, family, type, proto, W_RSocket) + sock = rsocket.fromfd(fd, family, s_type, proto, W_RSocket) except SocketError, e: raise converted_error(space, e) return space.wrap(sock) - at unwrap_spec(family=int, type=int, proto=int) + at unwrap_spec(family=int, s_type=int, proto=int) def socketpair(space, family=rsocket.socketpair_default_family, - type =rsocket.SOCK_STREAM, + s_type =rsocket.SOCK_STREAM, proto =0): - """socketpair([family[, type[, proto]]]) -> (socket object, socket object) + """socketpair([family[, s_type[, proto]]]) -> (socket object, socket object) Create a pair of socket objects from the sockets returned by the platform socketpair() function. @@ -151,7 +151,7 @@ AF_UNIX if defined on the platform; otherwise, the default is AF_INET. """ try: - sock1, sock2 = rsocket.socketpair(family, type, proto, W_RSocket) + sock1, sock2 = rsocket.socketpair(family, s_type, proto, W_RSocket) except SocketError, e: raise converted_error(space, e) return space.newtuple([space.wrap(sock1), space.wrap(sock2)]) diff --git a/pypy/module/_socket/interp_socket.py b/pypy/module/_socket/interp_socket.py --- a/pypy/module/_socket/interp_socket.py +++ b/pypy/module/_socket/interp_socket.py @@ -146,7 +146,7 @@ try: fd, addr = self.accept() sock = rsocket.make_socket( - fd, self.family, self.type, self.proto, W_RSocket) + fd, self.family, self.s_type, self.proto, W_RSocket) return space.newtuple([space.wrap(sock), addr_as_object(addr, sock.fd, space)]) except SocketError, e: @@ -540,16 +540,16 @@ return os.fdopen(newfd, mode, buffersize) ''', filename =__file__).interphook('makefile') - at unwrap_spec(family=int, type=int, proto=int) + at unwrap_spec(family=int, s_type=int, proto=int) def newsocket(space, w_subtype, family=AF_INET, - type=SOCK_STREAM, proto=0): - # XXX If we want to support subclassing the socket type we will need + s_type=SOCK_STREAM, proto=0): + # XXX If we want to support subclassing the socket s_type we will need # something along these lines. But allocate_instance is only defined # on the standard object space, so this is not really correct. #sock = space.allocate_instance(W_RSocket, w_subtype) - #Socket.__init__(sock, space, fd, family, type, proto) + #Socket.__init__(sock, space, fd, family, s_type, proto) try: - sock = W_RSocket(family, type, proto) + sock = W_RSocket(family, s_type, proto) except SocketError, e: raise converted_error(space, e) return space.wrap(sock) @@ -651,7 +651,7 @@ [*] not available on all platforms!""", __new__ = descr_socket_new, __weakref__ = make_weakref_descr(W_RSocket), - type = interp_attrproperty('type', W_RSocket), + s_type = interp_attrproperty('s_type', W_RSocket), proto = interp_attrproperty('proto', W_RSocket), family = interp_attrproperty('family', W_RSocket), ** socketmethods diff --git a/rpython/rlib/rsocket.py b/rpython/rlib/rsocket.py --- a/rpython/rlib/rsocket.py +++ b/rpython/rlib/rsocket.py @@ -480,17 +480,17 @@ """ _mixin_ = True # for interp_socket.py fd = _c.INVALID_SOCKET - def __init__(self, family=AF_INET, type=SOCK_STREAM, proto=0, + def __init__(self, family=AF_INET, s_type=SOCK_STREAM, proto=0, fd=_c.INVALID_SOCKET): """Create a new socket.""" if _c.invalid_socket(fd): - fd = _c.socket(family, type, proto) + fd = _c.socket(family, s_type, proto) if _c.invalid_socket(fd): raise self.error_handler() # PLAT RISCOS self.fd = fd self.family = family - self.type = type + self.s_type = s_type self.proto = proto self.timeout = defaults.timeout @@ -710,7 +710,7 @@ fd = _c.dup(self.fd) if fd < 0: raise self.error_handler() - return make_socket(fd, self.family, self.type, self.proto, + return make_socket(fd, self.family, self.s_type, self.proto, SocketClass=SocketClass) def getpeername(self): @@ -954,11 +954,11 @@ # ____________________________________________________________ -def make_socket(fd, family, type, proto, SocketClass=RSocket): +def make_socket(fd, family, s_type, proto, SocketClass=RSocket): result = instantiate(SocketClass) result.fd = fd result.family = family - result.type = type + result.s_type = s_type result.proto = proto result.timeout = defaults.timeout return result @@ -1025,9 +1025,9 @@ socketpair_default_family = AF_UNIX if hasattr(_c, 'socketpair'): - def socketpair(family=socketpair_default_family, type=SOCK_STREAM, proto=0, + def socketpair(family=socketpair_default_family, s_type=SOCK_STREAM, proto=0, SocketClass=RSocket): - """socketpair([family[, type[, proto]]]) -> (socket object, socket object) + """socketpair([family[, s_type[, proto]]]) -> (socket object, socket object) Create a pair of socket objects from the sockets returned by the platform socketpair() function. @@ -1035,14 +1035,14 @@ AF_UNIX if defined on the platform; otherwise, the default is AF_INET. """ result = lltype.malloc(_c.socketpair_t, 2, flavor='raw') - res = _c.socketpair(family, type, proto, result) + res = _c.socketpair(family, s_type, proto, result) if res < 0: raise last_error() fd0 = rffi.cast(lltype.Signed, result[0]) fd1 = rffi.cast(lltype.Signed, result[1]) lltype.free(result, flavor='raw') - return (make_socket(fd0, family, type, proto, SocketClass), - make_socket(fd1, family, type, proto, SocketClass)) + return (make_socket(fd0, family, s_type, proto, SocketClass), + make_socket(fd1, family, s_type, proto, SocketClass)) if _c.WIN32: def dup(fd): @@ -1059,12 +1059,12 @@ def dup(fd): return _c.dup(fd) - def fromfd(fd, family, type, proto=0, SocketClass=RSocket): + def fromfd(fd, family, s_type, proto=0, SocketClass=RSocket): # Dup the fd so it and the socket can be closed independently fd = _c.dup(fd) if fd < 0: raise last_error() - return make_socket(fd, family, type, proto, SocketClass) + return make_socket(fd, family, s_type, proto, SocketClass) def getdefaulttimeout(): return defaults.timeout From noreply at buildbot.pypy.org Mon Feb 4 21:52:47 2013 From: noreply at buildbot.pypy.org (mattip) Date: Mon, 4 Feb 2013 21:52:47 +0100 (CET) Subject: [pypy-commit] pypy missing-ndarray-attributes: never pass an RSocket class around, it is a mixin Message-ID: <20130204205247.8FE421C0239@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: missing-ndarray-attributes Changeset: r60873:e5ee474dc98a Date: 2013-02-04 22:51 +0200 http://bitbucket.org/pypy/pypy/changeset/e5ee474dc98a/ Log: never pass an RSocket class around, it is a mixin diff --git a/rpython/rlib/rsocket.py b/rpython/rlib/rsocket.py --- a/rpython/rlib/rsocket.py +++ b/rpython/rlib/rsocket.py @@ -704,14 +704,16 @@ return err if hasattr(_c, 'dup'): - def dup(self, SocketClass=None): - if SocketClass is None: - SocketClass = RSocket + def dup(self, SocketClass): + #def dup(self, SocketClass=None): + #if SocketClass is None: + # SocketClass = RSocket + # assert SocketClass is not None fd = _c.dup(self.fd) if fd < 0: raise self.error_handler() return make_socket(fd, self.family, self.s_type, self.proto, - SocketClass=SocketClass) + SocketClass) def getpeername(self): """Return the address of the remote endpoint.""" @@ -954,7 +956,7 @@ # ____________________________________________________________ -def make_socket(fd, family, s_type, proto, SocketClass=RSocket): +def make_socket(fd, family, s_type, proto, SocketClass): result = instantiate(SocketClass) result.fd = fd result.family = family From noreply at buildbot.pypy.org Mon Feb 4 21:52:48 2013 From: noreply at buildbot.pypy.org (mattip) Date: Mon, 4 Feb 2013 21:52:48 +0100 (CET) Subject: [pypy-commit] pypy missing-ndarray-attributes: merge heads Message-ID: <20130204205248.DF3C71C0239@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: missing-ndarray-attributes Changeset: r60874:68612418c26e Date: 2013-02-04 22:51 +0200 http://bitbucket.org/pypy/pypy/changeset/68612418c26e/ Log: merge heads diff --git a/pypy/module/micronumpy/arrayimpl/sort.py b/pypy/module/micronumpy/arrayimpl/sort.py --- a/pypy/module/micronumpy/arrayimpl/sort.py +++ b/pypy/module/micronumpy/arrayimpl/sort.py @@ -42,11 +42,11 @@ _v = raw_storage_getitem(TP, self.values, item * self.stride_size + self.start + step * i) v.append(_v) - if comp_type=='int': + if comp_type == 'int': v = intmask(v) - elif comp_type=='float': + elif comp_type == 'float': v = float(v) - elif comp_type=='complex': + elif comp_type == 'complex': v = [float(v[0]),float(v[1])] else: raise NotImplementedError('cannot reach') From noreply at buildbot.pypy.org Mon Feb 4 21:52:50 2013 From: noreply at buildbot.pypy.org (mattip) Date: Mon, 4 Feb 2013 21:52:50 +0100 (CET) Subject: [pypy-commit] pypy missing-ndarray-attributes: merge default into branch Message-ID: <20130204205250.336EE1C0239@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: missing-ndarray-attributes Changeset: r60875:f2ead9283d4f Date: 2013-02-04 22:52 +0200 http://bitbucket.org/pypy/pypy/changeset/f2ead9283d4f/ Log: merge default into branch diff --git a/pypy/interpreter/pytraceback.py b/pypy/interpreter/pytraceback.py --- a/pypy/interpreter/pytraceback.py +++ b/pypy/interpreter/pytraceback.py @@ -1,5 +1,6 @@ from pypy.interpreter import baseobjspace from pypy.interpreter.error import OperationError + from rpython.tool.error import offset2lineno @@ -27,10 +28,10 @@ def descr__reduce__(self, space): from pypy.interpreter.mixedmodule import MixedModule - w_mod = space.getbuiltinmodule('_pickle_support') - mod = space.interp_w(MixedModule, w_mod) + w_mod = space.getbuiltinmodule('_pickle_support') + mod = space.interp_w(MixedModule, w_mod) new_inst = mod.get('traceback_new') - w = space.wrap + w = space.wrap tup_base = [] tup_state = [ @@ -49,6 +50,7 @@ self.lasti = space.int_w(w_lasti) self.next = space.interp_w(PyTraceback, w_next, can_be_None=True) + def record_application_traceback(space, operror, frame, last_instruction): if frame.pycode.hidden_applevel: return @@ -56,10 +58,11 @@ tb = PyTraceback(space, frame, last_instruction, tb) operror.set_traceback(tb) + def check_traceback(space, w_tb, msg): from pypy.interpreter.typedef import PyTraceback tb = space.interpclass_w(w_tb) - if tb is None or not space.is_true(space.isinstance(tb, + if tb is None or not space.is_true(space.isinstance(tb, space.gettypeobject(PyTraceback.typedef))): raise OperationError(space.w_TypeError, space.wrap(msg)) return tb diff --git a/pypy/interpreter/typedef.py b/pypy/interpreter/typedef.py --- a/pypy/interpreter/typedef.py +++ b/pypy/interpreter/typedef.py @@ -1,18 +1,17 @@ -""" +import py - -""" -import py -from pypy.interpreter.gateway import interp2app, BuiltinCode, unwrap_spec,\ - WrappedDefault from pypy.interpreter.argument import Arguments from pypy.interpreter.baseobjspace import Wrappable, DescrMismatch from pypy.interpreter.error import OperationError, operationerrfmt +from pypy.interpreter.gateway import (interp2app, BuiltinCode, unwrap_spec, + WrappedDefault) + +from rpython.rlib.jit import promote +from rpython.rlib.objectmodel import compute_identity_hash, specialize from rpython.tool.sourcetools import compile2, func_with_new_name -from rpython.rlib.objectmodel import instantiate, compute_identity_hash, specialize -from rpython.rlib.jit import promote -class TypeDef: + +class TypeDef(object): def __init__(self, __name, __base=None, __total_ordering__=None, **rawdict): "NOT_RPYTHON: initialization-time only" self.name = __name @@ -27,7 +26,7 @@ self.weakrefable = '__weakref__' in rawdict self.doc = rawdict.pop('__doc__', None) for base in bases: - self.hasdict |= base.hasdict + self.hasdict |= base.hasdict self.weakrefable |= base.weakrefable self.rawdict = {} self.acceptable_as_base_class = '__new__' in rawdict @@ -426,7 +425,7 @@ return unknown_objclass_getter, cls miniglobals = {} if isinstance(cls, str): - assert cls.startswith('<'),"pythontype typecheck should begin with <" + assert cls.startswith('<'), "pythontype typecheck should begin with <" cls_name = cls[1:] typeexpr = "space.w_%s" % cls_name else: @@ -474,7 +473,7 @@ else: try: return self.fget(self, space, w_obj) - except DescrMismatch, e: + except DescrMismatch: return w_obj.descr_call_mismatch( space, '__getattribute__', self.reqcls, Arguments(space, [w_obj, @@ -489,7 +488,7 @@ space.wrap("readonly attribute")) try: fset(self, space, w_obj, w_value) - except DescrMismatch, e: + except DescrMismatch: w_obj.descr_call_mismatch( space, '__setattr__', self.reqcls, Arguments(space, [w_obj, @@ -505,7 +504,7 @@ space.wrap("cannot delete attribute")) try: fdel(self, space, w_obj) - except DescrMismatch, e: + except DescrMismatch: w_obj.descr_call_mismatch( space, '__delattr__', self.reqcls, Arguments(space, [w_obj, @@ -546,6 +545,7 @@ class Member(Wrappable): """For slots.""" _immutable_ = True + def __init__(self, index, name, w_cls): self.index = index self.name = name @@ -617,9 +617,8 @@ from pypy.interpreter.pyframe import PyFrame from pypy.interpreter.pyopcode import SuspendedUnroller from pypy.interpreter.module import Module -from pypy.interpreter.function import Function, Method, StaticMethod -from pypy.interpreter.function import ClassMethod -from pypy.interpreter.function import BuiltinFunction, descr_function_get +from pypy.interpreter.function import (Function, Method, StaticMethod, + ClassMethod, BuiltinFunction, descr_function_get) from pypy.interpreter.pytraceback import PyTraceback from pypy.interpreter.generator import GeneratorIterator from pypy.interpreter.nestedscope import Cell @@ -663,8 +662,10 @@ def fget_co_flags(space, code): # unwrapping through unwrap_spec sig = code.signature() flags = 0 - if sig.has_vararg(): flags |= CO_VARARGS - if sig.has_kwarg(): flags |= CO_VARKEYWORDS + if sig.has_vararg(): + flags |= CO_VARARGS + if sig.has_kwarg(): + flags |= CO_VARKEYWORDS return space.wrap(flags) def fget_co_consts(space, code): # unwrapping through unwrap_spec @@ -728,7 +729,7 @@ __eq__ = interp2app(PyCode.descr_code__eq__), __ne__ = descr_generic_ne, __hash__ = interp2app(PyCode.descr_code__hash__), - __reduce__ = interp2app(PyCode.descr__reduce__), + __reduce__ = interp2app(PyCode.descr__reduce__), __repr__ = interp2app(PyCode.repr), co_argcount = interp_attrproperty('co_argcount', cls=PyCode), co_nlocals = interp_attrproperty('co_nlocals', cls=PyCode), @@ -737,9 +738,9 @@ co_code = interp_attrproperty('co_code', cls=PyCode), co_consts = GetSetProperty(PyCode.fget_co_consts), co_names = GetSetProperty(PyCode.fget_co_names), - co_varnames = GetSetProperty(PyCode.fget_co_varnames), - co_freevars = GetSetProperty(PyCode.fget_co_freevars), - co_cellvars = GetSetProperty(PyCode.fget_co_cellvars), + co_varnames = GetSetProperty(PyCode.fget_co_varnames), + co_freevars = GetSetProperty(PyCode.fget_co_freevars), + co_cellvars = GetSetProperty(PyCode.fget_co_cellvars), co_filename = interp_attrproperty('co_filename', cls=PyCode), co_name = interp_attrproperty('co_name', cls=PyCode), co_firstlineno = interp_attrproperty('co_firstlineno', cls=PyCode), @@ -749,7 +750,7 @@ PyCode.typedef.acceptable_as_base_class = False PyFrame.typedef = TypeDef('frame', - __reduce__ = interp2app(PyFrame.descr__reduce__), + __reduce__ = interp2app(PyFrame.descr__reduce__), __setstate__ = interp2app(PyFrame.descr__setstate__), f_builtins = GetSetProperty(PyFrame.fget_f_builtins), f_lineno = GetSetProperty(PyFrame.fget_f_lineno, PyFrame.fset_f_lineno), @@ -827,9 +828,9 @@ __new__ = interp2app(Method.descr_method__new__.im_func), __call__ = interp2app(Method.descr_method_call), __get__ = interp2app(Method.descr_method_get), - im_func = interp_attrproperty_w('w_function', cls=Method), + im_func = interp_attrproperty_w('w_function', cls=Method), __func__ = interp_attrproperty_w('w_function', cls=Method), - im_self = interp_attrproperty_w('w_instance', cls=Method), + im_self = interp_attrproperty_w('w_instance', cls=Method), __self__ = interp_attrproperty_w('w_instance', cls=Method), im_class = interp_attrproperty_w('w_class', cls=Method), __getattribute__ = interp2app(Method.descr_method_getattribute), @@ -886,7 +887,7 @@ def always_none(self, obj): return None -BuiltinFunction.typedef = TypeDef("builtin_function",**Function.typedef.rawdict) +BuiltinFunction.typedef = TypeDef("builtin_function", **Function.typedef.rawdict) BuiltinFunction.typedef.rawdict.update({ '__new__': interp2app(BuiltinFunction.descr_builtinfunction__new__.im_func), '__self__': GetSetProperty(always_none, cls=BuiltinFunction), @@ -897,12 +898,12 @@ BuiltinFunction.typedef.acceptable_as_base_class = False PyTraceback.typedef = TypeDef("traceback", - __reduce__ = interp2app(PyTraceback.descr__reduce__), + __reduce__ = interp2app(PyTraceback.descr__reduce__), __setstate__ = interp2app(PyTraceback.descr__setstate__), - tb_frame = interp_attrproperty('frame', cls=PyTraceback), - tb_lasti = interp_attrproperty('lasti', cls=PyTraceback), + tb_frame = interp_attrproperty('frame', cls=PyTraceback), + tb_lasti = interp_attrproperty('lasti', cls=PyTraceback), tb_lineno = GetSetProperty(PyTraceback.descr_tb_lineno), - tb_next = interp_attrproperty('next', cls=PyTraceback), + tb_next = interp_attrproperty('next', cls=PyTraceback), ) PyTraceback.typedef.acceptable_as_base_class = False @@ -937,12 +938,12 @@ Cell.typedef.acceptable_as_base_class = False Ellipsis.typedef = TypeDef("Ellipsis", - __repr__ = interp2app(Ellipsis.descr__repr__), + __repr__ = interp2app(Ellipsis.descr__repr__), ) Ellipsis.typedef.acceptable_as_base_class = False NotImplemented.typedef = TypeDef("NotImplemented", - __repr__ = interp2app(NotImplemented.descr__repr__), + __repr__ = interp2app(NotImplemented.descr__repr__), ) NotImplemented.typedef.acceptable_as_base_class = False diff --git a/pypy/objspace/std/typeobject.py b/pypy/objspace/std/typeobject.py --- a/pypy/objspace/std/typeobject.py +++ b/pypy/objspace/std/typeobject.py @@ -1,24 +1,23 @@ +from pypy.interpreter import gateway +from pypy.interpreter.baseobjspace import W_Root +from pypy.interpreter.error import OperationError, operationerrfmt +from pypy.interpreter.function import Function, StaticMethod +from pypy.interpreter.typedef import weakref_descr from pypy.objspace.std.model import W_Object from pypy.objspace.std.register_all import register_all -from pypy.interpreter.function import Function, StaticMethod -from pypy.interpreter import gateway -from pypy.interpreter.error import OperationError, operationerrfmt -from pypy.interpreter.typedef import weakref_descr -from pypy.interpreter.baseobjspace import W_Root from pypy.objspace.std.stdtypedef import std_dict_descr, issubtypedef, Member -from pypy.objspace.std.objecttype import object_typedef -from pypy.objspace.std import identitydict -from rpython.rlib.objectmodel import we_are_translated + +from rpython.rlib.jit import (promote, elidable_promote, we_are_jitted, + promote_string, elidable, dont_look_inside, unroll_safe) from rpython.rlib.objectmodel import current_object_addr_as_int, compute_hash -from rpython.rlib.jit import promote, elidable_promote, we_are_jitted,\ - promote_string -from rpython.rlib.jit import elidable, dont_look_inside, unroll_safe from rpython.rlib.rarithmetic import intmask, r_uint + class TypeCell(W_Root): def __init__(self, w_value=None): self.w_value = w_value + def unwrap_cell(space, w_value): if (space.config.objspace.std.withtypeversion and isinstance(w_value, TypeCell)): @@ -278,7 +277,7 @@ if attr in w_self.lazyloaders: # very clever next line: it forces the attr string # to be interned. - w_attr = space.new_interned_str(attr) + space.new_interned_str(attr) loader = w_self.lazyloaders[attr] del w_self.lazyloaders[attr] w_value = loader() @@ -497,7 +496,7 @@ def get_module(w_self): space = w_self.space - if w_self.is_heaptype() and '__module__' in w_self.dict_w: + if w_self.is_heaptype() and w_self.getdictvalue(space, '__module__') is not None: return w_self.getdictvalue(space, '__module__') else: # for non-heap types, CPython checks for a module.name in the @@ -516,7 +515,7 @@ mod = '__builtin__' else: mod = space.str_w(w_mod) - if mod !='__builtin__': + if mod != '__builtin__': return '%s.%s' % (mod, w_self.name) else: return w_self.name @@ -560,13 +559,15 @@ subclasses_w.append(w_ob) return subclasses_w - # for now, weakref support for W_TypeObject is hard to get automatically _lifeline_ = None + def getweakref(self): return self._lifeline_ + def setweakref(self, space, weakreflifeline): self._lifeline_ = weakreflifeline + def delweakref(self): self._lifeline_ = None @@ -693,9 +694,12 @@ else: create_slot(w_self, slot_name) wantdict = wantdict or hasoldstylebase - if wantdict: create_dict_slot(w_self) - if wantweakref: create_weakref_slot(w_self) - if '__del__' in dict_w: w_self.needsdel = True + if wantdict: + create_dict_slot(w_self) + if wantweakref: + create_weakref_slot(w_self) + if '__del__' in dict_w: + w_self.needsdel = True def create_slot(w_self, slot_name): space = w_self.space @@ -868,7 +872,7 @@ kind = 'type' else: kind = 'class' - if mod is not None and mod !='__builtin__': + if mod is not None and mod != '__builtin__': return space.wrap("<%s '%s.%s'>" % (kind, mod, w_obj.name)) else: return space.wrap("<%s '%s'>" % (kind, w_obj.name)) @@ -887,7 +891,7 @@ # __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) + return space.get(w_descr, w_type) raise operationerrfmt(space.w_AttributeError, "type object '%s' has no attribute '%s'", w_type.name, name) @@ -933,7 +937,7 @@ return mro_error(space, orderlists) # no candidate found assert candidate not in order order.append(candidate) - for i in range(len(orderlists)-1, -1, -1): + for i in range(len(orderlists) - 1, -1, -1): if orderlists[i][0] is candidate: del orderlists[i][0] if len(orderlists[i]) == 0: diff --git a/pypy/objspace/std/typetype.py b/pypy/objspace/std/typetype.py --- a/pypy/objspace/std/typetype.py +++ b/pypy/objspace/std/typetype.py @@ -1,5 +1,4 @@ from pypy.interpreter import gateway -from pypy.interpreter.argument import Arguments from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.typedef import (GetSetProperty, descr_get_dict, weakref_descr) @@ -90,9 +89,9 @@ return space.wrap(w_type.name) def descr_set__name__(space, w_type, w_value): - w_type = _check(space, w_type) + w_type = _check(space, w_type) if not w_type.is_heaptype(): - raise operationerrfmt(space.w_TypeError, + raise operationerrfmt(space.w_TypeError, "can't set %s.__name__", w_type.name) w_type.name = space.str_w(w_value) @@ -119,10 +118,9 @@ def descr_set__bases__(space, w_type, w_value): # this assumes all app-level type objects are W_TypeObject - from pypy.objspace.std.typeobject import W_TypeObject - from pypy.objspace.std.typeobject import check_and_find_best_base - from pypy.objspace.std.typeobject import get_parent_layout - from pypy.objspace.std.typeobject import is_mro_purely_of_types + from pypy.objspace.std.typeobject import (W_TypeObject, get_parent_layout, + check_and_find_best_base, is_mro_purely_of_types) + w_type = _check(space, w_type) if not w_type.is_heaptype(): raise operationerrfmt(space.w_TypeError, @@ -213,9 +211,12 @@ # w_type = _check(space, w_type) flags = 0 - if w_type.flag_heaptype: flags |= _HEAPTYPE - if w_type.flag_cpytype: flags |= _CPYTYPE - if w_type.flag_abstract: flags |= _ABSTRACT + if w_type.flag_heaptype: + flags |= _HEAPTYPE + if w_type.flag_cpytype: + flags |= _CPYTYPE + if w_type.flag_abstract: + flags |= _ABSTRACT return space.wrap(flags) def descr_get__module(space, w_type): From noreply at buildbot.pypy.org Mon Feb 4 22:13:04 2013 From: noreply at buildbot.pypy.org (mattip) Date: Mon, 4 Feb 2013 22:13:04 +0100 (CET) Subject: [pypy-commit] pypy missing-ndarray-attributes: Backed out changeset: e5ee474dc98a - not related to this branch Message-ID: <20130204211304.4475A1C009B@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: missing-ndarray-attributes Changeset: r60876:c5931fbe51ca Date: 2013-02-04 23:10 +0200 http://bitbucket.org/pypy/pypy/changeset/c5931fbe51ca/ Log: Backed out changeset: e5ee474dc98a - not related to this branch diff --git a/rpython/rlib/rsocket.py b/rpython/rlib/rsocket.py --- a/rpython/rlib/rsocket.py +++ b/rpython/rlib/rsocket.py @@ -704,16 +704,14 @@ return err if hasattr(_c, 'dup'): - def dup(self, SocketClass): - #def dup(self, SocketClass=None): - #if SocketClass is None: - # SocketClass = RSocket - # assert SocketClass is not None + def dup(self, SocketClass=None): + if SocketClass is None: + SocketClass = RSocket fd = _c.dup(self.fd) if fd < 0: raise self.error_handler() return make_socket(fd, self.family, self.s_type, self.proto, - SocketClass) + SocketClass=SocketClass) def getpeername(self): """Return the address of the remote endpoint.""" @@ -956,7 +954,7 @@ # ____________________________________________________________ -def make_socket(fd, family, s_type, proto, SocketClass): +def make_socket(fd, family, s_type, proto, SocketClass=RSocket): result = instantiate(SocketClass) result.fd = fd result.family = family From noreply at buildbot.pypy.org Mon Feb 4 22:13:05 2013 From: noreply at buildbot.pypy.org (mattip) Date: Mon, 4 Feb 2013 22:13:05 +0100 (CET) Subject: [pypy-commit] pypy missing-ndarray-attributes: Backed out changeset: 81d15ae6c6bc - not related to this branch Message-ID: <20130204211305.8FFF21C009B@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: missing-ndarray-attributes Changeset: r60877:4ea6a2f41001 Date: 2013-02-04 23:11 +0200 http://bitbucket.org/pypy/pypy/changeset/4ea6a2f41001/ Log: Backed out changeset: 81d15ae6c6bc - not related to this branch diff --git a/pypy/module/_socket/interp_func.py b/pypy/module/_socket/interp_func.py --- a/pypy/module/_socket/interp_func.py +++ b/pypy/module/_socket/interp_func.py @@ -126,24 +126,24 @@ raise converted_error(space, e) return space.newtuple([space.wrap(host), space.wrap(servport)]) - at unwrap_spec(fd=int, family=int, s_type=int, proto=int) -def fromfd(space, fd, family, s_type, proto=0): - """fromfd(fd, family, s_type[, proto]) -> socket object + at unwrap_spec(fd=int, family=int, type=int, proto=int) +def fromfd(space, fd, family, type, proto=0): + """fromfd(fd, family, type[, proto]) -> socket object Create a socket object from the given file descriptor. The remaining arguments are the same as for socket(). """ try: - sock = rsocket.fromfd(fd, family, s_type, proto, W_RSocket) + sock = rsocket.fromfd(fd, family, type, proto, W_RSocket) except SocketError, e: raise converted_error(space, e) return space.wrap(sock) - at unwrap_spec(family=int, s_type=int, proto=int) + at unwrap_spec(family=int, type=int, proto=int) def socketpair(space, family=rsocket.socketpair_default_family, - s_type =rsocket.SOCK_STREAM, + type =rsocket.SOCK_STREAM, proto =0): - """socketpair([family[, s_type[, proto]]]) -> (socket object, socket object) + """socketpair([family[, type[, proto]]]) -> (socket object, socket object) Create a pair of socket objects from the sockets returned by the platform socketpair() function. @@ -151,7 +151,7 @@ AF_UNIX if defined on the platform; otherwise, the default is AF_INET. """ try: - sock1, sock2 = rsocket.socketpair(family, s_type, proto, W_RSocket) + sock1, sock2 = rsocket.socketpair(family, type, proto, W_RSocket) except SocketError, e: raise converted_error(space, e) return space.newtuple([space.wrap(sock1), space.wrap(sock2)]) diff --git a/pypy/module/_socket/interp_socket.py b/pypy/module/_socket/interp_socket.py --- a/pypy/module/_socket/interp_socket.py +++ b/pypy/module/_socket/interp_socket.py @@ -146,7 +146,7 @@ try: fd, addr = self.accept() sock = rsocket.make_socket( - fd, self.family, self.s_type, self.proto, W_RSocket) + fd, self.family, self.type, self.proto, W_RSocket) return space.newtuple([space.wrap(sock), addr_as_object(addr, sock.fd, space)]) except SocketError, e: @@ -540,16 +540,16 @@ return os.fdopen(newfd, mode, buffersize) ''', filename =__file__).interphook('makefile') - at unwrap_spec(family=int, s_type=int, proto=int) + at unwrap_spec(family=int, type=int, proto=int) def newsocket(space, w_subtype, family=AF_INET, - s_type=SOCK_STREAM, proto=0): - # XXX If we want to support subclassing the socket s_type we will need + type=SOCK_STREAM, proto=0): + # XXX If we want to support subclassing the socket type we will need # something along these lines. But allocate_instance is only defined # on the standard object space, so this is not really correct. #sock = space.allocate_instance(W_RSocket, w_subtype) - #Socket.__init__(sock, space, fd, family, s_type, proto) + #Socket.__init__(sock, space, fd, family, type, proto) try: - sock = W_RSocket(family, s_type, proto) + sock = W_RSocket(family, type, proto) except SocketError, e: raise converted_error(space, e) return space.wrap(sock) @@ -651,7 +651,7 @@ [*] not available on all platforms!""", __new__ = descr_socket_new, __weakref__ = make_weakref_descr(W_RSocket), - s_type = interp_attrproperty('s_type', W_RSocket), + type = interp_attrproperty('type', W_RSocket), proto = interp_attrproperty('proto', W_RSocket), family = interp_attrproperty('family', W_RSocket), ** socketmethods diff --git a/rpython/rlib/rsocket.py b/rpython/rlib/rsocket.py --- a/rpython/rlib/rsocket.py +++ b/rpython/rlib/rsocket.py @@ -480,17 +480,17 @@ """ _mixin_ = True # for interp_socket.py fd = _c.INVALID_SOCKET - def __init__(self, family=AF_INET, s_type=SOCK_STREAM, proto=0, + def __init__(self, family=AF_INET, type=SOCK_STREAM, proto=0, fd=_c.INVALID_SOCKET): """Create a new socket.""" if _c.invalid_socket(fd): - fd = _c.socket(family, s_type, proto) + fd = _c.socket(family, type, proto) if _c.invalid_socket(fd): raise self.error_handler() # PLAT RISCOS self.fd = fd self.family = family - self.s_type = s_type + self.type = type self.proto = proto self.timeout = defaults.timeout @@ -710,7 +710,7 @@ fd = _c.dup(self.fd) if fd < 0: raise self.error_handler() - return make_socket(fd, self.family, self.s_type, self.proto, + return make_socket(fd, self.family, self.type, self.proto, SocketClass=SocketClass) def getpeername(self): @@ -954,11 +954,11 @@ # ____________________________________________________________ -def make_socket(fd, family, s_type, proto, SocketClass=RSocket): +def make_socket(fd, family, type, proto, SocketClass=RSocket): result = instantiate(SocketClass) result.fd = fd result.family = family - result.s_type = s_type + result.type = type result.proto = proto result.timeout = defaults.timeout return result @@ -1025,9 +1025,9 @@ socketpair_default_family = AF_UNIX if hasattr(_c, 'socketpair'): - def socketpair(family=socketpair_default_family, s_type=SOCK_STREAM, proto=0, + def socketpair(family=socketpair_default_family, type=SOCK_STREAM, proto=0, SocketClass=RSocket): - """socketpair([family[, s_type[, proto]]]) -> (socket object, socket object) + """socketpair([family[, type[, proto]]]) -> (socket object, socket object) Create a pair of socket objects from the sockets returned by the platform socketpair() function. @@ -1035,14 +1035,14 @@ AF_UNIX if defined on the platform; otherwise, the default is AF_INET. """ result = lltype.malloc(_c.socketpair_t, 2, flavor='raw') - res = _c.socketpair(family, s_type, proto, result) + res = _c.socketpair(family, type, proto, result) if res < 0: raise last_error() fd0 = rffi.cast(lltype.Signed, result[0]) fd1 = rffi.cast(lltype.Signed, result[1]) lltype.free(result, flavor='raw') - return (make_socket(fd0, family, s_type, proto, SocketClass), - make_socket(fd1, family, s_type, proto, SocketClass)) + return (make_socket(fd0, family, type, proto, SocketClass), + make_socket(fd1, family, type, proto, SocketClass)) if _c.WIN32: def dup(fd): @@ -1059,12 +1059,12 @@ def dup(fd): return _c.dup(fd) - def fromfd(fd, family, s_type, proto=0, SocketClass=RSocket): + def fromfd(fd, family, type, proto=0, SocketClass=RSocket): # Dup the fd so it and the socket can be closed independently fd = _c.dup(fd) if fd < 0: raise last_error() - return make_socket(fd, family, s_type, proto, SocketClass) + return make_socket(fd, family, type, proto, SocketClass) def getdefaulttimeout(): return defaults.timeout From noreply at buildbot.pypy.org Mon Feb 4 22:13:06 2013 From: noreply at buildbot.pypy.org (mattip) Date: Mon, 4 Feb 2013 22:13:06 +0100 (CET) Subject: [pypy-commit] pypy missing-ndarray-attributes: Backed out changeset: 17baab38318a - not related to this branch Message-ID: <20130204211306.C556E1C009B@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: missing-ndarray-attributes Changeset: r60878:f107e08335aa Date: 2013-02-04 23:12 +0200 http://bitbucket.org/pypy/pypy/changeset/f107e08335aa/ Log: Backed out changeset: 17baab38318a - not related to this branch diff --git a/rpython/annotator/bookkeeper.py b/rpython/annotator/bookkeeper.py --- a/rpython/annotator/bookkeeper.py +++ b/rpython/annotator/bookkeeper.py @@ -447,9 +447,9 @@ if (x is type(None) or # add cases here if needed x.__module__ == 'rpython.rtyper.lltypesystem.lltype'): result = SomeType() - elif x.__dict__.get('_mixin_', False): - raise Exception("Creating a PBC of a mixin class is " - "not RPython for class %r" % x) + #elif x.__dict__.get('_mixin_', False): + # raise Exception("Creating a PBC of a mixin class is " + # "not RPython for class %r" % x) else: result = SomePBC([self.getdesc(x)]) elif callable(x): From noreply at buildbot.pypy.org Mon Feb 4 22:30:03 2013 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 4 Feb 2013 22:30:03 +0100 (CET) Subject: [pypy-commit] pypy default: Add an error message on translating locals() which points people to the Message-ID: <20130204213003.640361C0183@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r60879:2c31a396f622 Date: 2013-02-04 22:29 +0100 http://bitbucket.org/pypy/pypy/changeset/2c31a396f622/ Log: Add an error message on translating locals() which points people to the right direction, after a discussion on #pypy where people complained about doing something more automatically. diff --git a/rpython/flowspace/specialcase.py b/rpython/flowspace/specialcase.py --- a/rpython/flowspace/specialcase.py +++ b/rpython/flowspace/specialcase.py @@ -65,8 +65,18 @@ def sc_we_are_translated(space, we_are_translated, args): return Constant(True) +def sc_locals(space, locals, args): + raise Exception( + "A function calling locals() is not RPython. " + "Note that if you're translating code outside the PyPy " + "repository, a likely cause is that py.test's --assert=rewrite " + "mode is getting in the way. You should copy the file " + "pytest.ini from the root of the PyPy repository into your " + "own project.") + SPECIAL_CASES = {__import__: sc_import, r_uint: sc_r_uint, - we_are_translated: sc_we_are_translated} + we_are_translated: sc_we_are_translated, + locals: sc_locals} for fn in OperationName: SPECIAL_CASES[fn] = sc_operator From noreply at buildbot.pypy.org Mon Feb 4 22:43:12 2013 From: noreply at buildbot.pypy.org (hakanardo) Date: Mon, 4 Feb 2013 22:43:12 +0100 (CET) Subject: [pypy-commit] pypy jit-usable_retrace_3: allow more compilcated datastructures to be formed Message-ID: <20130204214312.8BAD91C0183@cobra.cs.uni-duesseldorf.de> Author: Hakan Ardo Branch: jit-usable_retrace_3 Changeset: r60880:e69dd4c61c91 Date: 2013-02-04 22:39 +0100 http://bitbucket.org/pypy/pypy/changeset/e69dd4c61c91/ Log: allow more compilcated datastructures to be formed diff --git a/pypy/jit/metainterp/test/test_random_loops.py b/pypy/jit/metainterp/test/test_random_loops.py --- a/pypy/jit/metainterp/test/test_random_loops.py +++ b/pypy/jit/metainterp/test/test_random_loops.py @@ -1,5 +1,5 @@ from pypy.jit.metainterp.test.support import LLJitMixin -from pypy.rlib.jit import JitDriver +from pypy.rlib.jit import JitDriver, unroll_safe from random import choice, randrange from pypy.rlib.rarithmetic import ovfcheck import re @@ -10,6 +10,8 @@ def value(self): return self.val + + final_value = value def add(self, other): try: @@ -32,6 +34,65 @@ def eq(self, other): return IntBox(self.value() == other.value()) + def set_left(self, val): + self.val = val.value() + + def set_right(self, val): + self.val = val.value() + + def get_right(self): + return self + + def get_left(self): + return self + +class PairBox(IntBox): + def __init__(self, left, right): + self.left = left + self.right = right + self._inlist = False + + def final_value(self): + sa = i = 0 + all_nodes = [self] + while i < len(all_nodes): + node = all_nodes[i] + i += 1 + if isinstance(node, PairBox): + if node._inlist: + continue + node._inlist = True + all_nodes.append(node.left) + all_nodes.append(node.right) + else: + sa ^= node.value() + for node in all_nodes: + if isinstance(node, PairBox): + node._inlist = False + return sa + + @unroll_safe + def value(self): + node = self + for i in xrange(5): + if isinstance(node, PairBox): + node = node.left + else: + return node.value() + return 0 + + def set_left(self, val): + self.left = val + + def set_right(self, val): + self.right = val + + def get_right(self): + return self.right + + def get_left(self): + return self.left + class UnknonwOpCode(Exception): pass @@ -120,12 +181,22 @@ pc += offsets[pc] elif op == ')': value = IntBox(0) + elif op == 'P': + value = PairBox(prev, value) + elif op == 'l': + value = value.get_left() + elif op == 'r': + value = value.get_right() + elif op == 'L': + prev.set_left(value) + elif op == 'R': + prev.set_right(value) else: raise UnknonwOpCode prev = current pc += 1 - return a.value(), b.value(), c.value(), d.value(), e.value() + return a.final_value(), b.final_value(), c.final_value(), d.final_value(), e.final_value() obj = interpreter(*args) expected = {'a': obj[0], 'b': obj[1], 'c': obj[2], 'd': obj[3], 'e': obj[4]} @@ -160,13 +231,19 @@ return choice([self.variable, self.constant])() def binop(self): - return self.value() + self.value() + choice('+-') + self.variable().upper() + return self.value() + self.value() + choice('+-P') + self.variable().upper() def break_loop(self): return 'x' def compare(self): return self.value() + self.value() + choice('<>=') + + def setitem(self): + return self.value() + self.variable() + choice('LR') + + def getitem(self): + return self.variable() + choice('lr') + self.variable().uppder() def while_loop(self): self.levels -= 1 @@ -233,6 +310,20 @@ def test_overflow(self): self.check('9A{aa+A}', max_back_jumps=100) self.check('09-A{aa+A}', max_back_jumps=100) + + def test_pair(self): + self.check('12PA', a=3) + self.check('12PAa1R', a=0) + self.check('12PAa2L', a=0) + self.check('12PAalBarC', a=3, b=1, c=2) + self.check('12PA3Bab+EelCerD', a=3, b=3, c=4, d=4) + self.check('12PA3Bab-EelCerD', a=3, b=3, c=-2, d=-2) + + def test_recursive_pair(self): + self.check('12PAaaR3Bab+Caa+DaE', a=1, b=3, c=4, d=2, e=1) + + def test_huge_pair(self): + self.check('1A{1BabPAa()}', max_back_jumps=1000, a=1) def test_failure1(self): self.check('{{7d<(37>(c6-A{a6>n(x)5b<()(bb+Bea-A){7d>n(x)1e+A7d-B3d+E35+Eac-B2b<(04+Cxe8+D9d+C)(){c6n(x)a5=(2c+E)(xxe9-A)ec>(b7-A40+Ce0-Cx06-A)(xc0-Ad2-A1e+B0d+Bx09+B0b-D)}be-Ab7=(3a+Ab7-Dde<(x))(ec+Cd4+D5d<(x10+A)(cb-Cb9-C))59<(2b-C00-Ab0<(bc-Bde+Bxa2-E4d+A))(e7+Eb3<(c4-Bxx)59-C7c+Aa8>(96-Exce+D3e-Ex)db+A76-Cdb-Bdc=(2b-A))}d2+D)(27-C26+B39+A9d+Bcc+Dab+Cdd=(ae+Eee-Ex{5d>n(x)}d0<(2a+C41+Dca+C6a>(47-Ae9-Eb7+Cx60+D63-C)bb+D9e+Ec5=(d2-Cxaa-D84-Ced+B20+A4c+B)65+A59-E)ed<(cd+B{a8=n(x)ed+Bxxd8+A}ba-D{66=n(x)a4+D30+Acd+C1c+A6c+Ac7-Dxc0+B}x)4b-Dx)e4-D{aa=n(x)44-Eac>(3e+Aae+A12<(a4-A)99<(ce-C4a+A7b+Dxdd+E)(c5+A10-D63-Eda-E22-E85+Dea+E)x)ed+Dbb=(e5-A9e-C)(x{can(x)}e5+Ba5+B}c9=()c0=(7b-Ae1+Daa+Aed+C)(91-C))3d=(a2>(1e-Cba=(2c-A)21+C6b>(aa-Bxd5-Bc7-E)ab<(8c-Ba8-Cxea-D4e+Ae8+Dc5+Ade+B)x33+B5a-C17+D)2a+B{ebn(x)x6a+Cb4+A27-Eab-C35-E25+B1d+C}cc+Aae-D}cc+C61-C68-D)(xe4>(e4+Db4-Cxdb=(xc7-Bcd-Bde-A00+A39+E9c+Dc9+B24-B){2b>n(x)x4d+E8d+Dbb+Ce7-Bxea+B54+A}80-A43<(89-B)(1c+Cx7b+Ae2+E02-C84+Exd0+A))(3d+Eb3-Ecd-A{8c=n(x)37-Bb0+Axxee+C11-C2c-De6-D46+D}cb+E)84+B05-Cbd+D)ad>(b6-C7d+Ae4-B4a+E)34-Cx9a=({c4>n(x)dd+B72<(a9+A)(b0-Db8-Dac-Bba-Excb+Ce2+Bx)ba-Bda+Cce-Cx}78+E97=(aa+Dx67+Dbc+B{de>n(x)b8-C14-Cx})c4+Cac+Ex80+C))xca=({55(de+Ax)da-B{d6>n(x)8d+A36-Bx8d-Bx49+Bbc-D88+Bx}x26-Da7-E)({9c>n(x)}bc<(0a-Cx61+Cce+A54-Ce7+A21-C9d+D)(6d-E)x{7e=n(x)6d-Ce6-Cx}5c>(bd+Ed5+Cc0-Dc2+C93-B)x69>(d9-Ac8+B8c-Dx94-E76+Ax)(ba+D)b6>(bb+Ebb-A5e+Bc3-D6c-E))54>(95+B46-D{15(xb6+Ec6-Aac-Bxc2-Ax99-C))b0-E58>(x0e+Bxa4+D5e>(7e-Dde-B1c+Bba-B8a-D)(35-Cce-C4c-C90-C1e+B9a+Be7+C1d-E)45>(xb9+A91+Ecc-Aac-B91+Cd1-De3+Ddd-B)c0+A0a>(45+Cbd+Bdc+Db4-D7c+C29+A7a+B60+A))(5d>(xx6e-Dxea+C)(c2-Cad+D36-Cx)61+E20-C9e-Cc2+Cce+Ad0+B{4b=n(x)})x{a1=n(x)e8<(x35-Dd3-Bd6-Bea+Eac-Acc+B79+Eaa-C)}x)xc7>(6b-C{57>n(x)e2>(1a+A97+Dxcc-E7b+A5d-B82+C2b-B)0a+Be1-Cbc+Ca2-E01+B{41>n(x)e1+Dc6+B47+Beb+Ac2+Bxab+D}}d3-D0e+E0d+Bae=(c7+Ce3-Bc3<(d2+E68+Bbc-Cdc+B1b-Ea2-Ac8-E)45-B43+Aac-E)xbe+C)dc=({ee>n(x)a4-Axd2+B1b+B}aa+Exxxb4>()(cb-C{4d(a0-Dab+A8c+Ddd-Edc+A)(xce-D)de=(d6+E83+Cxxc6-Axx)(0b+D78+Cx07-Eda+Ax1d-Eba+A)e6+E)de-E1c+Aae=(20-B25+Dba>(xxx71-A2b+Dc7+E){e9=n(x)7b+Ecd+Bda-Eec-A4b+De7-Ae3-D}ae+C7c+Aaa+Bx)86+B)}{cc=n(x)6b-B{cd(cc+D7e-Bc0+Bxde-A2c-B5d-C)(ba+D2b-Axxx07+Ca4-C)eb-C23-D7e<(xb8+Edd-De1+Add+C35-Dxx)x)(87-Ccc+Ee2=(9a-E78-C)()cb-A)39+D0b-Aa4>(ca+A)c6=({9c(bb-E22-D)x5e-C11<()9b=(6d-Bcd+A9e-E2a-E38+B4e-C)xaa-B{82=n(x)ae-B6a-Ab7+Ca9-A}08+C)d7+Cxcb-A}6c-B9c+D9c-E})3d+Cd4>(xab<()()3e+Ebd-Ba0-B{6c(63+Eb5+Bxec<(a1+E4e+Axdc-C)ea+Eaa=(x37-Edd-Cb4+B)(43-Ae0-Bx7e-C94+A)e8-Bd1-Da8-D)())(ce=(6c-B10+C7a+A3d+Ax19+Aca+B)(ed+A)1d>()d1+Ex43+A9d+Eb5+A)}8d+Ae9-C)(3d-D6c+Ee9<(29-C4c=({e9(4c+B)8a-Dc0-E82+E50+D}a1+D98=(be-B)3a-Ae9+De2-Add-E)35-D}}', [13, 40, 35, 44, 76], 1000) From noreply at buildbot.pypy.org Tue Feb 5 00:36:19 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Tue, 5 Feb 2013 00:36:19 +0100 (CET) Subject: [pypy-commit] pypy py3k: merge default Message-ID: <20130204233619.0A0E61C02AF@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r60881:2b5161e7db07 Date: 2013-02-04 15:35 -0800 http://bitbucket.org/pypy/pypy/changeset/2b5161e7db07/ Log: merge default diff --git a/lib-python/2.7/collections.py b/lib-python/2.7/collections.py --- a/lib-python/2.7/collections.py +++ b/lib-python/2.7/collections.py @@ -6,7 +6,6 @@ __all__ += _abcoll.__all__ from _collections import deque, defaultdict -from operator import itemgetter as _itemgetter from keyword import iskeyword as _iskeyword import sys as _sys import heapq as _heapq @@ -298,7 +297,7 @@ _fields = %(field_names)r \n def __new__(_cls, %(argtxt)s): 'Create new instance of %(typename)s(%(argtxt)s)' - return _tuple.__new__(_cls, (%(argtxt)s)) \n + return tuple.__new__(_cls, (%(argtxt)s)) \n @classmethod def _make(cls, iterable, new=tuple.__new__, len=len): 'Make a new %(typename)s object from a sequence or iterable' @@ -323,14 +322,14 @@ 'Return self as a plain tuple. Used by copy and pickle.' return tuple(self) \n\n''' % locals() for i, name in enumerate(field_names): - template += " %s = _property(_itemgetter(%d), doc='Alias for field number %d')\n" % (name, i, i) + template += " %s = property(lambda self: self[%d], doc='Alias for field number %d')\n" % (name, i, i) if verbose: print template # Execute the template string in a temporary namespace and # support tracing utilities by setting a value for frame.f_globals['__name__'] - namespace = dict(_itemgetter=_itemgetter, __name__='namedtuple_%s' % typename, - OrderedDict=OrderedDict, _property=property, _tuple=tuple) + namespace = {'__name__': 'namedtuple_%s' % typename, + 'OrderedDict': OrderedDict} try: exec template in namespace except SyntaxError, e: diff --git a/pypy/interpreter/executioncontext.py b/pypy/interpreter/executioncontext.py --- a/pypy/interpreter/executioncontext.py +++ b/pypy/interpreter/executioncontext.py @@ -40,6 +40,7 @@ def gettopframe(self): return self.topframeref() + @jit.unroll_safe def gettopframe_nohidden(self): frame = self.topframeref() while frame and frame.hide(): diff --git a/pypy/interpreter/pytraceback.py b/pypy/interpreter/pytraceback.py --- a/pypy/interpreter/pytraceback.py +++ b/pypy/interpreter/pytraceback.py @@ -1,5 +1,6 @@ from pypy.interpreter import baseobjspace from pypy.interpreter.error import OperationError + from rpython.tool.error import offset2lineno @@ -27,10 +28,10 @@ def descr__reduce__(self, space): from pypy.interpreter.mixedmodule import MixedModule - w_mod = space.getbuiltinmodule('_pickle_support') - mod = space.interp_w(MixedModule, w_mod) + w_mod = space.getbuiltinmodule('_pickle_support') + mod = space.interp_w(MixedModule, w_mod) new_inst = mod.get('traceback_new') - w = space.wrap + w = space.wrap tup_base = [] tup_state = [ @@ -49,6 +50,7 @@ self.lasti = space.int_w(w_lasti) self.next = space.interp_w(PyTraceback, w_next, can_be_None=True) + def record_application_traceback(space, operror, frame, last_instruction): if frame.pycode.hidden_applevel: return @@ -56,10 +58,11 @@ tb = PyTraceback(space, frame, last_instruction, tb) operror.set_traceback(tb) + def check_traceback(space, w_tb, msg): from pypy.interpreter.typedef import PyTraceback tb = space.interpclass_w(w_tb) - if tb is None or not space.is_true(space.isinstance(tb, + if tb is None or not space.is_true(space.isinstance(tb, space.gettypeobject(PyTraceback.typedef))): raise OperationError(space.w_TypeError, space.wrap(msg)) return tb diff --git a/pypy/interpreter/typedef.py b/pypy/interpreter/typedef.py --- a/pypy/interpreter/typedef.py +++ b/pypy/interpreter/typedef.py @@ -1,18 +1,17 @@ -""" +import py - -""" -import py -from pypy.interpreter.gateway import interp2app, BuiltinCode, unwrap_spec,\ - WrappedDefault from pypy.interpreter.argument import Arguments from pypy.interpreter.baseobjspace import Wrappable, DescrMismatch from pypy.interpreter.error import OperationError, operationerrfmt +from pypy.interpreter.gateway import (interp2app, BuiltinCode, unwrap_spec, + WrappedDefault) + +from rpython.rlib.jit import promote +from rpython.rlib.objectmodel import compute_identity_hash, specialize from rpython.tool.sourcetools import compile2, func_with_new_name -from rpython.rlib.objectmodel import instantiate, compute_identity_hash, specialize -from rpython.rlib.jit import promote -class TypeDef: + +class TypeDef(object): def __init__(self, __name, __base=None, __total_ordering__=None, **rawdict): "NOT_RPYTHON: initialization-time only" self.name = __name @@ -27,7 +26,7 @@ self.weakrefable = '__weakref__' in rawdict self.doc = rawdict.get('__doc__', None) for base in bases: - self.hasdict |= base.hasdict + self.hasdict |= base.hasdict self.weakrefable |= base.weakrefable self.rawdict = {} self.acceptable_as_base_class = '__new__' in rawdict @@ -426,7 +425,7 @@ return unknown_objclass_getter, cls miniglobals = {} if isinstance(cls, str): - assert cls.startswith('<'),"pythontype typecheck should begin with <" + assert cls.startswith('<'), "pythontype typecheck should begin with <" cls_name = cls[1:] typeexpr = "space.w_%s" % cls_name else: @@ -474,7 +473,7 @@ else: try: return self.fget(self, space, w_obj) - except DescrMismatch, e: + except DescrMismatch: return w_obj.descr_call_mismatch( space, '__getattribute__', self.reqcls, Arguments(space, [w_obj, @@ -489,7 +488,7 @@ space.wrap("readonly attribute")) try: fset(self, space, w_obj, w_value) - except DescrMismatch, e: + except DescrMismatch: w_obj.descr_call_mismatch( space, '__setattr__', self.reqcls, Arguments(space, [w_obj, @@ -505,7 +504,7 @@ space.wrap("cannot delete attribute")) try: fdel(self, space, w_obj) - except DescrMismatch, e: + except DescrMismatch: w_obj.descr_call_mismatch( space, '__delattr__', self.reqcls, Arguments(space, [w_obj, @@ -552,6 +551,7 @@ class Member(Wrappable): """For slots.""" _immutable_ = True + def __init__(self, index, name, w_cls): self.index = index self.name = name @@ -623,9 +623,8 @@ from pypy.interpreter.pyframe import PyFrame from pypy.interpreter.pyopcode import SuspendedUnroller, W_OperationError from pypy.interpreter.module import Module -from pypy.interpreter.function import Function, Method, StaticMethod -from pypy.interpreter.function import ClassMethod -from pypy.interpreter.function import BuiltinFunction, descr_function_get +from pypy.interpreter.function import (Function, Method, StaticMethod, + ClassMethod, BuiltinFunction, descr_function_get) from pypy.interpreter.pytraceback import PyTraceback from pypy.interpreter.generator import GeneratorIterator from pypy.interpreter.nestedscope import Cell @@ -669,8 +668,10 @@ def fget_co_flags(space, code): # unwrapping through unwrap_spec sig = code.signature() flags = 0 - if sig.has_vararg(): flags |= CO_VARARGS - if sig.has_kwarg(): flags |= CO_VARKEYWORDS + if sig.has_vararg(): + flags |= CO_VARARGS + if sig.has_kwarg(): + flags |= CO_VARKEYWORDS return space.wrap(flags) def fget_co_consts(space, code): # unwrapping through unwrap_spec @@ -734,7 +735,7 @@ __eq__ = interp2app(PyCode.descr_code__eq__), __ne__ = descr_generic_ne, __hash__ = interp2app(PyCode.descr_code__hash__), - __reduce__ = interp2app(PyCode.descr__reduce__), + __reduce__ = interp2app(PyCode.descr__reduce__), __repr__ = interp2app(PyCode.repr), co_argcount = interp_attrproperty('co_argcount', cls=PyCode), co_kwonlyargcount = interp_attrproperty('co_kwonlyargcount', cls=PyCode), @@ -744,9 +745,9 @@ co_code = interp_attrproperty_bytes('co_code', cls=PyCode), co_consts = GetSetProperty(PyCode.fget_co_consts), co_names = GetSetProperty(PyCode.fget_co_names), - co_varnames = GetSetProperty(PyCode.fget_co_varnames), - co_freevars = GetSetProperty(PyCode.fget_co_freevars), - co_cellvars = GetSetProperty(PyCode.fget_co_cellvars), + co_varnames = GetSetProperty(PyCode.fget_co_varnames), + co_freevars = GetSetProperty(PyCode.fget_co_freevars), + co_cellvars = GetSetProperty(PyCode.fget_co_cellvars), co_filename = interp_attrproperty('co_filename', cls=PyCode), co_name = interp_attrproperty('co_name', cls=PyCode), co_firstlineno = interp_attrproperty('co_firstlineno', cls=PyCode), @@ -756,7 +757,7 @@ PyCode.typedef.acceptable_as_base_class = False PyFrame.typedef = TypeDef('frame', - __reduce__ = interp2app(PyFrame.descr__reduce__), + __reduce__ = interp2app(PyFrame.descr__reduce__), __setstate__ = interp2app(PyFrame.descr__setstate__), f_builtins = GetSetProperty(PyFrame.fget_f_builtins), f_lineno = GetSetProperty(PyFrame.fget_f_lineno, PyFrame.fset_f_lineno), @@ -892,7 +893,7 @@ def always_none(self, obj): return None -BuiltinFunction.typedef = TypeDef("builtin_function",**Function.typedef.rawdict) +BuiltinFunction.typedef = TypeDef("builtin_function", **Function.typedef.rawdict) BuiltinFunction.typedef.rawdict.update({ '__new__': interp2app(BuiltinFunction.descr_builtinfunction__new__.im_func), '__self__': GetSetProperty(always_none, cls=BuiltinFunction), @@ -903,12 +904,12 @@ BuiltinFunction.typedef.acceptable_as_base_class = False PyTraceback.typedef = TypeDef("traceback", - __reduce__ = interp2app(PyTraceback.descr__reduce__), + __reduce__ = interp2app(PyTraceback.descr__reduce__), __setstate__ = interp2app(PyTraceback.descr__setstate__), - tb_frame = interp_attrproperty('frame', cls=PyTraceback), - tb_lasti = interp_attrproperty('lasti', cls=PyTraceback), + tb_frame = interp_attrproperty('frame', cls=PyTraceback), + tb_lasti = interp_attrproperty('lasti', cls=PyTraceback), tb_lineno = GetSetProperty(PyTraceback.descr_tb_lineno), - tb_next = interp_attrproperty('next', cls=PyTraceback), + tb_next = interp_attrproperty('next', cls=PyTraceback), ) PyTraceback.typedef.acceptable_as_base_class = False @@ -945,12 +946,12 @@ Cell.typedef.acceptable_as_base_class = False Ellipsis.typedef = TypeDef("Ellipsis", - __repr__ = interp2app(Ellipsis.descr__repr__), + __repr__ = interp2app(Ellipsis.descr__repr__), ) Ellipsis.typedef.acceptable_as_base_class = False NotImplemented.typedef = TypeDef("NotImplemented", - __repr__ = interp2app(NotImplemented.descr__repr__), + __repr__ = interp2app(NotImplemented.descr__repr__), ) NotImplemented.typedef.acceptable_as_base_class = False diff --git a/pypy/module/__pypy__/interp_identitydict.py b/pypy/module/__pypy__/interp_identitydict.py --- a/pypy/module/__pypy__/interp_identitydict.py +++ b/pypy/module/__pypy__/interp_identitydict.py @@ -33,6 +33,11 @@ except KeyError: raise OperationError(space.w_KeyError, w_key) + def descr_iter(self, space): + raise OperationError(space.w_TypeError, + space.wrap("'identity_dict' object does not support iteration; " + "iterate over x.keys()")) + def get(self, space, w_key, w_default=None): if w_default is None: w_default = space.w_None @@ -50,8 +55,11 @@ W_IdentityDict.typedef = TypeDef("identity_dict", __doc__="""\ A dictionary that considers keys by object identity. -Distinct objects that compare equal will have separate entries. -All objects can be used as keys, even non-hashable ones. +Distinct objects will have separate entries even if they +compare equal. All objects can be used as keys, even +non-hashable ones --- but avoid using immutable objects +like integers: two int objects 42 may or may not be +internally the same object. """, __new__ = interp2app(W_IdentityDict.descr_new.im_func), __len__ = interp2app(W_IdentityDict.descr_len), @@ -59,6 +67,7 @@ __setitem__ = interp2app(W_IdentityDict.descr_setitem), __getitem__ = interp2app(W_IdentityDict.descr_getitem), __delitem__ = interp2app(W_IdentityDict.descr_delitem), + __iter__ = interp2app(W_IdentityDict.descr_iter), get = interp2app(W_IdentityDict.get), keys = interp2app(W_IdentityDict.keys), values = interp2app(W_IdentityDict.values), diff --git a/pypy/module/__pypy__/test/test_identitydict.py b/pypy/module/__pypy__/test/test_identitydict.py --- a/pypy/module/__pypy__/test/test_identitydict.py +++ b/pypy/module/__pypy__/test/test_identitydict.py @@ -55,3 +55,10 @@ assert None in d assert [] not in d + + def test_iterate(self): + from __pypy__ import identity_dict + d = identity_dict() + d[None] = 1 + raises(TypeError, iter, d) + raises(TypeError, list, d) diff --git a/pypy/module/signal/interp_signal.py b/pypy/module/signal/interp_signal.py --- a/pypy/module/signal/interp_signal.py +++ b/pypy/module/signal/interp_signal.py @@ -60,7 +60,6 @@ def __init__(self, space): "NOT_RPYTHON" AsyncAction.__init__(self, space) - self.handlers_w = {} self.pending_signal = -1 self.fire_in_main_thread = False if self.space.config.objspace.usemodules.thread: @@ -91,7 +90,7 @@ # If we are in the main thread, report the signal now, # and poll more self.pending_signal = -1 - self._report_signal(n) + report_signal(self.space, n) n = self.pending_signal if n < 0: n = pypysig_poll() else: @@ -110,20 +109,31 @@ pypysig_pushback(cpy_signal.SIGINT) self.fire_in_main_thread = True - def _report_signal(self, n): - try: - w_handler = self.handlers_w[n] - except KeyError: - return # no handler, ignore signal - space = self.space - if not space.is_true(space.callable(w_handler)): - return # w_handler is SIG_IGN or SIG_DFL? - # re-install signal handler, for OSes that clear it - pypysig_reinstall(n) - # invoke the app-level handler - ec = space.getexecutioncontext() - w_frame = space.wrap(ec.gettopframe_nohidden()) - space.call_function(w_handler, space.wrap(n), w_frame) +# ____________________________________________________________ + + +class Handlers: + def __init__(self, space): + self.handlers_w = {} + +def _get_handlers(space): + return space.fromcache(Handlers).handlers_w + + +def report_signal(space, n): + handlers_w = _get_handlers(space) + try: + w_handler = handlers_w[n] + except KeyError: + return # no handler, ignore signal + if not space.is_true(space.callable(w_handler)): + return # w_handler is SIG_IGN or SIG_DFL? + # re-install signal handler, for OSes that clear it + pypysig_reinstall(n) + # invoke the app-level handler + ec = space.getexecutioncontext() + w_frame = space.wrap(ec.gettopframe_nohidden()) + space.call_function(w_handler, space.wrap(n), w_frame) @unwrap_spec(signum=int) @@ -141,9 +151,9 @@ check_signum_exists(space, signum) else: check_signum_in_range(space, signum) - action = space.check_signal_action - if signum in action.handlers_w: - return action.handlers_w[signum] + handlers_w = _get_handlers(space) + if signum in handlers_w: + return handlers_w[signum] return space.wrap(SIG_DFL) @@ -204,7 +214,6 @@ "main thread")) old_handler = getsignal(space, signum) - action = space.check_signal_action if space.eq_w(w_handler, space.wrap(SIG_DFL)): pypysig_default(signum) elif space.eq_w(w_handler, space.wrap(SIG_IGN)): @@ -215,7 +224,8 @@ space.wrap("'handler' must be a callable " "or SIG_DFL or SIG_IGN")) pypysig_setflag(signum) - action.handlers_w[signum] = w_handler + handlers_w = _get_handlers(space) + handlers_w[signum] = w_handler return old_handler diff --git a/pypy/objspace/std/tupleobject.py b/pypy/objspace/std/tupleobject.py --- a/pypy/objspace/std/tupleobject.py +++ b/pypy/objspace/std/tupleobject.py @@ -80,6 +80,15 @@ start += step return space.newtuple(subitems) +THRESHOLD = 7 + +def unroll_tuple_contains(space, w_tuple, w_obj): + if (jit.isconstant(w_tuple) or jit.isvirtual(w_tuple) and + len(w_tuple.wrappeditems) < THRESHOLD): + return True + return False + + at jit.look_inside_iff(unroll_tuple_contains) def contains__Tuple_ANY(space, w_tuple, w_obj): for w_item in w_tuple.wrappeditems: if space.eq_w(w_item, w_obj): diff --git a/pypy/objspace/std/typeobject.py b/pypy/objspace/std/typeobject.py --- a/pypy/objspace/std/typeobject.py +++ b/pypy/objspace/std/typeobject.py @@ -1,24 +1,23 @@ +from pypy.interpreter import gateway +from pypy.interpreter.baseobjspace import W_Root +from pypy.interpreter.error import OperationError, operationerrfmt +from pypy.interpreter.function import Function, StaticMethod +from pypy.interpreter.typedef import weakref_descr from pypy.objspace.std.model import W_Object from pypy.objspace.std.register_all import register_all -from pypy.interpreter.function import Function, StaticMethod -from pypy.interpreter import gateway -from pypy.interpreter.error import OperationError, operationerrfmt -from pypy.interpreter.typedef import weakref_descr -from pypy.interpreter.baseobjspace import W_Root from pypy.objspace.std.stdtypedef import std_dict_descr, issubtypedef, Member -from pypy.objspace.std.objecttype import object_typedef -from pypy.objspace.std import identitydict -from rpython.rlib.objectmodel import we_are_translated + +from rpython.rlib.jit import (promote, elidable_promote, we_are_jitted, + promote_string, elidable, dont_look_inside, unroll_safe) from rpython.rlib.objectmodel import current_object_addr_as_int, compute_hash -from rpython.rlib.jit import promote, elidable_promote, we_are_jitted,\ - promote_string -from rpython.rlib.jit import elidable, dont_look_inside, unroll_safe from rpython.rlib.rarithmetic import intmask, r_uint + class TypeCell(W_Root): def __init__(self, w_value=None): self.w_value = w_value + def unwrap_cell(space, w_value): if (space.config.objspace.std.withtypeversion and isinstance(w_value, TypeCell)): @@ -276,7 +275,7 @@ if attr in w_self.lazyloaders: # very clever next line: it forces the attr string # to be interned. - w_attr = space.new_interned_str(attr) + space.new_interned_str(attr) loader = w_self.lazyloaders[attr] del w_self.lazyloaders[attr] w_value = loader() @@ -495,7 +494,7 @@ def get_module(w_self): space = w_self.space - if w_self.is_heaptype() and '__module__' in w_self.dict_w: + if w_self.is_heaptype() and w_self.getdictvalue(space, '__module__') is not None: return w_self.getdictvalue(space, '__module__') else: # for non-heap types, CPython checks for a module.name in the @@ -558,13 +557,15 @@ subclasses_w.append(w_ob) return subclasses_w - # for now, weakref support for W_TypeObject is hard to get automatically _lifeline_ = None + def getweakref(self): return self._lifeline_ + def setweakref(self, space, weakreflifeline): self._lifeline_ = weakreflifeline + def delweakref(self): self._lifeline_ = None @@ -691,9 +692,12 @@ else: create_slot(w_self, slot_name) wantdict = wantdict or hasoldstylebase - if wantdict: create_dict_slot(w_self) - if wantweakref: create_weakref_slot(w_self) - if '__del__' in dict_w: w_self.needsdel = True + if wantdict: + create_dict_slot(w_self) + if wantweakref: + create_weakref_slot(w_self) + if '__del__' in dict_w: + w_self.needsdel = True def create_slot(w_self, slot_name): space = w_self.space @@ -869,7 +873,7 @@ mod = None else: mod = space.str_w(w_mod) - if mod is not None and mod !='builtins': + if mod is not None and mod != 'builtins': return space.wrap("" % (mod, w_obj.name)) else: return space.wrap("" % (w_obj.name)) @@ -888,7 +892,7 @@ # __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) + return space.get(w_descr, w_type) raise operationerrfmt(space.w_AttributeError, "type object '%s' has no attribute '%s'", w_type.name, name) @@ -934,7 +938,7 @@ return mro_error(space, orderlists) # no candidate found assert candidate not in order order.append(candidate) - for i in range(len(orderlists)-1, -1, -1): + for i in range(len(orderlists) - 1, -1, -1): if orderlists[i][0] is candidate: del orderlists[i][0] if len(orderlists[i]) == 0: diff --git a/pypy/objspace/std/typetype.py b/pypy/objspace/std/typetype.py --- a/pypy/objspace/std/typetype.py +++ b/pypy/objspace/std/typetype.py @@ -1,5 +1,4 @@ from pypy.interpreter import gateway -from pypy.interpreter.argument import Arguments from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.typedef import (GetSetProperty, descr_get_dict, weakref_descr) @@ -92,9 +91,9 @@ return space.wrap(w_type.name) def descr_set__name__(space, w_type, w_value): - w_type = _check(space, w_type) + w_type = _check(space, w_type) if not w_type.is_heaptype(): - raise operationerrfmt(space.w_TypeError, + raise operationerrfmt(space.w_TypeError, "can't set %s.__name__", w_type.name) w_type.name = space.str_w(w_value) @@ -121,10 +120,9 @@ def descr_set__bases__(space, w_type, w_value): # this assumes all app-level type objects are W_TypeObject - from pypy.objspace.std.typeobject import W_TypeObject - from pypy.objspace.std.typeobject import check_and_find_best_base - from pypy.objspace.std.typeobject import get_parent_layout - from pypy.objspace.std.typeobject import is_mro_purely_of_types + from pypy.objspace.std.typeobject import (W_TypeObject, get_parent_layout, + check_and_find_best_base, is_mro_purely_of_types) + w_type = _check(space, w_type) if not w_type.is_heaptype(): raise operationerrfmt(space.w_TypeError, @@ -215,9 +213,12 @@ # w_type = _check(space, w_type) flags = 0 - if w_type.flag_heaptype: flags |= _HEAPTYPE - if w_type.flag_cpytype: flags |= _CPYTYPE - if w_type.flag_abstract: flags |= _ABSTRACT + if w_type.flag_heaptype: + flags |= _HEAPTYPE + if w_type.flag_cpytype: + flags |= _CPYTYPE + if w_type.flag_abstract: + flags |= _ABSTRACT return space.wrap(flags) def descr_get__module(space, w_type): diff --git a/rpython/flowspace/specialcase.py b/rpython/flowspace/specialcase.py --- a/rpython/flowspace/specialcase.py +++ b/rpython/flowspace/specialcase.py @@ -65,8 +65,18 @@ def sc_we_are_translated(space, we_are_translated, args): return Constant(True) +def sc_locals(space, locals, args): + raise Exception( + "A function calling locals() is not RPython. " + "Note that if you're translating code outside the PyPy " + "repository, a likely cause is that py.test's --assert=rewrite " + "mode is getting in the way. You should copy the file " + "pytest.ini from the root of the PyPy repository into your " + "own project.") + SPECIAL_CASES = {__import__: sc_import, r_uint: sc_r_uint, - we_are_translated: sc_we_are_translated} + we_are_translated: sc_we_are_translated, + locals: sc_locals} for fn in OperationName: SPECIAL_CASES[fn] = sc_operator diff --git a/rpython/translator/c/genc.py b/rpython/translator/c/genc.py --- a/rpython/translator/c/genc.py +++ b/rpython/translator/c/genc.py @@ -761,6 +761,7 @@ srcdir / 'exception.c', srcdir / 'rtyper.c', # ifdef HAVE_RTYPER srcdir / 'support.c', + srcdir / 'profiling.c', srcdir / 'debug_print.c', srcdir / 'debug_traceback.c', # ifdef HAVE_RTYPER srcdir / 'asm.c', diff --git a/rpython/translator/platform/__init__.py b/rpython/translator/platform/__init__.py --- a/rpython/translator/platform/__init__.py +++ b/rpython/translator/platform/__init__.py @@ -53,9 +53,18 @@ ofiles = self._compile_o_files(cfiles, eci, standalone) return self._finish_linking(ofiles, eci, outputfilename, standalone) + def _all_cfiles(self, cfiles, eci): + seen = set() + result = [] + for cfile in list(cfiles) + list(eci.separate_module_files): + cfile = py.path.local(cfile) + if cfile not in seen: + seen.add(cfile) + result.append(cfile) + return result + def _compile_o_files(self, cfiles, eci, standalone=True): - cfiles = [py.path.local(f) for f in cfiles] - cfiles += [py.path.local(f) for f in eci.separate_module_files] + cfiles = self._all_cfiles(cfiles, eci) compile_args = self._compile_args_from_eci(eci, standalone) ofiles = [] for cfile in cfiles: diff --git a/rpython/translator/platform/posix.py b/rpython/translator/platform/posix.py --- a/rpython/translator/platform/posix.py +++ b/rpython/translator/platform/posix.py @@ -84,8 +84,7 @@ def gen_makefile(self, cfiles, eci, exe_name=None, path=None, shared=False): - cfiles = [py.path.local(f) for f in cfiles] - cfiles += [py.path.local(f) for f in eci.separate_module_files] + cfiles = self._all_cfiles(cfiles, eci) if path is None: path = cfiles[0].dirpath() diff --git a/rpython/translator/platform/windows.py b/rpython/translator/platform/windows.py --- a/rpython/translator/platform/windows.py +++ b/rpython/translator/platform/windows.py @@ -248,8 +248,7 @@ def gen_makefile(self, cfiles, eci, exe_name=None, path=None, shared=False): - cfiles = [py.path.local(f) for f in cfiles] - cfiles += [py.path.local(f) for f in eci.separate_module_files] + cfiles = self._all_cfiles(cfiles, eci) if path is None: path = cfiles[0].dirpath() From noreply at buildbot.pypy.org Tue Feb 5 05:28:03 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Tue, 5 Feb 2013 05:28:03 +0100 (CET) Subject: [pypy-commit] pypy default: Remove sme references to the old codespeak server Message-ID: <20130205042803.467751C02AF@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r60882:5457ef99d0bb Date: 2013-02-04 20:27 -0800 http://bitbucket.org/pypy/pypy/changeset/5457ef99d0bb/ Log: Remove sme references to the old codespeak server diff --git a/pypy/doc/coding-guide.rst b/pypy/doc/coding-guide.rst --- a/pypy/doc/coding-guide.rst +++ b/pypy/doc/coding-guide.rst @@ -832,7 +832,7 @@ for the next milestone, both from an E-Mail and from a web interface. -.. _`development tracker`: https://codespeak.net/issue/pypy-dev/ +.. _`development tracker`: https://bugs.pypy.org/ use your codespeak login or register ------------------------------------ @@ -841,7 +841,7 @@ tracker. Else, you can `register with the tracker`_ easily. -.. _`register with the tracker`: https://codespeak.net/issue/pypy-dev/user?@template=register +.. _`register with the tracker`: https://bugs.pypy.org/user?@template=register .. _`roundup`: http://roundup.sourceforge.net/ diff --git a/pypy/doc/confrest.py b/pypy/doc/confrest.py --- a/pypy/doc/confrest.py +++ b/pypy/doc/confrest.py @@ -4,7 +4,8 @@ from confrest_oldpy import Project, Page, relpath html = py.xml.html -class PyPyPage(Page): + +class PyPyPage(Page): googlefragment = """ """ + def fill_menubar(self): self.menubar = html.div( - html.a("home", - href=self.get_doclink("index.html"), - class_="menu"), + html.a("home", + href=self.get_doclink("index.html"), + class_="menu"), " ", html.a("blog", href="http://morepypy.blogspot.com", class_="menu"), - " ", + " ", html.a("getting-started", href=self.get_doclink("getting-started.html"), - class_="menu"), + class_="menu"), " ", html.a("documentation", href=self.get_doclink("docindex.html"), class_="menu"), - " ", + " ", html.a("hg", href="https://bitbucket.org/pypy/pypy", class_="menu"), - " ", + " ", html.a("issues", - href="https://codespeak.net/issue/pypy-dev/", + href="https://bugs.pypy.org/", class_="menu"), " ", id="menubar") @@ -43,25 +45,25 @@ return relpath(self.targetpath.strpath, self.project.docpath.join(target).strpath) - def unicode(self, doctype=True): - page = self._root.unicode() + def unicode(self, doctype=True): + page = self._root.unicode() page = page.replace("", self.googlefragment + "") - if doctype: - return self.doctype + page - else: - return page - + if doctype: + return self.doctype + page + else: + return page -class Project(Project): + +class Project(Project): mydir = py.path.local(__file__).dirpath() - title = "PyPy" + title = "PyPy" stylesheet = 'style.css' - encoding = 'latin1' + encoding = 'latin1' prefix_title = "PyPy" logo = html.div( html.a( - html.img(alt="PyPy", id="pyimg", - src="http://codespeak.net/pypy/img/py-web1.png", + html.img(alt="PyPy", id="pyimg", + src="http://codespeak.net/pypy/img/py-web1.png", height=110, width=149))) - Page = PyPyPage + Page = PyPyPage diff --git a/pypy/doc/getting-started.rst b/pypy/doc/getting-started.rst --- a/pypy/doc/getting-started.rst +++ b/pypy/doc/getting-started.rst @@ -1,10 +1,10 @@ ================================== -Getting Started +Getting Started ================================== .. contents:: -.. _howtopypy: +.. _howtopypy: What is PyPy ? ============== @@ -33,8 +33,8 @@ .. _`RPython translation toolchain`: translation.html .. _`more...`: architecture.html -Just the facts -============== +Just the facts +============== Download a pre-built PyPy ------------------------- @@ -125,7 +125,7 @@ ``pypy/pypy`` and documentation files in ``pypy/pypy/doc``. We try to ensure that the tip is always stable, but it might occasionally be broken. You may want to check out `our nightly tests:`_ -find a revision (12-chars alphanumeric string, e.g. "963e808156b3") +find a revision (12-chars alphanumeric string, e.g. "963e808156b3") that passed at least the ``{linux32}`` tests (corresponding to a ``+`` sign on the line ``success``) and then, in your cloned repository, switch to this revision @@ -159,24 +159,24 @@ Understanding PyPy's architecture --------------------------------- -For in-depth information about architecture and coding documentation -head over to the `documentation section`_ where you'll find lots of -interesting information. Additionally, in true hacker spirit, you -may just `start reading sources`_ . +For in-depth information about architecture and coding documentation +head over to the `documentation section`_ where you'll find lots of +interesting information. Additionally, in true hacker spirit, you +may just `start reading sources`_ . .. _`documentation section`: index.html#project-documentation .. _`start reading sources`: getting-started-dev.html#start-reading-sources -Filing bugs or feature requests +Filing bugs or feature requests ------------------------------- You may file `bug reports`_ on our issue tracker which is -also accessible through the 'issues' top menu of -the PyPy website. `Using the development tracker`_ has -more detailed information on specific features of the tracker. +also accessible through the 'issues' top menu of +the PyPy website. `Using the development tracker`_ has +more detailed information on specific features of the tracker. .. _`Using the development tracker`: coding-guide.html#using-development-tracker -.. _bug reports: https://codespeak.net/issue/pypy-dev/ +.. _bug reports: https://bugs.pypy.org/ .. include:: _ref.txt From noreply at buildbot.pypy.org Tue Feb 5 13:53:21 2013 From: noreply at buildbot.pypy.org (mattip) Date: Tue, 5 Feb 2013 13:53:21 +0100 (CET) Subject: [pypy-commit] pypy default: fix fail caused by 4237a1dca2e8 Message-ID: <20130205125321.92D801C080A@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: Changeset: r60883:ddba75d6edf2 Date: 2013-02-05 14:52 +0200 http://bitbucket.org/pypy/pypy/changeset/ddba75d6edf2/ Log: fix fail caused by 4237a1dca2e8 diff --git a/lib-python/2.7/collections.py b/lib-python/2.7/collections.py --- a/lib-python/2.7/collections.py +++ b/lib-python/2.7/collections.py @@ -9,6 +9,7 @@ from keyword import iskeyword as _iskeyword import sys as _sys import heapq as _heapq +from operator import itemgetter as _itemgetter from itertools import repeat as _repeat, chain as _chain, starmap as _starmap try: From noreply at buildbot.pypy.org Tue Feb 5 17:55:40 2013 From: noreply at buildbot.pypy.org (rlamy) Date: Tue, 5 Feb 2013 17:55:40 +0100 (CET) Subject: [pypy-commit] pypy kill-flowobjspace: hg merge default Message-ID: <20130205165540.519171C008F@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: kill-flowobjspace Changeset: r60884:b4d30ddab1be Date: 2013-02-05 16:54 +0000 http://bitbucket.org/pypy/pypy/changeset/b4d30ddab1be/ Log: hg merge default diff --git a/lib-python/2.7/collections.py b/lib-python/2.7/collections.py --- a/lib-python/2.7/collections.py +++ b/lib-python/2.7/collections.py @@ -9,6 +9,7 @@ from keyword import iskeyword as _iskeyword import sys as _sys import heapq as _heapq +from operator import itemgetter as _itemgetter from itertools import repeat as _repeat, chain as _chain, starmap as _starmap try: @@ -328,7 +329,8 @@ # Execute the template string in a temporary namespace and # support tracing utilities by setting a value for frame.f_globals['__name__'] - namespace = {'__name__': 'namedtuple_%s' % typename} + namespace = {'__name__': 'namedtuple_%s' % typename, + 'OrderedDict': OrderedDict} try: exec template in namespace except SyntaxError, e: diff --git a/pypy/doc/coding-guide.rst b/pypy/doc/coding-guide.rst --- a/pypy/doc/coding-guide.rst +++ b/pypy/doc/coding-guide.rst @@ -832,7 +832,7 @@ for the next milestone, both from an E-Mail and from a web interface. -.. _`development tracker`: https://codespeak.net/issue/pypy-dev/ +.. _`development tracker`: https://bugs.pypy.org/ use your codespeak login or register ------------------------------------ @@ -841,7 +841,7 @@ tracker. Else, you can `register with the tracker`_ easily. -.. _`register with the tracker`: https://codespeak.net/issue/pypy-dev/user?@template=register +.. _`register with the tracker`: https://bugs.pypy.org/user?@template=register .. _`roundup`: http://roundup.sourceforge.net/ diff --git a/pypy/doc/confrest.py b/pypy/doc/confrest.py --- a/pypy/doc/confrest.py +++ b/pypy/doc/confrest.py @@ -4,7 +4,8 @@ from confrest_oldpy import Project, Page, relpath html = py.xml.html -class PyPyPage(Page): + +class PyPyPage(Page): googlefragment = """ """ + def fill_menubar(self): self.menubar = html.div( - html.a("home", - href=self.get_doclink("index.html"), - class_="menu"), + html.a("home", + href=self.get_doclink("index.html"), + class_="menu"), " ", html.a("blog", href="http://morepypy.blogspot.com", class_="menu"), - " ", + " ", html.a("getting-started", href=self.get_doclink("getting-started.html"), - class_="menu"), + class_="menu"), " ", html.a("documentation", href=self.get_doclink("docindex.html"), class_="menu"), - " ", + " ", html.a("hg", href="https://bitbucket.org/pypy/pypy", class_="menu"), - " ", + " ", html.a("issues", - href="https://codespeak.net/issue/pypy-dev/", + href="https://bugs.pypy.org/", class_="menu"), " ", id="menubar") @@ -43,25 +45,25 @@ return relpath(self.targetpath.strpath, self.project.docpath.join(target).strpath) - def unicode(self, doctype=True): - page = self._root.unicode() + def unicode(self, doctype=True): + page = self._root.unicode() page = page.replace("", self.googlefragment + "") - if doctype: - return self.doctype + page - else: - return page - + if doctype: + return self.doctype + page + else: + return page -class Project(Project): + +class Project(Project): mydir = py.path.local(__file__).dirpath() - title = "PyPy" + title = "PyPy" stylesheet = 'style.css' - encoding = 'latin1' + encoding = 'latin1' prefix_title = "PyPy" logo = html.div( html.a( - html.img(alt="PyPy", id="pyimg", - src="http://codespeak.net/pypy/img/py-web1.png", + html.img(alt="PyPy", id="pyimg", + src="http://codespeak.net/pypy/img/py-web1.png", height=110, width=149))) - Page = PyPyPage + Page = PyPyPage diff --git a/pypy/doc/getting-started.rst b/pypy/doc/getting-started.rst --- a/pypy/doc/getting-started.rst +++ b/pypy/doc/getting-started.rst @@ -1,10 +1,10 @@ ================================== -Getting Started +Getting Started ================================== .. contents:: -.. _howtopypy: +.. _howtopypy: What is PyPy ? ============== @@ -33,8 +33,8 @@ .. _`RPython translation toolchain`: translation.html .. _`more...`: architecture.html -Just the facts -============== +Just the facts +============== Download a pre-built PyPy ------------------------- @@ -125,7 +125,7 @@ ``pypy/pypy`` and documentation files in ``pypy/pypy/doc``. We try to ensure that the tip is always stable, but it might occasionally be broken. You may want to check out `our nightly tests:`_ -find a revision (12-chars alphanumeric string, e.g. "963e808156b3") +find a revision (12-chars alphanumeric string, e.g. "963e808156b3") that passed at least the ``{linux32}`` tests (corresponding to a ``+`` sign on the line ``success``) and then, in your cloned repository, switch to this revision @@ -159,24 +159,24 @@ Understanding PyPy's architecture --------------------------------- -For in-depth information about architecture and coding documentation -head over to the `documentation section`_ where you'll find lots of -interesting information. Additionally, in true hacker spirit, you -may just `start reading sources`_ . +For in-depth information about architecture and coding documentation +head over to the `documentation section`_ where you'll find lots of +interesting information. Additionally, in true hacker spirit, you +may just `start reading sources`_ . .. _`documentation section`: index.html#project-documentation .. _`start reading sources`: getting-started-dev.html#start-reading-sources -Filing bugs or feature requests +Filing bugs or feature requests ------------------------------- You may file `bug reports`_ on our issue tracker which is -also accessible through the 'issues' top menu of -the PyPy website. `Using the development tracker`_ has -more detailed information on specific features of the tracker. +also accessible through the 'issues' top menu of +the PyPy website. `Using the development tracker`_ has +more detailed information on specific features of the tracker. .. _`Using the development tracker`: coding-guide.html#using-development-tracker -.. _bug reports: https://codespeak.net/issue/pypy-dev/ +.. _bug reports: https://bugs.pypy.org/ .. include:: _ref.txt diff --git a/pypy/interpreter/pytraceback.py b/pypy/interpreter/pytraceback.py --- a/pypy/interpreter/pytraceback.py +++ b/pypy/interpreter/pytraceback.py @@ -1,5 +1,6 @@ from pypy.interpreter import baseobjspace from pypy.interpreter.error import OperationError + from rpython.tool.error import offset2lineno @@ -27,10 +28,10 @@ def descr__reduce__(self, space): from pypy.interpreter.mixedmodule import MixedModule - w_mod = space.getbuiltinmodule('_pickle_support') - mod = space.interp_w(MixedModule, w_mod) + w_mod = space.getbuiltinmodule('_pickle_support') + mod = space.interp_w(MixedModule, w_mod) new_inst = mod.get('traceback_new') - w = space.wrap + w = space.wrap tup_base = [] tup_state = [ @@ -49,6 +50,7 @@ self.lasti = space.int_w(w_lasti) self.next = space.interp_w(PyTraceback, w_next, can_be_None=True) + def record_application_traceback(space, operror, frame, last_instruction): if frame.pycode.hidden_applevel: return @@ -56,10 +58,11 @@ tb = PyTraceback(space, frame, last_instruction, tb) operror.set_traceback(tb) + def check_traceback(space, w_tb, msg): from pypy.interpreter.typedef import PyTraceback tb = space.interpclass_w(w_tb) - if tb is None or not space.is_true(space.isinstance(tb, + if tb is None or not space.is_true(space.isinstance(tb, space.gettypeobject(PyTraceback.typedef))): raise OperationError(space.w_TypeError, space.wrap(msg)) return tb diff --git a/pypy/interpreter/typedef.py b/pypy/interpreter/typedef.py --- a/pypy/interpreter/typedef.py +++ b/pypy/interpreter/typedef.py @@ -1,18 +1,17 @@ -""" +import py - -""" -import py -from pypy.interpreter.gateway import interp2app, BuiltinCode, unwrap_spec,\ - WrappedDefault from pypy.interpreter.argument import Arguments from pypy.interpreter.baseobjspace import Wrappable, DescrMismatch from pypy.interpreter.error import OperationError, operationerrfmt +from pypy.interpreter.gateway import (interp2app, BuiltinCode, unwrap_spec, + WrappedDefault) + +from rpython.rlib.jit import promote +from rpython.rlib.objectmodel import compute_identity_hash, specialize from rpython.tool.sourcetools import compile2, func_with_new_name -from rpython.rlib.objectmodel import instantiate, compute_identity_hash, specialize -from rpython.rlib.jit import promote -class TypeDef: + +class TypeDef(object): def __init__(self, __name, __base=None, __total_ordering__=None, **rawdict): "NOT_RPYTHON: initialization-time only" self.name = __name @@ -27,7 +26,7 @@ self.weakrefable = '__weakref__' in rawdict self.doc = rawdict.pop('__doc__', None) for base in bases: - self.hasdict |= base.hasdict + self.hasdict |= base.hasdict self.weakrefable |= base.weakrefable self.rawdict = {} self.acceptable_as_base_class = '__new__' in rawdict @@ -426,7 +425,7 @@ return unknown_objclass_getter, cls miniglobals = {} if isinstance(cls, str): - assert cls.startswith('<'),"pythontype typecheck should begin with <" + assert cls.startswith('<'), "pythontype typecheck should begin with <" cls_name = cls[1:] typeexpr = "space.w_%s" % cls_name else: @@ -474,7 +473,7 @@ else: try: return self.fget(self, space, w_obj) - except DescrMismatch, e: + except DescrMismatch: return w_obj.descr_call_mismatch( space, '__getattribute__', self.reqcls, Arguments(space, [w_obj, @@ -489,7 +488,7 @@ space.wrap("readonly attribute")) try: fset(self, space, w_obj, w_value) - except DescrMismatch, e: + except DescrMismatch: w_obj.descr_call_mismatch( space, '__setattr__', self.reqcls, Arguments(space, [w_obj, @@ -505,7 +504,7 @@ space.wrap("cannot delete attribute")) try: fdel(self, space, w_obj) - except DescrMismatch, e: + except DescrMismatch: w_obj.descr_call_mismatch( space, '__delattr__', self.reqcls, Arguments(space, [w_obj, @@ -546,6 +545,7 @@ class Member(Wrappable): """For slots.""" _immutable_ = True + def __init__(self, index, name, w_cls): self.index = index self.name = name @@ -617,9 +617,8 @@ from pypy.interpreter.pyframe import PyFrame from pypy.interpreter.pyopcode import SuspendedUnroller from pypy.interpreter.module import Module -from pypy.interpreter.function import Function, Method, StaticMethod -from pypy.interpreter.function import ClassMethod -from pypy.interpreter.function import BuiltinFunction, descr_function_get +from pypy.interpreter.function import (Function, Method, StaticMethod, + ClassMethod, BuiltinFunction, descr_function_get) from pypy.interpreter.pytraceback import PyTraceback from pypy.interpreter.generator import GeneratorIterator from pypy.interpreter.nestedscope import Cell @@ -663,8 +662,10 @@ def fget_co_flags(space, code): # unwrapping through unwrap_spec sig = code.signature() flags = 0 - if sig.has_vararg(): flags |= CO_VARARGS - if sig.has_kwarg(): flags |= CO_VARKEYWORDS + if sig.has_vararg(): + flags |= CO_VARARGS + if sig.has_kwarg(): + flags |= CO_VARKEYWORDS return space.wrap(flags) def fget_co_consts(space, code): # unwrapping through unwrap_spec @@ -728,7 +729,7 @@ __eq__ = interp2app(PyCode.descr_code__eq__), __ne__ = descr_generic_ne, __hash__ = interp2app(PyCode.descr_code__hash__), - __reduce__ = interp2app(PyCode.descr__reduce__), + __reduce__ = interp2app(PyCode.descr__reduce__), __repr__ = interp2app(PyCode.repr), co_argcount = interp_attrproperty('co_argcount', cls=PyCode), co_nlocals = interp_attrproperty('co_nlocals', cls=PyCode), @@ -737,9 +738,9 @@ co_code = interp_attrproperty('co_code', cls=PyCode), co_consts = GetSetProperty(PyCode.fget_co_consts), co_names = GetSetProperty(PyCode.fget_co_names), - co_varnames = GetSetProperty(PyCode.fget_co_varnames), - co_freevars = GetSetProperty(PyCode.fget_co_freevars), - co_cellvars = GetSetProperty(PyCode.fget_co_cellvars), + co_varnames = GetSetProperty(PyCode.fget_co_varnames), + co_freevars = GetSetProperty(PyCode.fget_co_freevars), + co_cellvars = GetSetProperty(PyCode.fget_co_cellvars), co_filename = interp_attrproperty('co_filename', cls=PyCode), co_name = interp_attrproperty('co_name', cls=PyCode), co_firstlineno = interp_attrproperty('co_firstlineno', cls=PyCode), @@ -749,7 +750,7 @@ PyCode.typedef.acceptable_as_base_class = False PyFrame.typedef = TypeDef('frame', - __reduce__ = interp2app(PyFrame.descr__reduce__), + __reduce__ = interp2app(PyFrame.descr__reduce__), __setstate__ = interp2app(PyFrame.descr__setstate__), f_builtins = GetSetProperty(PyFrame.fget_f_builtins), f_lineno = GetSetProperty(PyFrame.fget_f_lineno, PyFrame.fset_f_lineno), @@ -827,9 +828,9 @@ __new__ = interp2app(Method.descr_method__new__.im_func), __call__ = interp2app(Method.descr_method_call), __get__ = interp2app(Method.descr_method_get), - im_func = interp_attrproperty_w('w_function', cls=Method), + im_func = interp_attrproperty_w('w_function', cls=Method), __func__ = interp_attrproperty_w('w_function', cls=Method), - im_self = interp_attrproperty_w('w_instance', cls=Method), + im_self = interp_attrproperty_w('w_instance', cls=Method), __self__ = interp_attrproperty_w('w_instance', cls=Method), im_class = interp_attrproperty_w('w_class', cls=Method), __getattribute__ = interp2app(Method.descr_method_getattribute), @@ -886,7 +887,7 @@ def always_none(self, obj): return None -BuiltinFunction.typedef = TypeDef("builtin_function",**Function.typedef.rawdict) +BuiltinFunction.typedef = TypeDef("builtin_function", **Function.typedef.rawdict) BuiltinFunction.typedef.rawdict.update({ '__new__': interp2app(BuiltinFunction.descr_builtinfunction__new__.im_func), '__self__': GetSetProperty(always_none, cls=BuiltinFunction), @@ -897,12 +898,12 @@ BuiltinFunction.typedef.acceptable_as_base_class = False PyTraceback.typedef = TypeDef("traceback", - __reduce__ = interp2app(PyTraceback.descr__reduce__), + __reduce__ = interp2app(PyTraceback.descr__reduce__), __setstate__ = interp2app(PyTraceback.descr__setstate__), - tb_frame = interp_attrproperty('frame', cls=PyTraceback), - tb_lasti = interp_attrproperty('lasti', cls=PyTraceback), + tb_frame = interp_attrproperty('frame', cls=PyTraceback), + tb_lasti = interp_attrproperty('lasti', cls=PyTraceback), tb_lineno = GetSetProperty(PyTraceback.descr_tb_lineno), - tb_next = interp_attrproperty('next', cls=PyTraceback), + tb_next = interp_attrproperty('next', cls=PyTraceback), ) PyTraceback.typedef.acceptable_as_base_class = False @@ -937,12 +938,12 @@ Cell.typedef.acceptable_as_base_class = False Ellipsis.typedef = TypeDef("Ellipsis", - __repr__ = interp2app(Ellipsis.descr__repr__), + __repr__ = interp2app(Ellipsis.descr__repr__), ) Ellipsis.typedef.acceptable_as_base_class = False NotImplemented.typedef = TypeDef("NotImplemented", - __repr__ = interp2app(NotImplemented.descr__repr__), + __repr__ = interp2app(NotImplemented.descr__repr__), ) NotImplemented.typedef.acceptable_as_base_class = False diff --git a/pypy/objspace/std/tupleobject.py b/pypy/objspace/std/tupleobject.py --- a/pypy/objspace/std/tupleobject.py +++ b/pypy/objspace/std/tupleobject.py @@ -85,6 +85,15 @@ start, stop = normalize_simple_slice(space, length, w_start, w_stop) return space.newtuple(w_tuple.wrappeditems[start:stop]) +THRESHOLD = 7 + +def unroll_tuple_contains(space, w_tuple, w_obj): + if (jit.isconstant(w_tuple) or jit.isvirtual(w_tuple) and + len(w_tuple.wrappeditems) < THRESHOLD): + return True + return False + + at jit.look_inside_iff(unroll_tuple_contains) def contains__Tuple_ANY(space, w_tuple, w_obj): for w_item in w_tuple.wrappeditems: if space.eq_w(w_item, w_obj): diff --git a/pypy/objspace/std/typeobject.py b/pypy/objspace/std/typeobject.py --- a/pypy/objspace/std/typeobject.py +++ b/pypy/objspace/std/typeobject.py @@ -1,24 +1,23 @@ +from pypy.interpreter import gateway +from pypy.interpreter.baseobjspace import W_Root +from pypy.interpreter.error import OperationError, operationerrfmt +from pypy.interpreter.function import Function, StaticMethod +from pypy.interpreter.typedef import weakref_descr from pypy.objspace.std.model import W_Object from pypy.objspace.std.register_all import register_all -from pypy.interpreter.function import Function, StaticMethod -from pypy.interpreter import gateway -from pypy.interpreter.error import OperationError, operationerrfmt -from pypy.interpreter.typedef import weakref_descr -from pypy.interpreter.baseobjspace import W_Root from pypy.objspace.std.stdtypedef import std_dict_descr, issubtypedef, Member -from pypy.objspace.std.objecttype import object_typedef -from pypy.objspace.std import identitydict -from rpython.rlib.objectmodel import we_are_translated + +from rpython.rlib.jit import (promote, elidable_promote, we_are_jitted, + promote_string, elidable, dont_look_inside, unroll_safe) from rpython.rlib.objectmodel import current_object_addr_as_int, compute_hash -from rpython.rlib.jit import promote, elidable_promote, we_are_jitted,\ - promote_string -from rpython.rlib.jit import elidable, dont_look_inside, unroll_safe from rpython.rlib.rarithmetic import intmask, r_uint + class TypeCell(W_Root): def __init__(self, w_value=None): self.w_value = w_value + def unwrap_cell(space, w_value): if (space.config.objspace.std.withtypeversion and isinstance(w_value, TypeCell)): @@ -278,7 +277,7 @@ if attr in w_self.lazyloaders: # very clever next line: it forces the attr string # to be interned. - w_attr = space.new_interned_str(attr) + space.new_interned_str(attr) loader = w_self.lazyloaders[attr] del w_self.lazyloaders[attr] w_value = loader() @@ -497,7 +496,7 @@ def get_module(w_self): space = w_self.space - if w_self.is_heaptype() and '__module__' in w_self.dict_w: + if w_self.is_heaptype() and w_self.getdictvalue(space, '__module__') is not None: return w_self.getdictvalue(space, '__module__') else: # for non-heap types, CPython checks for a module.name in the @@ -516,7 +515,7 @@ mod = '__builtin__' else: mod = space.str_w(w_mod) - if mod !='__builtin__': + if mod != '__builtin__': return '%s.%s' % (mod, w_self.name) else: return w_self.name @@ -560,13 +559,15 @@ subclasses_w.append(w_ob) return subclasses_w - # for now, weakref support for W_TypeObject is hard to get automatically _lifeline_ = None + def getweakref(self): return self._lifeline_ + def setweakref(self, space, weakreflifeline): self._lifeline_ = weakreflifeline + def delweakref(self): self._lifeline_ = None @@ -693,9 +694,12 @@ else: create_slot(w_self, slot_name) wantdict = wantdict or hasoldstylebase - if wantdict: create_dict_slot(w_self) - if wantweakref: create_weakref_slot(w_self) - if '__del__' in dict_w: w_self.needsdel = True + if wantdict: + create_dict_slot(w_self) + if wantweakref: + create_weakref_slot(w_self) + if '__del__' in dict_w: + w_self.needsdel = True def create_slot(w_self, slot_name): space = w_self.space @@ -868,7 +872,7 @@ kind = 'type' else: kind = 'class' - if mod is not None and mod !='__builtin__': + if mod is not None and mod != '__builtin__': return space.wrap("<%s '%s.%s'>" % (kind, mod, w_obj.name)) else: return space.wrap("<%s '%s'>" % (kind, w_obj.name)) @@ -887,7 +891,7 @@ # __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) + return space.get(w_descr, w_type) raise operationerrfmt(space.w_AttributeError, "type object '%s' has no attribute '%s'", w_type.name, name) @@ -933,7 +937,7 @@ return mro_error(space, orderlists) # no candidate found assert candidate not in order order.append(candidate) - for i in range(len(orderlists)-1, -1, -1): + for i in range(len(orderlists) - 1, -1, -1): if orderlists[i][0] is candidate: del orderlists[i][0] if len(orderlists[i]) == 0: diff --git a/pypy/objspace/std/typetype.py b/pypy/objspace/std/typetype.py --- a/pypy/objspace/std/typetype.py +++ b/pypy/objspace/std/typetype.py @@ -1,5 +1,4 @@ from pypy.interpreter import gateway -from pypy.interpreter.argument import Arguments from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.typedef import (GetSetProperty, descr_get_dict, weakref_descr) @@ -90,9 +89,9 @@ return space.wrap(w_type.name) def descr_set__name__(space, w_type, w_value): - w_type = _check(space, w_type) + w_type = _check(space, w_type) if not w_type.is_heaptype(): - raise operationerrfmt(space.w_TypeError, + raise operationerrfmt(space.w_TypeError, "can't set %s.__name__", w_type.name) w_type.name = space.str_w(w_value) @@ -119,10 +118,9 @@ def descr_set__bases__(space, w_type, w_value): # this assumes all app-level type objects are W_TypeObject - from pypy.objspace.std.typeobject import W_TypeObject - from pypy.objspace.std.typeobject import check_and_find_best_base - from pypy.objspace.std.typeobject import get_parent_layout - from pypy.objspace.std.typeobject import is_mro_purely_of_types + from pypy.objspace.std.typeobject import (W_TypeObject, get_parent_layout, + check_and_find_best_base, is_mro_purely_of_types) + w_type = _check(space, w_type) if not w_type.is_heaptype(): raise operationerrfmt(space.w_TypeError, @@ -213,9 +211,12 @@ # w_type = _check(space, w_type) flags = 0 - if w_type.flag_heaptype: flags |= _HEAPTYPE - if w_type.flag_cpytype: flags |= _CPYTYPE - if w_type.flag_abstract: flags |= _ABSTRACT + if w_type.flag_heaptype: + flags |= _HEAPTYPE + if w_type.flag_cpytype: + flags |= _CPYTYPE + if w_type.flag_abstract: + flags |= _ABSTRACT return space.wrap(flags) def descr_get__module(space, w_type): diff --git a/rpython/flowspace/specialcase.py b/rpython/flowspace/specialcase.py --- a/rpython/flowspace/specialcase.py +++ b/rpython/flowspace/specialcase.py @@ -59,8 +59,18 @@ def sc_we_are_translated(space, we_are_translated, args_w): return Constant(True) +def sc_locals(space, locals, args): + raise Exception( + "A function calling locals() is not RPython. " + "Note that if you're translating code outside the PyPy " + "repository, a likely cause is that py.test's --assert=rewrite " + "mode is getting in the way. You should copy the file " + "pytest.ini from the root of the PyPy repository into your " + "own project.") + SPECIAL_CASES = {__import__: sc_import, r_uint: sc_r_uint, - we_are_translated: sc_we_are_translated} + we_are_translated: sc_we_are_translated, + locals: sc_locals} for fn in OperationName: SPECIAL_CASES[fn] = sc_operator From noreply at buildbot.pypy.org Tue Feb 5 20:46:58 2013 From: noreply at buildbot.pypy.org (matti) Date: Tue, 5 Feb 2013 20:46:58 +0100 (CET) Subject: [pypy-commit] extradoc extradoc: update, change intent of FFT to FFI Message-ID: <20130205194658.993021C008F@cobra.cs.uni-duesseldorf.de> Author: matti Branch: extradoc Changeset: r4942:aacbb71514b1 Date: 2013-02-05 21:46 +0200 http://bitbucket.org/pypy/extradoc/changeset/aacbb71514b1/ Log: update, change intent of FFT to FFI diff --git a/blog/draft/numpy-status-update-6.rst b/blog/draft/numpy-status-update-6.rst --- a/blog/draft/numpy-status-update-6.rst +++ b/blog/draft/numpy-status-update-6.rst @@ -1,21 +1,22 @@ NumPy status update #6 ---------------------- -Hello. - -This is the last two months update of the activities on the NumPyPy project. +This is status report on PyPy's NumPyPy project. First the update: * **dtype support** - NumPy on PyPy now supports all the numeric dtypes in numpy, including non-native storage formats, longdouble, clongdouble and friends. -* **missing ndarray attributes** - work has been made toward supporting the attributes +* **missing ndarray attributes** - work has been made toward supporting the + complete set of attributes on ndarrays. We are progressing alphabetically, and have made it to d. + Unsupported attributes, and unsupported arguments to attribute calls + will raise a NotImplementedException. * **pickling support for numarray** - hasn't started yet, but next on the list -* There has been some work on exposing FFT routines into numpypy. +* There has been some work on exposing FFI routines in numpypy. More importantly, we're closing on being able to run the pure-python part of numpy without modifications. This is not getting us close to passing all @@ -23,7 +24,8 @@ The most important part is the funding. While we managed to get a significant amount of money in donations, we only managed to spend around $10 000 from it -so far. XXX +so far. We have issued a call for additional developers, and hope to be able to +report on speedier progress soon. Cheers, Matti Picus, Maciej Fijalkowski From noreply at buildbot.pypy.org Tue Feb 5 23:57:08 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Tue, 5 Feb 2013 23:57:08 +0100 (CET) Subject: [pypy-commit] pypy default: a couple usemodules lines Message-ID: <20130205225708.B51241C008F@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r60885:d5b5b5689313 Date: 2013-02-05 17:36 -0500 http://bitbucket.org/pypy/pypy/changeset/d5b5b5689313/ Log: a couple usemodules lines diff --git a/lib-python/conftest.py b/lib-python/conftest.py --- a/lib-python/conftest.py +++ b/lib-python/conftest.py @@ -160,7 +160,7 @@ RegrTest('test_codeop.py', core=True), RegrTest('test_coding.py', core=True), RegrTest('test_coercion.py', core=True), - RegrTest('test_collections.py'), + RegrTest('test_collections.py', usemodules='binascii struct'), RegrTest('test_colorsys.py'), RegrTest('test_commands.py'), RegrTest('test_compare.py', core=True), @@ -181,7 +181,7 @@ RegrTest('test_csv.py', usemodules='_csv'), RegrTest('test_ctypes.py', usemodules="_rawffi thread"), RegrTest('test_curses.py'), - RegrTest('test_datetime.py'), + RegrTest('test_datetime.py', usemodules='binascii struct'), RegrTest('test_dbm.py'), RegrTest('test_decimal.py'), RegrTest('test_decorators.py', core=True), From noreply at buildbot.pypy.org Tue Feb 5 23:57:09 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Tue, 5 Feb 2013 23:57:09 +0100 (CET) Subject: [pypy-commit] pypy cleanup-tests: this should always import lib_pypy's sqlite3, never the host's Message-ID: <20130205225709.E0BE41C0613@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: cleanup-tests Changeset: r60886:9e7230d8f10c Date: 2013-02-05 17:45 -0500 http://bitbucket.org/pypy/pypy/changeset/9e7230d8f10c/ Log: this should always import lib_pypy's sqlite3, never the host's diff --git a/pypy/module/test_lib_pypy/test_sqlite3.py b/pypy/module/test_lib_pypy/test_sqlite3.py --- a/pypy/module/test_lib_pypy/test_sqlite3.py +++ b/pypy/module/test_lib_pypy/test_sqlite3.py @@ -2,7 +2,7 @@ def test_list_ddl(): """From issue996. Mostly just looking for lack of exceptions.""" - from sqlite3.dbapi2 import connect + from lib_pypy._sqlite3 import connect connection = connect(':memory:') cursor = connection.cursor() cursor.execute('CREATE TABLE foo (bar INTEGER)') From noreply at buildbot.pypy.org Tue Feb 5 23:57:11 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Tue, 5 Feb 2013 23:57:11 +0100 (CET) Subject: [pypy-commit] pypy cleanup-tests: merge tests in the two datetime test files Message-ID: <20130205225711.1BFA31C008F@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: cleanup-tests Changeset: r60887:d57434b6a9d7 Date: 2013-02-05 17:52 -0500 http://bitbucket.org/pypy/pypy/changeset/d57434b6a9d7/ Log: merge tests in the two datetime test files diff --git a/pypy/module/test_lib_pypy/test_datetime.py b/pypy/module/test_lib_pypy/test_datetime.py --- a/pypy/module/test_lib_pypy/test_datetime.py +++ b/pypy/module/test_lib_pypy/test_datetime.py @@ -57,3 +57,50 @@ for t in sorted(expected_results): dt = datetime.datetime.utcfromtimestamp(t) assert repr(dt) == expected_results[t] + +def test_utcfromtimestamp(): + """Confirm that utcfromtimestamp and fromtimestamp give consistent results. + + Based on danchr's test script in https://bugs.pypy.org/issue986 + """ + import os + import time + try: + prev_tz = os.environ.get("TZ") + os.environ["TZ"] = "GMT" + for unused in xrange(100): + now = time.time() + delta = (datetime.datetime.utcfromtimestamp(now) - + datetime.datetime.fromtimestamp(now)) + assert delta.days * 86400 + delta.seconds == 0 + finally: + if prev_tz is None: + del os.environ["TZ"] + else: + os.environ["TZ"] = prev_tz + +def test_utcfromtimestamp_microsecond(): + dt = datetime.datetime.utcfromtimestamp(0) + assert isinstance(dt.microsecond, int) + +def test_integer_args(): + with py.test.raises(TypeError): + datetime.datetime(10, 10, 10.) + with py.test.raises(TypeError): + datetime.datetime(10, 10, 10, 10, 10.) + with py.test.raises(TypeError): + datetime.datetime(10, 10, 10, 10, 10, 10.) + +def test_utcnow_microsecond(): + import copy + + dt = datetime.datetime.utcnow() + assert type(dt.microsecond) is int + + copy.copy(dt) + +def test_radd(): + class X(object): + def __radd__(self, other): + return "radd" + assert datetime.date(10, 10, 10) + X() == "radd" diff --git a/pypy/module/test_lib_pypy/test_datetime_extra.py b/pypy/module/test_lib_pypy/test_datetime_extra.py deleted file mode 100644 --- a/pypy/module/test_lib_pypy/test_datetime_extra.py +++ /dev/null @@ -1,52 +0,0 @@ -"""Additional tests for datetime.""" - -import py - -import time -from lib_pypy import datetime -import copy -import os - -def test_utcfromtimestamp(): - """Confirm that utcfromtimestamp and fromtimestamp give consistent results. - - Based on danchr's test script in https://bugs.pypy.org/issue986 - """ - try: - prev_tz = os.environ.get("TZ") - os.environ["TZ"] = "GMT" - for unused in xrange(100): - now = time.time() - delta = (datetime.datetime.utcfromtimestamp(now) - - datetime.datetime.fromtimestamp(now)) - assert delta.days * 86400 + delta.seconds == 0 - finally: - if prev_tz is None: - del os.environ["TZ"] - else: - os.environ["TZ"] = prev_tz - -def test_utcfromtimestamp_microsecond(): - dt = datetime.datetime.utcfromtimestamp(0) - assert isinstance(dt.microsecond, int) - - -def test_integer_args(): - with py.test.raises(TypeError): - datetime.datetime(10, 10, 10.) - with py.test.raises(TypeError): - datetime.datetime(10, 10, 10, 10, 10.) - with py.test.raises(TypeError): - datetime.datetime(10, 10, 10, 10, 10, 10.) - -def test_utcnow_microsecond(): - dt = datetime.datetime.utcnow() - assert type(dt.microsecond) is int - - copy.copy(dt) - -def test_radd(): - class X(object): - def __radd__(self, other): - return "radd" - assert datetime.date(10, 10, 10) + X() == "radd" From noreply at buildbot.pypy.org Tue Feb 5 23:57:12 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Tue, 5 Feb 2013 23:57:12 +0100 (CET) Subject: [pypy-commit] pypy default: put this line back where it is upstream Message-ID: <20130205225712.54B551C008F@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r60888:4a15e2b1773e Date: 2013-02-05 17:55 -0500 http://bitbucket.org/pypy/pypy/changeset/4a15e2b1773e/ Log: put this line back where it is upstream diff --git a/lib-python/2.7/collections.py b/lib-python/2.7/collections.py --- a/lib-python/2.7/collections.py +++ b/lib-python/2.7/collections.py @@ -6,10 +6,10 @@ __all__ += _abcoll.__all__ from _collections import deque, defaultdict +from operator import itemgetter as _itemgetter from keyword import iskeyword as _iskeyword import sys as _sys import heapq as _heapq -from operator import itemgetter as _itemgetter from itertools import repeat as _repeat, chain as _chain, starmap as _starmap try: From noreply at buildbot.pypy.org Tue Feb 5 23:57:13 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Tue, 5 Feb 2013 23:57:13 +0100 (CET) Subject: [pypy-commit] pypy cleanup-tests: merge default Message-ID: <20130205225713.E422C1C008F@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: cleanup-tests Changeset: r60889:01cab6cc71bf Date: 2013-02-05 17:56 -0500 http://bitbucket.org/pypy/pypy/changeset/01cab6cc71bf/ Log: merge default diff --git a/lib-python/2.7/collections.py b/lib-python/2.7/collections.py --- a/lib-python/2.7/collections.py +++ b/lib-python/2.7/collections.py @@ -298,7 +298,7 @@ _fields = %(field_names)r \n def __new__(_cls, %(argtxt)s): 'Create new instance of %(typename)s(%(argtxt)s)' - return _tuple.__new__(_cls, (%(argtxt)s)) \n + return tuple.__new__(_cls, (%(argtxt)s)) \n @classmethod def _make(cls, iterable, new=tuple.__new__, len=len): 'Make a new %(typename)s object from a sequence or iterable' @@ -323,14 +323,14 @@ 'Return self as a plain tuple. Used by copy and pickle.' return tuple(self) \n\n''' % locals() for i, name in enumerate(field_names): - template += " %s = _property(_itemgetter(%d), doc='Alias for field number %d')\n" % (name, i, i) + template += " %s = property(lambda self: self[%d], doc='Alias for field number %d')\n" % (name, i, i) if verbose: print template # Execute the template string in a temporary namespace and # support tracing utilities by setting a value for frame.f_globals['__name__'] - namespace = dict(_itemgetter=_itemgetter, __name__='namedtuple_%s' % typename, - OrderedDict=OrderedDict, _property=property, _tuple=tuple) + namespace = {'__name__': 'namedtuple_%s' % typename, + 'OrderedDict': OrderedDict} try: exec template in namespace except SyntaxError, e: diff --git a/lib-python/2.7/test/test_zipfile.py b/lib-python/2.7/test/test_zipfile.py --- a/lib-python/2.7/test/test_zipfile.py +++ b/lib-python/2.7/test/test_zipfile.py @@ -1213,6 +1213,17 @@ self.assertEqual(data1, '1'*FIXEDTEST_SIZE) self.assertEqual(data2, '2'*FIXEDTEST_SIZE) + def test_many_opens(self): + # Verify that read() and open() promptly close the file descriptor, + # and don't rely on the garbage collector to free resources. + with zipfile.ZipFile(TESTFN2, mode="r") as zipf: + for x in range(100): + zipf.read('ones') + with zipf.open('ones') as zopen1: + pass + for x in range(10): + self.assertLess(open('/dev/null').fileno(), 100) + def tearDown(self): unlink(TESTFN2) diff --git a/lib-python/2.7/zipfile.py b/lib-python/2.7/zipfile.py --- a/lib-python/2.7/zipfile.py +++ b/lib-python/2.7/zipfile.py @@ -475,9 +475,11 @@ # Search for universal newlines or line chunks. PATTERN = re.compile(r'^(?P[^\r\n]+)|(?P\n|\r\n?)') - def __init__(self, fileobj, mode, zipinfo, decrypter=None): + def __init__(self, fileobj, mode, zipinfo, decrypter=None, + close_fileobj=False): self._fileobj = fileobj self._decrypter = decrypter + self._close_fileobj = close_fileobj self._compress_type = zipinfo.compress_type self._compress_size = zipinfo.compress_size @@ -649,6 +651,12 @@ self._offset += len(data) return data + def close(self): + try: + if self._close_fileobj: + self._fileobj.close() + finally: + super(ZipExtFile, self).close() class ZipFile: @@ -866,7 +874,8 @@ def read(self, name, pwd=None): """Return file bytes (as a string) for name.""" - return self.open(name, "r", pwd).read() + with self.open(name, "r", pwd) as fp: + return fp.read() def open(self, name, mode="r", pwd=None): """Return file-like object for 'name'.""" @@ -889,8 +898,12 @@ zinfo = name else: # Get info object for name - zinfo = self.getinfo(name) - + try: + zinfo = self.getinfo(name) + except KeyError: + if not self._filePassed: + zef_file.close() + raise zef_file.seek(zinfo.header_offset, 0) # Skip the file header: @@ -904,6 +917,8 @@ zef_file.read(fheader[_FH_EXTRA_FIELD_LENGTH]) if fname != zinfo.orig_filename: + if not self._filePassed: + zef_file.close() raise BadZipfile, \ 'File name in directory "%s" and header "%s" differ.' % ( zinfo.orig_filename, fname) @@ -915,6 +930,8 @@ if not pwd: pwd = self.pwd if not pwd: + if not self._filePassed: + zef_file.close() raise RuntimeError, "File %s is encrypted, " \ "password required for extraction" % name @@ -933,9 +950,12 @@ # compare against the CRC otherwise check_byte = (zinfo.CRC >> 24) & 0xff if ord(h[11]) != check_byte: + if not self._filePassed: + zef_file.close() raise RuntimeError("Bad password for file", name) - return ZipExtFile(zef_file, mode, zinfo, zd) + return ZipExtFile(zef_file, mode, zinfo, zd, + close_fileobj=not self._filePassed) def extract(self, member, path=None, pwd=None): """Extract a member from the archive to the current working directory, @@ -993,7 +1013,7 @@ return targetpath source = self.open(member, pwd=pwd) - target = file(targetpath, "wb") + target = open(targetpath, "wb") shutil.copyfileobj(source, target) source.close() target.close() diff --git a/lib-python/conftest.py b/lib-python/conftest.py --- a/lib-python/conftest.py +++ b/lib-python/conftest.py @@ -160,7 +160,7 @@ RegrTest('test_codeop.py', core=True), RegrTest('test_coding.py', core=True), RegrTest('test_coercion.py', core=True), - RegrTest('test_collections.py'), + RegrTest('test_collections.py', usemodules='binascii struct'), RegrTest('test_colorsys.py'), RegrTest('test_commands.py'), RegrTest('test_compare.py', core=True), @@ -181,7 +181,7 @@ RegrTest('test_csv.py', usemodules='_csv'), RegrTest('test_ctypes.py', usemodules="_rawffi thread"), RegrTest('test_curses.py'), - RegrTest('test_datetime.py'), + RegrTest('test_datetime.py', usemodules='binascii struct'), RegrTest('test_dbm.py'), RegrTest('test_decimal.py'), RegrTest('test_decorators.py', core=True), diff --git a/pypy/doc/coding-guide.rst b/pypy/doc/coding-guide.rst --- a/pypy/doc/coding-guide.rst +++ b/pypy/doc/coding-guide.rst @@ -832,7 +832,7 @@ for the next milestone, both from an E-Mail and from a web interface. -.. _`development tracker`: https://codespeak.net/issue/pypy-dev/ +.. _`development tracker`: https://bugs.pypy.org/ use your codespeak login or register ------------------------------------ @@ -841,7 +841,7 @@ tracker. Else, you can `register with the tracker`_ easily. -.. _`register with the tracker`: https://codespeak.net/issue/pypy-dev/user?@template=register +.. _`register with the tracker`: https://bugs.pypy.org/user?@template=register .. _`roundup`: http://roundup.sourceforge.net/ diff --git a/pypy/doc/confrest.py b/pypy/doc/confrest.py --- a/pypy/doc/confrest.py +++ b/pypy/doc/confrest.py @@ -4,7 +4,8 @@ from confrest_oldpy import Project, Page, relpath html = py.xml.html -class PyPyPage(Page): + +class PyPyPage(Page): googlefragment = """ """ + def fill_menubar(self): self.menubar = html.div( - html.a("home", - href=self.get_doclink("index.html"), - class_="menu"), + html.a("home", + href=self.get_doclink("index.html"), + class_="menu"), " ", html.a("blog", href="http://morepypy.blogspot.com", class_="menu"), - " ", + " ", html.a("getting-started", href=self.get_doclink("getting-started.html"), - class_="menu"), + class_="menu"), " ", html.a("documentation", href=self.get_doclink("docindex.html"), class_="menu"), - " ", + " ", html.a("hg", href="https://bitbucket.org/pypy/pypy", class_="menu"), - " ", + " ", html.a("issues", - href="https://codespeak.net/issue/pypy-dev/", + href="https://bugs.pypy.org/", class_="menu"), " ", id="menubar") @@ -43,25 +45,25 @@ return relpath(self.targetpath.strpath, self.project.docpath.join(target).strpath) - def unicode(self, doctype=True): - page = self._root.unicode() + def unicode(self, doctype=True): + page = self._root.unicode() page = page.replace("", self.googlefragment + "") - if doctype: - return self.doctype + page - else: - return page - + if doctype: + return self.doctype + page + else: + return page -class Project(Project): + +class Project(Project): mydir = py.path.local(__file__).dirpath() - title = "PyPy" + title = "PyPy" stylesheet = 'style.css' - encoding = 'latin1' + encoding = 'latin1' prefix_title = "PyPy" logo = html.div( html.a( - html.img(alt="PyPy", id="pyimg", - src="http://codespeak.net/pypy/img/py-web1.png", + html.img(alt="PyPy", id="pyimg", + src="http://codespeak.net/pypy/img/py-web1.png", height=110, width=149))) - Page = PyPyPage + Page = PyPyPage diff --git a/pypy/doc/getting-started.rst b/pypy/doc/getting-started.rst --- a/pypy/doc/getting-started.rst +++ b/pypy/doc/getting-started.rst @@ -1,10 +1,10 @@ ================================== -Getting Started +Getting Started ================================== .. contents:: -.. _howtopypy: +.. _howtopypy: What is PyPy ? ============== @@ -33,8 +33,8 @@ .. _`RPython translation toolchain`: translation.html .. _`more...`: architecture.html -Just the facts -============== +Just the facts +============== Download a pre-built PyPy ------------------------- @@ -125,7 +125,7 @@ ``pypy/pypy`` and documentation files in ``pypy/pypy/doc``. We try to ensure that the tip is always stable, but it might occasionally be broken. You may want to check out `our nightly tests:`_ -find a revision (12-chars alphanumeric string, e.g. "963e808156b3") +find a revision (12-chars alphanumeric string, e.g. "963e808156b3") that passed at least the ``{linux32}`` tests (corresponding to a ``+`` sign on the line ``success``) and then, in your cloned repository, switch to this revision @@ -159,24 +159,24 @@ Understanding PyPy's architecture --------------------------------- -For in-depth information about architecture and coding documentation -head over to the `documentation section`_ where you'll find lots of -interesting information. Additionally, in true hacker spirit, you -may just `start reading sources`_ . +For in-depth information about architecture and coding documentation +head over to the `documentation section`_ where you'll find lots of +interesting information. Additionally, in true hacker spirit, you +may just `start reading sources`_ . .. _`documentation section`: index.html#project-documentation .. _`start reading sources`: getting-started-dev.html#start-reading-sources -Filing bugs or feature requests +Filing bugs or feature requests ------------------------------- You may file `bug reports`_ on our issue tracker which is -also accessible through the 'issues' top menu of -the PyPy website. `Using the development tracker`_ has -more detailed information on specific features of the tracker. +also accessible through the 'issues' top menu of +the PyPy website. `Using the development tracker`_ has +more detailed information on specific features of the tracker. .. _`Using the development tracker`: coding-guide.html#using-development-tracker -.. _bug reports: https://codespeak.net/issue/pypy-dev/ +.. _bug reports: https://bugs.pypy.org/ .. include:: _ref.txt diff --git a/pypy/interpreter/executioncontext.py b/pypy/interpreter/executioncontext.py --- a/pypy/interpreter/executioncontext.py +++ b/pypy/interpreter/executioncontext.py @@ -40,6 +40,7 @@ def gettopframe(self): return self.topframeref() + @jit.unroll_safe def gettopframe_nohidden(self): frame = self.topframeref() while frame and frame.hide(): diff --git a/pypy/interpreter/pytraceback.py b/pypy/interpreter/pytraceback.py --- a/pypy/interpreter/pytraceback.py +++ b/pypy/interpreter/pytraceback.py @@ -1,5 +1,6 @@ from pypy.interpreter import baseobjspace from pypy.interpreter.error import OperationError + from rpython.tool.error import offset2lineno @@ -27,10 +28,10 @@ def descr__reduce__(self, space): from pypy.interpreter.mixedmodule import MixedModule - w_mod = space.getbuiltinmodule('_pickle_support') - mod = space.interp_w(MixedModule, w_mod) + w_mod = space.getbuiltinmodule('_pickle_support') + mod = space.interp_w(MixedModule, w_mod) new_inst = mod.get('traceback_new') - w = space.wrap + w = space.wrap tup_base = [] tup_state = [ @@ -49,6 +50,7 @@ self.lasti = space.int_w(w_lasti) self.next = space.interp_w(PyTraceback, w_next, can_be_None=True) + def record_application_traceback(space, operror, frame, last_instruction): if frame.pycode.hidden_applevel: return @@ -56,10 +58,11 @@ tb = PyTraceback(space, frame, last_instruction, tb) operror.set_traceback(tb) + def check_traceback(space, w_tb, msg): from pypy.interpreter.typedef import PyTraceback tb = space.interpclass_w(w_tb) - if tb is None or not space.is_true(space.isinstance(tb, + if tb is None or not space.is_true(space.isinstance(tb, space.gettypeobject(PyTraceback.typedef))): raise OperationError(space.w_TypeError, space.wrap(msg)) return tb diff --git a/pypy/interpreter/typedef.py b/pypy/interpreter/typedef.py --- a/pypy/interpreter/typedef.py +++ b/pypy/interpreter/typedef.py @@ -1,18 +1,17 @@ -""" +import py - -""" -import py -from pypy.interpreter.gateway import interp2app, BuiltinCode, unwrap_spec,\ - WrappedDefault from pypy.interpreter.argument import Arguments from pypy.interpreter.baseobjspace import Wrappable, DescrMismatch from pypy.interpreter.error import OperationError, operationerrfmt +from pypy.interpreter.gateway import (interp2app, BuiltinCode, unwrap_spec, + WrappedDefault) + +from rpython.rlib.jit import promote +from rpython.rlib.objectmodel import compute_identity_hash, specialize from rpython.tool.sourcetools import compile2, func_with_new_name -from rpython.rlib.objectmodel import instantiate, compute_identity_hash, specialize -from rpython.rlib.jit import promote -class TypeDef: + +class TypeDef(object): def __init__(self, __name, __base=None, __total_ordering__=None, **rawdict): "NOT_RPYTHON: initialization-time only" self.name = __name @@ -27,7 +26,7 @@ self.weakrefable = '__weakref__' in rawdict self.doc = rawdict.pop('__doc__', None) for base in bases: - self.hasdict |= base.hasdict + self.hasdict |= base.hasdict self.weakrefable |= base.weakrefable self.rawdict = {} self.acceptable_as_base_class = '__new__' in rawdict @@ -426,7 +425,7 @@ return unknown_objclass_getter, cls miniglobals = {} if isinstance(cls, str): - assert cls.startswith('<'),"pythontype typecheck should begin with <" + assert cls.startswith('<'), "pythontype typecheck should begin with <" cls_name = cls[1:] typeexpr = "space.w_%s" % cls_name else: @@ -474,7 +473,7 @@ else: try: return self.fget(self, space, w_obj) - except DescrMismatch, e: + except DescrMismatch: return w_obj.descr_call_mismatch( space, '__getattribute__', self.reqcls, Arguments(space, [w_obj, @@ -489,7 +488,7 @@ space.wrap("readonly attribute")) try: fset(self, space, w_obj, w_value) - except DescrMismatch, e: + except DescrMismatch: w_obj.descr_call_mismatch( space, '__setattr__', self.reqcls, Arguments(space, [w_obj, @@ -505,7 +504,7 @@ space.wrap("cannot delete attribute")) try: fdel(self, space, w_obj) - except DescrMismatch, e: + except DescrMismatch: w_obj.descr_call_mismatch( space, '__delattr__', self.reqcls, Arguments(space, [w_obj, @@ -546,6 +545,7 @@ class Member(Wrappable): """For slots.""" _immutable_ = True + def __init__(self, index, name, w_cls): self.index = index self.name = name @@ -617,9 +617,8 @@ from pypy.interpreter.pyframe import PyFrame from pypy.interpreter.pyopcode import SuspendedUnroller from pypy.interpreter.module import Module -from pypy.interpreter.function import Function, Method, StaticMethod -from pypy.interpreter.function import ClassMethod -from pypy.interpreter.function import BuiltinFunction, descr_function_get +from pypy.interpreter.function import (Function, Method, StaticMethod, + ClassMethod, BuiltinFunction, descr_function_get) from pypy.interpreter.pytraceback import PyTraceback from pypy.interpreter.generator import GeneratorIterator from pypy.interpreter.nestedscope import Cell @@ -663,8 +662,10 @@ def fget_co_flags(space, code): # unwrapping through unwrap_spec sig = code.signature() flags = 0 - if sig.has_vararg(): flags |= CO_VARARGS - if sig.has_kwarg(): flags |= CO_VARKEYWORDS + if sig.has_vararg(): + flags |= CO_VARARGS + if sig.has_kwarg(): + flags |= CO_VARKEYWORDS return space.wrap(flags) def fget_co_consts(space, code): # unwrapping through unwrap_spec @@ -728,7 +729,7 @@ __eq__ = interp2app(PyCode.descr_code__eq__), __ne__ = descr_generic_ne, __hash__ = interp2app(PyCode.descr_code__hash__), - __reduce__ = interp2app(PyCode.descr__reduce__), + __reduce__ = interp2app(PyCode.descr__reduce__), __repr__ = interp2app(PyCode.repr), co_argcount = interp_attrproperty('co_argcount', cls=PyCode), co_nlocals = interp_attrproperty('co_nlocals', cls=PyCode), @@ -737,9 +738,9 @@ co_code = interp_attrproperty('co_code', cls=PyCode), co_consts = GetSetProperty(PyCode.fget_co_consts), co_names = GetSetProperty(PyCode.fget_co_names), - co_varnames = GetSetProperty(PyCode.fget_co_varnames), - co_freevars = GetSetProperty(PyCode.fget_co_freevars), - co_cellvars = GetSetProperty(PyCode.fget_co_cellvars), + co_varnames = GetSetProperty(PyCode.fget_co_varnames), + co_freevars = GetSetProperty(PyCode.fget_co_freevars), + co_cellvars = GetSetProperty(PyCode.fget_co_cellvars), co_filename = interp_attrproperty('co_filename', cls=PyCode), co_name = interp_attrproperty('co_name', cls=PyCode), co_firstlineno = interp_attrproperty('co_firstlineno', cls=PyCode), @@ -749,7 +750,7 @@ PyCode.typedef.acceptable_as_base_class = False PyFrame.typedef = TypeDef('frame', - __reduce__ = interp2app(PyFrame.descr__reduce__), + __reduce__ = interp2app(PyFrame.descr__reduce__), __setstate__ = interp2app(PyFrame.descr__setstate__), f_builtins = GetSetProperty(PyFrame.fget_f_builtins), f_lineno = GetSetProperty(PyFrame.fget_f_lineno, PyFrame.fset_f_lineno), @@ -827,9 +828,9 @@ __new__ = interp2app(Method.descr_method__new__.im_func), __call__ = interp2app(Method.descr_method_call), __get__ = interp2app(Method.descr_method_get), - im_func = interp_attrproperty_w('w_function', cls=Method), + im_func = interp_attrproperty_w('w_function', cls=Method), __func__ = interp_attrproperty_w('w_function', cls=Method), - im_self = interp_attrproperty_w('w_instance', cls=Method), + im_self = interp_attrproperty_w('w_instance', cls=Method), __self__ = interp_attrproperty_w('w_instance', cls=Method), im_class = interp_attrproperty_w('w_class', cls=Method), __getattribute__ = interp2app(Method.descr_method_getattribute), @@ -886,7 +887,7 @@ def always_none(self, obj): return None -BuiltinFunction.typedef = TypeDef("builtin_function",**Function.typedef.rawdict) +BuiltinFunction.typedef = TypeDef("builtin_function", **Function.typedef.rawdict) BuiltinFunction.typedef.rawdict.update({ '__new__': interp2app(BuiltinFunction.descr_builtinfunction__new__.im_func), '__self__': GetSetProperty(always_none, cls=BuiltinFunction), @@ -897,12 +898,12 @@ BuiltinFunction.typedef.acceptable_as_base_class = False PyTraceback.typedef = TypeDef("traceback", - __reduce__ = interp2app(PyTraceback.descr__reduce__), + __reduce__ = interp2app(PyTraceback.descr__reduce__), __setstate__ = interp2app(PyTraceback.descr__setstate__), - tb_frame = interp_attrproperty('frame', cls=PyTraceback), - tb_lasti = interp_attrproperty('lasti', cls=PyTraceback), + tb_frame = interp_attrproperty('frame', cls=PyTraceback), + tb_lasti = interp_attrproperty('lasti', cls=PyTraceback), tb_lineno = GetSetProperty(PyTraceback.descr_tb_lineno), - tb_next = interp_attrproperty('next', cls=PyTraceback), + tb_next = interp_attrproperty('next', cls=PyTraceback), ) PyTraceback.typedef.acceptable_as_base_class = False @@ -937,12 +938,12 @@ Cell.typedef.acceptable_as_base_class = False Ellipsis.typedef = TypeDef("Ellipsis", - __repr__ = interp2app(Ellipsis.descr__repr__), + __repr__ = interp2app(Ellipsis.descr__repr__), ) Ellipsis.typedef.acceptable_as_base_class = False NotImplemented.typedef = TypeDef("NotImplemented", - __repr__ = interp2app(NotImplemented.descr__repr__), + __repr__ = interp2app(NotImplemented.descr__repr__), ) NotImplemented.typedef.acceptable_as_base_class = False diff --git a/pypy/module/__pypy__/interp_identitydict.py b/pypy/module/__pypy__/interp_identitydict.py --- a/pypy/module/__pypy__/interp_identitydict.py +++ b/pypy/module/__pypy__/interp_identitydict.py @@ -33,6 +33,11 @@ except KeyError: raise OperationError(space.w_KeyError, w_key) + def descr_iter(self, space): + raise OperationError(space.w_TypeError, + space.wrap("'identity_dict' object does not support iteration; " + "iterate over x.keys()")) + def get(self, space, w_key, w_default=None): if w_default is None: w_default = space.w_None @@ -50,8 +55,11 @@ W_IdentityDict.typedef = TypeDef("identity_dict", __doc__="""\ A dictionary that considers keys by object identity. -Distinct objects that compare equal will have separate entries. -All objects can be used as keys, even non-hashable ones. +Distinct objects will have separate entries even if they +compare equal. All objects can be used as keys, even +non-hashable ones --- but avoid using immutable objects +like integers: two int objects 42 may or may not be +internally the same object. """, __new__ = interp2app(W_IdentityDict.descr_new.im_func), __len__ = interp2app(W_IdentityDict.descr_len), @@ -59,6 +67,7 @@ __setitem__ = interp2app(W_IdentityDict.descr_setitem), __getitem__ = interp2app(W_IdentityDict.descr_getitem), __delitem__ = interp2app(W_IdentityDict.descr_delitem), + __iter__ = interp2app(W_IdentityDict.descr_iter), get = interp2app(W_IdentityDict.get), keys = interp2app(W_IdentityDict.keys), values = interp2app(W_IdentityDict.values), diff --git a/pypy/module/__pypy__/test/test_identitydict.py b/pypy/module/__pypy__/test/test_identitydict.py --- a/pypy/module/__pypy__/test/test_identitydict.py +++ b/pypy/module/__pypy__/test/test_identitydict.py @@ -56,3 +56,10 @@ assert None in d assert [] not in d + + def test_iterate(self): + from __pypy__ import identity_dict + d = identity_dict() + d[None] = 1 + raises(TypeError, iter, d) + raises(TypeError, list, d) diff --git a/pypy/module/signal/interp_signal.py b/pypy/module/signal/interp_signal.py --- a/pypy/module/signal/interp_signal.py +++ b/pypy/module/signal/interp_signal.py @@ -60,7 +60,6 @@ def __init__(self, space): "NOT_RPYTHON" AsyncAction.__init__(self, space) - self.handlers_w = {} self.pending_signal = -1 self.fire_in_main_thread = False if self.space.config.objspace.usemodules.thread: @@ -91,7 +90,7 @@ # If we are in the main thread, report the signal now, # and poll more self.pending_signal = -1 - self._report_signal(n) + report_signal(self.space, n) n = self.pending_signal if n < 0: n = pypysig_poll() else: @@ -110,20 +109,31 @@ pypysig_pushback(cpy_signal.SIGINT) self.fire_in_main_thread = True - def _report_signal(self, n): - try: - w_handler = self.handlers_w[n] - except KeyError: - return # no handler, ignore signal - space = self.space - if not space.is_true(space.callable(w_handler)): - return # w_handler is SIG_IGN or SIG_DFL? - # re-install signal handler, for OSes that clear it - pypysig_reinstall(n) - # invoke the app-level handler - ec = space.getexecutioncontext() - w_frame = space.wrap(ec.gettopframe_nohidden()) - space.call_function(w_handler, space.wrap(n), w_frame) +# ____________________________________________________________ + + +class Handlers: + def __init__(self, space): + self.handlers_w = {} + +def _get_handlers(space): + return space.fromcache(Handlers).handlers_w + + +def report_signal(space, n): + handlers_w = _get_handlers(space) + try: + w_handler = handlers_w[n] + except KeyError: + return # no handler, ignore signal + if not space.is_true(space.callable(w_handler)): + return # w_handler is SIG_IGN or SIG_DFL? + # re-install signal handler, for OSes that clear it + pypysig_reinstall(n) + # invoke the app-level handler + ec = space.getexecutioncontext() + w_frame = space.wrap(ec.gettopframe_nohidden()) + space.call_function(w_handler, space.wrap(n), w_frame) @unwrap_spec(signum=int) @@ -141,9 +151,9 @@ check_signum_exists(space, signum) else: check_signum_in_range(space, signum) - action = space.check_signal_action - if signum in action.handlers_w: - return action.handlers_w[signum] + handlers_w = _get_handlers(space) + if signum in handlers_w: + return handlers_w[signum] return space.wrap(SIG_DFL) @@ -204,7 +214,6 @@ "main thread")) old_handler = getsignal(space, signum) - action = space.check_signal_action if space.eq_w(w_handler, space.wrap(SIG_DFL)): pypysig_default(signum) elif space.eq_w(w_handler, space.wrap(SIG_IGN)): @@ -215,7 +224,8 @@ space.wrap("'handler' must be a callable " "or SIG_DFL or SIG_IGN")) pypysig_setflag(signum) - action.handlers_w[signum] = w_handler + handlers_w = _get_handlers(space) + handlers_w[signum] = w_handler return old_handler diff --git a/pypy/module/thread/os_lock.py b/pypy/module/thread/os_lock.py --- a/pypy/module/thread/os_lock.py +++ b/pypy/module/thread/os_lock.py @@ -38,10 +38,10 @@ @unwrap_spec(waitflag=int) def descr_lock_acquire(self, space, waitflag=1): - """Lock the lock. Without argument, this blocks if the lock is already -locked (even by the same thread), waiting for another thread to release -the lock, and return None once the lock is acquired. -With an argument, this will only block if the argument is true, + """Lock the lock. With the default argument of True, this blocks +if the lock is already locked (even by the same thread), waiting for +another thread to release the lock, and returns True once the lock is +acquired. With an argument of False, this will always return immediately and the return value reflects whether the lock is acquired. The blocking operation is not interruptible.""" mylock = self.lock @@ -113,4 +113,4 @@ def allocate_lock(space): """Create a new lock object. (allocate() is an obsolete synonym.) See LockType.__doc__ for information about locks.""" - return space.wrap(Lock(space)) \ No newline at end of file + return space.wrap(Lock(space)) diff --git a/pypy/module/thread/test/test_lock.py b/pypy/module/thread/test/test_lock.py --- a/pypy/module/thread/test/test_lock.py +++ b/pypy/module/thread/test/test_lock.py @@ -12,7 +12,10 @@ assert lock.locked() is False raises(thread.error, lock.release) assert lock.locked() is False - lock.acquire() + r = lock.acquire() + assert r is True + r = lock.acquire(False) + assert r is False assert lock.locked() is True lock.release() assert lock.locked() is False diff --git a/pypy/objspace/std/tupleobject.py b/pypy/objspace/std/tupleobject.py --- a/pypy/objspace/std/tupleobject.py +++ b/pypy/objspace/std/tupleobject.py @@ -85,6 +85,15 @@ start, stop = normalize_simple_slice(space, length, w_start, w_stop) return space.newtuple(w_tuple.wrappeditems[start:stop]) +THRESHOLD = 7 + +def unroll_tuple_contains(space, w_tuple, w_obj): + if (jit.isconstant(w_tuple) or jit.isvirtual(w_tuple) and + len(w_tuple.wrappeditems) < THRESHOLD): + return True + return False + + at jit.look_inside_iff(unroll_tuple_contains) def contains__Tuple_ANY(space, w_tuple, w_obj): for w_item in w_tuple.wrappeditems: if space.eq_w(w_item, w_obj): diff --git a/pypy/objspace/std/typeobject.py b/pypy/objspace/std/typeobject.py --- a/pypy/objspace/std/typeobject.py +++ b/pypy/objspace/std/typeobject.py @@ -1,24 +1,23 @@ +from pypy.interpreter import gateway +from pypy.interpreter.baseobjspace import W_Root +from pypy.interpreter.error import OperationError, operationerrfmt +from pypy.interpreter.function import Function, StaticMethod +from pypy.interpreter.typedef import weakref_descr from pypy.objspace.std.model import W_Object from pypy.objspace.std.register_all import register_all -from pypy.interpreter.function import Function, StaticMethod -from pypy.interpreter import gateway -from pypy.interpreter.error import OperationError, operationerrfmt -from pypy.interpreter.typedef import weakref_descr -from pypy.interpreter.baseobjspace import W_Root from pypy.objspace.std.stdtypedef import std_dict_descr, issubtypedef, Member -from pypy.objspace.std.objecttype import object_typedef -from pypy.objspace.std import identitydict -from rpython.rlib.objectmodel import we_are_translated + +from rpython.rlib.jit import (promote, elidable_promote, we_are_jitted, + promote_string, elidable, dont_look_inside, unroll_safe) from rpython.rlib.objectmodel import current_object_addr_as_int, compute_hash -from rpython.rlib.jit import promote, elidable_promote, we_are_jitted,\ - promote_string -from rpython.rlib.jit import elidable, dont_look_inside, unroll_safe from rpython.rlib.rarithmetic import intmask, r_uint + class TypeCell(W_Root): def __init__(self, w_value=None): self.w_value = w_value + def unwrap_cell(space, w_value): if (space.config.objspace.std.withtypeversion and isinstance(w_value, TypeCell)): @@ -278,7 +277,7 @@ if attr in w_self.lazyloaders: # very clever next line: it forces the attr string # to be interned. - w_attr = space.new_interned_str(attr) + space.new_interned_str(attr) loader = w_self.lazyloaders[attr] del w_self.lazyloaders[attr] w_value = loader() @@ -497,7 +496,7 @@ def get_module(w_self): space = w_self.space - if w_self.is_heaptype() and '__module__' in w_self.dict_w: + if w_self.is_heaptype() and w_self.getdictvalue(space, '__module__') is not None: return w_self.getdictvalue(space, '__module__') else: # for non-heap types, CPython checks for a module.name in the @@ -516,7 +515,7 @@ mod = '__builtin__' else: mod = space.str_w(w_mod) - if mod !='__builtin__': + if mod != '__builtin__': return '%s.%s' % (mod, w_self.name) else: return w_self.name @@ -560,13 +559,15 @@ subclasses_w.append(w_ob) return subclasses_w - # for now, weakref support for W_TypeObject is hard to get automatically _lifeline_ = None + def getweakref(self): return self._lifeline_ + def setweakref(self, space, weakreflifeline): self._lifeline_ = weakreflifeline + def delweakref(self): self._lifeline_ = None @@ -693,9 +694,12 @@ else: create_slot(w_self, slot_name) wantdict = wantdict or hasoldstylebase - if wantdict: create_dict_slot(w_self) - if wantweakref: create_weakref_slot(w_self) - if '__del__' in dict_w: w_self.needsdel = True + if wantdict: + create_dict_slot(w_self) + if wantweakref: + create_weakref_slot(w_self) + if '__del__' in dict_w: + w_self.needsdel = True def create_slot(w_self, slot_name): space = w_self.space @@ -868,7 +872,7 @@ kind = 'type' else: kind = 'class' - if mod is not None and mod !='__builtin__': + if mod is not None and mod != '__builtin__': return space.wrap("<%s '%s.%s'>" % (kind, mod, w_obj.name)) else: return space.wrap("<%s '%s'>" % (kind, w_obj.name)) @@ -887,7 +891,7 @@ # __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) + return space.get(w_descr, w_type) raise operationerrfmt(space.w_AttributeError, "type object '%s' has no attribute '%s'", w_type.name, name) @@ -933,7 +937,7 @@ return mro_error(space, orderlists) # no candidate found assert candidate not in order order.append(candidate) - for i in range(len(orderlists)-1, -1, -1): + for i in range(len(orderlists) - 1, -1, -1): if orderlists[i][0] is candidate: del orderlists[i][0] if len(orderlists[i]) == 0: diff --git a/pypy/objspace/std/typetype.py b/pypy/objspace/std/typetype.py --- a/pypy/objspace/std/typetype.py +++ b/pypy/objspace/std/typetype.py @@ -1,5 +1,4 @@ from pypy.interpreter import gateway -from pypy.interpreter.argument import Arguments from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.typedef import (GetSetProperty, descr_get_dict, weakref_descr) @@ -90,9 +89,9 @@ return space.wrap(w_type.name) def descr_set__name__(space, w_type, w_value): - w_type = _check(space, w_type) + w_type = _check(space, w_type) if not w_type.is_heaptype(): - raise operationerrfmt(space.w_TypeError, + raise operationerrfmt(space.w_TypeError, "can't set %s.__name__", w_type.name) w_type.name = space.str_w(w_value) @@ -119,10 +118,9 @@ def descr_set__bases__(space, w_type, w_value): # this assumes all app-level type objects are W_TypeObject - from pypy.objspace.std.typeobject import W_TypeObject - from pypy.objspace.std.typeobject import check_and_find_best_base - from pypy.objspace.std.typeobject import get_parent_layout - from pypy.objspace.std.typeobject import is_mro_purely_of_types + from pypy.objspace.std.typeobject import (W_TypeObject, get_parent_layout, + check_and_find_best_base, is_mro_purely_of_types) + w_type = _check(space, w_type) if not w_type.is_heaptype(): raise operationerrfmt(space.w_TypeError, @@ -213,9 +211,12 @@ # w_type = _check(space, w_type) flags = 0 - if w_type.flag_heaptype: flags |= _HEAPTYPE - if w_type.flag_cpytype: flags |= _CPYTYPE - if w_type.flag_abstract: flags |= _ABSTRACT + if w_type.flag_heaptype: + flags |= _HEAPTYPE + if w_type.flag_cpytype: + flags |= _CPYTYPE + if w_type.flag_abstract: + flags |= _ABSTRACT return space.wrap(flags) def descr_get__module(space, w_type): diff --git a/rpython/flowspace/specialcase.py b/rpython/flowspace/specialcase.py --- a/rpython/flowspace/specialcase.py +++ b/rpython/flowspace/specialcase.py @@ -65,8 +65,18 @@ def sc_we_are_translated(space, we_are_translated, args): return Constant(True) +def sc_locals(space, locals, args): + raise Exception( + "A function calling locals() is not RPython. " + "Note that if you're translating code outside the PyPy " + "repository, a likely cause is that py.test's --assert=rewrite " + "mode is getting in the way. You should copy the file " + "pytest.ini from the root of the PyPy repository into your " + "own project.") + SPECIAL_CASES = {__import__: sc_import, r_uint: sc_r_uint, - we_are_translated: sc_we_are_translated} + we_are_translated: sc_we_are_translated, + locals: sc_locals} for fn in OperationName: SPECIAL_CASES[fn] = sc_operator diff --git a/rpython/translator/c/src/profiling.c b/rpython/translator/c/src/profiling.c --- a/rpython/translator/c/src/profiling.c +++ b/rpython/translator/c/src/profiling.c @@ -8,8 +8,8 @@ #include #endif -cpu_set_t base_cpu_set; -int profiling_setup = 0; +static cpu_set_t base_cpu_set; +static int profiling_setup = 0; void pypy_setup_profiling() { @@ -37,8 +37,8 @@ #include -DWORD_PTR base_affinity_mask; -int profiling_setup = 0; +static DWORD_PTR base_affinity_mask; +static int profiling_setup = 0; void pypy_setup_profiling() { if (!profiling_setup) { diff --git a/rpython/translator/platform/__init__.py b/rpython/translator/platform/__init__.py --- a/rpython/translator/platform/__init__.py +++ b/rpython/translator/platform/__init__.py @@ -53,9 +53,18 @@ ofiles = self._compile_o_files(cfiles, eci, standalone) return self._finish_linking(ofiles, eci, outputfilename, standalone) + def _all_cfiles(self, cfiles, eci): + seen = set() + result = [] + for cfile in list(cfiles) + list(eci.separate_module_files): + cfile = py.path.local(cfile) + if cfile not in seen: + seen.add(cfile) + result.append(cfile) + return result + def _compile_o_files(self, cfiles, eci, standalone=True): - cfiles = [py.path.local(f) for f in cfiles] - cfiles += [py.path.local(f) for f in eci.separate_module_files] + cfiles = self._all_cfiles(cfiles, eci) compile_args = self._compile_args_from_eci(eci, standalone) ofiles = [] for cfile in cfiles: diff --git a/rpython/translator/platform/posix.py b/rpython/translator/platform/posix.py --- a/rpython/translator/platform/posix.py +++ b/rpython/translator/platform/posix.py @@ -84,8 +84,7 @@ def gen_makefile(self, cfiles, eci, exe_name=None, path=None, shared=False): - cfiles = [py.path.local(f) for f in cfiles] - cfiles += [py.path.local(f) for f in eci.separate_module_files] + cfiles = self._all_cfiles(cfiles, eci) if path is None: path = cfiles[0].dirpath() diff --git a/rpython/translator/platform/windows.py b/rpython/translator/platform/windows.py --- a/rpython/translator/platform/windows.py +++ b/rpython/translator/platform/windows.py @@ -248,8 +248,7 @@ def gen_makefile(self, cfiles, eci, exe_name=None, path=None, shared=False): - cfiles = [py.path.local(f) for f in cfiles] - cfiles += [py.path.local(f) for f in eci.separate_module_files] + cfiles = self._all_cfiles(cfiles, eci) if path is None: path = cfiles[0].dirpath() From noreply at buildbot.pypy.org Wed Feb 6 01:32:13 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Wed, 6 Feb 2013 01:32:13 +0100 (CET) Subject: [pypy-commit] pypy py3k: add _io Warnings Message-ID: <20130206003213.B0B0A1C0613@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r60890:0a5251c5e487 Date: 2013-02-05 16:28 -0800 http://bitbucket.org/pypy/pypy/changeset/0a5251c5e487/ Log: add _io Warnings diff --git a/pypy/module/_io/interp_bufferedio.py b/pypy/module/_io/interp_bufferedio.py --- a/pypy/module/_io/interp_bufferedio.py +++ b/pypy/module/_io/interp_bufferedio.py @@ -104,6 +104,9 @@ rwbuffer.setslice(0, data) return space.wrap(len(data)) + def _complain_about_max_buffer_size(self, space): + space.warn("max_buffer_size is deprecated", space.w_DeprecationWarning) + W_BufferedIOBase.typedef = TypeDef( '_io._BufferedIOBase', W_IOBase.typedef, __new__ = generic_new_descr(W_BufferedIOBase), @@ -316,6 +319,9 @@ with self.lock: space.call_method(self.w_raw, "close") + def _dealloc_warn_w(self, space, w_source): + space.call_method(self.w_raw, "_dealloc_warn", w_source) + def simple_flush_w(self, space): self._check_init(space) return space.call_method(self.w_raw, "flush") @@ -810,14 +816,18 @@ truncate = interp2app(W_BufferedReader.truncate_w), fileno = interp2app(W_BufferedReader.fileno_w), isatty = interp2app(W_BufferedReader.isatty_w), + _dealloc_warn = interp2app(W_BufferedReader._dealloc_warn_w), closed = GetSetProperty(W_BufferedReader.closed_get_w), name = GetSetProperty(W_BufferedReader.name_get_w), mode = GetSetProperty(W_BufferedReader.mode_get_w), ) class W_BufferedWriter(BufferedMixin, W_BufferedIOBase): - @unwrap_spec(buffer_size=int) - def descr_init(self, space, w_raw, buffer_size=DEFAULT_BUFFER_SIZE): + @unwrap_spec(buffer_size=int, max_buffer_size=int) + def descr_init(self, space, w_raw, buffer_size=DEFAULT_BUFFER_SIZE, + max_buffer_size=-234): + if max_buffer_size != -234: + self._complain_about_max_buffer_size(space) self.state = STATE_ZERO check_writable_w(space, w_raw) @@ -851,6 +861,7 @@ isatty = interp2app(W_BufferedWriter.isatty_w), detach = interp2app(W_BufferedWriter.detach_w), truncate = interp2app(W_BufferedWriter.truncate_w), + _dealloc_warn = interp2app(W_BufferedWriter._dealloc_warn_w), closed = GetSetProperty(W_BufferedWriter.closed_get_w), name = GetSetProperty(W_BufferedWriter.name_get_w), mode = GetSetProperty(W_BufferedWriter.mode_get_w), @@ -876,10 +887,12 @@ w_reader = None w_writer = None - @unwrap_spec(buffer_size=int) + @unwrap_spec(buffer_size=int, max_buffer_size=int) def descr_init(self, space, w_reader, w_writer, - buffer_size=DEFAULT_BUFFER_SIZE): + buffer_size=DEFAULT_BUFFER_SIZE, max_buffer_size=-234): try: + if max_buffer_size != -234: + self._complain_about_max_buffer_size(space) self.w_reader = W_BufferedReader(space) self.w_reader.descr_init(space, w_reader, buffer_size) self.w_writer = W_BufferedWriter(space) @@ -931,10 +944,13 @@ ) class W_BufferedRandom(BufferedMixin, W_BufferedIOBase): - @unwrap_spec(buffer_size=int) - def descr_init(self, space, w_raw, buffer_size=DEFAULT_BUFFER_SIZE): + @unwrap_spec(buffer_size=int, max_buffer_size=int) + def descr_init(self, space, w_raw, buffer_size=DEFAULT_BUFFER_SIZE, + max_buffer_size=-234): + if max_buffer_size != -234: + self._complain_about_max_buffer_size(space) + self.state = STATE_ZERO - check_readable_w(space, w_raw) check_writable_w(space, w_raw) check_seekable_w(space, w_raw) @@ -975,6 +991,7 @@ truncate = interp2app(W_BufferedRandom.truncate_w), fileno = interp2app(W_BufferedRandom.fileno_w), isatty = interp2app(W_BufferedRandom.isatty_w), + _dealloc_warn = interp2app(W_BufferedRandom._dealloc_warn_w), closed = GetSetProperty(W_BufferedRandom.closed_get_w), name = GetSetProperty(W_BufferedRandom.name_get_w), mode = GetSetProperty(W_BufferedRandom.mode_get_w), diff --git a/pypy/module/_io/interp_fileio.py b/pypy/module/_io/interp_fileio.py --- a/pypy/module/_io/interp_fileio.py +++ b/pypy/module/_io/interp_fileio.py @@ -246,6 +246,16 @@ self._close(space) W_RawIOBase.close_w(self, space) + def _dealloc_warn_w(self, space, w_source): + if self.fd >= 0 and self.closefd: + try: + r = space.unicode_w(space.repr(w_source)) + space.warn("unclosed file %s" % r, space.w_ResourceWarning) + except OperationError as e: + # Spurious errors can appear at shutdown + if e.match(space, space.w_Warning): + e.write_unraisable(space, '', space.wrap(self)) + def _dircheck(self, space, w_filename): # On Unix, fopen will succeed for directories. # In Python, there should be no file objects referring to @@ -443,6 +453,7 @@ seekable = interp2app(W_FileIO.seekable_w), fileno = interp2app(W_FileIO.fileno_w), isatty = interp2app(W_FileIO.isatty_w), + _dealloc_warn = interp2app(W_FileIO._dealloc_warn_w), name = interp_member_w('w_name', cls=W_FileIO), closefd = interp_attrproperty( 'closefd', cls=W_FileIO, diff --git a/pypy/module/_io/interp_iobase.py b/pypy/module/_io/interp_iobase.py --- a/pypy/module/_io/interp_iobase.py +++ b/pypy/module/_io/interp_iobase.py @@ -71,7 +71,10 @@ # If `closed` doesn't exist or can't be evaluated as bool, then # the object is probably in an unusable state, so ignore. if w_closed is not None and not space.is_true(w_closed): - space.call_method(self, "close") + try: + self._dealloc_warn_w(space, space.wrap(self)) + finally: + space.call_method(self, "close") except OperationError: # Silencing I/O errors is bad, but printing spurious tracebacks is # equally as bad, and potentially more frequent (because of @@ -109,6 +112,10 @@ self.__IOBase_closed = True get_autoflushher(space).remove(self) + def _dealloc_warn_w(self, space, w_source): + """Called when the io is implicitly closed via the deconstructor""" + pass + def flush_w(self, space): if self._CLOSED(): raise OperationError( diff --git a/pypy/module/_io/interp_textio.py b/pypy/module/_io/interp_textio.py --- a/pypy/module/_io/interp_textio.py +++ b/pypy/module/_io/interp_textio.py @@ -503,6 +503,9 @@ space.call_method(self, "flush") return space.call_method(self.w_buffer, "close") + def _dealloc_warn_w(self, space, w_source): + space.call_method(self.w_buffer, "_dealloc_warn", w_source) + # _____________________________________________________________ # read methods @@ -1007,6 +1010,7 @@ writable = interp2app(W_TextIOWrapper.writable_w), seekable = interp2app(W_TextIOWrapper.seekable_w), fileno = interp2app(W_TextIOWrapper.fileno_w), + _dealloc_warn = interp2app(W_TextIOWrapper._dealloc_warn_w), name = GetSetProperty(W_TextIOWrapper.name_get_w), buffer = interp_attrproperty_w("w_buffer", cls=W_TextIOWrapper), closed = GetSetProperty(W_TextIOWrapper.closed_get_w), diff --git a/pypy/module/_io/test/test_bufferedio.py b/pypy/module/_io/test/test_bufferedio.py --- a/pypy/module/_io/test/test_bufferedio.py +++ b/pypy/module/_io/test/test_bufferedio.py @@ -613,6 +613,31 @@ assert raw.getvalue() == b'1b\n2def\n3\n' +class AppTestDeprecation: + + def w_check_max_buffer_size_deprecation(self, test): + import _io + import _warnings + def simplefilter(action, category): + _warnings.filters.insert(0, (action, None, category, None, 0)) + simplefilter('error', DeprecationWarning) + try: + test(_io.BytesIO(), 8, 12) + except DeprecationWarning as e: + assert 'max_buffer_size is deprecated' in str(e) + else: + assert False, 'Expected DeprecationWarning' + finally: + simplefilter('default', DeprecationWarning) + + def test_max_buffer_size_deprecation(self): + import _io + self.check_max_buffer_size_deprecation(_io.BufferedWriter) + self.check_max_buffer_size_deprecation(_io.BufferedRandom) + self.check_max_buffer_size_deprecation( + lambda raw, *args: _io.BufferedRWPair(raw, raw, *args)) + + class TestNonReentrantLock: spaceconfig = dict(usemodules=['thread']) diff --git a/pypy/module/_io/test/test_io.py b/pypy/module/_io/test/test_io.py --- a/pypy/module/_io/test/test_io.py +++ b/pypy/module/_io/test/test_io.py @@ -333,3 +333,21 @@ assert res == "world\n" assert f.newlines == "\n" assert type(f.newlines) is str + + def w__check_warn_on_dealloc(self, *args, **kwargs): + import gc + import warnings + + f = open(*args, **kwargs) + r = repr(f) + with warnings.catch_warnings(record=True) as w: + warnings.simplefilter('always') + f = None + gc.collect() + assert len(w) == 1, len(w) + assert r in str(w[0]) + + def test_warn_on_dealloc(self): + self._check_warn_on_dealloc(self.tmpfile, 'wb', buffering=0) + self._check_warn_on_dealloc(self.tmpfile, 'wb') + self._check_warn_on_dealloc(self.tmpfile, 'w') From noreply at buildbot.pypy.org Wed Feb 6 02:05:27 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Wed, 6 Feb 2013 02:05:27 +0100 (CET) Subject: [pypy-commit] pypy default: add argtypes to silence some warnings Message-ID: <20130206010527.33B0C1C0613@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r60891:0a4512ee16b3 Date: 2013-02-05 20:04 -0500 http://bitbucket.org/pypy/pypy/changeset/0a4512ee16b3/ Log: add argtypes to silence some warnings diff --git a/lib_pypy/ctypes_support.py b/lib_pypy/ctypes_support.py --- a/lib_pypy/ctypes_support.py +++ b/lib_pypy/ctypes_support.py @@ -19,16 +19,19 @@ if sys.platform == 'win32': standard_c_lib._errno.restype = ctypes.POINTER(ctypes.c_int) + standard_c_lib._errno.argtypes = None def _where_is_errno(): return standard_c_lib._errno() elif sys.platform in ('linux2', 'freebsd6'): standard_c_lib.__errno_location.restype = ctypes.POINTER(ctypes.c_int) + standard_c_lib.__errno_location.argtypes = None def _where_is_errno(): return standard_c_lib.__errno_location() elif sys.platform in ('darwin', 'freebsd7', 'freebsd8', 'freebsd9'): standard_c_lib.__error.restype = ctypes.POINTER(ctypes.c_int) + standard_c_lib.__error.argtypes = None def _where_is_errno(): return standard_c_lib.__error() From noreply at buildbot.pypy.org Wed Feb 6 03:54:08 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Wed, 6 Feb 2013 03:54:08 +0100 (CET) Subject: [pypy-commit] pypy default: __future__ is frozen, so use another module's __file__ (see issue1259) Message-ID: <20130206025408.3512C1C0673@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r60892:fa85e21b3f1b Date: 2013-02-05 21:45 -0500 http://bitbucket.org/pypy/pypy/changeset/fa85e21b3f1b/ Log: __future__ is frozen, so use another module's __file__ (see issue1259) diff --git a/lib-python/2.7/test/test_modulefinder.py b/lib-python/2.7/test/test_modulefinder.py --- a/lib-python/2.7/test/test_modulefinder.py +++ b/lib-python/2.7/test/test_modulefinder.py @@ -16,7 +16,7 @@ # library. TEST_DIR = tempfile.mkdtemp() -TEST_PATH = [TEST_DIR, os.path.dirname(__future__.__file__)] +TEST_PATH = [TEST_DIR, os.path.dirname(tempfile.__file__)] # Each test description is a list of 5 items: # From noreply at buildbot.pypy.org Wed Feb 6 06:22:21 2013 From: noreply at buildbot.pypy.org (jphalip) Date: Wed, 6 Feb 2013 06:22:21 +0100 (CET) Subject: [pypy-commit] pypy popen2-removal: Use subprocess instead of the deprecated popen2 inside posix.popen(). The 'signal' and 'select' modules are included in the tests as they're imported by subprocess. Message-ID: <20130206052221.49AFD1C008F@cobra.cs.uni-duesseldorf.de> Author: Julien Phalip Branch: popen2-removal Changeset: r60893:82e23579d3e9 Date: 2013-02-05 21:12 -0800 http://bitbucket.org/pypy/pypy/changeset/82e23579d3e9/ Log: Use subprocess instead of the deprecated popen2 inside posix.popen(). The 'signal' and 'select' modules are included in the tests as they're imported by subprocess. diff --git a/pypy/module/posix/app_posix.py b/pypy/module/posix/app_posix.py --- a/pypy/module/posix/app_posix.py +++ b/pypy/module/posix/app_posix.py @@ -140,7 +140,7 @@ Open a pipe to/from a command returning a file object.""" - from popen2 import MAXFD + from subprocess import MAXFD import os, gc def try_close(fd): diff --git a/pypy/module/posix/test/test_posix2.py b/pypy/module/posix/test/test_posix2.py --- a/pypy/module/posix/test/test_posix2.py +++ b/pypy/module/posix/test/test_posix2.py @@ -14,7 +14,7 @@ import signal def setup_module(mod): - usemodules = ['binascii', 'posix', 'struct', 'rctime'] + usemodules = ['binascii', 'posix', 'struct', 'rctime', 'signal', 'select'] if os.name != 'nt': usemodules += ['fcntl'] else: From noreply at buildbot.pypy.org Wed Feb 6 06:22:22 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Wed, 6 Feb 2013 06:22:22 +0100 (CET) Subject: [pypy-commit] pypy default: Merged in jphalip/pypy/popen2-removal (pull request #114) Message-ID: <20130206052222.7EAA41C008F@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r60894:1042c2c9707e Date: 2013-02-05 21:22 -0800 http://bitbucket.org/pypy/pypy/changeset/1042c2c9707e/ Log: Merged in jphalip/pypy/popen2-removal (pull request #114) Use subprocess instead of the deprecated popen2 inside posix.popen() diff --git a/pypy/module/posix/app_posix.py b/pypy/module/posix/app_posix.py --- a/pypy/module/posix/app_posix.py +++ b/pypy/module/posix/app_posix.py @@ -140,7 +140,7 @@ Open a pipe to/from a command returning a file object.""" - from popen2 import MAXFD + from subprocess import MAXFD import os, gc def try_close(fd): diff --git a/pypy/module/posix/test/test_posix2.py b/pypy/module/posix/test/test_posix2.py --- a/pypy/module/posix/test/test_posix2.py +++ b/pypy/module/posix/test/test_posix2.py @@ -14,7 +14,7 @@ import signal def setup_module(mod): - usemodules = ['binascii', 'posix', 'struct', 'rctime'] + usemodules = ['binascii', 'posix', 'struct', 'rctime', 'signal', 'select'] if os.name != 'nt': usemodules += ['fcntl'] else: From noreply at buildbot.pypy.org Wed Feb 6 06:27:40 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Wed, 6 Feb 2013 06:27:40 +0100 (CET) Subject: [pypy-commit] pypy default: fix whatsnew Message-ID: <20130206052740.CD93C1C062C@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r60895:43221081dc07 Date: 2013-02-06 00:27 -0500 http://bitbucket.org/pypy/pypy/changeset/43221081dc07/ Log: fix whatsnew diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst --- a/pypy/doc/whatsnew-head.rst +++ b/pypy/doc/whatsnew-head.rst @@ -37,6 +37,7 @@ .. branch: fix-e4fa0b2 .. branch: win32-fixes .. branch: fix-version-tool +.. branch: popen2-removal .. branch: release-2.0-beta1 From noreply at buildbot.pypy.org Wed Feb 6 08:27:31 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Wed, 6 Feb 2013 08:27:31 +0100 (CET) Subject: [pypy-commit] pypy default: whitespace Message-ID: <20130206072731.BBE591C1006@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r60896:0fa34dc08184 Date: 2013-02-06 01:16 -0500 http://bitbucket.org/pypy/pypy/changeset/0fa34dc08184/ Log: whitespace diff --git a/pypy/module/bz2/test/test_bz2_compdecomp.py b/pypy/module/bz2/test/test_bz2_compdecomp.py --- a/pypy/module/bz2/test/test_bz2_compdecomp.py +++ b/pypy/module/bz2/test/test_bz2_compdecomp.py @@ -12,7 +12,7 @@ if os.name == "nt": from py.test import skip skip("bz2 module is not available on Windows") - + def setup_module(mod): DATA = 'BZh91AY&SY.\xc8N\x18\x00\x01>_\x80\x00\x10@\x02\xff\xf0\x01\x07n\x00?\xe7\xff\xe00\x01\x99\xaa\x00\xc0\x03F\x86\x8c#&\x83F\x9a\x03\x06\xa6\xd0\xa6\x93M\x0fQ\xa7\xa8\x06\x804hh\x12$\x11\xa4i4\xf14S\xd2\x88\xe5\xcd9gd6\x0b\n\xe9\x9b\xd5\x8a\x99\xf7\x08.K\x8ev\xfb\xf7xw\xbb\xdf\xa1\x92\xf1\xdd|/";\xa2\xba\x9f\xd5\xb1#A\xb6\xf6\xb3o\xc9\xc5y\\\xebO\xe7\x85\x9a\xbc\xb6f8\x952\xd5\xd7"%\x89>V,\xf7\xa6z\xe2\x9f\xa3\xdf\x11\x11"\xd6E)I\xa9\x13^\xca\xf3r\xd0\x03U\x922\xf26\xec\xb6\xed\x8b\xc3U\x13\x9d\xc5\x170\xa4\xfa^\x92\xacDF\x8a\x97\xd6\x19\xfe\xdd\xb8\xbd\x1a\x9a\x19\xa3\x80ankR\x8b\xe5\xd83]\xa9\xc6\x08\x82f\xf6\xb9"6l$\xb8j@\xc0\x8a\xb0l1..\xbak\x83ls\x15\xbc\xf4\xc1\x13\xbe\xf8E\xb8\x9d\r\xa8\x9dk\x84\xd3n\xfa\xacQ\x07\xb1%y\xaav\xb4\x08\xe0z\x1b\x16\xf5\x04\xe9\xcc\xb9\x08z\x1en7.G\xfc]\xc9\x14\xe1B@\xbb!8`' @@ -54,27 +54,27 @@ def test_creation(self): from bz2 import BZ2Compressor - + raises(TypeError, BZ2Compressor, "foo") raises(ValueError, BZ2Compressor, 10) - + BZ2Compressor(1) BZ2Compressor(9) - + def test_compress(self): from bz2 import BZ2Compressor - + bz2c = BZ2Compressor() raises(TypeError, bz2c.compress) data = bz2c.compress(self.TEXT) data = "%s%s" % (data, bz2c.flush()) assert self.decompress(data) == self.TEXT - + def test_compress_huge_data(self): if not self.HUGE_OK: skip("skipping test requiring lots of memory") - from bz2 import BZ2Compressor - + from bz2 import BZ2Compressor + HUGE_DATA = self.TEXT * 10000 bz2c = BZ2Compressor() raises(TypeError, bz2c.compress) @@ -83,8 +83,8 @@ assert self.decompress(data) == HUGE_DATA def test_compress_chunks_10(self): - from bz2 import BZ2Compressor - + from bz2 import BZ2Compressor + bz2c = BZ2Compressor() n = 0 data = "" @@ -112,23 +112,23 @@ cls.w_TEXT = cls.space.wrap(TEXT) cls.w_DATA = cls.space.wrap(DATA) cls.w_BUGGY_DATA = cls.space.wrap(BUGGY_DATA) - + def test_creation(self): from bz2 import BZ2Decompressor - + raises(TypeError, BZ2Decompressor, "foo") - + BZ2Decompressor() - + def test_attribute(self): from bz2 import BZ2Decompressor - + bz2d = BZ2Decompressor() assert bz2d.unused_data == "" def test_decompress(self): from bz2 import BZ2Decompressor - + bz2d = BZ2Decompressor() raises(TypeError, bz2d.decompress) decompressed_data = bz2d.decompress(self.DATA) @@ -136,7 +136,7 @@ def test_decompress_chunks_10(self): from bz2 import BZ2Decompressor - + bz2d = BZ2Decompressor() decompressed_data = "" n = 0 @@ -146,13 +146,13 @@ break decompressed_data = "%s%s" % (decompressed_data, bz2d.decompress(temp)) n += 1 - + assert decompressed_data == self.TEXT - + def test_decompress_unused_data(self): # test with unused data. (data after EOF) from bz2 import BZ2Decompressor - + bz2d = BZ2Decompressor() unused_data = "this is unused data" decompressed_data = bz2d.decompress(self.DATA + unused_data) @@ -161,7 +161,7 @@ def test_EOF_error(self): from bz2 import BZ2Decompressor - + bz2d = BZ2Decompressor() bz2d.decompress(self.DATA) raises(EOFError, bz2d.decompress, "foo") @@ -195,11 +195,11 @@ def test_compress_function(self): from bz2 import compress - + raises(TypeError, compress, 123) raises(ValueError, compress, "foo", 10) raises(TypeError, compress, "foo", "foo") - + data = compress(self.TEXT) assert self.decompress(data) == self.TEXT @@ -207,7 +207,7 @@ if not self.HUGE_OK: skip("skipping test requiring lots of memory") from bz2 import compress - + HUGE_DATA = self.TEXT * 10000 data = compress(HUGE_DATA) @@ -215,7 +215,7 @@ def test_decompress_function(self): import bz2 - + raises(TypeError, bz2.decompress) assert bz2.decompress("") == "" decompressed_data = bz2.decompress(self.DATA) diff --git a/pypy/module/bz2/test/test_bz2_file.py b/pypy/module/bz2/test/test_bz2_file.py --- a/pypy/module/bz2/test/test_bz2_file.py +++ b/pypy/module/bz2/test/test_bz2_file.py @@ -85,15 +85,15 @@ assert bz2f.closed == False bz2f.close() assert bz2f.closed == True - + def test_creation(self): from bz2 import BZ2File - + raises(ValueError, BZ2File, self.temppath, mode='w', compresslevel=10) raises(ValueError, BZ2File, self.temppath, mode='XYZ') # XXX the following is fine, currently: #raises(ValueError, BZ2File, self.temppath, mode='ww') - + BZ2File(self.temppath, mode='wU', buffering=0, compresslevel=8) BZ2File(self.temppath, mode='wb') # a large buf size @@ -101,50 +101,50 @@ def test_close(self): from bz2 import BZ2File - + # writeonly bz2f = BZ2File(self.temppath, mode='w') bz2f.close() # since we use fclose() internally you can't close it twice # bz2f.close() - + # readonly bz2f = BZ2File(self.temppath, mode='r') bz2f.close() - + def test_tell(self): from bz2 import BZ2File - + bz2f = BZ2File(self.temppath, mode='w') bz2f.close() raises(ValueError, bz2f.tell) - + bz2f = BZ2File(self.temppath, mode='w') pos = bz2f.tell() bz2f.close() assert pos == 0 - + def test_seek(self): from bz2 import BZ2File - + # hack to create a foo file open(self.temppath, "w").close() - + # cannot seek if close bz2f = BZ2File(self.temppath, mode='r') bz2f.close() raises(ValueError, bz2f.seek, 0) - + # cannot seek if 'w' bz2f = BZ2File(self.temppath, mode='w') raises(IOError, bz2f.seek, 0) bz2f.close() - + bz2f = BZ2File(self.temppath, mode='r') raises(TypeError, bz2f.seek) raises(TypeError, bz2f.seek, "foo") raises(TypeError, bz2f.seek, 0, "foo") - + bz2f.seek(0) assert bz2f.tell() == 0 del bz2f # delete from this frame, which is captured in the traceback @@ -152,21 +152,21 @@ def test_open_close_del(self): from bz2 import BZ2File self.create_temp_file() - + for i in range(10): f = BZ2File(self.temppath) f.close() del f - + def test_open_non_existent(self): from bz2 import BZ2File raises(IOError, BZ2File, "/non/existent/path") - + def test_open_mode_U(self): # bug #1194181: bz2.BZ2File opened for write with mode "U" from bz2 import BZ2File self.create_temp_file() - + bz2f = BZ2File(self.temppath, "U") bz2f.close() f = open(self.temppath) @@ -174,7 +174,7 @@ f.read() assert f.tell() == len(self.DATA) f.close() - + def test_seek_forward(self): from bz2 import BZ2File self.create_temp_file() @@ -214,7 +214,7 @@ assert bz2f.tell() == len(self.TEXT) assert bz2f.read() == "" bz2f.close() - + def test_seek_post_end_twice(self): from bz2 import BZ2File self.create_temp_file() @@ -240,7 +240,7 @@ from bz2 import BZ2File from cStringIO import StringIO self.create_temp_file() - + bz2f = BZ2File(self.temppath) # XXX #raises(TypeError, bz2f.readline, None) @@ -253,7 +253,7 @@ def test_read(self): from bz2 import BZ2File self.create_temp_file() - + bz2f = BZ2File(self.temppath) # XXX # raises(TypeError, bz2f.read, None) @@ -291,7 +291,7 @@ def test_read_chunk9(self): from bz2 import BZ2File self.create_temp_file() - + bz2f = BZ2File(self.temppath) text_read = "" while True: @@ -305,7 +305,7 @@ def test_read_100_bytes(self): from bz2 import BZ2File self.create_temp_file() - + bz2f = BZ2File(self.temppath) assert bz2f.read(100) == self.TEXT[:100] bz2f.close() @@ -313,7 +313,7 @@ def test_universal_newlines_lf(self): from bz2 import BZ2File self.create_temp_file() - + bz2f = BZ2File(self.temppath, "rU") assert bz2f.read() == self.TEXT assert bz2f.newlines == "\n" @@ -322,7 +322,7 @@ def test_universal_newlines_crlf(self): from bz2 import BZ2File self.create_temp_file(crlf=True) - + bz2f = BZ2File(self.temppath, "rU") data = bz2f.read() assert data == self.TEXT @@ -333,7 +333,7 @@ from bz2 import BZ2File from cStringIO import StringIO self.create_temp_file() - + bz2f = BZ2File(self.temppath) # XXX #raises(TypeError, bz2f.readlines, None) @@ -345,17 +345,17 @@ from bz2 import BZ2File from cStringIO import StringIO self.create_temp_file() - + bz2f = BZ2File(self.temppath) sio = StringIO(self.TEXT) assert list(iter(bz2f)) == sio.readlines() bz2f.close() - + def test_xreadlines(self): from bz2 import BZ2File from cStringIO import StringIO self.create_temp_file() - + bz2f = BZ2File(self.temppath) sio = StringIO(self.TEXT) assert list(bz2f.xreadlines()) == sio.readlines() @@ -364,12 +364,12 @@ def test_readlines_bug_1191043(self): # readlines()/xreadlines() for files containing no newline from bz2 import BZ2File - + DATA = 'BZh91AY&SY\xd9b\x89]\x00\x00\x00\x03\x80\x04\x00\x02\x00\x0c\x00 \x00!\x9ah3M\x13<]\xc9\x14\xe1BCe\x8a%t' f = open(self.temppath, "wb") f.write(DATA) f.close() - + bz2f = BZ2File(self.temppath) lines = bz2f.readlines() bz2f.close() @@ -379,7 +379,7 @@ xlines = list(bz2f.xreadlines()) bz2f.close() assert xlines == ['Test'] - + def test_write(self): from bz2 import BZ2File @@ -387,7 +387,7 @@ raises(TypeError, bz2f.write) bz2f.write(self.TEXT) bz2f.close() - + f = open(self.temppath, "rb") assert self.decompress(f.read()) == self.TEXT f.close() @@ -401,11 +401,11 @@ data = self.TEXT[n * 10:(n + 1) * 10] if not data: break - + bz2f.write(data) n += 1 bz2f.close() - + f = open(self.temppath, "rb") assert self.decompress(f.read()) == self.TEXT f.close() @@ -422,7 +422,7 @@ f = open(self.temppath, "rb") assert self.decompress(f.read()) == self.TEXT f.close() - + def test_write_methods_on_readonly_file(self): from bz2 import BZ2File @@ -453,8 +453,8 @@ assert data == "abc" assert f.closed - - + + # has_cmdline_bunzip2 = sys.platform not in ("win32", "os2emx", "riscos") # # if has_cmdline_bunzip2: From noreply at buildbot.pypy.org Wed Feb 6 08:27:33 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Wed, 6 Feb 2013 08:27:33 +0100 (CET) Subject: [pypy-commit] pypy default: CheckAllocation seems to work fine here Message-ID: <20130206072733.1469F1C1006@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r60897:eecd3ad78b7a Date: 2013-02-06 01:44 -0500 http://bitbucket.org/pypy/pypy/changeset/eecd3ad78b7a/ Log: CheckAllocation seems to work fine here diff --git a/pypy/module/bz2/test/test_bz2_file.py b/pypy/module/bz2/test/test_bz2_file.py --- a/pypy/module/bz2/test/test_bz2_file.py +++ b/pypy/module/bz2/test/test_bz2_file.py @@ -6,6 +6,7 @@ import py from pypy.interpreter.gateway import unwrap_spec, interp2app +from pypy.module.bz2.test.support import CheckAllocation if os.name == "nt": @@ -50,10 +51,7 @@ mod.RANDOM_DATA = ''.join([s[int(random.random() * len(s))] for i in range(30000)]) -class AppTestBZ2File: #(CheckAllocation): - # XXX for unknown reasons, we cannot do allocation checks, as sth is - # keeping those objects alive (BZ2File objects) - +class AppTestBZ2File(CheckAllocation): spaceconfig = { "usemodules": ["bz2", "binascii", "rctime"] } From noreply at buildbot.pypy.org Wed Feb 6 08:50:41 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Wed, 6 Feb 2013 08:50:41 +0100 (CET) Subject: [pypy-commit] pypy default: these XXX/commented lines are valid tests now Message-ID: <20130206075041.9D7391C0313@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r60898:196680d468e4 Date: 2013-02-06 02:50 -0500 http://bitbucket.org/pypy/pypy/changeset/196680d468e4/ Log: these XXX/commented lines are valid tests now diff --git a/pypy/module/bz2/test/test_bz2_file.py b/pypy/module/bz2/test/test_bz2_file.py --- a/pypy/module/bz2/test/test_bz2_file.py +++ b/pypy/module/bz2/test/test_bz2_file.py @@ -103,12 +103,12 @@ # writeonly bz2f = BZ2File(self.temppath, mode='w') bz2f.close() - # since we use fclose() internally you can't close it twice - # bz2f.close() + bz2f.close() # readonly bz2f = BZ2File(self.temppath, mode='r') bz2f.close() + bz2f.close() def test_tell(self): from bz2 import BZ2File @@ -240,8 +240,7 @@ self.create_temp_file() bz2f = BZ2File(self.temppath) - # XXX - #raises(TypeError, bz2f.readline, None) + raises(TypeError, bz2f.readline, None) sio = StringIO(self.TEXT) for line in sio.readlines(): line_read = bz2f.readline() @@ -253,8 +252,7 @@ self.create_temp_file() bz2f = BZ2File(self.temppath) - # XXX - # raises(TypeError, bz2f.read, None) + raises(TypeError, bz2f.read, None) text_read = bz2f.read() assert text_read == self.TEXT bz2f.close() @@ -333,8 +331,7 @@ self.create_temp_file() bz2f = BZ2File(self.temppath) - # XXX - #raises(TypeError, bz2f.readlines, None) + raises(TypeError, bz2f.readlines, None) sio = StringIO(self.TEXT) assert bz2f.readlines() == sio.readlines() bz2f.close() From noreply at buildbot.pypy.org Wed Feb 6 09:59:08 2013 From: noreply at buildbot.pypy.org (mattip) Date: Wed, 6 Feb 2013 09:59:08 +0100 (CET) Subject: [pypy-commit] pypy default: do not crash on random input Message-ID: <20130206085908.719361C0313@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: Changeset: r60899:e8f4b8257bf2 Date: 2013-02-06 10:59 +0200 http://bitbucket.org/pypy/pypy/changeset/e8f4b8257bf2/ Log: do not crash on random input diff --git a/rpython/rlib/runicode.py b/rpython/rlib/runicode.py --- a/rpython/rlib/runicode.py +++ b/rpython/rlib/runicode.py @@ -31,7 +31,8 @@ ch2 = ord(u[1]) if 0xD800 <= ch1 <= 0xDBFF and 0xDC00 <= ch2 <= 0xDFFF: return (((ch1 - 0xD800) << 10) | (ch2 - 0xDC00)) + 0x10000 - assert len(u) == 1 + if len(u) != 1: + raise ValueError('not a surrogate') return ord(u[0]) if MAXUNICODE > sys.maxunicode: From noreply at buildbot.pypy.org Wed Feb 6 11:10:34 2013 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 6 Feb 2013 11:10:34 +0100 (CET) Subject: [pypy-commit] pypy default: Calling str() on bytearrays in RPython. Message-ID: <20130206101034.7840E1C0313@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r60900:266b2f7ea599 Date: 2013-02-06 11:10 +0100 http://bitbucket.org/pypy/pypy/changeset/266b2f7ea599/ Log: Calling str() on bytearrays in RPython. diff --git a/rpython/rtyper/lltypesystem/rbytearray.py b/rpython/rtyper/lltypesystem/rbytearray.py --- a/rpython/rtyper/lltypesystem/rbytearray.py +++ b/rpython/rtyper/lltypesystem/rbytearray.py @@ -57,6 +57,17 @@ p.chars[i] = chr(c) return p + def ll_str(self, ll_b): + from rpython.rtyper.lltypesystem.rstr import mallocstr, STR + if ll_b: + lgt = ll_b.length() + ll_s = mallocstr(lgt) + for i in range(lgt): + ll_s.chars[i] = ll_b.chars[i] + return ll_s + else: + return lltype.nullptr(STR) + bytearray_repr = ByteArrayRepr() def hlbytearray(ll_b): diff --git a/rpython/rtyper/test/test_rbytearray.py b/rpython/rtyper/test/test_rbytearray.py --- a/rpython/rtyper/test/test_rbytearray.py +++ b/rpython/rtyper/test/test_rbytearray.py @@ -43,3 +43,10 @@ ll_res = self.interpret(f, [llstr("abc"), 1, ord('d')]) assert ll_res == ord('d') + ord('c') * 255 + + def test_str_of_bytearray(self): + def f(x): + return str(bytearray(str(x))) + + ll_res = self.interpret(f, [123]) + assert hlstr(ll_res) == "123" From noreply at buildbot.pypy.org Wed Feb 6 11:12:47 2013 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 6 Feb 2013 11:12:47 +0100 (CET) Subject: [pypy-commit] pypy default: Uh? Message-ID: <20130206101247.2ED4E1C0313@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r60901:b970e1d7abc4 Date: 2013-02-06 11:12 +0100 http://bitbucket.org/pypy/pypy/changeset/b970e1d7abc4/ Log: Uh? diff --git a/rpython/annotator/test/test_annrpython.py b/rpython/annotator/test/test_annrpython.py --- a/rpython/annotator/test/test_annrpython.py +++ b/rpython/annotator/test/test_annrpython.py @@ -1983,13 +1983,9 @@ return None def g(a): x = f(a) - #assert x is not None if x is None: return "abcd" return x - if isinstance(x, str): - return x - return "impossible" a = self.RPythonAnnotator() s = a.build_types(f, [int]) assert s.can_be_None From noreply at buildbot.pypy.org Wed Feb 6 13:36:15 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Wed, 6 Feb 2013 13:36:15 +0100 (CET) Subject: [pypy-commit] pypy default: let host ord handle non-surrogate cases so we get proper exceptions, test Message-ID: <20130206123615.98C071C1006@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r60902:093fe9b62735 Date: 2013-02-06 07:06 -0500 http://bitbucket.org/pypy/pypy/changeset/093fe9b62735/ Log: let host ord handle non-surrogate cases so we get proper exceptions, test diff --git a/rpython/rlib/runicode.py b/rpython/rlib/runicode.py --- a/rpython/rlib/runicode.py +++ b/rpython/rlib/runicode.py @@ -31,9 +31,7 @@ ch2 = ord(u[1]) if 0xD800 <= ch1 <= 0xDBFF and 0xDC00 <= ch2 <= 0xDFFF: return (((ch1 - 0xD800) << 10) | (ch2 - 0xDC00)) + 0x10000 - if len(u) != 1: - raise ValueError('not a surrogate') - return ord(u[0]) + return ord(u) if MAXUNICODE > sys.maxunicode: # A version of unichr which allows codes outside the BMP diff --git a/rpython/rlib/test/test_runicode.py b/rpython/rlib/test/test_runicode.py --- a/rpython/rlib/test/test_runicode.py +++ b/rpython/rlib/test/test_runicode.py @@ -5,16 +5,26 @@ from rpython.rlib import runicode def test_unichr(): - a = runicode.UNICHR(0xffff) - assert a == u'\uffff' + assert runicode.UNICHR(0xffff) == u'\uffff' if runicode.MAXUNICODE > 0xffff: - a = runicode.UNICHR(0x10000) if sys.maxunicode < 0x10000: - assert len(a) == 2 # surrogates + assert runicode.UNICHR(0x10000) == u'\ud800\udc00' else: - assert len(a) == 1 + assert runicode.UNICHR(0x10000) == u'\U00010000' else: py.test.raises(ValueError, runicode.UNICHR, 0x10000) + py.test.raises(TypeError, runicode.UNICHR, 'abc') + +def test_ord(): + assert runicode.ORD(u'\uffff') == 0xffff + if runicode.MAXUNICODE > 0xffff: + if sys.maxunicode < 0x10000: + assert runicode.ORD(u'\ud800\udc00') == 0x10000 + else: + assert runicode.ORD(u'\U00010000') == 0x10000 + else: + py.test.raises(TypeError, runicode.ORD, u'\ud800\udc00') + py.test.raises(TypeError, runicode.ORD, 'abc') class UnicodeTests(object): From noreply at buildbot.pypy.org Wed Feb 6 14:50:47 2013 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 6 Feb 2013 14:50:47 +0100 (CET) Subject: [pypy-commit] pypy default: (fijal, mattip) merge missing-ndarray-attributes. As the branch suggests, Message-ID: <20130206135047.6BD8D1C0313@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r60903:2eb2f0833bbe Date: 2013-02-06 15:50 +0200 http://bitbucket.org/pypy/pypy/changeset/2eb2f0833bbe/ Log: (fijal, mattip) merge missing-ndarray-attributes. As the branch suggests, this adds quite a few attributes on ndarrays that were not there before diff too long, truncating to 2000 out of 3679 lines diff --git a/pypy/module/micronumpy/arrayimpl/base.py b/pypy/module/micronumpy/arrayimpl/base.py --- a/pypy/module/micronumpy/arrayimpl/base.py +++ b/pypy/module/micronumpy/arrayimpl/base.py @@ -3,6 +3,12 @@ def is_scalar(self): return False + def base(self): + raise NotImplementedError + + def create_iter(self, shape=None): + raise NotImplementedError + class BaseArrayIterator(object): def next(self): raise NotImplementedError # purely abstract base class diff --git a/pypy/module/micronumpy/arrayimpl/concrete.py b/pypy/module/micronumpy/arrayimpl/concrete.py --- a/pypy/module/micronumpy/arrayimpl/concrete.py +++ b/pypy/module/micronumpy/arrayimpl/concrete.py @@ -1,178 +1,20 @@ from pypy.module.micronumpy.arrayimpl import base -from pypy.module.micronumpy import support, loop +from pypy.module.micronumpy import support, loop, iter from pypy.module.micronumpy.base import convert_to_array, W_NDimArray,\ ArrayArgumentException from pypy.module.micronumpy.strides import calc_new_strides, shape_agreement,\ calculate_broadcast_strides, calculate_dot_strides from pypy.module.micronumpy.iter import Chunk, Chunks, NewAxisChunk, RecordChunk from pypy.interpreter.error import OperationError, operationerrfmt +from pypy.interpreter.buffer import RWBuffer +from rpython.rlib import jit from rpython.rtyper.lltypesystem import rffi, lltype -from rpython.rlib import jit -from rpython.rlib.rawstorage import free_raw_storage, RAW_STORAGE +from rpython.rlib.rawstorage import free_raw_storage, raw_storage_getitem,\ + raw_storage_setitem, RAW_STORAGE +from pypy.module.micronumpy.arrayimpl.sort import argsort_array from rpython.rlib.debug import make_sure_not_resized -class ConcreteArrayIterator(base.BaseArrayIterator): - _immutable_fields_ = ['dtype', 'skip', 'size'] - def __init__(self, array): - self.array = array - self.offset = 0 - self.dtype = array.dtype - self.skip = self.dtype.itemtype.get_element_size() - self.size = array.size - - def setitem(self, elem): - self.dtype.setitem(self.array, self.offset, elem) - - def getitem(self): - return self.dtype.getitem(self.array, self.offset) - - def getitem_bool(self): - return self.dtype.getitem_bool(self.array, self.offset) - - def next(self): - self.offset += self.skip - - def next_skip_x(self, x): - self.offset += self.skip * x - - def done(self): - return self.offset >= self.size - - def reset(self): - self.offset %= self.size - -class OneDimViewIterator(ConcreteArrayIterator): - ''' The view iterator dtype can be different from the - array.dtype, this is what makes it a View - ''' - def __init__(self, array, dtype, start, strides, shape): - self.array = array - self.dtype = dtype - self.offset = start - self.skip = strides[0] - self.index = 0 - self.size = shape[0] - - def next(self): - self.offset += self.skip - self.index += 1 - - def next_skip_x(self, x): - self.offset += self.skip * x - self.index += x - - def done(self): - return self.index >= self.size - - def reset(self): - self.offset %= self.size - -class MultiDimViewIterator(ConcreteArrayIterator): - ''' The view iterator dtype can be different from the - array.dtype, this is what makes it a View - ''' - def __init__(self, array, dtype, start, strides, backstrides, shape): - self.indexes = [0] * len(shape) - self.array = array - self.dtype = dtype - self.shape = shape - self.offset = start - self.shapelen = len(shape) - self._done = False - self.strides = strides - self.backstrides = backstrides - self.size = array.size - - @jit.unroll_safe - def next(self): - offset = self.offset - for i in range(self.shapelen - 1, -1, -1): - if self.indexes[i] < self.shape[i] - 1: - self.indexes[i] += 1 - offset += self.strides[i] - break - else: - self.indexes[i] = 0 - offset -= self.backstrides[i] - else: - self._done = True - self.offset = offset - - @jit.unroll_safe - def next_skip_x(self, step): - for i in range(len(self.shape) - 1, -1, -1): - if self.indexes[i] < self.shape[i] - step: - self.indexes[i] += step - self.offset += self.strides[i] * step - break - else: - remaining_step = (self.indexes[i] + step) // self.shape[i] - this_i_step = step - remaining_step * self.shape[i] - self.offset += self.strides[i] * this_i_step - self.indexes[i] = self.indexes[i] + this_i_step - step = remaining_step - else: - self._done = True - - def done(self): - return self._done - - def reset(self): - self.offset %= self.size - -class AxisIterator(base.BaseArrayIterator): - def __init__(self, array, shape, dim): - self.shape = shape - strides = array.get_strides() - backstrides = array.get_backstrides() - if len(shape) == len(strides): - # keepdims = True - self.strides = strides[:dim] + [0] + strides[dim + 1:] - self.backstrides = backstrides[:dim] + [0] + backstrides[dim + 1:] - else: - self.strides = strides[:dim] + [0] + strides[dim:] - self.backstrides = backstrides[:dim] + [0] + backstrides[dim:] - self.first_line = True - self.indices = [0] * len(shape) - self._done = False - self.offset = array.start - self.dim = dim - self.array = array - self.dtype = array.dtype - - def setitem(self, elem): - self.dtype.setitem(self.array, self.offset, elem) - - def getitem(self): - return self.dtype.getitem(self.array, self.offset) - - @jit.unroll_safe - def next(self): - for i in range(len(self.shape) - 1, -1, -1): - if self.indices[i] < self.shape[i] - 1: - if i == self.dim: - self.first_line = False - self.indices[i] += 1 - self.offset += self.strides[i] - break - else: - if i == self.dim: - self.first_line = True - self.indices[i] = 0 - self.offset -= self.backstrides[i] - else: - self._done = True - - def done(self): - return self._done - -def int_w(space, w_obj): - try: - return space.int_w(space.index(w_obj)) - except OperationError: - return space.int_w(space.int(w_obj)) - class BaseConcreteArray(base.BaseArrayImplementation): start = 0 parent = None @@ -213,7 +55,7 @@ def get_size(self): return self.size // self.dtype.itemtype.get_element_size() - def reshape(self, space, new_shape): + def reshape(self, space, orig_array, new_shape): # Since we got to here, prod(new_shape) == self.size new_strides = None if self.size > 0: @@ -226,31 +68,31 @@ for nd in range(ndims): new_backstrides[nd] = (new_shape[nd] - 1) * new_strides[nd] return SliceArray(self.start, new_strides, new_backstrides, - new_shape, self) + new_shape, self, orig_array) else: return None - def get_real(self): + def get_real(self, orig_array): strides = self.get_strides() backstrides = self.get_backstrides() if self.dtype.is_complex_type(): dtype = self.dtype.float_type return SliceArray(self.start, strides, backstrides, - self.get_shape(), self, dtype=dtype) + self.get_shape(), self, orig_array, dtype=dtype) return SliceArray(self.start, strides, backstrides, - self.get_shape(), self) + self.get_shape(), self, orig_array) - def get_imag(self): + def get_imag(self, orig_array): strides = self.get_strides() backstrides = self.get_backstrides() if self.dtype.is_complex_type(): dtype = self.dtype.float_type return SliceArray(self.start + dtype.get_size(), strides, - backstrides, self.get_shape(), self, dtype=dtype) + backstrides, self.get_shape(), self, orig_array, dtype=dtype) if self.dtype.is_flexible_type(): # numpy returns self for self.imag return SliceArray(self.start, strides, backstrides, - self.get_shape(), self) + self.get_shape(), self, orig_array) impl = NonWritableArray(self.get_shape(), self.dtype, self.order, strides, backstrides) impl.fill(self.dtype.box(0)) @@ -265,7 +107,7 @@ for i, w_index in enumerate(view_w): if space.isinstance_w(w_index, space.w_slice): raise IndexError - idx = int_w(space, w_index) + idx = support.int_w(space, w_index) if idx < 0: idx = self.get_shape()[i] + idx if idx < 0 or idx >= self.get_shape()[i]: @@ -339,7 +181,7 @@ return self._lookup_by_index(space, view_w) if shape_len > 1: raise IndexError - idx = int_w(space, w_idx) + idx = support.int_w(space, w_idx) return self._lookup_by_index(space, [space.wrap(idx)]) @jit.unroll_safe @@ -367,26 +209,26 @@ i += 1 return Chunks(result) - def descr_getitem(self, space, w_index): + def descr_getitem(self, space, orig_arr, w_index): try: item = self._single_item_index(space, w_index) return self.getitem(item) except IndexError: # not a single result chunks = self._prepare_slice_args(space, w_index) - return chunks.apply(self) + return chunks.apply(orig_arr) - def descr_setitem(self, space, w_index, w_value): + def descr_setitem(self, space, orig_arr, w_index, w_value): try: item = self._single_item_index(space, w_index) self.setitem(item, self.dtype.coerce(space, w_value)) except IndexError: w_value = convert_to_array(space, w_value) chunks = self._prepare_slice_args(space, w_index) - view = chunks.apply(self) + view = chunks.apply(orig_arr) view.implementation.setslice(space, w_value) - def transpose(self): + def transpose(self, orig_array): if len(self.get_shape()) < 2: return self strides = [] @@ -397,7 +239,7 @@ backstrides.append(self.get_backstrides()[i]) shape.append(self.get_shape()[i]) return SliceArray(self.start, strides, - backstrides, shape, self) + backstrides, shape, self, orig_array) def copy(self): strides, backstrides = support.calc_strides(self.get_shape(), self.dtype, @@ -406,15 +248,15 @@ backstrides) return loop.setslice(self.get_shape(), impl, self) - def create_axis_iter(self, shape, dim): - return AxisIterator(self, shape, dim) + def create_axis_iter(self, shape, dim, cum): + return iter.AxisIterator(self, shape, dim, cum) def create_dot_iter(self, shape, skip): r = calculate_dot_strides(self.get_strides(), self.get_backstrides(), shape, skip) - return MultiDimViewIterator(self, self.dtype, self.start, r[0], r[1], shape) + return iter.MultiDimViewIterator(self, self.dtype, self.start, r[0], r[1], shape) - def swapaxes(self, axis1, axis2): + def swapaxes(self, orig_arr, axis1, axis2): shape = self.get_shape()[:] strides = self.get_strides()[:] backstrides = self.get_backstrides()[:] @@ -422,13 +264,20 @@ strides[axis1], strides[axis2] = strides[axis2], strides[axis1] backstrides[axis1], backstrides[axis2] = backstrides[axis2], backstrides[axis1] return W_NDimArray.new_slice(self.start, strides, - backstrides, shape, self) + backstrides, shape, self, orig_arr) def get_storage_as_int(self, space): return rffi.cast(lltype.Signed, self.storage) + def get_storage(self): + return self.storage + + def get_buffer(self, space): + return ArrayBuffer(self) + class ConcreteArrayNotOwning(BaseConcreteArray): def __init__(self, shape, dtype, order, strides, backstrides, storage): + make_sure_not_resized(shape) make_sure_not_resized(strides) make_sure_not_resized(backstrides) @@ -442,19 +291,31 @@ def create_iter(self, shape=None): if shape is None or shape == self.get_shape(): - return ConcreteArrayIterator(self) + return iter.ConcreteArrayIterator(self) r = calculate_broadcast_strides(self.get_strides(), self.get_backstrides(), self.get_shape(), shape) - return MultiDimViewIterator(self, self.dtype, 0, r[0], r[1], shape) + return iter.MultiDimViewIterator(self, self.dtype, 0, r[0], r[1], shape) def fill(self, box): self.dtype.fill(self.storage, box, 0, self.size) - def set_shape(self, space, new_shape): + def set_shape(self, space, orig_array, new_shape): strides, backstrides = support.calc_strides(new_shape, self.dtype, self.order) - return SliceArray(0, strides, backstrides, new_shape, self) + return SliceArray(0, strides, backstrides, new_shape, self, + orig_array) + + def argsort(self, space, w_axis): + return argsort_array(self, space, w_axis) + + def astype(self, space, dtype): + new_arr = W_NDimArray.from_shape(self.get_shape(), dtype) + loop.copy_from_to(self, new_arr.implementation, dtype) + return new_arr + + def base(self): + return None class ConcreteArray(ConcreteArrayNotOwning): def __init__(self, shape, dtype, order, strides, backstrides): @@ -469,14 +330,17 @@ free_raw_storage(self.storage, track_allocation=False) + + class NonWritableArray(ConcreteArray): - def descr_setitem(self, space, w_index, w_value): + def descr_setitem(self, space, orig_array, w_index, w_value): raise OperationError(space.w_RuntimeError, space.wrap( "array is not writable")) class SliceArray(BaseConcreteArray): - def __init__(self, start, strides, backstrides, shape, parent, dtype=None): + def __init__(self, start, strides, backstrides, shape, parent, orig_arr, + dtype=None): self.strides = strides self.backstrides = backstrides self.shape = shape @@ -490,6 +354,10 @@ self.dtype = dtype self.size = support.product(shape) * self.dtype.itemtype.get_element_size() self.start = start + self.orig_arr = orig_arr + + def base(self): + return self.orig_arr def fill(self, box): loop.fill(self, box.convert_to(self.dtype)) @@ -499,16 +367,16 @@ r = calculate_broadcast_strides(self.get_strides(), self.get_backstrides(), self.get_shape(), shape) - return MultiDimViewIterator(self.parent, self.dtype, - self.start, r[0], r[1], shape) + return iter.MultiDimViewIterator(self.parent, self.dtype, + self.start, r[0], r[1], shape) if len(self.get_shape()) == 1: - return OneDimViewIterator(self.parent, self.dtype, self.start, + return iter.OneDimViewIterator(self.parent, self.dtype, self.start, self.get_strides(), self.get_shape()) - return MultiDimViewIterator(self.parent, self.dtype, self.start, + return iter.MultiDimViewIterator(self.parent, self.dtype, self.start, self.get_strides(), self.get_backstrides(), self.get_shape()) - def set_shape(self, space, new_shape): + def set_shape(self, space, orig_array, new_shape): if len(self.get_shape()) < 2 or self.size == 0: # TODO: this code could be refactored into calc_strides # but then calc_strides would have to accept a stepping factor @@ -527,7 +395,7 @@ backstrides.reverse() new_shape.reverse() return SliceArray(self.start, strides, backstrides, new_shape, - self) + self, orig_array) new_strides = calc_new_strides(new_shape, self.get_shape(), self.get_strides(), self.order) @@ -538,4 +406,18 @@ for nd in range(len(new_shape)): new_backstrides[nd] = (new_shape[nd] - 1) * new_strides[nd] return SliceArray(self.start, new_strides, new_backstrides, new_shape, - self) + self, orig_array) + +class ArrayBuffer(RWBuffer): + def __init__(self, impl): + self.impl = impl + + def getitem(self, item): + return raw_storage_getitem(lltype.Char, self.impl.storage, item) + + def setitem(self, item, v): + return raw_storage_setitem(self.impl.storage, item, + rffi.cast(lltype.Char, v)) + + def getlength(self): + return self.impl.size diff --git a/pypy/module/micronumpy/arrayimpl/scalar.py b/pypy/module/micronumpy/arrayimpl/scalar.py --- a/pypy/module/micronumpy/arrayimpl/scalar.py +++ b/pypy/module/micronumpy/arrayimpl/scalar.py @@ -54,10 +54,10 @@ def get_size(self): return 1 - def transpose(self): + def transpose(self, _): return self - def descr_getitem(self, space, w_idx): + def descr_getitem(self, space, _, w_idx): raise OperationError(space.w_IndexError, space.wrap("scalars cannot be indexed")) @@ -65,14 +65,14 @@ raise OperationError(space.w_IndexError, space.wrap("scalars cannot be indexed")) - def descr_setitem(self, space, w_idx, w_val): + def descr_setitem(self, space, _, w_idx, w_val): raise OperationError(space.w_IndexError, space.wrap("scalars cannot be indexed")) def setitem_index(self, space, idx, w_val): raise OperationError(space.w_IndexError, space.wrap("scalars cannot be indexed")) - def set_shape(self, space, new_shape): + def set_shape(self, space, orig_array, new_shape): if not new_shape: return self if support.product(new_shape) == 1: @@ -83,13 +83,13 @@ raise OperationError(space.w_ValueError, space.wrap( "total size of the array must be unchanged")) - def reshape(self, space, new_shape): - return self.set_shape(space, new_shape) + def reshape(self, space, orig_array, new_shape): + return self.set_shape(space, orig_array, new_shape) - def create_axis_iter(self, shape, dim): + def create_axis_iter(self, shape, dim, cum): raise Exception("axis iter should not happen on scalar") - def swapaxes(self, axis1, axis2): + def swapaxes(self, orig_array, axis1, axis2): raise Exception("should not be called") def fill(self, w_value): @@ -98,3 +98,17 @@ def get_storage_as_int(self, space): raise OperationError(space.w_ValueError, space.wrap("scalars have no address")) + + def argsort(self, space, w_axis): + return space.wrap(0) + + def astype(self, space, dtype): + return W_NDimArray.new_scalar(space, dtype, self.value) + + def base(self): + return None + + def get_buffer(self, space): + raise OperationError(space.w_ValueError, space.wrap( + "cannot point buffer to a scalar")) + diff --git a/pypy/module/micronumpy/arrayimpl/sort.py b/pypy/module/micronumpy/arrayimpl/sort.py new file mode 100644 --- /dev/null +++ b/pypy/module/micronumpy/arrayimpl/sort.py @@ -0,0 +1,195 @@ + +""" This is the implementation of various sorting routines in numpy. It's here +because it only makes sense on a concrete array +""" + +from rpython.rtyper.lltypesystem import rffi, lltype +from rpython.rlib.listsort import make_timsort_class +from rpython.rlib.rawstorage import raw_storage_getitem, raw_storage_setitem, \ + free_raw_storage, alloc_raw_storage +from rpython.rlib.unroll import unrolling_iterable +from rpython.rlib.rarithmetic import intmask +from rpython.rlib.objectmodel import specialize +from pypy.interpreter.error import OperationError +from pypy.module.micronumpy.base import W_NDimArray +from pypy.module.micronumpy import interp_dtype, types +from pypy.module.micronumpy.iter import AxisIterator + +INT_SIZE = rffi.sizeof(lltype.Signed) + +def make_sort_function(space, itemtype, comp_type, count=1): + TP = itemtype.T + step = rffi.sizeof(TP) + + class Repr(object): + def __init__(self, index_stride_size, stride_size, size, values, + indexes, index_start, start): + self.index_stride_size = index_stride_size + self.stride_size = stride_size + self.index_start = index_start + self.start = start + self.size = size + self.values = values + self.indexes = indexes + + def getitem(self, item): + if count < 2: + v = raw_storage_getitem(TP, self.values, item * self.stride_size + + self.start) + else: + v = [] + for i in range(count): + _v = raw_storage_getitem(TP, self.values, item * self.stride_size + + self.start + step * i) + v.append(_v) + if comp_type == 'int': + v = intmask(v) + elif comp_type == 'float': + v = float(v) + elif comp_type == 'complex': + v = [float(v[0]),float(v[1])] + else: + raise NotImplementedError('cannot reach') + return (v, raw_storage_getitem(lltype.Signed, self.indexes, + item * self.index_stride_size + + self.index_start)) + + def setitem(self, idx, item): + if count < 2: + raw_storage_setitem(self.values, idx * self.stride_size + + self.start, rffi.cast(TP, item[0])) + else: + i = 0 + for val in item[0]: + raw_storage_setitem(self.values, idx * self.stride_size + + self.start + i*step, rffi.cast(TP, val)) + i += 1 + raw_storage_setitem(self.indexes, idx * self.index_stride_size + + self.index_start, item[1]) + + class ArgArrayRepWithStorage(Repr): + def __init__(self, index_stride_size, stride_size, size): + start = 0 + dtype = interp_dtype.get_dtype_cache(space).w_longdtype + self.indexes = dtype.itemtype.malloc(size*dtype.get_size()) + self.values = alloc_raw_storage(size * stride_size, + track_allocation=False) + Repr.__init__(self, index_stride_size, stride_size, + size, self.values, self.indexes, start, start) + + def __del__(self): + free_raw_storage(self.indexes, track_allocation=False) + free_raw_storage(self.values, track_allocation=False) + + def arg_getitem(lst, item): + return lst.getitem(item) + + def arg_setitem(lst, item, value): + lst.setitem(item, value) + + def arg_length(lst): + return lst.size + + def arg_getitem_slice(lst, start, stop): + retval = ArgArrayRepWithStorage(lst.index_stride_size, lst.stride_size, + stop-start) + for i in range(stop-start): + retval.setitem(i, lst.getitem(i+start)) + return retval + + if count < 2: + def arg_lt(a, b): + # Does numpy do <= ? + return a[0] < b[0] + else: + def arg_lt(a, b): + for i in range(count): + if a[0][i] < b[0][i]: + return True + elif a[0][i] > b[0][i]: + return False + # Does numpy do True? + return False + + ArgSort = make_timsort_class(arg_getitem, arg_setitem, arg_length, + arg_getitem_slice, arg_lt) + + def argsort(arr, space, w_axis, itemsize): + if w_axis is space.w_None: + # note that it's fine ot pass None here as we're not going + # to pass the result around (None is the link to base in slices) + arr = arr.reshape(space, None, [arr.get_size()]) + axis = 0 + elif w_axis is None: + axis = -1 + else: + axis = space.int_w(w_axis) + # create array of indexes + dtype = interp_dtype.get_dtype_cache(space).w_longdtype + index_arr = W_NDimArray.from_shape(arr.get_shape(), dtype) + storage = index_arr.implementation.get_storage() + if len(arr.get_shape()) == 1: + for i in range(arr.get_size()): + raw_storage_setitem(storage, i * INT_SIZE, i) + r = Repr(INT_SIZE, itemsize, arr.get_size(), arr.get_storage(), + storage, 0, arr.start) + ArgSort(r).sort() + else: + shape = arr.get_shape() + if axis < 0: + axis = len(shape) + axis - 1 + if axis < 0 or axis > len(shape): + raise OperationError(space.w_IndexError, space.wrap( + "Wrong axis %d" % axis)) + iterable_shape = shape[:axis] + [0] + shape[axis + 1:] + iter = AxisIterator(arr, iterable_shape, axis, False) + index_impl = index_arr.implementation + index_iter = AxisIterator(index_impl, iterable_shape, axis, False) + stride_size = arr.strides[axis] + index_stride_size = index_impl.strides[axis] + axis_size = arr.shape[axis] + while not iter.done(): + for i in range(axis_size): + raw_storage_setitem(storage, i * index_stride_size + + index_iter.offset, i) + r = Repr(index_stride_size, stride_size, axis_size, + arr.get_storage(), storage, index_iter.offset, iter.offset) + ArgSort(r).sort() + iter.next() + index_iter.next() + return index_arr + + return argsort + +def argsort_array(arr, space, w_axis): + cache = space.fromcache(SortCache) # that populates SortClasses + itemtype = arr.dtype.itemtype + for tp in all_types: + if isinstance(itemtype, tp[0]): + return cache._lookup(tp)(arr, space, w_axis, + itemtype.get_element_size()) + # XXX this should probably be changed + raise OperationError(space.w_NotImplementedError, + space.wrap("sorting of non-numeric types " + \ + "'%s' is not implemented" % arr.dtype.get_name(), )) + +all_types = (types.all_float_types + types.all_complex_types + + types.all_int_types) +all_types = [i for i in all_types if not '_mixin_' in i[0].__dict__] +all_types = unrolling_iterable(all_types) + +class SortCache(object): + built = False + + def __init__(self, space): + if self.built: + return + self.built = True + cache = {} + for cls, it in all_types._items: + if it == 'complex': + cache[cls] = make_sort_function(space, cls, it, 2) + else: + cache[cls] = make_sort_function(space, cls, it) + self.cache = cache + self._lookup = specialize.memo()(lambda tp : cache[tp[0]]) diff --git a/pypy/module/micronumpy/base.py b/pypy/module/micronumpy/base.py --- a/pypy/module/micronumpy/base.py +++ b/pypy/module/micronumpy/base.py @@ -2,6 +2,7 @@ from pypy.interpreter.baseobjspace import Wrappable from rpython.tool.pairtype import extendabletype from pypy.module.micronumpy.support import calc_strides +from pypy.module.micronumpy.arrayimpl.base import BaseArrayImplementation def issequence_w(space, w_obj): return (space.isinstance_w(w_obj, space.w_tuple) or @@ -15,6 +16,7 @@ __metaclass__ = extendabletype def __init__(self, implementation): + assert isinstance(implementation, BaseArrayImplementation) self.implementation = implementation @staticmethod @@ -38,11 +40,11 @@ @staticmethod - def new_slice(offset, strides, backstrides, shape, parent, dtype=None): + def new_slice(offset, strides, backstrides, shape, parent, orig_arr, dtype=None): from pypy.module.micronumpy.arrayimpl import concrete impl = concrete.SliceArray(offset, strides, backstrides, shape, parent, - dtype) + orig_arr, dtype) return W_NDimArray(impl) @staticmethod diff --git a/pypy/module/micronumpy/compile.py b/pypy/module/micronumpy/compile.py --- a/pypy/module/micronumpy/compile.py +++ b/pypy/module/micronumpy/compile.py @@ -35,7 +35,8 @@ pass SINGLE_ARG_FUNCTIONS = ["sum", "prod", "max", "min", "all", "any", - "unegative", "flat", "tostring","count_nonzero"] + "unegative", "flat", "tostring","count_nonzero", + "argsort"] TWO_ARG_FUNCTIONS = ["dot", 'take'] THREE_ARG_FUNCTIONS = ['where'] @@ -482,6 +483,8 @@ w_res = cos.call(interp.space, [arr]) elif self.name == "flat": w_res = arr.descr_get_flatiter(interp.space) + elif self.name == "argsort": + w_res = arr.descr_argsort(interp.space) elif self.name == "tostring": arr.descr_tostring(interp.space) w_res = None diff --git a/pypy/module/micronumpy/constants.py b/pypy/module/micronumpy/constants.py new file mode 100644 --- /dev/null +++ b/pypy/module/micronumpy/constants.py @@ -0,0 +1,4 @@ + +MODE_WRAP, MODE_RAISE, MODE_CLIP = range(3) + +MODES = {'wrap': MODE_WRAP, 'raise': MODE_RAISE, 'clip': MODE_CLIP} diff --git a/pypy/module/micronumpy/interp_arrayops.py b/pypy/module/micronumpy/interp_arrayops.py --- a/pypy/module/micronumpy/interp_arrayops.py +++ b/pypy/module/micronumpy/interp_arrayops.py @@ -1,8 +1,10 @@ from pypy.module.micronumpy.base import convert_to_array, W_NDimArray -from pypy.module.micronumpy import loop, interp_ufuncs +from pypy.module.micronumpy import loop, interp_dtype, interp_ufuncs from pypy.module.micronumpy.iter import Chunk, Chunks -from pypy.module.micronumpy.strides import shape_agreement +from pypy.module.micronumpy.strides import shape_agreement,\ + shape_agreement_multiple +from pypy.module.micronumpy.constants import MODES from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.gateway import unwrap_spec @@ -123,7 +125,7 @@ for arr in args_w: chunks[axis] = Chunk(axis_start, axis_start + arr.get_shape()[axis], 1, arr.get_shape()[axis]) - Chunks(chunks).apply(res.implementation).implementation.setslice(space, arr) + Chunks(chunks).apply(res).implementation.setslice(space, arr) axis_start += arr.get_shape()[axis] return res @@ -137,7 +139,7 @@ res = W_NDimArray.from_shape(shape, arr.get_dtype()) for i in range(repeats): Chunks([Chunk(i, shape[0] - repeats + i, repeats, - orig_size)]).apply(res.implementation).implementation.setslice(space, arr) + orig_size)]).apply(res).implementation.setslice(space, arr) else: axis = space.int_w(w_axis) shape = arr.get_shape()[:] @@ -148,8 +150,47 @@ for i in range(repeats): chunks[axis] = Chunk(i, shape[axis] - repeats + i, repeats, orig_size) - Chunks(chunks).apply(res.implementation).implementation.setslice(space, arr) + Chunks(chunks).apply(res).implementation.setslice(space, arr) return res def count_nonzero(space, w_obj): return space.wrap(loop.count_all_true(convert_to_array(space, w_obj))) + +def choose(space, arr, w_choices, out, mode): + choices = [convert_to_array(space, w_item) for w_item + in space.listview(w_choices)] + if not choices: + raise OperationError(space.w_ValueError, + space.wrap("choices list cannot be empty")) + shape = shape_agreement_multiple(space, choices + [out]) + out = interp_dtype.dtype_agreement(space, choices, shape, out) + dtype = out.get_dtype() + if mode not in MODES: + raise OperationError(space.w_ValueError, + space.wrap("mode %s not known" % (mode,))) + loop.choose(space, arr, choices, shape, dtype, out, MODES[mode]) + return out + +def diagonal(space, arr, offset, axis1, axis2): + shape = arr.get_shape() + shapelen = len(shape) + if offset < 0: + offset = -offset + axis1, axis2 = axis2, axis1 + size = min(shape[axis1], shape[axis2] - offset) + dtype = arr.dtype + if axis1 < axis2: + shape = (shape[:axis1] + shape[axis1 + 1:axis2] + + shape[axis2 + 1:] + [size]) + else: + shape = (shape[:axis2] + shape[axis2 + 1:axis1] + + shape[axis1 + 1:] + [size]) + out = W_NDimArray.from_shape(shape, dtype) + if size == 0: + return out + if shapelen == 2: + # simple case + loop.diagonal_simple(space, arr, out, offset, axis1, axis2, size) + else: + loop.diagonal_array(space, arr, out, offset, axis1, axis2, shape) + return out diff --git a/pypy/module/micronumpy/interp_boxes.py b/pypy/module/micronumpy/interp_boxes.py --- a/pypy/module/micronumpy/interp_boxes.py +++ b/pypy/module/micronumpy/interp_boxes.py @@ -43,6 +43,9 @@ def convert_to(self, dtype): return dtype.box(self.value) + def __repr__(self): + return '%s(%s)' % (self.__class__.__name__, self.value) + class ComplexBox(object): _mixin_ = True @@ -284,6 +287,11 @@ for i in range(len(arg)): arr.storage[i] = arg[i] return W_StringBox(arr, 0, arr.dtype) + + def convert_to(self, dtype): + from pypy.module.micronumpy import types + assert isinstance(dtype.itemtype, types.StringType) + return self class W_UnicodeBox(W_CharacterBox): def descr__new__unicode_box(space, w_subtype, w_arg): @@ -297,6 +305,11 @@ # arr.storage[i] = arg[i] return W_UnicodeBox(arr, 0, arr.dtype) + def convert_to(self, dtype): + from pypy.module.micronumpy import types + assert isinstance(dtype.itemtype, types.UnicodeType) + return self + class W_ComplexFloatingBox(W_InexactBox): _attrs_ = () diff --git a/pypy/module/micronumpy/interp_dtype.py b/pypy/module/micronumpy/interp_dtype.py --- a/pypy/module/micronumpy/interp_dtype.py +++ b/pypy/module/micronumpy/interp_dtype.py @@ -5,10 +5,11 @@ from pypy.interpreter.gateway import interp2app, unwrap_spec from pypy.interpreter.typedef import (TypeDef, GetSetProperty, interp_attrproperty, interp_attrproperty_w) -from pypy.module.micronumpy import types, interp_boxes +from pypy.module.micronumpy import types, interp_boxes, base from rpython.rlib.objectmodel import specialize from rpython.rlib.rarithmetic import LONG_BIT, r_longlong, r_ulonglong from rpython.rtyper.lltypesystem import rffi +from rpython.rlib import jit UNSIGNEDLTR = "u" @@ -28,6 +29,21 @@ return space.interp_w(W_Dtype, space.call_function(space.gettypefor(W_Dtype), w_dtype)) + at jit.unroll_safe +def dtype_agreement(space, w_arr_list, shape, out=None): + """ agree on dtype from a list of arrays. if out is allocated, + use it's dtype, otherwise allocate a new one with agreed dtype + """ + from pypy.module.micronumpy.interp_ufuncs import find_binop_result_dtype + + if not space.is_none(out): + return out + dtype = w_arr_list[0].get_dtype() + for w_arr in w_arr_list[1:]: + dtype = find_binop_result_dtype(space, dtype, w_arr.get_dtype()) + out = base.W_NDimArray.from_shape(shape, dtype) + return out + class W_Dtype(Wrappable): _immutable_fields_ = ["itemtype", "num", "kind"] @@ -45,6 +61,7 @@ self.fields = fields self.fieldnames = fieldnames self.native = native + self.float_type = None @specialize.argtype(1) def box(self, value): @@ -138,6 +155,9 @@ def is_complex_type(self): return False + def is_float_type(self): + return (self.kind == FLOATINGLTR or self.float_type is not None) + def is_bool_type(self): return self.kind == BOOLLTR @@ -156,7 +176,6 @@ return self.itemtype.get_element_size() class W_ComplexDtype(W_Dtype): - def __init__(self, itemtype, num, kind, name, char, w_box_type, alternate_constructors=[], aliases=[], fields=None, fieldnames=None, native=True, float_type=None): @@ -257,7 +276,7 @@ return dtype if w_dtype is dtype.w_box_type: return dtype - raise OperationError(space.w_TypeError, space.wrap("data type not understood")) + raise OperationError(space.w_TypeError, space.wrap("data type %s not understood")) W_Dtype.typedef = TypeDef("dtype", __module__ = "numpypy", @@ -382,6 +401,7 @@ char="l", w_box_type=space.gettypefor(interp_boxes.W_LongBox), alternate_constructors=[space.w_int], + aliases=['int'], ) self.w_ulongdtype = W_Dtype( types.ULong(), @@ -596,6 +616,16 @@ itemtype, dtype.num, dtype.kind, new_name, dtype.char, dtype.w_box_type, native=False) + if dtype.kind != dtype.char: + can_name = dtype.char + self.dtypes_by_name[byteorder_prefix + can_name] = dtype + self.dtypes_by_name['=' + can_name] = dtype + new_name = nonnative_byteorder_prefix + can_name + self.dtypes_by_name[new_name] = W_Dtype( + itemtype, + dtype.num, dtype.kind, new_name, dtype.char, dtype.w_box_type, + native=False) + for alias in dtype.aliases: self.dtypes_by_name[alias] = dtype self.dtypes_by_name[dtype.char] = dtype diff --git a/pypy/module/micronumpy/interp_flatiter.py b/pypy/module/micronumpy/interp_flatiter.py --- a/pypy/module/micronumpy/interp_flatiter.py +++ b/pypy/module/micronumpy/interp_flatiter.py @@ -9,15 +9,19 @@ like a real array for descr_eq and friends """ def __init__(self, base): - self.base = base + self._base = base self.dtype = base.get_dtype() self.shape = [base.get_size()] + def base(self): + return self._base + def get_shape(self): return self.shape def create_iter(self, shape=None): - return self.base.create_iter() + assert isinstance(self.base(), W_NDimArray) + return self.base().create_iter() class W_FlatIterator(W_NDimArray): def __init__(self, arr): diff --git a/pypy/module/micronumpy/interp_numarray.py b/pypy/module/micronumpy/interp_numarray.py --- a/pypy/module/micronumpy/interp_numarray.py +++ b/pypy/module/micronumpy/interp_numarray.py @@ -4,9 +4,11 @@ from pypy.interpreter.gateway import interp2app, unwrap_spec, WrappedDefault from pypy.module.micronumpy.base import W_NDimArray, convert_to_array,\ ArrayArgumentException, issequence_w -from pypy.module.micronumpy import interp_dtype, interp_ufuncs, interp_boxes +from pypy.module.micronumpy import interp_dtype, interp_ufuncs, interp_boxes,\ + interp_arrayops from pypy.module.micronumpy.strides import find_shape_and_elems,\ - get_shape_from_iterable, to_coords, shape_agreement + get_shape_from_iterable, to_coords, shape_agreement, \ + shape_agreement_multiple from pypy.module.micronumpy.interp_flatiter import W_FlatIterator from pypy.module.micronumpy.interp_support import unwrap_axis_arg from pypy.module.micronumpy.appbridge import get_appbridge_cache @@ -16,6 +18,7 @@ from rpython.tool.sourcetools import func_with_new_name from rpython.rlib import jit from rpython.rlib.rstring import StringBuilder +from pypy.module.micronumpy.arrayimpl.base import BaseArrayImplementation def _find_shape(space, w_size): if space.is_none(w_size): @@ -37,7 +40,7 @@ return self.implementation.get_shape() def descr_set_shape(self, space, w_new_shape): - self.implementation = self.implementation.set_shape(space, + self.implementation = self.implementation.set_shape(space, self, get_shape_from_iterable(space, self.get_size(), w_new_shape)) def descr_get_strides(self, space): @@ -152,7 +155,7 @@ w_idx.get_dtype().is_bool_type()): return self.getitem_filter(space, w_idx) try: - return self.implementation.descr_getitem(space, w_idx) + return self.implementation.descr_getitem(space, self, w_idx) except ArrayArgumentException: return self.getitem_array_int(space, w_idx) except OperationError: @@ -170,7 +173,7 @@ return self.setitem_filter(space, w_idx, convert_to_array(space, w_value)) try: - self.implementation.descr_setitem(space, w_idx, w_value) + self.implementation.descr_setitem(space, self, w_idx, w_value) except ArrayArgumentException: self.setitem_array_int(space, w_idx, w_value) @@ -210,10 +213,11 @@ return s.build() def create_iter(self, shape=None): + assert isinstance(self.implementation, BaseArrayImplementation) return self.implementation.create_iter(shape) - def create_axis_iter(self, shape, dim): - return self.implementation.create_axis_iter(shape, dim) + def create_axis_iter(self, shape, dim, cum): + return self.implementation.create_axis_iter(shape, dim, cum) def create_dot_iter(self, shape, skip): return self.implementation.create_dot_iter(shape, skip) @@ -240,10 +244,10 @@ return W_NDimArray(self.implementation.copy()) def descr_get_real(self, space): - return W_NDimArray(self.implementation.get_real()) + return W_NDimArray(self.implementation.get_real(self)) def descr_get_imag(self, space): - ret = self.implementation.get_imag() + ret = self.implementation.get_imag(self) if ret: return W_NDimArray(ret) raise OperationError(space.w_NotImplementedError, @@ -251,7 +255,7 @@ def descr_set_real(self, space, w_value): # copy (broadcast) values into self - tmp = self.implementation.get_real() + tmp = self.implementation.get_real(self) tmp.setslice(space, convert_to_array(space, w_value)) def descr_set_imag(self, space, w_value): @@ -259,7 +263,7 @@ if not self.get_dtype().is_complex_type(): raise OperationError(space.w_TypeError, space.wrap('array does not have imaginary part to set')) - tmp = self.implementation.get_imag() + tmp = self.implementation.get_imag(self) tmp.setslice(space, convert_to_array(space, w_value)) def descr_reshape(self, space, args_w): @@ -279,20 +283,21 @@ else: w_shape = space.newtuple(args_w) new_shape = get_shape_from_iterable(space, self.get_size(), w_shape) - new_impl = self.implementation.reshape(space, new_shape) + new_impl = self.implementation.reshape(space, self, new_shape) if new_impl is not None: return W_NDimArray(new_impl) # Create copy with contiguous data arr = self.descr_copy(space) if arr.get_size() > 0: - arr.implementation = arr.implementation.reshape(space, new_shape) + arr.implementation = arr.implementation.reshape(space, self, + new_shape) assert arr.implementation else: arr.implementation.shape = new_shape return arr def descr_get_transpose(self, space): - return W_NDimArray(self.implementation.transpose()) + return W_NDimArray(self.implementation.transpose(self)) @unwrap_spec(axis1=int, axis2=int) def descr_swapaxes(self, space, axis1, axis2): @@ -308,7 +313,7 @@ """ if self.is_scalar(): return self - return self.implementation.swapaxes(axis1, axis2) + return self.implementation.swapaxes(self, axis1, axis2) def descr_tolist(self, space): if len(self.get_shape()) == 0: @@ -411,6 +416,170 @@ def fdel___pypy_data__(self, space): self.w_pypy_data = None + def descr_argsort(self, space, w_axis=None, w_kind=None, w_order=None): + # happily ignore the kind + # create a contiguous copy of the array + # we must do that, because we need a working set. otherwise + # we would modify the array in-place. Use this to our advantage + # by converting nonnative byte order. + s = self.get_dtype().name + if not self.get_dtype().native: + s = s[1:] + dtype = interp_dtype.get_dtype_cache(space).dtypes_by_name[s] + contig = self.implementation.astype(space, dtype) + return contig.implementation.argsort(space, w_axis) + + def descr_astype(self, space, w_dtype): + dtype = space.interp_w(interp_dtype.W_Dtype, + space.call_function(space.gettypefor(interp_dtype.W_Dtype), w_dtype)) + return self.implementation.astype(space, dtype) + + def descr_get_base(self, space): + impl = self.implementation + ret = impl.base() + if ret is None: + return space.w_None + return ret + + @unwrap_spec(inplace=bool) + def descr_byteswap(self, space, inplace=False): + if inplace: + loop.byteswap(self.implementation, self.implementation) + return self + else: + res = W_NDimArray.from_shape(self.get_shape(), self.get_dtype()) + loop.byteswap(self.implementation, res.implementation) + return res + + @unwrap_spec(mode=str) + def descr_choose(self, space, w_choices, mode='raise', w_out=None): + if w_out is not None and not isinstance(w_out, W_NDimArray): + raise OperationError(space.w_TypeError, space.wrap( + "return arrays must be of ArrayType")) + return interp_arrayops.choose(space, self, w_choices, w_out, mode) + + def descr_clip(self, space, w_min, w_max, w_out=None): + if w_out is not None and not isinstance(w_out, W_NDimArray): + raise OperationError(space.w_TypeError, space.wrap( + "return arrays must be of ArrayType")) + min = convert_to_array(space, w_min) + max = convert_to_array(space, w_max) + shape = shape_agreement_multiple(space, [self, min, max, w_out]) + out = interp_dtype.dtype_agreement(space, [self, min, max], shape, + w_out) + loop.clip(space, self, shape, min, max, out) + return out + + def descr_get_ctypes(self, space): + raise OperationError(space.w_NotImplementedError, space.wrap( + "ctypes not implemented yet")) + + def descr_get_data(self, space): + return self.implementation.get_buffer(space) + + @unwrap_spec(offset=int, axis1=int, axis2=int) + def descr_diagonal(self, space, offset=0, axis1=0, axis2=1): + if len(self.get_shape()) < 2: + raise OperationError(space.w_ValueError, space.wrap( + "need at least 2 dimensions for diagonal")) + if (axis1 < 0 or axis2 < 0 or axis1 >= len(self.get_shape()) or + axis2 >= len(self.get_shape())): + raise operationerrfmt(space.w_ValueError, + "axis1(=%d) and axis2(=%d) must be withing range (ndim=%d)", + axis1, axis2, len(self.get_shape())) + if axis1 == axis2: + raise OperationError(space.w_ValueError, space.wrap( + "axis1 and axis2 cannot be the same")) + return interp_arrayops.diagonal(space, self.implementation, offset, + axis1, axis2) + + def descr_dump(self, space, w_file): + raise OperationError(space.w_NotImplementedError, space.wrap( + "dump not implemented yet")) + + def descr_dumps(self, space): + raise OperationError(space.w_NotImplementedError, space.wrap( + "dumps not implemented yet")) + + def descr_get_flags(self, space): + raise OperationError(space.w_NotImplementedError, space.wrap( + "getting flags not implemented yet")) + + def descr_set_flags(self, space, w_args): + raise OperationError(space.w_NotImplementedError, space.wrap( + "setting flags not implemented yet")) + + @unwrap_spec(offset=int) + def descr_getfield(self, space, w_dtype, offset): + raise OperationError(space.w_NotImplementedError, space.wrap( + "getfield not implemented yet")) + + def descr_itemset(self, space, w_arg): + raise OperationError(space.w_NotImplementedError, space.wrap( + "itemset not implemented yet")) + + @unwrap_spec(neworder=str) + def descr_newbyteorder(self, space, neworder): + raise OperationError(space.w_NotImplementedError, space.wrap( + "newbyteorder not implemented yet")) + + def descr_ptp(self, space, w_axis=None, w_out=None): + raise OperationError(space.w_NotImplementedError, space.wrap( + "ptp (peak to peak) not implemented yet")) + + def descr_put(self, space, w_indices, w_values, w_mode='raise'): + raise OperationError(space.w_NotImplementedError, space.wrap( + "put not implemented yet")) + + def descr_resize(self, space, w_new_shape, w_refcheck=True): + raise OperationError(space.w_NotImplementedError, space.wrap( + "resize not implemented yet")) + + def descr_round(self, space, w_decimals=0, w_out=None): + raise OperationError(space.w_NotImplementedError, space.wrap( + "round not implemented yet")) + + def descr_searchsorted(self, space, w_v, w_side='left'): + raise OperationError(space.w_NotImplementedError, space.wrap( + "searchsorted not implemented yet")) + + def descr_setasflat(self, space, w_v): + raise OperationError(space.w_NotImplementedError, space.wrap( + "setasflat not implemented yet")) + + def descr_setfield(self, space, w_val, w_dtype, w_offset=0): + raise OperationError(space.w_NotImplementedError, space.wrap( + "setfield not implemented yet")) + + def descr_setflags(self, space, w_write=None, w_align=None, w_uic=None): + raise OperationError(space.w_NotImplementedError, space.wrap( + "setflags not implemented yet")) + + def descr_sort(self, space, w_axis=-1, w_kind='quicksort', w_order=None): + raise OperationError(space.w_NotImplementedError, space.wrap( + "sort not implemented yet")) + + def descr_squeeze(self, space): + raise OperationError(space.w_NotImplementedError, space.wrap( + "squeeze not implemented yet")) + + def descr_strides(self, space): + raise OperationError(space.w_NotImplementedError, space.wrap( + "strides not implemented yet")) + + def descr_tofile(self, space, w_fid, w_sep="", w_format="%s"): + raise OperationError(space.w_NotImplementedError, space.wrap( + "tofile not implemented yet")) + + def descr_trace(self, space, w_offset=0, w_axis1=0, w_axis2=1, + w_dtype=None, w_out=None): + raise OperationError(space.w_NotImplementedError, space.wrap( + "trace not implemented yet")) + + def descr_view(self, space, w_dtype=None, w_type=None) : + raise OperationError(space.w_NotImplementedError, space.wrap( + "view not implemented yet")) + # --------------------- operations ---------------------------- def _unaryop_impl(ufunc_name): @@ -424,6 +593,8 @@ descr_abs = _unaryop_impl("absolute") descr_invert = _unaryop_impl("invert") + descr_conj = _unaryop_impl('conjugate') + def descr_nonzero(self, space): if self.get_size() > 1: raise OperationError(space.w_ValueError, space.wrap( @@ -521,7 +692,8 @@ # ----------------------- reduce ------------------------------- - def _reduce_ufunc_impl(ufunc_name, promote_to_largest=False): + def _reduce_ufunc_impl(ufunc_name, promote_to_largest=False, + cumultative=False): def impl(self, space, w_axis=None, w_out=None, w_dtype=None): if space.is_none(w_out): out = None @@ -530,10 +702,11 @@ 'output must be an array')) else: out = w_out - return getattr(interp_ufuncs.get(space), ufunc_name).reduce(space, - self, True, promote_to_largest, w_axis, - False, out, w_dtype) - return func_with_new_name(impl, "reduce_%s_impl" % ufunc_name) + return getattr(interp_ufuncs.get(space), ufunc_name).reduce( + space, self, True, promote_to_largest, w_axis, + False, out, w_dtype, cumultative=cumultative) + return func_with_new_name(impl, "reduce_%s_impl_%d_%d" % (ufunc_name, + promote_to_largest, cumultative)) descr_sum = _reduce_ufunc_impl("add") descr_sum_promote = _reduce_ufunc_impl("add", True) @@ -543,6 +716,9 @@ descr_all = _reduce_ufunc_impl('logical_and') descr_any = _reduce_ufunc_impl('logical_or') + descr_cumsum = _reduce_ufunc_impl('add', cumultative=True) + descr_cumprod = _reduce_ufunc_impl('multiply', cumultative=True) + def descr_mean(self, space, w_axis=None, w_out=None): if space.is_none(w_axis): w_denom = space.wrap(self.get_size()) @@ -671,6 +847,9 @@ var = interp2app(W_NDimArray.descr_var), std = interp2app(W_NDimArray.descr_std), + cumsum = interp2app(W_NDimArray.descr_cumsum), + cumprod = interp2app(W_NDimArray.descr_cumprod), + copy = interp2app(W_NDimArray.descr_copy), reshape = interp2app(W_NDimArray.descr_reshape), T = GetSetProperty(W_NDimArray.descr_get_transpose), @@ -688,6 +867,18 @@ W_NDimArray.descr_set_real), imag = GetSetProperty(W_NDimArray.descr_get_imag, W_NDimArray.descr_set_imag), + conj = interp2app(W_NDimArray.descr_conj), + + argsort = interp2app(W_NDimArray.descr_argsort), + astype = interp2app(W_NDimArray.descr_astype), + base = GetSetProperty(W_NDimArray.descr_get_base), + byteswap = interp2app(W_NDimArray.descr_byteswap), + choose = interp2app(W_NDimArray.descr_choose), + clip = interp2app(W_NDimArray.descr_clip), + data = GetSetProperty(W_NDimArray.descr_get_data), + diagonal = interp2app(W_NDimArray.descr_diagonal), + + ctypes = GetSetProperty(W_NDimArray.descr_get_ctypes), # XXX unimplemented __array_interface__ = GetSetProperty(W_NDimArray.descr_array_iface), __weakref__ = make_weakref_descr(W_NDimArray), _from_shape_and_storage = interp2app(descr__from_shape_and_storage, diff --git a/pypy/module/micronumpy/interp_ufuncs.py b/pypy/module/micronumpy/interp_ufuncs.py --- a/pypy/module/micronumpy/interp_ufuncs.py +++ b/pypy/module/micronumpy/interp_ufuncs.py @@ -144,7 +144,7 @@ w_dtype) def reduce(self, space, w_obj, multidim, promote_to_largest, w_axis, - keepdims=False, out=None, dtype=None): + keepdims=False, out=None, dtype=None, cumultative=False): if self.argcount != 2: raise OperationError(space.w_ValueError, space.wrap("reduce only " "supported for binary functions")) @@ -158,7 +158,7 @@ return obj.get_scalar_value() shapelen = len(obj_shape) axis = unwrap_axis_arg(space, shapelen, w_axis) - assert axis>=0 + assert axis >= 0 size = obj.get_size() dtype = interp_dtype.decode_w_dtype(space, dtype) if dtype is None: @@ -175,7 +175,14 @@ raise operationerrfmt(space.w_ValueError, "zero-size array to " "%s.reduce without identity", self.name) if shapelen > 1 and axis < shapelen: - if keepdims: + temp = None + if cumultative: + shape = obj_shape[:] + temp_shape = obj_shape[:axis] + obj_shape[axis + 1:] + if out: + dtype = out.get_dtype() + temp = W_NDimArray.from_shape(temp_shape, dtype) + elif keepdims: shape = obj_shape[:axis] + [1] + obj_shape[axis + 1:] else: shape = obj_shape[:axis] + obj_shape[axis + 1:] @@ -202,7 +209,17 @@ else: out = W_NDimArray.from_shape(shape, dtype) return loop.do_axis_reduce(shape, self.func, obj, dtype, axis, out, - self.identity) + self.identity, cumultative, temp) + if cumultative: + if out: + if out.get_shape() != [obj.get_size()]: + raise OperationError(space.w_ValueError, space.wrap( + "out of incompatible size")) + else: + out = W_NDimArray.from_shape([obj.get_size()], dtype) + loop.compute_reduce_cumultative(obj, out, dtype, self.func, + self.identity) + return out if out: if len(out.get_shape())>0: raise operationerrfmt(space.w_ValueError, "output parameter " diff --git a/pypy/module/micronumpy/iter.py b/pypy/module/micronumpy/iter.py --- a/pypy/module/micronumpy/iter.py +++ b/pypy/module/micronumpy/iter.py @@ -45,6 +45,7 @@ from pypy.module.micronumpy.strides import enumerate_chunks,\ calculate_slice_strides from pypy.module.micronumpy.base import W_NDimArray +from pypy.module.micronumpy.arrayimpl import base from rpython.rlib import jit # structures to describe slicing @@ -56,12 +57,13 @@ def __init__(self, name): self.name = name - def apply(self, arr): + def apply(self, orig_arr): + arr = orig_arr.implementation ofs, subdtype = arr.dtype.fields[self.name] # strides backstrides are identical, ofs only changes start return W_NDimArray.new_slice(arr.start + ofs, arr.get_strides(), arr.get_backstrides(), - arr.shape, arr, subdtype) + arr.shape, arr, orig_arr, subdtype) class Chunks(BaseChunk): def __init__(self, l): @@ -78,13 +80,14 @@ assert s >= 0 return shape[:] + old_shape[s:] - def apply(self, arr): + def apply(self, orig_arr): + arr = orig_arr.implementation shape = self.extend_shape(arr.shape) r = calculate_slice_strides(arr.shape, arr.start, arr.get_strides(), arr.get_backstrides(), self.l) _, start, strides, backstrides = r return W_NDimArray.new_slice(start, strides[:], backstrides[:], - shape[:], arr) + shape[:], arr, orig_arr) class Chunk(BaseChunk): @@ -121,3 +124,193 @@ class BroadcastTransform(BaseTransform): def __init__(self, res_shape): self.res_shape = res_shape + +class PureShapeIterator(object): + def __init__(self, shape, idx_w): + self.shape = shape + self.shapelen = len(shape) + self.indexes = [0] * len(shape) + self._done = False + self.idx_w = [None] * len(idx_w) + for i, w_idx in enumerate(idx_w): + if isinstance(w_idx, W_NDimArray): + self.idx_w[i] = w_idx.create_iter(shape) + + def done(self): + return self._done + + @jit.unroll_safe + def next(self): + for w_idx in self.idx_w: + if w_idx is not None: + w_idx.next() + for i in range(self.shapelen - 1, -1, -1): + if self.indexes[i] < self.shape[i] - 1: + self.indexes[i] += 1 + break + else: + self.indexes[i] = 0 + else: + self._done = True + + @jit.unroll_safe + def get_index(self, space, shapelen): + return [space.wrap(self.indexes[i]) for i in range(shapelen)] + +class ConcreteArrayIterator(base.BaseArrayIterator): + _immutable_fields_ = ['dtype', 'skip', 'size'] + def __init__(self, array): + self.array = array + self.offset = 0 + self.dtype = array.dtype + self.skip = self.dtype.itemtype.get_element_size() + self.size = array.size + + def setitem(self, elem): + self.dtype.setitem(self.array, self.offset, elem) + + def getitem(self): + return self.dtype.getitem(self.array, self.offset) + + def getitem_bool(self): + return self.dtype.getitem_bool(self.array, self.offset) + + def next(self): + self.offset += self.skip + + def next_skip_x(self, x): + self.offset += self.skip * x + + def done(self): + return self.offset >= self.size + + def reset(self): + self.offset %= self.size + +class OneDimViewIterator(ConcreteArrayIterator): + ''' The view iterator dtype can be different from the + array.dtype, this is what makes it a View + ''' + def __init__(self, array, dtype, start, strides, shape): + self.array = array + self.dtype = dtype + self.offset = start + self.skip = strides[0] + self.index = 0 + self.size = shape[0] + + def next(self): + self.offset += self.skip + self.index += 1 + + def next_skip_x(self, x): + self.offset += self.skip * x + self.index += x + + def done(self): + return self.index >= self.size + + def reset(self): + self.offset %= self.size + +class MultiDimViewIterator(ConcreteArrayIterator): + ''' The view iterator dtype can be different from the + array.dtype, this is what makes it a View + ''' + def __init__(self, array, dtype, start, strides, backstrides, shape): + self.indexes = [0] * len(shape) + self.array = array + self.dtype = dtype + self.shape = shape + self.offset = start + self.shapelen = len(shape) + self._done = False + self.strides = strides + self.backstrides = backstrides + self.size = array.size + + @jit.unroll_safe + def next(self): + offset = self.offset + for i in range(self.shapelen - 1, -1, -1): + if self.indexes[i] < self.shape[i] - 1: + self.indexes[i] += 1 + offset += self.strides[i] + break + else: + self.indexes[i] = 0 + offset -= self.backstrides[i] + else: + self._done = True + self.offset = offset + + @jit.unroll_safe + def next_skip_x(self, step): + for i in range(len(self.shape) - 1, -1, -1): + if self.indexes[i] < self.shape[i] - step: + self.indexes[i] += step + self.offset += self.strides[i] * step + break + else: + remaining_step = (self.indexes[i] + step) // self.shape[i] + this_i_step = step - remaining_step * self.shape[i] + self.offset += self.strides[i] * this_i_step + self.indexes[i] = self.indexes[i] + this_i_step + step = remaining_step + else: + self._done = True + + def done(self): + return self._done + + def reset(self): + self.offset %= self.size + +class AxisIterator(base.BaseArrayIterator): + def __init__(self, array, shape, dim, cumultative): + self.shape = shape + strides = array.get_strides() + backstrides = array.get_backstrides() + if cumultative: + self.strides = strides + self.backstrides = backstrides + elif len(shape) == len(strides): + # keepdims = True + self.strides = strides[:dim] + [0] + strides[dim + 1:] + self.backstrides = backstrides[:dim] + [0] + backstrides[dim + 1:] + else: + self.strides = strides[:dim] + [0] + strides[dim:] + self.backstrides = backstrides[:dim] + [0] + backstrides[dim:] + self.first_line = True + self.indices = [0] * len(shape) + self._done = False + self.offset = array.start + self.dim = dim + self.array = array + self.dtype = array.dtype + + def setitem(self, elem): + self.dtype.setitem(self.array, self.offset, elem) + + def getitem(self): + return self.dtype.getitem(self.array, self.offset) + + @jit.unroll_safe + def next(self): + for i in range(len(self.shape) - 1, -1, -1): + if self.indices[i] < self.shape[i] - 1: + if i == self.dim: + self.first_line = False + self.indices[i] += 1 + self.offset += self.strides[i] + break + else: + if i == self.dim: + self.first_line = True + self.indices[i] = 0 + self.offset -= self.backstrides[i] + else: + self._done = True + + def done(self): + return self._done diff --git a/pypy/module/micronumpy/loop.py b/pypy/module/micronumpy/loop.py --- a/pypy/module/micronumpy/loop.py +++ b/pypy/module/micronumpy/loop.py @@ -5,9 +5,13 @@ """ from rpython.rlib.rstring import StringBuilder +from pypy.interpreter.error import OperationError from rpython.rlib import jit from rpython.rtyper.lltypesystem import lltype, rffi from pypy.module.micronumpy.base import W_NDimArray +from pypy.module.micronumpy.iter import PureShapeIterator +from pypy.module.micronumpy import constants +from pypy.module.micronumpy.support import int_w call2_driver = jit.JitDriver(name='numpy_call2', greens = ['shapelen', 'func', 'calc_dtype', @@ -86,7 +90,7 @@ reduce_driver = jit.JitDriver(name='numpy_reduce', greens = ['shapelen', 'func', 'done_func', 'calc_dtype', 'identity'], - reds = ['obj', 'obj_iter', 'cur_value']) + reds = 'auto') def compute_reduce(obj, calc_dtype, func, done_func, identity): obj_iter = obj.create_iter() @@ -98,9 +102,9 @@ shapelen = len(obj.get_shape()) while not obj_iter.done(): reduce_driver.jit_merge_point(shapelen=shapelen, func=func, + done_func=done_func, calc_dtype=calc_dtype, identity=identity, - done_func=done_func, obj=obj, - obj_iter=obj_iter, cur_value=cur_value) + ) rval = obj_iter.getitem().convert_to(calc_dtype) if done_func is not None and done_func(calc_dtype, rval): return rval @@ -108,6 +112,24 @@ obj_iter.next() return cur_value +reduce_cum_driver = jit.JitDriver(greens = ['shapelen', 'func', 'dtype'], + reds = 'auto') + +def compute_reduce_cumultative(obj, out, calc_dtype, func, identity): + obj_iter = obj.create_iter() + out_iter = out.create_iter() + cur_value = identity.convert_to(calc_dtype) + shapelen = len(obj.get_shape()) + while not obj_iter.done(): + reduce_cum_driver.jit_merge_point(shapelen=shapelen, func=func, + dtype=calc_dtype, + ) + rval = obj_iter.getitem().convert_to(calc_dtype) + cur_value = func(calc_dtype, cur_value, rval) + out_iter.setitem(cur_value) + out_iter.next() + obj_iter.next() + def fill(arr, box): arr_iter = arr.create_iter() while not arr_iter.done(): @@ -116,8 +138,7 @@ where_driver = jit.JitDriver(name='numpy_where', greens = ['shapelen', 'dtype', 'arr_dtype'], - reds = ['shape', 'arr', 'x', 'y','arr_iter', 'out', - 'x_iter', 'y_iter', 'iter', 'out_iter']) + reds = 'auto') def where(out, shape, arr, x, y, dtype): out_iter = out.create_iter(shape) @@ -134,11 +155,8 @@ iter = x_iter shapelen = len(shape) while not iter.done(): - where_driver.jit_merge_point(shapelen=shapelen, shape=shape, - dtype=dtype, iter=iter, x_iter=x_iter, - y_iter=y_iter, arr_iter=arr_iter, - arr=arr, x=x, y=y, arr_dtype=arr_dtype, - out_iter=out_iter, out=out) + where_driver.jit_merge_point(shapelen=shapelen, dtype=dtype, + arr_dtype=arr_dtype) w_cond = arr_iter.getitem() if arr_dtype.itemtype.bool(w_cond): w_val = x_iter.getitem().convert_to(dtype) @@ -152,13 +170,18 @@ return out axis_reduce__driver = jit.JitDriver(name='numpy_axis_reduce', - greens=['shapelen', 'func', 'dtype', + greens=['shapelen', + 'func', 'dtype', 'identity'], - reds=['axis', 'arr', 'out', 'shape', - 'out_iter', 'arr_iter']) + reds='auto') -def do_axis_reduce(shape, func, arr, dtype, axis, out, identity): - out_iter = out.create_axis_iter(arr.get_shape(), axis) +def do_axis_reduce(shape, func, arr, dtype, axis, out, identity, cumultative, + temp): + out_iter = out.create_axis_iter(arr.get_shape(), axis, cumultative) + if cumultative: + temp_iter = temp.create_axis_iter(arr.get_shape(), axis, False) + else: + temp_iter = out_iter # hack arr_iter = arr.create_iter() if identity is not None: identity = identity.convert_to(dtype) @@ -166,17 +189,18 @@ while not out_iter.done(): axis_reduce__driver.jit_merge_point(shapelen=shapelen, func=func, dtype=dtype, identity=identity, - axis=axis, arr=arr, out=out, - shape=shape, out_iter=out_iter, - arr_iter=arr_iter) + ) w_val = arr_iter.getitem().convert_to(dtype) if out_iter.first_line: if identity is not None: w_val = func(dtype, identity, w_val) else: - cur = out_iter.getitem() + cur = temp_iter.getitem() w_val = func(dtype, cur, w_val) out_iter.setitem(w_val) + if cumultative: + temp_iter.setitem(w_val) + temp_iter.next() arr_iter.next() out_iter.next() return out @@ -185,8 +209,7 @@ def _new_argmin_argmax(op_name): arg_driver = jit.JitDriver(name='numpy_' + op_name, greens = ['shapelen', 'dtype'], - reds = ['result', 'idx', 'cur_best', 'arr', - 'iter']) + reds = 'auto') def argmin_argmax(arr): result = 0 @@ -198,8 +221,7 @@ shapelen = len(arr.get_shape()) while not iter.done(): arg_driver.jit_merge_point(shapelen=shapelen, dtype=dtype, - result=result, idx=idx, - cur_best=cur_best, arr=arr, iter=iter) + ) w_val = iter.getitem() new_best = getattr(dtype.itemtype, op_name)(cur_best, w_val) if dtype.itemtype.ne(new_best, cur_best): @@ -215,7 +237,7 @@ # note that shapelen == 2 always dot_driver = jit.JitDriver(name = 'numpy_dot', greens = ['dtype'], - reds = ['outi', 'lefti', 'righti', 'result']) + reds = 'auto') def multidim_dot(space, left, right, result, dtype, right_critical_dim): ''' assumes left, right are concrete arrays @@ -242,8 +264,7 @@ lefti = left.create_dot_iter(broadcast_shape, left_skip) righti = right.create_dot_iter(broadcast_shape, right_skip) while not outi.done(): - dot_driver.jit_merge_point(dtype=dtype, outi=outi, lefti=lefti, - righti=righti, result=result) + dot_driver.jit_merge_point(dtype=dtype) lval = lefti.getitem().convert_to(dtype) rval = righti.getitem().convert_to(dtype) outval = outi.getitem().convert_to(dtype) @@ -257,7 +278,7 @@ count_all_true_driver = jit.JitDriver(name = 'numpy_count', greens = ['shapelen', 'dtype'], - reds = ['s', 'iter']) + reds = 'auto') def count_all_true(arr): s = 0 @@ -267,8 +288,7 @@ shapelen = len(arr.get_shape()) dtype = arr.get_dtype() while not iter.done(): - count_all_true_driver.jit_merge_point(shapelen=shapelen, iter=iter, - s=s, dtype=dtype) + count_all_true_driver.jit_merge_point(shapelen=shapelen, dtype=dtype) s += iter.getitem_bool() iter.next() return s @@ -276,8 +296,7 @@ getitem_filter_driver = jit.JitDriver(name = 'numpy_getitem_bool', greens = ['shapelen', 'arr_dtype', 'index_dtype'], - reds = ['res', 'index_iter', 'res_iter', - 'arr_iter']) + reds = 'auto') def getitem_filter(res, arr, index): res_iter = res.create_iter() @@ -291,9 +310,7 @@ getitem_filter_driver.jit_merge_point(shapelen=shapelen, index_dtype=index_dtype, arr_dtype=arr_dtype, - res=res, index_iter=index_iter, - res_iter=res_iter, - arr_iter=arr_iter) + ) if index_iter.getitem_bool(): res_iter.setitem(arr_iter.getitem()) res_iter.next() @@ -304,8 +321,7 @@ setitem_filter_driver = jit.JitDriver(name = 'numpy_setitem_bool', greens = ['shapelen', 'arr_dtype', 'index_dtype'], - reds = ['index_iter', 'value_iter', - 'arr_iter']) + reds = 'auto') def setitem_filter(arr, index, value): arr_iter = arr.create_iter() @@ -318,9 +334,7 @@ setitem_filter_driver.jit_merge_point(shapelen=shapelen, index_dtype=index_dtype, arr_dtype=arr_dtype, - index_iter=index_iter, - value_iter=value_iter, - arr_iter=arr_iter) + ) if index_iter.getitem_bool(): arr_iter.setitem(value_iter.getitem()) value_iter.next() @@ -329,16 +343,13 @@ flatiter_getitem_driver = jit.JitDriver(name = 'numpy_flatiter_getitem', greens = ['dtype'], - reds = ['step', 'ri', 'res', - 'base_iter']) + reds = 'auto') def flatiter_getitem(res, base_iter, step): ri = res.create_iter() dtype = res.get_dtype() while not ri.done(): - flatiter_getitem_driver.jit_merge_point(dtype=dtype, - base_iter=base_iter, - ri=ri, res=res, step=step) + flatiter_getitem_driver.jit_merge_point(dtype=dtype) ri.setitem(base_iter.getitem()) base_iter.next_skip_x(step) ri.next() @@ -346,8 +357,7 @@ flatiter_setitem_driver = jit.JitDriver(name = 'numpy_flatiter_setitem', greens = ['dtype'], - reds = ['length', 'step', 'arr_iter', - 'val_iter']) + reds = 'auto') def flatiter_setitem(arr, val, start, step, length): dtype = arr.get_dtype() @@ -355,9 +365,7 @@ val_iter = val.create_iter() arr_iter.next_skip_x(start) while length > 0: - flatiter_setitem_driver.jit_merge_point(dtype=dtype, length=length, - step=step, arr_iter=arr_iter, - val_iter=val_iter) + flatiter_setitem_driver.jit_merge_point(dtype=dtype) arr_iter.setitem(val_iter.getitem().convert_to(dtype)) # need to repeat i_nput values until all assignments are done arr_iter.next_skip_x(step) @@ -368,14 +376,13 @@ fromstring_driver = jit.JitDriver(name = 'numpy_fromstring', greens = ['itemsize', 'dtype'], - reds = ['i', 's', 'ai']) + reds = 'auto') def fromstring_loop(a, dtype, itemsize, s): i = 0 From noreply at buildbot.pypy.org Wed Feb 6 14:51:16 2013 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 6 Feb 2013 14:51:16 +0100 (CET) Subject: [pypy-commit] pypy missing-ndarray-attributes: close to-be-merged branch Message-ID: <20130206135116.B559A1C0313@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: missing-ndarray-attributes Changeset: r60904:7011833f8fac Date: 2013-02-06 15:50 +0200 http://bitbucket.org/pypy/pypy/changeset/7011833f8fac/ Log: close to-be-merged branch From noreply at buildbot.pypy.org Wed Feb 6 14:51:41 2013 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 6 Feb 2013 14:51:41 +0100 (CET) Subject: [pypy-commit] pypy default: dummy merge to avoid dangling heads\ Message-ID: <20130206135141.B8C821C0313@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r60905:71826102f2d6 Date: 2013-02-06 15:51 +0200 http://bitbucket.org/pypy/pypy/changeset/71826102f2d6/ Log: dummy merge to avoid dangling heads\ From noreply at buildbot.pypy.org Wed Feb 6 17:50:14 2013 From: noreply at buildbot.pypy.org (bivab) Date: Wed, 6 Feb 2013 17:50:14 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: start moving gcmap code to llsupport Message-ID: <20130206165014.1535C1C101E@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: jitframe-on-heap Changeset: r60907:f3bcd44e7321 Date: 2013-02-06 17:20 +0100 http://bitbucket.org/pypy/pypy/changeset/f3bcd44e7321/ Log: start moving gcmap code to llsupport diff --git a/rpython/jit/backend/llsupport/gcmap.py b/rpython/jit/backend/llsupport/gcmap.py new file mode 100644 --- /dev/null +++ b/rpython/jit/backend/llsupport/gcmap.py @@ -0,0 +1,20 @@ +from rpython.rtyper.lltypesystem import rffi +from rpython.rtyper.lltypesystem import lltype +from rpython.jit.backend.llsupport import jitframe +from rpython.rlib.rarithmetic import r_uint +from rpython.jit.backend.llsupport.symbolic import WORD +from rpython.rlib.debug import debug_print + +def allocate_gcmap(assembler, frame_depth, fixed_size): + size = frame_depth + fixed_size + malloc_size = (size // WORD // 8 + 1) + 1 + rawgcmap = assembler.datablockwrapper.malloc_aligned(WORD * malloc_size, + WORD) + debug_print("gcmap: %x, len %d" % (rawgcmap, malloc_size - 1)) + # set the length field + rffi.cast(rffi.CArrayPtr(lltype.Signed), rawgcmap)[0] = malloc_size - 1 + gcmap = rffi.cast(lltype.Ptr(jitframe.GCMAP), rawgcmap) + # zero the area + for i in range(malloc_size - 1): + gcmap[i] = r_uint(0) + return gcmap diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -2,6 +2,7 @@ import sys, os from rpython.jit.backend.llsupport import symbolic, jitframe from rpython.jit.backend.llsupport.asmmemmgr import MachineDataBlockWrapper +from rpython.jit.backend.llsupport.gcmap import allocate_gcmap from rpython.jit.metainterp.history import Const, Box, BoxInt, ConstInt from rpython.jit.metainterp.history import AbstractFailDescr, INT, REF, FLOAT from rpython.jit.metainterp.history import JitCellToken @@ -1845,26 +1846,11 @@ guard_opnum == rop.GUARD_NOT_FORCED) is_guard_not_invalidated = guard_opnum == rop.GUARD_NOT_INVALIDATED is_guard_not_forced = guard_opnum == rop.GUARD_NOT_FORCED - gcmap = self.allocate_gcmap(frame_depth) + gcmap = allocate_gcmap(self, frame_depth, JITFRAME_FIXED_SIZE) return GuardToken(gcmap, faildescr, failargs, fail_locs, exc, frame_depth, is_guard_not_invalidated, is_guard_not_forced) - def allocate_gcmap(self, frame_depth): - size = frame_depth + JITFRAME_FIXED_SIZE - malloc_size = (size // WORD // 8 + 1) + 1 - rawgcmap = self.datablockwrapper.malloc_aligned(WORD * malloc_size, - WORD) - debug_print("gcmap: %x, len %d for %d" % (rawgcmap, malloc_size - 1, - self.mc.get_relative_pos())) - # set the length field - rffi.cast(rffi.CArrayPtr(lltype.Signed), rawgcmap)[0] = malloc_size - 1 - gcmap = rffi.cast(lltype.Ptr(jitframe.GCMAP), rawgcmap) - # zero the area - for i in range(malloc_size - 1): - gcmap[i] = r_uint(0) - return gcmap - def generate_propagate_error_64(self): assert WORD == 8 startpos = self.mc.get_relative_pos() From noreply at buildbot.pypy.org Wed Feb 6 17:50:12 2013 From: noreply at buildbot.pypy.org (bivab) Date: Wed, 6 Feb 2013 17:50:12 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: move code to llmodel Message-ID: <20130206165012.A6FF01C101A@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: jitframe-on-heap Changeset: r60906:80c28f5cff6d Date: 2013-02-06 17:09 +0100 http://bitbucket.org/pypy/pypy/changeset/80c28f5cff6d/ Log: move code to llmodel diff --git a/rpython/jit/backend/llsupport/llmodel.py b/rpython/jit/backend/llsupport/llmodel.py --- a/rpython/jit/backend/llsupport/llmodel.py +++ b/rpython/jit/backend/llsupport/llmodel.py @@ -11,7 +11,8 @@ from rpython.jit.backend.llsupport.descr import ( get_size_descr, get_field_descr, get_array_descr, get_call_descr, get_interiorfield_descr, - FieldDescr, ArrayDescr, CallDescr, InteriorFieldDescr) + FieldDescr, ArrayDescr, CallDescr, InteriorFieldDescr, + FLAG_POINTER, FLAG_FLOAT) from rpython.jit.backend.llsupport.asmmemmgr import AsmMemoryManager from rpython.annotator import model as annmodel @@ -46,8 +47,25 @@ self._setup_exception_handling_untranslated() self.asmmemmgr = AsmMemoryManager() self._setup_frame_realloc(translate_support_code) + ad = self.gc_ll_descr.getframedescrs(self).arraydescr + self.signedarraydescr = ad + # the same as normal JITFRAME, however with an array of pointers + self.refarraydescr = ArrayDescr(ad.basesize, ad.itemsize, ad.lendescr, + FLAG_POINTER) + self.floatarraydescr = ArrayDescr(ad.basesize, ad.itemsize, ad.lendescr, + FLAG_FLOAT) self.setup() + def getarraydescr_for_frame(self, type, index): + if type == history.FLOAT: + descr = self.floatarraydescr + elif type == history.REF: + descr = self.refarraydescr + else: + descr = self.signedarraydescr + return JITFRAME_FIXED_SIZE + index, descr + + def setup(self): pass diff --git a/rpython/jit/backend/x86/runner.py b/rpython/jit/backend/x86/runner.py --- a/rpython/jit/backend/x86/runner.py +++ b/rpython/jit/backend/x86/runner.py @@ -13,8 +13,6 @@ from rpython.jit.backend.llsupport import jitframe from rpython.jit.backend.x86 import regloc from rpython.jit.backend.llsupport.symbolic import WORD -from rpython.jit.backend.llsupport.descr import ArrayDescr, FLAG_POINTER,\ - FLAG_FLOAT import sys @@ -48,23 +46,6 @@ self.profile_agent = profile_agent - ad = self.gc_ll_descr.getframedescrs(self).arraydescr - self.signedarraydescr = ad - # the same as normal JITFRAME, however with an array of pointers - self.refarraydescr = ArrayDescr(ad.basesize, ad.itemsize, ad.lendescr, - FLAG_POINTER) - self.floatarraydescr = ArrayDescr(ad.basesize, ad.itemsize, ad.lendescr, - FLAG_FLOAT) - - def getarraydescr_for_frame(self, type, index): - if type == history.FLOAT: - descr = self.floatarraydescr - elif type == history.REF: - descr = self.refarraydescr - else: - descr = self.signedarraydescr - return JITFRAME_FIXED_SIZE + index, descr - def set_debug(self, flag): return self.assembler.set_debug(flag) From noreply at buildbot.pypy.org Wed Feb 6 17:50:15 2013 From: noreply at buildbot.pypy.org (bivab) Date: Wed, 6 Feb 2013 17:50:15 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: load store helper methods Message-ID: <20130206165015.5068E1C105B@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: jitframe-on-heap Changeset: r60908:747460bbcce4 Date: 2013-02-06 17:28 +0100 http://bitbucket.org/pypy/pypy/changeset/747460bbcce4/ Log: load store helper methods diff --git a/rpython/jit/backend/arm/assembler.py b/rpython/jit/backend/arm/assembler.py --- a/rpython/jit/backend/arm/assembler.py +++ b/rpython/jit/backend/arm/assembler.py @@ -966,6 +966,46 @@ faildescr._arm_failure_recovery_block = 0 # regalloc support + def load_reg(self, mc, target, base, ofs, cond=c.AL, helper=r.ip): + if target.is_vfp_reg(): + return self._load_vfp_reg(mc, target, base, ofs, cond) + elif target.is_reg(): + return self._load_core_reg(mc, target, base, ofs, cond) + + def _load_vfp_reg(self, mc, target, base, ofs, cond=c.AL, helper=r.ip): + if check_imm_arg(ofs): + mc.VLDR(target.value, base.value, imm=ofs, cond=cond) + else: + mc.gen_load_int(helper.value, ofs) + mc.VLDR(target.value, base.value, helper.value, cond=cond) + + def _load_core_reg(self, mc, target, base, ofs, cond=c.AL, helper=r.ip): + if check_imm_arg(ofs): + mc.LDR_ri(target.value, base.value, imm=ofs, cond=cond) + else: + mc.gen_load_int(helper.value, ofs) + mc.LDR_rr(target.value, base.value, helper.value, cond=cond) + + def store_reg(self, mc, source, base, ofs, cond=c.AL, helper=r.ip): + if source.is_vfp_reg(): + return self._store_vfp_reg(mc, source, base, ofs, cond) + else: + return self._store_core_reg(mc, source, base, ofs, cond) + + def _store_vfp_reg(self, mc, source, base, ofs, cond=c.AL, helper=r.ip): + if check_imm_arg(ofs): + mc.VSTR(source.value, base.value, imm=ofs, cond=cond) + else: + mc.gen_load_int(helper.value, ofs) + mc.VSTR(source.value, base.value, helper.value, cond=cond) + + def _store_core_reg(self, mc, source, base, ofs, cond=c.AL, helper=r.ip): + if check_imm_arg(ofs): + mc.STR_ri(source.value, base.value, imm=ofs, cond=cond) + else: + gen_load_int(helper.value, ofs) + mc.STR_rr(source.value, base.value, helper.value, cond=cond) + def load(self, loc, value): assert (loc.is_reg() and value.is_imm() or loc.is_vfp_reg() and value.is_imm_float()) From noreply at buildbot.pypy.org Wed Feb 6 17:50:16 2013 From: noreply at buildbot.pypy.org (bivab) Date: Wed, 6 Feb 2013 17:50:16 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: fp register now points to the start of the JITFRAME Message-ID: <20130206165016.85DC41C101A@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: jitframe-on-heap Changeset: r60909:a31d38ea0ff3 Date: 2013-02-06 17:37 +0100 http://bitbucket.org/pypy/pypy/changeset/a31d38ea0ff3/ Log: fp register now points to the start of the JITFRAME diff --git a/rpython/jit/backend/arm/assembler.py b/rpython/jit/backend/arm/assembler.py --- a/rpython/jit/backend/arm/assembler.py +++ b/rpython/jit/backend/arm/assembler.py @@ -231,6 +231,7 @@ ofs = self.cpu.get_ofs_of_frame_field('jf_descr') # make sure ofs fits into a register assert check_imm_arg(ofs) + self.mc.MOV_rr(r.r0.value, r.fp.value) self.mc.BKPT() #base_ofs = self.cpu.get_baseofs_of_frame_field() #self.mc.MOV_bi(ofs, propagate_exception_descr) @@ -377,15 +378,16 @@ def _push_all_regs_to_jitframe(self, mc, ignored_regs, withfloats, callee_only=False): + base_ofs = self.cpu.get_baseofs_of_frame_field() if callee_only: regs = CoreRegisterManager.save_around_call_regs else: regs = CoreRegisterManager.all_regs - # use STMDB ops here + # XXX use STMDB ops here for i, gpr in enumerate(regs): if gpr in ignored_regs: continue - mc.STR_ri(gpr.value, r.fp.value, i * WORD) + self.store_reg(mc, gpr, r.fp, base_ofs + i * WORD) if withfloats: if callee_only: regs = VFPRegisterManager.save_around_call_regs @@ -394,8 +396,36 @@ for i, vfpr in enumerate(regs): if vfpr in ignored_regs: continue - # add the offset of the gpr_regs - mc.VSTR(vfpr.value, r.fp.value, imm=i * DOUBLE_WORD) + ofs = len(CoreRegisterManager.all_regs) * WORD + ofs += i * DOUBLE_WORD + base_ofs + self.store_reg(mc, vfpr, r.fp, ofs) + + def _pop_all_regs_from_jitframe(self, mc, ignored_regs, withfloats, + callee_only=False): + # Pop all general purpose registers + base_ofs = self.cpu.get_baseofs_of_frame_field() + if callee_only: + regs = CoreRegisterManager.save_around_call_regs + else: + regs = CoreRegisterManager.all_regs + # XXX use LDMDB ops here + for i, gpr in enumerate(regs): + if gpr in ignored_regs: + continue + ofs = i * WORD + base_ofs + self.load_reg(mc, gpr, r.fp, ofs) + if withfloats: + # Pop all XMM regs + if callee_only: + regs = VFPRegisterManager.save_around_call_regs + else: + regs = VFPRegisterManager.all_regs + for i, vfpr in enumerate(regs): + if vfpr in ignored_regs: + continue + ofs = len(CoreRegisterManager.all_regs) * WORD + ofs += i * DOUBLE_WORD + base_ofs + self.load_reg(mc, vfpr, r.fp, ofs) def _build_failure_recovery(self, exc, withfloats=False): mc = ARMv7Builder() @@ -434,8 +464,8 @@ # set return value assert check_imm_arg(base_ofs) - mc.SUB_ri(r.r0.value, r.fp.value, base_ofs) - + mc.MOV_rr(r.r0.value, r.fp.value) + # self.gen_func_epilog(mc) rawstart = mc.materialize(self.cpu.asmmemmgr, []) self.failure_recovery_code[exc + 2 * withfloats] = rawstart @@ -547,10 +577,8 @@ self.mc.SUB_ri(r.sp.value, r.sp.value, WORD) # for the force index assert stack_size % 8 == 0 # ensure we keep alignment - # set fp to point to the JITFRAME + ofs - ofs = self.cpu.get_baseofs_of_frame_field() - assert check_imm_arg(ofs) - self.mc.ADD_ri(r.fp.value, r.r0.value, imm=ofs) + # set fp to point to the JITFRAME + self.mc.MOV_rr(r.fp.value, r.r0.value) # gcrootmap = self.cpu.gc_ll_descr.gcrootmap if gcrootmap and gcrootmap.is_shadow_stack: @@ -734,9 +762,12 @@ faildescr._arm_bridge_frame_depth = frame_depth if log: self.mc._dump_trace(rawstart, 'bridge.asm') + + ops_offset = self.mc.ops_offset frame_depth = max(self.current_clt.frame_info.jfi_frame_depth, - frame_depth + JITFRAME_FIXED_SIZE) - ops_offset = self.mc.ops_offset + frame_depth_no_fixed_size + JITFRAME_FIXED_SIZE) + self.fixup_target_tokens(rawstart) + self.update_frame_depth(frame_depth) self.teardown() debug_start("jit-backend-addr") @@ -1309,6 +1340,7 @@ mc.MOV_bi(ofs, 0) + def not_implemented(msg): os.write(2, '[ARM/asm] %s\n' % msg) raise NotImplementedError(msg) diff --git a/rpython/jit/backend/arm/locations.py b/rpython/jit/backend/arm/locations.py --- a/rpython/jit/backend/arm/locations.py +++ b/rpython/jit/backend/arm/locations.py @@ -136,5 +136,5 @@ return ImmLocation(i) -def get_fp_offset(position): - return WORD * (position + JITFRAME_FIXED_SIZE) +def get_fp_offset(base_ofs, position): + return base_ofs + WORD * (position + JITFRAME_FIXED_SIZE) diff --git a/rpython/jit/backend/arm/opassembler.py b/rpython/jit/backend/arm/opassembler.py --- a/rpython/jit/backend/arm/opassembler.py +++ b/rpython/jit/backend/arm/opassembler.py @@ -67,8 +67,8 @@ if loc.is_reg(): val = loc.value else: - assert 0, 'ffuu, implement' - val = loc.value // WORD + assert loc.is_stack() + val = JITFRAME_FIXED_SIZE + loc.value gcmap[val // WORD // 8] |= r_uint(1) << (val % (WORD * 8)) return gcmap @@ -358,25 +358,20 @@ return fcond def emit_op_finish(self, op, arglocs, regalloc, fcond): - base_ofs = self.cpu.get_baseofs_of_frame_field() - WORD + base_ofs = self.cpu.get_baseofs_of_frame_field() if len(arglocs) == 2: [return_val, fail_descr_loc] = arglocs - if op.getarg(0).type == FLOAT: - self.mc.VSTR(return_val.value, r.fp.value)#, imm=-base_ofs) - else: - self.mc.STR_ri(return_val.value, r.fp.value)#, imm=-base_ofs) - #self.save_into_mem(raw_stack(0), return_val, imm(size)) + self.store_reg(self.mc, return_val, r.fp, base_ofs) else: [fail_descr_loc] = arglocs ofs = self.cpu.get_ofs_of_frame_field('jf_descr') - base_ofs = self.cpu.get_baseofs_of_frame_field() self.mc.gen_load_int(r.ip.value, fail_descr_loc.value) # XXX self.mov(fail_descr_loc, RawStackLoc(ofs)) - self.mc.STR_ri(r.ip.value, r.fp.value, imm=ofs) + self.store_reg(self.mc, r.ip, r.fp, ofs, helper=r.lr) gcmap = self.gcmap_for_finish self.push_gcmap(self.mc, gcmap, store=True) - self.mc.SUB_ri(r.r0.value, r.fp.value, base_ofs) + self.mc.MOV_rr(r.r0.value, r.fp.value) # exit function self.gen_func_epilog() return fcond diff --git a/rpython/jit/backend/arm/regalloc.py b/rpython/jit/backend/arm/regalloc.py --- a/rpython/jit/backend/arm/regalloc.py +++ b/rpython/jit/backend/arm/regalloc.py @@ -61,12 +61,12 @@ class ARMFrameManager(FrameManager): - def __init__(self): + def __init__(self, base_ofs): FrameManager.__init__(self) + self.base_ofs = base_ofs - @staticmethod - def frame_pos(i, box_type): - return locations.StackLocation(i, get_fp_offset(i), box_type) + def frame_pos(self, i, box_type): + return locations.StackLocation(i, get_fp_offset(self.base_ofs, i), box_type) @staticmethod def frame_size(type): @@ -282,8 +282,9 @@ return self.vfprm.convert_to_imm(value) def _prepare(self, inputargs, operations, allgcrefs): - self.frame_manager = self.fm = ARMFrameManager() cpu = self.assembler.cpu + self.fm = ARMFrameManager(cpu.get_baseofs_of_frame_field()) + self.frame_manager = self.fm operations = cpu.gc_ll_descr.rewrite_assembler(cpu, operations, allgcrefs) # compute longevity of variables From noreply at buildbot.pypy.org Wed Feb 6 17:50:17 2013 From: noreply at buildbot.pypy.org (bivab) Date: Wed, 6 Feb 2013 17:50:17 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: add jitframe checks Message-ID: <20130206165017.D02341C101A@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: jitframe-on-heap Changeset: r60910:c76760a2e950 Date: 2013-02-06 17:40 +0100 http://bitbucket.org/pypy/pypy/changeset/c76760a2e950/ Log: add jitframe checks diff --git a/rpython/jit/backend/arm/assembler.py b/rpython/jit/backend/arm/assembler.py --- a/rpython/jit/backend/arm/assembler.py +++ b/rpython/jit/backend/arm/assembler.py @@ -96,6 +96,7 @@ self._build_failure_recovery(exc=False, withfloats=False) self._build_wb_slowpath(False) self._build_wb_slowpath(True) + self._build_stack_check_failure() if self.cpu.supports_floats: self._build_wb_slowpath(False, withfloats=True) self._build_wb_slowpath(True, withfloats=True) @@ -341,6 +342,7 @@ self.wb_slowpath[withcards + 2 * withfloats] = rawstart def _build_malloc_slowpath(self): + return # XXX fix me mc = ARMv7Builder() if self.cpu.supports_floats: vfp_regs = r.all_vfp_regs @@ -731,35 +733,30 @@ arglocs = self.rebuild_faillocs_from_descr(faildescr, inputargs) regalloc = Regalloc(assembler=self) + startpos = self.mc.get_relative_pos() operations = regalloc.prepare_bridge(inputargs, arglocs, operations, self.current_clt.allgcrefs, self.current_clt.frame_info) - #sp_patch_location = self._prepare_sp_patch_position() + stack_check_patch_ofs = self._check_frame_depth(self.mc, + regalloc.get_gcmap()) - startpos = self.mc.get_relative_pos() - - frame_depth = self._assemble(regalloc, inputargs, operations) + frame_depth_no_fixed_size = self._assemble(regalloc, inputargs, operations) codeendpos = self.mc.get_relative_pos() - #self._patch_sp_offset(sp_patch_location, frame_depth) - self.write_pending_failure_recoveries() rawstart = self.materialize_loop(original_loop_token) self.process_pending_guards(rawstart) - self.fixup_target_tokens(rawstart) # patch the jump from original guard self.patch_trace(faildescr, original_loop_token, rawstart, regalloc) if not we_are_translated(): - # for the benefit of tests - faildescr._arm_bridge_frame_depth = frame_depth if log: self.mc._dump_trace(rawstart, 'bridge.asm') @@ -798,6 +795,108 @@ input_i += 1 return locs + def check_frame_before_jump(self, target_token): + if target_token in self.target_tokens_currently_compiling: + return + if target_token._arm_clt is self.current_clt: + return + # We can have a frame coming from god knows where that's + # passed to a jump to another loop. Make sure it has the + # correct depth + expected_size = target_token._arm_clt.frame_info.jfi_frame_depth + self._check_frame_depth(self.mc, self._regalloc.get_gcmap(), + expected_size=expected_size) + + + def _check_frame_depth(self, mc, gcmap, expected_size=-1): + """ check if the frame is of enough depth to follow this bridge. + Otherwise reallocate the frame in a helper. + There are other potential solutions + to that, but this one does not sound too bad. + """ + descrs = self.cpu.gc_ll_descr.getframedescrs(self.cpu) + ofs = self.cpu.unpack_fielddescr(descrs.arraydescr.lendescr) + base_ofs = self.cpu.get_baseofs_of_frame_field() + mc.gen_load_int(r.ip.value, ofs) + mc.SUB_ri(r.ip.value, r.ip.value, base_ofs) + stack_check_cmp_ofs = mc.currpos() + if expected_size == -1: + mc.gen_load_int(r.lr.value, 0xffffff) + else: + mc.gen_load_int(r.lr.value, expected_size) + mc.CMP_rr(r.ip.value, r.lr.value) + + jg_location = mc.currpos() + mc.BKPT() + + self.push_gcmap(mc, gcmap, push=True) + + # the size value is still stored in lr + mc.PUSH([r.lr.value]) + + self.mc.BL(self._stack_check_failure) + + # patch jg_location above + currpos = self.mc.currpos() + pmc = OverwritingBuilder(mc, jg_location, WORD) + pmc.B_offs(currpos, c.GE) + + return stack_check_cmp_ofs + + def _build_stack_check_failure(self): + # this code should do the following steps + # a) store all registers in the jitframe + # b) fish for the arguments passed by the caller + # c) store the gcmap in the jitframe + # d) call realloc_frame + # e) set the fp to point to the new jitframe + # f) store the address of the new jitframe in the shadowstack + # c) set the gcmap field to 0 in the new jitframe + # g) restore registers and return + mc = ARMv7Builder() + self._push_all_regs_to_jitframe(mc, [], self.cpu.supports_floats) + # this is the gcmap stored by push_gcmap(mov=True) in _check_stack_frame + # and the expected_size pushed in _check_stack_frame + # pop the values passed on the stack, gcmap -> r0, expected_size -> r1 + mc.POP([r.r0.value, r.r1.value]) + # store return address and keep the stack aligned + mc.PUSH([r.ip.value, r.lr.value]) + + # store the current gcmap(r1) in the jitframe + gcmap_ofs = self.cpu.get_ofs_of_frame_field('jf_gcmap') + assert check_imm_arg(abs(gcmap_ofs)) + mc.STR_ri(r.r1.value, r.fp.value, imm=gcmap_ofs) + + # set first arg, which is the old jitframe address + mc.MOV_rr(r.r0.value, r.fp.value) + # call realloc_frame, it takes two arguments + # arg0: the old jitframe + # arg1: the new size + mc.BL(self.cpu.realloc_frame) + # set fp to the new jitframe plus the baseofs + mc.ADD_ri(r.fp.value, r.r0.value) + + gcrootmap = self.cpu.gc_ll_descr.gcrootmap + if gcrootmap and gcrootmap.is_shadow_stack: + self._load_shadowstack_top(mc, r.r5, gcrootmap) + # store the new jitframe addr in the shadowstack + mc.STR_ri(r.r0.value, r.r5.value, imm=-WORD) + + # reset the jf_gcmap field in the jitframe + mc.gen_load_int(r.ip.value, 0) + mc.STR_ri(r.ip.value, r.fp.value, imm=gcmap_ofs) + + # restore registers + self._pop_all_regs_from_jitframe(mc, [], self.cpu.supports_floats) + mc.POP([r.ip.value, r.pc.value]) # return + self._stack_check_failure = mc.materialize(self.cpu.asmmemmgr, []) + + def _load_shadowstack_top(self, mc, reg, gcrootmap): + rst = gcrootmap.get_root_stack_top_addr() + self.mc.gen_load_int(reg.value, rst) + self.mc.gen_load_int(reg.value, reg.value) + return rst + def fixup_target_tokens(self, rawstart): for targettoken in self.target_tokens_currently_compiling: targettoken._arm_loop_code += rawstart diff --git a/rpython/jit/backend/arm/opassembler.py b/rpython/jit/backend/arm/opassembler.py --- a/rpython/jit/backend/arm/opassembler.py +++ b/rpython/jit/backend/arm/opassembler.py @@ -22,6 +22,7 @@ from rpython.jit.backend.arm.regalloc import TempInt, TempPtr from rpython.jit.backend.arm.locations import imm from rpython.jit.backend.llsupport import symbolic, jitframe +from rpython.jit.backend.llsupport.gcmap import allocate_gcmap from rpython.jit.backend.llsupport.descr import InteriorFieldDescr from rpython.jit.metainterp.history import (Box, AbstractFailDescr, INT, FLOAT, REF) @@ -234,7 +235,7 @@ self.mc.NOP() else: self.mc.BKPT() - gcmap = self.allocate_gcmap(arglocs[0].value) + gcmap = allocate_gcmap(self, arglocs[0].value, JITFRAME_FIXED_SIZE) self.pending_guards.append(GuardToken(gcmap, descr, failargs=op.getfailargs(), @@ -247,19 +248,6 @@ fcond=fcond)) return c.AL - def allocate_gcmap(self, frame_depth): - size = frame_depth + JITFRAME_FIXED_SIZE - malloc_size = (size // WORD // 8 + 1) + 1 - rawgcmap = self.datablockwrapper.malloc_aligned(WORD * malloc_size, - WORD) - # set the length field - rffi.cast(rffi.CArrayPtr(lltype.Signed), rawgcmap)[0] = malloc_size - 1 - gcmap = rffi.cast(lltype.Ptr(jitframe.GCMAP), rawgcmap) - # zero the area - for i in range(malloc_size - 1): - gcmap[i] = r_uint(0) - return gcmap - def _emit_guard_overflow(self, guard, failargs, fcond): if guard.getopnum() == rop.GUARD_OVERFLOW: fcond = self._emit_guard(guard, failargs, c.VS, save_exc=False) @@ -344,6 +332,7 @@ # stack locations both before and after the jump. # target_token = op.getdescr() + target = target_token._arm_loop_code assert isinstance(target_token, TargetToken) assert fcond == c.AL my_nbargs = self.current_clt._debug_nbargs @@ -352,9 +341,9 @@ self._insert_checks() if target_token in self.target_tokens_currently_compiling: - self.mc.B_offs(target_token._arm_loop_code, fcond) + self.mc.B_offs(target, fcond) else: - self.mc.B(target_token._arm_loop_code, fcond) + self.mc.B(target, fcond) return fcond def emit_op_finish(self, op, arglocs, regalloc, fcond): diff --git a/rpython/jit/backend/arm/regalloc.py b/rpython/jit/backend/arm/regalloc.py --- a/rpython/jit/backend/arm/regalloc.py +++ b/rpython/jit/backend/arm/regalloc.py @@ -1,5 +1,6 @@ from rpython.rtyper.annlowlevel import llhelper, cast_instance_to_gcref from rpython.rlib import rgc +from rpython.rlib.debug import debug_print, debug_start, debug_stop from rpython.jit.backend.llsupport.regalloc import FrameManager, \ RegisterManager, TempBox, compute_vars_longevity from rpython.jit.backend.arm import registers as r @@ -15,7 +16,7 @@ ) from rpython.jit.backend.arm.jump import remap_frame_layout_mixed from rpython.jit.backend.arm.arch import MY_COPY_OF_REGS -from rpython.jit.backend.arm.arch import WORD +from rpython.jit.backend.arm.arch import WORD, DOUBLE_WORD, JITFRAME_FIXED_SIZE from rpython.jit.codewriter import longlong from rpython.jit.metainterp.history import (Const, ConstInt, ConstFloat, ConstPtr, Box, BoxPtr, @@ -23,6 +24,7 @@ from rpython.jit.metainterp.history import JitCellToken, TargetToken from rpython.jit.metainterp.resoperation import rop from rpython.jit.backend.llsupport.descr import ArrayDescr +from rpython.jit.backend.llsupport.gcmap import allocate_gcmap from rpython.jit.backend.llsupport import symbolic from rpython.rtyper.lltypesystem import lltype, rffi, rstr, llmemory from rpython.rtyper.lltypesystem.lloperation import llop @@ -351,6 +353,30 @@ # is also used on op args, which is a non-resizable list self.possibly_free_vars(list(inputargs)) + def get_gcmap(self, forbidden_regs=[], noregs=False): + frame_depth = self.fm.get_frame_depth() + gcmap = allocate_gcmap(self.assembler, + frame_depth, JITFRAME_FIXED_SIZE) + debug_start("jit-backend-gcmap") + for box, loc in self.rm.reg_bindings.iteritems(): + if loc in forbidden_regs: + continue + if box.type == REF: + assert not noregs + assert isinstance(loc, RegLoc) + val = gpr_reg_mgr_cls.all_reg_indexes[loc.value] + gcmap[val // WORD // 8] |= r_uint(1) << (val % (WORD * 8)) + for box, loc in self.fm.bindings.iteritems(): + if box.type == REF: + assert isinstance(loc, StackLoc) + val = loc.value // WORD + gcmap[val // WORD // 8] |= r_uint(1) << (val % (WORD * 8)) + for i in range(len(gcmap)): + debug_print(str(gcmap[i])) + debug_stop('jit-backend-gcmap') + return gcmap + + # ------------------------------------------------------------ def perform_llong(self, op, args, fcond): return self.assembler.regalloc_emit_llong(op, args, fcond, self) @@ -768,6 +794,7 @@ else: src_locations2.append(src_loc) dst_locations2.append(dst_loc) + self.assembler.check_frame_before_jump(self.jump_target_descr) remap_frame_layout_mixed(self.assembler, src_locations1, dst_locations1, tmploc, src_locations2, dst_locations2, vfptmploc) From noreply at buildbot.pypy.org Wed Feb 6 19:53:46 2013 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 6 Feb 2013 19:53:46 +0100 (CET) Subject: [pypy-commit] pypy default: update docs to mention new dir layout Message-ID: <20130206185346.DC47C1C3BF7@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r60911:d52661180965 Date: 2013-02-06 20:53 +0200 http://bitbucket.org/pypy/pypy/changeset/d52661180965/ Log: update docs to mention new dir layout diff --git a/pypy/doc/arm.rst b/pypy/doc/arm.rst --- a/pypy/doc/arm.rst +++ b/pypy/doc/arm.rst @@ -145,7 +145,7 @@ :: - pypy ~/path_to_pypy_checkout/pypy/translator/goal/translate.py -O1 --platform=arm target.py + pypy ~/path_to_pypy_checkout/rpython/translator/goal/translate.py -O1 --platform=arm target.py If everything worked correctly this should yield an ARM binary. Running this binary in the ARM chroot or on an ARM device should produce the output ``"Hello World"``. diff --git a/pypy/doc/cppyy.rst b/pypy/doc/cppyy.rst --- a/pypy/doc/cppyy.rst +++ b/pypy/doc/cppyy.rst @@ -86,10 +86,10 @@ $ hg clone https://bitbucket.org/pypy/pypy $ cd pypy $ hg up reflex-support # optional - $ cd pypy/translator/goal + $ cd pypy/goal # This example shows python, but using pypy-c is faster and uses less memory - $ python translate.py -O jit --gcrootfinder=shadowstack targetpypystandalone.py --withmod-cppyy + $ python ../../rpython/bin/rpython.py -O jit --gcrootfinder=shadowstack targetpypystandalone.py --withmod-cppyy This will build a ``pypy-c`` that includes the cppyy module, and through that, Reflex support. diff --git a/pypy/doc/ctypes-implementation.rst b/pypy/doc/ctypes-implementation.rst --- a/pypy/doc/ctypes-implementation.rst +++ b/pypy/doc/ctypes-implementation.rst @@ -113,7 +113,7 @@ The pypy-c translated to run the ctypes tests can be used to run the pyglet examples as well. They can be run like e.g.:: $ cd pyglet/ - $ PYTHONPATH=. ../ctypes-stable/pypy/translator/goal/pypy-c examples/opengl.py + $ PYTHONPATH=. ../ctypes-stable/pypy/goal/pypy-c examples/opengl.py they usually should be terminated with ctrl-c. Refer to the their doc strings for details about how they should behave. diff --git a/pypy/doc/getting-started-dev.rst b/pypy/doc/getting-started-dev.rst --- a/pypy/doc/getting-started-dev.rst +++ b/pypy/doc/getting-started-dev.rst @@ -24,7 +24,7 @@ python bin/translatorshell.py Test snippets of translatable code are provided in the file -``pypy/translator/test/snippet.py``, which is imported under the name +``rpython/translator/test/snippet.py``, which is imported under the name ``snippet``. For example:: >>> t = Translation(snippet.is_perfect_number, [int]) @@ -52,16 +52,18 @@ The graph can be turned into C code:: >>> t.rtype() - >>> f = t.compile_c() + >>> lib = t.compile_c() The first command replaces the operations with other low level versions that -only use low level types that are available in C (e.g. int). To try out the -compiled version:: +only use low level types that are available in C (e.g. int). The compiled +version is now in a ``.so`` library. You can run it say using ctypes: + >>> from ctypes import CDLL + >>> f = CDLL(lib) >>> f(5) - False + 0 >>> f(6) - True + 1 Translating the flow graph to CLI or JVM code +++++++++++++++++++++++++++++++++++++++++++++ @@ -108,7 +110,7 @@ There is a small-to-medium demo showing the translator and the annotator:: cd demo - ../pypy/translator/goal/translate.py --view --annotate bpnn.py + ../rpython/translator/goal/translate.py --view --annotate bpnn.py This causes ``bpnn.py`` to display itself as a call graph and class hierarchy. Clicking on functions shows the flow graph of the particular @@ -119,17 +121,17 @@ To turn this example to C code (compiled to the executable ``bpnn-c``), type simply:: - ../pypy/translator/goal/translate.py bpnn.py + ../rpython/translator/goal/translate.py bpnn.py Translating Full Programs +++++++++++++++++++++++++ To translate full RPython programs, there is the script ``translate.py`` in -``translator/goal``. Examples for this are a slightly changed version of +``rpython/translator/goal``. Examples for this are a slightly changed version of Pystone:: - cd pypy/translator/goal + cd rpython/translator/goal python translate.py targetrpystonedalone This will produce the executable "targetrpystonedalone-c". diff --git a/pypy/doc/index.rst b/pypy/doc/index.rst --- a/pypy/doc/index.rst +++ b/pypy/doc/index.rst @@ -220,9 +220,8 @@ ================================ =========================================== Directory explanation/links ================================ =========================================== -`pypy/annotation/`_ `type inferencing code`_ for `RPython`_ programs -`pypy/bin/`_ command-line scripts, mainly `py.py`_ and `translatorshell.py`_ +`pypy/bin/`_ command-line scripts, mainly `pyinteractive.py`_ `pypy/config/`_ handles the numerous options for building and running PyPy @@ -249,20 +248,8 @@ `pypy/objspace/`_ `object space`_ implementations -`pypy/objspace/flow/`_ the FlowObjSpace_ implementing `abstract interpretation`_ - `pypy/objspace/std/`_ the StdObjSpace_ implementing CPython's objects and types -`pypy/rlib/`_ a `"standard library"`_ for RPython_ programs - -`pypy/rpython/`_ the `RPython Typer`_ - -`pypy/rpython/lltypesystem/`_ the `low-level type system`_ for C-like backends - -`pypy/rpython/ootypesystem/`_ the `object-oriented type system`_ for OO backends - -`pypy/rpython/memory/`_ the `garbage collector`_ construction framework - `pypy/tool/`_ various utilities and hacks used from various places `pypy/tool/algo/`_ general-purpose algorithmic and mathematic @@ -270,20 +257,39 @@ `pypy/tool/pytest/`_ support code for our `testing methods`_ -`pypy/translator/`_ translation_ backends and support code -`pypy/translator/backendopt/`_ general optimizations that run before a backend generates code +`rpython/annotator/`_ `type inferencing code`_ for `RPython`_ programs -`pypy/translator/c/`_ the `GenC backend`_, producing C code from an +`rpython/config/`_ handles the numerous options for RPython + + +`rpython/flowspace/`_ the FlowObjSpace_ implementing `abstract interpretation`_ + + +`rpython/rlib/`_ a `"standard library"`_ for RPython_ programs + +`rpython/rtyper/`_ the `RPython Typer`_ + +`rpython/rtyper/lltypesystem/`_ the `low-level type system`_ for C-like backends + +`rpython/rtyper/ootypesystem/`_ the `object-oriented type system`_ for OO backends + +`rpython/rtyper/memory/`_ the `garbage collector`_ construction framework + +`rpython/translator/`_ translation_ backends and support code + +`rpython/translator/backendopt/`_ general optimizations that run before a backend generates code + +`rpython/translator/c/`_ the `GenC backend`_, producing C code from an RPython program (generally via the rtyper_) -`pypy/translator/cli/`_ the `CLI backend`_ for `.NET`_ (Microsoft CLR or Mono_) +`rpython/translator/cli/`_ the `CLI backend`_ for `.NET`_ (Microsoft CLR or Mono_) -`pypy/translator/goal/`_ our `main PyPy-translation scripts`_ live here +`pypy/goal/`_ our `main PyPy-translation scripts`_ live here -`pypy/translator/jvm/`_ the Java backend +`rpython/translator/jvm/`_ the Java backend -`pypy/translator/tool/`_ helper tools for translation, including the Pygame +`rpython/translator/tool/`_ helper tools for translation, including the Pygame `graph viewer`_ ``*/test/`` many directories have a test subdirectory containing test diff --git a/pypy/doc/sandbox.rst b/pypy/doc/sandbox.rst --- a/pypy/doc/sandbox.rst +++ b/pypy/doc/sandbox.rst @@ -87,15 +87,15 @@ ----- -In pypy/translator/goal:: +In pypy/goal:: - ./translate.py -O2 --sandbox targetpypystandalone.py + ../../rpython/bin/rpython -O2 --sandbox targetpypystandalone.py If you don't have a regular PyPy installed, you should, because it's faster to translate, but you can also run ``python translate.py`` instead. -To run it, use the tools in the pypy/translator/sandbox directory:: +To run it, use the tools in the pypy/sandbox directory:: ./pypy_interact.py /some/path/pypy-c-sandbox [args...] diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst --- a/pypy/doc/whatsnew-head.rst +++ b/pypy/doc/whatsnew-head.rst @@ -51,3 +51,6 @@ .. branch: inline-virtualref-2 Better optimized certain types of frame accesses in the JIT, particularly around exceptions that escape the function they were raised in. + +.. branch: missing-ndarray-attributes +Some missing attributes from ndarrays From noreply at buildbot.pypy.org Wed Feb 6 21:06:30 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Wed, 6 Feb 2013 21:06:30 +0100 (CET) Subject: [pypy-commit] pypy default: some cleanups for the missing-ndarray-attributes merge Message-ID: <20130206200630.875841C3BF9@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r60912:5fe3bb565c81 Date: 2013-02-06 15:05 -0500 http://bitbucket.org/pypy/pypy/changeset/5fe3bb565c81/ Log: some cleanups for the missing-ndarray-attributes merge diff --git a/pypy/tool/watchdog_nt.py b/pypy/tool/watchdog_nt.py deleted file mode 100644 --- a/pypy/tool/watchdog_nt.py +++ /dev/null @@ -1,33 +0,0 @@ -import sys, os -import threading -import ctypes - -def childkill(pid): - global timedout - timedout = True - sys.stderr.write("==== test running for %d seconds ====\n" % timeout) - sys.stderr.write("="*26 + "timedout" + "="*26 + "\n") - ctypes.windll.kernel32.TerminateProcess(pid, 1) - -if __name__ == '__main__': - PROCESS_TERMINATE = 0x1 - - timeout = float(sys.argv[1]) - timedout = False - - pid = os.spawnv(os.P_NOWAIT, sys.argv[2], sys.argv[2:]) - - t = threading.Timer(timeout, childkill, (pid,)) - t.start() - while True: - try: - pid, status = os.waitpid(pid, 0) - except KeyboardInterrupt: - continue - else: - t.cancel() - break - - #print 'status ', status >> 8 - sys.exit(status >> 8) - diff --git a/rpython/annotator/bookkeeper.py b/rpython/annotator/bookkeeper.py --- a/rpython/annotator/bookkeeper.py +++ b/rpython/annotator/bookkeeper.py @@ -447,9 +447,6 @@ if (x is type(None) or # add cases here if needed x.__module__ == 'rpython.rtyper.lltypesystem.lltype'): result = SomeType() - #elif x.__dict__.get('_mixin_', False): - # raise Exception("Creating a PBC of a mixin class is " - # "not RPython for class %r" % x) else: result = SomePBC([self.getdesc(x)]) elif callable(x): diff --git a/rpython/rlib/test/test_rarithmetic.py b/rpython/rlib/test/test_rarithmetic.py --- a/rpython/rlib/test/test_rarithmetic.py +++ b/rpython/rlib/test/test_rarithmetic.py @@ -1,5 +1,5 @@ from rpython.rtyper.test.tool import BaseRtypingTest, LLRtypeMixin, OORtypeMixin -from rpython.test.test_llinterp import interpret +from rpython.rtyper.test.test_llinterp import interpret from rpython.rlib.rarithmetic import * import sys import py From noreply at buildbot.pypy.org Wed Feb 6 21:52:43 2013 From: noreply at buildbot.pypy.org (mattip) Date: Wed, 6 Feb 2013 21:52:43 +0100 (CET) Subject: [pypy-commit] pypy win32-distutils: make setup.py work under win32 Message-ID: <20130206205243.BA5091C3BFC@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: win32-distutils Changeset: r60913:2f51f2142f7b Date: 2013-02-05 21:18 +0200 http://bitbucket.org/pypy/pypy/changeset/2f51f2142f7b/ Log: make setup.py work under win32 From noreply at buildbot.pypy.org Wed Feb 6 21:52:45 2013 From: noreply at buildbot.pypy.org (mattip) Date: Wed, 6 Feb 2013 21:52:45 +0100 (CET) Subject: [pypy-commit] pypy default: add test that goes through runicode.ord_accepts_surrogate Message-ID: <20130206205245.90EA91C3BFC@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: Changeset: r60914:f9b0d0e350a8 Date: 2013-02-06 22:51 +0200 http://bitbucket.org/pypy/pypy/changeset/f9b0d0e350a8/ Log: add test that goes through runicode.ord_accepts_surrogate diff --git a/pypy/module/unicodedata/test/test_unicodedata.py b/pypy/module/unicodedata/test/test_unicodedata.py --- a/pypy/module/unicodedata/test/test_unicodedata.py +++ b/pypy/module/unicodedata/test/test_unicodedata.py @@ -102,3 +102,7 @@ import unicodedata # For no reason, unicodedata.mirrored() returns an int, not a bool assert repr(unicodedata.mirrored(u' ')) == '0' + + def test_bidirectional(self): + import unicodedata + raises(ValueError, unicodedata.bidirectional, u'xx') From noreply at buildbot.pypy.org Wed Feb 6 21:58:02 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Wed, 6 Feb 2013 21:58:02 +0100 (CET) Subject: [pypy-commit] pypy default: this should be a TypeError Message-ID: <20130206205802.68FEE1C3BFC@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r60915:8f6d5b79802a Date: 2013-02-06 15:57 -0500 http://bitbucket.org/pypy/pypy/changeset/8f6d5b79802a/ Log: this should be a TypeError diff --git a/pypy/module/unicodedata/test/test_unicodedata.py b/pypy/module/unicodedata/test/test_unicodedata.py --- a/pypy/module/unicodedata/test/test_unicodedata.py +++ b/pypy/module/unicodedata/test/test_unicodedata.py @@ -105,4 +105,4 @@ def test_bidirectional(self): import unicodedata - raises(ValueError, unicodedata.bidirectional, u'xx') + raises(TypeError, unicodedata.bidirectional, u'xx') From noreply at buildbot.pypy.org Wed Feb 6 22:00:13 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Wed, 6 Feb 2013 22:00:13 +0100 (CET) Subject: [pypy-commit] pypy default: catch proper exception here Message-ID: <20130206210013.E47501C3BFC@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r60916:84dc0de034e8 Date: 2013-02-06 12:59 -0800 http://bitbucket.org/pypy/pypy/changeset/84dc0de034e8/ Log: catch proper exception here diff --git a/pypy/module/unicodedata/interp_ucd.py b/pypy/module/unicodedata/interp_ucd.py --- a/pypy/module/unicodedata/interp_ucd.py +++ b/pypy/module/unicodedata/interp_ucd.py @@ -40,7 +40,7 @@ # Host CPython is narrow build, accept surrogates try: return ord_accepts_surrogate(space.unicode_w(w_unichr)) - except ValueError: + except TypeError: raise OperationError(space.w_TypeError, space.wrap( 'need a single Unicode character as parameter')) else: From noreply at buildbot.pypy.org Wed Feb 6 22:04:49 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Wed, 6 Feb 2013 22:04:49 +0100 (CET) Subject: [pypy-commit] pypy default: here too Message-ID: <20130206210449.147D31C3BFD@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r60917:e12b860bab28 Date: 2013-02-06 16:04 -0500 http://bitbucket.org/pypy/pypy/changeset/e12b860bab28/ Log: here too diff --git a/pypy/module/unicodedata/interp_ucd.py b/pypy/module/unicodedata/interp_ucd.py --- a/pypy/module/unicodedata/interp_ucd.py +++ b/pypy/module/unicodedata/interp_ucd.py @@ -67,7 +67,7 @@ # Accept surrogates try: return ord_accepts_surrogate(space.unicode_w(w_unichr)) - except ValueError: + except TypeError: raise OperationError(space.w_TypeError, space.wrap( 'need a single Unicode character as parameter')) From noreply at buildbot.pypy.org Thu Feb 7 00:06:23 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Thu, 7 Feb 2013 00:06:23 +0100 (CET) Subject: [pypy-commit] pypy default: export a few more constants Message-ID: <20130206230623.1874B1C3BF9@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r60918:1721aeaf522f Date: 2013-02-06 18:05 -0500 http://bitbucket.org/pypy/pypy/changeset/1721aeaf522f/ Log: export a few more constants diff --git a/pypy/module/imp/__init__.py b/pypy/module/imp/__init__.py --- a/pypy/module/imp/__init__.py +++ b/pypy/module/imp/__init__.py @@ -6,12 +6,14 @@ __import__ function. """ interpleveldefs = { + 'SEARCH_ERROR': 'space.wrap(importing.SEARCH_ERROR)', 'PY_SOURCE': 'space.wrap(importing.PY_SOURCE)', 'PY_COMPILED': 'space.wrap(importing.PY_COMPILED)', 'C_EXTENSION': 'space.wrap(importing.C_EXTENSION)', 'PKG_DIRECTORY': 'space.wrap(importing.PKG_DIRECTORY)', 'C_BUILTIN': 'space.wrap(importing.C_BUILTIN)', 'PY_FROZEN': 'space.wrap(importing.PY_FROZEN)', + 'IMP_HOOK': 'space.wrap(importing.IMP_HOOK)', 'get_suffixes': 'interp_imp.get_suffixes', 'get_magic': 'interp_imp.get_magic', From noreply at buildbot.pypy.org Thu Feb 7 00:33:06 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Thu, 7 Feb 2013 00:33:06 +0100 (CET) Subject: [pypy-commit] pypy py3k: IOError -> UnsupportedOperation Message-ID: <20130206233306.3E3051C3BF8@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r60919:f8a6a39cdb36 Date: 2013-02-06 15:29 -0800 http://bitbucket.org/pypy/pypy/changeset/f8a6a39cdb36/ Log: IOError -> UnsupportedOperation diff --git a/pypy/module/_io/interp_textio.py b/pypy/module/_io/interp_textio.py --- a/pypy/module/_io/interp_textio.py +++ b/pypy/module/_io/interp_textio.py @@ -809,8 +809,7 @@ self._check_closed(space) if not self.seekable: - raise OperationError(space.w_IOError, space.wrap( - "underlying stream is not seekable")) + self._unsupportedoperation("underlying stream is not seekable") if whence == 1: # seek relative to current position @@ -888,8 +887,7 @@ self._check_closed(space) if not self.seekable: - raise OperationError(space.w_IOError, space.wrap( - "underlying stream is not seekable")) + self._unsupportedoperation("underlying stream is not seekable") if not self.telling: raise OperationError(space.w_IOError, space.wrap( diff --git a/pypy/module/_io/test/test_bufferedio.py b/pypy/module/_io/test/test_bufferedio.py --- a/pypy/module/_io/test/test_bufferedio.py +++ b/pypy/module/_io/test/test_bufferedio.py @@ -214,6 +214,19 @@ assert r == b"abca" assert rawio.count == 4 + def test_unseekable(self): + import _io + class Unseekable(_io.BytesIO): + def seekable(self): + return False + def seek(self, *args): + raise _io.UnsupportedOperation("not seekable") + def tell(self, *args): + raise _io.UnsupportedOperation("not seekable") + bufio = _io.BufferedReader(Unseekable()) + raises(_io.UnsupportedOperation, bufio.tell) + raises(_io.UnsupportedOperation, bufio.seek, 0) + class AppTestBufferedReaderWithThreads(AppTestBufferedReader): spaceconfig = dict(usemodules=['_io', 'thread']) diff --git a/pypy/module/_io/test/test_textio.py b/pypy/module/_io/test/test_textio.py --- a/pypy/module/_io/test/test_textio.py +++ b/pypy/module/_io/test/test_textio.py @@ -42,6 +42,15 @@ txt = _io.TextIOWrapper(UnReadable()) raises(IOError, txt.read) + def test_unseekable(self): + import _io + class Unseekable(_io.BytesIO): + def seekable(self): + return False + txt = _io.TextIOWrapper(Unseekable()) + raises(_io.UnsupportedOperation, txt.tell) + raises(_io.UnsupportedOperation, txt.seek, 0) + def test_detach(self): import _io b = _io.BytesIO() From noreply at buildbot.pypy.org Thu Feb 7 00:33:07 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Thu, 7 Feb 2013 00:33:07 +0100 (CET) Subject: [pypy-commit] pypy py3k: forbid pickling of _io objects Message-ID: <20130206233307.C5FBF1C3BF8@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r60920:1370dfe72906 Date: 2013-02-06 15:31 -0800 http://bitbucket.org/pypy/pypy/changeset/1370dfe72906/ Log: forbid pickling of _io objects diff --git a/pypy/module/_io/interp_bufferedio.py b/pypy/module/_io/interp_bufferedio.py --- a/pypy/module/_io/interp_bufferedio.py +++ b/pypy/module/_io/interp_bufferedio.py @@ -796,6 +796,7 @@ 'BufferedReader', W_BufferedIOBase.typedef, __new__ = generic_new_descr(W_BufferedReader), __init__ = interp2app(W_BufferedReader.descr_init), + __getstate__ = interp2app(W_BufferedReader.getstate_w), __module__ = "_io", read = interp2app(W_BufferedReader.read_w), @@ -843,6 +844,7 @@ 'BufferedWriter', W_BufferedIOBase.typedef, __new__ = generic_new_descr(W_BufferedWriter), __init__ = interp2app(W_BufferedWriter.descr_init), + __getstate__ = interp2app(W_BufferedWriter.getstate_w), __module__ = "_io", write = interp2app(W_BufferedWriter.write_w), @@ -939,6 +941,7 @@ '_io.BufferedRWPair', W_BufferedIOBase.typedef, __new__ = generic_new_descr(W_BufferedRWPair), __init__ = interp2app(W_BufferedRWPair.descr_init), + __getstate__ = interp2app(W_BufferedRWPair.getstate_w), closed = GetSetProperty(W_BufferedRWPair.closed_get_w), **methods ) @@ -969,6 +972,7 @@ 'BufferedRandom', W_BufferedIOBase.typedef, __new__ = generic_new_descr(W_BufferedRandom), __init__ = interp2app(W_BufferedRandom.descr_init), + __getstate__ = interp2app(W_BufferedRandom.getstate_w), __module__ = "_io", read = interp2app(W_BufferedRandom.read_w), diff --git a/pypy/module/_io/interp_fileio.py b/pypy/module/_io/interp_fileio.py --- a/pypy/module/_io/interp_fileio.py +++ b/pypy/module/_io/interp_fileio.py @@ -438,6 +438,7 @@ __new__ = interp2app(W_FileIO.descr_new.im_func), __init__ = interp2app(W_FileIO.descr_init), __repr__ = interp2app(W_FileIO.repr_w), + __getstate__ = interp2app(W_FileIO.getstate_w), seek = interp2app(W_FileIO.seek_w), tell = interp2app(W_FileIO.tell_w), diff --git a/pypy/module/_io/interp_iobase.py b/pypy/module/_io/interp_iobase.py --- a/pypy/module/_io/interp_iobase.py +++ b/pypy/module/_io/interp_iobase.py @@ -164,6 +164,11 @@ def seekable_w(self, space): return space.w_False + def getstate_w(self, space): + raise operationerrfmt(space.w_TypeError, + "cannot serialize '%s' object", + space.type(self).getname(space)) + # ______________________________________________________________ def readline_w(self, space, w_limit=None): diff --git a/pypy/module/_io/interp_textio.py b/pypy/module/_io/interp_textio.py --- a/pypy/module/_io/interp_textio.py +++ b/pypy/module/_io/interp_textio.py @@ -989,9 +989,10 @@ __new__ = generic_new_descr(W_TextIOWrapper), __init__ = interp2app(W_TextIOWrapper.descr_init), __repr__ = interp2app(W_TextIOWrapper.descr_repr), + __next__ = interp2app(W_TextIOWrapper.next_w), + __getstate__ = interp2app(W_TextIOWrapper.getstate_w), __module__ = "_io", - __next__ = interp2app(W_TextIOWrapper.next_w), read = interp2app(W_TextIOWrapper.read_w), readline = interp2app(W_TextIOWrapper.readline_w), write = interp2app(W_TextIOWrapper.write_w), diff --git a/pypy/module/_io/test/test_io.py b/pypy/module/_io/test/test_io.py --- a/pypy/module/_io/test/test_io.py +++ b/pypy/module/_io/test/test_io.py @@ -351,3 +351,22 @@ self._check_warn_on_dealloc(self.tmpfile, 'wb', buffering=0) self._check_warn_on_dealloc(self.tmpfile, 'wb') self._check_warn_on_dealloc(self.tmpfile, 'w') + + def test_pickling(self): + import _io + import pickle + # Pickling file objects is forbidden + for kwargs in [ + {"mode": "w"}, + {"mode": "wb"}, + {"mode": "wb", "buffering": 0}, + {"mode": "r"}, + {"mode": "rb"}, + {"mode": "rb", "buffering": 0}, + {"mode": "w+"}, + {"mode": "w+b"}, + {"mode": "w+b", "buffering": 0}, + ]: + for protocol in range(pickle.HIGHEST_PROTOCOL + 1): + with _io.open(self.tmpfile, **kwargs) as f: + raises(TypeError, pickle.dumps, f, protocol) From noreply at buildbot.pypy.org Thu Feb 7 04:44:05 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Thu, 7 Feb 2013 04:44:05 +0100 (CET) Subject: [pypy-commit] pypy default: don't use closerange in os.popen (cpython doesn't), add test Message-ID: <20130207034405.794FE1C3BF9@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r60921:3863e3e7c3e2 Date: 2013-02-06 21:52 -0500 http://bitbucket.org/pypy/pypy/changeset/3863e3e7c3e2/ Log: don't use closerange in os.popen (cpython doesn't), add test diff --git a/pypy/module/posix/app_posix.py b/pypy/module/posix/app_posix.py --- a/pypy/module/posix/app_posix.py +++ b/pypy/module/posix/app_posix.py @@ -140,8 +140,8 @@ Open a pipe to/from a command returning a file object.""" - from subprocess import MAXFD - import os, gc + import os + import gc def try_close(fd): try: @@ -165,7 +165,6 @@ else: os.dup2(read_end, 0) os.close(write_end) - os.closerange(3, MAXFD) cmd = ['/bin/sh', '-c', command] os.execvp(cmd[0], cmd) finally: diff --git a/pypy/module/posix/test/test_posix2.py b/pypy/module/posix/test/test_posix2.py --- a/pypy/module/posix/test/test_posix2.py +++ b/pypy/module/posix/test/test_posix2.py @@ -14,7 +14,7 @@ import signal def setup_module(mod): - usemodules = ['binascii', 'posix', 'struct', 'rctime', 'signal', 'select'] + usemodules = ['binascii', 'posix', 'struct', 'rctime'] if os.name != 'nt': usemodules += ['fcntl'] else: @@ -513,6 +513,14 @@ res = fp.read() assert res == '1\n' + def test_popen_child_fds(self): + os = self.posix + from os.path import join + with open(join(self.pdir, 'file1'), 'r') as fd: + with os.popen('%s -c "import os; print os.read(%d, 10)"' % (self.python, fd.fileno())) as stream: + res = stream.read() + assert res == 'test1\n' + if hasattr(__import__(os.name), '_getfullpathname'): def test__getfullpathname(self): # nt specific From noreply at buildbot.pypy.org Thu Feb 7 06:30:53 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Thu, 7 Feb 2013 06:30:53 +0100 (CET) Subject: [pypy-commit] pypy default: silence some compilation signedness warnings Message-ID: <20130207053053.8859B1C3BF7@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r60922:b31ca122767b Date: 2013-02-07 00:17 -0500 http://bitbucket.org/pypy/pypy/changeset/b31ca122767b/ Log: silence some compilation signedness warnings diff --git a/rpython/translator/c/src/cjkcodecs/multibytecodec.c b/rpython/translator/c/src/cjkcodecs/multibytecodec.c --- a/rpython/translator/c/src/cjkcodecs/multibytecodec.c +++ b/rpython/translator/c/src/cjkcodecs/multibytecodec.c @@ -21,9 +21,9 @@ Py_ssize_t pypy_cjk_dec_init(struct pypy_cjk_dec_s *d, char *inbuf, Py_ssize_t inlen) { - d->inbuf_start = inbuf; - d->inbuf = inbuf; - d->inbuf_end = inbuf + inlen; + d->inbuf_start = (unsigned char *)inbuf; + d->inbuf = (unsigned char *)inbuf; + d->inbuf_end = (unsigned char *)inbuf + inlen; if (d->outbuf_start == NULL) { d->outbuf_start = (inlen <= (PY_SSIZE_T_MAX / sizeof(Py_UNICODE)) ? @@ -219,7 +219,7 @@ char *pypy_cjk_enc_outbuf(struct pypy_cjk_enc_s *d) { - return d->outbuf_start; + return (char *)d->outbuf_start; } Py_ssize_t pypy_cjk_enc_outlen(struct pypy_cjk_enc_s *d) From noreply at buildbot.pypy.org Thu Feb 7 08:27:53 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Thu, 7 Feb 2013 08:27:53 +0100 (CET) Subject: [pypy-commit] pypy default: wrestle more with unicode Message-ID: <20130207072753.EA71E1C087A@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r60923:2c191315b989 Date: 2013-02-06 23:27 -0800 http://bitbucket.org/pypy/pypy/changeset/2c191315b989/ Log: wrestle more with unicode diff --git a/rpython/rlib/runicode.py b/rpython/rlib/runicode.py --- a/rpython/rlib/runicode.py +++ b/rpython/rlib/runicode.py @@ -31,7 +31,12 @@ ch2 = ord(u[1]) if 0xD800 <= ch1 <= 0xDBFF and 0xDC00 <= ch2 <= 0xDFFF: return (((ch1 - 0xD800) << 10) | (ch2 - 0xDC00)) + 0x10000 - return ord(u) + if not we_are_translated(): + return ord(u) + else: + if len(u) == 1: + return ord(u[0]) + raise TypeError if MAXUNICODE > sys.maxunicode: # A version of unichr which allows codes outside the BMP diff --git a/rpython/rlib/test/test_runicode.py b/rpython/rlib/test/test_runicode.py --- a/rpython/rlib/test/test_runicode.py +++ b/rpython/rlib/test/test_runicode.py @@ -16,6 +16,8 @@ py.test.raises(TypeError, runicode.UNICHR, 'abc') def test_ord(): + assert runicode.ORD('a') == 97 + assert runicode.ORD(u'a') == 97 assert runicode.ORD(u'\uffff') == 0xffff if runicode.MAXUNICODE > 0xffff: if sys.maxunicode < 0x10000: From noreply at buildbot.pypy.org Thu Feb 7 09:06:54 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Thu, 7 Feb 2013 09:06:54 +0100 (CET) Subject: [pypy-commit] pypy default: fix unichr_returns_surrogate when both host and target are narrow Message-ID: <20130207080654.2AABD1C087A@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r60924:78a4037ea447 Date: 2013-02-07 03:06 -0500 http://bitbucket.org/pypy/pypy/changeset/78a4037ea447/ Log: fix unichr_returns_surrogate when both host and target are narrow diff --git a/rpython/rlib/runicode.py b/rpython/rlib/runicode.py --- a/rpython/rlib/runicode.py +++ b/rpython/rlib/runicode.py @@ -18,7 +18,7 @@ # or in unicodedata in pypy def unichr_returns_surrogate(c): - if c <= sys.maxunicode or c > MAXUNICODE: + if c <= 0xffff or c > 0x10ffff: return unichr(c) else: c -= 0x10000 From noreply at buildbot.pypy.org Thu Feb 7 09:30:22 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Thu, 7 Feb 2013 09:30:22 +0100 (CET) Subject: [pypy-commit] pypy default: fix collection of test_lib_pypy tests when runappdirect is set Message-ID: <20130207083022.E0DF01C087A@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r60925:10d502e8cb87 Date: 2013-01-31 16:53 -0500 http://bitbucket.org/pypy/pypy/changeset/10d502e8cb87/ Log: fix collection of test_lib_pypy tests when runappdirect is set (transplanted from 5acfa3319a452ba70b7b04a21525e4d66aa242a9) diff --git a/pypy/conftest.py b/pypy/conftest.py --- a/pypy/conftest.py +++ b/pypy/conftest.py @@ -84,10 +84,11 @@ if self.config.option.runappdirect: # only collect regular tests if we are in an 'app_test' directory, # or in test_lib_pypy - names = self.listnames() - return "app_test" in names or "test_lib_pypy" in names - else: - return True + for name in self.listnames(): + if "app_test" in name or "test_lib_pypy" in name: + return True + return False + return True def funcnamefilter(self, name): if name.startswith('test_'): From noreply at buildbot.pypy.org Thu Feb 7 09:30:24 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Thu, 7 Feb 2013 09:30:24 +0100 (CET) Subject: [pypy-commit] pypy default: this should always import lib_pypy's sqlite3, never the host's Message-ID: <20130207083024.30B431C087A@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r60926:b6d2a9b0bcc0 Date: 2013-02-05 17:45 -0500 http://bitbucket.org/pypy/pypy/changeset/b6d2a9b0bcc0/ Log: this should always import lib_pypy's sqlite3, never the host's (transplanted from 9e7230d8f10c39195ff46b9950be20e7d026f320) diff --git a/pypy/module/test_lib_pypy/test_sqlite3.py b/pypy/module/test_lib_pypy/test_sqlite3.py --- a/pypy/module/test_lib_pypy/test_sqlite3.py +++ b/pypy/module/test_lib_pypy/test_sqlite3.py @@ -2,7 +2,7 @@ def test_list_ddl(): """From issue996. Mostly just looking for lack of exceptions.""" - from sqlite3.dbapi2 import connect + from lib_pypy._sqlite3 import connect connection = connect(':memory:') cursor = connection.cursor() cursor.execute('CREATE TABLE foo (bar INTEGER)') From noreply at buildbot.pypy.org Thu Feb 7 09:30:27 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Thu, 7 Feb 2013 09:30:27 +0100 (CET) Subject: [pypy-commit] pypy cleanup-tests: merge default Message-ID: <20130207083027.2B59F1C087A@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: cleanup-tests Changeset: r60927:3ea32708db7b Date: 2013-02-07 03:29 -0500 http://bitbucket.org/pypy/pypy/changeset/3ea32708db7b/ Log: merge default diff too long, truncating to 2000 out of 4587 lines diff --git a/lib-python/2.7/test/test_modulefinder.py b/lib-python/2.7/test/test_modulefinder.py --- a/lib-python/2.7/test/test_modulefinder.py +++ b/lib-python/2.7/test/test_modulefinder.py @@ -16,7 +16,7 @@ # library. TEST_DIR = tempfile.mkdtemp() -TEST_PATH = [TEST_DIR, os.path.dirname(__future__.__file__)] +TEST_PATH = [TEST_DIR, os.path.dirname(tempfile.__file__)] # Each test description is a list of 5 items: # diff --git a/lib_pypy/ctypes_support.py b/lib_pypy/ctypes_support.py --- a/lib_pypy/ctypes_support.py +++ b/lib_pypy/ctypes_support.py @@ -19,16 +19,19 @@ if sys.platform == 'win32': standard_c_lib._errno.restype = ctypes.POINTER(ctypes.c_int) + standard_c_lib._errno.argtypes = None def _where_is_errno(): return standard_c_lib._errno() elif sys.platform in ('linux2', 'freebsd6'): standard_c_lib.__errno_location.restype = ctypes.POINTER(ctypes.c_int) + standard_c_lib.__errno_location.argtypes = None def _where_is_errno(): return standard_c_lib.__errno_location() elif sys.platform in ('darwin', 'freebsd7', 'freebsd8', 'freebsd9'): standard_c_lib.__error.restype = ctypes.POINTER(ctypes.c_int) + standard_c_lib.__error.argtypes = None def _where_is_errno(): return standard_c_lib.__error() diff --git a/pypy/doc/arm.rst b/pypy/doc/arm.rst --- a/pypy/doc/arm.rst +++ b/pypy/doc/arm.rst @@ -145,7 +145,7 @@ :: - pypy ~/path_to_pypy_checkout/pypy/translator/goal/translate.py -O1 --platform=arm target.py + pypy ~/path_to_pypy_checkout/rpython/translator/goal/translate.py -O1 --platform=arm target.py If everything worked correctly this should yield an ARM binary. Running this binary in the ARM chroot or on an ARM device should produce the output ``"Hello World"``. diff --git a/pypy/doc/cppyy.rst b/pypy/doc/cppyy.rst --- a/pypy/doc/cppyy.rst +++ b/pypy/doc/cppyy.rst @@ -86,10 +86,10 @@ $ hg clone https://bitbucket.org/pypy/pypy $ cd pypy $ hg up reflex-support # optional - $ cd pypy/translator/goal + $ cd pypy/goal # This example shows python, but using pypy-c is faster and uses less memory - $ python translate.py -O jit --gcrootfinder=shadowstack targetpypystandalone.py --withmod-cppyy + $ python ../../rpython/bin/rpython.py -O jit --gcrootfinder=shadowstack targetpypystandalone.py --withmod-cppyy This will build a ``pypy-c`` that includes the cppyy module, and through that, Reflex support. diff --git a/pypy/doc/ctypes-implementation.rst b/pypy/doc/ctypes-implementation.rst --- a/pypy/doc/ctypes-implementation.rst +++ b/pypy/doc/ctypes-implementation.rst @@ -113,7 +113,7 @@ The pypy-c translated to run the ctypes tests can be used to run the pyglet examples as well. They can be run like e.g.:: $ cd pyglet/ - $ PYTHONPATH=. ../ctypes-stable/pypy/translator/goal/pypy-c examples/opengl.py + $ PYTHONPATH=. ../ctypes-stable/pypy/goal/pypy-c examples/opengl.py they usually should be terminated with ctrl-c. Refer to the their doc strings for details about how they should behave. diff --git a/pypy/doc/getting-started-dev.rst b/pypy/doc/getting-started-dev.rst --- a/pypy/doc/getting-started-dev.rst +++ b/pypy/doc/getting-started-dev.rst @@ -24,7 +24,7 @@ python bin/translatorshell.py Test snippets of translatable code are provided in the file -``pypy/translator/test/snippet.py``, which is imported under the name +``rpython/translator/test/snippet.py``, which is imported under the name ``snippet``. For example:: >>> t = Translation(snippet.is_perfect_number, [int]) @@ -52,16 +52,18 @@ The graph can be turned into C code:: >>> t.rtype() - >>> f = t.compile_c() + >>> lib = t.compile_c() The first command replaces the operations with other low level versions that -only use low level types that are available in C (e.g. int). To try out the -compiled version:: +only use low level types that are available in C (e.g. int). The compiled +version is now in a ``.so`` library. You can run it say using ctypes: + >>> from ctypes import CDLL + >>> f = CDLL(lib) >>> f(5) - False + 0 >>> f(6) - True + 1 Translating the flow graph to CLI or JVM code +++++++++++++++++++++++++++++++++++++++++++++ @@ -108,7 +110,7 @@ There is a small-to-medium demo showing the translator and the annotator:: cd demo - ../pypy/translator/goal/translate.py --view --annotate bpnn.py + ../rpython/translator/goal/translate.py --view --annotate bpnn.py This causes ``bpnn.py`` to display itself as a call graph and class hierarchy. Clicking on functions shows the flow graph of the particular @@ -119,17 +121,17 @@ To turn this example to C code (compiled to the executable ``bpnn-c``), type simply:: - ../pypy/translator/goal/translate.py bpnn.py + ../rpython/translator/goal/translate.py bpnn.py Translating Full Programs +++++++++++++++++++++++++ To translate full RPython programs, there is the script ``translate.py`` in -``translator/goal``. Examples for this are a slightly changed version of +``rpython/translator/goal``. Examples for this are a slightly changed version of Pystone:: - cd pypy/translator/goal + cd rpython/translator/goal python translate.py targetrpystonedalone This will produce the executable "targetrpystonedalone-c". diff --git a/pypy/doc/index.rst b/pypy/doc/index.rst --- a/pypy/doc/index.rst +++ b/pypy/doc/index.rst @@ -220,9 +220,8 @@ ================================ =========================================== Directory explanation/links ================================ =========================================== -`pypy/annotation/`_ `type inferencing code`_ for `RPython`_ programs -`pypy/bin/`_ command-line scripts, mainly `py.py`_ and `translatorshell.py`_ +`pypy/bin/`_ command-line scripts, mainly `pyinteractive.py`_ `pypy/config/`_ handles the numerous options for building and running PyPy @@ -249,20 +248,8 @@ `pypy/objspace/`_ `object space`_ implementations -`pypy/objspace/flow/`_ the FlowObjSpace_ implementing `abstract interpretation`_ - `pypy/objspace/std/`_ the StdObjSpace_ implementing CPython's objects and types -`pypy/rlib/`_ a `"standard library"`_ for RPython_ programs - -`pypy/rpython/`_ the `RPython Typer`_ - -`pypy/rpython/lltypesystem/`_ the `low-level type system`_ for C-like backends - -`pypy/rpython/ootypesystem/`_ the `object-oriented type system`_ for OO backends - -`pypy/rpython/memory/`_ the `garbage collector`_ construction framework - `pypy/tool/`_ various utilities and hacks used from various places `pypy/tool/algo/`_ general-purpose algorithmic and mathematic @@ -270,20 +257,39 @@ `pypy/tool/pytest/`_ support code for our `testing methods`_ -`pypy/translator/`_ translation_ backends and support code -`pypy/translator/backendopt/`_ general optimizations that run before a backend generates code +`rpython/annotator/`_ `type inferencing code`_ for `RPython`_ programs -`pypy/translator/c/`_ the `GenC backend`_, producing C code from an +`rpython/config/`_ handles the numerous options for RPython + + +`rpython/flowspace/`_ the FlowObjSpace_ implementing `abstract interpretation`_ + + +`rpython/rlib/`_ a `"standard library"`_ for RPython_ programs + +`rpython/rtyper/`_ the `RPython Typer`_ + +`rpython/rtyper/lltypesystem/`_ the `low-level type system`_ for C-like backends + +`rpython/rtyper/ootypesystem/`_ the `object-oriented type system`_ for OO backends + +`rpython/rtyper/memory/`_ the `garbage collector`_ construction framework + +`rpython/translator/`_ translation_ backends and support code + +`rpython/translator/backendopt/`_ general optimizations that run before a backend generates code + +`rpython/translator/c/`_ the `GenC backend`_, producing C code from an RPython program (generally via the rtyper_) -`pypy/translator/cli/`_ the `CLI backend`_ for `.NET`_ (Microsoft CLR or Mono_) +`rpython/translator/cli/`_ the `CLI backend`_ for `.NET`_ (Microsoft CLR or Mono_) -`pypy/translator/goal/`_ our `main PyPy-translation scripts`_ live here +`pypy/goal/`_ our `main PyPy-translation scripts`_ live here -`pypy/translator/jvm/`_ the Java backend +`rpython/translator/jvm/`_ the Java backend -`pypy/translator/tool/`_ helper tools for translation, including the Pygame +`rpython/translator/tool/`_ helper tools for translation, including the Pygame `graph viewer`_ ``*/test/`` many directories have a test subdirectory containing test diff --git a/pypy/doc/sandbox.rst b/pypy/doc/sandbox.rst --- a/pypy/doc/sandbox.rst +++ b/pypy/doc/sandbox.rst @@ -87,15 +87,15 @@ ----- -In pypy/translator/goal:: +In pypy/goal:: - ./translate.py -O2 --sandbox targetpypystandalone.py + ../../rpython/bin/rpython -O2 --sandbox targetpypystandalone.py If you don't have a regular PyPy installed, you should, because it's faster to translate, but you can also run ``python translate.py`` instead. -To run it, use the tools in the pypy/translator/sandbox directory:: +To run it, use the tools in the pypy/sandbox directory:: ./pypy_interact.py /some/path/pypy-c-sandbox [args...] diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst --- a/pypy/doc/whatsnew-head.rst +++ b/pypy/doc/whatsnew-head.rst @@ -37,6 +37,7 @@ .. branch: fix-e4fa0b2 .. branch: win32-fixes .. branch: fix-version-tool +.. branch: popen2-removal .. branch: release-2.0-beta1 @@ -50,3 +51,6 @@ .. branch: inline-virtualref-2 Better optimized certain types of frame accesses in the JIT, particularly around exceptions that escape the function they were raised in. + +.. branch: missing-ndarray-attributes +Some missing attributes from ndarrays diff --git a/pypy/module/bz2/test/test_bz2_compdecomp.py b/pypy/module/bz2/test/test_bz2_compdecomp.py --- a/pypy/module/bz2/test/test_bz2_compdecomp.py +++ b/pypy/module/bz2/test/test_bz2_compdecomp.py @@ -12,7 +12,7 @@ if os.name == "nt": from py.test import skip skip("bz2 module is not available on Windows") - + def setup_module(mod): DATA = 'BZh91AY&SY.\xc8N\x18\x00\x01>_\x80\x00\x10@\x02\xff\xf0\x01\x07n\x00?\xe7\xff\xe00\x01\x99\xaa\x00\xc0\x03F\x86\x8c#&\x83F\x9a\x03\x06\xa6\xd0\xa6\x93M\x0fQ\xa7\xa8\x06\x804hh\x12$\x11\xa4i4\xf14S\xd2\x88\xe5\xcd9gd6\x0b\n\xe9\x9b\xd5\x8a\x99\xf7\x08.K\x8ev\xfb\xf7xw\xbb\xdf\xa1\x92\xf1\xdd|/";\xa2\xba\x9f\xd5\xb1#A\xb6\xf6\xb3o\xc9\xc5y\\\xebO\xe7\x85\x9a\xbc\xb6f8\x952\xd5\xd7"%\x89>V,\xf7\xa6z\xe2\x9f\xa3\xdf\x11\x11"\xd6E)I\xa9\x13^\xca\xf3r\xd0\x03U\x922\xf26\xec\xb6\xed\x8b\xc3U\x13\x9d\xc5\x170\xa4\xfa^\x92\xacDF\x8a\x97\xd6\x19\xfe\xdd\xb8\xbd\x1a\x9a\x19\xa3\x80ankR\x8b\xe5\xd83]\xa9\xc6\x08\x82f\xf6\xb9"6l$\xb8j@\xc0\x8a\xb0l1..\xbak\x83ls\x15\xbc\xf4\xc1\x13\xbe\xf8E\xb8\x9d\r\xa8\x9dk\x84\xd3n\xfa\xacQ\x07\xb1%y\xaav\xb4\x08\xe0z\x1b\x16\xf5\x04\xe9\xcc\xb9\x08z\x1en7.G\xfc]\xc9\x14\xe1B@\xbb!8`' @@ -54,27 +54,27 @@ def test_creation(self): from bz2 import BZ2Compressor - + raises(TypeError, BZ2Compressor, "foo") raises(ValueError, BZ2Compressor, 10) - + BZ2Compressor(1) BZ2Compressor(9) - + def test_compress(self): from bz2 import BZ2Compressor - + bz2c = BZ2Compressor() raises(TypeError, bz2c.compress) data = bz2c.compress(self.TEXT) data = "%s%s" % (data, bz2c.flush()) assert self.decompress(data) == self.TEXT - + def test_compress_huge_data(self): if not self.HUGE_OK: skip("skipping test requiring lots of memory") - from bz2 import BZ2Compressor - + from bz2 import BZ2Compressor + HUGE_DATA = self.TEXT * 10000 bz2c = BZ2Compressor() raises(TypeError, bz2c.compress) @@ -83,8 +83,8 @@ assert self.decompress(data) == HUGE_DATA def test_compress_chunks_10(self): - from bz2 import BZ2Compressor - + from bz2 import BZ2Compressor + bz2c = BZ2Compressor() n = 0 data = "" @@ -112,23 +112,23 @@ cls.w_TEXT = cls.space.wrap(TEXT) cls.w_DATA = cls.space.wrap(DATA) cls.w_BUGGY_DATA = cls.space.wrap(BUGGY_DATA) - + def test_creation(self): from bz2 import BZ2Decompressor - + raises(TypeError, BZ2Decompressor, "foo") - + BZ2Decompressor() - + def test_attribute(self): from bz2 import BZ2Decompressor - + bz2d = BZ2Decompressor() assert bz2d.unused_data == "" def test_decompress(self): from bz2 import BZ2Decompressor - + bz2d = BZ2Decompressor() raises(TypeError, bz2d.decompress) decompressed_data = bz2d.decompress(self.DATA) @@ -136,7 +136,7 @@ def test_decompress_chunks_10(self): from bz2 import BZ2Decompressor - + bz2d = BZ2Decompressor() decompressed_data = "" n = 0 @@ -146,13 +146,13 @@ break decompressed_data = "%s%s" % (decompressed_data, bz2d.decompress(temp)) n += 1 - + assert decompressed_data == self.TEXT - + def test_decompress_unused_data(self): # test with unused data. (data after EOF) from bz2 import BZ2Decompressor - + bz2d = BZ2Decompressor() unused_data = "this is unused data" decompressed_data = bz2d.decompress(self.DATA + unused_data) @@ -161,7 +161,7 @@ def test_EOF_error(self): from bz2 import BZ2Decompressor - + bz2d = BZ2Decompressor() bz2d.decompress(self.DATA) raises(EOFError, bz2d.decompress, "foo") @@ -195,11 +195,11 @@ def test_compress_function(self): from bz2 import compress - + raises(TypeError, compress, 123) raises(ValueError, compress, "foo", 10) raises(TypeError, compress, "foo", "foo") - + data = compress(self.TEXT) assert self.decompress(data) == self.TEXT @@ -207,7 +207,7 @@ if not self.HUGE_OK: skip("skipping test requiring lots of memory") from bz2 import compress - + HUGE_DATA = self.TEXT * 10000 data = compress(HUGE_DATA) @@ -215,7 +215,7 @@ def test_decompress_function(self): import bz2 - + raises(TypeError, bz2.decompress) assert bz2.decompress("") == "" decompressed_data = bz2.decompress(self.DATA) diff --git a/pypy/module/bz2/test/test_bz2_file.py b/pypy/module/bz2/test/test_bz2_file.py --- a/pypy/module/bz2/test/test_bz2_file.py +++ b/pypy/module/bz2/test/test_bz2_file.py @@ -6,6 +6,7 @@ import py from pypy.interpreter.gateway import unwrap_spec, interp2app +from pypy.module.bz2.test.support import CheckAllocation if os.name == "nt": @@ -50,10 +51,7 @@ mod.RANDOM_DATA = ''.join([s[int(random.random() * len(s))] for i in range(30000)]) -class AppTestBZ2File: #(CheckAllocation): - # XXX for unknown reasons, we cannot do allocation checks, as sth is - # keeping those objects alive (BZ2File objects) - +class AppTestBZ2File(CheckAllocation): spaceconfig = { "usemodules": ["bz2", "binascii", "rctime"] } @@ -85,15 +83,15 @@ assert bz2f.closed == False bz2f.close() assert bz2f.closed == True - + def test_creation(self): from bz2 import BZ2File - + raises(ValueError, BZ2File, self.temppath, mode='w', compresslevel=10) raises(ValueError, BZ2File, self.temppath, mode='XYZ') # XXX the following is fine, currently: #raises(ValueError, BZ2File, self.temppath, mode='ww') - + BZ2File(self.temppath, mode='wU', buffering=0, compresslevel=8) BZ2File(self.temppath, mode='wb') # a large buf size @@ -101,50 +99,50 @@ def test_close(self): from bz2 import BZ2File - + # writeonly bz2f = BZ2File(self.temppath, mode='w') bz2f.close() - # since we use fclose() internally you can't close it twice - # bz2f.close() - + bz2f.close() + # readonly bz2f = BZ2File(self.temppath, mode='r') bz2f.close() - + bz2f.close() + def test_tell(self): from bz2 import BZ2File - + bz2f = BZ2File(self.temppath, mode='w') bz2f.close() raises(ValueError, bz2f.tell) - + bz2f = BZ2File(self.temppath, mode='w') pos = bz2f.tell() bz2f.close() assert pos == 0 - + def test_seek(self): from bz2 import BZ2File - + # hack to create a foo file open(self.temppath, "w").close() - + # cannot seek if close bz2f = BZ2File(self.temppath, mode='r') bz2f.close() raises(ValueError, bz2f.seek, 0) - + # cannot seek if 'w' bz2f = BZ2File(self.temppath, mode='w') raises(IOError, bz2f.seek, 0) bz2f.close() - + bz2f = BZ2File(self.temppath, mode='r') raises(TypeError, bz2f.seek) raises(TypeError, bz2f.seek, "foo") raises(TypeError, bz2f.seek, 0, "foo") - + bz2f.seek(0) assert bz2f.tell() == 0 del bz2f # delete from this frame, which is captured in the traceback @@ -152,21 +150,21 @@ def test_open_close_del(self): from bz2 import BZ2File self.create_temp_file() - + for i in range(10): f = BZ2File(self.temppath) f.close() del f - + def test_open_non_existent(self): from bz2 import BZ2File raises(IOError, BZ2File, "/non/existent/path") - + def test_open_mode_U(self): # bug #1194181: bz2.BZ2File opened for write with mode "U" from bz2 import BZ2File self.create_temp_file() - + bz2f = BZ2File(self.temppath, "U") bz2f.close() f = open(self.temppath) @@ -174,7 +172,7 @@ f.read() assert f.tell() == len(self.DATA) f.close() - + def test_seek_forward(self): from bz2 import BZ2File self.create_temp_file() @@ -214,7 +212,7 @@ assert bz2f.tell() == len(self.TEXT) assert bz2f.read() == "" bz2f.close() - + def test_seek_post_end_twice(self): from bz2 import BZ2File self.create_temp_file() @@ -240,10 +238,9 @@ from bz2 import BZ2File from cStringIO import StringIO self.create_temp_file() - + bz2f = BZ2File(self.temppath) - # XXX - #raises(TypeError, bz2f.readline, None) + raises(TypeError, bz2f.readline, None) sio = StringIO(self.TEXT) for line in sio.readlines(): line_read = bz2f.readline() @@ -253,10 +250,9 @@ def test_read(self): from bz2 import BZ2File self.create_temp_file() - + bz2f = BZ2File(self.temppath) - # XXX - # raises(TypeError, bz2f.read, None) + raises(TypeError, bz2f.read, None) text_read = bz2f.read() assert text_read == self.TEXT bz2f.close() @@ -291,7 +287,7 @@ def test_read_chunk9(self): from bz2 import BZ2File self.create_temp_file() - + bz2f = BZ2File(self.temppath) text_read = "" while True: @@ -305,7 +301,7 @@ def test_read_100_bytes(self): from bz2 import BZ2File self.create_temp_file() - + bz2f = BZ2File(self.temppath) assert bz2f.read(100) == self.TEXT[:100] bz2f.close() @@ -313,7 +309,7 @@ def test_universal_newlines_lf(self): from bz2 import BZ2File self.create_temp_file() - + bz2f = BZ2File(self.temppath, "rU") assert bz2f.read() == self.TEXT assert bz2f.newlines == "\n" @@ -322,7 +318,7 @@ def test_universal_newlines_crlf(self): from bz2 import BZ2File self.create_temp_file(crlf=True) - + bz2f = BZ2File(self.temppath, "rU") data = bz2f.read() assert data == self.TEXT @@ -333,10 +329,9 @@ from bz2 import BZ2File from cStringIO import StringIO self.create_temp_file() - + bz2f = BZ2File(self.temppath) - # XXX - #raises(TypeError, bz2f.readlines, None) + raises(TypeError, bz2f.readlines, None) sio = StringIO(self.TEXT) assert bz2f.readlines() == sio.readlines() bz2f.close() @@ -345,17 +340,17 @@ from bz2 import BZ2File from cStringIO import StringIO self.create_temp_file() - + bz2f = BZ2File(self.temppath) sio = StringIO(self.TEXT) assert list(iter(bz2f)) == sio.readlines() bz2f.close() - + def test_xreadlines(self): from bz2 import BZ2File from cStringIO import StringIO self.create_temp_file() - + bz2f = BZ2File(self.temppath) sio = StringIO(self.TEXT) assert list(bz2f.xreadlines()) == sio.readlines() @@ -364,12 +359,12 @@ def test_readlines_bug_1191043(self): # readlines()/xreadlines() for files containing no newline from bz2 import BZ2File - + DATA = 'BZh91AY&SY\xd9b\x89]\x00\x00\x00\x03\x80\x04\x00\x02\x00\x0c\x00 \x00!\x9ah3M\x13<]\xc9\x14\xe1BCe\x8a%t' f = open(self.temppath, "wb") f.write(DATA) f.close() - + bz2f = BZ2File(self.temppath) lines = bz2f.readlines() bz2f.close() @@ -379,7 +374,7 @@ xlines = list(bz2f.xreadlines()) bz2f.close() assert xlines == ['Test'] - + def test_write(self): from bz2 import BZ2File @@ -387,7 +382,7 @@ raises(TypeError, bz2f.write) bz2f.write(self.TEXT) bz2f.close() - + f = open(self.temppath, "rb") assert self.decompress(f.read()) == self.TEXT f.close() @@ -401,11 +396,11 @@ data = self.TEXT[n * 10:(n + 1) * 10] if not data: break - + bz2f.write(data) n += 1 bz2f.close() - + f = open(self.temppath, "rb") assert self.decompress(f.read()) == self.TEXT f.close() @@ -422,7 +417,7 @@ f = open(self.temppath, "rb") assert self.decompress(f.read()) == self.TEXT f.close() - + def test_write_methods_on_readonly_file(self): from bz2 import BZ2File @@ -453,8 +448,8 @@ assert data == "abc" assert f.closed - - + + # has_cmdline_bunzip2 = sys.platform not in ("win32", "os2emx", "riscos") # # if has_cmdline_bunzip2: diff --git a/pypy/module/imp/__init__.py b/pypy/module/imp/__init__.py --- a/pypy/module/imp/__init__.py +++ b/pypy/module/imp/__init__.py @@ -6,12 +6,14 @@ __import__ function. """ interpleveldefs = { + 'SEARCH_ERROR': 'space.wrap(importing.SEARCH_ERROR)', 'PY_SOURCE': 'space.wrap(importing.PY_SOURCE)', 'PY_COMPILED': 'space.wrap(importing.PY_COMPILED)', 'C_EXTENSION': 'space.wrap(importing.C_EXTENSION)', 'PKG_DIRECTORY': 'space.wrap(importing.PKG_DIRECTORY)', 'C_BUILTIN': 'space.wrap(importing.C_BUILTIN)', 'PY_FROZEN': 'space.wrap(importing.PY_FROZEN)', + 'IMP_HOOK': 'space.wrap(importing.IMP_HOOK)', 'get_suffixes': 'interp_imp.get_suffixes', 'get_magic': 'interp_imp.get_magic', diff --git a/pypy/module/micronumpy/arrayimpl/base.py b/pypy/module/micronumpy/arrayimpl/base.py --- a/pypy/module/micronumpy/arrayimpl/base.py +++ b/pypy/module/micronumpy/arrayimpl/base.py @@ -3,6 +3,12 @@ def is_scalar(self): return False + def base(self): + raise NotImplementedError + + def create_iter(self, shape=None): + raise NotImplementedError + class BaseArrayIterator(object): def next(self): raise NotImplementedError # purely abstract base class diff --git a/pypy/module/micronumpy/arrayimpl/concrete.py b/pypy/module/micronumpy/arrayimpl/concrete.py --- a/pypy/module/micronumpy/arrayimpl/concrete.py +++ b/pypy/module/micronumpy/arrayimpl/concrete.py @@ -1,178 +1,20 @@ from pypy.module.micronumpy.arrayimpl import base -from pypy.module.micronumpy import support, loop +from pypy.module.micronumpy import support, loop, iter from pypy.module.micronumpy.base import convert_to_array, W_NDimArray,\ ArrayArgumentException from pypy.module.micronumpy.strides import calc_new_strides, shape_agreement,\ calculate_broadcast_strides, calculate_dot_strides from pypy.module.micronumpy.iter import Chunk, Chunks, NewAxisChunk, RecordChunk from pypy.interpreter.error import OperationError, operationerrfmt +from pypy.interpreter.buffer import RWBuffer +from rpython.rlib import jit from rpython.rtyper.lltypesystem import rffi, lltype -from rpython.rlib import jit -from rpython.rlib.rawstorage import free_raw_storage, RAW_STORAGE +from rpython.rlib.rawstorage import free_raw_storage, raw_storage_getitem,\ + raw_storage_setitem, RAW_STORAGE +from pypy.module.micronumpy.arrayimpl.sort import argsort_array from rpython.rlib.debug import make_sure_not_resized -class ConcreteArrayIterator(base.BaseArrayIterator): - _immutable_fields_ = ['dtype', 'skip', 'size'] - def __init__(self, array): - self.array = array - self.offset = 0 - self.dtype = array.dtype - self.skip = self.dtype.itemtype.get_element_size() - self.size = array.size - - def setitem(self, elem): - self.dtype.setitem(self.array, self.offset, elem) - - def getitem(self): - return self.dtype.getitem(self.array, self.offset) - - def getitem_bool(self): - return self.dtype.getitem_bool(self.array, self.offset) - - def next(self): - self.offset += self.skip - - def next_skip_x(self, x): - self.offset += self.skip * x - - def done(self): - return self.offset >= self.size - - def reset(self): - self.offset %= self.size - -class OneDimViewIterator(ConcreteArrayIterator): - ''' The view iterator dtype can be different from the - array.dtype, this is what makes it a View - ''' - def __init__(self, array, dtype, start, strides, shape): - self.array = array - self.dtype = dtype - self.offset = start - self.skip = strides[0] - self.index = 0 - self.size = shape[0] - - def next(self): - self.offset += self.skip - self.index += 1 - - def next_skip_x(self, x): - self.offset += self.skip * x - self.index += x - - def done(self): - return self.index >= self.size - - def reset(self): - self.offset %= self.size - -class MultiDimViewIterator(ConcreteArrayIterator): - ''' The view iterator dtype can be different from the - array.dtype, this is what makes it a View - ''' - def __init__(self, array, dtype, start, strides, backstrides, shape): - self.indexes = [0] * len(shape) - self.array = array - self.dtype = dtype - self.shape = shape - self.offset = start - self.shapelen = len(shape) - self._done = False - self.strides = strides - self.backstrides = backstrides - self.size = array.size - - @jit.unroll_safe - def next(self): - offset = self.offset - for i in range(self.shapelen - 1, -1, -1): - if self.indexes[i] < self.shape[i] - 1: - self.indexes[i] += 1 - offset += self.strides[i] - break - else: - self.indexes[i] = 0 - offset -= self.backstrides[i] - else: - self._done = True - self.offset = offset - - @jit.unroll_safe - def next_skip_x(self, step): - for i in range(len(self.shape) - 1, -1, -1): - if self.indexes[i] < self.shape[i] - step: - self.indexes[i] += step - self.offset += self.strides[i] * step - break - else: - remaining_step = (self.indexes[i] + step) // self.shape[i] - this_i_step = step - remaining_step * self.shape[i] - self.offset += self.strides[i] * this_i_step - self.indexes[i] = self.indexes[i] + this_i_step - step = remaining_step - else: - self._done = True - - def done(self): - return self._done - - def reset(self): - self.offset %= self.size - -class AxisIterator(base.BaseArrayIterator): - def __init__(self, array, shape, dim): - self.shape = shape - strides = array.get_strides() - backstrides = array.get_backstrides() - if len(shape) == len(strides): - # keepdims = True - self.strides = strides[:dim] + [0] + strides[dim + 1:] - self.backstrides = backstrides[:dim] + [0] + backstrides[dim + 1:] - else: - self.strides = strides[:dim] + [0] + strides[dim:] - self.backstrides = backstrides[:dim] + [0] + backstrides[dim:] - self.first_line = True - self.indices = [0] * len(shape) - self._done = False - self.offset = array.start - self.dim = dim - self.array = array - self.dtype = array.dtype - - def setitem(self, elem): - self.dtype.setitem(self.array, self.offset, elem) - - def getitem(self): - return self.dtype.getitem(self.array, self.offset) - - @jit.unroll_safe - def next(self): - for i in range(len(self.shape) - 1, -1, -1): - if self.indices[i] < self.shape[i] - 1: - if i == self.dim: - self.first_line = False - self.indices[i] += 1 - self.offset += self.strides[i] - break - else: - if i == self.dim: - self.first_line = True - self.indices[i] = 0 - self.offset -= self.backstrides[i] - else: - self._done = True - - def done(self): - return self._done - -def int_w(space, w_obj): - try: - return space.int_w(space.index(w_obj)) - except OperationError: - return space.int_w(space.int(w_obj)) - class BaseConcreteArray(base.BaseArrayImplementation): start = 0 parent = None @@ -213,7 +55,7 @@ def get_size(self): return self.size // self.dtype.itemtype.get_element_size() - def reshape(self, space, new_shape): + def reshape(self, space, orig_array, new_shape): # Since we got to here, prod(new_shape) == self.size new_strides = None if self.size > 0: @@ -226,31 +68,31 @@ for nd in range(ndims): new_backstrides[nd] = (new_shape[nd] - 1) * new_strides[nd] return SliceArray(self.start, new_strides, new_backstrides, - new_shape, self) + new_shape, self, orig_array) else: return None - def get_real(self): + def get_real(self, orig_array): strides = self.get_strides() backstrides = self.get_backstrides() if self.dtype.is_complex_type(): dtype = self.dtype.float_type return SliceArray(self.start, strides, backstrides, - self.get_shape(), self, dtype=dtype) + self.get_shape(), self, orig_array, dtype=dtype) return SliceArray(self.start, strides, backstrides, - self.get_shape(), self) + self.get_shape(), self, orig_array) - def get_imag(self): + def get_imag(self, orig_array): strides = self.get_strides() backstrides = self.get_backstrides() if self.dtype.is_complex_type(): dtype = self.dtype.float_type return SliceArray(self.start + dtype.get_size(), strides, - backstrides, self.get_shape(), self, dtype=dtype) + backstrides, self.get_shape(), self, orig_array, dtype=dtype) if self.dtype.is_flexible_type(): # numpy returns self for self.imag return SliceArray(self.start, strides, backstrides, - self.get_shape(), self) + self.get_shape(), self, orig_array) impl = NonWritableArray(self.get_shape(), self.dtype, self.order, strides, backstrides) impl.fill(self.dtype.box(0)) @@ -265,7 +107,7 @@ for i, w_index in enumerate(view_w): if space.isinstance_w(w_index, space.w_slice): raise IndexError - idx = int_w(space, w_index) + idx = support.int_w(space, w_index) if idx < 0: idx = self.get_shape()[i] + idx if idx < 0 or idx >= self.get_shape()[i]: @@ -339,7 +181,7 @@ return self._lookup_by_index(space, view_w) if shape_len > 1: raise IndexError - idx = int_w(space, w_idx) + idx = support.int_w(space, w_idx) return self._lookup_by_index(space, [space.wrap(idx)]) @jit.unroll_safe @@ -367,26 +209,26 @@ i += 1 return Chunks(result) - def descr_getitem(self, space, w_index): + def descr_getitem(self, space, orig_arr, w_index): try: item = self._single_item_index(space, w_index) return self.getitem(item) except IndexError: # not a single result chunks = self._prepare_slice_args(space, w_index) - return chunks.apply(self) + return chunks.apply(orig_arr) - def descr_setitem(self, space, w_index, w_value): + def descr_setitem(self, space, orig_arr, w_index, w_value): try: item = self._single_item_index(space, w_index) self.setitem(item, self.dtype.coerce(space, w_value)) except IndexError: w_value = convert_to_array(space, w_value) chunks = self._prepare_slice_args(space, w_index) - view = chunks.apply(self) + view = chunks.apply(orig_arr) view.implementation.setslice(space, w_value) - def transpose(self): + def transpose(self, orig_array): if len(self.get_shape()) < 2: return self strides = [] @@ -397,7 +239,7 @@ backstrides.append(self.get_backstrides()[i]) shape.append(self.get_shape()[i]) return SliceArray(self.start, strides, - backstrides, shape, self) + backstrides, shape, self, orig_array) def copy(self): strides, backstrides = support.calc_strides(self.get_shape(), self.dtype, @@ -406,15 +248,15 @@ backstrides) return loop.setslice(self.get_shape(), impl, self) - def create_axis_iter(self, shape, dim): - return AxisIterator(self, shape, dim) + def create_axis_iter(self, shape, dim, cum): + return iter.AxisIterator(self, shape, dim, cum) def create_dot_iter(self, shape, skip): r = calculate_dot_strides(self.get_strides(), self.get_backstrides(), shape, skip) - return MultiDimViewIterator(self, self.dtype, self.start, r[0], r[1], shape) + return iter.MultiDimViewIterator(self, self.dtype, self.start, r[0], r[1], shape) - def swapaxes(self, axis1, axis2): + def swapaxes(self, orig_arr, axis1, axis2): shape = self.get_shape()[:] strides = self.get_strides()[:] backstrides = self.get_backstrides()[:] @@ -422,13 +264,20 @@ strides[axis1], strides[axis2] = strides[axis2], strides[axis1] backstrides[axis1], backstrides[axis2] = backstrides[axis2], backstrides[axis1] return W_NDimArray.new_slice(self.start, strides, - backstrides, shape, self) + backstrides, shape, self, orig_arr) def get_storage_as_int(self, space): return rffi.cast(lltype.Signed, self.storage) + def get_storage(self): + return self.storage + + def get_buffer(self, space): + return ArrayBuffer(self) + class ConcreteArrayNotOwning(BaseConcreteArray): def __init__(self, shape, dtype, order, strides, backstrides, storage): + make_sure_not_resized(shape) make_sure_not_resized(strides) make_sure_not_resized(backstrides) @@ -442,19 +291,31 @@ def create_iter(self, shape=None): if shape is None or shape == self.get_shape(): - return ConcreteArrayIterator(self) + return iter.ConcreteArrayIterator(self) r = calculate_broadcast_strides(self.get_strides(), self.get_backstrides(), self.get_shape(), shape) - return MultiDimViewIterator(self, self.dtype, 0, r[0], r[1], shape) + return iter.MultiDimViewIterator(self, self.dtype, 0, r[0], r[1], shape) def fill(self, box): self.dtype.fill(self.storage, box, 0, self.size) - def set_shape(self, space, new_shape): + def set_shape(self, space, orig_array, new_shape): strides, backstrides = support.calc_strides(new_shape, self.dtype, self.order) - return SliceArray(0, strides, backstrides, new_shape, self) + return SliceArray(0, strides, backstrides, new_shape, self, + orig_array) + + def argsort(self, space, w_axis): + return argsort_array(self, space, w_axis) + + def astype(self, space, dtype): + new_arr = W_NDimArray.from_shape(self.get_shape(), dtype) + loop.copy_from_to(self, new_arr.implementation, dtype) + return new_arr + + def base(self): + return None class ConcreteArray(ConcreteArrayNotOwning): def __init__(self, shape, dtype, order, strides, backstrides): @@ -469,14 +330,17 @@ free_raw_storage(self.storage, track_allocation=False) + + class NonWritableArray(ConcreteArray): - def descr_setitem(self, space, w_index, w_value): + def descr_setitem(self, space, orig_array, w_index, w_value): raise OperationError(space.w_RuntimeError, space.wrap( "array is not writable")) class SliceArray(BaseConcreteArray): - def __init__(self, start, strides, backstrides, shape, parent, dtype=None): + def __init__(self, start, strides, backstrides, shape, parent, orig_arr, + dtype=None): self.strides = strides self.backstrides = backstrides self.shape = shape @@ -490,6 +354,10 @@ self.dtype = dtype self.size = support.product(shape) * self.dtype.itemtype.get_element_size() self.start = start + self.orig_arr = orig_arr + + def base(self): + return self.orig_arr def fill(self, box): loop.fill(self, box.convert_to(self.dtype)) @@ -499,16 +367,16 @@ r = calculate_broadcast_strides(self.get_strides(), self.get_backstrides(), self.get_shape(), shape) - return MultiDimViewIterator(self.parent, self.dtype, - self.start, r[0], r[1], shape) + return iter.MultiDimViewIterator(self.parent, self.dtype, + self.start, r[0], r[1], shape) if len(self.get_shape()) == 1: - return OneDimViewIterator(self.parent, self.dtype, self.start, + return iter.OneDimViewIterator(self.parent, self.dtype, self.start, self.get_strides(), self.get_shape()) - return MultiDimViewIterator(self.parent, self.dtype, self.start, + return iter.MultiDimViewIterator(self.parent, self.dtype, self.start, self.get_strides(), self.get_backstrides(), self.get_shape()) - def set_shape(self, space, new_shape): + def set_shape(self, space, orig_array, new_shape): if len(self.get_shape()) < 2 or self.size == 0: # TODO: this code could be refactored into calc_strides # but then calc_strides would have to accept a stepping factor @@ -527,7 +395,7 @@ backstrides.reverse() new_shape.reverse() return SliceArray(self.start, strides, backstrides, new_shape, - self) + self, orig_array) new_strides = calc_new_strides(new_shape, self.get_shape(), self.get_strides(), self.order) @@ -538,4 +406,18 @@ for nd in range(len(new_shape)): new_backstrides[nd] = (new_shape[nd] - 1) * new_strides[nd] return SliceArray(self.start, new_strides, new_backstrides, new_shape, - self) + self, orig_array) + +class ArrayBuffer(RWBuffer): + def __init__(self, impl): + self.impl = impl + + def getitem(self, item): + return raw_storage_getitem(lltype.Char, self.impl.storage, item) + + def setitem(self, item, v): + return raw_storage_setitem(self.impl.storage, item, + rffi.cast(lltype.Char, v)) + + def getlength(self): + return self.impl.size diff --git a/pypy/module/micronumpy/arrayimpl/scalar.py b/pypy/module/micronumpy/arrayimpl/scalar.py --- a/pypy/module/micronumpy/arrayimpl/scalar.py +++ b/pypy/module/micronumpy/arrayimpl/scalar.py @@ -54,10 +54,10 @@ def get_size(self): return 1 - def transpose(self): + def transpose(self, _): return self - def descr_getitem(self, space, w_idx): + def descr_getitem(self, space, _, w_idx): raise OperationError(space.w_IndexError, space.wrap("scalars cannot be indexed")) @@ -65,14 +65,14 @@ raise OperationError(space.w_IndexError, space.wrap("scalars cannot be indexed")) - def descr_setitem(self, space, w_idx, w_val): + def descr_setitem(self, space, _, w_idx, w_val): raise OperationError(space.w_IndexError, space.wrap("scalars cannot be indexed")) def setitem_index(self, space, idx, w_val): raise OperationError(space.w_IndexError, space.wrap("scalars cannot be indexed")) - def set_shape(self, space, new_shape): + def set_shape(self, space, orig_array, new_shape): if not new_shape: return self if support.product(new_shape) == 1: @@ -83,13 +83,13 @@ raise OperationError(space.w_ValueError, space.wrap( "total size of the array must be unchanged")) - def reshape(self, space, new_shape): - return self.set_shape(space, new_shape) + def reshape(self, space, orig_array, new_shape): + return self.set_shape(space, orig_array, new_shape) - def create_axis_iter(self, shape, dim): + def create_axis_iter(self, shape, dim, cum): raise Exception("axis iter should not happen on scalar") - def swapaxes(self, axis1, axis2): + def swapaxes(self, orig_array, axis1, axis2): raise Exception("should not be called") def fill(self, w_value): @@ -98,3 +98,17 @@ def get_storage_as_int(self, space): raise OperationError(space.w_ValueError, space.wrap("scalars have no address")) + + def argsort(self, space, w_axis): + return space.wrap(0) + + def astype(self, space, dtype): + return W_NDimArray.new_scalar(space, dtype, self.value) + + def base(self): + return None + + def get_buffer(self, space): + raise OperationError(space.w_ValueError, space.wrap( + "cannot point buffer to a scalar")) + diff --git a/pypy/module/micronumpy/arrayimpl/sort.py b/pypy/module/micronumpy/arrayimpl/sort.py new file mode 100644 --- /dev/null +++ b/pypy/module/micronumpy/arrayimpl/sort.py @@ -0,0 +1,195 @@ + +""" This is the implementation of various sorting routines in numpy. It's here +because it only makes sense on a concrete array +""" + +from rpython.rtyper.lltypesystem import rffi, lltype +from rpython.rlib.listsort import make_timsort_class +from rpython.rlib.rawstorage import raw_storage_getitem, raw_storage_setitem, \ + free_raw_storage, alloc_raw_storage +from rpython.rlib.unroll import unrolling_iterable +from rpython.rlib.rarithmetic import intmask +from rpython.rlib.objectmodel import specialize +from pypy.interpreter.error import OperationError +from pypy.module.micronumpy.base import W_NDimArray +from pypy.module.micronumpy import interp_dtype, types +from pypy.module.micronumpy.iter import AxisIterator + +INT_SIZE = rffi.sizeof(lltype.Signed) + +def make_sort_function(space, itemtype, comp_type, count=1): + TP = itemtype.T + step = rffi.sizeof(TP) + + class Repr(object): + def __init__(self, index_stride_size, stride_size, size, values, + indexes, index_start, start): + self.index_stride_size = index_stride_size + self.stride_size = stride_size + self.index_start = index_start + self.start = start + self.size = size + self.values = values + self.indexes = indexes + + def getitem(self, item): + if count < 2: + v = raw_storage_getitem(TP, self.values, item * self.stride_size + + self.start) + else: + v = [] + for i in range(count): + _v = raw_storage_getitem(TP, self.values, item * self.stride_size + + self.start + step * i) + v.append(_v) + if comp_type == 'int': + v = intmask(v) + elif comp_type == 'float': + v = float(v) + elif comp_type == 'complex': + v = [float(v[0]),float(v[1])] + else: + raise NotImplementedError('cannot reach') + return (v, raw_storage_getitem(lltype.Signed, self.indexes, + item * self.index_stride_size + + self.index_start)) + + def setitem(self, idx, item): + if count < 2: + raw_storage_setitem(self.values, idx * self.stride_size + + self.start, rffi.cast(TP, item[0])) + else: + i = 0 + for val in item[0]: + raw_storage_setitem(self.values, idx * self.stride_size + + self.start + i*step, rffi.cast(TP, val)) + i += 1 + raw_storage_setitem(self.indexes, idx * self.index_stride_size + + self.index_start, item[1]) + + class ArgArrayRepWithStorage(Repr): + def __init__(self, index_stride_size, stride_size, size): + start = 0 + dtype = interp_dtype.get_dtype_cache(space).w_longdtype + self.indexes = dtype.itemtype.malloc(size*dtype.get_size()) + self.values = alloc_raw_storage(size * stride_size, + track_allocation=False) + Repr.__init__(self, index_stride_size, stride_size, + size, self.values, self.indexes, start, start) + + def __del__(self): + free_raw_storage(self.indexes, track_allocation=False) + free_raw_storage(self.values, track_allocation=False) + + def arg_getitem(lst, item): + return lst.getitem(item) + + def arg_setitem(lst, item, value): + lst.setitem(item, value) + + def arg_length(lst): + return lst.size + + def arg_getitem_slice(lst, start, stop): + retval = ArgArrayRepWithStorage(lst.index_stride_size, lst.stride_size, + stop-start) + for i in range(stop-start): + retval.setitem(i, lst.getitem(i+start)) + return retval + + if count < 2: + def arg_lt(a, b): + # Does numpy do <= ? + return a[0] < b[0] + else: + def arg_lt(a, b): + for i in range(count): + if a[0][i] < b[0][i]: + return True + elif a[0][i] > b[0][i]: + return False + # Does numpy do True? + return False + + ArgSort = make_timsort_class(arg_getitem, arg_setitem, arg_length, + arg_getitem_slice, arg_lt) + + def argsort(arr, space, w_axis, itemsize): + if w_axis is space.w_None: + # note that it's fine ot pass None here as we're not going + # to pass the result around (None is the link to base in slices) + arr = arr.reshape(space, None, [arr.get_size()]) + axis = 0 + elif w_axis is None: + axis = -1 + else: + axis = space.int_w(w_axis) + # create array of indexes + dtype = interp_dtype.get_dtype_cache(space).w_longdtype + index_arr = W_NDimArray.from_shape(arr.get_shape(), dtype) + storage = index_arr.implementation.get_storage() + if len(arr.get_shape()) == 1: + for i in range(arr.get_size()): + raw_storage_setitem(storage, i * INT_SIZE, i) + r = Repr(INT_SIZE, itemsize, arr.get_size(), arr.get_storage(), + storage, 0, arr.start) + ArgSort(r).sort() + else: + shape = arr.get_shape() + if axis < 0: + axis = len(shape) + axis - 1 + if axis < 0 or axis > len(shape): + raise OperationError(space.w_IndexError, space.wrap( + "Wrong axis %d" % axis)) + iterable_shape = shape[:axis] + [0] + shape[axis + 1:] + iter = AxisIterator(arr, iterable_shape, axis, False) + index_impl = index_arr.implementation + index_iter = AxisIterator(index_impl, iterable_shape, axis, False) + stride_size = arr.strides[axis] + index_stride_size = index_impl.strides[axis] + axis_size = arr.shape[axis] + while not iter.done(): + for i in range(axis_size): + raw_storage_setitem(storage, i * index_stride_size + + index_iter.offset, i) + r = Repr(index_stride_size, stride_size, axis_size, + arr.get_storage(), storage, index_iter.offset, iter.offset) + ArgSort(r).sort() + iter.next() + index_iter.next() + return index_arr + + return argsort + +def argsort_array(arr, space, w_axis): + cache = space.fromcache(SortCache) # that populates SortClasses + itemtype = arr.dtype.itemtype + for tp in all_types: + if isinstance(itemtype, tp[0]): + return cache._lookup(tp)(arr, space, w_axis, + itemtype.get_element_size()) + # XXX this should probably be changed + raise OperationError(space.w_NotImplementedError, + space.wrap("sorting of non-numeric types " + \ + "'%s' is not implemented" % arr.dtype.get_name(), )) + +all_types = (types.all_float_types + types.all_complex_types + + types.all_int_types) +all_types = [i for i in all_types if not '_mixin_' in i[0].__dict__] +all_types = unrolling_iterable(all_types) + +class SortCache(object): + built = False + + def __init__(self, space): + if self.built: + return + self.built = True + cache = {} + for cls, it in all_types._items: + if it == 'complex': + cache[cls] = make_sort_function(space, cls, it, 2) + else: + cache[cls] = make_sort_function(space, cls, it) + self.cache = cache + self._lookup = specialize.memo()(lambda tp : cache[tp[0]]) diff --git a/pypy/module/micronumpy/base.py b/pypy/module/micronumpy/base.py --- a/pypy/module/micronumpy/base.py +++ b/pypy/module/micronumpy/base.py @@ -2,6 +2,7 @@ from pypy.interpreter.baseobjspace import Wrappable from rpython.tool.pairtype import extendabletype from pypy.module.micronumpy.support import calc_strides +from pypy.module.micronumpy.arrayimpl.base import BaseArrayImplementation def issequence_w(space, w_obj): return (space.isinstance_w(w_obj, space.w_tuple) or @@ -15,6 +16,7 @@ __metaclass__ = extendabletype def __init__(self, implementation): + assert isinstance(implementation, BaseArrayImplementation) self.implementation = implementation @staticmethod @@ -38,11 +40,11 @@ @staticmethod - def new_slice(offset, strides, backstrides, shape, parent, dtype=None): + def new_slice(offset, strides, backstrides, shape, parent, orig_arr, dtype=None): from pypy.module.micronumpy.arrayimpl import concrete impl = concrete.SliceArray(offset, strides, backstrides, shape, parent, - dtype) + orig_arr, dtype) return W_NDimArray(impl) @staticmethod diff --git a/pypy/module/micronumpy/compile.py b/pypy/module/micronumpy/compile.py --- a/pypy/module/micronumpy/compile.py +++ b/pypy/module/micronumpy/compile.py @@ -35,7 +35,8 @@ pass SINGLE_ARG_FUNCTIONS = ["sum", "prod", "max", "min", "all", "any", - "unegative", "flat", "tostring","count_nonzero"] + "unegative", "flat", "tostring","count_nonzero", + "argsort"] TWO_ARG_FUNCTIONS = ["dot", 'take'] THREE_ARG_FUNCTIONS = ['where'] @@ -482,6 +483,8 @@ w_res = cos.call(interp.space, [arr]) elif self.name == "flat": w_res = arr.descr_get_flatiter(interp.space) + elif self.name == "argsort": + w_res = arr.descr_argsort(interp.space) elif self.name == "tostring": arr.descr_tostring(interp.space) w_res = None diff --git a/pypy/module/micronumpy/constants.py b/pypy/module/micronumpy/constants.py new file mode 100644 --- /dev/null +++ b/pypy/module/micronumpy/constants.py @@ -0,0 +1,4 @@ + +MODE_WRAP, MODE_RAISE, MODE_CLIP = range(3) + +MODES = {'wrap': MODE_WRAP, 'raise': MODE_RAISE, 'clip': MODE_CLIP} diff --git a/pypy/module/micronumpy/interp_arrayops.py b/pypy/module/micronumpy/interp_arrayops.py --- a/pypy/module/micronumpy/interp_arrayops.py +++ b/pypy/module/micronumpy/interp_arrayops.py @@ -1,8 +1,10 @@ from pypy.module.micronumpy.base import convert_to_array, W_NDimArray -from pypy.module.micronumpy import loop, interp_ufuncs +from pypy.module.micronumpy import loop, interp_dtype, interp_ufuncs from pypy.module.micronumpy.iter import Chunk, Chunks -from pypy.module.micronumpy.strides import shape_agreement +from pypy.module.micronumpy.strides import shape_agreement,\ + shape_agreement_multiple +from pypy.module.micronumpy.constants import MODES from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.gateway import unwrap_spec @@ -123,7 +125,7 @@ for arr in args_w: chunks[axis] = Chunk(axis_start, axis_start + arr.get_shape()[axis], 1, arr.get_shape()[axis]) - Chunks(chunks).apply(res.implementation).implementation.setslice(space, arr) + Chunks(chunks).apply(res).implementation.setslice(space, arr) axis_start += arr.get_shape()[axis] return res @@ -137,7 +139,7 @@ res = W_NDimArray.from_shape(shape, arr.get_dtype()) for i in range(repeats): Chunks([Chunk(i, shape[0] - repeats + i, repeats, - orig_size)]).apply(res.implementation).implementation.setslice(space, arr) + orig_size)]).apply(res).implementation.setslice(space, arr) else: axis = space.int_w(w_axis) shape = arr.get_shape()[:] @@ -148,8 +150,47 @@ for i in range(repeats): chunks[axis] = Chunk(i, shape[axis] - repeats + i, repeats, orig_size) - Chunks(chunks).apply(res.implementation).implementation.setslice(space, arr) + Chunks(chunks).apply(res).implementation.setslice(space, arr) return res def count_nonzero(space, w_obj): return space.wrap(loop.count_all_true(convert_to_array(space, w_obj))) + +def choose(space, arr, w_choices, out, mode): + choices = [convert_to_array(space, w_item) for w_item + in space.listview(w_choices)] + if not choices: + raise OperationError(space.w_ValueError, + space.wrap("choices list cannot be empty")) + shape = shape_agreement_multiple(space, choices + [out]) + out = interp_dtype.dtype_agreement(space, choices, shape, out) + dtype = out.get_dtype() + if mode not in MODES: + raise OperationError(space.w_ValueError, + space.wrap("mode %s not known" % (mode,))) + loop.choose(space, arr, choices, shape, dtype, out, MODES[mode]) + return out + +def diagonal(space, arr, offset, axis1, axis2): + shape = arr.get_shape() + shapelen = len(shape) + if offset < 0: + offset = -offset + axis1, axis2 = axis2, axis1 + size = min(shape[axis1], shape[axis2] - offset) + dtype = arr.dtype + if axis1 < axis2: + shape = (shape[:axis1] + shape[axis1 + 1:axis2] + + shape[axis2 + 1:] + [size]) + else: + shape = (shape[:axis2] + shape[axis2 + 1:axis1] + + shape[axis1 + 1:] + [size]) + out = W_NDimArray.from_shape(shape, dtype) + if size == 0: + return out + if shapelen == 2: + # simple case + loop.diagonal_simple(space, arr, out, offset, axis1, axis2, size) + else: + loop.diagonal_array(space, arr, out, offset, axis1, axis2, shape) + return out diff --git a/pypy/module/micronumpy/interp_boxes.py b/pypy/module/micronumpy/interp_boxes.py --- a/pypy/module/micronumpy/interp_boxes.py +++ b/pypy/module/micronumpy/interp_boxes.py @@ -43,6 +43,9 @@ def convert_to(self, dtype): return dtype.box(self.value) + def __repr__(self): + return '%s(%s)' % (self.__class__.__name__, self.value) + class ComplexBox(object): _mixin_ = True @@ -284,6 +287,11 @@ for i in range(len(arg)): arr.storage[i] = arg[i] return W_StringBox(arr, 0, arr.dtype) + + def convert_to(self, dtype): + from pypy.module.micronumpy import types + assert isinstance(dtype.itemtype, types.StringType) + return self class W_UnicodeBox(W_CharacterBox): def descr__new__unicode_box(space, w_subtype, w_arg): @@ -297,6 +305,11 @@ # arr.storage[i] = arg[i] return W_UnicodeBox(arr, 0, arr.dtype) + def convert_to(self, dtype): + from pypy.module.micronumpy import types + assert isinstance(dtype.itemtype, types.UnicodeType) + return self + class W_ComplexFloatingBox(W_InexactBox): _attrs_ = () diff --git a/pypy/module/micronumpy/interp_dtype.py b/pypy/module/micronumpy/interp_dtype.py --- a/pypy/module/micronumpy/interp_dtype.py +++ b/pypy/module/micronumpy/interp_dtype.py @@ -5,10 +5,11 @@ from pypy.interpreter.gateway import interp2app, unwrap_spec from pypy.interpreter.typedef import (TypeDef, GetSetProperty, interp_attrproperty, interp_attrproperty_w) -from pypy.module.micronumpy import types, interp_boxes +from pypy.module.micronumpy import types, interp_boxes, base from rpython.rlib.objectmodel import specialize from rpython.rlib.rarithmetic import LONG_BIT, r_longlong, r_ulonglong from rpython.rtyper.lltypesystem import rffi +from rpython.rlib import jit UNSIGNEDLTR = "u" @@ -28,6 +29,21 @@ return space.interp_w(W_Dtype, space.call_function(space.gettypefor(W_Dtype), w_dtype)) + at jit.unroll_safe +def dtype_agreement(space, w_arr_list, shape, out=None): + """ agree on dtype from a list of arrays. if out is allocated, + use it's dtype, otherwise allocate a new one with agreed dtype + """ + from pypy.module.micronumpy.interp_ufuncs import find_binop_result_dtype + + if not space.is_none(out): + return out + dtype = w_arr_list[0].get_dtype() + for w_arr in w_arr_list[1:]: + dtype = find_binop_result_dtype(space, dtype, w_arr.get_dtype()) + out = base.W_NDimArray.from_shape(shape, dtype) + return out + class W_Dtype(Wrappable): _immutable_fields_ = ["itemtype", "num", "kind"] @@ -45,6 +61,7 @@ self.fields = fields self.fieldnames = fieldnames self.native = native + self.float_type = None @specialize.argtype(1) def box(self, value): @@ -138,6 +155,9 @@ def is_complex_type(self): return False + def is_float_type(self): + return (self.kind == FLOATINGLTR or self.float_type is not None) + def is_bool_type(self): return self.kind == BOOLLTR @@ -156,7 +176,6 @@ return self.itemtype.get_element_size() class W_ComplexDtype(W_Dtype): - def __init__(self, itemtype, num, kind, name, char, w_box_type, alternate_constructors=[], aliases=[], fields=None, fieldnames=None, native=True, float_type=None): @@ -257,7 +276,7 @@ return dtype if w_dtype is dtype.w_box_type: return dtype - raise OperationError(space.w_TypeError, space.wrap("data type not understood")) + raise OperationError(space.w_TypeError, space.wrap("data type %s not understood")) W_Dtype.typedef = TypeDef("dtype", __module__ = "numpypy", @@ -382,6 +401,7 @@ char="l", w_box_type=space.gettypefor(interp_boxes.W_LongBox), alternate_constructors=[space.w_int], + aliases=['int'], ) self.w_ulongdtype = W_Dtype( types.ULong(), @@ -596,6 +616,16 @@ itemtype, dtype.num, dtype.kind, new_name, dtype.char, dtype.w_box_type, native=False) + if dtype.kind != dtype.char: + can_name = dtype.char + self.dtypes_by_name[byteorder_prefix + can_name] = dtype + self.dtypes_by_name['=' + can_name] = dtype + new_name = nonnative_byteorder_prefix + can_name + self.dtypes_by_name[new_name] = W_Dtype( + itemtype, + dtype.num, dtype.kind, new_name, dtype.char, dtype.w_box_type, + native=False) + for alias in dtype.aliases: self.dtypes_by_name[alias] = dtype self.dtypes_by_name[dtype.char] = dtype diff --git a/pypy/module/micronumpy/interp_flatiter.py b/pypy/module/micronumpy/interp_flatiter.py --- a/pypy/module/micronumpy/interp_flatiter.py +++ b/pypy/module/micronumpy/interp_flatiter.py @@ -9,15 +9,19 @@ like a real array for descr_eq and friends """ def __init__(self, base): - self.base = base + self._base = base self.dtype = base.get_dtype() self.shape = [base.get_size()] + def base(self): + return self._base + def get_shape(self): return self.shape def create_iter(self, shape=None): - return self.base.create_iter() + assert isinstance(self.base(), W_NDimArray) + return self.base().create_iter() class W_FlatIterator(W_NDimArray): def __init__(self, arr): diff --git a/pypy/module/micronumpy/interp_numarray.py b/pypy/module/micronumpy/interp_numarray.py --- a/pypy/module/micronumpy/interp_numarray.py +++ b/pypy/module/micronumpy/interp_numarray.py @@ -4,9 +4,11 @@ from pypy.interpreter.gateway import interp2app, unwrap_spec, WrappedDefault from pypy.module.micronumpy.base import W_NDimArray, convert_to_array,\ ArrayArgumentException, issequence_w -from pypy.module.micronumpy import interp_dtype, interp_ufuncs, interp_boxes +from pypy.module.micronumpy import interp_dtype, interp_ufuncs, interp_boxes,\ + interp_arrayops from pypy.module.micronumpy.strides import find_shape_and_elems,\ - get_shape_from_iterable, to_coords, shape_agreement + get_shape_from_iterable, to_coords, shape_agreement, \ + shape_agreement_multiple from pypy.module.micronumpy.interp_flatiter import W_FlatIterator from pypy.module.micronumpy.interp_support import unwrap_axis_arg from pypy.module.micronumpy.appbridge import get_appbridge_cache @@ -16,6 +18,7 @@ from rpython.tool.sourcetools import func_with_new_name from rpython.rlib import jit from rpython.rlib.rstring import StringBuilder +from pypy.module.micronumpy.arrayimpl.base import BaseArrayImplementation def _find_shape(space, w_size): if space.is_none(w_size): @@ -37,7 +40,7 @@ return self.implementation.get_shape() def descr_set_shape(self, space, w_new_shape): - self.implementation = self.implementation.set_shape(space, + self.implementation = self.implementation.set_shape(space, self, get_shape_from_iterable(space, self.get_size(), w_new_shape)) def descr_get_strides(self, space): @@ -152,7 +155,7 @@ w_idx.get_dtype().is_bool_type()): return self.getitem_filter(space, w_idx) try: - return self.implementation.descr_getitem(space, w_idx) + return self.implementation.descr_getitem(space, self, w_idx) except ArrayArgumentException: return self.getitem_array_int(space, w_idx) except OperationError: @@ -170,7 +173,7 @@ return self.setitem_filter(space, w_idx, convert_to_array(space, w_value)) try: - self.implementation.descr_setitem(space, w_idx, w_value) + self.implementation.descr_setitem(space, self, w_idx, w_value) except ArrayArgumentException: self.setitem_array_int(space, w_idx, w_value) @@ -210,10 +213,11 @@ return s.build() def create_iter(self, shape=None): + assert isinstance(self.implementation, BaseArrayImplementation) return self.implementation.create_iter(shape) - def create_axis_iter(self, shape, dim): - return self.implementation.create_axis_iter(shape, dim) + def create_axis_iter(self, shape, dim, cum): + return self.implementation.create_axis_iter(shape, dim, cum) def create_dot_iter(self, shape, skip): return self.implementation.create_dot_iter(shape, skip) @@ -240,10 +244,10 @@ return W_NDimArray(self.implementation.copy()) def descr_get_real(self, space): - return W_NDimArray(self.implementation.get_real()) + return W_NDimArray(self.implementation.get_real(self)) def descr_get_imag(self, space): - ret = self.implementation.get_imag() + ret = self.implementation.get_imag(self) if ret: return W_NDimArray(ret) raise OperationError(space.w_NotImplementedError, @@ -251,7 +255,7 @@ def descr_set_real(self, space, w_value): # copy (broadcast) values into self - tmp = self.implementation.get_real() + tmp = self.implementation.get_real(self) tmp.setslice(space, convert_to_array(space, w_value)) def descr_set_imag(self, space, w_value): @@ -259,7 +263,7 @@ if not self.get_dtype().is_complex_type(): raise OperationError(space.w_TypeError, space.wrap('array does not have imaginary part to set')) - tmp = self.implementation.get_imag() + tmp = self.implementation.get_imag(self) tmp.setslice(space, convert_to_array(space, w_value)) def descr_reshape(self, space, args_w): @@ -279,20 +283,21 @@ else: w_shape = space.newtuple(args_w) new_shape = get_shape_from_iterable(space, self.get_size(), w_shape) - new_impl = self.implementation.reshape(space, new_shape) + new_impl = self.implementation.reshape(space, self, new_shape) if new_impl is not None: return W_NDimArray(new_impl) # Create copy with contiguous data arr = self.descr_copy(space) if arr.get_size() > 0: - arr.implementation = arr.implementation.reshape(space, new_shape) + arr.implementation = arr.implementation.reshape(space, self, + new_shape) assert arr.implementation else: arr.implementation.shape = new_shape return arr def descr_get_transpose(self, space): - return W_NDimArray(self.implementation.transpose()) + return W_NDimArray(self.implementation.transpose(self)) @unwrap_spec(axis1=int, axis2=int) def descr_swapaxes(self, space, axis1, axis2): @@ -308,7 +313,7 @@ """ if self.is_scalar(): return self - return self.implementation.swapaxes(axis1, axis2) + return self.implementation.swapaxes(self, axis1, axis2) def descr_tolist(self, space): if len(self.get_shape()) == 0: @@ -411,6 +416,170 @@ def fdel___pypy_data__(self, space): self.w_pypy_data = None + def descr_argsort(self, space, w_axis=None, w_kind=None, w_order=None): + # happily ignore the kind + # create a contiguous copy of the array + # we must do that, because we need a working set. otherwise + # we would modify the array in-place. Use this to our advantage + # by converting nonnative byte order. + s = self.get_dtype().name + if not self.get_dtype().native: + s = s[1:] + dtype = interp_dtype.get_dtype_cache(space).dtypes_by_name[s] + contig = self.implementation.astype(space, dtype) + return contig.implementation.argsort(space, w_axis) + + def descr_astype(self, space, w_dtype): + dtype = space.interp_w(interp_dtype.W_Dtype, + space.call_function(space.gettypefor(interp_dtype.W_Dtype), w_dtype)) + return self.implementation.astype(space, dtype) + + def descr_get_base(self, space): + impl = self.implementation + ret = impl.base() + if ret is None: + return space.w_None + return ret + + @unwrap_spec(inplace=bool) + def descr_byteswap(self, space, inplace=False): + if inplace: + loop.byteswap(self.implementation, self.implementation) + return self + else: + res = W_NDimArray.from_shape(self.get_shape(), self.get_dtype()) + loop.byteswap(self.implementation, res.implementation) + return res + + @unwrap_spec(mode=str) + def descr_choose(self, space, w_choices, mode='raise', w_out=None): + if w_out is not None and not isinstance(w_out, W_NDimArray): + raise OperationError(space.w_TypeError, space.wrap( + "return arrays must be of ArrayType")) + return interp_arrayops.choose(space, self, w_choices, w_out, mode) + + def descr_clip(self, space, w_min, w_max, w_out=None): + if w_out is not None and not isinstance(w_out, W_NDimArray): + raise OperationError(space.w_TypeError, space.wrap( + "return arrays must be of ArrayType")) + min = convert_to_array(space, w_min) + max = convert_to_array(space, w_max) + shape = shape_agreement_multiple(space, [self, min, max, w_out]) + out = interp_dtype.dtype_agreement(space, [self, min, max], shape, + w_out) + loop.clip(space, self, shape, min, max, out) + return out + + def descr_get_ctypes(self, space): + raise OperationError(space.w_NotImplementedError, space.wrap( + "ctypes not implemented yet")) + + def descr_get_data(self, space): + return self.implementation.get_buffer(space) + + @unwrap_spec(offset=int, axis1=int, axis2=int) + def descr_diagonal(self, space, offset=0, axis1=0, axis2=1): + if len(self.get_shape()) < 2: + raise OperationError(space.w_ValueError, space.wrap( + "need at least 2 dimensions for diagonal")) + if (axis1 < 0 or axis2 < 0 or axis1 >= len(self.get_shape()) or + axis2 >= len(self.get_shape())): + raise operationerrfmt(space.w_ValueError, From noreply at buildbot.pypy.org Thu Feb 7 11:46:07 2013 From: noreply at buildbot.pypy.org (arigo) Date: Thu, 7 Feb 2013 11:46:07 +0100 (CET) Subject: [pypy-commit] pypy default: Try to hide another small difference between pickle and cPickle. Message-ID: <20130207104607.ADDBA1C082E@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r60928:78bc49b20cba Date: 2013-02-07 11:45 +0100 http://bitbucket.org/pypy/pypy/changeset/78bc49b20cba/ Log: Try to hide another small difference between pickle and cPickle. diff --git a/lib_pypy/cPickle.py b/lib_pypy/cPickle.py --- a/lib_pypy/cPickle.py +++ b/lib_pypy/cPickle.py @@ -1,5 +1,5 @@ # -# One-liner implementation of cPickle +# Reimplementation of cPickle, mostly as a copy of pickle.py # from pickle import Pickler, dump, dumps, PickleError, PicklingError, UnpicklingError, _EmptyClass @@ -131,6 +131,13 @@ # Unpickling machinery +class _Stack(list): + def pop(self, index=-1): + try: + return list.pop(self, index) + except IndexError: + raise UnpicklingError("unpickling stack underflow") + class Unpickler(object): def __init__(self, file): @@ -155,7 +162,7 @@ Return the reconstituted object hierarchy specified in the file. """ self.mark = object() # any new unique object - self.stack = [] + self.stack = _Stack() self.append = self.stack.append try: key = ord(self.read(1)) diff --git a/lib_pypy/pypy_test/test_cPickle.py b/lib_pypy/pypy_test/test_cPickle.py new file mode 100644 --- /dev/null +++ b/lib_pypy/pypy_test/test_cPickle.py @@ -0,0 +1,7 @@ +from __future__ import absolute_import +import py + +from lib_pypy import cPickle + +def test_stack_underflow(): + py.test.raises(cPickle.UnpicklingError, cPickle.loads, "a string") From noreply at buildbot.pypy.org Thu Feb 7 11:55:35 2013 From: noreply at buildbot.pypy.org (arigo) Date: Thu, 7 Feb 2013 11:55:35 +0100 (CET) Subject: [pypy-commit] pypy default: Test and fix Message-ID: <20130207105535.E17501C087A@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r60929:45310cdfd89e Date: 2013-02-07 11:55 +0100 http://bitbucket.org/pypy/pypy/changeset/45310cdfd89e/ Log: Test and fix diff --git a/lib_pypy/greenlet.py b/lib_pypy/greenlet.py --- a/lib_pypy/greenlet.py +++ b/lib_pypy/greenlet.py @@ -57,7 +57,8 @@ def __switch(target, methodname, *args): current = getcurrent() # - while not target: + while not (target.__main or _continulet.is_pending(target)): + # inlined __nonzero__ ^^^ in case it's overridden if not target.__started: if methodname == 'switch': greenlet_func = _greenlet_start diff --git a/pypy/module/test_lib_pypy/test_greenlet.py b/pypy/module/test_lib_pypy/test_greenlet.py --- a/pypy/module/test_lib_pypy/test_greenlet.py +++ b/pypy/module/test_lib_pypy/test_greenlet.py @@ -310,3 +310,12 @@ assert g.gr_frame.f_code.co_name == 'f2' g.switch() assert g.gr_frame is None + + def test_override_nonzero(self): + from greenlet import greenlet + class G(greenlet): + def __nonzero__(self): + raise ValueError + g = G(lambda: 42) + x = g.switch() + assert x == 42 From noreply at buildbot.pypy.org Thu Feb 7 12:21:03 2013 From: noreply at buildbot.pypy.org (fijal) Date: Thu, 7 Feb 2013 12:21:03 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: merge default Message-ID: <20130207112103.CC4BC1C0884@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r60930:108aad194d6a Date: 2013-02-07 13:11 +0200 http://bitbucket.org/pypy/pypy/changeset/108aad194d6a/ Log: merge default diff too long, truncating to 2000 out of 5368 lines diff --git a/lib-python/2.7/collections.py b/lib-python/2.7/collections.py --- a/lib-python/2.7/collections.py +++ b/lib-python/2.7/collections.py @@ -6,6 +6,7 @@ __all__ += _abcoll.__all__ from _collections import deque, defaultdict +from operator import itemgetter as _itemgetter from keyword import iskeyword as _iskeyword import sys as _sys import heapq as _heapq @@ -328,7 +329,8 @@ # Execute the template string in a temporary namespace and # support tracing utilities by setting a value for frame.f_globals['__name__'] - namespace = {'__name__': 'namedtuple_%s' % typename} + namespace = {'__name__': 'namedtuple_%s' % typename, + 'OrderedDict': OrderedDict} try: exec template in namespace except SyntaxError, e: diff --git a/lib-python/2.7/test/test_modulefinder.py b/lib-python/2.7/test/test_modulefinder.py --- a/lib-python/2.7/test/test_modulefinder.py +++ b/lib-python/2.7/test/test_modulefinder.py @@ -16,7 +16,7 @@ # library. TEST_DIR = tempfile.mkdtemp() -TEST_PATH = [TEST_DIR, os.path.dirname(__future__.__file__)] +TEST_PATH = [TEST_DIR, os.path.dirname(tempfile.__file__)] # Each test description is a list of 5 items: # diff --git a/lib-python/conftest.py b/lib-python/conftest.py --- a/lib-python/conftest.py +++ b/lib-python/conftest.py @@ -160,7 +160,7 @@ RegrTest('test_codeop.py', core=True), RegrTest('test_coding.py', core=True), RegrTest('test_coercion.py', core=True), - RegrTest('test_collections.py'), + RegrTest('test_collections.py', usemodules='binascii struct'), RegrTest('test_colorsys.py'), RegrTest('test_commands.py'), RegrTest('test_compare.py', core=True), @@ -181,7 +181,7 @@ RegrTest('test_csv.py', usemodules='_csv'), RegrTest('test_ctypes.py', usemodules="_rawffi thread"), RegrTest('test_curses.py'), - RegrTest('test_datetime.py'), + RegrTest('test_datetime.py', usemodules='binascii struct'), RegrTest('test_dbm.py'), RegrTest('test_decimal.py'), RegrTest('test_decorators.py', core=True), diff --git a/lib_pypy/cPickle.py b/lib_pypy/cPickle.py --- a/lib_pypy/cPickle.py +++ b/lib_pypy/cPickle.py @@ -1,5 +1,5 @@ # -# One-liner implementation of cPickle +# Reimplementation of cPickle, mostly as a copy of pickle.py # from pickle import Pickler, dump, dumps, PickleError, PicklingError, UnpicklingError, _EmptyClass @@ -131,6 +131,13 @@ # Unpickling machinery +class _Stack(list): + def pop(self, index=-1): + try: + return list.pop(self, index) + except IndexError: + raise UnpicklingError("unpickling stack underflow") + class Unpickler(object): def __init__(self, file): @@ -155,7 +162,7 @@ Return the reconstituted object hierarchy specified in the file. """ self.mark = object() # any new unique object - self.stack = [] + self.stack = _Stack() self.append = self.stack.append try: key = ord(self.read(1)) diff --git a/lib_pypy/ctypes_support.py b/lib_pypy/ctypes_support.py --- a/lib_pypy/ctypes_support.py +++ b/lib_pypy/ctypes_support.py @@ -19,16 +19,19 @@ if sys.platform == 'win32': standard_c_lib._errno.restype = ctypes.POINTER(ctypes.c_int) + standard_c_lib._errno.argtypes = None def _where_is_errno(): return standard_c_lib._errno() elif sys.platform in ('linux2', 'freebsd6'): standard_c_lib.__errno_location.restype = ctypes.POINTER(ctypes.c_int) + standard_c_lib.__errno_location.argtypes = None def _where_is_errno(): return standard_c_lib.__errno_location() elif sys.platform in ('darwin', 'freebsd7', 'freebsd8', 'freebsd9'): standard_c_lib.__error.restype = ctypes.POINTER(ctypes.c_int) + standard_c_lib.__error.argtypes = None def _where_is_errno(): return standard_c_lib.__error() diff --git a/lib_pypy/greenlet.py b/lib_pypy/greenlet.py --- a/lib_pypy/greenlet.py +++ b/lib_pypy/greenlet.py @@ -57,7 +57,8 @@ def __switch(target, methodname, *args): current = getcurrent() # - while not target: + while not (target.__main or _continulet.is_pending(target)): + # inlined __nonzero__ ^^^ in case it's overridden if not target.__started: if methodname == 'switch': greenlet_func = _greenlet_start diff --git a/lib_pypy/pypy_test/test_cPickle.py b/lib_pypy/pypy_test/test_cPickle.py new file mode 100644 --- /dev/null +++ b/lib_pypy/pypy_test/test_cPickle.py @@ -0,0 +1,7 @@ +from __future__ import absolute_import +import py + +from lib_pypy import cPickle + +def test_stack_underflow(): + py.test.raises(cPickle.UnpicklingError, cPickle.loads, "a string") diff --git a/pypy/conftest.py b/pypy/conftest.py --- a/pypy/conftest.py +++ b/pypy/conftest.py @@ -84,10 +84,11 @@ if self.config.option.runappdirect: # only collect regular tests if we are in an 'app_test' directory, # or in test_lib_pypy - names = self.listnames() - return "app_test" in names or "test_lib_pypy" in names - else: - return True + for name in self.listnames(): + if "app_test" in name or "test_lib_pypy" in name: + return True + return False + return True def funcnamefilter(self, name): if name.startswith('test_'): diff --git a/pypy/doc/arm.rst b/pypy/doc/arm.rst --- a/pypy/doc/arm.rst +++ b/pypy/doc/arm.rst @@ -145,7 +145,7 @@ :: - pypy ~/path_to_pypy_checkout/pypy/translator/goal/translate.py -O1 --platform=arm target.py + pypy ~/path_to_pypy_checkout/rpython/translator/goal/translate.py -O1 --platform=arm target.py If everything worked correctly this should yield an ARM binary. Running this binary in the ARM chroot or on an ARM device should produce the output ``"Hello World"``. diff --git a/pypy/doc/coding-guide.rst b/pypy/doc/coding-guide.rst --- a/pypy/doc/coding-guide.rst +++ b/pypy/doc/coding-guide.rst @@ -832,7 +832,7 @@ for the next milestone, both from an E-Mail and from a web interface. -.. _`development tracker`: https://codespeak.net/issue/pypy-dev/ +.. _`development tracker`: https://bugs.pypy.org/ use your codespeak login or register ------------------------------------ @@ -841,7 +841,7 @@ tracker. Else, you can `register with the tracker`_ easily. -.. _`register with the tracker`: https://codespeak.net/issue/pypy-dev/user?@template=register +.. _`register with the tracker`: https://bugs.pypy.org/user?@template=register .. _`roundup`: http://roundup.sourceforge.net/ diff --git a/pypy/doc/confrest.py b/pypy/doc/confrest.py --- a/pypy/doc/confrest.py +++ b/pypy/doc/confrest.py @@ -4,7 +4,8 @@ from confrest_oldpy import Project, Page, relpath html = py.xml.html -class PyPyPage(Page): + +class PyPyPage(Page): googlefragment = """ """ + def fill_menubar(self): self.menubar = html.div( - html.a("home", - href=self.get_doclink("index.html"), - class_="menu"), + html.a("home", + href=self.get_doclink("index.html"), + class_="menu"), " ", html.a("blog", href="http://morepypy.blogspot.com", class_="menu"), - " ", + " ", html.a("getting-started", href=self.get_doclink("getting-started.html"), - class_="menu"), + class_="menu"), " ", html.a("documentation", href=self.get_doclink("docindex.html"), class_="menu"), - " ", + " ", html.a("hg", href="https://bitbucket.org/pypy/pypy", class_="menu"), - " ", + " ", html.a("issues", - href="https://codespeak.net/issue/pypy-dev/", + href="https://bugs.pypy.org/", class_="menu"), " ", id="menubar") @@ -43,25 +45,25 @@ return relpath(self.targetpath.strpath, self.project.docpath.join(target).strpath) - def unicode(self, doctype=True): - page = self._root.unicode() + def unicode(self, doctype=True): + page = self._root.unicode() page = page.replace("", self.googlefragment + "") - if doctype: - return self.doctype + page - else: - return page - + if doctype: + return self.doctype + page + else: + return page -class Project(Project): + +class Project(Project): mydir = py.path.local(__file__).dirpath() - title = "PyPy" + title = "PyPy" stylesheet = 'style.css' - encoding = 'latin1' + encoding = 'latin1' prefix_title = "PyPy" logo = html.div( html.a( - html.img(alt="PyPy", id="pyimg", - src="http://codespeak.net/pypy/img/py-web1.png", + html.img(alt="PyPy", id="pyimg", + src="http://codespeak.net/pypy/img/py-web1.png", height=110, width=149))) - Page = PyPyPage + Page = PyPyPage diff --git a/pypy/doc/cppyy.rst b/pypy/doc/cppyy.rst --- a/pypy/doc/cppyy.rst +++ b/pypy/doc/cppyy.rst @@ -86,10 +86,10 @@ $ hg clone https://bitbucket.org/pypy/pypy $ cd pypy $ hg up reflex-support # optional - $ cd pypy/translator/goal + $ cd pypy/goal # This example shows python, but using pypy-c is faster and uses less memory - $ python translate.py -O jit --gcrootfinder=shadowstack targetpypystandalone.py --withmod-cppyy + $ python ../../rpython/bin/rpython.py -O jit --gcrootfinder=shadowstack targetpypystandalone.py --withmod-cppyy This will build a ``pypy-c`` that includes the cppyy module, and through that, Reflex support. diff --git a/pypy/doc/ctypes-implementation.rst b/pypy/doc/ctypes-implementation.rst --- a/pypy/doc/ctypes-implementation.rst +++ b/pypy/doc/ctypes-implementation.rst @@ -113,7 +113,7 @@ The pypy-c translated to run the ctypes tests can be used to run the pyglet examples as well. They can be run like e.g.:: $ cd pyglet/ - $ PYTHONPATH=. ../ctypes-stable/pypy/translator/goal/pypy-c examples/opengl.py + $ PYTHONPATH=. ../ctypes-stable/pypy/goal/pypy-c examples/opengl.py they usually should be terminated with ctrl-c. Refer to the their doc strings for details about how they should behave. diff --git a/pypy/doc/getting-started-dev.rst b/pypy/doc/getting-started-dev.rst --- a/pypy/doc/getting-started-dev.rst +++ b/pypy/doc/getting-started-dev.rst @@ -24,7 +24,7 @@ python bin/translatorshell.py Test snippets of translatable code are provided in the file -``pypy/translator/test/snippet.py``, which is imported under the name +``rpython/translator/test/snippet.py``, which is imported under the name ``snippet``. For example:: >>> t = Translation(snippet.is_perfect_number, [int]) @@ -52,16 +52,18 @@ The graph can be turned into C code:: >>> t.rtype() - >>> f = t.compile_c() + >>> lib = t.compile_c() The first command replaces the operations with other low level versions that -only use low level types that are available in C (e.g. int). To try out the -compiled version:: +only use low level types that are available in C (e.g. int). The compiled +version is now in a ``.so`` library. You can run it say using ctypes: + >>> from ctypes import CDLL + >>> f = CDLL(lib) >>> f(5) - False + 0 >>> f(6) - True + 1 Translating the flow graph to CLI or JVM code +++++++++++++++++++++++++++++++++++++++++++++ @@ -108,7 +110,7 @@ There is a small-to-medium demo showing the translator and the annotator:: cd demo - ../pypy/translator/goal/translate.py --view --annotate bpnn.py + ../rpython/translator/goal/translate.py --view --annotate bpnn.py This causes ``bpnn.py`` to display itself as a call graph and class hierarchy. Clicking on functions shows the flow graph of the particular @@ -119,17 +121,17 @@ To turn this example to C code (compiled to the executable ``bpnn-c``), type simply:: - ../pypy/translator/goal/translate.py bpnn.py + ../rpython/translator/goal/translate.py bpnn.py Translating Full Programs +++++++++++++++++++++++++ To translate full RPython programs, there is the script ``translate.py`` in -``translator/goal``. Examples for this are a slightly changed version of +``rpython/translator/goal``. Examples for this are a slightly changed version of Pystone:: - cd pypy/translator/goal + cd rpython/translator/goal python translate.py targetrpystonedalone This will produce the executable "targetrpystonedalone-c". diff --git a/pypy/doc/getting-started.rst b/pypy/doc/getting-started.rst --- a/pypy/doc/getting-started.rst +++ b/pypy/doc/getting-started.rst @@ -1,10 +1,10 @@ ================================== -Getting Started +Getting Started ================================== .. contents:: -.. _howtopypy: +.. _howtopypy: What is PyPy ? ============== @@ -33,8 +33,8 @@ .. _`RPython translation toolchain`: translation.html .. _`more...`: architecture.html -Just the facts -============== +Just the facts +============== Download a pre-built PyPy ------------------------- @@ -125,7 +125,7 @@ ``pypy/pypy`` and documentation files in ``pypy/pypy/doc``. We try to ensure that the tip is always stable, but it might occasionally be broken. You may want to check out `our nightly tests:`_ -find a revision (12-chars alphanumeric string, e.g. "963e808156b3") +find a revision (12-chars alphanumeric string, e.g. "963e808156b3") that passed at least the ``{linux32}`` tests (corresponding to a ``+`` sign on the line ``success``) and then, in your cloned repository, switch to this revision @@ -159,24 +159,24 @@ Understanding PyPy's architecture --------------------------------- -For in-depth information about architecture and coding documentation -head over to the `documentation section`_ where you'll find lots of -interesting information. Additionally, in true hacker spirit, you -may just `start reading sources`_ . +For in-depth information about architecture and coding documentation +head over to the `documentation section`_ where you'll find lots of +interesting information. Additionally, in true hacker spirit, you +may just `start reading sources`_ . .. _`documentation section`: index.html#project-documentation .. _`start reading sources`: getting-started-dev.html#start-reading-sources -Filing bugs or feature requests +Filing bugs or feature requests ------------------------------- You may file `bug reports`_ on our issue tracker which is -also accessible through the 'issues' top menu of -the PyPy website. `Using the development tracker`_ has -more detailed information on specific features of the tracker. +also accessible through the 'issues' top menu of +the PyPy website. `Using the development tracker`_ has +more detailed information on specific features of the tracker. .. _`Using the development tracker`: coding-guide.html#using-development-tracker -.. _bug reports: https://codespeak.net/issue/pypy-dev/ +.. _bug reports: https://bugs.pypy.org/ .. include:: _ref.txt diff --git a/pypy/doc/index.rst b/pypy/doc/index.rst --- a/pypy/doc/index.rst +++ b/pypy/doc/index.rst @@ -220,9 +220,8 @@ ================================ =========================================== Directory explanation/links ================================ =========================================== -`pypy/annotation/`_ `type inferencing code`_ for `RPython`_ programs -`pypy/bin/`_ command-line scripts, mainly `py.py`_ and `translatorshell.py`_ +`pypy/bin/`_ command-line scripts, mainly `pyinteractive.py`_ `pypy/config/`_ handles the numerous options for building and running PyPy @@ -249,20 +248,8 @@ `pypy/objspace/`_ `object space`_ implementations -`pypy/objspace/flow/`_ the FlowObjSpace_ implementing `abstract interpretation`_ - `pypy/objspace/std/`_ the StdObjSpace_ implementing CPython's objects and types -`pypy/rlib/`_ a `"standard library"`_ for RPython_ programs - -`pypy/rpython/`_ the `RPython Typer`_ - -`pypy/rpython/lltypesystem/`_ the `low-level type system`_ for C-like backends - -`pypy/rpython/ootypesystem/`_ the `object-oriented type system`_ for OO backends - -`pypy/rpython/memory/`_ the `garbage collector`_ construction framework - `pypy/tool/`_ various utilities and hacks used from various places `pypy/tool/algo/`_ general-purpose algorithmic and mathematic @@ -270,20 +257,39 @@ `pypy/tool/pytest/`_ support code for our `testing methods`_ -`pypy/translator/`_ translation_ backends and support code -`pypy/translator/backendopt/`_ general optimizations that run before a backend generates code +`rpython/annotator/`_ `type inferencing code`_ for `RPython`_ programs -`pypy/translator/c/`_ the `GenC backend`_, producing C code from an +`rpython/config/`_ handles the numerous options for RPython + + +`rpython/flowspace/`_ the FlowObjSpace_ implementing `abstract interpretation`_ + + +`rpython/rlib/`_ a `"standard library"`_ for RPython_ programs + +`rpython/rtyper/`_ the `RPython Typer`_ + +`rpython/rtyper/lltypesystem/`_ the `low-level type system`_ for C-like backends + +`rpython/rtyper/ootypesystem/`_ the `object-oriented type system`_ for OO backends + +`rpython/rtyper/memory/`_ the `garbage collector`_ construction framework + +`rpython/translator/`_ translation_ backends and support code + +`rpython/translator/backendopt/`_ general optimizations that run before a backend generates code + +`rpython/translator/c/`_ the `GenC backend`_, producing C code from an RPython program (generally via the rtyper_) -`pypy/translator/cli/`_ the `CLI backend`_ for `.NET`_ (Microsoft CLR or Mono_) +`rpython/translator/cli/`_ the `CLI backend`_ for `.NET`_ (Microsoft CLR or Mono_) -`pypy/translator/goal/`_ our `main PyPy-translation scripts`_ live here +`pypy/goal/`_ our `main PyPy-translation scripts`_ live here -`pypy/translator/jvm/`_ the Java backend +`rpython/translator/jvm/`_ the Java backend -`pypy/translator/tool/`_ helper tools for translation, including the Pygame +`rpython/translator/tool/`_ helper tools for translation, including the Pygame `graph viewer`_ ``*/test/`` many directories have a test subdirectory containing test diff --git a/pypy/doc/sandbox.rst b/pypy/doc/sandbox.rst --- a/pypy/doc/sandbox.rst +++ b/pypy/doc/sandbox.rst @@ -87,15 +87,15 @@ ----- -In pypy/translator/goal:: +In pypy/goal:: - ./translate.py -O2 --sandbox targetpypystandalone.py + ../../rpython/bin/rpython -O2 --sandbox targetpypystandalone.py If you don't have a regular PyPy installed, you should, because it's faster to translate, but you can also run ``python translate.py`` instead. -To run it, use the tools in the pypy/translator/sandbox directory:: +To run it, use the tools in the pypy/sandbox directory:: ./pypy_interact.py /some/path/pypy-c-sandbox [args...] diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst --- a/pypy/doc/whatsnew-head.rst +++ b/pypy/doc/whatsnew-head.rst @@ -37,6 +37,7 @@ .. branch: fix-e4fa0b2 .. branch: win32-fixes .. branch: fix-version-tool +.. branch: popen2-removal .. branch: release-2.0-beta1 @@ -50,3 +51,6 @@ .. branch: inline-virtualref-2 Better optimized certain types of frame accesses in the JIT, particularly around exceptions that escape the function they were raised in. + +.. branch: missing-ndarray-attributes +Some missing attributes from ndarrays diff --git a/pypy/interpreter/pytraceback.py b/pypy/interpreter/pytraceback.py --- a/pypy/interpreter/pytraceback.py +++ b/pypy/interpreter/pytraceback.py @@ -1,5 +1,6 @@ from pypy.interpreter import baseobjspace from pypy.interpreter.error import OperationError + from rpython.tool.error import offset2lineno @@ -27,10 +28,10 @@ def descr__reduce__(self, space): from pypy.interpreter.mixedmodule import MixedModule - w_mod = space.getbuiltinmodule('_pickle_support') - mod = space.interp_w(MixedModule, w_mod) + w_mod = space.getbuiltinmodule('_pickle_support') + mod = space.interp_w(MixedModule, w_mod) new_inst = mod.get('traceback_new') - w = space.wrap + w = space.wrap tup_base = [] tup_state = [ @@ -49,6 +50,7 @@ self.lasti = space.int_w(w_lasti) self.next = space.interp_w(PyTraceback, w_next, can_be_None=True) + def record_application_traceback(space, operror, frame, last_instruction): if frame.pycode.hidden_applevel: return @@ -56,10 +58,11 @@ tb = PyTraceback(space, frame, last_instruction, tb) operror.set_traceback(tb) + def check_traceback(space, w_tb, msg): from pypy.interpreter.typedef import PyTraceback tb = space.interpclass_w(w_tb) - if tb is None or not space.is_true(space.isinstance(tb, + if tb is None or not space.is_true(space.isinstance(tb, space.gettypeobject(PyTraceback.typedef))): raise OperationError(space.w_TypeError, space.wrap(msg)) return tb diff --git a/pypy/interpreter/typedef.py b/pypy/interpreter/typedef.py --- a/pypy/interpreter/typedef.py +++ b/pypy/interpreter/typedef.py @@ -1,18 +1,17 @@ -""" +import py - -""" -import py -from pypy.interpreter.gateway import interp2app, BuiltinCode, unwrap_spec,\ - WrappedDefault from pypy.interpreter.argument import Arguments from pypy.interpreter.baseobjspace import Wrappable, DescrMismatch from pypy.interpreter.error import OperationError, operationerrfmt +from pypy.interpreter.gateway import (interp2app, BuiltinCode, unwrap_spec, + WrappedDefault) + +from rpython.rlib.jit import promote +from rpython.rlib.objectmodel import compute_identity_hash, specialize from rpython.tool.sourcetools import compile2, func_with_new_name -from rpython.rlib.objectmodel import instantiate, compute_identity_hash, specialize -from rpython.rlib.jit import promote -class TypeDef: + +class TypeDef(object): def __init__(self, __name, __base=None, __total_ordering__=None, **rawdict): "NOT_RPYTHON: initialization-time only" self.name = __name @@ -27,7 +26,7 @@ self.weakrefable = '__weakref__' in rawdict self.doc = rawdict.pop('__doc__', None) for base in bases: - self.hasdict |= base.hasdict + self.hasdict |= base.hasdict self.weakrefable |= base.weakrefable self.rawdict = {} self.acceptable_as_base_class = '__new__' in rawdict @@ -426,7 +425,7 @@ return unknown_objclass_getter, cls miniglobals = {} if isinstance(cls, str): - assert cls.startswith('<'),"pythontype typecheck should begin with <" + assert cls.startswith('<'), "pythontype typecheck should begin with <" cls_name = cls[1:] typeexpr = "space.w_%s" % cls_name else: @@ -474,7 +473,7 @@ else: try: return self.fget(self, space, w_obj) - except DescrMismatch, e: + except DescrMismatch: return w_obj.descr_call_mismatch( space, '__getattribute__', self.reqcls, Arguments(space, [w_obj, @@ -489,7 +488,7 @@ space.wrap("readonly attribute")) try: fset(self, space, w_obj, w_value) - except DescrMismatch, e: + except DescrMismatch: w_obj.descr_call_mismatch( space, '__setattr__', self.reqcls, Arguments(space, [w_obj, @@ -505,7 +504,7 @@ space.wrap("cannot delete attribute")) try: fdel(self, space, w_obj) - except DescrMismatch, e: + except DescrMismatch: w_obj.descr_call_mismatch( space, '__delattr__', self.reqcls, Arguments(space, [w_obj, @@ -546,6 +545,7 @@ class Member(Wrappable): """For slots.""" _immutable_ = True + def __init__(self, index, name, w_cls): self.index = index self.name = name @@ -617,9 +617,8 @@ from pypy.interpreter.pyframe import PyFrame from pypy.interpreter.pyopcode import SuspendedUnroller from pypy.interpreter.module import Module -from pypy.interpreter.function import Function, Method, StaticMethod -from pypy.interpreter.function import ClassMethod -from pypy.interpreter.function import BuiltinFunction, descr_function_get +from pypy.interpreter.function import (Function, Method, StaticMethod, + ClassMethod, BuiltinFunction, descr_function_get) from pypy.interpreter.pytraceback import PyTraceback from pypy.interpreter.generator import GeneratorIterator from pypy.interpreter.nestedscope import Cell @@ -663,8 +662,10 @@ def fget_co_flags(space, code): # unwrapping through unwrap_spec sig = code.signature() flags = 0 - if sig.has_vararg(): flags |= CO_VARARGS - if sig.has_kwarg(): flags |= CO_VARKEYWORDS + if sig.has_vararg(): + flags |= CO_VARARGS + if sig.has_kwarg(): + flags |= CO_VARKEYWORDS return space.wrap(flags) def fget_co_consts(space, code): # unwrapping through unwrap_spec @@ -728,7 +729,7 @@ __eq__ = interp2app(PyCode.descr_code__eq__), __ne__ = descr_generic_ne, __hash__ = interp2app(PyCode.descr_code__hash__), - __reduce__ = interp2app(PyCode.descr__reduce__), + __reduce__ = interp2app(PyCode.descr__reduce__), __repr__ = interp2app(PyCode.repr), co_argcount = interp_attrproperty('co_argcount', cls=PyCode), co_nlocals = interp_attrproperty('co_nlocals', cls=PyCode), @@ -737,9 +738,9 @@ co_code = interp_attrproperty('co_code', cls=PyCode), co_consts = GetSetProperty(PyCode.fget_co_consts), co_names = GetSetProperty(PyCode.fget_co_names), - co_varnames = GetSetProperty(PyCode.fget_co_varnames), - co_freevars = GetSetProperty(PyCode.fget_co_freevars), - co_cellvars = GetSetProperty(PyCode.fget_co_cellvars), + co_varnames = GetSetProperty(PyCode.fget_co_varnames), + co_freevars = GetSetProperty(PyCode.fget_co_freevars), + co_cellvars = GetSetProperty(PyCode.fget_co_cellvars), co_filename = interp_attrproperty('co_filename', cls=PyCode), co_name = interp_attrproperty('co_name', cls=PyCode), co_firstlineno = interp_attrproperty('co_firstlineno', cls=PyCode), @@ -749,7 +750,7 @@ PyCode.typedef.acceptable_as_base_class = False PyFrame.typedef = TypeDef('frame', - __reduce__ = interp2app(PyFrame.descr__reduce__), + __reduce__ = interp2app(PyFrame.descr__reduce__), __setstate__ = interp2app(PyFrame.descr__setstate__), f_builtins = GetSetProperty(PyFrame.fget_f_builtins), f_lineno = GetSetProperty(PyFrame.fget_f_lineno, PyFrame.fset_f_lineno), @@ -827,9 +828,9 @@ __new__ = interp2app(Method.descr_method__new__.im_func), __call__ = interp2app(Method.descr_method_call), __get__ = interp2app(Method.descr_method_get), - im_func = interp_attrproperty_w('w_function', cls=Method), + im_func = interp_attrproperty_w('w_function', cls=Method), __func__ = interp_attrproperty_w('w_function', cls=Method), - im_self = interp_attrproperty_w('w_instance', cls=Method), + im_self = interp_attrproperty_w('w_instance', cls=Method), __self__ = interp_attrproperty_w('w_instance', cls=Method), im_class = interp_attrproperty_w('w_class', cls=Method), __getattribute__ = interp2app(Method.descr_method_getattribute), @@ -886,7 +887,7 @@ def always_none(self, obj): return None -BuiltinFunction.typedef = TypeDef("builtin_function",**Function.typedef.rawdict) +BuiltinFunction.typedef = TypeDef("builtin_function", **Function.typedef.rawdict) BuiltinFunction.typedef.rawdict.update({ '__new__': interp2app(BuiltinFunction.descr_builtinfunction__new__.im_func), '__self__': GetSetProperty(always_none, cls=BuiltinFunction), @@ -897,12 +898,12 @@ BuiltinFunction.typedef.acceptable_as_base_class = False PyTraceback.typedef = TypeDef("traceback", - __reduce__ = interp2app(PyTraceback.descr__reduce__), + __reduce__ = interp2app(PyTraceback.descr__reduce__), __setstate__ = interp2app(PyTraceback.descr__setstate__), - tb_frame = interp_attrproperty('frame', cls=PyTraceback), - tb_lasti = interp_attrproperty('lasti', cls=PyTraceback), + tb_frame = interp_attrproperty('frame', cls=PyTraceback), + tb_lasti = interp_attrproperty('lasti', cls=PyTraceback), tb_lineno = GetSetProperty(PyTraceback.descr_tb_lineno), - tb_next = interp_attrproperty('next', cls=PyTraceback), + tb_next = interp_attrproperty('next', cls=PyTraceback), ) PyTraceback.typedef.acceptable_as_base_class = False @@ -937,12 +938,12 @@ Cell.typedef.acceptable_as_base_class = False Ellipsis.typedef = TypeDef("Ellipsis", - __repr__ = interp2app(Ellipsis.descr__repr__), + __repr__ = interp2app(Ellipsis.descr__repr__), ) Ellipsis.typedef.acceptable_as_base_class = False NotImplemented.typedef = TypeDef("NotImplemented", - __repr__ = interp2app(NotImplemented.descr__repr__), + __repr__ = interp2app(NotImplemented.descr__repr__), ) NotImplemented.typedef.acceptable_as_base_class = False diff --git a/pypy/module/bz2/test/test_bz2_compdecomp.py b/pypy/module/bz2/test/test_bz2_compdecomp.py --- a/pypy/module/bz2/test/test_bz2_compdecomp.py +++ b/pypy/module/bz2/test/test_bz2_compdecomp.py @@ -12,7 +12,7 @@ if os.name == "nt": from py.test import skip skip("bz2 module is not available on Windows") - + def setup_module(mod): DATA = 'BZh91AY&SY.\xc8N\x18\x00\x01>_\x80\x00\x10@\x02\xff\xf0\x01\x07n\x00?\xe7\xff\xe00\x01\x99\xaa\x00\xc0\x03F\x86\x8c#&\x83F\x9a\x03\x06\xa6\xd0\xa6\x93M\x0fQ\xa7\xa8\x06\x804hh\x12$\x11\xa4i4\xf14S\xd2\x88\xe5\xcd9gd6\x0b\n\xe9\x9b\xd5\x8a\x99\xf7\x08.K\x8ev\xfb\xf7xw\xbb\xdf\xa1\x92\xf1\xdd|/";\xa2\xba\x9f\xd5\xb1#A\xb6\xf6\xb3o\xc9\xc5y\\\xebO\xe7\x85\x9a\xbc\xb6f8\x952\xd5\xd7"%\x89>V,\xf7\xa6z\xe2\x9f\xa3\xdf\x11\x11"\xd6E)I\xa9\x13^\xca\xf3r\xd0\x03U\x922\xf26\xec\xb6\xed\x8b\xc3U\x13\x9d\xc5\x170\xa4\xfa^\x92\xacDF\x8a\x97\xd6\x19\xfe\xdd\xb8\xbd\x1a\x9a\x19\xa3\x80ankR\x8b\xe5\xd83]\xa9\xc6\x08\x82f\xf6\xb9"6l$\xb8j@\xc0\x8a\xb0l1..\xbak\x83ls\x15\xbc\xf4\xc1\x13\xbe\xf8E\xb8\x9d\r\xa8\x9dk\x84\xd3n\xfa\xacQ\x07\xb1%y\xaav\xb4\x08\xe0z\x1b\x16\xf5\x04\xe9\xcc\xb9\x08z\x1en7.G\xfc]\xc9\x14\xe1B@\xbb!8`' @@ -54,27 +54,27 @@ def test_creation(self): from bz2 import BZ2Compressor - + raises(TypeError, BZ2Compressor, "foo") raises(ValueError, BZ2Compressor, 10) - + BZ2Compressor(1) BZ2Compressor(9) - + def test_compress(self): from bz2 import BZ2Compressor - + bz2c = BZ2Compressor() raises(TypeError, bz2c.compress) data = bz2c.compress(self.TEXT) data = "%s%s" % (data, bz2c.flush()) assert self.decompress(data) == self.TEXT - + def test_compress_huge_data(self): if not self.HUGE_OK: skip("skipping test requiring lots of memory") - from bz2 import BZ2Compressor - + from bz2 import BZ2Compressor + HUGE_DATA = self.TEXT * 10000 bz2c = BZ2Compressor() raises(TypeError, bz2c.compress) @@ -83,8 +83,8 @@ assert self.decompress(data) == HUGE_DATA def test_compress_chunks_10(self): - from bz2 import BZ2Compressor - + from bz2 import BZ2Compressor + bz2c = BZ2Compressor() n = 0 data = "" @@ -112,23 +112,23 @@ cls.w_TEXT = cls.space.wrap(TEXT) cls.w_DATA = cls.space.wrap(DATA) cls.w_BUGGY_DATA = cls.space.wrap(BUGGY_DATA) - + def test_creation(self): from bz2 import BZ2Decompressor - + raises(TypeError, BZ2Decompressor, "foo") - + BZ2Decompressor() - + def test_attribute(self): from bz2 import BZ2Decompressor - + bz2d = BZ2Decompressor() assert bz2d.unused_data == "" def test_decompress(self): from bz2 import BZ2Decompressor - + bz2d = BZ2Decompressor() raises(TypeError, bz2d.decompress) decompressed_data = bz2d.decompress(self.DATA) @@ -136,7 +136,7 @@ def test_decompress_chunks_10(self): from bz2 import BZ2Decompressor - + bz2d = BZ2Decompressor() decompressed_data = "" n = 0 @@ -146,13 +146,13 @@ break decompressed_data = "%s%s" % (decompressed_data, bz2d.decompress(temp)) n += 1 - + assert decompressed_data == self.TEXT - + def test_decompress_unused_data(self): # test with unused data. (data after EOF) from bz2 import BZ2Decompressor - + bz2d = BZ2Decompressor() unused_data = "this is unused data" decompressed_data = bz2d.decompress(self.DATA + unused_data) @@ -161,7 +161,7 @@ def test_EOF_error(self): from bz2 import BZ2Decompressor - + bz2d = BZ2Decompressor() bz2d.decompress(self.DATA) raises(EOFError, bz2d.decompress, "foo") @@ -195,11 +195,11 @@ def test_compress_function(self): from bz2 import compress - + raises(TypeError, compress, 123) raises(ValueError, compress, "foo", 10) raises(TypeError, compress, "foo", "foo") - + data = compress(self.TEXT) assert self.decompress(data) == self.TEXT @@ -207,7 +207,7 @@ if not self.HUGE_OK: skip("skipping test requiring lots of memory") from bz2 import compress - + HUGE_DATA = self.TEXT * 10000 data = compress(HUGE_DATA) @@ -215,7 +215,7 @@ def test_decompress_function(self): import bz2 - + raises(TypeError, bz2.decompress) assert bz2.decompress("") == "" decompressed_data = bz2.decompress(self.DATA) diff --git a/pypy/module/bz2/test/test_bz2_file.py b/pypy/module/bz2/test/test_bz2_file.py --- a/pypy/module/bz2/test/test_bz2_file.py +++ b/pypy/module/bz2/test/test_bz2_file.py @@ -6,6 +6,7 @@ import py from pypy.interpreter.gateway import unwrap_spec, interp2app +from pypy.module.bz2.test.support import CheckAllocation if os.name == "nt": @@ -50,10 +51,7 @@ mod.RANDOM_DATA = ''.join([s[int(random.random() * len(s))] for i in range(30000)]) -class AppTestBZ2File: #(CheckAllocation): - # XXX for unknown reasons, we cannot do allocation checks, as sth is - # keeping those objects alive (BZ2File objects) - +class AppTestBZ2File(CheckAllocation): spaceconfig = { "usemodules": ["bz2", "binascii", "rctime"] } @@ -85,15 +83,15 @@ assert bz2f.closed == False bz2f.close() assert bz2f.closed == True - + def test_creation(self): from bz2 import BZ2File - + raises(ValueError, BZ2File, self.temppath, mode='w', compresslevel=10) raises(ValueError, BZ2File, self.temppath, mode='XYZ') # XXX the following is fine, currently: #raises(ValueError, BZ2File, self.temppath, mode='ww') - + BZ2File(self.temppath, mode='wU', buffering=0, compresslevel=8) BZ2File(self.temppath, mode='wb') # a large buf size @@ -101,50 +99,50 @@ def test_close(self): from bz2 import BZ2File - + # writeonly bz2f = BZ2File(self.temppath, mode='w') bz2f.close() - # since we use fclose() internally you can't close it twice - # bz2f.close() - + bz2f.close() + # readonly bz2f = BZ2File(self.temppath, mode='r') bz2f.close() - + bz2f.close() + def test_tell(self): from bz2 import BZ2File - + bz2f = BZ2File(self.temppath, mode='w') bz2f.close() raises(ValueError, bz2f.tell) - + bz2f = BZ2File(self.temppath, mode='w') pos = bz2f.tell() bz2f.close() assert pos == 0 - + def test_seek(self): from bz2 import BZ2File - + # hack to create a foo file open(self.temppath, "w").close() - + # cannot seek if close bz2f = BZ2File(self.temppath, mode='r') bz2f.close() raises(ValueError, bz2f.seek, 0) - + # cannot seek if 'w' bz2f = BZ2File(self.temppath, mode='w') raises(IOError, bz2f.seek, 0) bz2f.close() - + bz2f = BZ2File(self.temppath, mode='r') raises(TypeError, bz2f.seek) raises(TypeError, bz2f.seek, "foo") raises(TypeError, bz2f.seek, 0, "foo") - + bz2f.seek(0) assert bz2f.tell() == 0 del bz2f # delete from this frame, which is captured in the traceback @@ -152,21 +150,21 @@ def test_open_close_del(self): from bz2 import BZ2File self.create_temp_file() - + for i in range(10): f = BZ2File(self.temppath) f.close() del f - + def test_open_non_existent(self): from bz2 import BZ2File raises(IOError, BZ2File, "/non/existent/path") - + def test_open_mode_U(self): # bug #1194181: bz2.BZ2File opened for write with mode "U" from bz2 import BZ2File self.create_temp_file() - + bz2f = BZ2File(self.temppath, "U") bz2f.close() f = open(self.temppath) @@ -174,7 +172,7 @@ f.read() assert f.tell() == len(self.DATA) f.close() - + def test_seek_forward(self): from bz2 import BZ2File self.create_temp_file() @@ -214,7 +212,7 @@ assert bz2f.tell() == len(self.TEXT) assert bz2f.read() == "" bz2f.close() - + def test_seek_post_end_twice(self): from bz2 import BZ2File self.create_temp_file() @@ -240,10 +238,9 @@ from bz2 import BZ2File from cStringIO import StringIO self.create_temp_file() - + bz2f = BZ2File(self.temppath) - # XXX - #raises(TypeError, bz2f.readline, None) + raises(TypeError, bz2f.readline, None) sio = StringIO(self.TEXT) for line in sio.readlines(): line_read = bz2f.readline() @@ -253,10 +250,9 @@ def test_read(self): from bz2 import BZ2File self.create_temp_file() - + bz2f = BZ2File(self.temppath) - # XXX - # raises(TypeError, bz2f.read, None) + raises(TypeError, bz2f.read, None) text_read = bz2f.read() assert text_read == self.TEXT bz2f.close() @@ -291,7 +287,7 @@ def test_read_chunk9(self): from bz2 import BZ2File self.create_temp_file() - + bz2f = BZ2File(self.temppath) text_read = "" while True: @@ -305,7 +301,7 @@ def test_read_100_bytes(self): from bz2 import BZ2File self.create_temp_file() - + bz2f = BZ2File(self.temppath) assert bz2f.read(100) == self.TEXT[:100] bz2f.close() @@ -313,7 +309,7 @@ def test_universal_newlines_lf(self): from bz2 import BZ2File self.create_temp_file() - + bz2f = BZ2File(self.temppath, "rU") assert bz2f.read() == self.TEXT assert bz2f.newlines == "\n" @@ -322,7 +318,7 @@ def test_universal_newlines_crlf(self): from bz2 import BZ2File self.create_temp_file(crlf=True) - + bz2f = BZ2File(self.temppath, "rU") data = bz2f.read() assert data == self.TEXT @@ -333,10 +329,9 @@ from bz2 import BZ2File from cStringIO import StringIO self.create_temp_file() - + bz2f = BZ2File(self.temppath) - # XXX - #raises(TypeError, bz2f.readlines, None) + raises(TypeError, bz2f.readlines, None) sio = StringIO(self.TEXT) assert bz2f.readlines() == sio.readlines() bz2f.close() @@ -345,17 +340,17 @@ from bz2 import BZ2File from cStringIO import StringIO self.create_temp_file() - + bz2f = BZ2File(self.temppath) sio = StringIO(self.TEXT) assert list(iter(bz2f)) == sio.readlines() bz2f.close() - + def test_xreadlines(self): from bz2 import BZ2File from cStringIO import StringIO self.create_temp_file() - + bz2f = BZ2File(self.temppath) sio = StringIO(self.TEXT) assert list(bz2f.xreadlines()) == sio.readlines() @@ -364,12 +359,12 @@ def test_readlines_bug_1191043(self): # readlines()/xreadlines() for files containing no newline from bz2 import BZ2File - + DATA = 'BZh91AY&SY\xd9b\x89]\x00\x00\x00\x03\x80\x04\x00\x02\x00\x0c\x00 \x00!\x9ah3M\x13<]\xc9\x14\xe1BCe\x8a%t' f = open(self.temppath, "wb") f.write(DATA) f.close() - + bz2f = BZ2File(self.temppath) lines = bz2f.readlines() bz2f.close() @@ -379,7 +374,7 @@ xlines = list(bz2f.xreadlines()) bz2f.close() assert xlines == ['Test'] - + def test_write(self): from bz2 import BZ2File @@ -387,7 +382,7 @@ raises(TypeError, bz2f.write) bz2f.write(self.TEXT) bz2f.close() - + f = open(self.temppath, "rb") assert self.decompress(f.read()) == self.TEXT f.close() @@ -401,11 +396,11 @@ data = self.TEXT[n * 10:(n + 1) * 10] if not data: break - + bz2f.write(data) n += 1 bz2f.close() - + f = open(self.temppath, "rb") assert self.decompress(f.read()) == self.TEXT f.close() @@ -422,7 +417,7 @@ f = open(self.temppath, "rb") assert self.decompress(f.read()) == self.TEXT f.close() - + def test_write_methods_on_readonly_file(self): from bz2 import BZ2File @@ -453,8 +448,8 @@ assert data == "abc" assert f.closed - - + + # has_cmdline_bunzip2 = sys.platform not in ("win32", "os2emx", "riscos") # # if has_cmdline_bunzip2: diff --git a/pypy/module/imp/__init__.py b/pypy/module/imp/__init__.py --- a/pypy/module/imp/__init__.py +++ b/pypy/module/imp/__init__.py @@ -6,12 +6,14 @@ __import__ function. """ interpleveldefs = { + 'SEARCH_ERROR': 'space.wrap(importing.SEARCH_ERROR)', 'PY_SOURCE': 'space.wrap(importing.PY_SOURCE)', 'PY_COMPILED': 'space.wrap(importing.PY_COMPILED)', 'C_EXTENSION': 'space.wrap(importing.C_EXTENSION)', 'PKG_DIRECTORY': 'space.wrap(importing.PKG_DIRECTORY)', 'C_BUILTIN': 'space.wrap(importing.C_BUILTIN)', 'PY_FROZEN': 'space.wrap(importing.PY_FROZEN)', + 'IMP_HOOK': 'space.wrap(importing.IMP_HOOK)', 'get_suffixes': 'interp_imp.get_suffixes', 'get_magic': 'interp_imp.get_magic', diff --git a/pypy/module/micronumpy/arrayimpl/base.py b/pypy/module/micronumpy/arrayimpl/base.py --- a/pypy/module/micronumpy/arrayimpl/base.py +++ b/pypy/module/micronumpy/arrayimpl/base.py @@ -3,6 +3,12 @@ def is_scalar(self): return False + def base(self): + raise NotImplementedError + + def create_iter(self, shape=None): + raise NotImplementedError + class BaseArrayIterator(object): def next(self): raise NotImplementedError # purely abstract base class diff --git a/pypy/module/micronumpy/arrayimpl/concrete.py b/pypy/module/micronumpy/arrayimpl/concrete.py --- a/pypy/module/micronumpy/arrayimpl/concrete.py +++ b/pypy/module/micronumpy/arrayimpl/concrete.py @@ -1,178 +1,20 @@ from pypy.module.micronumpy.arrayimpl import base -from pypy.module.micronumpy import support, loop +from pypy.module.micronumpy import support, loop, iter from pypy.module.micronumpy.base import convert_to_array, W_NDimArray,\ ArrayArgumentException from pypy.module.micronumpy.strides import calc_new_strides, shape_agreement,\ calculate_broadcast_strides, calculate_dot_strides from pypy.module.micronumpy.iter import Chunk, Chunks, NewAxisChunk, RecordChunk from pypy.interpreter.error import OperationError, operationerrfmt +from pypy.interpreter.buffer import RWBuffer +from rpython.rlib import jit from rpython.rtyper.lltypesystem import rffi, lltype -from rpython.rlib import jit -from rpython.rlib.rawstorage import free_raw_storage, RAW_STORAGE +from rpython.rlib.rawstorage import free_raw_storage, raw_storage_getitem,\ + raw_storage_setitem, RAW_STORAGE +from pypy.module.micronumpy.arrayimpl.sort import argsort_array from rpython.rlib.debug import make_sure_not_resized -class ConcreteArrayIterator(base.BaseArrayIterator): - _immutable_fields_ = ['dtype', 'skip', 'size'] - def __init__(self, array): - self.array = array - self.offset = 0 - self.dtype = array.dtype - self.skip = self.dtype.itemtype.get_element_size() - self.size = array.size - - def setitem(self, elem): - self.dtype.setitem(self.array, self.offset, elem) - - def getitem(self): - return self.dtype.getitem(self.array, self.offset) - - def getitem_bool(self): - return self.dtype.getitem_bool(self.array, self.offset) - - def next(self): - self.offset += self.skip - - def next_skip_x(self, x): - self.offset += self.skip * x - - def done(self): - return self.offset >= self.size - - def reset(self): - self.offset %= self.size - -class OneDimViewIterator(ConcreteArrayIterator): - ''' The view iterator dtype can be different from the - array.dtype, this is what makes it a View - ''' - def __init__(self, array, dtype, start, strides, shape): - self.array = array - self.dtype = dtype - self.offset = start - self.skip = strides[0] - self.index = 0 - self.size = shape[0] - - def next(self): - self.offset += self.skip - self.index += 1 - - def next_skip_x(self, x): - self.offset += self.skip * x - self.index += x - - def done(self): - return self.index >= self.size - - def reset(self): - self.offset %= self.size - -class MultiDimViewIterator(ConcreteArrayIterator): - ''' The view iterator dtype can be different from the - array.dtype, this is what makes it a View - ''' - def __init__(self, array, dtype, start, strides, backstrides, shape): - self.indexes = [0] * len(shape) - self.array = array - self.dtype = dtype - self.shape = shape - self.offset = start - self.shapelen = len(shape) - self._done = False - self.strides = strides - self.backstrides = backstrides - self.size = array.size - - @jit.unroll_safe - def next(self): - offset = self.offset - for i in range(self.shapelen - 1, -1, -1): - if self.indexes[i] < self.shape[i] - 1: - self.indexes[i] += 1 - offset += self.strides[i] - break - else: - self.indexes[i] = 0 - offset -= self.backstrides[i] - else: - self._done = True - self.offset = offset - - @jit.unroll_safe - def next_skip_x(self, step): - for i in range(len(self.shape) - 1, -1, -1): - if self.indexes[i] < self.shape[i] - step: - self.indexes[i] += step - self.offset += self.strides[i] * step - break - else: - remaining_step = (self.indexes[i] + step) // self.shape[i] - this_i_step = step - remaining_step * self.shape[i] - self.offset += self.strides[i] * this_i_step - self.indexes[i] = self.indexes[i] + this_i_step - step = remaining_step - else: - self._done = True - - def done(self): - return self._done - - def reset(self): - self.offset %= self.size - -class AxisIterator(base.BaseArrayIterator): - def __init__(self, array, shape, dim): - self.shape = shape - strides = array.get_strides() - backstrides = array.get_backstrides() - if len(shape) == len(strides): - # keepdims = True - self.strides = strides[:dim] + [0] + strides[dim + 1:] - self.backstrides = backstrides[:dim] + [0] + backstrides[dim + 1:] - else: - self.strides = strides[:dim] + [0] + strides[dim:] - self.backstrides = backstrides[:dim] + [0] + backstrides[dim:] - self.first_line = True - self.indices = [0] * len(shape) - self._done = False - self.offset = array.start - self.dim = dim - self.array = array - self.dtype = array.dtype - - def setitem(self, elem): - self.dtype.setitem(self.array, self.offset, elem) - - def getitem(self): - return self.dtype.getitem(self.array, self.offset) - - @jit.unroll_safe - def next(self): - for i in range(len(self.shape) - 1, -1, -1): - if self.indices[i] < self.shape[i] - 1: - if i == self.dim: - self.first_line = False - self.indices[i] += 1 - self.offset += self.strides[i] - break - else: - if i == self.dim: - self.first_line = True - self.indices[i] = 0 - self.offset -= self.backstrides[i] - else: - self._done = True - - def done(self): - return self._done - -def int_w(space, w_obj): - try: - return space.int_w(space.index(w_obj)) - except OperationError: - return space.int_w(space.int(w_obj)) - class BaseConcreteArray(base.BaseArrayImplementation): start = 0 parent = None @@ -213,7 +55,7 @@ def get_size(self): return self.size // self.dtype.itemtype.get_element_size() - def reshape(self, space, new_shape): + def reshape(self, space, orig_array, new_shape): # Since we got to here, prod(new_shape) == self.size new_strides = None if self.size > 0: @@ -226,31 +68,31 @@ for nd in range(ndims): new_backstrides[nd] = (new_shape[nd] - 1) * new_strides[nd] return SliceArray(self.start, new_strides, new_backstrides, - new_shape, self) + new_shape, self, orig_array) else: return None - def get_real(self): + def get_real(self, orig_array): strides = self.get_strides() backstrides = self.get_backstrides() if self.dtype.is_complex_type(): dtype = self.dtype.float_type return SliceArray(self.start, strides, backstrides, - self.get_shape(), self, dtype=dtype) + self.get_shape(), self, orig_array, dtype=dtype) return SliceArray(self.start, strides, backstrides, - self.get_shape(), self) + self.get_shape(), self, orig_array) - def get_imag(self): + def get_imag(self, orig_array): strides = self.get_strides() backstrides = self.get_backstrides() if self.dtype.is_complex_type(): dtype = self.dtype.float_type return SliceArray(self.start + dtype.get_size(), strides, - backstrides, self.get_shape(), self, dtype=dtype) + backstrides, self.get_shape(), self, orig_array, dtype=dtype) if self.dtype.is_flexible_type(): # numpy returns self for self.imag return SliceArray(self.start, strides, backstrides, - self.get_shape(), self) + self.get_shape(), self, orig_array) impl = NonWritableArray(self.get_shape(), self.dtype, self.order, strides, backstrides) impl.fill(self.dtype.box(0)) @@ -265,7 +107,7 @@ for i, w_index in enumerate(view_w): if space.isinstance_w(w_index, space.w_slice): raise IndexError - idx = int_w(space, w_index) + idx = support.int_w(space, w_index) if idx < 0: idx = self.get_shape()[i] + idx if idx < 0 or idx >= self.get_shape()[i]: @@ -339,7 +181,7 @@ return self._lookup_by_index(space, view_w) if shape_len > 1: raise IndexError - idx = int_w(space, w_idx) + idx = support.int_w(space, w_idx) return self._lookup_by_index(space, [space.wrap(idx)]) @jit.unroll_safe @@ -367,26 +209,26 @@ i += 1 return Chunks(result) - def descr_getitem(self, space, w_index): + def descr_getitem(self, space, orig_arr, w_index): try: item = self._single_item_index(space, w_index) return self.getitem(item) except IndexError: # not a single result chunks = self._prepare_slice_args(space, w_index) - return chunks.apply(self) + return chunks.apply(orig_arr) - def descr_setitem(self, space, w_index, w_value): + def descr_setitem(self, space, orig_arr, w_index, w_value): try: item = self._single_item_index(space, w_index) self.setitem(item, self.dtype.coerce(space, w_value)) except IndexError: w_value = convert_to_array(space, w_value) chunks = self._prepare_slice_args(space, w_index) - view = chunks.apply(self) + view = chunks.apply(orig_arr) view.implementation.setslice(space, w_value) - def transpose(self): + def transpose(self, orig_array): if len(self.get_shape()) < 2: return self strides = [] @@ -397,7 +239,7 @@ backstrides.append(self.get_backstrides()[i]) shape.append(self.get_shape()[i]) return SliceArray(self.start, strides, - backstrides, shape, self) + backstrides, shape, self, orig_array) def copy(self): strides, backstrides = support.calc_strides(self.get_shape(), self.dtype, @@ -406,15 +248,15 @@ backstrides) return loop.setslice(self.get_shape(), impl, self) - def create_axis_iter(self, shape, dim): - return AxisIterator(self, shape, dim) + def create_axis_iter(self, shape, dim, cum): + return iter.AxisIterator(self, shape, dim, cum) def create_dot_iter(self, shape, skip): r = calculate_dot_strides(self.get_strides(), self.get_backstrides(), shape, skip) - return MultiDimViewIterator(self, self.dtype, self.start, r[0], r[1], shape) + return iter.MultiDimViewIterator(self, self.dtype, self.start, r[0], r[1], shape) - def swapaxes(self, axis1, axis2): + def swapaxes(self, orig_arr, axis1, axis2): shape = self.get_shape()[:] strides = self.get_strides()[:] backstrides = self.get_backstrides()[:] @@ -422,13 +264,20 @@ strides[axis1], strides[axis2] = strides[axis2], strides[axis1] backstrides[axis1], backstrides[axis2] = backstrides[axis2], backstrides[axis1] return W_NDimArray.new_slice(self.start, strides, - backstrides, shape, self) + backstrides, shape, self, orig_arr) def get_storage_as_int(self, space): return rffi.cast(lltype.Signed, self.storage) + def get_storage(self): + return self.storage + + def get_buffer(self, space): + return ArrayBuffer(self) + class ConcreteArrayNotOwning(BaseConcreteArray): def __init__(self, shape, dtype, order, strides, backstrides, storage): + make_sure_not_resized(shape) make_sure_not_resized(strides) make_sure_not_resized(backstrides) @@ -442,19 +291,31 @@ def create_iter(self, shape=None): if shape is None or shape == self.get_shape(): - return ConcreteArrayIterator(self) + return iter.ConcreteArrayIterator(self) r = calculate_broadcast_strides(self.get_strides(), self.get_backstrides(), self.get_shape(), shape) - return MultiDimViewIterator(self, self.dtype, 0, r[0], r[1], shape) + return iter.MultiDimViewIterator(self, self.dtype, 0, r[0], r[1], shape) def fill(self, box): self.dtype.fill(self.storage, box, 0, self.size) - def set_shape(self, space, new_shape): + def set_shape(self, space, orig_array, new_shape): strides, backstrides = support.calc_strides(new_shape, self.dtype, self.order) - return SliceArray(0, strides, backstrides, new_shape, self) + return SliceArray(0, strides, backstrides, new_shape, self, + orig_array) + + def argsort(self, space, w_axis): + return argsort_array(self, space, w_axis) + + def astype(self, space, dtype): + new_arr = W_NDimArray.from_shape(self.get_shape(), dtype) + loop.copy_from_to(self, new_arr.implementation, dtype) + return new_arr + + def base(self): + return None class ConcreteArray(ConcreteArrayNotOwning): def __init__(self, shape, dtype, order, strides, backstrides): @@ -469,14 +330,17 @@ free_raw_storage(self.storage, track_allocation=False) + + class NonWritableArray(ConcreteArray): - def descr_setitem(self, space, w_index, w_value): + def descr_setitem(self, space, orig_array, w_index, w_value): raise OperationError(space.w_RuntimeError, space.wrap( "array is not writable")) class SliceArray(BaseConcreteArray): - def __init__(self, start, strides, backstrides, shape, parent, dtype=None): + def __init__(self, start, strides, backstrides, shape, parent, orig_arr, + dtype=None): self.strides = strides self.backstrides = backstrides self.shape = shape @@ -490,6 +354,10 @@ self.dtype = dtype self.size = support.product(shape) * self.dtype.itemtype.get_element_size() self.start = start + self.orig_arr = orig_arr + + def base(self): + return self.orig_arr def fill(self, box): loop.fill(self, box.convert_to(self.dtype)) @@ -499,16 +367,16 @@ r = calculate_broadcast_strides(self.get_strides(), self.get_backstrides(), self.get_shape(), shape) - return MultiDimViewIterator(self.parent, self.dtype, - self.start, r[0], r[1], shape) + return iter.MultiDimViewIterator(self.parent, self.dtype, + self.start, r[0], r[1], shape) if len(self.get_shape()) == 1: - return OneDimViewIterator(self.parent, self.dtype, self.start, + return iter.OneDimViewIterator(self.parent, self.dtype, self.start, self.get_strides(), self.get_shape()) - return MultiDimViewIterator(self.parent, self.dtype, self.start, + return iter.MultiDimViewIterator(self.parent, self.dtype, self.start, self.get_strides(), self.get_backstrides(), self.get_shape()) - def set_shape(self, space, new_shape): + def set_shape(self, space, orig_array, new_shape): if len(self.get_shape()) < 2 or self.size == 0: # TODO: this code could be refactored into calc_strides # but then calc_strides would have to accept a stepping factor @@ -527,7 +395,7 @@ backstrides.reverse() new_shape.reverse() return SliceArray(self.start, strides, backstrides, new_shape, - self) + self, orig_array) new_strides = calc_new_strides(new_shape, self.get_shape(), self.get_strides(), self.order) @@ -538,4 +406,18 @@ for nd in range(len(new_shape)): new_backstrides[nd] = (new_shape[nd] - 1) * new_strides[nd] return SliceArray(self.start, new_strides, new_backstrides, new_shape, - self) + self, orig_array) + +class ArrayBuffer(RWBuffer): + def __init__(self, impl): + self.impl = impl + + def getitem(self, item): + return raw_storage_getitem(lltype.Char, self.impl.storage, item) + + def setitem(self, item, v): + return raw_storage_setitem(self.impl.storage, item, + rffi.cast(lltype.Char, v)) + + def getlength(self): + return self.impl.size diff --git a/pypy/module/micronumpy/arrayimpl/scalar.py b/pypy/module/micronumpy/arrayimpl/scalar.py --- a/pypy/module/micronumpy/arrayimpl/scalar.py +++ b/pypy/module/micronumpy/arrayimpl/scalar.py @@ -54,10 +54,10 @@ def get_size(self): return 1 - def transpose(self): + def transpose(self, _): return self - def descr_getitem(self, space, w_idx): + def descr_getitem(self, space, _, w_idx): raise OperationError(space.w_IndexError, space.wrap("scalars cannot be indexed")) @@ -65,14 +65,14 @@ raise OperationError(space.w_IndexError, space.wrap("scalars cannot be indexed")) - def descr_setitem(self, space, w_idx, w_val): + def descr_setitem(self, space, _, w_idx, w_val): raise OperationError(space.w_IndexError, space.wrap("scalars cannot be indexed")) def setitem_index(self, space, idx, w_val): raise OperationError(space.w_IndexError, space.wrap("scalars cannot be indexed")) - def set_shape(self, space, new_shape): + def set_shape(self, space, orig_array, new_shape): if not new_shape: return self if support.product(new_shape) == 1: @@ -83,13 +83,13 @@ raise OperationError(space.w_ValueError, space.wrap( "total size of the array must be unchanged")) - def reshape(self, space, new_shape): - return self.set_shape(space, new_shape) + def reshape(self, space, orig_array, new_shape): + return self.set_shape(space, orig_array, new_shape) - def create_axis_iter(self, shape, dim): + def create_axis_iter(self, shape, dim, cum): raise Exception("axis iter should not happen on scalar") - def swapaxes(self, axis1, axis2): + def swapaxes(self, orig_array, axis1, axis2): raise Exception("should not be called") def fill(self, w_value): @@ -98,3 +98,17 @@ def get_storage_as_int(self, space): raise OperationError(space.w_ValueError, space.wrap("scalars have no address")) + + def argsort(self, space, w_axis): + return space.wrap(0) + + def astype(self, space, dtype): + return W_NDimArray.new_scalar(space, dtype, self.value) + + def base(self): + return None + + def get_buffer(self, space): + raise OperationError(space.w_ValueError, space.wrap( + "cannot point buffer to a scalar")) + diff --git a/pypy/module/micronumpy/arrayimpl/sort.py b/pypy/module/micronumpy/arrayimpl/sort.py new file mode 100644 --- /dev/null +++ b/pypy/module/micronumpy/arrayimpl/sort.py @@ -0,0 +1,195 @@ + +""" This is the implementation of various sorting routines in numpy. It's here +because it only makes sense on a concrete array +""" + +from rpython.rtyper.lltypesystem import rffi, lltype +from rpython.rlib.listsort import make_timsort_class +from rpython.rlib.rawstorage import raw_storage_getitem, raw_storage_setitem, \ + free_raw_storage, alloc_raw_storage +from rpython.rlib.unroll import unrolling_iterable +from rpython.rlib.rarithmetic import intmask +from rpython.rlib.objectmodel import specialize +from pypy.interpreter.error import OperationError +from pypy.module.micronumpy.base import W_NDimArray +from pypy.module.micronumpy import interp_dtype, types +from pypy.module.micronumpy.iter import AxisIterator + +INT_SIZE = rffi.sizeof(lltype.Signed) + +def make_sort_function(space, itemtype, comp_type, count=1): + TP = itemtype.T + step = rffi.sizeof(TP) + + class Repr(object): + def __init__(self, index_stride_size, stride_size, size, values, + indexes, index_start, start): + self.index_stride_size = index_stride_size + self.stride_size = stride_size + self.index_start = index_start + self.start = start + self.size = size + self.values = values + self.indexes = indexes + + def getitem(self, item): + if count < 2: + v = raw_storage_getitem(TP, self.values, item * self.stride_size + + self.start) + else: + v = [] + for i in range(count): + _v = raw_storage_getitem(TP, self.values, item * self.stride_size + + self.start + step * i) + v.append(_v) + if comp_type == 'int': + v = intmask(v) + elif comp_type == 'float': + v = float(v) + elif comp_type == 'complex': + v = [float(v[0]),float(v[1])] + else: + raise NotImplementedError('cannot reach') + return (v, raw_storage_getitem(lltype.Signed, self.indexes, + item * self.index_stride_size + + self.index_start)) + + def setitem(self, idx, item): + if count < 2: + raw_storage_setitem(self.values, idx * self.stride_size + + self.start, rffi.cast(TP, item[0])) + else: + i = 0 + for val in item[0]: + raw_storage_setitem(self.values, idx * self.stride_size + + self.start + i*step, rffi.cast(TP, val)) + i += 1 + raw_storage_setitem(self.indexes, idx * self.index_stride_size + + self.index_start, item[1]) + + class ArgArrayRepWithStorage(Repr): + def __init__(self, index_stride_size, stride_size, size): + start = 0 + dtype = interp_dtype.get_dtype_cache(space).w_longdtype + self.indexes = dtype.itemtype.malloc(size*dtype.get_size()) + self.values = alloc_raw_storage(size * stride_size, + track_allocation=False) + Repr.__init__(self, index_stride_size, stride_size, + size, self.values, self.indexes, start, start) + + def __del__(self): + free_raw_storage(self.indexes, track_allocation=False) + free_raw_storage(self.values, track_allocation=False) + + def arg_getitem(lst, item): + return lst.getitem(item) + + def arg_setitem(lst, item, value): + lst.setitem(item, value) + + def arg_length(lst): + return lst.size + + def arg_getitem_slice(lst, start, stop): + retval = ArgArrayRepWithStorage(lst.index_stride_size, lst.stride_size, + stop-start) + for i in range(stop-start): + retval.setitem(i, lst.getitem(i+start)) + return retval + + if count < 2: + def arg_lt(a, b): + # Does numpy do <= ? + return a[0] < b[0] + else: + def arg_lt(a, b): + for i in range(count): + if a[0][i] < b[0][i]: + return True + elif a[0][i] > b[0][i]: + return False + # Does numpy do True? + return False + + ArgSort = make_timsort_class(arg_getitem, arg_setitem, arg_length, + arg_getitem_slice, arg_lt) + + def argsort(arr, space, w_axis, itemsize): + if w_axis is space.w_None: + # note that it's fine ot pass None here as we're not going + # to pass the result around (None is the link to base in slices) + arr = arr.reshape(space, None, [arr.get_size()]) + axis = 0 + elif w_axis is None: + axis = -1 + else: + axis = space.int_w(w_axis) + # create array of indexes + dtype = interp_dtype.get_dtype_cache(space).w_longdtype + index_arr = W_NDimArray.from_shape(arr.get_shape(), dtype) + storage = index_arr.implementation.get_storage() + if len(arr.get_shape()) == 1: + for i in range(arr.get_size()): + raw_storage_setitem(storage, i * INT_SIZE, i) + r = Repr(INT_SIZE, itemsize, arr.get_size(), arr.get_storage(), + storage, 0, arr.start) + ArgSort(r).sort() + else: + shape = arr.get_shape() + if axis < 0: + axis = len(shape) + axis - 1 + if axis < 0 or axis > len(shape): + raise OperationError(space.w_IndexError, space.wrap( + "Wrong axis %d" % axis)) + iterable_shape = shape[:axis] + [0] + shape[axis + 1:] + iter = AxisIterator(arr, iterable_shape, axis, False) + index_impl = index_arr.implementation + index_iter = AxisIterator(index_impl, iterable_shape, axis, False) + stride_size = arr.strides[axis] + index_stride_size = index_impl.strides[axis] + axis_size = arr.shape[axis] + while not iter.done(): + for i in range(axis_size): + raw_storage_setitem(storage, i * index_stride_size + + index_iter.offset, i) + r = Repr(index_stride_size, stride_size, axis_size, + arr.get_storage(), storage, index_iter.offset, iter.offset) + ArgSort(r).sort() + iter.next() + index_iter.next() + return index_arr + + return argsort + +def argsort_array(arr, space, w_axis): + cache = space.fromcache(SortCache) # that populates SortClasses + itemtype = arr.dtype.itemtype + for tp in all_types: + if isinstance(itemtype, tp[0]): + return cache._lookup(tp)(arr, space, w_axis, + itemtype.get_element_size()) + # XXX this should probably be changed From noreply at buildbot.pypy.org Thu Feb 7 12:21:05 2013 From: noreply at buildbot.pypy.org (fijal) Date: Thu, 7 Feb 2013 12:21:05 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: merge Message-ID: <20130207112105.6B5A61C0DC1@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r60931:1aaead29f5ad Date: 2013-02-07 13:20 +0200 http://bitbucket.org/pypy/pypy/changeset/1aaead29f5ad/ Log: merge diff --git a/rpython/jit/backend/arm/assembler.py b/rpython/jit/backend/arm/assembler.py --- a/rpython/jit/backend/arm/assembler.py +++ b/rpython/jit/backend/arm/assembler.py @@ -96,6 +96,7 @@ self._build_failure_recovery(exc=False, withfloats=False) self._build_wb_slowpath(False) self._build_wb_slowpath(True) + self._build_stack_check_failure() if self.cpu.supports_floats: self._build_wb_slowpath(False, withfloats=True) self._build_wb_slowpath(True, withfloats=True) @@ -231,6 +232,7 @@ ofs = self.cpu.get_ofs_of_frame_field('jf_descr') # make sure ofs fits into a register assert check_imm_arg(ofs) + self.mc.MOV_rr(r.r0.value, r.fp.value) self.mc.BKPT() #base_ofs = self.cpu.get_baseofs_of_frame_field() #self.mc.MOV_bi(ofs, propagate_exception_descr) @@ -340,6 +342,7 @@ self.wb_slowpath[withcards + 2 * withfloats] = rawstart def _build_malloc_slowpath(self): + return # XXX fix me mc = ARMv7Builder() if self.cpu.supports_floats: vfp_regs = r.all_vfp_regs @@ -377,15 +380,16 @@ def _push_all_regs_to_jitframe(self, mc, ignored_regs, withfloats, callee_only=False): + base_ofs = self.cpu.get_baseofs_of_frame_field() if callee_only: regs = CoreRegisterManager.save_around_call_regs else: regs = CoreRegisterManager.all_regs - # use STMDB ops here + # XXX use STMDB ops here for i, gpr in enumerate(regs): if gpr in ignored_regs: continue - mc.STR_ri(gpr.value, r.fp.value, i * WORD) + self.store_reg(mc, gpr, r.fp, base_ofs + i * WORD) if withfloats: if callee_only: regs = VFPRegisterManager.save_around_call_regs @@ -394,8 +398,36 @@ for i, vfpr in enumerate(regs): if vfpr in ignored_regs: continue - # add the offset of the gpr_regs - mc.VSTR(vfpr.value, r.fp.value, imm=i * DOUBLE_WORD) + ofs = len(CoreRegisterManager.all_regs) * WORD + ofs += i * DOUBLE_WORD + base_ofs + self.store_reg(mc, vfpr, r.fp, ofs) + + def _pop_all_regs_from_jitframe(self, mc, ignored_regs, withfloats, + callee_only=False): + # Pop all general purpose registers + base_ofs = self.cpu.get_baseofs_of_frame_field() + if callee_only: + regs = CoreRegisterManager.save_around_call_regs + else: + regs = CoreRegisterManager.all_regs + # XXX use LDMDB ops here + for i, gpr in enumerate(regs): + if gpr in ignored_regs: + continue + ofs = i * WORD + base_ofs + self.load_reg(mc, gpr, r.fp, ofs) + if withfloats: + # Pop all XMM regs + if callee_only: + regs = VFPRegisterManager.save_around_call_regs + else: + regs = VFPRegisterManager.all_regs + for i, vfpr in enumerate(regs): + if vfpr in ignored_regs: + continue + ofs = len(CoreRegisterManager.all_regs) * WORD + ofs += i * DOUBLE_WORD + base_ofs + self.load_reg(mc, vfpr, r.fp, ofs) def _build_failure_recovery(self, exc, withfloats=False): mc = ARMv7Builder() @@ -434,8 +466,8 @@ # set return value assert check_imm_arg(base_ofs) - mc.SUB_ri(r.r0.value, r.fp.value, base_ofs) - + mc.MOV_rr(r.r0.value, r.fp.value) + # self.gen_func_epilog(mc) rawstart = mc.materialize(self.cpu.asmmemmgr, []) self.failure_recovery_code[exc + 2 * withfloats] = rawstart @@ -547,10 +579,8 @@ self.mc.SUB_ri(r.sp.value, r.sp.value, WORD) # for the force index assert stack_size % 8 == 0 # ensure we keep alignment - # set fp to point to the JITFRAME + ofs - ofs = self.cpu.get_baseofs_of_frame_field() - assert check_imm_arg(ofs) - self.mc.ADD_ri(r.fp.value, r.r0.value, imm=ofs) + # set fp to point to the JITFRAME + self.mc.MOV_rr(r.fp.value, r.r0.value) # gcrootmap = self.cpu.gc_ll_descr.gcrootmap if gcrootmap and gcrootmap.is_shadow_stack: @@ -703,40 +733,38 @@ arglocs = self.rebuild_faillocs_from_descr(faildescr, inputargs) regalloc = Regalloc(assembler=self) + startpos = self.mc.get_relative_pos() operations = regalloc.prepare_bridge(inputargs, arglocs, operations, self.current_clt.allgcrefs, self.current_clt.frame_info) - #sp_patch_location = self._prepare_sp_patch_position() + stack_check_patch_ofs = self._check_frame_depth(self.mc, + regalloc.get_gcmap()) - startpos = self.mc.get_relative_pos() - - frame_depth = self._assemble(regalloc, inputargs, operations) + frame_depth_no_fixed_size = self._assemble(regalloc, inputargs, operations) codeendpos = self.mc.get_relative_pos() - #self._patch_sp_offset(sp_patch_location, frame_depth) - self.write_pending_failure_recoveries() rawstart = self.materialize_loop(original_loop_token) self.process_pending_guards(rawstart) - self.fixup_target_tokens(rawstart) # patch the jump from original guard self.patch_trace(faildescr, original_loop_token, rawstart, regalloc) if not we_are_translated(): - # for the benefit of tests - faildescr._arm_bridge_frame_depth = frame_depth if log: self.mc._dump_trace(rawstart, 'bridge.asm') + + ops_offset = self.mc.ops_offset frame_depth = max(self.current_clt.frame_info.jfi_frame_depth, - frame_depth + JITFRAME_FIXED_SIZE) - ops_offset = self.mc.ops_offset + frame_depth_no_fixed_size + JITFRAME_FIXED_SIZE) + self.fixup_target_tokens(rawstart) + self.update_frame_depth(frame_depth) self.teardown() debug_start("jit-backend-addr") @@ -767,6 +795,108 @@ input_i += 1 return locs + def check_frame_before_jump(self, target_token): + if target_token in self.target_tokens_currently_compiling: + return + if target_token._arm_clt is self.current_clt: + return + # We can have a frame coming from god knows where that's + # passed to a jump to another loop. Make sure it has the + # correct depth + expected_size = target_token._arm_clt.frame_info.jfi_frame_depth + self._check_frame_depth(self.mc, self._regalloc.get_gcmap(), + expected_size=expected_size) + + + def _check_frame_depth(self, mc, gcmap, expected_size=-1): + """ check if the frame is of enough depth to follow this bridge. + Otherwise reallocate the frame in a helper. + There are other potential solutions + to that, but this one does not sound too bad. + """ + descrs = self.cpu.gc_ll_descr.getframedescrs(self.cpu) + ofs = self.cpu.unpack_fielddescr(descrs.arraydescr.lendescr) + base_ofs = self.cpu.get_baseofs_of_frame_field() + mc.gen_load_int(r.ip.value, ofs) + mc.SUB_ri(r.ip.value, r.ip.value, base_ofs) + stack_check_cmp_ofs = mc.currpos() + if expected_size == -1: + mc.gen_load_int(r.lr.value, 0xffffff) + else: + mc.gen_load_int(r.lr.value, expected_size) + mc.CMP_rr(r.ip.value, r.lr.value) + + jg_location = mc.currpos() + mc.BKPT() + + self.push_gcmap(mc, gcmap, push=True) + + # the size value is still stored in lr + mc.PUSH([r.lr.value]) + + self.mc.BL(self._stack_check_failure) + + # patch jg_location above + currpos = self.mc.currpos() + pmc = OverwritingBuilder(mc, jg_location, WORD) + pmc.B_offs(currpos, c.GE) + + return stack_check_cmp_ofs + + def _build_stack_check_failure(self): + # this code should do the following steps + # a) store all registers in the jitframe + # b) fish for the arguments passed by the caller + # c) store the gcmap in the jitframe + # d) call realloc_frame + # e) set the fp to point to the new jitframe + # f) store the address of the new jitframe in the shadowstack + # c) set the gcmap field to 0 in the new jitframe + # g) restore registers and return + mc = ARMv7Builder() + self._push_all_regs_to_jitframe(mc, [], self.cpu.supports_floats) + # this is the gcmap stored by push_gcmap(mov=True) in _check_stack_frame + # and the expected_size pushed in _check_stack_frame + # pop the values passed on the stack, gcmap -> r0, expected_size -> r1 + mc.POP([r.r0.value, r.r1.value]) + # store return address and keep the stack aligned + mc.PUSH([r.ip.value, r.lr.value]) + + # store the current gcmap(r1) in the jitframe + gcmap_ofs = self.cpu.get_ofs_of_frame_field('jf_gcmap') + assert check_imm_arg(abs(gcmap_ofs)) + mc.STR_ri(r.r1.value, r.fp.value, imm=gcmap_ofs) + + # set first arg, which is the old jitframe address + mc.MOV_rr(r.r0.value, r.fp.value) + # call realloc_frame, it takes two arguments + # arg0: the old jitframe + # arg1: the new size + mc.BL(self.cpu.realloc_frame) + # set fp to the new jitframe plus the baseofs + mc.ADD_ri(r.fp.value, r.r0.value) + + gcrootmap = self.cpu.gc_ll_descr.gcrootmap + if gcrootmap and gcrootmap.is_shadow_stack: + self._load_shadowstack_top(mc, r.r5, gcrootmap) + # store the new jitframe addr in the shadowstack + mc.STR_ri(r.r0.value, r.r5.value, imm=-WORD) + + # reset the jf_gcmap field in the jitframe + mc.gen_load_int(r.ip.value, 0) + mc.STR_ri(r.ip.value, r.fp.value, imm=gcmap_ofs) + + # restore registers + self._pop_all_regs_from_jitframe(mc, [], self.cpu.supports_floats) + mc.POP([r.ip.value, r.pc.value]) # return + self._stack_check_failure = mc.materialize(self.cpu.asmmemmgr, []) + + def _load_shadowstack_top(self, mc, reg, gcrootmap): + rst = gcrootmap.get_root_stack_top_addr() + self.mc.gen_load_int(reg.value, rst) + self.mc.gen_load_int(reg.value, reg.value) + return rst + def fixup_target_tokens(self, rawstart): for targettoken in self.target_tokens_currently_compiling: targettoken._arm_loop_code += rawstart @@ -966,6 +1096,46 @@ faildescr._arm_failure_recovery_block = 0 # regalloc support + def load_reg(self, mc, target, base, ofs, cond=c.AL, helper=r.ip): + if target.is_vfp_reg(): + return self._load_vfp_reg(mc, target, base, ofs, cond) + elif target.is_reg(): + return self._load_core_reg(mc, target, base, ofs, cond) + + def _load_vfp_reg(self, mc, target, base, ofs, cond=c.AL, helper=r.ip): + if check_imm_arg(ofs): + mc.VLDR(target.value, base.value, imm=ofs, cond=cond) + else: + mc.gen_load_int(helper.value, ofs) + mc.VLDR(target.value, base.value, helper.value, cond=cond) + + def _load_core_reg(self, mc, target, base, ofs, cond=c.AL, helper=r.ip): + if check_imm_arg(ofs): + mc.LDR_ri(target.value, base.value, imm=ofs, cond=cond) + else: + mc.gen_load_int(helper.value, ofs) + mc.LDR_rr(target.value, base.value, helper.value, cond=cond) + + def store_reg(self, mc, source, base, ofs, cond=c.AL, helper=r.ip): + if source.is_vfp_reg(): + return self._store_vfp_reg(mc, source, base, ofs, cond) + else: + return self._store_core_reg(mc, source, base, ofs, cond) + + def _store_vfp_reg(self, mc, source, base, ofs, cond=c.AL, helper=r.ip): + if check_imm_arg(ofs): + mc.VSTR(source.value, base.value, imm=ofs, cond=cond) + else: + mc.gen_load_int(helper.value, ofs) + mc.VSTR(source.value, base.value, helper.value, cond=cond) + + def _store_core_reg(self, mc, source, base, ofs, cond=c.AL, helper=r.ip): + if check_imm_arg(ofs): + mc.STR_ri(source.value, base.value, imm=ofs, cond=cond) + else: + gen_load_int(helper.value, ofs) + mc.STR_rr(source.value, base.value, helper.value, cond=cond) + def load(self, loc, value): assert (loc.is_reg() and value.is_imm() or loc.is_vfp_reg() and value.is_imm_float()) @@ -1269,6 +1439,7 @@ mc.MOV_bi(ofs, 0) + def not_implemented(msg): os.write(2, '[ARM/asm] %s\n' % msg) raise NotImplementedError(msg) diff --git a/rpython/jit/backend/arm/locations.py b/rpython/jit/backend/arm/locations.py --- a/rpython/jit/backend/arm/locations.py +++ b/rpython/jit/backend/arm/locations.py @@ -136,5 +136,5 @@ return ImmLocation(i) -def get_fp_offset(position): - return WORD * (position + JITFRAME_FIXED_SIZE) +def get_fp_offset(base_ofs, position): + return base_ofs + WORD * (position + JITFRAME_FIXED_SIZE) diff --git a/rpython/jit/backend/arm/opassembler.py b/rpython/jit/backend/arm/opassembler.py --- a/rpython/jit/backend/arm/opassembler.py +++ b/rpython/jit/backend/arm/opassembler.py @@ -22,6 +22,7 @@ from rpython.jit.backend.arm.regalloc import TempInt, TempPtr from rpython.jit.backend.arm.locations import imm from rpython.jit.backend.llsupport import symbolic, jitframe +from rpython.jit.backend.llsupport.gcmap import allocate_gcmap from rpython.jit.backend.llsupport.descr import InteriorFieldDescr from rpython.jit.metainterp.history import (Box, AbstractFailDescr, INT, FLOAT, REF) @@ -67,8 +68,8 @@ if loc.is_reg(): val = loc.value else: - assert 0, 'ffuu, implement' - val = loc.value // WORD + assert loc.is_stack() + val = JITFRAME_FIXED_SIZE + loc.value gcmap[val // WORD // 8] |= r_uint(1) << (val % (WORD * 8)) return gcmap @@ -234,7 +235,7 @@ self.mc.NOP() else: self.mc.BKPT() - gcmap = self.allocate_gcmap(arglocs[0].value) + gcmap = allocate_gcmap(self, arglocs[0].value, JITFRAME_FIXED_SIZE) self.pending_guards.append(GuardToken(gcmap, descr, failargs=op.getfailargs(), @@ -247,19 +248,6 @@ fcond=fcond)) return c.AL - def allocate_gcmap(self, frame_depth): - size = frame_depth + JITFRAME_FIXED_SIZE - malloc_size = (size // WORD // 8 + 1) + 1 - rawgcmap = self.datablockwrapper.malloc_aligned(WORD * malloc_size, - WORD) - # set the length field - rffi.cast(rffi.CArrayPtr(lltype.Signed), rawgcmap)[0] = malloc_size - 1 - gcmap = rffi.cast(lltype.Ptr(jitframe.GCMAP), rawgcmap) - # zero the area - for i in range(malloc_size - 1): - gcmap[i] = r_uint(0) - return gcmap - def _emit_guard_overflow(self, guard, failargs, fcond): if guard.getopnum() == rop.GUARD_OVERFLOW: fcond = self._emit_guard(guard, failargs, c.VS, save_exc=False) @@ -344,6 +332,7 @@ # stack locations both before and after the jump. # target_token = op.getdescr() + target = target_token._arm_loop_code assert isinstance(target_token, TargetToken) assert fcond == c.AL my_nbargs = self.current_clt._debug_nbargs @@ -352,31 +341,26 @@ self._insert_checks() if target_token in self.target_tokens_currently_compiling: - self.mc.B_offs(target_token._arm_loop_code, fcond) + self.mc.B_offs(target, fcond) else: - self.mc.B(target_token._arm_loop_code, fcond) + self.mc.B(target, fcond) return fcond def emit_op_finish(self, op, arglocs, regalloc, fcond): - base_ofs = self.cpu.get_baseofs_of_frame_field() - WORD + base_ofs = self.cpu.get_baseofs_of_frame_field() if len(arglocs) == 2: [return_val, fail_descr_loc] = arglocs - if op.getarg(0).type == FLOAT: - self.mc.VSTR(return_val.value, r.fp.value)#, imm=-base_ofs) - else: - self.mc.STR_ri(return_val.value, r.fp.value)#, imm=-base_ofs) - #self.save_into_mem(raw_stack(0), return_val, imm(size)) + self.store_reg(self.mc, return_val, r.fp, base_ofs) else: [fail_descr_loc] = arglocs ofs = self.cpu.get_ofs_of_frame_field('jf_descr') - base_ofs = self.cpu.get_baseofs_of_frame_field() self.mc.gen_load_int(r.ip.value, fail_descr_loc.value) # XXX self.mov(fail_descr_loc, RawStackLoc(ofs)) - self.mc.STR_ri(r.ip.value, r.fp.value, imm=ofs) + self.store_reg(self.mc, r.ip, r.fp, ofs, helper=r.lr) gcmap = self.gcmap_for_finish self.push_gcmap(self.mc, gcmap, store=True) - self.mc.SUB_ri(r.r0.value, r.fp.value, base_ofs) + self.mc.MOV_rr(r.r0.value, r.fp.value) # exit function self.gen_func_epilog() return fcond diff --git a/rpython/jit/backend/arm/regalloc.py b/rpython/jit/backend/arm/regalloc.py --- a/rpython/jit/backend/arm/regalloc.py +++ b/rpython/jit/backend/arm/regalloc.py @@ -1,5 +1,6 @@ from rpython.rtyper.annlowlevel import llhelper, cast_instance_to_gcref from rpython.rlib import rgc +from rpython.rlib.debug import debug_print, debug_start, debug_stop from rpython.jit.backend.llsupport.regalloc import FrameManager, \ RegisterManager, TempBox, compute_vars_longevity from rpython.jit.backend.arm import registers as r @@ -15,7 +16,7 @@ ) from rpython.jit.backend.arm.jump import remap_frame_layout_mixed from rpython.jit.backend.arm.arch import MY_COPY_OF_REGS -from rpython.jit.backend.arm.arch import WORD +from rpython.jit.backend.arm.arch import WORD, DOUBLE_WORD, JITFRAME_FIXED_SIZE from rpython.jit.codewriter import longlong from rpython.jit.metainterp.history import (Const, ConstInt, ConstFloat, ConstPtr, Box, BoxPtr, @@ -23,6 +24,7 @@ from rpython.jit.metainterp.history import JitCellToken, TargetToken from rpython.jit.metainterp.resoperation import rop from rpython.jit.backend.llsupport.descr import ArrayDescr +from rpython.jit.backend.llsupport.gcmap import allocate_gcmap from rpython.jit.backend.llsupport import symbolic from rpython.rtyper.lltypesystem import lltype, rffi, rstr, llmemory from rpython.rtyper.lltypesystem.lloperation import llop @@ -61,12 +63,12 @@ class ARMFrameManager(FrameManager): - def __init__(self): + def __init__(self, base_ofs): FrameManager.__init__(self) + self.base_ofs = base_ofs - @staticmethod - def frame_pos(i, box_type): - return locations.StackLocation(i, get_fp_offset(i), box_type) + def frame_pos(self, i, box_type): + return locations.StackLocation(i, get_fp_offset(self.base_ofs, i), box_type) @staticmethod def frame_size(type): @@ -282,8 +284,9 @@ return self.vfprm.convert_to_imm(value) def _prepare(self, inputargs, operations, allgcrefs): - self.frame_manager = self.fm = ARMFrameManager() cpu = self.assembler.cpu + self.fm = ARMFrameManager(cpu.get_baseofs_of_frame_field()) + self.frame_manager = self.fm operations = cpu.gc_ll_descr.rewrite_assembler(cpu, operations, allgcrefs) # compute longevity of variables @@ -350,6 +353,30 @@ # is also used on op args, which is a non-resizable list self.possibly_free_vars(list(inputargs)) + def get_gcmap(self, forbidden_regs=[], noregs=False): + frame_depth = self.fm.get_frame_depth() + gcmap = allocate_gcmap(self.assembler, + frame_depth, JITFRAME_FIXED_SIZE) + debug_start("jit-backend-gcmap") + for box, loc in self.rm.reg_bindings.iteritems(): + if loc in forbidden_regs: + continue + if box.type == REF: + assert not noregs + assert isinstance(loc, RegLoc) + val = gpr_reg_mgr_cls.all_reg_indexes[loc.value] + gcmap[val // WORD // 8] |= r_uint(1) << (val % (WORD * 8)) + for box, loc in self.fm.bindings.iteritems(): + if box.type == REF: + assert isinstance(loc, StackLoc) + val = loc.value // WORD + gcmap[val // WORD // 8] |= r_uint(1) << (val % (WORD * 8)) + for i in range(len(gcmap)): + debug_print(str(gcmap[i])) + debug_stop('jit-backend-gcmap') + return gcmap + + # ------------------------------------------------------------ def perform_llong(self, op, args, fcond): return self.assembler.regalloc_emit_llong(op, args, fcond, self) @@ -767,6 +794,7 @@ else: src_locations2.append(src_loc) dst_locations2.append(dst_loc) + self.assembler.check_frame_before_jump(self.jump_target_descr) remap_frame_layout_mixed(self.assembler, src_locations1, dst_locations1, tmploc, src_locations2, dst_locations2, vfptmploc) diff --git a/rpython/jit/backend/llsupport/gcmap.py b/rpython/jit/backend/llsupport/gcmap.py new file mode 100644 --- /dev/null +++ b/rpython/jit/backend/llsupport/gcmap.py @@ -0,0 +1,20 @@ +from rpython.rtyper.lltypesystem import rffi +from rpython.rtyper.lltypesystem import lltype +from rpython.jit.backend.llsupport import jitframe +from rpython.rlib.rarithmetic import r_uint +from rpython.jit.backend.llsupport.symbolic import WORD +from rpython.rlib.debug import debug_print + +def allocate_gcmap(assembler, frame_depth, fixed_size): + size = frame_depth + fixed_size + malloc_size = (size // WORD // 8 + 1) + 1 + rawgcmap = assembler.datablockwrapper.malloc_aligned(WORD * malloc_size, + WORD) + debug_print("gcmap: %x, len %d" % (rawgcmap, malloc_size - 1)) + # set the length field + rffi.cast(rffi.CArrayPtr(lltype.Signed), rawgcmap)[0] = malloc_size - 1 + gcmap = rffi.cast(lltype.Ptr(jitframe.GCMAP), rawgcmap) + # zero the area + for i in range(malloc_size - 1): + gcmap[i] = r_uint(0) + return gcmap diff --git a/rpython/jit/backend/llsupport/llmodel.py b/rpython/jit/backend/llsupport/llmodel.py --- a/rpython/jit/backend/llsupport/llmodel.py +++ b/rpython/jit/backend/llsupport/llmodel.py @@ -11,7 +11,8 @@ from rpython.jit.backend.llsupport.descr import ( get_size_descr, get_field_descr, get_array_descr, get_call_descr, get_interiorfield_descr, - FieldDescr, ArrayDescr, CallDescr, InteriorFieldDescr) + FieldDescr, ArrayDescr, CallDescr, InteriorFieldDescr, + FLAG_POINTER, FLAG_FLOAT) from rpython.jit.backend.llsupport.asmmemmgr import AsmMemoryManager from rpython.annotator import model as annmodel @@ -46,8 +47,25 @@ self._setup_exception_handling_untranslated() self.asmmemmgr = AsmMemoryManager() self._setup_frame_realloc(translate_support_code) + ad = self.gc_ll_descr.getframedescrs(self).arraydescr + self.signedarraydescr = ad + # the same as normal JITFRAME, however with an array of pointers + self.refarraydescr = ArrayDescr(ad.basesize, ad.itemsize, ad.lendescr, + FLAG_POINTER) + self.floatarraydescr = ArrayDescr(ad.basesize, ad.itemsize, ad.lendescr, + FLAG_FLOAT) self.setup() + def getarraydescr_for_frame(self, type, index): + if type == history.FLOAT: + descr = self.floatarraydescr + elif type == history.REF: + descr = self.refarraydescr + else: + descr = self.signedarraydescr + return JITFRAME_FIXED_SIZE + index, descr + + def setup(self): pass diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -2,6 +2,7 @@ import sys, os from rpython.jit.backend.llsupport import symbolic, jitframe from rpython.jit.backend.llsupport.asmmemmgr import MachineDataBlockWrapper +from rpython.jit.backend.llsupport.gcmap import allocate_gcmap from rpython.jit.metainterp.history import Const, Box, BoxInt, ConstInt from rpython.jit.metainterp.history import AbstractFailDescr, INT, REF, FLOAT from rpython.jit.metainterp.history import JitCellToken @@ -1845,26 +1846,11 @@ guard_opnum == rop.GUARD_NOT_FORCED) is_guard_not_invalidated = guard_opnum == rop.GUARD_NOT_INVALIDATED is_guard_not_forced = guard_opnum == rop.GUARD_NOT_FORCED - gcmap = self.allocate_gcmap(frame_depth) + gcmap = allocate_gcmap(self, frame_depth, JITFRAME_FIXED_SIZE) return GuardToken(gcmap, faildescr, failargs, fail_locs, exc, frame_depth, is_guard_not_invalidated, is_guard_not_forced) - def allocate_gcmap(self, frame_depth): - size = frame_depth + JITFRAME_FIXED_SIZE - malloc_size = (size // WORD // 8 + 1) + 1 - rawgcmap = self.datablockwrapper.malloc_aligned(WORD * malloc_size, - WORD) - debug_print("gcmap: %x, len %d for %d" % (rawgcmap, malloc_size - 1, - self.mc.get_relative_pos())) - # set the length field - rffi.cast(rffi.CArrayPtr(lltype.Signed), rawgcmap)[0] = malloc_size - 1 - gcmap = rffi.cast(lltype.Ptr(jitframe.GCMAP), rawgcmap) - # zero the area - for i in range(malloc_size - 1): - gcmap[i] = r_uint(0) - return gcmap - def generate_propagate_error_64(self): assert WORD == 8 startpos = self.mc.get_relative_pos() diff --git a/rpython/jit/backend/x86/runner.py b/rpython/jit/backend/x86/runner.py --- a/rpython/jit/backend/x86/runner.py +++ b/rpython/jit/backend/x86/runner.py @@ -13,8 +13,6 @@ from rpython.jit.backend.llsupport import jitframe from rpython.jit.backend.x86 import regloc from rpython.jit.backend.llsupport.symbolic import WORD -from rpython.jit.backend.llsupport.descr import ArrayDescr, FLAG_POINTER,\ - FLAG_FLOAT import sys @@ -48,23 +46,6 @@ self.profile_agent = profile_agent - ad = self.gc_ll_descr.getframedescrs(self).arraydescr - self.signedarraydescr = ad - # the same as normal JITFRAME, however with an array of pointers - self.refarraydescr = ArrayDescr(ad.basesize, ad.itemsize, ad.lendescr, - FLAG_POINTER) - self.floatarraydescr = ArrayDescr(ad.basesize, ad.itemsize, ad.lendescr, - FLAG_FLOAT) - - def getarraydescr_for_frame(self, type, index): - if type == history.FLOAT: - descr = self.floatarraydescr - elif type == history.REF: - descr = self.refarraydescr - else: - descr = self.signedarraydescr - return JITFRAME_FIXED_SIZE + index, descr - def set_debug(self, flag): return self.assembler.set_debug(flag) From noreply at buildbot.pypy.org Thu Feb 7 12:21:47 2013 From: noreply at buildbot.pypy.org (fijal) Date: Thu, 7 Feb 2013 12:21:47 +0100 (CET) Subject: [pypy-commit] pypy default: add __version__ in greenlet Message-ID: <20130207112147.EC6101C0DC1@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r60932:8fbd55b9dc9d Date: 2013-02-07 13:21 +0200 http://bitbucket.org/pypy/pypy/changeset/8fbd55b9dc9d/ Log: add __version__ in greenlet diff --git a/lib_pypy/greenlet.py b/lib_pypy/greenlet.py --- a/lib_pypy/greenlet.py +++ b/lib_pypy/greenlet.py @@ -1,5 +1,6 @@ import _continuation, sys +__version__ = "0.4.0" # ____________________________________________________________ # Exceptions From noreply at buildbot.pypy.org Thu Feb 7 14:07:16 2013 From: noreply at buildbot.pypy.org (bivab) Date: Thu, 7 Feb 2013 14:07:16 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: getarraydescr_for_frame now only returns a descr and not a tuple of index and descr. Message-ID: <20130207130716.DDB791C0E2E@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: jitframe-on-heap Changeset: r60933:6605eefbe6fb Date: 2013-02-07 14:08 +0100 http://bitbucket.org/pypy/pypy/changeset/6605eefbe6fb/ Log: getarraydescr_for_frame now only returns a descr and not a tuple of index and descr. (fixes translation too) diff --git a/rpython/jit/backend/llsupport/gc.py b/rpython/jit/backend/llsupport/gc.py --- a/rpython/jit/backend/llsupport/gc.py +++ b/rpython/jit/backend/llsupport/gc.py @@ -128,12 +128,9 @@ 'jfi_frame_depth') return descrs - def getarraydescr_for_frame(self, type, index): - """ This function returns a tuple (descr, index) for storing - index inside a frame array. It's a little bit delicate, because on - say x86 32bit, we can't express all indexes of floats. - """ - raise NotImplementedError # cpu specific + def getarraydescr_for_frame(self, type): + """ This functions retuns an arraydescr of type for the JITFRAME""" + raise NotImplementedError def malloc_jitframe(self, frame_info): """ Allocate a new frame, overwritten by tests diff --git a/rpython/jit/backend/llsupport/llmodel.py b/rpython/jit/backend/llsupport/llmodel.py --- a/rpython/jit/backend/llsupport/llmodel.py +++ b/rpython/jit/backend/llsupport/llmodel.py @@ -56,15 +56,14 @@ FLAG_FLOAT) self.setup() - def getarraydescr_for_frame(self, type, index): + def getarraydescr_for_frame(self, type): if type == history.FLOAT: descr = self.floatarraydescr elif type == history.REF: descr = self.refarraydescr else: descr = self.signedarraydescr - return JITFRAME_FIXED_SIZE + index, descr - + return descr def setup(self): pass diff --git a/rpython/jit/backend/llsupport/regalloc.py b/rpython/jit/backend/llsupport/regalloc.py --- a/rpython/jit/backend/llsupport/regalloc.py +++ b/rpython/jit/backend/llsupport/regalloc.py @@ -2,6 +2,7 @@ from rpython.jit.metainterp.history import Const, Box, REF, INT from rpython.rlib.objectmodel import we_are_translated, specialize from rpython.jit.metainterp.resoperation import rop + try: from collections import OrderedDict except ImportError: diff --git a/rpython/jit/backend/llsupport/rewrite.py b/rpython/jit/backend/llsupport/rewrite.py --- a/rpython/jit/backend/llsupport/rewrite.py +++ b/rpython/jit/backend/llsupport/rewrite.py @@ -175,11 +175,16 @@ None, descr=descrs.jf_frame_info) self.newops.append(op2) arglist = op.getarglist() + index = self.cpu.getarryoffset_for_frame() for i, arg in enumerate(arglist): - index, descr = self.cpu.getarraydescr_for_frame(arg.type, i) + descr = self.cpu.getarraydescr_for_frame(arg.type) self.newops.append(ResOperation(rop.SETARRAYITEM_GC, [frame, ConstInt(index), arg], None, descr)) + if WORD == 4 and type == history.FLOAT: + index += 2 + else: + index += 1 descr = op.getdescr() assert isinstance(descr, JitCellToken) jd = descr.outermost_jitdriver_sd diff --git a/rpython/jit/backend/llsupport/test/test_rewrite.py b/rpython/jit/backend/llsupport/test/test_rewrite.py --- a/rpython/jit/backend/llsupport/test/test_rewrite.py +++ b/rpython/jit/backend/llsupport/test/test_rewrite.py @@ -111,10 +111,13 @@ self.signedframedescr = ArrayDescr(3, 8, FieldDescr('len', 0, 0, 0), 0) self.floatframedescr = ArrayDescr(5, 8, FieldDescr('len', 0, 0, 0), 0) - def getarraydescr_for_frame(self, tp, index): + def getarraydescr_for_frame(self, tp): if tp == FLOAT: - return index, self.floatframedescr - return index, self.signedframedescr + return self.floatframedescr + return self.signedframedescr + + def getarryoffset_for_frame(self): + return 0 def arraydescrof(self, ARRAY): try: diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -2310,14 +2310,14 @@ # load the return value from the dead frame's value index 0 kind = op.result.type if kind == FLOAT: - _, descr = self.cpu.getarraydescr_for_frame(kind, 0) + descr = self.cpu.getarraydescr_for_frame(kind) ofs = self.cpu.unpack_arraydescr(descr) self.mc.MOVSD_xm(xmm0.value, (eax.value, ofs)) if result_loc is not xmm0: self.mc.MOVSD(result_loc, xmm0) else: assert result_loc is eax - _, descr = self.cpu.getarraydescr_for_frame(kind, 0) + descr = self.cpu.getarraydescr_for_frame(kind) ofs = self.cpu.unpack_arraydescr(descr) self.mc.MOV_rm(eax.value, (eax.value, ofs)) # diff --git a/rpython/jit/backend/x86/regalloc.py b/rpython/jit/backend/x86/regalloc.py --- a/rpython/jit/backend/x86/regalloc.py +++ b/rpython/jit/backend/x86/regalloc.py @@ -22,6 +22,7 @@ from rpython.jit.backend.llsupport.descr import unpack_arraydescr from rpython.jit.backend.llsupport.descr import unpack_fielddescr from rpython.jit.backend.llsupport.descr import unpack_interiorfielddescr +from rpython.jit.backend.llsupport.gcmap import allocate_gcmap from rpython.jit.backend.llsupport.regalloc import FrameManager,\ RegisterManager, TempBox, compute_vars_longevity, is_comparison_or_ovf_op from rpython.jit.backend.x86.arch import WORD, JITFRAME_FIXED_SIZE @@ -897,7 +898,7 @@ def get_gcmap(self, forbidden_regs=[], noregs=False): frame_depth = self.fm.get_frame_depth() - gcmap = self.assembler.allocate_gcmap(frame_depth) + gcmap = allocate_gcmap(self.assembler, frame_depth, JITFRAME_FIXED_SIZE) debug_start("jit-backend-gcmap") for box, loc in self.rm.reg_bindings.iteritems(): if loc in forbidden_regs: diff --git a/rpython/jit/backend/x86/runner.py b/rpython/jit/backend/x86/runner.py --- a/rpython/jit/backend/x86/runner.py +++ b/rpython/jit/backend/x86/runner.py @@ -55,6 +55,9 @@ else: return 1000 + def getarryoffset_for_frame(self): + return JITFRAME_FIXED_SIZE + def setup(self): self.assembler = Assembler386(self, self.translate_support_code) From noreply at buildbot.pypy.org Thu Feb 7 14:07:18 2013 From: noreply at buildbot.pypy.org (bivab) Date: Thu, 7 Feb 2013 14:07:18 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: merge heads Message-ID: <20130207130718.8B7881C0E2E@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: jitframe-on-heap Changeset: r60934:bf9bc21a1daf Date: 2013-02-07 14:11 +0100 http://bitbucket.org/pypy/pypy/changeset/bf9bc21a1daf/ Log: merge heads diff too long, truncating to 2000 out of 5368 lines diff --git a/lib-python/2.7/collections.py b/lib-python/2.7/collections.py --- a/lib-python/2.7/collections.py +++ b/lib-python/2.7/collections.py @@ -6,6 +6,7 @@ __all__ += _abcoll.__all__ from _collections import deque, defaultdict +from operator import itemgetter as _itemgetter from keyword import iskeyword as _iskeyword import sys as _sys import heapq as _heapq @@ -328,7 +329,8 @@ # Execute the template string in a temporary namespace and # support tracing utilities by setting a value for frame.f_globals['__name__'] - namespace = {'__name__': 'namedtuple_%s' % typename} + namespace = {'__name__': 'namedtuple_%s' % typename, + 'OrderedDict': OrderedDict} try: exec template in namespace except SyntaxError, e: diff --git a/lib-python/2.7/test/test_modulefinder.py b/lib-python/2.7/test/test_modulefinder.py --- a/lib-python/2.7/test/test_modulefinder.py +++ b/lib-python/2.7/test/test_modulefinder.py @@ -16,7 +16,7 @@ # library. TEST_DIR = tempfile.mkdtemp() -TEST_PATH = [TEST_DIR, os.path.dirname(__future__.__file__)] +TEST_PATH = [TEST_DIR, os.path.dirname(tempfile.__file__)] # Each test description is a list of 5 items: # diff --git a/lib-python/conftest.py b/lib-python/conftest.py --- a/lib-python/conftest.py +++ b/lib-python/conftest.py @@ -160,7 +160,7 @@ RegrTest('test_codeop.py', core=True), RegrTest('test_coding.py', core=True), RegrTest('test_coercion.py', core=True), - RegrTest('test_collections.py'), + RegrTest('test_collections.py', usemodules='binascii struct'), RegrTest('test_colorsys.py'), RegrTest('test_commands.py'), RegrTest('test_compare.py', core=True), @@ -181,7 +181,7 @@ RegrTest('test_csv.py', usemodules='_csv'), RegrTest('test_ctypes.py', usemodules="_rawffi thread"), RegrTest('test_curses.py'), - RegrTest('test_datetime.py'), + RegrTest('test_datetime.py', usemodules='binascii struct'), RegrTest('test_dbm.py'), RegrTest('test_decimal.py'), RegrTest('test_decorators.py', core=True), diff --git a/lib_pypy/cPickle.py b/lib_pypy/cPickle.py --- a/lib_pypy/cPickle.py +++ b/lib_pypy/cPickle.py @@ -1,5 +1,5 @@ # -# One-liner implementation of cPickle +# Reimplementation of cPickle, mostly as a copy of pickle.py # from pickle import Pickler, dump, dumps, PickleError, PicklingError, UnpicklingError, _EmptyClass @@ -131,6 +131,13 @@ # Unpickling machinery +class _Stack(list): + def pop(self, index=-1): + try: + return list.pop(self, index) + except IndexError: + raise UnpicklingError("unpickling stack underflow") + class Unpickler(object): def __init__(self, file): @@ -155,7 +162,7 @@ Return the reconstituted object hierarchy specified in the file. """ self.mark = object() # any new unique object - self.stack = [] + self.stack = _Stack() self.append = self.stack.append try: key = ord(self.read(1)) diff --git a/lib_pypy/ctypes_support.py b/lib_pypy/ctypes_support.py --- a/lib_pypy/ctypes_support.py +++ b/lib_pypy/ctypes_support.py @@ -19,16 +19,19 @@ if sys.platform == 'win32': standard_c_lib._errno.restype = ctypes.POINTER(ctypes.c_int) + standard_c_lib._errno.argtypes = None def _where_is_errno(): return standard_c_lib._errno() elif sys.platform in ('linux2', 'freebsd6'): standard_c_lib.__errno_location.restype = ctypes.POINTER(ctypes.c_int) + standard_c_lib.__errno_location.argtypes = None def _where_is_errno(): return standard_c_lib.__errno_location() elif sys.platform in ('darwin', 'freebsd7', 'freebsd8', 'freebsd9'): standard_c_lib.__error.restype = ctypes.POINTER(ctypes.c_int) + standard_c_lib.__error.argtypes = None def _where_is_errno(): return standard_c_lib.__error() diff --git a/lib_pypy/greenlet.py b/lib_pypy/greenlet.py --- a/lib_pypy/greenlet.py +++ b/lib_pypy/greenlet.py @@ -57,7 +57,8 @@ def __switch(target, methodname, *args): current = getcurrent() # - while not target: + while not (target.__main or _continulet.is_pending(target)): + # inlined __nonzero__ ^^^ in case it's overridden if not target.__started: if methodname == 'switch': greenlet_func = _greenlet_start diff --git a/lib_pypy/pypy_test/test_cPickle.py b/lib_pypy/pypy_test/test_cPickle.py new file mode 100644 --- /dev/null +++ b/lib_pypy/pypy_test/test_cPickle.py @@ -0,0 +1,7 @@ +from __future__ import absolute_import +import py + +from lib_pypy import cPickle + +def test_stack_underflow(): + py.test.raises(cPickle.UnpicklingError, cPickle.loads, "a string") diff --git a/pypy/conftest.py b/pypy/conftest.py --- a/pypy/conftest.py +++ b/pypy/conftest.py @@ -84,10 +84,11 @@ if self.config.option.runappdirect: # only collect regular tests if we are in an 'app_test' directory, # or in test_lib_pypy - names = self.listnames() - return "app_test" in names or "test_lib_pypy" in names - else: - return True + for name in self.listnames(): + if "app_test" in name or "test_lib_pypy" in name: + return True + return False + return True def funcnamefilter(self, name): if name.startswith('test_'): diff --git a/pypy/doc/arm.rst b/pypy/doc/arm.rst --- a/pypy/doc/arm.rst +++ b/pypy/doc/arm.rst @@ -145,7 +145,7 @@ :: - pypy ~/path_to_pypy_checkout/pypy/translator/goal/translate.py -O1 --platform=arm target.py + pypy ~/path_to_pypy_checkout/rpython/translator/goal/translate.py -O1 --platform=arm target.py If everything worked correctly this should yield an ARM binary. Running this binary in the ARM chroot or on an ARM device should produce the output ``"Hello World"``. diff --git a/pypy/doc/coding-guide.rst b/pypy/doc/coding-guide.rst --- a/pypy/doc/coding-guide.rst +++ b/pypy/doc/coding-guide.rst @@ -832,7 +832,7 @@ for the next milestone, both from an E-Mail and from a web interface. -.. _`development tracker`: https://codespeak.net/issue/pypy-dev/ +.. _`development tracker`: https://bugs.pypy.org/ use your codespeak login or register ------------------------------------ @@ -841,7 +841,7 @@ tracker. Else, you can `register with the tracker`_ easily. -.. _`register with the tracker`: https://codespeak.net/issue/pypy-dev/user?@template=register +.. _`register with the tracker`: https://bugs.pypy.org/user?@template=register .. _`roundup`: http://roundup.sourceforge.net/ diff --git a/pypy/doc/confrest.py b/pypy/doc/confrest.py --- a/pypy/doc/confrest.py +++ b/pypy/doc/confrest.py @@ -4,7 +4,8 @@ from confrest_oldpy import Project, Page, relpath html = py.xml.html -class PyPyPage(Page): + +class PyPyPage(Page): googlefragment = """ """ + def fill_menubar(self): self.menubar = html.div( - html.a("home", - href=self.get_doclink("index.html"), - class_="menu"), + html.a("home", + href=self.get_doclink("index.html"), + class_="menu"), " ", html.a("blog", href="http://morepypy.blogspot.com", class_="menu"), - " ", + " ", html.a("getting-started", href=self.get_doclink("getting-started.html"), - class_="menu"), + class_="menu"), " ", html.a("documentation", href=self.get_doclink("docindex.html"), class_="menu"), - " ", + " ", html.a("hg", href="https://bitbucket.org/pypy/pypy", class_="menu"), - " ", + " ", html.a("issues", - href="https://codespeak.net/issue/pypy-dev/", + href="https://bugs.pypy.org/", class_="menu"), " ", id="menubar") @@ -43,25 +45,25 @@ return relpath(self.targetpath.strpath, self.project.docpath.join(target).strpath) - def unicode(self, doctype=True): - page = self._root.unicode() + def unicode(self, doctype=True): + page = self._root.unicode() page = page.replace("", self.googlefragment + "") - if doctype: - return self.doctype + page - else: - return page - + if doctype: + return self.doctype + page + else: + return page -class Project(Project): + +class Project(Project): mydir = py.path.local(__file__).dirpath() - title = "PyPy" + title = "PyPy" stylesheet = 'style.css' - encoding = 'latin1' + encoding = 'latin1' prefix_title = "PyPy" logo = html.div( html.a( - html.img(alt="PyPy", id="pyimg", - src="http://codespeak.net/pypy/img/py-web1.png", + html.img(alt="PyPy", id="pyimg", + src="http://codespeak.net/pypy/img/py-web1.png", height=110, width=149))) - Page = PyPyPage + Page = PyPyPage diff --git a/pypy/doc/cppyy.rst b/pypy/doc/cppyy.rst --- a/pypy/doc/cppyy.rst +++ b/pypy/doc/cppyy.rst @@ -86,10 +86,10 @@ $ hg clone https://bitbucket.org/pypy/pypy $ cd pypy $ hg up reflex-support # optional - $ cd pypy/translator/goal + $ cd pypy/goal # This example shows python, but using pypy-c is faster and uses less memory - $ python translate.py -O jit --gcrootfinder=shadowstack targetpypystandalone.py --withmod-cppyy + $ python ../../rpython/bin/rpython.py -O jit --gcrootfinder=shadowstack targetpypystandalone.py --withmod-cppyy This will build a ``pypy-c`` that includes the cppyy module, and through that, Reflex support. diff --git a/pypy/doc/ctypes-implementation.rst b/pypy/doc/ctypes-implementation.rst --- a/pypy/doc/ctypes-implementation.rst +++ b/pypy/doc/ctypes-implementation.rst @@ -113,7 +113,7 @@ The pypy-c translated to run the ctypes tests can be used to run the pyglet examples as well. They can be run like e.g.:: $ cd pyglet/ - $ PYTHONPATH=. ../ctypes-stable/pypy/translator/goal/pypy-c examples/opengl.py + $ PYTHONPATH=. ../ctypes-stable/pypy/goal/pypy-c examples/opengl.py they usually should be terminated with ctrl-c. Refer to the their doc strings for details about how they should behave. diff --git a/pypy/doc/getting-started-dev.rst b/pypy/doc/getting-started-dev.rst --- a/pypy/doc/getting-started-dev.rst +++ b/pypy/doc/getting-started-dev.rst @@ -24,7 +24,7 @@ python bin/translatorshell.py Test snippets of translatable code are provided in the file -``pypy/translator/test/snippet.py``, which is imported under the name +``rpython/translator/test/snippet.py``, which is imported under the name ``snippet``. For example:: >>> t = Translation(snippet.is_perfect_number, [int]) @@ -52,16 +52,18 @@ The graph can be turned into C code:: >>> t.rtype() - >>> f = t.compile_c() + >>> lib = t.compile_c() The first command replaces the operations with other low level versions that -only use low level types that are available in C (e.g. int). To try out the -compiled version:: +only use low level types that are available in C (e.g. int). The compiled +version is now in a ``.so`` library. You can run it say using ctypes: + >>> from ctypes import CDLL + >>> f = CDLL(lib) >>> f(5) - False + 0 >>> f(6) - True + 1 Translating the flow graph to CLI or JVM code +++++++++++++++++++++++++++++++++++++++++++++ @@ -108,7 +110,7 @@ There is a small-to-medium demo showing the translator and the annotator:: cd demo - ../pypy/translator/goal/translate.py --view --annotate bpnn.py + ../rpython/translator/goal/translate.py --view --annotate bpnn.py This causes ``bpnn.py`` to display itself as a call graph and class hierarchy. Clicking on functions shows the flow graph of the particular @@ -119,17 +121,17 @@ To turn this example to C code (compiled to the executable ``bpnn-c``), type simply:: - ../pypy/translator/goal/translate.py bpnn.py + ../rpython/translator/goal/translate.py bpnn.py Translating Full Programs +++++++++++++++++++++++++ To translate full RPython programs, there is the script ``translate.py`` in -``translator/goal``. Examples for this are a slightly changed version of +``rpython/translator/goal``. Examples for this are a slightly changed version of Pystone:: - cd pypy/translator/goal + cd rpython/translator/goal python translate.py targetrpystonedalone This will produce the executable "targetrpystonedalone-c". diff --git a/pypy/doc/getting-started.rst b/pypy/doc/getting-started.rst --- a/pypy/doc/getting-started.rst +++ b/pypy/doc/getting-started.rst @@ -1,10 +1,10 @@ ================================== -Getting Started +Getting Started ================================== .. contents:: -.. _howtopypy: +.. _howtopypy: What is PyPy ? ============== @@ -33,8 +33,8 @@ .. _`RPython translation toolchain`: translation.html .. _`more...`: architecture.html -Just the facts -============== +Just the facts +============== Download a pre-built PyPy ------------------------- @@ -125,7 +125,7 @@ ``pypy/pypy`` and documentation files in ``pypy/pypy/doc``. We try to ensure that the tip is always stable, but it might occasionally be broken. You may want to check out `our nightly tests:`_ -find a revision (12-chars alphanumeric string, e.g. "963e808156b3") +find a revision (12-chars alphanumeric string, e.g. "963e808156b3") that passed at least the ``{linux32}`` tests (corresponding to a ``+`` sign on the line ``success``) and then, in your cloned repository, switch to this revision @@ -159,24 +159,24 @@ Understanding PyPy's architecture --------------------------------- -For in-depth information about architecture and coding documentation -head over to the `documentation section`_ where you'll find lots of -interesting information. Additionally, in true hacker spirit, you -may just `start reading sources`_ . +For in-depth information about architecture and coding documentation +head over to the `documentation section`_ where you'll find lots of +interesting information. Additionally, in true hacker spirit, you +may just `start reading sources`_ . .. _`documentation section`: index.html#project-documentation .. _`start reading sources`: getting-started-dev.html#start-reading-sources -Filing bugs or feature requests +Filing bugs or feature requests ------------------------------- You may file `bug reports`_ on our issue tracker which is -also accessible through the 'issues' top menu of -the PyPy website. `Using the development tracker`_ has -more detailed information on specific features of the tracker. +also accessible through the 'issues' top menu of +the PyPy website. `Using the development tracker`_ has +more detailed information on specific features of the tracker. .. _`Using the development tracker`: coding-guide.html#using-development-tracker -.. _bug reports: https://codespeak.net/issue/pypy-dev/ +.. _bug reports: https://bugs.pypy.org/ .. include:: _ref.txt diff --git a/pypy/doc/index.rst b/pypy/doc/index.rst --- a/pypy/doc/index.rst +++ b/pypy/doc/index.rst @@ -220,9 +220,8 @@ ================================ =========================================== Directory explanation/links ================================ =========================================== -`pypy/annotation/`_ `type inferencing code`_ for `RPython`_ programs -`pypy/bin/`_ command-line scripts, mainly `py.py`_ and `translatorshell.py`_ +`pypy/bin/`_ command-line scripts, mainly `pyinteractive.py`_ `pypy/config/`_ handles the numerous options for building and running PyPy @@ -249,20 +248,8 @@ `pypy/objspace/`_ `object space`_ implementations -`pypy/objspace/flow/`_ the FlowObjSpace_ implementing `abstract interpretation`_ - `pypy/objspace/std/`_ the StdObjSpace_ implementing CPython's objects and types -`pypy/rlib/`_ a `"standard library"`_ for RPython_ programs - -`pypy/rpython/`_ the `RPython Typer`_ - -`pypy/rpython/lltypesystem/`_ the `low-level type system`_ for C-like backends - -`pypy/rpython/ootypesystem/`_ the `object-oriented type system`_ for OO backends - -`pypy/rpython/memory/`_ the `garbage collector`_ construction framework - `pypy/tool/`_ various utilities and hacks used from various places `pypy/tool/algo/`_ general-purpose algorithmic and mathematic @@ -270,20 +257,39 @@ `pypy/tool/pytest/`_ support code for our `testing methods`_ -`pypy/translator/`_ translation_ backends and support code -`pypy/translator/backendopt/`_ general optimizations that run before a backend generates code +`rpython/annotator/`_ `type inferencing code`_ for `RPython`_ programs -`pypy/translator/c/`_ the `GenC backend`_, producing C code from an +`rpython/config/`_ handles the numerous options for RPython + + +`rpython/flowspace/`_ the FlowObjSpace_ implementing `abstract interpretation`_ + + +`rpython/rlib/`_ a `"standard library"`_ for RPython_ programs + +`rpython/rtyper/`_ the `RPython Typer`_ + +`rpython/rtyper/lltypesystem/`_ the `low-level type system`_ for C-like backends + +`rpython/rtyper/ootypesystem/`_ the `object-oriented type system`_ for OO backends + +`rpython/rtyper/memory/`_ the `garbage collector`_ construction framework + +`rpython/translator/`_ translation_ backends and support code + +`rpython/translator/backendopt/`_ general optimizations that run before a backend generates code + +`rpython/translator/c/`_ the `GenC backend`_, producing C code from an RPython program (generally via the rtyper_) -`pypy/translator/cli/`_ the `CLI backend`_ for `.NET`_ (Microsoft CLR or Mono_) +`rpython/translator/cli/`_ the `CLI backend`_ for `.NET`_ (Microsoft CLR or Mono_) -`pypy/translator/goal/`_ our `main PyPy-translation scripts`_ live here +`pypy/goal/`_ our `main PyPy-translation scripts`_ live here -`pypy/translator/jvm/`_ the Java backend +`rpython/translator/jvm/`_ the Java backend -`pypy/translator/tool/`_ helper tools for translation, including the Pygame +`rpython/translator/tool/`_ helper tools for translation, including the Pygame `graph viewer`_ ``*/test/`` many directories have a test subdirectory containing test diff --git a/pypy/doc/sandbox.rst b/pypy/doc/sandbox.rst --- a/pypy/doc/sandbox.rst +++ b/pypy/doc/sandbox.rst @@ -87,15 +87,15 @@ ----- -In pypy/translator/goal:: +In pypy/goal:: - ./translate.py -O2 --sandbox targetpypystandalone.py + ../../rpython/bin/rpython -O2 --sandbox targetpypystandalone.py If you don't have a regular PyPy installed, you should, because it's faster to translate, but you can also run ``python translate.py`` instead. -To run it, use the tools in the pypy/translator/sandbox directory:: +To run it, use the tools in the pypy/sandbox directory:: ./pypy_interact.py /some/path/pypy-c-sandbox [args...] diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst --- a/pypy/doc/whatsnew-head.rst +++ b/pypy/doc/whatsnew-head.rst @@ -37,6 +37,7 @@ .. branch: fix-e4fa0b2 .. branch: win32-fixes .. branch: fix-version-tool +.. branch: popen2-removal .. branch: release-2.0-beta1 @@ -50,3 +51,6 @@ .. branch: inline-virtualref-2 Better optimized certain types of frame accesses in the JIT, particularly around exceptions that escape the function they were raised in. + +.. branch: missing-ndarray-attributes +Some missing attributes from ndarrays diff --git a/pypy/interpreter/pytraceback.py b/pypy/interpreter/pytraceback.py --- a/pypy/interpreter/pytraceback.py +++ b/pypy/interpreter/pytraceback.py @@ -1,5 +1,6 @@ from pypy.interpreter import baseobjspace from pypy.interpreter.error import OperationError + from rpython.tool.error import offset2lineno @@ -27,10 +28,10 @@ def descr__reduce__(self, space): from pypy.interpreter.mixedmodule import MixedModule - w_mod = space.getbuiltinmodule('_pickle_support') - mod = space.interp_w(MixedModule, w_mod) + w_mod = space.getbuiltinmodule('_pickle_support') + mod = space.interp_w(MixedModule, w_mod) new_inst = mod.get('traceback_new') - w = space.wrap + w = space.wrap tup_base = [] tup_state = [ @@ -49,6 +50,7 @@ self.lasti = space.int_w(w_lasti) self.next = space.interp_w(PyTraceback, w_next, can_be_None=True) + def record_application_traceback(space, operror, frame, last_instruction): if frame.pycode.hidden_applevel: return @@ -56,10 +58,11 @@ tb = PyTraceback(space, frame, last_instruction, tb) operror.set_traceback(tb) + def check_traceback(space, w_tb, msg): from pypy.interpreter.typedef import PyTraceback tb = space.interpclass_w(w_tb) - if tb is None or not space.is_true(space.isinstance(tb, + if tb is None or not space.is_true(space.isinstance(tb, space.gettypeobject(PyTraceback.typedef))): raise OperationError(space.w_TypeError, space.wrap(msg)) return tb diff --git a/pypy/interpreter/typedef.py b/pypy/interpreter/typedef.py --- a/pypy/interpreter/typedef.py +++ b/pypy/interpreter/typedef.py @@ -1,18 +1,17 @@ -""" +import py - -""" -import py -from pypy.interpreter.gateway import interp2app, BuiltinCode, unwrap_spec,\ - WrappedDefault from pypy.interpreter.argument import Arguments from pypy.interpreter.baseobjspace import Wrappable, DescrMismatch from pypy.interpreter.error import OperationError, operationerrfmt +from pypy.interpreter.gateway import (interp2app, BuiltinCode, unwrap_spec, + WrappedDefault) + +from rpython.rlib.jit import promote +from rpython.rlib.objectmodel import compute_identity_hash, specialize from rpython.tool.sourcetools import compile2, func_with_new_name -from rpython.rlib.objectmodel import instantiate, compute_identity_hash, specialize -from rpython.rlib.jit import promote -class TypeDef: + +class TypeDef(object): def __init__(self, __name, __base=None, __total_ordering__=None, **rawdict): "NOT_RPYTHON: initialization-time only" self.name = __name @@ -27,7 +26,7 @@ self.weakrefable = '__weakref__' in rawdict self.doc = rawdict.pop('__doc__', None) for base in bases: - self.hasdict |= base.hasdict + self.hasdict |= base.hasdict self.weakrefable |= base.weakrefable self.rawdict = {} self.acceptable_as_base_class = '__new__' in rawdict @@ -426,7 +425,7 @@ return unknown_objclass_getter, cls miniglobals = {} if isinstance(cls, str): - assert cls.startswith('<'),"pythontype typecheck should begin with <" + assert cls.startswith('<'), "pythontype typecheck should begin with <" cls_name = cls[1:] typeexpr = "space.w_%s" % cls_name else: @@ -474,7 +473,7 @@ else: try: return self.fget(self, space, w_obj) - except DescrMismatch, e: + except DescrMismatch: return w_obj.descr_call_mismatch( space, '__getattribute__', self.reqcls, Arguments(space, [w_obj, @@ -489,7 +488,7 @@ space.wrap("readonly attribute")) try: fset(self, space, w_obj, w_value) - except DescrMismatch, e: + except DescrMismatch: w_obj.descr_call_mismatch( space, '__setattr__', self.reqcls, Arguments(space, [w_obj, @@ -505,7 +504,7 @@ space.wrap("cannot delete attribute")) try: fdel(self, space, w_obj) - except DescrMismatch, e: + except DescrMismatch: w_obj.descr_call_mismatch( space, '__delattr__', self.reqcls, Arguments(space, [w_obj, @@ -546,6 +545,7 @@ class Member(Wrappable): """For slots.""" _immutable_ = True + def __init__(self, index, name, w_cls): self.index = index self.name = name @@ -617,9 +617,8 @@ from pypy.interpreter.pyframe import PyFrame from pypy.interpreter.pyopcode import SuspendedUnroller from pypy.interpreter.module import Module -from pypy.interpreter.function import Function, Method, StaticMethod -from pypy.interpreter.function import ClassMethod -from pypy.interpreter.function import BuiltinFunction, descr_function_get +from pypy.interpreter.function import (Function, Method, StaticMethod, + ClassMethod, BuiltinFunction, descr_function_get) from pypy.interpreter.pytraceback import PyTraceback from pypy.interpreter.generator import GeneratorIterator from pypy.interpreter.nestedscope import Cell @@ -663,8 +662,10 @@ def fget_co_flags(space, code): # unwrapping through unwrap_spec sig = code.signature() flags = 0 - if sig.has_vararg(): flags |= CO_VARARGS - if sig.has_kwarg(): flags |= CO_VARKEYWORDS + if sig.has_vararg(): + flags |= CO_VARARGS + if sig.has_kwarg(): + flags |= CO_VARKEYWORDS return space.wrap(flags) def fget_co_consts(space, code): # unwrapping through unwrap_spec @@ -728,7 +729,7 @@ __eq__ = interp2app(PyCode.descr_code__eq__), __ne__ = descr_generic_ne, __hash__ = interp2app(PyCode.descr_code__hash__), - __reduce__ = interp2app(PyCode.descr__reduce__), + __reduce__ = interp2app(PyCode.descr__reduce__), __repr__ = interp2app(PyCode.repr), co_argcount = interp_attrproperty('co_argcount', cls=PyCode), co_nlocals = interp_attrproperty('co_nlocals', cls=PyCode), @@ -737,9 +738,9 @@ co_code = interp_attrproperty('co_code', cls=PyCode), co_consts = GetSetProperty(PyCode.fget_co_consts), co_names = GetSetProperty(PyCode.fget_co_names), - co_varnames = GetSetProperty(PyCode.fget_co_varnames), - co_freevars = GetSetProperty(PyCode.fget_co_freevars), - co_cellvars = GetSetProperty(PyCode.fget_co_cellvars), + co_varnames = GetSetProperty(PyCode.fget_co_varnames), + co_freevars = GetSetProperty(PyCode.fget_co_freevars), + co_cellvars = GetSetProperty(PyCode.fget_co_cellvars), co_filename = interp_attrproperty('co_filename', cls=PyCode), co_name = interp_attrproperty('co_name', cls=PyCode), co_firstlineno = interp_attrproperty('co_firstlineno', cls=PyCode), @@ -749,7 +750,7 @@ PyCode.typedef.acceptable_as_base_class = False PyFrame.typedef = TypeDef('frame', - __reduce__ = interp2app(PyFrame.descr__reduce__), + __reduce__ = interp2app(PyFrame.descr__reduce__), __setstate__ = interp2app(PyFrame.descr__setstate__), f_builtins = GetSetProperty(PyFrame.fget_f_builtins), f_lineno = GetSetProperty(PyFrame.fget_f_lineno, PyFrame.fset_f_lineno), @@ -827,9 +828,9 @@ __new__ = interp2app(Method.descr_method__new__.im_func), __call__ = interp2app(Method.descr_method_call), __get__ = interp2app(Method.descr_method_get), - im_func = interp_attrproperty_w('w_function', cls=Method), + im_func = interp_attrproperty_w('w_function', cls=Method), __func__ = interp_attrproperty_w('w_function', cls=Method), - im_self = interp_attrproperty_w('w_instance', cls=Method), + im_self = interp_attrproperty_w('w_instance', cls=Method), __self__ = interp_attrproperty_w('w_instance', cls=Method), im_class = interp_attrproperty_w('w_class', cls=Method), __getattribute__ = interp2app(Method.descr_method_getattribute), @@ -886,7 +887,7 @@ def always_none(self, obj): return None -BuiltinFunction.typedef = TypeDef("builtin_function",**Function.typedef.rawdict) +BuiltinFunction.typedef = TypeDef("builtin_function", **Function.typedef.rawdict) BuiltinFunction.typedef.rawdict.update({ '__new__': interp2app(BuiltinFunction.descr_builtinfunction__new__.im_func), '__self__': GetSetProperty(always_none, cls=BuiltinFunction), @@ -897,12 +898,12 @@ BuiltinFunction.typedef.acceptable_as_base_class = False PyTraceback.typedef = TypeDef("traceback", - __reduce__ = interp2app(PyTraceback.descr__reduce__), + __reduce__ = interp2app(PyTraceback.descr__reduce__), __setstate__ = interp2app(PyTraceback.descr__setstate__), - tb_frame = interp_attrproperty('frame', cls=PyTraceback), - tb_lasti = interp_attrproperty('lasti', cls=PyTraceback), + tb_frame = interp_attrproperty('frame', cls=PyTraceback), + tb_lasti = interp_attrproperty('lasti', cls=PyTraceback), tb_lineno = GetSetProperty(PyTraceback.descr_tb_lineno), - tb_next = interp_attrproperty('next', cls=PyTraceback), + tb_next = interp_attrproperty('next', cls=PyTraceback), ) PyTraceback.typedef.acceptable_as_base_class = False @@ -937,12 +938,12 @@ Cell.typedef.acceptable_as_base_class = False Ellipsis.typedef = TypeDef("Ellipsis", - __repr__ = interp2app(Ellipsis.descr__repr__), + __repr__ = interp2app(Ellipsis.descr__repr__), ) Ellipsis.typedef.acceptable_as_base_class = False NotImplemented.typedef = TypeDef("NotImplemented", - __repr__ = interp2app(NotImplemented.descr__repr__), + __repr__ = interp2app(NotImplemented.descr__repr__), ) NotImplemented.typedef.acceptable_as_base_class = False diff --git a/pypy/module/bz2/test/test_bz2_compdecomp.py b/pypy/module/bz2/test/test_bz2_compdecomp.py --- a/pypy/module/bz2/test/test_bz2_compdecomp.py +++ b/pypy/module/bz2/test/test_bz2_compdecomp.py @@ -12,7 +12,7 @@ if os.name == "nt": from py.test import skip skip("bz2 module is not available on Windows") - + def setup_module(mod): DATA = 'BZh91AY&SY.\xc8N\x18\x00\x01>_\x80\x00\x10@\x02\xff\xf0\x01\x07n\x00?\xe7\xff\xe00\x01\x99\xaa\x00\xc0\x03F\x86\x8c#&\x83F\x9a\x03\x06\xa6\xd0\xa6\x93M\x0fQ\xa7\xa8\x06\x804hh\x12$\x11\xa4i4\xf14S\xd2\x88\xe5\xcd9gd6\x0b\n\xe9\x9b\xd5\x8a\x99\xf7\x08.K\x8ev\xfb\xf7xw\xbb\xdf\xa1\x92\xf1\xdd|/";\xa2\xba\x9f\xd5\xb1#A\xb6\xf6\xb3o\xc9\xc5y\\\xebO\xe7\x85\x9a\xbc\xb6f8\x952\xd5\xd7"%\x89>V,\xf7\xa6z\xe2\x9f\xa3\xdf\x11\x11"\xd6E)I\xa9\x13^\xca\xf3r\xd0\x03U\x922\xf26\xec\xb6\xed\x8b\xc3U\x13\x9d\xc5\x170\xa4\xfa^\x92\xacDF\x8a\x97\xd6\x19\xfe\xdd\xb8\xbd\x1a\x9a\x19\xa3\x80ankR\x8b\xe5\xd83]\xa9\xc6\x08\x82f\xf6\xb9"6l$\xb8j@\xc0\x8a\xb0l1..\xbak\x83ls\x15\xbc\xf4\xc1\x13\xbe\xf8E\xb8\x9d\r\xa8\x9dk\x84\xd3n\xfa\xacQ\x07\xb1%y\xaav\xb4\x08\xe0z\x1b\x16\xf5\x04\xe9\xcc\xb9\x08z\x1en7.G\xfc]\xc9\x14\xe1B@\xbb!8`' @@ -54,27 +54,27 @@ def test_creation(self): from bz2 import BZ2Compressor - + raises(TypeError, BZ2Compressor, "foo") raises(ValueError, BZ2Compressor, 10) - + BZ2Compressor(1) BZ2Compressor(9) - + def test_compress(self): from bz2 import BZ2Compressor - + bz2c = BZ2Compressor() raises(TypeError, bz2c.compress) data = bz2c.compress(self.TEXT) data = "%s%s" % (data, bz2c.flush()) assert self.decompress(data) == self.TEXT - + def test_compress_huge_data(self): if not self.HUGE_OK: skip("skipping test requiring lots of memory") - from bz2 import BZ2Compressor - + from bz2 import BZ2Compressor + HUGE_DATA = self.TEXT * 10000 bz2c = BZ2Compressor() raises(TypeError, bz2c.compress) @@ -83,8 +83,8 @@ assert self.decompress(data) == HUGE_DATA def test_compress_chunks_10(self): - from bz2 import BZ2Compressor - + from bz2 import BZ2Compressor + bz2c = BZ2Compressor() n = 0 data = "" @@ -112,23 +112,23 @@ cls.w_TEXT = cls.space.wrap(TEXT) cls.w_DATA = cls.space.wrap(DATA) cls.w_BUGGY_DATA = cls.space.wrap(BUGGY_DATA) - + def test_creation(self): from bz2 import BZ2Decompressor - + raises(TypeError, BZ2Decompressor, "foo") - + BZ2Decompressor() - + def test_attribute(self): from bz2 import BZ2Decompressor - + bz2d = BZ2Decompressor() assert bz2d.unused_data == "" def test_decompress(self): from bz2 import BZ2Decompressor - + bz2d = BZ2Decompressor() raises(TypeError, bz2d.decompress) decompressed_data = bz2d.decompress(self.DATA) @@ -136,7 +136,7 @@ def test_decompress_chunks_10(self): from bz2 import BZ2Decompressor - + bz2d = BZ2Decompressor() decompressed_data = "" n = 0 @@ -146,13 +146,13 @@ break decompressed_data = "%s%s" % (decompressed_data, bz2d.decompress(temp)) n += 1 - + assert decompressed_data == self.TEXT - + def test_decompress_unused_data(self): # test with unused data. (data after EOF) from bz2 import BZ2Decompressor - + bz2d = BZ2Decompressor() unused_data = "this is unused data" decompressed_data = bz2d.decompress(self.DATA + unused_data) @@ -161,7 +161,7 @@ def test_EOF_error(self): from bz2 import BZ2Decompressor - + bz2d = BZ2Decompressor() bz2d.decompress(self.DATA) raises(EOFError, bz2d.decompress, "foo") @@ -195,11 +195,11 @@ def test_compress_function(self): from bz2 import compress - + raises(TypeError, compress, 123) raises(ValueError, compress, "foo", 10) raises(TypeError, compress, "foo", "foo") - + data = compress(self.TEXT) assert self.decompress(data) == self.TEXT @@ -207,7 +207,7 @@ if not self.HUGE_OK: skip("skipping test requiring lots of memory") from bz2 import compress - + HUGE_DATA = self.TEXT * 10000 data = compress(HUGE_DATA) @@ -215,7 +215,7 @@ def test_decompress_function(self): import bz2 - + raises(TypeError, bz2.decompress) assert bz2.decompress("") == "" decompressed_data = bz2.decompress(self.DATA) diff --git a/pypy/module/bz2/test/test_bz2_file.py b/pypy/module/bz2/test/test_bz2_file.py --- a/pypy/module/bz2/test/test_bz2_file.py +++ b/pypy/module/bz2/test/test_bz2_file.py @@ -6,6 +6,7 @@ import py from pypy.interpreter.gateway import unwrap_spec, interp2app +from pypy.module.bz2.test.support import CheckAllocation if os.name == "nt": @@ -50,10 +51,7 @@ mod.RANDOM_DATA = ''.join([s[int(random.random() * len(s))] for i in range(30000)]) -class AppTestBZ2File: #(CheckAllocation): - # XXX for unknown reasons, we cannot do allocation checks, as sth is - # keeping those objects alive (BZ2File objects) - +class AppTestBZ2File(CheckAllocation): spaceconfig = { "usemodules": ["bz2", "binascii", "rctime"] } @@ -85,15 +83,15 @@ assert bz2f.closed == False bz2f.close() assert bz2f.closed == True - + def test_creation(self): from bz2 import BZ2File - + raises(ValueError, BZ2File, self.temppath, mode='w', compresslevel=10) raises(ValueError, BZ2File, self.temppath, mode='XYZ') # XXX the following is fine, currently: #raises(ValueError, BZ2File, self.temppath, mode='ww') - + BZ2File(self.temppath, mode='wU', buffering=0, compresslevel=8) BZ2File(self.temppath, mode='wb') # a large buf size @@ -101,50 +99,50 @@ def test_close(self): from bz2 import BZ2File - + # writeonly bz2f = BZ2File(self.temppath, mode='w') bz2f.close() - # since we use fclose() internally you can't close it twice - # bz2f.close() - + bz2f.close() + # readonly bz2f = BZ2File(self.temppath, mode='r') bz2f.close() - + bz2f.close() + def test_tell(self): from bz2 import BZ2File - + bz2f = BZ2File(self.temppath, mode='w') bz2f.close() raises(ValueError, bz2f.tell) - + bz2f = BZ2File(self.temppath, mode='w') pos = bz2f.tell() bz2f.close() assert pos == 0 - + def test_seek(self): from bz2 import BZ2File - + # hack to create a foo file open(self.temppath, "w").close() - + # cannot seek if close bz2f = BZ2File(self.temppath, mode='r') bz2f.close() raises(ValueError, bz2f.seek, 0) - + # cannot seek if 'w' bz2f = BZ2File(self.temppath, mode='w') raises(IOError, bz2f.seek, 0) bz2f.close() - + bz2f = BZ2File(self.temppath, mode='r') raises(TypeError, bz2f.seek) raises(TypeError, bz2f.seek, "foo") raises(TypeError, bz2f.seek, 0, "foo") - + bz2f.seek(0) assert bz2f.tell() == 0 del bz2f # delete from this frame, which is captured in the traceback @@ -152,21 +150,21 @@ def test_open_close_del(self): from bz2 import BZ2File self.create_temp_file() - + for i in range(10): f = BZ2File(self.temppath) f.close() del f - + def test_open_non_existent(self): from bz2 import BZ2File raises(IOError, BZ2File, "/non/existent/path") - + def test_open_mode_U(self): # bug #1194181: bz2.BZ2File opened for write with mode "U" from bz2 import BZ2File self.create_temp_file() - + bz2f = BZ2File(self.temppath, "U") bz2f.close() f = open(self.temppath) @@ -174,7 +172,7 @@ f.read() assert f.tell() == len(self.DATA) f.close() - + def test_seek_forward(self): from bz2 import BZ2File self.create_temp_file() @@ -214,7 +212,7 @@ assert bz2f.tell() == len(self.TEXT) assert bz2f.read() == "" bz2f.close() - + def test_seek_post_end_twice(self): from bz2 import BZ2File self.create_temp_file() @@ -240,10 +238,9 @@ from bz2 import BZ2File from cStringIO import StringIO self.create_temp_file() - + bz2f = BZ2File(self.temppath) - # XXX - #raises(TypeError, bz2f.readline, None) + raises(TypeError, bz2f.readline, None) sio = StringIO(self.TEXT) for line in sio.readlines(): line_read = bz2f.readline() @@ -253,10 +250,9 @@ def test_read(self): from bz2 import BZ2File self.create_temp_file() - + bz2f = BZ2File(self.temppath) - # XXX - # raises(TypeError, bz2f.read, None) + raises(TypeError, bz2f.read, None) text_read = bz2f.read() assert text_read == self.TEXT bz2f.close() @@ -291,7 +287,7 @@ def test_read_chunk9(self): from bz2 import BZ2File self.create_temp_file() - + bz2f = BZ2File(self.temppath) text_read = "" while True: @@ -305,7 +301,7 @@ def test_read_100_bytes(self): from bz2 import BZ2File self.create_temp_file() - + bz2f = BZ2File(self.temppath) assert bz2f.read(100) == self.TEXT[:100] bz2f.close() @@ -313,7 +309,7 @@ def test_universal_newlines_lf(self): from bz2 import BZ2File self.create_temp_file() - + bz2f = BZ2File(self.temppath, "rU") assert bz2f.read() == self.TEXT assert bz2f.newlines == "\n" @@ -322,7 +318,7 @@ def test_universal_newlines_crlf(self): from bz2 import BZ2File self.create_temp_file(crlf=True) - + bz2f = BZ2File(self.temppath, "rU") data = bz2f.read() assert data == self.TEXT @@ -333,10 +329,9 @@ from bz2 import BZ2File from cStringIO import StringIO self.create_temp_file() - + bz2f = BZ2File(self.temppath) - # XXX - #raises(TypeError, bz2f.readlines, None) + raises(TypeError, bz2f.readlines, None) sio = StringIO(self.TEXT) assert bz2f.readlines() == sio.readlines() bz2f.close() @@ -345,17 +340,17 @@ from bz2 import BZ2File from cStringIO import StringIO self.create_temp_file() - + bz2f = BZ2File(self.temppath) sio = StringIO(self.TEXT) assert list(iter(bz2f)) == sio.readlines() bz2f.close() - + def test_xreadlines(self): from bz2 import BZ2File from cStringIO import StringIO self.create_temp_file() - + bz2f = BZ2File(self.temppath) sio = StringIO(self.TEXT) assert list(bz2f.xreadlines()) == sio.readlines() @@ -364,12 +359,12 @@ def test_readlines_bug_1191043(self): # readlines()/xreadlines() for files containing no newline from bz2 import BZ2File - + DATA = 'BZh91AY&SY\xd9b\x89]\x00\x00\x00\x03\x80\x04\x00\x02\x00\x0c\x00 \x00!\x9ah3M\x13<]\xc9\x14\xe1BCe\x8a%t' f = open(self.temppath, "wb") f.write(DATA) f.close() - + bz2f = BZ2File(self.temppath) lines = bz2f.readlines() bz2f.close() @@ -379,7 +374,7 @@ xlines = list(bz2f.xreadlines()) bz2f.close() assert xlines == ['Test'] - + def test_write(self): from bz2 import BZ2File @@ -387,7 +382,7 @@ raises(TypeError, bz2f.write) bz2f.write(self.TEXT) bz2f.close() - + f = open(self.temppath, "rb") assert self.decompress(f.read()) == self.TEXT f.close() @@ -401,11 +396,11 @@ data = self.TEXT[n * 10:(n + 1) * 10] if not data: break - + bz2f.write(data) n += 1 bz2f.close() - + f = open(self.temppath, "rb") assert self.decompress(f.read()) == self.TEXT f.close() @@ -422,7 +417,7 @@ f = open(self.temppath, "rb") assert self.decompress(f.read()) == self.TEXT f.close() - + def test_write_methods_on_readonly_file(self): from bz2 import BZ2File @@ -453,8 +448,8 @@ assert data == "abc" assert f.closed - - + + # has_cmdline_bunzip2 = sys.platform not in ("win32", "os2emx", "riscos") # # if has_cmdline_bunzip2: diff --git a/pypy/module/imp/__init__.py b/pypy/module/imp/__init__.py --- a/pypy/module/imp/__init__.py +++ b/pypy/module/imp/__init__.py @@ -6,12 +6,14 @@ __import__ function. """ interpleveldefs = { + 'SEARCH_ERROR': 'space.wrap(importing.SEARCH_ERROR)', 'PY_SOURCE': 'space.wrap(importing.PY_SOURCE)', 'PY_COMPILED': 'space.wrap(importing.PY_COMPILED)', 'C_EXTENSION': 'space.wrap(importing.C_EXTENSION)', 'PKG_DIRECTORY': 'space.wrap(importing.PKG_DIRECTORY)', 'C_BUILTIN': 'space.wrap(importing.C_BUILTIN)', 'PY_FROZEN': 'space.wrap(importing.PY_FROZEN)', + 'IMP_HOOK': 'space.wrap(importing.IMP_HOOK)', 'get_suffixes': 'interp_imp.get_suffixes', 'get_magic': 'interp_imp.get_magic', diff --git a/pypy/module/micronumpy/arrayimpl/base.py b/pypy/module/micronumpy/arrayimpl/base.py --- a/pypy/module/micronumpy/arrayimpl/base.py +++ b/pypy/module/micronumpy/arrayimpl/base.py @@ -3,6 +3,12 @@ def is_scalar(self): return False + def base(self): + raise NotImplementedError + + def create_iter(self, shape=None): + raise NotImplementedError + class BaseArrayIterator(object): def next(self): raise NotImplementedError # purely abstract base class diff --git a/pypy/module/micronumpy/arrayimpl/concrete.py b/pypy/module/micronumpy/arrayimpl/concrete.py --- a/pypy/module/micronumpy/arrayimpl/concrete.py +++ b/pypy/module/micronumpy/arrayimpl/concrete.py @@ -1,178 +1,20 @@ from pypy.module.micronumpy.arrayimpl import base -from pypy.module.micronumpy import support, loop +from pypy.module.micronumpy import support, loop, iter from pypy.module.micronumpy.base import convert_to_array, W_NDimArray,\ ArrayArgumentException from pypy.module.micronumpy.strides import calc_new_strides, shape_agreement,\ calculate_broadcast_strides, calculate_dot_strides from pypy.module.micronumpy.iter import Chunk, Chunks, NewAxisChunk, RecordChunk from pypy.interpreter.error import OperationError, operationerrfmt +from pypy.interpreter.buffer import RWBuffer +from rpython.rlib import jit from rpython.rtyper.lltypesystem import rffi, lltype -from rpython.rlib import jit -from rpython.rlib.rawstorage import free_raw_storage, RAW_STORAGE +from rpython.rlib.rawstorage import free_raw_storage, raw_storage_getitem,\ + raw_storage_setitem, RAW_STORAGE +from pypy.module.micronumpy.arrayimpl.sort import argsort_array from rpython.rlib.debug import make_sure_not_resized -class ConcreteArrayIterator(base.BaseArrayIterator): - _immutable_fields_ = ['dtype', 'skip', 'size'] - def __init__(self, array): - self.array = array - self.offset = 0 - self.dtype = array.dtype - self.skip = self.dtype.itemtype.get_element_size() - self.size = array.size - - def setitem(self, elem): - self.dtype.setitem(self.array, self.offset, elem) - - def getitem(self): - return self.dtype.getitem(self.array, self.offset) - - def getitem_bool(self): - return self.dtype.getitem_bool(self.array, self.offset) - - def next(self): - self.offset += self.skip - - def next_skip_x(self, x): - self.offset += self.skip * x - - def done(self): - return self.offset >= self.size - - def reset(self): - self.offset %= self.size - -class OneDimViewIterator(ConcreteArrayIterator): - ''' The view iterator dtype can be different from the - array.dtype, this is what makes it a View - ''' - def __init__(self, array, dtype, start, strides, shape): - self.array = array - self.dtype = dtype - self.offset = start - self.skip = strides[0] - self.index = 0 - self.size = shape[0] - - def next(self): - self.offset += self.skip - self.index += 1 - - def next_skip_x(self, x): - self.offset += self.skip * x - self.index += x - - def done(self): - return self.index >= self.size - - def reset(self): - self.offset %= self.size - -class MultiDimViewIterator(ConcreteArrayIterator): - ''' The view iterator dtype can be different from the - array.dtype, this is what makes it a View - ''' - def __init__(self, array, dtype, start, strides, backstrides, shape): - self.indexes = [0] * len(shape) - self.array = array - self.dtype = dtype - self.shape = shape - self.offset = start - self.shapelen = len(shape) - self._done = False - self.strides = strides - self.backstrides = backstrides - self.size = array.size - - @jit.unroll_safe - def next(self): - offset = self.offset - for i in range(self.shapelen - 1, -1, -1): - if self.indexes[i] < self.shape[i] - 1: - self.indexes[i] += 1 - offset += self.strides[i] - break - else: - self.indexes[i] = 0 - offset -= self.backstrides[i] - else: - self._done = True - self.offset = offset - - @jit.unroll_safe - def next_skip_x(self, step): - for i in range(len(self.shape) - 1, -1, -1): - if self.indexes[i] < self.shape[i] - step: - self.indexes[i] += step - self.offset += self.strides[i] * step - break - else: - remaining_step = (self.indexes[i] + step) // self.shape[i] - this_i_step = step - remaining_step * self.shape[i] - self.offset += self.strides[i] * this_i_step - self.indexes[i] = self.indexes[i] + this_i_step - step = remaining_step - else: - self._done = True - - def done(self): - return self._done - - def reset(self): - self.offset %= self.size - -class AxisIterator(base.BaseArrayIterator): - def __init__(self, array, shape, dim): - self.shape = shape - strides = array.get_strides() - backstrides = array.get_backstrides() - if len(shape) == len(strides): - # keepdims = True - self.strides = strides[:dim] + [0] + strides[dim + 1:] - self.backstrides = backstrides[:dim] + [0] + backstrides[dim + 1:] - else: - self.strides = strides[:dim] + [0] + strides[dim:] - self.backstrides = backstrides[:dim] + [0] + backstrides[dim:] - self.first_line = True - self.indices = [0] * len(shape) - self._done = False - self.offset = array.start - self.dim = dim - self.array = array - self.dtype = array.dtype - - def setitem(self, elem): - self.dtype.setitem(self.array, self.offset, elem) - - def getitem(self): - return self.dtype.getitem(self.array, self.offset) - - @jit.unroll_safe - def next(self): - for i in range(len(self.shape) - 1, -1, -1): - if self.indices[i] < self.shape[i] - 1: - if i == self.dim: - self.first_line = False - self.indices[i] += 1 - self.offset += self.strides[i] - break - else: - if i == self.dim: - self.first_line = True - self.indices[i] = 0 - self.offset -= self.backstrides[i] - else: - self._done = True - - def done(self): - return self._done - -def int_w(space, w_obj): - try: - return space.int_w(space.index(w_obj)) - except OperationError: - return space.int_w(space.int(w_obj)) - class BaseConcreteArray(base.BaseArrayImplementation): start = 0 parent = None @@ -213,7 +55,7 @@ def get_size(self): return self.size // self.dtype.itemtype.get_element_size() - def reshape(self, space, new_shape): + def reshape(self, space, orig_array, new_shape): # Since we got to here, prod(new_shape) == self.size new_strides = None if self.size > 0: @@ -226,31 +68,31 @@ for nd in range(ndims): new_backstrides[nd] = (new_shape[nd] - 1) * new_strides[nd] return SliceArray(self.start, new_strides, new_backstrides, - new_shape, self) + new_shape, self, orig_array) else: return None - def get_real(self): + def get_real(self, orig_array): strides = self.get_strides() backstrides = self.get_backstrides() if self.dtype.is_complex_type(): dtype = self.dtype.float_type return SliceArray(self.start, strides, backstrides, - self.get_shape(), self, dtype=dtype) + self.get_shape(), self, orig_array, dtype=dtype) return SliceArray(self.start, strides, backstrides, - self.get_shape(), self) + self.get_shape(), self, orig_array) - def get_imag(self): + def get_imag(self, orig_array): strides = self.get_strides() backstrides = self.get_backstrides() if self.dtype.is_complex_type(): dtype = self.dtype.float_type return SliceArray(self.start + dtype.get_size(), strides, - backstrides, self.get_shape(), self, dtype=dtype) + backstrides, self.get_shape(), self, orig_array, dtype=dtype) if self.dtype.is_flexible_type(): # numpy returns self for self.imag return SliceArray(self.start, strides, backstrides, - self.get_shape(), self) + self.get_shape(), self, orig_array) impl = NonWritableArray(self.get_shape(), self.dtype, self.order, strides, backstrides) impl.fill(self.dtype.box(0)) @@ -265,7 +107,7 @@ for i, w_index in enumerate(view_w): if space.isinstance_w(w_index, space.w_slice): raise IndexError - idx = int_w(space, w_index) + idx = support.int_w(space, w_index) if idx < 0: idx = self.get_shape()[i] + idx if idx < 0 or idx >= self.get_shape()[i]: @@ -339,7 +181,7 @@ return self._lookup_by_index(space, view_w) if shape_len > 1: raise IndexError - idx = int_w(space, w_idx) + idx = support.int_w(space, w_idx) return self._lookup_by_index(space, [space.wrap(idx)]) @jit.unroll_safe @@ -367,26 +209,26 @@ i += 1 return Chunks(result) - def descr_getitem(self, space, w_index): + def descr_getitem(self, space, orig_arr, w_index): try: item = self._single_item_index(space, w_index) return self.getitem(item) except IndexError: # not a single result chunks = self._prepare_slice_args(space, w_index) - return chunks.apply(self) + return chunks.apply(orig_arr) - def descr_setitem(self, space, w_index, w_value): + def descr_setitem(self, space, orig_arr, w_index, w_value): try: item = self._single_item_index(space, w_index) self.setitem(item, self.dtype.coerce(space, w_value)) except IndexError: w_value = convert_to_array(space, w_value) chunks = self._prepare_slice_args(space, w_index) - view = chunks.apply(self) + view = chunks.apply(orig_arr) view.implementation.setslice(space, w_value) - def transpose(self): + def transpose(self, orig_array): if len(self.get_shape()) < 2: return self strides = [] @@ -397,7 +239,7 @@ backstrides.append(self.get_backstrides()[i]) shape.append(self.get_shape()[i]) return SliceArray(self.start, strides, - backstrides, shape, self) + backstrides, shape, self, orig_array) def copy(self): strides, backstrides = support.calc_strides(self.get_shape(), self.dtype, @@ -406,15 +248,15 @@ backstrides) return loop.setslice(self.get_shape(), impl, self) - def create_axis_iter(self, shape, dim): - return AxisIterator(self, shape, dim) + def create_axis_iter(self, shape, dim, cum): + return iter.AxisIterator(self, shape, dim, cum) def create_dot_iter(self, shape, skip): r = calculate_dot_strides(self.get_strides(), self.get_backstrides(), shape, skip) - return MultiDimViewIterator(self, self.dtype, self.start, r[0], r[1], shape) + return iter.MultiDimViewIterator(self, self.dtype, self.start, r[0], r[1], shape) - def swapaxes(self, axis1, axis2): + def swapaxes(self, orig_arr, axis1, axis2): shape = self.get_shape()[:] strides = self.get_strides()[:] backstrides = self.get_backstrides()[:] @@ -422,13 +264,20 @@ strides[axis1], strides[axis2] = strides[axis2], strides[axis1] backstrides[axis1], backstrides[axis2] = backstrides[axis2], backstrides[axis1] return W_NDimArray.new_slice(self.start, strides, - backstrides, shape, self) + backstrides, shape, self, orig_arr) def get_storage_as_int(self, space): return rffi.cast(lltype.Signed, self.storage) + def get_storage(self): + return self.storage + + def get_buffer(self, space): + return ArrayBuffer(self) + class ConcreteArrayNotOwning(BaseConcreteArray): def __init__(self, shape, dtype, order, strides, backstrides, storage): + make_sure_not_resized(shape) make_sure_not_resized(strides) make_sure_not_resized(backstrides) @@ -442,19 +291,31 @@ def create_iter(self, shape=None): if shape is None or shape == self.get_shape(): - return ConcreteArrayIterator(self) + return iter.ConcreteArrayIterator(self) r = calculate_broadcast_strides(self.get_strides(), self.get_backstrides(), self.get_shape(), shape) - return MultiDimViewIterator(self, self.dtype, 0, r[0], r[1], shape) + return iter.MultiDimViewIterator(self, self.dtype, 0, r[0], r[1], shape) def fill(self, box): self.dtype.fill(self.storage, box, 0, self.size) - def set_shape(self, space, new_shape): + def set_shape(self, space, orig_array, new_shape): strides, backstrides = support.calc_strides(new_shape, self.dtype, self.order) - return SliceArray(0, strides, backstrides, new_shape, self) + return SliceArray(0, strides, backstrides, new_shape, self, + orig_array) + + def argsort(self, space, w_axis): + return argsort_array(self, space, w_axis) + + def astype(self, space, dtype): + new_arr = W_NDimArray.from_shape(self.get_shape(), dtype) + loop.copy_from_to(self, new_arr.implementation, dtype) + return new_arr + + def base(self): + return None class ConcreteArray(ConcreteArrayNotOwning): def __init__(self, shape, dtype, order, strides, backstrides): @@ -469,14 +330,17 @@ free_raw_storage(self.storage, track_allocation=False) + + class NonWritableArray(ConcreteArray): - def descr_setitem(self, space, w_index, w_value): + def descr_setitem(self, space, orig_array, w_index, w_value): raise OperationError(space.w_RuntimeError, space.wrap( "array is not writable")) class SliceArray(BaseConcreteArray): - def __init__(self, start, strides, backstrides, shape, parent, dtype=None): + def __init__(self, start, strides, backstrides, shape, parent, orig_arr, + dtype=None): self.strides = strides self.backstrides = backstrides self.shape = shape @@ -490,6 +354,10 @@ self.dtype = dtype self.size = support.product(shape) * self.dtype.itemtype.get_element_size() self.start = start + self.orig_arr = orig_arr + + def base(self): + return self.orig_arr def fill(self, box): loop.fill(self, box.convert_to(self.dtype)) @@ -499,16 +367,16 @@ r = calculate_broadcast_strides(self.get_strides(), self.get_backstrides(), self.get_shape(), shape) - return MultiDimViewIterator(self.parent, self.dtype, - self.start, r[0], r[1], shape) + return iter.MultiDimViewIterator(self.parent, self.dtype, + self.start, r[0], r[1], shape) if len(self.get_shape()) == 1: - return OneDimViewIterator(self.parent, self.dtype, self.start, + return iter.OneDimViewIterator(self.parent, self.dtype, self.start, self.get_strides(), self.get_shape()) - return MultiDimViewIterator(self.parent, self.dtype, self.start, + return iter.MultiDimViewIterator(self.parent, self.dtype, self.start, self.get_strides(), self.get_backstrides(), self.get_shape()) - def set_shape(self, space, new_shape): + def set_shape(self, space, orig_array, new_shape): if len(self.get_shape()) < 2 or self.size == 0: # TODO: this code could be refactored into calc_strides # but then calc_strides would have to accept a stepping factor @@ -527,7 +395,7 @@ backstrides.reverse() new_shape.reverse() return SliceArray(self.start, strides, backstrides, new_shape, - self) + self, orig_array) new_strides = calc_new_strides(new_shape, self.get_shape(), self.get_strides(), self.order) @@ -538,4 +406,18 @@ for nd in range(len(new_shape)): new_backstrides[nd] = (new_shape[nd] - 1) * new_strides[nd] return SliceArray(self.start, new_strides, new_backstrides, new_shape, - self) + self, orig_array) + +class ArrayBuffer(RWBuffer): + def __init__(self, impl): + self.impl = impl + + def getitem(self, item): + return raw_storage_getitem(lltype.Char, self.impl.storage, item) + + def setitem(self, item, v): + return raw_storage_setitem(self.impl.storage, item, + rffi.cast(lltype.Char, v)) + + def getlength(self): + return self.impl.size diff --git a/pypy/module/micronumpy/arrayimpl/scalar.py b/pypy/module/micronumpy/arrayimpl/scalar.py --- a/pypy/module/micronumpy/arrayimpl/scalar.py +++ b/pypy/module/micronumpy/arrayimpl/scalar.py @@ -54,10 +54,10 @@ def get_size(self): return 1 - def transpose(self): + def transpose(self, _): return self - def descr_getitem(self, space, w_idx): + def descr_getitem(self, space, _, w_idx): raise OperationError(space.w_IndexError, space.wrap("scalars cannot be indexed")) @@ -65,14 +65,14 @@ raise OperationError(space.w_IndexError, space.wrap("scalars cannot be indexed")) - def descr_setitem(self, space, w_idx, w_val): + def descr_setitem(self, space, _, w_idx, w_val): raise OperationError(space.w_IndexError, space.wrap("scalars cannot be indexed")) def setitem_index(self, space, idx, w_val): raise OperationError(space.w_IndexError, space.wrap("scalars cannot be indexed")) - def set_shape(self, space, new_shape): + def set_shape(self, space, orig_array, new_shape): if not new_shape: return self if support.product(new_shape) == 1: @@ -83,13 +83,13 @@ raise OperationError(space.w_ValueError, space.wrap( "total size of the array must be unchanged")) - def reshape(self, space, new_shape): - return self.set_shape(space, new_shape) + def reshape(self, space, orig_array, new_shape): + return self.set_shape(space, orig_array, new_shape) - def create_axis_iter(self, shape, dim): + def create_axis_iter(self, shape, dim, cum): raise Exception("axis iter should not happen on scalar") - def swapaxes(self, axis1, axis2): + def swapaxes(self, orig_array, axis1, axis2): raise Exception("should not be called") def fill(self, w_value): @@ -98,3 +98,17 @@ def get_storage_as_int(self, space): raise OperationError(space.w_ValueError, space.wrap("scalars have no address")) + + def argsort(self, space, w_axis): + return space.wrap(0) + + def astype(self, space, dtype): + return W_NDimArray.new_scalar(space, dtype, self.value) + + def base(self): + return None + + def get_buffer(self, space): + raise OperationError(space.w_ValueError, space.wrap( + "cannot point buffer to a scalar")) + diff --git a/pypy/module/micronumpy/arrayimpl/sort.py b/pypy/module/micronumpy/arrayimpl/sort.py new file mode 100644 --- /dev/null +++ b/pypy/module/micronumpy/arrayimpl/sort.py @@ -0,0 +1,195 @@ + +""" This is the implementation of various sorting routines in numpy. It's here +because it only makes sense on a concrete array +""" + +from rpython.rtyper.lltypesystem import rffi, lltype +from rpython.rlib.listsort import make_timsort_class +from rpython.rlib.rawstorage import raw_storage_getitem, raw_storage_setitem, \ + free_raw_storage, alloc_raw_storage +from rpython.rlib.unroll import unrolling_iterable +from rpython.rlib.rarithmetic import intmask +from rpython.rlib.objectmodel import specialize +from pypy.interpreter.error import OperationError +from pypy.module.micronumpy.base import W_NDimArray +from pypy.module.micronumpy import interp_dtype, types +from pypy.module.micronumpy.iter import AxisIterator + +INT_SIZE = rffi.sizeof(lltype.Signed) + +def make_sort_function(space, itemtype, comp_type, count=1): + TP = itemtype.T + step = rffi.sizeof(TP) + + class Repr(object): + def __init__(self, index_stride_size, stride_size, size, values, + indexes, index_start, start): + self.index_stride_size = index_stride_size + self.stride_size = stride_size + self.index_start = index_start + self.start = start + self.size = size + self.values = values + self.indexes = indexes + + def getitem(self, item): + if count < 2: + v = raw_storage_getitem(TP, self.values, item * self.stride_size + + self.start) + else: + v = [] + for i in range(count): + _v = raw_storage_getitem(TP, self.values, item * self.stride_size + + self.start + step * i) + v.append(_v) + if comp_type == 'int': + v = intmask(v) + elif comp_type == 'float': + v = float(v) + elif comp_type == 'complex': + v = [float(v[0]),float(v[1])] + else: + raise NotImplementedError('cannot reach') + return (v, raw_storage_getitem(lltype.Signed, self.indexes, + item * self.index_stride_size + + self.index_start)) + + def setitem(self, idx, item): + if count < 2: + raw_storage_setitem(self.values, idx * self.stride_size + + self.start, rffi.cast(TP, item[0])) + else: + i = 0 + for val in item[0]: + raw_storage_setitem(self.values, idx * self.stride_size + + self.start + i*step, rffi.cast(TP, val)) + i += 1 + raw_storage_setitem(self.indexes, idx * self.index_stride_size + + self.index_start, item[1]) + + class ArgArrayRepWithStorage(Repr): + def __init__(self, index_stride_size, stride_size, size): + start = 0 + dtype = interp_dtype.get_dtype_cache(space).w_longdtype + self.indexes = dtype.itemtype.malloc(size*dtype.get_size()) + self.values = alloc_raw_storage(size * stride_size, + track_allocation=False) + Repr.__init__(self, index_stride_size, stride_size, + size, self.values, self.indexes, start, start) + + def __del__(self): + free_raw_storage(self.indexes, track_allocation=False) + free_raw_storage(self.values, track_allocation=False) + + def arg_getitem(lst, item): + return lst.getitem(item) + + def arg_setitem(lst, item, value): + lst.setitem(item, value) + + def arg_length(lst): + return lst.size + + def arg_getitem_slice(lst, start, stop): + retval = ArgArrayRepWithStorage(lst.index_stride_size, lst.stride_size, + stop-start) + for i in range(stop-start): + retval.setitem(i, lst.getitem(i+start)) + return retval + + if count < 2: + def arg_lt(a, b): + # Does numpy do <= ? + return a[0] < b[0] + else: + def arg_lt(a, b): + for i in range(count): + if a[0][i] < b[0][i]: + return True + elif a[0][i] > b[0][i]: + return False + # Does numpy do True? + return False + + ArgSort = make_timsort_class(arg_getitem, arg_setitem, arg_length, + arg_getitem_slice, arg_lt) + + def argsort(arr, space, w_axis, itemsize): + if w_axis is space.w_None: + # note that it's fine ot pass None here as we're not going + # to pass the result around (None is the link to base in slices) + arr = arr.reshape(space, None, [arr.get_size()]) + axis = 0 + elif w_axis is None: + axis = -1 + else: + axis = space.int_w(w_axis) + # create array of indexes + dtype = interp_dtype.get_dtype_cache(space).w_longdtype + index_arr = W_NDimArray.from_shape(arr.get_shape(), dtype) + storage = index_arr.implementation.get_storage() + if len(arr.get_shape()) == 1: + for i in range(arr.get_size()): + raw_storage_setitem(storage, i * INT_SIZE, i) + r = Repr(INT_SIZE, itemsize, arr.get_size(), arr.get_storage(), + storage, 0, arr.start) + ArgSort(r).sort() + else: + shape = arr.get_shape() + if axis < 0: + axis = len(shape) + axis - 1 + if axis < 0 or axis > len(shape): + raise OperationError(space.w_IndexError, space.wrap( + "Wrong axis %d" % axis)) + iterable_shape = shape[:axis] + [0] + shape[axis + 1:] + iter = AxisIterator(arr, iterable_shape, axis, False) + index_impl = index_arr.implementation + index_iter = AxisIterator(index_impl, iterable_shape, axis, False) + stride_size = arr.strides[axis] + index_stride_size = index_impl.strides[axis] + axis_size = arr.shape[axis] + while not iter.done(): + for i in range(axis_size): + raw_storage_setitem(storage, i * index_stride_size + + index_iter.offset, i) + r = Repr(index_stride_size, stride_size, axis_size, + arr.get_storage(), storage, index_iter.offset, iter.offset) + ArgSort(r).sort() + iter.next() + index_iter.next() + return index_arr + + return argsort + +def argsort_array(arr, space, w_axis): + cache = space.fromcache(SortCache) # that populates SortClasses + itemtype = arr.dtype.itemtype + for tp in all_types: + if isinstance(itemtype, tp[0]): + return cache._lookup(tp)(arr, space, w_axis, + itemtype.get_element_size()) + # XXX this should probably be changed From noreply at buildbot.pypy.org Thu Feb 7 16:28:53 2013 From: noreply at buildbot.pypy.org (jerith) Date: Thu, 7 Feb 2013 16:28:53 +0100 (CET) Subject: [pypy-commit] pypy curses_cffi: First stab at cffi-based _curses implementation. Message-ID: <20130207152853.5E4221C02D9@cobra.cs.uni-duesseldorf.de> Author: Jeremy Thurgood Branch: curses_cffi Changeset: r60935:9e15167381cb Date: 2012-11-01 16:09 +0200 http://bitbucket.org/pypy/pypy/changeset/9e15167381cb/ Log: First stab at cffi-based _curses implementation. diff --git a/lib_pypy/_curses.py b/lib_pypy/_curses.py new file mode 100644 --- /dev/null +++ b/lib_pypy/_curses.py @@ -0,0 +1,1360 @@ +"""Reimplementation of the standard extension module '_curses' using cffi.""" + +import sys +from functools import wraps + +from cffi import FFI + +ffi = FFI() + +ffi.cdef(""" +typedef ... WINDOW; +typedef ... SCREEN; +typedef unsigned long mmask_t; +typedef unsigned char bool; +typedef unsigned int chtype; +typedef chtype attr_t; + +typedef struct +{ + short id; /* ID to distinguish multiple devices */ + int x, y, z; /* event coordinates (character-cell) */ + mmask_t bstate; /* button state bits */ +} +MEVENT; + +static const int ERR, OK; +static const int TRUE, FALSE; +static const int KEY_MIN, KEY_MAX; + +static const int COLOR_BLACK; +static const int COLOR_RED; +static const int COLOR_GREEN; +static const int COLOR_YELLOW; +static const int COLOR_BLUE; +static const int COLOR_MAGENTA; +static const int COLOR_CYAN; +static const int COLOR_WHITE; + +static const chtype A_ATTRIBUTES; +static const chtype A_NORMAL; +static const chtype A_STANDOUT; +static const chtype A_UNDERLINE; +static const chtype A_REVERSE; +static const chtype A_BLINK; +static const chtype A_DIM; +static const chtype A_BOLD; +static const chtype A_ALTCHARSET; +static const chtype A_INVIS; +static const chtype A_PROTECT; +static const chtype A_CHARTEXT; +static const chtype A_COLOR; + +static const int BUTTON1_RELEASED; +static const int BUTTON1_PRESSED; +static const int BUTTON1_CLICKED; +static const int BUTTON1_DOUBLE_CLICKED; +static const int BUTTON1_TRIPLE_CLICKED; +static const int BUTTON2_RELEASED; +static const int BUTTON2_PRESSED; +static const int BUTTON2_CLICKED; +static const int BUTTON2_DOUBLE_CLICKED; +static const int BUTTON2_TRIPLE_CLICKED; +static const int BUTTON3_RELEASED; +static const int BUTTON3_PRESSED; +static const int BUTTON3_CLICKED; +static const int BUTTON3_DOUBLE_CLICKED; +static const int BUTTON3_TRIPLE_CLICKED; +static const int BUTTON4_RELEASED; +static const int BUTTON4_PRESSED; +static const int BUTTON4_CLICKED; +static const int BUTTON4_DOUBLE_CLICKED; +static const int BUTTON4_TRIPLE_CLICKED; +static const int BUTTON_SHIFT; +static const int BUTTON_CTRL; +static const int BUTTON_ALT; +static const int ALL_MOUSE_EVENTS; +static const int REPORT_MOUSE_POSITION; + +int setupterm(char *, int, int *); + +WINDOW *stdscr; +int COLORS; +int COLOR_PAIRS; +int COLS; +int LINES; + +int baudrate(void); +int beep(void); +int box(WINDOW *, chtype, chtype); +bool can_change_color(void); +int cbreak(void); +int clearok(WINDOW *, bool); +int color_content(short, short*, short*, short*); +int copywin(const WINDOW*, WINDOW*, int, int, int, int, int, int, int); +int curs_set(int); +int def_prog_mode(void); +int def_shell_mode(void); +int delay_output(int); +int delwin(WINDOW *); +WINDOW * derwin(WINDOW *, int, int, int, int); +int doupdate(void); +int echo(void); +int endwin(void); +char erasechar(void); +void filter(void); +int flash(void); +int flushinp(void); +chtype getbkgd(WINDOW *); +WINDOW * getwin(FILE *); +int halfdelay(int); +bool has_colors(void); +bool has_ic(void); +bool has_il(void); +void idcok(WINDOW *, bool); +int idlok(WINDOW *, bool); +void immedok(WINDOW *, bool); +WINDOW * initscr(void); +int init_color(short, short, short, short); +int init_pair(short, short, short); +int intrflush(WINDOW *, bool); +bool isendwin(void); +bool is_linetouched(WINDOW *, int); +bool is_wintouched(WINDOW *); +char * keyname(int); +int keypad(WINDOW *, bool); +char killchar(void); +int leaveok(WINDOW *, bool); +char * longname(void); +int meta(WINDOW *, bool); +int mvderwin(WINDOW *, int, int); +int mvwaddch(WINDOW *, int, int, const chtype); +int mvwaddnstr(WINDOW *, int, int, const char *, int); +int mvwaddstr(WINDOW *, int, int, const char *); +int mvwchgat(WINDOW *, int, int, int, attr_t, short, const void *); +int mvwdelch(WINDOW *, int, int); +int mvwgetch(WINDOW *, int, int); +int mvwgetnstr(WINDOW *, int, int, char *, int); +int mvwin(WINDOW *, int, int); +chtype mvwinch(WINDOW *, int, int); +int mvwinnstr(WINDOW *, int, int, char *, int); +int mvwinsch(WINDOW *, int, int, chtype); +int mvwinsnstr(WINDOW *, int, int, const char *, int); +int mvwinsstr(WINDOW *, int, int, const char *); +int napms(int); +WINDOW * newpad(int, int); +WINDOW * newwin(int, int, int, int); +int nl(void); +int nocbreak(void); +int nodelay(WINDOW *, bool); +int noecho(void); +int nonl(void); +void noqiflush(void); +int noraw(void); +int notimeout(WINDOW *, bool); +int overlay(const WINDOW*, WINDOW *); +int overwrite(const WINDOW*, WINDOW *); +int pair_content(short, short*, short*); +int pechochar(WINDOW *, const chtype); +int pnoutrefresh(WINDOW*, int, int, int, int, int, int); +int prefresh(WINDOW *, int, int, int, int, int, int); +int putwin(WINDOW *, FILE *); +void qiflush(void); +int raw(void); +int redrawwin(WINDOW *); +int resetty(void); +int reset_prog_mode(void); +int reset_shell_mode(void); +int savetty(void); +int scroll(WINDOW *); +int scrollok(WINDOW *, bool); +int start_color(void); +WINDOW * subpad(WINDOW *, int, int, int, int); +WINDOW * subwin(WINDOW *, int, int, int, int); +int syncok(WINDOW *, bool); +chtype termattrs(void); +char * termname(void); +int touchline(WINDOW *, int, int); +int touchwin(WINDOW *); +int typeahead(int); +int ungetch(int); +int untouchwin(WINDOW *); +void use_env(bool); +int waddch(WINDOW *, const chtype); +int waddnstr(WINDOW *, const char *, int); +int waddstr(WINDOW *, const char *); +int wattron(WINDOW *, int); +int wattroff(WINDOW *, int); +int wattrset(WINDOW *, int); +int wbkgd(WINDOW *, chtype); +void wbkgdset(WINDOW *, chtype); +int wborder(WINDOW *, chtype, chtype, chtype, chtype, + chtype, chtype, chtype, chtype); +int wchgat(WINDOW *, int, attr_t, short, const void *); +int wclear(WINDOW *); +int wclrtobot(WINDOW *); +int wclrtoeol(WINDOW *); +void wcursyncup(WINDOW *); +int wdelch(WINDOW *); +int wdeleteln(WINDOW *); +int wechochar(WINDOW *, const chtype); +int werase(WINDOW *); +int wgetch(WINDOW *); +int wgetnstr(WINDOW *, char *, int); +int whline(WINDOW *, chtype, int); +chtype winch(WINDOW *); +int winnstr(WINDOW *, char *, int); +int winsch(WINDOW *, chtype); +int winsdelln(WINDOW *, int); +int winsertln(WINDOW *); +int winsnstr(WINDOW *, const char *, int); +int winsstr(WINDOW *, const char *); +int wmove(WINDOW *, int, int); +int wnoutrefresh(WINDOW *); +int wredrawln(WINDOW *, int, int); +int wrefresh(WINDOW *); +int wscrl(WINDOW *, int); +int wsetscrreg(WINDOW *, int, int); +int wstandout(WINDOW *); +int wstandend(WINDOW *); +void wsyncdown(WINDOW *); +void wsyncup(WINDOW *); +void wtimeout(WINDOW *, int); +int wtouchln(WINDOW *, int, int, int); +int wvline(WINDOW *, chtype, int); +int tigetflag(char *); +int tigetnum(char *); +char * tigetstr(char *); +int putp(const char *); +char * tparm(char *, ...); +int getattrs(const WINDOW *); +int getcurx(const WINDOW *); +int getcury(const WINDOW *); +int getbegx(const WINDOW *); +int getbegy(const WINDOW *); +int getmaxx(const WINDOW *); +int getmaxy(const WINDOW *); +int getparx(const WINDOW *); +int getpary(const WINDOW *); + +int getmouse(MEVENT *); +int ungetmouse(MEVENT *); +mmask_t mousemask(mmask_t, mmask_t *); +bool wenclose(const WINDOW *, int, int); +int mouseinterval(int); + +void getsyx(int y, int x); +void setsyx(int y, int x); +char *unctrl(chtype); +int use_default_colors(void); + +int has_key(int); +bool is_term_resized(int, int); + +#define _m_STRICT_SYSV_CURSES ... +#define _m_NCURSES_MOUSE_VERSION ... +#define _m_NetBSD ... +int _m_ispad(WINDOW *); + +chtype acs_map[]; + +// For _curses_panel: + +typedef ... PANEL; + +WINDOW *panel_window(const PANEL *); +void update_panels(void); +int hide_panel(PANEL *); +int show_panel(PANEL *); +int del_panel(PANEL *); +int top_panel(PANEL *); +int bottom_panel(PANEL *); +PANEL *new_panel(WINDOW *); +PANEL *panel_above(const PANEL *); +PANEL *panel_below(const PANEL *); +int set_panel_userptr(PANEL *, void *); +void *panel_userptr(const PANEL *); +int move_panel(PANEL *, int, int); +int replace_panel(PANEL *,WINDOW *); +int panel_hidden(const PANEL *); +""") + + +lib = ffi.verify(""" +#include +#include +#include + +#if defined STRICT_SYSV_CURSES +#define _m_STRICT_SYSV_CURSES TRUE +#else +#define _m_STRICT_SYSV_CURSES FALSE +#endif + +#if defined NCURSES_MOUSE_VERSION +#define _m_NCURSES_MOUSE_VERSION TRUE +#else +#define _m_NCURSES_MOUSE_VERSION FALSE +#endif + +#if defined __NetBSD__ +#define _m_NetBSD TRUE +#else +#define _m_NetBSD FALSE +#endif + +int _m_ispad(WINDOW *win) { +#if defined WINDOW_HAS_FLAGS + return (win->_flags & _ISPAD); +#else + return 0; +#endif +} +""", libraries=['ncurses', 'panel']) + + +def _copy_to_globals(name): + globals()[name] = getattr(lib, name) + + +def _setup(): + for name in ['ERR', 'OK', 'KEY_MIN', 'KEY_MAX', + 'A_ATTRIBUTES', 'A_NORMAL', 'A_STANDOUT', 'A_UNDERLINE', + 'A_REVERSE', 'A_BLINK', 'A_DIM', 'A_BOLD', 'A_ALTCHARSET', + 'A_PROTECT', 'A_CHARTEXT', 'A_COLOR', + 'COLOR_BLACK', 'COLOR_RED', 'COLOR_GREEN', 'COLOR_YELLOW', + 'COLOR_BLUE', 'COLOR_MAGENTA', 'COLOR_CYAN', 'COLOR_WHITE', + ]: + _copy_to_globals(name) + + if not lib._m_NetBSD: + _copy_to_globals('A_INVIS') + + for name in ['A_HORIZONTAL', 'A_LEFT', 'A_LOW', 'A_RIGHT', 'A_TOP', + 'A_VERTICAL', + ]: + if hasattr(lib, name): + _copy_to_globals(name) + + if lib._m_NCURSES_MOUSE_VERSION: + for name in ["BUTTON1_PRESSED", "BUTTON1_RELEASED", "BUTTON1_CLICKED", + "BUTTON1_DOUBLE_CLICKED", "BUTTON1_TRIPLE_CLICKED", + "BUTTON2_PRESSED", "BUTTON2_RELEASED", "BUTTON2_CLICKED", + "BUTTON2_DOUBLE_CLICKED", "BUTTON2_TRIPLE_CLICKED", + "BUTTON3_PRESSED", "BUTTON3_RELEASED", "BUTTON3_CLICKED", + "BUTTON3_DOUBLE_CLICKED", "BUTTON3_TRIPLE_CLICKED", + "BUTTON4_PRESSED", "BUTTON4_RELEASED", "BUTTON4_CLICKED", + "BUTTON4_DOUBLE_CLICKED", "BUTTON4_TRIPLE_CLICKED", + "BUTTON_SHIFT", "BUTTON_CTRL", "BUTTON_ALT", + "ALL_MOUSE_EVENTS", "REPORT_MOUSE_POSITION", + ]: + _copy_to_globals(name) + + if not lib._m_NetBSD: + for key in range(lib.KEY_MIN, lib.KEY_MAX): + key_n = lib.keyname(key) + if key_n == ffi.NULL or ffi.string(key_n) == "UNKNOWN KEY": + continue + key_n = ffi.string(key_n).replace('(', '').replace(')', '') + globals()[key_n] = key + +_setup() + +# Do we want this? +# version = "2.2" +# __version__ = "2.2" + + +# ____________________________________________________________ + + +_initialised_setupterm = False +_initialised = False +_initialised_color = False + + +def _ensure_initialised_setupterm(): + if not _initialised_setupterm: + raise error("must call (at least) setupterm() first") + + +def _ensure_initialised(): + if not _initialised: + raise error("must call initscr() first") + + +def _ensure_initialised_color(): + if not _initialised and _initialised_color: + raise error("must call start_color() first") + + +def _check_ERR(code, fname): + if code != lib.ERR: + return None + elif fname is None: + raise error("curses function returned ERR") + else: + raise error("%s() returned ERR" % (fname,)) + + +def _check_NULL(rval): + if rval == ffi.NULL: + raise error("curses function returned NULL") + return rval + + +def _call_lib(method_name, *args): + return getattr(lib, method_name)(*args) + + +def _call_lib_check_ERR(method_name, *args): + return _check_ERR(_call_lib(method_name, *args), method_name) + + +def _mk_no_return(method_name): + def _execute(): + _ensure_initialised() + return _call_lib_check_ERR(method_name) + _execute.__name__ = method_name + return _execute + + +def _mk_flag_func(method_name): + # This is in the CPython implementation, but not documented anywhere. + # We have to support it, though, even if it make me sad. + def _execute(flag=True): + _ensure_initialised() + if flag: + return _call_lib_check_ERR(method_name) + else: + return _call_lib_check_ERR('no' + method_name) + _execute.__name__ = method_name + return _execute + + +def _mk_return_val(method_name): + def _execute(): + return _call_lib(method_name) + _execute.__name__ = method_name + return _execute + + +def _mk_w_getyx(method_name): + def _execute(self): + y = _call_lib(method_name + 'y', self._win) + x = _call_lib(method_name + 'x', self._win) + return (y, x) + _execute.__name__ = method_name + return _execute + + +def _mk_w_no_return(method_name): + def _execute(self, *args): + return _call_lib_check_ERR(method_name, self._win, *args) + _execute.__name__ = method_name + return _execute + + +def _mk_w_return_val(method_name): + def _execute(self, *args): + return _call_lib(method_name, self._win, *args) + _execute.__name__ = method_name + return _execute + + +def _chtype(ch): + return int(ffi.cast("chtype", ch)) + + +def _extract_yx(args): + if len(args) >= 2: + return (args[0], args[1], args[2:]) + return (None, None, args) + + +def _process_args(funcname, args, count, optcount, frontopt=0): + outargs = [] + if frontopt: + if len(args) > count + optcount: + # We have the front optional args here. + outargs.extend(args[:frontopt]) + args = args[frontopt:] + else: + # No front optional args, so make them None. + outargs.extend([None] * frontopt) + if (len(args) < count) or (len(args) > count + optcount): + raise error("%s requires %s to %s arguments" % ( + funcname, count, count + optcount + frontopt)) + outargs.extend(args) + return outargs + + +def _argspec(count, optcount=0, frontopt=0): + def _argspec_deco(func): + @wraps(func) + def _wrapped(self, *args): + outargs = _process_args( + func.__name__, args, count, optcount, frontopt) + return func(self, *outargs) + return _wrapped + return _argspec_deco + + +# ____________________________________________________________ + + +class error(Exception): + pass + + +class Window(object): + def __init__(self, window): + self._win = window + + def __del__(self): + if self._win != lib.stdscr: + lib.delwin(self._win) + + untouchwin = _mk_w_no_return("untouchwin") + touchwin = _mk_w_no_return("touchwin") + redrawwin = _mk_w_no_return("redrawwin") + insertln = _mk_w_no_return("winsertln") + erase = _mk_w_no_return("werase") + deleteln = _mk_w_no_return("wdeleteln") + + is_wintouched = _mk_w_return_val("is_wintouched") + + syncdown = _mk_w_return_val("wsyncdown") + syncup = _mk_w_return_val("wsyncup") + standend = _mk_w_return_val("wstandend") + standout = _mk_w_return_val("wstandout") + cursyncup = _mk_w_return_val("wcursyncup") + clrtoeol = _mk_w_return_val("wclrtoeol") + clrtobot = _mk_w_return_val("wclrtobot") + clear = _mk_w_return_val("wclear") + + idcok = _mk_w_no_return("idcok") + immedok = _mk_w_no_return("immedok") + timeout = _mk_w_no_return("wtimeout") + + getyx = _mk_w_getyx("getcur") + getbegyx = _mk_w_getyx("getbeg") + getmaxyx = _mk_w_getyx("getmax") + getparyx = _mk_w_getyx("getpar") + + clearok = _mk_w_no_return("clearok") + idlok = _mk_w_no_return("idlok") + leaveok = _mk_w_no_return("leaveok") + notimeout = _mk_w_no_return("notimeout") + scrollok = _mk_w_no_return("scrollok") + insdelln = _mk_w_no_return("winsdelln") + syncok = _mk_w_no_return("syncok") + + mvwin = _mk_w_no_return("mvwin") + mvderwin = _mk_w_no_return("mvderwin") + move = _mk_w_no_return("wmove") + + if not lib._m_STRICT_SYSV_CURSES: + resize = _mk_w_no_return("wresize") + + if lib._m_NetBSD: + keypad = _mk_w_return_val("keypad") + nodelay = _mk_w_return_val("nodelay") + else: + keypad = _mk_w_no_return("keypad") + nodelay = _mk_w_no_return("nodelay") + + @_argspec(1, 1, 2) + def addch(self, y, x, ch, attr=None): + if attr is None: + attr = lib.A_NORMAL + ch = _chtype(ch) + + if y is not None: + code = lib.mvwaddch(self._win, y, x, ch | attr) + else: + code = lib.waddch(self._win, ch | attr) + return _check_ERR(code, "addch") + + @_argspec(1, 1, 2) + def addstr(self, y, x, text, attr=None): + if attr is not None: + attr_old = lib.getattrs(self._win) + lib.wattrset(self._win, attr) + if y is not None: + code = lib.mvwaddstr(self._win, y, x, text) + else: + code = lib.waddstr(self._win, text) + if attr is not None: + lib.wattrset(self._win, attr_old) + return _check_ERR(code, "addstr") + + @_argspec(2, 1, 2) + def addnstr(self, y, x, text, n, attr=None): + if attr is not None: + attr_old = lib.getattrs(self._win) + lib.wattrset(self._win, attr) + if y is not None: + code = lib.mvwaddnstr(self._win, y, x, text, n) + else: + code = lib.waddnstr(self._win, text, n) + if attr is not None: + lib.wattrset(self._win, attr_old) + return _check_ERR(code, "addnstr") + + def bkgd(self, ch, attr=None): + if attr is None: + attr = lib.A_NORMAL + return _check_ERR(lib.wbkgd(self._win, _chtype(ch) | attr), "bkgd") + + attroff = _mk_w_no_return("wattroff") + attron = _mk_w_no_return("wattron") + attrset = _mk_w_no_return("wattrset") + + def bkgdset(self, ch, attr=None): + if attr is None: + attr = lib.A_NORMAL + lib.wbkgdset(self._win, _chtype(ch) | attr) + return None + + def border(self, ls=0, rs=0, ts=0, bs=0, tl=0, tr=0, bl=0, br=0): + lib.wborder(self._win, + _chtype(ls), _chtype(rs), _chtype(ts), _chtype(bs), + _chtype(tl), _chtype(tr), _chtype(bl), _chtype(br)) + return None + + def box(self, vertint=0, horint=0): + lib.box(self._win, vertint, horint) + return None + + @_argspec(1, 1, 2) + def chgat(self, y, x, num, attr=None): + # These optional args are in a weird order. + if attr is None: + attr = num + num = -1 + + color = ((attr >> 8) & 0xff) + attr = attr - (color << 8) + + if y is not None: + code = lib.mvwchgat(self._win, y, x, num, attr, color, ffi.NULL) + lib.touchline(self._win, y, 1) + else: + yy, _ = self.getyx() + code = lib.wchgat(self._win, num, attr, color, ffi.NULL) + lib.touchline(self._win, yy, 1) + return _check_ERR(code, "chgat") + + def delch(self, *args): + if len(args) == 0: + code = lib.wdelch(self._win) + elif len(args) == 2: + code = lib.mvwdelch(self._win, *args) + else: + raise error("delch requires 0 or 2 arguments") + return _check_ERR(code, "[mv]wdelch") + + def derwin(self, *args): + nlines = 0 + ncols = 0 + if len(args) == 2: + begin_y, begin_x = args + elif len(args) == 4: + nlines, ncols, begin_y, begin_x = args + else: + raise error("derwin requires 2 or 4 arguments") + + win = lib.derwin(self._win, nlines, ncols, begin_y, begin_x) + return Window(_check_NULL(win)) + + def echochar(self, ch, attr=None): + if attr is None: + attr = lib.A_NORMAL + ch = _chtype(ch) + + if lib._m_ispad(self._win): + code = lib.pechochar(self._win, ch | attr) + else: + code = lib.wechochar(self._win, ch | attr) + return _check_ERR(code, "echochar") + + if lib._m_NCURSES_MOUSE_VERSION: + enclose = _mk_w_return_val("wenclose") + + getbkgd = _mk_w_return_val("getbkgd") + + def getch(self, *args): + if len(args) == 0: + val = lib.wgetch(self._win) + elif len(args) == 2: + val = lib.mvwgetch(self._win, *args) + else: + raise error("getch requires 0 or 2 arguments") + return val + + def getkey(self, *args): + if len(args) == 0: + val = lib.wgetch(self._win) + elif len(args) == 2: + val = lib.mvwgetch(self._win, *args) + else: + raise error("getkey requires 0 or 2 arguments") + + if val == lib.ERR: + raise error("no input") + elif val <= 255: + return chr(val) + else: + # XXX: The following line is different if `__NetBSD__` is defined. + val = lib.keyname(val) + if val == ffi.NULL: + return "" + return ffi.string(val) + + @_argspec(0, 1, 2) + def getstr(self, y, x, n=1023): + n = min(n, 1023) + buf = ffi.new("char[1024]") # /* This should be big enough.. I hope */ + + if y is None: + val = lib.wgetnstr(self._win, buf, n) + else: + val = lib.mvwgetnstr(self._win, y, x, buf, n) + + if val == lib.ERR: + return "" + return ffi.string(buf) + + @_argspec(2, 1, 2) + def hline(self, y, x, ch, n, attr=None): + ch = _chtype(ch) + if attr is None: + attr = lib.A_NORMAL + if y is not None: + _check_ERR(lib.wmove(self._win, y, x), "wmove") + return _check_ERR(lib.whline(self._win, ch | attr, n), "hline") + + @_argspec(1, 1, 2) + def insch(self, y, x, ch, attr=None): + ch = _chtype(ch) + if attr is None: + attr = lib.A_NORMAL + if y is not None: + code = lib.mvwinsch(self._win, y, x, ch | attr) + else: + code = lib.winsch(self._win, ch | attr) + return _check_ERR(code, "insch") + + def inch(self, *args): + if len(args) == 0: + return lib.winch(self._win) + elif len(args) == 2: + return lib.mvwinch(self._win, *args) + else: + raise error("inch requires 0 or 2 arguments") + + @_argspec(0, 1, 2) + def instr(self, y, x, n=1023): + n = min(n, 1023) + buf = ffi.new("char[1024]") # /* This should be big enough.. I hope */ + if y is None: + code = lib.winnstr(self._win, buf, n) + else: + code = lib.mvwinnstr(self._win, y, x, buf, n) + + if code == lib.ERR: + return "" + return ffi.string(buf) + + @_argspec(1, 1, 2) + def insstr(self, y, x, text, attr=None): + if attr is not None: + attr_old = lib.getattrs(self._win) + lib.wattrset(self._win, attr) + if y is not None: + code = lib.mvwinsstr(self._win, y, x, text) + else: + code = lib.winsstr(self._win, text) + if attr is not None: + lib.wattrset(self._win, attr_old) + return _check_ERR(code, "insstr") + + @_argspec(2, 1, 2) + def insnstr(self, y, x, text, n, attr=None): + if attr is not None: + attr_old = lib.getattrs(self._win) + lib.wattrset(self._win, attr) + if y is not None: + code = lib.mvwinsnstr(self._win, y, x, text, n) + else: + code = lib.winsnstr(self._win, text, n) + if attr is not None: + lib.wattrset(self._win, attr_old) + return _check_ERR(code, "insnstr") + + def is_linetouched(self, line): + code = lib.is_linetouched(self._win, line) + if code == lib.ERR: + raise error("is_linetouched: line number outside of boundaries") + if code == lib.FALSE: + return False + return True + + def noutrefresh(self, *args): + if lib._m_ispad(self._win): + if len(args) != 6: + raise error( + "noutrefresh() called for a pad requires 6 arguments") + return _check_ERR(lib.pnoutrefresh(self._win, *args), + "pnoutrefresh") + else: + # XXX: Better args check here? We need zero args. + return _check_ERR(lib.wnoutrefresh(self._win, *args), + "wnoutrefresh") + + nooutrefresh = noutrefresh # "to be removed in 2.3", but in 2.7, 3.x. + + def _copywin(self, dstwin, overlay, + sminr, sminc, dminr, dminc, dmaxr, dmaxc): + return _check_ERR(lib.copywin(self._win, dstwin._win, + sminr, sminc, dminr, dminc, dmaxr, dmaxc, + overlay), "copywin") + + def overlay(self, dstwin, *args): + if len(args) == 6: + return self._copywin(dstwin, True, *args) + elif len(args) == 0: + return _check_ERR(lib.overlay(self._win, dstwin._win), "overlay") + else: + raise error("overlay requires one or seven arguments") + + def overwrite(self, dstwin, *args): + if len(args) == 6: + return self._copywin(dstwin, False, *args) + elif len(args) == 0: + return _check_ERR(lib.overwrite(self._win, dstwin._win), + "overwrite") + else: + raise error("overwrite requires one or seven arguments") + + def putwin(self, filep): + # filestar = ffi.new("FILE *", filep) + return _check_ERR(lib.putwin(self._win, filep), "putwin") + + def redrawln(self, beg, num): + return _check_ERR(lib.wredrawln(self._win, beg, num), "redrawln") + + def refresh(self, *args): + if lib._m_ispad(self._win): + if len(args) != 6: + raise error( + "noutrefresh() called for a pad requires 6 arguments") + return _check_ERR(lib.prefresh(self._win, *args), "prefresh") + else: + # XXX: Better args check here? We need zero args. + return _check_ERR(lib.wrefresh(self._win, *args), "wrefresh") + + def setscrreg(self, y, x): + return _check_ERR(lib.wsetscrreg(self._win, y, x), "wsetscrreg") + + def subwin(self, *args): + nlines = 0 + ncols = 0 + if len(args) == 2: + begin_y, begin_x = args + elif len(args) == 4: + nlines, ncols, begin_y, begin_x = args + else: + raise error("subwin requires 2 or 4 arguments") + + if lib._m_ispad(self._win): + win = lib.subpad(self._win, nlines, ncols, begin_y, begin_x) + else: + win = lib.subwin(self._win, nlines, ncols, begin_y, begin_x) + return Window(_check_NULL(win)) + + def scroll(self, nlines=None): + if nlines is None: + return _check_ERR(lib.scroll(self._win), "scroll") + else: + return _check_ERR(lib.wscrl(self._win, nlines), "scroll") + + def touchline(self, st, cnt, val=None): + if val is None: + return _check_ERR(lib.touchline(self._win, st, cnt), "touchline") + else: + return _check_ERR(lib.wtouchln(self._win, st, cnt, val), + "touchline") + + @_argspec(2, 1, 2) + def vline(self, y, x, ch, n, attr=None): + ch = _chtype(ch) + if attr is None: + attr = lib.A_NORMAL + if y is not None: + _check_ERR(lib.wmove(self._win, y, x), "wmove") + return _check_ERR(lib.wvline(self._win, ch | attr, n), "vline") + + +beep = _mk_no_return("beep") +def_prog_mode = _mk_no_return("def_prog_mode") +def_shell_mode = _mk_no_return("def_shell_mode") +doupdate = _mk_no_return("doupdate") +endwin = _mk_no_return("endwin") +flash = _mk_no_return("flash") +nocbreak = _mk_no_return("nocbreak") +noecho = _mk_no_return("noecho") +nonl = _mk_no_return("nonl") +noraw = _mk_no_return("noraw") +reset_prog_mode = _mk_no_return("reset_prog_mode") +reset_shell_mode = _mk_no_return("reset_shell_mode") +resetty = _mk_no_return("resetty") +savetty = _mk_no_return("savetty") + +cbreak = _mk_flag_func("cbreak") +echo = _mk_flag_func("echo") +nl = _mk_flag_func("nl") +raw = _mk_flag_func("raw") + +baudrate = _mk_return_val("baudrate") +termattrs = _mk_return_val("termattrs") + +termname = _mk_return_val("termname") +longname = _mk_return_val("longname") + +can_change_color = _mk_return_val("can_change_color") +has_colors = _mk_return_val("has_colors") +has_ic = _mk_return_val("has_ic") +has_il = _mk_return_val("has_il") +isendwin = _mk_return_val("isendwin") +flushinp = _mk_return_val("flushinp") +noqiflush = _mk_return_val("noqiflush") + + +def filter(): + lib.filter() + return None + + +def color_content(color): + _ensure_initialised_color() + r, g, b = ffi.new("short *"), ffi.new("short *"), ffi.new("short *") + if lib.color_content(color, r, g, b) == lib.ERR: + raise error("Argument 1 was out of range. Check value of COLORS.") + return (r, g, b) + + +def color_pair(n): + _ensure_initialised_color() + return (n << 8) + + +def curs_set(vis): + _ensure_initialised() + val = lib.curs_set(vis) + _check_ERR(val, "curs_set") + return val + + +def delay_output(ms): + _ensure_initialised() + return _check_ERR(lib.delay_output(ms), "delay_output") + + +def erasechar(): + _ensure_initialised() + return lib.erasechar() + + +def getsyx(): + _ensure_initialised() + yx = ffi.new("int[2]") + lib.getsyx(yx[0], yx[1]) + return (yx[0], yx[1]) + + +if lib._m_NCURSES_MOUSE_VERSION: + + def getmouse(): + _ensure_initialised() + mevent = ffi.new("MEVENT *") + _check_ERR(lib.getmouse(mevent), "getmouse") + return (mevent.id, mevent.x, mevent.y, mevent.z, mevent.bstate) + + def ungetmouse(id, x, y, z, bstate): + _ensure_initialised() + mevent = ffi.new("MEVENT *") + mevent.id, mevent.x, mevent.y, mevent.z, mevent.bstate = ( + id, x, y, z, bstate) + return _check_ERR(lib.ungetmouse(mevent), "ungetmouse") + + +def getwin(filep): + return Window(_check_NULL(lib.getwin(filep))) + + +def halfdelay(tenths): + _ensure_initialised() + return _check_ERR(lib.halfdelay(tenths), "halfdelay") + + +if not lib._m_STRICT_SYSV_CURSES: + def has_key(ch): + _ensure_initialised() + return lib.has_key(ch) + + +def init_color(color, r, g, b): + _ensure_initialised_color() + return _check_ERR(lib.init_color(color, r, g, b), "init_color") + + +def init_pair(pair, f, b): + _ensure_initialised_color() + return _check_ERR(lib.init_pair(pair, f, b), "init_pair") + + +def _mk_acs(name, ichar): + if len(ichar) == 1: + globals()[name] = lib.acs_map[ord(ichar)] + else: + globals()[name] = globals()[ichar] + + +def _map_acs(): + _mk_acs("ACS_ULCORNER", 'l') + _mk_acs("ACS_LLCORNER", 'm') + _mk_acs("ACS_URCORNER", 'k') + _mk_acs("ACS_LRCORNER", 'j') + _mk_acs("ACS_LTEE", 't') + _mk_acs("ACS_RTEE", 'u') + _mk_acs("ACS_BTEE", 'v') + _mk_acs("ACS_TTEE", 'w') + _mk_acs("ACS_HLINE", 'q') + _mk_acs("ACS_VLINE", 'x') + _mk_acs("ACS_PLUS", 'n') + _mk_acs("ACS_S1", 'o') + _mk_acs("ACS_S9", 's') + _mk_acs("ACS_DIAMOND", '`') + _mk_acs("ACS_CKBOARD", 'a') + _mk_acs("ACS_DEGREE", 'f') + _mk_acs("ACS_PLMINUS", 'g') + _mk_acs("ACS_BULLET", '~') + _mk_acs("ACS_LARROW", ',') + _mk_acs("ACS_RARROW", '+') + _mk_acs("ACS_DARROW", '.') + _mk_acs("ACS_UARROW", '-') + _mk_acs("ACS_BOARD", 'h') + _mk_acs("ACS_LANTERN", 'i') + _mk_acs("ACS_BLOCK", '0') + _mk_acs("ACS_S3", 'p') + _mk_acs("ACS_S7", 'r') + _mk_acs("ACS_LEQUAL", 'y') + _mk_acs("ACS_GEQUAL", 'z') + _mk_acs("ACS_PI", '{') + _mk_acs("ACS_NEQUAL", '|') + _mk_acs("ACS_STERLING", '}') + _mk_acs("ACS_BSSB", "ACS_ULCORNER") + _mk_acs("ACS_SSBB", "ACS_LLCORNER") + _mk_acs("ACS_BBSS", "ACS_URCORNER") + _mk_acs("ACS_SBBS", "ACS_LRCORNER") + _mk_acs("ACS_SBSS", "ACS_RTEE") + _mk_acs("ACS_SSSB", "ACS_LTEE") + _mk_acs("ACS_SSBS", "ACS_BTEE") + _mk_acs("ACS_BSSS", "ACS_TTEE") + _mk_acs("ACS_BSBS", "ACS_HLINE") + _mk_acs("ACS_SBSB", "ACS_VLINE") + _mk_acs("ACS_SSSS", "ACS_PLUS") + + +def initscr(): + if _initialised: + lib.wrefresh(lib.stdscr) + return Window(lib.stdscr) + + win = _check_NULL(lib.initscr()) + globals()['_initialised_setupterm'] = True + globals()['_initialised'] = True + + _map_acs() + + globals()["LINES"] = lib.LINES + globals()["COLS"] = lib.COLS + + return Window(win) + + +def setupterm(term=None, fd=-1): + if fd == -1: + # XXX: Check for missing stdout here? + fd = sys.stdout.fileno() + + if _initialised_setupterm: + return None + + err = ffi.new("int *") + if lib.setupterm(term, fd, err) == lib.ERR: + if err == 0: + raise error("setupterm: could not find terminal") + elif err == -1: + raise error("setupterm: could not find terminfo database") + else: + raise error("setupterm: unknown error") + + globals()["_initialised_setupterm"] = True + return None + + +def intrflush(ch): + _ensure_initialised() + return _check_ERR(lib.intrflush(ffi.NULL, ch), "intrflush") + + +# XXX: #ifdef HAVE_CURSES_IS_TERM_RESIZED +def is_term_resized(lines, columns): + _ensure_initialised() + return lib.is_term_resized(lines, columns) + + +if not lib._m_NetBSD: + def keyname(ch): + _ensure_initialised() + if ch < 0: + raise error("invalid key number") + knp = lib.keyname(ch) + if knp == ffi.NULL: + return "" + return ffi.string(knp) + + +def killchar(): + return lib.killchar() + + +def meta(ch): + return _check_ERR(lib.meta(lib.stdscr, ch), "meta") + + +if lib._m_NCURSES_MOUSE_VERSION: + + def mouseinterval(interval): + _ensure_initialised() + return _check_ERR(lib.mouseinterval(interval), "mouseinterval") + + def mousemask(newmask): + _ensure_initialised() + oldmask = ffi.new("mmask_t *") + availmask = lib.mousemask(newmask, oldmask) + return (availmask, oldmask) + + +def napms(ms): + _ensure_initialised() + return lib.napms(ms) + + +def newpad(nlines, ncols): + _ensure_initialised() + return Window(_check_NULL(lib.newpad(nlines, ncols))) + + +def newwin(nlines, ncols, begin_y=None, begin_x=None): + _ensure_initialised() + if begin_x is None: + if begin_y is not None: + raise error("newwin requires 2 or 4 arguments") + begin_y = begin_x = 0 + + return Window(_check_NULL(lib.newwin(nlines, ncols, begin_y, begin_x))) + + +def pair_content(pair): + _ensure_initialised_color() + f = ffi.new("short *") + b = ffi.new("short *") + if lib.pair_content(pair, f, b) == lib.ERR: + raise error("Argument 1 was out of range. (1..COLOR_PAIRS-1)") + return (f, b) + + +def pair_number(pairvalue): + _ensure_initialised_color() + return (pairvalue & lib.A_COLOR) >> 8 + + +def putp(text): + return _check_ERR(lib.putp(text), "putp") + + +def qiflush(flag=True): + _ensure_initialised() + if flag: + lib.qiflush() + else: + lib.noqiflush() + return None + + +# XXX: Do something about the following? +# /* Internal helper used for updating curses.LINES, curses.COLS, _curses.LINES +# * and _curses.COLS */ +# #if defined(HAVE_CURSES_RESIZETERM) || defined(HAVE_CURSES_RESIZE_TERM) +# static int +# update_lines_cols(void) +# { +# PyObject *o; +# PyObject *m = PyImport_ImportModuleNoBlock("curses"); + +# if (!m) +# return 0; + +# o = PyInt_FromLong(LINES); +# if (!o) { +# Py_DECREF(m); +# return 0; +# } +# if (PyObject_SetAttrString(m, "LINES", o)) { +# Py_DECREF(m); +# Py_DECREF(o); +# return 0; +# } +# if (PyDict_SetItemString(ModDict, "LINES", o)) { +# Py_DECREF(m); +# Py_DECREF(o); +# return 0; +# } +# Py_DECREF(o); +# o = PyInt_FromLong(COLS); +# if (!o) { +# Py_DECREF(m); +# return 0; +# } +# if (PyObject_SetAttrString(m, "COLS", o)) { +# Py_DECREF(m); +# Py_DECREF(o); +# return 0; +# } +# if (PyDict_SetItemString(ModDict, "COLS", o)) { +# Py_DECREF(m); +# Py_DECREF(o); +# return 0; +# } +# Py_DECREF(o); +# Py_DECREF(m); +# return 1; +# } +# #endif + +# #ifdef HAVE_CURSES_RESIZETERM +# static PyObject * +# PyCurses_ResizeTerm(PyObject *self, PyObject *args) +# { +# int lines; +# int columns; +# PyObject *result; + +# PyCursesInitialised; + +# if (!PyArg_ParseTuple(args,"ii:resizeterm", &lines, &columns)) +# return NULL; + +# result = PyCursesCheckERR(resizeterm(lines, columns), "resizeterm"); +# if (!result) +# return NULL; +# if (!update_lines_cols()) +# return NULL; +# return result; +# } + +# #endif + +# #ifdef HAVE_CURSES_RESIZE_TERM +# static PyObject * +# PyCurses_Resize_Term(PyObject *self, PyObject *args) +# { +# int lines; +# int columns; + +# PyObject *result; + +# PyCursesInitialised; + +# if (!PyArg_ParseTuple(args,"ii:resize_term", &lines, &columns)) +# return NULL; + +# result = PyCursesCheckERR(resize_term(lines, columns), "resize_term"); +# if (!result) +# return NULL; +# if (!update_lines_cols()) +# return NULL; +# return result; +# } +# #endif /* HAVE_CURSES_RESIZE_TERM */ + + +def setsyx(y, x): + _ensure_initialised() + lib.setsyx(y, x) + return None + + +def start_color(): + _check_ERR(lib.start_color(), "start_color") + globals()["COLORS"] = lib.COLORS + globals()["COLOR_PAIRS"] = lib.COLOR_PAIRS + globals()["_initialised_color"] = True + return None + + +def tigetflag(capname): + _ensure_initialised_setupterm() + return lib.tigetflag(capname) + + +def tigetnum(capname): + _ensure_initialised_setupterm() + return lib.tigetnum(capname) + + +def tigetstr(capname): + _ensure_initialised_setupterm() + val = lib.tigetstr(capname) + if val == 0 or val == -1: + return None + return ffi.string(val) + + +def tparm(fmt, i1=0, i2=0, i3=0, i4=0, i5=0, i6=0, i7=0, i8=0, i9=0): + args = [ffi.cast("int", i) for i in (i1, i2, i3, i4, i5, i6, i7, i8, i9)] + result = lib.tparm(fmt, *args) + if result == ffi.NULL: + raise error("tparm() returned NULL") + return ffi.string(result) + + +def typeahead(fd): + _ensure_initialised() + return _check_ERR(lib.typeahead(fd), "typeahead") + + +def unctrl(ch): + _ensure_initialised() + return lib.unctrl(_chtype(ch)) + + +def ungetch(ch): + _ensure_initialised() + return _check_ERR(lib.ungetch(_chtype(ch)), "ungetch") + + +def use_env(flag): + lib.use_env(flag) + return None + + +if not lib._m_STRICT_SYSV_CURSES: + + def use_default_colors(): + _ensure_initialised_color() + return _check_ERR(lib.use_default_colors(), "use_default_colors") diff --git a/lib_pypy/_curses_panel.py b/lib_pypy/_curses_panel.py new file mode 100644 --- /dev/null +++ b/lib_pypy/_curses_panel.py @@ -0,0 +1,132 @@ +"Reimplementation of the standard extension module '_curses_panel' using cffi." + +from _curses import _ensure_initialised, _check_ERR, error, ffi, lib + + +def _call_lib(method_name, *args): + return getattr(lib, method_name)(*args) + + +def _call_lib_check_ERR(method_name, *args): + return _check_ERR(_call_lib(method_name, *args), method_name) + + +def _mk_no_arg_no_return(method_name): + def _execute(): + _ensure_initialised() + return _call_lib_check_ERR(method_name) + _execute.__name__ = method_name + return _execute + + +def _mk_no_arg_return_val(method_name): + def _execute(): + return _call_lib(method_name) + _execute.__name__ = method_name + return _execute + + +def _mk_args_no_return(method_name): + def _execute(*args): + return _call_lib_check_ERR(method_name, *args) + _execute.__name__ = method_name + return _execute + + +# ____________________________________________________________ + + +bottom_panel = _mk_no_arg_no_return("bottom_panel") +hide_panel = _mk_no_arg_no_return("hide_panel") +show_panel = _mk_no_arg_no_return("show_panel") +top_panel = _mk_no_arg_no_return("top_panel") +panel_hidden = _mk_no_arg_return_val("panel_hidden") +move_panel = _mk_args_no_return("move_panel") + + +_panels = [] + + +def _add_panel(panel): + _panels.insert(0, panel) + + +def _remove_panel(panel): + _panels.remove(panel) + + +def _find_panel(pan): + for panel in _panels: + if panel._pan == pan: + return panel + return None + + +class Panel(object): + def __init__(self, pan, window): + self._pan = pan + self._window = window + _add_panel(self) + + def __del__(self): + _remove_panel(self) + lib.del_panel(self._pan) + + def above(self): + pan = lib.panel_above(self._pan) + if pan == ffi.NULL: + return None + return _find_panel(pan) + + def below(self): + pan = lib.panel_below(self._pan) + if pan == ffi.NULL: + return None + return _find_panel(pan) + + def window(self): + return self._window + + def replace_panel(self, window): + panel = _find_panel(self._pan) + _check_ERR(lib.replace_panel(self._pan, window._win), "replace_panel") + panel._window = window + return None + + def set_panel_userptr(self, obj): + code = lib.set_panel_userptr(self._pan, ffi.cast("void *", obj)) + return _check_ERR(code, "set_panel_userptr") + + def userptr(self): + # XXX: This is probably wrong. + obj = lib.panel_userptr(self._pan) + if obj == ffi.NULL: + raise error("no userptr set") + return obj + + +def bottom_panel(): + _ensure_initialised() + pan = lib.panel_above(ffi.NULL) + if pan == ffi.NULL: + return None + return _find_panel(pan) + + +def new_panel(window): + pan = lib.new_panel(window._win) + return Panel(pan, window) + + +def panel_below(): + _ensure_initialised() + pan = lib.panel_below(ffi.NULL) + if pan == ffi.NULL: + return None + return _find_panel(pan) + + +def update_panels(): + _ensure_initialised() + lib.update_panels() + return None From noreply at buildbot.pypy.org Thu Feb 7 16:29:38 2013 From: noreply at buildbot.pypy.org (jerith) Date: Thu, 7 Feb 2013 16:29:38 +0100 (CET) Subject: [pypy-commit] pypy curses_cffi: Merge default branch. Message-ID: <20130207152938.4AEE61C02D9@cobra.cs.uni-duesseldorf.de> Author: Jeremy Thurgood Branch: curses_cffi Changeset: r60936:3898bda6607a Date: 2013-02-07 13:06 +0200 http://bitbucket.org/pypy/pypy/changeset/3898bda6607a/ Log: Merge default branch. diff too long, truncating to 2000 out of 895696 lines diff --git a/.hgignore b/.hgignore --- a/.hgignore +++ b/.hgignore @@ -85,3 +85,4 @@ ^compiled ^.git/ ^release/ +^rpython/_cache$ diff --git a/.hgtags b/.hgtags --- a/.hgtags +++ b/.hgtags @@ -2,3 +2,4 @@ b48df0bf4e75b81d98f19ce89d4a7dc3e1dab5e5 benchmarked d8ac7d23d3ec5f9a0fa1264972f74a010dbfd07f release-1.6 ff4af8f318821f7f5ca998613a60fca09aa137da release-1.7 +07e08e9c885ca67d89bcc304e45a32346daea2fa release-2.0-beta-1 diff --git a/LICENSE b/LICENSE --- a/LICENSE +++ b/LICENSE @@ -1,9 +1,10 @@ -License for files in the pypy/ directory -================================================== +License +======= Except when otherwise stated (look for LICENSE files in directories or information at the beginning of each file) all software and -documentation in the 'pypy' directories is licensed as follows: +documentation in the 'pypy', 'ctype_configure', 'dotviewer', 'demo', +and 'lib_pypy' directories is licensed as follows: The MIT License @@ -27,7 +28,7 @@ DEALINGS IN THE SOFTWARE. -PyPy Copyright holders 2003-2012 +PyPy Copyright holders 2003-2013 ----------------------------------- Except when otherwise stated (look for LICENSE files or information at diff --git a/README b/README deleted file mode 100644 --- a/README +++ /dev/null @@ -1,24 +0,0 @@ -===================================== -PyPy: Python in Python Implementation -===================================== - -Welcome to PyPy! - -PyPy is both an implementation of the Python programming language, and -an extensive compiler framework for dynamic language implementations. -You can build self-contained Python implementations which execute -independently from CPython. - -The home page is: - - http://pypy.org/ - -The getting-started document will help guide you: - - http://doc.pypy.org/en/latest/getting-started.html - -It will also point you to the rest of the documentation which is generated -from files in the pypy/doc directory within the source repositories. Enjoy -and send us feedback! - - the pypy-dev team diff --git a/README.rst b/README.rst new file mode 100644 --- /dev/null +++ b/README.rst @@ -0,0 +1,24 @@ +===================================== +PyPy: Python in Python Implementation +===================================== + +Welcome to PyPy! + +PyPy is both an implementation of the Python programming language, and +an extensive compiler framework for dynamic language implementations. +You can build self-contained Python implementations which execute +independently from CPython. + +The home page is: + + http://pypy.org/ + +The getting-started document will help guide you: + + http://doc.pypy.org/en/latest/getting-started.html + +It will also point you to the rest of the documentation which is generated +from files in the pypy/doc directory within the source repositories. Enjoy +and send us feedback! + + the pypy-dev team diff --git a/demo/autopath.py b/demo/autopath.py deleted file mode 100644 --- a/demo/autopath.py +++ /dev/null @@ -1,2 +0,0 @@ -import sys, os -sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) diff --git a/demo/bpnn.py b/demo/bpnn.py deleted file mode 100755 --- a/demo/bpnn.py +++ /dev/null @@ -1,214 +0,0 @@ -#!/usr/bin/env python -""" - Translator Demo - - To analyse and type-annotate the functions and class defined in - this module, starting from the entry point function demo(), - use the following command line: - - ../pypy/translator/goal/translate.py bpnn.py - - Insert '--help' before 'bpnn.py' for a list of translation options, - or see the Overview of Command Line Options for translation at - http://codespeak.net/pypy/dist/pypy/doc/config/commandline.html -""" -# Back-Propagation Neural Networks -# -# Written in Python. See http://www.python.org/ -# -# Neil Schemenauer -# -# Modifications to the original (Armin Rigo): -# * import random from PyPy's lib, which is Python 2.2's plain -# Python implementation -# * print a doc about how to start the Translator - -import sys -import math -import time - -import autopath -from pypy.rlib import rrandom - -PRINT_IT = True - -random = rrandom.Random(1) - -# calculate a random number where: a <= rand < b -def rand(a, b): - return (b-a)*random.random() + a - -# Make a matrix (we could use NumPy to speed this up) -def makeMatrix(I, J, fill=0.0): - m = [] - for i in range(I): - m.append([fill]*J) - return m - -class NN: - - def __init__(self, ni, nh, no): - # number of input, hidden, and output nodes - self.ni = ni + 1 # +1 for bias node - self.nh = nh - self.no = no - - # activations for nodes - self.ai = [1.0]*self.ni - self.ah = [1.0]*self.nh - self.ao = [1.0]*self.no - - # create weights - self.wi = makeMatrix(self.ni, self.nh) - self.wo = makeMatrix(self.nh, self.no) - # set them to random vaules - for i in range(self.ni): - for j in range(self.nh): - self.wi[i][j] = rand(-2.0, 2.0) - for j in range(self.nh): - for k in range(self.no): - self.wo[j][k] = rand(-2.0, 2.0) - - # last change in weights for momentum - self.ci = makeMatrix(self.ni, self.nh) - self.co = makeMatrix(self.nh, self.no) - - def update(self, inputs): - if len(inputs) != self.ni-1: - raise ValueError, 'wrong number of inputs' - - # input activations - for i in range(self.ni-1): - #self.ai[i] = 1.0/(1.0+math.exp(-inputs[i])) - self.ai[i] = inputs[i] - - # hidden activations - for j in range(self.nh): - sum = 0.0 - for i in range(self.ni): - sum = sum + self.ai[i] * self.wi[i][j] - self.ah[j] = 1.0/(1.0+math.exp(-sum)) - - # output activations - for k in range(self.no): - sum = 0.0 - for j in range(self.nh): - sum = sum + self.ah[j] * self.wo[j][k] - self.ao[k] = 1.0/(1.0+math.exp(-sum)) - - return self.ao[:] - - - def backPropagate(self, targets, N, M): - if len(targets) != self.no: - raise ValueError, 'wrong number of target values' - - # calculate error terms for output - output_deltas = [0.0] * self.no - for k in range(self.no): - ao = self.ao[k] - output_deltas[k] = ao*(1-ao)*(targets[k]-ao) - - # calculate error terms for hidden - hidden_deltas = [0.0] * self.nh - for j in range(self.nh): - sum = 0.0 - for k in range(self.no): - sum = sum + output_deltas[k]*self.wo[j][k] - hidden_deltas[j] = self.ah[j]*(1-self.ah[j])*sum - - # update output weights - for j in range(self.nh): - for k in range(self.no): - change = output_deltas[k]*self.ah[j] - self.wo[j][k] = self.wo[j][k] + N*change + M*self.co[j][k] - self.co[j][k] = change - #print N*change, M*self.co[j][k] - - # update input weights - for i in range(self.ni): - for j in range(self.nh): - change = hidden_deltas[j]*self.ai[i] - self.wi[i][j] = self.wi[i][j] + N*change + M*self.ci[i][j] - self.ci[i][j] = change - - # calculate error - error = 0.0 - for k in range(len(targets)): - delta = targets[k]-self.ao[k] - error = error + 0.5*delta*delta - return error - - - def test(self, patterns): - for p in patterns: - if PRINT_IT: - print p[0], '->', self.update(p[0]) - - def weights(self): - if PRINT_IT: - print 'Input weights:' - for i in range(self.ni): - print self.wi[i] - print - print 'Output weights:' - for j in range(self.nh): - print self.wo[j] - - def train(self, patterns, iterations=2000, N=0.5, M=0.1): - # N: learning rate - # M: momentum factor - for i in xrange(iterations): - error = 0.0 - for p in patterns: - inputs = p[0] - targets = p[1] - self.update(inputs) - error = error + self.backPropagate(targets, N, M) - if PRINT_IT and i % 100 == 0: - print 'error', error - - -def demo(): - # Teach network XOR function - pat = [ - [[0,0], [0]], - [[0,1], [1]], - [[1,0], [1]], - [[1,1], [0]] - ] - - # create a network with two input, two hidden, and two output nodes - n = NN(2, 3, 1) - # train it with some patterns - n.train(pat, 2000) - # test it - n.test(pat) - - -# __________ Entry point for stand-alone builds __________ - -import time - -def entry_point(argv): - if len(argv) > 1: - N = int(argv[1]) - else: - N = 200 - T = time.time() - for i in range(N): - demo() - t1 = time.time() - T - print "%d iterations, %s milliseconds per iteration" % (N, 1000.0*t1/N) - return 0 - -# _____ Define and setup target ___ - -def target(*args): - return entry_point, None - -if __name__ == '__main__': - if len(sys.argv) == 1: - sys.argv.append('1') - entry_point(sys.argv) - print __doc__ diff --git a/demo/dis-goal.py b/demo/dis-goal.py deleted file mode 100644 --- a/demo/dis-goal.py +++ /dev/null @@ -1,7 +0,0 @@ -""" -An old-time classical example, and one of our first goals. -To run on top of PyPy. -""" - -import dis -dis.dis(dis.dis) diff --git a/demo/distribution/client.py b/demo/distribution/client.py deleted file mode 100644 --- a/demo/distribution/client.py +++ /dev/null @@ -1,35 +0,0 @@ -""" This a sample client, suitable for use with server.py from this -directory - -run by: -pypy-c client.py -""" - -HOST = '127.0.0.1' -PORT = 12222 - -from distributed.socklayer import connect -remote_handle = connect((HOST, PORT)) - -import code -code.interact(local=locals()) - -""" Things that can be done: 1. remote object access - -x = remote_handle.x -assert type(x) is remote_handle.X # typecheck -x.meth(lambda x: x + 10, 6) # remote call, with callback localy -x.meth(remote_handle.f, 3) # remote call, remote callback -remote_handle.sys._getframe(2).f_locals['x'] # remote frame access -# XXX should be 'is x' and shouldn't need (2) argument - -# XXX next one does not work, while it should. Too much mangling with remote -# traceback frames probably -try: - x.meth(1, 2) # non-callable argument, AssertionError -except: - import sys - e, c, tb = sys.exc_info() - import pdb - pdb.post_mortem(tb) -""" diff --git a/demo/distribution/fileclient.py b/demo/distribution/fileclient.py deleted file mode 100644 --- a/demo/distribution/fileclient.py +++ /dev/null @@ -1,25 +0,0 @@ - -""" This is sample client for a server based in fileserver.py, not counting -initialization, code.interact and __doc__ has just 2 lines! Usage: - -pypy-c fileclient.py - -The file_opener is a proxy for remote file object. Which means you can -perform same operations as locally, like file_opener('/etc/passwd').read() -or file_opener('/tmp/x', 'w').write('x') - -pypy-c needs to be compiled with --allworkingmodules in order to have socket -working. -""" - -HOST = '127.0.0.1' -PORT = 12221 - -from distributed.socklayer import connect -file_opener = connect((HOST, PORT)).open - -import code -code.interact(local=locals()) -# The file_opener is a proxy for remote file object. Which means you can -# perform same operations as locally, like file_opener('/etc/passwd').read() -# or file_opener('/tmp/x', 'w').write('x') diff --git a/demo/distribution/fileserver.py b/demo/distribution/fileserver.py deleted file mode 100644 --- a/demo/distribution/fileserver.py +++ /dev/null @@ -1,19 +0,0 @@ -""" This is a sample demo showcasing file server, done by the pypy -distribution library. - -Not counting __doc__ and initialization this is 2 line, -fully operational file server, -sample client which is in fileclient.py is included as well. - -run by: -pypy-c fileserver.py - -pypy-c needs to be compiled with --allworkingmodules in order to have socket -working. -""" - -HOST = '127.0.0.1' # defaults to localhost, not to export your files -PORT = 12221 - -from distributed.socklayer import socket_loop -socket_loop((HOST, PORT), {'open':open}) diff --git a/demo/distribution/server.py b/demo/distribution/server.py deleted file mode 100644 --- a/demo/distribution/server.py +++ /dev/null @@ -1,38 +0,0 @@ -""" This is a demo exposing all globals from the current process over -socket, to be accessible remotely. - -run by: -pypy-c server.py - -pypy-c needs to be compiled with --allworkingmodules in order to have socket -working. -""" - -# things to export -# function -def f(x): - return x + 3 - -# class -class X: - def __init__(self): - self.slot = 3 - - def meth(self, f, arg): - """ Method eating callable and calling it with an argument - """ - assert callable(f) - return f(arg) - -# object -x = X() - -# module -import sys - -# constants -HOST = '127.0.0.1' -PORT = 12222 - -from distributed.socklayer import socket_loop -socket_loop((HOST, PORT), globals()) diff --git a/demo/fibonacci.py b/demo/fibonacci.py deleted file mode 100644 --- a/demo/fibonacci.py +++ /dev/null @@ -1,43 +0,0 @@ -""" -Thunk (a.k.a. lazy objects) in PyPy. -To run on top of the thunk object space with the following command-line: - - py.py -o thunk fibonacci.py - -This is a typical Functional Programming Languages demo, computing the -Fibonacci sequence by using an infinite lazy linked list. -""" - -try: - from __pypy__ import thunk # only available in 'py.py -o thunk' -except ImportError: - print __doc__ - raise SystemExit(2) - -# ____________________________________________________________ - - -class ListNode: - def __init__(self, head, tail): - self.head = head # the first element of the list - self.tail = tail # the sublist of all remaining elements - - -def add_lists(list1, list2): - """Compute the linked-list equivalent of the Python expression - [a+b for (a,b) in zip(list1,list2)] - """ - return ListNode(list1.head + list2.head, - thunk(add_lists, list1.tail, list2.tail)) - - -# 1, 1, 2, 3, 5, 8, 13, 21, 34, ... -Fibonacci = ListNode(1, ListNode(1, None)) -Fibonacci.tail.tail = thunk(add_lists, Fibonacci, Fibonacci.tail) - - -if __name__ == '__main__': - node = Fibonacci - while True: - print node.head - node = node.tail diff --git a/demo/fibonacci2.py b/demo/fibonacci2.py deleted file mode 100644 --- a/demo/fibonacci2.py +++ /dev/null @@ -1,27 +0,0 @@ -""" -Lazy functions in PyPy. -To run on top of the thunk object space with the following command-line: - - py.py -o thunk fibonacci2.py - -This is a typical Functional Programming Languages demo, computing the -Fibonacci sequence as nested 2-tuples. -""" - -import pprint - -try: - from __pypy__ import lazy -except ImportError: - print __doc__ - raise SystemExit(2) - - - at lazy -def fibo(a, b): - return (a, fibo(b, a + b)) - - -fibonacci = fibo(1, 1) - -pprint.pprint(fibonacci, depth=10) diff --git a/demo/foodbill.py b/demo/foodbill.py deleted file mode 100644 --- a/demo/foodbill.py +++ /dev/null @@ -1,59 +0,0 @@ -""" -Of historical interest: we computed the food bill of our first Gothenburg -sprint with PyPy :-) -""" - -slips=[(1, 'Kals MatMarkn', 6150, 'Chutney for Curry', 'dinner Saturday'), - (2, 'Kals MatMarkn', 32000, 'Spaghetti, Beer', 'dinner Monday'), - (2, 'Kals MatMarkn', -810, 'Deposit on Beer Bottles', 'various'), - (3, 'Fram', 7700, 'Rice and Curry Spice', 'dinner Saturday'), - (4, 'Kals MatMarkn', 25000, 'Alcohol-Free Beer, sundries', 'various'), - (4, 'Kals MatMarkn', -1570, "Michael's toothpaste", 'none'), - (4, 'Kals MatMarkn', -1690, "Laura's toothpaste", 'none'), - (4, 'Kals MatMarkn', -720, 'Deposit on Beer Bottles', 'various'), - (4, 'Kals MatMarkn', -60, 'Deposit on another Beer Bottle', 'various'), - (5, 'Kals MatMarkn', 26750, 'lunch bread meat cheese', 'lunch Monday'), - (6, 'Kals MatMarkn', 15950, 'various', 'dinner Tuesday and Thursday'), - (7, 'Kals MatMarkn', 3650, 'Drottningsylt, etc.', 'dinner Thursday'), - (8, 'Kals MatMarkn', 26150, 'Chicken and Mushroom Sauce', 'dinner Wed'), - (8, 'Kals MatMarkn', -2490, 'Jacob and Laura -- juice', 'dinner Wed'), - (8, 'Kals MatMarkn', -2990, "Chicken we didn't cook", 'dinner Wednesday'), - (9, 'Kals MatMarkn', 1380, 'fruit for Curry', 'dinner Saturday'), - (9, 'Kals MatMarkn', 1380, 'fruit for Curry', 'dinner Saturday'), - (10, 'Kals MatMarkn', 26900, 'Jansons Frestelse', 'dinner Sunday'), - (10, 'Kals MatMarkn', -540, 'Deposit on Beer Bottles', 'dinner Sunday'), - (11, 'Kals MatMarkn', 22650, 'lunch bread meat cheese', 'lunch Thursday'), - (11, 'Kals MatMarkn', -2190, 'Jacob and Laura -- juice', 'lunch Thursday'), - (11, 'Kals MatMarkn', -2790, 'Jacob and Laura -- cereal', 'lunch Thurs'), - (11, 'Kals MatMarkn', -760, 'Jacob and Laura -- milk', 'lunch Thursday'), - (12, 'Kals MatMarkn', 18850, 'lunch bread meat cheese', 'lunch Friday'), - (13, 'Kals MatMarkn', 18850, 'lunch bread meat cheese', 'guestimate Sun'), - (14, 'Kals MatMarkn', 18850, 'lunch bread meat cheese', 'guestimate Tues'), - (15, 'Kals MatMarkn', 20000, 'lunch bread meat cheese', 'guestimate Wed'), - (16, 'Kals MatMarkn', 42050, 'grillfest', 'dinner Friday'), - (16, 'Kals MatMarkn', -1350, 'Deposit on Beer Bottles', 'dinner Friday'), - (17, 'System Bolaget', 15500, 'Cederlunds Caloric', 'dinner Thursday'), - (17, 'System Bolaget', 22400, '4 x Farnese Sangiovese 56SEK', 'various'), - (17, 'System Bolaget', 22400, '4 x Farnese Sangiovese 56SEK', 'various'), - (17, 'System Bolaget', 13800, '2 x Jacobs Creek 69SEK', 'various'), - (18, 'J and Ls winecabinet', 10800, '2 x Parrotes 54SEK', 'various'), - (18, 'J and Ls winecabinet', 14700, '3 x Saint Paulin 49SEK', 'various'), - (18, 'J and Ls winecabinet', 10400, '2 x Farnese Sangioves 52SEK', - 'cheaper when we bought it'), - (18, 'J and Ls winecabinet', 17800, '2 x Le Poiane 89SEK', 'various'), - (18, 'J and Ls winecabinet', 9800, '2 x Something Else 49SEK', 'various'), - (19, 'Konsum', 26000, 'Saturday Bread and Fruit', 'Slip MISSING'), - (20, 'Konsum', 15245, 'Mooseburgers', 'found slip'), - (21, 'Kals MatMarkn', 20650, 'Grilling', 'Friday dinner'), - (22, 'J and Ls freezer', 21000, 'Meat for Curry, grilling', ''), - (22, 'J and Ls cupboard', 3000, 'Rice', ''), - (22, 'J and Ls cupboard', 4000, 'Charcoal', ''), - (23, 'Fram', 2975, 'Potatoes', '3.5 kg @ 8.50SEK'), - (23, 'Fram', 1421, 'Peas', 'Thursday dinner'), - (24, 'Kals MatMarkn', 20650, 'Grilling', 'Friday dinner'), - (24, 'Kals MatMarkn', -2990, 'TP', 'None'), - (24, 'Kals MatMarkn', -2320, 'T-Gul', 'None') - ] - -print [t[2] for t in slips] -print (reduce(lambda x, y: x+y, [t[2] for t in slips], 0))/900 diff --git a/demo/pickle_coroutine.py b/demo/pickle_coroutine.py deleted file mode 100644 --- a/demo/pickle_coroutine.py +++ /dev/null @@ -1,86 +0,0 @@ -""" -Stackless demo. - -This example only works on top of a pypy-c compiled with stackless features -and the signal module: - - translate.py --stackless targetpypystandalone --withmod-signal - -Usage: - - pypy-c pickle_coroutine.py --start demo.pickle - - Start the computation. You can interrupt it at any time by - pressing Ctrl-C; at this point, the state of the computing - coroutine is saved in demo.pickle. - - pypy-c pickle_coroutine.py --resume demo.pickle - - Reload the coroutine from demo.pickle and continue running it. - (It can be interrupted again with Ctrl-C.) - -This demo is documented in detail in pypy/doc/stackless.txt. -""" - -try: - import sys, pickle, signal - from stackless import coroutine -except ImportError: - print __doc__ - sys.exit(2) - - -def ackermann(x, y): - check() - if x == 0: - return y + 1 - if y == 0: - return ackermann(x - 1, 1) - return ackermann(x - 1, ackermann(x, y - 1)) - -# ____________________________________________________________ - -main = coroutine.getcurrent() -sys.setrecursionlimit(100000) - -interrupt_flag = False - -def interrupt_handler(*args): - global interrupt_flag - interrupt_flag = True - -def check(): - if interrupt_flag: - main.switch() - - -def execute(coro): - signal.signal(signal.SIGINT, interrupt_handler) - res = coro.switch() - if res is None and coro.is_alive: # interrupted! - print "interrupted! writing %s..." % (filename,) - f = open(filename, 'w') - pickle.dump(coro, f) - f.close() - print "done" - else: - print "result:", res - -try: - operation, filename = sys.argv[1:] -except ValueError: - print __doc__ - sys.exit(2) - -if operation == '--start': - coro = coroutine() - coro.bind(ackermann, 3, 7) - print "running from the start..." - execute(coro) -elif operation == '--resume': - print "reloading %s..." % (filename,) - f = open(filename) - coro = pickle.load(f) - f.close() - print "done, running now..." - execute(coro) diff --git a/demo/sharedref.py b/demo/sharedref.py deleted file mode 100644 --- a/demo/sharedref.py +++ /dev/null @@ -1,184 +0,0 @@ -""" - This is an example usage of the 'thunk' object space of PyPy. - It implements transparent distributed object manipulation. - - Start a server on a local port, say port 8888, with: - - $ py.py -o thunk sharedref.py 8888 - Waiting for connection on port 8888 - - Then start and connect a client from the same or another machine: - - $ py.py -o thunk sharedref.py ip_or_name:8888 - Connecting to ('...', 8888) - Ok - >>> l = [1,2,3] - >>> chan.send(l) # send the list to the server over the connexion - - On the server-side: - - Connected from ('...', 1046) - >>> l = chan.recv() # receive the list sent above - >>> l - [1, 2, 3] - >>> l.append(4) - - Back on the client-side: - - >>> l - [1, 2, 3, 4] - - The list behaves like a single distributed object, which both sides can - modify and access without needing further explicit synchronization. - There is no difference between who was the original sender or receiver of - the object, nor between which side was originally 'server' or 'client'. -""" - -import sys, marshal -from __pypy__ import thunk, become -from socket import * -from select import select - - -class Channel: - - def __init__(self, s, serverside): - # invariants: a shared object 'obj' is - # - either remote, and a thunk, and not a value in self.cache - # - or local (or at least on "our" side of this Channel), and - # then it has a corresponding key in self.cache - self.s = s - self.cache = {} - self.inputfifo = [] - self.count = int(not serverside) - -## def _check(self, obj): -## print '%s: cache=%r' % (self, self.cache.keys()), -## if is_thunk(obj): -## print 'THUNK' -## else: -## print obj - - def sendraw(self, obj): - data = marshal.dumps(obj) - hdr = str(len(data)) - hdr = '0'*(10-len(hdr)) + hdr - self.s.sendall(hdr + data) - - def _readbytes(self, count): - data = '' - while len(data) < count: - t = self.s.recv(count - len(data)) - if not t: - raise EOFError - data += t - return data - - def recvraw(self): - datasize = int(self._readbytes(10)) - data = self._readbytes(datasize) - return marshal.loads(data) - - def send(self, obj, n=None): - #print 'send', n,; self._check(obj) - if n is None: - n = self.count - self.count += 2 - data = (n, obj, None) - else: - data = (n, obj) - self.sendraw(data) - become(obj, thunk(self._resume, n)) - #print 'done', n,; self._check(obj) - - def recv(self): - obj = self.inputfifo.pop(0) - #print 'recv',; self._check(obj) - return obj - - def _resume(self, n): - #print 'resume', n,; sys.stdout.flush() - assert n not in self.cache - self.sendraw((n,)) - while n not in self.cache: - self.handle_once() - obj = self.cache[n] - #self._check(obj) - return obj - - def handle_once(self): - input = self.recvraw() - if len(input) > 1: - obj = input[1] - self.cache[input[0]] = obj - if len(input) > 2: - self.inputfifo.append(obj) - else: - n = input[0] - obj = self.cache[n] - self.send(obj, n) - del self.cache[n] - - -def mainloop(channels): - stdin = sys.stdin.fileno() - sockfd = [chan.s.fileno() for chan in channels] - while True: - sys.stdout.write('>>> ') - sys.stdout.flush() - while True: - iwtd, owtd, ewtd = select([stdin] + sockfd, [], [stdin]) - if stdin in iwtd or stdin in ewtd: break - for chan in channels: - if chan.s.fileno() in iwtd: - chan.handle_once() - code = raw_input() - if not code: break - try: - co = compile(code, '', 'single') - exec co in globals() - except Exception, e: - print e.__class__.__name__, str(e) - - -def server(port): - s = socket(AF_INET, SOCK_STREAM) - s.bind(('', port)) - s.listen(1) - print 'Waiting for connection on port', port - s, addr = s.accept() - print 'Connected from', addr - return Channel(s, True) - -def client(addr): - s = socket(AF_INET, SOCK_STREAM) - print 'Connecting to', addr - s.connect(addr) - print 'Ok' - return Channel(s, False) - - -if __name__ == '__main__': - try: - thunk, become # only available in 'py.py -o thunk' - except NameError: - print __doc__ - raise SystemExit(2) - - channels = [] - for a in sys.argv[1:]: - try: - port = int(a) - except ValueError: - host, port = a.split(':') - port = int(port) - chan = client((host, port)) - else: - chan = server(port) - channels.append(chan) - - try: - mainloop(channels) - finally: - for channel in channels: - channel.s.close() diff --git a/demo/tproxy/persistence.py b/demo/tproxy/persistence.py deleted file mode 100644 --- a/demo/tproxy/persistence.py +++ /dev/null @@ -1,62 +0,0 @@ -""" - -This small example implements a basic orthogonal persistence -mechanism on top of PyPy's transparent proxies. - -""" -from tputil import make_proxy - -list_changeops = set('__iadd__ __imul__ __delitem__ __setitem__ __setattr__' - '__delslice__ __setslice__ ' - 'append extend insert pop remove reverse sort'.split()) - -dict_changeops = set('__delitem__ __setitem__ __setattr__' - 'clear pop popitem setdefault update'.split()) - -def ischangeop(operation): - """ return True if this operation is a changing operation - on known builtins (dicts, lists). - """ - if isinstance(operation.obj, list): - changeops = list_changeops - elif isinstance(operation.obj, dict): - changeops = dict_changeops - else: - return False - return operation.opname in changeops - -def make_persistent_proxy(instance, storage): - def perform(operation): - res = operation.delegate() - if ischangeop(operation): - print "persisting after:", operation - storage.dump(instance) - if res is not operation.proxyobj and isinstance(res, (dict, list)): - res = make_proxy(perform, obj=res) - return res - return make_proxy(perform, obj=instance) - -def load(storage): - obj = storage.load() - return make_persistent_proxy(obj, storage) - -if __name__ == '__main__': - import py - storage = py.path.local("/tmp/dictpickle") - pdict = make_persistent_proxy({}, storage) - - # the code below is not aware of pdict being a proxy - assert type(pdict) is dict - pdict['hello'] = 'world' - pdict['somelist'] = [] - del pdict - - newdict = load(storage) - assert newdict == {'hello': 'world', 'somelist': []} - l = newdict['somelist'] - l.append(1) # this triggers persisting the whole dict - l.extend([2,3]) # this triggers persisting the whole dict - del newdict, l - - newdict = load(storage) - print newdict['somelist'] # will show [1,2,3] diff --git a/demo/tproxy/print_operations.py b/demo/tproxy/print_operations.py deleted file mode 100644 --- a/demo/tproxy/print_operations.py +++ /dev/null @@ -1,26 +0,0 @@ -""" - -This example transparently intercepts and shows operations on -builtin objects. Requires the "--objspace-std-withtproxy" option. - -""" - -from tputil import make_proxy - -def make_show_proxy(instance): - def controller(operation): - print "proxy sees:", operation - res = operation.delegate() - return res - tproxy = make_proxy(controller, obj=instance) - return tproxy - -if __name__ == '__main__': - mydict = make_show_proxy({}) - assert type(mydict) is dict # this looks exactly like a dict - mydict['hello'] = 'world' # will print __setitem__ - mydict[42] = 23 # will print __setitem__ - assert mydict.pop('hello') == 'world' # will print pop - assert mydict.popitem() == (42,23) # will print popitem - - diff --git a/dotviewer/test/test_translator.py b/dotviewer/test/test_translator.py --- a/dotviewer/test/test_translator.py +++ b/dotviewer/test/test_translator.py @@ -21,7 +21,7 @@ def test_annotated(): - from pypy.translator.interactive import Translation + from rpython.translator.interactive import Translation t = Translation(is_prime) t.annotate([int]) t.viewcg() diff --git a/lib-python/2.7/collections.py b/lib-python/2.7/collections.py --- a/lib-python/2.7/collections.py +++ b/lib-python/2.7/collections.py @@ -298,7 +298,7 @@ _fields = %(field_names)r \n def __new__(_cls, %(argtxt)s): 'Create new instance of %(typename)s(%(argtxt)s)' - return _tuple.__new__(_cls, (%(argtxt)s)) \n + return tuple.__new__(_cls, (%(argtxt)s)) \n @classmethod def _make(cls, iterable, new=tuple.__new__, len=len): 'Make a new %(typename)s object from a sequence or iterable' @@ -323,14 +323,14 @@ 'Return self as a plain tuple. Used by copy and pickle.' return tuple(self) \n\n''' % locals() for i, name in enumerate(field_names): - template += " %s = _property(_itemgetter(%d), doc='Alias for field number %d')\n" % (name, i, i) + template += " %s = property(lambda self: self[%d], doc='Alias for field number %d')\n" % (name, i, i) if verbose: print template # Execute the template string in a temporary namespace and # support tracing utilities by setting a value for frame.f_globals['__name__'] - namespace = dict(_itemgetter=_itemgetter, __name__='namedtuple_%s' % typename, - OrderedDict=OrderedDict, _property=property, _tuple=tuple) + namespace = {'__name__': 'namedtuple_%s' % typename, + 'OrderedDict': OrderedDict} try: exec template in namespace except SyntaxError, e: diff --git a/lib-python/2.7/ctypes/test/test_internals.py b/lib-python/2.7/ctypes/test/test_internals.py --- a/lib-python/2.7/ctypes/test/test_internals.py +++ b/lib-python/2.7/ctypes/test/test_internals.py @@ -1,7 +1,10 @@ # This tests the internal _objects attribute import unittest from ctypes import * -from sys import getrefcount as grc +try: + from sys import getrefcount as grc +except ImportError: + grc = None # e.g. PyPy # XXX This test must be reviewed for correctness!!! @@ -22,6 +25,8 @@ self.assertEqual(id(a), id(b)) def test_ints(self): + if grc is None: + return unittest.skip("no sys.getrefcount()") i = 42000123 refcnt = grc(i) ci = c_int(i) @@ -29,6 +34,8 @@ self.assertEqual(ci._objects, None) def test_c_char_p(self): + if grc is None: + return unittest.skip("no sys.getrefcount()") s = "Hello, World" refcnt = grc(s) cs = c_char_p(s) diff --git a/lib-python/2.7/ctypes/test/test_memfunctions.py b/lib-python/2.7/ctypes/test/test_memfunctions.py --- a/lib-python/2.7/ctypes/test/test_memfunctions.py +++ b/lib-python/2.7/ctypes/test/test_memfunctions.py @@ -53,7 +53,8 @@ s = string_at("foo bar") # XXX The following may be wrong, depending on how Python # manages string instances - self.assertEqual(2, sys.getrefcount(s)) + if hasattr(sys, 'getrefcount'): + self.assertEqual(2, sys.getrefcount(s)) self.assertTrue(s, "foo bar") self.assertEqual(string_at("foo bar", 8), "foo bar\0") diff --git a/lib-python/2.7/ctypes/test/test_python_api.py b/lib-python/2.7/ctypes/test/test_python_api.py --- a/lib-python/2.7/ctypes/test/test_python_api.py +++ b/lib-python/2.7/ctypes/test/test_python_api.py @@ -9,7 +9,10 @@ ################################################################ -from sys import getrefcount as grc +try: + from sys import getrefcount as grc +except ImportError: + grc = None # e.g. PyPy if sys.version_info > (2, 4): c_py_ssize_t = c_size_t else: diff --git a/lib-python/2.7/ctypes/test/test_refcounts.py b/lib-python/2.7/ctypes/test/test_refcounts.py --- a/lib-python/2.7/ctypes/test/test_refcounts.py +++ b/lib-python/2.7/ctypes/test/test_refcounts.py @@ -11,7 +11,10 @@ class RefcountTestCase(unittest.TestCase): def test_1(self): - from sys import getrefcount as grc + try: + from sys import getrefcount as grc + except ImportError: + return unittest.skip("no sys.getrefcount()") f = dll._testfunc_callback_i_if f.restype = ctypes.c_int @@ -35,7 +38,10 @@ def test_refcount(self): - from sys import getrefcount as grc + try: + from sys import getrefcount as grc + except ImportError: + return unittest.skip("no sys.getrefcount()") def func(*args): pass # this is the standard refcount for func @@ -84,6 +90,10 @@ class AnotherLeak(unittest.TestCase): def test_callback(self): import sys + try: + from sys import getrefcount + except ImportError: + return unittest.skip("no sys.getrefcount()") proto = ctypes.CFUNCTYPE(ctypes.c_int, ctypes.c_int, ctypes.c_int) def func(a, b): diff --git a/lib-python/2.7/distutils/command/build_ext.py b/lib-python/2.7/distutils/command/build_ext.py --- a/lib-python/2.7/distutils/command/build_ext.py +++ b/lib-python/2.7/distutils/command/build_ext.py @@ -699,6 +699,9 @@ shared extension. On most platforms, this is just 'ext.libraries'; on Windows and OS/2, we add the Python library (eg. python20.dll). """ + # For PyPy, we must not add any such Python library, on any platform + if "__pypy__" in sys.builtin_module_names: + return ext.libraries # The python library is always needed on Windows. if sys.platform == "win32": template = "python%d%d" diff --git a/lib-python/2.7/inspect.py b/lib-python/2.7/inspect.py --- a/lib-python/2.7/inspect.py +++ b/lib-python/2.7/inspect.py @@ -960,7 +960,7 @@ raise TypeError('%s() takes exactly 0 arguments ' '(%d given)' % (f_name, num_total)) else: - raise TypeError('%s() takes no argument (%d given)' % + raise TypeError('%s() takes no arguments (%d given)' % (f_name, num_total)) for arg in args: if isinstance(arg, str) and arg in named: diff --git a/lib-python/2.7/json/decoder.py b/lib-python/2.7/json/decoder.py --- a/lib-python/2.7/json/decoder.py +++ b/lib-python/2.7/json/decoder.py @@ -62,8 +62,7 @@ DEFAULT_ENCODING = "utf-8" -def py_scanstring(s, end, encoding=None, strict=True, - _b=BACKSLASH, _m=STRINGCHUNK.match): +def py_scanstring(s, end, encoding=None, strict=True): """Scan the string s for a JSON string. End is the index of the character in s after the quote that started the JSON string. Unescapes all valid JSON string escape sequences and raises ValueError @@ -78,7 +77,7 @@ _append = chunks.append begin = end - 1 while 1: - chunk = _m(s, end) + chunk = STRINGCHUNK.match(s, end) if chunk is None: raise ValueError( errmsg("Unterminated string starting at", s, begin)) @@ -109,7 +108,7 @@ # If not a unicode escape sequence, must be in the lookup table if esc != 'u': try: - char = _b[esc] + char = BACKSLASH[esc] except KeyError: msg = "Invalid \\escape: " + repr(esc) raise ValueError(errmsg(msg, s, end)) @@ -147,7 +146,7 @@ WHITESPACE_STR = ' \t\n\r' def JSONObject(s_and_end, encoding, strict, scan_once, object_hook, - object_pairs_hook, _w=WHITESPACE.match, _ws=WHITESPACE_STR): + object_pairs_hook): s, end = s_and_end pairs = [] pairs_append = pairs.append @@ -156,8 +155,8 @@ nextchar = s[end:end + 1] # Normally we expect nextchar == '"' if nextchar != '"': - if nextchar in _ws: - end = _w(s, end).end() + if nextchar in WHITESPACE_STR: + end = WHITESPACE.match(s, end).end() nextchar = s[end:end + 1] # Trivial empty object if nextchar == '}': @@ -177,17 +176,17 @@ # To skip some function call overhead we optimize the fast paths where # the JSON key separator is ": " or just ":". if s[end:end + 1] != ':': - end = _w(s, end).end() + end = WHITESPACE.match(s, end).end() if s[end:end + 1] != ':': raise ValueError(errmsg("Expecting : delimiter", s, end)) end += 1 try: - if s[end] in _ws: + if s[end] in WHITESPACE_STR: end += 1 - if s[end] in _ws: - end = _w(s, end + 1).end() + if s[end] in WHITESPACE_STR: + end = WHITESPACE.match(s, end + 1).end() except IndexError: pass @@ -199,8 +198,8 @@ try: nextchar = s[end] - if nextchar in _ws: - end = _w(s, end + 1).end() + if nextchar in WHITESPACE_STR: + end = WHITESPACE.match(s, end + 1).end() nextchar = s[end] except IndexError: nextchar = '' @@ -213,11 +212,11 @@ try: nextchar = s[end] - if nextchar in _ws: + if nextchar in WHITESPACE_STR: end += 1 nextchar = s[end] - if nextchar in _ws: - end = _w(s, end + 1).end() + if nextchar in WHITESPACE_STR: + end = WHITESPACE.match(s, end + 1).end() nextchar = s[end] except IndexError: nextchar = '' @@ -234,12 +233,12 @@ pairs = object_hook(pairs) return pairs, end -def JSONArray(s_and_end, scan_once, _w=WHITESPACE.match, _ws=WHITESPACE_STR): +def JSONArray(s_and_end, scan_once): s, end = s_and_end values = [] nextchar = s[end:end + 1] - if nextchar in _ws: - end = _w(s, end + 1).end() + if nextchar in WHITESPACE_STR: + end = WHITESPACE.match(s, end + 1).end() nextchar = s[end:end + 1] # Look-ahead for trivial empty array if nextchar == ']': @@ -252,8 +251,8 @@ raise ValueError(errmsg("Expecting object", s, end)) _append(value) nextchar = s[end:end + 1] - if nextchar in _ws: - end = _w(s, end + 1).end() + if nextchar in WHITESPACE_STR: + end = WHITESPACE.match(s, end + 1).end() nextchar = s[end:end + 1] end += 1 if nextchar == ']': @@ -262,10 +261,10 @@ raise ValueError(errmsg("Expecting , delimiter", s, end)) try: - if s[end] in _ws: + if s[end] in WHITESPACE_STR: end += 1 - if s[end] in _ws: - end = _w(s, end + 1).end() + if s[end] in WHITESPACE_STR: + end = WHITESPACE.match(s, end + 1).end() except IndexError: pass @@ -358,13 +357,13 @@ self.parse_string = scanstring self.scan_once = scanner.make_scanner(self) - def decode(self, s, _w=WHITESPACE.match): + def decode(self, s): """Return the Python representation of ``s`` (a ``str`` or ``unicode`` instance containing a JSON document) """ - obj, end = self.raw_decode(s, idx=_w(s, 0).end()) - end = _w(s, end).end() + obj, end = self.raw_decode(s, idx=WHITESPACE.match(s, 0).end()) + end = WHITESPACE.match(s, end).end() if end != len(s): raise ValueError(errmsg("Extra data", s, end, len(s))) return obj diff --git a/lib-python/2.7/site.py b/lib-python/2.7/site.py --- a/lib-python/2.7/site.py +++ b/lib-python/2.7/site.py @@ -75,6 +75,7 @@ USER_SITE = None USER_BASE = None + def makepath(*paths): dir = os.path.join(*paths) try: diff --git a/lib-python/2.7/sre_parse.py b/lib-python/2.7/sre_parse.py --- a/lib-python/2.7/sre_parse.py +++ b/lib-python/2.7/sre_parse.py @@ -16,6 +16,12 @@ from sre_constants import * +try: + from __pypy__ import newdict +except ImportError: + def newdict(tp): + return {} + SPECIAL_CHARS = ".\\[{()*+?^$|" REPEAT_CHARS = "*+?{" @@ -68,7 +74,7 @@ self.flags = 0 self.open = [] self.groups = 1 - self.groupdict = {} + self.groupdict = newdict("module") def opengroup(self, name=None): gid = self.groups self.groups = gid + 1 diff --git a/lib-python/2.7/sysconfig.py b/lib-python/2.7/sysconfig.py --- a/lib-python/2.7/sysconfig.py +++ b/lib-python/2.7/sysconfig.py @@ -27,10 +27,10 @@ 'data' : '{base}', }, 'pypy': { - 'stdlib': '{base}/lib-python', - 'platstdlib': '{base}/lib-python', - 'purelib': '{base}/lib-python', - 'platlib': '{base}/lib-python', + 'stdlib': '{base}/lib-python/{py_version_short}', + 'platstdlib': '{base}/lib-python/{py_version_short}', + 'purelib': '{base}/lib-python/{py_version_short}', + 'platlib': '{base}/lib-python/{py_version_short}', 'include': '{base}/include', 'platinclude': '{base}/include', 'scripts': '{base}/bin', diff --git a/lib-python/2.7/test/test_capi.py b/lib-python/2.7/test/test_capi.py --- a/lib-python/2.7/test/test_capi.py +++ b/lib-python/2.7/test/test_capi.py @@ -13,6 +13,17 @@ threading = None import _testcapi +skips = [] +if test_support.check_impl_detail(pypy=True): + skips += [ + 'test_broken_memoryview', + 'test_capsule', + 'test_lazy_hash_inheritance', + 'test_widechar', + 'TestThreadState', + 'TestPendingCalls', + ] + @unittest.skipUnless(threading, 'Threading required for this test.') class TestPendingCalls(unittest.TestCase): @@ -99,7 +110,7 @@ def test_main(): for name in dir(_testcapi): - if name.startswith('test_'): + if name.startswith('test_') and name not in skips: test = getattr(_testcapi, name) if test_support.verbose: print "internal", name @@ -126,7 +137,7 @@ raise test_support.TestFailed, \ "Couldn't find main thread correctly in the list" - if threading: + if threading and 'TestThreadState' not in skips: import thread import time TestThreadState() @@ -134,7 +145,8 @@ t.start() t.join() - test_support.run_unittest(TestPendingCalls) + if 'TestPendingCalls' not in skips: + test_support.run_unittest(TestPendingCalls) if __name__ == "__main__": test_main() diff --git a/lib-python/2.7/test/test_iterlen.py b/lib-python/2.7/test/test_iterlen.py --- a/lib-python/2.7/test/test_iterlen.py +++ b/lib-python/2.7/test/test_iterlen.py @@ -94,7 +94,11 @@ def test_no_len_for_infinite_repeat(self): # The repeat() object can also be infinite - self.assertRaises(TypeError, len, repeat(None)) + if test_support.check_impl_detail(pypy=True): + # 3.4 (PEP 424) behavior + self.assertEqual(len(repeat(None)), NotImplemented) + else: + self.assertRaises(TypeError, len, repeat(None)) class TestXrange(TestInvariantWithoutMutations): @@ -230,6 +234,7 @@ self.assertRaises(RuntimeError, b.extend, BadLen()) self.assertRaises(RuntimeError, b.extend, BadLengthHint()) + @test_support.impl_detail("PEP 424 disallows None results", pypy=False) def test_invalid_hint(self): # Make sure an invalid result doesn't muck-up the works self.assertEqual(list(NoneLengthHint()), list(range(10))) diff --git a/lib-python/2.7/test/test_itertools.py b/lib-python/2.7/test/test_itertools.py --- a/lib-python/2.7/test/test_itertools.py +++ b/lib-python/2.7/test/test_itertools.py @@ -533,11 +533,11 @@ self.assertEqual(list(izip()), zip()) self.assertRaises(TypeError, izip, 3) self.assertRaises(TypeError, izip, range(3), 3) - self.assertEqual([tuple(list(pair)) for pair in izip('abc', 'def')], zip('abc', 'def')) self.assertEqual([pair for pair in izip('abc', 'def')], zip('abc', 'def')) + @test_support.impl_detail("tuple reuse is specific to CPython") def test_izip_tuple_reuse(self): ids = map(id, izip('abc', 'def')) @@ -588,6 +588,7 @@ zip('abc', 'def')) self.assertEqual([pair for pair in izip_longest('abc', 'def')], zip('abc', 'def')) + @test_support.impl_detail("tuple reuse is specific to CPython") def test_izip_longest_tuple_reuse(self): ids = map(id, izip_longest('abc', 'def')) diff --git a/lib-python/2.7/test/test_modulefinder.py b/lib-python/2.7/test/test_modulefinder.py --- a/lib-python/2.7/test/test_modulefinder.py +++ b/lib-python/2.7/test/test_modulefinder.py @@ -16,7 +16,7 @@ # library. TEST_DIR = tempfile.mkdtemp() -TEST_PATH = [TEST_DIR, os.path.dirname(__future__.__file__)] +TEST_PATH = [TEST_DIR, os.path.dirname(tempfile.__file__)] # Each test description is a list of 5 items: # diff --git a/lib-python/2.7/test/test_multiprocessing.py b/lib-python/2.7/test/test_multiprocessing.py --- a/lib-python/2.7/test/test_multiprocessing.py +++ b/lib-python/2.7/test/test_multiprocessing.py @@ -1343,7 +1343,7 @@ # Because we are using xmlrpclib for serialization instead of # pickle this will cause a serialization error. - self.assertRaises(Exception, queue.put, time.sleep) + self.assertRaises(Exception, queue.put, object) # Make queue finalizer run before the server is stopped del queue @@ -1800,9 +1800,9 @@ if not gc.isenabled(): gc.enable() self.addCleanup(gc.disable) - thresholds = gc.get_threshold() - self.addCleanup(gc.set_threshold, *thresholds) - gc.set_threshold(10) + #thresholds = gc.get_threshold() + #self.addCleanup(gc.set_threshold, *thresholds) + #gc.set_threshold(10) # perform numerous block allocations, with cyclic references to make # sure objects are collected asynchronously by the gc @@ -1865,6 +1865,7 @@ def test_synchronize(self): self.test_sharedctypes(lock=True) + @unittest.skipUnless(test_support.check_impl_detail(pypy=False), "pypy ctypes differences") def test_copy(self): foo = _Foo(2, 5.0) bar = copy(foo) diff --git a/lib-python/2.7/test/test_support.py b/lib-python/2.7/test/test_support.py --- a/lib-python/2.7/test/test_support.py +++ b/lib-python/2.7/test/test_support.py @@ -1085,7 +1085,6 @@ else: runner = BasicTestRunner() - result = runner.run(suite) if not result.wasSuccessful(): if len(result.errors) == 1 and not result.failures: diff --git a/lib-python/2.7/test/test_zipfile.py b/lib-python/2.7/test/test_zipfile.py --- a/lib-python/2.7/test/test_zipfile.py +++ b/lib-python/2.7/test/test_zipfile.py @@ -1213,6 +1213,17 @@ self.assertEqual(data1, '1'*FIXEDTEST_SIZE) self.assertEqual(data2, '2'*FIXEDTEST_SIZE) + def test_many_opens(self): + # Verify that read() and open() promptly close the file descriptor, + # and don't rely on the garbage collector to free resources. + with zipfile.ZipFile(TESTFN2, mode="r") as zipf: + for x in range(100): + zipf.read('ones') + with zipf.open('ones') as zopen1: + pass + for x in range(10): + self.assertLess(open('/dev/null').fileno(), 100) + def tearDown(self): unlink(TESTFN2) diff --git a/lib-python/2.7/timeit.py b/lib-python/2.7/timeit.py --- a/lib-python/2.7/timeit.py +++ b/lib-python/2.7/timeit.py @@ -190,7 +190,8 @@ else: it = [None] * number gcold = gc.isenabled() - gc.disable() + if '__pypy__' not in sys.builtin_module_names: + gc.disable() # only do that on CPython try: timing = self.inner(it, self.timer) finally: diff --git a/lib-python/2.7/zipfile.py b/lib-python/2.7/zipfile.py --- a/lib-python/2.7/zipfile.py +++ b/lib-python/2.7/zipfile.py @@ -475,9 +475,11 @@ # Search for universal newlines or line chunks. PATTERN = re.compile(r'^(?P[^\r\n]+)|(?P\n|\r\n?)') - def __init__(self, fileobj, mode, zipinfo, decrypter=None): + def __init__(self, fileobj, mode, zipinfo, decrypter=None, + close_fileobj=False): self._fileobj = fileobj self._decrypter = decrypter + self._close_fileobj = close_fileobj self._compress_type = zipinfo.compress_type self._compress_size = zipinfo.compress_size @@ -649,6 +651,12 @@ self._offset += len(data) return data + def close(self): + try: + if self._close_fileobj: + self._fileobj.close() + finally: + super(ZipExtFile, self).close() class ZipFile: @@ -866,7 +874,8 @@ def read(self, name, pwd=None): """Return file bytes (as a string) for name.""" - return self.open(name, "r", pwd).read() + with self.open(name, "r", pwd) as fp: + return fp.read() def open(self, name, mode="r", pwd=None): """Return file-like object for 'name'.""" @@ -889,8 +898,12 @@ zinfo = name else: # Get info object for name - zinfo = self.getinfo(name) - + try: + zinfo = self.getinfo(name) + except KeyError: + if not self._filePassed: + zef_file.close() + raise zef_file.seek(zinfo.header_offset, 0) # Skip the file header: @@ -904,6 +917,8 @@ zef_file.read(fheader[_FH_EXTRA_FIELD_LENGTH]) if fname != zinfo.orig_filename: + if not self._filePassed: + zef_file.close() raise BadZipfile, \ 'File name in directory "%s" and header "%s" differ.' % ( zinfo.orig_filename, fname) @@ -915,6 +930,8 @@ if not pwd: pwd = self.pwd if not pwd: + if not self._filePassed: + zef_file.close() raise RuntimeError, "File %s is encrypted, " \ "password required for extraction" % name @@ -933,9 +950,12 @@ # compare against the CRC otherwise check_byte = (zinfo.CRC >> 24) & 0xff if ord(h[11]) != check_byte: + if not self._filePassed: + zef_file.close() raise RuntimeError("Bad password for file", name) - return ZipExtFile(zef_file, mode, zinfo, zd) + return ZipExtFile(zef_file, mode, zinfo, zd, + close_fileobj=not self._filePassed) def extract(self, member, path=None, pwd=None): """Extract a member from the archive to the current working directory, @@ -993,7 +1013,7 @@ return targetpath source = self.open(member, pwd=pwd) - target = file(targetpath, "wb") + target = open(targetpath, "wb") shutil.copyfileobj(source, target) source.close() target.close() diff --git a/lib-python/conftest.py b/lib-python/conftest.py --- a/lib-python/conftest.py +++ b/lib-python/conftest.py @@ -14,11 +14,11 @@ from pypy.interpreter.main import run_string, run_file # the following adds command line options as a side effect! -from pypy.conftest import gettestobjspace, option as pypy_option +from pypy.conftest import option as pypy_option from pypy.tool.pytest import appsupport -from pypy.tool.pytest.confpath import pypydir, testdir, testresultdir -from pypy.config.parse import parse_info +from pypy.tool.pytest.confpath import pypydir, rpythondir, testdir, testresultdir +from rpython.config.parse import parse_info pytest_plugins = "resultlog", rsyncdirs = ['.', '../pypy/'] @@ -40,7 +40,7 @@ dest="unittest_filter", help="Similar to -k, XXX") def gettimeout(timeout): - from test import pystone + from rpython.translator.test import rpystone if timeout.endswith('mp'): megapystone = float(timeout[:-2]) t, stone = pystone.Proc0(10000) @@ -61,7 +61,7 @@ usemodules = '', skip=None): self.basename = basename - self._usemodules = usemodules.split() + ['signal'] + self._usemodules = usemodules.split() + ['signal', 'rctime', 'itertools', '_socket'] self._compiler = compiler self.core = core self.skip = skip @@ -93,63 +93,57 @@ m.test_main() ''' % locals()) -if sys.platform == 'win32': - skip_win32 = "Not supported on Windows" - only_win32 = False -else: - skip_win32 = False - only_win32 = "Only on Windows" - testmap = [ RegrTest('test___all__.py', core=True), RegrTest('test___future__.py', core=True), - RegrTest('test__locale.py', skip=skip_win32), + RegrTest('test__locale.py', usemodules='_locale'), RegrTest('test_abc.py'), RegrTest('test_abstract_numbers.py'), - RegrTest('test_aepack.py', skip=True), + RegrTest('test_aepack.py'), RegrTest('test_aifc.py'), - RegrTest('test_argparse.py'), - RegrTest('test_al.py', skip=True), - RegrTest('test_ast.py', core=True), - RegrTest('test_anydbm.py'), - RegrTest('test_applesingle.py', skip=True), - RegrTest('test_array.py', core=True, usemodules='struct array'), + RegrTest('test_al.py'), + RegrTest('test_anydbm.py', usemodules='struct'), + RegrTest('test_applesingle.py'), + RegrTest('test_argparse.py', usemodules='binascii'), + RegrTest('test_array.py', core=True, usemodules='struct array binascii'), RegrTest('test_ascii_formatd.py'), - RegrTest('test_asynchat.py', usemodules='thread'), - RegrTest('test_asyncore.py'), + RegrTest('test_ast.py', core=True, usemodules='struct'), + RegrTest('test_asynchat.py', usemodules='select fcntl'), + RegrTest('test_asyncore.py', usemodules='select fcntl'), RegrTest('test_atexit.py', core=True), - RegrTest('test_audioop.py', skip=True), + RegrTest('test_audioop.py', skip="unsupported extension module"), RegrTest('test_augassign.py', core=True), - RegrTest('test_base64.py'), + RegrTest('test_base64.py', usemodules='struct'), RegrTest('test_bastion.py'), + RegrTest('test_bigaddrspace.py'), + RegrTest('test_bigmem.py'), RegrTest('test_binascii.py', usemodules='binascii'), - RegrTest('test_binhex.py'), - RegrTest('test_binop.py', core=True), RegrTest('test_bisect.py', core=True, usemodules='_bisect'), RegrTest('test_bool.py', core=True), - RegrTest('test_bsddb.py', skip="unsupported extension module"), - RegrTest('test_bsddb185.py', skip="unsupported extension module"), - RegrTest('test_bsddb3.py', skip="unsupported extension module"), + RegrTest('test_bsddb.py'), + RegrTest('test_bsddb185.py'), + RegrTest('test_bsddb3.py'), RegrTest('test_buffer.py'), RegrTest('test_bufio.py', core=True), - RegrTest('test_builtin.py', core=True), - RegrTest('test_bytes.py'), + RegrTest('test_builtin.py', core=True, usemodules='binascii'), + RegrTest('test_bytes.py', usemodules='struct binascii'), RegrTest('test_bz2.py', usemodules='bz2'), RegrTest('test_calendar.py'), RegrTest('test_call.py', core=True), - RegrTest('test_capi.py', skip="not applicable"), - RegrTest('test_cd.py', skip=True), + RegrTest('test_capi.py'), + RegrTest('test_cd.py'), RegrTest('test_cfgparser.py'), - RegrTest('test_cgi.py'), RegrTest('test_charmapcodec.py', core=True), - RegrTest('test_cl.py', skip=True), + RegrTest('test_cl.py'), RegrTest('test_class.py', core=True), RegrTest('test_cmath.py', core=True), RegrTest('test_cmd.py'), + RegrTest('test_cmd_line.py'), RegrTest('test_cmd_line_script.py'), + RegrTest('test_code.py', core=True), RegrTest('test_codeccallbacks.py', core=True), RegrTest('test_codecencodings_cn.py', usemodules='_multibytecodec'), RegrTest('test_codecencodings_hk.py', usemodules='_multibytecodec'), @@ -157,7 +151,6 @@ RegrTest('test_codecencodings_jp.py', usemodules='_multibytecodec'), RegrTest('test_codecencodings_kr.py', usemodules='_multibytecodec'), RegrTest('test_codecencodings_tw.py', usemodules='_multibytecodec'), - RegrTest('test_codecmaps_cn.py', usemodules='_multibytecodec'), RegrTest('test_codecmaps_hk.py', usemodules='_multibytecodec'), RegrTest('test_codecmaps_jp.py', usemodules='_multibytecodec'), @@ -165,8 +158,9 @@ RegrTest('test_codecmaps_tw.py', usemodules='_multibytecodec'), RegrTest('test_codecs.py', core=True, usemodules='_multibytecodec'), RegrTest('test_codeop.py', core=True), + RegrTest('test_coding.py', core=True), RegrTest('test_coercion.py', core=True), - RegrTest('test_collections.py'), + RegrTest('test_collections.py', usemodules='binascii struct'), RegrTest('test_colorsys.py'), RegrTest('test_commands.py'), RegrTest('test_compare.py', core=True), @@ -174,22 +168,24 @@ RegrTest('test_compileall.py'), RegrTest('test_compiler.py', core=False, skip="slowly deprecating compiler"), RegrTest('test_complex.py', core=True), - + RegrTest('test_complex_args.py'), RegrTest('test_contains.py', core=True), + RegrTest('test_contextlib.py', usemodules="thread"), RegrTest('test_cookie.py'), RegrTest('test_cookielib.py'), RegrTest('test_copy.py', core=True), RegrTest('test_copy_reg.py', core=True), RegrTest('test_cpickle.py', core=True), - RegrTest('test_cprofile.py'), - RegrTest('test_crypt.py', usemodules='crypt', skip=skip_win32), + RegrTest('test_cprofile.py'), + RegrTest('test_crypt.py', usemodules='crypt'), RegrTest('test_csv.py', usemodules='_csv'), - - RegrTest('test_curses.py', skip="unsupported extension module"), - RegrTest('test_datetime.py'), + RegrTest('test_ctypes.py', usemodules="_rawffi thread"), + RegrTest('test_curses.py'), + RegrTest('test_datetime.py', usemodules='binascii struct'), RegrTest('test_dbm.py'), RegrTest('test_decimal.py'), RegrTest('test_decorators.py', core=True), + RegrTest('test_defaultdict.py', usemodules='_collections'), RegrTest('test_deque.py', core=True, usemodules='_collections'), RegrTest('test_descr.py', core=True, usemodules='_weakref'), RegrTest('test_descrtut.py', core=True), @@ -200,7 +196,7 @@ RegrTest('test_dircache.py', core=True), RegrTest('test_dis.py'), RegrTest('test_distutils.py', skip=True), - RegrTest('test_dl.py', skip=True), + RegrTest('test_dl.py'), RegrTest('test_doctest.py', usemodules="thread"), RegrTest('test_doctest2.py'), RegrTest('test_docxmlrpc.py'), @@ -208,20 +204,22 @@ RegrTest('test_dummy_thread.py', core=True), RegrTest('test_dummy_threading.py', core=True), RegrTest('test_email.py'), - RegrTest('test_email_codecs.py'), + RegrTest('test_email_renamed.py'), RegrTest('test_enumerate.py', core=True), RegrTest('test_eof.py', core=True), RegrTest('test_epoll.py'), RegrTest('test_errno.py', usemodules="errno"), + RegrTest('test_exception_variations.py'), RegrTest('test_exceptions.py', core=True), RegrTest('test_extcall.py', core=True), - RegrTest('test_fcntl.py', usemodules='fcntl', skip=skip_win32), + RegrTest('test_fcntl.py', usemodules='fcntl'), RegrTest('test_file.py', usemodules="posix", core=True), RegrTest('test_file2k.py', usemodules="posix", core=True), RegrTest('test_filecmp.py', core=True), RegrTest('test_fileinput.py', core=True), RegrTest('test_fileio.py'), + RegrTest('test_float.py', core=True), RegrTest('test_fnmatch.py', core=True), RegrTest('test_fork1.py', usemodules="thread"), RegrTest('test_format.py', core=True), @@ -230,6 +228,7 @@ RegrTest('test_frozen.py', skip="unsupported extension module"), RegrTest('test_ftplib.py'), RegrTest('test_funcattrs.py', core=True), + RegrTest('test_functools.py'), RegrTest('test_future.py', core=True), RegrTest('test_future1.py', core=True), RegrTest('test_future2.py', core=True), @@ -239,41 +238,37 @@ RegrTest('test_future_builtins.py'), RegrTest('test_gc.py', usemodules='_weakref', skip="implementation detail"), RegrTest('test_gdb.py', skip="not applicable"), - RegrTest('test_gdbm.py', skip="unsupported extension module"), + RegrTest('test_gdbm.py'), RegrTest('test_generators.py', core=True, usemodules='thread _weakref'), RegrTest('test_genericpath.py'), RegrTest('test_genexps.py', core=True, usemodules='_weakref'), - RegrTest('test_getargs.py', skip="unsupported extension module"), - RegrTest('test_getargs2.py', skip="unsupported extension module"), - + RegrTest('test_getargs.py'), + RegrTest('test_getargs2.py', usemodules='binascii', skip=True), RegrTest('test_getopt.py', core=True), RegrTest('test_gettext.py'), - - RegrTest('test_gl.py', skip=True), + RegrTest('test_gl.py'), RegrTest('test_glob.py', core=True), RegrTest('test_global.py', core=True), RegrTest('test_grammar.py', core=True), - RegrTest('test_grp.py', skip=skip_win32), - - RegrTest('test_gzip.py'), + RegrTest('test_grp.py'), + RegrTest('test_gzip.py', usemodules='zlib'), RegrTest('test_hash.py', core=True), RegrTest('test_hashlib.py', core=True), - RegrTest('test_heapq.py', core=True), RegrTest('test_hmac.py'), RegrTest('test_hotshot.py', skip="unsupported extension module"), - RegrTest('test_htmllib.py'), RegrTest('test_htmlparser.py'), RegrTest('test_httplib.py'), RegrTest('test_httpservers.py'), - RegrTest('test_imageop.py', skip="unsupported extension module"), + RegrTest('test_imageop.py'), RegrTest('test_imaplib.py'), - RegrTest('test_imgfile.py', skip="unsupported extension module"), + RegrTest('test_imgfile.py'), RegrTest('test_imp.py', core=True, usemodules='thread'), RegrTest('test_import.py', core=True), RegrTest('test_importhooks.py', core=True), RegrTest('test_importlib.py'), + RegrTest('test_index.py'), RegrTest('test_inspect.py'), RegrTest('test_int.py', core=True), RegrTest('test_int_literal.py', core=True), @@ -281,7 +276,7 @@ RegrTest('test_ioctl.py'), RegrTest('test_isinstance.py', core=True), RegrTest('test_iter.py', core=True), - RegrTest('test_iterlen.py', skip="undocumented internal API behavior __length_hint__"), + RegrTest('test_iterlen.py', core=True, usemodules="_collections itertools"), RegrTest('test_itertools.py', core=True, usemodules="itertools struct"), RegrTest('test_json.py'), RegrTest('test_kqueue.py'), @@ -296,7 +291,7 @@ RegrTest('test_long_future.py', core=True), RegrTest('test_longexp.py', core=True), RegrTest('test_macos.py'), - RegrTest('test_macostools.py', skip=True), + RegrTest('test_macostools.py'), RegrTest('test_macpath.py'), RegrTest('test_mailbox.py'), RegrTest('test_marshal.py', core=True), @@ -307,30 +302,29 @@ RegrTest('test_mhlib.py'), RegrTest('test_mimetools.py'), RegrTest('test_mimetypes.py'), - RegrTest('test_MimeWriter.py', core=False), + RegrTest('test_MimeWriter.py', core=False, usemodules='binascii'), RegrTest('test_minidom.py'), RegrTest('test_mmap.py', usemodules="mmap"), RegrTest('test_module.py', core=True), RegrTest('test_modulefinder.py'), - RegrTest('test_msilib.py', skip=only_win32), + RegrTest('test_msilib.py'), RegrTest('test_multibytecodec.py', usemodules='_multibytecodec'), - RegrTest('test_multibytecodec_support.py', skip="not a test"), RegrTest('test_multifile.py'), - RegrTest('test_multiprocessing.py', skip="FIXME leaves subprocesses"), + RegrTest('test_multiprocessing.py'), RegrTest('test_mutants.py', core="possibly"), RegrTest('test_mutex.py'), RegrTest('test_netrc.py'), RegrTest('test_new.py', core=True), - RegrTest('test_nis.py', skip="unsupported extension module"), + RegrTest('test_nis.py'), RegrTest('test_normalization.py'), RegrTest('test_ntpath.py'), + RegrTest('test_old_mailbox.py'), RegrTest('test_opcodes.py', core=True), RegrTest('test_openpty.py'), RegrTest('test_operator.py', core=True), RegrTest('test_optparse.py'), - RegrTest('test_os.py', core=True), - RegrTest('test_ossaudiodev.py', skip="unsupported extension module"), + RegrTest('test_ossaudiodev.py'), RegrTest('test_parser.py', skip="slowly deprecating compiler"), RegrTest('test_pdb.py'), RegrTest('test_peepholer.py'), @@ -338,14 +332,16 @@ RegrTest('test_pep263.py'), RegrTest('test_pep277.py'), RegrTest('test_pep292.py'), + RegrTest('test_pep352.py'), RegrTest('test_pickle.py', core=True), RegrTest('test_pickletools.py', core=False), RegrTest('test_pipes.py'), RegrTest('test_pkg.py', core=True), RegrTest('test_pkgimport.py', core=True), RegrTest('test_pkgutil.py'), - RegrTest('test_plistlib.py', skip="unsupported module"), - RegrTest('test_poll.py', skip=skip_win32), + RegrTest('test_platform.py'), + RegrTest('test_plistlib.py'), + RegrTest('test_poll.py'), RegrTest('test_popen.py'), RegrTest('test_popen2.py'), RegrTest('test_poplib.py'), @@ -357,8 +353,8 @@ RegrTest('test_profile.py'), RegrTest('test_property.py', core=True), From noreply at buildbot.pypy.org Thu Feb 7 16:29:39 2013 From: noreply at buildbot.pypy.org (jerith) Date: Thu, 7 Feb 2013 16:29:39 +0100 (CET) Subject: [pypy-commit] pypy curses_cffi: Turns out we need to be able to resize windows. Message-ID: <20130207152939.8472E1C02D9@cobra.cs.uni-duesseldorf.de> Author: Jeremy Thurgood Branch: curses_cffi Changeset: r60937:dff6aa17b730 Date: 2013-02-07 17:10 +0200 http://bitbucket.org/pypy/pypy/changeset/dff6aa17b730/ Log: Turns out we need to be able to resize windows. diff --git a/lib_pypy/_curses.py b/lib_pypy/_curses.py --- a/lib_pypy/_curses.py +++ b/lib_pypy/_curses.py @@ -210,6 +210,7 @@ int winsnstr(WINDOW *, const char *, int); int winsstr(WINDOW *, const char *); int wmove(WINDOW *, int, int); +int wresize(WINDOW *, int, int); int wnoutrefresh(WINDOW *); int wredrawln(WINDOW *, int, int); int wrefresh(WINDOW *); From noreply at buildbot.pypy.org Thu Feb 7 20:03:50 2013 From: noreply at buildbot.pypy.org (arigo) Date: Thu, 7 Feb 2013 20:03:50 +0100 (CET) Subject: [pypy-commit] cffi default: minibuffer: weakref support, and keep alive the argument. Message-ID: <20130207190350.536D51C02D9@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r1121:00f0e57fce9a Date: 2013-01-10 10:01 +0100 http://bitbucket.org/cffi/cffi/changeset/00f0e57fce9a/ Log: minibuffer: weakref support, and keep alive the argument. diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c --- a/c/_cffi_backend.c +++ b/c/_cffi_backend.c @@ -4485,7 +4485,7 @@ return NULL; } /*WRITE(cd->c_data, size)*/ - return minibuffer_new(cd->c_data, size); + return minibuffer_new(cd->c_data, size, (PyObject *)cd); } static PyObject *b_get_errno(PyObject *self, PyObject *noarg) diff --git a/c/minibuffer.h b/c/minibuffer.h --- a/c/minibuffer.h +++ b/c/minibuffer.h @@ -9,6 +9,8 @@ PyObject_HEAD char *mb_data; Py_ssize_t mb_size; + PyObject *mb_keepalive; + PyObject *mb_weakreflist; /* weakref support */ } MiniBufferObj; static Py_ssize_t mb_length(MiniBufferObj *self) @@ -120,6 +122,30 @@ (releasebufferproc)0, }; +static void +mb_dealloc(MiniBufferObj *ob) +{ + PyObject_GC_UnTrack(ob); + if (ob->mb_weakreflist != NULL) + PyObject_ClearWeakRefs((PyObject *)ob); + Py_XDECREF(ob->mb_keepalive); + Py_TYPE(ob)->tp_free((PyObject *)ob); +} + +static int +mb_traverse(MiniBufferObj *ob, visitproc visit, void *arg) +{ + Py_VISIT(ob->mb_keepalive); + return 0; +} + +static int +mb_clear(MiniBufferObj *ob) +{ + Py_CLEAR(ob->mb_keepalive); + return 0; +} + #if PY_MAJOR_VERSION >= 3 /* pfffffffffffff pages of copy-paste from listobject.c */ static PyObject *mb_subscript(MiniBufferObj *self, PyObject *item) @@ -198,9 +224,9 @@ #endif #if PY_MAJOR_VERSION >= 3 -# define MINIBUF_TPFLAGS (Py_TPFLAGS_DEFAULT) +# define MINIBUF_TPFLAGS 0 #else -# define MINIBUF_TPFLAGS (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GETCHARBUFFER | Py_TPFLAGS_HAVE_NEWBUFFER) +# define MINIBUF_TPFLAGS (Py_TPFLAGS_HAVE_GETCHARBUFFER | Py_TPFLAGS_HAVE_NEWBUFFER) #endif static PyTypeObject MiniBuffer_Type = { @@ -208,7 +234,7 @@ "_cffi_backend.buffer", sizeof(MiniBufferObj), 0, - (destructor)PyObject_Del, /* tp_dealloc */ + (destructor)mb_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ @@ -227,15 +253,25 @@ PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ &mb_as_buffer, /* tp_as_buffer */ - MINIBUF_TPFLAGS, /* tp_flags */ + (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | + MINIBUF_TPFLAGS), /* tp_flags */ + 0, /* tp_doc */ + (traverseproc)mb_traverse, /* tp_traverse */ + (inquiry)mb_clear, /* tp_clear */ + 0, /* tp_richcompare */ + offsetof(MiniBufferObj, mb_weakreflist), /* tp_weaklistoffset */ }; -static PyObject *minibuffer_new(char *data, Py_ssize_t size) +static PyObject *minibuffer_new(char *data, Py_ssize_t size, + PyObject *keepalive) { - MiniBufferObj *ob = PyObject_New(MiniBufferObj, &MiniBuffer_Type); + MiniBufferObj *ob = PyObject_GC_New(MiniBufferObj, &MiniBuffer_Type); if (ob != NULL) { ob->mb_data = data; ob->mb_size = size; + ob->mb_keepalive = keepalive; Py_INCREF(keepalive); + ob->mb_weakreflist = NULL; + PyObject_GC_Track(ob); } return (PyObject *)ob; } diff --git a/c/test_c.py b/c/test_c.py --- a/c/test_c.py +++ b/c/test_c.py @@ -1446,10 +1446,16 @@ import _weakref BInt = new_primitive_type("int") BPtr = new_pointer_type(BInt) - _weakref.ref(BInt) - _weakref.ref(newp(BPtr, 42)) - _weakref.ref(cast(BPtr, 42)) - _weakref.ref(cast(BInt, 42)) + rlist = [_weakref.ref(BInt), + _weakref.ref(newp(BPtr, 42)), + _weakref.ref(cast(BPtr, 42)), + _weakref.ref(cast(BInt, 42)), + _weakref.ref(buffer(newp(BPtr, 42))), + ] + for i in range(5): + import gc; gc.collect() + if [r() for r in rlist] == [None for r in rlist]: + break def test_no_inheritance(): BInt = new_primitive_type("int") @@ -2552,3 +2558,15 @@ BCharP = new_pointer_type(new_primitive_type("char")) BCharArray = new_array_type(BCharP, None) py.test.raises(TypeError, newp, BCharArray, u+'foobar') + +def test_buffer_keepalive(): + BCharP = new_pointer_type(new_primitive_type("char")) + BCharArray = new_array_type(BCharP, None) + buflist = [] + for i in range(20): + c = newp(BCharArray, b"hi there %d" % i) + buflist.append(buffer(c)) + import gc; gc.collect() + for i in range(20): + buf = buflist[i] + assert buf[:] == b"hi there %d\x00" % i From noreply at buildbot.pypy.org Thu Feb 7 20:03:52 2013 From: noreply at buildbot.pypy.org (arigo) Date: Thu, 7 Feb 2013 20:03:52 +0100 (CET) Subject: [pypy-commit] cffi default: Document the changes Message-ID: <20130207190352.730A11C02D9@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r1122:a44545d70be4 Date: 2013-01-10 10:03 +0100 http://bitbucket.org/cffi/cffi/changeset/a44545d70be4/ Log: Document the changes diff --git a/doc/source/index.rst b/doc/source/index.rst --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -1097,6 +1097,12 @@ - ``len(buf), buf[index], buf[index] = newchar``: access as a sequence of characters. +.. versionchanged:: 0.5 + The buffer object returned by ``ffi.buffer(cdata)`` keeps alive the + ``cdata`` object: if it was originally an owning cdata, then its + owned memory will not be freed as long as the buffer is alive. + Moreover buffer objects now support weakrefs to them. + ``ffi.typeof("C type" or cdata object)``: return an object of type ```` corresponding to the parsed string, or to the C type of the From noreply at buildbot.pypy.org Thu Feb 7 20:03:53 2013 From: noreply at buildbot.pypy.org (arigo) Date: Thu, 7 Feb 2013 20:03:53 +0100 (CET) Subject: [pypy-commit] cffi default: Python 3 compat Message-ID: <20130207190353.F37301C02D9@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r1123:ba9640dcaa31 Date: 2013-02-07 19:50 +0100 http://bitbucket.org/cffi/cffi/changeset/ba9640dcaa31/ Log: Python 3 compat diff --git a/c/test_c.py b/c/test_c.py --- a/c/test_c.py +++ b/c/test_c.py @@ -20,6 +20,7 @@ return eval('u'+repr(other).replace(r'\\u', r'\u') .replace(r'\\U', r'\U')) u = U() + str2bytes = str else: type_or_class = "class" long = int @@ -30,6 +31,7 @@ bytechr = lambda n: bytes([n]) bitem2bchr = bytechr u = "" + str2bytes = lambda s: bytes(s, "ascii") def size_of_int(): BInt = new_primitive_type("int") @@ -2564,9 +2566,9 @@ BCharArray = new_array_type(BCharP, None) buflist = [] for i in range(20): - c = newp(BCharArray, b"hi there %d" % i) + c = newp(BCharArray, str2bytes("hi there %d" % i)) buflist.append(buffer(c)) import gc; gc.collect() for i in range(20): buf = buflist[i] - assert buf[:] == b"hi there %d\x00" % i + assert buf[:] == str2bytes("hi there %d\x00" % i) From noreply at buildbot.pypy.org Thu Feb 7 20:03:56 2013 From: noreply at buildbot.pypy.org (arigo) Date: Thu, 7 Feb 2013 20:03:56 +0100 (CET) Subject: [pypy-commit] cffi default: Python 3 compat Message-ID: <20130207190356.B05BC1C02D9@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r1124:8fb5a8ea6de2 Date: 2013-02-07 19:58 +0100 http://bitbucket.org/cffi/cffi/changeset/8fb5a8ea6de2/ Log: Python 3 compat diff --git a/cffi/api.py b/cffi/api.py --- a/cffi/api.py +++ b/cffi/api.py @@ -7,6 +7,12 @@ from collections import Callable callable = lambda x: isinstance(x, Callable) +try: + basestring +except NameError: + # Python 3.x + basestring = str + class FFIError(Exception): pass diff --git a/testing/test_zintegration.py b/testing/test_zintegration.py --- a/testing/test_zintegration.py +++ b/testing/test_zintegration.py @@ -9,7 +9,7 @@ subprocess.check_call(['virtualenv', '--distribute', '-p', sys.executable, str(tmpdir)]) - except OSError, e: + except OSError as e: py.test.skip("Cannot execute virtualenv: %s" % (e,)) site_packages = None From noreply at buildbot.pypy.org Thu Feb 7 20:03:58 2013 From: noreply at buildbot.pypy.org (arigo) Date: Thu, 7 Feb 2013 20:03:58 +0100 (CET) Subject: [pypy-commit] cffi default: Python 3 compat Message-ID: <20130207190358.8A6C11C02D9@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r1125:b9ebe6faeed2 Date: 2013-02-07 20:03 +0100 http://bitbucket.org/cffi/cffi/changeset/b9ebe6faeed2/ Log: Python 3 compat diff --git a/testing/test_verify.py b/testing/test_verify.py --- a/testing/test_verify.py +++ b/testing/test_verify.py @@ -1502,6 +1502,6 @@ return f[0] + f[1] + f[2]; } """) - assert lib.sum3chars(('\x10', '\x20', '\x30')) == '\x60' - p = ffi.new("char[]", '\x10\x20\x30') - assert lib.sum3chars(p) == '\x60' + assert lib.sum3chars((b'\x10', b'\x20', b'\x30')) == b'\x60' + p = ffi.new("char[]", b'\x10\x20\x30') + assert lib.sum3chars(p) == b'\x60' From noreply at buildbot.pypy.org Thu Feb 7 20:29:23 2013 From: noreply at buildbot.pypy.org (arigo) Date: Thu, 7 Feb 2013 20:29:23 +0100 (CET) Subject: [pypy-commit] buildbot default: Re-enable nightly builds on FreeBSD (thanks exarkun) Message-ID: <20130207192924.058BA1C02D9@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r737:56a33ea7610b Date: 2013-02-07 20:29 +0100 http://bitbucket.org/pypy/buildbot/changeset/56a33ea7610b/ Log: Re-enable nightly builds on FreeBSD (thanks exarkun) diff --git a/bot2/pypybuildbot/master.py b/bot2/pypybuildbot/master.py --- a/bot2/pypybuildbot/master.py +++ b/bot2/pypybuildbot/master.py @@ -285,7 +285,7 @@ # other platforms MACOSX32, # on minime JITWIN32, # on aurora - #JITFREEBSD64, # on headless + JITFREEBSD64, # on headless JITMACOSX64, # on mvt's machine ], branch=None, hour=0, minute=0), From noreply at buildbot.pypy.org Thu Feb 7 21:06:01 2013 From: noreply at buildbot.pypy.org (arigo) Date: Thu, 7 Feb 2013 21:06:01 +0100 (CET) Subject: [pypy-commit] cffi default: * Win32 fix Message-ID: <20130207200601.CD47C1C0110@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r1126:5a617a8f418b Date: 2013-02-07 21:05 +0100 http://bitbucket.org/cffi/cffi/changeset/5a617a8f418b/ Log: * Win32 fix * Don't depend on the order in which the two calls are made! diff --git a/testing/test_verify.py b/testing/test_verify.py --- a/testing/test_verify.py +++ b/testing/test_verify.py @@ -1455,7 +1455,12 @@ """) lib = ffi.verify(""" #include + #ifdef _WIN32 + #include + #define alloca _alloca + #else #include + #endif static int (*python_callback)(int how_many, int *values); static int c_callback(int how_many, ...) { va_list ap; @@ -1468,7 +1473,9 @@ return python_callback(how_many, values); } int some_c_function(int(*cb)(int,...)) { - return cb(2, 10, 20) + cb(3, 30, 40, 50); + int result = cb(2, 10, 20); + result += cb(3, 30, 40, 50); + return result; } """) seen = [] From noreply at buildbot.pypy.org Thu Feb 7 21:16:54 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Thu, 7 Feb 2013 21:16:54 +0100 (CET) Subject: [pypy-commit] pypy default: support PYTHONUNBUFFERED (thanks wpq for original patch) Message-ID: <20130207201654.1B8A91C02D9@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r60938:79f1404df7ae Date: 2013-02-07 15:15 -0500 http://bitbucket.org/pypy/pypy/changeset/79f1404df7ae/ Log: support PYTHONUNBUFFERED (thanks wpq for original patch) diff --git a/pypy/interpreter/app_main.py b/pypy/interpreter/app_main.py --- a/pypy/interpreter/app_main.py +++ b/pypy/interpreter/app_main.py @@ -436,11 +436,14 @@ # (relevant in case of "reload(sys)") sys.argv[:] = argv - if PYTHON26 and not options["ignore_environment"]: - if os.getenv('PYTHONNOUSERSITE'): - options["no_user_site"] = 1 - if os.getenv('PYTHONDONTWRITEBYTECODE'): - options["dont_write_bytecode"] = 1 + if not options["ignore_environment"]: + if os.getenv('PYTHONUNBUFFERED'): + options["unbuffered"] = 1 + if PYTHON26: + if os.getenv('PYTHONNOUSERSITE'): + options["no_user_site"] = 1 + if os.getenv('PYTHONDONTWRITEBYTECODE'): + options["dont_write_bytecode"] = 1 if (options["interactive"] or (not options["ignore_environment"] and os.getenv('PYTHONINSPECT'))): diff --git a/pypy/interpreter/test2/test_app_main.py b/pypy/interpreter/test2/test_app_main.py --- a/pypy/interpreter/test2/test_app_main.py +++ b/pypy/interpreter/test2/test_app_main.py @@ -712,6 +712,26 @@ assert data == '\x00(STDOUT)\n\x00' # from stdout child_out_err.close() + def test_non_interactive_stdout_unbuffered(self, monkeypatch): + monkeypatch.setenv('PYTHONUNBUFFERED', '1') + path = getscript(r""" + import sys, time + sys.stdout.write('\x00(STDOUT)\n\x00') + time.sleep(1) + sys.stderr.write('\x00[STDERR]\n\x00') + time.sleep(1) + # stdout flushed automatically here + """) + cmdline = '%s -E "%s" %s' % (sys.executable, app_main, path) + print 'POPEN:', cmdline + child_in, child_out_err = os.popen4(cmdline) + data = child_out_err.read(11) + assert data == '\x00(STDOUT)\n\x00' # from stderr + data = child_out_err.read(11) + assert data == '\x00[STDERR]\n\x00' # from stdout + child_out_err.close() + child_in.close() + def test_proper_sys_path(self, tmpdir): data = self.run('-c "import _ctypes"', python_flags='-S') if data.startswith('Traceback'): From noreply at buildbot.pypy.org Thu Feb 7 21:41:01 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Thu, 7 Feb 2013 21:41:01 +0100 (CET) Subject: [pypy-commit] pypy default: fix some app_main tests when time isn't built-in to the host python Message-ID: <20130207204101.3DDE31C0110@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r60939:c113eeb0f55b Date: 2013-02-07 15:40 -0500 http://bitbucket.org/pypy/pypy/changeset/c113eeb0f55b/ Log: fix some app_main tests when time isn't built-in to the host python diff --git a/pypy/interpreter/app_main.py b/pypy/interpreter/app_main.py --- a/pypy/interpreter/app_main.py +++ b/pypy/interpreter/app_main.py @@ -719,7 +719,7 @@ root = dn(dn(dn(thisfile))) return [join(root, 'lib-python', '2.7'), join(root, 'lib_pypy')] - + def pypy_resolvedirof(s): # we ignore the issue of symlinks; for tests, the executable is always # interpreter/app_main.py anyway @@ -759,6 +759,10 @@ del os # make sure that os is not available globally, because this is what # happens in "real life" outside the tests + if 'time' not in sys.builtin_module_names: + # make some tests happy by loading this before we clobber sys.path + import time; del time + # no one should change to which lists sys.argv and sys.path are bound old_argv = sys.argv old_path = sys.path From noreply at buildbot.pypy.org Thu Feb 7 21:53:27 2013 From: noreply at buildbot.pypy.org (arigo) Date: Thu, 7 Feb 2013 21:53:27 +0100 (CET) Subject: [pypy-commit] cffi default: Update the docs. Message-ID: <20130207205327.7C0BC1C0110@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r1127:84304e92b0bf Date: 2013-02-07 21:53 +0100 http://bitbucket.org/cffi/cffi/changeset/84304e92b0bf/ Log: Update the docs. diff --git a/doc/source/index.rst b/doc/source/index.rst --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -90,16 +90,13 @@ Download and Installation: -* http://pypi.python.org/packages/source/c/cffi/cffi-0.4.2.tar.gz +* http://pypi.python.org/packages/source/c/cffi/cffi-0.5.tar.gz - Or grab the most current version by following the instructions below. - - Version 0.4.2 fixes some issues with 0.4 and 0.4.1 on Python 3.x - (and possibly 2.7.3). + - MD5: b163c11f68cad4371e8caeb91d81743f - - MD5: c2a35af157006e966c67d1a725e7875e - - - SHA: adbc997377a3efc0d2841968ae7441e0152c272c + - SHA: d201e114d701eafbf458ebde569acbcc5225eeff * Or get it from the `Bitbucket page`_: ``hg clone https://bitbucket.org/cffi/cffi`` From noreply at buildbot.pypy.org Thu Feb 7 22:32:17 2013 From: noreply at buildbot.pypy.org (mattip) Date: Thu, 7 Feb 2013 22:32:17 +0100 (CET) Subject: [pypy-commit] pypy default: a failing test of byteswap on scalar Message-ID: <20130207213217.8207E1C02D9@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: Changeset: r60940:9cf628e3dfc6 Date: 2013-02-07 17:43 +0200 http://bitbucket.org/pypy/pypy/changeset/9cf628e3dfc6/ Log: a failing test of byteswap on scalar diff --git a/pypy/module/micronumpy/test/test_numarray.py b/pypy/module/micronumpy/test/test_numarray.py --- a/pypy/module/micronumpy/test/test_numarray.py +++ b/pypy/module/micronumpy/test/test_numarray.py @@ -1700,6 +1700,12 @@ n = a.dtype.itemsize assert s1[n-1] == s2[0] + a = array(0., dtype='longfloat') + s1 = map(ord, a.tostring()) + s2 = map(ord, a.byteswap().tostring()) + n = a.dtype.itemsize + assert s1[n-1] == s2[0] + def test_clip(self): from _numpypy import array a = array([1, 2, 17, -3, 12]) From noreply at buildbot.pypy.org Thu Feb 7 22:32:19 2013 From: noreply at buildbot.pypy.org (mattip) Date: Thu, 7 Feb 2013 22:32:19 +0100 (CET) Subject: [pypy-commit] pypy default: a failing test of tostring on scalar Message-ID: <20130207213219.4F25B1C02D9@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: Changeset: r60941:9fb80985bb20 Date: 2013-02-07 17:50 +0200 http://bitbucket.org/pypy/pypy/changeset/9fb80985bb20/ Log: a failing test of tostring on scalar diff --git a/pypy/module/micronumpy/test/test_numarray.py b/pypy/module/micronumpy/test/test_numarray.py --- a/pypy/module/micronumpy/test/test_numarray.py +++ b/pypy/module/micronumpy/test/test_numarray.py @@ -2374,6 +2374,7 @@ assert array([1, 2, 3], 'i2')[::2].tostring() == '\x01\x00\x03\x00' assert array([1, 2, 3], 'i2')[::2].tostring() == '\x00\x01\x00\x03' + assert array(0, dtype='i2').tostring() == '\x00\x00' def test_argsort_dtypes(self): from _numpypy import array, arange From noreply at buildbot.pypy.org Thu Feb 7 22:32:20 2013 From: noreply at buildbot.pypy.org (mattip) Date: Thu, 7 Feb 2013 22:32:20 +0100 (CET) Subject: [pypy-commit] pypy default: flesh out ScalarIterator so no 'if arr.is_scalar()' everywhere Message-ID: <20130207213220.E829D1C02D9@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: Changeset: r60942:a0980f72c3fb Date: 2013-02-07 18:26 +0200 http://bitbucket.org/pypy/pypy/changeset/a0980f72c3fb/ Log: flesh out ScalarIterator so no 'if arr.is_scalar()' everywhere diff --git a/pypy/module/micronumpy/arrayimpl/scalar.py b/pypy/module/micronumpy/arrayimpl/scalar.py --- a/pypy/module/micronumpy/arrayimpl/scalar.py +++ b/pypy/module/micronumpy/arrayimpl/scalar.py @@ -7,18 +7,19 @@ class ScalarIterator(base.BaseArrayIterator): def __init__(self, v): self.v = v + self.called_once = False def next(self): - pass + self.called_once = True def getitem(self): - return self.v + return self.v.get_scalar_value() def setitem(self, v): - raise Exception("Don't call setitem on scalar iterators") + self.v.set_scalar_value(v) def done(self): - raise Exception("should not call done on scalar") + return self.called_once def reset(self): pass @@ -38,7 +39,7 @@ return [] def create_iter(self, shape=None): - return ScalarIterator(self.value) + return ScalarIterator(self) def get_scalar_value(self): return self.value From noreply at buildbot.pypy.org Thu Feb 7 22:32:23 2013 From: noreply at buildbot.pypy.org (mattip) Date: Thu, 7 Feb 2013 22:32:23 +0100 (CET) Subject: [pypy-commit] pypy default: allow from_shape to create scalar arrays Message-ID: <20130207213223.42C951C02D9@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: Changeset: r60943:f8b66eb99972 Date: 2013-02-07 18:48 +0200 http://bitbucket.org/pypy/pypy/changeset/f8b66eb99972/ Log: allow from_shape to create scalar arrays diff --git a/pypy/module/micronumpy/base.py b/pypy/module/micronumpy/base.py --- a/pypy/module/micronumpy/base.py +++ b/pypy/module/micronumpy/base.py @@ -21,11 +21,13 @@ @staticmethod def from_shape(shape, dtype, order='C'): - from pypy.module.micronumpy.arrayimpl import concrete - - assert shape - strides, backstrides = calc_strides(shape, dtype, order) - impl = concrete.ConcreteArray(shape, dtype, order, strides, + from pypy.module.micronumpy.arrayimpl import concrete, scalar + + if not shape: + impl = scalar.Scalar(dtype) + else: + strides, backstrides = calc_strides(shape, dtype, order) + impl = concrete.ConcreteArray(shape, dtype, order, strides, backstrides) return W_NDimArray(impl) From noreply at buildbot.pypy.org Thu Feb 7 22:32:24 2013 From: noreply at buildbot.pypy.org (mattip) Date: Thu, 7 Feb 2013 22:32:24 +0100 (CET) Subject: [pypy-commit] pypy default: merge heads, fix numpypy scalar crashes Message-ID: <20130207213224.DA23D1C02D9@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: Changeset: r60944:e89396c9a1d0 Date: 2013-02-07 23:23 +0200 http://bitbucket.org/pypy/pypy/changeset/e89396c9a1d0/ Log: merge heads, fix numpypy scalar crashes diff --git a/pypy/interpreter/app_main.py b/pypy/interpreter/app_main.py --- a/pypy/interpreter/app_main.py +++ b/pypy/interpreter/app_main.py @@ -436,11 +436,14 @@ # (relevant in case of "reload(sys)") sys.argv[:] = argv - if PYTHON26 and not options["ignore_environment"]: - if os.getenv('PYTHONNOUSERSITE'): - options["no_user_site"] = 1 - if os.getenv('PYTHONDONTWRITEBYTECODE'): - options["dont_write_bytecode"] = 1 + if not options["ignore_environment"]: + if os.getenv('PYTHONUNBUFFERED'): + options["unbuffered"] = 1 + if PYTHON26: + if os.getenv('PYTHONNOUSERSITE'): + options["no_user_site"] = 1 + if os.getenv('PYTHONDONTWRITEBYTECODE'): + options["dont_write_bytecode"] = 1 if (options["interactive"] or (not options["ignore_environment"] and os.getenv('PYTHONINSPECT'))): @@ -716,7 +719,7 @@ root = dn(dn(dn(thisfile))) return [join(root, 'lib-python', '2.7'), join(root, 'lib_pypy')] - + def pypy_resolvedirof(s): # we ignore the issue of symlinks; for tests, the executable is always # interpreter/app_main.py anyway @@ -756,6 +759,10 @@ del os # make sure that os is not available globally, because this is what # happens in "real life" outside the tests + if 'time' not in sys.builtin_module_names: + # make some tests happy by loading this before we clobber sys.path + import time; del time + # no one should change to which lists sys.argv and sys.path are bound old_argv = sys.argv old_path = sys.path diff --git a/pypy/interpreter/test2/test_app_main.py b/pypy/interpreter/test2/test_app_main.py --- a/pypy/interpreter/test2/test_app_main.py +++ b/pypy/interpreter/test2/test_app_main.py @@ -712,6 +712,26 @@ assert data == '\x00(STDOUT)\n\x00' # from stdout child_out_err.close() + def test_non_interactive_stdout_unbuffered(self, monkeypatch): + monkeypatch.setenv('PYTHONUNBUFFERED', '1') + path = getscript(r""" + import sys, time + sys.stdout.write('\x00(STDOUT)\n\x00') + time.sleep(1) + sys.stderr.write('\x00[STDERR]\n\x00') + time.sleep(1) + # stdout flushed automatically here + """) + cmdline = '%s -E "%s" %s' % (sys.executable, app_main, path) + print 'POPEN:', cmdline + child_in, child_out_err = os.popen4(cmdline) + data = child_out_err.read(11) + assert data == '\x00(STDOUT)\n\x00' # from stderr + data = child_out_err.read(11) + assert data == '\x00[STDERR]\n\x00' # from stdout + child_out_err.close() + child_in.close() + def test_proper_sys_path(self, tmpdir): data = self.run('-c "import _ctypes"', python_flags='-S') if data.startswith('Traceback'): From noreply at buildbot.pypy.org Thu Feb 7 22:40:12 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Thu, 7 Feb 2013 22:40:12 +0100 (CET) Subject: [pypy-commit] pypy default: have the version-script actually limit symbols exported on posix Message-ID: <20130207214012.B819E1C02D9@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r60945:65047c26392c Date: 2013-02-07 16:38 -0500 http://bitbucket.org/pypy/pypy/changeset/65047c26392c/ Log: have the version-script actually limit symbols exported on posix diff --git a/rpython/translator/platform/posix.py b/rpython/translator/platform/posix.py --- a/rpython/translator/platform/posix.py +++ b/rpython/translator/platform/posix.py @@ -49,10 +49,10 @@ response_file = self._make_response_file("dynamic-symbols-") f = response_file.open("w") - f.write("{\n") + f.write("{\n\tglobal:\n") for sym in eci.export_symbols: - f.write("%s;\n" % (sym,)) - f.write("};") + f.write("\t\t%s;\n" % (sym,)) + f.write("\tlocal:\n\t\t*;\n};") f.close() if relto: From noreply at buildbot.pypy.org Thu Feb 7 22:40:14 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Thu, 7 Feb 2013 22:40:14 +0100 (CET) Subject: [pypy-commit] pypy default: fix a missing export_symbol in _multibytecodec module Message-ID: <20130207214014.6223D1C02D9@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r60946:9429071666e6 Date: 2013-02-07 16:39 -0500 http://bitbucket.org/pypy/pypy/changeset/9429071666e6/ Log: fix a missing export_symbol in _multibytecodec module diff --git a/pypy/module/_multibytecodec/c_codecs.py b/pypy/module/_multibytecodec/c_codecs.py --- a/pypy/module/_multibytecodec/c_codecs.py +++ b/pypy/module/_multibytecodec/c_codecs.py @@ -62,7 +62,7 @@ "pypy_cjk_enc_init", "pypy_cjk_enc_free", "pypy_cjk_enc_chunk", "pypy_cjk_enc_reset", "pypy_cjk_enc_outbuf", "pypy_cjk_enc_outlen", "pypy_cjk_enc_inbuf_remaining", "pypy_cjk_enc_inbuf_consumed", - "pypy_cjk_enc_replace_on_error", + "pypy_cjk_enc_replace_on_error", "pypy_cjk_enc_getcodec", ] + ["pypy_cjkcodec_%s" % codec for codec in codecs], ) From noreply at buildbot.pypy.org Thu Feb 7 23:06:12 2013 From: noreply at buildbot.pypy.org (fijal) Date: Thu, 7 Feb 2013 23:06:12 +0100 (CET) Subject: [pypy-commit] buildbot default: add freebsd9 slave Message-ID: <20130207220612.F1BAA1C02D9@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r738:53ce58597b8c Date: 2013-02-08 00:05 +0200 http://bitbucket.org/pypy/buildbot/changeset/53ce58597b8c/ Log: add freebsd9 slave diff --git a/bot2/pypybuildbot/master.py b/bot2/pypybuildbot/master.py --- a/bot2/pypybuildbot/master.py +++ b/bot2/pypybuildbot/master.py @@ -252,6 +252,7 @@ JITWIN32 = "pypy-c-jit-win-x86-32" JITWIN64 = "pypy-c-jit-win-x86-64" JITFREEBSD64 = 'pypy-c-jit-freebsd-7-x86-64' +JITFREEBSD964 = 'pypy-c-jit-freebsd-9-x86-64' JITINDIANA32 = "pypy-c-jit-indiana-x86-32" JITBACKENDONLYLINUXARMEL = "jitbackendonly-own-linux-armel" @@ -286,6 +287,7 @@ MACOSX32, # on minime JITWIN32, # on aurora JITFREEBSD64, # on headless + JITFREEBSD964, # on exarkun's freebsd JITMACOSX64, # on mvt's machine ], branch=None, hour=0, minute=0), @@ -487,6 +489,12 @@ 'factory' : pypyJITTranslatedTestFactoryFreeBSD, "category": 'freebsd64' }, + {"name" : JITFREEBSD964, + "slavenames": ['hybridlogic'], + 'builddir' : JITFREEBSD964, + 'factory' : pypyJITTranslatedTestFactoryFreeBSD, + "category": 'freebsd64' + }, # PPC {"name": LINUXPPC64, "slavenames": ["gcc1"], From noreply at buildbot.pypy.org Thu Feb 7 23:22:18 2013 From: noreply at buildbot.pypy.org (arigo) Date: Thu, 7 Feb 2013 23:22:18 +0100 (CET) Subject: [pypy-commit] cffi default: Fix when running on pypy without cpyext. Message-ID: <20130207222218.C304F1C0110@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r1128:a8bdd46c8afb Date: 2013-02-07 23:22 +0100 http://bitbucket.org/cffi/cffi/changeset/a8bdd46c8afb/ Log: Fix when running on pypy without cpyext. diff --git a/cffi/verifier.py b/cffi/verifier.py --- a/cffi/verifier.py +++ b/cffi/verifier.py @@ -223,7 +223,11 @@ for suffix, mode, type in imp.get_suffixes(): if type == imp.C_EXTENSION: return suffix - raise ffiplatform.VerificationError("no C_EXTENSION available") + # bah, no C_EXTENSION available. Occurs on pypy without cpyext + if sys.platform == 'win32': + return ".pyd" + else: + return ".so" def _ensure_dir(filename): try: From noreply at buildbot.pypy.org Fri Feb 8 01:56:59 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Fri, 8 Feb 2013 01:56:59 +0100 (CET) Subject: [pypy-commit] pypy default: fix this test on windows Message-ID: <20130208005659.8615B1C1581@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r60947:100529d2dbf1 Date: 2013-02-07 19:56 -0500 http://bitbucket.org/pypy/pypy/changeset/100529d2dbf1/ Log: fix this test on windows diff --git a/pypy/module/posix/test/test_posix2.py b/pypy/module/posix/test/test_posix2.py --- a/pypy/module/posix/test/test_posix2.py +++ b/pypy/module/posix/test/test_posix2.py @@ -514,12 +514,14 @@ assert res == '1\n' def test_popen_child_fds(self): - os = self.posix - from os.path import join - with open(join(self.pdir, 'file1'), 'r') as fd: - with os.popen('%s -c "import os; print os.read(%d, 10)"' % (self.python, fd.fileno())) as stream: + import os + with open(os.path.join(self.pdir, 'file1'), 'r') as fd: + with self.posix.popen('%s -c "import os; print os.read(%d, 10)" 2>&1' % (self.python, fd.fileno())) as stream: res = stream.read() - assert res == 'test1\n' + if os.name == 'nt': + assert '\nOSError: [Errno 9]' in res + else: + assert res == 'test1\n' if hasattr(__import__(os.name), '_getfullpathname'): def test__getfullpathname(self): From noreply at buildbot.pypy.org Fri Feb 8 02:18:21 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Fri, 8 Feb 2013 02:18:21 +0100 (CET) Subject: [pypy-commit] pypy default: add a test for 65047c2 Message-ID: <20130208011821.AB4161C02D9@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r60948:abc13a6dcad1 Date: 2013-02-07 20:18 -0500 http://bitbucket.org/pypy/pypy/changeset/abc13a6dcad1/ Log: add a test for 65047c2 diff --git a/rpython/translator/tool/test/test_cbuild.py b/rpython/translator/tool/test/test_cbuild.py --- a/rpython/translator/tool/test/test_cbuild.py +++ b/rpython/translator/tool/test/test_cbuild.py @@ -77,6 +77,10 @@ int get() { return 42; + } + int shouldnt_export() + { + return 43; }'''], export_symbols = ['get'] ) @@ -87,6 +91,7 @@ except ImportError: py.test.skip("Need ctypes for that test") assert ctypes.CDLL(neweci.libraries[0]).get() == 42 + assert not hasattr(ctypes.CDLL(neweci.libraries[0]), 'shouldnt_export') assert not neweci.separate_module_sources assert not neweci.separate_module_files From noreply at buildbot.pypy.org Fri Feb 8 02:43:46 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Fri, 8 Feb 2013 02:43:46 +0100 (CET) Subject: [pypy-commit] pypy default: fix some tests for bsd Message-ID: <20130208014346.26C1A1C0110@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r60949:a06da7965b64 Date: 2013-02-07 20:43 -0500 http://bitbucket.org/pypy/pypy/changeset/a06da7965b64/ Log: fix some tests for bsd diff --git a/pypy/module/__pypy__/__init__.py b/pypy/module/__pypy__/__init__.py --- a/pypy/module/__pypy__/__init__.py +++ b/pypy/module/__pypy__/__init__.py @@ -14,7 +14,7 @@ class TimeModule(MixedModule): appleveldefs = {} interpleveldefs = {} - if sys.platform.startswith("linux"): + if sys.platform.startswith("linux") or 'bsd' in sys.platform: from pypy.module.__pypy__ import interp_time interpleveldefs["clock_gettime"] = "interp_time.clock_gettime" interpleveldefs["clock_getres"] = "interp_time.clock_getres" diff --git a/pypy/module/rctime/test/test_rctime.py b/pypy/module/rctime/test/test_rctime.py --- a/pypy/module/rctime/test/test_rctime.py +++ b/pypy/module/rctime/test/test_rctime.py @@ -237,7 +237,7 @@ # input to [w]strftime is not kosher. if os.name == 'nt': raises(ValueError, rctime.strftime, '%f') - elif sys.platform == 'darwin': + elif sys.platform == 'darwin' or 'bsd' in sys.platform: # darwin strips % of unknown format codes # http://bugs.python.org/issue9811 assert rctime.strftime('%f') == 'f' diff --git a/pypy/module/signal/test/test_signal.py b/pypy/module/signal/test/test_signal.py --- a/pypy/module/signal/test/test_signal.py +++ b/pypy/module/signal/test/test_signal.py @@ -157,7 +157,7 @@ if sys.platform == 'win32': raises(ValueError, signal, 42, lambda *args: None) raises(ValueError, signal, 7, lambda *args: None) - elif sys.platform == 'darwin': + elif sys.platform == 'darwin' or 'bsd' in sys.platform: raises(ValueError, signal, 42, lambda *args: None) else: signal(42, lambda *args: None) From noreply at buildbot.pypy.org Fri Feb 8 04:52:57 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Fri, 8 Feb 2013 04:52:57 +0100 (CET) Subject: [pypy-commit] pypy default: a pyrepl + threads fix from amaury (fixes issue 1349) Message-ID: <20130208035258.0E7AE1C0110@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r60950:c17aa572ce36 Date: 2013-02-07 22:50 -0500 http://bitbucket.org/pypy/pypy/changeset/c17aa572ce36/ Log: a pyrepl + threads fix from amaury (fixes issue 1349) diff --git a/lib_pypy/pyrepl/unix_console.py b/lib_pypy/pyrepl/unix_console.py --- a/lib_pypy/pyrepl/unix_console.py +++ b/lib_pypy/pyrepl/unix_console.py @@ -398,6 +398,7 @@ if hasattr(self, 'old_sigwinch'): signal.signal(signal.SIGWINCH, self.old_sigwinch) + del self.old_sigwinch def __sigwinch(self, signum, frame): self.height, self.width = self.getheightwidth() From noreply at buildbot.pypy.org Fri Feb 8 05:03:49 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Fri, 8 Feb 2013 05:03:49 +0100 (CET) Subject: [pypy-commit] pypy py3k: forgot the space arg Message-ID: <20130208040349.137041C02D9@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r60951:c5421524b416 Date: 2013-02-07 20:03 -0800 http://bitbucket.org/pypy/pypy/changeset/c5421524b416/ Log: forgot the space arg diff --git a/pypy/module/_io/interp_textio.py b/pypy/module/_io/interp_textio.py --- a/pypy/module/_io/interp_textio.py +++ b/pypy/module/_io/interp_textio.py @@ -809,7 +809,8 @@ self._check_closed(space) if not self.seekable: - self._unsupportedoperation("underlying stream is not seekable") + self._unsupportedoperation(space, + "underlying stream is not seekable") if whence == 1: # seek relative to current position @@ -887,7 +888,8 @@ self._check_closed(space) if not self.seekable: - self._unsupportedoperation("underlying stream is not seekable") + self._unsupportedoperation(space, + "underlying stream is not seekable") if not self.telling: raise OperationError(space.w_IOError, space.wrap( From noreply at buildbot.pypy.org Fri Feb 8 06:34:18 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Fri, 8 Feb 2013 06:34:18 +0100 (CET) Subject: [pypy-commit] pypy py3k: fix translation Message-ID: <20130208053418.6A3FE1C104D@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r60952:338a5d152817 Date: 2013-02-07 21:33 -0800 http://bitbucket.org/pypy/pypy/changeset/338a5d152817/ Log: fix translation diff --git a/pypy/module/_io/interp_fileio.py b/pypy/module/_io/interp_fileio.py --- a/pypy/module/_io/interp_fileio.py +++ b/pypy/module/_io/interp_fileio.py @@ -250,7 +250,7 @@ if self.fd >= 0 and self.closefd: try: r = space.unicode_w(space.repr(w_source)) - space.warn("unclosed file %s" % r, space.w_ResourceWarning) + space.warn(u"unclosed file %s" % r, space.w_ResourceWarning) except OperationError as e: # Spurious errors can appear at shutdown if e.match(space, space.w_Warning): From noreply at buildbot.pypy.org Fri Feb 8 08:41:38 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Fri, 8 Feb 2013 08:41:38 +0100 (CET) Subject: [pypy-commit] pypy default: apply OrderedDict cleanups from raymondh that were applied upstream Message-ID: <20130208074138.436D81C0110@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r60953:ec577d173019 Date: 2013-02-08 02:37 -0500 http://bitbucket.org/pypy/pypy/changeset/ec577d173019/ Log: apply OrderedDict cleanups from raymondh that were applied upstream diff --git a/lib-python/2.7/collections.py b/lib-python/2.7/collections.py --- a/lib-python/2.7/collections.py +++ b/lib-python/2.7/collections.py @@ -6,11 +6,12 @@ __all__ += _abcoll.__all__ from _collections import deque, defaultdict -from operator import itemgetter as _itemgetter +from operator import itemgetter as _itemgetter, eq as _eq from keyword import iskeyword as _iskeyword import sys as _sys import heapq as _heapq from itertools import repeat as _repeat, chain as _chain, starmap as _starmap +from itertools import imap as _imap try: from thread import get_ident as _get_ident @@ -50,49 +51,45 @@ self.__map = {} self.__update(*args, **kwds) - def __setitem__(self, key, value, PREV=0, NEXT=1, dict_setitem=dict.__setitem__): + def __setitem__(self, key, value, dict_setitem=dict.__setitem__): 'od.__setitem__(i, y) <==> od[i]=y' # Setting a new item creates a new link at the end of the linked list, # and the inherited dictionary is updated with the new key/value pair. if key not in self: root = self.__root - last = root[PREV] - last[NEXT] = root[PREV] = self.__map[key] = [last, root, key] - dict_setitem(self, key, value) + last = root[0] + last[1] = root[0] = self.__map[key] = [last, root, key] + return dict_setitem(self, key, value) - def __delitem__(self, key, PREV=0, NEXT=1, dict_delitem=dict.__delitem__): + def __delitem__(self, key, dict_delitem=dict.__delitem__): 'od.__delitem__(y) <==> del od[y]' # Deleting an existing item uses self.__map to find the link which gets # removed by updating the links in the predecessor and successor nodes. dict_delitem(self, key) link_prev, link_next, key = self.__map.pop(key) - link_prev[NEXT] = link_next - link_next[PREV] = link_prev + link_prev[1] = link_next # update link_prev[NEXT] + link_next[0] = link_prev # update link_next[PREV] def __iter__(self): 'od.__iter__() <==> iter(od)' # Traverse the linked list in order. - NEXT, KEY = 1, 2 root = self.__root - curr = root[NEXT] + curr = root[1] # start at the first node while curr is not root: - yield curr[KEY] - curr = curr[NEXT] + yield curr[2] # yield the curr[KEY] + curr = curr[1] # move to next node def __reversed__(self): 'od.__reversed__() <==> reversed(od)' # Traverse the linked list in reverse order. - PREV, KEY = 0, 2 root = self.__root - curr = root[PREV] + curr = root[0] # start at the last node while curr is not root: - yield curr[KEY] - curr = curr[PREV] + yield curr[2] # yield the curr[KEY] + curr = curr[0] # move to previous node def clear(self): 'od.clear() -> None. Remove all items from od.' - for node in self.__map.itervalues(): - del node[:] root = self.__root root[:] = [root, root, None] self.__map.clear() @@ -208,7 +205,7 @@ ''' if isinstance(other, OrderedDict): - return len(self)==len(other) and self.items() == other.items() + return dict.__eq__(self, other) and all(_imap(_eq, self, other)) return dict.__eq__(self, other) def __ne__(self, other): From noreply at buildbot.pypy.org Fri Feb 8 09:05:47 2013 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 8 Feb 2013 09:05:47 +0100 (CET) Subject: [pypy-commit] pypy default: Test and fix Message-ID: <20130208080547.96CFB1C0110@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r60954:35ab7f14c707 Date: 2013-02-08 09:03 +0100 http://bitbucket.org/pypy/pypy/changeset/35ab7f14c707/ Log: Test and fix diff --git a/pypy/module/zipimport/interp_zipimport.py b/pypy/module/zipimport/interp_zipimport.py --- a/pypy/module/zipimport/interp_zipimport.py +++ b/pypy/module/zipimport/interp_zipimport.py @@ -172,24 +172,24 @@ return mtime def check_newer_pyfile(self, space, filename, timestamp): + # check if the timestamp stored in the .pyc is matching + # the actual timestamp of the .py file, if any mtime = self._parse_mtime(space, filename) if mtime == 0: return False - return mtime > timestamp - - def check_compatible_mtime(self, space, filename, timestamp): - mtime = self._parse_mtime(space, filename) - if mtime == 0 or mtime != (timestamp & (~1)): - return False - return True + # Lenient date/time comparison function. The precision of the mtime + # in the archive is lower than the mtime stored in a .pyc: we + # must allow a difference of at most one second. + d = mtime - timestamp + if d < 0: + d = -d + return d > 1 # more than one second => different def can_use_pyc(self, space, filename, magic, timestamp): if magic != importing.get_pyc_magic(space): return False if self.check_newer_pyfile(space, filename[:-1], timestamp): return False - if not self.check_compatible_mtime(space, filename, timestamp): - return False return True def import_pyc_file(self, space, modname, filename, buf, pkgpath): diff --git a/pypy/module/zipimport/test/test_zipimport.py b/pypy/module/zipimport/test/test_zipimport.py --- a/pypy/module/zipimport/test/test_zipimport.py +++ b/pypy/module/zipimport/test/test_zipimport.py @@ -95,6 +95,9 @@ """) self.w_modules = [] + def w_now_in_the_future(self, delta): + self.now += delta + def w_writefile(self, filename, data): import sys import time @@ -264,10 +267,12 @@ import os import zipimport data = "saddsadsa" + pyc_data = self.test_pyc + self.now_in_the_future(+5) # write the zipfile 5 secs after the .pyc self.writefile("xxx", data) self.writefile("xx/__init__.py", "5") self.writefile("yy.py", "3") - self.writefile('uu.pyc', self.test_pyc) + self.writefile('uu.pyc', pyc_data) z = zipimport.zipimporter(self.zipfile) assert z.get_data(self.zipfile + os.sep + "xxx") == data assert z.is_package("xx") @@ -277,6 +282,7 @@ raises(ImportError, "z.get_source('zz')") #assert z.get_code('yy') == py.code.Source('3').compile() #assert z.get_code('uu') == self.co + assert z.get_code('uu') assert z.get_code('xx') assert z.get_source('xx') == "5" assert z.archive == self.zipfile From noreply at buildbot.pypy.org Fri Feb 8 09:05:48 2013 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 8 Feb 2013 09:05:48 +0100 (CET) Subject: [pypy-commit] pypy default: merge heads Message-ID: <20130208080548.EFB991C0110@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r60955:81cb7e69c819 Date: 2013-02-08 09:05 +0100 http://bitbucket.org/pypy/pypy/changeset/81cb7e69c819/ Log: merge heads diff --git a/pypy/module/zipimport/interp_zipimport.py b/pypy/module/zipimport/interp_zipimport.py --- a/pypy/module/zipimport/interp_zipimport.py +++ b/pypy/module/zipimport/interp_zipimport.py @@ -172,24 +172,24 @@ return mtime def check_newer_pyfile(self, space, filename, timestamp): + # check if the timestamp stored in the .pyc is matching + # the actual timestamp of the .py file, if any mtime = self._parse_mtime(space, filename) if mtime == 0: return False - return mtime > timestamp - - def check_compatible_mtime(self, space, filename, timestamp): - mtime = self._parse_mtime(space, filename) - if mtime == 0 or mtime != (timestamp & (~1)): - return False - return True + # Lenient date/time comparison function. The precision of the mtime + # in the archive is lower than the mtime stored in a .pyc: we + # must allow a difference of at most one second. + d = mtime - timestamp + if d < 0: + d = -d + return d > 1 # more than one second => different def can_use_pyc(self, space, filename, magic, timestamp): if magic != importing.get_pyc_magic(space): return False if self.check_newer_pyfile(space, filename[:-1], timestamp): return False - if not self.check_compatible_mtime(space, filename, timestamp): - return False return True def import_pyc_file(self, space, modname, filename, buf, pkgpath): diff --git a/pypy/module/zipimport/test/test_zipimport.py b/pypy/module/zipimport/test/test_zipimport.py --- a/pypy/module/zipimport/test/test_zipimport.py +++ b/pypy/module/zipimport/test/test_zipimport.py @@ -95,6 +95,9 @@ """) self.w_modules = [] + def w_now_in_the_future(self, delta): + self.now += delta + def w_writefile(self, filename, data): import sys import time @@ -264,10 +267,12 @@ import os import zipimport data = "saddsadsa" + pyc_data = self.test_pyc + self.now_in_the_future(+5) # write the zipfile 5 secs after the .pyc self.writefile("xxx", data) self.writefile("xx/__init__.py", "5") self.writefile("yy.py", "3") - self.writefile('uu.pyc', self.test_pyc) + self.writefile('uu.pyc', pyc_data) z = zipimport.zipimporter(self.zipfile) assert z.get_data(self.zipfile + os.sep + "xxx") == data assert z.is_package("xx") @@ -277,6 +282,7 @@ raises(ImportError, "z.get_source('zz')") #assert z.get_code('yy') == py.code.Source('3').compile() #assert z.get_code('uu') == self.co + assert z.get_code('uu') assert z.get_code('xx') assert z.get_source('xx') == "5" assert z.archive == self.zipfile From noreply at buildbot.pypy.org Fri Feb 8 09:11:41 2013 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 8 Feb 2013 09:11:41 +0100 (CET) Subject: [pypy-commit] pypy default: Port cffi 00f0e57fce9a. Message-ID: <20130208081141.ECB361C0110@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r60956:19b642a3d0a9 Date: 2013-02-08 09:11 +0100 http://bitbucket.org/pypy/pypy/changeset/19b642a3d0a9/ Log: Port cffi 00f0e57fce9a. diff --git a/pypy/module/_cffi_backend/cbuffer.py b/pypy/module/_cffi_backend/cbuffer.py --- a/pypy/module/_cffi_backend/cbuffer.py +++ b/pypy/module/_cffi_backend/cbuffer.py @@ -2,7 +2,7 @@ from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.buffer import RWBuffer from pypy.interpreter.gateway import unwrap_spec, interp2app -from pypy.interpreter.typedef import TypeDef +from pypy.interpreter.typedef import TypeDef, make_weakref_descr from rpython.rtyper.lltypesystem import rffi from pypy.module._cffi_backend import cdataobj, ctypeptr, ctypearray @@ -41,8 +41,9 @@ # a different subclass of Wrappable for the MiniBuffer, because we # want a slightly different (simplified) API at the level of Python. - def __init__(self, buffer): + def __init__(self, buffer, keepalive=None): self.buffer = buffer + self.keepalive = keepalive def descr_len(self, space): return self.buffer.descr_len(space) @@ -65,6 +66,7 @@ __getitem__ = interp2app(MiniBuffer.descr_getitem), __setitem__ = interp2app(MiniBuffer.descr_setitem), __buffer__ = interp2app(MiniBuffer.descr__buffer__), + __weakref__ = make_weakref_descr(MiniBuffer), ) MiniBuffer.typedef.acceptable_as_base_class = False @@ -86,4 +88,4 @@ raise operationerrfmt(space.w_TypeError, "don't know the size pointed to by '%s'", ctype.name) - return space.wrap(MiniBuffer(LLBuffer(cdata._cdata, size))) + return space.wrap(MiniBuffer(LLBuffer(cdata._cdata, size), cdata)) diff --git a/pypy/module/_cffi_backend/test/_backend_test_c.py b/pypy/module/_cffi_backend/test/_backend_test_c.py --- a/pypy/module/_cffi_backend/test/_backend_test_c.py +++ b/pypy/module/_cffi_backend/test/_backend_test_c.py @@ -12,6 +12,7 @@ return eval('u'+repr(other).replace(r'\\u', r'\u') .replace(r'\\U', r'\U')) u = U() + str2bytes = str else: type_or_class = "class" long = int @@ -22,6 +23,7 @@ bytechr = lambda n: bytes([n]) bitem2bchr = bytechr u = "" + str2bytes = lambda s: bytes(s, "ascii") def size_of_int(): BInt = new_primitive_type("int") @@ -1438,10 +1440,16 @@ import _weakref BInt = new_primitive_type("int") BPtr = new_pointer_type(BInt) - _weakref.ref(BInt) - _weakref.ref(newp(BPtr, 42)) - _weakref.ref(cast(BPtr, 42)) - _weakref.ref(cast(BInt, 42)) + rlist = [_weakref.ref(BInt), + _weakref.ref(newp(BPtr, 42)), + _weakref.ref(cast(BPtr, 42)), + _weakref.ref(cast(BInt, 42)), + _weakref.ref(buffer(newp(BPtr, 42))), + ] + for i in range(5): + import gc; gc.collect() + if [r() for r in rlist] == [None for r in rlist]: + break def test_no_inheritance(): BInt = new_primitive_type("int") @@ -2544,3 +2552,15 @@ BCharP = new_pointer_type(new_primitive_type("char")) BCharArray = new_array_type(BCharP, None) py.test.raises(TypeError, newp, BCharArray, u+'foobar') + +def test_buffer_keepalive(): + BCharP = new_pointer_type(new_primitive_type("char")) + BCharArray = new_array_type(BCharP, None) + buflist = [] + for i in range(20): + c = newp(BCharArray, str2bytes("hi there %d" % i)) + buflist.append(buffer(c)) + import gc; gc.collect() + for i in range(20): + buf = buflist[i] + assert buf[:] == str2bytes("hi there %d\x00" % i) From noreply at buildbot.pypy.org Fri Feb 8 09:25:48 2013 From: noreply at buildbot.pypy.org (RonnyPfannschmidt) Date: Fri, 8 Feb 2013 09:25:48 +0100 (CET) Subject: [pypy-commit] pypy pytest: merge from default Message-ID: <20130208082548.7FB981C0110@cobra.cs.uni-duesseldorf.de> Author: Ronny Pfannschmidt Branch: pytest Changeset: r60957:4dc8d51415cf Date: 2013-02-08 09:25 +0100 http://bitbucket.org/pypy/pypy/changeset/4dc8d51415cf/ Log: merge from default diff too long, truncating to 2000 out of 152879 lines diff --git a/lib-python/2.7/collections.py b/lib-python/2.7/collections.py --- a/lib-python/2.7/collections.py +++ b/lib-python/2.7/collections.py @@ -6,11 +6,12 @@ __all__ += _abcoll.__all__ from _collections import deque, defaultdict -from operator import itemgetter as _itemgetter +from operator import itemgetter as _itemgetter, eq as _eq from keyword import iskeyword as _iskeyword import sys as _sys import heapq as _heapq from itertools import repeat as _repeat, chain as _chain, starmap as _starmap +from itertools import imap as _imap try: from thread import get_ident as _get_ident @@ -50,49 +51,45 @@ self.__map = {} self.__update(*args, **kwds) - def __setitem__(self, key, value, PREV=0, NEXT=1, dict_setitem=dict.__setitem__): + def __setitem__(self, key, value, dict_setitem=dict.__setitem__): 'od.__setitem__(i, y) <==> od[i]=y' # Setting a new item creates a new link at the end of the linked list, # and the inherited dictionary is updated with the new key/value pair. if key not in self: root = self.__root - last = root[PREV] - last[NEXT] = root[PREV] = self.__map[key] = [last, root, key] - dict_setitem(self, key, value) + last = root[0] + last[1] = root[0] = self.__map[key] = [last, root, key] + return dict_setitem(self, key, value) - def __delitem__(self, key, PREV=0, NEXT=1, dict_delitem=dict.__delitem__): + def __delitem__(self, key, dict_delitem=dict.__delitem__): 'od.__delitem__(y) <==> del od[y]' # Deleting an existing item uses self.__map to find the link which gets # removed by updating the links in the predecessor and successor nodes. dict_delitem(self, key) link_prev, link_next, key = self.__map.pop(key) - link_prev[NEXT] = link_next - link_next[PREV] = link_prev + link_prev[1] = link_next # update link_prev[NEXT] + link_next[0] = link_prev # update link_next[PREV] def __iter__(self): 'od.__iter__() <==> iter(od)' # Traverse the linked list in order. - NEXT, KEY = 1, 2 root = self.__root - curr = root[NEXT] + curr = root[1] # start at the first node while curr is not root: - yield curr[KEY] - curr = curr[NEXT] + yield curr[2] # yield the curr[KEY] + curr = curr[1] # move to next node def __reversed__(self): 'od.__reversed__() <==> reversed(od)' # Traverse the linked list in reverse order. - PREV, KEY = 0, 2 root = self.__root - curr = root[PREV] + curr = root[0] # start at the last node while curr is not root: - yield curr[KEY] - curr = curr[PREV] + yield curr[2] # yield the curr[KEY] + curr = curr[0] # move to previous node def clear(self): 'od.clear() -> None. Remove all items from od.' - for node in self.__map.itervalues(): - del node[:] root = self.__root root[:] = [root, root, None] self.__map.clear() @@ -208,7 +205,7 @@ ''' if isinstance(other, OrderedDict): - return len(self)==len(other) and self.items() == other.items() + return dict.__eq__(self, other) and all(_imap(_eq, self, other)) return dict.__eq__(self, other) def __ne__(self, other): @@ -298,7 +295,7 @@ _fields = %(field_names)r \n def __new__(_cls, %(argtxt)s): 'Create new instance of %(typename)s(%(argtxt)s)' - return _tuple.__new__(_cls, (%(argtxt)s)) \n + return tuple.__new__(_cls, (%(argtxt)s)) \n @classmethod def _make(cls, iterable, new=tuple.__new__, len=len): 'Make a new %(typename)s object from a sequence or iterable' @@ -323,14 +320,14 @@ 'Return self as a plain tuple. Used by copy and pickle.' return tuple(self) \n\n''' % locals() for i, name in enumerate(field_names): - template += " %s = _property(_itemgetter(%d), doc='Alias for field number %d')\n" % (name, i, i) + template += " %s = property(lambda self: self[%d], doc='Alias for field number %d')\n" % (name, i, i) if verbose: print template # Execute the template string in a temporary namespace and # support tracing utilities by setting a value for frame.f_globals['__name__'] - namespace = dict(_itemgetter=_itemgetter, __name__='namedtuple_%s' % typename, - OrderedDict=OrderedDict, _property=property, _tuple=tuple) + namespace = {'__name__': 'namedtuple_%s' % typename, + 'OrderedDict': OrderedDict} try: exec template in namespace except SyntaxError, e: diff --git a/lib-python/2.7/inspect.py b/lib-python/2.7/inspect.py --- a/lib-python/2.7/inspect.py +++ b/lib-python/2.7/inspect.py @@ -960,7 +960,7 @@ raise TypeError('%s() takes exactly 0 arguments ' '(%d given)' % (f_name, num_total)) else: - raise TypeError('%s() takes no argument (%d given)' % + raise TypeError('%s() takes no arguments (%d given)' % (f_name, num_total)) for arg in args: if isinstance(arg, str) and arg in named: diff --git a/lib-python/2.7/site.py b/lib-python/2.7/site.py --- a/lib-python/2.7/site.py +++ b/lib-python/2.7/site.py @@ -75,6 +75,7 @@ USER_SITE = None USER_BASE = None + def makepath(*paths): dir = os.path.join(*paths) try: diff --git a/lib-python/2.7/sysconfig.py b/lib-python/2.7/sysconfig.py --- a/lib-python/2.7/sysconfig.py +++ b/lib-python/2.7/sysconfig.py @@ -27,10 +27,10 @@ 'data' : '{base}', }, 'pypy': { - 'stdlib': '{base}/lib-python', - 'platstdlib': '{base}/lib-python', - 'purelib': '{base}/lib-python', - 'platlib': '{base}/lib-python', + 'stdlib': '{base}/lib-python/{py_version_short}', + 'platstdlib': '{base}/lib-python/{py_version_short}', + 'purelib': '{base}/lib-python/{py_version_short}', + 'platlib': '{base}/lib-python/{py_version_short}', 'include': '{base}/include', 'platinclude': '{base}/include', 'scripts': '{base}/bin', diff --git a/lib-python/2.7/test/test_capi.py b/lib-python/2.7/test/test_capi.py --- a/lib-python/2.7/test/test_capi.py +++ b/lib-python/2.7/test/test_capi.py @@ -13,6 +13,17 @@ threading = None import _testcapi +skips = [] +if test_support.check_impl_detail(pypy=True): + skips += [ + 'test_broken_memoryview', + 'test_capsule', + 'test_lazy_hash_inheritance', + 'test_widechar', + 'TestThreadState', + 'TestPendingCalls', + ] + @unittest.skipUnless(threading, 'Threading required for this test.') class TestPendingCalls(unittest.TestCase): @@ -99,7 +110,7 @@ def test_main(): for name in dir(_testcapi): - if name.startswith('test_'): + if name.startswith('test_') and name not in skips: test = getattr(_testcapi, name) if test_support.verbose: print "internal", name @@ -126,7 +137,7 @@ raise test_support.TestFailed, \ "Couldn't find main thread correctly in the list" - if threading: + if threading and 'TestThreadState' not in skips: import thread import time TestThreadState() @@ -134,7 +145,8 @@ t.start() t.join() - test_support.run_unittest(TestPendingCalls) + if 'TestPendingCalls' not in skips: + test_support.run_unittest(TestPendingCalls) if __name__ == "__main__": test_main() diff --git a/lib-python/2.7/test/test_itertools.py b/lib-python/2.7/test/test_itertools.py --- a/lib-python/2.7/test/test_itertools.py +++ b/lib-python/2.7/test/test_itertools.py @@ -533,11 +533,11 @@ self.assertEqual(list(izip()), zip()) self.assertRaises(TypeError, izip, 3) self.assertRaises(TypeError, izip, range(3), 3) - self.assertEqual([tuple(list(pair)) for pair in izip('abc', 'def')], zip('abc', 'def')) self.assertEqual([pair for pair in izip('abc', 'def')], zip('abc', 'def')) + @test_support.impl_detail("tuple reuse is specific to CPython") def test_izip_tuple_reuse(self): ids = map(id, izip('abc', 'def')) @@ -588,6 +588,7 @@ zip('abc', 'def')) self.assertEqual([pair for pair in izip_longest('abc', 'def')], zip('abc', 'def')) + @test_support.impl_detail("tuple reuse is specific to CPython") def test_izip_longest_tuple_reuse(self): ids = map(id, izip_longest('abc', 'def')) diff --git a/lib-python/2.7/test/test_modulefinder.py b/lib-python/2.7/test/test_modulefinder.py --- a/lib-python/2.7/test/test_modulefinder.py +++ b/lib-python/2.7/test/test_modulefinder.py @@ -16,7 +16,7 @@ # library. TEST_DIR = tempfile.mkdtemp() -TEST_PATH = [TEST_DIR, os.path.dirname(__future__.__file__)] +TEST_PATH = [TEST_DIR, os.path.dirname(tempfile.__file__)] # Each test description is a list of 5 items: # diff --git a/lib-python/2.7/test/test_multiprocessing.py b/lib-python/2.7/test/test_multiprocessing.py --- a/lib-python/2.7/test/test_multiprocessing.py +++ b/lib-python/2.7/test/test_multiprocessing.py @@ -1343,7 +1343,7 @@ # Because we are using xmlrpclib for serialization instead of # pickle this will cause a serialization error. - self.assertRaises(Exception, queue.put, time.sleep) + self.assertRaises(Exception, queue.put, object) # Make queue finalizer run before the server is stopped del queue @@ -1800,9 +1800,9 @@ if not gc.isenabled(): gc.enable() self.addCleanup(gc.disable) - thresholds = gc.get_threshold() - self.addCleanup(gc.set_threshold, *thresholds) - gc.set_threshold(10) + #thresholds = gc.get_threshold() + #self.addCleanup(gc.set_threshold, *thresholds) + #gc.set_threshold(10) # perform numerous block allocations, with cyclic references to make # sure objects are collected asynchronously by the gc @@ -1865,6 +1865,7 @@ def test_synchronize(self): self.test_sharedctypes(lock=True) + @unittest.skipUnless(test_support.check_impl_detail(pypy=False), "pypy ctypes differences") def test_copy(self): foo = _Foo(2, 5.0) bar = copy(foo) diff --git a/lib-python/2.7/test/test_support.py b/lib-python/2.7/test/test_support.py --- a/lib-python/2.7/test/test_support.py +++ b/lib-python/2.7/test/test_support.py @@ -1085,7 +1085,6 @@ else: runner = BasicTestRunner() - result = runner.run(suite) if not result.wasSuccessful(): if len(result.errors) == 1 and not result.failures: diff --git a/lib-python/2.7/test/test_zipfile.py b/lib-python/2.7/test/test_zipfile.py --- a/lib-python/2.7/test/test_zipfile.py +++ b/lib-python/2.7/test/test_zipfile.py @@ -1213,6 +1213,17 @@ self.assertEqual(data1, '1'*FIXEDTEST_SIZE) self.assertEqual(data2, '2'*FIXEDTEST_SIZE) + def test_many_opens(self): + # Verify that read() and open() promptly close the file descriptor, + # and don't rely on the garbage collector to free resources. + with zipfile.ZipFile(TESTFN2, mode="r") as zipf: + for x in range(100): + zipf.read('ones') + with zipf.open('ones') as zopen1: + pass + for x in range(10): + self.assertLess(open('/dev/null').fileno(), 100) + def tearDown(self): unlink(TESTFN2) diff --git a/lib-python/2.7/zipfile.py b/lib-python/2.7/zipfile.py --- a/lib-python/2.7/zipfile.py +++ b/lib-python/2.7/zipfile.py @@ -475,9 +475,11 @@ # Search for universal newlines or line chunks. PATTERN = re.compile(r'^(?P[^\r\n]+)|(?P\n|\r\n?)') - def __init__(self, fileobj, mode, zipinfo, decrypter=None): + def __init__(self, fileobj, mode, zipinfo, decrypter=None, + close_fileobj=False): self._fileobj = fileobj self._decrypter = decrypter + self._close_fileobj = close_fileobj self._compress_type = zipinfo.compress_type self._compress_size = zipinfo.compress_size @@ -649,6 +651,12 @@ self._offset += len(data) return data + def close(self): + try: + if self._close_fileobj: + self._fileobj.close() + finally: + super(ZipExtFile, self).close() class ZipFile: @@ -866,7 +874,8 @@ def read(self, name, pwd=None): """Return file bytes (as a string) for name.""" - return self.open(name, "r", pwd).read() + with self.open(name, "r", pwd) as fp: + return fp.read() def open(self, name, mode="r", pwd=None): """Return file-like object for 'name'.""" @@ -889,8 +898,12 @@ zinfo = name else: # Get info object for name - zinfo = self.getinfo(name) - + try: + zinfo = self.getinfo(name) + except KeyError: + if not self._filePassed: + zef_file.close() + raise zef_file.seek(zinfo.header_offset, 0) # Skip the file header: @@ -904,6 +917,8 @@ zef_file.read(fheader[_FH_EXTRA_FIELD_LENGTH]) if fname != zinfo.orig_filename: + if not self._filePassed: + zef_file.close() raise BadZipfile, \ 'File name in directory "%s" and header "%s" differ.' % ( zinfo.orig_filename, fname) @@ -915,6 +930,8 @@ if not pwd: pwd = self.pwd if not pwd: + if not self._filePassed: + zef_file.close() raise RuntimeError, "File %s is encrypted, " \ "password required for extraction" % name @@ -933,9 +950,12 @@ # compare against the CRC otherwise check_byte = (zinfo.CRC >> 24) & 0xff if ord(h[11]) != check_byte: + if not self._filePassed: + zef_file.close() raise RuntimeError("Bad password for file", name) - return ZipExtFile(zef_file, mode, zinfo, zd) + return ZipExtFile(zef_file, mode, zinfo, zd, + close_fileobj=not self._filePassed) def extract(self, member, path=None, pwd=None): """Extract a member from the archive to the current working directory, @@ -993,7 +1013,7 @@ return targetpath source = self.open(member, pwd=pwd) - target = file(targetpath, "wb") + target = open(targetpath, "wb") shutil.copyfileobj(source, target) source.close() target.close() diff --git a/lib-python/conftest.py b/lib-python/conftest.py --- a/lib-python/conftest.py +++ b/lib-python/conftest.py @@ -61,7 +61,7 @@ usemodules = '', skip=None): self.basename = basename - self._usemodules = usemodules.split() + ['signal'] + self._usemodules = usemodules.split() + ['signal', 'rctime', 'itertools', '_socket'] self._compiler = compiler self.core = core self.skip = skip @@ -93,63 +93,57 @@ m.test_main() ''' % locals()) -if sys.platform == 'win32': - skip_win32 = "Not supported on Windows" - only_win32 = False -else: - skip_win32 = False - only_win32 = "Only on Windows" - testmap = [ RegrTest('test___all__.py', core=True), RegrTest('test___future__.py', core=True), - RegrTest('test__locale.py', skip=skip_win32), + RegrTest('test__locale.py', usemodules='_locale'), RegrTest('test_abc.py'), RegrTest('test_abstract_numbers.py'), - RegrTest('test_aepack.py', skip=True), + RegrTest('test_aepack.py'), RegrTest('test_aifc.py'), - RegrTest('test_argparse.py'), - RegrTest('test_al.py', skip=True), - RegrTest('test_ast.py', core=True), - RegrTest('test_anydbm.py'), - RegrTest('test_applesingle.py', skip=True), - RegrTest('test_array.py', core=True, usemodules='struct array'), + RegrTest('test_al.py'), + RegrTest('test_anydbm.py', usemodules='struct'), + RegrTest('test_applesingle.py'), + RegrTest('test_argparse.py', usemodules='binascii'), + RegrTest('test_array.py', core=True, usemodules='struct array binascii'), RegrTest('test_ascii_formatd.py'), - RegrTest('test_asynchat.py', usemodules='thread'), - RegrTest('test_asyncore.py'), + RegrTest('test_ast.py', core=True, usemodules='struct'), + RegrTest('test_asynchat.py', usemodules='select fcntl'), + RegrTest('test_asyncore.py', usemodules='select fcntl'), RegrTest('test_atexit.py', core=True), - RegrTest('test_audioop.py', skip=True), + RegrTest('test_audioop.py', skip="unsupported extension module"), RegrTest('test_augassign.py', core=True), - RegrTest('test_base64.py'), + RegrTest('test_base64.py', usemodules='struct'), RegrTest('test_bastion.py'), + RegrTest('test_bigaddrspace.py'), + RegrTest('test_bigmem.py'), RegrTest('test_binascii.py', usemodules='binascii'), - RegrTest('test_binhex.py'), - RegrTest('test_binop.py', core=True), RegrTest('test_bisect.py', core=True, usemodules='_bisect'), RegrTest('test_bool.py', core=True), - RegrTest('test_bsddb.py', skip="unsupported extension module"), - RegrTest('test_bsddb185.py', skip="unsupported extension module"), - RegrTest('test_bsddb3.py', skip="unsupported extension module"), + RegrTest('test_bsddb.py'), + RegrTest('test_bsddb185.py'), + RegrTest('test_bsddb3.py'), RegrTest('test_buffer.py'), RegrTest('test_bufio.py', core=True), - RegrTest('test_builtin.py', core=True), - RegrTest('test_bytes.py'), + RegrTest('test_builtin.py', core=True, usemodules='binascii'), + RegrTest('test_bytes.py', usemodules='struct binascii'), RegrTest('test_bz2.py', usemodules='bz2'), RegrTest('test_calendar.py'), RegrTest('test_call.py', core=True), - RegrTest('test_capi.py', skip="not applicable"), - RegrTest('test_cd.py', skip=True), + RegrTest('test_capi.py'), + RegrTest('test_cd.py'), RegrTest('test_cfgparser.py'), - RegrTest('test_cgi.py'), RegrTest('test_charmapcodec.py', core=True), - RegrTest('test_cl.py', skip=True), + RegrTest('test_cl.py'), RegrTest('test_class.py', core=True), RegrTest('test_cmath.py', core=True), RegrTest('test_cmd.py'), + RegrTest('test_cmd_line.py'), RegrTest('test_cmd_line_script.py'), + RegrTest('test_code.py', core=True), RegrTest('test_codeccallbacks.py', core=True), RegrTest('test_codecencodings_cn.py', usemodules='_multibytecodec'), RegrTest('test_codecencodings_hk.py', usemodules='_multibytecodec'), @@ -157,7 +151,6 @@ RegrTest('test_codecencodings_jp.py', usemodules='_multibytecodec'), RegrTest('test_codecencodings_kr.py', usemodules='_multibytecodec'), RegrTest('test_codecencodings_tw.py', usemodules='_multibytecodec'), - RegrTest('test_codecmaps_cn.py', usemodules='_multibytecodec'), RegrTest('test_codecmaps_hk.py', usemodules='_multibytecodec'), RegrTest('test_codecmaps_jp.py', usemodules='_multibytecodec'), @@ -165,8 +158,9 @@ RegrTest('test_codecmaps_tw.py', usemodules='_multibytecodec'), RegrTest('test_codecs.py', core=True, usemodules='_multibytecodec'), RegrTest('test_codeop.py', core=True), + RegrTest('test_coding.py', core=True), RegrTest('test_coercion.py', core=True), - RegrTest('test_collections.py'), + RegrTest('test_collections.py', usemodules='binascii struct'), RegrTest('test_colorsys.py'), RegrTest('test_commands.py'), RegrTest('test_compare.py', core=True), @@ -174,22 +168,24 @@ RegrTest('test_compileall.py'), RegrTest('test_compiler.py', core=False, skip="slowly deprecating compiler"), RegrTest('test_complex.py', core=True), - + RegrTest('test_complex_args.py'), RegrTest('test_contains.py', core=True), + RegrTest('test_contextlib.py', usemodules="thread"), RegrTest('test_cookie.py'), RegrTest('test_cookielib.py'), RegrTest('test_copy.py', core=True), RegrTest('test_copy_reg.py', core=True), RegrTest('test_cpickle.py', core=True), - RegrTest('test_cprofile.py'), - RegrTest('test_crypt.py', usemodules='crypt', skip=skip_win32), + RegrTest('test_cprofile.py'), + RegrTest('test_crypt.py', usemodules='crypt'), RegrTest('test_csv.py', usemodules='_csv'), - - RegrTest('test_curses.py', skip="unsupported extension module"), - RegrTest('test_datetime.py'), + RegrTest('test_ctypes.py', usemodules="_rawffi thread"), + RegrTest('test_curses.py'), + RegrTest('test_datetime.py', usemodules='binascii struct'), RegrTest('test_dbm.py'), RegrTest('test_decimal.py'), RegrTest('test_decorators.py', core=True), + RegrTest('test_defaultdict.py', usemodules='_collections'), RegrTest('test_deque.py', core=True, usemodules='_collections'), RegrTest('test_descr.py', core=True, usemodules='_weakref'), RegrTest('test_descrtut.py', core=True), @@ -200,7 +196,7 @@ RegrTest('test_dircache.py', core=True), RegrTest('test_dis.py'), RegrTest('test_distutils.py', skip=True), - RegrTest('test_dl.py', skip=True), + RegrTest('test_dl.py'), RegrTest('test_doctest.py', usemodules="thread"), RegrTest('test_doctest2.py'), RegrTest('test_docxmlrpc.py'), @@ -208,20 +204,22 @@ RegrTest('test_dummy_thread.py', core=True), RegrTest('test_dummy_threading.py', core=True), RegrTest('test_email.py'), - RegrTest('test_email_codecs.py'), + RegrTest('test_email_renamed.py'), RegrTest('test_enumerate.py', core=True), RegrTest('test_eof.py', core=True), RegrTest('test_epoll.py'), RegrTest('test_errno.py', usemodules="errno"), + RegrTest('test_exception_variations.py'), RegrTest('test_exceptions.py', core=True), RegrTest('test_extcall.py', core=True), - RegrTest('test_fcntl.py', usemodules='fcntl', skip=skip_win32), + RegrTest('test_fcntl.py', usemodules='fcntl'), RegrTest('test_file.py', usemodules="posix", core=True), RegrTest('test_file2k.py', usemodules="posix", core=True), RegrTest('test_filecmp.py', core=True), RegrTest('test_fileinput.py', core=True), RegrTest('test_fileio.py'), + RegrTest('test_float.py', core=True), RegrTest('test_fnmatch.py', core=True), RegrTest('test_fork1.py', usemodules="thread"), RegrTest('test_format.py', core=True), @@ -230,6 +228,7 @@ RegrTest('test_frozen.py', skip="unsupported extension module"), RegrTest('test_ftplib.py'), RegrTest('test_funcattrs.py', core=True), + RegrTest('test_functools.py'), RegrTest('test_future.py', core=True), RegrTest('test_future1.py', core=True), RegrTest('test_future2.py', core=True), @@ -239,41 +238,37 @@ RegrTest('test_future_builtins.py'), RegrTest('test_gc.py', usemodules='_weakref', skip="implementation detail"), RegrTest('test_gdb.py', skip="not applicable"), - RegrTest('test_gdbm.py', skip="unsupported extension module"), + RegrTest('test_gdbm.py'), RegrTest('test_generators.py', core=True, usemodules='thread _weakref'), RegrTest('test_genericpath.py'), RegrTest('test_genexps.py', core=True, usemodules='_weakref'), - RegrTest('test_getargs.py', skip="unsupported extension module"), - RegrTest('test_getargs2.py', skip="unsupported extension module"), - + RegrTest('test_getargs.py'), + RegrTest('test_getargs2.py', usemodules='binascii', skip=True), RegrTest('test_getopt.py', core=True), RegrTest('test_gettext.py'), - - RegrTest('test_gl.py', skip=True), + RegrTest('test_gl.py'), RegrTest('test_glob.py', core=True), RegrTest('test_global.py', core=True), RegrTest('test_grammar.py', core=True), - RegrTest('test_grp.py', skip=skip_win32), - - RegrTest('test_gzip.py'), + RegrTest('test_grp.py'), + RegrTest('test_gzip.py', usemodules='zlib'), RegrTest('test_hash.py', core=True), RegrTest('test_hashlib.py', core=True), - RegrTest('test_heapq.py', core=True), RegrTest('test_hmac.py'), RegrTest('test_hotshot.py', skip="unsupported extension module"), - RegrTest('test_htmllib.py'), RegrTest('test_htmlparser.py'), RegrTest('test_httplib.py'), RegrTest('test_httpservers.py'), - RegrTest('test_imageop.py', skip="unsupported extension module"), + RegrTest('test_imageop.py'), RegrTest('test_imaplib.py'), - RegrTest('test_imgfile.py', skip="unsupported extension module"), + RegrTest('test_imgfile.py'), RegrTest('test_imp.py', core=True, usemodules='thread'), RegrTest('test_import.py', core=True), RegrTest('test_importhooks.py', core=True), RegrTest('test_importlib.py'), + RegrTest('test_index.py'), RegrTest('test_inspect.py'), RegrTest('test_int.py', core=True), RegrTest('test_int_literal.py', core=True), @@ -296,7 +291,7 @@ RegrTest('test_long_future.py', core=True), RegrTest('test_longexp.py', core=True), RegrTest('test_macos.py'), - RegrTest('test_macostools.py', skip=True), + RegrTest('test_macostools.py'), RegrTest('test_macpath.py'), RegrTest('test_mailbox.py'), RegrTest('test_marshal.py', core=True), @@ -307,30 +302,29 @@ RegrTest('test_mhlib.py'), RegrTest('test_mimetools.py'), RegrTest('test_mimetypes.py'), - RegrTest('test_MimeWriter.py', core=False), + RegrTest('test_MimeWriter.py', core=False, usemodules='binascii'), RegrTest('test_minidom.py'), RegrTest('test_mmap.py', usemodules="mmap"), RegrTest('test_module.py', core=True), RegrTest('test_modulefinder.py'), - RegrTest('test_msilib.py', skip=only_win32), + RegrTest('test_msilib.py'), RegrTest('test_multibytecodec.py', usemodules='_multibytecodec'), - RegrTest('test_multibytecodec_support.py', skip="not a test"), RegrTest('test_multifile.py'), - RegrTest('test_multiprocessing.py', skip="FIXME leaves subprocesses"), + RegrTest('test_multiprocessing.py'), RegrTest('test_mutants.py', core="possibly"), RegrTest('test_mutex.py'), RegrTest('test_netrc.py'), RegrTest('test_new.py', core=True), - RegrTest('test_nis.py', skip="unsupported extension module"), + RegrTest('test_nis.py'), RegrTest('test_normalization.py'), RegrTest('test_ntpath.py'), + RegrTest('test_old_mailbox.py'), RegrTest('test_opcodes.py', core=True), RegrTest('test_openpty.py'), RegrTest('test_operator.py', core=True), RegrTest('test_optparse.py'), - RegrTest('test_os.py', core=True), - RegrTest('test_ossaudiodev.py', skip="unsupported extension module"), + RegrTest('test_ossaudiodev.py'), RegrTest('test_parser.py', skip="slowly deprecating compiler"), RegrTest('test_pdb.py'), RegrTest('test_peepholer.py'), @@ -338,14 +332,16 @@ RegrTest('test_pep263.py'), RegrTest('test_pep277.py'), RegrTest('test_pep292.py'), + RegrTest('test_pep352.py'), RegrTest('test_pickle.py', core=True), RegrTest('test_pickletools.py', core=False), RegrTest('test_pipes.py'), RegrTest('test_pkg.py', core=True), RegrTest('test_pkgimport.py', core=True), RegrTest('test_pkgutil.py'), - RegrTest('test_plistlib.py', skip="unsupported module"), - RegrTest('test_poll.py', skip=skip_win32), + RegrTest('test_platform.py'), + RegrTest('test_plistlib.py'), + RegrTest('test_poll.py'), RegrTest('test_popen.py'), RegrTest('test_popen2.py'), RegrTest('test_poplib.py'), @@ -357,8 +353,8 @@ RegrTest('test_profile.py'), RegrTest('test_property.py', core=True), RegrTest('test_pstats.py'), - RegrTest('test_pty.py', skip="unsupported extension module"), - RegrTest('test_pwd.py', usemodules="pwd", skip=skip_win32), + RegrTest('test_pty.py', usemodules='fcntl termios select'), + RegrTest('test_pwd.py', usemodules="pwd"), RegrTest('test_py3kwarn.py'), RegrTest('test_py_compile.py'), RegrTest('test_pyclbr.py'), @@ -370,15 +366,15 @@ RegrTest('test_re.py', core=True), RegrTest('test_readline.py'), RegrTest('test_repr.py', core=True), - RegrTest('test_resource.py', skip=skip_win32), + RegrTest('test_resource.py'), RegrTest('test_rfc822.py'), RegrTest('test_richcmp.py', core=True), RegrTest('test_rlcompleter.py'), - RegrTest('test_robotparser.py'), + RegrTest('test_runpy.py'), RegrTest('test_sax.py'), RegrTest('test_scope.py', core=True), - RegrTest('test_scriptpackages.py', skip="unsupported extension module"), + RegrTest('test_scriptpackages.py'), RegrTest('test_select.py'), RegrTest('test_set.py', core=True), RegrTest('test_sets.py'), @@ -389,64 +385,59 @@ RegrTest('test_shlex.py'), RegrTest('test_shutil.py'), RegrTest('test_signal.py'), - RegrTest('test_SimpleHTTPServer.py'), + RegrTest('test_SimpleHTTPServer.py', usemodules='binascii'), RegrTest('test_site.py', core=False), RegrTest('test_slice.py', core=True), RegrTest('test_smtplib.py'), RegrTest('test_smtpnet.py'), RegrTest('test_socket.py', usemodules='thread _weakref'), - RegrTest('test_socketserver.py', usemodules='thread'), - RegrTest('test_softspace.py', core=True), RegrTest('test_sort.py', core=True), + RegrTest('test_sqlite.py', usemodules="thread _rawffi zlib"), RegrTest('test_ssl.py', usemodules='_ssl _socket select'), + RegrTest('test_startfile.py'), RegrTest('test_str.py', core=True), - RegrTest('test_strftime.py'), RegrTest('test_string.py', core=True), - RegrTest('test_StringIO.py', core=True, usemodules='cStringIO'), + RegrTest('test_StringIO.py', core=True, usemodules='cStringIO array'), RegrTest('test_stringprep.py'), RegrTest('test_strop.py', skip="deprecated"), - RegrTest('test_strptime.py'), RegrTest('test_strtod.py'), RegrTest('test_struct.py', usemodules='struct'), RegrTest('test_structmembers.py', skip="CPython specific"), RegrTest('test_structseq.py'), RegrTest('test_subprocess.py', usemodules='signal'), - RegrTest('test_sunaudiodev.py', skip=True), + RegrTest('test_sunaudiodev.py'), RegrTest('test_sundry.py'), RegrTest('test_symtable.py', skip="implementation detail"), RegrTest('test_syntax.py', core=True), RegrTest('test_sys.py', core=True, usemodules='struct'), + RegrTest('test_sys_setprofile.py', core=True), RegrTest('test_sys_settrace.py', core=True), - RegrTest('test_sys_setprofile.py', core=True), RegrTest('test_sysconfig.py'), - RegrTest('test_tcl.py', skip="unsupported extension module"), RegrTest('test_tarfile.py'), + RegrTest('test_tcl.py'), RegrTest('test_telnetlib.py'), RegrTest('test_tempfile.py'), - RegrTest('test_textwrap.py'), RegrTest('test_thread.py', usemodules="thread", core=True), RegrTest('test_threaded_import.py', usemodules="thread", core=True), RegrTest('test_threadedtempfile.py', usemodules="thread", core=False), - RegrTest('test_threading.py', usemodules="thread", core=True), RegrTest('test_threading_local.py', usemodules="thread", core=True), RegrTest('test_threadsignals.py', usemodules="thread"), - RegrTest('test_time.py', core=True), RegrTest('test_timeout.py'), RegrTest('test_tk.py'), - RegrTest('test_ttk_guionly.py'), - RegrTest('test_ttk_textonly.py'), RegrTest('test_tokenize.py'), RegrTest('test_trace.py'), RegrTest('test_traceback.py', core=True), RegrTest('test_transformer.py', core=True), + RegrTest('test_ttk_guionly.py'), + RegrTest('test_ttk_textonly.py'), RegrTest('test_tuple.py', core=True), RegrTest('test_typechecks.py'), RegrTest('test_types.py', core=True), @@ -462,6 +453,7 @@ RegrTest('test_unpack.py', core=True), RegrTest('test_urllib.py'), RegrTest('test_urllib2.py'), + RegrTest('test_urllib2_localnet.py', usemodules="thread"), RegrTest('test_urllib2net.py'), RegrTest('test_urllibnet.py'), RegrTest('test_urlparse.py'), @@ -469,61 +461,38 @@ RegrTest('test_userlist.py', core=True), RegrTest('test_userstring.py', core=True), RegrTest('test_uu.py'), - - RegrTest('test_warnings.py', core=True), - RegrTest('test_wave.py', skip="unsupported extension module"), - RegrTest('test_weakref.py', core=True, usemodules='_weakref'), - RegrTest('test_weakset.py'), - - RegrTest('test_whichdb.py'), - RegrTest('test_winreg.py', skip=only_win32), - RegrTest('test_winsound.py', skip="unsupported extension module"), - RegrTest('test_xmllib.py'), - RegrTest('test_xmlrpc.py'), - - RegrTest('test_xpickle.py'), - RegrTest('test_xrange.py', core=True), - RegrTest('test_zipfile.py'), - RegrTest('test_zipimport.py', usemodules='zlib zipimport'), - RegrTest('test_zipimport_support.py', usemodules='zlib zipimport'), - RegrTest('test_zlib.py', usemodules='zlib'), - - RegrTest('test_bigaddrspace.py'), - RegrTest('test_bigmem.py'), - RegrTest('test_cmd_line.py'), - RegrTest('test_code.py'), - RegrTest('test_coding.py'), - RegrTest('test_complex_args.py'), - RegrTest('test_contextlib.py', usemodules="thread"), - RegrTest('test_ctypes.py', usemodules="_rawffi thread"), - RegrTest('test_defaultdict.py', usemodules='_collections'), - RegrTest('test_email_renamed.py'), - RegrTest('test_exception_variations.py'), - RegrTest('test_float.py'), - RegrTest('test_functools.py'), - RegrTest('test_index.py'), - RegrTest('test_old_mailbox.py'), - RegrTest('test_pep352.py'), - RegrTest('test_platform.py'), - RegrTest('test_runpy.py'), - RegrTest('test_sqlite.py', usemodules="thread _rawffi zlib"), - RegrTest('test_startfile.py', skip="bogus test"), - RegrTest('test_structmembers.py', skip="depends on _testcapi"), - RegrTest('test_urllib2_localnet.py', usemodules="thread"), RegrTest('test_uuid.py'), RegrTest('test_wait3.py', usemodules="thread"), RegrTest('test_wait4.py', usemodules="thread"), + RegrTest('test_warnings.py', core=True), + RegrTest('test_wave.py'), + RegrTest('test_weakref.py', core=True, usemodules='_weakref'), + RegrTest('test_weakset.py'), + RegrTest('test_whichdb.py'), + RegrTest('test_winreg.py'), + RegrTest('test_winsound.py'), RegrTest('test_with.py'), RegrTest('test_wsgiref.py'), RegrTest('test_xdrlib.py'), RegrTest('test_xml_etree.py'), RegrTest('test_xml_etree_c.py'), + RegrTest('test_xmllib.py'), + RegrTest('test_xmlrpc.py'), + RegrTest('test_xpickle.py'), + RegrTest('test_xrange.py', core=True), + RegrTest('test_zipfile.py'), RegrTest('test_zipfile64.py'), + RegrTest('test_zipimport.py', usemodules='zlib zipimport'), + RegrTest('test_zipimport_support.py', usemodules='zlib zipimport'), + RegrTest('test_zlib.py', usemodules='zlib'), ] def check_testmap_complete(): listed_names = dict.fromkeys([regrtest.basename for regrtest in testmap]) - listed_names['test_support.py'] = True # ignore this + assert len(listed_names) == len(testmap) + # names to ignore + listed_names['test_support.py'] = True + listed_names['test_multibytecodec_support.py'] = True missing = [] for path in testdir.listdir(fil='test_*.py'): name = path.basename @@ -578,7 +547,7 @@ def getinvocation(self, regrtest): fspath = regrtest.getfspath() python = sys.executable - pypy_script = pypydir.join('bin', 'py.py') + pypy_script = pypydir.join('bin', 'pyinteractive.py') alarm_script = pypydir.join('tool', 'alarm.py') if sys.platform == 'win32': watchdog_name = 'watchdog_nt.py' diff --git a/lib_pypy/_ctypes_test.py b/lib_pypy/_ctypes_test.py --- a/lib_pypy/_ctypes_test.py +++ b/lib_pypy/_ctypes_test.py @@ -1,6 +1,5 @@ import os, sys import tempfile -import gc def compile_shared(): """Compile '_ctypes_test.c' into an extension module, and import it @@ -19,7 +18,7 @@ if sys.platform == 'win32': ccflags = ['-D_CRT_SECURE_NO_WARNINGS'] else: - ccflags = ['-fPIC'] + ccflags = ['-fPIC', '-Wimplicit-function-declaration'] res = compiler.compile([os.path.join(thisdir, '_ctypes_test.c')], include_dirs=[include_dir], extra_preargs=ccflags) @@ -35,10 +34,10 @@ library = os.path.join(thisdir, '..', 'include', 'python27') if not os.path.exists(library + '.lib'): # For a local translation - library = os.path.join(thisdir, '..', 'pypy', 'translator', - 'goal', 'libpypy-c') + library = os.path.join(thisdir, '..', 'pypy', 'goal', 'libpypy-c') libraries = [library, 'oleaut32'] - extra_ldargs = ['/MANIFEST'] # needed for VC10 + extra_ldargs = ['/MANIFEST', # needed for VC10 + '/EXPORT:init_ctypes_test'] else: libraries = [] extra_ldargs = [] diff --git a/lib_pypy/_testcapi.py b/lib_pypy/_testcapi.py --- a/lib_pypy/_testcapi.py +++ b/lib_pypy/_testcapi.py @@ -34,8 +34,7 @@ library = os.path.join(thisdir, '..', 'include', 'python27') if not os.path.exists(library + '.lib'): # For a local translation - library = os.path.join(thisdir, '..', 'pypy', 'translator', - 'goal', 'libpypy-c') + library = os.path.join(thisdir, '..', 'pypy', 'goal', 'libpypy-c') libraries = [library, 'oleaut32'] extra_ldargs = ['/MANIFEST', # needed for VC10 '/EXPORT:init_testcapi'] diff --git a/lib_pypy/cPickle.py b/lib_pypy/cPickle.py --- a/lib_pypy/cPickle.py +++ b/lib_pypy/cPickle.py @@ -1,5 +1,5 @@ # -# One-liner implementation of cPickle +# Reimplementation of cPickle, mostly as a copy of pickle.py # from pickle import Pickler, dump, dumps, PickleError, PicklingError, UnpicklingError, _EmptyClass @@ -131,6 +131,13 @@ # Unpickling machinery +class _Stack(list): + def pop(self, index=-1): + try: + return list.pop(self, index) + except IndexError: + raise UnpicklingError("unpickling stack underflow") + class Unpickler(object): def __init__(self, file): @@ -155,7 +162,7 @@ Return the reconstituted object hierarchy specified in the file. """ self.mark = object() # any new unique object - self.stack = [] + self.stack = _Stack() self.append = self.stack.append try: key = ord(self.read(1)) diff --git a/lib_pypy/ctypes_support.py b/lib_pypy/ctypes_support.py --- a/lib_pypy/ctypes_support.py +++ b/lib_pypy/ctypes_support.py @@ -19,16 +19,19 @@ if sys.platform == 'win32': standard_c_lib._errno.restype = ctypes.POINTER(ctypes.c_int) + standard_c_lib._errno.argtypes = None def _where_is_errno(): return standard_c_lib._errno() elif sys.platform in ('linux2', 'freebsd6'): standard_c_lib.__errno_location.restype = ctypes.POINTER(ctypes.c_int) + standard_c_lib.__errno_location.argtypes = None def _where_is_errno(): return standard_c_lib.__errno_location() elif sys.platform in ('darwin', 'freebsd7', 'freebsd8', 'freebsd9'): standard_c_lib.__error.restype = ctypes.POINTER(ctypes.c_int) + standard_c_lib.__error.argtypes = None def _where_is_errno(): return standard_c_lib.__error() diff --git a/lib_pypy/greenlet.py b/lib_pypy/greenlet.py --- a/lib_pypy/greenlet.py +++ b/lib_pypy/greenlet.py @@ -1,5 +1,6 @@ import _continuation, sys +__version__ = "0.4.0" # ____________________________________________________________ # Exceptions @@ -57,7 +58,8 @@ def __switch(target, methodname, *args): current = getcurrent() # - while not target: + while not (target.__main or _continulet.is_pending(target)): + # inlined __nonzero__ ^^^ in case it's overridden if not target.__started: if methodname == 'switch': greenlet_func = _greenlet_start diff --git a/lib_pypy/pypy_test/test_cPickle.py b/lib_pypy/pypy_test/test_cPickle.py new file mode 100644 --- /dev/null +++ b/lib_pypy/pypy_test/test_cPickle.py @@ -0,0 +1,7 @@ +from __future__ import absolute_import +import py + +from lib_pypy import cPickle + +def test_stack_underflow(): + py.test.raises(cPickle.UnpicklingError, cPickle.loads, "a string") diff --git a/lib_pypy/pyrepl/unix_console.py b/lib_pypy/pyrepl/unix_console.py --- a/lib_pypy/pyrepl/unix_console.py +++ b/lib_pypy/pyrepl/unix_console.py @@ -398,6 +398,7 @@ if hasattr(self, 'old_sigwinch'): signal.signal(signal.SIGWINCH, self.old_sigwinch) + del self.old_sigwinch def __sigwinch(self, signum, frame): self.height, self.width = self.getheightwidth() diff --git a/pypy/bin/checkmodule.py b/pypy/bin/checkmodule.py --- a/pypy/bin/checkmodule.py +++ b/pypy/bin/checkmodule.py @@ -8,6 +8,8 @@ """ import sys, os +sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', '..')) + from pypy.objspace.fake.checkmodule import checkmodule def main(argv): diff --git a/pypy/conftest.py b/pypy/conftest.py --- a/pypy/conftest.py +++ b/pypy/conftest.py @@ -67,10 +67,11 @@ if self.config.option.runappdirect: # only collect regular tests if we are in an 'app_test' directory, # or in test_lib_pypy - names = self.listnames() - return "app_test" in names or "test_lib_pypy" in names - else: - return True + for name in self.listnames(): + if "app_test" in name or "test_lib_pypy" in name: + return True + return False + return True def funcnamefilter(self, name): if name.startswith('test_'): diff --git a/pypy/doc/arm.rst b/pypy/doc/arm.rst --- a/pypy/doc/arm.rst +++ b/pypy/doc/arm.rst @@ -145,7 +145,7 @@ :: - pypy ~/path_to_pypy_checkout/pypy/translator/goal/translate.py -O1 --platform=arm target.py + pypy ~/path_to_pypy_checkout/rpython/translator/goal/translate.py -O1 --platform=arm target.py If everything worked correctly this should yield an ARM binary. Running this binary in the ARM chroot or on an ARM device should produce the output ``"Hello World"``. diff --git a/pypy/doc/coding-guide.rst b/pypy/doc/coding-guide.rst --- a/pypy/doc/coding-guide.rst +++ b/pypy/doc/coding-guide.rst @@ -832,7 +832,7 @@ for the next milestone, both from an E-Mail and from a web interface. -.. _`development tracker`: https://codespeak.net/issue/pypy-dev/ +.. _`development tracker`: https://bugs.pypy.org/ use your codespeak login or register ------------------------------------ @@ -841,7 +841,7 @@ tracker. Else, you can `register with the tracker`_ easily. -.. _`register with the tracker`: https://codespeak.net/issue/pypy-dev/user?@template=register +.. _`register with the tracker`: https://bugs.pypy.org/user?@template=register .. _`roundup`: http://roundup.sourceforge.net/ diff --git a/pypy/doc/confrest.py b/pypy/doc/confrest.py --- a/pypy/doc/confrest.py +++ b/pypy/doc/confrest.py @@ -4,7 +4,8 @@ from confrest_oldpy import Project, Page, relpath html = py.xml.html -class PyPyPage(Page): + +class PyPyPage(Page): googlefragment = """ """ + def fill_menubar(self): self.menubar = html.div( - html.a("home", - href=self.get_doclink("index.html"), - class_="menu"), + html.a("home", + href=self.get_doclink("index.html"), + class_="menu"), " ", html.a("blog", href="http://morepypy.blogspot.com", class_="menu"), - " ", + " ", html.a("getting-started", href=self.get_doclink("getting-started.html"), - class_="menu"), + class_="menu"), " ", html.a("documentation", href=self.get_doclink("docindex.html"), class_="menu"), - " ", + " ", html.a("hg", href="https://bitbucket.org/pypy/pypy", class_="menu"), - " ", + " ", html.a("issues", - href="https://codespeak.net/issue/pypy-dev/", + href="https://bugs.pypy.org/", class_="menu"), " ", id="menubar") @@ -43,25 +45,25 @@ return relpath(self.targetpath.strpath, self.project.docpath.join(target).strpath) - def unicode(self, doctype=True): - page = self._root.unicode() + def unicode(self, doctype=True): + page = self._root.unicode() page = page.replace("", self.googlefragment + "") - if doctype: - return self.doctype + page - else: - return page - + if doctype: + return self.doctype + page + else: + return page -class Project(Project): + +class Project(Project): mydir = py.path.local(__file__).dirpath() - title = "PyPy" + title = "PyPy" stylesheet = 'style.css' - encoding = 'latin1' + encoding = 'latin1' prefix_title = "PyPy" logo = html.div( html.a( - html.img(alt="PyPy", id="pyimg", - src="http://codespeak.net/pypy/img/py-web1.png", + html.img(alt="PyPy", id="pyimg", + src="http://codespeak.net/pypy/img/py-web1.png", height=110, width=149))) - Page = PyPyPage + Page = PyPyPage diff --git a/pypy/doc/cppyy.rst b/pypy/doc/cppyy.rst --- a/pypy/doc/cppyy.rst +++ b/pypy/doc/cppyy.rst @@ -86,10 +86,10 @@ $ hg clone https://bitbucket.org/pypy/pypy $ cd pypy $ hg up reflex-support # optional - $ cd pypy/translator/goal + $ cd pypy/goal # This example shows python, but using pypy-c is faster and uses less memory - $ python translate.py -O jit --gcrootfinder=shadowstack targetpypystandalone.py --withmod-cppyy + $ python ../../rpython/bin/rpython.py -O jit --gcrootfinder=shadowstack targetpypystandalone.py --withmod-cppyy This will build a ``pypy-c`` that includes the cppyy module, and through that, Reflex support. diff --git a/pypy/doc/cpython_differences.rst b/pypy/doc/cpython_differences.rst --- a/pypy/doc/cpython_differences.rst +++ b/pypy/doc/cpython_differences.rst @@ -318,10 +318,5 @@ type and vice versa. For builtin types, a dictionary will be returned that cannot be changed (but still looks and behaves like a normal dictionary). -* the ``__len__`` or ``__length_hint__`` special methods are sometimes - called by CPython to get a length estimate to preallocate internal arrays. - So far, PyPy never calls ``__len__`` for this purpose, and never calls - ``__length_hint__`` at all. - .. include:: _ref.txt diff --git a/pypy/doc/ctypes-implementation.rst b/pypy/doc/ctypes-implementation.rst --- a/pypy/doc/ctypes-implementation.rst +++ b/pypy/doc/ctypes-implementation.rst @@ -113,7 +113,7 @@ The pypy-c translated to run the ctypes tests can be used to run the pyglet examples as well. They can be run like e.g.:: $ cd pyglet/ - $ PYTHONPATH=. ../ctypes-stable/pypy/translator/goal/pypy-c examples/opengl.py + $ PYTHONPATH=. ../ctypes-stable/pypy/goal/pypy-c examples/opengl.py they usually should be terminated with ctrl-c. Refer to the their doc strings for details about how they should behave. diff --git a/pypy/doc/discussion/improve-rpython.rst b/pypy/doc/discussion/improve-rpython.rst --- a/pypy/doc/discussion/improve-rpython.rst +++ b/pypy/doc/discussion/improve-rpython.rst @@ -15,7 +15,7 @@ from pypy.interpreter.typedef import interp_attrproperty, interp_attrproperty_w from pypy.interpreter.gateway import interp2app from pypy.interpreter.error import OperationError - from pypy.rpython.lltypesystem import rffi, lltype + from rpython.rtyper.lltypesystem import rffi, lltype - A more direct declarative way to write Typedef:: diff --git a/pypy/doc/faq.rst b/pypy/doc/faq.rst --- a/pypy/doc/faq.rst +++ b/pypy/doc/faq.rst @@ -300,12 +300,26 @@ Do I have to rewrite my programs in RPython? -------------------------------------------- -No. And you shouldn't try. PyPy always runs your code in its own interpreter, which is a -full and compliant Python 2.7 interpreter. RPython is only the -language in which parts of PyPy itself are written and extension -modules for it. Not only is it not necessary for you to rewrite your -code in RPython, it probably won't give you any speed improvements if you -try. +No. And you shouldn't try. First and foremost, RPython is a language +that is designed to write interpreters in. It is a restricted subset of +Python. If you program is not an interpreter but tries to do "real +things", like use *any* part of the standard Python library or *any* +3rd-party library, then it is not RPython to start with. You should +only look at RPython if you try to `write your own interpreter`__. + +.. __: `how do I compile my own interpreters`_ + +If your goal is to speed up Python code, then look at the regular PyPy, +which is a full and compliant Python 2.7 interpreter (which happens to +be written in RPython). Not only is it not necessary for you to rewrite +your code in RPython, it might not give you any speed improvements even +if you manage to. + +Yes, it is possible with enough effort to compile small self-contained +pieces of RPython code doing a few performance-sensitive things. But +this case is not interesting for us. If you needed to rewrite the code +in RPython, you could as well have rewritten it in C for example. The +latter is a much more supported, much more documented language `:-)` --------------------------------------------------- Which backends are there for the RPython toolchain? diff --git a/pypy/doc/getting-started-dev.rst b/pypy/doc/getting-started-dev.rst --- a/pypy/doc/getting-started-dev.rst +++ b/pypy/doc/getting-started-dev.rst @@ -24,7 +24,7 @@ python bin/translatorshell.py Test snippets of translatable code are provided in the file -``pypy/translator/test/snippet.py``, which is imported under the name +``rpython/translator/test/snippet.py``, which is imported under the name ``snippet``. For example:: >>> t = Translation(snippet.is_perfect_number, [int]) @@ -52,16 +52,18 @@ The graph can be turned into C code:: >>> t.rtype() - >>> f = t.compile_c() + >>> lib = t.compile_c() The first command replaces the operations with other low level versions that -only use low level types that are available in C (e.g. int). To try out the -compiled version:: +only use low level types that are available in C (e.g. int). The compiled +version is now in a ``.so`` library. You can run it say using ctypes: + >>> from ctypes import CDLL + >>> f = CDLL(lib) >>> f(5) - False + 0 >>> f(6) - True + 1 Translating the flow graph to CLI or JVM code +++++++++++++++++++++++++++++++++++++++++++++ @@ -108,7 +110,7 @@ There is a small-to-medium demo showing the translator and the annotator:: cd demo - ../pypy/translator/goal/translate.py --view --annotate bpnn.py + ../rpython/translator/goal/translate.py --view --annotate bpnn.py This causes ``bpnn.py`` to display itself as a call graph and class hierarchy. Clicking on functions shows the flow graph of the particular @@ -119,17 +121,17 @@ To turn this example to C code (compiled to the executable ``bpnn-c``), type simply:: - ../pypy/translator/goal/translate.py bpnn.py + ../rpython/translator/goal/translate.py bpnn.py Translating Full Programs +++++++++++++++++++++++++ To translate full RPython programs, there is the script ``translate.py`` in -``translator/goal``. Examples for this are a slightly changed version of +``rpython/translator/goal``. Examples for this are a slightly changed version of Pystone:: - cd pypy/translator/goal + cd rpython/translator/goal python translate.py targetrpystonedalone This will produce the executable "targetrpystonedalone-c". diff --git a/pypy/doc/getting-started.rst b/pypy/doc/getting-started.rst --- a/pypy/doc/getting-started.rst +++ b/pypy/doc/getting-started.rst @@ -1,10 +1,10 @@ ================================== -Getting Started +Getting Started ================================== .. contents:: -.. _howtopypy: +.. _howtopypy: What is PyPy ? ============== @@ -33,8 +33,8 @@ .. _`RPython translation toolchain`: translation.html .. _`more...`: architecture.html -Just the facts -============== +Just the facts +============== Download a pre-built PyPy ------------------------- @@ -125,7 +125,7 @@ ``pypy/pypy`` and documentation files in ``pypy/pypy/doc``. We try to ensure that the tip is always stable, but it might occasionally be broken. You may want to check out `our nightly tests:`_ -find a revision (12-chars alphanumeric string, e.g. "963e808156b3") +find a revision (12-chars alphanumeric string, e.g. "963e808156b3") that passed at least the ``{linux32}`` tests (corresponding to a ``+`` sign on the line ``success``) and then, in your cloned repository, switch to this revision @@ -159,24 +159,24 @@ Understanding PyPy's architecture --------------------------------- -For in-depth information about architecture and coding documentation -head over to the `documentation section`_ where you'll find lots of -interesting information. Additionally, in true hacker spirit, you -may just `start reading sources`_ . +For in-depth information about architecture and coding documentation +head over to the `documentation section`_ where you'll find lots of +interesting information. Additionally, in true hacker spirit, you +may just `start reading sources`_ . .. _`documentation section`: index.html#project-documentation .. _`start reading sources`: getting-started-dev.html#start-reading-sources -Filing bugs or feature requests +Filing bugs or feature requests ------------------------------- You may file `bug reports`_ on our issue tracker which is -also accessible through the 'issues' top menu of -the PyPy website. `Using the development tracker`_ has -more detailed information on specific features of the tracker. +also accessible through the 'issues' top menu of +the PyPy website. `Using the development tracker`_ has +more detailed information on specific features of the tracker. .. _`Using the development tracker`: coding-guide.html#using-development-tracker -.. _bug reports: https://codespeak.net/issue/pypy-dev/ +.. _bug reports: https://bugs.pypy.org/ .. include:: _ref.txt diff --git a/pypy/doc/index.rst b/pypy/doc/index.rst --- a/pypy/doc/index.rst +++ b/pypy/doc/index.rst @@ -220,9 +220,8 @@ ================================ =========================================== Directory explanation/links ================================ =========================================== -`pypy/annotation/`_ `type inferencing code`_ for `RPython`_ programs -`pypy/bin/`_ command-line scripts, mainly `py.py`_ and `translatorshell.py`_ +`pypy/bin/`_ command-line scripts, mainly `pyinteractive.py`_ `pypy/config/`_ handles the numerous options for building and running PyPy @@ -249,20 +248,8 @@ `pypy/objspace/`_ `object space`_ implementations -`pypy/objspace/flow/`_ the FlowObjSpace_ implementing `abstract interpretation`_ - `pypy/objspace/std/`_ the StdObjSpace_ implementing CPython's objects and types -`pypy/rlib/`_ a `"standard library"`_ for RPython_ programs - -`pypy/rpython/`_ the `RPython Typer`_ - -`pypy/rpython/lltypesystem/`_ the `low-level type system`_ for C-like backends - -`pypy/rpython/ootypesystem/`_ the `object-oriented type system`_ for OO backends - -`pypy/rpython/memory/`_ the `garbage collector`_ construction framework - `pypy/tool/`_ various utilities and hacks used from various places `pypy/tool/algo/`_ general-purpose algorithmic and mathematic @@ -270,20 +257,39 @@ `pypy/tool/pytest/`_ support code for our `testing methods`_ -`pypy/translator/`_ translation_ backends and support code -`pypy/translator/backendopt/`_ general optimizations that run before a backend generates code +`rpython/annotator/`_ `type inferencing code`_ for `RPython`_ programs -`pypy/translator/c/`_ the `GenC backend`_, producing C code from an +`rpython/config/`_ handles the numerous options for RPython + + +`rpython/flowspace/`_ the FlowObjSpace_ implementing `abstract interpretation`_ + + +`rpython/rlib/`_ a `"standard library"`_ for RPython_ programs + +`rpython/rtyper/`_ the `RPython Typer`_ + +`rpython/rtyper/lltypesystem/`_ the `low-level type system`_ for C-like backends + +`rpython/rtyper/ootypesystem/`_ the `object-oriented type system`_ for OO backends + +`rpython/rtyper/memory/`_ the `garbage collector`_ construction framework + +`rpython/translator/`_ translation_ backends and support code + +`rpython/translator/backendopt/`_ general optimizations that run before a backend generates code + +`rpython/translator/c/`_ the `GenC backend`_, producing C code from an RPython program (generally via the rtyper_) -`pypy/translator/cli/`_ the `CLI backend`_ for `.NET`_ (Microsoft CLR or Mono_) +`rpython/translator/cli/`_ the `CLI backend`_ for `.NET`_ (Microsoft CLR or Mono_) -`pypy/translator/goal/`_ our `main PyPy-translation scripts`_ live here +`pypy/goal/`_ our `main PyPy-translation scripts`_ live here -`pypy/translator/jvm/`_ the Java backend +`rpython/translator/jvm/`_ the Java backend -`pypy/translator/tool/`_ helper tools for translation, including the Pygame +`rpython/translator/tool/`_ helper tools for translation, including the Pygame `graph viewer`_ ``*/test/`` many directories have a test subdirectory containing test diff --git a/pypy/doc/rffi.rst b/pypy/doc/rffi.rst --- a/pypy/doc/rffi.rst +++ b/pypy/doc/rffi.rst @@ -17,7 +17,7 @@ lltype.Signed or lltype.Array) and memory management must be done by hand. To declare a function, we write:: - from pypy.rpython.lltypesystem import rffi + from rpython.rtyper.lltypesystem import rffi external_function = rffi.llexternal(name, args, result) @@ -31,7 +31,7 @@ libraries and sources by passing in the optional ``compilation_info`` parameter:: - from pypy.rpython.lltypesystem import rffi + from rpython.rtyper.lltypesystem import rffi from rpython.translator.tool.cbuild import ExternalCompilationInfo info = ExternalCompilationInfo(includes=[], libraries=[]) diff --git a/pypy/doc/sandbox.rst b/pypy/doc/sandbox.rst --- a/pypy/doc/sandbox.rst +++ b/pypy/doc/sandbox.rst @@ -87,15 +87,15 @@ ----- -In pypy/translator/goal:: +In pypy/goal:: - ./translate.py -O2 --sandbox targetpypystandalone.py + ../../rpython/bin/rpython -O2 --sandbox targetpypystandalone.py If you don't have a regular PyPy installed, you should, because it's faster to translate, but you can also run ``python translate.py`` instead. -To run it, use the tools in the pypy/translator/sandbox directory:: +To run it, use the tools in the pypy/sandbox directory:: ./pypy_interact.py /some/path/pypy-c-sandbox [args...] diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst --- a/pypy/doc/whatsnew-head.rst +++ b/pypy/doc/whatsnew-head.rst @@ -34,6 +34,10 @@ .. branch: kill-faking .. branch: improved_ebnfparse_error .. branch: task-decorator +.. branch: fix-e4fa0b2 +.. branch: win32-fixes +.. branch: fix-version-tool +.. branch: popen2-removal .. branch: release-2.0-beta1 @@ -47,3 +51,6 @@ .. branch: inline-virtualref-2 Better optimized certain types of frame accesses in the JIT, particularly around exceptions that escape the function they were raised in. + +.. branch: missing-ndarray-attributes +Some missing attributes from ndarrays diff --git a/pypy/interpreter/app_main.py b/pypy/interpreter/app_main.py --- a/pypy/interpreter/app_main.py +++ b/pypy/interpreter/app_main.py @@ -436,11 +436,14 @@ # (relevant in case of "reload(sys)") sys.argv[:] = argv - if PYTHON26 and not options["ignore_environment"]: - if os.getenv('PYTHONNOUSERSITE'): - options["no_user_site"] = 1 - if os.getenv('PYTHONDONTWRITEBYTECODE'): - options["dont_write_bytecode"] = 1 + if not options["ignore_environment"]: + if os.getenv('PYTHONUNBUFFERED'): + options["unbuffered"] = 1 + if PYTHON26: + if os.getenv('PYTHONNOUSERSITE'): + options["no_user_site"] = 1 + if os.getenv('PYTHONDONTWRITEBYTECODE'): + options["dont_write_bytecode"] = 1 if (options["interactive"] or (not options["ignore_environment"] and os.getenv('PYTHONINSPECT'))): @@ -713,13 +716,13 @@ def pypy_find_stdlib(s): from os.path import abspath, join, dirname as dn thisfile = abspath(__file__) - root = dn(dn(dn(dn(thisfile)))) + root = dn(dn(dn(thisfile))) return [join(root, 'lib-python', '2.7'), join(root, 'lib_pypy')] - + def pypy_resolvedirof(s): # we ignore the issue of symlinks; for tests, the executable is always - # translator/goal/app_main.py anyway + # interpreter/app_main.py anyway import os return os.path.abspath(os.path.join(s, '..')) @@ -756,6 +759,10 @@ del os # make sure that os is not available globally, because this is what # happens in "real life" outside the tests + if 'time' not in sys.builtin_module_names: + # make some tests happy by loading this before we clobber sys.path + import time; del time + # no one should change to which lists sys.argv and sys.path are bound old_argv = sys.argv old_path = sys.path diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -1482,9 +1482,10 @@ ) raise w_fd = self.call_function(w_fileno) - if not self.isinstance_w(w_fd, self.w_int): + if (not self.isinstance_w(w_fd, self.w_int) and + not self.isinstance_w(w_fd, self.w_long)): raise OperationError(self.w_TypeError, - self.wrap("fileno() must return an integer") + self.wrap("fileno() returned a non-integer") ) fd = self.int_w(w_fd) if fd < 0: diff --git a/pypy/interpreter/executioncontext.py b/pypy/interpreter/executioncontext.py --- a/pypy/interpreter/executioncontext.py +++ b/pypy/interpreter/executioncontext.py @@ -40,6 +40,7 @@ def gettopframe(self): return self.topframeref() + @jit.unroll_safe def gettopframe_nohidden(self): frame = self.topframeref() while frame and frame.hide(): @@ -343,9 +344,13 @@ signal, the tick counter is set to -1 by C code in signals.h. """ assert isinstance(action, PeriodicAsyncAction) - self._periodic_actions.append(action) + # hack to put the release-the-GIL one at the end of the list, + # and the report-the-signals one at the start of the list. if use_bytecode_counter: + self._periodic_actions.append(action) self.has_bytecode_counter = True + else: + self._periodic_actions.insert(0, action) self._rebuild_action_dispatcher() def getcheckinterval(self): @@ -419,15 +424,6 @@ The action must have been registered at space initalization time.""" self.space.actionflag.fire(self) - def fire_after_thread_switch(self): - """Bit of a hack: fire() the action but only the next time the GIL - is released and re-acquired (i.e. after a potential thread switch). - Don't call this if threads are not enabled. Currently limited to - one action (i.e. reserved for CheckSignalAction from module/signal). - """ - from pypy.module.thread.gil import spacestate - spacestate.action_after_thread_switch = self - def perform(self, executioncontext, frame): """To be overridden.""" diff --git a/pypy/interpreter/miscutils.py b/pypy/interpreter/miscutils.py --- a/pypy/interpreter/miscutils.py +++ b/pypy/interpreter/miscutils.py @@ -17,9 +17,8 @@ def setvalue(self, value): self._value = value - def getmainthreadvalue(self): - return self._value + def ismainthread(self): + return True def getallvalues(self): return {0: self._value} - diff --git a/pypy/interpreter/pytraceback.py b/pypy/interpreter/pytraceback.py --- a/pypy/interpreter/pytraceback.py +++ b/pypy/interpreter/pytraceback.py @@ -1,5 +1,6 @@ from pypy.interpreter import baseobjspace from pypy.interpreter.error import OperationError + from rpython.tool.error import offset2lineno @@ -27,10 +28,10 @@ def descr__reduce__(self, space): from pypy.interpreter.mixedmodule import MixedModule - w_mod = space.getbuiltinmodule('_pickle_support') - mod = space.interp_w(MixedModule, w_mod) + w_mod = space.getbuiltinmodule('_pickle_support') + mod = space.interp_w(MixedModule, w_mod) new_inst = mod.get('traceback_new') - w = space.wrap + w = space.wrap tup_base = [] tup_state = [ @@ -49,6 +50,7 @@ self.lasti = space.int_w(w_lasti) self.next = space.interp_w(PyTraceback, w_next, can_be_None=True) + def record_application_traceback(space, operror, frame, last_instruction): if frame.pycode.hidden_applevel: return @@ -56,10 +58,11 @@ tb = PyTraceback(space, frame, last_instruction, tb) operror.set_traceback(tb) + def check_traceback(space, w_tb, msg): from pypy.interpreter.typedef import PyTraceback tb = space.interpclass_w(w_tb) - if tb is None or not space.is_true(space.isinstance(tb, + if tb is None or not space.is_true(space.isinstance(tb, space.gettypeobject(PyTraceback.typedef))): raise OperationError(space.w_TypeError, space.wrap(msg)) return tb diff --git a/pypy/interpreter/test2/test_app_main.py b/pypy/interpreter/test2/test_app_main.py --- a/pypy/interpreter/test2/test_app_main.py +++ b/pypy/interpreter/test2/test_app_main.py @@ -547,7 +547,7 @@ assert line.rstrip() == 'Not at all. They could be carried.' print 'A five ounce bird could not carry a one pound coconut.' """) - py_py = os.path.join(pypydir, 'bin', 'py.py') + py_py = os.path.join(pypydir, 'bin', 'pyinteractive.py') child = self._spawn(sys.executable, [py_py, '-S', path]) child.expect('Are you suggesting coconuts migrate?', timeout=120) child.sendline('Not at all. They could be carried.') @@ -712,6 +712,26 @@ assert data == '\x00(STDOUT)\n\x00' # from stdout child_out_err.close() + def test_non_interactive_stdout_unbuffered(self, monkeypatch): + monkeypatch.setenv('PYTHONUNBUFFERED', '1') + path = getscript(r""" + import sys, time + sys.stdout.write('\x00(STDOUT)\n\x00') + time.sleep(1) + sys.stderr.write('\x00[STDERR]\n\x00') + time.sleep(1) + # stdout flushed automatically here + """) + cmdline = '%s -E "%s" %s' % (sys.executable, app_main, path) + print 'POPEN:', cmdline + child_in, child_out_err = os.popen4(cmdline) + data = child_out_err.read(11) + assert data == '\x00(STDOUT)\n\x00' # from stderr + data = child_out_err.read(11) + assert data == '\x00[STDERR]\n\x00' # from stdout + child_out_err.close() + child_in.close() + def test_proper_sys_path(self, tmpdir): data = self.run('-c "import _ctypes"', python_flags='-S') if data.startswith('Traceback'): @@ -774,7 +794,7 @@ assert data == p + os.sep + '\n' def test_getfilesystemencoding(self): - py.test.skip("this has been failing since forever, but it's not tested nightly because buildbot uses python2.6 :-(") + py.test.skip("encoding is only set if stdout.isatty(), test is flawed") if sys.version_info < (2, 7): skip("test requires Python >= 2.7") p = getscript_in_dir(""" @@ -881,7 +901,6 @@ def test_setup_bootstrap_path(self): import sys - import os old_sys_path = sys.path[:] sys.path.append(self.goal_dir) try: @@ -907,7 +926,7 @@ sys.path.append(self.goal_dir) try: import app_main - pypy_c = os.path.join(self.trunkdir, 'pypy', 'translator', 'goal', 'pypy-c') + pypy_c = os.path.join(self.trunkdir, 'pypy', 'goal', 'pypy-c') app_main.setup_bootstrap_path(pypy_c) newpath = sys.path[:] # we get at least lib_pypy @@ -925,7 +944,7 @@ sys.path.append(self.goal_dir) try: import app_main - pypy_c = os.path.join(self.trunkdir, 'pypy', 'translator', 'goal', 'pypy-c') + pypy_c = os.path.join(self.trunkdir, 'pypy', 'goal', 'pypy-c') app_main.entry_point(pypy_c, [self.foo_py]) # assert it did not crash finally: diff --git a/pypy/interpreter/test2/test_targetpypy.py b/pypy/interpreter/test2/test_targetpypy.py --- a/pypy/interpreter/test2/test_targetpypy.py +++ b/pypy/interpreter/test2/test_targetpypy.py @@ -1,5 +1,3 @@ - -import py from pypy.goal.targetpypystandalone import get_entry_point from pypy.config.pypyoption import get_pypy_config @@ -7,6 +5,4 @@ def test_run(self): config = get_pypy_config(translating=False) entry_point = get_entry_point(config)[0] - space = self.space - py.test.skip("not working so far") entry_point(['pypy-c' , '-S', '-c', 'print 3']) diff --git a/pypy/interpreter/typedef.py b/pypy/interpreter/typedef.py --- a/pypy/interpreter/typedef.py +++ b/pypy/interpreter/typedef.py @@ -1,18 +1,17 @@ -""" +import py - -""" -import py -from pypy.interpreter.gateway import interp2app, BuiltinCode, unwrap_spec,\ - WrappedDefault from pypy.interpreter.argument import Arguments from pypy.interpreter.baseobjspace import Wrappable, DescrMismatch from pypy.interpreter.error import OperationError, operationerrfmt +from pypy.interpreter.gateway import (interp2app, BuiltinCode, unwrap_spec, + WrappedDefault) + +from rpython.rlib.jit import promote +from rpython.rlib.objectmodel import compute_identity_hash, specialize from rpython.tool.sourcetools import compile2, func_with_new_name -from rpython.rlib.objectmodel import instantiate, compute_identity_hash, specialize -from rpython.rlib.jit import promote -class TypeDef: + +class TypeDef(object): def __init__(self, __name, __base=None, __total_ordering__=None, **rawdict): "NOT_RPYTHON: initialization-time only" self.name = __name @@ -27,7 +26,7 @@ self.weakrefable = '__weakref__' in rawdict self.doc = rawdict.pop('__doc__', None) for base in bases: - self.hasdict |= base.hasdict + self.hasdict |= base.hasdict self.weakrefable |= base.weakrefable self.rawdict = {} self.acceptable_as_base_class = '__new__' in rawdict @@ -426,7 +425,7 @@ return unknown_objclass_getter, cls miniglobals = {} if isinstance(cls, str): - assert cls.startswith('<'),"pythontype typecheck should begin with <" + assert cls.startswith('<'), "pythontype typecheck should begin with <" cls_name = cls[1:] typeexpr = "space.w_%s" % cls_name else: @@ -474,7 +473,7 @@ else: try: return self.fget(self, space, w_obj) - except DescrMismatch, e: + except DescrMismatch: return w_obj.descr_call_mismatch( space, '__getattribute__', self.reqcls, Arguments(space, [w_obj, @@ -489,7 +488,7 @@ space.wrap("readonly attribute")) try: fset(self, space, w_obj, w_value) - except DescrMismatch, e: + except DescrMismatch: w_obj.descr_call_mismatch( space, '__setattr__', self.reqcls, Arguments(space, [w_obj, @@ -505,7 +504,7 @@ space.wrap("cannot delete attribute")) try: fdel(self, space, w_obj) - except DescrMismatch, e: + except DescrMismatch: w_obj.descr_call_mismatch( space, '__delattr__', self.reqcls, Arguments(space, [w_obj, @@ -546,6 +545,7 @@ class Member(Wrappable): """For slots.""" _immutable_ = True + def __init__(self, index, name, w_cls): self.index = index self.name = name @@ -617,9 +617,8 @@ from pypy.interpreter.pyframe import PyFrame from pypy.interpreter.pyopcode import SuspendedUnroller from pypy.interpreter.module import Module -from pypy.interpreter.function import Function, Method, StaticMethod -from pypy.interpreter.function import ClassMethod -from pypy.interpreter.function import BuiltinFunction, descr_function_get +from pypy.interpreter.function import (Function, Method, StaticMethod, + ClassMethod, BuiltinFunction, descr_function_get) from pypy.interpreter.pytraceback import PyTraceback from pypy.interpreter.generator import GeneratorIterator from pypy.interpreter.nestedscope import Cell @@ -663,8 +662,10 @@ def fget_co_flags(space, code): # unwrapping through unwrap_spec sig = code.signature() flags = 0 - if sig.has_vararg(): flags |= CO_VARARGS - if sig.has_kwarg(): flags |= CO_VARKEYWORDS + if sig.has_vararg(): + flags |= CO_VARARGS + if sig.has_kwarg(): + flags |= CO_VARKEYWORDS return space.wrap(flags) def fget_co_consts(space, code): # unwrapping through unwrap_spec @@ -728,7 +729,7 @@ __eq__ = interp2app(PyCode.descr_code__eq__), __ne__ = descr_generic_ne, __hash__ = interp2app(PyCode.descr_code__hash__), - __reduce__ = interp2app(PyCode.descr__reduce__), + __reduce__ = interp2app(PyCode.descr__reduce__), __repr__ = interp2app(PyCode.repr), co_argcount = interp_attrproperty('co_argcount', cls=PyCode), co_nlocals = interp_attrproperty('co_nlocals', cls=PyCode), @@ -737,9 +738,9 @@ co_code = interp_attrproperty('co_code', cls=PyCode), co_consts = GetSetProperty(PyCode.fget_co_consts), co_names = GetSetProperty(PyCode.fget_co_names), - co_varnames = GetSetProperty(PyCode.fget_co_varnames), - co_freevars = GetSetProperty(PyCode.fget_co_freevars), - co_cellvars = GetSetProperty(PyCode.fget_co_cellvars), + co_varnames = GetSetProperty(PyCode.fget_co_varnames), + co_freevars = GetSetProperty(PyCode.fget_co_freevars), + co_cellvars = GetSetProperty(PyCode.fget_co_cellvars), co_filename = interp_attrproperty('co_filename', cls=PyCode), co_name = interp_attrproperty('co_name', cls=PyCode), co_firstlineno = interp_attrproperty('co_firstlineno', cls=PyCode), @@ -749,7 +750,7 @@ PyCode.typedef.acceptable_as_base_class = False PyFrame.typedef = TypeDef('frame', - __reduce__ = interp2app(PyFrame.descr__reduce__), + __reduce__ = interp2app(PyFrame.descr__reduce__), __setstate__ = interp2app(PyFrame.descr__setstate__), f_builtins = GetSetProperty(PyFrame.fget_f_builtins), f_lineno = GetSetProperty(PyFrame.fget_f_lineno, PyFrame.fset_f_lineno), @@ -827,9 +828,9 @@ __new__ = interp2app(Method.descr_method__new__.im_func), __call__ = interp2app(Method.descr_method_call), __get__ = interp2app(Method.descr_method_get), - im_func = interp_attrproperty_w('w_function', cls=Method), + im_func = interp_attrproperty_w('w_function', cls=Method), __func__ = interp_attrproperty_w('w_function', cls=Method), - im_self = interp_attrproperty_w('w_instance', cls=Method), + im_self = interp_attrproperty_w('w_instance', cls=Method), __self__ = interp_attrproperty_w('w_instance', cls=Method), im_class = interp_attrproperty_w('w_class', cls=Method), __getattribute__ = interp2app(Method.descr_method_getattribute), @@ -886,7 +887,7 @@ def always_none(self, obj): return None -BuiltinFunction.typedef = TypeDef("builtin_function",**Function.typedef.rawdict) +BuiltinFunction.typedef = TypeDef("builtin_function", **Function.typedef.rawdict) BuiltinFunction.typedef.rawdict.update({ '__new__': interp2app(BuiltinFunction.descr_builtinfunction__new__.im_func), '__self__': GetSetProperty(always_none, cls=BuiltinFunction), From noreply at buildbot.pypy.org Fri Feb 8 09:32:59 2013 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 8 Feb 2013 09:32:59 +0100 (CET) Subject: [pypy-commit] pypy default: Fix 2.6 compatibility Message-ID: <20130208083259.C7E881C0110@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r60958:9aafa03d6994 Date: 2013-02-08 10:32 +0200 http://bitbucket.org/pypy/pypy/changeset/9aafa03d6994/ Log: Fix 2.6 compatibility diff --git a/rpython/annotator/description.py b/rpython/annotator/description.py --- a/rpython/annotator/description.py +++ b/rpython/annotator/description.py @@ -497,8 +497,8 @@ # will do the right thing in s_get_value(). if isinstance(value, staticmethod) and mixin: # make a new copy of staticmethod - value = staticmethod(func_with_new_name(value.__func__, - value.__func__.__name__)) + func = value.__get__(42) + value = staticmethod(func_with_new_name(func, func.__name__)) if type(value) in MemberDescriptorTypes: # skip __slots__, showing up in the class as 'member' objects From noreply at buildbot.pypy.org Fri Feb 8 09:50:08 2013 From: noreply at buildbot.pypy.org (mattip) Date: Fri, 8 Feb 2013 09:50:08 +0100 (CET) Subject: [pypy-commit] pypy python-numpy: merge pre-split default into branch Message-ID: <20130208085008.295941C02D9@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: python-numpy Changeset: r60959:35f4c189e3c9 Date: 2013-02-08 10:20 +0200 http://bitbucket.org/pypy/pypy/changeset/35f4c189e3c9/ Log: merge pre-split default into branch diff too long, truncating to 2000 out of 62395 lines diff --git a/.hgtags b/.hgtags --- a/.hgtags +++ b/.hgtags @@ -2,3 +2,4 @@ b48df0bf4e75b81d98f19ce89d4a7dc3e1dab5e5 benchmarked d8ac7d23d3ec5f9a0fa1264972f74a010dbfd07f release-1.6 ff4af8f318821f7f5ca998613a60fca09aa137da release-1.7 +07e08e9c885ca67d89bcc304e45a32346daea2fa release-2.0-beta-1 diff --git a/LICENSE b/LICENSE --- a/LICENSE +++ b/LICENSE @@ -1,9 +1,10 @@ -License for files in the pypy/ directory -================================================== +License +======= Except when otherwise stated (look for LICENSE files in directories or information at the beginning of each file) all software and -documentation in the 'pypy' directories is licensed as follows: +documentation in the 'pypy', 'ctype_configure', 'dotviewer', 'demo', +and 'lib_pypy' directories is licensed as follows: The MIT License @@ -27,7 +28,7 @@ DEALINGS IN THE SOFTWARE. -PyPy Copyright holders 2003-2012 +PyPy Copyright holders 2003-2013 ----------------------------------- Except when otherwise stated (look for LICENSE files or information at diff --git a/README b/README deleted file mode 100644 --- a/README +++ /dev/null @@ -1,24 +0,0 @@ -===================================== -PyPy: Python in Python Implementation -===================================== - -Welcome to PyPy! - -PyPy is both an implementation of the Python programming language, and -an extensive compiler framework for dynamic language implementations. -You can build self-contained Python implementations which execute -independently from CPython. - -The home page is: - - http://pypy.org/ - -The getting-started document will help guide you: - - http://doc.pypy.org/en/latest/getting-started.html - -It will also point you to the rest of the documentation which is generated -from files in the pypy/doc directory within the source repositories. Enjoy -and send us feedback! - - the pypy-dev team diff --git a/README.rst b/README.rst new file mode 100644 --- /dev/null +++ b/README.rst @@ -0,0 +1,24 @@ +===================================== +PyPy: Python in Python Implementation +===================================== + +Welcome to PyPy! + +PyPy is both an implementation of the Python programming language, and +an extensive compiler framework for dynamic language implementations. +You can build self-contained Python implementations which execute +independently from CPython. + +The home page is: + + http://pypy.org/ + +The getting-started document will help guide you: + + http://doc.pypy.org/en/latest/getting-started.html + +It will also point you to the rest of the documentation which is generated +from files in the pypy/doc directory within the source repositories. Enjoy +and send us feedback! + + the pypy-dev team diff --git a/demo/autopath.py b/demo/autopath.py deleted file mode 100644 --- a/demo/autopath.py +++ /dev/null @@ -1,2 +0,0 @@ -import sys, os -sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) diff --git a/demo/bpnn.py b/demo/bpnn.py deleted file mode 100755 --- a/demo/bpnn.py +++ /dev/null @@ -1,214 +0,0 @@ -#!/usr/bin/env python -""" - Translator Demo - - To analyse and type-annotate the functions and class defined in - this module, starting from the entry point function demo(), - use the following command line: - - ../pypy/translator/goal/translate.py bpnn.py - - Insert '--help' before 'bpnn.py' for a list of translation options, - or see the Overview of Command Line Options for translation at - http://codespeak.net/pypy/dist/pypy/doc/config/commandline.html -""" -# Back-Propagation Neural Networks -# -# Written in Python. See http://www.python.org/ -# -# Neil Schemenauer -# -# Modifications to the original (Armin Rigo): -# * import random from PyPy's lib, which is Python 2.2's plain -# Python implementation -# * print a doc about how to start the Translator - -import sys -import math -import time - -import autopath -from pypy.rlib import rrandom - -PRINT_IT = True - -random = rrandom.Random(1) - -# calculate a random number where: a <= rand < b -def rand(a, b): - return (b-a)*random.random() + a - -# Make a matrix (we could use NumPy to speed this up) -def makeMatrix(I, J, fill=0.0): - m = [] - for i in range(I): - m.append([fill]*J) - return m - -class NN: - - def __init__(self, ni, nh, no): - # number of input, hidden, and output nodes - self.ni = ni + 1 # +1 for bias node - self.nh = nh - self.no = no - - # activations for nodes - self.ai = [1.0]*self.ni - self.ah = [1.0]*self.nh - self.ao = [1.0]*self.no - - # create weights - self.wi = makeMatrix(self.ni, self.nh) - self.wo = makeMatrix(self.nh, self.no) - # set them to random vaules - for i in range(self.ni): - for j in range(self.nh): - self.wi[i][j] = rand(-2.0, 2.0) - for j in range(self.nh): - for k in range(self.no): - self.wo[j][k] = rand(-2.0, 2.0) - - # last change in weights for momentum - self.ci = makeMatrix(self.ni, self.nh) - self.co = makeMatrix(self.nh, self.no) - - def update(self, inputs): - if len(inputs) != self.ni-1: - raise ValueError, 'wrong number of inputs' - - # input activations - for i in range(self.ni-1): - #self.ai[i] = 1.0/(1.0+math.exp(-inputs[i])) - self.ai[i] = inputs[i] - - # hidden activations - for j in range(self.nh): - sum = 0.0 - for i in range(self.ni): - sum = sum + self.ai[i] * self.wi[i][j] - self.ah[j] = 1.0/(1.0+math.exp(-sum)) - - # output activations - for k in range(self.no): - sum = 0.0 - for j in range(self.nh): - sum = sum + self.ah[j] * self.wo[j][k] - self.ao[k] = 1.0/(1.0+math.exp(-sum)) - - return self.ao[:] - - - def backPropagate(self, targets, N, M): - if len(targets) != self.no: - raise ValueError, 'wrong number of target values' - - # calculate error terms for output - output_deltas = [0.0] * self.no - for k in range(self.no): - ao = self.ao[k] - output_deltas[k] = ao*(1-ao)*(targets[k]-ao) - - # calculate error terms for hidden - hidden_deltas = [0.0] * self.nh - for j in range(self.nh): - sum = 0.0 - for k in range(self.no): - sum = sum + output_deltas[k]*self.wo[j][k] - hidden_deltas[j] = self.ah[j]*(1-self.ah[j])*sum - - # update output weights - for j in range(self.nh): - for k in range(self.no): - change = output_deltas[k]*self.ah[j] - self.wo[j][k] = self.wo[j][k] + N*change + M*self.co[j][k] - self.co[j][k] = change - #print N*change, M*self.co[j][k] - - # update input weights - for i in range(self.ni): - for j in range(self.nh): - change = hidden_deltas[j]*self.ai[i] - self.wi[i][j] = self.wi[i][j] + N*change + M*self.ci[i][j] - self.ci[i][j] = change - - # calculate error - error = 0.0 - for k in range(len(targets)): - delta = targets[k]-self.ao[k] - error = error + 0.5*delta*delta - return error - - - def test(self, patterns): - for p in patterns: - if PRINT_IT: - print p[0], '->', self.update(p[0]) - - def weights(self): - if PRINT_IT: - print 'Input weights:' - for i in range(self.ni): - print self.wi[i] - print - print 'Output weights:' - for j in range(self.nh): - print self.wo[j] - - def train(self, patterns, iterations=2000, N=0.5, M=0.1): - # N: learning rate - # M: momentum factor - for i in xrange(iterations): - error = 0.0 - for p in patterns: - inputs = p[0] - targets = p[1] - self.update(inputs) - error = error + self.backPropagate(targets, N, M) - if PRINT_IT and i % 100 == 0: - print 'error', error - - -def demo(): - # Teach network XOR function - pat = [ - [[0,0], [0]], - [[0,1], [1]], - [[1,0], [1]], - [[1,1], [0]] - ] - - # create a network with two input, two hidden, and two output nodes - n = NN(2, 3, 1) - # train it with some patterns - n.train(pat, 2000) - # test it - n.test(pat) - - -# __________ Entry point for stand-alone builds __________ - -import time - -def entry_point(argv): - if len(argv) > 1: - N = int(argv[1]) - else: - N = 200 - T = time.time() - for i in range(N): - demo() - t1 = time.time() - T - print "%d iterations, %s milliseconds per iteration" % (N, 1000.0*t1/N) - return 0 - -# _____ Define and setup target ___ - -def target(*args): - return entry_point, None - -if __name__ == '__main__': - if len(sys.argv) == 1: - sys.argv.append('1') - entry_point(sys.argv) - print __doc__ diff --git a/demo/dis-goal.py b/demo/dis-goal.py deleted file mode 100644 --- a/demo/dis-goal.py +++ /dev/null @@ -1,7 +0,0 @@ -""" -An old-time classical example, and one of our first goals. -To run on top of PyPy. -""" - -import dis -dis.dis(dis.dis) diff --git a/demo/distribution/client.py b/demo/distribution/client.py deleted file mode 100644 --- a/demo/distribution/client.py +++ /dev/null @@ -1,35 +0,0 @@ -""" This a sample client, suitable for use with server.py from this -directory - -run by: -pypy-c client.py -""" - -HOST = '127.0.0.1' -PORT = 12222 - -from distributed.socklayer import connect -remote_handle = connect((HOST, PORT)) - -import code -code.interact(local=locals()) - -""" Things that can be done: 1. remote object access - -x = remote_handle.x -assert type(x) is remote_handle.X # typecheck -x.meth(lambda x: x + 10, 6) # remote call, with callback localy -x.meth(remote_handle.f, 3) # remote call, remote callback -remote_handle.sys._getframe(2).f_locals['x'] # remote frame access -# XXX should be 'is x' and shouldn't need (2) argument - -# XXX next one does not work, while it should. Too much mangling with remote -# traceback frames probably -try: - x.meth(1, 2) # non-callable argument, AssertionError -except: - import sys - e, c, tb = sys.exc_info() - import pdb - pdb.post_mortem(tb) -""" diff --git a/demo/distribution/fileclient.py b/demo/distribution/fileclient.py deleted file mode 100644 --- a/demo/distribution/fileclient.py +++ /dev/null @@ -1,25 +0,0 @@ - -""" This is sample client for a server based in fileserver.py, not counting -initialization, code.interact and __doc__ has just 2 lines! Usage: - -pypy-c fileclient.py - -The file_opener is a proxy for remote file object. Which means you can -perform same operations as locally, like file_opener('/etc/passwd').read() -or file_opener('/tmp/x', 'w').write('x') - -pypy-c needs to be compiled with --allworkingmodules in order to have socket -working. -""" - -HOST = '127.0.0.1' -PORT = 12221 - -from distributed.socklayer import connect -file_opener = connect((HOST, PORT)).open - -import code -code.interact(local=locals()) -# The file_opener is a proxy for remote file object. Which means you can -# perform same operations as locally, like file_opener('/etc/passwd').read() -# or file_opener('/tmp/x', 'w').write('x') diff --git a/demo/distribution/fileserver.py b/demo/distribution/fileserver.py deleted file mode 100644 --- a/demo/distribution/fileserver.py +++ /dev/null @@ -1,19 +0,0 @@ -""" This is a sample demo showcasing file server, done by the pypy -distribution library. - -Not counting __doc__ and initialization this is 2 line, -fully operational file server, -sample client which is in fileclient.py is included as well. - -run by: -pypy-c fileserver.py - -pypy-c needs to be compiled with --allworkingmodules in order to have socket -working. -""" - -HOST = '127.0.0.1' # defaults to localhost, not to export your files -PORT = 12221 - -from distributed.socklayer import socket_loop -socket_loop((HOST, PORT), {'open':open}) diff --git a/demo/distribution/server.py b/demo/distribution/server.py deleted file mode 100644 --- a/demo/distribution/server.py +++ /dev/null @@ -1,38 +0,0 @@ -""" This is a demo exposing all globals from the current process over -socket, to be accessible remotely. - -run by: -pypy-c server.py - -pypy-c needs to be compiled with --allworkingmodules in order to have socket -working. -""" - -# things to export -# function -def f(x): - return x + 3 - -# class -class X: - def __init__(self): - self.slot = 3 - - def meth(self, f, arg): - """ Method eating callable and calling it with an argument - """ - assert callable(f) - return f(arg) - -# object -x = X() - -# module -import sys - -# constants -HOST = '127.0.0.1' -PORT = 12222 - -from distributed.socklayer import socket_loop -socket_loop((HOST, PORT), globals()) diff --git a/demo/fibonacci.py b/demo/fibonacci.py deleted file mode 100644 --- a/demo/fibonacci.py +++ /dev/null @@ -1,43 +0,0 @@ -""" -Thunk (a.k.a. lazy objects) in PyPy. -To run on top of the thunk object space with the following command-line: - - py.py -o thunk fibonacci.py - -This is a typical Functional Programming Languages demo, computing the -Fibonacci sequence by using an infinite lazy linked list. -""" - -try: - from __pypy__ import thunk # only available in 'py.py -o thunk' -except ImportError: - print __doc__ - raise SystemExit(2) - -# ____________________________________________________________ - - -class ListNode: - def __init__(self, head, tail): - self.head = head # the first element of the list - self.tail = tail # the sublist of all remaining elements - - -def add_lists(list1, list2): - """Compute the linked-list equivalent of the Python expression - [a+b for (a,b) in zip(list1,list2)] - """ - return ListNode(list1.head + list2.head, - thunk(add_lists, list1.tail, list2.tail)) - - -# 1, 1, 2, 3, 5, 8, 13, 21, 34, ... -Fibonacci = ListNode(1, ListNode(1, None)) -Fibonacci.tail.tail = thunk(add_lists, Fibonacci, Fibonacci.tail) - - -if __name__ == '__main__': - node = Fibonacci - while True: - print node.head - node = node.tail diff --git a/demo/fibonacci2.py b/demo/fibonacci2.py deleted file mode 100644 --- a/demo/fibonacci2.py +++ /dev/null @@ -1,27 +0,0 @@ -""" -Lazy functions in PyPy. -To run on top of the thunk object space with the following command-line: - - py.py -o thunk fibonacci2.py - -This is a typical Functional Programming Languages demo, computing the -Fibonacci sequence as nested 2-tuples. -""" - -import pprint - -try: - from __pypy__ import lazy -except ImportError: - print __doc__ - raise SystemExit(2) - - - at lazy -def fibo(a, b): - return (a, fibo(b, a + b)) - - -fibonacci = fibo(1, 1) - -pprint.pprint(fibonacci, depth=10) diff --git a/demo/foodbill.py b/demo/foodbill.py deleted file mode 100644 --- a/demo/foodbill.py +++ /dev/null @@ -1,59 +0,0 @@ -""" -Of historical interest: we computed the food bill of our first Gothenburg -sprint with PyPy :-) -""" - -slips=[(1, 'Kals MatMarkn', 6150, 'Chutney for Curry', 'dinner Saturday'), - (2, 'Kals MatMarkn', 32000, 'Spaghetti, Beer', 'dinner Monday'), - (2, 'Kals MatMarkn', -810, 'Deposit on Beer Bottles', 'various'), - (3, 'Fram', 7700, 'Rice and Curry Spice', 'dinner Saturday'), - (4, 'Kals MatMarkn', 25000, 'Alcohol-Free Beer, sundries', 'various'), - (4, 'Kals MatMarkn', -1570, "Michael's toothpaste", 'none'), - (4, 'Kals MatMarkn', -1690, "Laura's toothpaste", 'none'), - (4, 'Kals MatMarkn', -720, 'Deposit on Beer Bottles', 'various'), - (4, 'Kals MatMarkn', -60, 'Deposit on another Beer Bottle', 'various'), - (5, 'Kals MatMarkn', 26750, 'lunch bread meat cheese', 'lunch Monday'), - (6, 'Kals MatMarkn', 15950, 'various', 'dinner Tuesday and Thursday'), - (7, 'Kals MatMarkn', 3650, 'Drottningsylt, etc.', 'dinner Thursday'), - (8, 'Kals MatMarkn', 26150, 'Chicken and Mushroom Sauce', 'dinner Wed'), - (8, 'Kals MatMarkn', -2490, 'Jacob and Laura -- juice', 'dinner Wed'), - (8, 'Kals MatMarkn', -2990, "Chicken we didn't cook", 'dinner Wednesday'), - (9, 'Kals MatMarkn', 1380, 'fruit for Curry', 'dinner Saturday'), - (9, 'Kals MatMarkn', 1380, 'fruit for Curry', 'dinner Saturday'), - (10, 'Kals MatMarkn', 26900, 'Jansons Frestelse', 'dinner Sunday'), - (10, 'Kals MatMarkn', -540, 'Deposit on Beer Bottles', 'dinner Sunday'), - (11, 'Kals MatMarkn', 22650, 'lunch bread meat cheese', 'lunch Thursday'), - (11, 'Kals MatMarkn', -2190, 'Jacob and Laura -- juice', 'lunch Thursday'), - (11, 'Kals MatMarkn', -2790, 'Jacob and Laura -- cereal', 'lunch Thurs'), - (11, 'Kals MatMarkn', -760, 'Jacob and Laura -- milk', 'lunch Thursday'), - (12, 'Kals MatMarkn', 18850, 'lunch bread meat cheese', 'lunch Friday'), - (13, 'Kals MatMarkn', 18850, 'lunch bread meat cheese', 'guestimate Sun'), - (14, 'Kals MatMarkn', 18850, 'lunch bread meat cheese', 'guestimate Tues'), - (15, 'Kals MatMarkn', 20000, 'lunch bread meat cheese', 'guestimate Wed'), - (16, 'Kals MatMarkn', 42050, 'grillfest', 'dinner Friday'), - (16, 'Kals MatMarkn', -1350, 'Deposit on Beer Bottles', 'dinner Friday'), - (17, 'System Bolaget', 15500, 'Cederlunds Caloric', 'dinner Thursday'), - (17, 'System Bolaget', 22400, '4 x Farnese Sangiovese 56SEK', 'various'), - (17, 'System Bolaget', 22400, '4 x Farnese Sangiovese 56SEK', 'various'), - (17, 'System Bolaget', 13800, '2 x Jacobs Creek 69SEK', 'various'), - (18, 'J and Ls winecabinet', 10800, '2 x Parrotes 54SEK', 'various'), - (18, 'J and Ls winecabinet', 14700, '3 x Saint Paulin 49SEK', 'various'), - (18, 'J and Ls winecabinet', 10400, '2 x Farnese Sangioves 52SEK', - 'cheaper when we bought it'), - (18, 'J and Ls winecabinet', 17800, '2 x Le Poiane 89SEK', 'various'), - (18, 'J and Ls winecabinet', 9800, '2 x Something Else 49SEK', 'various'), - (19, 'Konsum', 26000, 'Saturday Bread and Fruit', 'Slip MISSING'), - (20, 'Konsum', 15245, 'Mooseburgers', 'found slip'), - (21, 'Kals MatMarkn', 20650, 'Grilling', 'Friday dinner'), - (22, 'J and Ls freezer', 21000, 'Meat for Curry, grilling', ''), - (22, 'J and Ls cupboard', 3000, 'Rice', ''), - (22, 'J and Ls cupboard', 4000, 'Charcoal', ''), - (23, 'Fram', 2975, 'Potatoes', '3.5 kg @ 8.50SEK'), - (23, 'Fram', 1421, 'Peas', 'Thursday dinner'), - (24, 'Kals MatMarkn', 20650, 'Grilling', 'Friday dinner'), - (24, 'Kals MatMarkn', -2990, 'TP', 'None'), - (24, 'Kals MatMarkn', -2320, 'T-Gul', 'None') - ] - -print [t[2] for t in slips] -print (reduce(lambda x, y: x+y, [t[2] for t in slips], 0))/900 diff --git a/demo/pickle_coroutine.py b/demo/pickle_coroutine.py deleted file mode 100644 --- a/demo/pickle_coroutine.py +++ /dev/null @@ -1,86 +0,0 @@ -""" -Stackless demo. - -This example only works on top of a pypy-c compiled with stackless features -and the signal module: - - translate.py --stackless targetpypystandalone --withmod-signal - -Usage: - - pypy-c pickle_coroutine.py --start demo.pickle - - Start the computation. You can interrupt it at any time by - pressing Ctrl-C; at this point, the state of the computing - coroutine is saved in demo.pickle. - - pypy-c pickle_coroutine.py --resume demo.pickle - - Reload the coroutine from demo.pickle and continue running it. - (It can be interrupted again with Ctrl-C.) - -This demo is documented in detail in pypy/doc/stackless.txt. -""" - -try: - import sys, pickle, signal - from stackless import coroutine -except ImportError: - print __doc__ - sys.exit(2) - - -def ackermann(x, y): - check() - if x == 0: - return y + 1 - if y == 0: - return ackermann(x - 1, 1) - return ackermann(x - 1, ackermann(x, y - 1)) - -# ____________________________________________________________ - -main = coroutine.getcurrent() -sys.setrecursionlimit(100000) - -interrupt_flag = False - -def interrupt_handler(*args): - global interrupt_flag - interrupt_flag = True - -def check(): - if interrupt_flag: - main.switch() - - -def execute(coro): - signal.signal(signal.SIGINT, interrupt_handler) - res = coro.switch() - if res is None and coro.is_alive: # interrupted! - print "interrupted! writing %s..." % (filename,) - f = open(filename, 'w') - pickle.dump(coro, f) - f.close() - print "done" - else: - print "result:", res - -try: - operation, filename = sys.argv[1:] -except ValueError: - print __doc__ - sys.exit(2) - -if operation == '--start': - coro = coroutine() - coro.bind(ackermann, 3, 7) - print "running from the start..." - execute(coro) -elif operation == '--resume': - print "reloading %s..." % (filename,) - f = open(filename) - coro = pickle.load(f) - f.close() - print "done, running now..." - execute(coro) diff --git a/demo/sharedref.py b/demo/sharedref.py deleted file mode 100644 --- a/demo/sharedref.py +++ /dev/null @@ -1,184 +0,0 @@ -""" - This is an example usage of the 'thunk' object space of PyPy. - It implements transparent distributed object manipulation. - - Start a server on a local port, say port 8888, with: - - $ py.py -o thunk sharedref.py 8888 - Waiting for connection on port 8888 - - Then start and connect a client from the same or another machine: - - $ py.py -o thunk sharedref.py ip_or_name:8888 - Connecting to ('...', 8888) - Ok - >>> l = [1,2,3] - >>> chan.send(l) # send the list to the server over the connexion - - On the server-side: - - Connected from ('...', 1046) - >>> l = chan.recv() # receive the list sent above - >>> l - [1, 2, 3] - >>> l.append(4) - - Back on the client-side: - - >>> l - [1, 2, 3, 4] - - The list behaves like a single distributed object, which both sides can - modify and access without needing further explicit synchronization. - There is no difference between who was the original sender or receiver of - the object, nor between which side was originally 'server' or 'client'. -""" - -import sys, marshal -from __pypy__ import thunk, become -from socket import * -from select import select - - -class Channel: - - def __init__(self, s, serverside): - # invariants: a shared object 'obj' is - # - either remote, and a thunk, and not a value in self.cache - # - or local (or at least on "our" side of this Channel), and - # then it has a corresponding key in self.cache - self.s = s - self.cache = {} - self.inputfifo = [] - self.count = int(not serverside) - -## def _check(self, obj): -## print '%s: cache=%r' % (self, self.cache.keys()), -## if is_thunk(obj): -## print 'THUNK' -## else: -## print obj - - def sendraw(self, obj): - data = marshal.dumps(obj) - hdr = str(len(data)) - hdr = '0'*(10-len(hdr)) + hdr - self.s.sendall(hdr + data) - - def _readbytes(self, count): - data = '' - while len(data) < count: - t = self.s.recv(count - len(data)) - if not t: - raise EOFError - data += t - return data - - def recvraw(self): - datasize = int(self._readbytes(10)) - data = self._readbytes(datasize) - return marshal.loads(data) - - def send(self, obj, n=None): - #print 'send', n,; self._check(obj) - if n is None: - n = self.count - self.count += 2 - data = (n, obj, None) - else: - data = (n, obj) - self.sendraw(data) - become(obj, thunk(self._resume, n)) - #print 'done', n,; self._check(obj) - - def recv(self): - obj = self.inputfifo.pop(0) - #print 'recv',; self._check(obj) - return obj - - def _resume(self, n): - #print 'resume', n,; sys.stdout.flush() - assert n not in self.cache - self.sendraw((n,)) - while n not in self.cache: - self.handle_once() - obj = self.cache[n] - #self._check(obj) - return obj - - def handle_once(self): - input = self.recvraw() - if len(input) > 1: - obj = input[1] - self.cache[input[0]] = obj - if len(input) > 2: - self.inputfifo.append(obj) - else: - n = input[0] - obj = self.cache[n] - self.send(obj, n) - del self.cache[n] - - -def mainloop(channels): - stdin = sys.stdin.fileno() - sockfd = [chan.s.fileno() for chan in channels] - while True: - sys.stdout.write('>>> ') - sys.stdout.flush() - while True: - iwtd, owtd, ewtd = select([stdin] + sockfd, [], [stdin]) - if stdin in iwtd or stdin in ewtd: break - for chan in channels: - if chan.s.fileno() in iwtd: - chan.handle_once() - code = raw_input() - if not code: break - try: - co = compile(code, '', 'single') - exec co in globals() - except Exception, e: - print e.__class__.__name__, str(e) - - -def server(port): - s = socket(AF_INET, SOCK_STREAM) - s.bind(('', port)) - s.listen(1) - print 'Waiting for connection on port', port - s, addr = s.accept() - print 'Connected from', addr - return Channel(s, True) - -def client(addr): - s = socket(AF_INET, SOCK_STREAM) - print 'Connecting to', addr - s.connect(addr) - print 'Ok' - return Channel(s, False) - - -if __name__ == '__main__': - try: - thunk, become # only available in 'py.py -o thunk' - except NameError: - print __doc__ - raise SystemExit(2) - - channels = [] - for a in sys.argv[1:]: - try: - port = int(a) - except ValueError: - host, port = a.split(':') - port = int(port) - chan = client((host, port)) - else: - chan = server(port) - channels.append(chan) - - try: - mainloop(channels) - finally: - for channel in channels: - channel.s.close() diff --git a/demo/tproxy/persistence.py b/demo/tproxy/persistence.py deleted file mode 100644 --- a/demo/tproxy/persistence.py +++ /dev/null @@ -1,62 +0,0 @@ -""" - -This small example implements a basic orthogonal persistence -mechanism on top of PyPy's transparent proxies. - -""" -from tputil import make_proxy - -list_changeops = set('__iadd__ __imul__ __delitem__ __setitem__ __setattr__' - '__delslice__ __setslice__ ' - 'append extend insert pop remove reverse sort'.split()) - -dict_changeops = set('__delitem__ __setitem__ __setattr__' - 'clear pop popitem setdefault update'.split()) - -def ischangeop(operation): - """ return True if this operation is a changing operation - on known builtins (dicts, lists). - """ - if isinstance(operation.obj, list): - changeops = list_changeops - elif isinstance(operation.obj, dict): - changeops = dict_changeops - else: - return False - return operation.opname in changeops - -def make_persistent_proxy(instance, storage): - def perform(operation): - res = operation.delegate() - if ischangeop(operation): - print "persisting after:", operation - storage.dump(instance) - if res is not operation.proxyobj and isinstance(res, (dict, list)): - res = make_proxy(perform, obj=res) - return res - return make_proxy(perform, obj=instance) - -def load(storage): - obj = storage.load() - return make_persistent_proxy(obj, storage) - -if __name__ == '__main__': - import py - storage = py.path.local("/tmp/dictpickle") - pdict = make_persistent_proxy({}, storage) - - # the code below is not aware of pdict being a proxy - assert type(pdict) is dict - pdict['hello'] = 'world' - pdict['somelist'] = [] - del pdict - - newdict = load(storage) - assert newdict == {'hello': 'world', 'somelist': []} - l = newdict['somelist'] - l.append(1) # this triggers persisting the whole dict - l.extend([2,3]) # this triggers persisting the whole dict - del newdict, l - - newdict = load(storage) - print newdict['somelist'] # will show [1,2,3] diff --git a/demo/tproxy/print_operations.py b/demo/tproxy/print_operations.py deleted file mode 100644 --- a/demo/tproxy/print_operations.py +++ /dev/null @@ -1,26 +0,0 @@ -""" - -This example transparently intercepts and shows operations on -builtin objects. Requires the "--objspace-std-withtproxy" option. - -""" - -from tputil import make_proxy - -def make_show_proxy(instance): - def controller(operation): - print "proxy sees:", operation - res = operation.delegate() - return res - tproxy = make_proxy(controller, obj=instance) - return tproxy - -if __name__ == '__main__': - mydict = make_show_proxy({}) - assert type(mydict) is dict # this looks exactly like a dict - mydict['hello'] = 'world' # will print __setitem__ - mydict[42] = 23 # will print __setitem__ - assert mydict.pop('hello') == 'world' # will print pop - assert mydict.popitem() == (42,23) # will print popitem - - diff --git a/lib-python/2.7/ctypes/test/test_internals.py b/lib-python/2.7/ctypes/test/test_internals.py --- a/lib-python/2.7/ctypes/test/test_internals.py +++ b/lib-python/2.7/ctypes/test/test_internals.py @@ -1,7 +1,10 @@ # This tests the internal _objects attribute import unittest from ctypes import * -from sys import getrefcount as grc +try: + from sys import getrefcount as grc +except ImportError: + grc = None # e.g. PyPy # XXX This test must be reviewed for correctness!!! @@ -22,6 +25,8 @@ self.assertEqual(id(a), id(b)) def test_ints(self): + if grc is None: + return unittest.skip("no sys.getrefcount()") i = 42000123 refcnt = grc(i) ci = c_int(i) @@ -29,6 +34,8 @@ self.assertEqual(ci._objects, None) def test_c_char_p(self): + if grc is None: + return unittest.skip("no sys.getrefcount()") s = "Hello, World" refcnt = grc(s) cs = c_char_p(s) diff --git a/lib-python/2.7/ctypes/test/test_memfunctions.py b/lib-python/2.7/ctypes/test/test_memfunctions.py --- a/lib-python/2.7/ctypes/test/test_memfunctions.py +++ b/lib-python/2.7/ctypes/test/test_memfunctions.py @@ -53,7 +53,8 @@ s = string_at("foo bar") # XXX The following may be wrong, depending on how Python # manages string instances - self.assertEqual(2, sys.getrefcount(s)) + if hasattr(sys, 'getrefcount'): + self.assertEqual(2, sys.getrefcount(s)) self.assertTrue(s, "foo bar") self.assertEqual(string_at("foo bar", 8), "foo bar\0") diff --git a/lib-python/2.7/ctypes/test/test_python_api.py b/lib-python/2.7/ctypes/test/test_python_api.py --- a/lib-python/2.7/ctypes/test/test_python_api.py +++ b/lib-python/2.7/ctypes/test/test_python_api.py @@ -9,7 +9,10 @@ ################################################################ -from sys import getrefcount as grc +try: + from sys import getrefcount as grc +except ImportError: + grc = None # e.g. PyPy if sys.version_info > (2, 4): c_py_ssize_t = c_size_t else: diff --git a/lib-python/2.7/ctypes/test/test_refcounts.py b/lib-python/2.7/ctypes/test/test_refcounts.py --- a/lib-python/2.7/ctypes/test/test_refcounts.py +++ b/lib-python/2.7/ctypes/test/test_refcounts.py @@ -11,7 +11,10 @@ class RefcountTestCase(unittest.TestCase): def test_1(self): - from sys import getrefcount as grc + try: + from sys import getrefcount as grc + except ImportError: + return unittest.skip("no sys.getrefcount()") f = dll._testfunc_callback_i_if f.restype = ctypes.c_int @@ -35,7 +38,10 @@ def test_refcount(self): - from sys import getrefcount as grc + try: + from sys import getrefcount as grc + except ImportError: + return unittest.skip("no sys.getrefcount()") def func(*args): pass # this is the standard refcount for func @@ -84,6 +90,10 @@ class AnotherLeak(unittest.TestCase): def test_callback(self): import sys + try: + from sys import getrefcount + except ImportError: + return unittest.skip("no sys.getrefcount()") proto = ctypes.CFUNCTYPE(ctypes.c_int, ctypes.c_int, ctypes.c_int) def func(a, b): diff --git a/lib-python/2.7/distutils/command/build_ext.py b/lib-python/2.7/distutils/command/build_ext.py --- a/lib-python/2.7/distutils/command/build_ext.py +++ b/lib-python/2.7/distutils/command/build_ext.py @@ -699,6 +699,9 @@ shared extension. On most platforms, this is just 'ext.libraries'; on Windows and OS/2, we add the Python library (eg. python20.dll). """ + # For PyPy, we must not add any such Python library, on any platform + if "__pypy__" in sys.builtin_module_names: + return ext.libraries # The python library is always needed on Windows. if sys.platform == "win32": template = "python%d%d" diff --git a/lib-python/2.7/json/decoder.py b/lib-python/2.7/json/decoder.py --- a/lib-python/2.7/json/decoder.py +++ b/lib-python/2.7/json/decoder.py @@ -62,8 +62,7 @@ DEFAULT_ENCODING = "utf-8" -def py_scanstring(s, end, encoding=None, strict=True, - _b=BACKSLASH, _m=STRINGCHUNK.match): +def py_scanstring(s, end, encoding=None, strict=True): """Scan the string s for a JSON string. End is the index of the character in s after the quote that started the JSON string. Unescapes all valid JSON string escape sequences and raises ValueError @@ -78,7 +77,7 @@ _append = chunks.append begin = end - 1 while 1: - chunk = _m(s, end) + chunk = STRINGCHUNK.match(s, end) if chunk is None: raise ValueError( errmsg("Unterminated string starting at", s, begin)) @@ -109,7 +108,7 @@ # If not a unicode escape sequence, must be in the lookup table if esc != 'u': try: - char = _b[esc] + char = BACKSLASH[esc] except KeyError: msg = "Invalid \\escape: " + repr(esc) raise ValueError(errmsg(msg, s, end)) @@ -147,7 +146,7 @@ WHITESPACE_STR = ' \t\n\r' def JSONObject(s_and_end, encoding, strict, scan_once, object_hook, - object_pairs_hook, _w=WHITESPACE.match, _ws=WHITESPACE_STR): + object_pairs_hook): s, end = s_and_end pairs = [] pairs_append = pairs.append @@ -156,8 +155,8 @@ nextchar = s[end:end + 1] # Normally we expect nextchar == '"' if nextchar != '"': - if nextchar in _ws: - end = _w(s, end).end() + if nextchar in WHITESPACE_STR: + end = WHITESPACE.match(s, end).end() nextchar = s[end:end + 1] # Trivial empty object if nextchar == '}': @@ -177,17 +176,17 @@ # To skip some function call overhead we optimize the fast paths where # the JSON key separator is ": " or just ":". if s[end:end + 1] != ':': - end = _w(s, end).end() + end = WHITESPACE.match(s, end).end() if s[end:end + 1] != ':': raise ValueError(errmsg("Expecting : delimiter", s, end)) end += 1 try: - if s[end] in _ws: + if s[end] in WHITESPACE_STR: end += 1 - if s[end] in _ws: - end = _w(s, end + 1).end() + if s[end] in WHITESPACE_STR: + end = WHITESPACE.match(s, end + 1).end() except IndexError: pass @@ -199,8 +198,8 @@ try: nextchar = s[end] - if nextchar in _ws: - end = _w(s, end + 1).end() + if nextchar in WHITESPACE_STR: + end = WHITESPACE.match(s, end + 1).end() nextchar = s[end] except IndexError: nextchar = '' @@ -213,11 +212,11 @@ try: nextchar = s[end] - if nextchar in _ws: + if nextchar in WHITESPACE_STR: end += 1 nextchar = s[end] - if nextchar in _ws: - end = _w(s, end + 1).end() + if nextchar in WHITESPACE_STR: + end = WHITESPACE.match(s, end + 1).end() nextchar = s[end] except IndexError: nextchar = '' @@ -234,12 +233,12 @@ pairs = object_hook(pairs) return pairs, end -def JSONArray(s_and_end, scan_once, _w=WHITESPACE.match, _ws=WHITESPACE_STR): +def JSONArray(s_and_end, scan_once): s, end = s_and_end values = [] nextchar = s[end:end + 1] - if nextchar in _ws: - end = _w(s, end + 1).end() + if nextchar in WHITESPACE_STR: + end = WHITESPACE.match(s, end + 1).end() nextchar = s[end:end + 1] # Look-ahead for trivial empty array if nextchar == ']': @@ -252,8 +251,8 @@ raise ValueError(errmsg("Expecting object", s, end)) _append(value) nextchar = s[end:end + 1] - if nextchar in _ws: - end = _w(s, end + 1).end() + if nextchar in WHITESPACE_STR: + end = WHITESPACE.match(s, end + 1).end() nextchar = s[end:end + 1] end += 1 if nextchar == ']': @@ -262,10 +261,10 @@ raise ValueError(errmsg("Expecting , delimiter", s, end)) try: - if s[end] in _ws: + if s[end] in WHITESPACE_STR: end += 1 - if s[end] in _ws: - end = _w(s, end + 1).end() + if s[end] in WHITESPACE_STR: + end = WHITESPACE.match(s, end + 1).end() except IndexError: pass @@ -358,13 +357,13 @@ self.parse_string = scanstring self.scan_once = scanner.make_scanner(self) - def decode(self, s, _w=WHITESPACE.match): + def decode(self, s): """Return the Python representation of ``s`` (a ``str`` or ``unicode`` instance containing a JSON document) """ - obj, end = self.raw_decode(s, idx=_w(s, 0).end()) - end = _w(s, end).end() + obj, end = self.raw_decode(s, idx=WHITESPACE.match(s, 0).end()) + end = WHITESPACE.match(s, end).end() if end != len(s): raise ValueError(errmsg("Extra data", s, end, len(s))) return obj diff --git a/lib-python/2.7/sre_parse.py b/lib-python/2.7/sre_parse.py --- a/lib-python/2.7/sre_parse.py +++ b/lib-python/2.7/sre_parse.py @@ -16,6 +16,12 @@ from sre_constants import * +try: + from __pypy__ import newdict +except ImportError: + def newdict(tp): + return {} + SPECIAL_CHARS = ".\\[{()*+?^$|" REPEAT_CHARS = "*+?{" @@ -68,7 +74,7 @@ self.flags = 0 self.open = [] self.groups = 1 - self.groupdict = {} + self.groupdict = newdict("module") def opengroup(self, name=None): gid = self.groups self.groups = gid + 1 diff --git a/lib-python/2.7/timeit.py b/lib-python/2.7/timeit.py --- a/lib-python/2.7/timeit.py +++ b/lib-python/2.7/timeit.py @@ -190,7 +190,8 @@ else: it = [None] * number gcold = gc.isenabled() - gc.disable() + if '__pypy__' not in sys.builtin_module_names: + gc.disable() # only do that on CPython try: timing = self.inner(it, self.timer) finally: diff --git a/lib-python/conftest.py b/lib-python/conftest.py --- a/lib-python/conftest.py +++ b/lib-python/conftest.py @@ -14,7 +14,7 @@ from pypy.interpreter.main import run_string, run_file # the following adds command line options as a side effect! -from pypy.conftest import gettestobjspace, option as pypy_option +from pypy.conftest import option as pypy_option from pypy.tool.pytest import appsupport from pypy.tool.pytest.confpath import pypydir, testdir, testresultdir diff --git a/lib_pypy/_ctypes_test.py b/lib_pypy/_ctypes_test.py --- a/lib_pypy/_ctypes_test.py +++ b/lib_pypy/_ctypes_test.py @@ -2,10 +2,6 @@ import tempfile import gc -# Monkeypatch & hacks to let ctypes.tests import. -# This should be removed at some point. -sys.getrefcount = lambda x: len(gc.get_referrers(x)) - 1 - def compile_shared(): """Compile '_ctypes_test.c' into an extension module, and import it """ diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -784,6 +784,9 @@ self.statement.reset() raise self.connection._get_exception(ret) + if self.statement.kind == DML: + self.statement.reset() + if self.statement.kind == DQL and ret == SQLITE_ROW: self.statement._build_row_cast_map() self.statement._readahead(self) @@ -791,9 +794,6 @@ self.statement.item = None self.statement.exhausted = True - if self.statement.kind == DML: - self.statement.reset() - self.rowcount = -1 if self.statement.kind == DML: self.rowcount = sqlite.sqlite3_changes(self.connection.db) diff --git a/lib_pypy/itertools.py b/lib_pypy/itertools.py deleted file mode 100644 --- a/lib_pypy/itertools.py +++ /dev/null @@ -1,670 +0,0 @@ -# Note that PyPy contains also a built-in module 'itertools' which will -# hide this one if compiled in. - -"""Functional tools for creating and using iterators. - -Infinite iterators: -count([n]) --> n, n+1, n+2, ... -cycle(p) --> p0, p1, ... plast, p0, p1, ... -repeat(elem [,n]) --> elem, elem, elem, ... endlessly or up to n times - -Iterators terminating on the shortest input sequence: -izip(p, q, ...) --> (p[0], q[0]), (p[1], q[1]), ... -ifilter(pred, seq) --> elements of seq where pred(elem) is True -ifilterfalse(pred, seq) --> elements of seq where pred(elem) is False -islice(seq, [start,] stop [, step]) --> elements from - seq[start:stop:step] -imap(fun, p, q, ...) --> fun(p0, q0), fun(p1, q1), ... -starmap(fun, seq) --> fun(*seq[0]), fun(*seq[1]), ... -tee(it, n=2) --> (it1, it2 , ... itn) splits one iterator into n -chain(p, q, ...) --> p0, p1, ... plast, q0, q1, ... -takewhile(pred, seq) --> seq[0], seq[1], until pred fails -dropwhile(pred, seq) --> seq[n], seq[n+1], starting when pred fails -groupby(iterable[, keyfunc]) --> sub-iterators grouped by value of keyfunc(v) -""" - -__all__ = ['chain', 'count', 'cycle', 'dropwhile', 'groupby', 'ifilter', - 'ifilterfalse', 'imap', 'islice', 'izip', 'repeat', 'starmap', - 'takewhile', 'tee', 'compress', 'product'] - -try: from __pypy__ import builtinify -except ImportError: builtinify = lambda f: f - - -class chain(object): - """Make an iterator that returns elements from the first iterable - until it is exhausted, then proceeds to the next iterable, until - all of the iterables are exhausted. Used for treating consecutive - sequences as a single sequence. - - Equivalent to : - - def chain(*iterables): - for it in iterables: - for element in it: - yield element - """ - def __init__(self, *iterables): - self._iterables_iter = iter(map(iter, iterables)) - # little trick for the first chain.next() call - self._cur_iterable_iter = iter([]) - - def __iter__(self): - return self - - def next(self): - while True: - try: - return self._cur_iterable_iter.next() - except StopIteration: - self._cur_iterable_iter = self._iterables_iter.next() - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % \ - (self._cur_iterable_iter)) - - -class compress(object): - def __init__(self, data, selectors): - self.data = iter(data) - self.selectors = iter(selectors) - - def __iter__(self): - return self - - def next(self): - while True: - next_item = self.data.next() - next_selector = self.selectors.next() - if bool(next_selector): - return next_item - - -class count(object): - """Make an iterator that returns consecutive integers starting - with n. If not specified n defaults to zero. Does not currently - support python long integers. Often used as an argument to imap() - to generate consecutive data points. Also, used with izip() to - add sequence numbers. - - Equivalent to : - - def count(n=0): - if not isinstance(n, int): - raise TypeError("%s is not a regular integer" % n) - while True: - yield n - n += 1 - """ - def __init__(self, n=0): - if not isinstance(n, int): - raise TypeError('%s is not a regular integer' % n) - self.times = n-1 - - def __iter__(self): - return self - - def next(self): - self.times += 1 - return self.times - - def __repr__(self): - return 'count(%d)' % (self.times + 1) - - - -class cycle(object): - """Make an iterator returning elements from the iterable and - saving a copy of each. When the iterable is exhausted, return - elements from the saved copy. Repeats indefinitely. - - Equivalent to : - - def cycle(iterable): - saved = [] - for element in iterable: - yield element - saved.append(element) - while saved: - for element in saved: - yield element - """ - def __init__(self, iterable): - self._cur_iter = iter(iterable) - self._saved = [] - self._must_save = True - - def __iter__(self): - return self - - def next(self): - # XXX Could probably be improved - try: - next_elt = self._cur_iter.next() - if self._must_save: - self._saved.append(next_elt) - except StopIteration: - self._cur_iter = iter(self._saved) - next_elt = self._cur_iter.next() - self._must_save = False - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % \ - (self._cur_iter)) - return next_elt - - -class dropwhile(object): - """Make an iterator that drops elements from the iterable as long - as the predicate is true; afterwards, returns every - element. Note, the iterator does not produce any output until the - predicate is true, so it may have a lengthy start-up time. - - Equivalent to : - - def dropwhile(predicate, iterable): - iterable = iter(iterable) - for x in iterable: - if not predicate(x): - yield x - break - for x in iterable: - yield x - """ - def __init__(self, predicate, iterable): - self._predicate = predicate - self._iter = iter(iterable) - self._dropped = False - - def __iter__(self): - return self - - def next(self): - try: - value = self._iter.next() - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % \ - (self._iter)) - if self._dropped: - return value - while self._predicate(value): - value = self._iter.next() - self._dropped = True - return value - -class groupby(object): - """Make an iterator that returns consecutive keys and groups from the - iterable. The key is a function computing a key value for each - element. If not specified or is None, key defaults to an identity - function and returns the element unchanged. Generally, the - iterable needs to already be sorted on the same key function. - - The returned group is itself an iterator that shares the - underlying iterable with groupby(). Because the source is shared, - when the groupby object is advanced, the previous group is no - longer visible. So, if that data is needed later, it should be - stored as a list: - - groups = [] - uniquekeys = [] - for k, g in groupby(data, keyfunc): - groups.append(list(g)) # Store group iterator as a list - uniquekeys.append(k) - """ - def __init__(self, iterable, key=None): - if key is None: - key = lambda x: x - self.keyfunc = key - self.it = iter(iterable) - self.tgtkey = self.currkey = self.currvalue = xrange(0) - - def __iter__(self): - return self - - def next(self): - while self.currkey == self.tgtkey: - try: - self.currvalue = self.it.next() # Exit on StopIteration - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % \ - (self.it)) - self.currkey = self.keyfunc(self.currvalue) - self.tgtkey = self.currkey - return (self.currkey, self._grouper(self.tgtkey)) - - def _grouper(self, tgtkey): - while self.currkey == tgtkey: - yield self.currvalue - self.currvalue = self.it.next() # Exit on StopIteration - self.currkey = self.keyfunc(self.currvalue) - - - -class _ifilter_base(object): - """base class for ifilter and ifilterflase""" - def __init__(self, predicate, iterable): - # Make sure iterable *IS* iterable - self._iter = iter(iterable) - if predicate is None: - self._predicate = bool - else: - self._predicate = predicate - - def __iter__(self): - return self - -class ifilter(_ifilter_base): - """Make an iterator that filters elements from iterable returning - only those for which the predicate is True. If predicate is - None, return the items that are true. - - Equivalent to : - - def ifilter: - if predicate is None: - predicate = bool - for x in iterable: - if predicate(x): - yield x - """ - def next(self): - try: - next_elt = self._iter.next() - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % \ - (self._iter)) - while True: - if self._predicate(next_elt): - return next_elt - next_elt = self._iter.next() - -class ifilterfalse(_ifilter_base): - """Make an iterator that filters elements from iterable returning - only those for which the predicate is False. If predicate is - None, return the items that are false. - - Equivalent to : - - def ifilterfalse(predicate, iterable): - if predicate is None: - predicate = bool - for x in iterable: - if not predicate(x): - yield x - """ - def next(self): - try: - next_elt = self._iter.next() - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % \ - (self._iter)) - while True: - if not self._predicate(next_elt): - return next_elt - next_elt = self._iter.next() - - - - -class imap(object): - """Make an iterator that computes the function using arguments - from each of the iterables. If function is set to None, then - imap() returns the arguments as a tuple. Like map() but stops - when the shortest iterable is exhausted instead of filling in - None for shorter iterables. The reason for the difference is that - infinite iterator arguments are typically an error for map() - (because the output is fully evaluated) but represent a common - and useful way of supplying arguments to imap(). - - Equivalent to : - - def imap(function, *iterables): - iterables = map(iter, iterables) - while True: - args = [i.next() for i in iterables] - if function is None: - yield tuple(args) - else: - yield function(*args) - - """ - def __init__(self, function, iterable, *other_iterables): - self._func = function - self._iters = map(iter, (iterable, ) + other_iterables) - - def __iter__(self): - return self - - def next(self): - try: - args = [it.next() for it in self._iters] - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % \ - (it)) - if self._func is None: - return tuple(args) - else: - return self._func(*args) - - - -class islice(object): - """Make an iterator that returns selected elements from the - iterable. If start is non-zero, then elements from the iterable - are skipped until start is reached. Afterward, elements are - returned consecutively unless step is set higher than one which - results in items being skipped. If stop is None, then iteration - continues until the iterator is exhausted, if at all; otherwise, - it stops at the specified position. Unlike regular slicing, - islice() does not support negative values for start, stop, or - step. Can be used to extract related fields from data where the - internal structure has been flattened (for example, a multi-line - report may list a name field on every third line). - """ - def __init__(self, iterable, *args): - s = slice(*args) - self.start, self.stop, self.step = s.start or 0, s.stop, s.step - if not isinstance(self.start, (int, long)): - raise ValueError("Start argument must be an integer") - if self.stop is not None and not isinstance(self.stop, (int,long)): - raise ValueError("Stop argument must be an integer or None") - if self.step is None: - self.step = 1 - if self.start<0 or (self.stop is not None and self.stop<0 - ) or self.step<=0: - raise ValueError, "indices for islice() must be positive" - self.it = iter(iterable) - self.donext = None - self.cnt = 0 - - def __iter__(self): - return self - - def next(self): - if self.donext is None: - try: - self.donext = self.it.next - except AttributeError: - raise TypeError - nextindex = self.start - if self.stop is not None and nextindex >= self.stop: - raise StopIteration - while self.cnt <= nextindex: - nextitem = self.donext() - self.cnt += 1 - self.start += self.step - return nextitem - -class izip(object): - """Make an iterator that aggregates elements from each of the - iterables. Like zip() except that it returns an iterator instead - of a list. Used for lock-step iteration over several iterables at - a time. - - Equivalent to : - - def izip(*iterables): - iterables = map(iter, iterables) - while iterables: - result = [i.next() for i in iterables] - yield tuple(result) - """ - def __init__(self, *iterables): - self._iterators = map(iter, iterables) - self._result = [None] * len(self._iterators) - - def __iter__(self): - return self - - def next(self): - if not self._iterators: - raise StopIteration() - try: - return tuple([i.next() for i in self._iterators]) - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % (i)) - - -class product(object): - - def __init__(self, *args, **kw): - if len(kw) > 1: - raise TypeError("product() takes at most 1 argument (%d given)" % - len(kw)) - self.repeat = kw.get('repeat', 1) - self.gears = [x for x in args] * self.repeat - self.num_gears = len(self.gears) - # initialization of indicies to loop over - self.indicies = [(0, len(self.gears[x])) - for x in range(0, self.num_gears)] - self.cont = True - - def roll_gears(self): - # Starting from the end of the gear indicies work to the front - # incrementing the gear until the limit is reached. When the limit - # is reached carry operation to the next gear - should_carry = True - for n in range(0, self.num_gears): - nth_gear = self.num_gears - n - 1 - if should_carry: - count, lim = self.indicies[nth_gear] - count += 1 - if count == lim and nth_gear == 0: - self.cont = False - if count == lim: - should_carry = True - count = 0 - else: - should_carry = False - self.indicies[nth_gear] = (count, lim) - else: - break - - def __iter__(self): - return self - - def next(self): - if not self.cont: - raise StopIteration - l = [] - for x in range(0, self.num_gears): - index, limit = self.indicies[x] - l.append(self.gears[x][index]) - self.roll_gears() - return tuple(l) - - -class repeat(object): - """Make an iterator that returns object over and over again. - Runs indefinitely unless the times argument is specified. Used - as argument to imap() for invariant parameters to the called - function. Also used with izip() to create an invariant part of a - tuple record. - - Equivalent to : - - def repeat(object, times=None): - if times is None: - while True: - yield object - else: - for i in xrange(times): - yield object - """ - def __init__(self, obj, times=None): - self._obj = obj - if times is not None: - xrange(times) # Raise a TypeError - if times < 0: - times = 0 - self._times = times - - def __iter__(self): - return self - - def next(self): - # next() *need* to decrement self._times when consumed - if self._times is not None: - if self._times <= 0: - raise StopIteration() - self._times -= 1 - return self._obj - - def __repr__(self): - if self._times is not None: - return 'repeat(%r, %r)' % (self._obj, self._times) - else: - return 'repeat(%r)' % (self._obj,) - - def __len__(self): - if self._times == -1 or self._times is None: - raise TypeError("len() of uniszed object") - return self._times - - -class starmap(object): - """Make an iterator that computes the function using arguments - tuples obtained from the iterable. Used instead of imap() when - argument parameters are already grouped in tuples from a single - iterable (the data has been ``pre-zipped''). The difference - between imap() and starmap() parallels the distinction between - function(a,b) and function(*c). - - Equivalent to : - - def starmap(function, iterable): - iterable = iter(iterable) - while True: - yield function(*iterable.next()) - """ - def __init__(self, function, iterable): - self._func = function - self._iter = iter(iterable) - - def __iter__(self): - return self - - def next(self): - # CPython raises a TypeError when the iterator doesn't return a tuple - try: - t = self._iter.next() - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % self._iter) - if not isinstance(t, tuple): - raise TypeError("iterator must return a tuple") - return self._func(*t) - - - -class takewhile(object): - """Make an iterator that returns elements from the iterable as - long as the predicate is true. - - Equivalent to : - - def takewhile(predicate, iterable): - for x in iterable: - if predicate(x): - yield x - else: - break - """ - def __init__(self, predicate, iterable): - self._predicate = predicate - self._iter = iter(iterable) - - def __iter__(self): - return self - - def next(self): - try: - value = self._iter.next() - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % \ - (self._iter)) - if not self._predicate(value): - raise StopIteration() - return value - - -class TeeData(object): - """Holds cached values for TeeObjects""" - def __init__(self, iterator): - self.data = [] - self._iter = iterator - - def __getitem__(self, i): - # iterates until 'i' if not done yet - while i>= len(self.data): - try: - self.data.append( self._iter.next() ) - except AttributeError: - # CPython raises a TypeError when next() is not defined - raise TypeError('%s has no next() method' % self._iter) - return self.data[i] - - -class TeeObject(object): - """Iterables / Iterators as returned by the tee() function""" - def __init__(self, iterable=None, tee_data=None): - if tee_data: - self.tee_data = tee_data - self.pos = 0 - # <=> Copy constructor - elif isinstance(iterable, TeeObject): - self.tee_data = iterable.tee_data - self.pos = iterable.pos - else: - self.tee_data = TeeData(iter(iterable)) - self.pos = 0 - - def next(self): - data = self.tee_data[self.pos] - self.pos += 1 - return data - - def __iter__(self): - return self - - - at builtinify -def tee(iterable, n=2): - """Return n independent iterators from a single iterable. - Note : once tee() has made a split, the original iterable - should not be used anywhere else; otherwise, the iterable could get - advanced without the tee objects being informed. - - Note : this member of the toolkit may require significant auxiliary - storage (depending on how much temporary data needs to be stored). - In general, if one iterator is going to use most or all of the - data before the other iterator, it is faster to use list() instead - of tee() - From noreply at buildbot.pypy.org Fri Feb 8 09:50:32 2013 From: noreply at buildbot.pypy.org (mattip) Date: Fri, 8 Feb 2013 09:50:32 +0100 (CET) Subject: [pypy-commit] pypy python-numpy: merge default into branch Message-ID: <20130208085032.B784F1C02D9@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: python-numpy Changeset: r60960:dbdfabb6c600 Date: 2013-02-08 10:34 +0200 http://bitbucket.org/pypy/pypy/changeset/dbdfabb6c600/ Log: merge default into branch diff too long, truncating to 2000 out of 775068 lines diff --git a/.hgignore b/.hgignore --- a/.hgignore +++ b/.hgignore @@ -85,3 +85,4 @@ ^compiled ^.git/ ^release/ +^rpython/_cache$ diff --git a/dotviewer/test/test_translator.py b/dotviewer/test/test_translator.py --- a/dotviewer/test/test_translator.py +++ b/dotviewer/test/test_translator.py @@ -21,7 +21,7 @@ def test_annotated(): - from pypy.translator.interactive import Translation + from rpython.translator.interactive import Translation t = Translation(is_prime) t.annotate([int]) t.viewcg() diff --git a/lib-python/2.7/collections.py b/lib-python/2.7/collections.py --- a/lib-python/2.7/collections.py +++ b/lib-python/2.7/collections.py @@ -6,11 +6,12 @@ __all__ += _abcoll.__all__ from _collections import deque, defaultdict -from operator import itemgetter as _itemgetter +from operator import itemgetter as _itemgetter, eq as _eq from keyword import iskeyword as _iskeyword import sys as _sys import heapq as _heapq from itertools import repeat as _repeat, chain as _chain, starmap as _starmap +from itertools import imap as _imap try: from thread import get_ident as _get_ident @@ -50,49 +51,45 @@ self.__map = {} self.__update(*args, **kwds) - def __setitem__(self, key, value, PREV=0, NEXT=1, dict_setitem=dict.__setitem__): + def __setitem__(self, key, value, dict_setitem=dict.__setitem__): 'od.__setitem__(i, y) <==> od[i]=y' # Setting a new item creates a new link at the end of the linked list, # and the inherited dictionary is updated with the new key/value pair. if key not in self: root = self.__root - last = root[PREV] - last[NEXT] = root[PREV] = self.__map[key] = [last, root, key] - dict_setitem(self, key, value) + last = root[0] + last[1] = root[0] = self.__map[key] = [last, root, key] + return dict_setitem(self, key, value) - def __delitem__(self, key, PREV=0, NEXT=1, dict_delitem=dict.__delitem__): + def __delitem__(self, key, dict_delitem=dict.__delitem__): 'od.__delitem__(y) <==> del od[y]' # Deleting an existing item uses self.__map to find the link which gets # removed by updating the links in the predecessor and successor nodes. dict_delitem(self, key) link_prev, link_next, key = self.__map.pop(key) - link_prev[NEXT] = link_next - link_next[PREV] = link_prev + link_prev[1] = link_next # update link_prev[NEXT] + link_next[0] = link_prev # update link_next[PREV] def __iter__(self): 'od.__iter__() <==> iter(od)' # Traverse the linked list in order. - NEXT, KEY = 1, 2 root = self.__root - curr = root[NEXT] + curr = root[1] # start at the first node while curr is not root: - yield curr[KEY] - curr = curr[NEXT] + yield curr[2] # yield the curr[KEY] + curr = curr[1] # move to next node def __reversed__(self): 'od.__reversed__() <==> reversed(od)' # Traverse the linked list in reverse order. - PREV, KEY = 0, 2 root = self.__root - curr = root[PREV] + curr = root[0] # start at the last node while curr is not root: - yield curr[KEY] - curr = curr[PREV] + yield curr[2] # yield the curr[KEY] + curr = curr[0] # move to previous node def clear(self): 'od.clear() -> None. Remove all items from od.' - for node in self.__map.itervalues(): - del node[:] root = self.__root root[:] = [root, root, None] self.__map.clear() @@ -208,7 +205,7 @@ ''' if isinstance(other, OrderedDict): - return len(self)==len(other) and self.items() == other.items() + return dict.__eq__(self, other) and all(_imap(_eq, self, other)) return dict.__eq__(self, other) def __ne__(self, other): @@ -298,7 +295,7 @@ _fields = %(field_names)r \n def __new__(_cls, %(argtxt)s): 'Create new instance of %(typename)s(%(argtxt)s)' - return _tuple.__new__(_cls, (%(argtxt)s)) \n + return tuple.__new__(_cls, (%(argtxt)s)) \n @classmethod def _make(cls, iterable, new=tuple.__new__, len=len): 'Make a new %(typename)s object from a sequence or iterable' @@ -323,14 +320,14 @@ 'Return self as a plain tuple. Used by copy and pickle.' return tuple(self) \n\n''' % locals() for i, name in enumerate(field_names): - template += " %s = _property(_itemgetter(%d), doc='Alias for field number %d')\n" % (name, i, i) + template += " %s = property(lambda self: self[%d], doc='Alias for field number %d')\n" % (name, i, i) if verbose: print template # Execute the template string in a temporary namespace and # support tracing utilities by setting a value for frame.f_globals['__name__'] - namespace = dict(_itemgetter=_itemgetter, __name__='namedtuple_%s' % typename, - OrderedDict=OrderedDict, _property=property, _tuple=tuple) + namespace = {'__name__': 'namedtuple_%s' % typename, + 'OrderedDict': OrderedDict} try: exec template in namespace except SyntaxError, e: diff --git a/lib-python/2.7/inspect.py b/lib-python/2.7/inspect.py --- a/lib-python/2.7/inspect.py +++ b/lib-python/2.7/inspect.py @@ -960,7 +960,7 @@ raise TypeError('%s() takes exactly 0 arguments ' '(%d given)' % (f_name, num_total)) else: - raise TypeError('%s() takes no argument (%d given)' % + raise TypeError('%s() takes no arguments (%d given)' % (f_name, num_total)) for arg in args: if isinstance(arg, str) and arg in named: diff --git a/lib-python/2.7/site.py b/lib-python/2.7/site.py --- a/lib-python/2.7/site.py +++ b/lib-python/2.7/site.py @@ -75,6 +75,7 @@ USER_SITE = None USER_BASE = None + def makepath(*paths): dir = os.path.join(*paths) try: diff --git a/lib-python/2.7/sysconfig.py b/lib-python/2.7/sysconfig.py --- a/lib-python/2.7/sysconfig.py +++ b/lib-python/2.7/sysconfig.py @@ -27,10 +27,10 @@ 'data' : '{base}', }, 'pypy': { - 'stdlib': '{base}/lib-python', - 'platstdlib': '{base}/lib-python', - 'purelib': '{base}/lib-python', - 'platlib': '{base}/lib-python', + 'stdlib': '{base}/lib-python/{py_version_short}', + 'platstdlib': '{base}/lib-python/{py_version_short}', + 'purelib': '{base}/lib-python/{py_version_short}', + 'platlib': '{base}/lib-python/{py_version_short}', 'include': '{base}/include', 'platinclude': '{base}/include', 'scripts': '{base}/bin', diff --git a/lib-python/2.7/test/test_capi.py b/lib-python/2.7/test/test_capi.py --- a/lib-python/2.7/test/test_capi.py +++ b/lib-python/2.7/test/test_capi.py @@ -13,6 +13,17 @@ threading = None import _testcapi +skips = [] +if test_support.check_impl_detail(pypy=True): + skips += [ + 'test_broken_memoryview', + 'test_capsule', + 'test_lazy_hash_inheritance', + 'test_widechar', + 'TestThreadState', + 'TestPendingCalls', + ] + @unittest.skipUnless(threading, 'Threading required for this test.') class TestPendingCalls(unittest.TestCase): @@ -99,7 +110,7 @@ def test_main(): for name in dir(_testcapi): - if name.startswith('test_'): + if name.startswith('test_') and name not in skips: test = getattr(_testcapi, name) if test_support.verbose: print "internal", name @@ -126,7 +137,7 @@ raise test_support.TestFailed, \ "Couldn't find main thread correctly in the list" - if threading: + if threading and 'TestThreadState' not in skips: import thread import time TestThreadState() @@ -134,7 +145,8 @@ t.start() t.join() - test_support.run_unittest(TestPendingCalls) + if 'TestPendingCalls' not in skips: + test_support.run_unittest(TestPendingCalls) if __name__ == "__main__": test_main() diff --git a/lib-python/2.7/test/test_iterlen.py b/lib-python/2.7/test/test_iterlen.py --- a/lib-python/2.7/test/test_iterlen.py +++ b/lib-python/2.7/test/test_iterlen.py @@ -94,7 +94,11 @@ def test_no_len_for_infinite_repeat(self): # The repeat() object can also be infinite - self.assertRaises(TypeError, len, repeat(None)) + if test_support.check_impl_detail(pypy=True): + # 3.4 (PEP 424) behavior + self.assertEqual(len(repeat(None)), NotImplemented) + else: + self.assertRaises(TypeError, len, repeat(None)) class TestXrange(TestInvariantWithoutMutations): @@ -230,6 +234,7 @@ self.assertRaises(RuntimeError, b.extend, BadLen()) self.assertRaises(RuntimeError, b.extend, BadLengthHint()) + @test_support.impl_detail("PEP 424 disallows None results", pypy=False) def test_invalid_hint(self): # Make sure an invalid result doesn't muck-up the works self.assertEqual(list(NoneLengthHint()), list(range(10))) diff --git a/lib-python/2.7/test/test_itertools.py b/lib-python/2.7/test/test_itertools.py --- a/lib-python/2.7/test/test_itertools.py +++ b/lib-python/2.7/test/test_itertools.py @@ -533,11 +533,11 @@ self.assertEqual(list(izip()), zip()) self.assertRaises(TypeError, izip, 3) self.assertRaises(TypeError, izip, range(3), 3) - self.assertEqual([tuple(list(pair)) for pair in izip('abc', 'def')], zip('abc', 'def')) self.assertEqual([pair for pair in izip('abc', 'def')], zip('abc', 'def')) + @test_support.impl_detail("tuple reuse is specific to CPython") def test_izip_tuple_reuse(self): ids = map(id, izip('abc', 'def')) @@ -588,6 +588,7 @@ zip('abc', 'def')) self.assertEqual([pair for pair in izip_longest('abc', 'def')], zip('abc', 'def')) + @test_support.impl_detail("tuple reuse is specific to CPython") def test_izip_longest_tuple_reuse(self): ids = map(id, izip_longest('abc', 'def')) diff --git a/lib-python/2.7/test/test_modulefinder.py b/lib-python/2.7/test/test_modulefinder.py --- a/lib-python/2.7/test/test_modulefinder.py +++ b/lib-python/2.7/test/test_modulefinder.py @@ -16,7 +16,7 @@ # library. TEST_DIR = tempfile.mkdtemp() -TEST_PATH = [TEST_DIR, os.path.dirname(__future__.__file__)] +TEST_PATH = [TEST_DIR, os.path.dirname(tempfile.__file__)] # Each test description is a list of 5 items: # diff --git a/lib-python/2.7/test/test_multiprocessing.py b/lib-python/2.7/test/test_multiprocessing.py --- a/lib-python/2.7/test/test_multiprocessing.py +++ b/lib-python/2.7/test/test_multiprocessing.py @@ -1343,7 +1343,7 @@ # Because we are using xmlrpclib for serialization instead of # pickle this will cause a serialization error. - self.assertRaises(Exception, queue.put, time.sleep) + self.assertRaises(Exception, queue.put, object) # Make queue finalizer run before the server is stopped del queue @@ -1800,9 +1800,9 @@ if not gc.isenabled(): gc.enable() self.addCleanup(gc.disable) - thresholds = gc.get_threshold() - self.addCleanup(gc.set_threshold, *thresholds) - gc.set_threshold(10) + #thresholds = gc.get_threshold() + #self.addCleanup(gc.set_threshold, *thresholds) + #gc.set_threshold(10) # perform numerous block allocations, with cyclic references to make # sure objects are collected asynchronously by the gc @@ -1865,6 +1865,7 @@ def test_synchronize(self): self.test_sharedctypes(lock=True) + @unittest.skipUnless(test_support.check_impl_detail(pypy=False), "pypy ctypes differences") def test_copy(self): foo = _Foo(2, 5.0) bar = copy(foo) diff --git a/lib-python/2.7/test/test_support.py b/lib-python/2.7/test/test_support.py --- a/lib-python/2.7/test/test_support.py +++ b/lib-python/2.7/test/test_support.py @@ -1085,7 +1085,6 @@ else: runner = BasicTestRunner() - result = runner.run(suite) if not result.wasSuccessful(): if len(result.errors) == 1 and not result.failures: diff --git a/lib-python/2.7/test/test_zipfile.py b/lib-python/2.7/test/test_zipfile.py --- a/lib-python/2.7/test/test_zipfile.py +++ b/lib-python/2.7/test/test_zipfile.py @@ -1213,6 +1213,17 @@ self.assertEqual(data1, '1'*FIXEDTEST_SIZE) self.assertEqual(data2, '2'*FIXEDTEST_SIZE) + def test_many_opens(self): + # Verify that read() and open() promptly close the file descriptor, + # and don't rely on the garbage collector to free resources. + with zipfile.ZipFile(TESTFN2, mode="r") as zipf: + for x in range(100): + zipf.read('ones') + with zipf.open('ones') as zopen1: + pass + for x in range(10): + self.assertLess(open('/dev/null').fileno(), 100) + def tearDown(self): unlink(TESTFN2) diff --git a/lib-python/2.7/zipfile.py b/lib-python/2.7/zipfile.py --- a/lib-python/2.7/zipfile.py +++ b/lib-python/2.7/zipfile.py @@ -475,9 +475,11 @@ # Search for universal newlines or line chunks. PATTERN = re.compile(r'^(?P[^\r\n]+)|(?P\n|\r\n?)') - def __init__(self, fileobj, mode, zipinfo, decrypter=None): + def __init__(self, fileobj, mode, zipinfo, decrypter=None, + close_fileobj=False): self._fileobj = fileobj self._decrypter = decrypter + self._close_fileobj = close_fileobj self._compress_type = zipinfo.compress_type self._compress_size = zipinfo.compress_size @@ -649,6 +651,12 @@ self._offset += len(data) return data + def close(self): + try: + if self._close_fileobj: + self._fileobj.close() + finally: + super(ZipExtFile, self).close() class ZipFile: @@ -866,7 +874,8 @@ def read(self, name, pwd=None): """Return file bytes (as a string) for name.""" - return self.open(name, "r", pwd).read() + with self.open(name, "r", pwd) as fp: + return fp.read() def open(self, name, mode="r", pwd=None): """Return file-like object for 'name'.""" @@ -889,8 +898,12 @@ zinfo = name else: # Get info object for name - zinfo = self.getinfo(name) - + try: + zinfo = self.getinfo(name) + except KeyError: + if not self._filePassed: + zef_file.close() + raise zef_file.seek(zinfo.header_offset, 0) # Skip the file header: @@ -904,6 +917,8 @@ zef_file.read(fheader[_FH_EXTRA_FIELD_LENGTH]) if fname != zinfo.orig_filename: + if not self._filePassed: + zef_file.close() raise BadZipfile, \ 'File name in directory "%s" and header "%s" differ.' % ( zinfo.orig_filename, fname) @@ -915,6 +930,8 @@ if not pwd: pwd = self.pwd if not pwd: + if not self._filePassed: + zef_file.close() raise RuntimeError, "File %s is encrypted, " \ "password required for extraction" % name @@ -933,9 +950,12 @@ # compare against the CRC otherwise check_byte = (zinfo.CRC >> 24) & 0xff if ord(h[11]) != check_byte: + if not self._filePassed: + zef_file.close() raise RuntimeError("Bad password for file", name) - return ZipExtFile(zef_file, mode, zinfo, zd) + return ZipExtFile(zef_file, mode, zinfo, zd, + close_fileobj=not self._filePassed) def extract(self, member, path=None, pwd=None): """Extract a member from the archive to the current working directory, @@ -993,7 +1013,7 @@ return targetpath source = self.open(member, pwd=pwd) - target = file(targetpath, "wb") + target = open(targetpath, "wb") shutil.copyfileobj(source, target) source.close() target.close() diff --git a/lib-python/conftest.py b/lib-python/conftest.py --- a/lib-python/conftest.py +++ b/lib-python/conftest.py @@ -17,8 +17,8 @@ from pypy.conftest import option as pypy_option from pypy.tool.pytest import appsupport -from pypy.tool.pytest.confpath import pypydir, testdir, testresultdir -from pypy.config.parse import parse_info +from pypy.tool.pytest.confpath import pypydir, rpythondir, testdir, testresultdir +from rpython.config.parse import parse_info pytest_plugins = "resultlog", rsyncdirs = ['.', '../pypy/'] @@ -40,7 +40,7 @@ dest="unittest_filter", help="Similar to -k, XXX") def gettimeout(timeout): - from test import pystone + from rpython.translator.test import rpystone if timeout.endswith('mp'): megapystone = float(timeout[:-2]) t, stone = pystone.Proc0(10000) @@ -61,7 +61,7 @@ usemodules = '', skip=None): self.basename = basename - self._usemodules = usemodules.split() + ['signal'] + self._usemodules = usemodules.split() + ['signal', 'rctime', 'itertools', '_socket'] self._compiler = compiler self.core = core self.skip = skip @@ -93,63 +93,57 @@ m.test_main() ''' % locals()) -if sys.platform == 'win32': - skip_win32 = "Not supported on Windows" - only_win32 = False -else: - skip_win32 = False - only_win32 = "Only on Windows" - testmap = [ RegrTest('test___all__.py', core=True), RegrTest('test___future__.py', core=True), - RegrTest('test__locale.py', skip=skip_win32), + RegrTest('test__locale.py', usemodules='_locale'), RegrTest('test_abc.py'), RegrTest('test_abstract_numbers.py'), - RegrTest('test_aepack.py', skip=True), + RegrTest('test_aepack.py'), RegrTest('test_aifc.py'), - RegrTest('test_argparse.py'), - RegrTest('test_al.py', skip=True), - RegrTest('test_ast.py', core=True), - RegrTest('test_anydbm.py'), - RegrTest('test_applesingle.py', skip=True), - RegrTest('test_array.py', core=True, usemodules='struct array'), + RegrTest('test_al.py'), + RegrTest('test_anydbm.py', usemodules='struct'), + RegrTest('test_applesingle.py'), + RegrTest('test_argparse.py', usemodules='binascii'), + RegrTest('test_array.py', core=True, usemodules='struct array binascii'), RegrTest('test_ascii_formatd.py'), - RegrTest('test_asynchat.py', usemodules='thread'), - RegrTest('test_asyncore.py'), + RegrTest('test_ast.py', core=True, usemodules='struct'), + RegrTest('test_asynchat.py', usemodules='select fcntl'), + RegrTest('test_asyncore.py', usemodules='select fcntl'), RegrTest('test_atexit.py', core=True), - RegrTest('test_audioop.py', skip=True), + RegrTest('test_audioop.py', skip="unsupported extension module"), RegrTest('test_augassign.py', core=True), - RegrTest('test_base64.py'), + RegrTest('test_base64.py', usemodules='struct'), RegrTest('test_bastion.py'), + RegrTest('test_bigaddrspace.py'), + RegrTest('test_bigmem.py'), RegrTest('test_binascii.py', usemodules='binascii'), - RegrTest('test_binhex.py'), - RegrTest('test_binop.py', core=True), RegrTest('test_bisect.py', core=True, usemodules='_bisect'), RegrTest('test_bool.py', core=True), - RegrTest('test_bsddb.py', skip="unsupported extension module"), - RegrTest('test_bsddb185.py', skip="unsupported extension module"), - RegrTest('test_bsddb3.py', skip="unsupported extension module"), + RegrTest('test_bsddb.py'), + RegrTest('test_bsddb185.py'), + RegrTest('test_bsddb3.py'), RegrTest('test_buffer.py'), RegrTest('test_bufio.py', core=True), - RegrTest('test_builtin.py', core=True), - RegrTest('test_bytes.py'), + RegrTest('test_builtin.py', core=True, usemodules='binascii'), + RegrTest('test_bytes.py', usemodules='struct binascii'), RegrTest('test_bz2.py', usemodules='bz2'), RegrTest('test_calendar.py'), RegrTest('test_call.py', core=True), - RegrTest('test_capi.py', skip="not applicable"), - RegrTest('test_cd.py', skip=True), + RegrTest('test_capi.py'), + RegrTest('test_cd.py'), RegrTest('test_cfgparser.py'), - RegrTest('test_cgi.py'), RegrTest('test_charmapcodec.py', core=True), - RegrTest('test_cl.py', skip=True), + RegrTest('test_cl.py'), RegrTest('test_class.py', core=True), RegrTest('test_cmath.py', core=True), RegrTest('test_cmd.py'), + RegrTest('test_cmd_line.py'), RegrTest('test_cmd_line_script.py'), + RegrTest('test_code.py', core=True), RegrTest('test_codeccallbacks.py', core=True), RegrTest('test_codecencodings_cn.py', usemodules='_multibytecodec'), RegrTest('test_codecencodings_hk.py', usemodules='_multibytecodec'), @@ -157,7 +151,6 @@ RegrTest('test_codecencodings_jp.py', usemodules='_multibytecodec'), RegrTest('test_codecencodings_kr.py', usemodules='_multibytecodec'), RegrTest('test_codecencodings_tw.py', usemodules='_multibytecodec'), - RegrTest('test_codecmaps_cn.py', usemodules='_multibytecodec'), RegrTest('test_codecmaps_hk.py', usemodules='_multibytecodec'), RegrTest('test_codecmaps_jp.py', usemodules='_multibytecodec'), @@ -165,8 +158,9 @@ RegrTest('test_codecmaps_tw.py', usemodules='_multibytecodec'), RegrTest('test_codecs.py', core=True, usemodules='_multibytecodec'), RegrTest('test_codeop.py', core=True), + RegrTest('test_coding.py', core=True), RegrTest('test_coercion.py', core=True), - RegrTest('test_collections.py'), + RegrTest('test_collections.py', usemodules='binascii struct'), RegrTest('test_colorsys.py'), RegrTest('test_commands.py'), RegrTest('test_compare.py', core=True), @@ -174,22 +168,24 @@ RegrTest('test_compileall.py'), RegrTest('test_compiler.py', core=False, skip="slowly deprecating compiler"), RegrTest('test_complex.py', core=True), - + RegrTest('test_complex_args.py'), RegrTest('test_contains.py', core=True), + RegrTest('test_contextlib.py', usemodules="thread"), RegrTest('test_cookie.py'), RegrTest('test_cookielib.py'), RegrTest('test_copy.py', core=True), RegrTest('test_copy_reg.py', core=True), RegrTest('test_cpickle.py', core=True), - RegrTest('test_cprofile.py'), - RegrTest('test_crypt.py', usemodules='crypt', skip=skip_win32), + RegrTest('test_cprofile.py'), + RegrTest('test_crypt.py', usemodules='crypt'), RegrTest('test_csv.py', usemodules='_csv'), - - RegrTest('test_curses.py', skip="unsupported extension module"), - RegrTest('test_datetime.py'), + RegrTest('test_ctypes.py', usemodules="_rawffi thread"), + RegrTest('test_curses.py'), + RegrTest('test_datetime.py', usemodules='binascii struct'), RegrTest('test_dbm.py'), RegrTest('test_decimal.py'), RegrTest('test_decorators.py', core=True), + RegrTest('test_defaultdict.py', usemodules='_collections'), RegrTest('test_deque.py', core=True, usemodules='_collections'), RegrTest('test_descr.py', core=True, usemodules='_weakref'), RegrTest('test_descrtut.py', core=True), @@ -200,7 +196,7 @@ RegrTest('test_dircache.py', core=True), RegrTest('test_dis.py'), RegrTest('test_distutils.py', skip=True), - RegrTest('test_dl.py', skip=True), + RegrTest('test_dl.py'), RegrTest('test_doctest.py', usemodules="thread"), RegrTest('test_doctest2.py'), RegrTest('test_docxmlrpc.py'), @@ -208,20 +204,22 @@ RegrTest('test_dummy_thread.py', core=True), RegrTest('test_dummy_threading.py', core=True), RegrTest('test_email.py'), - RegrTest('test_email_codecs.py'), + RegrTest('test_email_renamed.py'), RegrTest('test_enumerate.py', core=True), RegrTest('test_eof.py', core=True), RegrTest('test_epoll.py'), RegrTest('test_errno.py', usemodules="errno"), + RegrTest('test_exception_variations.py'), RegrTest('test_exceptions.py', core=True), RegrTest('test_extcall.py', core=True), - RegrTest('test_fcntl.py', usemodules='fcntl', skip=skip_win32), + RegrTest('test_fcntl.py', usemodules='fcntl'), RegrTest('test_file.py', usemodules="posix", core=True), RegrTest('test_file2k.py', usemodules="posix", core=True), RegrTest('test_filecmp.py', core=True), RegrTest('test_fileinput.py', core=True), RegrTest('test_fileio.py'), + RegrTest('test_float.py', core=True), RegrTest('test_fnmatch.py', core=True), RegrTest('test_fork1.py', usemodules="thread"), RegrTest('test_format.py', core=True), @@ -230,6 +228,7 @@ RegrTest('test_frozen.py', skip="unsupported extension module"), RegrTest('test_ftplib.py'), RegrTest('test_funcattrs.py', core=True), + RegrTest('test_functools.py'), RegrTest('test_future.py', core=True), RegrTest('test_future1.py', core=True), RegrTest('test_future2.py', core=True), @@ -239,41 +238,37 @@ RegrTest('test_future_builtins.py'), RegrTest('test_gc.py', usemodules='_weakref', skip="implementation detail"), RegrTest('test_gdb.py', skip="not applicable"), - RegrTest('test_gdbm.py', skip="unsupported extension module"), + RegrTest('test_gdbm.py'), RegrTest('test_generators.py', core=True, usemodules='thread _weakref'), RegrTest('test_genericpath.py'), RegrTest('test_genexps.py', core=True, usemodules='_weakref'), - RegrTest('test_getargs.py', skip="unsupported extension module"), - RegrTest('test_getargs2.py', skip="unsupported extension module"), - + RegrTest('test_getargs.py'), + RegrTest('test_getargs2.py', usemodules='binascii', skip=True), RegrTest('test_getopt.py', core=True), RegrTest('test_gettext.py'), - - RegrTest('test_gl.py', skip=True), + RegrTest('test_gl.py'), RegrTest('test_glob.py', core=True), RegrTest('test_global.py', core=True), RegrTest('test_grammar.py', core=True), - RegrTest('test_grp.py', skip=skip_win32), - - RegrTest('test_gzip.py'), + RegrTest('test_grp.py'), + RegrTest('test_gzip.py', usemodules='zlib'), RegrTest('test_hash.py', core=True), RegrTest('test_hashlib.py', core=True), - RegrTest('test_heapq.py', core=True), RegrTest('test_hmac.py'), RegrTest('test_hotshot.py', skip="unsupported extension module"), - RegrTest('test_htmllib.py'), RegrTest('test_htmlparser.py'), RegrTest('test_httplib.py'), RegrTest('test_httpservers.py'), - RegrTest('test_imageop.py', skip="unsupported extension module"), + RegrTest('test_imageop.py'), RegrTest('test_imaplib.py'), - RegrTest('test_imgfile.py', skip="unsupported extension module"), + RegrTest('test_imgfile.py'), RegrTest('test_imp.py', core=True, usemodules='thread'), RegrTest('test_import.py', core=True), RegrTest('test_importhooks.py', core=True), RegrTest('test_importlib.py'), + RegrTest('test_index.py'), RegrTest('test_inspect.py'), RegrTest('test_int.py', core=True), RegrTest('test_int_literal.py', core=True), @@ -281,7 +276,7 @@ RegrTest('test_ioctl.py'), RegrTest('test_isinstance.py', core=True), RegrTest('test_iter.py', core=True), - RegrTest('test_iterlen.py', skip="undocumented internal API behavior __length_hint__"), + RegrTest('test_iterlen.py', core=True, usemodules="_collections itertools"), RegrTest('test_itertools.py', core=True, usemodules="itertools struct"), RegrTest('test_json.py'), RegrTest('test_kqueue.py'), @@ -296,7 +291,7 @@ RegrTest('test_long_future.py', core=True), RegrTest('test_longexp.py', core=True), RegrTest('test_macos.py'), - RegrTest('test_macostools.py', skip=True), + RegrTest('test_macostools.py'), RegrTest('test_macpath.py'), RegrTest('test_mailbox.py'), RegrTest('test_marshal.py', core=True), @@ -307,30 +302,29 @@ RegrTest('test_mhlib.py'), RegrTest('test_mimetools.py'), RegrTest('test_mimetypes.py'), - RegrTest('test_MimeWriter.py', core=False), + RegrTest('test_MimeWriter.py', core=False, usemodules='binascii'), RegrTest('test_minidom.py'), RegrTest('test_mmap.py', usemodules="mmap"), RegrTest('test_module.py', core=True), RegrTest('test_modulefinder.py'), - RegrTest('test_msilib.py', skip=only_win32), + RegrTest('test_msilib.py'), RegrTest('test_multibytecodec.py', usemodules='_multibytecodec'), - RegrTest('test_multibytecodec_support.py', skip="not a test"), RegrTest('test_multifile.py'), - RegrTest('test_multiprocessing.py', skip="FIXME leaves subprocesses"), + RegrTest('test_multiprocessing.py'), RegrTest('test_mutants.py', core="possibly"), RegrTest('test_mutex.py'), RegrTest('test_netrc.py'), RegrTest('test_new.py', core=True), - RegrTest('test_nis.py', skip="unsupported extension module"), + RegrTest('test_nis.py'), RegrTest('test_normalization.py'), RegrTest('test_ntpath.py'), + RegrTest('test_old_mailbox.py'), RegrTest('test_opcodes.py', core=True), RegrTest('test_openpty.py'), RegrTest('test_operator.py', core=True), RegrTest('test_optparse.py'), - RegrTest('test_os.py', core=True), - RegrTest('test_ossaudiodev.py', skip="unsupported extension module"), + RegrTest('test_ossaudiodev.py'), RegrTest('test_parser.py', skip="slowly deprecating compiler"), RegrTest('test_pdb.py'), RegrTest('test_peepholer.py'), @@ -338,14 +332,16 @@ RegrTest('test_pep263.py'), RegrTest('test_pep277.py'), RegrTest('test_pep292.py'), + RegrTest('test_pep352.py'), RegrTest('test_pickle.py', core=True), RegrTest('test_pickletools.py', core=False), RegrTest('test_pipes.py'), RegrTest('test_pkg.py', core=True), RegrTest('test_pkgimport.py', core=True), RegrTest('test_pkgutil.py'), - RegrTest('test_plistlib.py', skip="unsupported module"), - RegrTest('test_poll.py', skip=skip_win32), + RegrTest('test_platform.py'), + RegrTest('test_plistlib.py'), + RegrTest('test_poll.py'), RegrTest('test_popen.py'), RegrTest('test_popen2.py'), RegrTest('test_poplib.py'), @@ -357,8 +353,8 @@ RegrTest('test_profile.py'), RegrTest('test_property.py', core=True), RegrTest('test_pstats.py'), - RegrTest('test_pty.py', skip="unsupported extension module"), - RegrTest('test_pwd.py', usemodules="pwd", skip=skip_win32), + RegrTest('test_pty.py', usemodules='fcntl termios select'), + RegrTest('test_pwd.py', usemodules="pwd"), RegrTest('test_py3kwarn.py'), RegrTest('test_py_compile.py'), RegrTest('test_pyclbr.py'), @@ -370,15 +366,15 @@ RegrTest('test_re.py', core=True), RegrTest('test_readline.py'), RegrTest('test_repr.py', core=True), - RegrTest('test_resource.py', skip=skip_win32), + RegrTest('test_resource.py'), RegrTest('test_rfc822.py'), RegrTest('test_richcmp.py', core=True), RegrTest('test_rlcompleter.py'), - RegrTest('test_robotparser.py'), + RegrTest('test_runpy.py'), RegrTest('test_sax.py'), RegrTest('test_scope.py', core=True), - RegrTest('test_scriptpackages.py', skip="unsupported extension module"), + RegrTest('test_scriptpackages.py'), RegrTest('test_select.py'), RegrTest('test_set.py', core=True), RegrTest('test_sets.py'), @@ -389,64 +385,59 @@ RegrTest('test_shlex.py'), RegrTest('test_shutil.py'), RegrTest('test_signal.py'), - RegrTest('test_SimpleHTTPServer.py'), + RegrTest('test_SimpleHTTPServer.py', usemodules='binascii'), RegrTest('test_site.py', core=False), RegrTest('test_slice.py', core=True), RegrTest('test_smtplib.py'), RegrTest('test_smtpnet.py'), RegrTest('test_socket.py', usemodules='thread _weakref'), - RegrTest('test_socketserver.py', usemodules='thread'), - RegrTest('test_softspace.py', core=True), RegrTest('test_sort.py', core=True), + RegrTest('test_sqlite.py', usemodules="thread _rawffi zlib"), RegrTest('test_ssl.py', usemodules='_ssl _socket select'), + RegrTest('test_startfile.py'), RegrTest('test_str.py', core=True), - RegrTest('test_strftime.py'), RegrTest('test_string.py', core=True), - RegrTest('test_StringIO.py', core=True, usemodules='cStringIO'), + RegrTest('test_StringIO.py', core=True, usemodules='cStringIO array'), RegrTest('test_stringprep.py'), RegrTest('test_strop.py', skip="deprecated"), - RegrTest('test_strptime.py'), RegrTest('test_strtod.py'), RegrTest('test_struct.py', usemodules='struct'), RegrTest('test_structmembers.py', skip="CPython specific"), RegrTest('test_structseq.py'), RegrTest('test_subprocess.py', usemodules='signal'), - RegrTest('test_sunaudiodev.py', skip=True), + RegrTest('test_sunaudiodev.py'), RegrTest('test_sundry.py'), RegrTest('test_symtable.py', skip="implementation detail"), RegrTest('test_syntax.py', core=True), RegrTest('test_sys.py', core=True, usemodules='struct'), + RegrTest('test_sys_setprofile.py', core=True), RegrTest('test_sys_settrace.py', core=True), - RegrTest('test_sys_setprofile.py', core=True), RegrTest('test_sysconfig.py'), - RegrTest('test_tcl.py', skip="unsupported extension module"), RegrTest('test_tarfile.py'), + RegrTest('test_tcl.py'), RegrTest('test_telnetlib.py'), RegrTest('test_tempfile.py'), - RegrTest('test_textwrap.py'), RegrTest('test_thread.py', usemodules="thread", core=True), RegrTest('test_threaded_import.py', usemodules="thread", core=True), RegrTest('test_threadedtempfile.py', usemodules="thread", core=False), - RegrTest('test_threading.py', usemodules="thread", core=True), RegrTest('test_threading_local.py', usemodules="thread", core=True), RegrTest('test_threadsignals.py', usemodules="thread"), - RegrTest('test_time.py', core=True), RegrTest('test_timeout.py'), RegrTest('test_tk.py'), - RegrTest('test_ttk_guionly.py'), - RegrTest('test_ttk_textonly.py'), RegrTest('test_tokenize.py'), RegrTest('test_trace.py'), RegrTest('test_traceback.py', core=True), RegrTest('test_transformer.py', core=True), + RegrTest('test_ttk_guionly.py'), + RegrTest('test_ttk_textonly.py'), RegrTest('test_tuple.py', core=True), RegrTest('test_typechecks.py'), RegrTest('test_types.py', core=True), @@ -462,6 +453,7 @@ RegrTest('test_unpack.py', core=True), RegrTest('test_urllib.py'), RegrTest('test_urllib2.py'), + RegrTest('test_urllib2_localnet.py', usemodules="thread"), RegrTest('test_urllib2net.py'), RegrTest('test_urllibnet.py'), RegrTest('test_urlparse.py'), @@ -469,61 +461,38 @@ RegrTest('test_userlist.py', core=True), RegrTest('test_userstring.py', core=True), RegrTest('test_uu.py'), - - RegrTest('test_warnings.py', core=True), - RegrTest('test_wave.py', skip="unsupported extension module"), - RegrTest('test_weakref.py', core=True, usemodules='_weakref'), - RegrTest('test_weakset.py'), - - RegrTest('test_whichdb.py'), - RegrTest('test_winreg.py', skip=only_win32), - RegrTest('test_winsound.py', skip="unsupported extension module"), - RegrTest('test_xmllib.py'), - RegrTest('test_xmlrpc.py'), - - RegrTest('test_xpickle.py'), - RegrTest('test_xrange.py', core=True), - RegrTest('test_zipfile.py'), - RegrTest('test_zipimport.py', usemodules='zlib zipimport'), - RegrTest('test_zipimport_support.py', usemodules='zlib zipimport'), - RegrTest('test_zlib.py', usemodules='zlib'), - - RegrTest('test_bigaddrspace.py'), - RegrTest('test_bigmem.py'), - RegrTest('test_cmd_line.py'), - RegrTest('test_code.py'), - RegrTest('test_coding.py'), - RegrTest('test_complex_args.py'), - RegrTest('test_contextlib.py', usemodules="thread"), - RegrTest('test_ctypes.py', usemodules="_rawffi thread"), - RegrTest('test_defaultdict.py', usemodules='_collections'), - RegrTest('test_email_renamed.py'), - RegrTest('test_exception_variations.py'), - RegrTest('test_float.py'), - RegrTest('test_functools.py'), - RegrTest('test_index.py'), - RegrTest('test_old_mailbox.py'), - RegrTest('test_pep352.py'), - RegrTest('test_platform.py'), - RegrTest('test_runpy.py'), - RegrTest('test_sqlite.py', usemodules="thread _rawffi zlib"), - RegrTest('test_startfile.py', skip="bogus test"), - RegrTest('test_structmembers.py', skip="depends on _testcapi"), - RegrTest('test_urllib2_localnet.py', usemodules="thread"), RegrTest('test_uuid.py'), RegrTest('test_wait3.py', usemodules="thread"), RegrTest('test_wait4.py', usemodules="thread"), + RegrTest('test_warnings.py', core=True), + RegrTest('test_wave.py'), + RegrTest('test_weakref.py', core=True, usemodules='_weakref'), + RegrTest('test_weakset.py'), + RegrTest('test_whichdb.py'), + RegrTest('test_winreg.py'), + RegrTest('test_winsound.py'), RegrTest('test_with.py'), RegrTest('test_wsgiref.py'), RegrTest('test_xdrlib.py'), RegrTest('test_xml_etree.py'), RegrTest('test_xml_etree_c.py'), + RegrTest('test_xmllib.py'), + RegrTest('test_xmlrpc.py'), + RegrTest('test_xpickle.py'), + RegrTest('test_xrange.py', core=True), + RegrTest('test_zipfile.py'), RegrTest('test_zipfile64.py'), + RegrTest('test_zipimport.py', usemodules='zlib zipimport'), + RegrTest('test_zipimport_support.py', usemodules='zlib zipimport'), + RegrTest('test_zlib.py', usemodules='zlib'), ] def check_testmap_complete(): listed_names = dict.fromkeys([regrtest.basename for regrtest in testmap]) - listed_names['test_support.py'] = True # ignore this + assert len(listed_names) == len(testmap) + # names to ignore + listed_names['test_support.py'] = True + listed_names['test_multibytecodec_support.py'] = True missing = [] for path in testdir.listdir(fil='test_*.py'): name = path.basename @@ -578,13 +547,13 @@ def getinvocation(self, regrtest): fspath = regrtest.getfspath() python = sys.executable - pypy_script = pypydir.join('bin', 'py.py') + pypy_script = pypydir.join('bin', 'pyinteractive.py') alarm_script = pypydir.join('tool', 'alarm.py') if sys.platform == 'win32': watchdog_name = 'watchdog_nt.py' else: watchdog_name = 'watchdog.py' - watchdog_script = pypydir.join('tool', watchdog_name) + watchdog_script = rpythondir.join('tool', watchdog_name) regr_script = pypydir.join('tool', 'pytest', 'run-script', 'regrverbose.py') diff --git a/lib_pypy/_ctypes_test.py b/lib_pypy/_ctypes_test.py --- a/lib_pypy/_ctypes_test.py +++ b/lib_pypy/_ctypes_test.py @@ -1,6 +1,5 @@ import os, sys import tempfile -import gc def compile_shared(): """Compile '_ctypes_test.c' into an extension module, and import it @@ -19,7 +18,7 @@ if sys.platform == 'win32': ccflags = ['-D_CRT_SECURE_NO_WARNINGS'] else: - ccflags = ['-fPIC'] + ccflags = ['-fPIC', '-Wimplicit-function-declaration'] res = compiler.compile([os.path.join(thisdir, '_ctypes_test.c')], include_dirs=[include_dir], extra_preargs=ccflags) @@ -35,10 +34,10 @@ library = os.path.join(thisdir, '..', 'include', 'python27') if not os.path.exists(library + '.lib'): # For a local translation - library = os.path.join(thisdir, '..', 'pypy', 'translator', - 'goal', 'libpypy-c') + library = os.path.join(thisdir, '..', 'pypy', 'goal', 'libpypy-c') libraries = [library, 'oleaut32'] - extra_ldargs = ['/MANIFEST'] # needed for VC10 + extra_ldargs = ['/MANIFEST', # needed for VC10 + '/EXPORT:init_ctypes_test'] else: libraries = [] extra_ldargs = [] diff --git a/lib_pypy/_testcapi.py b/lib_pypy/_testcapi.py --- a/lib_pypy/_testcapi.py +++ b/lib_pypy/_testcapi.py @@ -34,8 +34,7 @@ library = os.path.join(thisdir, '..', 'include', 'python27') if not os.path.exists(library + '.lib'): # For a local translation - library = os.path.join(thisdir, '..', 'pypy', 'translator', - 'goal', 'libpypy-c') + library = os.path.join(thisdir, '..', 'pypy', 'goal', 'libpypy-c') libraries = [library, 'oleaut32'] extra_ldargs = ['/MANIFEST', # needed for VC10 '/EXPORT:init_testcapi'] diff --git a/lib_pypy/cPickle.py b/lib_pypy/cPickle.py --- a/lib_pypy/cPickle.py +++ b/lib_pypy/cPickle.py @@ -1,5 +1,5 @@ # -# One-liner implementation of cPickle +# Reimplementation of cPickle, mostly as a copy of pickle.py # from pickle import Pickler, dump, dumps, PickleError, PicklingError, UnpicklingError, _EmptyClass @@ -131,6 +131,13 @@ # Unpickling machinery +class _Stack(list): + def pop(self, index=-1): + try: + return list.pop(self, index) + except IndexError: + raise UnpicklingError("unpickling stack underflow") + class Unpickler(object): def __init__(self, file): @@ -155,7 +162,7 @@ Return the reconstituted object hierarchy specified in the file. """ self.mark = object() # any new unique object - self.stack = [] + self.stack = _Stack() self.append = self.stack.append try: key = ord(self.read(1)) diff --git a/lib_pypy/ctypes_config_cache/autopath.py b/lib_pypy/ctypes_config_cache/autopath.py deleted file mode 100644 --- a/lib_pypy/ctypes_config_cache/autopath.py +++ /dev/null @@ -1,131 +0,0 @@ -""" -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 don't have the part - an EnvironmentError is raised.""" - - import sys, os - try: - head = this_dir = os.path.realpath(os.path.dirname(__file__)) - except NameError: - head = this_dir = os.path.realpath(os.path.dirname(sys.argv[0])) - - error = None - while head: - partdir = head - head, tail = os.path.split(head) - if tail == part: - checkfile = os.path.join(partdir, os.pardir, 'pypy', '__init__.py') - if not os.path.exists(checkfile): - error = "Cannot find %r" % (os.path.normpath(checkfile),) - break - else: - error = "Cannot find the parent directory %r of the path %r" % ( - partdir, this_dir) - if not error: - # check for bogus end-of-line style (e.g. files checked out on - # Windows and moved to Unix) - f = open(__file__.replace('.pyc', '.py'), 'r') - data = f.read() - f.close() - if data.endswith('\r\n') or data.endswith('\r'): - error = ("Bad end-of-line style in the .py files. Typically " - "caused by a zip file or a checkout done on Windows and " - "moved to Unix or vice-versa.") - if error: - raise EnvironmentError("Invalid source tree - bogus checkout! " + - error) - - pypy_root = os.path.join(head, '') - try: - sys.path.remove(head) - except ValueError: - pass - sys.path.insert(0, head) - - munged = {} - for name, mod in sys.modules.items(): - if '.' in name: - continue - fn = getattr(mod, '__file__', None) - if not isinstance(fn, str): - continue - newname = os.path.splitext(os.path.basename(fn))[0] - if not newname.startswith(part + '.'): - continue - path = os.path.join(os.path.dirname(os.path.realpath(fn)), '') - if path.startswith(pypy_root) and newname != part: - modpaths = os.path.normpath(path[len(pypy_root):]).split(os.sep) - if newname != '__init__': - modpaths.append(newname) - modpath = '.'.join(modpaths) - if modpath not in sys.modules: - munged[modpath] = mod - - for name, mod in munged.iteritems(): - if name not in sys.modules: - sys.modules[name] = mod - if '.' in name: - prename = name[:name.rfind('.')] - postname = name[len(prename)+1:] - if prename not in sys.modules: - __import__(prename) - if not hasattr(sys.modules[prename], postname): - setattr(sys.modules[prename], postname, mod) - - return partdir, this_dir - -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() diff --git a/lib_pypy/ctypes_config_cache/dumpcache.py b/lib_pypy/ctypes_config_cache/dumpcache.py --- a/lib_pypy/ctypes_config_cache/dumpcache.py +++ b/lib_pypy/ctypes_config_cache/dumpcache.py @@ -1,6 +1,6 @@ import os from ctypes_configure import dumpcache -from pypy.jit.backend import detect_cpu +from rpython.jit.backend import detect_cpu def dumpcache2(basename, config): model = detect_cpu.autodetect_main_model_and_size() @@ -14,7 +14,7 @@ try: from __pypy__ import cpumodel except ImportError: - from pypy.jit.backend import detect_cpu + from rpython.jit.backend import detect_cpu cpumodel = detect_cpu.autodetect_main_model_and_size() # XXX relative import, should be removed together with # XXX the relative imports done e.g. by lib_pypy/pypy_test/test_hashlib diff --git a/lib_pypy/ctypes_config_cache/rebuild.py b/lib_pypy/ctypes_config_cache/rebuild.py --- a/lib_pypy/ctypes_config_cache/rebuild.py +++ b/lib_pypy/ctypes_config_cache/rebuild.py @@ -1,21 +1,15 @@ #! /usr/bin/env python # Run this script to rebuild all caches from the *.ctc.py files. -# hack: we cannot directly import autopath, as we are outside the pypy -# package. However, we pretend to be inside pypy/tool and manually run it, to -# get the correct path -import os.path -this_dir = os.path.dirname(__file__) -autopath_py = os.path.join(this_dir, '../../pypy/tool/autopath.py') -autopath_py = os.path.abspath(autopath_py) -execfile(autopath_py, dict(__name__='autopath', __file__=autopath_py)) +import os, sys -import os, sys +sys.path.insert(0, os.path.realpath(os.path.join(os.path.dirname(__file__), '..', '..'))) + import py _dirpath = os.path.dirname(__file__) or os.curdir -from pypy.tool.ansi_print import ansi_log +from rpython.tool.ansi_print import ansi_log log = py.log.Producer("ctypes_config_cache") py.log.setconsumer("ctypes_config_cache", ansi_log) @@ -31,7 +25,7 @@ sys.path[:] = path def try_rebuild(): - from pypy.jit.backend import detect_cpu + from rpython.jit.backend import detect_cpu model = detect_cpu.autodetect_main_model_and_size() # remove the files '_*_model_.py' left = {} diff --git a/lib_pypy/ctypes_config_cache/test/test_cache.py b/lib_pypy/ctypes_config_cache/test/test_cache.py --- a/lib_pypy/ctypes_config_cache/test/test_cache.py +++ b/lib_pypy/ctypes_config_cache/test/test_cache.py @@ -1,6 +1,6 @@ import py import sys, os -from pypy.tool.udir import udir +from rpython.tool.udir import udir dirpath = py.path.local(__file__).dirpath().dirpath() diff --git a/lib_pypy/ctypes_support.py b/lib_pypy/ctypes_support.py --- a/lib_pypy/ctypes_support.py +++ b/lib_pypy/ctypes_support.py @@ -19,16 +19,19 @@ if sys.platform == 'win32': standard_c_lib._errno.restype = ctypes.POINTER(ctypes.c_int) + standard_c_lib._errno.argtypes = None def _where_is_errno(): return standard_c_lib._errno() elif sys.platform in ('linux2', 'freebsd6'): standard_c_lib.__errno_location.restype = ctypes.POINTER(ctypes.c_int) + standard_c_lib.__errno_location.argtypes = None def _where_is_errno(): return standard_c_lib.__errno_location() elif sys.platform in ('darwin', 'freebsd7', 'freebsd8', 'freebsd9'): standard_c_lib.__error.restype = ctypes.POINTER(ctypes.c_int) + standard_c_lib.__error.argtypes = None def _where_is_errno(): return standard_c_lib.__error() diff --git a/lib_pypy/greenlet.py b/lib_pypy/greenlet.py --- a/lib_pypy/greenlet.py +++ b/lib_pypy/greenlet.py @@ -1,5 +1,6 @@ import _continuation, sys +__version__ = "0.4.0" # ____________________________________________________________ # Exceptions @@ -57,7 +58,8 @@ def __switch(target, methodname, *args): current = getcurrent() # - while not target: + while not (target.__main or _continulet.is_pending(target)): + # inlined __nonzero__ ^^^ in case it's overridden if not target.__started: if methodname == 'switch': greenlet_func = _greenlet_start diff --git a/lib_pypy/pypy_test/test_cPickle.py b/lib_pypy/pypy_test/test_cPickle.py new file mode 100644 --- /dev/null +++ b/lib_pypy/pypy_test/test_cPickle.py @@ -0,0 +1,7 @@ +from __future__ import absolute_import +import py + +from lib_pypy import cPickle + +def test_stack_underflow(): + py.test.raises(cPickle.UnpicklingError, cPickle.loads, "a string") diff --git a/lib_pypy/pypy_test/test_dbm_extra.py b/lib_pypy/pypy_test/test_dbm_extra.py --- a/lib_pypy/pypy_test/test_dbm_extra.py +++ b/lib_pypy/pypy_test/test_dbm_extra.py @@ -1,6 +1,6 @@ from __future__ import absolute_import import py -from pypy.tool.udir import udir +from rpython.tool.udir import udir try: from lib_pypy import dbm except ImportError, e: diff --git a/lib_pypy/pypy_test/test_marshal_extra.py b/lib_pypy/pypy_test/test_marshal_extra.py --- a/lib_pypy/pypy_test/test_marshal_extra.py +++ b/lib_pypy/pypy_test/test_marshal_extra.py @@ -4,7 +4,7 @@ import marshal as cpy_marshal from lib_pypy import _marshal as marshal -from pypy.tool.udir import udir +from rpython.tool.udir import udir hello = "he" hello += "llo" diff --git a/lib_pypy/pyrepl/unix_console.py b/lib_pypy/pyrepl/unix_console.py --- a/lib_pypy/pyrepl/unix_console.py +++ b/lib_pypy/pyrepl/unix_console.py @@ -398,6 +398,7 @@ if hasattr(self, 'old_sigwinch'): signal.signal(signal.SIGWINCH, self.old_sigwinch) + del self.old_sigwinch def __sigwinch(self, signum, frame): self.height, self.width = self.getheightwidth() diff --git a/py/_code/source.py b/py/_code/source.py --- a/py/_code/source.py +++ b/py/_code/source.py @@ -141,6 +141,8 @@ trysource = self[start:end] if trysource.isparseable(): return start, end + if end == start + 100: # XXX otherwise, it takes forever + break # XXX if end is None: raise IndexError("no valid source range around line %d " % (lineno,)) return start, end diff --git a/pypy/annotation/annrpython.py b/pypy/annotation/annrpython.py deleted file mode 100644 --- a/pypy/annotation/annrpython.py +++ /dev/null @@ -1,676 +0,0 @@ -from __future__ import absolute_import - -import types -from pypy.tool.ansi_print import ansi_log -from pypy.tool.pairtype import pair -from pypy.tool.error import (format_blocked_annotation_error, - AnnotatorError, gather_error, ErrorWrapper) -from pypy.objspace.flow.model import (Variable, Constant, FunctionGraph, - c_last_exception, checkgraph) -from pypy.translator import simplify, transform -from pypy.annotation import model as annmodel, signature, unaryop, binaryop -from pypy.annotation.bookkeeper import Bookkeeper -import py -log = py.log.Producer("annrpython") -py.log.setconsumer("annrpython", ansi_log) - - -FAIL = object() - -class RPythonAnnotator(object): - """Block annotator for RPython. - See description in doc/translation.txt.""" - - def __init__(self, translator=None, policy=None, bookkeeper=None): - import pypy.rpython.ootypesystem.ooregistry # has side effects - import pypy.rpython.extfuncregistry # has side effects - import pypy.rlib.nonconst # has side effects - - if translator is None: - # interface for tests - from pypy.translator.translator import TranslationContext - translator = TranslationContext() - translator.annotator = self - self.translator = translator - self.pendingblocks = {} # map {block: graph-containing-it} - self.bindings = {} # map Variables to SomeValues - self.annotated = {} # set of blocks already seen - self.added_blocks = None # see processblock() below - self.links_followed = {} # set of links that have ever been followed - self.notify = {} # {block: {positions-to-reflow-from-when-done}} - self.fixed_graphs = {} # set of graphs not to annotate again - self.blocked_blocks = {} # set of {blocked_block: (graph, index)} - # --- the following information is recorded for debugging --- - self.blocked_graphs = {} # set of graphs that have blocked blocks - # --- end of debugging information --- - self.frozen = False - if policy is None: - from pypy.annotation.policy import AnnotatorPolicy - self.policy = AnnotatorPolicy() - else: - self.policy = policy - if bookkeeper is None: - bookkeeper = Bookkeeper(self) - self.bookkeeper = bookkeeper - - def __getstate__(self): - attrs = """translator pendingblocks bindings annotated links_followed - notify bookkeeper frozen policy added_blocks""".split() - ret = self.__dict__.copy() - for key, value in ret.items(): - if key not in attrs: - assert type(value) is dict, ( - "%r is not dict. please update %s.__getstate__" % - (key, self.__class__.__name__)) - ret[key] = {} - return ret - - #___ convenience high-level interface __________________ - - def build_types(self, function, input_arg_types, complete_now=True, - main_entry_point=False): - """Recursively build annotations about the specific entry point.""" - assert isinstance(function, types.FunctionType), "fix that!" - - from pypy.annotation.policy import AnnotatorPolicy - policy = AnnotatorPolicy() - # make input arguments and set their type - args_s = [self.typeannotation(t) for t in input_arg_types] - - # XXX hack - annmodel.TLS.check_str_without_nul = ( - self.translator.config.translation.check_str_without_nul) - - flowgraph, inputcells = self.get_call_parameters(function, args_s, policy) - if not isinstance(flowgraph, FunctionGraph): - assert isinstance(flowgraph, annmodel.SomeObject) - return flowgraph - - if main_entry_point: - self.translator.entry_point_graph = flowgraph - return self.build_graph_types(flowgraph, inputcells, complete_now=complete_now) - - def get_call_parameters(self, function, args_s, policy): - desc = self.bookkeeper.getdesc(function) - args = self.bookkeeper.build_args("simple_call", args_s[:]) - result = [] - def schedule(graph, inputcells): - result.append((graph, inputcells)) - return annmodel.s_ImpossibleValue - - prevpolicy = self.policy - self.policy = policy - self.bookkeeper.enter(None) - try: - desc.pycall(schedule, args, annmodel.s_ImpossibleValue) - finally: - self.bookkeeper.leave() - self.policy = prevpolicy - [(graph, inputcells)] = result - return graph, inputcells - - def annotate_helper(self, function, args_s, policy=None): - if policy is None: - from pypy.annotation.policy import AnnotatorPolicy - policy = AnnotatorPolicy() - graph, inputcells = self.get_call_parameters(function, args_s, policy) - self.build_graph_types(graph, inputcells, complete_now=False) - self.complete_helpers(policy) - return graph - - def complete_helpers(self, policy): - saved = self.policy, self.added_blocks - self.policy = policy - try: - self.added_blocks = {} - self.complete() - # invoke annotation simplifications for the new blocks - self.simplify(block_subset=self.added_blocks) - finally: - self.policy, self.added_blocks = saved - - def build_graph_types(self, flowgraph, inputcells, complete_now=True): - checkgraph(flowgraph) - - nbarg = len(flowgraph.getargs()) - if len(inputcells) != nbarg: - raise TypeError("%s expects %d args, got %d" %( - flowgraph, nbarg, len(inputcells))) - - # register the entry point - self.addpendinggraph(flowgraph, inputcells) - # recursively proceed until no more pending block is left - if complete_now: - self.complete() - return self.binding(flowgraph.getreturnvar(), None) - - def gettype(self, variable): - """Return the known type of a control flow graph variable, - defaulting to 'object'.""" - if isinstance(variable, Constant): - return type(variable.value) - elif isinstance(variable, Variable): - cell = self.bindings.get(variable) - if cell: - return cell.knowntype - else: - return object - else: - raise TypeError, ("Variable or Constant instance expected, " - "got %r" % (variable,)) - - def getuserclassdefinitions(self): - """Return a list of ClassDefs.""" - return self.bookkeeper.classdefs - - #___ medium-level interface ____________________________ - - def addpendinggraph(self, flowgraph, inputcells): - self.addpendingblock(flowgraph, flowgraph.startblock, inputcells) - - def addpendingblock(self, graph, block, cells): - """Register an entry point into block with the given input cells.""" - if graph in self.fixed_graphs: - # special case for annotating/rtyping in several phases: calling - # a graph that has already been rtyped. Safety-check the new - # annotations that are passed in, and don't annotate the old - # graph -- it's already low-level operations! - for a, s_newarg in zip(graph.getargs(), cells): - s_oldarg = self.binding(a) - assert annmodel.unionof(s_oldarg, s_newarg) == s_oldarg - else: - assert not self.frozen - for a in cells: - assert isinstance(a, annmodel.SomeObject) - if block not in self.annotated: - self.bindinputargs(graph, block, cells) - else: - self.mergeinputargs(graph, block, cells) - if not self.annotated[block]: - self.pendingblocks[block] = graph - - def complete(self): - """Process pending blocks until none is left.""" - while True: - while self.pendingblocks: - block, graph = self.pendingblocks.popitem() - self.processblock(graph, block) - self.policy.no_more_blocks_to_annotate(self) - if not self.pendingblocks: - break # finished - # make sure that the return variables of all graphs is annotated - if self.added_blocks is not None: - newgraphs = [self.annotated[block] for block in self.added_blocks] - newgraphs = dict.fromkeys(newgraphs) - got_blocked_blocks = False in newgraphs - else: - newgraphs = self.translator.graphs #all of them - got_blocked_blocks = False in self.annotated.values() - if got_blocked_blocks: - for graph in self.blocked_graphs.values(): - self.blocked_graphs[graph] = True - - blocked_blocks = [block for block, done in self.annotated.items() - if done is False] - assert len(blocked_blocks) == len(self.blocked_blocks) - - text = format_blocked_annotation_error(self, self.blocked_blocks) - #raise SystemExit() - raise AnnotatorError(text) - for graph in newgraphs: - v = graph.getreturnvar() - if v not in self.bindings: - self.setbinding(v, annmodel.s_ImpossibleValue) - # policy-dependent computation - self.bookkeeper.compute_at_fixpoint() - - def binding(self, arg, default=FAIL): - "Gives the SomeValue corresponding to the given Variable or Constant." - if isinstance(arg, Variable): - try: - return self.bindings[arg] - except KeyError: - if default is not FAIL: - return default - else: - raise - elif isinstance(arg, Constant): - #if arg.value is undefined_value: # undefined local variables - # return annmodel.s_ImpossibleValue - return self.bookkeeper.immutableconstant(arg) - else: - raise TypeError, 'Variable or Constant expected, got %r' % (arg,) - - def typeannotation(self, t): - return signature.annotation(t, self.bookkeeper) - - def setbinding(self, arg, s_value): - if arg in self.bindings: - assert s_value.contains(self.bindings[arg]) - self.bindings[arg] = s_value - - def transfer_binding(self, v_target, v_source): - assert v_source in self.bindings - self.bindings[v_target] = self.bindings[v_source] - - def warning(self, msg, pos=None): - if pos is None: - try: - pos = self.bookkeeper.position_key - except AttributeError: - pos = '?' - if pos != '?': - pos = self.whereami(pos) - - log.WARNING("%s/ %s" % (pos, msg)) - - - #___ interface for annotator.bookkeeper _______ - - def recursivecall(self, graph, whence, inputcells): - if isinstance(whence, tuple): - parent_graph, parent_block, parent_index = whence - tag = parent_block, parent_index - self.translator.update_call_graph(parent_graph, graph, tag) - # self.notify[graph.returnblock] is a dictionary of call - # points to this func which triggers a reflow whenever the - # return block of this graph has been analysed. - callpositions = self.notify.setdefault(graph.returnblock, {}) - if whence is not None: - if callable(whence): - def callback(): - whence(self, graph) - else: - callback = whence - callpositions[callback] = True - - # generalize the function's input arguments - self.addpendingblock(graph, graph.startblock, inputcells) - - # get the (current) return value - v = graph.getreturnvar() - try: - return self.bindings[v] - except KeyError: - # the function didn't reach any return statement so far. - # (some functions actually never do, they always raise exceptions) - return annmodel.s_ImpossibleValue - - def reflowfromposition(self, position_key): - graph, block, index = position_key - self.reflowpendingblock(graph, block) - - - #___ simplification (should be moved elsewhere?) _______ - - def simplify(self, block_subset=None, extra_passes=None): - # Generic simplifications - transform.transform_graph(self, block_subset=block_subset, - extra_passes=extra_passes) - if block_subset is None: - graphs = self.translator.graphs - else: - graphs = {} - for block in block_subset: - graph = self.annotated.get(block) - if graph: - graphs[graph] = True - for graph in graphs: - simplify.eliminate_empty_blocks(graph) - - - #___ flowing annotations in blocks _____________________ - - def processblock(self, graph, block): - # Important: this is not called recursively. - # self.flowin() can only issue calls to self.addpendingblock(). - # The analysis of a block can be in three states: - # * block not in self.annotated: - # never seen the block. - # * self.annotated[block] == False: - # the input variables of the block are in self.bindings but we - # still have to consider all the operations in the block. - # * self.annotated[block] == graph-containing-block: - # analysis done (at least until we find we must generalize the - # input variables). - - #print '* processblock', block, cells - self.annotated[block] = graph - if block in self.blocked_blocks: - del self.blocked_blocks[block] - try: - self.flowin(graph, block) - except BlockedInference, e: - self.annotated[block] = False # failed, hopefully temporarily - self.blocked_blocks[block] = (graph, e.opindex) - except Exception, e: - # hack for debug tools only - if not hasattr(e, '__annotator_block'): - setattr(e, '__annotator_block', block) - raise - - # The dict 'added_blocks' is used by rpython.annlowlevel to - # detect which are the new blocks that annotating an additional - # small helper creates. - if self.added_blocks is not None: - self.added_blocks[block] = True - - def reflowpendingblock(self, graph, block): - assert not self.frozen - assert graph not in self.fixed_graphs - self.pendingblocks[block] = graph - assert block in self.annotated - self.annotated[block] = False # must re-flow - self.blocked_blocks[block] = (graph, None) - - def bindinputargs(self, graph, block, inputcells): - # Create the initial bindings for the input args of a block. - assert len(block.inputargs) == len(inputcells) - for a, cell in zip(block.inputargs, inputcells): - self.setbinding(a, cell) - self.annotated[block] = False # must flowin. - self.blocked_blocks[block] = (graph, None) - - def mergeinputargs(self, graph, block, inputcells): - # Merge the new 'cells' with each of the block's existing input - # variables. - oldcells = [self.binding(a) for a in block.inputargs] - try: - unions = [annmodel.unionof(c1,c2) for c1, c2 in zip(oldcells,inputcells)] - except annmodel.UnionError, e: - e.args = e.args + ( - ErrorWrapper(gather_error(self, graph, block, None)),) - raise - # if the merged cells changed, we must redo the analysis - if unions != oldcells: - self.bindinputargs(graph, block, unions) - - def whereami(self, position_key): - graph, block, i = position_key - blk = "" - if block: - at = block.at() - if at: - blk = " block"+at - opid="" - if i is not None: - opid = " op=%d" % i - return repr(graph) + blk + opid - - def flowin(self, graph, block): - #print 'Flowing', block, [self.binding(a) for a in block.inputargs] - try: - for i in range(len(block.operations)): - try: - self.bookkeeper.enter((graph, block, i)) - self.consider_op(block, i) - finally: - self.bookkeeper.leave() - - except BlockedInference, e: - if (e.op is block.operations[-1] and - block.exitswitch == c_last_exception): - # this is the case where the last operation of the block will - # always raise an exception which is immediately caught by - # an exception handler. We then only follow the exceptional - # branches. - exits = [link for link in block.exits - if link.exitcase is not None] - - elif e.op.opname in ('simple_call', 'call_args', 'next'): - # XXX warning, keep the name of the call operations in sync - # with the flow object space. These are the operations for - # which it is fine to always raise an exception. We then - # swallow the BlockedInference and that's it. - # About 'next': see test_annotate_iter_empty_container(). - return - - else: - # other cases are problematic (but will hopefully be solved - # later by reflowing). Throw the BlockedInference up to - # processblock(). - raise - - except annmodel.HarmlesslyBlocked: - return - - else: - # dead code removal: don't follow all exits if the exitswitch - # is known - exits = block.exits - if isinstance(block.exitswitch, Variable): - s_exitswitch = self.bindings[block.exitswitch] - if s_exitswitch.is_constant(): - exits = [link for link in exits - if link.exitcase == s_exitswitch.const] - - # mapping (exitcase, variable) -> s_annotation - # that can be attached to booleans, exitswitches - knowntypedata = getattr(self.bindings.get(block.exitswitch), - "knowntypedata", {}) - - # filter out those exceptions which cannot - # occour for this specific, typed operation. - if block.exitswitch == c_last_exception: - op = block.operations[-1] - if op.opname in binaryop.BINARY_OPERATIONS: - arg1 = self.binding(op.args[0]) - arg2 = self.binding(op.args[1]) - binop = getattr(pair(arg1, arg2), op.opname, None) - can_only_throw = annmodel.read_can_only_throw(binop, arg1, arg2) - elif op.opname in unaryop.UNARY_OPERATIONS: - arg1 = self.binding(op.args[0]) - opname = op.opname - if opname == 'contains': opname = 'op_contains' - unop = getattr(arg1, opname, None) - can_only_throw = annmodel.read_can_only_throw(unop, arg1) - else: - can_only_throw = None - - if can_only_throw is not None: - candidates = can_only_throw - candidate_exits = exits - exits = [] - for link in candidate_exits: - case = link.exitcase - if case is None: - exits.append(link) - continue - covered = [c for c in candidates if issubclass(c, case)] - if covered: - exits.append(link) - candidates = [c for c in candidates if c not in covered] - - for link in exits: - in_except_block = False - - last_exception_var = link.last_exception # may be None for non-exception link - last_exc_value_var = link.last_exc_value # may be None for non-exception link - - if isinstance(link.exitcase, (types.ClassType, type)) \ - and issubclass(link.exitcase, py.builtin.BaseException): - assert last_exception_var and last_exc_value_var - last_exc_value_object = self.bookkeeper.valueoftype(link.exitcase) - last_exception_object = annmodel.SomeType() - if isinstance(last_exception_var, Constant): - last_exception_object.const = last_exception_var.value - last_exception_object.is_type_of = [last_exc_value_var] - - if isinstance(last_exception_var, Variable): - self.setbinding(last_exception_var, last_exception_object) - if isinstance(last_exc_value_var, Variable): - self.setbinding(last_exc_value_var, last_exc_value_object) - - last_exception_object = annmodel.SomeType() - if isinstance(last_exception_var, Constant): - last_exception_object.const = last_exception_var.value - #if link.exitcase is Exception: - # last_exc_value_object = annmodel.SomeObject() - #else: - last_exc_value_vars = [] - in_except_block = True - - ignore_link = False - cells = [] - renaming = {} - for a,v in zip(link.args,link.target.inputargs): - renaming.setdefault(a, []).append(v) - for a,v in zip(link.args,link.target.inputargs): - if a == last_exception_var: - assert in_except_block - cells.append(last_exception_object) - elif a == last_exc_value_var: - assert in_except_block - cells.append(last_exc_value_object) - last_exc_value_vars.append(v) - else: - cell = self.binding(a) - if (link.exitcase, a) in knowntypedata: - knownvarvalue = knowntypedata[(link.exitcase, a)] - cell = pair(cell, knownvarvalue).improve() - # ignore links that try to pass impossible values - if cell == annmodel.s_ImpossibleValue: - ignore_link = True - - if hasattr(cell,'is_type_of'): - renamed_is_type_of = [] - for v in cell.is_type_of: - new_vs = renaming.get(v,[]) - renamed_is_type_of += new_vs - assert cell.knowntype is type - newcell = annmodel.SomeType() - if cell.is_constant(): - newcell.const = cell.const - cell = newcell - cell.is_type_of = renamed_is_type_of - - if hasattr(cell, 'knowntypedata'): - renamed_knowntypedata = {} - for (value, v), s in cell.knowntypedata.items(): - new_vs = renaming.get(v, []) - for new_v in new_vs: - renamed_knowntypedata[value, new_v] = s - assert isinstance(cell, annmodel.SomeBool) - newcell = annmodel.SomeBool() - if cell.is_constant(): - newcell.const = cell.const - cell = newcell - cell.set_knowntypedata(renamed_knowntypedata) - - cells.append(cell) - - if ignore_link: - continue - - if in_except_block: - last_exception_object.is_type_of = last_exc_value_vars - - self.links_followed[link] = True - self.addpendingblock(graph, link.target, cells) - - if block in self.notify: - # reflow from certain positions when this block is done - for callback in self.notify[block]: - if isinstance(callback, tuple): - self.reflowfromposition(callback) # callback is a position - else: - callback() - - - #___ creating the annotations based on operations ______ - - def consider_op(self, block, opindex): - op = block.operations[opindex] - argcells = [self.binding(a) for a in op.args] - consider_meth = getattr(self,'consider_op_'+op.opname, - None) - if not consider_meth: - raise Exception,"unknown op: %r" % op - - # let's be careful about avoiding propagated SomeImpossibleValues - # to enter an op; the latter can result in violations of the - # more general results invariant: e.g. if SomeImpossibleValue enters is_ - # is_(SomeImpossibleValue, None) -> SomeBool - # is_(SomeInstance(not None), None) -> SomeBool(const=False) ... - # boom -- in the assert of setbinding() - for arg in argcells: - if isinstance(arg, annmodel.SomeImpossibleValue): - raise BlockedInference(self, op, opindex) - try: - resultcell = consider_meth(*argcells) - except Exception, e: - graph = self.bookkeeper.position_key[0] - e.args = e.args + ( - ErrorWrapper(gather_error(self, graph, block, opindex)),) - raise - if resultcell is None: - resultcell = self.noreturnvalue(op) - elif resultcell == annmodel.s_ImpossibleValue: - raise BlockedInference(self, op, opindex) # the operation cannot succeed - assert isinstance(resultcell, annmodel.SomeObject) - assert isinstance(op.result, Variable) - self.setbinding(op.result, resultcell) # bind resultcell to op.result - - def noreturnvalue(self, op): - return annmodel.s_ImpossibleValue # no return value (hook method) - - # XXX "contains" clash with SomeObject method - def consider_op_contains(self, seq, elem): From noreply at buildbot.pypy.org Fri Feb 8 09:50:34 2013 From: noreply at buildbot.pypy.org (mattip) Date: Fri, 8 Feb 2013 09:50:34 +0100 (CET) Subject: [pypy-commit] pypy default: failing test - SliceArray has no astype Message-ID: <20130208085034.2D3C01C02D9@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: Changeset: r60961:18f31c26605b Date: 2013-02-08 10:49 +0200 http://bitbucket.org/pypy/pypy/changeset/18f31c26605b/ Log: failing test - SliceArray has no astype diff --git a/pypy/module/micronumpy/test/test_numarray.py b/pypy/module/micronumpy/test/test_numarray.py --- a/pypy/module/micronumpy/test/test_numarray.py +++ b/pypy/module/micronumpy/test/test_numarray.py @@ -1640,7 +1640,7 @@ assert _weakref.ref(a) def test_astype(self): - from _numpypy import array + from _numpypy import array, arange b = array(1).astype(float) assert b == 1 assert b.dtype == float @@ -1653,7 +1653,9 @@ b = array([0, 1, 2], dtype=complex).astype(bool) assert (b == [False, True, True]).all() assert b.dtype == 'bool' - + + a = arange(6, dtype='f4').reshape(2,3) + b = a.astype('i4') def test_base(self): from _numpypy import array From noreply at buildbot.pypy.org Fri Feb 8 10:10:21 2013 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 8 Feb 2013 10:10:21 +0100 (CET) Subject: [pypy-commit] cffi default: Move the development to 0.6 Message-ID: <20130208091021.C61071C0884@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r1129:8bc2fd1e557f Date: 2013-02-08 10:07 +0100 http://bitbucket.org/cffi/cffi/changeset/8bc2fd1e557f/ Log: Move the development to 0.6 diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c --- a/c/_cffi_backend.c +++ b/c/_cffi_backend.c @@ -4961,7 +4961,7 @@ if (v == NULL || PyModule_AddObject(m, "_C_API", v) < 0) INITERROR; - v = PyText_FromString("0.5"); + v = PyText_FromString("0.6"); if (v == NULL || PyModule_AddObject(m, "__version__", v) < 0) INITERROR; diff --git a/cffi/__init__.py b/cffi/__init__.py --- a/cffi/__init__.py +++ b/cffi/__init__.py @@ -4,5 +4,5 @@ from .api import FFI, CDefError, FFIError from .ffiplatform import VerificationError, VerificationMissing -__version__ = "0.5" -__version_info__ = (0, 5) +__version__ = "0.6" +__version_info__ = (0, 6) diff --git a/doc/source/conf.py b/doc/source/conf.py --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -45,9 +45,9 @@ # built documents. # # The short X.Y version. -version = '0.5' +version = '0.6' # The full version, including alpha/beta/rc tags. -release = '0.5' +release = '0.6' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/setup.py b/setup.py --- a/setup.py +++ b/setup.py @@ -81,7 +81,7 @@ setup( name='cffi', description='Foreign Function Interface for Python calling C code.', - version='0.5', + version='0.6', packages=['cffi'], zip_safe=False, From noreply at buildbot.pypy.org Fri Feb 8 10:10:23 2013 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 8 Feb 2013 10:10:23 +0100 (CET) Subject: [pypy-commit] cffi default: Passing None as an ``item *`` argument to a function. Message-ID: <20130208091023.1A7D91C0884@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r1130:c42e0c485fc8 Date: 2013-02-08 10:10 +0100 http://bitbucket.org/cffi/cffi/changeset/c42e0c485fc8/ Log: Passing None as an ``item *`` argument to a function. diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c --- a/c/_cffi_backend.c +++ b/c/_cffi_backend.c @@ -1934,7 +1934,11 @@ ctitem = ctptr->ct_itemdescr; /* XXX some code duplication, how to avoid it? */ - if (PyBytes_Check(init)) { + if (init == Py_None) { + *output_data = NULL; + return 0; + } + else if (PyBytes_Check(init)) { /* from a string: just returning the string here is fine. We assume that the C code won't modify the 'char *' data. */ if ((ctptr->ct_flags & CT_CAST_ANYTHING) || @@ -4683,7 +4687,9 @@ static int _testfunc23(char *p) { - return 1000 * p[0]; + if (p) + return 1000 * p[0]; + return -42; } static PyObject *b__testfunc(PyObject *self, PyObject *args) diff --git a/c/test_c.py b/c/test_c.py --- a/c/test_c.py +++ b/c/test_c.py @@ -1006,6 +1006,8 @@ f = cast(BFunc23, _testfunc(23)) res = f(b"foo") assert res == 1000 * ord(b'f') + res = f(None) + assert res == -42 def test_call_function_23_bis(): # declaring the function as int(unsigned char*) diff --git a/doc/source/index.rst b/doc/source/index.rst --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -1329,6 +1329,9 @@ you need to specify it in a list of length 1; for example, a ``struct foo *`` argument might be passed as ``[[field1, field2...]]``. +.. versionadded:: 0.6 + You can also pass None to ``item *`` arguments (meaning NULL). + As an optimization, the CPython version of CFFI assumes that a function with a ``char *`` argument to which you pass a Python string will not actually modify the array of characters passed in, and so passes directly diff --git a/testing/test_verify.py b/testing/test_verify.py --- a/testing/test_verify.py +++ b/testing/test_verify.py @@ -1512,3 +1512,19 @@ assert lib.sum3chars((b'\x10', b'\x20', b'\x30')) == b'\x60' p = ffi.new("char[]", b'\x10\x20\x30') assert lib.sum3chars(p) == b'\x60' + +def test_passing_None(): + ffi = FFI() + ffi.cdef("int seeme1(char *); int seeme2(int *);") + lib = ffi.verify(""" + int seeme1(char *x) { + return (x == NULL); + } + int seeme2(int *x) { + return (x == NULL); + } + """) + assert lib.seeme1("foo") == 0 + assert lib.seeme1(None) == 1 + assert lib.seeme2([42, 43]) == 0 + assert lib.seeme2(None) == 1 From noreply at buildbot.pypy.org Fri Feb 8 10:21:20 2013 From: noreply at buildbot.pypy.org (jerith) Date: Fri, 8 Feb 2013 10:21:20 +0100 (CET) Subject: [pypy-commit] pypy curses_cffi: Fix getsyx() and stuff related to repl setup. Message-ID: <20130208092120.3A5F61C0884@cobra.cs.uni-duesseldorf.de> Author: Jeremy Thurgood Branch: curses_cffi Changeset: r60962:a903bf4f9acf Date: 2013-02-08 11:20 +0200 http://bitbucket.org/pypy/pypy/changeset/a903bf4f9acf/ Log: Fix getsyx() and stuff related to repl setup. diff --git a/lib_pypy/_curses.py b/lib_pypy/_curses.py --- a/lib_pypy/_curses.py +++ b/lib_pypy/_curses.py @@ -244,7 +244,6 @@ bool wenclose(const WINDOW *, int, int); int mouseinterval(int); -void getsyx(int y, int x); void setsyx(int y, int x); char *unctrl(chtype); int use_default_colors(void); @@ -278,6 +277,8 @@ int move_panel(PANEL *, int, int); int replace_panel(PANEL *,WINDOW *); int panel_hidden(const PANEL *); + +void _m_getsyx(int *yx); """) @@ -311,6 +312,10 @@ return 0; #endif } + +void _m_getsyx(int *yx) { + getsyx(yx[0], yx[1]); +} """, libraries=['ncurses', 'panel']) @@ -971,7 +976,7 @@ def getsyx(): _ensure_initialised() yx = ffi.new("int[2]") - lib.getsyx(yx[0], yx[1]) + lib._m_getsyx(yx) return (yx[0], yx[1]) @@ -1094,6 +1099,8 @@ if _initialised_setupterm: return None + if term is None: + term = ffi.NULL err = ffi.new("int *") if lib.setupterm(term, fd, err) == lib.ERR: if err == 0: @@ -1321,7 +1328,7 @@ def tigetstr(capname): _ensure_initialised_setupterm() val = lib.tigetstr(capname) - if val == 0 or val == -1: + if val in (0, -1, ffi.NULL): return None return ffi.string(val) From noreply at buildbot.pypy.org Fri Feb 8 10:22:42 2013 From: noreply at buildbot.pypy.org (mattip) Date: Fri, 8 Feb 2013 10:22:42 +0100 (CET) Subject: [pypy-commit] pypy default: move astype to BaseConcreteArray Message-ID: <20130208092242.9489B1C0884@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: Changeset: r60963:28bd3105555c Date: 2013-02-08 11:22 +0200 http://bitbucket.org/pypy/pypy/changeset/28bd3105555c/ Log: move astype to BaseConcreteArray diff --git a/pypy/module/micronumpy/arrayimpl/concrete.py b/pypy/module/micronumpy/arrayimpl/concrete.py --- a/pypy/module/micronumpy/arrayimpl/concrete.py +++ b/pypy/module/micronumpy/arrayimpl/concrete.py @@ -275,6 +275,11 @@ def get_buffer(self, space): return ArrayBuffer(self) + def astype(self, space, dtype): + new_arr = W_NDimArray.from_shape(self.get_shape(), dtype) + loop.copy_from_to(self, new_arr.implementation, dtype) + return new_arr + class ConcreteArrayNotOwning(BaseConcreteArray): def __init__(self, shape, dtype, order, strides, backstrides, storage): @@ -309,11 +314,6 @@ def argsort(self, space, w_axis): return argsort_array(self, space, w_axis) - def astype(self, space, dtype): - new_arr = W_NDimArray.from_shape(self.get_shape(), dtype) - loop.copy_from_to(self, new_arr.implementation, dtype) - return new_arr - def base(self): return None From noreply at buildbot.pypy.org Fri Feb 8 10:28:54 2013 From: noreply at buildbot.pypy.org (RonnyPfannschmidt) Date: Fri, 8 Feb 2013 10:28:54 +0100 (CET) Subject: [pypy-commit] pypy pytest: remove __multicall__ from runtest hooks, mark them as trylast Message-ID: <20130208092854.9D85C1C0884@cobra.cs.uni-duesseldorf.de> Author: Ronny Pfannschmidt Branch: pytest Changeset: r60964:a2980dc0fe2a Date: 2013-02-08 10:24 +0100 http://bitbucket.org/pypy/pypy/changeset/a2980dc0fe2a/ Log: remove __multicall__ from runtest hooks, mark them as trylast diff --git a/pypy/conftest.py b/pypy/conftest.py --- a/pypy/conftest.py +++ b/pypy/conftest.py @@ -132,8 +132,8 @@ cls.space = space return space - -def pytest_runtest_setup(__multicall__, item): + at py.test.mark.trylast +def pytest_runtest_setup(item): if isinstance(item, py.test.collect.Function): appclass = item.getparent(PyPyClassCollector) if appclass is not None: @@ -144,10 +144,9 @@ appclass.obj.space = gettestobjspace(**spaceconfig) appclass.obj.runappdirect = item.config.option.runappdirect - __multicall__.execute() -def pytest_runtest_teardown(__multicall__, item): - __multicall__.execute() + at py.test.mark.trylast +def pytest_runtest_teardown(item): class PyPyClassCollector(py.test.collect.Class): From noreply at buildbot.pypy.org Fri Feb 8 10:28:55 2013 From: noreply at buildbot.pypy.org (RonnyPfannschmidt) Date: Fri, 8 Feb 2013 10:28:55 +0100 (CET) Subject: [pypy-commit] pypy pytest: make winreg tests importable and skipping on unix, use setup_module as well Message-ID: <20130208092855.EA1C01C0884@cobra.cs.uni-duesseldorf.de> Author: Ronny Pfannschmidt Branch: pytest Changeset: r60965:ec2f3369976c Date: 2013-02-08 10:26 +0100 http://bitbucket.org/pypy/pypy/changeset/ec2f3369976c/ Log: make winreg tests importable and skipping on unix, use setup_module as well diff --git a/pypy/module/_winreg/interp_winreg.py b/pypy/module/_winreg/interp_winreg.py --- a/pypy/module/_winreg/interp_winreg.py +++ b/pypy/module/_winreg/interp_winreg.py @@ -2,7 +2,7 @@ from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.gateway import interp2app, unwrap_spec from pypy.interpreter.typedef import TypeDef, GetSetProperty -from pypy.interpreter.error import OperationError, wrap_windowserror +from pypy.interpreter.error import OperationError, wrap_oserror2 from rpython.rtyper.lltypesystem import rffi, lltype from rpython.rlib import rwinreg, rwin32 from rpython.rlib.rarithmetic import r_uint, intmask @@ -691,7 +691,10 @@ try: return space.wrap(rwinreg.ExpandEnvironmentStrings(source)) except WindowsError, e: - raise wrap_windowserror(space, e) + # use it instead of wrap_windowserror + # since it delegates directly to it but is importable on all platforms + # needed for avoiding test failure on unix + raise wrap_oserror2(space, e) def DisableReflectionKey(space, w_key): """Disables registry reflection for 32-bit processes running on a 64-bit diff --git a/pypy/module/_winreg/test/test_winreg.py b/pypy/module/_winreg/test/test_winreg.py --- a/pypy/module/_winreg/test/test_winreg.py +++ b/pypy/module/_winreg/test/test_winreg.py @@ -1,22 +1,24 @@ from rpython.tool.udir import udir import os, sys, py +pytestmark = py.test.mark.skipif('sys.platform != "win32"', reason='_winreg is a win32 module') -if sys.platform != 'win32': - py.test.skip("_winreg is a win32 module") +canSaveKey = None -try: - # To call SaveKey, the process must have Backup Privileges - import win32api - import win32security - priv_flags = win32security.TOKEN_ADJUST_PRIVILEGES | win32security.TOKEN_QUERY - hToken = win32security.OpenProcessToken (win32api.GetCurrentProcess (), priv_flags) - privilege_id = win32security.LookupPrivilegeValue (None, "SeBackupPrivilege") - win32security.AdjustTokenPrivileges (hToken, 0, [(privilege_id, win32security.SE_PRIVILEGE_ENABLED)]) -except: - canSaveKey = False -else: - canSaveKey = True + +def setup_module(mod): + try: + # To call SaveKey, the process must have Backup Privileges + import win32api + import win32security + priv_flags = win32security.TOKEN_ADJUST_PRIVILEGES | win32security.TOKEN_QUERY + hToken = win32security.OpenProcessToken (win32api.GetCurrentProcess (), priv_flags) + privilege_id = win32security.LookupPrivilegeValue (None, "SeBackupPrivilege") + win32security.AdjustTokenPrivileges (hToken, 0, [(privilege_id, win32security.SE_PRIVILEGE_ENABLED)]) + except: + mod.canSaveKey = False + else: + mod.canSaveKey = True class AppTestHKey: spaceconfig = dict(usemodules=('_winreg',)) @@ -36,6 +38,7 @@ cls.test_key_name = "SOFTWARE\\Pypy Registry Test Key - Delete Me" cls.w_root_key = space.wrap(cls.root_key) cls.w_test_key_name = space.wrap(cls.test_key_name) + assert canSaveKey is not None cls.w_canSaveKey = space.wrap(canSaveKey) cls.w_tmpfilename = space.wrap(str(udir.join('winreg-temp'))) From noreply at buildbot.pypy.org Fri Feb 8 10:38:40 2013 From: noreply at buildbot.pypy.org (RonnyPfannschmidt) Date: Fri, 8 Feb 2013 10:38:40 +0100 (CET) Subject: [pypy-commit] pypy pytest: undo merge mistake Message-ID: <20130208093840.290591C0884@cobra.cs.uni-duesseldorf.de> Author: Ronny Pfannschmidt Branch: pytest Changeset: r60966:38762af09d39 Date: 2013-02-08 10:38 +0100 http://bitbucket.org/pypy/pypy/changeset/38762af09d39/ Log: undo merge mistake diff --git a/pypy/conftest.py b/pypy/conftest.py --- a/pypy/conftest.py +++ b/pypy/conftest.py @@ -145,10 +145,6 @@ appclass.obj.runappdirect = item.config.option.runappdirect - at py.test.mark.trylast -def pytest_runtest_teardown(item): - - class PyPyClassCollector(py.test.collect.Class): # All pypy Test classes have a "space" member. def setup(self): From noreply at buildbot.pypy.org Fri Feb 8 11:43:27 2013 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 8 Feb 2013 11:43:27 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: merge default Message-ID: <20130208104327.CC47E1C0110@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r60969:2bddf45f0f34 Date: 2013-02-08 12:43 +0200 http://bitbucket.org/pypy/pypy/changeset/2bddf45f0f34/ Log: merge default diff --git a/lib-python/2.7/collections.py b/lib-python/2.7/collections.py --- a/lib-python/2.7/collections.py +++ b/lib-python/2.7/collections.py @@ -6,11 +6,12 @@ __all__ += _abcoll.__all__ from _collections import deque, defaultdict -from operator import itemgetter as _itemgetter +from operator import itemgetter as _itemgetter, eq as _eq from keyword import iskeyword as _iskeyword import sys as _sys import heapq as _heapq from itertools import repeat as _repeat, chain as _chain, starmap as _starmap +from itertools import imap as _imap try: from thread import get_ident as _get_ident @@ -50,49 +51,45 @@ self.__map = {} self.__update(*args, **kwds) - def __setitem__(self, key, value, PREV=0, NEXT=1, dict_setitem=dict.__setitem__): + def __setitem__(self, key, value, dict_setitem=dict.__setitem__): 'od.__setitem__(i, y) <==> od[i]=y' # Setting a new item creates a new link at the end of the linked list, # and the inherited dictionary is updated with the new key/value pair. if key not in self: root = self.__root - last = root[PREV] - last[NEXT] = root[PREV] = self.__map[key] = [last, root, key] - dict_setitem(self, key, value) + last = root[0] + last[1] = root[0] = self.__map[key] = [last, root, key] + return dict_setitem(self, key, value) - def __delitem__(self, key, PREV=0, NEXT=1, dict_delitem=dict.__delitem__): + def __delitem__(self, key, dict_delitem=dict.__delitem__): 'od.__delitem__(y) <==> del od[y]' # Deleting an existing item uses self.__map to find the link which gets # removed by updating the links in the predecessor and successor nodes. dict_delitem(self, key) link_prev, link_next, key = self.__map.pop(key) - link_prev[NEXT] = link_next - link_next[PREV] = link_prev + link_prev[1] = link_next # update link_prev[NEXT] + link_next[0] = link_prev # update link_next[PREV] def __iter__(self): 'od.__iter__() <==> iter(od)' # Traverse the linked list in order. - NEXT, KEY = 1, 2 root = self.__root - curr = root[NEXT] + curr = root[1] # start at the first node while curr is not root: - yield curr[KEY] - curr = curr[NEXT] + yield curr[2] # yield the curr[KEY] + curr = curr[1] # move to next node def __reversed__(self): 'od.__reversed__() <==> reversed(od)' # Traverse the linked list in reverse order. - PREV, KEY = 0, 2 root = self.__root - curr = root[PREV] + curr = root[0] # start at the last node while curr is not root: - yield curr[KEY] - curr = curr[PREV] + yield curr[2] # yield the curr[KEY] + curr = curr[0] # move to previous node def clear(self): 'od.clear() -> None. Remove all items from od.' - for node in self.__map.itervalues(): - del node[:] root = self.__root root[:] = [root, root, None] self.__map.clear() @@ -208,7 +205,7 @@ ''' if isinstance(other, OrderedDict): - return len(self)==len(other) and self.items() == other.items() + return dict.__eq__(self, other) and all(_imap(_eq, self, other)) return dict.__eq__(self, other) def __ne__(self, other): diff --git a/lib_pypy/greenlet.py b/lib_pypy/greenlet.py --- a/lib_pypy/greenlet.py +++ b/lib_pypy/greenlet.py @@ -1,5 +1,6 @@ import _continuation, sys +__version__ = "0.4.0" # ____________________________________________________________ # Exceptions diff --git a/lib_pypy/pyrepl/unix_console.py b/lib_pypy/pyrepl/unix_console.py --- a/lib_pypy/pyrepl/unix_console.py +++ b/lib_pypy/pyrepl/unix_console.py @@ -398,6 +398,7 @@ if hasattr(self, 'old_sigwinch'): signal.signal(signal.SIGWINCH, self.old_sigwinch) + del self.old_sigwinch def __sigwinch(self, signum, frame): self.height, self.width = self.getheightwidth() diff --git a/pypy/interpreter/app_main.py b/pypy/interpreter/app_main.py --- a/pypy/interpreter/app_main.py +++ b/pypy/interpreter/app_main.py @@ -436,11 +436,14 @@ # (relevant in case of "reload(sys)") sys.argv[:] = argv - if PYTHON26 and not options["ignore_environment"]: - if os.getenv('PYTHONNOUSERSITE'): - options["no_user_site"] = 1 - if os.getenv('PYTHONDONTWRITEBYTECODE'): - options["dont_write_bytecode"] = 1 + if not options["ignore_environment"]: + if os.getenv('PYTHONUNBUFFERED'): + options["unbuffered"] = 1 + if PYTHON26: + if os.getenv('PYTHONNOUSERSITE'): + options["no_user_site"] = 1 + if os.getenv('PYTHONDONTWRITEBYTECODE'): + options["dont_write_bytecode"] = 1 if (options["interactive"] or (not options["ignore_environment"] and os.getenv('PYTHONINSPECT'))): @@ -716,7 +719,7 @@ root = dn(dn(dn(thisfile))) return [join(root, 'lib-python', '2.7'), join(root, 'lib_pypy')] - + def pypy_resolvedirof(s): # we ignore the issue of symlinks; for tests, the executable is always # interpreter/app_main.py anyway @@ -756,6 +759,10 @@ del os # make sure that os is not available globally, because this is what # happens in "real life" outside the tests + if 'time' not in sys.builtin_module_names: + # make some tests happy by loading this before we clobber sys.path + import time; del time + # no one should change to which lists sys.argv and sys.path are bound old_argv = sys.argv old_path = sys.path diff --git a/pypy/interpreter/test2/test_app_main.py b/pypy/interpreter/test2/test_app_main.py --- a/pypy/interpreter/test2/test_app_main.py +++ b/pypy/interpreter/test2/test_app_main.py @@ -712,6 +712,26 @@ assert data == '\x00(STDOUT)\n\x00' # from stdout child_out_err.close() + def test_non_interactive_stdout_unbuffered(self, monkeypatch): + monkeypatch.setenv('PYTHONUNBUFFERED', '1') + path = getscript(r""" + import sys, time + sys.stdout.write('\x00(STDOUT)\n\x00') + time.sleep(1) + sys.stderr.write('\x00[STDERR]\n\x00') + time.sleep(1) + # stdout flushed automatically here + """) + cmdline = '%s -E "%s" %s' % (sys.executable, app_main, path) + print 'POPEN:', cmdline + child_in, child_out_err = os.popen4(cmdline) + data = child_out_err.read(11) + assert data == '\x00(STDOUT)\n\x00' # from stderr + data = child_out_err.read(11) + assert data == '\x00[STDERR]\n\x00' # from stdout + child_out_err.close() + child_in.close() + def test_proper_sys_path(self, tmpdir): data = self.run('-c "import _ctypes"', python_flags='-S') if data.startswith('Traceback'): diff --git a/pypy/module/__pypy__/__init__.py b/pypy/module/__pypy__/__init__.py --- a/pypy/module/__pypy__/__init__.py +++ b/pypy/module/__pypy__/__init__.py @@ -14,7 +14,7 @@ class TimeModule(MixedModule): appleveldefs = {} interpleveldefs = {} - if sys.platform.startswith("linux"): + if sys.platform.startswith("linux") or 'bsd' in sys.platform: from pypy.module.__pypy__ import interp_time interpleveldefs["clock_gettime"] = "interp_time.clock_gettime" interpleveldefs["clock_getres"] = "interp_time.clock_getres" diff --git a/pypy/module/_cffi_backend/cbuffer.py b/pypy/module/_cffi_backend/cbuffer.py --- a/pypy/module/_cffi_backend/cbuffer.py +++ b/pypy/module/_cffi_backend/cbuffer.py @@ -2,7 +2,7 @@ from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.buffer import RWBuffer from pypy.interpreter.gateway import unwrap_spec, interp2app -from pypy.interpreter.typedef import TypeDef +from pypy.interpreter.typedef import TypeDef, make_weakref_descr from rpython.rtyper.lltypesystem import rffi from pypy.module._cffi_backend import cdataobj, ctypeptr, ctypearray @@ -41,8 +41,9 @@ # a different subclass of Wrappable for the MiniBuffer, because we # want a slightly different (simplified) API at the level of Python. - def __init__(self, buffer): + def __init__(self, buffer, keepalive=None): self.buffer = buffer + self.keepalive = keepalive def descr_len(self, space): return self.buffer.descr_len(space) @@ -65,6 +66,7 @@ __getitem__ = interp2app(MiniBuffer.descr_getitem), __setitem__ = interp2app(MiniBuffer.descr_setitem), __buffer__ = interp2app(MiniBuffer.descr__buffer__), + __weakref__ = make_weakref_descr(MiniBuffer), ) MiniBuffer.typedef.acceptable_as_base_class = False @@ -86,4 +88,4 @@ raise operationerrfmt(space.w_TypeError, "don't know the size pointed to by '%s'", ctype.name) - return space.wrap(MiniBuffer(LLBuffer(cdata._cdata, size))) + return space.wrap(MiniBuffer(LLBuffer(cdata._cdata, size), cdata)) diff --git a/pypy/module/_cffi_backend/test/_backend_test_c.py b/pypy/module/_cffi_backend/test/_backend_test_c.py --- a/pypy/module/_cffi_backend/test/_backend_test_c.py +++ b/pypy/module/_cffi_backend/test/_backend_test_c.py @@ -12,6 +12,7 @@ return eval('u'+repr(other).replace(r'\\u', r'\u') .replace(r'\\U', r'\U')) u = U() + str2bytes = str else: type_or_class = "class" long = int @@ -22,6 +23,7 @@ bytechr = lambda n: bytes([n]) bitem2bchr = bytechr u = "" + str2bytes = lambda s: bytes(s, "ascii") def size_of_int(): BInt = new_primitive_type("int") @@ -1438,10 +1440,16 @@ import _weakref BInt = new_primitive_type("int") BPtr = new_pointer_type(BInt) - _weakref.ref(BInt) - _weakref.ref(newp(BPtr, 42)) - _weakref.ref(cast(BPtr, 42)) - _weakref.ref(cast(BInt, 42)) + rlist = [_weakref.ref(BInt), + _weakref.ref(newp(BPtr, 42)), + _weakref.ref(cast(BPtr, 42)), + _weakref.ref(cast(BInt, 42)), + _weakref.ref(buffer(newp(BPtr, 42))), + ] + for i in range(5): + import gc; gc.collect() + if [r() for r in rlist] == [None for r in rlist]: + break def test_no_inheritance(): BInt = new_primitive_type("int") @@ -2544,3 +2552,15 @@ BCharP = new_pointer_type(new_primitive_type("char")) BCharArray = new_array_type(BCharP, None) py.test.raises(TypeError, newp, BCharArray, u+'foobar') + +def test_buffer_keepalive(): + BCharP = new_pointer_type(new_primitive_type("char")) + BCharArray = new_array_type(BCharP, None) + buflist = [] + for i in range(20): + c = newp(BCharArray, str2bytes("hi there %d" % i)) + buflist.append(buffer(c)) + import gc; gc.collect() + for i in range(20): + buf = buflist[i] + assert buf[:] == str2bytes("hi there %d\x00" % i) diff --git a/pypy/module/_multibytecodec/c_codecs.py b/pypy/module/_multibytecodec/c_codecs.py --- a/pypy/module/_multibytecodec/c_codecs.py +++ b/pypy/module/_multibytecodec/c_codecs.py @@ -62,7 +62,7 @@ "pypy_cjk_enc_init", "pypy_cjk_enc_free", "pypy_cjk_enc_chunk", "pypy_cjk_enc_reset", "pypy_cjk_enc_outbuf", "pypy_cjk_enc_outlen", "pypy_cjk_enc_inbuf_remaining", "pypy_cjk_enc_inbuf_consumed", - "pypy_cjk_enc_replace_on_error", + "pypy_cjk_enc_replace_on_error", "pypy_cjk_enc_getcodec", ] + ["pypy_cjkcodec_%s" % codec for codec in codecs], ) diff --git a/pypy/module/micronumpy/arrayimpl/concrete.py b/pypy/module/micronumpy/arrayimpl/concrete.py --- a/pypy/module/micronumpy/arrayimpl/concrete.py +++ b/pypy/module/micronumpy/arrayimpl/concrete.py @@ -275,6 +275,11 @@ def get_buffer(self, space): return ArrayBuffer(self) + def astype(self, space, dtype): + new_arr = W_NDimArray.from_shape(self.get_shape(), dtype) + loop.copy_from_to(self, new_arr.implementation, dtype) + return new_arr + class ConcreteArrayNotOwning(BaseConcreteArray): def __init__(self, shape, dtype, order, strides, backstrides, storage): @@ -309,11 +314,6 @@ def argsort(self, space, w_axis): return argsort_array(self, space, w_axis) - def astype(self, space, dtype): - new_arr = W_NDimArray.from_shape(self.get_shape(), dtype) - loop.copy_from_to(self, new_arr.implementation, dtype) - return new_arr - def base(self): return None diff --git a/pypy/module/micronumpy/arrayimpl/scalar.py b/pypy/module/micronumpy/arrayimpl/scalar.py --- a/pypy/module/micronumpy/arrayimpl/scalar.py +++ b/pypy/module/micronumpy/arrayimpl/scalar.py @@ -7,18 +7,19 @@ class ScalarIterator(base.BaseArrayIterator): def __init__(self, v): self.v = v + self.called_once = False def next(self): - pass + self.called_once = True def getitem(self): - return self.v + return self.v.get_scalar_value() def setitem(self, v): - raise Exception("Don't call setitem on scalar iterators") + self.v.set_scalar_value(v) def done(self): - raise Exception("should not call done on scalar") + return self.called_once def reset(self): pass @@ -38,7 +39,7 @@ return [] def create_iter(self, shape=None): - return ScalarIterator(self.value) + return ScalarIterator(self) def get_scalar_value(self): return self.value diff --git a/pypy/module/micronumpy/base.py b/pypy/module/micronumpy/base.py --- a/pypy/module/micronumpy/base.py +++ b/pypy/module/micronumpy/base.py @@ -21,11 +21,13 @@ @staticmethod def from_shape(shape, dtype, order='C'): - from pypy.module.micronumpy.arrayimpl import concrete - - assert shape - strides, backstrides = calc_strides(shape, dtype, order) - impl = concrete.ConcreteArray(shape, dtype, order, strides, + from pypy.module.micronumpy.arrayimpl import concrete, scalar + + if not shape: + impl = scalar.Scalar(dtype) + else: + strides, backstrides = calc_strides(shape, dtype, order) + impl = concrete.ConcreteArray(shape, dtype, order, strides, backstrides) return W_NDimArray(impl) diff --git a/pypy/module/micronumpy/test/test_numarray.py b/pypy/module/micronumpy/test/test_numarray.py --- a/pypy/module/micronumpy/test/test_numarray.py +++ b/pypy/module/micronumpy/test/test_numarray.py @@ -1640,7 +1640,7 @@ assert _weakref.ref(a) def test_astype(self): - from _numpypy import array + from _numpypy import array, arange b = array(1).astype(float) assert b == 1 assert b.dtype == float @@ -1653,7 +1653,9 @@ b = array([0, 1, 2], dtype=complex).astype(bool) assert (b == [False, True, True]).all() assert b.dtype == 'bool' - + + a = arange(6, dtype='f4').reshape(2,3) + b = a.astype('i4') def test_base(self): from _numpypy import array @@ -1700,6 +1702,12 @@ n = a.dtype.itemsize assert s1[n-1] == s2[0] + a = array(0., dtype='longfloat') + s1 = map(ord, a.tostring()) + s2 = map(ord, a.byteswap().tostring()) + n = a.dtype.itemsize + assert s1[n-1] == s2[0] + def test_clip(self): from _numpypy import array a = array([1, 2, 17, -3, 12]) @@ -2368,6 +2376,7 @@ assert array([1, 2, 3], 'i2')[::2].tostring() == '\x01\x00\x03\x00' assert array([1, 2, 3], 'i2')[::2].tostring() == '\x00\x01\x00\x03' + assert array(0, dtype='i2').tostring() == '\x00\x00' def test_argsort_dtypes(self): from _numpypy import array, arange diff --git a/pypy/module/posix/test/test_posix2.py b/pypy/module/posix/test/test_posix2.py --- a/pypy/module/posix/test/test_posix2.py +++ b/pypy/module/posix/test/test_posix2.py @@ -514,12 +514,14 @@ assert res == '1\n' def test_popen_child_fds(self): - os = self.posix - from os.path import join - with open(join(self.pdir, 'file1'), 'r') as fd: - with os.popen('%s -c "import os; print os.read(%d, 10)"' % (self.python, fd.fileno())) as stream: + import os + with open(os.path.join(self.pdir, 'file1'), 'r') as fd: + with self.posix.popen('%s -c "import os; print os.read(%d, 10)" 2>&1' % (self.python, fd.fileno())) as stream: res = stream.read() - assert res == 'test1\n' + if os.name == 'nt': + assert '\nOSError: [Errno 9]' in res + else: + assert res == 'test1\n' if hasattr(__import__(os.name), '_getfullpathname'): def test__getfullpathname(self): diff --git a/pypy/module/pyexpat/interp_pyexpat.py b/pypy/module/pyexpat/interp_pyexpat.py --- a/pypy/module/pyexpat/interp_pyexpat.py +++ b/pypy/module/pyexpat/interp_pyexpat.py @@ -443,7 +443,10 @@ if XML_ParserFree: # careful with CPython interpreter shutdown XML_ParserFree(self.itself) if global_storage: - global_storage.free_nonmoving_id(self.id) + try: + global_storage.free_nonmoving_id(self.id) + except KeyError: + pass # maybe global_storage.clear() was already called @unwrap_spec(flag=int) def SetParamEntityParsing(self, space, flag): @@ -636,10 +639,13 @@ def ParseFile(self, space, w_file): """ParseFile(file) Parse XML data from file-like object.""" - # XXX not the more efficient method - w_data = space.call_method(w_file, 'read') - data = space.str_w(w_data) - return self.Parse(space, data, isfinal=True) + eof = False + while not eof: + w_data = space.call_method(w_file, 'read', space.wrap(2048)) + data = space.str_w(w_data) + eof = len(data) == 0 + w_res = self.Parse(space, data, isfinal=eof) + return w_res @unwrap_spec(base=str) def SetBase(self, space, base): diff --git a/pypy/module/pyexpat/test/test_parser.py b/pypy/module/pyexpat/test/test_parser.py --- a/pypy/module/pyexpat/test/test_parser.py +++ b/pypy/module/pyexpat/test/test_parser.py @@ -146,3 +146,24 @@ def test_model(self): import pyexpat assert isinstance(pyexpat.model.XML_CTYPE_EMPTY, int) + + def test_read_chunks(self): + import pyexpat + import StringIO + from contextlib import closing + + xml = '' + (' ' * 4096) + '' + with closing(StringIO.StringIO(xml)) as sio: + class FakeReader(): + def __init__(self): + self.read_count = 0 + + def read(self, size): + self.read_count += 1 + assert size > 0 + return sio.read(size) + + fake_reader = FakeReader() + p = pyexpat.ParserCreate() + p.ParseFile(fake_reader) + assert fake_reader.read_count == 4 diff --git a/pypy/module/rctime/test/test_rctime.py b/pypy/module/rctime/test/test_rctime.py --- a/pypy/module/rctime/test/test_rctime.py +++ b/pypy/module/rctime/test/test_rctime.py @@ -237,7 +237,7 @@ # input to [w]strftime is not kosher. if os.name == 'nt': raises(ValueError, rctime.strftime, '%f') - elif sys.platform == 'darwin': + elif sys.platform == 'darwin' or 'bsd' in sys.platform: # darwin strips % of unknown format codes # http://bugs.python.org/issue9811 assert rctime.strftime('%f') == 'f' diff --git a/pypy/module/signal/test/test_signal.py b/pypy/module/signal/test/test_signal.py --- a/pypy/module/signal/test/test_signal.py +++ b/pypy/module/signal/test/test_signal.py @@ -157,7 +157,7 @@ if sys.platform == 'win32': raises(ValueError, signal, 42, lambda *args: None) raises(ValueError, signal, 7, lambda *args: None) - elif sys.platform == 'darwin': + elif sys.platform == 'darwin' or 'bsd' in sys.platform: raises(ValueError, signal, 42, lambda *args: None) else: signal(42, lambda *args: None) diff --git a/pypy/module/zipimport/interp_zipimport.py b/pypy/module/zipimport/interp_zipimport.py --- a/pypy/module/zipimport/interp_zipimport.py +++ b/pypy/module/zipimport/interp_zipimport.py @@ -172,24 +172,24 @@ return mtime def check_newer_pyfile(self, space, filename, timestamp): + # check if the timestamp stored in the .pyc is matching + # the actual timestamp of the .py file, if any mtime = self._parse_mtime(space, filename) if mtime == 0: return False - return mtime > timestamp - - def check_compatible_mtime(self, space, filename, timestamp): - mtime = self._parse_mtime(space, filename) - if mtime == 0 or mtime != (timestamp & (~1)): - return False - return True + # Lenient date/time comparison function. The precision of the mtime + # in the archive is lower than the mtime stored in a .pyc: we + # must allow a difference of at most one second. + d = mtime - timestamp + if d < 0: + d = -d + return d > 1 # more than one second => different def can_use_pyc(self, space, filename, magic, timestamp): if magic != importing.get_pyc_magic(space): return False if self.check_newer_pyfile(space, filename[:-1], timestamp): return False - if not self.check_compatible_mtime(space, filename, timestamp): - return False return True def import_pyc_file(self, space, modname, filename, buf, pkgpath): diff --git a/pypy/module/zipimport/test/test_zipimport.py b/pypy/module/zipimport/test/test_zipimport.py --- a/pypy/module/zipimport/test/test_zipimport.py +++ b/pypy/module/zipimport/test/test_zipimport.py @@ -95,6 +95,9 @@ """) self.w_modules = [] + def w_now_in_the_future(self, delta): + self.now += delta + def w_writefile(self, filename, data): import sys import time @@ -264,10 +267,12 @@ import os import zipimport data = "saddsadsa" + pyc_data = self.test_pyc + self.now_in_the_future(+5) # write the zipfile 5 secs after the .pyc self.writefile("xxx", data) self.writefile("xx/__init__.py", "5") self.writefile("yy.py", "3") - self.writefile('uu.pyc', self.test_pyc) + self.writefile('uu.pyc', pyc_data) z = zipimport.zipimporter(self.zipfile) assert z.get_data(self.zipfile + os.sep + "xxx") == data assert z.is_package("xx") @@ -277,6 +282,7 @@ raises(ImportError, "z.get_source('zz')") #assert z.get_code('yy') == py.code.Source('3').compile() #assert z.get_code('uu') == self.co + assert z.get_code('uu') assert z.get_code('xx') assert z.get_source('xx') == "5" assert z.archive == self.zipfile diff --git a/rpython/annotator/description.py b/rpython/annotator/description.py --- a/rpython/annotator/description.py +++ b/rpython/annotator/description.py @@ -497,8 +497,8 @@ # will do the right thing in s_get_value(). if isinstance(value, staticmethod) and mixin: # make a new copy of staticmethod - value = staticmethod(func_with_new_name(value.__func__, - value.__func__.__name__)) + func = value.__get__(42) + value = staticmethod(func_with_new_name(func, func.__name__)) if type(value) in MemberDescriptorTypes: # skip __slots__, showing up in the class as 'member' objects diff --git a/rpython/translator/platform/posix.py b/rpython/translator/platform/posix.py --- a/rpython/translator/platform/posix.py +++ b/rpython/translator/platform/posix.py @@ -49,10 +49,10 @@ response_file = self._make_response_file("dynamic-symbols-") f = response_file.open("w") - f.write("{\n") + f.write("{\n\tglobal:\n") for sym in eci.export_symbols: - f.write("%s;\n" % (sym,)) - f.write("};") + f.write("\t\t%s;\n" % (sym,)) + f.write("\tlocal:\n\t\t*;\n};") f.close() if relto: diff --git a/rpython/translator/tool/test/test_cbuild.py b/rpython/translator/tool/test/test_cbuild.py --- a/rpython/translator/tool/test/test_cbuild.py +++ b/rpython/translator/tool/test/test_cbuild.py @@ -77,6 +77,10 @@ int get() { return 42; + } + int shouldnt_export() + { + return 43; }'''], export_symbols = ['get'] ) @@ -87,6 +91,7 @@ except ImportError: py.test.skip("Need ctypes for that test") assert ctypes.CDLL(neweci.libraries[0]).get() == 42 + assert not hasattr(ctypes.CDLL(neweci.libraries[0]), 'shouldnt_export') assert not neweci.separate_module_sources assert not neweci.separate_module_files From noreply at buildbot.pypy.org Fri Feb 8 12:45:37 2013 From: noreply at buildbot.pypy.org (mattip) Date: Fri, 8 Feb 2013 12:45:37 +0100 (CET) Subject: [pypy-commit] pypy python-numpy: merge from default Message-ID: <20130208114537.952911C02E4@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: python-numpy Changeset: r60970:d617732c1123 Date: 2013-02-08 11:25 +0200 http://bitbucket.org/pypy/pypy/changeset/d617732c1123/ Log: merge from default diff --git a/pypy/module/micronumpy/arrayimpl/concrete.py b/pypy/module/micronumpy/arrayimpl/concrete.py --- a/pypy/module/micronumpy/arrayimpl/concrete.py +++ b/pypy/module/micronumpy/arrayimpl/concrete.py @@ -275,6 +275,11 @@ def get_buffer(self, space): return ArrayBuffer(self) + def astype(self, space, dtype): + new_arr = W_NDimArray.from_shape(self.get_shape(), dtype) + loop.copy_from_to(self, new_arr.implementation, dtype) + return new_arr + class ConcreteArrayNotOwning(BaseConcreteArray): def __init__(self, shape, dtype, order, strides, backstrides, storage): @@ -309,11 +314,6 @@ def argsort(self, space, w_axis): return argsort_array(self, space, w_axis) - def astype(self, space, dtype): - new_arr = W_NDimArray.from_shape(self.get_shape(), dtype) - loop.copy_from_to(self, new_arr.implementation, dtype) - return new_arr - def base(self): return None diff --git a/pypy/module/micronumpy/test/test_numarray.py b/pypy/module/micronumpy/test/test_numarray.py --- a/pypy/module/micronumpy/test/test_numarray.py +++ b/pypy/module/micronumpy/test/test_numarray.py @@ -1640,7 +1640,7 @@ assert _weakref.ref(a) def test_astype(self): - from _numpypy import array + from _numpypy import array, arange b = array(1).astype(float) assert b == 1 assert b.dtype == float @@ -1653,7 +1653,9 @@ b = array([0, 1, 2], dtype=complex).astype(bool) assert (b == [False, True, True]).all() assert b.dtype == 'bool' - + + a = arange(6, dtype='f4').reshape(2,3) + b = a.astype('i4') def test_base(self): from _numpypy import array diff --git a/rpython/annotator/description.py b/rpython/annotator/description.py --- a/rpython/annotator/description.py +++ b/rpython/annotator/description.py @@ -497,8 +497,8 @@ # will do the right thing in s_get_value(). if isinstance(value, staticmethod) and mixin: # make a new copy of staticmethod - value = staticmethod(func_with_new_name(value.__func__, - value.__func__.__name__)) + func = value.__get__(42) + value = staticmethod(func_with_new_name(func, func.__name__)) if type(value) in MemberDescriptorTypes: # skip __slots__, showing up in the class as 'member' objects From noreply at buildbot.pypy.org Fri Feb 8 12:45:38 2013 From: noreply at buildbot.pypy.org (mattip) Date: Fri, 8 Feb 2013 12:45:38 +0100 (CET) Subject: [pypy-commit] pypy python-numpy: update HOWTO for this branch Message-ID: <20130208114538.E28581C0634@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: python-numpy Changeset: r60971:5a8676a23e8a Date: 2013-02-08 13:45 +0200 http://bitbucket.org/pypy/pypy/changeset/5a8676a23e8a/ Log: update HOWTO for this branch diff --git a/HOW_TO_CONTRIBUTE.txt b/HOW_TO_CONTRIBUTE.txt --- a/HOW_TO_CONTRIBUTE.txt +++ b/HOW_TO_CONTRIBUTE.txt @@ -2,38 +2,31 @@ from a random version of numpy (git version fd15162 to be exact). pypy has a builtin module called _numpypy that provides things like -ndarray, dtypes, ufuncs, and binfuncs. +ndarray, dtypes, ufuncs, and binfuncs. It has no linalg module, and +lots is missing or incomplete. -The branch will be complete when it is possible to run -pypy -c 'import numpy;numpy.test()' and most tests pass. +The strategy for completing this branch is: +1. Find missing functionality or a failing test +2. Fix and test -The strategy for completing the branch is: -1. Set up pypy and cpython -2. Find missing functionality or a failing test -3. Fix and test +And in more detail (asusming you already can run tests on untranslated pypy: +1a. download a nightly default branch version of pypy +1a. copy the pypy executable into pypy/bin +1c. update to this branch +1d. run 'pypy/bin/pypy -c "import numpy; numpy.test(verbose=2)" +2a. if the failure is pure python, update it on this branch. +2b. if the failure is deeper, the failing part of the test probably + belongs in pypy/module/micronumpy/tests. Transplant the test there + and submit a patch to pypy +Let us know you are planning to work on this, usually a note on IRC will be sufficient. -Currently, 'import numpy' fails, since we are missing the -c-level multiarray module. +It may be possible to run on an untranslated pypy, the command line to do this is +python pypy/bin/pyinteractive.py --withmod-micronumpy --withmod-struct --withmod-binascii --withmod-itertools --withmod-rctime --withmod-signal +I didn't have much luck, even something as simple as +>>>import numpy as np +>>>x = np.array([np.nan, np.inf]) +>>>print x +failed, where a translated pypy succeeded, but ymmv -So what we need in the short-term is to implement a python version of -multiarray, work has been begun and it lives in lib_pypy/numpypy/multiarray.py -And in more detail: -1a. Get a recent trunk version of numpy -1a. Install numpy into python, for extra points use virtualenv, by running 'python setup.py install' in the numpy trunk -1c. Get the source tree for this branch of pypy -1d. Download a nightly build of pypy and put the binary into the source tree, preferably at pypy/translator/goal/pypy. Alternatively, translate pypy -2a. Run 'pypy/translator/goal/pypy -c 'import numpy;numpy.test()' -2b. Something will fail. Poke around to see what the missing function or import is supposed to do. Hint: try http://docs.scipy.org/doc/numpy/reference/index.html -2c. Let us know you are planning to work on this, usually a note on IRC will be sufficient. -2c. Write a test for the missing functionality. For instance, tests for multiarray live in lib_pypy/numpypy/test/test_multiarray.py Try to think of corner cases: inappropriate arguments, missing defaults, and other wierd combination of arguments. -3a. Try to find where numpy implemented it and stare at that till it makes sense. -3b. Write some code -3c. Test under pypy, python, and then think again about the tests, did you miss a corner case? Testing is done by: - pypy/translator/pypy pytest.py lib_pypy/numpypy/test -as well as - python pytest.py lib_pypy/numpypy/test -3d. Rerun 2a to make sure you accomplished what you set out to do -3e. Commit and push your changes, if you are working on a fork let us know what you have done. - - +Matti Picus (mattip on IRC) From noreply at buildbot.pypy.org Fri Feb 8 13:52:16 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Fri, 8 Feb 2013 13:52:16 +0100 (CET) Subject: [pypy-commit] pypy default: cleanup signal module and fix win32 behavior Message-ID: <20130208125216.9C2391C02E4@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r60972:ace3ca8195f3 Date: 2013-02-08 07:51 -0500 http://bitbucket.org/pypy/pypy/changeset/ace3ca8195f3/ Log: cleanup signal module and fix win32 behavior diff --git a/pypy/module/signal/interp_signal.py b/pypy/module/signal/interp_signal.py --- a/pypy/module/signal/interp_signal.py +++ b/pypy/module/signal/interp_signal.py @@ -115,6 +115,11 @@ class Handlers: def __init__(self, space): self.handlers_w = {} + for signum in range(1, NSIG): + if WIN32 and signum not in signal_values: + self.handlers_w[signum] = space.w_None + else: + self.handlers_w[signum] = space.wrap(SIG_DFL) def _get_handlers(space): return space.fromcache(Handlers).handlers_w @@ -144,17 +149,12 @@ Return the current action for the given signal. The return value can be: SIG_IGN -- if the signal is being ignored SIG_DFL -- if the default action for the signal is in effect - None -- if an unknown handler is in effect (XXX UNIMPLEMENTED) + None -- if an unknown handler is in effect anything else -- the callable Python object used as a handler """ - if WIN32: - check_signum_exists(space, signum) - else: - check_signum_in_range(space, signum) + check_signum_in_range(space, signum) handlers_w = _get_handlers(space) - if signum in handlers_w: - return handlers_w[signum] - return space.wrap(SIG_DFL) + return handlers_w[signum] def default_int_handler(space, w_signum, w_frame): @@ -180,13 +180,6 @@ return space.w_None -def check_signum_exists(space, signum): - if signum in signal_values: - return - raise OperationError(space.w_ValueError, - space.wrap("invalid signal value")) - - def check_signum_in_range(space, signum): if 1 <= signum < NSIG: return @@ -208,11 +201,13 @@ A signal handler function is called with two arguments: the first is the signal number, the second is the interrupted stack frame. """ + if WIN32 and signum not in signal_values: + raise OperationError(space.w_ValueError, + space.wrap("invalid signal value")) if not space.threadlocals.ismainthread(): raise OperationError(space.w_ValueError, - space.wrap("signal() must be called from the " - "main thread")) - old_handler = getsignal(space, signum) + space.wrap("signal only works in main thread")) + check_signum_in_range(space, signum) if space.eq_w(w_handler, space.wrap(SIG_DFL)): pypysig_default(signum) @@ -224,7 +219,9 @@ space.wrap("'handler' must be a callable " "or SIG_DFL or SIG_IGN")) pypysig_setflag(signum) + handlers_w = _get_handlers(space) + old_handler = handlers_w[signum] handlers_w[signum] = w_handler return old_handler @@ -249,7 +246,7 @@ @jit.dont_look_inside @unwrap_spec(signum=int, flag=int) def siginterrupt(space, signum, flag): - check_signum_exists(space, signum) + check_signum_in_range(space, signum) if rffi.cast(lltype.Signed, c_siginterrupt(signum, flag)) < 0: errno = rposix.get_errno() raise OperationError(space.w_RuntimeError, space.wrap(errno)) diff --git a/pypy/module/signal/test/test_signal.py b/pypy/module/signal/test/test_signal.py --- a/pypy/module/signal/test/test_signal.py +++ b/pypy/module/signal/test/test_signal.py @@ -85,7 +85,6 @@ signal.signal(signum, signal.SIG_DFL) - def test_default_return(self): """ Test that signal.signal returns SIG_DFL if that is the current handler. @@ -99,7 +98,6 @@ finally: signal(SIGINT, SIG_DFL) - def test_ignore_return(self): """ Test that signal.signal returns SIG_IGN if that is the current handler. @@ -113,7 +111,6 @@ finally: signal(SIGINT, SIG_DFL) - def test_obj_return(self): """ Test that signal.signal returns a Python object if one is the current @@ -130,7 +127,6 @@ finally: signal(SIGINT, SIG_DFL) - def test_getsignal(self): """ Test that signal.getsignal returns the currently installed handler. @@ -151,17 +147,18 @@ finally: signal(SIGINT, SIG_DFL) - raises(ValueError, getsignal, 4444) - raises(ValueError, signal, 4444, lambda *args: None) + def test_check_signum(self): import sys + from signal import getsignal, signal, NSIG + + # signum out of range fails + raises(ValueError, getsignal, NSIG) + raises(ValueError, signal, NSIG, lambda *args: None) + + # on windows invalid signal within range should pass getsignal but fail signal if sys.platform == 'win32': - raises(ValueError, signal, 42, lambda *args: None) + assert getsignal(7) == None raises(ValueError, signal, 7, lambda *args: None) - elif sys.platform == 'darwin' or 'bsd' in sys.platform: - raises(ValueError, signal, 42, lambda *args: None) - else: - signal(42, lambda *args: None) - signal(42, SIG_DFL) def test_alarm(self): try: From noreply at buildbot.pypy.org Fri Feb 8 14:11:21 2013 From: noreply at buildbot.pypy.org (RonnyPfannschmidt) Date: Fri, 8 Feb 2013 14:11:21 +0100 (CET) Subject: [pypy-commit] pypy pytest: kill trylast again, it breaks for us Message-ID: <20130208131121.D94FF1C0110@cobra.cs.uni-duesseldorf.de> Author: Ronny Pfannschmidt Branch: pytest Changeset: r60973:761524c30402 Date: 2013-02-08 14:04 +0100 http://bitbucket.org/pypy/pypy/changeset/761524c30402/ Log: kill trylast again, it breaks for us diff --git a/pypy/conftest.py b/pypy/conftest.py --- a/pypy/conftest.py +++ b/pypy/conftest.py @@ -132,7 +132,6 @@ cls.space = space return space - at py.test.mark.trylast def pytest_runtest_setup(item): if isinstance(item, py.test.collect.Function): appclass = item.getparent(PyPyClassCollector) From noreply at buildbot.pypy.org Fri Feb 8 15:35:27 2013 From: noreply at buildbot.pypy.org (RonnyPfannschmidt) Date: Fri, 8 Feb 2013 15:35:27 +0100 (CET) Subject: [pypy-commit] pypy pytest: kill winreg test __init__ to avoid importing and skip on collection instead of execution Message-ID: <20130208143527.32C481C104D@cobra.cs.uni-duesseldorf.de> Author: Ronny Pfannschmidt Branch: pytest Changeset: r60974:1b0b2f5c1cf1 Date: 2013-02-08 15:35 +0100 http://bitbucket.org/pypy/pypy/changeset/1b0b2f5c1cf1/ Log: kill winreg test __init__ to avoid importing and skip on collection instead of execution diff --git a/pypy/module/_winreg/test/__init__.py b/pypy/module/_winreg/test/__init__.py deleted file mode 100644 diff --git a/pypy/module/_winreg/test/test_winreg.py b/pypy/module/_winreg/test/test_winreg.py --- a/pypy/module/_winreg/test/test_winreg.py +++ b/pypy/module/_winreg/test/test_winreg.py @@ -1,10 +1,12 @@ from rpython.tool.udir import udir import os, sys, py -pytestmark = py.test.mark.skipif('sys.platform != "win32"', reason='_winreg is a win32 module') canSaveKey = None +#XXX: mark again +if sys.platform != "win32": + py.test.skip('_winreg is a win32 module') def setup_module(mod): try: From noreply at buildbot.pypy.org Fri Feb 8 16:35:17 2013 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 8 Feb 2013 16:35:17 +0100 (CET) Subject: [pypy-commit] cffi enum-as-int: Enums should behave just like ints. No more using the string of the enum. Message-ID: <20130208153517.EAACF1C02E4@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: enum-as-int Changeset: r1131:71656eb169b2 Date: 2013-02-08 16:34 +0100 http://bitbucket.org/cffi/cffi/changeset/71656eb169b2/ Log: Enums should behave just like ints. No more using the string of the enum. From noreply at buildbot.pypy.org Fri Feb 8 16:35:19 2013 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 8 Feb 2013 16:35:19 +0100 (CET) Subject: [pypy-commit] cffi enum-as-int: Implementation Message-ID: <20130208153519.382381C02E4@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: enum-as-int Changeset: r1132:2b7869e88162 Date: 2013-02-08 16:35 +0100 http://bitbucket.org/cffi/cffi/changeset/2b7869e88162/ Log: Implementation diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c --- a/c/_cffi_backend.c +++ b/c/_cffi_backend.c @@ -823,32 +823,29 @@ return (PyObject *)cd; } -static PyObject *convert_enum_string_to_int(CTypeDescrObject *ct, PyObject *ob) +static PyObject *convert_cdata_to_enum_string(CDataObject *cd, int both) { - PyObject *d_value; - char *p = PyText_AsUTF8(ob); - if (p == NULL) + int value; + PyObject *d_key, *d_value; + CTypeDescrObject *ct = cd->c_type; + + assert(ct->ct_flags & CT_IS_ENUM); + value = (int)read_raw_signed_data(cd->c_data, ct->ct_size); + d_key = PyInt_FromLong(value); + if (d_key == NULL) return NULL; - if (p[0] == '#') { - char *number = p + 1; /* strip initial '#' */ - PyObject *ob2 = PyText_FromString(number); - if (ob2 == NULL) - return NULL; - - d_value = PyNumber_Long(ob2); - Py_DECREF(ob2); - } - else { - d_value = PyDict_GetItem(PyTuple_GET_ITEM(ct->ct_stuff, 0), ob); - if (d_value == NULL) { - PyErr_Format(PyExc_ValueError, - "'%s' is not an enumerator for %s", - p, ct->ct_name); - return NULL; - } - Py_INCREF(d_value); - } + d_value = PyDict_GetItem(PyTuple_GET_ITEM(ct->ct_stuff, 1), d_key); + if (d_value != NULL) { + if (both) + d_value = PyText_FromFormat("%d: %s", value, + PyText_AS_UTF8(d_value)); + else + Py_INCREF(d_value); + } + else + d_value = PyObject_Str(d_key); + Py_DECREF(d_key); return d_value; } @@ -886,21 +883,7 @@ PY_LONG_LONG value; /*READ(data, ct->ct_size)*/ value = read_raw_signed_data(data, ct->ct_size); - - if (ct->ct_flags & CT_IS_ENUM) { - PyObject *d_value, *d_key = PyInt_FromLong((int)value); - if (d_key == NULL) - return NULL; - - d_value = PyDict_GetItem(PyTuple_GET_ITEM(ct->ct_stuff, 1), d_key); - Py_DECREF(d_key); - if (d_value != NULL) - Py_INCREF(d_value); - else - d_value = PyText_FromFormat("#%d", (int)value); - return d_value; - } - else if (ct->ct_flags & CT_PRIMITIVE_FITS_LONG) + if (ct->ct_flags & CT_PRIMITIVE_FITS_LONG) return PyInt_FromLong((long)value); else return PyLong_FromLongLong(value); @@ -1189,27 +1172,8 @@ } if (ct->ct_flags & CT_PRIMITIVE_SIGNED) { PY_LONG_LONG value = _my_PyLong_AsLongLong(init); - - if (value == -1 && PyErr_Occurred()) { - if (!(ct->ct_flags & CT_IS_ENUM)) - return -1; - else { - PyObject *ob; - PyErr_Clear(); - if (!PyTextAny_Check(init)) { - expected = "str or int"; - goto cannot_convert; - } - - ob = convert_enum_string_to_int(ct, init); - if (ob == NULL) - return -1; - value = PyLong_AsLongLong(ob); - Py_DECREF(ob); - if (value == -1 && PyErr_Occurred()) - return -1; - } - } + if (value == -1 && PyErr_Occurred()) + return -1; write_raw_integer_data(buf, value, ct->ct_size); if (value != read_raw_signed_data(buf, ct->ct_size)) goto overflow; @@ -1474,14 +1438,10 @@ PyObject *result, *s; if (cd->c_type->ct_flags & CT_PRIMITIVE_ANY) { - if (!(cd->c_type->ct_flags & CT_IS_LONGDOUBLE)) { - PyObject *o = convert_to_object(cd->c_data, cd->c_type); - if (o == NULL) - return NULL; - s = PyObject_Repr(o); - Py_DECREF(o); + if (cd->c_type->ct_flags & CT_IS_ENUM) { + s = convert_cdata_to_enum_string(cd, 1); } - else { + else if (cd->c_type->ct_flags & CT_IS_LONGDOUBLE) { long double lvalue; char buffer[128]; /* big enough */ /*READ(cd->c_data, sizeof(long double)*/ @@ -1489,6 +1449,13 @@ sprintf(buffer, "%LE", lvalue); s = PyText_FromString(buffer); } + else { + PyObject *o = convert_to_object(cd->c_data, cd->c_type); + if (o == NULL) + return NULL; + s = PyObject_Repr(o); + Py_DECREF(o); + } } else { if (cd->c_data != NULL) { @@ -2586,14 +2553,6 @@ (CT_POINTER|CT_FUNCTIONPTR|CT_ARRAY)) { value = (Py_intptr_t)((CDataObject *)ob)->c_data; } - else if ((ct->ct_flags & CT_IS_ENUM) && PyTextAny_Check(ob)) { - ob = convert_enum_string_to_int(ct, ob); - if (ob == NULL) - return NULL; - cd = cast_to_integer_or_char(ct, ob); - Py_DECREF(ob); - return cd; - } #if PY_MAJOR_VERSION < 3 else if (PyString_Check(ob)) { if (PyString_GET_SIZE(ob) != 1) { @@ -4144,6 +4103,10 @@ dict1 = PyDict_New(); if (dict1 == NULL) goto error; + dict2 = PyDict_New(); + if (dict2 == NULL) + goto error; + for (i=n; --i >= 0; ) { long lvalue; PyObject *value = PyTuple_GET_ITEM(enumvalues, i); @@ -4177,19 +4140,12 @@ } if (PyDict_SetItem(dict1, tmpkey, value) < 0) goto error; + if (PyDict_SetItem(dict2, value, tmpkey) < 0) + goto error; Py_DECREF(tmpkey); tmpkey = NULL; } - dict2 = PyDict_New(); - if (dict2 == NULL) - goto error; - for (i=n; --i >= 0; ) { - if (PyDict_SetItem(dict2, PyTuple_GET_ITEM(enumvalues, i), - PyTuple_GET_ITEM(enumerators, i)) < 0) - goto error; - } - combined = PyTuple_Pack(2, dict1, dict2); if (combined == NULL) goto error; @@ -4437,7 +4393,7 @@ #endif } else if (cd->c_type->ct_flags & CT_IS_ENUM) { - return convert_to_object(cd->c_data, cd->c_type); + return convert_cdata_to_enum_string(cd, 0); } else if (cd->c_type->ct_flags & CT_IS_BOOL) { /* fall through to TypeError */ diff --git a/c/test_c.py b/c/test_c.py --- a/c/test_c.py +++ b/c/test_c.py @@ -1292,22 +1292,20 @@ def test_cast_to_enum(): BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, -20)) e = cast(BEnum, 0) - assert repr(e) == "" + assert repr(e) == "" + assert repr(cast(BEnum, -42)) == "" + assert repr(cast(BEnum, -20)) == "" assert string(e) == 'def' assert string(cast(BEnum, -20)) == 'ab' - assert string(cast(BEnum, 'c')) == 'c' - assert int(cast(BEnum, 'c')) == 1 - assert int(cast(BEnum, 'def')) == 0 + assert int(cast(BEnum, 1)) == 1 + assert int(cast(BEnum, 0)) == 0 assert int(cast(BEnum, -242 + 2**128)) == -242 - assert string(cast(BEnum, -242 + 2**128)) == '#-242' - assert string(cast(BEnum, '#-20')) == 'ab' - assert repr(cast(BEnum, '#-20')) == "" - assert repr(cast(BEnum, '#-21')) == "" + assert string(cast(BEnum, -242 + 2**128)) == '-242' def test_enum_with_non_injective_mapping(): BEnum = new_enum_type("foo", ('ab', 'cd'), (7, 7)) e = cast(BEnum, 7) - assert repr(e) == "" + assert repr(e) == "" assert string(e) == 'ab' def test_enum_in_struct(): @@ -1316,17 +1314,16 @@ BStructPtr = new_pointer_type(BStruct) complete_struct_or_union(BStruct, [('a1', BEnum, -1)]) p = newp(BStructPtr, [-20]) - assert p.a1 == "ab" - p = newp(BStructPtr, ["c"]) - assert p.a1 == "c" + assert p.a1 == -20 + p = newp(BStructPtr, [12]) + assert p.a1 == 12 e = py.test.raises(TypeError, newp, BStructPtr, [None]) - assert "must be a str or int, not NoneType" in str(e.value) + assert "an integer is required" in str(e.value) + py.test.raises(TypeError, 'p.a1 = "def"') if sys.version_info < (3,): - p.a1 = unicode("def") - assert p.a1 == "def" and type(p.a1) is str - py.test.raises(UnicodeEncodeError, "p.a1 = unichr(1234)") BEnum2 = new_enum_type(unicode("foo"), (unicode('abc'),), (5,)) - assert string(cast(BEnum2, unicode('abc'))) == 'abc' + assert string(cast(BEnum2, 5)) == 'abc' + assert type(string(cast(BEnum2, 5))) is str def test_enum_overflow(): for ovf in (2**63, -2**63-1, 2**31, -2**31-1): @@ -1339,13 +1336,17 @@ BInt = new_primitive_type("int") BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, -20)) def cb(n): - return '#%d' % n + if n & 1: + return cast(BEnum, n) + else: + return n BFunc = new_function_type((BInt,), BEnum) f = callback(BFunc, cb) - assert f(0) == 'def' - assert f(1) == 'c' - assert f(-20) == 'ab' - assert f(20) == '#20' + assert f(0) == 0 + assert f(1) == 1 + assert f(-20) == -20 + assert f(20) == 20 + assert f(21) == 21 def test_callback_returning_char(): BInt = new_primitive_type("int") diff --git a/cffi/backend_ctypes.py b/cffi/backend_ctypes.py --- a/cffi/backend_ctypes.py +++ b/cffi/backend_ctypes.py @@ -926,49 +926,27 @@ def new_enum_type(self, name, enumerators, enumvalues): assert isinstance(name, str) - mapping = dict(zip(enumerators, enumvalues)) reverse_mapping = dict(zip(reversed(enumvalues), reversed(enumerators))) CTypesInt = self.ffi._get_cached_btype(model.PrimitiveType('int')) # - def forward_map(source): - if not isinstance(source, str): - return source - try: - return mapping[source] - except KeyError: - if source.startswith('#'): - try: - return int(source[1:]) - except ValueError: - pass - raise ValueError("%r is not an enumerator for %r" % ( - source, CTypesEnum)) - # class CTypesEnum(CTypesInt): __slots__ = [] _reftypename = 'enum %s &' % name + def _get_own_repr(self): + value = self._value + try: + return '%d: %s' % (value, reverse_mapping[value]) + except KeyError: + return str(value) + def _to_string(self, maxlen): - return str(CTypesEnum._from_ctypes(self._value)) - - @classmethod - def _cast_from(cls, source): - source = forward_map(source) - return super(CTypesEnum, cls)._cast_from(source) - - @staticmethod - def _to_ctypes(x): - x = forward_map(x) - return CTypesInt._to_ctypes(x) - - @staticmethod - def _from_ctypes(value): - value = CTypesInt._from_ctypes(value) + value = self._value try: return reverse_mapping[value] except KeyError: - return '#%s' % value + return str(value) # CTypesEnum._fix_class() return CTypesEnum diff --git a/testing/backend_tests.py b/testing/backend_tests.py --- a/testing/backend_tests.py +++ b/testing/backend_tests.py @@ -860,54 +860,52 @@ def test_enum(self): ffi = FFI(backend=self.Backend()) ffi.cdef("enum foo { A, B, CC, D };") - assert int(ffi.cast("enum foo", "A")) == 0 - assert int(ffi.cast("enum foo", "B")) == 1 - assert int(ffi.cast("enum foo", "CC")) == 2 - assert int(ffi.cast("enum foo", "D")) == 3 - ffi.cdef("enum bar { A, B=-2, CC, D };") - assert int(ffi.cast("enum bar", "A")) == 0 - assert int(ffi.cast("enum bar", "B")) == -2 - assert int(ffi.cast("enum bar", "CC")) == -1 - assert int(ffi.cast("enum bar", "D")) == 0 - assert ffi.cast("enum bar", "B") != ffi.cast("enum bar", "B") - assert ffi.cast("enum foo", "A") != ffi.cast("enum bar", "A") - assert ffi.cast("enum bar", "A") != ffi.cast("int", 0) - assert repr(ffi.cast("enum bar", "CC")) == "" - py.test.raises(ValueError, ffi.cast, "enum bar", "UNKNOWN") + assert ffi.string(ffi.cast("enum foo", 0)) == "A" + assert ffi.string(ffi.cast("enum foo", 2)) == "CC" + assert ffi.string(ffi.cast("enum foo", 3)) == "D" + assert ffi.string(ffi.cast("enum foo", 4)) == "4" + ffi.cdef("enum bar { A, B=-2, CC, D, E };") + assert ffi.string(ffi.cast("enum bar", 0)) == "A" + assert ffi.string(ffi.cast("enum bar", -2)) == "B" + assert ffi.string(ffi.cast("enum bar", -1)) == "CC" + assert ffi.string(ffi.cast("enum bar", 1)) == "E" + assert ffi.cast("enum bar", -2) != ffi.cast("enum bar", -2) + assert ffi.cast("enum foo", 0) != ffi.cast("enum bar", 0) + assert ffi.cast("enum bar", 0) != ffi.cast("int", 0) + assert repr(ffi.cast("enum bar", -1)) == "" ffi.cdef("enum baz { A=0x1000, B=0x2000 };") - assert int(ffi.cast("enum baz", "A")) == 0x1000 - assert int(ffi.cast("enum baz", "B")) == 0x2000 + assert ffi.string(ffi.cast("enum baz", 0x1000)) == "A" + assert ffi.string(ffi.cast("enum baz", 0x2000)) == "B" def test_enum_in_struct(self): ffi = FFI(backend=self.Backend()) ffi.cdef("enum foo { A, B, C, D }; struct bar { enum foo e; };") s = ffi.new("struct bar *") s.e = 0 - assert s.e == "A" - s.e = "D" - assert s.e == "D" - assert s[0].e == "D" - s[0].e = "C" - assert s.e == "C" - assert s[0].e == "C" + assert s.e == 0 + s.e = 3 + assert s.e == 3 + assert s[0].e == 3 + s[0].e = 2 + assert s.e == 2 + assert s[0].e == 2 s.e = ffi.cast("enum foo", -1) - assert s.e == '#-1' - assert s[0].e == '#-1' + assert s.e == -1 + assert s[0].e == -1 s.e = s.e - py.test.raises(TypeError, "s.e = None") + py.test.raises(TypeError, "s.e = 'B'") + py.test.raises(TypeError, "s.e = '#2'") + py.test.raises(TypeError, "s.e = '#7'") def test_enum_non_contiguous(self): ffi = FFI(backend=self.Backend()) ffi.cdef("enum foo { A, B=42, C };") - assert int(ffi.cast("enum foo", "A")) == 0 - assert int(ffi.cast("enum foo", "B")) == 42 - assert int(ffi.cast("enum foo", "C")) == 43 assert ffi.string(ffi.cast("enum foo", 0)) == "A" assert ffi.string(ffi.cast("enum foo", 42)) == "B" assert ffi.string(ffi.cast("enum foo", 43)) == "C" invalid_value = ffi.cast("enum foo", 2) assert int(invalid_value) == 2 - assert ffi.string(invalid_value) == "#2" + assert ffi.string(invalid_value) == "2" def test_array_of_struct(self): ffi = FFI(backend=self.Backend()) @@ -1301,7 +1299,7 @@ def test_enum_with_non_injective_mapping(self): ffi = FFI(backend=self.Backend()) ffi.cdef("enum e { AA=0, BB=0, CC=0, DD=0 };") - e = ffi.cast("enum e", 'CC') + e = ffi.cast("enum e", 0) assert ffi.string(e) == "AA" # pick the first one arbitrarily def test_nested_anonymous_struct(self): diff --git a/testing/test_unicode_literals.py b/testing/test_unicode_literals.py --- a/testing/test_unicode_literals.py +++ b/testing/test_unicode_literals.py @@ -49,7 +49,7 @@ def test_enum(): ffi = FFI() ffi.cdef("enum foo_e { AA, BB, CC };") # unicode literal - x = ffi.cast("enum foo_e", "BB") + x = ffi.cast("enum foo_e", 1) assert int(ffi.cast("int", x)) == 1 def test_dlopen(): diff --git a/testing/test_verify.py b/testing/test_verify.py --- a/testing/test_verify.py +++ b/testing/test_verify.py @@ -558,13 +558,12 @@ ffi.cdef("enum ee { EE1, EE2, EE3, ... \n \t };") py.test.raises(VerificationMissing, ffi.cast, 'enum ee', 'EE2') ffi.verify("enum ee { EE1=10, EE2, EE3=-10, EE4 };") - assert int(ffi.cast('enum ee', 'EE2')) == 11 - assert int(ffi.cast('enum ee', 'EE3')) == -10 - py.test.raises(ValueError, ffi.cast, 'enum ee', '__dotdotdot0__') + assert ffi.string(ffi.cast('enum ee', 11)) == "EE2" + assert ffi.string(ffi.cast('enum ee', -10)) == "EE3" # # try again ffi.verify("enum ee { EE1=10, EE2, EE3=-10, EE4 };") - assert int(ffi.cast('enum ee', 'EE2')) == 11 + assert ffi.string(ffi.cast('enum ee', 11)) == "EE2" def test_full_enum(): ffi = FFI() @@ -578,25 +577,35 @@ lib = ffi.verify("enum ee { EE1, EE2, EE3, EE4 };") assert lib.EE3 == 2 +def test_enum_usage(): + ffi = FFI() + ffi.cdef("enum ee { EE1,EE2 }; typedef struct { enum ee x; } *sp;") + lib = ffi.verify("enum ee { EE1,EE2 }; typedef struct { enum ee x; } *sp;") + assert lib.EE2 == 1 + s = ffi.new("sp", [lib.EE2]) + assert s.x == 1 + s.x = 17 + assert s.x == 17 + def test_nonfull_enum_syntax2(): ffi = FFI() ffi.cdef("enum ee { EE1, EE2=\t..., EE3 };") py.test.raises(VerificationMissing, ffi.cast, 'enum ee', 'EE1') ffi.verify("enum ee { EE1=10, EE2, EE3=-10, EE4 };") - assert int(ffi.cast('enum ee', 'EE2')) == 11 - assert int(ffi.cast('enum ee', 'EE3')) == -10 + assert ffi.string(ffi.cast('enum ee', 11)) == 'EE2' + assert ffi.string(ffi.cast('enum ee', -10)) == 'EE3' # ffi = FFI() ffi.cdef("enum ee { EE1, EE2=\t... };") py.test.raises(VerificationMissing, ffi.cast, 'enum ee', 'EE1') ffi.verify("enum ee { EE1=10, EE2, EE3=-10, EE4 };") - assert int(ffi.cast('enum ee', 'EE2')) == 11 + assert ffi.string(ffi.cast('enum ee', 11)) == 'EE2' # ffi = FFI() ffi.cdef("enum ee2 { EE4=..., EE5=..., ... };") ffi.verify("enum ee2 { EE4=-1234-5, EE5 }; ") - assert int(ffi.cast('enum ee2', 'EE4')) == -1239 - assert int(ffi.cast('enum ee2', 'EE5')) == -1238 + assert ffi.string(ffi.cast('enum ee2', -1239)) == 'EE4' + assert ffi.string(ffi.cast('enum ee2', -1238)) == 'EE5' def test_get_set_errno(): ffi = FFI() @@ -961,7 +970,7 @@ int foo_func(enum foo_e e) { return e; } """) assert lib.foo_func(lib.BB) == 2 - assert lib.foo_func("BB") == 2 + py.test.raises(TypeError, lib.foo_func, "BB") def test_enum_as_function_result(): ffi = FFI() @@ -973,7 +982,7 @@ enum foo_e { AA, CC, BB }; enum foo_e foo_func(int x) { return x; } """) - assert lib.foo_func(lib.BB) == "BB" + assert lib.foo_func(lib.BB) == lib.BB == 2 def test_enum_values(): ffi = FFI() @@ -1001,7 +1010,7 @@ ffi = FFI() ffi.cdef("typedef enum { AA, BB, ... } enum1_t;") lib = ffi.verify("typedef enum { AA, CC, BB } enum1_t;") - assert ffi.string(ffi.cast("enum1_t", 1)) == '#1' + assert ffi.string(ffi.cast("enum1_t", 1)) == '1' assert ffi.string(ffi.cast("enum1_t", 2)) == 'BB' assert lib.AA == 0 assert lib.BB == 2 @@ -1016,7 +1025,7 @@ typedef enum { AA, CC, BB } foo_t; foo_t foo_func(int x) { return x; } """) - assert lib.foo_func(lib.BB) == "BB" + assert lib.foo_func(lib.BB) == lib.BB == 2 def test_callback_calling_convention(): py.test.skip("later") @@ -1429,7 +1438,7 @@ ffi2.cdef("int myfunc(enum foo_e);") lib2 = ffi2.verify("enum foo_e { CC, BB, AA };" "int myfunc(enum foo_e x) { return (int)x; }") - res = lib2.myfunc("AA") + res = lib2.myfunc(lib2.AA) assert res == 2 def test_string_to_voidp_arg(): From noreply at buildbot.pypy.org Fri Feb 8 16:41:50 2013 From: noreply at buildbot.pypy.org (bivab) Date: Fri, 8 Feb 2013 16:41:50 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: fix Message-ID: <20130208154150.2921E1C0110@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: jitframe-on-heap Changeset: r60975:bfd3a14ff568 Date: 2013-02-08 16:24 +0100 http://bitbucket.org/pypy/pypy/changeset/bfd3a14ff568/ Log: fix diff --git a/rpython/jit/backend/arm/assembler.py b/rpython/jit/backend/arm/assembler.py --- a/rpython/jit/backend/arm/assembler.py +++ b/rpython/jit/backend/arm/assembler.py @@ -1245,9 +1245,9 @@ offset = loc.value if not check_imm_arg(offset): self.mc.gen_load_int(r.ip.value, offset, cond=cond) - self.mc.SUB_rr(r.ip.value, r.fp.value, r.ip.value, cond=cond) + self.mc.ADD_rr(r.ip.value, r.fp.value, r.ip.value, cond=cond) else: - self.mc.SUB_ri(r.ip.value, r.fp.value, offset, cond=cond) + self.mc.ADD_ri(r.ip.value, r.fp.value, offset, cond=cond) self.mc.VSTR(prev_loc.value, r.ip.value, cond=cond) self.mc.POP([r.ip.value], cond=cond) else: From noreply at buildbot.pypy.org Fri Feb 8 16:41:51 2013 From: noreply at buildbot.pypy.org (bivab) Date: Fri, 8 Feb 2013 16:41:51 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: kill check, does not make sense any more Message-ID: <20130208154151.81D901C0110@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: jitframe-on-heap Changeset: r60976:0bc82182bf6f Date: 2013-02-08 16:30 +0100 http://bitbucket.org/pypy/pypy/changeset/0bc82182bf6f/ Log: kill check, does not make sense any more diff --git a/rpython/jit/backend/arm/assembler.py b/rpython/jit/backend/arm/assembler.py --- a/rpython/jit/backend/arm/assembler.py +++ b/rpython/jit/backend/arm/assembler.py @@ -432,7 +432,6 @@ def _build_failure_recovery(self, exc, withfloats=False): mc = ARMv7Builder() self._push_all_regs_to_jitframe(mc, [], withfloats) - self._insert_checks(mc) if exc: # We might have an exception pending. Load it into r4 @@ -1061,15 +1060,6 @@ asm_math_operations[oopspecindex](self, op, arglocs, regalloc, fcond) return fcond - - def _insert_checks(self, mc=None): - if not we_are_translated() and self._debug: - if mc is None: - mc = self.mc - mc.CMP_rr(r.fp.value, r.sp.value) - mc.MOV_rr(r.pc.value, r.pc.value, cond=c.GE) - mc.BKPT() - def _ensure_result_bit_extension(self, resloc, size, signed): if size == 4: return diff --git a/rpython/jit/backend/arm/opassembler.py b/rpython/jit/backend/arm/opassembler.py --- a/rpython/jit/backend/arm/opassembler.py +++ b/rpython/jit/backend/arm/opassembler.py @@ -339,7 +339,6 @@ target_nbargs = target_token._arm_clt._debug_nbargs assert my_nbargs == target_nbargs - self._insert_checks() if target_token in self.target_tokens_currently_compiling: self.mc.B_offs(target, fcond) else: From noreply at buildbot.pypy.org Fri Feb 8 16:41:52 2013 From: noreply at buildbot.pypy.org (bivab) Date: Fri, 8 Feb 2013 16:41:52 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: more unused code Message-ID: <20130208154152.AFBEF1C0110@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: jitframe-on-heap Changeset: r60977:8a0e03dc520f Date: 2013-02-08 16:31 +0100 http://bitbucket.org/pypy/pypy/changeset/8a0e03dc520f/ Log: more unused code diff --git a/rpython/jit/backend/arm/assembler.py b/rpython/jit/backend/arm/assembler.py --- a/rpython/jit/backend/arm/assembler.py +++ b/rpython/jit/backend/arm/assembler.py @@ -471,49 +471,6 @@ rawstart = mc.materialize(self.cpu.asmmemmgr, []) self.failure_recovery_code[exc + 2 * withfloats] = rawstart - DESCR_REF = 0x00 - DESCR_INT = 0x01 - DESCR_FLOAT = 0x02 - DESCR_SPECIAL = 0x03 - CODE_FROMSTACK = 64 - CODE_STOP = 0 | DESCR_SPECIAL - CODE_HOLE = 4 | DESCR_SPECIAL - CODE_INPUTARG = 8 | DESCR_SPECIAL - CODE_FORCED = 12 | DESCR_SPECIAL #XXX where should this be written? - - def write_failure_recovery_description(self, descr, failargs, locs): - assert self.mc is not None - for i in range(len(failargs)): - arg = failargs[i] - if arg is not None: - if arg.type == REF: - kind = self.DESCR_REF - elif arg.type == INT: - kind = self.DESCR_INT - elif arg.type == FLOAT: - kind = self.DESCR_FLOAT - else: - raise AssertionError("bogus kind") - loc = locs[i] - if loc.is_stack(): - pos = loc.position - if pos < 0: - self.mc.writechar(chr(self.CODE_INPUTARG)) - pos = ~pos - n = self.CODE_FROMSTACK // 4 + pos - else: - assert loc.is_reg() or loc.is_vfp_reg() - n = loc.value - n = kind + 4 * n - while n > 0x7F: - self.mc.writechar(chr((n & 0x7F) | 0x80)) - n >>= 7 - else: - n = self.CODE_HOLE - self.mc.writechar(chr(n)) - self.mc.writechar(chr(self.CODE_STOP)) - - def generate_quick_failure(self, guardtok, fcond=c.AL): assert isinstance(guardtok.exc, bool) startpos = self.mc.currpos() From noreply at buildbot.pypy.org Fri Feb 8 16:41:53 2013 From: noreply at buildbot.pypy.org (bivab) Date: Fri, 8 Feb 2013 16:41:53 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: disable code Message-ID: <20130208154153.E91181C0110@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: jitframe-on-heap Changeset: r60978:86cf63b65bce Date: 2013-02-08 16:34 +0100 http://bitbucket.org/pypy/pypy/changeset/86cf63b65bce/ Log: disable code diff --git a/rpython/jit/backend/arm/regalloc.py b/rpython/jit/backend/arm/regalloc.py --- a/rpython/jit/backend/arm/regalloc.py +++ b/rpython/jit/backend/arm/regalloc.py @@ -1109,9 +1109,9 @@ # end of the same loop, i.e. if what we are compiling is a single # loop that ends up jumping to this LABEL, then we can now provide # the hints about the expected position of the spilled variables. - jump_op = self.final_jump_op - if jump_op is not None and jump_op.getdescr() is descr: - self._compute_hint_frame_locations_from_descr(descr) + #jump_op = self.final_jump_op + #if jump_op is not None and jump_op.getdescr() is descr: + # self._compute_hint_frame_locations_from_descr(descr) def prepare_guard_call_may_force(self, op, guard_op, fcond): args = self._prepare_call(op, save_all_regs=True) From noreply at buildbot.pypy.org Fri Feb 8 16:41:55 2013 From: noreply at buildbot.pypy.org (bivab) Date: Fri, 8 Feb 2013 16:41:55 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: fixes for bridges and jitframe relocation Message-ID: <20130208154155.2A8DE1C0110@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: jitframe-on-heap Changeset: r60979:eaa9093c3214 Date: 2013-02-08 16:36 +0100 http://bitbucket.org/pypy/pypy/changeset/eaa9093c3214/ Log: fixes for bridges and jitframe relocation diff --git a/rpython/jit/backend/arm/assembler.py b/rpython/jit/backend/arm/assembler.py --- a/rpython/jit/backend/arm/assembler.py +++ b/rpython/jit/backend/arm/assembler.py @@ -259,7 +259,7 @@ def _build_stack_check_slowpath(self): _, _, slowpathaddr = self.cpu.insert_stack_check() - if slowpathaddr == 0 or self.cpu.propagate_exception_v < 0: + if slowpathaddr == 0 or not self.cpu.propagate_exception_descr: return # no stack check (for tests, or non-translated) # # make a "function" that is called immediately at the start of @@ -483,12 +483,13 @@ target = self.failure_recovery_code[exc + 2 * withfloats] fail_descr = cast_instance_to_gcref(guardtok.faildescr) fail_descr = rffi.cast(lltype.Signed, fail_descr) + base_ofs = self.cpu.get_baseofs_of_frame_field() positions = [0] * len(guardtok.fail_locs) for i, loc in enumerate(guardtok.fail_locs): if loc is None: positions[i] = -1 elif loc.is_stack(): - positions[i] = loc.value + positions[i] = loc.value - base_ofs else: if loc.is_reg(): assert loc is not r.fp # for now @@ -629,8 +630,8 @@ loop_head = self.mc.get_relative_pos() looptoken._arm_loop_code = loop_head # - frame_depth = self._assemble(regalloc, inputargs, operations) - self.update_frame_depth(frame_depth + JITFRAME_FIXED_SIZE) + frame_depth_no_fixed_size = self._assemble(regalloc, inputargs, operations) + self.update_frame_depth(frame_depth_no_fixed_size + JITFRAME_FIXED_SIZE) # size_excluding_failure_stuff = self.mc.get_relative_pos() @@ -720,6 +721,7 @@ frame_depth = max(self.current_clt.frame_info.jfi_frame_depth, frame_depth_no_fixed_size + JITFRAME_FIXED_SIZE) self.fixup_target_tokens(rawstart) + self._patch_stackadjust(stack_check_patch_ofs + rawstart, frame_depth) self.update_frame_depth(frame_depth) self.teardown() @@ -772,12 +774,11 @@ """ descrs = self.cpu.gc_ll_descr.getframedescrs(self.cpu) ofs = self.cpu.unpack_fielddescr(descrs.arraydescr.lendescr) - base_ofs = self.cpu.get_baseofs_of_frame_field() mc.gen_load_int(r.ip.value, ofs) - mc.SUB_ri(r.ip.value, r.ip.value, base_ofs) stack_check_cmp_ofs = mc.currpos() if expected_size == -1: - mc.gen_load_int(r.lr.value, 0xffffff) + mc.NOP() + mc.NOP() else: mc.gen_load_int(r.lr.value, expected_size) mc.CMP_rr(r.ip.value, r.lr.value) @@ -785,10 +786,11 @@ jg_location = mc.currpos() mc.BKPT() + # the size value is still stored in lr + mc.PUSH([r.lr.value]) + self.push_gcmap(mc, gcmap, push=True) - # the size value is still stored in lr - mc.PUSH([r.lr.value]) self.mc.BL(self._stack_check_failure) @@ -818,19 +820,20 @@ # store return address and keep the stack aligned mc.PUSH([r.ip.value, r.lr.value]) - # store the current gcmap(r1) in the jitframe + # store the current gcmap(r0) in the jitframe gcmap_ofs = self.cpu.get_ofs_of_frame_field('jf_gcmap') assert check_imm_arg(abs(gcmap_ofs)) - mc.STR_ri(r.r1.value, r.fp.value, imm=gcmap_ofs) + mc.STR_ri(r.r0.value, r.fp.value, imm=gcmap_ofs) # set first arg, which is the old jitframe address mc.MOV_rr(r.r0.value, r.fp.value) # call realloc_frame, it takes two arguments # arg0: the old jitframe # arg1: the new size + # mc.BL(self.cpu.realloc_frame) - # set fp to the new jitframe plus the baseofs - mc.ADD_ri(r.fp.value, r.r0.value) + # set fp to the new jitframe + mc.MOV_rr(r.fp.value, r.r0.value) gcrootmap = self.cpu.gc_ll_descr.gcrootmap if gcrootmap and gcrootmap.is_shadow_stack: @@ -858,6 +861,11 @@ targettoken._arm_loop_code += rawstart self.target_tokens_currently_compiling = None + def _patch_stackadjust(self, adr, allocated_depth): + mc = ARMv7Builder() + mc.gen_load_int(r.lr.value, allocated_depth) + mc.copy_to_raw_memory(adr) + def target_arglocs(self, loop_token): return loop_token._arm_arglocs From noreply at buildbot.pypy.org Fri Feb 8 16:41:56 2013 From: noreply at buildbot.pypy.org (bivab) Date: Fri, 8 Feb 2013 16:41:56 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: merge Message-ID: <20130208154156.DE0AD1C0110@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: jitframe-on-heap Changeset: r60980:0b7ee0aefa60 Date: 2013-02-08 16:41 +0100 http://bitbucket.org/pypy/pypy/changeset/0b7ee0aefa60/ Log: merge diff --git a/lib-python/2.7/collections.py b/lib-python/2.7/collections.py --- a/lib-python/2.7/collections.py +++ b/lib-python/2.7/collections.py @@ -6,11 +6,12 @@ __all__ += _abcoll.__all__ from _collections import deque, defaultdict -from operator import itemgetter as _itemgetter +from operator import itemgetter as _itemgetter, eq as _eq from keyword import iskeyword as _iskeyword import sys as _sys import heapq as _heapq from itertools import repeat as _repeat, chain as _chain, starmap as _starmap +from itertools import imap as _imap try: from thread import get_ident as _get_ident @@ -50,49 +51,45 @@ self.__map = {} self.__update(*args, **kwds) - def __setitem__(self, key, value, PREV=0, NEXT=1, dict_setitem=dict.__setitem__): + def __setitem__(self, key, value, dict_setitem=dict.__setitem__): 'od.__setitem__(i, y) <==> od[i]=y' # Setting a new item creates a new link at the end of the linked list, # and the inherited dictionary is updated with the new key/value pair. if key not in self: root = self.__root - last = root[PREV] - last[NEXT] = root[PREV] = self.__map[key] = [last, root, key] - dict_setitem(self, key, value) + last = root[0] + last[1] = root[0] = self.__map[key] = [last, root, key] + return dict_setitem(self, key, value) - def __delitem__(self, key, PREV=0, NEXT=1, dict_delitem=dict.__delitem__): + def __delitem__(self, key, dict_delitem=dict.__delitem__): 'od.__delitem__(y) <==> del od[y]' # Deleting an existing item uses self.__map to find the link which gets # removed by updating the links in the predecessor and successor nodes. dict_delitem(self, key) link_prev, link_next, key = self.__map.pop(key) - link_prev[NEXT] = link_next - link_next[PREV] = link_prev + link_prev[1] = link_next # update link_prev[NEXT] + link_next[0] = link_prev # update link_next[PREV] def __iter__(self): 'od.__iter__() <==> iter(od)' # Traverse the linked list in order. - NEXT, KEY = 1, 2 root = self.__root - curr = root[NEXT] + curr = root[1] # start at the first node while curr is not root: - yield curr[KEY] - curr = curr[NEXT] + yield curr[2] # yield the curr[KEY] + curr = curr[1] # move to next node def __reversed__(self): 'od.__reversed__() <==> reversed(od)' # Traverse the linked list in reverse order. - PREV, KEY = 0, 2 root = self.__root - curr = root[PREV] + curr = root[0] # start at the last node while curr is not root: - yield curr[KEY] - curr = curr[PREV] + yield curr[2] # yield the curr[KEY] + curr = curr[0] # move to previous node def clear(self): 'od.clear() -> None. Remove all items from od.' - for node in self.__map.itervalues(): - del node[:] root = self.__root root[:] = [root, root, None] self.__map.clear() @@ -208,7 +205,7 @@ ''' if isinstance(other, OrderedDict): - return len(self)==len(other) and self.items() == other.items() + return dict.__eq__(self, other) and all(_imap(_eq, self, other)) return dict.__eq__(self, other) def __ne__(self, other): diff --git a/lib_pypy/greenlet.py b/lib_pypy/greenlet.py --- a/lib_pypy/greenlet.py +++ b/lib_pypy/greenlet.py @@ -1,5 +1,6 @@ import _continuation, sys +__version__ = "0.4.0" # ____________________________________________________________ # Exceptions diff --git a/lib_pypy/pyrepl/unix_console.py b/lib_pypy/pyrepl/unix_console.py --- a/lib_pypy/pyrepl/unix_console.py +++ b/lib_pypy/pyrepl/unix_console.py @@ -398,6 +398,7 @@ if hasattr(self, 'old_sigwinch'): signal.signal(signal.SIGWINCH, self.old_sigwinch) + del self.old_sigwinch def __sigwinch(self, signum, frame): self.height, self.width = self.getheightwidth() diff --git a/pypy/interpreter/app_main.py b/pypy/interpreter/app_main.py --- a/pypy/interpreter/app_main.py +++ b/pypy/interpreter/app_main.py @@ -436,11 +436,14 @@ # (relevant in case of "reload(sys)") sys.argv[:] = argv - if PYTHON26 and not options["ignore_environment"]: - if os.getenv('PYTHONNOUSERSITE'): - options["no_user_site"] = 1 - if os.getenv('PYTHONDONTWRITEBYTECODE'): - options["dont_write_bytecode"] = 1 + if not options["ignore_environment"]: + if os.getenv('PYTHONUNBUFFERED'): + options["unbuffered"] = 1 + if PYTHON26: + if os.getenv('PYTHONNOUSERSITE'): + options["no_user_site"] = 1 + if os.getenv('PYTHONDONTWRITEBYTECODE'): + options["dont_write_bytecode"] = 1 if (options["interactive"] or (not options["ignore_environment"] and os.getenv('PYTHONINSPECT'))): @@ -716,7 +719,7 @@ root = dn(dn(dn(thisfile))) return [join(root, 'lib-python', '2.7'), join(root, 'lib_pypy')] - + def pypy_resolvedirof(s): # we ignore the issue of symlinks; for tests, the executable is always # interpreter/app_main.py anyway @@ -756,6 +759,10 @@ del os # make sure that os is not available globally, because this is what # happens in "real life" outside the tests + if 'time' not in sys.builtin_module_names: + # make some tests happy by loading this before we clobber sys.path + import time; del time + # no one should change to which lists sys.argv and sys.path are bound old_argv = sys.argv old_path = sys.path diff --git a/pypy/interpreter/test2/test_app_main.py b/pypy/interpreter/test2/test_app_main.py --- a/pypy/interpreter/test2/test_app_main.py +++ b/pypy/interpreter/test2/test_app_main.py @@ -712,6 +712,26 @@ assert data == '\x00(STDOUT)\n\x00' # from stdout child_out_err.close() + def test_non_interactive_stdout_unbuffered(self, monkeypatch): + monkeypatch.setenv('PYTHONUNBUFFERED', '1') + path = getscript(r""" + import sys, time + sys.stdout.write('\x00(STDOUT)\n\x00') + time.sleep(1) + sys.stderr.write('\x00[STDERR]\n\x00') + time.sleep(1) + # stdout flushed automatically here + """) + cmdline = '%s -E "%s" %s' % (sys.executable, app_main, path) + print 'POPEN:', cmdline + child_in, child_out_err = os.popen4(cmdline) + data = child_out_err.read(11) + assert data == '\x00(STDOUT)\n\x00' # from stderr + data = child_out_err.read(11) + assert data == '\x00[STDERR]\n\x00' # from stdout + child_out_err.close() + child_in.close() + def test_proper_sys_path(self, tmpdir): data = self.run('-c "import _ctypes"', python_flags='-S') if data.startswith('Traceback'): diff --git a/pypy/module/__pypy__/__init__.py b/pypy/module/__pypy__/__init__.py --- a/pypy/module/__pypy__/__init__.py +++ b/pypy/module/__pypy__/__init__.py @@ -14,7 +14,7 @@ class TimeModule(MixedModule): appleveldefs = {} interpleveldefs = {} - if sys.platform.startswith("linux"): + if sys.platform.startswith("linux") or 'bsd' in sys.platform: from pypy.module.__pypy__ import interp_time interpleveldefs["clock_gettime"] = "interp_time.clock_gettime" interpleveldefs["clock_getres"] = "interp_time.clock_getres" diff --git a/pypy/module/_cffi_backend/cbuffer.py b/pypy/module/_cffi_backend/cbuffer.py --- a/pypy/module/_cffi_backend/cbuffer.py +++ b/pypy/module/_cffi_backend/cbuffer.py @@ -2,7 +2,7 @@ from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.buffer import RWBuffer from pypy.interpreter.gateway import unwrap_spec, interp2app -from pypy.interpreter.typedef import TypeDef +from pypy.interpreter.typedef import TypeDef, make_weakref_descr from rpython.rtyper.lltypesystem import rffi from pypy.module._cffi_backend import cdataobj, ctypeptr, ctypearray @@ -41,8 +41,9 @@ # a different subclass of Wrappable for the MiniBuffer, because we # want a slightly different (simplified) API at the level of Python. - def __init__(self, buffer): + def __init__(self, buffer, keepalive=None): self.buffer = buffer + self.keepalive = keepalive def descr_len(self, space): return self.buffer.descr_len(space) @@ -65,6 +66,7 @@ __getitem__ = interp2app(MiniBuffer.descr_getitem), __setitem__ = interp2app(MiniBuffer.descr_setitem), __buffer__ = interp2app(MiniBuffer.descr__buffer__), + __weakref__ = make_weakref_descr(MiniBuffer), ) MiniBuffer.typedef.acceptable_as_base_class = False @@ -86,4 +88,4 @@ raise operationerrfmt(space.w_TypeError, "don't know the size pointed to by '%s'", ctype.name) - return space.wrap(MiniBuffer(LLBuffer(cdata._cdata, size))) + return space.wrap(MiniBuffer(LLBuffer(cdata._cdata, size), cdata)) diff --git a/pypy/module/_cffi_backend/test/_backend_test_c.py b/pypy/module/_cffi_backend/test/_backend_test_c.py --- a/pypy/module/_cffi_backend/test/_backend_test_c.py +++ b/pypy/module/_cffi_backend/test/_backend_test_c.py @@ -12,6 +12,7 @@ return eval('u'+repr(other).replace(r'\\u', r'\u') .replace(r'\\U', r'\U')) u = U() + str2bytes = str else: type_or_class = "class" long = int @@ -22,6 +23,7 @@ bytechr = lambda n: bytes([n]) bitem2bchr = bytechr u = "" + str2bytes = lambda s: bytes(s, "ascii") def size_of_int(): BInt = new_primitive_type("int") @@ -1438,10 +1440,16 @@ import _weakref BInt = new_primitive_type("int") BPtr = new_pointer_type(BInt) - _weakref.ref(BInt) - _weakref.ref(newp(BPtr, 42)) - _weakref.ref(cast(BPtr, 42)) - _weakref.ref(cast(BInt, 42)) + rlist = [_weakref.ref(BInt), + _weakref.ref(newp(BPtr, 42)), + _weakref.ref(cast(BPtr, 42)), + _weakref.ref(cast(BInt, 42)), + _weakref.ref(buffer(newp(BPtr, 42))), + ] + for i in range(5): + import gc; gc.collect() + if [r() for r in rlist] == [None for r in rlist]: + break def test_no_inheritance(): BInt = new_primitive_type("int") @@ -2544,3 +2552,15 @@ BCharP = new_pointer_type(new_primitive_type("char")) BCharArray = new_array_type(BCharP, None) py.test.raises(TypeError, newp, BCharArray, u+'foobar') + +def test_buffer_keepalive(): + BCharP = new_pointer_type(new_primitive_type("char")) + BCharArray = new_array_type(BCharP, None) + buflist = [] + for i in range(20): + c = newp(BCharArray, str2bytes("hi there %d" % i)) + buflist.append(buffer(c)) + import gc; gc.collect() + for i in range(20): + buf = buflist[i] + assert buf[:] == str2bytes("hi there %d\x00" % i) diff --git a/pypy/module/_multibytecodec/c_codecs.py b/pypy/module/_multibytecodec/c_codecs.py --- a/pypy/module/_multibytecodec/c_codecs.py +++ b/pypy/module/_multibytecodec/c_codecs.py @@ -62,7 +62,7 @@ "pypy_cjk_enc_init", "pypy_cjk_enc_free", "pypy_cjk_enc_chunk", "pypy_cjk_enc_reset", "pypy_cjk_enc_outbuf", "pypy_cjk_enc_outlen", "pypy_cjk_enc_inbuf_remaining", "pypy_cjk_enc_inbuf_consumed", - "pypy_cjk_enc_replace_on_error", + "pypy_cjk_enc_replace_on_error", "pypy_cjk_enc_getcodec", ] + ["pypy_cjkcodec_%s" % codec for codec in codecs], ) diff --git a/pypy/module/micronumpy/arrayimpl/concrete.py b/pypy/module/micronumpy/arrayimpl/concrete.py --- a/pypy/module/micronumpy/arrayimpl/concrete.py +++ b/pypy/module/micronumpy/arrayimpl/concrete.py @@ -275,6 +275,11 @@ def get_buffer(self, space): return ArrayBuffer(self) + def astype(self, space, dtype): + new_arr = W_NDimArray.from_shape(self.get_shape(), dtype) + loop.copy_from_to(self, new_arr.implementation, dtype) + return new_arr + class ConcreteArrayNotOwning(BaseConcreteArray): def __init__(self, shape, dtype, order, strides, backstrides, storage): @@ -309,11 +314,6 @@ def argsort(self, space, w_axis): return argsort_array(self, space, w_axis) - def astype(self, space, dtype): - new_arr = W_NDimArray.from_shape(self.get_shape(), dtype) - loop.copy_from_to(self, new_arr.implementation, dtype) - return new_arr - def base(self): return None diff --git a/pypy/module/micronumpy/arrayimpl/scalar.py b/pypy/module/micronumpy/arrayimpl/scalar.py --- a/pypy/module/micronumpy/arrayimpl/scalar.py +++ b/pypy/module/micronumpy/arrayimpl/scalar.py @@ -7,18 +7,19 @@ class ScalarIterator(base.BaseArrayIterator): def __init__(self, v): self.v = v + self.called_once = False def next(self): - pass + self.called_once = True def getitem(self): - return self.v + return self.v.get_scalar_value() def setitem(self, v): - raise Exception("Don't call setitem on scalar iterators") + self.v.set_scalar_value(v) def done(self): - raise Exception("should not call done on scalar") + return self.called_once def reset(self): pass @@ -38,7 +39,7 @@ return [] def create_iter(self, shape=None): - return ScalarIterator(self.value) + return ScalarIterator(self) def get_scalar_value(self): return self.value diff --git a/pypy/module/micronumpy/base.py b/pypy/module/micronumpy/base.py --- a/pypy/module/micronumpy/base.py +++ b/pypy/module/micronumpy/base.py @@ -21,11 +21,13 @@ @staticmethod def from_shape(shape, dtype, order='C'): - from pypy.module.micronumpy.arrayimpl import concrete - - assert shape - strides, backstrides = calc_strides(shape, dtype, order) - impl = concrete.ConcreteArray(shape, dtype, order, strides, + from pypy.module.micronumpy.arrayimpl import concrete, scalar + + if not shape: + impl = scalar.Scalar(dtype) + else: + strides, backstrides = calc_strides(shape, dtype, order) + impl = concrete.ConcreteArray(shape, dtype, order, strides, backstrides) return W_NDimArray(impl) diff --git a/pypy/module/micronumpy/test/test_numarray.py b/pypy/module/micronumpy/test/test_numarray.py --- a/pypy/module/micronumpy/test/test_numarray.py +++ b/pypy/module/micronumpy/test/test_numarray.py @@ -1640,7 +1640,7 @@ assert _weakref.ref(a) def test_astype(self): - from _numpypy import array + from _numpypy import array, arange b = array(1).astype(float) assert b == 1 assert b.dtype == float @@ -1653,7 +1653,9 @@ b = array([0, 1, 2], dtype=complex).astype(bool) assert (b == [False, True, True]).all() assert b.dtype == 'bool' - + + a = arange(6, dtype='f4').reshape(2,3) + b = a.astype('i4') def test_base(self): from _numpypy import array @@ -1700,6 +1702,12 @@ n = a.dtype.itemsize assert s1[n-1] == s2[0] + a = array(0., dtype='longfloat') + s1 = map(ord, a.tostring()) + s2 = map(ord, a.byteswap().tostring()) + n = a.dtype.itemsize + assert s1[n-1] == s2[0] + def test_clip(self): from _numpypy import array a = array([1, 2, 17, -3, 12]) @@ -2368,6 +2376,7 @@ assert array([1, 2, 3], 'i2')[::2].tostring() == '\x01\x00\x03\x00' assert array([1, 2, 3], 'i2')[::2].tostring() == '\x00\x01\x00\x03' + assert array(0, dtype='i2').tostring() == '\x00\x00' def test_argsort_dtypes(self): from _numpypy import array, arange diff --git a/pypy/module/posix/test/test_posix2.py b/pypy/module/posix/test/test_posix2.py --- a/pypy/module/posix/test/test_posix2.py +++ b/pypy/module/posix/test/test_posix2.py @@ -514,12 +514,14 @@ assert res == '1\n' def test_popen_child_fds(self): - os = self.posix - from os.path import join - with open(join(self.pdir, 'file1'), 'r') as fd: - with os.popen('%s -c "import os; print os.read(%d, 10)"' % (self.python, fd.fileno())) as stream: + import os + with open(os.path.join(self.pdir, 'file1'), 'r') as fd: + with self.posix.popen('%s -c "import os; print os.read(%d, 10)" 2>&1' % (self.python, fd.fileno())) as stream: res = stream.read() - assert res == 'test1\n' + if os.name == 'nt': + assert '\nOSError: [Errno 9]' in res + else: + assert res == 'test1\n' if hasattr(__import__(os.name), '_getfullpathname'): def test__getfullpathname(self): diff --git a/pypy/module/pyexpat/interp_pyexpat.py b/pypy/module/pyexpat/interp_pyexpat.py --- a/pypy/module/pyexpat/interp_pyexpat.py +++ b/pypy/module/pyexpat/interp_pyexpat.py @@ -443,7 +443,10 @@ if XML_ParserFree: # careful with CPython interpreter shutdown XML_ParserFree(self.itself) if global_storage: - global_storage.free_nonmoving_id(self.id) + try: + global_storage.free_nonmoving_id(self.id) + except KeyError: + pass # maybe global_storage.clear() was already called @unwrap_spec(flag=int) def SetParamEntityParsing(self, space, flag): @@ -636,10 +639,13 @@ def ParseFile(self, space, w_file): """ParseFile(file) Parse XML data from file-like object.""" - # XXX not the more efficient method - w_data = space.call_method(w_file, 'read') - data = space.str_w(w_data) - return self.Parse(space, data, isfinal=True) + eof = False + while not eof: + w_data = space.call_method(w_file, 'read', space.wrap(2048)) + data = space.str_w(w_data) + eof = len(data) == 0 + w_res = self.Parse(space, data, isfinal=eof) + return w_res @unwrap_spec(base=str) def SetBase(self, space, base): diff --git a/pypy/module/pyexpat/test/test_parser.py b/pypy/module/pyexpat/test/test_parser.py --- a/pypy/module/pyexpat/test/test_parser.py +++ b/pypy/module/pyexpat/test/test_parser.py @@ -146,3 +146,24 @@ def test_model(self): import pyexpat assert isinstance(pyexpat.model.XML_CTYPE_EMPTY, int) + + def test_read_chunks(self): + import pyexpat + import StringIO + from contextlib import closing + + xml = '' + (' ' * 4096) + '' + with closing(StringIO.StringIO(xml)) as sio: + class FakeReader(): + def __init__(self): + self.read_count = 0 + + def read(self, size): + self.read_count += 1 + assert size > 0 + return sio.read(size) + + fake_reader = FakeReader() + p = pyexpat.ParserCreate() + p.ParseFile(fake_reader) + assert fake_reader.read_count == 4 diff --git a/pypy/module/rctime/test/test_rctime.py b/pypy/module/rctime/test/test_rctime.py --- a/pypy/module/rctime/test/test_rctime.py +++ b/pypy/module/rctime/test/test_rctime.py @@ -237,7 +237,7 @@ # input to [w]strftime is not kosher. if os.name == 'nt': raises(ValueError, rctime.strftime, '%f') - elif sys.platform == 'darwin': + elif sys.platform == 'darwin' or 'bsd' in sys.platform: # darwin strips % of unknown format codes # http://bugs.python.org/issue9811 assert rctime.strftime('%f') == 'f' diff --git a/pypy/module/signal/test/test_signal.py b/pypy/module/signal/test/test_signal.py --- a/pypy/module/signal/test/test_signal.py +++ b/pypy/module/signal/test/test_signal.py @@ -157,7 +157,7 @@ if sys.platform == 'win32': raises(ValueError, signal, 42, lambda *args: None) raises(ValueError, signal, 7, lambda *args: None) - elif sys.platform == 'darwin': + elif sys.platform == 'darwin' or 'bsd' in sys.platform: raises(ValueError, signal, 42, lambda *args: None) else: signal(42, lambda *args: None) diff --git a/pypy/module/zipimport/interp_zipimport.py b/pypy/module/zipimport/interp_zipimport.py --- a/pypy/module/zipimport/interp_zipimport.py +++ b/pypy/module/zipimport/interp_zipimport.py @@ -172,24 +172,24 @@ return mtime def check_newer_pyfile(self, space, filename, timestamp): + # check if the timestamp stored in the .pyc is matching + # the actual timestamp of the .py file, if any mtime = self._parse_mtime(space, filename) if mtime == 0: return False - return mtime > timestamp - - def check_compatible_mtime(self, space, filename, timestamp): - mtime = self._parse_mtime(space, filename) - if mtime == 0 or mtime != (timestamp & (~1)): - return False - return True + # Lenient date/time comparison function. The precision of the mtime + # in the archive is lower than the mtime stored in a .pyc: we + # must allow a difference of at most one second. + d = mtime - timestamp + if d < 0: + d = -d + return d > 1 # more than one second => different def can_use_pyc(self, space, filename, magic, timestamp): if magic != importing.get_pyc_magic(space): return False if self.check_newer_pyfile(space, filename[:-1], timestamp): return False - if not self.check_compatible_mtime(space, filename, timestamp): - return False return True def import_pyc_file(self, space, modname, filename, buf, pkgpath): diff --git a/pypy/module/zipimport/test/test_zipimport.py b/pypy/module/zipimport/test/test_zipimport.py --- a/pypy/module/zipimport/test/test_zipimport.py +++ b/pypy/module/zipimport/test/test_zipimport.py @@ -95,6 +95,9 @@ """) self.w_modules = [] + def w_now_in_the_future(self, delta): + self.now += delta + def w_writefile(self, filename, data): import sys import time @@ -264,10 +267,12 @@ import os import zipimport data = "saddsadsa" + pyc_data = self.test_pyc + self.now_in_the_future(+5) # write the zipfile 5 secs after the .pyc self.writefile("xxx", data) self.writefile("xx/__init__.py", "5") self.writefile("yy.py", "3") - self.writefile('uu.pyc', self.test_pyc) + self.writefile('uu.pyc', pyc_data) z = zipimport.zipimporter(self.zipfile) assert z.get_data(self.zipfile + os.sep + "xxx") == data assert z.is_package("xx") @@ -277,6 +282,7 @@ raises(ImportError, "z.get_source('zz')") #assert z.get_code('yy') == py.code.Source('3').compile() #assert z.get_code('uu') == self.co + assert z.get_code('uu') assert z.get_code('xx') assert z.get_source('xx') == "5" assert z.archive == self.zipfile diff --git a/rpython/annotator/description.py b/rpython/annotator/description.py --- a/rpython/annotator/description.py +++ b/rpython/annotator/description.py @@ -497,8 +497,8 @@ # will do the right thing in s_get_value(). if isinstance(value, staticmethod) and mixin: # make a new copy of staticmethod - value = staticmethod(func_with_new_name(value.__func__, - value.__func__.__name__)) + func = value.__get__(42) + value = staticmethod(func_with_new_name(func, func.__name__)) if type(value) in MemberDescriptorTypes: # skip __slots__, showing up in the class as 'member' objects diff --git a/rpython/translator/platform/posix.py b/rpython/translator/platform/posix.py --- a/rpython/translator/platform/posix.py +++ b/rpython/translator/platform/posix.py @@ -49,10 +49,10 @@ response_file = self._make_response_file("dynamic-symbols-") f = response_file.open("w") - f.write("{\n") + f.write("{\n\tglobal:\n") for sym in eci.export_symbols: - f.write("%s;\n" % (sym,)) - f.write("};") + f.write("\t\t%s;\n" % (sym,)) + f.write("\tlocal:\n\t\t*;\n};") f.close() if relto: diff --git a/rpython/translator/tool/test/test_cbuild.py b/rpython/translator/tool/test/test_cbuild.py --- a/rpython/translator/tool/test/test_cbuild.py +++ b/rpython/translator/tool/test/test_cbuild.py @@ -77,6 +77,10 @@ int get() { return 42; + } + int shouldnt_export() + { + return 43; }'''], export_symbols = ['get'] ) @@ -87,6 +91,7 @@ except ImportError: py.test.skip("Need ctypes for that test") assert ctypes.CDLL(neweci.libraries[0]).get() == 42 + assert not hasattr(ctypes.CDLL(neweci.libraries[0]), 'shouldnt_export') assert not neweci.separate_module_sources assert not neweci.separate_module_files From noreply at buildbot.pypy.org Fri Feb 8 17:31:48 2013 From: noreply at buildbot.pypy.org (mattip) Date: Fri, 8 Feb 2013 17:31:48 +0100 (CET) Subject: [pypy-commit] pypy default: add test, implementation of to_builtin_type for complex Message-ID: <20130208163148.1FD151C0110@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: Changeset: r60981:4f6fde5fcf81 Date: 2013-02-08 18:31 +0200 http://bitbucket.org/pypy/pypy/changeset/4f6fde5fcf81/ Log: add test, implementation of to_builtin_type for complex diff --git a/pypy/module/micronumpy/test/test_dtypes.py b/pypy/module/micronumpy/test/test_dtypes.py --- a/pypy/module/micronumpy/test/test_dtypes.py +++ b/pypy/module/micronumpy/test/test_dtypes.py @@ -529,6 +529,8 @@ assert numpy.complex128(1.2) == numpy.complex128(complex(1.2, 0)) assert numpy.complex64(1.2) == numpy.complex64(complex(1.2, 0)) raises (TypeError, numpy.array, [3+4j], dtype=float) + a = (0.5+1.5j) + assert '{0:g}'.format(a) == '{0:g}'.format(numpy.complex64(a)) def test_complex(self): import _numpypy as numpy diff --git a/pypy/module/micronumpy/types.py b/pypy/module/micronumpy/types.py --- a/pypy/module/micronumpy/types.py +++ b/pypy/module/micronumpy/types.py @@ -1030,6 +1030,9 @@ def for_computation(v): return float(v[0]), float(v[1]) + def to_builtin_type(self, space, box): + return space.wrap(complex(*self.for_computation(self.unbox(box)))) + def read_bool(self, arr, i, offset): v = self.for_computation(self._read(arr.storage, i, offset)) return bool(v[0]) or bool(v[1]) From noreply at buildbot.pypy.org Fri Feb 8 18:09:05 2013 From: noreply at buildbot.pypy.org (bivab) Date: Fri, 8 Feb 2013 18:09:05 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: move force method to llsupport Message-ID: <20130208170905.6B4DD1C0110@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: jitframe-on-heap Changeset: r60982:a2b8f39dec68 Date: 2013-02-08 17:41 +0100 http://bitbucket.org/pypy/pypy/changeset/a2b8f39dec68/ Log: move force method to llsupport diff --git a/rpython/jit/backend/arm/runner.py b/rpython/jit/backend/arm/runner.py --- a/rpython/jit/backend/arm/runner.py +++ b/rpython/jit/backend/arm/runner.py @@ -117,33 +117,6 @@ cast_ptr_to_int._annspecialcase_ = 'specialize:arglltype(0)' cast_ptr_to_int = staticmethod(cast_ptr_to_int) - all_null_registers = lltype.malloc(rffi.LONGP.TO, - len(all_vfp_regs) * 2 + len(all_regs), - flavor='raw', zero=True, immortal=True) - - def force(self, addr_of_force_index): - TP = rffi.CArrayPtr(lltype.Signed) - fail_index = rffi.cast(TP, addr_of_force_index)[0] - assert fail_index >= 0, "already forced!" - faildescr = self.get_fail_descr_from_number(fail_index) - rffi.cast(TP, addr_of_force_index)[0] = ~fail_index - frb = self.assembler._find_failure_recovery_bytecode(faildescr) - bytecode = rffi.cast(rffi.UCHARP, frb) - addr_all_null_regsiters = rffi.cast(rffi.LONG, self.all_null_registers) - # - assert (rffi.cast(lltype.Signed, bytecode[0]) == - self.assembler.CODE_FORCED) - bytecode = rffi.ptradd(bytecode, 1) - deadframe = self.assembler.grab_frame_values(self, - bytecode, addr_of_force_index, - self.all_null_registers, - self.all_null_registers) - # - assert self.get_latest_descr(deadframe) is faildescr - self.assembler.force_token_to_dead_frame[addr_of_force_index] = ( - deadframe) - return deadframe - def redirect_call_assembler(self, oldlooptoken, newlooptoken): self.assembler.redirect_call_assembler(oldlooptoken, newlooptoken) diff --git a/rpython/jit/backend/llsupport/llmodel.py b/rpython/jit/backend/llsupport/llmodel.py --- a/rpython/jit/backend/llsupport/llmodel.py +++ b/rpython/jit/backend/llsupport/llmodel.py @@ -178,6 +178,11 @@ self.gc_ll_descr.freeing_block(rawstart, rawstop) self.asmmemmgr.free(rawstart, rawstop) + def force(self, addr_of_force_token): + frame = rffi.cast(jitframe.JITFRAMEPTR, addr_of_force_token) + frame.jf_descr = frame.jf_force_descr + return lltype.cast_opaque_ptr(llmemory.GCREF, frame) + # ------------------- helpers and descriptions -------------------- @staticmethod diff --git a/rpython/jit/backend/x86/runner.py b/rpython/jit/backend/x86/runner.py --- a/rpython/jit/backend/x86/runner.py +++ b/rpython/jit/backend/x86/runner.py @@ -152,11 +152,6 @@ cast_ptr_to_int._annspecialcase_ = 'specialize:arglltype(0)' cast_ptr_to_int = staticmethod(cast_ptr_to_int) - def force(self, addr_of_force_token): - frame = rffi.cast(jitframe.JITFRAMEPTR, addr_of_force_token) - frame.jf_descr = frame.jf_force_descr - return lltype.cast_opaque_ptr(llmemory.GCREF, frame) - def redirect_call_assembler(self, oldlooptoken, newlooptoken): self.assembler.redirect_call_assembler(oldlooptoken, newlooptoken) From noreply at buildbot.pypy.org Fri Feb 8 18:09:06 2013 From: noreply at buildbot.pypy.org (bivab) Date: Fri, 8 Feb 2013 18:09:06 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: kill code Message-ID: <20130208170906.C1EB81C0110@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: jitframe-on-heap Changeset: r60983:cfec96854f0e Date: 2013-02-08 17:43 +0100 http://bitbucket.org/pypy/pypy/changeset/cfec96854f0e/ Log: kill code diff --git a/rpython/jit/backend/arm/assembler.py b/rpython/jit/backend/arm/assembler.py --- a/rpython/jit/backend/arm/assembler.py +++ b/rpython/jit/backend/arm/assembler.py @@ -1345,36 +1345,11 @@ # malloc_slowpath in case we called malloc_slowpath, which returns the # new value of nursery_free_adr in r1 and the adr of the new object in # r0. - self.mark_gc_roots(self.write_new_force_index(), - use_copy_area=True) self.mc.BL(self.malloc_slowpath, c=c.HI) self.mc.gen_load_int(r.ip.value, nursery_free_adr) self.mc.STR_ri(r.r1.value, r.ip.value) - def mark_gc_roots(self, force_index, use_copy_area=False): - if force_index < 0: - return # not needed - gcrootmap = self.cpu.gc_ll_descr.gcrootmap - if gcrootmap: - mark = self._regalloc.get_mark_gc_roots(gcrootmap, use_copy_area) - assert gcrootmap.is_shadow_stack - gcrootmap.write_callshape(mark, force_index) - - def write_new_force_index(self): - # for shadowstack only: get a new, unused force_index number and - # write it to FORCE_INDEX_OFS. Used to record the call shape - # (i.e. where the GC pointers are in the stack) around a CALL - # instruction that doesn't already have a force_index. - gcrootmap = self.cpu.gc_ll_descr.gcrootmap - if gcrootmap and gcrootmap.is_shadow_stack: - clt = self.current_clt - force_index = clt.reserve_and_record_some_faildescr_index() - self._write_fail_index(force_index) - return force_index - else: - return 0 - def push_gcmap(self, mc, gcmap, push=False, mov=False, store=False): ptr = rffi.cast(lltype.Signed, gcmap) if push: diff --git a/rpython/jit/backend/arm/opassembler.py b/rpython/jit/backend/arm/opassembler.py --- a/rpython/jit/backend/arm/opassembler.py +++ b/rpython/jit/backend/arm/opassembler.py @@ -398,7 +398,6 @@ assert adr.is_reg() if adr.is_reg(): self.mc.BLX(adr.value) - self.mark_gc_roots(force_index) self._restore_sp(stack_args, fcond) # ensure the result is wellformed and stored in the correct location @@ -1371,23 +1370,6 @@ with saved_registers(self.mc, regs_to_save, vfp_regs_to_save): self._emit_call(NO_FORCE_INDEX, imm(self.reacqgil_addr), [], fcond) - def write_new_force_index(self): - # for shadowstack only: get a new, unused force_index number and - # write it to FORCE_INDEX_OFS. Used to record the call shape - # (i.e. where the GC pointers are in the stack) around a CALL - # instruction that doesn't already have a force_index. - gcrootmap = self.cpu.gc_ll_descr.gcrootmap - if gcrootmap and gcrootmap.is_shadow_stack: - clt = self.current_clt - force_index = clt.reserve_and_record_some_faildescr_index() - self._write_fail_index(force_index) - return force_index - else: - return 0 - - def _write_fail_index(self, fail_index): - self.mc.gen_load_int(r.ip.value, fail_index) - self.mc.STR_ri(r.ip.value, r.fp.value) def emit_op_call_malloc_gc(self, op, arglocs, regalloc, fcond): self.emit_op_call(op, arglocs, regalloc, fcond) From noreply at buildbot.pypy.org Fri Feb 8 18:09:07 2013 From: noreply at buildbot.pypy.org (bivab) Date: Fri, 8 Feb 2013 18:09:07 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: force Message-ID: <20130208170907.F1DD41C0110@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: jitframe-on-heap Changeset: r60984:cedf96638849 Date: 2013-02-08 17:44 +0100 http://bitbucket.org/pypy/pypy/changeset/cedf96638849/ Log: force diff --git a/rpython/jit/backend/arm/opassembler.py b/rpython/jit/backend/arm/opassembler.py --- a/rpython/jit/backend/arm/opassembler.py +++ b/rpython/jit/backend/arm/opassembler.py @@ -32,6 +32,7 @@ from rpython.rlib import rgc from rpython.rtyper.lltypesystem import rstr, rffi, lltype, llmemory from rpython.rlib.rarithmetic import r_uint +from rpython.rtyper.annlowlevel import cast_instance_to_gcref NO_FORCE_INDEX = -1 @@ -364,27 +365,24 @@ self.gen_func_epilog() return fcond - def emit_op_call(self, op, arglocs, regalloc, fcond, - force_index=NO_FORCE_INDEX): - if force_index == NO_FORCE_INDEX: - force_index = self.write_new_force_index() + def emit_op_call(self, op, arglocs, regalloc, fcond): resloc = arglocs[0] adr = arglocs[1] arglist = arglocs[2:] descr = op.getdescr() size = descr.get_result_size() signed = descr.is_result_signed() - cond = self._emit_call(force_index, adr, arglist, + cond = self._emit_call(adr, arglist, fcond, resloc, (size, signed)) return cond - def _emit_call(self, force_index, adr, arglocs, fcond=c.AL, + def _emit_call(self, adr, arglocs, fcond=c.AL, resloc=None, result_info=(-1, -1)): if self.cpu.use_hf_abi: - stack_args, adr = self._setup_call_hf(force_index, adr, + stack_args, adr = self._setup_call_hf(adr, arglocs, fcond, resloc, result_info) else: - stack_args, adr = self._setup_call_sf(force_index, adr, + stack_args, adr = self._setup_call_sf(adr, arglocs, fcond, resloc, result_info) #the actual call @@ -452,7 +450,7 @@ else: self.regalloc_push(arg) - def _setup_call_sf(self, force_index, adr, arglocs, fcond=c.AL, + def _setup_call_sf(self, adr, arglocs, fcond=c.AL, resloc=None, result_info=(-1, -1)): reg_args = count_reg_args(arglocs) stack_args = self._collect_stack_args_sf(arglocs) @@ -497,7 +495,7 @@ self.mov_from_vfp_loc(loc, reg, r.all_regs[reg.value + 1]) return stack_args, adr - def _setup_call_hf(self, force_index, adr, arglocs, fcond=c.AL, + def _setup_call_hf(self, adr, arglocs, fcond=c.AL, resloc=None, result_info=(-1, -1)): non_float_locs = [] non_float_regs = [] @@ -1051,7 +1049,7 @@ length_loc = bytes_loc # call memcpy() regalloc.before_call() - self._emit_call(NO_FORCE_INDEX, imm(self.memcpy_addr), + self._emit_call(imm(self.memcpy_addr), [dstaddr_loc, srcaddr_loc, length_loc]) regalloc.possibly_free_var(length_box) @@ -1124,6 +1122,7 @@ return fcond def emit_op_force_token(self, op, arglocs, regalloc, fcond): + # XXX kill me res_loc = arglocs[0] self.mc.MOV_rr(res_loc.value, r.fp.value) return fcond @@ -1136,14 +1135,12 @@ resloc = arglocs[2] callargs = arglocs[3:] - faildescr = guard_op.getdescr() - fail_index = self.cpu.get_fail_descr_number(faildescr) - self._write_fail_index(fail_index) + self._store_force_index(guard_op) descr = op.getdescr() assert isinstance(descr, JitCellToken) # check value assert tmploc is r.r0 - self._emit_call(fail_index, imm(descr._arm_func_addr), + self._emit_call(imm(descr._arm_func_addr), callargs, fcond, resloc=tmploc) if op.result is None: value = self.cpu.done_with_this_frame_void_v @@ -1286,9 +1283,7 @@ def emit_guard_call_may_force(self, op, guard_op, arglocs, regalloc, fcond): - faildescr = guard_op.getdescr() - fail_index = self.cpu.get_fail_descr_number(faildescr) - self._write_fail_index(fail_index) + self._store_force_index(guard_op) numargs = op.numargs() callargs = arglocs[2:numargs + 1] # extract the arguments to the call adr = arglocs[1] @@ -1298,12 +1293,13 @@ size = descr.get_result_size() signed = descr.is_result_signed() # - self._emit_call(fail_index, adr, callargs, fcond, + self._emit_call(adr, callargs, fcond, resloc, (size, signed)) - self.mc.LDR_ri(r.ip.value, r.fp.value) + ofs = self.cpu.get_ofs_of_frame_field('jf_descr') + self.mc.LDR_ri(r.ip.value, r.fp.value, imm=ofs) self.mc.CMP_ri(r.ip.value, 0) - self._emit_guard(guard_op, arglocs[1 + numargs:], c.GE, + self._emit_guard(guard_op, arglocs[1 + numargs:], c.EQ, save_exc=True, is_guard_not_forced=True) return fcond @@ -1320,15 +1316,13 @@ if gcrootmap: self.call_release_gil(gcrootmap, arglocs, fcond) # do the call - faildescr = guard_op.getdescr() - fail_index = self.cpu.get_fail_descr_number(faildescr) - self._write_fail_index(fail_index) + self._store_force_index(guard_op) # descr = op.getdescr() size = descr.get_result_size() signed = descr.is_result_signed() # - self._emit_call(fail_index, adr, callargs, fcond, + self._emit_call(adr, callargs, fcond, resloc, (size, signed)) # then reopen the stack if gcrootmap: @@ -1350,8 +1344,7 @@ regs_to_save.append(reg) assert gcrootmap.is_shadow_stack with saved_registers(self.mc, regs_to_save): - self._emit_call(NO_FORCE_INDEX, - imm(self.releasegil_addr), [], fcond) + self._emit_call(imm(self.releasegil_addr), [], fcond) def call_reacquire_gil(self, gcrootmap, save_loc, fcond): # save the previous result into the stack temporarily. @@ -1368,8 +1361,14 @@ regs_to_save.append(r.ip) # for alingment assert gcrootmap.is_shadow_stack with saved_registers(self.mc, regs_to_save, vfp_regs_to_save): - self._emit_call(NO_FORCE_INDEX, imm(self.reacqgil_addr), [], fcond) + self._emit_call(imm(self.reacqgil_addr), [], fcond) + def _store_force_index(self, guard_op): + faildescr = guard_op.getdescr() + ofs = self.cpu.get_ofs_of_frame_field('jf_force_descr') + value = rffi.cast(lltype.Signed, cast_instance_to_gcref(faildescr)) + self.mc.gen_load_int(r.ip.value, value) + self.store_reg(self.mc, r.ip, r.fp, ofs) def emit_op_call_malloc_gc(self, op, arglocs, regalloc, fcond): self.emit_op_call(op, arglocs, regalloc, fcond) diff --git a/rpython/jit/backend/arm/regalloc.py b/rpython/jit/backend/arm/regalloc.py --- a/rpython/jit/backend/arm/regalloc.py +++ b/rpython/jit/backend/arm/regalloc.py @@ -1070,6 +1070,7 @@ prepare_op_cond_call_gc_wb_array = prepare_op_cond_call_gc_wb def prepare_op_force_token(self, op, fcond): + # XXX for now we return a regular reg res_loc = self.force_allocate_reg(op.result) self.possibly_free_var(op.result) return [res_loc] From noreply at buildbot.pypy.org Fri Feb 8 18:09:09 2013 From: noreply at buildbot.pypy.org (bivab) Date: Fri, 8 Feb 2013 18:09:09 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: this slot on the stack is not needed anymore Message-ID: <20130208170909.248821C0110@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: jitframe-on-heap Changeset: r60985:943b0d880835 Date: 2013-02-08 17:46 +0100 http://bitbucket.org/pypy/pypy/changeset/943b0d880835/ Log: this slot on the stack is not needed anymore diff --git a/rpython/jit/backend/arm/assembler.py b/rpython/jit/backend/arm/assembler.py --- a/rpython/jit/backend/arm/assembler.py +++ b/rpython/jit/backend/arm/assembler.py @@ -517,7 +517,6 @@ mc = self.mc if gcrootmap and gcrootmap.is_shadow_stack: self.gen_footer_shadowstack(gcrootmap, mc) - mc.ADD_ri(r.sp.value, r.sp.value, WORD, cond=cond) # for the force index if self.cpu.supports_floats: mc.VPOP([reg.value for reg in r.callee_saved_vfp_registers], cond=cond) @@ -533,7 +532,6 @@ self.mc.PUSH([reg.value for reg in r.callee_saved_registers]) if self.cpu.supports_floats: self.mc.VPUSH([reg.value for reg in r.callee_saved_vfp_registers]) - self.mc.SUB_ri(r.sp.value, r.sp.value, WORD) # for the force index assert stack_size % 8 == 0 # ensure we keep alignment # set fp to point to the JITFRAME From noreply at buildbot.pypy.org Fri Feb 8 18:09:10 2013 From: noreply at buildbot.pypy.org (bivab) Date: Fri, 8 Feb 2013 18:09:10 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: keep stack aligned Message-ID: <20130208170910.539681C0110@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: jitframe-on-heap Changeset: r60986:c55cd071b268 Date: 2013-02-08 18:08 +0100 http://bitbucket.org/pypy/pypy/changeset/c55cd071b268/ Log: keep stack aligned diff --git a/rpython/jit/backend/arm/arch.py b/rpython/jit/backend/arm/arch.py --- a/rpython/jit/backend/arm/arch.py +++ b/rpython/jit/backend/arm/arch.py @@ -17,6 +17,4 @@ # A jitframe is a jit.backend.llsupport.llmodel.JITFRAME = GcArray(Signed). # Stack frame fixed area # Currently only the force_index -FRAME_FIXED_SIZE = 1 JITFRAME_FIXED_SIZE = 16 + 16 * 2 # 16 GPR + 16 VFP Regs (64bit) - diff --git a/rpython/jit/backend/arm/assembler.py b/rpython/jit/backend/arm/assembler.py --- a/rpython/jit/backend/arm/assembler.py +++ b/rpython/jit/backend/arm/assembler.py @@ -6,7 +6,7 @@ from rpython.jit.backend.arm import registers as r from rpython.jit.backend.arm.arch import WORD, DOUBLE_WORD, FUNC_ALIGN, \ N_REGISTERS_SAVED_BY_MALLOC, \ - JITFRAME_FIXED_SIZE, FRAME_FIXED_SIZE + JITFRAME_FIXED_SIZE from rpython.jit.backend.arm.codebuilder import ARMv7Builder, OverwritingBuilder from rpython.jit.backend.arm.locations import get_fp_offset, imm, StackLocation from rpython.jit.backend.arm.regalloc import (Regalloc, ARMFrameManager, @@ -520,16 +520,20 @@ if self.cpu.supports_floats: mc.VPOP([reg.value for reg in r.callee_saved_vfp_registers], cond=cond) - mc.POP([reg.value for reg in r.callee_restored_registers], cond=cond) + # push all callee saved registers and IP to keep the alignment + mc.POP([reg.value for reg in r.callee_restored_registers] + + [r.ip.value], cond=cond) mc.BKPT() def gen_func_prolog(self): - stack_size = FRAME_FIXED_SIZE * WORD + stack_size = WORD #alignment stack_size += len(r.callee_saved_registers) * WORD if self.cpu.supports_floats: stack_size += len(r.callee_saved_vfp_registers) * 2 * WORD - self.mc.PUSH([reg.value for reg in r.callee_saved_registers]) + # push all callee saved registers and IP to keep the alignment + self.mc.PUSH([reg.value for reg in r.callee_saved_registers] + + [r.ip.value]) if self.cpu.supports_floats: self.mc.VPUSH([reg.value for reg in r.callee_saved_vfp_registers]) assert stack_size % 8 == 0 # ensure we keep alignment From noreply at buildbot.pypy.org Fri Feb 8 18:37:10 2013 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 8 Feb 2013 18:37:10 +0100 (CET) Subject: [pypy-commit] pypy default: Update to cffi c42e0c485fc8. Message-ID: <20130208173710.14C391C0110@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r60987:e2ea2eb4743c Date: 2013-02-08 10:16 +0100 http://bitbucket.org/pypy/pypy/changeset/e2ea2eb4743c/ Log: Update to cffi c42e0c485fc8. diff --git a/pypy/module/_cffi_backend/ctypeptr.py b/pypy/module/_cffi_backend/ctypeptr.py --- a/pypy/module/_cffi_backend/ctypeptr.py +++ b/pypy/module/_cffi_backend/ctypeptr.py @@ -252,7 +252,10 @@ def _prepare_pointer_call_argument(self, w_init, cdata): space = self.space - if (space.isinstance_w(w_init, space.w_list) or + if space.is_w(w_init, space.w_None): + rffi.cast(rffi.CCHARPP, cdata)[0] = lltype.nullptr(rffi.CCHARP.TO) + return 3 + elif (space.isinstance_w(w_init, space.w_list) or space.isinstance_w(w_init, space.w_tuple)): length = space.int_w(space.len(w_init)) elif space.isinstance_w(w_init, space.w_basestring): diff --git a/pypy/module/_cffi_backend/test/_backend_test_c.py b/pypy/module/_cffi_backend/test/_backend_test_c.py --- a/pypy/module/_cffi_backend/test/_backend_test_c.py +++ b/pypy/module/_cffi_backend/test/_backend_test_c.py @@ -998,6 +998,8 @@ f = cast(BFunc23, _testfunc(23)) res = f(b"foo") assert res == 1000 * ord(b'f') + res = f(None) + assert res == -42 def test_call_function_23_bis(): # declaring the function as int(unsigned char*) diff --git a/pypy/module/_cffi_backend/test/_test_lib.c b/pypy/module/_cffi_backend/test/_test_lib.c --- a/pypy/module/_cffi_backend/test/_test_lib.c +++ b/pypy/module/_cffi_backend/test/_test_lib.c @@ -174,7 +174,9 @@ static int _testfunc23(char *p) { - return 1000 * p[0]; + if (p) + return 1000 * p[0]; + return -42; } DLLEXPORT void *gettestfunc(int num) From noreply at buildbot.pypy.org Fri Feb 8 18:37:11 2013 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 8 Feb 2013 18:37:11 +0100 (CET) Subject: [pypy-commit] pypy default: merge heads Message-ID: <20130208173711.69B0D1C0110@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r60988:ca1b566f9dea Date: 2013-02-08 18:36 +0100 http://bitbucket.org/pypy/pypy/changeset/ca1b566f9dea/ Log: merge heads diff --git a/pypy/module/_cffi_backend/ctypeptr.py b/pypy/module/_cffi_backend/ctypeptr.py --- a/pypy/module/_cffi_backend/ctypeptr.py +++ b/pypy/module/_cffi_backend/ctypeptr.py @@ -252,7 +252,10 @@ def _prepare_pointer_call_argument(self, w_init, cdata): space = self.space - if (space.isinstance_w(w_init, space.w_list) or + if space.is_w(w_init, space.w_None): + rffi.cast(rffi.CCHARPP, cdata)[0] = lltype.nullptr(rffi.CCHARP.TO) + return 3 + elif (space.isinstance_w(w_init, space.w_list) or space.isinstance_w(w_init, space.w_tuple)): length = space.int_w(space.len(w_init)) elif space.isinstance_w(w_init, space.w_basestring): diff --git a/pypy/module/_cffi_backend/test/_backend_test_c.py b/pypy/module/_cffi_backend/test/_backend_test_c.py --- a/pypy/module/_cffi_backend/test/_backend_test_c.py +++ b/pypy/module/_cffi_backend/test/_backend_test_c.py @@ -998,6 +998,8 @@ f = cast(BFunc23, _testfunc(23)) res = f(b"foo") assert res == 1000 * ord(b'f') + res = f(None) + assert res == -42 def test_call_function_23_bis(): # declaring the function as int(unsigned char*) diff --git a/pypy/module/_cffi_backend/test/_test_lib.c b/pypy/module/_cffi_backend/test/_test_lib.c --- a/pypy/module/_cffi_backend/test/_test_lib.c +++ b/pypy/module/_cffi_backend/test/_test_lib.c @@ -174,7 +174,9 @@ static int _testfunc23(char *p) { - return 1000 * p[0]; + if (p) + return 1000 * p[0]; + return -42; } DLLEXPORT void *gettestfunc(int num) From noreply at buildbot.pypy.org Fri Feb 8 18:49:24 2013 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 8 Feb 2013 18:49:24 +0100 (CET) Subject: [pypy-commit] pypy default: Backout 4f6fde5fcf81 (breaks translation) Message-ID: <20130208174924.E85EE1C0110@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r60989:39f0f4bc6109 Date: 2013-02-08 19:48 +0200 http://bitbucket.org/pypy/pypy/changeset/39f0f4bc6109/ Log: Backout 4f6fde5fcf81 (breaks translation) diff --git a/pypy/module/micronumpy/test/test_dtypes.py b/pypy/module/micronumpy/test/test_dtypes.py --- a/pypy/module/micronumpy/test/test_dtypes.py +++ b/pypy/module/micronumpy/test/test_dtypes.py @@ -529,8 +529,6 @@ assert numpy.complex128(1.2) == numpy.complex128(complex(1.2, 0)) assert numpy.complex64(1.2) == numpy.complex64(complex(1.2, 0)) raises (TypeError, numpy.array, [3+4j], dtype=float) - a = (0.5+1.5j) - assert '{0:g}'.format(a) == '{0:g}'.format(numpy.complex64(a)) def test_complex(self): import _numpypy as numpy diff --git a/pypy/module/micronumpy/types.py b/pypy/module/micronumpy/types.py --- a/pypy/module/micronumpy/types.py +++ b/pypy/module/micronumpy/types.py @@ -1030,9 +1030,6 @@ def for_computation(v): return float(v[0]), float(v[1]) - def to_builtin_type(self, space, box): - return space.wrap(complex(*self.for_computation(self.unbox(box)))) - def read_bool(self, arr, i, offset): v = self.for_computation(self._read(arr.storage, i, offset)) return bool(v[0]) or bool(v[1]) From noreply at buildbot.pypy.org Fri Feb 8 19:39:43 2013 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 8 Feb 2013 19:39:43 +0100 (CET) Subject: [pypy-commit] pypy default: A hard-to-test case: an assert which may actually fail Message-ID: <20130208183943.9813F1C0110@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r60990:bfb3a4f5c8ad Date: 2013-02-08 18:37 +0100 http://bitbucket.org/pypy/pypy/changeset/bfb3a4f5c8ad/ Log: A hard-to-test case: an assert which may actually fail diff --git a/rpython/jit/metainterp/pyjitpl.py b/rpython/jit/metainterp/pyjitpl.py --- a/rpython/jit/metainterp/pyjitpl.py +++ b/rpython/jit/metainterp/pyjitpl.py @@ -2108,8 +2108,11 @@ num_green_args = self.jitdriver_sd.num_green_args greenkey = original_boxes[:num_green_args] if not self.partial_trace: - assert self.get_procedure_token(greenkey) is None or \ - self.get_procedure_token(greenkey).target_tokens is None + ptoken = self.get_procedure_token(greenkey) + if ptoken is not None and ptoken.target_tokens is not None: + # XXX this path not tested, but shown to occur on pypy-c :-( + self.staticdata.log('cancelled: we already have a token now') + raise SwitchToBlackhole(Counters.ABORT_BAD_LOOP) if self.partial_trace: target_token = compile.compile_retrace(self, greenkey, start, original_boxes[num_green_args:], From noreply at buildbot.pypy.org Fri Feb 8 19:39:44 2013 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 8 Feb 2013 19:39:44 +0100 (CET) Subject: [pypy-commit] pypy default: merge heads Message-ID: <20130208183944.C34701C0110@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r60991:e6bb3153dc24 Date: 2013-02-08 19:39 +0100 http://bitbucket.org/pypy/pypy/changeset/e6bb3153dc24/ Log: merge heads diff --git a/pypy/module/micronumpy/test/test_dtypes.py b/pypy/module/micronumpy/test/test_dtypes.py --- a/pypy/module/micronumpy/test/test_dtypes.py +++ b/pypy/module/micronumpy/test/test_dtypes.py @@ -529,8 +529,6 @@ assert numpy.complex128(1.2) == numpy.complex128(complex(1.2, 0)) assert numpy.complex64(1.2) == numpy.complex64(complex(1.2, 0)) raises (TypeError, numpy.array, [3+4j], dtype=float) - a = (0.5+1.5j) - assert '{0:g}'.format(a) == '{0:g}'.format(numpy.complex64(a)) def test_complex(self): import _numpypy as numpy diff --git a/pypy/module/micronumpy/types.py b/pypy/module/micronumpy/types.py --- a/pypy/module/micronumpy/types.py +++ b/pypy/module/micronumpy/types.py @@ -1030,9 +1030,6 @@ def for_computation(v): return float(v[0]), float(v[1]) - def to_builtin_type(self, space, box): - return space.wrap(complex(*self.for_computation(self.unbox(box)))) - def read_bool(self, arr, i, offset): v = self.for_computation(self._read(arr.storage, i, offset)) return bool(v[0]) or bool(v[1]) From noreply at buildbot.pypy.org Sat Feb 9 00:23:51 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sat, 9 Feb 2013 00:23:51 +0100 (CET) Subject: [pypy-commit] pypy default: try to fix freebsd7 translation Message-ID: <20130208232351.44EB61C0110@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r60992:fe56756e3a72 Date: 2013-02-08 18:23 -0500 http://bitbucket.org/pypy/pypy/changeset/fe56756e3a72/ Log: try to fix freebsd7 translation diff --git a/rpython/translator/platform/posix.py b/rpython/translator/platform/posix.py --- a/rpython/translator/platform/posix.py +++ b/rpython/translator/platform/posix.py @@ -47,6 +47,9 @@ if not eci.export_symbols: return [] + if sys.platform == 'freebsd7': + eci.export_symbols += ('__progname', 'environ') + response_file = self._make_response_file("dynamic-symbols-") f = response_file.open("w") f.write("{\n\tglobal:\n") From noreply at buildbot.pypy.org Sat Feb 9 00:26:09 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Sat, 9 Feb 2013 00:26:09 +0100 (CET) Subject: [pypy-commit] pypy py3k: hack around space.warn unicode input for now to fix translation Message-ID: <20130208232609.D44BB1C0110@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r60993:170b1c1a475c Date: 2013-02-08 15:01 -0800 http://bitbucket.org/pypy/pypy/changeset/170b1c1a475c/ Log: hack around space.warn unicode input for now to fix translation diff --git a/pypy/module/_io/interp_fileio.py b/pypy/module/_io/interp_fileio.py --- a/pypy/module/_io/interp_fileio.py +++ b/pypy/module/_io/interp_fileio.py @@ -250,7 +250,13 @@ if self.fd >= 0 and self.closefd: try: r = space.unicode_w(space.repr(w_source)) - space.warn(u"unclosed file %s" % r, space.w_ResourceWarning) + # TODO: space.warn is currently typed to str + #space.warn(u"unclosed file %s" % r, space.w_ResourceWarning) + msg = u"unclosed file %s" % r + space.appexec([space.wrap(msg), space.w_ResourceWarning], + """(msg, warningcls): + import _warnings + _warnings.warn(msg, warningcls, stacklevel=2)""") except OperationError as e: # Spurious errors can appear at shutdown if e.match(space, space.w_Warning): From noreply at buildbot.pypy.org Sat Feb 9 00:26:11 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Sat, 9 Feb 2013 00:26:11 +0100 (CET) Subject: [pypy-commit] pypy py3k: use full paths for __file__ and fix test_zipimport's marshal data Message-ID: <20130208232611.0B7941C0110@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r60994:a823801fd7ed Date: 2013-02-08 15:06 -0800 http://bitbucket.org/pypy/pypy/changeset/a823801fd7ed/ Log: use full paths for __file__ and fix test_zipimport's marshal data diff --git a/pypy/module/zipimport/interp_zipimport.py b/pypy/module/zipimport/interp_zipimport.py --- a/pypy/module/zipimport/interp_zipimport.py +++ b/pypy/module/zipimport/interp_zipimport.py @@ -205,7 +205,7 @@ space.setattr(w_mod, w('__loader__'), space.wrap(self)) importing._prepare_module(space, w_mod, real_name, pkgpath) result = importing.load_compiled_module(space, w(modname), w_mod, - filename, magic, timestamp, + real_name, magic, timestamp, buf) return result diff --git a/pypy/module/zipimport/test/test_zipimport.py b/pypy/module/zipimport/test/test_zipimport.py --- a/pypy/module/zipimport/test/test_zipimport.py +++ b/pypy/module/zipimport/test/test_zipimport.py @@ -1,5 +1,3 @@ - -import marshal import py, os import time import struct @@ -16,13 +14,15 @@ """ compression = ZIP_STORED spaceconfig = { - "usemodules": ['zipimport', 'rctime', 'struct', 'binascii'], + "usemodules": ['zipimport', 'rctime', 'struct', 'binascii', 'marshal'], } pathsep = os.path.sep @classmethod - def make_pyc(cls, space, co, mtime): - data = marshal.dumps(co) + def make_pyc(cls, space, w_co, mtime): + w_data = space.call_method(space.getbuiltinmodule('marshal'), + 'dumps', w_co) + data = space.bytes_w(w_data) if type(mtime) is type(0.0): # Mac mtimes need a bit of special casing if mtime < 0x7fffffff: @@ -40,30 +40,27 @@ @classmethod def make_class(cls): - # XXX: this is (mostly) wrong: .compile() compiles the code object - # using the host python compiler, but then in the tests we load it - # with py.py. It works (mostly by chance) because the two functions - # are very simple and the bytecodes are compatible enough. - # XXX with py3k this does not work anymore. - co = py.code.Source(""" - def get_name(): - return __name__ - def get_file(): - return __file__ - """).compile() - + source = """\ +def get_name(): + return __name__ +def get_file(): + return __file__ + """ space = cls.space + w = space.wrap + w_co = space.call_method(space.builtin, 'compile', + w(source), w('uuu.py'), w('exec')) tmpdir = udir.ensure('zipimport_%s' % cls.__name__, dir=1) now = time.time() - cls.w_now = space.wrap(now) - test_pyc = cls.make_pyc(space, co, now) + cls.w_now = w(now) + test_pyc = cls.make_pyc(space, w_co, now) cls.w_test_pyc = space.wrapbytes(test_pyc) - cls.w_compression = space.wrap(cls.compression) - cls.w_pathsep = space.wrap(cls.pathsep) + cls.w_compression = w(cls.compression) + cls.w_pathsep = w(cls.pathsep) #ziptestmodule = tmpdir.ensure('ziptestmodule.zip').write( ziptestmodule = tmpdir.join("somezip.zip") - cls.w_tmpzip = space.wrap(str(ziptestmodule)) + cls.w_tmpzip = w(str(ziptestmodule)) cls.tmpdir = tmpdir def setup_class(cls): From noreply at buildbot.pypy.org Sat Feb 9 01:54:15 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sat, 9 Feb 2013 01:54:15 +0100 (CET) Subject: [pypy-commit] pypy default: clean up datetime argument handling, improve tests Message-ID: <20130209005415.BB8701C0110@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r60995:72e79a8305c7 Date: 2013-02-08 19:52 -0500 http://bitbucket.org/pypy/pypy/changeset/72e79a8305c7/ Log: clean up datetime argument handling, improve tests diff --git a/lib_pypy/datetime.py b/lib_pypy/datetime.py --- a/lib_pypy/datetime.py +++ b/lib_pypy/datetime.py @@ -18,6 +18,7 @@ import time as _time import math as _math +import decimal as _decimal MINYEAR = 1 MAXYEAR = 9999 @@ -270,10 +271,15 @@ return offset raise ValueError("%s()=%d, must be in -1439..1439" % (name, offset)) +def _check_int_field(value): + if not isinstance(value, (int, long, _decimal.Decimal)): + raise TypeError('integer argument expected') + return int(value) + def _check_date_fields(year, month, day): - for value in [year, day]: - if not isinstance(value, (int, long)): - raise TypeError('int expected') + year = _check_int_field(year) + month = _check_int_field(month) + day = _check_int_field(day) if not MINYEAR <= year <= MAXYEAR: raise ValueError('year must be in %d..%d' % (MINYEAR, MAXYEAR), year) if not 1 <= month <= 12: @@ -281,11 +287,13 @@ dim = _days_in_month(year, month) if not 1 <= day <= dim: raise ValueError('day must be in 1..%d' % dim, day) + return year, month, day def _check_time_fields(hour, minute, second, microsecond): - for value in [hour, minute, second, microsecond]: - if not isinstance(value, (int, long)): - raise TypeError('int expected') + hour = _check_int_field(hour) + minute = _check_int_field(minute) + second = _check_int_field(second) + microsecond = _check_int_field(microsecond) if not 0 <= hour <= 23: raise ValueError('hour must be in 0..23', hour) if not 0 <= minute <= 59: @@ -294,6 +302,7 @@ raise ValueError('second must be in 0..59', second) if not 0 <= microsecond <= 999999: raise ValueError('microsecond must be in 0..999999', microsecond) + return hour, minute, second, microsecond def _check_tzinfo_arg(tz): if tz is not None and not isinstance(tz, tzinfo): @@ -768,7 +777,7 @@ self = object.__new__(cls) self.__setstate(year) return self - _check_date_fields(year, month, day) + year, month, day = _check_date_fields(year, month, day) self = object.__new__(cls) self._year = year self._month = month @@ -889,7 +898,7 @@ month = self._month if day is None: day = self._day - _check_date_fields(year, month, day) + year, month, day = _check_date_fields(year, month, day) return date(year, month, day) # Comparisons of date objects with other. @@ -1150,13 +1159,14 @@ second, microsecond (default to zero) tzinfo (default to None) """ - self = object.__new__(cls) if isinstance(hour, str): # Pickle support + self = object.__new__(cls) self.__setstate(hour, minute or None) return self + hour, minute, second, microsecond = _check_time_fields(hour, minute, second, microsecond) _check_tzinfo_arg(tzinfo) - _check_time_fields(hour, minute, second, microsecond) + self = object.__new__(cls) self._hour = hour self._minute = minute self._second = second @@ -1387,7 +1397,7 @@ microsecond = self.microsecond if tzinfo is True: tzinfo = self.tzinfo - _check_time_fields(hour, minute, second, microsecond) + hour, minute, second, microsecond = _check_time_fields(hour, minute, second, microsecond) _check_tzinfo_arg(tzinfo) return time(hour, minute, second, microsecond, tzinfo) @@ -1449,10 +1459,10 @@ self = date.__new__(cls, year[:4]) self.__setstate(year, month) return self + year, month, day = _check_date_fields(year, month, day) + hour, minute, second, microsecond = _check_time_fields(hour, minute, second, microsecond) _check_tzinfo_arg(tzinfo) - _check_time_fields(hour, minute, second, microsecond) - self = date.__new__(cls, year, month, day) - # XXX This duplicates __year, __month, __day for convenience :-( + self = object.__new__(cls) self._year = year self._month = month self._day = day @@ -1617,8 +1627,8 @@ microsecond = self.microsecond if tzinfo is True: tzinfo = self.tzinfo - _check_date_fields(year, month, day) - _check_time_fields(hour, minute, second, microsecond) + year, month, day = _check_date_fields(year, month, day) + hour, minute, second, microsecond = _check_time_fields(hour, minute, second, microsecond) _check_tzinfo_arg(tzinfo) return datetime(year, month, day, hour, minute, second, microsecond, tzinfo) diff --git a/pypy/module/test_lib_pypy/test_datetime.py b/pypy/module/test_lib_pypy/test_datetime.py --- a/pypy/module/test_lib_pypy/test_datetime.py +++ b/pypy/module/test_lib_pypy/test_datetime.py @@ -30,14 +30,40 @@ dt = datetime.datetime.utcfromtimestamp(0) assert isinstance(dt.microsecond, int) +def test_default_args(): + with py.test.raises(TypeError): + datetime.datetime() + with py.test.raises(TypeError): + datetime.datetime(10) + with py.test.raises(TypeError): + datetime.datetime(10, 10) + datetime.datetime(10, 10, 10) -def test_integer_args(): +def test_check_arg_types(): + import decimal + i10 = 10 + l10 = 10L + d10 = decimal.Decimal(10) + d11 = decimal.Decimal(10.9) + assert datetime.datetime(i10, i10, i10, i10, i10, i10, i10) == \ + datetime.datetime(l10, l10, l10, l10, l10, l10, l10) == \ + datetime.datetime(d10, d10, d10, d10, d10, d10, d10) == \ + datetime.datetime(d11, d11, d11, d11, d11, d11, d11) + + with py.test.raises(TypeError): + datetime.datetime(10., 10, 10) + with py.test.raises(TypeError): + datetime.datetime(10, 10., 10) with py.test.raises(TypeError): datetime.datetime(10, 10, 10.) with py.test.raises(TypeError): + datetime.datetime(10, 10, 10, 10.) + with py.test.raises(TypeError): datetime.datetime(10, 10, 10, 10, 10.) with py.test.raises(TypeError): datetime.datetime(10, 10, 10, 10, 10, 10.) + with py.test.raises(TypeError): + datetime.datetime(10, 10, 10, 10, 10, 10, 10.) def test_utcnow_microsecond(): dt = datetime.datetime.utcnow() From noreply at buildbot.pypy.org Sat Feb 9 03:16:14 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sat, 9 Feb 2013 03:16:14 +0100 (CET) Subject: [pypy-commit] pypy default: add numpy indexing by list test Message-ID: <20130209021614.0B9221C0110@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r60996:5691aa9f6d83 Date: 2013-02-08 21:13 -0500 http://bitbucket.org/pypy/pypy/changeset/5691aa9f6d83/ Log: add numpy indexing by list test diff --git a/lib_pypy/_collections.py b/lib_pypy/_collections.py --- a/lib_pypy/_collections.py +++ b/lib_pypy/_collections.py @@ -142,12 +142,15 @@ return c def remove(self, value): - # Need to be defensive for mutating comparisons for i in range(len(self)): - if self[i] == value: - del self[i] - return - raise ValueError("deque.remove(x): x not in deque") + elem = self.popleft() + if elem == value: + break + self.append(elem) + else: + raise ValueError("deque.remove(x): x not in deque") + for i in range(len(self) - i): + self.append(self.popleft()) def rotate(self, n=1): length = len(self) diff --git a/pypy/module/micronumpy/test/test_numarray.py b/pypy/module/micronumpy/test/test_numarray.py --- a/pypy/module/micronumpy/test/test_numarray.py +++ b/pypy/module/micronumpy/test/test_numarray.py @@ -1595,6 +1595,12 @@ a[a<0] = -a[a<0] assert (a == [1, 1]).all() + def test_int_list_index(slf): + from numpypy import array, arange + assert (array([10,11,12,13])[[1,2]] == [11, 12]).all() + assert (arange(6).reshape((2,3))[[0,1]] == [[0, 1, 2], [3, 4, 5]]).all() + assert arange(6).reshape((2,3))[(0,1)] == 1 + def test_int_array_index(self): from numpypy import array, arange, zeros b = arange(10)[array([3, 2, 1, 5])] From noreply at buildbot.pypy.org Sat Feb 9 03:18:58 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sat, 9 Feb 2013 03:18:58 +0100 (CET) Subject: [pypy-commit] pypy default: backout accidental inclusion to last commit Message-ID: <20130209021858.8855E1C02D9@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r60997:a8d47219e78c Date: 2013-02-08 21:18 -0500 http://bitbucket.org/pypy/pypy/changeset/a8d47219e78c/ Log: backout accidental inclusion to last commit diff --git a/lib_pypy/_collections.py b/lib_pypy/_collections.py --- a/lib_pypy/_collections.py +++ b/lib_pypy/_collections.py @@ -142,15 +142,12 @@ return c def remove(self, value): + # Need to be defensive for mutating comparisons for i in range(len(self)): - elem = self.popleft() - if elem == value: - break - self.append(elem) - else: - raise ValueError("deque.remove(x): x not in deque") - for i in range(len(self) - i): - self.append(self.popleft()) + if self[i] == value: + del self[i] + return + raise ValueError("deque.remove(x): x not in deque") def rotate(self, n=1): length = len(self) From noreply at buildbot.pypy.org Sat Feb 9 04:10:29 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sat, 9 Feb 2013 04:10:29 +0100 (CET) Subject: [pypy-commit] pypy default: add numpy.bool/int aliases, test (fixes issue1161) Message-ID: <20130209031029.07DCE1C0110@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r60998:481f9cde9e3e Date: 2013-02-08 22:09 -0500 http://bitbucket.org/pypy/pypy/changeset/481f9cde9e3e/ Log: add numpy.bool/int aliases, test (fixes issue1161) diff --git a/pypy/module/micronumpy/__init__.py b/pypy/module/micronumpy/__init__.py --- a/pypy/module/micronumpy/__init__.py +++ b/pypy/module/micronumpy/__init__.py @@ -27,6 +27,9 @@ 'True_': 'types.Bool.True', 'False_': 'types.Bool.False', + 'bool': 'space.w_bool', + 'int': 'space.w_int', + 'typeinfo': 'interp_dtype.get_dtype_cache(space).w_typeinfo', 'generic': 'interp_boxes.W_GenericBox', diff --git a/pypy/module/micronumpy/test/test_dtypes.py b/pypy/module/micronumpy/test/test_dtypes.py --- a/pypy/module/micronumpy/test/test_dtypes.py +++ b/pypy/module/micronumpy/test/test_dtypes.py @@ -494,7 +494,7 @@ def test_complex_format(self): import _numpypy as numpy - + for complex_ in (numpy.complex128, numpy.complex64,): for real, imag, should in [ (1, 2, '(1+2j)'), @@ -505,13 +505,13 @@ #xxx #(numpy.inf, numpy.inf, '(inf+inf*j)'), ]: - + c = complex_(complex(real, imag)) assert c == complex(real, imag) assert c.real == real assert c.imag == imag assert repr(c) == should - + real, imag, should = (1e100, 3e66, '(1e+100+3e+66j)') c128 = numpy.complex128(complex(real, imag)) assert type(c128.real) is type(c128.imag) is numpy.float64 @@ -547,8 +547,6 @@ assert d.kind == 'c' assert d.num == 14 assert d.char == 'F' - - def test_subclass_type(self): import _numpypy as numpy @@ -580,6 +578,9 @@ def test_various_types(self): import _numpypy as numpy + assert numpy.bool is bool + assert numpy.int is int + assert numpy.int16 is numpy.short assert numpy.int8 is numpy.byte assert numpy.bool_ is numpy.bool8 From noreply at buildbot.pypy.org Sat Feb 9 05:55:49 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sat, 9 Feb 2013 05:55:49 +0100 (CET) Subject: [pypy-commit] pypy default: reset mainthreadident after fork (thanks amaury) Message-ID: <20130209045549.B7C121C0110@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r60999:3b06320cf630 Date: 2013-02-08 23:42 -0500 http://bitbucket.org/pypy/pypy/changeset/3b06320cf630/ Log: reset mainthreadident after fork (thanks amaury) diff --git a/pypy/module/thread/gil.py b/pypy/module/thread/gil.py --- a/pypy/module/thread/gil.py +++ b/pypy/module/thread/gil.py @@ -49,6 +49,8 @@ return result def reinit_threads(self, space): + "Called in the child process after a fork()" + OSThreadLocals.reinit_threads(self, space) if self.gil_ready: # re-initialize the gil if needed self._initialize_gil(space) diff --git a/pypy/module/thread/test/test_fork.py b/pypy/module/thread/test/test_fork.py --- a/pypy/module/thread/test/test_fork.py +++ b/pypy/module/thread/test/test_fork.py @@ -57,3 +57,30 @@ self.timeout_killer(pid, 5) exitcode = os.waitpid(pid, 0)[1] assert exitcode == 0 # if 9, process was killed by timer! + + def test_forked_is_main_thread(self): + "Checks that a forked interpreter is the main thread" + import os, thread, signal + + if not hasattr(os, 'fork'): + skip("No fork on this platform") + + def threadfunction(): + pid = os.fork() + if pid == 0: + print 'in child' + # signal() only works from the 'main' thread + signal.signal(signal.SIGUSR1, signal.SIG_IGN) + os._exit(42) + else: + self.timeout_killer(pid, 5) + exitcode = os.waitpid(pid, 0)[1] + feedback.append(exitcode) + + feedback = [] + thread.start_new_thread(threadfunction, ()) + self.waitfor(lambda: feedback) + # if 0, an (unraisable) exception was raised from the forked thread. + # if 9, process was killed by timer. + # if 42<<8, os._exit(42) was correctly reached. + assert feedback == [42<<8] diff --git a/pypy/module/thread/threadlocals.py b/pypy/module/thread/threadlocals.py --- a/pypy/module/thread/threadlocals.py +++ b/pypy/module/thread/threadlocals.py @@ -57,3 +57,7 @@ thread_is_stopping(self.getvalue()) finally: self.setvalue(None) + + def reinit_threads(self, space): + "Called in the child process after a fork()" + self._mainthreadident = thread.get_ident() From noreply at buildbot.pypy.org Sat Feb 9 07:41:51 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sat, 9 Feb 2013 07:41:51 +0100 (CET) Subject: [pypy-commit] pypy default: patch from raymondh to optimize deque.remove in lib_pypy/_collections.py (normally overridden by builtin _collections) Message-ID: <20130209064151.E44251C0228@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61000:5e3878959d9b Date: 2013-02-09 01:21 -0500 http://bitbucket.org/pypy/pypy/changeset/5e3878959d9b/ Log: patch from raymondh to optimize deque.remove in lib_pypy/_collections.py (normally overridden by builtin _collections) diff --git a/lib_pypy/_collections.py b/lib_pypy/_collections.py --- a/lib_pypy/_collections.py +++ b/lib_pypy/_collections.py @@ -142,12 +142,18 @@ return c def remove(self, value): - # Need to be defensive for mutating comparisons - for i in range(len(self)): - if self[i] == value: - del self[i] - return - raise ValueError("deque.remove(x): x not in deque") + # Need to defend mutating or failing comparisons + i = 0 + try: + for i in range(len(self)): + if self[0] == value: + self.popleft() + return + self.append(self.popleft()) + i += 1 + raise ValueError("deque.remove(x): x not in deque") + finally: + self.rotate(i) def rotate(self, n=1): length = len(self) From noreply at buildbot.pypy.org Sat Feb 9 07:41:53 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sat, 9 Feb 2013 07:41:53 +0100 (CET) Subject: [pypy-commit] pypy default: add another test here Message-ID: <20130209064153.26A311C0228@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61001:b585e6cac917 Date: 2013-02-09 01:41 -0500 http://bitbucket.org/pypy/pypy/changeset/b585e6cac917/ Log: add another test here diff --git a/lib_pypy/pypy_test/test_collections.py b/lib_pypy/pypy_test/test_collections.py --- a/lib_pypy/pypy_test/test_collections.py +++ b/lib_pypy/pypy_test/test_collections.py @@ -16,6 +16,17 @@ d = collections.deque([MutatingCmp()]) py.test.raises(IndexError, d.remove, 1) + def test_remove_failing(self): + class FailingCmp(object): + def __eq__(self, other): + assert False + + f = FailingCmp() + d = collections.deque([1, 2, 3, f, 4, 5]) + d.remove(3) + py.test.raises(AssertionError, d.remove, 4) + assert d == collections.deque([1, 2, f, 4, 5]) + def test_maxlen(self): d = collections.deque([], 3) d.append(1); d.append(2); d.append(3); d.append(4) From noreply at buildbot.pypy.org Sat Feb 9 08:07:47 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Sat, 9 Feb 2013 08:07:47 +0100 (CET) Subject: [pypy-commit] pypy py3k: test_multiprocessing seems to deadlock the buildbots Message-ID: <20130209070747.DECA21C1029@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61002:6d540e777b5b Date: 2013-02-08 23:07 -0800 http://bitbucket.org/pypy/pypy/changeset/6d540e777b5b/ Log: test_multiprocessing seems to deadlock the buildbots diff --git a/lib-python/conftest.py b/lib-python/conftest.py --- a/lib-python/conftest.py +++ b/lib-python/conftest.py @@ -280,7 +280,7 @@ RegrTest('test_modulefinder.py'), RegrTest('test_msilib.py'), RegrTest('test_multibytecodec.py', usemodules='_multibytecodec'), - RegrTest('test_multiprocessing.py'), + RegrTest('test_multiprocessing.py', skip="XXX: deadlocks the buildbots"), RegrTest('test_mutants.py', core="possibly"), RegrTest('test_netrc.py'), RegrTest('test_nis.py'), From noreply at buildbot.pypy.org Sat Feb 9 11:52:10 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sat, 9 Feb 2013 11:52:10 +0100 (CET) Subject: [pypy-commit] pypy default: use DYLD_LIBRARY_PATH on darwin Message-ID: <20130209105210.2D6CC1C1029@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61003:c729af9671e6 Date: 2013-02-09 02:51 -0800 http://bitbucket.org/pypy/pypy/changeset/c729af9671e6/ Log: use DYLD_LIBRARY_PATH on darwin diff --git a/rpython/translator/c/gcc/test/test_asmgcroot.py b/rpython/translator/c/gcc/test/test_asmgcroot.py --- a/rpython/translator/c/gcc/test/test_asmgcroot.py +++ b/rpython/translator/c/gcc/test/test_asmgcroot.py @@ -73,7 +73,11 @@ else: redirect = '' if config.translation.shared and os.name == 'posix': - env = 'LD_LIBRARY_PATH="%s" ' % (exe_name.dirpath(),) + library_path = exe_name.dirpath() + if sys.platform == 'darwin': + env = 'DYLD_LIBRARY_PATH="%s" ' % library_path + else: + env = 'LD_LIBRARY_PATH="%s" ' % library_path else: env = '' cwd = os.getcwd() diff --git a/rpython/translator/c/test/test_standalone.py b/rpython/translator/c/test/test_standalone.py --- a/rpython/translator/c/test/test_standalone.py +++ b/rpython/translator/c/test/test_standalone.py @@ -687,8 +687,12 @@ t, cbuilder = self.compile(entry_point, shared=True) assert cbuilder.shared_library_name is not None assert cbuilder.shared_library_name != cbuilder.executable_name - monkeypatch.setenv('LD_LIBRARY_PATH', - cbuilder.shared_library_name.dirpath()) + if os.name == 'posix': + library_path = cbuilder.shared_library_name.dirpath() + if sys.platform == 'darwin': + monkeypatch.setenv('DYLD_LIBRARY_PATH', library_path) + else: + monkeypatch.setenv('LD_LIBRARY_PATH', library_path) out, err = cbuilder.cmdexec("a b") assert out == "3" diff --git a/rpython/translator/platform/__init__.py b/rpython/translator/platform/__init__.py --- a/rpython/translator/platform/__init__.py +++ b/rpython/translator/platform/__init__.py @@ -89,8 +89,11 @@ # Set LD_LIBRARY_PATH on posix platforms if os.name == 'posix' and compilation_info is not None: - env['LD_LIBRARY_PATH'] = ':'.join( - [str(i) for i in compilation_info.library_dirs]) + library_path = ':'.join([str(i) for i in compilation_info.library_dirs]) + if sys.platform == 'darwin': + env['DYLD_LIBRARY_PATH'] = library_path + else: + env['LD_LIBRARY_PATH'] = library_path returncode, stdout, stderr = _run_subprocess(str(executable), args, env) From noreply at buildbot.pypy.org Sat Feb 9 17:50:16 2013 From: noreply at buildbot.pypy.org (rlamy) Date: Sat, 9 Feb 2013 17:50:16 +0100 (CET) Subject: [pypy-commit] pypy kill-flowobjspace: hg merge default Message-ID: <20130209165016.345BD1C080A@cobra.cs.uni-duesseldorf.de> Author: Ronan Lamy Branch: kill-flowobjspace Changeset: r61004:581e3b2a8a35 Date: 2013-02-09 16:49 +0000 http://bitbucket.org/pypy/pypy/changeset/581e3b2a8a35/ Log: hg merge default diff too long, truncating to 2000 out of 5859 lines diff --git a/lib-python/2.7/collections.py b/lib-python/2.7/collections.py --- a/lib-python/2.7/collections.py +++ b/lib-python/2.7/collections.py @@ -6,11 +6,12 @@ __all__ += _abcoll.__all__ from _collections import deque, defaultdict +from operator import itemgetter as _itemgetter, eq as _eq from keyword import iskeyword as _iskeyword import sys as _sys import heapq as _heapq -from operator import itemgetter as _itemgetter from itertools import repeat as _repeat, chain as _chain, starmap as _starmap +from itertools import imap as _imap try: from thread import get_ident as _get_ident @@ -50,49 +51,45 @@ self.__map = {} self.__update(*args, **kwds) - def __setitem__(self, key, value, PREV=0, NEXT=1, dict_setitem=dict.__setitem__): + def __setitem__(self, key, value, dict_setitem=dict.__setitem__): 'od.__setitem__(i, y) <==> od[i]=y' # Setting a new item creates a new link at the end of the linked list, # and the inherited dictionary is updated with the new key/value pair. if key not in self: root = self.__root - last = root[PREV] - last[NEXT] = root[PREV] = self.__map[key] = [last, root, key] - dict_setitem(self, key, value) + last = root[0] + last[1] = root[0] = self.__map[key] = [last, root, key] + return dict_setitem(self, key, value) - def __delitem__(self, key, PREV=0, NEXT=1, dict_delitem=dict.__delitem__): + def __delitem__(self, key, dict_delitem=dict.__delitem__): 'od.__delitem__(y) <==> del od[y]' # Deleting an existing item uses self.__map to find the link which gets # removed by updating the links in the predecessor and successor nodes. dict_delitem(self, key) link_prev, link_next, key = self.__map.pop(key) - link_prev[NEXT] = link_next - link_next[PREV] = link_prev + link_prev[1] = link_next # update link_prev[NEXT] + link_next[0] = link_prev # update link_next[PREV] def __iter__(self): 'od.__iter__() <==> iter(od)' # Traverse the linked list in order. - NEXT, KEY = 1, 2 root = self.__root - curr = root[NEXT] + curr = root[1] # start at the first node while curr is not root: - yield curr[KEY] - curr = curr[NEXT] + yield curr[2] # yield the curr[KEY] + curr = curr[1] # move to next node def __reversed__(self): 'od.__reversed__() <==> reversed(od)' # Traverse the linked list in reverse order. - PREV, KEY = 0, 2 root = self.__root - curr = root[PREV] + curr = root[0] # start at the last node while curr is not root: - yield curr[KEY] - curr = curr[PREV] + yield curr[2] # yield the curr[KEY] + curr = curr[0] # move to previous node def clear(self): 'od.clear() -> None. Remove all items from od.' - for node in self.__map.itervalues(): - del node[:] root = self.__root root[:] = [root, root, None] self.__map.clear() @@ -208,7 +205,7 @@ ''' if isinstance(other, OrderedDict): - return len(self)==len(other) and self.items() == other.items() + return dict.__eq__(self, other) and all(_imap(_eq, self, other)) return dict.__eq__(self, other) def __ne__(self, other): diff --git a/lib-python/2.7/test/test_modulefinder.py b/lib-python/2.7/test/test_modulefinder.py --- a/lib-python/2.7/test/test_modulefinder.py +++ b/lib-python/2.7/test/test_modulefinder.py @@ -16,7 +16,7 @@ # library. TEST_DIR = tempfile.mkdtemp() -TEST_PATH = [TEST_DIR, os.path.dirname(__future__.__file__)] +TEST_PATH = [TEST_DIR, os.path.dirname(tempfile.__file__)] # Each test description is a list of 5 items: # diff --git a/lib-python/conftest.py b/lib-python/conftest.py --- a/lib-python/conftest.py +++ b/lib-python/conftest.py @@ -160,7 +160,7 @@ RegrTest('test_codeop.py', core=True), RegrTest('test_coding.py', core=True), RegrTest('test_coercion.py', core=True), - RegrTest('test_collections.py'), + RegrTest('test_collections.py', usemodules='binascii struct'), RegrTest('test_colorsys.py'), RegrTest('test_commands.py'), RegrTest('test_compare.py', core=True), @@ -181,7 +181,7 @@ RegrTest('test_csv.py', usemodules='_csv'), RegrTest('test_ctypes.py', usemodules="_rawffi thread"), RegrTest('test_curses.py'), - RegrTest('test_datetime.py'), + RegrTest('test_datetime.py', usemodules='binascii struct'), RegrTest('test_dbm.py'), RegrTest('test_decimal.py'), RegrTest('test_decorators.py', core=True), diff --git a/lib_pypy/_collections.py b/lib_pypy/_collections.py --- a/lib_pypy/_collections.py +++ b/lib_pypy/_collections.py @@ -142,12 +142,18 @@ return c def remove(self, value): - # Need to be defensive for mutating comparisons - for i in range(len(self)): - if self[i] == value: - del self[i] - return - raise ValueError("deque.remove(x): x not in deque") + # Need to defend mutating or failing comparisons + i = 0 + try: + for i in range(len(self)): + if self[0] == value: + self.popleft() + return + self.append(self.popleft()) + i += 1 + raise ValueError("deque.remove(x): x not in deque") + finally: + self.rotate(i) def rotate(self, n=1): length = len(self) diff --git a/lib_pypy/cPickle.py b/lib_pypy/cPickle.py --- a/lib_pypy/cPickle.py +++ b/lib_pypy/cPickle.py @@ -1,5 +1,5 @@ # -# One-liner implementation of cPickle +# Reimplementation of cPickle, mostly as a copy of pickle.py # from pickle import Pickler, dump, dumps, PickleError, PicklingError, UnpicklingError, _EmptyClass @@ -131,6 +131,13 @@ # Unpickling machinery +class _Stack(list): + def pop(self, index=-1): + try: + return list.pop(self, index) + except IndexError: + raise UnpicklingError("unpickling stack underflow") + class Unpickler(object): def __init__(self, file): @@ -155,7 +162,7 @@ Return the reconstituted object hierarchy specified in the file. """ self.mark = object() # any new unique object - self.stack = [] + self.stack = _Stack() self.append = self.stack.append try: key = ord(self.read(1)) diff --git a/lib_pypy/ctypes_support.py b/lib_pypy/ctypes_support.py --- a/lib_pypy/ctypes_support.py +++ b/lib_pypy/ctypes_support.py @@ -19,16 +19,19 @@ if sys.platform == 'win32': standard_c_lib._errno.restype = ctypes.POINTER(ctypes.c_int) + standard_c_lib._errno.argtypes = None def _where_is_errno(): return standard_c_lib._errno() elif sys.platform in ('linux2', 'freebsd6'): standard_c_lib.__errno_location.restype = ctypes.POINTER(ctypes.c_int) + standard_c_lib.__errno_location.argtypes = None def _where_is_errno(): return standard_c_lib.__errno_location() elif sys.platform in ('darwin', 'freebsd7', 'freebsd8', 'freebsd9'): standard_c_lib.__error.restype = ctypes.POINTER(ctypes.c_int) + standard_c_lib.__error.argtypes = None def _where_is_errno(): return standard_c_lib.__error() diff --git a/lib_pypy/datetime.py b/lib_pypy/datetime.py --- a/lib_pypy/datetime.py +++ b/lib_pypy/datetime.py @@ -18,6 +18,7 @@ import time as _time import math as _math +import decimal as _decimal MINYEAR = 1 MAXYEAR = 9999 @@ -270,10 +271,15 @@ return offset raise ValueError("%s()=%d, must be in -1439..1439" % (name, offset)) +def _check_int_field(value): + if not isinstance(value, (int, long, _decimal.Decimal)): + raise TypeError('integer argument expected') + return int(value) + def _check_date_fields(year, month, day): - for value in [year, day]: - if not isinstance(value, (int, long)): - raise TypeError('int expected') + year = _check_int_field(year) + month = _check_int_field(month) + day = _check_int_field(day) if not MINYEAR <= year <= MAXYEAR: raise ValueError('year must be in %d..%d' % (MINYEAR, MAXYEAR), year) if not 1 <= month <= 12: @@ -281,11 +287,13 @@ dim = _days_in_month(year, month) if not 1 <= day <= dim: raise ValueError('day must be in 1..%d' % dim, day) + return year, month, day def _check_time_fields(hour, minute, second, microsecond): - for value in [hour, minute, second, microsecond]: - if not isinstance(value, (int, long)): - raise TypeError('int expected') + hour = _check_int_field(hour) + minute = _check_int_field(minute) + second = _check_int_field(second) + microsecond = _check_int_field(microsecond) if not 0 <= hour <= 23: raise ValueError('hour must be in 0..23', hour) if not 0 <= minute <= 59: @@ -294,6 +302,7 @@ raise ValueError('second must be in 0..59', second) if not 0 <= microsecond <= 999999: raise ValueError('microsecond must be in 0..999999', microsecond) + return hour, minute, second, microsecond def _check_tzinfo_arg(tz): if tz is not None and not isinstance(tz, tzinfo): @@ -768,7 +777,7 @@ self = object.__new__(cls) self.__setstate(year) return self - _check_date_fields(year, month, day) + year, month, day = _check_date_fields(year, month, day) self = object.__new__(cls) self._year = year self._month = month @@ -889,7 +898,7 @@ month = self._month if day is None: day = self._day - _check_date_fields(year, month, day) + year, month, day = _check_date_fields(year, month, day) return date(year, month, day) # Comparisons of date objects with other. @@ -1150,13 +1159,14 @@ second, microsecond (default to zero) tzinfo (default to None) """ - self = object.__new__(cls) if isinstance(hour, str): # Pickle support + self = object.__new__(cls) self.__setstate(hour, minute or None) return self + hour, minute, second, microsecond = _check_time_fields(hour, minute, second, microsecond) _check_tzinfo_arg(tzinfo) - _check_time_fields(hour, minute, second, microsecond) + self = object.__new__(cls) self._hour = hour self._minute = minute self._second = second @@ -1387,7 +1397,7 @@ microsecond = self.microsecond if tzinfo is True: tzinfo = self.tzinfo - _check_time_fields(hour, minute, second, microsecond) + hour, minute, second, microsecond = _check_time_fields(hour, minute, second, microsecond) _check_tzinfo_arg(tzinfo) return time(hour, minute, second, microsecond, tzinfo) @@ -1449,10 +1459,10 @@ self = date.__new__(cls, year[:4]) self.__setstate(year, month) return self + year, month, day = _check_date_fields(year, month, day) + hour, minute, second, microsecond = _check_time_fields(hour, minute, second, microsecond) _check_tzinfo_arg(tzinfo) - _check_time_fields(hour, minute, second, microsecond) - self = date.__new__(cls, year, month, day) - # XXX This duplicates __year, __month, __day for convenience :-( + self = object.__new__(cls) self._year = year self._month = month self._day = day @@ -1617,8 +1627,8 @@ microsecond = self.microsecond if tzinfo is True: tzinfo = self.tzinfo - _check_date_fields(year, month, day) - _check_time_fields(hour, minute, second, microsecond) + year, month, day = _check_date_fields(year, month, day) + hour, minute, second, microsecond = _check_time_fields(hour, minute, second, microsecond) _check_tzinfo_arg(tzinfo) return datetime(year, month, day, hour, minute, second, microsecond, tzinfo) diff --git a/lib_pypy/greenlet.py b/lib_pypy/greenlet.py --- a/lib_pypy/greenlet.py +++ b/lib_pypy/greenlet.py @@ -1,5 +1,6 @@ import _continuation, sys +__version__ = "0.4.0" # ____________________________________________________________ # Exceptions @@ -57,7 +58,8 @@ def __switch(target, methodname, *args): current = getcurrent() # - while not target: + while not (target.__main or _continulet.is_pending(target)): + # inlined __nonzero__ ^^^ in case it's overridden if not target.__started: if methodname == 'switch': greenlet_func = _greenlet_start diff --git a/lib_pypy/pypy_test/test_cPickle.py b/lib_pypy/pypy_test/test_cPickle.py new file mode 100644 --- /dev/null +++ b/lib_pypy/pypy_test/test_cPickle.py @@ -0,0 +1,7 @@ +from __future__ import absolute_import +import py + +from lib_pypy import cPickle + +def test_stack_underflow(): + py.test.raises(cPickle.UnpicklingError, cPickle.loads, "a string") diff --git a/lib_pypy/pypy_test/test_collections.py b/lib_pypy/pypy_test/test_collections.py --- a/lib_pypy/pypy_test/test_collections.py +++ b/lib_pypy/pypy_test/test_collections.py @@ -16,6 +16,17 @@ d = collections.deque([MutatingCmp()]) py.test.raises(IndexError, d.remove, 1) + def test_remove_failing(self): + class FailingCmp(object): + def __eq__(self, other): + assert False + + f = FailingCmp() + d = collections.deque([1, 2, 3, f, 4, 5]) + d.remove(3) + py.test.raises(AssertionError, d.remove, 4) + assert d == collections.deque([1, 2, f, 4, 5]) + def test_maxlen(self): d = collections.deque([], 3) d.append(1); d.append(2); d.append(3); d.append(4) diff --git a/lib_pypy/pyrepl/unix_console.py b/lib_pypy/pyrepl/unix_console.py --- a/lib_pypy/pyrepl/unix_console.py +++ b/lib_pypy/pyrepl/unix_console.py @@ -398,6 +398,7 @@ if hasattr(self, 'old_sigwinch'): signal.signal(signal.SIGWINCH, self.old_sigwinch) + del self.old_sigwinch def __sigwinch(self, signum, frame): self.height, self.width = self.getheightwidth() diff --git a/pypy/conftest.py b/pypy/conftest.py --- a/pypy/conftest.py +++ b/pypy/conftest.py @@ -84,10 +84,11 @@ if self.config.option.runappdirect: # only collect regular tests if we are in an 'app_test' directory, # or in test_lib_pypy - names = self.listnames() - return "app_test" in names or "test_lib_pypy" in names - else: - return True + for name in self.listnames(): + if "app_test" in name or "test_lib_pypy" in name: + return True + return False + return True def funcnamefilter(self, name): if name.startswith('test_'): diff --git a/pypy/doc/arm.rst b/pypy/doc/arm.rst --- a/pypy/doc/arm.rst +++ b/pypy/doc/arm.rst @@ -145,7 +145,7 @@ :: - pypy ~/path_to_pypy_checkout/pypy/translator/goal/translate.py -O1 --platform=arm target.py + pypy ~/path_to_pypy_checkout/rpython/translator/goal/translate.py -O1 --platform=arm target.py If everything worked correctly this should yield an ARM binary. Running this binary in the ARM chroot or on an ARM device should produce the output ``"Hello World"``. diff --git a/pypy/doc/cppyy.rst b/pypy/doc/cppyy.rst --- a/pypy/doc/cppyy.rst +++ b/pypy/doc/cppyy.rst @@ -86,10 +86,10 @@ $ hg clone https://bitbucket.org/pypy/pypy $ cd pypy $ hg up reflex-support # optional - $ cd pypy/translator/goal + $ cd pypy/goal # This example shows python, but using pypy-c is faster and uses less memory - $ python translate.py -O jit --gcrootfinder=shadowstack targetpypystandalone.py --withmod-cppyy + $ python ../../rpython/bin/rpython.py -O jit --gcrootfinder=shadowstack targetpypystandalone.py --withmod-cppyy This will build a ``pypy-c`` that includes the cppyy module, and through that, Reflex support. diff --git a/pypy/doc/ctypes-implementation.rst b/pypy/doc/ctypes-implementation.rst --- a/pypy/doc/ctypes-implementation.rst +++ b/pypy/doc/ctypes-implementation.rst @@ -113,7 +113,7 @@ The pypy-c translated to run the ctypes tests can be used to run the pyglet examples as well. They can be run like e.g.:: $ cd pyglet/ - $ PYTHONPATH=. ../ctypes-stable/pypy/translator/goal/pypy-c examples/opengl.py + $ PYTHONPATH=. ../ctypes-stable/pypy/goal/pypy-c examples/opengl.py they usually should be terminated with ctrl-c. Refer to the their doc strings for details about how they should behave. diff --git a/pypy/doc/getting-started-dev.rst b/pypy/doc/getting-started-dev.rst --- a/pypy/doc/getting-started-dev.rst +++ b/pypy/doc/getting-started-dev.rst @@ -24,7 +24,7 @@ python bin/translatorshell.py Test snippets of translatable code are provided in the file -``pypy/translator/test/snippet.py``, which is imported under the name +``rpython/translator/test/snippet.py``, which is imported under the name ``snippet``. For example:: >>> t = Translation(snippet.is_perfect_number, [int]) @@ -52,16 +52,18 @@ The graph can be turned into C code:: >>> t.rtype() - >>> f = t.compile_c() + >>> lib = t.compile_c() The first command replaces the operations with other low level versions that -only use low level types that are available in C (e.g. int). To try out the -compiled version:: +only use low level types that are available in C (e.g. int). The compiled +version is now in a ``.so`` library. You can run it say using ctypes: + >>> from ctypes import CDLL + >>> f = CDLL(lib) >>> f(5) - False + 0 >>> f(6) - True + 1 Translating the flow graph to CLI or JVM code +++++++++++++++++++++++++++++++++++++++++++++ @@ -108,7 +110,7 @@ There is a small-to-medium demo showing the translator and the annotator:: cd demo - ../pypy/translator/goal/translate.py --view --annotate bpnn.py + ../rpython/translator/goal/translate.py --view --annotate bpnn.py This causes ``bpnn.py`` to display itself as a call graph and class hierarchy. Clicking on functions shows the flow graph of the particular @@ -119,17 +121,17 @@ To turn this example to C code (compiled to the executable ``bpnn-c``), type simply:: - ../pypy/translator/goal/translate.py bpnn.py + ../rpython/translator/goal/translate.py bpnn.py Translating Full Programs +++++++++++++++++++++++++ To translate full RPython programs, there is the script ``translate.py`` in -``translator/goal``. Examples for this are a slightly changed version of +``rpython/translator/goal``. Examples for this are a slightly changed version of Pystone:: - cd pypy/translator/goal + cd rpython/translator/goal python translate.py targetrpystonedalone This will produce the executable "targetrpystonedalone-c". diff --git a/pypy/doc/index.rst b/pypy/doc/index.rst --- a/pypy/doc/index.rst +++ b/pypy/doc/index.rst @@ -220,9 +220,8 @@ ================================ =========================================== Directory explanation/links ================================ =========================================== -`pypy/annotation/`_ `type inferencing code`_ for `RPython`_ programs -`pypy/bin/`_ command-line scripts, mainly `py.py`_ and `translatorshell.py`_ +`pypy/bin/`_ command-line scripts, mainly `pyinteractive.py`_ `pypy/config/`_ handles the numerous options for building and running PyPy @@ -249,20 +248,8 @@ `pypy/objspace/`_ `object space`_ implementations -`pypy/objspace/flow/`_ the FlowObjSpace_ implementing `abstract interpretation`_ - `pypy/objspace/std/`_ the StdObjSpace_ implementing CPython's objects and types -`pypy/rlib/`_ a `"standard library"`_ for RPython_ programs - -`pypy/rpython/`_ the `RPython Typer`_ - -`pypy/rpython/lltypesystem/`_ the `low-level type system`_ for C-like backends - -`pypy/rpython/ootypesystem/`_ the `object-oriented type system`_ for OO backends - -`pypy/rpython/memory/`_ the `garbage collector`_ construction framework - `pypy/tool/`_ various utilities and hacks used from various places `pypy/tool/algo/`_ general-purpose algorithmic and mathematic @@ -270,20 +257,39 @@ `pypy/tool/pytest/`_ support code for our `testing methods`_ -`pypy/translator/`_ translation_ backends and support code -`pypy/translator/backendopt/`_ general optimizations that run before a backend generates code +`rpython/annotator/`_ `type inferencing code`_ for `RPython`_ programs -`pypy/translator/c/`_ the `GenC backend`_, producing C code from an +`rpython/config/`_ handles the numerous options for RPython + + +`rpython/flowspace/`_ the FlowObjSpace_ implementing `abstract interpretation`_ + + +`rpython/rlib/`_ a `"standard library"`_ for RPython_ programs + +`rpython/rtyper/`_ the `RPython Typer`_ + +`rpython/rtyper/lltypesystem/`_ the `low-level type system`_ for C-like backends + +`rpython/rtyper/ootypesystem/`_ the `object-oriented type system`_ for OO backends + +`rpython/rtyper/memory/`_ the `garbage collector`_ construction framework + +`rpython/translator/`_ translation_ backends and support code + +`rpython/translator/backendopt/`_ general optimizations that run before a backend generates code + +`rpython/translator/c/`_ the `GenC backend`_, producing C code from an RPython program (generally via the rtyper_) -`pypy/translator/cli/`_ the `CLI backend`_ for `.NET`_ (Microsoft CLR or Mono_) +`rpython/translator/cli/`_ the `CLI backend`_ for `.NET`_ (Microsoft CLR or Mono_) -`pypy/translator/goal/`_ our `main PyPy-translation scripts`_ live here +`pypy/goal/`_ our `main PyPy-translation scripts`_ live here -`pypy/translator/jvm/`_ the Java backend +`rpython/translator/jvm/`_ the Java backend -`pypy/translator/tool/`_ helper tools for translation, including the Pygame +`rpython/translator/tool/`_ helper tools for translation, including the Pygame `graph viewer`_ ``*/test/`` many directories have a test subdirectory containing test diff --git a/pypy/doc/sandbox.rst b/pypy/doc/sandbox.rst --- a/pypy/doc/sandbox.rst +++ b/pypy/doc/sandbox.rst @@ -87,15 +87,15 @@ ----- -In pypy/translator/goal:: +In pypy/goal:: - ./translate.py -O2 --sandbox targetpypystandalone.py + ../../rpython/bin/rpython -O2 --sandbox targetpypystandalone.py If you don't have a regular PyPy installed, you should, because it's faster to translate, but you can also run ``python translate.py`` instead. -To run it, use the tools in the pypy/translator/sandbox directory:: +To run it, use the tools in the pypy/sandbox directory:: ./pypy_interact.py /some/path/pypy-c-sandbox [args...] diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst --- a/pypy/doc/whatsnew-head.rst +++ b/pypy/doc/whatsnew-head.rst @@ -37,6 +37,7 @@ .. branch: fix-e4fa0b2 .. branch: win32-fixes .. branch: fix-version-tool +.. branch: popen2-removal .. branch: release-2.0-beta1 @@ -50,3 +51,6 @@ .. branch: inline-virtualref-2 Better optimized certain types of frame accesses in the JIT, particularly around exceptions that escape the function they were raised in. + +.. branch: missing-ndarray-attributes +Some missing attributes from ndarrays diff --git a/pypy/interpreter/app_main.py b/pypy/interpreter/app_main.py --- a/pypy/interpreter/app_main.py +++ b/pypy/interpreter/app_main.py @@ -436,11 +436,14 @@ # (relevant in case of "reload(sys)") sys.argv[:] = argv - if PYTHON26 and not options["ignore_environment"]: - if os.getenv('PYTHONNOUSERSITE'): - options["no_user_site"] = 1 - if os.getenv('PYTHONDONTWRITEBYTECODE'): - options["dont_write_bytecode"] = 1 + if not options["ignore_environment"]: + if os.getenv('PYTHONUNBUFFERED'): + options["unbuffered"] = 1 + if PYTHON26: + if os.getenv('PYTHONNOUSERSITE'): + options["no_user_site"] = 1 + if os.getenv('PYTHONDONTWRITEBYTECODE'): + options["dont_write_bytecode"] = 1 if (options["interactive"] or (not options["ignore_environment"] and os.getenv('PYTHONINSPECT'))): @@ -716,7 +719,7 @@ root = dn(dn(dn(thisfile))) return [join(root, 'lib-python', '2.7'), join(root, 'lib_pypy')] - + def pypy_resolvedirof(s): # we ignore the issue of symlinks; for tests, the executable is always # interpreter/app_main.py anyway @@ -756,6 +759,10 @@ del os # make sure that os is not available globally, because this is what # happens in "real life" outside the tests + if 'time' not in sys.builtin_module_names: + # make some tests happy by loading this before we clobber sys.path + import time; del time + # no one should change to which lists sys.argv and sys.path are bound old_argv = sys.argv old_path = sys.path diff --git a/pypy/interpreter/test2/test_app_main.py b/pypy/interpreter/test2/test_app_main.py --- a/pypy/interpreter/test2/test_app_main.py +++ b/pypy/interpreter/test2/test_app_main.py @@ -712,6 +712,26 @@ assert data == '\x00(STDOUT)\n\x00' # from stdout child_out_err.close() + def test_non_interactive_stdout_unbuffered(self, monkeypatch): + monkeypatch.setenv('PYTHONUNBUFFERED', '1') + path = getscript(r""" + import sys, time + sys.stdout.write('\x00(STDOUT)\n\x00') + time.sleep(1) + sys.stderr.write('\x00[STDERR]\n\x00') + time.sleep(1) + # stdout flushed automatically here + """) + cmdline = '%s -E "%s" %s' % (sys.executable, app_main, path) + print 'POPEN:', cmdline + child_in, child_out_err = os.popen4(cmdline) + data = child_out_err.read(11) + assert data == '\x00(STDOUT)\n\x00' # from stderr + data = child_out_err.read(11) + assert data == '\x00[STDERR]\n\x00' # from stdout + child_out_err.close() + child_in.close() + def test_proper_sys_path(self, tmpdir): data = self.run('-c "import _ctypes"', python_flags='-S') if data.startswith('Traceback'): diff --git a/pypy/module/__pypy__/__init__.py b/pypy/module/__pypy__/__init__.py --- a/pypy/module/__pypy__/__init__.py +++ b/pypy/module/__pypy__/__init__.py @@ -14,7 +14,7 @@ class TimeModule(MixedModule): appleveldefs = {} interpleveldefs = {} - if sys.platform.startswith("linux"): + if sys.platform.startswith("linux") or 'bsd' in sys.platform: from pypy.module.__pypy__ import interp_time interpleveldefs["clock_gettime"] = "interp_time.clock_gettime" interpleveldefs["clock_getres"] = "interp_time.clock_getres" diff --git a/pypy/module/_cffi_backend/cbuffer.py b/pypy/module/_cffi_backend/cbuffer.py --- a/pypy/module/_cffi_backend/cbuffer.py +++ b/pypy/module/_cffi_backend/cbuffer.py @@ -2,7 +2,7 @@ from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.buffer import RWBuffer from pypy.interpreter.gateway import unwrap_spec, interp2app -from pypy.interpreter.typedef import TypeDef +from pypy.interpreter.typedef import TypeDef, make_weakref_descr from rpython.rtyper.lltypesystem import rffi from pypy.module._cffi_backend import cdataobj, ctypeptr, ctypearray @@ -41,8 +41,9 @@ # a different subclass of Wrappable for the MiniBuffer, because we # want a slightly different (simplified) API at the level of Python. - def __init__(self, buffer): + def __init__(self, buffer, keepalive=None): self.buffer = buffer + self.keepalive = keepalive def descr_len(self, space): return self.buffer.descr_len(space) @@ -65,6 +66,7 @@ __getitem__ = interp2app(MiniBuffer.descr_getitem), __setitem__ = interp2app(MiniBuffer.descr_setitem), __buffer__ = interp2app(MiniBuffer.descr__buffer__), + __weakref__ = make_weakref_descr(MiniBuffer), ) MiniBuffer.typedef.acceptable_as_base_class = False @@ -86,4 +88,4 @@ raise operationerrfmt(space.w_TypeError, "don't know the size pointed to by '%s'", ctype.name) - return space.wrap(MiniBuffer(LLBuffer(cdata._cdata, size))) + return space.wrap(MiniBuffer(LLBuffer(cdata._cdata, size), cdata)) diff --git a/pypy/module/_cffi_backend/ctypeptr.py b/pypy/module/_cffi_backend/ctypeptr.py --- a/pypy/module/_cffi_backend/ctypeptr.py +++ b/pypy/module/_cffi_backend/ctypeptr.py @@ -252,7 +252,10 @@ def _prepare_pointer_call_argument(self, w_init, cdata): space = self.space - if (space.isinstance_w(w_init, space.w_list) or + if space.is_w(w_init, space.w_None): + rffi.cast(rffi.CCHARPP, cdata)[0] = lltype.nullptr(rffi.CCHARP.TO) + return 3 + elif (space.isinstance_w(w_init, space.w_list) or space.isinstance_w(w_init, space.w_tuple)): length = space.int_w(space.len(w_init)) elif space.isinstance_w(w_init, space.w_basestring): diff --git a/pypy/module/_cffi_backend/test/_backend_test_c.py b/pypy/module/_cffi_backend/test/_backend_test_c.py --- a/pypy/module/_cffi_backend/test/_backend_test_c.py +++ b/pypy/module/_cffi_backend/test/_backend_test_c.py @@ -12,6 +12,7 @@ return eval('u'+repr(other).replace(r'\\u', r'\u') .replace(r'\\U', r'\U')) u = U() + str2bytes = str else: type_or_class = "class" long = int @@ -22,6 +23,7 @@ bytechr = lambda n: bytes([n]) bitem2bchr = bytechr u = "" + str2bytes = lambda s: bytes(s, "ascii") def size_of_int(): BInt = new_primitive_type("int") @@ -996,6 +998,8 @@ f = cast(BFunc23, _testfunc(23)) res = f(b"foo") assert res == 1000 * ord(b'f') + res = f(None) + assert res == -42 def test_call_function_23_bis(): # declaring the function as int(unsigned char*) @@ -1438,10 +1442,16 @@ import _weakref BInt = new_primitive_type("int") BPtr = new_pointer_type(BInt) - _weakref.ref(BInt) - _weakref.ref(newp(BPtr, 42)) - _weakref.ref(cast(BPtr, 42)) - _weakref.ref(cast(BInt, 42)) + rlist = [_weakref.ref(BInt), + _weakref.ref(newp(BPtr, 42)), + _weakref.ref(cast(BPtr, 42)), + _weakref.ref(cast(BInt, 42)), + _weakref.ref(buffer(newp(BPtr, 42))), + ] + for i in range(5): + import gc; gc.collect() + if [r() for r in rlist] == [None for r in rlist]: + break def test_no_inheritance(): BInt = new_primitive_type("int") @@ -2544,3 +2554,15 @@ BCharP = new_pointer_type(new_primitive_type("char")) BCharArray = new_array_type(BCharP, None) py.test.raises(TypeError, newp, BCharArray, u+'foobar') + +def test_buffer_keepalive(): + BCharP = new_pointer_type(new_primitive_type("char")) + BCharArray = new_array_type(BCharP, None) + buflist = [] + for i in range(20): + c = newp(BCharArray, str2bytes("hi there %d" % i)) + buflist.append(buffer(c)) + import gc; gc.collect() + for i in range(20): + buf = buflist[i] + assert buf[:] == str2bytes("hi there %d\x00" % i) diff --git a/pypy/module/_cffi_backend/test/_test_lib.c b/pypy/module/_cffi_backend/test/_test_lib.c --- a/pypy/module/_cffi_backend/test/_test_lib.c +++ b/pypy/module/_cffi_backend/test/_test_lib.c @@ -174,7 +174,9 @@ static int _testfunc23(char *p) { - return 1000 * p[0]; + if (p) + return 1000 * p[0]; + return -42; } DLLEXPORT void *gettestfunc(int num) diff --git a/pypy/module/_multibytecodec/c_codecs.py b/pypy/module/_multibytecodec/c_codecs.py --- a/pypy/module/_multibytecodec/c_codecs.py +++ b/pypy/module/_multibytecodec/c_codecs.py @@ -62,7 +62,7 @@ "pypy_cjk_enc_init", "pypy_cjk_enc_free", "pypy_cjk_enc_chunk", "pypy_cjk_enc_reset", "pypy_cjk_enc_outbuf", "pypy_cjk_enc_outlen", "pypy_cjk_enc_inbuf_remaining", "pypy_cjk_enc_inbuf_consumed", - "pypy_cjk_enc_replace_on_error", + "pypy_cjk_enc_replace_on_error", "pypy_cjk_enc_getcodec", ] + ["pypy_cjkcodec_%s" % codec for codec in codecs], ) diff --git a/pypy/module/bz2/test/test_bz2_compdecomp.py b/pypy/module/bz2/test/test_bz2_compdecomp.py --- a/pypy/module/bz2/test/test_bz2_compdecomp.py +++ b/pypy/module/bz2/test/test_bz2_compdecomp.py @@ -12,7 +12,7 @@ if os.name == "nt": from py.test import skip skip("bz2 module is not available on Windows") - + def setup_module(mod): DATA = 'BZh91AY&SY.\xc8N\x18\x00\x01>_\x80\x00\x10@\x02\xff\xf0\x01\x07n\x00?\xe7\xff\xe00\x01\x99\xaa\x00\xc0\x03F\x86\x8c#&\x83F\x9a\x03\x06\xa6\xd0\xa6\x93M\x0fQ\xa7\xa8\x06\x804hh\x12$\x11\xa4i4\xf14S\xd2\x88\xe5\xcd9gd6\x0b\n\xe9\x9b\xd5\x8a\x99\xf7\x08.K\x8ev\xfb\xf7xw\xbb\xdf\xa1\x92\xf1\xdd|/";\xa2\xba\x9f\xd5\xb1#A\xb6\xf6\xb3o\xc9\xc5y\\\xebO\xe7\x85\x9a\xbc\xb6f8\x952\xd5\xd7"%\x89>V,\xf7\xa6z\xe2\x9f\xa3\xdf\x11\x11"\xd6E)I\xa9\x13^\xca\xf3r\xd0\x03U\x922\xf26\xec\xb6\xed\x8b\xc3U\x13\x9d\xc5\x170\xa4\xfa^\x92\xacDF\x8a\x97\xd6\x19\xfe\xdd\xb8\xbd\x1a\x9a\x19\xa3\x80ankR\x8b\xe5\xd83]\xa9\xc6\x08\x82f\xf6\xb9"6l$\xb8j@\xc0\x8a\xb0l1..\xbak\x83ls\x15\xbc\xf4\xc1\x13\xbe\xf8E\xb8\x9d\r\xa8\x9dk\x84\xd3n\xfa\xacQ\x07\xb1%y\xaav\xb4\x08\xe0z\x1b\x16\xf5\x04\xe9\xcc\xb9\x08z\x1en7.G\xfc]\xc9\x14\xe1B@\xbb!8`' @@ -54,27 +54,27 @@ def test_creation(self): from bz2 import BZ2Compressor - + raises(TypeError, BZ2Compressor, "foo") raises(ValueError, BZ2Compressor, 10) - + BZ2Compressor(1) BZ2Compressor(9) - + def test_compress(self): from bz2 import BZ2Compressor - + bz2c = BZ2Compressor() raises(TypeError, bz2c.compress) data = bz2c.compress(self.TEXT) data = "%s%s" % (data, bz2c.flush()) assert self.decompress(data) == self.TEXT - + def test_compress_huge_data(self): if not self.HUGE_OK: skip("skipping test requiring lots of memory") - from bz2 import BZ2Compressor - + from bz2 import BZ2Compressor + HUGE_DATA = self.TEXT * 10000 bz2c = BZ2Compressor() raises(TypeError, bz2c.compress) @@ -83,8 +83,8 @@ assert self.decompress(data) == HUGE_DATA def test_compress_chunks_10(self): - from bz2 import BZ2Compressor - + from bz2 import BZ2Compressor + bz2c = BZ2Compressor() n = 0 data = "" @@ -112,23 +112,23 @@ cls.w_TEXT = cls.space.wrap(TEXT) cls.w_DATA = cls.space.wrap(DATA) cls.w_BUGGY_DATA = cls.space.wrap(BUGGY_DATA) - + def test_creation(self): from bz2 import BZ2Decompressor - + raises(TypeError, BZ2Decompressor, "foo") - + BZ2Decompressor() - + def test_attribute(self): from bz2 import BZ2Decompressor - + bz2d = BZ2Decompressor() assert bz2d.unused_data == "" def test_decompress(self): from bz2 import BZ2Decompressor - + bz2d = BZ2Decompressor() raises(TypeError, bz2d.decompress) decompressed_data = bz2d.decompress(self.DATA) @@ -136,7 +136,7 @@ def test_decompress_chunks_10(self): from bz2 import BZ2Decompressor - + bz2d = BZ2Decompressor() decompressed_data = "" n = 0 @@ -146,13 +146,13 @@ break decompressed_data = "%s%s" % (decompressed_data, bz2d.decompress(temp)) n += 1 - + assert decompressed_data == self.TEXT - + def test_decompress_unused_data(self): # test with unused data. (data after EOF) from bz2 import BZ2Decompressor - + bz2d = BZ2Decompressor() unused_data = "this is unused data" decompressed_data = bz2d.decompress(self.DATA + unused_data) @@ -161,7 +161,7 @@ def test_EOF_error(self): from bz2 import BZ2Decompressor - + bz2d = BZ2Decompressor() bz2d.decompress(self.DATA) raises(EOFError, bz2d.decompress, "foo") @@ -195,11 +195,11 @@ def test_compress_function(self): from bz2 import compress - + raises(TypeError, compress, 123) raises(ValueError, compress, "foo", 10) raises(TypeError, compress, "foo", "foo") - + data = compress(self.TEXT) assert self.decompress(data) == self.TEXT @@ -207,7 +207,7 @@ if not self.HUGE_OK: skip("skipping test requiring lots of memory") from bz2 import compress - + HUGE_DATA = self.TEXT * 10000 data = compress(HUGE_DATA) @@ -215,7 +215,7 @@ def test_decompress_function(self): import bz2 - + raises(TypeError, bz2.decompress) assert bz2.decompress("") == "" decompressed_data = bz2.decompress(self.DATA) diff --git a/pypy/module/bz2/test/test_bz2_file.py b/pypy/module/bz2/test/test_bz2_file.py --- a/pypy/module/bz2/test/test_bz2_file.py +++ b/pypy/module/bz2/test/test_bz2_file.py @@ -6,6 +6,7 @@ import py from pypy.interpreter.gateway import unwrap_spec, interp2app +from pypy.module.bz2.test.support import CheckAllocation if os.name == "nt": @@ -50,10 +51,7 @@ mod.RANDOM_DATA = ''.join([s[int(random.random() * len(s))] for i in range(30000)]) -class AppTestBZ2File: #(CheckAllocation): - # XXX for unknown reasons, we cannot do allocation checks, as sth is - # keeping those objects alive (BZ2File objects) - +class AppTestBZ2File(CheckAllocation): spaceconfig = { "usemodules": ["bz2", "binascii", "rctime"] } @@ -85,15 +83,15 @@ assert bz2f.closed == False bz2f.close() assert bz2f.closed == True - + def test_creation(self): from bz2 import BZ2File - + raises(ValueError, BZ2File, self.temppath, mode='w', compresslevel=10) raises(ValueError, BZ2File, self.temppath, mode='XYZ') # XXX the following is fine, currently: #raises(ValueError, BZ2File, self.temppath, mode='ww') - + BZ2File(self.temppath, mode='wU', buffering=0, compresslevel=8) BZ2File(self.temppath, mode='wb') # a large buf size @@ -101,50 +99,50 @@ def test_close(self): from bz2 import BZ2File - + # writeonly bz2f = BZ2File(self.temppath, mode='w') bz2f.close() - # since we use fclose() internally you can't close it twice - # bz2f.close() - + bz2f.close() + # readonly bz2f = BZ2File(self.temppath, mode='r') bz2f.close() - + bz2f.close() + def test_tell(self): from bz2 import BZ2File - + bz2f = BZ2File(self.temppath, mode='w') bz2f.close() raises(ValueError, bz2f.tell) - + bz2f = BZ2File(self.temppath, mode='w') pos = bz2f.tell() bz2f.close() assert pos == 0 - + def test_seek(self): from bz2 import BZ2File - + # hack to create a foo file open(self.temppath, "w").close() - + # cannot seek if close bz2f = BZ2File(self.temppath, mode='r') bz2f.close() raises(ValueError, bz2f.seek, 0) - + # cannot seek if 'w' bz2f = BZ2File(self.temppath, mode='w') raises(IOError, bz2f.seek, 0) bz2f.close() - + bz2f = BZ2File(self.temppath, mode='r') raises(TypeError, bz2f.seek) raises(TypeError, bz2f.seek, "foo") raises(TypeError, bz2f.seek, 0, "foo") - + bz2f.seek(0) assert bz2f.tell() == 0 del bz2f # delete from this frame, which is captured in the traceback @@ -152,21 +150,21 @@ def test_open_close_del(self): from bz2 import BZ2File self.create_temp_file() - + for i in range(10): f = BZ2File(self.temppath) f.close() del f - + def test_open_non_existent(self): from bz2 import BZ2File raises(IOError, BZ2File, "/non/existent/path") - + def test_open_mode_U(self): # bug #1194181: bz2.BZ2File opened for write with mode "U" from bz2 import BZ2File self.create_temp_file() - + bz2f = BZ2File(self.temppath, "U") bz2f.close() f = open(self.temppath) @@ -174,7 +172,7 @@ f.read() assert f.tell() == len(self.DATA) f.close() - + def test_seek_forward(self): from bz2 import BZ2File self.create_temp_file() @@ -214,7 +212,7 @@ assert bz2f.tell() == len(self.TEXT) assert bz2f.read() == "" bz2f.close() - + def test_seek_post_end_twice(self): from bz2 import BZ2File self.create_temp_file() @@ -240,10 +238,9 @@ from bz2 import BZ2File from cStringIO import StringIO self.create_temp_file() - + bz2f = BZ2File(self.temppath) - # XXX - #raises(TypeError, bz2f.readline, None) + raises(TypeError, bz2f.readline, None) sio = StringIO(self.TEXT) for line in sio.readlines(): line_read = bz2f.readline() @@ -253,10 +250,9 @@ def test_read(self): from bz2 import BZ2File self.create_temp_file() - + bz2f = BZ2File(self.temppath) - # XXX - # raises(TypeError, bz2f.read, None) + raises(TypeError, bz2f.read, None) text_read = bz2f.read() assert text_read == self.TEXT bz2f.close() @@ -291,7 +287,7 @@ def test_read_chunk9(self): from bz2 import BZ2File self.create_temp_file() - + bz2f = BZ2File(self.temppath) text_read = "" while True: @@ -305,7 +301,7 @@ def test_read_100_bytes(self): from bz2 import BZ2File self.create_temp_file() - + bz2f = BZ2File(self.temppath) assert bz2f.read(100) == self.TEXT[:100] bz2f.close() @@ -313,7 +309,7 @@ def test_universal_newlines_lf(self): from bz2 import BZ2File self.create_temp_file() - + bz2f = BZ2File(self.temppath, "rU") assert bz2f.read() == self.TEXT assert bz2f.newlines == "\n" @@ -322,7 +318,7 @@ def test_universal_newlines_crlf(self): from bz2 import BZ2File self.create_temp_file(crlf=True) - + bz2f = BZ2File(self.temppath, "rU") data = bz2f.read() assert data == self.TEXT @@ -333,10 +329,9 @@ from bz2 import BZ2File from cStringIO import StringIO self.create_temp_file() - + bz2f = BZ2File(self.temppath) - # XXX - #raises(TypeError, bz2f.readlines, None) + raises(TypeError, bz2f.readlines, None) sio = StringIO(self.TEXT) assert bz2f.readlines() == sio.readlines() bz2f.close() @@ -345,17 +340,17 @@ from bz2 import BZ2File from cStringIO import StringIO self.create_temp_file() - + bz2f = BZ2File(self.temppath) sio = StringIO(self.TEXT) assert list(iter(bz2f)) == sio.readlines() bz2f.close() - + def test_xreadlines(self): from bz2 import BZ2File from cStringIO import StringIO self.create_temp_file() - + bz2f = BZ2File(self.temppath) sio = StringIO(self.TEXT) assert list(bz2f.xreadlines()) == sio.readlines() @@ -364,12 +359,12 @@ def test_readlines_bug_1191043(self): # readlines()/xreadlines() for files containing no newline from bz2 import BZ2File - + DATA = 'BZh91AY&SY\xd9b\x89]\x00\x00\x00\x03\x80\x04\x00\x02\x00\x0c\x00 \x00!\x9ah3M\x13<]\xc9\x14\xe1BCe\x8a%t' f = open(self.temppath, "wb") f.write(DATA) f.close() - + bz2f = BZ2File(self.temppath) lines = bz2f.readlines() bz2f.close() @@ -379,7 +374,7 @@ xlines = list(bz2f.xreadlines()) bz2f.close() assert xlines == ['Test'] - + def test_write(self): from bz2 import BZ2File @@ -387,7 +382,7 @@ raises(TypeError, bz2f.write) bz2f.write(self.TEXT) bz2f.close() - + f = open(self.temppath, "rb") assert self.decompress(f.read()) == self.TEXT f.close() @@ -401,11 +396,11 @@ data = self.TEXT[n * 10:(n + 1) * 10] if not data: break - + bz2f.write(data) n += 1 bz2f.close() - + f = open(self.temppath, "rb") assert self.decompress(f.read()) == self.TEXT f.close() @@ -422,7 +417,7 @@ f = open(self.temppath, "rb") assert self.decompress(f.read()) == self.TEXT f.close() - + def test_write_methods_on_readonly_file(self): from bz2 import BZ2File @@ -453,8 +448,8 @@ assert data == "abc" assert f.closed - - + + # has_cmdline_bunzip2 = sys.platform not in ("win32", "os2emx", "riscos") # # if has_cmdline_bunzip2: diff --git a/pypy/module/imp/__init__.py b/pypy/module/imp/__init__.py --- a/pypy/module/imp/__init__.py +++ b/pypy/module/imp/__init__.py @@ -6,12 +6,14 @@ __import__ function. """ interpleveldefs = { + 'SEARCH_ERROR': 'space.wrap(importing.SEARCH_ERROR)', 'PY_SOURCE': 'space.wrap(importing.PY_SOURCE)', 'PY_COMPILED': 'space.wrap(importing.PY_COMPILED)', 'C_EXTENSION': 'space.wrap(importing.C_EXTENSION)', 'PKG_DIRECTORY': 'space.wrap(importing.PKG_DIRECTORY)', 'C_BUILTIN': 'space.wrap(importing.C_BUILTIN)', 'PY_FROZEN': 'space.wrap(importing.PY_FROZEN)', + 'IMP_HOOK': 'space.wrap(importing.IMP_HOOK)', 'get_suffixes': 'interp_imp.get_suffixes', 'get_magic': 'interp_imp.get_magic', diff --git a/pypy/module/micronumpy/__init__.py b/pypy/module/micronumpy/__init__.py --- a/pypy/module/micronumpy/__init__.py +++ b/pypy/module/micronumpy/__init__.py @@ -27,6 +27,9 @@ 'True_': 'types.Bool.True', 'False_': 'types.Bool.False', + 'bool': 'space.w_bool', + 'int': 'space.w_int', + 'typeinfo': 'interp_dtype.get_dtype_cache(space).w_typeinfo', 'generic': 'interp_boxes.W_GenericBox', diff --git a/pypy/module/micronumpy/arrayimpl/base.py b/pypy/module/micronumpy/arrayimpl/base.py --- a/pypy/module/micronumpy/arrayimpl/base.py +++ b/pypy/module/micronumpy/arrayimpl/base.py @@ -3,6 +3,12 @@ def is_scalar(self): return False + def base(self): + raise NotImplementedError + + def create_iter(self, shape=None): + raise NotImplementedError + class BaseArrayIterator(object): def next(self): raise NotImplementedError # purely abstract base class diff --git a/pypy/module/micronumpy/arrayimpl/concrete.py b/pypy/module/micronumpy/arrayimpl/concrete.py --- a/pypy/module/micronumpy/arrayimpl/concrete.py +++ b/pypy/module/micronumpy/arrayimpl/concrete.py @@ -1,178 +1,20 @@ from pypy.module.micronumpy.arrayimpl import base -from pypy.module.micronumpy import support, loop +from pypy.module.micronumpy import support, loop, iter from pypy.module.micronumpy.base import convert_to_array, W_NDimArray,\ ArrayArgumentException from pypy.module.micronumpy.strides import calc_new_strides, shape_agreement,\ calculate_broadcast_strides, calculate_dot_strides from pypy.module.micronumpy.iter import Chunk, Chunks, NewAxisChunk, RecordChunk from pypy.interpreter.error import OperationError, operationerrfmt +from pypy.interpreter.buffer import RWBuffer +from rpython.rlib import jit from rpython.rtyper.lltypesystem import rffi, lltype -from rpython.rlib import jit -from rpython.rlib.rawstorage import free_raw_storage, RAW_STORAGE +from rpython.rlib.rawstorage import free_raw_storage, raw_storage_getitem,\ + raw_storage_setitem, RAW_STORAGE +from pypy.module.micronumpy.arrayimpl.sort import argsort_array from rpython.rlib.debug import make_sure_not_resized -class ConcreteArrayIterator(base.BaseArrayIterator): - _immutable_fields_ = ['dtype', 'skip', 'size'] - def __init__(self, array): - self.array = array - self.offset = 0 - self.dtype = array.dtype - self.skip = self.dtype.itemtype.get_element_size() - self.size = array.size - - def setitem(self, elem): - self.dtype.setitem(self.array, self.offset, elem) - - def getitem(self): - return self.dtype.getitem(self.array, self.offset) - - def getitem_bool(self): - return self.dtype.getitem_bool(self.array, self.offset) - - def next(self): - self.offset += self.skip - - def next_skip_x(self, x): - self.offset += self.skip * x - - def done(self): - return self.offset >= self.size - - def reset(self): - self.offset %= self.size - -class OneDimViewIterator(ConcreteArrayIterator): - ''' The view iterator dtype can be different from the - array.dtype, this is what makes it a View - ''' - def __init__(self, array, dtype, start, strides, shape): - self.array = array - self.dtype = dtype - self.offset = start - self.skip = strides[0] - self.index = 0 - self.size = shape[0] - - def next(self): - self.offset += self.skip - self.index += 1 - - def next_skip_x(self, x): - self.offset += self.skip * x - self.index += x - - def done(self): - return self.index >= self.size - - def reset(self): - self.offset %= self.size - -class MultiDimViewIterator(ConcreteArrayIterator): - ''' The view iterator dtype can be different from the - array.dtype, this is what makes it a View - ''' - def __init__(self, array, dtype, start, strides, backstrides, shape): - self.indexes = [0] * len(shape) - self.array = array - self.dtype = dtype - self.shape = shape - self.offset = start - self.shapelen = len(shape) - self._done = False - self.strides = strides - self.backstrides = backstrides - self.size = array.size - - @jit.unroll_safe - def next(self): - offset = self.offset - for i in range(self.shapelen - 1, -1, -1): - if self.indexes[i] < self.shape[i] - 1: - self.indexes[i] += 1 - offset += self.strides[i] - break - else: - self.indexes[i] = 0 - offset -= self.backstrides[i] - else: - self._done = True - self.offset = offset - - @jit.unroll_safe - def next_skip_x(self, step): - for i in range(len(self.shape) - 1, -1, -1): - if self.indexes[i] < self.shape[i] - step: - self.indexes[i] += step - self.offset += self.strides[i] * step - break - else: - remaining_step = (self.indexes[i] + step) // self.shape[i] - this_i_step = step - remaining_step * self.shape[i] - self.offset += self.strides[i] * this_i_step - self.indexes[i] = self.indexes[i] + this_i_step - step = remaining_step - else: - self._done = True - - def done(self): - return self._done - - def reset(self): - self.offset %= self.size - -class AxisIterator(base.BaseArrayIterator): - def __init__(self, array, shape, dim): - self.shape = shape - strides = array.get_strides() - backstrides = array.get_backstrides() - if len(shape) == len(strides): - # keepdims = True - self.strides = strides[:dim] + [0] + strides[dim + 1:] - self.backstrides = backstrides[:dim] + [0] + backstrides[dim + 1:] - else: - self.strides = strides[:dim] + [0] + strides[dim:] - self.backstrides = backstrides[:dim] + [0] + backstrides[dim:] - self.first_line = True - self.indices = [0] * len(shape) - self._done = False - self.offset = array.start - self.dim = dim - self.array = array - self.dtype = array.dtype - - def setitem(self, elem): - self.dtype.setitem(self.array, self.offset, elem) - - def getitem(self): - return self.dtype.getitem(self.array, self.offset) - - @jit.unroll_safe - def next(self): - for i in range(len(self.shape) - 1, -1, -1): - if self.indices[i] < self.shape[i] - 1: - if i == self.dim: - self.first_line = False - self.indices[i] += 1 - self.offset += self.strides[i] - break - else: - if i == self.dim: - self.first_line = True - self.indices[i] = 0 - self.offset -= self.backstrides[i] - else: - self._done = True - - def done(self): - return self._done - -def int_w(space, w_obj): - try: - return space.int_w(space.index(w_obj)) - except OperationError: - return space.int_w(space.int(w_obj)) - class BaseConcreteArray(base.BaseArrayImplementation): start = 0 parent = None @@ -213,7 +55,7 @@ def get_size(self): return self.size // self.dtype.itemtype.get_element_size() - def reshape(self, space, new_shape): + def reshape(self, space, orig_array, new_shape): # Since we got to here, prod(new_shape) == self.size new_strides = None if self.size > 0: @@ -226,31 +68,31 @@ for nd in range(ndims): new_backstrides[nd] = (new_shape[nd] - 1) * new_strides[nd] return SliceArray(self.start, new_strides, new_backstrides, - new_shape, self) + new_shape, self, orig_array) else: return None - def get_real(self): + def get_real(self, orig_array): strides = self.get_strides() backstrides = self.get_backstrides() if self.dtype.is_complex_type(): dtype = self.dtype.float_type return SliceArray(self.start, strides, backstrides, - self.get_shape(), self, dtype=dtype) + self.get_shape(), self, orig_array, dtype=dtype) return SliceArray(self.start, strides, backstrides, - self.get_shape(), self) + self.get_shape(), self, orig_array) - def get_imag(self): + def get_imag(self, orig_array): strides = self.get_strides() backstrides = self.get_backstrides() if self.dtype.is_complex_type(): dtype = self.dtype.float_type return SliceArray(self.start + dtype.get_size(), strides, - backstrides, self.get_shape(), self, dtype=dtype) + backstrides, self.get_shape(), self, orig_array, dtype=dtype) if self.dtype.is_flexible_type(): # numpy returns self for self.imag return SliceArray(self.start, strides, backstrides, - self.get_shape(), self) + self.get_shape(), self, orig_array) impl = NonWritableArray(self.get_shape(), self.dtype, self.order, strides, backstrides) impl.fill(self.dtype.box(0)) @@ -265,7 +107,7 @@ for i, w_index in enumerate(view_w): if space.isinstance_w(w_index, space.w_slice): raise IndexError - idx = int_w(space, w_index) + idx = support.int_w(space, w_index) if idx < 0: idx = self.get_shape()[i] + idx if idx < 0 or idx >= self.get_shape()[i]: @@ -339,7 +181,7 @@ return self._lookup_by_index(space, view_w) if shape_len > 1: raise IndexError - idx = int_w(space, w_idx) + idx = support.int_w(space, w_idx) return self._lookup_by_index(space, [space.wrap(idx)]) @jit.unroll_safe @@ -367,26 +209,26 @@ i += 1 return Chunks(result) - def descr_getitem(self, space, w_index): + def descr_getitem(self, space, orig_arr, w_index): try: item = self._single_item_index(space, w_index) return self.getitem(item) except IndexError: # not a single result chunks = self._prepare_slice_args(space, w_index) - return chunks.apply(self) + return chunks.apply(orig_arr) - def descr_setitem(self, space, w_index, w_value): + def descr_setitem(self, space, orig_arr, w_index, w_value): try: item = self._single_item_index(space, w_index) self.setitem(item, self.dtype.coerce(space, w_value)) except IndexError: w_value = convert_to_array(space, w_value) chunks = self._prepare_slice_args(space, w_index) - view = chunks.apply(self) + view = chunks.apply(orig_arr) view.implementation.setslice(space, w_value) - def transpose(self): + def transpose(self, orig_array): if len(self.get_shape()) < 2: return self strides = [] @@ -397,7 +239,7 @@ backstrides.append(self.get_backstrides()[i]) shape.append(self.get_shape()[i]) return SliceArray(self.start, strides, - backstrides, shape, self) + backstrides, shape, self, orig_array) def copy(self): strides, backstrides = support.calc_strides(self.get_shape(), self.dtype, @@ -406,15 +248,15 @@ backstrides) return loop.setslice(self.get_shape(), impl, self) - def create_axis_iter(self, shape, dim): - return AxisIterator(self, shape, dim) + def create_axis_iter(self, shape, dim, cum): + return iter.AxisIterator(self, shape, dim, cum) def create_dot_iter(self, shape, skip): r = calculate_dot_strides(self.get_strides(), self.get_backstrides(), shape, skip) - return MultiDimViewIterator(self, self.dtype, self.start, r[0], r[1], shape) + return iter.MultiDimViewIterator(self, self.dtype, self.start, r[0], r[1], shape) - def swapaxes(self, axis1, axis2): + def swapaxes(self, orig_arr, axis1, axis2): shape = self.get_shape()[:] strides = self.get_strides()[:] backstrides = self.get_backstrides()[:] @@ -422,13 +264,25 @@ strides[axis1], strides[axis2] = strides[axis2], strides[axis1] backstrides[axis1], backstrides[axis2] = backstrides[axis2], backstrides[axis1] return W_NDimArray.new_slice(self.start, strides, - backstrides, shape, self) + backstrides, shape, self, orig_arr) def get_storage_as_int(self, space): return rffi.cast(lltype.Signed, self.storage) + def get_storage(self): + return self.storage + + def get_buffer(self, space): + return ArrayBuffer(self) + + def astype(self, space, dtype): + new_arr = W_NDimArray.from_shape(self.get_shape(), dtype) + loop.copy_from_to(self, new_arr.implementation, dtype) + return new_arr + class ConcreteArrayNotOwning(BaseConcreteArray): def __init__(self, shape, dtype, order, strides, backstrides, storage): + make_sure_not_resized(shape) make_sure_not_resized(strides) make_sure_not_resized(backstrides) @@ -442,19 +296,26 @@ def create_iter(self, shape=None): if shape is None or shape == self.get_shape(): - return ConcreteArrayIterator(self) + return iter.ConcreteArrayIterator(self) r = calculate_broadcast_strides(self.get_strides(), self.get_backstrides(), self.get_shape(), shape) - return MultiDimViewIterator(self, self.dtype, 0, r[0], r[1], shape) + return iter.MultiDimViewIterator(self, self.dtype, 0, r[0], r[1], shape) def fill(self, box): self.dtype.fill(self.storage, box, 0, self.size) - def set_shape(self, space, new_shape): + def set_shape(self, space, orig_array, new_shape): strides, backstrides = support.calc_strides(new_shape, self.dtype, self.order) - return SliceArray(0, strides, backstrides, new_shape, self) + return SliceArray(0, strides, backstrides, new_shape, self, + orig_array) + + def argsort(self, space, w_axis): + return argsort_array(self, space, w_axis) + + def base(self): + return None class ConcreteArray(ConcreteArrayNotOwning): def __init__(self, shape, dtype, order, strides, backstrides): @@ -469,14 +330,17 @@ free_raw_storage(self.storage, track_allocation=False) + + class NonWritableArray(ConcreteArray): - def descr_setitem(self, space, w_index, w_value): + def descr_setitem(self, space, orig_array, w_index, w_value): raise OperationError(space.w_RuntimeError, space.wrap( "array is not writable")) class SliceArray(BaseConcreteArray): - def __init__(self, start, strides, backstrides, shape, parent, dtype=None): + def __init__(self, start, strides, backstrides, shape, parent, orig_arr, + dtype=None): self.strides = strides self.backstrides = backstrides self.shape = shape @@ -490,6 +354,10 @@ self.dtype = dtype self.size = support.product(shape) * self.dtype.itemtype.get_element_size() self.start = start + self.orig_arr = orig_arr + + def base(self): + return self.orig_arr def fill(self, box): loop.fill(self, box.convert_to(self.dtype)) @@ -499,16 +367,16 @@ r = calculate_broadcast_strides(self.get_strides(), self.get_backstrides(), self.get_shape(), shape) - return MultiDimViewIterator(self.parent, self.dtype, - self.start, r[0], r[1], shape) + return iter.MultiDimViewIterator(self.parent, self.dtype, + self.start, r[0], r[1], shape) if len(self.get_shape()) == 1: - return OneDimViewIterator(self.parent, self.dtype, self.start, + return iter.OneDimViewIterator(self.parent, self.dtype, self.start, self.get_strides(), self.get_shape()) - return MultiDimViewIterator(self.parent, self.dtype, self.start, + return iter.MultiDimViewIterator(self.parent, self.dtype, self.start, self.get_strides(), self.get_backstrides(), self.get_shape()) - def set_shape(self, space, new_shape): + def set_shape(self, space, orig_array, new_shape): if len(self.get_shape()) < 2 or self.size == 0: # TODO: this code could be refactored into calc_strides # but then calc_strides would have to accept a stepping factor @@ -527,7 +395,7 @@ backstrides.reverse() new_shape.reverse() return SliceArray(self.start, strides, backstrides, new_shape, - self) + self, orig_array) new_strides = calc_new_strides(new_shape, self.get_shape(), self.get_strides(), self.order) @@ -538,4 +406,18 @@ for nd in range(len(new_shape)): new_backstrides[nd] = (new_shape[nd] - 1) * new_strides[nd] return SliceArray(self.start, new_strides, new_backstrides, new_shape, - self) + self, orig_array) + +class ArrayBuffer(RWBuffer): + def __init__(self, impl): + self.impl = impl + + def getitem(self, item): + return raw_storage_getitem(lltype.Char, self.impl.storage, item) + + def setitem(self, item, v): + return raw_storage_setitem(self.impl.storage, item, + rffi.cast(lltype.Char, v)) + + def getlength(self): + return self.impl.size diff --git a/pypy/module/micronumpy/arrayimpl/scalar.py b/pypy/module/micronumpy/arrayimpl/scalar.py --- a/pypy/module/micronumpy/arrayimpl/scalar.py +++ b/pypy/module/micronumpy/arrayimpl/scalar.py @@ -7,18 +7,19 @@ class ScalarIterator(base.BaseArrayIterator): def __init__(self, v): self.v = v + self.called_once = False def next(self): - pass + self.called_once = True def getitem(self): - return self.v + return self.v.get_scalar_value() def setitem(self, v): - raise Exception("Don't call setitem on scalar iterators") + self.v.set_scalar_value(v) def done(self): - raise Exception("should not call done on scalar") + return self.called_once def reset(self): pass @@ -38,7 +39,7 @@ return [] def create_iter(self, shape=None): - return ScalarIterator(self.value) + return ScalarIterator(self) def get_scalar_value(self): return self.value @@ -54,10 +55,10 @@ def get_size(self): return 1 - def transpose(self): + def transpose(self, _): return self - def descr_getitem(self, space, w_idx): + def descr_getitem(self, space, _, w_idx): raise OperationError(space.w_IndexError, space.wrap("scalars cannot be indexed")) @@ -65,14 +66,14 @@ raise OperationError(space.w_IndexError, space.wrap("scalars cannot be indexed")) - def descr_setitem(self, space, w_idx, w_val): + def descr_setitem(self, space, _, w_idx, w_val): raise OperationError(space.w_IndexError, space.wrap("scalars cannot be indexed")) def setitem_index(self, space, idx, w_val): raise OperationError(space.w_IndexError, space.wrap("scalars cannot be indexed")) - def set_shape(self, space, new_shape): + def set_shape(self, space, orig_array, new_shape): if not new_shape: return self if support.product(new_shape) == 1: @@ -83,13 +84,13 @@ raise OperationError(space.w_ValueError, space.wrap( "total size of the array must be unchanged")) - def reshape(self, space, new_shape): - return self.set_shape(space, new_shape) + def reshape(self, space, orig_array, new_shape): + return self.set_shape(space, orig_array, new_shape) - def create_axis_iter(self, shape, dim): + def create_axis_iter(self, shape, dim, cum): raise Exception("axis iter should not happen on scalar") - def swapaxes(self, axis1, axis2): + def swapaxes(self, orig_array, axis1, axis2): raise Exception("should not be called") def fill(self, w_value): @@ -98,3 +99,17 @@ def get_storage_as_int(self, space): raise OperationError(space.w_ValueError, space.wrap("scalars have no address")) + + def argsort(self, space, w_axis): + return space.wrap(0) + + def astype(self, space, dtype): + return W_NDimArray.new_scalar(space, dtype, self.value) + + def base(self): + return None + + def get_buffer(self, space): + raise OperationError(space.w_ValueError, space.wrap( + "cannot point buffer to a scalar")) + diff --git a/pypy/module/micronumpy/arrayimpl/sort.py b/pypy/module/micronumpy/arrayimpl/sort.py new file mode 100644 --- /dev/null +++ b/pypy/module/micronumpy/arrayimpl/sort.py @@ -0,0 +1,195 @@ + +""" This is the implementation of various sorting routines in numpy. It's here +because it only makes sense on a concrete array +""" + +from rpython.rtyper.lltypesystem import rffi, lltype +from rpython.rlib.listsort import make_timsort_class +from rpython.rlib.rawstorage import raw_storage_getitem, raw_storage_setitem, \ + free_raw_storage, alloc_raw_storage +from rpython.rlib.unroll import unrolling_iterable +from rpython.rlib.rarithmetic import intmask +from rpython.rlib.objectmodel import specialize +from pypy.interpreter.error import OperationError +from pypy.module.micronumpy.base import W_NDimArray +from pypy.module.micronumpy import interp_dtype, types +from pypy.module.micronumpy.iter import AxisIterator + +INT_SIZE = rffi.sizeof(lltype.Signed) + +def make_sort_function(space, itemtype, comp_type, count=1): + TP = itemtype.T + step = rffi.sizeof(TP) + + class Repr(object): + def __init__(self, index_stride_size, stride_size, size, values, + indexes, index_start, start): + self.index_stride_size = index_stride_size + self.stride_size = stride_size + self.index_start = index_start + self.start = start + self.size = size + self.values = values + self.indexes = indexes + + def getitem(self, item): + if count < 2: + v = raw_storage_getitem(TP, self.values, item * self.stride_size + + self.start) + else: + v = [] + for i in range(count): + _v = raw_storage_getitem(TP, self.values, item * self.stride_size + + self.start + step * i) + v.append(_v) + if comp_type == 'int': + v = intmask(v) + elif comp_type == 'float': + v = float(v) + elif comp_type == 'complex': + v = [float(v[0]),float(v[1])] + else: + raise NotImplementedError('cannot reach') + return (v, raw_storage_getitem(lltype.Signed, self.indexes, + item * self.index_stride_size + From noreply at buildbot.pypy.org Sat Feb 9 21:33:35 2013 From: noreply at buildbot.pypy.org (mattip) Date: Sat, 9 Feb 2013 21:33:35 +0100 (CET) Subject: [pypy-commit] pypy default: test, fix complex to_builtin_type with ztranslation Message-ID: <20130209203335.131341C1028@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: Changeset: r61005:dcb190707bf8 Date: 2013-02-09 18:22 +0200 http://bitbucket.org/pypy/pypy/changeset/dcb190707bf8/ Log: test,fix complex to_builtin_type with ztranslation diff --git a/pypy/module/micronumpy/test/test_dtypes.py b/pypy/module/micronumpy/test/test_dtypes.py --- a/pypy/module/micronumpy/test/test_dtypes.py +++ b/pypy/module/micronumpy/test/test_dtypes.py @@ -472,6 +472,7 @@ assert numpy.float64(2.0) == 2.0 assert numpy.float64('23.4') == numpy.float64(23.4) raises(ValueError, numpy.float64, '23.2df') + assert "{:g}".format(numpy.complex(0.5+1.5j)) == '{:g}'.format(0.5+1.5j) def test_longfloat(self): import _numpypy as numpy diff --git a/pypy/module/micronumpy/types.py b/pypy/module/micronumpy/types.py --- a/pypy/module/micronumpy/types.py +++ b/pypy/module/micronumpy/types.py @@ -1030,6 +1030,14 @@ def for_computation(v): return float(v[0]), float(v[1]) + @raw_unary_op + def _to_builtin_type(self, v): + return v + + def to_builtin_type(self, space, box): + real,imag = self.for_computation(self.unbox(box)) + return space.newcomplex(real, imag) + def read_bool(self, arr, i, offset): v = self.for_computation(self._read(arr.storage, i, offset)) return bool(v[0]) or bool(v[1]) From noreply at buildbot.pypy.org Sat Feb 9 21:33:36 2013 From: noreply at buildbot.pypy.org (mattip) Date: Sat, 9 Feb 2013 21:33:36 +0100 (CET) Subject: [pypy-commit] pypy default: allow abstract dtypes in array construction, issue # 1160 Message-ID: <20130209203336.6BF0C1C1028@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: Changeset: r61006:fa8c91ae3a18 Date: 2013-02-09 22:23 +0200 http://bitbucket.org/pypy/pypy/changeset/fa8c91ae3a18/ Log: allow abstract dtypes in array construction, issue # 1160 diff --git a/pypy/module/micronumpy/interp_dtype.py b/pypy/module/micronumpy/interp_dtype.py --- a/pypy/module/micronumpy/interp_dtype.py +++ b/pypy/module/micronumpy/interp_dtype.py @@ -270,13 +270,12 @@ return dtype_from_list(space, w_dtype) elif space.isinstance_w(w_dtype, space.w_dict): return dtype_from_dict(space, w_dtype) - else: - for dtype in cache.builtin_dtypes: - if w_dtype in dtype.alternate_constructors: - return dtype - if w_dtype is dtype.w_box_type: - return dtype - raise OperationError(space.w_TypeError, space.wrap("data type %s not understood")) + for dtype in cache.builtin_dtypes: + if w_dtype in dtype.alternate_constructors: + return dtype + if w_dtype is dtype.w_box_type: + return dtype + raise OperationError(space.w_TypeError, space.wrap("data type %r not understood" % w_dtype)) W_Dtype.typedef = TypeDef("dtype", __module__ = "numpypy", @@ -400,7 +399,10 @@ name=name, char="l", w_box_type=space.gettypefor(interp_boxes.W_LongBox), - alternate_constructors=[space.w_int], + alternate_constructors=[space.w_int, + space.gettypefor(interp_boxes.W_IntegerBox), + space.gettypefor(interp_boxes.W_SignedIntegerBox), + ], aliases=['int'], ) self.w_ulongdtype = W_Dtype( @@ -410,6 +412,8 @@ name="u" + name, char="L", w_box_type=space.gettypefor(interp_boxes.W_ULongBox), + alternate_constructors=[ space.gettypefor(interp_boxes.W_UnsignedIntegerBox), + ], ) self.w_int64dtype = W_Dtype( types.Int64(), @@ -443,7 +447,9 @@ name="float64", char="d", w_box_type = space.gettypefor(interp_boxes.W_Float64Box), - alternate_constructors=[space.w_float], + alternate_constructors=[space.w_float, + space.gettypefor(interp_boxes.W_NumberBox), + ], aliases=["float"], ) self.w_complex64dtype = W_ComplexDtype( @@ -546,6 +552,8 @@ w_box_type = space.gettypefor(interp_boxes.W_VoidBox), #alternate_constructors=[space.w_buffer], # XXX no buffer in space + #alternate_constructors=[space.gettypefor(interp_boxes.W_GenericBox)], + # XXX fix, leads to _coerce error ) self.w_float16dtype = W_Dtype( types.Float16(), diff --git a/pypy/module/micronumpy/test/test_dtypes.py b/pypy/module/micronumpy/test/test_dtypes.py --- a/pypy/module/micronumpy/test/test_dtypes.py +++ b/pypy/module/micronumpy/test/test_dtypes.py @@ -266,6 +266,18 @@ assert 'unsignedinteger' in str(exc.value) raises(TypeError, numpy.floating, 0) raises(TypeError, numpy.inexact, 0) + # numpy allows abstract types in array creation + a = numpy.array([4,4], numpy.integer) + assert a.dtype is numpy.dtype('int64') + a = numpy.array([4,4], numpy.number) + assert a.dtype is numpy.dtype('float') + a = numpy.array([4,4], numpy.signedinteger) + assert a.dtype is numpy.dtype('int64') + a = numpy.array([4,4], numpy.unsignedinteger) + assert a.dtype is numpy.dtype('uint64') + # too ambitious for now + #a = numpy.array('xxxx', numpy.generic) + #assert a.dtype is numpy.dtype('|V4') def test_new(self): import _numpypy as np @@ -472,7 +484,7 @@ assert numpy.float64(2.0) == 2.0 assert numpy.float64('23.4') == numpy.float64(23.4) raises(ValueError, numpy.float64, '23.2df') - assert "{:g}".format(numpy.complex(0.5+1.5j)) == '{:g}'.format(0.5+1.5j) + assert "{:g}".format(numpy.complex_(0.5+1.5j)) == '{:g}'.format(0.5+1.5j) def test_longfloat(self): import _numpypy as numpy diff --git a/pypy/module/micronumpy/test/test_numarray.py b/pypy/module/micronumpy/test/test_numarray.py --- a/pypy/module/micronumpy/test/test_numarray.py +++ b/pypy/module/micronumpy/test/test_numarray.py @@ -2470,7 +2470,7 @@ class AppTestRecordDtype(BaseNumpyAppTest): def test_zeros(self): - from _numpypy import zeros + from _numpypy import zeros, integer a = zeros(2, dtype=[('x', int), ('y', float)]) raises(IndexError, 'a[0]["xyz"]') assert a[0]['x'] == 0 From noreply at buildbot.pypy.org Sat Feb 9 21:33:37 2013 From: noreply at buildbot.pypy.org (mattip) Date: Sat, 9 Feb 2013 21:33:37 +0100 (CET) Subject: [pypy-commit] pypy default: move test, skip if not python2.7 or greater, accept either ValueError or TypeError for -A compatibility Message-ID: <20130209203337.B4A1A1C1028@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: Changeset: r61007:a9b26dd44954 Date: 2013-02-09 22:33 +0200 http://bitbucket.org/pypy/pypy/changeset/a9b26dd44954/ Log: move test, skip if not python2.7 or greater, accept either ValueError or TypeError for -A compatibility diff --git a/pypy/module/micronumpy/test/test_dtypes.py b/pypy/module/micronumpy/test/test_dtypes.py --- a/pypy/module/micronumpy/test/test_dtypes.py +++ b/pypy/module/micronumpy/test/test_dtypes.py @@ -484,7 +484,6 @@ assert numpy.float64(2.0) == 2.0 assert numpy.float64('23.4') == numpy.float64(23.4) raises(ValueError, numpy.float64, '23.2df') - assert "{:g}".format(numpy.complex_(0.5+1.5j)) == '{:g}'.format(0.5+1.5j) def test_longfloat(self): import _numpypy as numpy @@ -541,7 +540,14 @@ assert numpy.complex128(1.2) == numpy.complex128(complex(1.2, 0)) assert numpy.complex64(1.2) == numpy.complex64(complex(1.2, 0)) - raises (TypeError, numpy.array, [3+4j], dtype=float) + try: + numpy.array([3+4j], dtype=float) + except (ValueError, TypeError): + pass + else: + assert False, 'should have raised' + if sys.version_info >= (2, 7): + assert "{:g}".format(numpy.complex_(0.5+1.5j)) == '{:g}'.format(0.5+1.5j) def test_complex(self): import _numpypy as numpy From noreply at buildbot.pypy.org Sat Feb 9 21:56:26 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sat, 9 Feb 2013 21:56:26 +0100 (CET) Subject: [pypy-commit] pypy default: fixes for a9b26dd44954 Message-ID: <20130209205626.C1BEE1C0228@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61008:76c65fdbeef9 Date: 2013-02-09 15:55 -0500 http://bitbucket.org/pypy/pypy/changeset/76c65fdbeef9/ Log: fixes for a9b26dd44954 diff --git a/pypy/module/micronumpy/test/test_dtypes.py b/pypy/module/micronumpy/test/test_dtypes.py --- a/pypy/module/micronumpy/test/test_dtypes.py +++ b/pypy/module/micronumpy/test/test_dtypes.py @@ -505,6 +505,7 @@ numpy.inexact, numpy.number, numpy.generic, object) def test_complex_format(self): + import sys import _numpypy as numpy for complex_ in (numpy.complex128, numpy.complex64,): @@ -540,12 +541,7 @@ assert numpy.complex128(1.2) == numpy.complex128(complex(1.2, 0)) assert numpy.complex64(1.2) == numpy.complex64(complex(1.2, 0)) - try: - numpy.array([3+4j], dtype=float) - except (ValueError, TypeError): - pass - else: - assert False, 'should have raised' + raises((ValueError, TypeError), numpy.array, [3+4j], dtype=float) if sys.version_info >= (2, 7): assert "{:g}".format(numpy.complex_(0.5+1.5j)) == '{:g}'.format(0.5+1.5j) From noreply at buildbot.pypy.org Sat Feb 9 22:04:02 2013 From: noreply at buildbot.pypy.org (shomah4a) Date: Sat, 9 Feb 2013 22:04:02 +0100 (CET) Subject: [pypy-commit] pypy default: fix: cannot find targetpypystandalone.py from translate.py Message-ID: <20130209210402.B645A1C0228@cobra.cs.uni-duesseldorf.de> Author: shoma hosaka Branch: Changeset: r61009:4b3fbe42045c Date: 2013-02-10 00:50 +0900 http://bitbucket.org/pypy/pypy/changeset/4b3fbe42045c/ Log: fix: cannot find targetpypystandalone.py from translate.py diff --git a/rpython/translator/goal/translate.py b/rpython/translator/goal/translate.py --- a/rpython/translator/goal/translate.py +++ b/rpython/translator/goal/translate.py @@ -50,7 +50,7 @@ return result translate_optiondescr = OptionDescription("translate", "XXX", [ - StrOption("targetspec", "XXX", default='../../pypy/goal/targetpypystandalone', + StrOption("targetspec", "XXX", default='../../../pypy/goal/targetpypystandalone', cmdline=None), ChoiceOption("opt", "optimization level", OPT_LEVELS, default=DEFAULT_OPT_LEVEL, From noreply at buildbot.pypy.org Sat Feb 9 22:04:03 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sat, 9 Feb 2013 22:04:03 +0100 (CET) Subject: [pypy-commit] pypy default: Merged in shomah4a/pypy2 (pull request #116) Message-ID: <20130209210403.EC77C1C0228@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61010:01077f021ef5 Date: 2013-02-09 13:03 -0800 http://bitbucket.org/pypy/pypy/changeset/01077f021ef5/ Log: Merged in shomah4a/pypy2 (pull request #116) fix: cannot find targetpypystandalone.py from translate.py diff --git a/rpython/translator/goal/translate.py b/rpython/translator/goal/translate.py --- a/rpython/translator/goal/translate.py +++ b/rpython/translator/goal/translate.py @@ -50,7 +50,7 @@ return result translate_optiondescr = OptionDescription("translate", "XXX", [ - StrOption("targetspec", "XXX", default='../../pypy/goal/targetpypystandalone', + StrOption("targetspec", "XXX", default='../../../pypy/goal/targetpypystandalone', cmdline=None), ChoiceOption("opt", "optimization level", OPT_LEVELS, default=DEFAULT_OPT_LEVEL, From noreply at buildbot.pypy.org Sat Feb 9 22:47:01 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sat, 9 Feb 2013 22:47:01 +0100 (CET) Subject: [pypy-commit] pypy default: fix numpy.dtype(intp/uintp).num on 64bit Message-ID: <20130209214701.C86941C0228@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61011:4846addd215e Date: 2013-02-09 16:46 -0500 http://bitbucket.org/pypy/pypy/changeset/4846addd215e/ Log: fix numpy.dtype(intp/uintp).num on 64bit diff --git a/pypy/module/micronumpy/interp_dtype.py b/pypy/module/micronumpy/interp_dtype.py --- a/pypy/module/micronumpy/interp_dtype.py +++ b/pypy/module/micronumpy/interp_dtype.py @@ -567,18 +567,22 @@ if ptr_size == 4: intp_box = interp_boxes.W_Int32Box intp_type = types.Int32() + intp_num = 5 uintp_box = interp_boxes.W_UInt32Box uintp_type = types.UInt32() + uintp_num = 6 elif ptr_size == 8: intp_box = interp_boxes.W_Int64Box intp_type = types.Int64() + intp_num = 7 uintp_box = interp_boxes.W_UInt64Box uintp_type = types.UInt64() + uintp_num = 8 else: raise ValueError('unknown point size %d' % ptr_size) self.w_intpdtype = W_Dtype( intp_type, - num=5, + num=intp_num, kind=INTPLTR, name='intp', char=INTPLTR, @@ -586,7 +590,7 @@ ) self.w_uintpdtype = W_Dtype( uintp_type, - num=6, + num=uintp_num, kind=UINTPLTR, name='uintp', char=UINTPLTR, diff --git a/pypy/module/micronumpy/test/test_dtypes.py b/pypy/module/micronumpy/test/test_dtypes.py --- a/pypy/module/micronumpy/test/test_dtypes.py +++ b/pypy/module/micronumpy/test/test_dtypes.py @@ -4,6 +4,17 @@ from pypy.interpreter.gateway import interp2app class AppTestDtypes(BaseNumpyAppTest): + def setup_class(cls): + BaseNumpyAppTest.setup_class.im_func(cls) + if option.runappdirect: + import platform + bits, linkage = platform.architecture() + ptr_size = int(bits[:-3]) // 8 + else: + from rpython.rtyper.lltypesystem import rffi + ptr_size = rffi.sizeof(rffi.CCHARP) + cls.w_ptr_size = cls.space.wrap(ptr_size) + def test_dtype(self): from _numpypy import dtype @@ -31,8 +42,12 @@ from _numpypy import dtype assert dtype(bool).num == 0 - assert dtype('intp').num == 5 - assert dtype('uintp').num == 6 + if self.ptr_size == 4: + assert dtype('intp').num == 5 + assert dtype('uintp').num == 6 + else: + assert dtype('intp').num == 7 + assert dtype('uintp').num == 8 assert dtype(int).num == 7 assert dtype(long).num == 9 assert dtype(float).num == 12 From noreply at buildbot.pypy.org Sat Feb 9 22:53:37 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sat, 9 Feb 2013 22:53:37 +0100 (CET) Subject: [pypy-commit] pypy default: more updates to lib_pypy/_collections.py from raymondh Message-ID: <20130209215337.AEE771C0228@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61012:059a8feb392c Date: 2013-02-09 16:53 -0500 http://bitbucket.org/pypy/pypy/changeset/059a8feb392c/ Log: more updates to lib_pypy/_collections.py from raymondh diff --git a/lib_pypy/_collections.py b/lib_pypy/_collections.py --- a/lib_pypy/_collections.py +++ b/lib_pypy/_collections.py @@ -157,9 +157,9 @@ def rotate(self, n=1): length = len(self) - if length == 0: + if length <= 1: return - halflen = (length+1) >> 1 + halflen = length >> 1 if n > halflen or n < -halflen: n %= length if n > halflen: From noreply at buildbot.pypy.org Sat Feb 9 23:04:13 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sat, 9 Feb 2013 23:04:13 +0100 (CET) Subject: [pypy-commit] pypy default: put this in a base test class instead of repeating it Message-ID: <20130209220413.8C7601C080A@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61013:3e9687a238a8 Date: 2013-02-09 17:04 -0500 http://bitbucket.org/pypy/pypy/changeset/3e9687a238a8/ Log: put this in a base test class instead of repeating it diff --git a/pypy/module/micronumpy/test/test_dtypes.py b/pypy/module/micronumpy/test/test_dtypes.py --- a/pypy/module/micronumpy/test/test_dtypes.py +++ b/pypy/module/micronumpy/test/test_dtypes.py @@ -3,7 +3,7 @@ from pypy.module.micronumpy.test.test_base import BaseNumpyAppTest from pypy.interpreter.gateway import interp2app -class AppTestDtypes(BaseNumpyAppTest): +class BaseAppTestDtypes(BaseNumpyAppTest): def setup_class(cls): BaseNumpyAppTest.setup_class.im_func(cls) if option.runappdirect: @@ -15,6 +15,7 @@ ptr_size = rffi.sizeof(rffi.CCHARP) cls.w_ptr_size = cls.space.wrap(ptr_size) +class AppTestDtypes(BaseAppTestDtypes): def test_dtype(self): from _numpypy import dtype @@ -256,18 +257,7 @@ assert hash(tp(value)) == hash(value) -class AppTestTypes(BaseNumpyAppTest): - def setup_class(cls): - BaseNumpyAppTest.setup_class.im_func(cls) - if option.runappdirect: - import platform - bits, linkage = platform.architecture() - ptr_size = int(bits[:-3]) // 8 - else: - from rpython.rtyper.lltypesystem import rffi - ptr_size = rffi.sizeof(rffi.CCHARP) - cls.w_ptr_size = cls.space.wrap(ptr_size) - +class AppTestTypes(BaseAppTestDtypes): def test_abstract_types(self): import _numpypy as numpy raises(TypeError, numpy.generic, 0) From noreply at buildbot.pypy.org Sun Feb 10 00:55:16 2013 From: noreply at buildbot.pypy.org (RonnyPfannschmidt) Date: Sun, 10 Feb 2013 00:55:16 +0100 (CET) Subject: [pypy-commit] pyrepl py3k-readline: fix some minimal problems Message-ID: <20130209235516.155881C080A@cobra.cs.uni-duesseldorf.de> Author: Ronny Pfannschmidt Branch: py3k-readline Changeset: r219:37149e9029f6 Date: 2013-01-15 22:16 +0100 http://bitbucket.org/pypy/pyrepl/changeset/37149e9029f6/ Log: fix some minimal problems diff --git a/testing/test_readline.py b/testing/test_readline.py --- a/testing/test_readline.py +++ b/testing/test_readline.py @@ -1,11 +1,13 @@ from pyrepl.readline import _ReadlineWrapper -import os, pty +import os +import pty + def test_raw_input(): readline_wrapper = _ReadlineWrapper() master, slave = pty.openpty() readline_wrapper.f_in = slave - os.write(master, 'input\n') + os.write(master, b'input\n') result = readline_wrapper.raw_input('prompt:') assert result == 'input' # A bytes string on python2, a unicode string on python3. diff --git a/testing/test_unix_reader.py b/testing/test_unix_reader.py --- a/testing/test_unix_reader.py +++ b/testing/test_unix_reader.py @@ -7,7 +7,7 @@ def test_simple(): q = EncodedQueue({}, 'utf-8') - a = u'\u1234' + a = b'\u1234'.decode('unicode-escape') b = a.encode('utf-8') for c in b: q.push(c) From noreply at buildbot.pypy.org Sun Feb 10 00:55:22 2013 From: noreply at buildbot.pypy.org (RonnyPfannschmidt) Date: Sun, 10 Feb 2013 00:55:22 +0100 (CET) Subject: [pypy-commit] pyrepl codecheck-clean: kill dead code + more cleanups Message-ID: <20130209235522.042441C11A8@cobra.cs.uni-duesseldorf.de> Author: Ronny Pfannschmidt Branch: codecheck-clean Changeset: r224:98e49b18c489 Date: 2013-01-15 23:32 +0100 http://bitbucket.org/pypy/pyrepl/changeset/98e49b18c489/ Log: kill dead code + more cleanups diff --git a/pyrepl/copy_code.py b/pyrepl/copy_code.py deleted file mode 100644 --- a/pyrepl/copy_code.py +++ /dev/null @@ -1,73 +0,0 @@ -# Copyright 2000-2004 Michael Hudson-Doyle -# -# All Rights Reserved -# -# -# Permission to use, copy, modify, and distribute this software and -# its documentation for any purpose is hereby granted without fee, -# provided that the above copyright notice appear in all copies and -# that both that copyright notice and this permission notice appear in -# supporting documentation. -# -# THE AUTHOR MICHAEL HUDSON DISCLAIMS ALL WARRANTIES WITH REGARD TO -# THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY -# AND FITNESS, IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, -# INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER -# RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF -# CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -from types import CodeType - -def copy_code_with_changes(codeobject, - argcount=None, - nlocals=None, - stacksize=None, - flags=None, - code=None, - consts=None, - names=None, - varnames=None, - filename=None, - name=None, - firstlineno=None, - lnotab=None): - if argcount is None: argcount = codeobject.co_argcount - if nlocals is None: nlocals = codeobject.co_nlocals - if stacksize is None: stacksize = codeobject.co_stacksize - if flags is None: flags = codeobject.co_flags - if code is None: code = codeobject.co_code - if consts is None: consts = codeobject.co_consts - if names is None: names = codeobject.co_names - if varnames is None: varnames = codeobject.co_varnames - if filename is None: filename = codeobject.co_filename - if name is None: name = codeobject.co_name - if firstlineno is None: firstlineno = codeobject.co_firstlineno - if lnotab is None: lnotab = codeobject.co_lnotab - return CodeType(argcount, - nlocals, - stacksize, - flags, - code, - consts, - names, - varnames, - filename, - name, - firstlineno, - lnotab) - -code_attrs=['argcount', - 'nlocals', - 'stacksize', - 'flags', - 'code', - 'consts', - 'names', - 'varnames', - 'filename', - 'name', - 'firstlineno', - 'lnotab'] - - diff --git a/pyrepl/unix_console.py b/pyrepl/unix_console.py --- a/pyrepl/unix_console.py +++ b/pyrepl/unix_console.py @@ -19,8 +19,15 @@ # CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -import termios, select, os, struct, errno -import signal, re, time, sys +import termios +import select +import os +import struct +import errno +import signal +import re +import time +import sys from fcntl import ioctl from . import curses from .fancy_termios import tcgetattr, tcsetattr @@ -28,6 +35,7 @@ from .unix_eventqueue import EventQueue from .trace import trace + class InvalidTerminal(RuntimeError): pass @@ -44,13 +52,15 @@ FIONREAD = getattr(termios, "FIONREAD", None) TIOCGWINSZ = getattr(termios, "TIOCGWINSZ", None) + def _my_getstr(cap, optional=0): r = curses.tigetstr(cap) if not optional and r is None: raise InvalidTerminal( - "terminal doesn't have the required '%s' capability"%cap) + "terminal doesn't have the required '%s' capability" % cap) return r + # at this point, can we say: AAAAAAAAAAAAAAAAAAAAAARGH! def maybe_add_baudrate(dict, rate): name = 'B%d'%rate @@ -74,19 +84,22 @@ class poll: def __init__(self): pass + def register(self, fd, flag): self.fd = fd + def poll(self, timeout=None): - r,w,e = select.select([self.fd],[],[],timeout) + r, w, e = select.select([self.fd],[],[],timeout) return r POLLIN = getattr(select, "POLLIN", None) + class UnixConsole(Console): def __init__(self, f_in=0, f_out=1, term=None, encoding=None): if encoding is None: encoding = sys.getdefaultencoding() - + self.encoding = encoding if isinstance(f_in, int): @@ -98,13 +111,12 @@ self.output_fd = f_out else: self.output_fd = f_out.fileno() - self.pollob = poll() self.pollob.register(self.input_fd, POLLIN) curses.setupterm(term, self.output_fd) self.term = term - + self._bel = _my_getstr("bel") self._civis = _my_getstr("civis", optional=1) self._clear = _my_getstr("clear") @@ -166,9 +178,6 @@ self.event_queue = EventQueue(self.input_fd, self.encoding) self.cursor_visible = 1 - def change_encoding(self, encoding): - self.encoding = encoding - def refresh(self, screen, c_xy): # this function is still too long (over 90 lines) cx, cy = c_xy @@ -181,7 +190,7 @@ self.screen.append("") else: while len(self.screen) < len(screen): - self.screen.append("") + self.screen.append("") if len(screen) > self.height: self.__gone_tall = 1 @@ -191,7 +200,6 @@ old_offset = offset = self.__offset height = self.height - # we make sure the cursor is on the screen, and that we're # using all of the screen if we can if cy < offset: @@ -230,7 +238,7 @@ newscr): if oldline != newline: self.__write_changed_line(y, oldline, newline, px) - + y = len(newscr) while y < len(oldscr): self.__hide_cursor() @@ -240,7 +248,7 @@ y += 1 self.__show_cursor() - + self.screen = screen self.move_cursor(cx, cy) self.flushoutput() @@ -288,7 +296,7 @@ self.__write_code(self._el) self.__write(newline[x:]) self.__posxy = len(newline), y - + if '\x1b' in newline: # ANSI escape characters are present, so we can't assume # anything about the position of the cursor. Moving the cursor @@ -362,10 +370,10 @@ raw.iflag &=~ (termios.BRKINT | termios.INPCK | termios.ISTRIP | termios.IXON) raw.oflag &=~ (termios.OPOST) - raw.cflag &=~ (termios.CSIZE|termios.PARENB) + raw.cflag &=~ (termios.CSIZE | termios.PARENB) raw.cflag |= (termios.CS8) - raw.lflag &=~ (termios.ICANON|termios.ECHO| - termios.IEXTEN|(termios.ISIG*1)) + raw.lflag &=~ (termios.ICANON | termios.ECHO| + termios.IEXTEN | (termios.ISIG * 1)) raw.cc[termios.VMIN] = 1 raw.cc[termios.VTIME] = 0 tcsetattr(self.input_fd, termios.TCSADRAIN, raw) @@ -374,7 +382,7 @@ self.height, self.width = self.getheightwidth() self.__buffer = [] - + self.__posxy = 0, 0 self.__gone_tall = 0 self.__move = self.__move_short @@ -403,10 +411,11 @@ def push_char(self, char): trace('push char {char!r}', char=char) self.event_queue.push(char) - + def get_event(self, block=1): while self.event_queue.empty(): - while 1: # All hail Unix! + while 1: + # All hail Unix! try: self.push_char(os.read(self.input_fd, 1)) except (IOError, OSError) as err: @@ -461,7 +470,8 @@ except KeyError: height, width = struct.unpack( "hhhh", ioctl(self.input_fd, TIOCGWINSZ, "\000"*8))[0:2] - if not height: return 25, 80 + if not height: + return 25, 80 return height, width else: def getheightwidth(self): @@ -528,7 +538,7 @@ e2 = self.event_queue.get() e.data += e2.data e.raw += e.raw - + amount = struct.unpack( "i", ioctl(self.input_fd, FIONREAD, "\0\0\0\0"))[0] raw = unicode(os.read(self.input_fd, amount), self.encoding, 'replace') From noreply at buildbot.pypy.org Sun Feb 10 00:55:17 2013 From: noreply at buildbot.pypy.org (RonnyPfannschmidt) Date: Sun, 10 Feb 2013 00:55:17 +0100 (CET) Subject: [pypy-commit] pyrepl default: merge codecheck clean Message-ID: <20130209235517.4D6481C1028@cobra.cs.uni-duesseldorf.de> Author: Ronny Pfannschmidt Branch: Changeset: r220:7a5bb323410c Date: 2013-01-15 22:58 +0100 http://bitbucket.org/pypy/pyrepl/changeset/7a5bb323410c/ Log: merge codecheck clean diff --git a/.hgignore b/.hgignore --- a/.hgignore +++ b/.hgignore @@ -1,4 +1,5 @@ dist/ build/ +.cache/ \.tox/ .*\.egg-info diff --git a/pyrepl/_minimal_curses.py b/pyrepl/_minimal_curses.py --- a/pyrepl/_minimal_curses.py +++ b/pyrepl/_minimal_curses.py @@ -9,7 +9,8 @@ hide this one if compiled in. """ -import ctypes, ctypes.util +import ctypes.util + class error(Exception): pass @@ -42,8 +43,12 @@ # ____________________________________________________________ -try: from __pypy__ import builtinify -except ImportError: builtinify = lambda f: f +try: + from __pypy__ import builtinify + builtinify # silence broken pyflakes +except ImportError: + builtinify = lambda f: f + @builtinify def setupterm(termstr, fd): @@ -52,6 +57,7 @@ if result == ERR: raise error("setupterm() failed (err=%d)" % err.value) + @builtinify def tigetstr(cap): if not isinstance(cap, bytes): @@ -61,6 +67,7 @@ return None return ctypes.cast(result, ctypes.c_char_p).value + @builtinify def tparm(str, i1=0, i2=0, i3=0, i4=0, i5=0, i6=0, i7=0, i8=0, i9=0): result = clib.tparm(str, i1, i2, i3, i4, i5, i6, i7, i8, i9) diff --git a/pyrepl/cmdrepl.py b/pyrepl/cmdrepl.py --- a/pyrepl/cmdrepl.py +++ b/pyrepl/cmdrepl.py @@ -35,26 +35,28 @@ from __future__ import print_function -from pyrepl import completing_reader as cr, reader, completer +from pyrepl import completer from pyrepl.completing_reader import CompletingReader as CR import cmd + class CmdReader(CR): def collect_keymap(self): return super(CmdReader, self).collect_keymap() + ( ("\\M-\\n", "invalid-key"), ("\\n", "accept")) - - CR_init = CR.__init__ + def __init__(self, completions): - self.CR_init(self) + super(CmdReader, self).__init__() self.completions = completions def get_completions(self, stem): if len(stem) != self.pos: return [] - return sorted(set(s for s in self.completions - if s.startswith(stem))) + return sorted(set(s + for s in self.completions + if s.startswith(stem))) + def replize(klass, history_across_invocations=1): @@ -71,26 +73,25 @@ for s in completer.get_class_members(klass) if s.startswith("do_")] - if not issubclass(klass, cmd.Cmd): - raise Exception + assert issubclass(klass, cmd.Cmd) # if klass.cmdloop.im_class is not cmd.Cmd: # print "this may not work" - class CmdRepl(klass): - k_init = klass.__init__ + class MultiHist(object): + __history = [] - if history_across_invocations: - _CmdRepl__history = [] - def __init__(self, *args, **kw): - self.k_init(*args, **kw) - self.__reader = CmdReader(completions) - self.__reader.history = CmdRepl._CmdRepl__history - self.__reader.historyi = len(CmdRepl._CmdRepl__history) - else: - def __init__(self, *args, **kw): - self.k_init(*args, **kw) - self.__reader = CmdReader(completions) - + def __init__(self, *args, **kw): + super(MultiHist, self).__init__(*args, **kw) + self.__reader = CmdReader(completions) + self.__reader.history = self.__history + self.__reader.historyi = len(self.__history) + + class SimpleHist(object): + def __init__(self, *args, **kw): + super(SimpleHist, self).__init__(*args, **kw) + self.__reader = CmdReader(completions) + + class CmdLoopMixin(object): def cmdloop(self, intro=None): self.preloop() if intro is not None: @@ -113,6 +114,8 @@ stop = self.postcmd(stop, line) self.postloop() - CmdRepl.__name__ = "replize(%s.%s)"%(klass.__module__, klass.__name__) + hist = MultiHist if history_across_invocations else SimpleHist + + class CmdRepl(hist, CmdLoopMixin, klass): + __name__ = "replize(%s.%s)" % (klass.__module__, klass.__name__) return CmdRepl - diff --git a/pyrepl/completer.py b/pyrepl/completer.py --- a/pyrepl/completer.py +++ b/pyrepl/completer.py @@ -19,10 +19,12 @@ try: import __builtin__ as builtins + builtins # silence broken pyflakes except ImportError: import builtins -class Completer: + +class Completer(object): def __init__(self, ns): self.ns = ns @@ -79,11 +81,10 @@ matches.append("%s.%s" % (expr, word)) return matches + def get_class_members(klass): ret = dir(klass) if hasattr(klass, '__bases__'): for base in klass.__bases__: ret = ret + get_class_members(base) return ret - - diff --git a/pyrepl/completing_reader.py b/pyrepl/completing_reader.py --- a/pyrepl/completing_reader.py +++ b/pyrepl/completing_reader.py @@ -18,11 +18,12 @@ # CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +import re from pyrepl import commands, reader from pyrepl.reader import Reader -def prefix(wordlist, j = 0): +def prefix(wordlist, j=0): d = {} i = j try: @@ -36,14 +37,18 @@ except IndexError: return wordlist[0][j:i] -import re + +STRIPCOLOR_REGEX = re.compile(r"\x1B\[([0-9]{1,3}(;[0-9]{1,2})?)?[m|K]") + + def stripcolor(s): - return stripcolor.regexp.sub('', s) -stripcolor.regexp = re.compile(r"\x1B\[([0-9]{1,3}(;[0-9]{1,2})?)?[m|K]") + return STRIPCOLOR_REGEX.regexp.sub('', s) + def real_len(s): return len(stripcolor(s)) + def left_align(s, maxlen): stripped = stripcolor(s) if len(stripped) > maxlen: @@ -52,6 +57,7 @@ padding = maxlen - len(stripped) return s + ' '*padding + def build_menu(cons, wordlist, start, use_brackets, sort_in_column): if use_brackets: item = "[ %s ]" @@ -66,14 +72,14 @@ if sort_in_column: # sort_in_column=False (default) sort_in_column=True # A B C A D G - # D E F B E + # D E F B E # G C F # # "fill" the table with empty words, so we always have the same amout # of rows for each column missing = cols*rows - len(wordlist) wordlist = wordlist + ['']*missing - indexes = [(i%cols)*rows + i//cols for i in range(len(wordlist))] + indexes = [(i % cols) * rows + i // cols for i in range(len(wordlist))] wordlist = [wordlist[i] for i in indexes] menu = [] i = start @@ -84,14 +90,14 @@ i += 1 if i >= len(wordlist): break - menu.append( ''.join(row) ) + menu.append(''.join(row)) if i >= len(wordlist): i = 0 break if r + 5 > cons.height: - menu.append(" %d more... "%(len(wordlist) - i)) + menu.append(" %d more... " % (len(wordlist) - i)) break - return menu, i + return menu, i # this gets somewhat user interface-y, and as a result the logic gets # very convoluted. @@ -118,7 +124,7 @@ # only if the ``assume_immutable_completions`` is True. # # now it gets complicated. -# +# # for the first press of a completion key: # if there's a common prefix, stick it in. @@ -140,22 +146,22 @@ # for subsequent bangs, rotate the menu around (if there are sufficient # choices). + class complete(commands.Command): def do(self): r = self.reader + last_is_completer = r.last_command_is(self.__class__) + immutable_completions = r.assume_immutable_completions + completions_unchangable = last_is_completer and immutable_completions stem = r.get_stem() - if r.assume_immutable_completions and \ - r.last_command_is(self.__class__): - completions = r.cmpltn_menu_choices - else: - r.cmpltn_menu_choices = completions = \ - r.get_completions(stem) - if len(completions) == 0: + if not completions_unchangable: + r.cmpltn_menu_choices = r.get_completions(stem) + + completions = r.cmpltn_menu_choices + if not completions: r.error("no matches") elif len(completions) == 1: - if r.assume_immutable_completions and \ - len(completions[0]) == len(stem) and \ - r.last_command_is(self.__class__): + if completions_unchangable and len(completions[0]) == len(stem): r.msg = "[ sole completion ]" r.dirty = 1 r.insert(completions[0][len(stem):]) @@ -163,7 +169,7 @@ p = prefix(completions, len(stem)) if p: r.insert(p) - if r.last_command_is(self.__class__): + if last_is_completer: if not r.cmpltn_menu_vis: r.cmpltn_menu_vis = 1 r.cmpltn_menu, r.cmpltn_menu_end = build_menu( @@ -177,6 +183,7 @@ r.msg = "[ not unique ]" r.dirty = 1 + class self_insert(commands.self_insert): def do(self): commands.self_insert.do(self) @@ -195,6 +202,7 @@ else: r.cmpltn_reset() + class CompletingReader(Reader): """Adds completion support @@ -204,26 +212,25 @@ """ # see the comment for the complete command assume_immutable_completions = True - use_brackets = True # display completions inside [] + use_brackets = True # display completions inside [] sort_in_column = False - + def collect_keymap(self): return super(CompletingReader, self).collect_keymap() + ( (r'\t', 'complete'),) - + def __init__(self, console): super(CompletingReader, self).__init__(console) self.cmpltn_menu = ["[ menu 1 ]", "[ menu 2 ]"] self.cmpltn_menu_vis = 0 self.cmpltn_menu_end = 0 - for c in [complete, self_insert]: + for c in (complete, self_insert): self.commands[c.__name__] = c - self.commands[c.__name__.replace('_', '-')] = c + self.commands[c.__name__.replace('_', '-')] = c def after_command(self, cmd): super(CompletingReader, self).after_command(cmd) - if not isinstance(cmd, self.commands['complete']) \ - and not isinstance(cmd, self.commands['self_insert']): + if not isinstance(cmd, (complete, self_insert)): self.cmpltn_reset() def calc_screen(self): @@ -243,7 +250,7 @@ self.cmpltn_menu = [] self.cmpltn_menu_vis = 0 self.cmpltn_menu_end = 0 - self.cmpltn_menu_choices = [] + self.cmpltn_menu_choices = [] def get_stem(self): st = self.syntax_table @@ -257,11 +264,14 @@ def get_completions(self, stem): return [] + def test(): class TestReader(CompletingReader): def get_completions(self, stem): - return [s for l in map(lambda x:x.split(),self.history) - for s in l if s and s.startswith(stem)] + return [s for l in self.history + for s in l.split() + if s and s.startswith(stem)] + reader = TestReader() reader.ps1 = "c**> " reader.ps2 = "c/*> " @@ -270,5 +280,6 @@ while reader.readline(): pass -if __name__=='__main__': + +if __name__ == '__main__': test() diff --git a/pyrepl/console.py b/pyrepl/console.py --- a/pyrepl/console.py +++ b/pyrepl/console.py @@ -17,6 +17,7 @@ # CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + class Event(object): """An Event. `evt' is 'key' or somesuch.""" __slots__ = 'evt', 'data', 'raw' @@ -27,7 +28,8 @@ self.raw = raw def __repr__(self): - return 'Event(%r, %r)'%(self.evt, self.data) + return 'Event(%r, %r)' % (self.evt, self.data) + class Console(object): """Attributes: @@ -36,7 +38,7 @@ height, width, """ - + def refresh(self, screen, xy): pass diff --git a/pyrepl/unix_eventqueue.py b/pyrepl/unix_eventqueue.py --- a/pyrepl/unix_eventqueue.py +++ b/pyrepl/unix_eventqueue.py @@ -21,6 +21,8 @@ # Bah, this would be easier to test if curses/terminfo didn't have so # much non-introspectable global state. +from collections import deque + from pyrepl import keymap from pyrepl.console import Event from pyrepl import curses @@ -34,23 +36,23 @@ _keynames = { - "delete" : "kdch1", - "down" : "kcud1", - "end" : "kend", - "enter" : "kent", - "f1" : "kf1", "f2" : "kf2", "f3" : "kf3", "f4" : "kf4", - "f5" : "kf5", "f6" : "kf6", "f7" : "kf7", "f8" : "kf8", - "f9" : "kf9", "f10" : "kf10", "f11" : "kf11", "f12" : "kf12", - "f13" : "kf13", "f14" : "kf14", "f15" : "kf15", "f16" : "kf16", - "f17" : "kf17", "f18" : "kf18", "f19" : "kf19", "f20" : "kf20", - "home" : "khome", - "insert" : "kich1", - "left" : "kcub1", - "page down" : "knp", - "page up" : "kpp", - "right" : "kcuf1", - "up" : "kcuu1", - } + "delete": "kdch1", + "down": "kcud1", + "end": "kend", + "enter": "kent", + "home": "khome", + "insert": "kich1", + "left": "kcub1", + "page down": "knp", + "page up": "kpp", + "right": "kcuf1", + "up": "kcuu1", +} + + +#function keys x in 1-20 -> fX: kfX +_keynames.update(('f%d' % i, 'kf%d' % i) for i in range(1, 21)) + def general_keycodes(): keycodes = {} @@ -62,7 +64,6 @@ return keycodes - def EventQueue(fd, encoding): keycodes = general_keycodes() if os.isatty(fd): @@ -72,16 +73,17 @@ trace('keymap {k!r}', k=k) return EncodedQueue(k, encoding) + class EncodedQueue(object): def __init__(self, keymap, encoding): self.k = self.ck = keymap - self.events = [] + self.events = deque() self.buf = bytearray() - self.encoding=encoding + self.encoding = encoding def get(self): if self.events: - return self.events.pop(0) + return self.events.popleft() else: return None diff --git a/setup.py b/setup.py --- a/setup.py +++ b/setup.py @@ -17,7 +17,7 @@ # CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -from setuptools import setup, Extension +from setuptools import setup long_desc = """\ pyrepl is a Python library, inspired by readline, for building flexible @@ -31,17 +31,17 @@ setup( - name = "pyrepl", - version = "0.8.4", - author = "Michael Hudson-Doyle", - author_email = "micahel at gmail.com", + name="pyrepl", + version="0.8.4", + author="Michael Hudson-Doyle", + author_email="micahel at gmail.com", maintainer="Ronny Pfannschmidt", maintainer_email="ronny.pfannschmidt at gmx.de", - url = "http://bitbucket.org/pypy/pyrepl/", - license = "MIT X11 style", - description = "A library for building flexible command line interfaces", - platforms = ["unix", "linux"], - packages = ["pyrepl" ], - scripts = ["pythoni", "pythoni1"], - long_description = long_desc, - ) + url="http://bitbucket.org/pypy/pyrepl/", + license="MIT X11 style", + description="A library for building flexible command line interfaces", + platforms=["unix", "linux"], + packages=["pyrepl"], + scripts=["pythoni", "pythoni1"], + long_description=long_desc, +) diff --git a/testing/test_unix_reader.py b/testing/test_unix_reader.py --- a/testing/test_unix_reader.py +++ b/testing/test_unix_reader.py @@ -1,9 +1,6 @@ from __future__ import unicode_literals from pyrepl.unix_eventqueue import EncodedQueue -from pyrepl import curses - - def test_simple(): q = EncodedQueue({}, 'utf-8') diff --git a/testing/test_wishes.py b/testing/test_wishes.py --- a/testing/test_wishes.py +++ b/testing/test_wishes.py @@ -24,8 +24,8 @@ def test_quoted_insert_repeat(): - read_spec([(('digit-arg', '3'), ['']), - (('quoted-insert', None), ['']), - (('self-insert', '\033'), ['^[^[^[']), - (('accept', None), None)]) - + read_spec([ + (('digit-arg', '3'), ['']), + (('quoted-insert', None), ['']), + (('self-insert', '\033'), ['^[^[^[']), + (('accept', None), None)]) From noreply at buildbot.pypy.org Sun Feb 10 00:55:23 2013 From: noreply at buildbot.pypy.org (RonnyPfannschmidt) Date: Sun, 10 Feb 2013 00:55:23 +0100 (CET) Subject: [pypy-commit] pyrepl codecheck-clean: codecheck clean reader Message-ID: <20130209235523.142DA1C080A@cobra.cs.uni-duesseldorf.de> Author: Ronny Pfannschmidt Branch: codecheck-clean Changeset: r225:a027dd430157 Date: 2013-01-16 21:15 +0100 http://bitbucket.org/pypy/pyrepl/changeset/a027dd430157/ Log: codecheck clean reader diff --git a/pyrepl/reader.py b/pyrepl/reader.py --- a/pyrepl/reader.py +++ b/pyrepl/reader.py @@ -143,11 +143,11 @@ (r'\M-8', 'digit-arg'), (r'\M-9', 'digit-arg'), #(r'\M-\n', 'insert-nl'), - ('\\\\', 'self-insert')] + \ + ('\\\\', 'self-insert')] + [(c, 'self-insert') - for c in map(chr, range(32, 127)) if c != '\\'] + \ + for c in map(chr, range(32, 127)) if c != '\\'] + [(c, 'self-insert') - for c in map(chr, range(128, 256)) if c.isalpha()] + \ + for c in map(chr, range(128, 256)) if c.isalpha()] + [(r'\', 'up'), (r'\', 'down'), (r'\', 'left'), @@ -244,9 +244,9 @@ self.commands = {} self.msg = '' for v in vars(commands).values(): - if (isinstance(v, type) - and issubclass(v, commands.Command) - and v.__name__[0].islower()): + if (isinstance(v, type) and + issubclass(v, commands.Command) and + v.__name__[0].islower()): self.commands[v.__name__] = v self.commands[v.__name__.replace('_', '-')] = v self.syntax_table = make_default_syntax_table() From noreply at buildbot.pypy.org Sun Feb 10 00:55:24 2013 From: noreply at buildbot.pypy.org (RonnyPfannschmidt) Date: Sun, 10 Feb 2013 00:55:24 +0100 (CET) Subject: [pypy-commit] pyrepl codecheck-clean: more cleanups Message-ID: <20130209235524.1A7C31C080A@cobra.cs.uni-duesseldorf.de> Author: Ronny Pfannschmidt Branch: codecheck-clean Changeset: r226:dbed922d398b Date: 2013-01-16 21:16 +0100 http://bitbucket.org/pypy/pyrepl/changeset/dbed922d398b/ Log: more cleanups diff --git a/pyrepl/readline.py b/pyrepl/readline.py --- a/pyrepl/readline.py +++ b/pyrepl/readline.py @@ -26,7 +26,8 @@ extensions for multiline input. """ -import sys, os +import sys +import os from pyrepl import commands from pyrepl.historical_reader import HistoricalReader from pyrepl.completing_reader import CompletingReader @@ -35,41 +36,43 @@ ENCODING = sys.getfilesystemencoding() or 'latin1' # XXX review -__all__ = ['add_history', - 'clear_history', - 'get_begidx', - 'get_completer', - 'get_completer_delims', - 'get_current_history_length', - 'get_endidx', - 'get_history_item', - 'get_history_length', - 'get_line_buffer', - 'insert_text', - 'parse_and_bind', - 'read_history_file', - 'read_init_file', - 'redisplay', - 'remove_history_item', - 'replace_history_item', - 'set_completer', - 'set_completer_delims', - 'set_history_length', - 'set_pre_input_hook', - 'set_startup_hook', - 'write_history_file', - # ---- multiline extensions ---- - 'multiline_input', - ] +__all__ = [ + 'add_history', + 'clear_history', + 'get_begidx', + 'get_completer', + 'get_completer_delims', + 'get_current_history_length', + 'get_endidx', + 'get_history_item', + 'get_history_length', + 'get_line_buffer', + 'insert_text', + 'parse_and_bind', + 'read_history_file', + 'read_init_file', + 'redisplay', + 'remove_history_item', + 'replace_history_item', + 'set_completer', + 'set_completer_delims', + 'set_history_length', + 'set_pre_input_hook', + 'set_startup_hook', + 'write_history_file', + # ---- multiline extensions ---- + 'multiline_input', +] # ____________________________________________________________ + class ReadlineConfig(object): readline_completer = None completer_delims = dict.fromkeys(' \t\n`~!@#$%^&*()-=+[{]}\\|;:\'",<>/?') + class ReadlineAlikeReader(HistoricalReader, CompletingReader): - assume_immutable_completions = False use_brackets = False sort_in_column = True @@ -156,10 +159,11 @@ if self.pos > len(self.buffer): self.pos = len(self.buffer) + class maybe_accept(commands.Command): def do(self): r = self.reader - r.dirty = 1 # this is needed to hide the completion menu, if visible + r.dirty = 1 # this is needed to hide the completion menu, if visible # # if there are already several lines and the cursor # is not on the last one, always insert a new \n. @@ -171,7 +175,6 @@ else: self.finish = 1 -# ____________________________________________________________ class _ReadlineWrapper(object): reader = None @@ -369,6 +372,7 @@ # ____________________________________________________________ # Stubs + def _make_stub(_name, _ret): def stub(*args, **kwds): import warnings @@ -380,16 +384,16 @@ ('read_init_file', None), ('redisplay', None), ('set_pre_input_hook', None), - ]: +]: assert _name not in globals(), _name _make_stub(_name, _ret) -# ____________________________________________________________ def _setup(): global _old_raw_input if _old_raw_input is not None: - return # don't run _setup twice + return + # don't run _setup twice try: f_in = sys.stdin.fileno() diff --git a/pyrepl/simple_interact.py b/pyrepl/simple_interact.py --- a/pyrepl/simple_interact.py +++ b/pyrepl/simple_interact.py @@ -26,6 +26,7 @@ import sys from pyrepl.readline import multiline_input, _error, _get_reader + def check(): # returns False if there is a problem initializing the state try: _get_reader() @@ -33,6 +34,7 @@ return False return True + def run_multiline_interactive_console(mainmodule=None): import code import __main__ From noreply at buildbot.pypy.org Sun Feb 10 00:55:18 2013 From: noreply at buildbot.pypy.org (RonnyPfannschmidt) Date: Sun, 10 Feb 2013 00:55:18 +0100 (CET) Subject: [pypy-commit] pyrepl py3k-readline: merge from default Message-ID: <20130209235518.6B29E1C1029@cobra.cs.uni-duesseldorf.de> Author: Ronny Pfannschmidt Branch: py3k-readline Changeset: r221:595774962c18 Date: 2013-01-15 22:59 +0100 http://bitbucket.org/pypy/pyrepl/changeset/595774962c18/ Log: merge from default diff --git a/.hgignore b/.hgignore --- a/.hgignore +++ b/.hgignore @@ -1,4 +1,5 @@ dist/ build/ +.cache/ \.tox/ .*\.egg-info diff --git a/pyrepl/_minimal_curses.py b/pyrepl/_minimal_curses.py --- a/pyrepl/_minimal_curses.py +++ b/pyrepl/_minimal_curses.py @@ -9,7 +9,8 @@ hide this one if compiled in. """ -import ctypes, ctypes.util +import ctypes.util + class error(Exception): pass @@ -42,8 +43,12 @@ # ____________________________________________________________ -try: from __pypy__ import builtinify -except ImportError: builtinify = lambda f: f +try: + from __pypy__ import builtinify + builtinify # silence broken pyflakes +except ImportError: + builtinify = lambda f: f + @builtinify def setupterm(termstr, fd): @@ -52,6 +57,7 @@ if result == ERR: raise error("setupterm() failed (err=%d)" % err.value) + @builtinify def tigetstr(cap): if not isinstance(cap, bytes): @@ -61,6 +67,7 @@ return None return ctypes.cast(result, ctypes.c_char_p).value + @builtinify def tparm(str, i1=0, i2=0, i3=0, i4=0, i5=0, i6=0, i7=0, i8=0, i9=0): result = clib.tparm(str, i1, i2, i3, i4, i5, i6, i7, i8, i9) diff --git a/pyrepl/cmdrepl.py b/pyrepl/cmdrepl.py --- a/pyrepl/cmdrepl.py +++ b/pyrepl/cmdrepl.py @@ -35,26 +35,28 @@ from __future__ import print_function -from pyrepl import completing_reader as cr, reader, completer +from pyrepl import completer from pyrepl.completing_reader import CompletingReader as CR import cmd + class CmdReader(CR): def collect_keymap(self): return super(CmdReader, self).collect_keymap() + ( ("\\M-\\n", "invalid-key"), ("\\n", "accept")) - - CR_init = CR.__init__ + def __init__(self, completions): - self.CR_init(self) + super(CmdReader, self).__init__() self.completions = completions def get_completions(self, stem): if len(stem) != self.pos: return [] - return sorted(set(s for s in self.completions - if s.startswith(stem))) + return sorted(set(s + for s in self.completions + if s.startswith(stem))) + def replize(klass, history_across_invocations=1): @@ -71,26 +73,25 @@ for s in completer.get_class_members(klass) if s.startswith("do_")] - if not issubclass(klass, cmd.Cmd): - raise Exception + assert issubclass(klass, cmd.Cmd) # if klass.cmdloop.im_class is not cmd.Cmd: # print "this may not work" - class CmdRepl(klass): - k_init = klass.__init__ + class MultiHist(object): + __history = [] - if history_across_invocations: - _CmdRepl__history = [] - def __init__(self, *args, **kw): - self.k_init(*args, **kw) - self.__reader = CmdReader(completions) - self.__reader.history = CmdRepl._CmdRepl__history - self.__reader.historyi = len(CmdRepl._CmdRepl__history) - else: - def __init__(self, *args, **kw): - self.k_init(*args, **kw) - self.__reader = CmdReader(completions) - + def __init__(self, *args, **kw): + super(MultiHist, self).__init__(*args, **kw) + self.__reader = CmdReader(completions) + self.__reader.history = self.__history + self.__reader.historyi = len(self.__history) + + class SimpleHist(object): + def __init__(self, *args, **kw): + super(SimpleHist, self).__init__(*args, **kw) + self.__reader = CmdReader(completions) + + class CmdLoopMixin(object): def cmdloop(self, intro=None): self.preloop() if intro is not None: @@ -113,6 +114,8 @@ stop = self.postcmd(stop, line) self.postloop() - CmdRepl.__name__ = "replize(%s.%s)"%(klass.__module__, klass.__name__) + hist = MultiHist if history_across_invocations else SimpleHist + + class CmdRepl(hist, CmdLoopMixin, klass): + __name__ = "replize(%s.%s)" % (klass.__module__, klass.__name__) return CmdRepl - diff --git a/pyrepl/completer.py b/pyrepl/completer.py --- a/pyrepl/completer.py +++ b/pyrepl/completer.py @@ -19,10 +19,12 @@ try: import __builtin__ as builtins + builtins # silence broken pyflakes except ImportError: import builtins -class Completer: + +class Completer(object): def __init__(self, ns): self.ns = ns @@ -79,11 +81,10 @@ matches.append("%s.%s" % (expr, word)) return matches + def get_class_members(klass): ret = dir(klass) if hasattr(klass, '__bases__'): for base in klass.__bases__: ret = ret + get_class_members(base) return ret - - diff --git a/pyrepl/completing_reader.py b/pyrepl/completing_reader.py --- a/pyrepl/completing_reader.py +++ b/pyrepl/completing_reader.py @@ -18,11 +18,12 @@ # CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +import re from pyrepl import commands, reader from pyrepl.reader import Reader -def prefix(wordlist, j = 0): +def prefix(wordlist, j=0): d = {} i = j try: @@ -36,14 +37,18 @@ except IndexError: return wordlist[0][j:i] -import re + +STRIPCOLOR_REGEX = re.compile(r"\x1B\[([0-9]{1,3}(;[0-9]{1,2})?)?[m|K]") + + def stripcolor(s): - return stripcolor.regexp.sub('', s) -stripcolor.regexp = re.compile(r"\x1B\[([0-9]{1,3}(;[0-9]{1,2})?)?[m|K]") + return STRIPCOLOR_REGEX.regexp.sub('', s) + def real_len(s): return len(stripcolor(s)) + def left_align(s, maxlen): stripped = stripcolor(s) if len(stripped) > maxlen: @@ -52,6 +57,7 @@ padding = maxlen - len(stripped) return s + ' '*padding + def build_menu(cons, wordlist, start, use_brackets, sort_in_column): if use_brackets: item = "[ %s ]" @@ -66,14 +72,14 @@ if sort_in_column: # sort_in_column=False (default) sort_in_column=True # A B C A D G - # D E F B E + # D E F B E # G C F # # "fill" the table with empty words, so we always have the same amout # of rows for each column missing = cols*rows - len(wordlist) wordlist = wordlist + ['']*missing - indexes = [(i%cols)*rows + i//cols for i in range(len(wordlist))] + indexes = [(i % cols) * rows + i // cols for i in range(len(wordlist))] wordlist = [wordlist[i] for i in indexes] menu = [] i = start @@ -84,14 +90,14 @@ i += 1 if i >= len(wordlist): break - menu.append( ''.join(row) ) + menu.append(''.join(row)) if i >= len(wordlist): i = 0 break if r + 5 > cons.height: - menu.append(" %d more... "%(len(wordlist) - i)) + menu.append(" %d more... " % (len(wordlist) - i)) break - return menu, i + return menu, i # this gets somewhat user interface-y, and as a result the logic gets # very convoluted. @@ -118,7 +124,7 @@ # only if the ``assume_immutable_completions`` is True. # # now it gets complicated. -# +# # for the first press of a completion key: # if there's a common prefix, stick it in. @@ -140,22 +146,22 @@ # for subsequent bangs, rotate the menu around (if there are sufficient # choices). + class complete(commands.Command): def do(self): r = self.reader + last_is_completer = r.last_command_is(self.__class__) + immutable_completions = r.assume_immutable_completions + completions_unchangable = last_is_completer and immutable_completions stem = r.get_stem() - if r.assume_immutable_completions and \ - r.last_command_is(self.__class__): - completions = r.cmpltn_menu_choices - else: - r.cmpltn_menu_choices = completions = \ - r.get_completions(stem) - if len(completions) == 0: + if not completions_unchangable: + r.cmpltn_menu_choices = r.get_completions(stem) + + completions = r.cmpltn_menu_choices + if not completions: r.error("no matches") elif len(completions) == 1: - if r.assume_immutable_completions and \ - len(completions[0]) == len(stem) and \ - r.last_command_is(self.__class__): + if completions_unchangable and len(completions[0]) == len(stem): r.msg = "[ sole completion ]" r.dirty = 1 r.insert(completions[0][len(stem):]) @@ -163,7 +169,7 @@ p = prefix(completions, len(stem)) if p: r.insert(p) - if r.last_command_is(self.__class__): + if last_is_completer: if not r.cmpltn_menu_vis: r.cmpltn_menu_vis = 1 r.cmpltn_menu, r.cmpltn_menu_end = build_menu( @@ -177,6 +183,7 @@ r.msg = "[ not unique ]" r.dirty = 1 + class self_insert(commands.self_insert): def do(self): commands.self_insert.do(self) @@ -195,6 +202,7 @@ else: r.cmpltn_reset() + class CompletingReader(Reader): """Adds completion support @@ -204,26 +212,25 @@ """ # see the comment for the complete command assume_immutable_completions = True - use_brackets = True # display completions inside [] + use_brackets = True # display completions inside [] sort_in_column = False - + def collect_keymap(self): return super(CompletingReader, self).collect_keymap() + ( (r'\t', 'complete'),) - + def __init__(self, console): super(CompletingReader, self).__init__(console) self.cmpltn_menu = ["[ menu 1 ]", "[ menu 2 ]"] self.cmpltn_menu_vis = 0 self.cmpltn_menu_end = 0 - for c in [complete, self_insert]: + for c in (complete, self_insert): self.commands[c.__name__] = c - self.commands[c.__name__.replace('_', '-')] = c + self.commands[c.__name__.replace('_', '-')] = c def after_command(self, cmd): super(CompletingReader, self).after_command(cmd) - if not isinstance(cmd, self.commands['complete']) \ - and not isinstance(cmd, self.commands['self_insert']): + if not isinstance(cmd, (complete, self_insert)): self.cmpltn_reset() def calc_screen(self): @@ -243,7 +250,7 @@ self.cmpltn_menu = [] self.cmpltn_menu_vis = 0 self.cmpltn_menu_end = 0 - self.cmpltn_menu_choices = [] + self.cmpltn_menu_choices = [] def get_stem(self): st = self.syntax_table @@ -257,11 +264,14 @@ def get_completions(self, stem): return [] + def test(): class TestReader(CompletingReader): def get_completions(self, stem): - return [s for l in map(lambda x:x.split(),self.history) - for s in l if s and s.startswith(stem)] + return [s for l in self.history + for s in l.split() + if s and s.startswith(stem)] + reader = TestReader() reader.ps1 = "c**> " reader.ps2 = "c/*> " @@ -270,5 +280,6 @@ while reader.readline(): pass -if __name__=='__main__': + +if __name__ == '__main__': test() diff --git a/pyrepl/console.py b/pyrepl/console.py --- a/pyrepl/console.py +++ b/pyrepl/console.py @@ -17,6 +17,7 @@ # CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + class Event(object): """An Event. `evt' is 'key' or somesuch.""" __slots__ = 'evt', 'data', 'raw' @@ -27,7 +28,8 @@ self.raw = raw def __repr__(self): - return 'Event(%r, %r)'%(self.evt, self.data) + return 'Event(%r, %r)' % (self.evt, self.data) + class Console(object): """Attributes: @@ -36,7 +38,7 @@ height, width, """ - + def refresh(self, screen, xy): pass diff --git a/pyrepl/unix_eventqueue.py b/pyrepl/unix_eventqueue.py --- a/pyrepl/unix_eventqueue.py +++ b/pyrepl/unix_eventqueue.py @@ -21,6 +21,8 @@ # Bah, this would be easier to test if curses/terminfo didn't have so # much non-introspectable global state. +from collections import deque + from pyrepl import keymap from pyrepl.console import Event from pyrepl import curses @@ -34,23 +36,23 @@ _keynames = { - "delete" : "kdch1", - "down" : "kcud1", - "end" : "kend", - "enter" : "kent", - "f1" : "kf1", "f2" : "kf2", "f3" : "kf3", "f4" : "kf4", - "f5" : "kf5", "f6" : "kf6", "f7" : "kf7", "f8" : "kf8", - "f9" : "kf9", "f10" : "kf10", "f11" : "kf11", "f12" : "kf12", - "f13" : "kf13", "f14" : "kf14", "f15" : "kf15", "f16" : "kf16", - "f17" : "kf17", "f18" : "kf18", "f19" : "kf19", "f20" : "kf20", - "home" : "khome", - "insert" : "kich1", - "left" : "kcub1", - "page down" : "knp", - "page up" : "kpp", - "right" : "kcuf1", - "up" : "kcuu1", - } + "delete": "kdch1", + "down": "kcud1", + "end": "kend", + "enter": "kent", + "home": "khome", + "insert": "kich1", + "left": "kcub1", + "page down": "knp", + "page up": "kpp", + "right": "kcuf1", + "up": "kcuu1", +} + + +#function keys x in 1-20 -> fX: kfX +_keynames.update(('f%d' % i, 'kf%d' % i) for i in range(1, 21)) + def general_keycodes(): keycodes = {} @@ -62,7 +64,6 @@ return keycodes - def EventQueue(fd, encoding): keycodes = general_keycodes() if os.isatty(fd): @@ -72,16 +73,17 @@ trace('keymap {k!r}', k=k) return EncodedQueue(k, encoding) + class EncodedQueue(object): def __init__(self, keymap, encoding): self.k = self.ck = keymap - self.events = [] + self.events = deque() self.buf = bytearray() - self.encoding=encoding + self.encoding = encoding def get(self): if self.events: - return self.events.pop(0) + return self.events.popleft() else: return None diff --git a/setup.py b/setup.py --- a/setup.py +++ b/setup.py @@ -17,7 +17,7 @@ # CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -from setuptools import setup, Extension +from setuptools import setup long_desc = """\ pyrepl is a Python library, inspired by readline, for building flexible @@ -31,17 +31,17 @@ setup( - name = "pyrepl", - version = "0.8.4", - author = "Michael Hudson-Doyle", - author_email = "micahel at gmail.com", + name="pyrepl", + version="0.8.4", + author="Michael Hudson-Doyle", + author_email="micahel at gmail.com", maintainer="Ronny Pfannschmidt", maintainer_email="ronny.pfannschmidt at gmx.de", - url = "http://bitbucket.org/pypy/pyrepl/", - license = "MIT X11 style", - description = "A library for building flexible command line interfaces", - platforms = ["unix", "linux"], - packages = ["pyrepl" ], - scripts = ["pythoni", "pythoni1"], - long_description = long_desc, - ) + url="http://bitbucket.org/pypy/pyrepl/", + license="MIT X11 style", + description="A library for building flexible command line interfaces", + platforms=["unix", "linux"], + packages=["pyrepl"], + scripts=["pythoni", "pythoni1"], + long_description=long_desc, +) diff --git a/testing/test_unix_reader.py b/testing/test_unix_reader.py --- a/testing/test_unix_reader.py +++ b/testing/test_unix_reader.py @@ -1,9 +1,6 @@ from __future__ import unicode_literals from pyrepl.unix_eventqueue import EncodedQueue -from pyrepl import curses - - def test_simple(): q = EncodedQueue({}, 'utf-8') diff --git a/testing/test_wishes.py b/testing/test_wishes.py --- a/testing/test_wishes.py +++ b/testing/test_wishes.py @@ -24,8 +24,8 @@ def test_quoted_insert_repeat(): - read_spec([(('digit-arg', '3'), ['']), - (('quoted-insert', None), ['']), - (('self-insert', '\033'), ['^[^[^[']), - (('accept', None), None)]) - + read_spec([ + (('digit-arg', '3'), ['']), + (('quoted-insert', None), ['']), + (('self-insert', '\033'), ['^[^[^[']), + (('accept', None), None)]) From noreply at buildbot.pypy.org Sun Feb 10 00:55:25 2013 From: noreply at buildbot.pypy.org (RonnyPfannschmidt) Date: Sun, 10 Feb 2013 00:55:25 +0100 (CET) Subject: [pypy-commit] pyrepl codecheck-clean: slight refactoring of the unix reader to start cleaning up some messes Message-ID: <20130209235525.1E36B1C080A@cobra.cs.uni-duesseldorf.de> Author: Ronny Pfannschmidt Branch: codecheck-clean Changeset: r227:5ee7b6b755d0 Date: 2013-01-16 21:17 +0100 http://bitbucket.org/pypy/pyrepl/changeset/5ee7b6b755d0/ Log: slight refactoring of the unix reader to start cleaning up some messes diff --git a/pyrepl/unix_console.py b/pyrepl/unix_console.py --- a/pyrepl/unix_console.py +++ b/pyrepl/unix_console.py @@ -63,7 +63,7 @@ # at this point, can we say: AAAAAAAAAAAAAAAAAAAAAARGH! def maybe_add_baudrate(dict, rate): - name = 'B%d'%rate + name = 'B%d' % rate if hasattr(termios, name): dict[getattr(termios, name)] = rate @@ -89,12 +89,18 @@ self.fd = fd def poll(self, timeout=None): - r, w, e = select.select([self.fd],[],[],timeout) + r, w, e = select.select([self.fd], [], [], timeout) return r POLLIN = getattr(select, "POLLIN", None) +required_curses_tistrings = 'bel clear cup el' +optional_curses_tistrings = ( + 'civis cnorm cub cub1 cud cud1 cud cud1 cuf ' + 'cuf1 cuu cuu1 dch dch1 hpa ich ich1 ind pad ri rmkx smkx') + + class UnixConsole(Console): def __init__(self, f_in=0, f_out=1, term=None, encoding=None): if encoding is None: @@ -117,33 +123,15 @@ curses.setupterm(term, self.output_fd) self.term = term - self._bel = _my_getstr("bel") - self._civis = _my_getstr("civis", optional=1) - self._clear = _my_getstr("clear") - self._cnorm = _my_getstr("cnorm", optional=1) - self._cub = _my_getstr("cub", optional=1) - self._cub1 = _my_getstr("cub1", 1) - self._cud = _my_getstr("cud", 1) - self._cud1 = _my_getstr("cud1", 1) - self._cuf = _my_getstr("cuf", 1) - self._cuf1 = _my_getstr("cuf1", 1) - self._cup = _my_getstr("cup") - self._cuu = _my_getstr("cuu", 1) - self._cuu1 = _my_getstr("cuu1", 1) - self._dch1 = _my_getstr("dch1", 1) - self._dch = _my_getstr("dch", 1) - self._el = _my_getstr("el") - self._hpa = _my_getstr("hpa", 1) - self._ich = _my_getstr("ich", 1) - self._ich1 = _my_getstr("ich1", 1) - self._ind = _my_getstr("ind", 1) - self._pad = _my_getstr("pad", 1) - self._ri = _my_getstr("ri", 1) - self._rmkx = _my_getstr("rmkx", 1) - self._smkx = _my_getstr("smkx", 1) - + for name in required_curses_tistrings.split(): + setattr(self, '_' + name, _my_getstr(name)) + + for name in optional_curses_tistrings.split(): + setattr(self, '_' + name, _my_getstr(name, optional=1)) + ## work out how we're going to sling the cursor around - if 0 and self._hpa: # hpa don't work in windows telnet :-( + # hpa don't work in windows telnet :-( + if 0 and self._hpa: self.__move_x = self.__move_x_hpa elif self._cub and self._cuf: self.__move_x = self.__move_x_cub_cuf @@ -264,11 +252,12 @@ # reuse the oldline as much as possible, but stop as soon as we # encounter an ESCAPE, because it might be the start of an escape # sequene + #XXX unicode check! while x < minlen and oldline[x] == newline[x] and newline[x] != '\x1b': x += 1 if oldline[x:] == newline[x+1:] and self.ich1: - if ( y == self.__posxy[1] and x > self.__posxy[0] - and oldline[px:x] == newline[px+1:x+1] ): + if (y == self.__posxy[1] and x > self.__posxy[0] and + oldline[px:x] == newline[px+1:x+1]): x = px self.__move(x, y) self.__write_code(self.ich1) @@ -297,6 +286,7 @@ self.__write(newline[x:]) self.__posxy = len(newline), y + #XXX: check for unicode mess if '\x1b' in newline: # ANSI escape characters are present, so we can't assume # anything about the position of the cursor. Moving the cursor @@ -367,12 +357,12 @@ self.__svtermstate = tcgetattr(self.input_fd) raw = self.__svtermstate.copy() raw.iflag |= termios.ICRNL - raw.iflag &=~ (termios.BRKINT | termios.INPCK | + raw.iflag &= ~(termios.BRKINT | termios.INPCK | termios.ISTRIP | termios.IXON) - raw.oflag &=~ (termios.OPOST) - raw.cflag &=~ (termios.CSIZE | termios.PARENB) - raw.cflag |= (termios.CS8) - raw.lflag &=~ (termios.ICANON | termios.ECHO| + raw.oflag &= ~termios.OPOST + raw.cflag &= ~(termios.CSIZE | termios.PARENB) + raw.cflag |= (termios.CS8) + raw.lflag &= ~(termios.ICANON | termios.ECHO | termios.IEXTEN | (termios.ISIG * 1)) raw.cc[termios.VMIN] = 1 raw.cc[termios.VTIME] = 0 @@ -414,7 +404,7 @@ def get_event(self, block=1): while self.event_queue.empty(): - while 1: + while 1: # All hail Unix! try: self.push_char(os.read(self.input_fd, 1)) @@ -541,7 +531,9 @@ amount = struct.unpack( "i", ioctl(self.input_fd, FIONREAD, "\0\0\0\0"))[0] - raw = unicode(os.read(self.input_fd, amount), self.encoding, 'replace') + data = os.read(self.input_fd, amount) + raw = unicode(data, self.encoding, 'replace') + #XXX: something is wrong here e.data += raw e.raw += raw return e @@ -553,9 +545,11 @@ e2 = self.event_queue.get() e.data += e2.data e.raw += e.raw - + amount = 10000 - raw = unicode(os.read(self.input_fd, amount), self.encoding, 'replace') + data = os.read(self.input_fd, amount) + raw = unicode(data, self.encoding, 'replace') + #XXX: something is wrong here e.data += raw e.raw += raw return e @@ -566,4 +560,3 @@ self.__move = self.__move_tall self.__posxy = 0, 0 self.screen = [] - From noreply at buildbot.pypy.org Sun Feb 10 00:55:20 2013 From: noreply at buildbot.pypy.org (RonnyPfannschmidt) Date: Sun, 10 Feb 2013 00:55:20 +0100 (CET) Subject: [pypy-commit] pyrepl codecheck-clean: more codecheck cleans Message-ID: <20130209235520.055C61C1047@cobra.cs.uni-duesseldorf.de> Author: Ronny Pfannschmidt Branch: codecheck-clean Changeset: r222:099eed38e5fd Date: 2013-01-15 23:13 +0100 http://bitbucket.org/pypy/pyrepl/changeset/099eed38e5fd/ Log: more codecheck cleans diff --git a/pyrepl/unix_eventqueue.py b/pyrepl/unix_eventqueue.py --- a/pyrepl/unix_eventqueue.py +++ b/pyrepl/unix_eventqueue.py @@ -100,7 +100,7 @@ self.events.append(event) def push(self, char): - self.buf.append(char) + self.buf.append(ord(char)) if char in self.k: if self.k is self.ck: #sanity check, buffer is empty when a special key comes diff --git a/testing/infrastructure.py b/testing/infrastructure.py --- a/testing/infrastructure.py +++ b/testing/infrastructure.py @@ -21,11 +21,15 @@ from pyrepl.reader import Reader from pyrepl.console import Console, Event + class EqualsAnything(object): def __eq__(self, other): return True + + EA = EqualsAnything() + class TestConsole(Console): height = 24 width = 80 @@ -38,7 +42,7 @@ def refresh(self, screen, xy): if self.next_screen is not None: - assert screen == self.next_screen, "[ %s != %s after %r ]"%( + assert screen == self.next_screen, "[ %s != %s after %r ]" % ( screen, self.next_screen, self.last_event_name) def get_event(self, block=1): diff --git a/testing/test_basic.py b/testing/test_basic.py --- a/testing/test_basic.py +++ b/testing/test_basic.py @@ -24,23 +24,27 @@ read_spec([(('self-insert', 'a'), ['a']), ( 'accept', ['a'])]) + def test_repeat(): read_spec([(('digit-arg', '3'), ['']), (('self-insert', 'a'), ['aaa']), ( 'accept', ['aaa'])]) + def test_kill_line(): read_spec([(('self-insert', 'abc'), ['abc']), ( 'left', None), ( 'kill-line', ['ab']), ( 'accept', ['ab'])]) + def test_unix_line_discard(): read_spec([(('self-insert', 'abc'), ['abc']), ( 'left', None), ( 'unix-word-rubout', ['c']), ( 'accept', ['c'])]) + def test_kill_word(): read_spec([(('self-insert', 'ab cd'), ['ab cd']), ( 'beginning-of-line', ['ab cd']), diff --git a/testing/test_bugs.py b/testing/test_bugs.py --- a/testing/test_bugs.py +++ b/testing/test_bugs.py @@ -25,13 +25,17 @@ import pytest + class HistoricalTestReader(HistoricalReader, TestReader): pass + @pytest.mark.xfail(reason='event missing', run=False) def test_transpose_at_start(): - read_spec([( 'transpose', [EA, '']), - ( 'accept', [''])]) + read_spec([ + ('transpose', [EA, '']), + ('accept', [''])]) + def test_cmd_instantiation_crash(): spec = [ diff --git a/testing/test_functional.py b/testing/test_functional.py --- a/testing/test_functional.py +++ b/testing/test_functional.py @@ -6,6 +6,7 @@ import pytest import sys + def pytest_funcarg__child(request): try: pexpect = pytest.importorskip('pexpect') @@ -17,8 +18,8 @@ child.sendline('main()') return child + def test_basic(child): child.sendline('a = 3') child.sendline('a') child.expect('3') - diff --git a/testing/test_keymap.py b/testing/test_keymap.py --- a/testing/test_keymap.py +++ b/testing/test_keymap.py @@ -1,4 +1,3 @@ -import pytest from pyrepl.keymap import compile_keymap diff --git a/testing/test_readline.py b/testing/test_readline.py --- a/testing/test_readline.py +++ b/testing/test_readline.py @@ -1,11 +1,13 @@ from pyrepl.readline import _ReadlineWrapper -import os, pty +import os +import pty + def test_raw_input(): readline_wrapper = _ReadlineWrapper() master, slave = pty.openpty() readline_wrapper.f_in = slave - os.write(master, 'input\n') + os.write(master, b'input\n') result = readline_wrapper.raw_input('prompt:') assert result == 'input' # A bytes string on python2, a unicode string on python3. diff --git a/testing/test_unix_reader.py b/testing/test_unix_reader.py --- a/testing/test_unix_reader.py +++ b/testing/test_unix_reader.py @@ -1,6 +1,7 @@ from __future__ import unicode_literals from pyrepl.unix_eventqueue import EncodedQueue + def test_simple(): q = EncodedQueue({}, 'utf-8') @@ -13,4 +14,3 @@ assert q.get() is None assert event.data == a assert event.raw == b - From noreply at buildbot.pypy.org Sun Feb 10 00:55:26 2013 From: noreply at buildbot.pypy.org (RonnyPfannschmidt) Date: Sun, 10 Feb 2013 00:55:26 +0100 (CET) Subject: [pypy-commit] pyrepl default: merge code cleanup branch Message-ID: <20130209235526.412831C080A@cobra.cs.uni-duesseldorf.de> Author: Ronny Pfannschmidt Branch: Changeset: r228:a7fc31cb4fce Date: 2013-01-16 21:19 +0100 http://bitbucket.org/pypy/pyrepl/changeset/a7fc31cb4fce/ Log: merge code cleanup branch diff --git a/pyrepl/copy_code.py b/pyrepl/copy_code.py deleted file mode 100644 --- a/pyrepl/copy_code.py +++ /dev/null @@ -1,73 +0,0 @@ -# Copyright 2000-2004 Michael Hudson-Doyle -# -# All Rights Reserved -# -# -# Permission to use, copy, modify, and distribute this software and -# its documentation for any purpose is hereby granted without fee, -# provided that the above copyright notice appear in all copies and -# that both that copyright notice and this permission notice appear in -# supporting documentation. -# -# THE AUTHOR MICHAEL HUDSON DISCLAIMS ALL WARRANTIES WITH REGARD TO -# THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY -# AND FITNESS, IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, -# INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER -# RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF -# CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -from types import CodeType - -def copy_code_with_changes(codeobject, - argcount=None, - nlocals=None, - stacksize=None, - flags=None, - code=None, - consts=None, - names=None, - varnames=None, - filename=None, - name=None, - firstlineno=None, - lnotab=None): - if argcount is None: argcount = codeobject.co_argcount - if nlocals is None: nlocals = codeobject.co_nlocals - if stacksize is None: stacksize = codeobject.co_stacksize - if flags is None: flags = codeobject.co_flags - if code is None: code = codeobject.co_code - if consts is None: consts = codeobject.co_consts - if names is None: names = codeobject.co_names - if varnames is None: varnames = codeobject.co_varnames - if filename is None: filename = codeobject.co_filename - if name is None: name = codeobject.co_name - if firstlineno is None: firstlineno = codeobject.co_firstlineno - if lnotab is None: lnotab = codeobject.co_lnotab - return CodeType(argcount, - nlocals, - stacksize, - flags, - code, - consts, - names, - varnames, - filename, - name, - firstlineno, - lnotab) - -code_attrs=['argcount', - 'nlocals', - 'stacksize', - 'flags', - 'code', - 'consts', - 'names', - 'varnames', - 'filename', - 'name', - 'firstlineno', - 'lnotab'] - - diff --git a/pyrepl/reader.py b/pyrepl/reader.py --- a/pyrepl/reader.py +++ b/pyrepl/reader.py @@ -143,11 +143,11 @@ (r'\M-8', 'digit-arg'), (r'\M-9', 'digit-arg'), #(r'\M-\n', 'insert-nl'), - ('\\\\', 'self-insert')] + \ + ('\\\\', 'self-insert')] + [(c, 'self-insert') - for c in map(chr, range(32, 127)) if c != '\\'] + \ + for c in map(chr, range(32, 127)) if c != '\\'] + [(c, 'self-insert') - for c in map(chr, range(128, 256)) if c.isalpha()] + \ + for c in map(chr, range(128, 256)) if c.isalpha()] + [(r'\', 'up'), (r'\', 'down'), (r'\', 'left'), @@ -244,9 +244,9 @@ self.commands = {} self.msg = '' for v in vars(commands).values(): - if (isinstance(v, type) - and issubclass(v, commands.Command) - and v.__name__[0].islower()): + if (isinstance(v, type) and + issubclass(v, commands.Command) and + v.__name__[0].islower()): self.commands[v.__name__] = v self.commands[v.__name__.replace('_', '-')] = v self.syntax_table = make_default_syntax_table() diff --git a/pyrepl/readline.py b/pyrepl/readline.py --- a/pyrepl/readline.py +++ b/pyrepl/readline.py @@ -26,7 +26,8 @@ extensions for multiline input. """ -import sys, os +import sys +import os from pyrepl import commands from pyrepl.historical_reader import HistoricalReader from pyrepl.completing_reader import CompletingReader @@ -35,41 +36,43 @@ ENCODING = sys.getfilesystemencoding() or 'latin1' # XXX review -__all__ = ['add_history', - 'clear_history', - 'get_begidx', - 'get_completer', - 'get_completer_delims', - 'get_current_history_length', - 'get_endidx', - 'get_history_item', - 'get_history_length', - 'get_line_buffer', - 'insert_text', - 'parse_and_bind', - 'read_history_file', - 'read_init_file', - 'redisplay', - 'remove_history_item', - 'replace_history_item', - 'set_completer', - 'set_completer_delims', - 'set_history_length', - 'set_pre_input_hook', - 'set_startup_hook', - 'write_history_file', - # ---- multiline extensions ---- - 'multiline_input', - ] +__all__ = [ + 'add_history', + 'clear_history', + 'get_begidx', + 'get_completer', + 'get_completer_delims', + 'get_current_history_length', + 'get_endidx', + 'get_history_item', + 'get_history_length', + 'get_line_buffer', + 'insert_text', + 'parse_and_bind', + 'read_history_file', + 'read_init_file', + 'redisplay', + 'remove_history_item', + 'replace_history_item', + 'set_completer', + 'set_completer_delims', + 'set_history_length', + 'set_pre_input_hook', + 'set_startup_hook', + 'write_history_file', + # ---- multiline extensions ---- + 'multiline_input', +] # ____________________________________________________________ + class ReadlineConfig(object): readline_completer = None completer_delims = dict.fromkeys(' \t\n`~!@#$%^&*()-=+[{]}\\|;:\'",<>/?') + class ReadlineAlikeReader(HistoricalReader, CompletingReader): - assume_immutable_completions = False use_brackets = False sort_in_column = True @@ -156,10 +159,11 @@ if self.pos > len(self.buffer): self.pos = len(self.buffer) + class maybe_accept(commands.Command): def do(self): r = self.reader - r.dirty = 1 # this is needed to hide the completion menu, if visible + r.dirty = 1 # this is needed to hide the completion menu, if visible # # if there are already several lines and the cursor # is not on the last one, always insert a new \n. @@ -171,7 +175,6 @@ else: self.finish = 1 -# ____________________________________________________________ class _ReadlineWrapper(object): reader = None @@ -369,6 +372,7 @@ # ____________________________________________________________ # Stubs + def _make_stub(_name, _ret): def stub(*args, **kwds): import warnings @@ -380,16 +384,16 @@ ('read_init_file', None), ('redisplay', None), ('set_pre_input_hook', None), - ]: +]: assert _name not in globals(), _name _make_stub(_name, _ret) -# ____________________________________________________________ def _setup(): global _old_raw_input if _old_raw_input is not None: - return # don't run _setup twice + return + # don't run _setup twice try: f_in = sys.stdin.fileno() diff --git a/pyrepl/simple_interact.py b/pyrepl/simple_interact.py --- a/pyrepl/simple_interact.py +++ b/pyrepl/simple_interact.py @@ -26,6 +26,7 @@ import sys from pyrepl.readline import multiline_input, _error, _get_reader + def check(): # returns False if there is a problem initializing the state try: _get_reader() @@ -33,6 +34,7 @@ return False return True + def run_multiline_interactive_console(mainmodule=None): import code import __main__ diff --git a/pyrepl/unix_console.py b/pyrepl/unix_console.py --- a/pyrepl/unix_console.py +++ b/pyrepl/unix_console.py @@ -19,8 +19,15 @@ # CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -import termios, select, os, struct, errno -import signal, re, time, sys +import termios +import select +import os +import struct +import errno +import signal +import re +import time +import sys from fcntl import ioctl from . import curses from .fancy_termios import tcgetattr, tcsetattr @@ -28,6 +35,7 @@ from .unix_eventqueue import EventQueue from .trace import trace + class InvalidTerminal(RuntimeError): pass @@ -44,16 +52,18 @@ FIONREAD = getattr(termios, "FIONREAD", None) TIOCGWINSZ = getattr(termios, "TIOCGWINSZ", None) + def _my_getstr(cap, optional=0): r = curses.tigetstr(cap) if not optional and r is None: raise InvalidTerminal( - "terminal doesn't have the required '%s' capability"%cap) + "terminal doesn't have the required '%s' capability" % cap) return r + # at this point, can we say: AAAAAAAAAAAAAAAAAAAAAARGH! def maybe_add_baudrate(dict, rate): - name = 'B%d'%rate + name = 'B%d' % rate if hasattr(termios, name): dict[getattr(termios, name)] = rate @@ -74,19 +84,28 @@ class poll: def __init__(self): pass + def register(self, fd, flag): self.fd = fd + def poll(self, timeout=None): - r,w,e = select.select([self.fd],[],[],timeout) + r, w, e = select.select([self.fd], [], [], timeout) return r POLLIN = getattr(select, "POLLIN", None) + +required_curses_tistrings = 'bel clear cup el' +optional_curses_tistrings = ( + 'civis cnorm cub cub1 cud cud1 cud cud1 cuf ' + 'cuf1 cuu cuu1 dch dch1 hpa ich ich1 ind pad ri rmkx smkx') + + class UnixConsole(Console): def __init__(self, f_in=0, f_out=1, term=None, encoding=None): if encoding is None: encoding = sys.getdefaultencoding() - + self.encoding = encoding if isinstance(f_in, int): @@ -98,40 +117,21 @@ self.output_fd = f_out else: self.output_fd = f_out.fileno() - self.pollob = poll() self.pollob.register(self.input_fd, POLLIN) curses.setupterm(term, self.output_fd) self.term = term - - self._bel = _my_getstr("bel") - self._civis = _my_getstr("civis", optional=1) - self._clear = _my_getstr("clear") - self._cnorm = _my_getstr("cnorm", optional=1) - self._cub = _my_getstr("cub", optional=1) - self._cub1 = _my_getstr("cub1", 1) - self._cud = _my_getstr("cud", 1) - self._cud1 = _my_getstr("cud1", 1) - self._cuf = _my_getstr("cuf", 1) - self._cuf1 = _my_getstr("cuf1", 1) - self._cup = _my_getstr("cup") - self._cuu = _my_getstr("cuu", 1) - self._cuu1 = _my_getstr("cuu1", 1) - self._dch1 = _my_getstr("dch1", 1) - self._dch = _my_getstr("dch", 1) - self._el = _my_getstr("el") - self._hpa = _my_getstr("hpa", 1) - self._ich = _my_getstr("ich", 1) - self._ich1 = _my_getstr("ich1", 1) - self._ind = _my_getstr("ind", 1) - self._pad = _my_getstr("pad", 1) - self._ri = _my_getstr("ri", 1) - self._rmkx = _my_getstr("rmkx", 1) - self._smkx = _my_getstr("smkx", 1) - + + for name in required_curses_tistrings.split(): + setattr(self, '_' + name, _my_getstr(name)) + + for name in optional_curses_tistrings.split(): + setattr(self, '_' + name, _my_getstr(name, optional=1)) + ## work out how we're going to sling the cursor around - if 0 and self._hpa: # hpa don't work in windows telnet :-( + # hpa don't work in windows telnet :-( + if 0 and self._hpa: self.__move_x = self.__move_x_hpa elif self._cub and self._cuf: self.__move_x = self.__move_x_cub_cuf @@ -166,9 +166,6 @@ self.event_queue = EventQueue(self.input_fd, self.encoding) self.cursor_visible = 1 - def change_encoding(self, encoding): - self.encoding = encoding - def refresh(self, screen, c_xy): # this function is still too long (over 90 lines) cx, cy = c_xy @@ -181,7 +178,7 @@ self.screen.append("") else: while len(self.screen) < len(screen): - self.screen.append("") + self.screen.append("") if len(screen) > self.height: self.__gone_tall = 1 @@ -191,7 +188,6 @@ old_offset = offset = self.__offset height = self.height - # we make sure the cursor is on the screen, and that we're # using all of the screen if we can if cy < offset: @@ -230,7 +226,7 @@ newscr): if oldline != newline: self.__write_changed_line(y, oldline, newline, px) - + y = len(newscr) while y < len(oldscr): self.__hide_cursor() @@ -240,7 +236,7 @@ y += 1 self.__show_cursor() - + self.screen = screen self.move_cursor(cx, cy) self.flushoutput() @@ -256,11 +252,12 @@ # reuse the oldline as much as possible, but stop as soon as we # encounter an ESCAPE, because it might be the start of an escape # sequene + #XXX unicode check! while x < minlen and oldline[x] == newline[x] and newline[x] != '\x1b': x += 1 if oldline[x:] == newline[x+1:] and self.ich1: - if ( y == self.__posxy[1] and x > self.__posxy[0] - and oldline[px:x] == newline[px+1:x+1] ): + if (y == self.__posxy[1] and x > self.__posxy[0] and + oldline[px:x] == newline[px+1:x+1]): x = px self.__move(x, y) self.__write_code(self.ich1) @@ -288,7 +285,8 @@ self.__write_code(self._el) self.__write(newline[x:]) self.__posxy = len(newline), y - + + #XXX: check for unicode mess if '\x1b' in newline: # ANSI escape characters are present, so we can't assume # anything about the position of the cursor. Moving the cursor @@ -359,13 +357,13 @@ self.__svtermstate = tcgetattr(self.input_fd) raw = self.__svtermstate.copy() raw.iflag |= termios.ICRNL - raw.iflag &=~ (termios.BRKINT | termios.INPCK | + raw.iflag &= ~(termios.BRKINT | termios.INPCK | termios.ISTRIP | termios.IXON) - raw.oflag &=~ (termios.OPOST) - raw.cflag &=~ (termios.CSIZE|termios.PARENB) - raw.cflag |= (termios.CS8) - raw.lflag &=~ (termios.ICANON|termios.ECHO| - termios.IEXTEN|(termios.ISIG*1)) + raw.oflag &= ~termios.OPOST + raw.cflag &= ~(termios.CSIZE | termios.PARENB) + raw.cflag |= (termios.CS8) + raw.lflag &= ~(termios.ICANON | termios.ECHO | + termios.IEXTEN | (termios.ISIG * 1)) raw.cc[termios.VMIN] = 1 raw.cc[termios.VTIME] = 0 tcsetattr(self.input_fd, termios.TCSADRAIN, raw) @@ -374,7 +372,7 @@ self.height, self.width = self.getheightwidth() self.__buffer = [] - + self.__posxy = 0, 0 self.__gone_tall = 0 self.__move = self.__move_short @@ -403,10 +401,11 @@ def push_char(self, char): trace('push char {char!r}', char=char) self.event_queue.push(char) - + def get_event(self, block=1): while self.event_queue.empty(): - while 1: # All hail Unix! + while 1: + # All hail Unix! try: self.push_char(os.read(self.input_fd, 1)) except (IOError, OSError) as err: @@ -461,7 +460,8 @@ except KeyError: height, width = struct.unpack( "hhhh", ioctl(self.input_fd, TIOCGWINSZ, "\000"*8))[0:2] - if not height: return 25, 80 + if not height: + return 25, 80 return height, width else: def getheightwidth(self): @@ -528,10 +528,12 @@ e2 = self.event_queue.get() e.data += e2.data e.raw += e.raw - + amount = struct.unpack( "i", ioctl(self.input_fd, FIONREAD, "\0\0\0\0"))[0] - raw = unicode(os.read(self.input_fd, amount), self.encoding, 'replace') + data = os.read(self.input_fd, amount) + raw = unicode(data, self.encoding, 'replace') + #XXX: something is wrong here e.data += raw e.raw += raw return e @@ -543,9 +545,11 @@ e2 = self.event_queue.get() e.data += e2.data e.raw += e.raw - + amount = 10000 - raw = unicode(os.read(self.input_fd, amount), self.encoding, 'replace') + data = os.read(self.input_fd, amount) + raw = unicode(data, self.encoding, 'replace') + #XXX: something is wrong here e.data += raw e.raw += raw return e @@ -556,4 +560,3 @@ self.__move = self.__move_tall self.__posxy = 0, 0 self.screen = [] - diff --git a/pyrepl/unix_eventqueue.py b/pyrepl/unix_eventqueue.py --- a/pyrepl/unix_eventqueue.py +++ b/pyrepl/unix_eventqueue.py @@ -100,7 +100,7 @@ self.events.append(event) def push(self, char): - self.buf.append(char) + self.buf.append(ord(char)) if char in self.k: if self.k is self.ck: #sanity check, buffer is empty when a special key comes diff --git a/testing/infrastructure.py b/testing/infrastructure.py --- a/testing/infrastructure.py +++ b/testing/infrastructure.py @@ -21,11 +21,15 @@ from pyrepl.reader import Reader from pyrepl.console import Console, Event + class EqualsAnything(object): def __eq__(self, other): return True + + EA = EqualsAnything() + class TestConsole(Console): height = 24 width = 80 @@ -38,7 +42,7 @@ def refresh(self, screen, xy): if self.next_screen is not None: - assert screen == self.next_screen, "[ %s != %s after %r ]"%( + assert screen == self.next_screen, "[ %s != %s after %r ]" % ( screen, self.next_screen, self.last_event_name) def get_event(self, block=1): @@ -51,18 +55,19 @@ print("event", ev) return Event(*ev) + class TestReader(Reader): def get_prompt(self, lineno, cursor_on_line): return '' - + def refresh(self): Reader.refresh(self) self.dirty = True + def read_spec(test_spec, reader_class=TestReader): # remember to finish your test_spec with 'accept' or similar! con = TestConsole(test_spec, verbose=True) reader = reader_class(con) reader.readline() - diff --git a/testing/test_basic.py b/testing/test_basic.py --- a/testing/test_basic.py +++ b/testing/test_basic.py @@ -24,41 +24,48 @@ read_spec([(('self-insert', 'a'), ['a']), ( 'accept', ['a'])]) + def test_repeat(): read_spec([(('digit-arg', '3'), ['']), (('self-insert', 'a'), ['aaa']), ( 'accept', ['aaa'])]) + def test_kill_line(): read_spec([(('self-insert', 'abc'), ['abc']), ( 'left', None), ( 'kill-line', ['ab']), ( 'accept', ['ab'])]) + def test_unix_line_discard(): read_spec([(('self-insert', 'abc'), ['abc']), ( 'left', None), ( 'unix-word-rubout', ['c']), ( 'accept', ['c'])]) + def test_kill_word(): read_spec([(('self-insert', 'ab cd'), ['ab cd']), ( 'beginning-of-line', ['ab cd']), ( 'kill-word', [' cd']), ( 'accept', [' cd'])]) + def test_backward_kill_word(): read_spec([(('self-insert', 'ab cd'), ['ab cd']), ( 'backward-kill-word', ['ab ']), ( 'accept', ['ab '])]) + def test_yank(): read_spec([(('self-insert', 'ab cd'), ['ab cd']), ( 'backward-kill-word', ['ab ']), ( 'beginning-of-line', ['ab ']), ( 'yank', ['cdab ']), ( 'accept', ['cdab '])]) - + + def test_yank_pop(): read_spec([(('self-insert', 'ab cd'), ['ab cd']), ( 'backward-kill-word', ['ab ']), @@ -68,18 +75,20 @@ ( 'yank-pop', ['cd ']), ( 'accept', ['cd '])]) + def test_interrupt(): with pytest.raises(KeyboardInterrupt): - read_spec([( 'interrupt', [''])]) + read_spec([('interrupt', [''])]) + # test_suspend -- hah - def test_up(): read_spec([(('self-insert', 'ab\ncd'), ['ab', 'cd']), ( 'up', ['ab', 'cd']), (('self-insert', 'e'), ['abe', 'cd']), ( 'accept', ['abe', 'cd'])]) + def test_down(): read_spec([(('self-insert', 'ab\ncd'), ['ab', 'cd']), ( 'up', ['ab', 'cd']), @@ -88,12 +97,14 @@ (('self-insert', 'f'), ['abe', 'cdf']), ( 'accept', ['abe', 'cdf'])]) + def test_left(): read_spec([(('self-insert', 'ab'), ['ab']), ( 'left', ['ab']), (('self-insert', 'c'), ['acb']), ( 'accept', ['acb'])]) + def test_right(): read_spec([(('self-insert', 'ab'), ['ab']), ( 'left', ['ab']), @@ -101,4 +112,3 @@ ( 'right', ['acb']), (('self-insert', 'd'), ['acbd']), ( 'accept', ['acbd'])]) - diff --git a/testing/test_bugs.py b/testing/test_bugs.py --- a/testing/test_bugs.py +++ b/testing/test_bugs.py @@ -25,13 +25,17 @@ import pytest + class HistoricalTestReader(HistoricalReader, TestReader): pass + @pytest.mark.xfail(reason='event missing', run=False) def test_transpose_at_start(): - read_spec([( 'transpose', [EA, '']), - ( 'accept', [''])]) + read_spec([ + ('transpose', [EA, '']), + ('accept', [''])]) + def test_cmd_instantiation_crash(): spec = [ diff --git a/testing/test_functional.py b/testing/test_functional.py --- a/testing/test_functional.py +++ b/testing/test_functional.py @@ -6,6 +6,7 @@ import pytest import sys + def pytest_funcarg__child(request): try: pexpect = pytest.importorskip('pexpect') @@ -17,8 +18,8 @@ child.sendline('main()') return child + def test_basic(child): child.sendline('a = 3') child.sendline('a') child.expect('3') - diff --git a/testing/test_keymap.py b/testing/test_keymap.py --- a/testing/test_keymap.py +++ b/testing/test_keymap.py @@ -1,4 +1,3 @@ -import pytest from pyrepl.keymap import compile_keymap diff --git a/testing/test_readline.py b/testing/test_readline.py --- a/testing/test_readline.py +++ b/testing/test_readline.py @@ -1,13 +1,14 @@ from pyrepl.readline import _ReadlineWrapper -import os, pty +import os +import pty + def test_raw_input(): readline_wrapper = _ReadlineWrapper() master, slave = pty.openpty() readline_wrapper.f_in = slave - os.write(master, 'input\n') + os.write(master, b'input\n') result = readline_wrapper.raw_input('prompt:') assert result == 'input' # A bytes string on python2, a unicode string on python3. assert isinstance(result, str) - diff --git a/testing/test_unix_reader.py b/testing/test_unix_reader.py --- a/testing/test_unix_reader.py +++ b/testing/test_unix_reader.py @@ -1,6 +1,7 @@ from __future__ import unicode_literals from pyrepl.unix_eventqueue import EncodedQueue + def test_simple(): q = EncodedQueue({}, 'utf-8') @@ -13,4 +14,3 @@ assert q.get() is None assert event.data == a assert event.raw == b - From noreply at buildbot.pypy.org Sun Feb 10 00:55:21 2013 From: noreply at buildbot.pypy.org (RonnyPfannschmidt) Date: Sun, 10 Feb 2013 00:55:21 +0100 (CET) Subject: [pypy-commit] pyrepl codecheck-clean: final testing codecheck fixes Message-ID: <20130209235521.014061C118C@cobra.cs.uni-duesseldorf.de> Author: Ronny Pfannschmidt Branch: codecheck-clean Changeset: r223:f37cfe591296 Date: 2013-01-15 23:19 +0100 http://bitbucket.org/pypy/pyrepl/changeset/f37cfe591296/ Log: final testing codecheck fixes diff --git a/testing/infrastructure.py b/testing/infrastructure.py --- a/testing/infrastructure.py +++ b/testing/infrastructure.py @@ -55,18 +55,19 @@ print("event", ev) return Event(*ev) + class TestReader(Reader): def get_prompt(self, lineno, cursor_on_line): return '' - + def refresh(self): Reader.refresh(self) self.dirty = True + def read_spec(test_spec, reader_class=TestReader): # remember to finish your test_spec with 'accept' or similar! con = TestConsole(test_spec, verbose=True) reader = reader_class(con) reader.readline() - diff --git a/testing/test_basic.py b/testing/test_basic.py --- a/testing/test_basic.py +++ b/testing/test_basic.py @@ -51,18 +51,21 @@ ( 'kill-word', [' cd']), ( 'accept', [' cd'])]) + def test_backward_kill_word(): read_spec([(('self-insert', 'ab cd'), ['ab cd']), ( 'backward-kill-word', ['ab ']), ( 'accept', ['ab '])]) + def test_yank(): read_spec([(('self-insert', 'ab cd'), ['ab cd']), ( 'backward-kill-word', ['ab ']), ( 'beginning-of-line', ['ab ']), ( 'yank', ['cdab ']), ( 'accept', ['cdab '])]) - + + def test_yank_pop(): read_spec([(('self-insert', 'ab cd'), ['ab cd']), ( 'backward-kill-word', ['ab ']), @@ -72,18 +75,20 @@ ( 'yank-pop', ['cd ']), ( 'accept', ['cd '])]) + def test_interrupt(): with pytest.raises(KeyboardInterrupt): - read_spec([( 'interrupt', [''])]) + read_spec([('interrupt', [''])]) + # test_suspend -- hah - def test_up(): read_spec([(('self-insert', 'ab\ncd'), ['ab', 'cd']), ( 'up', ['ab', 'cd']), (('self-insert', 'e'), ['abe', 'cd']), ( 'accept', ['abe', 'cd'])]) + def test_down(): read_spec([(('self-insert', 'ab\ncd'), ['ab', 'cd']), ( 'up', ['ab', 'cd']), @@ -92,12 +97,14 @@ (('self-insert', 'f'), ['abe', 'cdf']), ( 'accept', ['abe', 'cdf'])]) + def test_left(): read_spec([(('self-insert', 'ab'), ['ab']), ( 'left', ['ab']), (('self-insert', 'c'), ['acb']), ( 'accept', ['acb'])]) + def test_right(): read_spec([(('self-insert', 'ab'), ['ab']), ( 'left', ['ab']), @@ -105,4 +112,3 @@ ( 'right', ['acb']), (('self-insert', 'd'), ['acbd']), ( 'accept', ['acbd'])]) - diff --git a/testing/test_readline.py b/testing/test_readline.py --- a/testing/test_readline.py +++ b/testing/test_readline.py @@ -12,4 +12,3 @@ assert result == 'input' # A bytes string on python2, a unicode string on python3. assert isinstance(result, str) - From noreply at buildbot.pypy.org Sun Feb 10 00:55:27 2013 From: noreply at buildbot.pypy.org (RonnyPfannschmidt) Date: Sun, 10 Feb 2013 00:55:27 +0100 (CET) Subject: [pypy-commit] pyrepl default: support filenos as args for readline wrapper Message-ID: <20130209235527.4B9641C080A@cobra.cs.uni-duesseldorf.de> Author: Ronny Pfannschmidt Branch: Changeset: r229:b7de2cb80611 Date: 2013-01-18 09:38 +0100 http://bitbucket.org/pypy/pyrepl/changeset/b7de2cb80611/ Log: support filenos as args for readline wrapper diff --git a/pyrepl/readline.py b/pyrepl/readline.py --- a/pyrepl/readline.py +++ b/pyrepl/readline.py @@ -182,9 +182,9 @@ startup_hook = None config = ReadlineConfig() - def __init__(self): - self.f_in = os.dup(0) - self.f_out = os.dup(1) + def __init__(self, f_in=None, f_out=None): + self.f_in = f_in if f_in is not None else os.dup(0) + self.f_out = f_out if f_out is not None else os.dup(1) def get_reader(self): if self.reader is None: diff --git a/testing/test_readline.py b/testing/test_readline.py --- a/testing/test_readline.py +++ b/testing/test_readline.py @@ -4,11 +4,12 @@ def test_raw_input(): - readline_wrapper = _ReadlineWrapper() master, slave = pty.openpty() - readline_wrapper.f_in = slave + readline_wrapper = _ReadlineWrapper(slave, slave) os.write(master, b'input\n') - result = readline_wrapper.raw_input('prompt:') + + result = readline_wrapper.get_reader().readline() + #result = readline_wrapper.raw_input('prompt:') assert result == 'input' # A bytes string on python2, a unicode string on python3. assert isinstance(result, str) From noreply at buildbot.pypy.org Sun Feb 10 00:55:28 2013 From: noreply at buildbot.pypy.org (RonnyPfannschmidt) Date: Sun, 10 Feb 2013 00:55:28 +0100 (CET) Subject: [pypy-commit] pyrepl default: add tests to sdist, addresses issue #7 Message-ID: <20130209235528.567501C080A@cobra.cs.uni-duesseldorf.de> Author: Ronny Pfannschmidt Branch: Changeset: r230:7866209c4ed3 Date: 2013-02-10 00:55 +0100 http://bitbucket.org/pypy/pyrepl/changeset/7866209c4ed3/ Log: add tests to sdist, addresses issue #7 diff --git a/MANIFEST.in b/MANIFEST.in --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,1 +1,3 @@ include TODO CREDITS CHANGES pythoni encopyright.py LICENSE +include MANIFEST.in +recursive-include testing *.py From noreply at buildbot.pypy.org Sun Feb 10 02:46:57 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sun, 10 Feb 2013 02:46:57 +0100 (CET) Subject: [pypy-commit] pypy default: further improve datetime argument handling Message-ID: <20130210014657.B56F11C080A@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61014:43e61ecb2e40 Date: 2013-02-09 20:46 -0500 http://bitbucket.org/pypy/pypy/changeset/43e61ecb2e40/ Log: further improve datetime argument handling diff --git a/lib_pypy/datetime.py b/lib_pypy/datetime.py --- a/lib_pypy/datetime.py +++ b/lib_pypy/datetime.py @@ -18,7 +18,6 @@ import time as _time import math as _math -import decimal as _decimal MINYEAR = 1 MAXYEAR = 9999 @@ -272,9 +271,15 @@ raise ValueError("%s()=%d, must be in -1439..1439" % (name, offset)) def _check_int_field(value): - if not isinstance(value, (int, long, _decimal.Decimal)): - raise TypeError('integer argument expected') - return int(value) + if not isinstance(value, float): + try: + value = value.__int__() + except AttributeError: + pass + else: + if isinstance(value, int): + return value + raise TypeError('integer argument expected') def _check_date_fields(year, month, day): year = _check_int_field(year) diff --git a/pypy/module/test_lib_pypy/test_datetime.py b/pypy/module/test_lib_pypy/test_datetime.py --- a/pypy/module/test_lib_pypy/test_datetime.py +++ b/pypy/module/test_lib_pypy/test_datetime.py @@ -45,10 +45,31 @@ l10 = 10L d10 = decimal.Decimal(10) d11 = decimal.Decimal(10.9) + class C10: + def __int__(self): + return 10 + c10 = C10() assert datetime.datetime(i10, i10, i10, i10, i10, i10, i10) == \ datetime.datetime(l10, l10, l10, l10, l10, l10, l10) == \ datetime.datetime(d10, d10, d10, d10, d10, d10, d10) == \ - datetime.datetime(d11, d11, d11, d11, d11, d11, d11) + datetime.datetime(d11, d11, d11, d11, d11, d11, d11) == \ + datetime.datetime(c10, c10, c10, c10, c10, c10, c10) + + with py.test.raises(TypeError): + datetime.datetime(10, '10', 10) + + class S10(float): + pass + s10 = S10(10.9) + with py.test.raises(TypeError): + datetime.datetime(10, s10, 10) + + class F10: + def __int__(self): + return 10.9 + f10 = F10() + with py.test.raises(TypeError): + datetime.datetime(10, f10, 10) with py.test.raises(TypeError): datetime.datetime(10., 10, 10) From noreply at buildbot.pypy.org Sun Feb 10 03:31:27 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sun, 10 Feb 2013 03:31:27 +0100 (CET) Subject: [pypy-commit] pypy default: another datetime argument correctness fix Message-ID: <20130210023127.AF9D01C080A@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61015:53f105d99a07 Date: 2013-02-09 21:02 -0500 http://bitbucket.org/pypy/pypy/changeset/53f105d99a07/ Log: another datetime argument correctness fix diff --git a/lib_pypy/datetime.py b/lib_pypy/datetime.py --- a/lib_pypy/datetime.py +++ b/lib_pypy/datetime.py @@ -277,7 +277,7 @@ except AttributeError: pass else: - if isinstance(value, int): + if isinstance(value, (int, long)): return value raise TypeError('integer argument expected') diff --git a/pypy/module/test_lib_pypy/test_datetime.py b/pypy/module/test_lib_pypy/test_datetime.py --- a/pypy/module/test_lib_pypy/test_datetime.py +++ b/pypy/module/test_lib_pypy/test_datetime.py @@ -41,35 +41,36 @@ def test_check_arg_types(): import decimal + class Number: + def __init__(self, value): + self.value = value + def __int__(self): + return self.value i10 = 10 l10 = 10L d10 = decimal.Decimal(10) d11 = decimal.Decimal(10.9) - class C10: - def __int__(self): - return 10 - c10 = C10() + c10 = Number(10) + o10 = Number(10L) assert datetime.datetime(i10, i10, i10, i10, i10, i10, i10) == \ datetime.datetime(l10, l10, l10, l10, l10, l10, l10) == \ datetime.datetime(d10, d10, d10, d10, d10, d10, d10) == \ datetime.datetime(d11, d11, d11, d11, d11, d11, d11) == \ - datetime.datetime(c10, c10, c10, c10, c10, c10, c10) + datetime.datetime(c10, c10, c10, c10, c10, c10, c10) == \ + datetime.datetime(o10, o10, o10, o10, o10, o10, o10) with py.test.raises(TypeError): - datetime.datetime(10, '10', 10) + datetime.datetime(10, 10, '10') - class S10(float): + f10 = Number(10.9) + with py.test.raises(TypeError): + datetime.datetime(10, 10, f10) + + class Float(float): pass - s10 = S10(10.9) + s10 = Float(10.9) with py.test.raises(TypeError): - datetime.datetime(10, s10, 10) - - class F10: - def __int__(self): - return 10.9 - f10 = F10() - with py.test.raises(TypeError): - datetime.datetime(10, f10, 10) + datetime.datetime(10, 10, s10) with py.test.raises(TypeError): datetime.datetime(10., 10, 10) From noreply at buildbot.pypy.org Sun Feb 10 04:08:29 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sun, 10 Feb 2013 04:08:29 +0100 (CET) Subject: [pypy-commit] pypy default: put these tests where they will be executed and fix them up Message-ID: <20130210030829.1B5CC1C080A@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61016:81d9454bb7dc Date: 2013-02-09 22:06 -0500 http://bitbucket.org/pypy/pypy/changeset/81d9454bb7dc/ Log: put these tests where they will be executed and fix them up diff --git a/lib_pypy/pypy_test/test_collections.py b/lib_pypy/pypy_test/test_collections.py deleted file mode 100644 --- a/lib_pypy/pypy_test/test_collections.py +++ /dev/null @@ -1,64 +0,0 @@ -from __future__ import absolute_import -from lib_pypy import _collections as collections -import py - -class TestDeque: - def test_remove_empty(self): - d = collections.deque([]) - py.test.raises(ValueError, d.remove, 1) - - def test_remove_mutating(self): - class MutatingCmp(object): - def __eq__(self, other): - d.clear() - return True - - d = collections.deque([MutatingCmp()]) - py.test.raises(IndexError, d.remove, 1) - - def test_remove_failing(self): - class FailingCmp(object): - def __eq__(self, other): - assert False - - f = FailingCmp() - d = collections.deque([1, 2, 3, f, 4, 5]) - d.remove(3) - py.test.raises(AssertionError, d.remove, 4) - assert d == collections.deque([1, 2, f, 4, 5]) - - def test_maxlen(self): - d = collections.deque([], 3) - d.append(1); d.append(2); d.append(3); d.append(4) - assert list(d) == [2, 3, 4] - assert repr(d) == "deque([2, 3, 4], maxlen=3)" - - import pickle - d2 = pickle.loads(pickle.dumps(d)) - assert repr(d2) == "deque([2, 3, 4], maxlen=3)" - - import copy - d3 = copy.copy(d) - assert repr(d3) == "deque([2, 3, 4], maxlen=3)" - - def test_count(self): - d = collections.deque([1, 2, 2, 3, 2]) - assert d.count(2) == 3 - assert d.count(4) == 0 - - def test_reverse(self): - d = collections.deque([1, 2, 2, 3, 2]) - d.reverse() - assert list(d) == [2, 3, 2, 2, 1] - - d = collections.deque(range(100)) - d.reverse() - assert list(d) == range(99, -1, -1) - - def test_subclass_with_kwargs(self): - class SubclassWithKwargs(collections.deque): - def __init__(self, newarg=1): - collections.deque.__init__(self) - - # SF bug #1486663 -- this used to erroneously raise a TypeError - SubclassWithKwargs(newarg=1) diff --git a/lib_pypy/pypy_test/test_datetime.py b/lib_pypy/pypy_test/test_datetime.py deleted file mode 100644 --- a/lib_pypy/pypy_test/test_datetime.py +++ /dev/null @@ -1,59 +0,0 @@ -from __future__ import absolute_import -import py - -from lib_pypy import datetime - -def test_repr(): - print datetime - expected = "datetime.datetime(1, 2, 3, 0, 0)" - assert repr(datetime.datetime(1,2,3)) == expected - -def test_strptime(): - import time, sys - if sys.version_info < (2, 6): - py.test.skip("needs the _strptime module") - - string = '2004-12-01 13:02:47' - format = '%Y-%m-%d %H:%M:%S' - expected = datetime.datetime(*(time.strptime(string, format)[0:6])) - got = datetime.datetime.strptime(string, format) - assert expected == got - -def test_datetime_rounding(): - b = 0.0000001 - a = 0.9999994 - - assert datetime.datetime.utcfromtimestamp(a).microsecond == 999999 - assert datetime.datetime.utcfromtimestamp(a).second == 0 - a += b - assert datetime.datetime.utcfromtimestamp(a).microsecond == 999999 - assert datetime.datetime.utcfromtimestamp(a).second == 0 - a += b - assert datetime.datetime.utcfromtimestamp(a).microsecond == 0 - assert datetime.datetime.utcfromtimestamp(a).second == 1 - -def test_more_datetime_rounding(): - # this test verified on top of CPython 2.7 (using a plain - # "import datetime" above) - expected_results = { - -1000.0: 'datetime.datetime(1970, 1, 1, 0, 43, 20)', - -999.9999996: 'datetime.datetime(1970, 1, 1, 0, 43, 20)', - -999.4: 'datetime.datetime(1970, 1, 1, 0, 43, 20, 600000)', - -999.0000004: 'datetime.datetime(1970, 1, 1, 0, 43, 21)', - -1.0: 'datetime.datetime(1970, 1, 1, 0, 59, 59)', - -0.9999996: 'datetime.datetime(1970, 1, 1, 0, 59, 59)', - -0.4: 'datetime.datetime(1970, 1, 1, 0, 59, 59, 600000)', - -0.0000004: 'datetime.datetime(1970, 1, 1, 1, 0)', - 0.0: 'datetime.datetime(1970, 1, 1, 1, 0)', - 0.0000004: 'datetime.datetime(1970, 1, 1, 1, 0)', - 0.4: 'datetime.datetime(1970, 1, 1, 1, 0, 0, 400000)', - 0.9999996: 'datetime.datetime(1970, 1, 1, 1, 0, 1)', - 1000.0: 'datetime.datetime(1970, 1, 1, 1, 16, 40)', - 1000.0000004: 'datetime.datetime(1970, 1, 1, 1, 16, 40)', - 1000.4: 'datetime.datetime(1970, 1, 1, 1, 16, 40, 400000)', - 1000.9999996: 'datetime.datetime(1970, 1, 1, 1, 16, 41)', - 1293843661.191: 'datetime.datetime(2011, 1, 1, 2, 1, 1, 191000)', - } - for t in sorted(expected_results): - dt = datetime.datetime.fromtimestamp(t) - assert repr(dt) == expected_results[t] diff --git a/lib_pypy/pypy_test/test_deque_extra.py b/lib_pypy/pypy_test/test_deque_extra.py deleted file mode 100644 --- a/lib_pypy/pypy_test/test_deque_extra.py +++ /dev/null @@ -1,56 +0,0 @@ -# Deque Tests -from __future__ import absolute_import -import py - - -n = 10 -class Test_deque: - def setup_method(self,method): - - from lib_pypy._collections import deque - self.deque = deque - self.d = deque(range(n)) - - def test_deque(self): - - assert len(self.d) == n - for i in range(n): - assert i == self.d[i] - for i in range(n-1, -1, -1): - assert self.d.pop() == i - assert len(self.d) == 0 - - def test_deque_iter(self): - it = iter(self.d) - py.test.raises(TypeError, len, it) - assert it.next() == 0 - self.d.pop() - py.test.raises(RuntimeError, it.next) - - def test_deque_reversed(self): - it = reversed(self.d) - py.test.raises(TypeError, len, it) - assert it.next() == n-1 - assert it.next() == n-2 - self.d.pop() - py.test.raises(RuntimeError, it.next) - - def test_deque_remove(self): - d = self.d - py.test.raises(ValueError, d.remove, "foobar") - - def test_mutate_during_remove(self): - # Handle evil mutator - class MutateCmp: - def __init__(self, deque, result): - self.deque = deque - self.result = result - def __eq__(self, other): - self.deque.clear() - return self.result - - for match in (True, False): - d = self.deque(['ab']) - d.extend([MutateCmp(d, match), 'c']) - py.test.raises(IndexError, d.remove, 'c') - assert len(d) == 0 diff --git a/pypy/module/test_lib_pypy/test_collections.py b/pypy/module/test_lib_pypy/test_collections.py --- a/pypy/module/test_lib_pypy/test_collections.py +++ b/pypy/module/test_lib_pypy/test_collections.py @@ -1,25 +1,136 @@ - """ Extra tests for the pure Python PyPy _collections module (not used in normal PyPy's) """ -class AppTestCollections: +from __future__ import absolute_import +from lib_pypy import _collections as collections +import py + +class TestDeque: + def setup_method(self, method): + self.n = 10 + self.d = collections.deque(range(self.n)) + + def test_deque(self): + assert len(self.d) == self.n + for i in range(self.n): + assert i == self.d[i] + for i in range(self.n-1, -1, -1): + assert self.d.pop() == i + assert len(self.d) == 0 + + def test_deque_iter(self): + it = iter(self.d) + py.test.raises(TypeError, len, it) + assert it.next() == 0 + self.d.pop() + py.test.raises(RuntimeError, it.next) + + def test_deque_reversed(self): + it = reversed(self.d) + py.test.raises(TypeError, len, it) + assert it.next() == self.n-1 + assert it.next() == self.n-2 + self.d.pop() + py.test.raises(RuntimeError, it.next) + + def test_deque_remove(self): + d = self.d + py.test.raises(ValueError, d.remove, "foobar") + + def test_mutate_during_remove(self): + # Handle evil mutator + class MutateCmp: + def __init__(self, deque, result): + self.deque = deque + self.result = result + def __eq__(self, other): + self.deque.clear() + return self.result + + for match in (True, False): + d = collections.deque(['ab']) + d.extend([MutateCmp(d, match), 'c']) + py.test.raises(IndexError, d.remove, 'c') + assert len(d) == 0 + +class TestDequeExtra: + def test_remove_empty(self): + d = collections.deque([]) + py.test.raises(ValueError, d.remove, 1) + + def test_remove_mutating(self): + class MutatingCmp(object): + def __eq__(self, other): + d.clear() + return True + + d = collections.deque([MutatingCmp()]) + py.test.raises(IndexError, d.remove, 1) + + def test_remove_failing(self): + class FailingCmp(object): + def __eq__(self, other): + assert False + + f = FailingCmp() + d = collections.deque([1, 2, 3, f, 4, 5]) + d.remove(3) + py.test.raises(AssertionError, d.remove, 4) + assert d == collections.deque([1, 2, f, 4, 5]) + + def test_maxlen(self): + d = collections.deque([], 3) + d.append(1); d.append(2); d.append(3); d.append(4) + assert list(d) == [2, 3, 4] + assert repr(d) == "deque([2, 3, 4], maxlen=3)" + + import pickle + d2 = pickle.loads(pickle.dumps(d)) + assert repr(d2) == "deque([2, 3, 4], maxlen=3)" + + import copy + d3 = copy.copy(d) + assert repr(d3) == "deque([2, 3, 4], maxlen=3)" + + def test_count(self): + d = collections.deque([1, 2, 2, 3, 2]) + assert d.count(2) == 3 + assert d.count(4) == 0 + + def test_reverse(self): + d = collections.deque([1, 2, 2, 3, 2]) + d.reverse() + assert list(d) == [2, 3, 2, 2, 1] + + d = collections.deque(range(100)) + d.reverse() + assert list(d) == range(99, -1, -1) + + def test_subclass_with_kwargs(self): + class SubclassWithKwargs(collections.deque): + def __init__(self, newarg=1): + collections.deque.__init__(self) + + # SF bug #1486663 -- this used to erroneously raise a TypeError + SubclassWithKwargs(newarg=1) + +class TestDefaultDict: def test_copy(self): - import _collections def f(): return 42 - d = _collections.defaultdict(f, {2: 3}) + d = collections.defaultdict(f, {2: 3}) # d1 = d.copy() - assert type(d1) is _collections.defaultdict + assert type(d1) is collections.defaultdict assert len(d1) == 1 assert d1[2] == 3 assert d1[3] == 42 # import copy d2 = copy.deepcopy(d) - assert type(d2) is _collections.defaultdict + assert type(d2) is collections.defaultdict assert len(d2) == 1 assert d2[2] == 3 assert d2[3] == 42 diff --git a/pypy/module/test_lib_pypy/test_datetime.py b/pypy/module/test_lib_pypy/test_datetime.py --- a/pypy/module/test_lib_pypy/test_datetime.py +++ b/pypy/module/test_lib_pypy/test_datetime.py @@ -1,17 +1,71 @@ """Additional tests for datetime.""" +from __future__ import absolute_import +from lib_pypy import datetime import py -import time -from lib_pypy import datetime -import copy -import os +def test_repr(): + print datetime + expected = "datetime.datetime(1, 2, 3, 0, 0)" + assert repr(datetime.datetime(1,2,3)) == expected + +def test_strptime(): + import time, sys + if sys.version_info < (2, 6): + py.test.skip("needs the _strptime module") + + string = '2004-12-01 13:02:47' + format = '%Y-%m-%d %H:%M:%S' + expected = datetime.datetime(*(time.strptime(string, format)[0:6])) + got = datetime.datetime.strptime(string, format) + assert expected == got + +def test_datetime_rounding(): + b = 0.0000001 + a = 0.9999994 + + assert datetime.datetime.utcfromtimestamp(a).microsecond == 999999 + assert datetime.datetime.utcfromtimestamp(a).second == 0 + a += b + assert datetime.datetime.utcfromtimestamp(a).microsecond == 999999 + assert datetime.datetime.utcfromtimestamp(a).second == 0 + a += b + assert datetime.datetime.utcfromtimestamp(a).microsecond == 0 + assert datetime.datetime.utcfromtimestamp(a).second == 1 + +def test_more_datetime_rounding(): + # this test verified on top of CPython 2.7 (using a plain + # "import datetime" above) + expected_results = { + -1000.0: 'datetime.datetime(1969, 12, 31, 23, 43, 20)', + -999.9999996: 'datetime.datetime(1969, 12, 31, 23, 43, 20)', + -999.4: 'datetime.datetime(1969, 12, 31, 23, 43, 20, 600000)', + -999.0000004: 'datetime.datetime(1969, 12, 31, 23, 43, 21)', + -1.0: 'datetime.datetime(1969, 12, 31, 23, 59, 59)', + -0.9999996: 'datetime.datetime(1969, 12, 31, 23, 59, 59)', + -0.4: 'datetime.datetime(1969, 12, 31, 23, 59, 59, 600000)', + -0.0000004: 'datetime.datetime(1970, 1, 1, 0, 0)', + 0.0: 'datetime.datetime(1970, 1, 1, 0, 0)', + 0.0000004: 'datetime.datetime(1970, 1, 1, 0, 0)', + 0.4: 'datetime.datetime(1970, 1, 1, 0, 0, 0, 400000)', + 0.9999996: 'datetime.datetime(1970, 1, 1, 0, 0, 1)', + 1000.0: 'datetime.datetime(1970, 1, 1, 0, 16, 40)', + 1000.0000004: 'datetime.datetime(1970, 1, 1, 0, 16, 40)', + 1000.4: 'datetime.datetime(1970, 1, 1, 0, 16, 40, 400000)', + 1000.9999996: 'datetime.datetime(1970, 1, 1, 0, 16, 41)', + 1293843661.191: 'datetime.datetime(2011, 1, 1, 1, 1, 1, 191000)', + } + for t in sorted(expected_results): + dt = datetime.datetime.utcfromtimestamp(t) + assert repr(dt) == expected_results[t] def test_utcfromtimestamp(): """Confirm that utcfromtimestamp and fromtimestamp give consistent results. Based on danchr's test script in https://bugs.pypy.org/issue986 """ + import os + import time try: prev_tz = os.environ.get("TZ") os.environ["TZ"] = "GMT" @@ -88,6 +142,8 @@ datetime.datetime(10, 10, 10, 10, 10, 10, 10.) def test_utcnow_microsecond(): + import copy + dt = datetime.datetime.utcnow() assert type(dt.microsecond) is int From noreply at buildbot.pypy.org Sun Feb 10 04:26:22 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sun, 10 Feb 2013 04:26:22 +0100 (CET) Subject: [pypy-commit] pypy cleanup-tests: merge default Message-ID: <20130210032622.375651C1028@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: cleanup-tests Changeset: r61017:9e6e7a38ed0c Date: 2013-02-09 22:25 -0500 http://bitbucket.org/pypy/pypy/changeset/9e6e7a38ed0c/ Log: merge default diff --git a/lib-python/2.7/collections.py b/lib-python/2.7/collections.py --- a/lib-python/2.7/collections.py +++ b/lib-python/2.7/collections.py @@ -6,11 +6,12 @@ __all__ += _abcoll.__all__ from _collections import deque, defaultdict -from operator import itemgetter as _itemgetter +from operator import itemgetter as _itemgetter, eq as _eq from keyword import iskeyword as _iskeyword import sys as _sys import heapq as _heapq from itertools import repeat as _repeat, chain as _chain, starmap as _starmap +from itertools import imap as _imap try: from thread import get_ident as _get_ident @@ -50,49 +51,45 @@ self.__map = {} self.__update(*args, **kwds) - def __setitem__(self, key, value, PREV=0, NEXT=1, dict_setitem=dict.__setitem__): + def __setitem__(self, key, value, dict_setitem=dict.__setitem__): 'od.__setitem__(i, y) <==> od[i]=y' # Setting a new item creates a new link at the end of the linked list, # and the inherited dictionary is updated with the new key/value pair. if key not in self: root = self.__root - last = root[PREV] - last[NEXT] = root[PREV] = self.__map[key] = [last, root, key] - dict_setitem(self, key, value) + last = root[0] + last[1] = root[0] = self.__map[key] = [last, root, key] + return dict_setitem(self, key, value) - def __delitem__(self, key, PREV=0, NEXT=1, dict_delitem=dict.__delitem__): + def __delitem__(self, key, dict_delitem=dict.__delitem__): 'od.__delitem__(y) <==> del od[y]' # Deleting an existing item uses self.__map to find the link which gets # removed by updating the links in the predecessor and successor nodes. dict_delitem(self, key) link_prev, link_next, key = self.__map.pop(key) - link_prev[NEXT] = link_next - link_next[PREV] = link_prev + link_prev[1] = link_next # update link_prev[NEXT] + link_next[0] = link_prev # update link_next[PREV] def __iter__(self): 'od.__iter__() <==> iter(od)' # Traverse the linked list in order. - NEXT, KEY = 1, 2 root = self.__root - curr = root[NEXT] + curr = root[1] # start at the first node while curr is not root: - yield curr[KEY] - curr = curr[NEXT] + yield curr[2] # yield the curr[KEY] + curr = curr[1] # move to next node def __reversed__(self): 'od.__reversed__() <==> reversed(od)' # Traverse the linked list in reverse order. - PREV, KEY = 0, 2 root = self.__root - curr = root[PREV] + curr = root[0] # start at the last node while curr is not root: - yield curr[KEY] - curr = curr[PREV] + yield curr[2] # yield the curr[KEY] + curr = curr[0] # move to previous node def clear(self): 'od.clear() -> None. Remove all items from od.' - for node in self.__map.itervalues(): - del node[:] root = self.__root root[:] = [root, root, None] self.__map.clear() @@ -208,7 +205,7 @@ ''' if isinstance(other, OrderedDict): - return len(self)==len(other) and self.items() == other.items() + return dict.__eq__(self, other) and all(_imap(_eq, self, other)) return dict.__eq__(self, other) def __ne__(self, other): diff --git a/lib_pypy/_collections.py b/lib_pypy/_collections.py --- a/lib_pypy/_collections.py +++ b/lib_pypy/_collections.py @@ -142,18 +142,24 @@ return c def remove(self, value): - # Need to be defensive for mutating comparisons - for i in range(len(self)): - if self[i] == value: - del self[i] - return - raise ValueError("deque.remove(x): x not in deque") + # Need to defend mutating or failing comparisons + i = 0 + try: + for i in range(len(self)): + if self[0] == value: + self.popleft() + return + self.append(self.popleft()) + i += 1 + raise ValueError("deque.remove(x): x not in deque") + finally: + self.rotate(i) def rotate(self, n=1): length = len(self) - if length == 0: + if length <= 1: return - halflen = (length+1) >> 1 + halflen = length >> 1 if n > halflen or n < -halflen: n %= length if n > halflen: diff --git a/lib_pypy/cPickle.py b/lib_pypy/cPickle.py --- a/lib_pypy/cPickle.py +++ b/lib_pypy/cPickle.py @@ -1,5 +1,5 @@ # -# One-liner implementation of cPickle +# Reimplementation of cPickle, mostly as a copy of pickle.py # from pickle import Pickler, dump, dumps, PickleError, PicklingError, UnpicklingError, _EmptyClass @@ -131,6 +131,13 @@ # Unpickling machinery +class _Stack(list): + def pop(self, index=-1): + try: + return list.pop(self, index) + except IndexError: + raise UnpicklingError("unpickling stack underflow") + class Unpickler(object): def __init__(self, file): @@ -155,7 +162,7 @@ Return the reconstituted object hierarchy specified in the file. """ self.mark = object() # any new unique object - self.stack = [] + self.stack = _Stack() self.append = self.stack.append try: key = ord(self.read(1)) diff --git a/lib_pypy/datetime.py b/lib_pypy/datetime.py --- a/lib_pypy/datetime.py +++ b/lib_pypy/datetime.py @@ -270,10 +270,21 @@ return offset raise ValueError("%s()=%d, must be in -1439..1439" % (name, offset)) +def _check_int_field(value): + if not isinstance(value, float): + try: + value = value.__int__() + except AttributeError: + pass + else: + if isinstance(value, (int, long)): + return value + raise TypeError('integer argument expected') + def _check_date_fields(year, month, day): - for value in [year, day]: - if not isinstance(value, (int, long)): - raise TypeError('int expected') + year = _check_int_field(year) + month = _check_int_field(month) + day = _check_int_field(day) if not MINYEAR <= year <= MAXYEAR: raise ValueError('year must be in %d..%d' % (MINYEAR, MAXYEAR), year) if not 1 <= month <= 12: @@ -281,11 +292,13 @@ dim = _days_in_month(year, month) if not 1 <= day <= dim: raise ValueError('day must be in 1..%d' % dim, day) + return year, month, day def _check_time_fields(hour, minute, second, microsecond): - for value in [hour, minute, second, microsecond]: - if not isinstance(value, (int, long)): - raise TypeError('int expected') + hour = _check_int_field(hour) + minute = _check_int_field(minute) + second = _check_int_field(second) + microsecond = _check_int_field(microsecond) if not 0 <= hour <= 23: raise ValueError('hour must be in 0..23', hour) if not 0 <= minute <= 59: @@ -294,6 +307,7 @@ raise ValueError('second must be in 0..59', second) if not 0 <= microsecond <= 999999: raise ValueError('microsecond must be in 0..999999', microsecond) + return hour, minute, second, microsecond def _check_tzinfo_arg(tz): if tz is not None and not isinstance(tz, tzinfo): @@ -768,7 +782,7 @@ self = object.__new__(cls) self.__setstate(year) return self - _check_date_fields(year, month, day) + year, month, day = _check_date_fields(year, month, day) self = object.__new__(cls) self._year = year self._month = month @@ -889,7 +903,7 @@ month = self._month if day is None: day = self._day - _check_date_fields(year, month, day) + year, month, day = _check_date_fields(year, month, day) return date(year, month, day) # Comparisons of date objects with other. @@ -1150,13 +1164,14 @@ second, microsecond (default to zero) tzinfo (default to None) """ - self = object.__new__(cls) if isinstance(hour, str): # Pickle support + self = object.__new__(cls) self.__setstate(hour, minute or None) return self + hour, minute, second, microsecond = _check_time_fields(hour, minute, second, microsecond) _check_tzinfo_arg(tzinfo) - _check_time_fields(hour, minute, second, microsecond) + self = object.__new__(cls) self._hour = hour self._minute = minute self._second = second @@ -1387,7 +1402,7 @@ microsecond = self.microsecond if tzinfo is True: tzinfo = self.tzinfo - _check_time_fields(hour, minute, second, microsecond) + hour, minute, second, microsecond = _check_time_fields(hour, minute, second, microsecond) _check_tzinfo_arg(tzinfo) return time(hour, minute, second, microsecond, tzinfo) @@ -1449,10 +1464,10 @@ self = date.__new__(cls, year[:4]) self.__setstate(year, month) return self + year, month, day = _check_date_fields(year, month, day) + hour, minute, second, microsecond = _check_time_fields(hour, minute, second, microsecond) _check_tzinfo_arg(tzinfo) - _check_time_fields(hour, minute, second, microsecond) - self = date.__new__(cls, year, month, day) - # XXX This duplicates __year, __month, __day for convenience :-( + self = object.__new__(cls) self._year = year self._month = month self._day = day @@ -1617,8 +1632,8 @@ microsecond = self.microsecond if tzinfo is True: tzinfo = self.tzinfo - _check_date_fields(year, month, day) - _check_time_fields(hour, minute, second, microsecond) + year, month, day = _check_date_fields(year, month, day) + hour, minute, second, microsecond = _check_time_fields(hour, minute, second, microsecond) _check_tzinfo_arg(tzinfo) return datetime(year, month, day, hour, minute, second, microsecond, tzinfo) diff --git a/lib_pypy/greenlet.py b/lib_pypy/greenlet.py --- a/lib_pypy/greenlet.py +++ b/lib_pypy/greenlet.py @@ -1,5 +1,6 @@ import _continuation, sys +__version__ = "0.4.0" # ____________________________________________________________ # Exceptions @@ -57,7 +58,8 @@ def __switch(target, methodname, *args): current = getcurrent() # - while not target: + while not (target.__main or _continulet.is_pending(target)): + # inlined __nonzero__ ^^^ in case it's overridden if not target.__started: if methodname == 'switch': greenlet_func = _greenlet_start diff --git a/lib_pypy/pyrepl/unix_console.py b/lib_pypy/pyrepl/unix_console.py --- a/lib_pypy/pyrepl/unix_console.py +++ b/lib_pypy/pyrepl/unix_console.py @@ -398,6 +398,7 @@ if hasattr(self, 'old_sigwinch'): signal.signal(signal.SIGWINCH, self.old_sigwinch) + del self.old_sigwinch def __sigwinch(self, signum, frame): self.height, self.width = self.getheightwidth() diff --git a/pypy/interpreter/app_main.py b/pypy/interpreter/app_main.py --- a/pypy/interpreter/app_main.py +++ b/pypy/interpreter/app_main.py @@ -436,11 +436,14 @@ # (relevant in case of "reload(sys)") sys.argv[:] = argv - if PYTHON26 and not options["ignore_environment"]: - if os.getenv('PYTHONNOUSERSITE'): - options["no_user_site"] = 1 - if os.getenv('PYTHONDONTWRITEBYTECODE'): - options["dont_write_bytecode"] = 1 + if not options["ignore_environment"]: + if os.getenv('PYTHONUNBUFFERED'): + options["unbuffered"] = 1 + if PYTHON26: + if os.getenv('PYTHONNOUSERSITE'): + options["no_user_site"] = 1 + if os.getenv('PYTHONDONTWRITEBYTECODE'): + options["dont_write_bytecode"] = 1 if (options["interactive"] or (not options["ignore_environment"] and os.getenv('PYTHONINSPECT'))): @@ -716,7 +719,7 @@ root = dn(dn(dn(thisfile))) return [join(root, 'lib-python', '2.7'), join(root, 'lib_pypy')] - + def pypy_resolvedirof(s): # we ignore the issue of symlinks; for tests, the executable is always # interpreter/app_main.py anyway @@ -756,6 +759,10 @@ del os # make sure that os is not available globally, because this is what # happens in "real life" outside the tests + if 'time' not in sys.builtin_module_names: + # make some tests happy by loading this before we clobber sys.path + import time; del time + # no one should change to which lists sys.argv and sys.path are bound old_argv = sys.argv old_path = sys.path diff --git a/pypy/interpreter/test2/test_app_main.py b/pypy/interpreter/test2/test_app_main.py --- a/pypy/interpreter/test2/test_app_main.py +++ b/pypy/interpreter/test2/test_app_main.py @@ -712,6 +712,26 @@ assert data == '\x00(STDOUT)\n\x00' # from stdout child_out_err.close() + def test_non_interactive_stdout_unbuffered(self, monkeypatch): + monkeypatch.setenv('PYTHONUNBUFFERED', '1') + path = getscript(r""" + import sys, time + sys.stdout.write('\x00(STDOUT)\n\x00') + time.sleep(1) + sys.stderr.write('\x00[STDERR]\n\x00') + time.sleep(1) + # stdout flushed automatically here + """) + cmdline = '%s -E "%s" %s' % (sys.executable, app_main, path) + print 'POPEN:', cmdline + child_in, child_out_err = os.popen4(cmdline) + data = child_out_err.read(11) + assert data == '\x00(STDOUT)\n\x00' # from stderr + data = child_out_err.read(11) + assert data == '\x00[STDERR]\n\x00' # from stdout + child_out_err.close() + child_in.close() + def test_proper_sys_path(self, tmpdir): data = self.run('-c "import _ctypes"', python_flags='-S') if data.startswith('Traceback'): diff --git a/pypy/module/__pypy__/__init__.py b/pypy/module/__pypy__/__init__.py --- a/pypy/module/__pypy__/__init__.py +++ b/pypy/module/__pypy__/__init__.py @@ -14,7 +14,7 @@ class TimeModule(MixedModule): appleveldefs = {} interpleveldefs = {} - if sys.platform.startswith("linux"): + if sys.platform.startswith("linux") or 'bsd' in sys.platform: from pypy.module.__pypy__ import interp_time interpleveldefs["clock_gettime"] = "interp_time.clock_gettime" interpleveldefs["clock_getres"] = "interp_time.clock_getres" diff --git a/pypy/module/_cffi_backend/cbuffer.py b/pypy/module/_cffi_backend/cbuffer.py --- a/pypy/module/_cffi_backend/cbuffer.py +++ b/pypy/module/_cffi_backend/cbuffer.py @@ -2,7 +2,7 @@ from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.buffer import RWBuffer from pypy.interpreter.gateway import unwrap_spec, interp2app -from pypy.interpreter.typedef import TypeDef +from pypy.interpreter.typedef import TypeDef, make_weakref_descr from rpython.rtyper.lltypesystem import rffi from pypy.module._cffi_backend import cdataobj, ctypeptr, ctypearray @@ -41,8 +41,9 @@ # a different subclass of Wrappable for the MiniBuffer, because we # want a slightly different (simplified) API at the level of Python. - def __init__(self, buffer): + def __init__(self, buffer, keepalive=None): self.buffer = buffer + self.keepalive = keepalive def descr_len(self, space): return self.buffer.descr_len(space) @@ -65,6 +66,7 @@ __getitem__ = interp2app(MiniBuffer.descr_getitem), __setitem__ = interp2app(MiniBuffer.descr_setitem), __buffer__ = interp2app(MiniBuffer.descr__buffer__), + __weakref__ = make_weakref_descr(MiniBuffer), ) MiniBuffer.typedef.acceptable_as_base_class = False @@ -86,4 +88,4 @@ raise operationerrfmt(space.w_TypeError, "don't know the size pointed to by '%s'", ctype.name) - return space.wrap(MiniBuffer(LLBuffer(cdata._cdata, size))) + return space.wrap(MiniBuffer(LLBuffer(cdata._cdata, size), cdata)) diff --git a/pypy/module/_cffi_backend/ctypeptr.py b/pypy/module/_cffi_backend/ctypeptr.py --- a/pypy/module/_cffi_backend/ctypeptr.py +++ b/pypy/module/_cffi_backend/ctypeptr.py @@ -252,7 +252,10 @@ def _prepare_pointer_call_argument(self, w_init, cdata): space = self.space - if (space.isinstance_w(w_init, space.w_list) or + if space.is_w(w_init, space.w_None): + rffi.cast(rffi.CCHARPP, cdata)[0] = lltype.nullptr(rffi.CCHARP.TO) + return 3 + elif (space.isinstance_w(w_init, space.w_list) or space.isinstance_w(w_init, space.w_tuple)): length = space.int_w(space.len(w_init)) elif space.isinstance_w(w_init, space.w_basestring): diff --git a/pypy/module/_cffi_backend/test/_backend_test_c.py b/pypy/module/_cffi_backend/test/_backend_test_c.py --- a/pypy/module/_cffi_backend/test/_backend_test_c.py +++ b/pypy/module/_cffi_backend/test/_backend_test_c.py @@ -12,6 +12,7 @@ return eval('u'+repr(other).replace(r'\\u', r'\u') .replace(r'\\U', r'\U')) u = U() + str2bytes = str else: type_or_class = "class" long = int @@ -22,6 +23,7 @@ bytechr = lambda n: bytes([n]) bitem2bchr = bytechr u = "" + str2bytes = lambda s: bytes(s, "ascii") def size_of_int(): BInt = new_primitive_type("int") @@ -996,6 +998,8 @@ f = cast(BFunc23, _testfunc(23)) res = f(b"foo") assert res == 1000 * ord(b'f') + res = f(None) + assert res == -42 def test_call_function_23_bis(): # declaring the function as int(unsigned char*) @@ -1438,10 +1442,16 @@ import _weakref BInt = new_primitive_type("int") BPtr = new_pointer_type(BInt) - _weakref.ref(BInt) - _weakref.ref(newp(BPtr, 42)) - _weakref.ref(cast(BPtr, 42)) - _weakref.ref(cast(BInt, 42)) + rlist = [_weakref.ref(BInt), + _weakref.ref(newp(BPtr, 42)), + _weakref.ref(cast(BPtr, 42)), + _weakref.ref(cast(BInt, 42)), + _weakref.ref(buffer(newp(BPtr, 42))), + ] + for i in range(5): + import gc; gc.collect() + if [r() for r in rlist] == [None for r in rlist]: + break def test_no_inheritance(): BInt = new_primitive_type("int") @@ -2544,3 +2554,15 @@ BCharP = new_pointer_type(new_primitive_type("char")) BCharArray = new_array_type(BCharP, None) py.test.raises(TypeError, newp, BCharArray, u+'foobar') + +def test_buffer_keepalive(): + BCharP = new_pointer_type(new_primitive_type("char")) + BCharArray = new_array_type(BCharP, None) + buflist = [] + for i in range(20): + c = newp(BCharArray, str2bytes("hi there %d" % i)) + buflist.append(buffer(c)) + import gc; gc.collect() + for i in range(20): + buf = buflist[i] + assert buf[:] == str2bytes("hi there %d\x00" % i) diff --git a/pypy/module/_cffi_backend/test/_test_lib.c b/pypy/module/_cffi_backend/test/_test_lib.c --- a/pypy/module/_cffi_backend/test/_test_lib.c +++ b/pypy/module/_cffi_backend/test/_test_lib.c @@ -174,7 +174,9 @@ static int _testfunc23(char *p) { - return 1000 * p[0]; + if (p) + return 1000 * p[0]; + return -42; } DLLEXPORT void *gettestfunc(int num) diff --git a/pypy/module/_multibytecodec/c_codecs.py b/pypy/module/_multibytecodec/c_codecs.py --- a/pypy/module/_multibytecodec/c_codecs.py +++ b/pypy/module/_multibytecodec/c_codecs.py @@ -62,7 +62,7 @@ "pypy_cjk_enc_init", "pypy_cjk_enc_free", "pypy_cjk_enc_chunk", "pypy_cjk_enc_reset", "pypy_cjk_enc_outbuf", "pypy_cjk_enc_outlen", "pypy_cjk_enc_inbuf_remaining", "pypy_cjk_enc_inbuf_consumed", - "pypy_cjk_enc_replace_on_error", + "pypy_cjk_enc_replace_on_error", "pypy_cjk_enc_getcodec", ] + ["pypy_cjkcodec_%s" % codec for codec in codecs], ) diff --git a/pypy/module/micronumpy/__init__.py b/pypy/module/micronumpy/__init__.py --- a/pypy/module/micronumpy/__init__.py +++ b/pypy/module/micronumpy/__init__.py @@ -27,6 +27,9 @@ 'True_': 'types.Bool.True', 'False_': 'types.Bool.False', + 'bool': 'space.w_bool', + 'int': 'space.w_int', + 'typeinfo': 'interp_dtype.get_dtype_cache(space).w_typeinfo', 'generic': 'interp_boxes.W_GenericBox', diff --git a/pypy/module/micronumpy/arrayimpl/concrete.py b/pypy/module/micronumpy/arrayimpl/concrete.py --- a/pypy/module/micronumpy/arrayimpl/concrete.py +++ b/pypy/module/micronumpy/arrayimpl/concrete.py @@ -275,6 +275,11 @@ def get_buffer(self, space): return ArrayBuffer(self) + def astype(self, space, dtype): + new_arr = W_NDimArray.from_shape(self.get_shape(), dtype) + loop.copy_from_to(self, new_arr.implementation, dtype) + return new_arr + class ConcreteArrayNotOwning(BaseConcreteArray): def __init__(self, shape, dtype, order, strides, backstrides, storage): @@ -309,11 +314,6 @@ def argsort(self, space, w_axis): return argsort_array(self, space, w_axis) - def astype(self, space, dtype): - new_arr = W_NDimArray.from_shape(self.get_shape(), dtype) - loop.copy_from_to(self, new_arr.implementation, dtype) - return new_arr - def base(self): return None diff --git a/pypy/module/micronumpy/arrayimpl/scalar.py b/pypy/module/micronumpy/arrayimpl/scalar.py --- a/pypy/module/micronumpy/arrayimpl/scalar.py +++ b/pypy/module/micronumpy/arrayimpl/scalar.py @@ -7,18 +7,19 @@ class ScalarIterator(base.BaseArrayIterator): def __init__(self, v): self.v = v + self.called_once = False def next(self): - pass + self.called_once = True def getitem(self): - return self.v + return self.v.get_scalar_value() def setitem(self, v): - raise Exception("Don't call setitem on scalar iterators") + self.v.set_scalar_value(v) def done(self): - raise Exception("should not call done on scalar") + return self.called_once def reset(self): pass @@ -38,7 +39,7 @@ return [] def create_iter(self, shape=None): - return ScalarIterator(self.value) + return ScalarIterator(self) def get_scalar_value(self): return self.value diff --git a/pypy/module/micronumpy/base.py b/pypy/module/micronumpy/base.py --- a/pypy/module/micronumpy/base.py +++ b/pypy/module/micronumpy/base.py @@ -21,11 +21,13 @@ @staticmethod def from_shape(shape, dtype, order='C'): - from pypy.module.micronumpy.arrayimpl import concrete - - assert shape - strides, backstrides = calc_strides(shape, dtype, order) - impl = concrete.ConcreteArray(shape, dtype, order, strides, + from pypy.module.micronumpy.arrayimpl import concrete, scalar + + if not shape: + impl = scalar.Scalar(dtype) + else: + strides, backstrides = calc_strides(shape, dtype, order) + impl = concrete.ConcreteArray(shape, dtype, order, strides, backstrides) return W_NDimArray(impl) diff --git a/pypy/module/micronumpy/interp_dtype.py b/pypy/module/micronumpy/interp_dtype.py --- a/pypy/module/micronumpy/interp_dtype.py +++ b/pypy/module/micronumpy/interp_dtype.py @@ -270,13 +270,12 @@ return dtype_from_list(space, w_dtype) elif space.isinstance_w(w_dtype, space.w_dict): return dtype_from_dict(space, w_dtype) - else: - for dtype in cache.builtin_dtypes: - if w_dtype in dtype.alternate_constructors: - return dtype - if w_dtype is dtype.w_box_type: - return dtype - raise OperationError(space.w_TypeError, space.wrap("data type %s not understood")) + for dtype in cache.builtin_dtypes: + if w_dtype in dtype.alternate_constructors: + return dtype + if w_dtype is dtype.w_box_type: + return dtype + raise OperationError(space.w_TypeError, space.wrap("data type %r not understood" % w_dtype)) W_Dtype.typedef = TypeDef("dtype", __module__ = "numpypy", @@ -400,7 +399,10 @@ name=name, char="l", w_box_type=space.gettypefor(interp_boxes.W_LongBox), - alternate_constructors=[space.w_int], + alternate_constructors=[space.w_int, + space.gettypefor(interp_boxes.W_IntegerBox), + space.gettypefor(interp_boxes.W_SignedIntegerBox), + ], aliases=['int'], ) self.w_ulongdtype = W_Dtype( @@ -410,6 +412,8 @@ name="u" + name, char="L", w_box_type=space.gettypefor(interp_boxes.W_ULongBox), + alternate_constructors=[ space.gettypefor(interp_boxes.W_UnsignedIntegerBox), + ], ) self.w_int64dtype = W_Dtype( types.Int64(), @@ -443,7 +447,9 @@ name="float64", char="d", w_box_type = space.gettypefor(interp_boxes.W_Float64Box), - alternate_constructors=[space.w_float], + alternate_constructors=[space.w_float, + space.gettypefor(interp_boxes.W_NumberBox), + ], aliases=["float"], ) self.w_complex64dtype = W_ComplexDtype( @@ -546,6 +552,8 @@ w_box_type = space.gettypefor(interp_boxes.W_VoidBox), #alternate_constructors=[space.w_buffer], # XXX no buffer in space + #alternate_constructors=[space.gettypefor(interp_boxes.W_GenericBox)], + # XXX fix, leads to _coerce error ) self.w_float16dtype = W_Dtype( types.Float16(), @@ -559,18 +567,22 @@ if ptr_size == 4: intp_box = interp_boxes.W_Int32Box intp_type = types.Int32() + intp_num = 5 uintp_box = interp_boxes.W_UInt32Box uintp_type = types.UInt32() + uintp_num = 6 elif ptr_size == 8: intp_box = interp_boxes.W_Int64Box intp_type = types.Int64() + intp_num = 7 uintp_box = interp_boxes.W_UInt64Box uintp_type = types.UInt64() + uintp_num = 8 else: raise ValueError('unknown point size %d' % ptr_size) self.w_intpdtype = W_Dtype( intp_type, - num=5, + num=intp_num, kind=INTPLTR, name='intp', char=INTPLTR, @@ -578,7 +590,7 @@ ) self.w_uintpdtype = W_Dtype( uintp_type, - num=6, + num=uintp_num, kind=UINTPLTR, name='uintp', char=UINTPLTR, diff --git a/pypy/module/micronumpy/test/test_dtypes.py b/pypy/module/micronumpy/test/test_dtypes.py --- a/pypy/module/micronumpy/test/test_dtypes.py +++ b/pypy/module/micronumpy/test/test_dtypes.py @@ -3,7 +3,19 @@ from pypy.module.micronumpy.test.test_base import BaseNumpyAppTest from pypy.interpreter.gateway import interp2app -class AppTestDtypes(BaseNumpyAppTest): +class BaseAppTestDtypes(BaseNumpyAppTest): + def setup_class(cls): + BaseNumpyAppTest.setup_class.im_func(cls) + if option.runappdirect: + import platform + bits, linkage = platform.architecture() + ptr_size = int(bits[:-3]) // 8 + else: + from rpython.rtyper.lltypesystem import rffi + ptr_size = rffi.sizeof(rffi.CCHARP) + cls.w_ptr_size = cls.space.wrap(ptr_size) + +class AppTestDtypes(BaseAppTestDtypes): def test_dtype(self): from _numpypy import dtype @@ -31,8 +43,12 @@ from _numpypy import dtype assert dtype(bool).num == 0 - assert dtype('intp').num == 5 - assert dtype('uintp').num == 6 + if self.ptr_size == 4: + assert dtype('intp').num == 5 + assert dtype('uintp').num == 6 + else: + assert dtype('intp').num == 7 + assert dtype('uintp').num == 8 assert dtype(int).num == 7 assert dtype(long).num == 9 assert dtype(float).num == 12 @@ -241,18 +257,7 @@ assert hash(tp(value)) == hash(value) -class AppTestTypes(BaseNumpyAppTest): - def setup_class(cls): - BaseNumpyAppTest.setup_class.im_func(cls) - if option.runappdirect: - import platform - bits, linkage = platform.architecture() - ptr_size = int(bits[:-3]) // 8 - else: - from rpython.rtyper.lltypesystem import rffi - ptr_size = rffi.sizeof(rffi.CCHARP) - cls.w_ptr_size = cls.space.wrap(ptr_size) - +class AppTestTypes(BaseAppTestDtypes): def test_abstract_types(self): import _numpypy as numpy raises(TypeError, numpy.generic, 0) @@ -266,6 +271,18 @@ assert 'unsignedinteger' in str(exc.value) raises(TypeError, numpy.floating, 0) raises(TypeError, numpy.inexact, 0) + # numpy allows abstract types in array creation + a = numpy.array([4,4], numpy.integer) + assert a.dtype is numpy.dtype('int64') + a = numpy.array([4,4], numpy.number) + assert a.dtype is numpy.dtype('float') + a = numpy.array([4,4], numpy.signedinteger) + assert a.dtype is numpy.dtype('int64') + a = numpy.array([4,4], numpy.unsignedinteger) + assert a.dtype is numpy.dtype('uint64') + # too ambitious for now + #a = numpy.array('xxxx', numpy.generic) + #assert a.dtype is numpy.dtype('|V4') def test_new(self): import _numpypy as np @@ -493,8 +510,9 @@ numpy.inexact, numpy.number, numpy.generic, object) def test_complex_format(self): + import sys import _numpypy as numpy - + for complex_ in (numpy.complex128, numpy.complex64,): for real, imag, should in [ (1, 2, '(1+2j)'), @@ -505,13 +523,13 @@ #xxx #(numpy.inf, numpy.inf, '(inf+inf*j)'), ]: - + c = complex_(complex(real, imag)) assert c == complex(real, imag) assert c.real == real assert c.imag == imag assert repr(c) == should - + real, imag, should = (1e100, 3e66, '(1e+100+3e+66j)') c128 = numpy.complex128(complex(real, imag)) assert type(c128.real) is type(c128.imag) is numpy.float64 @@ -528,7 +546,9 @@ assert numpy.complex128(1.2) == numpy.complex128(complex(1.2, 0)) assert numpy.complex64(1.2) == numpy.complex64(complex(1.2, 0)) - raises (TypeError, numpy.array, [3+4j], dtype=float) + raises((ValueError, TypeError), numpy.array, [3+4j], dtype=float) + if sys.version_info >= (2, 7): + assert "{:g}".format(numpy.complex_(0.5+1.5j)) == '{:g}'.format(0.5+1.5j) def test_complex(self): import _numpypy as numpy @@ -547,8 +567,6 @@ assert d.kind == 'c' assert d.num == 14 assert d.char == 'F' - - def test_subclass_type(self): import _numpypy as numpy @@ -580,6 +598,9 @@ def test_various_types(self): import _numpypy as numpy + assert numpy.bool is bool + assert numpy.int is int + assert numpy.int16 is numpy.short assert numpy.int8 is numpy.byte assert numpy.bool_ is numpy.bool8 diff --git a/pypy/module/micronumpy/test/test_numarray.py b/pypy/module/micronumpy/test/test_numarray.py --- a/pypy/module/micronumpy/test/test_numarray.py +++ b/pypy/module/micronumpy/test/test_numarray.py @@ -1595,6 +1595,12 @@ a[a<0] = -a[a<0] assert (a == [1, 1]).all() + def test_int_list_index(slf): + from numpypy import array, arange + assert (array([10,11,12,13])[[1,2]] == [11, 12]).all() + assert (arange(6).reshape((2,3))[[0,1]] == [[0, 1, 2], [3, 4, 5]]).all() + assert arange(6).reshape((2,3))[(0,1)] == 1 + def test_int_array_index(self): from numpypy import array, arange, zeros b = arange(10)[array([3, 2, 1, 5])] @@ -1640,7 +1646,7 @@ assert _weakref.ref(a) def test_astype(self): - from _numpypy import array + from _numpypy import array, arange b = array(1).astype(float) assert b == 1 assert b.dtype == float @@ -1653,7 +1659,9 @@ b = array([0, 1, 2], dtype=complex).astype(bool) assert (b == [False, True, True]).all() assert b.dtype == 'bool' - + + a = arange(6, dtype='f4').reshape(2,3) + b = a.astype('i4') def test_base(self): from _numpypy import array @@ -1700,6 +1708,12 @@ n = a.dtype.itemsize assert s1[n-1] == s2[0] + a = array(0., dtype='longfloat') + s1 = map(ord, a.tostring()) + s2 = map(ord, a.byteswap().tostring()) + n = a.dtype.itemsize + assert s1[n-1] == s2[0] + def test_clip(self): from _numpypy import array a = array([1, 2, 17, -3, 12]) @@ -2368,6 +2382,7 @@ assert array([1, 2, 3], 'i2')[::2].tostring() == '\x01\x00\x03\x00' assert array([1, 2, 3], 'i2')[::2].tostring() == '\x00\x01\x00\x03' + assert array(0, dtype='i2').tostring() == '\x00\x00' def test_argsort_dtypes(self): from _numpypy import array, arange @@ -2455,7 +2470,7 @@ class AppTestRecordDtype(BaseNumpyAppTest): def test_zeros(self): - from _numpypy import zeros + from _numpypy import zeros, integer a = zeros(2, dtype=[('x', int), ('y', float)]) raises(IndexError, 'a[0]["xyz"]') assert a[0]['x'] == 0 diff --git a/pypy/module/micronumpy/types.py b/pypy/module/micronumpy/types.py --- a/pypy/module/micronumpy/types.py +++ b/pypy/module/micronumpy/types.py @@ -1030,6 +1030,14 @@ def for_computation(v): return float(v[0]), float(v[1]) + @raw_unary_op + def _to_builtin_type(self, v): + return v + + def to_builtin_type(self, space, box): + real,imag = self.for_computation(self.unbox(box)) + return space.newcomplex(real, imag) + def read_bool(self, arr, i, offset): v = self.for_computation(self._read(arr.storage, i, offset)) return bool(v[0]) or bool(v[1]) diff --git a/pypy/module/posix/test/test_posix2.py b/pypy/module/posix/test/test_posix2.py --- a/pypy/module/posix/test/test_posix2.py +++ b/pypy/module/posix/test/test_posix2.py @@ -514,12 +514,14 @@ assert res == '1\n' def test_popen_child_fds(self): - os = self.posix - from os.path import join - with open(join(self.pdir, 'file1'), 'r') as fd: - with os.popen('%s -c "import os; print os.read(%d, 10)"' % (self.python, fd.fileno())) as stream: + import os + with open(os.path.join(self.pdir, 'file1'), 'r') as fd: + with self.posix.popen('%s -c "import os; print os.read(%d, 10)" 2>&1' % (self.python, fd.fileno())) as stream: res = stream.read() - assert res == 'test1\n' + if os.name == 'nt': + assert '\nOSError: [Errno 9]' in res + else: + assert res == 'test1\n' if hasattr(__import__(os.name), '_getfullpathname'): def test__getfullpathname(self): diff --git a/pypy/module/pyexpat/interp_pyexpat.py b/pypy/module/pyexpat/interp_pyexpat.py --- a/pypy/module/pyexpat/interp_pyexpat.py +++ b/pypy/module/pyexpat/interp_pyexpat.py @@ -443,7 +443,10 @@ if XML_ParserFree: # careful with CPython interpreter shutdown XML_ParserFree(self.itself) if global_storage: - global_storage.free_nonmoving_id(self.id) + try: + global_storage.free_nonmoving_id(self.id) + except KeyError: + pass # maybe global_storage.clear() was already called @unwrap_spec(flag=int) def SetParamEntityParsing(self, space, flag): @@ -636,10 +639,13 @@ def ParseFile(self, space, w_file): """ParseFile(file) Parse XML data from file-like object.""" - # XXX not the more efficient method - w_data = space.call_method(w_file, 'read') - data = space.str_w(w_data) - return self.Parse(space, data, isfinal=True) + eof = False + while not eof: + w_data = space.call_method(w_file, 'read', space.wrap(2048)) + data = space.str_w(w_data) + eof = len(data) == 0 + w_res = self.Parse(space, data, isfinal=eof) + return w_res @unwrap_spec(base=str) def SetBase(self, space, base): diff --git a/pypy/module/pyexpat/test/test_parser.py b/pypy/module/pyexpat/test/test_parser.py --- a/pypy/module/pyexpat/test/test_parser.py +++ b/pypy/module/pyexpat/test/test_parser.py @@ -146,3 +146,24 @@ def test_model(self): import pyexpat assert isinstance(pyexpat.model.XML_CTYPE_EMPTY, int) + + def test_read_chunks(self): + import pyexpat + import StringIO + from contextlib import closing + + xml = '' + (' ' * 4096) + '' + with closing(StringIO.StringIO(xml)) as sio: + class FakeReader(): + def __init__(self): + self.read_count = 0 + + def read(self, size): + self.read_count += 1 + assert size > 0 + return sio.read(size) + + fake_reader = FakeReader() + p = pyexpat.ParserCreate() + p.ParseFile(fake_reader) + assert fake_reader.read_count == 4 diff --git a/pypy/module/rctime/test/test_rctime.py b/pypy/module/rctime/test/test_rctime.py --- a/pypy/module/rctime/test/test_rctime.py +++ b/pypy/module/rctime/test/test_rctime.py @@ -237,7 +237,7 @@ # input to [w]strftime is not kosher. if os.name == 'nt': raises(ValueError, rctime.strftime, '%f') - elif sys.platform == 'darwin': + elif sys.platform == 'darwin' or 'bsd' in sys.platform: # darwin strips % of unknown format codes # http://bugs.python.org/issue9811 assert rctime.strftime('%f') == 'f' diff --git a/pypy/module/signal/interp_signal.py b/pypy/module/signal/interp_signal.py --- a/pypy/module/signal/interp_signal.py +++ b/pypy/module/signal/interp_signal.py @@ -115,6 +115,11 @@ class Handlers: def __init__(self, space): self.handlers_w = {} + for signum in range(1, NSIG): + if WIN32 and signum not in signal_values: + self.handlers_w[signum] = space.w_None + else: + self.handlers_w[signum] = space.wrap(SIG_DFL) def _get_handlers(space): return space.fromcache(Handlers).handlers_w @@ -144,17 +149,12 @@ Return the current action for the given signal. The return value can be: SIG_IGN -- if the signal is being ignored SIG_DFL -- if the default action for the signal is in effect - None -- if an unknown handler is in effect (XXX UNIMPLEMENTED) + None -- if an unknown handler is in effect anything else -- the callable Python object used as a handler """ - if WIN32: - check_signum_exists(space, signum) - else: - check_signum_in_range(space, signum) + check_signum_in_range(space, signum) handlers_w = _get_handlers(space) - if signum in handlers_w: - return handlers_w[signum] - return space.wrap(SIG_DFL) + return handlers_w[signum] def default_int_handler(space, w_signum, w_frame): @@ -180,13 +180,6 @@ return space.w_None -def check_signum_exists(space, signum): - if signum in signal_values: - return - raise OperationError(space.w_ValueError, - space.wrap("invalid signal value")) - - def check_signum_in_range(space, signum): if 1 <= signum < NSIG: return @@ -208,11 +201,13 @@ A signal handler function is called with two arguments: the first is the signal number, the second is the interrupted stack frame. """ + if WIN32 and signum not in signal_values: + raise OperationError(space.w_ValueError, + space.wrap("invalid signal value")) if not space.threadlocals.ismainthread(): raise OperationError(space.w_ValueError, - space.wrap("signal() must be called from the " - "main thread")) - old_handler = getsignal(space, signum) + space.wrap("signal only works in main thread")) + check_signum_in_range(space, signum) if space.eq_w(w_handler, space.wrap(SIG_DFL)): pypysig_default(signum) @@ -224,7 +219,9 @@ space.wrap("'handler' must be a callable " "or SIG_DFL or SIG_IGN")) pypysig_setflag(signum) + handlers_w = _get_handlers(space) + old_handler = handlers_w[signum] handlers_w[signum] = w_handler return old_handler @@ -249,7 +246,7 @@ @jit.dont_look_inside @unwrap_spec(signum=int, flag=int) def siginterrupt(space, signum, flag): - check_signum_exists(space, signum) + check_signum_in_range(space, signum) if rffi.cast(lltype.Signed, c_siginterrupt(signum, flag)) < 0: errno = rposix.get_errno() raise OperationError(space.w_RuntimeError, space.wrap(errno)) diff --git a/pypy/module/signal/test/test_signal.py b/pypy/module/signal/test/test_signal.py --- a/pypy/module/signal/test/test_signal.py +++ b/pypy/module/signal/test/test_signal.py @@ -85,7 +85,6 @@ signal.signal(signum, signal.SIG_DFL) - def test_default_return(self): """ Test that signal.signal returns SIG_DFL if that is the current handler. @@ -99,7 +98,6 @@ finally: signal(SIGINT, SIG_DFL) - def test_ignore_return(self): """ Test that signal.signal returns SIG_IGN if that is the current handler. @@ -113,7 +111,6 @@ finally: signal(SIGINT, SIG_DFL) - def test_obj_return(self): """ Test that signal.signal returns a Python object if one is the current @@ -130,7 +127,6 @@ finally: signal(SIGINT, SIG_DFL) - def test_getsignal(self): """ Test that signal.getsignal returns the currently installed handler. @@ -151,17 +147,18 @@ finally: signal(SIGINT, SIG_DFL) - raises(ValueError, getsignal, 4444) - raises(ValueError, signal, 4444, lambda *args: None) + def test_check_signum(self): import sys + from signal import getsignal, signal, NSIG + + # signum out of range fails + raises(ValueError, getsignal, NSIG) + raises(ValueError, signal, NSIG, lambda *args: None) + + # on windows invalid signal within range should pass getsignal but fail signal if sys.platform == 'win32': - raises(ValueError, signal, 42, lambda *args: None) + assert getsignal(7) == None raises(ValueError, signal, 7, lambda *args: None) - elif sys.platform == 'darwin': - raises(ValueError, signal, 42, lambda *args: None) - else: - signal(42, lambda *args: None) - signal(42, SIG_DFL) def test_alarm(self): try: diff --git a/pypy/module/test_lib_pypy/test_cPickle.py b/pypy/module/test_lib_pypy/test_cPickle.py new file mode 100644 --- /dev/null +++ b/pypy/module/test_lib_pypy/test_cPickle.py @@ -0,0 +1,7 @@ +from __future__ import absolute_import +import py + +from lib_pypy import cPickle + +def test_stack_underflow(): + py.test.raises(cPickle.UnpicklingError, cPickle.loads, "a string") diff --git a/pypy/module/test_lib_pypy/test_collections.py b/pypy/module/test_lib_pypy/test_collections.py --- a/pypy/module/test_lib_pypy/test_collections.py +++ b/pypy/module/test_lib_pypy/test_collections.py @@ -1,8 +1,61 @@ +""" +Extra tests for the pure Python PyPy _collections module +(not used in normal PyPy's) +""" + from __future__ import absolute_import from lib_pypy import _collections as collections import py class TestDeque: + def setup_method(self, method): + self.n = 10 + self.d = collections.deque(range(self.n)) + + def test_deque(self): + assert len(self.d) == self.n + for i in range(self.n): + assert i == self.d[i] + for i in range(self.n-1, -1, -1): + assert self.d.pop() == i + assert len(self.d) == 0 + + def test_deque_iter(self): + it = iter(self.d) + py.test.raises(TypeError, len, it) + assert it.next() == 0 + self.d.pop() + py.test.raises(RuntimeError, it.next) + + def test_deque_reversed(self): + it = reversed(self.d) + py.test.raises(TypeError, len, it) + assert it.next() == self.n-1 + assert it.next() == self.n-2 + self.d.pop() + py.test.raises(RuntimeError, it.next) + + def test_deque_remove(self): + d = self.d + py.test.raises(ValueError, d.remove, "foobar") + + def test_mutate_during_remove(self): + # Handle evil mutator + class MutateCmp: + def __init__(self, deque, result): + self.deque = deque + self.result = result + def __eq__(self, other): + self.deque.clear() + return self.result + + for match in (True, False): + d = collections.deque(['ab']) + d.extend([MutateCmp(d, match), 'c']) + py.test.raises(IndexError, d.remove, 'c') + assert len(d) == 0 + +class TestDequeExtra: def test_remove_empty(self): d = collections.deque([]) py.test.raises(ValueError, d.remove, 1) @@ -16,6 +69,17 @@ d = collections.deque([MutatingCmp()]) py.test.raises(IndexError, d.remove, 1) + def test_remove_failing(self): + class FailingCmp(object): + def __eq__(self, other): + assert False + + f = FailingCmp() + d = collections.deque([1, 2, 3, f, 4, 5]) + d.remove(3) + py.test.raises(AssertionError, d.remove, 4) + assert d == collections.deque([1, 2, f, 4, 5]) + def test_maxlen(self): d = collections.deque([], 3) d.append(1); d.append(2); d.append(3); d.append(4) @@ -51,3 +115,22 @@ # SF bug #1486663 -- this used to erroneously raise a TypeError SubclassWithKwargs(newarg=1) + +class TestDefaultDict: + def test_copy(self): + def f(): + return 42 + d = collections.defaultdict(f, {2: 3}) + # + d1 = d.copy() + assert type(d1) is collections.defaultdict + assert len(d1) == 1 + assert d1[2] == 3 + assert d1[3] == 42 + # + import copy + d2 = copy.deepcopy(d) + assert type(d2) is collections.defaultdict + assert len(d2) == 1 + assert d2[2] == 3 + assert d2[3] == 42 diff --git a/pypy/module/test_lib_pypy/test_collections_extra.py b/pypy/module/test_lib_pypy/test_collections_extra.py deleted file mode 100644 --- a/pypy/module/test_lib_pypy/test_collections_extra.py +++ /dev/null @@ -1,25 +0,0 @@ - -""" -Extra tests for the pure Python PyPy _collections module -(not used in normal PyPy's) -""" - -class AppTestCollections: - def test_copy(self): - import _collections - def f(): - return 42 - d = _collections.defaultdict(f, {2: 3}) - # - d1 = d.copy() - assert type(d1) is _collections.defaultdict - assert len(d1) == 1 - assert d1[2] == 3 - assert d1[3] == 42 - # - import copy - d2 = copy.deepcopy(d) - assert type(d2) is _collections.defaultdict - assert len(d2) == 1 - assert d2[2] == 3 - assert d2[3] == 42 diff --git a/pypy/module/test_lib_pypy/test_datetime.py b/pypy/module/test_lib_pypy/test_datetime.py --- a/pypy/module/test_lib_pypy/test_datetime.py +++ b/pypy/module/test_lib_pypy/test_datetime.py @@ -1,8 +1,9 @@ +"""Additional tests for datetime.""" + from __future__ import absolute_import +from lib_pypy import datetime import py -from lib_pypy import datetime - def test_repr(): print datetime expected = "datetime.datetime(1, 2, 3, 0, 0)" @@ -83,13 +84,62 @@ dt = datetime.datetime.utcfromtimestamp(0) assert isinstance(dt.microsecond, int) -def test_integer_args(): +def test_default_args(): + with py.test.raises(TypeError): + datetime.datetime() + with py.test.raises(TypeError): + datetime.datetime(10) + with py.test.raises(TypeError): + datetime.datetime(10, 10) + datetime.datetime(10, 10, 10) + +def test_check_arg_types(): + import decimal + class Number: + def __init__(self, value): + self.value = value + def __int__(self): + return self.value + i10 = 10 + l10 = 10L + d10 = decimal.Decimal(10) + d11 = decimal.Decimal(10.9) + c10 = Number(10) + o10 = Number(10L) + assert datetime.datetime(i10, i10, i10, i10, i10, i10, i10) == \ + datetime.datetime(l10, l10, l10, l10, l10, l10, l10) == \ + datetime.datetime(d10, d10, d10, d10, d10, d10, d10) == \ + datetime.datetime(d11, d11, d11, d11, d11, d11, d11) == \ + datetime.datetime(c10, c10, c10, c10, c10, c10, c10) == \ + datetime.datetime(o10, o10, o10, o10, o10, o10, o10) + + with py.test.raises(TypeError): + datetime.datetime(10, 10, '10') + + f10 = Number(10.9) + with py.test.raises(TypeError): + datetime.datetime(10, 10, f10) + + class Float(float): + pass + s10 = Float(10.9) + with py.test.raises(TypeError): + datetime.datetime(10, 10, s10) + + with py.test.raises(TypeError): + datetime.datetime(10., 10, 10) + with py.test.raises(TypeError): + datetime.datetime(10, 10., 10) with py.test.raises(TypeError): datetime.datetime(10, 10, 10.) with py.test.raises(TypeError): + datetime.datetime(10, 10, 10, 10.) + with py.test.raises(TypeError): datetime.datetime(10, 10, 10, 10, 10.) with py.test.raises(TypeError): datetime.datetime(10, 10, 10, 10, 10, 10.) + with py.test.raises(TypeError): + datetime.datetime(10, 10, 10, 10, 10, 10, 10.) def test_utcnow_microsecond(): import copy diff --git a/pypy/module/test_lib_pypy/test_deque_extra.py b/pypy/module/test_lib_pypy/test_deque_extra.py deleted file mode 100644 --- a/pypy/module/test_lib_pypy/test_deque_extra.py +++ /dev/null @@ -1,56 +0,0 @@ -# Deque Tests -from __future__ import absolute_import -import py - - -n = 10 -class Test_deque: - def setup_method(self,method): - - from lib_pypy._collections import deque - self.deque = deque - self.d = deque(range(n)) - - def test_deque(self): - - assert len(self.d) == n - for i in range(n): - assert i == self.d[i] - for i in range(n-1, -1, -1): - assert self.d.pop() == i - assert len(self.d) == 0 - - def test_deque_iter(self): - it = iter(self.d) - py.test.raises(TypeError, len, it) - assert it.next() == 0 - self.d.pop() - py.test.raises(RuntimeError, it.next) - - def test_deque_reversed(self): - it = reversed(self.d) - py.test.raises(TypeError, len, it) - assert it.next() == n-1 - assert it.next() == n-2 - self.d.pop() - py.test.raises(RuntimeError, it.next) - - def test_deque_remove(self): - d = self.d - py.test.raises(ValueError, d.remove, "foobar") - - def test_mutate_during_remove(self): - # Handle evil mutator - class MutateCmp: - def __init__(self, deque, result): - self.deque = deque - self.result = result - def __eq__(self, other): - self.deque.clear() - return self.result - - for match in (True, False): - d = self.deque(['ab']) - d.extend([MutateCmp(d, match), 'c']) - py.test.raises(IndexError, d.remove, 'c') - assert len(d) == 0 diff --git a/pypy/module/test_lib_pypy/test_greenlet.py b/pypy/module/test_lib_pypy/test_greenlet.py --- a/pypy/module/test_lib_pypy/test_greenlet.py +++ b/pypy/module/test_lib_pypy/test_greenlet.py @@ -310,3 +310,12 @@ assert g.gr_frame.f_code.co_name == 'f2' g.switch() assert g.gr_frame is None + + def test_override_nonzero(self): + from greenlet import greenlet + class G(greenlet): + def __nonzero__(self): + raise ValueError + g = G(lambda: 42) + x = g.switch() + assert x == 42 diff --git a/pypy/module/thread/gil.py b/pypy/module/thread/gil.py --- a/pypy/module/thread/gil.py +++ b/pypy/module/thread/gil.py @@ -49,6 +49,8 @@ return result def reinit_threads(self, space): + "Called in the child process after a fork()" + OSThreadLocals.reinit_threads(self, space) if self.gil_ready: # re-initialize the gil if needed self._initialize_gil(space) diff --git a/pypy/module/thread/test/test_fork.py b/pypy/module/thread/test/test_fork.py --- a/pypy/module/thread/test/test_fork.py +++ b/pypy/module/thread/test/test_fork.py @@ -57,3 +57,30 @@ self.timeout_killer(pid, 5) exitcode = os.waitpid(pid, 0)[1] assert exitcode == 0 # if 9, process was killed by timer! + + def test_forked_is_main_thread(self): + "Checks that a forked interpreter is the main thread" + import os, thread, signal + + if not hasattr(os, 'fork'): + skip("No fork on this platform") + + def threadfunction(): + pid = os.fork() + if pid == 0: + print 'in child' + # signal() only works from the 'main' thread + signal.signal(signal.SIGUSR1, signal.SIG_IGN) + os._exit(42) + else: + self.timeout_killer(pid, 5) + exitcode = os.waitpid(pid, 0)[1] + feedback.append(exitcode) + + feedback = [] + thread.start_new_thread(threadfunction, ()) + self.waitfor(lambda: feedback) + # if 0, an (unraisable) exception was raised from the forked thread. + # if 9, process was killed by timer. + # if 42<<8, os._exit(42) was correctly reached. + assert feedback == [42<<8] diff --git a/pypy/module/thread/threadlocals.py b/pypy/module/thread/threadlocals.py --- a/pypy/module/thread/threadlocals.py +++ b/pypy/module/thread/threadlocals.py @@ -57,3 +57,7 @@ thread_is_stopping(self.getvalue()) finally: self.setvalue(None) + + def reinit_threads(self, space): + "Called in the child process after a fork()" + self._mainthreadident = thread.get_ident() diff --git a/pypy/module/zipimport/interp_zipimport.py b/pypy/module/zipimport/interp_zipimport.py --- a/pypy/module/zipimport/interp_zipimport.py +++ b/pypy/module/zipimport/interp_zipimport.py @@ -172,24 +172,24 @@ return mtime def check_newer_pyfile(self, space, filename, timestamp): + # check if the timestamp stored in the .pyc is matching + # the actual timestamp of the .py file, if any mtime = self._parse_mtime(space, filename) if mtime == 0: return False - return mtime > timestamp - - def check_compatible_mtime(self, space, filename, timestamp): - mtime = self._parse_mtime(space, filename) - if mtime == 0 or mtime != (timestamp & (~1)): - return False - return True + # Lenient date/time comparison function. The precision of the mtime + # in the archive is lower than the mtime stored in a .pyc: we + # must allow a difference of at most one second. + d = mtime - timestamp + if d < 0: + d = -d + return d > 1 # more than one second => different def can_use_pyc(self, space, filename, magic, timestamp): if magic != importing.get_pyc_magic(space): return False if self.check_newer_pyfile(space, filename[:-1], timestamp): return False - if not self.check_compatible_mtime(space, filename, timestamp): - return False return True def import_pyc_file(self, space, modname, filename, buf, pkgpath): diff --git a/pypy/module/zipimport/test/test_zipimport.py b/pypy/module/zipimport/test/test_zipimport.py --- a/pypy/module/zipimport/test/test_zipimport.py +++ b/pypy/module/zipimport/test/test_zipimport.py @@ -95,6 +95,9 @@ """) self.w_modules = [] + def w_now_in_the_future(self, delta): + self.now += delta + def w_writefile(self, filename, data): import sys import time @@ -264,10 +267,12 @@ import os import zipimport data = "saddsadsa" + pyc_data = self.test_pyc + self.now_in_the_future(+5) # write the zipfile 5 secs after the .pyc self.writefile("xxx", data) self.writefile("xx/__init__.py", "5") self.writefile("yy.py", "3") - self.writefile('uu.pyc', self.test_pyc) + self.writefile('uu.pyc', pyc_data) z = zipimport.zipimporter(self.zipfile) assert z.get_data(self.zipfile + os.sep + "xxx") == data assert z.is_package("xx") @@ -277,6 +282,7 @@ raises(ImportError, "z.get_source('zz')") #assert z.get_code('yy') == py.code.Source('3').compile() #assert z.get_code('uu') == self.co + assert z.get_code('uu') assert z.get_code('xx') assert z.get_source('xx') == "5" assert z.archive == self.zipfile diff --git a/rpython/annotator/description.py b/rpython/annotator/description.py --- a/rpython/annotator/description.py +++ b/rpython/annotator/description.py @@ -497,8 +497,8 @@ # will do the right thing in s_get_value(). if isinstance(value, staticmethod) and mixin: # make a new copy of staticmethod - value = staticmethod(func_with_new_name(value.__func__, - value.__func__.__name__)) + func = value.__get__(42) + value = staticmethod(func_with_new_name(func, func.__name__)) if type(value) in MemberDescriptorTypes: # skip __slots__, showing up in the class as 'member' objects diff --git a/rpython/jit/metainterp/pyjitpl.py b/rpython/jit/metainterp/pyjitpl.py --- a/rpython/jit/metainterp/pyjitpl.py +++ b/rpython/jit/metainterp/pyjitpl.py @@ -2108,8 +2108,11 @@ num_green_args = self.jitdriver_sd.num_green_args greenkey = original_boxes[:num_green_args] if not self.partial_trace: - assert self.get_procedure_token(greenkey) is None or \ - self.get_procedure_token(greenkey).target_tokens is None + ptoken = self.get_procedure_token(greenkey) + if ptoken is not None and ptoken.target_tokens is not None: + # XXX this path not tested, but shown to occur on pypy-c :-( + self.staticdata.log('cancelled: we already have a token now') + raise SwitchToBlackhole(Counters.ABORT_BAD_LOOP) if self.partial_trace: target_token = compile.compile_retrace(self, greenkey, start, original_boxes[num_green_args:], diff --git a/rpython/translator/c/gcc/test/test_asmgcroot.py b/rpython/translator/c/gcc/test/test_asmgcroot.py --- a/rpython/translator/c/gcc/test/test_asmgcroot.py +++ b/rpython/translator/c/gcc/test/test_asmgcroot.py @@ -73,7 +73,11 @@ else: redirect = '' if config.translation.shared and os.name == 'posix': - env = 'LD_LIBRARY_PATH="%s" ' % (exe_name.dirpath(),) + library_path = exe_name.dirpath() + if sys.platform == 'darwin': + env = 'DYLD_LIBRARY_PATH="%s" ' % library_path + else: + env = 'LD_LIBRARY_PATH="%s" ' % library_path else: env = '' cwd = os.getcwd() diff --git a/rpython/translator/c/test/test_standalone.py b/rpython/translator/c/test/test_standalone.py --- a/rpython/translator/c/test/test_standalone.py +++ b/rpython/translator/c/test/test_standalone.py @@ -687,8 +687,12 @@ t, cbuilder = self.compile(entry_point, shared=True) assert cbuilder.shared_library_name is not None assert cbuilder.shared_library_name != cbuilder.executable_name - monkeypatch.setenv('LD_LIBRARY_PATH', - cbuilder.shared_library_name.dirpath()) + if os.name == 'posix': + library_path = cbuilder.shared_library_name.dirpath() + if sys.platform == 'darwin': + monkeypatch.setenv('DYLD_LIBRARY_PATH', library_path) + else: + monkeypatch.setenv('LD_LIBRARY_PATH', library_path) out, err = cbuilder.cmdexec("a b") assert out == "3" diff --git a/rpython/translator/goal/translate.py b/rpython/translator/goal/translate.py --- a/rpython/translator/goal/translate.py +++ b/rpython/translator/goal/translate.py @@ -50,7 +50,7 @@ return result translate_optiondescr = OptionDescription("translate", "XXX", [ - StrOption("targetspec", "XXX", default='../../pypy/goal/targetpypystandalone', + StrOption("targetspec", "XXX", default='../../../pypy/goal/targetpypystandalone', cmdline=None), ChoiceOption("opt", "optimization level", OPT_LEVELS, default=DEFAULT_OPT_LEVEL, diff --git a/rpython/translator/platform/__init__.py b/rpython/translator/platform/__init__.py --- a/rpython/translator/platform/__init__.py +++ b/rpython/translator/platform/__init__.py @@ -89,8 +89,11 @@ # Set LD_LIBRARY_PATH on posix platforms if os.name == 'posix' and compilation_info is not None: - env['LD_LIBRARY_PATH'] = ':'.join( - [str(i) for i in compilation_info.library_dirs]) + library_path = ':'.join([str(i) for i in compilation_info.library_dirs]) + if sys.platform == 'darwin': + env['DYLD_LIBRARY_PATH'] = library_path + else: + env['LD_LIBRARY_PATH'] = library_path returncode, stdout, stderr = _run_subprocess(str(executable), args, env) diff --git a/rpython/translator/platform/posix.py b/rpython/translator/platform/posix.py --- a/rpython/translator/platform/posix.py +++ b/rpython/translator/platform/posix.py @@ -47,12 +47,15 @@ if not eci.export_symbols: return [] + if sys.platform == 'freebsd7': + eci.export_symbols += ('__progname', 'environ') + response_file = self._make_response_file("dynamic-symbols-") f = response_file.open("w") - f.write("{\n") + f.write("{\n\tglobal:\n") for sym in eci.export_symbols: - f.write("%s;\n" % (sym,)) - f.write("};") + f.write("\t\t%s;\n" % (sym,)) + f.write("\tlocal:\n\t\t*;\n};") f.close() if relto: diff --git a/rpython/translator/tool/test/test_cbuild.py b/rpython/translator/tool/test/test_cbuild.py --- a/rpython/translator/tool/test/test_cbuild.py +++ b/rpython/translator/tool/test/test_cbuild.py @@ -77,6 +77,10 @@ int get() { return 42; + } + int shouldnt_export() + { + return 43; }'''], export_symbols = ['get'] ) @@ -87,6 +91,7 @@ except ImportError: py.test.skip("Need ctypes for that test") assert ctypes.CDLL(neweci.libraries[0]).get() == 42 + assert not hasattr(ctypes.CDLL(neweci.libraries[0]), 'shouldnt_export') assert not neweci.separate_module_sources assert not neweci.separate_module_files From noreply at buildbot.pypy.org Sun Feb 10 04:46:11 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sun, 10 Feb 2013 04:46:11 +0100 (CET) Subject: [pypy-commit] pypy default: also merge these tests so they run Message-ID: <20130210034611.E50511C1028@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61018:7d728a69c7ce Date: 2013-02-09 22:40 -0500 http://bitbucket.org/pypy/pypy/changeset/7d728a69c7ce/ Log: also merge these tests so they run diff --git a/lib_pypy/pypy_test/test_defaultdict.py b/lib_pypy/pypy_test/test_defaultdict.py deleted file mode 100644 --- a/lib_pypy/pypy_test/test_defaultdict.py +++ /dev/null @@ -1,130 +0,0 @@ -# defaultdict Tests -# from CPython2.5 -from __future__ import absolute_import -import py -import sys -if sys.version_info < (2, 5): - # the app-level defaultdict relies on the interp-level dict - # calling __missing__() - py.test.skip("these tests only run on top of CPython 2.5") - -import copy - -from lib_pypy._collections import defaultdict - -def foobar(): - return list - -class Test_defaultdict: - - def test_basic(self): - d1 = defaultdict() - assert d1.default_factory is None - d1.default_factory = list - d1[12].append(42) - assert d1 == {12: [42]} - d1[12].append(24) - assert d1 == {12: [42, 24]} - d1[13] - d1[14] - assert d1 == {12: [42, 24], 13: [], 14: []} - assert d1[12] is not d1[13] is not d1[14] - d2 = defaultdict(list, foo=1, bar=2) - assert d2.default_factory == list - assert d2 == {"foo": 1, "bar": 2} - assert d2["foo"] == 1 - assert d2["bar"] == 2 - assert d2[42] == [] - assert "foo" in d2 - assert "foo" in d2.keys() - assert "bar" in d2 - assert "bar" in d2.keys() - assert 42 in d2 - assert 42 in d2.keys() - assert 12 not in d2 - assert 12 not in d2.keys() - d2.default_factory = None - assert d2.default_factory == None - py.test.raises(KeyError, d2.__getitem__, 15) - py.test.raises(TypeError, defaultdict, 1) - - def test_constructor(self): - assert defaultdict(None) == {} - assert defaultdict(None, {1: 2}) == {1: 2} - - def test_missing(self): - d1 = defaultdict() - py.test.raises(KeyError, d1.__missing__, 42) - d1.default_factory = list - assert d1.__missing__(42) == [] - - def test_repr(self): - d1 = defaultdict() - assert d1.default_factory == None - assert repr(d1) == "defaultdict(None, {})" - d1[11] = 41 - assert repr(d1) == "defaultdict(None, {11: 41})" - d2 = defaultdict(int) - assert d2.default_factory == int - d2[12] = 42 - assert repr(d2) == "defaultdict(, {12: 42})" - def foo(): return 43 - d3 = defaultdict(foo) - assert d3.default_factory is foo - d3[13] - assert repr(d3) == "defaultdict(%s, {13: 43})" % repr(foo) - d4 = defaultdict(int) - d4[14] = defaultdict() - assert repr(d4) == "defaultdict(%s, {14: defaultdict(None, {})})" % repr(int) - - def test_recursive_repr(self): - # Issue2045: stack overflow when default_factory is a bound method - class sub(defaultdict): - def __init__(self): - self.default_factory = self._factory - def _factory(self): - return [] - d = sub() - assert repr(d).startswith( - "defaultdict(, {12: 42})" + def foo(): return 43 + d3 = collections.defaultdict(foo) + assert d3.default_factory is foo + d3[13] + assert repr(d3) == "defaultdict(%s, {13: 43})" % repr(foo) + d4 = collections.defaultdict(int) + d4[14] = collections.defaultdict() + assert repr(d4) == "defaultdict(%s, {14: defaultdict(None, {})})" % repr(int) + + def test_recursive_repr(self): + # Issue2045: stack overflow when default_factory is a bound method + class sub(collections.defaultdict): + def __init__(self): + self.default_factory = self._factory + def _factory(self): + return [] + d = sub() + assert repr(d).startswith( + "defaultdict( Author: Brian Kearns Branch: cleanup-tests Changeset: r61019:0033be75b76f Date: 2013-02-09 22:48 -0500 http://bitbucket.org/pypy/pypy/changeset/0033be75b76f/ Log: merge default diff --git a/pypy/module/test_lib_pypy/test_cstringio.py b/pypy/module/test_lib_pypy/test_cStringIO.py rename from pypy/module/test_lib_pypy/test_cstringio.py rename to pypy/module/test_lib_pypy/test_cStringIO.py --- a/pypy/module/test_lib_pypy/test_cstringio.py +++ b/pypy/module/test_lib_pypy/test_cStringIO.py @@ -1,4 +1,3 @@ - """ Tests for the PyPy cStringIO implementation. """ @@ -8,7 +7,6 @@ cls.w_io = cls.space.appexec([], "(): import cStringIO; return cStringIO") cls.w_bytes = cls.space.wrap('some bytes') - def test_reset(self): """ Test that the reset method of cStringIO objects sets the position diff --git a/pypy/module/test_lib_pypy/test_collections.py b/pypy/module/test_lib_pypy/test_collections.py --- a/pypy/module/test_lib_pypy/test_collections.py +++ b/pypy/module/test_lib_pypy/test_collections.py @@ -116,21 +116,120 @@ # SF bug #1486663 -- this used to erroneously raise a TypeError SubclassWithKwargs(newarg=1) +def foobar(): + return list + class TestDefaultDict: + def test_basic(self): + d1 = collections.defaultdict() + assert d1.default_factory is None + d1.default_factory = list + d1[12].append(42) + assert d1 == {12: [42]} + d1[12].append(24) + assert d1 == {12: [42, 24]} + d1[13] + d1[14] + assert d1 == {12: [42, 24], 13: [], 14: []} + assert d1[12] is not d1[13] is not d1[14] + d2 = collections.defaultdict(list, foo=1, bar=2) + assert d2.default_factory == list + assert d2 == {"foo": 1, "bar": 2} + assert d2["foo"] == 1 + assert d2["bar"] == 2 + assert d2[42] == [] + assert "foo" in d2 + assert "foo" in d2.keys() + assert "bar" in d2 + assert "bar" in d2.keys() + assert 42 in d2 + assert 42 in d2.keys() + assert 12 not in d2 + assert 12 not in d2.keys() + d2.default_factory = None + assert d2.default_factory == None + py.test.raises(KeyError, d2.__getitem__, 15) + py.test.raises(TypeError, collections.defaultdict, 1) + + def test_constructor(self): + assert collections.defaultdict(None) == {} + assert collections.defaultdict(None, {1: 2}) == {1: 2} + + def test_missing(self): + d1 = collections.defaultdict() + py.test.raises(KeyError, d1.__missing__, 42) + d1.default_factory = list + assert d1.__missing__(42) == [] + + def test_repr(self): + d1 = collections.defaultdict() + assert d1.default_factory == None + assert repr(d1) == "defaultdict(None, {})" + d1[11] = 41 + assert repr(d1) == "defaultdict(None, {11: 41})" + d2 = collections.defaultdict(int) + assert d2.default_factory == int + d2[12] = 42 + assert repr(d2) == "defaultdict(, {12: 42})" + def foo(): return 43 + d3 = collections.defaultdict(foo) + assert d3.default_factory is foo + d3[13] + assert repr(d3) == "defaultdict(%s, {13: 43})" % repr(foo) + d4 = collections.defaultdict(int) + d4[14] = collections.defaultdict() + assert repr(d4) == "defaultdict(%s, {14: defaultdict(None, {})})" % repr(int) + + def test_recursive_repr(self): + # Issue2045: stack overflow when default_factory is a bound method + class sub(collections.defaultdict): + def __init__(self): + self.default_factory = self._factory + def _factory(self): + return [] + d = sub() + assert repr(d).startswith( + "defaultdict(, {12: 42})" - def foo(): return 43 - d3 = defaultdict(foo) - assert d3.default_factory is foo - d3[13] - assert repr(d3) == "defaultdict(%s, {13: 43})" % repr(foo) - d4 = defaultdict(int) - d4[14] = defaultdict() - assert repr(d4) == "defaultdict(%s, {14: defaultdict(None, {})})" % repr(int) - - def test_recursive_repr(self): - # Issue2045: stack overflow when default_factory is a bound method - class sub(defaultdict): - def __init__(self): - self.default_factory = self._factory - def _factory(self): - return [] - d = sub() - assert repr(d).startswith( - "defaultdict( Author: Brian Kearns Branch: cleanup-tests Changeset: r61020:d99b3dabfe66 Date: 2013-02-09 22:56 -0500 http://bitbucket.org/pypy/pypy/changeset/d99b3dabfe66/ Log: disable this out of date test until it can be updated diff --git a/pypy/module/test_lib_pypy/test_coroutine.py b/pypy/module/test_lib_pypy/test_coroutine.py --- a/pypy/module/test_lib_pypy/test_coroutine.py +++ b/pypy/module/test_lib_pypy/test_coroutine.py @@ -1,6 +1,8 @@ from __future__ import absolute_import from py.test import skip, raises +skip('test needs to be updated') + try: from stackless import coroutine, CoroutineExit except ImportError, e: From noreply at buildbot.pypy.org Sun Feb 10 05:01:36 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sun, 10 Feb 2013 05:01:36 +0100 (CET) Subject: [pypy-commit] pypy cleanup-tests: trash this file Message-ID: <20130210040136.66D981C1028@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: cleanup-tests Changeset: r61021:70eaa166d819 Date: 2013-02-09 23:00 -0500 http://bitbucket.org/pypy/pypy/changeset/70eaa166d819/ Log: trash this file diff --git a/pypy/module/test_lib_pypy/sample_aop_code.py b/pypy/module/test_lib_pypy/sample_aop_code.py deleted file mode 100644 --- a/pypy/module/test_lib_pypy/sample_aop_code.py +++ /dev/null @@ -1,50 +0,0 @@ -code = """ -def foo(b, c): - ''' - pre: - b < c - ''' - print 'foo' - a = 2 - d = bar(a) - print d - return b+a+c+d - - -def bar(val): - print 'bar', val - return 42 - -def baz(b,c): - try: - return foo(b,c) - finally: - bar(3) - -class Mumble: - def __init__(self, param): - self.p = param - def frobble(self, b): - return 3 * self.p + b - def __del__(self): - print 'Mumble goes poof' - -def truc(): - m = Mumble(2) - r = m.frobble(1) - print 'truc', r, 'expected 7' - return r -""" -import os, sys -import os.path as osp - -def _make_filename(name): - dir = sys.path[0] # see setup_class() - if not name.endswith('.py'): - name += ".py" - return osp.join(dir, name) - -def write_module(name): - f = open(_make_filename(name), 'w') - f.write(code) - f.close() From noreply at buildbot.pypy.org Sun Feb 10 05:28:09 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sun, 10 Feb 2013 05:28:09 +0100 (CET) Subject: [pypy-commit] pypy default: update whatsnew Message-ID: <20130210042809.7D3D51C1028@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61024:9ad6c8147ff3 Date: 2013-02-09 23:15 -0500 http://bitbucket.org/pypy/pypy/changeset/9ad6c8147ff3/ Log: update whatsnew diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst --- a/pypy/doc/whatsnew-head.rst +++ b/pypy/doc/whatsnew-head.rst @@ -54,3 +54,7 @@ .. branch: missing-ndarray-attributes Some missing attributes from ndarrays + +.. branch: cleanup-tests +Consolidated the lib_pypy/pypy_test and pypy/module/test_lib_pypy tests into ++one directory for reduced confusion and so they all run nightly. From noreply at buildbot.pypy.org Sun Feb 10 05:28:10 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sun, 10 Feb 2013 05:28:10 +0100 (CET) Subject: [pypy-commit] pypy default: fix numpy test_abstract_types for 32bit Message-ID: <20130210042810.CF6121C1028@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61025:8556098ab5f0 Date: 2013-02-09 23:27 -0500 http://bitbucket.org/pypy/pypy/changeset/8556098ab5f0/ Log: fix numpy test_abstract_types for 32bit diff --git a/pypy/module/micronumpy/test/test_dtypes.py b/pypy/module/micronumpy/test/test_dtypes.py --- a/pypy/module/micronumpy/test/test_dtypes.py +++ b/pypy/module/micronumpy/test/test_dtypes.py @@ -271,15 +271,22 @@ assert 'unsignedinteger' in str(exc.value) raises(TypeError, numpy.floating, 0) raises(TypeError, numpy.inexact, 0) + # numpy allows abstract types in array creation - a = numpy.array([4,4], numpy.integer) - assert a.dtype is numpy.dtype('int64') - a = numpy.array([4,4], numpy.number) - assert a.dtype is numpy.dtype('float') - a = numpy.array([4,4], numpy.signedinteger) - assert a.dtype is numpy.dtype('int64') - a = numpy.array([4,4], numpy.unsignedinteger) - assert a.dtype is numpy.dtype('uint64') + a_n = numpy.array([4,4], numpy.number) + a_i = numpy.array([4,4], numpy.integer) + a_s = numpy.array([4,4], numpy.signedinteger) + a_u = numpy.array([4,4], numpy.unsignedinteger) + if self.ptr_size == 4: + assert a_n.dtype is numpy.dtype('float32') + assert a_i.dtype is numpy.dtype('int32') + assert a_s.dtype is numpy.dtype('int32') + assert a_u.dtype is numpy.dtype('uint32') + else: + assert a_n.dtype is numpy.dtype('float64') + assert a_i.dtype is numpy.dtype('int64') + assert a_s.dtype is numpy.dtype('int64') + assert a_u.dtype is numpy.dtype('uint64') # too ambitious for now #a = numpy.array('xxxx', numpy.generic) #assert a.dtype is numpy.dtype('|V4') From noreply at buildbot.pypy.org Sun Feb 10 06:31:10 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sun, 10 Feb 2013 06:31:10 +0100 (CET) Subject: [pypy-commit] pypy default: mangle pypy's non-standard JSONEncoder modifications to avoid namespace clashes Message-ID: <20130210053110.94A7F1C1029@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61026:3655afd07f2f Date: 2013-02-10 00:07 -0500 http://bitbucket.org/pypy/pypy/changeset/3655afd07f2f/ Log: mangle pypy's non-standard JSONEncoder modifications to avoid namespace clashes diff --git a/lib-python/2.7/json/encoder.py b/lib-python/2.7/json/encoder.py --- a/lib-python/2.7/json/encoder.py +++ b/lib-python/2.7/json/encoder.py @@ -138,16 +138,16 @@ self.skipkeys = skipkeys self.ensure_ascii = ensure_ascii if ensure_ascii: - self.encoder = raw_encode_basestring_ascii + self.__encoder = raw_encode_basestring_ascii else: - self.encoder = raw_encode_basestring + self.__encoder = raw_encode_basestring if encoding != 'utf-8': - orig_encoder = self.encoder + orig_encoder = self.__encoder def encoder(o): if isinstance(o, str): o = o.decode(encoding) return orig_encoder(o) - self.encoder = encoder + self.__encoder = encoder self.check_circular = check_circular self.allow_nan = allow_nan self.sort_keys = sort_keys @@ -193,10 +193,10 @@ builder = StringBuilder() else: builder = UnicodeBuilder() - self._encode(o, markers, builder, 0) + self.__encode(o, markers, builder, 0) return builder.build() - def _emit_indent(self, builder, _current_indent_level): + def __emit_indent(self, builder, _current_indent_level): if self.indent is not None: _current_indent_level += 1 newline_indent = '\n' + (' ' * (self.indent * @@ -207,15 +207,15 @@ separator = self.item_separator return separator, _current_indent_level - def _emit_unindent(self, builder, _current_indent_level): + def __emit_unindent(self, builder, _current_indent_level): if self.indent is not None: builder.append('\n') builder.append(' ' * (self.indent * (_current_indent_level - 1))) - def _encode(self, o, markers, builder, _current_indent_level): + def __encode(self, o, markers, builder, _current_indent_level): if isinstance(o, basestring): builder.append('"') - builder.append(self.encoder(o)) + builder.append(self.__encoder(o)) builder.append('"') elif o is None: builder.append('null') @@ -226,46 +226,46 @@ elif isinstance(o, (int, long)): builder.append(str(o)) elif isinstance(o, float): - builder.append(self._floatstr(o)) + builder.append(self.__floatstr(o)) elif isinstance(o, (list, tuple)): if not o: builder.append('[]') return - self._encode_list(o, markers, builder, _current_indent_level) + self.__encode_list(o, markers, builder, _current_indent_level) elif isinstance(o, dict): if not o: builder.append('{}') return - self._encode_dict(o, markers, builder, _current_indent_level) + self.__encode_dict(o, markers, builder, _current_indent_level) else: - self._mark_markers(markers, o) + self.__mark_markers(markers, o) res = self.default(o) - self._encode(res, markers, builder, _current_indent_level) - self._remove_markers(markers, o) + self.__encode(res, markers, builder, _current_indent_level) + self.__remove_markers(markers, o) return res - def _encode_list(self, l, markers, builder, _current_indent_level): - self._mark_markers(markers, l) + def __encode_list(self, l, markers, builder, _current_indent_level): + self.__mark_markers(markers, l) builder.append('[') first = True - separator, _current_indent_level = self._emit_indent(builder, + separator, _current_indent_level = self.__emit_indent(builder, _current_indent_level) for elem in l: if first: first = False else: builder.append(separator) - self._encode(elem, markers, builder, _current_indent_level) + self.__encode(elem, markers, builder, _current_indent_level) del elem # XXX grumble - self._emit_unindent(builder, _current_indent_level) + self.__emit_unindent(builder, _current_indent_level) builder.append(']') - self._remove_markers(markers, l) + self.__remove_markers(markers, l) - def _encode_dict(self, d, markers, builder, _current_indent_level): - self._mark_markers(markers, d) + def __encode_dict(self, d, markers, builder, _current_indent_level): + self.__mark_markers(markers, d) first = True builder.append('{') - separator, _current_indent_level = self._emit_indent(builder, + separator, _current_indent_level = self.__emit_indent(builder, _current_indent_level) if self.sort_keys: items = sorted(d.items(), key=lambda kv: kv[0]) @@ -282,7 +282,7 @@ # JavaScript is weakly typed for these, so it makes sense to # also allow them. Many encoders seem to do something like this. elif isinstance(key, float): - key = self._floatstr(key) + key = self.__floatstr(key) elif key is True: key = 'true' elif key is False: @@ -296,15 +296,15 @@ else: raise TypeError("key " + repr(key) + " is not a string") builder.append('"') - builder.append(self.encoder(key)) + builder.append(self.__encoder(key)) builder.append('"') builder.append(self.key_separator) - self._encode(v, markers, builder, _current_indent_level) + self.__encode(v, markers, builder, _current_indent_level) del key del v # XXX grumble - self._emit_unindent(builder, _current_indent_level) + self.__emit_unindent(builder, _current_indent_level) builder.append('}') - self._remove_markers(markers, d) + self.__remove_markers(markers, d) def iterencode(self, o, _one_shot=False): """Encode the given object and yield each string @@ -320,9 +320,9 @@ markers = {} else: markers = None - return self._iterencode(o, markers, 0) + return self.__iterencode(o, markers, 0) - def _floatstr(self, o): + def __floatstr(self, o): # Check for specials. Note that this type of test is processor # and/or platform-specific, so do tests which don't depend on the # internals. @@ -343,21 +343,21 @@ return text - def _mark_markers(self, markers, o): + def __mark_markers(self, markers, o): if markers is not None: if id(o) in markers: raise ValueError("Circular reference detected") markers[id(o)] = None - def _remove_markers(self, markers, o): + def __remove_markers(self, markers, o): if markers is not None: del markers[id(o)] - def _iterencode_list(self, lst, markers, _current_indent_level): + def __iterencode_list(self, lst, markers, _current_indent_level): if not lst: yield '[]' return - self._mark_markers(markers, lst) + self.__mark_markers(markers, lst) buf = '[' if self.indent is not None: _current_indent_level += 1 @@ -375,7 +375,7 @@ else: buf = separator if isinstance(value, basestring): - yield buf + '"' + self.encoder(value) + '"' + yield buf + '"' + self.__encoder(value) + '"' elif value is None: yield buf + 'null' elif value is True: @@ -385,17 +385,17 @@ elif isinstance(value, (int, long)): yield buf + str(value) elif isinstance(value, float): - yield buf + self._floatstr(value) + yield buf + self.__floatstr(value) else: yield buf if isinstance(value, (list, tuple)): - chunks = self._iterencode_list(value, markers, + chunks = self.__iterencode_list(value, markers, _current_indent_level) elif isinstance(value, dict): - chunks = self._iterencode_dict(value, markers, + chunks = self.__iterencode_dict(value, markers, _current_indent_level) else: - chunks = self._iterencode(value, markers, + chunks = self.__iterencode(value, markers, _current_indent_level) for chunk in chunks: yield chunk @@ -403,13 +403,13 @@ _current_indent_level -= 1 yield '\n' + (' ' * (self.indent * _current_indent_level)) yield ']' - self._remove_markers(markers, lst) + self.__remove_markers(markers, lst) - def _iterencode_dict(self, dct, markers, _current_indent_level): + def __iterencode_dict(self, dct, markers, _current_indent_level): if not dct: yield '{}' return - self._mark_markers(markers, dct) + self.__mark_markers(markers, dct) yield '{' if self.indent is not None: _current_indent_level += 1 @@ -431,7 +431,7 @@ # JavaScript is weakly typed for these, so it makes sense to # also allow them. Many encoders seem to do something like this. elif isinstance(key, float): - key = self._floatstr(key) + key = self.__floatstr(key) elif key is True: key = 'true' elif key is False: @@ -448,10 +448,10 @@ first = False else: yield item_separator - yield '"' + self.encoder(key) + '"' + yield '"' + self.__encoder(key) + '"' yield self.key_separator if isinstance(value, basestring): - yield '"' + self.encoder(value) + '"' + yield '"' + self.__encoder(value) + '"' elif value is None: yield 'null' elif value is True: @@ -461,16 +461,16 @@ elif isinstance(value, (int, long)): yield str(value) elif isinstance(value, float): - yield self._floatstr(value) + yield self.__floatstr(value) else: if isinstance(value, (list, tuple)): - chunks = self._iterencode_list(value, markers, + chunks = self.__iterencode_list(value, markers, _current_indent_level) elif isinstance(value, dict): - chunks = self._iterencode_dict(value, markers, + chunks = self.__iterencode_dict(value, markers, _current_indent_level) else: - chunks = self._iterencode(value, markers, + chunks = self.__iterencode(value, markers, _current_indent_level) for chunk in chunks: yield chunk @@ -478,11 +478,11 @@ _current_indent_level -= 1 yield '\n' + (' ' * (self.indent * _current_indent_level)) yield '}' - self._remove_markers(markers, dct) + self.__remove_markers(markers, dct) - def _iterencode(self, o, markers, _current_indent_level): + def __iterencode(self, o, markers, _current_indent_level): if isinstance(o, basestring): - yield '"' + self.encoder(o) + '"' + yield '"' + self.__encoder(o) + '"' elif o is None: yield 'null' elif o is True: @@ -492,19 +492,19 @@ elif isinstance(o, (int, long)): yield str(o) elif isinstance(o, float): - yield self._floatstr(o) + yield self.__floatstr(o) elif isinstance(o, (list, tuple)): - for chunk in self._iterencode_list(o, markers, + for chunk in self.__iterencode_list(o, markers, _current_indent_level): yield chunk elif isinstance(o, dict): - for chunk in self._iterencode_dict(o, markers, + for chunk in self.__iterencode_dict(o, markers, _current_indent_level): yield chunk else: - self._mark_markers(markers, o) + self.__mark_markers(markers, o) obj = self.default(o) - for chunk in self._iterencode(obj, markers, + for chunk in self.__iterencode(obj, markers, _current_indent_level): yield chunk - self._remove_markers(markers, o) + self.__remove_markers(markers, o) From noreply at buildbot.pypy.org Sun Feb 10 08:22:42 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sun, 10 Feb 2013 08:22:42 +0100 (CET) Subject: [pypy-commit] pypy default: port a couple deque.rotate optimizations to the interp module Message-ID: <20130210072242.7DEA31C004F@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61027:868fc49b4595 Date: 2013-02-10 02:19 -0500 http://bitbucket.org/pypy/pypy/changeset/868fc49b4595/ Log: port a couple deque.rotate optimizations to the interp module diff --git a/pypy/module/_collections/interp_deque.py b/pypy/module/_collections/interp_deque.py --- a/pypy/module/_collections/interp_deque.py +++ b/pypy/module/_collections/interp_deque.py @@ -287,9 +287,9 @@ def rotate(self, n=1): "Rotate the deque n steps to the right (default n=1). If n is negative, rotates left." len = self.len - if len == 0: + if len <= 1: return - halflen = (len+1) >> 1 + halflen = len >> 1 if n > halflen or n < -halflen: n %= len if n > halflen: From noreply at buildbot.pypy.org Sun Feb 10 09:02:22 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sun, 10 Feb 2013 09:02:22 +0100 (CET) Subject: [pypy-commit] pypy default: fix test_app_main.py for win32 Message-ID: <20130210080222.DE4591C03D5@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61028:a069f835df51 Date: 2013-02-10 03:02 -0500 http://bitbucket.org/pypy/pypy/changeset/a069f835df51/ Log: fix test_app_main.py for win32 diff --git a/pypy/interpreter/test2/test_app_main.py b/pypy/interpreter/test2/test_app_main.py --- a/pypy/interpreter/test2/test_app_main.py +++ b/pypy/interpreter/test2/test_app_main.py @@ -843,7 +843,6 @@ class TestAppMain: - def test_print_info(self): from pypy.interpreter import app_main import sys, cStringIO @@ -874,23 +873,25 @@ class AppTestAppMain: - def setup_class(self): # ---------------------------------------- # setup code for test_setup_bootstrap_path # ---------------------------------------- from pypy.module.sys.version import CPYTHON_VERSION, PYPY_VERSION cpy_ver = '%d.%d' % CPYTHON_VERSION[:2] - + goal_dir = os.path.dirname(app_main) # build a directory hierarchy like which contains both bin/pypy-c and # lib/pypy1.2/* prefix = udir.join('pathtest').ensure(dir=1) - fake_exe = prefix.join('bin/pypy-c').ensure(file=1) + fake_exe = 'bin/pypy-c' + if sys.platform == 'win32': + fake_exe += '.exe' + fake_exe = prefix.join(fake_exe).ensure(file=1) expected_path = [str(prefix.join(subdir).ensure(dir=1)) for subdir in ('lib_pypy', 'lib-python/%s' % cpy_ver)] - + self.w_goal_dir = self.space.wrap(goal_dir) self.w_fake_exe = self.space.wrap(str(fake_exe)) self.w_expected_path = self.space.wrap(expected_path) @@ -906,9 +907,9 @@ try: import app_main app_main.setup_bootstrap_path('/tmp/pypy-c') # stdlib not found - sys.path == old_sys_path + assert sys.path[:-1] == old_sys_path assert sys.executable == '' - # + app_main.setup_bootstrap_path(self.fake_exe) assert sys.executable == self.fake_exe newpath = sys.path[:] From noreply at buildbot.pypy.org Sun Feb 10 09:27:47 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sun, 10 Feb 2013 09:27:47 +0100 (CET) Subject: [pypy-commit] pypy default: another fix for numpy test_abstract_types on 32bit Message-ID: <20130210082747.D1FBC1C004F@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61029:db8798f2b416 Date: 2013-02-10 03:27 -0500 http://bitbucket.org/pypy/pypy/changeset/db8798f2b416/ Log: another fix for numpy test_abstract_types on 32bit diff --git a/pypy/module/micronumpy/test/test_dtypes.py b/pypy/module/micronumpy/test/test_dtypes.py --- a/pypy/module/micronumpy/test/test_dtypes.py +++ b/pypy/module/micronumpy/test/test_dtypes.py @@ -277,13 +277,12 @@ a_i = numpy.array([4,4], numpy.integer) a_s = numpy.array([4,4], numpy.signedinteger) a_u = numpy.array([4,4], numpy.unsignedinteger) + assert a_n.dtype is numpy.dtype('float64') if self.ptr_size == 4: - assert a_n.dtype is numpy.dtype('float32') assert a_i.dtype is numpy.dtype('int32') assert a_s.dtype is numpy.dtype('int32') assert a_u.dtype is numpy.dtype('uint32') else: - assert a_n.dtype is numpy.dtype('float64') assert a_i.dtype is numpy.dtype('int64') assert a_s.dtype is numpy.dtype('int64') assert a_u.dtype is numpy.dtype('uint64') From noreply at buildbot.pypy.org Sun Feb 10 09:34:15 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sun, 10 Feb 2013 09:34:15 +0100 (CET) Subject: [pypy-commit] pypy default: fix test_kqueue Message-ID: <20130210083415.D20F11C004F@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61030:7f1bb5e70bca Date: 2013-02-10 00:33 -0800 http://bitbucket.org/pypy/pypy/changeset/7f1bb5e70bca/ Log: fix test_kqueue diff --git a/pypy/module/select/test/test_kqueue.py b/pypy/module/select/test/test_kqueue.py --- a/pypy/module/select/test/test_kqueue.py +++ b/pypy/module/select/test/test_kqueue.py @@ -4,7 +4,7 @@ import sys class AppTestKqueue(object): - spaceconfig = dict(usemodules=["select", "_socket", "posix"]) + spaceconfig = dict(usemodules=["select", "_socket", "posix", "rctime"]) def setup_class(cls): if not 'bsd' in sys.platform and \ @@ -90,6 +90,7 @@ import select import socket import sys + import time server_socket = socket.socket() server_socket.bind(("127.0.0.1", 0)) From noreply at buildbot.pypy.org Sun Feb 10 10:21:42 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sun, 10 Feb 2013 10:21:42 +0100 (CET) Subject: [pypy-commit] pypy default: python2.6 compat Message-ID: <20130210092142.2CFD11C03D5@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61031:a174c61bb9fc Date: 2013-02-10 04:21 -0500 http://bitbucket.org/pypy/pypy/changeset/a174c61bb9fc/ Log: python2.6 compat diff --git a/pypy/module/test_lib_pypy/test_datetime.py b/pypy/module/test_lib_pypy/test_datetime.py --- a/pypy/module/test_lib_pypy/test_datetime.py +++ b/pypy/module/test_lib_pypy/test_datetime.py @@ -103,7 +103,7 @@ i10 = 10 l10 = 10L d10 = decimal.Decimal(10) - d11 = decimal.Decimal(10.9) + d11 = decimal.Decimal('10.9') c10 = Number(10) o10 = Number(10L) assert datetime.datetime(i10, i10, i10, i10, i10, i10, i10) == \ From noreply at buildbot.pypy.org Sun Feb 10 10:39:18 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sun, 10 Feb 2013 10:39:18 +0100 (CET) Subject: [pypy-commit] pypy default: skip this test on older host pythons Message-ID: <20130210093918.48B781C004F@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61032:15b403e9996f Date: 2013-02-10 04:39 -0500 http://bitbucket.org/pypy/pypy/changeset/15b403e9996f/ Log: skip this test on older host pythons diff --git a/pypy/module/test_lib_pypy/test_sqlite3.py b/pypy/module/test_lib_pypy/test_sqlite3.py --- a/pypy/module/test_lib_pypy/test_sqlite3.py +++ b/pypy/module/test_lib_pypy/test_sqlite3.py @@ -1,5 +1,9 @@ """Tests for _sqlite3.py""" +import sys +if sys.version_info < (2, 7): + skip("lib_pypy._sqlite3 doesn't work with python < 2.7") + def test_list_ddl(): """From issue996. Mostly just looking for lack of exceptions.""" from lib_pypy._sqlite3 import connect From noreply at buildbot.pypy.org Sun Feb 10 10:55:19 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Sun, 10 Feb 2013 10:55:19 +0100 (CET) Subject: [pypy-commit] pypy default: Constant fold str.{start, end}swith in the annotator Message-ID: <20130210095519.2F15A1C004F@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r61033:96802b7f8b62 Date: 2013-02-10 01:55 -0800 http://bitbucket.org/pypy/pypy/changeset/96802b7f8b62/ Log: Constant fold str.{start,end}swith in the annotator diff --git a/rpython/annotator/test/test_annrpython.py b/rpython/annotator/test/test_annrpython.py --- a/rpython/annotator/test/test_annrpython.py +++ b/rpython/annotator/test/test_annrpython.py @@ -3915,8 +3915,16 @@ int, int]), annmodel.SomeInteger) + def test_constant_startswith_endswith(self): + def f(): + return "abc".startswith("ab") and "abc".endswith("bc") + a = self.RPythonAnnotator() + assert a.build_types(f, []).const is True + + def g(n): - return [0,1,2,n] + return [0, 1, 2, n] + def f_calls_g(n): total = 0 @@ -3932,4 +3940,3 @@ class Freezing: def _freeze_(self): return True - diff --git a/rpython/annotator/unaryop.py b/rpython/annotator/unaryop.py --- a/rpython/annotator/unaryop.py +++ b/rpython/annotator/unaryop.py @@ -456,9 +456,13 @@ SomeUnicodeString): def method_startswith(str, frag): + if str.is_constant() and frag.is_constant(): + return immutablevalue(str.const.startswith(frag.const)) return s_Bool def method_endswith(str, frag): + if str.is_constant() and frag.is_constant(): + return immutablevalue(str.const.endswith(frag.const)) return s_Bool def method_find(str, frag, start=None, end=None): From noreply at buildbot.pypy.org Sun Feb 10 11:50:06 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sun, 10 Feb 2013 11:50:06 +0100 (CET) Subject: [pypy-commit] pypy default: partially revert 4237a1dca2e8 to fix namedtuple namespace problems Message-ID: <20130210105006.D68D31C004F@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61034:f7c8f6cf3434 Date: 2013-02-10 05:49 -0500 http://bitbucket.org/pypy/pypy/changeset/f7c8f6cf3434/ Log: partially revert 4237a1dca2e8 to fix namedtuple namespace problems diff --git a/lib-python/2.7/collections.py b/lib-python/2.7/collections.py --- a/lib-python/2.7/collections.py +++ b/lib-python/2.7/collections.py @@ -295,7 +295,7 @@ _fields = %(field_names)r \n def __new__(_cls, %(argtxt)s): 'Create new instance of %(typename)s(%(argtxt)s)' - return tuple.__new__(_cls, (%(argtxt)s)) \n + return _tuple.__new__(_cls, (%(argtxt)s)) \n @classmethod def _make(cls, iterable, new=tuple.__new__, len=len): 'Make a new %(typename)s object from a sequence or iterable' @@ -320,14 +320,14 @@ 'Return self as a plain tuple. Used by copy and pickle.' return tuple(self) \n\n''' % locals() for i, name in enumerate(field_names): - template += " %s = property(lambda self: self[%d], doc='Alias for field number %d')\n" % (name, i, i) + template += " %s = _property(lambda self: self[%d], doc='Alias for field number %d')\n" % (name, i, i) if verbose: print template # Execute the template string in a temporary namespace and # support tracing utilities by setting a value for frame.f_globals['__name__'] - namespace = {'__name__': 'namedtuple_%s' % typename, - 'OrderedDict': OrderedDict} + namespace = dict(__name__='namedtuple_%s' % typename, + OrderedDict=OrderedDict, _property=property, _tuple=tuple) try: exec template in namespace except SyntaxError, e: From noreply at buildbot.pypy.org Sun Feb 10 11:54:55 2013 From: noreply at buildbot.pypy.org (fijal) Date: Sun, 10 Feb 2013 11:54:55 +0100 (CET) Subject: [pypy-commit] pypy default: Convert w_globals passed to exec to celldict, if not already a celldict. Message-ID: <20130210105455.4DF591C004F@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r61035:60b3f3d002ba Date: 2013-02-10 12:49 +0200 http://bitbucket.org/pypy/pypy/changeset/60b3f3d002ba/ Log: Convert w_globals passed to exec to celldict, if not already a celldict. Potentially questionable checkin, but I don't think it's too bad diff --git a/pypy/interpreter/eval.py b/pypy/interpreter/eval.py --- a/pypy/interpreter/eval.py +++ b/pypy/interpreter/eval.py @@ -28,6 +28,7 @@ def exec_code(self, space, w_globals, w_locals): "Implements the 'exec' statement." # this should be on PyCode? + space.possibly_convert_to_celldict(w_globals) frame = space.createframe(self, w_globals, None) frame.setdictscope(w_locals) return frame.run() diff --git a/pypy/objspace/std/dictmultiobject.py b/pypy/objspace/std/dictmultiobject.py --- a/pypy/objspace/std/dictmultiobject.py +++ b/pypy/objspace/std/dictmultiobject.py @@ -109,6 +109,18 @@ def view_as_kwargs(self): return self.strategy.view_as_kwargs(self) + def convert_to_celldict_strategy(self, space): + from pypy.objspace.std.celldict import ModuleDictStrategy + + if isinstance(self.strategy, ModuleDictStrategy): + return + items_w = self.items() + self.strategy = ModuleDictStrategy(space) + self.dstorage = self.strategy.get_empty_storage() + for w_tup in items_w: + w_key, w_val = space.fixedview(w_tup, 2) + self.setitem(w_key, w_val) + def _add_indirections(): dict_methods = "setitem setitem_str getitem \ getitem_str delitem length \ diff --git a/pypy/objspace/std/objspace.py b/pypy/objspace/std/objspace.py --- a/pypy/objspace/std/objspace.py +++ b/pypy/objspace/std/objspace.py @@ -684,3 +684,10 @@ if not hasattr(self, "_interplevel_classes"): return None # before running initialize return self._interplevel_classes.get(w_type, None) + + def possibly_convert_to_celldict(self, w_dict): + """ Converts the dict to celldict, if it's a dict, otherwise + leaves it alone + """ + if isinstance(w_dict, W_DictMultiObject): + w_dict.convert_to_celldict_strategy(self) From noreply at buildbot.pypy.org Sun Feb 10 11:54:57 2013 From: noreply at buildbot.pypy.org (fijal) Date: Sun, 10 Feb 2013 11:54:57 +0100 (CET) Subject: [pypy-commit] pypy default: merge Message-ID: <20130210105457.4A6F91C004F@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r61036:d8841110c366 Date: 2013-02-10 12:54 +0200 http://bitbucket.org/pypy/pypy/changeset/d8841110c366/ Log: merge diff --git a/lib-python/2.7/collections.py b/lib-python/2.7/collections.py --- a/lib-python/2.7/collections.py +++ b/lib-python/2.7/collections.py @@ -295,7 +295,7 @@ _fields = %(field_names)r \n def __new__(_cls, %(argtxt)s): 'Create new instance of %(typename)s(%(argtxt)s)' - return tuple.__new__(_cls, (%(argtxt)s)) \n + return _tuple.__new__(_cls, (%(argtxt)s)) \n @classmethod def _make(cls, iterable, new=tuple.__new__, len=len): 'Make a new %(typename)s object from a sequence or iterable' @@ -320,14 +320,14 @@ 'Return self as a plain tuple. Used by copy and pickle.' return tuple(self) \n\n''' % locals() for i, name in enumerate(field_names): - template += " %s = property(lambda self: self[%d], doc='Alias for field number %d')\n" % (name, i, i) + template += " %s = _property(lambda self: self[%d], doc='Alias for field number %d')\n" % (name, i, i) if verbose: print template # Execute the template string in a temporary namespace and # support tracing utilities by setting a value for frame.f_globals['__name__'] - namespace = {'__name__': 'namedtuple_%s' % typename, - 'OrderedDict': OrderedDict} + namespace = dict(__name__='namedtuple_%s' % typename, + OrderedDict=OrderedDict, _property=property, _tuple=tuple) try: exec template in namespace except SyntaxError, e: From noreply at buildbot.pypy.org Sun Feb 10 12:13:12 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sun, 10 Feb 2013 12:13:12 +0100 (CET) Subject: [pypy-commit] pypy default: fix test_ll_os_environ on darwin Message-ID: <20130210111312.4AC9C1C004F@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61037:2c718aa7ab8f Date: 2013-02-10 03:12 -0800 http://bitbucket.org/pypy/pypy/changeset/2c718aa7ab8f/ Log: fix test_ll_os_environ on darwin diff --git a/rpython/rtyper/module/ll_os_environ.py b/rpython/rtyper/module/ll_os_environ.py --- a/rpython/rtyper/module/ll_os_environ.py +++ b/rpython/rtyper/module/ll_os_environ.py @@ -109,19 +109,11 @@ r_putenv(name, '') if hasattr(__import__(os.name), 'unsetenv'): - - if sys.platform.startswith('darwin'): - RETTYPE = lltype.Void - os_unsetenv = rffi.llexternal('unsetenv', [rffi.CCHARP], RETTYPE) - else: - RETTYPE = rffi.INT - _os_unsetenv = rffi.llexternal('unsetenv', [rffi.CCHARP], RETTYPE) - def os_unsetenv(l_name): - return rffi.cast(lltype.Signed, _os_unsetenv(l_name)) + os_unsetenv = rffi.llexternal('unsetenv', [rffi.CCHARP], rffi.INT) def unsetenv_llimpl(name): l_name = rffi.str2charp(name) - error = os_unsetenv(l_name) # 'error' is None on OS/X + error = rffi.cast(lltype.Signed, os_unsetenv(l_name)) rffi.free_charp(l_name) if error: raise OSError(rposix.get_errno(), "os_unsetenv failed") diff --git a/rpython/rtyper/module/test/test_ll_os_environ.py b/rpython/rtyper/module/test/test_ll_os_environ.py --- a/rpython/rtyper/module/test/test_ll_os_environ.py +++ b/rpython/rtyper/module/test/test_ll_os_environ.py @@ -2,17 +2,16 @@ import os def test_environ_items(): - def foo(x): if x: return len(os.environ.items()) else: return 0 + f = compile(foo, [int], backendopt=False) assert f(1) > 0 - + def test_unset_error(): - def foo(x): if x: os.environ['TEST'] = 'STRING' @@ -25,6 +24,6 @@ return 2 else: return 0 + f = compile(foo, [int], backendopt=False) assert f(1) == 1 - From noreply at buildbot.pypy.org Sun Feb 10 13:36:52 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sun, 10 Feb 2013 13:36:52 +0100 (CET) Subject: [pypy-commit] pypy default: small cleanups Message-ID: <20130210123652.32A5E1C11D1@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61038:88ba0bad7688 Date: 2013-02-10 07:35 -0500 http://bitbucket.org/pypy/pypy/changeset/88ba0bad7688/ Log: small cleanups diff --git a/pypy/interpreter/test2/test_app_main.py b/pypy/interpreter/test2/test_app_main.py --- a/pypy/interpreter/test2/test_app_main.py +++ b/pypy/interpreter/test2/test_app_main.py @@ -907,8 +907,8 @@ try: import app_main app_main.setup_bootstrap_path('/tmp/pypy-c') # stdlib not found + assert sys.executable == '' assert sys.path[:-1] == old_sys_path - assert sys.executable == '' app_main.setup_bootstrap_path(self.fake_exe) assert sys.executable == self.fake_exe diff --git a/pypy/module/sys/initpath.py b/pypy/module/sys/initpath.py --- a/pypy/module/sys/initpath.py +++ b/pypy/module/sys/initpath.py @@ -32,15 +32,14 @@ executable = fn break executable = rpath.rabspath(executable) - # + # 'sys.executable' should not end up being an non-existing file; # just use '' in this case. (CPython issue #7774) if not os.path.isfile(executable): executable = '' return executable - -def readlink_maybe(filename): +def _readlink_maybe(filename): if not IS_WINDOWS: return os.readlink(filename) raise NotImplementedError @@ -53,7 +52,7 @@ dirname = rpath.rabspath(os.path.join(filename, '..')) if os.path.islink(filename): try: - link = readlink_maybe(filename) + link = _readlink_maybe(filename) except OSError: pass else: @@ -78,9 +77,7 @@ return newpath, dirname search = dirname # walk to the parent directory - - -def checkdir(path): +def _checkdir(path): st = os.stat(path) if not stat.S_ISDIR(st[0]): raise OSError(errno.ENOTDIR, path) @@ -96,24 +93,24 @@ CPYTHON_VERSION[1]) lib_python = os.path.join(prefix, 'lib-python') python_std_lib = os.path.join(lib_python, dirname) - checkdir(python_std_lib) - + _checkdir(python_std_lib) + lib_pypy = os.path.join(prefix, 'lib_pypy') - checkdir(lib_pypy) + _checkdir(lib_pypy) importlist = [] - # + if state is not None: # 'None' for testing only lib_extensions = os.path.join(lib_pypy, '__extensions__') state.w_lib_extensions = state.space.wrap(lib_extensions) importlist.append(lib_extensions) - # + importlist.append(lib_pypy) importlist.append(python_std_lib) - # + lib_tk = os.path.join(python_std_lib, 'lib-tk') importlist.append(lib_tk) - # + # List here the extra platform-specific paths. if platform != 'win32': importlist.append(os.path.join(python_std_lib, 'plat-'+platform)) @@ -121,7 +118,7 @@ platmac = os.path.join(python_std_lib, 'plat-mac') importlist.append(platmac) importlist.append(os.path.join(platmac, 'lib-scriptpackages')) - # + return importlist def compute_stdlib_path_maybe(state, prefix): diff --git a/pypy/module/sys/test/test_initpath.py b/pypy/module/sys/test/test_initpath.py --- a/pypy/module/sys/test/test_initpath.py +++ b/pypy/module/sys/test/test_initpath.py @@ -27,7 +27,6 @@ path, prefix = find_stdlib(None, str(pypy_sym)) assert prefix == pypydir - def test_compute_stdlib_path(tmpdir): dirs = build_hierarchy(tmpdir) path = compute_stdlib_path(None, str(tmpdir)) @@ -40,7 +39,6 @@ path = compute_stdlib_path(None, str(tmpdir)) assert lib_tk in path - def test_find_executable(tmpdir, monkeypatch): from pypy.module.sys import initpath tmpdir = py.path.local(os.path.realpath(str(tmpdir))) From noreply at buildbot.pypy.org Sun Feb 10 14:06:54 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sun, 10 Feb 2013 14:06:54 +0100 (CET) Subject: [pypy-commit] pypy default: fix test_app_main Message-ID: <20130210130654.13FCC1C1047@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61039:c7f4ca65c2ce Date: 2013-02-10 08:04 -0500 http://bitbucket.org/pypy/pypy/changeset/c7f4ca65c2ce/ Log: fix test_app_main diff --git a/pypy/interpreter/app_main.py b/pypy/interpreter/app_main.py --- a/pypy/interpreter/app_main.py +++ b/pypy/interpreter/app_main.py @@ -223,7 +223,6 @@ else: IS_WINDOWS = False - def setup_and_fix_paths(ignore_environment=False, **extra): import os newpath = sys.path[:] @@ -303,7 +302,6 @@ "hash_randomization", ) - default_options = dict.fromkeys( sys_flags + ("run_command", @@ -312,7 +310,6 @@ "warnoptions", "unbuffered"), 0) - PYTHON26 = True def simple_option(options, name, iterargv): @@ -376,10 +373,9 @@ 'R': (simple_option, 'hash_randomization'), }) - def handle_argument(c, options, iterargv, iterarg=iter(())): function, funcarg = cmdline_options[c] - # + # If needed, fill in the real argument by taking it from the command line if funcarg is Ellipsis: remaining = list(iterarg) @@ -392,15 +388,14 @@ if len(c) == 1: c = '-' + c raise CommandLineError('Argument expected for the %r option' % c) - # + return function(options, funcarg, iterargv) - def parse_command_line(argv): import os options = default_options.copy() options['warnoptions'] = [] - # + iterargv = iter(argv) argv = None for arg in iterargv: diff --git a/pypy/interpreter/test2/test_app_main.py b/pypy/interpreter/test2/test_app_main.py --- a/pypy/interpreter/test2/test_app_main.py +++ b/pypy/interpreter/test2/test_app_main.py @@ -72,7 +72,6 @@ class TestParseCommandLine: - def check_options(self, options, sys_argv, **expected): assert sys.argv == sys_argv for key, value in expected.items(): @@ -191,14 +190,13 @@ monkeypatch.setenv('PYTHONNOUSERSITE', '1') expected = {"no_user_site": True} self.check(['-c', 'pass'], sys_argv=['-c'], run_command='pass', **expected) - + class TestInteraction: """ These tests require pexpect (UNIX-only). http://pexpect.sourceforge.net/ """ - def setup_class(cls): # some tests need to be able to import test2, change the cwd goal_dir = os.path.abspath(os.path.join(os.path.realpath(os.path.dirname(__file__)), '..')) @@ -567,8 +565,8 @@ child = self.spawn(argv) child.expect('False') + class TestNonInteractive: - def run_with_status_code(self, cmdline, senddata='', expect_prompt=False, expect_banner=False, python_flags='', env=None): cmdline = '%s %s "%s" %s' % (sys.executable, python_flags, @@ -896,7 +894,7 @@ self.w_fake_exe = self.space.wrap(str(fake_exe)) self.w_expected_path = self.space.wrap(expected_path) self.w_trunkdir = self.space.wrap(os.path.dirname(pypydir)) - # + foo_py = prefix.join('foo.py').write("pass") self.w_foo_py = self.space.wrap(str(foo_py)) @@ -908,7 +906,7 @@ import app_main app_main.setup_bootstrap_path('/tmp/pypy-c') # stdlib not found assert sys.executable == '' - assert sys.path[:-1] == old_sys_path + assert sys.path[:len(old_sys_path)] == old_sys_path app_main.setup_bootstrap_path(self.fake_exe) assert sys.executable == self.fake_exe From noreply at buildbot.pypy.org Sun Feb 10 15:03:50 2013 From: noreply at buildbot.pypy.org (fijal) Date: Sun, 10 Feb 2013 15:03:50 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: 32bit fix Message-ID: <20130210140350.79C4D1C1029@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61040:fb53361d4f6e Date: 2013-02-10 16:02 +0200 http://bitbucket.org/pypy/pypy/changeset/fb53361d4f6e/ Log: 32bit fix diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -803,7 +803,10 @@ def _call_header(self): self.mc.SUB_ri(esp.value, FRAME_FIXED_SIZE * WORD) self.mc.MOV_sr(PASS_ON_MY_FRAME * WORD, ebp.value) - self.mc.MOV_rr(ebp.value, edi.value) + if IS_X86_64: + self.mc.MOV_rr(ebp.value, edi.value) + else: + self.mc.MOV_rs(ebp.value, (FRAME_FIXED_SIZE + 1) * WORD) for i, loc in enumerate(self.cpu.CALLEE_SAVE_REGISTERS): self.mc.MOV_sr((PASS_ON_MY_FRAME + i + 1) * WORD, loc.value) From noreply at buildbot.pypy.org Sun Feb 10 15:03:51 2013 From: noreply at buildbot.pypy.org (fijal) Date: Sun, 10 Feb 2013 15:03:51 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: merge Message-ID: <20130210140351.D6F711C1029@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61041:5ebb36945721 Date: 2013-02-10 16:03 +0200 http://bitbucket.org/pypy/pypy/changeset/5ebb36945721/ Log: merge diff --git a/rpython/jit/backend/arm/arch.py b/rpython/jit/backend/arm/arch.py --- a/rpython/jit/backend/arm/arch.py +++ b/rpython/jit/backend/arm/arch.py @@ -17,6 +17,4 @@ # A jitframe is a jit.backend.llsupport.llmodel.JITFRAME = GcArray(Signed). # Stack frame fixed area # Currently only the force_index -FRAME_FIXED_SIZE = 1 JITFRAME_FIXED_SIZE = 16 + 16 * 2 # 16 GPR + 16 VFP Regs (64bit) - diff --git a/rpython/jit/backend/arm/assembler.py b/rpython/jit/backend/arm/assembler.py --- a/rpython/jit/backend/arm/assembler.py +++ b/rpython/jit/backend/arm/assembler.py @@ -6,7 +6,7 @@ from rpython.jit.backend.arm import registers as r from rpython.jit.backend.arm.arch import WORD, DOUBLE_WORD, FUNC_ALIGN, \ N_REGISTERS_SAVED_BY_MALLOC, \ - JITFRAME_FIXED_SIZE, FRAME_FIXED_SIZE + JITFRAME_FIXED_SIZE from rpython.jit.backend.arm.codebuilder import ARMv7Builder, OverwritingBuilder from rpython.jit.backend.arm.locations import get_fp_offset, imm, StackLocation from rpython.jit.backend.arm.regalloc import (Regalloc, ARMFrameManager, @@ -259,7 +259,7 @@ def _build_stack_check_slowpath(self): _, _, slowpathaddr = self.cpu.insert_stack_check() - if slowpathaddr == 0 or self.cpu.propagate_exception_v < 0: + if slowpathaddr == 0 or not self.cpu.propagate_exception_descr: return # no stack check (for tests, or non-translated) # # make a "function" that is called immediately at the start of @@ -432,7 +432,6 @@ def _build_failure_recovery(self, exc, withfloats=False): mc = ARMv7Builder() self._push_all_regs_to_jitframe(mc, [], withfloats) - self._insert_checks(mc) if exc: # We might have an exception pending. Load it into r4 @@ -472,49 +471,6 @@ rawstart = mc.materialize(self.cpu.asmmemmgr, []) self.failure_recovery_code[exc + 2 * withfloats] = rawstart - DESCR_REF = 0x00 - DESCR_INT = 0x01 - DESCR_FLOAT = 0x02 - DESCR_SPECIAL = 0x03 - CODE_FROMSTACK = 64 - CODE_STOP = 0 | DESCR_SPECIAL - CODE_HOLE = 4 | DESCR_SPECIAL - CODE_INPUTARG = 8 | DESCR_SPECIAL - CODE_FORCED = 12 | DESCR_SPECIAL #XXX where should this be written? - - def write_failure_recovery_description(self, descr, failargs, locs): - assert self.mc is not None - for i in range(len(failargs)): - arg = failargs[i] - if arg is not None: - if arg.type == REF: - kind = self.DESCR_REF - elif arg.type == INT: - kind = self.DESCR_INT - elif arg.type == FLOAT: - kind = self.DESCR_FLOAT - else: - raise AssertionError("bogus kind") - loc = locs[i] - if loc.is_stack(): - pos = loc.position - if pos < 0: - self.mc.writechar(chr(self.CODE_INPUTARG)) - pos = ~pos - n = self.CODE_FROMSTACK // 4 + pos - else: - assert loc.is_reg() or loc.is_vfp_reg() - n = loc.value - n = kind + 4 * n - while n > 0x7F: - self.mc.writechar(chr((n & 0x7F) | 0x80)) - n >>= 7 - else: - n = self.CODE_HOLE - self.mc.writechar(chr(n)) - self.mc.writechar(chr(self.CODE_STOP)) - - def generate_quick_failure(self, guardtok, fcond=c.AL): assert isinstance(guardtok.exc, bool) startpos = self.mc.currpos() @@ -527,12 +483,13 @@ target = self.failure_recovery_code[exc + 2 * withfloats] fail_descr = cast_instance_to_gcref(guardtok.faildescr) fail_descr = rffi.cast(lltype.Signed, fail_descr) + base_ofs = self.cpu.get_baseofs_of_frame_field() positions = [0] * len(guardtok.fail_locs) for i, loc in enumerate(guardtok.fail_locs): if loc is None: positions[i] = -1 elif loc.is_stack(): - positions[i] = loc.value + positions[i] = loc.value - base_ofs else: if loc.is_reg(): assert loc is not r.fp # for now @@ -560,23 +517,25 @@ mc = self.mc if gcrootmap and gcrootmap.is_shadow_stack: self.gen_footer_shadowstack(gcrootmap, mc) - mc.ADD_ri(r.sp.value, r.sp.value, WORD, cond=cond) # for the force index if self.cpu.supports_floats: mc.VPOP([reg.value for reg in r.callee_saved_vfp_registers], cond=cond) - mc.POP([reg.value for reg in r.callee_restored_registers], cond=cond) + # push all callee saved registers and IP to keep the alignment + mc.POP([reg.value for reg in r.callee_restored_registers] + + [r.ip.value], cond=cond) mc.BKPT() def gen_func_prolog(self): - stack_size = FRAME_FIXED_SIZE * WORD + stack_size = WORD #alignment stack_size += len(r.callee_saved_registers) * WORD if self.cpu.supports_floats: stack_size += len(r.callee_saved_vfp_registers) * 2 * WORD - self.mc.PUSH([reg.value for reg in r.callee_saved_registers]) + # push all callee saved registers and IP to keep the alignment + self.mc.PUSH([reg.value for reg in r.callee_saved_registers] + + [r.ip.value]) if self.cpu.supports_floats: self.mc.VPUSH([reg.value for reg in r.callee_saved_vfp_registers]) - self.mc.SUB_ri(r.sp.value, r.sp.value, WORD) # for the force index assert stack_size % 8 == 0 # ensure we keep alignment # set fp to point to the JITFRAME @@ -673,8 +632,8 @@ loop_head = self.mc.get_relative_pos() looptoken._arm_loop_code = loop_head # - frame_depth = self._assemble(regalloc, inputargs, operations) - self.update_frame_depth(frame_depth + JITFRAME_FIXED_SIZE) + frame_depth_no_fixed_size = self._assemble(regalloc, inputargs, operations) + self.update_frame_depth(frame_depth_no_fixed_size + JITFRAME_FIXED_SIZE) # size_excluding_failure_stuff = self.mc.get_relative_pos() @@ -764,6 +723,7 @@ frame_depth = max(self.current_clt.frame_info.jfi_frame_depth, frame_depth_no_fixed_size + JITFRAME_FIXED_SIZE) self.fixup_target_tokens(rawstart) + self._patch_stackadjust(stack_check_patch_ofs + rawstart, frame_depth) self.update_frame_depth(frame_depth) self.teardown() @@ -816,12 +776,11 @@ """ descrs = self.cpu.gc_ll_descr.getframedescrs(self.cpu) ofs = self.cpu.unpack_fielddescr(descrs.arraydescr.lendescr) - base_ofs = self.cpu.get_baseofs_of_frame_field() mc.gen_load_int(r.ip.value, ofs) - mc.SUB_ri(r.ip.value, r.ip.value, base_ofs) stack_check_cmp_ofs = mc.currpos() if expected_size == -1: - mc.gen_load_int(r.lr.value, 0xffffff) + mc.NOP() + mc.NOP() else: mc.gen_load_int(r.lr.value, expected_size) mc.CMP_rr(r.ip.value, r.lr.value) @@ -829,10 +788,11 @@ jg_location = mc.currpos() mc.BKPT() + # the size value is still stored in lr + mc.PUSH([r.lr.value]) + self.push_gcmap(mc, gcmap, push=True) - # the size value is still stored in lr - mc.PUSH([r.lr.value]) self.mc.BL(self._stack_check_failure) @@ -862,19 +822,20 @@ # store return address and keep the stack aligned mc.PUSH([r.ip.value, r.lr.value]) - # store the current gcmap(r1) in the jitframe + # store the current gcmap(r0) in the jitframe gcmap_ofs = self.cpu.get_ofs_of_frame_field('jf_gcmap') assert check_imm_arg(abs(gcmap_ofs)) - mc.STR_ri(r.r1.value, r.fp.value, imm=gcmap_ofs) + mc.STR_ri(r.r0.value, r.fp.value, imm=gcmap_ofs) # set first arg, which is the old jitframe address mc.MOV_rr(r.r0.value, r.fp.value) # call realloc_frame, it takes two arguments # arg0: the old jitframe # arg1: the new size + # mc.BL(self.cpu.realloc_frame) - # set fp to the new jitframe plus the baseofs - mc.ADD_ri(r.fp.value, r.r0.value) + # set fp to the new jitframe + mc.MOV_rr(r.fp.value, r.r0.value) gcrootmap = self.cpu.gc_ll_descr.gcrootmap if gcrootmap and gcrootmap.is_shadow_stack: @@ -902,6 +863,11 @@ targettoken._arm_loop_code += rawstart self.target_tokens_currently_compiling = None + def _patch_stackadjust(self, adr, allocated_depth): + mc = ARMv7Builder() + mc.gen_load_int(r.lr.value, allocated_depth) + mc.copy_to_raw_memory(adr) + def target_arglocs(self, loop_token): return loop_token._arm_arglocs @@ -1061,15 +1027,6 @@ asm_math_operations[oopspecindex](self, op, arglocs, regalloc, fcond) return fcond - - def _insert_checks(self, mc=None): - if not we_are_translated() and self._debug: - if mc is None: - mc = self.mc - mc.CMP_rr(r.fp.value, r.sp.value) - mc.MOV_rr(r.pc.value, r.pc.value, cond=c.GE) - mc.BKPT() - def _ensure_result_bit_extension(self, resloc, size, signed): if size == 4: return @@ -1245,9 +1202,9 @@ offset = loc.value if not check_imm_arg(offset): self.mc.gen_load_int(r.ip.value, offset, cond=cond) - self.mc.SUB_rr(r.ip.value, r.fp.value, r.ip.value, cond=cond) + self.mc.ADD_rr(r.ip.value, r.fp.value, r.ip.value, cond=cond) else: - self.mc.SUB_ri(r.ip.value, r.fp.value, offset, cond=cond) + self.mc.ADD_ri(r.ip.value, r.fp.value, offset, cond=cond) self.mc.VSTR(prev_loc.value, r.ip.value, cond=cond) self.mc.POP([r.ip.value], cond=cond) else: @@ -1390,36 +1347,11 @@ # malloc_slowpath in case we called malloc_slowpath, which returns the # new value of nursery_free_adr in r1 and the adr of the new object in # r0. - self.mark_gc_roots(self.write_new_force_index(), - use_copy_area=True) self.mc.BL(self.malloc_slowpath, c=c.HI) self.mc.gen_load_int(r.ip.value, nursery_free_adr) self.mc.STR_ri(r.r1.value, r.ip.value) - def mark_gc_roots(self, force_index, use_copy_area=False): - if force_index < 0: - return # not needed - gcrootmap = self.cpu.gc_ll_descr.gcrootmap - if gcrootmap: - mark = self._regalloc.get_mark_gc_roots(gcrootmap, use_copy_area) - assert gcrootmap.is_shadow_stack - gcrootmap.write_callshape(mark, force_index) - - def write_new_force_index(self): - # for shadowstack only: get a new, unused force_index number and - # write it to FORCE_INDEX_OFS. Used to record the call shape - # (i.e. where the GC pointers are in the stack) around a CALL - # instruction that doesn't already have a force_index. - gcrootmap = self.cpu.gc_ll_descr.gcrootmap - if gcrootmap and gcrootmap.is_shadow_stack: - clt = self.current_clt - force_index = clt.reserve_and_record_some_faildescr_index() - self._write_fail_index(force_index) - return force_index - else: - return 0 - def push_gcmap(self, mc, gcmap, push=False, mov=False, store=False): ptr = rffi.cast(lltype.Signed, gcmap) if push: diff --git a/rpython/jit/backend/arm/opassembler.py b/rpython/jit/backend/arm/opassembler.py --- a/rpython/jit/backend/arm/opassembler.py +++ b/rpython/jit/backend/arm/opassembler.py @@ -32,6 +32,7 @@ from rpython.rlib import rgc from rpython.rtyper.lltypesystem import rstr, rffi, lltype, llmemory from rpython.rlib.rarithmetic import r_uint +from rpython.rtyper.annlowlevel import cast_instance_to_gcref NO_FORCE_INDEX = -1 @@ -339,7 +340,6 @@ target_nbargs = target_token._arm_clt._debug_nbargs assert my_nbargs == target_nbargs - self._insert_checks() if target_token in self.target_tokens_currently_compiling: self.mc.B_offs(target, fcond) else: @@ -365,27 +365,24 @@ self.gen_func_epilog() return fcond - def emit_op_call(self, op, arglocs, regalloc, fcond, - force_index=NO_FORCE_INDEX): - if force_index == NO_FORCE_INDEX: - force_index = self.write_new_force_index() + def emit_op_call(self, op, arglocs, regalloc, fcond): resloc = arglocs[0] adr = arglocs[1] arglist = arglocs[2:] descr = op.getdescr() size = descr.get_result_size() signed = descr.is_result_signed() - cond = self._emit_call(force_index, adr, arglist, + cond = self._emit_call(adr, arglist, fcond, resloc, (size, signed)) return cond - def _emit_call(self, force_index, adr, arglocs, fcond=c.AL, + def _emit_call(self, adr, arglocs, fcond=c.AL, resloc=None, result_info=(-1, -1)): if self.cpu.use_hf_abi: - stack_args, adr = self._setup_call_hf(force_index, adr, + stack_args, adr = self._setup_call_hf(adr, arglocs, fcond, resloc, result_info) else: - stack_args, adr = self._setup_call_sf(force_index, adr, + stack_args, adr = self._setup_call_sf(adr, arglocs, fcond, resloc, result_info) #the actual call @@ -399,7 +396,6 @@ assert adr.is_reg() if adr.is_reg(): self.mc.BLX(adr.value) - self.mark_gc_roots(force_index) self._restore_sp(stack_args, fcond) # ensure the result is wellformed and stored in the correct location @@ -454,7 +450,7 @@ else: self.regalloc_push(arg) - def _setup_call_sf(self, force_index, adr, arglocs, fcond=c.AL, + def _setup_call_sf(self, adr, arglocs, fcond=c.AL, resloc=None, result_info=(-1, -1)): reg_args = count_reg_args(arglocs) stack_args = self._collect_stack_args_sf(arglocs) @@ -499,7 +495,7 @@ self.mov_from_vfp_loc(loc, reg, r.all_regs[reg.value + 1]) return stack_args, adr - def _setup_call_hf(self, force_index, adr, arglocs, fcond=c.AL, + def _setup_call_hf(self, adr, arglocs, fcond=c.AL, resloc=None, result_info=(-1, -1)): non_float_locs = [] non_float_regs = [] @@ -1053,7 +1049,7 @@ length_loc = bytes_loc # call memcpy() regalloc.before_call() - self._emit_call(NO_FORCE_INDEX, imm(self.memcpy_addr), + self._emit_call(imm(self.memcpy_addr), [dstaddr_loc, srcaddr_loc, length_loc]) regalloc.possibly_free_var(length_box) @@ -1126,6 +1122,7 @@ return fcond def emit_op_force_token(self, op, arglocs, regalloc, fcond): + # XXX kill me res_loc = arglocs[0] self.mc.MOV_rr(res_loc.value, r.fp.value) return fcond @@ -1138,14 +1135,12 @@ resloc = arglocs[2] callargs = arglocs[3:] - faildescr = guard_op.getdescr() - fail_index = self.cpu.get_fail_descr_number(faildescr) - self._write_fail_index(fail_index) + self._store_force_index(guard_op) descr = op.getdescr() assert isinstance(descr, JitCellToken) # check value assert tmploc is r.r0 - self._emit_call(fail_index, imm(descr._arm_func_addr), + self._emit_call(imm(descr._arm_func_addr), callargs, fcond, resloc=tmploc) if op.result is None: value = self.cpu.done_with_this_frame_void_v @@ -1288,9 +1283,7 @@ def emit_guard_call_may_force(self, op, guard_op, arglocs, regalloc, fcond): - faildescr = guard_op.getdescr() - fail_index = self.cpu.get_fail_descr_number(faildescr) - self._write_fail_index(fail_index) + self._store_force_index(guard_op) numargs = op.numargs() callargs = arglocs[2:numargs + 1] # extract the arguments to the call adr = arglocs[1] @@ -1300,12 +1293,13 @@ size = descr.get_result_size() signed = descr.is_result_signed() # - self._emit_call(fail_index, adr, callargs, fcond, + self._emit_call(adr, callargs, fcond, resloc, (size, signed)) - self.mc.LDR_ri(r.ip.value, r.fp.value) + ofs = self.cpu.get_ofs_of_frame_field('jf_descr') + self.mc.LDR_ri(r.ip.value, r.fp.value, imm=ofs) self.mc.CMP_ri(r.ip.value, 0) - self._emit_guard(guard_op, arglocs[1 + numargs:], c.GE, + self._emit_guard(guard_op, arglocs[1 + numargs:], c.EQ, save_exc=True, is_guard_not_forced=True) return fcond @@ -1322,15 +1316,13 @@ if gcrootmap: self.call_release_gil(gcrootmap, arglocs, fcond) # do the call - faildescr = guard_op.getdescr() - fail_index = self.cpu.get_fail_descr_number(faildescr) - self._write_fail_index(fail_index) + self._store_force_index(guard_op) # descr = op.getdescr() size = descr.get_result_size() signed = descr.is_result_signed() # - self._emit_call(fail_index, adr, callargs, fcond, + self._emit_call(adr, callargs, fcond, resloc, (size, signed)) # then reopen the stack if gcrootmap: @@ -1352,8 +1344,7 @@ regs_to_save.append(reg) assert gcrootmap.is_shadow_stack with saved_registers(self.mc, regs_to_save): - self._emit_call(NO_FORCE_INDEX, - imm(self.releasegil_addr), [], fcond) + self._emit_call(imm(self.releasegil_addr), [], fcond) def call_reacquire_gil(self, gcrootmap, save_loc, fcond): # save the previous result into the stack temporarily. @@ -1370,25 +1361,14 @@ regs_to_save.append(r.ip) # for alingment assert gcrootmap.is_shadow_stack with saved_registers(self.mc, regs_to_save, vfp_regs_to_save): - self._emit_call(NO_FORCE_INDEX, imm(self.reacqgil_addr), [], fcond) + self._emit_call(imm(self.reacqgil_addr), [], fcond) - def write_new_force_index(self): - # for shadowstack only: get a new, unused force_index number and - # write it to FORCE_INDEX_OFS. Used to record the call shape - # (i.e. where the GC pointers are in the stack) around a CALL - # instruction that doesn't already have a force_index. - gcrootmap = self.cpu.gc_ll_descr.gcrootmap - if gcrootmap and gcrootmap.is_shadow_stack: - clt = self.current_clt - force_index = clt.reserve_and_record_some_faildescr_index() - self._write_fail_index(force_index) - return force_index - else: - return 0 - - def _write_fail_index(self, fail_index): - self.mc.gen_load_int(r.ip.value, fail_index) - self.mc.STR_ri(r.ip.value, r.fp.value) + def _store_force_index(self, guard_op): + faildescr = guard_op.getdescr() + ofs = self.cpu.get_ofs_of_frame_field('jf_force_descr') + value = rffi.cast(lltype.Signed, cast_instance_to_gcref(faildescr)) + self.mc.gen_load_int(r.ip.value, value) + self.store_reg(self.mc, r.ip, r.fp, ofs) def emit_op_call_malloc_gc(self, op, arglocs, regalloc, fcond): self.emit_op_call(op, arglocs, regalloc, fcond) diff --git a/rpython/jit/backend/arm/regalloc.py b/rpython/jit/backend/arm/regalloc.py --- a/rpython/jit/backend/arm/regalloc.py +++ b/rpython/jit/backend/arm/regalloc.py @@ -1070,6 +1070,7 @@ prepare_op_cond_call_gc_wb_array = prepare_op_cond_call_gc_wb def prepare_op_force_token(self, op, fcond): + # XXX for now we return a regular reg res_loc = self.force_allocate_reg(op.result) self.possibly_free_var(op.result) return [res_loc] @@ -1109,9 +1110,9 @@ # end of the same loop, i.e. if what we are compiling is a single # loop that ends up jumping to this LABEL, then we can now provide # the hints about the expected position of the spilled variables. - jump_op = self.final_jump_op - if jump_op is not None and jump_op.getdescr() is descr: - self._compute_hint_frame_locations_from_descr(descr) + #jump_op = self.final_jump_op + #if jump_op is not None and jump_op.getdescr() is descr: + # self._compute_hint_frame_locations_from_descr(descr) def prepare_guard_call_may_force(self, op, guard_op, fcond): args = self._prepare_call(op, save_all_regs=True) diff --git a/rpython/jit/backend/arm/runner.py b/rpython/jit/backend/arm/runner.py --- a/rpython/jit/backend/arm/runner.py +++ b/rpython/jit/backend/arm/runner.py @@ -117,33 +117,6 @@ cast_ptr_to_int._annspecialcase_ = 'specialize:arglltype(0)' cast_ptr_to_int = staticmethod(cast_ptr_to_int) - all_null_registers = lltype.malloc(rffi.LONGP.TO, - len(all_vfp_regs) * 2 + len(all_regs), - flavor='raw', zero=True, immortal=True) - - def force(self, addr_of_force_index): - TP = rffi.CArrayPtr(lltype.Signed) - fail_index = rffi.cast(TP, addr_of_force_index)[0] - assert fail_index >= 0, "already forced!" - faildescr = self.get_fail_descr_from_number(fail_index) - rffi.cast(TP, addr_of_force_index)[0] = ~fail_index - frb = self.assembler._find_failure_recovery_bytecode(faildescr) - bytecode = rffi.cast(rffi.UCHARP, frb) - addr_all_null_regsiters = rffi.cast(rffi.LONG, self.all_null_registers) - # - assert (rffi.cast(lltype.Signed, bytecode[0]) == - self.assembler.CODE_FORCED) - bytecode = rffi.ptradd(bytecode, 1) - deadframe = self.assembler.grab_frame_values(self, - bytecode, addr_of_force_index, - self.all_null_registers, - self.all_null_registers) - # - assert self.get_latest_descr(deadframe) is faildescr - self.assembler.force_token_to_dead_frame[addr_of_force_index] = ( - deadframe) - return deadframe - def redirect_call_assembler(self, oldlooptoken, newlooptoken): self.assembler.redirect_call_assembler(oldlooptoken, newlooptoken) diff --git a/rpython/jit/backend/llsupport/llmodel.py b/rpython/jit/backend/llsupport/llmodel.py --- a/rpython/jit/backend/llsupport/llmodel.py +++ b/rpython/jit/backend/llsupport/llmodel.py @@ -178,6 +178,11 @@ self.gc_ll_descr.freeing_block(rawstart, rawstop) self.asmmemmgr.free(rawstart, rawstop) + def force(self, addr_of_force_token): + frame = rffi.cast(jitframe.JITFRAMEPTR, addr_of_force_token) + frame.jf_descr = frame.jf_force_descr + return lltype.cast_opaque_ptr(llmemory.GCREF, frame) + # ------------------- helpers and descriptions -------------------- @staticmethod diff --git a/rpython/jit/backend/x86/runner.py b/rpython/jit/backend/x86/runner.py --- a/rpython/jit/backend/x86/runner.py +++ b/rpython/jit/backend/x86/runner.py @@ -152,11 +152,6 @@ cast_ptr_to_int._annspecialcase_ = 'specialize:arglltype(0)' cast_ptr_to_int = staticmethod(cast_ptr_to_int) - def force(self, addr_of_force_token): - frame = rffi.cast(jitframe.JITFRAMEPTR, addr_of_force_token) - frame.jf_descr = frame.jf_force_descr - return lltype.cast_opaque_ptr(llmemory.GCREF, frame) - def redirect_call_assembler(self, oldlooptoken, newlooptoken): self.assembler.redirect_call_assembler(oldlooptoken, newlooptoken) From noreply at buildbot.pypy.org Sun Feb 10 15:08:17 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sun, 10 Feb 2013 15:08:17 +0100 (CET) Subject: [pypy-commit] pypy default: these asserts should work Message-ID: <20130210140817.113391C1029@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61042:77dc5a5f2dfe Date: 2013-02-10 08:38 -0500 http://bitbucket.org/pypy/pypy/changeset/77dc5a5f2dfe/ Log: these asserts should work diff --git a/pypy/interpreter/test2/test_app_main.py b/pypy/interpreter/test2/test_app_main.py --- a/pypy/interpreter/test2/test_app_main.py +++ b/pypy/interpreter/test2/test_app_main.py @@ -906,10 +906,12 @@ import app_main app_main.setup_bootstrap_path('/tmp/pypy-c') # stdlib not found assert sys.executable == '' - assert sys.path[:len(old_sys_path)] == old_sys_path + assert sys.path == old_sys_path + [self.goal_dir] app_main.setup_bootstrap_path(self.fake_exe) assert sys.executable == self.fake_exe + assert self.goal_dir not in sys.path + newpath = sys.path[:] if newpath[0].endswith('__extensions__'): newpath = newpath[1:] From noreply at buildbot.pypy.org Sun Feb 10 15:14:01 2013 From: noreply at buildbot.pypy.org (fijal) Date: Sun, 10 Feb 2013 15:14:01 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: push for _check_frame_depth Message-ID: <20130210141401.A8BCC1C1029@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61043:70d8ed3723ef Date: 2013-02-10 16:13 +0200 http://bitbucket.org/pypy/pypy/changeset/70d8ed3723ef/ Log: push for _check_frame_depth diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -205,12 +205,17 @@ mc.MOV_rs(ecx.value, WORD) gcmap_ofs = self.cpu.get_ofs_of_frame_field('jf_gcmap') mc.MOV_br(gcmap_ofs, ecx.value) - # this is size that we're after, sanity checking only - mc.MOV_rs(esi.value, WORD*2) - # push first arg - mc.MOV_rr(edi.value, ebp.value) + if IS_X86_64: + # this is size that we're after, sanity checking only + mc.MOV_rs(esi.value, WORD*2) + # push first arg + mc.MOV_rr(edi.value, ebp.value) + align = align_stack_words(1) + else: + mc.PUSH(RawStackLoc(WORD * 2)) + mc.PUSH_r(ebp.value) + align = align_stack_words(3) # align - align = align_stack_words(1) mc.SUB_ri(esp.value, (align - 1) * WORD) mc.CALL(imm(self.cpu.realloc_frame)) @@ -677,7 +682,6 @@ else: mc.CMP_bi(ofs, expected_size) stack_check_cmp_ofs = mc.get_relative_pos() - 4 - assert not IS_X86_32 mc.J_il8(rx86.Conditions['GE'], 0) jg_location = mc.get_relative_pos() if expected_size == -1: From noreply at buildbot.pypy.org Sun Feb 10 15:21:23 2013 From: noreply at buildbot.pypy.org (fijal) Date: Sun, 10 Feb 2013 15:21:23 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: finish fix Message-ID: <20130210142123.45B2E1C1029@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61044:1b13505c17e9 Date: 2013-02-10 16:20 +0200 http://bitbucket.org/pypy/pypy/changeset/1b13505c17e9/ Log: finish fix diff --git a/rpython/jit/backend/x86/regloc.py b/rpython/jit/backend/x86/regloc.py --- a/rpython/jit/backend/x86/regloc.py +++ b/rpython/jit/backend/x86/regloc.py @@ -70,6 +70,9 @@ def is_float(self): return self.type == FLOAT + def add_offset(self, ofs): + return RawStackLoc(self.value + ofs) + class RawEspLoc(AssemblerLocation): """ Esp-based location """ From noreply at buildbot.pypy.org Sun Feb 10 15:27:37 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sun, 10 Feb 2013 15:27:37 +0100 (CET) Subject: [pypy-commit] cffi slicing: Slicing cdata objects Message-ID: <20130210142737.7F5871C1047@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: slicing Changeset: r1133:9320bd4488cf Date: 2013-02-10 14:44 +0100 http://bitbucket.org/cffi/cffi/changeset/9320bd4488cf/ Log: Slicing cdata objects From noreply at buildbot.pypy.org Sun Feb 10 15:27:38 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sun, 10 Feb 2013 15:27:38 +0100 (CET) Subject: [pypy-commit] cffi slicing: getting a slice Message-ID: <20130210142738.A9BAF1C1047@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: slicing Changeset: r1134:b68c5dd2b9ce Date: 2013-02-10 14:44 +0100 http://bitbucket.org/cffi/cffi/changeset/b68c5dd2b9ce/ Log: getting a slice diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c --- a/c/_cffi_backend.c +++ b/c/_cffi_backend.c @@ -102,7 +102,8 @@ PyObject *ct_stuff; /* structs: dict of the fields arrays: ctypedescr of the ptr type function: tuple(abi, ctres, ctargs..) - enum: pair {"name":x},{x:"name"} */ + enum: pair {"name":x},{x:"name"} + ptrs: lazily, ctypedescr of array */ void *ct_extra; /* structs: first field (not a ref!) function types: cif_description primitives: prebuilt "cif" object */ @@ -1490,6 +1491,9 @@ s = PyText_FromString(buffer); } } + else if ((cd->c_type->ct_flags & CT_ARRAY) && cd->c_type->ct_length < 0) { + s = PyText_FromFormat("sliced length %zd", get_array_length(cd)); + } else { if (cd->c_data != NULL) { s = PyText_FromFormat("%p", cd->c_data); @@ -1717,9 +1721,71 @@ } static PyObject * +new_array_type(CTypeDescrObject *ctptr, PyObject *lengthobj); /* forward */ + +static PyObject * +cdata_slice(CDataObject *cd, PySliceObject *slice) +{ + Py_ssize_t start, stop; + CDataObject_own_length *scd; + CTypeDescrObject *ct = cd->c_type; + + if (!(ct->ct_flags & (CT_ARRAY | CT_POINTER))) { + PyErr_Format(PyExc_TypeError, "cdata of type '%s' cannot be indexed", + ct->ct_name); + return NULL; + } + start = PyInt_AsSsize_t(slice->start); + if (start == -1 && PyErr_Occurred()) { + if (slice->start == Py_None) + PyErr_SetString(PyExc_IndexError, "slice start must be specified"); + return NULL; + } + stop = PyInt_AsSsize_t(slice->stop); + if (stop == -1 && PyErr_Occurred()) { + if (slice->stop == Py_None) + PyErr_SetString(PyExc_IndexError, "slice stop must be specified"); + return NULL; + } + if (slice->step != Py_None) { + PyErr_SetString(PyExc_IndexError, "slice with step not supported"); + return NULL; + } + if (start > stop) { + PyErr_SetString(PyExc_IndexError, "slice start > stop"); + return NULL; + } + + if (ct->ct_flags & CT_ARRAY) + ct = (CTypeDescrObject *)ct->ct_stuff; + assert(ct->ct_flags & CT_POINTER); + if (ct->ct_stuff == NULL) { + ct->ct_stuff = new_array_type(ct, Py_None); + if (ct->ct_stuff == NULL) + return NULL; + } + ct = (CTypeDescrObject *)ct->ct_stuff; + + scd = (CDataObject_own_length *)PyObject_Malloc( + offsetof(CDataObject_own_length, alignment)); + if (PyObject_Init((PyObject *)scd, &CData_Type) == NULL) + return NULL; + Py_INCREF(ct); + scd->head.c_type = ct; + scd->head.c_data = cd->c_data + ct->ct_itemdescr->ct_size * start; + scd->head.c_weakreflist = NULL; + scd->length = stop - start; + return (PyObject *)scd; +} + +static PyObject * cdataowning_subscript(CDataObject *cd, PyObject *key) { - char *c = _cdata_get_indexed_ptr(cd, key); + char *c; + if (PySlice_Check(key)) + return cdata_slice(cd, (PySliceObject *)key); + + c = _cdata_get_indexed_ptr(cd, key); /* use 'mp_subscript' instead of 'sq_item' because we don't want negative indexes to be corrected automatically */ if (c == NULL && PyErr_Occurred()) @@ -1738,7 +1804,11 @@ static PyObject * cdata_subscript(CDataObject *cd, PyObject *key) { - char *c = _cdata_get_indexed_ptr(cd, key); + char *c; + if (PySlice_Check(key)) + return cdata_slice(cd, (PySliceObject *)key); + + c = _cdata_get_indexed_ptr(cd, key); /* use 'mp_subscript' instead of 'sq_item' because we don't want negative indexes to be corrected automatically */ if (c == NULL && PyErr_Occurred()) @@ -3122,14 +3192,22 @@ static PyObject *b_new_array_type(PyObject *self, PyObject *args) { PyObject *lengthobj; - CTypeDescrObject *td, *ctitem, *ctptr; - char extra_text[32]; - Py_ssize_t length, arraysize; + CTypeDescrObject *ctptr; if (!PyArg_ParseTuple(args, "O!O:new_array_type", &CTypeDescr_Type, &ctptr, &lengthobj)) return NULL; + return new_array_type(ctptr, lengthobj); +} + +static PyObject * +new_array_type(CTypeDescrObject *ctptr, PyObject *lengthobj) +{ + CTypeDescrObject *td, *ctitem; + char extra_text[32]; + Py_ssize_t length, arraysize; + if (!(ctptr->ct_flags & CT_POINTER)) { PyErr_SetString(PyExc_TypeError, "first arg must be a pointer ctype"); return NULL; diff --git a/c/test_c.py b/c/test_c.py --- a/c/test_c.py +++ b/c/test_c.py @@ -2574,3 +2574,19 @@ for i in range(20): buf = buflist[i] assert buf[:] == str2bytes("hi there %d\x00" % i) + +def test_slice(): + BIntP = new_pointer_type(new_primitive_type("int")) + BIntArray = new_array_type(BIntP, None) + c = newp(BIntArray, 5) + assert len(c) == 5 + assert repr(c) == "" + d = c[1:4] + assert len(d) == 3 + assert repr(d) == "" + d[0] = 123 + d[2] = 456 + assert c[1] == 123 + assert c[3] == 456 + py.test.raises(IndexError, "d[3]") + py.test.raises(IndexError, "d[-1]") From noreply at buildbot.pypy.org Sun Feb 10 15:27:39 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sun, 10 Feb 2013 15:27:39 +0100 (CET) Subject: [pypy-commit] cffi slicing: More tests, small fixes Message-ID: <20130210142739.BEFED1C1047@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: slicing Changeset: r1135:15cf69c6307c Date: 2013-02-10 14:52 +0100 http://bitbucket.org/cffi/cffi/changeset/15cf69c6307c/ Log: More tests, small fixes diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c --- a/c/_cffi_backend.c +++ b/c/_cffi_backend.c @@ -1728,13 +1728,8 @@ { Py_ssize_t start, stop; CDataObject_own_length *scd; - CTypeDescrObject *ct = cd->c_type; - - if (!(ct->ct_flags & (CT_ARRAY | CT_POINTER))) { - PyErr_Format(PyExc_TypeError, "cdata of type '%s' cannot be indexed", - ct->ct_name); - return NULL; - } + CTypeDescrObject *ct; + start = PyInt_AsSsize_t(slice->start); if (start == -1 && PyErr_Occurred()) { if (slice->start == Py_None) @@ -1756,9 +1751,28 @@ return NULL; } - if (ct->ct_flags & CT_ARRAY) + ct = cd->c_type; + if (ct->ct_flags & CT_ARRAY) { + if (start < 0) { + PyErr_SetString(PyExc_IndexError, + "negative index not supported"); + return NULL; + } + if (stop >= get_array_length(cd)) { + PyErr_Format(PyExc_IndexError, + "index too large for cdata '%s' (expected %zd < %zd)", + cd->c_type->ct_name, + stop, get_array_length(cd)); + return NULL; + } ct = (CTypeDescrObject *)ct->ct_stuff; - assert(ct->ct_flags & CT_POINTER); + } + else if (!(ct->ct_flags & CT_POINTER)) { + PyErr_Format(PyExc_TypeError, "cdata of type '%s' cannot be indexed", + ct->ct_name); + return NULL; + } + if (ct->ct_stuff == NULL) { ct->ct_stuff = new_array_type(ct, Py_None); if (ct->ct_stuff == NULL) diff --git a/c/test_c.py b/c/test_c.py --- a/c/test_c.py +++ b/c/test_c.py @@ -2588,5 +2588,24 @@ d[2] = 456 assert c[1] == 123 assert c[3] == 456 + assert d[2] == 456 py.test.raises(IndexError, "d[3]") py.test.raises(IndexError, "d[-1]") + +def test_slice_ptr(): + BIntP = new_pointer_type(new_primitive_type("int")) + BIntArray = new_array_type(BIntP, None) + c = newp(BIntArray, 5) + d = (c+1)[0:2] + assert len(d) == 2 + assert repr(d) == "" + d[1] += 50 + assert c[2] == 50 + +def test_slice_array_checkbounds(): + BIntP = new_pointer_type(new_primitive_type("int")) + BIntArray = new_array_type(BIntP, None) + c = newp(BIntArray, 5) + py.test.raises(IndexError, "c[-1:1]") + cp = c + 0 + cp[-1:1] From noreply at buildbot.pypy.org Sun Feb 10 15:27:40 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sun, 10 Feb 2013 15:27:40 +0100 (CET) Subject: [pypy-commit] cffi slicing: Check error paths Message-ID: <20130210142740.F36571C1047@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: slicing Changeset: r1136:8e01f5212871 Date: 2013-02-10 14:57 +0100 http://bitbucket.org/cffi/cffi/changeset/8e01f5212871/ Log: Check error paths diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c --- a/c/_cffi_backend.c +++ b/c/_cffi_backend.c @@ -1760,8 +1760,7 @@ } if (stop >= get_array_length(cd)) { PyErr_Format(PyExc_IndexError, - "index too large for cdata '%s' (expected %zd < %zd)", - cd->c_type->ct_name, + "index too large (expected %zd < %zd)", stop, get_array_length(cd)); return NULL; } diff --git a/c/test_c.py b/c/test_c.py --- a/c/test_c.py +++ b/c/test_c.py @@ -2609,3 +2609,20 @@ py.test.raises(IndexError, "c[-1:1]") cp = c + 0 cp[-1:1] + +def test_nonstandard_slice(): + BIntP = new_pointer_type(new_primitive_type("int")) + BIntArray = new_array_type(BIntP, None) + c = newp(BIntArray, 5) + e = py.test.raises(IndexError, "c[:5]") + assert str(e.value) == "slice start must be specified" + e = py.test.raises(IndexError, "c[4:]") + assert str(e.value) == "slice stop must be specified" + e = py.test.raises(IndexError, "c[1:2:3]") + assert str(e.value) == "slice with step not supported" + e = py.test.raises(IndexError, "c[1:2:1]") + assert str(e.value) == "slice with step not supported" + e = py.test.raises(IndexError, "c[4:2]") + assert str(e.value) == "slice start > stop" + e = py.test.raises(IndexError, "c[6:6]") + assert str(e.value) == "index too large (expected 6 < 5)" From noreply at buildbot.pypy.org Sun Feb 10 15:27:42 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sun, 10 Feb 2013 15:27:42 +0100 (CET) Subject: [pypy-commit] cffi slicing: slice assignment. Message-ID: <20130210142742.2B80A1C1047@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: slicing Changeset: r1137:d44a9f5c736e Date: 2013-02-10 15:27 +0100 http://bitbucket.org/cffi/cffi/changeset/d44a9f5c736e/ Log: slice assignment. diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c --- a/c/_cffi_backend.c +++ b/c/_cffi_backend.c @@ -1723,11 +1723,10 @@ static PyObject * new_array_type(CTypeDescrObject *ctptr, PyObject *lengthobj); /* forward */ -static PyObject * -cdata_slice(CDataObject *cd, PySliceObject *slice) +static CTypeDescrObject * +_cdata_getslicearg(CDataObject *cd, PySliceObject *slice, Py_ssize_t bounds[]) { Py_ssize_t start, stop; - CDataObject_own_length *scd; CTypeDescrObject *ct; start = PyInt_AsSsize_t(slice->start); @@ -1772,6 +1771,20 @@ return NULL; } + bounds[0] = start; + bounds[1] = stop - start; + return ct; +} + +static PyObject * +cdata_slice(CDataObject *cd, PySliceObject *slice) +{ + Py_ssize_t bounds[2]; + CDataObject_own_length *scd; + CTypeDescrObject *ct = _cdata_getslicearg(cd, slice, bounds); + if (ct == NULL) + return NULL; + if (ct->ct_stuff == NULL) { ct->ct_stuff = new_array_type(ct, Py_None); if (ct->ct_stuff == NULL) @@ -1785,12 +1798,60 @@ return NULL; Py_INCREF(ct); scd->head.c_type = ct; - scd->head.c_data = cd->c_data + ct->ct_itemdescr->ct_size * start; + scd->head.c_data = cd->c_data + ct->ct_itemdescr->ct_size * bounds[0]; scd->head.c_weakreflist = NULL; - scd->length = stop - start; + scd->length = bounds[1]; return (PyObject *)scd; } +static int +cdata_ass_slice(CDataObject *cd, PySliceObject *slice, PyObject *v) +{ + Py_ssize_t bounds[2], i, length, itemsize; + PyObject *it, *item; + PyObject *(*iternext)(PyObject *); + char *cdata; + int err; + CTypeDescrObject *ct = _cdata_getslicearg(cd, slice, bounds); + if (ct == NULL) + return -1; + + it = PyObject_GetIter(v); + if (it == NULL) + return -1; + iternext = *it->ob_type->tp_iternext; + + ct = ct->ct_itemdescr; + itemsize = ct->ct_size; + cdata = cd->c_data + itemsize * bounds[0]; + length = bounds[1]; + for (i = 0; i < length; i++) { + item = iternext(it); + if (item == NULL) { + if (!PyErr_Occurred()) + PyErr_Format(PyExc_ValueError, + "need %zd values to unpack, got %zd", + length, i); + goto error; + } + err = convert_from_object(cdata, ct, item); + Py_DECREF(item); + if (err < 0) + goto error; + + cdata += itemsize; + } + item = iternext(it); + if (item != NULL) { + Py_DECREF(item); + PyErr_Format(PyExc_ValueError, + "got more than %zd values to unpack", length); + } + error: + Py_DECREF(it); + return PyErr_Occurred() ? -1 : 0; +} + static PyObject * cdataowning_subscript(CDataObject *cd, PyObject *key) { @@ -1832,8 +1893,13 @@ static int cdata_ass_sub(CDataObject *cd, PyObject *key, PyObject *v) { - char *c = _cdata_get_indexed_ptr(cd, key); - CTypeDescrObject *ctitem = cd->c_type->ct_itemdescr; + char *c; + CTypeDescrObject *ctitem; + if (PySlice_Check(key)) + return cdata_ass_slice(cd, (PySliceObject *)key, v); + + c = _cdata_get_indexed_ptr(cd, key); + ctitem = cd->c_type->ct_itemdescr; /* use 'mp_ass_subscript' instead of 'sq_ass_item' because we don't want negative indexes to be corrected automatically */ if (c == NULL && PyErr_Occurred()) diff --git a/c/test_c.py b/c/test_c.py --- a/c/test_c.py +++ b/c/test_c.py @@ -2626,3 +2626,19 @@ assert str(e.value) == "slice start > stop" e = py.test.raises(IndexError, "c[6:6]") assert str(e.value) == "index too large (expected 6 < 5)" + +def test_setslice(): + BIntP = new_pointer_type(new_primitive_type("int")) + BIntArray = new_array_type(BIntP, None) + c = newp(BIntArray, 5) + c[1:3] = [100, 200] + assert list(c) == [0, 100, 200, 0, 0] + cp = c + 3 + cp[-1:1] = [300, 400] + assert list(c) == [0, 100, 300, 400, 0] + cp[-1:1] = iter([500, 600]) + assert list(c) == [0, 100, 500, 600, 0] + py.test.raises(ValueError, "cp[-1:1] = [1000]") + assert list(c) == [0, 100, 1000, 600, 0] + py.test.raises(ValueError, "cp[-1:1] = (700, 800, 900)") + assert list(c) == [0, 100, 700, 800, 0] From noreply at buildbot.pypy.org Sun Feb 10 15:48:54 2013 From: noreply at buildbot.pypy.org (fijal) Date: Sun, 10 Feb 2013 15:48:54 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: some call fixes, comment out STDCALL (is it ever used?) Message-ID: <20130210144854.6A7A01C004F@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61045:3e1f51eb9620 Date: 2013-02-10 16:48 +0200 http://bitbucket.org/pypy/pypy/changeset/3e1f51eb9620/ Log: some call fixes, comment out STDCALL (is it ever used?) diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -1124,9 +1124,23 @@ if IS_X86_64: return self._emit_call_64(x, arglocs, start, argtypes, can_collect=can_collect) - XXX + stack_depth = 0 + n = len(arglocs) + for i in range(start, n): + loc = arglocs[i] + if isinstance(loc, RegLoc): + if loc.is_xmm: + stack_depth += 2 + else: + stack_depth += 1 + stack_depth += loc.get_width() + if stack_depth > PASS_ON_MY_FRAME: + stack_depth = align_stack_words(stack_depth) + align = (stack_depth - PASS_ON_MY_FRAME) + self.mc.SUB_ri(esp.value, align * WORD) + else: + align = 0 p = 0 - n = len(arglocs) for i in range(start, n): loc = arglocs[i] if isinstance(loc, RegLoc): @@ -1147,15 +1161,24 @@ self.mc.MOV_sr(p, tmp.value) p += loc.get_width() # x is a location + if can_collect: + noregs = self.cpu.gc_ll_descr.is_shadow_stack() + gcmap = self._regalloc.get_gcmap([eax], noregs=noregs) + self.push_gcmap(self.mc, gcmap, store=True) self.mc.CALL(x) + if can_collect: + self._reload_frame_if_necessary(self.mc) + if align: + self.mc.ADD_ri(esp.value, align * WORD) + if can_collect: + self.pop_gcmap(self.mc) # if callconv != FFI_DEFAULT_ABI: self._fix_stdcall(callconv, p) - # - self._regalloc.needed_extra_stack_locations(p//WORD) def _fix_stdcall(self, callconv, p): from rpython.rlib.clibffi import FFI_STDCALL + xxx assert callconv == FFI_STDCALL # it's a bit stupid, but we're just going to cancel the fact that # the called function just added 'p' to ESP, by subtracting it again. From noreply at buildbot.pypy.org Sun Feb 10 16:15:02 2013 From: noreply at buildbot.pypy.org (fijal) Date: Sun, 10 Feb 2013 16:15:02 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: turns out floats are 2-words wide on 32bit Message-ID: <20130210151502.15F071C03D5@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61046:87bb01bc4ae8 Date: 2013-02-10 17:14 +0200 http://bitbucket.org/pypy/pypy/changeset/87bb01bc4ae8/ Log: turns out floats are 2-words wide on 32bit diff --git a/rpython/jit/backend/x86/arch.py b/rpython/jit/backend/x86/arch.py --- a/rpython/jit/backend/x86/arch.py +++ b/rpython/jit/backend/x86/arch.py @@ -33,7 +33,7 @@ # ebp + ebx + esi + edi + 6 extra words + return address = 9 words FRAME_FIXED_SIZE = 11 PASS_ON_MY_FRAME = 6 - JITFRAME_FIXED_SIZE = 6 + 8 # 6 GPR + 8 XMM + JITFRAME_FIXED_SIZE = 6 + 8 * 2 # 6 GPR + 8 XMM * 2 WORDS/float else: # rbp + rbx + r12 + r13 + r14 + r15 + 12 extra words + return address = 19 FRAME_FIXED_SIZE = 19 diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -1958,7 +1958,10 @@ elif pos < GPR_REGS * WORD: locs.append(gpr_reg_mgr_cls.all_regs[pos // WORD]) elif pos < (GPR_REGS + XMM_REGS) * WORD: - pos = pos // WORD - GPR_REGS + if IS_X86_64: + pos = pos // WORD - GPR_REGS + else: + pos = (pos // WORD - GPR_REGS) // 2 locs.append(xmm_reg_mgr_cls.all_regs[pos]) else: i = pos // WORD - JITFRAME_FIXED_SIZE @@ -1983,10 +1986,14 @@ if gpr not in ignored_regs: mc.MOV_br(i * WORD + base_ofs, gpr.value) if withfloats: + if IS_X86_64: + coeff = 1 + else: + coeff = 2 # Push all XMM regs ofs = len(gpr_reg_mgr_cls.all_regs) for i in range(len(xmm_reg_mgr_cls.all_regs)): - mc.MOVSD_bx((ofs + i) * WORD + base_ofs, i) + mc.MOVSD_bx((ofs + i) * coeff * WORD + base_ofs, i) def _pop_all_regs_from_frame(self, mc, ignored_regs, withfloats, callee_only=False): @@ -2001,9 +2008,13 @@ mc.MOV_rb(gpr.value, i * WORD + base_ofs) if withfloats: # Pop all XMM regs + if IS_X86_64: + coeff = 1 + else: + coeff = 2 ofs = len(gpr_reg_mgr_cls.all_regs) for i in range(len(xmm_reg_mgr_cls.all_regs)): - mc.MOVSD_xb(i, (ofs + i) * WORD + base_ofs) + mc.MOVSD_xb(i, (ofs + i) * WORD * coeff + base_ofs) def _build_failure_recovery(self, exc, withfloats=False): mc = codebuf.MachineCodeBlockWrapper() From noreply at buildbot.pypy.org Sun Feb 10 16:37:06 2013 From: noreply at buildbot.pypy.org (fijal) Date: Sun, 10 Feb 2013 16:37:06 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: fix failure generation Message-ID: <20130210153706.21AD41C1029@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61047:46e31ce352d7 Date: 2013-02-10 17:36 +0200 http://bitbucket.org/pypy/pypy/changeset/46e31ce352d7/ Log: fix failure generation diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -1912,8 +1912,12 @@ else: assert isinstance(loc, RegLoc) assert loc is not ebp # for now + if IS_X86_64: + coeff = 1 + else: + coeff = 2 if loc.is_xmm: - v = len(gpr_reg_mgr_cls.all_regs) + loc.value + v = len(gpr_reg_mgr_cls.all_regs) + loc.value * coeff else: v = gpr_reg_mgr_cls.all_reg_indexes[loc.value] positions[i] = v * WORD @@ -1993,7 +1997,7 @@ # Push all XMM regs ofs = len(gpr_reg_mgr_cls.all_regs) for i in range(len(xmm_reg_mgr_cls.all_regs)): - mc.MOVSD_bx((ofs + i) * coeff * WORD + base_ofs, i) + mc.MOVSD_bx((ofs + i * coeff) * WORD + base_ofs, i) def _pop_all_regs_from_frame(self, mc, ignored_regs, withfloats, callee_only=False): @@ -2014,7 +2018,7 @@ coeff = 2 ofs = len(gpr_reg_mgr_cls.all_regs) for i in range(len(xmm_reg_mgr_cls.all_regs)): - mc.MOVSD_xb(i, (ofs + i) * WORD * coeff + base_ofs) + mc.MOVSD_xb(i, (ofs + i * coeff) * WORD + base_ofs) def _build_failure_recovery(self, exc, withfloats=False): mc = codebuf.MachineCodeBlockWrapper() From noreply at buildbot.pypy.org Sun Feb 10 16:55:37 2013 From: noreply at buildbot.pypy.org (fijal) Date: Sun, 10 Feb 2013 16:55:37 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: fix here too Message-ID: <20130210155537.EABEB1C004F@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61048:ae33ff65877b Date: 2013-02-10 17:54 +0200 http://bitbucket.org/pypy/pypy/changeset/ae33ff65877b/ Log: fix here too diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -1956,16 +1956,17 @@ XMM_REGS = len(xmm_reg_mgr_cls.all_regs) base_ofs = self.cpu.get_baseofs_of_frame_field() input_i = 0 + if IS_X86_64: + coeff = 1 + else: + coeff = 2 for pos in descr.rd_locs: if pos == -1: continue elif pos < GPR_REGS * WORD: locs.append(gpr_reg_mgr_cls.all_regs[pos // WORD]) - elif pos < (GPR_REGS + XMM_REGS) * WORD: - if IS_X86_64: - pos = pos // WORD - GPR_REGS - else: - pos = (pos // WORD - GPR_REGS) // 2 + elif pos < (GPR_REGS + XMM_REGS * coeff) * WORD: + pos = (pos // WORD - GPR_REGS) // coeff locs.append(xmm_reg_mgr_cls.all_regs[pos]) else: i = pos // WORD - JITFRAME_FIXED_SIZE From noreply at buildbot.pypy.org Sun Feb 10 17:37:12 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sun, 10 Feb 2013 17:37:12 +0100 (CET) Subject: [pypy-commit] cffi slicing: Document Message-ID: <20130210163712.6FF8B1C004F@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: slicing Changeset: r1138:91d651f7cdce Date: 2013-02-10 17:30 +0100 http://bitbucket.org/cffi/cffi/changeset/91d651f7cdce/ Log: Document diff --git a/doc/source/index.rst b/doc/source/index.rst --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -1274,9 +1274,9 @@ | | anything on which | precision `(***)`| | | | float() works | | | +---------------+------------------------+------------------+----------------+ -| pointers | another with | a | ``[]``, ``+``, | -| | a compatible type (i.e.| | ``-``, bool() | -| | same type or ``char*`` | | | +| pointers | another with | a |``[]`` `(****)`,| +| | a compatible type (i.e.| |``+``, ``-``, | +| | same type or ``char*`` | |bool() | | | or ``void*``, or as an | | | | | array instead) `(*)` | | | +---------------+------------------------+ | | @@ -1292,9 +1292,9 @@ | function | same as pointers | | bool(), | | pointers | | | call `(**)` | +---------------+------------------------+------------------+----------------+ -| arrays | a list or tuple of | a | len(), iter(), | -| | items | | ``[]``, | -| | | | ``+``, ``-`` | +| arrays | a list or tuple of | a |len(), iter(), | +| | items | |``[]`` `(****)`,| +| | | |``+``, ``-`` | +---------------+------------------------+ +----------------+ | ``char[]`` | same as arrays, or a | | len(), iter(), | | | Python string | | ``[]``, ``+``, | @@ -1349,6 +1349,15 @@ without any precision loss, you need to define and use a family of C functions like ``long double add(long double a, long double b);``. +.. versionadded:: 0.6 + `(****)` Supports simple slices as well: ``x[start:stop]`` gives another + cdata object that is a "view" of all items from ``start`` to ``stop``. + It is a cdata of type "array" (so e.g. passing it as an argument to a + C function would just convert it to a pointer to the ``start`` item). + As with indexing, negative bounds mean really negative indices, like in + C. As for slice assignment, it accepts any iterable, including a list + of items or another array-like cdata object, but the length must match. + Reference: verifier ------------------- From noreply at buildbot.pypy.org Sun Feb 10 17:37:13 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sun, 10 Feb 2013 17:37:13 +0100 (CET) Subject: [pypy-commit] cffi slicing: Add a past path for slice assignment with a cdata-of-same-type source. Message-ID: <20130210163713.90F0C1C004F@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: slicing Changeset: r1139:dc27146b274a Date: 2013-02-10 17:37 +0100 http://bitbucket.org/cffi/cffi/changeset/dc27146b274a/ Log: Add a past path for slice assignment with a cdata-of-same-type source. diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c --- a/c/_cffi_backend.c +++ b/c/_cffi_backend.c @@ -1815,16 +1815,26 @@ CTypeDescrObject *ct = _cdata_getslicearg(cd, slice, bounds); if (ct == NULL) return -1; + ct = ct->ct_itemdescr; + itemsize = ct->ct_size; + cdata = cd->c_data + itemsize * bounds[0]; + length = bounds[1]; + + if (CData_Check(v)) { + CTypeDescrObject *ctv = ((CDataObject *)v)->c_type; + if ((ctv->ct_flags & CT_ARRAY) && (ctv->ct_itemdescr == ct) && + (get_array_length((CDataObject *)v) == length)) { + /* fast path: copying from exactly the correct type */ + memcpy(cdata, ((CDataObject *)v)->c_data, itemsize * length); + return 0; + } + } it = PyObject_GetIter(v); if (it == NULL) return -1; iternext = *it->ob_type->tp_iternext; - ct = ct->ct_itemdescr; - itemsize = ct->ct_size; - cdata = cd->c_data + itemsize * bounds[0]; - length = bounds[1]; for (i = 0; i < length; i++) { item = iternext(it); if (item == NULL) { diff --git a/c/test_c.py b/c/test_c.py --- a/c/test_c.py +++ b/c/test_c.py @@ -2642,3 +2642,17 @@ assert list(c) == [0, 100, 1000, 600, 0] py.test.raises(ValueError, "cp[-1:1] = (700, 800, 900)") assert list(c) == [0, 100, 700, 800, 0] + +def test_setslice_array(): + BIntP = new_pointer_type(new_primitive_type("int")) + BIntArray = new_array_type(BIntP, None) + c = newp(BIntArray, 5) + d = newp(BIntArray, [10, 20, 30]) + c[1:4] = d + assert list(c) == [0, 10, 20, 30, 0] + # + BShortP = new_pointer_type(new_primitive_type("short")) + BShortArray = new_array_type(BShortP, None) + d = newp(BShortArray, [40, 50]) + c[1:3] = d + assert list(c) == [0, 40, 50, 30, 0] From noreply at buildbot.pypy.org Sun Feb 10 17:48:24 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sun, 10 Feb 2013 17:48:24 +0100 (CET) Subject: [pypy-commit] cffi enum-as-int: Document Message-ID: <20130210164824.759621C004F@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: enum-as-int Changeset: r1140:7ee599904f2f Date: 2013-02-10 17:48 +0100 http://bitbucket.org/cffi/cffi/changeset/7ee599904f2f/ Log: Document diff --git a/doc/source/index.rst b/doc/source/index.rst --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -1031,7 +1031,7 @@ ------------------- ``ffi.include(other_ffi)``: includes the typedefs, structs, unions and -enums defined in another FFI instance. Usage is similar to a +enum types defined in another FFI instance. Usage is similar to a ``#include`` in C, where a part of the program might include types defined in another part for its own usage. Note that the include() method has no effect on functions, constants and global variables, which @@ -1065,8 +1065,9 @@ byte string or unicode string. (Note that in some situation a single wchar_t may require a Python unicode string of length 2.) -- If 'cdata' is an enum, returns the value of the enumerator as a - string, or ``#NUMBER`` if the value is out of range. +- If 'cdata' is an enum, returns the value of the enumerator as a string. + If the value is out of range, it is simply returned as the stringified + integer. ``ffi.buffer(cdata, [size])``: return a buffer object that references @@ -1254,8 +1255,8 @@ | C type | writing into | reading from |other operations| +===============+========================+==================+================+ | integers | an integer or anything | a Python int or | int() | -| | on which int() works | long, depending | | -| | (but not a float!). | on the type | | +| and enums | on which int() works | long, depending | | +| `(*****)` | (but not a float!). | on the type | | | | Must be within range. | | | +---------------+------------------------+------------------+----------------+ | ``char`` | a string of length 1 | a string of | int() | @@ -1313,11 +1314,6 @@ | union | same as struct, but | | read/write | | | with at most one field | | fields | +---------------+------------------------+------------------+----------------+ -| enum | an integer, or the enum| the enum value | int() | -| | value as a string or | as a string, or | | -| | as ``"#NUMBER"`` | ``"#NUMBER"`` | | -| | | if out of range | | -+---------------+------------------------+------------------+----------------+ .. versionchanged:: 0.3 `(*)` Note that when calling a function, as per C, a ``item *`` argument @@ -1349,6 +1345,14 @@ without any precision loss, you need to define and use a family of C functions like ``long double add(long double a, long double b);``. +.. versionchanged:: 0.6 + `(*****)` Enums are now handled like ints. In previous versions, + you would get the enum's value as a string. Now we follow the C + convention and treat them as really equivalent to ints. To compare + their value symbolically, use code like ``if x.field == lib.FOO``. + If you really want to get their value as a string, use + ``ffi.string(ffi.cast("the_enum_type", x.field))``. + Reference: verifier ------------------- From noreply at buildbot.pypy.org Sun Feb 10 19:09:49 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sun, 10 Feb 2013 19:09:49 +0100 (CET) Subject: [pypy-commit] cffi auto-types: Playing with the idea of declaring common types more automatically, Message-ID: <20130210180949.DC7391C004F@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: auto-types Changeset: r1141:57fd9e0b796d Date: 2013-02-10 18:08 +0100 http://bitbucket.org/cffi/cffi/changeset/57fd9e0b796d/ Log: Playing with the idea of declaring common types more automatically, but only as long as the cdef code doesn't declare them too. From noreply at buildbot.pypy.org Sun Feb 10 19:09:51 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sun, 10 Feb 2013 19:09:51 +0100 (CET) Subject: [pypy-commit] cffi auto-types: Implementation Message-ID: <20130210180951.0F4881C03D5@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: auto-types Changeset: r1142:ee2c2a732000 Date: 2013-02-10 18:52 +0100 http://bitbucket.org/cffi/cffi/changeset/ee2c2a732000/ Log: Implementation diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c --- a/c/_cffi_backend.c +++ b/c/_cffi_backend.c @@ -3214,7 +3214,7 @@ return NULL; flag = CT_STRUCT; - if (strcmp(name, "_IO_FILE") == 0) + if (strcmp(name, "_IO_FILE") == 0 || strcmp(name, "$FILE") == 0) flag |= CT_IS_FILE; return _b_struct_or_union_type("struct", name, flag); } diff --git a/c/test_c.py b/c/test_c.py --- a/c/test_c.py +++ b/c/test_c.py @@ -2505,7 +2505,7 @@ if sys.platform == "win32": py.test.skip("testing FILE not implemented") # - BFILE = new_struct_type("_IO_FILE") + BFILE = new_struct_type("$FILE") BFILEP = new_pointer_type(BFILE) BChar = new_primitive_type("char") BCharP = new_pointer_type(BChar) diff --git a/cffi/api.py b/cffi/api.py --- a/cffi/api.py +++ b/cffi/api.py @@ -71,7 +71,6 @@ if name.startswith('RTLD_'): setattr(self, name, getattr(backend, name)) # - self._parser._declarations['typedef FILE'] = model.file_type BVoidP = self._get_cached_btype(model.voidp_type) if isinstance(backend, types.ModuleType): # _cffi_backend: attach these constants to the class diff --git a/cffi/cparser.py b/cffi/cparser.py --- a/cffi/cparser.py +++ b/cffi/cparser.py @@ -1,5 +1,6 @@ from . import api, model +from .commontypes import COMMON_TYPES import pycparser.c_parser, weakref, re, sys try: @@ -17,6 +18,7 @@ _r_partial_enum = re.compile(r"=\s*\.\.\.\s*[,}]|\.\.\.\s*\}") _r_enum_dotdotdot = re.compile(r"__dotdotdot\d+__$") _r_partial_array = re.compile(r"\[\s*\.\.\.\s*\]") +_r_words = re.compile(r"\w+|\S") _parser_cache = None def _get_parser(): @@ -58,10 +60,34 @@ # which is declared with a typedef for the purpose of C parsing. return csource.replace('...', ' __dotdotdot__ '), macros +def _common_type_names(csource): + # Look in the source for what looks like usages of types from the + # list of common types. A "usage" is approximated here as the + # appearance of the word, minus a "definition" of the type, which + # is the last word in a "typedef" statement. Approximative only + # but should be fine for all the common types. + look_for_words = set(COMMON_TYPES) + look_for_words.add(';') + look_for_words.add('typedef') + words_used = set() + is_typedef = False + previous_word = '' + for word in _r_words.findall(csource): + if word in look_for_words: + if word == ';': + if is_typedef: + words_used.discard(previous_word) + look_for_words.discard(previous_word) + is_typedef = False + elif word == 'typedef': + is_typedef = True + else: # word in COMMON_TYPES + words_used.add(word) + previous_word = word + return words_used + + class Parser(object): - TYPEDEFS = sorted( - [_name for _name in model.PrimitiveType.ALL_PRIMITIVE_TYPES - if _name.endswith('_t')]) def __init__(self): self._declarations = {} @@ -70,17 +96,23 @@ self._override = False def _parse(self, csource): + csource, macros = _preprocess(csource) # XXX: for more efficiency we would need to poke into the # internals of CParser... the following registers the # typedefs, because their presence or absence influences the # parsing itself (but what they are typedef'ed to plays no role) - typenames = self.TYPEDEFS[:] + ctn = _common_type_names(csource) + print `csource`, ctn + typenames = [] for name in sorted(self._declarations): if name.startswith('typedef '): - typenames.append(name[8:]) + name = name[8:] + typenames.append(name) + ctn.discard(name) + typenames += sorted(ctn) + # csourcelines = ['typedef int %s;' % typename for typename in typenames] csourcelines.append('typedef int __dotdotdot__;') - csource, macros = _preprocess(csource) csourcelines.append(csource) csource = '\n'.join(csourcelines) if lock is not None: @@ -267,6 +299,8 @@ return model.void_type if ident == '__dotdotdot__': raise api.FFIError('bad usage of "..."') + if ident in COMMON_TYPES: + return COMMON_TYPES[ident] return model.PrimitiveType(ident) # if isinstance(type, pycparser.c_ast.Struct): diff --git a/cffi/model.py b/cffi/model.py --- a/cffi/model.py +++ b/cffi/model.py @@ -73,9 +73,9 @@ 'float': 'f', 'double': 'f', 'long double': 'f', - 'wchar_t': 'c', '_Bool': 'u', # the following types are not primitive in the C sense + 'wchar_t': 'c', 'int8_t': 'i', 'uint8_t': 'u', 'int16_t': 'i', diff --git a/testing/test_parsing.py b/testing/test_parsing.py --- a/testing/test_parsing.py +++ b/testing/test_parsing.py @@ -208,3 +208,10 @@ assert str(e.value).startswith('cannot parse "foobarbazunknown*"') e = py.test.raises(CDefError, ffi.cast, "int(*)(foobarbazunknown)", 0) assert str(e.value).startswith('cannot parse "int(*)(foobarbazunknown)"') + +def test_redefine_common_type(): + ffi = FFI() + ffi.cdef("typedef char FILE;") + assert repr(ffi.cast("FILE", 123)) == "" + ffi.cdef("typedef char int32_t;") + assert repr(ffi.cast("int32_t", 123)) == "" From noreply at buildbot.pypy.org Sun Feb 10 20:12:16 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sun, 10 Feb 2013 20:12:16 +0100 (CET) Subject: [pypy-commit] cffi auto-types: Add all standard Windows types (as per a list from some official-looking Message-ID: <20130210191216.AC7E61C03D5@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: auto-types Changeset: r1144:34f7feebf13d Date: 2013-02-10 20:11 +0100 http://bitbucket.org/cffi/cffi/changeset/34f7feebf13d/ Log: Add all standard Windows types (as per a list from some official- looking page of the MS site). diff --git a/cffi/commontypes.py b/cffi/commontypes.py --- a/cffi/commontypes.py +++ b/cffi/commontypes.py @@ -1,12 +1,246 @@ +import sys from . import api, model COMMON_TYPES = { 'FILE': model.unknown_type('FILE', '_IO_FILE'), - 'bool': model.PrimitiveType('_Bool'), + 'bool': '_Bool', } for _type in model.PrimitiveType.ALL_PRIMITIVE_TYPES: if _type.endswith('_t'): - COMMON_TYPES[_type] = model.PrimitiveType(_type) + COMMON_TYPES[_type] = _type del _type + +_CACHE = {} + +def resolve_common_type(commontype): + try: + return _CACHE[commontype] + except KeyError: + result = COMMON_TYPES.get(commontype, commontype) + if not isinstance(result, str): + pass # result is already a BaseType + elif result.endswith(' *'): + if result.startswith('const '): + result = model.ConstPointerType( + resolve_common_type(result[6:-2])) + else: + result = model.PointerType(resolve_common_type(result[:-2])) + elif result in model.PrimitiveType.ALL_PRIMITIVE_TYPES: + result = model.PrimitiveType(result) + else: + assert commontype != result + result = resolve_common_type(result) # recursively + assert isinstance(result, model.BaseTypeByIdentity) + _CACHE[commontype] = result + return result + + +# ____________________________________________________________ +# Windows common types + + +def win_common_types(maxsize): + result = {} + if maxsize < (1<<32): + result.update({ # Windows 32-bits + 'HALF_PTR': 'short', + 'INT_PTR': 'int', + 'LONG_PTR': 'long', + 'UHALF_PTR': 'unsigned short', + 'UINT_PTR': 'unsigned int', + 'ULONG_PTR': 'unsigned long', + }) + else: + result.update({ # Windows 64-bits + 'HALF_PTR': 'int', + 'INT_PTR': 'long long', + 'LONG_PTR': 'long long', + 'UHALF_PTR': 'unsigned int', + 'UINT_PTR': 'unsigned long long', + 'ULONG_PTR': 'unsigned long long', + }) + result.update({ + "BYTE": "unsigned char", + "BOOL": "int", + "CCHAR": "char", + "CHAR": "char", + "DWORD": "unsigned long", + "DWORD32": "unsigned int", + "DWORD64": "unsigned long long", + "FLOAT": "float", + "INT": "int", + "INT8": "signed char", + "INT16": "short", + "INT32": "int", + "INT64": "long long", + "LONG": "long", + "LONGLONG": "long long", + "LONG32": "int", + "LONG64": "long long", + "WORD": "unsigned short", + "PVOID": model.voidp_type, + "ULONGLONG": "unsigned long long", + "WCHAR": "wchar_t", + "SHORT": "short", + "TBYTE": "WCHAR", + "TCHAR": "WCHAR", + "UCHAR": "unsigned char", + "UINT": "unsigned int", + "UINT8": "unsigned char", + "UINT16": "unsigned short", + "UINT32": "unsigned int", + "UINT64": "unsigned long long", + "ULONG": "unsigned long", + "ULONG32": "unsigned int", + "ULONG64": "unsigned long long", + "USHORT": "unsigned short", + + "SIZE_T": "ULONG_PTR", + "SSIZE_T": "LONG_PTR", + "ATOM": "WORD", + "BOOLEAN": "BYTE", + "COLORREF": "DWORD", + + "HANDLE": "PVOID", + "DWORDLONG": "ULONGLONG", + "DWORD_PTR": "ULONG_PTR", + "HACCEL": "HANDLE", + + "HBITMAP": "HANDLE", + "HBRUSH": "HANDLE", + "HCOLORSPACE": "HANDLE", + "HCONV": "HANDLE", + "HCONVLIST": "HANDLE", + "HDC": "HANDLE", + "HDDEDATA": "HANDLE", + "HDESK": "HANDLE", + "HDROP": "HANDLE", + "HDWP": "HANDLE", + "HENHMETAFILE": "HANDLE", + "HFILE": "int", + "HFONT": "HANDLE", + "HGDIOBJ": "HANDLE", + "HGLOBAL": "HANDLE", + "HHOOK": "HANDLE", + "HICON": "HANDLE", + "HCURSOR": "HICON", + "HINSTANCE": "HANDLE", + "HKEY": "HANDLE", + "HKL": "HANDLE", + "HLOCAL": "HANDLE", + "HMENU": "HANDLE", + "HMETAFILE": "HANDLE", + "HMODULE": "HINSTANCE", + "HMONITOR": "HANDLE", + "HPALETTE": "HANDLE", + "HPEN": "HANDLE", + "HRESULT": "LONG", + "HRGN": "HANDLE", + "HRSRC": "HANDLE", + "HSZ": "HANDLE", + "WINSTA": "HANDLE", + "HWND": "HANDLE", + + "LANGID": "WORD", + "LCID": "DWORD", + "LCTYPE": "DWORD", + "LGRPID": "DWORD", + "LPARAM": "LONG_PTR", + "LPBOOL": "BOOL *", + "LPBYTE": "BYTE *", + "LPCOLORREF": "DWORD *", + "LPCSTR": "const char *", + + "LPCVOID": model.const_voidp_type, + "LPCWSTR": "const WCHAR *", + "LPCTSTR": "LPCWSTR", + "LPDWORD": "DWORD *", + "LPHANDLE": "HANDLE *", + "LPINT": "int *", + "LPLONG": "long *", + "LPSTR": "CHAR *", + "LPWSTR": "WCHAR *", + "LPTSTR": "LPWSTR", + "LPVOID": model.voidp_type, + "LPWORD": "WORD *", + "LRESULT": "LONG_PTR", + "PBOOL": "BOOL *", + "PBOOLEAN": "BOOLEAN *", + "PBYTE": "BYTE *", + "PCHAR": "CHAR *", + "PCSTR": "const CHAR *", + "PCTSTR": "LPCWSTR", + "PCWSTR": "const WCHAR *", + "PDWORD": "DWORD *", + "PDWORDLONG": "DWORDLONG *", + "PDWORD_PTR": "DWORD_PTR *", + "PDWORD32": "DWORD32 *", + "PDWORD64": "DWORD64 *", + "PFLOAT": "FLOAT *", + "PHALF_PTR": "HALF_PTR *", + "PHANDLE": "HANDLE *", + "PHKEY": "HKEY *", + "PINT": "int *", + "PINT_PTR": "INT_PTR *", + "PINT8": "INT8 *", + "PINT16": "INT16 *", + "PINT32": "INT32 *", + "PINT64": "INT64 *", + "PLCID": "PDWORD", + "PLONG": "LONG *", + "PLONGLONG": "LONGLONG *", + "PLONG_PTR": "LONG_PTR *", + "PLONG32": "LONG32 *", + "PLONG64": "LONG64 *", + "PSHORT": "SHORT *", + "PSIZE_T": "SIZE_T *", + "PSSIZE_T": "SSIZE_T *", + "PSTR": "CHAR *", + "PTBYTE": "TBYTE *", + "PTCHAR": "TCHAR *", + "PTSTR": "LPWSTR", + "PUCHAR": "UCHAR *", + "PUHALF_PTR": "UHALF_PTR *", + "PUINT": "UINT *", + "PUINT_PTR": "UINT_PTR *", + "PUINT8": "UINT8 *", + "PUINT16": "UINT16 *", + "PUINT32": "UINT32 *", + "PUINT64": "UINT64 *", + "PULONG": "ULONG *", + "PULONGLONG": "ULONGLONG *", + "PULONG_PTR": "ULONG_PTR *", + "PULONG32": "ULONG32 *", + "PULONG64": "ULONG64 *", + "PUSHORT": "USHORT *", + "PWCHAR": "WCHAR *", + "PWORD": "WORD *", + "PWSTR": "WCHAR *", + "QWORD": "unsigned long long", + "SC_HANDLE": "HANDLE", + "SC_LOCK": "LPVOID", + "SERVICE_STATUS_HANDLE": "HANDLE", + + "UNICODE_STRING": model.StructType( + "_UNICODE_STRING", + ["Length", + "MaximumLength", + "Buffer"], + [model.PrimitiveType("unsigned short"), + model.PrimitiveType("unsigned short"), + model.PointerType(model.PrimitiveType("wchar_t"))], + [-1, -1, -1]), + "PUNICODE_STRING": "UNICODE_STRING *", + "PCUNICODE_STRING": "const UNICODE_STRING *", + + "USN": "LONGLONG", + "VOID": model.void_type, + "WPARAM": "UINT_PTR", + }) + return result + + +if sys.platform == 'win32': + COMMON_TYPES.update(win_common_types(sys.maxsize)) diff --git a/cffi/cparser.py b/cffi/cparser.py --- a/cffi/cparser.py +++ b/cffi/cparser.py @@ -1,6 +1,6 @@ from . import api, model -from .commontypes import COMMON_TYPES +from .commontypes import COMMON_TYPES, resolve_common_type import pycparser.c_parser, weakref, re, sys try: @@ -299,9 +299,7 @@ return model.void_type if ident == '__dotdotdot__': raise api.FFIError('bad usage of "..."') - if ident in COMMON_TYPES: - return COMMON_TYPES[ident] - return model.PrimitiveType(ident) + return resolve_common_type(ident) # if isinstance(type, pycparser.c_ast.Struct): # 'struct foobar' diff --git a/cffi/model.py b/cffi/model.py --- a/cffi/model.py +++ b/cffi/model.py @@ -183,6 +183,8 @@ BPtr = PointerType(self.totype).get_cached_btype(ffi, finishlist) return BPtr +const_voidp_type = ConstPointerType(void_type) + class NamedPointerType(PointerType): _attrs_ = ('totype', 'name') diff --git a/testing/test_parsing.py b/testing/test_parsing.py --- a/testing/test_parsing.py +++ b/testing/test_parsing.py @@ -222,3 +222,35 @@ # ffi = FFI() ffi.cdef("typedef _Bool bool; void f(bool);") + +def test_win_common_types(): + from cffi.commontypes import COMMON_TYPES, _CACHE + from cffi.commontypes import win_common_types, resolve_common_type + # + def clear_all(extra={}, old_dict=COMMON_TYPES.copy()): + COMMON_TYPES.clear() + COMMON_TYPES.update(old_dict) + COMMON_TYPES.update(extra) + _CACHE.clear() + # + for maxsize in [2**32-1, 2**64-1]: + ct = win_common_types(maxsize) + clear_all(ct) + for key in sorted(ct): + resolve_common_type(key) + # assert did not crash + # now try to use e.g. WPARAM (-> UINT_PTR -> unsigned 32/64-bit) + for maxsize in [2**32-1, 2**64-1]: + ct = win_common_types(maxsize) + clear_all(ct) + ffi = FFI() + value = int(ffi.cast("WPARAM", -1)) + assert value == maxsize + # + clear_all() + +def test_WPARAM_on_windows(): + if sys.platform != 'win32': + py.test.skip("Only for Windows") + ffi = FFI() + ffi.cdef("void f(WPARAM);") From noreply at buildbot.pypy.org Sun Feb 10 20:12:15 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sun, 10 Feb 2013 20:12:15 +0100 (CET) Subject: [pypy-commit] cffi auto-types: - add missing file Message-ID: <20130210191215.912B31C004F@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: auto-types Changeset: r1143:a059934a26e2 Date: 2013-02-10 19:12 +0100 http://bitbucket.org/cffi/cffi/changeset/a059934a26e2/ Log: - add missing file - add 'bool' support diff --git a/cffi/commontypes.py b/cffi/commontypes.py new file mode 100644 --- /dev/null +++ b/cffi/commontypes.py @@ -0,0 +1,12 @@ +from . import api, model + + +COMMON_TYPES = { + 'FILE': model.unknown_type('FILE', '_IO_FILE'), + 'bool': model.PrimitiveType('_Bool'), + } + +for _type in model.PrimitiveType.ALL_PRIMITIVE_TYPES: + if _type.endswith('_t'): + COMMON_TYPES[_type] = model.PrimitiveType(_type) +del _type diff --git a/cffi/model.py b/cffi/model.py --- a/cffi/model.py +++ b/cffi/model.py @@ -383,8 +383,6 @@ tp = StructType(structname, None, None, None) return NamedPointerType(tp, name) -file_type = unknown_type('FILE', '_IO_FILE') - def global_cache(srctype, ffi, funcname, *args, **kwds): key = kwds.pop('key', (funcname, args)) assert not kwds diff --git a/testing/test_parsing.py b/testing/test_parsing.py --- a/testing/test_parsing.py +++ b/testing/test_parsing.py @@ -215,3 +215,10 @@ assert repr(ffi.cast("FILE", 123)) == "" ffi.cdef("typedef char int32_t;") assert repr(ffi.cast("int32_t", 123)) == "" + +def test_bool(): + ffi = FFI() + ffi.cdef("void f(bool);") + # + ffi = FFI() + ffi.cdef("typedef _Bool bool; void f(bool);") From noreply at buildbot.pypy.org Sun Feb 10 20:52:12 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sun, 10 Feb 2013 20:52:12 +0100 (CET) Subject: [pypy-commit] cffi auto-types: Document Message-ID: <20130210195212.A33E81C004F@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: auto-types Changeset: r1145:0c6eccf9f424 Date: 2013-02-10 20:51 +0100 http://bitbucket.org/cffi/cffi/changeset/0c6eccf9f424/ Log: Document diff --git a/doc/source/index.rst b/doc/source/index.rst --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -390,25 +390,39 @@ * wchar_t (if supported by the backend) * *New in version 0.4:* _Bool. If not directly supported by the C compiler, - this is declared with the size of ``unsigned char``. Note that the - effects of ```` are not automatically included: you have - to say ``typedef _Bool bool;`` in your ``cdef()`` if you want to - use this ``_Bool`` with the more standard name ``bool``. This is because - some headers declare a different type (e.g. an enum) and also call it - ``bool``. + this is declared with the size of ``unsigned char``. + +* *New in version 0.6:* bool. In CFFI 0.4 or 0.5, you had to manually say + ``typedef _Bool bool;``. Now such a line is optional. * *New in version 0.4:* FILE. You can declare C functions taking a ``FILE *`` argument and call them with a Python file object. If needed, you can also do ``c_f = ffi.cast("FILE *", fileobj)`` and then pass around ``c_f``. -.. "versionadded:: 0.4": bool +* *New in version 0.6:* all `common Windows types`_ are defined if you run + on Windows (``DWORD``, ``LPARAM``, etc.). + +.. _`common Windows types`: http://msdn.microsoft.com/en-us/library/windows/desktop/aa383751%28v=vs.85%29.aspx + +.. "versionadded:: 0.4": _Bool +.. "versionadded:: 0.6": bool .. "versionadded:: 0.4": FILE +.. "versionadded:: 0.6": Wintypes As we will see on `the verification step`_ below, the declarations can also contain "``...``" at various places; these are placeholders that will be completed by a call to ``verify()``. +.. versionadded:: 0.6 + The standard type names listed above are now handled as *defaults* + only (apart from the ones that are keywords in the C language). + If your ``cdef`` contains an explicit typedef that redefines one of + the types above, then the default described above is ignored. (This + is a bit hard to implement cleanly, so in some corner cases it might + fail, notably with the error ``Multiple type specifiers with a type + tag``. Please report it as a bug if it does.) + Loading libraries ----------------- From noreply at buildbot.pypy.org Sun Feb 10 22:55:23 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sun, 10 Feb 2013 22:55:23 +0100 (CET) Subject: [pypy-commit] pypy default: kill this old unused flag Message-ID: <20130210215523.8F7411C03D5@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61049:daff78b35e66 Date: 2013-02-10 16:10 -0500 http://bitbucket.org/pypy/pypy/changeset/daff78b35e66/ Log: kill this old unused flag diff --git a/pypy/interpreter/app_main.py b/pypy/interpreter/app_main.py --- a/pypy/interpreter/app_main.py +++ b/pypy/interpreter/app_main.py @@ -310,8 +310,6 @@ "warnoptions", "unbuffered"), 0) -PYTHON26 = True - def simple_option(options, name, iterargv): options[name] += 1 @@ -341,38 +339,34 @@ cmdline_options = { # simple options just increment the counter of the options listed above + 'b': (simple_option, 'bytes_warning'), + 'B': (simple_option, 'dont_write_bytecode'), 'd': (simple_option, 'debug'), + 'E': (simple_option, 'ignore_environment'), 'i': (simple_option, 'interactive'), 'O': (simple_option, 'optimize'), + 'R': (simple_option, 'hash_randomization'), + 's': (simple_option, 'no_user_site'), 'S': (simple_option, 'no_site'), - 'E': (simple_option, 'ignore_environment'), 't': (simple_option, 'tabcheck'), - 'v': (simple_option, 'verbose'), 'U': (simple_option, 'unicode'), 'u': (simple_option, 'unbuffered'), + 'v': (simple_option, 'verbose'), + '3': (simple_option, 'py3k_warning'), # more complex options - 'Q': (div_option, Ellipsis), 'c': (c_option, Ellipsis), + 'h': (print_help, None), + '--help': (print_help, None), 'm': (m_option, Ellipsis), 'W': (W_option, Ellipsis), 'V': (print_version, None), '--version': (print_version, None), + 'Q': (div_option, Ellipsis), '--info': (print_info, None), - 'h': (print_help, None), - '--help': (print_help, None), '--jit': (set_jit_option, Ellipsis), '--': (end_options, None), } -if PYTHON26: - cmdline_options.update({ - '3': (simple_option, 'py3k_warning'), - 'B': (simple_option, 'dont_write_bytecode'), - 's': (simple_option, 'no_user_site'), - 'b': (simple_option, 'bytes_warning'), - 'R': (simple_option, 'hash_randomization'), - }) - def handle_argument(c, options, iterargv, iterarg=iter(())): function, funcarg = cmdline_options[c] @@ -434,11 +428,10 @@ if not options["ignore_environment"]: if os.getenv('PYTHONUNBUFFERED'): options["unbuffered"] = 1 - if PYTHON26: - if os.getenv('PYTHONNOUSERSITE'): - options["no_user_site"] = 1 - if os.getenv('PYTHONDONTWRITEBYTECODE'): - options["dont_write_bytecode"] = 1 + if os.getenv('PYTHONNOUSERSITE'): + options["no_user_site"] = 1 + if os.getenv('PYTHONDONTWRITEBYTECODE'): + options["dont_write_bytecode"] = 1 if (options["interactive"] or (not options["ignore_environment"] and os.getenv('PYTHONINSPECT'))): @@ -450,7 +443,7 @@ ## print >> sys.stderr, ( ## "Warning: pypy does not implement hash randomization") - if PYTHON26 and we_are_translated(): + if we_are_translated(): flags = [options[flag] for flag in sys_flags] sys.flags = type(sys.flags)(flags) sys.py3kwarning = bool(sys.flags.py3k_warning) From noreply at buildbot.pypy.org Sun Feb 10 22:55:24 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sun, 10 Feb 2013 22:55:24 +0100 (CET) Subject: [pypy-commit] pypy default: support testing env values passed to app_main, test supported vars Message-ID: <20130210215524.D2DC91C03D5@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61050:b36eaca14928 Date: 2013-02-10 16:48 -0500 http://bitbucket.org/pypy/pypy/changeset/b36eaca14928/ Log: support testing env values passed to app_main, test supported vars diff --git a/pypy/interpreter/test2/test_app_main.py b/pypy/interpreter/test2/test_app_main.py --- a/pypy/interpreter/test2/test_app_main.py +++ b/pypy/interpreter/test2/test_app_main.py @@ -81,14 +81,16 @@ assert not value, ( "option %r has unexpectedly the value %r" % (key, value)) - def check(self, argv, **expected): + def check(self, argv, env, **expected): import StringIO from pypy.interpreter import app_main + saved_env = os.environ.copy() saved_sys_argv = sys.argv[:] saved_sys_stdout = sys.stdout saved_sys_stderr = sys.stdout app_main.os = os try: + os.environ.update(env) sys.stdout = sys.stderr = StringIO.StringIO() try: options = app_main.parse_command_line(argv) @@ -98,64 +100,70 @@ else: self.check_options(options, **expected) finally: + os.environ.clear() + os.environ.update(saved_env) sys.argv[:] = saved_sys_argv sys.stdout = saved_sys_stdout sys.stderr = saved_sys_stderr def test_all_combinations_I_can_think_of(self): - self.check([], sys_argv=[''], run_stdin=True) - self.check(['-'], sys_argv=['-'], run_stdin=True) - self.check(['-S'], sys_argv=[''], run_stdin=True, no_site=1) - self.check(['-OO'], sys_argv=[''], run_stdin=True, optimize=2) - self.check(['-O', '-O'], sys_argv=[''], run_stdin=True, optimize=2) - self.check(['-Qnew'], sys_argv=[''], run_stdin=True, division_new=1) - self.check(['-Qold'], sys_argv=[''], run_stdin=True, division_new=0) - self.check(['-Qwarn'], sys_argv=[''], run_stdin=True, division_warning=1) - self.check(['-Qwarnall'], sys_argv=[''], run_stdin=True, + self.check([], {}, sys_argv=[''], run_stdin=True) + self.check(['-'], {}, sys_argv=['-'], run_stdin=True) + self.check(['-S'], {}, sys_argv=[''], run_stdin=True, no_site=1) + self.check(['-OO'], {}, sys_argv=[''], run_stdin=True, optimize=2) + self.check(['-O', '-O'], {}, sys_argv=[''], run_stdin=True, optimize=2) + self.check(['-Qnew'], {}, sys_argv=[''], run_stdin=True, division_new=1) + self.check(['-Qold'], {}, sys_argv=[''], run_stdin=True, division_new=0) + self.check(['-Qwarn'], {}, sys_argv=[''], run_stdin=True, division_warning=1) + self.check(['-Qwarnall'], {}, sys_argv=[''], run_stdin=True, division_warning=2) - self.check(['-Q', 'new'], sys_argv=[''], run_stdin=True, division_new=1) - self.check(['-SOQnew'], sys_argv=[''], run_stdin=True, + self.check(['-Q', 'new'], {}, sys_argv=[''], run_stdin=True, division_new=1) + self.check(['-SOQnew'], {}, sys_argv=[''], run_stdin=True, no_site=1, optimize=1, division_new=1) - self.check(['-SOQ', 'new'], sys_argv=[''], run_stdin=True, + self.check(['-SOQ', 'new'], {}, sys_argv=[''], run_stdin=True, no_site=1, optimize=1, division_new=1) - self.check(['-i'], sys_argv=[''], run_stdin=True, + self.check(['-i'], {}, sys_argv=[''], run_stdin=True, interactive=1, inspect=1) - self.check(['-h'], output_contains='usage:') - self.check(['-S', '-tO', '-h'], output_contains='usage:') - self.check(['-S', '-thO'], output_contains='usage:') - self.check(['-S', '-tO', '--help'], output_contains='usage:') - self.check(['-S', '-tO', '--info'], output_contains='translation') - self.check(['-S', '-tO', '--version'], output_contains='Python') - self.check(['-S', '-tOV'], output_contains='Python') - self.check(['--jit', 'foobar', '-S'], sys_argv=[''], + self.check(['-h'], {}, output_contains='usage:') + self.check(['-S', '-tO', '-h'], {}, output_contains='usage:') + self.check(['-S', '-thO'], {}, output_contains='usage:') + self.check(['-S', '-tO', '--help'], {}, output_contains='usage:') + self.check(['-S', '-tO', '--info'], {}, output_contains='translation') + self.check(['-S', '-tO', '--version'], {}, output_contains='Python') + self.check(['-S', '-tOV'], {}, output_contains='Python') + self.check(['--jit', 'foobar', '-S'], {}, sys_argv=[''], run_stdin=True, no_site=1) - self.check(['-c', 'pass'], sys_argv=['-c'], run_command='pass') - self.check(['-cpass'], sys_argv=['-c'], run_command='pass') - self.check(['-cpass','x'], sys_argv=['-c','x'], run_command='pass') - self.check(['-Sc', 'pass'], sys_argv=['-c'], run_command='pass', + self.check(['-c', 'pass'], {}, sys_argv=['-c'], run_command='pass') + self.check(['-cpass'], {}, sys_argv=['-c'], run_command='pass') + self.check(['-cpass','x'], {}, sys_argv=['-c','x'], run_command='pass') + self.check(['-Sc', 'pass'], {}, sys_argv=['-c'], run_command='pass', no_site=1) - self.check(['-Scpass'], sys_argv=['-c'], run_command='pass', no_site=1) - self.check(['-c', '', ''], sys_argv=['-c', ''], run_command='') - self.check(['-mfoo', 'bar', 'baz'], sys_argv=['foo', 'bar', 'baz'], + self.check(['-Scpass'], {}, sys_argv=['-c'], run_command='pass', no_site=1) + self.check(['-c', '', ''], {}, sys_argv=['-c', ''], run_command='') + self.check(['-mfoo', 'bar', 'baz'], {}, sys_argv=['foo', 'bar', 'baz'], run_module=True) - self.check(['-m', 'foo', 'bar', 'baz'], sys_argv=['foo', 'bar', 'baz'], + self.check(['-m', 'foo', 'bar', 'baz'], {}, sys_argv=['foo', 'bar', 'baz'], run_module=True) - self.check(['-Smfoo', 'bar', 'baz'], sys_argv=['foo', 'bar', 'baz'], + self.check(['-Smfoo', 'bar', 'baz'], {}, sys_argv=['foo', 'bar', 'baz'], run_module=True, no_site=1) - self.check(['-Sm', 'foo', 'bar', 'baz'], sys_argv=['foo', 'bar', 'baz'], + self.check(['-Sm', 'foo', 'bar', 'baz'], {}, sys_argv=['foo', 'bar', 'baz'], run_module=True, no_site=1) - self.check(['-', 'foo', 'bar'], sys_argv=['-', 'foo', 'bar'], + self.check(['-', 'foo', 'bar'], {}, sys_argv=['-', 'foo', 'bar'], run_stdin=True) - self.check(['foo', 'bar'], sys_argv=['foo', 'bar']) - self.check(['foo', '-i'], sys_argv=['foo', '-i']) - self.check(['-i', 'foo'], sys_argv=['foo'], interactive=1, inspect=1) - self.check(['--', 'foo'], sys_argv=['foo']) - self.check(['--', '-i', 'foo'], sys_argv=['-i', 'foo']) - self.check(['--', '-', 'foo'], sys_argv=['-', 'foo'], run_stdin=True) - self.check(['-Wbog'], sys_argv=[''], warnoptions=['bog'], run_stdin=True) - self.check(['-W', 'ab', '-SWc'], sys_argv=[''], warnoptions=['ab', 'c'], + self.check(['foo', 'bar'], {}, sys_argv=['foo', 'bar']) + self.check(['foo', '-i'], {}, sys_argv=['foo', '-i']) + self.check(['-i', 'foo'], {}, sys_argv=['foo'], interactive=1, inspect=1) + self.check(['--', 'foo'], {}, sys_argv=['foo']) + self.check(['--', '-i', 'foo'], {}, sys_argv=['-i', 'foo']) + self.check(['--', '-', 'foo'], {}, sys_argv=['-', 'foo'], run_stdin=True) + self.check(['-Wbog'], {}, sys_argv=[''], warnoptions=['bog'], run_stdin=True) + self.check(['-W', 'ab', '-SWc'], {}, sys_argv=[''], warnoptions=['ab', 'c'], run_stdin=True, no_site=1) + self.check([], {'PYTHONUNBUFFERED': '1'}, sys_argv=[''], run_stdin=True, unbuffered=1) + self.check([], {'PYTHONNOUSERSITE': '1'}, sys_argv=[''], run_stdin=True, no_user_site=1) + self.check([], {'PYTHONDONTWRITEBYTECODE': '1'}, sys_argv=[''], run_stdin=True, dont_write_bytecode=1) + def test_sysflags(self): flags = ( ("debug", "-d", "1"), @@ -183,13 +191,13 @@ expected[flag1] = int(value) else: expected = {flag: int(value)} - self.check([opt, '-c', 'pass'], sys_argv=['-c'], + self.check([opt, '-c', 'pass'], {}, sys_argv=['-c'], run_command='pass', **expected) def test_sysflags_envvar(self, monkeypatch): monkeypatch.setenv('PYTHONNOUSERSITE', '1') expected = {"no_user_site": True} - self.check(['-c', 'pass'], sys_argv=['-c'], run_command='pass', **expected) + self.check(['-c', 'pass'], {}, sys_argv=['-c'], run_command='pass', **expected) class TestInteraction: From noreply at buildbot.pypy.org Sun Feb 10 22:55:26 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sun, 10 Feb 2013 22:55:26 +0100 (CET) Subject: [pypy-commit] pypy default: app_main support a few more args/env vars Message-ID: <20130210215526.16EAB1C03D5@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61051:a4cde53c1b7e Date: 2013-02-10 16:54 -0500 http://bitbucket.org/pypy/pypy/changeset/a4cde53c1b7e/ Log: app_main support a few more args/env vars diff --git a/pypy/interpreter/app_main.py b/pypy/interpreter/app_main.py --- a/pypy/interpreter/app_main.py +++ b/pypy/interpreter/app_main.py @@ -355,6 +355,7 @@ '3': (simple_option, 'py3k_warning'), # more complex options 'c': (c_option, Ellipsis), + '?': (print_help, None), 'h': (print_help, None), '--help': (print_help, None), 'm': (m_option, Ellipsis), @@ -426,12 +427,16 @@ sys.argv[:] = argv if not options["ignore_environment"]: + if os.getenv('PYTHONDEBUG'): + options["debug"] = 1 + if os.getenv('PYTHONDONTWRITEBYTECODE'): + options["dont_write_bytecode"] = 1 + if os.getenv('PYTHONNOUSERSITE'): + options["no_user_site"] = 1 if os.getenv('PYTHONUNBUFFERED'): options["unbuffered"] = 1 - if os.getenv('PYTHONNOUSERSITE'): - options["no_user_site"] = 1 - if os.getenv('PYTHONDONTWRITEBYTECODE'): - options["dont_write_bytecode"] = 1 + if os.getenv('PYTHONVERBOSE'): + options["verbose"] = 1 if (options["interactive"] or (not options["ignore_environment"] and os.getenv('PYTHONINSPECT'))): diff --git a/pypy/interpreter/test2/test_app_main.py b/pypy/interpreter/test2/test_app_main.py --- a/pypy/interpreter/test2/test_app_main.py +++ b/pypy/interpreter/test2/test_app_main.py @@ -124,6 +124,7 @@ no_site=1, optimize=1, division_new=1) self.check(['-i'], {}, sys_argv=[''], run_stdin=True, interactive=1, inspect=1) + self.check(['-?'], {}, output_contains='usage:') self.check(['-h'], {}, output_contains='usage:') self.check(['-S', '-tO', '-h'], {}, output_contains='usage:') self.check(['-S', '-thO'], {}, output_contains='usage:') @@ -160,9 +161,11 @@ self.check(['-W', 'ab', '-SWc'], {}, sys_argv=[''], warnoptions=['ab', 'c'], run_stdin=True, no_site=1) + self.check([], {'PYTHONDEBUG': '1'}, sys_argv=[''], run_stdin=True, debug=1) + self.check([], {'PYTHONDONTWRITEBYTECODE': '1'}, sys_argv=[''], run_stdin=True, dont_write_bytecode=1) + self.check([], {'PYTHONNOUSERSITE': '1'}, sys_argv=[''], run_stdin=True, no_user_site=1) self.check([], {'PYTHONUNBUFFERED': '1'}, sys_argv=[''], run_stdin=True, unbuffered=1) - self.check([], {'PYTHONNOUSERSITE': '1'}, sys_argv=[''], run_stdin=True, no_user_site=1) - self.check([], {'PYTHONDONTWRITEBYTECODE': '1'}, sys_argv=[''], run_stdin=True, dont_write_bytecode=1) + self.check([], {'PYTHONVERBOSE': '1'}, sys_argv=[''], run_stdin=True, verbose=1) def test_sysflags(self): flags = ( From noreply at buildbot.pypy.org Sun Feb 10 23:00:24 2013 From: noreply at buildbot.pypy.org (fijal) Date: Sun, 10 Feb 2013 23:00:24 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: Make sure we allocate floats at even places (and the comments are true) Message-ID: <20130210220024.231F81C03D5@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61052:d1e8b34335c6 Date: 2013-02-10 23:59 +0200 http://bitbucket.org/pypy/pypy/changeset/d1e8b34335c6/ Log: Make sure we allocate floats at even places (and the comments are true) diff --git a/rpython/jit/backend/llsupport/regalloc.py b/rpython/jit/backend/llsupport/regalloc.py --- a/rpython/jit/backend/llsupport/regalloc.py +++ b/rpython/jit/backend/llsupport/regalloc.py @@ -1,5 +1,5 @@ import os -from rpython.jit.metainterp.history import Const, Box, REF, INT +from rpython.jit.metainterp.history import Const, Box, REF from rpython.rlib.objectmodel import we_are_translated, specialize from rpython.jit.metainterp.resoperation import rop @@ -77,7 +77,7 @@ return self.fm.frame_pos(node.val, tp) def _candidate(self, node): - return node.val + 1 == node.next.val + return (node.val & 1 == 0) and (node.val + 1 == node.next.val) def _pop_two(self, tp): node = self.master_node @@ -165,8 +165,15 @@ if newloc is None: # index = self.get_frame_depth() - newloc = self.frame_pos(index, box.type) - self.current_frame_depth += size + if index & 1 and size == 2: + # we can't allocate it at odd position + self.freelist._append(index) + newloc = self.frame_pos(index + 1, box.type) + self.current_frame_depth += 3 + index += 1 # for test + else: + newloc = self.frame_pos(index, box.type) + self.current_frame_depth += size # if not we_are_translated(): # extra testing testindex = self.get_loc_index(newloc) diff --git a/rpython/jit/backend/llsupport/test/test_regalloc.py b/rpython/jit/backend/llsupport/test/test_regalloc.py --- a/rpython/jit/backend/llsupport/test/test_regalloc.py +++ b/rpython/jit/backend/llsupport/test/test_regalloc.py @@ -477,8 +477,11 @@ assert l.pop(1, 0).pos == 2 assert l.pop(1, 0) is None l.append(2, Loc(1, 2, 0)) + # this will not work because the result will be odd + assert l.pop(2, 13) is None + l.append(1, Loc(3, 1, 0)) item = l.pop(2, 13) - assert item.pos == 1 + assert item.pos == 2 assert item.tp == 13 assert item.size == 2 @@ -553,13 +556,14 @@ # f0 = BoxFloat() locf0 = fm.loc(f0) - assert fm.get_loc_index(locf0) == 3 - assert fm.get_frame_depth() == 5 + # can't be odd + assert fm.get_loc_index(locf0) == 4 + assert fm.get_frame_depth() == 6 # f1 = BoxFloat() locf1 = fm.loc(f1) - assert fm.get_loc_index(locf1) == 5 - assert fm.get_frame_depth() == 7 + assert fm.get_loc_index(locf1) == 6 + assert fm.get_frame_depth() == 8 fm.mark_as_free(b1) assert fm.freelist b2 = BoxInt() @@ -570,11 +574,11 @@ p0 = BoxPtr() ploc = fm.loc(p0) assert fm.get_loc_index(ploc) == 0 - assert fm.get_frame_depth() == 7 + assert fm.get_frame_depth() == 8 assert ploc != loc1 p1 = BoxPtr() p1loc = fm.loc(p1) - assert fm.get_loc_index(p1loc) == 7 + assert fm.get_loc_index(p1loc) == 3 assert fm.get_frame_depth() == 8 fm.mark_as_free(p0) p2 = BoxPtr() From noreply at buildbot.pypy.org Sun Feb 10 23:08:23 2013 From: noreply at buildbot.pypy.org (fijal) Date: Sun, 10 Feb 2013 23:08:23 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: some wb fixes for 32bit Message-ID: <20130210220823.450F81C1029@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61053:6dea91b6fe28 Date: 2013-02-11 00:07 +0200 http://bitbucket.org/pypy/pypy/changeset/6dea91b6fe28/ Log: some wb fixes for 32bit diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -389,8 +389,10 @@ if not for_frame: self._push_all_regs_to_frame(mc, [], withfloats, callee_only=True) if IS_X86_32: - XXX - mc.MOV_rs(eax.value, WORD) + # we have 2 extra words on stack for retval and we pass 1 extra + # arg, so we need to substract 2 words + mc.SUB_ri(esp.value, 2 * WORD) + mc.MOV_rs(eax.value, 3 * WORD) # 2 + 1 mc.MOV_sr(0, eax.value) elif IS_X86_64: mc.MOV_rs(edi.value, WORD) @@ -398,6 +400,8 @@ # we're possibly called from the slowpath of malloc, so we have # one extra CALL on the stack, but one less PUSH, # save to store stuff 2 locations away on the stack. + if IS_X86_32: + xxx mc.MOV_sr(3*WORD, eax.value) mc.MOV_rr(edi.value, ebp.value) @@ -413,17 +417,17 @@ # if not for_frame: + if IS_X86_32: + xxx self._pop_all_regs_from_frame(mc, [], withfloats, callee_only=True) mc.RET16_i(WORD) else: + if IS_X86_32: + # ADD touches CPU flags + mc.LEA_rs(esp.value, 2 * WORD) mc.MOV_rs(eax.value, 3 * WORD) mc.RET() - # - # ADD esp, correct_esp_by --- but cannot use ADD, because - # of its effects on the CPU flags - - #mc.LEA_rs(esp.value, WORD) - # + rawstart = mc.materialize(self.cpu.asmmemmgr, []) if for_frame: self.wb_slowpath[4] = rawstart From noreply at buildbot.pypy.org Sun Feb 10 23:38:04 2013 From: noreply at buildbot.pypy.org (fijal) Date: Sun, 10 Feb 2013 23:38:04 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: 32bit fixes Message-ID: <20130210223804.E8E611C004F@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61054:3cd33894e381 Date: 2013-02-11 00:37 +0200 http://bitbucket.org/pypy/pypy/changeset/3cd33894e381/ Log: 32bit fixes diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -411,20 +411,23 @@ # A final TEST8 before the RET, for the caller. Careful to # not follow this instruction with another one that changes # the status of the CPU flags! - mc.MOV_rs(eax.value, WORD) + if IS_X86_32: + mc.MOV_rs(eax.value, 3*WORD) + else: + mc.MOV_rs(eax.value, WORD) mc.TEST8(addr_add_const(eax, descr.jit_wb_if_flag_byteofs), imm(-0x80)) # if not for_frame: if IS_X86_32: - xxx + # ADD touches CPU flags + mc.LEA_rs(esp.value, 2 * WORD) self._pop_all_regs_from_frame(mc, [], withfloats, callee_only=True) mc.RET16_i(WORD) else: if IS_X86_32: - # ADD touches CPU flags - mc.LEA_rs(esp.value, 2 * WORD) + XXX mc.MOV_rs(eax.value, 3 * WORD) mc.RET() From noreply at buildbot.pypy.org Mon Feb 11 02:17:00 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Mon, 11 Feb 2013 02:17:00 +0100 (CET) Subject: [pypy-commit] pypy default: allow dbm to find bdb up to 5.3 Message-ID: <20130211011700.D58241C03D5@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61055:8234f36749c5 Date: 2013-02-10 20:12 -0500 http://bitbucket.org/pypy/pypy/changeset/8234f36749c5/ Log: allow dbm to find bdb up to 5.3 diff --git a/lib_pypy/dbm.py b/lib_pypy/dbm.py --- a/lib_pypy/dbm.py +++ b/lib_pypy/dbm.py @@ -126,8 +126,8 @@ libpath = ctypes.util.find_library('db') if not libpath: # XXX this is hopeless... - for c in '56789': - libpath = ctypes.util.find_library('db-4.%s' % c) + for c in ['5.3', '5.2', '5.1', '5.0', '4.9', '4.8', '4.7', '4.6', '4.5']: + libpath = ctypes.util.find_library('db-%s' % c) if libpath: break else: From noreply at buildbot.pypy.org Mon Feb 11 02:45:35 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Mon, 11 Feb 2013 02:45:35 +0100 (CET) Subject: [pypy-commit] pypy default: test and fix lib_pypy.dbm handling of null characters (patch from antocuni) Message-ID: <20130211014535.DF9E21C1029@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61056:3bca589bc8bd Date: 2013-02-10 20:44 -0500 http://bitbucket.org/pypy/pypy/changeset/3bca589bc8bd/ Log: test and fix lib_pypy.dbm handling of null characters (patch from antocuni) diff --git a/lib_pypy/dbm.py b/lib_pypy/dbm.py --- a/lib_pypy/dbm.py +++ b/lib_pypy/dbm.py @@ -1,4 +1,4 @@ -from ctypes import Structure, c_char_p, c_int, c_void_p, CDLL +from ctypes import Structure, c_char_p, c_int, c_void_p, CDLL, POINTER, c_char import ctypes.util import os, sys @@ -11,7 +11,7 @@ class datum(Structure): _fields_ = [ - ('dptr', c_char_p), + ('dptr', POINTER(c_char)), ('dsize', c_int), ] diff --git a/pypy/module/test_lib_pypy/test_dbm_extra.py b/pypy/module/test_lib_pypy/test_dbm_extra.py --- a/pypy/module/test_lib_pypy/test_dbm_extra.py +++ b/pypy/module/test_lib_pypy/test_dbm_extra.py @@ -6,6 +6,10 @@ except ImportError, e: py.test.skip(e) +import sys +if '__pypy__' not in sys.builtin_module_names: + skip("lib_pypy.dbm requires PyPy's ctypes") + def test_get(): path = str(udir.join('test_dbm_extra.test_get')) d = dbm.open(path, 'c') @@ -48,3 +52,12 @@ def test_extra(): py.test.raises(TypeError, dbm.datum, 123) py.test.raises(TypeError, dbm.datum, False) + +def test_null(): + db = dbm.open('test', 'c') + db['1'] = 'a\x00b' + db.close() + + db = dbm.open('test', 'r') + assert db['1'] == 'a\x00b' + db.close() From noreply at buildbot.pypy.org Mon Feb 11 04:05:50 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Mon, 11 Feb 2013 04:05:50 +0100 (CET) Subject: [pypy-commit] pypy default: clean up ieee.py and add another test Message-ID: <20130211030550.77A931C1029@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61057:b93922fe456d Date: 2013-02-10 22:01 -0500 http://bitbucket.org/pypy/pypy/changeset/b93922fe456d/ Log: clean up ieee.py and add another test diff --git a/rpython/rlib/rstruct/ieee.py b/rpython/rlib/rstruct/ieee.py --- a/rpython/rlib/rstruct/ieee.py +++ b/rpython/rlib/rstruct/ieee.py @@ -7,7 +7,6 @@ from rpython.rlib import rarithmetic, rfloat, objectmodel, jit from rpython.rlib.rarithmetic import r_ulonglong - def round_to_nearest(x): """Python 3 style round: round a float x to the nearest int, but unlike the builtin Python 2.x round function: @@ -25,38 +24,6 @@ int_part += 1 return int_part -def float_unpack80(QQ): - '''Unpack a (mant, exp) tuple of r_ulonglong in 80-bit extended format - into a long double float - ''' - MIN_EXP = -16381 - MAX_EXP = 16384 - MANT_DIG = 64 - TOPBITS = 80 - 64 - one = r_ulonglong(1) - if len(QQ) != 2: - raise ValueError("QQ must be two 64 bit uints") - if not objectmodel.we_are_translated(): - # This tests generates wrong code when translated: - # with gcc, shifting a 64bit int by 64 bits does - # not change the value. - if QQ[1] >> TOPBITS: - raise ValueError("input '%r' out of range '%r'" % (QQ, QQ[1]>>TOPBITS)) - - # extract pieces with explicit one in MANT_DIG - sign = rarithmetic.intmask(QQ[1] >> TOPBITS - 1) - exp = rarithmetic.intmask((QQ[1] & ((one << TOPBITS - 1) - 1))) - mant = QQ[0] - - if exp == MAX_EXP - MIN_EXP + 2: - # nan or infinity - result = rfloat.NAN if mant &((one << MANT_DIG - 1) - 1) else rfloat.INFINITY - else: - # normal - result = math.ldexp(mant, exp + MIN_EXP - MANT_DIG - 1) - return -result if sign else result - - def float_unpack(Q, size): """Convert a 16-bit, 32-bit 64-bit integer created by float_pack into a Python float.""" @@ -73,8 +40,8 @@ BITS = 32 one = r_ulonglong(1) elif size == 2: - MIN_EXP = -13 - MAX_EXP = 16 + MIN_EXP = -13 + MAX_EXP = 16 MANT_DIG = 11 BITS = 16 one = r_ulonglong(1) @@ -105,6 +72,36 @@ result = math.ldexp(mant, exp + MIN_EXP - MANT_DIG - 1) return -result if sign else result +def float_unpack80(QQ): + '''Unpack a (mant, exp) tuple of r_ulonglong in 80-bit extended format + into a long double float + ''' + MIN_EXP = -16381 + MAX_EXP = 16384 + MANT_DIG = 64 + TOPBITS = 80 - 64 + one = r_ulonglong(1) + if len(QQ) != 2: + raise ValueError("QQ must be two 64 bit uints") + if not objectmodel.we_are_translated(): + # This tests generates wrong code when translated: + # with gcc, shifting a 64bit int by 64 bits does + # not change the value. + if QQ[1] >> TOPBITS: + raise ValueError("input '%r' out of range '%r'" % (QQ, QQ[1]>>TOPBITS)) + + # extract pieces with explicit one in MANT_DIG + sign = rarithmetic.intmask(QQ[1] >> TOPBITS - 1) + exp = rarithmetic.intmask((QQ[1] & ((one << TOPBITS - 1) - 1))) + mant = QQ[0] + + if exp == MAX_EXP - MIN_EXP + 2: + # nan or infinity + result = rfloat.NAN if mant &((one << MANT_DIG - 1) - 1) else rfloat.INFINITY + else: + # normal + result = math.ldexp(mant, exp + MIN_EXP - MANT_DIG - 1) + return -result if sign else result def float_pack(x, size): """Convert a Python float x into a 64-bit unsigned integer @@ -120,17 +117,10 @@ MANT_DIG = 24 # FLT_MANT_DIG BITS = 32 elif size == 2: - MIN_EXP = -13 - MAX_EXP = 16 + MIN_EXP = -13 + MAX_EXP = 16 MANT_DIG = 11 BITS = 16 - elif size == 16 or size == 12: - #Implement a x86-hardware extended 80 bit format - # with explicit 1 in bit 64 - MIN_EXP = -16381 - MAX_EXP = 16384 - MANT_DIG = 64 - BITS = 80 else: raise ValueError("invalid size value") @@ -177,21 +167,18 @@ assert 0 <= mant < 1 << MANT_DIG - 1 assert 0 <= exp <= MAX_EXP - MIN_EXP + 2 assert 0 <= sign <= 1 - if size==12 or size == 16: - mant |= r_ulonglong(1) <<(MANT_DIG-1) #1 is explicit for 80bit extended format - exp = exp << 1 exp = r_ulonglong(exp) sign = r_ulonglong(sign) return ((sign << BITS - 1) | (exp << MANT_DIG - 1)) | mant -def float_pack80(_x): +def float_pack80(x): """Convert a Python float or longfloat x into two 64-bit unsigned integers with 80 bit extended representation.""" MIN_EXP = -16381 MAX_EXP = 16384 - MANT_DIG = 64 + MANT_DIG = 64 BITS = 80 - x = float(_x) #longfloat not really supported + x = float(x) # longfloat not really supported sign = rfloat.copysign(1.0, x) < 0.0 if not rfloat.isfinite(x): if rfloat.isinf(x): @@ -237,6 +224,15 @@ sign = r_ulonglong(sign) return (mant, (sign << BITS - MANT_DIG - 1) | exp) + at jit.unroll_safe +def pack_float(result, x, size, be): + l = [] + unsigned = float_pack(x, size) + for i in range(size): + l.append(chr((unsigned >> (i * 8)) & 0xFF)) + if be: + l.reverse() + result.append("".join(l)) @jit.unroll_safe def pack_float80(result, x, size, be): @@ -250,16 +246,6 @@ l.reverse() result.append("".join(l)) - at jit.unroll_safe -def pack_float(result, x, size, be): - l = [] - unsigned = float_pack(x, size) - for i in range(size): - l.append(chr((unsigned >> (i * 8)) & 0xFF)) - if be: - l.reverse() - result.append("".join(l)) - def unpack_float(s, be): unsigned = r_ulonglong(0) for i in range(len(s)): diff --git a/rpython/rlib/rstruct/test/test_ieee.py b/rpython/rlib/rstruct/test/test_ieee.py --- a/rpython/rlib/rstruct/test/test_ieee.py +++ b/rpython/rlib/rstruct/test/test_ieee.py @@ -5,9 +5,7 @@ from rpython.rlib.rfloat import isnan from rpython.rlib.rstruct.ieee import float_pack, float_unpack, float_pack80, float_unpack80 - class TestFloatPacking: - def setup_class(cls): if sys.version_info < (2, 6): py.test.skip("the 'struct' module of this old CPython is broken") @@ -61,6 +59,13 @@ self.check_float(0.0) self.check_float(-0.0) + def test_check_size(self): + # these were refactored into separate pack80/unpack80 functions + py.test.raises(ValueError, float_pack, 1.0, 12) + py.test.raises(ValueError, float_pack, 1.0, 16) + py.test.raises(ValueError, float_unpack, 1, 12) + py.test.raises(ValueError, float_unpack, 1, 16) + def test_nans(self): Q = float_pack80(float('nan')) y = float_unpack80(Q) @@ -161,4 +166,3 @@ f_out = math.copysign(float('inf'), f1) assert f_out == f2 assert math.copysign(1., f_out) == math.copysign(1., f2) - From noreply at buildbot.pypy.org Mon Feb 11 07:52:52 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Mon, 11 Feb 2013 07:52:52 +0100 (CET) Subject: [pypy-commit] pypy default: move the pyrepl tests to test_lib_pypy so they have a hope of being executed Message-ID: <20130211065252.1216A1C0041@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61058:8f0c8d10c0cd Date: 2013-02-11 00:12 -0500 http://bitbucket.org/pypy/pypy/changeset/8f0c8d10c0cd/ Log: move the pyrepl tests to test_lib_pypy so they have a hope of being executed diff --git a/lib_pypy/pyrepl/tests/__init__.py b/pypy/module/test_lib_pypy/pyrepl/__init__.py rename from lib_pypy/pyrepl/tests/__init__.py rename to pypy/module/test_lib_pypy/pyrepl/__init__.py diff --git a/lib_pypy/pyrepl/tests/infrastructure.py b/pypy/module/test_lib_pypy/pyrepl/infrastructure.py rename from lib_pypy/pyrepl/tests/infrastructure.py rename to pypy/module/test_lib_pypy/pyrepl/infrastructure.py diff --git a/lib_pypy/pyrepl/tests/basic.py b/pypy/module/test_lib_pypy/pyrepl/test_basic.py rename from lib_pypy/pyrepl/tests/basic.py rename to pypy/module/test_lib_pypy/pyrepl/test_basic.py diff --git a/lib_pypy/pyrepl/tests/bugs.py b/pypy/module/test_lib_pypy/pyrepl/test_bugs.py rename from lib_pypy/pyrepl/tests/bugs.py rename to pypy/module/test_lib_pypy/pyrepl/test_bugs.py diff --git a/lib_pypy/pyrepl/test/test_functional.py b/pypy/module/test_lib_pypy/pyrepl/test_functional.py rename from lib_pypy/pyrepl/test/test_functional.py rename to pypy/module/test_lib_pypy/pyrepl/test_functional.py diff --git a/lib_pypy/pyrepl/tests/wishes.py b/pypy/module/test_lib_pypy/pyrepl/test_wishes.py rename from lib_pypy/pyrepl/tests/wishes.py rename to pypy/module/test_lib_pypy/pyrepl/test_wishes.py From noreply at buildbot.pypy.org Mon Feb 11 07:52:53 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Mon, 11 Feb 2013 07:52:53 +0100 (CET) Subject: [pypy-commit] pypy default: update the pyrepl tests from upstream Message-ID: <20130211065253.556061C0041@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61059:b724dd140134 Date: 2013-02-11 01:37 -0500 http://bitbucket.org/pypy/pypy/changeset/b724dd140134/ Log: update the pyrepl tests from upstream diff --git a/pypy/module/test_lib_pypy/pyrepl/__init__.py b/pypy/module/test_lib_pypy/pyrepl/__init__.py --- a/pypy/module/test_lib_pypy/pyrepl/__init__.py +++ b/pypy/module/test_lib_pypy/pyrepl/__init__.py @@ -1,20 +1,3 @@ -# Copyright 2000-2004 Michael Hudson-Doyle -# -# All Rights Reserved -# -# -# Permission to use, copy, modify, and distribute this software and -# its documentation for any purpose is hereby granted without fee, -# provided that the above copyright notice appear in all copies and -# that both that copyright notice and this permission notice appear in -# supporting documentation. -# -# THE AUTHOR MICHAEL HUDSON DISCLAIMS ALL WARRANTIES WITH REGARD TO -# THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY -# AND FITNESS, IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, -# INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER -# RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF -# CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -# moo +import sys +import lib_pypy.pyrepl +sys.modules['pyrepl'] = sys.modules['lib_pypy.pyrepl'] diff --git a/pypy/module/test_lib_pypy/pyrepl/infrastructure.py b/pypy/module/test_lib_pypy/pyrepl/infrastructure.py --- a/pypy/module/test_lib_pypy/pyrepl/infrastructure.py +++ b/pypy/module/test_lib_pypy/pyrepl/infrastructure.py @@ -17,66 +17,57 @@ # CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +from __future__ import print_function from pyrepl.reader import Reader from pyrepl.console import Console, Event -import unittest -import sys + class EqualsAnything(object): def __eq__(self, other): return True + + EA = EqualsAnything() + class TestConsole(Console): height = 24 width = 80 encoding = 'utf-8' - def __init__(self, events, testcase, verbose=False): + def __init__(self, events, verbose=False): self.events = events self.next_screen = None self.verbose = verbose - self.testcase = testcase def refresh(self, screen, xy): if self.next_screen is not None: - self.testcase.assertEqual( - screen, self.next_screen, - "[ %s != %s after %r ]"%(screen, self.next_screen, - self.last_event_name)) + assert screen == self.next_screen, "[ %s != %s after %r ]" % ( + screen, self.next_screen, self.last_event_name) def get_event(self, block=1): ev, sc = self.events.pop(0) self.next_screen = sc if not isinstance(ev, tuple): - ev = (ev,) + ev = (ev, None) self.last_event_name = ev[0] if self.verbose: - print "event", ev + print("event", ev) return Event(*ev) + class TestReader(Reader): + def get_prompt(self, lineno, cursor_on_line): return '' + def refresh(self): Reader.refresh(self) self.dirty = True -class ReaderTestCase(unittest.TestCase): - def run_test(self, test_spec, reader_class=TestReader): - # remember to finish your test_spec with 'accept' or similar! - con = TestConsole(test_spec, self) - reader = reader_class(con) - reader.readline() -class BasicTestRunner: - def run(self, test): - result = unittest.TestResult() - test(result) - return result - -def run_testcase(testclass): - suite = unittest.makeSuite(testclass) - runner = unittest.TextTestRunner(sys.stdout, verbosity=1) - result = runner.run(suite) - +def read_spec(test_spec, reader_class=TestReader): + # remember to finish your test_spec with 'accept' or similar! + con = TestConsole(test_spec, verbose=True) + reader = reader_class(con) + reader.readline() diff --git a/pypy/module/test_lib_pypy/pyrepl/test_basic.py b/pypy/module/test_lib_pypy/pyrepl/test_basic.py --- a/pypy/module/test_lib_pypy/pyrepl/test_basic.py +++ b/pypy/module/test_lib_pypy/pyrepl/test_basic.py @@ -16,100 +16,99 @@ # RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF # CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +import pytest +from .infrastructure import read_spec -from pyrepl.console import Event -from pyrepl.tests.infrastructure import ReaderTestCase, EA, run_testcase -class SimpleTestCase(ReaderTestCase): +def test_basic(): + read_spec([(('self-insert', 'a'), ['a']), + ( 'accept', ['a'])]) - def test_basic(self): - self.run_test([(('self-insert', 'a'), ['a']), - ( 'accept', ['a'])]) - def test_repeat(self): - self.run_test([(('digit-arg', '3'), ['']), - (('self-insert', 'a'), ['aaa']), - ( 'accept', ['aaa'])]) +def test_repeat(): + read_spec([(('digit-arg', '3'), ['']), + (('self-insert', 'a'), ['aaa']), + ( 'accept', ['aaa'])]) - def test_kill_line(self): - self.run_test([(('self-insert', 'abc'), ['abc']), - ( 'left', None), - ( 'kill-line', ['ab']), - ( 'accept', ['ab'])]) - def test_unix_line_discard(self): - self.run_test([(('self-insert', 'abc'), ['abc']), - ( 'left', None), - ( 'unix-word-rubout', ['c']), - ( 'accept', ['c'])]) +def test_kill_line(): + read_spec([(('self-insert', 'abc'), ['abc']), + ( 'left', None), + ( 'kill-line', ['ab']), + ( 'accept', ['ab'])]) - def test_kill_word(self): - self.run_test([(('self-insert', 'ab cd'), ['ab cd']), - ( 'beginning-of-line', ['ab cd']), - ( 'kill-word', [' cd']), - ( 'accept', [' cd'])]) - def test_backward_kill_word(self): - self.run_test([(('self-insert', 'ab cd'), ['ab cd']), - ( 'backward-kill-word', ['ab ']), - ( 'accept', ['ab '])]) +def test_unix_line_discard(): + read_spec([(('self-insert', 'abc'), ['abc']), + ( 'left', None), + ( 'unix-word-rubout', ['c']), + ( 'accept', ['c'])]) - def test_yank(self): - self.run_test([(('self-insert', 'ab cd'), ['ab cd']), - ( 'backward-kill-word', ['ab ']), - ( 'beginning-of-line', ['ab ']), - ( 'yank', ['cdab ']), - ( 'accept', ['cdab '])]) - - def test_yank_pop(self): - self.run_test([(('self-insert', 'ab cd'), ['ab cd']), - ( 'backward-kill-word', ['ab ']), - ( 'left', ['ab ']), - ( 'backward-kill-word', [' ']), - ( 'yank', ['ab ']), - ( 'yank-pop', ['cd ']), - ( 'accept', ['cd '])]) - def test_interrupt(self): - try: - self.run_test([( 'interrupt', [''])]) - except KeyboardInterrupt: - pass - else: - self.fail('KeyboardInterrupt got lost') +def test_kill_word(): + read_spec([(('self-insert', 'ab cd'), ['ab cd']), + ( 'beginning-of-line', ['ab cd']), + ( 'kill-word', [' cd']), + ( 'accept', [' cd'])]) - # test_suspend -- hah - def test_up(self): - self.run_test([(('self-insert', 'ab\ncd'), ['ab', 'cd']), - ( 'up', ['ab', 'cd']), - (('self-insert', 'e'), ['abe', 'cd']), - ( 'accept', ['abe', 'cd'])]) +def test_backward_kill_word(): + read_spec([(('self-insert', 'ab cd'), ['ab cd']), + ( 'backward-kill-word', ['ab ']), + ( 'accept', ['ab '])]) - def test_down(self): - self.run_test([(('self-insert', 'ab\ncd'), ['ab', 'cd']), - ( 'up', ['ab', 'cd']), - (('self-insert', 'e'), ['abe', 'cd']), - ( 'down', ['abe', 'cd']), - (('self-insert', 'f'), ['abe', 'cdf']), - ( 'accept', ['abe', 'cdf'])]) - def test_left(self): - self.run_test([(('self-insert', 'ab'), ['ab']), - ( 'left', ['ab']), - (('self-insert', 'c'), ['acb']), - ( 'accept', ['acb'])]) +def test_yank(): + read_spec([(('self-insert', 'ab cd'), ['ab cd']), + ( 'backward-kill-word', ['ab ']), + ( 'beginning-of-line', ['ab ']), + ( 'yank', ['cdab ']), + ( 'accept', ['cdab '])]) - def test_right(self): - self.run_test([(('self-insert', 'ab'), ['ab']), - ( 'left', ['ab']), - (('self-insert', 'c'), ['acb']), - ( 'right', ['acb']), - (('self-insert', 'd'), ['acbd']), - ( 'accept', ['acbd'])]) - -def test(): - run_testcase(SimpleTestCase) -if __name__ == '__main__': - test() +def test_yank_pop(): + read_spec([(('self-insert', 'ab cd'), ['ab cd']), + ( 'backward-kill-word', ['ab ']), + ( 'left', ['ab ']), + ( 'backward-kill-word', [' ']), + ( 'yank', ['ab ']), + ( 'yank-pop', ['cd ']), + ( 'accept', ['cd '])]) + + +def test_interrupt(): + with pytest.raises(KeyboardInterrupt): + read_spec([('interrupt', [''])]) + + +# test_suspend -- hah +def test_up(): + read_spec([(('self-insert', 'ab\ncd'), ['ab', 'cd']), + ( 'up', ['ab', 'cd']), + (('self-insert', 'e'), ['abe', 'cd']), + ( 'accept', ['abe', 'cd'])]) + + +def test_down(): + read_spec([(('self-insert', 'ab\ncd'), ['ab', 'cd']), + ( 'up', ['ab', 'cd']), + (('self-insert', 'e'), ['abe', 'cd']), + ( 'down', ['abe', 'cd']), + (('self-insert', 'f'), ['abe', 'cdf']), + ( 'accept', ['abe', 'cdf'])]) + + +def test_left(): + read_spec([(('self-insert', 'ab'), ['ab']), + ( 'left', ['ab']), + (('self-insert', 'c'), ['acb']), + ( 'accept', ['acb'])]) + + +def test_right(): + read_spec([(('self-insert', 'ab'), ['ab']), + ( 'left', ['ab']), + (('self-insert', 'c'), ['acb']), + ( 'right', ['acb']), + (('self-insert', 'd'), ['acbd']), + ( 'accept', ['acbd'])]) diff --git a/pypy/module/test_lib_pypy/pyrepl/test_bugs.py b/pypy/module/test_lib_pypy/pyrepl/test_bugs.py --- a/pypy/module/test_lib_pypy/pyrepl/test_bugs.py +++ b/pypy/module/test_lib_pypy/pyrepl/test_bugs.py @@ -17,20 +17,30 @@ # CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -from pyrepl.console import Event -from pyrepl.tests.infrastructure import ReaderTestCase, EA, run_testcase +from pyrepl.historical_reader import HistoricalReader +from .infrastructure import EA, TestReader, read_spec # this test case should contain as-verbatim-as-possible versions of # (applicable) bug reports -class BugsTestCase(ReaderTestCase): +import pytest - def test_transpose_at_start(self): - self.run_test([( 'transpose', [EA, '']), - ( 'accept', [''])]) -def test(): - run_testcase(BugsTestCase) +class HistoricalTestReader(HistoricalReader, TestReader): + pass -if __name__ == '__main__': - test() + + at pytest.mark.xfail(reason='event missing', run=False) +def test_transpose_at_start(): + read_spec([ + ('transpose', [EA, '']), + ('accept', [''])]) + + +def test_cmd_instantiation_crash(): + spec = [ + ('reverse-history-isearch', ["(r-search `') "]), + (('key', 'left'), ['']), + ('accept', ['']) + ] + read_spec(spec, HistoricalTestReader) diff --git a/pypy/module/test_lib_pypy/pyrepl/test_functional.py b/pypy/module/test_lib_pypy/pyrepl/test_functional.py --- a/pypy/module/test_lib_pypy/pyrepl/test_functional.py +++ b/pypy/module/test_lib_pypy/pyrepl/test_functional.py @@ -1,50 +1,25 @@ # Copyright 2000-2007 Michael Hudson-Doyle # Maciek Fijalkowski -# -# All Rights Reserved -# -# -# Permission to use, copy, modify, and distribute this software and -# its documentation for any purpose is hereby granted without fee, -# provided that the above copyright notice appear in all copies and -# that both that copyright notice and this permission notice appear in -# supporting documentation. -# -# THE AUTHOR MICHAEL HUDSON DISCLAIMS ALL WARRANTIES WITH REGARD TO -# THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY -# AND FITNESS, IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, -# INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER -# RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF -# CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - +# License: MIT # some functional tests, to see if this is really working -import py +import pytest import sys -class TestTerminal(object): - def _spawn(self, *args, **kwds): - try: - import pexpect - except ImportError, e: - py.test.skip(str(e)) - kwds.setdefault('timeout', 10) - child = pexpect.spawn(*args, **kwds) - child.logfile = sys.stdout - return child - def spawn(self, argv=[]): - # avoid running start.py, cause it might contain - # things like readline or rlcompleter(2) included - child = self._spawn(sys.executable, ['-S'] + argv) - child.sendline('from pyrepl.python_reader import main') - child.sendline('main()') - return child +def pytest_funcarg__child(request): + try: + pexpect = pytest.importorskip('pexpect') + except SyntaxError: + pytest.skip('pexpect wont work on py3k') + child = pexpect.spawn(sys.executable, ['-S'], timeout=10) + child.logfile = sys.stdout + child.sendline('from pyrepl.python_reader import main') + child.sendline('main()') + return child - def test_basic(self): - child = self.spawn() - child.sendline('a = 3') - child.sendline('a') - child.expect('3') - + +def test_basic(child): + child.sendline('a = 3') + child.sendline('a') + child.expect('3') diff --git a/pypy/module/test_lib_pypy/pyrepl/test_keymap.py b/pypy/module/test_lib_pypy/pyrepl/test_keymap.py new file mode 100644 --- /dev/null +++ b/pypy/module/test_lib_pypy/pyrepl/test_keymap.py @@ -0,0 +1,10 @@ +from pyrepl.keymap import compile_keymap + + +def test_compile_keymap(): + k = compile_keymap({ + b'a': 'test', + b'bc': 'test2', + }) + + assert k == {b'a': 'test', b'b': {b'c': 'test2'}} diff --git a/pypy/module/test_lib_pypy/pyrepl/test_readline.py b/pypy/module/test_lib_pypy/pyrepl/test_readline.py new file mode 100644 --- /dev/null +++ b/pypy/module/test_lib_pypy/pyrepl/test_readline.py @@ -0,0 +1,15 @@ +from pyrepl.readline import _ReadlineWrapper +import os +import pty + + +def test_raw_input(): + master, slave = pty.openpty() + readline_wrapper = _ReadlineWrapper(slave, slave) + os.write(master, b'input\n') + + result = readline_wrapper.get_reader().readline() + #result = readline_wrapper.raw_input('prompt:') + assert result == 'input' + # A bytes string on python2, a unicode string on python3. + assert isinstance(result, str) diff --git a/pypy/module/test_lib_pypy/pyrepl/test_wishes.py b/pypy/module/test_lib_pypy/pyrepl/test_wishes.py --- a/pypy/module/test_lib_pypy/pyrepl/test_wishes.py +++ b/pypy/module/test_lib_pypy/pyrepl/test_wishes.py @@ -17,22 +17,15 @@ # CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -from pyrepl.console import Event -from pyrepl.tests.infrastructure import ReaderTestCase, EA, run_testcase +from .infrastructure import read_spec # this test case should contain as-verbatim-as-possible versions of # (applicable) feature requests -class WishesTestCase(ReaderTestCase): - def test_quoted_insert_repeat(self): - self.run_test([(('digit-arg', '3'), ['']), - ( 'quoted-insert', ['']), - (('self-insert', '\033'), ['^[^[^[']), - ( 'accept', None)]) - -def test(): - run_testcase(WishesTestCase) - -if __name__ == '__main__': - test() +def test_quoted_insert_repeat(): + read_spec([ + (('digit-arg', '3'), ['']), + (('quoted-insert', None), ['']), + (('self-insert', '\033'), ['^[^[^[']), + (('accept', None), None)]) From noreply at buildbot.pypy.org Mon Feb 11 07:52:54 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Mon, 11 Feb 2013 07:52:54 +0100 (CET) Subject: [pypy-commit] pypy default: apply some fixes to get the pyrepl tests running Message-ID: <20130211065254.8C3E41C0041@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61060:4cc85256a407 Date: 2013-02-11 01:51 -0500 http://bitbucket.org/pypy/pypy/changeset/4cc85256a407/ Log: apply some fixes to get the pyrepl tests running diff --git a/lib_pypy/pyrepl/reader.py b/lib_pypy/pyrepl/reader.py --- a/lib_pypy/pyrepl/reader.py +++ b/lib_pypy/pyrepl/reader.py @@ -552,6 +552,8 @@ if not event: # can only happen if we're not blocking return None + translate = True + if event.evt == 'key': self.input_trans.push(event) elif event.evt == 'scroll': @@ -559,9 +561,12 @@ elif event.evt == 'resize': self.refresh() else: - pass + translate = False - cmd = self.input_trans.get() + if translate: + cmd = self.input_trans.get() + else: + cmd = event.evt, event.data if cmd is None: if block: diff --git a/lib_pypy/pyrepl/readline.py b/lib_pypy/pyrepl/readline.py --- a/lib_pypy/pyrepl/readline.py +++ b/lib_pypy/pyrepl/readline.py @@ -174,13 +174,15 @@ # ____________________________________________________________ class _ReadlineWrapper(object): - f_in = 0 - f_out = 1 reader = None saved_history_length = -1 startup_hook = None config = ReadlineConfig() + def __init__(self, f_in=None, f_out=None): + self.f_in = f_in if f_in is not None else os.dup(0) + self.f_out = f_out if f_out is not None else os.dup(1) + def get_reader(self): if self.reader is None: console = UnixConsole(self.f_in, self.f_out, encoding=ENCODING) diff --git a/pypy/module/test_lib_pypy/pyrepl/infrastructure.py b/pypy/module/test_lib_pypy/pyrepl/infrastructure.py --- a/pypy/module/test_lib_pypy/pyrepl/infrastructure.py +++ b/pypy/module/test_lib_pypy/pyrepl/infrastructure.py @@ -56,7 +56,7 @@ return Event(*ev) -class TestReader(Reader): +class BaseTestReader(Reader): def get_prompt(self, lineno, cursor_on_line): return '' @@ -66,7 +66,7 @@ self.dirty = True -def read_spec(test_spec, reader_class=TestReader): +def read_spec(test_spec, reader_class=BaseTestReader): # remember to finish your test_spec with 'accept' or similar! con = TestConsole(test_spec, verbose=True) reader = reader_class(con) diff --git a/pypy/module/test_lib_pypy/pyrepl/test_bugs.py b/pypy/module/test_lib_pypy/pyrepl/test_bugs.py --- a/pypy/module/test_lib_pypy/pyrepl/test_bugs.py +++ b/pypy/module/test_lib_pypy/pyrepl/test_bugs.py @@ -18,7 +18,7 @@ # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. from pyrepl.historical_reader import HistoricalReader -from .infrastructure import EA, TestReader, read_spec +from .infrastructure import EA, BaseTestReader, read_spec # this test case should contain as-verbatim-as-possible versions of # (applicable) bug reports @@ -26,7 +26,7 @@ import pytest -class HistoricalTestReader(HistoricalReader, TestReader): +class HistoricalTestReader(HistoricalReader, BaseTestReader): pass From noreply at buildbot.pypy.org Mon Feb 11 07:57:45 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Mon, 11 Feb 2013 07:57:45 +0100 (CET) Subject: [pypy-commit] pypy default: move this ctypes_config_cache test so it gets run Message-ID: <20130211065745.5D83E1C0041@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61061:d4f8da207e2d Date: 2013-02-11 01:57 -0500 http://bitbucket.org/pypy/pypy/changeset/d4f8da207e2d/ Log: move this ctypes_config_cache test so it gets run diff --git a/lib_pypy/ctypes_config_cache/test/test_cache.py b/pypy/module/test_lib_pypy/test_ctypes_config_cache.py rename from lib_pypy/ctypes_config_cache/test/test_cache.py rename to pypy/module/test_lib_pypy/test_ctypes_config_cache.py --- a/lib_pypy/ctypes_config_cache/test/test_cache.py +++ b/pypy/module/test_lib_pypy/test_ctypes_config_cache.py @@ -2,7 +2,8 @@ import sys, os from rpython.tool.udir import udir -dirpath = py.path.local(__file__).dirpath().dirpath() +dirpath = py.path.local(__file__).dirpath().dirpath().dirpath().dirpath() +dirpath = dirpath.join('lib_pypy').join('ctypes_config_cache') def run(filename, outputname): From noreply at buildbot.pypy.org Mon Feb 11 08:00:08 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Mon, 11 Feb 2013 08:00:08 +0100 (CET) Subject: [pypy-commit] pypy default: this file no longer needed Message-ID: <20130211070008.16EB41C0041@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61062:f8ad0b03911c Date: 2013-02-11 01:59 -0500 http://bitbucket.org/pypy/pypy/changeset/f8ad0b03911c/ Log: this file no longer needed diff --git a/lib_pypy/conftest.py b/lib_pypy/conftest.py deleted file mode 100644 --- a/lib_pypy/conftest.py +++ /dev/null @@ -1,2 +0,0 @@ - -from pypy.conftest import * From noreply at buildbot.pypy.org Mon Feb 11 09:04:27 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Mon, 11 Feb 2013 09:04:27 +0100 (CET) Subject: [pypy-commit] pypy default: backport some obvious fixes/cleanups from pyrepl including a fix for issue1098 Message-ID: <20130211080427.F3F6E1C1029@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61063:02a691b8f00d Date: 2013-02-11 02:58 -0500 http://bitbucket.org/pypy/pypy/changeset/02a691b8f00d/ Log: backport some obvious fixes/cleanups from pyrepl including a fix for issue1098 dup fds for UnixConsole and and check for closed stdout before flushing use reverse=True instead of negative comparator kill uniqify for sorted(set(...)) kill disabled setaf writeout code diff --git a/lib_pypy/pyrepl/cmdrepl.py b/lib_pypy/pyrepl/cmdrepl.py --- a/lib_pypy/pyrepl/cmdrepl.py +++ b/lib_pypy/pyrepl/cmdrepl.py @@ -53,8 +53,8 @@ def get_completions(self, stem): if len(stem) != self.pos: return [] - return cr.uniqify([s for s in self.completions - if s.startswith(stem)]) + return sorted(set(s for s in self.completions + if s.startswith(stem))) def replize(klass, history_across_invocations=1): diff --git a/lib_pypy/pyrepl/completing_reader.py b/lib_pypy/pyrepl/completing_reader.py --- a/lib_pypy/pyrepl/completing_reader.py +++ b/lib_pypy/pyrepl/completing_reader.py @@ -21,13 +21,6 @@ from pyrepl import commands, reader from pyrepl.reader import Reader -def uniqify(l): - d = {} - for i in l: - d[i] = 1 - r = d.keys() - r.sort() - return r def prefix(wordlist, j = 0): d = {} diff --git a/lib_pypy/pyrepl/module_lister.py b/lib_pypy/pyrepl/module_lister.py --- a/lib_pypy/pyrepl/module_lister.py +++ b/lib_pypy/pyrepl/module_lister.py @@ -17,7 +17,6 @@ # CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -from pyrepl.completing_reader import uniqify import os, sys # for the completion support. @@ -38,20 +37,12 @@ l.append( prefix + fname ) _packages[prefix + fname] = _make_module_list_dir( file, suffs, prefix + fname + '.' ) - l = uniqify(l) - l.sort() - return l + return sorted(set(l)) def _make_module_list(): import imp suffs = [x[0] for x in imp.get_suffixes() if x[0] != '.pyc'] - def compare(x, y): - c = -cmp(len(x), len(y)) - if c: - return c - else: - return -cmp(x, y) - suffs.sort(compare) + suffs.sort(reverse=True) _packages[''] = list(sys.builtin_module_names) for dir in sys.path: if dir == '': diff --git a/lib_pypy/pyrepl/python_reader.py b/lib_pypy/pyrepl/python_reader.py --- a/lib_pypy/pyrepl/python_reader.py +++ b/lib_pypy/pyrepl/python_reader.py @@ -140,7 +140,7 @@ return [x[len(mod) + 1:] for x in l if x.startswith(mod + '.' + name)] try: - l = completing_reader.uniqify(self.completer.complete(stem)) + l = sorted(set(self.completer.complete(stem))) return l except (NameError, AttributeError): return [] @@ -178,7 +178,8 @@ self.showsyntaxerror("") else: self.runcode(code) - sys.stdout.flush() + if sys.stdout and not sys.stdout.closed: + sys.stdout.flush() def interact(self): while 1: @@ -368,7 +369,7 @@ encoding = None else: encoding = None # so you get ASCII... - con = UnixConsole(0, 1, None, encoding) + con = UnixConsole(os.dup(0), os.dup(1), None, encoding) if print_banner: print "Python", sys.version, "on", sys.platform print 'Type "help", "copyright", "credits" or "license" '\ diff --git a/lib_pypy/pyrepl/unix_console.py b/lib_pypy/pyrepl/unix_console.py --- a/lib_pypy/pyrepl/unix_console.py +++ b/lib_pypy/pyrepl/unix_console.py @@ -185,16 +185,6 @@ old_offset = offset = self.__offset height = self.height - if 0: - global counter - try: - counter - except NameError: - counter = 0 - self.__write_code(curses.tigetstr("setaf"), counter) - counter += 1 - if counter > 8: - counter = 0 # we make sure the cursor is on the screen, and that we're # using all of the screen if we can From noreply at buildbot.pypy.org Mon Feb 11 09:40:07 2013 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 11 Feb 2013 09:40:07 +0100 (CET) Subject: [pypy-commit] pypy default: Yet Another assembler operation Message-ID: <20130211084007.A21311C0041@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r61064:71b742f86054 Date: 2013-02-11 09:39 +0100 http://bitbucket.org/pypy/pypy/changeset/71b742f86054/ Log: Yet Another assembler operation diff --git a/rpython/translator/c/gcc/trackgcroot.py b/rpython/translator/c/gcc/trackgcroot.py --- a/rpython/translator/c/gcc/trackgcroot.py +++ b/rpython/translator/c/gcc/trackgcroot.py @@ -477,7 +477,7 @@ # floating-point operations cannot produce GC pointers 'f', 'cvt', 'ucomi', 'comi', 'subs', 'subp' , 'adds', 'addp', 'xorp', - 'movap', 'movd', 'movlp', 'movup', 'sqrt', 'rsqrt', 'movhpd', + 'movap', 'movd', 'movlp', 'movup', 'sqrt', 'rsqrt', 'movhpd', 'movlhp', 'mins', 'minp', 'maxs', 'maxp', 'unpck', 'pxor', 'por', # sse2 'shufps', 'shufpd', # arithmetic operations should not produce GC pointers From noreply at buildbot.pypy.org Mon Feb 11 10:10:05 2013 From: noreply at buildbot.pypy.org (fijal) Date: Mon, 11 Feb 2013 10:10:05 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: more 32bit fixes Message-ID: <20130211091005.A72031C01BF@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61065:6dd263080f66 Date: 2013-02-11 11:09 +0200 http://bitbucket.org/pypy/pypy/changeset/6dd263080f66/ Log: more 32bit fixes diff --git a/rpython/jit/backend/llsupport/rewrite.py b/rpython/jit/backend/llsupport/rewrite.py --- a/rpython/jit/backend/llsupport/rewrite.py +++ b/rpython/jit/backend/llsupport/rewrite.py @@ -178,12 +178,17 @@ index = self.cpu.getarryoffset_for_frame() for i, arg in enumerate(arglist): descr = self.cpu.getarraydescr_for_frame(arg.type) - self.newops.append(ResOperation(rop.SETARRAYITEM_GC, - [frame, ConstInt(index), arg], - None, descr)) if WORD == 4 and type == history.FLOAT: + self.newops.append(ResOperation(rop.SETARRAYITEM_GC, + [frame, ConstInt(index // 2), + arg], + None, descr)) index += 2 else: + self.newops.append(ResOperation(rop.SETARRAYITEM_GC, + [frame, ConstInt(index), + arg], + None, descr)) index += 1 descr = op.getdescr() assert isinstance(descr, JitCellToken) diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -1140,7 +1140,7 @@ stack_depth += 2 else: stack_depth += 1 - stack_depth += loc.get_width() + stack_depth += loc.get_width() // WORD if stack_depth > PASS_ON_MY_FRAME: stack_depth = align_stack_words(stack_depth) align = (stack_depth - PASS_ON_MY_FRAME) diff --git a/rpython/jit/backend/x86/runner.py b/rpython/jit/backend/x86/runner.py --- a/rpython/jit/backend/x86/runner.py +++ b/rpython/jit/backend/x86/runner.py @@ -56,7 +56,7 @@ return 1000 def getarryoffset_for_frame(self): - return JITFRAME_FIXED_SIZE + return JITFRAME_FIXED_SIZE def setup(self): self.assembler = Assembler386(self, self.translate_support_code) From noreply at buildbot.pypy.org Mon Feb 11 10:15:45 2013 From: noreply at buildbot.pypy.org (fijal) Date: Mon, 11 Feb 2013 10:15:45 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: a set of oops and typos Message-ID: <20130211091545.794391C1047@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61066:5f0381c30ee5 Date: 2013-02-11 11:14 +0200 http://bitbucket.org/pypy/pypy/changeset/5f0381c30ee5/ Log: a set of oops and typos diff --git a/rpython/jit/backend/llsupport/llmodel.py b/rpython/jit/backend/llsupport/llmodel.py --- a/rpython/jit/backend/llsupport/llmodel.py +++ b/rpython/jit/backend/llsupport/llmodel.py @@ -52,8 +52,12 @@ # the same as normal JITFRAME, however with an array of pointers self.refarraydescr = ArrayDescr(ad.basesize, ad.itemsize, ad.lendescr, FLAG_POINTER) - self.floatarraydescr = ArrayDescr(ad.basesize, ad.itemsize, ad.lendescr, - FLAG_FLOAT) + if WORD == 4: + self.floatarraydescr = ArrayDescr(ad.basesize, ad.itemsize * 2, + ad.lendescr, FLAG_FLOAT) + else: + self.floatarraydescr = ArrayDescr(ad.basesize, ad.itemsize, + ad.lendescr, FLAG_FLOAT) self.setup() def getarraydescr_for_frame(self, type): diff --git a/rpython/jit/backend/llsupport/rewrite.py b/rpython/jit/backend/llsupport/rewrite.py --- a/rpython/jit/backend/llsupport/rewrite.py +++ b/rpython/jit/backend/llsupport/rewrite.py @@ -175,15 +175,15 @@ None, descr=descrs.jf_frame_info) self.newops.append(op2) arglist = op.getarglist() - index = self.cpu.getarryoffset_for_frame() + index = self.cpu.getarryoffset_for_frame() for i, arg in enumerate(arglist): descr = self.cpu.getarraydescr_for_frame(arg.type) - if WORD == 4 and type == history.FLOAT: + if WORD == 4 and arg.type == history.FLOAT: self.newops.append(ResOperation(rop.SETARRAYITEM_GC, [frame, ConstInt(index // 2), arg], None, descr)) - index += 2 + index += 2 else: self.newops.append(ResOperation(rop.SETARRAYITEM_GC, [frame, ConstInt(index), From noreply at buildbot.pypy.org Mon Feb 11 10:17:52 2013 From: noreply at buildbot.pypy.org (fijal) Date: Mon, 11 Feb 2013 10:17:52 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: the famous never passing test Message-ID: <20130211091752.DDE651C1047@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61068:bccb2f5c2cec Date: 2013-02-11 11:16 +0200 http://bitbucket.org/pypy/pypy/changeset/bccb2f5c2cec/ Log: the famous never passing test diff --git a/rpython/jit/backend/x86/test/test_runner.py b/rpython/jit/backend/x86/test/test_runner.py --- a/rpython/jit/backend/x86/test/test_runner.py +++ b/rpython/jit/backend/x86/test/test_runner.py @@ -31,8 +31,11 @@ # ====> ../../test/runner_test.py add_loop_instructions = ['mov', 'add', 'test', 'je', 'jmp'] - bridge_loop_instructions = ['cmp', 'jge', 'mov', 'mov', 'mov', 'mov', - 'call', 'mov', 'jmp'] + if WORD == 4: + bridge_loop_instructions = ['cmp', 'jge', 'mov', 'mov', 'call', 'jmp'] + else: + bridge_loop_instructions = ['cmp', 'jge', 'mov', 'mov', 'mov', 'mov', + 'call', 'mov', 'jmp'] def get_cpu(self): cpu = CPU(rtyper=None, stats=FakeStats()) From noreply at buildbot.pypy.org Mon Feb 11 10:28:25 2013 From: noreply at buildbot.pypy.org (fijal) Date: Mon, 11 Feb 2013 10:28:25 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: fixes Message-ID: <20130211092825.461361C11AD@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61069:9c927d062ac6 Date: 2013-02-11 11:27 +0200 http://bitbucket.org/pypy/pypy/changeset/9c927d062ac6/ Log: fixes diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -211,12 +211,14 @@ # push first arg mc.MOV_rr(edi.value, ebp.value) align = align_stack_words(1) + mc.SUB_ri(esp.value, (align - 1) * WORD) else: - mc.PUSH(RawStackLoc(WORD * 2)) - mc.PUSH_r(ebp.value) align = align_stack_words(3) + mc.MOV_rs(eax.value, WORD * 2) + mc.SUB_ri(esp.value, (align - 1) * WORD) + mc.MOV_sr(WORD, eax.value) + mc.MOV_sr(0, ebp.value) # align - mc.SUB_ri(esp.value, (align - 1) * WORD) mc.CALL(imm(self.cpu.realloc_frame)) mc.ADD_ri(esp.value, (align - 1) * WORD) From noreply at buildbot.pypy.org Mon Feb 11 10:29:19 2013 From: noreply at buildbot.pypy.org (krono) Date: Mon, 11 Feb 2013 10:29:19 +0100 (CET) Subject: [pypy-commit] pypy default: Enhance the dotviewer. Message-ID: <20130211092919.91FA81C11AD@cobra.cs.uni-duesseldorf.de> Author: Tobias Pape Branch: Changeset: r61070:0d0ae1254725 Date: 2013-01-25 16:39 +0100 http://bitbucket.org/pypy/pypy/changeset/0d0ae1254725/ Log: Enhance the dotviewer. - include Droid fonts (under Apache license) - allow for unicode by sending UTF-8 over the wire and force unicode decode on the other end - Make all text antialiased. It was already enabled unconditionally for the status bar and is now for the normal text, too. diff --git a/LICENSE b/LICENSE --- a/LICENSE +++ b/LICENSE @@ -270,3 +270,24 @@ LineBreak-*.txt UnicodeData-*.txt UnihanNumeric-*.txt + +License for 'dotviewer/font/' +============================= + +Copyright (C) 2008 The Android Open Source Project + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +Detailled license information is contained in the NOTICE file in the +directory. + diff --git a/dotviewer/VeraMoBd.ttf b/dotviewer/VeraMoBd.ttf deleted file mode 100644 Binary file dotviewer/VeraMoBd.ttf has changed diff --git a/dotviewer/cyrvetic.ttf b/dotviewer/cyrvetic.ttf deleted file mode 100644 Binary file dotviewer/cyrvetic.ttf has changed diff --git a/dotviewer/drawgraph.py b/dotviewer/drawgraph.py --- a/dotviewer/drawgraph.py +++ b/dotviewer/drawgraph.py @@ -10,8 +10,8 @@ this_dir = os.path.dirname(os.path.abspath(__file__)) -FONT = os.path.join(this_dir, 'cyrvetic.ttf') -FIXEDFONT = os.path.join(this_dir, 'VeraMoBd.ttf') +FONT = os.path.join(this_dir, 'font', 'DroidSans.ttf') +FIXEDFONT = os.path.join(this_dir, 'font', 'DroidSansMono.ttf') COLOR = { 'black': (0,0,0), 'white': (255,255,255), @@ -51,6 +51,12 @@ else: return default +def forceunicode(name): + return name if isinstance(name, unicode) else name.decode("utf-8") + +def forcestr(name): + return name if isinstance(name, str) else name.encode("utf-8") + class GraphLayout: fixedfont = False @@ -106,12 +112,12 @@ class Node: def __init__(self, name, x, y, w, h, label, style, shape, color, fillcolor): - self.name = name + self.name = forceunicode(name) self.x = float(x) self.y = float(y) self.w = float(w) self.h = float(h) - self.label = label + self.label = forceunicode(label) self.style = style self.shape = shape self.color = color @@ -125,8 +131,8 @@ label = None def __init__(self, nodes, tail, head, cnt, *rest): - self.tail = nodes[tail] - self.head = nodes[head] + self.tail = nodes[forceunicode(tail)] + self.head = nodes[forceunicode(head)] cnt = int(cnt) self.points = [(float(rest[i]), float(rest[i+1])) for i in range(0, cnt*2, 2)] @@ -655,11 +661,7 @@ part = parts[i] word = part[0] try: - try: - img = font.render(word, False, *part[1:]) - except pygame.error, e: - # Try *with* anti-aliasing to work around a bug in SDL - img = font.render(word, True, *part[1:]) + img = font.render(word, True, *part[1:]) except pygame.error: del parts[i] # Text has zero width else: diff --git a/dotviewer/font/DroidSans-Bold.ttf b/dotviewer/font/DroidSans-Bold.ttf new file mode 100644 index 0000000000000000000000000000000000000000..d065b64eb1863f83c2c982264f9442f2313a44a9 GIT binary patch [cut] diff --git a/dotviewer/font/DroidSans.ttf b/dotviewer/font/DroidSans.ttf new file mode 100644 index 0000000000000000000000000000000000000000..ad1efca88aed8d9e2d179f27dd713e2a1562fe5f GIT binary patch [cut] diff --git a/dotviewer/font/DroidSansMono.ttf b/dotviewer/font/DroidSansMono.ttf new file mode 100644 index 0000000000000000000000000000000000000000..a007071944f7c90020e798eea53b10065e2b45a5 GIT binary patch [cut] diff --git a/dotviewer/font/NOTICE b/dotviewer/font/NOTICE new file mode 100644 --- /dev/null +++ b/dotviewer/font/NOTICE @@ -0,0 +1,190 @@ + + Copyright (c) 2005-2008, The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + diff --git a/dotviewer/font/README.txt b/dotviewer/font/README.txt new file mode 100644 --- /dev/null +++ b/dotviewer/font/README.txt @@ -0,0 +1,18 @@ +Copyright (C) 2008 The Android Open Source Project + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +########## + +This directory contains the fonts for the platform. They are licensed +under the Apache 2 license. diff --git a/dotviewer/graphclient.py b/dotviewer/graphclient.py --- a/dotviewer/graphclient.py +++ b/dotviewer/graphclient.py @@ -33,8 +33,9 @@ def reload(graph_id): page = getpage(graph_id) if save_tmp_file: + from drawgraph import forcestr f = open(save_tmp_file, 'w') - f.write(page.source) + f.write(forcestr(page.source)) f.close() messages.extend(page_messages(page, graph_id)) send_graph_messages(io, messages) @@ -75,7 +76,8 @@ def page_messages(page, graph_id): import graphparse - return graphparse.parse_dot(graph_id, page.source, page.links, + from drawgraph import forcestr + return graphparse.parse_dot(graph_id, forcestr(page.source), page.links, getattr(page, 'fixedfont', False)) def send_graph_messages(io, messages): diff --git a/dotviewer/graphdisplay.py b/dotviewer/graphdisplay.py --- a/dotviewer/graphdisplay.py +++ b/dotviewer/graphdisplay.py @@ -4,7 +4,7 @@ from pygame.locals import * from drawgraph import GraphRenderer, FIXEDFONT from drawgraph import Node, Edge -from drawgraph import EventQueue, wait_for_events +from drawgraph import EventQueue, wait_for_events, forceunicode, forcestr METAKEYS = dict([ @@ -285,7 +285,7 @@ if e.key == K_ESCAPE: return None elif e.key == K_RETURN: - return text.encode('latin-1') # XXX do better + return forcestr(text) # return utf-8 encoded elif e.key == K_BACKSPACE: text = text[:-1] elif e.unicode and ord(e.unicode) >= ord(' '): @@ -423,7 +423,7 @@ self.layout.request_reload() def setstatusbar(self, text, fgcolor=None, bgcolor=None): - info = (text, fgcolor or self.STATUSBAR_FGCOLOR, bgcolor or self.STATUSBAR_BGCOLOR) + info = (forceunicode(text), fgcolor or self.STATUSBAR_FGCOLOR, bgcolor or self.STATUSBAR_BGCOLOR) if info != self.statusbarinfo: self.statusbarinfo = info self.must_redraw = True @@ -711,7 +711,7 @@ lines = [] while words: line = words.pop(0) - img = font.render(line or ' ', 1, fgcolor) + img = font.render(line or ' ', True, fgcolor) while words: longerline = line + ' ' + words[0] longerimg = font.render(longerline, 1, fgcolor) @@ -723,7 +723,7 @@ img = longerimg w, h = img.get_size() if h > maxheight: - img = font.render('...', 1, overflowcolor) + img = font.render('...', True, overflowcolor) w, h = img.get_size() while lines and h > maxheight: maxheight += lines.pop().get_size()[1] diff --git a/dotviewer/graphpage.py b/dotviewer/graphpage.py --- a/dotviewer/graphpage.py +++ b/dotviewer/graphpage.py @@ -44,6 +44,7 @@ class DotFileGraphPage(GraphPage): def compute(self, dotfile): + from drawgraph import forceunicode f = open(dotfile, 'r') - self.source = f.read() + self.source = forceunicode(f.read()) f.close() From noreply at buildbot.pypy.org Mon Feb 11 10:29:20 2013 From: noreply at buildbot.pypy.org (krono) Date: Mon, 11 Feb 2013 10:29:20 +0100 (CET) Subject: [pypy-commit] pypy default: Fix dotviewer translation test Message-ID: <20130211092920.DDE961C11AD@cobra.cs.uni-duesseldorf.de> Author: Tobias Pape Branch: Changeset: r61071:c0cda5df2cc0 Date: 2013-01-25 16:59 +0100 http://bitbucket.org/pypy/pypy/changeset/c0cda5df2cc0/ Log: Fix dotviewer translation test diff --git a/dotviewer/test/test_translator.py b/dotviewer/test/test_translator.py --- a/dotviewer/test/test_translator.py +++ b/dotviewer/test/test_translator.py @@ -22,6 +22,6 @@ def test_annotated(): from rpython.translator.interactive import Translation - t = Translation(is_prime) - t.annotate([int]) + t = Translation(is_prime, [int]) + t.annotate() t.viewcg() From noreply at buildbot.pypy.org Mon Feb 11 10:29:22 2013 From: noreply at buildbot.pypy.org (krono) Date: Mon, 11 Feb 2013 10:29:22 +0100 (CET) Subject: [pypy-commit] pypy default: add missing tests. factor magic constant into RAW_ENCODING Message-ID: <20130211092922.1499F1C11AD@cobra.cs.uni-duesseldorf.de> Author: Tobias Pape Branch: Changeset: r61072:3df200e8f904 Date: 2013-01-28 11:07 +0100 http://bitbucket.org/pypy/pypy/changeset/3df200e8f904/ Log: add missing tests. factor magic constant into RAW_ENCODING diff --git a/dotviewer/drawgraph.py b/dotviewer/drawgraph.py --- a/dotviewer/drawgraph.py +++ b/dotviewer/drawgraph.py @@ -9,6 +9,7 @@ from pygame.locals import * +RAW_ENCODING = "utf-8" this_dir = os.path.dirname(os.path.abspath(__file__)) FONT = os.path.join(this_dir, 'font', 'DroidSans.ttf') FIXEDFONT = os.path.join(this_dir, 'font', 'DroidSansMono.ttf') @@ -52,10 +53,10 @@ return default def forceunicode(name): - return name if isinstance(name, unicode) else name.decode("utf-8") + return name if isinstance(name, unicode) else name.decode(RAW_ENCODING) def forcestr(name): - return name if isinstance(name, str) else name.encode("utf-8") + return name if isinstance(name, str) else name.encode(RAW_ENCODING) class GraphLayout: diff --git a/dotviewer/graphdisplay.py b/dotviewer/graphdisplay.py --- a/dotviewer/graphdisplay.py +++ b/dotviewer/graphdisplay.py @@ -285,7 +285,7 @@ if e.key == K_ESCAPE: return None elif e.key == K_RETURN: - return forcestr(text) # return utf-8 encoded + return forcestr(text) # return encoded unicode elif e.key == K_BACKSPACE: text = text[:-1] elif e.unicode and ord(e.unicode) >= ord(' '): diff --git a/dotviewer/graphpage.py b/dotviewer/graphpage.py --- a/dotviewer/graphpage.py +++ b/dotviewer/graphpage.py @@ -44,7 +44,8 @@ class DotFileGraphPage(GraphPage): def compute(self, dotfile): - from drawgraph import forceunicode - f = open(dotfile, 'r') - self.source = forceunicode(f.read()) + import codecs + from drawgraph import RAW_ENCODING + f = codecs.open(dotfile, 'r', RAW_ENCODING) + self.source = f.read() f.close() diff --git a/dotviewer/test/test_interactive_unicode.py b/dotviewer/test/test_interactive_unicode.py new file mode 100755 --- /dev/null +++ b/dotviewer/test/test_interactive_unicode.py @@ -0,0 +1,103 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +import py +import sys, os, signal, thread, time, codecs +from dotviewer.conftest import option +from dotviewer.drawgraph import RAW_ENCODING + +SOURCE1 = u"""digraph G{ +λ -> b +b -> μ +} +""" + +FILENAME = 'graph1.dot' + +def setup_module(mod): + if not option.pygame: + py.test.skip("--pygame not enabled") + udir = py.path.local.make_numbered_dir(prefix='usession-dot-', keep=3) + f = codecs.open(str(udir.join(FILENAME)), 'wb', RAW_ENCODING) + f.write(SOURCE1) + f.close() + + from dotviewer import graphclient + mod.pkgdir = py.path.local(graphclient.this_dir) + mod.udir = udir + + try: + del os.environ['GRAPHSERVER'] + except KeyError: + pass + + +def test_dotviewer(): + print "=== dotviewer.py %s" % FILENAME + err = os.system('"%s" "%s"' % (pkgdir.join('dotviewer.py'), + udir.join(FILENAME))) + assert err == 0 + + plain_name = FILENAME.replace('.dot','.plain') + + os.system('dot -Tplain "%s" > "%s"' % (udir.join(FILENAME), + udir.join(plain_name))) + print "=== dotviewer.py %s" % plain_name + err = os.system('"%s" "%s"' % (pkgdir.join('dotviewer.py'), + udir.join(plain_name))) + assert err == 0 + +def test_display_dot_file(): + from dotviewer.graphclient import display_dot_file + print "=== display_dot_file(%s) with GRAPHSERVER=%s" % ( + FILENAME, os.environ.get('GRAPHSERVER', ''),) + display_dot_file(udir.join(FILENAME)) + print "=== display_dot_file finished" + + +def test_graphserver(): + import socket + s = socket.socket() + s.listen(1) + host, port = s.getsockname() # pick a random free port + s.close() + + if hasattr(sys, 'pypy_objspaceclass'): + python = 'python' + else: + python = sys.executable + + cmdargs = [python, str(pkgdir.join('graphserver.py')), + str(port)] + print '* starting:', ' '.join(cmdargs) + pid = os.spawnv(os.P_NOWAIT, cmdargs[0], cmdargs) + try: + time.sleep(1) # hack - wait a bit to make sure the server is up + os.environ['GRAPHSERVER'] = '%s:%d' % (host, port) + try: + test_display_dot_file() + finally: + del os.environ['GRAPHSERVER'] + finally: + os.kill(pid, signal.SIGTERM) + +def test_colors(): + from dotviewer import graphpage, graphclient + class MyPage(graphpage.DotFileGraphPage): + def compute(self, dotfile): + super(MyPage, self).compute(dotfile) + self.links = {'v2721': 'Hello world', + 'v2720': ('Something green', (0, 192, 0)), + } + dotfile = str(udir.join(FILENAME)) + page = MyPage(dotfile) + graphclient.display_page(page) + +def test_fixedfont(): + from dotviewer import graphpage, graphclient + class MyPage(graphpage.DotFileGraphPage): + fixedfont = True + dotfile = str(udir.join(FILENAME)) + page = MyPage(dotfile) + page.fixedfont = True + graphclient.display_page(page) diff --git a/dotviewer/test/test_unicode_util.py b/dotviewer/test/test_unicode_util.py new file mode 100755 --- /dev/null +++ b/dotviewer/test/test_unicode_util.py @@ -0,0 +1,57 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +import py +import codecs +from dotviewer.drawgraph import RAW_ENCODING, forcestr, forceunicode + +SOURCE1 = u"""digraph G{ +λ -> b +b -> μ +} +""" + +FILENAME = 'test.dot' + +class TestUnicodeUtil(object): + + def test_idempotent(self): + x = u"a" + assert forceunicode(forcestr(x)) == x + + x = u"λ" + assert forceunicode(forcestr(x)) == x + + assert forceunicode(forcestr(SOURCE1)) == SOURCE1 + + x = "a" + assert forcestr(forceunicode(x)) == x + + # utf-8 encoded. + # fragile, does not consider RAW_ENCODING + # x = "\xef\xbb\xbf\xce\xbb" + # assert forcestr(forceunicode(x)) == x + + def test_does_not_double_encode(self): + x = u"λ" + x_e = forcestr(x) + assert forcestr(x_e) == x_e + + x_u = forceunicode(x_e) + assert forceunicode(x_u) == x_u + + def test_file(self): + udir = py.path.local.make_numbered_dir(prefix='usession-dot-', keep=3) + full_filename = str(udir.join(FILENAME)) + f = codecs.open(full_filename, 'wb', RAW_ENCODING) + f.write(SOURCE1) + f.close() + + with open(full_filename) as f1: + assert forceunicode(f1.read()) == SOURCE1 + + f3 = codecs.open(full_filename, 'r', RAW_ENCODING) + c = f3.read() + f3.close() + result = (c == SOURCE1) + assert result From noreply at buildbot.pypy.org Mon Feb 11 10:29:37 2013 From: noreply at buildbot.pypy.org (krono) Date: Mon, 11 Feb 2013 10:29:37 +0100 (CET) Subject: [pypy-commit] pypy default: merge Message-ID: <20130211092937.6EDE01C11AD@cobra.cs.uni-duesseldorf.de> Author: Tobias Pape Branch: Changeset: r61073:348090133694 Date: 2013-01-28 11:18 +0100 http://bitbucket.org/pypy/pypy/changeset/348090133694/ Log: merge diff too long, truncating to 2000 out of 144316 lines diff --git a/py/_code/source.py b/py/_code/source.py --- a/py/_code/source.py +++ b/py/_code/source.py @@ -141,6 +141,8 @@ trysource = self[start:end] if trysource.isparseable(): return start, end + if end == start + 100: # XXX otherwise, it takes forever + break # XXX if end is None: raise IndexError("no valid source range around line %d " % (lineno,)) return start, end diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst --- a/pypy/doc/whatsnew-head.rst +++ b/pypy/doc/whatsnew-head.rst @@ -34,6 +34,9 @@ .. branch: kill-faking .. branch: improved_ebnfparse_error .. branch: task-decorator +.. branch: fix-e4fa0b2 +.. branch: win32-fixes +.. branch: fix-version-tool .. branch: release-2.0-beta1 diff --git a/pypy/interpreter/app_main.py b/pypy/interpreter/app_main.py --- a/pypy/interpreter/app_main.py +++ b/pypy/interpreter/app_main.py @@ -713,13 +713,13 @@ def pypy_find_stdlib(s): from os.path import abspath, join, dirname as dn thisfile = abspath(__file__) - root = dn(dn(dn(dn(thisfile)))) + root = dn(dn(dn(thisfile))) return [join(root, 'lib-python', '2.7'), join(root, 'lib_pypy')] def pypy_resolvedirof(s): # we ignore the issue of symlinks; for tests, the executable is always - # translator/goal/app_main.py anyway + # interpreter/app_main.py anyway import os return os.path.abspath(os.path.join(s, '..')) diff --git a/pypy/interpreter/test2/test_app_main.py b/pypy/interpreter/test2/test_app_main.py --- a/pypy/interpreter/test2/test_app_main.py +++ b/pypy/interpreter/test2/test_app_main.py @@ -547,7 +547,7 @@ assert line.rstrip() == 'Not at all. They could be carried.' print 'A five ounce bird could not carry a one pound coconut.' """) - py_py = os.path.join(pypydir, 'bin', 'py.py') + py_py = os.path.join(pypydir, 'bin', 'pyinteractive.py') child = self._spawn(sys.executable, [py_py, '-S', path]) child.expect('Are you suggesting coconuts migrate?', timeout=120) child.sendline('Not at all. They could be carried.') @@ -774,7 +774,7 @@ assert data == p + os.sep + '\n' def test_getfilesystemencoding(self): - py.test.skip("this has been failing since forever, but it's not tested nightly because buildbot uses python2.6 :-(") + py.test.skip("encoding is only set if stdout.isatty(), test is flawed") if sys.version_info < (2, 7): skip("test requires Python >= 2.7") p = getscript_in_dir(""" @@ -881,7 +881,6 @@ def test_setup_bootstrap_path(self): import sys - import os old_sys_path = sys.path[:] sys.path.append(self.goal_dir) try: @@ -907,7 +906,7 @@ sys.path.append(self.goal_dir) try: import app_main - pypy_c = os.path.join(self.trunkdir, 'pypy', 'translator', 'goal', 'pypy-c') + pypy_c = os.path.join(self.trunkdir, 'pypy', 'goal', 'pypy-c') app_main.setup_bootstrap_path(pypy_c) newpath = sys.path[:] # we get at least lib_pypy @@ -925,7 +924,7 @@ sys.path.append(self.goal_dir) try: import app_main - pypy_c = os.path.join(self.trunkdir, 'pypy', 'translator', 'goal', 'pypy-c') + pypy_c = os.path.join(self.trunkdir, 'pypy', 'goal', 'pypy-c') app_main.entry_point(pypy_c, [self.foo_py]) # assert it did not crash finally: diff --git a/pypy/interpreter/test2/test_targetpypy.py b/pypy/interpreter/test2/test_targetpypy.py --- a/pypy/interpreter/test2/test_targetpypy.py +++ b/pypy/interpreter/test2/test_targetpypy.py @@ -1,5 +1,3 @@ - -import py from pypy.goal.targetpypystandalone import get_entry_point from pypy.config.pypyoption import get_pypy_config @@ -7,6 +5,4 @@ def test_run(self): config = get_pypy_config(translating=False) entry_point = get_entry_point(config)[0] - space = self.space - py.test.skip("not working so far") entry_point(['pypy-c' , '-S', '-c', 'print 3']) diff --git a/pypy/module/_ffi/test/test_funcptr.py b/pypy/module/_ffi/test/test_funcptr.py --- a/pypy/module/_ffi/test/test_funcptr.py +++ b/pypy/module/_ffi/test/test_funcptr.py @@ -96,7 +96,7 @@ libm = CDLL(self.libm_name) pow_addr = libm.getaddressindll('pow') fff = sys.maxint*2-1 - if sys.platform == 'win32': + if sys.platform == 'win32' or sys.platform == 'darwin': fff = sys.maxint*2+1 assert pow_addr == self.pow_addr & fff diff --git a/pypy/module/_file/test/test_file.py b/pypy/module/_file/test/test_file.py --- a/pypy/module/_file/test/test_file.py +++ b/pypy/module/_file/test/test_file.py @@ -430,7 +430,7 @@ assert f.subclass_closed def test_readline_unbuffered_should_read_one_line_only(self): - import posix + import os with self.file(self.temppath, 'w') as f: f.write('foo\nbar\n') @@ -438,7 +438,7 @@ with self.file(self.temppath, 'r', 0) as f: s = f.readline() assert s == 'foo\n' - s = posix.read(f.fileno(), 10) + s = os.read(f.fileno(), 10) assert s == 'bar\n' def test_flush_at_exit(): diff --git a/pypy/module/_file/test/test_file_extra.py b/pypy/module/_file/test/test_file_extra.py --- a/pypy/module/_file/test/test_file_extra.py +++ b/pypy/module/_file/test/test_file_extra.py @@ -612,6 +612,7 @@ repr(unicode(self.temptestfile))) f.close() + @py.test.mark.skipif("os.name != 'posix'") def test_EAGAIN(self): import _socket, posix s1, s2 = _socket.socketpair() diff --git a/pypy/module/_io/test/test_fileio.py b/pypy/module/_io/test/test_fileio.py --- a/pypy/module/_io/test/test_fileio.py +++ b/pypy/module/_io/test/test_fileio.py @@ -2,7 +2,7 @@ import os class AppTestFileIO: - spaceconfig = dict(usemodules=['_io']) + spaceconfig = dict(usemodules=['_io'] + (['fcntl'] if os.name != 'nt' else [])) def setup_class(cls): tmpfile = udir.join('tmpfile') diff --git a/pypy/module/cpyext/test/test_cpyext.py b/pypy/module/cpyext/test/test_cpyext.py --- a/pypy/module/cpyext/test/test_cpyext.py +++ b/pypy/module/cpyext/test/test_cpyext.py @@ -49,6 +49,8 @@ kwds["libraries"] = [api_library] # '%s' undefined; assuming extern returning int kwds["compile_extra"] = ["/we4013"] + elif sys.platform == 'darwin': + kwds["link_files"] = [str(api_library + '.dylib')] else: kwds["link_files"] = [str(api_library + '.so')] if sys.platform.startswith('linux'): diff --git a/pypy/module/rctime/test/test_rctime.py b/pypy/module/rctime/test/test_rctime.py --- a/pypy/module/rctime/test/test_rctime.py +++ b/pypy/module/rctime/test/test_rctime.py @@ -114,7 +114,10 @@ assert rctime.mktime(rctime.localtime(-1)) == -1 res = rctime.mktime((2000, 1, 1, 0, 0, 0, -1, -1, -1)) - assert rctime.ctime(res) == 'Sat Jan 1 00:00:00 2000' + if os.name == 'nt': + assert rctime.ctime(res) == 'Sat Jan 01 00:00:00 2000' + else: + assert rctime.ctime(res) == 'Sat Jan 1 00:00:00 2000' def test_asctime(self): import time as rctime @@ -213,7 +216,7 @@ def test_strftime(self): import time as rctime - import os + import os, sys t = rctime.time() tt = rctime.gmtime(t) @@ -234,6 +237,10 @@ # input to [w]strftime is not kosher. if os.name == 'nt': raises(ValueError, rctime.strftime, '%f') + elif sys.platform == 'darwin': + # darwin strips % of unknown format codes + # http://bugs.python.org/issue9811 + assert rctime.strftime('%f') == 'f' else: assert rctime.strftime('%f') == '%f' diff --git a/pypy/module/signal/__init__.py b/pypy/module/signal/__init__.py --- a/pypy/module/signal/__init__.py +++ b/pypy/module/signal/__init__.py @@ -30,9 +30,10 @@ } def buildloaders(cls): - from pypy.module.signal import interp_signal - for name in interp_signal.signal_names: - signum = getattr(interp_signal, name) + from rpython.rlib import rsignal + + for name in rsignal.signal_names: + signum = getattr(rsignal, name) if signum is not None: Module.interpleveldefs[name] = 'space.wrap(%d)' % (signum,) super(Module, cls).buildloaders() diff --git a/pypy/module/signal/interp_signal.py b/pypy/module/signal/interp_signal.py --- a/pypy/module/signal/interp_signal.py +++ b/pypy/module/signal/interp_signal.py @@ -1,25 +1,27 @@ from __future__ import with_statement + +import signal as cpy_signal +import sys + from pypy.interpreter.error import OperationError, exception_from_errno -from pypy.interpreter.executioncontext import AsyncAction, AbstractActionFlag -from pypy.interpreter.executioncontext import PeriodicAsyncAction +from pypy.interpreter.executioncontext import (AsyncAction, AbstractActionFlag, + PeriodicAsyncAction) from pypy.interpreter.gateway import unwrap_spec -import signal as cpy_signal -from rpython.rtyper.lltypesystem import lltype, rffi -from rpython.rtyper.tool import rffi_platform -from rpython.translator.tool.cbuild import ExternalCompilationInfo -from rpython.conftest import cdir -import py -import sys + from rpython.rlib import jit, rposix from rpython.rlib.rarithmetic import intmask from rpython.rlib.rsignal import * +from rpython.rtyper.lltypesystem import lltype, rffi + WIN32 = sys.platform == 'win32' + class SignalActionFlag(AbstractActionFlag): # This class uses the C-level pypysig_counter variable as the tick # counter. The C-level signal handler will reset it to -1 whenever - # a signal is received. + # a signal is received. This causes CheckSignalAction.perform() to + # be called. def get_ticker(self): p = pypysig_getaddr_occurred() @@ -47,45 +49,40 @@ def __init__(self, space): AsyncAction.__init__(self, space) self.handlers_w = {} - if space.config.objspace.usemodules.thread: - # need a helper action in case signals arrive in a non-main thread - self.pending_signals = {} - self.reissue_signal_action = ReissueSignalAction(space) - else: - self.reissue_signal_action = None + self.emulated_sigint = False @jit.dont_look_inside def perform(self, executioncontext, frame): - while True: - n = pypysig_poll() - if n < 0: - break - self.perform_signal(executioncontext, n) - - @jit.dont_look_inside - def perform_signal(self, executioncontext, n): - if self.reissue_signal_action is None: - # no threads: we can report the signal immediately - self.report_signal(n) + if self.space.config.objspace.usemodules.thread: + main_ec = self.space.threadlocals.getmainthreadvalue() + in_main = executioncontext is main_ec else: - main_ec = self.space.threadlocals.getmainthreadvalue() - if executioncontext is main_ec: - # running in the main thread: we can report the - # signal immediately - self.report_signal(n) - else: - # running in another thread: we need to hack a bit - self.pending_signals[n] = None - self.reissue_signal_action.fire_after_thread_switch() + in_main = True + # If we are in the main thread, poll and report the signals now. + if in_main: + if self.emulated_sigint: + self.emulated_sigint = False + self._report_signal(cpy_signal.SIGINT) + while True: + n = pypysig_poll() + if n < 0: + break + self._report_signal(n) + else: + # Otherwise, don't call pypysig_poll() at all. Instead, + # arrange for perform() to be called again after a thread + # switch. It might be called again and again, until we + # land in the main thread. + self.fire_after_thread_switch() @jit.dont_look_inside def set_interrupt(self): "Simulates the effect of a SIGINT signal arriving" ec = self.space.getexecutioncontext() - self.perform_signal(ec, cpy_signal.SIGINT) + self.emulated_sigint = True + self.perform(ec, None) - @jit.dont_look_inside - def report_signal(self, n): + def _report_signal(self, n): try: w_handler = self.handlers_w[n] except KeyError: @@ -100,39 +97,6 @@ w_frame = space.wrap(ec.gettopframe_nohidden()) space.call_function(w_handler, space.wrap(n), w_frame) - @jit.dont_look_inside - def report_pending_signals(self): - # XXX this logic isn't so complicated but I have no clue how - # to test it :-( - pending_signals = self.pending_signals.keys() - self.pending_signals.clear() - try: - while pending_signals: - self.report_signal(pending_signals.pop()) - finally: - # in case of exception, put the undelivered signals back - # into the dict instead of silently swallowing them - if pending_signals: - for n in pending_signals: - self.pending_signals[n] = None - self.reissue_signal_action.fire() - - -class ReissueSignalAction(AsyncAction): - """A special action to help deliver signals to the main thread. If - a non-main thread caught a signal, this action fires after every - thread switch until we land in the main thread. - """ - - def perform(self, executioncontext, frame): - main_ec = self.space.threadlocals.getmainthreadvalue() - if executioncontext is main_ec: - # now running in the main thread: we can really report the signals - self.space.check_signal_action.report_pending_signals() - else: - # still running in some other thread: try again later - self.fire_after_thread_switch() - @unwrap_spec(signum=int) def getsignal(space, signum): @@ -154,6 +118,7 @@ return action.handlers_w[signum] return space.wrap(SIG_DFL) + def default_int_handler(space, w_signum, w_frame): """ default_int_handler(...) @@ -164,22 +129,26 @@ raise OperationError(space.w_KeyboardInterrupt, space.w_None) + @jit.dont_look_inside @unwrap_spec(timeout=int) def alarm(space, timeout): return space.wrap(c_alarm(timeout)) + @jit.dont_look_inside def pause(space): c_pause() return space.w_None + def check_signum_exists(space, signum): if signum in signal_values: return raise OperationError(space.w_ValueError, space.wrap("invalid signal value")) + def check_signum_in_range(space, signum): if 1 <= signum < NSIG: return @@ -201,7 +170,7 @@ A signal handler function is called with two arguments: the first is the signal number, the second is the interrupted stack frame. """ - ec = space.getexecutioncontext() + ec = space.getexecutioncontext() main_ec = space.threadlocals.getmainthreadvalue() old_handler = getsignal(space, signum) @@ -224,13 +193,14 @@ action.handlers_w[signum] = w_handler return old_handler + @jit.dont_look_inside @unwrap_spec(fd=int) def set_wakeup_fd(space, fd): """Sets the fd to be written to (with '\0') when a signal comes in. Returns the old fd. A library can use this to wakeup select or poll. The previous fd is returned. - + The fd must be non-blocking. """ if space.config.objspace.usemodules.thread: @@ -243,6 +213,7 @@ old_fd = pypysig_set_wakeup_fd(fd) return space.wrap(intmask(old_fd)) + @jit.dont_look_inside @unwrap_spec(signum=int, flag=int) def siginterrupt(space, signum, flag): @@ -258,33 +229,38 @@ rffi.setintfield(timeval, 'c_tv_sec', int(d)) rffi.setintfield(timeval, 'c_tv_usec', int((d - int(d)) * 1000000)) + def double_from_timeval(tv): return rffi.getintfield(tv, 'c_tv_sec') + ( rffi.getintfield(tv, 'c_tv_usec') / 1000000.0) + def itimer_retval(space, val): w_value = space.wrap(double_from_timeval(val.c_it_value)) w_interval = space.wrap(double_from_timeval(val.c_it_interval)) return space.newtuple([w_value, w_interval]) + class Cache: def __init__(self, space): self.w_itimererror = space.new_exception_class("signal.ItimerError", space.w_IOError) + def get_itimer_error(space): return space.fromcache(Cache).w_itimererror + @jit.dont_look_inside @unwrap_spec(which=int, first=float, interval=float) def setitimer(space, which, first, interval=0): """setitimer(which, seconds[, interval]) - Sets given itimer (one of ITIMER_REAL, ITIMER_VIRTUAL + or ITIMER_PROF) to fire after value seconds and after that every interval seconds. The itimer can be cleared by setting seconds to zero. - + Returns old values as a tuple: (delay, interval). """ with lltype.scoped_alloc(itimervalP.TO, 1) as new: @@ -298,14 +274,14 @@ if ret != 0: raise exception_from_errno(space, get_itimer_error(space)) + return itimer_retval(space, old[0]) - return itimer_retval(space, old[0]) @jit.dont_look_inside @unwrap_spec(which=int) def getitimer(space, which): """getitimer(which) - + Returns current value of given itimer. """ with lltype.scoped_alloc(itimervalP.TO, 1) as old: diff --git a/pypy/module/signal/test/test_signal.py b/pypy/module/signal/test/test_signal.py --- a/pypy/module/signal/test/test_signal.py +++ b/pypy/module/signal/test/test_signal.py @@ -36,7 +36,7 @@ class AppTestSignal: spaceconfig = { - "usemodules": ['signal', 'rctime'], + "usemodules": ['signal', 'rctime'] + (['fcntl'] if os.name != 'nt' else []), } def setup_class(cls): @@ -157,6 +157,8 @@ if sys.platform == 'win32': raises(ValueError, signal, 42, lambda *args: None) raises(ValueError, signal, 7, lambda *args: None) + elif sys.platform == 'darwin': + raises(ValueError, signal, 42, lambda *args: None) else: signal(42, lambda *args: None) signal(42, SIG_DFL) diff --git a/pypy/module/sys/version.py b/pypy/module/sys/version.py --- a/pypy/module/sys/version.py +++ b/pypy/module/sys/version.py @@ -28,8 +28,9 @@ import pypy pypydir = os.path.dirname(os.path.abspath(pypy.__file__)) +pypyroot = os.path.dirname(pypydir) del pypy -from pypy.tool.version import get_repo_version_info +from rpython.tool.version import get_repo_version_info import time as t gmtime = t.gmtime() @@ -68,7 +69,7 @@ CPYTHON_VERSION[0], CPYTHON_VERSION[1], CPYTHON_VERSION[2], - get_repo_version_info()[2], + get_repo_version_info(root=pypyroot)[1], date, time, ver, @@ -91,10 +92,10 @@ return space.wrap(('PyPy', '', '')) def get_repo_info(space): - info = get_repo_version_info() + info = get_repo_version_info(root=pypyroot) if info: - project, repo_tag, repo_version = info - return space.newtuple([space.wrap(project), + repo_tag, repo_version = info + return space.newtuple([space.wrap('PyPy'), space.wrap(repo_tag), space.wrap(repo_version)]) else: diff --git a/pypy/module/sys/vm.py b/pypy/module/sys/vm.py --- a/pypy/module/sys/vm.py +++ b/pypy/module/sys/vm.py @@ -95,7 +95,7 @@ def exc_info_with_tb(space): operror = space.getexecutioncontext().sys_exc_info() if operror is None: - return space.newtuple([space.w_None,space.w_None,space.w_None]) + return space.newtuple([space.w_None, space.w_None, space.w_None]) else: return space.newtuple([operror.w_type, operror.get_w_value(space), space.wrap(operror.get_traceback())]) diff --git a/pypy/module/thread/os_local.py b/pypy/module/thread/os_local.py --- a/pypy/module/thread/os_local.py +++ b/pypy/module/thread/os_local.py @@ -98,5 +98,5 @@ local = wref() if local is not None: del local.dicts[ec] - local.last_dict = None - local.last_ec = None + local.last_dict = None + local.last_ec = None diff --git a/pypy/module/thread/test/test_thread.py b/pypy/module/thread/test/test_thread.py --- a/pypy/module/thread/test/test_thread.py +++ b/pypy/module/thread/test/test_thread.py @@ -220,16 +220,24 @@ import signal def f(): - time.sleep(0.5) - thread.interrupt_main() + for x in range(50): + if waiting: + thread.interrupt_main() + return + print 'tock...', x # <-force the GIL to be released, as + time.sleep(0.01) # time.sleep doesn't do non-translated def busy_wait(): - for x in range(1000): + waiting.append(None) + for x in range(100): print 'tick...', x # <-force the GIL to be released, as time.sleep(0.01) # time.sleep doesn't do non-translated + waiting.pop() # This is normally called by app_main.py signal.signal(signal.SIGINT, signal.default_int_handler) - thread.start_new_thread(f, ()) - raises(KeyboardInterrupt, busy_wait) + for i in range(100): + waiting = [] + thread.start_new_thread(f, ()) + raises(KeyboardInterrupt, busy_wait) diff --git a/pypy/module/unicodedata/interp_ucd.py b/pypy/module/unicodedata/interp_ucd.py --- a/pypy/module/unicodedata/interp_ucd.py +++ b/pypy/module/unicodedata/interp_ucd.py @@ -9,7 +9,7 @@ from rpython.rlib.objectmodel import we_are_translated from rpython.rlib.runicode import MAXUNICODE from rpython.rlib.unicodedata import unicodedb_5_2_0, unicodedb_3_2_0 -from rpython.rlib.runicode import code_to_unichr, ORD +from rpython.rlib.runicode import code_to_unichr, ord_accepts_surrogate import sys @@ -28,8 +28,6 @@ # handling: on narrow unicode builds, a surrogate pair is considered as one # unicode code point. -# The functions below are subtly different from the ones in runicode.py. -# When PyPy implements Python 3 they should be merged. if MAXUNICODE > 0xFFFF: # Target is wide build @@ -41,7 +39,7 @@ if not we_are_translated() and sys.maxunicode == 0xFFFF: # Host CPython is narrow build, accept surrogates try: - return ORD(space.unicode_w(w_unichr)) + return ord_accepts_surrogate(space.unicode_w(w_unichr)) except ValueError: raise OperationError(space.w_TypeError, space.wrap( 'need a single Unicode character as parameter')) @@ -68,7 +66,7 @@ else: # Accept surrogates try: - return ORD(space.unicode_w(w_unichr)) + return ord_accepts_surrogate(space.unicode_w(w_unichr)) except ValueError: raise OperationError(space.w_TypeError, space.wrap( 'need a single Unicode character as parameter')) diff --git a/pypy/tool/jitlogparser/parser.py b/pypy/tool/jitlogparser/parser.py --- a/pypy/tool/jitlogparser/parser.py +++ b/pypy/tool/jitlogparser/parser.py @@ -215,6 +215,7 @@ _lineset = None is_bytecode = False inline_level = None + bytecode_name = None # factory method TraceForOpcode = TraceForOpcode @@ -244,23 +245,29 @@ return ",".join([str(len(v)) for v in stack]) def append_to_res(bc): - if not stack: - stack.append([]) - else: - if bc.inline_level is not None and bc.inline_level + 1 != len(stack): - if bc.inline_level < len(stack): + if bc.inline_level is not None: + if bc.inline_level == len(stack) - 1: + pass + elif bc.inline_level > len(stack) - 1: + stack.append([]) + else: + while bc.inline_level + 1 < len(stack): last = stack.pop() stack[-1].append(cls(last, getpath(stack), storage)) - else: - stack.append([]) stack[-1].append(bc) so_far = [] stack = [] + nothing_yet = True for op in operations: if op.name == 'debug_merge_point': if so_far: - append_to_res(cls.TraceForOpcode(so_far, storage, loopname)) + opc = cls.TraceForOpcode(so_far, storage, loopname) + if nothing_yet: + nothing_yet = False + for i in xrange(opc.inline_level + 1): + stack.append([]) + append_to_res(opc) if limit: break so_far = [] diff --git a/pypy/tool/jitlogparser/test/test_parser.py b/pypy/tool/jitlogparser/test/test_parser.py --- a/pypy/tool/jitlogparser/test/test_parser.py +++ b/pypy/tool/jitlogparser/test/test_parser.py @@ -354,3 +354,25 @@ f = Function.from_operations(loop.operations, LoopStorage()) assert f.chunks[-1].filename == 'x.py' assert f.filename is None + +def test_parse_2_levels_up(): + loop = parse(""" + [] + debug_merge_point(0, 0, 'one') + debug_merge_point(1, 0, 'two') + debug_merge_point(2, 0, 'three') + debug_merge_point(0, 0, 'one') + """) + f = Function.from_operations(loop.operations, LoopStorage()) + assert len(f.chunks) == 3 + +def test_parse_from_inside(): + loop = parse(""" + [] + debug_merge_point(1, 0, 'two') + debug_merge_point(2, 0, 'three') + debug_merge_point(0, 0, 'one') + """) + f = Function.from_operations(loop.operations, LoopStorage()) + assert len(f.chunks) == 2 + diff --git a/pypy/tool/release/package.py b/pypy/tool/release/package.py --- a/pypy/tool/release/package.py +++ b/pypy/tool/release/package.py @@ -1,6 +1,6 @@ #!/usr/bin/env python """ A sample script that packages PyPy, provided that it's already built. -It uses 'pypy/translator/goal/pypy-c' and parts of the rest of the working +It uses 'pypy/goal/pypy-c' and parts of the rest of the working copy. Usage: package.py root-pypy-dir [name-of-archive] [name-of-pypy-c] [destination-for-tarball] [pypy-c-path] @@ -13,7 +13,7 @@ import sys import os #Add toplevel repository dir to sys.path -sys.path.insert(0,os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(__file__))))) +sys.path.insert(0,os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))))) import py import fnmatch from rpython.tool.udir import udir diff --git a/pypy/tool/release/test/test_package.py b/pypy/tool/release/test/test_package.py --- a/pypy/tool/release/test/test_package.py +++ b/pypy/tool/release/test/test_package.py @@ -15,7 +15,7 @@ basename = 'pypy-c' rename_pypy_c = 'pypy' exe_name_in_archive = 'bin/pypy' - pypy_c = py.path.local(pypydir).join('..', basename) + pypy_c = py.path.local(pypydir).join('goal', basename) if not pypy_c.check(): os.system("echo faked_pypy_c> %s" % (pypy_c,)) pypy_c.chmod(0755) diff --git a/pypy/tool/rundictbenchmarks.py b/pypy/tool/rundictbenchmarks.py --- a/pypy/tool/rundictbenchmarks.py +++ b/pypy/tool/rundictbenchmarks.py @@ -3,7 +3,7 @@ # this file runs some benchmarks with a pypy-c that is assumed to be # built using the MeasuringDictImplementation. -# it should be run with pypy/translator/goal as the cwd, and you'll +# it should be run with pypy/goal as the cwd, and you'll # need to hack a copy of rst2html for yourself (svn docutils # required). diff --git a/pypy/tool/test/test_version.py b/pypy/tool/test/test_version.py deleted file mode 100644 --- a/pypy/tool/test/test_version.py +++ /dev/null @@ -1,24 +0,0 @@ -import os, sys -import py -from pypy.tool.version import get_repo_version_info, _get_hg_archive_version - -def test_hg_archival_version(tmpdir): - def version_for(name, **kw): - path = tmpdir.join(name) - path.write('\n'.join('%s: %s' % x for x in kw.items())) - return _get_hg_archive_version(str(path)) - - assert version_for('release', - tag='release-123', - node='000', - ) == ('PyPy', 'release-123', '000') - assert version_for('somebranch', - node='000', - branch='something', - ) == ('PyPy', 'something', '000') - - -def test_get_repo_version_info(): - assert get_repo_version_info(None) - assert get_repo_version_info(os.devnull) == ('PyPy', '?', '?') - assert get_repo_version_info(sys.executable) == ('PyPy', '?', '?') diff --git a/pypy/tool/version.py b/pypy/tool/version.py deleted file mode 100644 --- a/pypy/tool/version.py +++ /dev/null @@ -1,141 +0,0 @@ -import py -import os -from subprocess import Popen, PIPE -import pypy -pypydir = os.path.dirname(os.path.abspath(pypy.__file__)) -pypyroot = os.path.dirname(pypydir) -default_retval = 'PyPy', '?', '?' - -def maywarn(err, repo_type='Mercurial'): - if not err: - return - - from rpython.tool.ansi_print import ansi_log - log = py.log.Producer("version") - py.log.setconsumer("version", ansi_log) - log.WARNING('Errors getting %s information: %s' % (repo_type, err)) - -def get_repo_version_info(hgexe=None): - '''Obtain version information by invoking the 'hg' or 'git' commands.''' - - # Try to see if we can get info from Git if hgexe is not specified. - if not hgexe: - if os.path.isdir(os.path.join(pypyroot, '.git')): - return _get_git_version() - - # Fallback to trying Mercurial. - if hgexe is None: - hgexe = py.path.local.sysfind('hg') - - if os.path.isfile(os.path.join(pypyroot, '.hg_archival.txt')): - return _get_hg_archive_version(os.path.join(pypyroot, '.hg_archival.txt')) - elif not os.path.isdir(os.path.join(pypyroot, '.hg')): - maywarn('Not running from a Mercurial repository!') - return default_retval - elif not hgexe: - maywarn('Cannot find Mercurial command!') - return default_retval - else: - return _get_hg_version(hgexe) - - -def _get_hg_version(hgexe): - env = dict(os.environ) - # get Mercurial into scripting mode - env['HGPLAIN'] = '1' - # disable user configuration, extensions, etc. - env['HGRCPATH'] = os.devnull - - try: - p = Popen([str(hgexe), 'version', '-q'], - stdout=PIPE, stderr=PIPE, env=env) - except OSError, e: - maywarn(e) - return default_retval - - if not p.stdout.read().startswith('Mercurial Distributed SCM'): - maywarn('command does not identify itself as Mercurial') - return default_retval - - p = Popen([str(hgexe), 'id', '-i', pypyroot], - stdout=PIPE, stderr=PIPE, env=env) - hgid = p.stdout.read().strip() - maywarn(p.stderr.read()) - if p.wait() != 0: - hgid = '?' - - p = Popen([str(hgexe), 'id', '-t', pypyroot], - stdout=PIPE, stderr=PIPE, env=env) - hgtags = [t for t in p.stdout.read().strip().split() if t != 'tip'] - maywarn(p.stderr.read()) - if p.wait() != 0: - hgtags = ['?'] - - if hgtags: - return 'PyPy', hgtags[0], hgid - else: - # use the branch instead - p = Popen([str(hgexe), 'id', '-b', pypyroot], - stdout=PIPE, stderr=PIPE, env=env) - hgbranch = p.stdout.read().strip() - maywarn(p.stderr.read()) - - return 'PyPy', hgbranch, hgid - - -def _get_hg_archive_version(path): - fp = open(path) - try: - data = dict(x.split(': ', 1) for x in fp.read().splitlines()) - finally: - fp.close() - if 'tag' in data: - return 'PyPy', data['tag'], data['node'] - else: - return 'PyPy', data['branch'], data['node'] - - -def _get_git_version(): - #XXX: this function is a untested hack, - # so the git mirror tav made will work - gitexe = py.path.local.sysfind('git') - if not gitexe: - return default_retval - - try: - p = Popen( - [str(gitexe), 'rev-parse', 'HEAD'], - stdout=PIPE, stderr=PIPE, cwd=pypyroot - ) - except OSError, e: - maywarn(e, 'Git') - return default_retval - if p.wait() != 0: - maywarn(p.stderr.read(), 'Git') - return default_retval - revision_id = p.stdout.read().strip()[:12] - p = Popen( - [str(gitexe), 'describe', '--tags', '--exact-match'], - stdout=PIPE, stderr=PIPE, cwd=pypyroot - ) - if p.wait() != 0: - p = Popen( - [str(gitexe), 'branch'], stdout=PIPE, stderr=PIPE, - cwd=pypyroot - ) - if p.wait() != 0: - maywarn(p.stderr.read(), 'Git') - return 'PyPy', '?', revision_id - branch = '?' - for line in p.stdout.read().strip().split('\n'): - if line.startswith('* '): - branch = line[1:].strip() - if branch == '(no branch)': - branch = '?' - break - return 'PyPy', branch, revision_id - return 'PyPy', p.stdout.read().strip(), revision_id - - -if __name__ == '__main__': - print get_repo_version_info() diff --git a/rpython/annotator/builtin.py b/rpython/annotator/builtin.py --- a/rpython/annotator/builtin.py +++ b/rpython/annotator/builtin.py @@ -79,7 +79,7 @@ s_item = s_ImpossibleValue else: nonneg = False # so far - if step > 0: + if step > 0 or s_step.nonneg: nonneg = s_start.nonneg elif step < 0: nonneg = s_stop.nonneg or (s_stop.is_constant() and diff --git a/rpython/annotator/test/test_annrpython.py b/rpython/annotator/test/test_annrpython.py --- a/rpython/annotator/test/test_annrpython.py +++ b/rpython/annotator/test/test_annrpython.py @@ -2694,6 +2694,23 @@ assert isinstance(s, annmodel.SomeInteger) assert s.nonneg + def test_range_nonneg_variablestep(self): + def get_step(n): + if n == 1: + return 2 + else: + return 3 + def fun(n, k): + step = get_step(n) + for i in range(0, n, step): + if k == 17: + return i + return 0 + a = self.RPythonAnnotator() + s = a.build_types(fun, [int, int]) + assert isinstance(s, annmodel.SomeInteger) + assert s.nonneg + def test_reverse_range_nonneg(self): def fun(n, k): for i in range(n-1, -1, -1): @@ -3254,6 +3271,7 @@ a = self.RPythonAnnotator() s = a.build_types(f, [str]) assert isinstance(s, annmodel.SomeString) + assert s.no_nul def f(x): return u'a'.replace(x, u'b') diff --git a/rpython/annotator/unaryop.py b/rpython/annotator/unaryop.py --- a/rpython/annotator/unaryop.py +++ b/rpython/annotator/unaryop.py @@ -509,7 +509,7 @@ return getbookkeeper().newlist(s_item) def method_replace(str, s1, s2): - return str.basestringclass() + return str.basestringclass(no_nul=str.no_nul and s2.no_nul) def getslice(str, s_start, s_stop): check_negative_slice(s_start, s_stop) diff --git a/rpython/jit/backend/llgraph/llimpl.py b/rpython/jit/backend/llgraph/llimpl.py deleted file mode 100644 --- a/rpython/jit/backend/llgraph/llimpl.py +++ /dev/null @@ -1,1968 +0,0 @@ -""" -The non-RPythonic part of the llgraph backend. -This contains all the code that is directly run -when executing on top of the llinterpreter. -""" - -import weakref -from rpython.flowspace.model import Variable, Constant -from rpython.annotator import model as annmodel -from rpython.jit.metainterp.history import REF, INT, FLOAT -from rpython.jit.metainterp import history -from rpython.jit.codewriter import heaptracker -from rpython.rtyper.lltypesystem import lltype, llmemory, rclass, rstr, rffi -from rpython.rtyper.ootypesystem import ootype -from rpython.rtyper.module.support import LLSupport, OOSupport -from rpython.rtyper.llinterp import LLException -from rpython.rtyper.extregistry import ExtRegistryEntry - -from rpython.jit.metainterp import resoperation -from rpython.jit.metainterp.resoperation import rop -from rpython.jit.backend.llgraph import symbolic -from rpython.jit.codewriter import longlong -from rpython.jit.codewriter.effectinfo import EffectInfo - -from rpython.rlib.objectmodel import ComputedIntSymbolic, we_are_translated -from rpython.rlib.rarithmetic import ovfcheck -from rpython.rlib.rarithmetic import r_longlong, r_ulonglong, r_uint -from rpython.rlib.rtimer import read_timestamp - -import py -from rpython.tool.ansi_print import ansi_log -log = py.log.Producer('runner') -py.log.setconsumer('runner', ansi_log) - -IS_32_BIT = r_ulonglong is not r_uint - - -def _from_opaque(opq): - return opq._obj.externalobj - -_TO_OPAQUE = {} - -def _to_opaque(value): - try: - return value._the_opaque_pointer - except AttributeError: - op = lltype.opaqueptr(_TO_OPAQUE[value.__class__], 'opaque', - externalobj=value) - value._the_opaque_pointer = op - return op - -def _normalize(value): - if isinstance(value, lltype._ptr): - value = lltype.top_container(value._obj) - return value - -def from_opaque_string(s): - if isinstance(s, str): - return s - elif isinstance(s, ootype._string): - return OOSupport.from_rstr(s) - else: - return LLSupport.from_rstr(s) - -FLOAT_ARRAY_TP = lltype.Ptr(lltype.Array(lltype.Float, hints={"nolength": True})) -def maybe_uncast(TP, array): - if array._TYPE.TO.OF != lltype.Float: - # array._TYPE.TO._hints.get("uncast_on_llgraph"): - array = rffi.cast(TP, array) - return array - -# a list of argtypes of all operations - couldn't find any and it's -# very useful. Note however that the table is half-broken here and -# there, in ways that are sometimes a bit hard to fix; that's why -# it is not "official". -TYPES = { - 'int_add' : (('int', 'int'), 'int'), - 'int_sub' : (('int', 'int'), 'int'), - 'int_mul' : (('int', 'int'), 'int'), - 'int_floordiv' : (('int', 'int'), 'int'), - 'int_mod' : (('int', 'int'), 'int'), - 'int_and' : (('int', 'int'), 'int'), - 'int_or' : (('int', 'int'), 'int'), - 'int_xor' : (('int', 'int'), 'int'), - 'int_lshift' : (('int', 'int'), 'int'), - 'int_rshift' : (('int', 'int'), 'int'), - 'int_lt' : (('int', 'int'), 'bool'), - 'int_gt' : (('int', 'int'), 'bool'), - 'int_ge' : (('int', 'int'), 'bool'), - 'int_le' : (('int', 'int'), 'bool'), - 'int_eq' : (('int', 'int'), 'bool'), - 'int_ne' : (('int', 'int'), 'bool'), - 'int_is_true' : (('int',), 'bool'), - 'int_is_zero' : (('int',), 'bool'), - 'int_neg' : (('int',), 'int'), - 'int_invert' : (('int',), 'int'), - 'int_add_ovf' : (('int', 'int'), 'int'), - 'int_sub_ovf' : (('int', 'int'), 'int'), - 'int_mul_ovf' : (('int', 'int'), 'int'), - 'int_force_ge_zero':(('int',), 'int'), - 'uint_add' : (('int', 'int'), 'int'), - 'uint_sub' : (('int', 'int'), 'int'), - 'uint_mul' : (('int', 'int'), 'int'), - 'uint_lt' : (('int', 'int'), 'bool'), - 'uint_le' : (('int', 'int'), 'bool'), - 'uint_eq' : (('int', 'int'), 'bool'), - 'uint_ne' : (('int', 'int'), 'bool'), - 'uint_gt' : (('int', 'int'), 'bool'), - 'uint_ge' : (('int', 'int'), 'bool'), - 'uint_xor' : (('int', 'int'), 'int'), - 'uint_rshift' : (('int', 'int'), 'int'), - 'uint_floordiv' : (('int', 'int'), 'int'), - 'float_add' : (('float', 'float'), 'float'), - 'float_sub' : (('float', 'float'), 'float'), - 'float_mul' : (('float', 'float'), 'float'), - 'float_truediv' : (('float', 'float'), 'float'), - 'float_lt' : (('float', 'float'), 'bool'), - 'float_le' : (('float', 'float'), 'bool'), - 'float_eq' : (('float', 'float'), 'bool'), - 'float_ne' : (('float', 'float'), 'bool'), - 'float_gt' : (('float', 'float'), 'bool'), - 'float_ge' : (('float', 'float'), 'bool'), - 'float_neg' : (('float',), 'float'), - 'float_abs' : (('float',), 'float'), - 'cast_float_to_int':(('float',), 'int'), - 'cast_int_to_float':(('int',), 'float'), - 'same_as' : (('int',), 'int'), # could also be ptr=>ptr - 'new_with_vtable' : (('ref',), 'ref'), - 'new' : ((), 'ref'), - 'new_array' : (('int',), 'ref'), - 'oois' : (('ref', 'ref'), 'bool'), - 'ooisnot' : (('ref', 'ref'), 'bool'), - 'instanceof' : (('ref',), 'bool'), - 'subclassof' : (('ref', 'ref'), 'bool'), - 'runtimenew' : (('ref',), 'ref'), - 'setfield_gc' : (('ref', 'intorptr'), None), - 'getfield_gc' : (('ref',), 'intorptr'), - 'getfield_gc_pure': (('ref',), 'intorptr'), - 'setfield_raw' : (('ref', 'intorptr'), None), - 'getfield_raw' : (('ref',), 'intorptr'), - 'getfield_raw_pure': (('ref',), 'intorptr'), - 'setarrayitem_gc' : (('ref', 'int', 'intorptr'), None), - 'getarrayitem_gc' : (('ref', 'int'), 'intorptr'), - 'getarrayitem_gc_pure' : (('ref', 'int'), 'intorptr'), - 'setarrayitem_raw' : (('ref', 'int', 'intorptr'), None), - 'getarrayitem_raw' : (('ref', 'int'), 'intorptr'), - 'getarrayitem_raw_pure' : (('ref', 'int'), 'intorptr'), - 'arraylen_gc' : (('ref',), 'int'), - 'call' : (('ref', 'varargs'), 'intorptr'), - 'call_assembler' : (('varargs',), 'intorptr'), - 'cond_call_gc_wb' : (('ptr', 'ptr'), None), - 'cond_call_gc_wb_array': (('ptr', 'int', 'ptr'), None), - 'oosend' : (('varargs',), 'intorptr'), - 'oosend_pure' : (('varargs',), 'intorptr'), - 'guard_true' : (('bool',), None), - 'guard_false' : (('bool',), None), - 'guard_value' : (('int', 'int'), None), - 'guard_class' : (('ref', 'ref'), None), - 'guard_no_exception' : ((), None), - 'guard_exception' : (('ref',), 'ref'), - 'guard_no_overflow' : ((), None), - 'guard_overflow' : ((), None), - 'guard_nonnull' : (('ref',), None), - 'guard_isnull' : (('ref',), None), - 'guard_nonnull_class' : (('ref', 'ref'), None), - 'newstr' : (('int',), 'ref'), - 'strlen' : (('ref',), 'int'), - 'strgetitem' : (('ref', 'int'), 'int'), - 'strsetitem' : (('ref', 'int', 'int'), None), - 'newunicode' : (('int',), 'ref'), - 'unicodelen' : (('ref',), 'int'), - 'unicodegetitem' : (('ref', 'int'), 'int'), - 'unicodesetitem' : (('ref', 'int', 'int'), 'int'), - 'cast_ptr_to_int' : (('ref',), 'int'), - 'cast_int_to_ptr' : (('int',), 'ref'), - 'debug_merge_point': (('ref', 'int', 'int'), None), - 'force_token' : ((), 'int'), - 'call_may_force' : (('int', 'varargs'), 'intorptr'), - 'guard_not_forced': ((), None), -} - -# ____________________________________________________________ - -class CompiledLoop(object): - has_been_freed = False - invalid = False - - def __init__(self): - self.inputargs = [] - self.operations = [] - - def getargtypes(self): - return [v.concretetype for v in self.inputargs] - - def __repr__(self): - lines = [] - self.as_text(lines, 1) - return 'CompiledLoop %s:\n%s' % (self.inputargs, '\n'.join(lines)) - - def as_text(self, lines, indent): - for op in self.operations: - lines.append('\t'*indent + repr(op)) - -class Operation(object): - result = None - descr = None - jump_target = None - fail_args = None - - def __init__(self, opnum): - self.opnum = opnum - self.args = [] - - def __repr__(self): - if self.result is not None: - sres = repr0(self.result) + ' = ' - else: - sres = '' - return '{%s%s(%s)}' % (sres, self.getopname(), - ', '.join(map(repr0, self.args))) - - def getopname(self): - try: - return resoperation.opname[self.opnum] - except KeyError: - return '<%d>' % self.opnum - - def is_guard(self): - return rop._GUARD_FIRST <= self.opnum <= rop._GUARD_LAST - - def is_final(self): - return rop._FINAL_FIRST <= self.opnum <= rop._FINAL_LAST - -def repr0(x): - if isinstance(x, list): - return '[' + ', '.join(repr0(y) for y in x) + ']' - elif isinstance(x, Constant): - return '(' + repr0(x.value) + ')' - elif isinstance(x, lltype._ptr): - x = llmemory.cast_ptr_to_adr(x) - if x.ptr: - try: - container = x.ptr._obj._normalizedcontainer() - return '* %s' % (container._TYPE._short_name(),) - except AttributeError: - return repr(x) - else: - return 'NULL' - else: - return repr(x) - -def repr_list(lst, types): - res_l = [] - if types and types[-1] == 'varargs': - types = types[:-1] + ('int',) * (len(lst) - len(types) + 1) - assert len(types) == len(lst) - for elem, tp in zip(lst, types): - if isinstance(elem, Constant): - res_l.append('(%s)' % repr1(elem, tp)) - else: - res_l.append(repr1(elem, tp)) - return '[%s]' % (', '.join(res_l)) - -def repr1(x, tp): - if tp == "intorptr": - TYPE = lltype.typeOf(x) - if isinstance(TYPE, lltype.Ptr) and TYPE.TO._gckind == 'gc': - tp = "ref" - else: - tp = "int" - if tp == 'int': - return str(x) - elif tp == 'void': - return '---' - elif tp == 'ref': - if not x: - return '(* None)' - if isinstance(x, int): - # XXX normalize? - ptr = str(llmemory.cast_int_to_adr(x)) - elif isinstance(ootype.typeOf(x), ootype.OOType): - return repr(x) - else: - if getattr(x, '_fake', None): - return repr(x) - if lltype.typeOf(x) == llmemory.GCREF: - TP = lltype.Ptr(lltype.typeOf(x._obj.container)) - ptr = lltype.cast_opaque_ptr(TP, x) - else: - ptr = x - try: - container = ptr._obj._normalizedcontainer() - return '(* %s)' % (container._TYPE._short_name(),) - except AttributeError: - return '(%r)' % (ptr,) - elif tp == 'bool': - assert x == 0 or x == 1 - return str(bool(x)) - #elif tp == 'fieldname': - # return str(symbolic.TokenToField[x...][1]) - elif tp == 'float': - return str(x) - else: - raise NotImplementedError("tp = %s" % tp) - -_variables = [] - -def compile_start(): - del _variables[:] - return _to_opaque(CompiledLoop()) - -def mark_as_free(loop): - loop = _from_opaque(loop) - assert not loop.has_been_freed - loop.has_been_freed = True - -def compile_start_int_var(loop): - return compile_start_ref_var(loop, lltype.Signed) - -def compile_start_float_var(loop): - return compile_start_ref_var(loop, longlong.FLOATSTORAGE) - -def compile_start_ref_var(loop, TYPE): - loop = _from_opaque(loop) - assert not loop.operations - v = Variable() - v.concretetype = TYPE - loop.inputargs.append(v) - r = len(_variables) - _variables.append(v) - return r - -def compile_started_vars(clt): - if not hasattr(clt, '_debug_argtypes'): # only when compiling the loop - argtypes = [v.concretetype for v in _variables] - try: - clt._debug_argtypes = argtypes - except AttributeError: # when 'clt' is actually a translated - pass # GcStruct - -def compile_add(loop, opnum): - loop = _from_opaque(loop) - loop.operations.append(Operation(opnum)) - -def compile_add_descr(loop, ofs, type, arg_types, extrainfo, width): - from rpython.jit.backend.llgraph.runner import Descr - loop = _from_opaque(loop) - op = loop.operations[-1] - assert isinstance(type, str) and len(type) == 1 - op.descr = Descr(ofs, type, arg_types=arg_types, extrainfo=extrainfo, width=width) - -def compile_add_descr_arg(loop, ofs, type, arg_types): - from rpython.jit.backend.llgraph.runner import Descr - loop = _from_opaque(loop) - op = loop.operations[-1] - assert isinstance(type, str) and len(type) == 1 - op.args.append(Descr(ofs, type, arg_types=arg_types)) - -def compile_add_loop_token(loop, descr): - if we_are_translated(): - raise ValueError("CALL_ASSEMBLER not supported") - loop = _from_opaque(loop) - op = loop.operations[-1] - op.descr = weakref.ref(descr) - -TARGET_TOKENS = weakref.WeakKeyDictionary() - -def compile_add_target_token(loop, descr, clt): - # here, 'clt' is the compiled_loop_token of the original loop that - # we are compiling - loop = _from_opaque(loop) - op = loop.operations[-1] - descrobj = _normalize(descr) - TARGET_TOKENS[descrobj] = loop, len(loop.operations), op.args, clt - -def compile_add_var(loop, intvar): - loop = _from_opaque(loop) - op = loop.operations[-1] - op.args.append(_variables[intvar]) - -def compile_add_int_const(loop, value): - compile_add_ref_const(loop, value, lltype.Signed) - -def compile_add_float_const(loop, value): - compile_add_ref_const(loop, value, longlong.FLOATSTORAGE) - -def compile_add_ref_const(loop, value, TYPE): - loop = _from_opaque(loop) - const = Constant(value) - const.concretetype = TYPE - op = loop.operations[-1] - op.args.append(const) - -def compile_add_int_result(loop): - return compile_add_ref_result(loop, lltype.Signed) - -def compile_add_float_result(loop): - return compile_add_ref_result(loop, longlong.FLOATSTORAGE) - -def compile_add_ref_result(loop, TYPE): - loop = _from_opaque(loop) - v = Variable() - v.concretetype = TYPE - op = loop.operations[-1] - op.result = v - r = len(_variables) - _variables.append(v) - return r - -def compile_add_jump_target(loop, targettoken, source_clt): - loop = _from_opaque(loop) - descrobj = _normalize(targettoken) - (loop_target, target_opindex, target_inputargs, target_clt - ) = TARGET_TOKENS[descrobj] - # - try: - assert source_clt._debug_argtypes == target_clt._debug_argtypes - except AttributeError: # when translated - pass - # - op = loop.operations[-1] - op.jump_target = loop_target - op.jump_target_opindex = target_opindex - op.jump_target_inputargs = target_inputargs - assert op.opnum == rop.JUMP - assert [v.concretetype for v in op.args] == ( - [v.concretetype for v in target_inputargs]) - # - if loop_target == loop: - log.info("compiling new loop") - else: - log.info("compiling new bridge") - -def compile_add_guard_jump_target(loop, loop_target): - loop = _from_opaque(loop) - loop_target = _from_opaque(loop_target) - op = loop.operations[-1] - assert op.is_guard() - op.jump_target = loop_target - -def compile_add_fail(loop, fail_index): - loop = _from_opaque(loop) - index = len(loop.operations)-1 - op = loop.operations[index] - op.fail_index = fail_index - return index - -def compile_add_fail_arg(loop, intvar): - loop = _from_opaque(loop) - op = loop.operations[-1] - if op.fail_args is None: - op.fail_args = [] - if intvar == -1: - op.fail_args.append(None) - else: - op.fail_args.append(_variables[intvar]) - -def compile_redirect_fail(old_loop, old_index, new_loop): - old_loop = _from_opaque(old_loop) - new_loop = _from_opaque(new_loop) - guard_op = old_loop.operations[old_index] - assert guard_op.is_guard() - guard_op.jump_target = new_loop - # check that the bridge's inputargs are of the correct number and - # kind for the guard - if guard_op.fail_args is not None: - argkinds = [v.concretetype for v in guard_op.fail_args if v] - else: - argkinds = [] - assert argkinds == [v.concretetype for v in new_loop.inputargs] - -# ------------------------------ - -class Frame(object): - OPHANDLERS = [None] * (rop._LAST+1) - - def __init__(self, cpu): - self.verbose = False - self.cpu = cpu - self.opindex = 1 - self._forced = False - self._may_force = -1 - - def getenv(self, v): - from rpython.jit.backend.llgraph.runner import Descr - if isinstance(v, Constant): - return v.value - elif isinstance(v, Descr): - return v - else: - return self.env[v] - - def _populate_fail_args(self, op, skip=None): - fail_args = [] - if op.fail_args: - for fail_arg in op.fail_args: - if fail_arg is None: - fail_args.append(None) - elif fail_arg is skip: - fail_args.append(fail_arg.concretetype._defl()) - else: - fail_args.append(self.getenv(fail_arg)) - self.fail_args = fail_args - self.fail_index = op.fail_index - - def execute(self): - """Execute all operations in a loop, - possibly following to other loops as well. - """ - global _last_exception - assert _last_exception is None, "exception left behind" - verbose = True - self.opindex = 0 - while True: - assert not self.loop.has_been_freed - op = self.loop.operations[self.opindex] - args = [self.getenv(v) for v in op.args] - if not op.is_final(): - try: - result = self.execute_operation(op.opnum, args, op.descr, - verbose) - except GuardFailed: - assert op.is_guard() - _stats.exec_conditional_jumps += 1 - if op.jump_target is not None: - # a patched guard, pointing to further code - if op.fail_args: - args = [self.getenv(v) for v in op.fail_args if v] - else: - args = [] - assert len(op.jump_target.inputargs) == len(args) - self.env = dict(zip(op.jump_target.inputargs, args)) - self.loop = op.jump_target - self.opindex = 0 - continue - else: - self._populate_fail_args(op) - # a non-patched guard - if self.verbose: - log.trace('failed: %s' % ( - ', '.join(map(str, fail_args)),)) - return op.fail_index - #verbose = self.verbose - assert (result is None) == (op.result is None) - if op.result is not None: - RESTYPE = op.result.concretetype - if RESTYPE is lltype.Signed: - x = self.as_int(result) - elif RESTYPE is llmemory.GCREF: - x = self.as_ptr(result) - elif RESTYPE is ootype.Object: - x = self.as_object(result) - elif RESTYPE is longlong.FLOATSTORAGE: - x = self.as_floatstorage(result) - else: - raise Exception("op.result.concretetype is %r" - % (RESTYPE,)) - self.env[op.result] = x - self.opindex += 1 - continue - if op.opnum == rop.JUMP: - inputargs = op.jump_target_inputargs - assert len(inputargs) == len(args) - self.env = dict(zip(inputargs, args)) - self.loop = op.jump_target - self.opindex = op.jump_target_opindex - _stats.exec_jumps += 1 - elif op.opnum == rop.FINISH: - if self.verbose: - log.trace('finished: %s' % ( - ', '.join(map(str, args)),)) - self.fail_args = args - return op.fail_index - - else: - assert 0, "unknown final operation %d" % (op.opnum,) - - def execute_operation(self, opnum, values, descr, verbose): - """Execute a single operation. - """ - ophandler = self.OPHANDLERS[opnum] - if ophandler is None: - self._define_impl(opnum) - ophandler = self.OPHANDLERS[opnum] - assert ophandler is not None, "missing impl for op %d" % opnum - opname = resoperation.opname[opnum].lower() - exec_counters = _stats.exec_counters - exec_counters[opname] = exec_counters.get(opname, 0) + 1 - for i in range(len(values)): - if isinstance(values[i], ComputedIntSymbolic): - values[i] = values[i].compute_fn() - res = NotImplemented - try: - res = ophandler(self, descr, *values) - finally: - if 0: # if verbose: - argtypes, restype = TYPES[opname] - if res is None: - resdata = '' - elif res is NotImplemented: - resdata = '*fail*' - else: - resdata = '-> ' + repr1(res, restype) - # fish the types - log.cpu('\t%s %s %s' % (opname, repr_list(values, argtypes), - resdata)) - return res - - def as_int(self, x): - return cast_to_int(x) - - def as_ptr(self, x): - return cast_to_ptr(x) - - def as_object(self, x): - return ootype.cast_to_object(x) - - def as_floatstorage(self, x): - return cast_to_floatstorage(x) - - def log_progress(self): - count = sum(_stats.exec_counters.values()) - count_jumps = _stats.exec_jumps - log.trace('ran %d operations, %d jumps' % (count, count_jumps)) - - # ---------- - - @classmethod - def _define_impl(cls, opnum): - opname = resoperation.opname[opnum] - try: - op = getattr(cls, 'op_' + opname.lower()) # op_guard_true etc. - except AttributeError: - try: - impl = globals()['do_' + opname.lower()] # do_arraylen_gc etc. - def op(self, descr, *args): - if descr is None: - return impl(*args) - else: - return impl(descr, *args) - except KeyError: - op = cls._make_impl_from_blackhole_interp(opname) - cls.OPHANDLERS[opnum] = op - - @classmethod - def _make_impl_from_blackhole_interp(cls, opname): - from rpython.jit.metainterp.blackhole import BlackholeInterpreter - name = 'bhimpl_' + opname.lower() - func = BlackholeInterpreter.__dict__[name] - for argtype in func.argtypes: - assert argtype in ('i', 'r', 'f') - # - def _op_default_implementation(self, descr, *args): - # for all operations implemented in the blackhole interpreter - return func(*args) - # - return _op_default_implementation - - def op_label(self, _, *args): - op = self.loop.operations[self.opindex] - assert op.opnum == rop.LABEL - assert len(op.args) == len(args) - newenv = {} - for v, value in zip(op.args, args): - newenv[v] = value - self.env = newenv - - def op_debug_merge_point(self, _, *args): - from rpython.jit.metainterp.warmspot import get_stats - try: - stats = get_stats() - except AttributeError: - pass - else: - stats.add_merge_point_location(args[1:]) - pass - - def op_guard_true(self, _, value): - if not value: - raise GuardFailed - - def op_guard_false(self, _, value): - if value: - raise GuardFailed - - op_guard_nonnull = op_guard_true - op_guard_isnull = op_guard_false - - def op_guard_class(self, _, value, expected_class): - value = lltype.cast_opaque_ptr(rclass.OBJECTPTR, value) - expected_class = llmemory.cast_adr_to_ptr( - llmemory.cast_int_to_adr(expected_class), - rclass.CLASSTYPE) - if value.typeptr != expected_class: - raise GuardFailed - - def op_guard_nonnull_class(self, _, value, expected_class): - if not value: - raise GuardFailed - self.op_guard_class(_, value, expected_class) - - def op_guard_value(self, _, value, expected_value): - if value != expected_value: - raise GuardFailed - - def op_guard_no_exception(self, _): - if _last_exception: - raise GuardFailed - - def _check_exception(self, expected_exception): - global _last_exception - expected_exception = self._cast_exception(expected_exception) - assert expected_exception - exc = _last_exception - if exc: - got = exc.args[0] - # exact match! - if got != expected_exception: - return False - return True - else: - return False - - def _cast_exception(self, exception): - return llmemory.cast_adr_to_ptr( - llmemory.cast_int_to_adr(exception), - rclass.CLASSTYPE) - - def _issubclass(self, cls1, cls2): - return rclass.ll_issubclass(cls1, cls2) - - def op_guard_exception(self, _, expected_exception): - global _last_exception - if not self._check_exception(expected_exception): - raise GuardFailed - res = _last_exception[1] - _last_exception = None - return res - - def op_guard_no_overflow(self, _): - flag = self.overflow_flag - del self.overflow_flag - if flag: - raise GuardFailed - - def op_guard_overflow(self, _): - flag = self.overflow_flag - del self.overflow_flag - if not flag: - raise GuardFailed - - def op_int_add_ovf(self, _, x, y): - try: - z = ovfcheck(x + y) - except OverflowError: - ovf = True - z = 0 - else: - ovf = False - self.overflow_flag = ovf - return z - - def op_int_sub_ovf(self, _, x, y): - try: - z = ovfcheck(x - y) - except OverflowError: - ovf = True - z = 0 - else: - ovf = False - self.overflow_flag = ovf - return z - - def op_int_mul_ovf(self, _, x, y): - try: - z = ovfcheck(x * y) - except OverflowError: - ovf = True - z = 0 - else: - ovf = False - self.overflow_flag = ovf - return z - - def op_keepalive(self, _, x): - pass - - # ---------- - # delegating to the builtins do_xxx() (done automatically for simple cases) - - def op_getarrayitem_gc(self, arraydescr, array, index): - if arraydescr.typeinfo == REF: - return do_getarrayitem_gc_ptr(array, index) - elif arraydescr.typeinfo == INT: - return do_getarrayitem_gc_int(array, index) - elif arraydescr.typeinfo == FLOAT: - return do_getarrayitem_gc_float(array, index) - else: - raise NotImplementedError - - op_getarrayitem_gc_pure = op_getarrayitem_gc - - def op_getarrayitem_raw(self, arraydescr, array, index): - if arraydescr.typeinfo == REF: - raise NotImplementedError("getarrayitem_raw -> gcref") - elif arraydescr.typeinfo == INT: - return do_getarrayitem_raw_int(array, index, arraydescr.ofs) - elif arraydescr.typeinfo == FLOAT: - return do_getarrayitem_raw_float(array, index) - else: - raise NotImplementedError - - op_getarrayitem_raw_pure = op_getarrayitem_raw - - def op_getfield_gc(self, fielddescr, struct): - if fielddescr.typeinfo == REF: - return do_getfield_gc_ptr(struct, fielddescr.ofs) - elif fielddescr.typeinfo == INT: - return do_getfield_gc_int(struct, fielddescr.ofs) - elif fielddescr.typeinfo == FLOAT: - return do_getfield_gc_float(struct, fielddescr.ofs) - else: - raise NotImplementedError - - op_getfield_gc_pure = op_getfield_gc - - def op_getfield_raw(self, fielddescr, struct): - if fielddescr.typeinfo == REF: - return do_getfield_raw_ptr(struct, fielddescr.ofs) - elif fielddescr.typeinfo == INT: - return do_getfield_raw_int(struct, fielddescr.ofs) - elif fielddescr.typeinfo == FLOAT: - return do_getfield_raw_float(struct, fielddescr.ofs) - else: - raise NotImplementedError - - op_getfield_raw_pure = op_getfield_raw - - def op_raw_store(self, arraydescr, addr, offset, value): - if arraydescr.typeinfo == REF: - raise AssertionError("cannot store GC pointer in raw storage") - elif arraydescr.typeinfo == INT: - do_raw_store_int(addr, offset, arraydescr.ofs, value) - elif arraydescr.typeinfo == FLOAT: - do_raw_store_float(addr, offset, value) - else: - raise NotImplementedError - - def op_raw_load(self, arraydescr, addr, offset): - if arraydescr.typeinfo == REF: - raise AssertionError("cannot store GC pointer in raw storage") - elif arraydescr.typeinfo == INT: - return do_raw_load_int(addr, offset, arraydescr.ofs) - elif arraydescr.typeinfo == FLOAT: - return do_raw_load_float(addr, offset) - else: - raise NotImplementedError - - def op_new(self, size): - return do_new(size.ofs) - - def op_new_with_vtable(self, descr, vtable): - assert descr is None - descr = heaptracker.vtable2descr(self.cpu, vtable) - result = do_new(descr.ofs) - value = lltype.cast_opaque_ptr(rclass.OBJECTPTR, result) - value.typeptr = cast_from_int(rclass.CLASSTYPE, vtable) - return result - - def op_setarrayitem_gc(self, arraydescr, array, index, newvalue): - if arraydescr.typeinfo == REF: - do_setarrayitem_gc_ptr(array, index, newvalue) - elif arraydescr.typeinfo == INT: - do_setarrayitem_gc_int(array, index, newvalue) - elif arraydescr.typeinfo == FLOAT: - do_setarrayitem_gc_float(array, index, newvalue) - else: - raise NotImplementedError - - def op_setarrayitem_raw(self, arraydescr, array, index, newvalue): - if arraydescr.typeinfo == REF: - raise NotImplementedError("setarrayitem_raw <- gcref") - elif arraydescr.typeinfo == INT: - do_setarrayitem_raw_int(array, index, newvalue, arraydescr.ofs) - elif arraydescr.typeinfo == FLOAT: - do_setarrayitem_raw_float(array, index, newvalue) - else: - raise NotImplementedError - - def op_getinteriorfield_gc(self, descr, array, index): - if descr.typeinfo == REF: - return do_getinteriorfield_gc_ptr(array, index, descr.ofs) - elif descr.typeinfo == INT: - return do_getinteriorfield_gc_int(array, index, descr.ofs) - elif descr.typeinfo == FLOAT: - return do_getinteriorfield_gc_float(array, index, descr.ofs) - else: - raise NotImplementedError - - def op_getinteriorfield_raw(self, descr, array, index): - if descr.typeinfo == REF: - return do_getinteriorfield_raw_ptr(array, index, descr.width, descr.ofs) - elif descr.typeinfo == INT: - return do_getinteriorfield_raw_int(array, index, descr.width, descr.ofs) - elif descr.typeinfo == FLOAT: - return do_getinteriorfield_raw_float(array, index, descr.width, descr.ofs) - else: - raise NotImplementedError - - def op_setinteriorfield_gc(self, descr, array, index, newvalue): - if descr.typeinfo == REF: - return do_setinteriorfield_gc_ptr(array, index, descr.ofs, - newvalue) - elif descr.typeinfo == INT: - return do_setinteriorfield_gc_int(array, index, descr.ofs, - newvalue) - elif descr.typeinfo == FLOAT: - return do_setinteriorfield_gc_float(array, index, descr.ofs, - newvalue) - else: - raise NotImplementedError - - def op_setinteriorfield_raw(self, descr, array, index, newvalue): - if descr.typeinfo == REF: - return do_setinteriorfield_raw_ptr(array, index, newvalue, descr.width, descr.ofs) - elif descr.typeinfo == INT: - return do_setinteriorfield_raw_int(array, index, newvalue, descr.width, descr.ofs) - elif descr.typeinfo == FLOAT: - return do_setinteriorfield_raw_float(array, index, newvalue, descr.width, descr.ofs) - else: - raise NotImplementedError - - def op_setfield_gc(self, fielddescr, struct, newvalue): - if fielddescr.typeinfo == REF: - do_setfield_gc_ptr(struct, fielddescr.ofs, newvalue) - elif fielddescr.typeinfo == INT: - do_setfield_gc_int(struct, fielddescr.ofs, newvalue) - elif fielddescr.typeinfo == FLOAT: - do_setfield_gc_float(struct, fielddescr.ofs, newvalue) - else: - raise NotImplementedError - - def op_setfield_raw(self, fielddescr, struct, newvalue): - if fielddescr.typeinfo == REF: - do_setfield_raw_ptr(struct, fielddescr.ofs, newvalue) - elif fielddescr.typeinfo == INT: - do_setfield_raw_int(struct, fielddescr.ofs, newvalue) - elif fielddescr.typeinfo == FLOAT: - do_setfield_raw_float(struct, fielddescr.ofs, newvalue) - else: - raise NotImplementedError - - def op_call(self, calldescr, func, *args): - effectinfo = calldescr.get_extra_info() - if effectinfo is not None and hasattr(effectinfo, 'oopspecindex'): - oopspecindex = effectinfo.oopspecindex - if oopspecindex == EffectInfo.OS_MATH_SQRT: - return do_math_sqrt(args[0]) - return self._do_call(calldescr, func, args, call_with_llptr=False) - - def op_call_release_gil(self, calldescr, func, *args): - return self._do_call(calldescr, func, args, call_with_llptr=True) - - def _do_call(self, calldescr, func, args, call_with_llptr): - global _last_exception - assert _last_exception is None, "exception left behind" - assert _call_args_i == _call_args_r == _call_args_f == [] - args_in_order = [] - for x in args: - T = lltype.typeOf(x) - if T is lltype.Signed: - args_in_order.append('i') - _call_args_i.append(x) - elif T == llmemory.GCREF: - args_in_order.append('r') - _call_args_r.append(x) - elif T is longlong.FLOATSTORAGE: - args_in_order.append('f') - _call_args_f.append(x) - else: - raise TypeError(x) - try: From noreply at buildbot.pypy.org Mon Feb 11 10:29:38 2013 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 11 Feb 2013 10:29:38 +0100 (CET) Subject: [pypy-commit] pypy default: Merged in krono/pypy (pull request #109) Message-ID: <20130211092938.CD50D1C11AD@cobra.cs.uni-duesseldorf.de> Author: arigo Branch: Changeset: r61074:e268a994c86f Date: 2013-02-11 10:28 +0100 http://bitbucket.org/pypy/pypy/changeset/e268a994c86f/ Log: Merged in krono/pypy (pull request #109) Enhance the dotviewer: change the fonts and add support for unicode. diff --git a/LICENSE b/LICENSE --- a/LICENSE +++ b/LICENSE @@ -270,3 +270,24 @@ LineBreak-*.txt UnicodeData-*.txt UnihanNumeric-*.txt + +License for 'dotviewer/font/' +============================= + +Copyright (C) 2008 The Android Open Source Project + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +Detailled license information is contained in the NOTICE file in the +directory. + diff --git a/dotviewer/VeraMoBd.ttf b/dotviewer/VeraMoBd.ttf deleted file mode 100644 Binary file dotviewer/VeraMoBd.ttf has changed diff --git a/dotviewer/cyrvetic.ttf b/dotviewer/cyrvetic.ttf deleted file mode 100644 Binary file dotviewer/cyrvetic.ttf has changed diff --git a/dotviewer/drawgraph.py b/dotviewer/drawgraph.py --- a/dotviewer/drawgraph.py +++ b/dotviewer/drawgraph.py @@ -9,9 +9,10 @@ from pygame.locals import * +RAW_ENCODING = "utf-8" this_dir = os.path.dirname(os.path.abspath(__file__)) -FONT = os.path.join(this_dir, 'cyrvetic.ttf') -FIXEDFONT = os.path.join(this_dir, 'VeraMoBd.ttf') +FONT = os.path.join(this_dir, 'font', 'DroidSans.ttf') +FIXEDFONT = os.path.join(this_dir, 'font', 'DroidSansMono.ttf') COLOR = { 'black': (0,0,0), 'white': (255,255,255), @@ -51,6 +52,12 @@ else: return default +def forceunicode(name): + return name if isinstance(name, unicode) else name.decode(RAW_ENCODING) + +def forcestr(name): + return name if isinstance(name, str) else name.encode(RAW_ENCODING) + class GraphLayout: fixedfont = False @@ -106,12 +113,12 @@ class Node: def __init__(self, name, x, y, w, h, label, style, shape, color, fillcolor): - self.name = name + self.name = forceunicode(name) self.x = float(x) self.y = float(y) self.w = float(w) self.h = float(h) - self.label = label + self.label = forceunicode(label) self.style = style self.shape = shape self.color = color @@ -125,8 +132,8 @@ label = None def __init__(self, nodes, tail, head, cnt, *rest): - self.tail = nodes[tail] - self.head = nodes[head] + self.tail = nodes[forceunicode(tail)] + self.head = nodes[forceunicode(head)] cnt = int(cnt) self.points = [(float(rest[i]), float(rest[i+1])) for i in range(0, cnt*2, 2)] @@ -655,11 +662,7 @@ part = parts[i] word = part[0] try: - try: - img = font.render(word, False, *part[1:]) - except pygame.error, e: - # Try *with* anti-aliasing to work around a bug in SDL - img = font.render(word, True, *part[1:]) + img = font.render(word, True, *part[1:]) except pygame.error: del parts[i] # Text has zero width else: diff --git a/dotviewer/font/DroidSans-Bold.ttf b/dotviewer/font/DroidSans-Bold.ttf new file mode 100644 index 0000000000000000000000000000000000000000..d065b64eb1863f83c2c982264f9442f2313a44a9 GIT binary patch [cut] diff --git a/dotviewer/font/DroidSans.ttf b/dotviewer/font/DroidSans.ttf new file mode 100644 index 0000000000000000000000000000000000000000..ad1efca88aed8d9e2d179f27dd713e2a1562fe5f GIT binary patch [cut] diff --git a/dotviewer/font/DroidSansMono.ttf b/dotviewer/font/DroidSansMono.ttf new file mode 100644 index 0000000000000000000000000000000000000000..a007071944f7c90020e798eea53b10065e2b45a5 GIT binary patch [cut] diff --git a/dotviewer/font/NOTICE b/dotviewer/font/NOTICE new file mode 100644 --- /dev/null +++ b/dotviewer/font/NOTICE @@ -0,0 +1,190 @@ + + Copyright (c) 2005-2008, The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + diff --git a/dotviewer/font/README.txt b/dotviewer/font/README.txt new file mode 100644 --- /dev/null +++ b/dotviewer/font/README.txt @@ -0,0 +1,18 @@ +Copyright (C) 2008 The Android Open Source Project + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +########## + +This directory contains the fonts for the platform. They are licensed +under the Apache 2 license. diff --git a/dotviewer/graphclient.py b/dotviewer/graphclient.py --- a/dotviewer/graphclient.py +++ b/dotviewer/graphclient.py @@ -33,8 +33,9 @@ def reload(graph_id): page = getpage(graph_id) if save_tmp_file: + from drawgraph import forcestr f = open(save_tmp_file, 'w') - f.write(page.source) + f.write(forcestr(page.source)) f.close() messages.extend(page_messages(page, graph_id)) send_graph_messages(io, messages) @@ -75,7 +76,8 @@ def page_messages(page, graph_id): import graphparse - return graphparse.parse_dot(graph_id, page.source, page.links, + from drawgraph import forcestr + return graphparse.parse_dot(graph_id, forcestr(page.source), page.links, getattr(page, 'fixedfont', False)) def send_graph_messages(io, messages): diff --git a/dotviewer/graphdisplay.py b/dotviewer/graphdisplay.py --- a/dotviewer/graphdisplay.py +++ b/dotviewer/graphdisplay.py @@ -4,7 +4,7 @@ from pygame.locals import * from drawgraph import GraphRenderer, FIXEDFONT from drawgraph import Node, Edge -from drawgraph import EventQueue, wait_for_events +from drawgraph import EventQueue, wait_for_events, forceunicode, forcestr METAKEYS = dict([ @@ -285,7 +285,7 @@ if e.key == K_ESCAPE: return None elif e.key == K_RETURN: - return text.encode('latin-1') # XXX do better + return forcestr(text) # return encoded unicode elif e.key == K_BACKSPACE: text = text[:-1] elif e.unicode and ord(e.unicode) >= ord(' '): @@ -423,7 +423,7 @@ self.layout.request_reload() def setstatusbar(self, text, fgcolor=None, bgcolor=None): - info = (text, fgcolor or self.STATUSBAR_FGCOLOR, bgcolor or self.STATUSBAR_BGCOLOR) + info = (forceunicode(text), fgcolor or self.STATUSBAR_FGCOLOR, bgcolor or self.STATUSBAR_BGCOLOR) if info != self.statusbarinfo: self.statusbarinfo = info self.must_redraw = True @@ -711,7 +711,7 @@ lines = [] while words: line = words.pop(0) - img = font.render(line or ' ', 1, fgcolor) + img = font.render(line or ' ', True, fgcolor) while words: longerline = line + ' ' + words[0] longerimg = font.render(longerline, 1, fgcolor) @@ -723,7 +723,7 @@ img = longerimg w, h = img.get_size() if h > maxheight: - img = font.render('...', 1, overflowcolor) + img = font.render('...', True, overflowcolor) w, h = img.get_size() while lines and h > maxheight: maxheight += lines.pop().get_size()[1] diff --git a/dotviewer/graphpage.py b/dotviewer/graphpage.py --- a/dotviewer/graphpage.py +++ b/dotviewer/graphpage.py @@ -44,6 +44,8 @@ class DotFileGraphPage(GraphPage): def compute(self, dotfile): - f = open(dotfile, 'r') + import codecs + from drawgraph import RAW_ENCODING + f = codecs.open(dotfile, 'r', RAW_ENCODING) self.source = f.read() f.close() diff --git a/dotviewer/test/test_interactive_unicode.py b/dotviewer/test/test_interactive_unicode.py new file mode 100755 --- /dev/null +++ b/dotviewer/test/test_interactive_unicode.py @@ -0,0 +1,103 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +import py +import sys, os, signal, thread, time, codecs +from dotviewer.conftest import option +from dotviewer.drawgraph import RAW_ENCODING + +SOURCE1 = u"""digraph G{ +λ -> b +b -> μ +} +""" + +FILENAME = 'graph1.dot' + +def setup_module(mod): + if not option.pygame: + py.test.skip("--pygame not enabled") + udir = py.path.local.make_numbered_dir(prefix='usession-dot-', keep=3) + f = codecs.open(str(udir.join(FILENAME)), 'wb', RAW_ENCODING) + f.write(SOURCE1) + f.close() + + from dotviewer import graphclient + mod.pkgdir = py.path.local(graphclient.this_dir) + mod.udir = udir + + try: + del os.environ['GRAPHSERVER'] + except KeyError: + pass + + +def test_dotviewer(): + print "=== dotviewer.py %s" % FILENAME + err = os.system('"%s" "%s"' % (pkgdir.join('dotviewer.py'), + udir.join(FILENAME))) + assert err == 0 + + plain_name = FILENAME.replace('.dot','.plain') + + os.system('dot -Tplain "%s" > "%s"' % (udir.join(FILENAME), + udir.join(plain_name))) + print "=== dotviewer.py %s" % plain_name + err = os.system('"%s" "%s"' % (pkgdir.join('dotviewer.py'), + udir.join(plain_name))) + assert err == 0 + +def test_display_dot_file(): + from dotviewer.graphclient import display_dot_file + print "=== display_dot_file(%s) with GRAPHSERVER=%s" % ( + FILENAME, os.environ.get('GRAPHSERVER', ''),) + display_dot_file(udir.join(FILENAME)) + print "=== display_dot_file finished" + + +def test_graphserver(): + import socket + s = socket.socket() + s.listen(1) + host, port = s.getsockname() # pick a random free port + s.close() + + if hasattr(sys, 'pypy_objspaceclass'): + python = 'python' + else: + python = sys.executable + + cmdargs = [python, str(pkgdir.join('graphserver.py')), + str(port)] + print '* starting:', ' '.join(cmdargs) + pid = os.spawnv(os.P_NOWAIT, cmdargs[0], cmdargs) + try: + time.sleep(1) # hack - wait a bit to make sure the server is up + os.environ['GRAPHSERVER'] = '%s:%d' % (host, port) + try: + test_display_dot_file() + finally: + del os.environ['GRAPHSERVER'] + finally: + os.kill(pid, signal.SIGTERM) + +def test_colors(): + from dotviewer import graphpage, graphclient + class MyPage(graphpage.DotFileGraphPage): + def compute(self, dotfile): + super(MyPage, self).compute(dotfile) + self.links = {'v2721': 'Hello world', + 'v2720': ('Something green', (0, 192, 0)), + } + dotfile = str(udir.join(FILENAME)) + page = MyPage(dotfile) + graphclient.display_page(page) + +def test_fixedfont(): + from dotviewer import graphpage, graphclient + class MyPage(graphpage.DotFileGraphPage): + fixedfont = True + dotfile = str(udir.join(FILENAME)) + page = MyPage(dotfile) + page.fixedfont = True + graphclient.display_page(page) diff --git a/dotviewer/test/test_translator.py b/dotviewer/test/test_translator.py --- a/dotviewer/test/test_translator.py +++ b/dotviewer/test/test_translator.py @@ -22,6 +22,6 @@ def test_annotated(): from rpython.translator.interactive import Translation - t = Translation(is_prime) - t.annotate([int]) + t = Translation(is_prime, [int]) + t.annotate() t.viewcg() diff --git a/dotviewer/test/test_unicode_util.py b/dotviewer/test/test_unicode_util.py new file mode 100755 --- /dev/null +++ b/dotviewer/test/test_unicode_util.py @@ -0,0 +1,57 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +import py +import codecs +from dotviewer.drawgraph import RAW_ENCODING, forcestr, forceunicode + +SOURCE1 = u"""digraph G{ +λ -> b +b -> μ +} +""" + +FILENAME = 'test.dot' + +class TestUnicodeUtil(object): + + def test_idempotent(self): + x = u"a" + assert forceunicode(forcestr(x)) == x + + x = u"λ" + assert forceunicode(forcestr(x)) == x + + assert forceunicode(forcestr(SOURCE1)) == SOURCE1 + + x = "a" + assert forcestr(forceunicode(x)) == x + + # utf-8 encoded. + # fragile, does not consider RAW_ENCODING + # x = "\xef\xbb\xbf\xce\xbb" + # assert forcestr(forceunicode(x)) == x + + def test_does_not_double_encode(self): + x = u"λ" + x_e = forcestr(x) + assert forcestr(x_e) == x_e + + x_u = forceunicode(x_e) + assert forceunicode(x_u) == x_u + + def test_file(self): + udir = py.path.local.make_numbered_dir(prefix='usession-dot-', keep=3) + full_filename = str(udir.join(FILENAME)) + f = codecs.open(full_filename, 'wb', RAW_ENCODING) + f.write(SOURCE1) + f.close() + + with open(full_filename) as f1: + assert forceunicode(f1.read()) == SOURCE1 + + f3 = codecs.open(full_filename, 'r', RAW_ENCODING) + c = f3.read() + f3.close() + result = (c == SOURCE1) + assert result From noreply at buildbot.pypy.org Mon Feb 11 10:29:44 2013 From: noreply at buildbot.pypy.org (fijal) Date: Mon, 11 Feb 2013 10:29:44 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: fix the test Message-ID: <20130211092944.BD7D21C11AD@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61075:b11c19a58e2d Date: 2013-02-11 11:28 +0200 http://bitbucket.org/pypy/pypy/changeset/b11c19a58e2d/ Log: fix the test diff --git a/rpython/jit/backend/x86/test/test_runner.py b/rpython/jit/backend/x86/test/test_runner.py --- a/rpython/jit/backend/x86/test/test_runner.py +++ b/rpython/jit/backend/x86/test/test_runner.py @@ -500,7 +500,7 @@ ResOperation(rop.GUARD_FALSE, [i3], None, descr=BasicFailDescr(0)), ResOperation(rop.FINISH, [], None, - descr=BasicFailDescr(1)) + descr=BasicFinalDescr(1)) ] ops[-2].setfailargs([i3, i4, i5, i6]) ops[1].setfailargs([]) From noreply at buildbot.pypy.org Mon Feb 11 10:31:32 2013 From: noreply at buildbot.pypy.org (fijal) Date: Mon, 11 Feb 2013 10:31:32 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: fix the xxx Message-ID: <20130211093132.64FB51C11CF@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61076:fe60721f60e7 Date: 2013-02-11 11:30 +0200 http://bitbucket.org/pypy/pypy/changeset/fe60721f60e7/ Log: fix the xxx diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -1177,17 +1177,16 @@ self.mc.CALL(x) if can_collect: self._reload_frame_if_necessary(self.mc) - if align: - self.mc.ADD_ri(esp.value, align * WORD) if can_collect: self.pop_gcmap(self.mc) # if callconv != FFI_DEFAULT_ABI: - self._fix_stdcall(callconv, p) + self._fix_stdcall(callconv, p - align * WORD) + elif align: + self.mc.ADD_ri(esp.value, align * WORD) def _fix_stdcall(self, callconv, p): from rpython.rlib.clibffi import FFI_STDCALL - xxx assert callconv == FFI_STDCALL # it's a bit stupid, but we're just going to cancel the fact that # the called function just added 'p' to ESP, by subtracting it again. From noreply at buildbot.pypy.org Mon Feb 11 11:18:01 2013 From: noreply at buildbot.pypy.org (fijal) Date: Mon, 11 Feb 2013 11:18:01 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: remove "simple" logic duplication that was not quite correct Message-ID: <20130211101801.08ABD1C01BF@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61077:af844bfac322 Date: 2013-02-11 12:17 +0200 http://bitbucket.org/pypy/pypy/changeset/af844bfac322/ Log: remove "simple" logic duplication that was not quite correct diff --git a/rpython/jit/backend/x86/regalloc.py b/rpython/jit/backend/x86/regalloc.py --- a/rpython/jit/backend/x86/regalloc.py +++ b/rpython/jit/backend/x86/regalloc.py @@ -164,7 +164,7 @@ def prepare_loop(self, inputargs, operations, looptoken, allgcrefs): operations = self._prepare(inputargs, operations, allgcrefs) - self._set_initial_bindings(inputargs) + self._set_initial_bindings(inputargs, looptoken) # note: we need to make a copy of inputargs because possibly_free_vars # is also used on op args, which is a non-resizable list self.possibly_free_vars(list(inputargs)) @@ -188,10 +188,13 @@ def get_final_frame_depth(self): return self.fm.get_frame_depth() - def _set_initial_bindings(self, inputargs): + def _set_initial_bindings(self, inputargs, looptoken): + locs = [] for box in inputargs: assert isinstance(box, Box) - self.fm.get_new_loc(box) + loc = self.fm.get_new_loc(box) + locs.append(loc.value) + looptoken.compiled_loop_token._x86_initial_locs = locs def possibly_free_var(self, var): if var.type == FLOAT: diff --git a/rpython/jit/backend/x86/runner.py b/rpython/jit/backend/x86/runner.py --- a/rpython/jit/backend/x86/runner.py +++ b/rpython/jit/backend/x86/runner.py @@ -119,25 +119,24 @@ #llop.debug_print(lltype.Void, ">>>> Entering", addr) frame_info = clt.frame_info frame = self.gc_ll_descr.malloc_jitframe(frame_info) + base_ofs = self.get_baseofs_of_frame_field() ll_frame = lltype.cast_opaque_ptr(llmemory.GCREF, frame) + locs = executable_token.compiled_loop_token._x86_initial_locs prev_interpreter = None # help flow space if not self.translate_support_code: prev_interpreter = LLInterpreter.current_interpreter LLInterpreter.current_interpreter = self.debug_ll_interpreter try: - num = JITFRAME_FIXED_SIZE * WORD for i, kind in kinds: arg = args[i] + num = locs[i] - base_ofs if kind == history.INT: self.set_int_value(ll_frame, num, arg) elif kind == history.FLOAT: self.set_float_value(ll_frame, num, arg) - if IS_X86_32: - num += WORD else: assert kind == history.REF self.set_ref_value(ll_frame, num, arg) - num += WORD ll_frame = func(ll_frame) finally: if not self.translate_support_code: From noreply at buildbot.pypy.org Mon Feb 11 11:51:56 2013 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 11 Feb 2013 11:51:56 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: Tweak _getregkey(). The essential part is that for StackLocs it should Message-ID: <20130211105156.399A61C0041@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: jitframe-on-heap Changeset: r61078:7dd4f26ec840 Date: 2013-02-11 11:51 +0100 http://bitbucket.org/pypy/pypy/changeset/7dd4f26ec840/ Log: Tweak _getregkey(). The essential part is that for StackLocs it should return the ebp_offset, so that jump.py detects (on 32-bit) that some position is partially overlapping with a float because _getregkey() returned the previous value + WORD. diff --git a/rpython/jit/backend/x86/jump.py b/rpython/jit/backend/x86/jump.py --- a/rpython/jit/backend/x86/jump.py +++ b/rpython/jit/backend/x86/jump.py @@ -1,6 +1,7 @@ import sys from rpython.tool.pairtype import extendabletype -from rpython.jit.backend.x86.regloc import ImmediateAssemblerLocation, StackLoc +from rpython.jit.backend.x86.regloc import ImmediateAssemblerLocation +from rpython.jit.backend.x86.regloc import RegLoc, StackLoc def remap_frame_layout(assembler, src_locations, dst_locations, tmpreg): pending_dests = len(dst_locations) diff --git a/rpython/jit/backend/x86/regloc.py b/rpython/jit/backend/x86/regloc.py --- a/rpython/jit/backend/x86/regloc.py +++ b/rpython/jit/backend/x86/regloc.py @@ -53,9 +53,6 @@ self.value = value self.type = type - def _getregkey(self): - return -(self.value * 2 + 2) - def get_width(self): if self.type == FLOAT: return 8 @@ -80,11 +77,12 @@ _location_code = 's' def __init__(self, value, type): + assert value >= 0 self.value = value self.type = type def _getregkey(self): - return -(self.value * 2 + 1) + return ~self.value def get_width(self): if self.type == FLOAT: @@ -107,8 +105,7 @@ # _getregkey() returns self.value; the value returned must not # conflict with RegLoc._getregkey(). It doesn't a bit by chance, # so let it fail the following assert if it no longer does. - assert ebp_offset >= 0 - #assert not (0 <= ebp_offset < 8 + 8 * IS_X86_64) + assert ebp_offset >= 8 + 8 * IS_X86_64 self.position = position #if position != 9999: # assert (position + JITFRAME_FIXED_SIZE) * WORD == ebp_offset From noreply at buildbot.pypy.org Mon Feb 11 11:51:57 2013 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 11 Feb 2013 11:51:57 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: merge heads Message-ID: <20130211105157.8BDEF1C0041@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: jitframe-on-heap Changeset: r61079:327693ffe242 Date: 2013-02-11 11:51 +0100 http://bitbucket.org/pypy/pypy/changeset/327693ffe242/ Log: merge heads diff --git a/rpython/jit/backend/llsupport/llmodel.py b/rpython/jit/backend/llsupport/llmodel.py --- a/rpython/jit/backend/llsupport/llmodel.py +++ b/rpython/jit/backend/llsupport/llmodel.py @@ -52,8 +52,12 @@ # the same as normal JITFRAME, however with an array of pointers self.refarraydescr = ArrayDescr(ad.basesize, ad.itemsize, ad.lendescr, FLAG_POINTER) - self.floatarraydescr = ArrayDescr(ad.basesize, ad.itemsize, ad.lendescr, - FLAG_FLOAT) + if WORD == 4: + self.floatarraydescr = ArrayDescr(ad.basesize, ad.itemsize * 2, + ad.lendescr, FLAG_FLOAT) + else: + self.floatarraydescr = ArrayDescr(ad.basesize, ad.itemsize, + ad.lendescr, FLAG_FLOAT) self.setup() def getarraydescr_for_frame(self, type): diff --git a/rpython/jit/backend/llsupport/rewrite.py b/rpython/jit/backend/llsupport/rewrite.py --- a/rpython/jit/backend/llsupport/rewrite.py +++ b/rpython/jit/backend/llsupport/rewrite.py @@ -175,15 +175,20 @@ None, descr=descrs.jf_frame_info) self.newops.append(op2) arglist = op.getarglist() - index = self.cpu.getarryoffset_for_frame() + index = self.cpu.getarryoffset_for_frame() for i, arg in enumerate(arglist): descr = self.cpu.getarraydescr_for_frame(arg.type) - self.newops.append(ResOperation(rop.SETARRAYITEM_GC, - [frame, ConstInt(index), arg], - None, descr)) - if WORD == 4 and type == history.FLOAT: - index += 2 + if WORD == 4 and arg.type == history.FLOAT: + self.newops.append(ResOperation(rop.SETARRAYITEM_GC, + [frame, ConstInt(index // 2), + arg], + None, descr)) + index += 2 else: + self.newops.append(ResOperation(rop.SETARRAYITEM_GC, + [frame, ConstInt(index), + arg], + None, descr)) index += 1 descr = op.getdescr() assert isinstance(descr, JitCellToken) diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -211,12 +211,14 @@ # push first arg mc.MOV_rr(edi.value, ebp.value) align = align_stack_words(1) + mc.SUB_ri(esp.value, (align - 1) * WORD) else: - mc.PUSH(RawStackLoc(WORD * 2)) - mc.PUSH_r(ebp.value) align = align_stack_words(3) + mc.MOV_rs(eax.value, WORD * 2) + mc.SUB_ri(esp.value, (align - 1) * WORD) + mc.MOV_sr(WORD, eax.value) + mc.MOV_sr(0, ebp.value) # align - mc.SUB_ri(esp.value, (align - 1) * WORD) mc.CALL(imm(self.cpu.realloc_frame)) mc.ADD_ri(esp.value, (align - 1) * WORD) @@ -1140,7 +1142,7 @@ stack_depth += 2 else: stack_depth += 1 - stack_depth += loc.get_width() + stack_depth += loc.get_width() // WORD if stack_depth > PASS_ON_MY_FRAME: stack_depth = align_stack_words(stack_depth) align = (stack_depth - PASS_ON_MY_FRAME) @@ -1175,17 +1177,16 @@ self.mc.CALL(x) if can_collect: self._reload_frame_if_necessary(self.mc) - if align: - self.mc.ADD_ri(esp.value, align * WORD) if can_collect: self.pop_gcmap(self.mc) # if callconv != FFI_DEFAULT_ABI: - self._fix_stdcall(callconv, p) + self._fix_stdcall(callconv, p - align * WORD) + elif align: + self.mc.ADD_ri(esp.value, align * WORD) def _fix_stdcall(self, callconv, p): from rpython.rlib.clibffi import FFI_STDCALL - xxx assert callconv == FFI_STDCALL # it's a bit stupid, but we're just going to cancel the fact that # the called function just added 'p' to ESP, by subtracting it again. diff --git a/rpython/jit/backend/x86/regalloc.py b/rpython/jit/backend/x86/regalloc.py --- a/rpython/jit/backend/x86/regalloc.py +++ b/rpython/jit/backend/x86/regalloc.py @@ -164,7 +164,7 @@ def prepare_loop(self, inputargs, operations, looptoken, allgcrefs): operations = self._prepare(inputargs, operations, allgcrefs) - self._set_initial_bindings(inputargs) + self._set_initial_bindings(inputargs, looptoken) # note: we need to make a copy of inputargs because possibly_free_vars # is also used on op args, which is a non-resizable list self.possibly_free_vars(list(inputargs)) @@ -188,10 +188,13 @@ def get_final_frame_depth(self): return self.fm.get_frame_depth() - def _set_initial_bindings(self, inputargs): + def _set_initial_bindings(self, inputargs, looptoken): + locs = [] for box in inputargs: assert isinstance(box, Box) - self.fm.get_new_loc(box) + loc = self.fm.get_new_loc(box) + locs.append(loc.value) + looptoken.compiled_loop_token._x86_initial_locs = locs def possibly_free_var(self, var): if var.type == FLOAT: diff --git a/rpython/jit/backend/x86/runner.py b/rpython/jit/backend/x86/runner.py --- a/rpython/jit/backend/x86/runner.py +++ b/rpython/jit/backend/x86/runner.py @@ -56,7 +56,7 @@ return 1000 def getarryoffset_for_frame(self): - return JITFRAME_FIXED_SIZE + return JITFRAME_FIXED_SIZE def setup(self): self.assembler = Assembler386(self, self.translate_support_code) @@ -119,25 +119,24 @@ #llop.debug_print(lltype.Void, ">>>> Entering", addr) frame_info = clt.frame_info frame = self.gc_ll_descr.malloc_jitframe(frame_info) + base_ofs = self.get_baseofs_of_frame_field() ll_frame = lltype.cast_opaque_ptr(llmemory.GCREF, frame) + locs = executable_token.compiled_loop_token._x86_initial_locs prev_interpreter = None # help flow space if not self.translate_support_code: prev_interpreter = LLInterpreter.current_interpreter LLInterpreter.current_interpreter = self.debug_ll_interpreter try: - num = JITFRAME_FIXED_SIZE * WORD for i, kind in kinds: arg = args[i] + num = locs[i] - base_ofs if kind == history.INT: self.set_int_value(ll_frame, num, arg) elif kind == history.FLOAT: self.set_float_value(ll_frame, num, arg) - if IS_X86_32: - num += WORD else: assert kind == history.REF self.set_ref_value(ll_frame, num, arg) - num += WORD ll_frame = func(ll_frame) finally: if not self.translate_support_code: diff --git a/rpython/jit/backend/x86/test/test_runner.py b/rpython/jit/backend/x86/test/test_runner.py --- a/rpython/jit/backend/x86/test/test_runner.py +++ b/rpython/jit/backend/x86/test/test_runner.py @@ -31,8 +31,11 @@ # ====> ../../test/runner_test.py add_loop_instructions = ['mov', 'add', 'test', 'je', 'jmp'] - bridge_loop_instructions = ['cmp', 'jge', 'mov', 'mov', 'mov', 'mov', - 'call', 'mov', 'jmp'] + if WORD == 4: + bridge_loop_instructions = ['cmp', 'jge', 'mov', 'mov', 'call', 'jmp'] + else: + bridge_loop_instructions = ['cmp', 'jge', 'mov', 'mov', 'mov', 'mov', + 'call', 'mov', 'jmp'] def get_cpu(self): cpu = CPU(rtyper=None, stats=FakeStats()) @@ -497,7 +500,7 @@ ResOperation(rop.GUARD_FALSE, [i3], None, descr=BasicFailDescr(0)), ResOperation(rop.FINISH, [], None, - descr=BasicFailDescr(1)) + descr=BasicFinalDescr(1)) ] ops[-2].setfailargs([i3, i4, i5, i6]) ops[1].setfailargs([]) From noreply at buildbot.pypy.org Mon Feb 11 11:52:41 2013 From: noreply at buildbot.pypy.org (antocuni) Date: Mon, 11 Feb 2013 11:52:41 +0100 (CET) Subject: [pypy-commit] pypy default: implement numpypy.outer (by copying it from numpy source) Message-ID: <20130211105241.EA6111C0041@cobra.cs.uni-duesseldorf.de> Author: Antonio Cuni Branch: Changeset: r61080:ae915d2b7d56 Date: 2013-02-11 11:20 +0100 http://bitbucket.org/pypy/pypy/changeset/ae915d2b7d56/ Log: implement numpypy.outer (by copying it from numpy source) diff --git a/lib_pypy/numpypy/core/numeric.py b/lib_pypy/numpypy/core/numeric.py --- a/lib_pypy/numpypy/core/numeric.py +++ b/lib_pypy/numpypy/core/numeric.py @@ -428,3 +428,76 @@ True_ = bool_(True) e = math.e pi = math.pi + +def outer(a,b): + """ + Compute the outer product of two vectors. + + Given two vectors, ``a = [a0, a1, ..., aM]`` and + ``b = [b0, b1, ..., bN]``, + the outer product [1]_ is:: + + [[a0*b0 a0*b1 ... a0*bN ] + [a1*b0 . + [ ... . + [aM*b0 aM*bN ]] + + Parameters + ---------- + a, b : array_like, shape (M,), (N,) + First and second input vectors. Inputs are flattened if they + are not already 1-dimensional. + + Returns + ------- + out : ndarray, shape (M, N) + ``out[i, j] = a[i] * b[j]`` + + See also + -------- + inner, einsum + + References + ---------- + .. [1] : G. H. Golub and C. F. van Loan, *Matrix Computations*, 3rd + ed., Baltimore, MD, Johns Hopkins University Press, 1996, + pg. 8. + + Examples + -------- + Make a (*very* coarse) grid for computing a Mandelbrot set: + + >>> rl = np.outer(np.ones((5,)), np.linspace(-2, 2, 5)) + >>> rl + array([[-2., -1., 0., 1., 2.], + [-2., -1., 0., 1., 2.], + [-2., -1., 0., 1., 2.], + [-2., -1., 0., 1., 2.], + [-2., -1., 0., 1., 2.]]) + >>> im = np.outer(1j*np.linspace(2, -2, 5), np.ones((5,))) + >>> im + array([[ 0.+2.j, 0.+2.j, 0.+2.j, 0.+2.j, 0.+2.j], + [ 0.+1.j, 0.+1.j, 0.+1.j, 0.+1.j, 0.+1.j], + [ 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j], + [ 0.-1.j, 0.-1.j, 0.-1.j, 0.-1.j, 0.-1.j], + [ 0.-2.j, 0.-2.j, 0.-2.j, 0.-2.j, 0.-2.j]]) + >>> grid = rl + im + >>> grid + array([[-2.+2.j, -1.+2.j, 0.+2.j, 1.+2.j, 2.+2.j], + [-2.+1.j, -1.+1.j, 0.+1.j, 1.+1.j, 2.+1.j], + [-2.+0.j, -1.+0.j, 0.+0.j, 1.+0.j, 2.+0.j], + [-2.-1.j, -1.-1.j, 0.-1.j, 1.-1.j, 2.-1.j], + [-2.-2.j, -1.-2.j, 0.-2.j, 1.-2.j, 2.-2.j]]) + + An example using a "vector" of letters: + + >>> x = np.array(['a', 'b', 'c'], dtype=object) + >>> np.outer(x, [1, 2, 3]) + array([[a, aa, aaa], + [b, bb, bbb], + [c, cc, ccc]], dtype=object) + + """ + a = asarray(a) + b = asarray(b) + return a.ravel()[:,newaxis]*b.ravel()[newaxis,:] diff --git a/pypy/module/test_lib_pypy/numpypy/core/test_numeric.py b/pypy/module/test_lib_pypy/numpypy/core/test_numeric.py --- a/pypy/module/test_lib_pypy/numpypy/core/test_numeric.py +++ b/pypy/module/test_lib_pypy/numpypy/core/test_numeric.py @@ -178,3 +178,18 @@ assert not array_equal(a, array(b)) assert not array_equal(array(a), b) assert not array_equal(array(a), array(b)) + +class AppTestNumeric(BaseNumpyAppTest): + + def test_outer(self): + from _numpypy import array + from numpypy import outer + a = [1, 2, 3] + b = [4, 5, 6] + res = outer(a, b) + expected = array([[ 4, 5, 6], + [ 8, 10, 12], + [12, 15, 18]]) + assert (res == expected).all() + + From noreply at buildbot.pypy.org Mon Feb 11 11:52:43 2013 From: noreply at buildbot.pypy.org (antocuni) Date: Mon, 11 Feb 2013 11:52:43 +0100 (CET) Subject: [pypy-commit] pypy default: implement numpypy.atleast_1d (by copying it from numpy source) Message-ID: <20130211105243.1DEC21C0041@cobra.cs.uni-duesseldorf.de> Author: Antonio Cuni Branch: Changeset: r61081:5ab59a258c41 Date: 2013-02-11 11:39 +0100 http://bitbucket.org/pypy/pypy/changeset/5ab59a258c41/ Log: implement numpypy.atleast_1d (by copying it from numpy source) diff --git a/lib_pypy/numpypy/core/__init__.py b/lib_pypy/numpypy/core/__init__.py --- a/lib_pypy/numpypy/core/__init__.py +++ b/lib_pypy/numpypy/core/__init__.py @@ -1,2 +1,3 @@ from .fromnumeric import * from .numeric import * +from .shape_base import * diff --git a/lib_pypy/numpypy/core/shape_base.py b/lib_pypy/numpypy/core/shape_base.py new file mode 100644 --- /dev/null +++ b/lib_pypy/numpypy/core/shape_base.py @@ -0,0 +1,106 @@ +from numeric import array, asanyarray, newaxis + +def atleast_1d(*arys): + """ + Convert inputs to arrays with at least one dimension. + + Scalar inputs are converted to 1-dimensional arrays, whilst + higher-dimensional inputs are preserved. + + Parameters + ---------- + arys1, arys2, ... : array_like + One or more input arrays. + + Returns + ------- + ret : ndarray + An array, or sequence of arrays, each with ``a.ndim >= 1``. + Copies are made only if necessary. + + See Also + -------- + atleast_2d, atleast_3d + + Examples + -------- + >>> np.atleast_1d(1.0) + array([ 1.]) + + >>> x = np.arange(9.0).reshape(3,3) + >>> np.atleast_1d(x) + array([[ 0., 1., 2.], + [ 3., 4., 5.], + [ 6., 7., 8.]]) + >>> np.atleast_1d(x) is x + True + + >>> np.atleast_1d(1, [3, 4]) + [array([1]), array([3, 4])] + + """ + res = [] + for ary in arys: + ary = asanyarray(ary) + if len(ary.shape) == 0 : + result = ary.reshape(1) + else : + result = ary + res.append(result) + if len(res) == 1: + return res[0] + else: + return res + + +def atleast_2d(*arys): + """ + View inputs as arrays with at least two dimensions. + + Parameters + ---------- + arys1, arys2, ... : array_like + One or more array-like sequences. Non-array inputs are converted + to arrays. Arrays that already have two or more dimensions are + preserved. + + Returns + ------- + res, res2, ... : ndarray + An array, or tuple of arrays, each with ``a.ndim >= 2``. + Copies are avoided where possible, and views with two or more + dimensions are returned. + + See Also + -------- + atleast_1d, atleast_3d + + Examples + -------- + >>> np.atleast_2d(3.0) + array([[ 3.]]) + + >>> x = np.arange(3.0) + >>> np.atleast_2d(x) + array([[ 0., 1., 2.]]) + >>> np.atleast_2d(x).base is x + True + + >>> np.atleast_2d(1, [1, 2], [[1, 2]]) + [array([[1]]), array([[1, 2]]), array([[1, 2]])] + + """ + res = [] + for ary in arys: + ary = asanyarray(ary) + if len(ary.shape) == 0 : + result = ary.reshape(1, 1) + elif len(ary.shape) == 1 : + result = ary[newaxis, :] + else : + result = ary + res.append(result) + if len(res) == 1: + return res[0] + else: + return res diff --git a/pypy/module/test_lib_pypy/numpypy/core/test_numeric.py b/pypy/module/test_lib_pypy/numpypy/core/test_numeric.py --- a/pypy/module/test_lib_pypy/numpypy/core/test_numeric.py +++ b/pypy/module/test_lib_pypy/numpypy/core/test_numeric.py @@ -191,5 +191,4 @@ [ 8, 10, 12], [12, 15, 18]]) assert (res == expected).all() - diff --git a/pypy/module/test_lib_pypy/numpypy/core/test_shape_base.py b/pypy/module/test_lib_pypy/numpypy/core/test_shape_base.py new file mode 100644 --- /dev/null +++ b/pypy/module/test_lib_pypy/numpypy/core/test_shape_base.py @@ -0,0 +1,36 @@ +from pypy.module.micronumpy.test.test_base import BaseNumpyAppTest + +class AppTestShapeBase(BaseNumpyAppTest): + + def test_atleast_1d(self): + from numpypy import array, array_equal + import numpypy as np + a = np.atleast_1d(1.0) + assert np.array_equal(a, [ 1.]) + + x = np.arange(9.0).reshape(3,3) + a = np.atleast_1d(x) + assert np.array_equal(a, [[ 0., 1., 2.], + [ 3., 4., 5.], + [ 6., 7., 8.]]) + assert np.atleast_1d(x) is x + + a = np.atleast_1d(1, [3, 4]) + assert len(a) == 2 + assert array_equal(a[0], [1]) + assert array_equal(a[1], [3, 4]) + + def test_atleast_2d(self): + import numpypy as np + a = np.atleast_2d(3.0) + assert np.array_equal(a, [[ 3.]]) + + x = np.arange(3.0) + a = np.atleast_2d(x) + assert np.array_equal(a, [[ 0., 1., 2.]]) + + a = np.atleast_2d(1, [1, 2], [[1, 2]]) + assert len(a) == 3 + assert np.array_equal(a[0], [[1]]) + assert np.array_equal(a[1], [[1, 2]]) + assert np.array_equal(a[2], [[1, 2]]) From noreply at buildbot.pypy.org Mon Feb 11 11:52:44 2013 From: noreply at buildbot.pypy.org (antocuni) Date: Mon, 11 Feb 2013 11:52:44 +0100 (CET) Subject: [pypy-commit] pypy default: implement numpypy.atleast_3d (by copying it from numpy source) Message-ID: <20130211105244.617B81C0041@cobra.cs.uni-duesseldorf.de> Author: Antonio Cuni Branch: Changeset: r61082:041283a61f06 Date: 2013-02-11 11:43 +0100 http://bitbucket.org/pypy/pypy/changeset/041283a61f06/ Log: implement numpypy.atleast_3d (by copying it from numpy source) diff --git a/lib_pypy/numpypy/core/shape_base.py b/lib_pypy/numpypy/core/shape_base.py --- a/lib_pypy/numpypy/core/shape_base.py +++ b/lib_pypy/numpypy/core/shape_base.py @@ -104,3 +104,69 @@ return res[0] else: return res + +def atleast_3d(*arys): + """ + View inputs as arrays with at least three dimensions. + + Parameters + ---------- + arys1, arys2, ... : array_like + One or more array-like sequences. Non-array inputs are converted to + arrays. Arrays that already have three or more dimensions are + preserved. + + Returns + ------- + res1, res2, ... : ndarray + An array, or tuple of arrays, each with ``a.ndim >= 3``. Copies are + avoided where possible, and views with three or more dimensions are + returned. For example, a 1-D array of shape ``(N,)`` becomes a view + of shape ``(1, N, 1)``, and a 2-D array of shape ``(M, N)`` becomes a + view of shape ``(M, N, 1)``. + + See Also + -------- + atleast_1d, atleast_2d + + Examples + -------- + >>> np.atleast_3d(3.0) + array([[[ 3.]]]) + + >>> x = np.arange(3.0) + >>> np.atleast_3d(x).shape + (1, 3, 1) + + >>> x = np.arange(12.0).reshape(4,3) + >>> np.atleast_3d(x).shape + (4, 3, 1) + >>> np.atleast_3d(x).base is x + True + + >>> for arr in np.atleast_3d([1, 2], [[1, 2]], [[[1, 2]]]): + ... print arr, arr.shape + ... + [[[1] + [2]]] (1, 2, 1) + [[[1] + [2]]] (1, 2, 1) + [[[1 2]]] (1, 1, 2) + + """ + res = [] + for ary in arys: + ary = asanyarray(ary) + if len(ary.shape) == 0: + result = ary.reshape(1,1,1) + elif len(ary.shape) == 1: + result = ary[newaxis,:,newaxis] + elif len(ary.shape) == 2: + result = ary[:,:,newaxis] + else: + result = ary + res.append(result) + if len(res) == 1: + return res[0] + else: + return res diff --git a/pypy/module/test_lib_pypy/numpypy/core/test_shape_base.py b/pypy/module/test_lib_pypy/numpypy/core/test_shape_base.py --- a/pypy/module/test_lib_pypy/numpypy/core/test_shape_base.py +++ b/pypy/module/test_lib_pypy/numpypy/core/test_shape_base.py @@ -34,3 +34,29 @@ assert np.array_equal(a[0], [[1]]) assert np.array_equal(a[1], [[1, 2]]) assert np.array_equal(a[2], [[1, 2]]) + + def test_atleast_3d(self): + import numpypy as np + + a = np.atleast_3d(3.0) + assert np.array_equal(a, [[[ 3.]]]) + + x = np.arange(3.0) + assert np.atleast_3d(x).shape == (1, 3, 1) + + x = np.arange(12.0).reshape(4,3) + assert np.atleast_3d(x).shape == (4, 3, 1) + + a = np.atleast_3d([1, 2]) + assert np.array_equal(a, [[[1], + [2]]]) + assert a.shape == (1, 2, 1) + + a = np.atleast_3d([[1, 2]]) + assert np.array_equal(a, [[[1], + [2]]]) + assert a.shape == (1, 2, 1) + + a = np.atleast_3d([[[1, 2]]]) + assert np.array_equal(a, [[[1, 2]]]) + assert a.shape == (1, 1, 2) From noreply at buildbot.pypy.org Mon Feb 11 11:52:45 2013 From: noreply at buildbot.pypy.org (antocuni) Date: Mon, 11 Feb 2013 11:52:45 +0100 (CET) Subject: [pypy-commit] pypy default: implement numpypy.vstack (by copying it from numpy source) Message-ID: <20130211105245.7D73F1C0041@cobra.cs.uni-duesseldorf.de> Author: Antonio Cuni Branch: Changeset: r61083:d10570215445 Date: 2013-02-11 11:50 +0100 http://bitbucket.org/pypy/pypy/changeset/d10570215445/ Log: implement numpypy.vstack (by copying it from numpy source) diff --git a/lib_pypy/numpypy/core/shape_base.py b/lib_pypy/numpypy/core/shape_base.py --- a/lib_pypy/numpypy/core/shape_base.py +++ b/lib_pypy/numpypy/core/shape_base.py @@ -1,3 +1,4 @@ +import _numpypy from numeric import array, asanyarray, newaxis def atleast_1d(*arys): @@ -170,3 +171,54 @@ return res[0] else: return res + +def vstack(tup): + """ + Stack arrays in sequence vertically (row wise). + + Take a sequence of arrays and stack them vertically to make a single + array. Rebuild arrays divided by `vsplit`. + + Parameters + ---------- + tup : sequence of ndarrays + Tuple containing arrays to be stacked. The arrays must have the same + shape along all but the first axis. + + Returns + ------- + stacked : ndarray + The array formed by stacking the given arrays. + + See Also + -------- + hstack : Stack arrays in sequence horizontally (column wise). + dstack : Stack arrays in sequence depth wise (along third dimension). + concatenate : Join a sequence of arrays together. + vsplit : Split array into a list of multiple sub-arrays vertically. + + Notes + ----- + Equivalent to ``np.concatenate(tup, axis=0)`` if `tup` contains arrays that + are at least 2-dimensional. + + Examples + -------- + >>> a = np.array([1, 2, 3]) + >>> b = np.array([2, 3, 4]) + >>> np.vstack((a,b)) + array([[1, 2, 3], + [2, 3, 4]]) + + >>> a = np.array([[1], [2], [3]]) + >>> b = np.array([[2], [3], [4]]) + >>> np.vstack((a,b)) + array([[1], + [2], + [3], + [2], + [3], + [4]]) + + """ + return _numpypy.concatenate(map(atleast_2d,tup),0) diff --git a/pypy/module/test_lib_pypy/numpypy/core/test_shape_base.py b/pypy/module/test_lib_pypy/numpypy/core/test_shape_base.py --- a/pypy/module/test_lib_pypy/numpypy/core/test_shape_base.py +++ b/pypy/module/test_lib_pypy/numpypy/core/test_shape_base.py @@ -60,3 +60,22 @@ a = np.atleast_3d([[[1, 2]]]) assert np.array_equal(a, [[[1, 2]]]) assert a.shape == (1, 1, 2) + + def test_vstack(self): + import numpypy as np + + a = np.array([1, 2, 3]) + b = np.array([2, 3, 4]) + c = np.vstack((a,b)) + assert np.array_equal(c, [[1, 2, 3], + [2, 3, 4]]) + + a = np.array([[1], [2], [3]]) + b = np.array([[2], [3], [4]]) + c = np.vstack((a,b)) + assert np.array_equal(c, [[1], + [2], + [3], + [2], + [3], + [4]]) From noreply at buildbot.pypy.org Mon Feb 11 11:52:46 2013 From: noreply at buildbot.pypy.org (antocuni) Date: Mon, 11 Feb 2013 11:52:46 +0100 (CET) Subject: [pypy-commit] pypy default: implement numpypy.hstack (by copying it from numpy source) Message-ID: <20130211105246.94E8F1C0041@cobra.cs.uni-duesseldorf.de> Author: Antonio Cuni Branch: Changeset: r61084:74a2914159df Date: 2013-02-11 11:52 +0100 http://bitbucket.org/pypy/pypy/changeset/74a2914159df/ Log: implement numpypy.hstack (by copying it from numpy source) diff --git a/lib_pypy/numpypy/core/shape_base.py b/lib_pypy/numpypy/core/shape_base.py --- a/lib_pypy/numpypy/core/shape_base.py +++ b/lib_pypy/numpypy/core/shape_base.py @@ -222,3 +222,53 @@ """ return _numpypy.concatenate(map(atleast_2d,tup),0) + +def hstack(tup): + """ + Stack arrays in sequence horizontally (column wise). + + Take a sequence of arrays and stack them horizontally to make + a single array. Rebuild arrays divided by `hsplit`. + + Parameters + ---------- + tup : sequence of ndarrays + All arrays must have the same shape along all but the second axis. + + Returns + ------- + stacked : ndarray + The array formed by stacking the given arrays. + + See Also + -------- + vstack : Stack arrays in sequence vertically (row wise). + dstack : Stack arrays in sequence depth wise (along third axis). + concatenate : Join a sequence of arrays together. + hsplit : Split array along second axis. + + Notes + ----- + Equivalent to ``np.concatenate(tup, axis=1)`` + + Examples + -------- + >>> a = np.array((1,2,3)) + >>> b = np.array((2,3,4)) + >>> np.hstack((a,b)) + array([1, 2, 3, 2, 3, 4]) + >>> a = np.array([[1],[2],[3]]) + >>> b = np.array([[2],[3],[4]]) + >>> np.hstack((a,b)) + array([[1, 2], + [2, 3], + [3, 4]]) + + """ + arrs = map(atleast_1d,tup) + # As a special case, dimension 0 of 1-dimensional arrays is "horizontal" + if arrs[0].ndim == 1: + return _numpypy.concatenate(arrs, 0) + else: + return _numpypy.concatenate(arrs, 1) + diff --git a/pypy/module/test_lib_pypy/numpypy/core/test_shape_base.py b/pypy/module/test_lib_pypy/numpypy/core/test_shape_base.py --- a/pypy/module/test_lib_pypy/numpypy/core/test_shape_base.py +++ b/pypy/module/test_lib_pypy/numpypy/core/test_shape_base.py @@ -79,3 +79,18 @@ [2], [3], [4]]) + + def test_hstack(self): + import numpypy as np + a = np.array((1,2,3)) + b = np.array((2,3,4)) + c = np.hstack((a,b)) + assert np.array_equal(c, [1, 2, 3, 2, 3, 4]) + + a = np.array([[1],[2],[3]]) + b = np.array([[2],[3],[4]]) + c = np.hstack((a,b)) + assert np.array_equal(c, [[1, 2], + [2, 3], + [3, 4]]) + From noreply at buildbot.pypy.org Mon Feb 11 12:37:45 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Mon, 11 Feb 2013 12:37:45 +0100 (CET) Subject: [pypy-commit] pypy default: might as well add dstack too Message-ID: <20130211113745.5B7501C01BF@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61085:5fb4c2227097 Date: 2013-02-11 06:31 -0500 http://bitbucket.org/pypy/pypy/changeset/5fb4c2227097/ Log: might as well add dstack too diff --git a/lib_pypy/numpypy/core/shape_base.py b/lib_pypy/numpypy/core/shape_base.py --- a/lib_pypy/numpypy/core/shape_base.py +++ b/lib_pypy/numpypy/core/shape_base.py @@ -272,3 +272,52 @@ else: return _numpypy.concatenate(arrs, 1) +def dstack(tup): + """ + Stack arrays in sequence depth wise (along third axis). + + Takes a sequence of arrays and stack them along the third axis + to make a single array. Rebuilds arrays divided by `dsplit`. + This is a simple way to stack 2D arrays (images) into a single + 3D array for processing. + + Parameters + ---------- + tup : sequence of arrays + Arrays to stack. All of them must have the same shape along all + but the third axis. + + Returns + ------- + stacked : ndarray + The array formed by stacking the given arrays. + + See Also + -------- + vstack : Stack along first axis. + hstack : Stack along second axis. + concatenate : Join arrays. + dsplit : Split array along third axis. + + Notes + ----- + Equivalent to ``np.concatenate(tup, axis=2)``. + + Examples + -------- + >>> a = np.array((1,2,3)) + >>> b = np.array((2,3,4)) + >>> np.dstack((a,b)) + array([[[1, 2], + [2, 3], + [3, 4]]]) + + >>> a = np.array([[1],[2],[3]]) + >>> b = np.array([[2],[3],[4]]) + >>> np.dstack((a,b)) + array([[[1, 2]], + [[2, 3]], + [[3, 4]]]) + + """ + return _numpypy.concatenate(map(atleast_3d,tup),2) diff --git a/pypy/module/test_lib_pypy/numpypy/core/test_shape_base.py b/pypy/module/test_lib_pypy/numpypy/core/test_shape_base.py --- a/pypy/module/test_lib_pypy/numpypy/core/test_shape_base.py +++ b/pypy/module/test_lib_pypy/numpypy/core/test_shape_base.py @@ -94,3 +94,14 @@ [2, 3], [3, 4]]) + def test_dstack(self): + import numpypy as np + a = np.array((1,2,3)) + b = np.array((2,3,4)) + c = np.dstack((a,b)) + assert np.array_equal(c, [[[1, 2], [2, 3], [3, 4]]]) + + a = np.array([[1],[2],[3]]) + b = np.array([[2],[3],[4]]) + c = np.dstack((a,b)) + assert np.array_equal(c, [[[1, 2]], [[2, 3]], [[3, 4]]]) From noreply at buildbot.pypy.org Mon Feb 11 12:37:46 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Mon, 11 Feb 2013 12:37:46 +0100 (CET) Subject: [pypy-commit] pypy default: add better tests for vstack/hstack/dstack and pep8-ify Message-ID: <20130211113746.960221C03D5@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61086:78f7681f3126 Date: 2013-02-11 06:37 -0500 http://bitbucket.org/pypy/pypy/changeset/78f7681f3126/ Log: add better tests for vstack/hstack/dstack and pep8-ify diff --git a/pypy/module/test_lib_pypy/numpypy/core/test_shape_base.py b/pypy/module/test_lib_pypy/numpypy/core/test_shape_base.py --- a/pypy/module/test_lib_pypy/numpypy/core/test_shape_base.py +++ b/pypy/module/test_lib_pypy/numpypy/core/test_shape_base.py @@ -1,18 +1,19 @@ from pypy.module.micronumpy.test.test_base import BaseNumpyAppTest + class AppTestShapeBase(BaseNumpyAppTest): def test_atleast_1d(self): from numpypy import array, array_equal import numpypy as np a = np.atleast_1d(1.0) - assert np.array_equal(a, [ 1.]) - - x = np.arange(9.0).reshape(3,3) + assert np.array_equal(a, [1.]) + + x = np.arange(9.0).reshape(3, 3) a = np.atleast_1d(x) - assert np.array_equal(a, [[ 0., 1., 2.], - [ 3., 4., 5.], - [ 6., 7., 8.]]) + assert np.array_equal(a, [[0., 1., 2.], + [3., 4., 5.], + [6., 7., 8.]]) assert np.atleast_1d(x) is x a = np.atleast_1d(1, [3, 4]) @@ -23,11 +24,11 @@ def test_atleast_2d(self): import numpypy as np a = np.atleast_2d(3.0) - assert np.array_equal(a, [[ 3.]]) + assert np.array_equal(a, [[3.]]) x = np.arange(3.0) a = np.atleast_2d(x) - assert np.array_equal(a, [[ 0., 1., 2.]]) + assert np.array_equal(a, [[0., 1., 2.]]) a = np.atleast_2d(1, [1, 2], [[1, 2]]) assert len(a) == 3 @@ -39,12 +40,12 @@ import numpypy as np a = np.atleast_3d(3.0) - assert np.array_equal(a, [[[ 3.]]]) + assert np.array_equal(a, [[[3.]]]) x = np.arange(3.0) assert np.atleast_3d(x).shape == (1, 3, 1) - x = np.arange(12.0).reshape(4,3) + x = np.arange(12.0).reshape(4, 3) assert np.atleast_3d(x).shape == (4, 3, 1) a = np.atleast_3d([1, 2]) @@ -66,13 +67,13 @@ a = np.array([1, 2, 3]) b = np.array([2, 3, 4]) - c = np.vstack((a,b)) + c = np.vstack((a, b)) assert np.array_equal(c, [[1, 2, 3], [2, 3, 4]]) a = np.array([[1], [2], [3]]) b = np.array([[2], [3], [4]]) - c = np.vstack((a,b)) + c = np.vstack((a, b)) assert np.array_equal(c, [[1], [2], [3], @@ -80,28 +81,80 @@ [3], [4]]) + for shape1, shape2 in [[(2, 1), (3, 1)], + [(2, 4), [3, 4]]]: + a, b = np.ones(shape1), np.ones(shape2) + assert np.all(np.vstack((a, b)) == + np.ones((a.shape[0] + b.shape[0], + a.shape[1]))) + + for shape1, shape2 in [[(3, 2, 4), (7, 2, 4)], + [(0, 2, 7), (10, 2, 7)], + [(0, 2, 7), (0, 2, 7)]]: + a, b = np.ones(shape1), np.ones(shape2) + assert np.all(np.vstack((a, b)) == + np.ones((a.shape[0] + b.shape[0], + a.shape[1], + a.shape[2]))) + def test_hstack(self): import numpypy as np - a = np.array((1,2,3)) - b = np.array((2,3,4)) - c = np.hstack((a,b)) + a = np.array((1, 2, 3)) + b = np.array((2, 3, 4)) + c = np.hstack((a, b)) assert np.array_equal(c, [1, 2, 3, 2, 3, 4]) - - a = np.array([[1],[2],[3]]) - b = np.array([[2],[3],[4]]) - c = np.hstack((a,b)) + + a = np.array([[1], [2], [3]]) + b = np.array([[2], [3], [4]]) + c = np.hstack((a, b)) assert np.array_equal(c, [[1, 2], [2, 3], [3, 4]]) + for shape1, shape2 in [[(1, 2), (1, 3)], + [(4, 2), (4, 3)]]: + a, b = np.ones(shape1), np.ones(shape2) + assert np.all(np.hstack((a, b)) == + np.ones((a.shape[0], + a.shape[1] + b.shape[1]))) + + for shape1, shape2 in [[(2, 3, 4), (2, 7, 4)], + [(1, 4, 7), (1, 10, 7)], + [(1, 4, 7), (1, 0, 7)], + [(1, 0, 7), (1, 0, 7)]]: + a, b = np.ones(shape1), np.ones(shape2) + assert np.all(np.hstack((a, b)) == + np.ones((a.shape[0], + a.shape[1] + b.shape[1], + a.shape[2]))) + def test_dstack(self): import numpypy as np - a = np.array((1,2,3)) - b = np.array((2,3,4)) - c = np.dstack((a,b)) + a = np.array((1, 2, 3)) + b = np.array((2, 3, 4)) + c = np.dstack((a, b)) assert np.array_equal(c, [[[1, 2], [2, 3], [3, 4]]]) - a = np.array([[1],[2],[3]]) - b = np.array([[2],[3],[4]]) - c = np.dstack((a,b)) + a = np.array([[1], [2], [3]]) + b = np.array([[2], [3], [4]]) + c = np.dstack((a, b)) assert np.array_equal(c, [[[1, 2]], [[2, 3]], [[3, 4]]]) + + for shape1, shape2 in [[(4, 2, 3), (4, 2, 7)], + [(7, 2, 0), (7, 2, 10)], + [(7, 2, 0), (7, 2, 0)]]: + a, b = np.ones(shape1), np.ones(shape2) + assert np.all(np.dstack((a, b)) == + np.ones((a.shape[0], + a.shape[1], + a.shape[2] + b.shape[2]))) + + for shape1, shape2 in [[(4, 2, 3, 5), (4, 2, 7, 5)], + [(7, 2, 0, 5), (7, 2, 10, 5)], + [(7, 2, 0, 5), (7, 2, 0, 5)]]: + a, b = np.ones(shape1), np.ones(shape2) + assert np.all(np.dstack((a, b)) == + np.ones((a.shape[0], + a.shape[1], + a.shape[2] + b.shape[2], + a.shape[3]))) From noreply at buildbot.pypy.org Mon Feb 11 13:51:24 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Mon, 11 Feb 2013 13:51:24 +0100 (CET) Subject: [pypy-commit] pypy default: disable these segfaulting tests for now Message-ID: <20130211125124.516831C03D5@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61087:ab09fe08b372 Date: 2013-02-11 07:51 -0500 http://bitbucket.org/pypy/pypy/changeset/ab09fe08b372/ Log: disable these segfaulting tests for now diff --git a/pypy/module/test_lib_pypy/numpypy/core/test_shape_base.py b/pypy/module/test_lib_pypy/numpypy/core/test_shape_base.py --- a/pypy/module/test_lib_pypy/numpypy/core/test_shape_base.py +++ b/pypy/module/test_lib_pypy/numpypy/core/test_shape_base.py @@ -88,6 +88,7 @@ np.ones((a.shape[0] + b.shape[0], a.shape[1]))) + skip("https://bugs.pypy.org/issue1394") for shape1, shape2 in [[(3, 2, 4), (7, 2, 4)], [(0, 2, 7), (10, 2, 7)], [(0, 2, 7), (0, 2, 7)]]: @@ -118,6 +119,7 @@ np.ones((a.shape[0], a.shape[1] + b.shape[1]))) + skip("https://bugs.pypy.org/issue1394") for shape1, shape2 in [[(2, 3, 4), (2, 7, 4)], [(1, 4, 7), (1, 10, 7)], [(1, 4, 7), (1, 0, 7)], @@ -140,6 +142,7 @@ c = np.dstack((a, b)) assert np.array_equal(c, [[[1, 2]], [[2, 3]], [[3, 4]]]) + skip("https://bugs.pypy.org/issue1394") for shape1, shape2 in [[(4, 2, 3), (4, 2, 7)], [(7, 2, 0), (7, 2, 10)], [(7, 2, 0), (7, 2, 0)]]: From noreply at buildbot.pypy.org Mon Feb 11 14:49:31 2013 From: noreply at buildbot.pypy.org (fijal) Date: Mon, 11 Feb 2013 14:49:31 +0100 (CET) Subject: [pypy-commit] pypy default: add --nostrip option to package Message-ID: <20130211134931.57BED1C01BF@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r61088:b27656a5913a Date: 2013-02-11 15:42 +0200 http://bitbucket.org/pypy/pypy/changeset/b27656a5913a/ Log: add --nostrip option to package diff --git a/pypy/tool/release/package.py b/pypy/tool/release/package.py --- a/pypy/tool/release/package.py +++ b/pypy/tool/release/package.py @@ -3,7 +3,7 @@ It uses 'pypy/goal/pypy-c' and parts of the rest of the working copy. Usage: - package.py root-pypy-dir [name-of-archive] [name-of-pypy-c] [destination-for-tarball] [pypy-c-path] + package.py root-pypy-dir [--nostrip] [name-of-archive] [name-of-pypy-c] [destination-for-tarball] [pypy-c-path] Usually you would do: package.py ../../.. pypy-VER-PLATFORM The output is found in the directory /tmp/usession-YOURNAME/build/. @@ -44,7 +44,7 @@ os.system("chmod -R a+rX %s" % basedir) def package(basedir, name='pypy-nightly', rename_pypy_c='pypy', - copy_to_dir = None, override_pypy_c = None): + copy_to_dir = None, override_pypy_c = None, nostrip=False): basedir = py.path.local(basedir) if override_pypy_c is None: basename = 'pypy-c' @@ -124,13 +124,14 @@ os.chdir(str(builddir)) # # 'strip' fun: see issue #587 - for source, target in binaries: - if sys.platform == 'win32': - pass - elif sys.platform == 'darwin': - os.system("strip -x " + str(bindir.join(target))) # ignore errors - else: - os.system("strip " + str(bindir.join(target))) # ignore errors + if not nostrip: + for source, target in binaries: + if sys.platform == 'win32': + pass + elif sys.platform == 'darwin': + os.system("strip -x " + str(bindir.join(target))) # ignore errors + else: + os.system("strip " + str(bindir.join(target))) # ignore errors # if USE_ZIPFILE_MODULE: import zipfile @@ -166,4 +167,9 @@ print >>sys.stderr, __doc__ sys.exit(1) else: - package(*sys.argv[1:]) + args = sys.argv[1:] + kw = {} + if args[0] == '--nostrip': + kw['nostrip'] = True + args = args[1:] + package(*args, **kw) From noreply at buildbot.pypy.org Mon Feb 11 14:49:32 2013 From: noreply at buildbot.pypy.org (fijal) Date: Mon, 11 Feb 2013 14:49:32 +0100 (CET) Subject: [pypy-commit] pypy default: enable lldebug Message-ID: <20130211134932.96B9C1C01BF@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r61089:b121918635b5 Date: 2013-02-11 15:47 +0200 http://bitbucket.org/pypy/pypy/changeset/b121918635b5/ Log: enable lldebug diff --git a/rpython/config/translationoption.py b/rpython/config/translationoption.py --- a/rpython/config/translationoption.py +++ b/rpython/config/translationoption.py @@ -183,6 +183,9 @@ "When true, enable the use of tagged pointers. " "If false, use normal boxing", default=False), + BoolOption("lldebug", + "If true, makes an lldebug build", default=False, + cmdline="--lldebug"), # options for ootype OptionDescription("ootype", "Object Oriented Typesystem options", [ diff --git a/rpython/translator/c/genc.py b/rpython/translator/c/genc.py --- a/rpython/translator/c/genc.py +++ b/rpython/translator/c/genc.py @@ -360,6 +360,8 @@ extra_opts = [] if self.config.translation.make_jobs != 1: extra_opts += ['-j', str(self.config.translation.make_jobs)] + if self.config.translation.lldebug: + extra_opts += ["lldebug"] self.translator.platform.execute_makefile(self.targetdir, extra_opts) if shared: From noreply at buildbot.pypy.org Mon Feb 11 14:49:34 2013 From: noreply at buildbot.pypy.org (fijal) Date: Mon, 11 Feb 2013 14:49:34 +0100 (CET) Subject: [pypy-commit] pypy default: merge Message-ID: <20130211134934.1E1FA1C01BF@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r61090:3142ec6bffd6 Date: 2013-02-11 15:48 +0200 http://bitbucket.org/pypy/pypy/changeset/3142ec6bffd6/ Log: merge diff too long, truncating to 2000 out of 2643 lines diff --git a/LICENSE b/LICENSE --- a/LICENSE +++ b/LICENSE @@ -270,3 +270,24 @@ LineBreak-*.txt UnicodeData-*.txt UnihanNumeric-*.txt + +License for 'dotviewer/font/' +============================= + +Copyright (C) 2008 The Android Open Source Project + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +Detailled license information is contained in the NOTICE file in the +directory. + diff --git a/dotviewer/VeraMoBd.ttf b/dotviewer/VeraMoBd.ttf deleted file mode 100644 Binary file dotviewer/VeraMoBd.ttf has changed diff --git a/dotviewer/cyrvetic.ttf b/dotviewer/cyrvetic.ttf deleted file mode 100644 Binary file dotviewer/cyrvetic.ttf has changed diff --git a/dotviewer/drawgraph.py b/dotviewer/drawgraph.py --- a/dotviewer/drawgraph.py +++ b/dotviewer/drawgraph.py @@ -9,9 +9,10 @@ from pygame.locals import * +RAW_ENCODING = "utf-8" this_dir = os.path.dirname(os.path.abspath(__file__)) -FONT = os.path.join(this_dir, 'cyrvetic.ttf') -FIXEDFONT = os.path.join(this_dir, 'VeraMoBd.ttf') +FONT = os.path.join(this_dir, 'font', 'DroidSans.ttf') +FIXEDFONT = os.path.join(this_dir, 'font', 'DroidSansMono.ttf') COLOR = { 'black': (0,0,0), 'white': (255,255,255), @@ -51,6 +52,12 @@ else: return default +def forceunicode(name): + return name if isinstance(name, unicode) else name.decode(RAW_ENCODING) + +def forcestr(name): + return name if isinstance(name, str) else name.encode(RAW_ENCODING) + class GraphLayout: fixedfont = False @@ -106,12 +113,12 @@ class Node: def __init__(self, name, x, y, w, h, label, style, shape, color, fillcolor): - self.name = name + self.name = forceunicode(name) self.x = float(x) self.y = float(y) self.w = float(w) self.h = float(h) - self.label = label + self.label = forceunicode(label) self.style = style self.shape = shape self.color = color @@ -125,8 +132,8 @@ label = None def __init__(self, nodes, tail, head, cnt, *rest): - self.tail = nodes[tail] - self.head = nodes[head] + self.tail = nodes[forceunicode(tail)] + self.head = nodes[forceunicode(head)] cnt = int(cnt) self.points = [(float(rest[i]), float(rest[i+1])) for i in range(0, cnt*2, 2)] @@ -655,11 +662,7 @@ part = parts[i] word = part[0] try: - try: - img = font.render(word, False, *part[1:]) - except pygame.error, e: - # Try *with* anti-aliasing to work around a bug in SDL - img = font.render(word, True, *part[1:]) + img = font.render(word, True, *part[1:]) except pygame.error: del parts[i] # Text has zero width else: diff --git a/dotviewer/font/DroidSans-Bold.ttf b/dotviewer/font/DroidSans-Bold.ttf new file mode 100644 index 0000000000000000000000000000000000000000..d065b64eb1863f83c2c982264f9442f2313a44a9 GIT binary patch [cut] diff --git a/dotviewer/font/DroidSans.ttf b/dotviewer/font/DroidSans.ttf new file mode 100644 index 0000000000000000000000000000000000000000..ad1efca88aed8d9e2d179f27dd713e2a1562fe5f GIT binary patch [cut] diff --git a/dotviewer/font/DroidSansMono.ttf b/dotviewer/font/DroidSansMono.ttf new file mode 100644 index 0000000000000000000000000000000000000000..a007071944f7c90020e798eea53b10065e2b45a5 GIT binary patch [cut] diff --git a/dotviewer/font/NOTICE b/dotviewer/font/NOTICE new file mode 100644 --- /dev/null +++ b/dotviewer/font/NOTICE @@ -0,0 +1,190 @@ + + Copyright (c) 2005-2008, The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + diff --git a/dotviewer/font/README.txt b/dotviewer/font/README.txt new file mode 100644 --- /dev/null +++ b/dotviewer/font/README.txt @@ -0,0 +1,18 @@ +Copyright (C) 2008 The Android Open Source Project + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +########## + +This directory contains the fonts for the platform. They are licensed +under the Apache 2 license. diff --git a/dotviewer/graphclient.py b/dotviewer/graphclient.py --- a/dotviewer/graphclient.py +++ b/dotviewer/graphclient.py @@ -33,8 +33,9 @@ def reload(graph_id): page = getpage(graph_id) if save_tmp_file: + from drawgraph import forcestr f = open(save_tmp_file, 'w') - f.write(page.source) + f.write(forcestr(page.source)) f.close() messages.extend(page_messages(page, graph_id)) send_graph_messages(io, messages) @@ -75,7 +76,8 @@ def page_messages(page, graph_id): import graphparse - return graphparse.parse_dot(graph_id, page.source, page.links, + from drawgraph import forcestr + return graphparse.parse_dot(graph_id, forcestr(page.source), page.links, getattr(page, 'fixedfont', False)) def send_graph_messages(io, messages): diff --git a/dotviewer/graphdisplay.py b/dotviewer/graphdisplay.py --- a/dotviewer/graphdisplay.py +++ b/dotviewer/graphdisplay.py @@ -4,7 +4,7 @@ from pygame.locals import * from drawgraph import GraphRenderer, FIXEDFONT from drawgraph import Node, Edge -from drawgraph import EventQueue, wait_for_events +from drawgraph import EventQueue, wait_for_events, forceunicode, forcestr METAKEYS = dict([ @@ -285,7 +285,7 @@ if e.key == K_ESCAPE: return None elif e.key == K_RETURN: - return text.encode('latin-1') # XXX do better + return forcestr(text) # return encoded unicode elif e.key == K_BACKSPACE: text = text[:-1] elif e.unicode and ord(e.unicode) >= ord(' '): @@ -423,7 +423,7 @@ self.layout.request_reload() def setstatusbar(self, text, fgcolor=None, bgcolor=None): - info = (text, fgcolor or self.STATUSBAR_FGCOLOR, bgcolor or self.STATUSBAR_BGCOLOR) + info = (forceunicode(text), fgcolor or self.STATUSBAR_FGCOLOR, bgcolor or self.STATUSBAR_BGCOLOR) if info != self.statusbarinfo: self.statusbarinfo = info self.must_redraw = True @@ -711,7 +711,7 @@ lines = [] while words: line = words.pop(0) - img = font.render(line or ' ', 1, fgcolor) + img = font.render(line or ' ', True, fgcolor) while words: longerline = line + ' ' + words[0] longerimg = font.render(longerline, 1, fgcolor) @@ -723,7 +723,7 @@ img = longerimg w, h = img.get_size() if h > maxheight: - img = font.render('...', 1, overflowcolor) + img = font.render('...', True, overflowcolor) w, h = img.get_size() while lines and h > maxheight: maxheight += lines.pop().get_size()[1] diff --git a/dotviewer/graphpage.py b/dotviewer/graphpage.py --- a/dotviewer/graphpage.py +++ b/dotviewer/graphpage.py @@ -44,6 +44,8 @@ class DotFileGraphPage(GraphPage): def compute(self, dotfile): - f = open(dotfile, 'r') + import codecs + from drawgraph import RAW_ENCODING + f = codecs.open(dotfile, 'r', RAW_ENCODING) self.source = f.read() f.close() diff --git a/dotviewer/test/test_interactive_unicode.py b/dotviewer/test/test_interactive_unicode.py new file mode 100755 --- /dev/null +++ b/dotviewer/test/test_interactive_unicode.py @@ -0,0 +1,103 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +import py +import sys, os, signal, thread, time, codecs +from dotviewer.conftest import option +from dotviewer.drawgraph import RAW_ENCODING + +SOURCE1 = u"""digraph G{ +λ -> b +b -> μ +} +""" + +FILENAME = 'graph1.dot' + +def setup_module(mod): + if not option.pygame: + py.test.skip("--pygame not enabled") + udir = py.path.local.make_numbered_dir(prefix='usession-dot-', keep=3) + f = codecs.open(str(udir.join(FILENAME)), 'wb', RAW_ENCODING) + f.write(SOURCE1) + f.close() + + from dotviewer import graphclient + mod.pkgdir = py.path.local(graphclient.this_dir) + mod.udir = udir + + try: + del os.environ['GRAPHSERVER'] + except KeyError: + pass + + +def test_dotviewer(): + print "=== dotviewer.py %s" % FILENAME + err = os.system('"%s" "%s"' % (pkgdir.join('dotviewer.py'), + udir.join(FILENAME))) + assert err == 0 + + plain_name = FILENAME.replace('.dot','.plain') + + os.system('dot -Tplain "%s" > "%s"' % (udir.join(FILENAME), + udir.join(plain_name))) + print "=== dotviewer.py %s" % plain_name + err = os.system('"%s" "%s"' % (pkgdir.join('dotviewer.py'), + udir.join(plain_name))) + assert err == 0 + +def test_display_dot_file(): + from dotviewer.graphclient import display_dot_file + print "=== display_dot_file(%s) with GRAPHSERVER=%s" % ( + FILENAME, os.environ.get('GRAPHSERVER', ''),) + display_dot_file(udir.join(FILENAME)) + print "=== display_dot_file finished" + + +def test_graphserver(): + import socket + s = socket.socket() + s.listen(1) + host, port = s.getsockname() # pick a random free port + s.close() + + if hasattr(sys, 'pypy_objspaceclass'): + python = 'python' + else: + python = sys.executable + + cmdargs = [python, str(pkgdir.join('graphserver.py')), + str(port)] + print '* starting:', ' '.join(cmdargs) + pid = os.spawnv(os.P_NOWAIT, cmdargs[0], cmdargs) + try: + time.sleep(1) # hack - wait a bit to make sure the server is up + os.environ['GRAPHSERVER'] = '%s:%d' % (host, port) + try: + test_display_dot_file() + finally: + del os.environ['GRAPHSERVER'] + finally: + os.kill(pid, signal.SIGTERM) + +def test_colors(): + from dotviewer import graphpage, graphclient + class MyPage(graphpage.DotFileGraphPage): + def compute(self, dotfile): + super(MyPage, self).compute(dotfile) + self.links = {'v2721': 'Hello world', + 'v2720': ('Something green', (0, 192, 0)), + } + dotfile = str(udir.join(FILENAME)) + page = MyPage(dotfile) + graphclient.display_page(page) + +def test_fixedfont(): + from dotviewer import graphpage, graphclient + class MyPage(graphpage.DotFileGraphPage): + fixedfont = True + dotfile = str(udir.join(FILENAME)) + page = MyPage(dotfile) + page.fixedfont = True + graphclient.display_page(page) diff --git a/dotviewer/test/test_translator.py b/dotviewer/test/test_translator.py --- a/dotviewer/test/test_translator.py +++ b/dotviewer/test/test_translator.py @@ -22,6 +22,6 @@ def test_annotated(): from rpython.translator.interactive import Translation - t = Translation(is_prime) - t.annotate([int]) + t = Translation(is_prime, [int]) + t.annotate() t.viewcg() diff --git a/dotviewer/test/test_unicode_util.py b/dotviewer/test/test_unicode_util.py new file mode 100755 --- /dev/null +++ b/dotviewer/test/test_unicode_util.py @@ -0,0 +1,57 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +import py +import codecs +from dotviewer.drawgraph import RAW_ENCODING, forcestr, forceunicode + +SOURCE1 = u"""digraph G{ +λ -> b +b -> μ +} +""" + +FILENAME = 'test.dot' + +class TestUnicodeUtil(object): + + def test_idempotent(self): + x = u"a" + assert forceunicode(forcestr(x)) == x + + x = u"λ" + assert forceunicode(forcestr(x)) == x + + assert forceunicode(forcestr(SOURCE1)) == SOURCE1 + + x = "a" + assert forcestr(forceunicode(x)) == x + + # utf-8 encoded. + # fragile, does not consider RAW_ENCODING + # x = "\xef\xbb\xbf\xce\xbb" + # assert forcestr(forceunicode(x)) == x + + def test_does_not_double_encode(self): + x = u"λ" + x_e = forcestr(x) + assert forcestr(x_e) == x_e + + x_u = forceunicode(x_e) + assert forceunicode(x_u) == x_u + + def test_file(self): + udir = py.path.local.make_numbered_dir(prefix='usession-dot-', keep=3) + full_filename = str(udir.join(FILENAME)) + f = codecs.open(full_filename, 'wb', RAW_ENCODING) + f.write(SOURCE1) + f.close() + + with open(full_filename) as f1: + assert forceunicode(f1.read()) == SOURCE1 + + f3 = codecs.open(full_filename, 'r', RAW_ENCODING) + c = f3.read() + f3.close() + result = (c == SOURCE1) + assert result diff --git a/lib_pypy/conftest.py b/lib_pypy/conftest.py deleted file mode 100644 --- a/lib_pypy/conftest.py +++ /dev/null @@ -1,2 +0,0 @@ - -from pypy.conftest import * diff --git a/lib_pypy/dbm.py b/lib_pypy/dbm.py --- a/lib_pypy/dbm.py +++ b/lib_pypy/dbm.py @@ -1,4 +1,4 @@ -from ctypes import Structure, c_char_p, c_int, c_void_p, CDLL +from ctypes import Structure, c_char_p, c_int, c_void_p, CDLL, POINTER, c_char import ctypes.util import os, sys @@ -11,7 +11,7 @@ class datum(Structure): _fields_ = [ - ('dptr', c_char_p), + ('dptr', POINTER(c_char)), ('dsize', c_int), ] @@ -126,8 +126,8 @@ libpath = ctypes.util.find_library('db') if not libpath: # XXX this is hopeless... - for c in '56789': - libpath = ctypes.util.find_library('db-4.%s' % c) + for c in ['5.3', '5.2', '5.1', '5.0', '4.9', '4.8', '4.7', '4.6', '4.5']: + libpath = ctypes.util.find_library('db-%s' % c) if libpath: break else: diff --git a/lib_pypy/numpypy/core/__init__.py b/lib_pypy/numpypy/core/__init__.py --- a/lib_pypy/numpypy/core/__init__.py +++ b/lib_pypy/numpypy/core/__init__.py @@ -1,2 +1,3 @@ from .fromnumeric import * from .numeric import * +from .shape_base import * diff --git a/lib_pypy/numpypy/core/numeric.py b/lib_pypy/numpypy/core/numeric.py --- a/lib_pypy/numpypy/core/numeric.py +++ b/lib_pypy/numpypy/core/numeric.py @@ -428,3 +428,76 @@ True_ = bool_(True) e = math.e pi = math.pi + +def outer(a,b): + """ + Compute the outer product of two vectors. + + Given two vectors, ``a = [a0, a1, ..., aM]`` and + ``b = [b0, b1, ..., bN]``, + the outer product [1]_ is:: + + [[a0*b0 a0*b1 ... a0*bN ] + [a1*b0 . + [ ... . + [aM*b0 aM*bN ]] + + Parameters + ---------- + a, b : array_like, shape (M,), (N,) + First and second input vectors. Inputs are flattened if they + are not already 1-dimensional. + + Returns + ------- + out : ndarray, shape (M, N) + ``out[i, j] = a[i] * b[j]`` + + See also + -------- + inner, einsum + + References + ---------- + .. [1] : G. H. Golub and C. F. van Loan, *Matrix Computations*, 3rd + ed., Baltimore, MD, Johns Hopkins University Press, 1996, + pg. 8. + + Examples + -------- + Make a (*very* coarse) grid for computing a Mandelbrot set: + + >>> rl = np.outer(np.ones((5,)), np.linspace(-2, 2, 5)) + >>> rl + array([[-2., -1., 0., 1., 2.], + [-2., -1., 0., 1., 2.], + [-2., -1., 0., 1., 2.], + [-2., -1., 0., 1., 2.], + [-2., -1., 0., 1., 2.]]) + >>> im = np.outer(1j*np.linspace(2, -2, 5), np.ones((5,))) + >>> im + array([[ 0.+2.j, 0.+2.j, 0.+2.j, 0.+2.j, 0.+2.j], + [ 0.+1.j, 0.+1.j, 0.+1.j, 0.+1.j, 0.+1.j], + [ 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j], + [ 0.-1.j, 0.-1.j, 0.-1.j, 0.-1.j, 0.-1.j], + [ 0.-2.j, 0.-2.j, 0.-2.j, 0.-2.j, 0.-2.j]]) + >>> grid = rl + im + >>> grid + array([[-2.+2.j, -1.+2.j, 0.+2.j, 1.+2.j, 2.+2.j], + [-2.+1.j, -1.+1.j, 0.+1.j, 1.+1.j, 2.+1.j], + [-2.+0.j, -1.+0.j, 0.+0.j, 1.+0.j, 2.+0.j], + [-2.-1.j, -1.-1.j, 0.-1.j, 1.-1.j, 2.-1.j], + [-2.-2.j, -1.-2.j, 0.-2.j, 1.-2.j, 2.-2.j]]) + + An example using a "vector" of letters: + + >>> x = np.array(['a', 'b', 'c'], dtype=object) + >>> np.outer(x, [1, 2, 3]) + array([[a, aa, aaa], + [b, bb, bbb], + [c, cc, ccc]], dtype=object) + + """ + a = asarray(a) + b = asarray(b) + return a.ravel()[:,newaxis]*b.ravel()[newaxis,:] diff --git a/lib_pypy/numpypy/core/shape_base.py b/lib_pypy/numpypy/core/shape_base.py new file mode 100644 --- /dev/null +++ b/lib_pypy/numpypy/core/shape_base.py @@ -0,0 +1,323 @@ +import _numpypy +from numeric import array, asanyarray, newaxis + +def atleast_1d(*arys): + """ + Convert inputs to arrays with at least one dimension. + + Scalar inputs are converted to 1-dimensional arrays, whilst + higher-dimensional inputs are preserved. + + Parameters + ---------- + arys1, arys2, ... : array_like + One or more input arrays. + + Returns + ------- + ret : ndarray + An array, or sequence of arrays, each with ``a.ndim >= 1``. + Copies are made only if necessary. + + See Also + -------- + atleast_2d, atleast_3d + + Examples + -------- + >>> np.atleast_1d(1.0) + array([ 1.]) + + >>> x = np.arange(9.0).reshape(3,3) + >>> np.atleast_1d(x) + array([[ 0., 1., 2.], + [ 3., 4., 5.], + [ 6., 7., 8.]]) + >>> np.atleast_1d(x) is x + True + + >>> np.atleast_1d(1, [3, 4]) + [array([1]), array([3, 4])] + + """ + res = [] + for ary in arys: + ary = asanyarray(ary) + if len(ary.shape) == 0 : + result = ary.reshape(1) + else : + result = ary + res.append(result) + if len(res) == 1: + return res[0] + else: + return res + + +def atleast_2d(*arys): + """ + View inputs as arrays with at least two dimensions. + + Parameters + ---------- + arys1, arys2, ... : array_like + One or more array-like sequences. Non-array inputs are converted + to arrays. Arrays that already have two or more dimensions are + preserved. + + Returns + ------- + res, res2, ... : ndarray + An array, or tuple of arrays, each with ``a.ndim >= 2``. + Copies are avoided where possible, and views with two or more + dimensions are returned. + + See Also + -------- + atleast_1d, atleast_3d + + Examples + -------- + >>> np.atleast_2d(3.0) + array([[ 3.]]) + + >>> x = np.arange(3.0) + >>> np.atleast_2d(x) + array([[ 0., 1., 2.]]) + >>> np.atleast_2d(x).base is x + True + + >>> np.atleast_2d(1, [1, 2], [[1, 2]]) + [array([[1]]), array([[1, 2]]), array([[1, 2]])] + + """ + res = [] + for ary in arys: + ary = asanyarray(ary) + if len(ary.shape) == 0 : + result = ary.reshape(1, 1) + elif len(ary.shape) == 1 : + result = ary[newaxis, :] + else : + result = ary + res.append(result) + if len(res) == 1: + return res[0] + else: + return res + +def atleast_3d(*arys): + """ + View inputs as arrays with at least three dimensions. + + Parameters + ---------- + arys1, arys2, ... : array_like + One or more array-like sequences. Non-array inputs are converted to + arrays. Arrays that already have three or more dimensions are + preserved. + + Returns + ------- + res1, res2, ... : ndarray + An array, or tuple of arrays, each with ``a.ndim >= 3``. Copies are + avoided where possible, and views with three or more dimensions are + returned. For example, a 1-D array of shape ``(N,)`` becomes a view + of shape ``(1, N, 1)``, and a 2-D array of shape ``(M, N)`` becomes a + view of shape ``(M, N, 1)``. + + See Also + -------- + atleast_1d, atleast_2d + + Examples + -------- + >>> np.atleast_3d(3.0) + array([[[ 3.]]]) + + >>> x = np.arange(3.0) + >>> np.atleast_3d(x).shape + (1, 3, 1) + + >>> x = np.arange(12.0).reshape(4,3) + >>> np.atleast_3d(x).shape + (4, 3, 1) + >>> np.atleast_3d(x).base is x + True + + >>> for arr in np.atleast_3d([1, 2], [[1, 2]], [[[1, 2]]]): + ... print arr, arr.shape + ... + [[[1] + [2]]] (1, 2, 1) + [[[1] + [2]]] (1, 2, 1) + [[[1 2]]] (1, 1, 2) + + """ + res = [] + for ary in arys: + ary = asanyarray(ary) + if len(ary.shape) == 0: + result = ary.reshape(1,1,1) + elif len(ary.shape) == 1: + result = ary[newaxis,:,newaxis] + elif len(ary.shape) == 2: + result = ary[:,:,newaxis] + else: + result = ary + res.append(result) + if len(res) == 1: + return res[0] + else: + return res + +def vstack(tup): + """ + Stack arrays in sequence vertically (row wise). + + Take a sequence of arrays and stack them vertically to make a single + array. Rebuild arrays divided by `vsplit`. + + Parameters + ---------- + tup : sequence of ndarrays + Tuple containing arrays to be stacked. The arrays must have the same + shape along all but the first axis. + + Returns + ------- + stacked : ndarray + The array formed by stacking the given arrays. + + See Also + -------- + hstack : Stack arrays in sequence horizontally (column wise). + dstack : Stack arrays in sequence depth wise (along third dimension). + concatenate : Join a sequence of arrays together. + vsplit : Split array into a list of multiple sub-arrays vertically. + + Notes + ----- + Equivalent to ``np.concatenate(tup, axis=0)`` if `tup` contains arrays that + are at least 2-dimensional. + + Examples + -------- + >>> a = np.array([1, 2, 3]) + >>> b = np.array([2, 3, 4]) + >>> np.vstack((a,b)) + array([[1, 2, 3], + [2, 3, 4]]) + + >>> a = np.array([[1], [2], [3]]) + >>> b = np.array([[2], [3], [4]]) + >>> np.vstack((a,b)) + array([[1], + [2], + [3], + [2], + [3], + [4]]) + + """ + return _numpypy.concatenate(map(atleast_2d,tup),0) + +def hstack(tup): + """ + Stack arrays in sequence horizontally (column wise). + + Take a sequence of arrays and stack them horizontally to make + a single array. Rebuild arrays divided by `hsplit`. + + Parameters + ---------- + tup : sequence of ndarrays + All arrays must have the same shape along all but the second axis. + + Returns + ------- + stacked : ndarray + The array formed by stacking the given arrays. + + See Also + -------- + vstack : Stack arrays in sequence vertically (row wise). + dstack : Stack arrays in sequence depth wise (along third axis). + concatenate : Join a sequence of arrays together. + hsplit : Split array along second axis. + + Notes + ----- + Equivalent to ``np.concatenate(tup, axis=1)`` + + Examples + -------- + >>> a = np.array((1,2,3)) + >>> b = np.array((2,3,4)) + >>> np.hstack((a,b)) + array([1, 2, 3, 2, 3, 4]) + >>> a = np.array([[1],[2],[3]]) + >>> b = np.array([[2],[3],[4]]) + >>> np.hstack((a,b)) + array([[1, 2], + [2, 3], + [3, 4]]) + + """ + arrs = map(atleast_1d,tup) + # As a special case, dimension 0 of 1-dimensional arrays is "horizontal" + if arrs[0].ndim == 1: + return _numpypy.concatenate(arrs, 0) + else: + return _numpypy.concatenate(arrs, 1) + +def dstack(tup): + """ + Stack arrays in sequence depth wise (along third axis). + + Takes a sequence of arrays and stack them along the third axis + to make a single array. Rebuilds arrays divided by `dsplit`. + This is a simple way to stack 2D arrays (images) into a single + 3D array for processing. + + Parameters + ---------- + tup : sequence of arrays + Arrays to stack. All of them must have the same shape along all + but the third axis. + + Returns + ------- + stacked : ndarray + The array formed by stacking the given arrays. + + See Also + -------- + vstack : Stack along first axis. + hstack : Stack along second axis. + concatenate : Join arrays. + dsplit : Split array along third axis. + + Notes + ----- + Equivalent to ``np.concatenate(tup, axis=2)``. + + Examples + -------- + >>> a = np.array((1,2,3)) + >>> b = np.array((2,3,4)) + >>> np.dstack((a,b)) + array([[[1, 2], + [2, 3], + [3, 4]]]) + + >>> a = np.array([[1],[2],[3]]) + >>> b = np.array([[2],[3],[4]]) + >>> np.dstack((a,b)) + array([[[1, 2]], + [[2, 3]], + [[3, 4]]]) + + """ + return _numpypy.concatenate(map(atleast_3d,tup),2) diff --git a/lib_pypy/pyrepl/cmdrepl.py b/lib_pypy/pyrepl/cmdrepl.py --- a/lib_pypy/pyrepl/cmdrepl.py +++ b/lib_pypy/pyrepl/cmdrepl.py @@ -53,8 +53,8 @@ def get_completions(self, stem): if len(stem) != self.pos: return [] - return cr.uniqify([s for s in self.completions - if s.startswith(stem)]) + return sorted(set(s for s in self.completions + if s.startswith(stem))) def replize(klass, history_across_invocations=1): diff --git a/lib_pypy/pyrepl/completing_reader.py b/lib_pypy/pyrepl/completing_reader.py --- a/lib_pypy/pyrepl/completing_reader.py +++ b/lib_pypy/pyrepl/completing_reader.py @@ -21,13 +21,6 @@ from pyrepl import commands, reader from pyrepl.reader import Reader -def uniqify(l): - d = {} - for i in l: - d[i] = 1 - r = d.keys() - r.sort() - return r def prefix(wordlist, j = 0): d = {} diff --git a/lib_pypy/pyrepl/module_lister.py b/lib_pypy/pyrepl/module_lister.py --- a/lib_pypy/pyrepl/module_lister.py +++ b/lib_pypy/pyrepl/module_lister.py @@ -17,7 +17,6 @@ # CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -from pyrepl.completing_reader import uniqify import os, sys # for the completion support. @@ -38,20 +37,12 @@ l.append( prefix + fname ) _packages[prefix + fname] = _make_module_list_dir( file, suffs, prefix + fname + '.' ) - l = uniqify(l) - l.sort() - return l + return sorted(set(l)) def _make_module_list(): import imp suffs = [x[0] for x in imp.get_suffixes() if x[0] != '.pyc'] - def compare(x, y): - c = -cmp(len(x), len(y)) - if c: - return c - else: - return -cmp(x, y) - suffs.sort(compare) + suffs.sort(reverse=True) _packages[''] = list(sys.builtin_module_names) for dir in sys.path: if dir == '': diff --git a/lib_pypy/pyrepl/python_reader.py b/lib_pypy/pyrepl/python_reader.py --- a/lib_pypy/pyrepl/python_reader.py +++ b/lib_pypy/pyrepl/python_reader.py @@ -140,7 +140,7 @@ return [x[len(mod) + 1:] for x in l if x.startswith(mod + '.' + name)] try: - l = completing_reader.uniqify(self.completer.complete(stem)) + l = sorted(set(self.completer.complete(stem))) return l except (NameError, AttributeError): return [] @@ -178,7 +178,8 @@ self.showsyntaxerror("") else: self.runcode(code) - sys.stdout.flush() + if sys.stdout and not sys.stdout.closed: + sys.stdout.flush() def interact(self): while 1: @@ -368,7 +369,7 @@ encoding = None else: encoding = None # so you get ASCII... - con = UnixConsole(0, 1, None, encoding) + con = UnixConsole(os.dup(0), os.dup(1), None, encoding) if print_banner: print "Python", sys.version, "on", sys.platform print 'Type "help", "copyright", "credits" or "license" '\ diff --git a/lib_pypy/pyrepl/reader.py b/lib_pypy/pyrepl/reader.py --- a/lib_pypy/pyrepl/reader.py +++ b/lib_pypy/pyrepl/reader.py @@ -552,6 +552,8 @@ if not event: # can only happen if we're not blocking return None + translate = True + if event.evt == 'key': self.input_trans.push(event) elif event.evt == 'scroll': @@ -559,9 +561,12 @@ elif event.evt == 'resize': self.refresh() else: - pass + translate = False - cmd = self.input_trans.get() + if translate: + cmd = self.input_trans.get() + else: + cmd = event.evt, event.data if cmd is None: if block: diff --git a/lib_pypy/pyrepl/readline.py b/lib_pypy/pyrepl/readline.py --- a/lib_pypy/pyrepl/readline.py +++ b/lib_pypy/pyrepl/readline.py @@ -174,13 +174,15 @@ # ____________________________________________________________ class _ReadlineWrapper(object): - f_in = 0 - f_out = 1 reader = None saved_history_length = -1 startup_hook = None config = ReadlineConfig() + def __init__(self, f_in=None, f_out=None): + self.f_in = f_in if f_in is not None else os.dup(0) + self.f_out = f_out if f_out is not None else os.dup(1) + def get_reader(self): if self.reader is None: console = UnixConsole(self.f_in, self.f_out, encoding=ENCODING) diff --git a/lib_pypy/pyrepl/test/test_functional.py b/lib_pypy/pyrepl/test/test_functional.py deleted file mode 100644 --- a/lib_pypy/pyrepl/test/test_functional.py +++ /dev/null @@ -1,50 +0,0 @@ -# Copyright 2000-2007 Michael Hudson-Doyle -# Maciek Fijalkowski -# -# All Rights Reserved -# -# -# Permission to use, copy, modify, and distribute this software and -# its documentation for any purpose is hereby granted without fee, -# provided that the above copyright notice appear in all copies and -# that both that copyright notice and this permission notice appear in -# supporting documentation. -# -# THE AUTHOR MICHAEL HUDSON DISCLAIMS ALL WARRANTIES WITH REGARD TO -# THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY -# AND FITNESS, IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, -# INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER -# RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF -# CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -# some functional tests, to see if this is really working - -import py -import sys - -class TestTerminal(object): - def _spawn(self, *args, **kwds): - try: - import pexpect - except ImportError, e: - py.test.skip(str(e)) - kwds.setdefault('timeout', 10) - child = pexpect.spawn(*args, **kwds) - child.logfile = sys.stdout - return child - - def spawn(self, argv=[]): - # avoid running start.py, cause it might contain - # things like readline or rlcompleter(2) included - child = self._spawn(sys.executable, ['-S'] + argv) - child.sendline('from pyrepl.python_reader import main') - child.sendline('main()') - return child - - def test_basic(self): - child = self.spawn() - child.sendline('a = 3') - child.sendline('a') - child.expect('3') - diff --git a/lib_pypy/pyrepl/tests/__init__.py b/lib_pypy/pyrepl/tests/__init__.py deleted file mode 100644 --- a/lib_pypy/pyrepl/tests/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# Copyright 2000-2004 Michael Hudson-Doyle -# -# All Rights Reserved -# -# -# Permission to use, copy, modify, and distribute this software and -# its documentation for any purpose is hereby granted without fee, -# provided that the above copyright notice appear in all copies and -# that both that copyright notice and this permission notice appear in -# supporting documentation. -# -# THE AUTHOR MICHAEL HUDSON DISCLAIMS ALL WARRANTIES WITH REGARD TO -# THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY -# AND FITNESS, IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, -# INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER -# RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF -# CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -# moo diff --git a/lib_pypy/pyrepl/tests/basic.py b/lib_pypy/pyrepl/tests/basic.py deleted file mode 100644 --- a/lib_pypy/pyrepl/tests/basic.py +++ /dev/null @@ -1,115 +0,0 @@ -# Copyright 2000-2004 Michael Hudson-Doyle -# -# All Rights Reserved -# -# -# Permission to use, copy, modify, and distribute this software and -# its documentation for any purpose is hereby granted without fee, -# provided that the above copyright notice appear in all copies and -# that both that copyright notice and this permission notice appear in -# supporting documentation. -# -# THE AUTHOR MICHAEL HUDSON DISCLAIMS ALL WARRANTIES WITH REGARD TO -# THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY -# AND FITNESS, IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, -# INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER -# RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF -# CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -from pyrepl.console import Event -from pyrepl.tests.infrastructure import ReaderTestCase, EA, run_testcase - -class SimpleTestCase(ReaderTestCase): - - def test_basic(self): - self.run_test([(('self-insert', 'a'), ['a']), - ( 'accept', ['a'])]) - - def test_repeat(self): - self.run_test([(('digit-arg', '3'), ['']), - (('self-insert', 'a'), ['aaa']), - ( 'accept', ['aaa'])]) - - def test_kill_line(self): - self.run_test([(('self-insert', 'abc'), ['abc']), - ( 'left', None), - ( 'kill-line', ['ab']), - ( 'accept', ['ab'])]) - - def test_unix_line_discard(self): - self.run_test([(('self-insert', 'abc'), ['abc']), - ( 'left', None), - ( 'unix-word-rubout', ['c']), - ( 'accept', ['c'])]) - - def test_kill_word(self): - self.run_test([(('self-insert', 'ab cd'), ['ab cd']), - ( 'beginning-of-line', ['ab cd']), - ( 'kill-word', [' cd']), - ( 'accept', [' cd'])]) - - def test_backward_kill_word(self): - self.run_test([(('self-insert', 'ab cd'), ['ab cd']), - ( 'backward-kill-word', ['ab ']), - ( 'accept', ['ab '])]) - - def test_yank(self): - self.run_test([(('self-insert', 'ab cd'), ['ab cd']), - ( 'backward-kill-word', ['ab ']), - ( 'beginning-of-line', ['ab ']), - ( 'yank', ['cdab ']), - ( 'accept', ['cdab '])]) - - def test_yank_pop(self): - self.run_test([(('self-insert', 'ab cd'), ['ab cd']), - ( 'backward-kill-word', ['ab ']), - ( 'left', ['ab ']), - ( 'backward-kill-word', [' ']), - ( 'yank', ['ab ']), - ( 'yank-pop', ['cd ']), - ( 'accept', ['cd '])]) - - def test_interrupt(self): - try: - self.run_test([( 'interrupt', [''])]) - except KeyboardInterrupt: - pass - else: - self.fail('KeyboardInterrupt got lost') - - # test_suspend -- hah - - def test_up(self): - self.run_test([(('self-insert', 'ab\ncd'), ['ab', 'cd']), - ( 'up', ['ab', 'cd']), - (('self-insert', 'e'), ['abe', 'cd']), - ( 'accept', ['abe', 'cd'])]) - - def test_down(self): - self.run_test([(('self-insert', 'ab\ncd'), ['ab', 'cd']), - ( 'up', ['ab', 'cd']), - (('self-insert', 'e'), ['abe', 'cd']), - ( 'down', ['abe', 'cd']), - (('self-insert', 'f'), ['abe', 'cdf']), - ( 'accept', ['abe', 'cdf'])]) - - def test_left(self): - self.run_test([(('self-insert', 'ab'), ['ab']), - ( 'left', ['ab']), - (('self-insert', 'c'), ['acb']), - ( 'accept', ['acb'])]) - - def test_right(self): - self.run_test([(('self-insert', 'ab'), ['ab']), - ( 'left', ['ab']), - (('self-insert', 'c'), ['acb']), - ( 'right', ['acb']), - (('self-insert', 'd'), ['acbd']), - ( 'accept', ['acbd'])]) - -def test(): - run_testcase(SimpleTestCase) - -if __name__ == '__main__': - test() diff --git a/lib_pypy/pyrepl/tests/bugs.py b/lib_pypy/pyrepl/tests/bugs.py deleted file mode 100644 --- a/lib_pypy/pyrepl/tests/bugs.py +++ /dev/null @@ -1,36 +0,0 @@ -# Copyright 2000-2004 Michael Hudson-Doyle -# -# All Rights Reserved -# -# -# Permission to use, copy, modify, and distribute this software and -# its documentation for any purpose is hereby granted without fee, -# provided that the above copyright notice appear in all copies and -# that both that copyright notice and this permission notice appear in -# supporting documentation. -# -# THE AUTHOR MICHAEL HUDSON DISCLAIMS ALL WARRANTIES WITH REGARD TO -# THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY -# AND FITNESS, IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, -# INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER -# RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF -# CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -from pyrepl.console import Event -from pyrepl.tests.infrastructure import ReaderTestCase, EA, run_testcase - -# this test case should contain as-verbatim-as-possible versions of -# (applicable) bug reports - -class BugsTestCase(ReaderTestCase): - - def test_transpose_at_start(self): - self.run_test([( 'transpose', [EA, '']), - ( 'accept', [''])]) - -def test(): - run_testcase(BugsTestCase) - -if __name__ == '__main__': - test() diff --git a/lib_pypy/pyrepl/tests/infrastructure.py b/lib_pypy/pyrepl/tests/infrastructure.py deleted file mode 100644 --- a/lib_pypy/pyrepl/tests/infrastructure.py +++ /dev/null @@ -1,82 +0,0 @@ -# Copyright 2000-2004 Michael Hudson-Doyle -# -# All Rights Reserved -# -# -# Permission to use, copy, modify, and distribute this software and -# its documentation for any purpose is hereby granted without fee, -# provided that the above copyright notice appear in all copies and -# that both that copyright notice and this permission notice appear in -# supporting documentation. -# -# THE AUTHOR MICHAEL HUDSON DISCLAIMS ALL WARRANTIES WITH REGARD TO -# THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY -# AND FITNESS, IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, -# INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER -# RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF -# CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -from pyrepl.reader import Reader -from pyrepl.console import Console, Event -import unittest -import sys - -class EqualsAnything(object): - def __eq__(self, other): - return True -EA = EqualsAnything() - -class TestConsole(Console): - height = 24 - width = 80 - encoding = 'utf-8' - - def __init__(self, events, testcase, verbose=False): - self.events = events - self.next_screen = None - self.verbose = verbose - self.testcase = testcase - - def refresh(self, screen, xy): - if self.next_screen is not None: - self.testcase.assertEqual( - screen, self.next_screen, - "[ %s != %s after %r ]"%(screen, self.next_screen, - self.last_event_name)) - - def get_event(self, block=1): - ev, sc = self.events.pop(0) - self.next_screen = sc - if not isinstance(ev, tuple): - ev = (ev,) - self.last_event_name = ev[0] - if self.verbose: - print "event", ev - return Event(*ev) - -class TestReader(Reader): - def get_prompt(self, lineno, cursor_on_line): - return '' - def refresh(self): - Reader.refresh(self) - self.dirty = True - -class ReaderTestCase(unittest.TestCase): - def run_test(self, test_spec, reader_class=TestReader): - # remember to finish your test_spec with 'accept' or similar! - con = TestConsole(test_spec, self) - reader = reader_class(con) - reader.readline() - -class BasicTestRunner: - def run(self, test): - result = unittest.TestResult() - test(result) - return result - -def run_testcase(testclass): - suite = unittest.makeSuite(testclass) - runner = unittest.TextTestRunner(sys.stdout, verbosity=1) - result = runner.run(suite) - diff --git a/lib_pypy/pyrepl/tests/wishes.py b/lib_pypy/pyrepl/tests/wishes.py deleted file mode 100644 --- a/lib_pypy/pyrepl/tests/wishes.py +++ /dev/null @@ -1,38 +0,0 @@ -# Copyright 2000-2004 Michael Hudson-Doyle -# -# All Rights Reserved -# -# -# Permission to use, copy, modify, and distribute this software and -# its documentation for any purpose is hereby granted without fee, -# provided that the above copyright notice appear in all copies and -# that both that copyright notice and this permission notice appear in -# supporting documentation. -# -# THE AUTHOR MICHAEL HUDSON DISCLAIMS ALL WARRANTIES WITH REGARD TO -# THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY -# AND FITNESS, IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, -# INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER -# RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF -# CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -from pyrepl.console import Event -from pyrepl.tests.infrastructure import ReaderTestCase, EA, run_testcase - -# this test case should contain as-verbatim-as-possible versions of -# (applicable) feature requests - -class WishesTestCase(ReaderTestCase): - - def test_quoted_insert_repeat(self): - self.run_test([(('digit-arg', '3'), ['']), - ( 'quoted-insert', ['']), - (('self-insert', '\033'), ['^[^[^[']), - ( 'accept', None)]) - -def test(): - run_testcase(WishesTestCase) - -if __name__ == '__main__': - test() diff --git a/lib_pypy/pyrepl/unix_console.py b/lib_pypy/pyrepl/unix_console.py --- a/lib_pypy/pyrepl/unix_console.py +++ b/lib_pypy/pyrepl/unix_console.py @@ -185,16 +185,6 @@ old_offset = offset = self.__offset height = self.height - if 0: - global counter - try: - counter - except NameError: - counter = 0 - self.__write_code(curses.tigetstr("setaf"), counter) - counter += 1 - if counter > 8: - counter = 0 # we make sure the cursor is on the screen, and that we're # using all of the screen if we can diff --git a/pypy/interpreter/app_main.py b/pypy/interpreter/app_main.py --- a/pypy/interpreter/app_main.py +++ b/pypy/interpreter/app_main.py @@ -310,8 +310,6 @@ "warnoptions", "unbuffered"), 0) -PYTHON26 = True - def simple_option(options, name, iterargv): options[name] += 1 @@ -341,38 +339,35 @@ cmdline_options = { # simple options just increment the counter of the options listed above + 'b': (simple_option, 'bytes_warning'), + 'B': (simple_option, 'dont_write_bytecode'), 'd': (simple_option, 'debug'), + 'E': (simple_option, 'ignore_environment'), 'i': (simple_option, 'interactive'), 'O': (simple_option, 'optimize'), + 'R': (simple_option, 'hash_randomization'), + 's': (simple_option, 'no_user_site'), 'S': (simple_option, 'no_site'), - 'E': (simple_option, 'ignore_environment'), 't': (simple_option, 'tabcheck'), - 'v': (simple_option, 'verbose'), 'U': (simple_option, 'unicode'), 'u': (simple_option, 'unbuffered'), + 'v': (simple_option, 'verbose'), + '3': (simple_option, 'py3k_warning'), # more complex options - 'Q': (div_option, Ellipsis), 'c': (c_option, Ellipsis), + '?': (print_help, None), + 'h': (print_help, None), + '--help': (print_help, None), 'm': (m_option, Ellipsis), 'W': (W_option, Ellipsis), 'V': (print_version, None), '--version': (print_version, None), + 'Q': (div_option, Ellipsis), '--info': (print_info, None), - 'h': (print_help, None), - '--help': (print_help, None), '--jit': (set_jit_option, Ellipsis), '--': (end_options, None), } -if PYTHON26: - cmdline_options.update({ - '3': (simple_option, 'py3k_warning'), - 'B': (simple_option, 'dont_write_bytecode'), - 's': (simple_option, 'no_user_site'), - 'b': (simple_option, 'bytes_warning'), - 'R': (simple_option, 'hash_randomization'), - }) - def handle_argument(c, options, iterargv, iterarg=iter(())): function, funcarg = cmdline_options[c] @@ -432,13 +427,16 @@ sys.argv[:] = argv if not options["ignore_environment"]: + if os.getenv('PYTHONDEBUG'): + options["debug"] = 1 + if os.getenv('PYTHONDONTWRITEBYTECODE'): + options["dont_write_bytecode"] = 1 + if os.getenv('PYTHONNOUSERSITE'): + options["no_user_site"] = 1 if os.getenv('PYTHONUNBUFFERED'): options["unbuffered"] = 1 - if PYTHON26: - if os.getenv('PYTHONNOUSERSITE'): - options["no_user_site"] = 1 - if os.getenv('PYTHONDONTWRITEBYTECODE'): - options["dont_write_bytecode"] = 1 + if os.getenv('PYTHONVERBOSE'): + options["verbose"] = 1 if (options["interactive"] or (not options["ignore_environment"] and os.getenv('PYTHONINSPECT'))): @@ -450,7 +448,7 @@ ## print >> sys.stderr, ( ## "Warning: pypy does not implement hash randomization") - if PYTHON26 and we_are_translated(): + if we_are_translated(): flags = [options[flag] for flag in sys_flags] sys.flags = type(sys.flags)(flags) sys.py3kwarning = bool(sys.flags.py3k_warning) diff --git a/pypy/interpreter/test2/test_app_main.py b/pypy/interpreter/test2/test_app_main.py --- a/pypy/interpreter/test2/test_app_main.py +++ b/pypy/interpreter/test2/test_app_main.py @@ -81,14 +81,16 @@ assert not value, ( "option %r has unexpectedly the value %r" % (key, value)) - def check(self, argv, **expected): + def check(self, argv, env, **expected): import StringIO from pypy.interpreter import app_main + saved_env = os.environ.copy() saved_sys_argv = sys.argv[:] saved_sys_stdout = sys.stdout saved_sys_stderr = sys.stdout app_main.os = os try: + os.environ.update(env) sys.stdout = sys.stderr = StringIO.StringIO() try: options = app_main.parse_command_line(argv) @@ -98,64 +100,73 @@ else: self.check_options(options, **expected) finally: + os.environ.clear() + os.environ.update(saved_env) sys.argv[:] = saved_sys_argv sys.stdout = saved_sys_stdout sys.stderr = saved_sys_stderr def test_all_combinations_I_can_think_of(self): - self.check([], sys_argv=[''], run_stdin=True) - self.check(['-'], sys_argv=['-'], run_stdin=True) - self.check(['-S'], sys_argv=[''], run_stdin=True, no_site=1) - self.check(['-OO'], sys_argv=[''], run_stdin=True, optimize=2) - self.check(['-O', '-O'], sys_argv=[''], run_stdin=True, optimize=2) - self.check(['-Qnew'], sys_argv=[''], run_stdin=True, division_new=1) - self.check(['-Qold'], sys_argv=[''], run_stdin=True, division_new=0) - self.check(['-Qwarn'], sys_argv=[''], run_stdin=True, division_warning=1) - self.check(['-Qwarnall'], sys_argv=[''], run_stdin=True, + self.check([], {}, sys_argv=[''], run_stdin=True) + self.check(['-'], {}, sys_argv=['-'], run_stdin=True) + self.check(['-S'], {}, sys_argv=[''], run_stdin=True, no_site=1) + self.check(['-OO'], {}, sys_argv=[''], run_stdin=True, optimize=2) + self.check(['-O', '-O'], {}, sys_argv=[''], run_stdin=True, optimize=2) + self.check(['-Qnew'], {}, sys_argv=[''], run_stdin=True, division_new=1) + self.check(['-Qold'], {}, sys_argv=[''], run_stdin=True, division_new=0) + self.check(['-Qwarn'], {}, sys_argv=[''], run_stdin=True, division_warning=1) + self.check(['-Qwarnall'], {}, sys_argv=[''], run_stdin=True, division_warning=2) - self.check(['-Q', 'new'], sys_argv=[''], run_stdin=True, division_new=1) - self.check(['-SOQnew'], sys_argv=[''], run_stdin=True, + self.check(['-Q', 'new'], {}, sys_argv=[''], run_stdin=True, division_new=1) + self.check(['-SOQnew'], {}, sys_argv=[''], run_stdin=True, no_site=1, optimize=1, division_new=1) - self.check(['-SOQ', 'new'], sys_argv=[''], run_stdin=True, + self.check(['-SOQ', 'new'], {}, sys_argv=[''], run_stdin=True, no_site=1, optimize=1, division_new=1) - self.check(['-i'], sys_argv=[''], run_stdin=True, + self.check(['-i'], {}, sys_argv=[''], run_stdin=True, interactive=1, inspect=1) - self.check(['-h'], output_contains='usage:') - self.check(['-S', '-tO', '-h'], output_contains='usage:') - self.check(['-S', '-thO'], output_contains='usage:') - self.check(['-S', '-tO', '--help'], output_contains='usage:') - self.check(['-S', '-tO', '--info'], output_contains='translation') - self.check(['-S', '-tO', '--version'], output_contains='Python') - self.check(['-S', '-tOV'], output_contains='Python') - self.check(['--jit', 'foobar', '-S'], sys_argv=[''], + self.check(['-?'], {}, output_contains='usage:') + self.check(['-h'], {}, output_contains='usage:') + self.check(['-S', '-tO', '-h'], {}, output_contains='usage:') + self.check(['-S', '-thO'], {}, output_contains='usage:') + self.check(['-S', '-tO', '--help'], {}, output_contains='usage:') + self.check(['-S', '-tO', '--info'], {}, output_contains='translation') + self.check(['-S', '-tO', '--version'], {}, output_contains='Python') + self.check(['-S', '-tOV'], {}, output_contains='Python') + self.check(['--jit', 'foobar', '-S'], {}, sys_argv=[''], run_stdin=True, no_site=1) - self.check(['-c', 'pass'], sys_argv=['-c'], run_command='pass') - self.check(['-cpass'], sys_argv=['-c'], run_command='pass') - self.check(['-cpass','x'], sys_argv=['-c','x'], run_command='pass') - self.check(['-Sc', 'pass'], sys_argv=['-c'], run_command='pass', + self.check(['-c', 'pass'], {}, sys_argv=['-c'], run_command='pass') + self.check(['-cpass'], {}, sys_argv=['-c'], run_command='pass') + self.check(['-cpass','x'], {}, sys_argv=['-c','x'], run_command='pass') + self.check(['-Sc', 'pass'], {}, sys_argv=['-c'], run_command='pass', no_site=1) - self.check(['-Scpass'], sys_argv=['-c'], run_command='pass', no_site=1) - self.check(['-c', '', ''], sys_argv=['-c', ''], run_command='') - self.check(['-mfoo', 'bar', 'baz'], sys_argv=['foo', 'bar', 'baz'], + self.check(['-Scpass'], {}, sys_argv=['-c'], run_command='pass', no_site=1) + self.check(['-c', '', ''], {}, sys_argv=['-c', ''], run_command='') + self.check(['-mfoo', 'bar', 'baz'], {}, sys_argv=['foo', 'bar', 'baz'], run_module=True) - self.check(['-m', 'foo', 'bar', 'baz'], sys_argv=['foo', 'bar', 'baz'], + self.check(['-m', 'foo', 'bar', 'baz'], {}, sys_argv=['foo', 'bar', 'baz'], run_module=True) - self.check(['-Smfoo', 'bar', 'baz'], sys_argv=['foo', 'bar', 'baz'], + self.check(['-Smfoo', 'bar', 'baz'], {}, sys_argv=['foo', 'bar', 'baz'], run_module=True, no_site=1) - self.check(['-Sm', 'foo', 'bar', 'baz'], sys_argv=['foo', 'bar', 'baz'], + self.check(['-Sm', 'foo', 'bar', 'baz'], {}, sys_argv=['foo', 'bar', 'baz'], run_module=True, no_site=1) - self.check(['-', 'foo', 'bar'], sys_argv=['-', 'foo', 'bar'], + self.check(['-', 'foo', 'bar'], {}, sys_argv=['-', 'foo', 'bar'], run_stdin=True) - self.check(['foo', 'bar'], sys_argv=['foo', 'bar']) - self.check(['foo', '-i'], sys_argv=['foo', '-i']) - self.check(['-i', 'foo'], sys_argv=['foo'], interactive=1, inspect=1) - self.check(['--', 'foo'], sys_argv=['foo']) - self.check(['--', '-i', 'foo'], sys_argv=['-i', 'foo']) - self.check(['--', '-', 'foo'], sys_argv=['-', 'foo'], run_stdin=True) - self.check(['-Wbog'], sys_argv=[''], warnoptions=['bog'], run_stdin=True) - self.check(['-W', 'ab', '-SWc'], sys_argv=[''], warnoptions=['ab', 'c'], + self.check(['foo', 'bar'], {}, sys_argv=['foo', 'bar']) + self.check(['foo', '-i'], {}, sys_argv=['foo', '-i']) + self.check(['-i', 'foo'], {}, sys_argv=['foo'], interactive=1, inspect=1) + self.check(['--', 'foo'], {}, sys_argv=['foo']) + self.check(['--', '-i', 'foo'], {}, sys_argv=['-i', 'foo']) + self.check(['--', '-', 'foo'], {}, sys_argv=['-', 'foo'], run_stdin=True) + self.check(['-Wbog'], {}, sys_argv=[''], warnoptions=['bog'], run_stdin=True) + self.check(['-W', 'ab', '-SWc'], {}, sys_argv=[''], warnoptions=['ab', 'c'], run_stdin=True, no_site=1) + self.check([], {'PYTHONDEBUG': '1'}, sys_argv=[''], run_stdin=True, debug=1) + self.check([], {'PYTHONDONTWRITEBYTECODE': '1'}, sys_argv=[''], run_stdin=True, dont_write_bytecode=1) + self.check([], {'PYTHONNOUSERSITE': '1'}, sys_argv=[''], run_stdin=True, no_user_site=1) + self.check([], {'PYTHONUNBUFFERED': '1'}, sys_argv=[''], run_stdin=True, unbuffered=1) + self.check([], {'PYTHONVERBOSE': '1'}, sys_argv=[''], run_stdin=True, verbose=1) + def test_sysflags(self): flags = ( ("debug", "-d", "1"), @@ -183,13 +194,13 @@ expected[flag1] = int(value) else: expected = {flag: int(value)} - self.check([opt, '-c', 'pass'], sys_argv=['-c'], + self.check([opt, '-c', 'pass'], {}, sys_argv=['-c'], run_command='pass', **expected) def test_sysflags_envvar(self, monkeypatch): monkeypatch.setenv('PYTHONNOUSERSITE', '1') expected = {"no_user_site": True} - self.check(['-c', 'pass'], sys_argv=['-c'], run_command='pass', **expected) + self.check(['-c', 'pass'], {}, sys_argv=['-c'], run_command='pass', **expected) class TestInteraction: diff --git a/pypy/module/test_lib_pypy/numpypy/core/test_numeric.py b/pypy/module/test_lib_pypy/numpypy/core/test_numeric.py --- a/pypy/module/test_lib_pypy/numpypy/core/test_numeric.py +++ b/pypy/module/test_lib_pypy/numpypy/core/test_numeric.py @@ -178,3 +178,17 @@ assert not array_equal(a, array(b)) assert not array_equal(array(a), b) assert not array_equal(array(a), array(b)) + +class AppTestNumeric(BaseNumpyAppTest): + + def test_outer(self): + from _numpypy import array + from numpypy import outer + a = [1, 2, 3] + b = [4, 5, 6] + res = outer(a, b) + expected = array([[ 4, 5, 6], + [ 8, 10, 12], + [12, 15, 18]]) + assert (res == expected).all() + diff --git a/pypy/module/test_lib_pypy/numpypy/core/test_shape_base.py b/pypy/module/test_lib_pypy/numpypy/core/test_shape_base.py new file mode 100644 --- /dev/null +++ b/pypy/module/test_lib_pypy/numpypy/core/test_shape_base.py @@ -0,0 +1,163 @@ +from pypy.module.micronumpy.test.test_base import BaseNumpyAppTest + + +class AppTestShapeBase(BaseNumpyAppTest): + + def test_atleast_1d(self): + from numpypy import array, array_equal + import numpypy as np + a = np.atleast_1d(1.0) + assert np.array_equal(a, [1.]) + + x = np.arange(9.0).reshape(3, 3) + a = np.atleast_1d(x) + assert np.array_equal(a, [[0., 1., 2.], + [3., 4., 5.], + [6., 7., 8.]]) + assert np.atleast_1d(x) is x + + a = np.atleast_1d(1, [3, 4]) + assert len(a) == 2 + assert array_equal(a[0], [1]) + assert array_equal(a[1], [3, 4]) + + def test_atleast_2d(self): + import numpypy as np + a = np.atleast_2d(3.0) + assert np.array_equal(a, [[3.]]) + + x = np.arange(3.0) + a = np.atleast_2d(x) + assert np.array_equal(a, [[0., 1., 2.]]) + + a = np.atleast_2d(1, [1, 2], [[1, 2]]) + assert len(a) == 3 + assert np.array_equal(a[0], [[1]]) + assert np.array_equal(a[1], [[1, 2]]) + assert np.array_equal(a[2], [[1, 2]]) + + def test_atleast_3d(self): + import numpypy as np + + a = np.atleast_3d(3.0) + assert np.array_equal(a, [[[3.]]]) + + x = np.arange(3.0) + assert np.atleast_3d(x).shape == (1, 3, 1) + + x = np.arange(12.0).reshape(4, 3) + assert np.atleast_3d(x).shape == (4, 3, 1) + + a = np.atleast_3d([1, 2]) + assert np.array_equal(a, [[[1], + [2]]]) + assert a.shape == (1, 2, 1) + + a = np.atleast_3d([[1, 2]]) + assert np.array_equal(a, [[[1], + [2]]]) + assert a.shape == (1, 2, 1) + + a = np.atleast_3d([[[1, 2]]]) + assert np.array_equal(a, [[[1, 2]]]) + assert a.shape == (1, 1, 2) + + def test_vstack(self): + import numpypy as np + + a = np.array([1, 2, 3]) + b = np.array([2, 3, 4]) + c = np.vstack((a, b)) + assert np.array_equal(c, [[1, 2, 3], + [2, 3, 4]]) + + a = np.array([[1], [2], [3]]) + b = np.array([[2], [3], [4]]) + c = np.vstack((a, b)) + assert np.array_equal(c, [[1], + [2], + [3], + [2], + [3], + [4]]) + + for shape1, shape2 in [[(2, 1), (3, 1)], + [(2, 4), [3, 4]]]: + a, b = np.ones(shape1), np.ones(shape2) + assert np.all(np.vstack((a, b)) == + np.ones((a.shape[0] + b.shape[0], + a.shape[1]))) + + skip("https://bugs.pypy.org/issue1394") + for shape1, shape2 in [[(3, 2, 4), (7, 2, 4)], + [(0, 2, 7), (10, 2, 7)], + [(0, 2, 7), (0, 2, 7)]]: + a, b = np.ones(shape1), np.ones(shape2) + assert np.all(np.vstack((a, b)) == + np.ones((a.shape[0] + b.shape[0], + a.shape[1], + a.shape[2]))) + + def test_hstack(self): + import numpypy as np + a = np.array((1, 2, 3)) + b = np.array((2, 3, 4)) + c = np.hstack((a, b)) + assert np.array_equal(c, [1, 2, 3, 2, 3, 4]) + + a = np.array([[1], [2], [3]]) + b = np.array([[2], [3], [4]]) + c = np.hstack((a, b)) + assert np.array_equal(c, [[1, 2], + [2, 3], + [3, 4]]) + + for shape1, shape2 in [[(1, 2), (1, 3)], + [(4, 2), (4, 3)]]: + a, b = np.ones(shape1), np.ones(shape2) + assert np.all(np.hstack((a, b)) == + np.ones((a.shape[0], + a.shape[1] + b.shape[1]))) + + skip("https://bugs.pypy.org/issue1394") + for shape1, shape2 in [[(2, 3, 4), (2, 7, 4)], + [(1, 4, 7), (1, 10, 7)], + [(1, 4, 7), (1, 0, 7)], + [(1, 0, 7), (1, 0, 7)]]: + a, b = np.ones(shape1), np.ones(shape2) + assert np.all(np.hstack((a, b)) == + np.ones((a.shape[0], + a.shape[1] + b.shape[1], + a.shape[2]))) + + def test_dstack(self): + import numpypy as np + a = np.array((1, 2, 3)) + b = np.array((2, 3, 4)) + c = np.dstack((a, b)) + assert np.array_equal(c, [[[1, 2], [2, 3], [3, 4]]]) + From noreply at buildbot.pypy.org Mon Feb 11 14:52:24 2013 From: noreply at buildbot.pypy.org (fijal) Date: Mon, 11 Feb 2013 14:52:24 +0100 (CET) Subject: [pypy-commit] pypy default: document the option Message-ID: <20130211135224.550F91C03D5@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r61091:e6a2a179b6ae Date: 2013-02-11 15:51 +0200 http://bitbucket.org/pypy/pypy/changeset/e6a2a179b6ae/ Log: document the option diff --git a/pypy/doc/config/translation.lldebug.txt b/pypy/doc/config/translation.lldebug.txt new file mode 100644 --- /dev/null +++ b/pypy/doc/config/translation.lldebug.txt @@ -0,0 +1,1 @@ +Run make lldebug when source is ready From noreply at buildbot.pypy.org Mon Feb 11 14:53:17 2013 From: noreply at buildbot.pypy.org (antocuni) Date: Mon, 11 Feb 2013 14:53:17 +0100 (CET) Subject: [pypy-commit] pypy default: fix issue1000: None is an acceptable value for numpypy floats and has to be converted to NaN Message-ID: <20130211135317.A90C11C03D5@cobra.cs.uni-duesseldorf.de> Author: Antonio Cuni Branch: Changeset: r61092:0805e1ac97db Date: 2013-02-11 14:52 +0100 http://bitbucket.org/pypy/pypy/changeset/0805e1ac97db/ Log: fix issue1000: None is an acceptable value for numpypy floats and has to be converted to NaN diff --git a/pypy/module/micronumpy/test/test_dtypes.py b/pypy/module/micronumpy/test/test_dtypes.py --- a/pypy/module/micronumpy/test/test_dtypes.py +++ b/pypy/module/micronumpy/test/test_dtypes.py @@ -496,6 +496,13 @@ assert numpy.float64('23.4') == numpy.float64(23.4) raises(ValueError, numpy.float64, '23.2df') + def test_float_None(self): + import _numpypy as numpy + from math import isnan + assert isnan(numpy.float32(None)) + assert isnan(numpy.float64(None)) + assert isnan(numpy.float128(None)) + def test_longfloat(self): import _numpypy as numpy # it can be float96 or float128 diff --git a/pypy/module/micronumpy/types.py b/pypy/module/micronumpy/types.py --- a/pypy/module/micronumpy/types.py +++ b/pypy/module/micronumpy/types.py @@ -648,6 +648,8 @@ _mixin_ = True def _coerce(self, space, w_item): + if space.is_none(w_item): + return self.box(rfloat.NAN) return self.box(space.float_w(space.call_function(space.w_float, w_item))) def str_format(self, box): From noreply at buildbot.pypy.org Mon Feb 11 14:53:18 2013 From: noreply at buildbot.pypy.org (antocuni) Date: Mon, 11 Feb 2013 14:53:18 +0100 (CET) Subject: [pypy-commit] pypy default: merge heads Message-ID: <20130211135318.E03C41C03D5@cobra.cs.uni-duesseldorf.de> Author: Antonio Cuni Branch: Changeset: r61093:bed85891f7c2 Date: 2013-02-11 14:53 +0100 http://bitbucket.org/pypy/pypy/changeset/bed85891f7c2/ Log: merge heads diff --git a/lib_pypy/numpypy/core/shape_base.py b/lib_pypy/numpypy/core/shape_base.py --- a/lib_pypy/numpypy/core/shape_base.py +++ b/lib_pypy/numpypy/core/shape_base.py @@ -272,3 +272,52 @@ else: return _numpypy.concatenate(arrs, 1) +def dstack(tup): + """ + Stack arrays in sequence depth wise (along third axis). + + Takes a sequence of arrays and stack them along the third axis + to make a single array. Rebuilds arrays divided by `dsplit`. + This is a simple way to stack 2D arrays (images) into a single + 3D array for processing. + + Parameters + ---------- + tup : sequence of arrays + Arrays to stack. All of them must have the same shape along all + but the third axis. + + Returns + ------- + stacked : ndarray + The array formed by stacking the given arrays. + + See Also + -------- + vstack : Stack along first axis. + hstack : Stack along second axis. + concatenate : Join arrays. + dsplit : Split array along third axis. + + Notes + ----- + Equivalent to ``np.concatenate(tup, axis=2)``. + + Examples + -------- + >>> a = np.array((1,2,3)) + >>> b = np.array((2,3,4)) + >>> np.dstack((a,b)) + array([[[1, 2], + [2, 3], + [3, 4]]]) + + >>> a = np.array([[1],[2],[3]]) + >>> b = np.array([[2],[3],[4]]) + >>> np.dstack((a,b)) + array([[[1, 2]], + [[2, 3]], + [[3, 4]]]) + + """ + return _numpypy.concatenate(map(atleast_3d,tup),2) diff --git a/pypy/doc/config/translation.lldebug.txt b/pypy/doc/config/translation.lldebug.txt new file mode 100644 --- /dev/null +++ b/pypy/doc/config/translation.lldebug.txt @@ -0,0 +1,1 @@ +Run make lldebug when source is ready diff --git a/pypy/module/test_lib_pypy/numpypy/core/test_shape_base.py b/pypy/module/test_lib_pypy/numpypy/core/test_shape_base.py --- a/pypy/module/test_lib_pypy/numpypy/core/test_shape_base.py +++ b/pypy/module/test_lib_pypy/numpypy/core/test_shape_base.py @@ -1,18 +1,19 @@ from pypy.module.micronumpy.test.test_base import BaseNumpyAppTest + class AppTestShapeBase(BaseNumpyAppTest): def test_atleast_1d(self): from numpypy import array, array_equal import numpypy as np a = np.atleast_1d(1.0) - assert np.array_equal(a, [ 1.]) - - x = np.arange(9.0).reshape(3,3) + assert np.array_equal(a, [1.]) + + x = np.arange(9.0).reshape(3, 3) a = np.atleast_1d(x) - assert np.array_equal(a, [[ 0., 1., 2.], - [ 3., 4., 5.], - [ 6., 7., 8.]]) + assert np.array_equal(a, [[0., 1., 2.], + [3., 4., 5.], + [6., 7., 8.]]) assert np.atleast_1d(x) is x a = np.atleast_1d(1, [3, 4]) @@ -23,11 +24,11 @@ def test_atleast_2d(self): import numpypy as np a = np.atleast_2d(3.0) - assert np.array_equal(a, [[ 3.]]) + assert np.array_equal(a, [[3.]]) x = np.arange(3.0) a = np.atleast_2d(x) - assert np.array_equal(a, [[ 0., 1., 2.]]) + assert np.array_equal(a, [[0., 1., 2.]]) a = np.atleast_2d(1, [1, 2], [[1, 2]]) assert len(a) == 3 @@ -39,12 +40,12 @@ import numpypy as np a = np.atleast_3d(3.0) - assert np.array_equal(a, [[[ 3.]]]) + assert np.array_equal(a, [[[3.]]]) x = np.arange(3.0) assert np.atleast_3d(x).shape == (1, 3, 1) - x = np.arange(12.0).reshape(4,3) + x = np.arange(12.0).reshape(4, 3) assert np.atleast_3d(x).shape == (4, 3, 1) a = np.atleast_3d([1, 2]) @@ -66,13 +67,13 @@ a = np.array([1, 2, 3]) b = np.array([2, 3, 4]) - c = np.vstack((a,b)) + c = np.vstack((a, b)) assert np.array_equal(c, [[1, 2, 3], [2, 3, 4]]) a = np.array([[1], [2], [3]]) b = np.array([[2], [3], [4]]) - c = np.vstack((a,b)) + c = np.vstack((a, b)) assert np.array_equal(c, [[1], [2], [3], @@ -80,17 +81,83 @@ [3], [4]]) + for shape1, shape2 in [[(2, 1), (3, 1)], + [(2, 4), [3, 4]]]: + a, b = np.ones(shape1), np.ones(shape2) + assert np.all(np.vstack((a, b)) == + np.ones((a.shape[0] + b.shape[0], + a.shape[1]))) + + skip("https://bugs.pypy.org/issue1394") + for shape1, shape2 in [[(3, 2, 4), (7, 2, 4)], + [(0, 2, 7), (10, 2, 7)], + [(0, 2, 7), (0, 2, 7)]]: + a, b = np.ones(shape1), np.ones(shape2) + assert np.all(np.vstack((a, b)) == + np.ones((a.shape[0] + b.shape[0], + a.shape[1], + a.shape[2]))) + def test_hstack(self): import numpypy as np - a = np.array((1,2,3)) - b = np.array((2,3,4)) - c = np.hstack((a,b)) + a = np.array((1, 2, 3)) + b = np.array((2, 3, 4)) + c = np.hstack((a, b)) assert np.array_equal(c, [1, 2, 3, 2, 3, 4]) - - a = np.array([[1],[2],[3]]) - b = np.array([[2],[3],[4]]) - c = np.hstack((a,b)) + + a = np.array([[1], [2], [3]]) + b = np.array([[2], [3], [4]]) + c = np.hstack((a, b)) assert np.array_equal(c, [[1, 2], [2, 3], [3, 4]]) + for shape1, shape2 in [[(1, 2), (1, 3)], + [(4, 2), (4, 3)]]: + a, b = np.ones(shape1), np.ones(shape2) + assert np.all(np.hstack((a, b)) == + np.ones((a.shape[0], + a.shape[1] + b.shape[1]))) + + skip("https://bugs.pypy.org/issue1394") + for shape1, shape2 in [[(2, 3, 4), (2, 7, 4)], + [(1, 4, 7), (1, 10, 7)], + [(1, 4, 7), (1, 0, 7)], + [(1, 0, 7), (1, 0, 7)]]: + a, b = np.ones(shape1), np.ones(shape2) + assert np.all(np.hstack((a, b)) == + np.ones((a.shape[0], + a.shape[1] + b.shape[1], + a.shape[2]))) + + def test_dstack(self): + import numpypy as np + a = np.array((1, 2, 3)) + b = np.array((2, 3, 4)) + c = np.dstack((a, b)) + assert np.array_equal(c, [[[1, 2], [2, 3], [3, 4]]]) + + a = np.array([[1], [2], [3]]) + b = np.array([[2], [3], [4]]) + c = np.dstack((a, b)) + assert np.array_equal(c, [[[1, 2]], [[2, 3]], [[3, 4]]]) + + skip("https://bugs.pypy.org/issue1394") + for shape1, shape2 in [[(4, 2, 3), (4, 2, 7)], + [(7, 2, 0), (7, 2, 10)], + [(7, 2, 0), (7, 2, 0)]]: + a, b = np.ones(shape1), np.ones(shape2) + assert np.all(np.dstack((a, b)) == + np.ones((a.shape[0], + a.shape[1], + a.shape[2] + b.shape[2]))) + + for shape1, shape2 in [[(4, 2, 3, 5), (4, 2, 7, 5)], + [(7, 2, 0, 5), (7, 2, 10, 5)], + [(7, 2, 0, 5), (7, 2, 0, 5)]]: + a, b = np.ones(shape1), np.ones(shape2) + assert np.all(np.dstack((a, b)) == + np.ones((a.shape[0], + a.shape[1], + a.shape[2] + b.shape[2], + a.shape[3]))) diff --git a/pypy/tool/release/package.py b/pypy/tool/release/package.py --- a/pypy/tool/release/package.py +++ b/pypy/tool/release/package.py @@ -3,7 +3,7 @@ It uses 'pypy/goal/pypy-c' and parts of the rest of the working copy. Usage: - package.py root-pypy-dir [name-of-archive] [name-of-pypy-c] [destination-for-tarball] [pypy-c-path] + package.py root-pypy-dir [--nostrip] [name-of-archive] [name-of-pypy-c] [destination-for-tarball] [pypy-c-path] Usually you would do: package.py ../../.. pypy-VER-PLATFORM The output is found in the directory /tmp/usession-YOURNAME/build/. @@ -44,7 +44,7 @@ os.system("chmod -R a+rX %s" % basedir) def package(basedir, name='pypy-nightly', rename_pypy_c='pypy', - copy_to_dir = None, override_pypy_c = None): + copy_to_dir = None, override_pypy_c = None, nostrip=False): basedir = py.path.local(basedir) if override_pypy_c is None: basename = 'pypy-c' @@ -124,13 +124,14 @@ os.chdir(str(builddir)) # # 'strip' fun: see issue #587 - for source, target in binaries: - if sys.platform == 'win32': - pass - elif sys.platform == 'darwin': - os.system("strip -x " + str(bindir.join(target))) # ignore errors - else: - os.system("strip " + str(bindir.join(target))) # ignore errors + if not nostrip: + for source, target in binaries: + if sys.platform == 'win32': + pass + elif sys.platform == 'darwin': + os.system("strip -x " + str(bindir.join(target))) # ignore errors + else: + os.system("strip " + str(bindir.join(target))) # ignore errors # if USE_ZIPFILE_MODULE: import zipfile @@ -166,4 +167,9 @@ print >>sys.stderr, __doc__ sys.exit(1) else: - package(*sys.argv[1:]) + args = sys.argv[1:] + kw = {} + if args[0] == '--nostrip': + kw['nostrip'] = True + args = args[1:] + package(*args, **kw) diff --git a/rpython/config/translationoption.py b/rpython/config/translationoption.py --- a/rpython/config/translationoption.py +++ b/rpython/config/translationoption.py @@ -183,6 +183,9 @@ "When true, enable the use of tagged pointers. " "If false, use normal boxing", default=False), + BoolOption("lldebug", + "If true, makes an lldebug build", default=False, + cmdline="--lldebug"), # options for ootype OptionDescription("ootype", "Object Oriented Typesystem options", [ diff --git a/rpython/translator/c/genc.py b/rpython/translator/c/genc.py --- a/rpython/translator/c/genc.py +++ b/rpython/translator/c/genc.py @@ -360,6 +360,8 @@ extra_opts = [] if self.config.translation.make_jobs != 1: extra_opts += ['-j', str(self.config.translation.make_jobs)] + if self.config.translation.lldebug: + extra_opts += ["lldebug"] self.translator.platform.execute_makefile(self.targetdir, extra_opts) if shared: From noreply at buildbot.pypy.org Mon Feb 11 15:01:11 2013 From: noreply at buildbot.pypy.org (fijal) Date: Mon, 11 Feb 2013 15:01:11 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: fix test_regalloc Message-ID: <20130211140111.8B2401C03D5@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61094:8d6028ef2cb6 Date: 2013-02-11 15:59 +0200 http://bitbucket.org/pypy/pypy/changeset/8d6028ef2cb6/ Log: fix test_regalloc diff --git a/rpython/jit/backend/x86/regalloc.py b/rpython/jit/backend/x86/regalloc.py --- a/rpython/jit/backend/x86/regalloc.py +++ b/rpython/jit/backend/x86/regalloc.py @@ -194,7 +194,9 @@ assert isinstance(box, Box) loc = self.fm.get_new_loc(box) locs.append(loc.value) - looptoken.compiled_loop_token._x86_initial_locs = locs + if looptoken.compiled_loop_token is not None: + # for tests + looptoken.compiled_loop_token._x86_initial_locs = locs def possibly_free_var(self, var): if var.type == FLOAT: From noreply at buildbot.pypy.org Mon Feb 11 15:01:12 2013 From: noreply at buildbot.pypy.org (fijal) Date: Mon, 11 Feb 2013 15:01:12 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: merge Message-ID: <20130211140112.B1E1B1C03D5@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61095:60480aa850b8 Date: 2013-02-11 16:00 +0200 http://bitbucket.org/pypy/pypy/changeset/60480aa850b8/ Log: merge diff --git a/rpython/jit/backend/x86/jump.py b/rpython/jit/backend/x86/jump.py --- a/rpython/jit/backend/x86/jump.py +++ b/rpython/jit/backend/x86/jump.py @@ -1,6 +1,7 @@ import sys from rpython.tool.pairtype import extendabletype -from rpython.jit.backend.x86.regloc import ImmediateAssemblerLocation, StackLoc +from rpython.jit.backend.x86.regloc import ImmediateAssemblerLocation +from rpython.jit.backend.x86.regloc import RegLoc, StackLoc def remap_frame_layout(assembler, src_locations, dst_locations, tmpreg): pending_dests = len(dst_locations) diff --git a/rpython/jit/backend/x86/regloc.py b/rpython/jit/backend/x86/regloc.py --- a/rpython/jit/backend/x86/regloc.py +++ b/rpython/jit/backend/x86/regloc.py @@ -53,9 +53,6 @@ self.value = value self.type = type - def _getregkey(self): - return -(self.value * 2 + 2) - def get_width(self): if self.type == FLOAT: return 8 @@ -80,11 +77,12 @@ _location_code = 's' def __init__(self, value, type): + assert value >= 0 self.value = value self.type = type def _getregkey(self): - return -(self.value * 2 + 1) + return ~self.value def get_width(self): if self.type == FLOAT: @@ -107,8 +105,7 @@ # _getregkey() returns self.value; the value returned must not # conflict with RegLoc._getregkey(). It doesn't a bit by chance, # so let it fail the following assert if it no longer does. - assert ebp_offset >= 0 - #assert not (0 <= ebp_offset < 8 + 8 * IS_X86_64) + assert ebp_offset >= 8 + 8 * IS_X86_64 self.position = position #if position != 9999: # assert (position + JITFRAME_FIXED_SIZE) * WORD == ebp_offset From noreply at buildbot.pypy.org Mon Feb 11 17:34:11 2013 From: noreply at buildbot.pypy.org (antocuni) Date: Mon, 11 Feb 2013 17:34:11 +0100 (CET) Subject: [pypy-commit] pypy default: fix Issue1389 and Issue1281: we need to interpret the dtype before doing the comparison with the existing one Message-ID: <20130211163411.651A91C004F@cobra.cs.uni-duesseldorf.de> Author: Antonio Cuni Branch: Changeset: r61096:2d3671965584 Date: 2013-02-11 17:32 +0100 http://bitbucket.org/pypy/pypy/changeset/2d3671965584/ Log: fix Issue1389 and Issue1281: we need to interpret the dtype before doing the comparison with the existing one diff --git a/pypy/module/micronumpy/interp_numarray.py b/pypy/module/micronumpy/interp_numarray.py --- a/pypy/module/micronumpy/interp_numarray.py +++ b/pypy/module/micronumpy/interp_numarray.py @@ -904,15 +904,17 @@ if order != 'C': # or order != 'F': raise operationerrfmt(space.w_ValueError, "Unknown order: %s", order) + + dtype = interp_dtype.decode_w_dtype(space, w_dtype) if isinstance(w_object, W_NDimArray): if (not space.is_none(w_dtype) and - w_object.get_dtype() is not w_dtype): + w_object.get_dtype() is not dtype): raise OperationError(space.w_NotImplementedError, space.wrap( "copying over different dtypes unsupported")) if copy: return w_object.descr_copy(space) return w_object - dtype = interp_dtype.decode_w_dtype(space, w_dtype) + shape, elems_w = find_shape_and_elems(space, w_object, dtype) if dtype is None: for w_elem in elems_w: diff --git a/pypy/module/micronumpy/test/test_numarray.py b/pypy/module/micronumpy/test/test_numarray.py --- a/pypy/module/micronumpy/test/test_numarray.py +++ b/pypy/module/micronumpy/test/test_numarray.py @@ -1733,6 +1733,13 @@ assert a[1] == 0xff assert len(a.data) == 16 + + def test_explicit_dtype_conversion(self): + from _numpypy import array + a = array([1.0, 2.0]) + b = array(a, dtype='d') + assert a.dtype is b.dtype + class AppTestMultiDim(BaseNumpyAppTest): def test_init(self): import _numpypy From noreply at buildbot.pypy.org Mon Feb 11 19:53:29 2013 From: noreply at buildbot.pypy.org (mattip) Date: Mon, 11 Feb 2013 19:53:29 +0100 (CET) Subject: [pypy-commit] pypy default: add failing test that corrupts memory Message-ID: <20130211185329.6871E1C004F@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: Changeset: r61097:77172e93542b Date: 2013-02-11 17:54 +0200 http://bitbucket.org/pypy/pypy/changeset/77172e93542b/ Log: add failing test that corrupts memory diff --git a/pypy/module/micronumpy/test/test_numarray.py b/pypy/module/micronumpy/test/test_numarray.py --- a/pypy/module/micronumpy/test/test_numarray.py +++ b/pypy/module/micronumpy/test/test_numarray.py @@ -49,6 +49,9 @@ a = create_array([10, 5, 3], MockDtype(), order='C') assert a.strides == [15, 3, 1] assert a.backstrides == [135, 12, 2] + a = create_array([1, 0, 7], MockDtype(), order='C') + assert a.strides == [7, 7, 1] + assert a.backstrides == [-7, -7, 6] def test_create_slice_f(self): a = create_array([10, 5, 3], MockDtype(), order='F') From noreply at buildbot.pypy.org Mon Feb 11 19:53:30 2013 From: noreply at buildbot.pypy.org (mattip) Date: Mon, 11 Feb 2013 19:53:30 +0100 (CET) Subject: [pypy-commit] pypy default: allow 0 in shape for concatenate Message-ID: <20130211185330.BA5981C01BF@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: Changeset: r61098:5401a6758467 Date: 2013-02-11 20:37 +0200 http://bitbucket.org/pypy/pypy/changeset/5401a6758467/ Log: allow 0 in shape for concatenate diff --git a/pypy/module/micronumpy/interp_arrayops.py b/pypy/module/micronumpy/interp_arrayops.py --- a/pypy/module/micronumpy/interp_arrayops.py +++ b/pypy/module/micronumpy/interp_arrayops.py @@ -123,6 +123,8 @@ chunks = [Chunk(0, i, 1, i) for i in shape] axis_start = 0 for arr in args_w: + if arr.get_shape()[axis] == 0: + continue chunks[axis] = Chunk(axis_start, axis_start + arr.get_shape()[axis], 1, arr.get_shape()[axis]) Chunks(chunks).apply(res).implementation.setslice(space, arr) diff --git a/pypy/module/micronumpy/iter.py b/pypy/module/micronumpy/iter.py --- a/pypy/module/micronumpy/iter.py +++ b/pypy/module/micronumpy/iter.py @@ -4,7 +4,7 @@ http://docs.scipy.org/doc/numpy/reference/arrays.ndarray.html for a more gentle introduction. -Given an array x: x.shape == [5,6], +Given an array x: x.shape == [5,6], where each element occupies one byte At which byte in x.data does the item x[3,4] begin? if x.strides==[1,5]: diff --git a/pypy/module/micronumpy/strides.py b/pypy/module/micronumpy/strides.py --- a/pypy/module/micronumpy/strides.py +++ b/pypy/module/micronumpy/strides.py @@ -28,7 +28,7 @@ for i, chunk in enumerate_chunks(chunks): if chunk.step != 0: rstrides[j] = strides[i] * chunk.step - rbackstrides[j] = strides[i] * (chunk.lgt - 1) * chunk.step + rbackstrides[j] = strides[i] * max(0, chunk.lgt - 1) * chunk.step rshape[j] = chunk.lgt j += 1 rstart += strides[i] * chunk.start diff --git a/pypy/module/micronumpy/support.py b/pypy/module/micronumpy/support.py --- a/pypy/module/micronumpy/support.py +++ b/pypy/module/micronumpy/support.py @@ -23,9 +23,10 @@ if order == 'C': shape_rev.reverse() for sh in shape_rev: + slimit = max(sh, 1) strides.append(s * dtype.get_size()) - backstrides.append(s * (sh - 1) * dtype.get_size()) - s *= sh + backstrides.append(s * (slimit - 1) * dtype.get_size()) + s *= slimit if order == 'C': strides.reverse() backstrides.reverse() diff --git a/pypy/module/micronumpy/test/test_numarray.py b/pypy/module/micronumpy/test/test_numarray.py --- a/pypy/module/micronumpy/test/test_numarray.py +++ b/pypy/module/micronumpy/test/test_numarray.py @@ -51,7 +51,7 @@ assert a.backstrides == [135, 12, 2] a = create_array([1, 0, 7], MockDtype(), order='C') assert a.strides == [7, 7, 1] - assert a.backstrides == [-7, -7, 6] + assert a.backstrides == [0, 0, 6] def test_create_slice_f(self): a = create_array([10, 5, 3], MockDtype(), order='F') From noreply at buildbot.pypy.org Mon Feb 11 19:53:31 2013 From: noreply at buildbot.pypy.org (mattip) Date: Mon, 11 Feb 2013 19:53:31 +0100 (CET) Subject: [pypy-commit] pypy default: unskip concatenate tests Message-ID: <20130211185331.DE04D1C004F@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: Changeset: r61099:5b7bc878b043 Date: 2013-02-11 20:38 +0200 http://bitbucket.org/pypy/pypy/changeset/5b7bc878b043/ Log: unskip concatenate tests diff --git a/pypy/module/test_lib_pypy/numpypy/core/test_shape_base.py b/pypy/module/test_lib_pypy/numpypy/core/test_shape_base.py --- a/pypy/module/test_lib_pypy/numpypy/core/test_shape_base.py +++ b/pypy/module/test_lib_pypy/numpypy/core/test_shape_base.py @@ -88,7 +88,7 @@ np.ones((a.shape[0] + b.shape[0], a.shape[1]))) - skip("https://bugs.pypy.org/issue1394") + #skip("https://bugs.pypy.org/issue1394") for shape1, shape2 in [[(3, 2, 4), (7, 2, 4)], [(0, 2, 7), (10, 2, 7)], [(0, 2, 7), (0, 2, 7)]]: @@ -119,7 +119,7 @@ np.ones((a.shape[0], a.shape[1] + b.shape[1]))) - skip("https://bugs.pypy.org/issue1394") + #skip("https://bugs.pypy.org/issue1394") for shape1, shape2 in [[(2, 3, 4), (2, 7, 4)], [(1, 4, 7), (1, 10, 7)], [(1, 4, 7), (1, 0, 7)], @@ -129,7 +129,7 @@ np.ones((a.shape[0], a.shape[1] + b.shape[1], a.shape[2]))) - + def test_dstack(self): import numpypy as np a = np.array((1, 2, 3)) @@ -142,7 +142,7 @@ c = np.dstack((a, b)) assert np.array_equal(c, [[[1, 2]], [[2, 3]], [[3, 4]]]) - skip("https://bugs.pypy.org/issue1394") + #skip("https://bugs.pypy.org/issue1394") for shape1, shape2 in [[(4, 2, 3), (4, 2, 7)], [(7, 2, 0), (7, 2, 10)], [(7, 2, 0), (7, 2, 0)]]: From noreply at buildbot.pypy.org Mon Feb 11 19:53:33 2013 From: noreply at buildbot.pypy.org (mattip) Date: Mon, 11 Feb 2013 19:53:33 +0100 (CET) Subject: [pypy-commit] pypy default: fix test for 32 bit Message-ID: <20130211185333.1063F1C004F@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: Changeset: r61100:620e4dab1ebe Date: 2013-02-11 20:43 +0200 http://bitbucket.org/pypy/pypy/changeset/620e4dab1ebe/ Log: fix test for 32 bit diff --git a/pypy/module/micronumpy/test/test_dtypes.py b/pypy/module/micronumpy/test/test_dtypes.py --- a/pypy/module/micronumpy/test/test_dtypes.py +++ b/pypy/module/micronumpy/test/test_dtypes.py @@ -501,7 +501,7 @@ from math import isnan assert isnan(numpy.float32(None)) assert isnan(numpy.float64(None)) - assert isnan(numpy.float128(None)) + assert isnan(numpy.longdouble(None)) def test_longfloat(self): import _numpypy as numpy From noreply at buildbot.pypy.org Mon Feb 11 19:53:34 2013 From: noreply at buildbot.pypy.org (mattip) Date: Mon, 11 Feb 2013 19:53:34 +0100 (CET) Subject: [pypy-commit] pypy default: merge heads Message-ID: <20130211185334.44F071C004F@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: Changeset: r61101:69281cba1f44 Date: 2013-02-11 20:45 +0200 http://bitbucket.org/pypy/pypy/changeset/69281cba1f44/ Log: merge heads diff --git a/pypy/module/micronumpy/interp_numarray.py b/pypy/module/micronumpy/interp_numarray.py --- a/pypy/module/micronumpy/interp_numarray.py +++ b/pypy/module/micronumpy/interp_numarray.py @@ -904,15 +904,17 @@ if order != 'C': # or order != 'F': raise operationerrfmt(space.w_ValueError, "Unknown order: %s", order) + + dtype = interp_dtype.decode_w_dtype(space, w_dtype) if isinstance(w_object, W_NDimArray): if (not space.is_none(w_dtype) and - w_object.get_dtype() is not w_dtype): + w_object.get_dtype() is not dtype): raise OperationError(space.w_NotImplementedError, space.wrap( "copying over different dtypes unsupported")) if copy: return w_object.descr_copy(space) return w_object - dtype = interp_dtype.decode_w_dtype(space, w_dtype) + shape, elems_w = find_shape_and_elems(space, w_object, dtype) if dtype is None: for w_elem in elems_w: diff --git a/pypy/module/micronumpy/test/test_numarray.py b/pypy/module/micronumpy/test/test_numarray.py --- a/pypy/module/micronumpy/test/test_numarray.py +++ b/pypy/module/micronumpy/test/test_numarray.py @@ -1736,6 +1736,13 @@ assert a[1] == 0xff assert len(a.data) == 16 + + def test_explicit_dtype_conversion(self): + from _numpypy import array + a = array([1.0, 2.0]) + b = array(a, dtype='d') + assert a.dtype is b.dtype + class AppTestMultiDim(BaseNumpyAppTest): def test_init(self): import _numpypy From noreply at buildbot.pypy.org Mon Feb 11 22:30:36 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Mon, 11 Feb 2013 22:30:36 +0100 (CET) Subject: [pypy-commit] pypy py3k: merge default Message-ID: <20130211213036.E8A551C11A8@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61102:c74ea2c79961 Date: 2013-02-11 13:25 -0800 http://bitbucket.org/pypy/pypy/changeset/c74ea2c79961/ Log: merge default diff too long, truncating to 2000 out of 12961 lines diff --git a/LICENSE b/LICENSE --- a/LICENSE +++ b/LICENSE @@ -270,3 +270,24 @@ LineBreak-*.txt UnicodeData-*.txt UnihanNumeric-*.txt + +License for 'dotviewer/font/' +============================= + +Copyright (C) 2008 The Android Open Source Project + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +Detailled license information is contained in the NOTICE file in the +directory. + diff --git a/dotviewer/VeraMoBd.ttf b/dotviewer/VeraMoBd.ttf deleted file mode 100644 Binary file dotviewer/VeraMoBd.ttf has changed diff --git a/dotviewer/cyrvetic.ttf b/dotviewer/cyrvetic.ttf deleted file mode 100644 Binary file dotviewer/cyrvetic.ttf has changed diff --git a/dotviewer/drawgraph.py b/dotviewer/drawgraph.py --- a/dotviewer/drawgraph.py +++ b/dotviewer/drawgraph.py @@ -9,9 +9,10 @@ from pygame.locals import * +RAW_ENCODING = "utf-8" this_dir = os.path.dirname(os.path.abspath(__file__)) -FONT = os.path.join(this_dir, 'cyrvetic.ttf') -FIXEDFONT = os.path.join(this_dir, 'VeraMoBd.ttf') +FONT = os.path.join(this_dir, 'font', 'DroidSans.ttf') +FIXEDFONT = os.path.join(this_dir, 'font', 'DroidSansMono.ttf') COLOR = { 'black': (0,0,0), 'white': (255,255,255), @@ -51,6 +52,12 @@ else: return default +def forceunicode(name): + return name if isinstance(name, unicode) else name.decode(RAW_ENCODING) + +def forcestr(name): + return name if isinstance(name, str) else name.encode(RAW_ENCODING) + class GraphLayout: fixedfont = False @@ -106,12 +113,12 @@ class Node: def __init__(self, name, x, y, w, h, label, style, shape, color, fillcolor): - self.name = name + self.name = forceunicode(name) self.x = float(x) self.y = float(y) self.w = float(w) self.h = float(h) - self.label = label + self.label = forceunicode(label) self.style = style self.shape = shape self.color = color @@ -125,8 +132,8 @@ label = None def __init__(self, nodes, tail, head, cnt, *rest): - self.tail = nodes[tail] - self.head = nodes[head] + self.tail = nodes[forceunicode(tail)] + self.head = nodes[forceunicode(head)] cnt = int(cnt) self.points = [(float(rest[i]), float(rest[i+1])) for i in range(0, cnt*2, 2)] @@ -655,11 +662,7 @@ part = parts[i] word = part[0] try: - try: - img = font.render(word, False, *part[1:]) - except pygame.error, e: - # Try *with* anti-aliasing to work around a bug in SDL - img = font.render(word, True, *part[1:]) + img = font.render(word, True, *part[1:]) except pygame.error: del parts[i] # Text has zero width else: diff --git a/dotviewer/font/DroidSans-Bold.ttf b/dotviewer/font/DroidSans-Bold.ttf new file mode 100644 index 0000000000000000000000000000000000000000..d065b64eb1863f83c2c982264f9442f2313a44a9 GIT binary patch [cut] diff --git a/dotviewer/font/DroidSans.ttf b/dotviewer/font/DroidSans.ttf new file mode 100644 index 0000000000000000000000000000000000000000..ad1efca88aed8d9e2d179f27dd713e2a1562fe5f GIT binary patch [cut] diff --git a/dotviewer/font/DroidSansMono.ttf b/dotviewer/font/DroidSansMono.ttf new file mode 100644 index 0000000000000000000000000000000000000000..a007071944f7c90020e798eea53b10065e2b45a5 GIT binary patch [cut] diff --git a/dotviewer/font/NOTICE b/dotviewer/font/NOTICE new file mode 100644 --- /dev/null +++ b/dotviewer/font/NOTICE @@ -0,0 +1,190 @@ + + Copyright (c) 2005-2008, The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + diff --git a/dotviewer/font/README.txt b/dotviewer/font/README.txt new file mode 100644 --- /dev/null +++ b/dotviewer/font/README.txt @@ -0,0 +1,18 @@ +Copyright (C) 2008 The Android Open Source Project + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +########## + +This directory contains the fonts for the platform. They are licensed +under the Apache 2 license. diff --git a/dotviewer/graphclient.py b/dotviewer/graphclient.py --- a/dotviewer/graphclient.py +++ b/dotviewer/graphclient.py @@ -33,8 +33,9 @@ def reload(graph_id): page = getpage(graph_id) if save_tmp_file: + from drawgraph import forcestr f = open(save_tmp_file, 'w') - f.write(page.source) + f.write(forcestr(page.source)) f.close() messages.extend(page_messages(page, graph_id)) send_graph_messages(io, messages) @@ -75,7 +76,8 @@ def page_messages(page, graph_id): import graphparse - return graphparse.parse_dot(graph_id, page.source, page.links, + from drawgraph import forcestr + return graphparse.parse_dot(graph_id, forcestr(page.source), page.links, getattr(page, 'fixedfont', False)) def send_graph_messages(io, messages): diff --git a/dotviewer/graphdisplay.py b/dotviewer/graphdisplay.py --- a/dotviewer/graphdisplay.py +++ b/dotviewer/graphdisplay.py @@ -4,7 +4,7 @@ from pygame.locals import * from drawgraph import GraphRenderer, FIXEDFONT from drawgraph import Node, Edge -from drawgraph import EventQueue, wait_for_events +from drawgraph import EventQueue, wait_for_events, forceunicode, forcestr METAKEYS = dict([ @@ -285,7 +285,7 @@ if e.key == K_ESCAPE: return None elif e.key == K_RETURN: - return text.encode('latin-1') # XXX do better + return forcestr(text) # return encoded unicode elif e.key == K_BACKSPACE: text = text[:-1] elif e.unicode and ord(e.unicode) >= ord(' '): @@ -423,7 +423,7 @@ self.layout.request_reload() def setstatusbar(self, text, fgcolor=None, bgcolor=None): - info = (text, fgcolor or self.STATUSBAR_FGCOLOR, bgcolor or self.STATUSBAR_BGCOLOR) + info = (forceunicode(text), fgcolor or self.STATUSBAR_FGCOLOR, bgcolor or self.STATUSBAR_BGCOLOR) if info != self.statusbarinfo: self.statusbarinfo = info self.must_redraw = True @@ -711,7 +711,7 @@ lines = [] while words: line = words.pop(0) - img = font.render(line or ' ', 1, fgcolor) + img = font.render(line or ' ', True, fgcolor) while words: longerline = line + ' ' + words[0] longerimg = font.render(longerline, 1, fgcolor) @@ -723,7 +723,7 @@ img = longerimg w, h = img.get_size() if h > maxheight: - img = font.render('...', 1, overflowcolor) + img = font.render('...', True, overflowcolor) w, h = img.get_size() while lines and h > maxheight: maxheight += lines.pop().get_size()[1] diff --git a/dotviewer/graphpage.py b/dotviewer/graphpage.py --- a/dotviewer/graphpage.py +++ b/dotviewer/graphpage.py @@ -44,6 +44,8 @@ class DotFileGraphPage(GraphPage): def compute(self, dotfile): - f = open(dotfile, 'r') + import codecs + from drawgraph import RAW_ENCODING + f = codecs.open(dotfile, 'r', RAW_ENCODING) self.source = f.read() f.close() diff --git a/dotviewer/test/test_interactive_unicode.py b/dotviewer/test/test_interactive_unicode.py new file mode 100755 --- /dev/null +++ b/dotviewer/test/test_interactive_unicode.py @@ -0,0 +1,103 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +import py +import sys, os, signal, thread, time, codecs +from dotviewer.conftest import option +from dotviewer.drawgraph import RAW_ENCODING + +SOURCE1 = u"""digraph G{ +λ -> b +b -> μ +} +""" + +FILENAME = 'graph1.dot' + +def setup_module(mod): + if not option.pygame: + py.test.skip("--pygame not enabled") + udir = py.path.local.make_numbered_dir(prefix='usession-dot-', keep=3) + f = codecs.open(str(udir.join(FILENAME)), 'wb', RAW_ENCODING) + f.write(SOURCE1) + f.close() + + from dotviewer import graphclient + mod.pkgdir = py.path.local(graphclient.this_dir) + mod.udir = udir + + try: + del os.environ['GRAPHSERVER'] + except KeyError: + pass + + +def test_dotviewer(): + print "=== dotviewer.py %s" % FILENAME + err = os.system('"%s" "%s"' % (pkgdir.join('dotviewer.py'), + udir.join(FILENAME))) + assert err == 0 + + plain_name = FILENAME.replace('.dot','.plain') + + os.system('dot -Tplain "%s" > "%s"' % (udir.join(FILENAME), + udir.join(plain_name))) + print "=== dotviewer.py %s" % plain_name + err = os.system('"%s" "%s"' % (pkgdir.join('dotviewer.py'), + udir.join(plain_name))) + assert err == 0 + +def test_display_dot_file(): + from dotviewer.graphclient import display_dot_file + print "=== display_dot_file(%s) with GRAPHSERVER=%s" % ( + FILENAME, os.environ.get('GRAPHSERVER', ''),) + display_dot_file(udir.join(FILENAME)) + print "=== display_dot_file finished" + + +def test_graphserver(): + import socket + s = socket.socket() + s.listen(1) + host, port = s.getsockname() # pick a random free port + s.close() + + if hasattr(sys, 'pypy_objspaceclass'): + python = 'python' + else: + python = sys.executable + + cmdargs = [python, str(pkgdir.join('graphserver.py')), + str(port)] + print '* starting:', ' '.join(cmdargs) + pid = os.spawnv(os.P_NOWAIT, cmdargs[0], cmdargs) + try: + time.sleep(1) # hack - wait a bit to make sure the server is up + os.environ['GRAPHSERVER'] = '%s:%d' % (host, port) + try: + test_display_dot_file() + finally: + del os.environ['GRAPHSERVER'] + finally: + os.kill(pid, signal.SIGTERM) + +def test_colors(): + from dotviewer import graphpage, graphclient + class MyPage(graphpage.DotFileGraphPage): + def compute(self, dotfile): + super(MyPage, self).compute(dotfile) + self.links = {'v2721': 'Hello world', + 'v2720': ('Something green', (0, 192, 0)), + } + dotfile = str(udir.join(FILENAME)) + page = MyPage(dotfile) + graphclient.display_page(page) + +def test_fixedfont(): + from dotviewer import graphpage, graphclient + class MyPage(graphpage.DotFileGraphPage): + fixedfont = True + dotfile = str(udir.join(FILENAME)) + page = MyPage(dotfile) + page.fixedfont = True + graphclient.display_page(page) diff --git a/dotviewer/test/test_translator.py b/dotviewer/test/test_translator.py --- a/dotviewer/test/test_translator.py +++ b/dotviewer/test/test_translator.py @@ -22,6 +22,6 @@ def test_annotated(): from rpython.translator.interactive import Translation - t = Translation(is_prime) - t.annotate([int]) + t = Translation(is_prime, [int]) + t.annotate() t.viewcg() diff --git a/dotviewer/test/test_unicode_util.py b/dotviewer/test/test_unicode_util.py new file mode 100755 --- /dev/null +++ b/dotviewer/test/test_unicode_util.py @@ -0,0 +1,57 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +import py +import codecs +from dotviewer.drawgraph import RAW_ENCODING, forcestr, forceunicode + +SOURCE1 = u"""digraph G{ +λ -> b +b -> μ +} +""" + +FILENAME = 'test.dot' + +class TestUnicodeUtil(object): + + def test_idempotent(self): + x = u"a" + assert forceunicode(forcestr(x)) == x + + x = u"λ" + assert forceunicode(forcestr(x)) == x + + assert forceunicode(forcestr(SOURCE1)) == SOURCE1 + + x = "a" + assert forcestr(forceunicode(x)) == x + + # utf-8 encoded. + # fragile, does not consider RAW_ENCODING + # x = "\xef\xbb\xbf\xce\xbb" + # assert forcestr(forceunicode(x)) == x + + def test_does_not_double_encode(self): + x = u"λ" + x_e = forcestr(x) + assert forcestr(x_e) == x_e + + x_u = forceunicode(x_e) + assert forceunicode(x_u) == x_u + + def test_file(self): + udir = py.path.local.make_numbered_dir(prefix='usession-dot-', keep=3) + full_filename = str(udir.join(FILENAME)) + f = codecs.open(full_filename, 'wb', RAW_ENCODING) + f.write(SOURCE1) + f.close() + + with open(full_filename) as f1: + assert forceunicode(f1.read()) == SOURCE1 + + f3 = codecs.open(full_filename, 'r', RAW_ENCODING) + c = f3.read() + f3.close() + result = (c == SOURCE1) + assert result diff --git a/lib-python/2.7/collections.py b/lib-python/2.7/collections.py --- a/lib-python/2.7/collections.py +++ b/lib-python/2.7/collections.py @@ -6,10 +6,12 @@ __all__ += _abcoll.__all__ from _collections import deque, defaultdict +from operator import itemgetter as _itemgetter, eq as _eq from keyword import iskeyword as _iskeyword import sys as _sys import heapq as _heapq from itertools import repeat as _repeat, chain as _chain, starmap as _starmap +from itertools import imap as _imap try: from thread import get_ident as _get_ident @@ -49,49 +51,45 @@ self.__map = {} self.__update(*args, **kwds) - def __setitem__(self, key, value, PREV=0, NEXT=1, dict_setitem=dict.__setitem__): + def __setitem__(self, key, value, dict_setitem=dict.__setitem__): 'od.__setitem__(i, y) <==> od[i]=y' # Setting a new item creates a new link at the end of the linked list, # and the inherited dictionary is updated with the new key/value pair. if key not in self: root = self.__root - last = root[PREV] - last[NEXT] = root[PREV] = self.__map[key] = [last, root, key] - dict_setitem(self, key, value) + last = root[0] + last[1] = root[0] = self.__map[key] = [last, root, key] + return dict_setitem(self, key, value) - def __delitem__(self, key, PREV=0, NEXT=1, dict_delitem=dict.__delitem__): + def __delitem__(self, key, dict_delitem=dict.__delitem__): 'od.__delitem__(y) <==> del od[y]' # Deleting an existing item uses self.__map to find the link which gets # removed by updating the links in the predecessor and successor nodes. dict_delitem(self, key) link_prev, link_next, key = self.__map.pop(key) - link_prev[NEXT] = link_next - link_next[PREV] = link_prev + link_prev[1] = link_next # update link_prev[NEXT] + link_next[0] = link_prev # update link_next[PREV] def __iter__(self): 'od.__iter__() <==> iter(od)' # Traverse the linked list in order. - NEXT, KEY = 1, 2 root = self.__root - curr = root[NEXT] + curr = root[1] # start at the first node while curr is not root: - yield curr[KEY] - curr = curr[NEXT] + yield curr[2] # yield the curr[KEY] + curr = curr[1] # move to next node def __reversed__(self): 'od.__reversed__() <==> reversed(od)' # Traverse the linked list in reverse order. - PREV, KEY = 0, 2 root = self.__root - curr = root[PREV] + curr = root[0] # start at the last node while curr is not root: - yield curr[KEY] - curr = curr[PREV] + yield curr[2] # yield the curr[KEY] + curr = curr[0] # move to previous node def clear(self): 'od.clear() -> None. Remove all items from od.' - for node in self.__map.itervalues(): - del node[:] root = self.__root root[:] = [root, root, None] self.__map.clear() @@ -207,7 +205,7 @@ ''' if isinstance(other, OrderedDict): - return len(self)==len(other) and self.items() == other.items() + return dict.__eq__(self, other) and all(_imap(_eq, self, other)) return dict.__eq__(self, other) def __ne__(self, other): @@ -297,7 +295,7 @@ _fields = %(field_names)r \n def __new__(_cls, %(argtxt)s): 'Create new instance of %(typename)s(%(argtxt)s)' - return tuple.__new__(_cls, (%(argtxt)s)) \n + return _tuple.__new__(_cls, (%(argtxt)s)) \n @classmethod def _make(cls, iterable, new=tuple.__new__, len=len): 'Make a new %(typename)s object from a sequence or iterable' @@ -322,14 +320,14 @@ 'Return self as a plain tuple. Used by copy and pickle.' return tuple(self) \n\n''' % locals() for i, name in enumerate(field_names): - template += " %s = property(lambda self: self[%d], doc='Alias for field number %d')\n" % (name, i, i) + template += " %s = _property(lambda self: self[%d], doc='Alias for field number %d')\n" % (name, i, i) if verbose: print template # Execute the template string in a temporary namespace and # support tracing utilities by setting a value for frame.f_globals['__name__'] - namespace = {'__name__': 'namedtuple_%s' % typename, - 'OrderedDict': OrderedDict} + namespace = dict(__name__='namedtuple_%s' % typename, + OrderedDict=OrderedDict, _property=property, _tuple=tuple) try: exec template in namespace except SyntaxError, e: diff --git a/lib-python/2.7/json/encoder.py b/lib-python/2.7/json/encoder.py --- a/lib-python/2.7/json/encoder.py +++ b/lib-python/2.7/json/encoder.py @@ -138,16 +138,16 @@ self.skipkeys = skipkeys self.ensure_ascii = ensure_ascii if ensure_ascii: - self.encoder = raw_encode_basestring_ascii + self.__encoder = raw_encode_basestring_ascii else: - self.encoder = raw_encode_basestring + self.__encoder = raw_encode_basestring if encoding != 'utf-8': - orig_encoder = self.encoder + orig_encoder = self.__encoder def encoder(o): if isinstance(o, str): o = o.decode(encoding) return orig_encoder(o) - self.encoder = encoder + self.__encoder = encoder self.check_circular = check_circular self.allow_nan = allow_nan self.sort_keys = sort_keys @@ -193,10 +193,10 @@ builder = StringBuilder() else: builder = UnicodeBuilder() - self._encode(o, markers, builder, 0) + self.__encode(o, markers, builder, 0) return builder.build() - def _emit_indent(self, builder, _current_indent_level): + def __emit_indent(self, builder, _current_indent_level): if self.indent is not None: _current_indent_level += 1 newline_indent = '\n' + (' ' * (self.indent * @@ -207,15 +207,15 @@ separator = self.item_separator return separator, _current_indent_level - def _emit_unindent(self, builder, _current_indent_level): + def __emit_unindent(self, builder, _current_indent_level): if self.indent is not None: builder.append('\n') builder.append(' ' * (self.indent * (_current_indent_level - 1))) - def _encode(self, o, markers, builder, _current_indent_level): + def __encode(self, o, markers, builder, _current_indent_level): if isinstance(o, basestring): builder.append('"') - builder.append(self.encoder(o)) + builder.append(self.__encoder(o)) builder.append('"') elif o is None: builder.append('null') @@ -226,46 +226,46 @@ elif isinstance(o, (int, long)): builder.append(str(o)) elif isinstance(o, float): - builder.append(self._floatstr(o)) + builder.append(self.__floatstr(o)) elif isinstance(o, (list, tuple)): if not o: builder.append('[]') return - self._encode_list(o, markers, builder, _current_indent_level) + self.__encode_list(o, markers, builder, _current_indent_level) elif isinstance(o, dict): if not o: builder.append('{}') return - self._encode_dict(o, markers, builder, _current_indent_level) + self.__encode_dict(o, markers, builder, _current_indent_level) else: - self._mark_markers(markers, o) + self.__mark_markers(markers, o) res = self.default(o) - self._encode(res, markers, builder, _current_indent_level) - self._remove_markers(markers, o) + self.__encode(res, markers, builder, _current_indent_level) + self.__remove_markers(markers, o) return res - def _encode_list(self, l, markers, builder, _current_indent_level): - self._mark_markers(markers, l) + def __encode_list(self, l, markers, builder, _current_indent_level): + self.__mark_markers(markers, l) builder.append('[') first = True - separator, _current_indent_level = self._emit_indent(builder, + separator, _current_indent_level = self.__emit_indent(builder, _current_indent_level) for elem in l: if first: first = False else: builder.append(separator) - self._encode(elem, markers, builder, _current_indent_level) + self.__encode(elem, markers, builder, _current_indent_level) del elem # XXX grumble - self._emit_unindent(builder, _current_indent_level) + self.__emit_unindent(builder, _current_indent_level) builder.append(']') - self._remove_markers(markers, l) + self.__remove_markers(markers, l) - def _encode_dict(self, d, markers, builder, _current_indent_level): - self._mark_markers(markers, d) + def __encode_dict(self, d, markers, builder, _current_indent_level): + self.__mark_markers(markers, d) first = True builder.append('{') - separator, _current_indent_level = self._emit_indent(builder, + separator, _current_indent_level = self.__emit_indent(builder, _current_indent_level) if self.sort_keys: items = sorted(d.items(), key=lambda kv: kv[0]) @@ -282,7 +282,7 @@ # JavaScript is weakly typed for these, so it makes sense to # also allow them. Many encoders seem to do something like this. elif isinstance(key, float): - key = self._floatstr(key) + key = self.__floatstr(key) elif key is True: key = 'true' elif key is False: @@ -296,15 +296,15 @@ else: raise TypeError("key " + repr(key) + " is not a string") builder.append('"') - builder.append(self.encoder(key)) + builder.append(self.__encoder(key)) builder.append('"') builder.append(self.key_separator) - self._encode(v, markers, builder, _current_indent_level) + self.__encode(v, markers, builder, _current_indent_level) del key del v # XXX grumble - self._emit_unindent(builder, _current_indent_level) + self.__emit_unindent(builder, _current_indent_level) builder.append('}') - self._remove_markers(markers, d) + self.__remove_markers(markers, d) def iterencode(self, o, _one_shot=False): """Encode the given object and yield each string @@ -320,9 +320,9 @@ markers = {} else: markers = None - return self._iterencode(o, markers, 0) + return self.__iterencode(o, markers, 0) - def _floatstr(self, o): + def __floatstr(self, o): # Check for specials. Note that this type of test is processor # and/or platform-specific, so do tests which don't depend on the # internals. @@ -343,21 +343,21 @@ return text - def _mark_markers(self, markers, o): + def __mark_markers(self, markers, o): if markers is not None: if id(o) in markers: raise ValueError("Circular reference detected") markers[id(o)] = None - def _remove_markers(self, markers, o): + def __remove_markers(self, markers, o): if markers is not None: del markers[id(o)] - def _iterencode_list(self, lst, markers, _current_indent_level): + def __iterencode_list(self, lst, markers, _current_indent_level): if not lst: yield '[]' return - self._mark_markers(markers, lst) + self.__mark_markers(markers, lst) buf = '[' if self.indent is not None: _current_indent_level += 1 @@ -375,7 +375,7 @@ else: buf = separator if isinstance(value, basestring): - yield buf + '"' + self.encoder(value) + '"' + yield buf + '"' + self.__encoder(value) + '"' elif value is None: yield buf + 'null' elif value is True: @@ -385,17 +385,17 @@ elif isinstance(value, (int, long)): yield buf + str(value) elif isinstance(value, float): - yield buf + self._floatstr(value) + yield buf + self.__floatstr(value) else: yield buf if isinstance(value, (list, tuple)): - chunks = self._iterencode_list(value, markers, + chunks = self.__iterencode_list(value, markers, _current_indent_level) elif isinstance(value, dict): - chunks = self._iterencode_dict(value, markers, + chunks = self.__iterencode_dict(value, markers, _current_indent_level) else: - chunks = self._iterencode(value, markers, + chunks = self.__iterencode(value, markers, _current_indent_level) for chunk in chunks: yield chunk @@ -403,13 +403,13 @@ _current_indent_level -= 1 yield '\n' + (' ' * (self.indent * _current_indent_level)) yield ']' - self._remove_markers(markers, lst) + self.__remove_markers(markers, lst) - def _iterencode_dict(self, dct, markers, _current_indent_level): + def __iterencode_dict(self, dct, markers, _current_indent_level): if not dct: yield '{}' return - self._mark_markers(markers, dct) + self.__mark_markers(markers, dct) yield '{' if self.indent is not None: _current_indent_level += 1 @@ -431,7 +431,7 @@ # JavaScript is weakly typed for these, so it makes sense to # also allow them. Many encoders seem to do something like this. elif isinstance(key, float): - key = self._floatstr(key) + key = self.__floatstr(key) elif key is True: key = 'true' elif key is False: @@ -448,10 +448,10 @@ first = False else: yield item_separator - yield '"' + self.encoder(key) + '"' + yield '"' + self.__encoder(key) + '"' yield self.key_separator if isinstance(value, basestring): - yield '"' + self.encoder(value) + '"' + yield '"' + self.__encoder(value) + '"' elif value is None: yield 'null' elif value is True: @@ -461,16 +461,16 @@ elif isinstance(value, (int, long)): yield str(value) elif isinstance(value, float): - yield self._floatstr(value) + yield self.__floatstr(value) else: if isinstance(value, (list, tuple)): - chunks = self._iterencode_list(value, markers, + chunks = self.__iterencode_list(value, markers, _current_indent_level) elif isinstance(value, dict): - chunks = self._iterencode_dict(value, markers, + chunks = self.__iterencode_dict(value, markers, _current_indent_level) else: - chunks = self._iterencode(value, markers, + chunks = self.__iterencode(value, markers, _current_indent_level) for chunk in chunks: yield chunk @@ -478,11 +478,11 @@ _current_indent_level -= 1 yield '\n' + (' ' * (self.indent * _current_indent_level)) yield '}' - self._remove_markers(markers, dct) + self.__remove_markers(markers, dct) - def _iterencode(self, o, markers, _current_indent_level): + def __iterencode(self, o, markers, _current_indent_level): if isinstance(o, basestring): - yield '"' + self.encoder(o) + '"' + yield '"' + self.__encoder(o) + '"' elif o is None: yield 'null' elif o is True: @@ -492,19 +492,19 @@ elif isinstance(o, (int, long)): yield str(o) elif isinstance(o, float): - yield self._floatstr(o) + yield self.__floatstr(o) elif isinstance(o, (list, tuple)): - for chunk in self._iterencode_list(o, markers, + for chunk in self.__iterencode_list(o, markers, _current_indent_level): yield chunk elif isinstance(o, dict): - for chunk in self._iterencode_dict(o, markers, + for chunk in self.__iterencode_dict(o, markers, _current_indent_level): yield chunk else: - self._mark_markers(markers, o) + self.__mark_markers(markers, o) obj = self.default(o) - for chunk in self._iterencode(obj, markers, + for chunk in self.__iterencode(obj, markers, _current_indent_level): yield chunk - self._remove_markers(markers, o) + self.__remove_markers(markers, o) diff --git a/lib-python/2.7/test/test_modulefinder.py b/lib-python/2.7/test/test_modulefinder.py --- a/lib-python/2.7/test/test_modulefinder.py +++ b/lib-python/2.7/test/test_modulefinder.py @@ -16,7 +16,7 @@ # library. TEST_DIR = tempfile.mkdtemp() -TEST_PATH = [TEST_DIR, os.path.dirname(__future__.__file__)] +TEST_PATH = [TEST_DIR, os.path.dirname(tempfile.__file__)] # Each test description is a list of 5 items: # diff --git a/lib-python/conftest.py b/lib-python/conftest.py --- a/lib-python/conftest.py +++ b/lib-python/conftest.py @@ -148,7 +148,7 @@ RegrTest('test_codecs.py', core=True, usemodules='_multibytecodec'), RegrTest('test_codeop.py', core=True), RegrTest('test_coding.py', core=True), - RegrTest('test_collections.py'), + RegrTest('test_collections.py', usemodules='binascii struct'), RegrTest('test_colorsys.py'), RegrTest('test_compare.py', core=True), RegrTest('test_compile.py', core=True), @@ -164,7 +164,7 @@ RegrTest('test_csv.py', usemodules='_csv'), RegrTest('test_ctypes.py', usemodules="_rawffi thread"), RegrTest('test_curses.py'), - RegrTest('test_datetime.py'), + RegrTest('test_datetime.py', usemodules='binascii struct'), RegrTest('test_dbm.py'), RegrTest('test_dbm_dumb.py'), RegrTest('test_dbm_gnu.py'), diff --git a/lib_pypy/_collections.py b/lib_pypy/_collections.py --- a/lib_pypy/_collections.py +++ b/lib_pypy/_collections.py @@ -142,18 +142,24 @@ return c def remove(self, value): - # Need to be defensive for mutating comparisons - for i in range(len(self)): - if self[i] == value: - del self[i] - return - raise ValueError("deque.remove(x): x not in deque") + # Need to defend mutating or failing comparisons + i = 0 + try: + for i in range(len(self)): + if self[0] == value: + self.popleft() + return + self.append(self.popleft()) + i += 1 + raise ValueError("deque.remove(x): x not in deque") + finally: + self.rotate(i) def rotate(self, n=1): length = len(self) - if length == 0: + if length <= 1: return - halflen = (length+1) >> 1 + halflen = length >> 1 if n > halflen or n < -halflen: n %= length if n > halflen: diff --git a/lib_pypy/_pickle.py b/lib_pypy/_pickle.py --- a/lib_pypy/_pickle.py +++ b/lib_pypy/_pickle.py @@ -1,5 +1,5 @@ # -# One-liner implementation of cPickle +# Reimplementation of cPickle, mostly as a copy of pickle.py # import marshal diff --git a/lib_pypy/conftest.py b/lib_pypy/conftest.py deleted file mode 100644 --- a/lib_pypy/conftest.py +++ /dev/null @@ -1,2 +0,0 @@ - -from pypy.conftest import * diff --git a/lib_pypy/ctypes_support.py b/lib_pypy/ctypes_support.py --- a/lib_pypy/ctypes_support.py +++ b/lib_pypy/ctypes_support.py @@ -19,16 +19,19 @@ if sys.platform == 'win32': standard_c_lib._errno.restype = ctypes.POINTER(ctypes.c_int) + standard_c_lib._errno.argtypes = None def _where_is_errno(): return standard_c_lib._errno() elif sys.platform in ('linux2', 'freebsd6'): standard_c_lib.__errno_location.restype = ctypes.POINTER(ctypes.c_int) + standard_c_lib.__errno_location.argtypes = None def _where_is_errno(): return standard_c_lib.__errno_location() elif sys.platform in ('darwin', 'freebsd7', 'freebsd8', 'freebsd9'): standard_c_lib.__error.restype = ctypes.POINTER(ctypes.c_int) + standard_c_lib.__error.argtypes = None def _where_is_errno(): return standard_c_lib.__error() diff --git a/lib_pypy/dbm.py b/lib_pypy/dbm.py --- a/lib_pypy/dbm.py +++ b/lib_pypy/dbm.py @@ -1,4 +1,4 @@ -from ctypes import Structure, c_char_p, c_int, c_void_p, CDLL +from ctypes import Structure, c_char_p, c_int, c_void_p, CDLL, POINTER, c_char import ctypes.util import os, sys @@ -11,7 +11,7 @@ class datum(Structure): _fields_ = [ - ('dptr', c_char_p), + ('dptr', POINTER(c_char)), ('dsize', c_int), ] @@ -126,8 +126,8 @@ libpath = ctypes.util.find_library('db') if not libpath: # XXX this is hopeless... - for c in '56789': - libpath = ctypes.util.find_library('db-4.%s' % c) + for c in ['5.3', '5.2', '5.1', '5.0', '4.9', '4.8', '4.7', '4.6', '4.5']: + libpath = ctypes.util.find_library('db-%s' % c) if libpath: break else: diff --git a/lib_pypy/greenlet.py b/lib_pypy/greenlet.py --- a/lib_pypy/greenlet.py +++ b/lib_pypy/greenlet.py @@ -1,5 +1,6 @@ import _continuation, sys +__version__ = "0.4.0" # ____________________________________________________________ # Exceptions @@ -57,7 +58,8 @@ def __switch(target, methodname, *args): current = getcurrent() # - while not target: + while not (target.__main or _continulet.is_pending(target)): + # inlined __nonzero__ ^^^ in case it's overridden if not target.__started: if methodname == 'switch': greenlet_func = _greenlet_start diff --git a/lib_pypy/numpypy/core/__init__.py b/lib_pypy/numpypy/core/__init__.py --- a/lib_pypy/numpypy/core/__init__.py +++ b/lib_pypy/numpypy/core/__init__.py @@ -1,2 +1,3 @@ from .fromnumeric import * from .numeric import * +from .shape_base import * diff --git a/lib_pypy/numpypy/core/numeric.py b/lib_pypy/numpypy/core/numeric.py --- a/lib_pypy/numpypy/core/numeric.py +++ b/lib_pypy/numpypy/core/numeric.py @@ -428,3 +428,76 @@ True_ = bool_(True) e = math.e pi = math.pi + +def outer(a,b): + """ + Compute the outer product of two vectors. + + Given two vectors, ``a = [a0, a1, ..., aM]`` and + ``b = [b0, b1, ..., bN]``, + the outer product [1]_ is:: + + [[a0*b0 a0*b1 ... a0*bN ] + [a1*b0 . + [ ... . + [aM*b0 aM*bN ]] + + Parameters + ---------- + a, b : array_like, shape (M,), (N,) + First and second input vectors. Inputs are flattened if they + are not already 1-dimensional. + + Returns + ------- + out : ndarray, shape (M, N) + ``out[i, j] = a[i] * b[j]`` + + See also + -------- + inner, einsum + + References + ---------- + .. [1] : G. H. Golub and C. F. van Loan, *Matrix Computations*, 3rd + ed., Baltimore, MD, Johns Hopkins University Press, 1996, + pg. 8. + + Examples + -------- + Make a (*very* coarse) grid for computing a Mandelbrot set: + + >>> rl = np.outer(np.ones((5,)), np.linspace(-2, 2, 5)) + >>> rl + array([[-2., -1., 0., 1., 2.], + [-2., -1., 0., 1., 2.], + [-2., -1., 0., 1., 2.], + [-2., -1., 0., 1., 2.], + [-2., -1., 0., 1., 2.]]) + >>> im = np.outer(1j*np.linspace(2, -2, 5), np.ones((5,))) + >>> im + array([[ 0.+2.j, 0.+2.j, 0.+2.j, 0.+2.j, 0.+2.j], + [ 0.+1.j, 0.+1.j, 0.+1.j, 0.+1.j, 0.+1.j], + [ 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j], + [ 0.-1.j, 0.-1.j, 0.-1.j, 0.-1.j, 0.-1.j], + [ 0.-2.j, 0.-2.j, 0.-2.j, 0.-2.j, 0.-2.j]]) + >>> grid = rl + im + >>> grid + array([[-2.+2.j, -1.+2.j, 0.+2.j, 1.+2.j, 2.+2.j], + [-2.+1.j, -1.+1.j, 0.+1.j, 1.+1.j, 2.+1.j], + [-2.+0.j, -1.+0.j, 0.+0.j, 1.+0.j, 2.+0.j], + [-2.-1.j, -1.-1.j, 0.-1.j, 1.-1.j, 2.-1.j], + [-2.-2.j, -1.-2.j, 0.-2.j, 1.-2.j, 2.-2.j]]) + + An example using a "vector" of letters: + + >>> x = np.array(['a', 'b', 'c'], dtype=object) + >>> np.outer(x, [1, 2, 3]) + array([[a, aa, aaa], + [b, bb, bbb], + [c, cc, ccc]], dtype=object) + + """ + a = asarray(a) + b = asarray(b) + return a.ravel()[:,newaxis]*b.ravel()[newaxis,:] diff --git a/lib_pypy/numpypy/core/shape_base.py b/lib_pypy/numpypy/core/shape_base.py new file mode 100644 --- /dev/null +++ b/lib_pypy/numpypy/core/shape_base.py @@ -0,0 +1,323 @@ +import _numpypy +from numeric import array, asanyarray, newaxis + +def atleast_1d(*arys): + """ + Convert inputs to arrays with at least one dimension. + + Scalar inputs are converted to 1-dimensional arrays, whilst + higher-dimensional inputs are preserved. + + Parameters + ---------- + arys1, arys2, ... : array_like + One or more input arrays. + + Returns + ------- + ret : ndarray + An array, or sequence of arrays, each with ``a.ndim >= 1``. + Copies are made only if necessary. + + See Also + -------- + atleast_2d, atleast_3d + + Examples + -------- + >>> np.atleast_1d(1.0) + array([ 1.]) + + >>> x = np.arange(9.0).reshape(3,3) + >>> np.atleast_1d(x) + array([[ 0., 1., 2.], + [ 3., 4., 5.], + [ 6., 7., 8.]]) + >>> np.atleast_1d(x) is x + True + + >>> np.atleast_1d(1, [3, 4]) + [array([1]), array([3, 4])] + + """ + res = [] + for ary in arys: + ary = asanyarray(ary) + if len(ary.shape) == 0 : + result = ary.reshape(1) + else : + result = ary + res.append(result) + if len(res) == 1: + return res[0] + else: + return res + + +def atleast_2d(*arys): + """ + View inputs as arrays with at least two dimensions. + + Parameters + ---------- + arys1, arys2, ... : array_like + One or more array-like sequences. Non-array inputs are converted + to arrays. Arrays that already have two or more dimensions are + preserved. + + Returns + ------- + res, res2, ... : ndarray + An array, or tuple of arrays, each with ``a.ndim >= 2``. + Copies are avoided where possible, and views with two or more + dimensions are returned. + + See Also + -------- + atleast_1d, atleast_3d + + Examples + -------- + >>> np.atleast_2d(3.0) + array([[ 3.]]) + + >>> x = np.arange(3.0) + >>> np.atleast_2d(x) + array([[ 0., 1., 2.]]) + >>> np.atleast_2d(x).base is x + True + + >>> np.atleast_2d(1, [1, 2], [[1, 2]]) + [array([[1]]), array([[1, 2]]), array([[1, 2]])] + + """ + res = [] + for ary in arys: + ary = asanyarray(ary) + if len(ary.shape) == 0 : + result = ary.reshape(1, 1) + elif len(ary.shape) == 1 : + result = ary[newaxis, :] + else : + result = ary + res.append(result) + if len(res) == 1: + return res[0] + else: + return res + +def atleast_3d(*arys): + """ + View inputs as arrays with at least three dimensions. + + Parameters + ---------- + arys1, arys2, ... : array_like + One or more array-like sequences. Non-array inputs are converted to + arrays. Arrays that already have three or more dimensions are + preserved. + + Returns + ------- + res1, res2, ... : ndarray + An array, or tuple of arrays, each with ``a.ndim >= 3``. Copies are + avoided where possible, and views with three or more dimensions are + returned. For example, a 1-D array of shape ``(N,)`` becomes a view + of shape ``(1, N, 1)``, and a 2-D array of shape ``(M, N)`` becomes a + view of shape ``(M, N, 1)``. + + See Also + -------- + atleast_1d, atleast_2d + + Examples + -------- + >>> np.atleast_3d(3.0) + array([[[ 3.]]]) + + >>> x = np.arange(3.0) + >>> np.atleast_3d(x).shape + (1, 3, 1) + + >>> x = np.arange(12.0).reshape(4,3) + >>> np.atleast_3d(x).shape + (4, 3, 1) + >>> np.atleast_3d(x).base is x + True + + >>> for arr in np.atleast_3d([1, 2], [[1, 2]], [[[1, 2]]]): + ... print arr, arr.shape + ... + [[[1] + [2]]] (1, 2, 1) + [[[1] + [2]]] (1, 2, 1) + [[[1 2]]] (1, 1, 2) + + """ + res = [] + for ary in arys: + ary = asanyarray(ary) + if len(ary.shape) == 0: + result = ary.reshape(1,1,1) + elif len(ary.shape) == 1: + result = ary[newaxis,:,newaxis] + elif len(ary.shape) == 2: + result = ary[:,:,newaxis] + else: + result = ary + res.append(result) + if len(res) == 1: + return res[0] + else: + return res + +def vstack(tup): + """ + Stack arrays in sequence vertically (row wise). + + Take a sequence of arrays and stack them vertically to make a single + array. Rebuild arrays divided by `vsplit`. + + Parameters + ---------- + tup : sequence of ndarrays + Tuple containing arrays to be stacked. The arrays must have the same + shape along all but the first axis. + + Returns + ------- + stacked : ndarray + The array formed by stacking the given arrays. + + See Also + -------- + hstack : Stack arrays in sequence horizontally (column wise). + dstack : Stack arrays in sequence depth wise (along third dimension). + concatenate : Join a sequence of arrays together. + vsplit : Split array into a list of multiple sub-arrays vertically. + + Notes + ----- + Equivalent to ``np.concatenate(tup, axis=0)`` if `tup` contains arrays that + are at least 2-dimensional. + + Examples + -------- + >>> a = np.array([1, 2, 3]) + >>> b = np.array([2, 3, 4]) + >>> np.vstack((a,b)) + array([[1, 2, 3], + [2, 3, 4]]) + + >>> a = np.array([[1], [2], [3]]) + >>> b = np.array([[2], [3], [4]]) + >>> np.vstack((a,b)) + array([[1], + [2], + [3], + [2], + [3], + [4]]) + + """ + return _numpypy.concatenate(map(atleast_2d,tup),0) + +def hstack(tup): + """ + Stack arrays in sequence horizontally (column wise). + + Take a sequence of arrays and stack them horizontally to make + a single array. Rebuild arrays divided by `hsplit`. + + Parameters + ---------- + tup : sequence of ndarrays + All arrays must have the same shape along all but the second axis. + + Returns + ------- + stacked : ndarray + The array formed by stacking the given arrays. + + See Also + -------- + vstack : Stack arrays in sequence vertically (row wise). + dstack : Stack arrays in sequence depth wise (along third axis). + concatenate : Join a sequence of arrays together. + hsplit : Split array along second axis. + + Notes + ----- + Equivalent to ``np.concatenate(tup, axis=1)`` + + Examples + -------- + >>> a = np.array((1,2,3)) + >>> b = np.array((2,3,4)) + >>> np.hstack((a,b)) + array([1, 2, 3, 2, 3, 4]) + >>> a = np.array([[1],[2],[3]]) + >>> b = np.array([[2],[3],[4]]) + >>> np.hstack((a,b)) + array([[1, 2], + [2, 3], + [3, 4]]) + + """ + arrs = map(atleast_1d,tup) + # As a special case, dimension 0 of 1-dimensional arrays is "horizontal" + if arrs[0].ndim == 1: + return _numpypy.concatenate(arrs, 0) + else: + return _numpypy.concatenate(arrs, 1) + +def dstack(tup): + """ + Stack arrays in sequence depth wise (along third axis). + + Takes a sequence of arrays and stack them along the third axis + to make a single array. Rebuilds arrays divided by `dsplit`. + This is a simple way to stack 2D arrays (images) into a single + 3D array for processing. + + Parameters + ---------- + tup : sequence of arrays + Arrays to stack. All of them must have the same shape along all + but the third axis. + + Returns + ------- + stacked : ndarray + The array formed by stacking the given arrays. + + See Also + -------- + vstack : Stack along first axis. + hstack : Stack along second axis. + concatenate : Join arrays. + dsplit : Split array along third axis. + + Notes + ----- + Equivalent to ``np.concatenate(tup, axis=2)``. + + Examples + -------- + >>> a = np.array((1,2,3)) + >>> b = np.array((2,3,4)) + >>> np.dstack((a,b)) + array([[[1, 2], + [2, 3], + [3, 4]]]) + + >>> a = np.array([[1],[2],[3]]) + >>> b = np.array([[2],[3],[4]]) + >>> np.dstack((a,b)) + array([[[1, 2]], + [[2, 3]], + [[3, 4]]]) + + """ + return _numpypy.concatenate(map(atleast_3d,tup),2) diff --git a/lib_pypy/pypy_test/__init__.py b/lib_pypy/pypy_test/__init__.py deleted file mode 100644 --- a/lib_pypy/pypy_test/__init__.py +++ /dev/null @@ -1,1 +0,0 @@ -# diff --git a/lib_pypy/pypy_test/hack___pypy__.py b/lib_pypy/pypy_test/hack___pypy__.py deleted file mode 100644 --- a/lib_pypy/pypy_test/hack___pypy__.py +++ /dev/null @@ -1,9 +0,0 @@ -# here only to make test runs work even if not running on top of PyPy -import sys, new - -def builtinify(f): - return f - -pypy = new.module('__pypy__') -pypy.builtinify = builtinify -sys.modules.setdefault('__pypy__', pypy) diff --git a/lib_pypy/pypy_test/inprogress_test_binascii_extra.py b/lib_pypy/pypy_test/inprogress_test_binascii_extra.py deleted file mode 100644 --- a/lib_pypy/pypy_test/inprogress_test_binascii_extra.py +++ /dev/null @@ -1,18 +0,0 @@ -from lib_pypy import binascii - -def test_uu(): - assert binascii.b2a_uu('1234567') == "',3(S-#4V-P \n" - assert binascii.b2a_uu('123456789012345678901234567890123456789012345') == 'M,3(S-#4V-S at Y,#$R,S0U-C Author: Philip Jenvey Branch: py3k Changeset: r61103:0f6032e23564 Date: 2013-02-11 13:42 -0800 http://bitbucket.org/pypy/pypy/changeset/0f6032e23564/ Log: fix the funny merge from default of Parse and a related test diff --git a/pypy/module/pyexpat/interp_pyexpat.py b/pypy/module/pyexpat/interp_pyexpat.py --- a/pypy/module/pyexpat/interp_pyexpat.py +++ b/pypy/module/pyexpat/interp_pyexpat.py @@ -616,15 +616,10 @@ # Parse methods - @unwrap_spec(isfinal=bool) - def Parse(self, space, w_data, isfinal=False): + @unwrap_spec(data='bufferstr_or_u', isfinal=bool) + def Parse(self, space, data, isfinal=False): """Parse(data[, isfinal]) Parse XML data. `isfinal' should be true at end of input.""" - - if space.isinstance_w(w_data, space.w_bytes): - data = space.bytes_w(w_data) - else: - data = space.str_w(w_data) res = XML_Parse(self.itself, data, len(data), isfinal) if self._exc_info: e = self._exc_info diff --git a/pypy/module/pyexpat/test/test_parser.py b/pypy/module/pyexpat/test/test_parser.py --- a/pypy/module/pyexpat/test/test_parser.py +++ b/pypy/module/pyexpat/test/test_parser.py @@ -162,12 +162,12 @@ assert e.value.code == errors.codes[errors.XML_ERROR_UNCLOSED_TOKEN] def test_read_chunks(self): + import io import pyexpat - import StringIO from contextlib import closing - xml = '' + (' ' * 4096) + '' - with closing(StringIO.StringIO(xml)) as sio: + xml = b'' + (b' ' * 4096) + b'' + with closing(io.BytesIO(xml)) as sio: class FakeReader(): def __init__(self): self.read_count = 0 From noreply at buildbot.pypy.org Mon Feb 11 22:45:20 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Mon, 11 Feb 2013 22:45:20 +0100 (CET) Subject: [pypy-commit] pypy py3k: default stderr to backslashreplace Message-ID: <20130211214520.62C441C004F@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61104:b745bd223983 Date: 2013-02-11 13:43 -0800 http://bitbucket.org/pypy/pypy/changeset/b745bd223983/ Log: default stderr to backslashreplace diff --git a/pypy/interpreter/app_main.py b/pypy/interpreter/app_main.py --- a/pypy/interpreter/app_main.py +++ b/pypy/interpreter/app_main.py @@ -251,7 +251,7 @@ sys.stdout = sys.__stdout__ = create_stdio( 1, True, "", encoding, errors, unbuffered) sys.stderr = sys.__stderr__ = create_stdio( - 2, True, "", encoding, errors, unbuffered) + 2, True, "", encoding, 'backslashreplace', unbuffered) def create_stdio(fd, writing, name, encoding, errors, unbuffered): diff --git a/pypy/interpreter/test2/test_app_main.py b/pypy/interpreter/test2/test_app_main.py --- a/pypy/interpreter/test2/test_app_main.py +++ b/pypy/interpreter/test2/test_app_main.py @@ -880,6 +880,19 @@ assert status == 1 assert data.startswith("15\xe2\x82\xac") + def test_stderr_backslashreplace(self): + if sys.version_info < (2, 7): + skip("test required Python >= 2.7") + p = getscript_in_dir(""" + import sys + sys.exit('15\u20ac {}'.format((sys.stdout.errors, sys.stderr.errors))) + """) + env = os.environ.copy() + env["PYTHONIOENCODING"] = 'ascii' + data, status = self.run_with_status_code(p, env=env) + assert status == 1 + assert data.startswith("15\\u20ac ('strict', 'backslashreplace')") + class TestAppMain: def test_print_info(self): diff --git a/pypy/module/sys/__init__.py b/pypy/module/sys/__init__.py --- a/pypy/module/sys/__init__.py +++ b/pypy/module/sys/__init__.py @@ -121,6 +121,7 @@ closefd=False) sys.stdout.buffer.raw.name = "" sys.stderr = sys.__stderr__ = io.open(2, "w", encoding="ascii", + errors="backslashreplace", closefd=False) sys.stderr.buffer.raw.name = "" """) diff --git a/pypy/module/sys/test/test_sysmodule.py b/pypy/module/sys/test/test_sysmodule.py --- a/pypy/module/sys/test/test_sysmodule.py +++ b/pypy/module/sys/test/test_sysmodule.py @@ -96,6 +96,7 @@ assert isinstance(sys.__stdout__, io.IOBase) assert isinstance(sys.__stderr__, io.IOBase) assert isinstance(sys.__stdin__, io.IOBase) + assert sys.__stderr__.errors == 'backslashreplace' if self.appdirect and not isinstance(sys.stdin, io.IOBase): return @@ -103,6 +104,7 @@ assert isinstance(sys.stdout, io.IOBase) assert isinstance(sys.stderr, io.IOBase) assert isinstance(sys.stdin, io.IOBase) + assert sys.stderr.errors == 'backslashreplace' def test_getfilesystemencoding(self): import sys From noreply at buildbot.pypy.org Mon Feb 11 22:45:21 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Mon, 11 Feb 2013 22:45:21 +0100 (CET) Subject: [pypy-commit] pypy py3k: we don't expect the bytecode to be written to __pycache__ Message-ID: <20130211214521.A1DCC1C004F@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61105:8bdb31689146 Date: 2013-02-11 13:44 -0800 http://bitbucket.org/pypy/pypy/changeset/8bdb31689146/ Log: we don't expect the bytecode to be written to __pycache__ diff --git a/pypy/module/zipimport/test/test_undocumented.py b/pypy/module/zipimport/test/test_undocumented.py --- a/pypy/module/zipimport/test/test_undocumented.py +++ b/pypy/module/zipimport/test/test_undocumented.py @@ -52,7 +52,8 @@ if source: zip_file.write(code_path) if bytecode: - py_compile.compile(code_path, doraise=True) + py_compile.compile(code_path, code_path + bytecode_suffix, + doraise=True) zip_file.write(code_path + bytecode_suffix) zip_file.close() return os.path.abspath(zip_path) From noreply at buildbot.pypy.org Mon Feb 11 23:44:37 2013 From: noreply at buildbot.pypy.org (mattip) Date: Mon, 11 Feb 2013 23:44:37 +0100 (CET) Subject: [pypy-commit] pypy default: test, fix scalar string types Message-ID: <20130211224437.D8F801C004F@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: Changeset: r61106:21844583c8a0 Date: 2013-02-12 00:28 +0200 http://bitbucket.org/pypy/pypy/changeset/21844583c8a0/ Log: test, fix scalar string types diff --git a/pypy/module/micronumpy/interp_dtype.py b/pypy/module/micronumpy/interp_dtype.py --- a/pypy/module/micronumpy/interp_dtype.py +++ b/pypy/module/micronumpy/interp_dtype.py @@ -224,7 +224,7 @@ size = int(name[1:]) except ValueError: raise OperationError(space.w_TypeError, space.wrap("data type not understood")) - if char == 'S': + if char == 'S' or char == 'c': itemtype = types.StringType(size) basename = 'string' num = 18 @@ -264,8 +264,10 @@ return cache.dtypes_by_name[name] except KeyError: pass - if name[0] in 'VSU' or name[0] in '<>=' and name[1] in 'VSU': + if name[0] in 'VSUc' or name[0] in '<>=' and name[1] in 'VSUc': return variable_dtype(space, name) + raise OperationError(space.w_TypeError, space.wrap( + "data type %s not understood" % name)) elif space.isinstance_w(w_dtype, space.w_list): return dtype_from_list(space, w_dtype) elif space.isinstance_w(w_dtype, space.w_dict): diff --git a/pypy/module/micronumpy/interp_numarray.py b/pypy/module/micronumpy/interp_numarray.py --- a/pypy/module/micronumpy/interp_numarray.py +++ b/pypy/module/micronumpy/interp_numarray.py @@ -891,8 +891,9 @@ @unwrap_spec(ndmin=int, copy=bool, subok=bool) def array(space, w_object, w_dtype=None, copy=True, w_order=None, subok=False, ndmin=0): - if not issequence_w(space, w_object): - if space.is_none(w_dtype): + isstr = space.isinstance_w(w_object, space.w_str) + if not issequence_w(space, w_object) or isstr: + if space.is_none(w_dtype) or isstr: w_dtype = interp_ufuncs.find_dtype_for_scalar(space, w_object) dtype = space.interp_w(interp_dtype.W_Dtype, space.call_function(space.gettypefor(interp_dtype.W_Dtype), w_dtype)) diff --git a/pypy/module/micronumpy/interp_ufuncs.py b/pypy/module/micronumpy/interp_ufuncs.py --- a/pypy/module/micronumpy/interp_ufuncs.py +++ b/pypy/module/micronumpy/interp_ufuncs.py @@ -324,10 +324,12 @@ w_out = None w_lhs = convert_to_array(space, w_lhs) w_rhs = convert_to_array(space, w_rhs) - if w_lhs.get_dtype().is_flexible_type() or \ - w_rhs.get_dtype().is_flexible_type(): - raise OperationError(space.w_TypeError, - space.wrap('unsupported operand types')) + if (w_lhs.get_dtype().is_flexible_type() or \ + w_rhs.get_dtype().is_flexible_type()): + raise OperationError(space.w_TypeError, space.wrap( + 'unsupported operand dtypes %s and %s for "%s"' % \ + (w_rhs.get_dtype().get_name(), w_lhs.get_dtype().get_name(), + self.name))) calc_dtype = find_binop_result_dtype(space, w_lhs.get_dtype(), w_rhs.get_dtype(), int_only=self.int_only, diff --git a/pypy/module/micronumpy/test/test_numarray.py b/pypy/module/micronumpy/test/test_numarray.py --- a/pypy/module/micronumpy/test/test_numarray.py +++ b/pypy/module/micronumpy/test/test_numarray.py @@ -2561,6 +2561,12 @@ from _numpypy import array a = array('ffff') assert a.shape == () + a = array('x', dtype='>S') + assert str(a.dtype) == '|S1' + a = array('x', dtype='c') + assert str(a.dtype) == '|S1' + # XXX can sort flexible types, why not comparison? + #assert a == 'x' def test_flexible_repr(self): # numpypy overrides _numpypy repr with pure python one From noreply at buildbot.pypy.org Tue Feb 12 00:50:58 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Tue, 12 Feb 2013 00:50:58 +0100 (CET) Subject: [pypy-commit] pypy py3k: adapt to py3 Message-ID: <20130211235058.D3A6D1C004F@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61107:ed9576076627 Date: 2013-02-11 15:50 -0800 http://bitbucket.org/pypy/pypy/changeset/ed9576076627/ Log: adapt to py3 diff --git a/pypy/module/posix/test/test_posix2.py b/pypy/module/posix/test/test_posix2.py --- a/pypy/module/posix/test/test_posix2.py +++ b/pypy/module/posix/test/test_posix2.py @@ -489,16 +489,6 @@ res = fp.read() assert res == '1\n' - def test_popen_child_fds(self): - import os - with open(os.path.join(self.pdir, 'file1'), 'r') as fd: - with self.posix.popen('%s -c "import os; print os.read(%d, 10)" 2>&1' % (self.python, fd.fileno())) as stream: - res = stream.read() - if os.name == 'nt': - assert '\nOSError: [Errno 9]' in res - else: - assert res == 'test1\n' - if hasattr(__import__(os.name), '_getfullpathname'): def test__getfullpathname(self): # nt specific diff --git a/pypy/module/test_lib_pypy/test_cPickle.py b/pypy/module/test_lib_pypy/test__pickle.py rename from pypy/module/test_lib_pypy/test_cPickle.py rename to pypy/module/test_lib_pypy/test__pickle.py --- a/pypy/module/test_lib_pypy/test_cPickle.py +++ b/pypy/module/test_lib_pypy/test__pickle.py @@ -1,7 +1,6 @@ -from __future__ import absolute_import -import py -from lib_pypy import cPickle +class AppTestPickle: -def test_stack_underflow(): - py.test.raises(cPickle.UnpicklingError, cPickle.loads, "a string") + def test_stack_underflow(self): + import _pickle + raises(TypeError, _pickle.loads, "a string") diff --git a/pypy/module/thread/test/test_fork.py b/pypy/module/thread/test/test_fork.py --- a/pypy/module/thread/test/test_fork.py +++ b/pypy/module/thread/test/test_fork.py @@ -60,7 +60,7 @@ def test_forked_is_main_thread(self): "Checks that a forked interpreter is the main thread" - import os, thread, signal + import os, _thread, signal if not hasattr(os, 'fork'): skip("No fork on this platform") @@ -68,7 +68,7 @@ def threadfunction(): pid = os.fork() if pid == 0: - print 'in child' + print('in child') # signal() only works from the 'main' thread signal.signal(signal.SIGUSR1, signal.SIG_IGN) os._exit(42) @@ -78,7 +78,7 @@ feedback.append(exitcode) feedback = [] - thread.start_new_thread(threadfunction, ()) + _thread.start_new_thread(threadfunction, ()) self.waitfor(lambda: feedback) # if 0, an (unraisable) exception was raised from the forked thread. # if 9, process was killed by timer. From noreply at buildbot.pypy.org Tue Feb 12 01:11:21 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Tue, 12 Feb 2013 01:11:21 +0100 (CET) Subject: [pypy-commit] pypy default: some more asserts to point out numpypy dtype creation order issues on 32bit Message-ID: <20130212001121.69C821C0041@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61108:707ce69bcd6d Date: 2013-02-11 19:10 -0500 http://bitbucket.org/pypy/pypy/changeset/707ce69bcd6d/ Log: some more asserts to point out numpypy dtype creation order issues on 32bit diff --git a/pypy/module/micronumpy/test/test_dtypes.py b/pypy/module/micronumpy/test/test_dtypes.py --- a/pypy/module/micronumpy/test/test_dtypes.py +++ b/pypy/module/micronumpy/test/test_dtypes.py @@ -46,9 +46,17 @@ if self.ptr_size == 4: assert dtype('intp').num == 5 assert dtype('uintp').num == 6 + assert dtype('int32').num == 7 + assert dtype('uint32').num == 8 + assert dtype('int64').num == 9 + assert dtype('uint64').num == 10 else: assert dtype('intp').num == 7 assert dtype('uintp').num == 8 + assert dtype('int32').num == 5 + assert dtype('uint32').num == 6 + assert dtype('int64').num == 7 + assert dtype('uint64').num == 8 assert dtype(int).num == 7 assert dtype(long).num == 9 assert dtype(float).num == 12 @@ -260,6 +268,7 @@ class AppTestTypes(BaseAppTestDtypes): def test_abstract_types(self): import _numpypy as numpy + raises(TypeError, numpy.generic, 0) raises(TypeError, numpy.number, 0) raises(TypeError, numpy.integer, 0) @@ -277,6 +286,12 @@ a_i = numpy.array([4,4], numpy.integer) a_s = numpy.array([4,4], numpy.signedinteger) a_u = numpy.array([4,4], numpy.unsignedinteger) + + assert a_n.dtype.num == 12 + assert a_i.dtype.num == 7 + assert a_s.dtype.num == 7 + assert a_u.dtype.num == 8 + assert a_n.dtype is numpy.dtype('float64') if self.ptr_size == 4: assert a_i.dtype is numpy.dtype('int32') @@ -286,6 +301,7 @@ assert a_i.dtype is numpy.dtype('int64') assert a_s.dtype is numpy.dtype('int64') assert a_u.dtype is numpy.dtype('uint64') + # too ambitious for now #a = numpy.array('xxxx', numpy.generic) #assert a.dtype is numpy.dtype('|V4') From noreply at buildbot.pypy.org Tue Feb 12 01:27:16 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Tue, 12 Feb 2013 01:27:16 +0100 (CET) Subject: [pypy-commit] pypy default: have numpypy long dtype override both int32/int64 dtypes Message-ID: <20130212002716.26A131C004F@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61109:513c09948372 Date: 2013-02-11 19:26 -0500 http://bitbucket.org/pypy/pypy/changeset/513c09948372/ Log: have numpypy long dtype override both int32/int64 dtypes diff --git a/pypy/module/micronumpy/interp_dtype.py b/pypy/module/micronumpy/interp_dtype.py --- a/pypy/module/micronumpy/interp_dtype.py +++ b/pypy/module/micronumpy/interp_dtype.py @@ -589,7 +589,7 @@ name='intp', char=INTPLTR, w_box_type = space.gettypefor(intp_box), - ) + ) self.w_uintpdtype = W_Dtype( uintp_type, num=uintp_num, @@ -597,17 +597,19 @@ name='uintp', char=UINTPLTR, w_box_type = space.gettypefor(uintp_box), - ) + ) self.builtin_dtypes = [ - self.w_booldtype, self.w_int8dtype, self.w_uint8dtype, - self.w_int16dtype, self.w_uint16dtype, self.w_int32dtype, - self.w_uint32dtype, self.w_longdtype, self.w_ulongdtype, + self.w_booldtype, + self.w_int8dtype, self.w_uint8dtype, + self.w_int16dtype, self.w_uint16dtype, + self.w_longdtype, self.w_ulongdtype, + self.w_int32dtype, self.w_uint32dtype, self.w_int64dtype, self.w_uint64dtype, - self.w_float16dtype, self.w_float32dtype, self.w_float64dtype, - self.w_longdouble, + self.w_float32dtype, self.w_float64dtype, self.w_longdouble, self.w_complex64dtype, self.w_complex128dtype, self.w_clongdouble, - self.w_stringdtype, self.w_unicodedtype, - self.w_voiddtype, self.w_intpdtype, self.w_uintpdtype, + self.w_stringdtype, self.w_unicodedtype, self.w_voiddtype, + self.w_intpdtype, self.w_uintpdtype, + self.w_float16dtype, ] self.float_dtypes_by_num_bytes = sorted( (dtype.itemtype.get_element_size(), dtype) From noreply at buildbot.pypy.org Tue Feb 12 01:49:52 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Tue, 12 Feb 2013 01:49:52 +0100 (CET) Subject: [pypy-commit] pypy default: some cleanups and a test for numpypy longdouble aliases Message-ID: <20130212004952.E52251C004F@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61110:eea9453b9339 Date: 2013-02-11 19:49 -0500 http://bitbucket.org/pypy/pypy/changeset/eea9453b9339/ Log: some cleanups and a test for numpypy longdouble aliases diff --git a/pypy/module/micronumpy/interp_dtype.py b/pypy/module/micronumpy/interp_dtype.py --- a/pypy/module/micronumpy/interp_dtype.py +++ b/pypy/module/micronumpy/interp_dtype.py @@ -482,10 +482,8 @@ name="float96", char="g", w_box_type=space.gettypefor(interp_boxes.W_Float96Box), - aliases=["longfloat", "longdouble"], + aliases=["longdouble", "longfloat"], ) - self.w_longdouble = self.w_float96dtype - self.w_complex192dtype = W_ComplexDtype( types.Complex192(), num=16, @@ -497,8 +495,8 @@ aliases=["clongdouble", "clongfloat"], float_type = self.w_float96dtype, ) + self.w_longdouble = self.w_float96dtype self.w_clongdouble = self.w_complex192dtype - elif interp_boxes.long_double_size == 16: self.w_float128dtype = W_Dtype( types.Float128(), @@ -507,10 +505,8 @@ name="float128", char="g", w_box_type=space.gettypefor(interp_boxes.W_Float128Box), - aliases=["longfloat", "longdouble"], + aliases=["longdouble", "longfloat"], ) - self.w_longdouble = self.w_float128dtype - self.w_complex256dtype = W_ComplexDtype( types.Complex256(), num=16, @@ -522,11 +518,13 @@ aliases=["clongdouble", "clongfloat"], float_type = self.w_float128dtype, ) + self.w_longdouble = self.w_float128dtype self.w_clongdouble = self.w_complex256dtype else: - self.w_float64dtype.aliases += ["longfloat", "longdouble"] + self.w_float64dtype.aliases += ["longdouble", "longfloat"] + self.w_complex128dtype.aliases += ["clongdouble", "clongfloat"] self.w_longdouble = self.w_float64dtype - self.w_clongdouble = self.w_complex64dtype + self.w_clongdouble = self.w_complex128dtype self.w_stringdtype = W_Dtype( types.StringType(1), num=18, @@ -605,11 +603,11 @@ self.w_longdtype, self.w_ulongdtype, self.w_int32dtype, self.w_uint32dtype, self.w_int64dtype, self.w_uint64dtype, + self.w_float16dtype, self.w_float32dtype, self.w_float64dtype, self.w_longdouble, self.w_complex64dtype, self.w_complex128dtype, self.w_clongdouble, self.w_stringdtype, self.w_unicodedtype, self.w_voiddtype, self.w_intpdtype, self.w_uintpdtype, - self.w_float16dtype, ] self.float_dtypes_by_num_bytes = sorted( (dtype.itemtype.get_element_size(), dtype) diff --git a/pypy/module/micronumpy/test/test_dtypes.py b/pypy/module/micronumpy/test/test_dtypes.py --- a/pypy/module/micronumpy/test/test_dtypes.py +++ b/pypy/module/micronumpy/test/test_dtypes.py @@ -39,6 +39,13 @@ raises(TypeError, lambda: dtype("int8") == 3) assert dtype(bool) == bool + def test_dtype_aliases(self): + from _numpypy import dtype + assert dtype('longfloat').num in (12, 13) + assert dtype('longdouble').num in (12, 13) + assert dtype('clongfloat').num in (15, 16) + assert dtype('clongdouble').num in (15, 16) + def test_dtype_with_types(self): from _numpypy import dtype From noreply at buildbot.pypy.org Tue Feb 12 01:50:16 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Tue, 12 Feb 2013 01:50:16 +0100 (CET) Subject: [pypy-commit] pypy py3k: rearrange for py3 Message-ID: <20130212005016.BBD121C004F@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61111:2b7b47ad712d Date: 2013-02-11 16:14 -0800 http://bitbucket.org/pypy/pypy/changeset/2b7b47ad712d/ Log: rearrange for py3 diff --git a/pypy/interpreter/test2/test_app_main.py b/pypy/interpreter/test2/test_app_main.py --- a/pypy/interpreter/test2/test_app_main.py +++ b/pypy/interpreter/test2/test_app_main.py @@ -98,8 +98,7 @@ class TestParseCommandLine: - def check_options(self, options, sys_argv, **expected): - assert sys.argv == sys_argv + def check_options(self, options, **expected): for key, value in expected.items(): assert options[key] == value for key, value in options.items(): @@ -122,7 +121,7 @@ app_options = eval(p.stdout.readline()) sys_argv = eval(p.stdout.readline()) app_options['sys_argv'] = sys_argv - self.check_options(app_options, sys_argv, expected) + self.check_options(app_options, **expected) def test_all_combinations_I_can_think_of(self): self.check([], {}, sys_argv=[''], run_stdin=True) From noreply at buildbot.pypy.org Tue Feb 12 03:08:27 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Tue, 12 Feb 2013 03:08:27 +0100 (CET) Subject: [pypy-commit] pypy default: small additions/tightenings for numpypy tests Message-ID: <20130212020827.351581C004F@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61112:23bd5566c5f2 Date: 2013-02-11 20:13 -0500 http://bitbucket.org/pypy/pypy/changeset/23bd5566c5f2/ Log: small additions/tightenings for numpypy tests diff --git a/pypy/module/micronumpy/test/test_dtypes.py b/pypy/module/micronumpy/test/test_dtypes.py --- a/pypy/module/micronumpy/test/test_dtypes.py +++ b/pypy/module/micronumpy/test/test_dtypes.py @@ -22,12 +22,16 @@ d = dtype('?') assert d.num == 0 assert d.kind == 'b' + assert dtype(d) is d + assert dtype('bool') is d + assert dtype('int8').num == 1 - assert dtype(d) is d - assert dtype(None) is dtype(float) assert dtype('int8').name == 'int8' assert dtype(int).fields is None assert dtype(int).names is None + + assert dtype(None) is dtype(float) + raises(TypeError, dtype, 1042) raises(KeyError, 'dtype(int)["asdasd"]') @@ -178,7 +182,7 @@ for d1, d2, dout in tests: # make a failed test print helpful info d3 = (array([1], d1) + array([1], d2)).dtype - assert (d1, d2, repr(d3)) == (d1, d2, repr(dtype(dout))) + assert (d1, d2) == (d1, d2) and d3 is dtype(dout) def test_add_int8(self): from _numpypy import array, dtype @@ -534,7 +538,7 @@ numpy.inexact, numpy.number, numpy.generic, object] a = numpy.array([1, 2, 3], numpy.longdouble) - assert repr(type(a[1])) == repr(numpy.longdouble) + assert type(a[1]) is numpy.longdouble assert numpy.float64(12) == numpy.longdouble(12) assert numpy.float64(12) == numpy.longfloat(12) raises(ValueError, numpy.longfloat, '23.2df') @@ -574,7 +578,7 @@ assert repr(c128) == should c64 = numpy.complex64(complex(real, imag)) - assert repr(c64.real) == 'inf' + assert repr(c64.real) == 'inf' assert type(c64.real) is type(c64.imag) is numpy.float32 assert repr(c64.imag).startswith('inf') assert repr(c64) in ('(inf+inf*j)', '(inf+infj)') From noreply at buildbot.pypy.org Tue Feb 12 03:26:57 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Tue, 12 Feb 2013 03:26:57 +0100 (CET) Subject: [pypy-commit] pypy py3k: this can happen on certain environments unfortunately Message-ID: <20130212022657.ECBEC1C03D5@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61113:54d5f5238df9 Date: 2013-02-11 18:26 -0800 http://bitbucket.org/pypy/pypy/changeset/54d5f5238df9/ Log: this can happen on certain environments unfortunately diff --git a/pypy/module/imp/test/test_import.py b/pypy/module/imp/test/test_import.py --- a/pypy/module/imp/test/test_import.py +++ b/pypy/module/imp/test/test_import.py @@ -1094,12 +1094,6 @@ (mydir): import sys sys.path.append(mydir) - - # Obscure: manually bootstrap the utf-8 codec for - # TextIOs opened by imp.find_module. It's not otherwise - # loaded by the test infrastructure but would have been - # in any other situation - import encodings.utf_8 """) def teardown_class(cls): From noreply at buildbot.pypy.org Tue Feb 12 04:27:35 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Tue, 12 Feb 2013 04:27:35 +0100 (CET) Subject: [pypy-commit] pypy default: fix numpypy binop promotion Message-ID: <20130212032735.8D8361C0041@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61114:11d464cbfa08 Date: 2013-02-11 22:27 -0500 http://bitbucket.org/pypy/pypy/changeset/11d464cbfa08/ Log: fix numpypy binop promotion diff --git a/pypy/module/micronumpy/interp_dtype.py b/pypy/module/micronumpy/interp_dtype.py --- a/pypy/module/micronumpy/interp_dtype.py +++ b/pypy/module/micronumpy/interp_dtype.py @@ -614,10 +614,12 @@ for dtype in [self.w_float16dtype, self.w_float32dtype, self.w_float64dtype, self.w_longdouble] ) + self.dtypes_by_num = {} self.dtypes_by_name = {} # we reverse, so the stuff with lower numbers override stuff with # higher numbers for dtype in reversed(self.builtin_dtypes): + self.dtypes_by_num[dtype.num] = dtype self.dtypes_by_name[dtype.name] = dtype can_name = dtype.kind + str(dtype.itemtype.get_element_size()) self.dtypes_by_name[can_name] = dtype @@ -708,9 +710,7 @@ w_minobj = space.wrap(0) items_w = items_w + [w_maxobj, w_minobj] items_w = items_w + [dtype.w_box_type] - - w_tuple = space.newtuple(items_w) - space.setitem(w_typeinfo, space.wrap(k), w_tuple) + space.setitem(w_typeinfo, space.wrap(k), space.newtuple(items_w)) self.w_typeinfo = w_typeinfo def get_dtype_cache(space): diff --git a/pypy/module/micronumpy/interp_ufuncs.py b/pypy/module/micronumpy/interp_ufuncs.py --- a/pypy/module/micronumpy/interp_ufuncs.py +++ b/pypy/module/micronumpy/interp_ufuncs.py @@ -405,7 +405,6 @@ else: raise OperationError(space.w_TypeError, space.wrap("Unsupported types")) - if promote_to_float: return find_unaryop_result_dtype(space, dt2, promote_to_float=True) # If they're the same kind, choose the greater one. @@ -426,13 +425,13 @@ return dt2 # we need to promote both dtypes dtypenum = dt2.num + 2 + elif dt2.num == 10 or (LONG_BIT == 64 and dt2.num == 8): + # UInt64 + signed = Float64 + dtypenum = 12 else: - # increase to the next signed type (or to float) + # increase to the next signed type dtypenum = dt2.num + 1 - # UInt64 + signed = Float64 - if dt2.num == 10: - dtypenum += 2 - newdtype = interp_dtype.get_dtype_cache(space).builtin_dtypes[dtypenum] + newdtype = interp_dtype.get_dtype_cache(space).dtypes_by_num[dtypenum] if (newdtype.itemtype.get_element_size() > dt2.itemtype.get_element_size() or newdtype.kind == interp_dtype.FLOATINGLTR): @@ -440,11 +439,8 @@ else: # we only promoted to long on 32-bit or to longlong on 64-bit # this is really for dealing with the Long and Ulong dtypes - if LONG_BIT == 32: - dtypenum += 2 - else: - dtypenum += 4 - return interp_dtype.get_dtype_cache(space).builtin_dtypes[dtypenum] + dtypenum += 2 + return interp_dtype.get_dtype_cache(space).dtypes_by_num[dtypenum] @jit.unroll_safe From noreply at buildbot.pypy.org Tue Feb 12 06:01:35 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Tue, 12 Feb 2013 06:01:35 +0100 (CET) Subject: [pypy-commit] pypy default: enhance tests for numpypy string record/array to demonstrate existing bugs Message-ID: <20130212050135.DA9821C004F@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61115:c6a40e53bb2d Date: 2013-02-11 23:46 -0500 http://bitbucket.org/pypy/pypy/changeset/c6a40e53bb2d/ Log: enhance tests for numpypy string record/array to demonstrate existing bugs diff --git a/pypy/module/micronumpy/interp_boxes.py b/pypy/module/micronumpy/interp_boxes.py --- a/pypy/module/micronumpy/interp_boxes.py +++ b/pypy/module/micronumpy/interp_boxes.py @@ -287,11 +287,11 @@ for i in range(len(arg)): arr.storage[i] = arg[i] return W_StringBox(arr, 0, arr.dtype) - + def convert_to(self, dtype): from pypy.module.micronumpy import types assert isinstance(dtype.itemtype, types.StringType) - return self + return self class W_UnicodeBox(W_CharacterBox): def descr__new__unicode_box(space, w_subtype, w_arg): @@ -308,7 +308,7 @@ def convert_to(self, dtype): from pypy.module.micronumpy import types assert isinstance(dtype.itemtype, types.UnicodeType) - return self + return self class W_ComplexFloatingBox(W_InexactBox): diff --git a/pypy/module/micronumpy/interp_dtype.py b/pypy/module/micronumpy/interp_dtype.py --- a/pypy/module/micronumpy/interp_dtype.py +++ b/pypy/module/micronumpy/interp_dtype.py @@ -449,7 +449,7 @@ name="float64", char="d", w_box_type = space.gettypefor(interp_boxes.W_Float64Box), - alternate_constructors=[space.w_float, + alternate_constructors=[space.w_float, space.gettypefor(interp_boxes.W_NumberBox), ], aliases=["float"], diff --git a/pypy/module/micronumpy/test/test_numarray.py b/pypy/module/micronumpy/test/test_numarray.py --- a/pypy/module/micronumpy/test/test_numarray.py +++ b/pypy/module/micronumpy/test/test_numarray.py @@ -2533,23 +2533,44 @@ def test_string_record(self): from _numpypy import dtype, array + d = dtype([('x', str), ('y', 'int32')]) - assert d.fields['x'] == (dtype(str), 0) - assert d.fields['y'] == (dtype('int32'), 1) + assert str(d.fields['x'][0]) == '|S0' + assert d.fields['x'][1] == 0 + assert str(d.fields['y'][0]) == 'int32' + assert d.fields['y'][1] == 0 + assert d.name == 'void32' + + a = array([('a', 2), ('cde', 1)], dtype=d) + assert a[0]['x'] == '\x02' + assert a[0]['y'] == 2 + assert a[1]['x'] == '\x01' + assert a[1]['y'] == 1 + d = dtype([('x', 'S1'), ('y', 'int32')]) - assert d.fields['x'] == (dtype(str), 0) - assert d.fields['y'] == (dtype('int32'), 1) - a = array([('a', 2), ('c', 1)], dtype=d) + assert str(d.fields['x'][0]) == '|S1' + assert d.fields['x'][1] == 0 + assert str(d.fields['y'][0]) == 'int32' + assert d.fields['y'][1] == 1 + assert d.name == 'void40' + + a = array([('a', 2), ('cde', 1)], dtype=d) + assert a[0]['x'] == 'a' + assert a[0]['y'] == 2 + assert a[1]['x'] == 'c' assert a[1]['y'] == 1 - assert a[0]['x'] == 'a' - def test_stringarray(self): + def test_string_array(self): from _numpypy import array - a = array(['abc'],'S3') - assert str(a.dtype) == '|S3' a = array(['abc']) assert str(a.dtype) == '|S3' - a = array(['abc','defg','ab']) + a = array(['abc'], 'S') + assert str(a.dtype) == '|S3' + a = array(['abc'], 'S3') + assert str(a.dtype) == '|S3' + a = array(['abcde'], 'S3') + assert str(a.dtype) == '|S3' + a = array(['abc', 'defg', 'ab']) assert str(a.dtype) == '|S4' assert a[0] == 'abc' assert a[1] == 'defg' @@ -2561,6 +2582,8 @@ from _numpypy import array a = array('ffff') assert a.shape == () + a = array([], dtype='S') + assert str(a.dtype) == '|S1' a = array('x', dtype='>S') assert str(a.dtype) == '|S1' a = array('x', dtype='c') @@ -2581,14 +2604,14 @@ s = repr(a) assert s.replace('\n', '') == \ "array(['abc', 'defg', 'ab'], dtype='|S4')" - - + + class AppTestPyPy(BaseNumpyAppTest): def setup_class(cls): if option.runappdirect and '__pypy__' not in sys.builtin_module_names: py.test.skip("pypy only test") BaseNumpyAppTest.setup_class.im_func(cls) - + def test_init_2(self): # this test is pypy only since in numpy it becomes an object dtype import _numpypy diff --git a/pypy/module/micronumpy/types.py b/pypy/module/micronumpy/types.py --- a/pypy/module/micronumpy/types.py +++ b/pypy/module/micronumpy/types.py @@ -1019,17 +1019,17 @@ def str_format(self, box): real, imag = self.for_computation(self.unbox(box)) imag_str = str_format(imag) + 'j' - + # (0+2j) => 2j if real == 0: - return imag_str + return imag_str real_str = str_format(real) op = '+' if imag >= 0 else '' return ''.join(['(', real_str, op, imag_str, ')']) @staticmethod - def for_computation(v): + def for_computation(v): return float(v[0]), float(v[1]) @raw_unary_op @@ -1101,7 +1101,7 @@ @complex_binary_op def mul(self, v1, v2): return rcomplex.c_mul(v1, v2) - + @complex_binary_op def div(self, v1, v2): try: From noreply at buildbot.pypy.org Tue Feb 12 07:06:52 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Tue, 12 Feb 2013 07:06:52 +0100 (CET) Subject: [pypy-commit] pypy default: attempt to presize tehse lists Message-ID: <20130212060652.375271C0471@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r61116:ee04c61f776b Date: 2013-02-11 22:05 -0800 http://bitbucket.org/pypy/pypy/changeset/ee04c61f776b/ Log: attempt to presize tehse lists diff --git a/rpython/rlib/rstring.py b/rpython/rlib/rstring.py --- a/rpython/rlib/rstring.py +++ b/rpython/rlib/rstring.py @@ -3,9 +3,10 @@ from rpython.annotator.model import (SomeObject, SomeString, s_None, SomeChar, SomeInteger, SomeUnicodeCodePoint, SomeUnicodeString, SomePtr, SomePBC) +from rpython.rlib.objectmodel import newlist_hint from rpython.rlib.rarithmetic import ovfcheck -from rpython.tool.pairtype import pair, pairtype from rpython.rtyper.extregistry import ExtRegistryEntry +from rpython.tool.pairtype import pairtype # -------------- public API for string functions ----------------------- @@ -14,7 +15,10 @@ if bylen == 0: raise ValueError("empty separator") - res = [] + if maxsplit > 0: + res = newlist_hint(maxsplit) + else: + res = [] start = 0 while maxsplit != 0: next = value.find(by, start) @@ -27,8 +31,12 @@ res.append(value[start:len(value)]) return res + def rsplit(value, by, maxsplit=-1): - res = [] + if maxsplit > 0: + res = newlist_hint(maxsplit) + else: + res = [] end = len(value) bylen = len(by) if bylen == 0: @@ -38,7 +46,7 @@ next = value.rfind(by, 0, end) if next < 0: break - res.append(value[next+bylen:end]) + res.append(value[next + bylen:end]) end = next maxsplit -= 1 # NB. if it's already < 0, it stays < 0 @@ -50,6 +58,7 @@ INIT_SIZE = 100 # XXX tweak + class AbstractStringBuilder(object): def __init__(self, init_size=INIT_SIZE): self.l = [] @@ -91,9 +100,11 @@ def getlength(self): return len(self.build()) + class StringBuilder(AbstractStringBuilder): tp = str + class UnicodeBuilder(AbstractStringBuilder): tp = unicode @@ -260,4 +271,3 @@ def specialize_call(self, hop): hop.exception_cannot_occur() - From noreply at buildbot.pypy.org Tue Feb 12 07:06:54 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Tue, 12 Feb 2013 07:06:54 +0100 (CET) Subject: [pypy-commit] pypy default: merged upstream Message-ID: <20130212060654.A5BF41C0471@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r61117:0b85ac6f60b7 Date: 2013-02-11 22:06 -0800 http://bitbucket.org/pypy/pypy/changeset/0b85ac6f60b7/ Log: merged upstream diff too long, truncating to 2000 out of 3326 lines diff --git a/LICENSE b/LICENSE --- a/LICENSE +++ b/LICENSE @@ -270,3 +270,24 @@ LineBreak-*.txt UnicodeData-*.txt UnihanNumeric-*.txt + +License for 'dotviewer/font/' +============================= + +Copyright (C) 2008 The Android Open Source Project + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +Detailled license information is contained in the NOTICE file in the +directory. + diff --git a/dotviewer/VeraMoBd.ttf b/dotviewer/VeraMoBd.ttf deleted file mode 100644 Binary file dotviewer/VeraMoBd.ttf has changed diff --git a/dotviewer/cyrvetic.ttf b/dotviewer/cyrvetic.ttf deleted file mode 100644 Binary file dotviewer/cyrvetic.ttf has changed diff --git a/dotviewer/drawgraph.py b/dotviewer/drawgraph.py --- a/dotviewer/drawgraph.py +++ b/dotviewer/drawgraph.py @@ -9,9 +9,10 @@ from pygame.locals import * +RAW_ENCODING = "utf-8" this_dir = os.path.dirname(os.path.abspath(__file__)) -FONT = os.path.join(this_dir, 'cyrvetic.ttf') -FIXEDFONT = os.path.join(this_dir, 'VeraMoBd.ttf') +FONT = os.path.join(this_dir, 'font', 'DroidSans.ttf') +FIXEDFONT = os.path.join(this_dir, 'font', 'DroidSansMono.ttf') COLOR = { 'black': (0,0,0), 'white': (255,255,255), @@ -51,6 +52,12 @@ else: return default +def forceunicode(name): + return name if isinstance(name, unicode) else name.decode(RAW_ENCODING) + +def forcestr(name): + return name if isinstance(name, str) else name.encode(RAW_ENCODING) + class GraphLayout: fixedfont = False @@ -106,12 +113,12 @@ class Node: def __init__(self, name, x, y, w, h, label, style, shape, color, fillcolor): - self.name = name + self.name = forceunicode(name) self.x = float(x) self.y = float(y) self.w = float(w) self.h = float(h) - self.label = label + self.label = forceunicode(label) self.style = style self.shape = shape self.color = color @@ -125,8 +132,8 @@ label = None def __init__(self, nodes, tail, head, cnt, *rest): - self.tail = nodes[tail] - self.head = nodes[head] + self.tail = nodes[forceunicode(tail)] + self.head = nodes[forceunicode(head)] cnt = int(cnt) self.points = [(float(rest[i]), float(rest[i+1])) for i in range(0, cnt*2, 2)] @@ -655,11 +662,7 @@ part = parts[i] word = part[0] try: - try: - img = font.render(word, False, *part[1:]) - except pygame.error, e: - # Try *with* anti-aliasing to work around a bug in SDL - img = font.render(word, True, *part[1:]) + img = font.render(word, True, *part[1:]) except pygame.error: del parts[i] # Text has zero width else: diff --git a/dotviewer/font/DroidSans-Bold.ttf b/dotviewer/font/DroidSans-Bold.ttf new file mode 100644 index 0000000000000000000000000000000000000000..d065b64eb1863f83c2c982264f9442f2313a44a9 GIT binary patch [cut] diff --git a/dotviewer/font/DroidSans.ttf b/dotviewer/font/DroidSans.ttf new file mode 100644 index 0000000000000000000000000000000000000000..ad1efca88aed8d9e2d179f27dd713e2a1562fe5f GIT binary patch [cut] diff --git a/dotviewer/font/DroidSansMono.ttf b/dotviewer/font/DroidSansMono.ttf new file mode 100644 index 0000000000000000000000000000000000000000..a007071944f7c90020e798eea53b10065e2b45a5 GIT binary patch [cut] diff --git a/dotviewer/font/NOTICE b/dotviewer/font/NOTICE new file mode 100644 --- /dev/null +++ b/dotviewer/font/NOTICE @@ -0,0 +1,190 @@ + + Copyright (c) 2005-2008, The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + diff --git a/dotviewer/font/README.txt b/dotviewer/font/README.txt new file mode 100644 --- /dev/null +++ b/dotviewer/font/README.txt @@ -0,0 +1,18 @@ +Copyright (C) 2008 The Android Open Source Project + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +########## + +This directory contains the fonts for the platform. They are licensed +under the Apache 2 license. diff --git a/dotviewer/graphclient.py b/dotviewer/graphclient.py --- a/dotviewer/graphclient.py +++ b/dotviewer/graphclient.py @@ -33,8 +33,9 @@ def reload(graph_id): page = getpage(graph_id) if save_tmp_file: + from drawgraph import forcestr f = open(save_tmp_file, 'w') - f.write(page.source) + f.write(forcestr(page.source)) f.close() messages.extend(page_messages(page, graph_id)) send_graph_messages(io, messages) @@ -75,7 +76,8 @@ def page_messages(page, graph_id): import graphparse - return graphparse.parse_dot(graph_id, page.source, page.links, + from drawgraph import forcestr + return graphparse.parse_dot(graph_id, forcestr(page.source), page.links, getattr(page, 'fixedfont', False)) def send_graph_messages(io, messages): diff --git a/dotviewer/graphdisplay.py b/dotviewer/graphdisplay.py --- a/dotviewer/graphdisplay.py +++ b/dotviewer/graphdisplay.py @@ -4,7 +4,7 @@ from pygame.locals import * from drawgraph import GraphRenderer, FIXEDFONT from drawgraph import Node, Edge -from drawgraph import EventQueue, wait_for_events +from drawgraph import EventQueue, wait_for_events, forceunicode, forcestr METAKEYS = dict([ @@ -285,7 +285,7 @@ if e.key == K_ESCAPE: return None elif e.key == K_RETURN: - return text.encode('latin-1') # XXX do better + return forcestr(text) # return encoded unicode elif e.key == K_BACKSPACE: text = text[:-1] elif e.unicode and ord(e.unicode) >= ord(' '): @@ -423,7 +423,7 @@ self.layout.request_reload() def setstatusbar(self, text, fgcolor=None, bgcolor=None): - info = (text, fgcolor or self.STATUSBAR_FGCOLOR, bgcolor or self.STATUSBAR_BGCOLOR) + info = (forceunicode(text), fgcolor or self.STATUSBAR_FGCOLOR, bgcolor or self.STATUSBAR_BGCOLOR) if info != self.statusbarinfo: self.statusbarinfo = info self.must_redraw = True @@ -711,7 +711,7 @@ lines = [] while words: line = words.pop(0) - img = font.render(line or ' ', 1, fgcolor) + img = font.render(line or ' ', True, fgcolor) while words: longerline = line + ' ' + words[0] longerimg = font.render(longerline, 1, fgcolor) @@ -723,7 +723,7 @@ img = longerimg w, h = img.get_size() if h > maxheight: - img = font.render('...', 1, overflowcolor) + img = font.render('...', True, overflowcolor) w, h = img.get_size() while lines and h > maxheight: maxheight += lines.pop().get_size()[1] diff --git a/dotviewer/graphpage.py b/dotviewer/graphpage.py --- a/dotviewer/graphpage.py +++ b/dotviewer/graphpage.py @@ -44,6 +44,8 @@ class DotFileGraphPage(GraphPage): def compute(self, dotfile): - f = open(dotfile, 'r') + import codecs + from drawgraph import RAW_ENCODING + f = codecs.open(dotfile, 'r', RAW_ENCODING) self.source = f.read() f.close() diff --git a/dotviewer/test/test_interactive_unicode.py b/dotviewer/test/test_interactive_unicode.py new file mode 100755 --- /dev/null +++ b/dotviewer/test/test_interactive_unicode.py @@ -0,0 +1,103 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +import py +import sys, os, signal, thread, time, codecs +from dotviewer.conftest import option +from dotviewer.drawgraph import RAW_ENCODING + +SOURCE1 = u"""digraph G{ +λ -> b +b -> μ +} +""" + +FILENAME = 'graph1.dot' + +def setup_module(mod): + if not option.pygame: + py.test.skip("--pygame not enabled") + udir = py.path.local.make_numbered_dir(prefix='usession-dot-', keep=3) + f = codecs.open(str(udir.join(FILENAME)), 'wb', RAW_ENCODING) + f.write(SOURCE1) + f.close() + + from dotviewer import graphclient + mod.pkgdir = py.path.local(graphclient.this_dir) + mod.udir = udir + + try: + del os.environ['GRAPHSERVER'] + except KeyError: + pass + + +def test_dotviewer(): + print "=== dotviewer.py %s" % FILENAME + err = os.system('"%s" "%s"' % (pkgdir.join('dotviewer.py'), + udir.join(FILENAME))) + assert err == 0 + + plain_name = FILENAME.replace('.dot','.plain') + + os.system('dot -Tplain "%s" > "%s"' % (udir.join(FILENAME), + udir.join(plain_name))) + print "=== dotviewer.py %s" % plain_name + err = os.system('"%s" "%s"' % (pkgdir.join('dotviewer.py'), + udir.join(plain_name))) + assert err == 0 + +def test_display_dot_file(): + from dotviewer.graphclient import display_dot_file + print "=== display_dot_file(%s) with GRAPHSERVER=%s" % ( + FILENAME, os.environ.get('GRAPHSERVER', ''),) + display_dot_file(udir.join(FILENAME)) + print "=== display_dot_file finished" + + +def test_graphserver(): + import socket + s = socket.socket() + s.listen(1) + host, port = s.getsockname() # pick a random free port + s.close() + + if hasattr(sys, 'pypy_objspaceclass'): + python = 'python' + else: + python = sys.executable + + cmdargs = [python, str(pkgdir.join('graphserver.py')), + str(port)] + print '* starting:', ' '.join(cmdargs) + pid = os.spawnv(os.P_NOWAIT, cmdargs[0], cmdargs) + try: + time.sleep(1) # hack - wait a bit to make sure the server is up + os.environ['GRAPHSERVER'] = '%s:%d' % (host, port) + try: + test_display_dot_file() + finally: + del os.environ['GRAPHSERVER'] + finally: + os.kill(pid, signal.SIGTERM) + +def test_colors(): + from dotviewer import graphpage, graphclient + class MyPage(graphpage.DotFileGraphPage): + def compute(self, dotfile): + super(MyPage, self).compute(dotfile) + self.links = {'v2721': 'Hello world', + 'v2720': ('Something green', (0, 192, 0)), + } + dotfile = str(udir.join(FILENAME)) + page = MyPage(dotfile) + graphclient.display_page(page) + +def test_fixedfont(): + from dotviewer import graphpage, graphclient + class MyPage(graphpage.DotFileGraphPage): + fixedfont = True + dotfile = str(udir.join(FILENAME)) + page = MyPage(dotfile) + page.fixedfont = True + graphclient.display_page(page) diff --git a/dotviewer/test/test_translator.py b/dotviewer/test/test_translator.py --- a/dotviewer/test/test_translator.py +++ b/dotviewer/test/test_translator.py @@ -22,6 +22,6 @@ def test_annotated(): from rpython.translator.interactive import Translation - t = Translation(is_prime) - t.annotate([int]) + t = Translation(is_prime, [int]) + t.annotate() t.viewcg() diff --git a/dotviewer/test/test_unicode_util.py b/dotviewer/test/test_unicode_util.py new file mode 100755 --- /dev/null +++ b/dotviewer/test/test_unicode_util.py @@ -0,0 +1,57 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +import py +import codecs +from dotviewer.drawgraph import RAW_ENCODING, forcestr, forceunicode + +SOURCE1 = u"""digraph G{ +λ -> b +b -> μ +} +""" + +FILENAME = 'test.dot' + +class TestUnicodeUtil(object): + + def test_idempotent(self): + x = u"a" + assert forceunicode(forcestr(x)) == x + + x = u"λ" + assert forceunicode(forcestr(x)) == x + + assert forceunicode(forcestr(SOURCE1)) == SOURCE1 + + x = "a" + assert forcestr(forceunicode(x)) == x + + # utf-8 encoded. + # fragile, does not consider RAW_ENCODING + # x = "\xef\xbb\xbf\xce\xbb" + # assert forcestr(forceunicode(x)) == x + + def test_does_not_double_encode(self): + x = u"λ" + x_e = forcestr(x) + assert forcestr(x_e) == x_e + + x_u = forceunicode(x_e) + assert forceunicode(x_u) == x_u + + def test_file(self): + udir = py.path.local.make_numbered_dir(prefix='usession-dot-', keep=3) + full_filename = str(udir.join(FILENAME)) + f = codecs.open(full_filename, 'wb', RAW_ENCODING) + f.write(SOURCE1) + f.close() + + with open(full_filename) as f1: + assert forceunicode(f1.read()) == SOURCE1 + + f3 = codecs.open(full_filename, 'r', RAW_ENCODING) + c = f3.read() + f3.close() + result = (c == SOURCE1) + assert result diff --git a/lib_pypy/conftest.py b/lib_pypy/conftest.py deleted file mode 100644 --- a/lib_pypy/conftest.py +++ /dev/null @@ -1,2 +0,0 @@ - -from pypy.conftest import * diff --git a/lib_pypy/dbm.py b/lib_pypy/dbm.py --- a/lib_pypy/dbm.py +++ b/lib_pypy/dbm.py @@ -1,4 +1,4 @@ -from ctypes import Structure, c_char_p, c_int, c_void_p, CDLL +from ctypes import Structure, c_char_p, c_int, c_void_p, CDLL, POINTER, c_char import ctypes.util import os, sys @@ -11,7 +11,7 @@ class datum(Structure): _fields_ = [ - ('dptr', c_char_p), + ('dptr', POINTER(c_char)), ('dsize', c_int), ] @@ -126,8 +126,8 @@ libpath = ctypes.util.find_library('db') if not libpath: # XXX this is hopeless... - for c in '56789': - libpath = ctypes.util.find_library('db-4.%s' % c) + for c in ['5.3', '5.2', '5.1', '5.0', '4.9', '4.8', '4.7', '4.6', '4.5']: + libpath = ctypes.util.find_library('db-%s' % c) if libpath: break else: diff --git a/lib_pypy/numpypy/core/__init__.py b/lib_pypy/numpypy/core/__init__.py --- a/lib_pypy/numpypy/core/__init__.py +++ b/lib_pypy/numpypy/core/__init__.py @@ -1,2 +1,3 @@ from .fromnumeric import * from .numeric import * +from .shape_base import * diff --git a/lib_pypy/numpypy/core/numeric.py b/lib_pypy/numpypy/core/numeric.py --- a/lib_pypy/numpypy/core/numeric.py +++ b/lib_pypy/numpypy/core/numeric.py @@ -428,3 +428,76 @@ True_ = bool_(True) e = math.e pi = math.pi + +def outer(a,b): + """ + Compute the outer product of two vectors. + + Given two vectors, ``a = [a0, a1, ..., aM]`` and + ``b = [b0, b1, ..., bN]``, + the outer product [1]_ is:: + + [[a0*b0 a0*b1 ... a0*bN ] + [a1*b0 . + [ ... . + [aM*b0 aM*bN ]] + + Parameters + ---------- + a, b : array_like, shape (M,), (N,) + First and second input vectors. Inputs are flattened if they + are not already 1-dimensional. + + Returns + ------- + out : ndarray, shape (M, N) + ``out[i, j] = a[i] * b[j]`` + + See also + -------- + inner, einsum + + References + ---------- + .. [1] : G. H. Golub and C. F. van Loan, *Matrix Computations*, 3rd + ed., Baltimore, MD, Johns Hopkins University Press, 1996, + pg. 8. + + Examples + -------- + Make a (*very* coarse) grid for computing a Mandelbrot set: + + >>> rl = np.outer(np.ones((5,)), np.linspace(-2, 2, 5)) + >>> rl + array([[-2., -1., 0., 1., 2.], + [-2., -1., 0., 1., 2.], + [-2., -1., 0., 1., 2.], + [-2., -1., 0., 1., 2.], + [-2., -1., 0., 1., 2.]]) + >>> im = np.outer(1j*np.linspace(2, -2, 5), np.ones((5,))) + >>> im + array([[ 0.+2.j, 0.+2.j, 0.+2.j, 0.+2.j, 0.+2.j], + [ 0.+1.j, 0.+1.j, 0.+1.j, 0.+1.j, 0.+1.j], + [ 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j], + [ 0.-1.j, 0.-1.j, 0.-1.j, 0.-1.j, 0.-1.j], + [ 0.-2.j, 0.-2.j, 0.-2.j, 0.-2.j, 0.-2.j]]) + >>> grid = rl + im + >>> grid + array([[-2.+2.j, -1.+2.j, 0.+2.j, 1.+2.j, 2.+2.j], + [-2.+1.j, -1.+1.j, 0.+1.j, 1.+1.j, 2.+1.j], + [-2.+0.j, -1.+0.j, 0.+0.j, 1.+0.j, 2.+0.j], + [-2.-1.j, -1.-1.j, 0.-1.j, 1.-1.j, 2.-1.j], + [-2.-2.j, -1.-2.j, 0.-2.j, 1.-2.j, 2.-2.j]]) + + An example using a "vector" of letters: + + >>> x = np.array(['a', 'b', 'c'], dtype=object) + >>> np.outer(x, [1, 2, 3]) + array([[a, aa, aaa], + [b, bb, bbb], + [c, cc, ccc]], dtype=object) + + """ + a = asarray(a) + b = asarray(b) + return a.ravel()[:,newaxis]*b.ravel()[newaxis,:] diff --git a/lib_pypy/numpypy/core/shape_base.py b/lib_pypy/numpypy/core/shape_base.py new file mode 100644 --- /dev/null +++ b/lib_pypy/numpypy/core/shape_base.py @@ -0,0 +1,323 @@ +import _numpypy +from numeric import array, asanyarray, newaxis + +def atleast_1d(*arys): + """ + Convert inputs to arrays with at least one dimension. + + Scalar inputs are converted to 1-dimensional arrays, whilst + higher-dimensional inputs are preserved. + + Parameters + ---------- + arys1, arys2, ... : array_like + One or more input arrays. + + Returns + ------- + ret : ndarray + An array, or sequence of arrays, each with ``a.ndim >= 1``. + Copies are made only if necessary. + + See Also + -------- + atleast_2d, atleast_3d + + Examples + -------- + >>> np.atleast_1d(1.0) + array([ 1.]) + + >>> x = np.arange(9.0).reshape(3,3) + >>> np.atleast_1d(x) + array([[ 0., 1., 2.], + [ 3., 4., 5.], + [ 6., 7., 8.]]) + >>> np.atleast_1d(x) is x + True + + >>> np.atleast_1d(1, [3, 4]) + [array([1]), array([3, 4])] + + """ + res = [] + for ary in arys: + ary = asanyarray(ary) + if len(ary.shape) == 0 : + result = ary.reshape(1) + else : + result = ary + res.append(result) + if len(res) == 1: + return res[0] + else: + return res + + +def atleast_2d(*arys): + """ + View inputs as arrays with at least two dimensions. + + Parameters + ---------- + arys1, arys2, ... : array_like + One or more array-like sequences. Non-array inputs are converted + to arrays. Arrays that already have two or more dimensions are + preserved. + + Returns + ------- + res, res2, ... : ndarray + An array, or tuple of arrays, each with ``a.ndim >= 2``. + Copies are avoided where possible, and views with two or more + dimensions are returned. + + See Also + -------- + atleast_1d, atleast_3d + + Examples + -------- + >>> np.atleast_2d(3.0) + array([[ 3.]]) + + >>> x = np.arange(3.0) + >>> np.atleast_2d(x) + array([[ 0., 1., 2.]]) + >>> np.atleast_2d(x).base is x + True + + >>> np.atleast_2d(1, [1, 2], [[1, 2]]) + [array([[1]]), array([[1, 2]]), array([[1, 2]])] + + """ + res = [] + for ary in arys: + ary = asanyarray(ary) + if len(ary.shape) == 0 : + result = ary.reshape(1, 1) + elif len(ary.shape) == 1 : + result = ary[newaxis, :] + else : + result = ary + res.append(result) + if len(res) == 1: + return res[0] + else: + return res + +def atleast_3d(*arys): + """ + View inputs as arrays with at least three dimensions. + + Parameters + ---------- + arys1, arys2, ... : array_like + One or more array-like sequences. Non-array inputs are converted to + arrays. Arrays that already have three or more dimensions are + preserved. + + Returns + ------- + res1, res2, ... : ndarray + An array, or tuple of arrays, each with ``a.ndim >= 3``. Copies are + avoided where possible, and views with three or more dimensions are + returned. For example, a 1-D array of shape ``(N,)`` becomes a view + of shape ``(1, N, 1)``, and a 2-D array of shape ``(M, N)`` becomes a + view of shape ``(M, N, 1)``. + + See Also + -------- + atleast_1d, atleast_2d + + Examples + -------- + >>> np.atleast_3d(3.0) + array([[[ 3.]]]) + + >>> x = np.arange(3.0) + >>> np.atleast_3d(x).shape + (1, 3, 1) + + >>> x = np.arange(12.0).reshape(4,3) + >>> np.atleast_3d(x).shape + (4, 3, 1) + >>> np.atleast_3d(x).base is x + True + + >>> for arr in np.atleast_3d([1, 2], [[1, 2]], [[[1, 2]]]): + ... print arr, arr.shape + ... + [[[1] + [2]]] (1, 2, 1) + [[[1] + [2]]] (1, 2, 1) + [[[1 2]]] (1, 1, 2) + + """ + res = [] + for ary in arys: + ary = asanyarray(ary) + if len(ary.shape) == 0: + result = ary.reshape(1,1,1) + elif len(ary.shape) == 1: + result = ary[newaxis,:,newaxis] + elif len(ary.shape) == 2: + result = ary[:,:,newaxis] + else: + result = ary + res.append(result) + if len(res) == 1: + return res[0] + else: + return res + +def vstack(tup): + """ + Stack arrays in sequence vertically (row wise). + + Take a sequence of arrays and stack them vertically to make a single + array. Rebuild arrays divided by `vsplit`. + + Parameters + ---------- + tup : sequence of ndarrays + Tuple containing arrays to be stacked. The arrays must have the same + shape along all but the first axis. + + Returns + ------- + stacked : ndarray + The array formed by stacking the given arrays. + + See Also + -------- + hstack : Stack arrays in sequence horizontally (column wise). + dstack : Stack arrays in sequence depth wise (along third dimension). + concatenate : Join a sequence of arrays together. + vsplit : Split array into a list of multiple sub-arrays vertically. + + Notes + ----- + Equivalent to ``np.concatenate(tup, axis=0)`` if `tup` contains arrays that + are at least 2-dimensional. + + Examples + -------- + >>> a = np.array([1, 2, 3]) + >>> b = np.array([2, 3, 4]) + >>> np.vstack((a,b)) + array([[1, 2, 3], + [2, 3, 4]]) + + >>> a = np.array([[1], [2], [3]]) + >>> b = np.array([[2], [3], [4]]) + >>> np.vstack((a,b)) + array([[1], + [2], + [3], + [2], + [3], + [4]]) + + """ + return _numpypy.concatenate(map(atleast_2d,tup),0) + +def hstack(tup): + """ + Stack arrays in sequence horizontally (column wise). + + Take a sequence of arrays and stack them horizontally to make + a single array. Rebuild arrays divided by `hsplit`. + + Parameters + ---------- + tup : sequence of ndarrays + All arrays must have the same shape along all but the second axis. + + Returns + ------- + stacked : ndarray + The array formed by stacking the given arrays. + + See Also + -------- + vstack : Stack arrays in sequence vertically (row wise). + dstack : Stack arrays in sequence depth wise (along third axis). + concatenate : Join a sequence of arrays together. + hsplit : Split array along second axis. + + Notes + ----- + Equivalent to ``np.concatenate(tup, axis=1)`` + + Examples + -------- + >>> a = np.array((1,2,3)) + >>> b = np.array((2,3,4)) + >>> np.hstack((a,b)) + array([1, 2, 3, 2, 3, 4]) + >>> a = np.array([[1],[2],[3]]) + >>> b = np.array([[2],[3],[4]]) + >>> np.hstack((a,b)) + array([[1, 2], + [2, 3], + [3, 4]]) + + """ + arrs = map(atleast_1d,tup) + # As a special case, dimension 0 of 1-dimensional arrays is "horizontal" + if arrs[0].ndim == 1: + return _numpypy.concatenate(arrs, 0) + else: + return _numpypy.concatenate(arrs, 1) + +def dstack(tup): + """ + Stack arrays in sequence depth wise (along third axis). + + Takes a sequence of arrays and stack them along the third axis + to make a single array. Rebuilds arrays divided by `dsplit`. + This is a simple way to stack 2D arrays (images) into a single + 3D array for processing. + + Parameters + ---------- + tup : sequence of arrays + Arrays to stack. All of them must have the same shape along all + but the third axis. + + Returns + ------- + stacked : ndarray + The array formed by stacking the given arrays. + + See Also + -------- + vstack : Stack along first axis. + hstack : Stack along second axis. + concatenate : Join arrays. + dsplit : Split array along third axis. + + Notes + ----- + Equivalent to ``np.concatenate(tup, axis=2)``. + + Examples + -------- + >>> a = np.array((1,2,3)) + >>> b = np.array((2,3,4)) + >>> np.dstack((a,b)) + array([[[1, 2], + [2, 3], + [3, 4]]]) + + >>> a = np.array([[1],[2],[3]]) + >>> b = np.array([[2],[3],[4]]) + >>> np.dstack((a,b)) + array([[[1, 2]], + [[2, 3]], + [[3, 4]]]) + + """ + return _numpypy.concatenate(map(atleast_3d,tup),2) diff --git a/lib_pypy/pyrepl/cmdrepl.py b/lib_pypy/pyrepl/cmdrepl.py --- a/lib_pypy/pyrepl/cmdrepl.py +++ b/lib_pypy/pyrepl/cmdrepl.py @@ -53,8 +53,8 @@ def get_completions(self, stem): if len(stem) != self.pos: return [] - return cr.uniqify([s for s in self.completions - if s.startswith(stem)]) + return sorted(set(s for s in self.completions + if s.startswith(stem))) def replize(klass, history_across_invocations=1): diff --git a/lib_pypy/pyrepl/completing_reader.py b/lib_pypy/pyrepl/completing_reader.py --- a/lib_pypy/pyrepl/completing_reader.py +++ b/lib_pypy/pyrepl/completing_reader.py @@ -21,13 +21,6 @@ from pyrepl import commands, reader from pyrepl.reader import Reader -def uniqify(l): - d = {} - for i in l: - d[i] = 1 - r = d.keys() - r.sort() - return r def prefix(wordlist, j = 0): d = {} diff --git a/lib_pypy/pyrepl/module_lister.py b/lib_pypy/pyrepl/module_lister.py --- a/lib_pypy/pyrepl/module_lister.py +++ b/lib_pypy/pyrepl/module_lister.py @@ -17,7 +17,6 @@ # CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -from pyrepl.completing_reader import uniqify import os, sys # for the completion support. @@ -38,20 +37,12 @@ l.append( prefix + fname ) _packages[prefix + fname] = _make_module_list_dir( file, suffs, prefix + fname + '.' ) - l = uniqify(l) - l.sort() - return l + return sorted(set(l)) def _make_module_list(): import imp suffs = [x[0] for x in imp.get_suffixes() if x[0] != '.pyc'] - def compare(x, y): - c = -cmp(len(x), len(y)) - if c: - return c - else: - return -cmp(x, y) - suffs.sort(compare) + suffs.sort(reverse=True) _packages[''] = list(sys.builtin_module_names) for dir in sys.path: if dir == '': diff --git a/lib_pypy/pyrepl/python_reader.py b/lib_pypy/pyrepl/python_reader.py --- a/lib_pypy/pyrepl/python_reader.py +++ b/lib_pypy/pyrepl/python_reader.py @@ -140,7 +140,7 @@ return [x[len(mod) + 1:] for x in l if x.startswith(mod + '.' + name)] try: - l = completing_reader.uniqify(self.completer.complete(stem)) + l = sorted(set(self.completer.complete(stem))) return l except (NameError, AttributeError): return [] @@ -178,7 +178,8 @@ self.showsyntaxerror("") else: self.runcode(code) - sys.stdout.flush() + if sys.stdout and not sys.stdout.closed: + sys.stdout.flush() def interact(self): while 1: @@ -368,7 +369,7 @@ encoding = None else: encoding = None # so you get ASCII... - con = UnixConsole(0, 1, None, encoding) + con = UnixConsole(os.dup(0), os.dup(1), None, encoding) if print_banner: print "Python", sys.version, "on", sys.platform print 'Type "help", "copyright", "credits" or "license" '\ diff --git a/lib_pypy/pyrepl/reader.py b/lib_pypy/pyrepl/reader.py --- a/lib_pypy/pyrepl/reader.py +++ b/lib_pypy/pyrepl/reader.py @@ -552,6 +552,8 @@ if not event: # can only happen if we're not blocking return None + translate = True + if event.evt == 'key': self.input_trans.push(event) elif event.evt == 'scroll': @@ -559,9 +561,12 @@ elif event.evt == 'resize': self.refresh() else: - pass + translate = False - cmd = self.input_trans.get() + if translate: + cmd = self.input_trans.get() + else: + cmd = event.evt, event.data if cmd is None: if block: diff --git a/lib_pypy/pyrepl/readline.py b/lib_pypy/pyrepl/readline.py --- a/lib_pypy/pyrepl/readline.py +++ b/lib_pypy/pyrepl/readline.py @@ -174,13 +174,15 @@ # ____________________________________________________________ class _ReadlineWrapper(object): - f_in = 0 - f_out = 1 reader = None saved_history_length = -1 startup_hook = None config = ReadlineConfig() + def __init__(self, f_in=None, f_out=None): + self.f_in = f_in if f_in is not None else os.dup(0) + self.f_out = f_out if f_out is not None else os.dup(1) + def get_reader(self): if self.reader is None: console = UnixConsole(self.f_in, self.f_out, encoding=ENCODING) diff --git a/lib_pypy/pyrepl/test/test_functional.py b/lib_pypy/pyrepl/test/test_functional.py deleted file mode 100644 --- a/lib_pypy/pyrepl/test/test_functional.py +++ /dev/null @@ -1,50 +0,0 @@ -# Copyright 2000-2007 Michael Hudson-Doyle -# Maciek Fijalkowski -# -# All Rights Reserved -# -# -# Permission to use, copy, modify, and distribute this software and -# its documentation for any purpose is hereby granted without fee, -# provided that the above copyright notice appear in all copies and -# that both that copyright notice and this permission notice appear in -# supporting documentation. -# -# THE AUTHOR MICHAEL HUDSON DISCLAIMS ALL WARRANTIES WITH REGARD TO -# THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY -# AND FITNESS, IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, -# INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER -# RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF -# CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -# some functional tests, to see if this is really working - -import py -import sys - -class TestTerminal(object): - def _spawn(self, *args, **kwds): - try: - import pexpect - except ImportError, e: - py.test.skip(str(e)) - kwds.setdefault('timeout', 10) - child = pexpect.spawn(*args, **kwds) - child.logfile = sys.stdout - return child - - def spawn(self, argv=[]): - # avoid running start.py, cause it might contain - # things like readline or rlcompleter(2) included - child = self._spawn(sys.executable, ['-S'] + argv) - child.sendline('from pyrepl.python_reader import main') - child.sendline('main()') - return child - - def test_basic(self): - child = self.spawn() - child.sendline('a = 3') - child.sendline('a') - child.expect('3') - diff --git a/lib_pypy/pyrepl/tests/__init__.py b/lib_pypy/pyrepl/tests/__init__.py deleted file mode 100644 --- a/lib_pypy/pyrepl/tests/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# Copyright 2000-2004 Michael Hudson-Doyle -# -# All Rights Reserved -# -# -# Permission to use, copy, modify, and distribute this software and -# its documentation for any purpose is hereby granted without fee, -# provided that the above copyright notice appear in all copies and -# that both that copyright notice and this permission notice appear in -# supporting documentation. -# -# THE AUTHOR MICHAEL HUDSON DISCLAIMS ALL WARRANTIES WITH REGARD TO -# THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY -# AND FITNESS, IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, -# INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER -# RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF -# CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -# moo diff --git a/lib_pypy/pyrepl/tests/basic.py b/lib_pypy/pyrepl/tests/basic.py deleted file mode 100644 --- a/lib_pypy/pyrepl/tests/basic.py +++ /dev/null @@ -1,115 +0,0 @@ -# Copyright 2000-2004 Michael Hudson-Doyle -# -# All Rights Reserved -# -# -# Permission to use, copy, modify, and distribute this software and -# its documentation for any purpose is hereby granted without fee, -# provided that the above copyright notice appear in all copies and -# that both that copyright notice and this permission notice appear in -# supporting documentation. -# -# THE AUTHOR MICHAEL HUDSON DISCLAIMS ALL WARRANTIES WITH REGARD TO -# THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY -# AND FITNESS, IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, -# INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER -# RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF -# CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -from pyrepl.console import Event -from pyrepl.tests.infrastructure import ReaderTestCase, EA, run_testcase - -class SimpleTestCase(ReaderTestCase): - - def test_basic(self): - self.run_test([(('self-insert', 'a'), ['a']), - ( 'accept', ['a'])]) - - def test_repeat(self): - self.run_test([(('digit-arg', '3'), ['']), - (('self-insert', 'a'), ['aaa']), - ( 'accept', ['aaa'])]) - - def test_kill_line(self): - self.run_test([(('self-insert', 'abc'), ['abc']), - ( 'left', None), - ( 'kill-line', ['ab']), - ( 'accept', ['ab'])]) - - def test_unix_line_discard(self): - self.run_test([(('self-insert', 'abc'), ['abc']), - ( 'left', None), - ( 'unix-word-rubout', ['c']), - ( 'accept', ['c'])]) - - def test_kill_word(self): - self.run_test([(('self-insert', 'ab cd'), ['ab cd']), - ( 'beginning-of-line', ['ab cd']), - ( 'kill-word', [' cd']), - ( 'accept', [' cd'])]) - - def test_backward_kill_word(self): - self.run_test([(('self-insert', 'ab cd'), ['ab cd']), - ( 'backward-kill-word', ['ab ']), - ( 'accept', ['ab '])]) - - def test_yank(self): - self.run_test([(('self-insert', 'ab cd'), ['ab cd']), - ( 'backward-kill-word', ['ab ']), - ( 'beginning-of-line', ['ab ']), - ( 'yank', ['cdab ']), - ( 'accept', ['cdab '])]) - - def test_yank_pop(self): - self.run_test([(('self-insert', 'ab cd'), ['ab cd']), - ( 'backward-kill-word', ['ab ']), - ( 'left', ['ab ']), - ( 'backward-kill-word', [' ']), - ( 'yank', ['ab ']), - ( 'yank-pop', ['cd ']), - ( 'accept', ['cd '])]) - - def test_interrupt(self): - try: - self.run_test([( 'interrupt', [''])]) - except KeyboardInterrupt: - pass - else: - self.fail('KeyboardInterrupt got lost') - - # test_suspend -- hah - - def test_up(self): - self.run_test([(('self-insert', 'ab\ncd'), ['ab', 'cd']), - ( 'up', ['ab', 'cd']), - (('self-insert', 'e'), ['abe', 'cd']), - ( 'accept', ['abe', 'cd'])]) - - def test_down(self): - self.run_test([(('self-insert', 'ab\ncd'), ['ab', 'cd']), - ( 'up', ['ab', 'cd']), - (('self-insert', 'e'), ['abe', 'cd']), - ( 'down', ['abe', 'cd']), - (('self-insert', 'f'), ['abe', 'cdf']), - ( 'accept', ['abe', 'cdf'])]) - - def test_left(self): - self.run_test([(('self-insert', 'ab'), ['ab']), - ( 'left', ['ab']), - (('self-insert', 'c'), ['acb']), - ( 'accept', ['acb'])]) - - def test_right(self): - self.run_test([(('self-insert', 'ab'), ['ab']), - ( 'left', ['ab']), - (('self-insert', 'c'), ['acb']), - ( 'right', ['acb']), - (('self-insert', 'd'), ['acbd']), - ( 'accept', ['acbd'])]) - -def test(): - run_testcase(SimpleTestCase) - -if __name__ == '__main__': - test() diff --git a/lib_pypy/pyrepl/tests/bugs.py b/lib_pypy/pyrepl/tests/bugs.py deleted file mode 100644 --- a/lib_pypy/pyrepl/tests/bugs.py +++ /dev/null @@ -1,36 +0,0 @@ -# Copyright 2000-2004 Michael Hudson-Doyle -# -# All Rights Reserved -# -# -# Permission to use, copy, modify, and distribute this software and -# its documentation for any purpose is hereby granted without fee, -# provided that the above copyright notice appear in all copies and -# that both that copyright notice and this permission notice appear in -# supporting documentation. -# -# THE AUTHOR MICHAEL HUDSON DISCLAIMS ALL WARRANTIES WITH REGARD TO -# THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY -# AND FITNESS, IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, -# INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER -# RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF -# CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -from pyrepl.console import Event -from pyrepl.tests.infrastructure import ReaderTestCase, EA, run_testcase - -# this test case should contain as-verbatim-as-possible versions of -# (applicable) bug reports - -class BugsTestCase(ReaderTestCase): - - def test_transpose_at_start(self): - self.run_test([( 'transpose', [EA, '']), - ( 'accept', [''])]) - -def test(): - run_testcase(BugsTestCase) - -if __name__ == '__main__': - test() diff --git a/lib_pypy/pyrepl/tests/infrastructure.py b/lib_pypy/pyrepl/tests/infrastructure.py deleted file mode 100644 --- a/lib_pypy/pyrepl/tests/infrastructure.py +++ /dev/null @@ -1,82 +0,0 @@ -# Copyright 2000-2004 Michael Hudson-Doyle -# -# All Rights Reserved -# -# -# Permission to use, copy, modify, and distribute this software and -# its documentation for any purpose is hereby granted without fee, -# provided that the above copyright notice appear in all copies and -# that both that copyright notice and this permission notice appear in -# supporting documentation. -# -# THE AUTHOR MICHAEL HUDSON DISCLAIMS ALL WARRANTIES WITH REGARD TO -# THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY -# AND FITNESS, IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, -# INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER -# RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF -# CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -from pyrepl.reader import Reader -from pyrepl.console import Console, Event -import unittest -import sys - -class EqualsAnything(object): - def __eq__(self, other): - return True -EA = EqualsAnything() - -class TestConsole(Console): - height = 24 - width = 80 - encoding = 'utf-8' - - def __init__(self, events, testcase, verbose=False): - self.events = events - self.next_screen = None - self.verbose = verbose - self.testcase = testcase - - def refresh(self, screen, xy): - if self.next_screen is not None: - self.testcase.assertEqual( - screen, self.next_screen, - "[ %s != %s after %r ]"%(screen, self.next_screen, - self.last_event_name)) - - def get_event(self, block=1): - ev, sc = self.events.pop(0) - self.next_screen = sc - if not isinstance(ev, tuple): - ev = (ev,) - self.last_event_name = ev[0] - if self.verbose: - print "event", ev - return Event(*ev) - -class TestReader(Reader): - def get_prompt(self, lineno, cursor_on_line): - return '' - def refresh(self): - Reader.refresh(self) - self.dirty = True - -class ReaderTestCase(unittest.TestCase): - def run_test(self, test_spec, reader_class=TestReader): - # remember to finish your test_spec with 'accept' or similar! - con = TestConsole(test_spec, self) - reader = reader_class(con) - reader.readline() - -class BasicTestRunner: - def run(self, test): - result = unittest.TestResult() - test(result) - return result - -def run_testcase(testclass): - suite = unittest.makeSuite(testclass) - runner = unittest.TextTestRunner(sys.stdout, verbosity=1) - result = runner.run(suite) - diff --git a/lib_pypy/pyrepl/tests/wishes.py b/lib_pypy/pyrepl/tests/wishes.py deleted file mode 100644 --- a/lib_pypy/pyrepl/tests/wishes.py +++ /dev/null @@ -1,38 +0,0 @@ -# Copyright 2000-2004 Michael Hudson-Doyle -# -# All Rights Reserved -# -# -# Permission to use, copy, modify, and distribute this software and -# its documentation for any purpose is hereby granted without fee, -# provided that the above copyright notice appear in all copies and -# that both that copyright notice and this permission notice appear in -# supporting documentation. -# -# THE AUTHOR MICHAEL HUDSON DISCLAIMS ALL WARRANTIES WITH REGARD TO -# THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY -# AND FITNESS, IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, -# INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER -# RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF -# CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -from pyrepl.console import Event -from pyrepl.tests.infrastructure import ReaderTestCase, EA, run_testcase - -# this test case should contain as-verbatim-as-possible versions of -# (applicable) feature requests - -class WishesTestCase(ReaderTestCase): - - def test_quoted_insert_repeat(self): - self.run_test([(('digit-arg', '3'), ['']), - ( 'quoted-insert', ['']), - (('self-insert', '\033'), ['^[^[^[']), - ( 'accept', None)]) - -def test(): - run_testcase(WishesTestCase) - -if __name__ == '__main__': - test() diff --git a/lib_pypy/pyrepl/unix_console.py b/lib_pypy/pyrepl/unix_console.py --- a/lib_pypy/pyrepl/unix_console.py +++ b/lib_pypy/pyrepl/unix_console.py @@ -185,16 +185,6 @@ old_offset = offset = self.__offset height = self.height - if 0: - global counter - try: - counter - except NameError: - counter = 0 - self.__write_code(curses.tigetstr("setaf"), counter) - counter += 1 - if counter > 8: - counter = 0 # we make sure the cursor is on the screen, and that we're # using all of the screen if we can diff --git a/pypy/doc/config/translation.lldebug.txt b/pypy/doc/config/translation.lldebug.txt new file mode 100644 --- /dev/null +++ b/pypy/doc/config/translation.lldebug.txt @@ -0,0 +1,1 @@ +Run make lldebug when source is ready diff --git a/pypy/interpreter/app_main.py b/pypy/interpreter/app_main.py --- a/pypy/interpreter/app_main.py +++ b/pypy/interpreter/app_main.py @@ -310,8 +310,6 @@ "warnoptions", "unbuffered"), 0) -PYTHON26 = True - def simple_option(options, name, iterargv): options[name] += 1 @@ -341,38 +339,35 @@ cmdline_options = { # simple options just increment the counter of the options listed above + 'b': (simple_option, 'bytes_warning'), + 'B': (simple_option, 'dont_write_bytecode'), 'd': (simple_option, 'debug'), + 'E': (simple_option, 'ignore_environment'), 'i': (simple_option, 'interactive'), 'O': (simple_option, 'optimize'), + 'R': (simple_option, 'hash_randomization'), + 's': (simple_option, 'no_user_site'), 'S': (simple_option, 'no_site'), - 'E': (simple_option, 'ignore_environment'), 't': (simple_option, 'tabcheck'), - 'v': (simple_option, 'verbose'), 'U': (simple_option, 'unicode'), 'u': (simple_option, 'unbuffered'), + 'v': (simple_option, 'verbose'), + '3': (simple_option, 'py3k_warning'), # more complex options - 'Q': (div_option, Ellipsis), 'c': (c_option, Ellipsis), + '?': (print_help, None), + 'h': (print_help, None), + '--help': (print_help, None), 'm': (m_option, Ellipsis), 'W': (W_option, Ellipsis), 'V': (print_version, None), '--version': (print_version, None), + 'Q': (div_option, Ellipsis), '--info': (print_info, None), - 'h': (print_help, None), - '--help': (print_help, None), '--jit': (set_jit_option, Ellipsis), '--': (end_options, None), } -if PYTHON26: - cmdline_options.update({ - '3': (simple_option, 'py3k_warning'), - 'B': (simple_option, 'dont_write_bytecode'), - 's': (simple_option, 'no_user_site'), - 'b': (simple_option, 'bytes_warning'), - 'R': (simple_option, 'hash_randomization'), - }) - def handle_argument(c, options, iterargv, iterarg=iter(())): function, funcarg = cmdline_options[c] @@ -432,13 +427,16 @@ sys.argv[:] = argv if not options["ignore_environment"]: + if os.getenv('PYTHONDEBUG'): + options["debug"] = 1 + if os.getenv('PYTHONDONTWRITEBYTECODE'): + options["dont_write_bytecode"] = 1 + if os.getenv('PYTHONNOUSERSITE'): + options["no_user_site"] = 1 if os.getenv('PYTHONUNBUFFERED'): options["unbuffered"] = 1 - if PYTHON26: - if os.getenv('PYTHONNOUSERSITE'): - options["no_user_site"] = 1 - if os.getenv('PYTHONDONTWRITEBYTECODE'): - options["dont_write_bytecode"] = 1 + if os.getenv('PYTHONVERBOSE'): + options["verbose"] = 1 if (options["interactive"] or (not options["ignore_environment"] and os.getenv('PYTHONINSPECT'))): @@ -450,7 +448,7 @@ ## print >> sys.stderr, ( ## "Warning: pypy does not implement hash randomization") - if PYTHON26 and we_are_translated(): + if we_are_translated(): flags = [options[flag] for flag in sys_flags] sys.flags = type(sys.flags)(flags) sys.py3kwarning = bool(sys.flags.py3k_warning) diff --git a/pypy/interpreter/test2/test_app_main.py b/pypy/interpreter/test2/test_app_main.py --- a/pypy/interpreter/test2/test_app_main.py +++ b/pypy/interpreter/test2/test_app_main.py @@ -81,14 +81,16 @@ assert not value, ( "option %r has unexpectedly the value %r" % (key, value)) - def check(self, argv, **expected): + def check(self, argv, env, **expected): import StringIO from pypy.interpreter import app_main + saved_env = os.environ.copy() saved_sys_argv = sys.argv[:] saved_sys_stdout = sys.stdout saved_sys_stderr = sys.stdout app_main.os = os try: + os.environ.update(env) sys.stdout = sys.stderr = StringIO.StringIO() try: options = app_main.parse_command_line(argv) @@ -98,64 +100,73 @@ else: self.check_options(options, **expected) finally: + os.environ.clear() + os.environ.update(saved_env) sys.argv[:] = saved_sys_argv sys.stdout = saved_sys_stdout sys.stderr = saved_sys_stderr def test_all_combinations_I_can_think_of(self): - self.check([], sys_argv=[''], run_stdin=True) - self.check(['-'], sys_argv=['-'], run_stdin=True) - self.check(['-S'], sys_argv=[''], run_stdin=True, no_site=1) - self.check(['-OO'], sys_argv=[''], run_stdin=True, optimize=2) - self.check(['-O', '-O'], sys_argv=[''], run_stdin=True, optimize=2) - self.check(['-Qnew'], sys_argv=[''], run_stdin=True, division_new=1) - self.check(['-Qold'], sys_argv=[''], run_stdin=True, division_new=0) - self.check(['-Qwarn'], sys_argv=[''], run_stdin=True, division_warning=1) - self.check(['-Qwarnall'], sys_argv=[''], run_stdin=True, + self.check([], {}, sys_argv=[''], run_stdin=True) + self.check(['-'], {}, sys_argv=['-'], run_stdin=True) + self.check(['-S'], {}, sys_argv=[''], run_stdin=True, no_site=1) + self.check(['-OO'], {}, sys_argv=[''], run_stdin=True, optimize=2) + self.check(['-O', '-O'], {}, sys_argv=[''], run_stdin=True, optimize=2) + self.check(['-Qnew'], {}, sys_argv=[''], run_stdin=True, division_new=1) + self.check(['-Qold'], {}, sys_argv=[''], run_stdin=True, division_new=0) + self.check(['-Qwarn'], {}, sys_argv=[''], run_stdin=True, division_warning=1) + self.check(['-Qwarnall'], {}, sys_argv=[''], run_stdin=True, division_warning=2) - self.check(['-Q', 'new'], sys_argv=[''], run_stdin=True, division_new=1) - self.check(['-SOQnew'], sys_argv=[''], run_stdin=True, + self.check(['-Q', 'new'], {}, sys_argv=[''], run_stdin=True, division_new=1) + self.check(['-SOQnew'], {}, sys_argv=[''], run_stdin=True, no_site=1, optimize=1, division_new=1) - self.check(['-SOQ', 'new'], sys_argv=[''], run_stdin=True, + self.check(['-SOQ', 'new'], {}, sys_argv=[''], run_stdin=True, no_site=1, optimize=1, division_new=1) - self.check(['-i'], sys_argv=[''], run_stdin=True, + self.check(['-i'], {}, sys_argv=[''], run_stdin=True, interactive=1, inspect=1) - self.check(['-h'], output_contains='usage:') - self.check(['-S', '-tO', '-h'], output_contains='usage:') - self.check(['-S', '-thO'], output_contains='usage:') - self.check(['-S', '-tO', '--help'], output_contains='usage:') - self.check(['-S', '-tO', '--info'], output_contains='translation') - self.check(['-S', '-tO', '--version'], output_contains='Python') - self.check(['-S', '-tOV'], output_contains='Python') - self.check(['--jit', 'foobar', '-S'], sys_argv=[''], + self.check(['-?'], {}, output_contains='usage:') + self.check(['-h'], {}, output_contains='usage:') + self.check(['-S', '-tO', '-h'], {}, output_contains='usage:') + self.check(['-S', '-thO'], {}, output_contains='usage:') + self.check(['-S', '-tO', '--help'], {}, output_contains='usage:') + self.check(['-S', '-tO', '--info'], {}, output_contains='translation') + self.check(['-S', '-tO', '--version'], {}, output_contains='Python') + self.check(['-S', '-tOV'], {}, output_contains='Python') + self.check(['--jit', 'foobar', '-S'], {}, sys_argv=[''], run_stdin=True, no_site=1) - self.check(['-c', 'pass'], sys_argv=['-c'], run_command='pass') - self.check(['-cpass'], sys_argv=['-c'], run_command='pass') - self.check(['-cpass','x'], sys_argv=['-c','x'], run_command='pass') - self.check(['-Sc', 'pass'], sys_argv=['-c'], run_command='pass', + self.check(['-c', 'pass'], {}, sys_argv=['-c'], run_command='pass') + self.check(['-cpass'], {}, sys_argv=['-c'], run_command='pass') + self.check(['-cpass','x'], {}, sys_argv=['-c','x'], run_command='pass') + self.check(['-Sc', 'pass'], {}, sys_argv=['-c'], run_command='pass', no_site=1) - self.check(['-Scpass'], sys_argv=['-c'], run_command='pass', no_site=1) - self.check(['-c', '', ''], sys_argv=['-c', ''], run_command='') - self.check(['-mfoo', 'bar', 'baz'], sys_argv=['foo', 'bar', 'baz'], + self.check(['-Scpass'], {}, sys_argv=['-c'], run_command='pass', no_site=1) + self.check(['-c', '', ''], {}, sys_argv=['-c', ''], run_command='') + self.check(['-mfoo', 'bar', 'baz'], {}, sys_argv=['foo', 'bar', 'baz'], run_module=True) - self.check(['-m', 'foo', 'bar', 'baz'], sys_argv=['foo', 'bar', 'baz'], + self.check(['-m', 'foo', 'bar', 'baz'], {}, sys_argv=['foo', 'bar', 'baz'], run_module=True) - self.check(['-Smfoo', 'bar', 'baz'], sys_argv=['foo', 'bar', 'baz'], + self.check(['-Smfoo', 'bar', 'baz'], {}, sys_argv=['foo', 'bar', 'baz'], run_module=True, no_site=1) - self.check(['-Sm', 'foo', 'bar', 'baz'], sys_argv=['foo', 'bar', 'baz'], + self.check(['-Sm', 'foo', 'bar', 'baz'], {}, sys_argv=['foo', 'bar', 'baz'], run_module=True, no_site=1) - self.check(['-', 'foo', 'bar'], sys_argv=['-', 'foo', 'bar'], + self.check(['-', 'foo', 'bar'], {}, sys_argv=['-', 'foo', 'bar'], run_stdin=True) - self.check(['foo', 'bar'], sys_argv=['foo', 'bar']) - self.check(['foo', '-i'], sys_argv=['foo', '-i']) - self.check(['-i', 'foo'], sys_argv=['foo'], interactive=1, inspect=1) - self.check(['--', 'foo'], sys_argv=['foo']) - self.check(['--', '-i', 'foo'], sys_argv=['-i', 'foo']) - self.check(['--', '-', 'foo'], sys_argv=['-', 'foo'], run_stdin=True) - self.check(['-Wbog'], sys_argv=[''], warnoptions=['bog'], run_stdin=True) - self.check(['-W', 'ab', '-SWc'], sys_argv=[''], warnoptions=['ab', 'c'], + self.check(['foo', 'bar'], {}, sys_argv=['foo', 'bar']) + self.check(['foo', '-i'], {}, sys_argv=['foo', '-i']) + self.check(['-i', 'foo'], {}, sys_argv=['foo'], interactive=1, inspect=1) + self.check(['--', 'foo'], {}, sys_argv=['foo']) + self.check(['--', '-i', 'foo'], {}, sys_argv=['-i', 'foo']) + self.check(['--', '-', 'foo'], {}, sys_argv=['-', 'foo'], run_stdin=True) + self.check(['-Wbog'], {}, sys_argv=[''], warnoptions=['bog'], run_stdin=True) + self.check(['-W', 'ab', '-SWc'], {}, sys_argv=[''], warnoptions=['ab', 'c'], run_stdin=True, no_site=1) + self.check([], {'PYTHONDEBUG': '1'}, sys_argv=[''], run_stdin=True, debug=1) + self.check([], {'PYTHONDONTWRITEBYTECODE': '1'}, sys_argv=[''], run_stdin=True, dont_write_bytecode=1) + self.check([], {'PYTHONNOUSERSITE': '1'}, sys_argv=[''], run_stdin=True, no_user_site=1) + self.check([], {'PYTHONUNBUFFERED': '1'}, sys_argv=[''], run_stdin=True, unbuffered=1) + self.check([], {'PYTHONVERBOSE': '1'}, sys_argv=[''], run_stdin=True, verbose=1) + def test_sysflags(self): flags = ( ("debug", "-d", "1"), @@ -183,13 +194,13 @@ expected[flag1] = int(value) else: expected = {flag: int(value)} - self.check([opt, '-c', 'pass'], sys_argv=['-c'], + self.check([opt, '-c', 'pass'], {}, sys_argv=['-c'], run_command='pass', **expected) def test_sysflags_envvar(self, monkeypatch): monkeypatch.setenv('PYTHONNOUSERSITE', '1') expected = {"no_user_site": True} - self.check(['-c', 'pass'], sys_argv=['-c'], run_command='pass', **expected) + self.check(['-c', 'pass'], {}, sys_argv=['-c'], run_command='pass', **expected) class TestInteraction: diff --git a/pypy/module/micronumpy/interp_arrayops.py b/pypy/module/micronumpy/interp_arrayops.py --- a/pypy/module/micronumpy/interp_arrayops.py +++ b/pypy/module/micronumpy/interp_arrayops.py @@ -123,6 +123,8 @@ chunks = [Chunk(0, i, 1, i) for i in shape] axis_start = 0 for arr in args_w: + if arr.get_shape()[axis] == 0: + continue chunks[axis] = Chunk(axis_start, axis_start + arr.get_shape()[axis], 1, arr.get_shape()[axis]) Chunks(chunks).apply(res).implementation.setslice(space, arr) diff --git a/pypy/module/micronumpy/interp_boxes.py b/pypy/module/micronumpy/interp_boxes.py --- a/pypy/module/micronumpy/interp_boxes.py +++ b/pypy/module/micronumpy/interp_boxes.py @@ -287,11 +287,11 @@ for i in range(len(arg)): arr.storage[i] = arg[i] return W_StringBox(arr, 0, arr.dtype) - + def convert_to(self, dtype): from pypy.module.micronumpy import types assert isinstance(dtype.itemtype, types.StringType) - return self + return self class W_UnicodeBox(W_CharacterBox): def descr__new__unicode_box(space, w_subtype, w_arg): @@ -308,7 +308,7 @@ def convert_to(self, dtype): from pypy.module.micronumpy import types assert isinstance(dtype.itemtype, types.UnicodeType) - return self + return self class W_ComplexFloatingBox(W_InexactBox): diff --git a/pypy/module/micronumpy/interp_dtype.py b/pypy/module/micronumpy/interp_dtype.py --- a/pypy/module/micronumpy/interp_dtype.py +++ b/pypy/module/micronumpy/interp_dtype.py @@ -224,7 +224,7 @@ size = int(name[1:]) except ValueError: raise OperationError(space.w_TypeError, space.wrap("data type not understood")) - if char == 'S': + if char == 'S' or char == 'c': itemtype = types.StringType(size) basename = 'string' num = 18 @@ -264,8 +264,10 @@ return cache.dtypes_by_name[name] except KeyError: pass - if name[0] in 'VSU' or name[0] in '<>=' and name[1] in 'VSU': + if name[0] in 'VSUc' or name[0] in '<>=' and name[1] in 'VSUc': return variable_dtype(space, name) + raise OperationError(space.w_TypeError, space.wrap( + "data type %s not understood" % name)) elif space.isinstance_w(w_dtype, space.w_list): return dtype_from_list(space, w_dtype) elif space.isinstance_w(w_dtype, space.w_dict): @@ -447,7 +449,7 @@ name="float64", char="d", w_box_type = space.gettypefor(interp_boxes.W_Float64Box), - alternate_constructors=[space.w_float, + alternate_constructors=[space.w_float, space.gettypefor(interp_boxes.W_NumberBox), ], aliases=["float"], @@ -480,10 +482,8 @@ name="float96", char="g", w_box_type=space.gettypefor(interp_boxes.W_Float96Box), - aliases=["longfloat", "longdouble"], + aliases=["longdouble", "longfloat"], ) - self.w_longdouble = self.w_float96dtype - self.w_complex192dtype = W_ComplexDtype( types.Complex192(), num=16, @@ -495,8 +495,8 @@ aliases=["clongdouble", "clongfloat"], float_type = self.w_float96dtype, ) + self.w_longdouble = self.w_float96dtype self.w_clongdouble = self.w_complex192dtype - elif interp_boxes.long_double_size == 16: self.w_float128dtype = W_Dtype( types.Float128(), @@ -505,10 +505,8 @@ name="float128", char="g", w_box_type=space.gettypefor(interp_boxes.W_Float128Box), - aliases=["longfloat", "longdouble"], + aliases=["longdouble", "longfloat"], ) - self.w_longdouble = self.w_float128dtype - self.w_complex256dtype = W_ComplexDtype( types.Complex256(), num=16, @@ -520,11 +518,13 @@ aliases=["clongdouble", "clongfloat"], float_type = self.w_float128dtype, ) + self.w_longdouble = self.w_float128dtype self.w_clongdouble = self.w_complex256dtype else: - self.w_float64dtype.aliases += ["longfloat", "longdouble"] + self.w_float64dtype.aliases += ["longdouble", "longfloat"] + self.w_complex128dtype.aliases += ["clongdouble", "clongfloat"] self.w_longdouble = self.w_float64dtype - self.w_clongdouble = self.w_complex64dtype + self.w_clongdouble = self.w_complex128dtype self.w_stringdtype = W_Dtype( types.StringType(1), num=18, @@ -587,7 +587,7 @@ name='intp', char=INTPLTR, w_box_type = space.gettypefor(intp_box), - ) + ) self.w_uintpdtype = W_Dtype( uintp_type, num=uintp_num, @@ -595,27 +595,31 @@ name='uintp', char=UINTPLTR, w_box_type = space.gettypefor(uintp_box), - ) + ) self.builtin_dtypes = [ - self.w_booldtype, self.w_int8dtype, self.w_uint8dtype, - self.w_int16dtype, self.w_uint16dtype, self.w_int32dtype, - self.w_uint32dtype, self.w_longdtype, self.w_ulongdtype, + self.w_booldtype, + self.w_int8dtype, self.w_uint8dtype, + self.w_int16dtype, self.w_uint16dtype, + self.w_longdtype, self.w_ulongdtype, + self.w_int32dtype, self.w_uint32dtype, self.w_int64dtype, self.w_uint64dtype, - self.w_float16dtype, self.w_float32dtype, self.w_float64dtype, - self.w_longdouble, + self.w_float16dtype, + self.w_float32dtype, self.w_float64dtype, self.w_longdouble, self.w_complex64dtype, self.w_complex128dtype, self.w_clongdouble, - self.w_stringdtype, self.w_unicodedtype, - self.w_voiddtype, self.w_intpdtype, self.w_uintpdtype, + self.w_stringdtype, self.w_unicodedtype, self.w_voiddtype, + self.w_intpdtype, self.w_uintpdtype, ] self.float_dtypes_by_num_bytes = sorted( (dtype.itemtype.get_element_size(), dtype) for dtype in [self.w_float16dtype, self.w_float32dtype, From noreply at buildbot.pypy.org Tue Feb 12 07:43:39 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Tue, 12 Feb 2013 07:43:39 +0100 (CET) Subject: [pypy-commit] pypy default: convert this back to a list and verify it is complete Message-ID: <20130212064339.D35041C0253@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61118:f9c6ec8b2b64 Date: 2013-02-12 01:39 -0500 http://bitbucket.org/pypy/pypy/changeset/f9c6ec8b2b64/ Log: convert this back to a list and verify it is complete diff --git a/pypy/module/micronumpy/interp_dtype.py b/pypy/module/micronumpy/interp_dtype.py --- a/pypy/module/micronumpy/interp_dtype.py +++ b/pypy/module/micronumpy/interp_dtype.py @@ -646,6 +646,11 @@ self.dtypes_by_name[alias] = dtype self.dtypes_by_name[dtype.char] = dtype + self.dtypes_by_num = [dtype for dtype in + sorted(self.dtypes_by_num.values(), key=lambda dtype: dtype.num) + if dtype.num <= self.w_float64dtype.num] + assert len(self.dtypes_by_num) == self.w_float64dtype.num + 1 + typeinfo_full = { 'LONGLONG': self.w_int64dtype, 'SHORT': self.w_int16dtype, From noreply at buildbot.pypy.org Tue Feb 12 08:08:43 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Tue, 12 Feb 2013 08:08:43 +0100 (CET) Subject: [pypy-commit] pypy default: another numpypy string array test Message-ID: <20130212070843.9D9361C1047@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61119:7fc764cd60bf Date: 2013-02-12 02:07 -0500 http://bitbucket.org/pypy/pypy/changeset/7fc764cd60bf/ Log: another numpypy string array test diff --git a/pypy/module/micronumpy/test/test_numarray.py b/pypy/module/micronumpy/test/test_numarray.py --- a/pypy/module/micronumpy/test/test_numarray.py +++ b/pypy/module/micronumpy/test/test_numarray.py @@ -2575,6 +2575,11 @@ assert a[0] == 'abc' assert a[1] == 'defg' assert a[2] == 'ab' + a = array(['abc', 'defg', 'ab'], 'S3') + assert str(a.dtype) == '|S3' + assert a[0] == 'abc' + assert a[1] == 'def' + assert a[2] == 'ab' raises(TypeError, a, 'sum') raises(TypeError, 'a+a') From noreply at buildbot.pypy.org Tue Feb 12 08:08:44 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Tue, 12 Feb 2013 08:08:44 +0100 (CET) Subject: [pypy-commit] pypy default: backout 60b3f3d002ba to test if it caused the performance regression in genshi_text/xml Message-ID: <20130212070844.E14D71C1047@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61120:7532082ce881 Date: 2013-02-12 02:08 -0500 http://bitbucket.org/pypy/pypy/changeset/7532082ce881/ Log: backout 60b3f3d002ba to test if it caused the performance regression in genshi_text/xml diff --git a/pypy/interpreter/eval.py b/pypy/interpreter/eval.py --- a/pypy/interpreter/eval.py +++ b/pypy/interpreter/eval.py @@ -28,7 +28,6 @@ def exec_code(self, space, w_globals, w_locals): "Implements the 'exec' statement." # this should be on PyCode? - space.possibly_convert_to_celldict(w_globals) frame = space.createframe(self, w_globals, None) frame.setdictscope(w_locals) return frame.run() diff --git a/pypy/objspace/std/dictmultiobject.py b/pypy/objspace/std/dictmultiobject.py --- a/pypy/objspace/std/dictmultiobject.py +++ b/pypy/objspace/std/dictmultiobject.py @@ -109,18 +109,6 @@ def view_as_kwargs(self): return self.strategy.view_as_kwargs(self) - def convert_to_celldict_strategy(self, space): - from pypy.objspace.std.celldict import ModuleDictStrategy - - if isinstance(self.strategy, ModuleDictStrategy): - return - items_w = self.items() - self.strategy = ModuleDictStrategy(space) - self.dstorage = self.strategy.get_empty_storage() - for w_tup in items_w: - w_key, w_val = space.fixedview(w_tup, 2) - self.setitem(w_key, w_val) - def _add_indirections(): dict_methods = "setitem setitem_str getitem \ getitem_str delitem length \ diff --git a/pypy/objspace/std/objspace.py b/pypy/objspace/std/objspace.py --- a/pypy/objspace/std/objspace.py +++ b/pypy/objspace/std/objspace.py @@ -684,10 +684,3 @@ if not hasattr(self, "_interplevel_classes"): return None # before running initialize return self._interplevel_classes.get(w_type, None) - - def possibly_convert_to_celldict(self, w_dict): - """ Converts the dict to celldict, if it's a dict, otherwise - leaves it alone - """ - if isinstance(w_dict, W_DictMultiObject): - w_dict.convert_to_celldict_strategy(self) From noreply at buildbot.pypy.org Tue Feb 12 09:51:03 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Tue, 12 Feb 2013 09:51:03 +0100 (CET) Subject: [pypy-commit] pypy default: add a test for c17aa572ce36 Message-ID: <20130212085103.E7D021C0253@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61121:514fb4ea981d Date: 2013-02-12 03:50 -0500 http://bitbucket.org/pypy/pypy/changeset/514fb4ea981d/ Log: add a test for c17aa572ce36 diff --git a/pypy/module/test_lib_pypy/pyrepl/test_bugs.py b/pypy/module/test_lib_pypy/pyrepl/test_bugs.py --- a/pypy/module/test_lib_pypy/pyrepl/test_bugs.py +++ b/pypy/module/test_lib_pypy/pyrepl/test_bugs.py @@ -44,3 +44,24 @@ ('accept', ['']) ] read_spec(spec, HistoricalTestReader) + +def test_signal_failure(monkeypatch): + import os + import pty + import signal + from pyrepl.unix_console import UnixConsole + + def failing_signal(a, b): + raise ValueError + + mfd, sfd = pty.openpty() + try: + c = UnixConsole(sfd, sfd) + c.prepare() + c.restore() + monkeypatch.setattr(signal, 'signal', failing_signal) + c.prepare() + c.restore() + finally: + os.close(mfd) + os.close(sfd) From noreply at buildbot.pypy.org Tue Feb 12 10:04:20 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Tue, 12 Feb 2013 10:04:20 +0100 (CET) Subject: [pypy-commit] pypy default: small addition to last test Message-ID: <20130212090420.4C4BC1C1047@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61122:f81f586cea88 Date: 2013-02-12 04:04 -0500 http://bitbucket.org/pypy/pypy/changeset/f81f586cea88/ Log: small addition to last test diff --git a/pypy/module/test_lib_pypy/pyrepl/test_bugs.py b/pypy/module/test_lib_pypy/pyrepl/test_bugs.py --- a/pypy/module/test_lib_pypy/pyrepl/test_bugs.py +++ b/pypy/module/test_lib_pypy/pyrepl/test_bugs.py @@ -54,6 +54,9 @@ def failing_signal(a, b): raise ValueError + def really_failing_signal(a, b): + raise AssertionError + mfd, sfd = pty.openpty() try: c = UnixConsole(sfd, sfd) @@ -61,6 +64,7 @@ c.restore() monkeypatch.setattr(signal, 'signal', failing_signal) c.prepare() + monkeypatch.setattr(signal, 'signal', really_failing_signal) c.restore() finally: os.close(mfd) From noreply at buildbot.pypy.org Tue Feb 12 11:48:49 2013 From: noreply at buildbot.pypy.org (fijal) Date: Tue, 12 Feb 2013 11:48:49 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: Kill another copy of the same (broken) logic Message-ID: <20130212104849.8F7401C0253@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61123:009a38d24d36 Date: 2013-02-12 12:47 +0200 http://bitbucket.org/pypy/pypy/changeset/009a38d24d36/ Log: Kill another copy of the same (broken) logic diff --git a/rpython/jit/backend/llsupport/rewrite.py b/rpython/jit/backend/llsupport/rewrite.py --- a/rpython/jit/backend/llsupport/rewrite.py +++ b/rpython/jit/backend/llsupport/rewrite.py @@ -175,21 +175,15 @@ None, descr=descrs.jf_frame_info) self.newops.append(op2) arglist = op.getarglist() - index = self.cpu.getarryoffset_for_frame() + index_list = loop_token.compiled_loop_token._ll_initial_locs for i, arg in enumerate(arglist): descr = self.cpu.getarraydescr_for_frame(arg.type) - if WORD == 4 and arg.type == history.FLOAT: - self.newops.append(ResOperation(rop.SETARRAYITEM_GC, - [frame, ConstInt(index // 2), - arg], - None, descr)) - index += 2 - else: - self.newops.append(ResOperation(rop.SETARRAYITEM_GC, - [frame, ConstInt(index), - arg], - None, descr)) - index += 1 + _, itemsize, _ = self.cpu.unpack_arraydescr_size(descr) + index = index_list[i] // itemsize # index is in bytes + self.newops.append(ResOperation(rop.SETARRAYITEM_GC, + [frame, ConstInt(index), + arg], + None, descr)) descr = op.getdescr() assert isinstance(descr, JitCellToken) jd = descr.outermost_jitdriver_sd diff --git a/rpython/jit/backend/llsupport/test/test_rewrite.py b/rpython/jit/backend/llsupport/test/test_rewrite.py --- a/rpython/jit/backend/llsupport/test/test_rewrite.py +++ b/rpython/jit/backend/llsupport/test/test_rewrite.py @@ -72,6 +72,7 @@ casmdescr = JitCellToken() clt = FakeLoopToken() + clt._ll_initial_locs = [0, WORD] frame_info = lltype.malloc(jitframe.JITFRAMEINFO, flavor='raw') clt.frame_info = frame_info frame_info.jfi_frame_depth = 13 @@ -116,8 +117,8 @@ return self.floatframedescr return self.signedframedescr - def getarryoffset_for_frame(self): - return 0 + def unpack_arraydescr_size(self, d): + return 0, d.itemsize, 0 def arraydescrof(self, ARRAY): try: diff --git a/rpython/jit/backend/x86/regalloc.py b/rpython/jit/backend/x86/regalloc.py --- a/rpython/jit/backend/x86/regalloc.py +++ b/rpython/jit/backend/x86/regalloc.py @@ -190,13 +190,14 @@ def _set_initial_bindings(self, inputargs, looptoken): locs = [] + base_ofs = self.assembler.cpu.get_baseofs_of_frame_field() for box in inputargs: assert isinstance(box, Box) loc = self.fm.get_new_loc(box) - locs.append(loc.value) + locs.append(loc.value - base_ofs) if looptoken.compiled_loop_token is not None: # for tests - looptoken.compiled_loop_token._x86_initial_locs = locs + looptoken.compiled_loop_token._ll_initial_locs = locs def possibly_free_var(self, var): if var.type == FLOAT: diff --git a/rpython/jit/backend/x86/runner.py b/rpython/jit/backend/x86/runner.py --- a/rpython/jit/backend/x86/runner.py +++ b/rpython/jit/backend/x86/runner.py @@ -55,9 +55,6 @@ else: return 1000 - def getarryoffset_for_frame(self): - return JITFRAME_FIXED_SIZE - def setup(self): self.assembler = Assembler386(self, self.translate_support_code) @@ -119,9 +116,8 @@ #llop.debug_print(lltype.Void, ">>>> Entering", addr) frame_info = clt.frame_info frame = self.gc_ll_descr.malloc_jitframe(frame_info) - base_ofs = self.get_baseofs_of_frame_field() ll_frame = lltype.cast_opaque_ptr(llmemory.GCREF, frame) - locs = executable_token.compiled_loop_token._x86_initial_locs + locs = executable_token.compiled_loop_token._ll_initial_locs prev_interpreter = None # help flow space if not self.translate_support_code: prev_interpreter = LLInterpreter.current_interpreter @@ -129,7 +125,7 @@ try: for i, kind in kinds: arg = args[i] - num = locs[i] - base_ofs + num = locs[i] if kind == history.INT: self.set_int_value(ll_frame, num, arg) elif kind == history.FLOAT: From noreply at buildbot.pypy.org Tue Feb 12 12:00:40 2013 From: noreply at buildbot.pypy.org (kostialopuhin) Date: Tue, 12 Feb 2013 12:00:40 +0100 (CET) Subject: [pypy-commit] pypy urlparse-unquote-faster: fix quadratic slowness of unquote (caused by buliding string with inplace addition) Message-ID: <20130212110040.7DD451C0253@cobra.cs.uni-duesseldorf.de> Author: Konstantin Lopuhin Branch: urlparse-unquote-faster Changeset: r61124:c7ea99e3b4db Date: 2013-02-12 00:22 +0400 http://bitbucket.org/pypy/pypy/changeset/c7ea99e3b4db/ Log: fix quadratic slowness of unquote (caused by buliding string with inplace addition) diff --git a/lib-python/2.7/urllib.py b/lib-python/2.7/urllib.py --- a/lib-python/2.7/urllib.py +++ b/lib-python/2.7/urllib.py @@ -1205,15 +1205,16 @@ # fastpath if len(res) == 1: return s - s = res[0] + res_list = [res[0]] for item in res[1:]: try: - s += _hextochr[item[:2]] + item[2:] + x = _hextochr[item[:2]] + item[2:] except KeyError: - s += '%' + item + x = '%' + item except UnicodeDecodeError: - s += unichr(int(item[:2], 16)) + item[2:] - return s + x = unichr(int(item[:2], 16)) + item[2:] + res_list.append(x) + return ''.join(res_list) def unquote_plus(s): """unquote('%7e/abc+def') -> '~/abc def'""" diff --git a/lib-python/2.7/urlparse.py b/lib-python/2.7/urlparse.py --- a/lib-python/2.7/urlparse.py +++ b/lib-python/2.7/urlparse.py @@ -321,15 +321,16 @@ # fastpath if len(res) == 1: return s - s = res[0] + res_list = [res[0]] for item in res[1:]: try: - s += _hextochr[item[:2]] + item[2:] + x = _hextochr[item[:2]] + item[2:] except KeyError: - s += '%' + item + x = '%' + item except UnicodeDecodeError: - s += unichr(int(item[:2], 16)) + item[2:] - return s + x = unichr(int(item[:2], 16)) + item[2:] + res_list.append(x) + return ''.join(res_list) def parse_qs(qs, keep_blank_values=0, strict_parsing=0): """Parse a query given as a string argument. From noreply at buildbot.pypy.org Tue Feb 12 12:00:42 2013 From: noreply at buildbot.pypy.org (fijal) Date: Tue, 12 Feb 2013 12:00:42 +0100 (CET) Subject: [pypy-commit] pypy default: Merged in kostialopuhin/pypy/urlparse-unquote-faster (pull request #118) Message-ID: <20130212110042.151101C0253@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r61125:dcc4f89c3872 Date: 2013-02-12 12:59 +0200 http://bitbucket.org/pypy/pypy/changeset/dcc4f89c3872/ Log: Merged in kostialopuhin/pypy/urlparse-unquote-faster (pull request #118) Make unquote from urllib and urlparse faster diff --git a/pypy/doc/config/translation.lldebug.txt b//doc/config/translation.lldebug.txt rename from pypy/doc/config/translation.lldebug.txt rename to /doc/config/translation.lldebug.txt diff --git a/pypy/goal/__init__.py b//goal/__init__.py rename from pypy/goal/__init__.py rename to /goal/__init__.py diff --git a/pypy/module/cpyext/include/ceval.h b//module/cpyext/include/ceval.h rename from pypy/module/cpyext/include/ceval.h rename to /module/cpyext/include/ceval.h diff --git a/pypy/module/micronumpy/arrayimpl/sort.py b//module/micronumpy/arrayimpl/sort.py rename from pypy/module/micronumpy/arrayimpl/sort.py rename to /module/micronumpy/arrayimpl/sort.py diff --git a/pypy/module/micronumpy/constants.py b//module/micronumpy/constants.py rename from pypy/module/micronumpy/constants.py rename to /module/micronumpy/constants.py diff --git a/pypy/module/test_lib_pypy/numpypy/core/test_shape_base.py b//module/test_lib_pypy/numpypy/core/test_shape_base.py rename from pypy/module/test_lib_pypy/numpypy/core/test_shape_base.py rename to /module/test_lib_pypy/numpypy/core/test_shape_base.py diff --git a/pypy/module/test_lib_pypy/pyrepl/test_keymap.py b//module/test_lib_pypy/pyrepl/test_keymap.py rename from pypy/module/test_lib_pypy/pyrepl/test_keymap.py rename to /module/test_lib_pypy/pyrepl/test_keymap.py diff --git a/pypy/module/test_lib_pypy/pyrepl/test_readline.py b//module/test_lib_pypy/pyrepl/test_readline.py rename from pypy/module/test_lib_pypy/pyrepl/test_readline.py rename to /module/test_lib_pypy/pyrepl/test_readline.py diff --git a/pypy/sandbox/__init__.py b//sandbox/__init__.py rename from pypy/sandbox/__init__.py rename to /sandbox/__init__.py diff --git a/lib-python/2.7/urllib.py b/lib-python/2.7/urllib.py --- a/lib-python/2.7/urllib.py +++ b/lib-python/2.7/urllib.py @@ -1205,15 +1205,16 @@ # fastpath if len(res) == 1: return s - s = res[0] + res_list = [res[0]] for item in res[1:]: try: - s += _hextochr[item[:2]] + item[2:] + x = _hextochr[item[:2]] + item[2:] except KeyError: - s += '%' + item + x = '%' + item except UnicodeDecodeError: - s += unichr(int(item[:2], 16)) + item[2:] - return s + x = unichr(int(item[:2], 16)) + item[2:] + res_list.append(x) + return ''.join(res_list) def unquote_plus(s): """unquote('%7e/abc+def') -> '~/abc def'""" diff --git a/lib-python/2.7/urlparse.py b/lib-python/2.7/urlparse.py --- a/lib-python/2.7/urlparse.py +++ b/lib-python/2.7/urlparse.py @@ -321,15 +321,16 @@ # fastpath if len(res) == 1: return s - s = res[0] + res_list = [res[0]] for item in res[1:]: try: - s += _hextochr[item[:2]] + item[2:] + x = _hextochr[item[:2]] + item[2:] except KeyError: - s += '%' + item + x = '%' + item except UnicodeDecodeError: - s += unichr(int(item[:2], 16)) + item[2:] - return s + x = unichr(int(item[:2], 16)) + item[2:] + res_list.append(x) + return ''.join(res_list) def parse_qs(qs, keep_blank_values=0, strict_parsing=0): """Parse a query given as a string argument. From noreply at buildbot.pypy.org Tue Feb 12 12:06:27 2013 From: noreply at buildbot.pypy.org (fijal) Date: Tue, 12 Feb 2013 12:06:27 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: fixes for gc_integration Message-ID: <20130212110627.8660A1C0253@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61126:45ecdb12c70d Date: 2013-02-12 13:05 +0200 http://bitbucket.org/pypy/pypy/changeset/45ecdb12c70d/ Log: fixes for gc_integration diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -322,14 +322,11 @@ # have been used to pass arguments. Note that we pass only # one argument, that is the frame mc.PUSH_r(edi.value) + mc.MOV_rr(edi.value, esp.value) # if IS_X86_32: - xxx - stack_size += 2*WORD - mc.PUSH_r(eax.value) # alignment + mc.SUB_ri(esp.value, 2*WORD) # alignment mc.PUSH_r(esp.value) - elif IS_X86_64: - mc.MOV_rr(edi.value, esp.value) # # esp is now aligned to a multiple of 16 again mc.CALL(imm(slowpathaddr)) @@ -340,9 +337,8 @@ jnz_location = mc.get_relative_pos() # if IS_X86_32: - xxxx - mc.ADD_ri(esp.value, 2*WORD) # cancel the two PUSHes above - elif IS_X86_64: + mc.ADD_ri(esp.value, 3*WORD) # alignment + else: # restore the edi mc.POP_r(edi.value) # @@ -396,16 +392,18 @@ mc.SUB_ri(esp.value, 2 * WORD) mc.MOV_rs(eax.value, 3 * WORD) # 2 + 1 mc.MOV_sr(0, eax.value) - elif IS_X86_64: + else: mc.MOV_rs(edi.value, WORD) else: # we're possibly called from the slowpath of malloc, so we have # one extra CALL on the stack, but one less PUSH, # save to store stuff 2 locations away on the stack. + mc.MOV_sr(3 * WORD, eax.value) # save for later if IS_X86_32: - xxx - mc.MOV_sr(3*WORD, eax.value) - mc.MOV_rr(edi.value, ebp.value) + mc.SUB_ri(esp.value, 2 * WORD) # align + mc.MOV_sr(0, ebp.value) + else: + mc.MOV_rr(edi.value, ebp.value) mc.CALL(imm(func)) # @@ -429,8 +427,8 @@ mc.RET16_i(WORD) else: if IS_X86_32: - XXX - mc.MOV_rs(eax.value, 3 * WORD) + mc.LEA_rs(esp.value, 2 * WORD) + mc.MOV_rs(eax.value, 3 * WORD) # restore mc.RET() rawstart = mc.materialize(self.cpu.asmmemmgr, []) diff --git a/rpython/jit/backend/x86/test/test_gc_integration.py b/rpython/jit/backend/x86/test/test_gc_integration.py --- a/rpython/jit/backend/x86/test/test_gc_integration.py +++ b/rpython/jit/backend/x86/test/test_gc_integration.py @@ -7,7 +7,7 @@ from rpython.jit.backend.llsupport.gc import GcLLDescription, GcLLDescr_boehm,\ GcLLDescr_framework, GcCache, JitFrameDescrs from rpython.jit.backend.detect_cpu import getcpuclass -from rpython.jit.backend.x86.arch import WORD, JITFRAME_FIXED_SIZE +from rpython.jit.backend.x86.arch import WORD, JITFRAME_FIXED_SIZE, IS_X86_64 from rpython.jit.backend.llsupport import jitframe from rpython.rtyper.lltypesystem import lltype, llmemory, rffi from rpython.rtyper.annlowlevel import llhelper, llhelper_args @@ -71,10 +71,15 @@ # the gcmap should contain three things, p0, p1 and p3 # p3 stays in a register # while p0 and p1 are on the frame - assert frame.jf_gcmap[0] == (1 << 11) | (1 << 12) | (1 << 31) - assert frame.jf_frame[11] - assert frame.jf_frame[12] - assert frame.jf_frame[31] + if IS_X86_64: + nos = [11, 12, 31] + else: + nos = [4, 5, 25] + assert frame.jf_gcmap[0] == ((1 << nos[0]) | (1 << nos[1]) | + (1 << nos[2])) + assert frame.jf_frame[nos[0]] + assert frame.jf_frame[nos[1]] + assert frame.jf_frame[nos[2]] def test_rewrite_constptr(self): ops = ''' From noreply at buildbot.pypy.org Tue Feb 12 12:09:56 2013 From: noreply at buildbot.pypy.org (fijal) Date: Tue, 12 Feb 2013 12:09:56 +0100 (CET) Subject: [pypy-commit] pypy default: Backed out changeset dcc4f89c3872 Message-ID: <20130212110956.0DE6E1C0253@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r61127:a7dd6ebe1122 Date: 2013-02-12 13:09 +0200 http://bitbucket.org/pypy/pypy/changeset/a7dd6ebe1122/ Log: Backed out changeset dcc4f89c3872 diff --git a/lib-python/2.7/urllib.py b/lib-python/2.7/urllib.py --- a/lib-python/2.7/urllib.py +++ b/lib-python/2.7/urllib.py @@ -1205,16 +1205,15 @@ # fastpath if len(res) == 1: return s - res_list = [res[0]] + s = res[0] for item in res[1:]: try: - x = _hextochr[item[:2]] + item[2:] + s += _hextochr[item[:2]] + item[2:] except KeyError: - x = '%' + item + s += '%' + item except UnicodeDecodeError: - x = unichr(int(item[:2], 16)) + item[2:] - res_list.append(x) - return ''.join(res_list) + s += unichr(int(item[:2], 16)) + item[2:] + return s def unquote_plus(s): """unquote('%7e/abc+def') -> '~/abc def'""" diff --git a/lib-python/2.7/urlparse.py b/lib-python/2.7/urlparse.py --- a/lib-python/2.7/urlparse.py +++ b/lib-python/2.7/urlparse.py @@ -321,16 +321,15 @@ # fastpath if len(res) == 1: return s - res_list = [res[0]] + s = res[0] for item in res[1:]: try: - x = _hextochr[item[:2]] + item[2:] + s += _hextochr[item[:2]] + item[2:] except KeyError: - x = '%' + item + s += '%' + item except UnicodeDecodeError: - x = unichr(int(item[:2], 16)) + item[2:] - res_list.append(x) - return ''.join(res_list) + s += unichr(int(item[:2], 16)) + item[2:] + return s def parse_qs(qs, keep_blank_values=0, strict_parsing=0): """Parse a query given as a string argument. diff --git a/pypy/doc/config/translation.lldebug.txt b/pypy/doc/config/translation.lldebug.txt new file mode 100644 --- /dev/null +++ b/pypy/doc/config/translation.lldebug.txt @@ -0,0 +1,1 @@ +Run make lldebug when source is ready diff --git a/pypy/goal/__init__.py b/pypy/goal/__init__.py new file mode 100644 --- /dev/null +++ b/pypy/goal/__init__.py @@ -0,0 +1,1 @@ +#empty diff --git a/pypy/module/cpyext/include/ceval.h b/pypy/module/cpyext/include/ceval.h new file mode 100644 --- /dev/null +++ b/pypy/module/cpyext/include/ceval.h @@ -0,0 +1,1 @@ +/* empty */ diff --git a/pypy/module/micronumpy/arrayimpl/sort.py b/pypy/module/micronumpy/arrayimpl/sort.py new file mode 100644 --- /dev/null +++ b/pypy/module/micronumpy/arrayimpl/sort.py @@ -0,0 +1,195 @@ + +""" This is the implementation of various sorting routines in numpy. It's here +because it only makes sense on a concrete array +""" + +from rpython.rtyper.lltypesystem import rffi, lltype +from rpython.rlib.listsort import make_timsort_class +from rpython.rlib.rawstorage import raw_storage_getitem, raw_storage_setitem, \ + free_raw_storage, alloc_raw_storage +from rpython.rlib.unroll import unrolling_iterable +from rpython.rlib.rarithmetic import intmask +from rpython.rlib.objectmodel import specialize +from pypy.interpreter.error import OperationError +from pypy.module.micronumpy.base import W_NDimArray +from pypy.module.micronumpy import interp_dtype, types +from pypy.module.micronumpy.iter import AxisIterator + +INT_SIZE = rffi.sizeof(lltype.Signed) + +def make_sort_function(space, itemtype, comp_type, count=1): + TP = itemtype.T + step = rffi.sizeof(TP) + + class Repr(object): + def __init__(self, index_stride_size, stride_size, size, values, + indexes, index_start, start): + self.index_stride_size = index_stride_size + self.stride_size = stride_size + self.index_start = index_start + self.start = start + self.size = size + self.values = values + self.indexes = indexes + + def getitem(self, item): + if count < 2: + v = raw_storage_getitem(TP, self.values, item * self.stride_size + + self.start) + else: + v = [] + for i in range(count): + _v = raw_storage_getitem(TP, self.values, item * self.stride_size + + self.start + step * i) + v.append(_v) + if comp_type == 'int': + v = intmask(v) + elif comp_type == 'float': + v = float(v) + elif comp_type == 'complex': + v = [float(v[0]),float(v[1])] + else: + raise NotImplementedError('cannot reach') + return (v, raw_storage_getitem(lltype.Signed, self.indexes, + item * self.index_stride_size + + self.index_start)) + + def setitem(self, idx, item): + if count < 2: + raw_storage_setitem(self.values, idx * self.stride_size + + self.start, rffi.cast(TP, item[0])) + else: + i = 0 + for val in item[0]: + raw_storage_setitem(self.values, idx * self.stride_size + + self.start + i*step, rffi.cast(TP, val)) + i += 1 + raw_storage_setitem(self.indexes, idx * self.index_stride_size + + self.index_start, item[1]) + + class ArgArrayRepWithStorage(Repr): + def __init__(self, index_stride_size, stride_size, size): + start = 0 + dtype = interp_dtype.get_dtype_cache(space).w_longdtype + self.indexes = dtype.itemtype.malloc(size*dtype.get_size()) + self.values = alloc_raw_storage(size * stride_size, + track_allocation=False) + Repr.__init__(self, index_stride_size, stride_size, + size, self.values, self.indexes, start, start) + + def __del__(self): + free_raw_storage(self.indexes, track_allocation=False) + free_raw_storage(self.values, track_allocation=False) + + def arg_getitem(lst, item): + return lst.getitem(item) + + def arg_setitem(lst, item, value): + lst.setitem(item, value) + + def arg_length(lst): + return lst.size + + def arg_getitem_slice(lst, start, stop): + retval = ArgArrayRepWithStorage(lst.index_stride_size, lst.stride_size, + stop-start) + for i in range(stop-start): + retval.setitem(i, lst.getitem(i+start)) + return retval + + if count < 2: + def arg_lt(a, b): + # Does numpy do <= ? + return a[0] < b[0] + else: + def arg_lt(a, b): + for i in range(count): + if a[0][i] < b[0][i]: + return True + elif a[0][i] > b[0][i]: + return False + # Does numpy do True? + return False + + ArgSort = make_timsort_class(arg_getitem, arg_setitem, arg_length, + arg_getitem_slice, arg_lt) + + def argsort(arr, space, w_axis, itemsize): + if w_axis is space.w_None: + # note that it's fine ot pass None here as we're not going + # to pass the result around (None is the link to base in slices) + arr = arr.reshape(space, None, [arr.get_size()]) + axis = 0 + elif w_axis is None: + axis = -1 + else: + axis = space.int_w(w_axis) + # create array of indexes + dtype = interp_dtype.get_dtype_cache(space).w_longdtype + index_arr = W_NDimArray.from_shape(arr.get_shape(), dtype) + storage = index_arr.implementation.get_storage() + if len(arr.get_shape()) == 1: + for i in range(arr.get_size()): + raw_storage_setitem(storage, i * INT_SIZE, i) + r = Repr(INT_SIZE, itemsize, arr.get_size(), arr.get_storage(), + storage, 0, arr.start) + ArgSort(r).sort() + else: + shape = arr.get_shape() + if axis < 0: + axis = len(shape) + axis - 1 + if axis < 0 or axis > len(shape): + raise OperationError(space.w_IndexError, space.wrap( + "Wrong axis %d" % axis)) + iterable_shape = shape[:axis] + [0] + shape[axis + 1:] + iter = AxisIterator(arr, iterable_shape, axis, False) + index_impl = index_arr.implementation + index_iter = AxisIterator(index_impl, iterable_shape, axis, False) + stride_size = arr.strides[axis] + index_stride_size = index_impl.strides[axis] + axis_size = arr.shape[axis] + while not iter.done(): + for i in range(axis_size): + raw_storage_setitem(storage, i * index_stride_size + + index_iter.offset, i) + r = Repr(index_stride_size, stride_size, axis_size, + arr.get_storage(), storage, index_iter.offset, iter.offset) + ArgSort(r).sort() + iter.next() + index_iter.next() + return index_arr + + return argsort + +def argsort_array(arr, space, w_axis): + cache = space.fromcache(SortCache) # that populates SortClasses + itemtype = arr.dtype.itemtype + for tp in all_types: + if isinstance(itemtype, tp[0]): + return cache._lookup(tp)(arr, space, w_axis, + itemtype.get_element_size()) + # XXX this should probably be changed + raise OperationError(space.w_NotImplementedError, + space.wrap("sorting of non-numeric types " + \ + "'%s' is not implemented" % arr.dtype.get_name(), )) + +all_types = (types.all_float_types + types.all_complex_types + + types.all_int_types) +all_types = [i for i in all_types if not '_mixin_' in i[0].__dict__] +all_types = unrolling_iterable(all_types) + +class SortCache(object): + built = False + + def __init__(self, space): + if self.built: + return + self.built = True + cache = {} + for cls, it in all_types._items: + if it == 'complex': + cache[cls] = make_sort_function(space, cls, it, 2) + else: + cache[cls] = make_sort_function(space, cls, it) + self.cache = cache + self._lookup = specialize.memo()(lambda tp : cache[tp[0]]) diff --git a/pypy/module/micronumpy/constants.py b/pypy/module/micronumpy/constants.py new file mode 100644 --- /dev/null +++ b/pypy/module/micronumpy/constants.py @@ -0,0 +1,4 @@ + +MODE_WRAP, MODE_RAISE, MODE_CLIP = range(3) + +MODES = {'wrap': MODE_WRAP, 'raise': MODE_RAISE, 'clip': MODE_CLIP} diff --git a/pypy/module/test_lib_pypy/numpypy/core/test_shape_base.py b/pypy/module/test_lib_pypy/numpypy/core/test_shape_base.py new file mode 100644 --- /dev/null +++ b/pypy/module/test_lib_pypy/numpypy/core/test_shape_base.py @@ -0,0 +1,163 @@ +from pypy.module.micronumpy.test.test_base import BaseNumpyAppTest + + +class AppTestShapeBase(BaseNumpyAppTest): + + def test_atleast_1d(self): + from numpypy import array, array_equal + import numpypy as np + a = np.atleast_1d(1.0) + assert np.array_equal(a, [1.]) + + x = np.arange(9.0).reshape(3, 3) + a = np.atleast_1d(x) + assert np.array_equal(a, [[0., 1., 2.], + [3., 4., 5.], + [6., 7., 8.]]) + assert np.atleast_1d(x) is x + + a = np.atleast_1d(1, [3, 4]) + assert len(a) == 2 + assert array_equal(a[0], [1]) + assert array_equal(a[1], [3, 4]) + + def test_atleast_2d(self): + import numpypy as np + a = np.atleast_2d(3.0) + assert np.array_equal(a, [[3.]]) + + x = np.arange(3.0) + a = np.atleast_2d(x) + assert np.array_equal(a, [[0., 1., 2.]]) + + a = np.atleast_2d(1, [1, 2], [[1, 2]]) + assert len(a) == 3 + assert np.array_equal(a[0], [[1]]) + assert np.array_equal(a[1], [[1, 2]]) + assert np.array_equal(a[2], [[1, 2]]) + + def test_atleast_3d(self): + import numpypy as np + + a = np.atleast_3d(3.0) + assert np.array_equal(a, [[[3.]]]) + + x = np.arange(3.0) + assert np.atleast_3d(x).shape == (1, 3, 1) + + x = np.arange(12.0).reshape(4, 3) + assert np.atleast_3d(x).shape == (4, 3, 1) + + a = np.atleast_3d([1, 2]) + assert np.array_equal(a, [[[1], + [2]]]) + assert a.shape == (1, 2, 1) + + a = np.atleast_3d([[1, 2]]) + assert np.array_equal(a, [[[1], + [2]]]) + assert a.shape == (1, 2, 1) + + a = np.atleast_3d([[[1, 2]]]) + assert np.array_equal(a, [[[1, 2]]]) + assert a.shape == (1, 1, 2) + + def test_vstack(self): + import numpypy as np + + a = np.array([1, 2, 3]) + b = np.array([2, 3, 4]) + c = np.vstack((a, b)) + assert np.array_equal(c, [[1, 2, 3], + [2, 3, 4]]) + + a = np.array([[1], [2], [3]]) + b = np.array([[2], [3], [4]]) + c = np.vstack((a, b)) + assert np.array_equal(c, [[1], + [2], + [3], + [2], + [3], + [4]]) + + for shape1, shape2 in [[(2, 1), (3, 1)], + [(2, 4), [3, 4]]]: + a, b = np.ones(shape1), np.ones(shape2) + assert np.all(np.vstack((a, b)) == + np.ones((a.shape[0] + b.shape[0], + a.shape[1]))) + + #skip("https://bugs.pypy.org/issue1394") + for shape1, shape2 in [[(3, 2, 4), (7, 2, 4)], + [(0, 2, 7), (10, 2, 7)], + [(0, 2, 7), (0, 2, 7)]]: + a, b = np.ones(shape1), np.ones(shape2) + assert np.all(np.vstack((a, b)) == + np.ones((a.shape[0] + b.shape[0], + a.shape[1], + a.shape[2]))) + + def test_hstack(self): + import numpypy as np + a = np.array((1, 2, 3)) + b = np.array((2, 3, 4)) + c = np.hstack((a, b)) + assert np.array_equal(c, [1, 2, 3, 2, 3, 4]) + + a = np.array([[1], [2], [3]]) + b = np.array([[2], [3], [4]]) + c = np.hstack((a, b)) + assert np.array_equal(c, [[1, 2], + [2, 3], + [3, 4]]) + + for shape1, shape2 in [[(1, 2), (1, 3)], + [(4, 2), (4, 3)]]: + a, b = np.ones(shape1), np.ones(shape2) + assert np.all(np.hstack((a, b)) == + np.ones((a.shape[0], + a.shape[1] + b.shape[1]))) + + #skip("https://bugs.pypy.org/issue1394") + for shape1, shape2 in [[(2, 3, 4), (2, 7, 4)], + [(1, 4, 7), (1, 10, 7)], + [(1, 4, 7), (1, 0, 7)], + [(1, 0, 7), (1, 0, 7)]]: + a, b = np.ones(shape1), np.ones(shape2) + assert np.all(np.hstack((a, b)) == + np.ones((a.shape[0], + a.shape[1] + b.shape[1], + a.shape[2]))) + + def test_dstack(self): + import numpypy as np + a = np.array((1, 2, 3)) + b = np.array((2, 3, 4)) + c = np.dstack((a, b)) + assert np.array_equal(c, [[[1, 2], [2, 3], [3, 4]]]) + + a = np.array([[1], [2], [3]]) + b = np.array([[2], [3], [4]]) + c = np.dstack((a, b)) + assert np.array_equal(c, [[[1, 2]], [[2, 3]], [[3, 4]]]) + + #skip("https://bugs.pypy.org/issue1394") + for shape1, shape2 in [[(4, 2, 3), (4, 2, 7)], + [(7, 2, 0), (7, 2, 10)], + [(7, 2, 0), (7, 2, 0)]]: + a, b = np.ones(shape1), np.ones(shape2) + assert np.all(np.dstack((a, b)) == + np.ones((a.shape[0], + a.shape[1], + a.shape[2] + b.shape[2]))) + + for shape1, shape2 in [[(4, 2, 3, 5), (4, 2, 7, 5)], + [(7, 2, 0, 5), (7, 2, 10, 5)], + [(7, 2, 0, 5), (7, 2, 0, 5)]]: + a, b = np.ones(shape1), np.ones(shape2) + assert np.all(np.dstack((a, b)) == + np.ones((a.shape[0], + a.shape[1], + a.shape[2] + b.shape[2], + a.shape[3]))) diff --git a/pypy/module/test_lib_pypy/pyrepl/test_keymap.py b/pypy/module/test_lib_pypy/pyrepl/test_keymap.py new file mode 100644 --- /dev/null +++ b/pypy/module/test_lib_pypy/pyrepl/test_keymap.py @@ -0,0 +1,10 @@ +from pyrepl.keymap import compile_keymap + + +def test_compile_keymap(): + k = compile_keymap({ + b'a': 'test', + b'bc': 'test2', + }) + + assert k == {b'a': 'test', b'b': {b'c': 'test2'}} diff --git a/pypy/module/test_lib_pypy/pyrepl/test_readline.py b/pypy/module/test_lib_pypy/pyrepl/test_readline.py new file mode 100644 --- /dev/null +++ b/pypy/module/test_lib_pypy/pyrepl/test_readline.py @@ -0,0 +1,15 @@ +from pyrepl.readline import _ReadlineWrapper +import os +import pty + + +def test_raw_input(): + master, slave = pty.openpty() + readline_wrapper = _ReadlineWrapper(slave, slave) + os.write(master, b'input\n') + + result = readline_wrapper.get_reader().readline() + #result = readline_wrapper.raw_input('prompt:') + assert result == 'input' + # A bytes string on python2, a unicode string on python3. + assert isinstance(result, str) diff --git a/pypy/sandbox/__init__.py b/pypy/sandbox/__init__.py new file mode 100644 --- /dev/null +++ b/pypy/sandbox/__init__.py @@ -0,0 +1,1 @@ +# empty \ No newline at end of file From noreply at buildbot.pypy.org Tue Feb 12 12:20:13 2013 From: noreply at buildbot.pypy.org (fijal) Date: Tue, 12 Feb 2013 12:20:13 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: more 32bit fixes Message-ID: <20130212112013.C25CB1C0253@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61128:99028fa539f2 Date: 2013-02-12 13:19 +0200 http://bitbucket.org/pypy/pypy/changeset/99028fa539f2/ Log: more 32bit fixes diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -248,12 +248,15 @@ # XXX investigate if we need to save callee-saved registers # on the frame mc.SUB_rr(edi.value, eax.value) # compute the size we want - assert not IS_X86_32 # the arg is already in edi - if hasattr(self.cpu.gc_ll_descr, 'passes_frame'): + mc.SUB_ri(esp.value, 16 - WORD) + if IS_X86_32: + mc.MOV_sr(0, edi.value) + if hasattr(self.cpu.gc_ll_descr, 'passes_frame'): + mc.MOV_sr(WORD, ebp.value) + elif hasattr(self.cpu.gc_ll_descr, 'passes_frame'): # for tests only mc.MOV_rr(esi.value, ebp.value) - mc.SUB_ri(esp.value, 16 - WORD) mc.CALL(imm(addr)) mc.ADD_ri(esp.value, 16 - WORD) mc.TEST_rr(eax.value, eax.value) From noreply at buildbot.pypy.org Tue Feb 12 12:24:16 2013 From: noreply at buildbot.pypy.org (fijal) Date: Tue, 12 Feb 2013 12:24:16 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: fix those tests Message-ID: <20130212112416.B0A941C0253@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61129:b0c9765f3558 Date: 2013-02-12 13:23 +0200 http://bitbucket.org/pypy/pypy/changeset/b0c9765f3558/ Log: fix those tests diff --git a/rpython/jit/backend/x86/test/test_gc_integration.py b/rpython/jit/backend/x86/test/test_gc_integration.py --- a/rpython/jit/backend/x86/test/test_gc_integration.py +++ b/rpython/jit/backend/x86/test/test_gc_integration.py @@ -233,7 +233,10 @@ def test_malloc_slowpath(self): def check(frame): assert len(frame.jf_gcmap) == 1 - assert frame.jf_gcmap[0] == (1<<29) | (1 << 30) + if IS_X86_64: + assert frame.jf_gcmap[0] == (1<<29) | (1 << 30) + else: + assert frame.jf_gcmap[0] == (1<<24) | (1 << 23) self.cpu = self.getcpu(check) ops = ''' @@ -260,9 +263,14 @@ def test_save_regs_around_malloc(self): def check(frame): x = frame.jf_gcmap - assert len(x) == 1 - assert (bin(x[0]).count('1') == - '0b1111100000000000000001111111011110'.count('1')) + if IS_X86_64: + assert len(x) == 1 + assert (bin(x[0]).count('1') == + '0b1111100000000000000001111111011110'.count('1')) + else: + assert len(x) == 2 + s = bin(x[0]).count('1') + bin(x[1]).count('1') + assert s == 16 # all but two registers + some stuff on stack self.cpu = self.getcpu(check) From noreply at buildbot.pypy.org Tue Feb 12 12:30:06 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Tue, 12 Feb 2013 12:30:06 +0100 (CET) Subject: [pypy-commit] pypy default: actually backout dcc4f89c3872 Message-ID: <20130212113006.87A7D1C0253@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61130:935bd2f2584b Date: 2013-02-12 06:29 -0500 http://bitbucket.org/pypy/pypy/changeset/935bd2f2584b/ Log: actually backout dcc4f89c3872 From noreply at buildbot.pypy.org Tue Feb 12 12:41:55 2013 From: noreply at buildbot.pypy.org (fijal) Date: Tue, 12 Feb 2013 12:41:55 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: We now keep the frame in ebp, easy Message-ID: <20130212114155.B8F571C0253@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61131:7db4696a951c Date: 2013-02-12 13:41 +0200 http://bitbucket.org/pypy/pypy/changeset/7db4696a951c/ Log: We now keep the frame in ebp, easy diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -877,7 +877,7 @@ # to provide a place where we can read the frame from, in case # we need to reload it after a collection rst = self._load_shadowstack_top_in_ebx(self.mc, gcrootmap) - self.mc.MOV_mr((ebx.value, 0), edi.value) # MOV [ebx], edi + self.mc.MOV_mr((ebx.value, 0), ebp.value) # MOV [ebx], ebp self.mc.ADD_ri(ebx.value, WORD) if rx86.fits_in_32bits(rst): self.mc.MOV_jr(rst, ebx.value) # MOV [rootstacktop], ebx diff --git a/rpython/jit/backend/x86/test/test_gc_integration.py b/rpython/jit/backend/x86/test/test_gc_integration.py --- a/rpython/jit/backend/x86/test/test_gc_integration.py +++ b/rpython/jit/backend/x86/test/test_gc_integration.py @@ -548,7 +548,7 @@ loop = self.parse(""" [p0, p1, p2] - pf = force_token() # this is a bit below the frame + pf = force_token() # this is the frame call(ConstClass(check_adr), pf, descr=checkdescr) # this can collect p3 = getfield_gc(p0, descr=fielddescr) pf2 = force_token() From noreply at buildbot.pypy.org Tue Feb 12 12:44:36 2013 From: noreply at buildbot.pypy.org (fijal) Date: Tue, 12 Feb 2013 12:44:36 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: fix the last gc_integration test Message-ID: <20130212114436.CA5341C0253@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61132:094a1cda58d3 Date: 2013-02-12 13:43 +0200 http://bitbucket.org/pypy/pypy/changeset/094a1cda58d3/ Log: fix the last gc_integration test diff --git a/rpython/jit/backend/x86/test/test_gc_integration.py b/rpython/jit/backend/x86/test/test_gc_integration.py --- a/rpython/jit/backend/x86/test/test_gc_integration.py +++ b/rpython/jit/backend/x86/test/test_gc_integration.py @@ -527,7 +527,10 @@ frames.append(frame) new_frame = JITFRAME.allocate(frame.jf_frame_info) gcmap = unpack_gcmap(frame) - assert gcmap == [28, 29, 30] + if IS_X86_64: + assert gcmap == [28, 29, 30] + else: + assert gcmap == [22, 23, 24] for item, s in zip(gcmap, new_items): new_frame.jf_frame[item] = rffi.cast(lltype.Signed, s) assert cpu.gc_ll_descr.gcrootmap.stack[0] == rffi.cast(lltype.Signed, frame) From noreply at buildbot.pypy.org Tue Feb 12 14:07:32 2013 From: noreply at buildbot.pypy.org (kostialopuhin) Date: Tue, 12 Feb 2013 14:07:32 +0100 (CET) Subject: [pypy-commit] pypy unquote-faster: fix quadratic slowness of unquote (caused by buliding string with inplace addition) Message-ID: <20130212130732.0D9261C11CF@cobra.cs.uni-duesseldorf.de> Author: Konstantin Lopuhin Branch: unquote-faster Changeset: r61133:f505dfc8c778 Date: 2013-02-12 16:09 +0400 http://bitbucket.org/pypy/pypy/changeset/f505dfc8c778/ Log: fix quadratic slowness of unquote (caused by buliding string with inplace addition) diff --git a/lib-python/2.7/urllib.py b/lib-python/2.7/urllib.py --- a/lib-python/2.7/urllib.py +++ b/lib-python/2.7/urllib.py @@ -1205,15 +1205,16 @@ # fastpath if len(res) == 1: return s - s = res[0] + res_list = [res[0]] for item in res[1:]: try: - s += _hextochr[item[:2]] + item[2:] + x = _hextochr[item[:2]] + item[2:] except KeyError: - s += '%' + item + x = '%' + item except UnicodeDecodeError: - s += unichr(int(item[:2], 16)) + item[2:] - return s + x = unichr(int(item[:2], 16)) + item[2:] + res_list.append(x) + return ''.join(res_list) def unquote_plus(s): """unquote('%7e/abc+def') -> '~/abc def'""" diff --git a/lib-python/2.7/urlparse.py b/lib-python/2.7/urlparse.py --- a/lib-python/2.7/urlparse.py +++ b/lib-python/2.7/urlparse.py @@ -321,15 +321,16 @@ # fastpath if len(res) == 1: return s - s = res[0] + res_list = [res[0]] for item in res[1:]: try: - s += _hextochr[item[:2]] + item[2:] + x = _hextochr[item[:2]] + item[2:] except KeyError: - s += '%' + item + x = '%' + item except UnicodeDecodeError: - s += unichr(int(item[:2], 16)) + item[2:] - return s + x = unichr(int(item[:2], 16)) + item[2:] + res_list.append(x) + return ''.join(res_list) def parse_qs(qs, keep_blank_values=0, strict_parsing=0): """Parse a query given as a string argument. From noreply at buildbot.pypy.org Tue Feb 12 14:07:33 2013 From: noreply at buildbot.pypy.org (kostialopuhin) Date: Tue, 12 Feb 2013 14:07:33 +0100 (CET) Subject: [pypy-commit] pypy unquote-faster: avoid extra copy Message-ID: <20130212130733.2DEF61C11D1@cobra.cs.uni-duesseldorf.de> Author: Konstantin Lopuhin Branch: unquote-faster Changeset: r61134:134dddef38b4 Date: 2013-02-12 17:01 +0400 http://bitbucket.org/pypy/pypy/changeset/134dddef38b4/ Log: avoid extra copy diff --git a/lib-python/2.7/urllib.py b/lib-python/2.7/urllib.py --- a/lib-python/2.7/urllib.py +++ b/lib-python/2.7/urllib.py @@ -1206,7 +1206,8 @@ if len(res) == 1: return s res_list = [res[0]] - for item in res[1:]: + for j in xrange(1, len(res)): + item = res[j] try: x = _hextochr[item[:2]] + item[2:] except KeyError: diff --git a/lib-python/2.7/urlparse.py b/lib-python/2.7/urlparse.py --- a/lib-python/2.7/urlparse.py +++ b/lib-python/2.7/urlparse.py @@ -322,7 +322,8 @@ if len(res) == 1: return s res_list = [res[0]] - for item in res[1:]: + for j in xrange(1, len(res)): + item = res[j] try: x = _hextochr[item[:2]] + item[2:] except KeyError: From noreply at buildbot.pypy.org Tue Feb 12 14:07:34 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Tue, 12 Feb 2013 14:07:34 +0100 (CET) Subject: [pypy-commit] pypy default: Merged in kostialopuhin/pypy/unquote-faster (pull request #119) Message-ID: <20130212130734.682C01C11CF@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61135:46fb234140b9 Date: 2013-02-12 05:07 -0800 http://bitbucket.org/pypy/pypy/changeset/46fb234140b9/ Log: Merged in kostialopuhin/pypy/unquote-faster (pull request #119) Make unquote from urllib and urlparse faster diff --git a/lib-python/2.7/urllib.py b/lib-python/2.7/urllib.py --- a/lib-python/2.7/urllib.py +++ b/lib-python/2.7/urllib.py @@ -1205,15 +1205,17 @@ # fastpath if len(res) == 1: return s - s = res[0] - for item in res[1:]: + res_list = [res[0]] + for j in xrange(1, len(res)): + item = res[j] try: - s += _hextochr[item[:2]] + item[2:] + x = _hextochr[item[:2]] + item[2:] except KeyError: - s += '%' + item + x = '%' + item except UnicodeDecodeError: - s += unichr(int(item[:2], 16)) + item[2:] - return s + x = unichr(int(item[:2], 16)) + item[2:] + res_list.append(x) + return ''.join(res_list) def unquote_plus(s): """unquote('%7e/abc+def') -> '~/abc def'""" diff --git a/lib-python/2.7/urlparse.py b/lib-python/2.7/urlparse.py --- a/lib-python/2.7/urlparse.py +++ b/lib-python/2.7/urlparse.py @@ -321,15 +321,17 @@ # fastpath if len(res) == 1: return s - s = res[0] - for item in res[1:]: + res_list = [res[0]] + for j in xrange(1, len(res)): + item = res[j] try: - s += _hextochr[item[:2]] + item[2:] + x = _hextochr[item[:2]] + item[2:] except KeyError: - s += '%' + item + x = '%' + item except UnicodeDecodeError: - s += unichr(int(item[:2], 16)) + item[2:] - return s + x = unichr(int(item[:2], 16)) + item[2:] + res_list.append(x) + return ''.join(res_list) def parse_qs(qs, keep_blank_values=0, strict_parsing=0): """Parse a query given as a string argument. From noreply at buildbot.pypy.org Tue Feb 12 16:11:18 2013 From: noreply at buildbot.pypy.org (mattip) Date: Tue, 12 Feb 2013 16:11:18 +0100 (CET) Subject: [pypy-commit] pypy default: test, fix missing dtype in coerce Message-ID: <20130212151118.5898B1C1047@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: Changeset: r61136:78737ede9909 Date: 2013-02-12 17:09 +0200 http://bitbucket.org/pypy/pypy/changeset/78737ede9909/ Log: test, fix missing dtype in coerce diff --git a/pypy/module/micronumpy/test/test_numarray.py b/pypy/module/micronumpy/test/test_numarray.py --- a/pypy/module/micronumpy/test/test_numarray.py +++ b/pypy/module/micronumpy/test/test_numarray.py @@ -1666,6 +1666,9 @@ a = arange(6, dtype='f4').reshape(2,3) b = a.astype('i4') + a = array('x').astype('S3').dtype + assert a.itemsize == 3 + def test_base(self): from _numpypy import array assert array(1).base is None diff --git a/pypy/module/micronumpy/types.py b/pypy/module/micronumpy/types.py --- a/pypy/module/micronumpy/types.py +++ b/pypy/module/micronumpy/types.py @@ -1603,7 +1603,7 @@ arr = interp_boxes.VoidBoxStorage(len(arg), new_string_dtype(space, len(arg))) for i in range(len(arg)): arr.storage[i] = arg[i] - return interp_boxes.W_StringBox(arr, 0, None) + return interp_boxes.W_StringBox(arr, 0, arg.dtype) @jit.unroll_safe def store(self, arr, i, offset, box): From noreply at buildbot.pypy.org Tue Feb 12 16:28:02 2013 From: noreply at buildbot.pypy.org (mattip) Date: Tue, 12 Feb 2013 16:28:02 +0100 (CET) Subject: [pypy-commit] pypy default: typo Message-ID: <20130212152802.0FDE01C1047@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: Changeset: r61137:24d0ce574830 Date: 2013-02-12 17:25 +0200 http://bitbucket.org/pypy/pypy/changeset/24d0ce574830/ Log: typo diff --git a/pypy/module/micronumpy/types.py b/pypy/module/micronumpy/types.py --- a/pypy/module/micronumpy/types.py +++ b/pypy/module/micronumpy/types.py @@ -1603,7 +1603,7 @@ arr = interp_boxes.VoidBoxStorage(len(arg), new_string_dtype(space, len(arg))) for i in range(len(arg)): arr.storage[i] = arg[i] - return interp_boxes.W_StringBox(arr, 0, arg.dtype) + return interp_boxes.W_StringBox(arr, 0, arr.dtype) @jit.unroll_safe def store(self, arr, i, offset, box): From noreply at buildbot.pypy.org Tue Feb 12 16:39:13 2013 From: noreply at buildbot.pypy.org (fijal) Date: Tue, 12 Feb 2013 16:39:13 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: er, I'm a moron Message-ID: <20130212153913.52FCF1C1047@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61138:ad46b2046728 Date: 2013-02-12 17:38 +0200 http://bitbucket.org/pypy/pypy/changeset/ad46b2046728/ Log: er, I'm a moron diff --git a/rpython/jit/backend/llsupport/jitframe.py b/rpython/jit/backend/llsupport/jitframe.py --- a/rpython/jit/backend/llsupport/jitframe.py +++ b/rpython/jit/backend/llsupport/jitframe.py @@ -5,7 +5,7 @@ from rpython.rlib.objectmodel import enforceargs SIZEOFSIGNED = rffi.sizeof(lltype.Signed) -IS_32BIT = (SIZEOFSIGNED == 2 ** 31 - 1) +IS_32BIT = (SIZEOFSIGNED == 4) # this is an info that only depends on the assembler executed, copied from # compiled loop token (in fact we could use this as a compiled loop token From noreply at buildbot.pypy.org Tue Feb 12 16:49:30 2013 From: noreply at buildbot.pypy.org (fijal) Date: Tue, 12 Feb 2013 16:49:30 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: missing import Message-ID: <20130212154930.10EB41C1198@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61139:af14ec8e43fc Date: 2013-02-12 17:48 +0200 http://bitbucket.org/pypy/pypy/changeset/af14ec8e43fc/ Log: missing import diff --git a/rpython/jit/backend/x86/test/test_zrpy_gc_boehm.py b/rpython/jit/backend/x86/test/test_zrpy_gc_boehm.py --- a/rpython/jit/backend/x86/test/test_zrpy_gc_boehm.py +++ b/rpython/jit/backend/x86/test/test_zrpy_gc_boehm.py @@ -1,7 +1,7 @@ import weakref from rpython.rlib.jit import JitDriver, dont_look_inside -from rpython.jit.backend.x86.test.test_zrpy_gc import run, get_entry +from rpython.jit.backend.x86.test.test_zrpy_gc import run, get_entry, compile class X(object): def __init__(self, x=0): From noreply at buildbot.pypy.org Tue Feb 12 17:12:31 2013 From: noreply at buildbot.pypy.org (fijal) Date: Tue, 12 Feb 2013 17:12:31 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: oops Message-ID: <20130212161231.7E4391C1198@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61141:e11d4dff507d Date: 2013-02-12 18:11 +0200 http://bitbucket.org/pypy/pypy/changeset/e11d4dff507d/ Log: oops diff --git a/rpython/jit/backend/arm/test/test_runner.py b/rpython/jit/backend/arm/test/test_runner.py --- a/rpython/jit/backend/arm/test/test_runner.py +++ b/rpython/jit/backend/arm/test/test_runner.py @@ -57,7 +57,7 @@ ResOperation(rop.GUARD_FALSE, [inp[1]], None, descr=BasicFailDescr(1)), ResOperation(rop.FINISH, [inp[1]], None, descr=BasicFinalDescr(1)), ] - operations[-1].setfailargs(out) + operations[-2].setfailargs(out) cpu.compile_loop(inp, operations, looptoken) args = [i for i in range(1, 15)] deadframe = self.cpu.execute_token(looptoken, *args) From noreply at buildbot.pypy.org Tue Feb 12 17:11:09 2013 From: noreply at buildbot.pypy.org (fijal) Date: Tue, 12 Feb 2013 17:11:09 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: rewrite this test Message-ID: <20130212161109.683EF1C1198@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61140:8c534cd20ab5 Date: 2013-02-12 18:10 +0200 http://bitbucket.org/pypy/pypy/changeset/8c534cd20ab5/ Log: rewrite this test diff --git a/rpython/jit/backend/arm/test/test_runner.py b/rpython/jit/backend/arm/test/test_runner.py --- a/rpython/jit/backend/arm/test/test_runner.py +++ b/rpython/jit/backend/arm/test/test_runner.py @@ -1,12 +1,9 @@ import py from rpython.jit.backend.detect_cpu import getcpuclass -from rpython.jit.backend.arm.arch import WORD -from rpython.jit.backend.test.runner_test import LLtypeBackendTest, \ - boxfloat, \ - constfloat -from rpython.jit.metainterp.history import (BasicFailDescr, - BoxInt, - ConstInt) +from rpython.jit.backend.test.runner_test import LLtypeBackendTest,\ + boxfloat, constfloat +from rpython.jit.metainterp.history import (BasicFailDescr, BasicFinalDescr, + BoxInt) from rpython.jit.metainterp.resoperation import ResOperation, rop from rpython.jit.tool.oparser import parse from rpython.rtyper.lltypesystem import lltype, llmemory, rclass @@ -57,8 +54,10 @@ ResOperation(rop.INT_ADD, [inp[8], inp[9]], out[11]), ResOperation(rop.INT_ADD, [inp[10], inp[11]], out[12]), ResOperation(rop.INT_ADD, [inp[12], inp[13]], out[13]), - ResOperation(rop.FINISH, out, None, descr=BasicFailDescr(1)), + ResOperation(rop.GUARD_FALSE, [inp[1]], None, descr=BasicFailDescr(1)), + ResOperation(rop.FINISH, [inp[1]], None, descr=BasicFinalDescr(1)), ] + operations[-1].setfailargs(out) cpu.compile_loop(inp, operations, looptoken) args = [i for i in range(1, 15)] deadframe = self.cpu.execute_token(looptoken, *args) From noreply at buildbot.pypy.org Tue Feb 12 17:30:57 2013 From: noreply at buildbot.pypy.org (fijal) Date: Tue, 12 Feb 2013 17:30:57 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: a historical commit - start sharing code between arm and x86 Message-ID: <20130212163057.A7CFA1C11A8@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61143:3c7de3e490d1 Date: 2013-02-12 18:30 +0200 http://bitbucket.org/pypy/pypy/changeset/3c7de3e490d1/ Log: a historical commit - start sharing code between arm and x86 diff --git a/rpython/jit/backend/arm/regalloc.py b/rpython/jit/backend/arm/regalloc.py --- a/rpython/jit/backend/arm/regalloc.py +++ b/rpython/jit/backend/arm/regalloc.py @@ -1,8 +1,8 @@ -from rpython.rtyper.annlowlevel import llhelper, cast_instance_to_gcref +from rpython.rtyper.annlowlevel import cast_instance_to_gcref from rpython.rlib import rgc from rpython.rlib.debug import debug_print, debug_start, debug_stop from rpython.jit.backend.llsupport.regalloc import FrameManager, \ - RegisterManager, TempBox, compute_vars_longevity + RegisterManager, TempBox, compute_vars_longevity, BaseRegalloc from rpython.jit.backend.arm import registers as r from rpython.jit.backend.arm import locations from rpython.jit.backend.arm.locations import imm, get_fp_offset @@ -16,7 +16,7 @@ ) from rpython.jit.backend.arm.jump import remap_frame_layout_mixed from rpython.jit.backend.arm.arch import MY_COPY_OF_REGS -from rpython.jit.backend.arm.arch import WORD, DOUBLE_WORD, JITFRAME_FIXED_SIZE +from rpython.jit.backend.arm.arch import WORD, JITFRAME_FIXED_SIZE from rpython.jit.codewriter import longlong from rpython.jit.metainterp.history import (Const, ConstInt, ConstFloat, ConstPtr, Box, BoxPtr, @@ -32,7 +32,6 @@ from rpython.jit.backend.llsupport.descr import unpack_arraydescr from rpython.jit.backend.llsupport.descr import unpack_fielddescr from rpython.jit.backend.llsupport.descr import unpack_interiorfielddescr -from rpython.rlib.objectmodel import we_are_translated # xxx hack: set a default value for TargetToken._arm_loop_code. If 0, we know @@ -179,7 +178,7 @@ return reg -class Regalloc(object): +class Regalloc(BaseRegalloc): def __init__(self, assembler=None): self.cpu = assembler.cpu @@ -316,12 +315,6 @@ def get_final_frame_depth(self): return self.frame_manager.get_frame_depth() - def _set_initial_bindings(self, inputargs): - # the input args are passed in the jitframe - for box in inputargs: - assert isinstance(box, Box) - self.fm.get_new_loc(box) - def _update_bindings(self, locs, inputargs): used = {} i = 0 diff --git a/rpython/jit/backend/llsupport/regalloc.py b/rpython/jit/backend/llsupport/regalloc.py --- a/rpython/jit/backend/llsupport/regalloc.py +++ b/rpython/jit/backend/llsupport/regalloc.py @@ -627,6 +627,22 @@ """ Platform specific - Allocates a temporary register """ raise NotImplementedError("Abstract") +class BaseRegalloc(object): + """ Base class on which all the backend regallocs should be based + """ + def _set_initial_bindings(self, inputargs, looptoken): + """ Set the bindings at the start of the loop + """ + locs = [] + base_ofs = self.assembler.cpu.get_baseofs_of_frame_field() + for box in inputargs: + assert isinstance(box, Box) + loc = self.fm.get_new_loc(box) + locs.append(loc.value - base_ofs) + if looptoken.compiled_loop_token is not None: + # for tests + looptoken.compiled_loop_token._ll_initial_locs = locs + def compute_vars_longevity(inputargs, operations): # compute a dictionary that maps variables to index in diff --git a/rpython/jit/backend/x86/regalloc.py b/rpython/jit/backend/x86/regalloc.py --- a/rpython/jit/backend/x86/regalloc.py +++ b/rpython/jit/backend/x86/regalloc.py @@ -23,7 +23,7 @@ from rpython.jit.backend.llsupport.descr import unpack_fielddescr from rpython.jit.backend.llsupport.descr import unpack_interiorfielddescr from rpython.jit.backend.llsupport.gcmap import allocate_gcmap -from rpython.jit.backend.llsupport.regalloc import FrameManager,\ +from rpython.jit.backend.llsupport.regalloc import FrameManager, BaseRegalloc,\ RegisterManager, TempBox, compute_vars_longevity, is_comparison_or_ovf_op from rpython.jit.backend.x86.arch import WORD, JITFRAME_FIXED_SIZE from rpython.jit.backend.x86.arch import IS_X86_32, IS_X86_64 @@ -133,7 +133,7 @@ for _i, _reg in enumerate(gpr_reg_mgr_cls.all_regs): gpr_reg_mgr_cls.all_reg_indexes[_reg.value] = _i -class RegAlloc(object): +class RegAlloc(BaseRegalloc): def __init__(self, assembler, translate_support_code=False): assert isinstance(translate_support_code, bool) @@ -188,17 +188,6 @@ def get_final_frame_depth(self): return self.fm.get_frame_depth() - def _set_initial_bindings(self, inputargs, looptoken): - locs = [] - base_ofs = self.assembler.cpu.get_baseofs_of_frame_field() - for box in inputargs: - assert isinstance(box, Box) - loc = self.fm.get_new_loc(box) - locs.append(loc.value - base_ofs) - if looptoken.compiled_loop_token is not None: - # for tests - looptoken.compiled_loop_token._ll_initial_locs = locs - def possibly_free_var(self, var): if var.type == FLOAT: self.xrm.possibly_free_var(var) From noreply at buildbot.pypy.org Tue Feb 12 17:30:56 2013 From: noreply at buildbot.pypy.org (fijal) Date: Tue, 12 Feb 2013 17:30:56 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: finish fixing this test Message-ID: <20130212163056.625281C1198@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61142:932cb78d444f Date: 2013-02-12 18:14 +0200 http://bitbucket.org/pypy/pypy/changeset/932cb78d444f/ Log: finish fixing this test diff --git a/rpython/jit/backend/arm/test/test_runner.py b/rpython/jit/backend/arm/test/test_runner.py --- a/rpython/jit/backend/arm/test/test_runner.py +++ b/rpython/jit/backend/arm/test/test_runner.py @@ -61,7 +61,7 @@ cpu.compile_loop(inp, operations, looptoken) args = [i for i in range(1, 15)] deadframe = self.cpu.execute_token(looptoken, *args) - output = [self.cpu.get_latest_value_int(deadframe, i - 1) for i in range(1, 15)] + output = [self.cpu.get_int_value(deadframe, i - 1) for i in range(1, 15)] expected = [3, 7, 11, 15, 19, 23, 27, 3, 7, 11, 15, 19, 23, 27] assert output == expected From noreply at buildbot.pypy.org Tue Feb 12 20:29:33 2013 From: noreply at buildbot.pypy.org (arigo) Date: Tue, 12 Feb 2013 20:29:33 +0100 (CET) Subject: [pypy-commit] cffi auto-types: An extra test for 'bool'. Message-ID: <20130212192933.200501C1053@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: auto-types Changeset: r1146:c1ea20ec5783 Date: 2013-02-12 16:41 +0100 http://bitbucket.org/cffi/cffi/changeset/c1ea20ec5783/ Log: An extra test for 'bool'. diff --git a/testing/test_verify.py b/testing/test_verify.py --- a/testing/test_verify.py +++ b/testing/test_verify.py @@ -1249,6 +1249,7 @@ for sign in ['signed', 'unsigned']: type = '%s %s' % (sign, basetype) assert int(ffi.cast("_Bool", ffi.cast(type, 42))) == 1 + assert int(ffi.cast("bool", ffi.cast(type, 42))) == 1 assert int(ffi.cast("_Bool", ffi.cast(type, 0))) == 0 def test_addressof(): From noreply at buildbot.pypy.org Tue Feb 12 20:29:34 2013 From: noreply at buildbot.pypy.org (arigo) Date: Tue, 12 Feb 2013 20:29:34 +0100 (CET) Subject: [pypy-commit] cffi enum-as-int: Fix enums to use the same rule as gcc: they are actually not always Message-ID: <20130212192934.816521C1053@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: enum-as-int Changeset: r1147:c0fb2acdd6f7 Date: 2013-02-12 18:14 +0100 http://bitbucket.org/cffi/cffi/changeset/c0fb2acdd6f7/ Log: Fix enums to use the same rule as gcc: they are actually not always 'int', but the first of the following types that fits: 'unsigned int', 'int', 'unsigned long', 'long'. diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c --- a/c/_cffi_backend.c +++ b/c/_cffi_backend.c @@ -823,32 +823,6 @@ return (PyObject *)cd; } -static PyObject *convert_cdata_to_enum_string(CDataObject *cd, int both) -{ - int value; - PyObject *d_key, *d_value; - CTypeDescrObject *ct = cd->c_type; - - assert(ct->ct_flags & CT_IS_ENUM); - value = (int)read_raw_signed_data(cd->c_data, ct->ct_size); - d_key = PyInt_FromLong(value); - if (d_key == NULL) - return NULL; - - d_value = PyDict_GetItem(PyTuple_GET_ITEM(ct->ct_stuff, 1), d_key); - if (d_value != NULL) { - if (both) - d_value = PyText_FromFormat("%d: %s", value, - PyText_AS_UTF8(d_value)); - else - Py_INCREF(d_value); - } - else - d_value = PyObject_Str(d_key); - Py_DECREF(d_key); - return d_value; -} - static CDataObject *_new_casted_primitive(CTypeDescrObject *ct); /*forward*/ static PyObject * @@ -1432,6 +1406,38 @@ static PyObject *cdata_float(CDataObject *cd); /*forward*/ +static PyObject *convert_cdata_to_enum_string(CDataObject *cd, int both) +{ + PyObject *d_key, *d_value; + CTypeDescrObject *ct = cd->c_type; + + assert(ct->ct_flags & CT_IS_ENUM); + d_key = convert_to_object(cd->c_data, ct); + if (d_key == NULL) + return NULL; + + d_value = PyDict_GetItem(PyTuple_GET_ITEM(ct->ct_stuff, 1), d_key); + if (d_value != NULL) { + if (both) { + PyObject *o = PyObject_Str(d_key); + if (o == NULL) + d_value = NULL; + else { + d_value = PyText_FromFormat("%s: %s", + PyText_AS_UTF8(o), + PyText_AS_UTF8(d_value)); + Py_DECREF(o); + } + } + else + Py_INCREF(d_value); + } + else + d_value = PyObject_Str(d_key); + Py_DECREF(d_key); + return d_value; +} + static PyObject *cdata_repr(CDataObject *cd) { char *extra; @@ -3866,8 +3872,7 @@ return -1; } } - if ((ctype->ct_flags & (CT_PRIMITIVE_SIGNED | CT_IS_ENUM)) - == CT_PRIMITIVE_SIGNED) { + if (ctype->ct_flags & CT_PRIMITIVE_SIGNED) { PY_LONG_LONG value; /* It's probably fine to always zero-extend, but you never know: maybe some code somewhere expects a negative @@ -4086,6 +4091,10 @@ CTypeDescrObject *td; Py_ssize_t i, n; struct aligncheck_int { char x; int y; }; + struct aligncheck_long { char x; long y; }; + long smallest_item = 0; + unsigned long largest_item = 0; + int size, flags; if (!PyArg_ParseTuple(args, "sO!O!:new_enum_type", &ename, @@ -4109,6 +4118,7 @@ for (i=n; --i >= 0; ) { long lvalue; + unsigned long ulvalue; PyObject *value = PyTuple_GET_ITEM(enumvalues, i); tmpkey = PyTuple_GET_ITEM(enumerators, i); Py_INCREF(tmpkey); @@ -4132,11 +4142,29 @@ } } lvalue = PyLong_AsLong(value); - if ((lvalue == -1 && PyErr_Occurred()) || lvalue != (int)lvalue) { - PyErr_Format(PyExc_OverflowError, - "enum '%s' declaration for '%s' does not fit an int", - ename, PyText_AS_UTF8(tmpkey)); - goto error; + if (PyErr_Occurred()) { + PyErr_Clear(); + ulvalue = PyLong_AsUnsignedLong(value); + if (PyErr_Occurred()) { + PyErr_Format(PyExc_OverflowError, + "enum '%s' declaration for '%s' does not fit " + "a long or unsigned long", + ename, PyText_AS_UTF8(tmpkey)); + goto error; + } + if (ulvalue > largest_item) + largest_item = ulvalue; + } + else { + if (lvalue < 0) { + if (lvalue < smallest_item) + smallest_item = lvalue; + } + else { + ulvalue = (unsigned long)lvalue; + if (ulvalue > largest_item) + largest_item = ulvalue; + } } if (PyDict_SetItem(dict1, tmpkey, value) < 0) goto error; @@ -4146,6 +4174,32 @@ tmpkey = NULL; } + if (smallest_item < 0) { + flags = CT_PRIMITIVE_SIGNED | CT_PRIMITIVE_FITS_LONG | CT_IS_ENUM; + if (smallest_item == (int)smallest_item && + largest_item <= (unsigned long)INT_MAX) { + size = sizeof(int); + } + else if (largest_item <= (unsigned long)LONG_MAX) { + size = sizeof(long); + } + else { + PyErr_Format(PyExc_OverflowError, + "enum '%s' values don't all fit into either 'long' " + "or 'unsigned long'", ename); + goto error; + } + } + else if (sizeof(unsigned int) < sizeof(unsigned long) && + largest_item == (unsigned int)largest_item) { + flags = CT_PRIMITIVE_UNSIGNED | CT_PRIMITIVE_FITS_LONG | CT_IS_ENUM; + size = sizeof(unsigned int); + } + else { + flags = CT_PRIMITIVE_UNSIGNED | CT_IS_ENUM; + size = sizeof(unsigned long); + } + combined = PyTuple_Pack(2, dict1, dict2); if (combined == NULL) goto error; @@ -4153,10 +4207,10 @@ Py_CLEAR(dict2); Py_CLEAR(dict1); - switch (sizeof(int)) { + switch (size) { case 4: ffitype = &ffi_type_sint32; break; case 8: ffitype = &ffi_type_sint64; break; - default: Py_FatalError("'int' is not 4 or 8 bytes"); + default: Py_FatalError("'int' or 'long' is not 4 or 8 bytes"); return NULL; } name_size = strlen("enum ") + strlen(ename) + 1; @@ -4167,10 +4221,11 @@ memcpy(td->ct_name, "enum ", strlen("enum ")); memcpy(td->ct_name + strlen("enum "), ename, name_size - strlen("enum ")); td->ct_stuff = combined; - td->ct_size = sizeof(int); - td->ct_length = offsetof(struct aligncheck_int, y); + td->ct_size = size; + td->ct_length = size == sizeof(int) ? offsetof(struct aligncheck_int, y) + : offsetof(struct aligncheck_long, y); td->ct_extra = ffitype; - td->ct_flags = CT_PRIMITIVE_SIGNED | CT_PRIMITIVE_FITS_LONG | CT_IS_ENUM; + td->ct_flags = flags; td->ct_name_position = name_size - 1; return (PyObject *)td; diff --git a/c/test_c.py b/c/test_c.py --- a/c/test_c.py +++ b/c/test_c.py @@ -1301,6 +1301,10 @@ assert int(cast(BEnum, 0)) == 0 assert int(cast(BEnum, -242 + 2**128)) == -242 assert string(cast(BEnum, -242 + 2**128)) == '-242' + # + BEnum = new_enum_type("bar", ('def', 'c', 'ab'), (0, 1, 20)) + e = cast(BEnum, -1) + assert repr(e) == "" # unsigned int def test_enum_with_non_injective_mapping(): BEnum = new_enum_type("foo", ('ab', 'cd'), (7, 7)) @@ -1326,11 +1330,66 @@ assert type(string(cast(BEnum2, 5))) is str def test_enum_overflow(): - for ovf in (2**63, -2**63-1, 2**31, -2**31-1): - e = py.test.raises(OverflowError, new_enum_type, "foo", ('a', 'b'), - (5, ovf)) - assert str(e.value) == ( - "enum 'foo' declaration for 'b' does not fit an int") + max_uint = 2 ** (size_of_int()*8) - 1 + max_int = max_uint // 2 + max_ulong = 2 ** (size_of_long()*8) - 1 + max_long = max_ulong // 2 + # 'unsigned int' case + e = new_enum_type("foo", ('a', 'b'), (0, 3)) + assert sizeof(e) == size_of_int() + assert int(cast(e, -1)) == max_uint # 'e' is unsigned + e = new_enum_type("foo", ('a', 'b'), (0, max_uint)) + assert sizeof(e) == size_of_int() + assert int(cast(e, -1)) == max_uint + assert e.elements == {0: 'a', max_uint: 'b'} + assert e.relements == {'a': 0, 'b': max_uint} + # 'signed int' case + e = new_enum_type("foo", ('a', 'b'), (-1, max_int)) + assert sizeof(e) == size_of_int() + assert int(cast(e, -1)) == -1 + assert e.elements == {-1: 'a', max_int: 'b'} + assert e.relements == {'a': -1, 'b': max_int} + e = new_enum_type("foo", ('a', 'b'), (-max_int-1, max_int)) + assert sizeof(e) == size_of_int() + assert int(cast(e, -1)) == -1 + assert e.elements == {-max_int-1: 'a', max_int: 'b'} + assert e.relements == {'a': -max_int-1, 'b': max_int} + # 'unsigned long' case + e = new_enum_type("foo", ('a', 'b'), (0, max_long)) + assert sizeof(e) == size_of_long() + assert int(cast(e, -1)) == max_ulong # 'e' is unsigned + e = new_enum_type("foo", ('a', 'b'), (0, max_ulong)) + assert sizeof(e) == size_of_long() + assert int(cast(e, -1)) == max_ulong + assert e.elements == {0: 'a', max_ulong: 'b'} + assert e.relements == {'a': 0, 'b': max_ulong} + # 'signed long' case + e = new_enum_type("foo", ('a', 'b'), (-1, max_long)) + assert sizeof(e) == size_of_long() + assert int(cast(e, -1)) == -1 + assert e.elements == {-1: 'a', max_long: 'b'} + assert e.relements == {'a': -1, 'b': max_long} + e = new_enum_type("foo", ('a', 'b'), (-max_long-1, max_long)) + assert sizeof(e) == size_of_long() + assert int(cast(e, -1)) == -1 + assert e.elements == {-max_long-1: 'a', max_long: 'b'} + assert e.relements == {'a': -max_long-1, 'b': max_long} + # overflow: both negative items and items larger than max_long + e = py.test.raises(OverflowError, new_enum_type, "foo", ('a', 'b'), + (-1, max_long + 1)) + assert str(e.value) == ( + "enum 'foo' values don't all fit into either 'long' " + "or 'unsigned long'") + # overflow: items smaller than -max_long-1 + e = py.test.raises(OverflowError, new_enum_type, "foo", ('a', 'b'), + (-max_long-2, 5)) + assert str(e.value) == ( + "enum 'foo' declaration for 'a' does not fit a long or unsigned long") + # overflow: items larger than max_ulong + e = py.test.raises(OverflowError, new_enum_type, "foo", ('a', 'b'), + (5, max_ulong+1)) + assert str(e.value) == ( + "enum 'foo' declaration for 'b' does not fit a long or unsigned long") def test_callback_returning_enum(): BInt = new_primitive_type("int") @@ -1348,6 +1407,23 @@ assert f(20) == 20 assert f(21) == 21 +def test_callback_returning_enum_unsigned(): + BInt = new_primitive_type("int") + BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, 20)) + def cb(n): + print n + if n & 1: + return cast(BEnum, n) + else: + return n + BFunc = new_function_type((BInt,), BEnum) + f = callback(BFunc, cb) + assert f(0) == 0 + assert f(1) == 1 + assert f(-21) == 2**32 - 21 + assert f(20) == 20 + assert f(21) == 21 + def test_callback_returning_char(): BInt = new_primitive_type("int") BChar = new_primitive_type("char") diff --git a/cffi/backend_ctypes.py b/cffi/backend_ctypes.py --- a/cffi/backend_ctypes.py +++ b/cffi/backend_ctypes.py @@ -928,7 +928,23 @@ assert isinstance(name, str) reverse_mapping = dict(zip(reversed(enumvalues), reversed(enumerators))) - CTypesInt = self.ffi._get_cached_btype(model.PrimitiveType('int')) + smallest = min(enumvalues or [0]) + largest = max(enumvalues or [0]) + if smallest < 0: + if largest == ctypes.c_int(largest).value: + tp = 'int' + elif largest == ctypes.c_long(largest).value: + tp = 'long' + else: + raise OverflowError + else: + if largest == ctypes.c_uint(largest).value: + tp = 'unsigned int' + elif largest == ctypes.c_ulong(largest).value: + tp = 'unsigned long' + else: + raise OverflowError + CTypesInt = self.ffi._get_cached_btype(model.PrimitiveType(tp)) # class CTypesEnum(CTypesInt): __slots__ = [] diff --git a/testing/backend_tests.py b/testing/backend_tests.py --- a/testing/backend_tests.py +++ b/testing/backend_tests.py @@ -873,6 +873,8 @@ assert ffi.cast("enum foo", 0) != ffi.cast("enum bar", 0) assert ffi.cast("enum bar", 0) != ffi.cast("int", 0) assert repr(ffi.cast("enum bar", -1)) == "" + assert repr(ffi.cast("enum foo", -1)) == ( # enums are unsigned, if + "") # they contain no neg value ffi.cdef("enum baz { A=0x1000, B=0x2000 };") assert ffi.string(ffi.cast("enum baz", 0x1000)) == "A" assert ffi.string(ffi.cast("enum baz", 0x2000)) == "B" @@ -890,10 +892,11 @@ assert s.e == 2 assert s[0].e == 2 s.e = ffi.cast("enum foo", -1) - assert s.e == -1 - assert s[0].e == -1 + assert s.e == 4294967295 + assert s[0].e == 4294967295 s.e = s.e py.test.raises(TypeError, "s.e = 'B'") + py.test.raises(TypeError, "s.e = '2'") py.test.raises(TypeError, "s.e = '#2'") py.test.raises(TypeError, "s.e = '#7'") From noreply at buildbot.pypy.org Tue Feb 12 20:29:35 2013 From: noreply at buildbot.pypy.org (arigo) Date: Tue, 12 Feb 2013 20:29:35 +0100 (CET) Subject: [pypy-commit] cffi enum-as-int: Document Message-ID: <20130212192935.B80C91C1053@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: enum-as-int Changeset: r1148:affd8586b17f Date: 2013-02-12 18:18 +0100 http://bitbucket.org/cffi/cffi/changeset/affd8586b17f/ Log: Document diff --git a/doc/source/index.rst b/doc/source/index.rst --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -1194,15 +1194,16 @@ length 0, allocating a ``char[]`` of the correct size, and casting it to a struct pointer) -* Enum types are always ``int``. GCC supports enums containing - larger constants (``unsigned int``, or ``long long``) as an extension - to the C standard, but CFFI does not. Use - ``typedef my_enum;`` and then some ``#define foo ``. - .. versionadded:: 0.4 Now supported: the common GCC extension of anonymous nested structs/unions inside structs/unions. +.. versionadded:: 0.6 + Enum types follow the GCC rules: they are defined as the first of + ``unsigned int``, ``int``, ``unsigned long`` or ``long`` that fits + all numeric values. Note that the first choice is unsigned. In CFFI + 0.5 and before, it was always ``int``. + Debugging dlopen'ed C libraries ------------------------------- From noreply at buildbot.pypy.org Tue Feb 12 20:29:36 2013 From: noreply at buildbot.pypy.org (arigo) Date: Tue, 12 Feb 2013 20:29:36 +0100 (CET) Subject: [pypy-commit] cffi default: hg merge slicing Message-ID: <20130212192936.DE10E1C1053@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r1149:62db8ccc85d2 Date: 2013-02-12 18:19 +0100 http://bitbucket.org/cffi/cffi/changeset/62db8ccc85d2/ Log: hg merge slicing diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c --- a/c/_cffi_backend.c +++ b/c/_cffi_backend.c @@ -102,7 +102,8 @@ PyObject *ct_stuff; /* structs: dict of the fields arrays: ctypedescr of the ptr type function: tuple(abi, ctres, ctargs..) - enum: pair {"name":x},{x:"name"} */ + enum: pair {"name":x},{x:"name"} + ptrs: lazily, ctypedescr of array */ void *ct_extra; /* structs: first field (not a ref!) function types: cif_description primitives: prebuilt "cif" object */ @@ -1490,6 +1491,9 @@ s = PyText_FromString(buffer); } } + else if ((cd->c_type->ct_flags & CT_ARRAY) && cd->c_type->ct_length < 0) { + s = PyText_FromFormat("sliced length %zd", get_array_length(cd)); + } else { if (cd->c_data != NULL) { s = PyText_FromFormat("%p", cd->c_data); @@ -1717,9 +1721,155 @@ } static PyObject * +new_array_type(CTypeDescrObject *ctptr, PyObject *lengthobj); /* forward */ + +static CTypeDescrObject * +_cdata_getslicearg(CDataObject *cd, PySliceObject *slice, Py_ssize_t bounds[]) +{ + Py_ssize_t start, stop; + CTypeDescrObject *ct; + + start = PyInt_AsSsize_t(slice->start); + if (start == -1 && PyErr_Occurred()) { + if (slice->start == Py_None) + PyErr_SetString(PyExc_IndexError, "slice start must be specified"); + return NULL; + } + stop = PyInt_AsSsize_t(slice->stop); + if (stop == -1 && PyErr_Occurred()) { + if (slice->stop == Py_None) + PyErr_SetString(PyExc_IndexError, "slice stop must be specified"); + return NULL; + } + if (slice->step != Py_None) { + PyErr_SetString(PyExc_IndexError, "slice with step not supported"); + return NULL; + } + if (start > stop) { + PyErr_SetString(PyExc_IndexError, "slice start > stop"); + return NULL; + } + + ct = cd->c_type; + if (ct->ct_flags & CT_ARRAY) { + if (start < 0) { + PyErr_SetString(PyExc_IndexError, + "negative index not supported"); + return NULL; + } + if (stop >= get_array_length(cd)) { + PyErr_Format(PyExc_IndexError, + "index too large (expected %zd < %zd)", + stop, get_array_length(cd)); + return NULL; + } + ct = (CTypeDescrObject *)ct->ct_stuff; + } + else if (!(ct->ct_flags & CT_POINTER)) { + PyErr_Format(PyExc_TypeError, "cdata of type '%s' cannot be indexed", + ct->ct_name); + return NULL; + } + + bounds[0] = start; + bounds[1] = stop - start; + return ct; +} + +static PyObject * +cdata_slice(CDataObject *cd, PySliceObject *slice) +{ + Py_ssize_t bounds[2]; + CDataObject_own_length *scd; + CTypeDescrObject *ct = _cdata_getslicearg(cd, slice, bounds); + if (ct == NULL) + return NULL; + + if (ct->ct_stuff == NULL) { + ct->ct_stuff = new_array_type(ct, Py_None); + if (ct->ct_stuff == NULL) + return NULL; + } + ct = (CTypeDescrObject *)ct->ct_stuff; + + scd = (CDataObject_own_length *)PyObject_Malloc( + offsetof(CDataObject_own_length, alignment)); + if (PyObject_Init((PyObject *)scd, &CData_Type) == NULL) + return NULL; + Py_INCREF(ct); + scd->head.c_type = ct; + scd->head.c_data = cd->c_data + ct->ct_itemdescr->ct_size * bounds[0]; + scd->head.c_weakreflist = NULL; + scd->length = bounds[1]; + return (PyObject *)scd; +} + +static int +cdata_ass_slice(CDataObject *cd, PySliceObject *slice, PyObject *v) +{ + Py_ssize_t bounds[2], i, length, itemsize; + PyObject *it, *item; + PyObject *(*iternext)(PyObject *); + char *cdata; + int err; + CTypeDescrObject *ct = _cdata_getslicearg(cd, slice, bounds); + if (ct == NULL) + return -1; + ct = ct->ct_itemdescr; + itemsize = ct->ct_size; + cdata = cd->c_data + itemsize * bounds[0]; + length = bounds[1]; + + if (CData_Check(v)) { + CTypeDescrObject *ctv = ((CDataObject *)v)->c_type; + if ((ctv->ct_flags & CT_ARRAY) && (ctv->ct_itemdescr == ct) && + (get_array_length((CDataObject *)v) == length)) { + /* fast path: copying from exactly the correct type */ + memcpy(cdata, ((CDataObject *)v)->c_data, itemsize * length); + return 0; + } + } + + it = PyObject_GetIter(v); + if (it == NULL) + return -1; + iternext = *it->ob_type->tp_iternext; + + for (i = 0; i < length; i++) { + item = iternext(it); + if (item == NULL) { + if (!PyErr_Occurred()) + PyErr_Format(PyExc_ValueError, + "need %zd values to unpack, got %zd", + length, i); + goto error; + } + err = convert_from_object(cdata, ct, item); + Py_DECREF(item); + if (err < 0) + goto error; + + cdata += itemsize; + } + item = iternext(it); + if (item != NULL) { + Py_DECREF(item); + PyErr_Format(PyExc_ValueError, + "got more than %zd values to unpack", length); + } + error: + Py_DECREF(it); + return PyErr_Occurred() ? -1 : 0; +} + +static PyObject * cdataowning_subscript(CDataObject *cd, PyObject *key) { - char *c = _cdata_get_indexed_ptr(cd, key); + char *c; + if (PySlice_Check(key)) + return cdata_slice(cd, (PySliceObject *)key); + + c = _cdata_get_indexed_ptr(cd, key); /* use 'mp_subscript' instead of 'sq_item' because we don't want negative indexes to be corrected automatically */ if (c == NULL && PyErr_Occurred()) @@ -1738,7 +1888,11 @@ static PyObject * cdata_subscript(CDataObject *cd, PyObject *key) { - char *c = _cdata_get_indexed_ptr(cd, key); + char *c; + if (PySlice_Check(key)) + return cdata_slice(cd, (PySliceObject *)key); + + c = _cdata_get_indexed_ptr(cd, key); /* use 'mp_subscript' instead of 'sq_item' because we don't want negative indexes to be corrected automatically */ if (c == NULL && PyErr_Occurred()) @@ -1749,8 +1903,13 @@ static int cdata_ass_sub(CDataObject *cd, PyObject *key, PyObject *v) { - char *c = _cdata_get_indexed_ptr(cd, key); - CTypeDescrObject *ctitem = cd->c_type->ct_itemdescr; + char *c; + CTypeDescrObject *ctitem; + if (PySlice_Check(key)) + return cdata_ass_slice(cd, (PySliceObject *)key, v); + + c = _cdata_get_indexed_ptr(cd, key); + ctitem = cd->c_type->ct_itemdescr; /* use 'mp_ass_subscript' instead of 'sq_ass_item' because we don't want negative indexes to be corrected automatically */ if (c == NULL && PyErr_Occurred()) @@ -3122,14 +3281,22 @@ static PyObject *b_new_array_type(PyObject *self, PyObject *args) { PyObject *lengthobj; - CTypeDescrObject *td, *ctitem, *ctptr; - char extra_text[32]; - Py_ssize_t length, arraysize; + CTypeDescrObject *ctptr; if (!PyArg_ParseTuple(args, "O!O:new_array_type", &CTypeDescr_Type, &ctptr, &lengthobj)) return NULL; + return new_array_type(ctptr, lengthobj); +} + +static PyObject * +new_array_type(CTypeDescrObject *ctptr, PyObject *lengthobj) +{ + CTypeDescrObject *td, *ctitem; + char extra_text[32]; + Py_ssize_t length, arraysize; + if (!(ctptr->ct_flags & CT_POINTER)) { PyErr_SetString(PyExc_TypeError, "first arg must be a pointer ctype"); return NULL; diff --git a/c/test_c.py b/c/test_c.py --- a/c/test_c.py +++ b/c/test_c.py @@ -2574,3 +2574,85 @@ for i in range(20): buf = buflist[i] assert buf[:] == str2bytes("hi there %d\x00" % i) + +def test_slice(): + BIntP = new_pointer_type(new_primitive_type("int")) + BIntArray = new_array_type(BIntP, None) + c = newp(BIntArray, 5) + assert len(c) == 5 + assert repr(c) == "" + d = c[1:4] + assert len(d) == 3 + assert repr(d) == "" + d[0] = 123 + d[2] = 456 + assert c[1] == 123 + assert c[3] == 456 + assert d[2] == 456 + py.test.raises(IndexError, "d[3]") + py.test.raises(IndexError, "d[-1]") + +def test_slice_ptr(): + BIntP = new_pointer_type(new_primitive_type("int")) + BIntArray = new_array_type(BIntP, None) + c = newp(BIntArray, 5) + d = (c+1)[0:2] + assert len(d) == 2 + assert repr(d) == "" + d[1] += 50 + assert c[2] == 50 + +def test_slice_array_checkbounds(): + BIntP = new_pointer_type(new_primitive_type("int")) + BIntArray = new_array_type(BIntP, None) + c = newp(BIntArray, 5) + py.test.raises(IndexError, "c[-1:1]") + cp = c + 0 + cp[-1:1] + +def test_nonstandard_slice(): + BIntP = new_pointer_type(new_primitive_type("int")) + BIntArray = new_array_type(BIntP, None) + c = newp(BIntArray, 5) + e = py.test.raises(IndexError, "c[:5]") + assert str(e.value) == "slice start must be specified" + e = py.test.raises(IndexError, "c[4:]") + assert str(e.value) == "slice stop must be specified" + e = py.test.raises(IndexError, "c[1:2:3]") + assert str(e.value) == "slice with step not supported" + e = py.test.raises(IndexError, "c[1:2:1]") + assert str(e.value) == "slice with step not supported" + e = py.test.raises(IndexError, "c[4:2]") + assert str(e.value) == "slice start > stop" + e = py.test.raises(IndexError, "c[6:6]") + assert str(e.value) == "index too large (expected 6 < 5)" + +def test_setslice(): + BIntP = new_pointer_type(new_primitive_type("int")) + BIntArray = new_array_type(BIntP, None) + c = newp(BIntArray, 5) + c[1:3] = [100, 200] + assert list(c) == [0, 100, 200, 0, 0] + cp = c + 3 + cp[-1:1] = [300, 400] + assert list(c) == [0, 100, 300, 400, 0] + cp[-1:1] = iter([500, 600]) + assert list(c) == [0, 100, 500, 600, 0] + py.test.raises(ValueError, "cp[-1:1] = [1000]") + assert list(c) == [0, 100, 1000, 600, 0] + py.test.raises(ValueError, "cp[-1:1] = (700, 800, 900)") + assert list(c) == [0, 100, 700, 800, 0] + +def test_setslice_array(): + BIntP = new_pointer_type(new_primitive_type("int")) + BIntArray = new_array_type(BIntP, None) + c = newp(BIntArray, 5) + d = newp(BIntArray, [10, 20, 30]) + c[1:4] = d + assert list(c) == [0, 10, 20, 30, 0] + # + BShortP = new_pointer_type(new_primitive_type("short")) + BShortArray = new_array_type(BShortP, None) + d = newp(BShortArray, [40, 50]) + c[1:3] = d + assert list(c) == [0, 40, 50, 30, 0] diff --git a/doc/source/index.rst b/doc/source/index.rst --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -1274,9 +1274,9 @@ | | anything on which | precision `(***)`| | | | float() works | | | +---------------+------------------------+------------------+----------------+ -| pointers | another with | a | ``[]``, ``+``, | -| | a compatible type (i.e.| | ``-``, bool() | -| | same type or ``char*`` | | | +| pointers | another with | a |``[]`` `(****)`,| +| | a compatible type (i.e.| |``+``, ``-``, | +| | same type or ``char*`` | |bool() | | | or ``void*``, or as an | | | | | array instead) `(*)` | | | +---------------+------------------------+ | | @@ -1292,9 +1292,9 @@ | function | same as pointers | | bool(), | | pointers | | | call `(**)` | +---------------+------------------------+------------------+----------------+ -| arrays | a list or tuple of | a | len(), iter(), | -| | items | | ``[]``, | -| | | | ``+``, ``-`` | +| arrays | a list or tuple of | a |len(), iter(), | +| | items | |``[]`` `(****)`,| +| | | |``+``, ``-`` | +---------------+------------------------+ +----------------+ | ``char[]`` | same as arrays, or a | | len(), iter(), | | | Python string | | ``[]``, ``+``, | @@ -1349,6 +1349,15 @@ without any precision loss, you need to define and use a family of C functions like ``long double add(long double a, long double b);``. +.. versionadded:: 0.6 + `(****)` Supports simple slices as well: ``x[start:stop]`` gives another + cdata object that is a "view" of all items from ``start`` to ``stop``. + It is a cdata of type "array" (so e.g. passing it as an argument to a + C function would just convert it to a pointer to the ``start`` item). + As with indexing, negative bounds mean really negative indices, like in + C. As for slice assignment, it accepts any iterable, including a list + of items or another array-like cdata object, but the length must match. + Reference: verifier ------------------- From noreply at buildbot.pypy.org Tue Feb 12 20:29:38 2013 From: noreply at buildbot.pypy.org (arigo) Date: Tue, 12 Feb 2013 20:29:38 +0100 (CET) Subject: [pypy-commit] cffi enum-as-int: More documentation Message-ID: <20130212192938.24FFA1C1053@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: enum-as-int Changeset: r1150:ea9fec031def Date: 2013-02-12 18:21 +0100 http://bitbucket.org/cffi/cffi/changeset/ea9fec031def/ Log: More documentation diff --git a/doc/source/index.rst b/doc/source/index.rst --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -1347,9 +1347,10 @@ functions like ``long double add(long double a, long double b);``. .. versionchanged:: 0.6 - `(*****)` Enums are now handled like ints. In previous versions, - you would get the enum's value as a string. Now we follow the C - convention and treat them as really equivalent to ints. To compare + `(*****)` Enums are now handled like ints (unsigned or signed, int or + long, like GCC; note that the first choice is unsigned). In previous + versions, you would get the enum's value as a string. Now we follow the C + convention and treat them as really equivalent to integers. To compare their value symbolically, use code like ``if x.field == lib.FOO``. If you really want to get their value as a string, use ``ffi.string(ffi.cast("the_enum_type", x.field))``. From noreply at buildbot.pypy.org Tue Feb 12 20:29:39 2013 From: noreply at buildbot.pypy.org (arigo) Date: Tue, 12 Feb 2013 20:29:39 +0100 (CET) Subject: [pypy-commit] cffi default: hg merge enum-as-int Message-ID: <20130212192939.6B92F1C1053@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r1151:4aed2f4e2bc1 Date: 2013-02-12 18:26 +0100 http://bitbucket.org/cffi/cffi/changeset/4aed2f4e2bc1/ Log: hg merge enum-as-int diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c --- a/c/_cffi_backend.c +++ b/c/_cffi_backend.c @@ -824,35 +824,6 @@ return (PyObject *)cd; } -static PyObject *convert_enum_string_to_int(CTypeDescrObject *ct, PyObject *ob) -{ - PyObject *d_value; - char *p = PyText_AsUTF8(ob); - if (p == NULL) - return NULL; - - if (p[0] == '#') { - char *number = p + 1; /* strip initial '#' */ - PyObject *ob2 = PyText_FromString(number); - if (ob2 == NULL) - return NULL; - - d_value = PyNumber_Long(ob2); - Py_DECREF(ob2); - } - else { - d_value = PyDict_GetItem(PyTuple_GET_ITEM(ct->ct_stuff, 0), ob); - if (d_value == NULL) { - PyErr_Format(PyExc_ValueError, - "'%s' is not an enumerator for %s", - p, ct->ct_name); - return NULL; - } - Py_INCREF(d_value); - } - return d_value; -} - static CDataObject *_new_casted_primitive(CTypeDescrObject *ct); /*forward*/ static PyObject * @@ -887,21 +858,7 @@ PY_LONG_LONG value; /*READ(data, ct->ct_size)*/ value = read_raw_signed_data(data, ct->ct_size); - - if (ct->ct_flags & CT_IS_ENUM) { - PyObject *d_value, *d_key = PyInt_FromLong((int)value); - if (d_key == NULL) - return NULL; - - d_value = PyDict_GetItem(PyTuple_GET_ITEM(ct->ct_stuff, 1), d_key); - Py_DECREF(d_key); - if (d_value != NULL) - Py_INCREF(d_value); - else - d_value = PyText_FromFormat("#%d", (int)value); - return d_value; - } - else if (ct->ct_flags & CT_PRIMITIVE_FITS_LONG) + if (ct->ct_flags & CT_PRIMITIVE_FITS_LONG) return PyInt_FromLong((long)value); else return PyLong_FromLongLong(value); @@ -1190,27 +1147,8 @@ } if (ct->ct_flags & CT_PRIMITIVE_SIGNED) { PY_LONG_LONG value = _my_PyLong_AsLongLong(init); - - if (value == -1 && PyErr_Occurred()) { - if (!(ct->ct_flags & CT_IS_ENUM)) - return -1; - else { - PyObject *ob; - PyErr_Clear(); - if (!PyTextAny_Check(init)) { - expected = "str or int"; - goto cannot_convert; - } - - ob = convert_enum_string_to_int(ct, init); - if (ob == NULL) - return -1; - value = PyLong_AsLongLong(ob); - Py_DECREF(ob); - if (value == -1 && PyErr_Occurred()) - return -1; - } - } + if (value == -1 && PyErr_Occurred()) + return -1; write_raw_integer_data(buf, value, ct->ct_size); if (value != read_raw_signed_data(buf, ct->ct_size)) goto overflow; @@ -1469,20 +1407,48 @@ static PyObject *cdata_float(CDataObject *cd); /*forward*/ +static PyObject *convert_cdata_to_enum_string(CDataObject *cd, int both) +{ + PyObject *d_key, *d_value; + CTypeDescrObject *ct = cd->c_type; + + assert(ct->ct_flags & CT_IS_ENUM); + d_key = convert_to_object(cd->c_data, ct); + if (d_key == NULL) + return NULL; + + d_value = PyDict_GetItem(PyTuple_GET_ITEM(ct->ct_stuff, 1), d_key); + if (d_value != NULL) { + if (both) { + PyObject *o = PyObject_Str(d_key); + if (o == NULL) + d_value = NULL; + else { + d_value = PyText_FromFormat("%s: %s", + PyText_AS_UTF8(o), + PyText_AS_UTF8(d_value)); + Py_DECREF(o); + } + } + else + Py_INCREF(d_value); + } + else + d_value = PyObject_Str(d_key); + Py_DECREF(d_key); + return d_value; +} + static PyObject *cdata_repr(CDataObject *cd) { char *extra; PyObject *result, *s; if (cd->c_type->ct_flags & CT_PRIMITIVE_ANY) { - if (!(cd->c_type->ct_flags & CT_IS_LONGDOUBLE)) { - PyObject *o = convert_to_object(cd->c_data, cd->c_type); - if (o == NULL) - return NULL; - s = PyObject_Repr(o); - Py_DECREF(o); + if (cd->c_type->ct_flags & CT_IS_ENUM) { + s = convert_cdata_to_enum_string(cd, 1); } - else { + else if (cd->c_type->ct_flags & CT_IS_LONGDOUBLE) { long double lvalue; char buffer[128]; /* big enough */ /*READ(cd->c_data, sizeof(long double)*/ @@ -1490,6 +1456,13 @@ sprintf(buffer, "%LE", lvalue); s = PyText_FromString(buffer); } + else { + PyObject *o = convert_to_object(cd->c_data, cd->c_type); + if (o == NULL) + return NULL; + s = PyObject_Repr(o); + Py_DECREF(o); + } } else if ((cd->c_type->ct_flags & CT_ARRAY) && cd->c_type->ct_length < 0) { s = PyText_FromFormat("sliced length %zd", get_array_length(cd)); @@ -2745,14 +2718,6 @@ (CT_POINTER|CT_FUNCTIONPTR|CT_ARRAY)) { value = (Py_intptr_t)((CDataObject *)ob)->c_data; } - else if ((ct->ct_flags & CT_IS_ENUM) && PyTextAny_Check(ob)) { - ob = convert_enum_string_to_int(ct, ob); - if (ob == NULL) - return NULL; - cd = cast_to_integer_or_char(ct, ob); - Py_DECREF(ob); - return cd; - } #if PY_MAJOR_VERSION < 3 else if (PyString_Check(ob)) { if (PyString_GET_SIZE(ob) != 1) { @@ -4074,8 +4039,7 @@ return -1; } } - if ((ctype->ct_flags & (CT_PRIMITIVE_SIGNED | CT_IS_ENUM)) - == CT_PRIMITIVE_SIGNED) { + if (ctype->ct_flags & CT_PRIMITIVE_SIGNED) { PY_LONG_LONG value; /* It's probably fine to always zero-extend, but you never know: maybe some code somewhere expects a negative @@ -4294,6 +4258,10 @@ CTypeDescrObject *td; Py_ssize_t i, n; struct aligncheck_int { char x; int y; }; + struct aligncheck_long { char x; long y; }; + long smallest_item = 0; + unsigned long largest_item = 0; + int size, flags; if (!PyArg_ParseTuple(args, "sO!O!:new_enum_type", &ename, @@ -4311,8 +4279,13 @@ dict1 = PyDict_New(); if (dict1 == NULL) goto error; + dict2 = PyDict_New(); + if (dict2 == NULL) + goto error; + for (i=n; --i >= 0; ) { long lvalue; + unsigned long ulvalue; PyObject *value = PyTuple_GET_ITEM(enumvalues, i); tmpkey = PyTuple_GET_ITEM(enumerators, i); Py_INCREF(tmpkey); @@ -4336,25 +4309,62 @@ } } lvalue = PyLong_AsLong(value); - if ((lvalue == -1 && PyErr_Occurred()) || lvalue != (int)lvalue) { - PyErr_Format(PyExc_OverflowError, - "enum '%s' declaration for '%s' does not fit an int", - ename, PyText_AS_UTF8(tmpkey)); - goto error; + if (PyErr_Occurred()) { + PyErr_Clear(); + ulvalue = PyLong_AsUnsignedLong(value); + if (PyErr_Occurred()) { + PyErr_Format(PyExc_OverflowError, + "enum '%s' declaration for '%s' does not fit " + "a long or unsigned long", + ename, PyText_AS_UTF8(tmpkey)); + goto error; + } + if (ulvalue > largest_item) + largest_item = ulvalue; + } + else { + if (lvalue < 0) { + if (lvalue < smallest_item) + smallest_item = lvalue; + } + else { + ulvalue = (unsigned long)lvalue; + if (ulvalue > largest_item) + largest_item = ulvalue; + } } if (PyDict_SetItem(dict1, tmpkey, value) < 0) goto error; + if (PyDict_SetItem(dict2, value, tmpkey) < 0) + goto error; Py_DECREF(tmpkey); tmpkey = NULL; } - dict2 = PyDict_New(); - if (dict2 == NULL) - goto error; - for (i=n; --i >= 0; ) { - if (PyDict_SetItem(dict2, PyTuple_GET_ITEM(enumvalues, i), - PyTuple_GET_ITEM(enumerators, i)) < 0) + if (smallest_item < 0) { + flags = CT_PRIMITIVE_SIGNED | CT_PRIMITIVE_FITS_LONG | CT_IS_ENUM; + if (smallest_item == (int)smallest_item && + largest_item <= (unsigned long)INT_MAX) { + size = sizeof(int); + } + else if (largest_item <= (unsigned long)LONG_MAX) { + size = sizeof(long); + } + else { + PyErr_Format(PyExc_OverflowError, + "enum '%s' values don't all fit into either 'long' " + "or 'unsigned long'", ename); goto error; + } + } + else if (sizeof(unsigned int) < sizeof(unsigned long) && + largest_item == (unsigned int)largest_item) { + flags = CT_PRIMITIVE_UNSIGNED | CT_PRIMITIVE_FITS_LONG | CT_IS_ENUM; + size = sizeof(unsigned int); + } + else { + flags = CT_PRIMITIVE_UNSIGNED | CT_IS_ENUM; + size = sizeof(unsigned long); } combined = PyTuple_Pack(2, dict1, dict2); @@ -4364,10 +4374,10 @@ Py_CLEAR(dict2); Py_CLEAR(dict1); - switch (sizeof(int)) { + switch (size) { case 4: ffitype = &ffi_type_sint32; break; case 8: ffitype = &ffi_type_sint64; break; - default: Py_FatalError("'int' is not 4 or 8 bytes"); + default: Py_FatalError("'int' or 'long' is not 4 or 8 bytes"); return NULL; } name_size = strlen("enum ") + strlen(ename) + 1; @@ -4378,10 +4388,11 @@ memcpy(td->ct_name, "enum ", strlen("enum ")); memcpy(td->ct_name + strlen("enum "), ename, name_size - strlen("enum ")); td->ct_stuff = combined; - td->ct_size = sizeof(int); - td->ct_length = offsetof(struct aligncheck_int, y); + td->ct_size = size; + td->ct_length = size == sizeof(int) ? offsetof(struct aligncheck_int, y) + : offsetof(struct aligncheck_long, y); td->ct_extra = ffitype; - td->ct_flags = CT_PRIMITIVE_SIGNED | CT_PRIMITIVE_FITS_LONG | CT_IS_ENUM; + td->ct_flags = flags; td->ct_name_position = name_size - 1; return (PyObject *)td; @@ -4604,7 +4615,7 @@ #endif } else if (cd->c_type->ct_flags & CT_IS_ENUM) { - return convert_to_object(cd->c_data, cd->c_type); + return convert_cdata_to_enum_string(cd, 0); } else if (cd->c_type->ct_flags & CT_IS_BOOL) { /* fall through to TypeError */ diff --git a/c/test_c.py b/c/test_c.py --- a/c/test_c.py +++ b/c/test_c.py @@ -1292,22 +1292,24 @@ def test_cast_to_enum(): BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, -20)) e = cast(BEnum, 0) - assert repr(e) == "" + assert repr(e) == "" + assert repr(cast(BEnum, -42)) == "" + assert repr(cast(BEnum, -20)) == "" assert string(e) == 'def' assert string(cast(BEnum, -20)) == 'ab' - assert string(cast(BEnum, 'c')) == 'c' - assert int(cast(BEnum, 'c')) == 1 - assert int(cast(BEnum, 'def')) == 0 + assert int(cast(BEnum, 1)) == 1 + assert int(cast(BEnum, 0)) == 0 assert int(cast(BEnum, -242 + 2**128)) == -242 - assert string(cast(BEnum, -242 + 2**128)) == '#-242' - assert string(cast(BEnum, '#-20')) == 'ab' - assert repr(cast(BEnum, '#-20')) == "" - assert repr(cast(BEnum, '#-21')) == "" + assert string(cast(BEnum, -242 + 2**128)) == '-242' + # + BEnum = new_enum_type("bar", ('def', 'c', 'ab'), (0, 1, 20)) + e = cast(BEnum, -1) + assert repr(e) == "" # unsigned int def test_enum_with_non_injective_mapping(): BEnum = new_enum_type("foo", ('ab', 'cd'), (7, 7)) e = cast(BEnum, 7) - assert repr(e) == "" + assert repr(e) == "" assert string(e) == 'ab' def test_enum_in_struct(): @@ -1316,36 +1318,111 @@ BStructPtr = new_pointer_type(BStruct) complete_struct_or_union(BStruct, [('a1', BEnum, -1)]) p = newp(BStructPtr, [-20]) - assert p.a1 == "ab" - p = newp(BStructPtr, ["c"]) - assert p.a1 == "c" + assert p.a1 == -20 + p = newp(BStructPtr, [12]) + assert p.a1 == 12 e = py.test.raises(TypeError, newp, BStructPtr, [None]) - assert "must be a str or int, not NoneType" in str(e.value) + assert "an integer is required" in str(e.value) + py.test.raises(TypeError, 'p.a1 = "def"') if sys.version_info < (3,): - p.a1 = unicode("def") - assert p.a1 == "def" and type(p.a1) is str - py.test.raises(UnicodeEncodeError, "p.a1 = unichr(1234)") BEnum2 = new_enum_type(unicode("foo"), (unicode('abc'),), (5,)) - assert string(cast(BEnum2, unicode('abc'))) == 'abc' + assert string(cast(BEnum2, 5)) == 'abc' + assert type(string(cast(BEnum2, 5))) is str def test_enum_overflow(): - for ovf in (2**63, -2**63-1, 2**31, -2**31-1): - e = py.test.raises(OverflowError, new_enum_type, "foo", ('a', 'b'), - (5, ovf)) - assert str(e.value) == ( - "enum 'foo' declaration for 'b' does not fit an int") + max_uint = 2 ** (size_of_int()*8) - 1 + max_int = max_uint // 2 + max_ulong = 2 ** (size_of_long()*8) - 1 + max_long = max_ulong // 2 + # 'unsigned int' case + e = new_enum_type("foo", ('a', 'b'), (0, 3)) + assert sizeof(e) == size_of_int() + assert int(cast(e, -1)) == max_uint # 'e' is unsigned + e = new_enum_type("foo", ('a', 'b'), (0, max_uint)) + assert sizeof(e) == size_of_int() + assert int(cast(e, -1)) == max_uint + assert e.elements == {0: 'a', max_uint: 'b'} + assert e.relements == {'a': 0, 'b': max_uint} + # 'signed int' case + e = new_enum_type("foo", ('a', 'b'), (-1, max_int)) + assert sizeof(e) == size_of_int() + assert int(cast(e, -1)) == -1 + assert e.elements == {-1: 'a', max_int: 'b'} + assert e.relements == {'a': -1, 'b': max_int} + e = new_enum_type("foo", ('a', 'b'), (-max_int-1, max_int)) + assert sizeof(e) == size_of_int() + assert int(cast(e, -1)) == -1 + assert e.elements == {-max_int-1: 'a', max_int: 'b'} + assert e.relements == {'a': -max_int-1, 'b': max_int} + # 'unsigned long' case + e = new_enum_type("foo", ('a', 'b'), (0, max_long)) + assert sizeof(e) == size_of_long() + assert int(cast(e, -1)) == max_ulong # 'e' is unsigned + e = new_enum_type("foo", ('a', 'b'), (0, max_ulong)) + assert sizeof(e) == size_of_long() + assert int(cast(e, -1)) == max_ulong + assert e.elements == {0: 'a', max_ulong: 'b'} + assert e.relements == {'a': 0, 'b': max_ulong} + # 'signed long' case + e = new_enum_type("foo", ('a', 'b'), (-1, max_long)) + assert sizeof(e) == size_of_long() + assert int(cast(e, -1)) == -1 + assert e.elements == {-1: 'a', max_long: 'b'} + assert e.relements == {'a': -1, 'b': max_long} + e = new_enum_type("foo", ('a', 'b'), (-max_long-1, max_long)) + assert sizeof(e) == size_of_long() + assert int(cast(e, -1)) == -1 + assert e.elements == {-max_long-1: 'a', max_long: 'b'} + assert e.relements == {'a': -max_long-1, 'b': max_long} + # overflow: both negative items and items larger than max_long + e = py.test.raises(OverflowError, new_enum_type, "foo", ('a', 'b'), + (-1, max_long + 1)) + assert str(e.value) == ( + "enum 'foo' values don't all fit into either 'long' " + "or 'unsigned long'") + # overflow: items smaller than -max_long-1 + e = py.test.raises(OverflowError, new_enum_type, "foo", ('a', 'b'), + (-max_long-2, 5)) + assert str(e.value) == ( + "enum 'foo' declaration for 'a' does not fit a long or unsigned long") + # overflow: items larger than max_ulong + e = py.test.raises(OverflowError, new_enum_type, "foo", ('a', 'b'), + (5, max_ulong+1)) + assert str(e.value) == ( + "enum 'foo' declaration for 'b' does not fit a long or unsigned long") def test_callback_returning_enum(): BInt = new_primitive_type("int") BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, -20)) def cb(n): - return '#%d' % n + if n & 1: + return cast(BEnum, n) + else: + return n BFunc = new_function_type((BInt,), BEnum) f = callback(BFunc, cb) - assert f(0) == 'def' - assert f(1) == 'c' - assert f(-20) == 'ab' - assert f(20) == '#20' + assert f(0) == 0 + assert f(1) == 1 + assert f(-20) == -20 + assert f(20) == 20 + assert f(21) == 21 + +def test_callback_returning_enum_unsigned(): + BInt = new_primitive_type("int") + BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, 20)) + def cb(n): + print n + if n & 1: + return cast(BEnum, n) + else: + return n + BFunc = new_function_type((BInt,), BEnum) + f = callback(BFunc, cb) + assert f(0) == 0 + assert f(1) == 1 + assert f(-21) == 2**32 - 21 + assert f(20) == 20 + assert f(21) == 21 def test_callback_returning_char(): BInt = new_primitive_type("int") diff --git a/cffi/backend_ctypes.py b/cffi/backend_ctypes.py --- a/cffi/backend_ctypes.py +++ b/cffi/backend_ctypes.py @@ -926,49 +926,43 @@ def new_enum_type(self, name, enumerators, enumvalues): assert isinstance(name, str) - mapping = dict(zip(enumerators, enumvalues)) reverse_mapping = dict(zip(reversed(enumvalues), reversed(enumerators))) - CTypesInt = self.ffi._get_cached_btype(model.PrimitiveType('int')) - # - def forward_map(source): - if not isinstance(source, str): - return source - try: - return mapping[source] - except KeyError: - if source.startswith('#'): - try: - return int(source[1:]) - except ValueError: - pass - raise ValueError("%r is not an enumerator for %r" % ( - source, CTypesEnum)) + smallest = min(enumvalues or [0]) + largest = max(enumvalues or [0]) + if smallest < 0: + if largest == ctypes.c_int(largest).value: + tp = 'int' + elif largest == ctypes.c_long(largest).value: + tp = 'long' + else: + raise OverflowError + else: + if largest == ctypes.c_uint(largest).value: + tp = 'unsigned int' + elif largest == ctypes.c_ulong(largest).value: + tp = 'unsigned long' + else: + raise OverflowError + CTypesInt = self.ffi._get_cached_btype(model.PrimitiveType(tp)) # class CTypesEnum(CTypesInt): __slots__ = [] _reftypename = 'enum %s &' % name + def _get_own_repr(self): + value = self._value + try: + return '%d: %s' % (value, reverse_mapping[value]) + except KeyError: + return str(value) + def _to_string(self, maxlen): - return str(CTypesEnum._from_ctypes(self._value)) - - @classmethod - def _cast_from(cls, source): - source = forward_map(source) - return super(CTypesEnum, cls)._cast_from(source) - - @staticmethod - def _to_ctypes(x): - x = forward_map(x) - return CTypesInt._to_ctypes(x) - - @staticmethod - def _from_ctypes(value): - value = CTypesInt._from_ctypes(value) + value = self._value try: return reverse_mapping[value] except KeyError: - return '#%s' % value + return str(value) # CTypesEnum._fix_class() return CTypesEnum diff --git a/doc/source/index.rst b/doc/source/index.rst --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -1031,7 +1031,7 @@ ------------------- ``ffi.include(other_ffi)``: includes the typedefs, structs, unions and -enums defined in another FFI instance. Usage is similar to a +enum types defined in another FFI instance. Usage is similar to a ``#include`` in C, where a part of the program might include types defined in another part for its own usage. Note that the include() method has no effect on functions, constants and global variables, which @@ -1065,8 +1065,9 @@ byte string or unicode string. (Note that in some situation a single wchar_t may require a Python unicode string of length 2.) -- If 'cdata' is an enum, returns the value of the enumerator as a - string, or ``#NUMBER`` if the value is out of range. +- If 'cdata' is an enum, returns the value of the enumerator as a string. + If the value is out of range, it is simply returned as the stringified + integer. ``ffi.buffer(cdata, [size])``: return a buffer object that references @@ -1193,15 +1194,16 @@ length 0, allocating a ``char[]`` of the correct size, and casting it to a struct pointer) -* Enum types are always ``int``. GCC supports enums containing - larger constants (``unsigned int``, or ``long long``) as an extension - to the C standard, but CFFI does not. Use - ``typedef my_enum;`` and then some ``#define foo ``. - .. versionadded:: 0.4 Now supported: the common GCC extension of anonymous nested structs/unions inside structs/unions. +.. versionadded:: 0.6 + Enum types follow the GCC rules: they are defined as the first of + ``unsigned int``, ``int``, ``unsigned long`` or ``long`` that fits + all numeric values. Note that the first choice is unsigned. In CFFI + 0.5 and before, it was always ``int``. + Debugging dlopen'ed C libraries ------------------------------- @@ -1254,8 +1256,8 @@ | C type | writing into | reading from |other operations| +===============+========================+==================+================+ | integers | an integer or anything | a Python int or | int() | -| | on which int() works | long, depending | | -| | (but not a float!). | on the type | | +| and enums | on which int() works | long, depending | | +| `(*****)` | (but not a float!). | on the type | | | | Must be within range. | | | +---------------+------------------------+------------------+----------------+ | ``char`` | a string of length 1 | a string of | int() | @@ -1313,11 +1315,6 @@ | union | same as struct, but | | read/write | | | with at most one field | | fields | +---------------+------------------------+------------------+----------------+ -| enum | an integer, or the enum| the enum value | int() | -| | value as a string or | as a string, or | | -| | as ``"#NUMBER"`` | ``"#NUMBER"`` | | -| | | if out of range | | -+---------------+------------------------+------------------+----------------+ .. versionchanged:: 0.3 `(*)` Note that when calling a function, as per C, a ``item *`` argument @@ -1358,6 +1355,15 @@ C. As for slice assignment, it accepts any iterable, including a list of items or another array-like cdata object, but the length must match. +.. versionchanged:: 0.6 + `(*****)` Enums are now handled like ints (unsigned or signed, int or + long, like GCC; note that the first choice is unsigned). In previous + versions, you would get the enum's value as a string. Now we follow the C + convention and treat them as really equivalent to integers. To compare + their value symbolically, use code like ``if x.field == lib.FOO``. + If you really want to get their value as a string, use + ``ffi.string(ffi.cast("the_enum_type", x.field))``. + Reference: verifier ------------------- diff --git a/testing/backend_tests.py b/testing/backend_tests.py --- a/testing/backend_tests.py +++ b/testing/backend_tests.py @@ -860,54 +860,55 @@ def test_enum(self): ffi = FFI(backend=self.Backend()) ffi.cdef("enum foo { A, B, CC, D };") - assert int(ffi.cast("enum foo", "A")) == 0 - assert int(ffi.cast("enum foo", "B")) == 1 - assert int(ffi.cast("enum foo", "CC")) == 2 - assert int(ffi.cast("enum foo", "D")) == 3 - ffi.cdef("enum bar { A, B=-2, CC, D };") - assert int(ffi.cast("enum bar", "A")) == 0 - assert int(ffi.cast("enum bar", "B")) == -2 - assert int(ffi.cast("enum bar", "CC")) == -1 - assert int(ffi.cast("enum bar", "D")) == 0 - assert ffi.cast("enum bar", "B") != ffi.cast("enum bar", "B") - assert ffi.cast("enum foo", "A") != ffi.cast("enum bar", "A") - assert ffi.cast("enum bar", "A") != ffi.cast("int", 0) - assert repr(ffi.cast("enum bar", "CC")) == "" - py.test.raises(ValueError, ffi.cast, "enum bar", "UNKNOWN") + assert ffi.string(ffi.cast("enum foo", 0)) == "A" + assert ffi.string(ffi.cast("enum foo", 2)) == "CC" + assert ffi.string(ffi.cast("enum foo", 3)) == "D" + assert ffi.string(ffi.cast("enum foo", 4)) == "4" + ffi.cdef("enum bar { A, B=-2, CC, D, E };") + assert ffi.string(ffi.cast("enum bar", 0)) == "A" + assert ffi.string(ffi.cast("enum bar", -2)) == "B" + assert ffi.string(ffi.cast("enum bar", -1)) == "CC" + assert ffi.string(ffi.cast("enum bar", 1)) == "E" + assert ffi.cast("enum bar", -2) != ffi.cast("enum bar", -2) + assert ffi.cast("enum foo", 0) != ffi.cast("enum bar", 0) + assert ffi.cast("enum bar", 0) != ffi.cast("int", 0) + assert repr(ffi.cast("enum bar", -1)) == "" + assert repr(ffi.cast("enum foo", -1)) == ( # enums are unsigned, if + "") # they contain no neg value ffi.cdef("enum baz { A=0x1000, B=0x2000 };") - assert int(ffi.cast("enum baz", "A")) == 0x1000 - assert int(ffi.cast("enum baz", "B")) == 0x2000 + assert ffi.string(ffi.cast("enum baz", 0x1000)) == "A" + assert ffi.string(ffi.cast("enum baz", 0x2000)) == "B" def test_enum_in_struct(self): ffi = FFI(backend=self.Backend()) ffi.cdef("enum foo { A, B, C, D }; struct bar { enum foo e; };") s = ffi.new("struct bar *") s.e = 0 - assert s.e == "A" - s.e = "D" - assert s.e == "D" - assert s[0].e == "D" - s[0].e = "C" - assert s.e == "C" - assert s[0].e == "C" + assert s.e == 0 + s.e = 3 + assert s.e == 3 + assert s[0].e == 3 + s[0].e = 2 + assert s.e == 2 + assert s[0].e == 2 s.e = ffi.cast("enum foo", -1) - assert s.e == '#-1' - assert s[0].e == '#-1' + assert s.e == 4294967295 + assert s[0].e == 4294967295 s.e = s.e - py.test.raises(TypeError, "s.e = None") + py.test.raises(TypeError, "s.e = 'B'") + py.test.raises(TypeError, "s.e = '2'") + py.test.raises(TypeError, "s.e = '#2'") + py.test.raises(TypeError, "s.e = '#7'") def test_enum_non_contiguous(self): ffi = FFI(backend=self.Backend()) ffi.cdef("enum foo { A, B=42, C };") - assert int(ffi.cast("enum foo", "A")) == 0 - assert int(ffi.cast("enum foo", "B")) == 42 - assert int(ffi.cast("enum foo", "C")) == 43 assert ffi.string(ffi.cast("enum foo", 0)) == "A" assert ffi.string(ffi.cast("enum foo", 42)) == "B" assert ffi.string(ffi.cast("enum foo", 43)) == "C" invalid_value = ffi.cast("enum foo", 2) assert int(invalid_value) == 2 - assert ffi.string(invalid_value) == "#2" + assert ffi.string(invalid_value) == "2" def test_array_of_struct(self): ffi = FFI(backend=self.Backend()) @@ -1301,7 +1302,7 @@ def test_enum_with_non_injective_mapping(self): ffi = FFI(backend=self.Backend()) ffi.cdef("enum e { AA=0, BB=0, CC=0, DD=0 };") - e = ffi.cast("enum e", 'CC') + e = ffi.cast("enum e", 0) assert ffi.string(e) == "AA" # pick the first one arbitrarily def test_nested_anonymous_struct(self): diff --git a/testing/test_unicode_literals.py b/testing/test_unicode_literals.py --- a/testing/test_unicode_literals.py +++ b/testing/test_unicode_literals.py @@ -49,7 +49,7 @@ def test_enum(): ffi = FFI() ffi.cdef("enum foo_e { AA, BB, CC };") # unicode literal - x = ffi.cast("enum foo_e", "BB") + x = ffi.cast("enum foo_e", 1) assert int(ffi.cast("int", x)) == 1 def test_dlopen(): diff --git a/testing/test_verify.py b/testing/test_verify.py --- a/testing/test_verify.py +++ b/testing/test_verify.py @@ -558,13 +558,12 @@ ffi.cdef("enum ee { EE1, EE2, EE3, ... \n \t };") py.test.raises(VerificationMissing, ffi.cast, 'enum ee', 'EE2') ffi.verify("enum ee { EE1=10, EE2, EE3=-10, EE4 };") - assert int(ffi.cast('enum ee', 'EE2')) == 11 - assert int(ffi.cast('enum ee', 'EE3')) == -10 - py.test.raises(ValueError, ffi.cast, 'enum ee', '__dotdotdot0__') + assert ffi.string(ffi.cast('enum ee', 11)) == "EE2" + assert ffi.string(ffi.cast('enum ee', -10)) == "EE3" # # try again ffi.verify("enum ee { EE1=10, EE2, EE3=-10, EE4 };") - assert int(ffi.cast('enum ee', 'EE2')) == 11 + assert ffi.string(ffi.cast('enum ee', 11)) == "EE2" def test_full_enum(): ffi = FFI() @@ -578,25 +577,35 @@ lib = ffi.verify("enum ee { EE1, EE2, EE3, EE4 };") assert lib.EE3 == 2 +def test_enum_usage(): + ffi = FFI() + ffi.cdef("enum ee { EE1,EE2 }; typedef struct { enum ee x; } *sp;") + lib = ffi.verify("enum ee { EE1,EE2 }; typedef struct { enum ee x; } *sp;") + assert lib.EE2 == 1 + s = ffi.new("sp", [lib.EE2]) + assert s.x == 1 + s.x = 17 + assert s.x == 17 + def test_nonfull_enum_syntax2(): ffi = FFI() ffi.cdef("enum ee { EE1, EE2=\t..., EE3 };") py.test.raises(VerificationMissing, ffi.cast, 'enum ee', 'EE1') ffi.verify("enum ee { EE1=10, EE2, EE3=-10, EE4 };") - assert int(ffi.cast('enum ee', 'EE2')) == 11 - assert int(ffi.cast('enum ee', 'EE3')) == -10 + assert ffi.string(ffi.cast('enum ee', 11)) == 'EE2' + assert ffi.string(ffi.cast('enum ee', -10)) == 'EE3' # ffi = FFI() ffi.cdef("enum ee { EE1, EE2=\t... };") py.test.raises(VerificationMissing, ffi.cast, 'enum ee', 'EE1') ffi.verify("enum ee { EE1=10, EE2, EE3=-10, EE4 };") - assert int(ffi.cast('enum ee', 'EE2')) == 11 + assert ffi.string(ffi.cast('enum ee', 11)) == 'EE2' # ffi = FFI() ffi.cdef("enum ee2 { EE4=..., EE5=..., ... };") ffi.verify("enum ee2 { EE4=-1234-5, EE5 }; ") - assert int(ffi.cast('enum ee2', 'EE4')) == -1239 - assert int(ffi.cast('enum ee2', 'EE5')) == -1238 + assert ffi.string(ffi.cast('enum ee2', -1239)) == 'EE4' + assert ffi.string(ffi.cast('enum ee2', -1238)) == 'EE5' def test_get_set_errno(): ffi = FFI() @@ -961,7 +970,7 @@ int foo_func(enum foo_e e) { return e; } """) assert lib.foo_func(lib.BB) == 2 - assert lib.foo_func("BB") == 2 + py.test.raises(TypeError, lib.foo_func, "BB") def test_enum_as_function_result(): ffi = FFI() @@ -973,7 +982,7 @@ enum foo_e { AA, CC, BB }; enum foo_e foo_func(int x) { return x; } """) - assert lib.foo_func(lib.BB) == "BB" + assert lib.foo_func(lib.BB) == lib.BB == 2 def test_enum_values(): ffi = FFI() @@ -1001,7 +1010,7 @@ ffi = FFI() ffi.cdef("typedef enum { AA, BB, ... } enum1_t;") lib = ffi.verify("typedef enum { AA, CC, BB } enum1_t;") - assert ffi.string(ffi.cast("enum1_t", 1)) == '#1' + assert ffi.string(ffi.cast("enum1_t", 1)) == '1' assert ffi.string(ffi.cast("enum1_t", 2)) == 'BB' assert lib.AA == 0 assert lib.BB == 2 @@ -1016,7 +1025,7 @@ typedef enum { AA, CC, BB } foo_t; foo_t foo_func(int x) { return x; } """) - assert lib.foo_func(lib.BB) == "BB" + assert lib.foo_func(lib.BB) == lib.BB == 2 def test_callback_calling_convention(): py.test.skip("later") @@ -1429,7 +1438,7 @@ ffi2.cdef("int myfunc(enum foo_e);") lib2 = ffi2.verify("enum foo_e { CC, BB, AA };" "int myfunc(enum foo_e x) { return (int)x; }") - res = lib2.myfunc("AA") + res = lib2.myfunc(lib2.AA) assert res == 2 def test_string_to_voidp_arg(): From noreply at buildbot.pypy.org Tue Feb 12 20:29:40 2013 From: noreply at buildbot.pypy.org (arigo) Date: Tue, 12 Feb 2013 20:29:40 +0100 (CET) Subject: [pypy-commit] cffi default: hg merge auto-types Message-ID: <20130212192940.B137F1C1053@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r1152:a5e3e36914a5 Date: 2013-02-12 18:27 +0100 http://bitbucket.org/cffi/cffi/changeset/a5e3e36914a5/ Log: hg merge auto-types diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c --- a/c/_cffi_backend.c +++ b/c/_cffi_backend.c @@ -3346,7 +3346,7 @@ return NULL; flag = CT_STRUCT; - if (strcmp(name, "_IO_FILE") == 0) + if (strcmp(name, "_IO_FILE") == 0 || strcmp(name, "$FILE") == 0) flag |= CT_IS_FILE; return _b_struct_or_union_type("struct", name, flag); } diff --git a/c/test_c.py b/c/test_c.py --- a/c/test_c.py +++ b/c/test_c.py @@ -2582,7 +2582,7 @@ if sys.platform == "win32": py.test.skip("testing FILE not implemented") # - BFILE = new_struct_type("_IO_FILE") + BFILE = new_struct_type("$FILE") BFILEP = new_pointer_type(BFILE) BChar = new_primitive_type("char") BCharP = new_pointer_type(BChar) diff --git a/cffi/api.py b/cffi/api.py --- a/cffi/api.py +++ b/cffi/api.py @@ -71,7 +71,6 @@ if name.startswith('RTLD_'): setattr(self, name, getattr(backend, name)) # - self._parser._declarations['typedef FILE'] = model.file_type BVoidP = self._get_cached_btype(model.voidp_type) if isinstance(backend, types.ModuleType): # _cffi_backend: attach these constants to the class diff --git a/cffi/commontypes.py b/cffi/commontypes.py new file mode 100644 --- /dev/null +++ b/cffi/commontypes.py @@ -0,0 +1,246 @@ +import sys +from . import api, model + + +COMMON_TYPES = { + 'FILE': model.unknown_type('FILE', '_IO_FILE'), + 'bool': '_Bool', + } + +for _type in model.PrimitiveType.ALL_PRIMITIVE_TYPES: + if _type.endswith('_t'): + COMMON_TYPES[_type] = _type +del _type + +_CACHE = {} + +def resolve_common_type(commontype): + try: + return _CACHE[commontype] + except KeyError: + result = COMMON_TYPES.get(commontype, commontype) + if not isinstance(result, str): + pass # result is already a BaseType + elif result.endswith(' *'): + if result.startswith('const '): + result = model.ConstPointerType( + resolve_common_type(result[6:-2])) + else: + result = model.PointerType(resolve_common_type(result[:-2])) + elif result in model.PrimitiveType.ALL_PRIMITIVE_TYPES: + result = model.PrimitiveType(result) + else: + assert commontype != result + result = resolve_common_type(result) # recursively + assert isinstance(result, model.BaseTypeByIdentity) + _CACHE[commontype] = result + return result + + +# ____________________________________________________________ +# Windows common types + + +def win_common_types(maxsize): + result = {} + if maxsize < (1<<32): + result.update({ # Windows 32-bits + 'HALF_PTR': 'short', + 'INT_PTR': 'int', + 'LONG_PTR': 'long', + 'UHALF_PTR': 'unsigned short', + 'UINT_PTR': 'unsigned int', + 'ULONG_PTR': 'unsigned long', + }) + else: + result.update({ # Windows 64-bits + 'HALF_PTR': 'int', + 'INT_PTR': 'long long', + 'LONG_PTR': 'long long', + 'UHALF_PTR': 'unsigned int', + 'UINT_PTR': 'unsigned long long', + 'ULONG_PTR': 'unsigned long long', + }) + result.update({ + "BYTE": "unsigned char", + "BOOL": "int", + "CCHAR": "char", + "CHAR": "char", + "DWORD": "unsigned long", + "DWORD32": "unsigned int", + "DWORD64": "unsigned long long", + "FLOAT": "float", + "INT": "int", + "INT8": "signed char", + "INT16": "short", + "INT32": "int", + "INT64": "long long", + "LONG": "long", + "LONGLONG": "long long", + "LONG32": "int", + "LONG64": "long long", + "WORD": "unsigned short", + "PVOID": model.voidp_type, + "ULONGLONG": "unsigned long long", + "WCHAR": "wchar_t", + "SHORT": "short", + "TBYTE": "WCHAR", + "TCHAR": "WCHAR", + "UCHAR": "unsigned char", + "UINT": "unsigned int", + "UINT8": "unsigned char", + "UINT16": "unsigned short", + "UINT32": "unsigned int", + "UINT64": "unsigned long long", + "ULONG": "unsigned long", + "ULONG32": "unsigned int", + "ULONG64": "unsigned long long", + "USHORT": "unsigned short", + + "SIZE_T": "ULONG_PTR", + "SSIZE_T": "LONG_PTR", + "ATOM": "WORD", + "BOOLEAN": "BYTE", + "COLORREF": "DWORD", + + "HANDLE": "PVOID", + "DWORDLONG": "ULONGLONG", + "DWORD_PTR": "ULONG_PTR", + "HACCEL": "HANDLE", + + "HBITMAP": "HANDLE", + "HBRUSH": "HANDLE", + "HCOLORSPACE": "HANDLE", + "HCONV": "HANDLE", + "HCONVLIST": "HANDLE", + "HDC": "HANDLE", + "HDDEDATA": "HANDLE", + "HDESK": "HANDLE", + "HDROP": "HANDLE", + "HDWP": "HANDLE", + "HENHMETAFILE": "HANDLE", + "HFILE": "int", + "HFONT": "HANDLE", + "HGDIOBJ": "HANDLE", + "HGLOBAL": "HANDLE", + "HHOOK": "HANDLE", + "HICON": "HANDLE", + "HCURSOR": "HICON", + "HINSTANCE": "HANDLE", + "HKEY": "HANDLE", + "HKL": "HANDLE", + "HLOCAL": "HANDLE", + "HMENU": "HANDLE", + "HMETAFILE": "HANDLE", + "HMODULE": "HINSTANCE", + "HMONITOR": "HANDLE", + "HPALETTE": "HANDLE", + "HPEN": "HANDLE", + "HRESULT": "LONG", + "HRGN": "HANDLE", + "HRSRC": "HANDLE", + "HSZ": "HANDLE", + "WINSTA": "HANDLE", + "HWND": "HANDLE", + + "LANGID": "WORD", + "LCID": "DWORD", + "LCTYPE": "DWORD", + "LGRPID": "DWORD", + "LPARAM": "LONG_PTR", + "LPBOOL": "BOOL *", + "LPBYTE": "BYTE *", + "LPCOLORREF": "DWORD *", + "LPCSTR": "const char *", + + "LPCVOID": model.const_voidp_type, + "LPCWSTR": "const WCHAR *", + "LPCTSTR": "LPCWSTR", + "LPDWORD": "DWORD *", + "LPHANDLE": "HANDLE *", + "LPINT": "int *", + "LPLONG": "long *", + "LPSTR": "CHAR *", + "LPWSTR": "WCHAR *", + "LPTSTR": "LPWSTR", + "LPVOID": model.voidp_type, + "LPWORD": "WORD *", + "LRESULT": "LONG_PTR", + "PBOOL": "BOOL *", + "PBOOLEAN": "BOOLEAN *", + "PBYTE": "BYTE *", + "PCHAR": "CHAR *", + "PCSTR": "const CHAR *", + "PCTSTR": "LPCWSTR", + "PCWSTR": "const WCHAR *", + "PDWORD": "DWORD *", + "PDWORDLONG": "DWORDLONG *", + "PDWORD_PTR": "DWORD_PTR *", + "PDWORD32": "DWORD32 *", + "PDWORD64": "DWORD64 *", + "PFLOAT": "FLOAT *", + "PHALF_PTR": "HALF_PTR *", + "PHANDLE": "HANDLE *", + "PHKEY": "HKEY *", + "PINT": "int *", + "PINT_PTR": "INT_PTR *", + "PINT8": "INT8 *", + "PINT16": "INT16 *", + "PINT32": "INT32 *", + "PINT64": "INT64 *", + "PLCID": "PDWORD", + "PLONG": "LONG *", + "PLONGLONG": "LONGLONG *", + "PLONG_PTR": "LONG_PTR *", + "PLONG32": "LONG32 *", + "PLONG64": "LONG64 *", + "PSHORT": "SHORT *", + "PSIZE_T": "SIZE_T *", + "PSSIZE_T": "SSIZE_T *", + "PSTR": "CHAR *", + "PTBYTE": "TBYTE *", + "PTCHAR": "TCHAR *", + "PTSTR": "LPWSTR", + "PUCHAR": "UCHAR *", + "PUHALF_PTR": "UHALF_PTR *", + "PUINT": "UINT *", + "PUINT_PTR": "UINT_PTR *", + "PUINT8": "UINT8 *", + "PUINT16": "UINT16 *", + "PUINT32": "UINT32 *", + "PUINT64": "UINT64 *", + "PULONG": "ULONG *", + "PULONGLONG": "ULONGLONG *", + "PULONG_PTR": "ULONG_PTR *", + "PULONG32": "ULONG32 *", + "PULONG64": "ULONG64 *", + "PUSHORT": "USHORT *", + "PWCHAR": "WCHAR *", + "PWORD": "WORD *", + "PWSTR": "WCHAR *", + "QWORD": "unsigned long long", + "SC_HANDLE": "HANDLE", + "SC_LOCK": "LPVOID", + "SERVICE_STATUS_HANDLE": "HANDLE", + + "UNICODE_STRING": model.StructType( + "_UNICODE_STRING", + ["Length", + "MaximumLength", + "Buffer"], + [model.PrimitiveType("unsigned short"), + model.PrimitiveType("unsigned short"), + model.PointerType(model.PrimitiveType("wchar_t"))], + [-1, -1, -1]), + "PUNICODE_STRING": "UNICODE_STRING *", + "PCUNICODE_STRING": "const UNICODE_STRING *", + + "USN": "LONGLONG", + "VOID": model.void_type, + "WPARAM": "UINT_PTR", + }) + return result + + +if sys.platform == 'win32': + COMMON_TYPES.update(win_common_types(sys.maxsize)) diff --git a/cffi/cparser.py b/cffi/cparser.py --- a/cffi/cparser.py +++ b/cffi/cparser.py @@ -1,5 +1,6 @@ from . import api, model +from .commontypes import COMMON_TYPES, resolve_common_type import pycparser.c_parser, weakref, re, sys try: @@ -17,6 +18,7 @@ _r_partial_enum = re.compile(r"=\s*\.\.\.\s*[,}]|\.\.\.\s*\}") _r_enum_dotdotdot = re.compile(r"__dotdotdot\d+__$") _r_partial_array = re.compile(r"\[\s*\.\.\.\s*\]") +_r_words = re.compile(r"\w+|\S") _parser_cache = None def _get_parser(): @@ -58,10 +60,34 @@ # which is declared with a typedef for the purpose of C parsing. return csource.replace('...', ' __dotdotdot__ '), macros +def _common_type_names(csource): + # Look in the source for what looks like usages of types from the + # list of common types. A "usage" is approximated here as the + # appearance of the word, minus a "definition" of the type, which + # is the last word in a "typedef" statement. Approximative only + # but should be fine for all the common types. + look_for_words = set(COMMON_TYPES) + look_for_words.add(';') + look_for_words.add('typedef') + words_used = set() + is_typedef = False + previous_word = '' + for word in _r_words.findall(csource): + if word in look_for_words: + if word == ';': + if is_typedef: + words_used.discard(previous_word) + look_for_words.discard(previous_word) + is_typedef = False + elif word == 'typedef': + is_typedef = True + else: # word in COMMON_TYPES + words_used.add(word) + previous_word = word + return words_used + + class Parser(object): - TYPEDEFS = sorted( - [_name for _name in model.PrimitiveType.ALL_PRIMITIVE_TYPES - if _name.endswith('_t')]) def __init__(self): self._declarations = {} @@ -70,17 +96,23 @@ self._override = False def _parse(self, csource): + csource, macros = _preprocess(csource) # XXX: for more efficiency we would need to poke into the # internals of CParser... the following registers the # typedefs, because their presence or absence influences the # parsing itself (but what they are typedef'ed to plays no role) - typenames = self.TYPEDEFS[:] + ctn = _common_type_names(csource) + print `csource`, ctn + typenames = [] for name in sorted(self._declarations): if name.startswith('typedef '): - typenames.append(name[8:]) + name = name[8:] + typenames.append(name) + ctn.discard(name) + typenames += sorted(ctn) + # csourcelines = ['typedef int %s;' % typename for typename in typenames] csourcelines.append('typedef int __dotdotdot__;') - csource, macros = _preprocess(csource) csourcelines.append(csource) csource = '\n'.join(csourcelines) if lock is not None: @@ -267,7 +299,7 @@ return model.void_type if ident == '__dotdotdot__': raise api.FFIError('bad usage of "..."') - return model.PrimitiveType(ident) + return resolve_common_type(ident) # if isinstance(type, pycparser.c_ast.Struct): # 'struct foobar' diff --git a/cffi/model.py b/cffi/model.py --- a/cffi/model.py +++ b/cffi/model.py @@ -73,9 +73,9 @@ 'float': 'f', 'double': 'f', 'long double': 'f', - 'wchar_t': 'c', '_Bool': 'u', # the following types are not primitive in the C sense + 'wchar_t': 'c', 'int8_t': 'i', 'uint8_t': 'u', 'int16_t': 'i', @@ -183,6 +183,8 @@ BPtr = PointerType(self.totype).get_cached_btype(ffi, finishlist) return BPtr +const_voidp_type = ConstPointerType(void_type) + class NamedPointerType(PointerType): _attrs_ = ('totype', 'name') @@ -383,8 +385,6 @@ tp = StructType(structname, None, None, None) return NamedPointerType(tp, name) -file_type = unknown_type('FILE', '_IO_FILE') - def global_cache(srctype, ffi, funcname, *args, **kwds): key = kwds.pop('key', (funcname, args)) assert not kwds diff --git a/doc/source/index.rst b/doc/source/index.rst --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -390,25 +390,39 @@ * wchar_t (if supported by the backend) * *New in version 0.4:* _Bool. If not directly supported by the C compiler, - this is declared with the size of ``unsigned char``. Note that the - effects of ```` are not automatically included: you have - to say ``typedef _Bool bool;`` in your ``cdef()`` if you want to - use this ``_Bool`` with the more standard name ``bool``. This is because - some headers declare a different type (e.g. an enum) and also call it - ``bool``. + this is declared with the size of ``unsigned char``. + +* *New in version 0.6:* bool. In CFFI 0.4 or 0.5, you had to manually say + ``typedef _Bool bool;``. Now such a line is optional. * *New in version 0.4:* FILE. You can declare C functions taking a ``FILE *`` argument and call them with a Python file object. If needed, you can also do ``c_f = ffi.cast("FILE *", fileobj)`` and then pass around ``c_f``. -.. "versionadded:: 0.4": bool +* *New in version 0.6:* all `common Windows types`_ are defined if you run + on Windows (``DWORD``, ``LPARAM``, etc.). + +.. _`common Windows types`: http://msdn.microsoft.com/en-us/library/windows/desktop/aa383751%28v=vs.85%29.aspx + +.. "versionadded:: 0.4": _Bool +.. "versionadded:: 0.6": bool .. "versionadded:: 0.4": FILE +.. "versionadded:: 0.6": Wintypes As we will see on `the verification step`_ below, the declarations can also contain "``...``" at various places; these are placeholders that will be completed by a call to ``verify()``. +.. versionadded:: 0.6 + The standard type names listed above are now handled as *defaults* + only (apart from the ones that are keywords in the C language). + If your ``cdef`` contains an explicit typedef that redefines one of + the types above, then the default described above is ignored. (This + is a bit hard to implement cleanly, so in some corner cases it might + fail, notably with the error ``Multiple type specifiers with a type + tag``. Please report it as a bug if it does.) + Loading libraries ----------------- diff --git a/testing/test_parsing.py b/testing/test_parsing.py --- a/testing/test_parsing.py +++ b/testing/test_parsing.py @@ -208,3 +208,49 @@ assert str(e.value).startswith('cannot parse "foobarbazunknown*"') e = py.test.raises(CDefError, ffi.cast, "int(*)(foobarbazunknown)", 0) assert str(e.value).startswith('cannot parse "int(*)(foobarbazunknown)"') + +def test_redefine_common_type(): + ffi = FFI() + ffi.cdef("typedef char FILE;") + assert repr(ffi.cast("FILE", 123)) == "" + ffi.cdef("typedef char int32_t;") + assert repr(ffi.cast("int32_t", 123)) == "" + +def test_bool(): + ffi = FFI() + ffi.cdef("void f(bool);") + # + ffi = FFI() + ffi.cdef("typedef _Bool bool; void f(bool);") + +def test_win_common_types(): + from cffi.commontypes import COMMON_TYPES, _CACHE + from cffi.commontypes import win_common_types, resolve_common_type + # + def clear_all(extra={}, old_dict=COMMON_TYPES.copy()): + COMMON_TYPES.clear() + COMMON_TYPES.update(old_dict) + COMMON_TYPES.update(extra) + _CACHE.clear() + # + for maxsize in [2**32-1, 2**64-1]: + ct = win_common_types(maxsize) + clear_all(ct) + for key in sorted(ct): + resolve_common_type(key) + # assert did not crash + # now try to use e.g. WPARAM (-> UINT_PTR -> unsigned 32/64-bit) + for maxsize in [2**32-1, 2**64-1]: + ct = win_common_types(maxsize) + clear_all(ct) + ffi = FFI() + value = int(ffi.cast("WPARAM", -1)) + assert value == maxsize + # + clear_all() + +def test_WPARAM_on_windows(): + if sys.platform != 'win32': + py.test.skip("Only for Windows") + ffi = FFI() + ffi.cdef("void f(WPARAM);") diff --git a/testing/test_verify.py b/testing/test_verify.py --- a/testing/test_verify.py +++ b/testing/test_verify.py @@ -1258,6 +1258,7 @@ for sign in ['signed', 'unsigned']: type = '%s %s' % (sign, basetype) assert int(ffi.cast("_Bool", ffi.cast(type, 42))) == 1 + assert int(ffi.cast("bool", ffi.cast(type, 42))) == 1 assert int(ffi.cast("_Bool", ffi.cast(type, 0))) == 0 def test_addressof(): From noreply at buildbot.pypy.org Tue Feb 12 22:07:19 2013 From: noreply at buildbot.pypy.org (fijal) Date: Tue, 12 Feb 2013 22:07:19 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: fix this test Message-ID: <20130212210719.30E1B1C1198@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61144:a202d86f7287 Date: 2013-02-12 23:06 +0200 http://bitbucket.org/pypy/pypy/changeset/a202d86f7287/ Log: fix this test diff --git a/rpython/jit/backend/llsupport/test/test_runner.py b/rpython/jit/backend/llsupport/test/test_runner.py --- a/rpython/jit/backend/llsupport/test/test_runner.py +++ b/rpython/jit/backend/llsupport/test/test_runner.py @@ -22,6 +22,6 @@ # for the individual tests see # ====> ../../test/runner_test.py - - def setup_class(cls): - cls.cpu = MyLLCPU(rtyper=None, stats=FakeStats(), opts=None) + + def get_cpu(self): + return MyLLCPU(rtyper=None, stats=FakeStats(), opts=None) From noreply at buildbot.pypy.org Tue Feb 12 22:09:10 2013 From: noreply at buildbot.pypy.org (fijal) Date: Tue, 12 Feb 2013 22:09:10 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: test_gc for 32bit Message-ID: <20130212210910.7D0321C1047@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61145:839be53e2b6c Date: 2013-02-12 23:08 +0200 http://bitbucket.org/pypy/pypy/changeset/839be53e2b6c/ Log: test_gc for 32bit diff --git a/rpython/jit/backend/llsupport/test/test_gc.py b/rpython/jit/backend/llsupport/test/test_gc.py --- a/rpython/jit/backend/llsupport/test/test_gc.py +++ b/rpython/jit/backend/llsupport/test/test_gc.py @@ -299,9 +299,12 @@ assert all_addrs[6] == indexof(3) assert all_addrs[7] == indexof(5) assert all_addrs[8] == indexof(7) - assert all_addrs[9] == indexof(63) - # XXX 32bit - assert all_addrs[10] == indexof(65) + if sys.maxint == 2**31 - 1: + assert all_addrs[9] == indexof(31) + assert all_addrs[10] == indexof(33) + else: + assert all_addrs[9] == indexof(63) + assert all_addrs[10] == indexof(65) assert len(all_addrs) == 4 + 6 + 4 # 4 static fields, 4 addresses from gcmap, 2 from gcpattern From noreply at buildbot.pypy.org Tue Feb 12 22:10:36 2013 From: noreply at buildbot.pypy.org (mattip) Date: Tue, 12 Feb 2013 22:10:36 +0100 (CET) Subject: [pypy-commit] pypy default: test, add to_builtin_type for str Message-ID: <20130212211036.EED2F1C1053@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: Changeset: r61146:711464be0c98 Date: 2013-02-12 21:29 +0200 http://bitbucket.org/pypy/pypy/changeset/711464be0c98/ Log: test, add to_builtin_type for str diff --git a/pypy/module/micronumpy/test/test_numarray.py b/pypy/module/micronumpy/test/test_numarray.py --- a/pypy/module/micronumpy/test/test_numarray.py +++ b/pypy/module/micronumpy/test/test_numarray.py @@ -2195,6 +2195,8 @@ assert (a + a).item(1) == 4 raises(IndexError, "array(5).item(1)") assert array([1]).item() == 1 + a = array('x') + assert a.item() == 'x' def test_int_array_index(self): from _numpypy import array diff --git a/pypy/module/micronumpy/types.py b/pypy/module/micronumpy/types.py --- a/pypy/module/micronumpy/types.py +++ b/pypy/module/micronumpy/types.py @@ -1593,6 +1593,9 @@ def get_size(self): return self.size + def to_builtin_type(self, space, box): + return space.wrap(self.to_str(box)) + class StringType(BaseType, BaseStringType): T = lltype.Char From noreply at buildbot.pypy.org Tue Feb 12 22:23:24 2013 From: noreply at buildbot.pypy.org (fijal) Date: Tue, 12 Feb 2013 22:23:24 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: floats come at even places, always Message-ID: <20130212212324.6816B1C11A8@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61147:2b18ceeedd8f Date: 2013-02-12 23:22 +0200 http://bitbucket.org/pypy/pypy/changeset/2b18ceeedd8f/ Log: floats come at even places, always diff --git a/rpython/jit/backend/llsupport/test/test_rewrite.py b/rpython/jit/backend/llsupport/test/test_rewrite.py --- a/rpython/jit/backend/llsupport/test/test_rewrite.py +++ b/rpython/jit/backend/llsupport/test/test_rewrite.py @@ -72,7 +72,7 @@ casmdescr = JitCellToken() clt = FakeLoopToken() - clt._ll_initial_locs = [0, WORD] + clt._ll_initial_locs = [0, 8] frame_info = lltype.malloc(jitframe.JITFRAMEINFO, flavor='raw') clt.frame_info = frame_info frame_info.jfi_frame_depth = 13 From noreply at buildbot.pypy.org Tue Feb 12 22:40:43 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Tue, 12 Feb 2013 22:40:43 +0100 (CET) Subject: [pypy-commit] pypy default: backout ee04c61f776b to fix MemoryErrors in string tests Message-ID: <20130212214043.410641C1047@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61148:f5a9767fd636 Date: 2013-02-12 16:37 -0500 http://bitbucket.org/pypy/pypy/changeset/f5a9767fd636/ Log: backout ee04c61f776b to fix MemoryErrors in string tests diff --git a/rpython/rlib/rstring.py b/rpython/rlib/rstring.py --- a/rpython/rlib/rstring.py +++ b/rpython/rlib/rstring.py @@ -3,7 +3,6 @@ from rpython.annotator.model import (SomeObject, SomeString, s_None, SomeChar, SomeInteger, SomeUnicodeCodePoint, SomeUnicodeString, SomePtr, SomePBC) -from rpython.rlib.objectmodel import newlist_hint from rpython.rlib.rarithmetic import ovfcheck from rpython.rtyper.extregistry import ExtRegistryEntry from rpython.tool.pairtype import pairtype @@ -15,10 +14,7 @@ if bylen == 0: raise ValueError("empty separator") - if maxsplit > 0: - res = newlist_hint(maxsplit) - else: - res = [] + res = [] start = 0 while maxsplit != 0: next = value.find(by, start) @@ -31,12 +27,8 @@ res.append(value[start:len(value)]) return res - def rsplit(value, by, maxsplit=-1): - if maxsplit > 0: - res = newlist_hint(maxsplit) - else: - res = [] + res = [] end = len(value) bylen = len(by) if bylen == 0: From noreply at buildbot.pypy.org Tue Feb 12 22:51:26 2013 From: noreply at buildbot.pypy.org (amauryfa) Date: Tue, 12 Feb 2013 22:51:26 +0100 (CET) Subject: [pypy-commit] pypy missing-os-functions: A branch to expose all posix functions supported by the platform, Message-ID: <20130212215126.4DEB11C1047@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: missing-os-functions Changeset: r61149:6daaf21d82ff Date: 2013-02-12 21:34 +0100 http://bitbucket.org/pypy/pypy/changeset/6daaf21d82ff/ Log: A branch to expose all posix functions supported by the platform, even when the hosting Python does not have them. From noreply at buildbot.pypy.org Tue Feb 12 22:51:27 2013 From: noreply at buildbot.pypy.org (amauryfa) Date: Tue, 12 Feb 2013 22:51:27 +0100 (CET) Subject: [pypy-commit] pypy missing-os-functions: Use explicit names for posix functions and methods. Message-ID: <20130212215127.A68ED1C1047@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: missing-os-functions Changeset: r61150:0a0abe7ca7a4 Date: 2013-02-12 22:43 +0100 http://bitbucket.org/pypy/pypy/changeset/0a0abe7ca7a4/ Log: Use explicit names for posix functions and methods. It still relies on host Python for configuration, though diff --git a/pypy/module/posix/__init__.py b/pypy/module/posix/__init__.py --- a/pypy/module/posix/__init__.py +++ b/pypy/module/posix/__init__.py @@ -33,13 +33,13 @@ applevel_name = os.name appleveldefs = { - 'error' : 'app_posix.error', - 'stat_result': 'app_posix.stat_result', - 'fdopen' : 'app_posix.fdopen', - 'tmpfile' : 'app_posix.tmpfile', - 'popen' : 'app_posix.popen', - 'tmpnam' : 'app_posix.tmpnam', - 'tempnam' : 'app_posix.tempnam', + 'error' : 'app_posix.error', + 'stat_result': 'app_posix.stat_result', + 'fdopen' : 'app_posix.fdopen', + 'tmpfile' : 'app_posix.tmpfile', + 'popen' : 'app_posix.popen', + 'tmpnam' : 'app_posix.tmpnam', + 'tempnam' : 'app_posix.tempnam', } if os.name == 'nt': appleveldefs.update({ @@ -47,140 +47,92 @@ 'popen3' : 'app_posix.popen3', 'popen4' : 'app_posix.popen4', }) - - if hasattr(os, 'wait'): + if hasattr(posix, 'wait'): appleveldefs['wait'] = 'app_posix.wait' - if hasattr(os, 'wait3'): + if hasattr(posix, 'wait3'): appleveldefs['wait3'] = 'app_posix.wait3' - if hasattr(os, 'wait4'): + if hasattr(posix, 'wait4'): appleveldefs['wait4'] = 'app_posix.wait4' + # Functions implemented on all platforms interpleveldefs = { - 'open' : 'interp_posix.open', - 'lseek' : 'interp_posix.lseek', - 'write' : 'interp_posix.write', - 'isatty' : 'interp_posix.isatty', - 'read' : 'interp_posix.read', - 'close' : 'interp_posix.close', - 'closerange': 'interp_posix.closerange', - 'fstat' : 'interp_posix.fstat', - 'stat' : 'interp_posix.stat', - 'lstat' : 'interp_posix.lstat', - 'stat_float_times' : 'interp_posix.stat_float_times', - 'dup' : 'interp_posix.dup', - 'dup2' : 'interp_posix.dup2', - 'access' : 'interp_posix.access', - 'times' : 'interp_posix.times', - 'system' : 'interp_posix.system', - 'unlink' : 'interp_posix.unlink', - 'remove' : 'interp_posix.remove', - 'getcwd' : 'interp_posix.getcwd', - 'getcwdu' : 'interp_posix.getcwdu', - 'chdir' : 'interp_posix.chdir', - 'mkdir' : 'interp_posix.mkdir', - 'rmdir' : 'interp_posix.rmdir', - 'environ' : 'interp_posix.get(space).w_environ', - 'listdir' : 'interp_posix.listdir', - 'strerror' : 'interp_posix.strerror', - 'pipe' : 'interp_posix.pipe', - 'chmod' : 'interp_posix.chmod', - 'rename' : 'interp_posix.rename', - 'umask' : 'interp_posix.umask', - '_exit' : 'interp_posix._exit', - 'utime' : 'interp_posix.utime', - '_statfields': 'interp_posix.getstatfields(space)', - 'kill' : 'interp_posix.kill', - 'abort' : 'interp_posix.abort', - 'urandom' : 'interp_posix.urandom', - } + 'open' : 'interp_posix.open', + 'lseek' : 'interp_posix.lseek', + 'write' : 'interp_posix.write', + 'isatty' : 'interp_posix.isatty', + 'read' : 'interp_posix.read', + 'close' : 'interp_posix.close', + 'closerange': 'interp_posix.closerange', + 'fstat' : 'interp_posix.fstat', + 'stat' : 'interp_posix.stat', + 'lstat' : 'interp_posix.lstat', + 'stat_float_times' : 'interp_posix.stat_float_times', + 'dup' : 'interp_posix.dup', + 'dup2' : 'interp_posix.dup2', + 'access' : 'interp_posix.access', + 'times' : 'interp_posix.times', + 'system' : 'interp_posix.system', + 'unlink' : 'interp_posix.unlink', + 'remove' : 'interp_posix.remove', + 'getcwd' : 'interp_posix.getcwd', + 'getcwdu' : 'interp_posix.getcwdu', + 'chdir' : 'interp_posix.chdir', + 'mkdir' : 'interp_posix.mkdir', + 'rmdir' : 'interp_posix.rmdir', + 'environ' : 'interp_posix.get(space).w_environ', + 'listdir' : 'interp_posix.listdir', + 'strerror' : 'interp_posix.strerror', + 'pipe' : 'interp_posix.pipe', + 'chmod' : 'interp_posix.chmod', + 'rename' : 'interp_posix.rename', + 'umask' : 'interp_posix.umask', + '_exit' : 'interp_posix._exit', + 'utime' : 'interp_posix.utime', + '_statfields': 'interp_posix.getstatfields(space)', + 'kill' : 'interp_posix.kill', + 'abort' : 'interp_posix.abort', + 'urandom' : 'interp_posix.urandom', + } - if hasattr(os, 'chown'): - interpleveldefs['chown'] = 'interp_posix.chown' - if hasattr(os, 'lchown'): - interpleveldefs['lchown'] = 'interp_posix.lchown' - if hasattr(os, 'fchown'): - interpleveldefs['fchown'] = 'interp_posix.fchown' - if hasattr(os, 'fchmod'): - interpleveldefs['fchmod'] = 'interp_posix.fchmod' - if hasattr(os, 'ftruncate'): - interpleveldefs['ftruncate'] = 'interp_posix.ftruncate' - if hasattr(os, 'fsync'): - interpleveldefs['fsync'] = 'interp_posix.fsync' - if hasattr(os, 'fdatasync'): - interpleveldefs['fdatasync'] = 'interp_posix.fdatasync' - if hasattr(os, 'fchdir'): - interpleveldefs['fchdir'] = 'interp_posix.fchdir' - if hasattr(os, 'putenv'): - interpleveldefs['putenv'] = 'interp_posix.putenv' - if hasattr(posix, 'unsetenv'): # note: emulated in os - interpleveldefs['unsetenv'] = 'interp_posix.unsetenv' - if hasattr(os, 'killpg'): - interpleveldefs['killpg'] = 'interp_posix.killpg' - if hasattr(os, 'getpid'): - interpleveldefs['getpid'] = 'interp_posix.getpid' - if hasattr(os, 'link'): - interpleveldefs['link'] = 'interp_posix.link' - if hasattr(os, 'symlink'): - interpleveldefs['symlink'] = 'interp_posix.symlink' - if hasattr(os, 'readlink'): - interpleveldefs['readlink'] = 'interp_posix.readlink' - if hasattr(os, 'fork'): - interpleveldefs['fork'] = 'interp_posix.fork' - if hasattr(os, 'openpty'): - interpleveldefs['openpty'] = 'interp_posix.openpty' - if hasattr(os, 'forkpty'): - interpleveldefs['forkpty'] = 'interp_posix.forkpty' - if hasattr(os, 'waitpid'): - interpleveldefs['waitpid'] = 'interp_posix.waitpid' - if hasattr(os, 'execv'): - interpleveldefs['execv'] = 'interp_posix.execv' - if hasattr(os, 'execve'): - interpleveldefs['execve'] = 'interp_posix.execve' - if hasattr(posix, 'spawnv'): - interpleveldefs['spawnv'] = 'interp_posix.spawnv' - if hasattr(posix, 'spawnve'): - interpleveldefs['spawnve'] = 'interp_posix.spawnve' - if hasattr(os, 'uname'): - interpleveldefs['uname'] = 'interp_posix.uname' - if hasattr(os, 'sysconf'): - interpleveldefs['sysconf'] = 'interp_posix.sysconf' + for name in ''' + wait wait3 wait4 chown lchown fchown fchmod ftruncate + fsync fdatasync fchdir putenv unsetenv killpg getpid + link symlink readlink + fork openpty forkpty waitpid execv execve uname sysconf fpathconf + ttyname getloadavg makedev major minor mkfifo mknod nice getlogin + getsid getuid geteuid getgid getegid getpgrp getpgid + setsid setuid seteuid setgid setegid setpgrp setpgid + getppid getgroups setreuid setregid chroot + _getfullpathname + '''.split(): + if hasattr(posix, name): + interpleveldefs[name] = 'interp_posix.%s' % (name,) + + for constant in ''' + F_OK R_OK W_OK X_OK NGROUPS_MAX TMP_MAX + WNOHANG WCONTINUED WUNTRACED + O_RDONLY O_WRONLY O_RDWR O_NDELAY O_NONBLOCK O_APPEND + O_DSYNC O_RSYNC O_SYNC O_NOCTTY O_CREAT O_EXCL O_TRUNC + O_BINARY O_TEXT O_LARGEFILE O_SHLOCK O_EXLOCK + O_NOINHERIT O_TEMPORARY O_RANDOM O_SEQUENTIAL + O_ASYNC O_DIRECT O_DIRECTORY O_NOFOLLOW O_NOATIME + EX_OK EX_USAGE EX_DATAERR EX_NOINPUT EX_NOUSER EX_NOHOST + EX_UNAVAILABLE EX_SOFTWARE EX_OSERR EX_OSFILE EX_CANTCREAT + EX_IOERR EX_TEMPFAIL EX_PROTOCOL EX_NOPERM EX_CONFIG EX_NOTFOUND + '''.split(): + if hasattr(posix, constant): + value = getattr(posix, constant) + interpleveldefs[constant] = "space.wrap(%s)" % value + + # XXX don't use the os module here + if 'sysconf' in interpleveldefs: interpleveldefs['sysconf_names'] = 'space.wrap(os.sysconf_names)' - if hasattr(os, 'fpathconf'): - interpleveldefs['fpathconf'] = 'interp_posix.fpathconf' + if 'fpathconf' in interpleveldefs: interpleveldefs['pathconf_names'] = 'space.wrap(os.pathconf_names)' - if hasattr(os, 'ttyname'): - interpleveldefs['ttyname'] = 'interp_posix.ttyname' - if hasattr(os, 'getloadavg'): - interpleveldefs['getloadavg'] = 'interp_posix.getloadavg' - if hasattr(os, 'makedev'): - interpleveldefs['makedev'] = 'interp_posix.makedev' - if hasattr(os, 'major'): - interpleveldefs['major'] = 'interp_posix.major' - if hasattr(os, 'minor'): - interpleveldefs['minor'] = 'interp_posix.minor' - if hasattr(os, 'mkfifo'): - interpleveldefs['mkfifo'] = 'interp_posix.mkfifo' - if hasattr(os, 'mknod'): - interpleveldefs['mknod'] = 'interp_posix.mknod' - if hasattr(os, 'nice'): - interpleveldefs['nice'] = 'interp_posix.nice' - if hasattr(os, 'getlogin'): - interpleveldefs['getlogin'] = 'interp_posix.getlogin' - for name in ['setsid', 'getuid', 'geteuid', 'getgid', 'getegid', 'setuid', - 'seteuid', 'setgid', 'setegid', 'getgroups', 'getpgrp', - 'setpgrp', 'getppid', 'getpgid', 'setpgid', 'setreuid', - 'setregid', 'getsid', 'setsid']: - if hasattr(os, name): - interpleveldefs[name] = 'interp_posix.%s' % (name,) - # not visible via os, inconsistency in nt: - if hasattr(posix, '_getfullpathname'): - interpleveldefs['_getfullpathname'] = 'interp_posix._getfullpathname' - if hasattr(os, 'chroot'): - interpleveldefs['chroot'] = 'interp_posix.chroot' - + # Macros for process exit statuses: WIFEXITED &co for name in RegisterOs.w_star: - if hasattr(os, name): + if hasattr(posix, name): interpleveldefs[name] = 'interp_posix.' + name def __init__(self, space, w_name): @@ -195,8 +147,3 @@ def startup(self, space): from pypy.module.posix import interp_posix interp_posix.get(space).startup(space) - -for constant in dir(os): - value = getattr(os, constant) - if constant.isupper() and type(value) is int: - Module.interpleveldefs[constant] = "space.wrap(%s)" % value diff --git a/pypy/module/posix/test/test_posix2.py b/pypy/module/posix/test/test_posix2.py --- a/pypy/module/posix/test/test_posix2.py +++ b/pypy/module/posix/test/test_posix2.py @@ -92,6 +92,15 @@ def test_posix_is_pypy_s(self): assert self.posix.__file__ + def test_expected_functions(self): + import sys + if sys.platform.startswith('linux'): + for name in '''fork wait wait3 wait4 fchown fchmod'''.split(): + assert name in dir(self.posix) + if sys.platform.startswith('win32'): + for name in '''_getfullpathname O_TEXT O_BINARY'''.split(): + assert name in dir(self.posix) + def test_some_posix_basic_operation(self): path = self.path posix = self.posix From noreply at buildbot.pypy.org Tue Feb 12 22:55:27 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Tue, 12 Feb 2013 22:55:27 +0100 (CET) Subject: [pypy-commit] pypy default: (fijal, agaynor) another try at presizing Message-ID: <20130212215527.598961C1047@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61151:2924a59b74ba Date: 2013-02-12 16:54 -0500 http://bitbucket.org/pypy/pypy/changeset/2924a59b74ba/ Log: (fijal, agaynor) another try at presizing diff --git a/rpython/rlib/rstring.py b/rpython/rlib/rstring.py --- a/rpython/rlib/rstring.py +++ b/rpython/rlib/rstring.py @@ -3,6 +3,7 @@ from rpython.annotator.model import (SomeObject, SomeString, s_None, SomeChar, SomeInteger, SomeUnicodeCodePoint, SomeUnicodeString, SomePtr, SomePBC) +from rpython.rlib.objectmodel import newlist_hint from rpython.rlib.rarithmetic import ovfcheck from rpython.rtyper.extregistry import ExtRegistryEntry from rpython.tool.pairtype import pairtype @@ -14,7 +15,10 @@ if bylen == 0: raise ValueError("empty separator") - res = [] + if maxsplit > 0: + res = newlist_hint(min(maxsplit, len(value))) + else: + res = [] start = 0 while maxsplit != 0: next = value.find(by, start) @@ -27,8 +31,12 @@ res.append(value[start:len(value)]) return res + def rsplit(value, by, maxsplit=-1): - res = [] + if maxsplit > 0: + res = newlist_hint(min(maxsplit, len(value))) + else: + res = [] end = len(value) bylen = len(by) if bylen == 0: From noreply at buildbot.pypy.org Tue Feb 12 23:13:27 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Tue, 12 Feb 2013 23:13:27 +0100 (CET) Subject: [pypy-commit] pypy py3k: kill! Message-ID: <20130212221327.401A51C1047@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61152:cff1d143164c Date: 2013-02-12 14:06 -0800 http://bitbucket.org/pypy/pypy/changeset/cff1d143164c/ Log: kill! diff --git a/pypy/objspace/std/dictmultiobject.py b/pypy/objspace/std/dictmultiobject.py --- a/pypy/objspace/std/dictmultiobject.py +++ b/pypy/objspace/std/dictmultiobject.py @@ -862,49 +862,6 @@ return space.w_False return space.w_True -def characterize(space, w_a, w_b): - """ (similar to CPython) - returns the smallest key in acontent for which b's value is different or absent and this value """ - w_smallest_diff_a_key = None - w_its_value = None - iteratorimplementation = w_a.iteritems() - while 1: - w_key, w_val = iteratorimplementation.next_item() - if w_key is None: - break - if w_smallest_diff_a_key is None or space.is_true(space.lt(w_key, w_smallest_diff_a_key)): - w_bvalue = w_b.getitem(w_key) - if w_bvalue is None: - w_its_value = w_val - w_smallest_diff_a_key = w_key - else: - if not space.eq_w(w_val, w_bvalue): - w_its_value = w_val - w_smallest_diff_a_key = w_key - return w_smallest_diff_a_key, w_its_value - -def lt__DictMulti_DictMulti(space, w_left, w_right): - # Different sizes, no problem - if w_left.length() < w_right.length(): - return space.w_True - if w_left.length() > w_right.length(): - return space.w_False - - # Same size - w_leftdiff, w_leftval = characterize(space, w_left, w_right) - if w_leftdiff is None: - return space.w_False - w_rightdiff, w_rightval = characterize(space, w_right, w_left) - if w_rightdiff is None: - # w_leftdiff is not None, w_rightdiff is None - return space.w_True - w_res = space.lt(w_leftdiff, w_rightdiff) - if (not space.is_true(w_res) and - space.eq_w(w_leftdiff, w_rightdiff) and - w_rightval is not None): - w_res = space.lt(w_leftval, w_rightval) - return w_res - def dict_copy__DictMulti(space, w_self): w_new = W_DictMultiObject.allocate_and_init_instance(space) update1_dict_dict(space, w_new, w_self) diff --git a/pypy/objspace/std/test/test_dictmultiobject.py b/pypy/objspace/std/test/test_dictmultiobject.py --- a/pypy/objspace/std/test/test_dictmultiobject.py +++ b/pypy/objspace/std/test/test_dictmultiobject.py @@ -387,27 +387,13 @@ bool = d1 != d3 assert bool == True - def test_lt(self): + def test_richcompare(self): + import operator d1 = {1: 2, 3: 4} - d2 = {1: 2, 3: 4} - d3 = {1: 2, 3: 5} - d4 = {1: 2} - bool = d1 < d2 - assert bool == False - bool = d1 < d3 - assert bool == True - bool = d1 < d4 - assert bool == False - - def test_lt2(self): - assert {'a': 1 } < { 'a': 2 } - assert not {'a': 1 } > { 'a': 2 } - assert not {'a': 1, 'b': 0 } > { 'a': 2, 'b': 0 } - assert {'a': 1, 'b': 0 } < { 'a': 2, 'b': 0 } - assert {'a': 1, 'b': 0 } < { 'a': 1, 'b': 2 } - assert not {'a': 1, 'b': 0 } < { 'a': 1, 'b': -2 } - assert {'a': 1 } < { 'b': 1} - assert {'a': 1, 'x': 2 } < { 'b': 1, 'x': 2} + d2 = {1: 2, 3: 5} + for op in 'lt', 'le', 'gt', 'ge': + f = getattr(operator, op) + raises(TypeError, f, d1, d2) def test_str_repr(self): assert '{}' == str({}) From noreply at buildbot.pypy.org Tue Feb 12 23:13:28 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Tue, 12 Feb 2013 23:13:28 +0100 (CET) Subject: [pypy-commit] pypy py3k: regrtest.replace_stdout carelessly changes stdout's name attrib, fix it to Message-ID: <20130212221328.87DE81C1047@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61153:27dc4381e169 Date: 2013-02-12 14:10 -0800 http://bitbucket.org/pypy/pypy/changeset/27dc4381e169/ Log: regrtest.replace_stdout carelessly changes stdout's name attrib, fix it to happen before import so its consistent w/ the test run diff --git a/pypy/tool/pytest/run-script/regrverbose.py b/pypy/tool/pytest/run-script/regrverbose.py --- a/pypy/tool/pytest/run-script/regrverbose.py +++ b/pypy/tool/pytest/run-script/regrverbose.py @@ -8,10 +8,10 @@ modname = sys.argv[0] impname = 'test.' + modname try: + regrtest.replace_stdout() mod = __import__(impname, globals(), locals(), [modname]) indirect_test = getattr(mod, 'test_main', None) if indirect_test is not None: - regrtest.replace_stdout() indirect_test() except unittest.SkipTest: sys.stderr.write("="*26 + "skipped" + "="*26 + "\n") From noreply at buildbot.pypy.org Tue Feb 12 23:17:24 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Tue, 12 Feb 2013 23:17:24 +0100 (CET) Subject: [pypy-commit] pypy default: (amaury) presize to maxsplit + 1 not maxsplit Message-ID: <20130212221724.79F291C1047@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61154:2db1e1e6b77e Date: 2013-02-12 17:16 -0500 http://bitbucket.org/pypy/pypy/changeset/2db1e1e6b77e/ Log: (amaury) presize to maxsplit + 1 not maxsplit diff --git a/rpython/rlib/rstring.py b/rpython/rlib/rstring.py --- a/rpython/rlib/rstring.py +++ b/rpython/rlib/rstring.py @@ -16,7 +16,7 @@ raise ValueError("empty separator") if maxsplit > 0: - res = newlist_hint(min(maxsplit, len(value))) + res = newlist_hint(min(maxsplit + 1, len(value))) else: res = [] start = 0 @@ -34,7 +34,7 @@ def rsplit(value, by, maxsplit=-1): if maxsplit > 0: - res = newlist_hint(min(maxsplit, len(value))) + res = newlist_hint(min(maxsplit + 1, len(value))) else: res = [] end = len(value) From noreply at buildbot.pypy.org Tue Feb 12 23:20:49 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Tue, 12 Feb 2013 23:20:49 +0100 (CET) Subject: [pypy-commit] pypy default: backout 711464be0c98, breaks translation Message-ID: <20130212222049.4EF211C1047@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61155:717502002276 Date: 2013-02-12 17:20 -0500 http://bitbucket.org/pypy/pypy/changeset/717502002276/ Log: backout 711464be0c98, breaks translation diff --git a/pypy/module/micronumpy/test/test_numarray.py b/pypy/module/micronumpy/test/test_numarray.py --- a/pypy/module/micronumpy/test/test_numarray.py +++ b/pypy/module/micronumpy/test/test_numarray.py @@ -2195,8 +2195,6 @@ assert (a + a).item(1) == 4 raises(IndexError, "array(5).item(1)") assert array([1]).item() == 1 - a = array('x') - assert a.item() == 'x' def test_int_array_index(self): from _numpypy import array diff --git a/pypy/module/micronumpy/types.py b/pypy/module/micronumpy/types.py --- a/pypy/module/micronumpy/types.py +++ b/pypy/module/micronumpy/types.py @@ -1593,9 +1593,6 @@ def get_size(self): return self.size - def to_builtin_type(self, space, box): - return space.wrap(self.to_str(box)) - class StringType(BaseType, BaseStringType): T = lltype.Char From noreply at buildbot.pypy.org Tue Feb 12 23:29:19 2013 From: noreply at buildbot.pypy.org (mattip) Date: Tue, 12 Feb 2013 23:29:19 +0100 (CET) Subject: [pypy-commit] pypy default: test, implement to_builtin_type for StringType Message-ID: <20130212222919.DEB4C1C1047@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: Changeset: r61156:c99336a795d3 Date: 2013-02-13 00:25 +0200 http://bitbucket.org/pypy/pypy/changeset/c99336a795d3/ Log: test, implement to_builtin_type for StringType diff --git a/pypy/module/micronumpy/test/test_numarray.py b/pypy/module/micronumpy/test/test_numarray.py --- a/pypy/module/micronumpy/test/test_numarray.py +++ b/pypy/module/micronumpy/test/test_numarray.py @@ -2195,6 +2195,8 @@ assert (a + a).item(1) == 4 raises(IndexError, "array(5).item(1)") assert array([1]).item() == 1 + a = array('x') + assert a.item() == 'x' def test_int_array_index(self): from _numpypy import array diff --git a/pypy/module/micronumpy/types.py b/pypy/module/micronumpy/types.py --- a/pypy/module/micronumpy/types.py +++ b/pypy/module/micronumpy/types.py @@ -1637,6 +1637,10 @@ builder.append("'") return builder.build() + # XXX move to base class when UnicodeType is supported + def to_builtin_type(self, space, box): + return space.wrap(self.to_str(box)) + class VoidType(BaseType, BaseStringType): T = lltype.Char From noreply at buildbot.pypy.org Wed Feb 13 01:44:06 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Wed, 13 Feb 2013 01:44:06 +0100 (CET) Subject: [pypy-commit] pypy default: fix whatsnew Message-ID: <20130213004406.B9B761C0471@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61157:df3aa2beb60f Date: 2013-02-12 19:40 -0500 http://bitbucket.org/pypy/pypy/changeset/df3aa2beb60f/ Log: fix whatsnew diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst --- a/pypy/doc/whatsnew-head.rst +++ b/pypy/doc/whatsnew-head.rst @@ -58,3 +58,6 @@ .. branch: cleanup-tests Consolidated the lib_pypy/pypy_test and pypy/module/test_lib_pypy tests into +one directory for reduced confusion and so they all run nightly. + +.. branch: unquote-faster +.. branch: urlparse-unquote-faster From noreply at buildbot.pypy.org Wed Feb 13 03:16:33 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Wed, 13 Feb 2013 03:16:33 +0100 (CET) Subject: [pypy-commit] pypy py3k: update rich comparisons Message-ID: <20130213021633.792DC1C0471@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61158:46552d7beaa9 Date: 2013-02-12 18:14 -0800 http://bitbucket.org/pypy/pypy/changeset/46552d7beaa9/ Log: update rich comparisons diff --git a/pypy/interpreter/astcompiler/test/test_compiler.py b/pypy/interpreter/astcompiler/test/test_compiler.py --- a/pypy/interpreter/astcompiler/test/test_compiler.py +++ b/pypy/interpreter/astcompiler/test/test_compiler.py @@ -668,8 +668,8 @@ #cmp self.assert_(p == p) self.assert_(d == d) - self.assert_(p < d) - self.assert_(d > p) + self.failUnlessRaises(TypeError, lambda: p < d) + self.failUnlessRaises(TypeError, lambda: d > p) #__non__zero__ if p: self.fail("Empty mapping must compare to False") if not d: self.fail("Full mapping must compare to True") From noreply at buildbot.pypy.org Wed Feb 13 07:33:45 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Wed, 13 Feb 2013 07:33:45 +0100 (CET) Subject: [pypy-commit] pypy default: test and fix for _io buffering: in buffer back seeks shouldn't trash the buffer Message-ID: <20130213063345.B01CE1C1244@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61159:fa3dd6e22b8c Date: 2013-02-13 00:21 -0500 http://bitbucket.org/pypy/pypy/changeset/fa3dd6e22b8c/ Log: test and fix for _io buffering: in buffer back seeks shouldn't trash the buffer just because we have no forward buffer diff --git a/pypy/module/_io/interp_bufferedio.py b/pypy/module/_io/interp_bufferedio.py --- a/pypy/module/_io/interp_bufferedio.py +++ b/pypy/module/_io/interp_bufferedio.py @@ -268,16 +268,15 @@ self._raw_tell(space) current = self.abs_pos available = self._readahead() - if available > 0: - if whence == 0: - offset = pos - (current - self._raw_offset()) - else: - offset = pos - if -self.pos <= offset <= available: - newpos = self.pos + offset - assert newpos >= 0 - self.pos = newpos - return space.wrap(current - available + offset) + if whence == 0: + offset = pos - (current - self._raw_offset()) + else: + offset = pos + if -self.pos <= offset <= available: + newpos = self.pos + offset + assert newpos >= 0 + self.pos = newpos + return space.wrap(current - available + offset) # Fallback: invoke raw seek() method and clear buffer with self.lock: diff --git a/pypy/module/_io/test/test_bufferedio.py b/pypy/module/_io/test/test_bufferedio.py --- a/pypy/module/_io/test/test_bufferedio.py +++ b/pypy/module/_io/test/test_bufferedio.py @@ -153,6 +153,19 @@ assert f.read() == "\nc" f.close() + def test_seek_nocall(self): + # test that when we're at the end of the buffer, + # an in-buffer back seek doesn't produce a raw seek + import _io + raw = _io.FileIO(self.tmpfile) + f = _io.BufferedReader(raw, buffer_size=3) + f.read(1) + f.seek(3, 0) + def failing_seek(*args): + assert False + raw.seek = failing_seek + f.seek(-1, 1) + def test_readlines(self): import _io raw = _io.FileIO(self.tmpfile) From noreply at buildbot.pypy.org Wed Feb 13 07:33:46 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Wed, 13 Feb 2013 07:33:46 +0100 (CET) Subject: [pypy-commit] pypy default: fix this test: it wasn't testing what it claimed to because it was constructing Message-ID: <20130213063346.F2A3A1C1244@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61160:1aa187fce1db Date: 2013-02-13 00:30 -0500 http://bitbucket.org/pypy/pypy/changeset/1aa187fce1db/ Log: fix this test: it wasn't testing what it claimed to because it was constructing seekable sources for a no-seek-available test diff --git a/rpython/rlib/test/test_streamio.py b/rpython/rlib/test/test_streamio.py --- a/rpython/rlib/test/test_streamio.py +++ b/rpython/rlib/test/test_streamio.py @@ -12,18 +12,24 @@ class TSource(streamio.Stream): - def __init__(self, packets): + def __init__(self, packets, tell=True, seek=True): for x in packets: assert x self.orig_packets = packets[:] self.packets = packets[:] self.pos = 0 self.chunks = [] + self._tell = tell + self._seek = seek def tell(self): + if not self._tell: + raise streamio.MyNotImplementedError return self.pos def seek(self, offset, whence=0): + if not self._seek: + raise streamio.MyNotImplementedError if whence == 1: offset += self.pos elif whence == 2: @@ -391,7 +397,7 @@ cases = cases[:7] # pick some cases at random - too slow! def f(): for readto, seekto, whence in cases: - base = TSource(self.packets) + base = TSource(self.packets, seek=False) file = streamio.BufferingInputStream(base) head = file.read(readto) assert head == all[:readto] From noreply at buildbot.pypy.org Wed Feb 13 07:33:48 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Wed, 13 Feb 2013 07:33:48 +0100 (CET) Subject: [pypy-commit] pypy default: improve this test to also test failures on backwards seeks when no raw seek is available Message-ID: <20130213063348.49B571C1244@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61161:bca3a1371847 Date: 2013-02-13 00:41 -0500 http://bitbucket.org/pypy/pypy/changeset/bca3a1371847/ Log: improve this test to also test failures on backwards seeks when no raw seek is available diff --git a/rpython/rlib/test/test_streamio.py b/rpython/rlib/test/test_streamio.py --- a/rpython/rlib/test/test_streamio.py +++ b/rpython/rlib/test/test_streamio.py @@ -390,7 +390,7 @@ all = file.readall() end = len(all) cases = [(readto, seekto, whence) for readto in range(0, end+1) - for seekto in range(readto, end+1) + for seekto in range(0, end+1) for whence in [1, 2]] random.shuffle(cases) if isinstance(self, (LLRtypeMixin, OORtypeMixin)): @@ -406,9 +406,19 @@ offset = seekto - readto elif whence == 2: offset = seekto - end - file.seek(offset, whence) - rest = file.readall() - assert rest == all[seekto:] + if whence == 2 and seekto < file.tell() or seekto < file.tell() - file.pos: + try: + file.seek(offset, whence) + except streamio.MyNotImplementedError: + assert whence == 1 + except streamio.StreamError: + assert whence == 2 + else: + assert False + else: + file.seek(offset, whence) + rest = file.readall() + assert rest == all[seekto:] return True res = self.interpret(f, []) assert res From noreply at buildbot.pypy.org Wed Feb 13 07:33:49 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Wed, 13 Feb 2013 07:33:49 +0100 (CET) Subject: [pypy-commit] pypy default: prevent streamio SEEK_SET from trashing the buffers for in-buffer seeks, fixes issue1234 Message-ID: <20130213063349.7D76C1C1244@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61162:66d1e56f69a4 Date: 2013-02-13 01:25 -0500 http://bitbucket.org/pypy/pypy/changeset/66d1e56f69a4/ Log: prevent streamio SEEK_SET from trashing the buffers for in-buffer seeks, fixes issue1234 diff --git a/rpython/rlib/streamio.py b/rpython/rlib/streamio.py --- a/rpython/rlib/streamio.py +++ b/rpython/rlib/streamio.py @@ -552,30 +552,26 @@ # This may fail on the do_seek() or do_tell() call. # But it won't call either on a relative forward seek. # Nor on a seek to the very end. - if whence == 0: - self.do_seek(offset, 0) - self.buf = "" - self.pos = 0 - return - if whence == 1: + if whence == 0 or whence == 1: currentsize = len(self.buf) - self.pos - if offset < 0: - if self.pos + offset >= 0: - self.pos += offset - else: - self.do_seek(self.tell() + offset, 0) - self.pos = 0 - self.buf = "" - return - elif offset <= currentsize: - self.pos += offset + if whence == 0: + difpos = offset - self.tell() + else: + difpos = offset + if -self.pos <= difpos <= currentsize: + self.pos += difpos return self.buf = "" self.pos = 0 - offset -= currentsize + if whence == 1: + offset -= currentsize try: - self.do_seek(offset, 1) + self.do_seek(offset, whence) except MyNotImplementedError: + if difpos < 0: + raise + if whence == 0: + offset = difpos - currentsize intoffset = offset2int(offset) self.read(intoffset) return diff --git a/rpython/rlib/test/test_streamio.py b/rpython/rlib/test/test_streamio.py --- a/rpython/rlib/test/test_streamio.py +++ b/rpython/rlib/test/test_streamio.py @@ -391,7 +391,7 @@ end = len(all) cases = [(readto, seekto, whence) for readto in range(0, end+1) for seekto in range(0, end+1) - for whence in [1, 2]] + for whence in [0, 1, 2]] random.shuffle(cases) if isinstance(self, (LLRtypeMixin, OORtypeMixin)): cases = cases[:7] # pick some cases at random - too slow! @@ -401,16 +401,17 @@ file = streamio.BufferingInputStream(base) head = file.read(readto) assert head == all[:readto] - offset = 42 # for the flow space if whence == 1: offset = seekto - readto elif whence == 2: offset = seekto - end + else: + offset = seekto if whence == 2 and seekto < file.tell() or seekto < file.tell() - file.pos: try: file.seek(offset, whence) except streamio.MyNotImplementedError: - assert whence == 1 + assert whence in (0, 1) except streamio.StreamError: assert whence == 2 else: From noreply at buildbot.pypy.org Wed Feb 13 09:39:03 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Wed, 13 Feb 2013 09:39:03 +0100 (CET) Subject: [pypy-commit] pypy default: a test and fix for a problem induced by the _io changes Message-ID: <20130213083903.6C1C41C0253@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61163:5304bc773a43 Date: 2013-02-13 03:38 -0500 http://bitbucket.org/pypy/pypy/changeset/5304bc773a43/ Log: a test and fix for a problem induced by the _io changes diff --git a/lib-python/conftest.py b/lib-python/conftest.py --- a/lib-python/conftest.py +++ b/lib-python/conftest.py @@ -272,7 +272,7 @@ RegrTest('test_inspect.py'), RegrTest('test_int.py', core=True), RegrTest('test_int_literal.py', core=True), - RegrTest('test_io.py'), + RegrTest('test_io.py', usemodules='array binascii'), RegrTest('test_ioctl.py'), RegrTest('test_isinstance.py', core=True), RegrTest('test_iter.py', core=True), diff --git a/pypy/module/_io/interp_bufferedio.py b/pypy/module/_io/interp_bufferedio.py --- a/pypy/module/_io/interp_bufferedio.py +++ b/pypy/module/_io/interp_bufferedio.py @@ -260,7 +260,7 @@ raise operationerrfmt(space.w_ValueError, "whence must be between 0 and 2, not %d", whence) self._check_closed(space, "seek of closed file") - if whence != 2 and self.readable: + if whence != 2 and self.readable and self.read_end != -1: # Check if seeking leaves us inside the current buffer, so as to # return quickly if possible. Also, we needn't take the lock in # this fast path. diff --git a/pypy/module/_io/test/test_bufferedio.py b/pypy/module/_io/test/test_bufferedio.py --- a/pypy/module/_io/test/test_bufferedio.py +++ b/pypy/module/_io/test/test_bufferedio.py @@ -570,6 +570,14 @@ f.seek(0) assert f.read() == 'a\nbxxxx' + def test_simple_read_after_write(self): + import _io + raw = _io.FileIO(self.tmpfile, 'wb+') + f = _io.BufferedRandom(raw) + f.write('abc') + f.seek(0) + assert f.read() == 'abc' + def test_write_rewind_write(self): # Various combinations of reading / writing / seeking # backwards / writing again From noreply at buildbot.pypy.org Wed Feb 13 09:46:22 2013 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 13 Feb 2013 09:46:22 +0100 (CET) Subject: [pypy-commit] cffi default: test and fix Message-ID: <20130213084622.D625C1C080A@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r1153:94d3a3cf5895 Date: 2013-02-13 09:46 +0100 http://bitbucket.org/cffi/cffi/changeset/94d3a3cf5895/ Log: test and fix diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c --- a/c/_cffi_backend.c +++ b/c/_cffi_backend.c @@ -1730,9 +1730,9 @@ "negative index not supported"); return NULL; } - if (stop >= get_array_length(cd)) { + if (stop > get_array_length(cd)) { PyErr_Format(PyExc_IndexError, - "index too large (expected %zd < %zd)", + "index too large (expected %zd <= %zd)", stop, get_array_length(cd)); return NULL; } diff --git a/c/test_c.py b/c/test_c.py --- a/c/test_c.py +++ b/c/test_c.py @@ -2683,6 +2683,8 @@ BIntP = new_pointer_type(new_primitive_type("int")) BIntArray = new_array_type(BIntP, None) c = newp(BIntArray, 5) + c[0:5] + assert len(c[5:5]) == 0 py.test.raises(IndexError, "c[-1:1]") cp = c + 0 cp[-1:1] @@ -2702,7 +2704,7 @@ e = py.test.raises(IndexError, "c[4:2]") assert str(e.value) == "slice start > stop" e = py.test.raises(IndexError, "c[6:6]") - assert str(e.value) == "index too large (expected 6 < 5)" + assert str(e.value) == "index too large (expected 6 <= 5)" def test_setslice(): BIntP = new_pointer_type(new_primitive_type("int")) From noreply at buildbot.pypy.org Wed Feb 13 10:04:14 2013 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 13 Feb 2013 10:04:14 +0100 (CET) Subject: [pypy-commit] cffi default: Remove the debugging print Message-ID: <20130213090414.D31B41C1029@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r1154:078d2278e663 Date: 2013-02-13 10:00 +0100 http://bitbucket.org/cffi/cffi/changeset/078d2278e663/ Log: Remove the debugging print diff --git a/cffi/cparser.py b/cffi/cparser.py --- a/cffi/cparser.py +++ b/cffi/cparser.py @@ -102,7 +102,6 @@ # typedefs, because their presence or absence influences the # parsing itself (but what they are typedef'ed to plays no role) ctn = _common_type_names(csource) - print `csource`, ctn typenames = [] for name in sorted(self._declarations): if name.startswith('typedef '): From noreply at buildbot.pypy.org Wed Feb 13 11:24:49 2013 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 13 Feb 2013 11:24:49 +0100 (CET) Subject: [pypy-commit] cffi default: Support the PyPy error message here Message-ID: <20130213102449.5F1F61C11AD@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r1155:5de8873f4eb6 Date: 2013-02-13 11:24 +0100 http://bitbucket.org/cffi/cffi/changeset/5de8873f4eb6/ Log: Support the PyPy error message here diff --git a/c/test_c.py b/c/test_c.py --- a/c/test_c.py +++ b/c/test_c.py @@ -1322,7 +1322,8 @@ p = newp(BStructPtr, [12]) assert p.a1 == 12 e = py.test.raises(TypeError, newp, BStructPtr, [None]) - assert "an integer is required" in str(e.value) + assert ("an integer is required" in str(e.value) or + "unsupported operand type for int(): 'NoneType'" in str(e.value)) #PyPy py.test.raises(TypeError, 'p.a1 = "def"') if sys.version_info < (3,): BEnum2 = new_enum_type(unicode("foo"), (unicode('abc'),), (5,)) From noreply at buildbot.pypy.org Wed Feb 13 11:27:00 2013 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 13 Feb 2013 11:27:00 +0100 (CET) Subject: [pypy-commit] pypy default: Support cffi's "slicing" branch Message-ID: <20130213102700.270F71C11AD@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r61164:78787a1a14be Date: 2013-02-13 10:24 +0100 http://bitbucket.org/pypy/pypy/changeset/78787a1a14be/ Log: Support cffi's "slicing" branch diff --git a/pypy/module/_cffi_backend/cdataobj.py b/pypy/module/_cffi_backend/cdataobj.py --- a/pypy/module/_cffi_backend/cdataobj.py +++ b/pypy/module/_cffi_backend/cdataobj.py @@ -119,9 +119,12 @@ def getitem(self, w_index): space = self.space - i = space.getindex_w(w_index, space.w_IndexError) - ctype = self.ctype._check_subscript_index(self, i) - w_o = self._do_getitem(ctype, i) + if space.isinstance_w(w_index, space.w_slice): + w_o = self._do_getslice(w_index) + else: + i = space.getindex_w(w_index, space.w_IndexError) + ctype = self.ctype._check_subscript_index(self, i) + w_o = self._do_getitem(ctype, i) keepalive_until_here(self) return w_o @@ -132,14 +135,100 @@ def setitem(self, w_index, w_value): space = self.space - i = space.getindex_w(w_index, space.w_IndexError) - ctype = self.ctype._check_subscript_index(self, i) - ctitem = ctype.ctitem - ctitem.convert_from_object( - rffi.ptradd(self._cdata, i * ctitem.size), - w_value) + if space.isinstance_w(w_index, space.w_slice): + self._do_setslice(w_index, w_value) + else: + i = space.getindex_w(w_index, space.w_IndexError) + ctype = self.ctype._check_subscript_index(self, i) + ctitem = ctype.ctitem + ctitem.convert_from_object( + rffi.ptradd(self._cdata, i * ctitem.size), + w_value) keepalive_until_here(self) + def _do_getslicearg(self, w_slice): + from pypy.module._cffi_backend.ctypeptr import W_CTypePointer + from pypy.objspace.std.sliceobject import W_SliceObject + assert isinstance(w_slice, W_SliceObject) + space = self.space + # + if space.is_w(w_slice.w_start, space.w_None): + raise OperationError(space.w_IndexError, + space.wrap("slice start must be specified")) + start = space.int_w(w_slice.w_start) + # + if space.is_w(w_slice.w_stop, space.w_None): + raise OperationError(space.w_IndexError, + space.wrap("slice stop must be specified")) + stop = space.int_w(w_slice.w_stop) + # + if not space.is_w(w_slice.w_step, space.w_None): + raise OperationError(space.w_IndexError, + space.wrap("slice with step not supported")) + # + if start > stop: + raise OperationError(space.w_IndexError, + space.wrap("slice start > stop")) + # + ctype = self.ctype._check_slice_index(self, start, stop) + assert isinstance(ctype, W_CTypePointer) + # + return ctype, start, stop - start + + def _do_getslice(self, w_slice): + ctptr, start, length = self._do_getslicearg(w_slice) + # + space = self.space + ctarray = ctptr.cache_array_type + if ctarray is None: + from pypy.module._cffi_backend import newtype + ctarray = newtype.new_array_type(space, ctptr, space.w_None) + ctptr.cache_array_type = ctarray + # + p = rffi.ptradd(self._cdata, start * ctarray.ctitem.size) + return W_CDataSliced(space, p, ctarray, length) + + def _do_setslice(self, w_slice, w_value): + ctptr, start, length = self._do_getslicearg(w_slice) + ctitem = ctptr.ctitem + ctitemsize = ctitem.size + cdata = rffi.ptradd(self._cdata, start * ctitemsize) + # + if isinstance(w_value, W_CData): + from pypy.module._cffi_backend import ctypearray + ctv = w_value.ctype + if (isinstance(ctv, ctypearray.W_CTypeArray) and + ctv.ctitem is ctitem and + w_value.get_array_length() == length): + # fast path: copying from exactly the correct type + s = w_value._cdata + for i in range(ctitemsize * length): + cdata[i] = s[i] + keepalive_until_here(w_value) + return + # + space = self.space + w_iter = space.iter(w_value) + for i in range(length): + try: + w_item = space.next(w_iter) + except OperationError, e: + if not e.match(space, space.w_StopIteration): + raise + raise operationerrfmt(space.w_ValueError, + "need %d values to unpack, got %d", + length, i) + ctitem.convert_from_object(cdata, w_item) + cdata = rffi.ptradd(cdata, ctitemsize) + try: + space.next(w_iter) + except OperationError, e: + if not e.match(space, space.w_StopIteration): + raise + else: + raise operationerrfmt(space.w_ValueError, + "got more than %d values to unpack", length) + def _add_or_sub(self, w_other, sign): space = self.space i = sign * space.getindex_w(w_other, space.w_OverflowError) @@ -281,6 +370,22 @@ return self.structobj +class W_CDataSliced(W_CData): + """Subclass with an explicit length, for slices.""" + _attrs_ = ['length'] + _immutable_fields_ = ['length'] + + def __init__(self, space, cdata, ctype, length): + W_CData.__init__(self, space, cdata, ctype) + self.length = length + + def _repr_extra(self): + return "sliced length %d" % (self.length,) + + def get_array_length(self): + return self.length + + W_CData.typedef = TypeDef( 'CData', __module__ = '_cffi_backend', diff --git a/pypy/module/_cffi_backend/ctypearray.py b/pypy/module/_cffi_backend/ctypearray.py --- a/pypy/module/_cffi_backend/ctypearray.py +++ b/pypy/module/_cffi_backend/ctypearray.py @@ -76,6 +76,17 @@ self.name, i, w_cdata.get_array_length()) return self + def _check_slice_index(self, w_cdata, start, stop): + space = self.space + if start < 0: + raise OperationError(space.w_IndexError, + space.wrap("negative index not supported")) + if stop > w_cdata.get_array_length(): + raise operationerrfmt(space.w_IndexError, + "index too large (expected %d <= %d)", + stop, w_cdata.get_array_length()) + return self.ctptr + def convert_from_object(self, cdata, w_ob): self.convert_array_from_object(cdata, w_ob) diff --git a/pypy/module/_cffi_backend/ctypeobj.py b/pypy/module/_cffi_backend/ctypeobj.py --- a/pypy/module/_cffi_backend/ctypeobj.py +++ b/pypy/module/_cffi_backend/ctypeobj.py @@ -93,12 +93,18 @@ "not %s", self.name, expected, space.type(w_got).getname(space)) - def _check_subscript_index(self, w_cdata, i): + def _cannot_index(self): space = self.space raise operationerrfmt(space.w_TypeError, "cdata of type '%s' cannot be indexed", self.name) + def _check_subscript_index(self, w_cdata, i): + raise self._cannot_index() + + def _check_slice_index(self, w_cdata, start, stop): + raise self._cannot_index() + def string(self, cdataobj, maxlen): space = self.space raise operationerrfmt(space.w_TypeError, diff --git a/pypy/module/_cffi_backend/ctypeptr.py b/pypy/module/_cffi_backend/ctypeptr.py --- a/pypy/module/_cffi_backend/ctypeptr.py +++ b/pypy/module/_cffi_backend/ctypeptr.py @@ -174,9 +174,10 @@ class W_CTypePointer(W_CTypePtrBase): - _attrs_ = ['is_file'] + _attrs_ = ['is_file', 'cache_array_type'] _immutable_fields_ = ['is_file'] kind = "pointer" + cache_array_type = None def __init__(self, space, ctitem): from pypy.module._cffi_backend import ctypearray @@ -224,6 +225,9 @@ self.name) return self + def _check_slice_index(self, w_cdata, start, stop): + return self + def add(self, cdata, i): space = self.space ctitem = self.ctitem diff --git a/pypy/module/_cffi_backend/test/_backend_test_c.py b/pypy/module/_cffi_backend/test/_backend_test_c.py --- a/pypy/module/_cffi_backend/test/_backend_test_c.py +++ b/pypy/module/_cffi_backend/test/_backend_test_c.py @@ -1284,22 +1284,24 @@ def test_cast_to_enum(): BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, -20)) e = cast(BEnum, 0) - assert repr(e) == "" + assert repr(e) == "" + assert repr(cast(BEnum, -42)) == "" + assert repr(cast(BEnum, -20)) == "" assert string(e) == 'def' assert string(cast(BEnum, -20)) == 'ab' - assert string(cast(BEnum, 'c')) == 'c' - assert int(cast(BEnum, 'c')) == 1 - assert int(cast(BEnum, 'def')) == 0 + assert int(cast(BEnum, 1)) == 1 + assert int(cast(BEnum, 0)) == 0 assert int(cast(BEnum, -242 + 2**128)) == -242 - assert string(cast(BEnum, -242 + 2**128)) == '#-242' - assert string(cast(BEnum, '#-20')) == 'ab' - assert repr(cast(BEnum, '#-20')) == "" - assert repr(cast(BEnum, '#-21')) == "" + assert string(cast(BEnum, -242 + 2**128)) == '-242' + # + BEnum = new_enum_type("bar", ('def', 'c', 'ab'), (0, 1, 20)) + e = cast(BEnum, -1) + assert repr(e) == "" # unsigned int def test_enum_with_non_injective_mapping(): BEnum = new_enum_type("foo", ('ab', 'cd'), (7, 7)) e = cast(BEnum, 7) - assert repr(e) == "" + assert repr(e) == "" assert string(e) == 'ab' def test_enum_in_struct(): @@ -1308,36 +1310,111 @@ BStructPtr = new_pointer_type(BStruct) complete_struct_or_union(BStruct, [('a1', BEnum, -1)]) p = newp(BStructPtr, [-20]) - assert p.a1 == "ab" - p = newp(BStructPtr, ["c"]) - assert p.a1 == "c" + assert p.a1 == -20 + p = newp(BStructPtr, [12]) + assert p.a1 == 12 e = py.test.raises(TypeError, newp, BStructPtr, [None]) - assert "must be a str or int, not NoneType" in str(e.value) + assert "an integer is required" in str(e.value) + py.test.raises(TypeError, 'p.a1 = "def"') if sys.version_info < (3,): - p.a1 = unicode("def") - assert p.a1 == "def" and type(p.a1) is str - py.test.raises(UnicodeEncodeError, "p.a1 = unichr(1234)") BEnum2 = new_enum_type(unicode("foo"), (unicode('abc'),), (5,)) - assert string(cast(BEnum2, unicode('abc'))) == 'abc' + assert string(cast(BEnum2, 5)) == 'abc' + assert type(string(cast(BEnum2, 5))) is str def test_enum_overflow(): - for ovf in (2**63, -2**63-1, 2**31, -2**31-1): - e = py.test.raises(OverflowError, new_enum_type, "foo", ('a', 'b'), - (5, ovf)) - assert str(e.value) == ( - "enum 'foo' declaration for 'b' does not fit an int") + max_uint = 2 ** (size_of_int()*8) - 1 + max_int = max_uint // 2 + max_ulong = 2 ** (size_of_long()*8) - 1 + max_long = max_ulong // 2 + # 'unsigned int' case + e = new_enum_type("foo", ('a', 'b'), (0, 3)) + assert sizeof(e) == size_of_int() + assert int(cast(e, -1)) == max_uint # 'e' is unsigned + e = new_enum_type("foo", ('a', 'b'), (0, max_uint)) + assert sizeof(e) == size_of_int() + assert int(cast(e, -1)) == max_uint + assert e.elements == {0: 'a', max_uint: 'b'} + assert e.relements == {'a': 0, 'b': max_uint} + # 'signed int' case + e = new_enum_type("foo", ('a', 'b'), (-1, max_int)) + assert sizeof(e) == size_of_int() + assert int(cast(e, -1)) == -1 + assert e.elements == {-1: 'a', max_int: 'b'} + assert e.relements == {'a': -1, 'b': max_int} + e = new_enum_type("foo", ('a', 'b'), (-max_int-1, max_int)) + assert sizeof(e) == size_of_int() + assert int(cast(e, -1)) == -1 + assert e.elements == {-max_int-1: 'a', max_int: 'b'} + assert e.relements == {'a': -max_int-1, 'b': max_int} + # 'unsigned long' case + e = new_enum_type("foo", ('a', 'b'), (0, max_long)) + assert sizeof(e) == size_of_long() + assert int(cast(e, -1)) == max_ulong # 'e' is unsigned + e = new_enum_type("foo", ('a', 'b'), (0, max_ulong)) + assert sizeof(e) == size_of_long() + assert int(cast(e, -1)) == max_ulong + assert e.elements == {0: 'a', max_ulong: 'b'} + assert e.relements == {'a': 0, 'b': max_ulong} + # 'signed long' case + e = new_enum_type("foo", ('a', 'b'), (-1, max_long)) + assert sizeof(e) == size_of_long() + assert int(cast(e, -1)) == -1 + assert e.elements == {-1: 'a', max_long: 'b'} + assert e.relements == {'a': -1, 'b': max_long} + e = new_enum_type("foo", ('a', 'b'), (-max_long-1, max_long)) + assert sizeof(e) == size_of_long() + assert int(cast(e, -1)) == -1 + assert e.elements == {-max_long-1: 'a', max_long: 'b'} + assert e.relements == {'a': -max_long-1, 'b': max_long} + # overflow: both negative items and items larger than max_long + e = py.test.raises(OverflowError, new_enum_type, "foo", ('a', 'b'), + (-1, max_long + 1)) + assert str(e.value) == ( + "enum 'foo' values don't all fit into either 'long' " + "or 'unsigned long'") + # overflow: items smaller than -max_long-1 + e = py.test.raises(OverflowError, new_enum_type, "foo", ('a', 'b'), + (-max_long-2, 5)) + assert str(e.value) == ( + "enum 'foo' declaration for 'a' does not fit a long or unsigned long") + # overflow: items larger than max_ulong + e = py.test.raises(OverflowError, new_enum_type, "foo", ('a', 'b'), + (5, max_ulong+1)) + assert str(e.value) == ( + "enum 'foo' declaration for 'b' does not fit a long or unsigned long") def test_callback_returning_enum(): BInt = new_primitive_type("int") BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, -20)) def cb(n): - return '#%d' % n + if n & 1: + return cast(BEnum, n) + else: + return n BFunc = new_function_type((BInt,), BEnum) f = callback(BFunc, cb) - assert f(0) == 'def' - assert f(1) == 'c' - assert f(-20) == 'ab' - assert f(20) == '#20' + assert f(0) == 0 + assert f(1) == 1 + assert f(-20) == -20 + assert f(20) == 20 + assert f(21) == 21 + +def test_callback_returning_enum_unsigned(): + BInt = new_primitive_type("int") + BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, 20)) + def cb(n): + print n + if n & 1: + return cast(BEnum, n) + else: + return n + BFunc = new_function_type((BInt,), BEnum) + f = callback(BFunc, cb) + assert f(0) == 0 + assert f(1) == 1 + assert f(-21) == 2**32 - 21 + assert f(20) == 20 + assert f(21) == 21 def test_callback_returning_char(): BInt = new_primitive_type("int") @@ -2497,7 +2574,7 @@ if sys.platform == "win32": py.test.skip("testing FILE not implemented") # - BFILE = new_struct_type("_IO_FILE") + BFILE = new_struct_type("$FILE") BFILEP = new_pointer_type(BFILE) BChar = new_primitive_type("char") BCharP = new_pointer_type(BChar) @@ -2566,3 +2643,87 @@ for i in range(20): buf = buflist[i] assert buf[:] == str2bytes("hi there %d\x00" % i) + +def test_slice(): + BIntP = new_pointer_type(new_primitive_type("int")) + BIntArray = new_array_type(BIntP, None) + c = newp(BIntArray, 5) + assert len(c) == 5 + assert repr(c) == "" + d = c[1:4] + assert len(d) == 3 + assert repr(d) == "" + d[0] = 123 + d[2] = 456 + assert c[1] == 123 + assert c[3] == 456 + assert d[2] == 456 + py.test.raises(IndexError, "d[3]") + py.test.raises(IndexError, "d[-1]") + +def test_slice_ptr(): + BIntP = new_pointer_type(new_primitive_type("int")) + BIntArray = new_array_type(BIntP, None) + c = newp(BIntArray, 5) + d = (c+1)[0:2] + assert len(d) == 2 + assert repr(d) == "" + d[1] += 50 + assert c[2] == 50 + +def test_slice_array_checkbounds(): + BIntP = new_pointer_type(new_primitive_type("int")) + BIntArray = new_array_type(BIntP, None) + c = newp(BIntArray, 5) + c[0:5] + assert len(c[5:5]) == 0 + py.test.raises(IndexError, "c[-1:1]") + cp = c + 0 + cp[-1:1] + +def test_nonstandard_slice(): + BIntP = new_pointer_type(new_primitive_type("int")) + BIntArray = new_array_type(BIntP, None) + c = newp(BIntArray, 5) + e = py.test.raises(IndexError, "c[:5]") + assert str(e.value) == "slice start must be specified" + e = py.test.raises(IndexError, "c[4:]") + assert str(e.value) == "slice stop must be specified" + e = py.test.raises(IndexError, "c[1:2:3]") + assert str(e.value) == "slice with step not supported" + e = py.test.raises(IndexError, "c[1:2:1]") + assert str(e.value) == "slice with step not supported" + e = py.test.raises(IndexError, "c[4:2]") + assert str(e.value) == "slice start > stop" + e = py.test.raises(IndexError, "c[6:6]") + assert str(e.value) == "index too large (expected 6 <= 5)" + +def test_setslice(): + BIntP = new_pointer_type(new_primitive_type("int")) + BIntArray = new_array_type(BIntP, None) + c = newp(BIntArray, 5) + c[1:3] = [100, 200] + assert list(c) == [0, 100, 200, 0, 0] + cp = c + 3 + cp[-1:1] = [300, 400] + assert list(c) == [0, 100, 300, 400, 0] + cp[-1:1] = iter([500, 600]) + assert list(c) == [0, 100, 500, 600, 0] + py.test.raises(ValueError, "cp[-1:1] = [1000]") + assert list(c) == [0, 100, 1000, 600, 0] + py.test.raises(ValueError, "cp[-1:1] = (700, 800, 900)") + assert list(c) == [0, 100, 700, 800, 0] + +def test_setslice_array(): + BIntP = new_pointer_type(new_primitive_type("int")) + BIntArray = new_array_type(BIntP, None) + c = newp(BIntArray, 5) + d = newp(BIntArray, [10, 20, 30]) + c[1:4] = d + assert list(c) == [0, 10, 20, 30, 0] + # + BShortP = new_pointer_type(new_primitive_type("short")) + BShortArray = new_array_type(BShortP, None) + d = newp(BShortArray, [40, 50]) + c[1:3] = d + assert list(c) == [0, 40, 50, 30, 0] From noreply at buildbot.pypy.org Wed Feb 13 11:27:01 2013 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 13 Feb 2013 11:27:01 +0100 (CET) Subject: [pypy-commit] pypy default: Support cffi's "auto-types" branch Message-ID: <20130213102701.748B11C11AD@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r61165:22420672392e Date: 2013-02-13 10:26 +0100 http://bitbucket.org/pypy/pypy/changeset/22420672392e/ Log: Support cffi's "auto-types" branch diff --git a/pypy/module/_cffi_backend/ctypeptr.py b/pypy/module/_cffi_backend/ctypeptr.py --- a/pypy/module/_cffi_backend/ctypeptr.py +++ b/pypy/module/_cffi_backend/ctypeptr.py @@ -186,7 +186,8 @@ extra = "(*)" # obscure case: see test_array_add else: extra = " *" - self.is_file = (ctitem.name == "struct _IO_FILE") + self.is_file = (ctitem.name == "struct _IO_FILE" or + ctitem.name == "struct $FILE") W_CTypePtrBase.__init__(self, space, size, extra, 2, ctitem) def newp(self, w_init): From noreply at buildbot.pypy.org Wed Feb 13 11:27:02 2013 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 13 Feb 2013 11:27:02 +0100 (CET) Subject: [pypy-commit] pypy default: Add most_pos_value_of(), similar to most_neg_value_of(). Message-ID: <20130213102702.9EACF1C11AD@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r61166:4958d1d8d8d9 Date: 2013-02-13 10:50 +0100 http://bitbucket.org/pypy/pypy/changeset/4958d1d8d8d9/ Log: Add most_pos_value_of(), similar to most_neg_value_of(). diff --git a/rpython/rlib/rarithmetic.py b/rpython/rlib/rarithmetic.py --- a/rpython/rlib/rarithmetic.py +++ b/rpython/rlib/rarithmetic.py @@ -246,6 +246,23 @@ return r_class(0) most_neg_value_of._annspecialcase_ = 'specialize:memo' +def most_pos_value_of_same_type(x): + from rpython.rtyper.lltypesystem import lltype + return most_pos_value_of(lltype.typeOf(x)) +most_pos_value_of_same_type._annspecialcase_ = 'specialize:argtype(0)' + +def most_pos_value_of(tp): + from rpython.rtyper.lltypesystem import lltype, rffi + if tp is lltype.Signed: + return sys.maxint + r_class = rffi.platform.numbertype_to_rclass[tp] + assert issubclass(r_class, base_int) + if r_class.SIGNED: + return r_class(r_class.MASK >> 1) + else: + return r_class(r_class.MASK) +most_pos_value_of._annspecialcase_ = 'specialize:memo' + def is_signed_integer_type(tp): from rpython.rtyper.lltypesystem import lltype, rffi if tp is lltype.Signed: diff --git a/rpython/rlib/test/test_rarithmetic.py b/rpython/rlib/test/test_rarithmetic.py --- a/rpython/rlib/test/test_rarithmetic.py +++ b/rpython/rlib/test/test_rarithmetic.py @@ -357,6 +357,14 @@ assert most_neg_value_of_same_type(r_longlong(123)) == llmin assert most_neg_value_of_same_type(r_ulonglong(123)) == 0 +def test_most_pos_value_of(): + assert most_pos_value_of_same_type(123) == sys.maxint + assert most_pos_value_of_same_type(r_uint(123)) == 2 * sys.maxint + 1 + llmax_sign = (2**(r_longlong.BITS-1))-1 + llmax_unsign = (2**r_longlong.BITS)-1 + assert most_pos_value_of_same_type(r_longlong(123)) == llmax_sign + assert most_pos_value_of_same_type(r_ulonglong(123)) == llmax_unsign + def test_is_signed_integer_type(): from rpython.rtyper.lltypesystem import lltype, rffi assert is_signed_integer_type(lltype.Signed) From noreply at buildbot.pypy.org Wed Feb 13 11:27:03 2013 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 13 Feb 2013 11:27:03 +0100 (CET) Subject: [pypy-commit] pypy default: Add a passing test about str(r_uint(..)) in RPython. Message-ID: <20130213102703.E023C1C11AD@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r61167:32bc19b1826c Date: 2013-02-13 11:15 +0100 http://bitbucket.org/pypy/pypy/changeset/32bc19b1826c/ Log: Add a passing test about str(r_uint(..)) in RPython. diff --git a/rpython/rtyper/test/test_rint.py b/rpython/rtyper/test/test_rint.py --- a/rpython/rtyper/test/test_rint.py +++ b/rpython/rtyper/test/test_rint.py @@ -115,6 +115,22 @@ res = self.interpret(f, [r_int64(413974738222117)]) assert self.ll_to_string(res) == '413974738222117' + def test_str_of_uint(self): + def f(i): + return str(i) + + res = self.interpret(f, [r_uint(0)]) + assert self.ll_to_string(res) == '0' + + res = self.interpret(f, [r_uint(sys.maxint)]) + assert self.ll_to_string(res) == str(sys.maxint) + + res = self.interpret(f, [r_uint(sys.maxint+1)]) + assert self.ll_to_string(res) == str(sys.maxint+1) + + res = self.interpret(f, [r_uint(-1)]) + assert self.ll_to_string(res) == str(2*sys.maxint+1) + def test_unsigned(self): bigvalue = r_uint(sys.maxint + 17) def dummy(i): From noreply at buildbot.pypy.org Wed Feb 13 11:27:05 2013 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 13 Feb 2013 11:27:05 +0100 (CET) Subject: [pypy-commit] pypy default: Support cffi's "enum-as-int" branch Message-ID: <20130213102705.256FF1C11AD@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r61168:3d9c73dd0f46 Date: 2013-02-13 11:26 +0100 http://bitbucket.org/pypy/pypy/changeset/3d9c73dd0f46/ Log: Support cffi's "enum-as-int" branch diff --git a/pypy/module/_cffi_backend/ctypeenum.py b/pypy/module/_cffi_backend/ctypeenum.py --- a/pypy/module/_cffi_backend/ctypeenum.py +++ b/pypy/module/_cffi_backend/ctypeenum.py @@ -6,23 +6,19 @@ from rpython.rtyper.lltypesystem import rffi from rpython.rlib.rarithmetic import intmask, r_ulonglong from rpython.rlib.objectmodel import keepalive_until_here +from rpython.rlib.objectmodel import specialize from pypy.module._cffi_backend.ctypeprim import W_CTypePrimitiveSigned +from pypy.module._cffi_backend.ctypeprim import W_CTypePrimitiveUnsigned from pypy.module._cffi_backend import misc -class W_CTypeEnum(W_CTypePrimitiveSigned): - _attrs_ = ['enumerators2values', 'enumvalues2erators'] - _immutable_fields_ = ['enumerators2values', 'enumvalues2erators'] - kind = "enum" +class _Mixin_Enum(object): + _mixin_ = True - def __init__(self, space, name, enumerators, enumvalues): - from pypy.module._cffi_backend.newtype import alignment + def __init__(self, space, name, size, align, enumerators, enumvalues): name = "enum " + name - size = rffi.sizeof(rffi.INT) - align = alignment(rffi.INT) - W_CTypePrimitiveSigned.__init__(self, space, size, - name, len(name), align) + self._super.__init__(self, space, size, name, len(name), align) self.enumerators2values = {} # str -> int self.enumvalues2erators = {} # int -> str for i in range(len(enumerators)-1, -1, -1): @@ -44,55 +40,46 @@ space.setitem(w_dct, space.wrap(enumerator), space.wrap(enumvalue)) return w_dct - return W_CTypePrimitiveSigned._fget(self, attrchar) + return self._super._fget(self, attrchar) + + def extra_repr(self, cdata): + value = self._get_value(cdata) + try: + s = self.enumvalues2erators[value] + except KeyError: + return str(value) + else: + return '%s: %s' % (value, s) def string(self, cdataobj, maxlen): - w_result = self.convert_to_object(cdataobj._cdata) + value = self._get_value(cdataobj._cdata) keepalive_until_here(cdataobj) - return w_result + try: + s = self.enumvalues2erators[value] + except KeyError: + s = str(value) + return self.space.wrap(s) - def convert_to_object(self, cdata): - value = misc.read_raw_long_data(cdata, self.size) - try: - enumerator = self.enumvalues2erators[value] - except KeyError: - enumerator = '#%d' % (value,) - return self.space.wrap(enumerator) - def convert_from_object(self, cdata, w_ob): - space = self.space - try: - return W_CTypePrimitiveSigned.convert_from_object(self, cdata, - w_ob) - except OperationError, e: - if not e.match(space, space.w_TypeError): - raise - if space.isinstance_w(w_ob, space.w_basestring): - value = self.convert_enum_string_to_int(space.str_w(w_ob)) - value = r_ulonglong(value) - misc.write_raw_integer_data(cdata, value, self.size) - else: - raise self._convert_error("str or int", w_ob) +class W_CTypeEnumSigned(_Mixin_Enum, W_CTypePrimitiveSigned): + _attrs_ = ['enumerators2values', 'enumvalues2erators'] + _immutable_fields_ = ['enumerators2values', 'enumvalues2erators'] + kind = "enum" + _super = W_CTypePrimitiveSigned - def cast_str(self, w_ob): - space = self.space - return self.convert_enum_string_to_int(space.str_w(w_ob)) + def _get_value(self, cdata): + # returns a signed long + assert self.value_fits_long + return misc.read_raw_long_data(cdata, self.size) - def cast_unicode(self, w_ob): - return self.cast_str(w_ob) - def convert_enum_string_to_int(self, s): - space = self.space - if s.startswith('#'): - try: - return int(s[1:]) - except ValueError: - raise OperationError(space.w_ValueError, - space.wrap("invalid literal after '#'")) - else: - try: - return self.enumerators2values[s] - except KeyError: - raise operationerrfmt(space.w_ValueError, - "'%s' is not an enumerator for %s", - s, self.name) +class W_CTypeEnumUnsigned(_Mixin_Enum, W_CTypePrimitiveUnsigned): + _attrs_ = ['enumerators2values', 'enumvalues2erators'] + _immutable_fields_ = ['enumerators2values', 'enumvalues2erators'] + kind = "enum" + _super = W_CTypePrimitiveUnsigned + + def _get_value(self, cdata): + # returns an unsigned long + assert self.value_fits_ulong + return misc.read_raw_ulong_data(cdata, self.size) diff --git a/pypy/module/_cffi_backend/ctypeprim.py b/pypy/module/_cffi_backend/ctypeprim.py --- a/pypy/module/_cffi_backend/ctypeprim.py +++ b/pypy/module/_cffi_backend/ctypeprim.py @@ -171,9 +171,7 @@ self.vrangemax = (r_uint(1) << sh) - 1 def int(self, cdata): - # enums: really call convert_to_object() just below, - # and not the one overridden in W_CTypeEnum. - return W_CTypePrimitiveSigned.convert_to_object(self, cdata) + return self.convert_to_object(cdata) def convert_to_object(self, cdata): if self.value_fits_long: diff --git a/pypy/module/_cffi_backend/newtype.py b/pypy/module/_cffi_backend/newtype.py --- a/pypy/module/_cffi_backend/newtype.py +++ b/pypy/module/_cffi_backend/newtype.py @@ -1,7 +1,8 @@ from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.gateway import unwrap_spec from rpython.rtyper.lltypesystem import lltype, rffi -from rpython.rlib.rarithmetic import ovfcheck +from rpython.rlib.rarithmetic import ovfcheck, r_uint +from rpython.rlib.rarithmetic import most_neg_value_of, most_pos_value_of from rpython.rlib.objectmodel import specialize from pypy.module._cffi_backend import ctypeobj, ctypeprim, ctypeptr, ctypearray @@ -271,18 +272,57 @@ raise OperationError(space.w_ValueError, space.wrap("tuple args must have the same size")) enumerators = [space.str_w(w) for w in enumerators_w] - enumvalues = [] + # + smallest_value = 0 + largest_value = r_uint(0) + i = 0 try: for w in enumvalues_w: - enumvalues.append(space.c_int_w(w)) + try: + ulvalue = space.uint_w(w) + except OperationError, e: + if not e.match(space, space.w_ValueError): + raise + lvalue = space.int_w(w) + if lvalue < smallest_value: + smallest_value = lvalue + else: + if ulvalue > largest_value: + largest_value = ulvalue + i += 1 # 'i' is here for the exception case, see below except OperationError, e: if not e.match(space, space.w_OverflowError): raise - i = len(enumvalues) raise operationerrfmt(space.w_OverflowError, - "enum '%s' declaration for '%s' does not fit an int", + "enum '%s' declaration for '%s' does not fit " + "a long or unsigned long", name, enumerators[i]) - ctype = ctypeenum.W_CTypeEnum(space, name, enumerators, enumvalues) + # + if smallest_value < 0: + if (smallest_value >= most_neg_value_of(rffi.INT) and + largest_value <= r_uint(most_pos_value_of(rffi.INT))): + size = rffi.sizeof(rffi.INT) + align = alignment(rffi.INT) + elif largest_value <= r_uint(most_pos_value_of(rffi.LONG)): + size = rffi.sizeof(rffi.LONG) + align = alignment(rffi.LONG) + else: + raise operationerrfmt(space.w_OverflowError, + "enum '%s' values don't all fit into either 'long' " + "or 'unsigned long'", name) + enumvalues = [space.int_w(w) for w in enumvalues_w] + ctype = ctypeenum.W_CTypeEnumSigned(space, name, size, align, + enumerators, enumvalues) + else: + if largest_value <= r_uint(most_pos_value_of(rffi.UINT)): + size = rffi.sizeof(rffi.UINT) + align = alignment(rffi.UINT) + else: + size = rffi.sizeof(rffi.ULONG) + align = alignment(rffi.ULONG) + enumvalues = [space.uint_w(w) for w in enumvalues_w] + ctype = ctypeenum.W_CTypeEnumUnsigned(space, name, size, align, + enumerators, enumvalues) return ctype # ____________________________________________________________ diff --git a/pypy/module/_cffi_backend/test/_backend_test_c.py b/pypy/module/_cffi_backend/test/_backend_test_c.py --- a/pypy/module/_cffi_backend/test/_backend_test_c.py +++ b/pypy/module/_cffi_backend/test/_backend_test_c.py @@ -1314,7 +1314,8 @@ p = newp(BStructPtr, [12]) assert p.a1 == 12 e = py.test.raises(TypeError, newp, BStructPtr, [None]) - assert "an integer is required" in str(e.value) + assert ("an integer is required" in str(e.value) or + "unsupported operand type for int(): 'NoneType'" in str(e.value)) #PyPy py.test.raises(TypeError, 'p.a1 = "def"') if sys.version_info < (3,): BEnum2 = new_enum_type(unicode("foo"), (unicode('abc'),), (5,)) From noreply at buildbot.pypy.org Wed Feb 13 11:27:06 2013 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 13 Feb 2013 11:27:06 +0100 (CET) Subject: [pypy-commit] pypy default: merge heads Message-ID: <20130213102706.4F3281C11AD@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r61169:594758a6ff8b Date: 2013-02-13 11:26 +0100 http://bitbucket.org/pypy/pypy/changeset/594758a6ff8b/ Log: merge heads diff --git a/lib-python/conftest.py b/lib-python/conftest.py --- a/lib-python/conftest.py +++ b/lib-python/conftest.py @@ -272,7 +272,7 @@ RegrTest('test_inspect.py'), RegrTest('test_int.py', core=True), RegrTest('test_int_literal.py', core=True), - RegrTest('test_io.py'), + RegrTest('test_io.py', usemodules='array binascii'), RegrTest('test_ioctl.py'), RegrTest('test_isinstance.py', core=True), RegrTest('test_iter.py', core=True), diff --git a/pypy/module/_io/interp_bufferedio.py b/pypy/module/_io/interp_bufferedio.py --- a/pypy/module/_io/interp_bufferedio.py +++ b/pypy/module/_io/interp_bufferedio.py @@ -260,7 +260,7 @@ raise operationerrfmt(space.w_ValueError, "whence must be between 0 and 2, not %d", whence) self._check_closed(space, "seek of closed file") - if whence != 2 and self.readable: + if whence != 2 and self.readable and self.read_end != -1: # Check if seeking leaves us inside the current buffer, so as to # return quickly if possible. Also, we needn't take the lock in # this fast path. diff --git a/pypy/module/_io/test/test_bufferedio.py b/pypy/module/_io/test/test_bufferedio.py --- a/pypy/module/_io/test/test_bufferedio.py +++ b/pypy/module/_io/test/test_bufferedio.py @@ -570,6 +570,14 @@ f.seek(0) assert f.read() == 'a\nbxxxx' + def test_simple_read_after_write(self): + import _io + raw = _io.FileIO(self.tmpfile, 'wb+') + f = _io.BufferedRandom(raw) + f.write('abc') + f.seek(0) + assert f.read() == 'abc' + def test_write_rewind_write(self): # Various combinations of reading / writing / seeking # backwards / writing again From noreply at buildbot.pypy.org Wed Feb 13 11:31:08 2013 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 13 Feb 2013 11:31:08 +0100 (CET) Subject: [pypy-commit] pypy default: Translation fix on 64-bits Message-ID: <20130213103108.3BF181C11AD@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r61170:4de14e41742f Date: 2013-02-13 11:30 +0100 http://bitbucket.org/pypy/pypy/changeset/4de14e41742f/ Log: Translation fix on 64-bits diff --git a/pypy/module/_cffi_backend/newtype.py b/pypy/module/_cffi_backend/newtype.py --- a/pypy/module/_cffi_backend/newtype.py +++ b/pypy/module/_cffi_backend/newtype.py @@ -1,7 +1,7 @@ from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.gateway import unwrap_spec from rpython.rtyper.lltypesystem import lltype, rffi -from rpython.rlib.rarithmetic import ovfcheck, r_uint +from rpython.rlib.rarithmetic import ovfcheck, r_uint, intmask from rpython.rlib.rarithmetic import most_neg_value_of, most_pos_value_of from rpython.rlib.objectmodel import specialize @@ -299,7 +299,7 @@ name, enumerators[i]) # if smallest_value < 0: - if (smallest_value >= most_neg_value_of(rffi.INT) and + if (smallest_value >= intmask(most_neg_value_of(rffi.INT)) and largest_value <= r_uint(most_pos_value_of(rffi.INT))): size = rffi.sizeof(rffi.INT) align = alignment(rffi.INT) From noreply at buildbot.pypy.org Wed Feb 13 11:35:23 2013 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 13 Feb 2013 11:35:23 +0100 (CET) Subject: [pypy-commit] pypy default: Add a realpath() here to support symlinks to "rpython". Message-ID: <20130213103523.3D0B81C1244@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r61171:193acd48ceee Date: 2013-02-13 11:35 +0100 http://bitbucket.org/pypy/pypy/changeset/193acd48ceee/ Log: Add a realpath() here to support symlinks to "rpython". diff --git a/rpython/bin/rpython b/rpython/bin/rpython --- a/rpython/bin/rpython +++ b/rpython/bin/rpython @@ -8,7 +8,8 @@ """ import sys, os -sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.dirname(__file__)))) +sys.path.insert(0, os.path.dirname(os.path.dirname( + os.path.dirname(os.path.realpath(__file__))))) from rpython.translator.goal.translate import main # no implicit targets From noreply at buildbot.pypy.org Wed Feb 13 12:17:36 2013 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 13 Feb 2013 12:17:36 +0100 (CET) Subject: [pypy-commit] pypy default: Update the version number. Message-ID: <20130213111736.865271C0EB1@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r61172:281597744e2a Date: 2013-02-13 12:17 +0100 http://bitbucket.org/pypy/pypy/changeset/281597744e2a/ Log: Update the version number. diff --git a/pypy/module/_cffi_backend/__init__.py b/pypy/module/_cffi_backend/__init__.py --- a/pypy/module/_cffi_backend/__init__.py +++ b/pypy/module/_cffi_backend/__init__.py @@ -7,7 +7,7 @@ appleveldefs = { } interpleveldefs = { - '__version__': 'space.wrap("0.4")', + '__version__': 'space.wrap("0.6")', 'load_library': 'libraryobj.load_library', diff --git a/pypy/module/_cffi_backend/test/_backend_test_c.py b/pypy/module/_cffi_backend/test/_backend_test_c.py --- a/pypy/module/_cffi_backend/test/_backend_test_c.py +++ b/pypy/module/_cffi_backend/test/_backend_test_c.py @@ -2728,3 +2728,7 @@ d = newp(BShortArray, [40, 50]) c[1:3] = d assert list(c) == [0, 40, 50, 30, 0] + +def test_version(): + # this test is here mostly for PyPy + assert __version__ == "0.6" From noreply at buildbot.pypy.org Wed Feb 13 12:17:39 2013 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 13 Feb 2013 12:17:39 +0100 (CET) Subject: [pypy-commit] cffi default: Another test that version number matches. Message-ID: <20130213111739.4C13F1C0EB1@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r1156:66926e0d11ca Date: 2013-02-13 12:16 +0100 http://bitbucket.org/cffi/cffi/changeset/66926e0d11ca/ Log: Another test that version number matches. diff --git a/c/test_c.py b/c/test_c.py --- a/c/test_c.py +++ b/c/test_c.py @@ -4,7 +4,7 @@ sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..')) _setup_path() from _cffi_backend import * -from _cffi_backend import _testfunc, _get_types +from _cffi_backend import _testfunc, _get_types, __version__ # ____________________________________________________________ @@ -2736,3 +2736,7 @@ d = newp(BShortArray, [40, 50]) c[1:3] = d assert list(c) == [0, 40, 50, 30, 0] + +def test_version(): + # this test is here mostly for PyPy + assert __version__ == "0.6" diff --git a/testing/test_version.py b/testing/test_version.py --- a/testing/test_version.py +++ b/testing/test_version.py @@ -35,3 +35,10 @@ # v = cffi.__version__ assert ("version='%s'" % v) in content + +def test_c_version(): + parent = os.path.dirname(os.path.dirname(__file__)) + v = cffi.__version__ + p = os.path.join(parent, 'c', 'test_c.py') + content = open(p).read() + assert ('assert __version__ == "%s"' % v) in content From noreply at buildbot.pypy.org Wed Feb 13 12:29:52 2013 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 13 Feb 2013 12:29:52 +0100 (CET) Subject: [pypy-commit] pypy default: tweak Message-ID: <20130213112952.C684E1C1029@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r61173:a3e07b691eae Date: 2013-02-13 12:25 +0100 http://bitbucket.org/pypy/pypy/changeset/a3e07b691eae/ Log: tweak diff --git a/pypy/module/_cffi_backend/ctypeptr.py b/pypy/module/_cffi_backend/ctypeptr.py --- a/pypy/module/_cffi_backend/ctypeptr.py +++ b/pypy/module/_cffi_backend/ctypeptr.py @@ -175,7 +175,7 @@ class W_CTypePointer(W_CTypePtrBase): _attrs_ = ['is_file', 'cache_array_type'] - _immutable_fields_ = ['is_file'] + _immutable_fields_ = ['is_file', 'cache_array_type?'] kind = "pointer" cache_array_type = None From noreply at buildbot.pypy.org Wed Feb 13 12:29:54 2013 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 13 Feb 2013 12:29:54 +0100 (CET) Subject: [pypy-commit] pypy default: Compatibility Message-ID: <20130213112954.006ED1C1029@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r61174:dee788c3bc7b Date: 2013-02-13 12:29 +0100 http://bitbucket.org/pypy/pypy/changeset/dee788c3bc7b/ Log: Compatibility diff --git a/pypy/module/_cffi_backend/newtype.py b/pypy/module/_cffi_backend/newtype.py --- a/pypy/module/_cffi_backend/newtype.py +++ b/pypy/module/_cffi_backend/newtype.py @@ -342,8 +342,13 @@ # if ((fresult.size < 0 and not isinstance(fresult, ctypevoid.W_CTypeVoid)) or isinstance(fresult, ctypearray.W_CTypeArray)): - raise operationerrfmt(space.w_TypeError, - "invalid result type: '%s'", fresult.name) + if (isinstance(fresult, ctypestruct.W_CTypeStructOrUnion) and + fresult.size < 0): + raise operationerrfmt(space.w_TypeError, + "result type '%s' is opaque", fresult.name) + else: + raise operationerrfmt(space.w_TypeError, + "invalid result type: '%s'", fresult.name) # fct = ctypefunc.W_CTypeFunc(space, fargs, fresult, ellipsis) return fct From noreply at buildbot.pypy.org Wed Feb 13 12:30:33 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Wed, 13 Feb 2013 12:30:33 +0100 (CET) Subject: [pypy-commit] pypy default: revert this _io change, not worth differing from cpython Message-ID: <20130213113033.66EDD1C1029@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61175:0fa3dc324460 Date: 2013-02-13 06:22 -0500 http://bitbucket.org/pypy/pypy/changeset/0fa3dc324460/ Log: revert this _io change, not worth differing from cpython diff --git a/pypy/module/_io/interp_bufferedio.py b/pypy/module/_io/interp_bufferedio.py --- a/pypy/module/_io/interp_bufferedio.py +++ b/pypy/module/_io/interp_bufferedio.py @@ -260,7 +260,7 @@ raise operationerrfmt(space.w_ValueError, "whence must be between 0 and 2, not %d", whence) self._check_closed(space, "seek of closed file") - if whence != 2 and self.readable and self.read_end != -1: + if whence != 2 and self.readable: # Check if seeking leaves us inside the current buffer, so as to # return quickly if possible. Also, we needn't take the lock in # this fast path. @@ -268,15 +268,16 @@ self._raw_tell(space) current = self.abs_pos available = self._readahead() - if whence == 0: - offset = pos - (current - self._raw_offset()) - else: - offset = pos - if -self.pos <= offset <= available: - newpos = self.pos + offset - assert newpos >= 0 - self.pos = newpos - return space.wrap(current - available + offset) + if available > 0: + if whence == 0: + offset = pos - (current - self._raw_offset()) + else: + offset = pos + if -self.pos <= offset <= available: + newpos = self.pos + offset + assert newpos >= 0 + self.pos = newpos + return space.wrap(current - available + offset) # Fallback: invoke raw seek() method and clear buffer with self.lock: diff --git a/pypy/module/_io/test/test_bufferedio.py b/pypy/module/_io/test/test_bufferedio.py --- a/pypy/module/_io/test/test_bufferedio.py +++ b/pypy/module/_io/test/test_bufferedio.py @@ -153,19 +153,6 @@ assert f.read() == "\nc" f.close() - def test_seek_nocall(self): - # test that when we're at the end of the buffer, - # an in-buffer back seek doesn't produce a raw seek - import _io - raw = _io.FileIO(self.tmpfile) - f = _io.BufferedReader(raw, buffer_size=3) - f.read(1) - f.seek(3, 0) - def failing_seek(*args): - assert False - raw.seek = failing_seek - f.seek(-1, 1) - def test_readlines(self): import _io raw = _io.FileIO(self.tmpfile) @@ -604,7 +591,7 @@ expected[j] = 2 expected[i] = 1 assert raw.getvalue() == str(expected) - + def test_interleaved_read_write(self): import _io as io # Test for issue #12213 From noreply at buildbot.pypy.org Wed Feb 13 12:32:57 2013 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 13 Feb 2013 12:32:57 +0100 (CET) Subject: [pypy-commit] cffi default: Bah, seems Yet Another ctypes limitation of PyPy. Don't fully care :-/ Message-ID: <20130213113257.65F931C1029@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r1157:43c968f23b02 Date: 2013-02-13 12:32 +0100 http://bitbucket.org/cffi/cffi/changeset/43c968f23b02/ Log: Bah, seems Yet Another ctypes limitation of PyPy. Don't fully care :-/ diff --git a/testing/test_function.py b/testing/test_function.py --- a/testing/test_function.py +++ b/testing/test_function.py @@ -276,6 +276,9 @@ def test_function_with_struct_argument(self): if sys.platform == 'win32': py.test.skip("no 'inet_ntoa'") + if (self.Backend is CTypesBackend and + '__pypy__' in sys.builtin_module_names): + py.test.skip("ctypes limitation on pypy") ffi = FFI(backend=self.Backend()) ffi.cdef(""" struct in_addr { unsigned int s_addr; }; From noreply at buildbot.pypy.org Wed Feb 13 18:40:13 2013 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 13 Feb 2013 18:40:13 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: small fixes Message-ID: <20130213174013.EB9AF1C01A7@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61176:4085f406efb4 Date: 2013-02-13 19:39 +0200 http://bitbucket.org/pypy/pypy/changeset/4085f406efb4/ Log: small fixes diff --git a/rpython/jit/backend/arm/regalloc.py b/rpython/jit/backend/arm/regalloc.py --- a/rpython/jit/backend/arm/regalloc.py +++ b/rpython/jit/backend/arm/regalloc.py @@ -301,7 +301,7 @@ def prepare_loop(self, inputargs, operations, looptoken, allgcrefs): operations = self._prepare(inputargs, operations, allgcrefs) - self._set_initial_bindings(inputargs) + self._set_initial_bindings(inputargs, looptoken) self.possibly_free_vars(list(inputargs)) return operations @@ -311,7 +311,6 @@ self._update_bindings(arglocs, inputargs) return operations - def get_final_frame_depth(self): return self.frame_manager.get_frame_depth() @@ -749,15 +748,16 @@ # we would like the boxes to be after the jump. def _compute_hint_frame_locations_from_descr(self, descr): - arglocs = self.assembler.target_arglocs(descr) - jump_op = self.final_jump_op - assert len(arglocs) == jump_op.numargs() - for i in range(jump_op.numargs()): - box = jump_op.getarg(i) - if isinstance(box, Box): - loc = arglocs[i] - if loc is not None and loc.is_stack(): - self.frame_manager.hint_frame_locations[box] = loc + return + #arglocs = self.assembler.target_arglocs(descr) + #jump_op = self.final_jump_op + #assert len(arglocs) == jump_op.numargs() + #for i in range(jump_op.numargs()): + # box = jump_op.getarg(i) + # if isinstance(box, Box): + # loc = arglocs[i] + # if loc is not None and loc.is_stack(): + # self.frame_manager.hint_frame_locations[box] = loc def prepare_op_jump(self, op, fcond): descr = op.getdescr() diff --git a/rpython/jit/backend/x86/regalloc.py b/rpython/jit/backend/x86/regalloc.py --- a/rpython/jit/backend/x86/regalloc.py +++ b/rpython/jit/backend/x86/regalloc.py @@ -4,7 +4,7 @@ import os from rpython.jit.metainterp.history import (Box, Const, ConstInt, ConstPtr, - BoxPtr, ConstFloat, BoxInt, + ConstFloat, BoxInt, BoxFloat, INT, REF, FLOAT, TargetToken, JitCellToken) from rpython.jit.backend.x86.regloc import * From noreply at buildbot.pypy.org Wed Feb 13 18:46:20 2013 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 13 Feb 2013 18:46:20 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: skip those tests for now Message-ID: <20130213174620.756261C01A7@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61177:bb1b80dd503b Date: 2013-02-13 19:45 +0200 http://bitbucket.org/pypy/pypy/changeset/bb1b80dd503b/ Log: skip those tests for now diff --git a/rpython/jit/backend/arm/test/test_runner.py b/rpython/jit/backend/arm/test/test_runner.py --- a/rpython/jit/backend/arm/test/test_runner.py +++ b/rpython/jit/backend/arm/test/test_runner.py @@ -33,6 +33,7 @@ return cpu def test_result_is_spilled(self): + py.test.skip("later") cpu = self.cpu inp = [BoxInt(i) for i in range(1, 15)] out = [BoxInt(i) for i in range(1, 15)] @@ -66,6 +67,7 @@ assert output == expected def test_redirect_call_assembler2(self): + py.test.skip("later") def assembler_helper(deadframe, virtualizable): x = self.cpu.get_latest_value_int(deadframe, 0) assert x == 11 @@ -161,6 +163,7 @@ ('next', lltype.Ptr(SFloat))) def test_float_field(self): + py.test.skip("later") if not self.cpu.supports_floats: py.test.skip('requires floats') floatdescr = self.cpu.fielddescrof(self.SFloat, 'float') @@ -178,6 +181,7 @@ assert res.getfloat() == -3.6 def test_compile_loop_many_int_args(self): + py.test.skip("later") for numargs in range(2, 30): for _ in range(numargs): self.cpu.reserve_some_free_fail_descr_number() @@ -208,6 +212,7 @@ assert self.cpu.get_latest_value_int(deadframe, 0) == sum(args) def test_debugger_on(self): + py.test.skip("later") from rpython.rlib import debug targettoken, preambletoken = TargetToken(), TargetToken() From noreply at buildbot.pypy.org Wed Feb 13 19:18:50 2013 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 13 Feb 2013 19:18:50 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: move two copies of slightly different code into one place Message-ID: <20130213181850.3A3101C0EB1@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61178:9ea48f1df7ad Date: 2013-02-13 20:09 +0200 http://bitbucket.org/pypy/pypy/changeset/9ea48f1df7ad/ Log: move two copies of slightly different code into one place diff --git a/rpython/jit/backend/arm/locations.py b/rpython/jit/backend/arm/locations.py --- a/rpython/jit/backend/arm/locations.py +++ b/rpython/jit/backend/arm/locations.py @@ -24,6 +24,8 @@ def as_key(self): raise NotImplementedError + def get_position(self): + raise NotImplementedError # only for stack class RegisterLocation(AssemblerLocation): _immutable_ = True @@ -122,6 +124,9 @@ def location_code(self): return 'b' + def get_position(self): + return self.position + def assembler(self): return repr(self) diff --git a/rpython/jit/backend/arm/opassembler.py b/rpython/jit/backend/arm/opassembler.py --- a/rpython/jit/backend/arm/opassembler.py +++ b/rpython/jit/backend/arm/opassembler.py @@ -21,59 +21,31 @@ from rpython.jit.backend.arm.jump import remap_frame_layout from rpython.jit.backend.arm.regalloc import TempInt, TempPtr from rpython.jit.backend.arm.locations import imm -from rpython.jit.backend.llsupport import symbolic, jitframe +from rpython.jit.backend.llsupport import symbolic from rpython.jit.backend.llsupport.gcmap import allocate_gcmap from rpython.jit.backend.llsupport.descr import InteriorFieldDescr +from rpython.jit.backend.llsupport.assembler import GuardToken from rpython.jit.metainterp.history import (Box, AbstractFailDescr, INT, FLOAT, REF) from rpython.jit.metainterp.history import JitCellToken, TargetToken from rpython.jit.metainterp.resoperation import rop from rpython.rlib.objectmodel import we_are_translated from rpython.rlib import rgc -from rpython.rtyper.lltypesystem import rstr, rffi, lltype, llmemory -from rpython.rlib.rarithmetic import r_uint +from rpython.rtyper.lltypesystem import rstr, rffi, lltype from rpython.rtyper.annlowlevel import cast_instance_to_gcref NO_FORCE_INDEX = -1 -class GuardToken(object): - def __init__(self, gcmap, faildescr, failargs, fail_locs, offset, exc, - frame_depth, fcond=c.AL, is_guard_not_invalidated=False, - is_guard_not_forced=False): - assert isinstance(exc, bool) - self.faildescr = faildescr - self.failargs = failargs - self.fail_locs = fail_locs - self.offset = offset - self.gcmap = self.compute_gcmap(gcmap, failargs, - fail_locs, frame_depth) - self.exc = exc - self.is_guard_not_invalidated = is_guard_not_invalidated - self.is_guard_not_forced = is_guard_not_forced +class ArmGuardToken(GuardToken): + def __init__(self, cpu, gcmap, faildescr, failargs, fail_locs, + offset, exc, frame_depth, is_guard_not_invalidated=False, + is_guard_not_forced=False, fcond=c.AL): + GuardToken.__init__(self, cpu, gcmap, faildescr, failargs, fail_locs, + offset, exc, frame_depth, is_guard_not_invalidated, + is_guard_not_forced) self.fcond = fcond - def compute_gcmap(self, gcmap, failargs, fail_locs, frame_depth): - # note that regalloc has a very similar compute, but - # one that does iteration over all bindings, so slightly different, - # eh - input_i = 0 - for i in range(len(failargs)): - arg = failargs[i] - if arg is None: - continue - loc = fail_locs[input_i] - input_i += 1 - if arg.type == REF: - loc = fail_locs[i] - if loc.is_reg(): - val = loc.value - else: - assert loc.is_stack() - val = JITFRAME_FIXED_SIZE + loc.value - gcmap[val // WORD // 8] |= r_uint(1) << (val % (WORD * 8)) - return gcmap - class ResOpAssembler(object): @@ -237,7 +209,7 @@ else: self.mc.BKPT() gcmap = allocate_gcmap(self, arglocs[0].value, JITFRAME_FIXED_SIZE) - self.pending_guards.append(GuardToken(gcmap, + self.pending_guards.append(ArmGuardToken(self.cpu, gcmap, descr, failargs=op.getfailargs(), fail_locs=arglocs[1:], diff --git a/rpython/jit/backend/llsupport/assembler.py b/rpython/jit/backend/llsupport/assembler.py new file mode 100644 --- /dev/null +++ b/rpython/jit/backend/llsupport/assembler.py @@ -0,0 +1,41 @@ + +from rpython.rlib.rarithmetic import r_uint +from rpython.jit.backend.llsupport.symbolic import WORD +from rpython.jit.metainterp.history import REF + +class GuardToken(object): + def __init__(self, cpu, gcmap, faildescr, failargs, fail_locs, exc, + frame_depth, is_guard_not_invalidated, is_guard_not_forced): + self.cpu = cpu + self.faildescr = faildescr + self.failargs = failargs + self.fail_locs = fail_locs + self.gcmap = self.compute_gcmap(gcmap, failargs, + fail_locs, frame_depth) + self.exc = exc + self.is_guard_not_invalidated = is_guard_not_invalidated + self.is_guard_not_forced = is_guard_not_forced + + def compute_gcmap(self, gcmap, failargs, fail_locs, frame_depth): + # note that regalloc has a very similar compute, but + # one that does iteration over all bindings, so slightly different, + # eh + input_i = 0 + for i in range(len(failargs)): + arg = failargs[i] + if arg is None: + continue + loc = fail_locs[input_i] + input_i += 1 + if arg.type == REF: + loc = fail_locs[i] + if loc.is_reg(): + val = self.cpu.gpr_reg_mgr_cls.all_reg_indexes[loc.value] + else: + val = loc.get_position() + self.cpu.JITFRAME_FIXED_SIZE + gcmap[val // WORD // 8] |= r_uint(1) << (val % (WORD * 8)) + return gcmap + +class BaseAssembler(object): + """ Base class for Assembler generator in real backends + """ diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -1,6 +1,7 @@ import sys, os from rpython.jit.backend.llsupport import symbolic, jitframe +from rpython.jit.backend.llsupport.assembler import GuardToken, BaseAssembler from rpython.jit.backend.llsupport.asmmemmgr import MachineDataBlockWrapper from rpython.jit.backend.llsupport.gcmap import allocate_gcmap from rpython.jit.metainterp.history import Const, Box, BoxInt, ConstInt @@ -42,46 +43,12 @@ def align_stack_words(words): return (words + CALL_ALIGN - 1) & ~(CALL_ALIGN-1) - -class GuardToken(object): - def __init__(self, gcmap, faildescr, failargs, fail_locs, exc, - frame_depth, is_guard_not_invalidated, is_guard_not_forced): - self.faildescr = faildescr - self.failargs = failargs - self.fail_locs = fail_locs - self.gcmap = self.compute_gcmap(gcmap, failargs, - fail_locs, frame_depth) - self.exc = exc - self.is_guard_not_invalidated = is_guard_not_invalidated - self.is_guard_not_forced = is_guard_not_forced - - def compute_gcmap(self, gcmap, failargs, fail_locs, frame_depth): - # note that regalloc has a very similar compute, but - # one that does iteration over all bindings, so slightly different, - # eh - input_i = 0 - for i in range(len(failargs)): - arg = failargs[i] - if arg is None: - continue - loc = fail_locs[input_i] - input_i += 1 - if arg.type == REF: - loc = fail_locs[i] - if isinstance(loc, RegLoc): - val = gpr_reg_mgr_cls.all_reg_indexes[loc.value] - else: - assert isinstance(loc, StackLoc) - val = loc.position + JITFRAME_FIXED_SIZE - gcmap[val // WORD // 8] |= r_uint(1) << (val % (WORD * 8)) - return gcmap - DEBUG_COUNTER = lltype.Struct('DEBUG_COUNTER', ('i', lltype.Signed), ('type', lltype.Char), # 'b'ridge, 'l'abel or # 'e'ntry point ('number', lltype.Signed)) -class Assembler386(object): +class Assembler386(BaseAssembler): _regalloc = None _output_loop_log = None @@ -1886,7 +1853,7 @@ is_guard_not_invalidated = guard_opnum == rop.GUARD_NOT_INVALIDATED is_guard_not_forced = guard_opnum == rop.GUARD_NOT_FORCED gcmap = allocate_gcmap(self, frame_depth, JITFRAME_FIXED_SIZE) - return GuardToken(gcmap, faildescr, failargs, + return GuardToken(self.cpu, gcmap, faildescr, failargs, fail_locs, exc, frame_depth, is_guard_not_invalidated, is_guard_not_forced) diff --git a/rpython/jit/backend/x86/regloc.py b/rpython/jit/backend/x86/regloc.py --- a/rpython/jit/backend/x86/regloc.py +++ b/rpython/jit/backend/x86/regloc.py @@ -42,6 +42,15 @@ def find_unused_reg(self): return eax + def is_stack(self): + return False + + def is_reg(self): + return False + + def get_position(self): + raise NotImplementedError # only for stack + class RawStackLoc(AssemblerLocation): """ The same as stack location, but does not know it's position. Mostly usable for raw frame access @@ -70,6 +79,9 @@ def add_offset(self, ofs): return RawStackLoc(self.value + ofs) + def is_stack(self): + return True + class RawEspLoc(AssemblerLocation): """ Esp-based location """ @@ -113,6 +125,9 @@ # One of INT, REF, FLOAT self.type = type + def get_position(self): + return self.position + class RegLoc(AssemblerLocation): _immutable_ = True def __init__(self, regnum, is_xmm): @@ -154,6 +169,9 @@ def is_float(self): return self.is_xmm + def is_reg(self): + return True + class ImmediateAssemblerLocation(AssemblerLocation): _immutable_ = True diff --git a/rpython/jit/backend/x86/runner.py b/rpython/jit/backend/x86/runner.py --- a/rpython/jit/backend/x86/runner.py +++ b/rpython/jit/backend/x86/runner.py @@ -1,18 +1,13 @@ import py from rpython.rlib.unroll import unrolling_iterable from rpython.rtyper.lltypesystem import lltype, llmemory, rffi -from rpython.rtyper.lltypesystem.lloperation import llop from rpython.rtyper.llinterp import LLInterpreter -from rpython.rlib.objectmodel import specialize from rpython.rlib.jit_hooks import LOOP_RUN_CONTAINER from rpython.jit.metainterp import history from rpython.jit.backend.x86.assembler import Assembler386 -from rpython.jit.backend.x86.arch import IS_X86_32, JITFRAME_FIXED_SIZE from rpython.jit.backend.x86.profagent import ProfileAgent from rpython.jit.backend.llsupport.llmodel import AbstractLLCPU -from rpython.jit.backend.llsupport import jitframe from rpython.jit.backend.x86 import regloc -from rpython.jit.backend.llsupport.symbolic import WORD import sys @@ -29,6 +24,8 @@ dont_keepalive_stuff = False # for tests with_threads = False + from rpython.jit.backend.x86.arch import JITFRAME_FIXED_SIZE + def __init__(self, rtyper, stats, opts=None, translate_support_code=False, gcdescr=None): AbstractLLCPU.__init__(self, rtyper, stats, opts, From noreply at buildbot.pypy.org Wed Feb 13 19:18:51 2013 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 13 Feb 2013 19:18:51 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: Kill two copies of the same code for make_execute_token Message-ID: <20130213181851.8B32C1C0EB1@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61179:33f35592a600 Date: 2013-02-13 20:17 +0200 http://bitbucket.org/pypy/pypy/changeset/33f35592a600/ Log: Kill two copies of the same code for make_execute_token diff --git a/rpython/jit/backend/arm/assembler.py b/rpython/jit/backend/arm/assembler.py --- a/rpython/jit/backend/arm/assembler.py +++ b/rpython/jit/backend/arm/assembler.py @@ -641,7 +641,7 @@ self.write_pending_failure_recoveries() rawstart = self.materialize_loop(looptoken) - looptoken._function_addr = looptoken._arm_func_addr = rawstart + looptoken._function_addr = looptoken._ll_function_addr = rawstart self.process_pending_guards(rawstart) self.fixup_target_tokens(rawstart) diff --git a/rpython/jit/backend/arm/opassembler.py b/rpython/jit/backend/arm/opassembler.py --- a/rpython/jit/backend/arm/opassembler.py +++ b/rpython/jit/backend/arm/opassembler.py @@ -1112,7 +1112,7 @@ assert isinstance(descr, JitCellToken) # check value assert tmploc is r.r0 - self._emit_call(imm(descr._arm_func_addr), + self._emit_call(imm(descr._ll_function_addr), callargs, fcond, resloc=tmploc) if op.result is None: value = self.cpu.done_with_this_frame_void_v @@ -1243,12 +1243,12 @@ new_nbargs = newlooptoken.compiled_loop_token._debug_nbargs assert old_nbargs == new_nbargs # we overwrite the instructions at the old _arm_func_adddr - # to start with a JMP to the new _arm_func_addr. + # to start with a JMP to the new _ll_function_addr. # Ideally we should rather patch all existing CALLs, but well. XXX # this is wrong, copy the logic from x86, but also, shouldn't # it live on a base class instead? - oldadr = oldlooptoken._arm_func_addr - target = newlooptoken._arm_func_addr + oldadr = oldlooptoken._ll_function_addr + target = newlooptoken._ll_function_addr mc = ARMv7Builder() mc.B(target) mc.copy_to_raw_memory(oldadr) diff --git a/rpython/jit/backend/arm/runner.py b/rpython/jit/backend/arm/runner.py --- a/rpython/jit/backend/arm/runner.py +++ b/rpython/jit/backend/arm/runner.py @@ -65,52 +65,6 @@ for index in range(count): setitem(index, null) - def make_execute_token(self, *ARGS): - FUNCPTR = lltype.Ptr(lltype.FuncType([llmemory.GCREF], - llmemory.GCREF)) - - lst = [(i, history.getkind(ARG)[0]) for i, ARG in enumerate(ARGS)] - kinds = unrolling_iterable(lst) - - def execute_token(executable_token, *args): - clt = executable_token.compiled_loop_token - assert len(args) == clt._debug_nbargs - # - addr = executable_token._arm_func_addr - assert addr % 8 == 0 - func = rffi.cast(FUNCPTR, addr) - #llop.debug_print(lltype.Void, ">>>> Entering", addr) - frame_info = clt.frame_info - frame = self.gc_ll_descr.malloc_jitframe(frame_info) - ll_frame = lltype.cast_opaque_ptr(llmemory.GCREF, frame) - prev_interpreter = None # help flow space - if not self.translate_support_code: - prev_interpreter = LLInterpreter.current_interpreter - LLInterpreter.current_interpreter = self.debug_ll_interpreter - try: - num = JITFRAME_FIXED_SIZE * WORD - for i, kind in kinds: - arg = args[i] - if kind == history.INT: - self.set_int_value(ll_frame, num, arg) - elif kind == history.FLOAT: - self.set_float_value(ll_frame, num, arg) - num += WORD # on ARM(32 bit) a FLOAT needs two words - else: - assert kind == history.REF - self.set_ref_value(ll_frame, num, arg) - num += WORD - # no GC operation between gc_assume_young_pointers and - # the actual call to assembler! - llop.gc_assume_young_pointers(lltype.Void, frame) - ll_frame = func(ll_frame) - finally: - if not self.translate_support_code: - LLInterpreter.current_interpreter = prev_interpreter - #llop.debug_print(lltype.Void, "<<<< Back") - return ll_frame - return execute_token - def cast_ptr_to_int(x): adr = llmemory.cast_ptr_to_adr(x) return ArmCPU.cast_adr_to_int(adr) diff --git a/rpython/jit/backend/arm/test/test_regalloc.py b/rpython/jit/backend/arm/test/test_regalloc.py --- a/rpython/jit/backend/arm/test/test_regalloc.py +++ b/rpython/jit/backend/arm/test/test_regalloc.py @@ -791,7 +791,7 @@ large = self.interpret(loop1, range(11), run=False) large._jitcelltoken.outermost_jitdriver_sd = FakeJitDriverSD() self.namespace['looptoken'] = large._jitcelltoken - assert self.namespace['looptoken']._arm_func_addr != 0 + assert self.namespace['looptoken']._ll_function_addr != 0 loop2 = """ [i0] i1 = force_token() diff --git a/rpython/jit/backend/llsupport/llmodel.py b/rpython/jit/backend/llsupport/llmodel.py --- a/rpython/jit/backend/llsupport/llmodel.py +++ b/rpython/jit/backend/llsupport/llmodel.py @@ -15,6 +15,7 @@ FLAG_POINTER, FLAG_FLOAT) from rpython.jit.backend.llsupport.asmmemmgr import AsmMemoryManager from rpython.annotator import model as annmodel +from rpython.rlib.unroll import unrolling_iterable class AbstractLLCPU(AbstractCPU): @@ -187,6 +188,47 @@ frame.jf_descr = frame.jf_force_descr return lltype.cast_opaque_ptr(llmemory.GCREF, frame) + def make_execute_token(self, *ARGS): + FUNCPTR = lltype.Ptr(lltype.FuncType([llmemory.GCREF], + llmemory.GCREF)) + + lst = [(i, history.getkind(ARG)[0]) for i, ARG in enumerate(ARGS)] + kinds = unrolling_iterable(lst) + + def execute_token(executable_token, *args): + clt = executable_token.compiled_loop_token + assert len(args) == clt._debug_nbargs + # + addr = executable_token._ll_function_addr + func = rffi.cast(FUNCPTR, addr) + #llop.debug_print(lltype.Void, ">>>> Entering", addr) + frame_info = clt.frame_info + frame = self.gc_ll_descr.malloc_jitframe(frame_info) + ll_frame = lltype.cast_opaque_ptr(llmemory.GCREF, frame) + locs = executable_token.compiled_loop_token._ll_initial_locs + prev_interpreter = None # help flow space + if not self.translate_support_code: + prev_interpreter = LLInterpreter.current_interpreter + LLInterpreter.current_interpreter = self.debug_ll_interpreter + try: + for i, kind in kinds: + arg = args[i] + num = locs[i] + if kind == history.INT: + self.set_int_value(ll_frame, num, arg) + elif kind == history.FLOAT: + self.set_float_value(ll_frame, num, arg) + else: + assert kind == history.REF + self.set_ref_value(ll_frame, num, arg) + ll_frame = func(ll_frame) + finally: + if not self.translate_support_code: + LLInterpreter.current_interpreter = prev_interpreter + #llop.debug_print(lltype.Void, "<<<< Back") + return ll_frame + return execute_token + # ------------------- helpers and descriptions -------------------- @staticmethod diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -472,7 +472,7 @@ def assemble_loop(self, loopname, inputargs, operations, looptoken, log): '''adds the following attributes to looptoken: - _x86_function_addr (address of the generated func, as an int) + _ll_function_addr (address of the generated func, as an int) _x86_loop_code (debug: addr of the start of the ResOps) _x86_fullsize (debug: full size including failure) _x86_debug_checksum @@ -531,7 +531,7 @@ looptoken._x86_rawstart = rawstart looptoken._x86_fullsize = full_size looptoken._x86_ops_offset = ops_offset - looptoken._x86_function_addr = rawstart + looptoken._ll_function_addr = rawstart self.fixup_target_tokens(rawstart) self.teardown() @@ -865,11 +865,11 @@ old_nbargs = oldlooptoken.compiled_loop_token._debug_nbargs new_nbargs = newlooptoken.compiled_loop_token._debug_nbargs assert old_nbargs == new_nbargs - # we overwrite the instructions at the old _x86_function_addr - # to start with a JMP to the new _x86_function_addr. + # we overwrite the instructions at the old _ll_function_addr + # to start with a JMP to the new _ll_function_addr. # Ideally we should rather patch all existing CALLs, but well. - oldadr = oldlooptoken._x86_function_addr - target = newlooptoken._x86_function_addr + oldadr = oldlooptoken._ll_function_addr + target = newlooptoken._ll_function_addr # copy frame-info data baseofs = self.cpu.get_baseofs_of_frame_field() newlooptoken.compiled_loop_token.update_frame_info( @@ -2274,7 +2274,7 @@ # execute_token jd = descr.outermost_jitdriver_sd base_ofs = self.cpu.get_baseofs_of_frame_field() - self._emit_call(imm(descr._x86_function_addr), + self._emit_call(imm(descr._ll_function_addr), [argloc], 0, tmp=eax) if op.result is None: assert result_loc is None diff --git a/rpython/jit/backend/x86/runner.py b/rpython/jit/backend/x86/runner.py --- a/rpython/jit/backend/x86/runner.py +++ b/rpython/jit/backend/x86/runner.py @@ -1,9 +1,6 @@ import py -from rpython.rlib.unroll import unrolling_iterable from rpython.rtyper.lltypesystem import lltype, llmemory, rffi -from rpython.rtyper.llinterp import LLInterpreter from rpython.rlib.jit_hooks import LOOP_RUN_CONTAINER -from rpython.jit.metainterp import history from rpython.jit.backend.x86.assembler import Assembler386 from rpython.jit.backend.x86.profagent import ProfileAgent from rpython.jit.backend.llsupport.llmodel import AbstractLLCPU @@ -97,47 +94,6 @@ for index in range(count): setitem(index, null) - def make_execute_token(self, *ARGS): - FUNCPTR = lltype.Ptr(lltype.FuncType([llmemory.GCREF], - llmemory.GCREF)) - - lst = [(i, history.getkind(ARG)[0]) for i, ARG in enumerate(ARGS)] - kinds = unrolling_iterable(lst) - - def execute_token(executable_token, *args): - clt = executable_token.compiled_loop_token - assert len(args) == clt._debug_nbargs - # - addr = executable_token._x86_function_addr - func = rffi.cast(FUNCPTR, addr) - #llop.debug_print(lltype.Void, ">>>> Entering", addr) - frame_info = clt.frame_info - frame = self.gc_ll_descr.malloc_jitframe(frame_info) - ll_frame = lltype.cast_opaque_ptr(llmemory.GCREF, frame) - locs = executable_token.compiled_loop_token._ll_initial_locs - prev_interpreter = None # help flow space - if not self.translate_support_code: - prev_interpreter = LLInterpreter.current_interpreter - LLInterpreter.current_interpreter = self.debug_ll_interpreter - try: - for i, kind in kinds: - arg = args[i] - num = locs[i] - if kind == history.INT: - self.set_int_value(ll_frame, num, arg) - elif kind == history.FLOAT: - self.set_float_value(ll_frame, num, arg) - else: - assert kind == history.REF - self.set_ref_value(ll_frame, num, arg) - ll_frame = func(ll_frame) - finally: - if not self.translate_support_code: - LLInterpreter.current_interpreter = prev_interpreter - #llop.debug_print(lltype.Void, "<<<< Back") - return ll_frame - return execute_token - def cast_ptr_to_int(x): adr = llmemory.cast_ptr_to_adr(x) return CPU386.cast_adr_to_int(adr) From noreply at buildbot.pypy.org Wed Feb 13 19:22:17 2013 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 13 Feb 2013 19:22:17 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: this field does not go on parent Message-ID: <20130213182217.3BB491C3C1D@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61180:bda3f3563773 Date: 2013-02-13 20:21 +0200 http://bitbucket.org/pypy/pypy/changeset/bda3f3563773/ Log: this field does not go on parent diff --git a/rpython/jit/backend/arm/opassembler.py b/rpython/jit/backend/arm/opassembler.py --- a/rpython/jit/backend/arm/opassembler.py +++ b/rpython/jit/backend/arm/opassembler.py @@ -42,9 +42,10 @@ offset, exc, frame_depth, is_guard_not_invalidated=False, is_guard_not_forced=False, fcond=c.AL): GuardToken.__init__(self, cpu, gcmap, faildescr, failargs, fail_locs, - offset, exc, frame_depth, is_guard_not_invalidated, + exc, frame_depth, is_guard_not_invalidated, is_guard_not_forced) self.fcond = fcond + self.offset = offset class ResOpAssembler(object): From noreply at buildbot.pypy.org Wed Feb 13 19:31:50 2013 From: noreply at buildbot.pypy.org (Aquana) Date: Wed, 13 Feb 2013 19:31:50 +0100 (CET) Subject: [pypy-commit] pypy quiet-rpython: hg merge default Message-ID: <20130213183150.588A11C3C1D@cobra.cs.uni-duesseldorf.de> Author: Alexander Hesse Branch: quiet-rpython Changeset: r61181:25fd117e5d53 Date: 2013-02-13 19:30 +0100 http://bitbucket.org/pypy/pypy/changeset/25fd117e5d53/ Log: hg merge default diff too long, truncating to 2000 out of 12999 lines diff --git a/LICENSE b/LICENSE --- a/LICENSE +++ b/LICENSE @@ -270,3 +270,24 @@ LineBreak-*.txt UnicodeData-*.txt UnihanNumeric-*.txt + +License for 'dotviewer/font/' +============================= + +Copyright (C) 2008 The Android Open Source Project + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +Detailled license information is contained in the NOTICE file in the +directory. + diff --git a/dotviewer/VeraMoBd.ttf b/dotviewer/VeraMoBd.ttf deleted file mode 100644 Binary file dotviewer/VeraMoBd.ttf has changed diff --git a/dotviewer/cyrvetic.ttf b/dotviewer/cyrvetic.ttf deleted file mode 100644 Binary file dotviewer/cyrvetic.ttf has changed diff --git a/dotviewer/drawgraph.py b/dotviewer/drawgraph.py --- a/dotviewer/drawgraph.py +++ b/dotviewer/drawgraph.py @@ -9,9 +9,10 @@ from pygame.locals import * +RAW_ENCODING = "utf-8" this_dir = os.path.dirname(os.path.abspath(__file__)) -FONT = os.path.join(this_dir, 'cyrvetic.ttf') -FIXEDFONT = os.path.join(this_dir, 'VeraMoBd.ttf') +FONT = os.path.join(this_dir, 'font', 'DroidSans.ttf') +FIXEDFONT = os.path.join(this_dir, 'font', 'DroidSansMono.ttf') COLOR = { 'black': (0,0,0), 'white': (255,255,255), @@ -51,6 +52,12 @@ else: return default +def forceunicode(name): + return name if isinstance(name, unicode) else name.decode(RAW_ENCODING) + +def forcestr(name): + return name if isinstance(name, str) else name.encode(RAW_ENCODING) + class GraphLayout: fixedfont = False @@ -106,12 +113,12 @@ class Node: def __init__(self, name, x, y, w, h, label, style, shape, color, fillcolor): - self.name = name + self.name = forceunicode(name) self.x = float(x) self.y = float(y) self.w = float(w) self.h = float(h) - self.label = label + self.label = forceunicode(label) self.style = style self.shape = shape self.color = color @@ -125,8 +132,8 @@ label = None def __init__(self, nodes, tail, head, cnt, *rest): - self.tail = nodes[tail] - self.head = nodes[head] + self.tail = nodes[forceunicode(tail)] + self.head = nodes[forceunicode(head)] cnt = int(cnt) self.points = [(float(rest[i]), float(rest[i+1])) for i in range(0, cnt*2, 2)] @@ -655,11 +662,7 @@ part = parts[i] word = part[0] try: - try: - img = font.render(word, False, *part[1:]) - except pygame.error, e: - # Try *with* anti-aliasing to work around a bug in SDL - img = font.render(word, True, *part[1:]) + img = font.render(word, True, *part[1:]) except pygame.error: del parts[i] # Text has zero width else: diff --git a/dotviewer/font/DroidSans-Bold.ttf b/dotviewer/font/DroidSans-Bold.ttf new file mode 100644 index 0000000000000000000000000000000000000000..d065b64eb1863f83c2c982264f9442f2313a44a9 GIT binary patch [cut] diff --git a/dotviewer/font/DroidSans.ttf b/dotviewer/font/DroidSans.ttf new file mode 100644 index 0000000000000000000000000000000000000000..ad1efca88aed8d9e2d179f27dd713e2a1562fe5f GIT binary patch [cut] diff --git a/dotviewer/font/DroidSansMono.ttf b/dotviewer/font/DroidSansMono.ttf new file mode 100644 index 0000000000000000000000000000000000000000..a007071944f7c90020e798eea53b10065e2b45a5 GIT binary patch [cut] diff --git a/dotviewer/font/NOTICE b/dotviewer/font/NOTICE new file mode 100644 --- /dev/null +++ b/dotviewer/font/NOTICE @@ -0,0 +1,190 @@ + + Copyright (c) 2005-2008, The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + diff --git a/dotviewer/font/README.txt b/dotviewer/font/README.txt new file mode 100644 --- /dev/null +++ b/dotviewer/font/README.txt @@ -0,0 +1,18 @@ +Copyright (C) 2008 The Android Open Source Project + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +########## + +This directory contains the fonts for the platform. They are licensed +under the Apache 2 license. diff --git a/dotviewer/graphclient.py b/dotviewer/graphclient.py --- a/dotviewer/graphclient.py +++ b/dotviewer/graphclient.py @@ -33,8 +33,9 @@ def reload(graph_id): page = getpage(graph_id) if save_tmp_file: + from drawgraph import forcestr f = open(save_tmp_file, 'w') - f.write(page.source) + f.write(forcestr(page.source)) f.close() messages.extend(page_messages(page, graph_id)) send_graph_messages(io, messages) @@ -75,7 +76,8 @@ def page_messages(page, graph_id): import graphparse - return graphparse.parse_dot(graph_id, page.source, page.links, + from drawgraph import forcestr + return graphparse.parse_dot(graph_id, forcestr(page.source), page.links, getattr(page, 'fixedfont', False)) def send_graph_messages(io, messages): diff --git a/dotviewer/graphdisplay.py b/dotviewer/graphdisplay.py --- a/dotviewer/graphdisplay.py +++ b/dotviewer/graphdisplay.py @@ -4,7 +4,7 @@ from pygame.locals import * from drawgraph import GraphRenderer, FIXEDFONT from drawgraph import Node, Edge -from drawgraph import EventQueue, wait_for_events +from drawgraph import EventQueue, wait_for_events, forceunicode, forcestr METAKEYS = dict([ @@ -285,7 +285,7 @@ if e.key == K_ESCAPE: return None elif e.key == K_RETURN: - return text.encode('latin-1') # XXX do better + return forcestr(text) # return encoded unicode elif e.key == K_BACKSPACE: text = text[:-1] elif e.unicode and ord(e.unicode) >= ord(' '): @@ -423,7 +423,7 @@ self.layout.request_reload() def setstatusbar(self, text, fgcolor=None, bgcolor=None): - info = (text, fgcolor or self.STATUSBAR_FGCOLOR, bgcolor or self.STATUSBAR_BGCOLOR) + info = (forceunicode(text), fgcolor or self.STATUSBAR_FGCOLOR, bgcolor or self.STATUSBAR_BGCOLOR) if info != self.statusbarinfo: self.statusbarinfo = info self.must_redraw = True @@ -711,7 +711,7 @@ lines = [] while words: line = words.pop(0) - img = font.render(line or ' ', 1, fgcolor) + img = font.render(line or ' ', True, fgcolor) while words: longerline = line + ' ' + words[0] longerimg = font.render(longerline, 1, fgcolor) @@ -723,7 +723,7 @@ img = longerimg w, h = img.get_size() if h > maxheight: - img = font.render('...', 1, overflowcolor) + img = font.render('...', True, overflowcolor) w, h = img.get_size() while lines and h > maxheight: maxheight += lines.pop().get_size()[1] diff --git a/dotviewer/graphpage.py b/dotviewer/graphpage.py --- a/dotviewer/graphpage.py +++ b/dotviewer/graphpage.py @@ -44,6 +44,8 @@ class DotFileGraphPage(GraphPage): def compute(self, dotfile): - f = open(dotfile, 'r') + import codecs + from drawgraph import RAW_ENCODING + f = codecs.open(dotfile, 'r', RAW_ENCODING) self.source = f.read() f.close() diff --git a/dotviewer/test/test_interactive_unicode.py b/dotviewer/test/test_interactive_unicode.py new file mode 100755 --- /dev/null +++ b/dotviewer/test/test_interactive_unicode.py @@ -0,0 +1,103 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +import py +import sys, os, signal, thread, time, codecs +from dotviewer.conftest import option +from dotviewer.drawgraph import RAW_ENCODING + +SOURCE1 = u"""digraph G{ +λ -> b +b -> μ +} +""" + +FILENAME = 'graph1.dot' + +def setup_module(mod): + if not option.pygame: + py.test.skip("--pygame not enabled") + udir = py.path.local.make_numbered_dir(prefix='usession-dot-', keep=3) + f = codecs.open(str(udir.join(FILENAME)), 'wb', RAW_ENCODING) + f.write(SOURCE1) + f.close() + + from dotviewer import graphclient + mod.pkgdir = py.path.local(graphclient.this_dir) + mod.udir = udir + + try: + del os.environ['GRAPHSERVER'] + except KeyError: + pass + + +def test_dotviewer(): + print "=== dotviewer.py %s" % FILENAME + err = os.system('"%s" "%s"' % (pkgdir.join('dotviewer.py'), + udir.join(FILENAME))) + assert err == 0 + + plain_name = FILENAME.replace('.dot','.plain') + + os.system('dot -Tplain "%s" > "%s"' % (udir.join(FILENAME), + udir.join(plain_name))) + print "=== dotviewer.py %s" % plain_name + err = os.system('"%s" "%s"' % (pkgdir.join('dotviewer.py'), + udir.join(plain_name))) + assert err == 0 + +def test_display_dot_file(): + from dotviewer.graphclient import display_dot_file + print "=== display_dot_file(%s) with GRAPHSERVER=%s" % ( + FILENAME, os.environ.get('GRAPHSERVER', ''),) + display_dot_file(udir.join(FILENAME)) + print "=== display_dot_file finished" + + +def test_graphserver(): + import socket + s = socket.socket() + s.listen(1) + host, port = s.getsockname() # pick a random free port + s.close() + + if hasattr(sys, 'pypy_objspaceclass'): + python = 'python' + else: + python = sys.executable + + cmdargs = [python, str(pkgdir.join('graphserver.py')), + str(port)] + print '* starting:', ' '.join(cmdargs) + pid = os.spawnv(os.P_NOWAIT, cmdargs[0], cmdargs) + try: + time.sleep(1) # hack - wait a bit to make sure the server is up + os.environ['GRAPHSERVER'] = '%s:%d' % (host, port) + try: + test_display_dot_file() + finally: + del os.environ['GRAPHSERVER'] + finally: + os.kill(pid, signal.SIGTERM) + +def test_colors(): + from dotviewer import graphpage, graphclient + class MyPage(graphpage.DotFileGraphPage): + def compute(self, dotfile): + super(MyPage, self).compute(dotfile) + self.links = {'v2721': 'Hello world', + 'v2720': ('Something green', (0, 192, 0)), + } + dotfile = str(udir.join(FILENAME)) + page = MyPage(dotfile) + graphclient.display_page(page) + +def test_fixedfont(): + from dotviewer import graphpage, graphclient + class MyPage(graphpage.DotFileGraphPage): + fixedfont = True + dotfile = str(udir.join(FILENAME)) + page = MyPage(dotfile) + page.fixedfont = True + graphclient.display_page(page) diff --git a/dotviewer/test/test_translator.py b/dotviewer/test/test_translator.py --- a/dotviewer/test/test_translator.py +++ b/dotviewer/test/test_translator.py @@ -22,6 +22,6 @@ def test_annotated(): from rpython.translator.interactive import Translation - t = Translation(is_prime) - t.annotate([int]) + t = Translation(is_prime, [int]) + t.annotate() t.viewcg() diff --git a/dotviewer/test/test_unicode_util.py b/dotviewer/test/test_unicode_util.py new file mode 100755 --- /dev/null +++ b/dotviewer/test/test_unicode_util.py @@ -0,0 +1,57 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +import py +import codecs +from dotviewer.drawgraph import RAW_ENCODING, forcestr, forceunicode + +SOURCE1 = u"""digraph G{ +λ -> b +b -> μ +} +""" + +FILENAME = 'test.dot' + +class TestUnicodeUtil(object): + + def test_idempotent(self): + x = u"a" + assert forceunicode(forcestr(x)) == x + + x = u"λ" + assert forceunicode(forcestr(x)) == x + + assert forceunicode(forcestr(SOURCE1)) == SOURCE1 + + x = "a" + assert forcestr(forceunicode(x)) == x + + # utf-8 encoded. + # fragile, does not consider RAW_ENCODING + # x = "\xef\xbb\xbf\xce\xbb" + # assert forcestr(forceunicode(x)) == x + + def test_does_not_double_encode(self): + x = u"λ" + x_e = forcestr(x) + assert forcestr(x_e) == x_e + + x_u = forceunicode(x_e) + assert forceunicode(x_u) == x_u + + def test_file(self): + udir = py.path.local.make_numbered_dir(prefix='usession-dot-', keep=3) + full_filename = str(udir.join(FILENAME)) + f = codecs.open(full_filename, 'wb', RAW_ENCODING) + f.write(SOURCE1) + f.close() + + with open(full_filename) as f1: + assert forceunicode(f1.read()) == SOURCE1 + + f3 = codecs.open(full_filename, 'r', RAW_ENCODING) + c = f3.read() + f3.close() + result = (c == SOURCE1) + assert result diff --git a/lib-python/2.7/collections.py b/lib-python/2.7/collections.py --- a/lib-python/2.7/collections.py +++ b/lib-python/2.7/collections.py @@ -6,11 +6,12 @@ __all__ += _abcoll.__all__ from _collections import deque, defaultdict -from operator import itemgetter as _itemgetter +from operator import itemgetter as _itemgetter, eq as _eq from keyword import iskeyword as _iskeyword import sys as _sys import heapq as _heapq from itertools import repeat as _repeat, chain as _chain, starmap as _starmap +from itertools import imap as _imap try: from thread import get_ident as _get_ident @@ -50,49 +51,45 @@ self.__map = {} self.__update(*args, **kwds) - def __setitem__(self, key, value, PREV=0, NEXT=1, dict_setitem=dict.__setitem__): + def __setitem__(self, key, value, dict_setitem=dict.__setitem__): 'od.__setitem__(i, y) <==> od[i]=y' # Setting a new item creates a new link at the end of the linked list, # and the inherited dictionary is updated with the new key/value pair. if key not in self: root = self.__root - last = root[PREV] - last[NEXT] = root[PREV] = self.__map[key] = [last, root, key] - dict_setitem(self, key, value) + last = root[0] + last[1] = root[0] = self.__map[key] = [last, root, key] + return dict_setitem(self, key, value) - def __delitem__(self, key, PREV=0, NEXT=1, dict_delitem=dict.__delitem__): + def __delitem__(self, key, dict_delitem=dict.__delitem__): 'od.__delitem__(y) <==> del od[y]' # Deleting an existing item uses self.__map to find the link which gets # removed by updating the links in the predecessor and successor nodes. dict_delitem(self, key) link_prev, link_next, key = self.__map.pop(key) - link_prev[NEXT] = link_next - link_next[PREV] = link_prev + link_prev[1] = link_next # update link_prev[NEXT] + link_next[0] = link_prev # update link_next[PREV] def __iter__(self): 'od.__iter__() <==> iter(od)' # Traverse the linked list in order. - NEXT, KEY = 1, 2 root = self.__root - curr = root[NEXT] + curr = root[1] # start at the first node while curr is not root: - yield curr[KEY] - curr = curr[NEXT] + yield curr[2] # yield the curr[KEY] + curr = curr[1] # move to next node def __reversed__(self): 'od.__reversed__() <==> reversed(od)' # Traverse the linked list in reverse order. - PREV, KEY = 0, 2 root = self.__root - curr = root[PREV] + curr = root[0] # start at the last node while curr is not root: - yield curr[KEY] - curr = curr[PREV] + yield curr[2] # yield the curr[KEY] + curr = curr[0] # move to previous node def clear(self): 'od.clear() -> None. Remove all items from od.' - for node in self.__map.itervalues(): - del node[:] root = self.__root root[:] = [root, root, None] self.__map.clear() @@ -208,7 +205,7 @@ ''' if isinstance(other, OrderedDict): - return len(self)==len(other) and self.items() == other.items() + return dict.__eq__(self, other) and all(_imap(_eq, self, other)) return dict.__eq__(self, other) def __ne__(self, other): @@ -323,13 +320,13 @@ 'Return self as a plain tuple. Used by copy and pickle.' return tuple(self) \n\n''' % locals() for i, name in enumerate(field_names): - template += " %s = _property(_itemgetter(%d), doc='Alias for field number %d')\n" % (name, i, i) + template += " %s = _property(lambda self: self[%d], doc='Alias for field number %d')\n" % (name, i, i) if verbose: print template # Execute the template string in a temporary namespace and # support tracing utilities by setting a value for frame.f_globals['__name__'] - namespace = dict(_itemgetter=_itemgetter, __name__='namedtuple_%s' % typename, + namespace = dict(__name__='namedtuple_%s' % typename, OrderedDict=OrderedDict, _property=property, _tuple=tuple) try: exec template in namespace diff --git a/lib-python/2.7/json/encoder.py b/lib-python/2.7/json/encoder.py --- a/lib-python/2.7/json/encoder.py +++ b/lib-python/2.7/json/encoder.py @@ -138,16 +138,16 @@ self.skipkeys = skipkeys self.ensure_ascii = ensure_ascii if ensure_ascii: - self.encoder = raw_encode_basestring_ascii + self.__encoder = raw_encode_basestring_ascii else: - self.encoder = raw_encode_basestring + self.__encoder = raw_encode_basestring if encoding != 'utf-8': - orig_encoder = self.encoder + orig_encoder = self.__encoder def encoder(o): if isinstance(o, str): o = o.decode(encoding) return orig_encoder(o) - self.encoder = encoder + self.__encoder = encoder self.check_circular = check_circular self.allow_nan = allow_nan self.sort_keys = sort_keys @@ -193,10 +193,10 @@ builder = StringBuilder() else: builder = UnicodeBuilder() - self._encode(o, markers, builder, 0) + self.__encode(o, markers, builder, 0) return builder.build() - def _emit_indent(self, builder, _current_indent_level): + def __emit_indent(self, builder, _current_indent_level): if self.indent is not None: _current_indent_level += 1 newline_indent = '\n' + (' ' * (self.indent * @@ -207,15 +207,15 @@ separator = self.item_separator return separator, _current_indent_level - def _emit_unindent(self, builder, _current_indent_level): + def __emit_unindent(self, builder, _current_indent_level): if self.indent is not None: builder.append('\n') builder.append(' ' * (self.indent * (_current_indent_level - 1))) - def _encode(self, o, markers, builder, _current_indent_level): + def __encode(self, o, markers, builder, _current_indent_level): if isinstance(o, basestring): builder.append('"') - builder.append(self.encoder(o)) + builder.append(self.__encoder(o)) builder.append('"') elif o is None: builder.append('null') @@ -226,46 +226,46 @@ elif isinstance(o, (int, long)): builder.append(str(o)) elif isinstance(o, float): - builder.append(self._floatstr(o)) + builder.append(self.__floatstr(o)) elif isinstance(o, (list, tuple)): if not o: builder.append('[]') return - self._encode_list(o, markers, builder, _current_indent_level) + self.__encode_list(o, markers, builder, _current_indent_level) elif isinstance(o, dict): if not o: builder.append('{}') return - self._encode_dict(o, markers, builder, _current_indent_level) + self.__encode_dict(o, markers, builder, _current_indent_level) else: - self._mark_markers(markers, o) + self.__mark_markers(markers, o) res = self.default(o) - self._encode(res, markers, builder, _current_indent_level) - self._remove_markers(markers, o) + self.__encode(res, markers, builder, _current_indent_level) + self.__remove_markers(markers, o) return res - def _encode_list(self, l, markers, builder, _current_indent_level): - self._mark_markers(markers, l) + def __encode_list(self, l, markers, builder, _current_indent_level): + self.__mark_markers(markers, l) builder.append('[') first = True - separator, _current_indent_level = self._emit_indent(builder, + separator, _current_indent_level = self.__emit_indent(builder, _current_indent_level) for elem in l: if first: first = False else: builder.append(separator) - self._encode(elem, markers, builder, _current_indent_level) + self.__encode(elem, markers, builder, _current_indent_level) del elem # XXX grumble - self._emit_unindent(builder, _current_indent_level) + self.__emit_unindent(builder, _current_indent_level) builder.append(']') - self._remove_markers(markers, l) + self.__remove_markers(markers, l) - def _encode_dict(self, d, markers, builder, _current_indent_level): - self._mark_markers(markers, d) + def __encode_dict(self, d, markers, builder, _current_indent_level): + self.__mark_markers(markers, d) first = True builder.append('{') - separator, _current_indent_level = self._emit_indent(builder, + separator, _current_indent_level = self.__emit_indent(builder, _current_indent_level) if self.sort_keys: items = sorted(d.items(), key=lambda kv: kv[0]) @@ -282,7 +282,7 @@ # JavaScript is weakly typed for these, so it makes sense to # also allow them. Many encoders seem to do something like this. elif isinstance(key, float): - key = self._floatstr(key) + key = self.__floatstr(key) elif key is True: key = 'true' elif key is False: @@ -296,15 +296,15 @@ else: raise TypeError("key " + repr(key) + " is not a string") builder.append('"') - builder.append(self.encoder(key)) + builder.append(self.__encoder(key)) builder.append('"') builder.append(self.key_separator) - self._encode(v, markers, builder, _current_indent_level) + self.__encode(v, markers, builder, _current_indent_level) del key del v # XXX grumble - self._emit_unindent(builder, _current_indent_level) + self.__emit_unindent(builder, _current_indent_level) builder.append('}') - self._remove_markers(markers, d) + self.__remove_markers(markers, d) def iterencode(self, o, _one_shot=False): """Encode the given object and yield each string @@ -320,9 +320,9 @@ markers = {} else: markers = None - return self._iterencode(o, markers, 0) + return self.__iterencode(o, markers, 0) - def _floatstr(self, o): + def __floatstr(self, o): # Check for specials. Note that this type of test is processor # and/or platform-specific, so do tests which don't depend on the # internals. @@ -343,21 +343,21 @@ return text - def _mark_markers(self, markers, o): + def __mark_markers(self, markers, o): if markers is not None: if id(o) in markers: raise ValueError("Circular reference detected") markers[id(o)] = None - def _remove_markers(self, markers, o): + def __remove_markers(self, markers, o): if markers is not None: del markers[id(o)] - def _iterencode_list(self, lst, markers, _current_indent_level): + def __iterencode_list(self, lst, markers, _current_indent_level): if not lst: yield '[]' return - self._mark_markers(markers, lst) + self.__mark_markers(markers, lst) buf = '[' if self.indent is not None: _current_indent_level += 1 @@ -375,7 +375,7 @@ else: buf = separator if isinstance(value, basestring): - yield buf + '"' + self.encoder(value) + '"' + yield buf + '"' + self.__encoder(value) + '"' elif value is None: yield buf + 'null' elif value is True: @@ -385,17 +385,17 @@ elif isinstance(value, (int, long)): yield buf + str(value) elif isinstance(value, float): - yield buf + self._floatstr(value) + yield buf + self.__floatstr(value) else: yield buf if isinstance(value, (list, tuple)): - chunks = self._iterencode_list(value, markers, + chunks = self.__iterencode_list(value, markers, _current_indent_level) elif isinstance(value, dict): - chunks = self._iterencode_dict(value, markers, + chunks = self.__iterencode_dict(value, markers, _current_indent_level) else: - chunks = self._iterencode(value, markers, + chunks = self.__iterencode(value, markers, _current_indent_level) for chunk in chunks: yield chunk @@ -403,13 +403,13 @@ _current_indent_level -= 1 yield '\n' + (' ' * (self.indent * _current_indent_level)) yield ']' - self._remove_markers(markers, lst) + self.__remove_markers(markers, lst) - def _iterencode_dict(self, dct, markers, _current_indent_level): + def __iterencode_dict(self, dct, markers, _current_indent_level): if not dct: yield '{}' return - self._mark_markers(markers, dct) + self.__mark_markers(markers, dct) yield '{' if self.indent is not None: _current_indent_level += 1 @@ -431,7 +431,7 @@ # JavaScript is weakly typed for these, so it makes sense to # also allow them. Many encoders seem to do something like this. elif isinstance(key, float): - key = self._floatstr(key) + key = self.__floatstr(key) elif key is True: key = 'true' elif key is False: @@ -448,10 +448,10 @@ first = False else: yield item_separator - yield '"' + self.encoder(key) + '"' + yield '"' + self.__encoder(key) + '"' yield self.key_separator if isinstance(value, basestring): - yield '"' + self.encoder(value) + '"' + yield '"' + self.__encoder(value) + '"' elif value is None: yield 'null' elif value is True: @@ -461,16 +461,16 @@ elif isinstance(value, (int, long)): yield str(value) elif isinstance(value, float): - yield self._floatstr(value) + yield self.__floatstr(value) else: if isinstance(value, (list, tuple)): - chunks = self._iterencode_list(value, markers, + chunks = self.__iterencode_list(value, markers, _current_indent_level) elif isinstance(value, dict): - chunks = self._iterencode_dict(value, markers, + chunks = self.__iterencode_dict(value, markers, _current_indent_level) else: - chunks = self._iterencode(value, markers, + chunks = self.__iterencode(value, markers, _current_indent_level) for chunk in chunks: yield chunk @@ -478,11 +478,11 @@ _current_indent_level -= 1 yield '\n' + (' ' * (self.indent * _current_indent_level)) yield '}' - self._remove_markers(markers, dct) + self.__remove_markers(markers, dct) - def _iterencode(self, o, markers, _current_indent_level): + def __iterencode(self, o, markers, _current_indent_level): if isinstance(o, basestring): - yield '"' + self.encoder(o) + '"' + yield '"' + self.__encoder(o) + '"' elif o is None: yield 'null' elif o is True: @@ -492,19 +492,19 @@ elif isinstance(o, (int, long)): yield str(o) elif isinstance(o, float): - yield self._floatstr(o) + yield self.__floatstr(o) elif isinstance(o, (list, tuple)): - for chunk in self._iterencode_list(o, markers, + for chunk in self.__iterencode_list(o, markers, _current_indent_level): yield chunk elif isinstance(o, dict): - for chunk in self._iterencode_dict(o, markers, + for chunk in self.__iterencode_dict(o, markers, _current_indent_level): yield chunk else: - self._mark_markers(markers, o) + self.__mark_markers(markers, o) obj = self.default(o) - for chunk in self._iterencode(obj, markers, + for chunk in self.__iterencode(obj, markers, _current_indent_level): yield chunk - self._remove_markers(markers, o) + self.__remove_markers(markers, o) diff --git a/lib-python/2.7/test/test_modulefinder.py b/lib-python/2.7/test/test_modulefinder.py --- a/lib-python/2.7/test/test_modulefinder.py +++ b/lib-python/2.7/test/test_modulefinder.py @@ -16,7 +16,7 @@ # library. TEST_DIR = tempfile.mkdtemp() -TEST_PATH = [TEST_DIR, os.path.dirname(__future__.__file__)] +TEST_PATH = [TEST_DIR, os.path.dirname(tempfile.__file__)] # Each test description is a list of 5 items: # diff --git a/lib-python/2.7/test/test_zipfile.py b/lib-python/2.7/test/test_zipfile.py --- a/lib-python/2.7/test/test_zipfile.py +++ b/lib-python/2.7/test/test_zipfile.py @@ -1213,6 +1213,17 @@ self.assertEqual(data1, '1'*FIXEDTEST_SIZE) self.assertEqual(data2, '2'*FIXEDTEST_SIZE) + def test_many_opens(self): + # Verify that read() and open() promptly close the file descriptor, + # and don't rely on the garbage collector to free resources. + with zipfile.ZipFile(TESTFN2, mode="r") as zipf: + for x in range(100): + zipf.read('ones') + with zipf.open('ones') as zopen1: + pass + for x in range(10): + self.assertLess(open('/dev/null').fileno(), 100) + def tearDown(self): unlink(TESTFN2) diff --git a/lib-python/2.7/urllib.py b/lib-python/2.7/urllib.py --- a/lib-python/2.7/urllib.py +++ b/lib-python/2.7/urllib.py @@ -1205,15 +1205,17 @@ # fastpath if len(res) == 1: return s - s = res[0] - for item in res[1:]: + res_list = [res[0]] + for j in xrange(1, len(res)): + item = res[j] try: - s += _hextochr[item[:2]] + item[2:] + x = _hextochr[item[:2]] + item[2:] except KeyError: - s += '%' + item + x = '%' + item except UnicodeDecodeError: - s += unichr(int(item[:2], 16)) + item[2:] - return s + x = unichr(int(item[:2], 16)) + item[2:] + res_list.append(x) + return ''.join(res_list) def unquote_plus(s): """unquote('%7e/abc+def') -> '~/abc def'""" diff --git a/lib-python/2.7/urlparse.py b/lib-python/2.7/urlparse.py --- a/lib-python/2.7/urlparse.py +++ b/lib-python/2.7/urlparse.py @@ -321,15 +321,17 @@ # fastpath if len(res) == 1: return s - s = res[0] - for item in res[1:]: + res_list = [res[0]] + for j in xrange(1, len(res)): + item = res[j] try: - s += _hextochr[item[:2]] + item[2:] + x = _hextochr[item[:2]] + item[2:] except KeyError: - s += '%' + item + x = '%' + item except UnicodeDecodeError: - s += unichr(int(item[:2], 16)) + item[2:] - return s + x = unichr(int(item[:2], 16)) + item[2:] + res_list.append(x) + return ''.join(res_list) def parse_qs(qs, keep_blank_values=0, strict_parsing=0): """Parse a query given as a string argument. diff --git a/lib-python/2.7/zipfile.py b/lib-python/2.7/zipfile.py --- a/lib-python/2.7/zipfile.py +++ b/lib-python/2.7/zipfile.py @@ -475,9 +475,11 @@ # Search for universal newlines or line chunks. PATTERN = re.compile(r'^(?P[^\r\n]+)|(?P\n|\r\n?)') - def __init__(self, fileobj, mode, zipinfo, decrypter=None): + def __init__(self, fileobj, mode, zipinfo, decrypter=None, + close_fileobj=False): self._fileobj = fileobj self._decrypter = decrypter + self._close_fileobj = close_fileobj self._compress_type = zipinfo.compress_type self._compress_size = zipinfo.compress_size @@ -649,6 +651,12 @@ self._offset += len(data) return data + def close(self): + try: + if self._close_fileobj: + self._fileobj.close() + finally: + super(ZipExtFile, self).close() class ZipFile: @@ -866,7 +874,8 @@ def read(self, name, pwd=None): """Return file bytes (as a string) for name.""" - return self.open(name, "r", pwd).read() + with self.open(name, "r", pwd) as fp: + return fp.read() def open(self, name, mode="r", pwd=None): """Return file-like object for 'name'.""" @@ -889,8 +898,12 @@ zinfo = name else: # Get info object for name - zinfo = self.getinfo(name) - + try: + zinfo = self.getinfo(name) + except KeyError: + if not self._filePassed: + zef_file.close() + raise zef_file.seek(zinfo.header_offset, 0) # Skip the file header: @@ -904,6 +917,8 @@ zef_file.read(fheader[_FH_EXTRA_FIELD_LENGTH]) if fname != zinfo.orig_filename: + if not self._filePassed: + zef_file.close() raise BadZipfile, \ 'File name in directory "%s" and header "%s" differ.' % ( zinfo.orig_filename, fname) @@ -915,6 +930,8 @@ if not pwd: pwd = self.pwd if not pwd: + if not self._filePassed: + zef_file.close() raise RuntimeError, "File %s is encrypted, " \ "password required for extraction" % name @@ -933,9 +950,12 @@ # compare against the CRC otherwise check_byte = (zinfo.CRC >> 24) & 0xff if ord(h[11]) != check_byte: + if not self._filePassed: + zef_file.close() raise RuntimeError("Bad password for file", name) - return ZipExtFile(zef_file, mode, zinfo, zd) + return ZipExtFile(zef_file, mode, zinfo, zd, + close_fileobj=not self._filePassed) def extract(self, member, path=None, pwd=None): """Extract a member from the archive to the current working directory, @@ -993,7 +1013,7 @@ return targetpath source = self.open(member, pwd=pwd) - target = file(targetpath, "wb") + target = open(targetpath, "wb") shutil.copyfileobj(source, target) source.close() target.close() diff --git a/lib-python/conftest.py b/lib-python/conftest.py --- a/lib-python/conftest.py +++ b/lib-python/conftest.py @@ -160,7 +160,7 @@ RegrTest('test_codeop.py', core=True), RegrTest('test_coding.py', core=True), RegrTest('test_coercion.py', core=True), - RegrTest('test_collections.py'), + RegrTest('test_collections.py', usemodules='binascii struct'), RegrTest('test_colorsys.py'), RegrTest('test_commands.py'), RegrTest('test_compare.py', core=True), @@ -181,7 +181,7 @@ RegrTest('test_csv.py', usemodules='_csv'), RegrTest('test_ctypes.py', usemodules="_rawffi thread"), RegrTest('test_curses.py'), - RegrTest('test_datetime.py'), + RegrTest('test_datetime.py', usemodules='binascii struct'), RegrTest('test_dbm.py'), RegrTest('test_decimal.py'), RegrTest('test_decorators.py', core=True), @@ -272,7 +272,7 @@ RegrTest('test_inspect.py'), RegrTest('test_int.py', core=True), RegrTest('test_int_literal.py', core=True), - RegrTest('test_io.py'), + RegrTest('test_io.py', usemodules='array binascii'), RegrTest('test_ioctl.py'), RegrTest('test_isinstance.py', core=True), RegrTest('test_iter.py', core=True), diff --git a/lib_pypy/_collections.py b/lib_pypy/_collections.py --- a/lib_pypy/_collections.py +++ b/lib_pypy/_collections.py @@ -142,18 +142,24 @@ return c def remove(self, value): - # Need to be defensive for mutating comparisons - for i in range(len(self)): - if self[i] == value: - del self[i] - return - raise ValueError("deque.remove(x): x not in deque") + # Need to defend mutating or failing comparisons + i = 0 + try: + for i in range(len(self)): + if self[0] == value: + self.popleft() + return + self.append(self.popleft()) + i += 1 + raise ValueError("deque.remove(x): x not in deque") + finally: + self.rotate(i) def rotate(self, n=1): length = len(self) - if length == 0: + if length <= 1: return - halflen = (length+1) >> 1 + halflen = length >> 1 if n > halflen or n < -halflen: n %= length if n > halflen: diff --git a/lib_pypy/_ctypes_test.py b/lib_pypy/_ctypes_test.py --- a/lib_pypy/_ctypes_test.py +++ b/lib_pypy/_ctypes_test.py @@ -1,6 +1,5 @@ import os, sys import tempfile -import gc def compile_shared(): """Compile '_ctypes_test.c' into an extension module, and import it @@ -19,7 +18,7 @@ if sys.platform == 'win32': ccflags = ['-D_CRT_SECURE_NO_WARNINGS'] else: - ccflags = ['-fPIC'] + ccflags = ['-fPIC', '-Wimplicit-function-declaration'] res = compiler.compile([os.path.join(thisdir, '_ctypes_test.c')], include_dirs=[include_dir], extra_preargs=ccflags) @@ -35,10 +34,10 @@ library = os.path.join(thisdir, '..', 'include', 'python27') if not os.path.exists(library + '.lib'): # For a local translation - library = os.path.join(thisdir, '..', 'pypy', 'translator', - 'goal', 'libpypy-c') + library = os.path.join(thisdir, '..', 'pypy', 'goal', 'libpypy-c') libraries = [library, 'oleaut32'] - extra_ldargs = ['/MANIFEST'] # needed for VC10 + extra_ldargs = ['/MANIFEST', # needed for VC10 + '/EXPORT:init_ctypes_test'] else: libraries = [] extra_ldargs = [] diff --git a/lib_pypy/_testcapi.py b/lib_pypy/_testcapi.py --- a/lib_pypy/_testcapi.py +++ b/lib_pypy/_testcapi.py @@ -34,8 +34,7 @@ library = os.path.join(thisdir, '..', 'include', 'python27') if not os.path.exists(library + '.lib'): # For a local translation - library = os.path.join(thisdir, '..', 'pypy', 'translator', - 'goal', 'libpypy-c') + library = os.path.join(thisdir, '..', 'pypy', 'goal', 'libpypy-c') libraries = [library, 'oleaut32'] extra_ldargs = ['/MANIFEST', # needed for VC10 '/EXPORT:init_testcapi'] diff --git a/lib_pypy/cPickle.py b/lib_pypy/cPickle.py --- a/lib_pypy/cPickle.py +++ b/lib_pypy/cPickle.py @@ -1,5 +1,5 @@ # -# One-liner implementation of cPickle +# Reimplementation of cPickle, mostly as a copy of pickle.py # from pickle import Pickler, dump, dumps, PickleError, PicklingError, UnpicklingError, _EmptyClass @@ -131,6 +131,13 @@ # Unpickling machinery +class _Stack(list): + def pop(self, index=-1): + try: + return list.pop(self, index) + except IndexError: + raise UnpicklingError("unpickling stack underflow") + class Unpickler(object): def __init__(self, file): @@ -155,7 +162,7 @@ Return the reconstituted object hierarchy specified in the file. """ self.mark = object() # any new unique object - self.stack = [] + self.stack = _Stack() self.append = self.stack.append try: key = ord(self.read(1)) diff --git a/lib_pypy/conftest.py b/lib_pypy/conftest.py deleted file mode 100644 --- a/lib_pypy/conftest.py +++ /dev/null @@ -1,2 +0,0 @@ - -from pypy.conftest import * diff --git a/lib_pypy/ctypes_support.py b/lib_pypy/ctypes_support.py --- a/lib_pypy/ctypes_support.py +++ b/lib_pypy/ctypes_support.py @@ -19,16 +19,19 @@ if sys.platform == 'win32': standard_c_lib._errno.restype = ctypes.POINTER(ctypes.c_int) + standard_c_lib._errno.argtypes = None def _where_is_errno(): return standard_c_lib._errno() elif sys.platform in ('linux2', 'freebsd6'): standard_c_lib.__errno_location.restype = ctypes.POINTER(ctypes.c_int) + standard_c_lib.__errno_location.argtypes = None def _where_is_errno(): return standard_c_lib.__errno_location() elif sys.platform in ('darwin', 'freebsd7', 'freebsd8', 'freebsd9'): standard_c_lib.__error.restype = ctypes.POINTER(ctypes.c_int) + standard_c_lib.__error.argtypes = None def _where_is_errno(): return standard_c_lib.__error() diff --git a/lib_pypy/datetime.py b/lib_pypy/datetime.py --- a/lib_pypy/datetime.py +++ b/lib_pypy/datetime.py @@ -270,10 +270,21 @@ return offset raise ValueError("%s()=%d, must be in -1439..1439" % (name, offset)) +def _check_int_field(value): + if not isinstance(value, float): + try: + value = value.__int__() + except AttributeError: + pass + else: + if isinstance(value, (int, long)): + return value + raise TypeError('integer argument expected') + def _check_date_fields(year, month, day): - for value in [year, day]: - if not isinstance(value, (int, long)): - raise TypeError('int expected') + year = _check_int_field(year) + month = _check_int_field(month) + day = _check_int_field(day) if not MINYEAR <= year <= MAXYEAR: raise ValueError('year must be in %d..%d' % (MINYEAR, MAXYEAR), year) if not 1 <= month <= 12: @@ -281,11 +292,13 @@ dim = _days_in_month(year, month) if not 1 <= day <= dim: raise ValueError('day must be in 1..%d' % dim, day) + return year, month, day def _check_time_fields(hour, minute, second, microsecond): - for value in [hour, minute, second, microsecond]: - if not isinstance(value, (int, long)): - raise TypeError('int expected') + hour = _check_int_field(hour) + minute = _check_int_field(minute) + second = _check_int_field(second) + microsecond = _check_int_field(microsecond) if not 0 <= hour <= 23: raise ValueError('hour must be in 0..23', hour) if not 0 <= minute <= 59: @@ -294,6 +307,7 @@ raise ValueError('second must be in 0..59', second) if not 0 <= microsecond <= 999999: raise ValueError('microsecond must be in 0..999999', microsecond) + return hour, minute, second, microsecond def _check_tzinfo_arg(tz): if tz is not None and not isinstance(tz, tzinfo): @@ -768,7 +782,7 @@ self = object.__new__(cls) self.__setstate(year) return self - _check_date_fields(year, month, day) + year, month, day = _check_date_fields(year, month, day) self = object.__new__(cls) self._year = year self._month = month @@ -889,7 +903,7 @@ month = self._month if day is None: day = self._day - _check_date_fields(year, month, day) + year, month, day = _check_date_fields(year, month, day) return date(year, month, day) # Comparisons of date objects with other. @@ -1150,13 +1164,14 @@ second, microsecond (default to zero) tzinfo (default to None) """ - self = object.__new__(cls) if isinstance(hour, str): # Pickle support + self = object.__new__(cls) self.__setstate(hour, minute or None) return self + hour, minute, second, microsecond = _check_time_fields(hour, minute, second, microsecond) _check_tzinfo_arg(tzinfo) - _check_time_fields(hour, minute, second, microsecond) + self = object.__new__(cls) self._hour = hour self._minute = minute self._second = second @@ -1387,7 +1402,7 @@ microsecond = self.microsecond if tzinfo is True: tzinfo = self.tzinfo - _check_time_fields(hour, minute, second, microsecond) + hour, minute, second, microsecond = _check_time_fields(hour, minute, second, microsecond) _check_tzinfo_arg(tzinfo) return time(hour, minute, second, microsecond, tzinfo) @@ -1449,10 +1464,10 @@ self = date.__new__(cls, year[:4]) self.__setstate(year, month) return self + year, month, day = _check_date_fields(year, month, day) + hour, minute, second, microsecond = _check_time_fields(hour, minute, second, microsecond) _check_tzinfo_arg(tzinfo) - _check_time_fields(hour, minute, second, microsecond) - self = date.__new__(cls, year, month, day) - # XXX This duplicates __year, __month, __day for convenience :-( + self = object.__new__(cls) self._year = year self._month = month self._day = day @@ -1617,8 +1632,8 @@ microsecond = self.microsecond if tzinfo is True: tzinfo = self.tzinfo - _check_date_fields(year, month, day) - _check_time_fields(hour, minute, second, microsecond) + year, month, day = _check_date_fields(year, month, day) + hour, minute, second, microsecond = _check_time_fields(hour, minute, second, microsecond) _check_tzinfo_arg(tzinfo) return datetime(year, month, day, hour, minute, second, microsecond, tzinfo) diff --git a/lib_pypy/dbm.py b/lib_pypy/dbm.py --- a/lib_pypy/dbm.py +++ b/lib_pypy/dbm.py @@ -1,4 +1,4 @@ -from ctypes import Structure, c_char_p, c_int, c_void_p, CDLL +from ctypes import Structure, c_char_p, c_int, c_void_p, CDLL, POINTER, c_char import ctypes.util import os, sys @@ -11,7 +11,7 @@ class datum(Structure): _fields_ = [ - ('dptr', c_char_p), + ('dptr', POINTER(c_char)), ('dsize', c_int), ] @@ -126,8 +126,8 @@ libpath = ctypes.util.find_library('db') if not libpath: # XXX this is hopeless... - for c in '56789': - libpath = ctypes.util.find_library('db-4.%s' % c) + for c in ['5.3', '5.2', '5.1', '5.0', '4.9', '4.8', '4.7', '4.6', '4.5']: + libpath = ctypes.util.find_library('db-%s' % c) if libpath: break else: diff --git a/lib_pypy/greenlet.py b/lib_pypy/greenlet.py --- a/lib_pypy/greenlet.py +++ b/lib_pypy/greenlet.py @@ -1,5 +1,6 @@ import _continuation, sys +__version__ = "0.4.0" # ____________________________________________________________ # Exceptions @@ -57,7 +58,8 @@ def __switch(target, methodname, *args): current = getcurrent() # - while not target: + while not (target.__main or _continulet.is_pending(target)): + # inlined __nonzero__ ^^^ in case it's overridden if not target.__started: if methodname == 'switch': greenlet_func = _greenlet_start diff --git a/lib_pypy/numpypy/core/__init__.py b/lib_pypy/numpypy/core/__init__.py --- a/lib_pypy/numpypy/core/__init__.py +++ b/lib_pypy/numpypy/core/__init__.py @@ -1,2 +1,3 @@ from .fromnumeric import * from .numeric import * +from .shape_base import * diff --git a/lib_pypy/numpypy/core/numeric.py b/lib_pypy/numpypy/core/numeric.py --- a/lib_pypy/numpypy/core/numeric.py +++ b/lib_pypy/numpypy/core/numeric.py @@ -428,3 +428,76 @@ True_ = bool_(True) e = math.e pi = math.pi + +def outer(a,b): + """ + Compute the outer product of two vectors. + + Given two vectors, ``a = [a0, a1, ..., aM]`` and + ``b = [b0, b1, ..., bN]``, + the outer product [1]_ is:: + + [[a0*b0 a0*b1 ... a0*bN ] + [a1*b0 . + [ ... . + [aM*b0 aM*bN ]] + + Parameters + ---------- + a, b : array_like, shape (M,), (N,) + First and second input vectors. Inputs are flattened if they + are not already 1-dimensional. + + Returns + ------- + out : ndarray, shape (M, N) + ``out[i, j] = a[i] * b[j]`` + + See also + -------- + inner, einsum + + References + ---------- + .. [1] : G. H. Golub and C. F. van Loan, *Matrix Computations*, 3rd + ed., Baltimore, MD, Johns Hopkins University Press, 1996, + pg. 8. + + Examples + -------- + Make a (*very* coarse) grid for computing a Mandelbrot set: + + >>> rl = np.outer(np.ones((5,)), np.linspace(-2, 2, 5)) + >>> rl + array([[-2., -1., 0., 1., 2.], + [-2., -1., 0., 1., 2.], + [-2., -1., 0., 1., 2.], + [-2., -1., 0., 1., 2.], + [-2., -1., 0., 1., 2.]]) + >>> im = np.outer(1j*np.linspace(2, -2, 5), np.ones((5,))) + >>> im + array([[ 0.+2.j, 0.+2.j, 0.+2.j, 0.+2.j, 0.+2.j], + [ 0.+1.j, 0.+1.j, 0.+1.j, 0.+1.j, 0.+1.j], + [ 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j], + [ 0.-1.j, 0.-1.j, 0.-1.j, 0.-1.j, 0.-1.j], + [ 0.-2.j, 0.-2.j, 0.-2.j, 0.-2.j, 0.-2.j]]) + >>> grid = rl + im + >>> grid + array([[-2.+2.j, -1.+2.j, 0.+2.j, 1.+2.j, 2.+2.j], + [-2.+1.j, -1.+1.j, 0.+1.j, 1.+1.j, 2.+1.j], + [-2.+0.j, -1.+0.j, 0.+0.j, 1.+0.j, 2.+0.j], + [-2.-1.j, -1.-1.j, 0.-1.j, 1.-1.j, 2.-1.j], + [-2.-2.j, -1.-2.j, 0.-2.j, 1.-2.j, 2.-2.j]]) + + An example using a "vector" of letters: + + >>> x = np.array(['a', 'b', 'c'], dtype=object) + >>> np.outer(x, [1, 2, 3]) + array([[a, aa, aaa], + [b, bb, bbb], + [c, cc, ccc]], dtype=object) + + """ + a = asarray(a) + b = asarray(b) + return a.ravel()[:,newaxis]*b.ravel()[newaxis,:] diff --git a/lib_pypy/numpypy/core/shape_base.py b/lib_pypy/numpypy/core/shape_base.py new file mode 100644 --- /dev/null +++ b/lib_pypy/numpypy/core/shape_base.py @@ -0,0 +1,323 @@ +import _numpypy +from numeric import array, asanyarray, newaxis + +def atleast_1d(*arys): + """ + Convert inputs to arrays with at least one dimension. + + Scalar inputs are converted to 1-dimensional arrays, whilst + higher-dimensional inputs are preserved. + + Parameters + ---------- + arys1, arys2, ... : array_like + One or more input arrays. + + Returns + ------- + ret : ndarray + An array, or sequence of arrays, each with ``a.ndim >= 1``. + Copies are made only if necessary. + + See Also + -------- + atleast_2d, atleast_3d + + Examples + -------- + >>> np.atleast_1d(1.0) + array([ 1.]) + + >>> x = np.arange(9.0).reshape(3,3) + >>> np.atleast_1d(x) + array([[ 0., 1., 2.], + [ 3., 4., 5.], + [ 6., 7., 8.]]) + >>> np.atleast_1d(x) is x + True + + >>> np.atleast_1d(1, [3, 4]) + [array([1]), array([3, 4])] + + """ + res = [] + for ary in arys: + ary = asanyarray(ary) + if len(ary.shape) == 0 : + result = ary.reshape(1) + else : + result = ary + res.append(result) + if len(res) == 1: + return res[0] + else: + return res + + +def atleast_2d(*arys): + """ + View inputs as arrays with at least two dimensions. + + Parameters + ---------- + arys1, arys2, ... : array_like + One or more array-like sequences. Non-array inputs are converted + to arrays. Arrays that already have two or more dimensions are + preserved. + + Returns + ------- + res, res2, ... : ndarray + An array, or tuple of arrays, each with ``a.ndim >= 2``. + Copies are avoided where possible, and views with two or more + dimensions are returned. + + See Also + -------- + atleast_1d, atleast_3d + + Examples + -------- + >>> np.atleast_2d(3.0) + array([[ 3.]]) + + >>> x = np.arange(3.0) + >>> np.atleast_2d(x) + array([[ 0., 1., 2.]]) + >>> np.atleast_2d(x).base is x + True + + >>> np.atleast_2d(1, [1, 2], [[1, 2]]) + [array([[1]]), array([[1, 2]]), array([[1, 2]])] + + """ + res = [] + for ary in arys: + ary = asanyarray(ary) + if len(ary.shape) == 0 : + result = ary.reshape(1, 1) + elif len(ary.shape) == 1 : + result = ary[newaxis, :] + else : + result = ary + res.append(result) + if len(res) == 1: + return res[0] + else: + return res + +def atleast_3d(*arys): + """ + View inputs as arrays with at least three dimensions. + + Parameters + ---------- + arys1, arys2, ... : array_like + One or more array-like sequences. Non-array inputs are converted to + arrays. Arrays that already have three or more dimensions are + preserved. + + Returns + ------- + res1, res2, ... : ndarray + An array, or tuple of arrays, each with ``a.ndim >= 3``. Copies are + avoided where possible, and views with three or more dimensions are + returned. For example, a 1-D array of shape ``(N,)`` becomes a view + of shape ``(1, N, 1)``, and a 2-D array of shape ``(M, N)`` becomes a + view of shape ``(M, N, 1)``. + + See Also + -------- + atleast_1d, atleast_2d + + Examples + -------- + >>> np.atleast_3d(3.0) + array([[[ 3.]]]) + + >>> x = np.arange(3.0) + >>> np.atleast_3d(x).shape + (1, 3, 1) + + >>> x = np.arange(12.0).reshape(4,3) + >>> np.atleast_3d(x).shape + (4, 3, 1) + >>> np.atleast_3d(x).base is x + True + + >>> for arr in np.atleast_3d([1, 2], [[1, 2]], [[[1, 2]]]): + ... print arr, arr.shape + ... + [[[1] + [2]]] (1, 2, 1) + [[[1] + [2]]] (1, 2, 1) + [[[1 2]]] (1, 1, 2) + + """ + res = [] + for ary in arys: + ary = asanyarray(ary) + if len(ary.shape) == 0: + result = ary.reshape(1,1,1) + elif len(ary.shape) == 1: + result = ary[newaxis,:,newaxis] + elif len(ary.shape) == 2: + result = ary[:,:,newaxis] + else: + result = ary + res.append(result) + if len(res) == 1: + return res[0] + else: + return res + +def vstack(tup): + """ + Stack arrays in sequence vertically (row wise). + + Take a sequence of arrays and stack them vertically to make a single + array. Rebuild arrays divided by `vsplit`. + + Parameters + ---------- + tup : sequence of ndarrays + Tuple containing arrays to be stacked. The arrays must have the same + shape along all but the first axis. + + Returns + ------- + stacked : ndarray + The array formed by stacking the given arrays. + + See Also + -------- + hstack : Stack arrays in sequence horizontally (column wise). + dstack : Stack arrays in sequence depth wise (along third dimension). + concatenate : Join a sequence of arrays together. + vsplit : Split array into a list of multiple sub-arrays vertically. + + Notes + ----- + Equivalent to ``np.concatenate(tup, axis=0)`` if `tup` contains arrays that + are at least 2-dimensional. + + Examples + -------- + >>> a = np.array([1, 2, 3]) + >>> b = np.array([2, 3, 4]) + >>> np.vstack((a,b)) + array([[1, 2, 3], + [2, 3, 4]]) + + >>> a = np.array([[1], [2], [3]]) + >>> b = np.array([[2], [3], [4]]) + >>> np.vstack((a,b)) + array([[1], + [2], + [3], + [2], + [3], + [4]]) + + """ + return _numpypy.concatenate(map(atleast_2d,tup),0) + +def hstack(tup): + """ + Stack arrays in sequence horizontally (column wise). + + Take a sequence of arrays and stack them horizontally to make + a single array. Rebuild arrays divided by `hsplit`. + + Parameters + ---------- + tup : sequence of ndarrays + All arrays must have the same shape along all but the second axis. + + Returns + ------- + stacked : ndarray + The array formed by stacking the given arrays. + + See Also + -------- + vstack : Stack arrays in sequence vertically (row wise). + dstack : Stack arrays in sequence depth wise (along third axis). + concatenate : Join a sequence of arrays together. + hsplit : Split array along second axis. + + Notes + ----- + Equivalent to ``np.concatenate(tup, axis=1)`` + + Examples + -------- + >>> a = np.array((1,2,3)) + >>> b = np.array((2,3,4)) + >>> np.hstack((a,b)) + array([1, 2, 3, 2, 3, 4]) + >>> a = np.array([[1],[2],[3]]) + >>> b = np.array([[2],[3],[4]]) + >>> np.hstack((a,b)) + array([[1, 2], + [2, 3], + [3, 4]]) + + """ + arrs = map(atleast_1d,tup) + # As a special case, dimension 0 of 1-dimensional arrays is "horizontal" + if arrs[0].ndim == 1: + return _numpypy.concatenate(arrs, 0) + else: + return _numpypy.concatenate(arrs, 1) + +def dstack(tup): + """ + Stack arrays in sequence depth wise (along third axis). + + Takes a sequence of arrays and stack them along the third axis + to make a single array. Rebuilds arrays divided by `dsplit`. + This is a simple way to stack 2D arrays (images) into a single + 3D array for processing. + + Parameters + ---------- + tup : sequence of arrays + Arrays to stack. All of them must have the same shape along all + but the third axis. + + Returns + ------- + stacked : ndarray + The array formed by stacking the given arrays. + + See Also + -------- + vstack : Stack along first axis. + hstack : Stack along second axis. + concatenate : Join arrays. + dsplit : Split array along third axis. + + Notes + ----- + Equivalent to ``np.concatenate(tup, axis=2)``. + + Examples + -------- + >>> a = np.array((1,2,3)) + >>> b = np.array((2,3,4)) + >>> np.dstack((a,b)) + array([[[1, 2], + [2, 3], + [3, 4]]]) + + >>> a = np.array([[1],[2],[3]]) + >>> b = np.array([[2],[3],[4]]) + >>> np.dstack((a,b)) + array([[[1, 2]], + [[2, 3]], + [[3, 4]]]) + + """ + return _numpypy.concatenate(map(atleast_3d,tup),2) diff --git a/lib_pypy/pypy_test/__init__.py b/lib_pypy/pypy_test/__init__.py deleted file mode 100644 --- a/lib_pypy/pypy_test/__init__.py +++ /dev/null @@ -1,1 +0,0 @@ -# diff --git a/lib_pypy/pypy_test/hack___pypy__.py b/lib_pypy/pypy_test/hack___pypy__.py deleted file mode 100644 --- a/lib_pypy/pypy_test/hack___pypy__.py +++ /dev/null @@ -1,9 +0,0 @@ -# here only to make test runs work even if not running on top of PyPy -import sys, new - -def builtinify(f): - return f - -pypy = new.module('__pypy__') -pypy.builtinify = builtinify -sys.modules.setdefault('__pypy__', pypy) diff --git a/lib_pypy/pypy_test/inprogress_test_binascii_extra.py b/lib_pypy/pypy_test/inprogress_test_binascii_extra.py deleted file mode 100644 --- a/lib_pypy/pypy_test/inprogress_test_binascii_extra.py +++ /dev/null @@ -1,19 +0,0 @@ -from __future__ import absolute_import -from lib_pypy import binascii - -def test_uu(): - assert binascii.b2a_uu('1234567') == "',3(S-#4V-P \n" From noreply at buildbot.pypy.org Wed Feb 13 19:38:21 2013 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 13 Feb 2013 19:38:21 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: fix fix fix Message-ID: <20130213183821.2D18C1C3C21@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61182:f8277f4b139d Date: 2013-02-13 20:37 +0200 http://bitbucket.org/pypy/pypy/changeset/f8277f4b139d/ Log: fix fix fix diff --git a/rpython/jit/backend/arm/arch.py b/rpython/jit/backend/arm/arch.py --- a/rpython/jit/backend/arm/arch.py +++ b/rpython/jit/backend/arm/arch.py @@ -14,7 +14,7 @@ # ABI required information # All the rest of the data is in a GC-managed variable-size "frame". # This jitframe object's address is always stored in the register FP -# A jitframe is a jit.backend.llsupport.llmodel.JITFRAME = GcArray(Signed). +# A jitframe is a jit.backend.llsupport.llmodel.jitframe.JITFRAME # Stack frame fixed area # Currently only the force_index JITFRAME_FIXED_SIZE = 16 + 16 * 2 # 16 GPR + 16 VFP Regs (64bit) diff --git a/rpython/jit/backend/arm/runner.py b/rpython/jit/backend/arm/runner.py --- a/rpython/jit/backend/arm/runner.py +++ b/rpython/jit/backend/arm/runner.py @@ -1,6 +1,6 @@ from rpython.jit.backend.arm.arch import JITFRAME_FIXED_SIZE from rpython.jit.backend.arm.assembler import AssemblerARM -from rpython.jit.backend.arm.registers import all_regs, all_vfp_regs +from rpython.jit.backend.arm.registers import all_regs from rpython.jit.backend.llsupport import jitframe from rpython.jit.backend.llsupport.symbolic import WORD from rpython.jit.backend.llsupport.llmodel import AbstractLLCPU @@ -9,7 +9,6 @@ from rpython.rlib.unroll import unrolling_iterable from rpython.rtyper.llinterp import LLInterpreter from rpython.rtyper.lltypesystem import lltype, rffi, llmemory -from rpython.rtyper.lltypesystem.lloperation import llop jitframe.STATICSIZE = JITFRAME_FIXED_SIZE @@ -20,7 +19,10 @@ supports_longlong = False # XXX requires an implementation of # read_timestamp that works in user mode supports_singlefloats = True - + + from rpython.jit.backend.arm.arch import JITFRAME_FIXED_SIZE + all_reg_indexes = range(16) + use_hf_abi = False # use hard float abi flag def __init__(self, rtyper, stats, opts=None, translate_support_code=False, diff --git a/rpython/jit/backend/llsupport/assembler.py b/rpython/jit/backend/llsupport/assembler.py --- a/rpython/jit/backend/llsupport/assembler.py +++ b/rpython/jit/backend/llsupport/assembler.py @@ -30,7 +30,7 @@ if arg.type == REF: loc = fail_locs[i] if loc.is_reg(): - val = self.cpu.gpr_reg_mgr_cls.all_reg_indexes[loc.value] + val = self.cpu.all_reg_indexes[loc.value] else: val = loc.get_position() + self.cpu.JITFRAME_FIXED_SIZE gcmap[val // WORD // 8] |= r_uint(1) << (val % (WORD * 8)) diff --git a/rpython/jit/backend/x86/runner.py b/rpython/jit/backend/x86/runner.py --- a/rpython/jit/backend/x86/runner.py +++ b/rpython/jit/backend/x86/runner.py @@ -2,6 +2,7 @@ from rpython.rtyper.lltypesystem import lltype, llmemory, rffi from rpython.rlib.jit_hooks import LOOP_RUN_CONTAINER from rpython.jit.backend.x86.assembler import Assembler386 +from rpython.jit.backend.x86.regalloc import gpr_reg_mgr_cls from rpython.jit.backend.x86.profagent import ProfileAgent from rpython.jit.backend.llsupport.llmodel import AbstractLLCPU from rpython.jit.backend.x86 import regloc @@ -22,6 +23,7 @@ with_threads = False from rpython.jit.backend.x86.arch import JITFRAME_FIXED_SIZE + all_reg_indexes = gpr_reg_mgr_cls.all_reg_indexes def __init__(self, rtyper, stats, opts=None, translate_support_code=False, gcdescr=None): From noreply at buildbot.pypy.org Wed Feb 13 20:18:47 2013 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 13 Feb 2013 20:18:47 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: kill more duplication Message-ID: <20130213191847.6FA941C01A7@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61183:71edf3e0a14f Date: 2013-02-13 21:17 +0200 http://bitbucket.org/pypy/pypy/changeset/71edf3e0a14f/ Log: kill more duplication diff --git a/rpython/jit/backend/arm/assembler.py b/rpython/jit/backend/arm/assembler.py --- a/rpython/jit/backend/arm/assembler.py +++ b/rpython/jit/backend/arm/assembler.py @@ -734,26 +734,8 @@ return AsmInfo(ops_offset, startpos + rawstart, codeendpos - startpos) - def rebuild_faillocs_from_descr(self, descr, inputargs): - locs = [] - GPR_REGS = len(CoreRegisterManager.all_regs) - VFP_REGS = len(VFPRegisterManager.all_regs) - input_i = 0 - for pos in descr.rd_locs: - if pos == -1: - continue - elif pos < GPR_REGS * WORD: - locs.append(CoreRegisterManager.all_regs[pos // WORD]) - elif pos < (GPR_REGS * WORD + VFP_REGS * DOUBLE_WORD): - pos = pos // DOUBLE_WORD - GPR_REGS * WORD // DOUBLE_WORD - locs.append(VFPRegisterManager.all_regs[pos]) - else: - i = pos // WORD - JITFRAME_FIXED_SIZE - assert i >= 0 - tp = inputargs[input_i].type - locs.append(StackLocation(i, pos, tp)) - input_i += 1 - return locs + def new_stack_loc(self, i, pos, tp): + return StackLocation(i, pos, tp) def check_frame_before_jump(self, target_token): if target_token in self.target_tokens_currently_compiling: diff --git a/rpython/jit/backend/arm/opassembler.py b/rpython/jit/backend/arm/opassembler.py --- a/rpython/jit/backend/arm/opassembler.py +++ b/rpython/jit/backend/arm/opassembler.py @@ -24,7 +24,7 @@ from rpython.jit.backend.llsupport import symbolic from rpython.jit.backend.llsupport.gcmap import allocate_gcmap from rpython.jit.backend.llsupport.descr import InteriorFieldDescr -from rpython.jit.backend.llsupport.assembler import GuardToken +from rpython.jit.backend.llsupport.assembler import GuardToken, BaseAssembler from rpython.jit.metainterp.history import (Box, AbstractFailDescr, INT, FLOAT, REF) from rpython.jit.metainterp.history import JitCellToken, TargetToken @@ -48,7 +48,7 @@ self.offset = offset -class ResOpAssembler(object): +class ResOpAssembler(BaseAssembler): def emit_op_int_add(self, op, arglocs, regalloc, fcond): return self.int_add_impl(op, arglocs, regalloc, fcond) diff --git a/rpython/jit/backend/arm/runner.py b/rpython/jit/backend/arm/runner.py --- a/rpython/jit/backend/arm/runner.py +++ b/rpython/jit/backend/arm/runner.py @@ -1,20 +1,18 @@ from rpython.jit.backend.arm.arch import JITFRAME_FIXED_SIZE from rpython.jit.backend.arm.assembler import AssemblerARM -from rpython.jit.backend.arm.registers import all_regs +from rpython.jit.backend.arm.regalloc import CoreRegisterManager,\ + VFPRegisterManager from rpython.jit.backend.llsupport import jitframe -from rpython.jit.backend.llsupport.symbolic import WORD from rpython.jit.backend.llsupport.llmodel import AbstractLLCPU -from rpython.jit.metainterp import history from rpython.rlib.jit_hooks import LOOP_RUN_CONTAINER -from rpython.rlib.unroll import unrolling_iterable -from rpython.rtyper.llinterp import LLInterpreter -from rpython.rtyper.lltypesystem import lltype, rffi, llmemory - +from rpython.rtyper.lltypesystem import lltype, llmemory jitframe.STATICSIZE = JITFRAME_FIXED_SIZE class AbstractARMCPU(AbstractLLCPU): + IS_64_BIT = False + supports_floats = True supports_longlong = False # XXX requires an implementation of # read_timestamp that works in user mode @@ -22,6 +20,8 @@ from rpython.jit.backend.arm.arch import JITFRAME_FIXED_SIZE all_reg_indexes = range(16) + gen_regs = CoreRegisterManager.all_regs + float_regs = VFPRegisterManager.all_regs use_hf_abi = False # use hard float abi flag diff --git a/rpython/jit/backend/llsupport/assembler.py b/rpython/jit/backend/llsupport/assembler.py --- a/rpython/jit/backend/llsupport/assembler.py +++ b/rpython/jit/backend/llsupport/assembler.py @@ -36,6 +36,31 @@ gcmap[val // WORD // 8] |= r_uint(1) << (val % (WORD * 8)) return gcmap + class BaseAssembler(object): """ Base class for Assembler generator in real backends """ + def rebuild_faillocs_from_descr(self, descr, inputargs): + locs = [] + GPR_REGS = len(self.cpu.gen_regs) + XMM_REGS = len(self.cpu.float_regs) + input_i = 0 + if self.cpu.IS_64_BIT: + coeff = 1 + else: + coeff = 2 + for pos in descr.rd_locs: + if pos == -1: + continue + elif pos < GPR_REGS * WORD: + locs.append(self.cpu.gen_regs[pos // WORD]) + elif pos < (GPR_REGS + XMM_REGS * coeff) * WORD: + pos = (pos // WORD - GPR_REGS) // coeff + locs.append(self.cpu.float_regs[pos]) + else: + i = pos // WORD - self.cpu.JITFRAME_FIXED_SIZE + assert i >= 0 + tp = inputargs[input_i].type + locs.append(self.new_stack_loc(i, pos, tp)) + input_i += 1 + return locs diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -1926,31 +1926,9 @@ ofs = self.cpu.get_ofs_of_frame_field('jf_gcmap') mc.MOV_bi(ofs, 0) - def rebuild_faillocs_from_descr(self, descr, inputargs): - locs = [] - GPR_REGS = len(gpr_reg_mgr_cls.all_regs) - XMM_REGS = len(xmm_reg_mgr_cls.all_regs) + def new_stack_loc(self, i, pos, tp): base_ofs = self.cpu.get_baseofs_of_frame_field() - input_i = 0 - if IS_X86_64: - coeff = 1 - else: - coeff = 2 - for pos in descr.rd_locs: - if pos == -1: - continue - elif pos < GPR_REGS * WORD: - locs.append(gpr_reg_mgr_cls.all_regs[pos // WORD]) - elif pos < (GPR_REGS + XMM_REGS * coeff) * WORD: - pos = (pos // WORD - GPR_REGS) // coeff - locs.append(xmm_reg_mgr_cls.all_regs[pos]) - else: - i = pos // WORD - JITFRAME_FIXED_SIZE - assert i >= 0 - tp = inputargs[input_i].type - locs.append(StackLoc(i, get_ebp_ofs(base_ofs, i), tp)) - input_i += 1 - return locs + return StackLoc(i, get_ebp_ofs(base_ofs, i), tp) def setup_failure_recovery(self): self.failure_recovery_code = [0, 0, 0, 0] diff --git a/rpython/jit/backend/x86/runner.py b/rpython/jit/backend/x86/runner.py --- a/rpython/jit/backend/x86/runner.py +++ b/rpython/jit/backend/x86/runner.py @@ -2,7 +2,7 @@ from rpython.rtyper.lltypesystem import lltype, llmemory, rffi from rpython.rlib.jit_hooks import LOOP_RUN_CONTAINER from rpython.jit.backend.x86.assembler import Assembler386 -from rpython.jit.backend.x86.regalloc import gpr_reg_mgr_cls +from rpython.jit.backend.x86.regalloc import gpr_reg_mgr_cls, xmm_reg_mgr_cls from rpython.jit.backend.x86.profagent import ProfileAgent from rpython.jit.backend.llsupport.llmodel import AbstractLLCPU from rpython.jit.backend.x86 import regloc @@ -24,6 +24,8 @@ from rpython.jit.backend.x86.arch import JITFRAME_FIXED_SIZE all_reg_indexes = gpr_reg_mgr_cls.all_reg_indexes + gen_regs = gpr_reg_mgr_cls.all_regs + float_regs = xmm_reg_mgr_cls.all_regs def __init__(self, rtyper, stats, opts=None, translate_support_code=False, gcdescr=None): @@ -128,12 +130,13 @@ class CPU386(AbstractX86CPU): backend_name = 'x86' - WORD = 4 NUM_REGS = 8 CALLEE_SAVE_REGISTERS = [regloc.ebx, regloc.esi, regloc.edi] supports_longlong = True + IS_64_BIT = False + def __init__(self, *args, **kwargs): assert sys.maxint == (2**31 - 1) super(CPU386, self).__init__(*args, **kwargs) @@ -144,8 +147,9 @@ class CPU_X86_64(AbstractX86CPU): backend_name = 'x86_64' - WORD = 8 NUM_REGS = 16 CALLEE_SAVE_REGISTERS = [regloc.ebx, regloc.r12, regloc.r13, regloc.r14, regloc.r15] + IS_64_BIT = True + CPU = CPU386 From noreply at buildbot.pypy.org Wed Feb 13 21:25:15 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Wed, 13 Feb 2013 21:25:15 +0100 (CET) Subject: [pypy-commit] pypy py3k: update _ctypes_test.c to 3.2 Message-ID: <20130213202515.5B4F41C3C1D@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61185:963663b9ae4a Date: 2013-02-13 12:12 -0800 http://bitbucket.org/pypy/pypy/changeset/963663b9ae4a/ Log: update _ctypes_test.c to 3.2 diff --git a/lib_pypy/_ctypes_test.c b/lib_pypy/_ctypes_test.c --- a/lib_pypy/_ctypes_test.c +++ b/lib_pypy/_ctypes_test.c @@ -1,19 +1,6 @@ -/* This is a Verbatim copy of _ctypes_test.c from CPython 2.7 */ -/***************************************************************** - This file should be kept compatible with Python 2.3, see PEP 291. - *****************************************************************/ - - +/* This is a Verbatim copy of _ctypes_test.c from CPython 3.2 */ #include -/* - Backwards compatibility: - Python2.2 used LONG_LONG instead of PY_LONG_LONG -*/ -#if defined(HAVE_LONG_LONG) && !defined(PY_LONG_LONG) -#define PY_LONG_LONG LONG_LONG -#endif - #ifdef MS_WIN32 #include #endif @@ -388,7 +375,7 @@ short M: 1, N: 2, O: 3, P: 4, Q: 5, R: 6, S: 7; }; -DL_EXPORT(void) set_bitfields(struct BITS *bits, char name, int value) +EXPORT(void) set_bitfields(struct BITS *bits, char name, int value) { switch (name) { case 'A': bits->A = value; break; @@ -411,7 +398,7 @@ } } -DL_EXPORT(int) unpack_bitfields(struct BITS *bits, char name) +EXPORT(int) unpack_bitfields(struct BITS *bits, char name) { switch (name) { case 'A': return bits->A; @@ -610,8 +597,21 @@ #endif -DL_EXPORT(void) -init_ctypes_test(void) + +static struct PyModuleDef _ctypes_testmodule = { + PyModuleDef_HEAD_INIT, + "_ctypes_test", + NULL, + -1, + module_methods, + NULL, + NULL, + NULL, + NULL +}; + +PyMODINIT_FUNC +PyInit__ctypes_test(void) { - Py_InitModule("_ctypes_test", module_methods); + return PyModule_Create(&_ctypes_testmodule); } From noreply at buildbot.pypy.org Wed Feb 13 21:25:13 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Wed, 13 Feb 2013 21:25:13 +0100 (CET) Subject: [pypy-commit] pypy py3k: workaround lack of sys.getrefcount Message-ID: <20130213202513.3611C1C0EB1@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61184:e291f08cf01b Date: 2013-02-13 12:12 -0800 http://bitbucket.org/pypy/pypy/changeset/e291f08cf01b/ Log: workaround lack of sys.getrefcount diff --git a/lib-python/3.2/test/test_memoryview.py b/lib-python/3.2/test/test_memoryview.py --- a/lib-python/3.2/test/test_memoryview.py +++ b/lib-python/3.2/test/test_memoryview.py @@ -11,6 +11,7 @@ import array import io +getrefcount = sys.getrefcount if hasattr(sys, 'getrefcount') else lambda o: -1 class AbstractMemoryTests: source_bytes = b"abcdef" @@ -26,7 +27,7 @@ def check_getitem_with_type(self, tp): item = self.getitem_type b = tp(self._source) - oldrefcount = sys.getrefcount(b) + oldrefcount = getrefcount(b) m = self._view(b) self.assertEqual(m[0], item(b"a")) self.assertIsInstance(m[0], bytes) @@ -43,7 +44,7 @@ self.assertRaises(TypeError, lambda: m[0.0]) self.assertRaises(TypeError, lambda: m["a"]) m = None - self.assertEqual(sys.getrefcount(b), oldrefcount) + self.assertEqual(getrefcount(b), oldrefcount) def test_getitem(self): for tp in self._types: @@ -59,7 +60,7 @@ if not self.ro_type: return b = self.ro_type(self._source) - oldrefcount = sys.getrefcount(b) + oldrefcount = getrefcount(b) m = self._view(b) def setitem(value): m[0] = value @@ -67,14 +68,14 @@ self.assertRaises(TypeError, setitem, 65) self.assertRaises(TypeError, setitem, memoryview(b"a")) m = None - self.assertEqual(sys.getrefcount(b), oldrefcount) + self.assertEqual(getrefcount(b), oldrefcount) def test_setitem_writable(self): if not self.rw_type: return tp = self.rw_type b = self.rw_type(self._source) - oldrefcount = sys.getrefcount(b) + oldrefcount = getrefcount(b) m = self._view(b) m[0] = tp(b"0") self._check_contents(tp, b, b"0bcdef") @@ -110,7 +111,7 @@ self.assertRaises(ValueError, setitem, slice(0,2), b"a") m = None - self.assertEqual(sys.getrefcount(b), oldrefcount) + self.assertEqual(getrefcount(b), oldrefcount) def test_delitem(self): for tp in self._types: @@ -194,14 +195,14 @@ # Test PyObject_GetBuffer() on a memoryview object. for tp in self._types: b = tp(self._source) - oldrefcount = sys.getrefcount(b) + oldrefcount = getrefcount(b) m = self._view(b) - oldviewrefcount = sys.getrefcount(m) + oldviewrefcount = getrefcount(m) s = str(m, "utf-8") self._check_contents(tp, b, s.encode("utf-8")) - self.assertEqual(sys.getrefcount(m), oldviewrefcount) + self.assertEqual(getrefcount(m), oldviewrefcount) m = None - self.assertEqual(sys.getrefcount(b), oldrefcount) + self.assertEqual(getrefcount(b), oldrefcount) def test_gc(self): for tp in self._types: @@ -334,9 +335,9 @@ def test_refs(self): for tp in self._types: m = memoryview(tp(self._source)) - oldrefcount = sys.getrefcount(m) + oldrefcount = getrefcount(m) m[1:2] - self.assertEqual(sys.getrefcount(m), oldrefcount) + self.assertEqual(getrefcount(m), oldrefcount) class BaseMemorySliceSliceTests: source_bytes = b"XabcdefY" From noreply at buildbot.pypy.org Wed Feb 13 21:25:17 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Wed, 13 Feb 2013 21:25:17 +0100 (CET) Subject: [pypy-commit] pypy py3k: adapt our 2.7 ctypes workarounds Message-ID: <20130213202517.094FF1C0EB1@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61186:870d536b68cc Date: 2013-02-13 12:14 -0800 http://bitbucket.org/pypy/pypy/changeset/870d536b68cc/ Log: adapt our 2.7 ctypes workarounds diff --git a/lib-python/3.2/ctypes/test/__init__.py b/lib-python/3.2/ctypes/test/__init__.py --- a/lib-python/3.2/ctypes/test/__init__.py +++ b/lib-python/3.2/ctypes/test/__init__.py @@ -206,3 +206,16 @@ result = unittest.TestResult() test(result) return result + +def xfail(method): + """ + Poor's man xfail: remove it when all the failures have been fixed + """ + def new_method(self, *args, **kwds): + try: + method(self, *args, **kwds) + except: + pass + else: + self.assertTrue(False, "DID NOT RAISE") + return new_method diff --git a/lib-python/3.2/ctypes/test/test_arrays.py b/lib-python/3.2/ctypes/test/test_arrays.py --- a/lib-python/3.2/ctypes/test/test_arrays.py +++ b/lib-python/3.2/ctypes/test/test_arrays.py @@ -1,12 +1,23 @@ import unittest from ctypes import * +from test.support import impl_detail formats = "bBhHiIlLqQfd" +# c_longdouble commented out for PyPy, look at the commend in test_longdouble formats = c_byte, c_ubyte, c_short, c_ushort, c_int, c_uint, \ - c_long, c_ulonglong, c_float, c_double, c_longdouble + c_long, c_ulonglong, c_float, c_double #, c_longdouble class ArrayTestCase(unittest.TestCase): + + @impl_detail('long double not supported by PyPy', pypy=False) + def test_longdouble(self): + """ + This test is empty. It's just here to remind that we commented out + c_longdouble in "formats". If pypy will ever supports c_longdouble, we + should kill this test and uncomment c_longdouble inside formats. + """ + def test_simple(self): # create classes holding simple numeric types, and check # various properties. diff --git a/lib-python/3.2/ctypes/test/test_bitfields.py b/lib-python/3.2/ctypes/test/test_bitfields.py --- a/lib-python/3.2/ctypes/test/test_bitfields.py +++ b/lib-python/3.2/ctypes/test/test_bitfields.py @@ -115,17 +115,21 @@ def test_nonint_types(self): # bit fields are not allowed on non-integer types. result = self.fail_fields(("a", c_char_p, 1)) - self.assertEqual(result, (TypeError, 'bit fields not allowed for type c_char_p')) + self.assertEqual(result[0], TypeError) + self.assertIn('bit fields not allowed for type', result[1]) result = self.fail_fields(("a", c_void_p, 1)) - self.assertEqual(result, (TypeError, 'bit fields not allowed for type c_void_p')) + self.assertEqual(result[0], TypeError) + self.assertIn('bit fields not allowed for type', result[1]) if c_int != c_long: result = self.fail_fields(("a", POINTER(c_int), 1)) - self.assertEqual(result, (TypeError, 'bit fields not allowed for type LP_c_int')) + self.assertEqual(result[0], TypeError) + self.assertIn('bit fields not allowed for type', result[1]) result = self.fail_fields(("a", c_char, 1)) - self.assertEqual(result, (TypeError, 'bit fields not allowed for type c_char')) + self.assertEqual(result[0], TypeError) + self.assertIn('bit fields not allowed for type', result[1]) try: c_wchar @@ -133,13 +137,15 @@ pass else: result = self.fail_fields(("a", c_wchar, 1)) - self.assertEqual(result, (TypeError, 'bit fields not allowed for type c_wchar')) + self.assertEqual(result[0], TypeError) + self.assertIn('bit fields not allowed for type', result[1]) class Dummy(Structure): _fields_ = [] result = self.fail_fields(("a", Dummy, 1)) - self.assertEqual(result, (TypeError, 'bit fields not allowed for type Dummy')) + self.assertEqual(result[0], TypeError) + self.assertIn('bit fields not allowed for type', result[1]) def test_single_bitfield_size(self): for c_typ in int_types: diff --git a/lib-python/3.2/ctypes/test/test_byteswap.py b/lib-python/3.2/ctypes/test/test_byteswap.py --- a/lib-python/3.2/ctypes/test/test_byteswap.py +++ b/lib-python/3.2/ctypes/test/test_byteswap.py @@ -2,6 +2,7 @@ from binascii import hexlify from ctypes import * +from ctypes.test import xfail def bin(s): return hexlify(memoryview(s)).decode().upper() @@ -21,6 +22,7 @@ setattr(bits, "i%s" % i, 1) dump(bits) + @xfail def test_endian_short(self): if sys.byteorder == "little": self.assertTrue(c_short.__ctype_le__ is c_short) @@ -48,6 +50,7 @@ self.assertEqual(bin(s), "3412") self.assertEqual(s.value, 0x1234) + @xfail def test_endian_int(self): if sys.byteorder == "little": self.assertTrue(c_int.__ctype_le__ is c_int) @@ -76,6 +79,7 @@ self.assertEqual(bin(s), "78563412") self.assertEqual(s.value, 0x12345678) + @xfail def test_endian_longlong(self): if sys.byteorder == "little": self.assertTrue(c_longlong.__ctype_le__ is c_longlong) @@ -104,6 +108,7 @@ self.assertEqual(bin(s), "EFCDAB9078563412") self.assertEqual(s.value, 0x1234567890ABCDEF) + @xfail def test_endian_float(self): if sys.byteorder == "little": self.assertTrue(c_float.__ctype_le__ is c_float) @@ -122,6 +127,7 @@ self.assertAlmostEqual(s.value, math.pi, places=6) self.assertEqual(bin(struct.pack(">f", math.pi)), bin(s)) + @xfail def test_endian_double(self): if sys.byteorder == "little": self.assertTrue(c_double.__ctype_le__ is c_double) @@ -149,6 +155,7 @@ self.assertTrue(c_char.__ctype_le__ is c_char) self.assertTrue(c_char.__ctype_be__ is c_char) + @xfail def test_struct_fields_1(self): if sys.byteorder == "little": base = BigEndianStructure @@ -184,6 +191,7 @@ pass self.assertRaises(TypeError, setattr, T, "_fields_", [("x", typ)]) + @xfail def test_struct_struct(self): # nested structures with different byteorders @@ -212,6 +220,7 @@ self.assertEqual(s.point.x, 1) self.assertEqual(s.point.y, 2) + @xfail def test_struct_fields_2(self): # standard packing in struct uses no alignment. # So, we have to align using pad bytes. @@ -235,6 +244,7 @@ s2 = struct.pack(fmt, 0x12, 0x1234, 0x12345678, 3.14) self.assertEqual(bin(s1), bin(s2)) + @xfail def test_unaligned_nonnative_struct_fields(self): if sys.byteorder == "little": base = BigEndianStructure diff --git a/lib-python/3.2/ctypes/test/test_callbacks.py b/lib-python/3.2/ctypes/test/test_callbacks.py --- a/lib-python/3.2/ctypes/test/test_callbacks.py +++ b/lib-python/3.2/ctypes/test/test_callbacks.py @@ -1,5 +1,6 @@ import unittest from ctypes import * +from ctypes.test import xfail import _ctypes_test class Callbacks(unittest.TestCase): @@ -92,6 +93,7 @@ ## self.check_type(c_char_p, "abc") ## self.check_type(c_char_p, "def") + @xfail def test_pyobject(self): o = () from sys import getrefcount as grc diff --git a/lib-python/3.2/ctypes/test/test_cfuncs.py b/lib-python/3.2/ctypes/test/test_cfuncs.py --- a/lib-python/3.2/ctypes/test/test_cfuncs.py +++ b/lib-python/3.2/ctypes/test/test_cfuncs.py @@ -5,6 +5,7 @@ from ctypes import * import _ctypes_test +from test.support import impl_detail class CFunctions(unittest.TestCase): _dll = CDLL(_ctypes_test.__file__) @@ -158,12 +159,14 @@ self.assertEqual(self._dll.tf_bd(0, 42.), 14.) self.assertEqual(self.S(), 42) + @impl_detail('long double not supported by PyPy', pypy=False) def test_longdouble(self): self._dll.tf_D.restype = c_longdouble self._dll.tf_D.argtypes = (c_longdouble,) self.assertEqual(self._dll.tf_D(42.), 14.) self.assertEqual(self.S(), 42) + @impl_detail('long double not supported by PyPy', pypy=False) def test_longdouble_plus(self): self._dll.tf_bD.restype = c_longdouble self._dll.tf_bD.argtypes = (c_byte, c_longdouble) diff --git a/lib-python/3.2/ctypes/test/test_delattr.py b/lib-python/3.2/ctypes/test/test_delattr.py --- a/lib-python/3.2/ctypes/test/test_delattr.py +++ b/lib-python/3.2/ctypes/test/test_delattr.py @@ -6,15 +6,15 @@ class TestCase(unittest.TestCase): def test_simple(self): - self.assertRaises(TypeError, + self.assertRaises((TypeError, AttributeError), delattr, c_int(42), "value") def test_chararray(self): - self.assertRaises(TypeError, + self.assertRaises((TypeError, AttributeError), delattr, (c_char * 5)(), "value") def test_struct(self): - self.assertRaises(TypeError, + self.assertRaises((TypeError, AttributeError), delattr, X(), "foo") if __name__ == "__main__": diff --git a/lib-python/3.2/ctypes/test/test_frombuffer.py b/lib-python/3.2/ctypes/test/test_frombuffer.py --- a/lib-python/3.2/ctypes/test/test_frombuffer.py +++ b/lib-python/3.2/ctypes/test/test_frombuffer.py @@ -2,6 +2,7 @@ import array import gc import unittest +from ctypes.test import xfail class X(Structure): _fields_ = [("c_int", c_int)] @@ -10,6 +11,7 @@ self._init_called = True class Test(unittest.TestCase): + @xfail def test_fom_buffer(self): a = array.array("i", range(16)) x = (c_int * 16).from_buffer(a) @@ -35,6 +37,7 @@ self.assertRaises(TypeError, (c_char * 16).from_buffer, "a" * 16) + @xfail def test_fom_buffer_with_offset(self): a = array.array("i", range(16)) x = (c_int * 15).from_buffer(a, sizeof(c_int)) @@ -43,6 +46,7 @@ self.assertRaises(ValueError, lambda: (c_int * 16).from_buffer(a, sizeof(c_int))) self.assertRaises(ValueError, lambda: (c_int * 1).from_buffer(a, 16 * sizeof(c_int))) + @xfail def test_from_buffer_copy(self): a = array.array("i", range(16)) x = (c_int * 16).from_buffer_copy(a) @@ -67,6 +71,7 @@ x = (c_char * 16).from_buffer_copy(b"a" * 16) self.assertEqual(x[:], b"a" * 16) + @xfail def test_fom_buffer_copy_with_offset(self): a = array.array("i", range(16)) x = (c_int * 15).from_buffer_copy(a, sizeof(c_int)) diff --git a/lib-python/3.2/ctypes/test/test_functions.py b/lib-python/3.2/ctypes/test/test_functions.py --- a/lib-python/3.2/ctypes/test/test_functions.py +++ b/lib-python/3.2/ctypes/test/test_functions.py @@ -7,6 +7,8 @@ from ctypes import * import sys, unittest +from ctypes.test import xfail +from test.support import impl_detail try: WINFUNCTYPE @@ -143,6 +145,7 @@ self.assertEqual(result, -21) self.assertEqual(type(result), float) + @impl_detail('long double not supported by PyPy', pypy=False) def test_longdoubleresult(self): f = dll._testfunc_D_bhilfD f.argtypes = [c_byte, c_short, c_int, c_long, c_float, c_longdouble] @@ -394,6 +397,7 @@ self.assertEqual((s8i.a, s8i.b, s8i.c, s8i.d, s8i.e, s8i.f, s8i.g, s8i.h), (9*2, 8*3, 7*4, 6*5, 5*6, 4*7, 3*8, 2*9)) + @xfail def test_sf1651235(self): # see http://www.python.org/sf/1651235 diff --git a/lib-python/3.2/ctypes/test/test_internals.py b/lib-python/3.2/ctypes/test/test_internals.py --- a/lib-python/3.2/ctypes/test/test_internals.py +++ b/lib-python/3.2/ctypes/test/test_internals.py @@ -1,7 +1,10 @@ # This tests the internal _objects attribute import unittest from ctypes import * -from sys import getrefcount as grc +try: + from sys import getrefcount as grc +except ImportError: + grc = None # e.g. PyPy # XXX This test must be reviewed for correctness!!! @@ -22,6 +25,8 @@ self.assertEqual(id(a), id(b)) def test_ints(self): + if grc is None: + return unittest.skip("no sys.getrefcount()") i = 42000123 refcnt = grc(i) ci = c_int(i) @@ -29,6 +34,8 @@ self.assertEqual(ci._objects, None) def test_c_char_p(self): + if grc is None: + return unittest.skip("no sys.getrefcount()") s = b"Hello, World" refcnt = grc(s) cs = c_char_p(s) diff --git a/lib-python/3.2/ctypes/test/test_libc.py b/lib-python/3.2/ctypes/test/test_libc.py --- a/lib-python/3.2/ctypes/test/test_libc.py +++ b/lib-python/3.2/ctypes/test/test_libc.py @@ -29,5 +29,14 @@ lib.my_qsort(chars, len(chars)-1, sizeof(c_char), comparefunc(sort)) self.assertEqual(chars.raw, b" ,,aaaadmmmnpppsss\x00") + def SKIPPED_test_no_more_xfail(self): + # We decided to not explicitly support the whole ctypes-2.7 + # and instead go for a case-by-case, demand-driven approach. + # So this test is skipped instead of failing. + import socket + import ctypes.test + self.assertTrue(not hasattr(ctypes.test, 'xfail'), + "You should incrementally grep for '@xfail' and remove them, they are real failures") + if __name__ == "__main__": unittest.main() diff --git a/lib-python/3.2/ctypes/test/test_loading.py b/lib-python/3.2/ctypes/test/test_loading.py --- a/lib-python/3.2/ctypes/test/test_loading.py +++ b/lib-python/3.2/ctypes/test/test_loading.py @@ -2,7 +2,7 @@ import sys, unittest import os from ctypes.util import find_library -from ctypes.test import is_resource_enabled +from ctypes.test import is_resource_enabled, xfail libc_name = None if os.name == "nt": @@ -75,6 +75,7 @@ self.assertRaises(AttributeError, dll.__getitem__, 1234) if os.name == "nt": + @xfail def test_1703286_A(self): from _ctypes import LoadLibrary, FreeLibrary # On winXP 64-bit, advapi32 loads at an address that does @@ -85,6 +86,7 @@ handle = LoadLibrary("advapi32") FreeLibrary(handle) + @xfail def test_1703286_B(self): # Since on winXP 64-bit advapi32 loads like described # above, the (arbitrarily selected) CloseEventLog function diff --git a/lib-python/3.2/ctypes/test/test_macholib.py b/lib-python/3.2/ctypes/test/test_macholib.py --- a/lib-python/3.2/ctypes/test/test_macholib.py +++ b/lib-python/3.2/ctypes/test/test_macholib.py @@ -52,7 +52,6 @@ '/usr/lib/libSystem.B.dylib') result = find_lib('z') - self.assertTrue(result.startswith('/usr/lib/libz.1')) self.assertTrue(result.endswith('.dylib')) self.assertEqual(find_lib('IOKit'), diff --git a/lib-python/3.2/ctypes/test/test_memfunctions.py b/lib-python/3.2/ctypes/test/test_memfunctions.py --- a/lib-python/3.2/ctypes/test/test_memfunctions.py +++ b/lib-python/3.2/ctypes/test/test_memfunctions.py @@ -53,7 +53,8 @@ s = string_at(b"foo bar") # XXX The following may be wrong, depending on how Python # manages string instances - self.assertEqual(2, sys.getrefcount(s)) + if hasattr(sys, 'getrefcount'): + self.assertEqual(2, sys.getrefcount(s)) self.assertTrue(s, "foo bar") self.assertEqual(string_at(b"foo bar", 7), b"foo bar") diff --git a/lib-python/3.2/ctypes/test/test_numbers.py b/lib-python/3.2/ctypes/test/test_numbers.py --- a/lib-python/3.2/ctypes/test/test_numbers.py +++ b/lib-python/3.2/ctypes/test/test_numbers.py @@ -1,6 +1,7 @@ from ctypes import * import unittest import struct +from ctypes.test import xfail def valid_ranges(*types): # given a sequence of numeric types, collect their _type_ @@ -89,12 +90,14 @@ ## self.assertRaises(ValueError, t, l-1) ## self.assertRaises(ValueError, t, h+1) + @xfail def test_from_param(self): # the from_param class method attribute always # returns PyCArgObject instances for t in signed_types + unsigned_types + float_types: self.assertEqual(ArgType, type(t.from_param(0))) + @xfail def test_byref(self): # calling byref returns also a PyCArgObject instance for t in signed_types + unsigned_types + float_types + bool_types: @@ -102,6 +105,7 @@ self.assertEqual(ArgType, type(parm)) + @xfail def test_floats(self): # c_float and c_double can be created from # Python int, long and float @@ -115,6 +119,7 @@ self.assertEqual(t(2).value, 2.0) self.assertEqual(t(f).value, 2.0) + @xfail def test_integers(self): class FloatLike(object): def __float__(self): diff --git a/lib-python/3.2/ctypes/test/test_objects.py b/lib-python/3.2/ctypes/test/test_objects.py --- a/lib-python/3.2/ctypes/test/test_objects.py +++ b/lib-python/3.2/ctypes/test/test_objects.py @@ -22,7 +22,7 @@ >>> array[4] = b'foo bar' >>> array._objects -{'4': b'foo bar'} +{'4': } >>> array[4] b'foo bar' >>> @@ -47,9 +47,9 @@ >>> x.array[0] = b'spam spam spam' >>> x._objects -{'0:2': b'spam spam spam'} +{'0:2': } >>> x.array._b_base_._objects -{'0:2': b'spam spam spam'} +{'0:2': } >>> ''' diff --git a/lib-python/3.2/ctypes/test/test_parameters.py b/lib-python/3.2/ctypes/test/test_parameters.py --- a/lib-python/3.2/ctypes/test/test_parameters.py +++ b/lib-python/3.2/ctypes/test/test_parameters.py @@ -1,5 +1,7 @@ import unittest, sys +from ctypes.test import xfail + class SimpleTypesTestCase(unittest.TestCase): def setUp(self): @@ -48,6 +50,7 @@ self.assertEqual(CWCHARP.from_param("abc"), "abcabcabc") # XXX Replace by c_char_p tests + @xfail def test_cstrings(self): from ctypes import c_char_p, byref @@ -84,7 +87,10 @@ pa = c_wchar_p.from_param(c_wchar_p("123")) self.assertEqual(type(pa), c_wchar_p) + if sys.platform == "win32": + test_cw_strings = xfail(test_cw_strings) + @xfail def test_int_pointers(self): from ctypes import c_short, c_uint, c_int, c_long, POINTER, pointer LPINT = POINTER(c_int) diff --git a/lib-python/3.2/ctypes/test/test_pep3118.py b/lib-python/3.2/ctypes/test/test_pep3118.py --- a/lib-python/3.2/ctypes/test/test_pep3118.py +++ b/lib-python/3.2/ctypes/test/test_pep3118.py @@ -1,6 +1,7 @@ import unittest from ctypes import * import re, struct, sys +from ctypes.test import xfail if sys.byteorder == "little": THIS_ENDIAN = "<" @@ -19,6 +20,7 @@ class Test(unittest.TestCase): + @xfail def test_native_types(self): for tp, fmt, shape, itemtp in native_types: ob = tp() @@ -46,6 +48,7 @@ print(tp) raise + @xfail def test_endian_types(self): for tp, fmt, shape, itemtp in endian_types: ob = tp() diff --git a/lib-python/3.2/ctypes/test/test_pickling.py b/lib-python/3.2/ctypes/test/test_pickling.py --- a/lib-python/3.2/ctypes/test/test_pickling.py +++ b/lib-python/3.2/ctypes/test/test_pickling.py @@ -3,6 +3,7 @@ from ctypes import * import _ctypes_test dll = CDLL(_ctypes_test.__file__) +from ctypes.test import xfail class X(Structure): _fields_ = [("a", c_int), ("b", c_double)] @@ -21,6 +22,7 @@ def loads(self, item): return pickle.loads(item) + @xfail def test_simple(self): for src in [ c_int(42), @@ -31,6 +33,7 @@ self.assertEqual(memoryview(src).tobytes(), memoryview(dst).tobytes()) + @xfail def test_struct(self): X.init_called = 0 @@ -49,6 +52,7 @@ self.assertEqual(memoryview(y).tobytes(), memoryview(x).tobytes()) + @xfail def test_unpickable(self): # ctypes objects that are pointers or contain pointers are # unpickable. @@ -66,6 +70,7 @@ ]: self.assertRaises(ValueError, lambda: self.dumps(item)) + @xfail def test_wchar(self): pickle.dumps(c_char(b"x")) # Issue 5049 diff --git a/lib-python/3.2/ctypes/test/test_python_api.py b/lib-python/3.2/ctypes/test/test_python_api.py --- a/lib-python/3.2/ctypes/test/test_python_api.py +++ b/lib-python/3.2/ctypes/test/test_python_api.py @@ -1,6 +1,6 @@ from ctypes import * import unittest, sys -from ctypes.test import is_resource_enabled +from ctypes.test import is_resource_enabled, xfail ################################################################ # This section should be moved into ctypes\__init__.py, when it's ready. @@ -9,7 +9,10 @@ ################################################################ -from sys import getrefcount as grc +try: + from sys import getrefcount as grc +except ImportError: + grc = None # e.g. PyPy if sys.version_info > (2, 4): c_py_ssize_t = c_size_t else: @@ -25,6 +28,7 @@ self.assertEqual(PyBytes_FromStringAndSize(b"abcdefghi", 3), b"abc") + @xfail def test_PyString_FromString(self): pythonapi.PyBytes_FromString.restype = py_object pythonapi.PyBytes_FromString.argtypes = (c_char_p,) @@ -56,6 +60,7 @@ del res self.assertEqual(grc(42), ref42) + @xfail def test_PyObj_FromPtr(self): s = "abc def ghi jkl" ref = grc(s) @@ -81,6 +86,7 @@ # not enough arguments self.assertRaises(TypeError, PyOS_snprintf, buf) + @xfail def test_pyobject_repr(self): self.assertEqual(repr(py_object()), "py_object()") self.assertEqual(repr(py_object(42)), "py_object(42)") diff --git a/lib-python/3.2/ctypes/test/test_refcounts.py b/lib-python/3.2/ctypes/test/test_refcounts.py --- a/lib-python/3.2/ctypes/test/test_refcounts.py +++ b/lib-python/3.2/ctypes/test/test_refcounts.py @@ -11,7 +11,10 @@ class RefcountTestCase(unittest.TestCase): def test_1(self): - from sys import getrefcount as grc + try: + from sys import getrefcount as grc + except ImportError: + return unittest.skip("no sys.getrefcount()") f = dll._testfunc_callback_i_if f.restype = ctypes.c_int @@ -35,7 +38,10 @@ def test_refcount(self): - from sys import getrefcount as grc + try: + from sys import getrefcount as grc + except ImportError: + return unittest.skip("no sys.getrefcount()") def func(*args): pass # this is the standard refcount for func @@ -84,12 +90,17 @@ class AnotherLeak(unittest.TestCase): def test_callback(self): import sys + try: + from sys import getrefcount + except ImportError: + return unittest.skip("no sys.getrefcount()") proto = ctypes.CFUNCTYPE(ctypes.c_int, ctypes.c_int, ctypes.c_int) def func(a, b): return a * b * 2 f = proto(func) + gc.collect() a = sys.getrefcount(ctypes.c_int) f(1, 2) self.assertEqual(sys.getrefcount(ctypes.c_int), a) diff --git a/lib-python/3.2/ctypes/test/test_stringptr.py b/lib-python/3.2/ctypes/test/test_stringptr.py --- a/lib-python/3.2/ctypes/test/test_stringptr.py +++ b/lib-python/3.2/ctypes/test/test_stringptr.py @@ -2,11 +2,13 @@ from ctypes import * import _ctypes_test +from ctypes.test import xfail lib = CDLL(_ctypes_test.__file__) class StringPtrTestCase(unittest.TestCase): + @xfail def test__POINTER_c_char(self): class X(Structure): _fields_ = [("str", POINTER(c_char))] @@ -27,6 +29,7 @@ self.assertRaises(TypeError, setattr, x, "str", "Hello, World") + @xfail def test__c_char_p(self): class X(Structure): _fields_ = [("str", c_char_p)] diff --git a/lib-python/3.2/ctypes/test/test_strings.py b/lib-python/3.2/ctypes/test/test_strings.py --- a/lib-python/3.2/ctypes/test/test_strings.py +++ b/lib-python/3.2/ctypes/test/test_strings.py @@ -1,5 +1,6 @@ import unittest from ctypes import * +from test import support class StringArrayTestCase(unittest.TestCase): def test(self): @@ -30,8 +31,9 @@ buf.value = b"Hello, World" self.assertEqual(buf.value, b"Hello, World") - self.assertRaises(TypeError, setattr, buf, "value", memoryview(b"Hello, World")) - self.assertRaises(TypeError, setattr, buf, "value", memoryview(b"abc")) + if support.check_impl_detail(): + self.assertRaises(TypeError, setattr, buf, "value", memoryview(b"Hello, World")) + self.assertRaises(TypeError, setattr, buf, "value", memoryview(b"abc")) self.assertRaises(ValueError, setattr, buf, "raw", memoryview(b"x" * 100)) def test_c_buffer_raw(self): @@ -39,7 +41,8 @@ buf.raw = memoryview(b"Hello, World") self.assertEqual(buf.value, b"Hello, World") - self.assertRaises(TypeError, setattr, buf, "value", memoryview(b"abc")) + if support.check_impl_detail(): + self.assertRaises(TypeError, setattr, buf, "value", memoryview(b"abc")) self.assertRaises(ValueError, setattr, buf, "raw", memoryview(b"x" * 100)) def test_param_1(self): diff --git a/lib-python/3.2/ctypes/test/test_structures.py b/lib-python/3.2/ctypes/test/test_structures.py --- a/lib-python/3.2/ctypes/test/test_structures.py +++ b/lib-python/3.2/ctypes/test/test_structures.py @@ -194,8 +194,8 @@ self.assertEqual(X.b.offset, min(8, longlong_align)) - d = {"_fields_": [("a", "b"), - ("b", "q")], + d = {"_fields_": [("a", c_byte), + ("b", c_longlong)], "_pack_": -1} self.assertRaises(ValueError, type(Structure), "X", (Structure,), d) diff --git a/lib-python/3.2/ctypes/test/test_varsize_struct.py b/lib-python/3.2/ctypes/test/test_varsize_struct.py --- a/lib-python/3.2/ctypes/test/test_varsize_struct.py +++ b/lib-python/3.2/ctypes/test/test_varsize_struct.py @@ -1,7 +1,9 @@ from ctypes import * import unittest +from ctypes.test import xfail class VarSizeTest(unittest.TestCase): + @xfail def test_resize(self): class X(Structure): _fields_ = [("item", c_int), From noreply at buildbot.pypy.org Wed Feb 13 21:25:18 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Wed, 13 Feb 2013 21:25:18 +0100 (CET) Subject: [pypy-commit] pypy py3k: some quick fixes Message-ID: <20130213202518.9F2221C0EB1@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61187:bd87e595d506 Date: 2013-02-13 12:21 -0800 http://bitbucket.org/pypy/pypy/changeset/bd87e595d506/ Log: some quick fixes diff --git a/lib_pypy/_ctypes/array.py b/lib_pypy/_ctypes/array.py --- a/lib_pypy/_ctypes/array.py +++ b/lib_pypy/_ctypes/array.py @@ -23,7 +23,7 @@ for i in range(len(val)): self[i] = val[i] if len(val) < self._length_: - self[len(val)] = '\x00' + self[len(val)] = b'\x00' res.value = property(getvalue, setvalue) def getraw(self): @@ -89,12 +89,13 @@ # or function argument... from ctypes import c_char, c_wchar if issubclass(self._type_, (c_char, c_wchar)): - if isinstance(value, basestring): + # XXX: this should maybe be stricer for py3 (c_char disallowing str?) + if isinstance(value, (bytes, str)): if len(value) > self._length_: raise ValueError("Invalid length") value = self(*value) elif not isinstance(value, self): - raise TypeError("expected string or Unicode object, %s found" + raise TypeError("expected string, %s found" % (value.__class__.__name__,)) else: if isinstance(value, tuple): diff --git a/lib_pypy/_ctypes/basics.py b/lib_pypy/_ctypes/basics.py --- a/lib_pypy/_ctypes/basics.py +++ b/lib_pypy/_ctypes/basics.py @@ -137,7 +137,7 @@ return self.value def __buffer__(self): - return buffer(self._buffer) + return self._buffer.__buffer__() def _get_b_base(self): try: diff --git a/lib_pypy/_ctypes/function.py b/lib_pypy/_ctypes/function.py --- a/lib_pypy/_ctypes/function.py +++ b/lib_pypy/_ctypes/function.py @@ -307,7 +307,8 @@ except: exc_info = sys.exc_info() traceback.print_tb(exc_info[2], file=sys.stderr) - print >>sys.stderr, "%s: %s" % (exc_info[0].__name__, exc_info[1]) + print("%s: %s" % (exc_info[0].__name__, exc_info[1]), + file=sys.stderr) return 0 if self._restype_ is not None: return res diff --git a/lib_pypy/_ctypes/primitive.py b/lib_pypy/_ctypes/primitive.py --- a/lib_pypy/_ctypes/primitive.py +++ b/lib_pypy/_ctypes/primitive.py @@ -184,7 +184,7 @@ elif tp == 'u': def _setvalue(self, val): - if isinstance(val, str): + if isinstance(val, bytes): val = val.decode(ConvMode.encoding, ConvMode.errors) # possible if we use 'ignore' if val: @@ -195,7 +195,7 @@ elif tp == 'c': def _setvalue(self, val): - if isinstance(val, unicode): + if isinstance(val, str): val = val.encode(ConvMode.encoding, ConvMode.errors) if val: self._buffer[0] = val From noreply at buildbot.pypy.org Wed Feb 13 21:25:20 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Wed, 13 Feb 2013 21:25:20 +0100 (CET) Subject: [pypy-commit] pypy py3k: dbm.py -> _gdbm.py Message-ID: <20130213202520.6816A1C0EB1@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61188:38bdcc0d014a Date: 2013-02-13 12:22 -0800 http://bitbucket.org/pypy/pypy/changeset/38bdcc0d014a/ Log: dbm.py -> _gdbm.py diff --git a/lib_pypy/dbm.py b/lib_pypy/_gdbm.py rename from lib_pypy/dbm.py rename to lib_pypy/_gdbm.py From noreply at buildbot.pypy.org Wed Feb 13 21:37:16 2013 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 13 Feb 2013 21:37:16 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: and another bites the dust Message-ID: <20130213203716.3A0E31C0EB1@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61189:bcb1498b0dde Date: 2013-02-13 22:36 +0200 http://bitbucket.org/pypy/pypy/changeset/bcb1498b0dde/ Log: and another bites the dust diff --git a/rpython/jit/backend/arm/assembler.py b/rpython/jit/backend/arm/assembler.py --- a/rpython/jit/backend/arm/assembler.py +++ b/rpython/jit/backend/arm/assembler.py @@ -471,37 +471,9 @@ rawstart = mc.materialize(self.cpu.asmmemmgr, []) self.failure_recovery_code[exc + 2 * withfloats] = rawstart - def generate_quick_failure(self, guardtok, fcond=c.AL): - assert isinstance(guardtok.exc, bool) + def generate_quick_failure(self, guardtok): startpos = self.mc.currpos() - withfloats = False - for box in guardtok.failargs: - if box is not None and box.type == FLOAT: - withfloats = True - break - exc = guardtok.exc - target = self.failure_recovery_code[exc + 2 * withfloats] - fail_descr = cast_instance_to_gcref(guardtok.faildescr) - fail_descr = rffi.cast(lltype.Signed, fail_descr) - base_ofs = self.cpu.get_baseofs_of_frame_field() - positions = [0] * len(guardtok.fail_locs) - for i, loc in enumerate(guardtok.fail_locs): - if loc is None: - positions[i] = -1 - elif loc.is_stack(): - positions[i] = loc.value - base_ofs - else: - if loc.is_reg(): - assert loc is not r.fp # for now - v = loc.value - else: - assert loc.is_vfp_reg() - v = len(CoreRegisterManager.all_regs) + loc.value * 2 - positions[i] = v * WORD - # write down the positions of locs - guardtok.faildescr.rd_locs = positions - # we want the descr to keep alive - guardtok.faildescr.rd_loop_token = self.current_clt + fail_descr, target = self.store_info_on_descr(startpos, guardtok) self.regalloc_push(imm(fail_descr)) self.push_gcmap(self.mc, gcmap=guardtok.gcmap, push=True) self.mc.BL(target) diff --git a/rpython/jit/backend/arm/runner.py b/rpython/jit/backend/arm/runner.py --- a/rpython/jit/backend/arm/runner.py +++ b/rpython/jit/backend/arm/runner.py @@ -2,6 +2,7 @@ from rpython.jit.backend.arm.assembler import AssemblerARM from rpython.jit.backend.arm.regalloc import CoreRegisterManager,\ VFPRegisterManager +from rpython.jit.backend.arm.registers import fp, all_regs from rpython.jit.backend.llsupport import jitframe from rpython.jit.backend.llsupport.llmodel import AbstractLLCPU from rpython.rlib.jit_hooks import LOOP_RUN_CONTAINER @@ -19,9 +20,10 @@ supports_singlefloats = True from rpython.jit.backend.arm.arch import JITFRAME_FIXED_SIZE - all_reg_indexes = range(16) + all_reg_indexes = all_regs gen_regs = CoreRegisterManager.all_regs float_regs = VFPRegisterManager.all_regs + frame_reg = fp use_hf_abi = False # use hard float abi flag diff --git a/rpython/jit/backend/llsupport/assembler.py b/rpython/jit/backend/llsupport/assembler.py --- a/rpython/jit/backend/llsupport/assembler.py +++ b/rpython/jit/backend/llsupport/assembler.py @@ -1,7 +1,9 @@ from rpython.rlib.rarithmetic import r_uint from rpython.jit.backend.llsupport.symbolic import WORD -from rpython.jit.metainterp.history import REF +from rpython.jit.metainterp.history import REF, FLOAT +from rpython.rtyper.annlowlevel import cast_instance_to_gcref +from rpython.rtyper.lltypesystem import rffi, lltype class GuardToken(object): def __init__(self, cpu, gcmap, faildescr, failargs, fail_locs, exc, @@ -64,3 +66,37 @@ locs.append(self.new_stack_loc(i, pos, tp)) input_i += 1 return locs + + def store_info_on_descr(self, startspos, guardtok): + withfloats = False + for box in guardtok.failargs: + if box is not None and box.type == FLOAT: + withfloats = True + break + exc = guardtok.exc + target = self.failure_recovery_code[exc + 2 * withfloats] + fail_descr = cast_instance_to_gcref(guardtok.faildescr) + fail_descr = rffi.cast(lltype.Signed, fail_descr) + base_ofs = self.cpu.get_baseofs_of_frame_field() + positions = [0] * len(guardtok.fail_locs) + for i, loc in enumerate(guardtok.fail_locs): + if loc is None: + positions[i] = -1 + elif loc.is_stack(): + positions[i] = loc.value - base_ofs + else: + assert loc is not self.cpu.frame_reg # for now + if self.cpu.IS_64_BIT: + coeff = 1 + else: + coeff = 2 + if loc.is_float(): + v = len(self.cpu.gen_regs) + loc.value * coeff + else: + v = self.cpu.all_reg_indexes[loc.value] + positions[i] = v * WORD + # write down the positions of locs + guardtok.faildescr.rd_locs = positions + # we want the descr to keep alive + guardtok.faildescr.rd_loop_token = self.current_clt + return fail_descr, target diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -1864,51 +1864,13 @@ return startpos def generate_quick_failure(self, guardtok): - """Generate the initial code for handling a failure. We try to - keep it as compact as possible. + """ Gather information about failure """ - mc = self.mc - startpos = mc.get_relative_pos() - withfloats = False - for box in guardtok.failargs: - if box is not None and box.type == FLOAT: - withfloats = True - break - exc = guardtok.exc - target = self.failure_recovery_code[exc + 2 * withfloats] - fail_descr = cast_instance_to_gcref(guardtok.faildescr) - fail_descr = rffi.cast(lltype.Signed, fail_descr) - base_ofs = self.cpu.get_baseofs_of_frame_field() - positions = [0] * len(guardtok.fail_locs) - for i, loc in enumerate(guardtok.fail_locs): - if loc is None: - positions[i] = -1 - elif isinstance(loc, StackLoc): - positions[i] = loc.value - base_ofs - else: - assert isinstance(loc, RegLoc) - assert loc is not ebp # for now - if IS_X86_64: - coeff = 1 - else: - coeff = 2 - if loc.is_xmm: - v = len(gpr_reg_mgr_cls.all_regs) + loc.value * coeff - else: - v = gpr_reg_mgr_cls.all_reg_indexes[loc.value] - positions[i] = v * WORD - # write down the positions of locs - guardtok.faildescr.rd_locs = positions - # we want the descr to keep alive - guardtok.faildescr.rd_loop_token = self.current_clt - #if WORD == 4: - # mc.PUSH(imm(fail_descr)) - # mc.PUSH(imm(gcpattern)) - # mc.JMP(imm(target)) - #else: - mc.PUSH(imm(fail_descr)) - self.push_gcmap(mc, guardtok.gcmap, push=True) - mc.JMP(imm(target)) + startpos = self.mc.get_relative_pos() + fail_descr, target = self.store_info_on_descr(startpos, guardtok) + self.mc.PUSH(imm(fail_descr)) + self.push_gcmap(self.mc, guardtok.gcmap, push=True) + self.mc.JMP(imm(target)) return startpos def push_gcmap(self, mc, gcmap, push=False, mov=False, store=False): diff --git a/rpython/jit/backend/x86/runner.py b/rpython/jit/backend/x86/runner.py --- a/rpython/jit/backend/x86/runner.py +++ b/rpython/jit/backend/x86/runner.py @@ -21,6 +21,7 @@ dont_keepalive_stuff = False # for tests with_threads = False + frame_reg = regloc.ebp from rpython.jit.backend.x86.arch import JITFRAME_FIXED_SIZE all_reg_indexes = gpr_reg_mgr_cls.all_reg_indexes From noreply at buildbot.pypy.org Wed Feb 13 22:02:25 2013 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 13 Feb 2013 22:02:25 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: we don't use all the other regs Message-ID: <20130213210225.473BD1C3C21@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61190:8f9f3ad92893 Date: 2013-02-13 23:01 +0200 http://bitbucket.org/pypy/pypy/changeset/8f9f3ad92893/ Log: we don't use all the other regs diff --git a/rpython/jit/backend/arm/runner.py b/rpython/jit/backend/arm/runner.py --- a/rpython/jit/backend/arm/runner.py +++ b/rpython/jit/backend/arm/runner.py @@ -21,7 +21,7 @@ from rpython.jit.backend.arm.arch import JITFRAME_FIXED_SIZE all_reg_indexes = all_regs - gen_regs = CoreRegisterManager.all_regs + gen_regs = all_regs float_regs = VFPRegisterManager.all_regs frame_reg = fp From noreply at buildbot.pypy.org Wed Feb 13 22:09:28 2013 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 13 Feb 2013 22:09:28 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: We only store 11 registers Message-ID: <20130213210928.381991C01A7@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61191:3ad399d9067c Date: 2013-02-13 23:08 +0200 http://bitbucket.org/pypy/pypy/changeset/3ad399d9067c/ Log: We only store 11 registers diff --git a/rpython/jit/backend/arm/arch.py b/rpython/jit/backend/arm/arch.py --- a/rpython/jit/backend/arm/arch.py +++ b/rpython/jit/backend/arm/arch.py @@ -17,4 +17,4 @@ # A jitframe is a jit.backend.llsupport.llmodel.jitframe.JITFRAME # Stack frame fixed area # Currently only the force_index -JITFRAME_FIXED_SIZE = 16 + 16 * 2 # 16 GPR + 16 VFP Regs (64bit) +JITFRAME_FIXED_SIZE = 11 + 16 * 2 # 11 GPR + 16 VFP Regs (64bit) diff --git a/rpython/jit/backend/arm/regalloc.py b/rpython/jit/backend/arm/regalloc.py --- a/rpython/jit/backend/arm/regalloc.py +++ b/rpython/jit/backend/arm/regalloc.py @@ -142,18 +142,6 @@ no_lower_byte_regs = all_regs save_around_call_regs = r.caller_resp - REGLOC_TO_COPY_AREA_OFS = { - r.r2: MY_COPY_OF_REGS + 0 * WORD, - r.r3: MY_COPY_OF_REGS + 1 * WORD, - r.r4: MY_COPY_OF_REGS + 2 * WORD, - r.r5: MY_COPY_OF_REGS + 3 * WORD, - r.r6: MY_COPY_OF_REGS + 4 * WORD, - r.r7: MY_COPY_OF_REGS + 5 * WORD, - r.r8: MY_COPY_OF_REGS + 6 * WORD, - r.r9: MY_COPY_OF_REGS + 7 * WORD, - r.r10: MY_COPY_OF_REGS + 8 * WORD, - } - def __init__(self, longevity, frame_manager=None, assembler=None): RegisterManager.__init__(self, longevity, frame_manager, assembler) From noreply at buildbot.pypy.org Wed Feb 13 22:14:21 2013 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 13 Feb 2013 22:14:21 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: fix? Message-ID: <20130213211421.D7F921C3C21@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61192:d42e121a3bce Date: 2013-02-13 23:13 +0200 http://bitbucket.org/pypy/pypy/changeset/d42e121a3bce/ Log: fix? diff --git a/rpython/jit/backend/arm/assembler.py b/rpython/jit/backend/arm/assembler.py --- a/rpython/jit/backend/arm/assembler.py +++ b/rpython/jit/backend/arm/assembler.py @@ -707,7 +707,8 @@ return AsmInfo(ops_offset, startpos + rawstart, codeendpos - startpos) def new_stack_loc(self, i, pos, tp): - return StackLocation(i, pos, tp) + base_ofs = self.cpu.get_baseofs_of_frame_field() + return StackLocation(i, pos + base_ofs, tp) def check_frame_before_jump(self, target_token): if target_token in self.target_tokens_currently_compiling: From noreply at buildbot.pypy.org Wed Feb 13 22:17:56 2013 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 13 Feb 2013 22:17:56 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: provide is_float on arm locations Message-ID: <20130213211756.1A0591C3C29@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61193:ed34ec8baf40 Date: 2013-02-13 23:17 +0200 http://bitbucket.org/pypy/pypy/changeset/ed34ec8baf40/ Log: provide is_float on arm locations diff --git a/rpython/jit/backend/arm/locations.py b/rpython/jit/backend/arm/locations.py --- a/rpython/jit/backend/arm/locations.py +++ b/rpython/jit/backend/arm/locations.py @@ -21,6 +21,9 @@ def is_imm_float(self): return False + def is_float(self): + return False + def as_key(self): raise NotImplementedError @@ -65,6 +68,9 @@ def as_key(self): return self.value + 20 + def is_float(self): + return True + class ImmLocation(AssemblerLocation): _immutable_ = True @@ -105,6 +111,8 @@ def as_key(self): return self.value + def is_float(self): + return True class StackLocation(AssemblerLocation): _immutable_ = True @@ -136,6 +144,9 @@ def as_key(self): return self.position + 10000 + def is_float(self): + return type == FLOAT + def imm(i): return ImmLocation(i) From noreply at buildbot.pypy.org Wed Feb 13 22:19:58 2013 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 13 Feb 2013 22:19:58 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: oops Message-ID: <20130213211958.876A51C3C2D@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61194:b456a6001990 Date: 2013-02-13 23:19 +0200 http://bitbucket.org/pypy/pypy/changeset/b456a6001990/ Log: oops diff --git a/rpython/jit/backend/arm/runner.py b/rpython/jit/backend/arm/runner.py --- a/rpython/jit/backend/arm/runner.py +++ b/rpython/jit/backend/arm/runner.py @@ -20,7 +20,7 @@ supports_singlefloats = True from rpython.jit.backend.arm.arch import JITFRAME_FIXED_SIZE - all_reg_indexes = all_regs + all_reg_indexes = range(len(all_regs)) gen_regs = all_regs float_regs = VFPRegisterManager.all_regs frame_reg = fp From noreply at buildbot.pypy.org Wed Feb 13 22:24:54 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Wed, 13 Feb 2013 22:24:54 +0100 (CET) Subject: [pypy-commit] pypy py3k: Fix and test for the array module: accept all objects implementing the buffer interface where previously only bytes were accepted. Message-ID: <20130213212454.9A49E1C3C2E@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: py3k Changeset: r61195:4eaf46aa0ce4 Date: 2013-02-12 02:23 +0100 http://bitbucket.org/pypy/pypy/changeset/4eaf46aa0ce4/ Log: Fix and test for the array module: accept all objects implementing the buffer interface where previously only bytes were accepted. diff --git a/pypy/module/array/interp_array.py b/pypy/module/array/interp_array.py --- a/pypy/module/array/interp_array.py +++ b/pypy/module/array/interp_array.py @@ -38,8 +38,11 @@ if len(__args__.arguments_w) > 0: w_initializer = __args__.arguments_w[0] - if space.type(w_initializer) is space.w_bytes: - a.fromstring(space.bytes_w(w_initializer)) + if space.lookup(w_initializer, '__buffer__') is not None: + if isinstance(w_initializer, W_ArrayBase): + a.extend(w_initializer, True) + else: + a.fromstring(space.bufferstr_w(w_initializer)) elif space.type(w_initializer) is space.w_list: a.fromlist(w_initializer) else: @@ -569,7 +572,7 @@ self.fromlist(w_lst) def array_frombytes__Array_ANY(space, self, w_s): - self.fromstring(space.bytes_w(w_s)) + self.fromstring(space.bufferstr_w(w_s)) def array_fromstring__Array_ANY(space, self, w_s): space.warn("fromstring() is deprecated. Use frombytes() instead.", diff --git a/pypy/module/array/test/test_array.py b/pypy/module/array/test/test_array.py --- a/pypy/module/array/test/test_array.py +++ b/pypy/module/array/test/test_array.py @@ -848,6 +848,13 @@ assert l assert l[0] is None or len(l[0]) == 0 + def test_bytearray(self): + a = self.array('u', 'hi') + b = self.array('u') + b.frombytes(bytearray(a.tobytes())) + assert a == b + assert self.array('u', bytearray(a.tobytes())) == a + class DontTestCPythonsOwnArray(BaseArrayTests): From noreply at buildbot.pypy.org Wed Feb 13 22:24:56 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Wed, 13 Feb 2013 22:24:56 +0100 (CET) Subject: [pypy-commit] pypy py3k: Don't check how many warnings are emitted for array.{from, to}string(). Message-ID: <20130213212456.41CDE1C3C2E@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: py3k Changeset: r61196:039b56a3d65b Date: 2013-02-12 15:26 +0100 http://bitbucket.org/pypy/pypy/changeset/039b56a3d65b/ Log: Don't check how many warnings are emitted for array.{from,to}string(). diff --git a/lib-python/3.2/test/test_array.py b/lib-python/3.2/test/test_array.py --- a/lib-python/3.2/test/test_array.py +++ b/lib-python/3.2/test/test_array.py @@ -383,7 +383,10 @@ if a.itemsize>1: self.assertRaises(ValueError, b.fromstring, "x") nb_warnings += 1 - self.assertEqual(len(r), nb_warnings) + if support.check_impl_detail(): + # PyPy's multimethod dispatch is different from CPython's + # on CPython the warning is emitted before checking the arguments + self.assertEqual(len(r), nb_warnings) def test_tofrombytes(self): a = array.array(self.typecode, 2*self.example) From noreply at buildbot.pypy.org Wed Feb 13 22:24:57 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Wed, 13 Feb 2013 22:24:57 +0100 (CET) Subject: [pypy-commit] pypy py3k: Use unicode when formatting array's repr. Message-ID: <20130213212457.8FF081C3C2E@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: py3k Changeset: r61197:78f184ffa771 Date: 2013-02-12 16:58 +0100 http://bitbucket.org/pypy/pypy/changeset/78f184ffa771/ Log: Use unicode when formatting array's repr. diff --git a/pypy/module/array/interp_array.py b/pypy/module/array/interp_array.py --- a/pypy/module/array/interp_array.py +++ b/pypy/module/array/interp_array.py @@ -741,7 +741,7 @@ return space.wrap("array('%s')" % self.typecode) elif self.typecode == "u": r = space.repr(array_tounicode__Array(space, self)) - s = "array('%s', %s)" % (self.typecode, space.str_w(r)) + s = u"array('%s', %s)" % (self.typecode, space.unicode_w(r)) return space.wrap(s) else: r = space.repr(array_tolist__Array(space, self)) diff --git a/pypy/module/array/test/test_array.py b/pypy/module/array/test/test_array.py --- a/pypy/module/array/test/test_array.py +++ b/pypy/module/array/test/test_array.py @@ -855,6 +855,12 @@ assert a == b assert self.array('u', bytearray(a.tobytes())) == a + def test_repr(self): + s = '\x00="\'a\\b\x80\xff\u0000\u0001\u1234' + a = self.array('u', s) + assert repr(a) == "array('u', {!r})".format(s) + assert eval(repr(a), {'array': self.array}) == a + class DontTestCPythonsOwnArray(BaseArrayTests): From noreply at buildbot.pypy.org Wed Feb 13 22:24:58 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Wed, 13 Feb 2013 22:24:58 +0100 (CET) Subject: [pypy-commit] pypy py3k: Port implementation-dependent skips in test_bytes from 2.7 test suite to 3.2. Message-ID: <20130213212458.D25821C3C2E@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: py3k Changeset: r61198:eb20b02bd057 Date: 2013-02-12 17:13 +0100 http://bitbucket.org/pypy/pypy/changeset/eb20b02bd057/ Log: Port implementation-dependent skips in test_bytes from 2.7 test suite to 3.2. diff --git a/lib-python/3.2/test/test_bytes.py b/lib-python/3.2/test/test_bytes.py --- a/lib-python/3.2/test/test_bytes.py +++ b/lib-python/3.2/test/test_bytes.py @@ -764,6 +764,7 @@ self.assertEqual(b, b1) self.assertTrue(b is b1) + @test.support.impl_detail("undocumented bytes.__alloc__()") def test_alloc(self): b = bytearray() alloc = b.__alloc__() @@ -890,6 +891,8 @@ self.assertEqual(b, b"") self.assertEqual(c, b"") + @test.support.impl_detail( + "resizing semantics of CPython rely on refcounting") def test_resize_forbidden(self): # #4509: can't resize a bytearray when there are buffer exports, even # if it wouldn't reallocate the underlying buffer. @@ -922,6 +925,26 @@ self.assertRaises(BufferError, delslice) self.assertEqual(b, orig) + @test.support.impl_detail("resizing semantics", cpython=False) + def test_resize_forbidden_non_cpython(self): + # on non-CPython implementations, we cannot prevent changes to + # bytearrays just because there are buffers around. Instead, + # we get (on PyPy) a buffer that follows the changes and resizes. + b = bytearray(range(10)) + for v in [memoryview(b), buffer(b)]: + b[5] = 99 + self.assertIn(v[5], (99, chr(99))) + b[5] = 100 + b += b + b += b + b += b + self.assertEquals(len(v), 80) + self.assertIn(v[5], (100, chr(100))) + self.assertIn(v[79], (9, chr(9))) + del b[10:] + self.assertRaises(IndexError, lambda: v[10]) + self.assertEquals(len(v), 10) + class AssortedBytesTest(unittest.TestCase): # From noreply at buildbot.pypy.org Wed Feb 13 22:25:00 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Wed, 13 Feb 2013 22:25:00 +0100 (CET) Subject: [pypy-commit] pypy py3k: Change test_resize_forbidden_non_cpython to work on python 3. Message-ID: <20130213212500.2CDF41C3C2E@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: py3k Changeset: r61199:5e51cdf17291 Date: 2013-02-12 17:28 +0100 http://bitbucket.org/pypy/pypy/changeset/5e51cdf17291/ Log: Change test_resize_forbidden_non_cpython to work on python 3. diff --git a/lib-python/3.2/test/test_bytes.py b/lib-python/3.2/test/test_bytes.py --- a/lib-python/3.2/test/test_bytes.py +++ b/lib-python/3.2/test/test_bytes.py @@ -931,19 +931,19 @@ # bytearrays just because there are buffers around. Instead, # we get (on PyPy) a buffer that follows the changes and resizes. b = bytearray(range(10)) - for v in [memoryview(b), buffer(b)]: - b[5] = 99 - self.assertIn(v[5], (99, chr(99))) - b[5] = 100 - b += b - b += b - b += b - self.assertEquals(len(v), 80) - self.assertIn(v[5], (100, chr(100))) - self.assertIn(v[79], (9, chr(9))) - del b[10:] - self.assertRaises(IndexError, lambda: v[10]) - self.assertEquals(len(v), 10) + v = memoryview(b) + b[5] = 99 + self.assertIn(v[5], (99, bytes([99]))) + b[5] = 100 + b += b + b += b + b += b + self.assertEquals(len(v), 80) + self.assertIn(v[5], (100, bytes([100]))) + self.assertIn(v[79], (9, bytes([9]))) + del b[10:] + self.assertRaises(IndexError, lambda: v[10]) + self.assertEquals(len(v), 10) class AssortedBytesTest(unittest.TestCase): From noreply at buildbot.pypy.org Wed Feb 13 22:25:01 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Wed, 13 Feb 2013 22:25:01 +0100 (CET) Subject: [pypy-commit] pypy py3k: Skip test in test_bytes which tests CPython's C API. Message-ID: <20130213212501.767B21C3C2E@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: py3k Changeset: r61200:831f232a0160 Date: 2013-02-12 17:32 +0100 http://bitbucket.org/pypy/pypy/changeset/831f232a0160/ Log: Skip test in test_bytes which tests CPython's C API. diff --git a/lib-python/3.2/test/test_bytes.py b/lib-python/3.2/test/test_bytes.py --- a/lib-python/3.2/test/test_bytes.py +++ b/lib-python/3.2/test/test_bytes.py @@ -570,6 +570,7 @@ self.assertRaises(TypeError, bytes, A()) # Test PyBytes_FromFormat() + @test.support.impl_detail("don't test cpyext here") def test_from_format(self): test.support.import_module('ctypes') from ctypes import pythonapi, py_object, c_int, c_char_p From noreply at buildbot.pypy.org Wed Feb 13 22:25:02 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Wed, 13 Feb 2013 22:25:02 +0100 (CET) Subject: [pypy-commit] pypy py3k: Comparing reflexive dicts raises RuntimeError on PyPy. Message-ID: <20130213212502.D1E561C3C2E@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: py3k Changeset: r61201:8e728e74ca71 Date: 2013-02-12 17:57 +0100 http://bitbucket.org/pypy/pypy/changeset/8e728e74ca71/ Log: Comparing reflexive dicts raises RuntimeError on PyPy. diff --git a/lib-python/3.2/test/test_copy.py b/lib-python/3.2/test/test_copy.py --- a/lib-python/3.2/test/test_copy.py +++ b/lib-python/3.2/test/test_copy.py @@ -311,8 +311,14 @@ x = {} x['foo'] = x y = copy.deepcopy(x) - for op in order_comparisons: - self.assertRaises(TypeError, op, y, x) + if support.check_impl_detail(): + for op in order_comparisons: + self.assertRaises(TypeError, op, y, x) + else: + # this is an implementation detail + # equality comparisons raise RuntimeError on CPython, too + for op in order_comparisons: + self.assertRaises(RuntimeError, op, y, x) for op in equality_comparisons: self.assertRaises(RuntimeError, op, y, x) self.assertTrue(y is not x) From noreply at buildbot.pypy.org Wed Feb 13 22:25:04 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Wed, 13 Feb 2013 22:25:04 +0100 (CET) Subject: [pypy-commit] pypy py3k: merge upstream Message-ID: <20130213212504.546281C3C2E@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: py3k Changeset: r61202:be9716c1d767 Date: 2013-02-13 11:44 +0100 http://bitbucket.org/pypy/pypy/changeset/be9716c1d767/ Log: merge upstream diff --git a/pypy/interpreter/astcompiler/test/test_compiler.py b/pypy/interpreter/astcompiler/test/test_compiler.py --- a/pypy/interpreter/astcompiler/test/test_compiler.py +++ b/pypy/interpreter/astcompiler/test/test_compiler.py @@ -668,8 +668,8 @@ #cmp self.assert_(p == p) self.assert_(d == d) - self.assert_(p < d) - self.assert_(d > p) + self.failUnlessRaises(TypeError, lambda: p < d) + self.failUnlessRaises(TypeError, lambda: d > p) #__non__zero__ if p: self.fail("Empty mapping must compare to False") if not d: self.fail("Full mapping must compare to True") diff --git a/pypy/module/imp/test/test_import.py b/pypy/module/imp/test/test_import.py --- a/pypy/module/imp/test/test_import.py +++ b/pypy/module/imp/test/test_import.py @@ -1094,12 +1094,6 @@ (mydir): import sys sys.path.append(mydir) - - # Obscure: manually bootstrap the utf-8 codec for - # TextIOs opened by imp.find_module. It's not otherwise - # loaded by the test infrastructure but would have been - # in any other situation - import encodings.utf_8 """) def teardown_class(cls): diff --git a/pypy/objspace/std/dictmultiobject.py b/pypy/objspace/std/dictmultiobject.py --- a/pypy/objspace/std/dictmultiobject.py +++ b/pypy/objspace/std/dictmultiobject.py @@ -862,49 +862,6 @@ return space.w_False return space.w_True -def characterize(space, w_a, w_b): - """ (similar to CPython) - returns the smallest key in acontent for which b's value is different or absent and this value """ - w_smallest_diff_a_key = None - w_its_value = None - iteratorimplementation = w_a.iteritems() - while 1: - w_key, w_val = iteratorimplementation.next_item() - if w_key is None: - break - if w_smallest_diff_a_key is None or space.is_true(space.lt(w_key, w_smallest_diff_a_key)): - w_bvalue = w_b.getitem(w_key) - if w_bvalue is None: - w_its_value = w_val - w_smallest_diff_a_key = w_key - else: - if not space.eq_w(w_val, w_bvalue): - w_its_value = w_val - w_smallest_diff_a_key = w_key - return w_smallest_diff_a_key, w_its_value - -def lt__DictMulti_DictMulti(space, w_left, w_right): - # Different sizes, no problem - if w_left.length() < w_right.length(): - return space.w_True - if w_left.length() > w_right.length(): - return space.w_False - - # Same size - w_leftdiff, w_leftval = characterize(space, w_left, w_right) - if w_leftdiff is None: - return space.w_False - w_rightdiff, w_rightval = characterize(space, w_right, w_left) - if w_rightdiff is None: - # w_leftdiff is not None, w_rightdiff is None - return space.w_True - w_res = space.lt(w_leftdiff, w_rightdiff) - if (not space.is_true(w_res) and - space.eq_w(w_leftdiff, w_rightdiff) and - w_rightval is not None): - w_res = space.lt(w_leftval, w_rightval) - return w_res - def dict_copy__DictMulti(space, w_self): w_new = W_DictMultiObject.allocate_and_init_instance(space) update1_dict_dict(space, w_new, w_self) diff --git a/pypy/objspace/std/test/test_dictmultiobject.py b/pypy/objspace/std/test/test_dictmultiobject.py --- a/pypy/objspace/std/test/test_dictmultiobject.py +++ b/pypy/objspace/std/test/test_dictmultiobject.py @@ -387,27 +387,13 @@ bool = d1 != d3 assert bool == True - def test_lt(self): + def test_richcompare(self): + import operator d1 = {1: 2, 3: 4} - d2 = {1: 2, 3: 4} - d3 = {1: 2, 3: 5} - d4 = {1: 2} - bool = d1 < d2 - assert bool == False - bool = d1 < d3 - assert bool == True - bool = d1 < d4 - assert bool == False - - def test_lt2(self): - assert {'a': 1 } < { 'a': 2 } - assert not {'a': 1 } > { 'a': 2 } - assert not {'a': 1, 'b': 0 } > { 'a': 2, 'b': 0 } - assert {'a': 1, 'b': 0 } < { 'a': 2, 'b': 0 } - assert {'a': 1, 'b': 0 } < { 'a': 1, 'b': 2 } - assert not {'a': 1, 'b': 0 } < { 'a': 1, 'b': -2 } - assert {'a': 1 } < { 'b': 1} - assert {'a': 1, 'x': 2 } < { 'b': 1, 'x': 2} + d2 = {1: 2, 3: 5} + for op in 'lt', 'le', 'gt', 'ge': + f = getattr(operator, op) + raises(TypeError, f, d1, d2) def test_str_repr(self): assert '{}' == str({}) diff --git a/pypy/tool/pytest/run-script/regrverbose.py b/pypy/tool/pytest/run-script/regrverbose.py --- a/pypy/tool/pytest/run-script/regrverbose.py +++ b/pypy/tool/pytest/run-script/regrverbose.py @@ -8,10 +8,10 @@ modname = sys.argv[0] impname = 'test.' + modname try: + regrtest.replace_stdout() mod = __import__(impname, globals(), locals(), [modname]) indirect_test = getattr(mod, 'test_main', None) if indirect_test is not None: - regrtest.replace_stdout() indirect_test() except unittest.SkipTest: sys.stderr.write("="*26 + "skipped" + "="*26 + "\n") From noreply at buildbot.pypy.org Wed Feb 13 22:25:05 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Wed, 13 Feb 2013 22:25:05 +0100 (CET) Subject: [pypy-commit] pypy py3k: Fix translation. Message-ID: <20130213212505.987CD1C3C2E@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: py3k Changeset: r61203:2ced77b5acae Date: 2013-02-13 11:59 +0100 http://bitbucket.org/pypy/pypy/changeset/2ced77b5acae/ Log: Fix translation. diff --git a/pypy/module/array/interp_array.py b/pypy/module/array/interp_array.py --- a/pypy/module/array/interp_array.py +++ b/pypy/module/array/interp_array.py @@ -741,7 +741,7 @@ return space.wrap("array('%s')" % self.typecode) elif self.typecode == "u": r = space.repr(array_tounicode__Array(space, self)) - s = u"array('%s', %s)" % (self.typecode, space.unicode_w(r)) + s = u"array('u', %s)" % space.unicode_w(r) return space.wrap(s) else: r = space.repr(array_tolist__Array(space, self)) From noreply at buildbot.pypy.org Wed Feb 13 22:25:06 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Wed, 13 Feb 2013 22:25:06 +0100 (CET) Subject: [pypy-commit] pypy py3k: Port some changes in test_csv.py from 2.7 to 3.2. Message-ID: <20130213212506.D83A81C3C2E@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: py3k Changeset: r61204:c9147dcf3e21 Date: 2013-02-13 12:13 +0100 http://bitbucket.org/pypy/pypy/changeset/c9147dcf3e21/ Log: Port some changes in test_csv.py from 2.7 to 3.2. diff --git a/lib-python/3.2/test/test_csv.py b/lib-python/3.2/test/test_csv.py --- a/lib-python/3.2/test/test_csv.py +++ b/lib-python/3.2/test/test_csv.py @@ -19,7 +19,8 @@ """ def _test_arg_valid(self, ctor, arg): self.assertRaises(TypeError, ctor) - self.assertRaises(TypeError, ctor, None) + # PyPy gets an AttributeError instead of a TypeError + self.assertRaises((TypeError, AttributeError), ctor, None) self.assertRaises(TypeError, ctor, arg, bad_attr = 0) self.assertRaises(TypeError, ctor, arg, delimiter = 0) self.assertRaises(TypeError, ctor, arg, delimiter = 'XX') @@ -125,7 +126,8 @@ expect + writer.dialect.lineterminator) def test_write_arg_valid(self): - self.assertRaises(csv.Error, self._write_test, None, '') + # PyPy gets a TypeError instead of a csv.Error for "not a sequence" + self.assertRaises((csv.Error, TypeError), self._write_test, None, '') self._write_test((), '') self._write_test([None], '""') self.assertRaises(csv.Error, self._write_test, From noreply at buildbot.pypy.org Wed Feb 13 22:25:08 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Wed, 13 Feb 2013 22:25:08 +0100 (CET) Subject: [pypy-commit] pypy py3k: PyPy raises a TypeError here. Message-ID: <20130213212508.193B91C3C2E@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: py3k Changeset: r61205:2b675b2b2193 Date: 2013-02-13 12:15 +0100 http://bitbucket.org/pypy/pypy/changeset/2b675b2b2193/ Log: PyPy raises a TypeError here. diff --git a/lib-python/3.2/test/test_csv.py b/lib-python/3.2/test/test_csv.py --- a/lib-python/3.2/test/test_csv.py +++ b/lib-python/3.2/test/test_csv.py @@ -214,7 +214,8 @@ ['ab\0c'], None, strict = 1) self._read_test(['"ab"c'], [['abc']], doublequote = 0) - self.assertRaises(csv.Error, self._read_test, + # PyPy gets a TypeError instead of a csv.Error for bytes input + self.assertRaises((csv.Error, TypeError), self._read_test, [b'ab\0c'], None) From noreply at buildbot.pypy.org Wed Feb 13 22:25:09 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Wed, 13 Feb 2013 22:25:09 +0100 (CET) Subject: [pypy-commit] pypy py3k: Skip this check in the 3.2 test suite, too. Message-ID: <20130213212509.5DFF71C3C2E@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: py3k Changeset: r61206:ef43e3c73141 Date: 2013-02-13 13:19 +0100 http://bitbucket.org/pypy/pypy/changeset/ef43e3c73141/ Log: Skip this check in the 3.2 test suite, too. diff --git a/lib-python/3.2/test/test_dict.py b/lib-python/3.2/test/test_dict.py --- a/lib-python/3.2/test/test_dict.py +++ b/lib-python/3.2/test/test_dict.py @@ -319,7 +319,8 @@ self.assertEqual(va, int(ka)) kb, vb = tb = b.popitem() self.assertEqual(vb, int(kb)) - self.assertFalse(copymode < 0 and ta != tb) + if test_support.check_impl_detail(): + self.assertFalse(copymode < 0 and ta != tb) self.assertFalse(a) self.assertFalse(b) From noreply at buildbot.pypy.org Wed Feb 13 22:25:10 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Wed, 13 Feb 2013 22:25:10 +0100 (CET) Subject: [pypy-commit] pypy py3k: Port some gc.collect()s to test_generators in 3.2 test suite. Message-ID: <20130213212510.911AC1C3C2E@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: py3k Changeset: r61207:242725f91070 Date: 2013-02-13 13:33 +0100 http://bitbucket.org/pypy/pypy/changeset/242725f91070/ Log: Port some gc.collect()s to test_generators in 3.2 test suite. diff --git a/lib-python/3.2/test/test_generators.py b/lib-python/3.2/test/test_generators.py --- a/lib-python/3.2/test/test_generators.py +++ b/lib-python/3.2/test/test_generators.py @@ -1496,6 +1496,10 @@ """ coroutine_tests = """\ +A helper function to call gc.collect() without printing +>>> import gc +>>> def gc_collect(): gc.collect() + Sending a value into a started generator: >>> def f(): @@ -1729,7 +1733,7 @@ >>> g = f() >>> next(g) ->>> del g +>>> del g; gc_collect() exiting @@ -1744,7 +1748,7 @@ >>> g = f() >>> next(g) ->>> del g +>>> del g; gc_collect() finally @@ -1770,6 +1774,7 @@ >>> g = f() >>> next(g) >>> del g +>>> gc_collect() >>> sys.stderr.getvalue().startswith( ... "Exception RuntimeError: 'generator ignored GeneratorExit' in " ... ) @@ -1835,6 +1840,9 @@ references. We add it to the standard suite so the routine refleak-tests would trigger if it starts being uncleanable again. +>>> import gc +>>> def gc_collect(): gc.collect() + >>> import itertools >>> def leak(): ... class gen: @@ -1886,6 +1894,7 @@ ... ... l = Leaker() ... del l +... gc_collect() ... err = sys.stderr.getvalue().strip() ... err.startswith( ... "Exception RuntimeError: RuntimeError() in <" From noreply at buildbot.pypy.org Wed Feb 13 22:25:11 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Wed, 13 Feb 2013 22:25:11 +0100 (CET) Subject: [pypy-commit] pypy py3k: Port another change to test_generators in 3.2 test suite. Message-ID: <20130213212511.C4E3E1C3C2E@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: py3k Changeset: r61208:cf03320edfe5 Date: 2013-02-13 13:38 +0100 http://bitbucket.org/pypy/pypy/changeset/cf03320edfe5/ Log: Port another change to test_generators in 3.2 test suite. diff --git a/lib-python/3.2/test/test_generators.py b/lib-python/3.2/test/test_generators.py --- a/lib-python/3.2/test/test_generators.py +++ b/lib-python/3.2/test/test_generators.py @@ -1897,7 +1897,7 @@ ... gc_collect() ... err = sys.stderr.getvalue().strip() ... err.startswith( -... "Exception RuntimeError: RuntimeError() in <" +... "Exception RuntimeError: RuntimeError() in " ... ) ... err.endswith("> ignored") ... len(err.splitlines()) From noreply at buildbot.pypy.org Wed Feb 13 22:25:13 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Wed, 13 Feb 2013 22:25:13 +0100 (CET) Subject: [pypy-commit] pypy py3k: Port implementation-dependent skip to test_mutants in 3.2 test suite. Message-ID: <20130213212513.0FBB61C3C2E@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: py3k Changeset: r61209:84e5cc18568c Date: 2013-02-13 14:07 +0100 http://bitbucket.org/pypy/pypy/changeset/84e5cc18568c/ Log: Port implementation-dependent skip to test_mutants in 3.2 test suite. diff --git a/lib-python/3.2/test/test_mutants.py b/lib-python/3.2/test/test_mutants.py --- a/lib-python/3.2/test/test_mutants.py +++ b/lib-python/3.2/test/test_mutants.py @@ -1,4 +1,4 @@ -from test.support import verbose, TESTFN +from test.support import verbose, TESTFN, check_impl_detail import random import os @@ -139,7 +139,13 @@ while dict1 and len(dict1) == len(dict2): if verbose: print(".", end=' ') - c = dict1 == dict2 + try: + c = dict1 == dict2 + except RuntimeError: + # CPython never raises RuntimeError here, but other implementations + # might, and it's fine. + if check_impl_detail(cpython=True): + raise if verbose: print() From noreply at buildbot.pypy.org Wed Feb 13 22:25:14 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Wed, 13 Feb 2013 22:25:14 +0100 (CET) Subject: [pypy-commit] pypy py3k: Skip test_attribute_name_interning() in 3.2 test suite, too. Message-ID: <20130213212514.63C4E1C3C2E@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: py3k Changeset: r61210:975377190519 Date: 2013-02-13 14:17 +0100 http://bitbucket.org/pypy/pypy/changeset/975377190519/ Log: Skip test_attribute_name_interning() in 3.2 test suite, too. diff --git a/lib-python/3.2/test/pickletester.py b/lib-python/3.2/test/pickletester.py --- a/lib-python/3.2/test/pickletester.py +++ b/lib-python/3.2/test/pickletester.py @@ -8,7 +8,7 @@ from test.support import ( TestFailed, TESTFN, run_with_locale, - _2G, _4G, bigmemtest, + _2G, _4G, bigmemtest, impl_detail ) from pickle import bytes_types @@ -1080,6 +1080,7 @@ "Failed protocol %d: %r != %r" % (proto, obj, loaded)) + @impl_detail("pypy does not store attribute names", pypy=False) def test_attribute_name_interning(self): # Test that attribute names of pickled objects are interned when # unpickling. From noreply at buildbot.pypy.org Wed Feb 13 22:25:15 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Wed, 13 Feb 2013 22:25:15 +0100 (CET) Subject: [pypy-commit] pypy py3k: Port some PyPy-related changes to 3.2's test_socket. Message-ID: <20130213212515.BA89C1C3C2E@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: py3k Changeset: r61211:bb99cdea73f6 Date: 2013-02-13 14:37 +0100 http://bitbucket.org/pypy/pypy/changeset/bb99cdea73f6/ Log: Port some PyPy-related changes to 3.2's test_socket. diff --git a/lib-python/3.2/test/test_socket.py b/lib-python/3.2/test/test_socket.py --- a/lib-python/3.2/test/test_socket.py +++ b/lib-python/3.2/test/test_socket.py @@ -313,7 +313,7 @@ "'complex' does not support the buffer interface") with self.assertRaises(TypeError) as cm: s.sendto(b'foo', None) - self.assertIn('not NoneType',str(cm.exception)) + self.assertIn('NoneType', str(cm.exception)) # 3 args with self.assertRaises(TypeError) as cm: s.sendto('\u2620', 0, sockname) @@ -325,20 +325,22 @@ "'complex' does not support the buffer interface") with self.assertRaises(TypeError) as cm: s.sendto(b'foo', 0, None) - self.assertIn('not NoneType', str(cm.exception)) + if support.check_impl_detail(): + self.assertIn('not NoneType', str(cm.exception)) with self.assertRaises(TypeError) as cm: s.sendto(b'foo', 'bar', sockname) - self.assertIn('an integer is required', str(cm.exception)) + self.assertIn('integer', str(cm.exception)) with self.assertRaises(TypeError) as cm: s.sendto(b'foo', None, None) - self.assertIn('an integer is required', str(cm.exception)) + if support.check_impl_detail(): + self.assertIn('an integer is required', str(cm.exception)) # wrong number of args with self.assertRaises(TypeError) as cm: s.sendto(b'foo') - self.assertIn('(1 given)', str(cm.exception)) + self.assertIn(' given)', str(cm.exception)) with self.assertRaises(TypeError) as cm: s.sendto(b'foo', 0, sockname, 4) - self.assertIn('(4 given)', str(cm.exception)) + self.assertIn(' given)', str(cm.exception)) def testCrucialConstants(self): # Testing for mission critical constants @@ -412,10 +414,10 @@ socket.htonl(k) socket.htons(k) for k in bad_values: - self.assertRaises(OverflowError, socket.ntohl, k) - self.assertRaises(OverflowError, socket.ntohs, k) - self.assertRaises(OverflowError, socket.htonl, k) - self.assertRaises(OverflowError, socket.htons, k) + self.assertRaises((OverflowError, ValueError), socket.ntohl, k) + self.assertRaises((OverflowError, ValueError), socket.ntohs, k) + self.assertRaises((OverflowError, ValueError), socket.htonl, k) + self.assertRaises((OverflowError, ValueError), socket.htons, k) def testGetServBy(self): eq = self.assertEqual @@ -455,8 +457,8 @@ if udpport is not None: eq(socket.getservbyport(udpport, 'udp'), service) # Make sure getservbyport does not accept out of range ports. - self.assertRaises(OverflowError, socket.getservbyport, -1) - self.assertRaises(OverflowError, socket.getservbyport, 65536) + self.assertRaises((OverflowError, ValueError), socket.getservbyport, -1) + self.assertRaises((OverflowError, ValueError), socket.getservbyport, 65536) def testDefaultTimeout(self): # Testing default timeout @@ -686,8 +688,8 @@ neg_port = port - 65536 sock = socket.socket() try: - self.assertRaises(OverflowError, sock.bind, (host, big_port)) - self.assertRaises(OverflowError, sock.bind, (host, neg_port)) + self.assertRaises((OverflowError, ValueError), sock.bind, (host, big_port)) + self.assertRaises((OverflowError, ValueError), sock.bind, (host, neg_port)) sock.bind((host, port)) finally: sock.close() @@ -1475,10 +1477,11 @@ self.write_file.flush() def testMakefileCloseSocketDestroy(self): - refcount_before = sys.getrefcount(self.cli_conn) - self.read_file.close() - refcount_after = sys.getrefcount(self.cli_conn) - self.assertEqual(refcount_before - 1, refcount_after) + if hasattr(sys, "getrefcount"): + refcount_before = sys.getrefcount(self.cli_conn) + self.read_file.close() + refcount_after = sys.getrefcount(self.cli_conn) + self.assertEqual(refcount_before - 1, refcount_after) def _testMakefileCloseSocketDestroy(self): pass From noreply at buildbot.pypy.org Wed Feb 13 22:25:17 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Wed, 13 Feb 2013 22:25:17 +0100 (CET) Subject: [pypy-commit] pypy py3k: Merged in mjacob/pypy/py3k (pull request #120) Message-ID: <20130213212517.1CE841C3C2E@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61212:7cbe47c4eb6b Date: 2013-02-13 13:24 -0800 http://bitbucket.org/pypy/pypy/changeset/7cbe47c4eb6b/ Log: Merged in mjacob/pypy/py3k (pull request #120) Random py3k fixes diff --git a/lib-python/3.2/test/pickletester.py b/lib-python/3.2/test/pickletester.py --- a/lib-python/3.2/test/pickletester.py +++ b/lib-python/3.2/test/pickletester.py @@ -8,7 +8,7 @@ from test.support import ( TestFailed, TESTFN, run_with_locale, - _2G, _4G, bigmemtest, + _2G, _4G, bigmemtest, impl_detail ) from pickle import bytes_types @@ -1080,6 +1080,7 @@ "Failed protocol %d: %r != %r" % (proto, obj, loaded)) + @impl_detail("pypy does not store attribute names", pypy=False) def test_attribute_name_interning(self): # Test that attribute names of pickled objects are interned when # unpickling. diff --git a/lib-python/3.2/test/test_array.py b/lib-python/3.2/test/test_array.py --- a/lib-python/3.2/test/test_array.py +++ b/lib-python/3.2/test/test_array.py @@ -383,7 +383,10 @@ if a.itemsize>1: self.assertRaises(ValueError, b.fromstring, "x") nb_warnings += 1 - self.assertEqual(len(r), nb_warnings) + if support.check_impl_detail(): + # PyPy's multimethod dispatch is different from CPython's + # on CPython the warning is emitted before checking the arguments + self.assertEqual(len(r), nb_warnings) def test_tofrombytes(self): a = array.array(self.typecode, 2*self.example) diff --git a/lib-python/3.2/test/test_bytes.py b/lib-python/3.2/test/test_bytes.py --- a/lib-python/3.2/test/test_bytes.py +++ b/lib-python/3.2/test/test_bytes.py @@ -570,6 +570,7 @@ self.assertRaises(TypeError, bytes, A()) # Test PyBytes_FromFormat() + @test.support.impl_detail("don't test cpyext here") def test_from_format(self): test.support.import_module('ctypes') from ctypes import pythonapi, py_object, c_int, c_char_p @@ -764,6 +765,7 @@ self.assertEqual(b, b1) self.assertTrue(b is b1) + @test.support.impl_detail("undocumented bytes.__alloc__()") def test_alloc(self): b = bytearray() alloc = b.__alloc__() @@ -890,6 +892,8 @@ self.assertEqual(b, b"") self.assertEqual(c, b"") + @test.support.impl_detail( + "resizing semantics of CPython rely on refcounting") def test_resize_forbidden(self): # #4509: can't resize a bytearray when there are buffer exports, even # if it wouldn't reallocate the underlying buffer. @@ -922,6 +926,26 @@ self.assertRaises(BufferError, delslice) self.assertEqual(b, orig) + @test.support.impl_detail("resizing semantics", cpython=False) + def test_resize_forbidden_non_cpython(self): + # on non-CPython implementations, we cannot prevent changes to + # bytearrays just because there are buffers around. Instead, + # we get (on PyPy) a buffer that follows the changes and resizes. + b = bytearray(range(10)) + v = memoryview(b) + b[5] = 99 + self.assertIn(v[5], (99, bytes([99]))) + b[5] = 100 + b += b + b += b + b += b + self.assertEquals(len(v), 80) + self.assertIn(v[5], (100, bytes([100]))) + self.assertIn(v[79], (9, bytes([9]))) + del b[10:] + self.assertRaises(IndexError, lambda: v[10]) + self.assertEquals(len(v), 10) + class AssortedBytesTest(unittest.TestCase): # diff --git a/lib-python/3.2/test/test_copy.py b/lib-python/3.2/test/test_copy.py --- a/lib-python/3.2/test/test_copy.py +++ b/lib-python/3.2/test/test_copy.py @@ -311,8 +311,14 @@ x = {} x['foo'] = x y = copy.deepcopy(x) - for op in order_comparisons: - self.assertRaises(TypeError, op, y, x) + if support.check_impl_detail(): + for op in order_comparisons: + self.assertRaises(TypeError, op, y, x) + else: + # this is an implementation detail + # equality comparisons raise RuntimeError on CPython, too + for op in order_comparisons: + self.assertRaises(RuntimeError, op, y, x) for op in equality_comparisons: self.assertRaises(RuntimeError, op, y, x) self.assertTrue(y is not x) diff --git a/lib-python/3.2/test/test_csv.py b/lib-python/3.2/test/test_csv.py --- a/lib-python/3.2/test/test_csv.py +++ b/lib-python/3.2/test/test_csv.py @@ -19,7 +19,8 @@ """ def _test_arg_valid(self, ctor, arg): self.assertRaises(TypeError, ctor) - self.assertRaises(TypeError, ctor, None) + # PyPy gets an AttributeError instead of a TypeError + self.assertRaises((TypeError, AttributeError), ctor, None) self.assertRaises(TypeError, ctor, arg, bad_attr = 0) self.assertRaises(TypeError, ctor, arg, delimiter = 0) self.assertRaises(TypeError, ctor, arg, delimiter = 'XX') @@ -125,7 +126,8 @@ expect + writer.dialect.lineterminator) def test_write_arg_valid(self): - self.assertRaises(csv.Error, self._write_test, None, '') + # PyPy gets a TypeError instead of a csv.Error for "not a sequence" + self.assertRaises((csv.Error, TypeError), self._write_test, None, '') self._write_test((), '') self._write_test([None], '""') self.assertRaises(csv.Error, self._write_test, @@ -212,7 +214,8 @@ ['ab\0c'], None, strict = 1) self._read_test(['"ab"c'], [['abc']], doublequote = 0) - self.assertRaises(csv.Error, self._read_test, + # PyPy gets a TypeError instead of a csv.Error for bytes input + self.assertRaises((csv.Error, TypeError), self._read_test, [b'ab\0c'], None) diff --git a/lib-python/3.2/test/test_dict.py b/lib-python/3.2/test/test_dict.py --- a/lib-python/3.2/test/test_dict.py +++ b/lib-python/3.2/test/test_dict.py @@ -319,7 +319,8 @@ self.assertEqual(va, int(ka)) kb, vb = tb = b.popitem() self.assertEqual(vb, int(kb)) - self.assertFalse(copymode < 0 and ta != tb) + if test_support.check_impl_detail(): + self.assertFalse(copymode < 0 and ta != tb) self.assertFalse(a) self.assertFalse(b) diff --git a/lib-python/3.2/test/test_generators.py b/lib-python/3.2/test/test_generators.py --- a/lib-python/3.2/test/test_generators.py +++ b/lib-python/3.2/test/test_generators.py @@ -1496,6 +1496,10 @@ """ coroutine_tests = """\ +A helper function to call gc.collect() without printing +>>> import gc +>>> def gc_collect(): gc.collect() + Sending a value into a started generator: >>> def f(): @@ -1729,7 +1733,7 @@ >>> g = f() >>> next(g) ->>> del g +>>> del g; gc_collect() exiting @@ -1744,7 +1748,7 @@ >>> g = f() >>> next(g) ->>> del g +>>> del g; gc_collect() finally @@ -1770,6 +1774,7 @@ >>> g = f() >>> next(g) >>> del g +>>> gc_collect() >>> sys.stderr.getvalue().startswith( ... "Exception RuntimeError: 'generator ignored GeneratorExit' in " ... ) @@ -1835,6 +1840,9 @@ references. We add it to the standard suite so the routine refleak-tests would trigger if it starts being uncleanable again. +>>> import gc +>>> def gc_collect(): gc.collect() + >>> import itertools >>> def leak(): ... class gen: @@ -1886,9 +1894,10 @@ ... ... l = Leaker() ... del l +... gc_collect() ... err = sys.stderr.getvalue().strip() ... err.startswith( -... "Exception RuntimeError: RuntimeError() in <" +... "Exception RuntimeError: RuntimeError() in " ... ) ... err.endswith("> ignored") ... len(err.splitlines()) diff --git a/lib-python/3.2/test/test_mutants.py b/lib-python/3.2/test/test_mutants.py --- a/lib-python/3.2/test/test_mutants.py +++ b/lib-python/3.2/test/test_mutants.py @@ -1,4 +1,4 @@ -from test.support import verbose, TESTFN +from test.support import verbose, TESTFN, check_impl_detail import random import os @@ -139,7 +139,13 @@ while dict1 and len(dict1) == len(dict2): if verbose: print(".", end=' ') - c = dict1 == dict2 + try: + c = dict1 == dict2 + except RuntimeError: + # CPython never raises RuntimeError here, but other implementations + # might, and it's fine. + if check_impl_detail(cpython=True): + raise if verbose: print() diff --git a/lib-python/3.2/test/test_socket.py b/lib-python/3.2/test/test_socket.py --- a/lib-python/3.2/test/test_socket.py +++ b/lib-python/3.2/test/test_socket.py @@ -313,7 +313,7 @@ "'complex' does not support the buffer interface") with self.assertRaises(TypeError) as cm: s.sendto(b'foo', None) - self.assertIn('not NoneType',str(cm.exception)) + self.assertIn('NoneType', str(cm.exception)) # 3 args with self.assertRaises(TypeError) as cm: s.sendto('\u2620', 0, sockname) @@ -325,20 +325,22 @@ "'complex' does not support the buffer interface") with self.assertRaises(TypeError) as cm: s.sendto(b'foo', 0, None) - self.assertIn('not NoneType', str(cm.exception)) + if support.check_impl_detail(): + self.assertIn('not NoneType', str(cm.exception)) with self.assertRaises(TypeError) as cm: s.sendto(b'foo', 'bar', sockname) - self.assertIn('an integer is required', str(cm.exception)) + self.assertIn('integer', str(cm.exception)) with self.assertRaises(TypeError) as cm: s.sendto(b'foo', None, None) - self.assertIn('an integer is required', str(cm.exception)) + if support.check_impl_detail(): + self.assertIn('an integer is required', str(cm.exception)) # wrong number of args with self.assertRaises(TypeError) as cm: s.sendto(b'foo') - self.assertIn('(1 given)', str(cm.exception)) + self.assertIn(' given)', str(cm.exception)) with self.assertRaises(TypeError) as cm: s.sendto(b'foo', 0, sockname, 4) - self.assertIn('(4 given)', str(cm.exception)) + self.assertIn(' given)', str(cm.exception)) def testCrucialConstants(self): # Testing for mission critical constants @@ -412,10 +414,10 @@ socket.htonl(k) socket.htons(k) for k in bad_values: - self.assertRaises(OverflowError, socket.ntohl, k) - self.assertRaises(OverflowError, socket.ntohs, k) - self.assertRaises(OverflowError, socket.htonl, k) - self.assertRaises(OverflowError, socket.htons, k) + self.assertRaises((OverflowError, ValueError), socket.ntohl, k) + self.assertRaises((OverflowError, ValueError), socket.ntohs, k) + self.assertRaises((OverflowError, ValueError), socket.htonl, k) + self.assertRaises((OverflowError, ValueError), socket.htons, k) def testGetServBy(self): eq = self.assertEqual @@ -455,8 +457,8 @@ if udpport is not None: eq(socket.getservbyport(udpport, 'udp'), service) # Make sure getservbyport does not accept out of range ports. - self.assertRaises(OverflowError, socket.getservbyport, -1) - self.assertRaises(OverflowError, socket.getservbyport, 65536) + self.assertRaises((OverflowError, ValueError), socket.getservbyport, -1) + self.assertRaises((OverflowError, ValueError), socket.getservbyport, 65536) def testDefaultTimeout(self): # Testing default timeout @@ -686,8 +688,8 @@ neg_port = port - 65536 sock = socket.socket() try: - self.assertRaises(OverflowError, sock.bind, (host, big_port)) - self.assertRaises(OverflowError, sock.bind, (host, neg_port)) + self.assertRaises((OverflowError, ValueError), sock.bind, (host, big_port)) + self.assertRaises((OverflowError, ValueError), sock.bind, (host, neg_port)) sock.bind((host, port)) finally: sock.close() @@ -1475,10 +1477,11 @@ self.write_file.flush() def testMakefileCloseSocketDestroy(self): - refcount_before = sys.getrefcount(self.cli_conn) - self.read_file.close() - refcount_after = sys.getrefcount(self.cli_conn) - self.assertEqual(refcount_before - 1, refcount_after) + if hasattr(sys, "getrefcount"): + refcount_before = sys.getrefcount(self.cli_conn) + self.read_file.close() + refcount_after = sys.getrefcount(self.cli_conn) + self.assertEqual(refcount_before - 1, refcount_after) def _testMakefileCloseSocketDestroy(self): pass diff --git a/pypy/module/array/interp_array.py b/pypy/module/array/interp_array.py --- a/pypy/module/array/interp_array.py +++ b/pypy/module/array/interp_array.py @@ -38,8 +38,11 @@ if len(__args__.arguments_w) > 0: w_initializer = __args__.arguments_w[0] - if space.type(w_initializer) is space.w_bytes: - a.fromstring(space.bytes_w(w_initializer)) + if space.lookup(w_initializer, '__buffer__') is not None: + if isinstance(w_initializer, W_ArrayBase): + a.extend(w_initializer, True) + else: + a.fromstring(space.bufferstr_w(w_initializer)) elif space.type(w_initializer) is space.w_list: a.fromlist(w_initializer) else: @@ -569,7 +572,7 @@ self.fromlist(w_lst) def array_frombytes__Array_ANY(space, self, w_s): - self.fromstring(space.bytes_w(w_s)) + self.fromstring(space.bufferstr_w(w_s)) def array_fromstring__Array_ANY(space, self, w_s): space.warn("fromstring() is deprecated. Use frombytes() instead.", @@ -738,7 +741,7 @@ return space.wrap("array('%s')" % self.typecode) elif self.typecode == "u": r = space.repr(array_tounicode__Array(space, self)) - s = "array('%s', %s)" % (self.typecode, space.str_w(r)) + s = u"array('u', %s)" % space.unicode_w(r) return space.wrap(s) else: r = space.repr(array_tolist__Array(space, self)) diff --git a/pypy/module/array/test/test_array.py b/pypy/module/array/test/test_array.py --- a/pypy/module/array/test/test_array.py +++ b/pypy/module/array/test/test_array.py @@ -848,6 +848,19 @@ assert l assert l[0] is None or len(l[0]) == 0 + def test_bytearray(self): + a = self.array('u', 'hi') + b = self.array('u') + b.frombytes(bytearray(a.tobytes())) + assert a == b + assert self.array('u', bytearray(a.tobytes())) == a + + def test_repr(self): + s = '\x00="\'a\\b\x80\xff\u0000\u0001\u1234' + a = self.array('u', s) + assert repr(a) == "array('u', {!r})".format(s) + assert eval(repr(a), {'array': self.array}) == a + class DontTestCPythonsOwnArray(BaseArrayTests): From noreply at buildbot.pypy.org Wed Feb 13 22:28:38 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Wed, 13 Feb 2013 22:28:38 +0100 (CET) Subject: [pypy-commit] pypy default: use gc_collect from test_support Message-ID: <20130213212838.6C5A91C3C2E@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: Changeset: r61213:96be871fc24b Date: 2013-02-13 13:27 -0800 http://bitbucket.org/pypy/pypy/changeset/96be871fc24b/ Log: use gc_collect from test_support diff --git a/lib-python/2.7/test/test_generators.py b/lib-python/2.7/test/test_generators.py --- a/lib-python/2.7/test/test_generators.py +++ b/lib-python/2.7/test/test_generators.py @@ -1501,9 +1501,7 @@ """ coroutine_tests = """\ -A helper function to call gc.collect() without printing ->>> import gc ->>> def gc_collect(): gc.collect() +>>> from test.test_support import gc_collect Sending a value into a started generator: @@ -1823,8 +1821,7 @@ references. We add it to the standard suite so the routine refleak-tests would trigger if it starts being uncleanable again. ->>> import gc ->>> def gc_collect(): gc.collect() +>>> from test.test_support import gc_collect >>> import itertools >>> def leak(): From noreply at buildbot.pypy.org Wed Feb 13 22:31:53 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Wed, 13 Feb 2013 22:31:53 +0100 (CET) Subject: [pypy-commit] pypy py3k: hg backout 8e728e74ca71 Message-ID: <20130213213153.729F71C3C2F@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: py3k Changeset: r61214:5ce27d397871 Date: 2013-02-13 22:06 +0100 http://bitbucket.org/pypy/pypy/changeset/5ce27d397871/ Log: hg backout 8e728e74ca71 diff --git a/lib-python/3.2/test/test_copy.py b/lib-python/3.2/test/test_copy.py --- a/lib-python/3.2/test/test_copy.py +++ b/lib-python/3.2/test/test_copy.py @@ -311,14 +311,8 @@ x = {} x['foo'] = x y = copy.deepcopy(x) - if support.check_impl_detail(): - for op in order_comparisons: - self.assertRaises(TypeError, op, y, x) - else: - # this is an implementation detail - # equality comparisons raise RuntimeError on CPython, too - for op in order_comparisons: - self.assertRaises(RuntimeError, op, y, x) + for op in order_comparisons: + self.assertRaises(TypeError, op, y, x) for op in equality_comparisons: self.assertRaises(RuntimeError, op, y, x) self.assertTrue(y is not x) From noreply at buildbot.pypy.org Wed Feb 13 22:31:55 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Wed, 13 Feb 2013 22:31:55 +0100 (CET) Subject: [pypy-commit] pypy py3k: merge w/ mjacob's fix Message-ID: <20130213213155.118221C3C2F@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61215:728170fe29b8 Date: 2013-02-13 13:31 -0800 http://bitbucket.org/pypy/pypy/changeset/728170fe29b8/ Log: merge w/ mjacob's fix diff --git a/lib-python/3.2/test/test_copy.py b/lib-python/3.2/test/test_copy.py --- a/lib-python/3.2/test/test_copy.py +++ b/lib-python/3.2/test/test_copy.py @@ -311,14 +311,8 @@ x = {} x['foo'] = x y = copy.deepcopy(x) - if support.check_impl_detail(): - for op in order_comparisons: - self.assertRaises(TypeError, op, y, x) - else: - # this is an implementation detail - # equality comparisons raise RuntimeError on CPython, too - for op in order_comparisons: - self.assertRaises(RuntimeError, op, y, x) + for op in order_comparisons: + self.assertRaises(TypeError, op, y, x) for op in equality_comparisons: self.assertRaises(RuntimeError, op, y, x) self.assertTrue(y is not x) From noreply at buildbot.pypy.org Wed Feb 13 23:05:22 2013 From: noreply at buildbot.pypy.org (mattip) Date: Wed, 13 Feb 2013 23:05:22 +0100 (CET) Subject: [pypy-commit] pypy python-numpy: merge default into branch Message-ID: <20130213220522.1E82C1C0EB1@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: python-numpy Changeset: r61216:fba4e51443a9 Date: 2013-02-13 22:26 +0200 http://bitbucket.org/pypy/pypy/changeset/fba4e51443a9/ Log: merge default into branch diff too long, truncating to 2000 out of 7204 lines diff --git a/LICENSE b/LICENSE --- a/LICENSE +++ b/LICENSE @@ -270,3 +270,24 @@ LineBreak-*.txt UnicodeData-*.txt UnihanNumeric-*.txt + +License for 'dotviewer/font/' +============================= + +Copyright (C) 2008 The Android Open Source Project + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +Detailled license information is contained in the NOTICE file in the +directory. + diff --git a/dotviewer/VeraMoBd.ttf b/dotviewer/VeraMoBd.ttf deleted file mode 100644 Binary file dotviewer/VeraMoBd.ttf has changed diff --git a/dotviewer/cyrvetic.ttf b/dotviewer/cyrvetic.ttf deleted file mode 100644 Binary file dotviewer/cyrvetic.ttf has changed diff --git a/dotviewer/drawgraph.py b/dotviewer/drawgraph.py --- a/dotviewer/drawgraph.py +++ b/dotviewer/drawgraph.py @@ -9,9 +9,10 @@ from pygame.locals import * +RAW_ENCODING = "utf-8" this_dir = os.path.dirname(os.path.abspath(__file__)) -FONT = os.path.join(this_dir, 'cyrvetic.ttf') -FIXEDFONT = os.path.join(this_dir, 'VeraMoBd.ttf') +FONT = os.path.join(this_dir, 'font', 'DroidSans.ttf') +FIXEDFONT = os.path.join(this_dir, 'font', 'DroidSansMono.ttf') COLOR = { 'black': (0,0,0), 'white': (255,255,255), @@ -51,6 +52,12 @@ else: return default +def forceunicode(name): + return name if isinstance(name, unicode) else name.decode(RAW_ENCODING) + +def forcestr(name): + return name if isinstance(name, str) else name.encode(RAW_ENCODING) + class GraphLayout: fixedfont = False @@ -106,12 +113,12 @@ class Node: def __init__(self, name, x, y, w, h, label, style, shape, color, fillcolor): - self.name = name + self.name = forceunicode(name) self.x = float(x) self.y = float(y) self.w = float(w) self.h = float(h) - self.label = label + self.label = forceunicode(label) self.style = style self.shape = shape self.color = color @@ -125,8 +132,8 @@ label = None def __init__(self, nodes, tail, head, cnt, *rest): - self.tail = nodes[tail] - self.head = nodes[head] + self.tail = nodes[forceunicode(tail)] + self.head = nodes[forceunicode(head)] cnt = int(cnt) self.points = [(float(rest[i]), float(rest[i+1])) for i in range(0, cnt*2, 2)] @@ -655,11 +662,7 @@ part = parts[i] word = part[0] try: - try: - img = font.render(word, False, *part[1:]) - except pygame.error, e: - # Try *with* anti-aliasing to work around a bug in SDL - img = font.render(word, True, *part[1:]) + img = font.render(word, True, *part[1:]) except pygame.error: del parts[i] # Text has zero width else: diff --git a/dotviewer/font/DroidSans-Bold.ttf b/dotviewer/font/DroidSans-Bold.ttf new file mode 100644 index 0000000000000000000000000000000000000000..d065b64eb1863f83c2c982264f9442f2313a44a9 GIT binary patch [cut] diff --git a/dotviewer/font/DroidSans.ttf b/dotviewer/font/DroidSans.ttf new file mode 100644 index 0000000000000000000000000000000000000000..ad1efca88aed8d9e2d179f27dd713e2a1562fe5f GIT binary patch [cut] diff --git a/dotviewer/font/DroidSansMono.ttf b/dotviewer/font/DroidSansMono.ttf new file mode 100644 index 0000000000000000000000000000000000000000..a007071944f7c90020e798eea53b10065e2b45a5 GIT binary patch [cut] diff --git a/dotviewer/font/NOTICE b/dotviewer/font/NOTICE new file mode 100644 --- /dev/null +++ b/dotviewer/font/NOTICE @@ -0,0 +1,190 @@ + + Copyright (c) 2005-2008, The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + diff --git a/dotviewer/font/README.txt b/dotviewer/font/README.txt new file mode 100644 --- /dev/null +++ b/dotviewer/font/README.txt @@ -0,0 +1,18 @@ +Copyright (C) 2008 The Android Open Source Project + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +########## + +This directory contains the fonts for the platform. They are licensed +under the Apache 2 license. diff --git a/dotviewer/graphclient.py b/dotviewer/graphclient.py --- a/dotviewer/graphclient.py +++ b/dotviewer/graphclient.py @@ -33,8 +33,9 @@ def reload(graph_id): page = getpage(graph_id) if save_tmp_file: + from drawgraph import forcestr f = open(save_tmp_file, 'w') - f.write(page.source) + f.write(forcestr(page.source)) f.close() messages.extend(page_messages(page, graph_id)) send_graph_messages(io, messages) @@ -75,7 +76,8 @@ def page_messages(page, graph_id): import graphparse - return graphparse.parse_dot(graph_id, page.source, page.links, + from drawgraph import forcestr + return graphparse.parse_dot(graph_id, forcestr(page.source), page.links, getattr(page, 'fixedfont', False)) def send_graph_messages(io, messages): diff --git a/dotviewer/graphdisplay.py b/dotviewer/graphdisplay.py --- a/dotviewer/graphdisplay.py +++ b/dotviewer/graphdisplay.py @@ -4,7 +4,7 @@ from pygame.locals import * from drawgraph import GraphRenderer, FIXEDFONT from drawgraph import Node, Edge -from drawgraph import EventQueue, wait_for_events +from drawgraph import EventQueue, wait_for_events, forceunicode, forcestr METAKEYS = dict([ @@ -285,7 +285,7 @@ if e.key == K_ESCAPE: return None elif e.key == K_RETURN: - return text.encode('latin-1') # XXX do better + return forcestr(text) # return encoded unicode elif e.key == K_BACKSPACE: text = text[:-1] elif e.unicode and ord(e.unicode) >= ord(' '): @@ -423,7 +423,7 @@ self.layout.request_reload() def setstatusbar(self, text, fgcolor=None, bgcolor=None): - info = (text, fgcolor or self.STATUSBAR_FGCOLOR, bgcolor or self.STATUSBAR_BGCOLOR) + info = (forceunicode(text), fgcolor or self.STATUSBAR_FGCOLOR, bgcolor or self.STATUSBAR_BGCOLOR) if info != self.statusbarinfo: self.statusbarinfo = info self.must_redraw = True @@ -711,7 +711,7 @@ lines = [] while words: line = words.pop(0) - img = font.render(line or ' ', 1, fgcolor) + img = font.render(line or ' ', True, fgcolor) while words: longerline = line + ' ' + words[0] longerimg = font.render(longerline, 1, fgcolor) @@ -723,7 +723,7 @@ img = longerimg w, h = img.get_size() if h > maxheight: - img = font.render('...', 1, overflowcolor) + img = font.render('...', True, overflowcolor) w, h = img.get_size() while lines and h > maxheight: maxheight += lines.pop().get_size()[1] diff --git a/dotviewer/graphpage.py b/dotviewer/graphpage.py --- a/dotviewer/graphpage.py +++ b/dotviewer/graphpage.py @@ -44,6 +44,8 @@ class DotFileGraphPage(GraphPage): def compute(self, dotfile): - f = open(dotfile, 'r') + import codecs + from drawgraph import RAW_ENCODING + f = codecs.open(dotfile, 'r', RAW_ENCODING) self.source = f.read() f.close() diff --git a/dotviewer/test/test_interactive_unicode.py b/dotviewer/test/test_interactive_unicode.py new file mode 100755 --- /dev/null +++ b/dotviewer/test/test_interactive_unicode.py @@ -0,0 +1,103 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +import py +import sys, os, signal, thread, time, codecs +from dotviewer.conftest import option +from dotviewer.drawgraph import RAW_ENCODING + +SOURCE1 = u"""digraph G{ +λ -> b +b -> μ +} +""" + +FILENAME = 'graph1.dot' + +def setup_module(mod): + if not option.pygame: + py.test.skip("--pygame not enabled") + udir = py.path.local.make_numbered_dir(prefix='usession-dot-', keep=3) + f = codecs.open(str(udir.join(FILENAME)), 'wb', RAW_ENCODING) + f.write(SOURCE1) + f.close() + + from dotviewer import graphclient + mod.pkgdir = py.path.local(graphclient.this_dir) + mod.udir = udir + + try: + del os.environ['GRAPHSERVER'] + except KeyError: + pass + + +def test_dotviewer(): + print "=== dotviewer.py %s" % FILENAME + err = os.system('"%s" "%s"' % (pkgdir.join('dotviewer.py'), + udir.join(FILENAME))) + assert err == 0 + + plain_name = FILENAME.replace('.dot','.plain') + + os.system('dot -Tplain "%s" > "%s"' % (udir.join(FILENAME), + udir.join(plain_name))) + print "=== dotviewer.py %s" % plain_name + err = os.system('"%s" "%s"' % (pkgdir.join('dotviewer.py'), + udir.join(plain_name))) + assert err == 0 + +def test_display_dot_file(): + from dotviewer.graphclient import display_dot_file + print "=== display_dot_file(%s) with GRAPHSERVER=%s" % ( + FILENAME, os.environ.get('GRAPHSERVER', ''),) + display_dot_file(udir.join(FILENAME)) + print "=== display_dot_file finished" + + +def test_graphserver(): + import socket + s = socket.socket() + s.listen(1) + host, port = s.getsockname() # pick a random free port + s.close() + + if hasattr(sys, 'pypy_objspaceclass'): + python = 'python' + else: + python = sys.executable + + cmdargs = [python, str(pkgdir.join('graphserver.py')), + str(port)] + print '* starting:', ' '.join(cmdargs) + pid = os.spawnv(os.P_NOWAIT, cmdargs[0], cmdargs) + try: + time.sleep(1) # hack - wait a bit to make sure the server is up + os.environ['GRAPHSERVER'] = '%s:%d' % (host, port) + try: + test_display_dot_file() + finally: + del os.environ['GRAPHSERVER'] + finally: + os.kill(pid, signal.SIGTERM) + +def test_colors(): + from dotviewer import graphpage, graphclient + class MyPage(graphpage.DotFileGraphPage): + def compute(self, dotfile): + super(MyPage, self).compute(dotfile) + self.links = {'v2721': 'Hello world', + 'v2720': ('Something green', (0, 192, 0)), + } + dotfile = str(udir.join(FILENAME)) + page = MyPage(dotfile) + graphclient.display_page(page) + +def test_fixedfont(): + from dotviewer import graphpage, graphclient + class MyPage(graphpage.DotFileGraphPage): + fixedfont = True + dotfile = str(udir.join(FILENAME)) + page = MyPage(dotfile) + page.fixedfont = True + graphclient.display_page(page) diff --git a/dotviewer/test/test_translator.py b/dotviewer/test/test_translator.py --- a/dotviewer/test/test_translator.py +++ b/dotviewer/test/test_translator.py @@ -22,6 +22,6 @@ def test_annotated(): from rpython.translator.interactive import Translation - t = Translation(is_prime) - t.annotate([int]) + t = Translation(is_prime, [int]) + t.annotate() t.viewcg() diff --git a/dotviewer/test/test_unicode_util.py b/dotviewer/test/test_unicode_util.py new file mode 100755 --- /dev/null +++ b/dotviewer/test/test_unicode_util.py @@ -0,0 +1,57 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +import py +import codecs +from dotviewer.drawgraph import RAW_ENCODING, forcestr, forceunicode + +SOURCE1 = u"""digraph G{ +λ -> b +b -> μ +} +""" + +FILENAME = 'test.dot' + +class TestUnicodeUtil(object): + + def test_idempotent(self): + x = u"a" + assert forceunicode(forcestr(x)) == x + + x = u"λ" + assert forceunicode(forcestr(x)) == x + + assert forceunicode(forcestr(SOURCE1)) == SOURCE1 + + x = "a" + assert forcestr(forceunicode(x)) == x + + # utf-8 encoded. + # fragile, does not consider RAW_ENCODING + # x = "\xef\xbb\xbf\xce\xbb" + # assert forcestr(forceunicode(x)) == x + + def test_does_not_double_encode(self): + x = u"λ" + x_e = forcestr(x) + assert forcestr(x_e) == x_e + + x_u = forceunicode(x_e) + assert forceunicode(x_u) == x_u + + def test_file(self): + udir = py.path.local.make_numbered_dir(prefix='usession-dot-', keep=3) + full_filename = str(udir.join(FILENAME)) + f = codecs.open(full_filename, 'wb', RAW_ENCODING) + f.write(SOURCE1) + f.close() + + with open(full_filename) as f1: + assert forceunicode(f1.read()) == SOURCE1 + + f3 = codecs.open(full_filename, 'r', RAW_ENCODING) + c = f3.read() + f3.close() + result = (c == SOURCE1) + assert result diff --git a/lib-python/2.7/collections.py b/lib-python/2.7/collections.py --- a/lib-python/2.7/collections.py +++ b/lib-python/2.7/collections.py @@ -295,7 +295,7 @@ _fields = %(field_names)r \n def __new__(_cls, %(argtxt)s): 'Create new instance of %(typename)s(%(argtxt)s)' - return tuple.__new__(_cls, (%(argtxt)s)) \n + return _tuple.__new__(_cls, (%(argtxt)s)) \n @classmethod def _make(cls, iterable, new=tuple.__new__, len=len): 'Make a new %(typename)s object from a sequence or iterable' @@ -320,14 +320,14 @@ 'Return self as a plain tuple. Used by copy and pickle.' return tuple(self) \n\n''' % locals() for i, name in enumerate(field_names): - template += " %s = property(lambda self: self[%d], doc='Alias for field number %d')\n" % (name, i, i) + template += " %s = _property(lambda self: self[%d], doc='Alias for field number %d')\n" % (name, i, i) if verbose: print template # Execute the template string in a temporary namespace and # support tracing utilities by setting a value for frame.f_globals['__name__'] - namespace = {'__name__': 'namedtuple_%s' % typename, - 'OrderedDict': OrderedDict} + namespace = dict(__name__='namedtuple_%s' % typename, + OrderedDict=OrderedDict, _property=property, _tuple=tuple) try: exec template in namespace except SyntaxError, e: diff --git a/lib-python/2.7/json/encoder.py b/lib-python/2.7/json/encoder.py --- a/lib-python/2.7/json/encoder.py +++ b/lib-python/2.7/json/encoder.py @@ -138,16 +138,16 @@ self.skipkeys = skipkeys self.ensure_ascii = ensure_ascii if ensure_ascii: - self.encoder = raw_encode_basestring_ascii + self.__encoder = raw_encode_basestring_ascii else: - self.encoder = raw_encode_basestring + self.__encoder = raw_encode_basestring if encoding != 'utf-8': - orig_encoder = self.encoder + orig_encoder = self.__encoder def encoder(o): if isinstance(o, str): o = o.decode(encoding) return orig_encoder(o) - self.encoder = encoder + self.__encoder = encoder self.check_circular = check_circular self.allow_nan = allow_nan self.sort_keys = sort_keys @@ -193,10 +193,10 @@ builder = StringBuilder() else: builder = UnicodeBuilder() - self._encode(o, markers, builder, 0) + self.__encode(o, markers, builder, 0) return builder.build() - def _emit_indent(self, builder, _current_indent_level): + def __emit_indent(self, builder, _current_indent_level): if self.indent is not None: _current_indent_level += 1 newline_indent = '\n' + (' ' * (self.indent * @@ -207,15 +207,15 @@ separator = self.item_separator return separator, _current_indent_level - def _emit_unindent(self, builder, _current_indent_level): + def __emit_unindent(self, builder, _current_indent_level): if self.indent is not None: builder.append('\n') builder.append(' ' * (self.indent * (_current_indent_level - 1))) - def _encode(self, o, markers, builder, _current_indent_level): + def __encode(self, o, markers, builder, _current_indent_level): if isinstance(o, basestring): builder.append('"') - builder.append(self.encoder(o)) + builder.append(self.__encoder(o)) builder.append('"') elif o is None: builder.append('null') @@ -226,46 +226,46 @@ elif isinstance(o, (int, long)): builder.append(str(o)) elif isinstance(o, float): - builder.append(self._floatstr(o)) + builder.append(self.__floatstr(o)) elif isinstance(o, (list, tuple)): if not o: builder.append('[]') return - self._encode_list(o, markers, builder, _current_indent_level) + self.__encode_list(o, markers, builder, _current_indent_level) elif isinstance(o, dict): if not o: builder.append('{}') return - self._encode_dict(o, markers, builder, _current_indent_level) + self.__encode_dict(o, markers, builder, _current_indent_level) else: - self._mark_markers(markers, o) + self.__mark_markers(markers, o) res = self.default(o) - self._encode(res, markers, builder, _current_indent_level) - self._remove_markers(markers, o) + self.__encode(res, markers, builder, _current_indent_level) + self.__remove_markers(markers, o) return res - def _encode_list(self, l, markers, builder, _current_indent_level): - self._mark_markers(markers, l) + def __encode_list(self, l, markers, builder, _current_indent_level): + self.__mark_markers(markers, l) builder.append('[') first = True - separator, _current_indent_level = self._emit_indent(builder, + separator, _current_indent_level = self.__emit_indent(builder, _current_indent_level) for elem in l: if first: first = False else: builder.append(separator) - self._encode(elem, markers, builder, _current_indent_level) + self.__encode(elem, markers, builder, _current_indent_level) del elem # XXX grumble - self._emit_unindent(builder, _current_indent_level) + self.__emit_unindent(builder, _current_indent_level) builder.append(']') - self._remove_markers(markers, l) + self.__remove_markers(markers, l) - def _encode_dict(self, d, markers, builder, _current_indent_level): - self._mark_markers(markers, d) + def __encode_dict(self, d, markers, builder, _current_indent_level): + self.__mark_markers(markers, d) first = True builder.append('{') - separator, _current_indent_level = self._emit_indent(builder, + separator, _current_indent_level = self.__emit_indent(builder, _current_indent_level) if self.sort_keys: items = sorted(d.items(), key=lambda kv: kv[0]) @@ -282,7 +282,7 @@ # JavaScript is weakly typed for these, so it makes sense to # also allow them. Many encoders seem to do something like this. elif isinstance(key, float): - key = self._floatstr(key) + key = self.__floatstr(key) elif key is True: key = 'true' elif key is False: @@ -296,15 +296,15 @@ else: raise TypeError("key " + repr(key) + " is not a string") builder.append('"') - builder.append(self.encoder(key)) + builder.append(self.__encoder(key)) builder.append('"') builder.append(self.key_separator) - self._encode(v, markers, builder, _current_indent_level) + self.__encode(v, markers, builder, _current_indent_level) del key del v # XXX grumble - self._emit_unindent(builder, _current_indent_level) + self.__emit_unindent(builder, _current_indent_level) builder.append('}') - self._remove_markers(markers, d) + self.__remove_markers(markers, d) def iterencode(self, o, _one_shot=False): """Encode the given object and yield each string @@ -320,9 +320,9 @@ markers = {} else: markers = None - return self._iterencode(o, markers, 0) + return self.__iterencode(o, markers, 0) - def _floatstr(self, o): + def __floatstr(self, o): # Check for specials. Note that this type of test is processor # and/or platform-specific, so do tests which don't depend on the # internals. @@ -343,21 +343,21 @@ return text - def _mark_markers(self, markers, o): + def __mark_markers(self, markers, o): if markers is not None: if id(o) in markers: raise ValueError("Circular reference detected") markers[id(o)] = None - def _remove_markers(self, markers, o): + def __remove_markers(self, markers, o): if markers is not None: del markers[id(o)] - def _iterencode_list(self, lst, markers, _current_indent_level): + def __iterencode_list(self, lst, markers, _current_indent_level): if not lst: yield '[]' return - self._mark_markers(markers, lst) + self.__mark_markers(markers, lst) buf = '[' if self.indent is not None: _current_indent_level += 1 @@ -375,7 +375,7 @@ else: buf = separator if isinstance(value, basestring): - yield buf + '"' + self.encoder(value) + '"' + yield buf + '"' + self.__encoder(value) + '"' elif value is None: yield buf + 'null' elif value is True: @@ -385,17 +385,17 @@ elif isinstance(value, (int, long)): yield buf + str(value) elif isinstance(value, float): - yield buf + self._floatstr(value) + yield buf + self.__floatstr(value) else: yield buf if isinstance(value, (list, tuple)): - chunks = self._iterencode_list(value, markers, + chunks = self.__iterencode_list(value, markers, _current_indent_level) elif isinstance(value, dict): - chunks = self._iterencode_dict(value, markers, + chunks = self.__iterencode_dict(value, markers, _current_indent_level) else: - chunks = self._iterencode(value, markers, + chunks = self.__iterencode(value, markers, _current_indent_level) for chunk in chunks: yield chunk @@ -403,13 +403,13 @@ _current_indent_level -= 1 yield '\n' + (' ' * (self.indent * _current_indent_level)) yield ']' - self._remove_markers(markers, lst) + self.__remove_markers(markers, lst) - def _iterencode_dict(self, dct, markers, _current_indent_level): + def __iterencode_dict(self, dct, markers, _current_indent_level): if not dct: yield '{}' return - self._mark_markers(markers, dct) + self.__mark_markers(markers, dct) yield '{' if self.indent is not None: _current_indent_level += 1 @@ -431,7 +431,7 @@ # JavaScript is weakly typed for these, so it makes sense to # also allow them. Many encoders seem to do something like this. elif isinstance(key, float): - key = self._floatstr(key) + key = self.__floatstr(key) elif key is True: key = 'true' elif key is False: @@ -448,10 +448,10 @@ first = False else: yield item_separator - yield '"' + self.encoder(key) + '"' + yield '"' + self.__encoder(key) + '"' yield self.key_separator if isinstance(value, basestring): - yield '"' + self.encoder(value) + '"' + yield '"' + self.__encoder(value) + '"' elif value is None: yield 'null' elif value is True: @@ -461,16 +461,16 @@ elif isinstance(value, (int, long)): yield str(value) elif isinstance(value, float): - yield self._floatstr(value) + yield self.__floatstr(value) else: if isinstance(value, (list, tuple)): - chunks = self._iterencode_list(value, markers, + chunks = self.__iterencode_list(value, markers, _current_indent_level) elif isinstance(value, dict): - chunks = self._iterencode_dict(value, markers, + chunks = self.__iterencode_dict(value, markers, _current_indent_level) else: - chunks = self._iterencode(value, markers, + chunks = self.__iterencode(value, markers, _current_indent_level) for chunk in chunks: yield chunk @@ -478,11 +478,11 @@ _current_indent_level -= 1 yield '\n' + (' ' * (self.indent * _current_indent_level)) yield '}' - self._remove_markers(markers, dct) + self.__remove_markers(markers, dct) - def _iterencode(self, o, markers, _current_indent_level): + def __iterencode(self, o, markers, _current_indent_level): if isinstance(o, basestring): - yield '"' + self.encoder(o) + '"' + yield '"' + self.__encoder(o) + '"' elif o is None: yield 'null' elif o is True: @@ -492,19 +492,19 @@ elif isinstance(o, (int, long)): yield str(o) elif isinstance(o, float): - yield self._floatstr(o) + yield self.__floatstr(o) elif isinstance(o, (list, tuple)): - for chunk in self._iterencode_list(o, markers, + for chunk in self.__iterencode_list(o, markers, _current_indent_level): yield chunk elif isinstance(o, dict): - for chunk in self._iterencode_dict(o, markers, + for chunk in self.__iterencode_dict(o, markers, _current_indent_level): yield chunk else: - self._mark_markers(markers, o) + self.__mark_markers(markers, o) obj = self.default(o) - for chunk in self._iterencode(obj, markers, + for chunk in self.__iterencode(obj, markers, _current_indent_level): yield chunk - self._remove_markers(markers, o) + self.__remove_markers(markers, o) diff --git a/lib-python/2.7/urllib.py b/lib-python/2.7/urllib.py --- a/lib-python/2.7/urllib.py +++ b/lib-python/2.7/urllib.py @@ -1205,15 +1205,17 @@ # fastpath if len(res) == 1: return s - s = res[0] - for item in res[1:]: + res_list = [res[0]] + for j in xrange(1, len(res)): + item = res[j] try: - s += _hextochr[item[:2]] + item[2:] + x = _hextochr[item[:2]] + item[2:] except KeyError: - s += '%' + item + x = '%' + item except UnicodeDecodeError: - s += unichr(int(item[:2], 16)) + item[2:] - return s + x = unichr(int(item[:2], 16)) + item[2:] + res_list.append(x) + return ''.join(res_list) def unquote_plus(s): """unquote('%7e/abc+def') -> '~/abc def'""" diff --git a/lib-python/2.7/urlparse.py b/lib-python/2.7/urlparse.py --- a/lib-python/2.7/urlparse.py +++ b/lib-python/2.7/urlparse.py @@ -321,15 +321,17 @@ # fastpath if len(res) == 1: return s - s = res[0] - for item in res[1:]: + res_list = [res[0]] + for j in xrange(1, len(res)): + item = res[j] try: - s += _hextochr[item[:2]] + item[2:] + x = _hextochr[item[:2]] + item[2:] except KeyError: - s += '%' + item + x = '%' + item except UnicodeDecodeError: - s += unichr(int(item[:2], 16)) + item[2:] - return s + x = unichr(int(item[:2], 16)) + item[2:] + res_list.append(x) + return ''.join(res_list) def parse_qs(qs, keep_blank_values=0, strict_parsing=0): """Parse a query given as a string argument. diff --git a/lib-python/conftest.py b/lib-python/conftest.py --- a/lib-python/conftest.py +++ b/lib-python/conftest.py @@ -272,7 +272,7 @@ RegrTest('test_inspect.py'), RegrTest('test_int.py', core=True), RegrTest('test_int_literal.py', core=True), - RegrTest('test_io.py'), + RegrTest('test_io.py', usemodules='array binascii'), RegrTest('test_ioctl.py'), RegrTest('test_isinstance.py', core=True), RegrTest('test_iter.py', core=True), diff --git a/lib_pypy/_collections.py b/lib_pypy/_collections.py --- a/lib_pypy/_collections.py +++ b/lib_pypy/_collections.py @@ -142,18 +142,24 @@ return c def remove(self, value): - # Need to be defensive for mutating comparisons - for i in range(len(self)): - if self[i] == value: - del self[i] - return - raise ValueError("deque.remove(x): x not in deque") + # Need to defend mutating or failing comparisons + i = 0 + try: + for i in range(len(self)): + if self[0] == value: + self.popleft() + return + self.append(self.popleft()) + i += 1 + raise ValueError("deque.remove(x): x not in deque") + finally: + self.rotate(i) def rotate(self, n=1): length = len(self) - if length == 0: + if length <= 1: return - halflen = (length+1) >> 1 + halflen = length >> 1 if n > halflen or n < -halflen: n %= length if n > halflen: diff --git a/lib_pypy/conftest.py b/lib_pypy/conftest.py deleted file mode 100644 --- a/lib_pypy/conftest.py +++ /dev/null @@ -1,2 +0,0 @@ - -from pypy.conftest import * diff --git a/lib_pypy/datetime.py b/lib_pypy/datetime.py --- a/lib_pypy/datetime.py +++ b/lib_pypy/datetime.py @@ -270,10 +270,21 @@ return offset raise ValueError("%s()=%d, must be in -1439..1439" % (name, offset)) +def _check_int_field(value): + if not isinstance(value, float): + try: + value = value.__int__() + except AttributeError: + pass + else: + if isinstance(value, (int, long)): + return value + raise TypeError('integer argument expected') + def _check_date_fields(year, month, day): - for value in [year, day]: - if not isinstance(value, (int, long)): - raise TypeError('int expected') + year = _check_int_field(year) + month = _check_int_field(month) + day = _check_int_field(day) if not MINYEAR <= year <= MAXYEAR: raise ValueError('year must be in %d..%d' % (MINYEAR, MAXYEAR), year) if not 1 <= month <= 12: @@ -281,11 +292,13 @@ dim = _days_in_month(year, month) if not 1 <= day <= dim: raise ValueError('day must be in 1..%d' % dim, day) + return year, month, day def _check_time_fields(hour, minute, second, microsecond): - for value in [hour, minute, second, microsecond]: - if not isinstance(value, (int, long)): - raise TypeError('int expected') + hour = _check_int_field(hour) + minute = _check_int_field(minute) + second = _check_int_field(second) + microsecond = _check_int_field(microsecond) if not 0 <= hour <= 23: raise ValueError('hour must be in 0..23', hour) if not 0 <= minute <= 59: @@ -294,6 +307,7 @@ raise ValueError('second must be in 0..59', second) if not 0 <= microsecond <= 999999: raise ValueError('microsecond must be in 0..999999', microsecond) + return hour, minute, second, microsecond def _check_tzinfo_arg(tz): if tz is not None and not isinstance(tz, tzinfo): @@ -768,7 +782,7 @@ self = object.__new__(cls) self.__setstate(year) return self - _check_date_fields(year, month, day) + year, month, day = _check_date_fields(year, month, day) self = object.__new__(cls) self._year = year self._month = month @@ -889,7 +903,7 @@ month = self._month if day is None: day = self._day - _check_date_fields(year, month, day) + year, month, day = _check_date_fields(year, month, day) return date(year, month, day) # Comparisons of date objects with other. @@ -1150,13 +1164,14 @@ second, microsecond (default to zero) tzinfo (default to None) """ - self = object.__new__(cls) if isinstance(hour, str): # Pickle support + self = object.__new__(cls) self.__setstate(hour, minute or None) return self + hour, minute, second, microsecond = _check_time_fields(hour, minute, second, microsecond) _check_tzinfo_arg(tzinfo) - _check_time_fields(hour, minute, second, microsecond) + self = object.__new__(cls) self._hour = hour self._minute = minute self._second = second @@ -1387,7 +1402,7 @@ microsecond = self.microsecond if tzinfo is True: tzinfo = self.tzinfo - _check_time_fields(hour, minute, second, microsecond) + hour, minute, second, microsecond = _check_time_fields(hour, minute, second, microsecond) _check_tzinfo_arg(tzinfo) return time(hour, minute, second, microsecond, tzinfo) @@ -1449,10 +1464,10 @@ self = date.__new__(cls, year[:4]) self.__setstate(year, month) return self + year, month, day = _check_date_fields(year, month, day) + hour, minute, second, microsecond = _check_time_fields(hour, minute, second, microsecond) _check_tzinfo_arg(tzinfo) - _check_time_fields(hour, minute, second, microsecond) - self = date.__new__(cls, year, month, day) - # XXX This duplicates __year, __month, __day for convenience :-( + self = object.__new__(cls) self._year = year self._month = month self._day = day @@ -1617,8 +1632,8 @@ microsecond = self.microsecond if tzinfo is True: tzinfo = self.tzinfo - _check_date_fields(year, month, day) - _check_time_fields(hour, minute, second, microsecond) + year, month, day = _check_date_fields(year, month, day) + hour, minute, second, microsecond = _check_time_fields(hour, minute, second, microsecond) _check_tzinfo_arg(tzinfo) return datetime(year, month, day, hour, minute, second, microsecond, tzinfo) diff --git a/lib_pypy/dbm.py b/lib_pypy/dbm.py --- a/lib_pypy/dbm.py +++ b/lib_pypy/dbm.py @@ -1,4 +1,4 @@ -from ctypes import Structure, c_char_p, c_int, c_void_p, CDLL +from ctypes import Structure, c_char_p, c_int, c_void_p, CDLL, POINTER, c_char import ctypes.util import os, sys @@ -11,7 +11,7 @@ class datum(Structure): _fields_ = [ - ('dptr', c_char_p), + ('dptr', POINTER(c_char)), ('dsize', c_int), ] @@ -126,8 +126,8 @@ libpath = ctypes.util.find_library('db') if not libpath: # XXX this is hopeless... - for c in '56789': - libpath = ctypes.util.find_library('db-4.%s' % c) + for c in ['5.3', '5.2', '5.1', '5.0', '4.9', '4.8', '4.7', '4.6', '4.5']: + libpath = ctypes.util.find_library('db-%s' % c) if libpath: break else: diff --git a/lib_pypy/numpypy/core/__init__.py b/lib_pypy/numpypy/core/__init__.py --- a/lib_pypy/numpypy/core/__init__.py +++ b/lib_pypy/numpypy/core/__init__.py @@ -1,2 +1,3 @@ from .fromnumeric import * from .numeric import * +from .shape_base import * diff --git a/lib_pypy/numpypy/core/numeric.py b/lib_pypy/numpypy/core/numeric.py --- a/lib_pypy/numpypy/core/numeric.py +++ b/lib_pypy/numpypy/core/numeric.py @@ -428,3 +428,76 @@ True_ = bool_(True) e = math.e pi = math.pi + +def outer(a,b): + """ + Compute the outer product of two vectors. + + Given two vectors, ``a = [a0, a1, ..., aM]`` and + ``b = [b0, b1, ..., bN]``, + the outer product [1]_ is:: + + [[a0*b0 a0*b1 ... a0*bN ] + [a1*b0 . + [ ... . + [aM*b0 aM*bN ]] + + Parameters + ---------- + a, b : array_like, shape (M,), (N,) + First and second input vectors. Inputs are flattened if they + are not already 1-dimensional. + + Returns + ------- + out : ndarray, shape (M, N) + ``out[i, j] = a[i] * b[j]`` + + See also + -------- + inner, einsum + + References + ---------- + .. [1] : G. H. Golub and C. F. van Loan, *Matrix Computations*, 3rd + ed., Baltimore, MD, Johns Hopkins University Press, 1996, + pg. 8. + + Examples + -------- + Make a (*very* coarse) grid for computing a Mandelbrot set: + + >>> rl = np.outer(np.ones((5,)), np.linspace(-2, 2, 5)) + >>> rl + array([[-2., -1., 0., 1., 2.], + [-2., -1., 0., 1., 2.], + [-2., -1., 0., 1., 2.], + [-2., -1., 0., 1., 2.], + [-2., -1., 0., 1., 2.]]) + >>> im = np.outer(1j*np.linspace(2, -2, 5), np.ones((5,))) + >>> im + array([[ 0.+2.j, 0.+2.j, 0.+2.j, 0.+2.j, 0.+2.j], + [ 0.+1.j, 0.+1.j, 0.+1.j, 0.+1.j, 0.+1.j], + [ 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j], + [ 0.-1.j, 0.-1.j, 0.-1.j, 0.-1.j, 0.-1.j], + [ 0.-2.j, 0.-2.j, 0.-2.j, 0.-2.j, 0.-2.j]]) + >>> grid = rl + im + >>> grid + array([[-2.+2.j, -1.+2.j, 0.+2.j, 1.+2.j, 2.+2.j], + [-2.+1.j, -1.+1.j, 0.+1.j, 1.+1.j, 2.+1.j], + [-2.+0.j, -1.+0.j, 0.+0.j, 1.+0.j, 2.+0.j], + [-2.-1.j, -1.-1.j, 0.-1.j, 1.-1.j, 2.-1.j], + [-2.-2.j, -1.-2.j, 0.-2.j, 1.-2.j, 2.-2.j]]) + + An example using a "vector" of letters: + + >>> x = np.array(['a', 'b', 'c'], dtype=object) + >>> np.outer(x, [1, 2, 3]) + array([[a, aa, aaa], + [b, bb, bbb], + [c, cc, ccc]], dtype=object) + + """ + a = asarray(a) + b = asarray(b) + return a.ravel()[:,newaxis]*b.ravel()[newaxis,:] diff --git a/lib_pypy/numpypy/core/shape_base.py b/lib_pypy/numpypy/core/shape_base.py new file mode 100644 --- /dev/null +++ b/lib_pypy/numpypy/core/shape_base.py @@ -0,0 +1,323 @@ +import _numpypy +from numeric import array, asanyarray, newaxis + +def atleast_1d(*arys): + """ + Convert inputs to arrays with at least one dimension. + + Scalar inputs are converted to 1-dimensional arrays, whilst + higher-dimensional inputs are preserved. + + Parameters + ---------- + arys1, arys2, ... : array_like + One or more input arrays. + + Returns + ------- + ret : ndarray + An array, or sequence of arrays, each with ``a.ndim >= 1``. + Copies are made only if necessary. + + See Also + -------- + atleast_2d, atleast_3d + + Examples + -------- + >>> np.atleast_1d(1.0) + array([ 1.]) + + >>> x = np.arange(9.0).reshape(3,3) + >>> np.atleast_1d(x) + array([[ 0., 1., 2.], + [ 3., 4., 5.], + [ 6., 7., 8.]]) + >>> np.atleast_1d(x) is x + True + + >>> np.atleast_1d(1, [3, 4]) + [array([1]), array([3, 4])] + + """ + res = [] + for ary in arys: + ary = asanyarray(ary) + if len(ary.shape) == 0 : + result = ary.reshape(1) + else : + result = ary + res.append(result) + if len(res) == 1: + return res[0] + else: + return res + + +def atleast_2d(*arys): + """ + View inputs as arrays with at least two dimensions. + + Parameters + ---------- + arys1, arys2, ... : array_like + One or more array-like sequences. Non-array inputs are converted + to arrays. Arrays that already have two or more dimensions are + preserved. + + Returns + ------- + res, res2, ... : ndarray + An array, or tuple of arrays, each with ``a.ndim >= 2``. + Copies are avoided where possible, and views with two or more + dimensions are returned. + + See Also + -------- + atleast_1d, atleast_3d + + Examples + -------- + >>> np.atleast_2d(3.0) + array([[ 3.]]) + + >>> x = np.arange(3.0) + >>> np.atleast_2d(x) + array([[ 0., 1., 2.]]) + >>> np.atleast_2d(x).base is x + True + + >>> np.atleast_2d(1, [1, 2], [[1, 2]]) + [array([[1]]), array([[1, 2]]), array([[1, 2]])] + + """ + res = [] + for ary in arys: + ary = asanyarray(ary) + if len(ary.shape) == 0 : + result = ary.reshape(1, 1) + elif len(ary.shape) == 1 : + result = ary[newaxis, :] + else : + result = ary + res.append(result) + if len(res) == 1: + return res[0] + else: + return res + +def atleast_3d(*arys): + """ + View inputs as arrays with at least three dimensions. + + Parameters + ---------- + arys1, arys2, ... : array_like + One or more array-like sequences. Non-array inputs are converted to + arrays. Arrays that already have three or more dimensions are + preserved. + + Returns + ------- + res1, res2, ... : ndarray + An array, or tuple of arrays, each with ``a.ndim >= 3``. Copies are + avoided where possible, and views with three or more dimensions are + returned. For example, a 1-D array of shape ``(N,)`` becomes a view + of shape ``(1, N, 1)``, and a 2-D array of shape ``(M, N)`` becomes a + view of shape ``(M, N, 1)``. + + See Also + -------- + atleast_1d, atleast_2d + + Examples + -------- + >>> np.atleast_3d(3.0) + array([[[ 3.]]]) + + >>> x = np.arange(3.0) + >>> np.atleast_3d(x).shape + (1, 3, 1) + + >>> x = np.arange(12.0).reshape(4,3) + >>> np.atleast_3d(x).shape + (4, 3, 1) + >>> np.atleast_3d(x).base is x + True + + >>> for arr in np.atleast_3d([1, 2], [[1, 2]], [[[1, 2]]]): + ... print arr, arr.shape + ... + [[[1] + [2]]] (1, 2, 1) + [[[1] + [2]]] (1, 2, 1) + [[[1 2]]] (1, 1, 2) + + """ + res = [] + for ary in arys: + ary = asanyarray(ary) + if len(ary.shape) == 0: + result = ary.reshape(1,1,1) + elif len(ary.shape) == 1: + result = ary[newaxis,:,newaxis] + elif len(ary.shape) == 2: + result = ary[:,:,newaxis] + else: + result = ary + res.append(result) + if len(res) == 1: + return res[0] + else: + return res + +def vstack(tup): + """ + Stack arrays in sequence vertically (row wise). + + Take a sequence of arrays and stack them vertically to make a single + array. Rebuild arrays divided by `vsplit`. + + Parameters + ---------- + tup : sequence of ndarrays + Tuple containing arrays to be stacked. The arrays must have the same + shape along all but the first axis. + + Returns + ------- + stacked : ndarray + The array formed by stacking the given arrays. + + See Also + -------- + hstack : Stack arrays in sequence horizontally (column wise). + dstack : Stack arrays in sequence depth wise (along third dimension). + concatenate : Join a sequence of arrays together. + vsplit : Split array into a list of multiple sub-arrays vertically. + + Notes + ----- + Equivalent to ``np.concatenate(tup, axis=0)`` if `tup` contains arrays that + are at least 2-dimensional. + + Examples + -------- + >>> a = np.array([1, 2, 3]) + >>> b = np.array([2, 3, 4]) + >>> np.vstack((a,b)) + array([[1, 2, 3], + [2, 3, 4]]) + + >>> a = np.array([[1], [2], [3]]) + >>> b = np.array([[2], [3], [4]]) + >>> np.vstack((a,b)) + array([[1], + [2], + [3], + [2], + [3], + [4]]) + + """ + return _numpypy.concatenate(map(atleast_2d,tup),0) + +def hstack(tup): + """ + Stack arrays in sequence horizontally (column wise). + + Take a sequence of arrays and stack them horizontally to make + a single array. Rebuild arrays divided by `hsplit`. + + Parameters + ---------- + tup : sequence of ndarrays + All arrays must have the same shape along all but the second axis. + + Returns + ------- + stacked : ndarray + The array formed by stacking the given arrays. + + See Also + -------- + vstack : Stack arrays in sequence vertically (row wise). + dstack : Stack arrays in sequence depth wise (along third axis). + concatenate : Join a sequence of arrays together. + hsplit : Split array along second axis. + + Notes + ----- + Equivalent to ``np.concatenate(tup, axis=1)`` + + Examples + -------- + >>> a = np.array((1,2,3)) + >>> b = np.array((2,3,4)) + >>> np.hstack((a,b)) + array([1, 2, 3, 2, 3, 4]) + >>> a = np.array([[1],[2],[3]]) + >>> b = np.array([[2],[3],[4]]) + >>> np.hstack((a,b)) + array([[1, 2], + [2, 3], + [3, 4]]) + + """ + arrs = map(atleast_1d,tup) + # As a special case, dimension 0 of 1-dimensional arrays is "horizontal" + if arrs[0].ndim == 1: + return _numpypy.concatenate(arrs, 0) + else: + return _numpypy.concatenate(arrs, 1) + +def dstack(tup): + """ + Stack arrays in sequence depth wise (along third axis). + + Takes a sequence of arrays and stack them along the third axis + to make a single array. Rebuilds arrays divided by `dsplit`. + This is a simple way to stack 2D arrays (images) into a single + 3D array for processing. + + Parameters + ---------- + tup : sequence of arrays + Arrays to stack. All of them must have the same shape along all + but the third axis. + + Returns + ------- + stacked : ndarray + The array formed by stacking the given arrays. + + See Also + -------- + vstack : Stack along first axis. + hstack : Stack along second axis. + concatenate : Join arrays. + dsplit : Split array along third axis. + + Notes + ----- + Equivalent to ``np.concatenate(tup, axis=2)``. + + Examples + -------- + >>> a = np.array((1,2,3)) + >>> b = np.array((2,3,4)) + >>> np.dstack((a,b)) + array([[[1, 2], + [2, 3], + [3, 4]]]) + + >>> a = np.array([[1],[2],[3]]) + >>> b = np.array([[2],[3],[4]]) + >>> np.dstack((a,b)) + array([[[1, 2]], + [[2, 3]], + [[3, 4]]]) + + """ + return _numpypy.concatenate(map(atleast_3d,tup),2) diff --git a/lib_pypy/pypy_test/__init__.py b/lib_pypy/pypy_test/__init__.py deleted file mode 100644 --- a/lib_pypy/pypy_test/__init__.py +++ /dev/null @@ -1,1 +0,0 @@ -# diff --git a/lib_pypy/pypy_test/hack___pypy__.py b/lib_pypy/pypy_test/hack___pypy__.py deleted file mode 100644 --- a/lib_pypy/pypy_test/hack___pypy__.py +++ /dev/null @@ -1,9 +0,0 @@ -# here only to make test runs work even if not running on top of PyPy -import sys, new - -def builtinify(f): - return f - -pypy = new.module('__pypy__') -pypy.builtinify = builtinify -sys.modules.setdefault('__pypy__', pypy) diff --git a/lib_pypy/pypy_test/inprogress_test_binascii_extra.py b/lib_pypy/pypy_test/inprogress_test_binascii_extra.py deleted file mode 100644 --- a/lib_pypy/pypy_test/inprogress_test_binascii_extra.py +++ /dev/null @@ -1,19 +0,0 @@ -from __future__ import absolute_import -from lib_pypy import binascii - -def test_uu(): - assert binascii.b2a_uu('1234567') == "',3(S-#4V-P \n" - assert binascii.b2a_uu('123456789012345678901234567890123456789012345') == 'M,3(S-#4V-S at Y,#$R,S0U-C Author: mattip Branch: numpy-unify-methods Changeset: r61217:75b17b929bb1 Date: 2013-02-13 22:32 +0200 http://bitbucket.org/pypy/pypy/changeset/75b17b929bb1/ Log: ensure methods exists on classes From noreply at buildbot.pypy.org Wed Feb 13 23:05:24 2013 From: noreply at buildbot.pypy.org (mattip) Date: Wed, 13 Feb 2013 23:05:24 +0100 (CET) Subject: [pypy-commit] pypy numpy-unify-methods: a failing test Message-ID: <20130213220524.AE4F71C0EB1@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: numpy-unify-methods Changeset: r61218:1db349f824f6 Date: 2013-02-13 22:32 +0200 http://bitbucket.org/pypy/pypy/changeset/1db349f824f6/ Log: a failing test diff --git a/pypy/module/micronumpy/test/test_ufuncs.py b/pypy/module/micronumpy/test/test_ufuncs.py --- a/pypy/module/micronumpy/test/test_ufuncs.py +++ b/pypy/module/micronumpy/test/test_ufuncs.py @@ -249,13 +249,16 @@ assert (a == ref).all() def test_signbit(self): - from _numpypy import signbit + from _numpypy import signbit, add assert (signbit([0, 0.0, 1, 1.0, float('inf')]) == [False, False, False, False, False]).all() assert (signbit([-0, -0.0, -1, -1.0, float('-inf')]) == [False, True, True, True, True]).all() + a = add.identity + assert signbit(a) == False + skip('sign of nan is non-determinant') assert (signbit([float('nan'), float('-nan'), -float('nan')]) == [False, True, True]).all() From noreply at buildbot.pypy.org Wed Feb 13 23:05:25 2013 From: noreply at buildbot.pypy.org (mattip) Date: Wed, 13 Feb 2013 23:05:25 +0100 (CET) Subject: [pypy-commit] pypy numpy-unify-methods: test all single-arg utypes on scalars Message-ID: <20130213220525.DC2241C0EB1@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: numpy-unify-methods Changeset: r61219:79033551aea0 Date: 2013-02-13 22:58 +0200 http://bitbucket.org/pypy/pypy/changeset/79033551aea0/ Log: test all single-arg utypes on scalars diff --git a/pypy/module/micronumpy/test/test_ufuncs.py b/pypy/module/micronumpy/test/test_ufuncs.py --- a/pypy/module/micronumpy/test/test_ufuncs.py +++ b/pypy/module/micronumpy/test/test_ufuncs.py @@ -82,6 +82,19 @@ for i in range(3): assert min_c_b[i] == min(b[i], c) + def test_scalar(self): + import _numpypy as np + a = np.array(0,'int64') + missing = [] + for s in dir(np): + u = getattr(np, s) + if isinstance(u, np.ufunc) and u.nin < 2: + try: + u(a) + except: + missing.append(s) + assert len(missing) == 0 + def test_negative(self): from _numpypy import array, negative From noreply at buildbot.pypy.org Wed Feb 13 23:05:27 2013 From: noreply at buildbot.pypy.org (mattip) Date: Wed, 13 Feb 2013 23:05:27 +0100 (CET) Subject: [pypy-commit] pypy numpy-unify-methods: implement missing ufuncs for integers Message-ID: <20130213220527.188891C0EB1@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: numpy-unify-methods Changeset: r61220:219bbd8abdcd Date: 2013-02-13 23:28 +0200 http://bitbucket.org/pypy/pypy/changeset/219bbd8abdcd/ Log: implement missing ufuncs for integers diff --git a/pypy/module/micronumpy/types.py b/pypy/module/micronumpy/types.py --- a/pypy/module/micronumpy/types.py +++ b/pypy/module/micronumpy/types.py @@ -7,6 +7,7 @@ from pypy.objspace.std.floatobject import float2string from pypy.objspace.std.complexobject import str_format from rpython.rlib import rfloat, clibffi, rcomplex +from rpython.rlib.rarithmetic import maxint from rpython.rlib.rawstorage import (alloc_raw_storage, raw_storage_setitem, raw_storage_getitem) from rpython.rlib.objectmodel import specialize @@ -479,6 +480,17 @@ def invert(self, v): return ~v + @simple_unary_op + def reciprocal(self, v): + if v == 0: + # XXX good place to warn + return -maxint + return 1 / v + + @raw_unary_op + def signbit(self, v): + return v < 0 + class NonNativeInteger(NonNativePrimitive, Integer): _mixin_ = True From noreply at buildbot.pypy.org Wed Feb 13 23:05:28 2013 From: noreply at buildbot.pypy.org (mattip) Date: Wed, 13 Feb 2013 23:05:28 +0100 (CET) Subject: [pypy-commit] pypy numpy-unify-methods: test for other base numerical types Message-ID: <20130213220528.429D91C0EB1@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: numpy-unify-methods Changeset: r61221:5af3b14a4653 Date: 2013-02-13 23:55 +0200 http://bitbucket.org/pypy/pypy/changeset/5af3b14a4653/ Log: test for other base numerical types diff --git a/pypy/module/micronumpy/test/test_ufuncs.py b/pypy/module/micronumpy/test/test_ufuncs.py --- a/pypy/module/micronumpy/test/test_ufuncs.py +++ b/pypy/module/micronumpy/test/test_ufuncs.py @@ -84,16 +84,35 @@ def test_scalar(self): import _numpypy as np + def missing_ufuncs(v): + missing = [] + i = 0 + for s in dir(np): + u = getattr(np, s) + if isinstance(u, np.ufunc) and u.nin < 2: + try: + u(a) + except TypeError, e: + #assert e.message.startswith('ufunc') + missing.append(s) + i+= 1 + assert i == 47 #numpy 1.7.0 + return missing a = np.array(0,'int64') - missing = [] - for s in dir(np): - u = getattr(np, s) - if isinstance(u, np.ufunc) and u.nin < 2: - try: - u(a) - except: - missing.append(s) + missing = missing_ufuncs(a) assert len(missing) == 0 + a = np.array(True,'bool') + missing = missing_ufuncs(a) + assert len(missing) == 0 or missing == ['sign'] # numpy 1.7.0 + a = np.array(1.0,'float') + missing = missing_ufuncs(a) + assert len(missing) == 2 and set(missing) == set(['bitwise_not', 'invert']) + a = np.array(1.0,'complex') + missing = missing_ufuncs(a) + assert len(missing) == 14 and set(missing) == \ + set(['bitwise_not', 'ceil', 'deg2rad', 'degrees', 'fabs', 'floor', + 'rad2deg', 'invert', 'spacing', 'radians', 'frexp', 'signbit', + 'modf', 'trunc']) def test_negative(self): from _numpypy import array, negative From noreply at buildbot.pypy.org Wed Feb 13 23:05:29 2013 From: noreply at buildbot.pypy.org (mattip) Date: Wed, 13 Feb 2013 23:05:29 +0100 (CET) Subject: [pypy-commit] pypy numpy-unify-methods: flesh out Bool Message-ID: <20130213220529.7BE1A1C0EB1@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: numpy-unify-methods Changeset: r61222:a7610da341a2 Date: 2013-02-14 00:00 +0200 http://bitbucket.org/pypy/pypy/changeset/a7610da341a2/ Log: flesh out Bool diff --git a/pypy/module/micronumpy/types.py b/pypy/module/micronumpy/types.py --- a/pypy/module/micronumpy/types.py +++ b/pypy/module/micronumpy/types.py @@ -376,6 +376,20 @@ def invert(self, v): return ~v + @raw_unary_op + def isfinite(self, v): + return True + + @raw_unary_op + def signbit(self, v): + return False + + @simple_unary_op + def reciprocal(self, v): + if v: + return 1 + return 0 + NonNativeBool = Bool class Integer(Primitive): From noreply at buildbot.pypy.org Wed Feb 13 23:12:32 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Wed, 13 Feb 2013 23:12:32 +0100 (CET) Subject: [pypy-commit] pypy py3k: merge default Message-ID: <20130213221232.9BB3C1C3C1D@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61223:7e444a14b5f8 Date: 2013-02-13 14:10 -0800 http://bitbucket.org/pypy/pypy/changeset/7e444a14b5f8/ Log: merge default diff --git a/lib-python/2.7/test/test_generators.py b/lib-python/2.7/test/test_generators.py --- a/lib-python/2.7/test/test_generators.py +++ b/lib-python/2.7/test/test_generators.py @@ -1501,9 +1501,7 @@ """ coroutine_tests = """\ -A helper function to call gc.collect() without printing ->>> import gc ->>> def gc_collect(): gc.collect() +>>> from test.test_support import gc_collect Sending a value into a started generator: @@ -1823,8 +1821,7 @@ references. We add it to the standard suite so the routine refleak-tests would trigger if it starts being uncleanable again. ->>> import gc ->>> def gc_collect(): gc.collect() +>>> from test.test_support import gc_collect >>> import itertools >>> def leak(): diff --git a/lib-python/2.7/urllib.py b/lib-python/2.7/urllib.py --- a/lib-python/2.7/urllib.py +++ b/lib-python/2.7/urllib.py @@ -1205,15 +1205,17 @@ # fastpath if len(res) == 1: return s - s = res[0] - for item in res[1:]: + res_list = [res[0]] + for j in xrange(1, len(res)): + item = res[j] try: - s += _hextochr[item[:2]] + item[2:] + x = _hextochr[item[:2]] + item[2:] except KeyError: - s += '%' + item + x = '%' + item except UnicodeDecodeError: - s += unichr(int(item[:2], 16)) + item[2:] - return s + x = unichr(int(item[:2], 16)) + item[2:] + res_list.append(x) + return ''.join(res_list) def unquote_plus(s): """unquote('%7e/abc+def') -> '~/abc def'""" diff --git a/lib-python/2.7/urlparse.py b/lib-python/2.7/urlparse.py --- a/lib-python/2.7/urlparse.py +++ b/lib-python/2.7/urlparse.py @@ -321,15 +321,17 @@ # fastpath if len(res) == 1: return s - s = res[0] - for item in res[1:]: + res_list = [res[0]] + for j in xrange(1, len(res)): + item = res[j] try: - s += _hextochr[item[:2]] + item[2:] + x = _hextochr[item[:2]] + item[2:] except KeyError: - s += '%' + item + x = '%' + item except UnicodeDecodeError: - s += unichr(int(item[:2], 16)) + item[2:] - return s + x = unichr(int(item[:2], 16)) + item[2:] + res_list.append(x) + return ''.join(res_list) def parse_qs(qs, keep_blank_values=0, strict_parsing=0): """Parse a query given as a string argument. diff --git a/lib-python/conftest.py b/lib-python/conftest.py --- a/lib-python/conftest.py +++ b/lib-python/conftest.py @@ -248,7 +248,7 @@ RegrTest('test_inspect.py'), RegrTest('test_int.py', core=True), RegrTest('test_int_literal.py', core=True), - RegrTest('test_io.py', core=True), + RegrTest('test_io.py', core=True, usemodules='array binascii'), RegrTest('test_ioctl.py'), RegrTest('test_isinstance.py', core=True), RegrTest('test_iter.py', core=True), diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst --- a/pypy/doc/whatsnew-head.rst +++ b/pypy/doc/whatsnew-head.rst @@ -58,3 +58,6 @@ .. branch: cleanup-tests Consolidated the lib_pypy/pypy_test and pypy/module/test_lib_pypy tests into +one directory for reduced confusion and so they all run nightly. + +.. branch: unquote-faster +.. branch: urlparse-unquote-faster diff --git a/pypy/interpreter/eval.py b/pypy/interpreter/eval.py --- a/pypy/interpreter/eval.py +++ b/pypy/interpreter/eval.py @@ -28,7 +28,6 @@ def exec_code(self, space, w_globals, w_locals): "Implements the 'exec' statement." # this should be on PyCode? - space.possibly_convert_to_celldict(w_globals) frame = space.createframe(self, w_globals, None) frame.setdictscope(w_locals) return frame.run() diff --git a/pypy/module/_cffi_backend/__init__.py b/pypy/module/_cffi_backend/__init__.py --- a/pypy/module/_cffi_backend/__init__.py +++ b/pypy/module/_cffi_backend/__init__.py @@ -7,7 +7,7 @@ appleveldefs = { } interpleveldefs = { - '__version__': 'space.wrap("0.4")', + '__version__': 'space.wrap("0.6")', 'load_library': 'libraryobj.load_library', diff --git a/pypy/module/_cffi_backend/cdataobj.py b/pypy/module/_cffi_backend/cdataobj.py --- a/pypy/module/_cffi_backend/cdataobj.py +++ b/pypy/module/_cffi_backend/cdataobj.py @@ -119,9 +119,12 @@ def getitem(self, w_index): space = self.space - i = space.getindex_w(w_index, space.w_IndexError) - ctype = self.ctype._check_subscript_index(self, i) - w_o = self._do_getitem(ctype, i) + if space.isinstance_w(w_index, space.w_slice): + w_o = self._do_getslice(w_index) + else: + i = space.getindex_w(w_index, space.w_IndexError) + ctype = self.ctype._check_subscript_index(self, i) + w_o = self._do_getitem(ctype, i) keepalive_until_here(self) return w_o @@ -132,14 +135,100 @@ def setitem(self, w_index, w_value): space = self.space - i = space.getindex_w(w_index, space.w_IndexError) - ctype = self.ctype._check_subscript_index(self, i) - ctitem = ctype.ctitem - ctitem.convert_from_object( - rffi.ptradd(self._cdata, i * ctitem.size), - w_value) + if space.isinstance_w(w_index, space.w_slice): + self._do_setslice(w_index, w_value) + else: + i = space.getindex_w(w_index, space.w_IndexError) + ctype = self.ctype._check_subscript_index(self, i) + ctitem = ctype.ctitem + ctitem.convert_from_object( + rffi.ptradd(self._cdata, i * ctitem.size), + w_value) keepalive_until_here(self) + def _do_getslicearg(self, w_slice): + from pypy.module._cffi_backend.ctypeptr import W_CTypePointer + from pypy.objspace.std.sliceobject import W_SliceObject + assert isinstance(w_slice, W_SliceObject) + space = self.space + # + if space.is_w(w_slice.w_start, space.w_None): + raise OperationError(space.w_IndexError, + space.wrap("slice start must be specified")) + start = space.int_w(w_slice.w_start) + # + if space.is_w(w_slice.w_stop, space.w_None): + raise OperationError(space.w_IndexError, + space.wrap("slice stop must be specified")) + stop = space.int_w(w_slice.w_stop) + # + if not space.is_w(w_slice.w_step, space.w_None): + raise OperationError(space.w_IndexError, + space.wrap("slice with step not supported")) + # + if start > stop: + raise OperationError(space.w_IndexError, + space.wrap("slice start > stop")) + # + ctype = self.ctype._check_slice_index(self, start, stop) + assert isinstance(ctype, W_CTypePointer) + # + return ctype, start, stop - start + + def _do_getslice(self, w_slice): + ctptr, start, length = self._do_getslicearg(w_slice) + # + space = self.space + ctarray = ctptr.cache_array_type + if ctarray is None: + from pypy.module._cffi_backend import newtype + ctarray = newtype.new_array_type(space, ctptr, space.w_None) + ctptr.cache_array_type = ctarray + # + p = rffi.ptradd(self._cdata, start * ctarray.ctitem.size) + return W_CDataSliced(space, p, ctarray, length) + + def _do_setslice(self, w_slice, w_value): + ctptr, start, length = self._do_getslicearg(w_slice) + ctitem = ctptr.ctitem + ctitemsize = ctitem.size + cdata = rffi.ptradd(self._cdata, start * ctitemsize) + # + if isinstance(w_value, W_CData): + from pypy.module._cffi_backend import ctypearray + ctv = w_value.ctype + if (isinstance(ctv, ctypearray.W_CTypeArray) and + ctv.ctitem is ctitem and + w_value.get_array_length() == length): + # fast path: copying from exactly the correct type + s = w_value._cdata + for i in range(ctitemsize * length): + cdata[i] = s[i] + keepalive_until_here(w_value) + return + # + space = self.space + w_iter = space.iter(w_value) + for i in range(length): + try: + w_item = space.next(w_iter) + except OperationError, e: + if not e.match(space, space.w_StopIteration): + raise + raise operationerrfmt(space.w_ValueError, + "need %d values to unpack, got %d", + length, i) + ctitem.convert_from_object(cdata, w_item) + cdata = rffi.ptradd(cdata, ctitemsize) + try: + space.next(w_iter) + except OperationError, e: + if not e.match(space, space.w_StopIteration): + raise + else: + raise operationerrfmt(space.w_ValueError, + "got more than %d values to unpack", length) + def _add_or_sub(self, w_other, sign): space = self.space i = sign * space.getindex_w(w_other, space.w_OverflowError) @@ -281,6 +370,22 @@ return self.structobj +class W_CDataSliced(W_CData): + """Subclass with an explicit length, for slices.""" + _attrs_ = ['length'] + _immutable_fields_ = ['length'] + + def __init__(self, space, cdata, ctype, length): + W_CData.__init__(self, space, cdata, ctype) + self.length = length + + def _repr_extra(self): + return "sliced length %d" % (self.length,) + + def get_array_length(self): + return self.length + + W_CData.typedef = TypeDef( 'CData', __module__ = '_cffi_backend', diff --git a/pypy/module/_cffi_backend/ctypearray.py b/pypy/module/_cffi_backend/ctypearray.py --- a/pypy/module/_cffi_backend/ctypearray.py +++ b/pypy/module/_cffi_backend/ctypearray.py @@ -77,6 +77,17 @@ self.name, i, w_cdata.get_array_length()) return self + def _check_slice_index(self, w_cdata, start, stop): + space = self.space + if start < 0: + raise OperationError(space.w_IndexError, + space.wrap("negative index not supported")) + if stop > w_cdata.get_array_length(): + raise operationerrfmt(space.w_IndexError, + "index too large (expected %d <= %d)", + stop, w_cdata.get_array_length()) + return self.ctptr + def convert_from_object(self, cdata, w_ob): self.convert_array_from_object(cdata, w_ob) diff --git a/pypy/module/_cffi_backend/ctypeenum.py b/pypy/module/_cffi_backend/ctypeenum.py --- a/pypy/module/_cffi_backend/ctypeenum.py +++ b/pypy/module/_cffi_backend/ctypeenum.py @@ -6,23 +6,19 @@ from rpython.rtyper.lltypesystem import rffi from rpython.rlib.rarithmetic import intmask, r_ulonglong from rpython.rlib.objectmodel import keepalive_until_here +from rpython.rlib.objectmodel import specialize from pypy.module._cffi_backend.ctypeprim import W_CTypePrimitiveSigned +from pypy.module._cffi_backend.ctypeprim import W_CTypePrimitiveUnsigned from pypy.module._cffi_backend import misc -class W_CTypeEnum(W_CTypePrimitiveSigned): - _attrs_ = ['enumerators2values', 'enumvalues2erators'] - _immutable_fields_ = ['enumerators2values', 'enumvalues2erators'] - kind = "enum" +class _Mixin_Enum(object): + _mixin_ = True - def __init__(self, space, name, enumerators, enumvalues): - from pypy.module._cffi_backend.newtype import alignment + def __init__(self, space, name, size, align, enumerators, enumvalues): name = "enum " + name - size = rffi.sizeof(rffi.INT) - align = alignment(rffi.INT) - W_CTypePrimitiveSigned.__init__(self, space, size, - name, len(name), align) + self._super.__init__(self, space, size, name, len(name), align) self.enumerators2values = {} # str -> int self.enumvalues2erators = {} # int -> str for i in range(len(enumerators)-1, -1, -1): @@ -44,55 +40,46 @@ space.setitem(w_dct, space.wrap(enumerator), space.wrap(enumvalue)) return w_dct - return W_CTypePrimitiveSigned._fget(self, attrchar) + return self._super._fget(self, attrchar) + + def extra_repr(self, cdata): + value = self._get_value(cdata) + try: + s = self.enumvalues2erators[value] + except KeyError: + return str(value) + else: + return '%s: %s' % (value, s) def string(self, cdataobj, maxlen): - w_result = self.convert_to_object(cdataobj._cdata) + value = self._get_value(cdataobj._cdata) keepalive_until_here(cdataobj) - return w_result + try: + s = self.enumvalues2erators[value] + except KeyError: + s = str(value) + return self.space.wrap(s) - def convert_to_object(self, cdata): - value = misc.read_raw_long_data(cdata, self.size) - try: - enumerator = self.enumvalues2erators[value] - except KeyError: - enumerator = '#%d' % (value,) - return self.space.wrap(enumerator) - def convert_from_object(self, cdata, w_ob): - space = self.space - try: - return W_CTypePrimitiveSigned.convert_from_object(self, cdata, - w_ob) - except OperationError, e: - if not e.match(space, space.w_TypeError): - raise - if space.isinstance_w(w_ob, space.w_unicode): - value = self.convert_enum_string_to_int(space.str_w(w_ob)) - value = r_ulonglong(value) - misc.write_raw_integer_data(cdata, value, self.size) - else: - raise self._convert_error("str or int", w_ob) +class W_CTypeEnumSigned(_Mixin_Enum, W_CTypePrimitiveSigned): + _attrs_ = ['enumerators2values', 'enumvalues2erators'] + _immutable_fields_ = ['enumerators2values', 'enumvalues2erators'] + kind = "enum" + _super = W_CTypePrimitiveSigned - def cast_unicode(self, w_ob): - space = self.space - return self.convert_enum_string_to_int(space.str_w(w_ob)) + def _get_value(self, cdata): + # returns a signed long + assert self.value_fits_long + return misc.read_raw_long_data(cdata, self.size) - def cast_unicode(self, w_ob): - return self.cast_str(w_ob) - def convert_enum_string_to_int(self, s): - space = self.space - if s.startswith('#'): - try: - return int(s[1:]) - except ValueError: - raise OperationError(space.w_ValueError, - space.wrap("invalid literal after '#'")) - else: - try: - return self.enumerators2values[s] - except KeyError: - raise operationerrfmt(space.w_ValueError, - "'%s' is not an enumerator for %s", - s, self.name) +class W_CTypeEnumUnsigned(_Mixin_Enum, W_CTypePrimitiveUnsigned): + _attrs_ = ['enumerators2values', 'enumvalues2erators'] + _immutable_fields_ = ['enumerators2values', 'enumvalues2erators'] + kind = "enum" + _super = W_CTypePrimitiveUnsigned + + def _get_value(self, cdata): + # returns an unsigned long + assert self.value_fits_ulong + return misc.read_raw_ulong_data(cdata, self.size) diff --git a/pypy/module/_cffi_backend/ctypeobj.py b/pypy/module/_cffi_backend/ctypeobj.py --- a/pypy/module/_cffi_backend/ctypeobj.py +++ b/pypy/module/_cffi_backend/ctypeobj.py @@ -93,12 +93,18 @@ "not %s", self.name, expected, space.type(w_got).getname(space)) - def _check_subscript_index(self, w_cdata, i): + def _cannot_index(self): space = self.space raise operationerrfmt(space.w_TypeError, "cdata of type '%s' cannot be indexed", self.name) + def _check_subscript_index(self, w_cdata, i): + raise self._cannot_index() + + def _check_slice_index(self, w_cdata, start, stop): + raise self._cannot_index() + def string(self, cdataobj, maxlen): space = self.space raise operationerrfmt(space.w_TypeError, diff --git a/pypy/module/_cffi_backend/ctypeprim.py b/pypy/module/_cffi_backend/ctypeprim.py --- a/pypy/module/_cffi_backend/ctypeprim.py +++ b/pypy/module/_cffi_backend/ctypeprim.py @@ -171,9 +171,7 @@ self.vrangemax = (r_uint(1) << sh) - 1 def int(self, cdata): - # enums: really call convert_to_object() just below, - # and not the one overridden in W_CTypeEnum. - return W_CTypePrimitiveSigned.convert_to_object(self, cdata) + return self.convert_to_object(cdata) def convert_to_object(self, cdata): if self.value_fits_long: diff --git a/pypy/module/_cffi_backend/ctypeptr.py b/pypy/module/_cffi_backend/ctypeptr.py --- a/pypy/module/_cffi_backend/ctypeptr.py +++ b/pypy/module/_cffi_backend/ctypeptr.py @@ -174,9 +174,10 @@ class W_CTypePointer(W_CTypePtrBase): - _attrs_ = ['is_file'] - _immutable_fields_ = ['is_file'] + _attrs_ = ['is_file', 'cache_array_type'] + _immutable_fields_ = ['is_file', 'cache_array_type?'] kind = "pointer" + cache_array_type = None def __init__(self, space, ctitem): from pypy.module._cffi_backend import ctypearray @@ -185,7 +186,8 @@ extra = "(*)" # obscure case: see test_array_add else: extra = " *" - self.is_file = (ctitem.name == "struct _IO_FILE") + self.is_file = (ctitem.name == "struct _IO_FILE" or + ctitem.name == "struct $FILE") W_CTypePtrBase.__init__(self, space, size, extra, 2, ctitem) def newp(self, w_init): @@ -224,6 +226,9 @@ self.name) return self + def _check_slice_index(self, w_cdata, start, stop): + return self + def add(self, cdata, i): space = self.space ctitem = self.ctitem diff --git a/pypy/module/_cffi_backend/newtype.py b/pypy/module/_cffi_backend/newtype.py --- a/pypy/module/_cffi_backend/newtype.py +++ b/pypy/module/_cffi_backend/newtype.py @@ -1,7 +1,8 @@ from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.gateway import unwrap_spec from rpython.rtyper.lltypesystem import lltype, rffi -from rpython.rlib.rarithmetic import ovfcheck +from rpython.rlib.rarithmetic import ovfcheck, r_uint, intmask +from rpython.rlib.rarithmetic import most_neg_value_of, most_pos_value_of from rpython.rlib.objectmodel import specialize from pypy.module._cffi_backend import ctypeobj, ctypeprim, ctypeptr, ctypearray @@ -271,18 +272,57 @@ raise OperationError(space.w_ValueError, space.wrap("tuple args must have the same size")) enumerators = [space.str_w(w) for w in enumerators_w] - enumvalues = [] + # + smallest_value = 0 + largest_value = r_uint(0) + i = 0 try: for w in enumvalues_w: - enumvalues.append(space.c_int_w(w)) + try: + ulvalue = space.uint_w(w) + except OperationError, e: + if not e.match(space, space.w_ValueError): + raise + lvalue = space.int_w(w) + if lvalue < smallest_value: + smallest_value = lvalue + else: + if ulvalue > largest_value: + largest_value = ulvalue + i += 1 # 'i' is here for the exception case, see below except OperationError, e: if not e.match(space, space.w_OverflowError): raise - i = len(enumvalues) raise operationerrfmt(space.w_OverflowError, - "enum '%s' declaration for '%s' does not fit an int", + "enum '%s' declaration for '%s' does not fit " + "a long or unsigned long", name, enumerators[i]) - ctype = ctypeenum.W_CTypeEnum(space, name, enumerators, enumvalues) + # + if smallest_value < 0: + if (smallest_value >= intmask(most_neg_value_of(rffi.INT)) and + largest_value <= r_uint(most_pos_value_of(rffi.INT))): + size = rffi.sizeof(rffi.INT) + align = alignment(rffi.INT) + elif largest_value <= r_uint(most_pos_value_of(rffi.LONG)): + size = rffi.sizeof(rffi.LONG) + align = alignment(rffi.LONG) + else: + raise operationerrfmt(space.w_OverflowError, + "enum '%s' values don't all fit into either 'long' " + "or 'unsigned long'", name) + enumvalues = [space.int_w(w) for w in enumvalues_w] + ctype = ctypeenum.W_CTypeEnumSigned(space, name, size, align, + enumerators, enumvalues) + else: + if largest_value <= r_uint(most_pos_value_of(rffi.UINT)): + size = rffi.sizeof(rffi.UINT) + align = alignment(rffi.UINT) + else: + size = rffi.sizeof(rffi.ULONG) + align = alignment(rffi.ULONG) + enumvalues = [space.uint_w(w) for w in enumvalues_w] + ctype = ctypeenum.W_CTypeEnumUnsigned(space, name, size, align, + enumerators, enumvalues) return ctype # ____________________________________________________________ @@ -302,8 +342,13 @@ # if ((fresult.size < 0 and not isinstance(fresult, ctypevoid.W_CTypeVoid)) or isinstance(fresult, ctypearray.W_CTypeArray)): - raise operationerrfmt(space.w_TypeError, - "invalid result type: '%s'", fresult.name) + if (isinstance(fresult, ctypestruct.W_CTypeStructOrUnion) and + fresult.size < 0): + raise operationerrfmt(space.w_TypeError, + "result type '%s' is opaque", fresult.name) + else: + raise operationerrfmt(space.w_TypeError, + "invalid result type: '%s'", fresult.name) # fct = ctypefunc.W_CTypeFunc(space, fargs, fresult, ellipsis) return fct diff --git a/pypy/module/_cffi_backend/test/_backend_test_c.py b/pypy/module/_cffi_backend/test/_backend_test_c.py --- a/pypy/module/_cffi_backend/test/_backend_test_c.py +++ b/pypy/module/_cffi_backend/test/_backend_test_c.py @@ -1284,22 +1284,24 @@ def test_cast_to_enum(): BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, -20)) e = cast(BEnum, 0) - assert repr(e) == "" + assert repr(e) == "" + assert repr(cast(BEnum, -42)) == "" + assert repr(cast(BEnum, -20)) == "" assert string(e) == 'def' assert string(cast(BEnum, -20)) == 'ab' - assert string(cast(BEnum, 'c')) == 'c' - assert int(cast(BEnum, 'c')) == 1 - assert int(cast(BEnum, 'def')) == 0 + assert int(cast(BEnum, 1)) == 1 + assert int(cast(BEnum, 0)) == 0 assert int(cast(BEnum, -242 + 2**128)) == -242 - assert string(cast(BEnum, -242 + 2**128)) == '#-242' - assert string(cast(BEnum, '#-20')) == 'ab' - assert repr(cast(BEnum, '#-20')) == "" - assert repr(cast(BEnum, '#-21')) == "" + assert string(cast(BEnum, -242 + 2**128)) == '-242' + # + BEnum = new_enum_type("bar", ('def', 'c', 'ab'), (0, 1, 20)) + e = cast(BEnum, -1) + assert repr(e) == "" # unsigned int def test_enum_with_non_injective_mapping(): BEnum = new_enum_type("foo", ('ab', 'cd'), (7, 7)) e = cast(BEnum, 7) - assert repr(e) == "" + assert repr(e) == "" assert string(e) == 'ab' def test_enum_in_struct(): @@ -1308,36 +1310,112 @@ BStructPtr = new_pointer_type(BStruct) complete_struct_or_union(BStruct, [('a1', BEnum, -1)]) p = newp(BStructPtr, [-20]) - assert p.a1 == "ab" - p = newp(BStructPtr, ["c"]) - assert p.a1 == "c" + assert p.a1 == -20 + p = newp(BStructPtr, [12]) + assert p.a1 == 12 e = py.test.raises(TypeError, newp, BStructPtr, [None]) - assert "must be a str or int, not NoneType" in str(e.value) + assert ("an integer is required" in str(e.value) or + "unsupported operand type for int(): 'NoneType'" in str(e.value)) #PyPy + py.test.raises(TypeError, 'p.a1 = "def"') if sys.version_info < (3,): - p.a1 = unicode("def") - assert p.a1 == "def" and type(p.a1) is str - py.test.raises(UnicodeEncodeError, "p.a1 = unichr(1234)") BEnum2 = new_enum_type(unicode("foo"), (unicode('abc'),), (5,)) - assert string(cast(BEnum2, unicode('abc'))) == 'abc' + assert string(cast(BEnum2, 5)) == 'abc' + assert type(string(cast(BEnum2, 5))) is str def test_enum_overflow(): - for ovf in (2**63, -2**63-1, 2**31, -2**31-1): - e = py.test.raises(OverflowError, new_enum_type, "foo", ('a', 'b'), - (5, ovf)) - assert str(e.value) == ( - "enum 'foo' declaration for 'b' does not fit an int") + max_uint = 2 ** (size_of_int()*8) - 1 + max_int = max_uint // 2 + max_ulong = 2 ** (size_of_long()*8) - 1 + max_long = max_ulong // 2 + # 'unsigned int' case + e = new_enum_type("foo", ('a', 'b'), (0, 3)) + assert sizeof(e) == size_of_int() + assert int(cast(e, -1)) == max_uint # 'e' is unsigned + e = new_enum_type("foo", ('a', 'b'), (0, max_uint)) + assert sizeof(e) == size_of_int() + assert int(cast(e, -1)) == max_uint + assert e.elements == {0: 'a', max_uint: 'b'} + assert e.relements == {'a': 0, 'b': max_uint} + # 'signed int' case + e = new_enum_type("foo", ('a', 'b'), (-1, max_int)) + assert sizeof(e) == size_of_int() + assert int(cast(e, -1)) == -1 + assert e.elements == {-1: 'a', max_int: 'b'} + assert e.relements == {'a': -1, 'b': max_int} + e = new_enum_type("foo", ('a', 'b'), (-max_int-1, max_int)) + assert sizeof(e) == size_of_int() + assert int(cast(e, -1)) == -1 + assert e.elements == {-max_int-1: 'a', max_int: 'b'} + assert e.relements == {'a': -max_int-1, 'b': max_int} + # 'unsigned long' case + e = new_enum_type("foo", ('a', 'b'), (0, max_long)) + assert sizeof(e) == size_of_long() + assert int(cast(e, -1)) == max_ulong # 'e' is unsigned + e = new_enum_type("foo", ('a', 'b'), (0, max_ulong)) + assert sizeof(e) == size_of_long() + assert int(cast(e, -1)) == max_ulong + assert e.elements == {0: 'a', max_ulong: 'b'} + assert e.relements == {'a': 0, 'b': max_ulong} + # 'signed long' case + e = new_enum_type("foo", ('a', 'b'), (-1, max_long)) + assert sizeof(e) == size_of_long() + assert int(cast(e, -1)) == -1 + assert e.elements == {-1: 'a', max_long: 'b'} + assert e.relements == {'a': -1, 'b': max_long} + e = new_enum_type("foo", ('a', 'b'), (-max_long-1, max_long)) + assert sizeof(e) == size_of_long() + assert int(cast(e, -1)) == -1 + assert e.elements == {-max_long-1: 'a', max_long: 'b'} + assert e.relements == {'a': -max_long-1, 'b': max_long} + # overflow: both negative items and items larger than max_long + e = py.test.raises(OverflowError, new_enum_type, "foo", ('a', 'b'), + (-1, max_long + 1)) + assert str(e.value) == ( + "enum 'foo' values don't all fit into either 'long' " + "or 'unsigned long'") + # overflow: items smaller than -max_long-1 + e = py.test.raises(OverflowError, new_enum_type, "foo", ('a', 'b'), + (-max_long-2, 5)) + assert str(e.value) == ( + "enum 'foo' declaration for 'a' does not fit a long or unsigned long") + # overflow: items larger than max_ulong + e = py.test.raises(OverflowError, new_enum_type, "foo", ('a', 'b'), + (5, max_ulong+1)) + assert str(e.value) == ( + "enum 'foo' declaration for 'b' does not fit a long or unsigned long") def test_callback_returning_enum(): BInt = new_primitive_type("int") BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, -20)) def cb(n): - return '#%d' % n + if n & 1: + return cast(BEnum, n) + else: + return n BFunc = new_function_type((BInt,), BEnum) f = callback(BFunc, cb) - assert f(0) == 'def' - assert f(1) == 'c' - assert f(-20) == 'ab' - assert f(20) == '#20' + assert f(0) == 0 + assert f(1) == 1 + assert f(-20) == -20 + assert f(20) == 20 + assert f(21) == 21 + +def test_callback_returning_enum_unsigned(): + BInt = new_primitive_type("int") + BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, 20)) + def cb(n): + print n + if n & 1: + return cast(BEnum, n) + else: + return n + BFunc = new_function_type((BInt,), BEnum) + f = callback(BFunc, cb) + assert f(0) == 0 + assert f(1) == 1 + assert f(-21) == 2**32 - 21 + assert f(20) == 20 + assert f(21) == 21 def test_callback_returning_char(): BInt = new_primitive_type("int") @@ -2497,7 +2575,7 @@ if sys.platform == "win32": py.test.skip("testing FILE not implemented") # - BFILE = new_struct_type("_IO_FILE") + BFILE = new_struct_type("$FILE") BFILEP = new_pointer_type(BFILE) BChar = new_primitive_type("char") BCharP = new_pointer_type(BChar) @@ -2566,3 +2644,91 @@ for i in range(20): buf = buflist[i] assert buf[:] == str2bytes("hi there %d\x00" % i) + +def test_slice(): + BIntP = new_pointer_type(new_primitive_type("int")) + BIntArray = new_array_type(BIntP, None) + c = newp(BIntArray, 5) + assert len(c) == 5 + assert repr(c) == "" + d = c[1:4] + assert len(d) == 3 + assert repr(d) == "" + d[0] = 123 + d[2] = 456 + assert c[1] == 123 + assert c[3] == 456 + assert d[2] == 456 + py.test.raises(IndexError, "d[3]") + py.test.raises(IndexError, "d[-1]") + +def test_slice_ptr(): + BIntP = new_pointer_type(new_primitive_type("int")) + BIntArray = new_array_type(BIntP, None) + c = newp(BIntArray, 5) + d = (c+1)[0:2] + assert len(d) == 2 + assert repr(d) == "" + d[1] += 50 + assert c[2] == 50 + +def test_slice_array_checkbounds(): + BIntP = new_pointer_type(new_primitive_type("int")) + BIntArray = new_array_type(BIntP, None) + c = newp(BIntArray, 5) + c[0:5] + assert len(c[5:5]) == 0 + py.test.raises(IndexError, "c[-1:1]") + cp = c + 0 + cp[-1:1] + +def test_nonstandard_slice(): + BIntP = new_pointer_type(new_primitive_type("int")) + BIntArray = new_array_type(BIntP, None) + c = newp(BIntArray, 5) + e = py.test.raises(IndexError, "c[:5]") + assert str(e.value) == "slice start must be specified" + e = py.test.raises(IndexError, "c[4:]") + assert str(e.value) == "slice stop must be specified" + e = py.test.raises(IndexError, "c[1:2:3]") + assert str(e.value) == "slice with step not supported" + e = py.test.raises(IndexError, "c[1:2:1]") + assert str(e.value) == "slice with step not supported" + e = py.test.raises(IndexError, "c[4:2]") + assert str(e.value) == "slice start > stop" + e = py.test.raises(IndexError, "c[6:6]") + assert str(e.value) == "index too large (expected 6 <= 5)" + +def test_setslice(): + BIntP = new_pointer_type(new_primitive_type("int")) + BIntArray = new_array_type(BIntP, None) + c = newp(BIntArray, 5) + c[1:3] = [100, 200] + assert list(c) == [0, 100, 200, 0, 0] + cp = c + 3 + cp[-1:1] = [300, 400] + assert list(c) == [0, 100, 300, 400, 0] + cp[-1:1] = iter([500, 600]) + assert list(c) == [0, 100, 500, 600, 0] + py.test.raises(ValueError, "cp[-1:1] = [1000]") + assert list(c) == [0, 100, 1000, 600, 0] + py.test.raises(ValueError, "cp[-1:1] = (700, 800, 900)") + assert list(c) == [0, 100, 700, 800, 0] + +def test_setslice_array(): + BIntP = new_pointer_type(new_primitive_type("int")) + BIntArray = new_array_type(BIntP, None) + c = newp(BIntArray, 5) + d = newp(BIntArray, [10, 20, 30]) + c[1:4] = d + assert list(c) == [0, 10, 20, 30, 0] + # + BShortP = new_pointer_type(new_primitive_type("short")) + BShortArray = new_array_type(BShortP, None) + d = newp(BShortArray, [40, 50]) + c[1:3] = d + assert list(c) == [0, 40, 50, 30, 0] + +def test_version(): + # this test is here mostly for PyPy + assert __version__ == "0.6" diff --git a/pypy/module/_io/test/test_bufferedio.py b/pypy/module/_io/test/test_bufferedio.py --- a/pypy/module/_io/test/test_bufferedio.py +++ b/pypy/module/_io/test/test_bufferedio.py @@ -559,6 +559,14 @@ f.seek(0) assert f.read() == b'a\nbxxxx' + def test_simple_read_after_write(self): + import _io + raw = _io.FileIO(self.tmpfile, 'wb+') + f = _io.BufferedRandom(raw) + f.write('abc') + f.seek(0) + assert f.read() == 'abc' + def test_write_rewind_write(self): # Various combinations of reading / writing / seeking # backwards / writing again diff --git a/pypy/module/micronumpy/interp_boxes.py b/pypy/module/micronumpy/interp_boxes.py --- a/pypy/module/micronumpy/interp_boxes.py +++ b/pypy/module/micronumpy/interp_boxes.py @@ -287,11 +287,11 @@ for i in range(len(arg)): arr.storage[i] = arg[i] return W_StringBox(arr, 0, arr.dtype) - + def convert_to(self, dtype): from pypy.module.micronumpy import types assert isinstance(dtype.itemtype, types.StringType) - return self + return self class W_UnicodeBox(W_CharacterBox): def descr__new__unicode_box(space, w_subtype, w_arg): @@ -308,7 +308,7 @@ def convert_to(self, dtype): from pypy.module.micronumpy import types assert isinstance(dtype.itemtype, types.UnicodeType) - return self + return self class W_ComplexFloatingBox(W_InexactBox): diff --git a/pypy/module/micronumpy/interp_dtype.py b/pypy/module/micronumpy/interp_dtype.py --- a/pypy/module/micronumpy/interp_dtype.py +++ b/pypy/module/micronumpy/interp_dtype.py @@ -224,7 +224,7 @@ size = int(name[1:]) except ValueError: raise OperationError(space.w_TypeError, space.wrap("data type not understood")) - if char == 'S': + if char == 'S' or char == 'c': itemtype = types.StringType(size) basename = 'string' num = 18 @@ -264,8 +264,10 @@ return cache.dtypes_by_name[name] except KeyError: pass - if name[0] in 'VSU' or name[0] in '<>=' and name[1] in 'VSU': + if name[0] in 'VSUc' or name[0] in '<>=' and name[1] in 'VSUc': return variable_dtype(space, name) + raise OperationError(space.w_TypeError, space.wrap( + "data type %s not understood" % name)) elif space.isinstance_w(w_dtype, space.w_list): return dtype_from_list(space, w_dtype) elif space.isinstance_w(w_dtype, space.w_dict): @@ -447,7 +449,7 @@ name="float64", char="d", w_box_type = space.gettypefor(interp_boxes.W_Float64Box), - alternate_constructors=[space.w_float, + alternate_constructors=[space.w_float, space.gettypefor(interp_boxes.W_NumberBox), ], aliases=["float"], @@ -480,10 +482,8 @@ name="float96", char="g", w_box_type=space.gettypefor(interp_boxes.W_Float96Box), - aliases=["longfloat", "longdouble"], + aliases=["longdouble", "longfloat"], ) - self.w_longdouble = self.w_float96dtype - self.w_complex192dtype = W_ComplexDtype( types.Complex192(), num=16, @@ -495,8 +495,8 @@ aliases=["clongdouble", "clongfloat"], float_type = self.w_float96dtype, ) + self.w_longdouble = self.w_float96dtype self.w_clongdouble = self.w_complex192dtype - elif interp_boxes.long_double_size == 16: self.w_float128dtype = W_Dtype( types.Float128(), @@ -505,10 +505,8 @@ name="float128", char="g", w_box_type=space.gettypefor(interp_boxes.W_Float128Box), - aliases=["longfloat", "longdouble"], + aliases=["longdouble", "longfloat"], ) - self.w_longdouble = self.w_float128dtype - self.w_complex256dtype = W_ComplexDtype( types.Complex256(), num=16, @@ -520,11 +518,13 @@ aliases=["clongdouble", "clongfloat"], float_type = self.w_float128dtype, ) + self.w_longdouble = self.w_float128dtype self.w_clongdouble = self.w_complex256dtype else: - self.w_float64dtype.aliases += ["longfloat", "longdouble"] + self.w_float64dtype.aliases += ["longdouble", "longfloat"] + self.w_complex128dtype.aliases += ["clongdouble", "clongfloat"] self.w_longdouble = self.w_float64dtype - self.w_clongdouble = self.w_complex64dtype + self.w_clongdouble = self.w_complex128dtype self.w_stringdtype = W_Dtype( types.StringType(1), num=18, @@ -587,7 +587,7 @@ name='intp', char=INTPLTR, w_box_type = space.gettypefor(intp_box), - ) + ) self.w_uintpdtype = W_Dtype( uintp_type, num=uintp_num, @@ -595,27 +595,31 @@ name='uintp', char=UINTPLTR, w_box_type = space.gettypefor(uintp_box), - ) + ) self.builtin_dtypes = [ - self.w_booldtype, self.w_int8dtype, self.w_uint8dtype, - self.w_int16dtype, self.w_uint16dtype, self.w_int32dtype, - self.w_uint32dtype, self.w_longdtype, self.w_ulongdtype, + self.w_booldtype, + self.w_int8dtype, self.w_uint8dtype, + self.w_int16dtype, self.w_uint16dtype, + self.w_longdtype, self.w_ulongdtype, + self.w_int32dtype, self.w_uint32dtype, self.w_int64dtype, self.w_uint64dtype, - self.w_float16dtype, self.w_float32dtype, self.w_float64dtype, - self.w_longdouble, + self.w_float16dtype, + self.w_float32dtype, self.w_float64dtype, self.w_longdouble, self.w_complex64dtype, self.w_complex128dtype, self.w_clongdouble, - self.w_stringdtype, self.w_unicodedtype, - self.w_voiddtype, self.w_intpdtype, self.w_uintpdtype, + self.w_stringdtype, self.w_unicodedtype, self.w_voiddtype, + self.w_intpdtype, self.w_uintpdtype, ] self.float_dtypes_by_num_bytes = sorted( (dtype.itemtype.get_element_size(), dtype) for dtype in [self.w_float16dtype, self.w_float32dtype, self.w_float64dtype, self.w_longdouble] ) + self.dtypes_by_num = {} self.dtypes_by_name = {} # we reverse, so the stuff with lower numbers override stuff with # higher numbers for dtype in reversed(self.builtin_dtypes): + self.dtypes_by_num[dtype.num] = dtype self.dtypes_by_name[dtype.name] = dtype can_name = dtype.kind + str(dtype.itemtype.get_element_size()) self.dtypes_by_name[can_name] = dtype @@ -642,6 +646,11 @@ self.dtypes_by_name[alias] = dtype self.dtypes_by_name[dtype.char] = dtype + self.dtypes_by_num = [dtype for dtype in + sorted(self.dtypes_by_num.values(), key=lambda dtype: dtype.num) + if dtype.num <= self.w_float64dtype.num] + assert len(self.dtypes_by_num) == self.w_float64dtype.num + 1 + typeinfo_full = { 'LONGLONG': self.w_int64dtype, 'SHORT': self.w_int16dtype, @@ -706,9 +715,7 @@ w_minobj = space.wrap(0) items_w = items_w + [w_maxobj, w_minobj] items_w = items_w + [dtype.w_box_type] - - w_tuple = space.newtuple(items_w) - space.setitem(w_typeinfo, space.wrap(k), w_tuple) + space.setitem(w_typeinfo, space.wrap(k), space.newtuple(items_w)) self.w_typeinfo = w_typeinfo def get_dtype_cache(space): diff --git a/pypy/module/micronumpy/interp_numarray.py b/pypy/module/micronumpy/interp_numarray.py --- a/pypy/module/micronumpy/interp_numarray.py +++ b/pypy/module/micronumpy/interp_numarray.py @@ -891,8 +891,9 @@ @unwrap_spec(ndmin=int, copy=bool, subok=bool) def array(space, w_object, w_dtype=None, copy=True, w_order=None, subok=False, ndmin=0): - if not issequence_w(space, w_object): - if space.is_none(w_dtype): + isstr = space.isinstance_w(w_object, space.w_str) + if not issequence_w(space, w_object) or isstr: + if space.is_none(w_dtype) or isstr: w_dtype = interp_ufuncs.find_dtype_for_scalar(space, w_object) dtype = space.interp_w(interp_dtype.W_Dtype, space.call_function(space.gettypefor(interp_dtype.W_Dtype), w_dtype)) diff --git a/pypy/module/micronumpy/interp_ufuncs.py b/pypy/module/micronumpy/interp_ufuncs.py --- a/pypy/module/micronumpy/interp_ufuncs.py +++ b/pypy/module/micronumpy/interp_ufuncs.py @@ -324,10 +324,12 @@ w_out = None w_lhs = convert_to_array(space, w_lhs) w_rhs = convert_to_array(space, w_rhs) - if w_lhs.get_dtype().is_flexible_type() or \ - w_rhs.get_dtype().is_flexible_type(): - raise OperationError(space.w_TypeError, - space.wrap('unsupported operand types')) + if (w_lhs.get_dtype().is_flexible_type() or \ + w_rhs.get_dtype().is_flexible_type()): + raise OperationError(space.w_TypeError, space.wrap( + 'unsupported operand dtypes %s and %s for "%s"' % \ + (w_rhs.get_dtype().get_name(), w_lhs.get_dtype().get_name(), + self.name))) calc_dtype = find_binop_result_dtype(space, w_lhs.get_dtype(), w_rhs.get_dtype(), int_only=self.int_only, @@ -403,7 +405,6 @@ else: raise OperationError(space.w_TypeError, space.wrap("Unsupported types")) - if promote_to_float: return find_unaryop_result_dtype(space, dt2, promote_to_float=True) # If they're the same kind, choose the greater one. @@ -424,13 +425,13 @@ return dt2 # we need to promote both dtypes dtypenum = dt2.num + 2 + elif dt2.num == 10 or (LONG_BIT == 64 and dt2.num == 8): + # UInt64 + signed = Float64 + dtypenum = 12 else: - # increase to the next signed type (or to float) + # increase to the next signed type dtypenum = dt2.num + 1 - # UInt64 + signed = Float64 - if dt2.num == 10: - dtypenum += 2 - newdtype = interp_dtype.get_dtype_cache(space).builtin_dtypes[dtypenum] + newdtype = interp_dtype.get_dtype_cache(space).dtypes_by_num[dtypenum] if (newdtype.itemtype.get_element_size() > dt2.itemtype.get_element_size() or newdtype.kind == interp_dtype.FLOATINGLTR): @@ -438,11 +439,8 @@ else: # we only promoted to long on 32-bit or to longlong on 64-bit # this is really for dealing with the Long and Ulong dtypes - if LONG_BIT == 32: - dtypenum += 2 - else: - dtypenum += 4 - return interp_dtype.get_dtype_cache(space).builtin_dtypes[dtypenum] + dtypenum += 2 + return interp_dtype.get_dtype_cache(space).dtypes_by_num[dtypenum] @jit.unroll_safe diff --git a/pypy/module/micronumpy/test/test_dtypes.py b/pypy/module/micronumpy/test/test_dtypes.py --- a/pypy/module/micronumpy/test/test_dtypes.py +++ b/pypy/module/micronumpy/test/test_dtypes.py @@ -22,12 +22,16 @@ d = dtype('?') assert d.num == 0 assert d.kind == 'b' + assert dtype(d) is d + assert dtype('bool') is d + assert dtype('int8').num == 1 - assert dtype(d) is d - assert dtype(None) is dtype(float) assert dtype('int8').name == 'int8' assert dtype(int).fields is None assert dtype(int).names is None + + assert dtype(None) is dtype(float) + raises(TypeError, dtype, 1042) raises(KeyError, 'dtype(int)["asdasd"]') @@ -39,6 +43,13 @@ raises(TypeError, lambda: dtype("int8") == 3) assert dtype(bool) == bool + def test_dtype_aliases(self): + from _numpypy import dtype + assert dtype('longfloat').num in (12, 13) + assert dtype('longdouble').num in (12, 13) + assert dtype('clongfloat').num in (15, 16) + assert dtype('clongdouble').num in (15, 16) + def test_dtype_with_types(self): from _numpypy import dtype @@ -46,9 +57,17 @@ if self.ptr_size == 4: assert dtype('intp').num == 5 assert dtype('uintp').num == 6 + assert dtype('int32').num == 7 + assert dtype('uint32').num == 8 + assert dtype('int64').num == 9 + assert dtype('uint64').num == 10 else: assert dtype('intp').num == 7 assert dtype('uintp').num == 8 + assert dtype('int32').num == 5 + assert dtype('uint32').num == 6 + assert dtype('int64').num == 7 + assert dtype('uint64').num == 8 assert dtype(int).num == 7 assert dtype(float).num == 12 @@ -162,7 +181,7 @@ for d1, d2, dout in tests: # make a failed test print helpful info d3 = (array([1], d1) + array([1], d2)).dtype - assert (d1, d2, repr(d3)) == (d1, d2, repr(dtype(dout))) + assert (d1, d2) == (d1, d2) and d3 is dtype(dout) def test_add_int8(self): from _numpypy import array, dtype @@ -259,6 +278,7 @@ class AppTestTypes(BaseAppTestDtypes): def test_abstract_types(self): import _numpypy as numpy + raises(TypeError, numpy.generic, 0) raises(TypeError, numpy.number, 0) raises(TypeError, numpy.integer, 0) @@ -276,6 +296,12 @@ a_i = numpy.array([4,4], numpy.integer) a_s = numpy.array([4,4], numpy.signedinteger) a_u = numpy.array([4,4], numpy.unsignedinteger) + + assert a_n.dtype.num == 12 + assert a_i.dtype.num == 7 + assert a_s.dtype.num == 7 + assert a_u.dtype.num == 8 + assert a_n.dtype is numpy.dtype('float64') if self.ptr_size == 4: assert a_i.dtype is numpy.dtype('int32') @@ -285,6 +311,7 @@ assert a_i.dtype is numpy.dtype('int64') assert a_s.dtype is numpy.dtype('int64') assert a_u.dtype is numpy.dtype('uint64') + # too ambitious for now #a = numpy.array('xxxx', numpy.generic) #assert a.dtype is numpy.dtype('|V4') @@ -510,7 +537,7 @@ numpy.inexact, numpy.number, numpy.generic, object] a = numpy.array([1, 2, 3], numpy.longdouble) - assert repr(type(a[1])) == repr(numpy.longdouble) + assert type(a[1]) is numpy.longdouble assert numpy.float64(12) == numpy.longdouble(12) assert numpy.float64(12) == numpy.longfloat(12) raises(ValueError, numpy.longfloat, '23.2df') @@ -550,7 +577,7 @@ assert repr(c128) == should c64 = numpy.complex64(complex(real, imag)) - assert repr(c64.real) == 'inf' + assert repr(c64.real) == 'inf' assert type(c64.real) is type(c64.imag) is numpy.float32 assert repr(c64.imag).startswith('inf') assert repr(c64) in ('(inf+inf*j)', '(inf+infj)') diff --git a/pypy/module/micronumpy/test/test_numarray.py b/pypy/module/micronumpy/test/test_numarray.py --- a/pypy/module/micronumpy/test/test_numarray.py +++ b/pypy/module/micronumpy/test/test_numarray.py @@ -1666,6 +1666,9 @@ a = arange(6, dtype='f4').reshape(2,3) b = a.astype('i4') + a = array('x').astype('S3').dtype + assert a.itemsize == 3 + def test_base(self): from _numpypy import array assert array(1).base is None @@ -2192,6 +2195,8 @@ assert (a + a).item(1) == 4 raises(IndexError, "array(5).item(1)") assert array([1]).item() == 1 + a = array('x') + assert a.item() == 'x' def test_int_array_index(self): from _numpypy import array @@ -2534,27 +2539,53 @@ def test_string_record(self): from _numpypy import dtype, array + d = dtype([('x', str), ('y', 'int32')]) - assert d.fields['x'] == (dtype(str), 0) - assert d.fields['y'] == (dtype('int32'), 1) + assert str(d.fields['x'][0]) == '|S0' + assert d.fields['x'][1] == 0 + assert str(d.fields['y'][0]) == 'int32' + assert d.fields['y'][1] == 0 + assert d.name == 'void32' + + a = array([('a', 2), ('cde', 1)], dtype=d) + assert a[0]['x'] == '\x02' + assert a[0]['y'] == 2 + assert a[1]['x'] == '\x01' + assert a[1]['y'] == 1 + d = dtype([('x', 'S1'), ('y', 'int32')]) - assert d.fields['x'] == (dtype(str), 0) - assert d.fields['y'] == (dtype('int32'), 1) - a = array([('a', 2), ('c', 1)], dtype=d) + assert str(d.fields['x'][0]) == '|S1' + assert d.fields['x'][1] == 0 + assert str(d.fields['y'][0]) == 'int32' + assert d.fields['y'][1] == 1 + assert d.name == 'void40' + + a = array([('a', 2), ('cde', 1)], dtype=d) + assert a[0]['x'] == 'a' + assert a[0]['y'] == 2 + assert a[1]['x'] == 'c' assert a[1]['y'] == 1 - assert a[0]['x'] == 'a' - def test_stringarray(self): + def test_string_array(self): from _numpypy import array - a = array(['abc'],'S3') - assert str(a.dtype) == '|S3' a = array(['abc']) assert str(a.dtype) == '|S3' - a = array(['abc','defg','ab']) + a = array(['abc'], 'S') + assert str(a.dtype) == '|S3' + a = array(['abc'], 'S3') + assert str(a.dtype) == '|S3' + a = array(['abcde'], 'S3') + assert str(a.dtype) == '|S3' + a = array(['abc', 'defg', 'ab']) assert str(a.dtype) == '|S4' assert a[0] == 'abc' assert a[1] == 'defg' assert a[2] == 'ab' + a = array(['abc', 'defg', 'ab'], 'S3') + assert str(a.dtype) == '|S3' + assert a[0] == 'abc' + assert a[1] == 'def' + assert a[2] == 'ab' raises(TypeError, a, 'sum') raises(TypeError, 'a+a') @@ -2562,6 +2593,14 @@ from _numpypy import array a = array('ffff') assert a.shape == () + a = array([], dtype='S') + assert str(a.dtype) == '|S1' + a = array('x', dtype='>S') + assert str(a.dtype) == '|S1' + a = array('x', dtype='c') + assert str(a.dtype) == '|S1' + # XXX can sort flexible types, why not comparison? + #assert a == 'x' def test_flexible_repr(self): # numpypy overrides _numpypy repr with pure python one @@ -2576,14 +2615,14 @@ s = repr(a) assert s.replace('\n', '') == \ "array(['abc', 'defg', 'ab'], dtype='|S4')" - - + + class AppTestPyPy(BaseNumpyAppTest): def setup_class(cls): if option.runappdirect and '__pypy__' not in sys.builtin_module_names: py.test.skip("pypy only test") BaseNumpyAppTest.setup_class.im_func(cls) - + def test_init_2(self): # this test is pypy only since in numpy it becomes an object dtype import _numpypy diff --git a/pypy/module/micronumpy/types.py b/pypy/module/micronumpy/types.py --- a/pypy/module/micronumpy/types.py +++ b/pypy/module/micronumpy/types.py @@ -1019,17 +1019,17 @@ def str_format(self, box): real, imag = self.for_computation(self.unbox(box)) imag_str = str_format(imag) + 'j' - + # (0+2j) => 2j if real == 0: - return imag_str + return imag_str real_str = str_format(real) op = '+' if imag >= 0 else '' return ''.join(['(', real_str, op, imag_str, ')']) @staticmethod - def for_computation(v): + def for_computation(v): return float(v[0]), float(v[1]) @raw_unary_op @@ -1101,7 +1101,7 @@ @complex_binary_op def mul(self, v1, v2): return rcomplex.c_mul(v1, v2) - + @complex_binary_op def div(self, v1, v2): try: @@ -1603,7 +1603,7 @@ arr = interp_boxes.VoidBoxStorage(len(arg), new_string_dtype(space, len(arg))) for i in range(len(arg)): arr.storage[i] = arg[i] - return interp_boxes.W_StringBox(arr, 0, None) + return interp_boxes.W_StringBox(arr, 0, arr.dtype) @jit.unroll_safe def store(self, arr, i, offset, box): @@ -1637,6 +1637,10 @@ builder.append("'") return builder.build() + # XXX move to base class when UnicodeType is supported + def to_builtin_type(self, space, box): + return space.wrap(self.to_str(box)) + class VoidType(BaseType, BaseStringType): T = lltype.Char diff --git a/pypy/module/test_lib_pypy/pyrepl/test_bugs.py b/pypy/module/test_lib_pypy/pyrepl/test_bugs.py --- a/pypy/module/test_lib_pypy/pyrepl/test_bugs.py +++ b/pypy/module/test_lib_pypy/pyrepl/test_bugs.py @@ -44,3 +44,28 @@ ('accept', ['']) ] read_spec(spec, HistoricalTestReader) + +def test_signal_failure(monkeypatch): + import os + import pty + import signal + from pyrepl.unix_console import UnixConsole + + def failing_signal(a, b): + raise ValueError + + def really_failing_signal(a, b): + raise AssertionError + + mfd, sfd = pty.openpty() + try: + c = UnixConsole(sfd, sfd) + c.prepare() + c.restore() + monkeypatch.setattr(signal, 'signal', failing_signal) + c.prepare() + monkeypatch.setattr(signal, 'signal', really_failing_signal) + c.restore() + finally: + os.close(mfd) + os.close(sfd) diff --git a/pypy/objspace/std/dictmultiobject.py b/pypy/objspace/std/dictmultiobject.py --- a/pypy/objspace/std/dictmultiobject.py +++ b/pypy/objspace/std/dictmultiobject.py @@ -110,18 +110,6 @@ def view_as_kwargs(self): return self.strategy.view_as_kwargs(self) - def convert_to_celldict_strategy(self, space): - from pypy.objspace.std.celldict import ModuleDictStrategy - - if isinstance(self.strategy, ModuleDictStrategy): - return - items_w = self.items() - self.strategy = ModuleDictStrategy(space) - self.dstorage = self.strategy.get_empty_storage() - for w_tup in items_w: - w_key, w_val = space.fixedview(w_tup, 2) - self.setitem(w_key, w_val) - def _add_indirections(): dict_methods = "setitem setitem_str getitem \ getitem_str delitem length \ diff --git a/pypy/objspace/std/objspace.py b/pypy/objspace/std/objspace.py --- a/pypy/objspace/std/objspace.py +++ b/pypy/objspace/std/objspace.py @@ -714,10 +714,3 @@ if not hasattr(self, "_interplevel_classes"): return None # before running initialize return self._interplevel_classes.get(w_type, None) - - def possibly_convert_to_celldict(self, w_dict): - """ Converts the dict to celldict, if it's a dict, otherwise - leaves it alone - """ - if isinstance(w_dict, W_DictMultiObject): - w_dict.convert_to_celldict_strategy(self) diff --git a/rpython/bin/rpython b/rpython/bin/rpython --- a/rpython/bin/rpython +++ b/rpython/bin/rpython @@ -8,7 +8,8 @@ """ import sys, os -sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.dirname(__file__)))) +sys.path.insert(0, os.path.dirname(os.path.dirname( + os.path.dirname(os.path.realpath(__file__))))) from rpython.translator.goal.translate import main # no implicit targets diff --git a/rpython/rlib/rarithmetic.py b/rpython/rlib/rarithmetic.py --- a/rpython/rlib/rarithmetic.py +++ b/rpython/rlib/rarithmetic.py @@ -246,6 +246,23 @@ return r_class(0) most_neg_value_of._annspecialcase_ = 'specialize:memo' +def most_pos_value_of_same_type(x): + from rpython.rtyper.lltypesystem import lltype + return most_pos_value_of(lltype.typeOf(x)) +most_pos_value_of_same_type._annspecialcase_ = 'specialize:argtype(0)' + +def most_pos_value_of(tp): + from rpython.rtyper.lltypesystem import lltype, rffi + if tp is lltype.Signed: + return sys.maxint + r_class = rffi.platform.numbertype_to_rclass[tp] + assert issubclass(r_class, base_int) + if r_class.SIGNED: + return r_class(r_class.MASK >> 1) + else: + return r_class(r_class.MASK) +most_pos_value_of._annspecialcase_ = 'specialize:memo' + def is_signed_integer_type(tp): from rpython.rtyper.lltypesystem import lltype, rffi if tp is lltype.Signed: diff --git a/rpython/rlib/rstring.py b/rpython/rlib/rstring.py --- a/rpython/rlib/rstring.py +++ b/rpython/rlib/rstring.py @@ -3,9 +3,10 @@ from rpython.annotator.model import (SomeObject, SomeString, s_None, SomeChar, SomeInteger, SomeUnicodeCodePoint, SomeUnicodeString, SomePtr, SomePBC) +from rpython.rlib.objectmodel import newlist_hint from rpython.rlib.rarithmetic import ovfcheck -from rpython.tool.pairtype import pair, pairtype from rpython.rtyper.extregistry import ExtRegistryEntry +from rpython.tool.pairtype import pairtype # -------------- public API for string functions ----------------------- @@ -14,7 +15,10 @@ if bylen == 0: raise ValueError("empty separator") - res = [] + if maxsplit > 0: + res = newlist_hint(min(maxsplit + 1, len(value))) + else: + res = [] start = 0 while maxsplit != 0: next = value.find(by, start) @@ -27,8 +31,12 @@ res.append(value[start:len(value)]) return res + def rsplit(value, by, maxsplit=-1): - res = [] + if maxsplit > 0: + res = newlist_hint(min(maxsplit + 1, len(value))) + else: + res = [] end = len(value) bylen = len(by) if bylen == 0: @@ -38,7 +46,7 @@ next = value.rfind(by, 0, end) if next < 0: break - res.append(value[next+bylen:end]) + res.append(value[next + bylen:end]) end = next maxsplit -= 1 # NB. if it's already < 0, it stays < 0 @@ -50,6 +58,7 @@ INIT_SIZE = 100 # XXX tweak + class AbstractStringBuilder(object): def __init__(self, init_size=INIT_SIZE): self.l = [] @@ -91,9 +100,11 @@ def getlength(self): return len(self.build()) + class StringBuilder(AbstractStringBuilder): tp = str + class UnicodeBuilder(AbstractStringBuilder): tp = unicode @@ -260,4 +271,3 @@ def specialize_call(self, hop): hop.exception_cannot_occur() - diff --git a/rpython/rlib/streamio.py b/rpython/rlib/streamio.py --- a/rpython/rlib/streamio.py +++ b/rpython/rlib/streamio.py @@ -552,30 +552,26 @@ # This may fail on the do_seek() or do_tell() call. # But it won't call either on a relative forward seek. # Nor on a seek to the very end. - if whence == 0: - self.do_seek(offset, 0) - self.buf = "" - self.pos = 0 - return - if whence == 1: + if whence == 0 or whence == 1: currentsize = len(self.buf) - self.pos - if offset < 0: - if self.pos + offset >= 0: - self.pos += offset - else: - self.do_seek(self.tell() + offset, 0) - self.pos = 0 - self.buf = "" - return - elif offset <= currentsize: - self.pos += offset + if whence == 0: + difpos = offset - self.tell() + else: + difpos = offset + if -self.pos <= difpos <= currentsize: + self.pos += difpos return self.buf = "" self.pos = 0 - offset -= currentsize + if whence == 1: + offset -= currentsize try: - self.do_seek(offset, 1) + self.do_seek(offset, whence) except MyNotImplementedError: + if difpos < 0: + raise + if whence == 0: + offset = difpos - currentsize intoffset = offset2int(offset) self.read(intoffset) return diff --git a/rpython/rlib/test/test_rarithmetic.py b/rpython/rlib/test/test_rarithmetic.py --- a/rpython/rlib/test/test_rarithmetic.py +++ b/rpython/rlib/test/test_rarithmetic.py @@ -357,6 +357,14 @@ assert most_neg_value_of_same_type(r_longlong(123)) == llmin assert most_neg_value_of_same_type(r_ulonglong(123)) == 0 +def test_most_pos_value_of(): + assert most_pos_value_of_same_type(123) == sys.maxint + assert most_pos_value_of_same_type(r_uint(123)) == 2 * sys.maxint + 1 + llmax_sign = (2**(r_longlong.BITS-1))-1 + llmax_unsign = (2**r_longlong.BITS)-1 + assert most_pos_value_of_same_type(r_longlong(123)) == llmax_sign + assert most_pos_value_of_same_type(r_ulonglong(123)) == llmax_unsign + def test_is_signed_integer_type(): from rpython.rtyper.lltypesystem import lltype, rffi assert is_signed_integer_type(lltype.Signed) diff --git a/rpython/rlib/test/test_streamio.py b/rpython/rlib/test/test_streamio.py --- a/rpython/rlib/test/test_streamio.py +++ b/rpython/rlib/test/test_streamio.py @@ -12,18 +12,24 @@ class TSource(streamio.Stream): - def __init__(self, packets): + def __init__(self, packets, tell=True, seek=True): for x in packets: assert x self.orig_packets = packets[:] self.packets = packets[:] self.pos = 0 self.chunks = [] + self._tell = tell + self._seek = seek def tell(self): + if not self._tell: + raise streamio.MyNotImplementedError return self.pos def seek(self, offset, whence=0): + if not self._seek: + raise streamio.MyNotImplementedError if whence == 1: offset += self.pos elif whence == 2: @@ -384,25 +390,36 @@ all = file.readall() end = len(all) cases = [(readto, seekto, whence) for readto in range(0, end+1) - for seekto in range(readto, end+1) - for whence in [1, 2]] + for seekto in range(0, end+1) + for whence in [0, 1, 2]] random.shuffle(cases) if isinstance(self, (LLRtypeMixin, OORtypeMixin)): cases = cases[:7] # pick some cases at random - too slow! def f(): for readto, seekto, whence in cases: - base = TSource(self.packets) + base = TSource(self.packets, seek=False) file = streamio.BufferingInputStream(base) head = file.read(readto) assert head == all[:readto] - offset = 42 # for the flow space if whence == 1: offset = seekto - readto elif whence == 2: offset = seekto - end - file.seek(offset, whence) - rest = file.readall() - assert rest == all[seekto:] + else: + offset = seekto + if whence == 2 and seekto < file.tell() or seekto < file.tell() - file.pos: + try: + file.seek(offset, whence) + except streamio.MyNotImplementedError: + assert whence in (0, 1) + except streamio.StreamError: + assert whence == 2 + else: + assert False + else: + file.seek(offset, whence) + rest = file.readall() + assert rest == all[seekto:] return True res = self.interpret(f, []) assert res diff --git a/rpython/rtyper/test/test_rint.py b/rpython/rtyper/test/test_rint.py --- a/rpython/rtyper/test/test_rint.py +++ b/rpython/rtyper/test/test_rint.py @@ -115,6 +115,22 @@ res = self.interpret(f, [r_int64(413974738222117)]) assert self.ll_to_string(res) == '413974738222117' + def test_str_of_uint(self): + def f(i): + return str(i) + + res = self.interpret(f, [r_uint(0)]) + assert self.ll_to_string(res) == '0' + + res = self.interpret(f, [r_uint(sys.maxint)]) + assert self.ll_to_string(res) == str(sys.maxint) + + res = self.interpret(f, [r_uint(sys.maxint+1)]) + assert self.ll_to_string(res) == str(sys.maxint+1) + + res = self.interpret(f, [r_uint(-1)]) + assert self.ll_to_string(res) == str(2*sys.maxint+1) + def test_unsigned(self): bigvalue = r_uint(sys.maxint + 17) def dummy(i): From noreply at buildbot.pypy.org Wed Feb 13 23:12:34 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Wed, 13 Feb 2013 23:12:34 +0100 (CET) Subject: [pypy-commit] pypy py3k: adapt 96be871fc24b to py3 Message-ID: <20130213221234.0E4F51C3C1D@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61224:7668e24c3f92 Date: 2013-02-13 14:12 -0800 http://bitbucket.org/pypy/pypy/changeset/7668e24c3f92/ Log: adapt 96be871fc24b to py3 diff --git a/lib-python/3.2/test/test_generators.py b/lib-python/3.2/test/test_generators.py --- a/lib-python/3.2/test/test_generators.py +++ b/lib-python/3.2/test/test_generators.py @@ -1496,9 +1496,7 @@ """ coroutine_tests = """\ -A helper function to call gc.collect() without printing ->>> import gc ->>> def gc_collect(): gc.collect() +>>> from test.support import gc_collect Sending a value into a started generator: @@ -1840,8 +1838,7 @@ references. We add it to the standard suite so the routine refleak-tests would trigger if it starts being uncleanable again. ->>> import gc ->>> def gc_collect(): gc.collect() +>>> from test.support import gc_collect >>> import itertools >>> def leak(): From noreply at buildbot.pypy.org Wed Feb 13 23:53:27 2013 From: noreply at buildbot.pypy.org (mattip) Date: Wed, 13 Feb 2013 23:53:27 +0100 (CET) Subject: [pypy-commit] pypy numpy-unify-methods: test, fix raise for int_only Message-ID: <20130213225327.067A61C3C29@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: numpy-unify-methods Changeset: r61225:4f03e6c73208 Date: 2013-02-14 00:23 +0200 http://bitbucket.org/pypy/pypy/changeset/4f03e6c73208/ Log: test, fix raise for int_only diff --git a/pypy/module/micronumpy/interp_ufuncs.py b/pypy/module/micronumpy/interp_ufuncs.py --- a/pypy/module/micronumpy/interp_ufuncs.py +++ b/pypy/module/micronumpy/interp_ufuncs.py @@ -258,6 +258,9 @@ if w_obj.get_dtype().is_flexible_type(): raise OperationError(space.w_TypeError, space.wrap('Not implemented for this type')) + if self.int_only and not w_obj.get_dtype().is_int_type(): + raise OperationError(space.w_TypeError, space.wrap( + "ufunc %s not supported for the input type", self.name)) calc_dtype = find_unaryop_result_dtype(space, w_obj.get_dtype(), promote_to_float=self.promote_to_float, @@ -337,6 +340,9 @@ promote_bools=self.promote_bools, allow_complex=self.allow_complex, ) + if self.int_only and not calc_dtype.is_int_type(): + raise OperationError(space.w_TypeError, space.wrap( + "ufunc '%s' not supported for the input types", self.name)) if space.is_none(w_out): out = None elif not isinstance(w_out, W_NDimArray): diff --git a/pypy/module/micronumpy/test/test_ufuncs.py b/pypy/module/micronumpy/test/test_ufuncs.py --- a/pypy/module/micronumpy/test/test_ufuncs.py +++ b/pypy/module/micronumpy/test/test_ufuncs.py @@ -114,6 +114,11 @@ 'rad2deg', 'invert', 'spacing', 'radians', 'frexp', 'signbit', 'modf', 'trunc']) + def test_int_only(self): + from _numpypy import bitwise_and, array + a = array(1.0) + raises(TypeError, bitwise_and, a, a) + def test_negative(self): from _numpypy import array, negative From noreply at buildbot.pypy.org Wed Feb 13 23:53:28 2013 From: noreply at buildbot.pypy.org (mattip) Date: Wed, 13 Feb 2013 23:53:28 +0100 (CET) Subject: [pypy-commit] pypy numpy-unify-methods: fix exception formatting Message-ID: <20130213225328.3CE341C3C2A@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: numpy-unify-methods Changeset: r61226:207f00864f45 Date: 2013-02-14 00:30 +0200 http://bitbucket.org/pypy/pypy/changeset/207f00864f45/ Log: fix exception formatting diff --git a/pypy/module/micronumpy/interp_ufuncs.py b/pypy/module/micronumpy/interp_ufuncs.py --- a/pypy/module/micronumpy/interp_ufuncs.py +++ b/pypy/module/micronumpy/interp_ufuncs.py @@ -260,7 +260,7 @@ space.wrap('Not implemented for this type')) if self.int_only and not w_obj.get_dtype().is_int_type(): raise OperationError(space.w_TypeError, space.wrap( - "ufunc %s not supported for the input type", self.name)) + "ufunc %s not supported for the input type" % self.name)) calc_dtype = find_unaryop_result_dtype(space, w_obj.get_dtype(), promote_to_float=self.promote_to_float, @@ -342,7 +342,7 @@ ) if self.int_only and not calc_dtype.is_int_type(): raise OperationError(space.w_TypeError, space.wrap( - "ufunc '%s' not supported for the input types", self.name)) + "ufunc '%s' not supported for the input types" % self.name)) if space.is_none(w_out): out = None elif not isinstance(w_out, W_NDimArray): diff --git a/pypy/module/micronumpy/test/test_ufuncs.py b/pypy/module/micronumpy/test/test_ufuncs.py --- a/pypy/module/micronumpy/test/test_ufuncs.py +++ b/pypy/module/micronumpy/test/test_ufuncs.py @@ -109,7 +109,8 @@ assert len(missing) == 2 and set(missing) == set(['bitwise_not', 'invert']) a = np.array(1.0,'complex') missing = missing_ufuncs(a) - assert len(missing) == 14 and set(missing) == \ + assert len(missing) == 14 + assert set(missing) == \ set(['bitwise_not', 'ceil', 'deg2rad', 'degrees', 'fabs', 'floor', 'rad2deg', 'invert', 'spacing', 'radians', 'frexp', 'signbit', 'modf', 'trunc']) From noreply at buildbot.pypy.org Thu Feb 14 01:05:03 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Thu, 14 Feb 2013 01:05:03 +0100 (CET) Subject: [pypy-commit] pypy default: optimize LineBufOut.write to only produce a single underlying write in all cases Message-ID: <20130214000503.472801C3C29@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61227:2a03b3b62fba Date: 2013-02-13 19:04 -0500 http://bitbucket.org/pypy/pypy/changeset/2a03b3b62fba/ Log: optimize LineBufOut.write to only produce a single underlying write in all cases diff --git a/rpython/rlib/streamio.py b/rpython/rlib/streamio.py --- a/rpython/rlib/streamio.py +++ b/rpython/rlib/streamio.py @@ -795,8 +795,10 @@ self.buflen += len(data) else: if self.buflen: + self.buf.append(data[:p]) self.do_write(''.join(self.buf)) - self.do_write(data[:p]) + else: + self.do_write(data[:p]) self.buf = [data[p:]] self.buflen = len(self.buf[0]) else: From noreply at buildbot.pypy.org Thu Feb 14 10:58:45 2013 From: noreply at buildbot.pypy.org (fijal) Date: Thu, 14 Feb 2013 10:58:45 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: remove another copy of an identical function Message-ID: <20130214095845.8306D1C06E2@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61228:4c25a4b4fea3 Date: 2013-02-14 11:57 +0200 http://bitbucket.org/pypy/pypy/changeset/4c25a4b4fea3/ Log: remove another copy of an identical function diff --git a/rpython/jit/backend/arm/assembler.py b/rpython/jit/backend/arm/assembler.py --- a/rpython/jit/backend/arm/assembler.py +++ b/rpython/jit/backend/arm/assembler.py @@ -919,7 +919,7 @@ opnum = op.getopnum() if op.has_no_side_effect() and op.result not in regalloc.longevity: regalloc.possibly_free_vars_for_op(op) - elif self.can_merge_with_next_guard(op, i, operations): + elif self._regalloc.can_merge_with_next_guard(op, i, operations): guard = operations[i + 1] assert guard.is_guard() arglocs = regalloc_operations_with_guard[opnum](regalloc, op, @@ -945,31 +945,6 @@ regalloc._check_invariants() self.mc.mark_op(None) # end of the loop - # from ../x86/regalloc.py - def can_merge_with_next_guard(self, op, i, operations): - if (op.getopnum() == rop.CALL_MAY_FORCE or - op.getopnum() == rop.CALL_ASSEMBLER or - op.getopnum() == rop.CALL_RELEASE_GIL): - assert operations[i + 1].getopnum() == rop.GUARD_NOT_FORCED - return True - if not op.is_comparison(): - if op.is_ovf(): - if (operations[i + 1].getopnum() != rop.GUARD_NO_OVERFLOW and - operations[i + 1].getopnum() != rop.GUARD_OVERFLOW): - not_implemented("int_xxx_ovf not followed by " - "guard_(no)_overflow") - return True - return False - if (operations[i + 1].getopnum() != rop.GUARD_TRUE and - operations[i + 1].getopnum() != rop.GUARD_FALSE): - return False - if operations[i + 1].getarg(0) is not op.result: - return False - if (self._regalloc.longevity[op.result][1] > i + 1 or - op.result in operations[i + 1].getfailargs()): - return False - return True - def regalloc_emit_llong(self, op, arglocs, fcond, regalloc): effectinfo = op.getdescr().get_extra_info() oopspecindex = effectinfo.oopspecindex diff --git a/rpython/jit/backend/llsupport/regalloc.py b/rpython/jit/backend/llsupport/regalloc.py --- a/rpython/jit/backend/llsupport/regalloc.py +++ b/rpython/jit/backend/llsupport/regalloc.py @@ -643,6 +643,30 @@ # for tests looptoken.compiled_loop_token._ll_initial_locs = locs + def can_merge_with_next_guard(self, op, i, operations): + if (op.getopnum() == rop.CALL_MAY_FORCE or + op.getopnum() == rop.CALL_ASSEMBLER or + op.getopnum() == rop.CALL_RELEASE_GIL): + assert operations[i + 1].getopnum() == rop.GUARD_NOT_FORCED + return True + if not op.is_comparison(): + if op.is_ovf(): + if (operations[i + 1].getopnum() != rop.GUARD_NO_OVERFLOW and + operations[i + 1].getopnum() != rop.GUARD_OVERFLOW): + not_implemented("int_xxx_ovf not followed by " + "guard_(no)_overflow") + return True + return False + if (operations[i + 1].getopnum() != rop.GUARD_TRUE and + operations[i + 1].getopnum() != rop.GUARD_FALSE): + return False + if operations[i + 1].getarg(0) is not op.result: + return False + if (self.longevity[op.result][1] > i + 1 or + op.result in operations[i + 1].getfailargs()): + return False + return True + def compute_vars_longevity(inputargs, operations): # compute a dictionary that maps variables to index in diff --git a/rpython/jit/backend/x86/regalloc.py b/rpython/jit/backend/x86/regalloc.py --- a/rpython/jit/backend/x86/regalloc.py +++ b/rpython/jit/backend/x86/regalloc.py @@ -332,30 +332,6 @@ self.assembler.dump('%s(%s)' % (op, arglocs)) self.assembler.regalloc_perform_discard(op, arglocs) - def can_merge_with_next_guard(self, op, i, operations): - if (op.getopnum() == rop.CALL_MAY_FORCE or - op.getopnum() == rop.CALL_ASSEMBLER or - op.getopnum() == rop.CALL_RELEASE_GIL): - assert operations[i + 1].getopnum() == rop.GUARD_NOT_FORCED - return True - if not op.is_comparison(): - if op.is_ovf(): - if (operations[i + 1].getopnum() != rop.GUARD_NO_OVERFLOW and - operations[i + 1].getopnum() != rop.GUARD_OVERFLOW): - not_implemented("int_xxx_ovf not followed by " - "guard_(no)_overflow") - return True - return False - if (operations[i + 1].getopnum() != rop.GUARD_TRUE and - operations[i + 1].getopnum() != rop.GUARD_FALSE): - return False - if operations[i + 1].getarg(0) is not op.result: - return False - if (self.longevity[op.result][1] > i + 1 or - op.result in operations[i + 1].getfailargs()): - return False - return True - def walk_operations(self, inputargs, operations): i = 0 #self.operations = operations From noreply at buildbot.pypy.org Thu Feb 14 11:05:34 2013 From: noreply at buildbot.pypy.org (fijal) Date: Thu, 14 Feb 2013 11:05:34 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: fix call_release_gil Message-ID: <20130214100534.89B181C06E2@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61229:8a88bb8fc1ee Date: 2013-02-14 12:04 +0200 http://bitbucket.org/pypy/pypy/changeset/8a88bb8fc1ee/ Log: fix call_release_gil diff --git a/rpython/jit/backend/arm/opassembler.py b/rpython/jit/backend/arm/opassembler.py --- a/rpython/jit/backend/arm/opassembler.py +++ b/rpython/jit/backend/arm/opassembler.py @@ -1268,13 +1268,15 @@ # self._emit_call(adr, callargs, fcond, resloc, (size, signed)) + self.emit_guard_may_force(guard_op, arglocs, numargs) + return fcond + def emit_guard_may_force(self, guard_op, arglocs, numargs): ofs = self.cpu.get_ofs_of_frame_field('jf_descr') self.mc.LDR_ri(r.ip.value, r.fp.value, imm=ofs) self.mc.CMP_ri(r.ip.value, 0) self._emit_guard(guard_op, arglocs[1 + numargs:], c.EQ, save_exc=True, is_guard_not_forced=True) - return fcond def emit_guard_call_release_gil(self, op, guard_op, arglocs, regalloc, fcond): @@ -1301,10 +1303,7 @@ if gcrootmap: self.call_reacquire_gil(gcrootmap, resloc, fcond) - self.mc.LDR_ri(r.ip.value, r.fp.value) - self.mc.CMP_ri(r.ip.value, 0) - - self._emit_guard(guard_op, arglocs[1 + numargs:], c.GE, save_exc=True) + self.emit_guard_may_force(guard_op, arglocs, numargs) return fcond def call_release_gil(self, gcrootmap, save_registers, fcond): From noreply at buildbot.pypy.org Thu Feb 14 11:09:52 2013 From: noreply at buildbot.pypy.org (fijal) Date: Thu, 14 Feb 2013 11:09:52 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: don't call it 'emit_guard' Message-ID: <20130214100952.0A7751C00A8@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61230:cd08d01813b2 Date: 2013-02-14 12:09 +0200 http://bitbucket.org/pypy/pypy/changeset/cd08d01813b2/ Log: don't call it 'emit_guard' diff --git a/rpython/jit/backend/arm/opassembler.py b/rpython/jit/backend/arm/opassembler.py --- a/rpython/jit/backend/arm/opassembler.py +++ b/rpython/jit/backend/arm/opassembler.py @@ -1268,10 +1268,10 @@ # self._emit_call(adr, callargs, fcond, resloc, (size, signed)) - self.emit_guard_may_force(guard_op, arglocs, numargs) + self._emit_guard_may_force(guard_op, arglocs, numargs) return fcond - def emit_guard_may_force(self, guard_op, arglocs, numargs): + def _emit_guard_may_force(self, guard_op, arglocs, numargs): ofs = self.cpu.get_ofs_of_frame_field('jf_descr') self.mc.LDR_ri(r.ip.value, r.fp.value, imm=ofs) self.mc.CMP_ri(r.ip.value, 0) @@ -1303,7 +1303,7 @@ if gcrootmap: self.call_reacquire_gil(gcrootmap, resloc, fcond) - self.emit_guard_may_force(guard_op, arglocs, numargs) + self._emit_guard_may_force(guard_op, arglocs, numargs) return fcond def call_release_gil(self, gcrootmap, save_registers, fcond): From noreply at buildbot.pypy.org Thu Feb 14 13:51:27 2013 From: noreply at buildbot.pypy.org (krono) Date: Thu, 14 Feb 2013 13:51:27 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: fix Large Integers. They can be more than four bytes wide. Message-ID: <20130214125127.C09BE1C061B@cobra.cs.uni-duesseldorf.de> Author: Tobias Pape Branch: Changeset: r22:d0ece51ae683 Date: 2013-01-25 08:07 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/d0ece51ae683/ Log: fix Large Integers. They can be more than four bytes wide. The ruint test passes on 64bit now, too diff --git a/spyvm/objspace.py b/spyvm/objspace.py --- a/spyvm/objspace.py +++ b/spyvm/objspace.py @@ -173,8 +173,10 @@ except WrappingError: pass # XXX this is not really working well on 64 bit machines - w_result = model.W_BytesObject(self.classtable['w_LargePositiveInteger'], 4) - for i in range(4): + import math + bytes_len = max(4, int(math.log(val, 0xff)) + 1) + w_result = model.W_BytesObject(self.classtable['w_LargePositiveInteger'], bytes_len) + for i in range(bytes_len): w_result.setchar(i, chr(intmask((val >> i*8) & 255))) return w_result @@ -221,12 +223,10 @@ if isinstance(w_value, model.W_BytesObject): # TODO: Completely untested! This failed translation bigtime... # XXX Probably we want to allow all subclasses - if not (w_value.getclass(self).is_same_object( - self.w_LargePositiveInteger) and - w_value.size() == 4): + if not w_value.getclass(self).is_same_object(self.w_LargePositiveInteger): raise UnwrappingError("Failed to convert bytes to word") word = 0 - for i in range(4): + for i in range(w_value.size()): word += r_uint(ord(w_value.getchar(i))) << 8*i return word else: diff --git a/spyvm/test/test_objectspace.py b/spyvm/test/test_objectspace.py --- a/spyvm/test/test_objectspace.py +++ b/spyvm/test/test_objectspace.py @@ -28,25 +28,30 @@ assert w_Metaclass.w_class.w_class is w_Metaclass def test_ruint(): + """ + | a b | + a := (9223372036854775808). + b := LargePositiveInteger new: a size + 1. + 1 to: a size do: [:index | + b digitAt: index put: (a digitAt: index)]. + b digitAt: (a size + 1) put: 1. + b. + => 27670116110564327424 + """ + from rpython.rlib.rarithmetic import r_uint - for num in [0, 1, 41, 100, 2**31]: + for num in [0, 1, 41, 100, 2**31, sys.maxint + 1]: num = r_uint(num) assert space.unwrap_uint(space.wrap_uint(num)) == num - for num in [-1, -100]: - py.test.raises(objspace.WrappingError, space.wrap_uint, num) + for num in [-1, -100, -sys.maxint]: + with py.test.raises(objspace.WrappingError): + space.wrap_uint(num) for obj in [space.wrap_char('a'), space.wrap_int(-1)]: - py.test.raises(objspace.UnwrappingError, space.unwrap_uint, obj) + with py.test.raises(objspace.UnwrappingError): + space.unwrap_uint(obj) byteobj = space.wrap_uint(sys.maxint + 1) byteobj.bytes.append('\x01') - py.test.raises(objspace.UnwrappingError, space.unwrap_uint, byteobj) + num = space.unwrap_uint(byteobj) + # should not raise. see docstring. + - at py.test.skipif("sys.maxint > 2147483647") -def test_ruint_max(): - from rpython.rlib.rarithmetic import r_uint - num = r_uint(sys.maxint + 1) - assert space.unwrap_uint(space.wrap_uint(num)) == num - num = -sys.maxint - py.test.raises(objspace.WrappingError, space.wrap_uint, num) - - - From noreply at buildbot.pypy.org Thu Feb 14 13:51:26 2013 From: noreply at buildbot.pypy.org (krono) Date: Thu, 14 Feb 2013 13:51:26 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: mark integer wrapping test as skipped on 64 bit machines Message-ID: <20130214125126.A27E61C00A8@cobra.cs.uni-duesseldorf.de> Author: Tobias Pape Branch: Changeset: r21:45c9ef36a50c Date: 2013-01-24 17:17 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/45c9ef36a50c/ Log: mark integer wrapping test as skipped on 64 bit machines diff --git a/spyvm/objspace.py b/spyvm/objspace.py --- a/spyvm/objspace.py +++ b/spyvm/objspace.py @@ -167,7 +167,7 @@ def wrap_uint(self, val): if val < 0: raise WrappingError("negative integer") - if intmask(val) > 0: + if intmask(val) >= 0: try: return self.wrap_int(intmask(val)) except WrappingError: diff --git a/spyvm/test/test_objectspace.py b/spyvm/test/test_objectspace.py --- a/spyvm/test/test_objectspace.py +++ b/spyvm/test/test_objectspace.py @@ -1,4 +1,5 @@ import py +import sys from spyvm import objspace space = objspace.ObjSpace() @@ -28,16 +29,24 @@ def test_ruint(): from rpython.rlib.rarithmetic import r_uint - import sys - for num in [0, 1, 41, 100, 2**31, sys.maxint + 1]: + for num in [0, 1, 41, 100, 2**31]: num = r_uint(num) assert space.unwrap_uint(space.wrap_uint(num)) == num - for num in [-1, -100, -sys.maxint]: + for num in [-1, -100]: py.test.raises(objspace.WrappingError, space.wrap_uint, num) for obj in [space.wrap_char('a'), space.wrap_int(-1)]: py.test.raises(objspace.UnwrappingError, space.unwrap_uint, obj) byteobj = space.wrap_uint(sys.maxint + 1) byteobj.bytes.append('\x01') py.test.raises(objspace.UnwrappingError, space.unwrap_uint, byteobj) + + at py.test.skipif("sys.maxint > 2147483647") +def test_ruint_max(): + from rpython.rlib.rarithmetic import r_uint + num = r_uint(sys.maxint + 1) + assert space.unwrap_uint(space.wrap_uint(num)) == num + num = -sys.maxint + py.test.raises(objspace.WrappingError, space.wrap_uint, num) + From noreply at buildbot.pypy.org Thu Feb 14 14:26:42 2013 From: noreply at buildbot.pypy.org (krono) Date: Thu, 14 Feb 2013 14:26:42 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: remove autopath Message-ID: <20130214132642.ADAB01C00A8@cobra.cs.uni-duesseldorf.de> Author: Tobias Pape Branch: Changeset: r23:27343cfd74c8 Date: 2013-02-14 14:26 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/27343cfd74c8/ Log: remove autopath diff --git a/spyvm/autopath1.py b/spyvm/autopath1.py deleted file mode 100644 --- a/spyvm/autopath1.py +++ /dev/null @@ -1,5 +0,0 @@ -import sys, os - -spyvm = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) -if spyvm not in sys.path: - sys.path.insert(0, spyvm) diff --git a/spyvm/objspace.py b/spyvm/objspace.py --- a/spyvm/objspace.py +++ b/spyvm/objspace.py @@ -172,7 +172,7 @@ return self.wrap_int(intmask(val)) except WrappingError: pass - # XXX this is not really working well on 64 bit machines + # XXX is math allowed here? import math bytes_len = max(4, int(math.log(val, 0xff)) + 1) w_result = model.W_BytesObject(self.classtable['w_LargePositiveInteger'], bytes_len) diff --git a/spyvm/test/jit.py b/spyvm/test/jit.py new file mode 100755 --- /dev/null +++ b/spyvm/test/jit.py @@ -0,0 +1,89 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# view jit. +# + +import sys +from rpython import conftest +class o: + view = False + viewloops = True +conftest.option = o + +from rpython.jit.metainterp.test.test_ajit import LLJitMixin + + +from spyvm import model, interpreter, primitives, shadow +from spyvm import objspace +from spyvm.tool.analyseimage import create_squeakimage + + +mockclass = objspace.bootstrap_class + +space = objspace.ObjSpace() + +# expose the bytecode's values as global constants. +# Bytecodes that have a whole range are exposed as global functions: +# call them with an argument 'n' to get the bytecode number 'base + n'. +# XXX hackish +def setup(): + def make_getter(entry): + def get_opcode_chr(n): + opcode = entry[0] + n + assert entry[0] <= opcode <= entry[1] + return chr(opcode) + return get_opcode_chr + for entry in interpreter.BYTECODE_RANGES: + name = entry[-1] + if len(entry) == 2: # no range + globals()[name] = chr(entry[0]) + else: + globals()[name] = make_getter(entry) +setup() + +# +# Tests +# + +sys.setrecursionlimit(100000) + +class TestLLtype(LLJitMixin): + + + def test_tiny_benchmarks(self): + + def tinyBenchmarks(): + from spyvm import objspace + space = objspace.ObjSpace() + image = create_squeakimage(space) + interp = interpreter.Interpreter(space) + + w_object = model.W_SmallInteger(0) + + s_class = w_object.shadow_of_my_class(space) + w_method = s_class.lookup("tinyBenchmarks") + + assert w_method + w_frame = w_method.create_frame(space, w_object, []) + interp.store_w_active_context(w_frame) + + counter = 0 + + from spyvm.interpreter import BYTECODE_TABLE + return interp + + interp = tinyBenchmarks() + def interp_w(): + counter = 0 + try: + while True: + counter += 1 + interp.bytecode_step_translated() + if counter == 100000: + counter = 0 + except interpreter.ReturnFromTopLevel, e: + w_result = e.object + + self.meta_interp(interp_w, [], listcomp=True, listops=True, backendopt=True) + diff --git a/spyvm/tool/analyseimage.py b/spyvm/tool/analyseimage.py --- a/spyvm/tool/analyseimage.py +++ b/spyvm/tool/analyseimage.py @@ -1,4 +1,3 @@ -import autopath import py from spyvm import squeakimage from spyvm import constants @@ -6,7 +5,7 @@ from spyvm import interpreter import sys -mini_image = py.magic.autopath().dirpath().dirpath().join('mini.image') +mini_image = py.path.local(__file__).dirpath().dirpath().join('mini.image') def get_miniimage(space): return squeakimage.ImageReader(space, squeakimage.Stream(mini_image.open())) diff --git a/spyvm/tool/autopath.py b/spyvm/tool/autopath.py deleted file mode 100644 --- a/spyvm/tool/autopath.py +++ /dev/null @@ -1,135 +0,0 @@ -""" -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 don't have the part - an EnvironmentError is raised.""" - - import sys, os - try: - head = this_dir = os.path.realpath(os.path.dirname(__file__)) - except NameError: - head = this_dir = os.path.realpath(os.path.dirname(sys.argv[0])) - - error = None - while head: - partdir = head - head, tail = os.path.split(head) - if tail == part: - # check if "../py/__init__.py" exists - checkfile = os.path.join(partdir, os.pardir, 'py', '__init__.py') - if not os.path.exists(checkfile): - error = "Cannot find %r" % (os.path.normpath(checkfile),) - break - else: - error = "Cannot find the parent directory %r of the path %r" % ( - partdir, this_dir) - if not error: - # check for bogus end-of-line style (e.g. files checked out on - # Windows and moved to Unix) - f = open(__file__.replace('.pyc', '.py'), 'r') - data = f.read() - f.close() - if data.endswith('\r\n') or data.endswith('\r'): - error = ("Bad end-of-line style in the .py files. Typically " - "caused by a zip file or a checkout done on Windows and " - "moved to Unix or vice-versa.") - if error: - raise EnvironmentError("Invalid source tree - bogus checkout! " + - error) - - pypy_root = os.path.join(head, '') - try: - sys.path.remove(head) - except ValueError: - pass - sys.path.insert(0, head) - - munged = {} - for name, mod in sys.modules.items(): - if '.' in name: - continue - fn = getattr(mod, '__file__', None) - if not isinstance(fn, str): - continue - newname = os.path.splitext(os.path.basename(fn))[0] - if not newname.startswith(part + '.'): - continue - path = os.path.join(os.path.dirname(os.path.realpath(fn)), '') - if path.startswith(pypy_root) and newname != part: - modpaths = os.path.normpath(path[len(pypy_root):]).split(os.sep) - if newname != '__init__': - modpaths.append(newname) - modpath = '.'.join(modpaths) - if modpath not in sys.modules: - munged[modpath] = mod - - for name, mod in munged.iteritems(): - if name not in sys.modules: - sys.modules[name] = mod - if '.' in name: - prename = name[:name.rfind('.')] - postname = name[len(prename)+1:] - if prename not in sys.modules: - __import__(prename) - if not hasattr(sys.modules[prename], postname): - setattr(sys.modules[prename], postname, mod) - - return partdir, this_dir - -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') -import py -libpythondir = str(py.path.local(pypydir).dirpath().join('lib-python', '2.5.2')) -libpythonmodifieddir = str(py.path.local(libpythondir).dirpath().join('modified-2.5.2')) - -if __name__ == '__main__': - __clone() From noreply at buildbot.pypy.org Thu Feb 14 14:38:34 2013 From: noreply at buildbot.pypy.org (krono) Date: Thu, 14 Feb 2013 14:38:34 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: step by step Message-ID: <20130214133834.35A161C061B@cobra.cs.uni-duesseldorf.de> Author: Tobias Pape Branch: Changeset: r24:dd401696209d Date: 2013-02-14 14:38 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/dd401696209d/ Log: step by step diff --git a/spyvm/fixedstack.py b/spyvm/fixedstack.py --- a/spyvm/fixedstack.py +++ b/spyvm/fixedstack.py @@ -7,7 +7,7 @@ from rpython.rlib.rarithmetic import r_uint class FixedStack(object): - _annspecialcase_ = "specialize:ctr_location" # polymorphic + # _annspecialcase_ = "specialize:ctr_location" # polymorphic def __init__(self): pass diff --git a/spyvm/test/jit.py b/spyvm/test/jit.py --- a/spyvm/test/jit.py +++ b/spyvm/test/jit.py @@ -79,7 +79,8 @@ try: while True: counter += 1 - interp.bytecode_step_translated() + s_active_context = interp.s_active_context() + interp.bytecode_step_translated(s_active_context) if counter == 100000: counter = 0 except interpreter.ReturnFromTopLevel, e: From noreply at buildbot.pypy.org Thu Feb 14 15:06:18 2013 From: noreply at buildbot.pypy.org (arigo) Date: Thu, 14 Feb 2013 15:06:18 +0100 (CET) Subject: [pypy-commit] pypy default: Fix the imports: instead of "import rthread as thread", use the name Message-ID: <20130214140618.F3B8C1C071D@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r61231:adadaf3b93c0 Date: 2013-02-14 15:06 +0100 http://bitbucket.org/pypy/pypy/changeset/adadaf3b93c0/ Log: Fix the imports: instead of "import rthread as thread", use the name "rthread" throughout the files, which is less confusing. diff --git a/pypy/module/thread/gil.py b/pypy/module/thread/gil.py --- a/pypy/module/thread/gil.py +++ b/pypy/module/thread/gil.py @@ -7,7 +7,7 @@ # all but one will be blocked. The other threads get a chance to run # from time to time, using the periodic action GILReleaseAction. -from rpython.rlib import rthread as thread +from rpython.rlib import rthread from pypy.module.thread.error import wrap_thread_error from pypy.interpreter.executioncontext import PeriodicAsyncAction from pypy.module.thread.threadlocals import OSThreadLocals @@ -25,7 +25,7 @@ use_bytecode_counter=True) def _initialize_gil(self, space): - if not thread.gil_allocate(): + if not rthread.gil_allocate(): raise wrap_thread_error(space, "can't allocate GIL") def setup_threads(self, space): @@ -72,15 +72,15 @@ # this function must not raise, in such a way that the exception # transformer knows that it cannot raise! e = get_errno() - thread.gil_release() + rthread.gil_release() set_errno(e) before_external_call._gctransformer_hint_cannot_collect_ = True before_external_call._dont_reach_me_in_del_ = True def after_external_call(): e = get_errno() - thread.gil_acquire() - thread.gc_thread_run() + rthread.gil_acquire() + rthread.gc_thread_run() after_thread_switch() set_errno(e) after_external_call._gctransformer_hint_cannot_collect_ = True @@ -97,8 +97,8 @@ # explicitly release the gil, in a way that tries to give more # priority to other threads (as opposed to continuing to run in # the same thread). - if thread.gil_yield_thread(): - thread.gc_thread_run() + if rthread.gil_yield_thread(): + rthread.gc_thread_run() after_thread_switch() do_yield_thread._gctransformer_hint_close_stack_ = True do_yield_thread._dont_reach_me_in_del_ = True diff --git a/pypy/module/thread/os_lock.py b/pypy/module/thread/os_lock.py --- a/pypy/module/thread/os_lock.py +++ b/pypy/module/thread/os_lock.py @@ -2,15 +2,12 @@ Python locks, based on true threading locks provided by the OS. """ -from rpython.rlib import rthread as thread +from rpython.rlib import rthread from pypy.module.thread.error import wrap_thread_error from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.gateway import interp2app, unwrap_spec from pypy.interpreter.typedef import TypeDef -# Force the declaration of the type 'thread.LockType' for RPython -#import pypy.module.thread.rpython.exttable - ##import sys ##def debug(msg, n): @@ -22,7 +19,7 @@ ## except: ## pass ## tb = ' '.join(tb) -## msg = '| %6d | %d %s | %s\n' % (thread.get_ident(), n, msg, tb) +## msg = '| %6d | %d %s | %s\n' % (rthread.get_ident(), n, msg, tb) ## sys.stderr.write(msg) @@ -32,8 +29,8 @@ def __init__(self, space): self.space = space try: - self.lock = thread.allocate_lock() - except thread.error: + self.lock = rthread.allocate_lock() + except rthread.error: raise wrap_thread_error(space, "out of resources") @unwrap_spec(waitflag=int) @@ -54,7 +51,7 @@ but it needn't be locked by the same thread that unlocks it.""" try: self.lock.release() - except thread.error: + except rthread.error: raise wrap_thread_error(space, "release unlocked lock") def descr_lock_locked(self, space): diff --git a/pypy/module/thread/os_thread.py b/pypy/module/thread/os_thread.py --- a/pypy/module/thread/os_thread.py +++ b/pypy/module/thread/os_thread.py @@ -3,7 +3,7 @@ """ import os -from rpython.rlib import rthread as thread +from rpython.rlib import rthread from pypy.module.thread.error import wrap_thread_error from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.gateway import unwrap_spec, Arguments @@ -65,8 +65,8 @@ def setup(space): if bootstrapper.lock is None: try: - bootstrapper.lock = thread.allocate_lock() - except thread.error: + bootstrapper.lock = rthread.allocate_lock() + except rthread.error: raise wrap_thread_error(space, "can't allocate bootstrap lock") @staticmethod @@ -83,7 +83,7 @@ # Note that when this runs, we already hold the GIL. This is ensured # by rffi's callback mecanism: we are a callback for the # c_thread_start() external function. - thread.gc_thread_start() + rthread.gc_thread_start() space = bootstrapper.space w_callable = bootstrapper.w_callable args = bootstrapper.args @@ -103,7 +103,7 @@ except OSError: pass bootstrapper.nbthreads -= 1 - thread.gc_thread_die() + rthread.gc_thread_die() bootstrap = staticmethod(bootstrap) def acquire(space, w_callable, args): @@ -130,7 +130,7 @@ space.call_args(w_callable, args) except OperationError, e: if not e.match(space, space.w_SystemExit): - ident = thread.get_ident() + ident = rthread.get_ident() where = 'thread %d started by ' % ident e.write_unraisable(space, where, w_callable) e.clear(space) @@ -150,7 +150,7 @@ "Called in the child process after a fork()" space.threadlocals.reinit_threads(space) bootstrapper.reinit() - thread.thread_after_fork() + rthread.thread_after_fork() # Clean the threading module after a fork() w_modules = space.sys.get('modules') @@ -181,12 +181,12 @@ bootstrapper.acquire(space, w_callable, args) try: try: - thread.gc_thread_prepare() # (this has no effect any more) - ident = thread.start_new_thread(bootstrapper.bootstrap, ()) + rthread.gc_thread_prepare() # (this has no effect any more) + ident = rthread.start_new_thread(bootstrapper.bootstrap, ()) except Exception, e: bootstrapper.release() # normally called by the new thread raise - except thread.error: + except rthread.error: raise wrap_thread_error(space, "can't start new thread") return space.wrap(ident) @@ -199,7 +199,7 @@ allocated consecutive numbers starting at 1, this behavior should not be relied upon, and the number should be seen purely as a magic cookie. A thread's identity may be reused for another thread after it exits.""" - ident = thread.get_ident() + ident = rthread.get_ident() return space.wrap(ident) @unwrap_spec(size=int) @@ -225,8 +225,8 @@ if size < 0: raise OperationError(space.w_ValueError, space.wrap("size must be 0 or a positive value")) - old_size = thread.get_stacksize() - error = thread.set_stacksize(size) + old_size = rthread.get_stacksize() + error = rthread.set_stacksize(size) if error == -1: raise operationerrfmt(space.w_ValueError, "size not valid: %d bytes", size) diff --git a/pypy/module/thread/threadlocals.py b/pypy/module/thread/threadlocals.py --- a/pypy/module/thread/threadlocals.py +++ b/pypy/module/thread/threadlocals.py @@ -1,4 +1,4 @@ -from rpython.rlib import rthread as thread +from rpython.rlib import rthread class OSThreadLocals: @@ -18,7 +18,7 @@ self._mostrecentvalue = None # fast minicaching for the common case def getvalue(self): - ident = thread.get_ident() + ident = rthread.get_ident() if ident == self._mostrecentkey: result = self._mostrecentvalue else: @@ -30,7 +30,7 @@ return result def setvalue(self, value): - ident = thread.get_ident() + ident = rthread.get_ident() if value is not None: if len(self._valuedict) == 0: self._mainthreadident = ident @@ -45,7 +45,7 @@ self._mostrecentvalue = value def ismainthread(self): - return thread.get_ident() == self._mainthreadident + return rthread.get_ident() == self._mainthreadident def getallvalues(self): return self._valuedict @@ -60,4 +60,4 @@ def reinit_threads(self, space): "Called in the child process after a fork()" - self._mainthreadident = thread.get_ident() + self._mainthreadident = rthread.get_ident() From noreply at buildbot.pypy.org Thu Feb 14 15:27:29 2013 From: noreply at buildbot.pypy.org (krono) Date: Thu, 14 Feb 2013 15:27:29 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: force size of ByteObject to be integer typey; use interpret in jit-grapher Message-ID: <20130214142729.405381C00A8@cobra.cs.uni-duesseldorf.de> Author: Tobias Pape Branch: Changeset: r25:d9a275c053b1 Date: 2013-02-14 15:26 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/d9a275c053b1/ Log: force size of ByteObject to be integer typey; use interpret in jit- grapher diff --git a/spyvm/model.py b/spyvm/model.py --- a/spyvm/model.py +++ b/spyvm/model.py @@ -361,6 +361,7 @@ class W_BytesObject(W_AbstractObjectWithClassReference): def __init__(self, w_class, size): W_AbstractObjectWithClassReference.__init__(self, w_class) + assert isinstance(size, int) self.bytes = ['\x00'] * size def at0(self, space, index0): diff --git a/spyvm/objspace.py b/spyvm/objspace.py --- a/spyvm/objspace.py +++ b/spyvm/objspace.py @@ -174,7 +174,8 @@ pass # XXX is math allowed here? import math - bytes_len = max(4, int(math.log(val, 0xff)) + 1) + bytes_len = int(math.log(val) / math.log(0xff)) + 1 + bytes_len = 4 if 4 > bytes_len else bytes_len w_result = model.W_BytesObject(self.classtable['w_LargePositiveInteger'], bytes_len) for i in range(bytes_len): w_result.setchar(i, chr(intmask((val >> i*8) & 255))) diff --git a/spyvm/test/jit.py b/spyvm/test/jit.py --- a/spyvm/test/jit.py +++ b/spyvm/test/jit.py @@ -75,16 +75,9 @@ interp = tinyBenchmarks() def interp_w(): - counter = 0 - try: - while True: - counter += 1 - s_active_context = interp.s_active_context() - interp.bytecode_step_translated(s_active_context) - if counter == 100000: - counter = 0 - except interpreter.ReturnFromTopLevel, e: - w_result = e.object + interp.interpret() - self.meta_interp(interp_w, [], listcomp=True, listops=True, backendopt=True) + self.meta_interp(interp_w, [], listcomp=True, listops=True, + #backendopt=True + ) From noreply at buildbot.pypy.org Thu Feb 14 15:43:19 2013 From: noreply at buildbot.pypy.org (cfbolz) Date: Thu, 14 Feb 2013 15:43:19 +0100 (CET) Subject: [pypy-commit] pypy default: Add an assertion that the number of constants in a function is only up to 256. Message-ID: <20130214144319.23FF81C061B@cobra.cs.uni-duesseldorf.de> Author: Carl Friedrich Bolz Branch: Changeset: r61232:aabdafe82886 Date: 2013-02-14 15:42 +0100 http://bitbucket.org/pypy/pypy/changeset/aabdafe82886/ Log: Add an assertion that the number of constants in a function is only up to 256. I just ran into the problem and the behaviour is very confusing. diff --git a/rpython/jit/codewriter/assembler.py b/rpython/jit/codewriter/assembler.py --- a/rpython/jit/codewriter/assembler.py +++ b/rpython/jit/codewriter/assembler.py @@ -107,7 +107,9 @@ key = (kind, Constant(value)) if key not in self.constants_dict: constants.append(value) - self.constants_dict[key] = 256 - len(constants) + val = 256 - len(constants) + assert val >= 0, "too many constants" + self.constants_dict[key] = val # emit the constant normally, as one byte that is an index in the # list of constants self.code.append(chr(self.constants_dict[key])) From noreply at buildbot.pypy.org Thu Feb 14 15:49:28 2013 From: noreply at buildbot.pypy.org (taavi_burns) Date: Thu, 14 Feb 2013 15:49:28 +0100 (CET) Subject: [pypy-commit] pypy stm-thread-2: Fixes rpython.rlib.thread import. Message-ID: <20130214144928.074141C1D5D@cobra.cs.uni-duesseldorf.de> Author: Taavi Burns Branch: stm-thread-2 Changeset: r61233:0378c78cc316 Date: 2013-02-13 15:53 -0500 http://bitbucket.org/pypy/pypy/changeset/0378c78cc316/ Log: Fixes rpython.rlib.thread import. diff --git a/pypy/module/thread/stm.py b/pypy/module/thread/stm.py --- a/pypy/module/thread/stm.py +++ b/pypy/module/thread/stm.py @@ -4,7 +4,7 @@ from pypy.module.thread.threadlocals import OSThreadLocals from pypy.module.thread.error import wrap_thread_error -from pypy.module.thread import ll_thread +from rpython.rlib import rthread as thread from rpython.rlib import rstm from rpython.rlib.objectmodel import invoke_around_extcall @@ -44,21 +44,21 @@ rstm.set_transaction_length(interval) -class STMLock(ll_thread.Lock): +class STMLock(thread.Lock): def __init__(self, space, ll_lock): - ll_thread.Lock.__init__(self, ll_lock) + thread.Lock.__init__(self, ll_lock) self.space = space def acquire(self, flag): if rstm.is_atomic(): - acquired = ll_thread.Lock.acquire(self, False) + acquired = thread.Lock.acquire(self, False) if flag and not acquired: raise wrap_thread_error(self.space, "deadlock: an atomic transaction tries to acquire " "a lock that is already acquired. See pypy/doc/stm.rst.") else: - acquired = ll_thread.Lock.acquire(self, flag) + acquired = thread.Lock.acquire(self, flag) return acquired def allocate_stm_lock(space): - return STMLock(space, ll_thread.allocate_ll_lock()) + return STMLock(space, thread.allocate_ll_lock()) From noreply at buildbot.pypy.org Thu Feb 14 15:49:29 2013 From: noreply at buildbot.pypy.org (arigo) Date: Thu, 14 Feb 2013 15:49:29 +0100 (CET) Subject: [pypy-commit] pypy stm-thread-2: Avoid renaming the module on import; there is not really a point here now. Message-ID: <20130214144929.8FF291C1D5D@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stm-thread-2 Changeset: r61234:e090ba752fa1 Date: 2013-02-14 12:15 +0100 http://bitbucket.org/pypy/pypy/changeset/e090ba752fa1/ Log: Avoid renaming the module on import; there is not really a point here now. diff --git a/pypy/module/thread/stm.py b/pypy/module/thread/stm.py --- a/pypy/module/thread/stm.py +++ b/pypy/module/thread/stm.py @@ -4,7 +4,7 @@ from pypy.module.thread.threadlocals import OSThreadLocals from pypy.module.thread.error import wrap_thread_error -from rpython.rlib import rthread as thread +from rpython.rlib import rthread from rpython.rlib import rstm from rpython.rlib.objectmodel import invoke_around_extcall @@ -44,21 +44,21 @@ rstm.set_transaction_length(interval) -class STMLock(thread.Lock): +class STMLock(rthread.Lock): def __init__(self, space, ll_lock): - thread.Lock.__init__(self, ll_lock) + rthread.Lock.__init__(self, ll_lock) self.space = space def acquire(self, flag): if rstm.is_atomic(): - acquired = thread.Lock.acquire(self, False) + acquired = rthread.Lock.acquire(self, False) if flag and not acquired: raise wrap_thread_error(self.space, "deadlock: an atomic transaction tries to acquire " "a lock that is already acquired. See pypy/doc/stm.rst.") else: - acquired = thread.Lock.acquire(self, flag) + acquired = rthread.Lock.acquire(self, flag) return acquired def allocate_stm_lock(space): - return STMLock(space, thread.allocate_ll_lock()) + return STMLock(space, rthread.allocate_ll_lock()) From noreply at buildbot.pypy.org Thu Feb 14 15:49:30 2013 From: noreply at buildbot.pypy.org (arigo) Date: Thu, 14 Feb 2013 15:49:30 +0100 (CET) Subject: [pypy-commit] pypy stm-thread-2: Ignore for now jitdrivers with autoreds. Message-ID: <20130214144930.DBE8E1C1D5D@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stm-thread-2 Changeset: r61235:851ee1a2522d Date: 2013-02-14 12:51 +0100 http://bitbucket.org/pypy/pypy/changeset/851ee1a2522d/ Log: Ignore for now jitdrivers with autoreds. diff --git a/rpython/translator/stm/jitdriver.py b/rpython/translator/stm/jitdriver.py --- a/rpython/translator/stm/jitdriver.py +++ b/rpython/translator/stm/jitdriver.py @@ -17,7 +17,13 @@ op = block.operations[i] if (op.opname == 'jit_marker' and op.args[0].value == 'jit_merge_point'): - found.append((block, i)) + jitdriver = op.args[1].value + if not jitdriver.autoreds: + found.append((block, i)) + else: + from rpython.translator.c.support import log + log.WARNING("ignoring jitdriver with autoreds in %r" % ( + graph,)) # XXX XXX! if found: assert len(found) == 1, "several jit_merge_point's in %r" % (graph,) return found[0] @@ -83,7 +89,7 @@ assert op_jitmarker.opname == 'jit_marker' assert op_jitmarker.args[0].value == 'jit_merge_point' jitdriver = op_jitmarker.args[1].value - assert not jitdriver.autoreds # XXX + assert not jitdriver.autoreds # fix me def split_after_jit_merge_point(self, (portalblock, portalopindex)): link = split_block(None, portalblock, portalopindex + 1) From noreply at buildbot.pypy.org Thu Feb 14 15:49:32 2013 From: noreply at buildbot.pypy.org (arigo) Date: Thu, 14 Feb 2013 15:49:32 +0100 (CET) Subject: [pypy-commit] pypy stm-thread-2: Fix imports Message-ID: <20130214144932.22B6D1C1D5D@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stm-thread-2 Changeset: r61236:5b24155f6506 Date: 2013-02-14 14:04 +0000 http://bitbucket.org/pypy/pypy/changeset/5b24155f6506/ Log: Fix imports diff --git a/rpython/rtyper/memory/gc/stmgc.py b/rpython/rtyper/memory/gc/stmgc.py --- a/rpython/rtyper/memory/gc/stmgc.py +++ b/rpython/rtyper/memory/gc/stmgc.py @@ -7,7 +7,6 @@ from rpython.rlib.rarithmetic import LONG_BIT, r_uint from rpython.rlib.debug import ll_assert, debug_start, debug_stop, fatalerror from rpython.rlib.debug import debug_print -from pypy.module.thread import ll_thread WORD = LONG_BIT // 8 diff --git a/rpython/translator/stm/test/targetjit1.py b/rpython/translator/stm/test/targetjit1.py --- a/rpython/translator/stm/test/targetjit1.py +++ b/rpython/translator/stm/test/targetjit1.py @@ -1,5 +1,4 @@ -from pypy.module.thread import ll_thread -from rpython.rlib import jit, rstm +from rpython.rlib import jit, rstm, rthread from rpython.rlib.objectmodel import invoke_around_extcall @@ -48,7 +47,7 @@ def __init__(self, i): self.index = i self.value = 0 - self.finished_lock = ll_thread.allocate_lock() + self.finished_lock = rthread.allocate_lock() self.finished_lock.acquire(True) def run(self): @@ -78,7 +77,7 @@ @staticmethod def setup(): if bootstrapper.lock is None: - bootstrapper.lock = ll_thread.allocate_lock() + bootstrapper.lock = rthread.allocate_lock() @staticmethod def reinit(): @@ -94,14 +93,14 @@ # Note that when this runs, we already hold the GIL. This is ensured # by rffi's callback mecanism: we are a callback for the # c_thread_start() external function. - ll_thread.gc_thread_start() + rthread.gc_thread_start() args = bootstrapper.args bootstrapper.release() # run! try: args.run() finally: - ll_thread.gc_thread_die() + rthread.gc_thread_die() @staticmethod def acquire(args): @@ -130,8 +129,8 @@ def start_thread(args): bootstrapper.acquire(args) try: - ll_thread.gc_thread_prepare() # (this has no effect any more) - ident = ll_thread.start_new_thread(bootstrapper.bootstrap, ()) + rthread.gc_thread_prepare() # (this has no effect any more) + ident = rthread.start_new_thread(bootstrapper.bootstrap, ()) except Exception, e: bootstrapper.release() # normally called by the new thread raise From noreply at buildbot.pypy.org Thu Feb 14 15:49:33 2013 From: noreply at buildbot.pypy.org (arigo) Date: Thu, 14 Feb 2013 15:49:33 +0100 (CET) Subject: [pypy-commit] pypy stm-thread-2: Unclear why it occurs here and not on "default", but we need to prevent multiple #includes of this file Message-ID: <20130214144933.710051C1D5D@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stm-thread-2 Changeset: r61237:3b4ede83d81c Date: 2013-02-14 14:49 +0000 http://bitbucket.org/pypy/pypy/changeset/3b4ede83d81c/ Log: Unclear why it occurs here and not on "default", but we need to prevent multiple #includes of this file diff --git a/rpython/translator/c/src/stack.h b/rpython/translator/c/src/stack.h --- a/rpython/translator/c/src/stack.h +++ b/rpython/translator/c/src/stack.h @@ -2,6 +2,10 @@ /************************************************************/ /*** C header subsection: stack operations ***/ +#ifndef _RPY_STACK_H_ +#define _RPY_STACK_H_ + + #ifndef MAX_STACK_SIZE # define MAX_STACK_SIZE (3 << 18) /* 768 kb */ #endif @@ -35,3 +39,4 @@ #endif +#endif /* _RPY_STACK_H_ */ From noreply at buildbot.pypy.org Thu Feb 14 15:53:44 2013 From: noreply at buildbot.pypy.org (lwassermann) Date: Thu, 14 Feb 2013 15:53:44 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: add jitdriver, fix translation Message-ID: <20130214145344.89EB91C1D5D@cobra.cs.uni-duesseldorf.de> Author: Lars Wassermann Branch: Changeset: r26:cee7d1098087 Date: 2013-02-14 14:52 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/cee7d1098087/ Log: add jitdriver, fix translation diff --git a/spyvm/interpreter.py b/spyvm/interpreter.py --- a/spyvm/interpreter.py +++ b/spyvm/interpreter.py @@ -5,6 +5,7 @@ from spyvm import conftest from spyvm import wrapper +from rpython.rlib import jit from rpython.rlib import objectmodel, unroll class MissingBytecode(Exception): @@ -16,11 +17,19 @@ class IllegalStoreError(Exception): """Illegal Store.""" +def get_printable_location(self, pc, w_method): + return '%d: %s' % (pc, w_method.bytes[pc]) + class Interpreter(object): _w_last_active_context = None cnt = 0 _last_indent = "" + jit_driver = jit.JitDriver( + greens = ['self', 'pc', 'w_method'], + reds = ['s_active_context'], + get_printable_location = get_printable_location + ) def __init__(self, space, image_name=""): self._w_active_context = None @@ -81,15 +90,18 @@ bytecodeimpl(s_active_context, self) def loop(self): - # we_are_translated returns false on top of CPython and true when - # translating the interpreter - if not objectmodel.we_are_translated(): - step = Interpreter.step - else: - step = bytecode_step_translated while True: s_active_context = self.s_active_context() - step(self, s_active_context) + pc = s_active_context._pc + w_method = s_active_context.w_method() + + self.jit_driver.jit_merge_point( + self = self, + pc = pc, + w_method = w_method, + s_active_context = s_active_context) + + self.step(s_active_context) class ReturnFromTopLevel(Exception): @@ -461,7 +473,6 @@ def bytecodePrimPointY(self, interp): self._sendSelfSelector("y", 0, interp) - BYTECODE_RANGES = [ ( 0, 15, "pushReceiverVariableBytecode"), ( 16, 31, "pushTemporaryVariableBytecode"), @@ -578,3 +589,8 @@ return miniglob["bytecode_step_translated"] bytecode_step_translated = make_bytecode_dispatch_translated() + +# we_are_translated returns false on top of CPython and true when +# translating the interpreter +# if objectmodel.we_are_translated(): +Interpreter.step = bytecode_step_translated diff --git a/spyvm/objspace.py b/spyvm/objspace.py --- a/spyvm/objspace.py +++ b/spyvm/objspace.py @@ -174,7 +174,8 @@ pass # XXX is math allowed here? import math - bytes_len = max(4, int(math.log(val, 0xff)) + 1) + bytes_len = int(math.log(val) / math.log(0xff)) + 1 + bytes_len = 4 if 4 > bytes_len else bytes_len w_result = model.W_BytesObject(self.classtable['w_LargePositiveInteger'], bytes_len) for i in range(bytes_len): w_result.setchar(i, chr(intmask((val >> i*8) & 255))) diff --git a/spyvm/targettinybenchsmalltalk.py b/spyvm/targettinybenchsmalltalk.py --- a/spyvm/targettinybenchsmalltalk.py +++ b/spyvm/targettinybenchsmalltalk.py @@ -3,6 +3,8 @@ from spyvm import model, interpreter, primitives, shadow, constants from spyvm.tool.analyseimage import create_squeakimage +from rpython.jit.codewriter.policy import JitPolicy + # This loads the whole mini.image in advance. At run-time, # it executes the tinyBenchmark. In this way we get an RPython # "image" frozen into the executable, mmap'ed by the OS from @@ -44,7 +46,7 @@ try: while True: counter += 1 - interp.step() + interp.interpret() if counter == 100000: counter = 0 os.write(2, '#') @@ -60,3 +62,6 @@ def target(*args): return entry_point, None + +def jitpolicy(driver): + return JitPolicy() \ No newline at end of file From noreply at buildbot.pypy.org Thu Feb 14 15:53:45 2013 From: noreply at buildbot.pypy.org (lwassermann) Date: Thu, 14 Feb 2013 15:53:45 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: make spyvm translate Message-ID: <20130214145345.961651C1D5D@cobra.cs.uni-duesseldorf.de> Author: Lars Wassermann Branch: Changeset: r27:b5b267b6b378 Date: 2013-02-14 15:47 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/b5b267b6b378/ Log: make spyvm translate diff --git a/spyvm/interpreter.py b/spyvm/interpreter.py --- a/spyvm/interpreter.py +++ b/spyvm/interpreter.py @@ -17,7 +17,7 @@ class IllegalStoreError(Exception): """Illegal Store.""" -def get_printable_location(self, pc, w_method): +def get_printable_location(pc, self, w_method): return '%d: %s' % (pc, w_method.bytes[pc]) class Interpreter(object): @@ -26,7 +26,7 @@ cnt = 0 _last_indent = "" jit_driver = jit.JitDriver( - greens = ['self', 'pc', 'w_method'], + greens = ['pc', 'self', 'w_method'], reds = ['s_active_context'], get_printable_location = get_printable_location ) @@ -228,7 +228,7 @@ code = method.primitive if interp.should_trace(): print "%sActually calling primitive %d" % (interp._last_indent, code,) - if objectmodel.we_are_translated(): + if False: #objectmodel.we_are_translated(): for i, func in primitives.unrolling_prim_table: if i == code: try: diff --git a/spyvm/primitives.py b/spyvm/primitives.py --- a/spyvm/primitives.py +++ b/spyvm/primitives.py @@ -7,7 +7,7 @@ PrimitiveNotYetWrittenError from spyvm import wrapper -from rpython.rlib import rarithmetic, rfloat, unroll +from rpython.rlib import rarithmetic, rfloat, unroll, jit def assert_bounds(n0, minimum, maximum): if not minimum <= n0 < maximum: @@ -619,6 +619,7 @@ @expose_primitive(INC_GC, unwrap_spec=[object]) @expose_primitive(FULL_GC, unwrap_spec=[object]) + at jit.dont_look_inside def func(interp, w_arg): # Squeak pops the arg and ignores it ... go figure from rpython.rlib import rgc rgc.collect() From noreply at buildbot.pypy.org Thu Feb 14 15:53:46 2013 From: noreply at buildbot.pypy.org (lwassermann) Date: Thu, 14 Feb 2013 15:53:46 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: merge Message-ID: <20130214145346.AD4811C1D5D@cobra.cs.uni-duesseldorf.de> Author: Lars Wassermann Branch: Changeset: r28:c9013e79ed43 Date: 2013-02-14 15:53 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/c9013e79ed43/ Log: merge diff --git a/spyvm/model.py b/spyvm/model.py --- a/spyvm/model.py +++ b/spyvm/model.py @@ -361,6 +361,7 @@ class W_BytesObject(W_AbstractObjectWithClassReference): def __init__(self, w_class, size): W_AbstractObjectWithClassReference.__init__(self, w_class) + assert isinstance(size, int) self.bytes = ['\x00'] * size def at0(self, space, index0): diff --git a/spyvm/test/jit.py b/spyvm/test/jit.py --- a/spyvm/test/jit.py +++ b/spyvm/test/jit.py @@ -75,16 +75,9 @@ interp = tinyBenchmarks() def interp_w(): - counter = 0 - try: - while True: - counter += 1 - s_active_context = interp.s_active_context() - interp.bytecode_step_translated(s_active_context) - if counter == 100000: - counter = 0 - except interpreter.ReturnFromTopLevel, e: - w_result = e.object + interp.interpret() - self.meta_interp(interp_w, [], listcomp=True, listops=True, backendopt=True) + self.meta_interp(interp_w, [], listcomp=True, listops=True, + #backendopt=True + ) From noreply at buildbot.pypy.org Thu Feb 14 16:44:12 2013 From: noreply at buildbot.pypy.org (bivab) Date: Thu, 14 Feb 2013 16:44:12 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: start fixing call_assembler for ARM Message-ID: <20130214154412.6EE461C00BD@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: jitframe-on-heap Changeset: r61238:1dd0aa6c631a Date: 2013-02-14 16:43 +0100 http://bitbucket.org/pypy/pypy/changeset/1dd0aa6c631a/ Log: start fixing call_assembler for ARM floats do not work correctly yet diff --git a/rpython/jit/backend/arm/opassembler.py b/rpython/jit/backend/arm/opassembler.py --- a/rpython/jit/backend/arm/opassembler.py +++ b/rpython/jit/backend/arm/opassembler.py @@ -1104,59 +1104,52 @@ # XXX Split into some helper methods def emit_guard_call_assembler(self, op, guard_op, arglocs, regalloc, fcond): - tmploc = arglocs[1] - resloc = arglocs[2] - callargs = arglocs[3:] - self._store_force_index(guard_op) descr = op.getdescr() assert isinstance(descr, JitCellToken) - # check value - assert tmploc is r.r0 - self._emit_call(imm(descr._ll_function_addr), - callargs, fcond, resloc=tmploc) + if len(arglocs) == 4: + [frame_loc, vloc, result_loc, argloc] = arglocs + else: + [frame_loc, result_loc, argloc] = arglocs + vloc = imm(0) + + # + # Write a call to the target assembler + # we need to allocate the frame, keep in sync with runner's + # execute_token + jd = descr.outermost_jitdriver_sd + base_ofs = self.cpu.get_baseofs_of_frame_field() + self._emit_call(imm(descr._ll_function_addr), [argloc], fcond) if op.result is None: - value = self.cpu.done_with_this_frame_void_v + assert result_loc is None + value = self.cpu.done_with_this_frame_descr_void else: kind = op.result.type if kind == INT: - value = self.cpu.done_with_this_frame_int_v + assert result_loc is r.r0 + value = self.cpu.done_with_this_frame_descr_int elif kind == REF: - value = self.cpu.done_with_this_frame_ref_v + assert result_loc is r.r0 + value = self.cpu.done_with_this_frame_descr_ref elif kind == FLOAT: - value = self.cpu.done_with_this_frame_float_v + value = self.cpu.done_with_this_frame_descr_float else: raise AssertionError(kind) - from rpython.jit.backend.llsupport.descr import unpack_fielddescr - from rpython.jit.backend.llsupport.descr import unpack_interiorfielddescr - descrs = self.cpu.gc_ll_descr.getframedescrs(self.cpu) - _offset, _size, _ = unpack_fielddescr(descrs.jf_descr) - fail_descr = self.cpu.get_fail_descr_from_number(value) - value = fail_descr.hide(self.cpu) - rgc._make_sure_does_not_move(value) - value = rffi.cast(lltype.Signed, value) - if check_imm_arg(_offset): - self.mc.LDR_ri(r.ip.value, tmploc.value, imm=_offset) - else: - self.mc.gen_load_int(r.ip.value, _offset) - self.mc.LDR_rr(r.ip.value, tmploc.value, r.ip.value) + + gcref = cast_instance_to_gcref(value) + rgc._make_sure_does_not_move(gcref) + value = rffi.cast(lltype.Signed, gcref) + ofs = self.cpu.get_ofs_of_frame_field('jf_descr') + assert check_imm_arg(ofs) + self.mc.LDR_ri(r.ip.value, r.r0.value, imm=ofs) + if check_imm_arg(value): self.mc.CMP_ri(r.ip.value, imm=value) else: self.mc.gen_load_int(r.lr.value, value) self.mc.CMP_rr(r.lr.value, r.ip.value) - - - #if values are equal we take the fast path - # Slow path, calling helper - # jump to merge point - - jd = descr.outermost_jitdriver_sd - assert jd is not None - - # Path A: load return value and reset token - # Fast Path using result boxes + # Path 1: Fast Path fast_path_cond = c.EQ # Reset the vable token --- XXX really too much special logic here:-( @@ -1164,45 +1157,40 @@ from rpython.jit.backend.llsupport.descr import FieldDescr fielddescr = jd.vable_token_descr assert isinstance(fielddescr, FieldDescr) - ofs = fielddescr.offset - tmploc = regalloc.get_scratch_reg(INT) - self.mov_loc_loc(arglocs[0], r.ip, cond=fast_path_cond) - self.mc.MOV_ri(tmploc.value, 0, cond=fast_path_cond) - self.mc.STR_ri(tmploc.value, r.ip.value, ofs, cond=fast_path_cond) + assert isinstance(fielddescr, FieldDescr) + vtoken_ofs = fielddescr.offset + assert check_imm_arg(vtoken_ofs) + self.mov_loc_loc(vloc, r.ip, cond=fast_path_cond) + self.mc.MOV_ri(r.lr.value, 0, cond=fast_path_cond) + self.mc.STR_ri(tmploc.value, r.ip.value, vtoken_ofs, cond=fast_path_cond) + # in the line above, TOKEN_NONE = 0 if op.result is not None: - # load the return value from fail_boxes_xxx[0] + # load the return value from the dead frame's value index 0 kind = op.result.type if kind == FLOAT: - t = unpack_interiorfielddescr(descrs.as_float)[0] - if not check_imm_arg(t): - self.mc.gen_load_int(r.ip.value, t, cond=fast_path_cond) + descr = self.cpu.getarraydescr_for_frame(kind) + ofs = self.cpu.unpack_arraydescr(descr) + if not check_imm_arg(ofs): + self.mc.gen_load_int(r.ip.value, ofs, cond=fast_path_cond) self.mc.ADD_rr(r.ip.value, r.r0.value, r.ip.value, cond=fast_path_cond) - t = 0 + ofs = 0 base = r.ip else: base = r.r0 - self.mc.VLDR(resloc.value, base.value, imm=t, - cond=fast_path_cond) + self.mc.VLDR(result_loc.value, base.value, imm=ofs, + cond=fast_path_cond) else: - assert resloc is r.r0 - if kind == INT: - t = unpack_interiorfielddescr(descrs.as_int)[0] - else: - t = unpack_interiorfielddescr(descrs.as_ref)[0] - if not check_imm_arg(t): - self.mc.gen_load_int(r.ip.value, t, cond=fast_path_cond) - self.mc.LDR_rr(resloc.value, resloc.value, r.ip.value, - cond=fast_path_cond) - else: - self.mc.LDR_ri(resloc.value, resloc.value, imm=t, - cond=fast_path_cond) + assert result_loc is r.r0 + descr = self.cpu.getarraydescr_for_frame(kind) + ofs = self.cpu.unpack_arraydescr(descr) + self.load_reg(self.mc, r.r0, r.r0, ofs, cond=fast_path_cond) # jump to merge point jmp_pos = self.mc.currpos() self.mc.BKPT() - # Path B: use assembler helper + # Path 2: use assembler helper asm_helper_adr = self.cpu.cast_adr_to_int(jd.assembler_helper_adr) if self.cpu.supports_floats: floats = r.caller_vfp_resp @@ -1213,28 +1201,24 @@ # the result core = r.caller_resp if op.result: - if resloc.is_vfp_reg(): + if result_loc.is_vfp_reg(): floats = r.caller_vfp_resp[1:] else: core = r.caller_resp[1:] + [r.ip] # keep alignment with saved_registers(self.mc, core, floats): # result of previous call is in r0 - self.mov_loc_loc(arglocs[0], r.r1) + self.mov_loc_loc(vloc, r.r1) self.mc.BL(asm_helper_adr) - if not self.cpu.use_hf_abi and op.result and resloc.is_vfp_reg(): + if not self.cpu.use_hf_abi and op.result and result_loc.is_vfp_reg(): # move result to the allocated register - self.mov_to_vfp_loc(r.r0, r.r1, resloc) + self.mov_to_vfp_loc(r.r0, r.r1, result_loc) # merge point currpos = self.mc.currpos() pmc = OverwritingBuilder(self.mc, jmp_pos, WORD) pmc.B_offs(currpos, fast_path_cond) - self.mc.LDR_ri(r.ip.value, r.fp.value) - self.mc.CMP_ri(r.ip.value, 0) - - self._emit_guard(guard_op, regalloc._prepare_guard(guard_op), - c.GE, save_exc=True) + self._emit_guard_may_force(guard_op, arglocs, op.numargs()) return fcond # ../x86/assembler.py:668 diff --git a/rpython/jit/backend/arm/regalloc.py b/rpython/jit/backend/arm/regalloc.py --- a/rpython/jit/backend/arm/regalloc.py +++ b/rpython/jit/backend/arm/regalloc.py @@ -1101,20 +1101,18 @@ prepare_guard_call_release_gil = prepare_guard_call_may_force def prepare_guard_call_assembler(self, op, guard_op, fcond): + descr = op.getdescr() assert isinstance(descr, JitCellToken) - jd = descr.outermost_jitdriver_sd - assert jd is not None - vable_index = jd.index_of_virtualizable - if vable_index >= 0: - self._sync_var(op.getarg(vable_index)) - vable = self.frame_manager.loc(op.getarg(vable_index)) + arglist = op.getarglist() + self.rm._sync_var(arglist[0]) + frame_loc = self.fm.loc(op.getarg(0)) + if len(arglist) == 2: + self.rm._sync_var(arglist[1]) + locs = [frame_loc, self.fm.loc(arglist[1])] else: - vable = imm(0) - # make sure the call result location is free - tmploc = self.get_scratch_reg(INT, selected_reg=r.r0) - self.possibly_free_vars(guard_op.getfailargs()) - return [vable, tmploc] + self._prepare_call(op, save_all_regs=True) + locs = [frame_loc] + return locs + self._prepare_call(op, save_all_regs=True) def _prepare_args_for_new_op(self, new_args): gc_ll_descr = self.cpu.gc_ll_descr From noreply at buildbot.pypy.org Thu Feb 14 17:26:57 2013 From: noreply at buildbot.pypy.org (lwassermann) Date: Thu, 14 Feb 2013 17:26:57 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: fixed tests because step requires an argument Message-ID: <20130214162657.D392C1C3C65@cobra.cs.uni-duesseldorf.de> Author: Lars Wassermann Branch: Changeset: r29:12ffac6271fe Date: 2013-02-14 17:26 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/12ffac6271fe/ Log: fixed tests because step requires an argument diff --git a/spyvm/model.py b/spyvm/model.py --- a/spyvm/model.py +++ b/spyvm/model.py @@ -498,6 +498,8 @@ return space.w_CompiledMethod def getliteral(self, index): + if len(self.literals) <= index: + import pdb; pdb.set_trace() # We changed this part return self.literals[index] #+ constants.LITERAL_START] diff --git a/spyvm/targettinybenchsmalltalk.py b/spyvm/targettinybenchsmalltalk.py --- a/spyvm/targettinybenchsmalltalk.py +++ b/spyvm/targettinybenchsmalltalk.py @@ -1,4 +1,4 @@ -import autopath1 +# import autopath1 import os, sys from spyvm import model, interpreter, primitives, shadow, constants from spyvm.tool.analyseimage import create_squeakimage @@ -64,4 +64,7 @@ return entry_point, None def jitpolicy(driver): - return JitPolicy() \ No newline at end of file + return JitPolicy() + +if __name__ == "__main__": + entry_point(sys.argv) diff --git a/spyvm/test/test_interpreter.py b/spyvm/test/test_interpreter.py --- a/spyvm/test/test_interpreter.py +++ b/spyvm/test/test_interpreter.py @@ -25,7 +25,7 @@ globals()[name] = make_getter(entry) setup() -def run_with_faked_methods(methods, func): +def run_with_faked_methods(methods, func, active_context=None): # Install faked compiled methods that just invoke the primitive: for (w_class, primnum, argsize, methname) in methods: @@ -38,7 +38,7 @@ assert space.w_nil._shadow is None try: - func() + func(active_context) if active_context else func() finally: # Uninstall those methods: assert space.w_nil._shadow is None @@ -120,7 +120,7 @@ # push bytecodes def test_pushReceiverBytecode(): interp = new_interpreter(pushReceiverBytecode) - interp.step() + interp.step(interp.s_active_context()) assert interp.s_active_context().top().is_same_object( interp.w_active_context().as_methodcontext_get_shadow(space).w_receiver()) @@ -132,9 +132,9 @@ w_demo.store(space, 1, "bar") w_demo.store(space, 2, "baz") interp = new_interpreter(bytecode, receiver = w_demo) - interp.step() - interp.step() - interp.step() + interp.step(interp.s_active_context()) + interp.step(interp.s_active_context()) + interp.step(interp.s_active_context()) assert interp.s_active_context().stack() == ["egg", "bar", "baz"] def test_pushTemporaryVariableBytecode(bytecode=(pushTemporaryVariableBytecode(0) + @@ -142,9 +142,9 @@ pushTemporaryVariableBytecode(2))): interp = new_interpreter(bytecode) interp.w_active_context().as_methodcontext_get_shadow(space).settemp(2, "temp") - interp.step() - interp.step() - interp.step() + interp.step(interp.s_active_context()) + interp.step(interp.s_active_context()) + interp.step(interp.s_active_context()) assert interp.s_active_context().stack() == ["foo", "bar", "temp"] def test_pushLiteralConstantBytecode(bytecode=pushLiteralConstantBytecode(0) + @@ -152,9 +152,9 @@ pushLiteralConstantBytecode(2)): interp = new_interpreter(bytecode) interp.w_active_context().as_methodcontext_get_shadow(space).w_method().literals = fakeliterals(space, "a", "b", "c") - interp.step() - interp.step() - interp.step() + interp.step(interp.s_active_context()) + interp.step(interp.s_active_context()) + interp.step(interp.s_active_context()) assert interp.s_active_context().stack() == [fakesymbol("a"), fakesymbol("b"), fakesymbol("c")] @@ -165,7 +165,7 @@ w_association.store(space, 1, "myvalue") interp = new_interpreter(bytecode) interp.w_active_context().as_methodcontext_get_shadow(space).w_method().literals = fakeliterals(space, w_association) - interp.step() + interp.step(interp.s_active_context()) assert interp.s_active_context().stack() == ["myvalue"] def test_storeAndPopReceiverVariableBytecode(bytecode=storeAndPopReceiverVariableBytecode, @@ -175,8 +175,8 @@ w_object = shadow.new() interp = new_interpreter(pushConstantTrueBytecode + bytecode(index)) interp.w_active_context().as_methodcontext_get_shadow(space).store_w_receiver(w_object) - interp.step() - interp.step() + interp.step(interp.s_active_context()) + interp.step(interp.s_active_context()) if popped: assert interp.s_active_context().stack() == [] else: @@ -192,8 +192,8 @@ for index in range(8): interp = new_interpreter(pushConstantTrueBytecode + bytecode(index)) #interp.w_active_context().as_methodcontext_get_shadow(space).temps = [None] * 8 - interp.step() - interp.step() + interp.step(interp.s_active_context()) + interp.step(interp.s_active_context()) assert interp.s_active_context().stack() == [] interp.w_active_context().as_methodcontext_get_shadow(space) for test_index in range(8): @@ -205,141 +205,141 @@ def test_pushConstantTrueBytecode(): interp = new_interpreter(pushConstantTrueBytecode) - interp.step() + interp.step(interp.s_active_context()) assert interp.s_active_context().pop().is_same_object(space.w_true) assert interp.s_active_context().stack() == [] def test_pushConstantFalseBytecode(): interp = new_interpreter(pushConstantFalseBytecode) - interp.step() + interp.step(interp.s_active_context()) assert interp.s_active_context().pop().is_same_object(space.w_false) assert interp.s_active_context().stack() == [] def test_pushConstantNilBytecode(): interp = new_interpreter(pushConstantNilBytecode) - interp.step() + interp.step(interp.s_active_context()) assert interp.s_active_context().pop().is_same_object(space.w_nil) assert interp.s_active_context().stack() == [] def test_pushConstantMinusOneBytecode(): interp = new_interpreter(pushConstantMinusOneBytecode) - interp.step() + interp.step(interp.s_active_context()) assert interp.s_active_context().pop().is_same_object(space.w_minus_one) assert interp.s_active_context().stack() == [] def test_pushConstantZeroBytecode(): interp = new_interpreter(pushConstantZeroBytecode) - interp.step() + interp.step(interp.s_active_context()) assert interp.s_active_context().pop().is_same_object(space.w_zero) assert interp.s_active_context().stack() == [] def test_pushConstantOneBytecode(): interp = new_interpreter(pushConstantOneBytecode) - interp.step() + interp.step(interp.s_active_context()) assert interp.s_active_context().pop().is_same_object(space.w_one) assert interp.s_active_context().stack() == [] def test_pushConstantTwoBytecode(): interp = new_interpreter(pushConstantTwoBytecode) - interp.step() + interp.step(interp.s_active_context()) assert interp.s_active_context().pop().is_same_object(space.w_two) assert interp.s_active_context().stack() == [] def test_pushActiveContextBytecode(): interp = new_interpreter(pushActiveContextBytecode) - interp.step() + interp.step(interp.s_active_context()) assert interp.s_active_context().pop() == interp.w_active_context() assert interp.s_active_context().stack() == [] def test_duplicateTopBytecode(): interp = new_interpreter(pushConstantZeroBytecode + duplicateTopBytecode) - interp.step() - interp.step() + interp.step(interp.s_active_context()) + interp.step(interp.s_active_context()) assert interp.s_active_context().stack() == [space.w_zero, space.w_zero] def test_bytecodePrimBitAnd(): interp = new_interpreter(pushConstantOneBytecode + pushConstantTwoBytecode + bytecodePrimBitAnd) - interp.step() - interp.step() - interp.step() + interp.step(interp.s_active_context()) + interp.step(interp.s_active_context()) + interp.step(interp.s_active_context()) assert interp.s_active_context().pop().value == 0 assert interp.s_active_context().stack() == [] def test_bytecodePrimBitOr(): interp = new_interpreter(pushConstantOneBytecode + pushConstantTwoBytecode + bytecodePrimBitOr) - interp.step() - interp.step() - interp.step() + interp.step(interp.s_active_context()) + interp.step(interp.s_active_context()) + interp.step(interp.s_active_context()) assert interp.s_active_context().pop().value == 3 assert interp.s_active_context().stack() == [] def test_bytecodePrimBitShift(): interp = new_interpreter(pushConstantOneBytecode + pushConstantTwoBytecode + bytecodePrimBitShift) - interp.step() - interp.step() - interp.step() + interp.step(interp.s_active_context()) + interp.step(interp.s_active_context()) + interp.step(interp.s_active_context()) assert interp.s_active_context().pop().value == 4 assert interp.s_active_context().stack() == [] def test_bytecodePrimClass(): interp = new_interpreter(pushConstantOneBytecode + bytecodePrimClass) - interp.step() - interp.step() + interp.step(interp.s_active_context()) + interp.step(interp.s_active_context()) assert interp.s_active_context().pop() == space.w_SmallInteger assert interp.s_active_context().stack() == [] def test_bytecodePrimSubtract(): interp = new_interpreter(pushConstantOneBytecode + pushConstantTwoBytecode + bytecodePrimSubtract) - interp.step() - interp.step() - interp.step() + interp.step(interp.s_active_context()) + interp.step(interp.s_active_context()) + interp.step(interp.s_active_context()) assert interp.s_active_context().pop().value == -1 assert interp.s_active_context().stack() == [] def test_bytecodePrimMultiply(): interp = new_interpreter(pushConstantMinusOneBytecode + pushConstantTwoBytecode + bytecodePrimMultiply) - interp.step() - interp.step() - interp.step() + interp.step(interp.s_active_context()) + interp.step(interp.s_active_context()) + interp.step(interp.s_active_context()) assert interp.s_active_context().pop().value == -2 assert interp.s_active_context().stack() == [] def test_bytecodePrimDivide(): interp = new_interpreter(pushConstantTwoBytecode + pushConstantMinusOneBytecode + bytecodePrimDivide) - interp.step() - interp.step() - interp.step() + interp.step(interp.s_active_context()) + interp.step(interp.s_active_context()) + interp.step(interp.s_active_context()) assert interp.s_active_context().pop().value == -2 assert interp.s_active_context().stack() == [] def test_bytecodePrimDiv(): interp = new_interpreter(pushConstantTwoBytecode + pushConstantMinusOneBytecode + bytecodePrimDiv) - interp.step() - interp.step() - interp.step() + interp.step(interp.s_active_context()) + interp.step(interp.s_active_context()) + interp.step(interp.s_active_context()) assert interp.s_active_context().pop().value == -2 assert interp.s_active_context().stack() == [] def test_bytecodePrimMod(): interp = new_interpreter(pushConstantTwoBytecode + pushConstantMinusOneBytecode + bytecodePrimMod) - interp.step() - interp.step() - interp.step() + interp.step(interp.s_active_context()) + interp.step(interp.s_active_context()) + interp.step(interp.s_active_context()) assert interp.s_active_context().pop().value == 0 assert interp.s_active_context().stack() == [] def test_bytecodePrimEquivalent(): interp = new_interpreter(pushConstantTwoBytecode + pushConstantMinusOneBytecode + bytecodePrimEquivalent) - interp.step() - interp.step() - interp.step() + interp.step(interp.s_active_context()) + interp.step(interp.s_active_context()) + interp.step(interp.s_active_context()) assert interp.s_active_context().pop() == space.w_false assert interp.s_active_context().stack() == [] interp = new_interpreter(pushConstantOneBytecode + pushConstantOneBytecode + bytecodePrimEquivalent) - interp.step() - interp.step() - interp.step() + interp.step(interp.s_active_context()) + interp.step(interp.s_active_context()) + interp.step(interp.s_active_context()) assert interp.s_active_context().pop() == space.w_true assert interp.s_active_context().stack() == [] @@ -351,7 +351,8 @@ interp.s_active_context().push(w_fakeclass) run_with_faked_methods( [[w_fakeclassclass, primitives.NEW, 0, "new"]], - interp.step) + interp.step, + interp.s_active_context()) w_fakeinst = interp.s_active_context().pop() assert interp.s_active_context().stack() == [] assert w_fakeinst.getclass(space).is_same_object(w_fakeclass) @@ -366,7 +367,8 @@ interp.s_active_context().push(space.w_two) run_with_faked_methods( [[w_fakeclassclass, primitives.NEW_WITH_ARG, 1, "new:"]], - interp.step) + interp.step, + interp.s_active_context()) w_fakeinst = interp.s_active_context().pop() assert interp.s_active_context().stack() == [] assert w_fakeinst.getclass(space).is_same_object(w_fakeclass) @@ -379,7 +381,8 @@ interp.s_active_context().push(w_fakeinst) run_with_faked_methods( [[w_fakeclass, primitives.SIZE, 0, "size"]], - interp.step) + interp.step, + interp.s_active_context()) assert interp.s_active_context().pop().value == 5 assert interp.s_active_context().stack() == [] @@ -401,14 +404,14 @@ interp.w_active_context().as_methodcontext_get_shadow(space).w_method().literals = fakeliterals(space, "foo") interp.s_active_context().push(w_object) callerContext = interp.w_active_context() - interp.step() + interp.step(interp.s_active_context()) assert interp.s_active_context().w_sender() == callerContext assert interp.s_active_context().stack() == [] assert interp.w_active_context().as_methodcontext_get_shadow(space).w_receiver().is_same_object(w_object) assert interp.w_active_context().as_methodcontext_get_shadow(space).w_method().is_same_object(shadow.s_methoddict().methoddict["foo"]) assert callerContext.as_context_get_shadow(space).stack() == [] - interp.step() - interp.step() + interp.step(interp.s_active_context()) + interp.step(interp.s_active_context()) assert interp.w_active_context() == callerContext assert interp.s_active_context().stack() == [result] @@ -443,7 +446,7 @@ interp.s_active_context().push(space.wrap_int(50)) interp.s_active_context().push(space.wrap_int(8)) callerContext = interp.w_active_context() - interp.step() + interp.step(interp.s_active_context()) assert interp.w_active_context() is callerContext assert len(interp.s_active_context().stack()) == 1 w_result = interp.s_active_context().pop() @@ -458,9 +461,9 @@ interp = new_interpreter(pushConstantZeroBytecode + pushConstantOneBytecode + bytecodePrimMakePoint) - interp.step() - interp.step() - interp.step() + interp.step(interp.s_active_context()) + interp.step(interp.s_active_context()) + interp.step(interp.s_active_context()) w_point = interp.s_active_context().top() from spyvm.wrapper import PointWrapper point = PointWrapper(interp.space, w_point) @@ -471,55 +474,55 @@ interp = new_interpreter(longJumpIfTrue(0) + chr(15) + longJumpIfTrue(0) + chr(15)) interp.s_active_context().push(space.w_false) pc = interp.s_active_context().pc() + 2 - interp.step() + interp.step(interp.s_active_context()) assert interp.s_active_context().pc() == pc interp.s_active_context().push(space.w_true) pc = interp.s_active_context().pc() + 2 - interp.step() + interp.step(interp.s_active_context()) assert interp.s_active_context().pc() == pc + 15 def test_longJumpIfFalse(): interp = new_interpreter(pushConstantTrueBytecode + longJumpIfFalse(0) + chr(15) + pushConstantFalseBytecode + longJumpIfFalse(0) + chr(15)) - interp.step() + interp.step(interp.s_active_context()) pc = interp.s_active_context().pc() + 2 - interp.step() + interp.step(interp.s_active_context()) assert interp.s_active_context().pc() == pc - interp.step() + interp.step(interp.s_active_context()) pc = interp.s_active_context().pc() + 2 - interp.step() + interp.step(interp.s_active_context()) assert interp.s_active_context().pc() == pc + 15 def test_longUnconditionalJump(): interp = new_interpreter(longUnconditionalJump(4) + chr(15)) pc = interp.s_active_context().pc() + 2 - interp.step() + interp.step(interp.s_active_context()) assert interp.s_active_context().pc() == pc + 15 def test_shortUnconditionalJump(): interp = new_interpreter(chr(145)) pc = interp.s_active_context().pc() + 1 - interp.step() + interp.step(interp.s_active_context()) assert interp.s_active_context().pc() == pc + 2 def test_shortConditionalJump(): interp = new_interpreter(pushConstantTrueBytecode + shortConditionalJump(3) + pushConstantFalseBytecode + shortConditionalJump(3)) - interp.step() + interp.step(interp.s_active_context()) pc = interp.s_active_context().pc() + 1 - interp.step() + interp.step(interp.s_active_context()) assert interp.s_active_context().pc() == pc - interp.step() + interp.step(interp.s_active_context()) pc = interp.s_active_context().pc() + 1 - interp.step() + interp.step(interp.s_active_context()) assert interp.s_active_context().pc() == pc + 4 def test_popStackBytecode(): interp = new_interpreter(pushConstantTrueBytecode + popStackBytecode) - interp.step() + interp.step(interp.s_active_context()) assert interp.s_active_context().stack() == [space.w_true] - interp.step() + interp.step(interp.s_active_context()) assert interp.s_active_context().stack() == [] def test_extendedPushBytecode(): @@ -543,8 +546,8 @@ w_association.store(space, 1, "myvalue") interp = new_interpreter(pushConstantOneBytecode + bytecode) interp.w_active_context().as_methodcontext_get_shadow(space).w_method().literals = fakeliterals(space, w_association) - interp.step() - interp.step() + interp.step(interp.s_active_context()) + interp.step(interp.s_active_context()) assert w_association.fetch(space, 1).is_same_object(space.w_one) def test_extendedStoreAndPopBytecode(): @@ -570,7 +573,7 @@ w_object = shadow.new() interp.s_active_context().push(w_object) interp.s_active_context().push(space.w_one) - interp.step() + interp.step(interp.s_active_context()) assert interp.w_active_context().as_methodcontext_get_shadow(space).w_method() == shadow.s_methoddict().methoddict["+"] assert interp.s_active_context().w_receiver() is w_object assert interp.w_active_context().as_methodcontext_get_shadow(space).gettemp(0).is_same_object(space.w_one) @@ -586,7 +589,7 @@ for i in range(6): interp.s_active_context().push(space.w_one) interp.s_active_context().push(space.w_two) - interp.step() + interp.step(interp.s_active_context()) assert interp.s_active_context().stack() == [space.w_true, space.w_false, space.w_true, space.w_false, space.w_false, space.w_true] @@ -618,11 +621,11 @@ interp = new_interpreter(bytecodes) interp.w_active_context().as_methodcontext_get_shadow(space).w_method().literals = fakeliterals(space, "foo") interp.s_active_context().push(w_object) - interp.step() + interp.step(interp.s_active_context()) for w_specificclass in [w_super, w_supersuper]: callerContext = interp.w_active_context() - interp.step() - interp.step() + interp.step(interp.s_active_context()) + interp.step(interp.s_active_context()) assert interp.s_active_context().w_sender() == callerContext assert interp.s_active_context().stack() == [] assert interp.w_active_context().as_methodcontext_get_shadow(space).w_receiver() == w_object diff --git a/spyvm/test/test_miniimage.py b/spyvm/test/test_miniimage.py --- a/spyvm/test/test_miniimage.py +++ b/spyvm/test/test_miniimage.py @@ -197,7 +197,7 @@ while True: try: - interp.step() + interp.step(interp.s_active_context()) except interpreter.ReturnFromTopLevel, e: assert e.object.value == abs(int) return @@ -289,7 +289,7 @@ interp.store_w_active_context(w_frame) while True: try: - interp.step() + interp.step(interp.s_active_context()) #print interp.s_active_context.stack except interpreter.ReturnFromTopLevel, e: return e.object @@ -313,10 +313,10 @@ interp.store_w_active_context(s_ctx.w_self()) assert isinstance(s_ctx, shadow.MethodContextShadow) assert interp.s_active_context().top().is_same_object(space.w_true) - interp.step() - interp.step() + interp.step(interp.s_active_context()) + interp.step(interp.s_active_context()) assert interp.s_active_context().top().value == 1 - interp.step() + interp.step(interp.s_active_context()) assert interp.s_active_context().top().value == 2 - interp.step() + interp.step(interp.s_active_context()) assert interp.s_active_context().top().value == 3 From noreply at buildbot.pypy.org Thu Feb 14 19:07:20 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Thu, 14 Feb 2013 19:07:20 +0100 (CET) Subject: [pypy-commit] pypy default: make sure test_app_main reverts cwd after using chdir Message-ID: <20130214180720.E44D11C00A8@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61239:fb31f2123324 Date: 2013-02-14 13:05 -0500 http://bitbucket.org/pypy/pypy/changeset/fb31f2123324/ Log: make sure test_app_main reverts cwd after using chdir diff --git a/pypy/interpreter/test2/test_app_main.py b/pypy/interpreter/test2/test_app_main.py --- a/pypy/interpreter/test2/test_app_main.py +++ b/pypy/interpreter/test2/test_app_main.py @@ -208,11 +208,6 @@ These tests require pexpect (UNIX-only). http://pexpect.sourceforge.net/ """ - def setup_class(cls): - # some tests need to be able to import test2, change the cwd - goal_dir = os.path.abspath(os.path.join(os.path.realpath(os.path.dirname(__file__)), '..')) - os.chdir(goal_dir) - def _spawn(self, *args, **kwds): try: import pexpect @@ -456,13 +451,14 @@ child.expect('789') # expect to see it before the timeout hits child.sendline('X') - def test_options_i_m(self): + def test_options_i_m(self, monkeypatch): if sys.platform == "win32": skip("close_fds is not supported on Windows platforms") if not hasattr(runpy, '_run_module_as_main'): skip("requires CPython >= 2.6") p = os.path.join(os.path.realpath(os.path.dirname(__file__)), 'mymodule.py') p = os.path.abspath(p) + monkeypatch.chdir(os.path.dirname(app_main)) child = self.spawn(['-i', '-m', 'test2.mymodule', 'extra']) @@ -562,12 +558,13 @@ child.sendline('Not at all. They could be carried.') child.expect('A five ounce bird could not carry a one pound coconut.') - def test_no_space_before_argument(self): + def test_no_space_before_argument(self, monkeypatch): if not hasattr(runpy, '_run_module_as_main'): skip("requires CPython >= 2.6") child = self.spawn(['-cprint "hel" + "lo"']) child.expect('hello') + monkeypatch.chdir(os.path.dirname(app_main)) child = self.spawn(['-mtest2.mymodule']) child.expect('mymodule running') @@ -667,11 +664,12 @@ '-c "import sys; print sys.warnoptions"') assert "['ignore', 'default', 'once', 'error']" in data - def test_option_m(self): + def test_option_m(self, monkeypatch): if not hasattr(runpy, '_run_module_as_main'): skip("requires CPython >= 2.6") p = os.path.join(os.path.realpath(os.path.dirname(__file__)), 'mymodule.py') p = os.path.abspath(p) + monkeypatch.chdir(os.path.dirname(app_main)) data = self.run('-m test2.mymodule extra') assert 'mymodule running' in data assert 'Name: __main__' in data From noreply at buildbot.pypy.org Thu Feb 14 19:07:22 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Thu, 14 Feb 2013 19:07:22 +0100 (CET) Subject: [pypy-commit] pypy default: don't try to find stdlib if we didn't find an executable, test Message-ID: <20130214180722.331911C00BD@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61240:57305c375b04 Date: 2013-02-14 13:05 -0500 http://bitbucket.org/pypy/pypy/changeset/57305c375b04/ Log: don't try to find stdlib if we didn't find an executable, test diff --git a/pypy/module/sys/initpath.py b/pypy/module/sys/initpath.py --- a/pypy/module/sys/initpath.py +++ b/pypy/module/sys/initpath.py @@ -67,6 +67,8 @@ stdlib. If it cannot be found, return (None, None). """ + if executable == '': + return None, None search = executable while True: dirname = resolvedirof(search) diff --git a/pypy/module/sys/test/test_initpath.py b/pypy/module/sys/test/test_initpath.py --- a/pypy/module/sys/test/test_initpath.py +++ b/pypy/module/sys/test/test_initpath.py @@ -10,12 +10,15 @@ b = prefix.join('lib-python', dirname).ensure(dir=1) return a, b -def test_find_stdlib(tmpdir): +def test_find_stdlib(tmpdir, monkeypatch): bin_dir = tmpdir.join('bin').ensure(dir=True) pypy = bin_dir.join('pypy').ensure(file=True) build_hierarchy(tmpdir) path, prefix = find_stdlib(None, str(pypy)) assert prefix == tmpdir + # shouldn't find stdlib if executable == '' even if parent dir has a stdlib + monkeypatch.chdir(tmpdir.join('bin')) + assert find_stdlib(None, '') == (None, None) @py.test.mark.skipif('not hasattr(os, "symlink")') def test_find_stdlib_follow_symlink(tmpdir): @@ -84,6 +87,7 @@ assert find_executable('pypy') == a.join('pypy.exe') def test_resolvedirof(tmpdir): + assert resolvedirof('') == os.path.abspath(os.path.join(os.getcwd(), '..')) foo = tmpdir.join('foo').ensure(dir=True) bar = tmpdir.join('bar').ensure(dir=True) myfile = foo.join('myfile').ensure(file=True) From noreply at buildbot.pypy.org Thu Feb 14 22:58:53 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Thu, 14 Feb 2013 22:58:53 +0100 (CET) Subject: [pypy-commit] pypy py3k: we must flush this stream now as streamio's buffering may not have Message-ID: <20130214215853.8C26B1C00BD@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61241:45cb84f839e7 Date: 2013-02-14 13:57 -0800 http://bitbucket.org/pypy/pypy/changeset/45cb84f839e7/ Log: we must flush this stream now as streamio's buffering may not have diff --git a/pypy/module/imp/interp_imp.py b/pypy/module/imp/interp_imp.py --- a/pypy/module/imp/interp_imp.py +++ b/pypy/module/imp/interp_imp.py @@ -78,6 +78,7 @@ top = stream.readline() top += stream.readline() stream.seek(0, 0) # reset position + stream.flush() encoding = pyparse._check_for_encoding(top) if encoding is None: encoding = unicodetype.getdefaultencoding(space) diff --git a/pypy/module/imp/test/test_import.py b/pypy/module/imp/test/test_import.py --- a/pypy/module/imp/test/test_import.py +++ b/pypy/module/imp/test/test_import.py @@ -674,6 +674,7 @@ import encoded fd = imp.find_module('line2', encoded.__path__)[0] assert fd.encoding == 'iso-8859-1' + assert fd.tell() == 0 def test_bad_source_encoding(self): import imp From noreply at buildbot.pypy.org Fri Feb 15 02:25:51 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Fri, 15 Feb 2013 02:25:51 +0100 (CET) Subject: [pypy-commit] pypy default: clean up this test so it behaves the same on all platforms (which currently is fail) Message-ID: <20130215012551.3A7431C00A8@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61242:fd09eb119a1b Date: 2013-02-14 20:23 -0500 http://bitbucket.org/pypy/pypy/changeset/fd09eb119a1b/ Log: clean up this test so it behaves the same on all platforms (which currently is fail) diff --git a/pypy/module/micronumpy/test/test_numarray.py b/pypy/module/micronumpy/test/test_numarray.py --- a/pypy/module/micronumpy/test/test_numarray.py +++ b/pypy/module/micronumpy/test/test_numarray.py @@ -1662,13 +1662,13 @@ b = array([0, 1, 2], dtype=complex).astype(bool) assert (b == [False, True, True]).all() assert b.dtype == 'bool' - + a = arange(6, dtype='f4').reshape(2,3) b = a.astype('i4') a = array('x').astype('S3').dtype assert a.itemsize == 3 - + def test_base(self): from _numpypy import array assert array(1).base is None @@ -1679,6 +1679,11 @@ def test_byteswap(self): from _numpypy import array + + s1 = array(1.).byteswap().tostring() + s2 = array([1.]).byteswap().tostring() + assert s1 == s2 + a = array([1, 256 + 2, 3], dtype='i2') assert (a.byteswap() == [0x0100, 0x0201, 0x0300]).all() assert (a == [1, 256 + 2, 3]).all() @@ -1686,39 +1691,40 @@ assert (a == [0x0100, 0x0201, 0x0300]).all() a = array([1, -1, 1e300], dtype=float) - s1 = map(ord,a.tostring()) + s1 = map(ord, a.tostring()) s2 = map(ord, a.byteswap().tostring()) - assert s1[7::-1] == s2[:8] - assert s1[15:7:-1] == s2[8:16] - assert s1[:15:-1] == s2[16:] + assert a.dtype.itemsize == 8 + for i in range(a.size): + i1 = i * a.dtype.itemsize + i2 = (i+1) * a.dtype.itemsize + assert list(reversed(s1[i1:i2])) == s2[i1:i2] a = array([1+1e30j, -1, 1e10], dtype=complex) - s1 = map(ord,a.tostring()) + s1 = map(ord, a.tostring()) s2 = map(ord, a.byteswap().tostring()) - assert s1[7::-1] == s2[:8] - assert s1[15:7:-1] == s2[8:16] - assert s1[23:15:-1] == s2[16:24] - assert s1[31:23:-1] == s2[24:32] - assert s1[39:31:-1] == s2[32:40] - assert s1[:39:-1] == s2[40:] + assert a.dtype.itemsize == 16 + for i in range(a.size*2): + i1 = i * a.dtype.itemsize/2 + i2 = (i+1) * a.dtype.itemsize/2 + assert list(reversed(s1[i1:i2])) == s2[i1:i2] a = array([3.14, -1.5, 10000], dtype='float16') - s1 = map(ord,a.tostring()) + s1 = map(ord, a.tostring()) s2 = map(ord, a.byteswap().tostring()) - s3 = [s1[1], s1[0],s1[3], s1[2], s1[5], s1[4]] - assert s3 == s2 + assert a.dtype.itemsize == 2 + for i in range(a.size): + i1 = i * a.dtype.itemsize + i2 = (i+1) * a.dtype.itemsize + assert list(reversed(s1[i1:i2])) == s2[i1:i2] a = array([1, -1, 10000], dtype='longfloat') - s1 = map(ord,a.tostring()) - s2 = map(ord, a.byteswap().tostring()) - n = a.dtype.itemsize - assert s1[n-1] == s2[0] - - a = array(0., dtype='longfloat') s1 = map(ord, a.tostring()) s2 = map(ord, a.byteswap().tostring()) - n = a.dtype.itemsize - assert s1[n-1] == s2[0] + assert a.dtype.itemsize >= 8 + for i in range(a.size): + i1 = i * a.dtype.itemsize + i2 = (i+1) * a.dtype.itemsize + assert list(reversed(s1[i1:i2])) == s2[i1:i2] def test_clip(self): from _numpypy import array From noreply at buildbot.pypy.org Fri Feb 15 03:12:34 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Fri, 15 Feb 2013 03:12:34 +0100 (CET) Subject: [pypy-commit] pypy default: skip this test that can't work on win32 Message-ID: <20130215021234.F29BB1C00A8@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61243:7c100addc685 Date: 2013-02-14 21:12 -0500 http://bitbucket.org/pypy/pypy/changeset/7c100addc685/ Log: skip this test that can't work on win32 diff --git a/pypy/module/test_lib_pypy/test_datetime.py b/pypy/module/test_lib_pypy/test_datetime.py --- a/pypy/module/test_lib_pypy/test_datetime.py +++ b/pypy/module/test_lib_pypy/test_datetime.py @@ -66,9 +66,12 @@ """ import os import time + if os.name == 'nt': + skip("setting os.environ['TZ'] ineffective on windows") try: prev_tz = os.environ.get("TZ") os.environ["TZ"] = "GMT" + time.tzset() for unused in xrange(100): now = time.time() delta = (datetime.datetime.utcfromtimestamp(now) - @@ -79,6 +82,7 @@ del os.environ["TZ"] else: os.environ["TZ"] = prev_tz + time.tzset() def test_utcfromtimestamp_microsecond(): dt = datetime.datetime.utcfromtimestamp(0) From noreply at buildbot.pypy.org Fri Feb 15 09:14:26 2013 From: noreply at buildbot.pypy.org (RonnyPfannschmidt) Date: Fri, 15 Feb 2013 09:14:26 +0100 (CET) Subject: [pypy-commit] pypy pytest-update: sync pylib and pytest with the latest versions Message-ID: <20130215081426.D52631C0673@cobra.cs.uni-duesseldorf.de> Author: Ronny Pfannschmidt Branch: pytest-update Changeset: r61244:ca87ef6535e0 Date: 2013-02-15 09:13 +0100 http://bitbucket.org/pypy/pypy/changeset/ca87ef6535e0/ Log: sync pylib and pytest with the latest versions diff too long, truncating to 2000 out of 4863 lines diff --git a/_pytest/__init__.py b/_pytest/__init__.py --- a/_pytest/__init__.py +++ b/_pytest/__init__.py @@ -1,2 +1,2 @@ # -__version__ = '2.2.4.dev2' +__version__ = '2.3.5dev6' diff --git a/_pytest/assertion/__init__.py b/_pytest/assertion/__init__.py --- a/_pytest/assertion/__init__.py +++ b/_pytest/assertion/__init__.py @@ -50,7 +50,7 @@ hook = None if mode == "rewrite": hook = rewrite.AssertionRewritingHook() - sys.meta_path.append(hook) + sys.meta_path.insert(0, hook) warn_about_missing_assertion(mode) config._assertstate = AssertionState(config, mode) config._assertstate.hook = hook @@ -73,8 +73,12 @@ def callbinrepr(op, left, right): hook_result = item.ihook.pytest_assertrepr_compare( config=item.config, op=op, left=left, right=right) + for new_expl in hook_result: if new_expl: + # Don't include pageloads of data unless we are very verbose (-vv) + if len(''.join(new_expl[1:])) > 80*8 and item.config.option.verbose < 2: + new_expl[1:] = ['Detailed information truncated, use "-vv" to see'] res = '\n~'.join(new_expl) if item.config.getvalue("assertmode") == "rewrite": # The result will be fed back a python % formatting diff --git a/_pytest/assertion/newinterpret.py b/_pytest/assertion/newinterpret.py --- a/_pytest/assertion/newinterpret.py +++ b/_pytest/assertion/newinterpret.py @@ -11,7 +11,7 @@ from _pytest.assertion.reinterpret import BuiltinAssertionError -if sys.platform.startswith("java") and sys.version_info < (2, 5, 2): +if sys.platform.startswith("java"): # See http://bugs.jython.org/issue1497 _exprs = ("BoolOp", "BinOp", "UnaryOp", "Lambda", "IfExp", "Dict", "ListComp", "GeneratorExp", "Yield", "Compare", "Call", diff --git a/_pytest/assertion/oldinterpret.py b/_pytest/assertion/oldinterpret.py --- a/_pytest/assertion/oldinterpret.py +++ b/_pytest/assertion/oldinterpret.py @@ -526,10 +526,13 @@ # example: def f(): return 5 + def g(): return 3 + def h(x): return 'never' + check("f() * g() == 5") check("not f()") check("not (f() and g() or 0)") diff --git a/_pytest/assertion/reinterpret.py b/_pytest/assertion/reinterpret.py --- a/_pytest/assertion/reinterpret.py +++ b/_pytest/assertion/reinterpret.py @@ -44,4 +44,3 @@ from _pytest.assertion.newinterpret import interpret as reinterpret else: reinterpret = reinterpret_old - diff --git a/_pytest/assertion/rewrite.py b/_pytest/assertion/rewrite.py --- a/_pytest/assertion/rewrite.py +++ b/_pytest/assertion/rewrite.py @@ -34,13 +34,13 @@ PYTEST_TAG = "%s-%s%s-PYTEST" % (impl, ver[0], ver[1]) del ver, impl -PYC_EXT = ".py" + "c" if __debug__ else "o" +PYC_EXT = ".py" + (__debug__ and "c" or "o") PYC_TAIL = "." + PYTEST_TAG + PYC_EXT REWRITE_NEWLINES = sys.version_info[:2] != (2, 7) and sys.version_info < (3, 2) class AssertionRewritingHook(object): - """Import hook which rewrites asserts.""" + """PEP302 Import hook which rewrites asserts.""" def __init__(self): self.session = None @@ -95,7 +95,8 @@ finally: self.session = sess else: - state.trace("matched test file (was specified on cmdline): %r" % (fn,)) + state.trace("matched test file (was specified on cmdline): %r" % + (fn,)) # The requested module looks like a test file, so rewrite it. This is # the most magical part of the process: load the source, rewrite the # asserts, and load the rewritten source. We also cache the rewritten @@ -121,14 +122,14 @@ # because we're in a zip file. write = False elif e == errno.EACCES: - state.trace("read only directory: %r" % (fn_pypath.dirname,)) + state.trace("read only directory: %r" % fn_pypath.dirname) write = False else: raise cache_name = fn_pypath.basename[:-3] + PYC_TAIL pyc = os.path.join(cache_dir, cache_name) - # Notice that even if we're in a read-only directory, I'm going to check - # for a cached pyc. This may not be optimal... + # Notice that even if we're in a read-only directory, I'm going + # to check for a cached pyc. This may not be optimal... co = _read_pyc(fn_pypath, pyc) if co is None: state.trace("rewriting %r" % (fn,)) @@ -160,10 +161,11 @@ return sys.modules[name] def _write_pyc(co, source_path, pyc): - # Technically, we don't have to have the same pyc format as (C)Python, since - # these "pycs" should never be seen by builtin import. However, there's - # little reason deviate, and I hope sometime to be able to use - # imp.load_compiled to load them. (See the comment in load_module above.) + # Technically, we don't have to have the same pyc format as + # (C)Python, since these "pycs" should never be seen by builtin + # import. However, there's little reason deviate, and I hope + # sometime to be able to use imp.load_compiled to load them. (See + # the comment in load_module above.) mtime = int(source_path.mtime()) try: fp = open(pyc, "wb") @@ -240,9 +242,8 @@ except EnvironmentError: return None # Check for invalid or out of date pyc file. - if (len(data) != 8 or - data[:4] != imp.get_magic() or - struct.unpack(">", - ast.Add : "+", - ast.Sub : "-", - ast.Mult : "*", - ast.Div : "/", - ast.FloorDiv : "//", - ast.Mod : "%", - ast.Eq : "==", - ast.NotEq : "!=", - ast.Lt : "<", - ast.LtE : "<=", - ast.Gt : ">", - ast.GtE : ">=", - ast.Pow : "**", - ast.Is : "is", - ast.IsNot : "is not", - ast.In : "in", - ast.NotIn : "not in" + ast.BitOr: "|", + ast.BitXor: "^", + ast.BitAnd: "&", + ast.LShift: "<<", + ast.RShift: ">>", + ast.Add: "+", + ast.Sub: "-", + ast.Mult: "*", + ast.Div: "/", + ast.FloorDiv: "//", + ast.Mod: "%%", # escaped for string formatting + ast.Eq: "==", + ast.NotEq: "!=", + ast.Lt: "<", + ast.LtE: "<=", + ast.Gt: ">", + ast.GtE: ">=", + ast.Pow: "**", + ast.Is: "is", + ast.IsNot: "is not", + ast.In: "in", + ast.NotIn: "not in" } @@ -341,7 +345,7 @@ lineno = 0 for item in mod.body: if (expect_docstring and isinstance(item, ast.Expr) and - isinstance(item.value, ast.Str)): + isinstance(item.value, ast.Str)): doc = item.value.s if "PYTEST_DONT_REWRITE" in doc: # The module has disabled assertion rewriting. @@ -462,7 +466,8 @@ body.append(raise_) # Clear temporary variables by setting them to None. if self.variables: - variables = [ast.Name(name, ast.Store()) for name in self.variables] + variables = [ast.Name(name, ast.Store()) + for name in self.variables] clear = ast.Assign(variables, ast.Name("None", ast.Load())) self.statements.append(clear) # Fix line numbers. @@ -471,11 +476,12 @@ return self.statements def visit_Name(self, name): - # Check if the name is local or not. + # Display the repr of the name if it's a local variable or + # _should_repr_global_name() thinks it's acceptable. locs = ast.Call(self.builtin("locals"), [], [], None, None) - globs = ast.Call(self.builtin("globals"), [], [], None, None) - ops = [ast.In(), ast.IsNot()] - test = ast.Compare(ast.Str(name.id), ops, [locs, globs]) + inlocs = ast.Compare(ast.Str(name.id), [ast.In()], [locs]) + dorepr = self.helper("should_repr_global_name", name) + test = ast.BoolOp(ast.Or(), [inlocs, dorepr]) expr = ast.IfExp(test, self.display(name), ast.Str(name.id)) return name, self.explanation_param(expr) @@ -548,7 +554,8 @@ new_kwarg, expl = self.visit(call.kwargs) arg_expls.append("**" + expl) expl = "%s(%s)" % (func_expl, ', '.join(arg_expls)) - new_call = ast.Call(new_func, new_args, new_kwargs, new_star, new_kwarg) + new_call = ast.Call(new_func, new_args, new_kwargs, + new_star, new_kwarg) res = self.assign(new_call) res_expl = self.explanation_param(self.display(res)) outer_expl = "%s\n{%s = %s\n}" % (res_expl, res_expl, expl) diff --git a/_pytest/assertion/util.py b/_pytest/assertion/util.py --- a/_pytest/assertion/util.py +++ b/_pytest/assertion/util.py @@ -116,16 +116,11 @@ excinfo = py.code.ExceptionInfo() explanation = ['(pytest_assertion plugin: representation of ' 'details failed. Probably an object has a faulty __repr__.)', - str(excinfo) - ] - + str(excinfo)] if not explanation: return None - # Don't include pageloads of data, should be configurable - if len(''.join(explanation)) > 80*8: - explanation = ['Detailed information too verbose, truncated'] return [summary] + explanation diff --git a/_pytest/capture.py b/_pytest/capture.py --- a/_pytest/capture.py +++ b/_pytest/capture.py @@ -119,22 +119,20 @@ return "", "" def activate_funcargs(self, pyfuncitem): - if not hasattr(pyfuncitem, 'funcargs'): - return - assert not hasattr(self, '_capturing_funcargs') - self._capturing_funcargs = capturing_funcargs = [] - for name, capfuncarg in pyfuncitem.funcargs.items(): - if name in ('capsys', 'capfd'): - capturing_funcargs.append(capfuncarg) - capfuncarg._start() + funcargs = getattr(pyfuncitem, "funcargs", None) + if funcargs is not None: + for name, capfuncarg in funcargs.items(): + if name in ('capsys', 'capfd'): + assert not hasattr(self, '_capturing_funcarg') + self._capturing_funcarg = capfuncarg + capfuncarg._start() def deactivate_funcargs(self): - capturing_funcargs = getattr(self, '_capturing_funcargs', None) - if capturing_funcargs is not None: - while capturing_funcargs: - capfuncarg = capturing_funcargs.pop() - capfuncarg._finalize() - del self._capturing_funcargs + capturing_funcarg = getattr(self, '_capturing_funcarg', None) + if capturing_funcarg: + outerr = capturing_funcarg._finalize() + del self._capturing_funcarg + return outerr def pytest_make_collect_report(self, __multicall__, collector): method = self._getmethod(collector.config, collector.fspath) @@ -169,9 +167,12 @@ @pytest.mark.tryfirst def pytest_runtest_makereport(self, __multicall__, item, call): - self.deactivate_funcargs() + funcarg_outerr = self.deactivate_funcargs() rep = __multicall__.execute() outerr = self.suspendcapture(item) + if funcarg_outerr is not None: + outerr = (outerr[0] + funcarg_outerr[0], + outerr[1] + funcarg_outerr[1]) if not rep.passed: addouterr(rep, outerr) if not rep.passed or rep.when == "teardown": @@ -179,23 +180,29 @@ item.outerr = outerr return rep +error_capsysfderror = "cannot use capsys and capfd at the same time" + def pytest_funcarg__capsys(request): """enables capturing of writes to sys.stdout/sys.stderr and makes captured output available via ``capsys.readouterr()`` method calls which return a ``(out, err)`` tuple. """ - return CaptureFuncarg(py.io.StdCapture) + if "capfd" in request._funcargs: + raise request.raiseerror(error_capsysfderror) + return CaptureFixture(py.io.StdCapture) def pytest_funcarg__capfd(request): """enables capturing of writes to file descriptors 1 and 2 and makes captured output available via ``capsys.readouterr()`` method calls which return a ``(out, err)`` tuple. """ + if "capsys" in request._funcargs: + request.raiseerror(error_capsysfderror) if not hasattr(os, 'dup'): - py.test.skip("capfd funcarg needs os.dup") - return CaptureFuncarg(py.io.StdCaptureFD) + pytest.skip("capfd funcarg needs os.dup") + return CaptureFixture(py.io.StdCaptureFD) -class CaptureFuncarg: +class CaptureFixture: def __init__(self, captureclass): self.capture = captureclass(now=False) @@ -204,11 +211,15 @@ def _finalize(self): if hasattr(self, 'capture'): - self.capture.reset() + outerr = self._outerr = self.capture.reset() del self.capture + return outerr def readouterr(self): - return self.capture.readouterr() + try: + return self.capture.readouterr() + except AttributeError: + return self._outerr def close(self): self._finalize() diff --git a/_pytest/config.py b/_pytest/config.py --- a/_pytest/config.py +++ b/_pytest/config.py @@ -19,7 +19,7 @@ fin() class Parser: - """ Parser for command line arguments. """ + """ Parser for command line arguments and ini-file values. """ def __init__(self, usage=None, processopt=None): self._anonymous = OptionGroup("custom options", parser=self) @@ -35,15 +35,17 @@ if option.dest: self._processopt(option) - def addnote(self, note): - self._notes.append(note) - def getgroup(self, name, description="", after=None): """ get (or create) a named option Group. - :name: unique name of the option group. + :name: name of the option group. :description: long description for --help output. :after: name of other group, used for ordering --help output. + + The returned group object has an ``addoption`` method with the same + signature as :py:func:`parser.addoption + <_pytest.config.Parser.addoption>` but will be shown in the + respective group in the output of ``pytest. --help``. """ for group in self._groups: if group.name == name: @@ -57,7 +59,19 @@ return group def addoption(self, *opts, **attrs): - """ add an optparse-style option. """ + """ register a command line option. + + :opts: option names, can be short or long options. + :attrs: same attributes which the ``add_option()`` function of the + `optparse library + `_ + accepts. + + After command line parsing options are available on the pytest config + object via ``config.option.NAME`` where ``NAME`` is usually set + by passing a ``dest`` attribute, for example + ``addoption("--long", dest="NAME", ...)``. + """ self._anonymous.addoption(*opts, **attrs) def parse(self, args): @@ -78,7 +92,15 @@ return args def addini(self, name, help, type=None, default=None): - """ add an ini-file option with the given name and description. """ + """ register an ini-file option. + + :name: name of the ini-variable + :type: type of the variable, can be ``pathlist``, ``args`` or ``linelist``. + :default: default value if no ini-file option exists but is queried. + + The value of ini-variables can be retrieved via a call to + :py:func:`config.getini(name) <_pytest.config.Config.getini>`. + """ assert type in (None, "pathlist", "args", "linelist") self._inidict[name] = (help, type, default) self._ininames.append(name) @@ -154,20 +176,24 @@ p = current.join(opt1[len(opt)+1:], abs=1) self._confcutdir = p break - for arg in args + [current]: + foundanchor = False + for arg in args: if hasattr(arg, 'startswith') and arg.startswith("--"): continue anchor = current.join(arg, abs=1) - if anchor.check(): # we found some file object - self._path2confmods[None] = self.getconftestmodules(anchor) - # let's also consider test* dirs - if anchor.check(dir=1): - for x in anchor.listdir("test*"): - if x.check(dir=1): - self.getconftestmodules(x) - break - else: - assert 0, "no root of filesystem?" + if exists(anchor): # we found some file object + self._try_load_conftest(anchor) + foundanchor = True + if not foundanchor: + self._try_load_conftest(current) + + def _try_load_conftest(self, anchor): + self._path2confmods[None] = self.getconftestmodules(anchor) + # let's also consider test* subdirs + if anchor.check(dir=1): + for x in anchor.listdir("test*"): + if x.check(dir=1): + self.getconftestmodules(x) def getconftestmodules(self, path): """ return a list of imported conftest modules for the given path. """ @@ -245,8 +271,8 @@ class Config(object): """ access to configuration values, pluginmanager and plugin hooks. """ def __init__(self, pluginmanager=None): - #: command line option values, usually added via parser.addoption(...) - #: or parser.getgroup(...).addoption(...) calls + #: access to command line option as attributes. + #: (deprecated), use :py:func:`getoption() <_pytest.config.Config.getoption>` instead self.option = CmdOptions() self._parser = Parser( usage="usage: %prog [options] [file_or_dir] [file_or_dir] [...]", @@ -258,6 +284,7 @@ self._conftest = Conftest(onimport=self._onimportconftest) self.hook = self.pluginmanager.hook self._inicache = {} + self._opt2dest = {} self._cleanup = [] @classmethod @@ -278,6 +305,9 @@ self.pluginmanager.consider_conftest(conftestmodule) def _processopt(self, opt): + for name in opt._short_opts + opt._long_opts: + self._opt2dest[name] = opt.dest + if hasattr(opt, 'default') and opt.dest: if not hasattr(self.option, opt.dest): setattr(self.option, opt.dest, opt.default) @@ -356,8 +386,9 @@ x.append(line) # modifies the cached list inline def getini(self, name): - """ return configuration value from an ini file. If the - specified name hasn't been registered through a prior ``parse.addini`` + """ return configuration value from an :ref:`ini file `. If the + specified name hasn't been registered through a prior + :py:func:`parser.addini ` call (usually from a plugin), a ValueError is raised. """ try: return self._inicache[name] @@ -411,8 +442,22 @@ self._checkconftest(name) return self._conftest.rget(name, path) + def getoption(self, name): + """ return command line option value. + + :arg name: name of the option. You may also specify + the literal ``--OPT`` option instead of the "dest" option name. + """ + name = self._opt2dest.get(name, name) + try: + return getattr(self.option, name) + except AttributeError: + raise ValueError("no option named %r" % (name,)) + def getvalue(self, name, path=None): - """ return ``name`` value looked set from command line options. + """ return command line option value. + + :arg name: name of the command line option (deprecated) if we can't find the option also lookup the name in a matching conftest file. @@ -434,6 +479,11 @@ except KeyError: py.test.skip("no %r value found" %(name,)) +def exists(path, ignore=EnvironmentError): + try: + return path.check() + except ignore: + return False def getcfg(args, inibasenames): args = [x for x in args if not str(x).startswith("-")] @@ -444,20 +494,9 @@ for base in arg.parts(reverse=True): for inibasename in inibasenames: p = base.join(inibasename) - if p.check(): + if exists(p): iniconfig = py.iniconfig.IniConfig(p) if 'pytest' in iniconfig.sections: return iniconfig['pytest'] return {} -def findupwards(current, basename): - current = py.path.local(current) - while 1: - p = current.join(basename) - if p.check(): - return p - p = current.dirpath() - if p == current: - return - current = p - diff --git a/_pytest/core.py b/_pytest/core.py --- a/_pytest/core.py +++ b/_pytest/core.py @@ -24,12 +24,28 @@ def get(self, name): return TagTracerSub(self, (name,)) + def format_message(self, tags, args): + if isinstance(args[-1], dict): + extra = args[-1] + args = args[:-1] + else: + extra = {} + + content = " ".join(map(str, args)) + indent = " " * self.indent + + lines = [ + "%s%s [%s]\n" %(indent, content, ":".join(tags)) + ] + + for name, value in extra.items(): + lines.append("%s %s: %s\n" % (indent, name, value)) + return lines + def processmessage(self, tags, args): - if self.writer is not None: - if args: - indent = " " * self.indent - content = " ".join(map(str, args)) - self.writer("%s%s [%s]\n" %(indent, content, ":".join(tags))) + if self.writer is not None and args: + lines = self.format_message(tags, args) + self.writer(''.join(lines)) try: self._tag2proc[tags](tags, args) except KeyError: @@ -79,10 +95,11 @@ self.import_plugin(spec) def register(self, plugin, name=None, prepend=False): - assert not self.isregistered(plugin), plugin + if self._name2plugin.get(name, None) == -1: + return name = name or getattr(plugin, '__name__', str(id(plugin))) - if name in self._name2plugin: - return False + if self.isregistered(plugin, name): + raise ValueError("Plugin already registered: %s=%s" %(name, plugin)) #self.trace("registering", name, plugin) self._name2plugin[name] = plugin self.call_plugin(plugin, "pytest_addhooks", {'pluginmanager': self}) @@ -321,13 +338,18 @@ name = importspec try: mod = "_pytest." + name - return __import__(mod, None, None, '__doc__') + __import__(mod) + return sys.modules[mod] except ImportError: #e = py.std.sys.exc_info()[1] #if str(e).find(name) == -1: # raise pass # - return __import__(importspec, None, None, '__doc__') + try: + __import__(importspec) + except ImportError: + raise ImportError(importspec) + return sys.modules[importspec] class MultiCall: """ execute a call into multiple python functions/methods. """ @@ -460,16 +482,15 @@ pluginmanager=_pluginmanager, args=args) def main(args=None, plugins=None): - """ returned exit code integer, after an in-process testing run - with the given command line arguments, preloading an optional list - of passed in plugin objects. """ - try: - config = _prepareconfig(args, plugins) - exitstatus = config.hook.pytest_cmdline_main(config=config) - except UsageError: - e = sys.exc_info()[1] - sys.stderr.write("ERROR: %s\n" %(e.args[0],)) - exitstatus = 3 + """ return exit code, after performing an in-process test run. + + :arg args: list of command line arguments. + + :arg plugins: list of plugin objects to be auto-registered during + initialization. + """ + config = _prepareconfig(args, plugins) + exitstatus = config.hook.pytest_cmdline_main(config=config) return exitstatus class UsageError(Exception): diff --git a/_pytest/helpconfig.py b/_pytest/helpconfig.py --- a/_pytest/helpconfig.py +++ b/_pytest/helpconfig.py @@ -79,6 +79,8 @@ tw.line() ; tw.line() #tw.sep("=") + tw.line("to see available markers type: py.test --markers") + tw.line("to see available fixtures type: py.test --fixtures") return tw.line("conftest.py options:") diff --git a/_pytest/hookspec.py b/_pytest/hookspec.py --- a/_pytest/hookspec.py +++ b/_pytest/hookspec.py @@ -23,8 +23,28 @@ """modify command line arguments before option parsing. """ def pytest_addoption(parser): - """add optparse-style options and ini-style config values via calls - to ``parser.addoption`` and ``parser.addini(...)``. + """register optparse-style options and ini-style config values. + + This function must be implemented in a :ref:`plugin ` and is + called once at the beginning of a test run. + + :arg parser: To add command line options, call + :py:func:`parser.addoption(...) <_pytest.config.Parser.addoption>`. + To add ini-file values call :py:func:`parser.addini(...) + <_pytest.config.Parser.addini>`. + + Options can later be accessed through the + :py:class:`config <_pytest.config.Config>` object, respectively: + + - :py:func:`config.getoption(name) <_pytest.config.Config.getoption>` to + retrieve the value of a command line option. + + - :py:func:`config.getini(name) <_pytest.config.Config.getini>` to retrieve + a value read from an ini-style file. + + The config object is passed around on many internal objects via the ``.config`` + attribute or can be retrieved as the ``pytestconfig`` fixture or accessed + via (deprecated) ``pytest.config``. """ def pytest_cmdline_main(config): @@ -33,7 +53,7 @@ pytest_cmdline_main.firstresult = True def pytest_configure(config): - """ called after command line options have been parsed. + """ called after command line options have been parsed and all plugins and initial conftest files been loaded. """ @@ -193,7 +213,7 @@ # hooks for influencing reporting (invoked from _pytest_terminal) # ------------------------------------------------------------------------- -def pytest_report_header(config): +def pytest_report_header(config, startdir): """ return a string to be displayed as header info for terminal reporting.""" def pytest_report_teststatus(report): diff --git a/_pytest/junitxml.py b/_pytest/junitxml.py --- a/_pytest/junitxml.py +++ b/_pytest/junitxml.py @@ -57,7 +57,7 @@ return unicode('#x%02X') % i else: return unicode('#x%04X') % i - return illegal_xml_re.sub(repl, py.xml.escape(arg)) + return py.xml.raw(illegal_xml_re.sub(repl, py.xml.escape(arg))) def pytest_addoption(parser): group = parser.getgroup("terminal reporting") @@ -81,19 +81,22 @@ config.pluginmanager.unregister(xml) +def mangle_testnames(names): + names = [x.replace(".py", "") for x in names if x != '()'] + names[0] = names[0].replace("/", '.') + return names + class LogXML(object): def __init__(self, logfile, prefix): logfile = os.path.expanduser(os.path.expandvars(logfile)) - self.logfile = os.path.normpath(logfile) + self.logfile = os.path.normpath(os.path.abspath(logfile)) self.prefix = prefix self.tests = [] self.passed = self.skipped = 0 self.failed = self.errors = 0 def _opentestcase(self, report): - names = report.nodeid.split("::") - names[0] = names[0].replace("/", '.') - names = [x.replace(".py", "") for x in names if x != "()"] + names = mangle_testnames(report.nodeid.split("::")) classnames = names[:-1] if self.prefix: classnames.insert(0, self.prefix) @@ -111,7 +114,7 @@ def append_failure(self, report): #msg = str(report.longrepr.reprtraceback.extraline) - if "xfail" in report.keywords: + if hasattr(report, "wasxfail"): self.append( Junit.skipped(message="xfail-marked test passes unexpectedly")) self.skipped += 1 @@ -145,8 +148,8 @@ self.errors += 1 def append_skipped(self, report): - if "xfail" in report.keywords: - self.append(Junit.skipped(str(report.keywords['xfail']), + if hasattr(report, "wasxfail"): + self.append(Junit.skipped(str(report.wasxfail), message="expected test failure")) else: filename, lineno, skipreason = report.longrepr diff --git a/_pytest/main.py b/_pytest/main.py --- a/_pytest/main.py +++ b/_pytest/main.py @@ -2,7 +2,15 @@ import py import pytest, _pytest +import inspect import os, sys, imp +try: + from collections import MutableMapping as MappingMixin +except ImportError: + from UserDict import DictMixin as MappingMixin + +from _pytest.mark import MarkInfo + tracebackcutdir = py.path.local(_pytest.__file__).dirpath() # exitcodes for the command line @@ -10,6 +18,7 @@ EXIT_TESTSFAILED = 1 EXIT_INTERRUPTED = 2 EXIT_INTERNALERROR = 3 +EXIT_USAGEERROR = 4 name_re = py.std.re.compile("^[a-zA-Z_]\w*$") @@ -28,7 +37,6 @@ group._addoption('--maxfail', metavar="num", action="store", type="int", dest="maxfail", default=0, help="exit after first num failures or errors.") - group._addoption('--strict', action="store_true", help="run pytest in strict mode, warnings become errors.") @@ -65,30 +73,36 @@ session.exitstatus = EXIT_OK initstate = 0 try: - config.pluginmanager.do_configure(config) - initstate = 1 - config.hook.pytest_sessionstart(session=session) - initstate = 2 - doit(config, session) - except pytest.UsageError: - raise - except KeyboardInterrupt: - excinfo = py.code.ExceptionInfo() - config.hook.pytest_keyboard_interrupt(excinfo=excinfo) - session.exitstatus = EXIT_INTERRUPTED - except: - excinfo = py.code.ExceptionInfo() - config.pluginmanager.notify_exception(excinfo, config.option) - session.exitstatus = EXIT_INTERNALERROR - if excinfo.errisinstance(SystemExit): - sys.stderr.write("mainloop: caught Spurious SystemExit!\n") - if initstate >= 2: - config.hook.pytest_sessionfinish(session=session, - exitstatus=session.exitstatus or (session._testsfailed and 1)) - if not session.exitstatus and session._testsfailed: - session.exitstatus = EXIT_TESTSFAILED - if initstate >= 1: - config.pluginmanager.do_unconfigure(config) + try: + config.pluginmanager.do_configure(config) + initstate = 1 + config.hook.pytest_sessionstart(session=session) + initstate = 2 + doit(config, session) + except pytest.UsageError: + msg = sys.exc_info()[1].args[0] + sys.stderr.write("ERROR: %s\n" %(msg,)) + session.exitstatus = EXIT_USAGEERROR + except KeyboardInterrupt: + excinfo = py.code.ExceptionInfo() + config.hook.pytest_keyboard_interrupt(excinfo=excinfo) + session.exitstatus = EXIT_INTERRUPTED + except: + excinfo = py.code.ExceptionInfo() + config.pluginmanager.notify_exception(excinfo, config.option) + session.exitstatus = EXIT_INTERNALERROR + if excinfo.errisinstance(SystemExit): + sys.stderr.write("mainloop: caught Spurious SystemExit!\n") + else: + if session._testsfailed: + session.exitstatus = EXIT_TESTSFAILED + finally: + if initstate >= 2: + config.hook.pytest_sessionfinish( + session=session, + exitstatus=session.exitstatus) + if initstate >= 1: + config.pluginmanager.do_unconfigure(config) return session.exitstatus def pytest_cmdline_main(config): @@ -106,11 +120,18 @@ def pytest_runtestloop(session): if session.config.option.collectonly: return True + + def getnextitem(i): + # this is a function to avoid python2 + # keeping sys.exc_info set when calling into a test + # python2 keeps sys.exc_info till the frame is left + try: + return session.items[i+1] + except IndexError: + return None + for i, item in enumerate(session.items): - try: - nextitem = session.items[i+1] - except IndexError: - nextitem = None + nextitem = getnextitem(i) item.config.hook.pytest_runtest_protocol(item=item, nextitem=nextitem) if session.shouldstop: raise session.Interrupted(session.shouldstop) @@ -129,8 +150,10 @@ def __init__(self, fspath, config): self.fspath = fspath self.config = config + def __getattr__(self, name): hookmethod = getattr(self.config.hook, name) + def call_matching_hooks(**kwargs): plugins = self.config._getmatchingplugins(self.fspath) return hookmethod.pcall(plugins, **kwargs) @@ -138,31 +161,71 @@ def compatproperty(name): def fget(self): + # deprecated - use pytest.name return getattr(pytest, name) - return property(fget, None, None, - "deprecated attribute %r, use pytest.%s" % (name,name)) + + return property(fget) + +class NodeKeywords(MappingMixin): + def __init__(self, node): + parent = node.parent + bases = parent and (parent.keywords._markers,) or () + self._markers = type("dynmarker", bases, {node.name: True}) + + def __getitem__(self, key): + try: + return getattr(self._markers, key) + except AttributeError: + raise KeyError(key) + + def __setitem__(self, key, value): + setattr(self._markers, key, value) + + def __delitem__(self, key): + delattr(self._markers, key) + + def __iter__(self): + return iter(self.keys()) + + def __len__(self): + return len(self.keys()) + + def keys(self): + return dir(self._markers) class Node(object): - """ base class for all Nodes in the collection tree. + """ base class for Collector and Item the test collection tree. Collector subclasses have children, Items are terminal nodes.""" def __init__(self, name, parent=None, config=None, session=None): - #: a unique name with the scope of the parent + #: a unique name within the scope of the parent node self.name = name #: the parent collector node. self.parent = parent - #: the test config object + #: the pytest config object self.config = config or parent.config - #: the collection this node is part of + #: the session this node is part of self.session = session or parent.session - #: filesystem path where this node was collected from + #: filesystem path where this node was collected from (can be None) self.fspath = getattr(parent, 'fspath', None) - self.ihook = self.session.gethookproxy(self.fspath) - self.keywords = {self.name: True} + + #: keywords/markers collected from all scopes + self.keywords = NodeKeywords(self) + + #self.extrainit() + + @property + def ihook(self): + """ fspath sensitive hook proxy used to call pytest hooks""" + return self.session.gethookproxy(self.fspath) + + #def extrainit(self): + # """"extra initialization after Node is initialized. Implemented + # by some subclasses. """ Module = compatproperty("Module") Class = compatproperty("Class") @@ -180,25 +243,28 @@ return cls def __repr__(self): - return "<%s %r>" %(self.__class__.__name__, getattr(self, 'name', None)) + return "<%s %r>" %(self.__class__.__name__, + getattr(self, 'name', None)) # methods for ordering nodes @property def nodeid(self): + """ a ::-separated string denoting its collection tree address. """ try: return self._nodeid except AttributeError: self._nodeid = x = self._makeid() return x + def _makeid(self): return self.parent.nodeid + "::" + self.name def __eq__(self, other): if not isinstance(other, Node): return False - return self.__class__ == other.__class__ and \ - self.name == other.name and self.parent == other.parent + return (self.__class__ == other.__class__ and + self.name == other.name and self.parent == other.parent) def __ne__(self, other): return not self == other @@ -257,6 +323,9 @@ pass def _repr_failure_py(self, excinfo, style=None): + fm = self.session._fixturemanager + if excinfo.errisinstance(fm.FixtureLookupError): + return excinfo.value.formatrepr() if self.config.option.fulltrace: style="long" else: @@ -365,9 +434,9 @@ __module__ = 'builtins' # for py3 def __init__(self, config): - super(Session, self).__init__(py.path.local(), parent=None, - config=config, session=self) - assert self.config.pluginmanager.register(self, name="session", prepend=True) + FSCollector.__init__(self, py.path.local(), parent=None, + config=config, session=self) + self.config.pluginmanager.register(self, name="session", prepend=True) self._testsfailed = 0 self.shouldstop = False self.trace = config.trace.root.get("collection") @@ -378,7 +447,7 @@ raise self.Interrupted(self.shouldstop) def pytest_runtest_logreport(self, report): - if report.failed and 'xfail' not in getattr(report, 'keywords', []): + if report.failed and not hasattr(report, 'wasxfail'): self._testsfailed += 1 maxfail = self.config.getvalue("maxfail") if maxfail and self._testsfailed >= maxfail: @@ -453,7 +522,7 @@ if path.check(dir=1): assert not names, "invalid arg %r" %(arg,) for path in path.visit(fil=lambda x: x.check(file=1), - rec=self._recurse, bf=True, sort=True): + rec=self._recurse, bf=True, sort=True): for x in self._collectfile(path): yield x else: @@ -465,13 +534,13 @@ ihook = self.gethookproxy(path) if not self.isinitpath(path): if ihook.pytest_ignore_collect(path=path, config=self.config): - return () + return () return ihook.pytest_collect_file(path=path, parent=self) def _recurse(self, path): ihook = self.gethookproxy(path.dirpath()) if ihook.pytest_ignore_collect(path=path, config=self.config): - return + return for pat in self._norecursepatterns: if path.check(fnmatch=pat): return False @@ -574,3 +643,12 @@ for x in self.genitems(subnode): yield x node.ihook.pytest_collectreport(report=rep) + +def getfslineno(obj): + # xxx let decorators etc specify a sane ordering + if hasattr(obj, 'place_as'): + obj = obj.place_as + fslineno = py.code.getfslineno(obj) + assert isinstance(fslineno[1], int), obj + return fslineno + diff --git a/_pytest/mark.py b/_pytest/mark.py --- a/_pytest/mark.py +++ b/_pytest/mark.py @@ -8,11 +8,12 @@ group = parser.getgroup("general") group._addoption('-k', action="store", dest="keyword", default='', metavar="KEYWORDEXPR", - help="only run tests which match given keyword expression. " - "An expression consists of space-separated terms. " - "Each term must match. Precede a term with '-' to negate. " - "Terminate expression with ':' to make the first match match " - "all subsequent tests (usually file-order). ") + help="only run tests which match the given expression. " + "An expression is a python evaluatable expression " + "where all names are substring-matched against test names " + "and keywords. Example: -k 'test_method or test_other' " + "matches all test functions whose name contains " + "'test_method' or 'test_other'.") group._addoption("-m", action="store", dest="markexpr", default="", metavar="MARKEXPR", @@ -51,7 +52,7 @@ remaining = [] deselected = [] for colitem in items: - if keywordexpr and skipbykeyword(colitem, keywordexpr): + if keywordexpr and not matchkeyword(colitem, keywordexpr): deselected.append(colitem) else: if selectuntil: @@ -72,45 +73,26 @@ def __getitem__(self, name): return name in self._mydict +class SubstringDict: + def __init__(self, mydict): + self._mydict = mydict + def __getitem__(self, name): + for key in self._mydict: + if name in key: + return True + return False + def matchmark(colitem, matchexpr): - return eval(matchexpr, {}, BoolDict(colitem.obj.__dict__)) + return eval(matchexpr, {}, BoolDict(colitem.keywords)) + +def matchkeyword(colitem, keywordexpr): + keywordexpr = keywordexpr.replace("-", "not ") + return eval(keywordexpr, {}, SubstringDict(colitem.keywords)) def pytest_configure(config): if config.option.strict: pytest.mark._config = config -def skipbykeyword(colitem, keywordexpr): - """ return True if they given keyword expression means to - skip this collector/item. - """ - if not keywordexpr: - return - - itemkeywords = getkeywords(colitem) - for key in filter(None, keywordexpr.split()): - eor = key[:1] == '-' - if eor: - key = key[1:] - if not (eor ^ matchonekeyword(key, itemkeywords)): - return True - -def getkeywords(node): - keywords = {} - while node is not None: - keywords.update(node.keywords) - node = node.parent - return keywords - - -def matchonekeyword(key, itemkeywords): - for elem in key.split("."): - for kw in itemkeywords: - if elem in kw: - break - else: - return False - return True - class MarkGenerator: """ Factory for :class:`MarkDecorator` objects - exposed as a ``py.test.mark`` singleton instance. Example:: diff --git a/_pytest/monkeypatch.py b/_pytest/monkeypatch.py --- a/_pytest/monkeypatch.py +++ b/_pytest/monkeypatch.py @@ -1,6 +1,6 @@ """ monkeypatching and mocking functionality. """ -import os, sys +import os, sys, inspect def pytest_funcarg__monkeypatch(request): """The returned ``monkeypatch`` funcarg provides these @@ -39,6 +39,10 @@ oldval = getattr(obj, name, notset) if raising and oldval is notset: raise AttributeError("%r has no attribute %r" %(obj, name)) + + # avoid class descriptors like staticmethod/classmethod + if inspect.isclass(obj): + oldval = obj.__dict__.get(name, notset) self._setattr.insert(0, (obj, name, oldval)) setattr(obj, name, value) diff --git a/_pytest/nose.py b/_pytest/nose.py --- a/_pytest/nose.py +++ b/_pytest/nose.py @@ -3,6 +3,8 @@ import pytest, py import inspect import sys +from _pytest import unittest + def pytest_runtest_makereport(__multicall__, item, call): SkipTest = getattr(sys.modules.get('nose', None), 'SkipTest', None) @@ -15,7 +17,7 @@ @pytest.mark.trylast def pytest_runtest_setup(item): - if isinstance(item, (pytest.Function)): + if is_potential_nosetest(item): if isinstance(item.parent, pytest.Generator): gen = item.parent if not hasattr(gen, '_nosegensetup'): @@ -28,7 +30,7 @@ call_optional(item.parent.obj, 'setup') def pytest_runtest_teardown(item): - if isinstance(item, pytest.Function): + if is_potential_nosetest(item): if not call_optional(item.obj, 'teardown'): call_optional(item.parent.obj, 'teardown') #if hasattr(item.parent, '_nosegensetup'): @@ -39,9 +41,18 @@ if isinstance(collector, pytest.Generator): call_optional(collector.obj, 'setup') + +def is_potential_nosetest(item): + # extra check needed since we do not do nose style setup/teardown + # on direct unittest style classes + return isinstance(item, pytest.Function) and \ + not isinstance(item, unittest.TestCaseFunction) + + def call_optional(obj, name): method = getattr(obj, name, None) - if method: + isfixture = hasattr(method, "_pytestfixturefunction") + if method is not None and not isfixture and py.builtin.callable(method): # If there's any problems allow the exception to raise rather than # silently ignoring them method() diff --git a/_pytest/pastebin.py b/_pytest/pastebin.py --- a/_pytest/pastebin.py +++ b/_pytest/pastebin.py @@ -2,7 +2,7 @@ import py, sys class url: - base = "http://paste.pocoo.org" + base = "http://bpaste.net" xmlrpc = base + "/xmlrpc/" show = base + "/show/" @@ -11,7 +11,7 @@ group._addoption('--pastebin', metavar="mode", action='store', dest="pastebin", default=None, type="choice", choices=['failed', 'all'], - help="send failed|all info to Pocoo pastebin service.") + help="send failed|all info to bpaste.net pastebin service.") def pytest_configure(__multicall__, config): import tempfile diff --git a/_pytest/pdb.py b/_pytest/pdb.py --- a/_pytest/pdb.py +++ b/_pytest/pdb.py @@ -50,7 +50,7 @@ def pytest_runtest_makereport(): pytestPDB.item = None - + class PdbInvoke: @pytest.mark.tryfirst def pytest_runtest_makereport(self, item, call, __multicall__): @@ -59,7 +59,7 @@ call.excinfo.errisinstance(pytest.skip.Exception) or \ call.excinfo.errisinstance(py.std.bdb.BdbQuit): return rep - if "xfail" in rep.keywords: + if hasattr(rep, "wasxfail"): return rep # we assume that the above execute() suspended capturing # XXX we re-use the TerminalReporter's terminalwriter diff --git a/_pytest/pytester.py b/_pytest/pytester.py --- a/_pytest/pytester.py +++ b/_pytest/pytester.py @@ -2,6 +2,7 @@ import py, pytest import sys, os +import codecs import re import inspect import time @@ -194,10 +195,7 @@ except py.error.EEXIST: continue break - # we need to create another subdir - # because Directory.collect() currently loads - # conftest.py from sibling directories - self.tmpdir = tmpdir.mkdir(name) + self.tmpdir = tmpdir self.plugins = [] self._syspathremove = [] self.chdir() # always chdir @@ -244,8 +242,10 @@ ret = None for name, value in items: p = self.tmpdir.join(name).new(ext=ext) - source = py.builtin._totext(py.code.Source(value)).lstrip() - p.write(source.encode("utf-8"), "wb") + source = py.builtin._totext(py.code.Source(value)).strip() + content = source.encode("utf-8") # + "\n" + #content = content.rstrip() + "\n" + p.write(content, "wb") if ret is None: ret = p return ret @@ -318,7 +318,7 @@ # used from runner functional tests item = self.getitem(source) # the test class where we are called from wants to provide the runner - testclassinstance = py.builtin._getimself(self.request.function) + testclassinstance = self.request.instance runner = testclassinstance.getrunner() return runner(item) @@ -355,7 +355,7 @@ if not plugins: plugins = [] plugins.append(Collect()) - ret = self.pytestmain(list(args), plugins=[Collect()]) + ret = self.pytestmain(list(args), plugins=plugins) reprec = rec[0] reprec.ret = ret assert len(rec) == 1 @@ -388,10 +388,12 @@ return config def getitem(self, source, funcname="test_func"): - for item in self.getitems(source): + items = self.getitems(source) + for item in items: if item.name == funcname: return item - assert 0, "%r item not found in module:\n%s" %(funcname, source) + assert 0, "%r item not found in module:\n%s\nitems: %s" %( + funcname, source, items) def getitems(self, source): modcol = self.getmodulecol(source) @@ -417,7 +419,8 @@ str(os.getcwd()), env.get('PYTHONPATH', '')])) kw['env'] = env #print "env", env - return py.std.subprocess.Popen(cmdargs, stdout=stdout, stderr=stderr, **kw) + return py.std.subprocess.Popen(cmdargs, + stdout=stdout, stderr=stderr, **kw) def pytestmain(self, *args, **kwargs): class ResetCapturing: @@ -438,28 +441,35 @@ p1 = self.tmpdir.join("stdout") p2 = self.tmpdir.join("stderr") print_("running", cmdargs, "curdir=", py.path.local()) - f1 = p1.open("wb") - f2 = p2.open("wb") - now = time.time() - popen = self.popen(cmdargs, stdout=f1, stderr=f2, - close_fds=(sys.platform != "win32")) - ret = popen.wait() - f1.close() - f2.close() - out = p1.read("rb") - out = getdecoded(out).splitlines() - err = p2.read("rb") - err = getdecoded(err).splitlines() - def dump_lines(lines, fp): - try: - for line in lines: - py.builtin.print_(line, file=fp) - except UnicodeEncodeError: - print("couldn't print to %s because of encoding" % (fp,)) - dump_lines(out, sys.stdout) - dump_lines(err, sys.stderr) + f1 = codecs.open(str(p1), "w", encoding="utf8") + f2 = codecs.open(str(p2), "w", encoding="utf8") + try: + now = time.time() + popen = self.popen(cmdargs, stdout=f1, stderr=f2, + close_fds=(sys.platform != "win32")) + ret = popen.wait() + finally: + f1.close() + f2.close() + f1 = codecs.open(str(p1), "r", encoding="utf8") + f2 = codecs.open(str(p2), "r", encoding="utf8") + try: + out = f1.read().splitlines() + err = f2.read().splitlines() + finally: + f1.close() + f2.close() + self._dump_lines(out, sys.stdout) + self._dump_lines(err, sys.stderr) return RunResult(ret, out, err, time.time()-now) + def _dump_lines(self, lines, fp): + try: + for line in lines: + py.builtin.print_(line, file=fp) + except UnicodeEncodeError: + print("couldn't print to %s because of encoding" % (fp,)) + def runpybin(self, scriptname, *args): fullargs = self._getpybinargs(scriptname) + args return self.run(*fullargs) @@ -520,6 +530,8 @@ pytest.skip("pypy-64 bit not supported") if sys.platform == "darwin": pytest.xfail("pexpect does not work reliably on darwin?!") + if sys.platform.startswith("freebsd"): + pytest.xfail("pexpect does not work reliably on freebsd") logfile = self.tmpdir.join("spawn.out") child = pexpect.spawn(cmd, logfile=logfile.open("w")) child.timeout = expect_timeout diff --git a/_pytest/python.py b/_pytest/python.py --- a/_pytest/python.py +++ b/_pytest/python.py @@ -3,17 +3,85 @@ import inspect import sys import pytest +from _pytest.main import getfslineno +from _pytest.monkeypatch import monkeypatch from py._code.code import TerminalRepr -from _pytest.monkeypatch import monkeypatch import _pytest cutdir = py.path.local(_pytest.__file__).dirpath() +callable = py.builtin.callable + +def getimfunc(func): + try: + return func.__func__ + except AttributeError: + try: + return func.im_func + except AttributeError: + return func + + +class FixtureFunctionMarker: + def __init__(self, scope, params, autouse=False): + self.scope = scope + self.params = params + self.autouse = autouse + + def __call__(self, function): + if inspect.isclass(function): + raise ValueError("class fixtures not supported (may be in the future)") + function._pytestfixturefunction = self + return function + + +def fixture(scope="function", params=None, autouse=False): + """ (return a) decorator to mark a fixture factory function. + + This decorator can be used (with or or without parameters) to define + a fixture function. The name of the fixture function can later be + referenced to cause its invocation ahead of running tests: test + modules or classes can use the pytest.mark.usefixtures(fixturename) + marker. Test functions can directly use fixture names as input + arguments in which case the fixture instance returned from the fixture + function will be injected. + + :arg scope: the scope for which this fixture is shared, one of + "function" (default), "class", "module", "session". + + :arg params: an optional list of parameters which will cause multiple + invocations of the fixture function and all of the tests + using it. + + :arg autouse: if True, the fixture func is activated for all tests that + can see it. If False (the default) then an explicit + reference is needed to activate the fixture. + """ + if callable(scope) and params is None and autouse == False: + # direct decoration + return FixtureFunctionMarker("function", params, autouse)(scope) + else: + return FixtureFunctionMarker(scope, params, autouse=autouse) + +defaultfuncargprefixmarker = fixture() + +def pyobj_property(name): + def get(self): + node = self.getparent(getattr(pytest, name)) + if node is not None: + return node.obj + doc = "python %s object this node was collected from (can be None)." % ( + name.lower(),) + return property(get, None, None, doc) + + def pytest_addoption(parser): group = parser.getgroup("general") - group.addoption('--funcargs', - action="store_true", dest="showfuncargs", default=False, - help="show available function arguments, sorted by plugin") + group.addoption('--fixtures', '--funcargs', + action="store_true", dest="showfixtures", default=False, + help="show available fixtures, sorted by plugin appearance") + parser.addini("usefixtures", type="args", default=[], + help="list of default fixtures to be used with this project") parser.addini("python_files", type="args", default=('test_*.py', '*_test.py'), help="glob-style file patterns for Python test module discovery") @@ -23,18 +91,18 @@ help="prefixes for Python test function and method discovery") def pytest_cmdline_main(config): - if config.option.showfuncargs: - showfuncargs(config) + if config.option.showfixtures: + showfixtures(config) return 0 def pytest_generate_tests(metafunc): try: - param = metafunc.function.parametrize + markers = metafunc.function.parametrize except AttributeError: return - for p in param: - metafunc.parametrize(*p.args, **p.kwargs) + for marker in markers: + metafunc.parametrize(*marker.args, **marker.kwargs) def pytest_configure(config): config.addinivalue_line("markers", @@ -42,24 +110,35 @@ "times passing in multiple different argument value sets. Example: " "@parametrize('arg1', [1,2]) would lead to two calls of the decorated " "test function, one with arg1=1 and another with arg1=2." + " see http://pytest.org/latest/parametrize.html for more info and " + "examples." + ) + config.addinivalue_line("markers", + "usefixtures(fixturename1, fixturename2, ...): mark tests as needing " + "all of the specified fixtures. see http://pytest.org/latest/fixture.html#usefixtures " ) +def pytest_sessionstart(session): + session._fixturemanager = FixtureManager(session) @pytest.mark.trylast def pytest_namespace(): raises.Exception = pytest.fail.Exception return { + 'fixture': fixture, 'raises' : raises, 'collect': { 'Module': Module, 'Class': Class, 'Instance': Instance, 'Function': Function, 'Generator': Generator, - '_fillfuncargs': fillfuncargs} + '_fillfuncargs': fillfixtures} } -def pytest_funcarg__pytestconfig(request): + at fixture() +def pytestconfig(request): """ the pytest config object with access to command line opts.""" return request.config + def pytest_pyfunc_call(__multicall__, pyfuncitem): if not __multicall__.execute(): testfunction = pyfuncitem.obj @@ -67,7 +146,10 @@ testfunction(*pyfuncitem._args) else: funcargs = pyfuncitem.funcargs - testfunction(**funcargs) + testargs = {} + for arg in pyfuncitem._fixtureinfo.argnames: + testargs[arg] = funcargs[arg] + testfunction(**testargs) def pytest_collect_file(path, parent): ext = path.ext @@ -79,8 +161,8 @@ break else: return - return parent.ihook.pytest_pycollect_makemodule( - path=path, parent=parent) + ihook = parent.session.gethookproxy(path) + return ihook.pytest_pycollect_makemodule(path=path, parent=parent) def pytest_pycollect_makemodule(path, parent): return Module(path, parent) @@ -100,7 +182,7 @@ if is_generator(obj): return Generator(name, parent=collector) else: - return collector._genfunctions(name, obj) + return list(collector._genfunctions(name, obj)) def is_generator(func): try: @@ -109,7 +191,12 @@ # assume them to not be generators return False -class PyobjMixin(object): +class PyobjContext(object): + module = pyobj_property("Module") + cls = pyobj_property("Class") + instance = pyobj_property("Instance") + +class PyobjMixin(PyobjContext): def obj(): def fget(self): try: @@ -147,18 +234,7 @@ return s.replace(".[", "[") def _getfslineno(self): - try: - return self._fslineno - except AttributeError: - pass - obj = self.obj - # xxx let decorators etc specify a sane ordering - if hasattr(obj, 'place_as'): - obj = obj.place_as - - self._fslineno = py.code.getfslineno(obj) - assert isinstance(self._fslineno[1], int), obj - return self._fslineno + return getfslineno(self.obj) def reportinfo(self): # XXX caching? @@ -168,17 +244,15 @@ fspath = sys.modules[obj.__module__].__file__ if fspath.endswith(".pyc"): fspath = fspath[:-1] - #assert 0 - #fn = inspect.getsourcefile(obj) or inspect.getfile(obj) lineno = obj.compat_co_firstlineno modpath = obj.__module__ else: - fspath, lineno = self._getfslineno() + fspath, lineno = getfslineno(obj) modpath = self.getmodpath() assert isinstance(lineno, int) return fspath, lineno, modpath -class PyCollectorMixin(PyobjMixin, pytest.Collector): +class PyCollector(PyobjMixin, pytest.Collector): def funcnamefilter(self, name): for prefix in self.config.getini("python_functions"): @@ -203,17 +277,17 @@ if name in seen: continue seen[name] = True - if name[0] != "_": - res = self.makeitem(name, obj) - if res is None: - continue - if not isinstance(res, list): - res = [res] - l.extend(res) + res = self.makeitem(name, obj) + if res is None: + continue + if not isinstance(res, list): + res = [res] + l.extend(res) l.sort(key=lambda item: item.reportinfo()[:2]) return l def makeitem(self, name, obj): + #assert self.ihook.fspath == self.fspath, self return self.ihook.pytest_pycollect_makeitem( collector=self, name=name, obj=obj) @@ -222,8 +296,10 @@ clscol = self.getparent(Class) cls = clscol and clscol.obj or None transfer_markers(funcobj, cls, module) - metafunc = Metafunc(funcobj, config=self.config, - cls=cls, module=module) + fm = self.session._fixturemanager + fixtureinfo = fm.getfixtureinfo(self, funcobj, cls) + metafunc = Metafunc(funcobj, fixtureinfo, self.config, + cls=cls, module=module) gentesthook = self.config.hook.pytest_generate_tests extra = [module] if cls is not None: @@ -232,14 +308,20 @@ gentesthook.pcall(plugins, metafunc=metafunc) Function = self._getcustomclass("Function") if not metafunc._calls: - return Function(name, parent=self) - l = [] - for callspec in metafunc._calls: - subname = "%s[%s]" %(name, callspec.id) - function = Function(name=subname, parent=self, - callspec=callspec, callobj=funcobj, keywords={callspec.id:True}) - l.append(function) - return l + yield Function(name, parent=self) + else: + for callspec in metafunc._calls: + subname = "%s[%s]" %(name, callspec.id) + yield Function(name=subname, parent=self, + callspec=callspec, callobj=funcobj, + keywords={callspec.id:True}) + + +class FuncFixtureInfo: + def __init__(self, argnames, names_closure, name2fixturedefs): + self.argnames = argnames + self.names_closure = names_closure + self.name2fixturedefs = name2fixturedefs def transfer_markers(funcobj, cls, mod): # XXX this should rather be code in the mark plugin or the mark @@ -255,10 +337,15 @@ else: pytestmark(funcobj) -class Module(pytest.File, PyCollectorMixin): +class Module(pytest.File, PyCollector): + """ Collector for test classes and functions. """ def _getobj(self): return self._memoizedcall('_obj', self._importtestmodule) + def collect(self): + self.session._fixturemanager.parsefactories(self) + return super(Module, self).collect() + def _importtestmodule(self): # we assume we are only called once per module try: @@ -283,45 +370,54 @@ return mod def setup(self): - if hasattr(self.obj, 'setup_module'): + setup_module = xunitsetup(self.obj, "setup_module") + if setup_module is not None: #XXX: nose compat hack, move to nose plugin # if it takes a positional arg, its probably a pytest style one # so we pass the current module object - if inspect.getargspec(self.obj.setup_module)[0]: - self.obj.setup_module(self.obj) + if inspect.getargspec(setup_module)[0]: + setup_module(self.obj) else: - self.obj.setup_module() + setup_module() def teardown(self): - if hasattr(self.obj, 'teardown_module'): + teardown_module = xunitsetup(self.obj, 'teardown_module') + if teardown_module is not None: #XXX: nose compat hack, move to nose plugin # if it takes a positional arg, its probably a py.test style one # so we pass the current module object - if inspect.getargspec(self.obj.teardown_module)[0]: - self.obj.teardown_module(self.obj) + if inspect.getargspec(teardown_module)[0]: + teardown_module(self.obj) else: - self.obj.teardown_module() + teardown_module() -class Class(PyCollectorMixin, pytest.Collector): - +class Class(PyCollector): + """ Collector for test methods. """ def collect(self): return [self._getcustomclass("Instance")(name="()", parent=self)] def setup(self): - setup_class = getattr(self.obj, 'setup_class', None) + setup_class = xunitsetup(self.obj, 'setup_class') if setup_class is not None: setup_class = getattr(setup_class, 'im_func', setup_class) + setup_class = getattr(setup_class, '__func__', setup_class) setup_class(self.obj) def teardown(self): - teardown_class = getattr(self.obj, 'teardown_class', None) + teardown_class = xunitsetup(self.obj, 'teardown_class') if teardown_class is not None: teardown_class = getattr(teardown_class, 'im_func', teardown_class) + teardown_class = getattr(teardown_class, '__func__', teardown_class) teardown_class(self.obj) -class Instance(PyCollectorMixin, pytest.Collector): +class Instance(PyCollector): def _getobj(self): - return self.parent.obj() + obj = self.parent.obj() + return obj + + def collect(self): + self.session._fixturemanager.parsefactories(self) + return super(Instance, self).collect() def newinstance(self): self.obj = self._getobj() @@ -330,6 +426,7 @@ class FunctionMixin(PyobjMixin): """ mixin for the code common to Function and Generator. """ + def setup(self): """ perform setup for this test function. """ if hasattr(self, '_preservedparent'): @@ -343,7 +440,7 @@ name = 'setup_method' else: name = 'setup_function' - setup_func_or_method = getattr(obj, name, None) + setup_func_or_method = xunitsetup(obj, name) if setup_func_or_method is not None: setup_func_or_method(self.obj) @@ -354,7 +451,7 @@ else: name = 'teardown_function' obj = self.parent.obj - teardown_func_or_meth = getattr(obj, name, None) + teardown_func_or_meth = xunitsetup(obj, name) if teardown_func_or_meth is not None: teardown_func_or_meth(self.obj) @@ -371,13 +468,6 @@ excinfo.traceback = ntraceback.filter() def _repr_failure_py(self, excinfo, style="long"): - if excinfo.errisinstance(FuncargRequest.LookupError): - fspath, lineno, msg = self.reportinfo() - lines, _ = inspect.getsourcelines(self.obj) - for i, line in enumerate(lines): - if line.strip().startswith('def'): - return FuncargLookupErrorRepr(fspath, lineno, - lines[:i+1], str(excinfo.value)) if excinfo.errisinstance(pytest.fail.Exception): if not excinfo.value.pytrace: return str(excinfo.value) @@ -389,24 +479,8 @@ return self._repr_failure_py(excinfo, style=self.config.option.tbstyle) -class FuncargLookupErrorRepr(TerminalRepr): - def __init__(self, filename, firstlineno, deflines, errorstring): - self.deflines = deflines - self.errorstring = errorstring - self.filename = filename - self.firstlineno = firstlineno - def toterminal(self, tw): - tw.line() - for line in self.deflines: - tw.line(" " + line.strip()) - for line in self.errorstring.split("\n"): - tw.line(" " + line.strip(), red=True) - tw.line() - tw.line("%s:%d" % (self.filename, self.firstlineno+1)) - - -class Generator(FunctionMixin, PyCollectorMixin, pytest.Collector): +class Generator(FunctionMixin, PyCollector): def collect(self): # test generators are seen as collectors but they also # invoke setup/teardown on popular request @@ -418,7 +492,7 @@ seen = {} for i, x in enumerate(self.obj()): name, call, args = self.getcallargs(x) - if not py.builtin.callable(call): + if not callable(call): raise TypeError("%r yielded non callable test %r" %(self.obj, call,)) if name is None: name = "[%d]" % i @@ -443,77 +517,6 @@ return name, call, args -# -# Test Items -# -_dummy = object() -class Function(FunctionMixin, pytest.Item): - """ a Function Item is responsible for setting up - and executing a Python callable test object. - """ - _genid = None - def __init__(self, name, parent=None, args=None, config=None, - callspec=None, callobj=_dummy, keywords=None, session=None): - super(Function, self).__init__(name, parent, - config=config, session=session) - self._args = args - if self._isyieldedfunction(): - assert not callspec, ( - "yielded functions (deprecated) cannot have funcargs") - else: - if callspec is not None: - self.callspec = callspec - self.funcargs = callspec.funcargs or {} - self._genid = callspec.id - if hasattr(callspec, "param"): - self._requestparam = callspec.param - else: - self.funcargs = {} - if callobj is not _dummy: - self._obj = callobj - self.function = getattr(self.obj, 'im_func', self.obj) - self.keywords.update(py.builtin._getfuncdict(self.obj) or {}) - if keywords: - self.keywords.update(keywords) - - def _getobj(self): - name = self.name - i = name.find("[") # parametrization - if i != -1: - name = name[:i] - return getattr(self.parent.obj, name) - - def _isyieldedfunction(self): - return self._args is not None - - def runtest(self): - """ execute the underlying test function. """ - self.ihook.pytest_pyfunc_call(pyfuncitem=self) - - def setup(self): - super(Function, self).setup() - if hasattr(self, 'funcargs'): From noreply at buildbot.pypy.org Fri Feb 15 09:27:17 2013 From: noreply at buildbot.pypy.org (RonnyPfannschmidt) Date: Fri, 15 Feb 2013 09:27:17 +0100 (CET) Subject: [pypy-commit] pypy pytest-update: support kwargs in appsupport frame getargs for recent pytest Message-ID: <20130215082717.DEB3F1C158D@cobra.cs.uni-duesseldorf.de> Author: Ronny Pfannschmidt Branch: pytest-update Changeset: r61245:b2c8635d655e Date: 2013-02-15 09:26 +0100 http://bitbucket.org/pypy/pypy/changeset/b2c8635d655e/ Log: support kwargs in appsupport frame getargs for recent pytest diff --git a/pypy/tool/pytest/appsupport.py b/pypy/tool/pytest/appsupport.py --- a/pypy/tool/pytest/appsupport.py +++ b/pypy/tool/pytest/appsupport.py @@ -35,7 +35,8 @@ return None fullsource = property(fullsource, None, None, "Full source of AppCode") - def getargs(self): + def getargs(self, **kw): + #XXX: todo: test&support the pytest argument addition return self.raw.co_varnames[:self.raw.co_argcount] class AppFrame(py.code.Frame): From noreply at buildbot.pypy.org Fri Feb 15 09:32:24 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Fri, 15 Feb 2013 09:32:24 +0100 (CET) Subject: [pypy-commit] pypy default: move test_rstruct.py to rstruct test dir Message-ID: <20130215083224.98D541C1E24@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61246:3699a4ce0ec6 Date: 2013-02-15 03:31 -0500 http://bitbucket.org/pypy/pypy/changeset/3699a4ce0ec6/ Log: move test_rstruct.py to rstruct test dir diff --git a/rpython/rlib/test/test_rstruct.py b/rpython/rlib/rstruct/test/test_rstruct.py rename from rpython/rlib/test/test_rstruct.py rename to rpython/rlib/rstruct/test/test_rstruct.py --- a/rpython/rlib/test/test_rstruct.py +++ b/rpython/rlib/rstruct/test/test_rstruct.py @@ -1,4 +1,3 @@ - from rpython.rtyper.test.tool import BaseRtypingTest, LLRtypeMixin, OORtypeMixin from rpython.rlib.rstruct.runpack import runpack from rpython.rlib.rstruct import ieee @@ -17,11 +16,9 @@ def test_unpack_2(self): data = struct.pack('iiii', 0, 1, 2, 4) - def fn(): a, b, c, d = runpack('iiii', data) return a * 1000 + b * 100 + c * 10 + d - assert fn() == 124 assert self.interpret(fn, []) == 124 @@ -69,4 +66,3 @@ check_roundtrip(-123.456) check_roundtrip(INFINITY) check_roundtrip(NAN) - From noreply at buildbot.pypy.org Fri Feb 15 10:49:32 2013 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 15 Feb 2013 10:49:32 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: Backed out changeset 1dd0aa6c631a Message-ID: <20130215094932.6D05C1C0673@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61247:9fee4b350dff Date: 2013-02-14 19:51 +0200 http://bitbucket.org/pypy/pypy/changeset/9fee4b350dff/ Log: Backed out changeset 1dd0aa6c631a diff --git a/rpython/jit/backend/arm/opassembler.py b/rpython/jit/backend/arm/opassembler.py --- a/rpython/jit/backend/arm/opassembler.py +++ b/rpython/jit/backend/arm/opassembler.py @@ -1104,52 +1104,59 @@ # XXX Split into some helper methods def emit_guard_call_assembler(self, op, guard_op, arglocs, regalloc, fcond): + tmploc = arglocs[1] + resloc = arglocs[2] + callargs = arglocs[3:] + self._store_force_index(guard_op) descr = op.getdescr() assert isinstance(descr, JitCellToken) - if len(arglocs) == 4: - [frame_loc, vloc, result_loc, argloc] = arglocs - else: - [frame_loc, result_loc, argloc] = arglocs - vloc = imm(0) - - # - # Write a call to the target assembler - # we need to allocate the frame, keep in sync with runner's - # execute_token - jd = descr.outermost_jitdriver_sd - base_ofs = self.cpu.get_baseofs_of_frame_field() - self._emit_call(imm(descr._ll_function_addr), [argloc], fcond) + # check value + assert tmploc is r.r0 + self._emit_call(imm(descr._ll_function_addr), + callargs, fcond, resloc=tmploc) if op.result is None: - assert result_loc is None - value = self.cpu.done_with_this_frame_descr_void + value = self.cpu.done_with_this_frame_void_v else: kind = op.result.type if kind == INT: - assert result_loc is r.r0 - value = self.cpu.done_with_this_frame_descr_int + value = self.cpu.done_with_this_frame_int_v elif kind == REF: - assert result_loc is r.r0 - value = self.cpu.done_with_this_frame_descr_ref + value = self.cpu.done_with_this_frame_ref_v elif kind == FLOAT: - value = self.cpu.done_with_this_frame_descr_float + value = self.cpu.done_with_this_frame_float_v else: raise AssertionError(kind) + from rpython.jit.backend.llsupport.descr import unpack_fielddescr + from rpython.jit.backend.llsupport.descr import unpack_interiorfielddescr + descrs = self.cpu.gc_ll_descr.getframedescrs(self.cpu) + _offset, _size, _ = unpack_fielddescr(descrs.jf_descr) + fail_descr = self.cpu.get_fail_descr_from_number(value) + value = fail_descr.hide(self.cpu) + rgc._make_sure_does_not_move(value) + value = rffi.cast(lltype.Signed, value) - - gcref = cast_instance_to_gcref(value) - rgc._make_sure_does_not_move(gcref) - value = rffi.cast(lltype.Signed, gcref) - ofs = self.cpu.get_ofs_of_frame_field('jf_descr') - assert check_imm_arg(ofs) - self.mc.LDR_ri(r.ip.value, r.r0.value, imm=ofs) - + if check_imm_arg(_offset): + self.mc.LDR_ri(r.ip.value, tmploc.value, imm=_offset) + else: + self.mc.gen_load_int(r.ip.value, _offset) + self.mc.LDR_rr(r.ip.value, tmploc.value, r.ip.value) if check_imm_arg(value): self.mc.CMP_ri(r.ip.value, imm=value) else: self.mc.gen_load_int(r.lr.value, value) self.mc.CMP_rr(r.lr.value, r.ip.value) - # Path 1: Fast Path + + + #if values are equal we take the fast path + # Slow path, calling helper + # jump to merge point + + jd = descr.outermost_jitdriver_sd + assert jd is not None + + # Path A: load return value and reset token + # Fast Path using result boxes fast_path_cond = c.EQ # Reset the vable token --- XXX really too much special logic here:-( @@ -1157,40 +1164,45 @@ from rpython.jit.backend.llsupport.descr import FieldDescr fielddescr = jd.vable_token_descr assert isinstance(fielddescr, FieldDescr) - assert isinstance(fielddescr, FieldDescr) - vtoken_ofs = fielddescr.offset - assert check_imm_arg(vtoken_ofs) - self.mov_loc_loc(vloc, r.ip, cond=fast_path_cond) - self.mc.MOV_ri(r.lr.value, 0, cond=fast_path_cond) - self.mc.STR_ri(tmploc.value, r.ip.value, vtoken_ofs, cond=fast_path_cond) - # in the line above, TOKEN_NONE = 0 + ofs = fielddescr.offset + tmploc = regalloc.get_scratch_reg(INT) + self.mov_loc_loc(arglocs[0], r.ip, cond=fast_path_cond) + self.mc.MOV_ri(tmploc.value, 0, cond=fast_path_cond) + self.mc.STR_ri(tmploc.value, r.ip.value, ofs, cond=fast_path_cond) if op.result is not None: - # load the return value from the dead frame's value index 0 + # load the return value from fail_boxes_xxx[0] kind = op.result.type if kind == FLOAT: - descr = self.cpu.getarraydescr_for_frame(kind) - ofs = self.cpu.unpack_arraydescr(descr) - if not check_imm_arg(ofs): - self.mc.gen_load_int(r.ip.value, ofs, cond=fast_path_cond) + t = unpack_interiorfielddescr(descrs.as_float)[0] + if not check_imm_arg(t): + self.mc.gen_load_int(r.ip.value, t, cond=fast_path_cond) self.mc.ADD_rr(r.ip.value, r.r0.value, r.ip.value, cond=fast_path_cond) - ofs = 0 + t = 0 base = r.ip else: base = r.r0 - self.mc.VLDR(result_loc.value, base.value, imm=ofs, - cond=fast_path_cond) + self.mc.VLDR(resloc.value, base.value, imm=t, + cond=fast_path_cond) else: - assert result_loc is r.r0 - descr = self.cpu.getarraydescr_for_frame(kind) - ofs = self.cpu.unpack_arraydescr(descr) - self.load_reg(self.mc, r.r0, r.r0, ofs, cond=fast_path_cond) + assert resloc is r.r0 + if kind == INT: + t = unpack_interiorfielddescr(descrs.as_int)[0] + else: + t = unpack_interiorfielddescr(descrs.as_ref)[0] + if not check_imm_arg(t): + self.mc.gen_load_int(r.ip.value, t, cond=fast_path_cond) + self.mc.LDR_rr(resloc.value, resloc.value, r.ip.value, + cond=fast_path_cond) + else: + self.mc.LDR_ri(resloc.value, resloc.value, imm=t, + cond=fast_path_cond) # jump to merge point jmp_pos = self.mc.currpos() self.mc.BKPT() - # Path 2: use assembler helper + # Path B: use assembler helper asm_helper_adr = self.cpu.cast_adr_to_int(jd.assembler_helper_adr) if self.cpu.supports_floats: floats = r.caller_vfp_resp @@ -1201,24 +1213,28 @@ # the result core = r.caller_resp if op.result: - if result_loc.is_vfp_reg(): + if resloc.is_vfp_reg(): floats = r.caller_vfp_resp[1:] else: core = r.caller_resp[1:] + [r.ip] # keep alignment with saved_registers(self.mc, core, floats): # result of previous call is in r0 - self.mov_loc_loc(vloc, r.r1) + self.mov_loc_loc(arglocs[0], r.r1) self.mc.BL(asm_helper_adr) - if not self.cpu.use_hf_abi and op.result and result_loc.is_vfp_reg(): + if not self.cpu.use_hf_abi and op.result and resloc.is_vfp_reg(): # move result to the allocated register - self.mov_to_vfp_loc(r.r0, r.r1, result_loc) + self.mov_to_vfp_loc(r.r0, r.r1, resloc) # merge point currpos = self.mc.currpos() pmc = OverwritingBuilder(self.mc, jmp_pos, WORD) pmc.B_offs(currpos, fast_path_cond) - self._emit_guard_may_force(guard_op, arglocs, op.numargs()) + self.mc.LDR_ri(r.ip.value, r.fp.value) + self.mc.CMP_ri(r.ip.value, 0) + + self._emit_guard(guard_op, regalloc._prepare_guard(guard_op), + c.GE, save_exc=True) return fcond # ../x86/assembler.py:668 diff --git a/rpython/jit/backend/arm/regalloc.py b/rpython/jit/backend/arm/regalloc.py --- a/rpython/jit/backend/arm/regalloc.py +++ b/rpython/jit/backend/arm/regalloc.py @@ -1101,18 +1101,20 @@ prepare_guard_call_release_gil = prepare_guard_call_may_force def prepare_guard_call_assembler(self, op, guard_op, fcond): - descr = op.getdescr() assert isinstance(descr, JitCellToken) - arglist = op.getarglist() - self.rm._sync_var(arglist[0]) - frame_loc = self.fm.loc(op.getarg(0)) - if len(arglist) == 2: - self.rm._sync_var(arglist[1]) - locs = [frame_loc, self.fm.loc(arglist[1])] + jd = descr.outermost_jitdriver_sd + assert jd is not None + vable_index = jd.index_of_virtualizable + if vable_index >= 0: + self._sync_var(op.getarg(vable_index)) + vable = self.frame_manager.loc(op.getarg(vable_index)) else: - locs = [frame_loc] - return locs + self._prepare_call(op, save_all_regs=True) + vable = imm(0) + # make sure the call result location is free + tmploc = self.get_scratch_reg(INT, selected_reg=r.r0) + self.possibly_free_vars(guard_op.getfailargs()) + return [vable, tmploc] + self._prepare_call(op, save_all_regs=True) def _prepare_args_for_new_op(self, new_args): gc_ll_descr = self.cpu.gc_ll_descr From noreply at buildbot.pypy.org Fri Feb 15 10:49:33 2013 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 15 Feb 2013 10:49:33 +0100 (CET) Subject: [pypy-commit] pypy default: fix the test for 32bit Message-ID: <20130215094933.BA05F1C158D@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r61248:57adf4d24214 Date: 2013-02-15 11:48 +0200 http://bitbucket.org/pypy/pypy/changeset/57adf4d24214/ Log: fix the test for 32bit diff --git a/rpython/rlib/test/test_rarithmetic.py b/rpython/rlib/test/test_rarithmetic.py --- a/rpython/rlib/test/test_rarithmetic.py +++ b/rpython/rlib/test/test_rarithmetic.py @@ -400,8 +400,8 @@ assert rffi.cast(lltype.Signed, byteswap(rffi.cast(rffi.USHORT, 0x0102))) == 0x0201 assert rffi.cast(lltype.Signed, byteswap(rffi.cast(rffi.INT, 0x01020304))) == 0x04030201 - assert byteswap(rffi.cast(rffi.ULONGLONG, 0x0102030405060708L)) == 0x0807060504030201L - assert byteswap(rffi.cast(rffi.LONGLONG, 0x0102030405060708L)) == 0x0807060504030201L + assert byteswap(r_ulonglong(0x0102030405060708L)) == r_ulonglong(0x0807060504030201L) + assert byteswap(r_longlong(0x0102030405060708L)) == r_longlong(0x0807060504030201L) assert ((byteswap(2.3) - 1.903598566252326e+185) / 1e185) < 0.000001 assert (rffi.cast(lltype.Float, byteswap(rffi.cast(lltype.SingleFloat, 2.3))) - 4.173496037651603e-08) < 1e-16 From noreply at buildbot.pypy.org Fri Feb 15 12:00:03 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Fri, 15 Feb 2013 12:00:03 +0100 (CET) Subject: [pypy-commit] pypy default: move these ieee-specific tests to test_ieee.py Message-ID: <20130215110003.F0E8F1C062C@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61249:9ca97c0a7ccd Date: 2013-02-15 04:05 -0500 http://bitbucket.org/pypy/pypy/changeset/9ca97c0a7ccd/ Log: move these ieee-specific tests to test_ieee.py diff --git a/rpython/rlib/rstruct/test/test_ieee.py b/rpython/rlib/rstruct/test/test_ieee.py --- a/rpython/rlib/rstruct/test/test_ieee.py +++ b/rpython/rlib/rstruct/test/test_ieee.py @@ -1,9 +1,11 @@ -import py, sys +import py +import sys import random import struct -from rpython.rlib.rfloat import isnan -from rpython.rlib.rstruct.ieee import float_pack, float_unpack, float_pack80, float_unpack80 +from rpython.rlib.rstruct import ieee +from rpython.rlib.rfloat import isnan, NAN, INFINITY +from rpython.translator.c.test.test_genc import compile class TestFloatPacking: def setup_class(cls): @@ -12,17 +14,17 @@ def check_float(self, x): # check roundtrip - Q = float_pack(x, 8) - y = float_unpack(Q, 8) + Q = ieee.float_pack(x, 8) + y = ieee.float_unpack(Q, 8) assert repr(x) == repr(y) - Q = float_pack80(x) - y = float_unpack80(Q) + Q = ieee.float_pack80(x) + y = ieee.float_unpack80(Q) assert repr(x) == repr(y),'%r != %r, Q=%r'%(x, y, Q) # check that packing agrees with the struct module struct_pack8 = struct.unpack(' Author: Brian Kearns Branch: Changeset: r61254:2c747f18f5fd Date: 2013-02-15 05:52 -0500 http://bitbucket.org/pypy/pypy/changeset/2c747f18f5fd/ Log: make sure pack/unpack_float80 are doing what they claim, add tests diff --git a/pypy/module/micronumpy/types.py b/pypy/module/micronumpy/types.py --- a/pypy/module/micronumpy/types.py +++ b/pypy/module/micronumpy/types.py @@ -14,8 +14,8 @@ from rpython.rtyper.lltypesystem import lltype, rffi from rpython.rlib.rstruct.runpack import runpack from rpython.rlib.rstruct.nativefmttable import native_is_bigendian -from rpython.rlib.rstruct.ieee import (float_pack, float_unpack, pack_float80, - unpack_float, unpack_float128) +from rpython.rlib.rstruct.ieee import (float_pack, float_unpack, unpack_float, + pack_float80, unpack_float80) from rpython.tool.sourcetools import func_with_new_name from rpython.rlib import jit from rpython.rlib.rstring import StringBuilder @@ -1525,14 +1525,14 @@ def runpack_str(self, s): assert len(s) == 12 - fval = unpack_float128(s, native_is_bigendian) + fval = unpack_float80(s, native_is_bigendian) return self.box(fval) def byteswap(self, w_v): value = self.unbox(w_v) result = StringBuilder(12) - pack_float80(result, value, 12, not native_is_bigendian) - return self.box(unpack_float128(result.build(), native_is_bigendian)) + pack_float80(result, value, not native_is_bigendian) + return self.box(unpack_float80(result.build(), native_is_bigendian)) NonNativeFloat96 = Float96 @@ -1555,14 +1555,14 @@ def runpack_str(self, s): assert len(s) == 16 - fval = unpack_float128(s, native_is_bigendian) + fval = unpack_float80(s, native_is_bigendian) return self.box(fval) def byteswap(self, w_v): value = self.unbox(w_v) result = StringBuilder(16) - pack_float80(result, value, 16, not native_is_bigendian) - return self.box(unpack_float128(result.build(), native_is_bigendian)) + pack_float80(result, value, not native_is_bigendian) + return self.box(unpack_float80(result.build(), native_is_bigendian)) NonNativeFloat128 = Float128 diff --git a/rpython/rlib/rstruct/ieee.py b/rpython/rlib/rstruct/ieee.py --- a/rpython/rlib/rstruct/ieee.py +++ b/rpython/rlib/rstruct/ieee.py @@ -235,12 +235,12 @@ result.append("".join(l)) @jit.unroll_safe -def pack_float80(result, x, size, be): +def pack_float80(result, x, be): l = [] unsigned = float_pack80(x) for i in range(8): l.append(chr((unsigned[0] >> (i * 8)) & 0xFF)) - for i in range(size - 8): + for i in range(2): l.append(chr((unsigned[1] >> (i * 8)) & 0xFF)) if be: l.reverse() @@ -253,12 +253,14 @@ unsigned |= r_ulonglong(c) << (i * 8) return float_unpack(unsigned, len(s)) -def unpack_float128(s, be): +def unpack_float80(s, be): + if len(s) != 10: + raise ValueError QQ = [r_ulonglong(0), r_ulonglong(0)] for i in range(8): - c = ord(s[len(s) - 1 - i if be else i]) + c = ord(s[9 - i if be else i]) QQ[0] |= r_ulonglong(c) << (i * 8) - for i in range(8, len(s)): - c = ord(s[len(s) - 1 - i if be else i]) + for i in range(8, 10): + c = ord(s[9 - i if be else i]) QQ[1] |= r_ulonglong(c) << ((i - 8) * 8) return float_unpack80(QQ) diff --git a/rpython/rlib/rstruct/test/test_ieee.py b/rpython/rlib/rstruct/test/test_ieee.py --- a/rpython/rlib/rstruct/test/test_ieee.py +++ b/rpython/rlib/rstruct/test/test_ieee.py @@ -23,6 +23,18 @@ y = ieee.float_unpack80(Q) assert repr(x) == repr(y), '%r != %r, Q=%r' % (x, y, Q) + Q = [] + ieee.pack_float(Q, x, 8, False) + Q = Q[0] + y = ieee.unpack_float(Q, False) + assert repr(x) == repr(y), '%r != %r, Q=%r' % (x, y, Q) + + Q = [] + ieee.pack_float80(Q, x, False) + Q = Q[0] + y = ieee.unpack_float80(Q, False) + assert repr(x) == repr(y), '%r != %r, Q=%r' % (x, y, Q) + # check that packing agrees with the struct module struct_pack8 = struct.unpack(' Author: Brian Kearns Branch: Changeset: r61250:0e1ee744f087 Date: 2013-02-15 04:06 -0500 http://bitbucket.org/pypy/pypy/changeset/0e1ee744f087/ Log: these tests are runpack specific diff --git a/rpython/rlib/rstruct/test/test_rstruct.py b/rpython/rlib/rstruct/test/test_runpack.py rename from rpython/rlib/rstruct/test/test_rstruct.py rename to rpython/rlib/rstruct/test/test_runpack.py From noreply at buildbot.pypy.org Fri Feb 15 12:00:06 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Fri, 15 Feb 2013 12:00:06 +0100 (CET) Subject: [pypy-commit] pypy default: enhance this test to check roundtrip for all float sizes Message-ID: <20130215110006.5992C1C1E2B@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61251:6c656645c344 Date: 2013-02-15 04:13 -0500 http://bitbucket.org/pypy/pypy/changeset/6c656645c344/ Log: enhance this test to check roundtrip for all float sizes diff --git a/rpython/rlib/rstruct/test/test_ieee.py b/rpython/rlib/rstruct/test/test_ieee.py --- a/rpython/rlib/rstruct/test/test_ieee.py +++ b/rpython/rlib/rstruct/test/test_ieee.py @@ -171,24 +171,24 @@ class TestCompiled: def test_pack_float(self): - def pack(x): + def pack(x, size): result = [] - ieee.pack_float(result, x, 8, False) + ieee.pack_float(result, x, size, False) l = [] for x in result: for c in x: l.append(str(ord(c))) return ','.join(l) - c_pack = compile(pack, [float]) + c_pack = compile(pack, [float, int]) def unpack(s): l = s.split(',') s = ''.join([chr(int(x)) for x in l]) return ieee.unpack_float(s, False) c_unpack = compile(unpack, [str]) - def check_roundtrip(x): - s = c_pack(x) - assert s == pack(x) + def check_roundtrip(x, size): + s = c_pack(x, size) + assert s == pack(x, size) if not isnan(x): assert unpack(s) == x assert c_unpack(s) == x @@ -196,7 +196,8 @@ assert isnan(unpack(s)) assert isnan(c_unpack(s)) - check_roundtrip(123.456) - check_roundtrip(-123.456) - check_roundtrip(INFINITY) - check_roundtrip(NAN) + for size in [2, 4, 8]: + check_roundtrip(123.4375, size) + check_roundtrip(-123.4375, size) + check_roundtrip(INFINITY, size) + check_roundtrip(NAN, size) From noreply at buildbot.pypy.org Fri Feb 15 12:00:07 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Fri, 15 Feb 2013 12:00:07 +0100 (CET) Subject: [pypy-commit] pypy default: small cleanups Message-ID: <20130215110007.892901C1E4F@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61252:129254fd3ac3 Date: 2013-02-15 04:18 -0500 http://bitbucket.org/pypy/pypy/changeset/129254fd3ac3/ Log: small cleanups diff --git a/pypy/module/micronumpy/types.py b/pypy/module/micronumpy/types.py --- a/pypy/module/micronumpy/types.py +++ b/pypy/module/micronumpy/types.py @@ -958,7 +958,6 @@ swapped_value = byteswap(rffi.cast(self.T, value)) raw_storage_setitem(storage, i + offset, swapped_value) - class Float32(BaseType, Float): _attrs_ = () @@ -1505,7 +1504,6 @@ BoxType = interp_boxes.W_Complex64Box ComponentBoxType = interp_boxes.W_Float32Box - NonNativeComplex64 = Complex64 class Complex128(ComplexFloating, BaseType): @@ -1515,7 +1513,6 @@ BoxType = interp_boxes.W_Complex128Box ComponentBoxType = interp_boxes.W_Float64Box - NonNativeComplex128 = Complex128 if interp_boxes.long_double_size == 12: @@ -1537,8 +1534,7 @@ pack_float80(result, value, 12, not native_is_bigendian) return self.box(unpack_float128(result.build(), native_is_bigendian)) - class NonNativeFloat96(Float96): - pass + NonNativeFloat96 = Float96 class Complex192(ComplexFloating, BaseType): _attrs_ = () @@ -1549,7 +1545,6 @@ NonNativeComplex192 = Complex192 - elif interp_boxes.long_double_size == 16: class Float128(BaseType, Float): _attrs_ = () @@ -1578,7 +1573,6 @@ BoxType = interp_boxes.W_Complex256Box ComponentBoxType = interp_boxes.W_Float128Box - NonNativeComplex256 = Complex256 class BaseStringType(object): diff --git a/rpython/rlib/rstruct/test/test_ieee.py b/rpython/rlib/rstruct/test/test_ieee.py --- a/rpython/rlib/rstruct/test/test_ieee.py +++ b/rpython/rlib/rstruct/test/test_ieee.py @@ -7,6 +7,7 @@ from rpython.rlib.rfloat import isnan, NAN, INFINITY from rpython.translator.c.test.test_genc import compile + class TestFloatPacking: def setup_class(cls): if sys.version_info < (2, 6): @@ -16,11 +17,11 @@ # check roundtrip Q = ieee.float_pack(x, 8) y = ieee.float_unpack(Q, 8) - assert repr(x) == repr(y) + assert repr(x) == repr(y), '%r != %r, Q=%r' % (x, y, Q) Q = ieee.float_pack80(x) y = ieee.float_unpack80(Q) - assert repr(x) == repr(y),'%r != %r, Q=%r'%(x, y, Q) + assert repr(x) == repr(y), '%r != %r, Q=%r' % (x, y, Q) # check that packing agrees with the struct module struct_pack8 = struct.unpack(' Author: Brian Kearns Branch: Changeset: r61253:7567d8e56a54 Date: 2013-02-15 05:01 -0500 http://bitbucket.org/pypy/pypy/changeset/7567d8e56a54/ Log: cleanup byteswap function diff --git a/rpython/rlib/rarithmetic.py b/rpython/rlib/rarithmetic.py --- a/rpython/rlib/rarithmetic.py +++ b/rpython/rlib/rarithmetic.py @@ -630,21 +630,16 @@ uint2singlefloat, singlefloat2uint T = lltype.typeOf(arg) - is_float = False - is_single_float = False if T == lltype.SingleFloat: - T = rffi.UINT - is_single_float = True arg = singlefloat2uint(arg) elif T == lltype.Float: - is_float = True - T = rffi.LONGLONG arg = float2longlong(arg) elif T == lltype.LongFloat: assert False else: # we cannot do arithmetics on small ints arg = widen(arg) + if rffi.sizeof(T) == 1: res = arg elif rffi.sizeof(T) == 2: @@ -667,9 +662,9 @@ (f >> 24) | (g >> 40) | (h >> 56)) else: assert False # unreachable code - if is_single_float: + + if T == lltype.SingleFloat: return uint2singlefloat(rffi.cast(rffi.UINT, res)) - if is_float: - res = rffi.cast(rffi.LONGLONG, res) - return longlong2float(res) + if T == lltype.Float: + return longlong2float(rffi.cast(rffi.LONGLONG, res)) return rffi.cast(T, res) From noreply at buildbot.pypy.org Fri Feb 15 13:50:45 2013 From: noreply at buildbot.pypy.org (krono) Date: Fri, 15 Feb 2013 13:50:45 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: first jit hints, also: image with special test methods Message-ID: <20130215125045.A45EC1C00A8@cobra.cs.uni-duesseldorf.de> Author: Tobias Pape Branch: Changeset: r30:10a0cd258ca6 Date: 2013-02-15 13:48 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/10a0cd258ca6/ Log: first jit hints, also: image with special test methods diff --git a/spyvm/fixedstack.py b/spyvm/fixedstack.py --- a/spyvm/fixedstack.py +++ b/spyvm/fixedstack.py @@ -4,6 +4,7 @@ import types +from rpython.rlib import jit from rpython.rlib.rarithmetic import r_uint class FixedStack(object): @@ -29,18 +30,20 @@ return s def push(self, item): - ptr = self.ptr + ptr = jit.promote(self.ptr) self.items[ptr] = item self.ptr = ptr + 1 def pop(self): - ptr = self.ptr - 1 + ptr = jit.promote(self.ptr) - 1 ret = self.items[ptr] # you get OverflowError if the stack is empty self.items[ptr] = None self.ptr = ptr return ret - + + @jit.unroll_safe def drop(self, n): + jit.promote(self.ptr) while n > 0: n -= 1 self.ptr -= 1 diff --git a/spyvm/interpreter.py b/spyvm/interpreter.py --- a/spyvm/interpreter.py +++ b/spyvm/interpreter.py @@ -18,7 +18,9 @@ """Illegal Store.""" def get_printable_location(pc, self, w_method): - return '%d: %s' % (pc, w_method.bytes[pc]) + bc = ord(w_method.bytes[pc]) + return '%d: [%s]%s' % (pc, hex(bc), BYTECODE_NAMES[bc]) + class Interpreter(object): @@ -26,9 +28,9 @@ cnt = 0 _last_indent = "" jit_driver = jit.JitDriver( - greens = ['pc', 'self', 'w_method'], - reds = ['s_active_context'], - get_printable_location = get_printable_location + greens=['pc', 'self', 'w_method'], + reds=['s_active_context'], + get_printable_location=get_printable_location ) def __init__(self, space, image_name=""): @@ -96,11 +98,8 @@ w_method = s_active_context.w_method() self.jit_driver.jit_merge_point( - self = self, - pc = pc, - w_method = w_method, - s_active_context = s_active_context) - + pc=pc, self=self, w_method=w_method, + s_active_context=s_active_context) self.step(s_active_context) @@ -548,6 +547,20 @@ ] +def initialize_bytecode_names(): + result = [None] * 256 + for entry in BYTECODE_RANGES: + if len(entry) == 2: + positions = [entry[0]] + else: + positions = range(entry[0], entry[1]+1) + for pos in positions: + result[pos] = entry[-1] + assert None not in result + return result + +BYTECODE_NAMES = initialize_bytecode_names() + def initialize_bytecode_table(): result = [None] * 256 for entry in BYTECODE_RANGES: @@ -560,6 +573,7 @@ assert None not in result return result + BYTECODE_TABLE = initialize_bytecode_table() @@ -594,3 +608,4 @@ # translating the interpreter # if objectmodel.we_are_translated(): Interpreter.step = bytecode_step_translated + diff --git a/spyvm/minitest.image b/spyvm/minitest.image new file mode 100644 index 0000000000000000000000000000000000000000..5753d32adc6e5ca83c6b7bf990258090ca1812d7 GIT binary patch [cut] diff --git a/spyvm/shadow.py b/spyvm/shadow.py --- a/spyvm/shadow.py +++ b/spyvm/shadow.py @@ -1,7 +1,7 @@ import weakref from spyvm import model, constants, error from rpython.tool.pairtype import extendabletype -from rpython.rlib import rarithmetic +from rpython.rlib import rarithmetic, jit class AbstractShadow(object): """A shadow is an optional extra bit of information that @@ -445,6 +445,7 @@ return self.s_home().w_method() def getbytecode(self): + jit.promote(self._pc) assert self._pc >= 0 bytecode = self.w_method().bytes[self._pc] currentBytecode = ord(bytecode) diff --git a/spyvm/test/jit.py b/spyvm/test/jit.py --- a/spyvm/test/jit.py +++ b/spyvm/test/jit.py @@ -16,7 +16,7 @@ from spyvm import model, interpreter, primitives, shadow from spyvm import objspace -from spyvm.tool.analyseimage import create_squeakimage +from spyvm.tool.analyseimage import create_testimage mockclass = objspace.bootstrap_class @@ -51,18 +51,18 @@ class TestLLtype(LLJitMixin): - def test_tiny_benchmarks(self): + def test_miniloop(self): - def tinyBenchmarks(): + def miniloop(): from spyvm import objspace space = objspace.ObjSpace() - image = create_squeakimage(space) + image = create_testimage(space) interp = interpreter.Interpreter(space) w_object = model.W_SmallInteger(0) s_class = w_object.shadow_of_my_class(space) - w_method = s_class.lookup("tinyBenchmarks") + w_method = s_class.lookup("loopTest") assert w_method w_frame = w_method.create_frame(space, w_object, []) @@ -73,11 +73,9 @@ from spyvm.interpreter import BYTECODE_TABLE return interp - interp = tinyBenchmarks() + interp = miniloop() def interp_w(): interp.interpret() - self.meta_interp(interp_w, [], listcomp=True, listops=True, - #backendopt=True - ) + self.meta_interp(interp_w, [], listcomp=True, listops=True, backendopt=True) diff --git a/spyvm/tool/analyseimage.py b/spyvm/tool/analyseimage.py --- a/spyvm/tool/analyseimage.py +++ b/spyvm/tool/analyseimage.py @@ -6,18 +6,29 @@ import sys mini_image = py.path.local(__file__).dirpath().dirpath().join('mini.image') +minitest_image = py.path.local(__file__).dirpath().dirpath().join('minitest.image') def get_miniimage(space): return squeakimage.ImageReader(space, squeakimage.Stream(mini_image.open())) -def create_squeakimage(space): - example = get_miniimage(space) - example.initialize() +def get_minitestimage(space): + return squeakimage.ImageReader(space, squeakimage.Stream(minitest_image.open())) + +def create_image(space, image_reader): + image_reader.initialize() image = squeakimage.SqueakImage() - image.from_reader(space, example) + image.from_reader(space, image_reader) return image + +def create_squeakimage(space): + return create_image(space, get_miniimage(space)) + +def create_testimage(space): + return create_image(space, get_minitestimage(space)) + + def printStringsInImage(): image = create_squeakimage() for each in image.objects: From noreply at buildbot.pypy.org Fri Feb 15 13:50:46 2013 From: noreply at buildbot.pypy.org (krono) Date: Fri, 15 Feb 2013 13:50:46 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: merge Message-ID: <20130215125046.D6DF71C062C@cobra.cs.uni-duesseldorf.de> Author: Tobias Pape Branch: Changeset: r31:dcd301b0ca03 Date: 2013-02-15 13:50 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/dcd301b0ca03/ Log: merge diff --git a/spyvm/targettinybenchsmalltalk.py b/spyvm/targettinybenchsmalltalk.py --- a/spyvm/targettinybenchsmalltalk.py +++ b/spyvm/targettinybenchsmalltalk.py @@ -1,4 +1,3 @@ -import autopath1 import os, sys from spyvm import model, interpreter, primitives, shadow, constants from spyvm.tool.analyseimage import create_squeakimage @@ -64,4 +63,7 @@ return entry_point, None def jitpolicy(driver): - return JitPolicy() \ No newline at end of file + return JitPolicy() + +if __name__ == "__main__": + entry_point(sys.argv) diff --git a/spyvm/test/test_interpreter.py b/spyvm/test/test_interpreter.py --- a/spyvm/test/test_interpreter.py +++ b/spyvm/test/test_interpreter.py @@ -25,7 +25,7 @@ globals()[name] = make_getter(entry) setup() -def run_with_faked_methods(methods, func): +def run_with_faked_methods(methods, func, active_context=None): # Install faked compiled methods that just invoke the primitive: for (w_class, primnum, argsize, methname) in methods: @@ -38,7 +38,7 @@ assert space.w_nil._shadow is None try: - func() + func(active_context) if active_context else func() finally: # Uninstall those methods: assert space.w_nil._shadow is None @@ -120,7 +120,7 @@ # push bytecodes def test_pushReceiverBytecode(): interp = new_interpreter(pushReceiverBytecode) - interp.step() + interp.step(interp.s_active_context()) assert interp.s_active_context().top().is_same_object( interp.w_active_context().as_methodcontext_get_shadow(space).w_receiver()) @@ -132,9 +132,9 @@ w_demo.store(space, 1, "bar") w_demo.store(space, 2, "baz") interp = new_interpreter(bytecode, receiver = w_demo) - interp.step() - interp.step() - interp.step() + interp.step(interp.s_active_context()) + interp.step(interp.s_active_context()) + interp.step(interp.s_active_context()) assert interp.s_active_context().stack() == ["egg", "bar", "baz"] def test_pushTemporaryVariableBytecode(bytecode=(pushTemporaryVariableBytecode(0) + @@ -142,9 +142,9 @@ pushTemporaryVariableBytecode(2))): interp = new_interpreter(bytecode) interp.w_active_context().as_methodcontext_get_shadow(space).settemp(2, "temp") - interp.step() - interp.step() - interp.step() + interp.step(interp.s_active_context()) + interp.step(interp.s_active_context()) + interp.step(interp.s_active_context()) assert interp.s_active_context().stack() == ["foo", "bar", "temp"] def test_pushLiteralConstantBytecode(bytecode=pushLiteralConstantBytecode(0) + @@ -152,9 +152,9 @@ pushLiteralConstantBytecode(2)): interp = new_interpreter(bytecode) interp.w_active_context().as_methodcontext_get_shadow(space).w_method().literals = fakeliterals(space, "a", "b", "c") - interp.step() - interp.step() - interp.step() + interp.step(interp.s_active_context()) + interp.step(interp.s_active_context()) + interp.step(interp.s_active_context()) assert interp.s_active_context().stack() == [fakesymbol("a"), fakesymbol("b"), fakesymbol("c")] @@ -165,7 +165,7 @@ w_association.store(space, 1, "myvalue") interp = new_interpreter(bytecode) interp.w_active_context().as_methodcontext_get_shadow(space).w_method().literals = fakeliterals(space, w_association) - interp.step() + interp.step(interp.s_active_context()) assert interp.s_active_context().stack() == ["myvalue"] def test_storeAndPopReceiverVariableBytecode(bytecode=storeAndPopReceiverVariableBytecode, @@ -175,8 +175,8 @@ w_object = shadow.new() interp = new_interpreter(pushConstantTrueBytecode + bytecode(index)) interp.w_active_context().as_methodcontext_get_shadow(space).store_w_receiver(w_object) - interp.step() - interp.step() + interp.step(interp.s_active_context()) + interp.step(interp.s_active_context()) if popped: assert interp.s_active_context().stack() == [] else: @@ -192,8 +192,8 @@ for index in range(8): interp = new_interpreter(pushConstantTrueBytecode + bytecode(index)) #interp.w_active_context().as_methodcontext_get_shadow(space).temps = [None] * 8 - interp.step() - interp.step() + interp.step(interp.s_active_context()) + interp.step(interp.s_active_context()) assert interp.s_active_context().stack() == [] interp.w_active_context().as_methodcontext_get_shadow(space) for test_index in range(8): @@ -205,141 +205,141 @@ def test_pushConstantTrueBytecode(): interp = new_interpreter(pushConstantTrueBytecode) - interp.step() + interp.step(interp.s_active_context()) assert interp.s_active_context().pop().is_same_object(space.w_true) assert interp.s_active_context().stack() == [] def test_pushConstantFalseBytecode(): interp = new_interpreter(pushConstantFalseBytecode) - interp.step() + interp.step(interp.s_active_context()) assert interp.s_active_context().pop().is_same_object(space.w_false) assert interp.s_active_context().stack() == [] def test_pushConstantNilBytecode(): interp = new_interpreter(pushConstantNilBytecode) - interp.step() + interp.step(interp.s_active_context()) assert interp.s_active_context().pop().is_same_object(space.w_nil) assert interp.s_active_context().stack() == [] def test_pushConstantMinusOneBytecode(): interp = new_interpreter(pushConstantMinusOneBytecode) - interp.step() + interp.step(interp.s_active_context()) assert interp.s_active_context().pop().is_same_object(space.w_minus_one) assert interp.s_active_context().stack() == [] def test_pushConstantZeroBytecode(): interp = new_interpreter(pushConstantZeroBytecode) - interp.step() + interp.step(interp.s_active_context()) assert interp.s_active_context().pop().is_same_object(space.w_zero) assert interp.s_active_context().stack() == [] def test_pushConstantOneBytecode(): interp = new_interpreter(pushConstantOneBytecode) - interp.step() + interp.step(interp.s_active_context()) assert interp.s_active_context().pop().is_same_object(space.w_one) assert interp.s_active_context().stack() == [] def test_pushConstantTwoBytecode(): interp = new_interpreter(pushConstantTwoBytecode) - interp.step() + interp.step(interp.s_active_context()) assert interp.s_active_context().pop().is_same_object(space.w_two) assert interp.s_active_context().stack() == [] def test_pushActiveContextBytecode(): interp = new_interpreter(pushActiveContextBytecode) - interp.step() + interp.step(interp.s_active_context()) assert interp.s_active_context().pop() == interp.w_active_context() assert interp.s_active_context().stack() == [] def test_duplicateTopBytecode(): interp = new_interpreter(pushConstantZeroBytecode + duplicateTopBytecode) - interp.step() - interp.step() + interp.step(interp.s_active_context()) + interp.step(interp.s_active_context()) assert interp.s_active_context().stack() == [space.w_zero, space.w_zero] def test_bytecodePrimBitAnd(): interp = new_interpreter(pushConstantOneBytecode + pushConstantTwoBytecode + bytecodePrimBitAnd) - interp.step() - interp.step() - interp.step() + interp.step(interp.s_active_context()) + interp.step(interp.s_active_context()) + interp.step(interp.s_active_context()) assert interp.s_active_context().pop().value == 0 assert interp.s_active_context().stack() == [] def test_bytecodePrimBitOr(): interp = new_interpreter(pushConstantOneBytecode + pushConstantTwoBytecode + bytecodePrimBitOr) - interp.step() - interp.step() - interp.step() + interp.step(interp.s_active_context()) + interp.step(interp.s_active_context()) + interp.step(interp.s_active_context()) assert interp.s_active_context().pop().value == 3 assert interp.s_active_context().stack() == [] def test_bytecodePrimBitShift(): interp = new_interpreter(pushConstantOneBytecode + pushConstantTwoBytecode + bytecodePrimBitShift) - interp.step() - interp.step() - interp.step() + interp.step(interp.s_active_context()) + interp.step(interp.s_active_context()) + interp.step(interp.s_active_context()) assert interp.s_active_context().pop().value == 4 assert interp.s_active_context().stack() == [] def test_bytecodePrimClass(): interp = new_interpreter(pushConstantOneBytecode + bytecodePrimClass) - interp.step() - interp.step() + interp.step(interp.s_active_context()) + interp.step(interp.s_active_context()) assert interp.s_active_context().pop() == space.w_SmallInteger assert interp.s_active_context().stack() == [] def test_bytecodePrimSubtract(): interp = new_interpreter(pushConstantOneBytecode + pushConstantTwoBytecode + bytecodePrimSubtract) - interp.step() - interp.step() - interp.step() + interp.step(interp.s_active_context()) + interp.step(interp.s_active_context()) + interp.step(interp.s_active_context()) assert interp.s_active_context().pop().value == -1 assert interp.s_active_context().stack() == [] def test_bytecodePrimMultiply(): interp = new_interpreter(pushConstantMinusOneBytecode + pushConstantTwoBytecode + bytecodePrimMultiply) - interp.step() - interp.step() - interp.step() + interp.step(interp.s_active_context()) + interp.step(interp.s_active_context()) + interp.step(interp.s_active_context()) assert interp.s_active_context().pop().value == -2 assert interp.s_active_context().stack() == [] def test_bytecodePrimDivide(): interp = new_interpreter(pushConstantTwoBytecode + pushConstantMinusOneBytecode + bytecodePrimDivide) - interp.step() - interp.step() - interp.step() + interp.step(interp.s_active_context()) + interp.step(interp.s_active_context()) + interp.step(interp.s_active_context()) assert interp.s_active_context().pop().value == -2 assert interp.s_active_context().stack() == [] def test_bytecodePrimDiv(): interp = new_interpreter(pushConstantTwoBytecode + pushConstantMinusOneBytecode + bytecodePrimDiv) - interp.step() - interp.step() - interp.step() + interp.step(interp.s_active_context()) + interp.step(interp.s_active_context()) + interp.step(interp.s_active_context()) assert interp.s_active_context().pop().value == -2 assert interp.s_active_context().stack() == [] def test_bytecodePrimMod(): interp = new_interpreter(pushConstantTwoBytecode + pushConstantMinusOneBytecode + bytecodePrimMod) - interp.step() - interp.step() - interp.step() + interp.step(interp.s_active_context()) + interp.step(interp.s_active_context()) + interp.step(interp.s_active_context()) assert interp.s_active_context().pop().value == 0 assert interp.s_active_context().stack() == [] def test_bytecodePrimEquivalent(): interp = new_interpreter(pushConstantTwoBytecode + pushConstantMinusOneBytecode + bytecodePrimEquivalent) - interp.step() - interp.step() - interp.step() + interp.step(interp.s_active_context()) + interp.step(interp.s_active_context()) + interp.step(interp.s_active_context()) assert interp.s_active_context().pop() == space.w_false assert interp.s_active_context().stack() == [] interp = new_interpreter(pushConstantOneBytecode + pushConstantOneBytecode + bytecodePrimEquivalent) - interp.step() - interp.step() - interp.step() + interp.step(interp.s_active_context()) + interp.step(interp.s_active_context()) + interp.step(interp.s_active_context()) assert interp.s_active_context().pop() == space.w_true assert interp.s_active_context().stack() == [] @@ -351,7 +351,8 @@ interp.s_active_context().push(w_fakeclass) run_with_faked_methods( [[w_fakeclassclass, primitives.NEW, 0, "new"]], - interp.step) + interp.step, + interp.s_active_context()) w_fakeinst = interp.s_active_context().pop() assert interp.s_active_context().stack() == [] assert w_fakeinst.getclass(space).is_same_object(w_fakeclass) @@ -366,7 +367,8 @@ interp.s_active_context().push(space.w_two) run_with_faked_methods( [[w_fakeclassclass, primitives.NEW_WITH_ARG, 1, "new:"]], - interp.step) + interp.step, + interp.s_active_context()) w_fakeinst = interp.s_active_context().pop() assert interp.s_active_context().stack() == [] assert w_fakeinst.getclass(space).is_same_object(w_fakeclass) @@ -379,7 +381,8 @@ interp.s_active_context().push(w_fakeinst) run_with_faked_methods( [[w_fakeclass, primitives.SIZE, 0, "size"]], - interp.step) + interp.step, + interp.s_active_context()) assert interp.s_active_context().pop().value == 5 assert interp.s_active_context().stack() == [] @@ -401,14 +404,14 @@ interp.w_active_context().as_methodcontext_get_shadow(space).w_method().literals = fakeliterals(space, "foo") interp.s_active_context().push(w_object) callerContext = interp.w_active_context() - interp.step() + interp.step(interp.s_active_context()) assert interp.s_active_context().w_sender() == callerContext assert interp.s_active_context().stack() == [] assert interp.w_active_context().as_methodcontext_get_shadow(space).w_receiver().is_same_object(w_object) assert interp.w_active_context().as_methodcontext_get_shadow(space).w_method().is_same_object(shadow.s_methoddict().methoddict["foo"]) assert callerContext.as_context_get_shadow(space).stack() == [] - interp.step() - interp.step() + interp.step(interp.s_active_context()) + interp.step(interp.s_active_context()) assert interp.w_active_context() == callerContext assert interp.s_active_context().stack() == [result] @@ -443,7 +446,7 @@ interp.s_active_context().push(space.wrap_int(50)) interp.s_active_context().push(space.wrap_int(8)) callerContext = interp.w_active_context() - interp.step() + interp.step(interp.s_active_context()) assert interp.w_active_context() is callerContext assert len(interp.s_active_context().stack()) == 1 w_result = interp.s_active_context().pop() @@ -458,9 +461,9 @@ interp = new_interpreter(pushConstantZeroBytecode + pushConstantOneBytecode + bytecodePrimMakePoint) - interp.step() - interp.step() - interp.step() + interp.step(interp.s_active_context()) + interp.step(interp.s_active_context()) + interp.step(interp.s_active_context()) w_point = interp.s_active_context().top() from spyvm.wrapper import PointWrapper point = PointWrapper(interp.space, w_point) @@ -471,55 +474,55 @@ interp = new_interpreter(longJumpIfTrue(0) + chr(15) + longJumpIfTrue(0) + chr(15)) interp.s_active_context().push(space.w_false) pc = interp.s_active_context().pc() + 2 - interp.step() + interp.step(interp.s_active_context()) assert interp.s_active_context().pc() == pc interp.s_active_context().push(space.w_true) pc = interp.s_active_context().pc() + 2 - interp.step() + interp.step(interp.s_active_context()) assert interp.s_active_context().pc() == pc + 15 def test_longJumpIfFalse(): interp = new_interpreter(pushConstantTrueBytecode + longJumpIfFalse(0) + chr(15) + pushConstantFalseBytecode + longJumpIfFalse(0) + chr(15)) - interp.step() + interp.step(interp.s_active_context()) pc = interp.s_active_context().pc() + 2 - interp.step() + interp.step(interp.s_active_context()) assert interp.s_active_context().pc() == pc - interp.step() + interp.step(interp.s_active_context()) pc = interp.s_active_context().pc() + 2 - interp.step() + interp.step(interp.s_active_context()) assert interp.s_active_context().pc() == pc + 15 def test_longUnconditionalJump(): interp = new_interpreter(longUnconditionalJump(4) + chr(15)) pc = interp.s_active_context().pc() + 2 - interp.step() + interp.step(interp.s_active_context()) assert interp.s_active_context().pc() == pc + 15 def test_shortUnconditionalJump(): interp = new_interpreter(chr(145)) pc = interp.s_active_context().pc() + 1 - interp.step() + interp.step(interp.s_active_context()) assert interp.s_active_context().pc() == pc + 2 def test_shortConditionalJump(): interp = new_interpreter(pushConstantTrueBytecode + shortConditionalJump(3) + pushConstantFalseBytecode + shortConditionalJump(3)) - interp.step() + interp.step(interp.s_active_context()) pc = interp.s_active_context().pc() + 1 - interp.step() + interp.step(interp.s_active_context()) assert interp.s_active_context().pc() == pc - interp.step() + interp.step(interp.s_active_context()) pc = interp.s_active_context().pc() + 1 - interp.step() + interp.step(interp.s_active_context()) assert interp.s_active_context().pc() == pc + 4 def test_popStackBytecode(): interp = new_interpreter(pushConstantTrueBytecode + popStackBytecode) - interp.step() + interp.step(interp.s_active_context()) assert interp.s_active_context().stack() == [space.w_true] - interp.step() + interp.step(interp.s_active_context()) assert interp.s_active_context().stack() == [] def test_extendedPushBytecode(): @@ -543,8 +546,8 @@ w_association.store(space, 1, "myvalue") interp = new_interpreter(pushConstantOneBytecode + bytecode) interp.w_active_context().as_methodcontext_get_shadow(space).w_method().literals = fakeliterals(space, w_association) - interp.step() - interp.step() + interp.step(interp.s_active_context()) + interp.step(interp.s_active_context()) assert w_association.fetch(space, 1).is_same_object(space.w_one) def test_extendedStoreAndPopBytecode(): @@ -570,7 +573,7 @@ w_object = shadow.new() interp.s_active_context().push(w_object) interp.s_active_context().push(space.w_one) - interp.step() + interp.step(interp.s_active_context()) assert interp.w_active_context().as_methodcontext_get_shadow(space).w_method() == shadow.s_methoddict().methoddict["+"] assert interp.s_active_context().w_receiver() is w_object assert interp.w_active_context().as_methodcontext_get_shadow(space).gettemp(0).is_same_object(space.w_one) @@ -586,7 +589,7 @@ for i in range(6): interp.s_active_context().push(space.w_one) interp.s_active_context().push(space.w_two) - interp.step() + interp.step(interp.s_active_context()) assert interp.s_active_context().stack() == [space.w_true, space.w_false, space.w_true, space.w_false, space.w_false, space.w_true] @@ -618,11 +621,11 @@ interp = new_interpreter(bytecodes) interp.w_active_context().as_methodcontext_get_shadow(space).w_method().literals = fakeliterals(space, "foo") interp.s_active_context().push(w_object) - interp.step() + interp.step(interp.s_active_context()) for w_specificclass in [w_super, w_supersuper]: callerContext = interp.w_active_context() - interp.step() - interp.step() + interp.step(interp.s_active_context()) + interp.step(interp.s_active_context()) assert interp.s_active_context().w_sender() == callerContext assert interp.s_active_context().stack() == [] assert interp.w_active_context().as_methodcontext_get_shadow(space).w_receiver() == w_object diff --git a/spyvm/test/test_miniimage.py b/spyvm/test/test_miniimage.py --- a/spyvm/test/test_miniimage.py +++ b/spyvm/test/test_miniimage.py @@ -197,7 +197,7 @@ while True: try: - interp.step() + interp.step(interp.s_active_context()) except interpreter.ReturnFromTopLevel, e: assert e.object.value == abs(int) return @@ -289,7 +289,7 @@ interp.store_w_active_context(w_frame) while True: try: - interp.step() + interp.step(interp.s_active_context()) #print interp.s_active_context.stack except interpreter.ReturnFromTopLevel, e: return e.object @@ -313,10 +313,10 @@ interp.store_w_active_context(s_ctx.w_self()) assert isinstance(s_ctx, shadow.MethodContextShadow) assert interp.s_active_context().top().is_same_object(space.w_true) - interp.step() - interp.step() + interp.step(interp.s_active_context()) + interp.step(interp.s_active_context()) assert interp.s_active_context().top().value == 1 - interp.step() + interp.step(interp.s_active_context()) assert interp.s_active_context().top().value == 2 - interp.step() + interp.step(interp.s_active_context()) assert interp.s_active_context().top().value == 3 From noreply at buildbot.pypy.org Fri Feb 15 14:09:59 2013 From: noreply at buildbot.pypy.org (stepahn) Date: Fri, 15 Feb 2013 14:09:59 +0100 (CET) Subject: [pypy-commit] lang-js default: unified new_map Message-ID: <20130215130959.B31CE1C062C@cobra.cs.uni-duesseldorf.de> Author: Stephan Branch: Changeset: r350:9f8d4517536f Date: 2013-02-06 17:49 +0100 http://bitbucket.org/pypy/lang-js/changeset/9f8d4517536f/ Log: unified new_map diff --git a/js/environment_record.py b/js/environment_record.py --- a/js/environment_record.py +++ b/js/environment_record.py @@ -1,8 +1,4 @@ -from js.object_map import ROOT_MAP - - -def _new_map(): - return ROOT_MAP +from js.object_map import new_map class EnvironmentRecord(object): @@ -33,11 +29,11 @@ def __init__(self, size=0, resize=True): EnvironmentRecord.__init__(self) - self._binding_map_ = _new_map() + self._binding_map_ = new_map() self._binding_slots_ = [None] * size self._binding_resize_ = resize - self._mutable_bindings_map_ = _new_map() - self._deletable_bindings_map_ = _new_map() + self._mutable_bindings_map_ = new_map() + self._deletable_bindings_map_ = new_map() def _is_mutable_binding(self, identifier): return self._mutable_bindings_map_.contains(identifier) diff --git a/js/jsobj.py b/js/jsobj.py --- a/js/jsobj.py +++ b/js/jsobj.py @@ -8,11 +8,7 @@ from js.property_descriptor import PropertyDescriptor, DataPropertyDescriptor, AccessorPropertyDescriptor, is_data_descriptor, is_generic_descriptor, is_accessor_descriptor from js.property import DataProperty, AccessorProperty -from js.object_map import ROOT_MAP - - -def _new_map(): - return ROOT_MAP +from js.object_map import new_map @jit.elidable @@ -183,7 +179,7 @@ def __init__(self): from js.object_space import newnull - self._property_map_ = _new_map() + self._property_map_ = new_map() self._property_slots_ = [] self._prototype_ = newnull() @@ -921,7 +917,7 @@ from js.object_space import object_space _map = object_space.new_obj() - mapped_names = _new_map() + mapped_names = new_map() indx = _len - 1 while indx >= 0: val = args[indx] diff --git a/js/object_map.py b/js/object_map.py --- a/js/object_map.py +++ b/js/object_map.py @@ -97,5 +97,5 @@ ROOT_MAP = MapRoot() -def root_map(): +def new_map(): return ROOT_MAP From noreply at buildbot.pypy.org Fri Feb 15 14:10:01 2013 From: noreply at buildbot.pypy.org (stepahn) Date: Fri, 15 Feb 2013 14:10:01 +0100 (CET) Subject: [pypy-commit] lang-js default: moved SymbolMap into separate file Message-ID: <20130215131001.0B7071C062C@cobra.cs.uni-duesseldorf.de> Author: Stephan Branch: Changeset: r351:d1a5abd654d6 Date: 2013-02-15 14:08 +0100 http://bitbucket.org/pypy/lang-js/changeset/d1a5abd654d6/ Log: moved SymbolMap into separate file diff --git a/js/astbuilder.py b/js/astbuilder.py --- a/js/astbuilder.py +++ b/js/astbuilder.py @@ -4,59 +4,7 @@ from js import operations - -class SymbolMap(object): - def __init__(self): - self.symbols = {} - self.functions = [] - self.variables = [] - self.parameters = [] - self.next_index = 0 - - def add_symbol(self, identifyer): - #assert isinstance(identifyer, unicode) - if identifyer not in self.symbols: - self.symbols[identifyer] = self.next_index - self.next_index += 1 - idx = self.symbols[identifyer] - assert isinstance(idx, int) - return idx - - def add_variable(self, identifyer): - idx = self.add_symbol(identifyer) - - self.variables.append(identifyer) - return idx - - def add_function(self, identifyer): - idx = self.add_symbol(identifyer) - - self.functions.append(identifyer) - return idx - - def add_parameter(self, identifyer): - #assert isinstance(identifyer, unicode) - f = unicode(identifyer) - #assert isinstance(f, unicode) - idx = self.add_symbol(f) - self.parameters.append(f) - return idx - - def get_index(self, identifyer): - return self.symbols[identifyer] - - def get_symbols(self): - return self.symbols.keys() - - def get_symbol(self, index): - for symbol, idx in self.symbols.items(): - if idx == index: - return symbol - - def len(self): - return self.next_index - -empty_symbols = SymbolMap() +from js.symbol_map import SymbolMap class FakeParseError(Exception): diff --git a/js/jscode.py b/js/jscode.py --- a/js/jscode.py +++ b/js/jscode.py @@ -5,7 +5,6 @@ from js.exception import JsThrowException from js.opcodes import opcodes, LABEL, BaseJump from js.jsobj import W_String -from js.astbuilder import empty_symbols def get_printable_location(pc, debug, jscode): @@ -28,6 +27,9 @@ class AlreadyRun(Exception): pass +from js.symbol_map import SymbolMap +empty_symbols = SymbolMap() + class JsCode(object): _immutable_fields_ = ['compiled_opcodes[*]', '_symbols', 'parameters[*]'] diff --git a/js/object_map.py b/js/object_map.py --- a/js/object_map.py +++ b/js/object_map.py @@ -43,8 +43,9 @@ def empty(self): return True + @jit.elidable def len(self): - return self.index + return self.index + 1 @jit.elidable def add(self, name): diff --git a/js/symbol_map.py b/js/symbol_map.py new file mode 100644 --- /dev/null +++ b/js/symbol_map.py @@ -0,0 +1,49 @@ +from js.object_map import new_map + + +class SymbolMap(object): + def __init__(self): + self.symbols = new_map() + self.functions = [] + self.variables = [] + self.parameters = [] + self.next_index = 0 + + def add_symbol(self, identifyer): + idx = self.symbols.lookup(identifyer) + + if idx == self.symbols.NOT_FOUND: + self.symbols = self.symbols.add(identifyer) + idx = self.symbols.lookup(identifyer) + + assert isinstance(idx, int) + return idx + + def add_variable(self, identifyer): + idx = self.add_symbol(identifyer) + + self.variables.append(identifyer) + return idx + + def add_function(self, identifyer): + idx = self.add_symbol(identifyer) + + self.functions.append(identifyer) + return idx + + def add_parameter(self, identifyer): + #assert isinstance(identifyer, unicode) + f = unicode(identifyer) + #assert isinstance(f, unicode) + idx = self.add_symbol(f) + self.parameters.append(f) + return idx + + def get_index(self, identifyer): + return self.symbols.lookup(identifyer) + + def get_symbols(self): + return self.symbols.keys() + + def len(self): + return self.symbols.len() From noreply at buildbot.pypy.org Fri Feb 15 14:10:02 2013 From: noreply at buildbot.pypy.org (stepahn) Date: Fri, 15 Feb 2013 14:10:02 +0100 (CET) Subject: [pypy-commit] lang-js default: more jit view tests Message-ID: <20130215131002.3DACD1C062C@cobra.cs.uni-duesseldorf.de> Author: Stephan Branch: Changeset: r352:723ba8f60958 Date: 2013-02-15 14:09 +0100 http://bitbucket.org/pypy/lang-js/changeset/723ba8f60958/ Log: more jit view tests diff --git a/test/jit_view.py b/test/jit_view.py --- a/test/jit_view.py +++ b/test/jit_view.py @@ -106,6 +106,22 @@ self.run(code, 100) + def test_func_call_multiple_args(self): + code = """ + (function () { + var i = 0; + function f(a, b) { + return a + b; + } + while(i < 100) { + i = f(i, 1); + } + return i; + })(); + """ + + self.run(code, 100) + def test_double_func_call_in_loop(self): code = """ (function () { @@ -222,3 +238,18 @@ """ self.run(code, 1) + + def test_str_concat(self): + code = """ + (function () { + var i = 0; + var j = ''; + while(i < 10) { + i += 1; + j += 'a'; + } + return j; + })(); + """ + + self.run(code, 'aaaaaaaaaa') From noreply at buildbot.pypy.org Fri Feb 15 14:10:03 2013 From: noreply at buildbot.pypy.org (stepahn) Date: Fri, 15 Feb 2013 14:10:03 +0100 (CET) Subject: [pypy-commit] lang-js default: removed dead code and fixed whitespaces Message-ID: <20130215131003.51FA71C062C@cobra.cs.uni-duesseldorf.de> Author: Stephan Branch: Changeset: r353:6993c1e37591 Date: 2013-02-15 14:09 +0100 http://bitbucket.org/pypy/lang-js/changeset/6993c1e37591/ Log: removed dead code and fixed whitespaces diff --git a/js/astbuilder.py b/js/astbuilder.py --- a/js/astbuilder.py +++ b/js/astbuilder.py @@ -356,12 +356,6 @@ parameters, i = self.get_next_expr(node, i) functionbody, i = self.get_next_expr(node, i) - #params = [] - #if parameters is not None: - # params = [pident.get_literal() for pident in parameters.nodes] - - #params = self.current_scope_parameters() - if identifier is not None: funcname = identifier.get_literal() else: diff --git a/js/environment_record.py b/js/environment_record.py --- a/js/environment_record.py +++ b/js/environment_record.py @@ -83,7 +83,7 @@ i = (idx + 1) assert i >= 0 - self._binding_slots_ = self._binding_slots_[:idx] + self._binding_slots_[i:] #len(self._binding_slots_)] + self._binding_slots_ = self._binding_slots_[:idx] + self._binding_slots_[i:] # len(self._binding_slots_)] self._binding_map_ = self._binding_map_.delete(name) # 10.2.1.1.2 diff --git a/js/execution_context.py b/js/execution_context.py --- a/js/execution_context.py +++ b/js/execution_context.py @@ -70,7 +70,7 @@ # 4. if code.is_function_code(): - names = code.params() #_formal_parameters_ + names = code.params() n = 0 args = self._argument_values_ @@ -104,7 +104,7 @@ # TODO get calling W_Function func = self._w_func_ arguments = self._argument_values_ - names = code.params() #_formal_parameters_ + names = code.params() args_obj = W_Arguments(func, names, arguments, env, strict) if strict is True: diff --git a/js/jscode.py b/js/jscode.py --- a/js/jscode.py +++ b/js/jscode.py @@ -60,9 +60,6 @@ def symbols(self): return self._symbols.get_symbols() - def symbol_for_index(self, index): - return self._symbols.get_symbol(index) - @jit.unroll_safe def params(self): return [p for p in self.parameters] From noreply at buildbot.pypy.org Fri Feb 15 14:22:59 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Fri, 15 Feb 2013 14:22:59 +0100 (CET) Subject: [pypy-commit] pypy default: add a couple numpypy tests that currently fail Message-ID: <20130215132259.1B0901C0673@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61255:76d38fa4395b Date: 2013-02-15 08:21 -0500 http://bitbucket.org/pypy/pypy/changeset/76d38fa4395b/ Log: add a couple numpypy tests that currently fail diff --git a/pypy/module/micronumpy/test/test_module.py b/pypy/module/micronumpy/test/test_module.py --- a/pypy/module/micronumpy/test/test_module.py +++ b/pypy/module/micronumpy/test/test_module.py @@ -13,11 +13,13 @@ assert sum(array(range(10))) == 45 def test_min(self): - from _numpypy import array, min + from _numpypy import array, min, zeros assert min(range(10)) == 0 assert min(array(range(10))) == 0 + assert list(min(zeros((0, 2)), axis=1)) == [] def test_max(self): - from _numpypy import array, max + from _numpypy import array, max, zeros assert max(range(10)) == 9 assert max(array(range(10))) == 9 + assert list(max(zeros((0, 2)), axis=1)) == [] diff --git a/pypy/module/test_lib_pypy/numpypy/core/test_fromnumeric.py b/pypy/module/test_lib_pypy/numpypy/core/test_fromnumeric.py --- a/pypy/module/test_lib_pypy/numpypy/core/test_fromnumeric.py +++ b/pypy/module/test_lib_pypy/numpypy/core/test_fromnumeric.py @@ -127,7 +127,7 @@ assert reshape(a, (1, -1)).shape == (1, 105) assert reshape(a, (1, 1, -1)).shape == (1, 1, 105) assert reshape(a, (-1, 1, 1)).shape == (105, 1, 1) - + def test_transpose(self): from numpypy import arange, array, transpose, ones x = arange(4).reshape((2,2)) @@ -136,7 +136,7 @@ raises(NotImplementedError, "transpose(x, axes=(1, 0, 2))") # x = ones((1, 2, 3)) # assert transpose(x, (1, 0, 2)).shape == (2, 1, 3) - + def test_fromnumeric(self): from numpypy import array, swapaxes x = array([[1,2,3]]) diff --git a/pypy/module/test_lib_pypy/numpypy/test_numpy.py b/pypy/module/test_lib_pypy/numpypy/test_numpy.py --- a/pypy/module/test_lib_pypy/numpypy/test_numpy.py +++ b/pypy/module/test_lib_pypy/numpypy/test_numpy.py @@ -8,3 +8,11 @@ pass import numpypy import numpy # works after 'numpypy' has been imported + + def test_min_max_after_import(self): + from numpypy import * + assert min(1, 100) == 1 + assert min(100, 1) == 1 + + assert max(1, 100) == 100 + assert max(100, 1) == 100 diff --git a/rpython/rlib/rstruct/runpack.py b/rpython/rlib/rstruct/runpack.py --- a/rpython/rlib/rstruct/runpack.py +++ b/rpython/rlib/rstruct/runpack.py @@ -46,7 +46,7 @@ def __init__(self, fmt): self.formats = [] self.fmt = fmt - + def operate(self, fmtdesc, repetitions): if fmtdesc.needcount: self.formats.append((fmtdesc, repetitions, None)) @@ -110,5 +110,3 @@ unpacker = create_unpacker(fmt) return unpacker.unpack(input) runpack._annspecialcase_ = 'specialize:arg(0)' - - From noreply at buildbot.pypy.org Fri Feb 15 14:57:20 2013 From: noreply at buildbot.pypy.org (bivab) Date: Fri, 15 Feb 2013 14:57:20 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: rename _{arm, x86}_loop_code variable to _ll_loop_code Message-ID: <20130215135720.2D3AB1C00A8@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: jitframe-on-heap Changeset: r61256:28c020a9f122 Date: 2013-02-15 14:44 +0100 http://bitbucket.org/pypy/pypy/changeset/28c020a9f122/ Log: rename _{arm,x86}_loop_code variable to _ll_loop_code diff --git a/rpython/jit/backend/arm/assembler.py b/rpython/jit/backend/arm/assembler.py --- a/rpython/jit/backend/arm/assembler.py +++ b/rpython/jit/backend/arm/assembler.py @@ -602,7 +602,7 @@ clt.allgcrefs) loop_head = self.mc.get_relative_pos() - looptoken._arm_loop_code = loop_head + looptoken._ll_loop_code = loop_head # frame_depth_no_fixed_size = self._assemble(regalloc, inputargs, operations) self.update_frame_depth(frame_depth_no_fixed_size + JITFRAME_FIXED_SIZE) @@ -815,7 +815,7 @@ def fixup_target_tokens(self, rawstart): for targettoken in self.target_tokens_currently_compiling: - targettoken._arm_loop_code += rawstart + targettoken._ll_loop_code += rawstart self.target_tokens_currently_compiling = None def _patch_stackadjust(self, adr, allocated_depth): diff --git a/rpython/jit/backend/arm/opassembler.py b/rpython/jit/backend/arm/opassembler.py --- a/rpython/jit/backend/arm/opassembler.py +++ b/rpython/jit/backend/arm/opassembler.py @@ -306,7 +306,7 @@ # stack locations both before and after the jump. # target_token = op.getdescr() - target = target_token._arm_loop_code + target = target_token._ll_loop_code assert isinstance(target_token, TargetToken) assert fcond == c.AL my_nbargs = self.current_clt._debug_nbargs diff --git a/rpython/jit/backend/arm/regalloc.py b/rpython/jit/backend/arm/regalloc.py --- a/rpython/jit/backend/arm/regalloc.py +++ b/rpython/jit/backend/arm/regalloc.py @@ -34,9 +34,9 @@ from rpython.jit.backend.llsupport.descr import unpack_interiorfielddescr -# xxx hack: set a default value for TargetToken._arm_loop_code. If 0, we know +# xxx hack: set a default value for TargetToken._ll_loop_code. If 0, we know # that it is a LABEL that was not compiled yet. -TargetToken._arm_loop_code = 0 +TargetToken._ll_loop_code = 0 class TempInt(TempBox): type = INT @@ -725,7 +725,7 @@ self.final_jump_op = op descr = op.getdescr() assert isinstance(descr, TargetToken) - if descr._arm_loop_code != 0: + if descr._ll_loop_code != 0: # if the target LABEL was already compiled, i.e. if it belongs # to some already-compiled piece of code self._compute_hint_frame_locations_from_descr(descr) @@ -1082,7 +1082,7 @@ self.frame_manager.mark_as_free(arg) # descr._arm_arglocs = arglocs - descr._arm_loop_code = self.assembler.mc.currpos() + descr._ll_loop_code = self.assembler.mc.currpos() descr._arm_clt = self.assembler.current_clt self.assembler.target_tokens_currently_compiling[descr] = None self.possibly_free_vars_for_op(op) diff --git a/rpython/jit/backend/arm/test/test_regalloc.py b/rpython/jit/backend/arm/test/test_regalloc.py --- a/rpython/jit/backend/arm/test/test_regalloc.py +++ b/rpython/jit/backend/arm/test/test_regalloc.py @@ -121,8 +121,8 @@ fdescr3 = BasicFailDescr(3) def setup_method(self, meth): - self.targettoken._arm_loop_code = 0 - self.targettoken2._arm_loop_code = 0 + self.targettoken._ll_loop_code = 0 + self.targettoken2._ll_loop_code = 0 def f1(x): return x + 1 diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -473,7 +473,7 @@ def assemble_loop(self, loopname, inputargs, operations, looptoken, log): '''adds the following attributes to looptoken: _ll_function_addr (address of the generated func, as an int) - _x86_loop_code (debug: addr of the start of the ResOps) + _ll_loop_code (debug: addr of the start of the ResOps) _x86_fullsize (debug: full size including failure) _x86_debug_checksum ''' @@ -515,7 +515,7 @@ full_size = self.mc.get_relative_pos() # rawstart = self.materialize_loop(looptoken) - looptoken._x86_loop_code = looppos + rawstart + looptoken._ll_loop_code = looppos + rawstart debug_start("jit-backend-addr") debug_print("Loop %d (%s) has address %x to %x (bootstrap %x)" % ( looptoken.number, loopname, @@ -733,7 +733,7 @@ def fixup_target_tokens(self, rawstart): for targettoken in self.target_tokens_currently_compiling: - targettoken._x86_loop_code += rawstart + targettoken._ll_loop_code += rawstart self.target_tokens_currently_compiling = None def _append_debugging_code(self, operations, tp, number, token): @@ -2434,7 +2434,7 @@ expected_size=expected_size) def closing_jump(self, target_token): - target = target_token._x86_loop_code + target = target_token._ll_loop_code if target_token in self.target_tokens_currently_compiling: curpos = self.mc.get_relative_pos() + 5 self.mc.JMP_l(target - curpos) diff --git a/rpython/jit/backend/x86/regalloc.py b/rpython/jit/backend/x86/regalloc.py --- a/rpython/jit/backend/x86/regalloc.py +++ b/rpython/jit/backend/x86/regalloc.py @@ -1186,7 +1186,7 @@ self.final_jump_op = op descr = op.getdescr() assert isinstance(descr, TargetToken) - if descr._x86_loop_code != 0: + if descr._ll_loop_code != 0: # if the target LABEL was already compiled, i.e. if it belongs # to some already-compiled piece of code self._compute_hint_frame_locations_from_descr(descr) @@ -1298,7 +1298,7 @@ self.flush_loop() # descr._x86_arglocs = arglocs - descr._x86_loop_code = self.assembler.mc.get_relative_pos() + descr._ll_loop_code = self.assembler.mc.get_relative_pos() descr._x86_clt = self.assembler.current_clt self.assembler.target_tokens_currently_compiling[descr] = None self.possibly_free_vars_for_op(op) @@ -1364,6 +1364,6 @@ os.write(2, '[x86/regalloc] %s\n' % msg) raise NotImplementedError(msg) -# xxx hack: set a default value for TargetToken._x86_loop_code. +# xxx hack: set a default value for TargetToken._ll_loop_code. # If 0, we know that it is a LABEL that was not compiled yet. -TargetToken._x86_loop_code = 0 +TargetToken._ll_loop_code = 0 diff --git a/rpython/jit/backend/x86/test/test_regalloc.py b/rpython/jit/backend/x86/test/test_regalloc.py --- a/rpython/jit/backend/x86/test/test_regalloc.py +++ b/rpython/jit/backend/x86/test/test_regalloc.py @@ -115,8 +115,8 @@ fdescr3 = BasicFailDescr(3) def setup_method(self, meth): - self.targettoken._x86_loop_code = 0 - self.targettoken2._x86_loop_code = 0 + self.targettoken._ll_loop_code = 0 + self.targettoken2._ll_loop_code = 0 def f1(x): return x+1 diff --git a/rpython/jit/backend/x86/test/test_runner.py b/rpython/jit/backend/x86/test/test_runner.py --- a/rpython/jit/backend/x86/test/test_runner.py +++ b/rpython/jit/backend/x86/test/test_runner.py @@ -380,7 +380,7 @@ self.cpu.compile_loop(inputargs, operations, looptoken) name, loopaddress, loopsize = agent.functions[0] assert name == "Loop # 17: hello (loop counter 0)" - assert loopaddress <= looptoken._x86_loop_code + assert loopaddress <= looptoken._ll_loop_code assert loopsize >= 40 # randomish number i1b = BoxInt() From noreply at buildbot.pypy.org Fri Feb 15 14:57:21 2013 From: noreply at buildbot.pypy.org (bivab) Date: Fri, 15 Feb 2013 14:57:21 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: remove unused code and update x86 backend specific pieces in test_regalloc Message-ID: <20130215135721.56A5C1C00A8@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: jitframe-on-heap Changeset: r61257:83a73c5daab1 Date: 2013-02-15 14:47 +0100 http://bitbucket.org/pypy/pypy/changeset/83a73c5daab1/ Log: remove unused code and update x86 backend specific pieces in test_regalloc diff --git a/rpython/jit/backend/x86/test/test_regalloc.py b/rpython/jit/backend/x86/test/test_regalloc.py --- a/rpython/jit/backend/x86/test/test_regalloc.py +++ b/rpython/jit/backend/x86/test/test_regalloc.py @@ -8,77 +8,19 @@ from rpython.jit.metainterp.resoperation import rop, ResOperation from rpython.jit.backend.llsupport.descr import GcCache from rpython.jit.backend.detect_cpu import getcpuclass -from rpython.jit.backend.x86.regalloc import RegAlloc, X86RegisterManager,\ - is_comparison_or_ovf_op -from rpython.jit.backend.x86.arch import IS_X86_32, IS_X86_64 +from rpython.jit.backend.llsupport.regalloc import is_comparison_or_ovf_op from rpython.jit.tool.oparser import parse from rpython.rtyper.lltypesystem import lltype, llmemory, rffi from rpython.rtyper.annlowlevel import llhelper from rpython.rtyper.lltypesystem import rclass, rstr from rpython.jit.codewriter import longlong from rpython.jit.codewriter.effectinfo import EffectInfo -from rpython.jit.backend.x86.rx86 import * def test_is_comparison_or_ovf_op(): assert not is_comparison_or_ovf_op(rop.INT_ADD) assert is_comparison_or_ovf_op(rop.INT_ADD_OVF) assert is_comparison_or_ovf_op(rop.INT_EQ) -CPU = getcpuclass() -class MockGcDescr(GcCache): - def get_funcptr_for_new(self): - return 123 - get_funcptr_for_newarray = get_funcptr_for_new - get_funcptr_for_newstr = get_funcptr_for_new - get_funcptr_for_newunicode = get_funcptr_for_new - - def rewrite_assembler(self, cpu, operations): - pass - -class MockAssembler(object): - gcrefs = None - _float_constants = None - - def __init__(self, cpu=None, gc_ll_descr=None): - self.movs = [] - self.performs = [] - self.lea = [] - if cpu is None: - cpu = CPU(None, None) - cpu.setup_once() - self.cpu = cpu - if gc_ll_descr is None: - gc_ll_descr = MockGcDescr(False) - self.cpu.gc_ll_descr = gc_ll_descr - - def dump(self, *args): - pass - - def regalloc_mov(self, from_loc, to_loc): - self.movs.append((from_loc, to_loc)) - - def regalloc_perform(self, op, arglocs, resloc): - self.performs.append((op, arglocs, resloc)) - - def regalloc_perform_discard(self, op, arglocs): - self.performs.append((op, arglocs)) - - def load_effective_addr(self, *args): - self.lea.append(args) - -def fill_regs(regalloc, cls=BoxInt): - allboxes = [] - for reg in X86RegisterManager.all_regs: - box = cls() - allboxes.append(box) - regalloc.rm.try_allocate_reg() - return allboxes - -class RegAllocForTests(RegAlloc): - position = 0 - def _compute_next_usage(self, v, _): - return -1 - def get_zero_division_error(self): # for tests, a random emulated ll_inst will do @@ -91,6 +33,7 @@ return zer_vtable, zer_inst +CPU = getcpuclass() class BaseTestRegalloc(object): cpu = CPU(None, None) cpu.setup_once() @@ -172,7 +115,7 @@ def prepare_loop(self, ops): loop = self.parse(ops) - regalloc = RegAlloc(self.cpu.assembler, False) + regalloc = self.cpu.build_regalloc() regalloc.prepare_loop(loop.inputargs, loop.operations, loop.original_jitcell_token, []) return regalloc @@ -630,10 +573,10 @@ def expected_frame_depth(self, num_call_args, num_pushed_input_args=0): # Assumes the arguments are all non-float - if IS_X86_32: + if not self.cpu.IS_64_BIT: extra_esp = num_call_args return extra_esp - elif IS_X86_64: + elif self.cpu.IS_64_BIT: # 'num_pushed_input_args' is for X86_64 only extra_esp = max(num_call_args - 6, 0) return num_pushed_input_args + extra_esp From noreply at buildbot.pypy.org Fri Feb 15 14:57:22 2013 From: noreply at buildbot.pypy.org (bivab) Date: Fri, 15 Feb 2013 14:57:22 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: add helper method to create RegAlloc instances in tests Message-ID: <20130215135722.8FDA11C00A8@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: jitframe-on-heap Changeset: r61258:e2ca8ffabbd1 Date: 2013-02-15 14:49 +0100 http://bitbucket.org/pypy/pypy/changeset/e2ca8ffabbd1/ Log: add helper method to create RegAlloc instances in tests diff --git a/rpython/jit/backend/x86/runner.py b/rpython/jit/backend/x86/runner.py --- a/rpython/jit/backend/x86/runner.py +++ b/rpython/jit/backend/x86/runner.py @@ -57,6 +57,12 @@ def setup(self): self.assembler = Assembler386(self, self.translate_support_code) + def build_regalloc(self): + ''' for tests''' + from rpython.jit.backend.x86.regalloc import RegAlloc + assert self.assembler is not None + return RegAlloc(self.assembler, False) + def setup_once(self): self.profile_agent.startup() self.assembler.setup_once() From noreply at buildbot.pypy.org Fri Feb 15 14:57:23 2013 From: noreply at buildbot.pypy.org (bivab) Date: Fri, 15 Feb 2013 14:57:23 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: move x86/test_regalloc.py -> llsupport/test_regalloc_integration.py Message-ID: <20130215135723.BA0C91C00A8@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: jitframe-on-heap Changeset: r61259:ca3a3a1f4850 Date: 2013-02-15 14:50 +0100 http://bitbucket.org/pypy/pypy/changeset/ca3a3a1f4850/ Log: move x86/test_regalloc.py -> llsupport/test_regalloc_integration.py diff --git a/rpython/jit/backend/x86/test/test_regalloc.py b/rpython/jit/backend/llsupport/test/test_regalloc_integration.py rename from rpython/jit/backend/x86/test/test_regalloc.py rename to rpython/jit/backend/llsupport/test/test_regalloc_integration.py From noreply at buildbot.pypy.org Fri Feb 15 14:57:24 2013 From: noreply at buildbot.pypy.org (bivab) Date: Fri, 15 Feb 2013 14:57:24 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: update backend specific code in x86/test_gc_integration.py Message-ID: <20130215135724.E6ACA1C00A8@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: jitframe-on-heap Changeset: r61260:67b81bdaf158 Date: 2013-02-15 14:51 +0100 http://bitbucket.org/pypy/pypy/changeset/67b81bdaf158/ Log: update backend specific code in x86/test_gc_integration.py diff --git a/rpython/jit/backend/x86/test/test_gc_integration.py b/rpython/jit/backend/x86/test/test_gc_integration.py --- a/rpython/jit/backend/x86/test/test_gc_integration.py +++ b/rpython/jit/backend/x86/test/test_gc_integration.py @@ -7,12 +7,12 @@ from rpython.jit.backend.llsupport.gc import GcLLDescription, GcLLDescr_boehm,\ GcLLDescr_framework, GcCache, JitFrameDescrs from rpython.jit.backend.detect_cpu import getcpuclass -from rpython.jit.backend.x86.arch import WORD, JITFRAME_FIXED_SIZE, IS_X86_64 +from rpython.jit.backend.llsupport.symbolic import WORD from rpython.jit.backend.llsupport import jitframe from rpython.rtyper.lltypesystem import lltype, llmemory, rffi from rpython.rtyper.annlowlevel import llhelper, llhelper_args -from rpython.jit.backend.x86.test.test_regalloc import BaseTestRegalloc +from rpython.jit.backend.llsupport.test.test_regalloc_integration import BaseTestRegalloc from rpython.jit.codewriter.effectinfo import EffectInfo from rpython.rlib.objectmodel import invoke_around_extcall @@ -71,7 +71,7 @@ # the gcmap should contain three things, p0, p1 and p3 # p3 stays in a register # while p0 and p1 are on the frame - if IS_X86_64: + if self.cpu.IS_64_BIT: nos = [11, 12, 31] else: nos = [4, 5, 25] @@ -233,7 +233,7 @@ def test_malloc_slowpath(self): def check(frame): assert len(frame.jf_gcmap) == 1 - if IS_X86_64: + if self.cpu.IS_64_BIT: assert frame.jf_gcmap[0] == (1<<29) | (1 << 30) else: assert frame.jf_gcmap[0] == (1<<24) | (1 << 23) @@ -263,7 +263,7 @@ def test_save_regs_around_malloc(self): def check(frame): x = frame.jf_gcmap - if IS_X86_64: + if self.cpu.IS_64_BIT: assert len(x) == 1 assert (bin(x[0]).count('1') == '0b1111100000000000000001111111011110'.count('1')) @@ -522,12 +522,12 @@ def check(i): assert cpu.gc_ll_descr.gcrootmap.stack[0] == i frame = rffi.cast(JITFRAMEPTR, i) - assert len(frame.jf_frame) == JITFRAME_FIXED_SIZE + 4 + assert len(frame.jf_frame) == self.cpu.JITFRAME_FIXED_SIZE + 4 # we "collect" frames.append(frame) new_frame = JITFRAME.allocate(frame.jf_frame_info) gcmap = unpack_gcmap(frame) - if IS_X86_64: + if self.cpu.IS_64_BIT: assert gcmap == [28, 29, 30] else: assert gcmap == [22, 23, 24] @@ -575,7 +575,7 @@ frame = lltype.cast_opaque_ptr(JITFRAMEPTR, frame) gcmap = unpack_gcmap(lltype.cast_opaque_ptr(JITFRAMEPTR, frame)) assert len(gcmap) == 1 - assert gcmap[0] < JITFRAME_FIXED_SIZE + assert gcmap[0] < self.cpu.JITFRAME_FIXED_SIZE item = rffi.cast(lltype.Ptr(S), frame.jf_frame[gcmap[0]]) assert item == new_items[2] From noreply at buildbot.pypy.org Fri Feb 15 14:57:26 2013 From: noreply at buildbot.pypy.org (bivab) Date: Fri, 15 Feb 2013 14:57:26 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: move x86/test/test_gc_integration.py -> llsupport/test/test_gc_integration.py Message-ID: <20130215135726.45CD11C00A8@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: jitframe-on-heap Changeset: r61261:a903924c1948 Date: 2013-02-15 14:52 +0100 http://bitbucket.org/pypy/pypy/changeset/a903924c1948/ Log: move x86/test/test_gc_integration.py -> llsupport/test/test_gc_integration.py diff --git a/rpython/jit/backend/x86/test/test_gc_integration.py b/rpython/jit/backend/llsupport/test/test_gc_integration.py rename from rpython/jit/backend/x86/test/test_gc_integration.py rename to rpython/jit/backend/llsupport/test/test_gc_integration.py From noreply at buildbot.pypy.org Fri Feb 15 15:00:35 2013 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 15 Feb 2013 15:00:35 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: work on call_assembler up to the point at least Message-ID: <20130215140035.579711C00A8@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61262:5fadcd6a778d Date: 2013-02-15 14:37 +0200 http://bitbucket.org/pypy/pypy/changeset/5fadcd6a778d/ Log: work on call_assembler up to the point at least diff --git a/rpython/jit/backend/arm/opassembler.py b/rpython/jit/backend/arm/opassembler.py --- a/rpython/jit/backend/arm/opassembler.py +++ b/rpython/jit/backend/arm/opassembler.py @@ -1100,78 +1100,48 @@ self.mc.MOV_rr(res_loc.value, r.fp.value) return fcond - # from: ../x86/assembler.py:1668 - # XXX Split into some helper methods + def imm(self, v): + return imm(v) + def emit_guard_call_assembler(self, op, guard_op, arglocs, regalloc, - fcond): - tmploc = arglocs[1] - resloc = arglocs[2] - callargs = arglocs[3:] + fcond): + if len(arglocs) == 4: + [frame_loc, argloc, vloc, tmploc] = arglocs + else: + [frame_loc, argloc, tmploc] = arglocs + vloc = imm(0) + self.call_assembler(op, guard_op, frame_loc, argloc, vloc, tmploc) + xxx - self._store_force_index(guard_op) - descr = op.getdescr() - assert isinstance(descr, JitCellToken) - # check value - assert tmploc is r.r0 - self._emit_call(imm(descr._ll_function_addr), - callargs, fcond, resloc=tmploc) - if op.result is None: - value = self.cpu.done_with_this_frame_void_v - else: - kind = op.result.type - if kind == INT: - value = self.cpu.done_with_this_frame_int_v - elif kind == REF: - value = self.cpu.done_with_this_frame_ref_v - elif kind == FLOAT: - value = self.cpu.done_with_this_frame_float_v - else: - raise AssertionError(kind) - from rpython.jit.backend.llsupport.descr import unpack_fielddescr - from rpython.jit.backend.llsupport.descr import unpack_interiorfielddescr - descrs = self.cpu.gc_ll_descr.getframedescrs(self.cpu) - _offset, _size, _ = unpack_fielddescr(descrs.jf_descr) - fail_descr = self.cpu.get_fail_descr_from_number(value) - value = fail_descr.hide(self.cpu) - rgc._make_sure_does_not_move(value) - value = rffi.cast(lltype.Signed, value) + def _call_assembler_check_descr(self, value, tmploc): + ofs = self.cpu.get_ofs_of_frame_field('jf_descr') + self.mc.LDR_ri(r.ip.value, tmploc.value, imm=ofs) + self.mc.CMP_ri(r.ip.value, imm=value) + pos = self.mc.currpos() + self.mc.BPKT() + return pos - if check_imm_arg(_offset): - self.mc.LDR_ri(r.ip.value, tmploc.value, imm=_offset) - else: - self.mc.gen_load_int(r.ip.value, _offset) - self.mc.LDR_rr(r.ip.value, tmploc.value, r.ip.value) - if check_imm_arg(value): - self.mc.CMP_ri(r.ip.value, imm=value) - else: - self.mc.gen_load_int(r.lr.value, value) - self.mc.CMP_rr(r.lr.value, r.ip.value) + def _call_assembler_patch_je(self, result_loc, jmp_location): + pos = self.mc.currpos() + self.mc.BPKT() + pmc = OverwritingBuilder(self.mc, jmp_location, WORD) + pmc.B_offs(self.mc.currpos(), c.EQ) + return pos + def _call_assembler_reset_vtoken(self, jd, vloc): + from rpython.jit.backend.llsupport.descr import FieldDescr + fielddescr = jd.vable_token_descr + assert isinstance(fielddescr, FieldDescr) + ofs = fielddescr.offset + tmploc = self._regalloc.get_scratch_reg(INT) + self.mov_loc_loc(vloc, r.ip) + self.mc.MOV_ri(tmploc.value, 0) + self.mc.STR_ri(tmploc.value, r.ip.value, ofs) - #if values are equal we take the fast path - # Slow path, calling helper - # jump to merge point - - jd = descr.outermost_jitdriver_sd - assert jd is not None - - # Path A: load return value and reset token - # Fast Path using result boxes - - fast_path_cond = c.EQ - # Reset the vable token --- XXX really too much special logic here:-( - if jd.index_of_virtualizable >= 0: - from rpython.jit.backend.llsupport.descr import FieldDescr - fielddescr = jd.vable_token_descr - assert isinstance(fielddescr, FieldDescr) - ofs = fielddescr.offset - tmploc = regalloc.get_scratch_reg(INT) - self.mov_loc_loc(arglocs[0], r.ip, cond=fast_path_cond) - self.mc.MOV_ri(tmploc.value, 0, cond=fast_path_cond) - self.mc.STR_ri(tmploc.value, r.ip.value, ofs, cond=fast_path_cond) - + def _call_assembler_load_result(self, op, result_loc): + XXX if op.result is not None: - # load the return value from fail_boxes_xxx[0] + # load the return value from (tmploc, 0) kind = op.result.type if kind == FLOAT: t = unpack_interiorfielddescr(descrs.as_float)[0] diff --git a/rpython/jit/backend/arm/regalloc.py b/rpython/jit/backend/arm/regalloc.py --- a/rpython/jit/backend/arm/regalloc.py +++ b/rpython/jit/backend/arm/regalloc.py @@ -1101,20 +1101,10 @@ prepare_guard_call_release_gil = prepare_guard_call_may_force def prepare_guard_call_assembler(self, op, guard_op, fcond): - descr = op.getdescr() - assert isinstance(descr, JitCellToken) - jd = descr.outermost_jitdriver_sd - assert jd is not None - vable_index = jd.index_of_virtualizable - if vable_index >= 0: - self._sync_var(op.getarg(vable_index)) - vable = self.frame_manager.loc(op.getarg(vable_index)) - else: - vable = imm(0) - # make sure the call result location is free tmploc = self.get_scratch_reg(INT, selected_reg=r.r0) + locs = self.locs_for_call_assembler(op, guard_op) self.possibly_free_vars(guard_op.getfailargs()) - return [vable, tmploc] + self._prepare_call(op, save_all_regs=True) + return locs + [tmploc] def _prepare_args_for_new_op(self, new_args): gc_ll_descr = self.cpu.gc_ll_descr diff --git a/rpython/jit/backend/llsupport/assembler.py b/rpython/jit/backend/llsupport/assembler.py --- a/rpython/jit/backend/llsupport/assembler.py +++ b/rpython/jit/backend/llsupport/assembler.py @@ -1,7 +1,8 @@ +from rpython.rlib import rgc from rpython.rlib.rarithmetic import r_uint from rpython.jit.backend.llsupport.symbolic import WORD -from rpython.jit.metainterp.history import REF, FLOAT +from rpython.jit.metainterp.history import INT, REF, FLOAT, JitCellToken from rpython.rtyper.annlowlevel import cast_instance_to_gcref from rpython.rtyper.lltypesystem import rffi, lltype @@ -100,3 +101,59 @@ # we want the descr to keep alive guardtok.faildescr.rd_loop_token = self.current_clt return fail_descr, target + + def call_assembler(self, op, guard_op, frame_loc, argloc, + vloc, result_loc, tmploc): + self._store_force_index(guard_op) + descr = op.getdescr() + assert isinstance(descr, JitCellToken) + # + # Write a call to the target assembler + # we need to allocate the frame, keep in sync with runner's + # execute_token + jd = descr.outermost_jitdriver_sd + self._emit_call(self.imm(descr._ll_function_addr), + [argloc], 0, tmp=tmploc) + if op.result is None: + assert result_loc is None + value = self.cpu.done_with_this_frame_descr_void + else: + kind = op.result.type + if kind == INT: + assert result_loc is tmploc + value = self.cpu.done_with_this_frame_descr_int + elif kind == REF: + assert result_loc is tmploc + value = self.cpu.done_with_this_frame_descr_ref + elif kind == FLOAT: + value = self.cpu.done_with_this_frame_descr_float + else: + raise AssertionError(kind) + + gcref = cast_instance_to_gcref(value) + rgc._make_sure_does_not_move(gcref) + value = rffi.cast(lltype.Signed, gcref) + je_location = self._call_assembler_check_descr(value, tmploc) + # + # Path A: use assembler_helper_adr + assert jd is not None + asm_helper_adr = self.cpu.cast_adr_to_int(jd.assembler_helper_adr) + + self._emit_call(self.imm(asm_helper_adr), + [tmploc, vloc], 0, tmp=self._second_tmp_reg) + + jmp_location = self._call_assembler_patch_je(result_loc, je_location) + + # Path B: fast path. Must load the return value, and reset the token + + # Reset the vable token --- XXX really too much special logic here:-( + if jd.index_of_virtualizable >= 0: + self._call_assembler_reset_vtoken(jd, vloc) + # + self._call_assembler_load_result(op, result_loc) + # + # Here we join Path A and Path B again + self._call_assembler_patch_jmp(jmp_location) + # XXX here should be emitted guard_not_forced, but due + # to incompatibilities in how it's done, we leave it for the + # caller to deal with diff --git a/rpython/jit/backend/llsupport/regalloc.py b/rpython/jit/backend/llsupport/regalloc.py --- a/rpython/jit/backend/llsupport/regalloc.py +++ b/rpython/jit/backend/llsupport/regalloc.py @@ -1,5 +1,5 @@ import os -from rpython.jit.metainterp.history import Const, Box, REF +from rpython.jit.metainterp.history import Const, Box, REF, JitCellToken from rpython.rlib.objectmodel import we_are_translated, specialize from rpython.jit.metainterp.resoperation import rop @@ -667,6 +667,18 @@ return False return True + def locs_for_call_assembler(self, op, guard_op): + descr = op.getdescr() + assert isinstance(descr, JitCellToken) + arglist = op.getarglist() + self.rm._sync_var(arglist[0]) + frame_loc = self.fm.loc(op.getarg(0)) + if len(arglist) == 2: + self.rm._sync_var(arglist[1]) + return [frame_loc, self.loc(arglist[0]), self.fm.loc(arglist[1])] + else: + return [frame_loc, self.loc(arglist[0])] + def compute_vars_longevity(inputargs, operations): # compute a dictionary that maps variables to index in diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -51,6 +51,7 @@ class Assembler386(BaseAssembler): _regalloc = None _output_loop_log = None + _second_tmp_reg = ecx def __init__(self, cpu, translate_support_code=False): self.cpu = cpu @@ -2198,76 +2199,51 @@ if isinstance(save_loc, RegLoc) and not save_loc.is_xmm: self.mc.MOV_rs(save_loc.value, WORD) + def imm(self, v): + return imm(v) + + # ------------------- CALL ASSEMBLER -------------------------- + def genop_guard_call_assembler(self, op, guard_op, guard_token, arglocs, result_loc): - self._store_force_index(guard_op) - descr = op.getdescr() - assert isinstance(descr, JitCellToken) if len(arglocs) == 3: [frame_loc, argloc, vloc] = arglocs else: [frame_loc, argloc] = arglocs - vloc = imm(0) - # - # Write a call to the target assembler - # we need to allocate the frame, keep in sync with runner's - # execute_token - jd = descr.outermost_jitdriver_sd - base_ofs = self.cpu.get_baseofs_of_frame_field() - self._emit_call(imm(descr._ll_function_addr), - [argloc], 0, tmp=eax) - if op.result is None: - assert result_loc is None - value = self.cpu.done_with_this_frame_descr_void - else: - kind = op.result.type - if kind == INT: - assert result_loc is eax - value = self.cpu.done_with_this_frame_descr_int - elif kind == REF: - assert result_loc is eax - value = self.cpu.done_with_this_frame_descr_ref - elif kind == FLOAT: - value = self.cpu.done_with_this_frame_descr_float - else: - raise AssertionError(kind) + vloc = self.imm(0) + self.call_assembler(op, guard_op, frame_loc, argloc, vloc, + result_loc, eax) + self._emit_guard_not_forced(guard_token) - gcref = cast_instance_to_gcref(value) - rgc._make_sure_does_not_move(gcref) - value = rffi.cast(lltype.Signed, gcref) + def _call_assembler_check_descr(self, value, tmploc): ofs = self.cpu.get_ofs_of_frame_field('jf_descr') self.mc.CMP_mi((eax.value, ofs), value) # patched later self.mc.J_il8(rx86.Conditions['E'], 0) # goto B if we get 'done_with_this_frame' - je_location = self.mc.get_relative_pos() - # - # Path A: use assembler_helper_adr - assert jd is not None - asm_helper_adr = self.cpu.cast_adr_to_int(jd.assembler_helper_adr) + return self.mc.get_relative_pos() - self._emit_call(imm(asm_helper_adr), - [eax, vloc], 0, tmp=ecx) + def _call_assembler_patch_je(self, result_loc, je_location): if IS_X86_32 and isinstance(result_loc, StackLoc) and result_loc.type == FLOAT: self.mc.FSTPL_b(result_loc.value) - #else: result_loc is already either eax or None, checked below self.mc.JMP_l8(0) # jump to done, patched later jmp_location = self.mc.get_relative_pos() # - # Path B: fast path. Must load the return value, and reset the token offset = jmp_location - je_location assert 0 < offset <= 127 self.mc.overwrite(je_location - 1, chr(offset)) # - # Reset the vable token --- XXX really too much special logic here:-( - if jd.index_of_virtualizable >= 0: - from rpython.jit.backend.llsupport.descr import FieldDescr - fielddescr = jd.vable_token_descr - assert isinstance(fielddescr, FieldDescr) - vtoken_ofs = fielddescr.offset - self.mc.MOV(edx, vloc) # we know vloc is on the current frame - self.mc.MOV_mi((edx.value, vtoken_ofs), 0) - # in the line above, TOKEN_NONE = 0 - # + return jmp_location + + def _call_assembler_reset_vtoken(self, jd, vloc): + from rpython.jit.backend.llsupport.descr import FieldDescr + fielddescr = jd.vable_token_descr + assert isinstance(fielddescr, FieldDescr) + vtoken_ofs = fielddescr.offset + self.mc.MOV(edx, vloc) # we know vloc is on the current frame + self.mc.MOV_mi((edx.value, vtoken_ofs), 0) + # in the line above, TOKEN_NONE = 0 + + def _call_assembler_load_result(self, op, result_loc): if op.result is not None: # load the return value from the dead frame's value index 0 kind = op.result.type @@ -2282,12 +2258,13 @@ descr = self.cpu.getarraydescr_for_frame(kind) ofs = self.cpu.unpack_arraydescr(descr) self.mc.MOV_rm(eax.value, (eax.value, ofs)) - # - # Here we join Path A and Path B again + + def _call_assembler_patch_jmp(self, jmp_location): offset = self.mc.get_relative_pos() - jmp_location assert 0 <= offset <= 127 self.mc.overwrite(jmp_location - 1, chr(offset)) - self._emit_guard_not_forced(guard_token) + + # ------------------- END CALL ASSEMBLER ----------------------- def _write_barrier_fastpath(self, mc, descr, arglocs, array=False, is_frame=False): diff --git a/rpython/jit/backend/x86/regalloc.py b/rpython/jit/backend/x86/regalloc.py --- a/rpython/jit/backend/x86/regalloc.py +++ b/rpython/jit/backend/x86/regalloc.py @@ -6,7 +6,7 @@ from rpython.jit.metainterp.history import (Box, Const, ConstInt, ConstPtr, ConstFloat, BoxInt, BoxFloat, INT, REF, FLOAT, - TargetToken, JitCellToken) + TargetToken) from rpython.jit.backend.x86.regloc import * from rpython.rtyper.lltypesystem import lltype, rffi, rstr from rpython.rtyper.annlowlevel import cast_instance_to_gcref @@ -802,16 +802,7 @@ self._consider_call(op) def consider_call_assembler(self, op, guard_op): - descr = op.getdescr() - assert isinstance(descr, JitCellToken) - arglist = op.getarglist() - self.rm._sync_var(arglist[0]) - frame_loc = self.fm.loc(op.getarg(0)) - if len(arglist) == 2: - self.rm._sync_var(arglist[1]) - locs = [frame_loc, self.loc(arglist[0]), self.fm.loc(arglist[1])] - else: - locs = [frame_loc, self.loc(arglist[0])] + locs = self.locs_for_call_assembler(op, guard_op) self._call(op, locs, guard_not_forced_op=guard_op) def consider_cond_call_gc_wb(self, op): From noreply at buildbot.pypy.org Fri Feb 15 15:00:36 2013 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 15 Feb 2013 15:00:36 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: more work Message-ID: <20130215140036.9E07D1C00A8@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61263:97b326434c1a Date: 2013-02-15 15:58 +0200 http://bitbucket.org/pypy/pypy/changeset/97b326434c1a/ Log: more work diff --git a/rpython/jit/backend/arm/opassembler.py b/rpython/jit/backend/arm/opassembler.py --- a/rpython/jit/backend/arm/opassembler.py +++ b/rpython/jit/backend/arm/opassembler.py @@ -1139,12 +1139,17 @@ self.mc.STR_ri(tmploc.value, r.ip.value, ofs) def _call_assembler_load_result(self, op, result_loc): - XXX if op.result is not None: # load the return value from (tmploc, 0) kind = op.result.type + descr = self.cpu.getarraydescr_for_frame(kind) if kind == FLOAT: - t = unpack_interiorfielddescr(descrs.as_float)[0] + ofs = self.cpu.unpack_arraydescr(descr) + assert check_imm_arg(ofs) + assert result_loc.is_reg() + # we always have a register here, since we have to sync them + # before call_assembler + self.mc.VLDR(result_loc.value, xxx) if not check_imm_arg(t): self.mc.gen_load_int(r.ip.value, t, cond=fast_path_cond) self.mc.ADD_rr(r.ip.value, r.r0.value, r.ip.value, diff --git a/rpython/jit/backend/arm/regalloc.py b/rpython/jit/backend/arm/regalloc.py --- a/rpython/jit/backend/arm/regalloc.py +++ b/rpython/jit/backend/arm/regalloc.py @@ -1101,6 +1101,7 @@ prepare_guard_call_release_gil = prepare_guard_call_may_force def prepare_guard_call_assembler(self, op, guard_op, fcond): + self._prepare_call(op, save_all_regs=True) tmploc = self.get_scratch_reg(INT, selected_reg=r.r0) locs = self.locs_for_call_assembler(op, guard_op) self.possibly_free_vars(guard_op.getfailargs()) From noreply at buildbot.pypy.org Fri Feb 15 15:00:37 2013 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 15 Feb 2013 15:00:37 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: merge Message-ID: <20130215140037.E65E31C00A8@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61264:22ade1f1b39c Date: 2013-02-15 15:59 +0200 http://bitbucket.org/pypy/pypy/changeset/22ade1f1b39c/ Log: merge diff too long, truncating to 2000 out of 2918 lines diff --git a/rpython/jit/backend/arm/assembler.py b/rpython/jit/backend/arm/assembler.py --- a/rpython/jit/backend/arm/assembler.py +++ b/rpython/jit/backend/arm/assembler.py @@ -602,7 +602,7 @@ clt.allgcrefs) loop_head = self.mc.get_relative_pos() - looptoken._arm_loop_code = loop_head + looptoken._ll_loop_code = loop_head # frame_depth_no_fixed_size = self._assemble(regalloc, inputargs, operations) self.update_frame_depth(frame_depth_no_fixed_size + JITFRAME_FIXED_SIZE) @@ -815,7 +815,7 @@ def fixup_target_tokens(self, rawstart): for targettoken in self.target_tokens_currently_compiling: - targettoken._arm_loop_code += rawstart + targettoken._ll_loop_code += rawstart self.target_tokens_currently_compiling = None def _patch_stackadjust(self, adr, allocated_depth): diff --git a/rpython/jit/backend/arm/opassembler.py b/rpython/jit/backend/arm/opassembler.py --- a/rpython/jit/backend/arm/opassembler.py +++ b/rpython/jit/backend/arm/opassembler.py @@ -306,7 +306,7 @@ # stack locations both before and after the jump. # target_token = op.getdescr() - target = target_token._arm_loop_code + target = target_token._ll_loop_code assert isinstance(target_token, TargetToken) assert fcond == c.AL my_nbargs = self.current_clt._debug_nbargs diff --git a/rpython/jit/backend/arm/regalloc.py b/rpython/jit/backend/arm/regalloc.py --- a/rpython/jit/backend/arm/regalloc.py +++ b/rpython/jit/backend/arm/regalloc.py @@ -34,9 +34,9 @@ from rpython.jit.backend.llsupport.descr import unpack_interiorfielddescr -# xxx hack: set a default value for TargetToken._arm_loop_code. If 0, we know +# xxx hack: set a default value for TargetToken._ll_loop_code. If 0, we know # that it is a LABEL that was not compiled yet. -TargetToken._arm_loop_code = 0 +TargetToken._ll_loop_code = 0 class TempInt(TempBox): type = INT @@ -725,7 +725,7 @@ self.final_jump_op = op descr = op.getdescr() assert isinstance(descr, TargetToken) - if descr._arm_loop_code != 0: + if descr._ll_loop_code != 0: # if the target LABEL was already compiled, i.e. if it belongs # to some already-compiled piece of code self._compute_hint_frame_locations_from_descr(descr) @@ -1082,7 +1082,7 @@ self.frame_manager.mark_as_free(arg) # descr._arm_arglocs = arglocs - descr._arm_loop_code = self.assembler.mc.currpos() + descr._ll_loop_code = self.assembler.mc.currpos() descr._arm_clt = self.assembler.current_clt self.assembler.target_tokens_currently_compiling[descr] = None self.possibly_free_vars_for_op(op) diff --git a/rpython/jit/backend/arm/test/test_regalloc.py b/rpython/jit/backend/arm/test/test_regalloc.py --- a/rpython/jit/backend/arm/test/test_regalloc.py +++ b/rpython/jit/backend/arm/test/test_regalloc.py @@ -121,8 +121,8 @@ fdescr3 = BasicFailDescr(3) def setup_method(self, meth): - self.targettoken._arm_loop_code = 0 - self.targettoken2._arm_loop_code = 0 + self.targettoken._ll_loop_code = 0 + self.targettoken2._ll_loop_code = 0 def f1(x): return x + 1 diff --git a/rpython/jit/backend/llsupport/test/test_gc_integration.py b/rpython/jit/backend/llsupport/test/test_gc_integration.py new file mode 100644 --- /dev/null +++ b/rpython/jit/backend/llsupport/test/test_gc_integration.py @@ -0,0 +1,647 @@ + +""" Tests for register allocation for common constructs +""" + +from rpython.jit.metainterp.history import TargetToken, BasicFinalDescr,\ + JitCellToken, BasicFailDescr, AbstractDescr +from rpython.jit.backend.llsupport.gc import GcLLDescription, GcLLDescr_boehm,\ + GcLLDescr_framework, GcCache, JitFrameDescrs +from rpython.jit.backend.detect_cpu import getcpuclass +from rpython.jit.backend.llsupport.symbolic import WORD +from rpython.jit.backend.llsupport import jitframe +from rpython.rtyper.lltypesystem import lltype, llmemory, rffi +from rpython.rtyper.annlowlevel import llhelper, llhelper_args + +from rpython.jit.backend.llsupport.test.test_regalloc_integration import BaseTestRegalloc +from rpython.jit.codewriter.effectinfo import EffectInfo +from rpython.rlib.objectmodel import invoke_around_extcall + +CPU = getcpuclass() + +class TestRegallocGcIntegration(BaseTestRegalloc): + + cpu = CPU(None, None) + cpu.gc_ll_descr = GcLLDescr_boehm(None, None, None) + cpu.setup_once() + + S = lltype.GcForwardReference() + S.become(lltype.GcStruct('S', ('field', lltype.Ptr(S)), + ('int', lltype.Signed))) + + fielddescr = cpu.fielddescrof(S, 'field') + + struct_ptr = lltype.malloc(S) + struct_ref = lltype.cast_opaque_ptr(llmemory.GCREF, struct_ptr) + child_ptr = lltype.nullptr(S) + struct_ptr.field = child_ptr + + + intdescr = cpu.fielddescrof(S, 'int') + ptr0 = struct_ref + + targettoken = TargetToken() + targettoken2 = TargetToken() + + namespace = locals().copy() + + def test_basic(self): + ops = ''' + [p0] + p1 = getfield_gc(p0, descr=fielddescr) + finish(p1) + ''' + self.interpret(ops, [self.struct_ptr]) + assert not self.getptr(0, lltype.Ptr(self.S)) + + def test_guard(self): + ops = ''' + [i0, p0, i1, p1] + p3 = getfield_gc(p0, descr=fielddescr) + guard_true(i0) [p0, i1, p1, p3] + ''' + s1 = lltype.malloc(self.S) + s2 = lltype.malloc(self.S) + s1.field = s2 + self.interpret(ops, [0, s1, 1, s2]) + frame = lltype.cast_opaque_ptr(jitframe.JITFRAMEPTR, self.deadframe) + # p0 and p3 should be in registers, p1 not so much + assert self.getptr(0, lltype.Ptr(self.S)) == s1 + # this is a fairly CPU specific check + assert len(frame.jf_gcmap) == 1 + # the gcmap should contain three things, p0, p1 and p3 + # p3 stays in a register + # while p0 and p1 are on the frame + if self.cpu.IS_64_BIT: + nos = [11, 12, 31] + else: + nos = [4, 5, 25] + assert frame.jf_gcmap[0] == ((1 << nos[0]) | (1 << nos[1]) | + (1 << nos[2])) + assert frame.jf_frame[nos[0]] + assert frame.jf_frame[nos[1]] + assert frame.jf_frame[nos[2]] + + def test_rewrite_constptr(self): + ops = ''' + [] + p1 = getfield_gc(ConstPtr(struct_ref), descr=fielddescr) + finish(p1) + ''' + self.interpret(ops, []) + assert not self.getptr(0, lltype.Ptr(self.S)) + + def test_bug_0(self): + ops = ''' + [i0, i1, i2, i3, i4, i5, i6, i7, i8] + label(i0, i1, i2, i3, i4, i5, i6, i7, i8, descr=targettoken) + guard_value(i2, 1) [i2, i3, i4, i5, i6, i7, i0, i1, i8] + guard_class(i4, 138998336) [i4, i5, i6, i7, i0, i1, i8] + i11 = getfield_gc(i4, descr=intdescr) + guard_nonnull(i11) [i4, i5, i6, i7, i0, i1, i11, i8] + i13 = getfield_gc(i11, descr=intdescr) + guard_isnull(i13) [i4, i5, i6, i7, i0, i1, i11, i8] + i15 = getfield_gc(i4, descr=intdescr) + i17 = int_lt(i15, 0) + guard_false(i17) [i4, i5, i6, i7, i0, i1, i11, i15, i8] + i18 = getfield_gc(i11, descr=intdescr) + i19 = int_ge(i15, i18) + guard_false(i19) [i4, i5, i6, i7, i0, i1, i11, i15, i8] + i20 = int_lt(i15, 0) + guard_false(i20) [i4, i5, i6, i7, i0, i1, i11, i15, i8] + i21 = getfield_gc(i11, descr=intdescr) + i22 = getfield_gc(i11, descr=intdescr) + i23 = int_mul(i15, i22) + i24 = int_add(i21, i23) + i25 = getfield_gc(i4, descr=intdescr) + i27 = int_add(i25, 1) + setfield_gc(i4, i27, descr=intdescr) + i29 = getfield_raw(144839744, descr=intdescr) + i31 = int_and(i29, -2141192192) + i32 = int_is_true(i31) + guard_false(i32) [i4, i6, i7, i0, i1, i24] + i33 = getfield_gc(i0, descr=intdescr) + guard_value(i33, ConstPtr(ptr0)) [i4, i6, i7, i0, i1, i33, i24] + jump(i0, i1, 1, 17, i4, ConstPtr(ptr0), i6, i7, i24, descr=targettoken) + ''' + self.interpret(ops, [0, 0, 0, 0, 0, 0, 0, 0, 0], run=False) + +NOT_INITIALIZED = chr(0xdd) + +class GCDescrFastpathMalloc(GcLLDescription): + gcrootmap = None + passes_frame = True + write_barrier_descr = None + + def __init__(self, callback): + GcLLDescription.__init__(self, None) + # create a nursery + NTP = rffi.CArray(lltype.Char) + self.nursery = lltype.malloc(NTP, 64, flavor='raw') + for i in range(64): + self.nursery[i] = NOT_INITIALIZED + self.addrs = lltype.malloc(rffi.CArray(lltype.Signed), 2, + flavor='raw') + self.addrs[0] = rffi.cast(lltype.Signed, self.nursery) + self.addrs[1] = self.addrs[0] + 64 + self.calls = [] + def malloc_slowpath(size, frame): + if callback is not None: + callback(frame) + if self.gcrootmap is not None: # hook + self.gcrootmap.hook_malloc_slowpath() + self.calls.append(size) + # reset the nursery + nadr = rffi.cast(lltype.Signed, self.nursery) + self.addrs[0] = nadr + size + return nadr + self.generate_function('malloc_nursery', malloc_slowpath, + [lltype.Signed, jitframe.JITFRAMEPTR], + lltype.Signed) + + def get_nursery_free_addr(self): + return rffi.cast(lltype.Signed, self.addrs) + + def get_nursery_top_addr(self): + return rffi.cast(lltype.Signed, self.addrs) + WORD + + def get_malloc_slowpath_addr(self): + return self.get_malloc_fn_addr('malloc_nursery') + + def check_nothing_in_nursery(self): + # CALL_MALLOC_NURSERY should not write anything in the nursery + for i in range(64): + assert self.nursery[i] == NOT_INITIALIZED + +class TestMallocFastpath(BaseTestRegalloc): + + def teardown_method(self, method): + lltype.free(self.cpu.gc_ll_descr.addrs, flavor='raw') + lltype.free(self.cpu.gc_ll_descr.nursery, flavor='raw') + + def getcpu(self, callback): + cpu = CPU(None, None) + cpu.gc_ll_descr = GCDescrFastpathMalloc(callback) + cpu.setup_once() + return cpu + + def test_malloc_fastpath(self): + self.cpu = self.getcpu(None) + ops = ''' + [i0] + p0 = call_malloc_nursery(16) + p1 = call_malloc_nursery(32) + p2 = call_malloc_nursery(16) + guard_true(i0) [p0, p1, p2] + ''' + self.interpret(ops, [0]) + # check the returned pointers + gc_ll_descr = self.cpu.gc_ll_descr + nurs_adr = rffi.cast(lltype.Signed, gc_ll_descr.nursery) + ref = lambda n: self.cpu.get_ref_value(self.deadframe, n) + assert rffi.cast(lltype.Signed, ref(0)) == nurs_adr + 0 + assert rffi.cast(lltype.Signed, ref(1)) == nurs_adr + 16 + assert rffi.cast(lltype.Signed, ref(2)) == nurs_adr + 48 + # check the nursery content and state + gc_ll_descr.check_nothing_in_nursery() + assert gc_ll_descr.addrs[0] == nurs_adr + 64 + # slowpath never called + assert gc_ll_descr.calls == [] + + def test_malloc_nursery_varsize_small(self): + self.cpu = self.getcpu(None) + ops = ''' + [i0, i1, i2] + p0 = call_malloc_nursery_varsize_small(i0) + p1 = call_malloc_nursery_varsize_small(i1) + p2 = call_malloc_nursery_varsize_small(i2) + guard_true(i0) [p0, p1, p2] + ''' + self.interpret(ops, [16, 32, 16]) + # check the returned pointers + gc_ll_descr = self.cpu.gc_ll_descr + nurs_adr = rffi.cast(lltype.Signed, gc_ll_descr.nursery) + ref = lambda n: self.cpu.get_ref_value(self.deadframe, n) + assert rffi.cast(lltype.Signed, ref(0)) == nurs_adr + 0 + assert rffi.cast(lltype.Signed, ref(1)) == nurs_adr + 16 + assert rffi.cast(lltype.Signed, ref(2)) == nurs_adr + 48 + # check the nursery content and state + gc_ll_descr.check_nothing_in_nursery() + assert gc_ll_descr.addrs[0] == nurs_adr + 64 + # slowpath never called + assert gc_ll_descr.calls == [] + + def test_malloc_slowpath(self): + def check(frame): + assert len(frame.jf_gcmap) == 1 + if self.cpu.IS_64_BIT: + assert frame.jf_gcmap[0] == (1<<29) | (1 << 30) + else: + assert frame.jf_gcmap[0] == (1<<24) | (1 << 23) + + self.cpu = self.getcpu(check) + ops = ''' + [i0] + p0 = call_malloc_nursery(16) + p1 = call_malloc_nursery(32) + p2 = call_malloc_nursery(24) # overflow + guard_true(i0) [p0, p1, p2] + ''' + self.interpret(ops, [0]) + # check the returned pointers + gc_ll_descr = self.cpu.gc_ll_descr + nurs_adr = rffi.cast(lltype.Signed, gc_ll_descr.nursery) + ref = lambda n: self.cpu.get_ref_value(self.deadframe, n) + assert rffi.cast(lltype.Signed, ref(0)) == nurs_adr + 0 + assert rffi.cast(lltype.Signed, ref(1)) == nurs_adr + 16 + assert rffi.cast(lltype.Signed, ref(2)) == nurs_adr + 0 + # check the nursery content and state + gc_ll_descr.check_nothing_in_nursery() + assert gc_ll_descr.addrs[0] == nurs_adr + 24 + # this should call slow path once + assert gc_ll_descr.calls == [24] + + def test_save_regs_around_malloc(self): + def check(frame): + x = frame.jf_gcmap + if self.cpu.IS_64_BIT: + assert len(x) == 1 + assert (bin(x[0]).count('1') == + '0b1111100000000000000001111111011110'.count('1')) + else: + assert len(x) == 2 + s = bin(x[0]).count('1') + bin(x[1]).count('1') + assert s == 16 + # all but two registers + some stuff on stack + + self.cpu = self.getcpu(check) + S1 = lltype.GcStruct('S1') + S2 = lltype.GcStruct('S2', ('s0', lltype.Ptr(S1)), + ('s1', lltype.Ptr(S1)), + ('s2', lltype.Ptr(S1)), + ('s3', lltype.Ptr(S1)), + ('s4', lltype.Ptr(S1)), + ('s5', lltype.Ptr(S1)), + ('s6', lltype.Ptr(S1)), + ('s7', lltype.Ptr(S1)), + ('s8', lltype.Ptr(S1)), + ('s9', lltype.Ptr(S1)), + ('s10', lltype.Ptr(S1)), + ('s11', lltype.Ptr(S1)), + ('s12', lltype.Ptr(S1)), + ('s13', lltype.Ptr(S1)), + ('s14', lltype.Ptr(S1)), + ('s15', lltype.Ptr(S1))) + cpu = self.cpu + self.namespace = self.namespace.copy() + for i in range(16): + self.namespace['ds%i' % i] = cpu.fielddescrof(S2, 's%d' % i) + ops = ''' + [i0, p0] + p1 = getfield_gc(p0, descr=ds0) + p2 = getfield_gc(p0, descr=ds1) + p3 = getfield_gc(p0, descr=ds2) + p4 = getfield_gc(p0, descr=ds3) + p5 = getfield_gc(p0, descr=ds4) + p6 = getfield_gc(p0, descr=ds5) + p7 = getfield_gc(p0, descr=ds6) + p8 = getfield_gc(p0, descr=ds7) + p9 = getfield_gc(p0, descr=ds8) + p10 = getfield_gc(p0, descr=ds9) + p11 = getfield_gc(p0, descr=ds10) + p12 = getfield_gc(p0, descr=ds11) + p13 = getfield_gc(p0, descr=ds12) + p14 = getfield_gc(p0, descr=ds13) + p15 = getfield_gc(p0, descr=ds14) + p16 = getfield_gc(p0, descr=ds15) + # + # now all registers are in use + p17 = call_malloc_nursery(40) + p18 = call_malloc_nursery(40) # overflow + # + guard_true(i0) [p1, p2, p3, p4, p5, p6, \ + p7, p8, p9, p10, p11, p12, p13, p14, p15, p16] + ''' + s2 = lltype.malloc(S2) + for i in range(16): + setattr(s2, 's%d' % i, lltype.malloc(S1)) + s2ref = lltype.cast_opaque_ptr(llmemory.GCREF, s2) + # + self.interpret(ops, [0, s2ref]) + gc_ll_descr = cpu.gc_ll_descr + gc_ll_descr.check_nothing_in_nursery() + assert gc_ll_descr.calls == [40] + # check the returned pointers + for i in range(16): + s1ref = self.cpu.get_ref_value(self.deadframe, i) + s1 = lltype.cast_opaque_ptr(lltype.Ptr(S1), s1ref) + assert s1 == getattr(s2, 's%d' % i) + +class MockShadowStackRootMap(object): + is_shadow_stack = True + + def __init__(self): + TP = rffi.CArray(lltype.Signed) + self.stack = lltype.malloc(TP, 10, flavor='raw') + self.stack_addr = lltype.malloc(TP, 1, + flavor='raw') + self.stack_addr[0] = rffi.cast(lltype.Signed, self.stack) + + def __del__(self): + lltype.free(self.stack_addr, flavor='raw') + lltype.free(self.stack, flavor='raw') + + def register_asm_addr(self, start, mark): + pass + + def get_root_stack_top_addr(self): + return rffi.cast(lltype.Signed, self.stack_addr) + +class WriteBarrierDescr(AbstractDescr): + jit_wb_cards_set = 0 + jit_wb_if_flag_singlebyte = 1 + + def __init__(self, gc_ll_descr): + def write_barrier(frame): + gc_ll_descr.write_barrier_on_frame_called = frame + + self.write_barrier_fn = llhelper_args(write_barrier, + [lltype.Signed], lltype.Void) + + def get_write_barrier_fn(self, cpu): + return self.write_barrier_fn + +# a copy of JITFRAM that has 'hdr' field for tests + +def jitframe_allocate(frame_info): + frame = lltype.malloc(JITFRAME, frame_info.jfi_frame_depth, zero=True) + frame.jf_frame_info = frame_info + return frame + +JITFRAME = lltype.GcStruct( + 'JITFRAME', + ('hdr', lltype.Signed), + ('jf_frame_info', lltype.Ptr(jitframe.JITFRAMEINFO)), + ('jf_descr', llmemory.GCREF), + ('jf_force_descr', llmemory.GCREF), + ('jf_guard_exc', llmemory.GCREF), + ('jf_gcmap', lltype.Ptr(jitframe.GCMAP)), + ('jf_gc_trace_state', lltype.Signed), + ('jf_frame', lltype.Array(lltype.Signed)), + adtmeths = { + 'allocate': jitframe_allocate, + }, +) + +JITFRAMEPTR = lltype.Ptr(JITFRAME) + +class GCDescrShadowstackDirect(GcLLDescr_framework): + layoutbuilder = None + + class GCClass: + JIT_WB_IF_FLAG = 0 + + def __init__(self): + GcCache.__init__(self, False, None) + self._generated_functions = [] + self.gcrootmap = MockShadowStackRootMap() + self.write_barrier_descr = WriteBarrierDescr(self) + self.nursery_ptrs = lltype.malloc(rffi.CArray(lltype.Signed), 2, + flavor='raw') + self._initialize_for_tests() + self.frames = [] + + def malloc_slowpath(size): + self._collect() + res = self.nursery_ptrs[0] + self.nursery_ptrs[0] += size + return res + + self.malloc_slowpath_fnptr = llhelper_args(malloc_slowpath, + [lltype.Signed], + lltype.Signed) + self.all_nurseries = [] + + def init_nursery(self, nursery_size=None): + if nursery_size is None: + nursery_size = self.nursery_size + else: + self.nursery_size = nursery_size + self.nursery = lltype.malloc(rffi.CArray(lltype.Char), nursery_size, + flavor='raw', zero=True, + track_allocation=False) + self.nursery_ptrs[0] = rffi.cast(lltype.Signed, self.nursery) + self.nursery_ptrs[1] = self.nursery_ptrs[0] + nursery_size + self.nursery_addr = rffi.cast(lltype.Signed, self.nursery_ptrs) + self.all_nurseries.append(self.nursery) + if hasattr(self, 'collections'): + self.collections.reverse() + + def _collect(self): + gcmap = unpack_gcmap(self.frames[-1]) + col = self.collections.pop() + frame = self.frames[-1].jf_frame + start = rffi.cast(lltype.Signed, self.nursery) + assert len(gcmap) == len(col) + pos = [frame[item] for item in gcmap] + pos.sort() + for i in range(len(gcmap)): + assert col[i] + start == pos[i] + self.frames[-1].hdr |= 1 + self.init_nursery() + + def malloc_jitframe(self, frame_info): + """ Allocate a new frame, overwritten by tests + """ + frame = JITFRAME.allocate(frame_info) + self.frames.append(frame) + return frame + + def getframedescrs(self, cpu): + descrs = JitFrameDescrs() + descrs.arraydescr = cpu.arraydescrof(JITFRAME) + for name in ['jf_descr', 'jf_guard_exc', 'jf_force_descr', + 'jf_frame_info', 'jf_gcmap']: + setattr(descrs, name, cpu.fielddescrof(JITFRAME, name)) + descrs.jfi_frame_depth = cpu.fielddescrof(jitframe.JITFRAMEINFO, + 'jfi_frame_depth') + descrs.jfi_frame_size = cpu.fielddescrof(jitframe.JITFRAMEINFO, + 'jfi_frame_size') + return descrs + + def do_write_barrier(self, gcref_struct, gcref_newptr): + pass + + def get_malloc_slowpath_addr(self): + return self.malloc_slowpath_fnptr + + def get_nursery_free_addr(self): + return self.nursery_addr + + def get_nursery_top_addr(self): + return self.nursery_addr + rffi.sizeof(lltype.Signed) + + def __del__(self): + for nursery in self.all_nurseries: + lltype.free(nursery, flavor='raw', track_allocation=False) + lltype.free(self.nursery_ptrs, flavor='raw') + +def unpack_gcmap(frame): + res = [] + val = 0 + for i in range(len(frame.jf_gcmap)): + item = frame.jf_gcmap[i] + while item != 0: + if item & 1: + res.append(val) + val += 1 + item >>= 1 + return res + +class TestGcShadowstackDirect(BaseTestRegalloc): + + def setup_method(self, meth): + cpu = CPU(None, None) + cpu.gc_ll_descr = GCDescrShadowstackDirect() + wbd = cpu.gc_ll_descr.write_barrier_descr + wbd.jit_wb_if_flag_byteofs = 0 # directly into 'hdr' field + S = lltype.GcForwardReference() + S.become(lltype.GcStruct('S', + ('hdr', lltype.Signed), + ('x', lltype.Ptr(S)))) + cpu.gc_ll_descr.fielddescr_tid = cpu.fielddescrof(S, 'hdr') + self.S = S + self.cpu = cpu + + def test_shadowstack_call(self): + cpu = self.cpu + cpu.gc_ll_descr.init_nursery(100) + cpu.setup_once() + S = self.S + frames = [] + + def check(i): + assert cpu.gc_ll_descr.gcrootmap.stack[0] == i + frame = rffi.cast(JITFRAMEPTR, i) + assert len(frame.jf_frame) == self.cpu.JITFRAME_FIXED_SIZE + 4 + # we "collect" + frames.append(frame) + new_frame = JITFRAME.allocate(frame.jf_frame_info) + gcmap = unpack_gcmap(frame) + if self.cpu.IS_64_BIT: + assert gcmap == [28, 29, 30] + else: + assert gcmap == [22, 23, 24] + for item, s in zip(gcmap, new_items): + new_frame.jf_frame[item] = rffi.cast(lltype.Signed, s) + assert cpu.gc_ll_descr.gcrootmap.stack[0] == rffi.cast(lltype.Signed, frame) + cpu.gc_ll_descr.gcrootmap.stack[0] = rffi.cast(lltype.Signed, new_frame) + frames.append(new_frame) + + def check2(i): + assert cpu.gc_ll_descr.gcrootmap.stack[0] == i + frame = rffi.cast(JITFRAMEPTR, i) + assert frame == frames[1] + assert frame != frames[0] + + CHECK = lltype.FuncType([lltype.Signed], lltype.Void) + checkptr = llhelper(lltype.Ptr(CHECK), check) + check2ptr = llhelper(lltype.Ptr(CHECK), check2) + checkdescr = cpu.calldescrof(CHECK, CHECK.ARGS, CHECK.RESULT, + EffectInfo.MOST_GENERAL) + + loop = self.parse(""" + [p0, p1, p2] + pf = force_token() # this is the frame + call(ConstClass(check_adr), pf, descr=checkdescr) # this can collect + p3 = getfield_gc(p0, descr=fielddescr) + pf2 = force_token() + call(ConstClass(check2_adr), pf2, descr=checkdescr) + guard_nonnull(p3, descr=faildescr) [p0, p1, p2, p3] + p4 = getfield_gc(p0, descr=fielddescr) + finish(p4, descr=finaldescr) + """, namespace={'finaldescr': BasicFinalDescr(), + 'faildescr': BasicFailDescr(), + 'check_adr': checkptr, 'check2_adr': check2ptr, + 'checkdescr': checkdescr, + 'fielddescr': cpu.fielddescrof(S, 'x')}) + token = JitCellToken() + cpu.compile_loop(loop.inputargs, loop.operations, token) + p0 = lltype.malloc(S, zero=True) + p1 = lltype.malloc(S) + p2 = lltype.malloc(S) + new_items = [lltype.malloc(S), lltype.malloc(S), lltype.malloc(S)] + new_items[0].x = new_items[2] + frame = cpu.execute_token(token, p0, p1, p2) + frame = lltype.cast_opaque_ptr(JITFRAMEPTR, frame) + gcmap = unpack_gcmap(lltype.cast_opaque_ptr(JITFRAMEPTR, frame)) + assert len(gcmap) == 1 + assert gcmap[0] < self.cpu.JITFRAME_FIXED_SIZE + item = rffi.cast(lltype.Ptr(S), frame.jf_frame[gcmap[0]]) + assert item == new_items[2] + + def test_malloc_1(self): + cpu = self.cpu + sizeof = cpu.sizeof(self.S) + sizeof.tid = 0 + size = sizeof.size + loop = self.parse(""" + [] + p0 = call_malloc_nursery(%d) + p1 = call_malloc_nursery(%d) + p2 = call_malloc_nursery(%d) # this overflows + guard_nonnull(p2, descr=faildescr) [p0, p1, p2] + finish(p2, descr=finaldescr) + """ % (size, size, size), namespace={'sizedescr': sizeof, + 'finaldescr': BasicFinalDescr(), + 'faildescr': BasicFailDescr()}) + token = JitCellToken() + cpu.gc_ll_descr.collections = [[0, sizeof.size]] + cpu.gc_ll_descr.init_nursery(2 * sizeof.size) + cpu.setup_once() + cpu.compile_loop(loop.inputargs, loop.operations, token) + frame = cpu.execute_token(token) + # now we should be able to track everything from the frame + frame = lltype.cast_opaque_ptr(JITFRAMEPTR, frame) + thing = frame.jf_frame[unpack_gcmap(frame)[0]] + assert thing == rffi.cast(lltype.Signed, cpu.gc_ll_descr.nursery) + assert cpu.gc_ll_descr.nursery_ptrs[0] == thing + sizeof.size + assert rffi.cast(JITFRAMEPTR, cpu.gc_ll_descr.write_barrier_on_frame_called) == frame + + def test_call_release_gil(self): + # note that we can't test floats here because when untranslated + # people actually wreck xmm registers + cpu = self.cpu + l = [] + + def before(): + l.append("before") + + def after(): + l.append("after") + + invoke_around_extcall(before, after) + + def f(x): + assert x == 1 + return 2 + + FUNC = lltype.FuncType([lltype.Signed], lltype.Signed) + fptr = llhelper(lltype.Ptr(FUNC), f) + calldescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, + EffectInfo.MOST_GENERAL) + loop = self.parse(""" + [i0] + i1 = call_release_gil(ConstClass(fptr), i0, descr=calldescr) + guard_not_forced(descr=faildescr) [] + finish(i1, descr=finaldescr) + """, namespace={'fptr': fptr, 'calldescr':calldescr, + 'faildescr': BasicFailDescr(), + 'finaldescr': BasicFinalDescr()}) + token = JitCellToken() + cpu.gc_ll_descr.init_nursery(100) + cpu.setup_once() + cpu.compile_loop(loop.inputargs, loop.operations, token) + frame = cpu.execute_token(token, 1) + frame = rffi.cast(JITFRAMEPTR, frame) + assert frame.jf_frame[0] == 2 + assert l == ['before', 'after'] diff --git a/rpython/jit/backend/llsupport/test/test_regalloc_integration.py b/rpython/jit/backend/llsupport/test/test_regalloc_integration.py new file mode 100644 --- /dev/null +++ b/rpython/jit/backend/llsupport/test/test_regalloc_integration.py @@ -0,0 +1,685 @@ + +""" Tests for register allocation for common constructs +""" + +import py +from rpython.jit.metainterp.history import BoxInt, ConstInt,\ + BoxPtr, ConstPtr, BasicFailDescr, JitCellToken, TargetToken +from rpython.jit.metainterp.resoperation import rop, ResOperation +from rpython.jit.backend.llsupport.descr import GcCache +from rpython.jit.backend.detect_cpu import getcpuclass +from rpython.jit.backend.llsupport.regalloc import is_comparison_or_ovf_op +from rpython.jit.tool.oparser import parse +from rpython.rtyper.lltypesystem import lltype, llmemory, rffi +from rpython.rtyper.annlowlevel import llhelper +from rpython.rtyper.lltypesystem import rclass, rstr +from rpython.jit.codewriter import longlong +from rpython.jit.codewriter.effectinfo import EffectInfo + +def test_is_comparison_or_ovf_op(): + assert not is_comparison_or_ovf_op(rop.INT_ADD) + assert is_comparison_or_ovf_op(rop.INT_ADD_OVF) + assert is_comparison_or_ovf_op(rop.INT_EQ) + + +def get_zero_division_error(self): + # for tests, a random emulated ll_inst will do + ll_inst = lltype.malloc(rclass.OBJECT) + ll_inst.typeptr = lltype.malloc(rclass.OBJECT_VTABLE, + immortal=True) + _zer_error_vtable = llmemory.cast_ptr_to_adr(ll_inst.typeptr) + zer_vtable = self.cast_adr_to_int(_zer_error_vtable) + zer_inst = lltype.cast_opaque_ptr(llmemory.GCREF, ll_inst) + return zer_vtable, zer_inst + + +CPU = getcpuclass() +class BaseTestRegalloc(object): + cpu = CPU(None, None) + cpu.setup_once() + + def raising_func(i): + if i: + raise LLException(zero_division_error, + zero_division_value) + FPTR = lltype.Ptr(lltype.FuncType([lltype.Signed], lltype.Void)) + raising_fptr = llhelper(FPTR, raising_func) + zero_division_tp, zero_division_value = get_zero_division_error(cpu) + zd_addr = cpu.cast_int_to_adr(zero_division_tp) + zero_division_error = llmemory.cast_adr_to_ptr(zd_addr, + lltype.Ptr(rclass.OBJECT_VTABLE)) + raising_calldescr = cpu.calldescrof(FPTR.TO, FPTR.TO.ARGS, FPTR.TO.RESULT, + EffectInfo.MOST_GENERAL) + + targettoken = TargetToken() + targettoken2 = TargetToken() + fdescr1 = BasicFailDescr(1) + fdescr2 = BasicFailDescr(2) + fdescr3 = BasicFailDescr(3) + + def setup_method(self, meth): + self.targettoken._ll_loop_code = 0 + self.targettoken2._ll_loop_code = 0 + + def f1(x): + return x+1 + + def f2(x, y): + return x*y + + def f10(*args): + assert len(args) == 10 + return sum(args) + + F1PTR = lltype.Ptr(lltype.FuncType([lltype.Signed], lltype.Signed)) + F2PTR = lltype.Ptr(lltype.FuncType([lltype.Signed]*2, lltype.Signed)) + F10PTR = lltype.Ptr(lltype.FuncType([lltype.Signed]*10, lltype.Signed)) + f1ptr = llhelper(F1PTR, f1) + f2ptr = llhelper(F2PTR, f2) + f10ptr = llhelper(F10PTR, f10) + + f1_calldescr = cpu.calldescrof(F1PTR.TO, F1PTR.TO.ARGS, F1PTR.TO.RESULT, + EffectInfo.MOST_GENERAL) + f2_calldescr = cpu.calldescrof(F2PTR.TO, F2PTR.TO.ARGS, F2PTR.TO.RESULT, + EffectInfo.MOST_GENERAL) + f10_calldescr= cpu.calldescrof(F10PTR.TO, F10PTR.TO.ARGS, F10PTR.TO.RESULT, + EffectInfo.MOST_GENERAL) + + namespace = locals().copy() + type_system = 'lltype' + + def parse(self, s, boxkinds=None, namespace=None): + return parse(s, self.cpu, namespace or self.namespace, + type_system=self.type_system, + boxkinds=boxkinds) + + def interpret(self, ops, args, run=True): + loop = self.parse(ops) + looptoken = JitCellToken() + self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) + arguments = [] + for arg in args: + if isinstance(arg, int): + arguments.append(arg) + elif isinstance(arg, float): + arg = longlong.getfloatstorage(arg) + arguments.append(arg) + else: + assert isinstance(lltype.typeOf(arg), lltype.Ptr) + llgcref = lltype.cast_opaque_ptr(llmemory.GCREF, arg) + arguments.append(llgcref) + loop._jitcelltoken = looptoken + if run: + self.deadframe = self.cpu.execute_token(looptoken, *arguments) + return loop + + def prepare_loop(self, ops): + loop = self.parse(ops) + regalloc = self.cpu.build_regalloc() + regalloc.prepare_loop(loop.inputargs, loop.operations, + loop.original_jitcell_token, []) + return regalloc + + def getint(self, index): + return self.cpu.get_int_value(self.deadframe, index) + + def getfloat(self, index): + return self.cpu.get_float_value(self.deadframe, index) + + def getints(self, end): + return [self.cpu.get_int_value(self.deadframe, index) for + index in range(0, end)] + + def getfloats(self, end): + return [longlong.getrealfloat( + self.cpu.get_float_value(self.deadframe, index)) + for index in range(0, end)] + + def getptr(self, index, T): + gcref = self.cpu.get_ref_value(self.deadframe, index) + return lltype.cast_opaque_ptr(T, gcref) + + def attach_bridge(self, ops, loop, guard_op_index, **kwds): + guard_op = loop.operations[guard_op_index] + assert guard_op.is_guard() + bridge = self.parse(ops, **kwds) + assert ([box.type for box in bridge.inputargs] == + [box.type for box in guard_op.getfailargs()]) + faildescr = guard_op.getdescr() + self.cpu.compile_bridge(faildescr, bridge.inputargs, bridge.operations, + loop._jitcelltoken) + return bridge + + def run(self, loop, *arguments): + self.deadframe = self.cpu.execute_token(loop._jitcelltoken, *arguments) + return self.cpu.get_latest_descr(self.deadframe) + +class TestRegallocSimple(BaseTestRegalloc): + def test_simple_loop(self): + ops = ''' + [i0] + label(i0, descr=targettoken) + i1 = int_add(i0, 1) + i2 = int_lt(i1, 20) + guard_true(i2) [i1] + jump(i1, descr=targettoken) + ''' + self.interpret(ops, [0]) + assert self.getint(0) == 20 + + def test_two_loops_and_a_bridge(self): + ops = ''' + [i0, i1, i2, i3] + label(i0, i1, i2, i3, descr=targettoken) + i4 = int_add(i0, 1) + i5 = int_lt(i4, 20) + guard_true(i5) [i4, i1, i2, i3] + jump(i4, i1, i2, i3, descr=targettoken) + ''' + loop = self.interpret(ops, [0, 0, 0, 0]) + ops2 = ''' + [i5, i6, i7, i8] + label(i5, descr=targettoken2) + i1 = int_add(i5, 1) + i3 = int_add(i1, 1) + i4 = int_add(i3, 1) + i2 = int_lt(i4, 30) + guard_true(i2) [i4] + jump(i4, descr=targettoken2) + ''' + loop2 = self.interpret(ops2, [0, 0, 0, 0]) + bridge_ops = ''' + [i4] + jump(i4, i4, i4, i4, descr=targettoken) + ''' + bridge = self.attach_bridge(bridge_ops, loop2, 5) + self.run(loop2, 0, 0, 0, 0) + assert self.getint(0) == 31 + assert self.getint(1) == 30 + assert self.getint(2) == 30 + assert self.getint(3) == 30 + + def test_pointer_arg(self): + ops = ''' + [i0, p0] + label(i0, p0, descr=targettoken) + i1 = int_add(i0, 1) + i2 = int_lt(i1, 10) + guard_true(i2) [p0] + jump(i1, p0, descr=targettoken) + ''' + S = lltype.GcStruct('S') + ptr = lltype.malloc(S) + self.interpret(ops, [0, ptr]) + assert self.getptr(0, lltype.Ptr(S)) == ptr + + def test_exception_bridge_no_exception(self): + ops = ''' + [i0] + i1 = same_as(1) + call(ConstClass(raising_fptr), i0, descr=raising_calldescr) + guard_exception(ConstClass(zero_division_error)) [i1] + finish(0) + ''' + bridge_ops = ''' + [i3] + i2 = same_as(2) + guard_no_exception() [i2] + finish(1) + ''' + loop = self.interpret(ops, [0]) + assert self.getint(0) == 1 + bridge = self.attach_bridge(bridge_ops, loop, 2) + self.run(loop, 0) + assert self.getint(0) == 1 + + def test_inputarg_unused(self): + ops = ''' + [i0] + finish(1) + ''' + self.interpret(ops, [0]) + # assert did not explode + + def test_nested_guards(self): + ops = ''' + [i0, i1] + guard_true(i0) [i0, i1] + finish(4) + ''' + bridge_ops = ''' + [i0, i1] + guard_true(i0) [i0, i1] + finish(3) + ''' + loop = self.interpret(ops, [0, 10]) + assert self.getint(0) == 0 + assert self.getint(1) == 10 + bridge = self.attach_bridge(bridge_ops, loop, 0) + self.run(loop, 0, 10) + assert self.getint(0) == 0 + assert self.getint(1) == 10 + + def test_nested_unused_arg(self): + ops = ''' + [i0, i1] + guard_true(i0) [i0, i1] + finish(1) + ''' + loop = self.interpret(ops, [0, 1]) + assert self.getint(0) == 0 + bridge_ops = ''' + [i0, i1] + finish(2) + ''' + self.attach_bridge(bridge_ops, loop, 0) + self.run(loop, 0, 1) + + def test_spill_for_constant(self): + ops = ''' + [i0, i1, i2, i3] + label(i0, i1, i2, i3, descr=targettoken) + i4 = int_add(3, i1) + i5 = int_lt(i4, 30) + guard_true(i5) [i0, i4, i2, i3] + jump(1, i4, 3, 4, descr=targettoken) + ''' + self.interpret(ops, [0, 0, 0, 0]) + assert self.getints(4) == [1, 30, 3, 4] + + def test_spill_for_constant_lshift(self): + ops = ''' + [i0, i2, i1, i3] + label(i0, i2, i1, i3, descr=targettoken) + i4 = int_lshift(1, i1) + i5 = int_add(1, i1) + i6 = int_lt(i5, 30) + guard_true(i6) [i4, i5, i2, i3] + jump(i4, 3, i5, 4, descr=targettoken) + ''' + self.interpret(ops, [0, 0, 0, 0]) + assert self.getints(4) == [1<<29, 30, 3, 4] + ops = ''' + [i0, i1, i2, i3] + label(i0, i1, i2, i3, descr=targettoken) + i4 = int_lshift(1, i1) + i5 = int_add(1, i1) + i6 = int_lt(i5, 30) + guard_true(i6) [i4, i5, i2, i3] + jump(i4, i5, 3, 4, descr=targettoken) + ''' + self.interpret(ops, [0, 0, 0, 0]) + assert self.getints(4) == [1<<29, 30, 3, 4] + ops = ''' + [i0, i3, i1, i2] + label(i0, i3, i1, i2, descr=targettoken) + i4 = int_lshift(1, i1) + i5 = int_add(1, i1) + i6 = int_lt(i5, 30) + guard_true(i6) [i4, i5, i2, i3] + jump(i4, 4, i5, 3, descr=targettoken) + ''' + self.interpret(ops, [0, 0, 0, 0]) + assert self.getints(4) == [1<<29, 30, 3, 4] + + def test_result_selected_reg_via_neg(self): + ops = ''' + [i0, i1, i2, i3] + label(i0, i1, i2, i3, descr=targettoken) + i6 = int_neg(i2) + i7 = int_add(1, i1) + i4 = int_lt(i7, 10) + guard_true(i4) [i0, i6, i7] + jump(1, i7, i2, i6, descr=targettoken) + ''' + self.interpret(ops, [0, 0, 3, 0]) + assert self.getints(3) == [1, -3, 10] + + def test_compare_memory_result_survives(self): + ops = ''' + [i0, i1, i2, i3] + label(i0, i1, i2, i3, descr=targettoken) + i4 = int_lt(i0, i1) + i5 = int_add(i3, 1) + i6 = int_lt(i5, 30) + guard_true(i6) [i4] + jump(i0, i1, i4, i5, descr=targettoken) + ''' + self.interpret(ops, [0, 10, 0, 0]) + assert self.getint(0) == 1 + + def test_jump_different_args(self): + ops = ''' + [i0, i15, i16, i18, i1, i2, i3] + label(i0, i15, i16, i18, i1, i2, i3, descr=targettoken) + i4 = int_add(i3, 1) + i5 = int_lt(i4, 20) + guard_true(i5) [i2, i1] + jump(i0, i18, i15, i16, i2, i1, i4, descr=targettoken) + ''' + self.interpret(ops, [0, 1, 2, 3, 0, 0, 0]) + + def test_op_result_unused(self): + ops = ''' + [i0, i1] + i2 = int_add(i0, i1) + finish(0) + ''' + self.interpret(ops, [0, 0]) + + def test_guard_value_two_boxes(self): + ops = ''' + [i0, i1, i2, i3, i4, i5, i6, i7] + guard_value(i6, i1) [i0, i2, i3, i4, i5, i6] + finish(i0) + ''' + self.interpret(ops, [0, 0, 0, 0, 0, 0, 0, 0]) + assert self.getint(0) == 0 + + def test_bug_wrong_stack_adj(self): + ops = ''' + [i0, i1, i2, i3, i4, i5, i6, i7, i8] + i9 = same_as(0) + guard_true(i0) [i9, i0, i1, i2, i3, i4, i5, i6, i7, i8] + finish(1) + ''' + loop = self.interpret(ops, [0, 1, 2, 3, 4, 5, 6, 7, 8]) + assert self.getint(0) == 0 + bridge_ops = ''' + [i9, i0, i1, i2, i3, i4, i5, i6, i7, i8] + call(ConstClass(raising_fptr), 0, descr=raising_calldescr) + guard_true(i9) [i0, i1, i2, i3, i4, i5, i6, i7, i8] + finish() + ''' + self.attach_bridge(bridge_ops, loop, 1) + self.run(loop, 0, 1, 2, 3, 4, 5, 6, 7, 8) + assert self.getints(9) == range(9) + + def test_loopargs(self): + ops = """ + [i0, i1, i2, i3] + i4 = int_add(i0, i1) + jump(i4, i1, i2, i3) + """ + regalloc = self.prepare_loop(ops) + # we pass stuff on the frame + assert len(regalloc.rm.reg_bindings) == 0 + assert len(regalloc.fm.bindings) == 4 + + +class TestRegallocCompOps(BaseTestRegalloc): + + def test_cmp_op_0(self): + ops = ''' + [i0, i3] + i1 = same_as(1) + i2 = int_lt(i0, 100) + guard_true(i3) [i1, i2] + i4 = int_neg(i2) + finish(0) + ''' + self.interpret(ops, [0, 1]) + assert self.getint(0) == 0 + +class TestRegallocMoreRegisters(BaseTestRegalloc): + + cpu = BaseTestRegalloc.cpu + targettoken = TargetToken() + + S = lltype.GcStruct('S', ('field', lltype.Char)) + fielddescr = cpu.fielddescrof(S, 'field') + + A = lltype.GcArray(lltype.Char) + arraydescr = cpu.arraydescrof(A) + + namespace = locals().copy() + + def test_int_is_true(self): + ops = ''' + [i0, i1, i2, i3, i4, i5, i6, i7] + i10 = int_is_true(i0) + i11 = int_is_true(i1) + i12 = int_is_true(i2) + i13 = int_is_true(i3) + i14 = int_is_true(i4) + i15 = int_is_true(i5) + i16 = int_is_true(i6) + i17 = int_is_true(i7) + guard_true(i0) [i10, i11, i12, i13, i14, i15, i16, i17] + finish() + ''' + self.interpret(ops, [0, 42, 12, 0, 13, 0, 0, 3333]) + assert self.getints(8) == [0, 1, 1, 0, 1, 0, 0, 1] + + def test_comparison_ops(self): + ops = ''' + [i0, i1, i2, i3, i4, i5, i6] + i10 = int_lt(i0, i1) + i11 = int_le(i2, i3) + i12 = int_ge(i4, i5) + i13 = int_eq(i5, i6) + i14 = int_gt(i6, i2) + i15 = int_ne(i2, i6) + guard_true(i0) [i10, i11, i12, i13, i14, i15] + finish() + ''' + self.interpret(ops, [0, 1, 2, 3, 4, 5, 6]) + assert self.getints(6) == [1, 1, 0, 0, 1, 1] + + def test_strsetitem(self): + ops = ''' + [p0, i] + strsetitem(p0, 1, i) + finish() + ''' + llstr = rstr.mallocstr(10) + self.interpret(ops, [llstr, ord('a')]) + assert llstr.chars[1] == 'a' + + def test_setfield_char(self): + ops = ''' + [p0, i] + setfield_gc(p0, i, descr=fielddescr) + finish() + ''' + s = lltype.malloc(self.S) + self.interpret(ops, [s, ord('a')]) + assert s.field == 'a' + + def test_setarrayitem_gc(self): + ops = ''' + [p0, i] + setarrayitem_gc(p0, 1, i, descr=arraydescr) + finish() + ''' + s = lltype.malloc(self.A, 3) + self.interpret(ops, [s, ord('a')]) + assert s[1] == 'a' + + def test_division_optimized(self): + ops = ''' + [i7, i6] + label(i7, i6, descr=targettoken) + i18 = int_floordiv(i7, i6) + i19 = int_xor(i7, i6) + i21 = int_lt(i19, 0) + i22 = int_mod(i7, i6) + i23 = int_is_true(i22) + i24 = int_eq(i6, 4) + guard_false(i24) [i18] + jump(i18, i6, descr=targettoken) + ''' + self.interpret(ops, [10, 4]) + assert self.getint(0) == 2 + # FIXME: Verify that i19 - i23 are removed + +class TestRegallocFloats(BaseTestRegalloc): + def test_float_add(self): + ops = ''' + [f0, f1] + f2 = float_add(f0, f1) + i0 = same_as(0) + guard_true(i0) [f2, f0, f1] + finish() + ''' + self.interpret(ops, [3.0, 1.5]) + assert self.getfloats(3) == [4.5, 3.0, 1.5] + + def test_float_adds_stack(self): + ops = ''' + [f0, f1, f2, f3, f4, f5, f6, f7, f8] + f9 = float_add(f0, f1) + f10 = float_add(f8, 3.5) + i0 = same_as(0) + guard_true(i0) [f9, f10, f2, f3, f4, f5, f6, f7, f8] + finish() + ''' + self.interpret(ops, [0.1, .2, .3, .4, .5, .6, .7, .8, .9]) + assert self.getfloats(9) == [.1+.2, .9+3.5, .3, .4, .5, .6, .7, .8, .9] + + def test_lt_const(self): + ops = ''' + [f0] + i1 = float_lt(3.5, f0) + finish(i1) + ''' + self.interpret(ops, [0.1]) + assert self.getint(0) == 0 + + def test_bug_float_is_true_stack(self): + # NB. float_is_true no longer exists. Unsure if keeping this test + # makes sense any more. + ops = ''' + [f0, f1, f2, f3, f4, f5, f6, f7, f8, f9] + i0 = float_ne(f0, 0.0) + i1 = float_ne(f1, 0.0) + i2 = float_ne(f2, 0.0) + i3 = float_ne(f3, 0.0) + i4 = float_ne(f4, 0.0) + i5 = float_ne(f5, 0.0) + i6 = float_ne(f6, 0.0) + i7 = float_ne(f7, 0.0) + i8 = float_ne(f8, 0.0) + i9 = float_ne(f9, 0.0) + guard_true(i0) [i0, i1, i2, i3, i4, i5, i6, i7, i8, i9] + finish() + ''' + loop = self.interpret(ops, [0.0, .1, .2, .3, .4, .5, .6, .7, .8, .9]) + assert self.getints(9) == [0, 1, 1, 1, 1, 1, 1, 1, 1] + +class TestRegAllocCallAndStackDepth(BaseTestRegalloc): + def setup_class(cls): + py.test.skip("skip for now, not sure what do we do") + + def expected_frame_depth(self, num_call_args, num_pushed_input_args=0): + # Assumes the arguments are all non-float + if not self.cpu.IS_64_BIT: + extra_esp = num_call_args + return extra_esp + elif self.cpu.IS_64_BIT: + # 'num_pushed_input_args' is for X86_64 only + extra_esp = max(num_call_args - 6, 0) + return num_pushed_input_args + extra_esp + + def test_one_call(self): + ops = ''' + [i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i9b] + i10 = call(ConstClass(f1ptr), i0, descr=f1_calldescr) + guard_false(i10) [i10, i1, i2, i3, i4, i5, i6, i7, i8, i9, i9b] + ''' + loop = self.interpret(ops, [4, 7, 9, 9 ,9, 9, 9, 9, 9, 9, 8]) + assert self.getints(11) == [5, 7, 9, 9, 9, 9, 9, 9, 9, 9, 8] + clt = loop._jitcelltoken.compiled_loop_token + assert clt.frame_depth == self.expected_frame_depth(1, 5) + + def test_one_call_reverse(self): + ops = ''' + [i1, i2, i3, i4, i5, i6, i7, i8, i9, i9b, i0] + i10 = call(ConstClass(f1ptr), i0, descr=f1_calldescr) + guard_false(i10) [i10, i1, i2, i3, i4, i5, i6, i7, i8, i9, i9b] + ''' + loop = self.interpret(ops, [7, 9, 9 ,9, 9, 9, 9, 9, 9, 8, 4]) + assert self.getints(11) == [5, 7, 9, 9, 9, 9, 9, 9, 9, 9, 8] + clt = loop._jitcelltoken.compiled_loop_token + assert clt.frame_depth == self.expected_frame_depth(1, 6) + + def test_two_calls(self): + ops = ''' + [i0, i1, i2, i3, i4, i5, i6, i7, i8, i9] + i10 = call(ConstClass(f1ptr), i0, descr=f1_calldescr) + i11 = call(ConstClass(f2ptr), i10, i1, descr=f2_calldescr) + guard_false(i5) [i11, i1, i2, i3, i4, i5, i6, i7, i8, i9] + ''' + loop = self.interpret(ops, [4, 7, 9, 9 ,9, 9, 9, 9, 9, 9]) + assert self.getints(10) == [5*7, 7, 9, 9, 9, 9, 9, 9, 9, 9] + clt = loop._jitcelltoken.compiled_loop_token + assert clt.frame_depth == self.expected_frame_depth(2, 5) + + def test_call_many_arguments(self): + # NB: The first and last arguments in the call are constants. This + # is primarily for x86-64, to ensure that loading a constant to an + # argument register or to the stack works correctly + ops = ''' + [i0, i1, i2, i3, i4, i5, i6, i7] + i8 = call(ConstClass(f10ptr), 1, i0, i1, i2, i3, i4, i5, i6, i7, 10, descr=f10_calldescr) + finish(i8) + ''' + loop = self.interpret(ops, [2, 3, 4, 5, 6, 7, 8, 9]) + assert self.getint(0) == 55 + clt = loop._jitcelltoken.compiled_loop_token + assert clt.frame_depth == self.expected_frame_depth(10) + + def test_bridge_calls_1(self): + ops = ''' + [i0, i1] + i2 = call(ConstClass(f1ptr), i0, descr=f1_calldescr) + guard_value(i2, 0, descr=fdescr1) [i2, i0, i1] + guard_false(i1) [i1] + ''' + loop = self.interpret(ops, [4, 7]) + assert self.getint(0) == 5 + clt = loop._jitcelltoken.compiled_loop_token + orgdepth = clt.frame_depth + assert orgdepth == self.expected_frame_depth(1, 2) + + ops = ''' + [i2, i0, i1] + i3 = call(ConstClass(f2ptr), i2, i1, descr=f2_calldescr) + guard_false(i0, descr=fdescr2) [i3, i0] + ''' + bridge = self.attach_bridge(ops, loop, -2) + + assert clt.frame_depth == max(orgdepth, self.expected_frame_depth(2, 2)) + assert loop.operations[-2].getdescr()._x86_bridge_frame_depth == \ + self.expected_frame_depth(2, 2) + + self.run(loop, 4, 7) + assert self.getint(0) == 5*7 + + def test_bridge_calls_2(self): + ops = ''' + [i0, i1] + i2 = call(ConstClass(f2ptr), i0, i1, descr=f2_calldescr) + guard_value(i2, 0, descr=fdescr1) [i2] + guard_false(i2) [i2] + ''' + loop = self.interpret(ops, [4, 7]) + assert self.getint(0) == 4*7 + clt = loop._jitcelltoken.compiled_loop_token + orgdepth = clt.frame_depth + assert orgdepth == self.expected_frame_depth(2) + + ops = ''' + [i2] + i3 = call(ConstClass(f1ptr), i2, descr=f1_calldescr) + guard_false(i3, descr=fdescr2) [i3] + ''' + bridge = self.attach_bridge(ops, loop, -2) + + assert clt.frame_depth == max(orgdepth, self.expected_frame_depth(1)) + assert loop.operations[-2].getdescr()._x86_bridge_frame_depth == \ + self.expected_frame_depth(1) + + self.run(loop, 4, 7) + assert self.getint(0) == 29 + diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -474,7 +474,7 @@ def assemble_loop(self, loopname, inputargs, operations, looptoken, log): '''adds the following attributes to looptoken: _ll_function_addr (address of the generated func, as an int) - _x86_loop_code (debug: addr of the start of the ResOps) + _ll_loop_code (debug: addr of the start of the ResOps) _x86_fullsize (debug: full size including failure) _x86_debug_checksum ''' @@ -516,7 +516,7 @@ full_size = self.mc.get_relative_pos() # rawstart = self.materialize_loop(looptoken) - looptoken._x86_loop_code = looppos + rawstart + looptoken._ll_loop_code = looppos + rawstart debug_start("jit-backend-addr") debug_print("Loop %d (%s) has address %x to %x (bootstrap %x)" % ( looptoken.number, loopname, @@ -734,7 +734,7 @@ def fixup_target_tokens(self, rawstart): for targettoken in self.target_tokens_currently_compiling: - targettoken._x86_loop_code += rawstart + targettoken._ll_loop_code += rawstart self.target_tokens_currently_compiling = None def _append_debugging_code(self, operations, tp, number, token): @@ -2411,7 +2411,7 @@ expected_size=expected_size) def closing_jump(self, target_token): - target = target_token._x86_loop_code + target = target_token._ll_loop_code if target_token in self.target_tokens_currently_compiling: curpos = self.mc.get_relative_pos() + 5 self.mc.JMP_l(target - curpos) diff --git a/rpython/jit/backend/x86/regalloc.py b/rpython/jit/backend/x86/regalloc.py --- a/rpython/jit/backend/x86/regalloc.py +++ b/rpython/jit/backend/x86/regalloc.py @@ -1177,7 +1177,7 @@ self.final_jump_op = op descr = op.getdescr() assert isinstance(descr, TargetToken) - if descr._x86_loop_code != 0: + if descr._ll_loop_code != 0: # if the target LABEL was already compiled, i.e. if it belongs # to some already-compiled piece of code self._compute_hint_frame_locations_from_descr(descr) @@ -1289,7 +1289,7 @@ self.flush_loop() # descr._x86_arglocs = arglocs - descr._x86_loop_code = self.assembler.mc.get_relative_pos() + descr._ll_loop_code = self.assembler.mc.get_relative_pos() descr._x86_clt = self.assembler.current_clt self.assembler.target_tokens_currently_compiling[descr] = None self.possibly_free_vars_for_op(op) @@ -1355,6 +1355,6 @@ os.write(2, '[x86/regalloc] %s\n' % msg) raise NotImplementedError(msg) -# xxx hack: set a default value for TargetToken._x86_loop_code. +# xxx hack: set a default value for TargetToken._ll_loop_code. # If 0, we know that it is a LABEL that was not compiled yet. -TargetToken._x86_loop_code = 0 +TargetToken._ll_loop_code = 0 diff --git a/rpython/jit/backend/x86/runner.py b/rpython/jit/backend/x86/runner.py --- a/rpython/jit/backend/x86/runner.py +++ b/rpython/jit/backend/x86/runner.py @@ -57,6 +57,12 @@ def setup(self): self.assembler = Assembler386(self, self.translate_support_code) + def build_regalloc(self): + ''' for tests''' + from rpython.jit.backend.x86.regalloc import RegAlloc + assert self.assembler is not None + return RegAlloc(self.assembler, False) + def setup_once(self): self.profile_agent.startup() self.assembler.setup_once() diff --git a/rpython/jit/backend/x86/test/test_gc_integration.py b/rpython/jit/backend/x86/test/test_gc_integration.py deleted file mode 100644 --- a/rpython/jit/backend/x86/test/test_gc_integration.py +++ /dev/null @@ -1,647 +0,0 @@ - -""" Tests for register allocation for common constructs -""" - -from rpython.jit.metainterp.history import TargetToken, BasicFinalDescr,\ - JitCellToken, BasicFailDescr, AbstractDescr -from rpython.jit.backend.llsupport.gc import GcLLDescription, GcLLDescr_boehm,\ - GcLLDescr_framework, GcCache, JitFrameDescrs -from rpython.jit.backend.detect_cpu import getcpuclass -from rpython.jit.backend.x86.arch import WORD, JITFRAME_FIXED_SIZE, IS_X86_64 -from rpython.jit.backend.llsupport import jitframe -from rpython.rtyper.lltypesystem import lltype, llmemory, rffi -from rpython.rtyper.annlowlevel import llhelper, llhelper_args - -from rpython.jit.backend.x86.test.test_regalloc import BaseTestRegalloc -from rpython.jit.codewriter.effectinfo import EffectInfo -from rpython.rlib.objectmodel import invoke_around_extcall - -CPU = getcpuclass() - -class TestRegallocGcIntegration(BaseTestRegalloc): - - cpu = CPU(None, None) - cpu.gc_ll_descr = GcLLDescr_boehm(None, None, None) - cpu.setup_once() - - S = lltype.GcForwardReference() - S.become(lltype.GcStruct('S', ('field', lltype.Ptr(S)), - ('int', lltype.Signed))) - - fielddescr = cpu.fielddescrof(S, 'field') - - struct_ptr = lltype.malloc(S) - struct_ref = lltype.cast_opaque_ptr(llmemory.GCREF, struct_ptr) - child_ptr = lltype.nullptr(S) - struct_ptr.field = child_ptr - - - intdescr = cpu.fielddescrof(S, 'int') - ptr0 = struct_ref - - targettoken = TargetToken() - targettoken2 = TargetToken() - - namespace = locals().copy() - - def test_basic(self): - ops = ''' - [p0] - p1 = getfield_gc(p0, descr=fielddescr) - finish(p1) - ''' - self.interpret(ops, [self.struct_ptr]) - assert not self.getptr(0, lltype.Ptr(self.S)) - - def test_guard(self): - ops = ''' - [i0, p0, i1, p1] - p3 = getfield_gc(p0, descr=fielddescr) - guard_true(i0) [p0, i1, p1, p3] - ''' - s1 = lltype.malloc(self.S) - s2 = lltype.malloc(self.S) - s1.field = s2 - self.interpret(ops, [0, s1, 1, s2]) - frame = lltype.cast_opaque_ptr(jitframe.JITFRAMEPTR, self.deadframe) - # p0 and p3 should be in registers, p1 not so much - assert self.getptr(0, lltype.Ptr(self.S)) == s1 - # this is a fairly CPU specific check - assert len(frame.jf_gcmap) == 1 - # the gcmap should contain three things, p0, p1 and p3 - # p3 stays in a register - # while p0 and p1 are on the frame - if IS_X86_64: - nos = [11, 12, 31] - else: - nos = [4, 5, 25] - assert frame.jf_gcmap[0] == ((1 << nos[0]) | (1 << nos[1]) | - (1 << nos[2])) - assert frame.jf_frame[nos[0]] - assert frame.jf_frame[nos[1]] - assert frame.jf_frame[nos[2]] - - def test_rewrite_constptr(self): - ops = ''' - [] - p1 = getfield_gc(ConstPtr(struct_ref), descr=fielddescr) - finish(p1) - ''' - self.interpret(ops, []) - assert not self.getptr(0, lltype.Ptr(self.S)) - - def test_bug_0(self): - ops = ''' - [i0, i1, i2, i3, i4, i5, i6, i7, i8] - label(i0, i1, i2, i3, i4, i5, i6, i7, i8, descr=targettoken) - guard_value(i2, 1) [i2, i3, i4, i5, i6, i7, i0, i1, i8] - guard_class(i4, 138998336) [i4, i5, i6, i7, i0, i1, i8] - i11 = getfield_gc(i4, descr=intdescr) - guard_nonnull(i11) [i4, i5, i6, i7, i0, i1, i11, i8] - i13 = getfield_gc(i11, descr=intdescr) - guard_isnull(i13) [i4, i5, i6, i7, i0, i1, i11, i8] - i15 = getfield_gc(i4, descr=intdescr) - i17 = int_lt(i15, 0) - guard_false(i17) [i4, i5, i6, i7, i0, i1, i11, i15, i8] - i18 = getfield_gc(i11, descr=intdescr) - i19 = int_ge(i15, i18) - guard_false(i19) [i4, i5, i6, i7, i0, i1, i11, i15, i8] - i20 = int_lt(i15, 0) - guard_false(i20) [i4, i5, i6, i7, i0, i1, i11, i15, i8] - i21 = getfield_gc(i11, descr=intdescr) - i22 = getfield_gc(i11, descr=intdescr) - i23 = int_mul(i15, i22) - i24 = int_add(i21, i23) - i25 = getfield_gc(i4, descr=intdescr) - i27 = int_add(i25, 1) - setfield_gc(i4, i27, descr=intdescr) - i29 = getfield_raw(144839744, descr=intdescr) - i31 = int_and(i29, -2141192192) - i32 = int_is_true(i31) - guard_false(i32) [i4, i6, i7, i0, i1, i24] - i33 = getfield_gc(i0, descr=intdescr) - guard_value(i33, ConstPtr(ptr0)) [i4, i6, i7, i0, i1, i33, i24] - jump(i0, i1, 1, 17, i4, ConstPtr(ptr0), i6, i7, i24, descr=targettoken) - ''' - self.interpret(ops, [0, 0, 0, 0, 0, 0, 0, 0, 0], run=False) - -NOT_INITIALIZED = chr(0xdd) - -class GCDescrFastpathMalloc(GcLLDescription): - gcrootmap = None - passes_frame = True - write_barrier_descr = None - - def __init__(self, callback): - GcLLDescription.__init__(self, None) - # create a nursery - NTP = rffi.CArray(lltype.Char) - self.nursery = lltype.malloc(NTP, 64, flavor='raw') - for i in range(64): - self.nursery[i] = NOT_INITIALIZED - self.addrs = lltype.malloc(rffi.CArray(lltype.Signed), 2, - flavor='raw') - self.addrs[0] = rffi.cast(lltype.Signed, self.nursery) - self.addrs[1] = self.addrs[0] + 64 - self.calls = [] - def malloc_slowpath(size, frame): - if callback is not None: - callback(frame) - if self.gcrootmap is not None: # hook - self.gcrootmap.hook_malloc_slowpath() - self.calls.append(size) - # reset the nursery - nadr = rffi.cast(lltype.Signed, self.nursery) - self.addrs[0] = nadr + size - return nadr - self.generate_function('malloc_nursery', malloc_slowpath, - [lltype.Signed, jitframe.JITFRAMEPTR], - lltype.Signed) - - def get_nursery_free_addr(self): - return rffi.cast(lltype.Signed, self.addrs) - - def get_nursery_top_addr(self): - return rffi.cast(lltype.Signed, self.addrs) + WORD - - def get_malloc_slowpath_addr(self): - return self.get_malloc_fn_addr('malloc_nursery') - - def check_nothing_in_nursery(self): - # CALL_MALLOC_NURSERY should not write anything in the nursery - for i in range(64): - assert self.nursery[i] == NOT_INITIALIZED - -class TestMallocFastpath(BaseTestRegalloc): - - def teardown_method(self, method): - lltype.free(self.cpu.gc_ll_descr.addrs, flavor='raw') - lltype.free(self.cpu.gc_ll_descr.nursery, flavor='raw') - - def getcpu(self, callback): - cpu = CPU(None, None) - cpu.gc_ll_descr = GCDescrFastpathMalloc(callback) - cpu.setup_once() - return cpu - - def test_malloc_fastpath(self): - self.cpu = self.getcpu(None) - ops = ''' - [i0] - p0 = call_malloc_nursery(16) - p1 = call_malloc_nursery(32) - p2 = call_malloc_nursery(16) - guard_true(i0) [p0, p1, p2] - ''' - self.interpret(ops, [0]) - # check the returned pointers - gc_ll_descr = self.cpu.gc_ll_descr - nurs_adr = rffi.cast(lltype.Signed, gc_ll_descr.nursery) - ref = lambda n: self.cpu.get_ref_value(self.deadframe, n) - assert rffi.cast(lltype.Signed, ref(0)) == nurs_adr + 0 - assert rffi.cast(lltype.Signed, ref(1)) == nurs_adr + 16 - assert rffi.cast(lltype.Signed, ref(2)) == nurs_adr + 48 - # check the nursery content and state - gc_ll_descr.check_nothing_in_nursery() - assert gc_ll_descr.addrs[0] == nurs_adr + 64 - # slowpath never called - assert gc_ll_descr.calls == [] - - def test_malloc_nursery_varsize_small(self): - self.cpu = self.getcpu(None) - ops = ''' - [i0, i1, i2] - p0 = call_malloc_nursery_varsize_small(i0) - p1 = call_malloc_nursery_varsize_small(i1) - p2 = call_malloc_nursery_varsize_small(i2) - guard_true(i0) [p0, p1, p2] - ''' - self.interpret(ops, [16, 32, 16]) - # check the returned pointers - gc_ll_descr = self.cpu.gc_ll_descr - nurs_adr = rffi.cast(lltype.Signed, gc_ll_descr.nursery) - ref = lambda n: self.cpu.get_ref_value(self.deadframe, n) - assert rffi.cast(lltype.Signed, ref(0)) == nurs_adr + 0 - assert rffi.cast(lltype.Signed, ref(1)) == nurs_adr + 16 - assert rffi.cast(lltype.Signed, ref(2)) == nurs_adr + 48 - # check the nursery content and state - gc_ll_descr.check_nothing_in_nursery() - assert gc_ll_descr.addrs[0] == nurs_adr + 64 - # slowpath never called - assert gc_ll_descr.calls == [] - - def test_malloc_slowpath(self): - def check(frame): - assert len(frame.jf_gcmap) == 1 - if IS_X86_64: - assert frame.jf_gcmap[0] == (1<<29) | (1 << 30) - else: - assert frame.jf_gcmap[0] == (1<<24) | (1 << 23) - - self.cpu = self.getcpu(check) - ops = ''' - [i0] - p0 = call_malloc_nursery(16) - p1 = call_malloc_nursery(32) - p2 = call_malloc_nursery(24) # overflow - guard_true(i0) [p0, p1, p2] - ''' - self.interpret(ops, [0]) - # check the returned pointers - gc_ll_descr = self.cpu.gc_ll_descr - nurs_adr = rffi.cast(lltype.Signed, gc_ll_descr.nursery) - ref = lambda n: self.cpu.get_ref_value(self.deadframe, n) - assert rffi.cast(lltype.Signed, ref(0)) == nurs_adr + 0 - assert rffi.cast(lltype.Signed, ref(1)) == nurs_adr + 16 - assert rffi.cast(lltype.Signed, ref(2)) == nurs_adr + 0 - # check the nursery content and state - gc_ll_descr.check_nothing_in_nursery() - assert gc_ll_descr.addrs[0] == nurs_adr + 24 - # this should call slow path once - assert gc_ll_descr.calls == [24] - - def test_save_regs_around_malloc(self): - def check(frame): - x = frame.jf_gcmap - if IS_X86_64: - assert len(x) == 1 - assert (bin(x[0]).count('1') == - '0b1111100000000000000001111111011110'.count('1')) - else: - assert len(x) == 2 - s = bin(x[0]).count('1') + bin(x[1]).count('1') - assert s == 16 - # all but two registers + some stuff on stack - - self.cpu = self.getcpu(check) - S1 = lltype.GcStruct('S1') - S2 = lltype.GcStruct('S2', ('s0', lltype.Ptr(S1)), - ('s1', lltype.Ptr(S1)), - ('s2', lltype.Ptr(S1)), - ('s3', lltype.Ptr(S1)), - ('s4', lltype.Ptr(S1)), - ('s5', lltype.Ptr(S1)), - ('s6', lltype.Ptr(S1)), - ('s7', lltype.Ptr(S1)), - ('s8', lltype.Ptr(S1)), - ('s9', lltype.Ptr(S1)), - ('s10', lltype.Ptr(S1)), - ('s11', lltype.Ptr(S1)), - ('s12', lltype.Ptr(S1)), - ('s13', lltype.Ptr(S1)), - ('s14', lltype.Ptr(S1)), - ('s15', lltype.Ptr(S1))) - cpu = self.cpu - self.namespace = self.namespace.copy() - for i in range(16): - self.namespace['ds%i' % i] = cpu.fielddescrof(S2, 's%d' % i) - ops = ''' - [i0, p0] - p1 = getfield_gc(p0, descr=ds0) - p2 = getfield_gc(p0, descr=ds1) - p3 = getfield_gc(p0, descr=ds2) - p4 = getfield_gc(p0, descr=ds3) - p5 = getfield_gc(p0, descr=ds4) - p6 = getfield_gc(p0, descr=ds5) - p7 = getfield_gc(p0, descr=ds6) - p8 = getfield_gc(p0, descr=ds7) - p9 = getfield_gc(p0, descr=ds8) - p10 = getfield_gc(p0, descr=ds9) - p11 = getfield_gc(p0, descr=ds10) - p12 = getfield_gc(p0, descr=ds11) - p13 = getfield_gc(p0, descr=ds12) - p14 = getfield_gc(p0, descr=ds13) - p15 = getfield_gc(p0, descr=ds14) - p16 = getfield_gc(p0, descr=ds15) - # - # now all registers are in use - p17 = call_malloc_nursery(40) - p18 = call_malloc_nursery(40) # overflow - # - guard_true(i0) [p1, p2, p3, p4, p5, p6, \ - p7, p8, p9, p10, p11, p12, p13, p14, p15, p16] - ''' - s2 = lltype.malloc(S2) - for i in range(16): - setattr(s2, 's%d' % i, lltype.malloc(S1)) - s2ref = lltype.cast_opaque_ptr(llmemory.GCREF, s2) - # - self.interpret(ops, [0, s2ref]) - gc_ll_descr = cpu.gc_ll_descr - gc_ll_descr.check_nothing_in_nursery() - assert gc_ll_descr.calls == [40] - # check the returned pointers - for i in range(16): - s1ref = self.cpu.get_ref_value(self.deadframe, i) - s1 = lltype.cast_opaque_ptr(lltype.Ptr(S1), s1ref) - assert s1 == getattr(s2, 's%d' % i) - -class MockShadowStackRootMap(object): - is_shadow_stack = True - - def __init__(self): - TP = rffi.CArray(lltype.Signed) - self.stack = lltype.malloc(TP, 10, flavor='raw') - self.stack_addr = lltype.malloc(TP, 1, - flavor='raw') - self.stack_addr[0] = rffi.cast(lltype.Signed, self.stack) - - def __del__(self): - lltype.free(self.stack_addr, flavor='raw') - lltype.free(self.stack, flavor='raw') - - def register_asm_addr(self, start, mark): - pass - - def get_root_stack_top_addr(self): - return rffi.cast(lltype.Signed, self.stack_addr) - -class WriteBarrierDescr(AbstractDescr): - jit_wb_cards_set = 0 - jit_wb_if_flag_singlebyte = 1 - - def __init__(self, gc_ll_descr): - def write_barrier(frame): - gc_ll_descr.write_barrier_on_frame_called = frame - - self.write_barrier_fn = llhelper_args(write_barrier, - [lltype.Signed], lltype.Void) - - def get_write_barrier_fn(self, cpu): - return self.write_barrier_fn - -# a copy of JITFRAM that has 'hdr' field for tests - -def jitframe_allocate(frame_info): - frame = lltype.malloc(JITFRAME, frame_info.jfi_frame_depth, zero=True) - frame.jf_frame_info = frame_info - return frame - -JITFRAME = lltype.GcStruct( - 'JITFRAME', - ('hdr', lltype.Signed), - ('jf_frame_info', lltype.Ptr(jitframe.JITFRAMEINFO)), - ('jf_descr', llmemory.GCREF), - ('jf_force_descr', llmemory.GCREF), - ('jf_guard_exc', llmemory.GCREF), - ('jf_gcmap', lltype.Ptr(jitframe.GCMAP)), - ('jf_gc_trace_state', lltype.Signed), - ('jf_frame', lltype.Array(lltype.Signed)), - adtmeths = { - 'allocate': jitframe_allocate, - }, -) - -JITFRAMEPTR = lltype.Ptr(JITFRAME) - -class GCDescrShadowstackDirect(GcLLDescr_framework): - layoutbuilder = None - - class GCClass: - JIT_WB_IF_FLAG = 0 - - def __init__(self): - GcCache.__init__(self, False, None) - self._generated_functions = [] - self.gcrootmap = MockShadowStackRootMap() - self.write_barrier_descr = WriteBarrierDescr(self) - self.nursery_ptrs = lltype.malloc(rffi.CArray(lltype.Signed), 2, - flavor='raw') - self._initialize_for_tests() - self.frames = [] - - def malloc_slowpath(size): - self._collect() - res = self.nursery_ptrs[0] - self.nursery_ptrs[0] += size - return res - - self.malloc_slowpath_fnptr = llhelper_args(malloc_slowpath, - [lltype.Signed], - lltype.Signed) - self.all_nurseries = [] - - def init_nursery(self, nursery_size=None): - if nursery_size is None: - nursery_size = self.nursery_size - else: - self.nursery_size = nursery_size - self.nursery = lltype.malloc(rffi.CArray(lltype.Char), nursery_size, - flavor='raw', zero=True, - track_allocation=False) - self.nursery_ptrs[0] = rffi.cast(lltype.Signed, self.nursery) - self.nursery_ptrs[1] = self.nursery_ptrs[0] + nursery_size - self.nursery_addr = rffi.cast(lltype.Signed, self.nursery_ptrs) - self.all_nurseries.append(self.nursery) - if hasattr(self, 'collections'): - self.collections.reverse() - - def _collect(self): - gcmap = unpack_gcmap(self.frames[-1]) - col = self.collections.pop() - frame = self.frames[-1].jf_frame - start = rffi.cast(lltype.Signed, self.nursery) - assert len(gcmap) == len(col) - pos = [frame[item] for item in gcmap] - pos.sort() - for i in range(len(gcmap)): - assert col[i] + start == pos[i] - self.frames[-1].hdr |= 1 - self.init_nursery() - - def malloc_jitframe(self, frame_info): - """ Allocate a new frame, overwritten by tests - """ - frame = JITFRAME.allocate(frame_info) - self.frames.append(frame) - return frame - - def getframedescrs(self, cpu): - descrs = JitFrameDescrs() - descrs.arraydescr = cpu.arraydescrof(JITFRAME) - for name in ['jf_descr', 'jf_guard_exc', 'jf_force_descr', - 'jf_frame_info', 'jf_gcmap']: - setattr(descrs, name, cpu.fielddescrof(JITFRAME, name)) - descrs.jfi_frame_depth = cpu.fielddescrof(jitframe.JITFRAMEINFO, - 'jfi_frame_depth') - descrs.jfi_frame_size = cpu.fielddescrof(jitframe.JITFRAMEINFO, - 'jfi_frame_size') - return descrs - - def do_write_barrier(self, gcref_struct, gcref_newptr): - pass - - def get_malloc_slowpath_addr(self): - return self.malloc_slowpath_fnptr - - def get_nursery_free_addr(self): - return self.nursery_addr - - def get_nursery_top_addr(self): - return self.nursery_addr + rffi.sizeof(lltype.Signed) - - def __del__(self): - for nursery in self.all_nurseries: - lltype.free(nursery, flavor='raw', track_allocation=False) - lltype.free(self.nursery_ptrs, flavor='raw') - -def unpack_gcmap(frame): From noreply at buildbot.pypy.org Fri Feb 15 15:19:20 2013 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 15 Feb 2013 15:19:20 +0100 (CET) Subject: [pypy-commit] cffi default: Add a warning about "x[:]=string" (thanks David). Message-ID: <20130215141920.E41311C062C@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r1158:66a586f814c3 Date: 2013-02-15 15:19 +0100 http://bitbucket.org/cffi/cffi/changeset/66a586f814c3/ Log: Add a warning about "x[:]=string" (thanks David). diff --git a/doc/source/index.rst b/doc/source/index.rst --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -1368,6 +1368,9 @@ As with indexing, negative bounds mean really negative indices, like in C. As for slice assignment, it accepts any iterable, including a list of items or another array-like cdata object, but the length must match. + (Note that this behavior differs from initialization: e.g. if you pass + a string when assigning to a slice of a ``char`` array, it must be of + the correct length; no implicit null character is added.) .. versionchanged:: 0.6 `(*****)` Enums are now handled like ints (unsigned or signed, int or From noreply at buildbot.pypy.org Fri Feb 15 15:36:24 2013 From: noreply at buildbot.pypy.org (bivab) Date: Fri, 15 Feb 2013 15:36:24 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: move shared initialization of the assembler classes to llsupport Message-ID: <20130215143624.560081C0673@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: jitframe-on-heap Changeset: r61265:1767fd94f261 Date: 2013-02-15 15:35 +0100 http://bitbucket.org/pypy/pypy/changeset/1767fd94f261/ Log: move shared initialization of the assembler classes to llsupport diff --git a/rpython/jit/backend/arm/assembler.py b/rpython/jit/backend/arm/assembler.py --- a/rpython/jit/backend/arm/assembler.py +++ b/rpython/jit/backend/arm/assembler.py @@ -33,7 +33,6 @@ from rpython.rlib.objectmodel import compute_unique_id from rpython.rlib.rarithmetic import intmask, r_uint -from rpython.jit.backend.arm.support import memcpy_fn DEBUG_COUNTER = lltype.Struct('DEBUG_COUNTER', ('i', lltype.Signed), ('type', lltype.Char), # 'b'ridge, 'l'abel or @@ -46,10 +45,9 @@ debug = True def __init__(self, cpu, translate_support_code=False): - self.cpu = cpu + ResOpAssembler.__init__(self, cpu, translate_support_code) self.setup_failure_recovery() self.mc = None - self.memcpy_addr = 0 self.pending_guards = None self._exit_code_addr = 0 self.current_clt = None @@ -87,40 +85,6 @@ self.pending_guards = None assert self.datablockwrapper is None - def setup_once(self): - # Addresses of functions called by new_xxx operations - gc_ll_descr = self.cpu.gc_ll_descr - gc_ll_descr.initialize() - self.memcpy_addr = self.cpu.cast_ptr_to_int(memcpy_fn) - self._build_failure_recovery(exc=True, withfloats=False) - self._build_failure_recovery(exc=False, withfloats=False) - self._build_wb_slowpath(False) - self._build_wb_slowpath(True) - self._build_stack_check_failure() - if self.cpu.supports_floats: - self._build_wb_slowpath(False, withfloats=True) - self._build_wb_slowpath(True, withfloats=True) - self._build_failure_recovery(exc=True, withfloats=True) - self._build_failure_recovery(exc=False, withfloats=True) - self._build_propagate_exception_path() - if gc_ll_descr.get_malloc_slowpath_addr is not None: - self._build_malloc_slowpath() - self._build_stack_check_slowpath() - if gc_ll_descr.gcrootmap and gc_ll_descr.gcrootmap.is_shadow_stack: - self._build_release_gil(gc_ll_descr.gcrootmap) - - if not self._debug: - # if self._debug is already set it means that someone called - # set_debug by hand before initializing the assembler. Leave it - # as it is - debug_start('jit-backend-counts') - self.set_debug(have_debug_prints()) - debug_stop('jit-backend-counts') - # when finishing, we only have one value at [0], the rest dies - self.gcmap_for_finish = lltype.malloc(jitframe.GCMAP, 1, - flavor='raw', immortal=True) - self.gcmap_for_finish[0] = r_uint(1) - def setup_failure_recovery(self): self.failure_recovery_code = [0, 0, 0, 0] @@ -302,7 +266,7 @@ rawstart = mc.materialize(self.cpu.asmmemmgr, []) self.stack_check_slowpath = rawstart - def _build_wb_slowpath(self, withcards, withfloats=False): + def _build_wb_slowpath(self, withcards, withfloats=False, for_frame=False): descr = self.cpu.gc_ll_descr.write_barrier_descr if descr is None: return diff --git a/rpython/jit/backend/arm/support.py b/rpython/jit/backend/arm/support.py --- a/rpython/jit/backend/arm/support.py +++ b/rpython/jit/backend/arm/support.py @@ -52,10 +52,3 @@ _callable=arm_int_mod_emulator, compilation_info=eci, _nowrapper=True, elidable_function=True) -# ____________________________________________________________ - -memcpy_fn = rffi.llexternal('memcpy', [llmemory.Address, llmemory.Address, - rffi.SIZE_T], lltype.Void, - sandboxsafe=True, _nowrapper=True) - -# ____________________________________________________________ diff --git a/rpython/jit/backend/llsupport/assembler.py b/rpython/jit/backend/llsupport/assembler.py --- a/rpython/jit/backend/llsupport/assembler.py +++ b/rpython/jit/backend/llsupport/assembler.py @@ -2,9 +2,13 @@ from rpython.rlib import rgc from rpython.rlib.rarithmetic import r_uint from rpython.jit.backend.llsupport.symbolic import WORD +from rpython.jit.backend.llsupport import jitframe from rpython.jit.metainterp.history import INT, REF, FLOAT, JitCellToken from rpython.rtyper.annlowlevel import cast_instance_to_gcref from rpython.rtyper.lltypesystem import rffi, lltype +from rpython.jit.backend.llsupport.memcpy import memcpy_fn +from rpython.rlib.debug import (debug_print, debug_start, debug_stop, + have_debug_prints) class GuardToken(object): def __init__(self, cpu, gcmap, faildescr, failargs, fail_locs, exc, @@ -43,6 +47,47 @@ class BaseAssembler(object): """ Base class for Assembler generator in real backends """ + + def __init__(self, cpu, translate_support_code=False): + self.cpu = cpu + self.memcpy_addr = 0 + self.rtyper = cpu.rtyper + + def setup_once(self): + # the address of the function called by 'new' + gc_ll_descr = self.cpu.gc_ll_descr + gc_ll_descr.initialize() + self.memcpy_addr = self.cpu.cast_ptr_to_int(memcpy_fn) + self._build_failure_recovery(False, withfloats=False) + self._build_failure_recovery(True, withfloats=False) + self._build_wb_slowpath(False) + self._build_wb_slowpath(True) + self._build_wb_slowpath(False, for_frame=True) + # only one of those + self._build_stack_check_failure() + if self.cpu.supports_floats: + self._build_failure_recovery(False, withfloats=True) + self._build_failure_recovery(True, withfloats=True) + self._build_wb_slowpath(False, withfloats=True) + self._build_wb_slowpath(True, withfloats=True) + self._build_propagate_exception_path() + if gc_ll_descr.get_malloc_slowpath_addr is not None: + self._build_malloc_slowpath() + self._build_stack_check_slowpath() + if gc_ll_descr.gcrootmap: + self._build_release_gil(gc_ll_descr.gcrootmap) + if not self._debug: + # if self._debug is already set it means that someone called + # set_debug by hand before initializing the assembler. Leave it + # as it is + debug_start('jit-backend-counts') + self.set_debug(have_debug_prints()) + debug_stop('jit-backend-counts') + # when finishing, we only have one value at [0], the rest dies + self.gcmap_for_finish = lltype.malloc(jitframe.GCMAP, 1, + flavor='raw', immortal=True) + self.gcmap_for_finish[0] = r_uint(1) + def rebuild_faillocs_from_descr(self, descr, inputargs): locs = [] GPR_REGS = len(self.cpu.gen_regs) diff --git a/rpython/jit/backend/llsupport/memcpy.py b/rpython/jit/backend/llsupport/memcpy.py new file mode 100644 --- /dev/null +++ b/rpython/jit/backend/llsupport/memcpy.py @@ -0,0 +1,5 @@ +from rpython.rtyper.lltypesystem import lltype, rffi, llmemory + +memcpy_fn = rffi.llexternal('memcpy', [llmemory.Address, llmemory.Address, + rffi.SIZE_T], lltype.Void, + sandboxsafe=True, _nowrapper=True) diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -54,15 +54,13 @@ _second_tmp_reg = ecx def __init__(self, cpu, translate_support_code=False): - self.cpu = cpu + BaseAssembler.__init__(self, cpu, translate_support_code) self.verbose = False - self.rtyper = cpu.rtyper self.loop_run_counters = [] self.float_const_neg_addr = 0 self.float_const_abs_addr = 0 self.malloc_slowpath = 0 self.wb_slowpath = [0, 0, 0, 0, 0] - self.memcpy_addr = 0 self.setup_failure_recovery() self._debug = False self.debug_counter_descr = cpu.fielddescrof(DEBUG_COUNTER, 'i') @@ -78,41 +76,10 @@ return r def setup_once(self): - # the address of the function called by 'new' - gc_ll_descr = self.cpu.gc_ll_descr - gc_ll_descr.initialize() - self.memcpy_addr = self.cpu.cast_ptr_to_int(support.memcpy_fn) - self._build_failure_recovery(False) - self._build_failure_recovery(True) - self._build_wb_slowpath(False) - self._build_wb_slowpath(True) - self._build_wb_slowpath(False, for_frame=True) - # only one of those - self._build_stack_check_failure() + BaseAssembler.setup_once(self) if self.cpu.supports_floats: - self._build_failure_recovery(False, withfloats=True) - self._build_failure_recovery(True, withfloats=True) - self._build_wb_slowpath(False, withfloats=True) - self._build_wb_slowpath(True, withfloats=True) support.ensure_sse2_floats() self._build_float_constants() - self._build_propagate_exception_path() - if gc_ll_descr.get_malloc_slowpath_addr is not None: - self._build_malloc_slowpath() - self._build_stack_check_slowpath() - if gc_ll_descr.gcrootmap: - self._build_release_gil(gc_ll_descr.gcrootmap) - if not self._debug: - # if self._debug is already set it means that someone called - # set_debug by hand before initializing the assembler. Leave it - # as it is - debug_start('jit-backend-counts') - self.set_debug(have_debug_prints()) - debug_stop('jit-backend-counts') - # when finishing, we only have one value at [0], the rest dies - self.gcmap_for_finish = lltype.malloc(jitframe.GCMAP, 1, - flavor='raw', immortal=True) - self.gcmap_for_finish[0] = r_uint(1) def setup(self, looptoken): assert self.memcpy_addr != 0, "setup_once() not called?" diff --git a/rpython/jit/backend/x86/support.py b/rpython/jit/backend/x86/support.py --- a/rpython/jit/backend/x86/support.py +++ b/rpython/jit/backend/x86/support.py @@ -1,16 +1,8 @@ import sys -from rpython.rtyper.lltypesystem import lltype, rffi, llmemory +from rpython.rtyper.lltypesystem import rffi from rpython.translator.tool.cbuild import ExternalCompilationInfo from rpython.jit.backend.x86.arch import WORD -# ____________________________________________________________ - -memcpy_fn = rffi.llexternal('memcpy', [llmemory.Address, llmemory.Address, - rffi.SIZE_T], lltype.Void, - sandboxsafe=True, _nowrapper=True) - -# ____________________________________________________________ - if WORD == 4: extra = ['-DPYPY_X86_CHECK_SSE2'] else: From noreply at buildbot.pypy.org Fri Feb 15 16:05:23 2013 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 15 Feb 2013 16:05:23 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: clean up Message-ID: <20130215150523.A0EC81C10E6@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61266:c9ef8d769b0b Date: 2013-02-15 17:04 +0200 http://bitbucket.org/pypy/pypy/changeset/c9ef8d769b0b/ Log: clean up diff --git a/rpython/jit/backend/llsupport/assembler.py b/rpython/jit/backend/llsupport/assembler.py --- a/rpython/jit/backend/llsupport/assembler.py +++ b/rpython/jit/backend/llsupport/assembler.py @@ -147,7 +147,7 @@ guardtok.faildescr.rd_loop_token = self.current_clt return fail_descr, target - def call_assembler(self, op, guard_op, frame_loc, argloc, + def call_assembler(self, op, guard_op, argloc, vloc, result_loc, tmploc): self._store_force_index(guard_op) descr = op.getdescr() diff --git a/rpython/jit/backend/llsupport/regalloc.py b/rpython/jit/backend/llsupport/regalloc.py --- a/rpython/jit/backend/llsupport/regalloc.py +++ b/rpython/jit/backend/llsupport/regalloc.py @@ -671,13 +671,11 @@ descr = op.getdescr() assert isinstance(descr, JitCellToken) arglist = op.getarglist() - self.rm._sync_var(arglist[0]) - frame_loc = self.fm.loc(op.getarg(0)) if len(arglist) == 2: self.rm._sync_var(arglist[1]) - return [frame_loc, self.loc(arglist[0]), self.fm.loc(arglist[1])] + return [self.loc(arglist[0]), self.fm.loc(arglist[1])] else: - return [frame_loc, self.loc(arglist[0])] + return [self.loc(arglist[0])] def compute_vars_longevity(inputargs, operations): diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -2174,12 +2174,11 @@ def genop_guard_call_assembler(self, op, guard_op, guard_token, arglocs, result_loc): if len(arglocs) == 3: - [frame_loc, argloc, vloc] = arglocs + [argloc, vloc] = arglocs else: - [frame_loc, argloc] = arglocs + [argloc] = arglocs vloc = self.imm(0) - self.call_assembler(op, guard_op, frame_loc, argloc, vloc, - result_loc, eax) + self.call_assembler(op, guard_op, argloc, vloc, result_loc, eax) self._emit_guard_not_forced(guard_token) def _call_assembler_check_descr(self, value, tmploc): From noreply at buildbot.pypy.org Fri Feb 15 17:18:23 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Fri, 15 Feb 2013 17:18:23 +0100 (CET) Subject: [pypy-commit] pypy default: a flag to allow skipping argument checking in the jit driver when untranslated, this can take a lot of time Message-ID: <20130215161823.0B6231C00A8@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r61267:912ec202eba7 Date: 2013-02-15 08:17 -0800 http://bitbucket.org/pypy/pypy/changeset/912ec202eba7/ Log: a flag to allow skipping argument checking in the jit driver when untranslated, this can take a lot of time diff --git a/rpython/rlib/jit.py b/rpython/rlib/jit.py --- a/rpython/rlib/jit.py +++ b/rpython/rlib/jit.py @@ -476,7 +476,7 @@ get_jitcell_at=None, set_jitcell_at=None, get_printable_location=None, confirm_enter_jit=None, can_never_inline=None, should_unroll_one_iteration=None, - name='jitdriver'): + name='jitdriver', check_untranslated=True): if greens is not None: self.greens = greens self.name = name @@ -511,6 +511,7 @@ self.confirm_enter_jit = confirm_enter_jit self.can_never_inline = can_never_inline self.should_unroll_one_iteration = should_unroll_one_iteration + self.check_untranslated = check_untranslated def _freeze_(self): return True @@ -565,13 +566,15 @@ def jit_merge_point(_self, **livevars): # special-cased by ExtRegistryEntry - _self._check_arguments(livevars) + if _self.check_untranslated: + _self._check_arguments(livevars) def can_enter_jit(_self, **livevars): if _self.autoreds: raise TypeError, "Cannot call can_enter_jit on a driver with reds='auto'" # special-cased by ExtRegistryEntry - _self._check_arguments(livevars) + if _self.check_untranslated: + _self._check_arguments(livevars) def loop_header(self): # special-cased by ExtRegistryEntry diff --git a/rpython/rtyper/lltypesystem/rlist.py b/rpython/rtyper/lltypesystem/rlist.py --- a/rpython/rtyper/lltypesystem/rlist.py +++ b/rpython/rtyper/lltypesystem/rlist.py @@ -246,6 +246,7 @@ of the list to be 'newsize'.""" _ll_list_resize_really(l, newsize, False) + @jit.look_inside_iff(lambda l, newsize: jit.isconstant(len(l.items)) and jit.isconstant(newsize)) @jit.oopspec("list._resize_ge(l, newsize)") def _ll_list_resize_ge(l, newsize): From noreply at buildbot.pypy.org Fri Feb 15 17:18:24 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Fri, 15 Feb 2013 17:18:24 +0100 (CET) Subject: [pypy-commit] pypy default: merged upstream Message-ID: <20130215161824.990291C00A8@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r61268:71233ccceb29 Date: 2013-02-15 08:18 -0800 http://bitbucket.org/pypy/pypy/changeset/71233ccceb29/ Log: merged upstream diff --git a/pypy/interpreter/test2/test_app_main.py b/pypy/interpreter/test2/test_app_main.py --- a/pypy/interpreter/test2/test_app_main.py +++ b/pypy/interpreter/test2/test_app_main.py @@ -208,11 +208,6 @@ These tests require pexpect (UNIX-only). http://pexpect.sourceforge.net/ """ - def setup_class(cls): - # some tests need to be able to import test2, change the cwd - goal_dir = os.path.abspath(os.path.join(os.path.realpath(os.path.dirname(__file__)), '..')) - os.chdir(goal_dir) - def _spawn(self, *args, **kwds): try: import pexpect @@ -456,13 +451,14 @@ child.expect('789') # expect to see it before the timeout hits child.sendline('X') - def test_options_i_m(self): + def test_options_i_m(self, monkeypatch): if sys.platform == "win32": skip("close_fds is not supported on Windows platforms") if not hasattr(runpy, '_run_module_as_main'): skip("requires CPython >= 2.6") p = os.path.join(os.path.realpath(os.path.dirname(__file__)), 'mymodule.py') p = os.path.abspath(p) + monkeypatch.chdir(os.path.dirname(app_main)) child = self.spawn(['-i', '-m', 'test2.mymodule', 'extra']) @@ -562,12 +558,13 @@ child.sendline('Not at all. They could be carried.') child.expect('A five ounce bird could not carry a one pound coconut.') - def test_no_space_before_argument(self): + def test_no_space_before_argument(self, monkeypatch): if not hasattr(runpy, '_run_module_as_main'): skip("requires CPython >= 2.6") child = self.spawn(['-cprint "hel" + "lo"']) child.expect('hello') + monkeypatch.chdir(os.path.dirname(app_main)) child = self.spawn(['-mtest2.mymodule']) child.expect('mymodule running') @@ -667,11 +664,12 @@ '-c "import sys; print sys.warnoptions"') assert "['ignore', 'default', 'once', 'error']" in data - def test_option_m(self): + def test_option_m(self, monkeypatch): if not hasattr(runpy, '_run_module_as_main'): skip("requires CPython >= 2.6") p = os.path.join(os.path.realpath(os.path.dirname(__file__)), 'mymodule.py') p = os.path.abspath(p) + monkeypatch.chdir(os.path.dirname(app_main)) data = self.run('-m test2.mymodule extra') assert 'mymodule running' in data assert 'Name: __main__' in data diff --git a/pypy/module/micronumpy/test/test_module.py b/pypy/module/micronumpy/test/test_module.py --- a/pypy/module/micronumpy/test/test_module.py +++ b/pypy/module/micronumpy/test/test_module.py @@ -13,11 +13,13 @@ assert sum(array(range(10))) == 45 def test_min(self): - from _numpypy import array, min + from _numpypy import array, min, zeros assert min(range(10)) == 0 assert min(array(range(10))) == 0 + assert list(min(zeros((0, 2)), axis=1)) == [] def test_max(self): - from _numpypy import array, max + from _numpypy import array, max, zeros assert max(range(10)) == 9 assert max(array(range(10))) == 9 + assert list(max(zeros((0, 2)), axis=1)) == [] diff --git a/pypy/module/micronumpy/test/test_numarray.py b/pypy/module/micronumpy/test/test_numarray.py --- a/pypy/module/micronumpy/test/test_numarray.py +++ b/pypy/module/micronumpy/test/test_numarray.py @@ -1662,13 +1662,13 @@ b = array([0, 1, 2], dtype=complex).astype(bool) assert (b == [False, True, True]).all() assert b.dtype == 'bool' - + a = arange(6, dtype='f4').reshape(2,3) b = a.astype('i4') a = array('x').astype('S3').dtype assert a.itemsize == 3 - + def test_base(self): from _numpypy import array assert array(1).base is None @@ -1679,6 +1679,11 @@ def test_byteswap(self): from _numpypy import array + + s1 = array(1.).byteswap().tostring() + s2 = array([1.]).byteswap().tostring() + assert s1 == s2 + a = array([1, 256 + 2, 3], dtype='i2') assert (a.byteswap() == [0x0100, 0x0201, 0x0300]).all() assert (a == [1, 256 + 2, 3]).all() @@ -1686,39 +1691,40 @@ assert (a == [0x0100, 0x0201, 0x0300]).all() a = array([1, -1, 1e300], dtype=float) - s1 = map(ord,a.tostring()) + s1 = map(ord, a.tostring()) s2 = map(ord, a.byteswap().tostring()) - assert s1[7::-1] == s2[:8] - assert s1[15:7:-1] == s2[8:16] - assert s1[:15:-1] == s2[16:] + assert a.dtype.itemsize == 8 + for i in range(a.size): + i1 = i * a.dtype.itemsize + i2 = (i+1) * a.dtype.itemsize + assert list(reversed(s1[i1:i2])) == s2[i1:i2] a = array([1+1e30j, -1, 1e10], dtype=complex) - s1 = map(ord,a.tostring()) + s1 = map(ord, a.tostring()) s2 = map(ord, a.byteswap().tostring()) - assert s1[7::-1] == s2[:8] - assert s1[15:7:-1] == s2[8:16] - assert s1[23:15:-1] == s2[16:24] - assert s1[31:23:-1] == s2[24:32] - assert s1[39:31:-1] == s2[32:40] - assert s1[:39:-1] == s2[40:] + assert a.dtype.itemsize == 16 + for i in range(a.size*2): + i1 = i * a.dtype.itemsize/2 + i2 = (i+1) * a.dtype.itemsize/2 + assert list(reversed(s1[i1:i2])) == s2[i1:i2] a = array([3.14, -1.5, 10000], dtype='float16') - s1 = map(ord,a.tostring()) + s1 = map(ord, a.tostring()) s2 = map(ord, a.byteswap().tostring()) - s3 = [s1[1], s1[0],s1[3], s1[2], s1[5], s1[4]] - assert s3 == s2 + assert a.dtype.itemsize == 2 + for i in range(a.size): + i1 = i * a.dtype.itemsize + i2 = (i+1) * a.dtype.itemsize + assert list(reversed(s1[i1:i2])) == s2[i1:i2] a = array([1, -1, 10000], dtype='longfloat') - s1 = map(ord,a.tostring()) - s2 = map(ord, a.byteswap().tostring()) - n = a.dtype.itemsize - assert s1[n-1] == s2[0] - - a = array(0., dtype='longfloat') s1 = map(ord, a.tostring()) s2 = map(ord, a.byteswap().tostring()) - n = a.dtype.itemsize - assert s1[n-1] == s2[0] + assert a.dtype.itemsize >= 8 + for i in range(a.size): + i1 = i * a.dtype.itemsize + i2 = (i+1) * a.dtype.itemsize + assert list(reversed(s1[i1:i2])) == s2[i1:i2] def test_clip(self): from _numpypy import array diff --git a/pypy/module/micronumpy/types.py b/pypy/module/micronumpy/types.py --- a/pypy/module/micronumpy/types.py +++ b/pypy/module/micronumpy/types.py @@ -14,8 +14,8 @@ from rpython.rtyper.lltypesystem import lltype, rffi from rpython.rlib.rstruct.runpack import runpack from rpython.rlib.rstruct.nativefmttable import native_is_bigendian -from rpython.rlib.rstruct.ieee import (float_pack, float_unpack, pack_float80, - unpack_float, unpack_float128) +from rpython.rlib.rstruct.ieee import (float_pack, float_unpack, unpack_float, + pack_float80, unpack_float80) from rpython.tool.sourcetools import func_with_new_name from rpython.rlib import jit from rpython.rlib.rstring import StringBuilder @@ -958,7 +958,6 @@ swapped_value = byteswap(rffi.cast(self.T, value)) raw_storage_setitem(storage, i + offset, swapped_value) - class Float32(BaseType, Float): _attrs_ = () @@ -1505,7 +1504,6 @@ BoxType = interp_boxes.W_Complex64Box ComponentBoxType = interp_boxes.W_Float32Box - NonNativeComplex64 = Complex64 class Complex128(ComplexFloating, BaseType): @@ -1515,7 +1513,6 @@ BoxType = interp_boxes.W_Complex128Box ComponentBoxType = interp_boxes.W_Float64Box - NonNativeComplex128 = Complex128 if interp_boxes.long_double_size == 12: @@ -1528,17 +1525,16 @@ def runpack_str(self, s): assert len(s) == 12 - fval = unpack_float128(s, native_is_bigendian) + fval = unpack_float80(s, native_is_bigendian) return self.box(fval) def byteswap(self, w_v): value = self.unbox(w_v) result = StringBuilder(12) - pack_float80(result, value, 12, not native_is_bigendian) - return self.box(unpack_float128(result.build(), native_is_bigendian)) + pack_float80(result, value, not native_is_bigendian) + return self.box(unpack_float80(result.build(), native_is_bigendian)) - class NonNativeFloat96(Float96): - pass + NonNativeFloat96 = Float96 class Complex192(ComplexFloating, BaseType): _attrs_ = () @@ -1549,7 +1545,6 @@ NonNativeComplex192 = Complex192 - elif interp_boxes.long_double_size == 16: class Float128(BaseType, Float): _attrs_ = () @@ -1560,14 +1555,14 @@ def runpack_str(self, s): assert len(s) == 16 - fval = unpack_float128(s, native_is_bigendian) + fval = unpack_float80(s, native_is_bigendian) return self.box(fval) def byteswap(self, w_v): value = self.unbox(w_v) result = StringBuilder(16) - pack_float80(result, value, 16, not native_is_bigendian) - return self.box(unpack_float128(result.build(), native_is_bigendian)) + pack_float80(result, value, not native_is_bigendian) + return self.box(unpack_float80(result.build(), native_is_bigendian)) NonNativeFloat128 = Float128 @@ -1578,7 +1573,6 @@ BoxType = interp_boxes.W_Complex256Box ComponentBoxType = interp_boxes.W_Float128Box - NonNativeComplex256 = Complex256 class BaseStringType(object): diff --git a/pypy/module/sys/initpath.py b/pypy/module/sys/initpath.py --- a/pypy/module/sys/initpath.py +++ b/pypy/module/sys/initpath.py @@ -67,6 +67,8 @@ stdlib. If it cannot be found, return (None, None). """ + if executable == '': + return None, None search = executable while True: dirname = resolvedirof(search) diff --git a/pypy/module/sys/test/test_initpath.py b/pypy/module/sys/test/test_initpath.py --- a/pypy/module/sys/test/test_initpath.py +++ b/pypy/module/sys/test/test_initpath.py @@ -10,12 +10,15 @@ b = prefix.join('lib-python', dirname).ensure(dir=1) return a, b -def test_find_stdlib(tmpdir): +def test_find_stdlib(tmpdir, monkeypatch): bin_dir = tmpdir.join('bin').ensure(dir=True) pypy = bin_dir.join('pypy').ensure(file=True) build_hierarchy(tmpdir) path, prefix = find_stdlib(None, str(pypy)) assert prefix == tmpdir + # shouldn't find stdlib if executable == '' even if parent dir has a stdlib + monkeypatch.chdir(tmpdir.join('bin')) + assert find_stdlib(None, '') == (None, None) @py.test.mark.skipif('not hasattr(os, "symlink")') def test_find_stdlib_follow_symlink(tmpdir): @@ -84,6 +87,7 @@ assert find_executable('pypy') == a.join('pypy.exe') def test_resolvedirof(tmpdir): + assert resolvedirof('') == os.path.abspath(os.path.join(os.getcwd(), '..')) foo = tmpdir.join('foo').ensure(dir=True) bar = tmpdir.join('bar').ensure(dir=True) myfile = foo.join('myfile').ensure(file=True) diff --git a/pypy/module/test_lib_pypy/numpypy/core/test_fromnumeric.py b/pypy/module/test_lib_pypy/numpypy/core/test_fromnumeric.py --- a/pypy/module/test_lib_pypy/numpypy/core/test_fromnumeric.py +++ b/pypy/module/test_lib_pypy/numpypy/core/test_fromnumeric.py @@ -127,7 +127,7 @@ assert reshape(a, (1, -1)).shape == (1, 105) assert reshape(a, (1, 1, -1)).shape == (1, 1, 105) assert reshape(a, (-1, 1, 1)).shape == (105, 1, 1) - + def test_transpose(self): from numpypy import arange, array, transpose, ones x = arange(4).reshape((2,2)) @@ -136,7 +136,7 @@ raises(NotImplementedError, "transpose(x, axes=(1, 0, 2))") # x = ones((1, 2, 3)) # assert transpose(x, (1, 0, 2)).shape == (2, 1, 3) - + def test_fromnumeric(self): from numpypy import array, swapaxes x = array([[1,2,3]]) diff --git a/pypy/module/test_lib_pypy/numpypy/test_numpy.py b/pypy/module/test_lib_pypy/numpypy/test_numpy.py --- a/pypy/module/test_lib_pypy/numpypy/test_numpy.py +++ b/pypy/module/test_lib_pypy/numpypy/test_numpy.py @@ -8,3 +8,11 @@ pass import numpypy import numpy # works after 'numpypy' has been imported + + def test_min_max_after_import(self): + from numpypy import * + assert min(1, 100) == 1 + assert min(100, 1) == 1 + + assert max(1, 100) == 100 + assert max(100, 1) == 100 diff --git a/pypy/module/test_lib_pypy/test_datetime.py b/pypy/module/test_lib_pypy/test_datetime.py --- a/pypy/module/test_lib_pypy/test_datetime.py +++ b/pypy/module/test_lib_pypy/test_datetime.py @@ -66,9 +66,12 @@ """ import os import time + if os.name == 'nt': + skip("setting os.environ['TZ'] ineffective on windows") try: prev_tz = os.environ.get("TZ") os.environ["TZ"] = "GMT" + time.tzset() for unused in xrange(100): now = time.time() delta = (datetime.datetime.utcfromtimestamp(now) - @@ -79,6 +82,7 @@ del os.environ["TZ"] else: os.environ["TZ"] = prev_tz + time.tzset() def test_utcfromtimestamp_microsecond(): dt = datetime.datetime.utcfromtimestamp(0) diff --git a/rpython/rlib/rarithmetic.py b/rpython/rlib/rarithmetic.py --- a/rpython/rlib/rarithmetic.py +++ b/rpython/rlib/rarithmetic.py @@ -630,21 +630,16 @@ uint2singlefloat, singlefloat2uint T = lltype.typeOf(arg) - is_float = False - is_single_float = False if T == lltype.SingleFloat: - T = rffi.UINT - is_single_float = True arg = singlefloat2uint(arg) elif T == lltype.Float: - is_float = True - T = rffi.LONGLONG arg = float2longlong(arg) elif T == lltype.LongFloat: assert False else: # we cannot do arithmetics on small ints arg = widen(arg) + if rffi.sizeof(T) == 1: res = arg elif rffi.sizeof(T) == 2: @@ -667,9 +662,9 @@ (f >> 24) | (g >> 40) | (h >> 56)) else: assert False # unreachable code - if is_single_float: + + if T == lltype.SingleFloat: return uint2singlefloat(rffi.cast(rffi.UINT, res)) - if is_float: - res = rffi.cast(rffi.LONGLONG, res) - return longlong2float(res) + if T == lltype.Float: + return longlong2float(rffi.cast(rffi.LONGLONG, res)) return rffi.cast(T, res) diff --git a/rpython/rlib/rstruct/ieee.py b/rpython/rlib/rstruct/ieee.py --- a/rpython/rlib/rstruct/ieee.py +++ b/rpython/rlib/rstruct/ieee.py @@ -235,12 +235,12 @@ result.append("".join(l)) @jit.unroll_safe -def pack_float80(result, x, size, be): +def pack_float80(result, x, be): l = [] unsigned = float_pack80(x) for i in range(8): l.append(chr((unsigned[0] >> (i * 8)) & 0xFF)) - for i in range(size - 8): + for i in range(2): l.append(chr((unsigned[1] >> (i * 8)) & 0xFF)) if be: l.reverse() @@ -253,12 +253,14 @@ unsigned |= r_ulonglong(c) << (i * 8) return float_unpack(unsigned, len(s)) -def unpack_float128(s, be): +def unpack_float80(s, be): + if len(s) != 10: + raise ValueError QQ = [r_ulonglong(0), r_ulonglong(0)] for i in range(8): - c = ord(s[len(s) - 1 - i if be else i]) + c = ord(s[9 - i if be else i]) QQ[0] |= r_ulonglong(c) << (i * 8) - for i in range(8, len(s)): - c = ord(s[len(s) - 1 - i if be else i]) + for i in range(8, 10): + c = ord(s[9 - i if be else i]) QQ[1] |= r_ulonglong(c) << ((i - 8) * 8) return float_unpack80(QQ) diff --git a/rpython/rlib/rstruct/runpack.py b/rpython/rlib/rstruct/runpack.py --- a/rpython/rlib/rstruct/runpack.py +++ b/rpython/rlib/rstruct/runpack.py @@ -46,7 +46,7 @@ def __init__(self, fmt): self.formats = [] self.fmt = fmt - + def operate(self, fmtdesc, repetitions): if fmtdesc.needcount: self.formats.append((fmtdesc, repetitions, None)) @@ -110,5 +110,3 @@ unpacker = create_unpacker(fmt) return unpacker.unpack(input) runpack._annspecialcase_ = 'specialize:arg(0)' - - diff --git a/rpython/rlib/rstruct/test/test_ieee.py b/rpython/rlib/rstruct/test/test_ieee.py --- a/rpython/rlib/rstruct/test/test_ieee.py +++ b/rpython/rlib/rstruct/test/test_ieee.py @@ -1,9 +1,12 @@ -import py, sys +import py +import sys import random import struct -from rpython.rlib.rfloat import isnan -from rpython.rlib.rstruct.ieee import float_pack, float_unpack, float_pack80, float_unpack80 +from rpython.rlib.rstruct import ieee +from rpython.rlib.rfloat import isnan, NAN, INFINITY +from rpython.translator.c.test.test_genc import compile + class TestFloatPacking: def setup_class(cls): @@ -12,17 +15,29 @@ def check_float(self, x): # check roundtrip - Q = float_pack(x, 8) - y = float_unpack(Q, 8) - assert repr(x) == repr(y) + Q = ieee.float_pack(x, 8) + y = ieee.float_unpack(Q, 8) + assert repr(x) == repr(y), '%r != %r, Q=%r' % (x, y, Q) - Q = float_pack80(x) - y = float_unpack80(Q) - assert repr(x) == repr(y),'%r != %r, Q=%r'%(x, y, Q) + Q = ieee.float_pack80(x) + y = ieee.float_unpack80(Q) + assert repr(x) == repr(y), '%r != %r, Q=%r' % (x, y, Q) + + Q = [] + ieee.pack_float(Q, x, 8, False) + Q = Q[0] + y = ieee.unpack_float(Q, False) + assert repr(x) == repr(y), '%r != %r, Q=%r' % (x, y, Q) + + Q = [] + ieee.pack_float80(Q, x, False) + Q = Q[0] + y = ieee.unpack_float80(Q, False) + assert repr(x) == repr(y), '%r != %r, Q=%r' % (x, y, Q) # check that packing agrees with the struct module struct_pack8 = struct.unpack(' Author: David Schneider Branch: jitframe-on-heap Changeset: r61269:6d76b320ed6c Date: 2013-02-15 18:31 +0100 http://bitbucket.org/pypy/pypy/changeset/6d76b320ed6c/ Log: mostly finish call_assembler for ARM. Floating point results are still wrong. diff --git a/rpython/jit/backend/arm/opassembler.py b/rpython/jit/backend/arm/opassembler.py --- a/rpython/jit/backend/arm/opassembler.py +++ b/rpython/jit/backend/arm/opassembler.py @@ -349,8 +349,8 @@ fcond, resloc, (size, signed)) return cond - def _emit_call(self, adr, arglocs, fcond=c.AL, - resloc=None, result_info=(-1, -1)): + def _emit_call(self, adr, arglocs, fcond=c.AL, resloc=None, + result_info=(-1, -1)): if self.cpu.use_hf_abi: stack_args, adr = self._setup_call_hf(adr, arglocs, fcond, resloc, result_info) @@ -1102,28 +1102,37 @@ def imm(self, v): return imm(v) - + def emit_guard_call_assembler(self, op, guard_op, arglocs, regalloc, fcond): if len(arglocs) == 4: - [frame_loc, argloc, vloc, tmploc] = arglocs + [argloc, vloc, result_loc, tmploc] = arglocs else: - [frame_loc, argloc, tmploc] = arglocs + [argloc, result_loc, tmploc] = arglocs vloc = imm(0) - self.call_assembler(op, guard_op, frame_loc, argloc, vloc, tmploc) - xxx + self.call_assembler(op, guard_op, argloc, vloc, result_loc, tmploc, None) + self._emit_guard_may_force(guard_op, + regalloc._prepare_guard(guard_op), guard_op.numargs()) + return fcond + + def _call_assembler_emit_call(self, addr, argloc, resloc): + self._emit_call(addr, [argloc], resloc=resloc) + + def _call_assembler_emit_helper_call(self, addr, arglocs, resloc): + self._emit_call(addr, arglocs, resloc=resloc) def _call_assembler_check_descr(self, value, tmploc): ofs = self.cpu.get_ofs_of_frame_field('jf_descr') self.mc.LDR_ri(r.ip.value, tmploc.value, imm=ofs) self.mc.CMP_ri(r.ip.value, imm=value) pos = self.mc.currpos() - self.mc.BPKT() + self.mc.BKPT() return pos def _call_assembler_patch_je(self, result_loc, jmp_location): pos = self.mc.currpos() - self.mc.BPKT() + self.mc.BKPT() + # pmc = OverwritingBuilder(self.mc, jmp_location, WORD) pmc.B_offs(self.mc.currpos(), c.EQ) return pos @@ -1146,71 +1155,31 @@ if kind == FLOAT: ofs = self.cpu.unpack_arraydescr(descr) assert check_imm_arg(ofs) - assert result_loc.is_reg() + assert result_loc.is_vfp_reg() # we always have a register here, since we have to sync them # before call_assembler - self.mc.VLDR(result_loc.value, xxx) - if not check_imm_arg(t): - self.mc.gen_load_int(r.ip.value, t, cond=fast_path_cond) - self.mc.ADD_rr(r.ip.value, r.r0.value, r.ip.value, - cond=fast_path_cond) - t = 0 + if not check_imm_arg(ofs): + self.mc.gen_load_int(r.ip.value, ofs) + self.mc.ADD_rr(r.ip.value, r.r0.value, r.ip.value) + ofs = 0 base = r.ip else: base = r.r0 - self.mc.VLDR(resloc.value, base.value, imm=t, - cond=fast_path_cond) + self.mc.VLDR(result_loc.value, base.value, imm=ofs) else: - assert resloc is r.r0 - if kind == INT: - t = unpack_interiorfielddescr(descrs.as_int)[0] + assert result_loc is r.r0 + ofs = self.cpu.unpack_arraydescr(descr) + if not check_imm_arg(ofs): + self.mc.gen_load_int(r.ip.value, ofs) + self.mc.LDR_rr(result_loc.value, result_loc.value, r.ip.value) else: - t = unpack_interiorfielddescr(descrs.as_ref)[0] - if not check_imm_arg(t): - self.mc.gen_load_int(r.ip.value, t, cond=fast_path_cond) - self.mc.LDR_rr(resloc.value, resloc.value, r.ip.value, - cond=fast_path_cond) - else: - self.mc.LDR_ri(resloc.value, resloc.value, imm=t, - cond=fast_path_cond) - # jump to merge point - jmp_pos = self.mc.currpos() - self.mc.BKPT() + self.mc.LDR_ri(result_loc.value, result_loc.value, imm=ofs) - # Path B: use assembler helper - asm_helper_adr = self.cpu.cast_adr_to_int(jd.assembler_helper_adr) - if self.cpu.supports_floats: - floats = r.caller_vfp_resp - else: - floats = [] - # in case the call has a result we do not need to save the - # corresponding result register because it was already allocated for - # the result - core = r.caller_resp - if op.result: - if resloc.is_vfp_reg(): - floats = r.caller_vfp_resp[1:] - else: - core = r.caller_resp[1:] + [r.ip] # keep alignment - with saved_registers(self.mc, core, floats): - # result of previous call is in r0 - self.mov_loc_loc(arglocs[0], r.r1) - self.mc.BL(asm_helper_adr) - if not self.cpu.use_hf_abi and op.result and resloc.is_vfp_reg(): - # move result to the allocated register - self.mov_to_vfp_loc(r.r0, r.r1, resloc) - + def _call_assembler_patch_jmp(self, jmp_location): # merge point currpos = self.mc.currpos() - pmc = OverwritingBuilder(self.mc, jmp_pos, WORD) - pmc.B_offs(currpos, fast_path_cond) - - self.mc.LDR_ri(r.ip.value, r.fp.value) - self.mc.CMP_ri(r.ip.value, 0) - - self._emit_guard(guard_op, regalloc._prepare_guard(guard_op), - c.GE, save_exc=True) - return fcond + pmc = OverwritingBuilder(self.mc, jmp_location, WORD) + pmc.B_offs(currpos) # ../x86/assembler.py:668 def redirect_call_assembler(self, oldlooptoken, newlooptoken): @@ -1243,14 +1212,14 @@ # self._emit_call(adr, callargs, fcond, resloc, (size, signed)) - self._emit_guard_may_force(guard_op, arglocs, numargs) + self._emit_guard_may_force(guard_op, arglocs[1 + numargs:], numargs) return fcond def _emit_guard_may_force(self, guard_op, arglocs, numargs): ofs = self.cpu.get_ofs_of_frame_field('jf_descr') self.mc.LDR_ri(r.ip.value, r.fp.value, imm=ofs) self.mc.CMP_ri(r.ip.value, 0) - self._emit_guard(guard_op, arglocs[1 + numargs:], c.EQ, + self._emit_guard(guard_op, arglocs, c.EQ, save_exc=True, is_guard_not_forced=True) def emit_guard_call_release_gil(self, op, guard_op, arglocs, regalloc, diff --git a/rpython/jit/backend/arm/regalloc.py b/rpython/jit/backend/arm/regalloc.py --- a/rpython/jit/backend/arm/regalloc.py +++ b/rpython/jit/backend/arm/regalloc.py @@ -1101,11 +1101,11 @@ prepare_guard_call_release_gil = prepare_guard_call_may_force def prepare_guard_call_assembler(self, op, guard_op, fcond): - self._prepare_call(op, save_all_regs=True) + locs = self.locs_for_call_assembler(op, guard_op) tmploc = self.get_scratch_reg(INT, selected_reg=r.r0) - locs = self.locs_for_call_assembler(op, guard_op) + call_locs = self._prepare_call(op, save_all_regs=True) self.possibly_free_vars(guard_op.getfailargs()) - return locs + [tmploc] + return locs + [call_locs[0], tmploc] def _prepare_args_for_new_op(self, new_args): gc_ll_descr = self.cpu.gc_ll_descr diff --git a/rpython/jit/backend/llsupport/assembler.py b/rpython/jit/backend/llsupport/assembler.py --- a/rpython/jit/backend/llsupport/assembler.py +++ b/rpython/jit/backend/llsupport/assembler.py @@ -148,7 +148,7 @@ return fail_descr, target def call_assembler(self, op, guard_op, argloc, - vloc, result_loc, tmploc): + vloc, result_loc, tmploc, tmploc2): self._store_force_index(guard_op) descr = op.getdescr() assert isinstance(descr, JitCellToken) @@ -157,8 +157,9 @@ # we need to allocate the frame, keep in sync with runner's # execute_token jd = descr.outermost_jitdriver_sd - self._emit_call(self.imm(descr._ll_function_addr), - [argloc], 0, tmp=tmploc) + self._call_assembler_emit_call(self.imm(descr._ll_function_addr), + argloc, tmploc) + if op.result is None: assert result_loc is None value = self.cpu.done_with_this_frame_descr_void @@ -184,8 +185,8 @@ assert jd is not None asm_helper_adr = self.cpu.cast_adr_to_int(jd.assembler_helper_adr) - self._emit_call(self.imm(asm_helper_adr), - [tmploc, vloc], 0, tmp=self._second_tmp_reg) + self._call_assembler_emit_helper_call(self.imm(asm_helper_adr), + [tmploc, vloc], result_loc) jmp_location = self._call_assembler_patch_je(result_loc, je_location) diff --git a/rpython/jit/backend/llsupport/regalloc.py b/rpython/jit/backend/llsupport/regalloc.py --- a/rpython/jit/backend/llsupport/regalloc.py +++ b/rpython/jit/backend/llsupport/regalloc.py @@ -670,12 +670,11 @@ def locs_for_call_assembler(self, op, guard_op): descr = op.getdescr() assert isinstance(descr, JitCellToken) - arglist = op.getarglist() - if len(arglist) == 2: - self.rm._sync_var(arglist[1]) - return [self.loc(arglist[0]), self.fm.loc(arglist[1])] + if op.numargs() == 2: + self.rm._sync_var(op.getarg(1)) + return [self.loc(op.getarg(0)), self.fm.loc(op.getarg(1))] else: - return [self.loc(arglist[0])] + return [self.loc(op.getarg(0))] def compute_vars_longevity(inputargs, operations): diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -2181,6 +2181,12 @@ self.call_assembler(op, guard_op, argloc, vloc, result_loc, eax) self._emit_guard_not_forced(guard_token) + def _call_assembler_emit_call(self, addr, argloc, tmploc): + self._emit_call(addr, [argloc], 0, tmp=tmploc) + + def _call_assembler_emit_helper_call(self, addr, arglocs, _): + self._emit_call(addr, arglocs, 0, tmp=self._second_tmp_reg) + def _call_assembler_check_descr(self, value, tmploc): ofs = self.cpu.get_ofs_of_frame_field('jf_descr') self.mc.CMP_mi((eax.value, ofs), value) @@ -2213,15 +2219,14 @@ if op.result is not None: # load the return value from the dead frame's value index 0 kind = op.result.type + descr = self.cpu.getarraydescr_for_frame(kind) if kind == FLOAT: - descr = self.cpu.getarraydescr_for_frame(kind) ofs = self.cpu.unpack_arraydescr(descr) self.mc.MOVSD_xm(xmm0.value, (eax.value, ofs)) if result_loc is not xmm0: self.mc.MOVSD(result_loc, xmm0) else: assert result_loc is eax - descr = self.cpu.getarraydescr_for_frame(kind) ofs = self.cpu.unpack_arraydescr(descr) self.mc.MOV_rm(eax.value, (eax.value, ofs)) From noreply at buildbot.pypy.org Fri Feb 15 18:35:51 2013 From: noreply at buildbot.pypy.org (bivab) Date: Fri, 15 Feb 2013 18:35:51 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: fix Message-ID: <20130215173551.3D27D1C094A@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: jitframe-on-heap Changeset: r61270:bb51bc7a00ac Date: 2013-02-15 18:35 +0100 http://bitbucket.org/pypy/pypy/changeset/bb51bc7a00ac/ Log: fix diff --git a/rpython/jit/backend/arm/opassembler.py b/rpython/jit/backend/arm/opassembler.py --- a/rpython/jit/backend/arm/opassembler.py +++ b/rpython/jit/backend/arm/opassembler.py @@ -1110,7 +1110,7 @@ else: [argloc, result_loc, tmploc] = arglocs vloc = imm(0) - self.call_assembler(op, guard_op, argloc, vloc, result_loc, tmploc, None) + self.call_assembler(op, guard_op, argloc, vloc, result_loc, tmploc) self._emit_guard_may_force(guard_op, regalloc._prepare_guard(guard_op), guard_op.numargs()) return fcond diff --git a/rpython/jit/backend/llsupport/assembler.py b/rpython/jit/backend/llsupport/assembler.py --- a/rpython/jit/backend/llsupport/assembler.py +++ b/rpython/jit/backend/llsupport/assembler.py @@ -147,8 +147,7 @@ guardtok.faildescr.rd_loop_token = self.current_clt return fail_descr, target - def call_assembler(self, op, guard_op, argloc, - vloc, result_loc, tmploc, tmploc2): + def call_assembler(self, op, guard_op, argloc, vloc, result_loc, tmploc): self._store_force_index(guard_op) descr = op.getdescr() assert isinstance(descr, JitCellToken) From noreply at buildbot.pypy.org Fri Feb 15 18:43:30 2013 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 15 Feb 2013 18:43:30 +0100 (CET) Subject: [pypy-commit] pypy signal-and-thread: A branch to play with "__pypy__.enable_signals()" Message-ID: <20130215174330.52CBE1C094A@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: signal-and-thread Changeset: r61271:ada8118d3ebf Date: 2013-02-15 16:52 +0100 http://bitbucket.org/pypy/pypy/changeset/ada8118d3ebf/ Log: A branch to play with "__pypy__.enable_signals()" From noreply at buildbot.pypy.org Fri Feb 15 18:43:31 2013 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 15 Feb 2013 18:43:31 +0100 (CET) Subject: [pypy-commit] pypy signal-and-thread: First, refactor stuff Message-ID: <20130215174331.9EE841C094A@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: signal-and-thread Changeset: r61272:a3bd80f80f35 Date: 2013-02-15 16:56 +0100 http://bitbucket.org/pypy/pypy/changeset/a3bd80f80f35/ Log: First, refactor stuff diff --git a/pypy/interpreter/miscutils.py b/pypy/interpreter/miscutils.py --- a/pypy/interpreter/miscutils.py +++ b/pypy/interpreter/miscutils.py @@ -17,7 +17,7 @@ def setvalue(self, value): self._value = value - def ismainthread(self): + def signals_enabled(self): return True def getallvalues(self): diff --git a/pypy/module/signal/interp_signal.py b/pypy/module/signal/interp_signal.py --- a/pypy/module/signal/interp_signal.py +++ b/pypy/module/signal/interp_signal.py @@ -61,16 +61,16 @@ "NOT_RPYTHON" AsyncAction.__init__(self, space) self.pending_signal = -1 - self.fire_in_main_thread = False + self.fire_in_another_thread = False if self.space.config.objspace.usemodules.thread: from pypy.module.thread import gil gil.after_thread_switch = self._after_thread_switch @rgc.no_collect def _after_thread_switch(self): - if self.fire_in_main_thread: - if self.space.threadlocals.ismainthread(): - self.fire_in_main_thread = False + if self.fire_in_another_thread: + if self.space.threadlocals.signals_enabled(): + self.fire_in_another_thread = False SignalActionFlag.rearm_ticker() # this occurs when we just switched to the main thread # and there is a signal pending: we force the ticker to @@ -82,11 +82,7 @@ n = self.pending_signal if n < 0: n = pypysig_poll() while n >= 0: - if self.space.config.objspace.usemodules.thread: - in_main = self.space.threadlocals.ismainthread() - else: - in_main = True - if in_main: + if self.space.threadlocals.signals_enabled(): # If we are in the main thread, report the signal now, # and poll more self.pending_signal = -1 @@ -97,7 +93,7 @@ # Otherwise, arrange for perform() to be called again # after we switch to the main thread. self.pending_signal = n - self.fire_in_main_thread = True + self.fire_in_another_thread = True break def set_interrupt(self): @@ -107,7 +103,6 @@ # ^^^ may override another signal, but it's just for testing else: pypysig_pushback(cpy_signal.SIGINT) - self.fire_in_main_thread = True # ____________________________________________________________ @@ -204,9 +199,10 @@ if WIN32 and signum not in signal_values: raise OperationError(space.w_ValueError, space.wrap("invalid signal value")) - if not space.threadlocals.ismainthread(): + if not space.threadlocals.signals_enabled(): raise OperationError(space.w_ValueError, - space.wrap("signal only works in main thread")) + space.wrap("signal only works in main thread " + "or a thread in __pypy__.enable_signals()")) check_signum_in_range(space, signum) if space.eq_w(w_handler, space.wrap(SIG_DFL)): @@ -235,10 +231,11 @@ The fd must be non-blocking. """ - if not space.threadlocals.ismainthread(): + if not space.threadlocals.signals_enabled(): raise OperationError( space.w_ValueError, - space.wrap("set_wakeup_fd only works in main thread")) + space.wrap("set_wakeup_fd only works in main thread " + "or a thread in __pypy__.enable_signals()")) old_fd = pypysig_set_wakeup_fd(fd) return space.wrap(intmask(old_fd)) diff --git a/pypy/module/thread/threadlocals.py b/pypy/module/thread/threadlocals.py --- a/pypy/module/thread/threadlocals.py +++ b/pypy/module/thread/threadlocals.py @@ -9,11 +9,12 @@ def __init__(self): self._valuedict = {} # {thread_ident: ExecutionContext()} + self._signalsenabled = {} # {thread_ident: None} self._cleanup_() def _cleanup_(self): self._valuedict.clear() - self._mainthreadident = 0 + self._signalsenabled.clear() self._mostrecentkey = 0 # fast minicaching for the common case self._mostrecentvalue = None # fast minicaching for the common case @@ -33,7 +34,7 @@ ident = rthread.get_ident() if value is not None: if len(self._valuedict) == 0: - self._mainthreadident = ident + self._signalsenabled[ident] = None self._valuedict[ident] = value else: try: @@ -44,8 +45,14 @@ self._mostrecentkey = ident self._mostrecentvalue = value - def ismainthread(self): - return rthread.get_ident() == self._mainthreadident + def signals_enabled(self): + return rthread.get_ident() in self._signalsenabled + + def enable_signals(self): + self._signalsenabled[rthread.get_ident()] = None + + def disable_signals(self): + del self._signalsenabled[rthread.get_ident()] def getallvalues(self): return self._valuedict @@ -60,4 +67,5 @@ def reinit_threads(self, space): "Called in the child process after a fork()" - self._mainthreadident = rthread.get_ident() + self._signalsenabled.clear() + self.enable_signals() From noreply at buildbot.pypy.org Fri Feb 15 18:43:32 2013 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 15 Feb 2013 18:43:32 +0100 (CET) Subject: [pypy-commit] pypy signal-and-thread: Add '__pypy__.enable_signals', a context manager. Message-ID: <20130215174332.CD3271C094A@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: signal-and-thread Changeset: r61273:b869a617a78a Date: 2013-02-15 17:21 +0100 http://bitbucket.org/pypy/pypy/changeset/b869a617a78a/ Log: Add '__pypy__.enable_signals', a context manager. diff --git a/pypy/interpreter/miscutils.py b/pypy/interpreter/miscutils.py --- a/pypy/interpreter/miscutils.py +++ b/pypy/interpreter/miscutils.py @@ -20,5 +20,11 @@ def signals_enabled(self): return True + def enable_signals(self): + pass + + def disable_signals(self): + pass + def getallvalues(self): return {0: self._value} diff --git a/pypy/module/__pypy__/__init__.py b/pypy/module/__pypy__/__init__.py --- a/pypy/module/__pypy__/__init__.py +++ b/pypy/module/__pypy__/__init__.py @@ -28,6 +28,7 @@ class Module(MixedModule): appleveldefs = { + 'signals_enabled' : 'app_signal.signals_enabled', } interpleveldefs = { @@ -47,6 +48,8 @@ 'newlist_hint' : 'interp_magic.newlist_hint', 'newdict' : 'interp_dict.newdict', 'dictstrategy' : 'interp_dict.dictstrategy', + '_signals_enter' : 'interp_signal.signals_enter', + '_signals_exit' : 'interp_signal.signals_exit', } if sys.platform == 'win32': interpleveldefs['get_console_cp'] = 'interp_magic.get_console_cp' diff --git a/pypy/module/__pypy__/app_signal.py b/pypy/module/__pypy__/app_signal.py new file mode 100644 --- /dev/null +++ b/pypy/module/__pypy__/app_signal.py @@ -0,0 +1,14 @@ +import __pypy__ + +class SignalsEnabled(object): + '''A context manager to use in non-main threads: +enables receiving signals in a "with" statement. More precisely, if a +signal is received by the process, then the signal handler might be +called either in the main thread (as usual) or within another thread +that is within a "with signals_enabled:". This other thread should be +ready to handle unexpected exceptions that the signal handler might +raise --- notably KeyboardInterrupt.''' + __enter__ = __pypy__._signals_enter + __exit__ = __pypy__._signals_exit + +signals_enabled = SignalsEnabled() diff --git a/pypy/module/__pypy__/interp_signal.py b/pypy/module/__pypy__/interp_signal.py new file mode 100644 --- /dev/null +++ b/pypy/module/__pypy__/interp_signal.py @@ -0,0 +1,6 @@ + +def signals_enter(space): + space.threadlocals.enable_signals() + +def signals_exit(space): + space.threadlocals.disable_signals() diff --git a/pypy/module/thread/threadlocals.py b/pypy/module/thread/threadlocals.py --- a/pypy/module/thread/threadlocals.py +++ b/pypy/module/thread/threadlocals.py @@ -9,7 +9,7 @@ def __init__(self): self._valuedict = {} # {thread_ident: ExecutionContext()} - self._signalsenabled = {} # {thread_ident: None} + self._signalsenabled = {} # {thread_ident: number-of-times} self._cleanup_() def _cleanup_(self): @@ -34,7 +34,7 @@ ident = rthread.get_ident() if value is not None: if len(self._valuedict) == 0: - self._signalsenabled[ident] = None + self._signalsenabled[ident] = 1 # the main thread is enabled self._valuedict[ident] = value else: try: @@ -49,10 +49,20 @@ return rthread.get_ident() in self._signalsenabled def enable_signals(self): - self._signalsenabled[rthread.get_ident()] = None + ident = rthread.get_ident() + old = self._signalsenabled.get(ident, 0) + self._signalsenabled[ident] = old + 1 def disable_signals(self): - del self._signalsenabled[rthread.get_ident()] + ident = rthread.get_ident() + try: + new = self._signalsenabled[ident] - 1 + except KeyError: + return + if new > 0: + self._signalsenabled[ident] = new + else: + del self._signalsenabled[ident] def getallvalues(self): return self._valuedict From noreply at buildbot.pypy.org Fri Feb 15 18:43:34 2013 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 15 Feb 2013 18:43:34 +0100 (CET) Subject: [pypy-commit] pypy signal-and-thread: Oups Message-ID: <20130215174334.1EDFF1C094A@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: signal-and-thread Changeset: r61274:c934d2585639 Date: 2013-02-15 17:06 +0000 http://bitbucket.org/pypy/pypy/changeset/c934d2585639/ Log: Oups diff --git a/pypy/module/__pypy__/interp_signal.py b/pypy/module/__pypy__/interp_signal.py --- a/pypy/module/__pypy__/interp_signal.py +++ b/pypy/module/__pypy__/interp_signal.py @@ -2,5 +2,5 @@ def signals_enter(space): space.threadlocals.enable_signals() -def signals_exit(space): +def signals_exit(space, w_ignored1=None, w_ignored2=None, w_ignored3=None): space.threadlocals.disable_signals() From noreply at buildbot.pypy.org Fri Feb 15 18:43:35 2013 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 15 Feb 2013 18:43:35 +0100 (CET) Subject: [pypy-commit] pypy signal-and-thread: Move 'signals_enabled' from __pypy__ to thread. Message-ID: <20130215174335.4C3991C094A@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: signal-and-thread Changeset: r61275:627eb4502c26 Date: 2013-02-15 18:12 +0100 http://bitbucket.org/pypy/pypy/changeset/627eb4502c26/ Log: Move 'signals_enabled' from __pypy__ to thread. diff --git a/pypy/module/__pypy__/__init__.py b/pypy/module/__pypy__/__init__.py --- a/pypy/module/__pypy__/__init__.py +++ b/pypy/module/__pypy__/__init__.py @@ -28,7 +28,6 @@ class Module(MixedModule): appleveldefs = { - 'signals_enabled' : 'app_signal.signals_enabled', } interpleveldefs = { @@ -48,8 +47,6 @@ 'newlist_hint' : 'interp_magic.newlist_hint', 'newdict' : 'interp_dict.newdict', 'dictstrategy' : 'interp_dict.dictstrategy', - '_signals_enter' : 'interp_signal.signals_enter', - '_signals_exit' : 'interp_signal.signals_exit', } if sys.platform == 'win32': interpleveldefs['get_console_cp'] = 'interp_magic.get_console_cp' diff --git a/pypy/module/thread/__init__.py b/pypy/module/thread/__init__.py --- a/pypy/module/thread/__init__.py +++ b/pypy/module/thread/__init__.py @@ -4,6 +4,7 @@ class Module(MixedModule): appleveldefs = { + 'signals_enabled': 'app_signal.signals_enabled', } interpleveldefs = { @@ -20,6 +21,8 @@ 'LockType': 'os_lock.Lock', '_local': 'os_local.Local', 'error': 'space.fromcache(error.Cache).w_error', + '_signals_enter': 'interp_signal.signals_enter', + '_signals_exit': 'interp_signal.signals_exit', } def __init__(self, space, *args): diff --git a/pypy/module/__pypy__/app_signal.py b/pypy/module/thread/app_signal.py rename from pypy/module/__pypy__/app_signal.py rename to pypy/module/thread/app_signal.py diff --git a/pypy/module/__pypy__/interp_signal.py b/pypy/module/thread/interp_signal.py rename from pypy/module/__pypy__/interp_signal.py rename to pypy/module/thread/interp_signal.py From noreply at buildbot.pypy.org Fri Feb 15 18:43:36 2013 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 15 Feb 2013 18:43:36 +0100 (CET) Subject: [pypy-commit] pypy signal-and-thread: Fix the error message Message-ID: <20130215174336.6EC121C094A@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: signal-and-thread Changeset: r61276:2c033ba4cb6a Date: 2013-02-15 18:14 +0100 http://bitbucket.org/pypy/pypy/changeset/2c033ba4cb6a/ Log: Fix the error message diff --git a/pypy/module/signal/interp_signal.py b/pypy/module/signal/interp_signal.py --- a/pypy/module/signal/interp_signal.py +++ b/pypy/module/signal/interp_signal.py @@ -202,7 +202,7 @@ if not space.threadlocals.signals_enabled(): raise OperationError(space.w_ValueError, space.wrap("signal only works in main thread " - "or a thread in __pypy__.enable_signals()")) + "or with thread.enable_signals()")) check_signum_in_range(space, signum) if space.eq_w(w_handler, space.wrap(SIG_DFL)): @@ -235,7 +235,7 @@ raise OperationError( space.w_ValueError, space.wrap("set_wakeup_fd only works in main thread " - "or a thread in __pypy__.enable_signals()")) + "or with thread.enable_signals()")) old_fd = pypysig_set_wakeup_fd(fd) return space.wrap(intmask(old_fd)) From noreply at buildbot.pypy.org Fri Feb 15 18:43:37 2013 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 15 Feb 2013 18:43:37 +0100 (CET) Subject: [pypy-commit] pypy signal-and-thread: Add a test, which (most probably) only works on "pypy py.test -A". Message-ID: <20130215174337.98C6F1C094A@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: signal-and-thread Changeset: r61277:622fccdeb60f Date: 2013-02-15 17:28 +0000 http://bitbucket.org/pypy/pypy/changeset/622fccdeb60f/ Log: Add a test, which (most probably) only works on "pypy py.test -A". diff --git a/pypy/module/thread/test/test_signal.py b/pypy/module/thread/test/test_signal.py new file mode 100644 --- /dev/null +++ b/pypy/module/thread/test/test_signal.py @@ -0,0 +1,32 @@ +import sys + + +class AppTest: + spaceconfig = dict(usemodules=['thread', 'signal']) + + def setup_class(cls): + if (not cls.runappdirect or + '__pypy__' not in sys.builtin_module_names): + import py + py.test.skip("this is only a test for -A runs on top of pypy") + + def test_enable_signals(self): + import thread, signal, time + # + interrupted = [] + lock = thread.allocate_lock() + lock.acquire() + # + def subthread(): + try: + time.sleep(0.25) + with thread.signals_enabled: + thread.interrupt_main() + except BaseException, e: + interrupted.append(e) + lock.release() + # + thread.start_new_thread(subthread, ()) + lock.acquire() + assert len(interrupted) == 1 + assert 'KeyboardInterrupt' in interrupted[0].__class__.__name__ From noreply at buildbot.pypy.org Fri Feb 15 18:43:38 2013 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 15 Feb 2013 18:43:38 +0100 (CET) Subject: [pypy-commit] pypy signal-and-thread: Test and fix Message-ID: <20130215174338.C09DF1C094A@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: signal-and-thread Changeset: r61278:0d35394e8c39 Date: 2013-02-15 17:34 +0000 http://bitbucket.org/pypy/pypy/changeset/0d35394e8c39/ Log: Test and fix diff --git a/pypy/module/thread/app_signal.py b/pypy/module/thread/app_signal.py --- a/pypy/module/thread/app_signal.py +++ b/pypy/module/thread/app_signal.py @@ -1,4 +1,4 @@ -import __pypy__ +import thread class SignalsEnabled(object): '''A context manager to use in non-main threads: @@ -8,7 +8,7 @@ that is within a "with signals_enabled:". This other thread should be ready to handle unexpected exceptions that the signal handler might raise --- notably KeyboardInterrupt.''' - __enter__ = __pypy__._signals_enter - __exit__ = __pypy__._signals_exit + __enter__ = thread._signals_enter + __exit__ = thread._signals_exit signals_enabled = SignalsEnabled() diff --git a/pypy/module/thread/test/test_signal.py b/pypy/module/thread/test/test_signal.py --- a/pypy/module/thread/test/test_signal.py +++ b/pypy/module/thread/test/test_signal.py @@ -1,7 +1,17 @@ import sys -class AppTest: +class AppTestMinimal: + spaceconfig = dict(usemodules=['thread']) + + def test_signal(self): + import thread + with thread.signals_enabled: + pass + # assert did not crash + + +class AppTestThreadSignal: spaceconfig = dict(usemodules=['thread', 'signal']) def setup_class(cls): From noreply at buildbot.pypy.org Fri Feb 15 18:48:18 2013 From: noreply at buildbot.pypy.org (lwassermann) Date: Fri, 15 Feb 2013 18:48:18 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: added closure bytecodes Message-ID: <20130215174818.05AF51C094A@cobra.cs.uni-duesseldorf.de> Author: Lars Wassermann Branch: Changeset: r32:0f7c194a272d Date: 2013-02-15 18:47 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/0f7c194a272d/ Log: added closure bytecodes added NotYetImplementedError implementations for these bytecodes added test for the first new bytecode merge with tip diff --git a/spyvm/interpreter.py b/spyvm/interpreter.py --- a/spyvm/interpreter.py +++ b/spyvm/interpreter.py @@ -1,9 +1,7 @@ import py from spyvm.shadow import ContextPartShadow, MethodContextShadow, BlockContextShadow -from spyvm import model, constants, primitives -from spyvm.shadow import ContextPartShadow -from spyvm import conftest -from spyvm import wrapper +from spyvm import model, constants, primitives, conftest, wrapper +from spyvm.tool.bitmanipulation import splitter from rpython.rlib import jit from rpython.rlib import objectmodel, unroll @@ -370,9 +368,41 @@ def popStackBytecode(self, interp): self.pop() + # closure bytecodes + def pushNewArrayPopIntoArray(self, interp): + popIntoArray, arraySize = splitter[1, 7](self.getbytecode()) + newArray = None + #if popIntoArray == 1: + # newArray = interp.space.wrap_list(self.pop_and_return_n(arraySize)) + #else: + # newArray = interp.space.w_Array.as_class_get_shadow(interp.space).new(arraySize) + self.push(newArray) + raise MissingBytecode("not yet implemented: pushNewArray") + def experimentalBytecode(self, interp): raise MissingBytecode("experimentalBytecode") + def pushTempAtInTempVectorAt(self, interp): + k = self.getbytecode() + j = self.getbytecode() + raise MissingBytecode("not yet implemented: pushTempAt k inTempVectorAt j") + + def storeTempAtInTempVectorAt(self, interp): + k = self.getbytecode() + j = self.getbytecode() + raise MissingBytecode("not yet implemented: storeTempAt k inTempVectorAt j") + + def popAndStoreTempAtInTempVectorAt(self, interp): + k = self.getbytecode() + j = self.getbytecode() + raise MissingBytecode("not yet implemented: popAndstoreTempAt k inTempVectorAt j") + + def pushClosureNumCopiedNumArgsBlockSize(self, interp): + l, k = splitter[4, 4](self.getbytecode()) + j = self.getbytecode() + i = self.getbytecode() + raise MissingBytecode("not yet implemented: pushClosureNumCopied l numArgs k blockSize ij") + def jump(self,offset): self.store_pc(self.pc() + offset) @@ -505,7 +535,12 @@ (135, "popStackBytecode"), (136, "duplicateTopBytecode"), (137, "pushActiveContextBytecode"), - (138, 143, "experimentalBytecode"), + (138, "pushNewArrayPopIntoArray"), + (139, "experimentalBytecode"), + (140, "pushTempAtInTempVectorAt"), + (141, "storeTempAtInTempVectorAt"), + (142, "popAndStoreTempAtInTempVectorAt"), + (143, "pushClosureNumCopiedNumArgsBlockSize"), (144, 151, "shortUnconditionalJump"), (152, 159, "shortConditionalJump"), (160, 167, "longUnconditionalJump"), diff --git a/spyvm/objspace.py b/spyvm/objspace.py --- a/spyvm/objspace.py +++ b/spyvm/objspace.py @@ -205,9 +205,9 @@ a wrapped smalltalk array """ lstlen = len(lst_w) - res = self.w_Array.as_class_get_shadow().new(lstlen) + res = self.w_Array.as_class_get_shadow(self).new(lstlen) for i in range(lstlen): - res.storevarpointer(i, lit[i]) + res.storevarpointer(i, lst_w[i]) return res def unwrap_int(self, w_value): diff --git a/spyvm/targettinybenchsmalltalk.py b/spyvm/targettinybenchsmalltalk.py --- a/spyvm/targettinybenchsmalltalk.py +++ b/spyvm/targettinybenchsmalltalk.py @@ -1,6 +1,6 @@ import os, sys from spyvm import model, interpreter, primitives, shadow, constants -from spyvm.tool.analyseimage import create_squeakimage +from spyvm.tool.analyseimage import create_squeakimage, create_testimage from rpython.jit.codewriter.policy import JitPolicy @@ -19,13 +19,13 @@ def tinyBenchmarks(): from spyvm import objspace space = objspace.ObjSpace() - image = create_squeakimage(space) + image = create_testimage(space) interp = interpreter.Interpreter(space) w_object = model.W_SmallInteger(0) s_class = w_object.shadow_of_my_class(space) - w_method = s_class.lookup("tinyBenchmarks") + w_method = s_class.lookup("loopTest") assert w_method w_frame = w_method.create_frame(space, w_object, []) diff --git a/spyvm/test/jit.py b/spyvm/test/jit.py --- a/spyvm/test/jit.py +++ b/spyvm/test/jit.py @@ -16,7 +16,7 @@ from spyvm import model, interpreter, primitives, shadow from spyvm import objspace -from spyvm.tool.analyseimage import create_testimage +from spyvm.tool.analyseimage import create_squeakimage, create_testimage mockclass = objspace.bootstrap_class @@ -77,5 +77,4 @@ def interp_w(): interp.interpret() - self.meta_interp(interp_w, [], listcomp=True, listops=True, backendopt=True) - + self.meta_interp(interp_w, [], listcomp=True, listops=True, backendopt=True) \ No newline at end of file diff --git a/spyvm/test/test_interpreter.py b/spyvm/test/test_interpreter.py --- a/spyvm/test/test_interpreter.py +++ b/spyvm/test/test_interpreter.py @@ -829,3 +829,14 @@ test_storeAndPopReceiverVariableBytecode() test_bc_objectAtAndAtPut() option.bc_trace = bc_trace + +# Closure Bytecodes +def test_bc_pushNewArrayPopIntoArray(bytecode=pushNewArrayPopIntoArray): + py.test.skip("Fails, since pushNewArrayPopIntoArray is not yet implemented") + interp = new_interpreter(bytecode + chr(0x83)) + context = interp.s_active_context() + context.push(fakeliterals("egg")) + context.push(fakeliterals("bar")) + context.push(fakeliterals("baz")) + interp.step(interp.s_active_context()) + assert context.pop() == fakeliterals(["egg", "bar", "baz"]) \ No newline at end of file diff --git a/spyvm/todo.txt b/spyvm/todo.txt --- a/spyvm/todo.txt +++ b/spyvm/todo.txt @@ -21,3 +21,7 @@ Shadows: [ ] Fix invalidation of methoddictshadow when the w_self of its values array changes + +Lars ToDo +[ ] Tests for the new bytecodes. +[ ] Guess method names for JIT debugging, e.g. changing MethodDictShadow From noreply at buildbot.pypy.org Fri Feb 15 18:58:01 2013 From: noreply at buildbot.pypy.org (bivab) Date: Fri, 15 Feb 2013 18:58:01 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: another fix Message-ID: <20130215175801.106701C094A@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: jitframe-on-heap Changeset: r61279:1b1c7e46b694 Date: 2013-02-15 18:54 +0100 http://bitbucket.org/pypy/pypy/changeset/1b1c7e46b694/ Log: another fix diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -2173,7 +2173,7 @@ def genop_guard_call_assembler(self, op, guard_op, guard_token, arglocs, result_loc): - if len(arglocs) == 3: + if len(arglocs) == 2: [argloc, vloc] = arglocs else: [argloc] = arglocs From noreply at buildbot.pypy.org Fri Feb 15 19:21:58 2013 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 15 Feb 2013 19:21:58 +0100 (CET) Subject: [pypy-commit] pypy signal-and-thread: Ready for merge Message-ID: <20130215182158.CA3061C00A8@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: signal-and-thread Changeset: r61280:a60f2c43651a Date: 2013-02-15 18:17 +0000 http://bitbucket.org/pypy/pypy/changeset/a60f2c43651a/ Log: Ready for merge From noreply at buildbot.pypy.org Fri Feb 15 19:22:00 2013 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 15 Feb 2013 19:22:00 +0100 (CET) Subject: [pypy-commit] pypy default: hg merge signal-and-thread Message-ID: <20130215182200.0BBC81C00A8@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r61281:07f5d48c7467 Date: 2013-02-15 18:21 +0000 http://bitbucket.org/pypy/pypy/changeset/07f5d48c7467/ Log: hg merge signal-and-thread Add "thread.signals_enabled", a context manager. Can be used in a non-main thread to enable the processing of signal handlers in that other thread. diff --git a/pypy/interpreter/miscutils.py b/pypy/interpreter/miscutils.py --- a/pypy/interpreter/miscutils.py +++ b/pypy/interpreter/miscutils.py @@ -17,8 +17,14 @@ def setvalue(self, value): self._value = value - def ismainthread(self): + def signals_enabled(self): return True + def enable_signals(self): + pass + + def disable_signals(self): + pass + def getallvalues(self): return {0: self._value} diff --git a/pypy/module/signal/interp_signal.py b/pypy/module/signal/interp_signal.py --- a/pypy/module/signal/interp_signal.py +++ b/pypy/module/signal/interp_signal.py @@ -61,16 +61,16 @@ "NOT_RPYTHON" AsyncAction.__init__(self, space) self.pending_signal = -1 - self.fire_in_main_thread = False + self.fire_in_another_thread = False if self.space.config.objspace.usemodules.thread: from pypy.module.thread import gil gil.after_thread_switch = self._after_thread_switch @rgc.no_collect def _after_thread_switch(self): - if self.fire_in_main_thread: - if self.space.threadlocals.ismainthread(): - self.fire_in_main_thread = False + if self.fire_in_another_thread: + if self.space.threadlocals.signals_enabled(): + self.fire_in_another_thread = False SignalActionFlag.rearm_ticker() # this occurs when we just switched to the main thread # and there is a signal pending: we force the ticker to @@ -82,11 +82,7 @@ n = self.pending_signal if n < 0: n = pypysig_poll() while n >= 0: - if self.space.config.objspace.usemodules.thread: - in_main = self.space.threadlocals.ismainthread() - else: - in_main = True - if in_main: + if self.space.threadlocals.signals_enabled(): # If we are in the main thread, report the signal now, # and poll more self.pending_signal = -1 @@ -97,7 +93,7 @@ # Otherwise, arrange for perform() to be called again # after we switch to the main thread. self.pending_signal = n - self.fire_in_main_thread = True + self.fire_in_another_thread = True break def set_interrupt(self): @@ -107,7 +103,6 @@ # ^^^ may override another signal, but it's just for testing else: pypysig_pushback(cpy_signal.SIGINT) - self.fire_in_main_thread = True # ____________________________________________________________ @@ -204,9 +199,10 @@ if WIN32 and signum not in signal_values: raise OperationError(space.w_ValueError, space.wrap("invalid signal value")) - if not space.threadlocals.ismainthread(): + if not space.threadlocals.signals_enabled(): raise OperationError(space.w_ValueError, - space.wrap("signal only works in main thread")) + space.wrap("signal only works in main thread " + "or with thread.enable_signals()")) check_signum_in_range(space, signum) if space.eq_w(w_handler, space.wrap(SIG_DFL)): @@ -235,10 +231,11 @@ The fd must be non-blocking. """ - if not space.threadlocals.ismainthread(): + if not space.threadlocals.signals_enabled(): raise OperationError( space.w_ValueError, - space.wrap("set_wakeup_fd only works in main thread")) + space.wrap("set_wakeup_fd only works in main thread " + "or with thread.enable_signals()")) old_fd = pypysig_set_wakeup_fd(fd) return space.wrap(intmask(old_fd)) diff --git a/pypy/module/thread/__init__.py b/pypy/module/thread/__init__.py --- a/pypy/module/thread/__init__.py +++ b/pypy/module/thread/__init__.py @@ -4,6 +4,7 @@ class Module(MixedModule): appleveldefs = { + 'signals_enabled': 'app_signal.signals_enabled', } interpleveldefs = { @@ -20,6 +21,8 @@ 'LockType': 'os_lock.Lock', '_local': 'os_local.Local', 'error': 'space.fromcache(error.Cache).w_error', + '_signals_enter': 'interp_signal.signals_enter', + '_signals_exit': 'interp_signal.signals_exit', } def __init__(self, space, *args): diff --git a/pypy/module/thread/app_signal.py b/pypy/module/thread/app_signal.py new file mode 100644 --- /dev/null +++ b/pypy/module/thread/app_signal.py @@ -0,0 +1,14 @@ +import thread + +class SignalsEnabled(object): + '''A context manager to use in non-main threads: +enables receiving signals in a "with" statement. More precisely, if a +signal is received by the process, then the signal handler might be +called either in the main thread (as usual) or within another thread +that is within a "with signals_enabled:". This other thread should be +ready to handle unexpected exceptions that the signal handler might +raise --- notably KeyboardInterrupt.''' + __enter__ = thread._signals_enter + __exit__ = thread._signals_exit + +signals_enabled = SignalsEnabled() diff --git a/pypy/module/thread/interp_signal.py b/pypy/module/thread/interp_signal.py new file mode 100644 --- /dev/null +++ b/pypy/module/thread/interp_signal.py @@ -0,0 +1,6 @@ + +def signals_enter(space): + space.threadlocals.enable_signals() + +def signals_exit(space, w_ignored1=None, w_ignored2=None, w_ignored3=None): + space.threadlocals.disable_signals() diff --git a/pypy/module/thread/test/test_signal.py b/pypy/module/thread/test/test_signal.py new file mode 100644 --- /dev/null +++ b/pypy/module/thread/test/test_signal.py @@ -0,0 +1,42 @@ +import sys + + +class AppTestMinimal: + spaceconfig = dict(usemodules=['thread']) + + def test_signal(self): + import thread + with thread.signals_enabled: + pass + # assert did not crash + + +class AppTestThreadSignal: + spaceconfig = dict(usemodules=['thread', 'signal']) + + def setup_class(cls): + if (not cls.runappdirect or + '__pypy__' not in sys.builtin_module_names): + import py + py.test.skip("this is only a test for -A runs on top of pypy") + + def test_enable_signals(self): + import thread, signal, time + # + interrupted = [] + lock = thread.allocate_lock() + lock.acquire() + # + def subthread(): + try: + time.sleep(0.25) + with thread.signals_enabled: + thread.interrupt_main() + except BaseException, e: + interrupted.append(e) + lock.release() + # + thread.start_new_thread(subthread, ()) + lock.acquire() + assert len(interrupted) == 1 + assert 'KeyboardInterrupt' in interrupted[0].__class__.__name__ diff --git a/pypy/module/thread/threadlocals.py b/pypy/module/thread/threadlocals.py --- a/pypy/module/thread/threadlocals.py +++ b/pypy/module/thread/threadlocals.py @@ -9,11 +9,12 @@ def __init__(self): self._valuedict = {} # {thread_ident: ExecutionContext()} + self._signalsenabled = {} # {thread_ident: number-of-times} self._cleanup_() def _cleanup_(self): self._valuedict.clear() - self._mainthreadident = 0 + self._signalsenabled.clear() self._mostrecentkey = 0 # fast minicaching for the common case self._mostrecentvalue = None # fast minicaching for the common case @@ -33,7 +34,7 @@ ident = rthread.get_ident() if value is not None: if len(self._valuedict) == 0: - self._mainthreadident = ident + self._signalsenabled[ident] = 1 # the main thread is enabled self._valuedict[ident] = value else: try: @@ -44,8 +45,24 @@ self._mostrecentkey = ident self._mostrecentvalue = value - def ismainthread(self): - return rthread.get_ident() == self._mainthreadident + def signals_enabled(self): + return rthread.get_ident() in self._signalsenabled + + def enable_signals(self): + ident = rthread.get_ident() + old = self._signalsenabled.get(ident, 0) + self._signalsenabled[ident] = old + 1 + + def disable_signals(self): + ident = rthread.get_ident() + try: + new = self._signalsenabled[ident] - 1 + except KeyError: + return + if new > 0: + self._signalsenabled[ident] = new + else: + del self._signalsenabled[ident] def getallvalues(self): return self._valuedict @@ -60,4 +77,5 @@ def reinit_threads(self, space): "Called in the child process after a fork()" - self._mainthreadident = rthread.get_ident() + self._signalsenabled.clear() + self.enable_signals() From noreply at buildbot.pypy.org Fri Feb 15 19:22:01 2013 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 15 Feb 2013 19:22:01 +0100 (CET) Subject: [pypy-commit] pypy default: merge heads Message-ID: <20130215182201.349E81C00A8@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r61282:9ef3899846ea Date: 2013-02-15 18:22 +0000 http://bitbucket.org/pypy/pypy/changeset/9ef3899846ea/ Log: merge heads diff --git a/rpython/rlib/jit.py b/rpython/rlib/jit.py --- a/rpython/rlib/jit.py +++ b/rpython/rlib/jit.py @@ -476,7 +476,7 @@ get_jitcell_at=None, set_jitcell_at=None, get_printable_location=None, confirm_enter_jit=None, can_never_inline=None, should_unroll_one_iteration=None, - name='jitdriver'): + name='jitdriver', check_untranslated=True): if greens is not None: self.greens = greens self.name = name @@ -511,6 +511,7 @@ self.confirm_enter_jit = confirm_enter_jit self.can_never_inline = can_never_inline self.should_unroll_one_iteration = should_unroll_one_iteration + self.check_untranslated = check_untranslated def _freeze_(self): return True @@ -565,13 +566,15 @@ def jit_merge_point(_self, **livevars): # special-cased by ExtRegistryEntry - _self._check_arguments(livevars) + if _self.check_untranslated: + _self._check_arguments(livevars) def can_enter_jit(_self, **livevars): if _self.autoreds: raise TypeError, "Cannot call can_enter_jit on a driver with reds='auto'" # special-cased by ExtRegistryEntry - _self._check_arguments(livevars) + if _self.check_untranslated: + _self._check_arguments(livevars) def loop_header(self): # special-cased by ExtRegistryEntry diff --git a/rpython/rtyper/lltypesystem/rlist.py b/rpython/rtyper/lltypesystem/rlist.py --- a/rpython/rtyper/lltypesystem/rlist.py +++ b/rpython/rtyper/lltypesystem/rlist.py @@ -246,6 +246,7 @@ of the list to be 'newsize'.""" _ll_list_resize_really(l, newsize, False) + @jit.look_inside_iff(lambda l, newsize: jit.isconstant(len(l.items)) and jit.isconstant(newsize)) @jit.oopspec("list._resize_ge(l, newsize)") def _ll_list_resize_ge(l, newsize): From noreply at buildbot.pypy.org Fri Feb 15 19:41:29 2013 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 15 Feb 2013 19:41:29 +0100 (CET) Subject: [pypy-commit] pypy default: Uh, thread+signal+fork. Tons of fun. Message-ID: <20130215184129.D8C451C00A8@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r61283:15f640136dbf Date: 2013-02-15 19:41 +0100 http://bitbucket.org/pypy/pypy/changeset/15f640136dbf/ Log: Uh, thread+signal+fork. Tons of fun. diff --git a/pypy/module/thread/threadlocals.py b/pypy/module/thread/threadlocals.py --- a/pypy/module/thread/threadlocals.py +++ b/pypy/module/thread/threadlocals.py @@ -77,5 +77,13 @@ def reinit_threads(self, space): "Called in the child process after a fork()" + # clear the _signalsenabled dictionary for all other threads + # (which are now dead); and for the current thread, force an + # enable_signals() if necessary. That's a hack but I cannot + # figure out a non-hackish way to handle thread+signal+fork :-( + ident = rthread.get_ident() + old = self._signalsenabled.get(ident, 0) self._signalsenabled.clear() - self.enable_signals() + if old == 0: + old = 1 + self._signalsenabled[ident] = old From noreply at buildbot.pypy.org Fri Feb 15 20:48:34 2013 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 15 Feb 2013 20:48:34 +0100 (CET) Subject: [pypy-commit] pypy default: Add a test_ztranslation. Message-ID: <20130215194834.82C671C062C@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r61284:541390dc2850 Date: 2013-02-15 19:48 +0100 http://bitbucket.org/pypy/pypy/changeset/541390dc2850/ Log: Add a test_ztranslation. diff --git a/pypy/module/gc/test/test_ztranslation.py b/pypy/module/gc/test/test_ztranslation.py new file mode 100644 --- /dev/null +++ b/pypy/module/gc/test/test_ztranslation.py @@ -0,0 +1,4 @@ +from pypy.objspace.fake.checkmodule import checkmodule + +def test_checkmodule(): + checkmodule('gc') From noreply at buildbot.pypy.org Fri Feb 15 20:48:35 2013 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 15 Feb 2013 20:48:35 +0100 (CET) Subject: [pypy-commit] pypy default: Change my mind again, and put 'signals_enabled' in the new module Message-ID: <20130215194835.BFDCB1C0673@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r61285:b931b891fb14 Date: 2013-02-15 19:49 +0100 http://bitbucket.org/pypy/pypy/changeset/b931b891fb14/ Log: Change my mind again, and put 'signals_enabled' in the new module '__pypy__.thread'. Thanks Alex. diff --git a/pypy/module/__pypy__/__init__.py b/pypy/module/__pypy__/__init__.py --- a/pypy/module/__pypy__/__init__.py +++ b/pypy/module/__pypy__/__init__.py @@ -26,6 +26,16 @@ interpleveldefs[name] = "space.wrap(interp_time.%s)" % name +class ThreadModule(MixedModule): + appleveldefs = { + 'signals_enabled': 'app_signal.signals_enabled', + } + interpleveldefs = { + '_signals_enter': 'interp_signal.signals_enter', + '_signals_exit': 'interp_signal.signals_exit', + } + + class Module(MixedModule): appleveldefs = { } @@ -54,6 +64,7 @@ submodules = { "builders": BuildersModule, "time": TimeModule, + "thread": ThreadModule, } def setup_after_space_initialization(self): diff --git a/pypy/module/thread/app_signal.py b/pypy/module/__pypy__/app_signal.py rename from pypy/module/thread/app_signal.py rename to pypy/module/__pypy__/app_signal.py --- a/pypy/module/thread/app_signal.py +++ b/pypy/module/__pypy__/app_signal.py @@ -1,4 +1,4 @@ -import thread +import __pypy__.thread class SignalsEnabled(object): '''A context manager to use in non-main threads: @@ -8,7 +8,7 @@ that is within a "with signals_enabled:". This other thread should be ready to handle unexpected exceptions that the signal handler might raise --- notably KeyboardInterrupt.''' - __enter__ = thread._signals_enter - __exit__ = thread._signals_exit + __enter__ = __pypy__.thread._signals_enter + __exit__ = __pypy__.thread._signals_exit signals_enabled = SignalsEnabled() diff --git a/pypy/module/thread/interp_signal.py b/pypy/module/__pypy__/interp_signal.py rename from pypy/module/thread/interp_signal.py rename to pypy/module/__pypy__/interp_signal.py diff --git a/pypy/module/thread/test/test_signal.py b/pypy/module/__pypy__/test/test_signal.py rename from pypy/module/thread/test/test_signal.py rename to pypy/module/__pypy__/test/test_signal.py --- a/pypy/module/thread/test/test_signal.py +++ b/pypy/module/__pypy__/test/test_signal.py @@ -2,17 +2,17 @@ class AppTestMinimal: - spaceconfig = dict(usemodules=['thread']) + spaceconfig = dict(usemodules=['__pypy__']) def test_signal(self): - import thread + from __pypy__ import thread with thread.signals_enabled: pass # assert did not crash class AppTestThreadSignal: - spaceconfig = dict(usemodules=['thread', 'signal']) + spaceconfig = dict(usemodules=['__pypy__', 'thread', 'signal']) def setup_class(cls): if (not cls.runappdirect or @@ -21,7 +21,7 @@ py.test.skip("this is only a test for -A runs on top of pypy") def test_enable_signals(self): - import thread, signal, time + import __pypy__, thread, signal, time # interrupted = [] lock = thread.allocate_lock() @@ -30,7 +30,7 @@ def subthread(): try: time.sleep(0.25) - with thread.signals_enabled: + with __pypy__.thread.signals_enabled: thread.interrupt_main() except BaseException, e: interrupted.append(e) diff --git a/pypy/module/signal/interp_signal.py b/pypy/module/signal/interp_signal.py --- a/pypy/module/signal/interp_signal.py +++ b/pypy/module/signal/interp_signal.py @@ -202,7 +202,7 @@ if not space.threadlocals.signals_enabled(): raise OperationError(space.w_ValueError, space.wrap("signal only works in main thread " - "or with thread.enable_signals()")) + "or with __pypy__.thread.enable_signals()")) check_signum_in_range(space, signum) if space.eq_w(w_handler, space.wrap(SIG_DFL)): @@ -235,7 +235,7 @@ raise OperationError( space.w_ValueError, space.wrap("set_wakeup_fd only works in main thread " - "or with thread.enable_signals()")) + "or with __pypy__.thread.enable_signals()")) old_fd = pypysig_set_wakeup_fd(fd) return space.wrap(intmask(old_fd)) diff --git a/pypy/module/thread/__init__.py b/pypy/module/thread/__init__.py --- a/pypy/module/thread/__init__.py +++ b/pypy/module/thread/__init__.py @@ -4,7 +4,6 @@ class Module(MixedModule): appleveldefs = { - 'signals_enabled': 'app_signal.signals_enabled', } interpleveldefs = { @@ -21,8 +20,6 @@ 'LockType': 'os_lock.Lock', '_local': 'os_local.Local', 'error': 'space.fromcache(error.Cache).w_error', - '_signals_enter': 'interp_signal.signals_enter', - '_signals_exit': 'interp_signal.signals_exit', } def __init__(self, space, *args): From noreply at buildbot.pypy.org Fri Feb 15 20:48:39 2013 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 15 Feb 2013 20:48:39 +0100 (CET) Subject: [pypy-commit] pypy stm-thread-2: hg merge default Message-ID: <20130215194839.D2F231C062C@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stm-thread-2 Changeset: r61286:9b9a490ef63e Date: 2013-02-15 19:56 +0100 http://bitbucket.org/pypy/pypy/changeset/9b9a490ef63e/ Log: hg merge default diff too long, truncating to 2000 out of 14064 lines diff --git a/LICENSE b/LICENSE --- a/LICENSE +++ b/LICENSE @@ -270,3 +270,24 @@ LineBreak-*.txt UnicodeData-*.txt UnihanNumeric-*.txt + +License for 'dotviewer/font/' +============================= + +Copyright (C) 2008 The Android Open Source Project + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +Detailled license information is contained in the NOTICE file in the +directory. + diff --git a/dotviewer/VeraMoBd.ttf b/dotviewer/VeraMoBd.ttf deleted file mode 100644 Binary file dotviewer/VeraMoBd.ttf has changed diff --git a/dotviewer/cyrvetic.ttf b/dotviewer/cyrvetic.ttf deleted file mode 100644 Binary file dotviewer/cyrvetic.ttf has changed diff --git a/dotviewer/drawgraph.py b/dotviewer/drawgraph.py --- a/dotviewer/drawgraph.py +++ b/dotviewer/drawgraph.py @@ -9,9 +9,10 @@ from pygame.locals import * +RAW_ENCODING = "utf-8" this_dir = os.path.dirname(os.path.abspath(__file__)) -FONT = os.path.join(this_dir, 'cyrvetic.ttf') -FIXEDFONT = os.path.join(this_dir, 'VeraMoBd.ttf') +FONT = os.path.join(this_dir, 'font', 'DroidSans.ttf') +FIXEDFONT = os.path.join(this_dir, 'font', 'DroidSansMono.ttf') COLOR = { 'black': (0,0,0), 'white': (255,255,255), @@ -51,6 +52,12 @@ else: return default +def forceunicode(name): + return name if isinstance(name, unicode) else name.decode(RAW_ENCODING) + +def forcestr(name): + return name if isinstance(name, str) else name.encode(RAW_ENCODING) + class GraphLayout: fixedfont = False @@ -106,12 +113,12 @@ class Node: def __init__(self, name, x, y, w, h, label, style, shape, color, fillcolor): - self.name = name + self.name = forceunicode(name) self.x = float(x) self.y = float(y) self.w = float(w) self.h = float(h) - self.label = label + self.label = forceunicode(label) self.style = style self.shape = shape self.color = color @@ -125,8 +132,8 @@ label = None def __init__(self, nodes, tail, head, cnt, *rest): - self.tail = nodes[tail] - self.head = nodes[head] + self.tail = nodes[forceunicode(tail)] + self.head = nodes[forceunicode(head)] cnt = int(cnt) self.points = [(float(rest[i]), float(rest[i+1])) for i in range(0, cnt*2, 2)] @@ -655,11 +662,7 @@ part = parts[i] word = part[0] try: - try: - img = font.render(word, False, *part[1:]) - except pygame.error, e: - # Try *with* anti-aliasing to work around a bug in SDL - img = font.render(word, True, *part[1:]) + img = font.render(word, True, *part[1:]) except pygame.error: del parts[i] # Text has zero width else: diff --git a/dotviewer/font/DroidSans-Bold.ttf b/dotviewer/font/DroidSans-Bold.ttf new file mode 100644 index 0000000000000000000000000000000000000000..d065b64eb1863f83c2c982264f9442f2313a44a9 GIT binary patch [cut] diff --git a/dotviewer/font/DroidSans.ttf b/dotviewer/font/DroidSans.ttf new file mode 100644 index 0000000000000000000000000000000000000000..ad1efca88aed8d9e2d179f27dd713e2a1562fe5f GIT binary patch [cut] diff --git a/dotviewer/font/DroidSansMono.ttf b/dotviewer/font/DroidSansMono.ttf new file mode 100644 index 0000000000000000000000000000000000000000..a007071944f7c90020e798eea53b10065e2b45a5 GIT binary patch [cut] diff --git a/dotviewer/font/NOTICE b/dotviewer/font/NOTICE new file mode 100644 --- /dev/null +++ b/dotviewer/font/NOTICE @@ -0,0 +1,190 @@ + + Copyright (c) 2005-2008, The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + diff --git a/dotviewer/font/README.txt b/dotviewer/font/README.txt new file mode 100644 --- /dev/null +++ b/dotviewer/font/README.txt @@ -0,0 +1,18 @@ +Copyright (C) 2008 The Android Open Source Project + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +########## + +This directory contains the fonts for the platform. They are licensed +under the Apache 2 license. diff --git a/dotviewer/graphclient.py b/dotviewer/graphclient.py --- a/dotviewer/graphclient.py +++ b/dotviewer/graphclient.py @@ -33,8 +33,9 @@ def reload(graph_id): page = getpage(graph_id) if save_tmp_file: + from drawgraph import forcestr f = open(save_tmp_file, 'w') - f.write(page.source) + f.write(forcestr(page.source)) f.close() messages.extend(page_messages(page, graph_id)) send_graph_messages(io, messages) @@ -75,7 +76,8 @@ def page_messages(page, graph_id): import graphparse - return graphparse.parse_dot(graph_id, page.source, page.links, + from drawgraph import forcestr + return graphparse.parse_dot(graph_id, forcestr(page.source), page.links, getattr(page, 'fixedfont', False)) def send_graph_messages(io, messages): diff --git a/dotviewer/graphdisplay.py b/dotviewer/graphdisplay.py --- a/dotviewer/graphdisplay.py +++ b/dotviewer/graphdisplay.py @@ -4,7 +4,7 @@ from pygame.locals import * from drawgraph import GraphRenderer, FIXEDFONT from drawgraph import Node, Edge -from drawgraph import EventQueue, wait_for_events +from drawgraph import EventQueue, wait_for_events, forceunicode, forcestr METAKEYS = dict([ @@ -285,7 +285,7 @@ if e.key == K_ESCAPE: return None elif e.key == K_RETURN: - return text.encode('latin-1') # XXX do better + return forcestr(text) # return encoded unicode elif e.key == K_BACKSPACE: text = text[:-1] elif e.unicode and ord(e.unicode) >= ord(' '): @@ -423,7 +423,7 @@ self.layout.request_reload() def setstatusbar(self, text, fgcolor=None, bgcolor=None): - info = (text, fgcolor or self.STATUSBAR_FGCOLOR, bgcolor or self.STATUSBAR_BGCOLOR) + info = (forceunicode(text), fgcolor or self.STATUSBAR_FGCOLOR, bgcolor or self.STATUSBAR_BGCOLOR) if info != self.statusbarinfo: self.statusbarinfo = info self.must_redraw = True @@ -711,7 +711,7 @@ lines = [] while words: line = words.pop(0) - img = font.render(line or ' ', 1, fgcolor) + img = font.render(line or ' ', True, fgcolor) while words: longerline = line + ' ' + words[0] longerimg = font.render(longerline, 1, fgcolor) @@ -723,7 +723,7 @@ img = longerimg w, h = img.get_size() if h > maxheight: - img = font.render('...', 1, overflowcolor) + img = font.render('...', True, overflowcolor) w, h = img.get_size() while lines and h > maxheight: maxheight += lines.pop().get_size()[1] diff --git a/dotviewer/graphpage.py b/dotviewer/graphpage.py --- a/dotviewer/graphpage.py +++ b/dotviewer/graphpage.py @@ -44,6 +44,8 @@ class DotFileGraphPage(GraphPage): def compute(self, dotfile): - f = open(dotfile, 'r') + import codecs + from drawgraph import RAW_ENCODING + f = codecs.open(dotfile, 'r', RAW_ENCODING) self.source = f.read() f.close() diff --git a/dotviewer/test/test_interactive_unicode.py b/dotviewer/test/test_interactive_unicode.py new file mode 100755 --- /dev/null +++ b/dotviewer/test/test_interactive_unicode.py @@ -0,0 +1,103 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +import py +import sys, os, signal, thread, time, codecs +from dotviewer.conftest import option +from dotviewer.drawgraph import RAW_ENCODING + +SOURCE1 = u"""digraph G{ +λ -> b +b -> μ +} +""" + +FILENAME = 'graph1.dot' + +def setup_module(mod): + if not option.pygame: + py.test.skip("--pygame not enabled") + udir = py.path.local.make_numbered_dir(prefix='usession-dot-', keep=3) + f = codecs.open(str(udir.join(FILENAME)), 'wb', RAW_ENCODING) + f.write(SOURCE1) + f.close() + + from dotviewer import graphclient + mod.pkgdir = py.path.local(graphclient.this_dir) + mod.udir = udir + + try: + del os.environ['GRAPHSERVER'] + except KeyError: + pass + + +def test_dotviewer(): + print "=== dotviewer.py %s" % FILENAME + err = os.system('"%s" "%s"' % (pkgdir.join('dotviewer.py'), + udir.join(FILENAME))) + assert err == 0 + + plain_name = FILENAME.replace('.dot','.plain') + + os.system('dot -Tplain "%s" > "%s"' % (udir.join(FILENAME), + udir.join(plain_name))) + print "=== dotviewer.py %s" % plain_name + err = os.system('"%s" "%s"' % (pkgdir.join('dotviewer.py'), + udir.join(plain_name))) + assert err == 0 + +def test_display_dot_file(): + from dotviewer.graphclient import display_dot_file + print "=== display_dot_file(%s) with GRAPHSERVER=%s" % ( + FILENAME, os.environ.get('GRAPHSERVER', ''),) + display_dot_file(udir.join(FILENAME)) + print "=== display_dot_file finished" + + +def test_graphserver(): + import socket + s = socket.socket() + s.listen(1) + host, port = s.getsockname() # pick a random free port + s.close() + + if hasattr(sys, 'pypy_objspaceclass'): + python = 'python' + else: + python = sys.executable + + cmdargs = [python, str(pkgdir.join('graphserver.py')), + str(port)] + print '* starting:', ' '.join(cmdargs) + pid = os.spawnv(os.P_NOWAIT, cmdargs[0], cmdargs) + try: + time.sleep(1) # hack - wait a bit to make sure the server is up + os.environ['GRAPHSERVER'] = '%s:%d' % (host, port) + try: + test_display_dot_file() + finally: + del os.environ['GRAPHSERVER'] + finally: + os.kill(pid, signal.SIGTERM) + +def test_colors(): + from dotviewer import graphpage, graphclient + class MyPage(graphpage.DotFileGraphPage): + def compute(self, dotfile): + super(MyPage, self).compute(dotfile) + self.links = {'v2721': 'Hello world', + 'v2720': ('Something green', (0, 192, 0)), + } + dotfile = str(udir.join(FILENAME)) + page = MyPage(dotfile) + graphclient.display_page(page) + +def test_fixedfont(): + from dotviewer import graphpage, graphclient + class MyPage(graphpage.DotFileGraphPage): + fixedfont = True + dotfile = str(udir.join(FILENAME)) + page = MyPage(dotfile) + page.fixedfont = True + graphclient.display_page(page) diff --git a/dotviewer/test/test_translator.py b/dotviewer/test/test_translator.py --- a/dotviewer/test/test_translator.py +++ b/dotviewer/test/test_translator.py @@ -22,6 +22,6 @@ def test_annotated(): from rpython.translator.interactive import Translation - t = Translation(is_prime) - t.annotate([int]) + t = Translation(is_prime, [int]) + t.annotate() t.viewcg() diff --git a/dotviewer/test/test_unicode_util.py b/dotviewer/test/test_unicode_util.py new file mode 100755 --- /dev/null +++ b/dotviewer/test/test_unicode_util.py @@ -0,0 +1,57 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +import py +import codecs +from dotviewer.drawgraph import RAW_ENCODING, forcestr, forceunicode + +SOURCE1 = u"""digraph G{ +λ -> b +b -> μ +} +""" + +FILENAME = 'test.dot' + +class TestUnicodeUtil(object): + + def test_idempotent(self): + x = u"a" + assert forceunicode(forcestr(x)) == x + + x = u"λ" + assert forceunicode(forcestr(x)) == x + + assert forceunicode(forcestr(SOURCE1)) == SOURCE1 + + x = "a" + assert forcestr(forceunicode(x)) == x + + # utf-8 encoded. + # fragile, does not consider RAW_ENCODING + # x = "\xef\xbb\xbf\xce\xbb" + # assert forcestr(forceunicode(x)) == x + + def test_does_not_double_encode(self): + x = u"λ" + x_e = forcestr(x) + assert forcestr(x_e) == x_e + + x_u = forceunicode(x_e) + assert forceunicode(x_u) == x_u + + def test_file(self): + udir = py.path.local.make_numbered_dir(prefix='usession-dot-', keep=3) + full_filename = str(udir.join(FILENAME)) + f = codecs.open(full_filename, 'wb', RAW_ENCODING) + f.write(SOURCE1) + f.close() + + with open(full_filename) as f1: + assert forceunicode(f1.read()) == SOURCE1 + + f3 = codecs.open(full_filename, 'r', RAW_ENCODING) + c = f3.read() + f3.close() + result = (c == SOURCE1) + assert result diff --git a/lib-python/2.7/collections.py b/lib-python/2.7/collections.py --- a/lib-python/2.7/collections.py +++ b/lib-python/2.7/collections.py @@ -6,11 +6,12 @@ __all__ += _abcoll.__all__ from _collections import deque, defaultdict -from operator import itemgetter as _itemgetter +from operator import itemgetter as _itemgetter, eq as _eq from keyword import iskeyword as _iskeyword import sys as _sys import heapq as _heapq from itertools import repeat as _repeat, chain as _chain, starmap as _starmap +from itertools import imap as _imap try: from thread import get_ident as _get_ident @@ -50,49 +51,45 @@ self.__map = {} self.__update(*args, **kwds) - def __setitem__(self, key, value, PREV=0, NEXT=1, dict_setitem=dict.__setitem__): + def __setitem__(self, key, value, dict_setitem=dict.__setitem__): 'od.__setitem__(i, y) <==> od[i]=y' # Setting a new item creates a new link at the end of the linked list, # and the inherited dictionary is updated with the new key/value pair. if key not in self: root = self.__root - last = root[PREV] - last[NEXT] = root[PREV] = self.__map[key] = [last, root, key] - dict_setitem(self, key, value) + last = root[0] + last[1] = root[0] = self.__map[key] = [last, root, key] + return dict_setitem(self, key, value) - def __delitem__(self, key, PREV=0, NEXT=1, dict_delitem=dict.__delitem__): + def __delitem__(self, key, dict_delitem=dict.__delitem__): 'od.__delitem__(y) <==> del od[y]' # Deleting an existing item uses self.__map to find the link which gets # removed by updating the links in the predecessor and successor nodes. dict_delitem(self, key) link_prev, link_next, key = self.__map.pop(key) - link_prev[NEXT] = link_next - link_next[PREV] = link_prev + link_prev[1] = link_next # update link_prev[NEXT] + link_next[0] = link_prev # update link_next[PREV] def __iter__(self): 'od.__iter__() <==> iter(od)' # Traverse the linked list in order. - NEXT, KEY = 1, 2 root = self.__root - curr = root[NEXT] + curr = root[1] # start at the first node while curr is not root: - yield curr[KEY] - curr = curr[NEXT] + yield curr[2] # yield the curr[KEY] + curr = curr[1] # move to next node def __reversed__(self): 'od.__reversed__() <==> reversed(od)' # Traverse the linked list in reverse order. - PREV, KEY = 0, 2 root = self.__root - curr = root[PREV] + curr = root[0] # start at the last node while curr is not root: - yield curr[KEY] - curr = curr[PREV] + yield curr[2] # yield the curr[KEY] + curr = curr[0] # move to previous node def clear(self): 'od.clear() -> None. Remove all items from od.' - for node in self.__map.itervalues(): - del node[:] root = self.__root root[:] = [root, root, None] self.__map.clear() @@ -208,7 +205,7 @@ ''' if isinstance(other, OrderedDict): - return len(self)==len(other) and self.items() == other.items() + return dict.__eq__(self, other) and all(_imap(_eq, self, other)) return dict.__eq__(self, other) def __ne__(self, other): @@ -323,13 +320,13 @@ 'Return self as a plain tuple. Used by copy and pickle.' return tuple(self) \n\n''' % locals() for i, name in enumerate(field_names): - template += " %s = _property(_itemgetter(%d), doc='Alias for field number %d')\n" % (name, i, i) + template += " %s = _property(lambda self: self[%d], doc='Alias for field number %d')\n" % (name, i, i) if verbose: print template # Execute the template string in a temporary namespace and # support tracing utilities by setting a value for frame.f_globals['__name__'] - namespace = dict(_itemgetter=_itemgetter, __name__='namedtuple_%s' % typename, + namespace = dict(__name__='namedtuple_%s' % typename, OrderedDict=OrderedDict, _property=property, _tuple=tuple) try: exec template in namespace diff --git a/lib-python/2.7/json/encoder.py b/lib-python/2.7/json/encoder.py --- a/lib-python/2.7/json/encoder.py +++ b/lib-python/2.7/json/encoder.py @@ -138,16 +138,16 @@ self.skipkeys = skipkeys self.ensure_ascii = ensure_ascii if ensure_ascii: - self.encoder = raw_encode_basestring_ascii + self.__encoder = raw_encode_basestring_ascii else: - self.encoder = raw_encode_basestring + self.__encoder = raw_encode_basestring if encoding != 'utf-8': - orig_encoder = self.encoder + orig_encoder = self.__encoder def encoder(o): if isinstance(o, str): o = o.decode(encoding) return orig_encoder(o) - self.encoder = encoder + self.__encoder = encoder self.check_circular = check_circular self.allow_nan = allow_nan self.sort_keys = sort_keys @@ -193,10 +193,10 @@ builder = StringBuilder() else: builder = UnicodeBuilder() - self._encode(o, markers, builder, 0) + self.__encode(o, markers, builder, 0) return builder.build() - def _emit_indent(self, builder, _current_indent_level): + def __emit_indent(self, builder, _current_indent_level): if self.indent is not None: _current_indent_level += 1 newline_indent = '\n' + (' ' * (self.indent * @@ -207,15 +207,15 @@ separator = self.item_separator return separator, _current_indent_level - def _emit_unindent(self, builder, _current_indent_level): + def __emit_unindent(self, builder, _current_indent_level): if self.indent is not None: builder.append('\n') builder.append(' ' * (self.indent * (_current_indent_level - 1))) - def _encode(self, o, markers, builder, _current_indent_level): + def __encode(self, o, markers, builder, _current_indent_level): if isinstance(o, basestring): builder.append('"') - builder.append(self.encoder(o)) + builder.append(self.__encoder(o)) builder.append('"') elif o is None: builder.append('null') @@ -226,46 +226,46 @@ elif isinstance(o, (int, long)): builder.append(str(o)) elif isinstance(o, float): - builder.append(self._floatstr(o)) + builder.append(self.__floatstr(o)) elif isinstance(o, (list, tuple)): if not o: builder.append('[]') return - self._encode_list(o, markers, builder, _current_indent_level) + self.__encode_list(o, markers, builder, _current_indent_level) elif isinstance(o, dict): if not o: builder.append('{}') return - self._encode_dict(o, markers, builder, _current_indent_level) + self.__encode_dict(o, markers, builder, _current_indent_level) else: - self._mark_markers(markers, o) + self.__mark_markers(markers, o) res = self.default(o) - self._encode(res, markers, builder, _current_indent_level) - self._remove_markers(markers, o) + self.__encode(res, markers, builder, _current_indent_level) + self.__remove_markers(markers, o) return res - def _encode_list(self, l, markers, builder, _current_indent_level): - self._mark_markers(markers, l) + def __encode_list(self, l, markers, builder, _current_indent_level): + self.__mark_markers(markers, l) builder.append('[') first = True - separator, _current_indent_level = self._emit_indent(builder, + separator, _current_indent_level = self.__emit_indent(builder, _current_indent_level) for elem in l: if first: first = False else: builder.append(separator) - self._encode(elem, markers, builder, _current_indent_level) + self.__encode(elem, markers, builder, _current_indent_level) del elem # XXX grumble - self._emit_unindent(builder, _current_indent_level) + self.__emit_unindent(builder, _current_indent_level) builder.append(']') - self._remove_markers(markers, l) + self.__remove_markers(markers, l) - def _encode_dict(self, d, markers, builder, _current_indent_level): - self._mark_markers(markers, d) + def __encode_dict(self, d, markers, builder, _current_indent_level): + self.__mark_markers(markers, d) first = True builder.append('{') - separator, _current_indent_level = self._emit_indent(builder, + separator, _current_indent_level = self.__emit_indent(builder, _current_indent_level) if self.sort_keys: items = sorted(d.items(), key=lambda kv: kv[0]) @@ -282,7 +282,7 @@ # JavaScript is weakly typed for these, so it makes sense to # also allow them. Many encoders seem to do something like this. elif isinstance(key, float): - key = self._floatstr(key) + key = self.__floatstr(key) elif key is True: key = 'true' elif key is False: @@ -296,15 +296,15 @@ else: raise TypeError("key " + repr(key) + " is not a string") builder.append('"') - builder.append(self.encoder(key)) + builder.append(self.__encoder(key)) builder.append('"') builder.append(self.key_separator) - self._encode(v, markers, builder, _current_indent_level) + self.__encode(v, markers, builder, _current_indent_level) del key del v # XXX grumble - self._emit_unindent(builder, _current_indent_level) + self.__emit_unindent(builder, _current_indent_level) builder.append('}') - self._remove_markers(markers, d) + self.__remove_markers(markers, d) def iterencode(self, o, _one_shot=False): """Encode the given object and yield each string @@ -320,9 +320,9 @@ markers = {} else: markers = None - return self._iterencode(o, markers, 0) + return self.__iterencode(o, markers, 0) - def _floatstr(self, o): + def __floatstr(self, o): # Check for specials. Note that this type of test is processor # and/or platform-specific, so do tests which don't depend on the # internals. @@ -343,21 +343,21 @@ return text - def _mark_markers(self, markers, o): + def __mark_markers(self, markers, o): if markers is not None: if id(o) in markers: raise ValueError("Circular reference detected") markers[id(o)] = None - def _remove_markers(self, markers, o): + def __remove_markers(self, markers, o): if markers is not None: del markers[id(o)] - def _iterencode_list(self, lst, markers, _current_indent_level): + def __iterencode_list(self, lst, markers, _current_indent_level): if not lst: yield '[]' return - self._mark_markers(markers, lst) + self.__mark_markers(markers, lst) buf = '[' if self.indent is not None: _current_indent_level += 1 @@ -375,7 +375,7 @@ else: buf = separator if isinstance(value, basestring): - yield buf + '"' + self.encoder(value) + '"' + yield buf + '"' + self.__encoder(value) + '"' elif value is None: yield buf + 'null' elif value is True: @@ -385,17 +385,17 @@ elif isinstance(value, (int, long)): yield buf + str(value) elif isinstance(value, float): - yield buf + self._floatstr(value) + yield buf + self.__floatstr(value) else: yield buf if isinstance(value, (list, tuple)): - chunks = self._iterencode_list(value, markers, + chunks = self.__iterencode_list(value, markers, _current_indent_level) elif isinstance(value, dict): - chunks = self._iterencode_dict(value, markers, + chunks = self.__iterencode_dict(value, markers, _current_indent_level) else: - chunks = self._iterencode(value, markers, + chunks = self.__iterencode(value, markers, _current_indent_level) for chunk in chunks: yield chunk @@ -403,13 +403,13 @@ _current_indent_level -= 1 yield '\n' + (' ' * (self.indent * _current_indent_level)) yield ']' - self._remove_markers(markers, lst) + self.__remove_markers(markers, lst) - def _iterencode_dict(self, dct, markers, _current_indent_level): + def __iterencode_dict(self, dct, markers, _current_indent_level): if not dct: yield '{}' return - self._mark_markers(markers, dct) + self.__mark_markers(markers, dct) yield '{' if self.indent is not None: _current_indent_level += 1 @@ -431,7 +431,7 @@ # JavaScript is weakly typed for these, so it makes sense to # also allow them. Many encoders seem to do something like this. elif isinstance(key, float): - key = self._floatstr(key) + key = self.__floatstr(key) elif key is True: key = 'true' elif key is False: @@ -448,10 +448,10 @@ first = False else: yield item_separator - yield '"' + self.encoder(key) + '"' + yield '"' + self.__encoder(key) + '"' yield self.key_separator if isinstance(value, basestring): - yield '"' + self.encoder(value) + '"' + yield '"' + self.__encoder(value) + '"' elif value is None: yield 'null' elif value is True: @@ -461,16 +461,16 @@ elif isinstance(value, (int, long)): yield str(value) elif isinstance(value, float): - yield self._floatstr(value) + yield self.__floatstr(value) else: if isinstance(value, (list, tuple)): - chunks = self._iterencode_list(value, markers, + chunks = self.__iterencode_list(value, markers, _current_indent_level) elif isinstance(value, dict): - chunks = self._iterencode_dict(value, markers, + chunks = self.__iterencode_dict(value, markers, _current_indent_level) else: - chunks = self._iterencode(value, markers, + chunks = self.__iterencode(value, markers, _current_indent_level) for chunk in chunks: yield chunk @@ -478,11 +478,11 @@ _current_indent_level -= 1 yield '\n' + (' ' * (self.indent * _current_indent_level)) yield '}' - self._remove_markers(markers, dct) + self.__remove_markers(markers, dct) - def _iterencode(self, o, markers, _current_indent_level): + def __iterencode(self, o, markers, _current_indent_level): if isinstance(o, basestring): - yield '"' + self.encoder(o) + '"' + yield '"' + self.__encoder(o) + '"' elif o is None: yield 'null' elif o is True: @@ -492,19 +492,19 @@ elif isinstance(o, (int, long)): yield str(o) elif isinstance(o, float): - yield self._floatstr(o) + yield self.__floatstr(o) elif isinstance(o, (list, tuple)): - for chunk in self._iterencode_list(o, markers, + for chunk in self.__iterencode_list(o, markers, _current_indent_level): yield chunk elif isinstance(o, dict): - for chunk in self._iterencode_dict(o, markers, + for chunk in self.__iterencode_dict(o, markers, _current_indent_level): yield chunk else: - self._mark_markers(markers, o) + self.__mark_markers(markers, o) obj = self.default(o) - for chunk in self._iterencode(obj, markers, + for chunk in self.__iterencode(obj, markers, _current_indent_level): yield chunk - self._remove_markers(markers, o) + self.__remove_markers(markers, o) diff --git a/lib-python/2.7/test/test_generators.py b/lib-python/2.7/test/test_generators.py --- a/lib-python/2.7/test/test_generators.py +++ b/lib-python/2.7/test/test_generators.py @@ -1501,9 +1501,7 @@ """ coroutine_tests = """\ -A helper function to call gc.collect() without printing ->>> import gc ->>> def gc_collect(): gc.collect() +>>> from test.test_support import gc_collect Sending a value into a started generator: @@ -1823,8 +1821,7 @@ references. We add it to the standard suite so the routine refleak-tests would trigger if it starts being uncleanable again. ->>> import gc ->>> def gc_collect(): gc.collect() +>>> from test.test_support import gc_collect >>> import itertools >>> def leak(): diff --git a/lib-python/2.7/test/test_modulefinder.py b/lib-python/2.7/test/test_modulefinder.py --- a/lib-python/2.7/test/test_modulefinder.py +++ b/lib-python/2.7/test/test_modulefinder.py @@ -16,7 +16,7 @@ # library. TEST_DIR = tempfile.mkdtemp() -TEST_PATH = [TEST_DIR, os.path.dirname(__future__.__file__)] +TEST_PATH = [TEST_DIR, os.path.dirname(tempfile.__file__)] # Each test description is a list of 5 items: # diff --git a/lib-python/2.7/urllib.py b/lib-python/2.7/urllib.py --- a/lib-python/2.7/urllib.py +++ b/lib-python/2.7/urllib.py @@ -1205,15 +1205,17 @@ # fastpath if len(res) == 1: return s - s = res[0] - for item in res[1:]: + res_list = [res[0]] + for j in xrange(1, len(res)): + item = res[j] try: - s += _hextochr[item[:2]] + item[2:] + x = _hextochr[item[:2]] + item[2:] except KeyError: - s += '%' + item + x = '%' + item except UnicodeDecodeError: - s += unichr(int(item[:2], 16)) + item[2:] - return s + x = unichr(int(item[:2], 16)) + item[2:] + res_list.append(x) + return ''.join(res_list) def unquote_plus(s): """unquote('%7e/abc+def') -> '~/abc def'""" diff --git a/lib-python/2.7/urlparse.py b/lib-python/2.7/urlparse.py --- a/lib-python/2.7/urlparse.py +++ b/lib-python/2.7/urlparse.py @@ -321,15 +321,17 @@ # fastpath if len(res) == 1: return s - s = res[0] - for item in res[1:]: + res_list = [res[0]] + for j in xrange(1, len(res)): + item = res[j] try: - s += _hextochr[item[:2]] + item[2:] + x = _hextochr[item[:2]] + item[2:] except KeyError: - s += '%' + item + x = '%' + item except UnicodeDecodeError: - s += unichr(int(item[:2], 16)) + item[2:] - return s + x = unichr(int(item[:2], 16)) + item[2:] + res_list.append(x) + return ''.join(res_list) def parse_qs(qs, keep_blank_values=0, strict_parsing=0): """Parse a query given as a string argument. diff --git a/lib-python/conftest.py b/lib-python/conftest.py --- a/lib-python/conftest.py +++ b/lib-python/conftest.py @@ -160,7 +160,7 @@ RegrTest('test_codeop.py', core=True), RegrTest('test_coding.py', core=True), RegrTest('test_coercion.py', core=True), - RegrTest('test_collections.py'), + RegrTest('test_collections.py', usemodules='binascii struct'), RegrTest('test_colorsys.py'), RegrTest('test_commands.py'), RegrTest('test_compare.py', core=True), @@ -181,7 +181,7 @@ RegrTest('test_csv.py', usemodules='_csv'), RegrTest('test_ctypes.py', usemodules="_rawffi thread"), RegrTest('test_curses.py'), - RegrTest('test_datetime.py'), + RegrTest('test_datetime.py', usemodules='binascii struct'), RegrTest('test_dbm.py'), RegrTest('test_decimal.py'), RegrTest('test_decorators.py', core=True), @@ -272,7 +272,7 @@ RegrTest('test_inspect.py'), RegrTest('test_int.py', core=True), RegrTest('test_int_literal.py', core=True), - RegrTest('test_io.py'), + RegrTest('test_io.py', usemodules='array binascii'), RegrTest('test_ioctl.py'), RegrTest('test_isinstance.py', core=True), RegrTest('test_iter.py', core=True), diff --git a/lib_pypy/_collections.py b/lib_pypy/_collections.py --- a/lib_pypy/_collections.py +++ b/lib_pypy/_collections.py @@ -142,18 +142,24 @@ return c def remove(self, value): - # Need to be defensive for mutating comparisons - for i in range(len(self)): - if self[i] == value: - del self[i] - return - raise ValueError("deque.remove(x): x not in deque") + # Need to defend mutating or failing comparisons + i = 0 + try: + for i in range(len(self)): + if self[0] == value: + self.popleft() + return + self.append(self.popleft()) + i += 1 + raise ValueError("deque.remove(x): x not in deque") + finally: + self.rotate(i) def rotate(self, n=1): length = len(self) - if length == 0: + if length <= 1: return - halflen = (length+1) >> 1 + halflen = length >> 1 if n > halflen or n < -halflen: n %= length if n > halflen: diff --git a/lib_pypy/cPickle.py b/lib_pypy/cPickle.py --- a/lib_pypy/cPickle.py +++ b/lib_pypy/cPickle.py @@ -1,5 +1,5 @@ # -# One-liner implementation of cPickle +# Reimplementation of cPickle, mostly as a copy of pickle.py # from pickle import Pickler, dump, dumps, PickleError, PicklingError, UnpicklingError, _EmptyClass @@ -131,6 +131,13 @@ # Unpickling machinery +class _Stack(list): + def pop(self, index=-1): + try: + return list.pop(self, index) + except IndexError: + raise UnpicklingError("unpickling stack underflow") + class Unpickler(object): def __init__(self, file): @@ -155,7 +162,7 @@ Return the reconstituted object hierarchy specified in the file. """ self.mark = object() # any new unique object - self.stack = [] + self.stack = _Stack() self.append = self.stack.append try: key = ord(self.read(1)) diff --git a/lib_pypy/conftest.py b/lib_pypy/conftest.py deleted file mode 100644 --- a/lib_pypy/conftest.py +++ /dev/null @@ -1,2 +0,0 @@ - -from pypy.conftest import * diff --git a/lib_pypy/ctypes_support.py b/lib_pypy/ctypes_support.py --- a/lib_pypy/ctypes_support.py +++ b/lib_pypy/ctypes_support.py @@ -19,16 +19,19 @@ if sys.platform == 'win32': standard_c_lib._errno.restype = ctypes.POINTER(ctypes.c_int) + standard_c_lib._errno.argtypes = None def _where_is_errno(): return standard_c_lib._errno() elif sys.platform in ('linux2', 'freebsd6'): standard_c_lib.__errno_location.restype = ctypes.POINTER(ctypes.c_int) + standard_c_lib.__errno_location.argtypes = None def _where_is_errno(): return standard_c_lib.__errno_location() elif sys.platform in ('darwin', 'freebsd7', 'freebsd8', 'freebsd9'): standard_c_lib.__error.restype = ctypes.POINTER(ctypes.c_int) + standard_c_lib.__error.argtypes = None def _where_is_errno(): return standard_c_lib.__error() diff --git a/lib_pypy/datetime.py b/lib_pypy/datetime.py --- a/lib_pypy/datetime.py +++ b/lib_pypy/datetime.py @@ -270,10 +270,21 @@ return offset raise ValueError("%s()=%d, must be in -1439..1439" % (name, offset)) +def _check_int_field(value): + if not isinstance(value, float): + try: + value = value.__int__() + except AttributeError: + pass + else: + if isinstance(value, (int, long)): + return value + raise TypeError('integer argument expected') + def _check_date_fields(year, month, day): - for value in [year, day]: - if not isinstance(value, (int, long)): - raise TypeError('int expected') + year = _check_int_field(year) + month = _check_int_field(month) + day = _check_int_field(day) if not MINYEAR <= year <= MAXYEAR: raise ValueError('year must be in %d..%d' % (MINYEAR, MAXYEAR), year) if not 1 <= month <= 12: @@ -281,11 +292,13 @@ dim = _days_in_month(year, month) if not 1 <= day <= dim: raise ValueError('day must be in 1..%d' % dim, day) + return year, month, day def _check_time_fields(hour, minute, second, microsecond): - for value in [hour, minute, second, microsecond]: - if not isinstance(value, (int, long)): - raise TypeError('int expected') + hour = _check_int_field(hour) + minute = _check_int_field(minute) + second = _check_int_field(second) + microsecond = _check_int_field(microsecond) if not 0 <= hour <= 23: raise ValueError('hour must be in 0..23', hour) if not 0 <= minute <= 59: @@ -294,6 +307,7 @@ raise ValueError('second must be in 0..59', second) if not 0 <= microsecond <= 999999: raise ValueError('microsecond must be in 0..999999', microsecond) + return hour, minute, second, microsecond def _check_tzinfo_arg(tz): if tz is not None and not isinstance(tz, tzinfo): @@ -768,7 +782,7 @@ self = object.__new__(cls) self.__setstate(year) return self - _check_date_fields(year, month, day) + year, month, day = _check_date_fields(year, month, day) self = object.__new__(cls) self._year = year self._month = month @@ -889,7 +903,7 @@ month = self._month if day is None: day = self._day - _check_date_fields(year, month, day) + year, month, day = _check_date_fields(year, month, day) return date(year, month, day) # Comparisons of date objects with other. @@ -1150,13 +1164,14 @@ second, microsecond (default to zero) tzinfo (default to None) """ - self = object.__new__(cls) if isinstance(hour, str): # Pickle support + self = object.__new__(cls) self.__setstate(hour, minute or None) return self + hour, minute, second, microsecond = _check_time_fields(hour, minute, second, microsecond) _check_tzinfo_arg(tzinfo) - _check_time_fields(hour, minute, second, microsecond) + self = object.__new__(cls) self._hour = hour self._minute = minute self._second = second @@ -1387,7 +1402,7 @@ microsecond = self.microsecond if tzinfo is True: tzinfo = self.tzinfo - _check_time_fields(hour, minute, second, microsecond) + hour, minute, second, microsecond = _check_time_fields(hour, minute, second, microsecond) _check_tzinfo_arg(tzinfo) return time(hour, minute, second, microsecond, tzinfo) @@ -1449,10 +1464,10 @@ self = date.__new__(cls, year[:4]) self.__setstate(year, month) return self + year, month, day = _check_date_fields(year, month, day) + hour, minute, second, microsecond = _check_time_fields(hour, minute, second, microsecond) _check_tzinfo_arg(tzinfo) - _check_time_fields(hour, minute, second, microsecond) - self = date.__new__(cls, year, month, day) - # XXX This duplicates __year, __month, __day for convenience :-( + self = object.__new__(cls) self._year = year self._month = month self._day = day @@ -1617,8 +1632,8 @@ microsecond = self.microsecond if tzinfo is True: tzinfo = self.tzinfo - _check_date_fields(year, month, day) - _check_time_fields(hour, minute, second, microsecond) + year, month, day = _check_date_fields(year, month, day) + hour, minute, second, microsecond = _check_time_fields(hour, minute, second, microsecond) _check_tzinfo_arg(tzinfo) return datetime(year, month, day, hour, minute, second, microsecond, tzinfo) diff --git a/lib_pypy/dbm.py b/lib_pypy/dbm.py --- a/lib_pypy/dbm.py +++ b/lib_pypy/dbm.py @@ -1,4 +1,4 @@ -from ctypes import Structure, c_char_p, c_int, c_void_p, CDLL +from ctypes import Structure, c_char_p, c_int, c_void_p, CDLL, POINTER, c_char import ctypes.util import os, sys @@ -11,7 +11,7 @@ class datum(Structure): _fields_ = [ - ('dptr', c_char_p), + ('dptr', POINTER(c_char)), ('dsize', c_int), ] @@ -126,8 +126,8 @@ libpath = ctypes.util.find_library('db') if not libpath: # XXX this is hopeless... - for c in '56789': - libpath = ctypes.util.find_library('db-4.%s' % c) + for c in ['5.3', '5.2', '5.1', '5.0', '4.9', '4.8', '4.7', '4.6', '4.5']: + libpath = ctypes.util.find_library('db-%s' % c) if libpath: break else: diff --git a/lib_pypy/greenlet.py b/lib_pypy/greenlet.py --- a/lib_pypy/greenlet.py +++ b/lib_pypy/greenlet.py @@ -1,5 +1,6 @@ import _continuation, sys +__version__ = "0.4.0" # ____________________________________________________________ # Exceptions @@ -57,7 +58,8 @@ def __switch(target, methodname, *args): current = getcurrent() # - while not target: + while not (target.__main or _continulet.is_pending(target)): + # inlined __nonzero__ ^^^ in case it's overridden if not target.__started: if methodname == 'switch': greenlet_func = _greenlet_start diff --git a/lib_pypy/numpypy/core/__init__.py b/lib_pypy/numpypy/core/__init__.py --- a/lib_pypy/numpypy/core/__init__.py +++ b/lib_pypy/numpypy/core/__init__.py @@ -1,2 +1,3 @@ from .fromnumeric import * from .numeric import * +from .shape_base import * diff --git a/lib_pypy/numpypy/core/numeric.py b/lib_pypy/numpypy/core/numeric.py --- a/lib_pypy/numpypy/core/numeric.py +++ b/lib_pypy/numpypy/core/numeric.py @@ -428,3 +428,76 @@ True_ = bool_(True) e = math.e pi = math.pi + +def outer(a,b): + """ + Compute the outer product of two vectors. + + Given two vectors, ``a = [a0, a1, ..., aM]`` and + ``b = [b0, b1, ..., bN]``, + the outer product [1]_ is:: + + [[a0*b0 a0*b1 ... a0*bN ] + [a1*b0 . + [ ... . + [aM*b0 aM*bN ]] + + Parameters + ---------- + a, b : array_like, shape (M,), (N,) + First and second input vectors. Inputs are flattened if they + are not already 1-dimensional. + + Returns + ------- + out : ndarray, shape (M, N) + ``out[i, j] = a[i] * b[j]`` + + See also + -------- + inner, einsum + + References + ---------- + .. [1] : G. H. Golub and C. F. van Loan, *Matrix Computations*, 3rd + ed., Baltimore, MD, Johns Hopkins University Press, 1996, + pg. 8. + + Examples + -------- + Make a (*very* coarse) grid for computing a Mandelbrot set: + + >>> rl = np.outer(np.ones((5,)), np.linspace(-2, 2, 5)) + >>> rl + array([[-2., -1., 0., 1., 2.], + [-2., -1., 0., 1., 2.], + [-2., -1., 0., 1., 2.], + [-2., -1., 0., 1., 2.], + [-2., -1., 0., 1., 2.]]) + >>> im = np.outer(1j*np.linspace(2, -2, 5), np.ones((5,))) + >>> im + array([[ 0.+2.j, 0.+2.j, 0.+2.j, 0.+2.j, 0.+2.j], + [ 0.+1.j, 0.+1.j, 0.+1.j, 0.+1.j, 0.+1.j], + [ 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j], + [ 0.-1.j, 0.-1.j, 0.-1.j, 0.-1.j, 0.-1.j], + [ 0.-2.j, 0.-2.j, 0.-2.j, 0.-2.j, 0.-2.j]]) + >>> grid = rl + im + >>> grid + array([[-2.+2.j, -1.+2.j, 0.+2.j, 1.+2.j, 2.+2.j], + [-2.+1.j, -1.+1.j, 0.+1.j, 1.+1.j, 2.+1.j], + [-2.+0.j, -1.+0.j, 0.+0.j, 1.+0.j, 2.+0.j], + [-2.-1.j, -1.-1.j, 0.-1.j, 1.-1.j, 2.-1.j], + [-2.-2.j, -1.-2.j, 0.-2.j, 1.-2.j, 2.-2.j]]) + + An example using a "vector" of letters: + + >>> x = np.array(['a', 'b', 'c'], dtype=object) + >>> np.outer(x, [1, 2, 3]) + array([[a, aa, aaa], + [b, bb, bbb], + [c, cc, ccc]], dtype=object) + + """ + a = asarray(a) + b = asarray(b) + return a.ravel()[:,newaxis]*b.ravel()[newaxis,:] diff --git a/lib_pypy/numpypy/core/shape_base.py b/lib_pypy/numpypy/core/shape_base.py new file mode 100644 --- /dev/null +++ b/lib_pypy/numpypy/core/shape_base.py @@ -0,0 +1,323 @@ +import _numpypy +from numeric import array, asanyarray, newaxis + +def atleast_1d(*arys): + """ + Convert inputs to arrays with at least one dimension. + + Scalar inputs are converted to 1-dimensional arrays, whilst + higher-dimensional inputs are preserved. + + Parameters + ---------- + arys1, arys2, ... : array_like + One or more input arrays. + + Returns + ------- + ret : ndarray + An array, or sequence of arrays, each with ``a.ndim >= 1``. + Copies are made only if necessary. + + See Also + -------- + atleast_2d, atleast_3d + + Examples + -------- + >>> np.atleast_1d(1.0) + array([ 1.]) + + >>> x = np.arange(9.0).reshape(3,3) + >>> np.atleast_1d(x) + array([[ 0., 1., 2.], + [ 3., 4., 5.], + [ 6., 7., 8.]]) + >>> np.atleast_1d(x) is x + True + + >>> np.atleast_1d(1, [3, 4]) + [array([1]), array([3, 4])] + + """ + res = [] + for ary in arys: + ary = asanyarray(ary) + if len(ary.shape) == 0 : + result = ary.reshape(1) + else : + result = ary + res.append(result) + if len(res) == 1: + return res[0] + else: + return res + + +def atleast_2d(*arys): + """ + View inputs as arrays with at least two dimensions. + + Parameters + ---------- + arys1, arys2, ... : array_like + One or more array-like sequences. Non-array inputs are converted + to arrays. Arrays that already have two or more dimensions are + preserved. + + Returns + ------- + res, res2, ... : ndarray + An array, or tuple of arrays, each with ``a.ndim >= 2``. + Copies are avoided where possible, and views with two or more + dimensions are returned. + + See Also + -------- + atleast_1d, atleast_3d + + Examples + -------- + >>> np.atleast_2d(3.0) + array([[ 3.]]) + + >>> x = np.arange(3.0) + >>> np.atleast_2d(x) + array([[ 0., 1., 2.]]) + >>> np.atleast_2d(x).base is x + True + + >>> np.atleast_2d(1, [1, 2], [[1, 2]]) + [array([[1]]), array([[1, 2]]), array([[1, 2]])] + + """ + res = [] + for ary in arys: + ary = asanyarray(ary) + if len(ary.shape) == 0 : + result = ary.reshape(1, 1) + elif len(ary.shape) == 1 : + result = ary[newaxis, :] + else : + result = ary + res.append(result) + if len(res) == 1: + return res[0] + else: + return res + +def atleast_3d(*arys): + """ + View inputs as arrays with at least three dimensions. + + Parameters + ---------- + arys1, arys2, ... : array_like + One or more array-like sequences. Non-array inputs are converted to + arrays. Arrays that already have three or more dimensions are + preserved. + + Returns + ------- + res1, res2, ... : ndarray + An array, or tuple of arrays, each with ``a.ndim >= 3``. Copies are + avoided where possible, and views with three or more dimensions are + returned. For example, a 1-D array of shape ``(N,)`` becomes a view + of shape ``(1, N, 1)``, and a 2-D array of shape ``(M, N)`` becomes a + view of shape ``(M, N, 1)``. + + See Also + -------- + atleast_1d, atleast_2d + + Examples + -------- + >>> np.atleast_3d(3.0) + array([[[ 3.]]]) + + >>> x = np.arange(3.0) + >>> np.atleast_3d(x).shape + (1, 3, 1) + + >>> x = np.arange(12.0).reshape(4,3) + >>> np.atleast_3d(x).shape + (4, 3, 1) + >>> np.atleast_3d(x).base is x + True + + >>> for arr in np.atleast_3d([1, 2], [[1, 2]], [[[1, 2]]]): + ... print arr, arr.shape + ... + [[[1] + [2]]] (1, 2, 1) + [[[1] + [2]]] (1, 2, 1) + [[[1 2]]] (1, 1, 2) + + """ + res = [] + for ary in arys: + ary = asanyarray(ary) + if len(ary.shape) == 0: + result = ary.reshape(1,1,1) + elif len(ary.shape) == 1: + result = ary[newaxis,:,newaxis] + elif len(ary.shape) == 2: + result = ary[:,:,newaxis] + else: + result = ary + res.append(result) + if len(res) == 1: + return res[0] + else: + return res + +def vstack(tup): + """ + Stack arrays in sequence vertically (row wise). + + Take a sequence of arrays and stack them vertically to make a single + array. Rebuild arrays divided by `vsplit`. + + Parameters + ---------- + tup : sequence of ndarrays + Tuple containing arrays to be stacked. The arrays must have the same + shape along all but the first axis. + + Returns + ------- + stacked : ndarray + The array formed by stacking the given arrays. + + See Also + -------- + hstack : Stack arrays in sequence horizontally (column wise). + dstack : Stack arrays in sequence depth wise (along third dimension). + concatenate : Join a sequence of arrays together. + vsplit : Split array into a list of multiple sub-arrays vertically. + + Notes + ----- + Equivalent to ``np.concatenate(tup, axis=0)`` if `tup` contains arrays that + are at least 2-dimensional. + + Examples + -------- + >>> a = np.array([1, 2, 3]) + >>> b = np.array([2, 3, 4]) + >>> np.vstack((a,b)) + array([[1, 2, 3], + [2, 3, 4]]) + + >>> a = np.array([[1], [2], [3]]) + >>> b = np.array([[2], [3], [4]]) + >>> np.vstack((a,b)) + array([[1], + [2], + [3], + [2], + [3], + [4]]) + + """ + return _numpypy.concatenate(map(atleast_2d,tup),0) + +def hstack(tup): + """ + Stack arrays in sequence horizontally (column wise). + + Take a sequence of arrays and stack them horizontally to make + a single array. Rebuild arrays divided by `hsplit`. + + Parameters + ---------- + tup : sequence of ndarrays + All arrays must have the same shape along all but the second axis. + + Returns + ------- + stacked : ndarray + The array formed by stacking the given arrays. + + See Also + -------- + vstack : Stack arrays in sequence vertically (row wise). + dstack : Stack arrays in sequence depth wise (along third axis). + concatenate : Join a sequence of arrays together. + hsplit : Split array along second axis. + + Notes + ----- + Equivalent to ``np.concatenate(tup, axis=1)`` + + Examples + -------- + >>> a = np.array((1,2,3)) + >>> b = np.array((2,3,4)) + >>> np.hstack((a,b)) + array([1, 2, 3, 2, 3, 4]) + >>> a = np.array([[1],[2],[3]]) + >>> b = np.array([[2],[3],[4]]) + >>> np.hstack((a,b)) + array([[1, 2], + [2, 3], + [3, 4]]) + + """ + arrs = map(atleast_1d,tup) + # As a special case, dimension 0 of 1-dimensional arrays is "horizontal" + if arrs[0].ndim == 1: + return _numpypy.concatenate(arrs, 0) + else: + return _numpypy.concatenate(arrs, 1) + +def dstack(tup): + """ + Stack arrays in sequence depth wise (along third axis). + + Takes a sequence of arrays and stack them along the third axis + to make a single array. Rebuilds arrays divided by `dsplit`. + This is a simple way to stack 2D arrays (images) into a single + 3D array for processing. + + Parameters + ---------- + tup : sequence of arrays + Arrays to stack. All of them must have the same shape along all + but the third axis. + + Returns + ------- + stacked : ndarray + The array formed by stacking the given arrays. + + See Also + -------- + vstack : Stack along first axis. + hstack : Stack along second axis. + concatenate : Join arrays. + dsplit : Split array along third axis. + + Notes + ----- + Equivalent to ``np.concatenate(tup, axis=2)``. + + Examples + -------- + >>> a = np.array((1,2,3)) + >>> b = np.array((2,3,4)) + >>> np.dstack((a,b)) + array([[[1, 2], + [2, 3], + [3, 4]]]) + + >>> a = np.array([[1],[2],[3]]) + >>> b = np.array([[2],[3],[4]]) + >>> np.dstack((a,b)) + array([[[1, 2]], + [[2, 3]], + [[3, 4]]]) + + """ + return _numpypy.concatenate(map(atleast_3d,tup),2) diff --git a/lib_pypy/pypy_test/__init__.py b/lib_pypy/pypy_test/__init__.py deleted file mode 100644 --- a/lib_pypy/pypy_test/__init__.py +++ /dev/null @@ -1,1 +0,0 @@ -# diff --git a/lib_pypy/pypy_test/hack___pypy__.py b/lib_pypy/pypy_test/hack___pypy__.py deleted file mode 100644 --- a/lib_pypy/pypy_test/hack___pypy__.py +++ /dev/null @@ -1,9 +0,0 @@ -# here only to make test runs work even if not running on top of PyPy -import sys, new - -def builtinify(f): - return f - -pypy = new.module('__pypy__') -pypy.builtinify = builtinify -sys.modules.setdefault('__pypy__', pypy) diff --git a/lib_pypy/pypy_test/inprogress_test_binascii_extra.py b/lib_pypy/pypy_test/inprogress_test_binascii_extra.py deleted file mode 100644 --- a/lib_pypy/pypy_test/inprogress_test_binascii_extra.py +++ /dev/null @@ -1,19 +0,0 @@ -from __future__ import absolute_import -from lib_pypy import binascii - -def test_uu(): - assert binascii.b2a_uu('1234567') == "',3(S-#4V-P \n" - assert binascii.b2a_uu('123456789012345678901234567890123456789012345') == 'M,3(S-#4V-S at Y,#$R,S0U-C Author: Brian Kearns Branch: Changeset: r61287:1de5c08faeca Date: 2013-02-15 15:04 -0500 http://bitbucket.org/pypy/pypy/changeset/1de5c08faeca/ Log: set_interrupt should still trigger an ASAP perform diff --git a/pypy/module/signal/interp_signal.py b/pypy/module/signal/interp_signal.py --- a/pypy/module/signal/interp_signal.py +++ b/pypy/module/signal/interp_signal.py @@ -103,6 +103,7 @@ # ^^^ may override another signal, but it's just for testing else: pypysig_pushback(cpy_signal.SIGINT) + self.fire_in_another_thread = True # ____________________________________________________________ From noreply at buildbot.pypy.org Fri Feb 15 21:12:47 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Fri, 15 Feb 2013 21:12:47 +0100 (CET) Subject: [pypy-commit] pypy default: (arigato) this line is only needed untranslated Message-ID: <20130215201247.16E2E1C094A@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61288:fcc0ecd924c2 Date: 2013-02-15 15:12 -0500 http://bitbucket.org/pypy/pypy/changeset/fcc0ecd924c2/ Log: (arigato) this line is only needed untranslated diff --git a/pypy/module/signal/interp_signal.py b/pypy/module/signal/interp_signal.py --- a/pypy/module/signal/interp_signal.py +++ b/pypy/module/signal/interp_signal.py @@ -101,9 +101,9 @@ if not we_are_translated(): self.pending_signal = cpy_signal.SIGINT # ^^^ may override another signal, but it's just for testing + self.fire_in_another_thread = True else: pypysig_pushback(cpy_signal.SIGINT) - self.fire_in_another_thread = True # ____________________________________________________________ From noreply at buildbot.pypy.org Fri Feb 15 22:25:44 2013 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 15 Feb 2013 22:25:44 +0100 (CET) Subject: [pypy-commit] cffi default: Kill a debugging print (and make it py3k compatible again) Message-ID: <20130215212544.E3CB01C062C@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r1159:230624c57bf7 Date: 2013-02-15 22:25 +0100 http://bitbucket.org/cffi/cffi/changeset/230624c57bf7/ Log: Kill a debugging print (and make it py3k compatible again) diff --git a/c/test_c.py b/c/test_c.py --- a/c/test_c.py +++ b/c/test_c.py @@ -1412,7 +1412,6 @@ BInt = new_primitive_type("int") BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, 20)) def cb(n): - print n if n & 1: return cast(BEnum, n) else: From noreply at buildbot.pypy.org Fri Feb 15 22:29:28 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Fri, 15 Feb 2013 22:29:28 +0100 (CET) Subject: [pypy-commit] pypy default: update to 230624c57bf7 Message-ID: <20130215212928.D92431C062C@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: Changeset: r61289:42e4a7274ee9 Date: 2013-02-15 13:29 -0800 http://bitbucket.org/pypy/pypy/changeset/42e4a7274ee9/ Log: update to 230624c57bf7 diff --git a/pypy/module/_cffi_backend/test/_backend_test_c.py b/pypy/module/_cffi_backend/test/_backend_test_c.py --- a/pypy/module/_cffi_backend/test/_backend_test_c.py +++ b/pypy/module/_cffi_backend/test/_backend_test_c.py @@ -1404,7 +1404,6 @@ BInt = new_primitive_type("int") BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, 20)) def cb(n): - print n if n & 1: return cast(BEnum, n) else: From noreply at buildbot.pypy.org Fri Feb 15 22:58:00 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Fri, 15 Feb 2013 22:58:00 +0100 (CET) Subject: [pypy-commit] pypy default: add a modified test of the signals_enabled context manager that works untranslated Message-ID: <20130215215800.60D611C062C@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61290:e102f5736ab2 Date: 2013-02-15 16:56 -0500 http://bitbucket.org/pypy/pypy/changeset/e102f5736ab2/ Log: add a modified test of the signals_enabled context manager that works untranslated diff --git a/pypy/module/__pypy__/test/test_signal.py b/pypy/module/__pypy__/test/test_signal.py --- a/pypy/module/__pypy__/test/test_signal.py +++ b/pypy/module/__pypy__/test/test_signal.py @@ -12,6 +12,44 @@ class AppTestThreadSignal: + spaceconfig = dict(usemodules=['__pypy__', 'thread', 'signal', 'time']) + + def test_enable_signals(self): + import __pypy__, thread, signal, time + + def subthread(): + try: + with __pypy__.thread.signals_enabled: + thread.interrupt_main() + for i in range(10): + print 'x' + time.sleep(0.1) + except BaseException, e: + interrupted.append(e) + finally: + done.append(None) + + # This is normally called by app_main.py + signal.signal(signal.SIGINT, signal.default_int_handler) + + for i in range(10): + __pypy__.thread._signals_exit() + try: + done = [] + interrupted = [] + thread.start_new_thread(subthread, ()) + for i in range(10): + if len(done): break + print '.' + time.sleep(0.1) + assert len(done) == 1 + assert len(interrupted) == 1 + assert 'KeyboardInterrupt' in interrupted[0].__class__.__name__ + finally: + __pypy__.thread._signals_enter() + + +class AppTestThreadSignalLock: spaceconfig = dict(usemodules=['__pypy__', 'thread', 'signal']) def setup_class(cls): @@ -22,11 +60,11 @@ def test_enable_signals(self): import __pypy__, thread, signal, time - # + interrupted = [] lock = thread.allocate_lock() lock.acquire() - # + def subthread(): try: time.sleep(0.25) @@ -34,8 +72,9 @@ thread.interrupt_main() except BaseException, e: interrupted.append(e) - lock.release() - # + finally: + lock.release() + thread.start_new_thread(subthread, ()) lock.acquire() assert len(interrupted) == 1 From noreply at buildbot.pypy.org Sat Feb 16 01:22:54 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Sat, 16 Feb 2013 01:22:54 +0100 (CET) Subject: [pypy-commit] pypy py3k: merge default Message-ID: <20130216002254.C3CC11C00A8@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61291:6f8795612ffd Date: 2013-02-15 16:20 -0800 http://bitbucket.org/pypy/pypy/changeset/6f8795612ffd/ Log: merge default diff --git a/pypy/interpreter/miscutils.py b/pypy/interpreter/miscutils.py --- a/pypy/interpreter/miscutils.py +++ b/pypy/interpreter/miscutils.py @@ -17,8 +17,14 @@ def setvalue(self, value): self._value = value - def ismainthread(self): + def signals_enabled(self): return True + def enable_signals(self): + pass + + def disable_signals(self): + pass + def getallvalues(self): return {0: self._value} diff --git a/pypy/interpreter/test2/test_app_main.py b/pypy/interpreter/test2/test_app_main.py --- a/pypy/interpreter/test2/test_app_main.py +++ b/pypy/interpreter/test2/test_app_main.py @@ -225,11 +225,6 @@ These tests require pexpect (UNIX-only). http://pexpect.sourceforge.net/ """ - def setup_class(cls): - # some tests need to be able to import test2, change the cwd - goal_dir = os.path.abspath(os.path.join(os.path.realpath(os.path.dirname(__file__)), '..')) - os.chdir(goal_dir) - def _spawn(self, *args, **kwds): try: import pexpect @@ -484,13 +479,14 @@ child = self.spawn(['-c', 'import sys; print(sys.stdin.mode)']) child.expect('r') - def test_options_i_m(self): + def test_options_i_m(self, monkeypatch): if sys.platform == "win32": skip("close_fds is not supported on Windows platforms") if not hasattr(runpy, '_run_module_as_main'): skip("requires CPython >= 2.6") p = os.path.join(os.path.realpath(os.path.dirname(__file__)), 'mymodule.py') p = os.path.abspath(p) + monkeypatch.chdir(os.path.dirname(app_main)) child = self.spawn(['-i', '-m', 'test2.mymodule', 'extra']) @@ -590,12 +586,13 @@ child.sendline('Not at all. They could be carried.') child.expect('A five ounce bird could not carry a one pound coconut.') - def test_no_space_before_argument(self): + def test_no_space_before_argument(self, monkeypatch): if not hasattr(runpy, '_run_module_as_main'): skip("requires CPython >= 2.6") child = self.spawn(['-cprint("hel" + "lo")']) child.expect('hello') + monkeypatch.chdir(os.path.dirname(app_main)) child = self.spawn(['-mtest2.mymodule']) child.expect('mymodule running') @@ -696,11 +693,12 @@ '-c "import sys; print(sys.warnoptions)"') assert "['ignore', 'default', 'once', 'error']" in data - def test_option_m(self): + def test_option_m(self, monkeypatch): if not hasattr(runpy, '_run_module_as_main'): skip("requires CPython >= 2.6") p = os.path.join(os.path.realpath(os.path.dirname(__file__)), 'mymodule.py') p = os.path.abspath(p) + monkeypatch.chdir(os.path.dirname(app_main)) data = self.run('-m test2.mymodule extra') assert 'mymodule running' in data assert 'Name: __main__' in data diff --git a/pypy/module/__pypy__/__init__.py b/pypy/module/__pypy__/__init__.py --- a/pypy/module/__pypy__/__init__.py +++ b/pypy/module/__pypy__/__init__.py @@ -26,6 +26,16 @@ interpleveldefs[name] = "space.wrap(interp_time.%s)" % name +class ThreadModule(MixedModule): + appleveldefs = { + 'signals_enabled': 'app_signal.signals_enabled', + } + interpleveldefs = { + '_signals_enter': 'interp_signal.signals_enter', + '_signals_exit': 'interp_signal.signals_exit', + } + + class Module(MixedModule): appleveldefs = { } @@ -54,6 +64,7 @@ submodules = { "builders": BuildersModule, "time": TimeModule, + "thread": ThreadModule, } def setup_after_space_initialization(self): diff --git a/pypy/module/__pypy__/app_signal.py b/pypy/module/__pypy__/app_signal.py new file mode 100644 --- /dev/null +++ b/pypy/module/__pypy__/app_signal.py @@ -0,0 +1,14 @@ +import __pypy__.thread + +class SignalsEnabled(object): + '''A context manager to use in non-main threads: +enables receiving signals in a "with" statement. More precisely, if a +signal is received by the process, then the signal handler might be +called either in the main thread (as usual) or within another thread +that is within a "with signals_enabled:". This other thread should be +ready to handle unexpected exceptions that the signal handler might +raise --- notably KeyboardInterrupt.''' + __enter__ = __pypy__.thread._signals_enter + __exit__ = __pypy__.thread._signals_exit + +signals_enabled = SignalsEnabled() diff --git a/pypy/module/__pypy__/interp_signal.py b/pypy/module/__pypy__/interp_signal.py new file mode 100644 --- /dev/null +++ b/pypy/module/__pypy__/interp_signal.py @@ -0,0 +1,6 @@ + +def signals_enter(space): + space.threadlocals.enable_signals() + +def signals_exit(space, w_ignored1=None, w_ignored2=None, w_ignored3=None): + space.threadlocals.disable_signals() diff --git a/pypy/module/__pypy__/test/test_signal.py b/pypy/module/__pypy__/test/test_signal.py new file mode 100644 --- /dev/null +++ b/pypy/module/__pypy__/test/test_signal.py @@ -0,0 +1,81 @@ +import sys + + +class AppTestMinimal: + spaceconfig = dict(usemodules=['__pypy__']) + + def test_signal(self): + from __pypy__ import thread + with thread.signals_enabled: + pass + # assert did not crash + + +class AppTestThreadSignal: + spaceconfig = dict(usemodules=['__pypy__', 'thread', 'signal', 'time']) + + def test_enable_signals(self): + import __pypy__, thread, signal, time + + def subthread(): + try: + with __pypy__.thread.signals_enabled: + thread.interrupt_main() + for i in range(10): + print 'x' + time.sleep(0.1) + except BaseException, e: + interrupted.append(e) + finally: + done.append(None) + + # This is normally called by app_main.py + signal.signal(signal.SIGINT, signal.default_int_handler) + + for i in range(10): + __pypy__.thread._signals_exit() + try: + done = [] + interrupted = [] + thread.start_new_thread(subthread, ()) + for i in range(10): + if len(done): break + print '.' + time.sleep(0.1) + assert len(done) == 1 + assert len(interrupted) == 1 + assert 'KeyboardInterrupt' in interrupted[0].__class__.__name__ + finally: + __pypy__.thread._signals_enter() + + +class AppTestThreadSignalLock: + spaceconfig = dict(usemodules=['__pypy__', 'thread', 'signal']) + + def setup_class(cls): + if (not cls.runappdirect or + '__pypy__' not in sys.builtin_module_names): + import py + py.test.skip("this is only a test for -A runs on top of pypy") + + def test_enable_signals(self): + import __pypy__, thread, signal, time + + interrupted = [] + lock = thread.allocate_lock() + lock.acquire() + + def subthread(): + try: + time.sleep(0.25) + with __pypy__.thread.signals_enabled: + thread.interrupt_main() + except BaseException, e: + interrupted.append(e) + finally: + lock.release() + + thread.start_new_thread(subthread, ()) + lock.acquire() + assert len(interrupted) == 1 + assert 'KeyboardInterrupt' in interrupted[0].__class__.__name__ diff --git a/pypy/module/_cffi_backend/test/_backend_test_c.py b/pypy/module/_cffi_backend/test/_backend_test_c.py --- a/pypy/module/_cffi_backend/test/_backend_test_c.py +++ b/pypy/module/_cffi_backend/test/_backend_test_c.py @@ -1404,7 +1404,6 @@ BInt = new_primitive_type("int") BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, 20)) def cb(n): - print n if n & 1: return cast(BEnum, n) else: diff --git a/pypy/module/gc/test/test_ztranslation.py b/pypy/module/gc/test/test_ztranslation.py new file mode 100644 --- /dev/null +++ b/pypy/module/gc/test/test_ztranslation.py @@ -0,0 +1,4 @@ +from pypy.objspace.fake.checkmodule import checkmodule + +def test_checkmodule(): + checkmodule('gc') diff --git a/pypy/module/micronumpy/test/test_module.py b/pypy/module/micronumpy/test/test_module.py --- a/pypy/module/micronumpy/test/test_module.py +++ b/pypy/module/micronumpy/test/test_module.py @@ -13,11 +13,13 @@ assert sum(array(range(10))) == 45 def test_min(self): - from _numpypy import array, min + from _numpypy import array, min, zeros assert min(range(10)) == 0 assert min(array(range(10))) == 0 + assert list(min(zeros((0, 2)), axis=1)) == [] def test_max(self): - from _numpypy import array, max + from _numpypy import array, max, zeros assert max(range(10)) == 9 assert max(array(range(10))) == 9 + assert list(max(zeros((0, 2)), axis=1)) == [] diff --git a/pypy/module/micronumpy/test/test_numarray.py b/pypy/module/micronumpy/test/test_numarray.py --- a/pypy/module/micronumpy/test/test_numarray.py +++ b/pypy/module/micronumpy/test/test_numarray.py @@ -1662,13 +1662,13 @@ b = array([0, 1, 2], dtype=complex).astype(bool) assert (b == [False, True, True]).all() assert b.dtype == 'bool' - + a = arange(6, dtype='f4').reshape(2,3) b = a.astype('i4') a = array('x').astype('S3').dtype assert a.itemsize == 3 - + def test_base(self): from _numpypy import array assert array(1).base is None @@ -1679,6 +1679,11 @@ def test_byteswap(self): from _numpypy import array + + s1 = array(1.).byteswap().tostring() + s2 = array([1.]).byteswap().tostring() + assert s1 == s2 + a = array([1, 256 + 2, 3], dtype='i2') assert (a.byteswap() == [0x0100, 0x0201, 0x0300]).all() assert (a == [1, 256 + 2, 3]).all() @@ -1686,39 +1691,40 @@ assert (a == [0x0100, 0x0201, 0x0300]).all() a = array([1, -1, 1e300], dtype=float) - s1 = map(ord,a.tostring()) + s1 = map(ord, a.tostring()) s2 = map(ord, a.byteswap().tostring()) - assert s1[7::-1] == s2[:8] - assert s1[15:7:-1] == s2[8:16] - assert s1[:15:-1] == s2[16:] + assert a.dtype.itemsize == 8 + for i in range(a.size): + i1 = i * a.dtype.itemsize + i2 = (i+1) * a.dtype.itemsize + assert list(reversed(s1[i1:i2])) == s2[i1:i2] a = array([1+1e30j, -1, 1e10], dtype=complex) - s1 = map(ord,a.tostring()) + s1 = map(ord, a.tostring()) s2 = map(ord, a.byteswap().tostring()) - assert s1[7::-1] == s2[:8] - assert s1[15:7:-1] == s2[8:16] - assert s1[23:15:-1] == s2[16:24] - assert s1[31:23:-1] == s2[24:32] - assert s1[39:31:-1] == s2[32:40] - assert s1[:39:-1] == s2[40:] + assert a.dtype.itemsize == 16 + for i in range(a.size*2): + i1 = i * a.dtype.itemsize/2 + i2 = (i+1) * a.dtype.itemsize/2 + assert list(reversed(s1[i1:i2])) == s2[i1:i2] a = array([3.14, -1.5, 10000], dtype='float16') - s1 = map(ord,a.tostring()) + s1 = map(ord, a.tostring()) s2 = map(ord, a.byteswap().tostring()) - s3 = [s1[1], s1[0],s1[3], s1[2], s1[5], s1[4]] - assert s3 == s2 + assert a.dtype.itemsize == 2 + for i in range(a.size): + i1 = i * a.dtype.itemsize + i2 = (i+1) * a.dtype.itemsize + assert list(reversed(s1[i1:i2])) == s2[i1:i2] a = array([1, -1, 10000], dtype='longfloat') - s1 = map(ord,a.tostring()) - s2 = map(ord, a.byteswap().tostring()) - n = a.dtype.itemsize - assert s1[n-1] == s2[0] - - a = array(0., dtype='longfloat') s1 = map(ord, a.tostring()) s2 = map(ord, a.byteswap().tostring()) - n = a.dtype.itemsize - assert s1[n-1] == s2[0] + assert a.dtype.itemsize >= 8 + for i in range(a.size): + i1 = i * a.dtype.itemsize + i2 = (i+1) * a.dtype.itemsize + assert list(reversed(s1[i1:i2])) == s2[i1:i2] def test_clip(self): from _numpypy import array diff --git a/pypy/module/micronumpy/types.py b/pypy/module/micronumpy/types.py --- a/pypy/module/micronumpy/types.py +++ b/pypy/module/micronumpy/types.py @@ -14,8 +14,8 @@ from rpython.rtyper.lltypesystem import lltype, rffi from rpython.rlib.rstruct.runpack import runpack from rpython.rlib.rstruct.nativefmttable import native_is_bigendian -from rpython.rlib.rstruct.ieee import (float_pack, float_unpack, pack_float80, - unpack_float, unpack_float128) +from rpython.rlib.rstruct.ieee import (float_pack, float_unpack, unpack_float, + pack_float80, unpack_float80) from rpython.tool.sourcetools import func_with_new_name from rpython.rlib import jit from rpython.rlib.rstring import StringBuilder @@ -958,7 +958,6 @@ swapped_value = byteswap(rffi.cast(self.T, value)) raw_storage_setitem(storage, i + offset, swapped_value) - class Float32(BaseType, Float): _attrs_ = () @@ -1505,7 +1504,6 @@ BoxType = interp_boxes.W_Complex64Box ComponentBoxType = interp_boxes.W_Float32Box - NonNativeComplex64 = Complex64 class Complex128(ComplexFloating, BaseType): @@ -1515,7 +1513,6 @@ BoxType = interp_boxes.W_Complex128Box ComponentBoxType = interp_boxes.W_Float64Box - NonNativeComplex128 = Complex128 if interp_boxes.long_double_size == 12: @@ -1528,17 +1525,16 @@ def runpack_str(self, s): assert len(s) == 12 - fval = unpack_float128(s, native_is_bigendian) + fval = unpack_float80(s, native_is_bigendian) return self.box(fval) def byteswap(self, w_v): value = self.unbox(w_v) result = StringBuilder(12) - pack_float80(result, value, 12, not native_is_bigendian) - return self.box(unpack_float128(result.build(), native_is_bigendian)) + pack_float80(result, value, not native_is_bigendian) + return self.box(unpack_float80(result.build(), native_is_bigendian)) - class NonNativeFloat96(Float96): - pass + NonNativeFloat96 = Float96 class Complex192(ComplexFloating, BaseType): _attrs_ = () @@ -1549,7 +1545,6 @@ NonNativeComplex192 = Complex192 - elif interp_boxes.long_double_size == 16: class Float128(BaseType, Float): _attrs_ = () @@ -1560,14 +1555,14 @@ def runpack_str(self, s): assert len(s) == 16 - fval = unpack_float128(s, native_is_bigendian) + fval = unpack_float80(s, native_is_bigendian) return self.box(fval) def byteswap(self, w_v): value = self.unbox(w_v) result = StringBuilder(16) - pack_float80(result, value, 16, not native_is_bigendian) - return self.box(unpack_float128(result.build(), native_is_bigendian)) + pack_float80(result, value, not native_is_bigendian) + return self.box(unpack_float80(result.build(), native_is_bigendian)) NonNativeFloat128 = Float128 @@ -1578,7 +1573,6 @@ BoxType = interp_boxes.W_Complex256Box ComponentBoxType = interp_boxes.W_Float128Box - NonNativeComplex256 = Complex256 class BaseStringType(object): diff --git a/pypy/module/signal/interp_signal.py b/pypy/module/signal/interp_signal.py --- a/pypy/module/signal/interp_signal.py +++ b/pypy/module/signal/interp_signal.py @@ -61,16 +61,16 @@ "NOT_RPYTHON" AsyncAction.__init__(self, space) self.pending_signal = -1 - self.fire_in_main_thread = False + self.fire_in_another_thread = False if self.space.config.objspace.usemodules.thread: from pypy.module.thread import gil gil.after_thread_switch = self._after_thread_switch @rgc.no_collect def _after_thread_switch(self): - if self.fire_in_main_thread: - if self.space.threadlocals.ismainthread(): - self.fire_in_main_thread = False + if self.fire_in_another_thread: + if self.space.threadlocals.signals_enabled(): + self.fire_in_another_thread = False SignalActionFlag.rearm_ticker() # this occurs when we just switched to the main thread # and there is a signal pending: we force the ticker to @@ -82,11 +82,7 @@ n = self.pending_signal if n < 0: n = pypysig_poll() while n >= 0: - if self.space.config.objspace.usemodules.thread: - in_main = self.space.threadlocals.ismainthread() - else: - in_main = True - if in_main: + if self.space.threadlocals.signals_enabled(): # If we are in the main thread, report the signal now, # and poll more self.pending_signal = -1 @@ -97,7 +93,7 @@ # Otherwise, arrange for perform() to be called again # after we switch to the main thread. self.pending_signal = n - self.fire_in_main_thread = True + self.fire_in_another_thread = True break def set_interrupt(self): @@ -105,9 +101,9 @@ if not we_are_translated(): self.pending_signal = cpy_signal.SIGINT # ^^^ may override another signal, but it's just for testing + self.fire_in_another_thread = True else: pypysig_pushback(cpy_signal.SIGINT) - self.fire_in_main_thread = True # ____________________________________________________________ @@ -204,9 +200,10 @@ if WIN32 and signum not in signal_values: raise OperationError(space.w_ValueError, space.wrap("invalid signal value")) - if not space.threadlocals.ismainthread(): + if not space.threadlocals.signals_enabled(): raise OperationError(space.w_ValueError, - space.wrap("signal only works in main thread")) + space.wrap("signal only works in main thread " + "or with __pypy__.thread.enable_signals()")) check_signum_in_range(space, signum) if space.eq_w(w_handler, space.wrap(SIG_DFL)): @@ -235,10 +232,11 @@ The fd must be non-blocking. """ - if not space.threadlocals.ismainthread(): + if not space.threadlocals.signals_enabled(): raise OperationError( space.w_ValueError, - space.wrap("set_wakeup_fd only works in main thread")) + space.wrap("set_wakeup_fd only works in main thread " + "or with __pypy__.thread.enable_signals()")) old_fd = pypysig_set_wakeup_fd(fd) return space.wrap(intmask(old_fd)) diff --git a/pypy/module/sys/initpath.py b/pypy/module/sys/initpath.py --- a/pypy/module/sys/initpath.py +++ b/pypy/module/sys/initpath.py @@ -67,6 +67,8 @@ stdlib. If it cannot be found, return (None, None). """ + if executable == '': + return None, None search = executable while True: dirname = resolvedirof(search) diff --git a/pypy/module/sys/test/test_initpath.py b/pypy/module/sys/test/test_initpath.py --- a/pypy/module/sys/test/test_initpath.py +++ b/pypy/module/sys/test/test_initpath.py @@ -10,12 +10,15 @@ b = prefix.join('lib-python', dirname).ensure(dir=1) return a, b -def test_find_stdlib(tmpdir): +def test_find_stdlib(tmpdir, monkeypatch): bin_dir = tmpdir.join('bin').ensure(dir=True) pypy = bin_dir.join('pypy').ensure(file=True) build_hierarchy(tmpdir) path, prefix = find_stdlib(None, str(pypy)) assert prefix == tmpdir + # shouldn't find stdlib if executable == '' even if parent dir has a stdlib + monkeypatch.chdir(tmpdir.join('bin')) + assert find_stdlib(None, '') == (None, None) @py.test.mark.skipif('not hasattr(os, "symlink")') def test_find_stdlib_follow_symlink(tmpdir): @@ -84,6 +87,7 @@ assert find_executable('pypy') == a.join('pypy.exe') def test_resolvedirof(tmpdir): + assert resolvedirof('') == os.path.abspath(os.path.join(os.getcwd(), '..')) foo = tmpdir.join('foo').ensure(dir=True) bar = tmpdir.join('bar').ensure(dir=True) myfile = foo.join('myfile').ensure(file=True) diff --git a/pypy/module/test_lib_pypy/numpypy/core/test_fromnumeric.py b/pypy/module/test_lib_pypy/numpypy/core/test_fromnumeric.py --- a/pypy/module/test_lib_pypy/numpypy/core/test_fromnumeric.py +++ b/pypy/module/test_lib_pypy/numpypy/core/test_fromnumeric.py @@ -132,7 +132,7 @@ assert reshape(a, (1, -1)).shape == (1, 105) assert reshape(a, (1, 1, -1)).shape == (1, 1, 105) assert reshape(a, (-1, 1, 1)).shape == (105, 1, 1) - + def test_transpose(self): from numpypy import arange, array, transpose, ones x = arange(4).reshape((2,2)) @@ -141,7 +141,7 @@ raises(NotImplementedError, "transpose(x, axes=(1, 0, 2))") # x = ones((1, 2, 3)) # assert transpose(x, (1, 0, 2)).shape == (2, 1, 3) - + def test_fromnumeric(self): from numpypy import array, swapaxes x = array([[1,2,3]]) diff --git a/pypy/module/test_lib_pypy/numpypy/test_numpy.py b/pypy/module/test_lib_pypy/numpypy/test_numpy.py --- a/pypy/module/test_lib_pypy/numpypy/test_numpy.py +++ b/pypy/module/test_lib_pypy/numpypy/test_numpy.py @@ -12,3 +12,11 @@ pass import numpypy import numpy # works after 'numpypy' has been imported + + def test_min_max_after_import(self): + from numpypy import * + assert min(1, 100) == 1 + assert min(100, 1) == 1 + + assert max(1, 100) == 100 + assert max(100, 1) == 100 diff --git a/pypy/module/thread/gil.py b/pypy/module/thread/gil.py --- a/pypy/module/thread/gil.py +++ b/pypy/module/thread/gil.py @@ -7,7 +7,7 @@ # all but one will be blocked. The other threads get a chance to run # from time to time, using the periodic action GILReleaseAction. -from rpython.rlib import rthread as thread +from rpython.rlib import rthread from pypy.module.thread.error import wrap_thread_error from pypy.interpreter.executioncontext import PeriodicAsyncAction from pypy.module.thread.threadlocals import OSThreadLocals @@ -25,7 +25,7 @@ use_bytecode_counter=True) def _initialize_gil(self, space): - if not thread.gil_allocate(): + if not rthread.gil_allocate(): raise wrap_thread_error(space, "can't allocate GIL") def setup_threads(self, space): @@ -72,15 +72,15 @@ # this function must not raise, in such a way that the exception # transformer knows that it cannot raise! e = get_errno() - thread.gil_release() + rthread.gil_release() set_errno(e) before_external_call._gctransformer_hint_cannot_collect_ = True before_external_call._dont_reach_me_in_del_ = True def after_external_call(): e = get_errno() - thread.gil_acquire() - thread.gc_thread_run() + rthread.gil_acquire() + rthread.gc_thread_run() after_thread_switch() set_errno(e) after_external_call._gctransformer_hint_cannot_collect_ = True @@ -97,8 +97,8 @@ # explicitly release the gil, in a way that tries to give more # priority to other threads (as opposed to continuing to run in # the same thread). - if thread.gil_yield_thread(): - thread.gc_thread_run() + if rthread.gil_yield_thread(): + rthread.gc_thread_run() after_thread_switch() do_yield_thread._gctransformer_hint_close_stack_ = True do_yield_thread._dont_reach_me_in_del_ = True diff --git a/pypy/module/thread/os_lock.py b/pypy/module/thread/os_lock.py --- a/pypy/module/thread/os_lock.py +++ b/pypy/module/thread/os_lock.py @@ -2,7 +2,7 @@ Python locks, based on true threading locks provided by the OS. """ -from rpython.rlib import rthread as thread +from rpython.rlib import rthread from pypy.module.thread.error import wrap_thread_error from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.gateway import interp2app, unwrap_spec @@ -27,7 +27,7 @@ ## except: ## pass ## tb = ' '.join(tb) -## msg = '| %6d | %d %s | %s\n' % (thread.get_ident(), n, msg, tb) +## msg = '| %6d | %d %s | %s\n' % (rthread.get_ident(), n, msg, tb) ## sys.stderr.write(msg) @@ -57,8 +57,8 @@ def __init__(self, space): self.space = space try: - self.lock = thread.allocate_lock() - except thread.error: + self.lock = rthread.allocate_lock() + except rthread.error: raise wrap_thread_error(space, "out of resources") @unwrap_spec(blocking=int, timeout=float) @@ -81,7 +81,7 @@ but it needn't be locked by the same thread that unlocks it.""" try: self.lock.release() - except thread.error: + except rthread.error: raise wrap_thread_error(space, "release unlocked lock") def descr_lock_locked(self, space): diff --git a/pypy/module/thread/os_thread.py b/pypy/module/thread/os_thread.py --- a/pypy/module/thread/os_thread.py +++ b/pypy/module/thread/os_thread.py @@ -3,7 +3,7 @@ """ import os -from rpython.rlib import rthread as thread +from rpython.rlib import rthread from pypy.module.thread.error import wrap_thread_error from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.gateway import unwrap_spec, Arguments @@ -65,8 +65,8 @@ def setup(space): if bootstrapper.lock is None: try: - bootstrapper.lock = thread.allocate_lock() - except thread.error: + bootstrapper.lock = rthread.allocate_lock() + except rthread.error: raise wrap_thread_error(space, "can't allocate bootstrap lock") @staticmethod @@ -83,7 +83,7 @@ # Note that when this runs, we already hold the GIL. This is ensured # by rffi's callback mecanism: we are a callback for the # c_thread_start() external function. - thread.gc_thread_start() + rthread.gc_thread_start() space = bootstrapper.space w_callable = bootstrapper.w_callable args = bootstrapper.args @@ -103,7 +103,7 @@ except OSError: pass bootstrapper.nbthreads -= 1 - thread.gc_thread_die() + rthread.gc_thread_die() bootstrap = staticmethod(bootstrap) def acquire(space, w_callable, args): @@ -130,7 +130,7 @@ space.call_args(w_callable, args) except OperationError, e: if not e.match(space, space.w_SystemExit): - ident = thread.get_ident() + ident = rthread.get_ident() where = 'thread %d started by ' % ident e.write_unraisable(space, where, w_callable) e.clear(space) @@ -150,7 +150,7 @@ "Called in the child process after a fork()" space.threadlocals.reinit_threads(space) bootstrapper.reinit() - thread.thread_after_fork() + rthread.thread_after_fork() # Clean the threading module after a fork() w_modules = space.sys.get('modules') @@ -181,12 +181,12 @@ bootstrapper.acquire(space, w_callable, args) try: try: - thread.gc_thread_prepare() # (this has no effect any more) - ident = thread.start_new_thread(bootstrapper.bootstrap, ()) + rthread.gc_thread_prepare() # (this has no effect any more) + ident = rthread.start_new_thread(bootstrapper.bootstrap, ()) except Exception, e: bootstrapper.release() # normally called by the new thread raise - except thread.error: + except rthread.error: raise wrap_thread_error(space, "can't start new thread") return space.wrap(ident) @@ -199,7 +199,7 @@ allocated consecutive numbers starting at 1, this behavior should not be relied upon, and the number should be seen purely as a magic cookie. A thread's identity may be reused for another thread after it exits.""" - ident = thread.get_ident() + ident = rthread.get_ident() return space.wrap(ident) @unwrap_spec(size=int) @@ -225,8 +225,8 @@ if size < 0: raise OperationError(space.w_ValueError, space.wrap("size must be 0 or a positive value")) - old_size = thread.get_stacksize() - error = thread.set_stacksize(size) + old_size = rthread.get_stacksize() + error = rthread.set_stacksize(size) if error == -1: raise operationerrfmt(space.w_ValueError, "size not valid: %d bytes", size) diff --git a/pypy/module/thread/threadlocals.py b/pypy/module/thread/threadlocals.py --- a/pypy/module/thread/threadlocals.py +++ b/pypy/module/thread/threadlocals.py @@ -1,4 +1,4 @@ -from rpython.rlib import rthread as thread +from rpython.rlib import rthread class OSThreadLocals: @@ -9,16 +9,17 @@ def __init__(self): self._valuedict = {} # {thread_ident: ExecutionContext()} + self._signalsenabled = {} # {thread_ident: number-of-times} self._cleanup_() def _cleanup_(self): self._valuedict.clear() - self._mainthreadident = 0 + self._signalsenabled.clear() self._mostrecentkey = 0 # fast minicaching for the common case self._mostrecentvalue = None # fast minicaching for the common case def getvalue(self): - ident = thread.get_ident() + ident = rthread.get_ident() if ident == self._mostrecentkey: result = self._mostrecentvalue else: @@ -30,10 +31,10 @@ return result def setvalue(self, value): - ident = thread.get_ident() + ident = rthread.get_ident() if value is not None: if len(self._valuedict) == 0: - self._mainthreadident = ident + self._signalsenabled[ident] = 1 # the main thread is enabled self._valuedict[ident] = value else: try: @@ -44,8 +45,24 @@ self._mostrecentkey = ident self._mostrecentvalue = value - def ismainthread(self): - return thread.get_ident() == self._mainthreadident + def signals_enabled(self): + return rthread.get_ident() in self._signalsenabled + + def enable_signals(self): + ident = rthread.get_ident() + old = self._signalsenabled.get(ident, 0) + self._signalsenabled[ident] = old + 1 + + def disable_signals(self): + ident = rthread.get_ident() + try: + new = self._signalsenabled[ident] - 1 + except KeyError: + return + if new > 0: + self._signalsenabled[ident] = new + else: + del self._signalsenabled[ident] def getallvalues(self): return self._valuedict @@ -60,4 +77,13 @@ def reinit_threads(self, space): "Called in the child process after a fork()" - self._mainthreadident = thread.get_ident() + # clear the _signalsenabled dictionary for all other threads + # (which are now dead); and for the current thread, force an + # enable_signals() if necessary. That's a hack but I cannot + # figure out a non-hackish way to handle thread+signal+fork :-( + ident = rthread.get_ident() + old = self._signalsenabled.get(ident, 0) + self._signalsenabled.clear() + if old == 0: + old = 1 + self._signalsenabled[ident] = old diff --git a/rpython/jit/codewriter/assembler.py b/rpython/jit/codewriter/assembler.py --- a/rpython/jit/codewriter/assembler.py +++ b/rpython/jit/codewriter/assembler.py @@ -107,7 +107,9 @@ key = (kind, Constant(value)) if key not in self.constants_dict: constants.append(value) - self.constants_dict[key] = 256 - len(constants) + val = 256 - len(constants) + assert val >= 0, "too many constants" + self.constants_dict[key] = val # emit the constant normally, as one byte that is an index in the # list of constants self.code.append(chr(self.constants_dict[key])) diff --git a/rpython/rlib/jit.py b/rpython/rlib/jit.py --- a/rpython/rlib/jit.py +++ b/rpython/rlib/jit.py @@ -476,7 +476,7 @@ get_jitcell_at=None, set_jitcell_at=None, get_printable_location=None, confirm_enter_jit=None, can_never_inline=None, should_unroll_one_iteration=None, - name='jitdriver'): + name='jitdriver', check_untranslated=True): if greens is not None: self.greens = greens self.name = name @@ -511,6 +511,7 @@ self.confirm_enter_jit = confirm_enter_jit self.can_never_inline = can_never_inline self.should_unroll_one_iteration = should_unroll_one_iteration + self.check_untranslated = check_untranslated def _freeze_(self): return True @@ -565,13 +566,15 @@ def jit_merge_point(_self, **livevars): # special-cased by ExtRegistryEntry - _self._check_arguments(livevars) + if _self.check_untranslated: + _self._check_arguments(livevars) def can_enter_jit(_self, **livevars): if _self.autoreds: raise TypeError, "Cannot call can_enter_jit on a driver with reds='auto'" # special-cased by ExtRegistryEntry - _self._check_arguments(livevars) + if _self.check_untranslated: + _self._check_arguments(livevars) def loop_header(self): # special-cased by ExtRegistryEntry diff --git a/rpython/rlib/rarithmetic.py b/rpython/rlib/rarithmetic.py --- a/rpython/rlib/rarithmetic.py +++ b/rpython/rlib/rarithmetic.py @@ -630,21 +630,16 @@ uint2singlefloat, singlefloat2uint T = lltype.typeOf(arg) - is_float = False - is_single_float = False if T == lltype.SingleFloat: - T = rffi.UINT - is_single_float = True arg = singlefloat2uint(arg) elif T == lltype.Float: - is_float = True - T = rffi.LONGLONG arg = float2longlong(arg) elif T == lltype.LongFloat: assert False else: # we cannot do arithmetics on small ints arg = widen(arg) + if rffi.sizeof(T) == 1: res = arg elif rffi.sizeof(T) == 2: @@ -667,9 +662,9 @@ (f >> 24) | (g >> 40) | (h >> 56)) else: assert False # unreachable code - if is_single_float: + + if T == lltype.SingleFloat: return uint2singlefloat(rffi.cast(rffi.UINT, res)) - if is_float: - res = rffi.cast(rffi.LONGLONG, res) - return longlong2float(res) + if T == lltype.Float: + return longlong2float(rffi.cast(rffi.LONGLONG, res)) return rffi.cast(T, res) diff --git a/rpython/rlib/rstruct/ieee.py b/rpython/rlib/rstruct/ieee.py --- a/rpython/rlib/rstruct/ieee.py +++ b/rpython/rlib/rstruct/ieee.py @@ -235,12 +235,12 @@ result.append("".join(l)) @jit.unroll_safe -def pack_float80(result, x, size, be): +def pack_float80(result, x, be): l = [] unsigned = float_pack80(x) for i in range(8): l.append(chr((unsigned[0] >> (i * 8)) & 0xFF)) - for i in range(size - 8): + for i in range(2): l.append(chr((unsigned[1] >> (i * 8)) & 0xFF)) if be: l.reverse() @@ -253,12 +253,14 @@ unsigned |= r_ulonglong(c) << (i * 8) return float_unpack(unsigned, len(s)) -def unpack_float128(s, be): +def unpack_float80(s, be): + if len(s) != 10: + raise ValueError QQ = [r_ulonglong(0), r_ulonglong(0)] for i in range(8): - c = ord(s[len(s) - 1 - i if be else i]) + c = ord(s[9 - i if be else i]) QQ[0] |= r_ulonglong(c) << (i * 8) - for i in range(8, len(s)): - c = ord(s[len(s) - 1 - i if be else i]) + for i in range(8, 10): + c = ord(s[9 - i if be else i]) QQ[1] |= r_ulonglong(c) << ((i - 8) * 8) return float_unpack80(QQ) diff --git a/rpython/rlib/rstruct/runpack.py b/rpython/rlib/rstruct/runpack.py --- a/rpython/rlib/rstruct/runpack.py +++ b/rpython/rlib/rstruct/runpack.py @@ -46,7 +46,7 @@ def __init__(self, fmt): self.formats = [] self.fmt = fmt - + def operate(self, fmtdesc, repetitions): if fmtdesc.needcount: self.formats.append((fmtdesc, repetitions, None)) @@ -110,5 +110,3 @@ unpacker = create_unpacker(fmt) return unpacker.unpack(input) runpack._annspecialcase_ = 'specialize:arg(0)' - - diff --git a/rpython/rlib/rstruct/test/test_ieee.py b/rpython/rlib/rstruct/test/test_ieee.py --- a/rpython/rlib/rstruct/test/test_ieee.py +++ b/rpython/rlib/rstruct/test/test_ieee.py @@ -1,9 +1,12 @@ -import py, sys +import py +import sys import random import struct -from rpython.rlib.rfloat import isnan -from rpython.rlib.rstruct.ieee import float_pack, float_unpack, float_pack80, float_unpack80 +from rpython.rlib.rstruct import ieee +from rpython.rlib.rfloat import isnan, NAN, INFINITY +from rpython.translator.c.test.test_genc import compile + class TestFloatPacking: def setup_class(cls): @@ -12,17 +15,29 @@ def check_float(self, x): # check roundtrip - Q = float_pack(x, 8) - y = float_unpack(Q, 8) - assert repr(x) == repr(y) + Q = ieee.float_pack(x, 8) + y = ieee.float_unpack(Q, 8) + assert repr(x) == repr(y), '%r != %r, Q=%r' % (x, y, Q) - Q = float_pack80(x) - y = float_unpack80(Q) - assert repr(x) == repr(y),'%r != %r, Q=%r'%(x, y, Q) + Q = ieee.float_pack80(x) + y = ieee.float_unpack80(Q) + assert repr(x) == repr(y), '%r != %r, Q=%r' % (x, y, Q) + + Q = [] + ieee.pack_float(Q, x, 8, False) + Q = Q[0] + y = ieee.unpack_float(Q, False) + assert repr(x) == repr(y), '%r != %r, Q=%r' % (x, y, Q) + + Q = [] + ieee.pack_float80(Q, x, False) + Q = Q[0] + y = ieee.unpack_float80(Q, False) + assert repr(x) == repr(y), '%r != %r, Q=%r' % (x, y, Q) # check that packing agrees with the struct module struct_pack8 = struct.unpack(' Author: Philip Jenvey Branch: py3k Changeset: r61292:057f9d8723ad Date: 2013-02-15 16:21 -0800 http://bitbucket.org/pypy/pypy/changeset/057f9d8723ad/ Log: add more ceil/floor tests and direct test fixes from Timo Paulssen's py3k-ceil-floor branch diff --git a/pypy/module/math/test/test_math.py b/pypy/module/math/test/test_math.py --- a/pypy/module/math/test/test_math.py +++ b/pypy/module/math/test/test_math.py @@ -3,7 +3,7 @@ from pypy.interpreter.function import Function from pypy.interpreter.gateway import BuiltinCode from pypy.module.math.test import test_direct - +from rpython.rlib.rfloat import INFINITY, NAN class AppTestMath: spaceconfig = { @@ -18,6 +18,12 @@ # test_direct, but this is a ValueError on 3.x if (a, b, expected) == ('log1p', (-1.0,), OverflowError): expected = ValueError + # 3.x ceil/floor differ from 2.x + if a in ('ceil', 'floor'): + if b[0] in (INFINITY, -INFINITY): + expected = OverflowError + elif b[0] in (NAN, -NAN): + expected = ValueError if type(expected) is type and issubclass(expected, Exception): expected = getattr(space, "w_%s" % expected.__name__) @@ -320,3 +326,91 @@ assert type(func(0.5)) is int raises(OverflowError, func, float('inf')) raises(ValueError, func, float('nan')) + + def test_ceil(self): + # adapted from the cpython test case + import math + raises(TypeError, math.ceil) + assert type(math.ceil(0.4)) is int + assert math.ceil(0.5) == 1 + assert math.ceil(1.0) == 1 + assert math.ceil(1.5) == 2 + assert math.ceil(-0.5) == 0 + assert math.ceil(-1.0) == -1 + assert math.ceil(-1.5) == -1 + + class TestCeil: + def __ceil__(self): + return 42 + class TestNoCeil: + pass + assert math.ceil(TestCeil()) == 42 + raises(TypeError, math.ceil, TestNoCeil()) + + t = TestNoCeil() + t.__ceil__ = lambda *args: args + raises(TypeError, math.ceil, t) + raises(TypeError, math.ceil, t, 0) + + # observed in a cpython interactive shell + raises(OverflowError, math.ceil, float("inf")) + raises(OverflowError, math.ceil, float("-inf")) + raises(ValueError, math.ceil, float("nan")) + + class StrangeCeil: + def __ceil__(self): + return "this is a string" + + assert math.ceil(StrangeCeil()) == "this is a string" + + class CustomFloat: + def __float__(self): + return 99.9 + + assert math.ceil(CustomFloat()) == 100 + + def test_floor(self): + # adapted from the cpython test case + import math + raises(TypeError, math.floor) + assert type(math.floor(0.4)) is int + assert math.floor(0.5) == 0 + assert math.floor(1.0) == 1 + assert math.floor(1.5) == 1 + assert math.floor(-0.5) == -1 + assert math.floor(-1.0) == -1 + assert math.floor(-1.5) == -2 + assert math.floor(1.23e167) == int(1.23e167) + assert math.floor(-1.23e167) == int(-1.23e167) + + class TestFloor: + def __floor__(self): + return 42 + class TestNoFloor: + pass + assert math.floor(TestFloor()) == 42 + raises(TypeError, math.floor, TestNoFloor()) + + t = TestNoFloor() + t.__floor__ = lambda *args: args + raises(TypeError, math.floor, t) + raises(TypeError, math.floor, t, 0) + + # observed in a cpython interactive shell + raises(OverflowError, math.floor, float("inf")) + raises(OverflowError, math.floor, float("-inf")) + raises(ValueError, math.floor, float("nan")) + + class StrangeCeil: + def __floor__(self): + return "this is a string" + + assert math.floor(StrangeCeil()) == "this is a string" + + assert math.floor(1.23e167) - 1.23e167 == 0.0 + + class CustomFloat: + def __float__(self): + return 99.9 + + assert math.floor(CustomFloat()) == 99 From noreply at buildbot.pypy.org Sat Feb 16 01:22:57 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Sat, 16 Feb 2013 01:22:57 +0100 (CET) Subject: [pypy-commit] pypy py3k: 2to3 Message-ID: <20130216002257.869AE1C00A8@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61293:186e137b1c19 Date: 2013-02-15 16:21 -0800 http://bitbucket.org/pypy/pypy/changeset/186e137b1c19/ Log: 2to3 diff --git a/pypy/module/_io/test/test_bufferedio.py b/pypy/module/_io/test/test_bufferedio.py --- a/pypy/module/_io/test/test_bufferedio.py +++ b/pypy/module/_io/test/test_bufferedio.py @@ -563,9 +563,9 @@ import _io raw = _io.FileIO(self.tmpfile, 'wb+') f = _io.BufferedRandom(raw) - f.write('abc') + f.write(b'abc') f.seek(0) - assert f.read() == 'abc' + assert f.read() == b'abc' def test_write_rewind_write(self): # Various combinations of reading / writing / seeking From noreply at buildbot.pypy.org Sat Feb 16 01:22:58 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Sat, 16 Feb 2013 01:22:58 +0100 (CET) Subject: [pypy-commit] pypy py3k: quiet ctypes warnings Message-ID: <20130216002258.B506C1C00A8@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61294:053a010a3247 Date: 2013-02-15 16:21 -0800 http://bitbucket.org/pypy/pypy/changeset/053a010a3247/ Log: quiet ctypes warnings diff --git a/lib_pypy/grp.py b/lib_pypy/grp.py --- a/lib_pypy/grp.py +++ b/lib_pypy/grp.py @@ -60,6 +60,12 @@ libc.getgrent.argtypes = [] libc.getgrent.restype = POINTER(GroupStruct) +libc.setgrent.argtypes = [] +libc.setgrent.restype = None + +libc.endgrent.argtypes = [] +libc.endgrent.restype = None + def _group_from_gstruct(res): i = 0 mem = [] From noreply at buildbot.pypy.org Sat Feb 16 01:45:38 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Sat, 16 Feb 2013 01:45:38 +0100 (CET) Subject: [pypy-commit] pypy py3k: thread -> rthread Message-ID: <20130216004538.2B9A21C00A8@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61295:ea303d1c3d30 Date: 2013-02-15 16:45 -0800 http://bitbucket.org/pypy/pypy/changeset/ea303d1c3d30/ Log: thread -> rthread diff --git a/pypy/module/thread/os_lock.py b/pypy/module/thread/os_lock.py --- a/pypy/module/thread/os_lock.py +++ b/pypy/module/thread/os_lock.py @@ -142,8 +142,8 @@ self.rlock_count = 0 self.rlock_owner = 0 try: - self.lock = thread.allocate_lock() - except thread.error: + self.lock = rthread.allocate_lock() + except rthread.error: raise wrap_thread_error(space, "cannot allocate lock") def descr__new__(space, w_subtype): @@ -171,7 +171,7 @@ internal counter is simply incremented. If nobody holds the lock, the lock is taken and its internal counter initialized to 1.""" microseconds = parse_acquire_args(space, blocking, timeout) - tid = thread.get_ident() + tid = rthread.get_ident() if self.rlock_count > 0 and tid == self.rlock_owner: try: self.rlock_count = ovfcheck(self.rlock_count + 1) @@ -203,7 +203,7 @@ Do note that if the lock was acquire()d several times in a row by the current thread, release() needs to be called as many times for the lock to be available for other threads.""" - tid = thread.get_ident() + tid = rthread.get_ident() if self.rlock_count == 0 or self.rlock_owner != tid: raise OperationError(space.w_RuntimeError, space.wrap( "cannot release un-acquired lock")) @@ -214,7 +214,7 @@ def is_owned_w(self, space): """For internal use by `threading.Condition`.""" - tid = thread.get_ident() + tid = rthread.get_ident() if self.rlock_count > 0 and self.rlock_owner == tid: return space.w_True else: From noreply at buildbot.pypy.org Sat Feb 16 01:45:39 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Sat, 16 Feb 2013 01:45:39 +0100 (CET) Subject: [pypy-commit] pypy py3k: CheckAllocation fails on this branch for seemingly stupid reasons, disable it Message-ID: <20130216004539.66A3D1C00A8@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61296:96428cffca35 Date: 2013-02-15 16:45 -0800 http://bitbucket.org/pypy/pypy/changeset/96428cffca35/ Log: CheckAllocation fails on this branch for seemingly stupid reasons, disable it diff --git a/pypy/module/bz2/test/test_bz2_file.py b/pypy/module/bz2/test/test_bz2_file.py --- a/pypy/module/bz2/test/test_bz2_file.py +++ b/pypy/module/bz2/test/test_bz2_file.py @@ -52,7 +52,9 @@ mod.RANDOM_DATA = ''.join([s[int(random.random() * len(s))] for i in range(30000)]) -class AppTestBZ2File(CheckAllocation): +class AppTestBZ2File: #(CheckAllocation): + # XXX: CheckAllocation fails on py3 (seems to false positive on + # BZ2File's RLocks) spaceconfig = { "usemodules": ["bz2", "thread", "binascii", "rctime"] } From noreply at buildbot.pypy.org Sat Feb 16 01:52:47 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Sat, 16 Feb 2013 01:52:47 +0100 (CET) Subject: [pypy-commit] pypy py3k: this isn't necessary Message-ID: <20130216005247.6879F1C00A8@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61297:6c37adc8c491 Date: 2013-02-15 16:50 -0800 http://bitbucket.org/pypy/pypy/changeset/6c37adc8c491/ Log: this isn't necessary diff --git a/pypy/module/_cffi_backend/test/_backend_test_c.py b/pypy/module/_cffi_backend/test/_backend_test_c.py --- a/pypy/module/_cffi_backend/test/_backend_test_c.py +++ b/pypy/module/_cffi_backend/test/_backend_test_c.py @@ -1148,7 +1148,7 @@ orig_getline = linecache.getline try: linecache.getline = lambda *args: 'LINE' # hack: speed up PyPy tests - sys.stderr = io.StringIO() + sys.stderr = cStringIO.StringIO() assert f(100) == 300 assert sys.stderr.getvalue() == '' assert f(10000) == -42 @@ -1161,7 +1161,7 @@ $ ValueError: 42 """) - sys.stderr = io.StringIO() + sys.stderr = cStringIO.StringIO() bigvalue = 20000 assert f(bigvalue) == -42 assert matches(sys.stderr.getvalue(), """\ From noreply at buildbot.pypy.org Sat Feb 16 01:52:48 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Sat, 16 Feb 2013 01:52:48 +0100 (CET) Subject: [pypy-commit] pypy py3k: 2to3 Message-ID: <20130216005248.B480F1C00A8@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61298:402939c23428 Date: 2013-02-15 16:52 -0800 http://bitbucket.org/pypy/pypy/changeset/402939c23428/ Log: 2to3 diff --git a/pypy/module/fcntl/test/test_fcntl.py b/pypy/module/fcntl/test/test_fcntl.py --- a/pypy/module/fcntl/test/test_fcntl.py +++ b/pypy/module/fcntl/test/test_fcntl.py @@ -32,13 +32,13 @@ fcntl.fcntl(f, 1, 0) fcntl.fcntl(f, 1) - fcntl.fcntl(F(long(f.fileno())), 1) + fcntl.fcntl(F(int(f.fileno())), 1) raises(TypeError, fcntl.fcntl, "foo") raises(TypeError, fcntl.fcntl, f, "foo") raises(TypeError, fcntl.fcntl, F("foo"), 1) raises(ValueError, fcntl.fcntl, -1, 1, 0) raises(ValueError, fcntl.fcntl, F(-1), 1, 0) - raises(ValueError, fcntl.fcntl, F(long(-1)), 1, 0) + raises(ValueError, fcntl.fcntl, F(int(-1)), 1, 0) assert fcntl.fcntl(f, 1, 0) == 0 assert fcntl.fcntl(f, 2, "foo") == b"foo" assert fcntl.fcntl(f, 2, memoryview(b"foo")) == b"foo" From noreply at buildbot.pypy.org Sat Feb 16 02:26:50 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Sat, 16 Feb 2013 02:26:50 +0100 (CET) Subject: [pypy-commit] pypy py3k: fix NameError Message-ID: <20130216012650.4165E1C062C@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61299:3b672ceb8674 Date: 2013-02-15 17:26 -0800 http://bitbucket.org/pypy/pypy/changeset/3b672ceb8674/ Log: fix NameError diff --git a/lib-python/3.2/test/test_dict.py b/lib-python/3.2/test/test_dict.py --- a/lib-python/3.2/test/test_dict.py +++ b/lib-python/3.2/test/test_dict.py @@ -319,7 +319,7 @@ self.assertEqual(va, int(ka)) kb, vb = tb = b.popitem() self.assertEqual(vb, int(kb)) - if test_support.check_impl_detail(): + if support.check_impl_detail(): self.assertFalse(copymode < 0 and ta != tb) self.assertFalse(a) self.assertFalse(b) From noreply at buildbot.pypy.org Sat Feb 16 04:42:16 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sat, 16 Feb 2013 04:42:16 +0100 (CET) Subject: [pypy-commit] pypy default: modify this test so it would have failed untranslated without 1de5c08faeca Message-ID: <20130216034216.B12711C00A8@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61300:35075dd16ef9 Date: 2013-02-15 18:53 -0500 http://bitbucket.org/pypy/pypy/changeset/35075dd16ef9/ Log: modify this test so it would have failed untranslated without 1de5c08faeca diff --git a/pypy/module/thread/test/test_thread.py b/pypy/module/thread/test/test_thread.py --- a/pypy/module/thread/test/test_thread.py +++ b/pypy/module/thread/test/test_thread.py @@ -220,18 +220,18 @@ import signal def f(): - for x in range(50): + for x in range(5): if waiting: thread.interrupt_main() return print 'tock...', x # <-force the GIL to be released, as - time.sleep(0.01) # time.sleep doesn't do non-translated + time.sleep(0.1) # time.sleep doesn't do non-translated def busy_wait(): waiting.append(None) - for x in range(100): + for x in range(10): print 'tick...', x # <-force the GIL to be released, as - time.sleep(0.01) # time.sleep doesn't do non-translated + time.sleep(0.1) # time.sleep doesn't do non-translated waiting.pop() # This is normally called by app_main.py From noreply at buildbot.pypy.org Sat Feb 16 04:42:18 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sat, 16 Feb 2013 04:42:18 +0100 (CET) Subject: [pypy-commit] pypy default: clean up rstruct.ieee 80-bit float packing and improve tests Message-ID: <20130216034218.2D6681C00A8@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61301:0a025c478fca Date: 2013-02-15 21:53 -0500 http://bitbucket.org/pypy/pypy/changeset/0a025c478fca/ Log: clean up rstruct.ieee 80-bit float packing and improve tests diff --git a/pypy/module/micronumpy/test/test_numarray.py b/pypy/module/micronumpy/test/test_numarray.py --- a/pypy/module/micronumpy/test/test_numarray.py +++ b/pypy/module/micronumpy/test/test_numarray.py @@ -1745,13 +1745,13 @@ assert a[1] == 0xff assert len(a.data) == 16 - def test_explicit_dtype_conversion(self): from _numpypy import array a = array([1.0, 2.0]) b = array(a, dtype='d') assert a.dtype is b.dtype + class AppTestMultiDim(BaseNumpyAppTest): def test_init(self): import _numpypy diff --git a/pypy/module/micronumpy/types.py b/pypy/module/micronumpy/types.py --- a/pypy/module/micronumpy/types.py +++ b/pypy/module/micronumpy/types.py @@ -1530,8 +1530,8 @@ def byteswap(self, w_v): value = self.unbox(w_v) - result = StringBuilder(12) - pack_float80(result, value, not native_is_bigendian) + result = StringBuilder(10) + pack_float80(result, value, 10, not native_is_bigendian) return self.box(unpack_float80(result.build(), native_is_bigendian)) NonNativeFloat96 = Float96 @@ -1560,8 +1560,8 @@ def byteswap(self, w_v): value = self.unbox(w_v) - result = StringBuilder(16) - pack_float80(result, value, not native_is_bigendian) + result = StringBuilder(10) + pack_float80(result, value, 10, not native_is_bigendian) return self.box(unpack_float80(result.build(), native_is_bigendian)) NonNativeFloat128 = Float128 diff --git a/rpython/rlib/rstruct/ieee.py b/rpython/rlib/rstruct/ieee.py --- a/rpython/rlib/rstruct/ieee.py +++ b/rpython/rlib/rstruct/ieee.py @@ -25,26 +25,23 @@ return int_part def float_unpack(Q, size): - """Convert a 16-bit, 32-bit 64-bit integer created + """Convert a 16-bit, 32-bit, or 64-bit integer created by float_pack into a Python float.""" if size == 8: MIN_EXP = -1021 # = sys.float_info.min_exp MAX_EXP = 1024 # = sys.float_info.max_exp MANT_DIG = 53 # = sys.float_info.mant_dig BITS = 64 - one = r_ulonglong(1) elif size == 4: MIN_EXP = -125 # C's FLT_MIN_EXP MAX_EXP = 128 # FLT_MAX_EXP MANT_DIG = 24 # FLT_MANT_DIG BITS = 32 - one = r_ulonglong(1) elif size == 2: MIN_EXP = -13 MAX_EXP = 16 MANT_DIG = 11 BITS = 16 - one = r_ulonglong(1) else: raise ValueError("invalid size value") @@ -56,6 +53,7 @@ raise ValueError("input '%r' out of range '%r'" % (Q, Q>>BITS)) # extract pieces with assumed 1.mant values + one = r_ulonglong(1) sign = rarithmetic.intmask(Q >> BITS - 1) exp = rarithmetic.intmask((Q & ((one << BITS - 1) - (one << MANT_DIG - 1))) >> MANT_DIG - 1) mant = Q & ((one << MANT_DIG - 1) - 1) @@ -72,27 +70,32 @@ result = math.ldexp(mant, exp + MIN_EXP - MANT_DIG - 1) return -result if sign else result -def float_unpack80(QQ): +def float_unpack80(QQ, size): '''Unpack a (mant, exp) tuple of r_ulonglong in 80-bit extended format into a long double float ''' - MIN_EXP = -16381 - MAX_EXP = 16384 - MANT_DIG = 64 - TOPBITS = 80 - 64 - one = r_ulonglong(1) + if size == 10 or size == 12 or size == 16: + MIN_EXP = -16381 + MAX_EXP = 16384 + MANT_DIG = 64 + TOP_BITS = 80 - 64 + else: + raise ValueError("invalid size value") + if len(QQ) != 2: raise ValueError("QQ must be two 64 bit uints") + if not objectmodel.we_are_translated(): # This tests generates wrong code when translated: # with gcc, shifting a 64bit int by 64 bits does # not change the value. - if QQ[1] >> TOPBITS: - raise ValueError("input '%r' out of range '%r'" % (QQ, QQ[1]>>TOPBITS)) + if QQ[1] >> TOP_BITS: + raise ValueError("input '%r' out of range '%r'" % (QQ, QQ[1]>>TOP_BITS)) # extract pieces with explicit one in MANT_DIG - sign = rarithmetic.intmask(QQ[1] >> TOPBITS - 1) - exp = rarithmetic.intmask((QQ[1] & ((one << TOPBITS - 1) - 1))) + one = r_ulonglong(1) + sign = rarithmetic.intmask(QQ[1] >> TOP_BITS - 1) + exp = rarithmetic.intmask((QQ[1] & ((one << TOP_BITS - 1) - 1))) mant = QQ[0] if exp == MAX_EXP - MIN_EXP + 2: @@ -171,14 +174,18 @@ sign = r_ulonglong(sign) return ((sign << BITS - 1) | (exp << MANT_DIG - 1)) | mant -def float_pack80(x): +def float_pack80(x, size): """Convert a Python float or longfloat x into two 64-bit unsigned integers with 80 bit extended representation.""" - MIN_EXP = -16381 - MAX_EXP = 16384 - MANT_DIG = 64 - BITS = 80 x = float(x) # longfloat not really supported + if size == 10 or size == 12 or size == 16: + MIN_EXP = -16381 + MAX_EXP = 16384 + MANT_DIG = 64 + BITS = 80 + else: + raise ValueError("invalid size value") + sign = rfloat.copysign(1.0, x) < 0.0 if not rfloat.isfinite(x): if rfloat.isinf(x): @@ -235,32 +242,32 @@ result.append("".join(l)) @jit.unroll_safe -def pack_float80(result, x, be): +def pack_float80(result, x, size, be): l = [] - unsigned = float_pack80(x) + unsigned = float_pack80(x, size) for i in range(8): l.append(chr((unsigned[0] >> (i * 8)) & 0xFF)) for i in range(2): l.append(chr((unsigned[1] >> (i * 8)) & 0xFF)) + for i in range(size - 10): + l.append('\x00') if be: l.reverse() result.append("".join(l)) def unpack_float(s, be): unsigned = r_ulonglong(0) - for i in range(len(s)): - c = ord(s[len(s) - 1 - i if be else i]) + for i in range(min(len(s), 8)): + c = ord(s[-i - 1 if be else i]) unsigned |= r_ulonglong(c) << (i * 8) return float_unpack(unsigned, len(s)) def unpack_float80(s, be): - if len(s) != 10: - raise ValueError QQ = [r_ulonglong(0), r_ulonglong(0)] for i in range(8): - c = ord(s[9 - i if be else i]) + c = ord(s[-i - 1 if be else i]) QQ[0] |= r_ulonglong(c) << (i * 8) for i in range(8, 10): - c = ord(s[9 - i if be else i]) + c = ord(s[-i - 1 if be else i]) QQ[1] |= r_ulonglong(c) << ((i - 8) * 8) - return float_unpack80(QQ) + return float_unpack80(QQ, len(s)) diff --git a/rpython/rlib/rstruct/test/test_ieee.py b/rpython/rlib/rstruct/test/test_ieee.py --- a/rpython/rlib/rstruct/test/test_ieee.py +++ b/rpython/rlib/rstruct/test/test_ieee.py @@ -8,6 +8,55 @@ from rpython.translator.c.test.test_genc import compile +class TestFloatSpecific: + def test_halffloat_exact(self): + #testcases generated from numpy.float16(x).view('uint16') + cases = [[0, 0], [10, 18688], [-10, 51456], [10e3, 28898], + [float('inf'), 31744], [-float('inf'), 64512]] + for c, h in cases: + hbit = ieee.float_pack(c, 2) + assert hbit == h + assert c == ieee.float_unpack(h, 2) + + def test_halffloat_inexact(self): + #testcases generated from numpy.float16(x).view('uint16') + cases = [[10.001, 18688, 10.], [-10.001, 51456, -10], + [0.027588, 10000, 0.027587890625], + [22001, 30047, 22000]] + for c, h, f in cases: + hbit = ieee.float_pack(c, 2) + assert hbit == h + assert f == ieee.float_unpack(h, 2) + + def test_halffloat_overunderflow(self): + import math + cases = [[670000, float('inf')], [-67000, -float('inf')], + [1e-08, 0], [-1e-8, -0.]] + for f1, f2 in cases: + try: + f_out = ieee.float_unpack(ieee.float_pack(f1, 2), 2) + except OverflowError: + f_out = math.copysign(float('inf'), f1) + assert f_out == f2 + assert math.copysign(1., f_out) == math.copysign(1., f2) + + def test_float80_exact(self): + s = [] + ieee.pack_float80(s, -1., 16, False) + assert repr(s[-1]) == repr('\x00\x00\x00\x00\x00\x00\x00\x80\xff\xbf\x00\x00\x00\x00\x00\x00') + ieee.pack_float80(s, -1., 16, True) + assert repr(s[-1]) == repr('\x00\x00\x00\x00\x00\x00\xbf\xff\x80\x00\x00\x00\x00\x00\x00\x00') + ieee.pack_float80(s, -123.456, 16, False) + assert repr(s[-1]) == repr('\x00\xb8\xf3\xfd\xd4x\xe9\xf6\x05\xc0\x00\x00\x00\x00\x00\x00') + ieee.pack_float80(s, -123.456, 16, True) + assert repr(s[-1]) == repr('\x00\x00\x00\x00\x00\x00\xc0\x05\xf6\xe9x\xd4\xfd\xf3\xb8\x00') + + x = ieee.unpack_float80('\x00\x00\x00\x00\x00\x00\x00\x80\xff?\xc8\x01\x00\x00\x00\x00', False) + assert x == 1.0 + x = ieee.unpack_float80('\x00\x00\x7f\x83\xe1\x91?\xff\x80\x00\x00\x00\x00\x00\x00\x00', True) + assert x == 1.0 + + class TestFloatPacking: def setup_class(cls): if sys.version_info < (2, 6): @@ -15,25 +64,20 @@ def check_float(self, x): # check roundtrip - Q = ieee.float_pack(x, 8) - y = ieee.float_unpack(Q, 8) - assert repr(x) == repr(y), '%r != %r, Q=%r' % (x, y, Q) + for size in [10, 12, 16]: + for be in [False, True]: + Q = [] + ieee.pack_float80(Q, x, size, be) + Q = Q[0] + y = ieee.unpack_float80(Q, be) + assert repr(x) == repr(y), '%r != %r, Q=%r' % (x, y, Q) - Q = ieee.float_pack80(x) - y = ieee.float_unpack80(Q) - assert repr(x) == repr(y), '%r != %r, Q=%r' % (x, y, Q) - - Q = [] - ieee.pack_float(Q, x, 8, False) - Q = Q[0] - y = ieee.unpack_float(Q, False) - assert repr(x) == repr(y), '%r != %r, Q=%r' % (x, y, Q) - - Q = [] - ieee.pack_float80(Q, x, False) - Q = Q[0] - y = ieee.unpack_float80(Q, False) - assert repr(x) == repr(y), '%r != %r, Q=%r' % (x, y, Q) + for be in [False, True]: + Q = [] + ieee.pack_float(Q, x, 8, be) + Q = Q[0] + y = ieee.unpack_float(Q, be) + assert repr(x) == repr(y), '%r != %r, Q=%r' % (x, y, Q) # check that packing agrees with the struct module struct_pack8 = struct.unpack(' Author: Brian Kearns Branch: Changeset: r61302:4d472c7d55b5 Date: 2013-02-15 23:15 -0500 http://bitbucket.org/pypy/pypy/changeset/4d472c7d55b5/ Log: improve the numpypy concatenate test diff --git a/pypy/module/micronumpy/test/test_numarray.py b/pypy/module/micronumpy/test/test_numarray.py --- a/pypy/module/micronumpy/test/test_numarray.py +++ b/pypy/module/micronumpy/test/test_numarray.py @@ -1,5 +1,5 @@ - -import py, sys +import py +import sys from pypy.conftest import option from pypy.module.micronumpy.appbridge import get_appbridge_cache @@ -7,6 +7,7 @@ from pypy.module.micronumpy.interp_numarray import W_NDimArray from pypy.module.micronumpy.test.test_base import BaseNumpyAppTest + class MockDtype(object): class itemtype(object): @staticmethod @@ -24,9 +25,11 @@ def create_slice(a, chunks): return Chunks(chunks).apply(W_NDimArray(a)).implementation + def create_array(*args, **kwargs): return W_NDimArray.from_shape(*args, **kwargs).implementation + class TestNumArrayDirect(object): def newslice(self, *args): return self.space.newslice(*[self.space.wrap(arg) for arg in args]) @@ -1202,7 +1205,7 @@ assert d.shape == (3, 3) assert d.dtype == dtype('int32') assert (d == [[1, 0, 0], [0, 1, 0], [0, 0, 1]]).all() - + def test_eye(self): from _numpypy import eye from _numpypy import int32, dtype @@ -1232,9 +1235,6 @@ assert g.shape == (3, 4) assert (g == [[0, 0, 0, 0], [1, 0, 0, 0], [0, 1, 0, 0]]).all() - - - def test_prod(self): from _numpypy import array a = array(range(1, 6)) @@ -1473,6 +1473,11 @@ assert len(a) == 6 assert (a == [0,1,2,3,4,5]).all() assert a.dtype is dtype(int) + a = concatenate((a1, a2), axis=1) + assert (a == [0,1,2,3,4,5]).all() + a = concatenate((a1, a2), axis=-1) + assert (a == [0,1,2,3,4,5]).all() + b1 = array([[1, 2], [3, 4]]) b2 = array([[5, 6]]) b = concatenate((b1, b2), axis=0) @@ -1488,16 +1493,29 @@ f = concatenate((f1, [2], f1, [7])) assert (f == [0,1,2,0,1,7]).all() - bad_axis = raises(IndexError, concatenate, (a1,a2), axis=1) - assert str(bad_axis.value) == "axis 1 out of bounds [0, 1)" + g1 = array([[0,1,2]]) + g2 = array([[3,4,5]]) + g = concatenate((g1, g2), axis=-2) + assert (g == [[0,1,2],[3,4,5]]).all() + exc = raises(IndexError, concatenate, (g1, g2), axis=2) + assert str(exc.value) == "axis 2 out of bounds [0, 2)" + exc = raises(IndexError, concatenate, (g1, g2), axis=-3) + assert str(exc.value) == "axis -3 out of bounds [0, 2)" - concat_zero = raises(ValueError, concatenate, ()) - assert str(concat_zero.value) == \ - "need at least one array to concatenate" + exc = raises(ValueError, concatenate, ()) + assert str(exc.value) == \ + "need at least one array to concatenate" - dims_disagree = raises(ValueError, concatenate, (a1, b1), axis=0) - assert str(dims_disagree.value) == \ - "all the input arrays must have same number of dimensions" + exc = raises(ValueError, concatenate, (a1, b1), axis=0) + assert str(exc.value) == \ + "all the input arrays must have same number of dimensions" + + g1 = array([0,1,2]) + g2 = array([[3,4,5]]) + exc = raises(ValueError, concatenate, (g1, g2), axis=2) + assert str(exc.value) == \ + "all the input arrays must have same number of dimensions" + a = array([1, 2, 3, 4, 5, 6]) a = (a + a)[::2] b = concatenate((a[:3], a[-3:])) @@ -1583,7 +1601,7 @@ [[3, 9], [6, 12]]])).all() assert (x.swapaxes(1, 2) == array([[[1, 4], [2, 5], [3, 6]], [[7, 10], [8, 11],[9, 12]]])).all() - + # test slice assert (x[0:1,0:2].swapaxes(0,2) == array([[[1], [4]], [[2], [5]], [[3], [6]]])).all() @@ -2043,6 +2061,7 @@ False, False, True, False, False, False]).all() assert ((b > range(12)) == [False, True, True,False, True, True, False, False, True, False, False, False]).all() + def test_flatiter_view(self): from _numpypy import arange a = arange(10).reshape(5, 2) @@ -2263,10 +2282,10 @@ a = arange(12).reshape(2, 3, 2) assert (a.diagonal(0, 0, 1) == [[0, 8], [1, 9]]).all() assert a.diagonal(3, 0, 1).shape == (2, 0) - assert (a.diagonal(1, 0, 1) == [[2, 10], [3, 11]]).all() - assert (a.diagonal(0, 2, 1) == [[0, 3], [6, 9]]).all() - assert (a.diagonal(2, 2, 1) == [[4], [10]]).all() - assert (a.diagonal(1, 2, 1) == [[2, 5], [8, 11]]).all() + assert (a.diagonal(1, 0, 1) == [[2, 10], [3, 11]]).all() + assert (a.diagonal(0, 2, 1) == [[0, 3], [6, 9]]).all() + assert (a.diagonal(2, 2, 1) == [[4], [10]]).all() + assert (a.diagonal(1, 2, 1) == [[2, 5], [8, 11]]).all() def test_diagonal_axis_neg_ofs(self): from _numpypy import arange @@ -2274,6 +2293,7 @@ assert (a.diagonal(-1, 0, 1) == [[6], [7]]).all() assert a.diagonal(-2, 0, 1).shape == (2, 0) + class AppTestSupport(BaseNumpyAppTest): def setup_class(cls): import struct @@ -2444,6 +2464,7 @@ assert (a.argsort(axis=0) == [[1, 0, 0], [0, 1, 1]]).all() assert (a.argsort(axis=1) == [[2, 1, 0], [0, 1, 2]]).all() + class AppTestRanges(BaseNumpyAppTest): def test_arange(self): from _numpypy import arange, dtype @@ -2489,6 +2510,7 @@ cache.w_array_repr = cls.old_array_repr cache.w_array_str = cls.old_array_str + class AppTestRecordDtype(BaseNumpyAppTest): def test_zeros(self): from _numpypy import zeros, integer @@ -2659,4 +2681,3 @@ assert x.__pypy_data__ is obj del x.__pypy_data__ assert x.__pypy_data__ is None - From noreply at buildbot.pypy.org Sat Feb 16 05:20:01 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sat, 16 Feb 2013 05:20:01 +0100 (CET) Subject: [pypy-commit] pypy default: update whatsnew for signal-and-thread branch merge Message-ID: <20130216042001.7782E1C0673@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61303:0dfddf4a61ca Date: 2013-02-15 23:19 -0500 http://bitbucket.org/pypy/pypy/changeset/0dfddf4a61ca/ Log: update whatsnew for signal-and-thread branch merge diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst --- a/pypy/doc/whatsnew-head.rst +++ b/pypy/doc/whatsnew-head.rst @@ -19,7 +19,7 @@ .. branch: numpypy-longdouble Long double support for numpypy .. branch: numpypy-real-as-view -Convert real, imag from ufuncs to views. This involves the beginning of +Convert real, imag from ufuncs to views. This involves the beginning of view() functionality .. branch: signatures @@ -57,7 +57,11 @@ .. branch: cleanup-tests Consolidated the lib_pypy/pypy_test and pypy/module/test_lib_pypy tests into -+one directory for reduced confusion and so they all run nightly. +one directory for reduced confusion and so they all run nightly. .. branch: unquote-faster .. branch: urlparse-unquote-faster + +.. branch: signal-and-thread +Add "__pypy__.thread.signals_enabled", a context manager. Can be used in a +non-main thread to enable the processing of signal handlers in that thread. From noreply at buildbot.pypy.org Sat Feb 16 09:41:50 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sat, 16 Feb 2013 09:41:50 +0100 (CET) Subject: [pypy-commit] pypy default: a failing test for the signals_enabled context manager's fork logic Message-ID: <20130216084151.002361C009B@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61304:320c4790eae6 Date: 2013-02-16 02:26 -0500 http://bitbucket.org/pypy/pypy/changeset/320c4790eae6/ Log: a failing test for the signals_enabled context manager's fork logic diff --git a/pypy/module/__pypy__/test/test_signal.py b/pypy/module/__pypy__/test/test_signal.py --- a/pypy/module/__pypy__/test/test_signal.py +++ b/pypy/module/__pypy__/test/test_signal.py @@ -1,5 +1,7 @@ import sys +from pypy.module.thread.test.support import GenericTestThread + class AppTestMinimal: spaceconfig = dict(usemodules=['__pypy__']) @@ -11,7 +13,7 @@ # assert did not crash -class AppTestThreadSignal: +class AppTestThreadSignal(GenericTestThread): spaceconfig = dict(usemodules=['__pypy__', 'thread', 'signal', 'time']) def test_enable_signals(self): @@ -48,6 +50,37 @@ finally: __pypy__.thread._signals_enter() + def test_thread_fork_signals(self): + import __pypy__ + import os, thread, signal + + if not hasattr(os, 'fork'): + skip("No fork on this platform") + + def fork(): + with __pypy__.thread.signals_enabled: + return os.fork() + + def threadfunction(): + pid = fork() + if pid == 0: + print 'in child' + # signal() only works from the 'main' thread + signal.signal(signal.SIGUSR1, signal.SIG_IGN) + os._exit(42) + else: + self.timeout_killer(pid, 5) + exitcode = os.waitpid(pid, 0)[1] + feedback.append(exitcode) + + feedback = [] + thread.start_new_thread(threadfunction, ()) + self.waitfor(lambda: feedback) + # if 0, an (unraisable) exception was raised from the forked thread. + # if 9, process was killed by timer. + # if 42<<8, os._exit(42) was correctly reached. + assert feedback == [42<<8] + class AppTestThreadSignalLock: spaceconfig = dict(usemodules=['__pypy__', 'thread', 'signal']) diff --git a/pypy/module/thread/threadlocals.py b/pypy/module/thread/threadlocals.py --- a/pypy/module/thread/threadlocals.py +++ b/pypy/module/thread/threadlocals.py @@ -81,6 +81,16 @@ # (which are now dead); and for the current thread, force an # enable_signals() if necessary. That's a hack but I cannot # figure out a non-hackish way to handle thread+signal+fork :-( + """ + TODO: this logic is currently flawed as we need to differentiate + between: 1) fork while in a main thread, in which case old should + not be incremented + 2) fork while in a subthread that has an enable_threads + context but is not main (in which case old should be + incremented, as the thread should get a point for becoming + the new 'main', so it remains in the dict when all its + contexts exit) + """ ident = rthread.get_ident() old = self._signalsenabled.get(ident, 0) self._signalsenabled.clear() From noreply at buildbot.pypy.org Sat Feb 16 09:41:52 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sat, 16 Feb 2013 09:41:52 +0100 (CET) Subject: [pypy-commit] pypy default: fix the failing test by still keeping track of mainthreadident so we know if Message-ID: <20130216084152.588AA1C009B@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61305:2fe373e0724e Date: 2013-02-16 02:44 -0500 http://bitbucket.org/pypy/pypy/changeset/2fe373e0724e/ Log: fix the failing test by still keeping track of mainthreadident so we know if the forking thread should get an enable_signals point for becoming main diff --git a/pypy/module/thread/threadlocals.py b/pypy/module/thread/threadlocals.py --- a/pypy/module/thread/threadlocals.py +++ b/pypy/module/thread/threadlocals.py @@ -15,6 +15,7 @@ def _cleanup_(self): self._valuedict.clear() self._signalsenabled.clear() + self._mainthreadident = 0 self._mostrecentkey = 0 # fast minicaching for the common case self._mostrecentvalue = None # fast minicaching for the common case @@ -35,6 +36,7 @@ if value is not None: if len(self._valuedict) == 0: self._signalsenabled[ident] = 1 # the main thread is enabled + self._mainthreadident = ident self._valuedict[ident] = value else: try: @@ -81,19 +83,10 @@ # (which are now dead); and for the current thread, force an # enable_signals() if necessary. That's a hack but I cannot # figure out a non-hackish way to handle thread+signal+fork :-( - """ - TODO: this logic is currently flawed as we need to differentiate - between: 1) fork while in a main thread, in which case old should - not be incremented - 2) fork while in a subthread that has an enable_threads - context but is not main (in which case old should be - incremented, as the thread should get a point for becoming - the new 'main', so it remains in the dict when all its - contexts exit) - """ ident = rthread.get_ident() old = self._signalsenabled.get(ident, 0) + if ident is not self._mainthreadident: + self._mainthreadident = ident + old += 1 self._signalsenabled.clear() - if old == 0: - old = 1 self._signalsenabled[ident] = old From noreply at buildbot.pypy.org Sat Feb 16 09:41:53 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sat, 16 Feb 2013 09:41:53 +0100 (CET) Subject: [pypy-commit] pypy default: prevent signals from being disabled twice Message-ID: <20130216084153.92CA91C009B@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61306:04926eb3ab15 Date: 2013-02-16 03:15 -0500 http://bitbucket.org/pypy/pypy/changeset/04926eb3ab15/ Log: prevent signals from being disabled twice diff --git a/pypy/module/__pypy__/test/test_signal.py b/pypy/module/__pypy__/test/test_signal.py --- a/pypy/module/__pypy__/test/test_signal.py +++ b/pypy/module/__pypy__/test/test_signal.py @@ -3,6 +3,18 @@ from pypy.module.thread.test.support import GenericTestThread +class TestThreadSignal: + spaceconfig = dict(usemodules=['__pypy__', 'thread']) + + def test_exit_twice(self, space): + from pypy.module.__pypy__.interp_signal import signals_exit, signals_enter + signals_exit(space) + try: + raises(KeyError, signals_exit, space) + finally: + signals_enter(space) + + class AppTestMinimal: spaceconfig = dict(usemodules=['__pypy__']) diff --git a/pypy/module/thread/threadlocals.py b/pypy/module/thread/threadlocals.py --- a/pypy/module/thread/threadlocals.py +++ b/pypy/module/thread/threadlocals.py @@ -57,10 +57,7 @@ def disable_signals(self): ident = rthread.get_ident() - try: - new = self._signalsenabled[ident] - 1 - except KeyError: - return + new = self._signalsenabled[ident] - 1 if new > 0: self._signalsenabled[ident] = new else: From noreply at buildbot.pypy.org Sat Feb 16 09:41:54 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sat, 16 Feb 2013 09:41:54 +0100 (CET) Subject: [pypy-commit] pypy default: clean up the thread's signals enabled count on thread exit Message-ID: <20130216084154.C7E431C009B@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61307:0fb9480d9d6d Date: 2013-02-16 03:16 -0500 http://bitbucket.org/pypy/pypy/changeset/0fb9480d9d6d/ Log: clean up the thread's signals enabled count on thread exit diff --git a/pypy/module/thread/threadlocals.py b/pypy/module/thread/threadlocals.py --- a/pypy/module/thread/threadlocals.py +++ b/pypy/module/thread/threadlocals.py @@ -43,6 +43,10 @@ del self._valuedict[ident] except KeyError: pass + try: + del self._signalsenabled[ident] + except KeyError: + pass # update the minicache to prevent it from containing an outdated value self._mostrecentkey = ident self._mostrecentvalue = value From noreply at buildbot.pypy.org Sat Feb 16 10:19:10 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sat, 16 Feb 2013 10:19:10 +0100 (CET) Subject: [pypy-commit] cffi default: Moving the determination of the base integer type of an enum Message-ID: <20130216091910.5A7A81C062C@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r1160:70927696eb9c Date: 2013-02-16 10:17 +0100 http://bitbucket.org/cffi/cffi/changeset/70927696eb9c/ Log: Moving the determination of the base integer type of an enum out of C code, into the 'cffi' package. This is work in progress; it should eventually permit the new test to fully pass. For now wrote a warning in the doc. diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c --- a/c/_cffi_backend.c +++ b/c/_cffi_backend.c @@ -4253,20 +4253,15 @@ char *ename; PyObject *enumerators, *enumvalues; PyObject *dict1 = NULL, *dict2 = NULL, *combined = NULL, *tmpkey = NULL; - ffi_type *ffitype; int name_size; - CTypeDescrObject *td; + CTypeDescrObject *td, *basetd; Py_ssize_t i, n; - struct aligncheck_int { char x; int y; }; - struct aligncheck_long { char x; long y; }; - long smallest_item = 0; - unsigned long largest_item = 0; - int size, flags; - - if (!PyArg_ParseTuple(args, "sO!O!:new_enum_type", + + if (!PyArg_ParseTuple(args, "sO!O!O!:new_enum_type", &ename, &PyTuple_Type, &enumerators, - &PyTuple_Type, &enumvalues)) + &PyTuple_Type, &enumvalues, + &CTypeDescr_Type, &basetd)) return NULL; n = PyTuple_GET_SIZE(enumerators); @@ -4276,6 +4271,12 @@ return NULL; } + if (!(basetd->ct_flags & (CT_PRIMITIVE_SIGNED|CT_PRIMITIVE_UNSIGNED))) { + PyErr_SetString(PyExc_TypeError, + "expected a primitive signed or unsigned base type"); + return NULL; + } + dict1 = PyDict_New(); if (dict1 == NULL) goto error; @@ -4284,8 +4285,7 @@ goto error; for (i=n; --i >= 0; ) { - long lvalue; - unsigned long ulvalue; + long long lvalue; PyObject *value = PyTuple_GET_ITEM(enumvalues, i); tmpkey = PyTuple_GET_ITEM(enumerators, i); Py_INCREF(tmpkey); @@ -4308,31 +4308,8 @@ goto error; } } - lvalue = PyLong_AsLong(value); - if (PyErr_Occurred()) { - PyErr_Clear(); - ulvalue = PyLong_AsUnsignedLong(value); - if (PyErr_Occurred()) { - PyErr_Format(PyExc_OverflowError, - "enum '%s' declaration for '%s' does not fit " - "a long or unsigned long", - ename, PyText_AS_UTF8(tmpkey)); - goto error; - } - if (ulvalue > largest_item) - largest_item = ulvalue; - } - else { - if (lvalue < 0) { - if (lvalue < smallest_item) - smallest_item = lvalue; - } - else { - ulvalue = (unsigned long)lvalue; - if (ulvalue > largest_item) - largest_item = ulvalue; - } - } + if (convert_from_object((char*)&lvalue, basetd, value) < 0) + goto error; /* out-of-range or badly typed 'value' */ if (PyDict_SetItem(dict1, tmpkey, value) < 0) goto error; if (PyDict_SetItem(dict2, value, tmpkey) < 0) @@ -4341,32 +4318,6 @@ tmpkey = NULL; } - if (smallest_item < 0) { - flags = CT_PRIMITIVE_SIGNED | CT_PRIMITIVE_FITS_LONG | CT_IS_ENUM; - if (smallest_item == (int)smallest_item && - largest_item <= (unsigned long)INT_MAX) { - size = sizeof(int); - } - else if (largest_item <= (unsigned long)LONG_MAX) { - size = sizeof(long); - } - else { - PyErr_Format(PyExc_OverflowError, - "enum '%s' values don't all fit into either 'long' " - "or 'unsigned long'", ename); - goto error; - } - } - else if (sizeof(unsigned int) < sizeof(unsigned long) && - largest_item == (unsigned int)largest_item) { - flags = CT_PRIMITIVE_UNSIGNED | CT_PRIMITIVE_FITS_LONG | CT_IS_ENUM; - size = sizeof(unsigned int); - } - else { - flags = CT_PRIMITIVE_UNSIGNED | CT_IS_ENUM; - size = sizeof(unsigned long); - } - combined = PyTuple_Pack(2, dict1, dict2); if (combined == NULL) goto error; @@ -4374,12 +4325,6 @@ Py_CLEAR(dict2); Py_CLEAR(dict1); - switch (size) { - case 4: ffitype = &ffi_type_sint32; break; - case 8: ffitype = &ffi_type_sint64; break; - default: Py_FatalError("'int' or 'long' is not 4 or 8 bytes"); return NULL; - } - name_size = strlen("enum ") + strlen(ename) + 1; td = ctypedescr_new(name_size); if (td == NULL) @@ -4388,11 +4333,10 @@ memcpy(td->ct_name, "enum ", strlen("enum ")); memcpy(td->ct_name + strlen("enum "), ename, name_size - strlen("enum ")); td->ct_stuff = combined; - td->ct_size = size; - td->ct_length = size == sizeof(int) ? offsetof(struct aligncheck_int, y) - : offsetof(struct aligncheck_long, y); - td->ct_extra = ffitype; - td->ct_flags = flags; + td->ct_size = basetd->ct_size; + td->ct_length = basetd->ct_length; /* alignment */ + td->ct_extra = basetd->ct_extra; /* ffi type */ + td->ct_flags = basetd->ct_flags | CT_IS_ENUM; td->ct_name_position = name_size - 1; return (PyObject *)td; diff --git a/c/test_c.py b/c/test_c.py --- a/c/test_c.py +++ b/c/test_c.py @@ -1272,25 +1272,29 @@ py.test.raises(TypeError, callback, BFunc, cb, -42) def test_enum_type(): - BEnum = new_enum_type("foo", (), ()) + BUInt = new_primitive_type("unsigned int") + BEnum = new_enum_type("foo", (), (), BUInt) assert repr(BEnum) == "" assert BEnum.kind == "enum" assert BEnum.cname == "enum foo" assert BEnum.elements == {} # - BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, -20)) + BInt = new_primitive_type("int") + BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, -20), BInt) assert BEnum.kind == "enum" assert BEnum.elements == {-20: 'ab', 0: 'def', 1: 'c'} # 'elements' is not the real dict, but merely a copy BEnum.elements[2] = '??' assert BEnum.elements == {-20: 'ab', 0: 'def', 1: 'c'} # - BEnum = new_enum_type("bar", ('ab', 'cd'), (5, 5)) + BEnum = new_enum_type("bar", ('ab', 'cd'), (5, 5), BUInt) assert BEnum.elements == {5: 'ab'} assert BEnum.relements == {'ab': 5, 'cd': 5} def test_cast_to_enum(): - BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, -20)) + BInt = new_primitive_type("int") + BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, -20), BInt) + assert sizeof(BEnum) == sizeof(BInt) e = cast(BEnum, 0) assert repr(e) == "" assert repr(cast(BEnum, -42)) == "" @@ -1302,18 +1306,27 @@ assert int(cast(BEnum, -242 + 2**128)) == -242 assert string(cast(BEnum, -242 + 2**128)) == '-242' # - BEnum = new_enum_type("bar", ('def', 'c', 'ab'), (0, 1, 20)) + BUInt = new_primitive_type("unsigned int") + BEnum = new_enum_type("bar", ('def', 'c', 'ab'), (0, 1, 20), BUInt) e = cast(BEnum, -1) assert repr(e) == "" # unsigned int + # + BLong = new_primitive_type("long") + BEnum = new_enum_type("baz", (), (), BLong) + assert sizeof(BEnum) == sizeof(BLong) + e = cast(BEnum, -1) + assert repr(e) == "" def test_enum_with_non_injective_mapping(): - BEnum = new_enum_type("foo", ('ab', 'cd'), (7, 7)) + BInt = new_primitive_type("int") + BEnum = new_enum_type("foo", ('ab', 'cd'), (7, 7), BInt) e = cast(BEnum, 7) assert repr(e) == "" assert string(e) == 'ab' def test_enum_in_struct(): - BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, -20)) + BInt = new_primitive_type("int") + BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, -20), BInt) BStruct = new_struct_type("bar") BStructPtr = new_pointer_type(BStruct) complete_struct_or_union(BStruct, [('a1', BEnum, -1)]) @@ -1326,7 +1339,7 @@ "unsupported operand type for int(): 'NoneType'" in str(e.value)) #PyPy py.test.raises(TypeError, 'p.a1 = "def"') if sys.version_info < (3,): - BEnum2 = new_enum_type(unicode("foo"), (unicode('abc'),), (5,)) + BEnum2 = new_enum_type(unicode("foo"), (unicode('abc'),), (5,), BInt) assert string(cast(BEnum2, 5)) == 'abc' assert type(string(cast(BEnum2, 5))) is str @@ -1335,66 +1348,25 @@ max_int = max_uint // 2 max_ulong = 2 ** (size_of_long()*8) - 1 max_long = max_ulong // 2 - # 'unsigned int' case - e = new_enum_type("foo", ('a', 'b'), (0, 3)) - assert sizeof(e) == size_of_int() - assert int(cast(e, -1)) == max_uint # 'e' is unsigned - e = new_enum_type("foo", ('a', 'b'), (0, max_uint)) - assert sizeof(e) == size_of_int() - assert int(cast(e, -1)) == max_uint - assert e.elements == {0: 'a', max_uint: 'b'} - assert e.relements == {'a': 0, 'b': max_uint} - # 'signed int' case - e = new_enum_type("foo", ('a', 'b'), (-1, max_int)) - assert sizeof(e) == size_of_int() - assert int(cast(e, -1)) == -1 - assert e.elements == {-1: 'a', max_int: 'b'} - assert e.relements == {'a': -1, 'b': max_int} - e = new_enum_type("foo", ('a', 'b'), (-max_int-1, max_int)) - assert sizeof(e) == size_of_int() - assert int(cast(e, -1)) == -1 - assert e.elements == {-max_int-1: 'a', max_int: 'b'} - assert e.relements == {'a': -max_int-1, 'b': max_int} - # 'unsigned long' case - e = new_enum_type("foo", ('a', 'b'), (0, max_long)) - assert sizeof(e) == size_of_long() - assert int(cast(e, -1)) == max_ulong # 'e' is unsigned - e = new_enum_type("foo", ('a', 'b'), (0, max_ulong)) - assert sizeof(e) == size_of_long() - assert int(cast(e, -1)) == max_ulong - assert e.elements == {0: 'a', max_ulong: 'b'} - assert e.relements == {'a': 0, 'b': max_ulong} - # 'signed long' case - e = new_enum_type("foo", ('a', 'b'), (-1, max_long)) - assert sizeof(e) == size_of_long() - assert int(cast(e, -1)) == -1 - assert e.elements == {-1: 'a', max_long: 'b'} - assert e.relements == {'a': -1, 'b': max_long} - e = new_enum_type("foo", ('a', 'b'), (-max_long-1, max_long)) - assert sizeof(e) == size_of_long() - assert int(cast(e, -1)) == -1 - assert e.elements == {-max_long-1: 'a', max_long: 'b'} - assert e.relements == {'a': -max_long-1, 'b': max_long} - # overflow: both negative items and items larger than max_long - e = py.test.raises(OverflowError, new_enum_type, "foo", ('a', 'b'), - (-1, max_long + 1)) - assert str(e.value) == ( - "enum 'foo' values don't all fit into either 'long' " - "or 'unsigned long'") - # overflow: items smaller than -max_long-1 - e = py.test.raises(OverflowError, new_enum_type, "foo", ('a', 'b'), - (-max_long-2, 5)) - assert str(e.value) == ( - "enum 'foo' declaration for 'a' does not fit a long or unsigned long") - # overflow: items larger than max_ulong - e = py.test.raises(OverflowError, new_enum_type, "foo", ('a', 'b'), - (5, max_ulong+1)) - assert str(e.value) == ( - "enum 'foo' declaration for 'b' does not fit a long or unsigned long") + for BPrimitive in [new_primitive_type("int"), + new_primitive_type("unsigned int"), + new_primitive_type("long"), + new_primitive_type("unsigned long")]: + for x in [max_uint, max_int, max_ulong, max_long]: + for testcase in [x, x+1, -x-1, -x-2]: + if int(cast(BPrimitive, testcase)) == testcase: + # fits + BEnum = new_enum_type("foo", ("AA",), (testcase,), + BPrimitive) + assert int(cast(BEnum, testcase)) == testcase + else: + # overflows + py.test.raises(OverflowError, new_enum_type, + "foo", ("AA",), (testcase,), BPrimitive) def test_callback_returning_enum(): BInt = new_primitive_type("int") - BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, -20)) + BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, -20), BInt) def cb(n): if n & 1: return cast(BEnum, n) @@ -1410,7 +1382,8 @@ def test_callback_returning_enum_unsigned(): BInt = new_primitive_type("int") - BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, 20)) + BUInt = new_primitive_type("unsigned int") + BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, 20), BUInt) def cb(n): if n & 1: return cast(BEnum, n) diff --git a/cffi/backend_ctypes.py b/cffi/backend_ctypes.py --- a/cffi/backend_ctypes.py +++ b/cffi/backend_ctypes.py @@ -924,27 +924,10 @@ CTypesFunctionPtr._fix_class() return CTypesFunctionPtr - def new_enum_type(self, name, enumerators, enumvalues): + def new_enum_type(self, name, enumerators, enumvalues, CTypesInt): assert isinstance(name, str) reverse_mapping = dict(zip(reversed(enumvalues), reversed(enumerators))) - smallest = min(enumvalues or [0]) - largest = max(enumvalues or [0]) - if smallest < 0: - if largest == ctypes.c_int(largest).value: - tp = 'int' - elif largest == ctypes.c_long(largest).value: - tp = 'long' - else: - raise OverflowError - else: - if largest == ctypes.c_uint(largest).value: - tp = 'unsigned int' - elif largest == ctypes.c_ulong(largest).value: - tp = 'unsigned long' - else: - raise OverflowError - CTypesInt = self.ffi._get_cached_btype(model.PrimitiveType(tp)) # class CTypesEnum(CTypesInt): __slots__ = [] diff --git a/cffi/model.py b/cffi/model.py --- a/cffi/model.py +++ b/cffi/model.py @@ -356,10 +356,11 @@ partial = False partial_resolved = False - def __init__(self, name, enumerators, enumvalues): + def __init__(self, name, enumerators, enumvalues, baseinttype=None): self.name = name self.enumerators = enumerators self.enumvalues = enumvalues + self.baseinttype = baseinttype def check_not_partial(self): if self.partial and not self.partial_resolved: @@ -368,9 +369,41 @@ def build_backend_type(self, ffi, finishlist): self.check_not_partial() + base_btype = self.build_baseinttype(ffi, finishlist) return global_cache(self, ffi, 'new_enum_type', self.name, - self.enumerators, self.enumvalues, key=self) + self.enumerators, self.enumvalues, + base_btype, key=self) + def build_baseinttype(self, ffi, finishlist): + if self.baseinttype is not None: + return self.baseinttype.get_cached_btype(ffi, finishlist) + # + if self.enumvalues: + smallest_value = min(self.enumvalues) + largest_value = max(self.enumvalues) + else: + smallest_value = 0 + largest_value = 0 + if smallest_value < 0: # needs a signed type + sign = 1 + candidate1 = PrimitiveType("int") + candidate2 = PrimitiveType("long") + else: + sign = 0 + candidate1 = PrimitiveType("unsigned int") + candidate2 = PrimitiveType("unsigned long") + btype1 = candidate1.get_cached_btype(ffi, finishlist) + btype2 = candidate2.get_cached_btype(ffi, finishlist) + size1 = ffi.sizeof(btype1) + size2 = ffi.sizeof(btype2) + if (smallest_value >= ((-1) << (8*size1-1)) and + largest_value < (1 << (8*size1-sign))): + return btype1 + if (smallest_value >= ((-1) << (8*size2-1)) and + largest_value < (1 << (8*size2-sign))): + return btype2 + raise api.CDefError("%s values don't all fit into either 'long' " + "or 'unsigned long'" % self._get_c_name('')) def unknown_type(name, structname=None): if structname is None: diff --git a/doc/source/index.rst b/doc/source/index.rst --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -1216,7 +1216,10 @@ Enum types follow the GCC rules: they are defined as the first of ``unsigned int``, ``int``, ``unsigned long`` or ``long`` that fits all numeric values. Note that the first choice is unsigned. In CFFI - 0.5 and before, it was always ``int``. + 0.5 and before, it was always ``int``. *Unimplemented: if the very + large values are not declared, the enum size will be incorrectly + deduced! Work around this by making sure that you name the largest + value and/or any negative value in the cdef.* Debugging dlopen'ed C libraries diff --git a/testing/test_verify.py b/testing/test_verify.py --- a/testing/test_verify.py +++ b/testing/test_verify.py @@ -1442,6 +1442,35 @@ res = lib2.myfunc(lib2.AA) assert res == 2 +def test_enum_size(): + cases = [('123', 4, 4294967295), + ('4294967295U', 4, 4294967295), + ('-123', 4, -1), + ('-2147483647-1', 4, -1), + ] + if FFI().sizeof("long") == 8: + cases += [('4294967296L', 8, 2**64-1), + ('%dUL' % (2**64-1), 8, 2**64-1), + ('-2147483649L', 8, -1), + ('%dL-1L' % (1-2**63), 8, -1)] + for hidden_value, expected_size, expected_minus1 in cases: + ffi = FFI() + ffi.cdef("enum foo_e { AA, BB, ... };") + lib = ffi.verify("enum foo_e { AA, BB=%s };" % hidden_value) + assert lib.AA == 0 + assert lib.BB == eval(hidden_value.replace('U', '').replace('L', '')) + assert ffi.sizeof("enum foo_e") == expected_size + assert int(ffi.cast("enum foo_e", -1)) == expected_minus1 + # test with the large value hidden: + # disabled so far, doesn't work +## for hidden_value, expected_size, expected_minus1 in cases: +## ffi = FFI() +## ffi.cdef("enum foo_e { AA, BB, ... };") +## lib = ffi.verify("enum foo_e { AA, BB=%s };" % hidden_value) +## assert lib.AA == 0 +## assert ffi.sizeof("enum foo_e") == expected_size +## assert int(ffi.cast("enum foo_e", -1)) == expected_minus1 + def test_string_to_voidp_arg(): ffi = FFI() ffi.cdef("int myfunc(void *);") From noreply at buildbot.pypy.org Sat Feb 16 10:29:22 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sat, 16 Feb 2013 10:29:22 +0100 (CET) Subject: [pypy-commit] pypy default: Update to cffi/70927696eb9c Message-ID: <20130216092922.AE0DF1C0CA3@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r61308:c44d9205dbb4 Date: 2013-02-16 10:29 +0100 http://bitbucket.org/pypy/pypy/changeset/c44d9205dbb4/ Log: Update to cffi/70927696eb9c diff --git a/pypy/module/_cffi_backend/newtype.py b/pypy/module/_cffi_backend/newtype.py --- a/pypy/module/_cffi_backend/newtype.py +++ b/pypy/module/_cffi_backend/newtype.py @@ -264,8 +264,8 @@ # ____________________________________________________________ - at unwrap_spec(name=str) -def new_enum_type(space, name, w_enumerators, w_enumvalues): + at unwrap_spec(name=str, basectype=ctypeobj.W_CType) +def new_enum_type(space, name, w_enumerators, w_enumvalues, basectype): enumerators_w = space.fixedview(w_enumerators) enumvalues_w = space.fixedview(w_enumvalues) if len(enumerators_w) != len(enumvalues_w): @@ -273,53 +273,26 @@ space.wrap("tuple args must have the same size")) enumerators = [space.str_w(w) for w in enumerators_w] # - smallest_value = 0 - largest_value = r_uint(0) - i = 0 + if (not isinstance(basectype, ctypeprim.W_CTypePrimitiveSigned) and + not isinstance(basectype, ctypeprim.W_CTypePrimitiveUnsigned)): + raise OperationError(space.w_TypeError, + space.wrap("expected a primitive signed or unsigned base type")) + # + lvalue = lltype.malloc(rffi.CCHARP.TO, basectype.size, flavor='raw') try: for w in enumvalues_w: - try: - ulvalue = space.uint_w(w) - except OperationError, e: - if not e.match(space, space.w_ValueError): - raise - lvalue = space.int_w(w) - if lvalue < smallest_value: - smallest_value = lvalue - else: - if ulvalue > largest_value: - largest_value = ulvalue - i += 1 # 'i' is here for the exception case, see below - except OperationError, e: - if not e.match(space, space.w_OverflowError): - raise - raise operationerrfmt(space.w_OverflowError, - "enum '%s' declaration for '%s' does not fit " - "a long or unsigned long", - name, enumerators[i]) + # detects out-of-range or badly typed values + basectype.convert_from_object(lvalue, w) + finally: + lltype.free(lvalue, flavor='raw') # - if smallest_value < 0: - if (smallest_value >= intmask(most_neg_value_of(rffi.INT)) and - largest_value <= r_uint(most_pos_value_of(rffi.INT))): - size = rffi.sizeof(rffi.INT) - align = alignment(rffi.INT) - elif largest_value <= r_uint(most_pos_value_of(rffi.LONG)): - size = rffi.sizeof(rffi.LONG) - align = alignment(rffi.LONG) - else: - raise operationerrfmt(space.w_OverflowError, - "enum '%s' values don't all fit into either 'long' " - "or 'unsigned long'", name) + size = basectype.size + align = basectype.align + if isinstance(basectype, ctypeprim.W_CTypePrimitiveSigned): enumvalues = [space.int_w(w) for w in enumvalues_w] ctype = ctypeenum.W_CTypeEnumSigned(space, name, size, align, enumerators, enumvalues) else: - if largest_value <= r_uint(most_pos_value_of(rffi.UINT)): - size = rffi.sizeof(rffi.UINT) - align = alignment(rffi.UINT) - else: - size = rffi.sizeof(rffi.ULONG) - align = alignment(rffi.ULONG) enumvalues = [space.uint_w(w) for w in enumvalues_w] ctype = ctypeenum.W_CTypeEnumUnsigned(space, name, size, align, enumerators, enumvalues) diff --git a/pypy/module/_cffi_backend/test/_backend_test_c.py b/pypy/module/_cffi_backend/test/_backend_test_c.py --- a/pypy/module/_cffi_backend/test/_backend_test_c.py +++ b/pypy/module/_cffi_backend/test/_backend_test_c.py @@ -1264,25 +1264,29 @@ py.test.raises(TypeError, callback, BFunc, cb, -42) def test_enum_type(): - BEnum = new_enum_type("foo", (), ()) + BUInt = new_primitive_type("unsigned int") + BEnum = new_enum_type("foo", (), (), BUInt) assert repr(BEnum) == "" assert BEnum.kind == "enum" assert BEnum.cname == "enum foo" assert BEnum.elements == {} # - BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, -20)) + BInt = new_primitive_type("int") + BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, -20), BInt) assert BEnum.kind == "enum" assert BEnum.elements == {-20: 'ab', 0: 'def', 1: 'c'} # 'elements' is not the real dict, but merely a copy BEnum.elements[2] = '??' assert BEnum.elements == {-20: 'ab', 0: 'def', 1: 'c'} # - BEnum = new_enum_type("bar", ('ab', 'cd'), (5, 5)) + BEnum = new_enum_type("bar", ('ab', 'cd'), (5, 5), BUInt) assert BEnum.elements == {5: 'ab'} assert BEnum.relements == {'ab': 5, 'cd': 5} def test_cast_to_enum(): - BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, -20)) + BInt = new_primitive_type("int") + BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, -20), BInt) + assert sizeof(BEnum) == sizeof(BInt) e = cast(BEnum, 0) assert repr(e) == "" assert repr(cast(BEnum, -42)) == "" @@ -1294,18 +1298,27 @@ assert int(cast(BEnum, -242 + 2**128)) == -242 assert string(cast(BEnum, -242 + 2**128)) == '-242' # - BEnum = new_enum_type("bar", ('def', 'c', 'ab'), (0, 1, 20)) + BUInt = new_primitive_type("unsigned int") + BEnum = new_enum_type("bar", ('def', 'c', 'ab'), (0, 1, 20), BUInt) e = cast(BEnum, -1) assert repr(e) == "" # unsigned int + # + BLong = new_primitive_type("long") + BEnum = new_enum_type("baz", (), (), BLong) + assert sizeof(BEnum) == sizeof(BLong) + e = cast(BEnum, -1) + assert repr(e) == "" def test_enum_with_non_injective_mapping(): - BEnum = new_enum_type("foo", ('ab', 'cd'), (7, 7)) + BInt = new_primitive_type("int") + BEnum = new_enum_type("foo", ('ab', 'cd'), (7, 7), BInt) e = cast(BEnum, 7) assert repr(e) == "" assert string(e) == 'ab' def test_enum_in_struct(): - BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, -20)) + BInt = new_primitive_type("int") + BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, -20), BInt) BStruct = new_struct_type("bar") BStructPtr = new_pointer_type(BStruct) complete_struct_or_union(BStruct, [('a1', BEnum, -1)]) @@ -1318,7 +1331,7 @@ "unsupported operand type for int(): 'NoneType'" in str(e.value)) #PyPy py.test.raises(TypeError, 'p.a1 = "def"') if sys.version_info < (3,): - BEnum2 = new_enum_type(unicode("foo"), (unicode('abc'),), (5,)) + BEnum2 = new_enum_type(unicode("foo"), (unicode('abc'),), (5,), BInt) assert string(cast(BEnum2, 5)) == 'abc' assert type(string(cast(BEnum2, 5))) is str @@ -1327,66 +1340,25 @@ max_int = max_uint // 2 max_ulong = 2 ** (size_of_long()*8) - 1 max_long = max_ulong // 2 - # 'unsigned int' case - e = new_enum_type("foo", ('a', 'b'), (0, 3)) - assert sizeof(e) == size_of_int() - assert int(cast(e, -1)) == max_uint # 'e' is unsigned - e = new_enum_type("foo", ('a', 'b'), (0, max_uint)) - assert sizeof(e) == size_of_int() - assert int(cast(e, -1)) == max_uint - assert e.elements == {0: 'a', max_uint: 'b'} - assert e.relements == {'a': 0, 'b': max_uint} - # 'signed int' case - e = new_enum_type("foo", ('a', 'b'), (-1, max_int)) - assert sizeof(e) == size_of_int() - assert int(cast(e, -1)) == -1 - assert e.elements == {-1: 'a', max_int: 'b'} - assert e.relements == {'a': -1, 'b': max_int} - e = new_enum_type("foo", ('a', 'b'), (-max_int-1, max_int)) - assert sizeof(e) == size_of_int() - assert int(cast(e, -1)) == -1 - assert e.elements == {-max_int-1: 'a', max_int: 'b'} - assert e.relements == {'a': -max_int-1, 'b': max_int} - # 'unsigned long' case - e = new_enum_type("foo", ('a', 'b'), (0, max_long)) - assert sizeof(e) == size_of_long() - assert int(cast(e, -1)) == max_ulong # 'e' is unsigned - e = new_enum_type("foo", ('a', 'b'), (0, max_ulong)) - assert sizeof(e) == size_of_long() - assert int(cast(e, -1)) == max_ulong - assert e.elements == {0: 'a', max_ulong: 'b'} - assert e.relements == {'a': 0, 'b': max_ulong} - # 'signed long' case - e = new_enum_type("foo", ('a', 'b'), (-1, max_long)) - assert sizeof(e) == size_of_long() - assert int(cast(e, -1)) == -1 - assert e.elements == {-1: 'a', max_long: 'b'} - assert e.relements == {'a': -1, 'b': max_long} - e = new_enum_type("foo", ('a', 'b'), (-max_long-1, max_long)) - assert sizeof(e) == size_of_long() - assert int(cast(e, -1)) == -1 - assert e.elements == {-max_long-1: 'a', max_long: 'b'} - assert e.relements == {'a': -max_long-1, 'b': max_long} - # overflow: both negative items and items larger than max_long - e = py.test.raises(OverflowError, new_enum_type, "foo", ('a', 'b'), - (-1, max_long + 1)) - assert str(e.value) == ( - "enum 'foo' values don't all fit into either 'long' " - "or 'unsigned long'") - # overflow: items smaller than -max_long-1 - e = py.test.raises(OverflowError, new_enum_type, "foo", ('a', 'b'), - (-max_long-2, 5)) - assert str(e.value) == ( - "enum 'foo' declaration for 'a' does not fit a long or unsigned long") - # overflow: items larger than max_ulong - e = py.test.raises(OverflowError, new_enum_type, "foo", ('a', 'b'), - (5, max_ulong+1)) - assert str(e.value) == ( - "enum 'foo' declaration for 'b' does not fit a long or unsigned long") + for BPrimitive in [new_primitive_type("int"), + new_primitive_type("unsigned int"), + new_primitive_type("long"), + new_primitive_type("unsigned long")]: + for x in [max_uint, max_int, max_ulong, max_long]: + for testcase in [x, x+1, -x-1, -x-2]: + if int(cast(BPrimitive, testcase)) == testcase: + # fits + BEnum = new_enum_type("foo", ("AA",), (testcase,), + BPrimitive) + assert int(cast(BEnum, testcase)) == testcase + else: + # overflows + py.test.raises(OverflowError, new_enum_type, + "foo", ("AA",), (testcase,), BPrimitive) def test_callback_returning_enum(): BInt = new_primitive_type("int") - BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, -20)) + BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, -20), BInt) def cb(n): if n & 1: return cast(BEnum, n) @@ -1402,7 +1374,8 @@ def test_callback_returning_enum_unsigned(): BInt = new_primitive_type("int") - BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, 20)) + BUInt = new_primitive_type("unsigned int") + BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, 20), BUInt) def cb(n): if n & 1: return cast(BEnum, n) From noreply at buildbot.pypy.org Sat Feb 16 10:31:36 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sat, 16 Feb 2013 10:31:36 +0100 (CET) Subject: [pypy-commit] pypy default: try to clean up more on fork Message-ID: <20130216093136.4FE831C0CA3@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61309:8f52d162f0ee Date: 2013-02-16 04:27 -0500 http://bitbucket.org/pypy/pypy/changeset/8f52d162f0ee/ Log: try to clean up more on fork diff --git a/pypy/module/thread/threadlocals.py b/pypy/module/thread/threadlocals.py --- a/pypy/module/thread/threadlocals.py +++ b/pypy/module/thread/threadlocals.py @@ -85,9 +85,11 @@ # enable_signals() if necessary. That's a hack but I cannot # figure out a non-hackish way to handle thread+signal+fork :-( ident = rthread.get_ident() - old = self._signalsenabled.get(ident, 0) - if ident is not self._mainthreadident: - self._mainthreadident = ident - old += 1 - self._signalsenabled.clear() - self._signalsenabled[ident] = old + val = self.getvalue() + sig = self._signalsenabled.get(ident, 0) + if ident != self._mainthreadident: + sig += 1 + self._cleanup_() + self.setvalue(val) + self._signalsenabled[ident] = sig + self._mainthreadident = ident From noreply at buildbot.pypy.org Sat Feb 16 10:31:37 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sat, 16 Feb 2013 10:31:37 +0100 (CET) Subject: [pypy-commit] pypy default: mark these unroll safe also Message-ID: <20130216093137.9D99D1C0CA3@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61310:06d109391705 Date: 2013-02-16 04:28 -0500 http://bitbucket.org/pypy/pypy/changeset/06d109391705/ Log: mark these unroll safe also diff --git a/rpython/rlib/rstruct/ieee.py b/rpython/rlib/rstruct/ieee.py --- a/rpython/rlib/rstruct/ieee.py +++ b/rpython/rlib/rstruct/ieee.py @@ -255,6 +255,7 @@ l.reverse() result.append("".join(l)) + at jit.unroll_safe def unpack_float(s, be): unsigned = r_ulonglong(0) for i in range(min(len(s), 8)): @@ -262,6 +263,7 @@ unsigned |= r_ulonglong(c) << (i * 8) return float_unpack(unsigned, len(s)) + at jit.unroll_safe def unpack_float80(s, be): QQ = [r_ulonglong(0), r_ulonglong(0)] for i in range(8): From noreply at buildbot.pypy.org Sat Feb 16 10:48:45 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sat, 16 Feb 2013 10:48:45 +0100 (CET) Subject: [pypy-commit] pypy default: wrap the exception in signals_exit Message-ID: <20130216094845.03FED1C0F4B@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61311:46b70943f54b Date: 2013-02-16 04:28 -0500 http://bitbucket.org/pypy/pypy/changeset/46b70943f54b/ Log: wrap the exception in signals_exit diff --git a/pypy/interpreter/miscutils.py b/pypy/interpreter/miscutils.py --- a/pypy/interpreter/miscutils.py +++ b/pypy/interpreter/miscutils.py @@ -20,10 +20,10 @@ def signals_enabled(self): return True - def enable_signals(self): + def enable_signals(self, space): pass - def disable_signals(self): + def disable_signals(self, space): pass def getallvalues(self): diff --git a/pypy/module/__pypy__/interp_signal.py b/pypy/module/__pypy__/interp_signal.py --- a/pypy/module/__pypy__/interp_signal.py +++ b/pypy/module/__pypy__/interp_signal.py @@ -1,6 +1,6 @@ def signals_enter(space): - space.threadlocals.enable_signals() + space.threadlocals.enable_signals(space) def signals_exit(space, w_ignored1=None, w_ignored2=None, w_ignored3=None): - space.threadlocals.disable_signals() + space.threadlocals.disable_signals(space) diff --git a/pypy/module/__pypy__/test/test_signal.py b/pypy/module/__pypy__/test/test_signal.py --- a/pypy/module/__pypy__/test/test_signal.py +++ b/pypy/module/__pypy__/test/test_signal.py @@ -3,18 +3,6 @@ from pypy.module.thread.test.support import GenericTestThread -class TestThreadSignal: - spaceconfig = dict(usemodules=['__pypy__', 'thread']) - - def test_exit_twice(self, space): - from pypy.module.__pypy__.interp_signal import signals_exit, signals_enter - signals_exit(space) - try: - raises(KeyError, signals_exit, space) - finally: - signals_enter(space) - - class AppTestMinimal: spaceconfig = dict(usemodules=['__pypy__']) @@ -28,6 +16,14 @@ class AppTestThreadSignal(GenericTestThread): spaceconfig = dict(usemodules=['__pypy__', 'thread', 'signal', 'time']) + def test_exit_twice(self): + from __pypy__ import thread + thread._signals_exit() + try: + raises(KeyError, thread._signals_exit) + finally: + thread._signals_enter() + def test_enable_signals(self): import __pypy__, thread, signal, time diff --git a/pypy/module/thread/threadlocals.py b/pypy/module/thread/threadlocals.py --- a/pypy/module/thread/threadlocals.py +++ b/pypy/module/thread/threadlocals.py @@ -1,4 +1,5 @@ from rpython.rlib import rthread +from pypy.interpreter.error import OperationError class OSThreadLocals: @@ -54,14 +55,18 @@ def signals_enabled(self): return rthread.get_ident() in self._signalsenabled - def enable_signals(self): + def enable_signals(self, space): ident = rthread.get_ident() old = self._signalsenabled.get(ident, 0) self._signalsenabled[ident] = old + 1 - def disable_signals(self): + def disable_signals(self, space): ident = rthread.get_ident() - new = self._signalsenabled[ident] - 1 + try: + new = self._signalsenabled[ident] - 1 + except KeyError: + raise OperationError(space.w_KeyError, space.wrap( + "cannot disable signals in thread not enabled for signals")) if new > 0: self._signalsenabled[ident] = new else: From noreply at buildbot.pypy.org Sat Feb 16 10:54:58 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sat, 16 Feb 2013 10:54:58 +0100 (CET) Subject: [pypy-commit] pypy stm-thread-2: Move thread.atomic to __pypy__.thread.atomic. Message-ID: <20130216095458.C3DB91C11B7@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stm-thread-2 Changeset: r61312:43ffd21dc40e Date: 2013-02-16 10:54 +0100 http://bitbucket.org/pypy/pypy/changeset/43ffd21dc40e/ Log: Move thread.atomic to __pypy__.thread.atomic. diff --git a/pypy/module/__pypy__/__init__.py b/pypy/module/__pypy__/__init__.py --- a/pypy/module/__pypy__/__init__.py +++ b/pypy/module/__pypy__/__init__.py @@ -29,10 +29,16 @@ class ThreadModule(MixedModule): appleveldefs = { 'signals_enabled': 'app_signal.signals_enabled', + 'atomic': 'app_atomic.atomic', + 'exclusive_atomic': 'app_atomic.exclusive_atomic', + 'error': 'app_atomic.error', } interpleveldefs = { '_signals_enter': 'interp_signal.signals_enter', '_signals_exit': 'interp_signal.signals_exit', + '_atomic_enter': 'interp_atomic.atomic_enter', + '_exclusive_atomic_enter': 'interp_atomic.exclusive_atomic_enter', + '_atomic_exit': 'interp_atomic.atomic_exit', } diff --git a/pypy/module/thread/app_atomic.py b/pypy/module/__pypy__/app_atomic.py rename from pypy/module/thread/app_atomic.py rename to pypy/module/__pypy__/app_atomic.py --- a/pypy/module/thread/app_atomic.py +++ b/pypy/module/__pypy__/app_atomic.py @@ -1,4 +1,5 @@ -import thread +from thread import error # re-exported +from __pypy__ import thread class Atomic(object): __enter__ = thread._atomic_enter diff --git a/pypy/module/thread/atomic.py b/pypy/module/__pypy__/interp_atomic.py rename from pypy/module/thread/atomic.py rename to pypy/module/__pypy__/interp_atomic.py diff --git a/pypy/module/thread/test/test_atomic.py b/pypy/module/__pypy__/test/test_atomic.py rename from pypy/module/thread/test/test_atomic.py rename to pypy/module/__pypy__/test/test_atomic.py --- a/pypy/module/thread/test/test_atomic.py +++ b/pypy/module/__pypy__/test/test_atomic.py @@ -5,7 +5,7 @@ class AppTestAtomic(GenericTestThread): def test_simple(self): - import thread + from __pypy__ import thread for atomic in thread.atomic, thread.exclusive_atomic: with atomic: pass @@ -16,20 +16,20 @@ pass def test_nest_composable_atomic(self): - import thread + from __pypy__ import thread with thread.atomic: with thread.atomic: pass def test_nest_composable_below_exclusive(self): - import thread + from __pypy__ import thread with thread.exclusive_atomic: with thread.atomic: with thread.atomic: pass def test_nest_exclusive_fails(self): - import thread + from __pypy__ import thread try: with thread.exclusive_atomic: with thread.exclusive_atomic: @@ -38,7 +38,7 @@ assert e.message == "exclusive_atomic block can't be entered inside another atomic block" def test_nest_exclusive_fails2(self): - import thread + from __pypy__ import thread try: with thread.atomic: with thread.exclusive_atomic: diff --git a/pypy/module/thread/__init__.py b/pypy/module/thread/__init__.py --- a/pypy/module/thread/__init__.py +++ b/pypy/module/thread/__init__.py @@ -4,8 +4,6 @@ class Module(MixedModule): appleveldefs = { - 'atomic': 'app_atomic.atomic', - 'exclusive_atomic': 'app_atomic.exclusive_atomic', } interpleveldefs = { @@ -22,9 +20,6 @@ 'LockType': 'os_lock.Lock', '_local': 'os_local.Local', 'error': 'space.fromcache(error.Cache).w_error', - '_atomic_enter': 'atomic.atomic_enter', - '_exclusive_atomic_enter': 'atomic.exclusive_atomic_enter', - '_atomic_exit': 'atomic.atomic_exit', } def __init__(self, space, *args): From noreply at buildbot.pypy.org Sat Feb 16 10:55:00 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sat, 16 Feb 2013 10:55:00 +0100 (CET) Subject: [pypy-commit] pypy stm-thread-2: Fix this import. Message-ID: <20130216095500.247501C11B7@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stm-thread-2 Changeset: r61313:e1fb39f86281 Date: 2013-02-16 10:55 +0100 http://bitbucket.org/pypy/pypy/changeset/e1fb39f86281/ Log: Fix this import. diff --git a/lib_pypy/transaction.py b/lib_pypy/transaction.py --- a/lib_pypy/transaction.py +++ b/lib_pypy/transaction.py @@ -15,7 +15,7 @@ import sys, thread, collections try: - from thread import atomic + from __pypy__.thread import atomic except ImportError: # Not a STM-enabled PyPy. We can still provide a version of 'atomic' # that is good enough for our purposes. With this limited version, From noreply at buildbot.pypy.org Sat Feb 16 11:56:57 2013 From: noreply at buildbot.pypy.org (fijal) Date: Sat, 16 Feb 2013 11:56:57 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: make viewcode here support ARM Message-ID: <20130216105657.EA38F1C062C@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61314:ea07028f1133 Date: 2013-02-16 12:21 +0200 http://bitbucket.org/pypy/pypy/changeset/ea07028f1133/ Log: make viewcode here support ARM diff --git a/rpython/jit/backend/x86/tool/viewcode.py b/rpython/jit/backend/x86/tool/viewcode.py --- a/rpython/jit/backend/x86/tool/viewcode.py +++ b/rpython/jit/backend/x86/tool/viewcode.py @@ -53,9 +53,10 @@ 'x86_32': 'i386', 'x86_64': 'x86-64', 'i386': 'i386', + 'arm': 'arm', } cmd = find_objdump() - objdump = ('%(command)s -M %(backend)s -b binary -m i386 ' + objdump = ('%(command)s -M %(backend)s -b binary -m %(machine)s ' '--disassembler-options=intel-mnemonics ' '--adjust-vma=%(origin)d -D %(file)s') # @@ -67,6 +68,7 @@ 'file': tmpfile, 'origin': originaddr, 'backend': objdump_backend_option[backend_name], + 'machine': 'i386' if backend_name != 'arm' else 'arm', }, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = p.communicate() assert not p.returncode, ('Encountered an error running objdump: %s' % From noreply at buildbot.pypy.org Sat Feb 16 11:56:59 2013 From: noreply at buildbot.pypy.org (fijal) Date: Sat, 16 Feb 2013 11:56:59 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: merge Message-ID: <20130216105659.585EA1C0673@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61315:3cab31c2fdbd Date: 2013-02-16 12:56 +0200 http://bitbucket.org/pypy/pypy/changeset/3cab31c2fdbd/ Log: merge diff --git a/rpython/jit/backend/arm/opassembler.py b/rpython/jit/backend/arm/opassembler.py --- a/rpython/jit/backend/arm/opassembler.py +++ b/rpython/jit/backend/arm/opassembler.py @@ -349,8 +349,8 @@ fcond, resloc, (size, signed)) return cond - def _emit_call(self, adr, arglocs, fcond=c.AL, - resloc=None, result_info=(-1, -1)): + def _emit_call(self, adr, arglocs, fcond=c.AL, resloc=None, + result_info=(-1, -1)): if self.cpu.use_hf_abi: stack_args, adr = self._setup_call_hf(adr, arglocs, fcond, resloc, result_info) @@ -1102,28 +1102,37 @@ def imm(self, v): return imm(v) - + def emit_guard_call_assembler(self, op, guard_op, arglocs, regalloc, fcond): if len(arglocs) == 4: - [frame_loc, argloc, vloc, tmploc] = arglocs + [argloc, vloc, result_loc, tmploc] = arglocs else: - [frame_loc, argloc, tmploc] = arglocs + [argloc, result_loc, tmploc] = arglocs vloc = imm(0) - self.call_assembler(op, guard_op, frame_loc, argloc, vloc, tmploc) - xxx + self.call_assembler(op, guard_op, argloc, vloc, result_loc, tmploc) + self._emit_guard_may_force(guard_op, + regalloc._prepare_guard(guard_op), guard_op.numargs()) + return fcond + + def _call_assembler_emit_call(self, addr, argloc, resloc): + self._emit_call(addr, [argloc], resloc=resloc) + + def _call_assembler_emit_helper_call(self, addr, arglocs, resloc): + self._emit_call(addr, arglocs, resloc=resloc) def _call_assembler_check_descr(self, value, tmploc): ofs = self.cpu.get_ofs_of_frame_field('jf_descr') self.mc.LDR_ri(r.ip.value, tmploc.value, imm=ofs) self.mc.CMP_ri(r.ip.value, imm=value) pos = self.mc.currpos() - self.mc.BPKT() + self.mc.BKPT() return pos def _call_assembler_patch_je(self, result_loc, jmp_location): pos = self.mc.currpos() - self.mc.BPKT() + self.mc.BKPT() + # pmc = OverwritingBuilder(self.mc, jmp_location, WORD) pmc.B_offs(self.mc.currpos(), c.EQ) return pos @@ -1146,71 +1155,31 @@ if kind == FLOAT: ofs = self.cpu.unpack_arraydescr(descr) assert check_imm_arg(ofs) - assert result_loc.is_reg() + assert result_loc.is_vfp_reg() # we always have a register here, since we have to sync them # before call_assembler - self.mc.VLDR(result_loc.value, xxx) - if not check_imm_arg(t): - self.mc.gen_load_int(r.ip.value, t, cond=fast_path_cond) - self.mc.ADD_rr(r.ip.value, r.r0.value, r.ip.value, - cond=fast_path_cond) - t = 0 + if not check_imm_arg(ofs): + self.mc.gen_load_int(r.ip.value, ofs) + self.mc.ADD_rr(r.ip.value, r.r0.value, r.ip.value) + ofs = 0 base = r.ip else: base = r.r0 - self.mc.VLDR(resloc.value, base.value, imm=t, - cond=fast_path_cond) + self.mc.VLDR(result_loc.value, base.value, imm=ofs) else: - assert resloc is r.r0 - if kind == INT: - t = unpack_interiorfielddescr(descrs.as_int)[0] + assert result_loc is r.r0 + ofs = self.cpu.unpack_arraydescr(descr) + if not check_imm_arg(ofs): + self.mc.gen_load_int(r.ip.value, ofs) + self.mc.LDR_rr(result_loc.value, result_loc.value, r.ip.value) else: - t = unpack_interiorfielddescr(descrs.as_ref)[0] - if not check_imm_arg(t): - self.mc.gen_load_int(r.ip.value, t, cond=fast_path_cond) - self.mc.LDR_rr(resloc.value, resloc.value, r.ip.value, - cond=fast_path_cond) - else: - self.mc.LDR_ri(resloc.value, resloc.value, imm=t, - cond=fast_path_cond) - # jump to merge point - jmp_pos = self.mc.currpos() - self.mc.BKPT() + self.mc.LDR_ri(result_loc.value, result_loc.value, imm=ofs) - # Path B: use assembler helper - asm_helper_adr = self.cpu.cast_adr_to_int(jd.assembler_helper_adr) - if self.cpu.supports_floats: - floats = r.caller_vfp_resp - else: - floats = [] - # in case the call has a result we do not need to save the - # corresponding result register because it was already allocated for - # the result - core = r.caller_resp - if op.result: - if resloc.is_vfp_reg(): - floats = r.caller_vfp_resp[1:] - else: - core = r.caller_resp[1:] + [r.ip] # keep alignment - with saved_registers(self.mc, core, floats): - # result of previous call is in r0 - self.mov_loc_loc(arglocs[0], r.r1) - self.mc.BL(asm_helper_adr) - if not self.cpu.use_hf_abi and op.result and resloc.is_vfp_reg(): - # move result to the allocated register - self.mov_to_vfp_loc(r.r0, r.r1, resloc) - + def _call_assembler_patch_jmp(self, jmp_location): # merge point currpos = self.mc.currpos() - pmc = OverwritingBuilder(self.mc, jmp_pos, WORD) - pmc.B_offs(currpos, fast_path_cond) - - self.mc.LDR_ri(r.ip.value, r.fp.value) - self.mc.CMP_ri(r.ip.value, 0) - - self._emit_guard(guard_op, regalloc._prepare_guard(guard_op), - c.GE, save_exc=True) - return fcond + pmc = OverwritingBuilder(self.mc, jmp_location, WORD) + pmc.B_offs(currpos) # ../x86/assembler.py:668 def redirect_call_assembler(self, oldlooptoken, newlooptoken): @@ -1243,14 +1212,14 @@ # self._emit_call(adr, callargs, fcond, resloc, (size, signed)) - self._emit_guard_may_force(guard_op, arglocs, numargs) + self._emit_guard_may_force(guard_op, arglocs[1 + numargs:], numargs) return fcond def _emit_guard_may_force(self, guard_op, arglocs, numargs): ofs = self.cpu.get_ofs_of_frame_field('jf_descr') self.mc.LDR_ri(r.ip.value, r.fp.value, imm=ofs) self.mc.CMP_ri(r.ip.value, 0) - self._emit_guard(guard_op, arglocs[1 + numargs:], c.EQ, + self._emit_guard(guard_op, arglocs, c.EQ, save_exc=True, is_guard_not_forced=True) def emit_guard_call_release_gil(self, op, guard_op, arglocs, regalloc, diff --git a/rpython/jit/backend/arm/regalloc.py b/rpython/jit/backend/arm/regalloc.py --- a/rpython/jit/backend/arm/regalloc.py +++ b/rpython/jit/backend/arm/regalloc.py @@ -1101,11 +1101,11 @@ prepare_guard_call_release_gil = prepare_guard_call_may_force def prepare_guard_call_assembler(self, op, guard_op, fcond): - self._prepare_call(op, save_all_regs=True) + locs = self.locs_for_call_assembler(op, guard_op) tmploc = self.get_scratch_reg(INT, selected_reg=r.r0) - locs = self.locs_for_call_assembler(op, guard_op) + call_locs = self._prepare_call(op, save_all_regs=True) self.possibly_free_vars(guard_op.getfailargs()) - return locs + [tmploc] + return locs + [call_locs[0], tmploc] def _prepare_args_for_new_op(self, new_args): gc_ll_descr = self.cpu.gc_ll_descr diff --git a/rpython/jit/backend/llsupport/assembler.py b/rpython/jit/backend/llsupport/assembler.py --- a/rpython/jit/backend/llsupport/assembler.py +++ b/rpython/jit/backend/llsupport/assembler.py @@ -147,8 +147,7 @@ guardtok.faildescr.rd_loop_token = self.current_clt return fail_descr, target - def call_assembler(self, op, guard_op, argloc, - vloc, result_loc, tmploc): + def call_assembler(self, op, guard_op, argloc, vloc, result_loc, tmploc): self._store_force_index(guard_op) descr = op.getdescr() assert isinstance(descr, JitCellToken) @@ -157,8 +156,9 @@ # we need to allocate the frame, keep in sync with runner's # execute_token jd = descr.outermost_jitdriver_sd - self._emit_call(self.imm(descr._ll_function_addr), - [argloc], 0, tmp=tmploc) + self._call_assembler_emit_call(self.imm(descr._ll_function_addr), + argloc, tmploc) + if op.result is None: assert result_loc is None value = self.cpu.done_with_this_frame_descr_void @@ -184,8 +184,8 @@ assert jd is not None asm_helper_adr = self.cpu.cast_adr_to_int(jd.assembler_helper_adr) - self._emit_call(self.imm(asm_helper_adr), - [tmploc, vloc], 0, tmp=self._second_tmp_reg) + self._call_assembler_emit_helper_call(self.imm(asm_helper_adr), + [tmploc, vloc], result_loc) jmp_location = self._call_assembler_patch_je(result_loc, je_location) diff --git a/rpython/jit/backend/llsupport/regalloc.py b/rpython/jit/backend/llsupport/regalloc.py --- a/rpython/jit/backend/llsupport/regalloc.py +++ b/rpython/jit/backend/llsupport/regalloc.py @@ -670,12 +670,11 @@ def locs_for_call_assembler(self, op, guard_op): descr = op.getdescr() assert isinstance(descr, JitCellToken) - arglist = op.getarglist() - if len(arglist) == 2: - self.rm._sync_var(arglist[1]) - return [self.loc(arglist[0]), self.fm.loc(arglist[1])] + if op.numargs() == 2: + self.rm._sync_var(op.getarg(1)) + return [self.loc(op.getarg(0)), self.fm.loc(op.getarg(1))] else: - return [self.loc(arglist[0])] + return [self.loc(op.getarg(0))] def compute_vars_longevity(inputargs, operations): diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -2173,7 +2173,7 @@ def genop_guard_call_assembler(self, op, guard_op, guard_token, arglocs, result_loc): - if len(arglocs) == 3: + if len(arglocs) == 2: [argloc, vloc] = arglocs else: [argloc] = arglocs @@ -2181,6 +2181,12 @@ self.call_assembler(op, guard_op, argloc, vloc, result_loc, eax) self._emit_guard_not_forced(guard_token) + def _call_assembler_emit_call(self, addr, argloc, tmploc): + self._emit_call(addr, [argloc], 0, tmp=tmploc) + + def _call_assembler_emit_helper_call(self, addr, arglocs, _): + self._emit_call(addr, arglocs, 0, tmp=self._second_tmp_reg) + def _call_assembler_check_descr(self, value, tmploc): ofs = self.cpu.get_ofs_of_frame_field('jf_descr') self.mc.CMP_mi((eax.value, ofs), value) @@ -2213,15 +2219,14 @@ if op.result is not None: # load the return value from the dead frame's value index 0 kind = op.result.type + descr = self.cpu.getarraydescr_for_frame(kind) if kind == FLOAT: - descr = self.cpu.getarraydescr_for_frame(kind) ofs = self.cpu.unpack_arraydescr(descr) self.mc.MOVSD_xm(xmm0.value, (eax.value, ofs)) if result_loc is not xmm0: self.mc.MOVSD(result_loc, xmm0) else: assert result_loc is eax - descr = self.cpu.getarraydescr_for_frame(kind) ofs = self.cpu.unpack_arraydescr(descr) self.mc.MOV_rm(eax.value, (eax.value, ofs)) From noreply at buildbot.pypy.org Sat Feb 16 12:19:11 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sat, 16 Feb 2013 12:19:11 +0100 (CET) Subject: [pypy-commit] pypy default: Don't name the SignalActionFlag explicitly here. Message-ID: <20130216111911.8652C1C062C@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r61316:e7bbbe5d09ce Date: 2013-02-16 11:15 +0100 http://bitbucket.org/pypy/pypy/changeset/e7bbbe5d09ce/ Log: Don't name the SignalActionFlag explicitly here. diff --git a/pypy/module/signal/interp_signal.py b/pypy/module/signal/interp_signal.py --- a/pypy/module/signal/interp_signal.py +++ b/pypy/module/signal/interp_signal.py @@ -32,8 +32,7 @@ p = pypysig_getaddr_occurred() p.c_value = value - @staticmethod - def rearm_ticker(): + def rearm_ticker(self): p = pypysig_getaddr_occurred() p.c_value = -1 @@ -71,7 +70,7 @@ if self.fire_in_another_thread: if self.space.threadlocals.signals_enabled(): self.fire_in_another_thread = False - SignalActionFlag.rearm_ticker() + self.space.actionflag.rearm_ticker() # this occurs when we just switched to the main thread # and there is a signal pending: we force the ticker to # -1, which should ensure perform() is called quickly. From noreply at buildbot.pypy.org Sat Feb 16 12:19:16 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sat, 16 Feb 2013 12:19:16 +0100 (CET) Subject: [pypy-commit] pypy default: merge heads Message-ID: <20130216111916.B181F1C0CA3@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r61320:95b58361ccf1 Date: 2013-02-16 12:19 +0100 http://bitbucket.org/pypy/pypy/changeset/95b58361ccf1/ Log: merge heads diff --git a/pypy/interpreter/miscutils.py b/pypy/interpreter/miscutils.py --- a/pypy/interpreter/miscutils.py +++ b/pypy/interpreter/miscutils.py @@ -20,10 +20,10 @@ def signals_enabled(self): return True - def enable_signals(self): + def enable_signals(self, space): pass - def disable_signals(self): + def disable_signals(self, space): pass def getallvalues(self): diff --git a/pypy/module/__pypy__/interp_signal.py b/pypy/module/__pypy__/interp_signal.py --- a/pypy/module/__pypy__/interp_signal.py +++ b/pypy/module/__pypy__/interp_signal.py @@ -1,6 +1,6 @@ def signals_enter(space): - space.threadlocals.enable_signals() + space.threadlocals.enable_signals(space) def signals_exit(space, w_ignored1=None, w_ignored2=None, w_ignored3=None): - space.threadlocals.disable_signals() + space.threadlocals.disable_signals(space) diff --git a/pypy/module/__pypy__/test/test_signal.py b/pypy/module/__pypy__/test/test_signal.py --- a/pypy/module/__pypy__/test/test_signal.py +++ b/pypy/module/__pypy__/test/test_signal.py @@ -3,18 +3,6 @@ from pypy.module.thread.test.support import GenericTestThread -class TestThreadSignal: - spaceconfig = dict(usemodules=['__pypy__', 'thread']) - - def test_exit_twice(self, space): - from pypy.module.__pypy__.interp_signal import signals_exit, signals_enter - signals_exit(space) - try: - raises(KeyError, signals_exit, space) - finally: - signals_enter(space) - - class AppTestMinimal: spaceconfig = dict(usemodules=['__pypy__']) @@ -28,6 +16,14 @@ class AppTestThreadSignal(GenericTestThread): spaceconfig = dict(usemodules=['__pypy__', 'thread', 'signal', 'time']) + def test_exit_twice(self): + from __pypy__ import thread + thread._signals_exit() + try: + raises(KeyError, thread._signals_exit) + finally: + thread._signals_enter() + def test_enable_signals(self): import __pypy__, thread, signal, time diff --git a/pypy/module/thread/threadlocals.py b/pypy/module/thread/threadlocals.py --- a/pypy/module/thread/threadlocals.py +++ b/pypy/module/thread/threadlocals.py @@ -1,4 +1,5 @@ from rpython.rlib import rthread +from pypy.interpreter.error import OperationError class OSThreadLocals: @@ -54,14 +55,18 @@ def signals_enabled(self): return rthread.get_ident() in self._signalsenabled - def enable_signals(self): + def enable_signals(self, space): ident = rthread.get_ident() old = self._signalsenabled.get(ident, 0) self._signalsenabled[ident] = old + 1 - def disable_signals(self): + def disable_signals(self, space): ident = rthread.get_ident() - new = self._signalsenabled[ident] - 1 + try: + new = self._signalsenabled[ident] - 1 + except KeyError: + raise OperationError(space.w_KeyError, space.wrap( + "cannot disable signals in thread not enabled for signals")) if new > 0: self._signalsenabled[ident] = new else: @@ -85,9 +90,11 @@ # enable_signals() if necessary. That's a hack but I cannot # figure out a non-hackish way to handle thread+signal+fork :-( ident = rthread.get_ident() - old = self._signalsenabled.get(ident, 0) - if ident is not self._mainthreadident: - self._mainthreadident = ident - old += 1 - self._signalsenabled.clear() - self._signalsenabled[ident] = old + val = self.getvalue() + sig = self._signalsenabled.get(ident, 0) + if ident != self._mainthreadident: + sig += 1 + self._cleanup_() + self.setvalue(val) + self._signalsenabled[ident] = sig + self._mainthreadident = ident diff --git a/rpython/rlib/rstruct/ieee.py b/rpython/rlib/rstruct/ieee.py --- a/rpython/rlib/rstruct/ieee.py +++ b/rpython/rlib/rstruct/ieee.py @@ -255,6 +255,7 @@ l.reverse() result.append("".join(l)) + at jit.unroll_safe def unpack_float(s, be): unsigned = r_ulonglong(0) for i in range(min(len(s), 8)): @@ -262,6 +263,7 @@ unsigned |= r_ulonglong(c) << (i * 8) return float_unpack(unsigned, len(s)) + at jit.unroll_safe def unpack_float80(s, be): QQ = [r_ulonglong(0), r_ulonglong(0)] for i in range(8): From noreply at buildbot.pypy.org Sat Feb 16 12:19:13 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sat, 16 Feb 2013 12:19:13 +0100 (CET) Subject: [pypy-commit] pypy stm-thread-2: hg merge default Message-ID: <20130216111913.16E701C0673@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stm-thread-2 Changeset: r61317:8eedaf9d0459 Date: 2013-02-16 11:17 +0100 http://bitbucket.org/pypy/pypy/changeset/8eedaf9d0459/ Log: hg merge default diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst --- a/pypy/doc/whatsnew-head.rst +++ b/pypy/doc/whatsnew-head.rst @@ -19,7 +19,7 @@ .. branch: numpypy-longdouble Long double support for numpypy .. branch: numpypy-real-as-view -Convert real, imag from ufuncs to views. This involves the beginning of +Convert real, imag from ufuncs to views. This involves the beginning of view() functionality .. branch: signatures @@ -57,7 +57,11 @@ .. branch: cleanup-tests Consolidated the lib_pypy/pypy_test and pypy/module/test_lib_pypy tests into -+one directory for reduced confusion and so they all run nightly. +one directory for reduced confusion and so they all run nightly. .. branch: unquote-faster .. branch: urlparse-unquote-faster + +.. branch: signal-and-thread +Add "__pypy__.thread.signals_enabled", a context manager. Can be used in a +non-main thread to enable the processing of signal handlers in that thread. diff --git a/pypy/module/__pypy__/test/test_signal.py b/pypy/module/__pypy__/test/test_signal.py --- a/pypy/module/__pypy__/test/test_signal.py +++ b/pypy/module/__pypy__/test/test_signal.py @@ -1,5 +1,19 @@ import sys +from pypy.module.thread.test.support import GenericTestThread + + +class TestThreadSignal: + spaceconfig = dict(usemodules=['__pypy__', 'thread']) + + def test_exit_twice(self, space): + from pypy.module.__pypy__.interp_signal import signals_exit, signals_enter + signals_exit(space) + try: + raises(KeyError, signals_exit, space) + finally: + signals_enter(space) + class AppTestMinimal: spaceconfig = dict(usemodules=['__pypy__']) @@ -11,7 +25,76 @@ # assert did not crash -class AppTestThreadSignal: +class AppTestThreadSignal(GenericTestThread): + spaceconfig = dict(usemodules=['__pypy__', 'thread', 'signal', 'time']) + + def test_enable_signals(self): + import __pypy__, thread, signal, time + + def subthread(): + try: + with __pypy__.thread.signals_enabled: + thread.interrupt_main() + for i in range(10): + print 'x' + time.sleep(0.1) + except BaseException, e: + interrupted.append(e) + finally: + done.append(None) + + # This is normally called by app_main.py + signal.signal(signal.SIGINT, signal.default_int_handler) + + for i in range(10): + __pypy__.thread._signals_exit() + try: + done = [] + interrupted = [] + thread.start_new_thread(subthread, ()) + for i in range(10): + if len(done): break + print '.' + time.sleep(0.1) + assert len(done) == 1 + assert len(interrupted) == 1 + assert 'KeyboardInterrupt' in interrupted[0].__class__.__name__ + finally: + __pypy__.thread._signals_enter() + + def test_thread_fork_signals(self): + import __pypy__ + import os, thread, signal + + if not hasattr(os, 'fork'): + skip("No fork on this platform") + + def fork(): + with __pypy__.thread.signals_enabled: + return os.fork() + + def threadfunction(): + pid = fork() + if pid == 0: + print 'in child' + # signal() only works from the 'main' thread + signal.signal(signal.SIGUSR1, signal.SIG_IGN) + os._exit(42) + else: + self.timeout_killer(pid, 5) + exitcode = os.waitpid(pid, 0)[1] + feedback.append(exitcode) + + feedback = [] + thread.start_new_thread(threadfunction, ()) + self.waitfor(lambda: feedback) + # if 0, an (unraisable) exception was raised from the forked thread. + # if 9, process was killed by timer. + # if 42<<8, os._exit(42) was correctly reached. + assert feedback == [42<<8] + + +class AppTestThreadSignalLock: spaceconfig = dict(usemodules=['__pypy__', 'thread', 'signal']) def setup_class(cls): @@ -22,11 +105,11 @@ def test_enable_signals(self): import __pypy__, thread, signal, time - # + interrupted = [] lock = thread.allocate_lock() lock.acquire() - # + def subthread(): try: time.sleep(0.25) @@ -34,8 +117,9 @@ thread.interrupt_main() except BaseException, e: interrupted.append(e) - lock.release() - # + finally: + lock.release() + thread.start_new_thread(subthread, ()) lock.acquire() assert len(interrupted) == 1 diff --git a/pypy/module/_cffi_backend/newtype.py b/pypy/module/_cffi_backend/newtype.py --- a/pypy/module/_cffi_backend/newtype.py +++ b/pypy/module/_cffi_backend/newtype.py @@ -264,8 +264,8 @@ # ____________________________________________________________ - at unwrap_spec(name=str) -def new_enum_type(space, name, w_enumerators, w_enumvalues): + at unwrap_spec(name=str, basectype=ctypeobj.W_CType) +def new_enum_type(space, name, w_enumerators, w_enumvalues, basectype): enumerators_w = space.fixedview(w_enumerators) enumvalues_w = space.fixedview(w_enumvalues) if len(enumerators_w) != len(enumvalues_w): @@ -273,53 +273,26 @@ space.wrap("tuple args must have the same size")) enumerators = [space.str_w(w) for w in enumerators_w] # - smallest_value = 0 - largest_value = r_uint(0) - i = 0 + if (not isinstance(basectype, ctypeprim.W_CTypePrimitiveSigned) and + not isinstance(basectype, ctypeprim.W_CTypePrimitiveUnsigned)): + raise OperationError(space.w_TypeError, + space.wrap("expected a primitive signed or unsigned base type")) + # + lvalue = lltype.malloc(rffi.CCHARP.TO, basectype.size, flavor='raw') try: for w in enumvalues_w: - try: - ulvalue = space.uint_w(w) - except OperationError, e: - if not e.match(space, space.w_ValueError): - raise - lvalue = space.int_w(w) - if lvalue < smallest_value: - smallest_value = lvalue - else: - if ulvalue > largest_value: - largest_value = ulvalue - i += 1 # 'i' is here for the exception case, see below - except OperationError, e: - if not e.match(space, space.w_OverflowError): - raise - raise operationerrfmt(space.w_OverflowError, - "enum '%s' declaration for '%s' does not fit " - "a long or unsigned long", - name, enumerators[i]) + # detects out-of-range or badly typed values + basectype.convert_from_object(lvalue, w) + finally: + lltype.free(lvalue, flavor='raw') # - if smallest_value < 0: - if (smallest_value >= intmask(most_neg_value_of(rffi.INT)) and - largest_value <= r_uint(most_pos_value_of(rffi.INT))): - size = rffi.sizeof(rffi.INT) - align = alignment(rffi.INT) - elif largest_value <= r_uint(most_pos_value_of(rffi.LONG)): - size = rffi.sizeof(rffi.LONG) - align = alignment(rffi.LONG) - else: - raise operationerrfmt(space.w_OverflowError, - "enum '%s' values don't all fit into either 'long' " - "or 'unsigned long'", name) + size = basectype.size + align = basectype.align + if isinstance(basectype, ctypeprim.W_CTypePrimitiveSigned): enumvalues = [space.int_w(w) for w in enumvalues_w] ctype = ctypeenum.W_CTypeEnumSigned(space, name, size, align, enumerators, enumvalues) else: - if largest_value <= r_uint(most_pos_value_of(rffi.UINT)): - size = rffi.sizeof(rffi.UINT) - align = alignment(rffi.UINT) - else: - size = rffi.sizeof(rffi.ULONG) - align = alignment(rffi.ULONG) enumvalues = [space.uint_w(w) for w in enumvalues_w] ctype = ctypeenum.W_CTypeEnumUnsigned(space, name, size, align, enumerators, enumvalues) diff --git a/pypy/module/_cffi_backend/test/_backend_test_c.py b/pypy/module/_cffi_backend/test/_backend_test_c.py --- a/pypy/module/_cffi_backend/test/_backend_test_c.py +++ b/pypy/module/_cffi_backend/test/_backend_test_c.py @@ -1264,25 +1264,29 @@ py.test.raises(TypeError, callback, BFunc, cb, -42) def test_enum_type(): - BEnum = new_enum_type("foo", (), ()) + BUInt = new_primitive_type("unsigned int") + BEnum = new_enum_type("foo", (), (), BUInt) assert repr(BEnum) == "" assert BEnum.kind == "enum" assert BEnum.cname == "enum foo" assert BEnum.elements == {} # - BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, -20)) + BInt = new_primitive_type("int") + BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, -20), BInt) assert BEnum.kind == "enum" assert BEnum.elements == {-20: 'ab', 0: 'def', 1: 'c'} # 'elements' is not the real dict, but merely a copy BEnum.elements[2] = '??' assert BEnum.elements == {-20: 'ab', 0: 'def', 1: 'c'} # - BEnum = new_enum_type("bar", ('ab', 'cd'), (5, 5)) + BEnum = new_enum_type("bar", ('ab', 'cd'), (5, 5), BUInt) assert BEnum.elements == {5: 'ab'} assert BEnum.relements == {'ab': 5, 'cd': 5} def test_cast_to_enum(): - BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, -20)) + BInt = new_primitive_type("int") + BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, -20), BInt) + assert sizeof(BEnum) == sizeof(BInt) e = cast(BEnum, 0) assert repr(e) == "" assert repr(cast(BEnum, -42)) == "" @@ -1294,18 +1298,27 @@ assert int(cast(BEnum, -242 + 2**128)) == -242 assert string(cast(BEnum, -242 + 2**128)) == '-242' # - BEnum = new_enum_type("bar", ('def', 'c', 'ab'), (0, 1, 20)) + BUInt = new_primitive_type("unsigned int") + BEnum = new_enum_type("bar", ('def', 'c', 'ab'), (0, 1, 20), BUInt) e = cast(BEnum, -1) assert repr(e) == "" # unsigned int + # + BLong = new_primitive_type("long") + BEnum = new_enum_type("baz", (), (), BLong) + assert sizeof(BEnum) == sizeof(BLong) + e = cast(BEnum, -1) + assert repr(e) == "" def test_enum_with_non_injective_mapping(): - BEnum = new_enum_type("foo", ('ab', 'cd'), (7, 7)) + BInt = new_primitive_type("int") + BEnum = new_enum_type("foo", ('ab', 'cd'), (7, 7), BInt) e = cast(BEnum, 7) assert repr(e) == "" assert string(e) == 'ab' def test_enum_in_struct(): - BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, -20)) + BInt = new_primitive_type("int") + BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, -20), BInt) BStruct = new_struct_type("bar") BStructPtr = new_pointer_type(BStruct) complete_struct_or_union(BStruct, [('a1', BEnum, -1)]) @@ -1318,7 +1331,7 @@ "unsupported operand type for int(): 'NoneType'" in str(e.value)) #PyPy py.test.raises(TypeError, 'p.a1 = "def"') if sys.version_info < (3,): - BEnum2 = new_enum_type(unicode("foo"), (unicode('abc'),), (5,)) + BEnum2 = new_enum_type(unicode("foo"), (unicode('abc'),), (5,), BInt) assert string(cast(BEnum2, 5)) == 'abc' assert type(string(cast(BEnum2, 5))) is str @@ -1327,66 +1340,25 @@ max_int = max_uint // 2 max_ulong = 2 ** (size_of_long()*8) - 1 max_long = max_ulong // 2 - # 'unsigned int' case - e = new_enum_type("foo", ('a', 'b'), (0, 3)) - assert sizeof(e) == size_of_int() - assert int(cast(e, -1)) == max_uint # 'e' is unsigned - e = new_enum_type("foo", ('a', 'b'), (0, max_uint)) - assert sizeof(e) == size_of_int() - assert int(cast(e, -1)) == max_uint - assert e.elements == {0: 'a', max_uint: 'b'} - assert e.relements == {'a': 0, 'b': max_uint} - # 'signed int' case - e = new_enum_type("foo", ('a', 'b'), (-1, max_int)) - assert sizeof(e) == size_of_int() - assert int(cast(e, -1)) == -1 - assert e.elements == {-1: 'a', max_int: 'b'} - assert e.relements == {'a': -1, 'b': max_int} - e = new_enum_type("foo", ('a', 'b'), (-max_int-1, max_int)) - assert sizeof(e) == size_of_int() - assert int(cast(e, -1)) == -1 - assert e.elements == {-max_int-1: 'a', max_int: 'b'} - assert e.relements == {'a': -max_int-1, 'b': max_int} - # 'unsigned long' case - e = new_enum_type("foo", ('a', 'b'), (0, max_long)) - assert sizeof(e) == size_of_long() - assert int(cast(e, -1)) == max_ulong # 'e' is unsigned - e = new_enum_type("foo", ('a', 'b'), (0, max_ulong)) - assert sizeof(e) == size_of_long() - assert int(cast(e, -1)) == max_ulong - assert e.elements == {0: 'a', max_ulong: 'b'} - assert e.relements == {'a': 0, 'b': max_ulong} - # 'signed long' case - e = new_enum_type("foo", ('a', 'b'), (-1, max_long)) - assert sizeof(e) == size_of_long() - assert int(cast(e, -1)) == -1 - assert e.elements == {-1: 'a', max_long: 'b'} - assert e.relements == {'a': -1, 'b': max_long} - e = new_enum_type("foo", ('a', 'b'), (-max_long-1, max_long)) - assert sizeof(e) == size_of_long() - assert int(cast(e, -1)) == -1 - assert e.elements == {-max_long-1: 'a', max_long: 'b'} - assert e.relements == {'a': -max_long-1, 'b': max_long} - # overflow: both negative items and items larger than max_long - e = py.test.raises(OverflowError, new_enum_type, "foo", ('a', 'b'), - (-1, max_long + 1)) - assert str(e.value) == ( - "enum 'foo' values don't all fit into either 'long' " - "or 'unsigned long'") - # overflow: items smaller than -max_long-1 - e = py.test.raises(OverflowError, new_enum_type, "foo", ('a', 'b'), - (-max_long-2, 5)) - assert str(e.value) == ( - "enum 'foo' declaration for 'a' does not fit a long or unsigned long") - # overflow: items larger than max_ulong - e = py.test.raises(OverflowError, new_enum_type, "foo", ('a', 'b'), - (5, max_ulong+1)) - assert str(e.value) == ( - "enum 'foo' declaration for 'b' does not fit a long or unsigned long") + for BPrimitive in [new_primitive_type("int"), + new_primitive_type("unsigned int"), + new_primitive_type("long"), + new_primitive_type("unsigned long")]: + for x in [max_uint, max_int, max_ulong, max_long]: + for testcase in [x, x+1, -x-1, -x-2]: + if int(cast(BPrimitive, testcase)) == testcase: + # fits + BEnum = new_enum_type("foo", ("AA",), (testcase,), + BPrimitive) + assert int(cast(BEnum, testcase)) == testcase + else: + # overflows + py.test.raises(OverflowError, new_enum_type, + "foo", ("AA",), (testcase,), BPrimitive) def test_callback_returning_enum(): BInt = new_primitive_type("int") - BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, -20)) + BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, -20), BInt) def cb(n): if n & 1: return cast(BEnum, n) @@ -1402,9 +1374,9 @@ def test_callback_returning_enum_unsigned(): BInt = new_primitive_type("int") - BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, 20)) + BUInt = new_primitive_type("unsigned int") + BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, 20), BUInt) def cb(n): - print n if n & 1: return cast(BEnum, n) else: diff --git a/pypy/module/micronumpy/test/test_numarray.py b/pypy/module/micronumpy/test/test_numarray.py --- a/pypy/module/micronumpy/test/test_numarray.py +++ b/pypy/module/micronumpy/test/test_numarray.py @@ -1,5 +1,5 @@ - -import py, sys +import py +import sys from pypy.conftest import option from pypy.module.micronumpy.appbridge import get_appbridge_cache @@ -7,6 +7,7 @@ from pypy.module.micronumpy.interp_numarray import W_NDimArray from pypy.module.micronumpy.test.test_base import BaseNumpyAppTest + class MockDtype(object): class itemtype(object): @staticmethod @@ -24,9 +25,11 @@ def create_slice(a, chunks): return Chunks(chunks).apply(W_NDimArray(a)).implementation + def create_array(*args, **kwargs): return W_NDimArray.from_shape(*args, **kwargs).implementation + class TestNumArrayDirect(object): def newslice(self, *args): return self.space.newslice(*[self.space.wrap(arg) for arg in args]) @@ -1202,7 +1205,7 @@ assert d.shape == (3, 3) assert d.dtype == dtype('int32') assert (d == [[1, 0, 0], [0, 1, 0], [0, 0, 1]]).all() - + def test_eye(self): from _numpypy import eye from _numpypy import int32, dtype @@ -1232,9 +1235,6 @@ assert g.shape == (3, 4) assert (g == [[0, 0, 0, 0], [1, 0, 0, 0], [0, 1, 0, 0]]).all() - - - def test_prod(self): from _numpypy import array a = array(range(1, 6)) @@ -1473,6 +1473,11 @@ assert len(a) == 6 assert (a == [0,1,2,3,4,5]).all() assert a.dtype is dtype(int) + a = concatenate((a1, a2), axis=1) + assert (a == [0,1,2,3,4,5]).all() + a = concatenate((a1, a2), axis=-1) + assert (a == [0,1,2,3,4,5]).all() + b1 = array([[1, 2], [3, 4]]) b2 = array([[5, 6]]) b = concatenate((b1, b2), axis=0) @@ -1488,16 +1493,29 @@ f = concatenate((f1, [2], f1, [7])) assert (f == [0,1,2,0,1,7]).all() - bad_axis = raises(IndexError, concatenate, (a1,a2), axis=1) - assert str(bad_axis.value) == "axis 1 out of bounds [0, 1)" + g1 = array([[0,1,2]]) + g2 = array([[3,4,5]]) + g = concatenate((g1, g2), axis=-2) + assert (g == [[0,1,2],[3,4,5]]).all() + exc = raises(IndexError, concatenate, (g1, g2), axis=2) + assert str(exc.value) == "axis 2 out of bounds [0, 2)" + exc = raises(IndexError, concatenate, (g1, g2), axis=-3) + assert str(exc.value) == "axis -3 out of bounds [0, 2)" - concat_zero = raises(ValueError, concatenate, ()) - assert str(concat_zero.value) == \ - "need at least one array to concatenate" + exc = raises(ValueError, concatenate, ()) + assert str(exc.value) == \ + "need at least one array to concatenate" - dims_disagree = raises(ValueError, concatenate, (a1, b1), axis=0) - assert str(dims_disagree.value) == \ - "all the input arrays must have same number of dimensions" + exc = raises(ValueError, concatenate, (a1, b1), axis=0) + assert str(exc.value) == \ + "all the input arrays must have same number of dimensions" + + g1 = array([0,1,2]) + g2 = array([[3,4,5]]) + exc = raises(ValueError, concatenate, (g1, g2), axis=2) + assert str(exc.value) == \ + "all the input arrays must have same number of dimensions" + a = array([1, 2, 3, 4, 5, 6]) a = (a + a)[::2] b = concatenate((a[:3], a[-3:])) @@ -1583,7 +1601,7 @@ [[3, 9], [6, 12]]])).all() assert (x.swapaxes(1, 2) == array([[[1, 4], [2, 5], [3, 6]], [[7, 10], [8, 11],[9, 12]]])).all() - + # test slice assert (x[0:1,0:2].swapaxes(0,2) == array([[[1], [4]], [[2], [5]], [[3], [6]]])).all() @@ -1745,13 +1763,13 @@ assert a[1] == 0xff assert len(a.data) == 16 - def test_explicit_dtype_conversion(self): from _numpypy import array a = array([1.0, 2.0]) b = array(a, dtype='d') assert a.dtype is b.dtype + class AppTestMultiDim(BaseNumpyAppTest): def test_init(self): import _numpypy @@ -2043,6 +2061,7 @@ False, False, True, False, False, False]).all() assert ((b > range(12)) == [False, True, True,False, True, True, False, False, True, False, False, False]).all() + def test_flatiter_view(self): from _numpypy import arange a = arange(10).reshape(5, 2) @@ -2263,10 +2282,10 @@ a = arange(12).reshape(2, 3, 2) assert (a.diagonal(0, 0, 1) == [[0, 8], [1, 9]]).all() assert a.diagonal(3, 0, 1).shape == (2, 0) - assert (a.diagonal(1, 0, 1) == [[2, 10], [3, 11]]).all() - assert (a.diagonal(0, 2, 1) == [[0, 3], [6, 9]]).all() - assert (a.diagonal(2, 2, 1) == [[4], [10]]).all() - assert (a.diagonal(1, 2, 1) == [[2, 5], [8, 11]]).all() + assert (a.diagonal(1, 0, 1) == [[2, 10], [3, 11]]).all() + assert (a.diagonal(0, 2, 1) == [[0, 3], [6, 9]]).all() + assert (a.diagonal(2, 2, 1) == [[4], [10]]).all() + assert (a.diagonal(1, 2, 1) == [[2, 5], [8, 11]]).all() def test_diagonal_axis_neg_ofs(self): from _numpypy import arange @@ -2274,6 +2293,7 @@ assert (a.diagonal(-1, 0, 1) == [[6], [7]]).all() assert a.diagonal(-2, 0, 1).shape == (2, 0) + class AppTestSupport(BaseNumpyAppTest): def setup_class(cls): import struct @@ -2444,6 +2464,7 @@ assert (a.argsort(axis=0) == [[1, 0, 0], [0, 1, 1]]).all() assert (a.argsort(axis=1) == [[2, 1, 0], [0, 1, 2]]).all() + class AppTestRanges(BaseNumpyAppTest): def test_arange(self): from _numpypy import arange, dtype @@ -2489,6 +2510,7 @@ cache.w_array_repr = cls.old_array_repr cache.w_array_str = cls.old_array_str + class AppTestRecordDtype(BaseNumpyAppTest): def test_zeros(self): from _numpypy import zeros, integer @@ -2659,4 +2681,3 @@ assert x.__pypy_data__ is obj del x.__pypy_data__ assert x.__pypy_data__ is None - diff --git a/pypy/module/micronumpy/types.py b/pypy/module/micronumpy/types.py --- a/pypy/module/micronumpy/types.py +++ b/pypy/module/micronumpy/types.py @@ -1530,8 +1530,8 @@ def byteswap(self, w_v): value = self.unbox(w_v) - result = StringBuilder(12) - pack_float80(result, value, not native_is_bigendian) + result = StringBuilder(10) + pack_float80(result, value, 10, not native_is_bigendian) return self.box(unpack_float80(result.build(), native_is_bigendian)) NonNativeFloat96 = Float96 @@ -1560,8 +1560,8 @@ def byteswap(self, w_v): value = self.unbox(w_v) - result = StringBuilder(16) - pack_float80(result, value, not native_is_bigendian) + result = StringBuilder(10) + pack_float80(result, value, 10, not native_is_bigendian) return self.box(unpack_float80(result.build(), native_is_bigendian)) NonNativeFloat128 = Float128 diff --git a/pypy/module/signal/interp_signal.py b/pypy/module/signal/interp_signal.py --- a/pypy/module/signal/interp_signal.py +++ b/pypy/module/signal/interp_signal.py @@ -32,8 +32,7 @@ p = pypysig_getaddr_occurred() p.c_value = value - @staticmethod - def rearm_ticker(): + def rearm_ticker(self): p = pypysig_getaddr_occurred() p.c_value = -1 @@ -71,7 +70,7 @@ if self.fire_in_another_thread: if self.space.threadlocals.signals_enabled(): self.fire_in_another_thread = False - SignalActionFlag.rearm_ticker() + self.space.actionflag.rearm_ticker() # this occurs when we just switched to the main thread # and there is a signal pending: we force the ticker to # -1, which should ensure perform() is called quickly. @@ -101,6 +100,7 @@ if not we_are_translated(): self.pending_signal = cpy_signal.SIGINT # ^^^ may override another signal, but it's just for testing + self.fire_in_another_thread = True else: pypysig_pushback(cpy_signal.SIGINT) diff --git a/pypy/module/thread/test/test_thread.py b/pypy/module/thread/test/test_thread.py --- a/pypy/module/thread/test/test_thread.py +++ b/pypy/module/thread/test/test_thread.py @@ -220,18 +220,18 @@ import signal def f(): - for x in range(50): + for x in range(5): if waiting: thread.interrupt_main() return print 'tock...', x # <-force the GIL to be released, as - time.sleep(0.01) # time.sleep doesn't do non-translated + time.sleep(0.1) # time.sleep doesn't do non-translated def busy_wait(): waiting.append(None) - for x in range(100): + for x in range(10): print 'tick...', x # <-force the GIL to be released, as - time.sleep(0.01) # time.sleep doesn't do non-translated + time.sleep(0.1) # time.sleep doesn't do non-translated waiting.pop() # This is normally called by app_main.py diff --git a/pypy/module/thread/threadlocals.py b/pypy/module/thread/threadlocals.py --- a/pypy/module/thread/threadlocals.py +++ b/pypy/module/thread/threadlocals.py @@ -17,6 +17,7 @@ def _cleanup_(self): self._valuedict.clear() self._signalsenabled.clear() + self._mainthreadident = 0 if self.can_cache: self._mostrecentkey = 0 # fast minicaching for the common case self._mostrecentvalue = None # fast minicaching for the common case @@ -39,12 +40,17 @@ if value is not None: if len(self._valuedict) == 0: self._signalsenabled[ident] = 1 # the main thread is enabled + self._mainthreadident = ident self._valuedict[ident] = value else: try: del self._valuedict[ident] except KeyError: pass + try: + del self._signalsenabled[ident] + except KeyError: + pass if self.can_cache: # update the minicache to prevent it from containing an outdated value self._mostrecentkey = ident @@ -60,10 +66,7 @@ def disable_signals(self): ident = rthread.get_ident() - try: - new = self._signalsenabled[ident] - 1 - except KeyError: - return + new = self._signalsenabled[ident] - 1 if new > 0: self._signalsenabled[ident] = new else: @@ -88,7 +91,8 @@ # figure out a non-hackish way to handle thread+signal+fork :-( ident = rthread.get_ident() old = self._signalsenabled.get(ident, 0) + if ident is not self._mainthreadident: + self._mainthreadident = ident + old += 1 self._signalsenabled.clear() - if old == 0: - old = 1 self._signalsenabled[ident] = old diff --git a/rpython/rlib/rstruct/ieee.py b/rpython/rlib/rstruct/ieee.py --- a/rpython/rlib/rstruct/ieee.py +++ b/rpython/rlib/rstruct/ieee.py @@ -25,26 +25,23 @@ return int_part def float_unpack(Q, size): - """Convert a 16-bit, 32-bit 64-bit integer created + """Convert a 16-bit, 32-bit, or 64-bit integer created by float_pack into a Python float.""" if size == 8: MIN_EXP = -1021 # = sys.float_info.min_exp MAX_EXP = 1024 # = sys.float_info.max_exp MANT_DIG = 53 # = sys.float_info.mant_dig BITS = 64 - one = r_ulonglong(1) elif size == 4: MIN_EXP = -125 # C's FLT_MIN_EXP MAX_EXP = 128 # FLT_MAX_EXP MANT_DIG = 24 # FLT_MANT_DIG BITS = 32 - one = r_ulonglong(1) elif size == 2: MIN_EXP = -13 MAX_EXP = 16 MANT_DIG = 11 BITS = 16 - one = r_ulonglong(1) else: raise ValueError("invalid size value") @@ -56,6 +53,7 @@ raise ValueError("input '%r' out of range '%r'" % (Q, Q>>BITS)) # extract pieces with assumed 1.mant values + one = r_ulonglong(1) sign = rarithmetic.intmask(Q >> BITS - 1) exp = rarithmetic.intmask((Q & ((one << BITS - 1) - (one << MANT_DIG - 1))) >> MANT_DIG - 1) mant = Q & ((one << MANT_DIG - 1) - 1) @@ -72,27 +70,32 @@ result = math.ldexp(mant, exp + MIN_EXP - MANT_DIG - 1) return -result if sign else result -def float_unpack80(QQ): +def float_unpack80(QQ, size): '''Unpack a (mant, exp) tuple of r_ulonglong in 80-bit extended format into a long double float ''' - MIN_EXP = -16381 - MAX_EXP = 16384 - MANT_DIG = 64 - TOPBITS = 80 - 64 - one = r_ulonglong(1) + if size == 10 or size == 12 or size == 16: + MIN_EXP = -16381 + MAX_EXP = 16384 + MANT_DIG = 64 + TOP_BITS = 80 - 64 + else: + raise ValueError("invalid size value") + if len(QQ) != 2: raise ValueError("QQ must be two 64 bit uints") + if not objectmodel.we_are_translated(): # This tests generates wrong code when translated: # with gcc, shifting a 64bit int by 64 bits does # not change the value. - if QQ[1] >> TOPBITS: - raise ValueError("input '%r' out of range '%r'" % (QQ, QQ[1]>>TOPBITS)) + if QQ[1] >> TOP_BITS: + raise ValueError("input '%r' out of range '%r'" % (QQ, QQ[1]>>TOP_BITS)) # extract pieces with explicit one in MANT_DIG - sign = rarithmetic.intmask(QQ[1] >> TOPBITS - 1) - exp = rarithmetic.intmask((QQ[1] & ((one << TOPBITS - 1) - 1))) + one = r_ulonglong(1) + sign = rarithmetic.intmask(QQ[1] >> TOP_BITS - 1) + exp = rarithmetic.intmask((QQ[1] & ((one << TOP_BITS - 1) - 1))) mant = QQ[0] if exp == MAX_EXP - MIN_EXP + 2: @@ -171,14 +174,18 @@ sign = r_ulonglong(sign) return ((sign << BITS - 1) | (exp << MANT_DIG - 1)) | mant -def float_pack80(x): +def float_pack80(x, size): """Convert a Python float or longfloat x into two 64-bit unsigned integers with 80 bit extended representation.""" - MIN_EXP = -16381 - MAX_EXP = 16384 - MANT_DIG = 64 - BITS = 80 x = float(x) # longfloat not really supported + if size == 10 or size == 12 or size == 16: + MIN_EXP = -16381 + MAX_EXP = 16384 + MANT_DIG = 64 + BITS = 80 + else: + raise ValueError("invalid size value") + sign = rfloat.copysign(1.0, x) < 0.0 if not rfloat.isfinite(x): if rfloat.isinf(x): @@ -235,32 +242,32 @@ result.append("".join(l)) @jit.unroll_safe -def pack_float80(result, x, be): +def pack_float80(result, x, size, be): l = [] - unsigned = float_pack80(x) + unsigned = float_pack80(x, size) for i in range(8): l.append(chr((unsigned[0] >> (i * 8)) & 0xFF)) for i in range(2): l.append(chr((unsigned[1] >> (i * 8)) & 0xFF)) + for i in range(size - 10): + l.append('\x00') if be: l.reverse() result.append("".join(l)) def unpack_float(s, be): unsigned = r_ulonglong(0) - for i in range(len(s)): - c = ord(s[len(s) - 1 - i if be else i]) + for i in range(min(len(s), 8)): + c = ord(s[-i - 1 if be else i]) unsigned |= r_ulonglong(c) << (i * 8) return float_unpack(unsigned, len(s)) def unpack_float80(s, be): - if len(s) != 10: - raise ValueError QQ = [r_ulonglong(0), r_ulonglong(0)] for i in range(8): - c = ord(s[9 - i if be else i]) + c = ord(s[-i - 1 if be else i]) QQ[0] |= r_ulonglong(c) << (i * 8) for i in range(8, 10): - c = ord(s[9 - i if be else i]) + c = ord(s[-i - 1 if be else i]) QQ[1] |= r_ulonglong(c) << ((i - 8) * 8) - return float_unpack80(QQ) + return float_unpack80(QQ, len(s)) diff --git a/rpython/rlib/rstruct/test/test_ieee.py b/rpython/rlib/rstruct/test/test_ieee.py --- a/rpython/rlib/rstruct/test/test_ieee.py +++ b/rpython/rlib/rstruct/test/test_ieee.py @@ -8,6 +8,55 @@ from rpython.translator.c.test.test_genc import compile +class TestFloatSpecific: + def test_halffloat_exact(self): + #testcases generated from numpy.float16(x).view('uint16') + cases = [[0, 0], [10, 18688], [-10, 51456], [10e3, 28898], + [float('inf'), 31744], [-float('inf'), 64512]] + for c, h in cases: + hbit = ieee.float_pack(c, 2) + assert hbit == h + assert c == ieee.float_unpack(h, 2) + + def test_halffloat_inexact(self): + #testcases generated from numpy.float16(x).view('uint16') + cases = [[10.001, 18688, 10.], [-10.001, 51456, -10], + [0.027588, 10000, 0.027587890625], + [22001, 30047, 22000]] + for c, h, f in cases: + hbit = ieee.float_pack(c, 2) + assert hbit == h + assert f == ieee.float_unpack(h, 2) + + def test_halffloat_overunderflow(self): + import math + cases = [[670000, float('inf')], [-67000, -float('inf')], + [1e-08, 0], [-1e-8, -0.]] + for f1, f2 in cases: + try: + f_out = ieee.float_unpack(ieee.float_pack(f1, 2), 2) + except OverflowError: + f_out = math.copysign(float('inf'), f1) + assert f_out == f2 + assert math.copysign(1., f_out) == math.copysign(1., f2) + + def test_float80_exact(self): + s = [] + ieee.pack_float80(s, -1., 16, False) + assert repr(s[-1]) == repr('\x00\x00\x00\x00\x00\x00\x00\x80\xff\xbf\x00\x00\x00\x00\x00\x00') + ieee.pack_float80(s, -1., 16, True) + assert repr(s[-1]) == repr('\x00\x00\x00\x00\x00\x00\xbf\xff\x80\x00\x00\x00\x00\x00\x00\x00') + ieee.pack_float80(s, -123.456, 16, False) + assert repr(s[-1]) == repr('\x00\xb8\xf3\xfd\xd4x\xe9\xf6\x05\xc0\x00\x00\x00\x00\x00\x00') + ieee.pack_float80(s, -123.456, 16, True) + assert repr(s[-1]) == repr('\x00\x00\x00\x00\x00\x00\xc0\x05\xf6\xe9x\xd4\xfd\xf3\xb8\x00') + + x = ieee.unpack_float80('\x00\x00\x00\x00\x00\x00\x00\x80\xff?\xc8\x01\x00\x00\x00\x00', False) + assert x == 1.0 + x = ieee.unpack_float80('\x00\x00\x7f\x83\xe1\x91?\xff\x80\x00\x00\x00\x00\x00\x00\x00', True) + assert x == 1.0 + + class TestFloatPacking: def setup_class(cls): if sys.version_info < (2, 6): @@ -15,25 +64,20 @@ def check_float(self, x): # check roundtrip - Q = ieee.float_pack(x, 8) - y = ieee.float_unpack(Q, 8) - assert repr(x) == repr(y), '%r != %r, Q=%r' % (x, y, Q) + for size in [10, 12, 16]: + for be in [False, True]: + Q = [] + ieee.pack_float80(Q, x, size, be) + Q = Q[0] + y = ieee.unpack_float80(Q, be) + assert repr(x) == repr(y), '%r != %r, Q=%r' % (x, y, Q) - Q = ieee.float_pack80(x) - y = ieee.float_unpack80(Q) - assert repr(x) == repr(y), '%r != %r, Q=%r' % (x, y, Q) - - Q = [] - ieee.pack_float(Q, x, 8, False) - Q = Q[0] - y = ieee.unpack_float(Q, False) - assert repr(x) == repr(y), '%r != %r, Q=%r' % (x, y, Q) - - Q = [] - ieee.pack_float80(Q, x, False) - Q = Q[0] - y = ieee.unpack_float80(Q, False) - assert repr(x) == repr(y), '%r != %r, Q=%r' % (x, y, Q) + for be in [False, True]: + Q = [] + ieee.pack_float(Q, x, 8, be) + Q = Q[0] + y = ieee.unpack_float(Q, be) + assert repr(x) == repr(y), '%r != %r, Q=%r' % (x, y, Q) # check that packing agrees with the struct module struct_pack8 = struct.unpack(' Author: Armin Rigo Branch: stm-thread-2 Changeset: r61318:1bf6c8d6fe7b Date: 2013-02-16 11:35 +0100 http://bitbucket.org/pypy/pypy/changeset/1bf6c8d6fe7b/ Log: Untested so far: attempt to fix signals for stm diff --git a/pypy/module/signal/__init__.py b/pypy/module/signal/__init__.py --- a/pypy/module/signal/__init__.py +++ b/pypy/module/signal/__init__.py @@ -47,5 +47,10 @@ space.check_signal_action = interp_signal.CheckSignalAction(space) space.actionflag.register_periodic_action(space.check_signal_action, use_bytecode_counter=False) - space.actionflag.__class__ = interp_signal.SignalActionFlag + # + if space.config.translation.stm: + from pypy.module.signal.stmactionflag import SignalActionFlag + else: + from pypy.module.signal.actionflag import SignalActionFlag + space.actionflag.__class__ = SignalActionFlag # xxx yes I know the previous line is a hack diff --git a/pypy/module/signal/actionflag.py b/pypy/module/signal/actionflag.py new file mode 100644 --- /dev/null +++ b/pypy/module/signal/actionflag.py @@ -0,0 +1,33 @@ +from pypy.interpreter.executioncontext import AbstractActionFlag +from rpython.rlib import jit +from rpython.rlib.rsignal import pypysig_getaddr_occurred + + +class SignalActionFlag(AbstractActionFlag): + # This class uses the C-level pypysig_counter variable as the tick + # counter. The C-level signal handler will reset it to -1 whenever + # a signal is received. This causes CheckSignalAction.perform() to + # be called. + + def get_ticker(self): + p = pypysig_getaddr_occurred() + return p.c_value + + def reset_ticker(self, value): + p = pypysig_getaddr_occurred() + p.c_value = value + + def rearm_ticker(self): + p = pypysig_getaddr_occurred() + p.c_value = -1 + + def decrement_ticker(self, by): + p = pypysig_getaddr_occurred() + value = p.c_value + if self.has_bytecode_counter: # this 'if' is constant-folded + if jit.isconstant(by) and by == 0: + pass # normally constant-folded too + else: + value -= by + p.c_value = value + return value diff --git a/pypy/module/signal/interp_signal.py b/pypy/module/signal/interp_signal.py --- a/pypy/module/signal/interp_signal.py +++ b/pypy/module/signal/interp_signal.py @@ -4,8 +4,7 @@ import sys from pypy.interpreter.error import OperationError, exception_from_errno -from pypy.interpreter.executioncontext import (AsyncAction, AbstractActionFlag, - PeriodicAsyncAction) +from pypy.interpreter.executioncontext import AsyncAction, PeriodicAsyncAction from pypy.interpreter.gateway import unwrap_spec from rpython.rlib import jit, rposix, rgc @@ -18,36 +17,6 @@ WIN32 = sys.platform == 'win32' -class SignalActionFlag(AbstractActionFlag): - # This class uses the C-level pypysig_counter variable as the tick - # counter. The C-level signal handler will reset it to -1 whenever - # a signal is received. This causes CheckSignalAction.perform() to - # be called. - - def get_ticker(self): - p = pypysig_getaddr_occurred() - return p.c_value - - def reset_ticker(self, value): - p = pypysig_getaddr_occurred() - p.c_value = value - - def rearm_ticker(self): - p = pypysig_getaddr_occurred() - p.c_value = -1 - - def decrement_ticker(self, by): - p = pypysig_getaddr_occurred() - value = p.c_value - if self.has_bytecode_counter: # this 'if' is constant-folded - if jit.isconstant(by) and by == 0: - pass # normally constant-folded too - else: - value -= by - p.c_value = value - return value - - class CheckSignalAction(PeriodicAsyncAction): """An action that is automatically invoked when a signal is received.""" diff --git a/pypy/module/signal/stmactionflag.py b/pypy/module/signal/stmactionflag.py new file mode 100644 --- /dev/null +++ b/pypy/module/signal/stmactionflag.py @@ -0,0 +1,28 @@ +from pypy.interpreter.executioncontext import AbstractActionFlag +from rpython.rlib import jit +from rpython.rlib.rsignal import pypysig_get_occurred, pypysig_set_occurred + + +class SignalActionFlag(AbstractActionFlag): + # This is mostly a copy of actionflag.py, but written in a way + # that doesn't force atomic transactions --- but isn't very JIT + # friendly yet. + + def get_ticker(self): + return pypysig_get_occurred() + + def reset_ticker(self, value): + pypysig_set_occurred(value) + + def rearm_ticker(self): + pypysig_set_occurred(-1) + + def decrement_ticker(self, by): + value = pypysig_get_occurred() + if self.has_bytecode_counter: # this 'if' is constant-folded + if jit.isconstant(by) and by == 0: + pass # normally constant-folded too + else: + value -= by + pypysig_set_occurred(value) + return value diff --git a/rpython/rlib/rsignal.py b/rpython/rlib/rsignal.py --- a/rpython/rlib/rsignal.py +++ b/rpython/rlib/rsignal.py @@ -45,7 +45,8 @@ 'pypysig_ignore', 'pypysig_setflag', 'pypysig_reinstall', 'pypysig_set_wakeup_fd', - 'pypysig_getaddr_occurred'], + 'pypysig_getaddr_occurred', + 'pypysig_get_occurred', 'pypysig_set_occurred'], ) class CConfig: @@ -93,6 +94,12 @@ lltype.Ptr(LONG_STRUCT), _nowrapper=True, transactionsafe=True, elidable_function=True) +pypysig_get_occurred = external('pypysig_get_occurred', [], lltype.Signed, + _nowrapper=True, + transactionsafe=True) +pypysig_set_occurred = external('pypysig_set_occurred', [lltype.Signed], + lltype.Void, _nowrapper=True, + transactionsafe=True) c_alarm = external('alarm', [rffi.INT], rffi.INT) c_pause = external('pause', [], rffi.INT, threadsafe=True) c_siginterrupt = external('siginterrupt', [rffi.INT, rffi.INT], rffi.INT) diff --git a/rpython/translator/c/src/signals.h b/rpython/translator/c/src/signals.h --- a/rpython/translator/c/src/signals.h +++ b/rpython/translator/c/src/signals.h @@ -26,4 +26,7 @@ void *pypysig_getaddr_occurred(void); #define pypysig_getaddr_occurred() ((void *)(&pypysig_counter)) +static long pypysig_get_occurred(void) { return pypysig_counter.value; } +static void pypysig_set_occurred(long value) { pypysig_counter.value = value; } + #endif From noreply at buildbot.pypy.org Sat Feb 16 12:19:15 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sat, 16 Feb 2013 12:19:15 +0100 (CET) Subject: [pypy-commit] pypy stm-thread-2: Fix Message-ID: <20130216111915.8AB081C094A@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stm-thread-2 Changeset: r61319:f7cc11bdaed8 Date: 2013-02-16 11:51 +0100 http://bitbucket.org/pypy/pypy/changeset/f7cc11bdaed8/ Log: Fix diff --git a/pypy/module/signal/stmactionflag.py b/pypy/module/signal/stmactionflag.py --- a/pypy/module/signal/stmactionflag.py +++ b/pypy/module/signal/stmactionflag.py @@ -1,5 +1,6 @@ from pypy.interpreter.executioncontext import AbstractActionFlag from rpython.rlib import jit +from rpython.rlib.objectmodel import we_are_translated from rpython.rlib.rsignal import pypysig_get_occurred, pypysig_set_occurred @@ -9,20 +10,28 @@ # friendly yet. def get_ticker(self): - return pypysig_get_occurred() + if we_are_translated(): + return pypysig_get_occurred() + else: + return 42 def reset_ticker(self, value): - pypysig_set_occurred(value) + if we_are_translated(): + pypysig_set_occurred(value) def rearm_ticker(self): - pypysig_set_occurred(-1) + if we_are_translated(): + pypysig_set_occurred(-1) def decrement_ticker(self, by): - value = pypysig_get_occurred() - if self.has_bytecode_counter: # this 'if' is constant-folded - if jit.isconstant(by) and by == 0: - pass # normally constant-folded too - else: - value -= by - pypysig_set_occurred(value) - return value + if we_are_translated(): + value = pypysig_get_occurred() + if self.has_bytecode_counter: # this 'if' is constant-folded + if jit.isconstant(by) and by == 0: + pass # normally constant-folded too + else: + value -= by + pypysig_set_occurred(value) + return value + else: + return 42 From noreply at buildbot.pypy.org Sat Feb 16 15:43:21 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sat, 16 Feb 2013 15:43:21 +0100 (CET) Subject: [pypy-commit] pypy stm-thread-2: Probably fix stm_PtrEq, to never cause transaction aborts. Message-ID: <20130216144321.489021C062C@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stm-thread-2 Changeset: r61321:effc55eb6a11 Date: 2013-02-16 15:43 +0100 http://bitbucket.org/pypy/pypy/changeset/effc55eb6a11/ Log: Probably fix stm_PtrEq, to never cause transaction aborts. diff --git a/rpython/translator/stm/src_stm/et.c b/rpython/translator/stm/src_stm/et.c --- a/rpython/translator/stm/src_stm/et.c +++ b/rpython/translator/stm/src_stm/et.c @@ -676,22 +676,95 @@ /************************************************************/ -inline static gcptr GlobalizeForComparison(struct tx_descriptor *d, gcptr P) +inline static _Bool _PtrEq_Globals(gcptr G1, gcptr G2) { - if (P != NULL && (P->h_tid & (GCFLAG_GLOBAL | GCFLAG_LOCAL_COPY))) + /* This is a bit lengthy, but (probably) efficient: the idea is to + check if G1 and G2 are pointers in the same chained list of globals + or not. Assumes no partial sharing in the chained lists. Works by + trying to search forward with S1, starting from G1, if it reaches + G2; and conversely with S2, starting from G2, if it reaches G1. */ + gcptr S1 = G1, S2 = G2; + volatile revision_t *vp; + revision_t v; + + while (1) { - if (P->h_tid & GCFLAG_GLOBAL) - P = LatestGlobalRevision(d, P, NULL, 0); - else - P = (gcptr)P->h_revision; // LOCAL_COPY: return the original global obj + if (S2 == G1) + return 1; + + /* move forward S1 */ + vp = (volatile revision_t *)&S1->h_revision; + v = *vp; + if (v & 1) // "is not a pointer", i.e. + goto s1_end; // "doesn't have a more recent revision" + S1 = (gcptr)v; + + if (S1 == G2) + return 1; + + /* move forward S2 */ + vp = (volatile revision_t *)&S2->h_revision; + v = *vp; + if (v & 1) // "is not a pointer", i.e. + goto s2_end; // "doesn't have a more recent revision" + S2 = (gcptr)v; } - return P; + + s1_end: + while (1) + { + /* move forward S2 */ + vp = (volatile revision_t *)&S2->h_revision; + v = *vp; + if (v & 1) // "is not a pointer", i.e. + return 0; // "doesn't have a more recent revision" + S2 = (gcptr)v; + + if (S2 == G1) + return 1; + } + + s2_end: + while (1) + { + /* move forward S1 */ + vp = (volatile revision_t *)&S1->h_revision; + v = *vp; + if (v & 1) // "is not a pointer", i.e. + return 0; // "doesn't have a more recent revision" + S1 = (gcptr)v; + + if (S1 == G2) + return 1; + } } _Bool stm_PtrEq(gcptr P1, gcptr P2) { - struct tx_descriptor *d = thread_descriptor; - return GlobalizeForComparison(d, P1) == GlobalizeForComparison(d, P2); + if (P1 == P2) + return 1; + else if (P1 == NULL || P2 == NULL) /* and not P1 == P2 == NULL */ + return 0; + + if (P1->h_tid & GCFLAG_GLOBAL) + { + if (P2->h_tid & GCFLAG_GLOBAL) + return _PtrEq_Globals(P1, P2); + else if (P2->h_tid & GCFLAG_LOCAL_COPY) + return _PtrEq_Globals(P1, (gcptr)P2->h_revision); + else + return 0; /* P1 is global, P2 is new */ + } + /* P1 is local, i.e. either new or a local copy */ + if (P2->h_tid & GCFLAG_GLOBAL) + { + if (P1->h_tid & GCFLAG_LOCAL_COPY) + return _PtrEq_Globals((gcptr)P1->h_revision, P2); + else + return 0; /* P1 is new, P2 is global */ + } + /* P1 and P2 are both locals (and P1 != P2) */ + return 0; } /************************************************************/ From noreply at buildbot.pypy.org Sat Feb 16 15:59:26 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sat, 16 Feb 2013 15:59:26 +0100 (CET) Subject: [pypy-commit] pypy stm-thread-2: Argh. Disable this cache if we are running with stm. Message-ID: <20130216145926.9BB8F1C07E1@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stm-thread-2 Changeset: r61322:b692761b4013 Date: 2013-02-16 15:58 +0100 http://bitbucket.org/pypy/pypy/changeset/b692761b4013/ Log: Argh. Disable this cache if we are running with stm. diff --git a/pypy/module/thread/os_local.py b/pypy/module/thread/os_local.py --- a/pypy/module/thread/os_local.py +++ b/pypy/module/thread/os_local.py @@ -19,6 +19,7 @@ @jit.dont_look_inside def __init__(self, space, initargs): + self.space = space self.initargs = initargs self.dicts = {} # mapping ExecutionContexts to the wraped dict # The app-level __init__() will be called by the general @@ -31,11 +32,16 @@ self.dicts[ec] = w_dict self._register_in_ec(ec) # cache the last seen dict, works because we are protected by the GIL - self.last_dict = w_dict - self.last_ec = ec + if self.can_cache(): + self.last_dict = w_dict + self.last_ec = ec + + def can_cache(self): + # can't cache with STM! The cache causes conflicts + return not self.space.config.translation.stm def _register_in_ec(self, ec): - if not ec.space.config.translation.rweakref: + if not self.space.config.translation.rweakref: return # without weakrefs, works but 'dicts' is never cleared if ec._thread_local_objs is None: ec._thread_local_objs = WRefShrinkList() @@ -44,7 +50,7 @@ @jit.dont_look_inside def create_new_dict(self, ec): # create a new dict for this thread - space = ec.space + space = self.space w_dict = space.newdict(instance=True) self.dicts[ec] = w_dict # call __init__ @@ -63,14 +69,15 @@ def getdict(self, space): ec = space.getexecutioncontext() - if ec is self.last_ec: + if self.can_cache() and ec is self.last_ec: return self.last_dict try: w_dict = self.dicts[ec] except KeyError: w_dict = self.create_new_dict(ec) - self.last_ec = ec - self.last_dict = w_dict + if self.can_cache(): + self.last_ec = ec + self.last_dict = w_dict return w_dict def descr_local__new__(space, w_subtype, __args__): diff --git a/pypy/module/thread/test/test_local.py b/pypy/module/thread/test/test_local.py --- a/pypy/module/thread/test/test_local.py +++ b/pypy/module/thread/test/test_local.py @@ -128,6 +128,7 @@ class config: class translation: rweakref = True + stm = False class FakeEC: def __init__(self, space): @@ -158,4 +159,3 @@ l.dicts = "nope" assert l.getdict(space) is d1 l.dicts = dicts - From noreply at buildbot.pypy.org Sat Feb 16 16:09:54 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sat, 16 Feb 2013 16:09:54 +0100 (CET) Subject: [pypy-commit] pypy stm-thread-2: Needs a become_inevitable() Message-ID: <20130216150954.E0D3C1C009B@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stm-thread-2 Changeset: r61323:d3c03a277e35 Date: 2013-02-16 16:09 +0100 http://bitbucket.org/pypy/pypy/changeset/d3c03a277e35/ Log: Needs a become_inevitable() diff --git a/pypy/module/signal/stmactionflag.py b/pypy/module/signal/stmactionflag.py --- a/pypy/module/signal/stmactionflag.py +++ b/pypy/module/signal/stmactionflag.py @@ -1,5 +1,5 @@ from pypy.interpreter.executioncontext import AbstractActionFlag -from rpython.rlib import jit +from rpython.rlib import jit, rstm from rpython.rlib.objectmodel import we_are_translated from rpython.rlib.rsignal import pypysig_get_occurred, pypysig_set_occurred @@ -17,6 +17,12 @@ def reset_ticker(self, value): if we_are_translated(): + # explicit manipulation of the counter needs to turn the + # transaction inevitable. We don't turn it inevitable in + # decrement_ticker() or if a real signal is received, but + # we turn it inevitable when this condition is detected + # and we reset a value >= 0. + rstm.become_inevitable() pypysig_set_occurred(value) def rearm_ticker(self): From noreply at buildbot.pypy.org Sat Feb 16 16:14:37 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sat, 16 Feb 2013 16:14:37 +0100 (CET) Subject: [pypy-commit] pypy stm-thread-2: Kill the section about signals. Message-ID: <20130216151437.A14FE1C009B@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stm-thread-2 Changeset: r61324:a821fcfdb066 Date: 2013-02-16 16:14 +0100 http://bitbucket.org/pypy/pypy/changeset/a821fcfdb066/ Log: Kill the section about signals. diff --git a/TODO b/TODO --- a/TODO +++ b/TODO @@ -3,32 +3,6 @@ ------------------------------------------------------------ -signal module: plan: - - signal handler: - - d = main thread's thread_descriptor - d->reads_size_limit = GOT_SIGNAL ( = -1) - this makes stm_should_break_transaction(d) return 1 - - - def _runs_normal_handler(): - if rstm.should_break_transaction(): - if d->reads_size_limit == GOT_SIGNAL: - checksignals() - return not rstm.should_break_transaction() - return False - return True - - - def checksignals(): - if d->reads_size_limit == GOT_SIGNAL: - turn inevitable - reset d->reads_size_limit - handle the signal - ------------------------------------------------------------- - after an abort, keep old global_to_local and access it using special code ------------------------------------------------------------ From noreply at buildbot.pypy.org Sat Feb 16 16:14:38 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sat, 16 Feb 2013 16:14:38 +0100 (CET) Subject: [pypy-commit] pypy stm-thread-2: Use __pypy__.thread.signals_enabled here. Message-ID: <20130216151438.EEF921C009B@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stm-thread-2 Changeset: r61325:92cea4991f95 Date: 2013-02-16 16:14 +0100 http://bitbucket.org/pypy/pypy/changeset/92cea4991f95/ Log: Use __pypy__.thread.signals_enabled here. diff --git a/lib_pypy/transaction.py b/lib_pypy/transaction.py --- a/lib_pypy/transaction.py +++ b/lib_pypy/transaction.py @@ -29,6 +29,17 @@ _atomic_global_lock.release() atomic = _Atomic() +try: + from __pypy__.thread import signals_enabled +except ImportError: + # Not a PyPy at all. + class _SignalsEnabled(object): + def __enter__(self): + pass + def __exit__(self, *args): + pass + signals_enabled = _SignalsEnabled() + def set_num_threads(num): """Set the number of threads to use.""" @@ -114,11 +125,7 @@ thread.start_new_thread(self._run_thread, ()) # now wait. When we manage to acquire the following lock, then # we are finished. - try: - acquire = self.lock_if_released_then_finished.acquire_interruptible - except AttributeError: # not on pypy-stm - acquire = self.lock_if_released_then_finished.acquire - acquire() + self.lock_if_released_then_finished.acquire() def teardown(self): self.in_transaction = False @@ -203,13 +210,14 @@ def _do_it((f, args, kwds), got_exception): # this is a staticmethod in order to make sure that we don't # accidentally use 'self' in the atomic block. - with atomic: - if got_exception: - return # return early if already an exception to reraise - try: - f(*args, **kwds) - except: - got_exception[:] = sys.exc_info() + try: + with signals_enabled: + with atomic: + if got_exception: + return # return early if already an exc. to reraise + f(*args, **kwds) + except: + got_exception[:] = sys.exc_info() _thread_pool = _ThreadPool() From noreply at buildbot.pypy.org Sat Feb 16 18:10:34 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sat, 16 Feb 2013 18:10:34 +0100 (CET) Subject: [pypy-commit] pypy default: Kill the _signalsenabled dictionary. Replace it by a value directly Message-ID: <20130216171034.817841C009B@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r61326:5f7c2b2fcddd Date: 2013-02-16 17:33 +0100 http://bitbucket.org/pypy/pypy/changeset/5f7c2b2fcddd/ Log: Kill the _signalsenabled dictionary. Replace it by a value directly on the ExecutionContext. This avoids stm issues. diff --git a/pypy/module/thread/threadlocals.py b/pypy/module/thread/threadlocals.py --- a/pypy/module/thread/threadlocals.py +++ b/pypy/module/thread/threadlocals.py @@ -1,5 +1,9 @@ from rpython.rlib import rthread -from pypy.interpreter.error import OperationError +from pypy.module.thread.error import wrap_thread_error +from pypy.interpreter.executioncontext import ExecutionContext + + +ExecutionContext._signals_enabled = 0 # default value class OSThreadLocals: @@ -10,12 +14,10 @@ def __init__(self): self._valuedict = {} # {thread_ident: ExecutionContext()} - self._signalsenabled = {} # {thread_ident: number-of-times} self._cleanup_() def _cleanup_(self): self._valuedict.clear() - self._signalsenabled.clear() self._mainthreadident = 0 self._mostrecentkey = 0 # fast minicaching for the common case self._mostrecentvalue = None # fast minicaching for the common case @@ -36,7 +38,7 @@ ident = rthread.get_ident() if value is not None: if len(self._valuedict) == 0: - self._signalsenabled[ident] = 1 # the main thread is enabled + value._signals_enabled = 1 # the main thread is enabled self._mainthreadident = ident self._valuedict[ident] = value else: @@ -44,33 +46,25 @@ del self._valuedict[ident] except KeyError: pass - try: - del self._signalsenabled[ident] - except KeyError: - pass # update the minicache to prevent it from containing an outdated value self._mostrecentkey = ident self._mostrecentvalue = value def signals_enabled(self): - return rthread.get_ident() in self._signalsenabled + ec = self.getvalue() + return ec._signals_enabled def enable_signals(self, space): - ident = rthread.get_ident() - old = self._signalsenabled.get(ident, 0) - self._signalsenabled[ident] = old + 1 + ec = self.getvalue() + ec._signals_enabled += 1 def disable_signals(self, space): - ident = rthread.get_ident() - try: - new = self._signalsenabled[ident] - 1 - except KeyError: - raise OperationError(space.w_KeyError, space.wrap( - "cannot disable signals in thread not enabled for signals")) - if new > 0: - self._signalsenabled[ident] = new - else: - del self._signalsenabled[ident] + ec = self.getvalue() + new = ec._signals_enabled - 1 + if new < 0: + raise wrap_thread_error(space, + "cannot disable signals in thread not enabled for signals") + ec._signals_enabled = new def getallvalues(self): return self._valuedict @@ -85,16 +79,10 @@ def reinit_threads(self, space): "Called in the child process after a fork()" - # clear the _signalsenabled dictionary for all other threads - # (which are now dead); and for the current thread, force an - # enable_signals() if necessary. That's a hack but I cannot - # figure out a non-hackish way to handle thread+signal+fork :-( ident = rthread.get_ident() - val = self.getvalue() - sig = self._signalsenabled.get(ident, 0) + ec = self.getvalue() if ident != self._mainthreadident: - sig += 1 + ec._signals_enabled += 1 self._cleanup_() - self.setvalue(val) - self._signalsenabled[ident] = sig + self.setvalue(ec) self._mainthreadident = ident From noreply at buildbot.pypy.org Sat Feb 16 18:10:35 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sat, 16 Feb 2013 18:10:35 +0100 (CET) Subject: [pypy-commit] pypy stm-thread-2: hg merge default Message-ID: <20130216171035.BF79C1C062C@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stm-thread-2 Changeset: r61327:65ec96e15463 Date: 2013-02-16 17:34 +0100 http://bitbucket.org/pypy/pypy/changeset/65ec96e15463/ Log: hg merge default diff --git a/pypy/interpreter/miscutils.py b/pypy/interpreter/miscutils.py --- a/pypy/interpreter/miscutils.py +++ b/pypy/interpreter/miscutils.py @@ -20,10 +20,10 @@ def signals_enabled(self): return True - def enable_signals(self): + def enable_signals(self, space): pass - def disable_signals(self): + def disable_signals(self, space): pass def getallvalues(self): diff --git a/pypy/module/__pypy__/interp_signal.py b/pypy/module/__pypy__/interp_signal.py --- a/pypy/module/__pypy__/interp_signal.py +++ b/pypy/module/__pypy__/interp_signal.py @@ -1,6 +1,6 @@ def signals_enter(space): - space.threadlocals.enable_signals() + space.threadlocals.enable_signals(space) def signals_exit(space, w_ignored1=None, w_ignored2=None, w_ignored3=None): - space.threadlocals.disable_signals() + space.threadlocals.disable_signals(space) diff --git a/pypy/module/__pypy__/test/test_signal.py b/pypy/module/__pypy__/test/test_signal.py --- a/pypy/module/__pypy__/test/test_signal.py +++ b/pypy/module/__pypy__/test/test_signal.py @@ -3,18 +3,6 @@ from pypy.module.thread.test.support import GenericTestThread -class TestThreadSignal: - spaceconfig = dict(usemodules=['__pypy__', 'thread']) - - def test_exit_twice(self, space): - from pypy.module.__pypy__.interp_signal import signals_exit, signals_enter - signals_exit(space) - try: - raises(KeyError, signals_exit, space) - finally: - signals_enter(space) - - class AppTestMinimal: spaceconfig = dict(usemodules=['__pypy__']) @@ -28,6 +16,14 @@ class AppTestThreadSignal(GenericTestThread): spaceconfig = dict(usemodules=['__pypy__', 'thread', 'signal', 'time']) + def test_exit_twice(self): + from __pypy__ import thread + thread._signals_exit() + try: + raises(KeyError, thread._signals_exit) + finally: + thread._signals_enter() + def test_enable_signals(self): import __pypy__, thread, signal, time diff --git a/pypy/module/thread/threadlocals.py b/pypy/module/thread/threadlocals.py --- a/pypy/module/thread/threadlocals.py +++ b/pypy/module/thread/threadlocals.py @@ -1,4 +1,9 @@ from rpython.rlib import rthread +from pypy.module.thread.error import wrap_thread_error +from pypy.interpreter.executioncontext import ExecutionContext + + +ExecutionContext._signals_enabled = 0 # default value class OSThreadLocals: @@ -11,12 +16,10 @@ def __init__(self): self._valuedict = {} # {thread_ident: ExecutionContext()} - self._signalsenabled = {} # {thread_ident: number-of-times} self._cleanup_() def _cleanup_(self): self._valuedict.clear() - self._signalsenabled.clear() self._mainthreadident = 0 if self.can_cache: self._mostrecentkey = 0 # fast minicaching for the common case @@ -39,7 +42,7 @@ ident = rthread.get_ident() if value is not None: if len(self._valuedict) == 0: - self._signalsenabled[ident] = 1 # the main thread is enabled + value._signals_enabled = 1 # the main thread is enabled self._mainthreadident = ident self._valuedict[ident] = value else: @@ -47,30 +50,26 @@ del self._valuedict[ident] except KeyError: pass - try: - del self._signalsenabled[ident] - except KeyError: - pass if self.can_cache: # update the minicache to prevent it from containing an outdated value self._mostrecentkey = ident self._mostrecentvalue = value def signals_enabled(self): - return rthread.get_ident() in self._signalsenabled + ec = self.getvalue() + return ec._signals_enabled - def enable_signals(self): - ident = rthread.get_ident() - old = self._signalsenabled.get(ident, 0) - self._signalsenabled[ident] = old + 1 + def enable_signals(self, space): + ec = self.getvalue() + ec._signals_enabled += 1 - def disable_signals(self): - ident = rthread.get_ident() - new = self._signalsenabled[ident] - 1 - if new > 0: - self._signalsenabled[ident] = new - else: - del self._signalsenabled[ident] + def disable_signals(self, space): + ec = self.getvalue() + new = ec._signals_enabled - 1 + if new < 0: + raise wrap_thread_error(space, + "cannot disable signals in thread not enabled for signals") + ec._signals_enabled = new def getallvalues(self): return self._valuedict @@ -85,14 +84,10 @@ def reinit_threads(self, space): "Called in the child process after a fork()" - # clear the _signalsenabled dictionary for all other threads - # (which are now dead); and for the current thread, force an - # enable_signals() if necessary. That's a hack but I cannot - # figure out a non-hackish way to handle thread+signal+fork :-( ident = rthread.get_ident() - old = self._signalsenabled.get(ident, 0) - if ident is not self._mainthreadident: - self._mainthreadident = ident - old += 1 - self._signalsenabled.clear() - self._signalsenabled[ident] = old + ec = self.getvalue() + if ident != self._mainthreadident: + ec._signals_enabled += 1 + self._cleanup_() + self.setvalue(ec) + self._mainthreadident = ident diff --git a/rpython/rlib/rstruct/ieee.py b/rpython/rlib/rstruct/ieee.py --- a/rpython/rlib/rstruct/ieee.py +++ b/rpython/rlib/rstruct/ieee.py @@ -255,6 +255,7 @@ l.reverse() result.append("".join(l)) + at jit.unroll_safe def unpack_float(s, be): unsigned = r_ulonglong(0) for i in range(min(len(s), 8)): @@ -262,6 +263,7 @@ unsigned |= r_ulonglong(c) << (i * 8) return float_unpack(unsigned, len(s)) + at jit.unroll_safe def unpack_float80(s, be): QQ = [r_ulonglong(0), r_ulonglong(0)] for i in range(8): From noreply at buildbot.pypy.org Sat Feb 16 19:48:54 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Sat, 16 Feb 2013 19:48:54 +0100 (CET) Subject: [pypy-commit] pypy default: (alex, arigo) Make sure this value is immutable, otherwise traces are suboptimal Message-ID: <20130216184854.0E3221C009B@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r61328:f8fe57996da9 Date: 2013-02-16 10:48 -0800 http://bitbucket.org/pypy/pypy/changeset/f8fe57996da9/ Log: (alex, arigo) Make sure this value is immutable, otherwise traces are suboptimal diff --git a/pypy/interpreter/pycode.py b/pypy/interpreter/pycode.py --- a/pypy/interpreter/pycode.py +++ b/pypy/interpreter/pycode.py @@ -53,16 +53,17 @@ kwargname = None return Signature(argnames, varargname, kwargname) + class PyCode(eval.Code): "CPython-style code objects." _immutable_ = True _immutable_fields_ = ["co_consts_w[*]", "co_names_w[*]", "co_varnames[*]", - "co_freevars[*]", "co_cellvars[*]"] + "co_freevars[*]", "co_cellvars[*]", "_args_as_cellvars[*]"] def __init__(self, space, argcount, nlocals, stacksize, flags, code, consts, names, varnames, filename, name, firstlineno, lnotab, freevars, cellvars, - hidden_applevel=False, magic = default_magic): + hidden_applevel=False, magic=default_magic): """Initialize a new code object from parameters given by the pypy compiler""" self.space = space @@ -89,8 +90,6 @@ def _initialize(self): self._init_flags() - # Precompute what arguments need to be copied into cellvars - self._args_as_cellvars = [] if self.co_cellvars: argcount = self.co_argcount @@ -108,16 +107,22 @@ # produced by CPython are loaded by PyPy. Note that CPython # contains the following bad-looking nested loops at *every* # function call! - argvars = self.co_varnames + + # Precompute what arguments need to be copied into cellvars + args_as_cellvars = [] + argvars = self.co_varnames cellvars = self.co_cellvars for i in range(len(cellvars)): cellname = cellvars[i] for j in range(argcount): if cellname == argvars[j]: # argument j has the same name as the cell var i - while len(self._args_as_cellvars) <= i: - self._args_as_cellvars.append(-1) # pad - self._args_as_cellvars[i] = j + while len(args_as_cellvars) <= i: + args_as_cellvars.append(-1) # pad + args_as_cellvars[i] = j + self._args_as_cellvars = args_as_cellvars[:] + else: + self._args_as_cellvars = [] self._compute_flatcall() From noreply at buildbot.pypy.org Sat Feb 16 21:46:50 2013 From: noreply at buildbot.pypy.org (fijal) Date: Sat, 16 Feb 2013 21:46:50 +0100 (CET) Subject: [pypy-commit] pypy default: fix Message-ID: <20130216204650.996AA1C0673@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r61329:9c21a81579d9 Date: 2013-02-16 11:09 +0000 http://bitbucket.org/pypy/pypy/changeset/9c21a81579d9/ Log: fix diff --git a/rpython/rlib/test/test_rarithmetic.py b/rpython/rlib/test/test_rarithmetic.py --- a/rpython/rlib/test/test_rarithmetic.py +++ b/rpython/rlib/test/test_rarithmetic.py @@ -395,13 +395,18 @@ assert not int_between(1, 2, 2) assert not int_between(1, 1, 1) +U1 = r_ulonglong(0x0102030405060708L) +U2 = r_ulonglong(0x0807060504030201L) +S1 = r_longlong(0x0102030405060708L) +S2 = r_longlong(0x0807060504030201L) + def test_byteswap(): from rpython.rtyper.lltypesystem import rffi, lltype assert rffi.cast(lltype.Signed, byteswap(rffi.cast(rffi.USHORT, 0x0102))) == 0x0201 assert rffi.cast(lltype.Signed, byteswap(rffi.cast(rffi.INT, 0x01020304))) == 0x04030201 - assert byteswap(r_ulonglong(0x0102030405060708L)) == r_ulonglong(0x0807060504030201L) - assert byteswap(r_longlong(0x0102030405060708L)) == r_longlong(0x0807060504030201L) + assert byteswap(U1) == U2 + assert byteswap(S1) == S2 assert ((byteswap(2.3) - 1.903598566252326e+185) / 1e185) < 0.000001 assert (rffi.cast(lltype.Float, byteswap(rffi.cast(lltype.SingleFloat, 2.3))) - 4.173496037651603e-08) < 1e-16 From noreply at buildbot.pypy.org Sat Feb 16 21:46:52 2013 From: noreply at buildbot.pypy.org (fijal) Date: Sat, 16 Feb 2013 21:46:52 +0100 (CET) Subject: [pypy-commit] pypy default: merge Message-ID: <20130216204652.132BB1C0673@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r61330:36e9ac53a32b Date: 2013-02-16 21:46 +0100 http://bitbucket.org/pypy/pypy/changeset/36e9ac53a32b/ Log: merge diff --git a/pypy/interpreter/pycode.py b/pypy/interpreter/pycode.py --- a/pypy/interpreter/pycode.py +++ b/pypy/interpreter/pycode.py @@ -53,16 +53,17 @@ kwargname = None return Signature(argnames, varargname, kwargname) + class PyCode(eval.Code): "CPython-style code objects." _immutable_ = True _immutable_fields_ = ["co_consts_w[*]", "co_names_w[*]", "co_varnames[*]", - "co_freevars[*]", "co_cellvars[*]"] + "co_freevars[*]", "co_cellvars[*]", "_args_as_cellvars[*]"] def __init__(self, space, argcount, nlocals, stacksize, flags, code, consts, names, varnames, filename, name, firstlineno, lnotab, freevars, cellvars, - hidden_applevel=False, magic = default_magic): + hidden_applevel=False, magic=default_magic): """Initialize a new code object from parameters given by the pypy compiler""" self.space = space @@ -89,8 +90,6 @@ def _initialize(self): self._init_flags() - # Precompute what arguments need to be copied into cellvars - self._args_as_cellvars = [] if self.co_cellvars: argcount = self.co_argcount @@ -108,16 +107,22 @@ # produced by CPython are loaded by PyPy. Note that CPython # contains the following bad-looking nested loops at *every* # function call! - argvars = self.co_varnames + + # Precompute what arguments need to be copied into cellvars + args_as_cellvars = [] + argvars = self.co_varnames cellvars = self.co_cellvars for i in range(len(cellvars)): cellname = cellvars[i] for j in range(argcount): if cellname == argvars[j]: # argument j has the same name as the cell var i - while len(self._args_as_cellvars) <= i: - self._args_as_cellvars.append(-1) # pad - self._args_as_cellvars[i] = j + while len(args_as_cellvars) <= i: + args_as_cellvars.append(-1) # pad + args_as_cellvars[i] = j + self._args_as_cellvars = args_as_cellvars[:] + else: + self._args_as_cellvars = [] self._compute_flatcall() diff --git a/pypy/module/signal/interp_signal.py b/pypy/module/signal/interp_signal.py --- a/pypy/module/signal/interp_signal.py +++ b/pypy/module/signal/interp_signal.py @@ -32,8 +32,7 @@ p = pypysig_getaddr_occurred() p.c_value = value - @staticmethod - def rearm_ticker(): + def rearm_ticker(self): p = pypysig_getaddr_occurred() p.c_value = -1 @@ -71,7 +70,7 @@ if self.fire_in_another_thread: if self.space.threadlocals.signals_enabled(): self.fire_in_another_thread = False - SignalActionFlag.rearm_ticker() + self.space.actionflag.rearm_ticker() # this occurs when we just switched to the main thread # and there is a signal pending: we force the ticker to # -1, which should ensure perform() is called quickly. diff --git a/pypy/module/thread/threadlocals.py b/pypy/module/thread/threadlocals.py --- a/pypy/module/thread/threadlocals.py +++ b/pypy/module/thread/threadlocals.py @@ -1,5 +1,9 @@ from rpython.rlib import rthread -from pypy.interpreter.error import OperationError +from pypy.module.thread.error import wrap_thread_error +from pypy.interpreter.executioncontext import ExecutionContext + + +ExecutionContext._signals_enabled = 0 # default value class OSThreadLocals: @@ -10,12 +14,10 @@ def __init__(self): self._valuedict = {} # {thread_ident: ExecutionContext()} - self._signalsenabled = {} # {thread_ident: number-of-times} self._cleanup_() def _cleanup_(self): self._valuedict.clear() - self._signalsenabled.clear() self._mainthreadident = 0 self._mostrecentkey = 0 # fast minicaching for the common case self._mostrecentvalue = None # fast minicaching for the common case @@ -36,7 +38,7 @@ ident = rthread.get_ident() if value is not None: if len(self._valuedict) == 0: - self._signalsenabled[ident] = 1 # the main thread is enabled + value._signals_enabled = 1 # the main thread is enabled self._mainthreadident = ident self._valuedict[ident] = value else: @@ -44,33 +46,25 @@ del self._valuedict[ident] except KeyError: pass - try: - del self._signalsenabled[ident] - except KeyError: - pass # update the minicache to prevent it from containing an outdated value self._mostrecentkey = ident self._mostrecentvalue = value def signals_enabled(self): - return rthread.get_ident() in self._signalsenabled + ec = self.getvalue() + return ec._signals_enabled def enable_signals(self, space): - ident = rthread.get_ident() - old = self._signalsenabled.get(ident, 0) - self._signalsenabled[ident] = old + 1 + ec = self.getvalue() + ec._signals_enabled += 1 def disable_signals(self, space): - ident = rthread.get_ident() - try: - new = self._signalsenabled[ident] - 1 - except KeyError: - raise OperationError(space.w_KeyError, space.wrap( - "cannot disable signals in thread not enabled for signals")) - if new > 0: - self._signalsenabled[ident] = new - else: - del self._signalsenabled[ident] + ec = self.getvalue() + new = ec._signals_enabled - 1 + if new < 0: + raise wrap_thread_error(space, + "cannot disable signals in thread not enabled for signals") + ec._signals_enabled = new def getallvalues(self): return self._valuedict @@ -85,16 +79,10 @@ def reinit_threads(self, space): "Called in the child process after a fork()" - # clear the _signalsenabled dictionary for all other threads - # (which are now dead); and for the current thread, force an - # enable_signals() if necessary. That's a hack but I cannot - # figure out a non-hackish way to handle thread+signal+fork :-( ident = rthread.get_ident() - val = self.getvalue() - sig = self._signalsenabled.get(ident, 0) + ec = self.getvalue() if ident != self._mainthreadident: - sig += 1 + ec._signals_enabled += 1 self._cleanup_() - self.setvalue(val) - self._signalsenabled[ident] = sig + self.setvalue(ec) self._mainthreadident = ident From noreply at buildbot.pypy.org Sat Feb 16 22:12:48 2013 From: noreply at buildbot.pypy.org (fijal) Date: Sat, 16 Feb 2013 22:12:48 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: cleanup Message-ID: <20130216211248.6B9E01C009B@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61331:c56108e2bdc3 Date: 2013-02-16 23:11 +0200 http://bitbucket.org/pypy/pypy/changeset/c56108e2bdc3/ Log: cleanup diff --git a/rpython/jit/backend/arm/opassembler.py b/rpython/jit/backend/arm/opassembler.py --- a/rpython/jit/backend/arm/opassembler.py +++ b/rpython/jit/backend/arm/opassembler.py @@ -1158,22 +1158,12 @@ assert result_loc.is_vfp_reg() # we always have a register here, since we have to sync them # before call_assembler - if not check_imm_arg(ofs): - self.mc.gen_load_int(r.ip.value, ofs) - self.mc.ADD_rr(r.ip.value, r.r0.value, r.ip.value) - ofs = 0 - base = r.ip - else: - base = r.r0 - self.mc.VLDR(result_loc.value, base.value, imm=ofs) + self.mc.VLDR(result_loc.value, r.r0.value, imm=ofs) else: assert result_loc is r.r0 ofs = self.cpu.unpack_arraydescr(descr) - if not check_imm_arg(ofs): - self.mc.gen_load_int(r.ip.value, ofs) - self.mc.LDR_rr(result_loc.value, result_loc.value, r.ip.value) - else: - self.mc.LDR_ri(result_loc.value, result_loc.value, imm=ofs) + assert check_imm_arg(ofs) + self.mc.LDR_ri(result_loc.value, result_loc.value, imm=ofs) def _call_assembler_patch_jmp(self, jmp_location): # merge point From noreply at buildbot.pypy.org Sat Feb 16 22:19:23 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sat, 16 Feb 2013 22:19:23 +0100 (CET) Subject: [pypy-commit] pypy default: make this test failure more obvious Message-ID: <20130216211923.E4FF61C009B@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61332:b5e96acf8bd1 Date: 2013-02-16 05:39 -0500 http://bitbucket.org/pypy/pypy/changeset/b5e96acf8bd1/ Log: make this test failure more obvious diff --git a/pypy/module/test_lib_pypy/numpypy/test_numpy.py b/pypy/module/test_lib_pypy/numpypy/test_numpy.py --- a/pypy/module/test_lib_pypy/numpypy/test_numpy.py +++ b/pypy/module/test_lib_pypy/numpypy/test_numpy.py @@ -10,9 +10,21 @@ import numpy # works after 'numpypy' has been imported def test_min_max_after_import(self): + import __builtin__ + from numpypy import * + assert min is __builtin__.min + assert max is __builtin__.max + assert min(1, 100) == 1 assert min(100, 1) == 1 assert max(1, 100) == 100 assert max(100, 1) == 100 + + assert min(4, 3, 2, 1) == 1 + assert max(1, 2, 3, 4) == 4 + + from numpypy import min, max + assert min is not __builtin__.min + assert max is not __builtin__.max From noreply at buildbot.pypy.org Sat Feb 16 22:19:25 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sat, 16 Feb 2013 22:19:25 +0100 (CET) Subject: [pypy-commit] pypy default: fix the test: this now raises a thread.error Message-ID: <20130216211925.44BB51C009B@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61333:b53715e21d4d Date: 2013-02-16 16:09 -0500 http://bitbucket.org/pypy/pypy/changeset/b53715e21d4d/ Log: fix the test: this now raises a thread.error diff --git a/pypy/module/__pypy__/test/test_signal.py b/pypy/module/__pypy__/test/test_signal.py --- a/pypy/module/__pypy__/test/test_signal.py +++ b/pypy/module/__pypy__/test/test_signal.py @@ -17,12 +17,12 @@ spaceconfig = dict(usemodules=['__pypy__', 'thread', 'signal', 'time']) def test_exit_twice(self): - from __pypy__ import thread - thread._signals_exit() + import __pypy__, thread + __pypy__.thread._signals_exit() try: - raises(KeyError, thread._signals_exit) + raises(thread.error, __pypy__.thread._signals_exit) finally: - thread._signals_enter() + __pypy__.thread._signals_enter() def test_enable_signals(self): import __pypy__, thread, signal, time From noreply at buildbot.pypy.org Sat Feb 16 22:19:26 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sat, 16 Feb 2013 22:19:26 +0100 (CET) Subject: [pypy-commit] pypy default: fix thread+fork+signals after _signalsenabled dict removal Message-ID: <20130216211926.896841C009B@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61334:6bf80dae95f7 Date: 2013-02-16 16:19 -0500 http://bitbucket.org/pypy/pypy/changeset/6bf80dae95f7/ Log: fix thread+fork+signals after _signalsenabled dict removal diff --git a/pypy/module/thread/threadlocals.py b/pypy/module/thread/threadlocals.py --- a/pypy/module/thread/threadlocals.py +++ b/pypy/module/thread/threadlocals.py @@ -37,7 +37,7 @@ def setvalue(self, value): ident = rthread.get_ident() if value is not None: - if len(self._valuedict) == 0: + if self._mainthreadident == 0: value._signals_enabled = 1 # the main thread is enabled self._mainthreadident = ident self._valuedict[ident] = value @@ -84,5 +84,5 @@ if ident != self._mainthreadident: ec._signals_enabled += 1 self._cleanup_() + self._mainthreadident = ident self.setvalue(ec) - self._mainthreadident = ident From noreply at buildbot.pypy.org Sat Feb 16 22:29:27 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Sat, 16 Feb 2013 22:29:27 +0100 (CET) Subject: [pypy-commit] pypy py3k: 2to3, fix fix fix Message-ID: <20130216212927.36FA11C009B@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61335:2664c3cf8d21 Date: 2013-02-16 13:17 -0800 http://bitbucket.org/pypy/pypy/changeset/2664c3cf8d21/ Log: 2to3, fix fix fix diff --git a/pypy/interpreter/app_main.py b/pypy/interpreter/app_main.py --- a/pypy/interpreter/app_main.py +++ b/pypy/interpreter/app_main.py @@ -689,7 +689,7 @@ executable = sys.pypy_find_executable(executable) stdlib_path = sys.pypy_find_stdlib(executable) if stdlib_path is None: - print >> sys.stderr, STDLIB_WARNING + print(STDLIB_WARNING, file=sys.stderr) else: sys.path[:] = stdlib_path # from this point on, we are free to use all the unicode stuff we want, diff --git a/pypy/interpreter/test2/test_app_main.py b/pypy/interpreter/test2/test_app_main.py --- a/pypy/interpreter/test2/test_app_main.py +++ b/pypy/interpreter/test2/test_app_main.py @@ -187,7 +187,6 @@ def test_sysflags(self): flags = ( ("debug", "-d", "1"), - ("py3k_warning", "-3", "1"), ("division_warning", "-Qwarn", "1"), ("division_warning", "-Qwarnall", "2"), ("division_new", "-Qnew", "1"), @@ -215,9 +214,9 @@ run_command='pass', **expected) def test_sysflags_envvar(self, monkeypatch): - monkeypatch.setenv('PYTHONNOUSERSITE', '1') expected = {"no_user_site": True} - self.check(['-c', 'pass'], {}, sys_argv=['-c'], run_command='pass', **expected) + self.check(['-c', 'pass'], {'PYTHONNOUSERSITE': '1'}, sys_argv=['-c'], + run_command='pass', **expected) class TestInteraction: @@ -251,10 +250,10 @@ child.logfile = sys.stdout return child - def spawn(self, argv): + def spawn(self, argv, env=None): # make sure that when we do 'import pypy' we get the correct package with setpythonpath(): - return self._spawn(python3, [app_main] + argv) + return self._spawn(python3, [app_main] + argv, env=env) def test_interactive(self): child = self.spawn([]) @@ -362,6 +361,7 @@ child.expect(re.escape(repr('NameError'))) def test_atexit(self): + skip("Python3 atexit is a builtin module") child = self.spawn([]) child.expect('>>> ') child.sendline('def f(): print("foobye")') @@ -399,7 +399,7 @@ child.expect('Traceback') child.expect('NameError') - def test_pythonstartup_file1(self, monkeypatch): + def test_pythonstartup_file1(self, monkeypatch, demo_script): monkeypatch.setenv('PYTHONPATH', None) monkeypatch.setenv('PYTHONSTARTUP', demo_script) child = self.spawn([]) @@ -413,7 +413,7 @@ child.expect('Traceback') child.expect('NameError') - def test_pythonstartup_file2(self, monkeypatch): + def test_pythonstartup_file2(self, monkeypatch, crashing_demo_script): monkeypatch.setenv('PYTHONPATH', None) monkeypatch.setenv('PYTHONSTARTUP', crashing_demo_script) child = self.spawn([]) @@ -447,8 +447,8 @@ def test_python_path_keeps_duplicates(self): old = os.environ.get('PYTHONPATH', '') try: - os.environ['PYTHONPATH'] = 'foobarbaz:foobarbaz' - child = self.spawn(['-c', 'import sys; print sys.path']) + child = self.spawn(['-c', 'import sys; print(sys.path)'], + env={'PYTHONPATH': 'foobarbaz:foobarbaz'}) child.expect(r"\['', 'foobarbaz', 'foobarbaz', ") finally: os.environ['PYTHONPATH'] = old @@ -457,7 +457,7 @@ old = os.environ.get('PYTHONPATH', '') try: os.environ['PYTHONPATH'] = 'foobarbaz' - child = self.spawn(['-E', '-c', 'import sys; print sys.path']) + child = self.spawn(['-E', '-c', 'import sys; print(sys.path)']) from pexpect import EOF index = child.expect(['foobarbaz', EOF]) assert index == 1 # no foobarbaz @@ -742,10 +742,11 @@ print 'POPEN:', cmdline child_in, child_out_err = os.popen4(cmdline) data = child_out_err.read(11) - assert data == '\x00[STDERR]\n\x00' # from stderr + # Py3 is always at least line buffered + assert data == '\x00(STDOUT)\n\x00' # from stdout child_in.close() data = child_out_err.read(11) - assert data == '\x00(STDOUT)\n\x00' # from stdout + assert data == '\x00[STDERR]\n\x00' # from stderr child_out_err.close() def test_non_interactive_stdout_unbuffered(self, monkeypatch): @@ -758,7 +759,7 @@ time.sleep(1) # stdout flushed automatically here """) - cmdline = '%s -E "%s" %s' % (sys.executable, app_main, path) + cmdline = '%s -E "%s" %s' % (python3, app_main, path) print 'POPEN:', cmdline child_in, child_out_err = os.popen4(cmdline) data = child_out_err.read(11) From noreply at buildbot.pypy.org Sat Feb 16 22:36:07 2013 From: noreply at buildbot.pypy.org (fijal) Date: Sat, 16 Feb 2013 22:36:07 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: disable debug when we're translated Message-ID: <20130216213607.7A6971C009B@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61336:b41f1cbf3d8f Date: 2013-02-16 23:35 +0200 http://bitbucket.org/pypy/pypy/changeset/b41f1cbf3d8f/ Log: disable debug when we're translated diff --git a/rpython/jit/backend/arm/assembler.py b/rpython/jit/backend/arm/assembler.py --- a/rpython/jit/backend/arm/assembler.py +++ b/rpython/jit/backend/arm/assembler.py @@ -69,6 +69,8 @@ def setup(self, looptoken): assert self.memcpy_addr != 0, 'setup_once() not called?' + if we_are_translated(): + self.debug = False self.current_clt = looptoken.compiled_loop_token self.mc = ARMv7Builder() self.pending_guards = [] From noreply at buildbot.pypy.org Sat Feb 16 23:40:56 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Sat, 16 Feb 2013 23:40:56 +0100 (CET) Subject: [pypy-commit] pypy py3k: update sys.flags: add quiet, remove others Message-ID: <20130216224056.E89EF1C009B@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61337:60025b983898 Date: 2013-02-16 14:38 -0800 http://bitbucket.org/pypy/pypy/changeset/60025b983898/ Log: update sys.flags: add quiet, remove others diff --git a/lib_pypy/_pypy_interact.py b/lib_pypy/_pypy_interact.py --- a/lib_pypy/_pypy_interact.py +++ b/lib_pypy/_pypy_interact.py @@ -4,7 +4,7 @@ import os -def interactive_console(mainmodule=None): +def interactive_console(mainmodule=None, quiet=False): # set sys.{ps1,ps2} just before invoking the interactive interpreter. This # mimics what CPython does in pythonrun.c if not hasattr(sys, 'ps1'): @@ -12,17 +12,18 @@ if not hasattr(sys, 'ps2'): sys.ps2 = '.... ' # - try: - from _pypy_irc_topic import some_topic - text = "And now for something completely different: ``%s''" % ( - some_topic(),) - while len(text) >= 80: - i = text[:80].rfind(' ') - print(text[:i]) - text = text[i+1:] - print(text) - except ImportError: - pass + if not quiet: + try: + from _pypy_irc_topic import some_topic + text = "And now for something completely different: ``%s''" % ( + some_topic(),) + while len(text) >= 80: + i = text[:80].rfind(' ') + print(text[:i]) + text = text[i+1:] + print(text) + except ImportError: + pass # try: if not os.isatty(sys.stdin.fileno()): diff --git a/pypy/interpreter/app_main.py b/pypy/interpreter/app_main.py --- a/pypy/interpreter/app_main.py +++ b/pypy/interpreter/app_main.py @@ -299,9 +299,7 @@ # Order is significant! sys_flags = ( "debug", - "py3k_warning", "division_warning", - "division_new", "inspect", "interactive", "optimize", @@ -309,10 +307,9 @@ "no_user_site", "no_site", "ignore_environment", - "tabcheck", "verbose", - "unicode", "bytes_warning", + "quiet", "hash_randomization", ) @@ -327,16 +324,6 @@ def simple_option(options, name, iterargv): options[name] += 1 -def div_option(options, div, iterargv): - if div == "warn": - options["division_warning"] = 1 - elif div == "warnall": - options["division_warning"] = 2 - elif div == "new": - options["division_new"] = 1 - elif div != "old": - raise CommandLineError("invalid division option: %r" % (div,)) - def c_option(options, runcmd, iterargv): options["run_command"] = runcmd return ['-c'] + list(iterargv) @@ -362,11 +349,10 @@ 'R': (simple_option, 'hash_randomization'), 's': (simple_option, 'no_user_site'), 'S': (simple_option, 'no_site'), - 't': (simple_option, 'tabcheck'), - 'U': (simple_option, 'unicode'), 'u': (simple_option, 'unbuffered'), 'b': (simple_option, 'bytes_warning'), 'v': (simple_option, 'verbose'), + 'q': (simple_option, 'quiet'), # more complex options 'c': (c_option, Ellipsis), '?': (print_help, None), @@ -376,7 +362,6 @@ 'W': (W_option, Ellipsis), 'V': (print_version, None), '--version': (print_version, None), - 'Q': (div_option, Ellipsis), '--info': (print_info, None), '--jit': (set_jit_option, Ellipsis), '--': (end_options, None), @@ -465,13 +450,8 @@ if we_are_translated(): flags = [options[flag] for flag in sys_flags] sys.flags = type(sys.flags)(flags) - sys.py3kwarning = bool(sys.flags.py3k_warning) sys.dont_write_bytecode = bool(sys.flags.dont_write_bytecode) - if sys.py3kwarning: - print("Warning: pypy does not implement py3k warnings", - file=sys.stderr) - ## if not we_are_translated(): ## for key in sorted(options): ## print '%40s: %s' % (key, options[key]) @@ -493,6 +473,7 @@ warnoptions, unbuffered, ignore_environment, + quiet, **ignored): # with PyPy in top of CPython we can only have around 100 # but we need more in the translated PyPy for the compiler package @@ -577,9 +558,11 @@ sys.path.insert(0, '') if interactive or sys.stdin.isatty(): - # If stdin is a tty or if "-i" is specified, we print - # a banner and run $PYTHONSTARTUP. - print_banner() + # If stdin is a tty or if "-i" is specified, we print a + # banner (unless "-q" was specified) and run + # $PYTHONSTARTUP. + if not quiet: + print_banner() python_startup = readenv and os.getenv('PYTHONSTARTUP') if python_startup: try: @@ -655,7 +638,7 @@ inteactive = False try: from _pypy_interact import interactive_console - success = run_toplevel(interactive_console, mainmodule) + success = run_toplevel(interactive_console, mainmodule, quiet) except SystemExit as e: status = e.code else: diff --git a/pypy/interpreter/test2/test_app_main.py b/pypy/interpreter/test2/test_app_main.py --- a/pypy/interpreter/test2/test_app_main.py +++ b/pypy/interpreter/test2/test_app_main.py @@ -129,26 +129,18 @@ self.check(['-S'], {}, sys_argv=[''], run_stdin=True, no_site=1) self.check(['-OO'], {}, sys_argv=[''], run_stdin=True, optimize=2) self.check(['-O', '-O'], {}, sys_argv=[''], run_stdin=True, optimize=2) - self.check(['-Qnew'], {}, sys_argv=[''], run_stdin=True, division_new=1) - self.check(['-Qold'], {}, sys_argv=[''], run_stdin=True, division_new=0) - self.check(['-Qwarn'], {}, sys_argv=[''], run_stdin=True, division_warning=1) - self.check(['-Qwarnall'], {}, sys_argv=[''], run_stdin=True, - division_warning=2) - self.check(['-Q', 'new'], {}, sys_argv=[''], run_stdin=True, division_new=1) - self.check(['-SOQnew'], {}, sys_argv=[''], run_stdin=True, - no_site=1, optimize=1, division_new=1) - self.check(['-SOQ', 'new'], {}, sys_argv=[''], run_stdin=True, - no_site=1, optimize=1, division_new=1) + self.check(['-SO'], {}, sys_argv=[''], run_stdin=True, + no_site=1, optimize=1) self.check(['-i'], {}, sys_argv=[''], run_stdin=True, interactive=1, inspect=1) self.check(['-?'], {}, output_contains='usage:') self.check(['-h'], {}, output_contains='usage:') - self.check(['-S', '-tO', '-h'], {}, output_contains='usage:') - self.check(['-S', '-thO'], {}, output_contains='usage:') - self.check(['-S', '-tO', '--help'], {}, output_contains='usage:') - self.check(['-S', '-tO', '--info'], {}, output_contains='translation') - self.check(['-S', '-tO', '--version'], {}, output_contains='Python') - self.check(['-S', '-tOV'], {}, output_contains='Python') + self.check(['-S', '-O', '-h'], {}, output_contains='usage:') + self.check(['-S', '-hO'], {}, output_contains='usage:') + self.check(['-S', '-O', '--help'], {}, output_contains='usage:') + self.check(['-S', '-O', '--info'], {}, output_contains='translation') + self.check(['-S', '-O', '--version'], {}, output_contains='Python') + self.check(['-S', '-OV'], {}, output_contains='Python') self.check(['--jit', 'foobar', '-S'], {}, sys_argv=[''], run_stdin=True, no_site=1) self.check(['-c', 'pass'], {}, sys_argv=['-c'], run_command='pass') @@ -187,9 +179,6 @@ def test_sysflags(self): flags = ( ("debug", "-d", "1"), - ("division_warning", "-Qwarn", "1"), - ("division_warning", "-Qwarnall", "2"), - ("division_new", "-Qnew", "1"), (["inspect", "interactive"], "-i", "1"), ("optimize", "-O", "1"), ("optimize", "-OO", "2"), @@ -197,10 +186,7 @@ ("no_user_site", "-s", "1"), ("no_site", "-S", "1"), ("ignore_environment", "-E", "1"), - ("tabcheck", "-t", "1"), - ("tabcheck", "-tt", "2"), ("verbose", "-v", "1"), - ("unicode", "-U", "1"), ("bytes_warning", "-b", "1"), ) for flag, opt, value in flags: @@ -729,6 +715,11 @@ assert 'hello world\n' in data assert '42\n' in data + def test_q_flag(self): + data = self.run('-iq', senddata='6*7\nraise SystemExit\n', + expect_prompt=True, expect_banner=False) + assert '42\n' in data + def test_non_interactive_stdout_fully_buffered(self): path = getscript(r""" import sys, time diff --git a/pypy/module/_warnings/interp_warnings.py b/pypy/module/_warnings/interp_warnings.py --- a/pypy/module/_warnings/interp_warnings.py +++ b/pypy/module/_warnings/interp_warnings.py @@ -15,11 +15,8 @@ def init_filters(self, space): filters_w = [] - if (not space.sys.get_flag('py3k_warning') and - not space.sys.get_flag('division_warning')): - filters_w.append(create_filter( - space, space.w_DeprecationWarning, "ignore")) - + filters_w.append(create_filter( + space, space.w_DeprecationWarning, "ignore")) filters_w.append(create_filter( space, space.w_PendingDeprecationWarning, "ignore")) filters_w.append(create_filter( diff --git a/pypy/module/sys/app.py b/pypy/module/sys/app.py --- a/pypy/module/sys/app.py +++ b/pypy/module/sys/app.py @@ -90,20 +90,17 @@ name = "sys.flags" debug = structseqfield(0) - py3k_warning = structseqfield(1) - division_warning = structseqfield(2) - division_new = structseqfield(3) - inspect = structseqfield(4) - interactive = structseqfield(5) - optimize = structseqfield(6) - dont_write_bytecode = structseqfield(7) - no_user_site = structseqfield(8) - no_site = structseqfield(9) - ignore_environment = structseqfield(10) - tabcheck = structseqfield(11) - verbose = structseqfield(12) - unicode = structseqfield(13) - bytes_warning = structseqfield(14) - hash_randomization = structseqfield(15) + division_warning = structseqfield(1) + inspect = structseqfield(2) + interactive = structseqfield(3) + optimize = structseqfield(4) + dont_write_bytecode = structseqfield(5) + no_user_site = structseqfield(6) + no_site = structseqfield(7) + ignore_environment = structseqfield(8) + verbose = structseqfield(9) + bytes_warning = structseqfield(10) + quiet = structseqfield(11) + hash_randomization = structseqfield(12) -null_sysflags = sysflags((0,)*16) +null_sysflags = sysflags((0,)*13) From noreply at buildbot.pypy.org Sat Feb 16 23:44:16 2013 From: noreply at buildbot.pypy.org (fijal) Date: Sat, 16 Feb 2013 23:44:16 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: disable the debug to have less assembler to read Message-ID: <20130216224416.383861C009B@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61338:4c8a7712012c Date: 2013-02-17 00:43 +0200 http://bitbucket.org/pypy/pypy/changeset/4c8a7712012c/ Log: disable the debug to have less assembler to read diff --git a/rpython/jit/backend/arm/assembler.py b/rpython/jit/backend/arm/assembler.py --- a/rpython/jit/backend/arm/assembler.py +++ b/rpython/jit/backend/arm/assembler.py @@ -42,7 +42,7 @@ class AssemblerARM(ResOpAssembler): - debug = True + debug = False def __init__(self, cpu, translate_support_code=False): ResOpAssembler.__init__(self, cpu, translate_support_code) From noreply at buildbot.pypy.org Sun Feb 17 01:51:13 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sun, 17 Feb 2013 01:51:13 +0100 (CET) Subject: [pypy-commit] pypy default: try to fix test_rarithmetic again, this time on 64bit Message-ID: <20130217005113.5E4081C009B@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61339:e589c0ef83d7 Date: 2013-02-16 19:50 -0500 http://bitbucket.org/pypy/pypy/changeset/e589c0ef83d7/ Log: try to fix test_rarithmetic again, this time on 64bit diff --git a/rpython/rlib/test/test_rarithmetic.py b/rpython/rlib/test/test_rarithmetic.py --- a/rpython/rlib/test/test_rarithmetic.py +++ b/rpython/rlib/test/test_rarithmetic.py @@ -15,7 +15,6 @@ #print machbits - class Test_r_int: def test__add__(self): self.binary_test(lambda x, y: x + y) @@ -57,7 +56,7 @@ res = f(arg) cmp = f(r_int(arg)) assert res == cmp - + def binary_test(self, f, rargs = None): if not rargs: rargs = (-10, -1, 3, 55) @@ -118,7 +117,7 @@ res = f(arg) & maxint_mask cmp = f(r_uint(arg)) assert res == cmp - + def binary_test(self, f, rargs = None, translated=False): mask = maxint_mask if not rargs: @@ -243,7 +242,7 @@ except OverflowError: pass else: - assert False + assert False try: ovfcheck(x+x) except OverflowError: @@ -261,7 +260,7 @@ except OverflowError: pass else: - assert False + assert False def test_ovfcheck_float_to_int(): assert ovfcheck_float_to_int(1.0) == 1 @@ -395,18 +394,17 @@ assert not int_between(1, 2, 2) assert not int_between(1, 1, 1) -U1 = r_ulonglong(0x0102030405060708L) -U2 = r_ulonglong(0x0807060504030201L) -S1 = r_longlong(0x0102030405060708L) -S2 = r_longlong(0x0807060504030201L) +# these can't be prebuilt on 32bit +L1 = 0x0102030405060708L +L2 = 0x0807060504030201L def test_byteswap(): from rpython.rtyper.lltypesystem import rffi, lltype - + assert rffi.cast(lltype.Signed, byteswap(rffi.cast(rffi.USHORT, 0x0102))) == 0x0201 assert rffi.cast(lltype.Signed, byteswap(rffi.cast(rffi.INT, 0x01020304))) == 0x04030201 - assert byteswap(U1) == U2 - assert byteswap(S1) == S2 + assert byteswap(rffi.cast(rffi.LONGLONG, L1)) == L2 + assert byteswap(rffi.cast(rffi.ULONGLONG, L1)) == L2 assert ((byteswap(2.3) - 1.903598566252326e+185) / 1e185) < 0.000001 assert (rffi.cast(lltype.Float, byteswap(rffi.cast(lltype.SingleFloat, 2.3))) - 4.173496037651603e-08) < 1e-16 From noreply at buildbot.pypy.org Sun Feb 17 03:00:23 2013 From: noreply at buildbot.pypy.org (bivab) Date: Sun, 17 Feb 2013 03:00:23 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: refactor load, store and move helper methods. Message-ID: <20130217020023.CCFCC1C062C@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: jitframe-on-heap Changeset: r61340:413242473067 Date: 2013-02-17 02:56 +0100 http://bitbucket.org/pypy/pypy/changeset/413242473067/ Log: refactor load, store and move helper methods. Use imm offsets for VLDR and VSTR if possible diff --git a/rpython/jit/backend/arm/assembler.py b/rpython/jit/backend/arm/assembler.py --- a/rpython/jit/backend/arm/assembler.py +++ b/rpython/jit/backend/arm/assembler.py @@ -949,47 +949,8 @@ faildescr._arm_failure_recovery_block = 0 # regalloc support - def load_reg(self, mc, target, base, ofs, cond=c.AL, helper=r.ip): - if target.is_vfp_reg(): - return self._load_vfp_reg(mc, target, base, ofs, cond) - elif target.is_reg(): - return self._load_core_reg(mc, target, base, ofs, cond) - - def _load_vfp_reg(self, mc, target, base, ofs, cond=c.AL, helper=r.ip): - if check_imm_arg(ofs): - mc.VLDR(target.value, base.value, imm=ofs, cond=cond) - else: - mc.gen_load_int(helper.value, ofs) - mc.VLDR(target.value, base.value, helper.value, cond=cond) - - def _load_core_reg(self, mc, target, base, ofs, cond=c.AL, helper=r.ip): - if check_imm_arg(ofs): - mc.LDR_ri(target.value, base.value, imm=ofs, cond=cond) - else: - mc.gen_load_int(helper.value, ofs) - mc.LDR_rr(target.value, base.value, helper.value, cond=cond) - - def store_reg(self, mc, source, base, ofs, cond=c.AL, helper=r.ip): - if source.is_vfp_reg(): - return self._store_vfp_reg(mc, source, base, ofs, cond) - else: - return self._store_core_reg(mc, source, base, ofs, cond) - - def _store_vfp_reg(self, mc, source, base, ofs, cond=c.AL, helper=r.ip): - if check_imm_arg(ofs): - mc.VSTR(source.value, base.value, imm=ofs, cond=cond) - else: - mc.gen_load_int(helper.value, ofs) - mc.VSTR(source.value, base.value, helper.value, cond=cond) - - def _store_core_reg(self, mc, source, base, ofs, cond=c.AL, helper=r.ip): - if check_imm_arg(ofs): - mc.STR_ri(source.value, base.value, imm=ofs, cond=cond) - else: - gen_load_int(helper.value, ofs) - mc.STR_rr(source.value, base.value, helper.value, cond=cond) - def load(self, loc, value): + """load an immediate value into a register""" assert (loc.is_reg() and value.is_imm() or loc.is_vfp_reg() and value.is_imm_float()) if value.is_imm(): @@ -998,6 +959,48 @@ self.mc.gen_load_int(r.ip.value, value.getint()) self.mc.VLDR(loc.value, r.ip.value) + def load_reg(self, mc, target, base, ofs, cond=c.AL, helper=r.ip): + if target.is_vfp_reg(): + return self._load_vfp_reg(mc, target, base, ofs, cond, helper) + elif target.is_reg(): + return self._load_core_reg(mc, target, base, ofs, cond, helper) + + def _load_vfp_reg(self, mc, target, base, ofs, cond=c.AL, helper=r.ip): + if check_imm_arg(ofs): + mc.VLDR(target.value, base.value, imm=ofs, cond=cond) + else: + mc.gen_load_int(helper.value, ofs, cond=cond) + mc.ADD_rr(helper.value, base.value, helper.value, cond=cond) + mc.VLDR(target.value, helper.value, cond=cond) + + def _load_core_reg(self, mc, target, base, ofs, cond=c.AL, helper=r.ip): + if check_imm_arg(ofs): + mc.LDR_ri(target.value, base.value, imm=ofs, cond=cond) + else: + mc.gen_load_int(helper.value, ofs, cond=cond) + mc.LDR_rr(target.value, base.value, helper.value, cond=cond) + + def store_reg(self, mc, source, base, ofs, cond=c.AL, helper=r.ip): + if source.is_vfp_reg(): + return self._store_vfp_reg(mc, source, base, ofs, cond, helper) + else: + return self._store_core_reg(mc, source, base, ofs, cond, helper) + + def _store_vfp_reg(self, mc, source, base, ofs, cond=c.AL, helper=r.ip): + if check_imm_arg(ofs): + mc.VSTR(source.value, base.value, imm=ofs, cond=cond) + else: + mc.gen_load_int(helper.value, ofs, cond=cond) + mc.ADD_rr(helper.value, base.value, helper.value, cond=cond) + mc.VSTR(source.value, helper.value, cond=cond) + + def _store_core_reg(self, mc, source, base, ofs, cond=c.AL, helper=r.ip): + if check_imm_arg(ofs): + mc.STR_ri(source.value, base.value, imm=ofs, cond=cond) + else: + mc.gen_load_int(helper.value, ofs, cond=cond) + mc.STR_rr(source.value, base.value, helper.value, cond=cond) + def _mov_imm_to_loc(self, prev_loc, loc, cond=c.AL): if not loc.is_reg() and not (loc.is_stack() and loc.type != FLOAT): raise AssertionError("invalid target for move from imm value") @@ -1025,15 +1028,12 @@ else: temp = r.ip offset = loc.value - if not check_imm_arg(offset, size=0xFFF): + is_imm = check_imm_arg(offset, size=0xFFF) + if not is_imm: self.mc.PUSH([temp.value], cond=cond) - self.mc.gen_load_int(temp.value, offset, cond=cond) - self.mc.STR_rr(prev_loc.value, r.fp.value, - temp.value, cond=cond) + self.store_reg(self.mc, prev_loc, r.fp, offset, helper=temp, cond=cond) + if not is_imm: self.mc.POP([temp.value], cond=cond) - else: - self.mc.STR_ri(prev_loc.value, r.fp.value, - imm=offset, cond=cond) else: assert 0, 'unsupported case' @@ -1046,29 +1046,22 @@ when moving from the stack' # unspill a core register offset = prev_loc.value - if not check_imm_arg(offset, size=0xFFF): + is_imm = check_imm_arg(offset, size=0xFFF) + if not is_imm: self.mc.PUSH([r.lr.value], cond=cond) - pushed = True - self.mc.gen_load_int(r.lr.value, offset, cond=cond) - self.mc.LDR_rr(loc.value, r.fp.value, r.lr.value, cond=cond) - else: - self.mc.LDR_ri(loc.value, r.fp.value, imm=offset, cond=cond) - if pushed: + self.load_reg(self.mc, loc, r.fp, offset, cond=cond, helper=r.lr) + if not is_imm: self.mc.POP([r.lr.value], cond=cond) elif loc.is_vfp_reg(): assert prev_loc.type == FLOAT, 'trying to load from an \ incompatible location into a float register' # load spilled value into vfp reg offset = prev_loc.value - self.mc.PUSH([r.ip.value], cond=cond) - pushed = True - if not check_imm_arg(offset): - self.mc.gen_load_int(r.ip.value, offset, cond=cond) - self.mc.ADD_rr(r.ip.value, r.fp.value, r.ip.value, cond=cond) - else: - self.mc.ADD_ri(r.ip.value, r.fp.value, offset, cond=cond) - self.mc.VLDR(loc.value, r.ip.value, cond=cond) - if pushed: + is_imm = check_imm_arg(offset) + if not is_imm: + self.mc.PUSH([r.ip.value], cond=cond) + self.load_reg(self.mc, loc, r.fp, offset, cond=cond, helper=r.ip) + if not is_imm: self.mc.POP([r.ip.value], cond=cond) else: assert 0, 'unsupported case' @@ -1077,7 +1070,7 @@ if loc.is_vfp_reg(): self.mc.PUSH([r.ip.value], cond=cond) self.mc.gen_load_int(r.ip.value, prev_loc.getint(), cond=cond) - self.mc.VLDR(loc.value, r.ip.value, cond=cond) + self.load_reg(self.mc, loc, r.ip, 0, cond=cond) self.mc.POP([r.ip.value], cond=cond) elif loc.is_stack(): self.regalloc_push(r.vfp_ip) @@ -1094,15 +1087,13 @@ assert loc.type == FLOAT, 'trying to store to an \ incompatible location from a float register' # spill vfp register - self.mc.PUSH([r.ip.value], cond=cond) offset = loc.value - if not check_imm_arg(offset): - self.mc.gen_load_int(r.ip.value, offset, cond=cond) - self.mc.ADD_rr(r.ip.value, r.fp.value, r.ip.value, cond=cond) - else: - self.mc.ADD_ri(r.ip.value, r.fp.value, offset, cond=cond) - self.mc.VSTR(prev_loc.value, r.ip.value, cond=cond) - self.mc.POP([r.ip.value], cond=cond) + is_imm = check_imm_arg(offset) + if not is_imm: + self.mc.PUSH([r.ip.value], cond=cond) + self.store_reg(self.mc, prev_loc, r.fp, offset, cond=cond) + if not is_imm: + self.mc.POP([r.ip.value], cond=cond) else: assert 0, 'unsupported case' @@ -1162,7 +1153,7 @@ elif vfp_loc.is_stack(): # move from two core registers to a float stack location offset = vfp_loc.value - if not check_imm_arg(offset, size=0xFFF): + if not check_imm_arg(offset + WORD, size=0xFFF): self.mc.PUSH([r.ip.value], cond=cond) self.mc.gen_load_int(r.ip.value, offset, cond=cond) self.mc.STR_rr(reg1.value, r.fp.value, r.ip.value, cond=cond) @@ -1170,7 +1161,6 @@ self.mc.STR_rr(reg2.value, r.fp.value, r.ip.value, cond=cond) self.mc.POP([r.ip.value], cond=cond) else: - assert 0, 'verify this code' self.mc.STR_ri(reg1.value, r.fp.value, imm=offset, cond=cond) self.mc.STR_ri(reg2.value, r.fp.value, imm=offset + WORD, cond=cond) diff --git a/rpython/jit/backend/arm/test/test_regalloc_mov.py b/rpython/jit/backend/arm/test/test_regalloc_mov.py --- a/rpython/jit/backend/arm/test/test_regalloc_mov.py +++ b/rpython/jit/backend/arm/test/test_regalloc_mov.py @@ -43,11 +43,11 @@ def stack(i, **kwargs): - return StackLocation(i, get_fp_offset(i), **kwargs) + return StackLocation(i, get_fp_offset(0, i), **kwargs) def stack_float(i, **kwargs): - return StackLocation(i, get_fp_offset(i + 1), type=FLOAT) + return StackLocation(i, get_fp_offset(0, i + 1), type=FLOAT) def imm_float(value): @@ -100,7 +100,7 @@ expected = [ mi('PUSH', [lr.value], cond=AL), mi('gen_load_int', lr.value, 100, cond=AL), - mi('STR_ri', lr.value, fp.value, imm=-s.value, cond=AL), + mi('STR_ri', lr.value, fp.value, imm=s.value, cond=AL), mi('POP', [lr.value], cond=AL)] self.mov(val, s, expected) @@ -110,7 +110,7 @@ expected = [ mi('PUSH', [lr.value], cond=AL), mi('gen_load_int', lr.value, 65536, cond=AL), - mi('STR_ri', lr.value, fp.value, imm=-s.value, cond=AL), + mi('STR_ri', lr.value, fp.value, imm=s.value, cond=AL), mi('POP', [lr.value], cond=AL)] self.mov(val, s, expected) @@ -121,7 +121,7 @@ expected = [mi('PUSH', [lr.value], cond=AL), mi('gen_load_int', lr.value, 100, cond=AL), mi('PUSH', [ip.value], cond=AL), - mi('gen_load_int', ip.value, -s.value, cond=AL), + mi('gen_load_int', ip.value, s.value, cond=AL), mi('STR_rr', lr.value, fp.value, ip.value, cond=AL), mi('POP', [ip.value], cond=AL), mi('POP', [lr.value], cond=AL)] @@ -133,7 +133,7 @@ expected = [mi('PUSH', [lr.value], cond=AL), mi('gen_load_int', lr.value, 65536, cond=AL), mi('PUSH', [ip.value], cond=AL), - mi('gen_load_int', ip.value, -s.value, cond=AL), + mi('gen_load_int', ip.value, s.value, cond=AL), mi('STR_rr', lr.value, fp.value, ip.value, cond=AL), mi('POP', [ip.value], cond=AL), mi('POP', [lr.value], cond=AL)] @@ -148,14 +148,14 @@ def test_mov_reg_to_stack(self): s = stack(10) r6 = r(6) - expected = [mi('STR_ri', r6.value, fp.value, imm=-s.value, cond=AL)] + expected = [mi('STR_ri', r6.value, fp.value, imm=s.value, cond=AL)] self.mov(r6, s, expected) def test_mov_reg_to_big_stackloc(self): s = stack(8191) r6 = r(6) expected = [mi('PUSH', [ip.value], cond=AL), - mi('gen_load_int', ip.value, -s.value, cond=AL), + mi('gen_load_int', ip.value, s.value, cond=AL), mi('STR_rr', r6.value, fp.value, ip.value, cond=AL), mi('POP', [ip.value], cond=AL)] self.mov(r6, s, expected) @@ -163,7 +163,7 @@ def test_mov_stack_to_reg(self): s = stack(10) r6 = r(6) - expected = [mi('LDR_ri', r6.value, fp.value, imm=-s.value, cond=AL)] + expected = [mi('LDR_ri', r6.value, fp.value, imm=s.value, cond=AL)] self.mov(s, r6, expected) def test_mov_big_stackloc_to_reg(self): @@ -171,7 +171,7 @@ r6 = r(6) expected = [ mi('PUSH', [lr.value], cond=AL), - mi('gen_load_int', lr.value, -s.value, cond=AL), + mi('gen_load_int', lr.value, s.value, cond=AL), mi('LDR_rr', r6.value, fp.value, lr.value, cond=AL), mi('POP', [lr.value], cond=AL)] self.mov(s, r6, expected) @@ -182,7 +182,7 @@ expected = [ mi('PUSH', [ip.value], cond=AL), mi('gen_load_int', ip.value, f.value, cond=AL), - mi('VLDR', 5, ip.value, cond=AL), + mi('VLDR', 5, ip.value, imm=0, cond=AL), mi('POP', [ip.value], cond=AL)] self.mov(f, reg, expected) @@ -195,10 +195,7 @@ def test_mov_vfp_reg_to_stack(self): reg = vfp(7) s = stack_float(3) - expected = [mi('PUSH', [ip.value], cond=AL), - mi('SUB_ri', ip.value, fp.value, s.value, cond=AL), - mi('VSTR', reg.value, ip.value, cond=AL), - mi('POP', [ip.value], cond=AL)] + expected = [mi('VSTR', reg.value, fp.value, imm=188, cond=AL)] self.mov(reg, s, expected) def test_mov_vfp_reg_to_large_stackloc(self): @@ -206,7 +203,7 @@ s = stack_float(800) expected = [mi('PUSH', [ip.value], cond=AL), mi('gen_load_int', ip.value, s.value, cond=AL), - mi('SUB_rr', ip.value, fp.value, ip.value, cond=AL), + mi('ADD_rr', ip.value, fp.value, ip.value, cond=AL), mi('VSTR', reg.value, ip.value, cond=AL), mi('POP', [ip.value], cond=AL)] self.mov(reg, s, expected) @@ -214,10 +211,7 @@ def test_mov_stack_to_vfp_reg(self): reg = vfp(7) s = stack_float(3) - expected = [mi('PUSH', [ip.value], cond=AL), - mi('SUB_ri', ip.value, fp.value, s.value, cond=AL), - mi('VLDR', reg.value, ip.value, cond=AL), - mi('POP', [ip.value], cond=AL)] + expected = [mi('VLDR', reg.value, fp.value, imm=188, cond=AL)] self.mov(s, reg, expected) def test_mov_big_stackloc_to_vfp_reg(self): @@ -225,7 +219,7 @@ s = stack_float(800) expected = [mi('PUSH', [ip.value], cond=AL), mi('gen_load_int', ip.value, s.value, cond=AL), - mi('SUB_rr', ip.value, fp.value, ip.value, cond=AL), + mi('ADD_rr', ip.value, fp.value, ip.value, cond=AL), mi('VSTR', reg.value, ip.value, cond=AL), mi('POP', [ip.value], cond=AL)] self.mov(reg, s, expected) @@ -304,8 +298,8 @@ r1 = r(1) r2 = r(2) e = [ - mi('LDR_ri', r1.value, fp.value, imm=-s.value, cond=AL), - mi('LDR_ri', r2.value, fp.value, imm=-s.value + WORD, cond=AL)] + mi('LDR_ri', r1.value, fp.value, imm=s.value, cond=AL), + mi('LDR_ri', r2.value, fp.value, imm=s.value + WORD, cond=AL)] self.mov(s, r1, r2, e) def test_from_big_vfp_stack(self): @@ -314,7 +308,7 @@ r2 = r(2) e = [ mi('PUSH', [ip.value], cond=AL), - mi('gen_load_int', ip.value, -s.value, cond=AL), + mi('gen_load_int', ip.value, s.value, cond=AL), mi('LDR_rr', r1.value, fp.value, ip.value, cond=AL), mi('ADD_ri', ip.value, ip.value, imm=WORD, cond=AL), mi('LDR_rr', r2.value, fp.value, ip.value, cond=AL), @@ -361,8 +355,8 @@ r1 = r(1) r2 = r(2) e = [ - mi('STR_ri', r1.value, fp.value, imm=-s.value, cond=AL), - mi('STR_ri', r2.value, fp.value, imm=-s.value + WORD, cond=AL)] + mi('STR_ri', r1.value, fp.value, imm=s.value, cond=AL), + mi('STR_ri', r2.value, fp.value, imm=s.value + WORD, cond=AL)] self.mov(r1, r2, s, e) def test_from_big_vfp_stack(self): @@ -371,7 +365,7 @@ r2 = r(2) e = [ mi('PUSH', [ip.value], cond=AL), - mi('gen_load_int', ip.value, -s.value, cond=AL), + mi('gen_load_int', ip.value, s.value, cond=AL), mi('STR_rr', r1.value, fp.value, ip.value, cond=AL), mi('ADD_ri', ip.value, ip.value, imm=4, cond=AL), mi('STR_rr', r2.value, fp.value, ip.value, cond=AL), @@ -411,7 +405,7 @@ f = imm_float(7) e = [mi('PUSH', [ip.value], cond=AL), mi('gen_load_int', ip.value, 7, cond=AL), - mi('VLDR', vfp_ip.value, ip.value, cond=AL), + mi('VLDR', vfp_ip.value, ip.value, imm=0, cond=AL), mi('POP', [ip.value], cond=AL), mi('VPUSH', [vfp_ip.value], cond=AL) ] @@ -419,7 +413,7 @@ def test_push_stack(self): s = stack(7) - e = [mi('LDR_ri', ip.value, fp.value, imm=-s.value, cond=AL), + e = [mi('LDR_ri', ip.value, fp.value, imm=s.value, cond=AL), mi('PUSH', [ip.value], cond=AL) ] self.push(s, e) @@ -427,7 +421,7 @@ def test_push_big_stack(self): s = stack(1025) e = [mi('PUSH', [lr.value], cond=AL), - mi('gen_load_int', lr.value, -s.value, cond=AL), + mi('gen_load_int', lr.value, s.value, cond=AL), mi('LDR_rr', ip.value, fp.value, lr.value, cond=AL), mi('POP', [lr.value], cond=AL), mi('PUSH', [ip.value], cond=AL) @@ -442,10 +436,7 @@ def test_push_stack_float(self): sf = stack_float(4) e = [ - mi('PUSH', [ip.value], cond=AL), - mi('SUB_ri', ip.value, fp.value, sf.value, cond=AL), - mi('VLDR', vfp_ip.value, ip.value, cond=AL), - mi('POP', [ip.value], cond=AL), + mi('VLDR', vfp_ip.value, fp.value, imm=192, cond=AL), mi('VPUSH', [vfp_ip.value], cond=AL), ] self.push(sf, e) @@ -455,7 +446,7 @@ e = [ mi('PUSH', [ip.value], cond=AL), mi('gen_load_int', ip.value, sf.value, cond=AL), - mi('SUB_rr', ip.value, fp.value, ip.value, cond=AL), + mi('ADD_rr', ip.value, fp.value, ip.value, cond=AL), mi('VLDR', vfp_ip.value, ip.value, cond=AL), mi('POP', [ip.value], cond=AL), mi('VPUSH', [vfp_ip.value], cond=AL), @@ -482,7 +473,7 @@ s = stack(12) e = [ mi('POP', [ip.value], cond=AL), - mi('STR_ri', ip.value, fp.value, imm=-s.value, cond=AL)] + mi('STR_ri', ip.value, fp.value, imm=s.value, cond=AL)] self.pop(s, e) def test_pop_big_stackloc(self): @@ -490,7 +481,7 @@ e = [ mi('POP', [ip.value], cond=AL), mi('PUSH', [lr.value], cond=AL), - mi('gen_load_int', lr.value, -s.value, cond=AL), + mi('gen_load_int', lr.value, s.value, cond=AL), mi('STR_rr', ip.value, fp.value, lr.value, cond=AL), mi('POP', [lr.value], cond=AL) ] @@ -500,10 +491,8 @@ s = stack_float(12) e = [ mi('VPOP', [vfp_ip.value], cond=AL), - mi('PUSH', [ip.value], cond=AL), - mi('SUB_ri', ip.value, fp.value, s.value, cond=AL), - mi('VSTR', vfp_ip.value, ip.value, cond=AL), - mi('POP', [ip.value], cond=AL)] + mi('VSTR', vfp_ip.value, fp.value, imm=s.value, cond=AL), + ] self.pop(s, e) def test_pop_big_float_stackloc(self): @@ -512,7 +501,7 @@ mi('VPOP', [vfp_ip.value], cond=AL), mi('PUSH', [ip.value], cond=AL), mi('gen_load_int', ip.value, s.value, cond=AL), - mi('SUB_rr', ip.value, fp.value, ip.value, cond=AL), + mi('ADD_rr', ip.value, fp.value, ip.value, cond=AL), mi('VSTR', vfp_ip.value, ip.value, cond=AL), mi('POP', [ip.value], cond=AL)] self.pop(s, e) From noreply at buildbot.pypy.org Sun Feb 17 03:00:25 2013 From: noreply at buildbot.pypy.org (bivab) Date: Sun, 17 Feb 2013 03:00:25 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: fix for call_assembler with floats. The offset calculation for the arguments to call_assembler in rewrite.py assumes a double-word aligned JITFRAME Message-ID: <20130217020025.1B8A11C062C@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: jitframe-on-heap Changeset: r61341:017892f48c74 Date: 2013-02-17 02:59 +0100 http://bitbucket.org/pypy/pypy/changeset/017892f48c74/ Log: fix for call_assembler with floats. The offset calculation for the arguments to call_assembler in rewrite.py assumes a double-word aligned JITFRAME diff --git a/rpython/jit/backend/arm/arch.py b/rpython/jit/backend/arm/arch.py --- a/rpython/jit/backend/arm/arch.py +++ b/rpython/jit/backend/arm/arch.py @@ -17,4 +17,4 @@ # A jitframe is a jit.backend.llsupport.llmodel.jitframe.JITFRAME # Stack frame fixed area # Currently only the force_index -JITFRAME_FIXED_SIZE = 11 + 16 * 2 # 11 GPR + 16 VFP Regs (64bit) +JITFRAME_FIXED_SIZE = 12 + 16 * 2 # 11 GPR + one word to keep alignment + 16 VFP Regs (64bit) diff --git a/rpython/jit/backend/llsupport/rewrite.py b/rpython/jit/backend/llsupport/rewrite.py --- a/rpython/jit/backend/llsupport/rewrite.py +++ b/rpython/jit/backend/llsupport/rewrite.py @@ -179,6 +179,9 @@ for i, arg in enumerate(arglist): descr = self.cpu.getarraydescr_for_frame(arg.type) _, itemsize, _ = self.cpu.unpack_arraydescr_size(descr) + # XXX + # this calculation breaks for floats on 32 bit if + # base_ofs of JITFRAME + index * 8 is not double-word aligned index = index_list[i] // itemsize # index is in bytes self.newops.append(ResOperation(rop.SETARRAYITEM_GC, [frame, ConstInt(index), From noreply at buildbot.pypy.org Sun Feb 17 06:13:02 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Sun, 17 Feb 2013 06:13:02 +0100 (CET) Subject: [pypy-commit] pypy default: remove some dead imports, some PEP8, general cleanups Message-ID: <20130217051302.6377A1C062C@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r61342:5d31d8fd913b Date: 2013-02-16 21:12 -0800 http://bitbucket.org/pypy/pypy/changeset/5d31d8fd913b/ Log: remove some dead imports, some PEP8, general cleanups diff --git a/rpython/rtyper/annlowlevel.py b/rpython/rtyper/annlowlevel.py --- a/rpython/rtyper/annlowlevel.py +++ b/rpython/rtyper/annlowlevel.py @@ -2,18 +2,18 @@ The code needed to flow and annotate low-level helpers -- the ll_*() functions """ -import types -from rpython.tool.sourcetools import valid_identifier from rpython.annotator import model as annmodel from rpython.annotator.policy import AnnotatorPolicy, Sig from rpython.annotator.specialize import flatten_star_args +from rpython.flowspace.model import Constant +from rpython.rlib.objectmodel import specialize +from rpython.rtyper import extregistry from rpython.rtyper.lltypesystem import lltype from rpython.rtyper.ootypesystem import ootype -from rpython.rtyper import extregistry -from rpython.flowspace.model import Constant +from rpython.rtyper.rmodel import warning +from rpython.tool.sourcetools import valid_identifier from rpython.translator.simplify import get_functype -from rpython.rtyper.rmodel import warning -from rpython.rlib.objectmodel import specialize + class KeyComp(object): def __init__(self, val): @@ -34,7 +34,7 @@ if compact is None: s = repr(val) else: - s = compact() + s = compact() return s + 'Const' __repr__ = __str__ @@ -90,7 +90,7 @@ args_s[:] = [l2a(a2l(s)) for s in args_s] return LowLevelAnnotatorPolicy.default_specialize(funcdesc, args_s) specialize__semierased = staticmethod(specialize__semierased) - + specialize__ll = default_specialize def specialize__ll_and_arg(funcdesc, args_s, *argindices): @@ -103,7 +103,7 @@ def annotate_lowlevel_helper(annotator, ll_function, args_s, policy=None): if policy is None: - policy= LowLevelAnnotatorPolicy() + policy = LowLevelAnnotatorPolicy() return annotator.annotate_helper(ll_function, args_s, policy) # ___________________________________________________________________ @@ -380,7 +380,7 @@ else: FUNC = F.TO resultcls = annmodel.SomePtr - + args_s = [annmodel.lltype_to_annotation(T) for T in FUNC.ARGS] key = (llhelper, s_callable.const) s_res = self.bookkeeper.emulate_pbc_call(key, s_callable, args_s) @@ -603,7 +603,7 @@ assert s.islower() def expand(s_self, *args_s): assert isinstance(s_self, annmodel.SomePtr) - return getattr(s_self.ll_ptrtype.TO, s.upper()) + return getattr(s_self.ll_ptrtype.TO, s.upper()) return expand def typemeth_placeholder_sigarg(s): @@ -622,10 +622,10 @@ def expand(s_TYPE, *args_s): assert isinstance(s_TYPE, annmodel.SomePBC) assert s_TYPE.is_constant() - return getattr(s_TYPE.const, s.upper()) + return getattr(s_TYPE.const, s.upper()) return expand - + class ADTInterface(object): def __init__(self, base, sigtemplates): diff --git a/rpython/rtyper/exceptiondata.py b/rpython/rtyper/exceptiondata.py --- a/rpython/rtyper/exceptiondata.py +++ b/rpython/rtyper/exceptiondata.py @@ -1,6 +1,6 @@ -from rpython.rtyper import rclass from rpython.annotator import model as annmodel from rpython.rlib import rstackovf +from rpython.rtyper import rclass # the exceptions that can be implicitely raised by some operations @@ -38,16 +38,16 @@ r_instance = rclass.getinstancerepr(rtyper, None) r_type.setup() r_instance.setup() - self.r_exception_type = r_type + self.r_exception_type = r_type self.r_exception_value = r_instance - self.lltype_of_exception_type = r_type.lowleveltype + self.lltype_of_exception_type = r_type.lowleveltype self.lltype_of_exception_value = r_instance.lowleveltype self.rtyper = rtyper def make_standard_exceptions(self, rtyper): bk = rtyper.annotator.bookkeeper for cls in self.standardexceptions: - classdef = bk.getuniqueclassdef(cls) + bk.getuniqueclassdef(cls) def finish(self, rtyper): bk = rtyper.annotator.bookkeeper diff --git a/rpython/rtyper/llinterp.py b/rpython/rtyper/llinterp.py --- a/rpython/rtyper/llinterp.py +++ b/rpython/rtyper/llinterp.py @@ -1,17 +1,20 @@ -from rpython.flowspace.model import FunctionGraph, Constant, Variable, c_last_exception -from rpython.rlib.rarithmetic import intmask, r_uint, ovfcheck, r_longlong, r_longlonglong -from rpython.rlib.rarithmetic import r_ulonglong, is_valid_int -from rpython.rtyper.lltypesystem import lltype, llmemory, lloperation, llheap -from rpython.rtyper.lltypesystem import rclass +import cStringIO +import os +import sys +import traceback + +import py + +from rpython.flowspace.model import (FunctionGraph, Constant, Variable, + c_last_exception) +from rpython.rlib import rstackovf +from rpython.rlib.objectmodel import (ComputedIntSymbolic, CDefinedIntSymbolic, + Symbolic) +# intmask is used in an exec'd code block +from rpython.rlib.rarithmetic import ovfcheck, is_valid_int, intmask +from rpython.rtyper.lltypesystem import lltype, llmemory, lloperation, llheap, rclass from rpython.rtyper.ootypesystem import ootype -from rpython.rlib.objectmodel import ComputedIntSymbolic, CDefinedIntSymbolic -from rpython.rlib.objectmodel import Symbolic -from rpython.rlib import rstackovf -import sys, os -import math -import py -import traceback, cStringIO log = py.log.Producer('llinterp') @@ -19,6 +22,7 @@ def __init__(self, *args): "NOT_RPYTHON" Exception.__init__(self, *args) + def __str__(self): etype = self.args[0] #evalue = self.args[1] @@ -42,7 +46,7 @@ return ''.join(etype.name).rstrip('\x00') else: # ootype! - return etype._INSTANCE._name.split(".")[-1] + return etype._INSTANCE._name.split(".")[-1] class LLInterpreter(object): """ low level interpreter working with concrete values. """ @@ -336,7 +340,7 @@ evalue = exc_data.exc_value if tracer: tracer.dump('raise') - exc_data.exc_type = lltype.typeOf(etype )._defl() + exc_data.exc_type = lltype.typeOf(etype)._defl() exc_data.exc_value = lltype.typeOf(evalue)._defl() from rpython.translator import exceptiontransform T = resultvar.concretetype @@ -641,7 +645,6 @@ if ITEMTYPE is not lltype.Void: array[index] = item - def perform_call(self, f, ARGS, args): fobj = self.llinterpreter.typer.type_system.deref(f) has_callable = getattr(fobj, '_callable', None) is not None @@ -652,11 +655,11 @@ return self.invoke_callable_with_pyexceptions(f, *args) args_v = graph.getargs() if len(ARGS) != len(args_v): - raise TypeError("graph with %d args called with wrong func ptr type: %r" %(len(args_v), ARGS)) + raise TypeError("graph with %d args called with wrong func ptr type: %r" %(len(args_v), ARGS)) for T, v in zip(ARGS, args_v): if not lltype.isCompatibleType(T, v.concretetype): raise TypeError("graph with %r args called with wrong func ptr type: %r" % - (tuple([v.concretetype for v in args_v]), ARGS)) + (tuple([v.concretetype for v in args_v]), ARGS)) frame = self.newsubframe(graph, args) return frame.eval() @@ -670,7 +673,7 @@ if graphs is not None: obj = self.llinterpreter.typer.type_system.deref(f) if hasattr(obj, 'graph'): - assert obj.graph in graphs + assert obj.graph in graphs else: pass #log.warn("op_indirect_call with graphs=None:", f) @@ -1052,7 +1055,7 @@ if x^y < 0 and x%%y != 0: r += 1 return r - '''%locals() + ''' % locals() elif operator == '%': ## overflow check on % does not work with emulated int code = '''%(checkfn)s(x // y) @@ -1060,9 +1063,9 @@ if x^y < 0 and x%%y != 0: r -= y return r - '''%locals() + ''' % locals() else: - code = 'return %(checkfn)s(x %(operator)s y)'%locals() + code = 'return %(checkfn)s(x %(operator)s y)' % locals() exec py.code.Source(""" def %(fn)s(self, x, y): assert isinstance(x, %(xtype)s) @@ -1094,7 +1097,7 @@ _makefunc2('op_lllong_floordiv_zer', '//', 'r_longlonglong') _makefunc2('op_lllong_mod_zer', '%', 'r_longlonglong') - + def op_int_add_nonneg_ovf(self, x, y): if isinstance(y, int): assert y >= 0 @@ -1114,9 +1117,9 @@ def op_check_and_clear_exc(self): exc_data = self.llinterpreter.get_transformed_exc_data(self.graph) assert exc_data - etype = exc_data.exc_type + etype = exc_data.exc_type evalue = exc_data.exc_value - exc_data.exc_type = lltype.typeOf(etype )._defl() + exc_data.exc_type = lltype.typeOf(etype)._defl() exc_data.exc_value = lltype.typeOf(evalue)._defl() return bool(etype) @@ -1125,7 +1128,7 @@ def op_new(self, INST): assert isinstance(INST, (ootype.Instance, ootype.BuiltinType)) return ootype.new(INST) - + def op_oonewarray(self, ARRAY, length): assert isinstance(ARRAY, ootype.Array) assert is_valid_int(length) @@ -1139,7 +1142,7 @@ eq_name, interp_eq = \ wrap_callable(self.llinterpreter, eq_func, eq_obj, eq_method_name) EQ_FUNC = ootype.StaticMethod([DICT._KEYTYPE, DICT._KEYTYPE], ootype.Bool) - sm_eq = ootype.static_meth(EQ_FUNC, eq_name, _callable=interp_eq) + sm_eq = ootype.static_meth(EQ_FUNC, eq_name, _callable=interp_eq) hash_name, interp_hash = \ wrap_callable(self.llinterpreter, hash_func, hash_obj, hash_method_name) diff --git a/rpython/rtyper/raddress.py b/rpython/rtyper/raddress.py --- a/rpython/rtyper/raddress.py +++ b/rpython/rtyper/raddress.py @@ -1,18 +1,18 @@ # rtyping of memory address operations -from rpython.tool.pairtype import pairtype from rpython.annotator import model as annmodel -from rpython.rtyper.lltypesystem.llmemory import NULL, Address, \ - cast_adr_to_int, fakeaddress, sizeof +from rpython.rlib.rarithmetic import r_uint +from rpython.rtyper.lltypesystem import lltype +from rpython.rtyper.lltypesystem.llmemory import (NULL, Address, + cast_adr_to_int, fakeaddress, sizeof) from rpython.rtyper.rmodel import Repr, IntegerRepr from rpython.rtyper.rptr import PtrRepr -from rpython.rtyper.lltypesystem import lltype -from rpython.rlib.rarithmetic import r_uint +from rpython.tool.pairtype import pairtype class __extend__(annmodel.SomeAddress): def rtyper_makerepr(self, rtyper): return address_repr - + def rtyper_makekey(self): return self.__class__, @@ -141,5 +141,3 @@ def convert_from_to((r_ptr, r_addr), v, llops): return llops.genop('cast_ptr_to_adr', [v], resulttype=Address) - - diff --git a/rpython/rtyper/rbool.py b/rpython/rtyper/rbool.py --- a/rpython/rtyper/rbool.py +++ b/rpython/rtyper/rbool.py @@ -1,14 +1,14 @@ +from rpython.annotator import model as annmodel +from rpython.rtyper.error import TyperError +from rpython.rtyper.lltypesystem.lltype import Signed, Unsigned, Bool, Float +from rpython.rtyper.rmodel import IntegerRepr, BoolRepr, log from rpython.tool.pairtype import pairtype -from rpython.annotator import model as annmodel -from rpython.rtyper.lltypesystem.lltype import Signed, Unsigned, Bool, Float -from rpython.rtyper.error import TyperError -from rpython.rtyper.rmodel import IntegerRepr, BoolRepr -from rpython.rtyper.rmodel import log class __extend__(annmodel.SomeBool): def rtyper_makerepr(self, rtyper): return bool_repr + def rtyper_makekey(self): return self.__class__, diff --git a/rpython/rtyper/rbuilder.py b/rpython/rtyper/rbuilder.py --- a/rpython/rtyper/rbuilder.py +++ b/rpython/rtyper/rbuilder.py @@ -1,7 +1,7 @@ +from rpython.annotator.model import SomeChar, SomeUnicodeCodePoint +from rpython.rlib.rstring import INIT_SIZE +from rpython.rtyper.lltypesystem import lltype from rpython.rtyper.rmodel import Repr -from rpython.rtyper.lltypesystem import lltype -from rpython.rlib.rstring import INIT_SIZE -from rpython.annotator.model import SomeChar, SomeUnicodeCodePoint class AbstractStringBuilderRepr(Repr): diff --git a/rpython/rtyper/rbytearray.py b/rpython/rtyper/rbytearray.py --- a/rpython/rtyper/rbytearray.py +++ b/rpython/rtyper/rbytearray.py @@ -1,9 +1,9 @@ +from rpython.annotator import model as annmodel +from rpython.rtyper.lltypesystem import lltype +from rpython.rtyper.rmodel import IntegerRepr +from rpython.rtyper.rstr import AbstractStringRepr +from rpython.tool.pairtype import pairtype -from rpython.annotator import model as annmodel -from rpython.tool.pairtype import pairtype -from rpython.rtyper.rstr import AbstractStringRepr -from rpython.rtyper.rmodel import IntegerRepr -from rpython.rtyper.lltypesystem import lltype class AbstractByteArrayRepr(AbstractStringRepr): pass diff --git a/rpython/rtyper/rclass.py b/rpython/rtyper/rclass.py --- a/rpython/rtyper/rclass.py +++ b/rpython/rtyper/rclass.py @@ -1,10 +1,9 @@ import types -from rpython.annotator import model as annmodel -#from rpython.annotator.classdef import isclassdef -from rpython.annotator import description + +from rpython.annotator import description, model as annmodel from rpython.rtyper.error import TyperError +from rpython.rtyper.lltypesystem.lltype import Void from rpython.rtyper.rmodel import Repr, getgcflavor, inputconst -from rpython.rtyper.lltypesystem.lltype import Void class FieldListAccessor(object): @@ -76,7 +75,7 @@ def buildinstancerepr(rtyper, classdef, gcflavor='gc'): from rpython.rlib.objectmodel import UnboxedValue from rpython.flowspace.model import Constant - + if classdef is None: unboxed = [] virtualizable2 = False @@ -137,7 +136,7 @@ if self.classdef.commonbase(subclassdef) != self.classdef: raise TyperError("not a subclass of %r: %r" % ( self.classdef.name, desc)) - + r_subclass = getclassrepr(self.rtyper, subclassdef) return r_subclass.getruntime(self.lowleveltype) @@ -170,12 +169,14 @@ class __extend__(annmodel.SomeInstance): def rtyper_makerepr(self, rtyper): return getinstancerepr(rtyper, self.classdef) + def rtyper_makekey(self): return self.__class__, self.classdef class __extend__(annmodel.SomeType): def rtyper_makerepr(self, rtyper): return get_type_repr(rtyper) + def rtyper_makekey(self): return self.__class__, @@ -390,8 +391,8 @@ s_unbound_attr = clsdef.find_attribute(meth_name).getvalue() s_attr = clsdef.lookup_filter(s_unbound_attr, meth_name, hop.args_s[0].flags) - if s_attr.is_constant(): - xxx # does that even happen? + # does that even happen? + assert not s_attr.is_constant() if '__iter__' in self.allinstancefields: raise Exception("__iter__ on instance disallowed") r_method = self.rtyper.makerepr(s_attr) diff --git a/rpython/rtyper/rcontrollerentry.py b/rpython/rtyper/rcontrollerentry.py --- a/rpython/rtyper/rcontrollerentry.py +++ b/rpython/rtyper/rcontrollerentry.py @@ -1,7 +1,7 @@ +from rpython.flowspace.model import Constant +from rpython.rtyper.error import TyperError +from rpython.rtyper.rmodel import Repr from rpython.tool.pairtype import pairtype -from rpython.flowspace.model import Constant -from rpython.rtyper.rmodel import Repr -from rpython.rtyper.error import TyperError class ControlledInstanceRepr(Repr): diff --git a/rpython/rtyper/rdict.py b/rpython/rtyper/rdict.py --- a/rpython/rtyper/rdict.py +++ b/rpython/rtyper/rdict.py @@ -1,6 +1,6 @@ from rpython.annotator import model as annmodel +from rpython.rtyper import rmodel from rpython.rtyper.lltypesystem import lltype -from rpython.rtyper import rmodel class __extend__(annmodel.SomeDict): @@ -83,4 +83,3 @@ return self.r_dict.recast_value(hop.llops, v) else: return v - diff --git a/rpython/rtyper/rexternalobj.py b/rpython/rtyper/rexternalobj.py --- a/rpython/rtyper/rexternalobj.py +++ b/rpython/rtyper/rexternalobj.py @@ -1,17 +1,11 @@ from rpython.annotator import model as annmodel +from rpython.rtyper import extregistry from rpython.rtyper.lltypesystem import lltype -from rpython.rtyper.ootypesystem import ootype -from rpython.rtyper.rmodel import Repr -from rpython.rtyper import rbuiltin -from rpython.flowspace.model import Constant, Variable -from rpython.rtyper import extregistry -from rpython.annotator.signature import annotation -from rpython.tool.pairtype import pairtype # ExternalObjects + class __extend__(annmodel.SomeExternalObject): - def rtyper_makerepr(self, rtyper): # delegate to the get_repr() of the extregistrered Entry class entry = extregistry.lookup_type(self.knowntype) @@ -25,4 +19,3 @@ if 'const_box' in attrs: del attrs['const_box'] return self.__class__, attrs - diff --git a/rpython/rtyper/rfloat.py b/rpython/rtyper/rfloat.py --- a/rpython/rtyper/rfloat.py +++ b/rpython/rtyper/rfloat.py @@ -1,21 +1,18 @@ +from rpython.annotator import model as annmodel +from rpython.rlib.objectmodel import _hash_float +from rpython.rlib.rarithmetic import base_int +from rpython.rtyper.error import TyperError +from rpython.rtyper.lltypesystem.lltype import (Signed, Unsigned, + SignedLongLong, UnsignedLongLong, Bool, Float) +from rpython.rtyper.rmodel import FloatRepr, IntegerRepr, BoolRepr, log +from rpython.rtyper.rstr import AbstractStringRepr from rpython.tool.pairtype import pairtype -from rpython.annotator import model as annmodel -from rpython.rtyper.lltypesystem.lltype import (Signed, Unsigned, SignedLongLong, - UnsignedLongLong, Bool, Float) -from rpython.rtyper.error import TyperError -from rpython.rtyper.rmodel import FloatRepr -from rpython.rtyper.rmodel import IntegerRepr, BoolRepr -from rpython.rtyper.rstr import AbstractStringRepr -from rpython.rtyper.rmodel import log -from rpython.rlib.rarithmetic import base_int -from rpython.rlib.objectmodel import _hash_float - -import math class __extend__(annmodel.SomeFloat): def rtyper_makerepr(self, rtyper): return float_repr + def rtyper_makekey(self): return self.__class__, diff --git a/rpython/rtyper/rgeneric.py b/rpython/rtyper/rgeneric.py --- a/rpython/rtyper/rgeneric.py +++ b/rpython/rtyper/rgeneric.py @@ -1,9 +1,9 @@ from rpython.annotator import model as annmodel +from rpython.rtyper.lltypesystem import lltype from rpython.rtyper.rmodel import Repr -from rpython.rtyper.rpbc import AbstractFunctionsPBCRepr,\ - AbstractMethodsPBCRepr +from rpython.rtyper.rpbc import AbstractFunctionsPBCRepr from rpython.tool.pairtype import pairtype -from rpython.rtyper.lltypesystem import lltype + class AbstractGenericCallableRepr(Repr): def __init__(self, rtyper, s_generic): @@ -20,7 +20,6 @@ return self.call('call_args', hop) def call(self, opname, hop): - bk = self.rtyper.annotator.bookkeeper vlist = hop.inputargs(self, *self.args_r) + [hop.inputconst(lltype.Void, None)] hop.exception_is_here() v_result = hop.genop('indirect_call', vlist, resulttype=self.r_result) From noreply at buildbot.pypy.org Sun Feb 17 11:02:02 2013 From: noreply at buildbot.pypy.org (fijal) Date: Sun, 17 Feb 2013 11:02:02 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: fix import Message-ID: <20130217100202.5D89B1C021F@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61343:4ae329d875a7 Date: 2013-02-17 12:01 +0200 http://bitbucket.org/pypy/pypy/changeset/4ae329d875a7/ Log: fix import diff --git a/rpython/jit/backend/x86/test/test_recompilation.py b/rpython/jit/backend/x86/test/test_recompilation.py --- a/rpython/jit/backend/x86/test/test_recompilation.py +++ b/rpython/jit/backend/x86/test/test_recompilation.py @@ -1,4 +1,4 @@ -from rpython.jit.backend.x86.test.test_regalloc import BaseTestRegalloc +from rpython.jit.backend.llsupport.test.test_regalloc_integration import BaseTestRegalloc from rpython.jit.backend.x86.arch import IS_X86_32, IS_X86_64 class TestRecompilation(BaseTestRegalloc): From noreply at buildbot.pypy.org Sun Feb 17 13:59:46 2013 From: noreply at buildbot.pypy.org (fijal) Date: Sun, 17 Feb 2013 13:59:46 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: maybe it's not such a bad idea to just waste a word and have simplified logic Message-ID: <20130217125946.59F861C021F@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61344:175ce157b84b Date: 2013-02-17 14:58 +0200 http://bitbucket.org/pypy/pypy/changeset/175ce157b84b/ Log: maybe it's not such a bad idea to just waste a word and have simplified logic diff --git a/rpython/jit/backend/arm/arch.py b/rpython/jit/backend/arm/arch.py --- a/rpython/jit/backend/arm/arch.py +++ b/rpython/jit/backend/arm/arch.py @@ -17,4 +17,5 @@ # A jitframe is a jit.backend.llsupport.llmodel.jitframe.JITFRAME # Stack frame fixed area # Currently only the force_index -JITFRAME_FIXED_SIZE = 12 + 16 * 2 # 11 GPR + one word to keep alignment + 16 VFP Regs (64bit) +JITFRAME_FIXED_SIZE = 11 + 16 * 2 + 1 +# 11 GPR + 16 VFP Regs (64bit) + 1 word for alignment diff --git a/rpython/jit/backend/llsupport/rewrite.py b/rpython/jit/backend/llsupport/rewrite.py --- a/rpython/jit/backend/llsupport/rewrite.py +++ b/rpython/jit/backend/llsupport/rewrite.py @@ -178,10 +178,8 @@ index_list = loop_token.compiled_loop_token._ll_initial_locs for i, arg in enumerate(arglist): descr = self.cpu.getarraydescr_for_frame(arg.type) + assert self.cpu.JITFRAME_FIXED_SIZE & 1 == 0 _, itemsize, _ = self.cpu.unpack_arraydescr_size(descr) - # XXX - # this calculation breaks for floats on 32 bit if - # base_ofs of JITFRAME + index * 8 is not double-word aligned index = index_list[i] // itemsize # index is in bytes self.newops.append(ResOperation(rop.SETARRAYITEM_GC, [frame, ConstInt(index), diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -2220,14 +2220,13 @@ # load the return value from the dead frame's value index 0 kind = op.result.type descr = self.cpu.getarraydescr_for_frame(kind) + ofs = self.cpu.unpack_arraydescr(descr) if kind == FLOAT: - ofs = self.cpu.unpack_arraydescr(descr) self.mc.MOVSD_xm(xmm0.value, (eax.value, ofs)) if result_loc is not xmm0: self.mc.MOVSD(result_loc, xmm0) else: assert result_loc is eax - ofs = self.cpu.unpack_arraydescr(descr) self.mc.MOV_rm(eax.value, (eax.value, ofs)) def _call_assembler_patch_jmp(self, jmp_location): From noreply at buildbot.pypy.org Sun Feb 17 14:03:41 2013 From: noreply at buildbot.pypy.org (fijal) Date: Sun, 17 Feb 2013 14:03:41 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: fix (I should refactor it actually) Message-ID: <20130217130341.2B73B1C021F@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61345:bf07804d5c75 Date: 2013-02-17 15:02 +0200 http://bitbucket.org/pypy/pypy/changeset/bf07804d5c75/ Log: fix (I should refactor it actually) diff --git a/rpython/jit/backend/arm/opassembler.py b/rpython/jit/backend/arm/opassembler.py --- a/rpython/jit/backend/arm/opassembler.py +++ b/rpython/jit/backend/arm/opassembler.py @@ -1177,13 +1177,15 @@ old_nbargs = oldlooptoken.compiled_loop_token._debug_nbargs new_nbargs = newlooptoken.compiled_loop_token._debug_nbargs assert old_nbargs == new_nbargs - # we overwrite the instructions at the old _arm_func_adddr + # we overwrite the instructions at the old _ll_function_addr # to start with a JMP to the new _ll_function_addr. # Ideally we should rather patch all existing CALLs, but well. - XXX # this is wrong, copy the logic from x86, but also, shouldn't - # it live on a base class instead? oldadr = oldlooptoken._ll_function_addr target = newlooptoken._ll_function_addr + # copy frame-info data + baseofs = self.cpu.get_baseofs_of_frame_field() + newlooptoken.compiled_loop_token.update_frame_info( + oldlooptoken.compiled_loop_token, baseofs) mc = ARMv7Builder() mc.B(target) mc.copy_to_raw_memory(oldadr) From noreply at buildbot.pypy.org Sun Feb 17 14:45:48 2013 From: noreply at buildbot.pypy.org (fijal) Date: Sun, 17 Feb 2013 14:45:48 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: unskip those tests Message-ID: <20130217134548.CAE211C009B@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61346:53c1547352e3 Date: 2013-02-17 15:06 +0200 http://bitbucket.org/pypy/pypy/changeset/53c1547352e3/ Log: unskip those tests diff --git a/rpython/jit/backend/arm/test/test_runner.py b/rpython/jit/backend/arm/test/test_runner.py --- a/rpython/jit/backend/arm/test/test_runner.py +++ b/rpython/jit/backend/arm/test/test_runner.py @@ -33,7 +33,6 @@ return cpu def test_result_is_spilled(self): - py.test.skip("later") cpu = self.cpu inp = [BoxInt(i) for i in range(1, 15)] out = [BoxInt(i) for i in range(1, 15)] @@ -67,7 +66,6 @@ assert output == expected def test_redirect_call_assembler2(self): - py.test.skip("later") def assembler_helper(deadframe, virtualizable): x = self.cpu.get_latest_value_int(deadframe, 0) assert x == 11 @@ -163,7 +161,6 @@ ('next', lltype.Ptr(SFloat))) def test_float_field(self): - py.test.skip("later") if not self.cpu.supports_floats: py.test.skip('requires floats') floatdescr = self.cpu.fielddescrof(self.SFloat, 'float') @@ -181,7 +178,6 @@ assert res.getfloat() == -3.6 def test_compile_loop_many_int_args(self): - py.test.skip("later") for numargs in range(2, 30): for _ in range(numargs): self.cpu.reserve_some_free_fail_descr_number() @@ -212,7 +208,6 @@ assert self.cpu.get_latest_value_int(deadframe, 0) == sum(args) def test_debugger_on(self): - py.test.skip("later") from rpython.rlib import debug targettoken, preambletoken = TargetToken(), TargetToken() From noreply at buildbot.pypy.org Sun Feb 17 14:45:50 2013 From: noreply at buildbot.pypy.org (fijal) Date: Sun, 17 Feb 2013 14:45:50 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: fix Message-ID: <20130217134550.0BDC61C0133@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61347:d384b9fd7cff Date: 2013-02-17 15:44 +0200 http://bitbucket.org/pypy/pypy/changeset/d384b9fd7cff/ Log: fix diff --git a/rpython/jit/metainterp/pyjitpl.py b/rpython/jit/metainterp/pyjitpl.py --- a/rpython/jit/metainterp/pyjitpl.py +++ b/rpython/jit/metainterp/pyjitpl.py @@ -1477,7 +1477,7 @@ jd.portal_finishtoken = tokens[0].finishdescr jd.propagate_exc_descr = exc_descr # - self.cpu.propagate_exc_descr = exc_descr + self.cpu.propagate_exception_descr = exc_descr # self.globaldata = MetaInterpGlobalData(self) From noreply at buildbot.pypy.org Sun Feb 17 15:30:04 2013 From: noreply at buildbot.pypy.org (stepahn) Date: Sun, 17 Feb 2013 15:30:04 +0100 (CET) Subject: [pypy-commit] lang-js default: deleted unused file Message-ID: <20130217143004.15FE71C021F@cobra.cs.uni-duesseldorf.de> Author: Stephan Branch: Changeset: r354:9ebc5003814d Date: 2013-02-17 15:29 +0100 http://bitbucket.org/pypy/lang-js/changeset/9ebc5003814d/ Log: deleted unused file diff --git a/js/newparser.py b/js/newparser.py deleted file mode 100644 --- a/js/newparser.py +++ /dev/null @@ -1,95 +0,0 @@ -from pypy.rlib.parsing.ebnfparse import parse_ebnf, make_parse_function -from pypy.rlib.parsing.parsing import ParseError, Rule -from pypy.rlib.parsing.tree import RPythonVisitor, Symbol -from js.jsobj import W_Number -from js import operations -import sys - -##try: -## t = open("jsgrammar.txt").read() -## regexs, rules, ToAST = parse_ebnf(t) -##except ParseError,e: -## print e.nice_error_message(filename="jsgrammar.txt",source=t) -## sys.exit(1) -## -##def setstartrule(rules, start): -## "takes the rule start and put it on the beginning of the rules" -## oldpos = 0 -## newrules = [Rule("hacked_first_symbol", [[start, "EOF"]])] + rules -## return newrules -## -##if len(sys.argv) == 1: -## parse = make_parse_function(regexs, rules, eof=True) -##else: -## parse = make_parse_function(regexs, setstartrule(rules,sys.argv[1]), eof=True) -## -##print rules[2].nonterminal -##source = raw_input() -##while source != "": -## t = parse(source).children[0].visit(ToAST())[0] -## print t -## t.view() -## source = raw_input() - -class EvalTreeBuilder(RPythonVisitor): - BINOP_TO_CLS = { - '+': operations.Plus, - '-': operations.Minus, - '*': operations.Mult, - '/': operations.Div, - '%': operations.Mod, - } - UNOP_TO_CLS = { - '+': operations.UPlus, - '-': operations.UMinus, - '++': operations.Increment, - '--': operations.Decrement, - } - def get_instance(self, symbol, cls): - assert isinstance(symbol, Symbol) - source_pos = symbol.token.source_pos - # XXX some of the source positions are not perfect - return cls(None, "no clue what self.type is used for", - symbol.additional_info, - source_pos.lineno, - source_pos.columnno, - source_pos.columnno + len(symbol.additional_info)) - - def visit_DECIMALLITERAL(self, node): - result = self.get_instance(node, operations.Number) - result.num = float(node.additional_info) - return result - - def string(self,node): - print node.additional_info - result = self.get_instance(node, operations.String) - result.strval = node.additional_info[1:-1] #XXX should do unquoting - return result - - visit_DOUBLESTRING = string - visit_SINGLESTRING = string - - def binaryop(self, node): - left = self.dispatch(node.children[0]) - for i in range((len(node.children) - 1) // 2): - op = node.children[i * 2 + 1] - result = self.get_instance( - op, self.BINOP_TO_CLS[op.additional_info]) - right = self.dispatch(node.children[i * 2 + 2]) - result.left = left - result.right = right - left = result - return left - - visit_additiveexpression = binaryop - visit_multiplicativeexpression = binaryop - - def visit_unaryexpression(self, node): - op = node.children[0] - result = self.get_instance( - op, self.UNOP_TO_CLS[op.additional_info]) - child = self.dispatch(node.children[1]) - result.expr = child - result.postfix = False - return result - From noreply at buildbot.pypy.org Sun Feb 17 15:30:05 2013 From: noreply at buildbot.pypy.org (stepahn) Date: Sun, 17 Feb 2013 15:30:05 +0100 (CET) Subject: [pypy-commit] lang-js default: updated imports from pypy to rpython Message-ID: <20130217143005.66E591C021F@cobra.cs.uni-duesseldorf.de> Author: Stephan Branch: Changeset: r355:09ec22ba4517 Date: 2013-02-17 15:29 +0100 http://bitbucket.org/pypy/lang-js/changeset/09ec22ba4517/ Log: updated imports from pypy to rpython diff --git a/js/astbuilder.py b/js/astbuilder.py --- a/js/astbuilder.py +++ b/js/astbuilder.py @@ -1,6 +1,6 @@ -from pypy.rlib.rarithmetic import ovfcheck_float_to_int -from pypy.rlib.parsing.tree import RPythonVisitor, Symbol -from pypy.rlib.objectmodel import enforceargs +from rpython.rlib.rarithmetic import ovfcheck_float_to_int +from rpython.rlib.parsing.tree import RPythonVisitor, Symbol +from rpython.rlib.objectmodel import enforceargs from js import operations diff --git a/js/baseop.py b/js/baseop.py --- a/js/baseop.py +++ b/js/baseop.py @@ -5,8 +5,8 @@ from js.jsobj import W_String, W_IntNumber, W_FloatNumber from js.object_space import _w -from pypy.rlib.rarithmetic import ovfcheck -from pypy.rlib.rfloat import isnan, isinf +from rpython.rlib.rarithmetic import ovfcheck +from rpython.rlib.rfloat import isnan, isinf from js.builtins.number import w_NAN, w_POSITIVE_INFINITY, w_NEGATIVE_INFINITY import math diff --git a/js/builtins/date.py b/js/builtins/date.py --- a/js/builtins/date.py +++ b/js/builtins/date.py @@ -1,9 +1,9 @@ -from pypy.rlib.rfloat import NAN, isnan +from rpython.rlib.rfloat import NAN, isnan +from rpython.rlib.objectmodel import we_are_translated import datetime from js.builtins import get_arg from js.object_space import w_return, hide_on_translate, _w -from pypy.rlib.objectmodel import we_are_translated def setup(global_object): diff --git a/js/builtins/js_global.py b/js/builtins/js_global.py --- a/js/builtins/js_global.py +++ b/js/builtins/js_global.py @@ -1,16 +1,16 @@ # -*- coding: utf-8 -*- -from pypy.rlib.rfloat import NAN, INFINITY, isnan, isinf +from rpython.rlib.rfloat import NAN, INFINITY, isnan, isinf from js.builtins import get_arg from js.object_space import w_return from pypy.module.unicodedata import unicodedb def setup(global_object): + from rpython.rlib.objectmodel import we_are_translated from js.builtins import put_intimate_function, put_native_function, put_property from js.builtins.number import w_NAN from js.builtins.number import w_POSITIVE_INFINITY - from pypy.rlib.objectmodel import we_are_translated from js.object_space import newundefined # 15.1.1.1 @@ -167,7 +167,7 @@ try: number = int(num_str, r) try: - from pypy.rlib.rarithmetic import ovfcheck_float_to_int + from rpython.rlib.rarithmetic import ovfcheck_float_to_int ovfcheck_float_to_int(number) except OverflowError: number = float(number) @@ -221,7 +221,7 @@ if len(args) == 0: return - from pypy.rlib.rstring import UnicodeBuilder + from rpython.rlib.rstring import UnicodeBuilder from js.runistr import encode_unicode_utf8 builder = UnicodeBuilder() @@ -336,13 +336,14 @@ # 15.1.2.1 def js_eval(ctx): + from rpython.rlib.parsing.parsing import ParseError + from rpython.rlib.parsing.deterministic import LexerError + from js.astbuilder import parse_to_ast from js.jscode import ast_to_bytecode from js.jsobj import W_String from js.functions import JsEvalCode from js.execution_context import EvalExecutionContext - from pypy.rlib.parsing.parsing import ParseError - from pypy.rlib.parsing.deterministic import LexerError from js.astbuilder import FakeParseError from js.exception import JsSyntaxError diff --git a/js/builtins/js_math.py b/js/builtins/js_math.py --- a/js/builtins/js_math.py +++ b/js/builtins/js_math.py @@ -1,6 +1,6 @@ import math -from pypy.rlib.rfloat import NAN, INFINITY, isnan, isinf +from rpython.rlib.rfloat import NAN, INFINITY, isnan, isinf from js.builtins import get_arg from js.object_space import w_return, _w @@ -429,7 +429,7 @@ return math.exp(x) import time -from pypy.rlib import rrandom +from rpython.rlib import rrandom random = rrandom.Random(int(time.time())) diff --git a/js/builtins/number.py b/js/builtins/number.py --- a/js/builtins/number.py +++ b/js/builtins/number.py @@ -1,4 +1,4 @@ -from pypy.rlib.rfloat import NAN, INFINITY +from rpython.rlib.rfloat import NAN, INFINITY from js.exception import JsRangeError, JsTypeError from js.jsobj import W_Number, W_NumericObject from js.object_space import w_return, _w diff --git a/js/builtins/string.py b/js/builtins/string.py --- a/js/builtins/string.py +++ b/js/builtins/string.py @@ -1,9 +1,10 @@ +from rpython.rlib.rfloat import NAN +from rpython.rlib.rstring import UnicodeBuilder + from js.jsobj import W_String, W_StringObject -from pypy.rlib.rfloat import NAN from js.exception import JsTypeError from js.builtins import get_arg from js.object_space import w_return, _w -from pypy.rlib.rstring import UnicodeBuilder def setup(global_object): @@ -181,7 +182,7 @@ search_str = search_string.to_string() num_pos = position.ToNumber() - from pypy.rlib.rfloat import INFINITY, isnan, isinf + from rpython.rlib.rfloat import INFINITY, isnan, isinf if isnan(num_pos): pos = INFINITY diff --git a/js/constants.py b/js/constants.py --- a/js/constants.py +++ b/js/constants.py @@ -1,4 +1,4 @@ -from pypy.rlib.rsre.rsre_re import compile +from rpython.rlib.rsre.rsre_re import compile num_lit_exp = r'(?:[+-]?((?:(?:\d+)(?:\.\d*)?)|Infinity|(?:\.[0-9]+))(?:[eE][\+\-]?[0-9]*)?)' num_lit_rexp = compile(num_lit_exp) diff --git a/js/execution_context.py b/js/execution_context.py --- a/js/execution_context.py +++ b/js/execution_context.py @@ -1,6 +1,6 @@ from js.utils import StackMixin from js.object_space import newundefined -from pypy.rlib import jit +from rpython.rlib import jit class ExecutionContext(StackMixin): diff --git a/js/interpreter.py b/js/interpreter.py --- a/js/interpreter.py +++ b/js/interpreter.py @@ -1,4 +1,4 @@ -from pypy.rlib.streamio import open_file_as_stream +from rpython.rlib.streamio import open_file_as_stream def load_file(filename): diff --git a/js/jscode.py b/js/jscode.py --- a/js/jscode.py +++ b/js/jscode.py @@ -1,6 +1,6 @@ #from pypy.rlib.jit import hint #from pypy.rlib.objectmodel import we_are_translated -from pypy.rlib import jit +from rpython.rlib import jit from js.exception import JsThrowException from js.opcodes import opcodes, LABEL, BaseJump diff --git a/js/jsobj.py b/js/jsobj.py --- a/js/jsobj.py +++ b/js/jsobj.py @@ -1,14 +1,13 @@ # encoding: utf-8 -from pypy.rlib.rarithmetic import intmask -from pypy.rlib.rfloat import isnan, isinf, NAN, formatd, INFINITY -from js.exception import JsTypeError, JsRangeError - -from pypy.rlib.objectmodel import enforceargs -from pypy.rlib import jit +from rpython.rlib.rarithmetic import intmask +from rpython.rlib.rfloat import isnan, isinf, NAN, formatd, INFINITY +from rpython.rlib.objectmodel import enforceargs +from rpython.rlib import jit from js.property_descriptor import PropertyDescriptor, DataPropertyDescriptor, AccessorPropertyDescriptor, is_data_descriptor, is_generic_descriptor, is_accessor_descriptor from js.property import DataProperty, AccessorProperty from js.object_map import new_map +from js.exception import JsTypeError, JsRangeError @jit.elidable diff --git a/js/jsparser.py b/js/jsparser.py --- a/js/jsparser.py +++ b/js/jsparser.py @@ -1,5 +1,5 @@ -from pypy.rlib.parsing.ebnfparse import parse_ebnf, make_parse_function -from pypy.rlib.parsing.parsing import ParseError +from rpython.rlib.parsing.ebnfparse import parse_ebnf, make_parse_function +from rpython.rlib.parsing.parsing import ParseError import py import sys diff --git a/js/lexical_environment.py b/js/lexical_environment.py --- a/js/lexical_environment.py +++ b/js/lexical_environment.py @@ -1,4 +1,4 @@ -from pypy.rlib import jit +#from rpython.rlib import jit from js.reference import Reference diff --git a/js/object_map.py b/js/object_map.py --- a/js/object_map.py +++ b/js/object_map.py @@ -1,4 +1,4 @@ -from pypy.rlib import jit +from rpython.rlib import jit class Map(object): diff --git a/js/object_space.py b/js/object_space.py --- a/js/object_space.py +++ b/js/object_space.py @@ -1,5 +1,5 @@ -from pypy.rlib.objectmodel import specialize, enforceargs -from pypy.rlib import jit +from rpython.rlib.objectmodel import specialize, enforceargs +from rpython.rlib import jit @enforceargs(int) @@ -201,7 +201,7 @@ def _wrap(f): def _wrapped_f(*args): - from pypy.rlib.objectmodel import we_are_translated + from rpython.rlib.objectmodel import we_are_translated if not we_are_translated(): return f(*args) diff --git a/js/opcodes.py b/js/opcodes.py --- a/js/opcodes.py +++ b/js/opcodes.py @@ -1,11 +1,11 @@ +from rpython.rlib.rarithmetic import intmask +from rpython.rlib import jit + from js.object_space import _w from js.exception import JsTypeError from js.baseop import plus, sub, compare, AbstractEC, StrictEC,\ compare_e, increment, decrement, mult, division, uminus, mod -from pypy.rlib.rarithmetic import intmask - from js.jsobj import put_property -from pypy.rlib import jit class Opcode(object): @@ -363,7 +363,7 @@ rnum = rval.ToUInt32() lnum = lval.ToUInt32() - from pypy.rlib.rarithmetic import ovfcheck_float_to_int + from rpython.rlib.rarithmetic import ovfcheck_float_to_int shift_count = rnum & 0x1F res = lnum >> shift_count @@ -797,7 +797,7 @@ # ------------ iterator support ---------------- -from pypy.rlib.listsort import make_timsort_class +from rpython.rlib.listsort import make_timsort_class TimSort = make_timsort_class() diff --git a/js/operations.py b/js/operations.py --- a/js/operations.py +++ b/js/operations.py @@ -3,10 +3,10 @@ operations.py Implements the javascript operations nodes for the interpretation tree """ +from rpython.rlib.unroll import unrolling_iterable +from rpython.rlib.objectmodel import enforceargs from js.exception import JsTypeError, JsException -from pypy.rlib.unroll import unrolling_iterable -from pypy.rlib.objectmodel import enforceargs class Position(object): diff --git a/js/property.py b/js/property.py --- a/js/property.py +++ b/js/property.py @@ -1,6 +1,6 @@ -from pypy.rlib import jit +#from rpython.rlib import jit +#from rpython.rlib.objectmodel import enforceargs from js.property_descriptor import PropertyDescriptor, DataPropertyDescriptor, AccessorPropertyDescriptor -#from pypy.rlib.objectmodel import enforceargs NOT_SET = -1 diff --git a/js/runistr.py b/js/runistr.py --- a/js/runistr.py +++ b/js/runistr.py @@ -1,5 +1,5 @@ -from pypy.rlib.objectmodel import enforceargs -from pypy.rlib import runicode +from rpython.rlib.objectmodel import enforceargs +from rpython.rlib import runicode @enforceargs(str) @@ -36,7 +36,7 @@ errorhandler = unescape_errorhandler errors = 'strict' - from pypy.rlib.rstring import UnicodeBuilder + from rpython.rlib.rstring import UnicodeBuilder if size == 0: return u'' @@ -120,8 +120,8 @@ def hexescape(builder, s, pos, digits, encoding, errorhandler, message, errors): - from pypy.rlib.rarithmetic import r_uint - from pypy.rlib.runicode import MAXUNICODE, UNICHR + from rpython.rlib.rarithmetic import r_uint + from rpython.rlib.runicode import MAXUNICODE, UNICHR chr = 0 if pos + digits > len(s): diff --git a/js/utils.py b/js/utils.py --- a/js/utils.py +++ b/js/utils.py @@ -1,6 +1,6 @@ # encoding: utf-8 #from pypy.rlib.jit import hint -from pypy.rlib import jit # , debug +from rpython.rlib import jit # , debug class StackMixin(object): diff --git a/py-js.py b/py-js.py --- a/py-js.py +++ b/py-js.py @@ -1,10 +1,12 @@ #!/usr/bin/env python import os + +from rpython.rlib.objectmodel import enforceargs +from rpython.rlib.parsing.parsing import ParseError +from rpython.rlib.parsing.deterministic import LexerError + from js.exception import JsException -from pypy.rlib.objectmodel import enforceargs -from pypy.rlib.parsing.parsing import ParseError -from pypy.rlib.parsing.deterministic import LexerError def main(argv): @@ -144,7 +146,7 @@ def jitpolicy(driver): - from pypy.jit.codewriter.policy import JitPolicy + from rpython.jit.codewriter.policy import JitPolicy return JitPolicy() diff --git a/test/ecma/conftest.py b/test/ecma/conftest.py --- a/test/ecma/conftest.py +++ b/test/ecma/conftest.py @@ -1,11 +1,11 @@ import pytest import py +from _pytest.runner import Failed +from rpython.rlib.parsing.parsing import ParseError from js.interpreter import Interpreter, load_file -from _pytest.runner import Failed from js.object_space import _w from js.exception import JsException -from pypy.rlib.parsing.parsing import ParseError EXCLUSIONLIST = ['shell.js', 'browser.js'] SKIP = [ @@ -247,7 +247,7 @@ if self.do_compile: if self.compiled_interpreter is None: - from pypy.translator.c.test.test_genc import compile + from rpython.translator.c.test.test_genc import compile self.compiled_interpreter = compile(f, [str]) return self.compiled_interpreter else: diff --git a/test/jit_view.py b/test/jit_view.py --- a/test/jit_view.py +++ b/test/jit_view.py @@ -6,8 +6,8 @@ viewloops = True conftest.option = o -from pypy.jit.metainterp.test.support import LLJitMixin -from pypy.rlib import jit +from rpython.jit.metainterp.test.support import LLJitMixin +from rpython.rlib import jit from js import interpreter diff --git a/test/test_parser.py b/test/test_parser.py --- a/test/test_parser.py +++ b/test/test_parser.py @@ -1,15 +1,14 @@ from __future__ import division import py -from pypy.rlib.parsing.ebnfparse import parse_ebnf, make_parse_function -from pypy.rlib.parsing.parsing import Rule -from pypy.rlib.parsing.tree import RPythonVisitor +from rpython.rlib.parsing.ebnfparse import parse_ebnf, make_parse_function +from rpython.rlib.parsing.parsing import Rule, ParseError +from rpython.rlib.parsing.tree import RPythonVisitor from pypy import conftest from js.astbuilder import FakeParseError from js.astbuilder import ASTBuilder from js.jscode import JsCode -from pypy.rlib.parsing.parsing import ParseError xfail = py.test.mark.xfail @@ -311,7 +310,7 @@ def test_get_pos(self): from js import operations - from pypy.rlib.parsing.tree import Symbol + from rpython.rlib.parsing.tree import Symbol astb = ASTBuilder() t = self.parse('6') assert isinstance(t, Symbol) From noreply at buildbot.pypy.org Sun Feb 17 17:29:13 2013 From: noreply at buildbot.pypy.org (fijal) Date: Sun, 17 Feb 2013 17:29:13 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: fix? Message-ID: <20130217162913.0E47B1C0133@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61348:6c83318fbde8 Date: 2013-02-17 18:28 +0200 http://bitbucket.org/pypy/pypy/changeset/6c83318fbde8/ Log: fix? diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -6,7 +6,6 @@ from rpython.jit.backend.llsupport.gcmap import allocate_gcmap from rpython.jit.metainterp.history import Const, Box, BoxInt, ConstInt from rpython.jit.metainterp.history import AbstractFailDescr, INT, REF, FLOAT -from rpython.jit.metainterp.history import JitCellToken from rpython.rtyper.lltypesystem import lltype, rffi, rstr, llmemory from rpython.rtyper.lltypesystem.lloperation import llop from rpython.rtyper.annlowlevel import llhelper, cast_instance_to_gcref @@ -26,14 +25,13 @@ from rpython.jit.backend.x86 import rx86, codebuf from rpython.jit.metainterp.resoperation import rop, ResOperation from rpython.jit.backend.x86 import support -from rpython.rlib.debug import (debug_print, debug_start, debug_stop, - have_debug_prints) +from rpython.rlib.debug import debug_print, debug_start, debug_stop from rpython.rlib import rgc from rpython.rlib.clibffi import FFI_DEFAULT_ABI from rpython.jit.backend.x86.jump import remap_frame_layout from rpython.jit.codewriter.effectinfo import EffectInfo from rpython.jit.codewriter import longlong -from rpython.rlib.rarithmetic import intmask, r_uint +from rpython.rlib.rarithmetic import intmask from rpython.rlib.objectmodel import compute_unique_id # darwin requires the stack to be 16 bytes aligned on calls. Same for gcc 4.5.0, @@ -286,18 +284,7 @@ offset = mc.get_relative_pos() - jnz_location assert 0 < offset <= 127 mc.overwrite(jnz_location-1, chr(offset)) - # - # Call the helper, which will return a dead frame object with - # the correct exception set, or MemoryError by default - addr = rffi.cast(lltype.Signed, self.cpu.get_propagate_exception()) - mc.CALL(imm(addr)) - # - # footer -- note the ADD, which skips the return address of this - # function, and will instead return to the caller's caller. Note - # also that we completely ignore the saved arguments, because we - # are interrupting the function. - mc.ADD_ri(esp.value, 2*WORD) - mc.RET() + mc.JMP(self.propagate_exception_path) # rawstart = mc.materialize(self.cpu.asmmemmgr, []) self.stack_check_slowpath = rawstart From noreply at buildbot.pypy.org Sun Feb 17 17:31:25 2013 From: noreply at buildbot.pypy.org (fijal) Date: Sun, 17 Feb 2013 17:31:25 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: ARM support, IN-PROGRESS (not working) Message-ID: <20130217163125.0DE431C0133@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61349:376b0fcc2a80 Date: 2013-02-17 18:29 +0200 http://bitbucket.org/pypy/pypy/changeset/376b0fcc2a80/ Log: ARM support, IN-PROGRESS (not working) diff --git a/rpython/jit/backend/arm/assembler.py b/rpython/jit/backend/arm/assembler.py --- a/rpython/jit/backend/arm/assembler.py +++ b/rpython/jit/backend/arm/assembler.py @@ -180,39 +180,35 @@ if not self.cpu.propagate_exception_descr: return # not supported (for tests, or non-translated) # + # mc = ARMv7Builder() - # - # read and reset the current exception - addr = rffi.cast(lltype.Signed, self.cpu.get_propagate_exception()) - mc.BL(addr) - self.gen_func_epilog(mc=mc) - self.propagate_exception_path = mc.materialize(self.cpu.asmmemmgr, []) - # - self._store_and_reset_exception(r.r0) + self._store_and_reset_exception(mc, r.r0) ofs = self.cpu.get_ofs_of_frame_field('jf_guard_exc') # make sure ofs fits into a register assert check_imm_arg(ofs) - self.mc.STR_ri(r.r0.value, r.fp.value, imm=ofs) + mc.STR_ri(r.r0.value, r.fp.value, imm=ofs) propagate_exception_descr = rffi.cast(lltype.Signed, cast_instance_to_gcref(self.cpu.propagate_exception_descr)) + # put propagate_exception_descr into frame ofs = self.cpu.get_ofs_of_frame_field('jf_descr') # make sure ofs fits into a register assert check_imm_arg(ofs) - self.mc.MOV_rr(r.r0.value, r.fp.value) - self.mc.BKPT() - #base_ofs = self.cpu.get_baseofs_of_frame_field() - #self.mc.MOV_bi(ofs, propagate_exception_descr) - #self.mc.LEA_rb(eax.value, -base_ofs) - # - self._call_footer() - rawstart = self.mc.materialize(self.cpu.asmmemmgr, []) + mc.gen_load_int(r.r0.value, propagate_exception_descr) + mc.STR_ri(r.r0.value, r.fp.value, imm=ofs) + mc.MOV_rr(r.r0.value, r.fp.value) + self.gen_func_epilog(mc) + rawstart = mc.materialize(self.cpu.asmmemmgr, []) self.propagate_exception_path = rawstart - self.mc = None - def _store_and_reset_exception(self, resloc=None): - assert resloc is not r.ip - if resloc is not None: - self.mc.gen_load_int(resloc.value, self.cpu.pos_exc_value()) + def _store_and_reset_exception(self, mc, resloc): + assert resloc is r.r0 + + self.mc.gen_load_int(resloc.value, self.cpu.pos_exc_value()) + self.mc.gen_load_int(r.r0.value, self.cpu.pos_exc_value()) + self.mc.gen_load_int(r.ip.value, 0) + self.mc.STR_ri(r.ip.value, r.r0.value) + + self.mc.LDR_ri(resloc.value, resloc.value) self.mc.MOV(resloc, heap(self.cpu.pos_exc_value())) From noreply at buildbot.pypy.org Sun Feb 17 17:31:28 2013 From: noreply at buildbot.pypy.org (fijal) Date: Sun, 17 Feb 2013 17:31:28 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: merge default Message-ID: <20130217163128.B8F4F1C0133@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61350:25e3f7fc67fe Date: 2013-02-17 18:30 +0200 http://bitbucket.org/pypy/pypy/changeset/25e3f7fc67fe/ Log: merge default diff too long, truncating to 2000 out of 9623 lines diff --git a/LICENSE b/LICENSE --- a/LICENSE +++ b/LICENSE @@ -270,3 +270,24 @@ LineBreak-*.txt UnicodeData-*.txt UnihanNumeric-*.txt + +License for 'dotviewer/font/' +============================= + +Copyright (C) 2008 The Android Open Source Project + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +Detailled license information is contained in the NOTICE file in the +directory. + diff --git a/dotviewer/VeraMoBd.ttf b/dotviewer/VeraMoBd.ttf deleted file mode 100644 Binary file dotviewer/VeraMoBd.ttf has changed diff --git a/dotviewer/cyrvetic.ttf b/dotviewer/cyrvetic.ttf deleted file mode 100644 Binary file dotviewer/cyrvetic.ttf has changed diff --git a/dotviewer/drawgraph.py b/dotviewer/drawgraph.py --- a/dotviewer/drawgraph.py +++ b/dotviewer/drawgraph.py @@ -9,9 +9,10 @@ from pygame.locals import * +RAW_ENCODING = "utf-8" this_dir = os.path.dirname(os.path.abspath(__file__)) -FONT = os.path.join(this_dir, 'cyrvetic.ttf') -FIXEDFONT = os.path.join(this_dir, 'VeraMoBd.ttf') +FONT = os.path.join(this_dir, 'font', 'DroidSans.ttf') +FIXEDFONT = os.path.join(this_dir, 'font', 'DroidSansMono.ttf') COLOR = { 'black': (0,0,0), 'white': (255,255,255), @@ -51,6 +52,12 @@ else: return default +def forceunicode(name): + return name if isinstance(name, unicode) else name.decode(RAW_ENCODING) + +def forcestr(name): + return name if isinstance(name, str) else name.encode(RAW_ENCODING) + class GraphLayout: fixedfont = False @@ -106,12 +113,12 @@ class Node: def __init__(self, name, x, y, w, h, label, style, shape, color, fillcolor): - self.name = name + self.name = forceunicode(name) self.x = float(x) self.y = float(y) self.w = float(w) self.h = float(h) - self.label = label + self.label = forceunicode(label) self.style = style self.shape = shape self.color = color @@ -125,8 +132,8 @@ label = None def __init__(self, nodes, tail, head, cnt, *rest): - self.tail = nodes[tail] - self.head = nodes[head] + self.tail = nodes[forceunicode(tail)] + self.head = nodes[forceunicode(head)] cnt = int(cnt) self.points = [(float(rest[i]), float(rest[i+1])) for i in range(0, cnt*2, 2)] @@ -655,11 +662,7 @@ part = parts[i] word = part[0] try: - try: - img = font.render(word, False, *part[1:]) - except pygame.error, e: - # Try *with* anti-aliasing to work around a bug in SDL - img = font.render(word, True, *part[1:]) + img = font.render(word, True, *part[1:]) except pygame.error: del parts[i] # Text has zero width else: diff --git a/dotviewer/font/DroidSans-Bold.ttf b/dotviewer/font/DroidSans-Bold.ttf new file mode 100644 index 0000000000000000000000000000000000000000..d065b64eb1863f83c2c982264f9442f2313a44a9 GIT binary patch [cut] diff --git a/dotviewer/font/DroidSans.ttf b/dotviewer/font/DroidSans.ttf new file mode 100644 index 0000000000000000000000000000000000000000..ad1efca88aed8d9e2d179f27dd713e2a1562fe5f GIT binary patch [cut] diff --git a/dotviewer/font/DroidSansMono.ttf b/dotviewer/font/DroidSansMono.ttf new file mode 100644 index 0000000000000000000000000000000000000000..a007071944f7c90020e798eea53b10065e2b45a5 GIT binary patch [cut] diff --git a/dotviewer/font/NOTICE b/dotviewer/font/NOTICE new file mode 100644 --- /dev/null +++ b/dotviewer/font/NOTICE @@ -0,0 +1,190 @@ + + Copyright (c) 2005-2008, The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + diff --git a/dotviewer/font/README.txt b/dotviewer/font/README.txt new file mode 100644 --- /dev/null +++ b/dotviewer/font/README.txt @@ -0,0 +1,18 @@ +Copyright (C) 2008 The Android Open Source Project + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +########## + +This directory contains the fonts for the platform. They are licensed +under the Apache 2 license. diff --git a/dotviewer/graphclient.py b/dotviewer/graphclient.py --- a/dotviewer/graphclient.py +++ b/dotviewer/graphclient.py @@ -33,8 +33,9 @@ def reload(graph_id): page = getpage(graph_id) if save_tmp_file: + from drawgraph import forcestr f = open(save_tmp_file, 'w') - f.write(page.source) + f.write(forcestr(page.source)) f.close() messages.extend(page_messages(page, graph_id)) send_graph_messages(io, messages) @@ -75,7 +76,8 @@ def page_messages(page, graph_id): import graphparse - return graphparse.parse_dot(graph_id, page.source, page.links, + from drawgraph import forcestr + return graphparse.parse_dot(graph_id, forcestr(page.source), page.links, getattr(page, 'fixedfont', False)) def send_graph_messages(io, messages): diff --git a/dotviewer/graphdisplay.py b/dotviewer/graphdisplay.py --- a/dotviewer/graphdisplay.py +++ b/dotviewer/graphdisplay.py @@ -4,7 +4,7 @@ from pygame.locals import * from drawgraph import GraphRenderer, FIXEDFONT from drawgraph import Node, Edge -from drawgraph import EventQueue, wait_for_events +from drawgraph import EventQueue, wait_for_events, forceunicode, forcestr METAKEYS = dict([ @@ -285,7 +285,7 @@ if e.key == K_ESCAPE: return None elif e.key == K_RETURN: - return text.encode('latin-1') # XXX do better + return forcestr(text) # return encoded unicode elif e.key == K_BACKSPACE: text = text[:-1] elif e.unicode and ord(e.unicode) >= ord(' '): @@ -423,7 +423,7 @@ self.layout.request_reload() def setstatusbar(self, text, fgcolor=None, bgcolor=None): - info = (text, fgcolor or self.STATUSBAR_FGCOLOR, bgcolor or self.STATUSBAR_BGCOLOR) + info = (forceunicode(text), fgcolor or self.STATUSBAR_FGCOLOR, bgcolor or self.STATUSBAR_BGCOLOR) if info != self.statusbarinfo: self.statusbarinfo = info self.must_redraw = True @@ -711,7 +711,7 @@ lines = [] while words: line = words.pop(0) - img = font.render(line or ' ', 1, fgcolor) + img = font.render(line or ' ', True, fgcolor) while words: longerline = line + ' ' + words[0] longerimg = font.render(longerline, 1, fgcolor) @@ -723,7 +723,7 @@ img = longerimg w, h = img.get_size() if h > maxheight: - img = font.render('...', 1, overflowcolor) + img = font.render('...', True, overflowcolor) w, h = img.get_size() while lines and h > maxheight: maxheight += lines.pop().get_size()[1] diff --git a/dotviewer/graphpage.py b/dotviewer/graphpage.py --- a/dotviewer/graphpage.py +++ b/dotviewer/graphpage.py @@ -44,6 +44,8 @@ class DotFileGraphPage(GraphPage): def compute(self, dotfile): - f = open(dotfile, 'r') + import codecs + from drawgraph import RAW_ENCODING + f = codecs.open(dotfile, 'r', RAW_ENCODING) self.source = f.read() f.close() diff --git a/dotviewer/test/test_interactive_unicode.py b/dotviewer/test/test_interactive_unicode.py new file mode 100755 --- /dev/null +++ b/dotviewer/test/test_interactive_unicode.py @@ -0,0 +1,103 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +import py +import sys, os, signal, thread, time, codecs +from dotviewer.conftest import option +from dotviewer.drawgraph import RAW_ENCODING + +SOURCE1 = u"""digraph G{ +λ -> b +b -> μ +} +""" + +FILENAME = 'graph1.dot' + +def setup_module(mod): + if not option.pygame: + py.test.skip("--pygame not enabled") + udir = py.path.local.make_numbered_dir(prefix='usession-dot-', keep=3) + f = codecs.open(str(udir.join(FILENAME)), 'wb', RAW_ENCODING) + f.write(SOURCE1) + f.close() + + from dotviewer import graphclient + mod.pkgdir = py.path.local(graphclient.this_dir) + mod.udir = udir + + try: + del os.environ['GRAPHSERVER'] + except KeyError: + pass + + +def test_dotviewer(): + print "=== dotviewer.py %s" % FILENAME + err = os.system('"%s" "%s"' % (pkgdir.join('dotviewer.py'), + udir.join(FILENAME))) + assert err == 0 + + plain_name = FILENAME.replace('.dot','.plain') + + os.system('dot -Tplain "%s" > "%s"' % (udir.join(FILENAME), + udir.join(plain_name))) + print "=== dotviewer.py %s" % plain_name + err = os.system('"%s" "%s"' % (pkgdir.join('dotviewer.py'), + udir.join(plain_name))) + assert err == 0 + +def test_display_dot_file(): + from dotviewer.graphclient import display_dot_file + print "=== display_dot_file(%s) with GRAPHSERVER=%s" % ( + FILENAME, os.environ.get('GRAPHSERVER', ''),) + display_dot_file(udir.join(FILENAME)) + print "=== display_dot_file finished" + + +def test_graphserver(): + import socket + s = socket.socket() + s.listen(1) + host, port = s.getsockname() # pick a random free port + s.close() + + if hasattr(sys, 'pypy_objspaceclass'): + python = 'python' + else: + python = sys.executable + + cmdargs = [python, str(pkgdir.join('graphserver.py')), + str(port)] + print '* starting:', ' '.join(cmdargs) + pid = os.spawnv(os.P_NOWAIT, cmdargs[0], cmdargs) + try: + time.sleep(1) # hack - wait a bit to make sure the server is up + os.environ['GRAPHSERVER'] = '%s:%d' % (host, port) + try: + test_display_dot_file() + finally: + del os.environ['GRAPHSERVER'] + finally: + os.kill(pid, signal.SIGTERM) + +def test_colors(): + from dotviewer import graphpage, graphclient + class MyPage(graphpage.DotFileGraphPage): + def compute(self, dotfile): + super(MyPage, self).compute(dotfile) + self.links = {'v2721': 'Hello world', + 'v2720': ('Something green', (0, 192, 0)), + } + dotfile = str(udir.join(FILENAME)) + page = MyPage(dotfile) + graphclient.display_page(page) + +def test_fixedfont(): + from dotviewer import graphpage, graphclient + class MyPage(graphpage.DotFileGraphPage): + fixedfont = True + dotfile = str(udir.join(FILENAME)) + page = MyPage(dotfile) + page.fixedfont = True + graphclient.display_page(page) diff --git a/dotviewer/test/test_translator.py b/dotviewer/test/test_translator.py --- a/dotviewer/test/test_translator.py +++ b/dotviewer/test/test_translator.py @@ -22,6 +22,6 @@ def test_annotated(): from rpython.translator.interactive import Translation - t = Translation(is_prime) - t.annotate([int]) + t = Translation(is_prime, [int]) + t.annotate() t.viewcg() diff --git a/dotviewer/test/test_unicode_util.py b/dotviewer/test/test_unicode_util.py new file mode 100755 --- /dev/null +++ b/dotviewer/test/test_unicode_util.py @@ -0,0 +1,57 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +import py +import codecs +from dotviewer.drawgraph import RAW_ENCODING, forcestr, forceunicode + +SOURCE1 = u"""digraph G{ +λ -> b +b -> μ +} +""" + +FILENAME = 'test.dot' + +class TestUnicodeUtil(object): + + def test_idempotent(self): + x = u"a" + assert forceunicode(forcestr(x)) == x + + x = u"λ" + assert forceunicode(forcestr(x)) == x + + assert forceunicode(forcestr(SOURCE1)) == SOURCE1 + + x = "a" + assert forcestr(forceunicode(x)) == x + + # utf-8 encoded. + # fragile, does not consider RAW_ENCODING + # x = "\xef\xbb\xbf\xce\xbb" + # assert forcestr(forceunicode(x)) == x + + def test_does_not_double_encode(self): + x = u"λ" + x_e = forcestr(x) + assert forcestr(x_e) == x_e + + x_u = forceunicode(x_e) + assert forceunicode(x_u) == x_u + + def test_file(self): + udir = py.path.local.make_numbered_dir(prefix='usession-dot-', keep=3) + full_filename = str(udir.join(FILENAME)) + f = codecs.open(full_filename, 'wb', RAW_ENCODING) + f.write(SOURCE1) + f.close() + + with open(full_filename) as f1: + assert forceunicode(f1.read()) == SOURCE1 + + f3 = codecs.open(full_filename, 'r', RAW_ENCODING) + c = f3.read() + f3.close() + result = (c == SOURCE1) + assert result diff --git a/lib-python/2.7/collections.py b/lib-python/2.7/collections.py --- a/lib-python/2.7/collections.py +++ b/lib-python/2.7/collections.py @@ -295,7 +295,7 @@ _fields = %(field_names)r \n def __new__(_cls, %(argtxt)s): 'Create new instance of %(typename)s(%(argtxt)s)' - return tuple.__new__(_cls, (%(argtxt)s)) \n + return _tuple.__new__(_cls, (%(argtxt)s)) \n @classmethod def _make(cls, iterable, new=tuple.__new__, len=len): 'Make a new %(typename)s object from a sequence or iterable' @@ -320,14 +320,14 @@ 'Return self as a plain tuple. Used by copy and pickle.' return tuple(self) \n\n''' % locals() for i, name in enumerate(field_names): - template += " %s = property(lambda self: self[%d], doc='Alias for field number %d')\n" % (name, i, i) + template += " %s = _property(lambda self: self[%d], doc='Alias for field number %d')\n" % (name, i, i) if verbose: print template # Execute the template string in a temporary namespace and # support tracing utilities by setting a value for frame.f_globals['__name__'] - namespace = {'__name__': 'namedtuple_%s' % typename, - 'OrderedDict': OrderedDict} + namespace = dict(__name__='namedtuple_%s' % typename, + OrderedDict=OrderedDict, _property=property, _tuple=tuple) try: exec template in namespace except SyntaxError, e: diff --git a/lib-python/2.7/json/encoder.py b/lib-python/2.7/json/encoder.py --- a/lib-python/2.7/json/encoder.py +++ b/lib-python/2.7/json/encoder.py @@ -138,16 +138,16 @@ self.skipkeys = skipkeys self.ensure_ascii = ensure_ascii if ensure_ascii: - self.encoder = raw_encode_basestring_ascii + self.__encoder = raw_encode_basestring_ascii else: - self.encoder = raw_encode_basestring + self.__encoder = raw_encode_basestring if encoding != 'utf-8': - orig_encoder = self.encoder + orig_encoder = self.__encoder def encoder(o): if isinstance(o, str): o = o.decode(encoding) return orig_encoder(o) - self.encoder = encoder + self.__encoder = encoder self.check_circular = check_circular self.allow_nan = allow_nan self.sort_keys = sort_keys @@ -193,10 +193,10 @@ builder = StringBuilder() else: builder = UnicodeBuilder() - self._encode(o, markers, builder, 0) + self.__encode(o, markers, builder, 0) return builder.build() - def _emit_indent(self, builder, _current_indent_level): + def __emit_indent(self, builder, _current_indent_level): if self.indent is not None: _current_indent_level += 1 newline_indent = '\n' + (' ' * (self.indent * @@ -207,15 +207,15 @@ separator = self.item_separator return separator, _current_indent_level - def _emit_unindent(self, builder, _current_indent_level): + def __emit_unindent(self, builder, _current_indent_level): if self.indent is not None: builder.append('\n') builder.append(' ' * (self.indent * (_current_indent_level - 1))) - def _encode(self, o, markers, builder, _current_indent_level): + def __encode(self, o, markers, builder, _current_indent_level): if isinstance(o, basestring): builder.append('"') - builder.append(self.encoder(o)) + builder.append(self.__encoder(o)) builder.append('"') elif o is None: builder.append('null') @@ -226,46 +226,46 @@ elif isinstance(o, (int, long)): builder.append(str(o)) elif isinstance(o, float): - builder.append(self._floatstr(o)) + builder.append(self.__floatstr(o)) elif isinstance(o, (list, tuple)): if not o: builder.append('[]') return - self._encode_list(o, markers, builder, _current_indent_level) + self.__encode_list(o, markers, builder, _current_indent_level) elif isinstance(o, dict): if not o: builder.append('{}') return - self._encode_dict(o, markers, builder, _current_indent_level) + self.__encode_dict(o, markers, builder, _current_indent_level) else: - self._mark_markers(markers, o) + self.__mark_markers(markers, o) res = self.default(o) - self._encode(res, markers, builder, _current_indent_level) - self._remove_markers(markers, o) + self.__encode(res, markers, builder, _current_indent_level) + self.__remove_markers(markers, o) return res - def _encode_list(self, l, markers, builder, _current_indent_level): - self._mark_markers(markers, l) + def __encode_list(self, l, markers, builder, _current_indent_level): + self.__mark_markers(markers, l) builder.append('[') first = True - separator, _current_indent_level = self._emit_indent(builder, + separator, _current_indent_level = self.__emit_indent(builder, _current_indent_level) for elem in l: if first: first = False else: builder.append(separator) - self._encode(elem, markers, builder, _current_indent_level) + self.__encode(elem, markers, builder, _current_indent_level) del elem # XXX grumble - self._emit_unindent(builder, _current_indent_level) + self.__emit_unindent(builder, _current_indent_level) builder.append(']') - self._remove_markers(markers, l) + self.__remove_markers(markers, l) - def _encode_dict(self, d, markers, builder, _current_indent_level): - self._mark_markers(markers, d) + def __encode_dict(self, d, markers, builder, _current_indent_level): + self.__mark_markers(markers, d) first = True builder.append('{') - separator, _current_indent_level = self._emit_indent(builder, + separator, _current_indent_level = self.__emit_indent(builder, _current_indent_level) if self.sort_keys: items = sorted(d.items(), key=lambda kv: kv[0]) @@ -282,7 +282,7 @@ # JavaScript is weakly typed for these, so it makes sense to # also allow them. Many encoders seem to do something like this. elif isinstance(key, float): - key = self._floatstr(key) + key = self.__floatstr(key) elif key is True: key = 'true' elif key is False: @@ -296,15 +296,15 @@ else: raise TypeError("key " + repr(key) + " is not a string") builder.append('"') - builder.append(self.encoder(key)) + builder.append(self.__encoder(key)) builder.append('"') builder.append(self.key_separator) - self._encode(v, markers, builder, _current_indent_level) + self.__encode(v, markers, builder, _current_indent_level) del key del v # XXX grumble - self._emit_unindent(builder, _current_indent_level) + self.__emit_unindent(builder, _current_indent_level) builder.append('}') - self._remove_markers(markers, d) + self.__remove_markers(markers, d) def iterencode(self, o, _one_shot=False): """Encode the given object and yield each string @@ -320,9 +320,9 @@ markers = {} else: markers = None - return self._iterencode(o, markers, 0) + return self.__iterencode(o, markers, 0) - def _floatstr(self, o): + def __floatstr(self, o): # Check for specials. Note that this type of test is processor # and/or platform-specific, so do tests which don't depend on the # internals. @@ -343,21 +343,21 @@ return text - def _mark_markers(self, markers, o): + def __mark_markers(self, markers, o): if markers is not None: if id(o) in markers: raise ValueError("Circular reference detected") markers[id(o)] = None - def _remove_markers(self, markers, o): + def __remove_markers(self, markers, o): if markers is not None: del markers[id(o)] - def _iterencode_list(self, lst, markers, _current_indent_level): + def __iterencode_list(self, lst, markers, _current_indent_level): if not lst: yield '[]' return - self._mark_markers(markers, lst) + self.__mark_markers(markers, lst) buf = '[' if self.indent is not None: _current_indent_level += 1 @@ -375,7 +375,7 @@ else: buf = separator if isinstance(value, basestring): - yield buf + '"' + self.encoder(value) + '"' + yield buf + '"' + self.__encoder(value) + '"' elif value is None: yield buf + 'null' elif value is True: @@ -385,17 +385,17 @@ elif isinstance(value, (int, long)): yield buf + str(value) elif isinstance(value, float): - yield buf + self._floatstr(value) + yield buf + self.__floatstr(value) else: yield buf if isinstance(value, (list, tuple)): - chunks = self._iterencode_list(value, markers, + chunks = self.__iterencode_list(value, markers, _current_indent_level) elif isinstance(value, dict): - chunks = self._iterencode_dict(value, markers, + chunks = self.__iterencode_dict(value, markers, _current_indent_level) else: - chunks = self._iterencode(value, markers, + chunks = self.__iterencode(value, markers, _current_indent_level) for chunk in chunks: yield chunk @@ -403,13 +403,13 @@ _current_indent_level -= 1 yield '\n' + (' ' * (self.indent * _current_indent_level)) yield ']' - self._remove_markers(markers, lst) + self.__remove_markers(markers, lst) - def _iterencode_dict(self, dct, markers, _current_indent_level): + def __iterencode_dict(self, dct, markers, _current_indent_level): if not dct: yield '{}' return - self._mark_markers(markers, dct) + self.__mark_markers(markers, dct) yield '{' if self.indent is not None: _current_indent_level += 1 @@ -431,7 +431,7 @@ # JavaScript is weakly typed for these, so it makes sense to # also allow them. Many encoders seem to do something like this. elif isinstance(key, float): - key = self._floatstr(key) + key = self.__floatstr(key) elif key is True: key = 'true' elif key is False: @@ -448,10 +448,10 @@ first = False else: yield item_separator - yield '"' + self.encoder(key) + '"' + yield '"' + self.__encoder(key) + '"' yield self.key_separator if isinstance(value, basestring): - yield '"' + self.encoder(value) + '"' + yield '"' + self.__encoder(value) + '"' elif value is None: yield 'null' elif value is True: @@ -461,16 +461,16 @@ elif isinstance(value, (int, long)): yield str(value) elif isinstance(value, float): - yield self._floatstr(value) + yield self.__floatstr(value) else: if isinstance(value, (list, tuple)): - chunks = self._iterencode_list(value, markers, + chunks = self.__iterencode_list(value, markers, _current_indent_level) elif isinstance(value, dict): - chunks = self._iterencode_dict(value, markers, + chunks = self.__iterencode_dict(value, markers, _current_indent_level) else: - chunks = self._iterencode(value, markers, + chunks = self.__iterencode(value, markers, _current_indent_level) for chunk in chunks: yield chunk @@ -478,11 +478,11 @@ _current_indent_level -= 1 yield '\n' + (' ' * (self.indent * _current_indent_level)) yield '}' - self._remove_markers(markers, dct) + self.__remove_markers(markers, dct) - def _iterencode(self, o, markers, _current_indent_level): + def __iterencode(self, o, markers, _current_indent_level): if isinstance(o, basestring): - yield '"' + self.encoder(o) + '"' + yield '"' + self.__encoder(o) + '"' elif o is None: yield 'null' elif o is True: @@ -492,19 +492,19 @@ elif isinstance(o, (int, long)): yield str(o) elif isinstance(o, float): - yield self._floatstr(o) + yield self.__floatstr(o) elif isinstance(o, (list, tuple)): - for chunk in self._iterencode_list(o, markers, + for chunk in self.__iterencode_list(o, markers, _current_indent_level): yield chunk elif isinstance(o, dict): - for chunk in self._iterencode_dict(o, markers, + for chunk in self.__iterencode_dict(o, markers, _current_indent_level): yield chunk else: - self._mark_markers(markers, o) + self.__mark_markers(markers, o) obj = self.default(o) - for chunk in self._iterencode(obj, markers, + for chunk in self.__iterencode(obj, markers, _current_indent_level): yield chunk - self._remove_markers(markers, o) + self.__remove_markers(markers, o) diff --git a/lib-python/2.7/test/test_generators.py b/lib-python/2.7/test/test_generators.py --- a/lib-python/2.7/test/test_generators.py +++ b/lib-python/2.7/test/test_generators.py @@ -1501,9 +1501,7 @@ """ coroutine_tests = """\ -A helper function to call gc.collect() without printing ->>> import gc ->>> def gc_collect(): gc.collect() +>>> from test.test_support import gc_collect Sending a value into a started generator: @@ -1823,8 +1821,7 @@ references. We add it to the standard suite so the routine refleak-tests would trigger if it starts being uncleanable again. ->>> import gc ->>> def gc_collect(): gc.collect() +>>> from test.test_support import gc_collect >>> import itertools >>> def leak(): diff --git a/lib-python/2.7/urllib.py b/lib-python/2.7/urllib.py --- a/lib-python/2.7/urllib.py +++ b/lib-python/2.7/urllib.py @@ -1205,15 +1205,17 @@ # fastpath if len(res) == 1: return s - s = res[0] - for item in res[1:]: + res_list = [res[0]] + for j in xrange(1, len(res)): + item = res[j] try: - s += _hextochr[item[:2]] + item[2:] + x = _hextochr[item[:2]] + item[2:] except KeyError: - s += '%' + item + x = '%' + item except UnicodeDecodeError: - s += unichr(int(item[:2], 16)) + item[2:] - return s + x = unichr(int(item[:2], 16)) + item[2:] + res_list.append(x) + return ''.join(res_list) def unquote_plus(s): """unquote('%7e/abc+def') -> '~/abc def'""" diff --git a/lib-python/2.7/urlparse.py b/lib-python/2.7/urlparse.py --- a/lib-python/2.7/urlparse.py +++ b/lib-python/2.7/urlparse.py @@ -321,15 +321,17 @@ # fastpath if len(res) == 1: return s - s = res[0] - for item in res[1:]: + res_list = [res[0]] + for j in xrange(1, len(res)): + item = res[j] try: - s += _hextochr[item[:2]] + item[2:] + x = _hextochr[item[:2]] + item[2:] except KeyError: - s += '%' + item + x = '%' + item except UnicodeDecodeError: - s += unichr(int(item[:2], 16)) + item[2:] - return s + x = unichr(int(item[:2], 16)) + item[2:] + res_list.append(x) + return ''.join(res_list) def parse_qs(qs, keep_blank_values=0, strict_parsing=0): """Parse a query given as a string argument. diff --git a/lib-python/conftest.py b/lib-python/conftest.py --- a/lib-python/conftest.py +++ b/lib-python/conftest.py @@ -272,7 +272,7 @@ RegrTest('test_inspect.py'), RegrTest('test_int.py', core=True), RegrTest('test_int_literal.py', core=True), - RegrTest('test_io.py'), + RegrTest('test_io.py', usemodules='array binascii'), RegrTest('test_ioctl.py'), RegrTest('test_isinstance.py', core=True), RegrTest('test_iter.py', core=True), diff --git a/lib_pypy/_collections.py b/lib_pypy/_collections.py --- a/lib_pypy/_collections.py +++ b/lib_pypy/_collections.py @@ -142,18 +142,24 @@ return c def remove(self, value): - # Need to be defensive for mutating comparisons - for i in range(len(self)): - if self[i] == value: - del self[i] - return - raise ValueError("deque.remove(x): x not in deque") + # Need to defend mutating or failing comparisons + i = 0 + try: + for i in range(len(self)): + if self[0] == value: + self.popleft() + return + self.append(self.popleft()) + i += 1 + raise ValueError("deque.remove(x): x not in deque") + finally: + self.rotate(i) def rotate(self, n=1): length = len(self) - if length == 0: + if length <= 1: return - halflen = (length+1) >> 1 + halflen = length >> 1 if n > halflen or n < -halflen: n %= length if n > halflen: diff --git a/lib_pypy/conftest.py b/lib_pypy/conftest.py deleted file mode 100644 --- a/lib_pypy/conftest.py +++ /dev/null @@ -1,2 +0,0 @@ - -from pypy.conftest import * diff --git a/lib_pypy/datetime.py b/lib_pypy/datetime.py --- a/lib_pypy/datetime.py +++ b/lib_pypy/datetime.py @@ -270,10 +270,21 @@ return offset raise ValueError("%s()=%d, must be in -1439..1439" % (name, offset)) +def _check_int_field(value): + if not isinstance(value, float): + try: + value = value.__int__() + except AttributeError: + pass + else: + if isinstance(value, (int, long)): + return value + raise TypeError('integer argument expected') + def _check_date_fields(year, month, day): - for value in [year, day]: - if not isinstance(value, (int, long)): - raise TypeError('int expected') + year = _check_int_field(year) + month = _check_int_field(month) + day = _check_int_field(day) if not MINYEAR <= year <= MAXYEAR: raise ValueError('year must be in %d..%d' % (MINYEAR, MAXYEAR), year) if not 1 <= month <= 12: @@ -281,11 +292,13 @@ dim = _days_in_month(year, month) if not 1 <= day <= dim: raise ValueError('day must be in 1..%d' % dim, day) + return year, month, day def _check_time_fields(hour, minute, second, microsecond): - for value in [hour, minute, second, microsecond]: - if not isinstance(value, (int, long)): - raise TypeError('int expected') + hour = _check_int_field(hour) + minute = _check_int_field(minute) + second = _check_int_field(second) + microsecond = _check_int_field(microsecond) if not 0 <= hour <= 23: raise ValueError('hour must be in 0..23', hour) if not 0 <= minute <= 59: @@ -294,6 +307,7 @@ raise ValueError('second must be in 0..59', second) if not 0 <= microsecond <= 999999: raise ValueError('microsecond must be in 0..999999', microsecond) + return hour, minute, second, microsecond def _check_tzinfo_arg(tz): if tz is not None and not isinstance(tz, tzinfo): @@ -768,7 +782,7 @@ self = object.__new__(cls) self.__setstate(year) return self - _check_date_fields(year, month, day) + year, month, day = _check_date_fields(year, month, day) self = object.__new__(cls) self._year = year self._month = month @@ -889,7 +903,7 @@ month = self._month if day is None: day = self._day - _check_date_fields(year, month, day) + year, month, day = _check_date_fields(year, month, day) return date(year, month, day) # Comparisons of date objects with other. @@ -1150,13 +1164,14 @@ second, microsecond (default to zero) tzinfo (default to None) """ - self = object.__new__(cls) if isinstance(hour, str): # Pickle support + self = object.__new__(cls) self.__setstate(hour, minute or None) return self + hour, minute, second, microsecond = _check_time_fields(hour, minute, second, microsecond) _check_tzinfo_arg(tzinfo) - _check_time_fields(hour, minute, second, microsecond) + self = object.__new__(cls) self._hour = hour self._minute = minute self._second = second @@ -1387,7 +1402,7 @@ microsecond = self.microsecond if tzinfo is True: tzinfo = self.tzinfo - _check_time_fields(hour, minute, second, microsecond) + hour, minute, second, microsecond = _check_time_fields(hour, minute, second, microsecond) _check_tzinfo_arg(tzinfo) return time(hour, minute, second, microsecond, tzinfo) @@ -1449,10 +1464,10 @@ self = date.__new__(cls, year[:4]) self.__setstate(year, month) return self + year, month, day = _check_date_fields(year, month, day) + hour, minute, second, microsecond = _check_time_fields(hour, minute, second, microsecond) _check_tzinfo_arg(tzinfo) - _check_time_fields(hour, minute, second, microsecond) - self = date.__new__(cls, year, month, day) - # XXX This duplicates __year, __month, __day for convenience :-( + self = object.__new__(cls) self._year = year self._month = month self._day = day @@ -1617,8 +1632,8 @@ microsecond = self.microsecond if tzinfo is True: tzinfo = self.tzinfo - _check_date_fields(year, month, day) - _check_time_fields(hour, minute, second, microsecond) + year, month, day = _check_date_fields(year, month, day) + hour, minute, second, microsecond = _check_time_fields(hour, minute, second, microsecond) _check_tzinfo_arg(tzinfo) return datetime(year, month, day, hour, minute, second, microsecond, tzinfo) diff --git a/lib_pypy/dbm.py b/lib_pypy/dbm.py --- a/lib_pypy/dbm.py +++ b/lib_pypy/dbm.py @@ -1,4 +1,4 @@ -from ctypes import Structure, c_char_p, c_int, c_void_p, CDLL +from ctypes import Structure, c_char_p, c_int, c_void_p, CDLL, POINTER, c_char import ctypes.util import os, sys @@ -11,7 +11,7 @@ class datum(Structure): _fields_ = [ - ('dptr', c_char_p), + ('dptr', POINTER(c_char)), ('dsize', c_int), ] @@ -126,8 +126,8 @@ libpath = ctypes.util.find_library('db') if not libpath: # XXX this is hopeless... - for c in '56789': - libpath = ctypes.util.find_library('db-4.%s' % c) + for c in ['5.3', '5.2', '5.1', '5.0', '4.9', '4.8', '4.7', '4.6', '4.5']: + libpath = ctypes.util.find_library('db-%s' % c) if libpath: break else: diff --git a/lib_pypy/numpypy/core/__init__.py b/lib_pypy/numpypy/core/__init__.py --- a/lib_pypy/numpypy/core/__init__.py +++ b/lib_pypy/numpypy/core/__init__.py @@ -1,2 +1,3 @@ from .fromnumeric import * from .numeric import * +from .shape_base import * diff --git a/lib_pypy/numpypy/core/numeric.py b/lib_pypy/numpypy/core/numeric.py --- a/lib_pypy/numpypy/core/numeric.py +++ b/lib_pypy/numpypy/core/numeric.py @@ -428,3 +428,76 @@ True_ = bool_(True) e = math.e pi = math.pi + +def outer(a,b): + """ + Compute the outer product of two vectors. + + Given two vectors, ``a = [a0, a1, ..., aM]`` and + ``b = [b0, b1, ..., bN]``, + the outer product [1]_ is:: + + [[a0*b0 a0*b1 ... a0*bN ] + [a1*b0 . + [ ... . + [aM*b0 aM*bN ]] + + Parameters + ---------- + a, b : array_like, shape (M,), (N,) + First and second input vectors. Inputs are flattened if they + are not already 1-dimensional. + + Returns + ------- + out : ndarray, shape (M, N) + ``out[i, j] = a[i] * b[j]`` + + See also + -------- + inner, einsum + + References + ---------- + .. [1] : G. H. Golub and C. F. van Loan, *Matrix Computations*, 3rd + ed., Baltimore, MD, Johns Hopkins University Press, 1996, + pg. 8. + + Examples + -------- + Make a (*very* coarse) grid for computing a Mandelbrot set: + + >>> rl = np.outer(np.ones((5,)), np.linspace(-2, 2, 5)) + >>> rl + array([[-2., -1., 0., 1., 2.], + [-2., -1., 0., 1., 2.], + [-2., -1., 0., 1., 2.], + [-2., -1., 0., 1., 2.], + [-2., -1., 0., 1., 2.]]) + >>> im = np.outer(1j*np.linspace(2, -2, 5), np.ones((5,))) + >>> im + array([[ 0.+2.j, 0.+2.j, 0.+2.j, 0.+2.j, 0.+2.j], + [ 0.+1.j, 0.+1.j, 0.+1.j, 0.+1.j, 0.+1.j], + [ 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j], + [ 0.-1.j, 0.-1.j, 0.-1.j, 0.-1.j, 0.-1.j], + [ 0.-2.j, 0.-2.j, 0.-2.j, 0.-2.j, 0.-2.j]]) + >>> grid = rl + im + >>> grid + array([[-2.+2.j, -1.+2.j, 0.+2.j, 1.+2.j, 2.+2.j], + [-2.+1.j, -1.+1.j, 0.+1.j, 1.+1.j, 2.+1.j], + [-2.+0.j, -1.+0.j, 0.+0.j, 1.+0.j, 2.+0.j], + [-2.-1.j, -1.-1.j, 0.-1.j, 1.-1.j, 2.-1.j], + [-2.-2.j, -1.-2.j, 0.-2.j, 1.-2.j, 2.-2.j]]) + + An example using a "vector" of letters: + + >>> x = np.array(['a', 'b', 'c'], dtype=object) + >>> np.outer(x, [1, 2, 3]) + array([[a, aa, aaa], + [b, bb, bbb], + [c, cc, ccc]], dtype=object) + + """ + a = asarray(a) + b = asarray(b) + return a.ravel()[:,newaxis]*b.ravel()[newaxis,:] diff --git a/lib_pypy/numpypy/core/shape_base.py b/lib_pypy/numpypy/core/shape_base.py new file mode 100644 --- /dev/null +++ b/lib_pypy/numpypy/core/shape_base.py @@ -0,0 +1,323 @@ +import _numpypy +from numeric import array, asanyarray, newaxis + +def atleast_1d(*arys): + """ + Convert inputs to arrays with at least one dimension. + + Scalar inputs are converted to 1-dimensional arrays, whilst + higher-dimensional inputs are preserved. + + Parameters + ---------- + arys1, arys2, ... : array_like + One or more input arrays. + + Returns + ------- + ret : ndarray + An array, or sequence of arrays, each with ``a.ndim >= 1``. + Copies are made only if necessary. + + See Also + -------- + atleast_2d, atleast_3d + + Examples + -------- + >>> np.atleast_1d(1.0) + array([ 1.]) + + >>> x = np.arange(9.0).reshape(3,3) + >>> np.atleast_1d(x) + array([[ 0., 1., 2.], + [ 3., 4., 5.], + [ 6., 7., 8.]]) + >>> np.atleast_1d(x) is x + True + + >>> np.atleast_1d(1, [3, 4]) + [array([1]), array([3, 4])] + + """ + res = [] + for ary in arys: + ary = asanyarray(ary) + if len(ary.shape) == 0 : + result = ary.reshape(1) + else : + result = ary + res.append(result) + if len(res) == 1: + return res[0] + else: + return res + + +def atleast_2d(*arys): + """ + View inputs as arrays with at least two dimensions. + + Parameters + ---------- + arys1, arys2, ... : array_like + One or more array-like sequences. Non-array inputs are converted + to arrays. Arrays that already have two or more dimensions are + preserved. + + Returns + ------- + res, res2, ... : ndarray + An array, or tuple of arrays, each with ``a.ndim >= 2``. + Copies are avoided where possible, and views with two or more + dimensions are returned. + + See Also + -------- + atleast_1d, atleast_3d + + Examples + -------- + >>> np.atleast_2d(3.0) + array([[ 3.]]) + + >>> x = np.arange(3.0) + >>> np.atleast_2d(x) + array([[ 0., 1., 2.]]) + >>> np.atleast_2d(x).base is x + True + + >>> np.atleast_2d(1, [1, 2], [[1, 2]]) + [array([[1]]), array([[1, 2]]), array([[1, 2]])] + + """ + res = [] + for ary in arys: + ary = asanyarray(ary) + if len(ary.shape) == 0 : + result = ary.reshape(1, 1) + elif len(ary.shape) == 1 : + result = ary[newaxis, :] + else : + result = ary + res.append(result) + if len(res) == 1: + return res[0] + else: + return res + +def atleast_3d(*arys): + """ + View inputs as arrays with at least three dimensions. + + Parameters + ---------- + arys1, arys2, ... : array_like + One or more array-like sequences. Non-array inputs are converted to + arrays. Arrays that already have three or more dimensions are + preserved. + + Returns + ------- + res1, res2, ... : ndarray + An array, or tuple of arrays, each with ``a.ndim >= 3``. Copies are + avoided where possible, and views with three or more dimensions are + returned. For example, a 1-D array of shape ``(N,)`` becomes a view + of shape ``(1, N, 1)``, and a 2-D array of shape ``(M, N)`` becomes a + view of shape ``(M, N, 1)``. + + See Also + -------- + atleast_1d, atleast_2d + + Examples + -------- + >>> np.atleast_3d(3.0) + array([[[ 3.]]]) + + >>> x = np.arange(3.0) + >>> np.atleast_3d(x).shape + (1, 3, 1) + + >>> x = np.arange(12.0).reshape(4,3) + >>> np.atleast_3d(x).shape + (4, 3, 1) + >>> np.atleast_3d(x).base is x + True + + >>> for arr in np.atleast_3d([1, 2], [[1, 2]], [[[1, 2]]]): + ... print arr, arr.shape + ... + [[[1] + [2]]] (1, 2, 1) + [[[1] + [2]]] (1, 2, 1) + [[[1 2]]] (1, 1, 2) + + """ + res = [] + for ary in arys: + ary = asanyarray(ary) + if len(ary.shape) == 0: + result = ary.reshape(1,1,1) + elif len(ary.shape) == 1: + result = ary[newaxis,:,newaxis] + elif len(ary.shape) == 2: + result = ary[:,:,newaxis] + else: + result = ary + res.append(result) + if len(res) == 1: + return res[0] + else: + return res + +def vstack(tup): + """ + Stack arrays in sequence vertically (row wise). + + Take a sequence of arrays and stack them vertically to make a single + array. Rebuild arrays divided by `vsplit`. + + Parameters + ---------- + tup : sequence of ndarrays + Tuple containing arrays to be stacked. The arrays must have the same + shape along all but the first axis. + + Returns + ------- + stacked : ndarray + The array formed by stacking the given arrays. + + See Also + -------- + hstack : Stack arrays in sequence horizontally (column wise). + dstack : Stack arrays in sequence depth wise (along third dimension). + concatenate : Join a sequence of arrays together. + vsplit : Split array into a list of multiple sub-arrays vertically. + + Notes + ----- + Equivalent to ``np.concatenate(tup, axis=0)`` if `tup` contains arrays that + are at least 2-dimensional. + + Examples + -------- + >>> a = np.array([1, 2, 3]) + >>> b = np.array([2, 3, 4]) + >>> np.vstack((a,b)) + array([[1, 2, 3], + [2, 3, 4]]) + + >>> a = np.array([[1], [2], [3]]) + >>> b = np.array([[2], [3], [4]]) + >>> np.vstack((a,b)) + array([[1], + [2], + [3], + [2], + [3], + [4]]) + + """ + return _numpypy.concatenate(map(atleast_2d,tup),0) + +def hstack(tup): + """ + Stack arrays in sequence horizontally (column wise). + + Take a sequence of arrays and stack them horizontally to make + a single array. Rebuild arrays divided by `hsplit`. + + Parameters + ---------- + tup : sequence of ndarrays + All arrays must have the same shape along all but the second axis. + + Returns + ------- + stacked : ndarray + The array formed by stacking the given arrays. + + See Also + -------- + vstack : Stack arrays in sequence vertically (row wise). + dstack : Stack arrays in sequence depth wise (along third axis). + concatenate : Join a sequence of arrays together. + hsplit : Split array along second axis. + + Notes + ----- + Equivalent to ``np.concatenate(tup, axis=1)`` + + Examples + -------- + >>> a = np.array((1,2,3)) + >>> b = np.array((2,3,4)) + >>> np.hstack((a,b)) + array([1, 2, 3, 2, 3, 4]) + >>> a = np.array([[1],[2],[3]]) + >>> b = np.array([[2],[3],[4]]) + >>> np.hstack((a,b)) + array([[1, 2], + [2, 3], + [3, 4]]) + + """ + arrs = map(atleast_1d,tup) + # As a special case, dimension 0 of 1-dimensional arrays is "horizontal" + if arrs[0].ndim == 1: + return _numpypy.concatenate(arrs, 0) + else: + return _numpypy.concatenate(arrs, 1) + +def dstack(tup): + """ + Stack arrays in sequence depth wise (along third axis). + + Takes a sequence of arrays and stack them along the third axis + to make a single array. Rebuilds arrays divided by `dsplit`. + This is a simple way to stack 2D arrays (images) into a single + 3D array for processing. + + Parameters + ---------- + tup : sequence of arrays + Arrays to stack. All of them must have the same shape along all + but the third axis. + + Returns + ------- + stacked : ndarray + The array formed by stacking the given arrays. + + See Also + -------- + vstack : Stack along first axis. + hstack : Stack along second axis. + concatenate : Join arrays. + dsplit : Split array along third axis. + + Notes + ----- + Equivalent to ``np.concatenate(tup, axis=2)``. + + Examples + -------- + >>> a = np.array((1,2,3)) + >>> b = np.array((2,3,4)) + >>> np.dstack((a,b)) + array([[[1, 2], + [2, 3], + [3, 4]]]) + + >>> a = np.array([[1],[2],[3]]) + >>> b = np.array([[2],[3],[4]]) + >>> np.dstack((a,b)) + array([[[1, 2]], + [[2, 3]], + [[3, 4]]]) + + """ + return _numpypy.concatenate(map(atleast_3d,tup),2) diff --git a/lib_pypy/pypy_test/__init__.py b/lib_pypy/pypy_test/__init__.py deleted file mode 100644 --- a/lib_pypy/pypy_test/__init__.py +++ /dev/null @@ -1,1 +0,0 @@ -# diff --git a/lib_pypy/pypy_test/hack___pypy__.py b/lib_pypy/pypy_test/hack___pypy__.py deleted file mode 100644 --- a/lib_pypy/pypy_test/hack___pypy__.py +++ /dev/null @@ -1,9 +0,0 @@ -# here only to make test runs work even if not running on top of PyPy -import sys, new - -def builtinify(f): - return f - -pypy = new.module('__pypy__') -pypy.builtinify = builtinify -sys.modules.setdefault('__pypy__', pypy) diff --git a/lib_pypy/pypy_test/inprogress_test_binascii_extra.py b/lib_pypy/pypy_test/inprogress_test_binascii_extra.py deleted file mode 100644 --- a/lib_pypy/pypy_test/inprogress_test_binascii_extra.py +++ /dev/null @@ -1,19 +0,0 @@ -from __future__ import absolute_import -from lib_pypy import binascii - -def test_uu(): - assert binascii.b2a_uu('1234567') == "',3(S-#4V-P \n" - assert binascii.b2a_uu('123456789012345678901234567890123456789012345') == 'M,3(S-#4V-S at Y,#$R,S0U-C Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61351:a2a74b48aac6 Date: 2013-02-17 18:31 +0200 http://bitbucket.org/pypy/pypy/changeset/a2a74b48aac6/ Log: oops diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -284,7 +284,7 @@ offset = mc.get_relative_pos() - jnz_location assert 0 < offset <= 127 mc.overwrite(jnz_location-1, chr(offset)) - mc.JMP(self.propagate_exception_path) + mc.JMP_i(self.propagate_exception_path) # rawstart = mc.materialize(self.cpu.asmmemmgr, []) self.stack_check_slowpath = rawstart From noreply at buildbot.pypy.org Sun Feb 17 17:34:35 2013 From: noreply at buildbot.pypy.org (fijal) Date: Sun, 17 Feb 2013 17:34:35 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: no JMP_i, fine Message-ID: <20130217163435.1A00D1C0133@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61352:55ad9d09f1b1 Date: 2013-02-17 18:33 +0200 http://bitbucket.org/pypy/pypy/changeset/55ad9d09f1b1/ Log: no JMP_i, fine diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -284,7 +284,7 @@ offset = mc.get_relative_pos() - jnz_location assert 0 < offset <= 127 mc.overwrite(jnz_location-1, chr(offset)) - mc.JMP_i(self.propagate_exception_path) + mc.JMP(imm(self.propagate_exception_path)) # rawstart = mc.materialize(self.cpu.asmmemmgr, []) self.stack_check_slowpath = rawstart From noreply at buildbot.pypy.org Sun Feb 17 19:53:04 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Sun, 17 Feb 2013 19:53:04 +0100 (CET) Subject: [pypy-commit] pypy default: dead import removal + pep8 Message-ID: <20130217185304.8370B1C009B@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r61353:c6db23ce709e Date: 2013-02-17 10:52 -0800 http://bitbucket.org/pypy/pypy/changeset/c6db23ce709e/ Log: dead import removal + pep8 diff --git a/rpython/rtyper/rint.py b/rpython/rtyper/rint.py --- a/rpython/rtyper/rint.py +++ b/rpython/rtyper/rint.py @@ -1,17 +1,16 @@ import sys -from rpython.tool.pairtype import pairtype + from rpython.annotator import model as annmodel from rpython.flowspace.operation import op_appendices -from rpython.rtyper.lltypesystem.lltype import Signed, Unsigned, Bool, Float, \ - Void, Char, UniChar, malloc, UnsignedLongLong, \ - SignedLongLong, build_number, Number, cast_primitive, typeOf, \ - SignedLongLongLong -from rpython.rtyper.rmodel import IntegerRepr, inputconst -from rpython.rlib.rarithmetic import intmask, r_int, r_uint, r_ulonglong, \ - r_longlong, is_emulated_long -from rpython.rtyper.error import TyperError, MissingRTypeOperation -from rpython.rtyper.rmodel import log from rpython.rlib import objectmodel +from rpython.rlib.rarithmetic import intmask, r_int, r_longlong +from rpython.rtyper.error import TyperError +from rpython.rtyper.lltypesystem.lltype import (Signed, Unsigned, Bool, Float, + Char, UniChar, UnsignedLongLong, SignedLongLong, build_number, Number, + cast_primitive, typeOf, SignedLongLongLong) +from rpython.rtyper.rmodel import IntegerRepr, inputconst, log +from rpython.tool.pairtype import pairtype + _integer_reprs = {} def getintegerrepr(lltype, prefix=None): @@ -128,7 +127,7 @@ #comparisons: eq is_ ne lt le gt ge - def rtype_eq(_, hop): + def rtype_eq(_, hop): return _rtype_compare_template(hop, 'eq') rtype_is_ = rtype_eq @@ -259,7 +258,7 @@ get_ll_le_function = get_ll_eq_function def get_ll_ge_function(self): - return None + return None def get_ll_hash_function(self): if (sys.maxint == 2147483647 and @@ -279,7 +278,7 @@ ll_dummy_value = -1 def rtype_chr(_, hop): - vlist = hop.inputargs(Signed) + vlist = hop.inputargs(Signed) if hop.has_implicit_exception(ValueError): hop.exception_is_here() hop.gendirectcall(ll_check_chr, vlist[0]) @@ -301,8 +300,8 @@ vlist = hop.inputargs(self) return hop.genop(self.opprefix + 'is_true', vlist, resulttype=Bool) - #Unary arithmetic operations - + #Unary arithmetic operations + def rtype_abs(self, hop): self = self.as_int vlist = hop.inputargs(self) @@ -325,7 +324,7 @@ self = self.as_int vlist = hop.inputargs(self) return hop.genop(self.opprefix + 'invert', vlist, resulttype=self) - + def rtype_neg(self, hop): self = self.as_int vlist = hop.inputargs(self) diff --git a/rpython/rtyper/rmodel.py b/rpython/rtyper/rmodel.py --- a/rpython/rtyper/rmodel.py +++ b/rpython/rtyper/rmodel.py @@ -1,20 +1,18 @@ +from rpython.annotator import model as annmodel, unaryop, binaryop, description +from rpython.flowspace.model import Constant +from rpython.rtyper.error import TyperError, MissingRTypeOperation +from rpython.rtyper.lltypesystem import lltype +from rpython.rtyper.lltypesystem.lltype import (Void, Bool, Float, typeOf, + LowLevelType, isCompatibleType) from rpython.tool.pairtype import pairtype, extendabletype, pair -from rpython.annotator import model as annmodel, unaryop, binaryop -from rpython.annotator import description -from rpython.flowspace.model import Constant -from rpython.rtyper.lltypesystem.lltype import \ - Void, Bool, Float, Signed, Char, UniChar, \ - typeOf, LowLevelType, Ptr, isCompatibleType -from rpython.rtyper.lltypesystem import lltype, llmemory -from rpython.rtyper.ootypesystem import ootype -from rpython.rtyper.error import TyperError, MissingRTypeOperation -# initialization states for Repr instances -class setupstate(object): - NOTINITIALIZED = 0 +# initialization states for Repr instances + +class setupstate(object): + NOTINITIALIZED = 0 INPROGRESS = 1 - BROKEN = 2 + BROKEN = 2 FINISHED = 3 DELAYED = 4 @@ -27,7 +25,7 @@ iterating over. """ __metaclass__ = extendabletype - _initialized = setupstate.NOTINITIALIZED + _initialized = setupstate.NOTINITIALIZED def __repr__(self): return '<%s %s>' % (self.__class__.__name__, self.lowleveltype) @@ -35,31 +33,31 @@ def compact_repr(self): return '%s %s' % (self.__class__.__name__.replace('Repr','R'), self.lowleveltype._short_name()) - def setup(self): + def setup(self): """ call _setup_repr() and keep track of the initializiation status to e.g. detect recursive _setup_repr invocations. - the '_initialized' attr has four states: + the '_initialized' attr has four states: """ - if self._initialized == setupstate.FINISHED: - return - elif self._initialized == setupstate.BROKEN: + if self._initialized == setupstate.FINISHED: + return + elif self._initialized == setupstate.BROKEN: raise BrokenReprTyperError( "cannot setup already failed Repr: %r" %(self,)) - elif self._initialized == setupstate.INPROGRESS: + elif self._initialized == setupstate.INPROGRESS: raise AssertionError( "recursive invocation of Repr setup(): %r" %(self,)) elif self._initialized == setupstate.DELAYED: raise AssertionError( "Repr setup() is delayed and cannot be called yet: %r" %(self,)) - assert self._initialized == setupstate.NOTINITIALIZED - self._initialized = setupstate.INPROGRESS - try: - self._setup_repr() - except TyperError, e: - self._initialized = setupstate.BROKEN - raise - else: - self._initialized = setupstate.FINISHED + assert self._initialized == setupstate.NOTINITIALIZED + self._initialized = setupstate.INPROGRESS + try: + self._setup_repr() + except TyperError, e: + self._initialized = setupstate.BROKEN + raise + else: + self._initialized = setupstate.FINISHED def _setup_repr(self): "For recursive data structure, which must be initialized in two steps." @@ -68,15 +66,15 @@ """Same as setup(), called a bit later, for effects that are only needed after the typer finished (as opposed to needed for other parts of the typer itself).""" - if self._initialized == setupstate.BROKEN: + if self._initialized == setupstate.BROKEN: raise BrokenReprTyperError("cannot perform setup_final_touch " "on failed Repr: %r" %(self,)) assert self._initialized == setupstate.FINISHED, ( "setup_final() on repr with state %s: %r" % (self._initialized, self)) - self._setup_repr_final() + self._setup_repr_final() - def _setup_repr_final(self): + def _setup_repr_final(self): pass def is_setup_delayed(self): @@ -98,8 +96,8 @@ def __getattr__(self, name): # Assume that when an attribute is missing, it's because setup() needs # to be called - if not (name[:2] == '__' == name[-2:]): - if self._initialized == setupstate.NOTINITIALIZED: + if not (name[:2] == '__' == name[-2:]): + if self._initialized == setupstate.NOTINITIALIZED: self.setup() try: return self.__dict__[name] @@ -119,7 +117,7 @@ else: raise TyperError("convert_desc_or_const expects a Desc" "or Constant: %r" % desc_or_const) - + def convert_const(self, value): "Convert the given constant value to the low-level repr of 'self'." if self.lowleveltype is not Void: @@ -137,12 +135,12 @@ values of this Repr. This can return None to mean that simply using '==' is fine. """ - raise TyperError, 'no equality function for %r' % self + raise TyperError('no equality function for %r' % self) def get_ll_hash_function(self): """Return a hash(x) function for low-level values of this Repr. """ - raise TyperError, 'no hashing function for %r' % self + raise TyperError('no hashing function for %r' % self) def get_ll_fasthash_function(self): """Return a 'fast' hash(x) function for low-level values of this @@ -272,12 +270,15 @@ r_baseiter = r_container.make_iterator_repr() return EnumerateIteratorRepr(r_baseiter) return r_container.make_iterator_repr(*self.variant) + def rtyper_makekey_ex(self, rtyper): return self.__class__, rtyper.makekey(self.s_container), self.variant + class __extend__(annmodel.SomeImpossibleValue): def rtyper_makerepr(self, rtyper): return impossible_repr + def rtyper_makekey(self): return self.__class__, @@ -285,14 +286,14 @@ class __extend__(pairtype(Repr, Repr)): - + def rtype_is_((robj1, robj2), hop): if hop.s_result.is_constant(): return inputconst(Bool, hop.s_result.const) return hop.rtyper.type_system.generic_is(robj1, robj2, hop) # default implementation for checked getitems - + def rtype_getitem_idx_key((r_c1, r_o1), hop): return pair(r_c1, r_o1).rtype_getitem(hop) @@ -343,7 +344,7 @@ return self._opprefix opprefix = property(_get_opprefix) - + class BoolRepr(IntegerRepr): lowleveltype = Bool # NB. no 'opprefix' here. Use 'as_int' systematically. @@ -411,9 +412,9 @@ c.concretetype = lltype return c -class BrokenReprTyperError(TyperError): - """ raised when trying to setup a Repr whose setup - has failed already. +class BrokenReprTyperError(TyperError): + """ raised when trying to setup a Repr whose setup + has failed already. """ def mangle(prefix, name): @@ -489,6 +490,3 @@ def warning(msg): log.WARNING(msg) - - - diff --git a/rpython/rtyper/rpbc.py b/rpython/rtyper/rpbc.py --- a/rpython/rtyper/rpbc.py +++ b/rpython/rtyper/rpbc.py @@ -1,18 +1,15 @@ import types -import sys + +from rpython.annotator import model as annmodel, description +from rpython.flowspace.model import Constant +from rpython.rtyper import rclass, callparse +from rpython.rtyper.annlowlevel import llstr +from rpython.rtyper.error import TyperError +from rpython.rtyper.lltypesystem.lltype import typeOf, Void, Bool +from rpython.rtyper.rmodel import (Repr, inputconst, CanBeNull, mangle, + inputdesc, warning, impossible_repr) from rpython.tool.pairtype import pair, pairtype -from rpython.annotator import model as annmodel -from rpython.annotator import description -from rpython.flowspace.model import Constant -from rpython.rtyper.lltypesystem.lltype import \ - typeOf, Void, Bool, nullptr, frozendict, Ptr, Struct, malloc -from rpython.rtyper.error import TyperError -from rpython.rtyper.rmodel import Repr, inputconst, CanBeNull, \ - mangle, inputdesc, warning, impossible_repr -from rpython.rtyper import rclass -from rpython.rtyper.annlowlevel import llstr, llunicode -from rpython.rtyper import callparse def small_cand(rtyper, s_pbc): if 1 < len(s_pbc.descriptions) < rtyper.getconfig().translation.withsmallfuncsets and \ @@ -26,7 +23,7 @@ class __extend__(annmodel.SomePBC): def rtyper_makerepr(self, rtyper): if self.isNone(): - return none_frozen_pbc_repr + return none_frozen_pbc_repr kind = self.getKind() if issubclass(kind, description.FunctionDesc): sample = self.any_description() @@ -50,7 +47,7 @@ elif issubclass(kind, description.MethodOfFrozenDesc): getRepr = rtyper.type_system.rpbc.MethodOfFrozenPBCRepr else: - raise TyperError("unexpected PBC kind %r"%(kind,)) + raise TyperError("unexpected PBC kind %r" % (kind,)) return getRepr(rtyper, self) @@ -82,7 +79,7 @@ """ concretetable = {} # (shape,index): row, maybe with duplicates uniquerows = [] # list of rows, without duplicates - + def lookuprow(row): # a 'matching' row is one that has the same llfn, expect # that it may have more or less 'holes' @@ -333,15 +330,15 @@ return hop.llops.convertvar(v, rresult, hop.r_result) class __extend__(pairtype(AbstractFunctionsPBCRepr, AbstractFunctionsPBCRepr)): - def convert_from_to((r_fpbc1, r_fpbc2), v, llops): - # this check makes sense because both source and dest repr are FunctionsPBCRepr - if r_fpbc1.lowleveltype == r_fpbc2.lowleveltype: - return v - if r_fpbc1.lowleveltype is Void: - return inputconst(r_fpbc2, r_fpbc1.s_pbc.const) - if r_fpbc2.lowleveltype is Void: - return inputconst(Void, None) - return NotImplemented + def convert_from_to((r_fpbc1, r_fpbc2), v, llops): + # this check makes sense because both source and dest repr are FunctionsPBCRepr + if r_fpbc1.lowleveltype == r_fpbc2.lowleveltype: + return v + if r_fpbc1.lowleveltype is Void: + return inputconst(r_fpbc2, r_fpbc1.s_pbc.const) + if r_fpbc2.lowleveltype is Void: + return inputconst(Void, None) + return NotImplemented class OverriddenFunctionPBCRepr(Repr): def __init__(self, rtyper, s_pbc): @@ -377,7 +374,7 @@ result = rtyper.type_system.rpbc.MultipleFrozenPBCRepr(rtyper, access) rtyper.pbc_reprs[access] = result - rtyper.add_pendingsetup(result) + rtyper.add_pendingsetup(result) return result @@ -429,7 +426,7 @@ def convert_const(self, pbc): if pbc is None: - return self.null_instance() + return self.null_instance() if isinstance(pbc, types.MethodType) and pbc.im_self is None: value = pbc.im_func # unbound method -> bare function frozendesc = self.rtyper.annotator.bookkeeper.getdesc(pbc) @@ -455,7 +452,7 @@ mangled_name = mangle('pbc', attr) fields.append((mangled_name, r_value.lowleveltype)) self.fieldmap[attr] = mangled_name, r_value - return fields + return fields def convert_desc(self, frozendesc): if (self.access_set is not None and @@ -525,7 +522,7 @@ # XXX sort this out #call_families = rtyper.annotator.getpbccallfamilies() #call_families.find((None, self.function)) - + if s_pbc.can_be_none(): raise TyperError("unsupported: variable of type " "method-of-frozen-PBC or None") @@ -534,7 +531,7 @@ for desc in s_pbc.descriptions: assert desc.funcdesc is self.funcdesc im_selves.append(desc.frozendesc) - + self.s_im_self = annmodel.SomePBC(im_selves) self.r_im_self = rtyper.getrepr(self.s_im_self) self.lowleveltype = self.r_im_self.lowleveltype @@ -548,7 +545,7 @@ def convert_desc(self, mdesc): if mdesc.funcdesc is not self.funcdesc: - raise TyperError("not a method bound on %r: %r" % (self.funcdesc, + raise TyperError("not a method bound on %r: %r" % (self.funcdesc, mdesc)) return self.r_im_self.convert_desc(mdesc.frozendesc) @@ -615,7 +612,7 @@ def convert_from_to((r_from, _), v, llops): return inputconst(Void, None) - + def rtype_is_((robj1, rnone2), hop): if hop.s_result.is_constant(): return hop.inputconst(Bool, hop.s_result.const) @@ -666,7 +663,7 @@ def convert_desc(self, desc): if desc not in self.s_pbc.descriptions: - raise TyperError("%r not in %r" % (cls, self)) + raise TyperError("%r not in %r" % (desc, self)) if self.lowleveltype is Void: return None subclassdef = desc.getuniqueclassdef() @@ -726,7 +723,7 @@ s_init = classdef.classdesc.s_read_attribute('__init__') v_init = Constant("init-func-dummy") # this value not really used - if (isinstance(s_init, annmodel.SomeImpossibleValue) and + if (isinstance(s_init, annmodel.SomeImpossibleValue) and classdef.classdesc.is_exception_class() and classdef.has_no_attrs()): # special case for instanciating simple built-in @@ -753,7 +750,7 @@ else: s_init = access_set.s_value v_init = r_class.getpbcfield(vtypeptr, access_set, '__init__', - hop.llops) + hop.llops) v_instance = self._instantiate_runtime_class(hop, vtypeptr, r_instance) if isinstance(s_init, annmodel.SomeImpossibleValue): @@ -771,7 +768,6 @@ return v_instance - class __extend__(pairtype(AbstractClassesPBCRepr, rclass.AbstractClassRepr)): def convert_from_to((r_clspbc, r_cls), v, llops): # turn a PBC of classes to a standard pointer-to-vtable class repr @@ -904,4 +900,3 @@ for cdef1 in classdef.getmro(): for attrname in cdef1.attrs: yield cdef1, attrname - diff --git a/rpython/rtyper/rptr.py b/rpython/rtyper/rptr.py --- a/rpython/rtyper/rptr.py +++ b/rpython/rtyper/rptr.py @@ -1,10 +1,10 @@ -from rpython.tool.pairtype import pairtype from rpython.annotator import model as annmodel from rpython.flowspace import model as flowmodel +from rpython.rlib.rarithmetic import r_uint +from rpython.rtyper.error import TyperError from rpython.rtyper.lltypesystem import lltype -from rpython.rtyper.error import TyperError from rpython.rtyper.rmodel import Repr, IntegerRepr -from rpython.rlib.rarithmetic import r_uint +from rpython.tool.pairtype import pairtype class __extend__(annmodel.SomePtr): @@ -345,4 +345,3 @@ if r_from.lowleveltype == r_to.lowleveltype: return v return NotImplemented - diff --git a/rpython/rtyper/rrange.py b/rpython/rtyper/rrange.py --- a/rpython/rtyper/rrange.py +++ b/rpython/rtyper/rrange.py @@ -1,9 +1,9 @@ -from rpython.tool.pairtype import pairtype +from rpython.flowspace.model import Constant from rpython.rtyper.error import TyperError from rpython.rtyper.lltypesystem.lltype import Signed, Void, Ptr +from rpython.rtyper.rlist import dum_nocheck, dum_checkidx from rpython.rtyper.rmodel import Repr, IntegerRepr, IteratorRepr -from rpython.flowspace.model import Constant -from rpython.rtyper.rlist import dum_nocheck, dum_checkidx +from rpython.tool.pairtype import pairtype class AbstractRangeRepr(Repr): @@ -54,9 +54,9 @@ def _ll_rangelen(start, stop, step): if step > 0: - result = (stop - start + (step-1)) // step + result = (stop - start + (step - 1)) // step else: - result = (start - stop - (step+1)) // (-step) + result = (start - stop - (step + 1)) // (-step) if result < 0: result = 0 return result diff --git a/rpython/rtyper/rstr.py b/rpython/rtyper/rstr.py --- a/rpython/rtyper/rstr.py +++ b/rpython/rtyper/rstr.py @@ -1,16 +1,15 @@ -from rpython.tool.staticmethods import StaticMethods +from rpython.annotator import model as annmodel +from rpython.rlib import jit +from rpython.rtyper import rint +from rpython.rtyper.error import TyperError +from rpython.rtyper.lltypesystem.lltype import (Signed, Bool, Void, UniChar, + typeOf) +from rpython.rtyper.rmodel import IntegerRepr, IteratorRepr, inputconst, Repr +from rpython.rtyper.rtuple import AbstractTupleRepr from rpython.tool.pairtype import pairtype, pair from rpython.tool.sourcetools import func_with_new_name -from rpython.annotator import model as annmodel -from rpython.rlib import jit -from rpython.rlib.nonconst import NonConstant -from rpython.rtyper.error import TyperError -from rpython.rtyper.rmodel import IntegerRepr, IteratorRepr -from rpython.rtyper.rmodel import inputconst, Repr -from rpython.rtyper.rtuple import AbstractTupleRepr -from rpython.rtyper import rint -from rpython.rtyper.lltypesystem.lltype import Signed, Bool, Void, UniChar,\ - cast_primitive, typeOf +from rpython.tool.staticmethods import StaticMethods + class AbstractStringRepr(Repr): @@ -37,7 +36,7 @@ def ll_raise_unicode_exception_decode(self, errors, encoding, msg, s, startingpos, endingpos): raise UnicodeDecodeError(encoding, s, startingpos, endingpos, msg) - + class AbstractCharRepr(AbstractStringRepr): def rtype_method_lower(self, hop): @@ -87,7 +86,7 @@ def ll_raise_unicode_exception_encode(self, errors, encoding, msg, u, startingpos, endingpos): raise UnicodeEncodeError(encoding, u, startingpos, endingpos, msg) - + class __extend__(annmodel.SomeString): def rtyper_makerepr(self, rtyper): return rtyper.type_system.rstr.string_repr @@ -356,8 +355,8 @@ hop.exception_is_here() return hop.gendirectcall(self.ll.ll_int, v_str, c_base) if not hop.args_r[1] == rint.signed_repr: - raise TyperError, 'base needs to be an int' - v_str, v_base= hop.inputargs(string_repr, rint.signed_repr) + raise TyperError('base needs to be an int') + v_str, v_base = hop.inputargs(string_repr, rint.signed_repr) hop.exception_is_here() return hop.gendirectcall(self.ll.ll_int, v_str, v_base) @@ -653,7 +652,7 @@ def _rtype_compare_template(hop, func): rstr = hop.rtyper.type_system.rstr vlist = hop.inputargs(rstr.char_repr, rstr.char_repr) - return hop.genop('char_'+func, vlist, resulttype=Bool) + return hop.genop('char_' + func, vlist, resulttype=Bool) class __extend__(AbstractUniCharRepr): @@ -700,7 +699,7 @@ def _rtype_unchr_compare_template(hop, func): rstr = hop.rtyper.type_system.rstr vlist = hop.inputargs(rstr.unichar_repr, rstr.unichar_repr) - return hop.genop('unichar_'+func, vlist, resulttype=Bool) + return hop.genop('unichar_' + func, vlist, resulttype=Bool) # @@ -896,19 +895,18 @@ break if beg == n: raise ValueError - end = n-1 + end = n - 1 while end >= 0: if s[end] == ' ': end -= 1 else: break assert end >= 0 - return rstring_to_float(s[beg:end+1]) + return rstring_to_float(s[beg:end + 1]) def ll_splitlines(cls, LIST, ll_str, keep_newlines): from rpython.rtyper.annlowlevel import hlstr s = hlstr(ll_str) - STR = typeOf(ll_str) strlen = len(s) i = 0 j = 0 diff --git a/rpython/rtyper/rtuple.py b/rpython/rtyper/rtuple.py --- a/rpython/rtyper/rtuple.py +++ b/rpython/rtyper/rtuple.py @@ -1,20 +1,21 @@ import operator -from rpython.tool.pairtype import pairtype + from rpython.annotator import model as annmodel from rpython.flowspace.model import Constant -from rpython.rtyper.error import TyperError -from rpython.rtyper.rmodel import Repr, IntegerRepr, inputconst -from rpython.rtyper.rmodel import IteratorRepr -from rpython.rtyper.rmodel import externalvsinternal -from rpython.rtyper.lltypesystem.lltype import Void, Signed, Bool from rpython.rlib.rarithmetic import intmask from rpython.rlib.unroll import unrolling_iterable +from rpython.rtyper.error import TyperError +from rpython.rtyper.lltypesystem.lltype import Void, Signed, Bool +from rpython.rtyper.rmodel import (Repr, IntegerRepr, inputconst, IteratorRepr, + externalvsinternal) +from rpython.tool.pairtype import pairtype + class __extend__(annmodel.SomeTuple): def rtyper_makerepr(self, rtyper): repr_class = rtyper.type_system.rtuple.TupleRepr return repr_class(rtyper, [rtyper.getrepr(s_item) for s_item in self.items]) - + def rtyper_makekey_ex(self, rtyper): keys = [rtyper.makekey(s_item) for s_item in self.items] return tuple([self.__class__]+keys) @@ -202,29 +203,29 @@ for i in indices] return hop.r_result.newtuple(hop.llops, hop.r_result, items_v) -class __extend__(pairtype(AbstractTupleRepr, Repr)): +class __extend__(pairtype(AbstractTupleRepr, Repr)): def rtype_contains((r_tup, r_item), hop): s_tup = hop.args_s[0] if not s_tup.is_constant(): - raise TyperError("contains() on non-const tuple") + raise TyperError("contains() on non-const tuple") t = s_tup.const - typ = type(t[0]) - for x in t[1:]: - if type(x) is not typ: + typ = type(t[0]) + for x in t[1:]: + if type(x) is not typ: raise TyperError("contains() on mixed-type tuple " "constant %r" % (t,)) d = {} - for x in t: - d[x] = None + for x in t: + d[x] = None hop2 = hop.copy() _, _ = hop2.r_s_popfirstarg() v_dict = Constant(d) s_dict = hop.rtyper.annotator.bookkeeper.immutablevalue(d) hop2.v_s_insertfirstarg(v_dict, s_dict) return hop2.dispatch() - + class __extend__(pairtype(AbstractTupleRepr, AbstractTupleRepr)): - + def rtype_add((r_tup1, r_tup2), hop): v_tuple1, v_tuple2 = hop.inputargs(r_tup1, r_tup2) vlist = [] @@ -278,4 +279,3 @@ hop.exception_is_here() v = hop.gendirectcall(self.ll_tuplenext, v_iter) return hop.llops.convertvar(v, self.r_tuple.items_r[0], self.r_tuple.external_items_r[0]) - diff --git a/rpython/rtyper/rtyper.py b/rpython/rtyper/rtyper.py --- a/rpython/rtyper/rtyper.py +++ b/rpython/rtyper/rtyper.py @@ -12,25 +12,22 @@ """ import os + import py -from rpython.tool.pairtype import pair + from rpython.annotator import model as annmodel, unaryop, binaryop from rpython.annotator.annrpython import FAIL -from rpython.flowspace.model import Variable, Constant -from rpython.flowspace.model import SpaceOperation, c_last_exception -from rpython.rtyper.lltypesystem.lltype import \ - Signed, Unsigned, Float, Char, Bool, Void, \ - LowLevelType, Ptr, ContainerType, \ - FuncType, functionptr, typeOf, RuntimeTypeInfo, \ - attachRuntimeTypeInfo, Primitive, Number +from rpython.flowspace.model import Variable, Constant, SpaceOperation, c_last_exception +from rpython.rtyper.annlowlevel import annotate_lowlevel_helper, LowLevelAnnotatorPolicy +from rpython.rtyper.error import TyperError +from rpython.rtyper.lltypesystem.lltype import (Signed, Void, LowLevelType, + Ptr, ContainerType, FuncType, functionptr, typeOf, RuntimeTypeInfo, + attachRuntimeTypeInfo, Primitive) from rpython.rtyper.ootypesystem import ootype +from rpython.rtyper.rmodel import Repr, inputconst, BrokenReprTyperError +from rpython.rtyper.typesystem import LowLevelTypeSystem, ObjectOrientedTypeSystem +from rpython.tool.pairtype import pair from rpython.translator.unsimplify import insert_empty_block -from rpython.rtyper.error import TyperError -from rpython.rtyper.rmodel import Repr, inputconst, BrokenReprTyperError -from rpython.rtyper.rmodel import warning -from rpython.rtyper.annlowlevel import annotate_lowlevel_helper, LowLevelAnnotatorPolicy -from rpython.rtyper.typesystem import LowLevelTypeSystem,\ - ObjectOrientedTypeSystem class RPythonTyper(object): @@ -103,8 +100,8 @@ if isinstance(lltype, Primitive): repr = self.primitive_to_repr[lltype] = self.getrepr(annmodel.lltype_to_annotation(lltype)) return repr - raise TyperError('There is no primitive repr for %r'%(lltype,)) - + raise TyperError('There is no primitive repr for %r' % (lltype,)) + def add_wrapper(self, clsdef): # record that this class has a wrapper, and what the __init__ is cls = clsdef.classdesc.pyobj @@ -115,14 +112,14 @@ # not nice, but we sometimes need to know which function we are wrapping self.wrapper_context = obj - def add_pendingsetup(self, repr): + def add_pendingsetup(self, repr): assert isinstance(repr, Repr) - if repr in self._seen_reprs_must_call_setup: + if repr in self._seen_reprs_must_call_setup: #warning("ignoring already seen repr for setup: %r" %(repr,)) - return - self._reprs_must_call_setup.append(repr) - self._seen_reprs_must_call_setup[repr] = True - + return + self._reprs_must_call_setup.append(repr) + self._seen_reprs_must_call_setup[repr] = True + def getexceptiondata(self): return self.exceptiondata # built at the end of specialize() @@ -167,7 +164,7 @@ def makerepr(self, s_obj): return pair(self.type_system, s_obj).rtyper_makerepr(self) - + def getrepr(self, s_obj): # s_objs are not hashable... try hard to find a unique key anyway key = self.makekey(s_obj) @@ -268,8 +265,8 @@ # make sure all reprs so far have had their setup() called self.call_all_setups() - if self.typererrors: - self.dump_typererrors(to_log=True) + if self.typererrors: + self.dump_typererrors(to_log=True) raise TyperError("there were %d error" % len(self.typererrors)) self.log.event('-=- specialized %d%s blocks -=-' % ( blockcount, newtext)) @@ -312,12 +309,12 @@ if methname not in SELF._methods: ootype.addMethods(SELF, {methname: meth}) - def dump_typererrors(self, num=None, minimize=True, to_log=False): + def dump_typererrors(self, num=None, minimize=True, to_log=False): c = 0 bc = 0 - for err in self.typererrors[:num]: + for err in self.typererrors[:num]: c += 1 - if minimize and isinstance(err, BrokenReprTyperError): + if minimize and isinstance(err, BrokenReprTyperError): bc += 1 continue graph, block, position = err.where @@ -388,8 +385,8 @@ self.setup_block_entry(block) except TyperError, e: self.gottypererror(e, block, "block-entry", None) - return # cannot continue this block - + return # cannot continue this block + # specialize all the operations, as far as possible if block.operations == (): # return or except block @@ -412,7 +409,7 @@ extrablock = None pos = newops.llop_raising_exceptions - if (pos is not None and pos != len(newops)-1): + if (pos is not None and pos != len(newops) - 1): # this is for the case where the llop that raises the exceptions # is not the last one in the list. assert block.exitswitch == c_last_exception @@ -447,7 +444,7 @@ # consider it as a link source instead self.insert_link_conversions(extrablock) - def _convert_link(self, block, link): + def _convert_link(self, block, link): if link.exitcase is not None and link.exitcase != 'default': if isinstance(block.exitswitch, Variable): r_case = self.bindingrepr(block.exitswitch) @@ -800,11 +797,11 @@ return self.llops.gendirectcall(ll_function, *args_v) def r_s_pop(self, index=-1): - "Return and discard the argument with index position." + "Return and discard the argument with index position." self.nb_args -= 1 self.args_v.pop(index) return self.args_r.pop(index), self.args_s.pop(index) - + def r_s_popfirstarg(self): "Return and discard the first argument." return self.r_s_pop(0) @@ -966,7 +963,7 @@ else: args_s.append(annmodel.lltype_to_annotation(v.concretetype)) newargs_v.append(v) - + self.rtyper.call_all_setups() # compute ForwardReferences now # hack for bound methods From noreply at buildbot.pypy.org Sun Feb 17 20:25:53 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Sun, 17 Feb 2013 20:25:53 +0100 (CET) Subject: [pypy-commit] pypy py3k: 2to3 Message-ID: <20130217192553.9AD2B1C009B@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61354:4fd8ae7b9746 Date: 2013-02-17 11:23 -0800 http://bitbucket.org/pypy/pypy/changeset/4fd8ae7b9746/ Log: 2to3 diff --git a/pypy/module/__pypy__/test/test_signal.py b/pypy/module/__pypy__/test/test_signal.py --- a/pypy/module/__pypy__/test/test_signal.py +++ b/pypy/module/__pypy__/test/test_signal.py @@ -22,7 +22,7 @@ with __pypy__.thread.signals_enabled: thread.interrupt_main() for i in range(10): - print 'x' + print('x') time.sleep(0.1) except BaseException, e: interrupted.append(e) @@ -40,7 +40,7 @@ thread.start_new_thread(subthread, ()) for i in range(10): if len(done): break - print '.' + print('.') time.sleep(0.1) assert len(done) == 1 assert len(interrupted) == 1 From noreply at buildbot.pypy.org Sun Feb 17 20:25:54 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Sun, 17 Feb 2013 20:25:54 +0100 (CET) Subject: [pypy-commit] pypy py3k: ensure stderr's initialized before printing to it. this isn't easy to test Message-ID: <20130217192554.EE01D1C009B@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61355:4952d201e6a0 Date: 2013-02-17 11:24 -0800 http://bitbucket.org/pypy/pypy/changeset/4952d201e6a0/ Log: ensure stderr's initialized before printing to it. this isn't easy to test diff --git a/pypy/interpreter/app_main.py b/pypy/interpreter/app_main.py --- a/pypy/interpreter/app_main.py +++ b/pypy/interpreter/app_main.py @@ -672,6 +672,7 @@ executable = sys.pypy_find_executable(executable) stdlib_path = sys.pypy_find_stdlib(executable) if stdlib_path is None: + initstdio() print(STDLIB_WARNING, file=sys.stderr) else: sys.path[:] = stdlib_path From noreply at buildbot.pypy.org Sun Feb 17 21:31:29 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Sun, 17 Feb 2013 21:31:29 +0100 (CET) Subject: [pypy-commit] pypy py3k: normalize filesystemencoding Message-ID: <20130217203129.92B3D1C0133@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61356:53e06c688aa3 Date: 2013-02-17 12:27 -0800 http://bitbucket.org/pypy/pypy/changeset/53e06c688aa3/ Log: normalize filesystemencoding diff --git a/pypy/module/sys/interp_encoding.py b/pypy/module/sys/interp_encoding.py --- a/pypy/module/sys/interp_encoding.py +++ b/pypy/module/sys/interp_encoding.py @@ -44,7 +44,8 @@ w_res = space.call_method(codecmod, 'lookup', space.wrap(loc_codeset)) if space.is_true(w_res): - encoding = loc_codeset + w_name = space.getattr(w_res, space.wrap('name')) + encoding = space.str_w(w_name) finally: rlocale.setlocale(rlocale.LC_CTYPE, oldlocale) except rlocale.LocaleError: diff --git a/pypy/module/sys/test/test_encoding.py b/pypy/module/sys/test/test_encoding.py --- a/pypy/module/sys/test/test_encoding.py +++ b/pypy/module/sys/test/test_encoding.py @@ -23,8 +23,8 @@ clear() os.environ.update(original_env) - assert get() in (base_encoding, 'ANSI_X3.4-1968') - assert get(LANG='foobar') in (base_encoding, 'ANSI_X3.4-1968') - assert get(LANG='en_US.UTF-8') == 'UTF-8' - assert get(LC_ALL='en_US.UTF-8') == 'UTF-8' - assert get(LC_CTYPE='en_US.UTF-8') == 'UTF-8' + assert get() in (base_encoding, 'ascii') + assert get(LANG='foobar') in (base_encoding, 'ascii') + assert get(LANG='en_US.UTF-8') == 'utf-8' + assert get(LC_ALL='en_US.UTF-8') == 'utf-8' + assert get(LC_CTYPE='en_US.UTF-8') == 'utf-8' From noreply at buildbot.pypy.org Sun Feb 17 21:31:30 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Sun, 17 Feb 2013 21:31:30 +0100 (CET) Subject: [pypy-commit] pypy py3k: alphabetize Message-ID: <20130217203130.C9BD31C0133@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61357:f5639c619280 Date: 2013-02-17 12:30 -0800 http://bitbucket.org/pypy/pypy/changeset/f5639c619280/ Log: alphabetize diff --git a/pypy/module/exceptions/__init__.py b/pypy/module/exceptions/__init__.py --- a/pypy/module/exceptions/__init__.py +++ b/pypy/module/exceptions/__init__.py @@ -13,7 +13,6 @@ 'BufferError' : 'interp_exceptions.W_BufferError', 'BytesWarning' : 'interp_exceptions.W_BytesWarning', 'DeprecationWarning' : 'interp_exceptions.W_DeprecationWarning', - 'ResourceWarning' : 'interp_exceptions.W_ResourceWarning', 'EOFError' : 'interp_exceptions.W_EOFError', 'EnvironmentError' : 'interp_exceptions.W_EnvironmentError', 'Exception' : 'interp_exceptions.W_Exception', @@ -35,6 +34,7 @@ 'OverflowError' : 'interp_exceptions.W_OverflowError', 'PendingDeprecationWarning' : 'interp_exceptions.W_PendingDeprecationWarning', 'ReferenceError' : 'interp_exceptions.W_ReferenceError', + 'ResourceWarning' : 'interp_exceptions.W_ResourceWarning', 'RuntimeError' : 'interp_exceptions.W_RuntimeError', 'RuntimeWarning' : 'interp_exceptions.W_RuntimeWarning', 'StopIteration' : 'interp_exceptions.W_StopIteration', From noreply at buildbot.pypy.org Sun Feb 17 21:31:32 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Sun, 17 Feb 2013 21:31:32 +0100 (CET) Subject: [pypy-commit] pypy py3k: default ResourceWarning to ignore Message-ID: <20130217203132.28DB91C0133@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61358:a5aff3a56265 Date: 2013-02-17 12:30 -0800 http://bitbucket.org/pypy/pypy/changeset/a5aff3a56265/ Log: default ResourceWarning to ignore diff --git a/pypy/module/_warnings/interp_warnings.py b/pypy/module/_warnings/interp_warnings.py --- a/pypy/module/_warnings/interp_warnings.py +++ b/pypy/module/_warnings/interp_warnings.py @@ -32,6 +32,9 @@ filters_w.append(create_filter( space, space.w_BytesWarning, action)) + filters_w.append(create_filter( + space, space.w_ResourceWarning, "ignore")) + self.w_filters = space.newlist(filters_w) def get_warnings_attr(space, name): diff --git a/pypy/module/_warnings/test/test_warnings.py b/pypy/module/_warnings/test/test_warnings.py --- a/pypy/module/_warnings/test/test_warnings.py +++ b/pypy/module/_warnings/test/test_warnings.py @@ -5,7 +5,12 @@ import _warnings assert _warnings._onceregistry == {} assert _warnings._defaultaction == 'default' - assert "PendingDeprecationWarning" in str(_warnings.filters) + expected = [('ignore', None, DeprecationWarning, None, 0), + ('ignore', None, PendingDeprecationWarning, None, 0), + ('ignore', None, ImportWarning, None, 0), + ('ignore', None, BytesWarning, None, 0), + ('ignore', None, ResourceWarning, None, 0)] + assert expected == _warnings.filters def test_warn(self): import _warnings From noreply at buildbot.pypy.org Sun Feb 17 23:07:19 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Sun, 17 Feb 2013 23:07:19 +0100 (CET) Subject: [pypy-commit] pypy py3k: Prevent functools.reduce from binding to TestReduce class. Message-ID: <20130217220719.C4EB51C0133@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: py3k Changeset: r61359:1ae411871353 Date: 2013-02-16 17:23 +0100 http://bitbucket.org/pypy/pypy/changeset/1ae411871353/ Log: Prevent functools.reduce from binding to TestReduce class. diff --git a/lib-python/3.2/test/test_functools.py b/lib-python/3.2/test/test_functools.py --- a/lib-python/3.2/test/test_functools.py +++ b/lib-python/3.2/test/test_functools.py @@ -356,8 +356,6 @@ self.assertEqual(wrapper.dict_attr, f.dict_attr) class TestReduce(unittest.TestCase): - func = functools.reduce - def test_reduce(self): class Squares: def __init__(self, max): @@ -374,44 +372,45 @@ self.sofar.append(n*n) n += 1 return self.sofar[i] + reduce = functools.reduce def add(x, y): return x + y - self.assertEqual(self.func(add, ['a', 'b', 'c'], ''), 'abc') + self.assertEqual(reduce(add, ['a', 'b', 'c'], ''), 'abc') self.assertEqual( - self.func(add, [['a', 'c'], [], ['d', 'w']], []), + reduce(add, [['a', 'c'], [], ['d', 'w']], []), ['a','c','d','w'] ) - self.assertEqual(self.func(lambda x, y: x*y, range(2,8), 1), 5040) + self.assertEqual(reduce(lambda x, y: x*y, range(2,8), 1), 5040) self.assertEqual( - self.func(lambda x, y: x*y, range(2,21), 1), + reduce(lambda x, y: x*y, range(2,21), 1), 2432902008176640000 ) - self.assertEqual(self.func(add, Squares(10)), 285) - self.assertEqual(self.func(add, Squares(10), 0), 285) - self.assertEqual(self.func(add, Squares(0), 0), 0) - self.assertRaises(TypeError, self.func) - self.assertRaises(TypeError, self.func, 42, 42) - self.assertRaises(TypeError, self.func, 42, 42, 42) - self.assertEqual(self.func(42, "1"), "1") # func is never called with one item - self.assertEqual(self.func(42, "", "1"), "1") # func is never called with one item - self.assertRaises(TypeError, self.func, 42, (42, 42)) - self.assertRaises(TypeError, self.func, add, []) # arg 2 must not be empty sequence with no initial value - self.assertRaises(TypeError, self.func, add, "") - self.assertRaises(TypeError, self.func, add, ()) - self.assertRaises(TypeError, self.func, add, object()) + self.assertEqual(reduce(add, Squares(10)), 285) + self.assertEqual(reduce(add, Squares(10), 0), 285) + self.assertEqual(reduce(add, Squares(0), 0), 0) + self.assertRaises(TypeError, reduce) + self.assertRaises(TypeError, reduce, 42, 42) + self.assertRaises(TypeError, reduce, 42, 42, 42) + self.assertEqual(reduce(42, "1"), "1") # func is never called with one item + self.assertEqual(reduce(42, "", "1"), "1") # func is never called with one item + self.assertRaises(TypeError, reduce, 42, (42, 42)) + self.assertRaises(TypeError, reduce, add, []) # arg 2 must not be empty sequence with no initial value + self.assertRaises(TypeError, reduce, add, "") + self.assertRaises(TypeError, reduce, add, ()) + self.assertRaises(TypeError, reduce, add, object()) class TestFailingIter: def __iter__(self): raise RuntimeError - self.assertRaises(RuntimeError, self.func, add, TestFailingIter()) + self.assertRaises(RuntimeError, reduce, add, TestFailingIter()) - self.assertEqual(self.func(add, [], None), None) - self.assertEqual(self.func(add, [], 42), 42) + self.assertEqual(reduce(add, [], None), None) + self.assertEqual(reduce(add, [], 42), 42) class BadSeq: def __getitem__(self, index): raise ValueError - self.assertRaises(ValueError, self.func, 42, BadSeq()) + self.assertRaises(ValueError, reduce, 42, BadSeq()) # Test reduce()'s use of iterators. def test_iterator_usage(self): @@ -424,16 +423,17 @@ else: raise IndexError + reduce = functools.reduce from operator import add - self.assertEqual(self.func(add, SequenceClass(5)), 10) - self.assertEqual(self.func(add, SequenceClass(5), 42), 52) - self.assertRaises(TypeError, self.func, add, SequenceClass(0)) - self.assertEqual(self.func(add, SequenceClass(0), 42), 42) - self.assertEqual(self.func(add, SequenceClass(1)), 0) - self.assertEqual(self.func(add, SequenceClass(1), 42), 42) + self.assertEqual(reduce(add, SequenceClass(5)), 10) + self.assertEqual(reduce(add, SequenceClass(5), 42), 52) + self.assertRaises(TypeError, reduce, add, SequenceClass(0)) + self.assertEqual(reduce(add, SequenceClass(0), 42), 42) + self.assertEqual(reduce(add, SequenceClass(1)), 0) + self.assertEqual(reduce(add, SequenceClass(1), 42), 42) d = {"one": 1, "two": 2, "three": 3} - self.assertEqual(self.func(add, d), "".join(d.keys())) + self.assertEqual(reduce(add, d), "".join(d.keys())) class TestCmpToKey(unittest.TestCase): def test_cmp_to_key(self): From noreply at buildbot.pypy.org Sun Feb 17 23:07:21 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Sun, 17 Feb 2013 23:07:21 +0100 (CET) Subject: [pypy-commit] pypy py3k: Skip these checks (ported from 2.7's test_functools). Message-ID: <20130217220721.39C851C04F1@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: py3k Changeset: r61360:2aa29a87191b Date: 2013-02-16 17:25 +0100 http://bitbucket.org/pypy/pypy/changeset/2aa29a87191b/ Log: Skip these checks (ported from 2.7's test_functools). diff --git a/lib-python/3.2/test/test_functools.py b/lib-python/3.2/test/test_functools.py --- a/lib-python/3.2/test/test_functools.py +++ b/lib-python/3.2/test/test_functools.py @@ -47,6 +47,8 @@ # attributes should not be writable if not isinstance(self.thetype, type): return + if not test_support.check_impl_detail(): + return self.assertRaises(AttributeError, setattr, p, 'func', map) self.assertRaises(AttributeError, setattr, p, 'args', (1, 2)) self.assertRaises(AttributeError, setattr, p, 'keywords', dict(a=1, b=2)) From noreply at buildbot.pypy.org Sun Feb 17 23:07:22 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Sun, 17 Feb 2013 23:07:22 +0100 (CET) Subject: [pypy-commit] pypy py3k: Oops. Message-ID: <20130217220722.6A0581C0133@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: py3k Changeset: r61361:25627d9b6ee4 Date: 2013-02-16 17:29 +0100 http://bitbucket.org/pypy/pypy/changeset/25627d9b6ee4/ Log: Oops. diff --git a/lib-python/3.2/test/test_functools.py b/lib-python/3.2/test/test_functools.py --- a/lib-python/3.2/test/test_functools.py +++ b/lib-python/3.2/test/test_functools.py @@ -47,7 +47,7 @@ # attributes should not be writable if not isinstance(self.thetype, type): return - if not test_support.check_impl_detail(): + if not support.check_impl_detail(): return self.assertRaises(AttributeError, setattr, p, 'func', map) self.assertRaises(AttributeError, setattr, p, 'args', (1, 2)) From noreply at buildbot.pypy.org Sun Feb 17 23:07:23 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Sun, 17 Feb 2013 23:07:23 +0100 (CET) Subject: [pypy-commit] pypy py3k: Use equality operator instead of is operator. Message-ID: <20130217220723.9E9041C0133@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: py3k Changeset: r61362:c704dff6ddfa Date: 2013-02-16 17:34 +0100 http://bitbucket.org/pypy/pypy/changeset/c704dff6ddfa/ Log: Use equality operator instead of is operator. diff --git a/lib-python/3.2/test/test_functools.py b/lib-python/3.2/test/test_functools.py --- a/lib-python/3.2/test/test_functools.py +++ b/lib-python/3.2/test/test_functools.py @@ -205,7 +205,7 @@ updated=functools.WRAPPER_UPDATES): # Check attributes were assigned for name in assigned: - self.assertTrue(getattr(wrapper, name) is getattr(wrapped, name)) + self.assertTrue(getattr(wrapper, name) == getattr(wrapped, name)) # Check attributes were updated for name in updated: wrapper_attr = getattr(wrapper, name) From noreply at buildbot.pypy.org Sun Feb 17 23:07:24 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Sun, 17 Feb 2013 23:07:24 +0100 (CET) Subject: [pypy-commit] pypy py3k: Add a gc.collect() here (ported from 2.7's test_functools). Message-ID: <20130217220724.C4FFC1C0133@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: py3k Changeset: r61363:2ede4cf3b933 Date: 2013-02-16 17:36 +0100 http://bitbucket.org/pypy/pypy/changeset/2ede4cf3b933/ Log: Add a gc.collect() here (ported from 2.7's test_functools). diff --git a/lib-python/3.2/test/test_functools.py b/lib-python/3.2/test/test_functools.py --- a/lib-python/3.2/test/test_functools.py +++ b/lib-python/3.2/test/test_functools.py @@ -140,6 +140,7 @@ p = proxy(f) self.assertEqual(f.func, p.func) f = None + support.gc_collect() self.assertRaises(ReferenceError, getattr, p, 'func') def test_with_bound_and_unbound_methods(self): From noreply at buildbot.pypy.org Sun Feb 17 23:07:25 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Sun, 17 Feb 2013 23:07:25 +0100 (CET) Subject: [pypy-commit] pypy py3k: Fix TestPartial.test_repr(). Message-ID: <20130217220725.E70DE1C0133@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: py3k Changeset: r61364:90dd1dec9cba Date: 2013-02-16 17:55 +0100 http://bitbucket.org/pypy/pypy/changeset/90dd1dec9cba/ Log: Fix TestPartial.test_repr(). diff --git a/lib_pypy/_functools.py b/lib_pypy/_functools.py --- a/lib_pypy/_functools.py +++ b/lib_pypy/_functools.py @@ -40,3 +40,17 @@ if self.keywords is not None: fkeywords = dict(self.keywords, **fkeywords) return self.func(*(self.args + fargs), **fkeywords) + + def __repr__(self): + cls = type(self) + if cls is partial: + name = 'functools.partial' + else: + name = cls.__name__ + tmp = [repr(self.func)] + for arg in self.args: + tmp.append(repr(arg)) + if self.keywords: + for k, v in self.keywords.items(): + tmp.append("{}={!r}".format(k, v)) + return "{}({})".format(name, ', '.join(tmp)) From noreply at buildbot.pypy.org Sun Feb 17 23:07:27 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Sun, 17 Feb 2013 23:07:27 +0100 (CET) Subject: [pypy-commit] pypy py3k: Print a better error message when too many positional arguments are given. Message-ID: <20130217220727.28D501C0133@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: py3k Changeset: r61365:2fb15b5200b6 Date: 2013-02-16 18:34 +0100 http://bitbucket.org/pypy/pypy/changeset/2fb15b5200b6/ Log: Print a better error message when too many positional arguments are given. diff --git a/pypy/interpreter/argument.py b/pypy/interpreter/argument.py --- a/pypy/interpreter/argument.py +++ b/pypy/interpreter/argument.py @@ -508,6 +508,8 @@ plural = "s" if has_kwarg or num_kwds > 0: msg2 = " non-keyword" + elif defcount != -1: # XXX not sure about this + msg2 = " positional" else: msg2 = "" msg = "takes %s %d%s argument%s (%d given)" % ( diff --git a/pypy/interpreter/test/test_argument.py b/pypy/interpreter/test/test_argument.py --- a/pypy/interpreter/test/test_argument.py +++ b/pypy/interpreter/test/test_argument.py @@ -698,3 +698,11 @@ assert e.value.args[0] == "f() got an unexpected keyword argument 'ü'" """ + def test_error_positional(self): + """ + def f(a, b=None, *, c=None): + pass + exc = raises(TypeError, f, 1, 2, 3) + expected = "f() takes at most 2 positional arguments (3 given)" + assert str(exc.value) == expected + """ From noreply at buildbot.pypy.org Sun Feb 17 23:07:28 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Sun, 17 Feb 2013 23:07:28 +0100 (CET) Subject: [pypy-commit] pypy py3k: Raise the right error if int() is called with a base that doesn't fit into the machine's long int type. Message-ID: <20130217220728.994FB1C0133@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: py3k Changeset: r61366:a8df5c23b131 Date: 2013-02-16 18:52 +0100 http://bitbucket.org/pypy/pypy/changeset/a8df5c23b131/ Log: Raise the right error if int() is called with a base that doesn't fit into the machine's long int type. diff --git a/pypy/objspace/std/longtype.py b/pypy/objspace/std/longtype.py --- a/pypy/objspace/std/longtype.py +++ b/pypy/objspace/std/longtype.py @@ -48,7 +48,12 @@ bigint = space.bigint_w(w_obj) return newbigint(space, w_longtype, bigint) else: - base = space.int_w(w_base) + try: + base = space.int_w(w_base) + except OperationError, e: + if not e.match(space, space.w_OverflowError): + raise + base = 37 # this raises the right error in string_to_bigint() if space.isinstance_w(w_value, space.w_unicode): from pypy.objspace.std.unicodeobject import unicode_to_decimal_w diff --git a/pypy/objspace/std/test/test_longobject.py b/pypy/objspace/std/test/test_longobject.py --- a/pypy/objspace/std/test/test_longobject.py +++ b/pypy/objspace/std/test/test_longobject.py @@ -340,3 +340,6 @@ assert 'hello àèìò' in e.message else: assert False, 'did not raise' + + def test_base_overflow(self): + raises(ValueError, int, '42', 2**63) From noreply at buildbot.pypy.org Sun Feb 17 23:07:29 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Sun, 17 Feb 2013 23:07:29 +0100 (CET) Subject: [pypy-commit] pypy py3k: Port gc.collect()s from 2.7's test_tempfile. Message-ID: <20130217220729.BF6DC1C0133@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: py3k Changeset: r61367:68ca8b45806c Date: 2013-02-16 19:06 +0100 http://bitbucket.org/pypy/pypy/changeset/68ca8b45806c/ Log: Port gc.collect()s from 2.7's test_tempfile. diff --git a/lib-python/3.2/test/test_tempfile.py b/lib-python/3.2/test/test_tempfile.py --- a/lib-python/3.2/test/test_tempfile.py +++ b/lib-python/3.2/test/test_tempfile.py @@ -285,6 +285,7 @@ dir = tempfile.mkdtemp() try: self.do_create(dir=dir).write(b"blat") + support.gc_collect() finally: os.rmdir(dir) @@ -575,12 +576,15 @@ self.do_create(suf="b") self.do_create(pre="a", suf="b") self.do_create(pre="aa", suf=".txt") + support.gc_collect() def test_many(self): # mktemp can choose many usable file names (stochastic) extant = list(range(TEST_FILES)) for i in extant: extant[i] = self.do_create(pre="aa") + del extant + support.gc_collect() ## def test_warning(self): ## # mktemp issues a warning when used From noreply at buildbot.pypy.org Sun Feb 17 23:07:31 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Sun, 17 Feb 2013 23:07:31 +0100 (CET) Subject: [pypy-commit] pypy py3k: Add another gc.collect() in test_tempfile. Message-ID: <20130217220731.0222D1C0133@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: py3k Changeset: r61368:33195eac3e1c Date: 2013-02-16 19:14 +0100 http://bitbucket.org/pypy/pypy/changeset/33195eac3e1c/ Log: Add another gc.collect() in test_tempfile. diff --git a/lib-python/3.2/test/test_tempfile.py b/lib-python/3.2/test/test_tempfile.py --- a/lib-python/3.2/test/test_tempfile.py +++ b/lib-python/3.2/test/test_tempfile.py @@ -1016,6 +1016,7 @@ "TemporaryDirectory %s exists after cleanup" % d1.name) self.assertTrue(os.path.exists(d2.name), "Directory pointed to by a symlink was deleted") + support.gc_collect() self.assertEqual(os.listdir(d2.name), ['test.txt'], "Contents of the directory pointed to by a symlink " "were deleted") From noreply at buildbot.pypy.org Sun Feb 17 23:07:32 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Sun, 17 Feb 2013 23:07:32 +0100 (CET) Subject: [pypy-commit] pypy py3k: Don't test for hash randomization on PyPy. Message-ID: <20130217220732.3DBDA1C0133@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: py3k Changeset: r61369:b507401b531e Date: 2013-02-16 23:33 +0100 http://bitbucket.org/pypy/pypy/changeset/b507401b531e/ Log: Don't test for hash randomization on PyPy. diff --git a/lib-python/3.2/test/test_cmd_line.py b/lib-python/3.2/test/test_cmd_line.py --- a/lib-python/3.2/test/test_cmd_line.py +++ b/lib-python/3.2/test/test_cmd_line.py @@ -8,6 +8,7 @@ import subprocess import tempfile from test.script_helper import spawn_python, kill_python, assert_python_ok, assert_python_failure +from test.support import check_impl_detail # XXX (ncoghlan): Move to script_helper and make consistent with run_python @@ -339,7 +340,8 @@ rc, out, err = assert_python_ok('-R', '-c', code) self.assertEqual(rc, 0) hashes.append(out) - self.assertNotEqual(hashes[0], hashes[1]) + if check_impl_detail(pypy=False): # PyPy does not really implement it! + self.assertNotEqual(hashes[0], hashes[1]) # Verify that sys.flags contains hash_randomization code = 'import sys; print("random is", sys.flags.hash_randomization)' From noreply at buildbot.pypy.org Sun Feb 17 23:07:33 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Sun, 17 Feb 2013 23:07:33 +0100 (CET) Subject: [pypy-commit] pypy py3k: Ensure that repr() is the same as str(). Message-ID: <20130217220733.6B6E51C0133@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: py3k Changeset: r61370:858eded385ad Date: 2013-02-16 23:58 +0100 http://bitbucket.org/pypy/pypy/changeset/858eded385ad/ Log: Ensure that repr() is the same as str(). diff --git a/pypy/objspace/std/floatobject.py b/pypy/objspace/std/floatobject.py --- a/pypy/objspace/std/floatobject.py +++ b/pypy/objspace/std/floatobject.py @@ -162,11 +162,14 @@ s = "nan" return s +#XXX short float repr? + def repr__Float(space, w_float): return space.wrap(float2string(w_float.floatval, 'r', 0)) def str__Float(space, w_float): - return space.wrap(float2string(w_float.floatval, 'g', DTSF_STR_PRECISION)) + return space.wrap(float2string(w_float.floatval, 'r', 0)) + #return space.wrap(float2string(w_float.floatval, 'g', DTSF_STR_PRECISION)) def format__Float_ANY(space, w_float, w_spec): return newformat.run_formatter(space, w_spec, "format_float", w_float) diff --git a/pypy/objspace/std/test/test_floatobject.py b/pypy/objspace/std/test/test_floatobject.py --- a/pypy/objspace/std/test/test_floatobject.py +++ b/pypy/objspace/std/test/test_floatobject.py @@ -837,3 +837,6 @@ check(mod(0.0, -1.0), -0.0) check(mod(1e-100, -1.0), -1.0) check(mod(1.0, -1.0), -0.0) + + def test_repr_str_eq(self): + assert repr(19 * 0.1) == str(19 * 0.1) From noreply at buildbot.pypy.org Sun Feb 17 23:07:34 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Sun, 17 Feb 2013 23:07:34 +0100 (CET) Subject: [pypy-commit] pypy py3k: Raise ArgumentError here again. Message-ID: <20130217220734.98BED1C0133@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: py3k Changeset: r61371:effcd581dd9e Date: 2013-02-17 03:27 +0100 http://bitbucket.org/pypy/pypy/changeset/effcd581dd9e/ Log: Raise ArgumentError here again. diff --git a/lib_pypy/_ctypes/function.py b/lib_pypy/_ctypes/function.py --- a/lib_pypy/_ctypes/function.py +++ b/lib_pypy/_ctypes/function.py @@ -556,7 +556,6 @@ try: keepalive, newarg, newargtype = self._conv_param(argtype, args[i]) except (UnicodeError, TypeError, ValueError) as e: - raise raise ArgumentError(str(e)) keepalives.append(keepalive) newargs.append(newarg) From noreply at buildbot.pypy.org Sun Feb 17 23:07:35 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Sun, 17 Feb 2013 23:07:35 +0100 (CET) Subject: [pypy-commit] pypy py3k: Fix slicing. Message-ID: <20130217220735.B79DC1C0133@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: py3k Changeset: r61372:ce51a8cf30f4 Date: 2013-02-17 03:34 +0100 http://bitbucket.org/pypy/pypy/changeset/ce51a8cf30f4/ Log: Fix slicing. diff --git a/lib_pypy/_ctypes/array.py b/lib_pypy/_ctypes/array.py --- a/lib_pypy/_ctypes/array.py +++ b/lib_pypy/_ctypes/array.py @@ -144,7 +144,7 @@ l = [self[i] for i in range(start, stop, step)] letter = getattr(self._type_, '_type_', None) if letter == 'c': - return b"".join(l) + return bytes(l) if letter == 'u': return "".join(l) return l From noreply at buildbot.pypy.org Sun Feb 17 23:07:36 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Sun, 17 Feb 2013 23:07:36 +0100 (CET) Subject: [pypy-commit] pypy py3k: 2to3 Message-ID: <20130217220736.D5F791C0133@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: py3k Changeset: r61373:4da3c416a10c Date: 2013-02-17 14:46 +0100 http://bitbucket.org/pypy/pypy/changeset/4da3c416a10c/ Log: 2to3 diff --git a/pypy/module/_rawffi/test/test__rawffi.py b/pypy/module/_rawffi/test/test__rawffi.py --- a/pypy/module/_rawffi/test/test__rawffi.py +++ b/pypy/module/_rawffi/test/test__rawffi.py @@ -260,7 +260,6 @@ assert lib.ptr(1, [], 'i')()[0] == 42 def test_getchar(self): - py3k_skip('bytes vs unicode') import _rawffi lib = _rawffi.CDLL(self.lib_name) get_char = lib.ptr('get_char', ['P', 'H'], 'c') @@ -272,7 +271,7 @@ intptr = B(1) intptr[0] = i res = get_char(dupaptr, intptr) - assert res[0] == 'dupa'[i:i+1] + assert res[0] == b'dupa'[i:i+1] intptr.free() dupaptr.free() dupa.free() From noreply at buildbot.pypy.org Sun Feb 17 23:07:38 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Sun, 17 Feb 2013 23:07:38 +0100 (CET) Subject: [pypy-commit] pypy py3k: Work around BytecodeCorruption exception. Message-ID: <20130217220738.187051C0133@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: py3k Changeset: r61374:32478fc9726f Date: 2013-02-17 14:48 +0100 http://bitbucket.org/pypy/pypy/changeset/32478fc9726f/ Log: Work around BytecodeCorruption exception. diff --git a/pypy/module/_rawffi/test/test__rawffi.py b/pypy/module/_rawffi/test/test__rawffi.py --- a/pypy/module/_rawffi/test/test__rawffi.py +++ b/pypy/module/_rawffi/test/test__rawffi.py @@ -271,7 +271,8 @@ intptr = B(1) intptr[0] = i res = get_char(dupaptr, intptr) - assert res[0] == b'dupa'[i:i+1] + char = b'dupa'[i:i+1] + assert res[0] == char intptr.free() dupaptr.free() dupa.free() From noreply at buildbot.pypy.org Sun Feb 17 23:07:39 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Sun, 17 Feb 2013 23:07:39 +0100 (CET) Subject: [pypy-commit] pypy py3k: Revert some changes in this test: __getitem__ on _rawffi char arrays is supposed to return one-byte strings instead of integers. Message-ID: <20130217220739.4D1251C0133@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: py3k Changeset: r61375:252004d8094b Date: 2013-02-17 15:43 +0100 http://bitbucket.org/pypy/pypy/changeset/252004d8094b/ Log: Revert some changes in this test: __getitem__ on _rawffi char arrays is supposed to return one-byte strings instead of integers. diff --git a/pypy/module/_rawffi/test/test__rawffi.py b/pypy/module/_rawffi/test/test__rawffi.py --- a/pypy/module/_rawffi/test/test__rawffi.py +++ b/pypy/module/_rawffi/test/test__rawffi.py @@ -282,10 +282,10 @@ import _rawffi A = _rawffi.Array('c') buf = A(10, autofree=True) - buf[0] = ord('*') + buf[0] = b'*' assert buf[1:5] == b'\x00' * 4 buf[7:] = b'abc' - assert buf[9] == ord('c') + assert buf[9] == b'c' assert buf[:8] == b'*' + b'\x00'*6 + b'a' def test_returning_str(self): @@ -450,13 +450,13 @@ X = _rawffi.Structure([('x1', 'i'), ('x2', 'h'), ('x3', 'c'), ('next', 'P')]) next = X() next.next = 0 - next.x3 = ord('x') + next.x3 = b'x' x = X() x.next = next x.x1 = 1 x.x2 = 2 - x.x3 = ord('x') - assert X.fromaddress(x.next).x3 == ord('x') + x.x3 = b'x' + assert X.fromaddress(x.next).x3 == b'x' x.free() next.free() create_double_struct = lib.ptr("create_double_struct", [], 'P') @@ -997,15 +997,15 @@ A = _rawffi.Array('c') a = A(10, autofree=True) - a[3] = ord('x') + a[3] = b'x' b = memoryview(a) assert len(b) == 10 assert b[3] == b'x' b[6] = b'y' - assert a[6] == ord('y') + assert a[6] == b'y' b[3:5] = b'zt' - assert a[3] == ord('z') - assert a[4] == ord('t') + assert a[3] == b'z' + assert a[4] == b't' def test_union(self): import _rawffi From noreply at buildbot.pypy.org Sun Feb 17 23:07:40 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Sun, 17 Feb 2013 23:07:40 +0100 (CET) Subject: [pypy-commit] pypy py3k: Change API for _rawffi Arrays of type 'c': accept and return one-byte strings, like in default. Message-ID: <20130217220740.827531C0133@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: py3k Changeset: r61376:df47657149c2 Date: 2013-02-17 16:59 +0100 http://bitbucket.org/pypy/pypy/changeset/df47657149c2/ Log: Change API for _rawffi Arrays of type 'c': accept and return one- byte strings, like in default. diff --git a/pypy/module/_rawffi/interp_rawffi.py b/pypy/module/_rawffi/interp_rawffi.py --- a/pypy/module/_rawffi/interp_rawffi.py +++ b/pypy/module/_rawffi/interp_rawffi.py @@ -2,7 +2,6 @@ from pypy.interpreter.error import OperationError, wrap_oserror, operationerrfmt from pypy.interpreter.gateway import interp2app, unwrap_spec from pypy.interpreter.typedef import TypeDef, GetSetProperty -from pypy.objspace.std.stringtype import getbytevalue from rpython.rlib.clibffi import * from rpython.rtyper.lltypesystem import lltype, rffi @@ -55,7 +54,7 @@ return intmask(ffi_type.c_size), intmask(ffi_type.c_alignment) LL_TYPEMAP = { - 'c' : rffi.UCHAR, + 'c' : rffi.CHAR, 'u' : lltype.UniChar, 'b' : rffi.SIGNEDCHAR, 'B' : rffi.UCHAR, @@ -334,7 +333,11 @@ push_func(add_arg, argdesc, rffi.cast(rffi.LONGDOUBLE, space.float_w(w_arg))) elif letter == "c": - val = getbytevalue(space, w_arg) + s = space.str_w(w_arg) + if len(s) != 1: + raise OperationError(space.w_TypeError, w( + "Expected string of length one as character")) + val = s[0] push_func(add_arg, argdesc, val) elif letter == 'u': s = space.unicode_w(w_arg) @@ -363,7 +366,9 @@ if c in TYPEMAP_PTR_LETTERS: res = func(add_arg, argdesc, rffi.VOIDP) return space.wrap(rffi.cast(lltype.Unsigned, res)) - elif c == 'q' or c == 'Q' or c == 'L' or c == 'c' or c == 'u': + elif c == 'c': + return space.wrapbytes(func(add_arg, argdesc, ll_type)) + elif c == 'q' or c == 'Q' or c == 'L' or c == 'u': return space.wrap(func(add_arg, argdesc, ll_type)) elif c == 'f' or c == 'd' or c == 'g': return space.wrap(float(func(add_arg, argdesc, ll_type))) diff --git a/pypy/module/_rawffi/test/test__rawffi.py b/pypy/module/_rawffi/test/test__rawffi.py --- a/pypy/module/_rawffi/test/test__rawffi.py +++ b/pypy/module/_rawffi/test/test__rawffi.py @@ -260,12 +260,14 @@ assert lib.ptr(1, [], 'i')()[0] == 42 def test_getchar(self): + def _bytestring_to_list(bytestring): + return [bytestring[i:i+1] for i in range(len(bytestring))] import _rawffi lib = _rawffi.CDLL(self.lib_name) get_char = lib.ptr('get_char', ['P', 'H'], 'c') A = _rawffi.Array('c') B = _rawffi.Array('H') - dupa = A(5, b'dupa') + dupa = A(5, _bytestring_to_list(b'dupa')) dupaptr = dupa.byptr() for i in range(4): intptr = B(1) @@ -289,7 +291,8 @@ assert buf[:8] == b'*' + b'\x00'*6 + b'a' def test_returning_str(self): - py3k_skip('bytes vs unicode') + def _bytestring_to_list(bytestring): + return [bytestring[i:i+1] for i in range(len(bytestring))] import _rawffi lib = _rawffi.CDLL(self.lib_name) char_check = lib.ptr('char_check', ['c', 'c'], 's') @@ -302,7 +305,7 @@ assert _rawffi.charp2string(res[0]) == b'xxxxxx' assert _rawffi.charp2rawstring(res[0]) == b'xxxxxx' assert _rawffi.charp2rawstring(res[0], 3) == b'xxx' - a = A(6, b'xx\x00\x00xx') + a = A(6, _bytestring_to_list(b'xx\x00\x00xx')) assert _rawffi.charp2string(a.buffer) == b'xx' assert _rawffi.charp2rawstring(a.buffer, 4) == b'xx\x00\x00' arg1[0] = b'x' @@ -1046,12 +1049,14 @@ assert oldnum == _rawffi._num_of_allocated_objects() def test_array_autofree(self): + def _bytestring_to_list(bytestring): + return [bytestring[i:i+1] for i in range(len(bytestring))] import gc, _rawffi gc.collect() oldnum = _rawffi._num_of_allocated_objects() A = _rawffi.Array('c') - a = A(6, b'xxyxx\x00', autofree=True) + a = A(6, _bytestring_to_list(b'xxyxx\x00'), autofree=True) assert _rawffi.charp2string(a.buffer) == b'xxyxx' a = None gc.collect() From noreply at buildbot.pypy.org Sun Feb 17 23:07:41 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Sun, 17 Feb 2013 23:07:41 +0100 (CET) Subject: [pypy-commit] pypy py3k: Fix these tests to use the new API for _rawffi char Arrays. Message-ID: <20130217220741.B324B1C0133@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: py3k Changeset: r61377:976cb0174d70 Date: 2013-02-17 17:06 +0100 http://bitbucket.org/pypy/pypy/changeset/976cb0174d70/ Log: Fix these tests to use the new API for _rawffi char Arrays. diff --git a/pypy/module/_rawffi/test/test_nested.py b/pypy/module/_rawffi/test/test_nested.py --- a/pypy/module/_rawffi/test/test_nested.py +++ b/pypy/module/_rawffi/test/test_nested.py @@ -43,14 +43,14 @@ assert S.fieldoffset('x') == 0 assert S.fieldoffset('s1') == S1.alignment s = S() - s.x = ord('G') + s.x = b'G' raises(TypeError, 's.s1') assert s.fieldaddress('s1') == s.buffer + S.fieldoffset('s1') s1 = S1.fromaddress(s.fieldaddress('s1')) - s1.c = ord('H') + s1.c = b'H' rawbuf = _rawffi.Array('c').fromaddress(s.buffer, S.size) - assert rawbuf[0] == ord('G') - assert rawbuf[S1.alignment + S1.fieldoffset('c')] == ord('H') + assert rawbuf[0] == b'G' + assert rawbuf[S1.alignment + S1.fieldoffset('c')] == b'H' s.free() def test_array_of_structures(self): @@ -60,17 +60,17 @@ a = A(3) raises(TypeError, "a[0]") s0 = S.fromaddress(a.buffer) - s0.c = ord('B') + s0.c = b'B' assert a.itemaddress(1) == a.buffer + S.size s1 = S.fromaddress(a.itemaddress(1)) - s1.c = ord('A') + s1.c = b'A' s2 = S.fromaddress(a.itemaddress(2)) - s2.c = ord('Z') + s2.c = b'Z' rawbuf = _rawffi.Array('c').fromaddress(a.buffer, S.size * len(a)) ofs = S.fieldoffset('c') - assert rawbuf[0*S.size+ofs] == ord('B') - assert rawbuf[1*S.size+ofs] == ord('A') - assert rawbuf[2*S.size+ofs] == ord('Z') + assert rawbuf[0*S.size+ofs] == b'B' + assert rawbuf[1*S.size+ofs] == b'A' + assert rawbuf[2*S.size+ofs] == b'Z' a.free() def test_array_of_array(self): @@ -103,16 +103,16 @@ assert S.fieldoffset('x') == 0 assert S.fieldoffset('ar') == A5alignment s = S() - s.x = ord('G') + s.x = b'G' raises(TypeError, 's.ar') assert s.fieldaddress('ar') == s.buffer + S.fieldoffset('ar') a1 = A.fromaddress(s.fieldaddress('ar'), 5) a1[4] = 33 rawbuf = _rawffi.Array('c').fromaddress(s.buffer, S.size) - assert rawbuf[0] == ord('G') + assert rawbuf[0] == b'G' sizeofint = struct.calcsize("i") v = 0 for i in range(sizeofint): - v += rawbuf[A5alignment + sizeofint*4+i] + v += ord(rawbuf[A5alignment + sizeofint*4+i]) assert v == 33 s.free() From noreply at buildbot.pypy.org Sun Feb 17 23:07:42 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Sun, 17 Feb 2013 23:07:42 +0100 (CET) Subject: [pypy-commit] pypy py3k: Also accept integers but return one-byte strings. Message-ID: <20130217220742.E28F51C0133@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: py3k Changeset: r61378:dca1c3574ab8 Date: 2013-02-17 18:51 +0100 http://bitbucket.org/pypy/pypy/changeset/dca1c3574ab8/ Log: Also accept integers but return one-byte strings. diff --git a/pypy/module/_rawffi/interp_rawffi.py b/pypy/module/_rawffi/interp_rawffi.py --- a/pypy/module/_rawffi/interp_rawffi.py +++ b/pypy/module/_rawffi/interp_rawffi.py @@ -2,6 +2,7 @@ from pypy.interpreter.error import OperationError, wrap_oserror, operationerrfmt from pypy.interpreter.gateway import interp2app, unwrap_spec from pypy.interpreter.typedef import TypeDef, GetSetProperty +from pypy.objspace.std.stringtype import getbytevalue from rpython.rlib.clibffi import * from rpython.rtyper.lltypesystem import lltype, rffi @@ -333,11 +334,14 @@ push_func(add_arg, argdesc, rffi.cast(rffi.LONGDOUBLE, space.float_w(w_arg))) elif letter == "c": - s = space.str_w(w_arg) - if len(s) != 1: - raise OperationError(space.w_TypeError, w( - "Expected string of length one as character")) - val = s[0] + if space.isinstance_w(w_arg, space.w_int): + val = getbytevalue(space, w_arg) + else: + s = space.str_w(w_arg) + if len(s) != 1: + raise OperationError(space.w_TypeError, w( + "Expected string of length one as character")) + val = s[0] push_func(add_arg, argdesc, val) elif letter == 'u': s = space.unicode_w(w_arg) diff --git a/pypy/module/_rawffi/test/test__rawffi.py b/pypy/module/_rawffi/test/test__rawffi.py --- a/pypy/module/_rawffi/test/test__rawffi.py +++ b/pypy/module/_rawffi/test/test__rawffi.py @@ -260,14 +260,12 @@ assert lib.ptr(1, [], 'i')()[0] == 42 def test_getchar(self): - def _bytestring_to_list(bytestring): - return [bytestring[i:i+1] for i in range(len(bytestring))] import _rawffi lib = _rawffi.CDLL(self.lib_name) get_char = lib.ptr('get_char', ['P', 'H'], 'c') A = _rawffi.Array('c') B = _rawffi.Array('H') - dupa = A(5, _bytestring_to_list(b'dupa')) + dupa = A(5, b'dupa') dupaptr = dupa.byptr() for i in range(4): intptr = B(1) @@ -291,8 +289,6 @@ assert buf[:8] == b'*' + b'\x00'*6 + b'a' def test_returning_str(self): - def _bytestring_to_list(bytestring): - return [bytestring[i:i+1] for i in range(len(bytestring))] import _rawffi lib = _rawffi.CDLL(self.lib_name) char_check = lib.ptr('char_check', ['c', 'c'], 's') @@ -305,7 +301,7 @@ assert _rawffi.charp2string(res[0]) == b'xxxxxx' assert _rawffi.charp2rawstring(res[0]) == b'xxxxxx' assert _rawffi.charp2rawstring(res[0], 3) == b'xxx' - a = A(6, _bytestring_to_list(b'xx\x00\x00xx')) + a = A(6, b'xx\x00\x00xx') assert _rawffi.charp2string(a.buffer) == b'xx' assert _rawffi.charp2rawstring(a.buffer, 4) == b'xx\x00\x00' arg1[0] = b'x' @@ -1028,6 +1024,18 @@ S2E = _rawffi.Structure([('bah', (EMPTY, 1))]) S2E.get_ffi_type() # does not hang + def test_char_array_int(self): + import _rawffi + A = _rawffi.Array('c') + a = A(1) + a[0] = b'a' + assert a[0] == b'a' + # also accept int but return bytestring + a[0] = 100 + assert a[0] == b'd' + a.free() + + class AppTestAutoFree: spaceconfig = dict(usemodules=['_rawffi', 'struct']) @@ -1049,14 +1057,12 @@ assert oldnum == _rawffi._num_of_allocated_objects() def test_array_autofree(self): - def _bytestring_to_list(bytestring): - return [bytestring[i:i+1] for i in range(len(bytestring))] import gc, _rawffi gc.collect() oldnum = _rawffi._num_of_allocated_objects() A = _rawffi.Array('c') - a = A(6, _bytestring_to_list(b'xxyxx\x00'), autofree=True) + a = A(6, b'xxyxx\x00', autofree=True) assert _rawffi.charp2string(a.buffer) == b'xxyxx' a = None gc.collect() From noreply at buildbot.pypy.org Sun Feb 17 23:07:44 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Sun, 17 Feb 2013 23:07:44 +0100 (CET) Subject: [pypy-commit] pypy py3k: hg backout ce51a8cf30f4 Message-ID: <20130217220744.0E0181C0133@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: py3k Changeset: r61379:b1b930ca4d4f Date: 2013-02-17 19:23 +0100 http://bitbucket.org/pypy/pypy/changeset/b1b930ca4d4f/ Log: hg backout ce51a8cf30f4 diff --git a/lib_pypy/_ctypes/array.py b/lib_pypy/_ctypes/array.py --- a/lib_pypy/_ctypes/array.py +++ b/lib_pypy/_ctypes/array.py @@ -144,7 +144,7 @@ l = [self[i] for i in range(start, stop, step)] letter = getattr(self._type_, '_type_', None) if letter == 'c': - return bytes(l) + return b"".join(l) if letter == 'u': return "".join(l) return l From noreply at buildbot.pypy.org Sun Feb 17 23:07:45 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Sun, 17 Feb 2013 23:07:45 +0100 (CET) Subject: [pypy-commit] pypy py3k: Fix/simplify Array type creation. Message-ID: <20130217220745.2E2281C0133@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: py3k Changeset: r61380:5674074df77e Date: 2013-02-17 21:00 +0100 http://bitbucket.org/pypy/pypy/changeset/5674074df77e/ Log: Fix/simplify Array type creation. diff --git a/lib-python/3.2/ctypes/test/test_arrays.py b/lib-python/3.2/ctypes/test/test_arrays.py --- a/lib-python/3.2/ctypes/test/test_arrays.py +++ b/lib-python/3.2/ctypes/test/test_arrays.py @@ -185,7 +185,7 @@ class T(Array): _type_ = c_int _length_ = sys.maxsize * 2 - with self.assertRaises(AttributeError): + with self.assertRaises((AttributeError, TypeError)): class T(Array): _type_ = c_int _length_ = 1.87 diff --git a/lib_pypy/_ctypes/array.py b/lib_pypy/_ctypes/array.py --- a/lib_pypy/_ctypes/array.py +++ b/lib_pypy/_ctypes/array.py @@ -8,54 +8,52 @@ class ArrayMeta(_CDataMeta): def __new__(self, name, cls, typedict): res = type.__new__(self, name, cls, typedict) - if '_type_' in typedict: - ffiarray = _rawffi.Array(typedict['_type_']._ffishape) - res._ffiarray = ffiarray - subletter = getattr(typedict['_type_'], '_type_', None) - if subletter == 'c': - def getvalue(self): - return _rawffi.charp2string(self._buffer.buffer, - self._length_) - def setvalue(self, val): - # we don't want to have buffers here - if len(val) > self._length_: - raise ValueError("%r too long" % (val,)) - for i in range(len(val)): - self[i] = val[i] - if len(val) < self._length_: - self[len(val)] = b'\x00' - res.value = property(getvalue, setvalue) + if cls == (_CData,): # this is the Array class defined below + return res - def getraw(self): - return _rawffi.charp2rawstring(self._buffer.buffer, - self._length_) + ffiarray = res._ffiarray = _rawffi.Array(res._type_._ffishape) + subletter = getattr(res._type_, '_type_', None) + if subletter == 'c': + def getvalue(self): + return _rawffi.charp2string(self._buffer.buffer, + self._length_) + def setvalue(self, val): + # we don't want to have buffers here + if len(val) > self._length_: + raise ValueError("%r too long" % (val,)) + for i in range(len(val)): + self[i] = val[i] + if len(val) < self._length_: + self[len(val)] = b'\x00' + res.value = property(getvalue, setvalue) - def setraw(self, buffer): - if len(buffer) > self._length_: - raise ValueError("%r too long" % (buffer,)) - for i in range(len(buffer)): - self[i] = buffer[i] - res.raw = property(getraw, setraw) - elif subletter == 'u': - def getvalue(self): - return _rawffi.wcharp2unicode(self._buffer.buffer, - self._length_) + def getraw(self): + return _rawffi.charp2rawstring(self._buffer.buffer, + self._length_) - def setvalue(self, val): - # we don't want to have buffers here - if len(val) > self._length_: - raise ValueError("%r too long" % (val,)) - for i in range(len(val)): - self[i] = val[i] - if len(val) < self._length_: - self[len(val)] = '\x00' - res.value = property(getvalue, setvalue) - - if '_length_' in typedict: - res._ffishape = (ffiarray, typedict['_length_']) - res._fficompositesize = res._sizeofinstances() - else: - res._ffiarray = None + def setraw(self, buffer): + if len(buffer) > self._length_: + raise ValueError("%r too long" % (buffer,)) + for i in range(len(buffer)): + self[i] = buffer[i] + res.raw = property(getraw, setraw) + elif subletter == 'u': + def getvalue(self): + return _rawffi.wcharp2unicode(self._buffer.buffer, + self._length_) + + def setvalue(self, val): + # we don't want to have buffers here + if len(val) > self._length_: + raise ValueError("%r too long" % (val,)) + for i in range(len(val)): + self[i] = val[i] + if len(val) < self._length_: + self[len(val)] = '\x00' + res.value = property(getvalue, setvalue) + + res._ffishape = (ffiarray, res._length_) + res._fficompositesize = res._sizeofinstances() return res from_address = cdata_from_address From noreply at buildbot.pypy.org Sun Feb 17 23:07:46 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Sun, 17 Feb 2013 23:07:46 +0100 (CET) Subject: [pypy-commit] pypy py3k: hg backout 1ae411871353 Message-ID: <20130217220746.4C8BF1C0133@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: py3k Changeset: r61381:92847c29c6a7 Date: 2013-02-17 22:30 +0100 http://bitbucket.org/pypy/pypy/changeset/92847c29c6a7/ Log: hg backout 1ae411871353 diff --git a/lib-python/3.2/test/test_functools.py b/lib-python/3.2/test/test_functools.py --- a/lib-python/3.2/test/test_functools.py +++ b/lib-python/3.2/test/test_functools.py @@ -359,6 +359,8 @@ self.assertEqual(wrapper.dict_attr, f.dict_attr) class TestReduce(unittest.TestCase): + func = functools.reduce + def test_reduce(self): class Squares: def __init__(self, max): @@ -375,45 +377,44 @@ self.sofar.append(n*n) n += 1 return self.sofar[i] - reduce = functools.reduce def add(x, y): return x + y - self.assertEqual(reduce(add, ['a', 'b', 'c'], ''), 'abc') + self.assertEqual(self.func(add, ['a', 'b', 'c'], ''), 'abc') self.assertEqual( - reduce(add, [['a', 'c'], [], ['d', 'w']], []), + self.func(add, [['a', 'c'], [], ['d', 'w']], []), ['a','c','d','w'] ) - self.assertEqual(reduce(lambda x, y: x*y, range(2,8), 1), 5040) + self.assertEqual(self.func(lambda x, y: x*y, range(2,8), 1), 5040) self.assertEqual( - reduce(lambda x, y: x*y, range(2,21), 1), + self.func(lambda x, y: x*y, range(2,21), 1), 2432902008176640000 ) - self.assertEqual(reduce(add, Squares(10)), 285) - self.assertEqual(reduce(add, Squares(10), 0), 285) - self.assertEqual(reduce(add, Squares(0), 0), 0) - self.assertRaises(TypeError, reduce) - self.assertRaises(TypeError, reduce, 42, 42) - self.assertRaises(TypeError, reduce, 42, 42, 42) - self.assertEqual(reduce(42, "1"), "1") # func is never called with one item - self.assertEqual(reduce(42, "", "1"), "1") # func is never called with one item - self.assertRaises(TypeError, reduce, 42, (42, 42)) - self.assertRaises(TypeError, reduce, add, []) # arg 2 must not be empty sequence with no initial value - self.assertRaises(TypeError, reduce, add, "") - self.assertRaises(TypeError, reduce, add, ()) - self.assertRaises(TypeError, reduce, add, object()) + self.assertEqual(self.func(add, Squares(10)), 285) + self.assertEqual(self.func(add, Squares(10), 0), 285) + self.assertEqual(self.func(add, Squares(0), 0), 0) + self.assertRaises(TypeError, self.func) + self.assertRaises(TypeError, self.func, 42, 42) + self.assertRaises(TypeError, self.func, 42, 42, 42) + self.assertEqual(self.func(42, "1"), "1") # func is never called with one item + self.assertEqual(self.func(42, "", "1"), "1") # func is never called with one item + self.assertRaises(TypeError, self.func, 42, (42, 42)) + self.assertRaises(TypeError, self.func, add, []) # arg 2 must not be empty sequence with no initial value + self.assertRaises(TypeError, self.func, add, "") + self.assertRaises(TypeError, self.func, add, ()) + self.assertRaises(TypeError, self.func, add, object()) class TestFailingIter: def __iter__(self): raise RuntimeError - self.assertRaises(RuntimeError, reduce, add, TestFailingIter()) + self.assertRaises(RuntimeError, self.func, add, TestFailingIter()) - self.assertEqual(reduce(add, [], None), None) - self.assertEqual(reduce(add, [], 42), 42) + self.assertEqual(self.func(add, [], None), None) + self.assertEqual(self.func(add, [], 42), 42) class BadSeq: def __getitem__(self, index): raise ValueError - self.assertRaises(ValueError, reduce, 42, BadSeq()) + self.assertRaises(ValueError, self.func, 42, BadSeq()) # Test reduce()'s use of iterators. def test_iterator_usage(self): @@ -426,17 +427,16 @@ else: raise IndexError - reduce = functools.reduce from operator import add - self.assertEqual(reduce(add, SequenceClass(5)), 10) - self.assertEqual(reduce(add, SequenceClass(5), 42), 52) - self.assertRaises(TypeError, reduce, add, SequenceClass(0)) - self.assertEqual(reduce(add, SequenceClass(0), 42), 42) - self.assertEqual(reduce(add, SequenceClass(1)), 0) - self.assertEqual(reduce(add, SequenceClass(1), 42), 42) + self.assertEqual(self.func(add, SequenceClass(5)), 10) + self.assertEqual(self.func(add, SequenceClass(5), 42), 52) + self.assertRaises(TypeError, self.func, add, SequenceClass(0)) + self.assertEqual(self.func(add, SequenceClass(0), 42), 42) + self.assertEqual(self.func(add, SequenceClass(1)), 0) + self.assertEqual(self.func(add, SequenceClass(1), 42), 42) d = {"one": 1, "two": 2, "three": 3} - self.assertEqual(reduce(add, d), "".join(d.keys())) + self.assertEqual(self.func(add, d), "".join(d.keys())) class TestCmpToKey(unittest.TestCase): def test_cmp_to_key(self): From noreply at buildbot.pypy.org Sun Feb 17 23:07:47 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Sun, 17 Feb 2013 23:07:47 +0100 (CET) Subject: [pypy-commit] pypy py3k: Use builtinify() instead. Message-ID: <20130217220747.70B161C0133@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: py3k Changeset: r61382:f337b3bbb4be Date: 2013-02-17 22:33 +0100 http://bitbucket.org/pypy/pypy/changeset/f337b3bbb4be/ Log: Use builtinify() instead. diff --git a/lib_pypy/_functools.py b/lib_pypy/_functools.py --- a/lib_pypy/_functools.py +++ b/lib_pypy/_functools.py @@ -1,7 +1,10 @@ """ Supplies the internal functions for functools.py in the standard library """ +from __pypy__ import builtinify + sentinel = object() + at builtinify def reduce(func, sequence, initial=sentinel): """reduce(function, sequence[, initial]) -> value From noreply at buildbot.pypy.org Sun Feb 17 23:07:48 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Sun, 17 Feb 2013 23:07:48 +0100 (CET) Subject: [pypy-commit] pypy py3k: Remove these comments. Message-ID: <20130217220748.9B1821C0133@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: py3k Changeset: r61383:ede09f55217f Date: 2013-02-17 22:49 +0100 http://bitbucket.org/pypy/pypy/changeset/ede09f55217f/ Log: Remove these comments. diff --git a/pypy/objspace/std/floatobject.py b/pypy/objspace/std/floatobject.py --- a/pypy/objspace/std/floatobject.py +++ b/pypy/objspace/std/floatobject.py @@ -162,14 +162,11 @@ s = "nan" return s -#XXX short float repr? - def repr__Float(space, w_float): return space.wrap(float2string(w_float.floatval, 'r', 0)) def str__Float(space, w_float): return space.wrap(float2string(w_float.floatval, 'r', 0)) - #return space.wrap(float2string(w_float.floatval, 'g', DTSF_STR_PRECISION)) def format__Float_ANY(space, w_float, w_spec): return newformat.run_formatter(space, w_spec, "format_float", w_float) From noreply at buildbot.pypy.org Sun Feb 17 23:07:49 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Sun, 17 Feb 2013 23:07:49 +0100 (CET) Subject: [pypy-commit] pypy py3k: Merged in mjacob/pypy/py3k (pull request #121) Message-ID: <20130217220749.D15E71C0133@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61384:3e3e5f7a72a9 Date: 2013-02-17 14:07 -0800 http://bitbucket.org/pypy/pypy/changeset/3e3e5f7a72a9/ Log: Merged in mjacob/pypy/py3k (pull request #121) Random py3k fixes #2 diff --git a/lib-python/3.2/ctypes/test/test_arrays.py b/lib-python/3.2/ctypes/test/test_arrays.py --- a/lib-python/3.2/ctypes/test/test_arrays.py +++ b/lib-python/3.2/ctypes/test/test_arrays.py @@ -185,7 +185,7 @@ class T(Array): _type_ = c_int _length_ = sys.maxsize * 2 - with self.assertRaises(AttributeError): + with self.assertRaises((AttributeError, TypeError)): class T(Array): _type_ = c_int _length_ = 1.87 diff --git a/lib-python/3.2/test/test_cmd_line.py b/lib-python/3.2/test/test_cmd_line.py --- a/lib-python/3.2/test/test_cmd_line.py +++ b/lib-python/3.2/test/test_cmd_line.py @@ -8,6 +8,7 @@ import subprocess import tempfile from test.script_helper import spawn_python, kill_python, assert_python_ok, assert_python_failure +from test.support import check_impl_detail # XXX (ncoghlan): Move to script_helper and make consistent with run_python @@ -339,7 +340,8 @@ rc, out, err = assert_python_ok('-R', '-c', code) self.assertEqual(rc, 0) hashes.append(out) - self.assertNotEqual(hashes[0], hashes[1]) + if check_impl_detail(pypy=False): # PyPy does not really implement it! + self.assertNotEqual(hashes[0], hashes[1]) # Verify that sys.flags contains hash_randomization code = 'import sys; print("random is", sys.flags.hash_randomization)' diff --git a/lib-python/3.2/test/test_functools.py b/lib-python/3.2/test/test_functools.py --- a/lib-python/3.2/test/test_functools.py +++ b/lib-python/3.2/test/test_functools.py @@ -47,6 +47,8 @@ # attributes should not be writable if not isinstance(self.thetype, type): return + if not support.check_impl_detail(): + return self.assertRaises(AttributeError, setattr, p, 'func', map) self.assertRaises(AttributeError, setattr, p, 'args', (1, 2)) self.assertRaises(AttributeError, setattr, p, 'keywords', dict(a=1, b=2)) @@ -138,6 +140,7 @@ p = proxy(f) self.assertEqual(f.func, p.func) f = None + support.gc_collect() self.assertRaises(ReferenceError, getattr, p, 'func') def test_with_bound_and_unbound_methods(self): @@ -203,7 +206,7 @@ updated=functools.WRAPPER_UPDATES): # Check attributes were assigned for name in assigned: - self.assertTrue(getattr(wrapper, name) is getattr(wrapped, name)) + self.assertTrue(getattr(wrapper, name) == getattr(wrapped, name)) # Check attributes were updated for name in updated: wrapper_attr = getattr(wrapper, name) diff --git a/lib-python/3.2/test/test_tempfile.py b/lib-python/3.2/test/test_tempfile.py --- a/lib-python/3.2/test/test_tempfile.py +++ b/lib-python/3.2/test/test_tempfile.py @@ -285,6 +285,7 @@ dir = tempfile.mkdtemp() try: self.do_create(dir=dir).write(b"blat") + support.gc_collect() finally: os.rmdir(dir) @@ -575,12 +576,15 @@ self.do_create(suf="b") self.do_create(pre="a", suf="b") self.do_create(pre="aa", suf=".txt") + support.gc_collect() def test_many(self): # mktemp can choose many usable file names (stochastic) extant = list(range(TEST_FILES)) for i in extant: extant[i] = self.do_create(pre="aa") + del extant + support.gc_collect() ## def test_warning(self): ## # mktemp issues a warning when used @@ -1012,6 +1016,7 @@ "TemporaryDirectory %s exists after cleanup" % d1.name) self.assertTrue(os.path.exists(d2.name), "Directory pointed to by a symlink was deleted") + support.gc_collect() self.assertEqual(os.listdir(d2.name), ['test.txt'], "Contents of the directory pointed to by a symlink " "were deleted") diff --git a/lib_pypy/_ctypes/array.py b/lib_pypy/_ctypes/array.py --- a/lib_pypy/_ctypes/array.py +++ b/lib_pypy/_ctypes/array.py @@ -8,54 +8,52 @@ class ArrayMeta(_CDataMeta): def __new__(self, name, cls, typedict): res = type.__new__(self, name, cls, typedict) - if '_type_' in typedict: - ffiarray = _rawffi.Array(typedict['_type_']._ffishape) - res._ffiarray = ffiarray - subletter = getattr(typedict['_type_'], '_type_', None) - if subletter == 'c': - def getvalue(self): - return _rawffi.charp2string(self._buffer.buffer, - self._length_) - def setvalue(self, val): - # we don't want to have buffers here - if len(val) > self._length_: - raise ValueError("%r too long" % (val,)) - for i in range(len(val)): - self[i] = val[i] - if len(val) < self._length_: - self[len(val)] = b'\x00' - res.value = property(getvalue, setvalue) + if cls == (_CData,): # this is the Array class defined below + return res - def getraw(self): - return _rawffi.charp2rawstring(self._buffer.buffer, - self._length_) + ffiarray = res._ffiarray = _rawffi.Array(res._type_._ffishape) + subletter = getattr(res._type_, '_type_', None) + if subletter == 'c': + def getvalue(self): + return _rawffi.charp2string(self._buffer.buffer, + self._length_) + def setvalue(self, val): + # we don't want to have buffers here + if len(val) > self._length_: + raise ValueError("%r too long" % (val,)) + for i in range(len(val)): + self[i] = val[i] + if len(val) < self._length_: + self[len(val)] = b'\x00' + res.value = property(getvalue, setvalue) - def setraw(self, buffer): - if len(buffer) > self._length_: - raise ValueError("%r too long" % (buffer,)) - for i in range(len(buffer)): - self[i] = buffer[i] - res.raw = property(getraw, setraw) - elif subletter == 'u': - def getvalue(self): - return _rawffi.wcharp2unicode(self._buffer.buffer, - self._length_) + def getraw(self): + return _rawffi.charp2rawstring(self._buffer.buffer, + self._length_) - def setvalue(self, val): - # we don't want to have buffers here - if len(val) > self._length_: - raise ValueError("%r too long" % (val,)) - for i in range(len(val)): - self[i] = val[i] - if len(val) < self._length_: - self[len(val)] = '\x00' - res.value = property(getvalue, setvalue) - - if '_length_' in typedict: - res._ffishape = (ffiarray, typedict['_length_']) - res._fficompositesize = res._sizeofinstances() - else: - res._ffiarray = None + def setraw(self, buffer): + if len(buffer) > self._length_: + raise ValueError("%r too long" % (buffer,)) + for i in range(len(buffer)): + self[i] = buffer[i] + res.raw = property(getraw, setraw) + elif subletter == 'u': + def getvalue(self): + return _rawffi.wcharp2unicode(self._buffer.buffer, + self._length_) + + def setvalue(self, val): + # we don't want to have buffers here + if len(val) > self._length_: + raise ValueError("%r too long" % (val,)) + for i in range(len(val)): + self[i] = val[i] + if len(val) < self._length_: + self[len(val)] = '\x00' + res.value = property(getvalue, setvalue) + + res._ffishape = (ffiarray, res._length_) + res._fficompositesize = res._sizeofinstances() return res from_address = cdata_from_address diff --git a/lib_pypy/_ctypes/function.py b/lib_pypy/_ctypes/function.py --- a/lib_pypy/_ctypes/function.py +++ b/lib_pypy/_ctypes/function.py @@ -556,7 +556,6 @@ try: keepalive, newarg, newargtype = self._conv_param(argtype, args[i]) except (UnicodeError, TypeError, ValueError) as e: - raise raise ArgumentError(str(e)) keepalives.append(keepalive) newargs.append(newarg) diff --git a/lib_pypy/_functools.py b/lib_pypy/_functools.py --- a/lib_pypy/_functools.py +++ b/lib_pypy/_functools.py @@ -1,7 +1,10 @@ """ Supplies the internal functions for functools.py in the standard library """ +from __pypy__ import builtinify + sentinel = object() + at builtinify def reduce(func, sequence, initial=sentinel): """reduce(function, sequence[, initial]) -> value @@ -40,3 +43,17 @@ if self.keywords is not None: fkeywords = dict(self.keywords, **fkeywords) return self.func(*(self.args + fargs), **fkeywords) + + def __repr__(self): + cls = type(self) + if cls is partial: + name = 'functools.partial' + else: + name = cls.__name__ + tmp = [repr(self.func)] + for arg in self.args: + tmp.append(repr(arg)) + if self.keywords: + for k, v in self.keywords.items(): + tmp.append("{}={!r}".format(k, v)) + return "{}({})".format(name, ', '.join(tmp)) diff --git a/pypy/interpreter/argument.py b/pypy/interpreter/argument.py --- a/pypy/interpreter/argument.py +++ b/pypy/interpreter/argument.py @@ -508,6 +508,8 @@ plural = "s" if has_kwarg or num_kwds > 0: msg2 = " non-keyword" + elif defcount != -1: # XXX not sure about this + msg2 = " positional" else: msg2 = "" msg = "takes %s %d%s argument%s (%d given)" % ( diff --git a/pypy/interpreter/test/test_argument.py b/pypy/interpreter/test/test_argument.py --- a/pypy/interpreter/test/test_argument.py +++ b/pypy/interpreter/test/test_argument.py @@ -698,3 +698,11 @@ assert e.value.args[0] == "f() got an unexpected keyword argument 'ü'" """ + def test_error_positional(self): + """ + def f(a, b=None, *, c=None): + pass + exc = raises(TypeError, f, 1, 2, 3) + expected = "f() takes at most 2 positional arguments (3 given)" + assert str(exc.value) == expected + """ diff --git a/pypy/module/_rawffi/interp_rawffi.py b/pypy/module/_rawffi/interp_rawffi.py --- a/pypy/module/_rawffi/interp_rawffi.py +++ b/pypy/module/_rawffi/interp_rawffi.py @@ -55,7 +55,7 @@ return intmask(ffi_type.c_size), intmask(ffi_type.c_alignment) LL_TYPEMAP = { - 'c' : rffi.UCHAR, + 'c' : rffi.CHAR, 'u' : lltype.UniChar, 'b' : rffi.SIGNEDCHAR, 'B' : rffi.UCHAR, @@ -334,7 +334,14 @@ push_func(add_arg, argdesc, rffi.cast(rffi.LONGDOUBLE, space.float_w(w_arg))) elif letter == "c": - val = getbytevalue(space, w_arg) + if space.isinstance_w(w_arg, space.w_int): + val = getbytevalue(space, w_arg) + else: + s = space.str_w(w_arg) + if len(s) != 1: + raise OperationError(space.w_TypeError, w( + "Expected string of length one as character")) + val = s[0] push_func(add_arg, argdesc, val) elif letter == 'u': s = space.unicode_w(w_arg) @@ -363,7 +370,9 @@ if c in TYPEMAP_PTR_LETTERS: res = func(add_arg, argdesc, rffi.VOIDP) return space.wrap(rffi.cast(lltype.Unsigned, res)) - elif c == 'q' or c == 'Q' or c == 'L' or c == 'c' or c == 'u': + elif c == 'c': + return space.wrapbytes(func(add_arg, argdesc, ll_type)) + elif c == 'q' or c == 'Q' or c == 'L' or c == 'u': return space.wrap(func(add_arg, argdesc, ll_type)) elif c == 'f' or c == 'd' or c == 'g': return space.wrap(float(func(add_arg, argdesc, ll_type))) diff --git a/pypy/module/_rawffi/test/test__rawffi.py b/pypy/module/_rawffi/test/test__rawffi.py --- a/pypy/module/_rawffi/test/test__rawffi.py +++ b/pypy/module/_rawffi/test/test__rawffi.py @@ -260,7 +260,6 @@ assert lib.ptr(1, [], 'i')()[0] == 42 def test_getchar(self): - py3k_skip('bytes vs unicode') import _rawffi lib = _rawffi.CDLL(self.lib_name) get_char = lib.ptr('get_char', ['P', 'H'], 'c') @@ -272,7 +271,8 @@ intptr = B(1) intptr[0] = i res = get_char(dupaptr, intptr) - assert res[0] == 'dupa'[i:i+1] + char = b'dupa'[i:i+1] + assert res[0] == char intptr.free() dupaptr.free() dupa.free() @@ -282,14 +282,13 @@ import _rawffi A = _rawffi.Array('c') buf = A(10, autofree=True) - buf[0] = ord('*') + buf[0] = b'*' assert buf[1:5] == b'\x00' * 4 buf[7:] = b'abc' - assert buf[9] == ord('c') + assert buf[9] == b'c' assert buf[:8] == b'*' + b'\x00'*6 + b'a' def test_returning_str(self): - py3k_skip('bytes vs unicode') import _rawffi lib = _rawffi.CDLL(self.lib_name) char_check = lib.ptr('char_check', ['c', 'c'], 's') @@ -450,13 +449,13 @@ X = _rawffi.Structure([('x1', 'i'), ('x2', 'h'), ('x3', 'c'), ('next', 'P')]) next = X() next.next = 0 - next.x3 = ord('x') + next.x3 = b'x' x = X() x.next = next x.x1 = 1 x.x2 = 2 - x.x3 = ord('x') - assert X.fromaddress(x.next).x3 == ord('x') + x.x3 = b'x' + assert X.fromaddress(x.next).x3 == b'x' x.free() next.free() create_double_struct = lib.ptr("create_double_struct", [], 'P') @@ -997,15 +996,15 @@ A = _rawffi.Array('c') a = A(10, autofree=True) - a[3] = ord('x') + a[3] = b'x' b = memoryview(a) assert len(b) == 10 assert b[3] == b'x' b[6] = b'y' - assert a[6] == ord('y') + assert a[6] == b'y' b[3:5] = b'zt' - assert a[3] == ord('z') - assert a[4] == ord('t') + assert a[3] == b'z' + assert a[4] == b't' def test_union(self): import _rawffi @@ -1025,6 +1024,18 @@ S2E = _rawffi.Structure([('bah', (EMPTY, 1))]) S2E.get_ffi_type() # does not hang + def test_char_array_int(self): + import _rawffi + A = _rawffi.Array('c') + a = A(1) + a[0] = b'a' + assert a[0] == b'a' + # also accept int but return bytestring + a[0] = 100 + assert a[0] == b'd' + a.free() + + class AppTestAutoFree: spaceconfig = dict(usemodules=['_rawffi', 'struct']) diff --git a/pypy/module/_rawffi/test/test_nested.py b/pypy/module/_rawffi/test/test_nested.py --- a/pypy/module/_rawffi/test/test_nested.py +++ b/pypy/module/_rawffi/test/test_nested.py @@ -43,14 +43,14 @@ assert S.fieldoffset('x') == 0 assert S.fieldoffset('s1') == S1.alignment s = S() - s.x = ord('G') + s.x = b'G' raises(TypeError, 's.s1') assert s.fieldaddress('s1') == s.buffer + S.fieldoffset('s1') s1 = S1.fromaddress(s.fieldaddress('s1')) - s1.c = ord('H') + s1.c = b'H' rawbuf = _rawffi.Array('c').fromaddress(s.buffer, S.size) - assert rawbuf[0] == ord('G') - assert rawbuf[S1.alignment + S1.fieldoffset('c')] == ord('H') + assert rawbuf[0] == b'G' + assert rawbuf[S1.alignment + S1.fieldoffset('c')] == b'H' s.free() def test_array_of_structures(self): @@ -60,17 +60,17 @@ a = A(3) raises(TypeError, "a[0]") s0 = S.fromaddress(a.buffer) - s0.c = ord('B') + s0.c = b'B' assert a.itemaddress(1) == a.buffer + S.size s1 = S.fromaddress(a.itemaddress(1)) - s1.c = ord('A') + s1.c = b'A' s2 = S.fromaddress(a.itemaddress(2)) - s2.c = ord('Z') + s2.c = b'Z' rawbuf = _rawffi.Array('c').fromaddress(a.buffer, S.size * len(a)) ofs = S.fieldoffset('c') - assert rawbuf[0*S.size+ofs] == ord('B') - assert rawbuf[1*S.size+ofs] == ord('A') - assert rawbuf[2*S.size+ofs] == ord('Z') + assert rawbuf[0*S.size+ofs] == b'B' + assert rawbuf[1*S.size+ofs] == b'A' + assert rawbuf[2*S.size+ofs] == b'Z' a.free() def test_array_of_array(self): @@ -103,16 +103,16 @@ assert S.fieldoffset('x') == 0 assert S.fieldoffset('ar') == A5alignment s = S() - s.x = ord('G') + s.x = b'G' raises(TypeError, 's.ar') assert s.fieldaddress('ar') == s.buffer + S.fieldoffset('ar') a1 = A.fromaddress(s.fieldaddress('ar'), 5) a1[4] = 33 rawbuf = _rawffi.Array('c').fromaddress(s.buffer, S.size) - assert rawbuf[0] == ord('G') + assert rawbuf[0] == b'G' sizeofint = struct.calcsize("i") v = 0 for i in range(sizeofint): - v += rawbuf[A5alignment + sizeofint*4+i] + v += ord(rawbuf[A5alignment + sizeofint*4+i]) assert v == 33 s.free() diff --git a/pypy/objspace/std/floatobject.py b/pypy/objspace/std/floatobject.py --- a/pypy/objspace/std/floatobject.py +++ b/pypy/objspace/std/floatobject.py @@ -166,7 +166,7 @@ return space.wrap(float2string(w_float.floatval, 'r', 0)) def str__Float(space, w_float): - return space.wrap(float2string(w_float.floatval, 'g', DTSF_STR_PRECISION)) + return space.wrap(float2string(w_float.floatval, 'r', 0)) def format__Float_ANY(space, w_float, w_spec): return newformat.run_formatter(space, w_spec, "format_float", w_float) diff --git a/pypy/objspace/std/longtype.py b/pypy/objspace/std/longtype.py --- a/pypy/objspace/std/longtype.py +++ b/pypy/objspace/std/longtype.py @@ -48,7 +48,12 @@ bigint = space.bigint_w(w_obj) return newbigint(space, w_longtype, bigint) else: - base = space.int_w(w_base) + try: + base = space.int_w(w_base) + except OperationError, e: + if not e.match(space, space.w_OverflowError): + raise + base = 37 # this raises the right error in string_to_bigint() if space.isinstance_w(w_value, space.w_unicode): from pypy.objspace.std.unicodeobject import unicode_to_decimal_w diff --git a/pypy/objspace/std/test/test_floatobject.py b/pypy/objspace/std/test/test_floatobject.py --- a/pypy/objspace/std/test/test_floatobject.py +++ b/pypy/objspace/std/test/test_floatobject.py @@ -837,3 +837,6 @@ check(mod(0.0, -1.0), -0.0) check(mod(1e-100, -1.0), -1.0) check(mod(1.0, -1.0), -0.0) + + def test_repr_str_eq(self): + assert repr(19 * 0.1) == str(19 * 0.1) diff --git a/pypy/objspace/std/test/test_longobject.py b/pypy/objspace/std/test/test_longobject.py --- a/pypy/objspace/std/test/test_longobject.py +++ b/pypy/objspace/std/test/test_longobject.py @@ -340,3 +340,6 @@ assert 'hello àèìò' in e.message else: assert False, 'did not raise' + + def test_base_overflow(self): + raises(ValueError, int, '42', 2**63) From noreply at buildbot.pypy.org Sun Feb 17 23:13:39 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Sun, 17 Feb 2013 23:13:39 +0100 (CET) Subject: [pypy-commit] pypy py3k: fix __module__ on many _io types Message-ID: <20130217221339.0A1C01C009B@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61385:1a37ab162374 Date: 2013-02-17 13:05 -0800 http://bitbucket.org/pypy/pypy/changeset/1a37ab162374/ Log: fix __module__ on many _io types diff --git a/pypy/module/_io/interp_bufferedio.py b/pypy/module/_io/interp_bufferedio.py --- a/pypy/module/_io/interp_bufferedio.py +++ b/pypy/module/_io/interp_bufferedio.py @@ -108,7 +108,8 @@ space.warn("max_buffer_size is deprecated", space.w_DeprecationWarning) W_BufferedIOBase.typedef = TypeDef( - '_io._BufferedIOBase', W_IOBase.typedef, + '_BufferedIOBase', W_IOBase.typedef, + __module__ = "_io", __new__ = generic_new_descr(W_BufferedIOBase), read = interp2app(W_BufferedIOBase.read_w), read1 = interp2app(W_BufferedIOBase.read1_w), @@ -938,7 +939,8 @@ 'isatty']) W_BufferedRWPair.typedef = TypeDef( - '_io.BufferedRWPair', W_BufferedIOBase.typedef, + 'BufferedRWPair', W_BufferedIOBase.typedef, + __module__ = "_io", __new__ = generic_new_descr(W_BufferedRWPair), __init__ = interp2app(W_BufferedRWPair.descr_init), __getstate__ = interp2app(W_BufferedRWPair.getstate_w), diff --git a/pypy/module/_io/interp_bytesio.py b/pypy/module/_io/interp_bytesio.py --- a/pypy/module/_io/interp_bytesio.py +++ b/pypy/module/_io/interp_bytesio.py @@ -204,6 +204,7 @@ W_BytesIO.typedef = TypeDef( 'BytesIO', W_BufferedIOBase.typedef, + __module__ = "_io", __new__ = generic_new_descr(W_BytesIO), __init__ = interp2app(W_BytesIO.descr_init), diff --git a/pypy/module/_io/interp_fileio.py b/pypy/module/_io/interp_fileio.py --- a/pypy/module/_io/interp_fileio.py +++ b/pypy/module/_io/interp_fileio.py @@ -441,6 +441,7 @@ W_FileIO.typedef = TypeDef( 'FileIO', W_RawIOBase.typedef, + __module__ = "_io", __new__ = interp2app(W_FileIO.descr_new.im_func), __init__ = interp2app(W_FileIO.descr_init), __repr__ = interp2app(W_FileIO.repr_w), diff --git a/pypy/module/_io/interp_iobase.py b/pypy/module/_io/interp_iobase.py --- a/pypy/module/_io/interp_iobase.py +++ b/pypy/module/_io/interp_iobase.py @@ -268,6 +268,7 @@ W_IOBase.typedef = TypeDef( '_IOBase', + __module__ = "_io", __new__ = generic_new_descr(W_IOBase), __enter__ = interp2app(W_IOBase.enter_w), __exit__ = interp2app(W_IOBase.exit_w), @@ -334,6 +335,7 @@ W_RawIOBase.typedef = TypeDef( '_RawIOBase', W_IOBase.typedef, + __module__ = "_io", __new__ = generic_new_descr(W_RawIOBase), read = interp2app(W_RawIOBase.read_w), diff --git a/pypy/module/_io/interp_textio.py b/pypy/module/_io/interp_textio.py --- a/pypy/module/_io/interp_textio.py +++ b/pypy/module/_io/interp_textio.py @@ -179,6 +179,7 @@ W_IncrementalNewlineDecoder.typedef = TypeDef( 'IncrementalNewlineDecoder', + __module__ = "_io", __new__ = generic_new_descr(W_IncrementalNewlineDecoder), __init__ = interp2app(W_IncrementalNewlineDecoder.descr_init), @@ -256,6 +257,7 @@ W_TextIOBase.typedef = TypeDef( '_TextIOBase', W_IOBase.typedef, + __module__ = "_io", __new__ = generic_new_descr(W_TextIOBase), read = interp2app(W_TextIOBase.read_w), diff --git a/pypy/module/_io/test/test_io.py b/pypy/module/_io/test/test_io.py --- a/pypy/module/_io/test/test_io.py +++ b/pypy/module/_io/test/test_io.py @@ -370,3 +370,8 @@ for protocol in range(pickle.HIGHEST_PROTOCOL + 1): with _io.open(self.tmpfile, **kwargs) as f: raises(TypeError, pickle.dumps, f, protocol) + + def test_mod(self): + import _io + assert all(t.__module__ == '_io' for t in dir(_io) + if isinstance(t, type)) From noreply at buildbot.pypy.org Sun Feb 17 23:13:40 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Sun, 17 Feb 2013 23:13:40 +0100 (CET) Subject: [pypy-commit] pypy py3k: merge upstream Message-ID: <20130217221340.3D2311C009B@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61386:1a3dce362e2e Date: 2013-02-17 14:09 -0800 http://bitbucket.org/pypy/pypy/changeset/1a3dce362e2e/ Log: merge upstream diff --git a/lib-python/3.2/ctypes/test/test_arrays.py b/lib-python/3.2/ctypes/test/test_arrays.py --- a/lib-python/3.2/ctypes/test/test_arrays.py +++ b/lib-python/3.2/ctypes/test/test_arrays.py @@ -185,7 +185,7 @@ class T(Array): _type_ = c_int _length_ = sys.maxsize * 2 - with self.assertRaises(AttributeError): + with self.assertRaises((AttributeError, TypeError)): class T(Array): _type_ = c_int _length_ = 1.87 diff --git a/lib-python/3.2/test/test_cmd_line.py b/lib-python/3.2/test/test_cmd_line.py --- a/lib-python/3.2/test/test_cmd_line.py +++ b/lib-python/3.2/test/test_cmd_line.py @@ -8,6 +8,7 @@ import subprocess import tempfile from test.script_helper import spawn_python, kill_python, assert_python_ok, assert_python_failure +from test.support import check_impl_detail # XXX (ncoghlan): Move to script_helper and make consistent with run_python @@ -339,7 +340,8 @@ rc, out, err = assert_python_ok('-R', '-c', code) self.assertEqual(rc, 0) hashes.append(out) - self.assertNotEqual(hashes[0], hashes[1]) + if check_impl_detail(pypy=False): # PyPy does not really implement it! + self.assertNotEqual(hashes[0], hashes[1]) # Verify that sys.flags contains hash_randomization code = 'import sys; print("random is", sys.flags.hash_randomization)' diff --git a/lib-python/3.2/test/test_functools.py b/lib-python/3.2/test/test_functools.py --- a/lib-python/3.2/test/test_functools.py +++ b/lib-python/3.2/test/test_functools.py @@ -47,6 +47,8 @@ # attributes should not be writable if not isinstance(self.thetype, type): return + if not support.check_impl_detail(): + return self.assertRaises(AttributeError, setattr, p, 'func', map) self.assertRaises(AttributeError, setattr, p, 'args', (1, 2)) self.assertRaises(AttributeError, setattr, p, 'keywords', dict(a=1, b=2)) @@ -138,6 +140,7 @@ p = proxy(f) self.assertEqual(f.func, p.func) f = None + support.gc_collect() self.assertRaises(ReferenceError, getattr, p, 'func') def test_with_bound_and_unbound_methods(self): @@ -203,7 +206,7 @@ updated=functools.WRAPPER_UPDATES): # Check attributes were assigned for name in assigned: - self.assertTrue(getattr(wrapper, name) is getattr(wrapped, name)) + self.assertTrue(getattr(wrapper, name) == getattr(wrapped, name)) # Check attributes were updated for name in updated: wrapper_attr = getattr(wrapper, name) diff --git a/lib-python/3.2/test/test_tempfile.py b/lib-python/3.2/test/test_tempfile.py --- a/lib-python/3.2/test/test_tempfile.py +++ b/lib-python/3.2/test/test_tempfile.py @@ -285,6 +285,7 @@ dir = tempfile.mkdtemp() try: self.do_create(dir=dir).write(b"blat") + support.gc_collect() finally: os.rmdir(dir) @@ -575,12 +576,15 @@ self.do_create(suf="b") self.do_create(pre="a", suf="b") self.do_create(pre="aa", suf=".txt") + support.gc_collect() def test_many(self): # mktemp can choose many usable file names (stochastic) extant = list(range(TEST_FILES)) for i in extant: extant[i] = self.do_create(pre="aa") + del extant + support.gc_collect() ## def test_warning(self): ## # mktemp issues a warning when used @@ -1012,6 +1016,7 @@ "TemporaryDirectory %s exists after cleanup" % d1.name) self.assertTrue(os.path.exists(d2.name), "Directory pointed to by a symlink was deleted") + support.gc_collect() self.assertEqual(os.listdir(d2.name), ['test.txt'], "Contents of the directory pointed to by a symlink " "were deleted") diff --git a/lib_pypy/_ctypes/array.py b/lib_pypy/_ctypes/array.py --- a/lib_pypy/_ctypes/array.py +++ b/lib_pypy/_ctypes/array.py @@ -8,54 +8,52 @@ class ArrayMeta(_CDataMeta): def __new__(self, name, cls, typedict): res = type.__new__(self, name, cls, typedict) - if '_type_' in typedict: - ffiarray = _rawffi.Array(typedict['_type_']._ffishape) - res._ffiarray = ffiarray - subletter = getattr(typedict['_type_'], '_type_', None) - if subletter == 'c': - def getvalue(self): - return _rawffi.charp2string(self._buffer.buffer, - self._length_) - def setvalue(self, val): - # we don't want to have buffers here - if len(val) > self._length_: - raise ValueError("%r too long" % (val,)) - for i in range(len(val)): - self[i] = val[i] - if len(val) < self._length_: - self[len(val)] = b'\x00' - res.value = property(getvalue, setvalue) + if cls == (_CData,): # this is the Array class defined below + return res - def getraw(self): - return _rawffi.charp2rawstring(self._buffer.buffer, - self._length_) + ffiarray = res._ffiarray = _rawffi.Array(res._type_._ffishape) + subletter = getattr(res._type_, '_type_', None) + if subletter == 'c': + def getvalue(self): + return _rawffi.charp2string(self._buffer.buffer, + self._length_) + def setvalue(self, val): + # we don't want to have buffers here + if len(val) > self._length_: + raise ValueError("%r too long" % (val,)) + for i in range(len(val)): + self[i] = val[i] + if len(val) < self._length_: + self[len(val)] = b'\x00' + res.value = property(getvalue, setvalue) - def setraw(self, buffer): - if len(buffer) > self._length_: - raise ValueError("%r too long" % (buffer,)) - for i in range(len(buffer)): - self[i] = buffer[i] - res.raw = property(getraw, setraw) - elif subletter == 'u': - def getvalue(self): - return _rawffi.wcharp2unicode(self._buffer.buffer, - self._length_) + def getraw(self): + return _rawffi.charp2rawstring(self._buffer.buffer, + self._length_) - def setvalue(self, val): - # we don't want to have buffers here - if len(val) > self._length_: - raise ValueError("%r too long" % (val,)) - for i in range(len(val)): - self[i] = val[i] - if len(val) < self._length_: - self[len(val)] = '\x00' - res.value = property(getvalue, setvalue) - - if '_length_' in typedict: - res._ffishape = (ffiarray, typedict['_length_']) - res._fficompositesize = res._sizeofinstances() - else: - res._ffiarray = None + def setraw(self, buffer): + if len(buffer) > self._length_: + raise ValueError("%r too long" % (buffer,)) + for i in range(len(buffer)): + self[i] = buffer[i] + res.raw = property(getraw, setraw) + elif subletter == 'u': + def getvalue(self): + return _rawffi.wcharp2unicode(self._buffer.buffer, + self._length_) + + def setvalue(self, val): + # we don't want to have buffers here + if len(val) > self._length_: + raise ValueError("%r too long" % (val,)) + for i in range(len(val)): + self[i] = val[i] + if len(val) < self._length_: + self[len(val)] = '\x00' + res.value = property(getvalue, setvalue) + + res._ffishape = (ffiarray, res._length_) + res._fficompositesize = res._sizeofinstances() return res from_address = cdata_from_address diff --git a/lib_pypy/_ctypes/function.py b/lib_pypy/_ctypes/function.py --- a/lib_pypy/_ctypes/function.py +++ b/lib_pypy/_ctypes/function.py @@ -556,7 +556,6 @@ try: keepalive, newarg, newargtype = self._conv_param(argtype, args[i]) except (UnicodeError, TypeError, ValueError) as e: - raise raise ArgumentError(str(e)) keepalives.append(keepalive) newargs.append(newarg) diff --git a/lib_pypy/_functools.py b/lib_pypy/_functools.py --- a/lib_pypy/_functools.py +++ b/lib_pypy/_functools.py @@ -1,7 +1,10 @@ """ Supplies the internal functions for functools.py in the standard library """ +from __pypy__ import builtinify + sentinel = object() + at builtinify def reduce(func, sequence, initial=sentinel): """reduce(function, sequence[, initial]) -> value @@ -40,3 +43,17 @@ if self.keywords is not None: fkeywords = dict(self.keywords, **fkeywords) return self.func(*(self.args + fargs), **fkeywords) + + def __repr__(self): + cls = type(self) + if cls is partial: + name = 'functools.partial' + else: + name = cls.__name__ + tmp = [repr(self.func)] + for arg in self.args: + tmp.append(repr(arg)) + if self.keywords: + for k, v in self.keywords.items(): + tmp.append("{}={!r}".format(k, v)) + return "{}({})".format(name, ', '.join(tmp)) diff --git a/pypy/interpreter/argument.py b/pypy/interpreter/argument.py --- a/pypy/interpreter/argument.py +++ b/pypy/interpreter/argument.py @@ -508,6 +508,8 @@ plural = "s" if has_kwarg or num_kwds > 0: msg2 = " non-keyword" + elif defcount != -1: # XXX not sure about this + msg2 = " positional" else: msg2 = "" msg = "takes %s %d%s argument%s (%d given)" % ( diff --git a/pypy/interpreter/test/test_argument.py b/pypy/interpreter/test/test_argument.py --- a/pypy/interpreter/test/test_argument.py +++ b/pypy/interpreter/test/test_argument.py @@ -698,3 +698,11 @@ assert e.value.args[0] == "f() got an unexpected keyword argument 'ü'" """ + def test_error_positional(self): + """ + def f(a, b=None, *, c=None): + pass + exc = raises(TypeError, f, 1, 2, 3) + expected = "f() takes at most 2 positional arguments (3 given)" + assert str(exc.value) == expected + """ diff --git a/pypy/module/_rawffi/interp_rawffi.py b/pypy/module/_rawffi/interp_rawffi.py --- a/pypy/module/_rawffi/interp_rawffi.py +++ b/pypy/module/_rawffi/interp_rawffi.py @@ -55,7 +55,7 @@ return intmask(ffi_type.c_size), intmask(ffi_type.c_alignment) LL_TYPEMAP = { - 'c' : rffi.UCHAR, + 'c' : rffi.CHAR, 'u' : lltype.UniChar, 'b' : rffi.SIGNEDCHAR, 'B' : rffi.UCHAR, @@ -334,7 +334,14 @@ push_func(add_arg, argdesc, rffi.cast(rffi.LONGDOUBLE, space.float_w(w_arg))) elif letter == "c": - val = getbytevalue(space, w_arg) + if space.isinstance_w(w_arg, space.w_int): + val = getbytevalue(space, w_arg) + else: + s = space.str_w(w_arg) + if len(s) != 1: + raise OperationError(space.w_TypeError, w( + "Expected string of length one as character")) + val = s[0] push_func(add_arg, argdesc, val) elif letter == 'u': s = space.unicode_w(w_arg) @@ -363,7 +370,9 @@ if c in TYPEMAP_PTR_LETTERS: res = func(add_arg, argdesc, rffi.VOIDP) return space.wrap(rffi.cast(lltype.Unsigned, res)) - elif c == 'q' or c == 'Q' or c == 'L' or c == 'c' or c == 'u': + elif c == 'c': + return space.wrapbytes(func(add_arg, argdesc, ll_type)) + elif c == 'q' or c == 'Q' or c == 'L' or c == 'u': return space.wrap(func(add_arg, argdesc, ll_type)) elif c == 'f' or c == 'd' or c == 'g': return space.wrap(float(func(add_arg, argdesc, ll_type))) diff --git a/pypy/module/_rawffi/test/test__rawffi.py b/pypy/module/_rawffi/test/test__rawffi.py --- a/pypy/module/_rawffi/test/test__rawffi.py +++ b/pypy/module/_rawffi/test/test__rawffi.py @@ -260,7 +260,6 @@ assert lib.ptr(1, [], 'i')()[0] == 42 def test_getchar(self): - py3k_skip('bytes vs unicode') import _rawffi lib = _rawffi.CDLL(self.lib_name) get_char = lib.ptr('get_char', ['P', 'H'], 'c') @@ -272,7 +271,8 @@ intptr = B(1) intptr[0] = i res = get_char(dupaptr, intptr) - assert res[0] == 'dupa'[i:i+1] + char = b'dupa'[i:i+1] + assert res[0] == char intptr.free() dupaptr.free() dupa.free() @@ -282,14 +282,13 @@ import _rawffi A = _rawffi.Array('c') buf = A(10, autofree=True) - buf[0] = ord('*') + buf[0] = b'*' assert buf[1:5] == b'\x00' * 4 buf[7:] = b'abc' - assert buf[9] == ord('c') + assert buf[9] == b'c' assert buf[:8] == b'*' + b'\x00'*6 + b'a' def test_returning_str(self): - py3k_skip('bytes vs unicode') import _rawffi lib = _rawffi.CDLL(self.lib_name) char_check = lib.ptr('char_check', ['c', 'c'], 's') @@ -450,13 +449,13 @@ X = _rawffi.Structure([('x1', 'i'), ('x2', 'h'), ('x3', 'c'), ('next', 'P')]) next = X() next.next = 0 - next.x3 = ord('x') + next.x3 = b'x' x = X() x.next = next x.x1 = 1 x.x2 = 2 - x.x3 = ord('x') - assert X.fromaddress(x.next).x3 == ord('x') + x.x3 = b'x' + assert X.fromaddress(x.next).x3 == b'x' x.free() next.free() create_double_struct = lib.ptr("create_double_struct", [], 'P') @@ -997,15 +996,15 @@ A = _rawffi.Array('c') a = A(10, autofree=True) - a[3] = ord('x') + a[3] = b'x' b = memoryview(a) assert len(b) == 10 assert b[3] == b'x' b[6] = b'y' - assert a[6] == ord('y') + assert a[6] == b'y' b[3:5] = b'zt' - assert a[3] == ord('z') - assert a[4] == ord('t') + assert a[3] == b'z' + assert a[4] == b't' def test_union(self): import _rawffi @@ -1025,6 +1024,18 @@ S2E = _rawffi.Structure([('bah', (EMPTY, 1))]) S2E.get_ffi_type() # does not hang + def test_char_array_int(self): + import _rawffi + A = _rawffi.Array('c') + a = A(1) + a[0] = b'a' + assert a[0] == b'a' + # also accept int but return bytestring + a[0] = 100 + assert a[0] == b'd' + a.free() + + class AppTestAutoFree: spaceconfig = dict(usemodules=['_rawffi', 'struct']) diff --git a/pypy/module/_rawffi/test/test_nested.py b/pypy/module/_rawffi/test/test_nested.py --- a/pypy/module/_rawffi/test/test_nested.py +++ b/pypy/module/_rawffi/test/test_nested.py @@ -43,14 +43,14 @@ assert S.fieldoffset('x') == 0 assert S.fieldoffset('s1') == S1.alignment s = S() - s.x = ord('G') + s.x = b'G' raises(TypeError, 's.s1') assert s.fieldaddress('s1') == s.buffer + S.fieldoffset('s1') s1 = S1.fromaddress(s.fieldaddress('s1')) - s1.c = ord('H') + s1.c = b'H' rawbuf = _rawffi.Array('c').fromaddress(s.buffer, S.size) - assert rawbuf[0] == ord('G') - assert rawbuf[S1.alignment + S1.fieldoffset('c')] == ord('H') + assert rawbuf[0] == b'G' + assert rawbuf[S1.alignment + S1.fieldoffset('c')] == b'H' s.free() def test_array_of_structures(self): @@ -60,17 +60,17 @@ a = A(3) raises(TypeError, "a[0]") s0 = S.fromaddress(a.buffer) - s0.c = ord('B') + s0.c = b'B' assert a.itemaddress(1) == a.buffer + S.size s1 = S.fromaddress(a.itemaddress(1)) - s1.c = ord('A') + s1.c = b'A' s2 = S.fromaddress(a.itemaddress(2)) - s2.c = ord('Z') + s2.c = b'Z' rawbuf = _rawffi.Array('c').fromaddress(a.buffer, S.size * len(a)) ofs = S.fieldoffset('c') - assert rawbuf[0*S.size+ofs] == ord('B') - assert rawbuf[1*S.size+ofs] == ord('A') - assert rawbuf[2*S.size+ofs] == ord('Z') + assert rawbuf[0*S.size+ofs] == b'B' + assert rawbuf[1*S.size+ofs] == b'A' + assert rawbuf[2*S.size+ofs] == b'Z' a.free() def test_array_of_array(self): @@ -103,16 +103,16 @@ assert S.fieldoffset('x') == 0 assert S.fieldoffset('ar') == A5alignment s = S() - s.x = ord('G') + s.x = b'G' raises(TypeError, 's.ar') assert s.fieldaddress('ar') == s.buffer + S.fieldoffset('ar') a1 = A.fromaddress(s.fieldaddress('ar'), 5) a1[4] = 33 rawbuf = _rawffi.Array('c').fromaddress(s.buffer, S.size) - assert rawbuf[0] == ord('G') + assert rawbuf[0] == b'G' sizeofint = struct.calcsize("i") v = 0 for i in range(sizeofint): - v += rawbuf[A5alignment + sizeofint*4+i] + v += ord(rawbuf[A5alignment + sizeofint*4+i]) assert v == 33 s.free() diff --git a/pypy/objspace/std/floatobject.py b/pypy/objspace/std/floatobject.py --- a/pypy/objspace/std/floatobject.py +++ b/pypy/objspace/std/floatobject.py @@ -166,7 +166,7 @@ return space.wrap(float2string(w_float.floatval, 'r', 0)) def str__Float(space, w_float): - return space.wrap(float2string(w_float.floatval, 'g', DTSF_STR_PRECISION)) + return space.wrap(float2string(w_float.floatval, 'r', 0)) def format__Float_ANY(space, w_float, w_spec): return newformat.run_formatter(space, w_spec, "format_float", w_float) diff --git a/pypy/objspace/std/longtype.py b/pypy/objspace/std/longtype.py --- a/pypy/objspace/std/longtype.py +++ b/pypy/objspace/std/longtype.py @@ -48,7 +48,12 @@ bigint = space.bigint_w(w_obj) return newbigint(space, w_longtype, bigint) else: - base = space.int_w(w_base) + try: + base = space.int_w(w_base) + except OperationError, e: + if not e.match(space, space.w_OverflowError): + raise + base = 37 # this raises the right error in string_to_bigint() if space.isinstance_w(w_value, space.w_unicode): from pypy.objspace.std.unicodeobject import unicode_to_decimal_w diff --git a/pypy/objspace/std/test/test_floatobject.py b/pypy/objspace/std/test/test_floatobject.py --- a/pypy/objspace/std/test/test_floatobject.py +++ b/pypy/objspace/std/test/test_floatobject.py @@ -837,3 +837,6 @@ check(mod(0.0, -1.0), -0.0) check(mod(1e-100, -1.0), -1.0) check(mod(1.0, -1.0), -0.0) + + def test_repr_str_eq(self): + assert repr(19 * 0.1) == str(19 * 0.1) diff --git a/pypy/objspace/std/test/test_longobject.py b/pypy/objspace/std/test/test_longobject.py --- a/pypy/objspace/std/test/test_longobject.py +++ b/pypy/objspace/std/test/test_longobject.py @@ -340,3 +340,6 @@ assert 'hello àèìò' in e.message else: assert False, 'did not raise' + + def test_base_overflow(self): + raises(ValueError, int, '42', 2**63) From noreply at buildbot.pypy.org Sun Feb 17 23:13:41 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Sun, 17 Feb 2013 23:13:41 +0100 (CET) Subject: [pypy-commit] pypy py3k: simplify Message-ID: <20130217221341.6204B1C009B@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61387:57a1886270d2 Date: 2013-02-17 14:13 -0800 http://bitbucket.org/pypy/pypy/changeset/57a1886270d2/ Log: simplify diff --git a/pypy/objspace/std/floatobject.py b/pypy/objspace/std/floatobject.py --- a/pypy/objspace/std/floatobject.py +++ b/pypy/objspace/std/floatobject.py @@ -165,8 +165,7 @@ def repr__Float(space, w_float): return space.wrap(float2string(w_float.floatval, 'r', 0)) -def str__Float(space, w_float): - return space.wrap(float2string(w_float.floatval, 'r', 0)) +str__Float = repr__Float def format__Float_ANY(space, w_float, w_spec): return newformat.run_formatter(space, w_spec, "format_float", w_float) From noreply at buildbot.pypy.org Sun Feb 17 23:55:12 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Sun, 17 Feb 2013 23:55:12 +0100 (CET) Subject: [pypy-commit] pypy py3k: backout 2fb15b5200b6, this breaks things Message-ID: <20130217225512.E689F1C009B@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61388:43790fe331be Date: 2013-02-17 14:54 -0800 http://bitbucket.org/pypy/pypy/changeset/43790fe331be/ Log: backout 2fb15b5200b6, this breaks things diff --git a/pypy/interpreter/argument.py b/pypy/interpreter/argument.py --- a/pypy/interpreter/argument.py +++ b/pypy/interpreter/argument.py @@ -508,8 +508,6 @@ plural = "s" if has_kwarg or num_kwds > 0: msg2 = " non-keyword" - elif defcount != -1: # XXX not sure about this - msg2 = " positional" else: msg2 = "" msg = "takes %s %d%s argument%s (%d given)" % ( diff --git a/pypy/interpreter/test/test_argument.py b/pypy/interpreter/test/test_argument.py --- a/pypy/interpreter/test/test_argument.py +++ b/pypy/interpreter/test/test_argument.py @@ -698,11 +698,3 @@ assert e.value.args[0] == "f() got an unexpected keyword argument 'ü'" """ - def test_error_positional(self): - """ - def f(a, b=None, *, c=None): - pass - exc = raises(TypeError, f, 1, 2, 3) - expected = "f() takes at most 2 positional arguments (3 given)" - assert str(exc.value) == expected - """ From noreply at buildbot.pypy.org Mon Feb 18 00:45:19 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Mon, 18 Feb 2013 00:45:19 +0100 (CET) Subject: [pypy-commit] pypy default: believe this test_rarithmetic approach should work (but doesn't) Message-ID: <20130217234519.DBFD61C009B@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61389:39ef0a70c0e6 Date: 2013-02-18 00:44 +0100 http://bitbucket.org/pypy/pypy/changeset/39ef0a70c0e6/ Log: believe this test_rarithmetic approach should work (but doesn't) diff --git a/rpython/rlib/test/test_rarithmetic.py b/rpython/rlib/test/test_rarithmetic.py --- a/rpython/rlib/test/test_rarithmetic.py +++ b/rpython/rlib/test/test_rarithmetic.py @@ -395,16 +395,18 @@ assert not int_between(1, 1, 1) # these can't be prebuilt on 32bit -L1 = 0x0102030405060708L -L2 = 0x0807060504030201L +U1 = r_ulonglong(0x0102030405060708L) +U2 = r_ulonglong(0x0807060504030201L) +S1 = r_longlong(0x0102030405060708L) +S2 = r_longlong(0x0807060504030201L) def test_byteswap(): from rpython.rtyper.lltypesystem import rffi, lltype assert rffi.cast(lltype.Signed, byteswap(rffi.cast(rffi.USHORT, 0x0102))) == 0x0201 assert rffi.cast(lltype.Signed, byteswap(rffi.cast(rffi.INT, 0x01020304))) == 0x04030201 - assert byteswap(rffi.cast(rffi.LONGLONG, L1)) == L2 - assert byteswap(rffi.cast(rffi.ULONGLONG, L1)) == L2 + assert byteswap(U1) == U2 + assert byteswap(S1) == S2 assert ((byteswap(2.3) - 1.903598566252326e+185) / 1e185) < 0.000001 assert (rffi.cast(lltype.Float, byteswap(rffi.cast(lltype.SingleFloat, 2.3))) - 4.173496037651603e-08) < 1e-16 From noreply at buildbot.pypy.org Mon Feb 18 00:56:56 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Mon, 18 Feb 2013 00:56:56 +0100 (CET) Subject: [pypy-commit] pypy default: add a fast path to this check Message-ID: <20130217235656.AA8541C009B@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61392:d1488e476367 Date: 2013-02-17 18:56 -0500 http://bitbucket.org/pypy/pypy/changeset/d1488e476367/ Log: add a fast path to this check diff --git a/lib_pypy/datetime.py b/lib_pypy/datetime.py --- a/lib_pypy/datetime.py +++ b/lib_pypy/datetime.py @@ -271,6 +271,8 @@ raise ValueError("%s()=%d, must be in -1439..1439" % (name, offset)) def _check_int_field(value): + if isinstance(value, int): + return value if not isinstance(value, float): try: value = value.__int__() From noreply at buildbot.pypy.org Mon Feb 18 01:17:32 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Mon, 18 Feb 2013 01:17:32 +0100 (CET) Subject: [pypy-commit] pypy default: these imports are still needed Message-ID: <20130218001732.086E51C009B@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61393:dcf647ddffef Date: 2013-02-17 19:17 -0500 http://bitbucket.org/pypy/pypy/changeset/dcf647ddffef/ Log: these imports are still needed diff --git a/rpython/rtyper/llinterp.py b/rpython/rtyper/llinterp.py --- a/rpython/rtyper/llinterp.py +++ b/rpython/rtyper/llinterp.py @@ -11,7 +11,8 @@ from rpython.rlib.objectmodel import (ComputedIntSymbolic, CDefinedIntSymbolic, Symbolic) # intmask is used in an exec'd code block -from rpython.rlib.rarithmetic import ovfcheck, is_valid_int, intmask +from rpython.rlib.rarithmetic import (ovfcheck, is_valid_int, intmask, + r_uint, r_longlong, r_ulonglong, r_longlonglong) from rpython.rtyper.lltypesystem import lltype, llmemory, lloperation, llheap, rclass from rpython.rtyper.ootypesystem import ootype From noreply at buildbot.pypy.org Mon Feb 18 04:57:44 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Mon, 18 Feb 2013 04:57:44 +0100 (CET) Subject: [pypy-commit] pypy py3k: our dbm is more of the ndbm flavor not gdbm Message-ID: <20130218035744.220261C021F@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61394:ef1318b6b1bc Date: 2013-02-17 19:48 -0800 http://bitbucket.org/pypy/pypy/changeset/ef1318b6b1bc/ Log: our dbm is more of the ndbm flavor not gdbm diff --git a/lib_pypy/_gdbm.py b/lib_pypy/_dbm.py rename from lib_pypy/_gdbm.py rename to lib_pypy/_dbm.py From noreply at buildbot.pypy.org Mon Feb 18 04:57:45 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Mon, 18 Feb 2013 04:57:45 +0100 (CET) Subject: [pypy-commit] pypy py3k: fix test_dbm/dbm_ndbm Message-ID: <20130218035745.64F791C021F@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61395:9b0d6cfc3e39 Date: 2013-02-17 19:56 -0800 http://bitbucket.org/pypy/pypy/changeset/9b0d6cfc3e39/ Log: fix test_dbm/dbm_ndbm diff --git a/lib_pypy/_dbm.py b/lib_pypy/_dbm.py --- a/lib_pypy/_dbm.py +++ b/lib_pypy/_dbm.py @@ -1,8 +1,9 @@ -from ctypes import Structure, c_char_p, c_int, c_void_p, CDLL, POINTER, c_char +import os +import sys import ctypes.util -import os, sys +from ctypes import Structure, c_char, c_char_p, c_int, c_void_p, CDLL, POINTER -class error(Exception): +class error(IOError): def __init__(self, msg): self.msg = msg @@ -16,8 +17,11 @@ ] def __init__(self, text): - if not isinstance(text, str): - raise TypeError("datum: expected string, not %s" % type(text)) + if isinstance(text, str): + text = text.encode(sys.getdefaultencoding()) + elif not isinstance(text, bytes): + msg = "dbm mapping keys must be a string or bytes object, not {!r}" + raise TypeError(msg.format(type(text).__name__)) Structure.__init__(self, text, len(text)) class dbm(object): @@ -157,9 +161,9 @@ "open a DBM database" if not isinstance(filename, str): raise TypeError("expected string") + filename = filename.encode(sys.getdefaultencoding()) openflag = 0 - try: openflag = { 'r': os.O_RDONLY, @@ -177,4 +181,3 @@ return dbm(a_db) __all__ = ('datum', 'dbm', 'error', 'funcs', 'open', 'library') - From noreply at buildbot.pypy.org Mon Feb 18 05:22:49 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Mon, 18 Feb 2013 05:22:49 +0100 (CET) Subject: [pypy-commit] pypy py3k: fix test_syslog Message-ID: <20130218042249.57A661C009B@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61396:024efa6277ff Date: 2013-02-17 20:21 -0800 http://bitbucket.org/pypy/pypy/changeset/024efa6277ff/ Log: fix test_syslog diff --git a/lib_pypy/syslog.py b/lib_pypy/syslog.py --- a/lib_pypy/syslog.py +++ b/lib_pypy/syslog.py @@ -56,6 +56,11 @@ global _S_ident_o, _S_log_open if ident is None: ident = _get_argv() + if ident is not None: + if not isinstance(ident, str): + msg = "openlog() argument 1 must be a str, not {!r}" + raise TypeError(msg.format(type(ident).__name__)) + ident = ident.encode(sys.getdefaultencoding()) _S_ident_o = c_char_p(ident) # keepalive _openlog(_S_ident_o, logoption, facility) _S_log_open = True @@ -69,7 +74,11 @@ # if log is not opened, open it now if not _S_log_open: openlog() - _syslog(priority, "%s", message) + if not isinstance(message, str): + raise TypeError("syslog() message must be a str, not {!r}".format( + type(message).__name__)) + message = message.encode(sys.getdefaultencoding()) + _syslog(priority, b"%s", message) @builtinify def closelog(): From noreply at buildbot.pypy.org Mon Feb 18 05:22:50 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Mon, 18 Feb 2013 05:22:50 +0100 (CET) Subject: [pypy-commit] pypy py3k: really 2to3 this Message-ID: <20130218042250.93C211C009B@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61397:f0ad6a84aee7 Date: 2013-02-17 20:21 -0800 http://bitbucket.org/pypy/pypy/changeset/f0ad6a84aee7/ Log: really 2to3 this diff --git a/pypy/module/__pypy__/test/test_signal.py b/pypy/module/__pypy__/test/test_signal.py --- a/pypy/module/__pypy__/test/test_signal.py +++ b/pypy/module/__pypy__/test/test_signal.py @@ -15,16 +15,16 @@ spaceconfig = dict(usemodules=['__pypy__', 'thread', 'signal', 'time']) def test_enable_signals(self): - import __pypy__, thread, signal, time + import __pypy__, _thread, signal, time def subthread(): try: with __pypy__.thread.signals_enabled: - thread.interrupt_main() + _thread.interrupt_main() for i in range(10): print('x') time.sleep(0.1) - except BaseException, e: + except BaseException as e: interrupted.append(e) finally: done.append(None) @@ -37,7 +37,7 @@ try: done = [] interrupted = [] - thread.start_new_thread(subthread, ()) + _thread.start_new_thread(subthread, ()) for i in range(10): if len(done): break print('.') @@ -59,23 +59,23 @@ py.test.skip("this is only a test for -A runs on top of pypy") def test_enable_signals(self): - import __pypy__, thread, signal, time + import __pypy__, _thread, signal, time interrupted = [] - lock = thread.allocate_lock() + lock = _thread.allocate_lock() lock.acquire() def subthread(): try: time.sleep(0.25) with __pypy__.thread.signals_enabled: - thread.interrupt_main() - except BaseException, e: + _thread.interrupt_main() + except BaseException as e: interrupted.append(e) finally: lock.release() - thread.start_new_thread(subthread, ()) + _thread.start_new_thread(subthread, ()) lock.acquire() assert len(interrupted) == 1 assert 'KeyboardInterrupt' in interrupted[0].__class__.__name__ From noreply at buildbot.pypy.org Mon Feb 18 07:23:18 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Mon, 18 Feb 2013 07:23:18 +0100 (CET) Subject: [pypy-commit] pypy default: add a jitdriver for space.contains, fixes issue1327 Message-ID: <20130218062318.811E31C0133@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61398:7a0d27055cb4 Date: 2013-02-18 01:14 -0500 http://bitbucket.org/pypy/pypy/changeset/7a0d27055cb4/ Log: add a jitdriver for space.contains, fixes issue1327 diff --git a/pypy/objspace/descroperation.py b/pypy/objspace/descroperation.py --- a/pypy/objspace/descroperation.py +++ b/pypy/objspace/descroperation.py @@ -7,6 +7,7 @@ from rpython.tool.sourcetools import compile2, func_with_new_name from pypy.module.__builtin__.interp_classobj import W_InstanceObject from rpython.rlib.objectmodel import specialize +from rpython.rlib import jit def object_getattribute(space): "Utility that returns the app-level descriptor object.__getattribute__." @@ -118,6 +119,9 @@ def descr__init__(space, w_obj, __args__): pass +contains_jitdriver = jit.JitDriver(name='contains', + greens=['w_type'], reds='auto') + class DescrOperation(object): _mixin_ = True @@ -421,7 +425,9 @@ def _contains(space, w_container, w_item): w_iter = space.iter(w_container) + w_type = space.type(w_iter) while 1: + contains_jitdriver.jit_merge_point(w_type=w_type) try: w_next = space.next(w_iter) except OperationError, e: From noreply at buildbot.pypy.org Mon Feb 18 07:26:08 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Mon, 18 Feb 2013 07:26:08 +0100 (CET) Subject: [pypy-commit] pypy py3k: this now passes Message-ID: <20130218062608.3BD421C0133@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61399:4d0ba925ec33 Date: 2013-02-17 22:23 -0800 http://bitbucket.org/pypy/pypy/changeset/4d0ba925ec33/ Log: this now passes diff --git a/lib-python/3.2/ctypes/test/test_stringptr.py b/lib-python/3.2/ctypes/test/test_stringptr.py --- a/lib-python/3.2/ctypes/test/test_stringptr.py +++ b/lib-python/3.2/ctypes/test/test_stringptr.py @@ -29,7 +29,6 @@ self.assertRaises(TypeError, setattr, x, "str", "Hello, World") - @xfail def test__c_char_p(self): class X(Structure): _fields_ = [("str", c_char_p)] From noreply at buildbot.pypy.org Mon Feb 18 07:26:09 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Mon, 18 Feb 2013 07:26:09 +0100 (CET) Subject: [pypy-commit] pypy py3k: apply workaround from 2.7 Message-ID: <20130218062609.7005B1C0133@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61400:8207e13f2d5e Date: 2013-02-17 22:24 -0800 http://bitbucket.org/pypy/pypy/changeset/8207e13f2d5e/ Log: apply workaround from 2.7 diff --git a/lib-python/3.2/trace.py b/lib-python/3.2/trace.py --- a/lib-python/3.2/trace.py +++ b/lib-python/3.2/trace.py @@ -547,6 +547,10 @@ if len(funcs) == 1: dicts = [d for d in gc.get_referrers(funcs[0]) if isinstance(d, dict)] + if len(dicts) == 0: + # PyPy may store functions directly on the class + # (more exactly: the container is not a Python object) + dicts = funcs if len(dicts) == 1: classes = [c for c in gc.get_referrers(dicts[0]) if hasattr(c, "__bases__")] From noreply at buildbot.pypy.org Mon Feb 18 11:28:53 2013 From: noreply at buildbot.pypy.org (bivab) Date: Mon, 18 Feb 2013 11:28:53 +0100 (CET) Subject: [pypy-commit] pypy default: add a helper method to translatorshell to get the compiled function from the compiled library and update the documentation Message-ID: <20130218102853.9C5AC1C0264@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: Changeset: r61401:a57b50cb7158 Date: 2013-02-18 11:28 +0100 http://bitbucket.org/pypy/pypy/changeset/a57b50cb7158/ Log: add a helper method to translatorshell to get the compiled function from the compiled library and update the documentation diff --git a/pypy/doc/getting-started-dev.rst b/pypy/doc/getting-started-dev.rst --- a/pypy/doc/getting-started-dev.rst +++ b/pypy/doc/getting-started-dev.rst @@ -58,8 +58,7 @@ only use low level types that are available in C (e.g. int). The compiled version is now in a ``.so`` library. You can run it say using ctypes: - >>> from ctypes import CDLL - >>> f = CDLL(lib) + >>> f = get_c_function(lib, snippet.is_perfect_number) >>> f(5) 0 >>> f(6) diff --git a/rpython/bin/translatorshell.py b/rpython/bin/translatorshell.py --- a/rpython/bin/translatorshell.py +++ b/rpython/bin/translatorshell.py @@ -15,9 +15,10 @@ t.view() # graph + annotations under the mouse t.rtype() # use low level operations - f = t.compile_c() # C compilation + lib = t.compile_c() # C compilation as a library + f = get_c_function(lib, f) # get the function out of the library assert f(arg) == func(arg) # sanity check (for C) - + Some functions are provided for the benefit of interactive testing. Try dir(snippet) for list of current snippets. @@ -31,6 +32,13 @@ import py + +def get_c_function(lib, f): + from ctypes import CDLL + name = f.__name__ + return getattr(CDLL(lib.strpath), 'pypy_g_' + name) + + def setup_readline(): import readline try: From noreply at buildbot.pypy.org Mon Feb 18 12:39:17 2013 From: noreply at buildbot.pypy.org (fijal) Date: Mon, 18 Feb 2013 12:39:17 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: shuffle stuff around to account for ESP Message-ID: <20130218113917.089051C009B@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61402:650506e96a7a Date: 2013-02-18 13:37 +0200 http://bitbucket.org/pypy/pypy/changeset/650506e96a7a/ Log: shuffle stuff around to account for ESP diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -206,11 +206,11 @@ # # If the slowpath malloc failed, we raise a MemoryError that # always interrupts the current loop, as a "good enough" - # approximation. Also note that we didn't RET from this helper; - # but the code we jump to will actually restore the stack - # position based on EBP, which will get us out of here for free. + # approximation. We have to adjust the esp a little, to point to + # the correct "ret" arg offset = mc.get_relative_pos() - jz_location mc.overwrite32(jz_location-4, offset) + mc.ADD(esp.value, WORD) mc.JMP(imm(self.propagate_exception_path)) # rawstart = mc.materialize(self.cpu.asmmemmgr, []) @@ -257,7 +257,6 @@ # on the x86_64, we have to save all the registers that may # have been used to pass arguments. Note that we pass only # one argument, that is the frame - mc.PUSH_r(edi.value) mc.MOV_rr(edi.value, esp.value) # if IS_X86_32: @@ -274,9 +273,6 @@ # if IS_X86_32: mc.ADD_ri(esp.value, 3*WORD) # alignment - else: - # restore the edi - mc.POP_r(edi.value) # mc.RET() # @@ -284,6 +280,8 @@ offset = mc.get_relative_pos() - jnz_location assert 0 < offset <= 127 mc.overwrite(jnz_location-1, chr(offset)) + # adjust the esp to point back to the previous return + mc.ADD_ri(esp.value, WORD) mc.JMP(imm(self.propagate_exception_path)) # rawstart = mc.materialize(self.cpu.asmmemmgr, []) @@ -752,6 +750,7 @@ self._call_header_shadowstack(gcrootmap) def _call_header_with_stack_check(self): + self._call_header() if self.stack_check_slowpath == 0: pass # no stack check (e.g. not translated) else: @@ -767,7 +766,6 @@ assert 0 < offset <= 127 self.mc.overwrite(jb_location-1, chr(offset)) # - self._call_header() def _call_footer(self): gcrootmap = self.cpu.gc_ll_descr.gcrootmap From noreply at buildbot.pypy.org Mon Feb 18 12:40:59 2013 From: noreply at buildbot.pypy.org (fijal) Date: Mon, 18 Feb 2013 12:40:59 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: bah Message-ID: <20130218114059.5D1311C009B@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61403:348f38f86f8c Date: 2013-02-18 13:39 +0200 http://bitbucket.org/pypy/pypy/changeset/348f38f86f8c/ Log: bah diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -210,7 +210,7 @@ # the correct "ret" arg offset = mc.get_relative_pos() - jz_location mc.overwrite32(jz_location-4, offset) - mc.ADD(esp.value, WORD) + mc.ADD_ri(esp.value, WORD) mc.JMP(imm(self.propagate_exception_path)) # rawstart = mc.materialize(self.cpu.asmmemmgr, []) From noreply at buildbot.pypy.org Mon Feb 18 13:34:28 2013 From: noreply at buildbot.pypy.org (bivab) Date: Mon, 18 Feb 2013 13:34:28 +0100 (CET) Subject: [pypy-commit] pypy default: typo Message-ID: <20130218123428.47F201C03ED@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: Changeset: r61404:a49ec2df7e48 Date: 2013-02-18 13:34 +0100 http://bitbucket.org/pypy/pypy/changeset/a49ec2df7e48/ Log: typo diff --git a/rpython/bin/translatorshell.py b/rpython/bin/translatorshell.py --- a/rpython/bin/translatorshell.py +++ b/rpython/bin/translatorshell.py @@ -16,7 +16,7 @@ t.rtype() # use low level operations lib = t.compile_c() # C compilation as a library - f = get_c_function(lib, f) # get the function out of the library + f = get_c_function(lib, func) # get the function out of the library assert f(arg) == func(arg) # sanity check (for C) From noreply at buildbot.pypy.org Mon Feb 18 15:06:40 2013 From: noreply at buildbot.pypy.org (krono) Date: Mon, 18 Feb 2013 15:06:40 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: Update Constants to include BlockClosure in Special objects Message-ID: <20130218140640.10DFF1C0133@cobra.cs.uni-duesseldorf.de> Author: Tobias Pape Branch: Changeset: r33:42d60b768156 Date: 2013-02-18 11:13 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/42d60b768156/ Log: Update Constants to include BlockClosure in Special objects diff --git a/spyvm/constants.py b/spyvm/constants.py --- a/spyvm/constants.py +++ b/spyvm/constants.py @@ -73,9 +73,7 @@ SO_CHARACTER_CLASS = 19 SO_DOES_NOT_UNDERSTAND = 20 SO_CANNOT_RETURN = 21 - -# XXX no clue what 22 is doing, lookup in Squeak: ObjectMemory >> initializeSpecialObjectIndices - +SO_PROCESS_SIGNALIGN_LOW_SPACE = 22 # the process that triggered the low space semaphore. mostly nil SO_SPECIAL_SELECTORS_ARRAY = 23 SO_CHARACTER_TABLE_ARRAY = 24 SO_MUST_BE_BOOLEAN = 25 @@ -88,9 +86,9 @@ SO_LARGEPOSITIVEINTEGER_ZERO = 32 SO_A_POINT = 33 SO_CANNOT_INTERPRET = 34 -SO_A_METHODCONTEXT = 35 -# no clue what 36 is doing -SO_A_BLOCKCONTEXT = 37 +SO_A_METHODCONTEXT = 35 # deprecated in closure images +SO_BLOCKCLOSURE_CLASS = 36 +SO_A_BLOCKCONTEXT = 37 # deprecated in closure images SO_AN_ARRAY = 38 SO_PSEUDOCONTEXT_CLASS = 39 SO_TRANSLATEDMETHOD_CLASS = 40 @@ -106,6 +104,7 @@ "Float" : SO_FLOAT_CLASS, "MethodContext" : SO_METHODCONTEXT_CLASS, "BlockContext" : SO_BLOCKCONTEXT_CLASS, + "BlockClosure" : SO_BLOCKCLOSURE_CLASS, "Point" : SO_POINT_CLASS, "LargePositiveInteger" : SO_LARGEPOSITIVEINTEGER_CLASS, # "Display" : SO_DISPLAY_CLASS, From noreply at buildbot.pypy.org Mon Feb 18 15:06:41 2013 From: noreply at buildbot.pypy.org (krono) Date: Mon, 18 Feb 2013 15:06:41 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: more on special objects Message-ID: <20130218140641.1C9EE1C0264@cobra.cs.uni-duesseldorf.de> Author: Tobias Pape Branch: Changeset: r34:ee25b9f840e6 Date: 2013-02-18 15:06 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/ee25b9f840e6/ Log: more on special objects diff --git a/spyvm/constants.py b/spyvm/constants.py --- a/spyvm/constants.py +++ b/spyvm/constants.py @@ -59,7 +59,7 @@ SO_SMALLINTEGER_CLASS = 5 SO_STRING_CLASS = 6 SO_ARRAY_CLASS = 7 -SO_SMALLTALK = 8 +SO_SMALLTALK = 8 # Deperacted SO_FLOAT_CLASS = 9 SO_METHODCONTEXT_CLASS = 10 SO_BLOCKCONTEXT_CLASS = 11 @@ -89,7 +89,7 @@ SO_A_METHODCONTEXT = 35 # deprecated in closure images SO_BLOCKCLOSURE_CLASS = 36 SO_A_BLOCKCONTEXT = 37 # deprecated in closure images -SO_AN_ARRAY = 38 +SO_EXTERNAL_OBJECTS_ARRAY = 38 SO_PSEUDOCONTEXT_CLASS = 39 SO_TRANSLATEDMETHOD_CLASS = 40 SO_FINALIZATION_SEMPAHORE = 41 diff --git a/spyvm/test/test_miniimage.py b/spyvm/test/test_miniimage.py --- a/spyvm/test/test_miniimage.py +++ b/spyvm/test/test_miniimage.py @@ -154,9 +154,10 @@ assert str(w.getclass(space)) == "Symbol class" # for some strange reason not a symbol - """SO_DOES_NOT_UNDERSTAND = 20 + """ + SO_DOES_NOT_UNDERSTAND = 20 SO_CANNOT_RETURN = 21 - # no clue what 22 is doing + SO_PROCESS_SIGNALIGN_LOW_SPACE = 22 # the process that triggered the low space semaphore. mostly nil SO_SPECIAL_SELECTORS_ARRAY = 23 SO_CHARACTER_TABLE_ARRAY = 24 SO_MUST_BE_BOOLEAN = 25 @@ -169,14 +170,15 @@ SO_LARGEPOSITIVEINTEGER_ZERO = 32 SO_A_POINT = 33 SO_CANNOT_INTERPRET = 34 - SO_A_METHODCONTEXT = 35 - # no clue what 36 is doing - SO_A_BLOCKCONTEXT = 37 - SO_AN_ARRAY = 38 + SO_A_METHODCONTEXT = 35 # deprecated in closure images + SO_BLOCKCLOSURE_CLASS = 36 + SO_A_BLOCKCONTEXT = 37 # deprecated in closure images + SO_EXTERNAL_OBJECTS_ARRAY = 38 SO_PSEUDOCONTEXT_CLASS = 39 SO_TRANSLATEDMETHOD_CLASS = 40 SO_FINALIZATION_SEMPAHORE = 41 - SO_LARGENEGATIVEINTEGER_CLASS = 42""" + SO_LARGENEGATIVEINTEGER_CLASS = 42 + """ From noreply at buildbot.pypy.org Mon Feb 18 15:06:42 2013 From: noreply at buildbot.pypy.org (krono) Date: Mon, 18 Feb 2013 15:06:42 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: merge default Message-ID: <20130218140642.2C02D1C03ED@cobra.cs.uni-duesseldorf.de> Author: Tobias Pape Branch: Changeset: r35:f0ea960b893b Date: 2013-02-18 15:06 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/f0ea960b893b/ Log: merge default diff --git a/spyvm/interpreter.py b/spyvm/interpreter.py --- a/spyvm/interpreter.py +++ b/spyvm/interpreter.py @@ -1,9 +1,7 @@ import py from spyvm.shadow import ContextPartShadow, MethodContextShadow, BlockContextShadow -from spyvm import model, constants, primitives -from spyvm.shadow import ContextPartShadow -from spyvm import conftest -from spyvm import wrapper +from spyvm import model, constants, primitives, conftest, wrapper +from spyvm.tool.bitmanipulation import splitter from rpython.rlib import jit from rpython.rlib import objectmodel, unroll @@ -370,9 +368,41 @@ def popStackBytecode(self, interp): self.pop() + # closure bytecodes + def pushNewArrayPopIntoArray(self, interp): + popIntoArray, arraySize = splitter[1, 7](self.getbytecode()) + newArray = None + #if popIntoArray == 1: + # newArray = interp.space.wrap_list(self.pop_and_return_n(arraySize)) + #else: + # newArray = interp.space.w_Array.as_class_get_shadow(interp.space).new(arraySize) + self.push(newArray) + raise MissingBytecode("not yet implemented: pushNewArray") + def experimentalBytecode(self, interp): raise MissingBytecode("experimentalBytecode") + def pushTempAtInTempVectorAt(self, interp): + k = self.getbytecode() + j = self.getbytecode() + raise MissingBytecode("not yet implemented: pushTempAt k inTempVectorAt j") + + def storeTempAtInTempVectorAt(self, interp): + k = self.getbytecode() + j = self.getbytecode() + raise MissingBytecode("not yet implemented: storeTempAt k inTempVectorAt j") + + def popAndStoreTempAtInTempVectorAt(self, interp): + k = self.getbytecode() + j = self.getbytecode() + raise MissingBytecode("not yet implemented: popAndstoreTempAt k inTempVectorAt j") + + def pushClosureNumCopiedNumArgsBlockSize(self, interp): + l, k = splitter[4, 4](self.getbytecode()) + j = self.getbytecode() + i = self.getbytecode() + raise MissingBytecode("not yet implemented: pushClosureNumCopied l numArgs k blockSize ij") + def jump(self,offset): self.store_pc(self.pc() + offset) @@ -505,7 +535,12 @@ (135, "popStackBytecode"), (136, "duplicateTopBytecode"), (137, "pushActiveContextBytecode"), - (138, 143, "experimentalBytecode"), + (138, "pushNewArrayPopIntoArray"), + (139, "experimentalBytecode"), + (140, "pushTempAtInTempVectorAt"), + (141, "storeTempAtInTempVectorAt"), + (142, "popAndStoreTempAtInTempVectorAt"), + (143, "pushClosureNumCopiedNumArgsBlockSize"), (144, 151, "shortUnconditionalJump"), (152, 159, "shortConditionalJump"), (160, 167, "longUnconditionalJump"), diff --git a/spyvm/objspace.py b/spyvm/objspace.py --- a/spyvm/objspace.py +++ b/spyvm/objspace.py @@ -205,9 +205,9 @@ a wrapped smalltalk array """ lstlen = len(lst_w) - res = self.w_Array.as_class_get_shadow().new(lstlen) + res = self.w_Array.as_class_get_shadow(self).new(lstlen) for i in range(lstlen): - res.storevarpointer(i, lit[i]) + res.storevarpointer(i, lst_w[i]) return res def unwrap_int(self, w_value): diff --git a/spyvm/targettinybenchsmalltalk.py b/spyvm/targettinybenchsmalltalk.py --- a/spyvm/targettinybenchsmalltalk.py +++ b/spyvm/targettinybenchsmalltalk.py @@ -1,6 +1,6 @@ import os, sys from spyvm import model, interpreter, primitives, shadow, constants -from spyvm.tool.analyseimage import create_squeakimage +from spyvm.tool.analyseimage import create_squeakimage, create_testimage from rpython.jit.codewriter.policy import JitPolicy @@ -19,13 +19,13 @@ def tinyBenchmarks(): from spyvm import objspace space = objspace.ObjSpace() - image = create_squeakimage(space) + image = create_testimage(space) interp = interpreter.Interpreter(space) w_object = model.W_SmallInteger(0) s_class = w_object.shadow_of_my_class(space) - w_method = s_class.lookup("tinyBenchmarks") + w_method = s_class.lookup("loopTest") assert w_method w_frame = w_method.create_frame(space, w_object, []) diff --git a/spyvm/test/jit.py b/spyvm/test/jit.py --- a/spyvm/test/jit.py +++ b/spyvm/test/jit.py @@ -16,7 +16,7 @@ from spyvm import model, interpreter, primitives, shadow from spyvm import objspace -from spyvm.tool.analyseimage import create_testimage +from spyvm.tool.analyseimage import create_squeakimage, create_testimage mockclass = objspace.bootstrap_class @@ -77,5 +77,4 @@ def interp_w(): interp.interpret() - self.meta_interp(interp_w, [], listcomp=True, listops=True, backendopt=True) - + self.meta_interp(interp_w, [], listcomp=True, listops=True, backendopt=True) \ No newline at end of file diff --git a/spyvm/test/test_interpreter.py b/spyvm/test/test_interpreter.py --- a/spyvm/test/test_interpreter.py +++ b/spyvm/test/test_interpreter.py @@ -829,3 +829,14 @@ test_storeAndPopReceiverVariableBytecode() test_bc_objectAtAndAtPut() option.bc_trace = bc_trace + +# Closure Bytecodes +def test_bc_pushNewArrayPopIntoArray(bytecode=pushNewArrayPopIntoArray): + py.test.skip("Fails, since pushNewArrayPopIntoArray is not yet implemented") + interp = new_interpreter(bytecode + chr(0x83)) + context = interp.s_active_context() + context.push(fakeliterals("egg")) + context.push(fakeliterals("bar")) + context.push(fakeliterals("baz")) + interp.step(interp.s_active_context()) + assert context.pop() == fakeliterals(["egg", "bar", "baz"]) \ No newline at end of file diff --git a/spyvm/todo.txt b/spyvm/todo.txt --- a/spyvm/todo.txt +++ b/spyvm/todo.txt @@ -21,3 +21,7 @@ Shadows: [ ] Fix invalidation of methoddictshadow when the w_self of its values array changes + +Lars ToDo +[ ] Tests for the new bytecodes. +[ ] Guess method names for JIT debugging, e.g. changing MethodDictShadow From noreply at buildbot.pypy.org Mon Feb 18 15:10:49 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Mon, 18 Feb 2013 15:10:49 +0100 (CET) Subject: [pypy-commit] pypy default: significantly speed up min/max in the non-unrolled case Message-ID: <20130218141049.028C01C0133@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61405:ab0486abc9f6 Date: 2013-02-18 09:06 -0500 http://bitbucket.org/pypy/pypy/changeset/ab0486abc9f6/ Log: significantly speed up min/max in the non-unrolled case diff --git a/pypy/module/__builtin__/functional.py b/pypy/module/__builtin__/functional.py --- a/pypy/module/__builtin__/functional.py +++ b/pypy/module/__builtin__/functional.py @@ -133,56 +133,76 @@ v = v.add(step) return space.newlist(res_w) +min_jitdriver = jit.JitDriver(name='min', + greens=['w_type'], reds='auto') +max_jitdriver = jit.JitDriver(name='max', + greens=['w_type'], reds='auto') + +def make_min_max(unroll): + @specialize.arg(2) + def min_max_impl(space, args, implementation_of): + if implementation_of == "max": + compare = space.gt + jitdriver = max_jitdriver + else: + compare = space.lt + jitdriver = min_jitdriver + args_w = args.arguments_w + if len(args_w) > 1: + w_sequence = space.newtuple(args_w) + elif len(args_w): + w_sequence = args_w[0] + else: + msg = "%s() expects at least one argument" % (implementation_of,) + raise OperationError(space.w_TypeError, space.wrap(msg)) + w_key = None + kwds = args.keywords + if kwds: + if kwds[0] == "key" and len(kwds) == 1: + w_key = args.keywords_w[0] + else: + msg = "%s() got unexpected keyword argument" % (implementation_of,) + raise OperationError(space.w_TypeError, space.wrap(msg)) + + w_iter = space.iter(w_sequence) + w_type = space.type(w_iter) + w_max_item = None + w_max_val = None + while True: + if not unroll: + jitdriver.jit_merge_point(w_type=w_type) + try: + w_item = space.next(w_iter) + except OperationError, e: + if not e.match(space, space.w_StopIteration): + raise + break + if w_key is not None: + w_compare_with = space.call_function(w_key, w_item) + else: + w_compare_with = w_item + if w_max_item is None or \ + space.is_true(compare(w_compare_with, w_max_val)): + w_max_item = w_item + w_max_val = w_compare_with + if w_max_item is None: + msg = "arg is an empty sequence" + raise OperationError(space.w_ValueError, space.wrap(msg)) + return w_max_item + if unroll: + min_max_impl = jit.unroll_safe(min_max_impl) + return min_max_impl + +min_max_unroll = make_min_max(True) +min_max_normal = make_min_max(False) @specialize.arg(2) - at jit.look_inside_iff(lambda space, args, implementation_of: - jit.isconstant(len(args.arguments_w)) and - len(args.arguments_w) == 2 -) def min_max(space, args, implementation_of): - if implementation_of == "max": - compare = space.gt + if not jit.we_are_jitted() or (jit.isconstant(len(args.arguments_w)) and + len(args.arguments_w) == 2): + return min_max_unroll(space, args, implementation_of) else: - compare = space.lt - args_w = args.arguments_w - if len(args_w) > 1: - w_sequence = space.newtuple(args_w) - elif len(args_w): - w_sequence = args_w[0] - else: - msg = "%s() expects at least one argument" % (implementation_of,) - raise OperationError(space.w_TypeError, space.wrap(msg)) - w_key = None - kwds = args.keywords - if kwds: - if kwds[0] == "key" and len(kwds) == 1: - w_key = args.keywords_w[0] - else: - msg = "%s() got unexpected keyword argument" % (implementation_of,) - raise OperationError(space.w_TypeError, space.wrap(msg)) - - w_iter = space.iter(w_sequence) - w_max_item = None - w_max_val = None - while True: - try: - w_item = space.next(w_iter) - except OperationError, e: - if not e.match(space, space.w_StopIteration): - raise - break - if w_key is not None: - w_compare_with = space.call_function(w_key, w_item) - else: - w_compare_with = w_item - if w_max_item is None or \ - space.is_true(compare(w_compare_with, w_max_val)): - w_max_item = w_item - w_max_val = w_compare_with - if w_max_item is None: - msg = "arg is an empty sequence" - raise OperationError(space.w_ValueError, space.wrap(msg)) - return w_max_item + return min_max_normal(space, args, implementation_of) def max(space, __args__): """max(iterable[, key=func]) -> value From noreply at buildbot.pypy.org Mon Feb 18 15:45:10 2013 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 18 Feb 2013 15:45:10 +0100 (CET) Subject: [pypy-commit] pypy stm-thread-2: Add the ThreadLocalReference class. Message-ID: <20130218144510.D05571C009B@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stm-thread-2 Changeset: r61406:5d60f05ba873 Date: 2013-02-18 13:26 +0100 http://bitbucket.org/pypy/pypy/changeset/5d60f05ba873/ Log: Add the ThreadLocalReference class. diff --git a/rpython/rlib/rstm.py b/rpython/rlib/rstm.py --- a/rpython/rlib/rstm.py +++ b/rpython/rlib/rstm.py @@ -1,13 +1,15 @@ -import threading +import thread from rpython.translator.stm import stmgcintf from rpython.rlib.debug import ll_assert, fatalerror from rpython.rlib.objectmodel import keepalive_until_here, specialize from rpython.rlib.objectmodel import we_are_translated from rpython.rlib.rposix import get_errno, set_errno +from rpython.rlib.rarithmetic import intmask from rpython.rtyper.lltypesystem import lltype, llmemory, rffi, rclass from rpython.rtyper.lltypesystem.lloperation import llop -from rpython.rtyper.annlowlevel import (cast_instance_to_base_ptr, - llhelper) +from rpython.rtyper.annlowlevel import cast_instance_to_base_ptr, llhelper +from rpython.rtyper.annlowlevel import cast_base_ptr_to_instance + def is_inevitable(): return we_are_translated() and stmgcintf.StmOperations.is_inevitable() @@ -102,3 +104,35 @@ perform_transaction._transaction_break_ = True # return perform_transaction + +# ____________________________________________________________ + +class ThreadLocalReference(object): + + def __init__(self, Cls): + "NOT_RPYTHON: must be prebuilt" + self.Cls = Cls + self.unique_id = intmask(id(self)) + self.local = thread._local() + + def _freeze_(self): + return True + + @specialize.arg(0) + def get(self): + if we_are_translated(): + ptr = llop.stm_localref_get(llmemory.Address, self.unique_id) + ptr = rffi.cast(rclass.OBJECTPTR, ptr) + return cast_base_ptr_to_instance(self.Cls, ptr) + else: + return getattr(self.local, 'value', None) + + @specialize.arg(0) + def set(self, value): + assert isinstance(value, self.Cls) or value is None + if we_are_translated(): + ptr = cast_instance_to_base_ptr(value) + ptr = rffi.cast(llmemory.Address, ptr) + llop.stm_localref_set(lltype.Void, self.unique_id, ptr) + else: + self.local.value = value diff --git a/rpython/rlib/test/test_rstm.py b/rpython/rlib/test/test_rstm.py new file mode 100644 --- /dev/null +++ b/rpython/rlib/test/test_rstm.py @@ -0,0 +1,17 @@ +import thread, time +from rpython.rlib.rstm import ThreadLocalReference + +def test_tlref_untranslated(): + class FooBar(object): + pass + t = ThreadLocalReference(FooBar) + results = [] + def subthread(): + x = FooBar() + t.set(x) + time.sleep(0.2) + results.append(t.get() is x) + for i in range(5): + thread.start_new_thread(subthread, ()) + time.sleep(0.5) + assert results == [True] * 5 From noreply at buildbot.pypy.org Mon Feb 18 15:45:12 2013 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 18 Feb 2013 15:45:12 +0100 (CET) Subject: [pypy-commit] pypy stm-thread-2: ThreadLocalReference: implementation. Message-ID: <20130218144512.2A7BB1C009B@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stm-thread-2 Changeset: r61407:7000756077c5 Date: 2013-02-18 14:07 +0100 http://bitbucket.org/pypy/pypy/changeset/7000756077c5/ Log: ThreadLocalReference: implementation. diff --git a/rpython/rlib/rstm.py b/rpython/rlib/rstm.py --- a/rpython/rlib/rstm.py +++ b/rpython/rlib/rstm.py @@ -1,10 +1,9 @@ -import thread +import thread, weakref from rpython.translator.stm import stmgcintf from rpython.rlib.debug import ll_assert, fatalerror from rpython.rlib.objectmodel import keepalive_until_here, specialize from rpython.rlib.objectmodel import we_are_translated from rpython.rlib.rposix import get_errno, set_errno -from rpython.rlib.rarithmetic import intmask from rpython.rtyper.lltypesystem import lltype, llmemory, rffi, rclass from rpython.rtyper.lltypesystem.lloperation import llop from rpython.rtyper.annlowlevel import cast_instance_to_base_ptr, llhelper @@ -108,12 +107,16 @@ # ____________________________________________________________ class ThreadLocalReference(object): + _ALL = weakref.WeakKeyDictionary() + _COUNT = 0 def __init__(self, Cls): "NOT_RPYTHON: must be prebuilt" self.Cls = Cls - self.unique_id = intmask(id(self)) self.local = thread._local() + self.unique_id = ThreadLocalReference._COUNT + ThreadLocalReference._COUNT += 1 + ThreadLocalReference._ALL[self] = True def _freeze_(self): return True @@ -121,7 +124,7 @@ @specialize.arg(0) def get(self): if we_are_translated(): - ptr = llop.stm_localref_get(llmemory.Address, self.unique_id) + ptr = llop.stm_threadlocalref_get(llmemory.Address, self.unique_id) ptr = rffi.cast(rclass.OBJECTPTR, ptr) return cast_base_ptr_to_instance(self.Cls, ptr) else: @@ -133,6 +136,14 @@ if we_are_translated(): ptr = cast_instance_to_base_ptr(value) ptr = rffi.cast(llmemory.Address, ptr) - llop.stm_localref_set(lltype.Void, self.unique_id, ptr) + llop.stm_threadlocalref_set(lltype.Void, self.unique_id, ptr) else: self.local.value = value + + @staticmethod + def flush_all_in_this_thread(): + if we_are_translated(): + llop.stm_threadlocalref_flush(lltype.Void) + else: + for tlref in ThreadLocalReference._ALL.keys(): + tlref.local.value = None diff --git a/rpython/rlib/test/test_rstm.py b/rpython/rlib/test/test_rstm.py --- a/rpython/rlib/test/test_rstm.py +++ b/rpython/rlib/test/test_rstm.py @@ -8,10 +8,13 @@ results = [] def subthread(): x = FooBar() + results.append(t.get() is None) t.set(x) time.sleep(0.2) results.append(t.get() is x) + ThreadLocalReference.flush_all_in_this_thread() + results.append(t.get() is None) for i in range(5): thread.start_new_thread(subthread, ()) time.sleep(0.5) - assert results == [True] * 5 + assert results == [True] * 15 diff --git a/rpython/rtyper/lltypesystem/lloperation.py b/rpython/rtyper/lltypesystem/lloperation.py --- a/rpython/rtyper/lltypesystem/lloperation.py +++ b/rpython/rtyper/lltypesystem/lloperation.py @@ -429,6 +429,9 @@ 'stm_start_transaction': LLOp(canrun=True, canmallocgc=True), 'stm_stop_transaction': LLOp(canrun=True, canmallocgc=True), #'stm_jit_invoke_code': LLOp(canmallocgc=True), + 'stm_threadlocalref_get': LLOp(sideeffects=False), + 'stm_threadlocalref_set': LLOp(), + 'stm_threadlocalref_flush': LLOp(), # __________ address operations __________ diff --git a/rpython/translator/stm/src_stm/atomic_ops.h b/rpython/translator/stm/src_stm/atomic_ops.h --- a/rpython/translator/stm/src_stm/atomic_ops.h +++ b/rpython/translator/stm/src_stm/atomic_ops.h @@ -1,6 +1,8 @@ #ifndef _SRCSTM_ATOMIC_OPS_ #define _SRCSTM_ATOMIC_OPS_ +#include + /* "compiler fence" for preventing reordering of loads/stores to non-volatiles */ diff --git a/rpython/translator/stm/test/test_ztranslated.py b/rpython/translator/stm/test/test_ztranslated.py --- a/rpython/translator/stm/test/test_ztranslated.py +++ b/rpython/translator/stm/test/test_ztranslated.py @@ -104,3 +104,20 @@ t, cbuilder = self.compile(main) data = cbuilder.cmdexec('') assert '42\n' in data, "got: %r" % (data,) + + def test_threadlocalref(self): + class FooBar(object): + pass + t = rstm.ThreadLocalReference(FooBar) + def main(argv): + x = FooBar() + assert t.get() is None + t.set(x) + assert t.get() is x + rstm.ThreadLocalReference.flush_all_in_this_thread() + assert t.get() is None + print "ok" + return 0 + t, cbuilder = self.compile(main) + data = cbuilder.cmdexec('') + assert 'ok\n' in data diff --git a/rpython/translator/stm/threadlocalref.py b/rpython/translator/stm/threadlocalref.py new file mode 100644 --- /dev/null +++ b/rpython/translator/stm/threadlocalref.py @@ -0,0 +1,61 @@ +from rpython.rtyper.lltypesystem import lltype, llmemory +from rpython.translator.unsimplify import varoftype +from rpython.flowspace.model import SpaceOperation, Constant + +# +# Note: all this slightly messy code is to have 'stm_threadlocalref_flush' +# which zeroes *all* thread-locals variables accessed with +# stm_threadlocalref_{get,set}. +# + +def transform_tlref(graphs): + ids = set() + # + for graph in graphs: + for block in graph.iterblocks(): + for i in range(len(block.operations)): + op = block.operations[i] + if (op.opname == 'stm_threadlocalref_set' or + op.opname == 'stm_threadlocalref_get'): + ids.add(op.args[0].value) + if len(ids) == 0: + return + # + ids = sorted(ids) + fields = [('ptr%d' % id1, llmemory.Address) for id1 in ids] + kwds = {'hints': {'stm_thread_local': True}} + S = lltype.Struct('THREADLOCALREF', *fields, **kwds) + ll_threadlocalref = lltype.malloc(S, immortal=True) + c_threadlocalref = Constant(ll_threadlocalref, lltype.Ptr(S)) + c_fieldnames = {} + for id1 in ids: + fieldname = 'ptr%d' % id1 + c_fieldnames[id1] = Constant(fieldname, lltype.Void) + c_null = Constant(llmemory.NULL, llmemory.Address) + # + for graph in graphs: + for block in graph.iterblocks(): + for i in range(len(block.operations)-1, -1, -1): + op = block.operations[i] + if op.opname == 'stm_threadlocalref_set': + id1 = op.args[0].value + op = SpaceOperation('setfield', [c_threadlocalref, + c_fieldnames[id1], + op.args[1]], + op.result) + block.operations[i] = op + elif op.opname == 'stm_threadlocalref_get': + id1 = op.args[0].value + op = SpaceOperation('getfield', [c_threadlocalref, + c_fieldnames[id1]], + op.result) + block.operations[i] = op + elif op.opname == 'stm_threadlocalref_flush': + extra = [] + for id1 in ids: + op = SpaceOperation('setfield', [c_threadlocalref, + c_fieldnames[id1], + c_null], + varoftype(lltype.Void)) + extra.append(op) + block.operations[i:i+1] = extra diff --git a/rpython/translator/stm/transform2.py b/rpython/translator/stm/transform2.py --- a/rpython/translator/stm/transform2.py +++ b/rpython/translator/stm/transform2.py @@ -7,6 +7,7 @@ def transform(self): assert not hasattr(self.translator, 'stm_transformation_applied') self.start_log() + self.transform_threadlocalref() self.transform_jit_driver() self.transform_write_barrier() self.transform_turn_inevitable() @@ -34,6 +35,10 @@ for graph in self.translator.graphs: reorganize_around_jit_driver(self, graph) + def transform_threadlocalref(self): + from rpython.translator.stm.threadlocalref import transform_tlref + transform_tlref(self.translator.graphs) + def start_log(self): from rpython.translator.c.support import log log.info("Software Transactional Memory transformation") From noreply at buildbot.pypy.org Mon Feb 18 15:45:13 2013 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 18 Feb 2013 15:45:13 +0100 (CET) Subject: [pypy-commit] pypy stm-thread-2: Flush the ThreadLocalReferences whenever we are collecting. Message-ID: <20130218144513.552D91C009B@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stm-thread-2 Changeset: r61408:bdf4b499e39b Date: 2013-02-18 14:10 +0100 http://bitbucket.org/pypy/pypy/changeset/bdf4b499e39b/ Log: Flush the ThreadLocalReferences whenever we are collecting. diff --git a/rpython/rlib/rstm.py b/rpython/rlib/rstm.py --- a/rpython/rlib/rstm.py +++ b/rpython/rlib/rstm.py @@ -143,6 +143,7 @@ @staticmethod def flush_all_in_this_thread(): if we_are_translated(): + # NB. this line is repeated in stmtls.py llop.stm_threadlocalref_flush(lltype.Void) else: for tlref in ThreadLocalReference._ALL.keys(): diff --git a/rpython/rtyper/memory/gc/stmtls.py b/rpython/rtyper/memory/gc/stmtls.py --- a/rpython/rtyper/memory/gc/stmtls.py +++ b/rpython/rtyper/memory/gc/stmtls.py @@ -179,6 +179,10 @@ # debug_start("gc-local") # + # First clear all thread-local caches, because they might + # contain pointers to objects that are about to move. + llop.stm_threadlocalref_flush(lltype.Void) + # if end_of_transaction: self.detect_flag_combination = GCFLAG_LOCAL_COPY | GCFLAG_VISITED else: From noreply at buildbot.pypy.org Mon Feb 18 15:45:14 2013 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 18 Feb 2013 15:45:14 +0100 (CET) Subject: [pypy-commit] pypy stm-thread-2: Use ThreadLocalReference to get the excutioncontext more efficiently. Message-ID: <20130218144514.7CEF01C009B@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stm-thread-2 Changeset: r61409:3576f38d6a82 Date: 2013-02-18 14:21 +0100 http://bitbucket.org/pypy/pypy/changeset/3576f38d6a82/ Log: Use ThreadLocalReference to get the excutioncontext more efficiently. diff --git a/pypy/module/thread/stm.py b/pypy/module/thread/stm.py --- a/pypy/module/thread/stm.py +++ b/pypy/module/thread/stm.py @@ -4,13 +4,16 @@ from pypy.module.thread.threadlocals import OSThreadLocals from pypy.module.thread.error import wrap_thread_error +from pypy.interpreter.executioncontext import ExecutionContext from rpython.rlib import rthread from rpython.rlib import rstm from rpython.rlib.objectmodel import invoke_around_extcall +ec_cache = rstm.ThreadLocalReference(ExecutionContext) + + class STMThreadLocals(OSThreadLocals): - can_cache = False def initialize(self, space): """NOT_RPYTHON: set up a mechanism to send to the C code the value @@ -27,6 +30,17 @@ space.actionflag.setcheckinterval_callback = setcheckinterval_callback self.threads_running = False + def clear_cache(self): + ec_cache.set(None) + + def getvalue(self): + value = ec_cache.get() + if value is None: + ident = rthread.get_ident() + value = self._valuedict.get(ident, None) + ec_cache.set(value) + return value + def setup_threads(self, space): self.threads_running = True self.configure_transaction_length(space) diff --git a/pypy/module/thread/threadlocals.py b/pypy/module/thread/threadlocals.py --- a/pypy/module/thread/threadlocals.py +++ b/pypy/module/thread/threadlocals.py @@ -12,8 +12,6 @@ a thread finishes. This works as long as the thread was started by os_thread.bootstrap().""" - can_cache = True - def __init__(self): self._valuedict = {} # {thread_ident: ExecutionContext()} self._cleanup_() @@ -21,20 +19,24 @@ def _cleanup_(self): self._valuedict.clear() self._mainthreadident = 0 - if self.can_cache: - self._mostrecentkey = 0 # fast minicaching for the common case - self._mostrecentvalue = None # fast minicaching for the common case + self.clear_cache() + + def clear_cache(self): + # Cache function: fast minicaching for the common case. Relies + # on the GIL; overridden in stm.py. + self._mostrecentkey = 0 + self._mostrecentvalue = None def getvalue(self): + # Overridden in stm.py. ident = rthread.get_ident() - if self.can_cache and ident == self._mostrecentkey: + if ident == self._mostrecentkey: result = self._mostrecentvalue else: value = self._valuedict.get(ident, None) - if self.can_cache: - # slow path: update the minicache - self._mostrecentkey = ident - self._mostrecentvalue = value + # slow path: update the minicache + self._mostrecentkey = ident + self._mostrecentvalue = value result = value return result @@ -50,10 +52,8 @@ del self._valuedict[ident] except KeyError: pass - if self.can_cache: - # update the minicache to prevent it from containing an outdated value - self._mostrecentkey = ident - self._mostrecentvalue = value + # clear the minicache to prevent it from containing an outdated value + self.clear_cache() def signals_enabled(self): ec = self.getvalue() From noreply at buildbot.pypy.org Mon Feb 18 16:11:24 2013 From: noreply at buildbot.pypy.org (bivab) Date: Mon, 18 Feb 2013 16:11:24 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: _store_and_reset_exception Message-ID: <20130218151124.131A11C009B@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: jitframe-on-heap Changeset: r61410:ca4c8057230f Date: 2013-02-18 16:09 +0100 http://bitbucket.org/pypy/pypy/changeset/ca4c8057230f/ Log: _store_and_reset_exception diff --git a/rpython/jit/backend/arm/assembler.py b/rpython/jit/backend/arm/assembler.py --- a/rpython/jit/backend/arm/assembler.py +++ b/rpython/jit/backend/arm/assembler.py @@ -201,23 +201,19 @@ self.propagate_exception_path = rawstart def _store_and_reset_exception(self, mc, resloc): - assert resloc is r.r0 + assert resloc is not r.ip + tmpreg = r.lr # use lr as a second temporary reg + mc.gen_load_int(r.ip.value, self.cpu.pos_exc_value()) + if resloc is not None: # store + self.load_reg(mc, resloc, r.ip, 0) - self.mc.gen_load_int(resloc.value, self.cpu.pos_exc_value()) - self.mc.gen_load_int(r.r0.value, self.cpu.pos_exc_value()) - self.mc.gen_load_int(r.ip.value, 0) - self.mc.STR_ri(r.ip.value, r.r0.value) - - - self.mc.LDR_ri(resloc.value, resloc.value) - self.mc.MOV(resloc, heap(self.cpu.pos_exc_value())) + # reset exception + mc.gen_load_int(tmpreg.value, 0) - with saved_registers(self.mc, [r.r0]): - self.mc.gen_load_int(r.r0.value, self.cpu.pos_exc_value()) - self.mc.gen_load_int(r.ip.value, 0) - self.mc.STR_ri(r.ip.value, r.r0.value) - self.mc.gen_load_int(r.r0.value, self.cpu.pos_exception()) - self.mc.STR_ri(r.ip.value, r.r0.value) + self.store_reg(mc, tmpreg, r.ip, 0) + + mc.gen_load_int(r.ip.value, self.cpu.pos_exception()) + self.store_reg(mc, tmpreg, r.ip, 0) def _build_stack_check_slowpath(self): _, _, slowpathaddr = self.cpu.insert_stack_check() diff --git a/rpython/jit/backend/arm/opassembler.py b/rpython/jit/backend/arm/opassembler.py --- a/rpython/jit/backend/arm/opassembler.py +++ b/rpython/jit/backend/arm/opassembler.py @@ -538,12 +538,7 @@ self.mc.CMP_rr(r.ip.value, loc.value) self._emit_guard(op, failargs, c.EQ, save_exc=True) - self.mc.gen_load_int(loc.value, pos_exc_value.value) - if resloc: - self.mc.LDR_ri(resloc.value, loc.value) - self.mc.MOV_ri(r.ip.value, 0) - self.mc.STR_ri(r.ip.value, loc.value) - self.mc.STR_ri(r.ip.value, loc1.value) + self._store_and_reset_exception(self.mc, resloc) return fcond def emit_op_debug_merge_point(self, op, arglocs, regalloc, fcond): From noreply at buildbot.pypy.org Mon Feb 18 16:12:51 2013 From: noreply at buildbot.pypy.org (timfel) Date: Mon, 18 Feb 2013 16:12:51 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: (timfel, cfbolz) start adding shadows to compiled methods Message-ID: <20130218151251.290091C009B@cobra.cs.uni-duesseldorf.de> Author: Tim Felgentreff Branch: Changeset: r36:8986dba2aebd Date: 2013-02-18 15:08 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/8986dba2aebd/ Log: (timfel, cfbolz) start adding shadows to compiled methods diff --git a/spyvm/model.py b/spyvm/model.py --- a/spyvm/model.py +++ b/spyvm/model.py @@ -464,6 +464,7 @@ def __init__(self, bytecount=0, header=0): self.setheader(header) self.bytes = ["\x00"] * bytecount + self._shadow = None def become(self, w_other): if not isinstance(w_other, W_CompiledMethod): @@ -574,6 +575,15 @@ self.w_compiledin = None self.islarge = islarge + def setbytes(self, bytes): + self.bytes = bytes + + def as_compiledmethod_get_shadow(self, space): + from shadow import CompiledMethodShadow + if self._shadow is None: + self._shadow = CompiledMethodShadow(self) + return self._shadow + def literalat0(self, space, index0): if index0 == 0: return space.wrap_int(self.getheader()) diff --git a/spyvm/shadow.py b/spyvm/shadow.py --- a/spyvm/shadow.py +++ b/spyvm/shadow.py @@ -706,3 +706,9 @@ def myblocksize(self): return self.size() - self.tempsize() + + +class CompiledMethodShadow(object): + def __init__(self, w_compiledmethod): + self.w_compiledmethod = w_compiledmethod + self.bytecode = "".join(w_compiledmethod.bytes) diff --git a/spyvm/squeakimage.py b/spyvm/squeakimage.py --- a/spyvm/squeakimage.py +++ b/spyvm/squeakimage.py @@ -373,6 +373,7 @@ w_bytesobject.w_class = w_class w_bytesobject.bytes = self.get_bytes() w_bytesobject.hash = self.chunk.hash12 # XXX check this + def get_bytes(self): bytes = [] if self.reader.swap: @@ -400,7 +401,7 @@ w_compiledmethod.literalatput0( self.space, i, self.decode_pointer(self.chunk.data[i]).w_object) bbytes = self.get_bytes()[(w_compiledmethod.literalsize + 1)*4:] - w_compiledmethod.bytes = bbytes + w_compiledmethod.setbytes(bbytes) class ImageChunk(object): """ A chunk knows the information from the header, but the body of the diff --git a/spyvm/test/test_shadow.py b/spyvm/test/test_shadow.py --- a/spyvm/test/test_shadow.py +++ b/spyvm/test/test_shadow.py @@ -181,3 +181,9 @@ assert ([s_newobject.fetch(i) for i in range(s_newobject.size())] == [s_object.fetch(i) for i in range(s_newobject.size())]) assert w_object._shadow is s_newobject + +def test_compiledmethodshadow(): + w_compiledmethod = model.W_CompiledMethod() + w_compiledmethod.setbytes(list("abc")) + shadow = w_compiledmethod.as_compiledmethod_get_shadow(space) + assert shadow.bytecode == "abc" From noreply at buildbot.pypy.org Mon Feb 18 16:12:52 2013 From: noreply at buildbot.pypy.org (timfel) Date: Mon, 18 Feb 2013 16:12:52 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: (cfbolz, timfel) fix not-aligned access into compiled method Message-ID: <20130218151252.41FF21C009B@cobra.cs.uni-duesseldorf.de> Author: Tim Felgentreff Branch: Changeset: r37:ea768f7676bc Date: 2013-02-18 15:57 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/ea768f7676bc/ Log: (cfbolz, timfel) fix not-aligned access into compiled method diff --git a/spyvm/model.py b/spyvm/model.py --- a/spyvm/model.py +++ b/spyvm/model.py @@ -614,11 +614,14 @@ return space.wrap_int(ord(self.bytes[index0])) def atput0(self, space, index0, w_value): - if index0 <= self.getliteralsize(): + byteoffset = self.getliteralsize() + self.headersize() + if index0 < byteoffset: + if index0 % constants.BYTES_PER_WORD != 0: + raise error.PrimitiveFailedError("improper store") self.literalatput0(space, index0 / constants.BYTES_PER_WORD, w_value) else: # XXX use to-be-written unwrap_char - index0 = index0 - self.getliteralsize() - self.headersize() + index0 = index0 - byteoffset assert index0 < len(self.bytes) self.setchar(index0, chr(space.unwrap_int(w_value))) diff --git a/spyvm/test/test_model.py b/spyvm/test/test_model.py --- a/spyvm/test/test_model.py +++ b/spyvm/test/test_model.py @@ -1,7 +1,7 @@ import py from spyvm import model, shadow from spyvm.shadow import MethodNotFound -from spyvm import objspace +from spyvm import objspace, error mockclass = objspace.bootstrap_class @@ -130,6 +130,14 @@ assert space.unwrap_int(w_method.at0(space, 13)) == ord('b') assert space.unwrap_int(w_method.at0(space, 14)) == ord('c') +def test_compiledmethod_atput0_not_aligned(): + header = joinbits([0,2,0,0,0,0],[9,8,1,6,4,1]) + w_method = model.W_CompiledMethod(3, header) + with py.test.raises(error.PrimitiveFailedError): + w_method.atput0(space, 7, 'lit1') + with py.test.raises(error.PrimitiveFailedError): + w_method.atput0(space, 9, space.wrap_int(5)) + def test_is_same_object(w_o1=model.W_PointersObject(None,0), w_o2=None): if w_o2 is None: w_o2 = w_o1 From noreply at buildbot.pypy.org Mon Feb 18 16:12:53 2013 From: noreply at buildbot.pypy.org (timfel) Date: Mon, 18 Feb 2013 16:12:53 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: (cfbolz, timfel) shadow invalidation on atput0 and atliteralput0 Message-ID: <20130218151253.577E51C009B@cobra.cs.uni-duesseldorf.de> Author: Tim Felgentreff Branch: Changeset: r38:6a1de2f8b293 Date: 2013-02-18 15:59 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/6a1de2f8b293/ Log: (cfbolz, timfel) shadow invalidation on atput0 and atliteralput0 diff --git a/spyvm/model.py b/spyvm/model.py --- a/spyvm/model.py +++ b/spyvm/model.py @@ -596,6 +596,7 @@ self.setheader(header) else: self.literals[index0-1] = w_value + self._shadow = None def store(self, space, index0, w_v): self.atput0(space, index0, w_v) @@ -628,6 +629,7 @@ def setchar(self, index0, character): assert index0 >= 0 self.bytes[index0] = character + self._shadow = None # Use black magic to create w_nil without running the constructor, # thus allowing it to be used even in the constructor of its own diff --git a/spyvm/shadow.py b/spyvm/shadow.py --- a/spyvm/shadow.py +++ b/spyvm/shadow.py @@ -712,3 +712,4 @@ def __init__(self, w_compiledmethod): self.w_compiledmethod = w_compiledmethod self.bytecode = "".join(w_compiledmethod.bytes) + self.literals = w_compiledmethod.literals diff --git a/spyvm/test/test_shadow.py b/spyvm/test/test_shadow.py --- a/spyvm/test/test_shadow.py +++ b/spyvm/test/test_shadow.py @@ -183,7 +183,23 @@ assert w_object._shadow is s_newobject def test_compiledmethodshadow(): - w_compiledmethod = model.W_CompiledMethod() + from test_model import joinbits + header = joinbits([0,2,0,0,0,0],[9,8,1,6,4,1]) + + w_compiledmethod = model.W_CompiledMethod(3, header) w_compiledmethod.setbytes(list("abc")) shadow = w_compiledmethod.as_compiledmethod_get_shadow(space) assert shadow.bytecode == "abc" + + w_compiledmethod.literalatput0(space, 1, 17) + w_compiledmethod.literalatput0(space, 2, 41) + assert w_compiledmethod._shadow is None + + shadow = w_compiledmethod.as_compiledmethod_get_shadow(space) + assert shadow.literals == [17, 41] + + w_compiledmethod.atput0(space, 14, space.wrap_int(ord("x"))) + assert w_compiledmethod._shadow is None + + shadow = w_compiledmethod.as_compiledmethod_get_shadow(space) + assert shadow.bytecode == "abx" From noreply at buildbot.pypy.org Mon Feb 18 16:12:54 2013 From: noreply at buildbot.pypy.org (timfel) Date: Mon, 18 Feb 2013 16:12:54 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: (cfbolz, timfel) use compiled methods bytecodeoffset() method and comment Message-ID: <20130218151254.7D5611C009B@cobra.cs.uni-duesseldorf.de> Author: Tim Felgentreff Branch: Changeset: r39:e5c223dd3804 Date: 2013-02-18 16:09 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/e5c223dd3804/ Log: (cfbolz, timfel) use compiled methods bytecodeoffset() method and comment diff --git a/spyvm/model.py b/spyvm/model.py --- a/spyvm/model.py +++ b/spyvm/model.py @@ -602,7 +602,8 @@ self.atput0(space, index0, w_v) def at0(self, space, index0): - if index0 <= self.getliteralsize(): + if index0 < self.bytecodeoffset(): + # XXX: find out what happens if unaligned return self.literalat0(space, index0 / constants.BYTES_PER_WORD) else: # From blue book: @@ -610,19 +611,18 @@ # CompiledMethod's literal frame. # This, in turn, indicates where the # CompiledMethod's bytecodes start. - index0 = index0 - self.getliteralsize() - self.headersize() + index0 = index0 - self.bytecodeoffset() assert index0 < len(self.bytes) return space.wrap_int(ord(self.bytes[index0])) def atput0(self, space, index0, w_value): - byteoffset = self.getliteralsize() + self.headersize() - if index0 < byteoffset: + if index0 < self.bytecodeoffset(): if index0 % constants.BYTES_PER_WORD != 0: raise error.PrimitiveFailedError("improper store") self.literalatput0(space, index0 / constants.BYTES_PER_WORD, w_value) else: # XXX use to-be-written unwrap_char - index0 = index0 - byteoffset + index0 = index0 - self.bytecodeoffset() assert index0 < len(self.bytes) self.setchar(index0, chr(space.unwrap_int(w_value))) From noreply at buildbot.pypy.org Mon Feb 18 16:12:55 2013 From: noreply at buildbot.pypy.org (timfel) Date: Mon, 18 Feb 2013 16:12:55 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: (timfel, cfbolz) add bytecodeoffset to shadow Message-ID: <20130218151255.874781C009B@cobra.cs.uni-duesseldorf.de> Author: Tim Felgentreff Branch: Changeset: r40:946a179f9eef Date: 2013-02-18 16:09 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/946a179f9eef/ Log: (timfel, cfbolz) add bytecodeoffset to shadow diff --git a/spyvm/shadow.py b/spyvm/shadow.py --- a/spyvm/shadow.py +++ b/spyvm/shadow.py @@ -713,3 +713,4 @@ self.w_compiledmethod = w_compiledmethod self.bytecode = "".join(w_compiledmethod.bytes) self.literals = w_compiledmethod.literals + self.bytecodeoffset = w_compiledmethod.bytecodeoffset() diff --git a/spyvm/test/test_shadow.py b/spyvm/test/test_shadow.py --- a/spyvm/test/test_shadow.py +++ b/spyvm/test/test_shadow.py @@ -190,6 +190,7 @@ w_compiledmethod.setbytes(list("abc")) shadow = w_compiledmethod.as_compiledmethod_get_shadow(space) assert shadow.bytecode == "abc" + assert shadow.bytecodeoffset == 12 w_compiledmethod.literalatput0(space, 1, 17) w_compiledmethod.literalatput0(space, 2, 41) From noreply at buildbot.pypy.org Mon Feb 18 16:54:18 2013 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 18 Feb 2013 16:54:18 +0100 (CET) Subject: [pypy-commit] pypy stm-thread-2: Check in the latest version of richards. Message-ID: <20130218155418.4C8E91C009B@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stm-thread-2 Changeset: r61411:cb03b88cc37a Date: 2013-02-18 16:54 +0100 http://bitbucket.org/pypy/pypy/changeset/cb03b88cc37a/ Log: Check in the latest version of richards. diff --git a/rpython/translator/stm/test/richards.py b/rpython/translator/stm/test/richards.py --- a/rpython/translator/stm/test/richards.py +++ b/rpython/translator/stm/test/richards.py @@ -7,7 +7,10 @@ # Translation from C++, Mario Wolczko # Outer loop added by Alex Jacoby -import transaction +try: + import transaction +except ImportError: + import transaction_emulator as transaction # Task IDs @@ -345,6 +348,8 @@ import time + + def prepare_schedule(taskWorkArea): t = taskWorkArea.taskList transaction.add(schedule_one, taskWorkArea, t) @@ -428,8 +433,15 @@ if __name__ == '__main__': import sys - transaction.set_num_threads(4) - if len(sys.argv) >= 2: - main(iterations = int(sys.argv[1])) + max_num_threads = 5 + if len(sys.argv) > 1: + iterations = int(sys.argv[1]) + if len(sys.argv) > 2: + max_num_threads = int(sys.argv[2]) + assert max_num_threads <= iterations else: - main() + iterations = 10 + num_threads = min(iterations, max_num_threads) + print "Running %d iterations on %d threads" % (iterations, num_threads) + transaction.set_num_threads(num_threads) + main(iterations = iterations) diff --git a/rpython/translator/stm/test/transaction_emulator.py b/rpython/translator/stm/test/transaction_emulator.py new file mode 100644 --- /dev/null +++ b/rpython/translator/stm/test/transaction_emulator.py @@ -0,0 +1,32 @@ +print "warning: using transaction_emulator" + +from collections import deque + +pending = deque() + +def add(f, *args): + #print 'add:', f, args + pending.append((f, args)) + +def run(): + while pending: + f, args = pending.popleft() + #print 'run:', f, args + f(*args) + +def set_num_threads(num): + pass + +def add_epoll(ep, callback): + def poll_reader(): + # assume only one epoll is added. If the _pending list is + # now empty, wait. If not, then just poll non-blockingly. + if len(pending) == 0: + timeout = -1 + else: + timeout = 0 + got = ep.poll(timeout=timeout) + for fd, events in got: + add(callback, fd, events) + add(poll_reader) + add(poll_reader) From noreply at buildbot.pypy.org Mon Feb 18 17:26:30 2013 From: noreply at buildbot.pypy.org (bivab) Date: Mon, 18 Feb 2013 17:26:30 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: move viewcode to a shared location Message-ID: <20130218162630.8AF211C0264@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: jitframe-on-heap Changeset: r61412:0dc0400e0d73 Date: 2013-02-18 16:52 +0100 http://bitbucket.org/pypy/pypy/changeset/0dc0400e0d73/ Log: move viewcode to a shared location diff --git a/rpython/jit/backend/tool/viewcode.py b/rpython/jit/backend/tool/viewcode.py old mode 100644 new mode 100755 --- a/rpython/jit/backend/tool/viewcode.py +++ b/rpython/jit/backend/tool/viewcode.py @@ -1,11 +1,453 @@ -from rpython.jit.backend.detect_cpu import autodetect_main_model +#! /usr/bin/env python +""" +Viewer for the output of compiled programs generating code. +Use on the log files created with 'PYPYLOG=jit-backend-dump:log'. + +Try: + ./viewcode.py --text log # text only disassembly + ./viewcode.py log # also includes a pygame viewer +""" + +import new +import operator +import os +import py +import re import sys +import subprocess +from bisect import bisect_left +# don't use rpython.tool.udir here to avoid removing old usessions which +# might still contain interesting executables +udir = py.path.local.make_numbered_dir(prefix='viewcode-', keep=2) +tmpfile = str(udir.join('dump.tmp')) -def get_module(mod): - __import__(mod) - return sys.modules[mod] +# hack hack +import rpython.tool +mod = new.module('rpython.tool.udir') +mod.udir = udir +sys.modules['rpython.tool.udir'] = mod +rpython.tool.udir = mod -cpu = autodetect_main_model() -viewcode = get_module("rpython.jit.backend.%s.tool.viewcode" % cpu) -machine_code_dump = getattr(viewcode, 'machine_code_dump') +# ____________________________________________________________ +# Some support code from Psyco. There is more over there, +# I am porting it in a lazy fashion... See py-utils/xam.py + +if sys.platform == "win32": + pass # lots more in Psyco + +def find_objdump(): + exe = ('objdump', 'gobjdump') + path = os.environ['PATH'].split(os.pathsep) + for e in exe: + for p in path: + path_to = os.path.join(p, e) + if not os.path.exists(path_to): + continue + return e + raise AssertionError('(g)objdump was not found in PATH') + +def machine_code_dump(data, originaddr, backend_name, label_list=None): + objdump_backend_option = { + 'x86': 'i386', + 'x86_32': 'i386', + 'x86_64': 'x86-64', + 'i386': 'i386', + 'arm': 'arm', + } + cmd = find_objdump() + objdump = ('%(command)s -M %(backend)s -b binary -m %(machine)s ' + '--disassembler-options=intel-mnemonics ' + '--adjust-vma=%(origin)d -D %(file)s') + # + f = open(tmpfile, 'wb') + f.write(data) + f.close() + p = subprocess.Popen(objdump % { + 'command': cmd, + 'file': tmpfile, + 'origin': originaddr, + 'backend': objdump_backend_option[backend_name], + 'machine': 'i386' if backend_name != 'arm' else 'arm', + }, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + stdout, stderr = p.communicate() + assert not p.returncode, ('Encountered an error running objdump: %s' % + stderr) + # drop some objdump cruft + lines = stdout.splitlines(True)[6:] # drop some objdump cruft + return format_code_dump_with_labels(originaddr, lines, label_list) + +def format_code_dump_with_labels(originaddr, lines, label_list): + from rpython.rlib.rarithmetic import r_uint + if not label_list: + label_list = [] + originaddr = r_uint(originaddr) + itlines = iter(lines) + yield itlines.next() # don't process the first line + for lbl_start, lbl_name in label_list: + for line in itlines: + addr, _ = line.split(':', 1) + addr = int(addr, 16) + if addr >= originaddr+lbl_start: + yield '\n' + if lbl_name is None: + yield '--end of the loop--\n' + else: + yield str(lbl_name) + '\n' + yield line + break + yield line + # yield all the remaining lines + for line in itlines: + yield line + +def load_symbols(filename): + # the program that lists symbols, and the output it gives + symbollister = 'nm %s' + re_symbolentry = re.compile(r'([0-9a-fA-F]+)\s\w\s(.*)') + # + print 'loading symbols from %s...' % (filename,) + symbols = {} + p = subprocess.Popen(symbollister % filename, shell=True, + stdout=subprocess.PIPE, stderr=subprocess.PIPE) + stdout, stderr = p.communicate() + assert not p.returncode, ('Encountered an error running nm: %s' % + stderr) + for line in stdout.splitlines(True): + match = re_symbolentry.match(line) + if match: + addr = long(match.group(1), 16) + name = match.group(2) + if name.startswith('pypy_g_'): + name = '\xb7' + name[7:] + symbols[addr] = name + print '%d symbols found' % (len(symbols),) + return symbols + +re_addr = re.compile(r'[\s,$]0x([0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]+)') +re_lineaddr = re.compile(r'\s*0?x?([0-9a-fA-F]+)') + +def lineaddresses(line): + result = [] + i = 0 + while 1: + match = re_addr.search(line, i) + if not match: + break + i = match.end() + addr = long(match.group(1), 16) + result.append(addr) + return result + +# ____________________________________________________________ + +class CodeRange(object): + fallthrough = False + + def __init__(self, world, addr, data): + self.world = world + self.addr = addr + self.data = data + + def __repr__(self): + return '' % (hex(self.addr), len(self.data)) + + def touches(self, other): + return (self .addr < other.addr + len(other.data) and + other.addr < self .addr + len(self.data)) + + def update_from_old(self, other): + if other.addr < self.addr: + delta = self.addr - other.addr + assert delta <= len(other.data) + self.addr -= delta + self.data = other.data[:delta] + self.data + self_end = self .addr + len(self .data) + other_end = other.addr + len(other.data) + if other_end > self_end: + extra = other_end - self_end + assert extra <= len(other.data) + self.data += other.data[-extra:] + + def cmpop(op): + def _cmp(self, other): + if not isinstance(other, CodeRange): + return NotImplemented + return op((self.addr, self.data), (other.addr, other.data)) + return _cmp + __lt__ = cmpop(operator.lt) + __le__ = cmpop(operator.le) + __eq__ = cmpop(operator.eq) + __ne__ = cmpop(operator.ne) + __gt__ = cmpop(operator.gt) + __ge__ = cmpop(operator.ge) + del cmpop + + def disassemble(self): + if not hasattr(self, 'text'): + lines = machine_code_dump(self.data, self.addr, self.world.backend_name) + lines = list(lines) + # instead of adding symbol names in the dumps we could + # also make the 0xNNNNNNNN addresses be red and show the + # symbol name when the mouse is over them + logentries = self.world.logentries + symbols = self.world.symbols + for i, line in enumerate(lines): + match = re_lineaddr.match(line) + if match: + addr = long(match.group(1), 16) + logentry = logentries.get(addr) + if logentry: + lines[i] = '\n%s\n%s' % (logentry, lines[i]) + for addr in lineaddresses(line): + sym = symbols.get(addr) + if sym: + lines[i] = '%s\t%s\n' % (lines[i].rstrip(), sym) + self.text = ''.join(lines) + return self.text + + def findjumps(self): + text = self.disassemble() + lines = text.splitlines() + line = '' + for i, line in enumerate(lines): + if '\tj' not in line: # poor heuristic to recognize lines that + continue # could be jump instructions + addrs = list(lineaddresses(line)) + if not addrs: + continue + addr = addrs[-1] + final = '\tjmp' in line + yield i, addr, final + if self.fallthrough and '\tret' not in line: + yield len(lines), self.addr + len(self.data), True + + +class World(object): + + def __init__(self): + self.ranges = [] + self.labeltargets = {} + self.jumps = {} + self.symbols = {} + self.logentries = {} + self.backend_name = None + self.executable_name = None + + def parse(self, f, textonly=True): + for line in f: + if line.startswith('BACKEND '): + self.backend_name = line.split(' ')[1].strip() + elif line.startswith('CODE_DUMP '): + pieces = line.split() + assert pieces[1].startswith('@') + assert pieces[2].startswith('+') + if len(pieces) == 3: + continue # empty line + baseaddr = long(pieces[1][1:], 16) & 0xFFFFFFFFL + offset = int(pieces[2][1:]) + addr = baseaddr + offset + data = pieces[3].replace(':', '').decode('hex') + coderange = CodeRange(self, addr, data) + i = bisect_left(self.ranges, coderange) + j = i + while i>0 and coderange.touches(self.ranges[i-1]): + coderange.update_from_old(self.ranges[i-1]) + i -= 1 + while j= fnext: + sys.stderr.write("%d%%" % int(f*100.0)) + fnext += 0.1 + sys.stderr.write(".") + sys.stderr.write("100%") + # split blocks at labeltargets + t = self.labeltargets + #print t + for r in self.ranges: + #print r.addr, r.addr + len(r.data) + for i in range(r.addr + 1, r.addr + len(r.data)): + if i in t: + #print i + ofs = i - r.addr + self.ranges.append(CodeRange(self, i, r.data[ofs:])) + r.data = r.data[:ofs] + r.fallthrough = True + try: + del r.text + except AttributeError: + pass + break + # hack hack hacked + sys.stderr.write("\n") + + def show(self, showtext=True, showgraph=True): + if showgraph: + g1 = Graph('codedump') + self.ranges.sort() + for r in self.ranges: + disassembled = r.disassemble() + if showtext: + print disassembled + if showgraph: + text, width = tab2columns(disassembled) + text = '0x%x\n\n%s' % (r.addr, text) + g1.emit_node('N_%x' % r.addr, shape="box", label=text, + width=str(width*0.1125)) + for lineno, targetaddr, final in r.findjumps(): + if final: + color = "black" + else: + color = "red" + g1.emit_edge('N_%x' % r.addr, 'N_%x' % targetaddr, + color=color) + sys.stdout.flush() + if showgraph: + g1.display() + + def showtextonly(self): + self.ranges.sort() + for r in self.ranges: + disassembled = r.disassemble() + print disassembled + del r.text + + +def tab2columns(text): + lines = text.split('\n') + columnwidth = [] + for line in lines: + columns = line.split('\t')[:-1] + while len(columnwidth) < len(columns): + columnwidth.append(0) + for i, s in enumerate(columns): + width = len(s.strip()) + if not s.endswith(':'): + width += 2 + columnwidth[i] = max(columnwidth[i], width) + columnwidth.append(1) + result = [] + for line in lines: + columns = line.split('\t') + text = [] + for width, s in zip(columnwidth, columns): + text.append(s.strip().ljust(width)) + result.append(' '.join(text)) + lengths = [len(line) for line in result] + lengths.append(1) + totalwidth = max(lengths) + return '\\l'.join(result), totalwidth + +# ____________________________________________________________ +# XXX pasted from +# http://codespeak.net/svn/user/arigo/hack/misc/graphlib.py +# but needs to be a bit more subtle later + +from rpython.translator.tool.make_dot import DotGen +from dotviewer.graphclient import display_page + +class Graph(DotGen): + + def highlight(self, word, text, linked_to=None): + if not hasattr(self, '_links'): + self._links = {} + self._links_to = {} + self._links[word] = text + if linked_to: + self._links_to[word] = linked_to + + def display(self): + "Display a graph page locally." + display_page(_Page(self)) + + +class NoGraph(Exception): + pass + +class _Page: + def __init__(self, graph_builder): + if callable(graph_builder): + graph = graph_builder() + else: + graph = graph_builder + if graph is None: + raise NoGraph + self.graph_builder = graph_builder + + def content(self): + return _PageContent(self.graph_builder) + +class _PageContent: + fixedfont = True + + def __init__(self, graph_builder): + if callable(graph_builder): + graph = graph_builder() + else: + graph = graph_builder + assert graph is not None + self.graph_builder = graph_builder + self.graph = graph + self.links = getattr(graph, '_links', {}) + if not hasattr(graph, '_source'): + graph._source = graph.generate(target=None) + self.source = graph._source + + def followlink(self, link): + try: + return _Page(self.graph._links_to[link]) + except NoGraph: + return _Page(self.graph_builder) + +# ____________________________________________________________ + +if __name__ == '__main__': + if '--text' in sys.argv: + sys.argv.remove('--text') + showgraph = False + else: + showgraph = True + if len(sys.argv) != 2: + print >> sys.stderr, __doc__ + sys.exit(2) + # + import cStringIO + from rpython.tool import logparser + log1 = logparser.parse_log_file(sys.argv[1]) + text1 = logparser.extract_category(log1, catprefix='jit-backend-dump') + f = cStringIO.StringIO() + f.writelines(text1) + f.seek(0) + del log1, text1 + # + world = World() + world.parse(f) + if showgraph: + world.find_cross_references() + world.show(showtext=True) + else: + world.showtextonly() diff --git a/rpython/jit/backend/x86/tool/viewcode.py b/rpython/jit/backend/x86/tool/viewcode.py deleted file mode 100755 --- a/rpython/jit/backend/x86/tool/viewcode.py +++ /dev/null @@ -1,453 +0,0 @@ -#! /usr/bin/env python -""" -Viewer for the output of compiled programs generating code. -Use on the log files created with 'PYPYLOG=jit-backend-dump:log'. - -Try: - ./viewcode.py --text log # text only disassembly - ./viewcode.py log # also includes a pygame viewer -""" - -import new -import operator -import os -import py -import re -import sys -import subprocess -from bisect import bisect_left - -# don't use rpython.tool.udir here to avoid removing old usessions which -# might still contain interesting executables -udir = py.path.local.make_numbered_dir(prefix='viewcode-', keep=2) -tmpfile = str(udir.join('dump.tmp')) - -# hack hack -import rpython.tool -mod = new.module('rpython.tool.udir') -mod.udir = udir -sys.modules['rpython.tool.udir'] = mod -rpython.tool.udir = mod - -# ____________________________________________________________ -# Some support code from Psyco. There is more over there, -# I am porting it in a lazy fashion... See py-utils/xam.py - -if sys.platform == "win32": - pass # lots more in Psyco - -def find_objdump(): - exe = ('objdump', 'gobjdump') - path = os.environ['PATH'].split(os.pathsep) - for e in exe: - for p in path: - path_to = os.path.join(p, e) - if not os.path.exists(path_to): - continue - return e - raise AssertionError('(g)objdump was not found in PATH') - -def machine_code_dump(data, originaddr, backend_name, label_list=None): - objdump_backend_option = { - 'x86': 'i386', - 'x86_32': 'i386', - 'x86_64': 'x86-64', - 'i386': 'i386', - 'arm': 'arm', - } - cmd = find_objdump() - objdump = ('%(command)s -M %(backend)s -b binary -m %(machine)s ' - '--disassembler-options=intel-mnemonics ' - '--adjust-vma=%(origin)d -D %(file)s') - # - f = open(tmpfile, 'wb') - f.write(data) - f.close() - p = subprocess.Popen(objdump % { - 'command': cmd, - 'file': tmpfile, - 'origin': originaddr, - 'backend': objdump_backend_option[backend_name], - 'machine': 'i386' if backend_name != 'arm' else 'arm', - }, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) - stdout, stderr = p.communicate() - assert not p.returncode, ('Encountered an error running objdump: %s' % - stderr) - # drop some objdump cruft - lines = stdout.splitlines(True)[6:] # drop some objdump cruft - return format_code_dump_with_labels(originaddr, lines, label_list) - -def format_code_dump_with_labels(originaddr, lines, label_list): - from rpython.rlib.rarithmetic import r_uint - if not label_list: - label_list = [] - originaddr = r_uint(originaddr) - itlines = iter(lines) - yield itlines.next() # don't process the first line - for lbl_start, lbl_name in label_list: - for line in itlines: - addr, _ = line.split(':', 1) - addr = int(addr, 16) - if addr >= originaddr+lbl_start: - yield '\n' - if lbl_name is None: - yield '--end of the loop--\n' - else: - yield str(lbl_name) + '\n' - yield line - break - yield line - # yield all the remaining lines - for line in itlines: - yield line - -def load_symbols(filename): - # the program that lists symbols, and the output it gives - symbollister = 'nm %s' - re_symbolentry = re.compile(r'([0-9a-fA-F]+)\s\w\s(.*)') - # - print 'loading symbols from %s...' % (filename,) - symbols = {} - p = subprocess.Popen(symbollister % filename, shell=True, - stdout=subprocess.PIPE, stderr=subprocess.PIPE) - stdout, stderr = p.communicate() - assert not p.returncode, ('Encountered an error running nm: %s' % - stderr) - for line in stdout.splitlines(True): - match = re_symbolentry.match(line) - if match: - addr = long(match.group(1), 16) - name = match.group(2) - if name.startswith('pypy_g_'): - name = '\xb7' + name[7:] - symbols[addr] = name - print '%d symbols found' % (len(symbols),) - return symbols - -re_addr = re.compile(r'[\s,$]0x([0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]+)') -re_lineaddr = re.compile(r'\s*0?x?([0-9a-fA-F]+)') - -def lineaddresses(line): - result = [] - i = 0 - while 1: - match = re_addr.search(line, i) - if not match: - break - i = match.end() - addr = long(match.group(1), 16) - result.append(addr) - return result - -# ____________________________________________________________ - -class CodeRange(object): - fallthrough = False - - def __init__(self, world, addr, data): - self.world = world - self.addr = addr - self.data = data - - def __repr__(self): - return '' % (hex(self.addr), len(self.data)) - - def touches(self, other): - return (self .addr < other.addr + len(other.data) and - other.addr < self .addr + len(self.data)) - - def update_from_old(self, other): - if other.addr < self.addr: - delta = self.addr - other.addr - assert delta <= len(other.data) - self.addr -= delta - self.data = other.data[:delta] + self.data - self_end = self .addr + len(self .data) - other_end = other.addr + len(other.data) - if other_end > self_end: - extra = other_end - self_end - assert extra <= len(other.data) - self.data += other.data[-extra:] - - def cmpop(op): - def _cmp(self, other): - if not isinstance(other, CodeRange): - return NotImplemented - return op((self.addr, self.data), (other.addr, other.data)) - return _cmp - __lt__ = cmpop(operator.lt) - __le__ = cmpop(operator.le) - __eq__ = cmpop(operator.eq) - __ne__ = cmpop(operator.ne) - __gt__ = cmpop(operator.gt) - __ge__ = cmpop(operator.ge) - del cmpop - - def disassemble(self): - if not hasattr(self, 'text'): - lines = machine_code_dump(self.data, self.addr, self.world.backend_name) - lines = list(lines) - # instead of adding symbol names in the dumps we could - # also make the 0xNNNNNNNN addresses be red and show the - # symbol name when the mouse is over them - logentries = self.world.logentries - symbols = self.world.symbols - for i, line in enumerate(lines): - match = re_lineaddr.match(line) - if match: - addr = long(match.group(1), 16) - logentry = logentries.get(addr) - if logentry: - lines[i] = '\n%s\n%s' % (logentry, lines[i]) - for addr in lineaddresses(line): - sym = symbols.get(addr) - if sym: - lines[i] = '%s\t%s\n' % (lines[i].rstrip(), sym) - self.text = ''.join(lines) - return self.text - - def findjumps(self): - text = self.disassemble() - lines = text.splitlines() - line = '' - for i, line in enumerate(lines): - if '\tj' not in line: # poor heuristic to recognize lines that - continue # could be jump instructions - addrs = list(lineaddresses(line)) - if not addrs: - continue - addr = addrs[-1] - final = '\tjmp' in line - yield i, addr, final - if self.fallthrough and '\tret' not in line: - yield len(lines), self.addr + len(self.data), True - - -class World(object): - - def __init__(self): - self.ranges = [] - self.labeltargets = {} - self.jumps = {} - self.symbols = {} - self.logentries = {} - self.backend_name = None - self.executable_name = None - - def parse(self, f, textonly=True): - for line in f: - if line.startswith('BACKEND '): - self.backend_name = line.split(' ')[1].strip() - elif line.startswith('CODE_DUMP '): - pieces = line.split() - assert pieces[1].startswith('@') - assert pieces[2].startswith('+') - if len(pieces) == 3: - continue # empty line - baseaddr = long(pieces[1][1:], 16) & 0xFFFFFFFFL - offset = int(pieces[2][1:]) - addr = baseaddr + offset - data = pieces[3].replace(':', '').decode('hex') - coderange = CodeRange(self, addr, data) - i = bisect_left(self.ranges, coderange) - j = i - while i>0 and coderange.touches(self.ranges[i-1]): - coderange.update_from_old(self.ranges[i-1]) - i -= 1 - while j= fnext: - sys.stderr.write("%d%%" % int(f*100.0)) - fnext += 0.1 - sys.stderr.write(".") - sys.stderr.write("100%") - # split blocks at labeltargets - t = self.labeltargets - #print t - for r in self.ranges: - #print r.addr, r.addr + len(r.data) - for i in range(r.addr + 1, r.addr + len(r.data)): - if i in t: - #print i - ofs = i - r.addr - self.ranges.append(CodeRange(self, i, r.data[ofs:])) - r.data = r.data[:ofs] - r.fallthrough = True - try: - del r.text - except AttributeError: - pass - break - # hack hack hacked - sys.stderr.write("\n") - - def show(self, showtext=True, showgraph=True): - if showgraph: - g1 = Graph('codedump') - self.ranges.sort() - for r in self.ranges: - disassembled = r.disassemble() - if showtext: - print disassembled - if showgraph: - text, width = tab2columns(disassembled) - text = '0x%x\n\n%s' % (r.addr, text) - g1.emit_node('N_%x' % r.addr, shape="box", label=text, - width=str(width*0.1125)) - for lineno, targetaddr, final in r.findjumps(): - if final: - color = "black" - else: - color = "red" - g1.emit_edge('N_%x' % r.addr, 'N_%x' % targetaddr, - color=color) - sys.stdout.flush() - if showgraph: - g1.display() - - def showtextonly(self): - self.ranges.sort() - for r in self.ranges: - disassembled = r.disassemble() - print disassembled - del r.text - - -def tab2columns(text): - lines = text.split('\n') - columnwidth = [] - for line in lines: - columns = line.split('\t')[:-1] - while len(columnwidth) < len(columns): - columnwidth.append(0) - for i, s in enumerate(columns): - width = len(s.strip()) - if not s.endswith(':'): - width += 2 - columnwidth[i] = max(columnwidth[i], width) - columnwidth.append(1) - result = [] - for line in lines: - columns = line.split('\t') - text = [] - for width, s in zip(columnwidth, columns): - text.append(s.strip().ljust(width)) - result.append(' '.join(text)) - lengths = [len(line) for line in result] - lengths.append(1) - totalwidth = max(lengths) - return '\\l'.join(result), totalwidth - -# ____________________________________________________________ -# XXX pasted from -# http://codespeak.net/svn/user/arigo/hack/misc/graphlib.py -# but needs to be a bit more subtle later - -from rpython.translator.tool.make_dot import DotGen -from dotviewer.graphclient import display_page - -class Graph(DotGen): - - def highlight(self, word, text, linked_to=None): - if not hasattr(self, '_links'): - self._links = {} - self._links_to = {} - self._links[word] = text - if linked_to: - self._links_to[word] = linked_to - - def display(self): - "Display a graph page locally." - display_page(_Page(self)) - - -class NoGraph(Exception): - pass - -class _Page: - def __init__(self, graph_builder): - if callable(graph_builder): - graph = graph_builder() - else: - graph = graph_builder - if graph is None: - raise NoGraph - self.graph_builder = graph_builder - - def content(self): - return _PageContent(self.graph_builder) - -class _PageContent: - fixedfont = True - - def __init__(self, graph_builder): - if callable(graph_builder): - graph = graph_builder() - else: - graph = graph_builder - assert graph is not None - self.graph_builder = graph_builder - self.graph = graph - self.links = getattr(graph, '_links', {}) - if not hasattr(graph, '_source'): - graph._source = graph.generate(target=None) - self.source = graph._source - - def followlink(self, link): - try: - return _Page(self.graph._links_to[link]) - except NoGraph: - return _Page(self.graph_builder) - -# ____________________________________________________________ - -if __name__ == '__main__': - if '--text' in sys.argv: - sys.argv.remove('--text') - showgraph = False - else: - showgraph = True - if len(sys.argv) != 2: - print >> sys.stderr, __doc__ - sys.exit(2) - # - import cStringIO - from rpython.tool import logparser - log1 = logparser.parse_log_file(sys.argv[1]) - text1 = logparser.extract_category(log1, catprefix='jit-backend-dump') - f = cStringIO.StringIO() - f.writelines(text1) - f.seek(0) - del log1, text1 - # - world = World() - world.parse(f) - if showgraph: - world.find_cross_references() - world.show(showtext=True) - else: - world.showtextonly() From noreply at buildbot.pypy.org Mon Feb 18 17:26:31 2013 From: noreply at buildbot.pypy.org (bivab) Date: Mon, 18 Feb 2013 17:26:31 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: objdump shortcut Message-ID: <20130218162631.C008B1C0264@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: jitframe-on-heap Changeset: r61413:0dff79981834 Date: 2013-02-18 17:24 +0100 http://bitbucket.org/pypy/pypy/changeset/0dff79981834/ Log: objdump shortcut diff --git a/rpython/jit/backend/arm/tool/viewdump.sh b/rpython/jit/backend/arm/tool/viewdump.sh new file mode 100755 --- /dev/null +++ b/rpython/jit/backend/arm/tool/viewdump.sh @@ -0,0 +1,2 @@ +#!/bin/sh +objdump -D -M reg-names-std --architecture=arm --target=binary ${1} From noreply at buildbot.pypy.org Mon Feb 18 17:26:32 2013 From: noreply at buildbot.pypy.org (bivab) Date: Mon, 18 Feb 2013 17:26:32 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: add further architecture Message-ID: <20130218162632.E79DB1C0264@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: jitframe-on-heap Changeset: r61414:85b19ba29140 Date: 2013-02-18 17:24 +0100 http://bitbucket.org/pypy/pypy/changeset/85b19ba29140/ Log: add further architecture diff --git a/rpython/jit/backend/tool/viewcode.py b/rpython/jit/backend/tool/viewcode.py --- a/rpython/jit/backend/tool/viewcode.py +++ b/rpython/jit/backend/tool/viewcode.py @@ -16,12 +16,12 @@ import sys import subprocess from bisect import bisect_left + # don't use rpython.tool.udir here to avoid removing old usessions which # might still contain interesting executables udir = py.path.local.make_numbered_dir(prefix='viewcode-', keep=2) tmpfile = str(udir.join('dump.tmp')) - # hack hack import rpython.tool mod = new.module('rpython.tool.udir') @@ -54,6 +54,7 @@ 'x86_64': 'x86-64', 'i386': 'i386', 'arm': 'arm', + 'arm_32': 'arm', } cmd = find_objdump() objdump = ('%(command)s -M %(backend)s -b binary -m %(machine)s ' From noreply at buildbot.pypy.org Mon Feb 18 17:26:34 2013 From: noreply at buildbot.pypy.org (bivab) Date: Mon, 18 Feb 2013 17:26:34 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: kill arm version of viewcode Message-ID: <20130218162634.31E891C0264@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: jitframe-on-heap Changeset: r61415:dcb16cd1fff9 Date: 2013-02-18 17:25 +0100 http://bitbucket.org/pypy/pypy/changeset/dcb16cd1fff9/ Log: kill arm version of viewcode diff --git a/rpython/jit/backend/arm/tool/viewcode.py b/rpython/jit/backend/arm/tool/viewcode.py deleted file mode 100755 --- a/rpython/jit/backend/arm/tool/viewcode.py +++ /dev/null @@ -1,88 +0,0 @@ -#!/usr/bin/env python -""" -Try: - ./viewcode.py file.asm - ./viewcode.py --decode dumpfile -""" -import os, sys, py -import subprocess - -def machine_code_dump(data, originaddr, backend_name, label_list=None): - objdump_backend_option = { - 'arm': 'arm', - 'arm_32': 'arm', - } - assert backend_name in objdump_backend_option - tmpfile = get_tmp_file() - objdump = 'objdump -M reg-names-std --adjust-vma=%(origin)d -D --architecture=arm --target=binary %(file)s' - # - f = open(tmpfile, 'wb') - f.write(data) - f.close() - p = subprocess.Popen(objdump % { - 'file': tmpfile, - 'origin': originaddr, - }, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) - stdout, stderr = p.communicate() - assert not p.returncode, ('Encountered an error running objdump: %s' % - stderr) - # drop some objdump cruft - lines = stdout.splitlines(True)[6:] # drop some objdump cruft - return format_code_dump_with_labels(originaddr, lines, label_list) - -def format_code_dump_with_labels(originaddr, lines, label_list): - from rpython.rlib.rarithmetic import r_uint - if not label_list: - label_list = [] - originaddr = r_uint(originaddr) - itlines = iter(lines) - yield itlines.next() # don't process the first line - for lbl_start, lbl_name in label_list: - for line in itlines: - addr, _ = line.split(':', 1) - addr = int(addr, 16) - if addr >= originaddr+lbl_start: - yield '\n' - if lbl_name is None: - yield '--end of the loop--\n' - else: - yield str(lbl_name) + '\n' - yield line - break - yield line - # yield all the remaining lines - for line in itlines: - yield line - -def objdump(input): - os.system('objdump -D -M reg-names-std --architecture=arm --target=binary %s' % input) - - -def get_tmp_file(): - # don't use rpython.tool.udir here to avoid removing old usessions which - # might still contain interesting executables - udir = py.path.local.make_numbered_dir(prefix='viewcode-', keep=2) - tmpfile = str(udir.join('dump.tmp')) - return tmpfile - -def decode(source): - with open(source, 'r') as f: - data = f.read().strip() - data = data.decode('hex') - - target = get_tmp_file() - with open(target, 'wb') as f: - f.write(data) - return target - - -if __name__ == '__main__': - if len(sys.argv) == 2: - objdump(sys.argv[1]) - elif len(sys.argv) == 3: - assert sys.argv[1] == '--decode' - f = decode(sys.argv[2]) - objdump(f) - else: - print >> sys.stderr, __doc__ - sys.exit(2) From noreply at buildbot.pypy.org Mon Feb 18 17:43:35 2013 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 18 Feb 2013 17:43:35 +0100 (CET) Subject: [pypy-commit] pypy stm-thread-2: Fix: must do this step after the GC was annotated. Message-ID: <20130218164335.4A42A1C009B@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stm-thread-2 Changeset: r61416:8c39c061c441 Date: 2013-02-18 17:42 +0100 http://bitbucket.org/pypy/pypy/changeset/8c39c061c441/ Log: Fix: must do this step after the GC was annotated. diff --git a/rpython/translator/c/genc.py b/rpython/translator/c/genc.py --- a/rpython/translator/c/genc.py +++ b/rpython/translator/c/genc.py @@ -143,8 +143,8 @@ self.getentrypointptr() # build the wrapper first # ^^ this is needed to make sure we see the no-GC wrapper function # calling the GC entrypoint function. - transformer = transform2.STMTransformer(self.translator) - transformer.transform() + stmtransformer = transform2.STMTransformer(self.translator) + stmtransformer.transform() gcpolicyclass = self.get_gcpolicyclass() @@ -157,7 +157,10 @@ thread_enabled=self.config.translation.thread, sandbox=self.config.translation.sandbox) self.db = db - + + if self.config.translation.stm: + stmtransformer.transform_after_gc() + # give the gc a chance to register interest in the start-up functions it # need (we call this for its side-effects of db.get()) list(db.gcpolicy.gc_startup_code()) diff --git a/rpython/translator/stm/threadlocalref.py b/rpython/translator/stm/threadlocalref.py --- a/rpython/translator/stm/threadlocalref.py +++ b/rpython/translator/stm/threadlocalref.py @@ -18,8 +18,6 @@ if (op.opname == 'stm_threadlocalref_set' or op.opname == 'stm_threadlocalref_get'): ids.add(op.args[0].value) - if len(ids) == 0: - return # ids = sorted(ids) fields = [('ptr%d' % id1, llmemory.Address) for id1 in ids] diff --git a/rpython/translator/stm/transform2.py b/rpython/translator/stm/transform2.py --- a/rpython/translator/stm/transform2.py +++ b/rpython/translator/stm/transform2.py @@ -7,13 +7,16 @@ def transform(self): assert not hasattr(self.translator, 'stm_transformation_applied') self.start_log() - self.transform_threadlocalref() self.transform_jit_driver() self.transform_write_barrier() self.transform_turn_inevitable() self.print_logs() self.translator.stm_transformation_applied = True + def transform_after_gc(self): + self.transform_threadlocalref() + self.print_logs_after_gc() + def transform_write_barrier(self): from rpython.translator.backendopt.writeanalyze import WriteAnalyzer from rpython.translator.stm.writebarrier import insert_stm_barrier @@ -46,3 +49,7 @@ def print_logs(self): from rpython.translator.c.support import log log.info("Software Transactional Memory transformation applied") + + def print_logs_after_gc(self): + from rpython.translator.c.support import log + log.info("Software Transactional Memory transformation-after-gc done") From noreply at buildbot.pypy.org Mon Feb 18 17:56:43 2013 From: noreply at buildbot.pypy.org (lwassermann) Date: Mon, 18 Feb 2013 17:56:43 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: implemented another test Message-ID: <20130218165643.09B551C009B@cobra.cs.uni-duesseldorf.de> Author: Lars Wassermann Branch: Changeset: r41:28cf97406d04 Date: 2013-02-18 17:55 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/28cf97406d04/ Log: implemented another test implemented bytecode 138 diff --git a/spyvm/interpreter.py b/spyvm/interpreter.py --- a/spyvm/interpreter.py +++ b/spyvm/interpreter.py @@ -370,14 +370,14 @@ # closure bytecodes def pushNewArrayPopIntoArray(self, interp): - popIntoArray, arraySize = splitter[1, 7](self.getbytecode()) + arraySize, popIntoArray = splitter[7, 1](self.getbytecode()) newArray = None - #if popIntoArray == 1: - # newArray = interp.space.wrap_list(self.pop_and_return_n(arraySize)) - #else: - # newArray = interp.space.w_Array.as_class_get_shadow(interp.space).new(arraySize) + if popIntoArray == 1: + newArray = interp.space.wrap_list(self.pop_and_return_n(arraySize)) + else: + newArray = interp.space.w_Array.as_class_get_shadow(interp.space).new(arraySize) self.push(newArray) - raise MissingBytecode("not yet implemented: pushNewArray") + # rraise MissingBytecode("not yet implemented: pushNewArray") def experimentalBytecode(self, interp): raise MissingBytecode("experimentalBytecode") diff --git a/spyvm/objspace.py b/spyvm/objspace.py --- a/spyvm/objspace.py +++ b/spyvm/objspace.py @@ -207,7 +207,7 @@ lstlen = len(lst_w) res = self.w_Array.as_class_get_shadow(self).new(lstlen) for i in range(lstlen): - res.storevarpointer(i, lst_w[i]) + res.atput0(self, i, lst_w[i]) return res def unwrap_int(self, w_value): diff --git a/spyvm/test/test_interpreter.py b/spyvm/test/test_interpreter.py --- a/spyvm/test/test_interpreter.py +++ b/spyvm/test/test_interpreter.py @@ -832,11 +832,21 @@ # Closure Bytecodes def test_bc_pushNewArrayPopIntoArray(bytecode=pushNewArrayPopIntoArray): - py.test.skip("Fails, since pushNewArrayPopIntoArray is not yet implemented") interp = new_interpreter(bytecode + chr(0x83)) context = interp.s_active_context() - context.push(fakeliterals("egg")) - context.push(fakeliterals("bar")) - context.push(fakeliterals("baz")) + context.push(fakeliterals(space, "egg")) + context.push(fakeliterals(space, "bar")) + context.push(fakeliterals(space, "baz")) interp.step(interp.s_active_context()) - assert context.pop() == fakeliterals(["egg", "bar", "baz"]) \ No newline at end of file + array = context.pop() + assert array.at0(space, 0) == fakeliterals(space, "egg") + assert array.at0(space, 1) == fakeliterals(space, "bar") + assert array.at0(space, 2) == fakeliterals(space, "baz") + +def test_bc_pushNewArray(bytecode=pushNewArrayPopIntoArray): + interp = new_interpreter(bytecode + chr(0x07)) + context = interp.s_active_context() + interp.step(interp.s_active_context()) + array = context.pop() + assert array.size() == 7 + assert array.at0(space, 0) == space.w_nil From noreply at buildbot.pypy.org Mon Feb 18 18:23:27 2013 From: noreply at buildbot.pypy.org (timfel) Date: Mon, 18 Feb 2013 18:23:27 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: (timfel, cfbolz) add literalsize and tempsize shadowing, those are needed in contexts as well Message-ID: <20130218172327.753F91C009B@cobra.cs.uni-duesseldorf.de> Author: Tim Felgentreff Branch: Changeset: r42:cf8c1d976548 Date: 2013-02-18 16:28 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/cf8c1d976548/ Log: (timfel, cfbolz) add literalsize and tempsize shadowing, those are needed in contexts as well diff --git a/spyvm/model.py b/spyvm/model.py --- a/spyvm/model.py +++ b/spyvm/model.py @@ -539,6 +539,9 @@ def size(self): return self.headersize() + self.getliteralsize() + len(self.bytes) + def gettempsize(self): + return self.tempsize + def getliteralsize(self): return self.literalsize * constants.BYTES_PER_WORD diff --git a/spyvm/shadow.py b/spyvm/shadow.py --- a/spyvm/shadow.py +++ b/spyvm/shadow.py @@ -714,3 +714,5 @@ self.bytecode = "".join(w_compiledmethod.bytes) self.literals = w_compiledmethod.literals self.bytecodeoffset = w_compiledmethod.bytecodeoffset() + self.literalsize = w_compiledmethod.getliteralsize() + self.tempsize = w_compiledmethod.gettempsize() diff --git a/spyvm/test/test_shadow.py b/spyvm/test/test_shadow.py --- a/spyvm/test/test_shadow.py +++ b/spyvm/test/test_shadow.py @@ -184,13 +184,15 @@ def test_compiledmethodshadow(): from test_model import joinbits - header = joinbits([0,2,0,0,0,0],[9,8,1,6,4,1]) + header = joinbits([0,2,0,1,0,0],[9,8,1,6,4,1]) w_compiledmethod = model.W_CompiledMethod(3, header) w_compiledmethod.setbytes(list("abc")) shadow = w_compiledmethod.as_compiledmethod_get_shadow(space) assert shadow.bytecode == "abc" assert shadow.bytecodeoffset == 12 + assert shadow.literalsize == 8 # 12 - 4byte header + assert shadow.tempsize == 1 w_compiledmethod.literalatput0(space, 1, 17) w_compiledmethod.literalatput0(space, 2, 41) From noreply at buildbot.pypy.org Mon Feb 18 18:23:28 2013 From: noreply at buildbot.pypy.org (timfel) Date: Mon, 18 Feb 2013 18:23:28 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: use method shadow in context Message-ID: <20130218172328.854EE1C009B@cobra.cs.uni-duesseldorf.de> Author: Tim Felgentreff Branch: Changeset: r43:233e9c89fee7 Date: 2013-02-18 16:35 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/233e9c89fee7/ Log: use method shadow in context diff --git a/spyvm/shadow.py b/spyvm/shadow.py --- a/spyvm/shadow.py +++ b/spyvm/shadow.py @@ -419,14 +419,14 @@ if w_pc.is_same_object(self.space.w_nil): return pc = self.space.unwrap_int(w_pc) - pc -= self.w_method().bytecodeoffset() + pc -= self.method().bytecodeoffset pc -= 1 self.store_pc(pc) def wrap_pc(self): pc = self.pc() pc += 1 - pc += self.w_method().bytecodeoffset() + pc += self.method().bytecodeoffset return self.space.wrap_int(pc) def pc(self): @@ -444,10 +444,15 @@ def w_method(self): return self.s_home().w_method() + def method(self): + methodshadow = self.w_method().as_compiledmethod_get_shadow(self.space) + jit.promote(methodshadow) + return methodshadow + def getbytecode(self): jit.promote(self._pc) assert self._pc >= 0 - bytecode = self.w_method().bytes[self._pc] + bytecode = self.method().bytecode[self._pc] currentBytecode = ord(bytecode) self._pc += 1 return currentBytecode @@ -556,12 +561,12 @@ def unwrap_store_initialip(self, w_value): initialip = self.space.unwrap_int(w_value) - initialip -= 1 + self.w_method().getliteralsize() + initialip -= 1 + self.method().literalsize self.store_initialip(initialip) def wrap_initialip(self): initialip = self.initialip() - initialip += 1 + self.w_method().getliteralsize() + initialip += 1 + self.method().literalsize return self.space.wrap_int(initialip) def unwrap_store_eargc(self, w_value): @@ -670,7 +675,7 @@ ContextPartShadow.attach_shadow(self) def tempsize(self): - return self.w_method().tempsize + return self.method().tempsize def w_method(self): return self._w_method From noreply at buildbot.pypy.org Mon Feb 18 18:23:29 2013 From: noreply at buildbot.pypy.org (timfel) Date: Mon, 18 Feb 2013 18:23:29 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: (cfbolz, timfel) _shadow as class-level default, and clear on become Message-ID: <20130218172329.9418E1C009B@cobra.cs.uni-duesseldorf.de> Author: Tim Felgentreff Branch: Changeset: r44:2152a48cecb5 Date: 2013-02-18 16:41 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/2152a48cecb5/ Log: (cfbolz, timfel) _shadow as class-level default, and clear on become diff --git a/spyvm/model.py b/spyvm/model.py --- a/spyvm/model.py +++ b/spyvm/model.py @@ -461,10 +461,11 @@ ### variables. The number of bytes used for this purpose is the value of ### the last byte in the method. + _shadow = None + def __init__(self, bytecount=0, header=0): self.setheader(header) self.bytes = ["\x00"] * bytecount - self._shadow = None def become(self, w_other): if not isinstance(w_other, W_CompiledMethod): @@ -478,6 +479,7 @@ self.literalsize, w_other.literalsize = w_other.literalsize, self.literalsize self.w_compiledin, w_other.w_compiledin = w_other.w_compiledin, self.w_compiledin self.islarge, w_other.islarge = w_other.islarge, self.islarge + self._shadow = w_other._shadow = None W_AbstractObjectWithIdentityHash._become(self, w_other) return True From noreply at buildbot.pypy.org Mon Feb 18 18:23:30 2013 From: noreply at buildbot.pypy.org (timfel) Date: Mon, 18 Feb 2013 18:23:30 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: (timfel, cfbolz) immutability and promotes for method shadows Message-ID: <20130218172330.A01E41C009B@cobra.cs.uni-duesseldorf.de> Author: Tim Felgentreff Branch: Changeset: r45:420d5621ee9e Date: 2013-02-18 16:56 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/420d5621ee9e/ Log: (timfel, cfbolz) immutability and promotes for method shadows diff --git a/spyvm/model.py b/spyvm/model.py --- a/spyvm/model.py +++ b/spyvm/model.py @@ -451,6 +451,7 @@ bytecodes (variable) """ + _immutable_fields_ = ["_shadow?"] ### Extension from Squeak 3.9 doc, which we do not implement: ### trailer (variable) ### The trailer has two variant formats. In the first variant, the last diff --git a/spyvm/shadow.py b/spyvm/shadow.py --- a/spyvm/shadow.py +++ b/spyvm/shadow.py @@ -445,9 +445,10 @@ return self.s_home().w_method() def method(self): - methodshadow = self.w_method().as_compiledmethod_get_shadow(self.space) - jit.promote(methodshadow) - return methodshadow + w_method = jit.promote(self.w_method()) + return jit.promote( + w_method.as_compiledmethod_get_shadow(self.space) + ) def getbytecode(self): jit.promote(self._pc) @@ -714,8 +715,9 @@ class CompiledMethodShadow(object): + _immutable_fields_ = ["bytecode", "literals[*]", "bytecodeoffset", "literalsize", "tempsize"] + def __init__(self, w_compiledmethod): - self.w_compiledmethod = w_compiledmethod self.bytecode = "".join(w_compiledmethod.bytes) self.literals = w_compiledmethod.literals self.bytecodeoffset = w_compiledmethod.bytecodeoffset() From noreply at buildbot.pypy.org Mon Feb 18 18:23:31 2013 From: noreply at buildbot.pypy.org (timfel) Date: Mon, 18 Feb 2013 18:23:31 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: (timfel, cfbolz) change all uses of w_method to use the method shadow Message-ID: <20130218172331.B19921C009B@cobra.cs.uni-duesseldorf.de> Author: Tim Felgentreff Branch: Changeset: r46:871be2673edf Date: 2013-02-18 18:00 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/871be2673edf/ Log: (timfel, cfbolz) change all uses of w_method to use the method shadow diff --git a/spyvm/interpreter.py b/spyvm/interpreter.py --- a/spyvm/interpreter.py +++ b/spyvm/interpreter.py @@ -15,8 +15,8 @@ class IllegalStoreError(Exception): """Illegal Store.""" -def get_printable_location(pc, self, w_method): - bc = ord(w_method.bytes[pc]) +def get_printable_location(pc, self, method): + bc = ord(method.bytecode[pc]) return '%d: [%s]%s' % (pc, hex(bc), BYTECODE_NAMES[bc]) @@ -26,7 +26,7 @@ cnt = 0 _last_indent = "" jit_driver = jit.JitDriver( - greens=['pc', 'self', 'w_method'], + greens=['pc', 'self', 'method'], reds=['s_active_context'], get_printable_location=get_printable_location ) @@ -93,10 +93,10 @@ while True: s_active_context = self.s_active_context() pc = s_active_context._pc - w_method = s_active_context.w_method() + method = s_active_context.method() self.jit_driver.jit_merge_point( - pc=pc, self=self, w_method=w_method, + pc=pc, self=self, method=method, s_active_context=s_active_context) self.step(s_active_context) @@ -141,14 +141,14 @@ def pushLiteralConstantBytecode(self, interp): index = self.currentBytecode & 31 - self.push(self.w_method().getliteral(index)) + self.push(self.method().getliteral(index)) def pushLiteralVariableBytecode(self, interp): # this bytecode assumes that literals[index] is an Association # which is an object with two named vars, and fetches the second # named var (the value). index = self.currentBytecode & 31 - w_association = self.w_method().getliteral(index) + w_association = self.method().getliteral(index) association = wrapper.AssociationWrapper(self.space, w_association) self.push(association.value()) @@ -193,7 +193,7 @@ # send, return bytecodes def sendLiteralSelectorBytecode(self, interp): - selector = self.w_method().getliteralsymbol(self.currentBytecode & 15) + selector = self.method().getliteralsymbol(self.currentBytecode & 15) argcount = ((self.currentBytecode >> 4) & 3) - 1 self._sendSelfSelector(selector, argcount, interp) @@ -203,7 +203,7 @@ receiver, receiver.shadow_of_my_class(self.space)) def _sendSuperSelector(self, selector, argcount, interp): - w_compiledin = self.w_method().compiledin() + w_compiledin = self.method().w_compiledin assert isinstance(w_compiledin, model.W_PointersObject) s_compiledin = w_compiledin.as_class_get_shadow(self.space) self._sendSelector(selector, argcount, interp, self.w_receiver(), @@ -289,9 +289,9 @@ elif variableType == 1: self.push(self.gettemp(variableIndex)) elif variableType == 2: - self.push(self.w_method().getliteral(variableIndex)) + self.push(self.method().getliteral(variableIndex)) elif variableType == 3: - w_association = self.w_method().getliteral(variableIndex) + w_association = self.method().getliteral(variableIndex) association = wrapper.AssociationWrapper(self.space, w_association) self.push(association.value()) else: @@ -306,7 +306,7 @@ elif variableType == 2: raise IllegalStoreError elif variableType == 3: - w_association = self.w_method().getliteral(variableIndex) + w_association = self.method().getliteral(variableIndex) association = wrapper.AssociationWrapper(self.space, w_association) association.store_value(self.top()) @@ -316,7 +316,7 @@ def getExtendedSelectorArgcount(self): descriptor = self.getbytecode() - return ((self.w_method().getliteralsymbol(descriptor & 31)), + return ((self.method().getliteralsymbol(descriptor & 31)), (descriptor >> 5)) def singleExtendedSendBytecode(self, interp): @@ -329,21 +329,21 @@ opType = second >> 5 if opType == 0: # selfsend - self._sendSelfSelector(self.w_method().getliteralsymbol(third), + self._sendSelfSelector(self.method().getliteralsymbol(third), second & 31, interp) elif opType == 1: # supersend - self._sendSuperSelector(self.w_method().getliteralsymbol(third), + self._sendSuperSelector(self.method().getliteralsymbol(third), second & 31, interp) elif opType == 2: # pushReceiver self.push(self.w_receiver().fetch(self.space, third)) elif opType == 3: # pushLiteralConstant - self.push(self.w_method().getliteral(third)) + self.push(self.method().getliteral(third)) elif opType == 4: # pushLiteralVariable - w_association = self.w_method().getliteral(third) + w_association = self.method().getliteral(third) association = wrapper.AssociationWrapper(self.space, w_association) self.push(association.value()) elif opType == 5: @@ -351,7 +351,7 @@ elif opType == 6: self.w_receiver().store(self.space, third, self.pop()) elif opType == 7: - w_association = self.w_method().getliteral(third) + w_association = self.method().getliteral(third) association = wrapper.AssociationWrapper(self.space, w_association) association.store_value(self.top()) @@ -361,7 +361,7 @@ def secondExtendedSendBytecode(self, interp): descriptor = self.getbytecode() - selector = self.w_method().getliteralsymbol(descriptor & 63) + selector = self.method().getliteralsymbol(descriptor & 63) argcount = descriptor >> 6 self._sendSelfSelector(selector, argcount, interp) diff --git a/spyvm/model.py b/spyvm/model.py --- a/spyvm/model.py +++ b/spyvm/model.py @@ -478,38 +478,14 @@ self.bytes, w_other.bytes = w_other.bytes, self.bytes self.header, w_other.header = w_other.header, self.header self.literalsize, w_other.literalsize = w_other.literalsize, self.literalsize - self.w_compiledin, w_other.w_compiledin = w_other.w_compiledin, self.w_compiledin self.islarge, w_other.islarge = w_other.islarge, self.islarge self._shadow = w_other._shadow = None W_AbstractObjectWithIdentityHash._become(self, w_other) return True - def compiledin(self): - if self.w_compiledin is None: - from spyvm import wrapper - # (Blue book, p 607) All CompiledMethods that contain - # extended-super bytecodes have the clain which they are found as - # their last literal variable. - # Last of the literals is an association with compiledin - # as a class - w_association = self.literals[-1] - # XXX XXX XXX where to get a space from here - association = wrapper.AssociationWrapper(None, w_association) - self.w_compiledin = association.value() - return self.w_compiledin - def getclass(self, space): return space.w_CompiledMethod - def getliteral(self, index): - # We changed this part - return self.literals[index] #+ constants.LITERAL_START] - - def getliteralsymbol(self, index): - w_literal = self.getliteral(index) - assert isinstance(w_literal, W_BytesObject) - return w_literal.as_string() # XXX performance issue here - def create_frame(self, space, receiver, arguments, sender = None): from spyvm import shadow assert len(arguments) == self.argsize @@ -578,9 +554,14 @@ self.tempsize = tempsize assert self.tempsize >= self.argsize self.primitive = primitive - self.w_compiledin = None self.islarge = islarge + def setliterals(self, literals): + """NOT RPYTHON + Only for testing""" + self.literals = literals + self._shadow = None + def setbytes(self, bytes): self.bytes = bytes diff --git a/spyvm/shadow.py b/spyvm/shadow.py --- a/spyvm/shadow.py +++ b/spyvm/shadow.py @@ -1,5 +1,5 @@ import weakref -from spyvm import model, constants, error +from spyvm import model, constants, error, wrapper from rpython.tool.pairtype import extendabletype from rpython.rlib import rarithmetic, jit @@ -249,11 +249,12 @@ self.w_methoddict._store(1, model.W_PointersObject(None, 0)) self.s_methoddict().invalid = False - def installmethod(self, selector, method): + def installmethod(self, selector, w_method): "NOT_RPYTHON" # this is only for testing. self.initialize_methoddict() - self.s_methoddict().methoddict[selector] = method - if isinstance(method, model.W_CompiledMethod): + self.s_methoddict().methoddict[selector] = w_method + if isinstance(w_method, model.W_CompiledMethod): + method = w_method.as_compiledmethod_get_shadow(self.space) method.w_compiledin = self.w_self() class MethodDictionaryShadow(AbstractCachingShadow): @@ -715,7 +716,8 @@ class CompiledMethodShadow(object): - _immutable_fields_ = ["bytecode", "literals[*]", "bytecodeoffset", "literalsize", "tempsize"] + _immutable_fields_ = ["bytecode", "literals[*]", "bytecodeoffset", + "literalsize", "tempsize", "w_compiledin"] def __init__(self, w_compiledmethod): self.bytecode = "".join(w_compiledmethod.bytes) @@ -723,3 +725,24 @@ self.bytecodeoffset = w_compiledmethod.bytecodeoffset() self.literalsize = w_compiledmethod.getliteralsize() self.tempsize = w_compiledmethod.gettempsize() + + self.w_compiledin = None + if self.literals: + # (Blue book, p 607) All CompiledMethods that contain + # extended-super bytecodes have the clain which they are found as + # their last literal variable. + # Last of the literals is an association with compiledin + # as a class + w_association = self.literals[-1] + if isinstance(w_association, model.W_PointersObject) and w_association.size() >= 2: + # XXX XXX XXX where to get a space from here + association = wrapper.AssociationWrapper(None, w_association) + self.w_compiledin = association.value() + + def getliteral(self, index): + return self.literals[index] + + def getliteralsymbol(self, index): + w_literal = self.getliteral(index) + assert isinstance(w_literal, model.W_BytesObject) + return w_literal.as_string() # XXX performance issue here diff --git a/spyvm/test/test_interpreter.py b/spyvm/test/test_interpreter.py --- a/spyvm/test/test_interpreter.py +++ b/spyvm/test/test_interpreter.py @@ -32,7 +32,7 @@ s_class = w_class.as_class_get_shadow(space) prim_meth = model.W_CompiledMethod(0) prim_meth.primitive = primnum - prim_meth.w_compiledin = w_class + # prim_meth.w_compiledin = w_class prim_meth.argsize = argsize s_class.installmethod(methname, prim_meth) @@ -75,6 +75,7 @@ w_method.bytes = bytes w_method.argsize=2 w_method.tempsize=8 + w_method.setliterals([model.W_PointersObject(None, 2)]) w_frame = w_method.create_frame(space, receiver, ["foo", "bar"]) interp = interpreter.Interpreter(space) interp.store_w_active_context(w_frame) @@ -151,7 +152,7 @@ pushLiteralConstantBytecode(1) + pushLiteralConstantBytecode(2)): interp = new_interpreter(bytecode) - interp.w_active_context().as_methodcontext_get_shadow(space).w_method().literals = fakeliterals(space, "a", "b", "c") + interp.w_active_context().as_methodcontext_get_shadow(space).w_method().setliterals(fakeliterals(space, "a", "b", "c")) interp.step(interp.s_active_context()) interp.step(interp.s_active_context()) interp.step(interp.s_active_context()) @@ -164,7 +165,7 @@ w_association.store(space, 0, "mykey") w_association.store(space, 1, "myvalue") interp = new_interpreter(bytecode) - interp.w_active_context().as_methodcontext_get_shadow(space).w_method().literals = fakeliterals(space, w_association) + interp.w_active_context().as_methodcontext_get_shadow(space).w_method().setliterals( fakeliterals(space, w_association)) interp.step(interp.s_active_context()) assert interp.s_active_context().stack() == ["myvalue"] @@ -401,7 +402,7 @@ w_method.bytes = pushConstantOneBytecode + bytecode shadow.installmethod("foo", w_method) interp = new_interpreter(bytecodes) - interp.w_active_context().as_methodcontext_get_shadow(space).w_method().literals = fakeliterals(space, "foo") + interp.w_active_context().as_methodcontext_get_shadow(space).w_method().setliterals(fakeliterals(space, "foo")) interp.s_active_context().push(w_object) callerContext = interp.w_active_context() interp.step(interp.s_active_context()) @@ -428,11 +429,11 @@ method.bytes = bytecode method.argsize = 1 method.tempsize = 1 - method.literals = fakeliterals(space, "fib:") + method.setliterals(fakeliterals(space, "fib:")) shadow.installmethod("fib:", method) w_object = shadow.new() interp = new_interpreter(sendLiteralSelectorBytecode(16) + returnTopFromMethod) - interp.w_active_context().as_methodcontext_get_shadow(space).w_method().literals = fakeliterals(space, "fib:") + interp.w_active_context().as_methodcontext_get_shadow(space).w_method().setliterals(fakeliterals(space, "fib:")) interp.s_active_context().push(w_object) interp.s_active_context().push(space.wrap_int(8)) result = interp.interpret() @@ -442,7 +443,7 @@ def test(): interp = new_interpreter(sendLiteralSelectorBytecode(1 + 16)) - interp.w_active_context().as_methodcontext_get_shadow(space).w_method().literals = fakeliterals(space, "foo", "sub") + interp.w_active_context().as_methodcontext_get_shadow(space).w_method().setliterals(fakeliterals(space, "foo", "sub")) interp.s_active_context().push(space.wrap_int(50)) interp.s_active_context().push(space.wrap_int(8)) callerContext = interp.w_active_context() @@ -545,7 +546,7 @@ w_association.store(space, 0, "mykey") w_association.store(space, 1, "myvalue") interp = new_interpreter(pushConstantOneBytecode + bytecode) - interp.w_active_context().as_methodcontext_get_shadow(space).w_method().literals = fakeliterals(space, w_association) + interp.w_active_context().as_methodcontext_get_shadow(space).w_method().setliterals(fakeliterals(space, w_association)) interp.step(interp.s_active_context()) interp.step(interp.s_active_context()) assert w_association.fetch(space, 1).is_same_object(space.w_one) @@ -609,17 +610,17 @@ # which does a call to its super meth1 = model.W_CompiledMethod(2) meth1.bytes = pushReceiverBytecode + bytecode + meth1.setliterals(fakeliterals(space, "foo")) w_class.as_class_get_shadow(space).installmethod("foo", meth1) # and that one again to its super meth2 = model.W_CompiledMethod(2) meth2.bytes = pushReceiverBytecode + bytecode + meth2.setliterals(fakeliterals(space, "foo")) w_super.as_class_get_shadow(space).installmethod("foo", meth2) meth3 = model.W_CompiledMethod(0) w_supersuper.as_class_get_shadow(space).installmethod("foo", meth3) - meth1.literals = fakeliterals(space, "foo") - meth2.literals = fakeliterals(space, "foo") interp = new_interpreter(bytecodes) - interp.w_active_context().as_methodcontext_get_shadow(space).w_method().literals = fakeliterals(space, "foo") + interp.w_active_context().as_methodcontext_get_shadow(space).w_method().setliterals(fakeliterals(space, "foo")) interp.s_active_context().push(w_object) interp.step(interp.s_active_context()) for w_specificclass in [w_super, w_supersuper]: @@ -665,7 +666,7 @@ def interpret_bc(bcodes, literals, receiver=space.w_nil): bcode = "".join([chr(x) for x in bcodes]) interp = new_interpreter(bcode, receiver=receiver) - interp.w_active_context().as_methodcontext_get_shadow(space).w_method().literals = literals + interp.w_active_context().as_methodcontext_get_shadow(space).w_method().setliterals(literals) return interp.interpret() # tests: bytecodePrimValue & bytecodePrimValueWithArg @@ -804,7 +805,7 @@ # ^ self objectAt: 2 put: 3. changes the first literal to 3 # ^ self objectAt: 2. yields the new first literal (3) prim_meth = model.W_CompiledMethod(header=1024) - prim_meth.literals = fakeliterals(space, 22) + prim_meth.setliterals(fakeliterals(space, 22)) oal = fakeliterals(space, "objectAt:") oalp = fakeliterals(space, "objectAt:put:", 3) def test(): @@ -839,4 +840,4 @@ context.push(fakeliterals("bar")) context.push(fakeliterals("baz")) interp.step(interp.s_active_context()) - assert context.pop() == fakeliterals(["egg", "bar", "baz"]) \ No newline at end of file + assert context.pop() == fakeliterals(["egg", "bar", "baz"]) diff --git a/spyvm/test/test_model.py b/spyvm/test/test_model.py --- a/spyvm/test/test_model.py +++ b/spyvm/test/test_model.py @@ -81,7 +81,7 @@ supershadow.installmethod("foo", model.W_CompiledMethod(0)) classshadow = w_class.as_class_get_shadow(space) classshadow.initialize_methoddict() - assert classshadow.lookup("foo").w_compiledin is w_super + assert classshadow.lookup("foo").as_compiledmethod_get_shadow(space).w_compiledin is w_super def test_compiledmethod_setchar(): w_method = model.W_CompiledMethod(3) @@ -103,7 +103,7 @@ w_method = model.W_CompiledMethod() w_method.bytes = list("abc") w_method.header = 100 - w_method.literals = [ 'lit1', 'lit2' ] + w_method.setliterals(['lit1', 'lit2']) w_method.literalsize = 2 assert space.unwrap_int(w_method.at0(space, 0)) == 100 assert w_method.at0(space, 4) == 'lit1' From noreply at buildbot.pypy.org Mon Feb 18 18:23:32 2013 From: noreply at buildbot.pypy.org (timfel) Date: Mon, 18 Feb 2013 18:23:32 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: (timfel, cfbolz) remove useless statement Message-ID: <20130218172332.BEEB41C009B@cobra.cs.uni-duesseldorf.de> Author: Tim Felgentreff Branch: Changeset: r47:01a0d25813f9 Date: 2013-02-18 18:01 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/01a0d25813f9/ Log: (timfel, cfbolz) remove useless statement diff --git a/spyvm/test/test_interpreter.py b/spyvm/test/test_interpreter.py --- a/spyvm/test/test_interpreter.py +++ b/spyvm/test/test_interpreter.py @@ -32,7 +32,6 @@ s_class = w_class.as_class_get_shadow(space) prim_meth = model.W_CompiledMethod(0) prim_meth.primitive = primnum - # prim_meth.w_compiledin = w_class prim_meth.argsize = argsize s_class.installmethod(methname, prim_meth) From noreply at buildbot.pypy.org Mon Feb 18 18:23:33 2013 From: noreply at buildbot.pypy.org (timfel) Date: Mon, 18 Feb 2013 18:23:33 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: Revert adding BlockClosures to constants.py, because it breaks the tests Message-ID: <20130218172333.C22151C009B@cobra.cs.uni-duesseldorf.de> Author: Tim Felgentreff Branch: Changeset: r48:4e928992b598 Date: 2013-02-18 18:02 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/4e928992b598/ Log: Revert adding BlockClosures to constants.py, because it breaks the tests diff --git a/spyvm/constants.py b/spyvm/constants.py --- a/spyvm/constants.py +++ b/spyvm/constants.py @@ -104,7 +104,7 @@ "Float" : SO_FLOAT_CLASS, "MethodContext" : SO_METHODCONTEXT_CLASS, "BlockContext" : SO_BLOCKCONTEXT_CLASS, - "BlockClosure" : SO_BLOCKCLOSURE_CLASS, + # "BlockClosure" : SO_BLOCKCLOSURE_CLASS, "Point" : SO_POINT_CLASS, "LargePositiveInteger" : SO_LARGEPOSITIVEINTEGER_CLASS, # "Display" : SO_DISPLAY_CLASS, From noreply at buildbot.pypy.org Mon Feb 18 18:23:34 2013 From: noreply at buildbot.pypy.org (timfel) Date: Mon, 18 Feb 2013 18:23:34 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: (timfel, cfbolz) add literalsize and tempsize shadowing, those are needed in contexts as well Message-ID: <20130218172334.C0E551C009B@cobra.cs.uni-duesseldorf.de> Author: Tim Felgentreff Branch: Changeset: r49:15f6ac6c1189 Date: 2013-02-18 16:28 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/15f6ac6c1189/ Log: (timfel, cfbolz) add literalsize and tempsize shadowing, those are needed in contexts as well diff --git a/spyvm/model.py b/spyvm/model.py --- a/spyvm/model.py +++ b/spyvm/model.py @@ -539,6 +539,9 @@ def size(self): return self.headersize() + self.getliteralsize() + len(self.bytes) + def gettempsize(self): + return self.tempsize + def getliteralsize(self): return self.literalsize * constants.BYTES_PER_WORD diff --git a/spyvm/shadow.py b/spyvm/shadow.py --- a/spyvm/shadow.py +++ b/spyvm/shadow.py @@ -714,3 +714,5 @@ self.bytecode = "".join(w_compiledmethod.bytes) self.literals = w_compiledmethod.literals self.bytecodeoffset = w_compiledmethod.bytecodeoffset() + self.literalsize = w_compiledmethod.getliteralsize() + self.tempsize = w_compiledmethod.gettempsize() diff --git a/spyvm/test/test_shadow.py b/spyvm/test/test_shadow.py --- a/spyvm/test/test_shadow.py +++ b/spyvm/test/test_shadow.py @@ -184,13 +184,15 @@ def test_compiledmethodshadow(): from test_model import joinbits - header = joinbits([0,2,0,0,0,0],[9,8,1,6,4,1]) + header = joinbits([0,2,0,1,0,0],[9,8,1,6,4,1]) w_compiledmethod = model.W_CompiledMethod(3, header) w_compiledmethod.setbytes(list("abc")) shadow = w_compiledmethod.as_compiledmethod_get_shadow(space) assert shadow.bytecode == "abc" assert shadow.bytecodeoffset == 12 + assert shadow.literalsize == 8 # 12 - 4byte header + assert shadow.tempsize == 1 w_compiledmethod.literalatput0(space, 1, 17) w_compiledmethod.literalatput0(space, 2, 41) From noreply at buildbot.pypy.org Mon Feb 18 18:23:35 2013 From: noreply at buildbot.pypy.org (timfel) Date: Mon, 18 Feb 2013 18:23:35 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: use method shadow in context Message-ID: <20130218172335.C28C91C009B@cobra.cs.uni-duesseldorf.de> Author: Tim Felgentreff Branch: Changeset: r50:253b43e4abba Date: 2013-02-18 16:35 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/253b43e4abba/ Log: use method shadow in context diff --git a/spyvm/shadow.py b/spyvm/shadow.py --- a/spyvm/shadow.py +++ b/spyvm/shadow.py @@ -419,14 +419,14 @@ if w_pc.is_same_object(self.space.w_nil): return pc = self.space.unwrap_int(w_pc) - pc -= self.w_method().bytecodeoffset() + pc -= self.method().bytecodeoffset pc -= 1 self.store_pc(pc) def wrap_pc(self): pc = self.pc() pc += 1 - pc += self.w_method().bytecodeoffset() + pc += self.method().bytecodeoffset return self.space.wrap_int(pc) def pc(self): @@ -444,10 +444,15 @@ def w_method(self): return self.s_home().w_method() + def method(self): + methodshadow = self.w_method().as_compiledmethod_get_shadow(self.space) + jit.promote(methodshadow) + return methodshadow + def getbytecode(self): jit.promote(self._pc) assert self._pc >= 0 - bytecode = self.w_method().bytes[self._pc] + bytecode = self.method().bytecode[self._pc] currentBytecode = ord(bytecode) self._pc += 1 return currentBytecode @@ -556,12 +561,12 @@ def unwrap_store_initialip(self, w_value): initialip = self.space.unwrap_int(w_value) - initialip -= 1 + self.w_method().getliteralsize() + initialip -= 1 + self.method().literalsize self.store_initialip(initialip) def wrap_initialip(self): initialip = self.initialip() - initialip += 1 + self.w_method().getliteralsize() + initialip += 1 + self.method().literalsize return self.space.wrap_int(initialip) def unwrap_store_eargc(self, w_value): @@ -670,7 +675,7 @@ ContextPartShadow.attach_shadow(self) def tempsize(self): - return self.w_method().tempsize + return self.method().tempsize def w_method(self): return self._w_method From noreply at buildbot.pypy.org Mon Feb 18 18:23:36 2013 From: noreply at buildbot.pypy.org (timfel) Date: Mon, 18 Feb 2013 18:23:36 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: (cfbolz, timfel) _shadow as class-level default, and clear on become Message-ID: <20130218172336.D47351C009B@cobra.cs.uni-duesseldorf.de> Author: Tim Felgentreff Branch: Changeset: r51:b161fd148144 Date: 2013-02-18 16:41 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/b161fd148144/ Log: (cfbolz, timfel) _shadow as class-level default, and clear on become diff --git a/spyvm/model.py b/spyvm/model.py --- a/spyvm/model.py +++ b/spyvm/model.py @@ -461,10 +461,11 @@ ### variables. The number of bytes used for this purpose is the value of ### the last byte in the method. + _shadow = None + def __init__(self, bytecount=0, header=0): self.setheader(header) self.bytes = ["\x00"] * bytecount - self._shadow = None def become(self, w_other): if not isinstance(w_other, W_CompiledMethod): @@ -478,6 +479,7 @@ self.literalsize, w_other.literalsize = w_other.literalsize, self.literalsize self.w_compiledin, w_other.w_compiledin = w_other.w_compiledin, self.w_compiledin self.islarge, w_other.islarge = w_other.islarge, self.islarge + self._shadow = w_other._shadow = None W_AbstractObjectWithIdentityHash._become(self, w_other) return True From noreply at buildbot.pypy.org Mon Feb 18 18:23:37 2013 From: noreply at buildbot.pypy.org (timfel) Date: Mon, 18 Feb 2013 18:23:37 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: (timfel, cfbolz) immutability and promotes for method shadows Message-ID: <20130218172337.F08C81C009B@cobra.cs.uni-duesseldorf.de> Author: Tim Felgentreff Branch: Changeset: r52:0edabe042679 Date: 2013-02-18 16:56 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/0edabe042679/ Log: (timfel, cfbolz) immutability and promotes for method shadows diff --git a/spyvm/model.py b/spyvm/model.py --- a/spyvm/model.py +++ b/spyvm/model.py @@ -451,6 +451,7 @@ bytecodes (variable) """ + _immutable_fields_ = ["_shadow?"] ### Extension from Squeak 3.9 doc, which we do not implement: ### trailer (variable) ### The trailer has two variant formats. In the first variant, the last diff --git a/spyvm/shadow.py b/spyvm/shadow.py --- a/spyvm/shadow.py +++ b/spyvm/shadow.py @@ -445,9 +445,10 @@ return self.s_home().w_method() def method(self): - methodshadow = self.w_method().as_compiledmethod_get_shadow(self.space) - jit.promote(methodshadow) - return methodshadow + w_method = jit.promote(self.w_method()) + return jit.promote( + w_method.as_compiledmethod_get_shadow(self.space) + ) def getbytecode(self): jit.promote(self._pc) @@ -714,8 +715,9 @@ class CompiledMethodShadow(object): + _immutable_fields_ = ["bytecode", "literals[*]", "bytecodeoffset", "literalsize", "tempsize"] + def __init__(self, w_compiledmethod): - self.w_compiledmethod = w_compiledmethod self.bytecode = "".join(w_compiledmethod.bytes) self.literals = w_compiledmethod.literals self.bytecodeoffset = w_compiledmethod.bytecodeoffset() From noreply at buildbot.pypy.org Mon Feb 18 18:23:39 2013 From: noreply at buildbot.pypy.org (timfel) Date: Mon, 18 Feb 2013 18:23:39 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: (lwassermann) implemented another test Message-ID: <20130218172339.15EA61C009B@cobra.cs.uni-duesseldorf.de> Author: Tim Felgentreff Branch: Changeset: r53:403b4d8766ca Date: 2013-02-18 18:17 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/403b4d8766ca/ Log: (lwassermann) implemented another test implemented bytecode 138 diff --git a/spyvm/interpreter.py b/spyvm/interpreter.py --- a/spyvm/interpreter.py +++ b/spyvm/interpreter.py @@ -370,14 +370,14 @@ # closure bytecodes def pushNewArrayPopIntoArray(self, interp): - popIntoArray, arraySize = splitter[1, 7](self.getbytecode()) + arraySize, popIntoArray = splitter[7, 1](self.getbytecode()) newArray = None - #if popIntoArray == 1: - # newArray = interp.space.wrap_list(self.pop_and_return_n(arraySize)) - #else: - # newArray = interp.space.w_Array.as_class_get_shadow(interp.space).new(arraySize) + if popIntoArray == 1: + newArray = interp.space.wrap_list(self.pop_and_return_n(arraySize)) + else: + newArray = interp.space.w_Array.as_class_get_shadow(interp.space).new(arraySize) self.push(newArray) - raise MissingBytecode("not yet implemented: pushNewArray") + # raise MissingBytecode("not yet implemented: pushNewArray") def experimentalBytecode(self, interp): raise MissingBytecode("experimentalBytecode") diff --git a/spyvm/objspace.py b/spyvm/objspace.py --- a/spyvm/objspace.py +++ b/spyvm/objspace.py @@ -207,7 +207,7 @@ lstlen = len(lst_w) res = self.w_Array.as_class_get_shadow(self).new(lstlen) for i in range(lstlen): - res.storevarpointer(i, lst_w[i]) + res.atput0(self, i, lst_w[i]) return res def unwrap_int(self, w_value): diff --git a/spyvm/test/test_interpreter.py b/spyvm/test/test_interpreter.py --- a/spyvm/test/test_interpreter.py +++ b/spyvm/test/test_interpreter.py @@ -832,11 +832,21 @@ # Closure Bytecodes def test_bc_pushNewArrayPopIntoArray(bytecode=pushNewArrayPopIntoArray): - py.test.skip("Fails, since pushNewArrayPopIntoArray is not yet implemented") interp = new_interpreter(bytecode + chr(0x83)) context = interp.s_active_context() - context.push(fakeliterals("egg")) - context.push(fakeliterals("bar")) - context.push(fakeliterals("baz")) + context.push(fakeliterals(space, "egg")) + context.push(fakeliterals(space, "bar")) + context.push(fakeliterals(space, "baz")) interp.step(interp.s_active_context()) - assert context.pop() == fakeliterals(["egg", "bar", "baz"]) + array = context.pop() + assert array.at0(space, 0) == fakeliterals(space, "egg") + assert array.at0(space, 1) == fakeliterals(space, "bar") + assert array.at0(space, 2) == fakeliterals(space, "baz") + +def test_bc_pushNewArray(bytecode=pushNewArrayPopIntoArray): + interp = new_interpreter(bytecode + chr(0x07)) + context = interp.s_active_context() + interp.step(interp.s_active_context()) + array = context.pop() + assert array.size() == 7 + assert array.at0(space, 0) == space.w_nil From noreply at buildbot.pypy.org Mon Feb 18 18:23:40 2013 From: noreply at buildbot.pypy.org (timfel) Date: Mon, 18 Feb 2013 18:23:40 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: merge Message-ID: <20130218172340.0EE511C009B@cobra.cs.uni-duesseldorf.de> Author: Tim Felgentreff Branch: Changeset: r54:4509f7b67327 Date: 2013-02-18 18:22 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/4509f7b67327/ Log: merge From noreply at buildbot.pypy.org Mon Feb 18 18:26:41 2013 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 18 Feb 2013 18:26:41 +0100 (CET) Subject: [pypy-commit] pypy default: Remove old code, seems to be unused. Message-ID: <20130218172641.983661C009B@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r61417:0dec0c3abbbf Date: 2013-02-18 18:26 +0100 http://bitbucket.org/pypy/pypy/changeset/0dec0c3abbbf/ Log: Remove old code, seems to be unused. diff --git a/rpython/rlib/test/test_timer.py b/rpython/rlib/test/test_timer.py deleted file mode 100644 --- a/rpython/rlib/test/test_timer.py +++ /dev/null @@ -1,26 +0,0 @@ -from rpython.rlib.timer import Timer -from rpython.translator.c.test.test_genc import compile -from rpython.annotator.policy import AnnotatorPolicy - - -t = Timer() -t.start("testc") -t.stop("testc") - -def timer_user(): - assert "testc" not in t.timingorder - t.start("testa") - t.stop("testa") - t.start("testb") - t.start("testb") - t.stop("testb") - t.stop("testb") - t.start_name("test", "one") - t.stop_name("test", "one") - t.dump() - - -def test_compile_timer(): - policy = AnnotatorPolicy() - f_compiled = compile(timer_user, [], annotatorpolicy=policy) - f_compiled() diff --git a/rpython/rlib/timer.py b/rpython/rlib/timer.py deleted file mode 100644 --- a/rpython/rlib/timer.py +++ /dev/null @@ -1,77 +0,0 @@ -import time -import os - - -def _create_name(name, generation): - if generation == 0: - return name - else: - return "%s[%s]" % (name, str(generation)) - - -class Timer: - def __init__(self): - self.reset() - - def reset(self): - self.timings = {} - self.levels = {} - self.timingorder = [] - - def _cleanup_(self): - self.reset() - - def start(self, timer): - level = self.levels.setdefault(timer, -1) - new_level = level + 1 - name = _create_name(timer, new_level) - if name not in self.timings: - self.timingorder.append(name) - self.timings[name] = time.time() - self.timings.get(name, 0) - self.levels[timer] = new_level - - def start_name(self, timerone, timertwo): - self.start(timerone + " " + timertwo) - - def stop(self, timer): - level = self.levels.setdefault(timer, -1) - if level == -1: - raise ValueError("Invalid timer name") - if level >= 0: # timer is active - name = _create_name(timer, level) - self.timings[name] = time.time() - self.timings[name] - self.levels[timer] = level - 1 - - def stop_name(self, timerone, timertwo): - self.stop(timerone + " " + timertwo) - - def value(self, timer): - level = self.levels.get(timer, -1) - if level == -1: - result = "%fs" % self.timings[timer] - else: - result = "%fs (still running)" % (time.time() - self.timings[timer]) - return result - - def dump(self): - outlist = [] - for timer in self.timingorder: - value = self.value(timer) - outlist.append("%s = %s" % (timer, value)) - os.write(2, "\n".join(outlist)) - - -class DummyTimer: - def start(self, timer): - pass - def start_name(self, timerone, timertwo): - pass - def stop(self, timer): - pass - def stop_name(self, timerone, timertwo): - pass - def value(self, timer): - return "Timing disabled" - def dump(self): - pass - From noreply at buildbot.pypy.org Mon Feb 18 18:59:56 2013 From: noreply at buildbot.pypy.org (fijal) Date: Mon, 18 Feb 2013 18:59:56 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: improve tests, failing my hypothesis Message-ID: <20130218175956.911211C0925@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61418:979be9fdde79 Date: 2013-02-18 19:54 +0200 http://bitbucket.org/pypy/pypy/changeset/979be9fdde79/ Log: improve tests, failing my hypothesis diff --git a/rpython/jit/backend/llsupport/test/test_gc.py b/rpython/jit/backend/llsupport/test/test_gc.py --- a/rpython/jit/backend/llsupport/test/test_gc.py +++ b/rpython/jit/backend/llsupport/test/test_gc.py @@ -272,15 +272,16 @@ jitframe.BASEITEMOFS + jitframe.SIGN_SIZE * no) frame_info = lltype.malloc(jitframe.JITFRAMEINFO, zero=True, flavor='raw') - frame = lltype.malloc(jitframe.JITFRAME, 100, zero=True) + frame = lltype.malloc(jitframe.JITFRAME, 200, zero=True) frame.jf_frame_info = frame_info - frame.jf_gcmap = lltype.malloc(jitframe.GCMAP, 2, flavor='raw') + frame.jf_gcmap = lltype.malloc(jitframe.GCMAP, 3, flavor='raw') if sys.maxint == 2**31 - 1: max = r_uint(2 ** 31) else: max = r_uint(2 ** 63) frame.jf_gcmap[0] = r_uint(1 | 2 | 8 | 32 | 128) | max - frame.jf_gcmap[1] = r_uint(2 | 16 | 32 | 128) + frame.jf_gcmap[1] = r_uint(0) + frame.jf_gcmap[2] = r_uint(2 | 16 | 32 | 128) frame_adr = llmemory.cast_ptr_to_adr(frame) all_addrs = [] next = jitframe.jitframe_trace(frame_adr, llmemory.NULL) @@ -301,10 +302,10 @@ assert all_addrs[8] == indexof(7) if sys.maxint == 2**31 - 1: assert all_addrs[9] == indexof(31) - assert all_addrs[10] == indexof(33) + assert all_addrs[10] == indexof(33 + 32) else: assert all_addrs[9] == indexof(63) - assert all_addrs[10] == indexof(65) + assert all_addrs[10] == indexof(65 + 64) assert len(all_addrs) == 4 + 6 + 4 # 4 static fields, 4 addresses from gcmap, 2 from gcpattern From noreply at buildbot.pypy.org Mon Feb 18 18:59:57 2013 From: noreply at buildbot.pypy.org (fijal) Date: Mon, 18 Feb 2013 18:59:57 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: failing test Message-ID: <20130218175957.CABDA1C0925@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61419:7b124068c882 Date: 2013-02-18 19:58 +0200 http://bitbucket.org/pypy/pypy/changeset/7b124068c882/ Log: failing test diff --git a/rpython/jit/backend/llsupport/test/test_gc.py b/rpython/jit/backend/llsupport/test/test_gc.py --- a/rpython/jit/backend/llsupport/test/test_gc.py +++ b/rpython/jit/backend/llsupport/test/test_gc.py @@ -274,7 +274,7 @@ frame_info = lltype.malloc(jitframe.JITFRAMEINFO, zero=True, flavor='raw') frame = lltype.malloc(jitframe.JITFRAME, 200, zero=True) frame.jf_frame_info = frame_info - frame.jf_gcmap = lltype.malloc(jitframe.GCMAP, 3, flavor='raw') + frame.jf_gcmap = lltype.malloc(jitframe.GCMAP, 4, flavor='raw') if sys.maxint == 2**31 - 1: max = r_uint(2 ** 31) else: @@ -282,6 +282,7 @@ frame.jf_gcmap[0] = r_uint(1 | 2 | 8 | 32 | 128) | max frame.jf_gcmap[1] = r_uint(0) frame.jf_gcmap[2] = r_uint(2 | 16 | 32 | 128) + frame.jf_gcmap[3] = r_uint(0) frame_adr = llmemory.cast_ptr_to_adr(frame) all_addrs = [] next = jitframe.jitframe_trace(frame_adr, llmemory.NULL) @@ -311,3 +312,19 @@ # 4 static fields, 4 addresses from gcmap, 2 from gcpattern lltype.free(frame_info, flavor='raw') lltype.free(frame.jf_gcmap, flavor='raw') + +def test_custom_tracer_2(): + frame_info = lltype.malloc(jitframe.JITFRAMEINFO, zero=True, flavor='raw') + frame = lltype.malloc(jitframe.JITFRAME, 200, zero=True) + frame.jf_frame_info = frame_info + frame.jf_gcmap = lltype.malloc(jitframe.GCMAP, 3, flavor='raw') + frame.jf_gcmap[0] = r_uint(18446744073441116160) + frame.jf_gcmap[1] = r_uint(18446740775107559407) + frame.jf_gcmap[2] = r_uint(3) + all_addrs = [] + frame_adr = llmemory.cast_ptr_to_adr(frame) + next = jitframe.jitframe_trace(frame_adr, llmemory.NULL) + while next: + all_addrs.append(next) + next = jitframe.jitframe_trace(frame_adr, next) + # assert did not hang From noreply at buildbot.pypy.org Mon Feb 18 18:59:59 2013 From: noreply at buildbot.pypy.org (fijal) Date: Mon, 18 Feb 2013 18:59:59 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: merge Message-ID: <20130218175959.1256F1C0925@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61420:ffbd43de45b5 Date: 2013-02-18 19:58 +0200 http://bitbucket.org/pypy/pypy/changeset/ffbd43de45b5/ Log: merge diff --git a/rpython/jit/backend/arm/assembler.py b/rpython/jit/backend/arm/assembler.py --- a/rpython/jit/backend/arm/assembler.py +++ b/rpython/jit/backend/arm/assembler.py @@ -201,23 +201,19 @@ self.propagate_exception_path = rawstart def _store_and_reset_exception(self, mc, resloc): - assert resloc is r.r0 + assert resloc is not r.ip + tmpreg = r.lr # use lr as a second temporary reg + mc.gen_load_int(r.ip.value, self.cpu.pos_exc_value()) + if resloc is not None: # store + self.load_reg(mc, resloc, r.ip, 0) - self.mc.gen_load_int(resloc.value, self.cpu.pos_exc_value()) - self.mc.gen_load_int(r.r0.value, self.cpu.pos_exc_value()) - self.mc.gen_load_int(r.ip.value, 0) - self.mc.STR_ri(r.ip.value, r.r0.value) - - - self.mc.LDR_ri(resloc.value, resloc.value) - self.mc.MOV(resloc, heap(self.cpu.pos_exc_value())) + # reset exception + mc.gen_load_int(tmpreg.value, 0) - with saved_registers(self.mc, [r.r0]): - self.mc.gen_load_int(r.r0.value, self.cpu.pos_exc_value()) - self.mc.gen_load_int(r.ip.value, 0) - self.mc.STR_ri(r.ip.value, r.r0.value) - self.mc.gen_load_int(r.r0.value, self.cpu.pos_exception()) - self.mc.STR_ri(r.ip.value, r.r0.value) + self.store_reg(mc, tmpreg, r.ip, 0) + + mc.gen_load_int(r.ip.value, self.cpu.pos_exception()) + self.store_reg(mc, tmpreg, r.ip, 0) def _build_stack_check_slowpath(self): _, _, slowpathaddr = self.cpu.insert_stack_check() diff --git a/rpython/jit/backend/arm/opassembler.py b/rpython/jit/backend/arm/opassembler.py --- a/rpython/jit/backend/arm/opassembler.py +++ b/rpython/jit/backend/arm/opassembler.py @@ -538,12 +538,7 @@ self.mc.CMP_rr(r.ip.value, loc.value) self._emit_guard(op, failargs, c.EQ, save_exc=True) - self.mc.gen_load_int(loc.value, pos_exc_value.value) - if resloc: - self.mc.LDR_ri(resloc.value, loc.value) - self.mc.MOV_ri(r.ip.value, 0) - self.mc.STR_ri(r.ip.value, loc.value) - self.mc.STR_ri(r.ip.value, loc1.value) + self._store_and_reset_exception(self.mc, resloc) return fcond def emit_op_debug_merge_point(self, op, arglocs, regalloc, fcond): diff --git a/rpython/jit/backend/arm/tool/viewcode.py b/rpython/jit/backend/arm/tool/viewcode.py deleted file mode 100755 --- a/rpython/jit/backend/arm/tool/viewcode.py +++ /dev/null @@ -1,88 +0,0 @@ -#!/usr/bin/env python -""" -Try: - ./viewcode.py file.asm - ./viewcode.py --decode dumpfile -""" -import os, sys, py -import subprocess - -def machine_code_dump(data, originaddr, backend_name, label_list=None): - objdump_backend_option = { - 'arm': 'arm', - 'arm_32': 'arm', - } - assert backend_name in objdump_backend_option - tmpfile = get_tmp_file() - objdump = 'objdump -M reg-names-std --adjust-vma=%(origin)d -D --architecture=arm --target=binary %(file)s' - # - f = open(tmpfile, 'wb') - f.write(data) - f.close() - p = subprocess.Popen(objdump % { - 'file': tmpfile, - 'origin': originaddr, - }, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) - stdout, stderr = p.communicate() - assert not p.returncode, ('Encountered an error running objdump: %s' % - stderr) - # drop some objdump cruft - lines = stdout.splitlines(True)[6:] # drop some objdump cruft - return format_code_dump_with_labels(originaddr, lines, label_list) - -def format_code_dump_with_labels(originaddr, lines, label_list): - from rpython.rlib.rarithmetic import r_uint - if not label_list: - label_list = [] - originaddr = r_uint(originaddr) - itlines = iter(lines) - yield itlines.next() # don't process the first line - for lbl_start, lbl_name in label_list: - for line in itlines: - addr, _ = line.split(':', 1) - addr = int(addr, 16) - if addr >= originaddr+lbl_start: - yield '\n' - if lbl_name is None: - yield '--end of the loop--\n' - else: - yield str(lbl_name) + '\n' - yield line - break - yield line - # yield all the remaining lines - for line in itlines: - yield line - -def objdump(input): - os.system('objdump -D -M reg-names-std --architecture=arm --target=binary %s' % input) - - -def get_tmp_file(): - # don't use rpython.tool.udir here to avoid removing old usessions which - # might still contain interesting executables - udir = py.path.local.make_numbered_dir(prefix='viewcode-', keep=2) - tmpfile = str(udir.join('dump.tmp')) - return tmpfile - -def decode(source): - with open(source, 'r') as f: - data = f.read().strip() - data = data.decode('hex') - - target = get_tmp_file() - with open(target, 'wb') as f: - f.write(data) - return target - - -if __name__ == '__main__': - if len(sys.argv) == 2: - objdump(sys.argv[1]) - elif len(sys.argv) == 3: - assert sys.argv[1] == '--decode' - f = decode(sys.argv[2]) - objdump(f) - else: - print >> sys.stderr, __doc__ - sys.exit(2) diff --git a/rpython/jit/backend/arm/tool/viewdump.sh b/rpython/jit/backend/arm/tool/viewdump.sh new file mode 100755 --- /dev/null +++ b/rpython/jit/backend/arm/tool/viewdump.sh @@ -0,0 +1,2 @@ +#!/bin/sh +objdump -D -M reg-names-std --architecture=arm --target=binary ${1} diff --git a/rpython/jit/backend/tool/viewcode.py b/rpython/jit/backend/tool/viewcode.py old mode 100644 new mode 100755 --- a/rpython/jit/backend/tool/viewcode.py +++ b/rpython/jit/backend/tool/viewcode.py @@ -1,11 +1,454 @@ -from rpython.jit.backend.detect_cpu import autodetect_main_model +#! /usr/bin/env python +""" +Viewer for the output of compiled programs generating code. +Use on the log files created with 'PYPYLOG=jit-backend-dump:log'. + +Try: + ./viewcode.py --text log # text only disassembly + ./viewcode.py log # also includes a pygame viewer +""" + +import new +import operator +import os +import py +import re import sys +import subprocess +from bisect import bisect_left +# don't use rpython.tool.udir here to avoid removing old usessions which +# might still contain interesting executables +udir = py.path.local.make_numbered_dir(prefix='viewcode-', keep=2) +tmpfile = str(udir.join('dump.tmp')) -def get_module(mod): - __import__(mod) - return sys.modules[mod] +# hack hack +import rpython.tool +mod = new.module('rpython.tool.udir') +mod.udir = udir +sys.modules['rpython.tool.udir'] = mod +rpython.tool.udir = mod -cpu = autodetect_main_model() -viewcode = get_module("rpython.jit.backend.%s.tool.viewcode" % cpu) -machine_code_dump = getattr(viewcode, 'machine_code_dump') +# ____________________________________________________________ +# Some support code from Psyco. There is more over there, +# I am porting it in a lazy fashion... See py-utils/xam.py + +if sys.platform == "win32": + pass # lots more in Psyco + +def find_objdump(): + exe = ('objdump', 'gobjdump') + path = os.environ['PATH'].split(os.pathsep) + for e in exe: + for p in path: + path_to = os.path.join(p, e) + if not os.path.exists(path_to): + continue + return e + raise AssertionError('(g)objdump was not found in PATH') + +def machine_code_dump(data, originaddr, backend_name, label_list=None): + objdump_backend_option = { + 'x86': 'i386', + 'x86_32': 'i386', + 'x86_64': 'x86-64', + 'i386': 'i386', + 'arm': 'arm', + 'arm_32': 'arm', + } + cmd = find_objdump() + objdump = ('%(command)s -M %(backend)s -b binary -m %(machine)s ' + '--disassembler-options=intel-mnemonics ' + '--adjust-vma=%(origin)d -D %(file)s') + # + f = open(tmpfile, 'wb') + f.write(data) + f.close() + p = subprocess.Popen(objdump % { + 'command': cmd, + 'file': tmpfile, + 'origin': originaddr, + 'backend': objdump_backend_option[backend_name], + 'machine': 'i386' if backend_name != 'arm' else 'arm', + }, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + stdout, stderr = p.communicate() + assert not p.returncode, ('Encountered an error running objdump: %s' % + stderr) + # drop some objdump cruft + lines = stdout.splitlines(True)[6:] # drop some objdump cruft + return format_code_dump_with_labels(originaddr, lines, label_list) + +def format_code_dump_with_labels(originaddr, lines, label_list): + from rpython.rlib.rarithmetic import r_uint + if not label_list: + label_list = [] + originaddr = r_uint(originaddr) + itlines = iter(lines) + yield itlines.next() # don't process the first line + for lbl_start, lbl_name in label_list: + for line in itlines: + addr, _ = line.split(':', 1) + addr = int(addr, 16) + if addr >= originaddr+lbl_start: + yield '\n' + if lbl_name is None: + yield '--end of the loop--\n' + else: + yield str(lbl_name) + '\n' + yield line + break + yield line + # yield all the remaining lines + for line in itlines: + yield line + +def load_symbols(filename): + # the program that lists symbols, and the output it gives + symbollister = 'nm %s' + re_symbolentry = re.compile(r'([0-9a-fA-F]+)\s\w\s(.*)') + # + print 'loading symbols from %s...' % (filename,) + symbols = {} + p = subprocess.Popen(symbollister % filename, shell=True, + stdout=subprocess.PIPE, stderr=subprocess.PIPE) + stdout, stderr = p.communicate() + assert not p.returncode, ('Encountered an error running nm: %s' % + stderr) + for line in stdout.splitlines(True): + match = re_symbolentry.match(line) + if match: + addr = long(match.group(1), 16) + name = match.group(2) + if name.startswith('pypy_g_'): + name = '\xb7' + name[7:] + symbols[addr] = name + print '%d symbols found' % (len(symbols),) + return symbols + +re_addr = re.compile(r'[\s,$]0x([0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]+)') +re_lineaddr = re.compile(r'\s*0?x?([0-9a-fA-F]+)') + +def lineaddresses(line): + result = [] + i = 0 + while 1: + match = re_addr.search(line, i) + if not match: + break + i = match.end() + addr = long(match.group(1), 16) + result.append(addr) + return result + +# ____________________________________________________________ + +class CodeRange(object): + fallthrough = False + + def __init__(self, world, addr, data): + self.world = world + self.addr = addr + self.data = data + + def __repr__(self): + return '' % (hex(self.addr), len(self.data)) + + def touches(self, other): + return (self .addr < other.addr + len(other.data) and + other.addr < self .addr + len(self.data)) + + def update_from_old(self, other): + if other.addr < self.addr: + delta = self.addr - other.addr + assert delta <= len(other.data) + self.addr -= delta + self.data = other.data[:delta] + self.data + self_end = self .addr + len(self .data) + other_end = other.addr + len(other.data) + if other_end > self_end: + extra = other_end - self_end + assert extra <= len(other.data) + self.data += other.data[-extra:] + + def cmpop(op): + def _cmp(self, other): + if not isinstance(other, CodeRange): + return NotImplemented + return op((self.addr, self.data), (other.addr, other.data)) + return _cmp + __lt__ = cmpop(operator.lt) + __le__ = cmpop(operator.le) + __eq__ = cmpop(operator.eq) + __ne__ = cmpop(operator.ne) + __gt__ = cmpop(operator.gt) + __ge__ = cmpop(operator.ge) + del cmpop + + def disassemble(self): + if not hasattr(self, 'text'): + lines = machine_code_dump(self.data, self.addr, self.world.backend_name) + lines = list(lines) + # instead of adding symbol names in the dumps we could + # also make the 0xNNNNNNNN addresses be red and show the + # symbol name when the mouse is over them + logentries = self.world.logentries + symbols = self.world.symbols + for i, line in enumerate(lines): + match = re_lineaddr.match(line) + if match: + addr = long(match.group(1), 16) + logentry = logentries.get(addr) + if logentry: + lines[i] = '\n%s\n%s' % (logentry, lines[i]) + for addr in lineaddresses(line): + sym = symbols.get(addr) + if sym: + lines[i] = '%s\t%s\n' % (lines[i].rstrip(), sym) + self.text = ''.join(lines) + return self.text + + def findjumps(self): + text = self.disassemble() + lines = text.splitlines() + line = '' + for i, line in enumerate(lines): + if '\tj' not in line: # poor heuristic to recognize lines that + continue # could be jump instructions + addrs = list(lineaddresses(line)) + if not addrs: + continue + addr = addrs[-1] + final = '\tjmp' in line + yield i, addr, final + if self.fallthrough and '\tret' not in line: + yield len(lines), self.addr + len(self.data), True + + +class World(object): + + def __init__(self): + self.ranges = [] + self.labeltargets = {} + self.jumps = {} + self.symbols = {} + self.logentries = {} + self.backend_name = None + self.executable_name = None + + def parse(self, f, textonly=True): + for line in f: + if line.startswith('BACKEND '): + self.backend_name = line.split(' ')[1].strip() + elif line.startswith('CODE_DUMP '): + pieces = line.split() + assert pieces[1].startswith('@') + assert pieces[2].startswith('+') + if len(pieces) == 3: + continue # empty line + baseaddr = long(pieces[1][1:], 16) & 0xFFFFFFFFL + offset = int(pieces[2][1:]) + addr = baseaddr + offset + data = pieces[3].replace(':', '').decode('hex') + coderange = CodeRange(self, addr, data) + i = bisect_left(self.ranges, coderange) + j = i + while i>0 and coderange.touches(self.ranges[i-1]): + coderange.update_from_old(self.ranges[i-1]) + i -= 1 + while j= fnext: + sys.stderr.write("%d%%" % int(f*100.0)) + fnext += 0.1 + sys.stderr.write(".") + sys.stderr.write("100%") + # split blocks at labeltargets + t = self.labeltargets + #print t + for r in self.ranges: + #print r.addr, r.addr + len(r.data) + for i in range(r.addr + 1, r.addr + len(r.data)): + if i in t: + #print i + ofs = i - r.addr + self.ranges.append(CodeRange(self, i, r.data[ofs:])) + r.data = r.data[:ofs] + r.fallthrough = True + try: + del r.text + except AttributeError: + pass + break + # hack hack hacked + sys.stderr.write("\n") + + def show(self, showtext=True, showgraph=True): + if showgraph: + g1 = Graph('codedump') + self.ranges.sort() + for r in self.ranges: + disassembled = r.disassemble() + if showtext: + print disassembled + if showgraph: + text, width = tab2columns(disassembled) + text = '0x%x\n\n%s' % (r.addr, text) + g1.emit_node('N_%x' % r.addr, shape="box", label=text, + width=str(width*0.1125)) + for lineno, targetaddr, final in r.findjumps(): + if final: + color = "black" + else: + color = "red" + g1.emit_edge('N_%x' % r.addr, 'N_%x' % targetaddr, + color=color) + sys.stdout.flush() + if showgraph: + g1.display() + + def showtextonly(self): + self.ranges.sort() + for r in self.ranges: + disassembled = r.disassemble() + print disassembled + del r.text + + +def tab2columns(text): + lines = text.split('\n') + columnwidth = [] + for line in lines: + columns = line.split('\t')[:-1] + while len(columnwidth) < len(columns): + columnwidth.append(0) + for i, s in enumerate(columns): + width = len(s.strip()) + if not s.endswith(':'): + width += 2 + columnwidth[i] = max(columnwidth[i], width) + columnwidth.append(1) + result = [] + for line in lines: + columns = line.split('\t') + text = [] + for width, s in zip(columnwidth, columns): + text.append(s.strip().ljust(width)) + result.append(' '.join(text)) + lengths = [len(line) for line in result] + lengths.append(1) + totalwidth = max(lengths) + return '\\l'.join(result), totalwidth + +# ____________________________________________________________ +# XXX pasted from +# http://codespeak.net/svn/user/arigo/hack/misc/graphlib.py +# but needs to be a bit more subtle later + +from rpython.translator.tool.make_dot import DotGen +from dotviewer.graphclient import display_page + +class Graph(DotGen): + + def highlight(self, word, text, linked_to=None): + if not hasattr(self, '_links'): + self._links = {} + self._links_to = {} + self._links[word] = text + if linked_to: + self._links_to[word] = linked_to + + def display(self): + "Display a graph page locally." + display_page(_Page(self)) + + +class NoGraph(Exception): + pass + +class _Page: + def __init__(self, graph_builder): + if callable(graph_builder): + graph = graph_builder() + else: + graph = graph_builder + if graph is None: + raise NoGraph + self.graph_builder = graph_builder + + def content(self): + return _PageContent(self.graph_builder) + +class _PageContent: + fixedfont = True + + def __init__(self, graph_builder): + if callable(graph_builder): + graph = graph_builder() + else: + graph = graph_builder + assert graph is not None + self.graph_builder = graph_builder + self.graph = graph + self.links = getattr(graph, '_links', {}) + if not hasattr(graph, '_source'): + graph._source = graph.generate(target=None) + self.source = graph._source + + def followlink(self, link): + try: + return _Page(self.graph._links_to[link]) + except NoGraph: + return _Page(self.graph_builder) + +# ____________________________________________________________ + +if __name__ == '__main__': + if '--text' in sys.argv: + sys.argv.remove('--text') + showgraph = False + else: + showgraph = True + if len(sys.argv) != 2: + print >> sys.stderr, __doc__ + sys.exit(2) + # + import cStringIO + from rpython.tool import logparser + log1 = logparser.parse_log_file(sys.argv[1]) + text1 = logparser.extract_category(log1, catprefix='jit-backend-dump') + f = cStringIO.StringIO() + f.writelines(text1) + f.seek(0) + del log1, text1 + # + world = World() + world.parse(f) + if showgraph: + world.find_cross_references() + world.show(showtext=True) + else: + world.showtextonly() diff --git a/rpython/jit/backend/x86/tool/viewcode.py b/rpython/jit/backend/x86/tool/viewcode.py deleted file mode 100755 --- a/rpython/jit/backend/x86/tool/viewcode.py +++ /dev/null @@ -1,453 +0,0 @@ -#! /usr/bin/env python -""" -Viewer for the output of compiled programs generating code. -Use on the log files created with 'PYPYLOG=jit-backend-dump:log'. - -Try: - ./viewcode.py --text log # text only disassembly - ./viewcode.py log # also includes a pygame viewer -""" - -import new -import operator -import os -import py -import re -import sys -import subprocess -from bisect import bisect_left - -# don't use rpython.tool.udir here to avoid removing old usessions which -# might still contain interesting executables -udir = py.path.local.make_numbered_dir(prefix='viewcode-', keep=2) -tmpfile = str(udir.join('dump.tmp')) - -# hack hack -import rpython.tool -mod = new.module('rpython.tool.udir') -mod.udir = udir -sys.modules['rpython.tool.udir'] = mod -rpython.tool.udir = mod - -# ____________________________________________________________ -# Some support code from Psyco. There is more over there, -# I am porting it in a lazy fashion... See py-utils/xam.py - -if sys.platform == "win32": - pass # lots more in Psyco - -def find_objdump(): - exe = ('objdump', 'gobjdump') - path = os.environ['PATH'].split(os.pathsep) - for e in exe: - for p in path: - path_to = os.path.join(p, e) - if not os.path.exists(path_to): - continue - return e - raise AssertionError('(g)objdump was not found in PATH') - -def machine_code_dump(data, originaddr, backend_name, label_list=None): - objdump_backend_option = { - 'x86': 'i386', - 'x86_32': 'i386', - 'x86_64': 'x86-64', - 'i386': 'i386', - 'arm': 'arm', - } - cmd = find_objdump() - objdump = ('%(command)s -M %(backend)s -b binary -m %(machine)s ' - '--disassembler-options=intel-mnemonics ' - '--adjust-vma=%(origin)d -D %(file)s') - # - f = open(tmpfile, 'wb') - f.write(data) - f.close() - p = subprocess.Popen(objdump % { - 'command': cmd, - 'file': tmpfile, - 'origin': originaddr, - 'backend': objdump_backend_option[backend_name], - 'machine': 'i386' if backend_name != 'arm' else 'arm', - }, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) - stdout, stderr = p.communicate() - assert not p.returncode, ('Encountered an error running objdump: %s' % - stderr) - # drop some objdump cruft - lines = stdout.splitlines(True)[6:] # drop some objdump cruft - return format_code_dump_with_labels(originaddr, lines, label_list) - -def format_code_dump_with_labels(originaddr, lines, label_list): - from rpython.rlib.rarithmetic import r_uint - if not label_list: - label_list = [] - originaddr = r_uint(originaddr) - itlines = iter(lines) - yield itlines.next() # don't process the first line - for lbl_start, lbl_name in label_list: - for line in itlines: - addr, _ = line.split(':', 1) - addr = int(addr, 16) - if addr >= originaddr+lbl_start: - yield '\n' - if lbl_name is None: - yield '--end of the loop--\n' - else: - yield str(lbl_name) + '\n' - yield line - break - yield line - # yield all the remaining lines - for line in itlines: - yield line - -def load_symbols(filename): - # the program that lists symbols, and the output it gives - symbollister = 'nm %s' - re_symbolentry = re.compile(r'([0-9a-fA-F]+)\s\w\s(.*)') - # - print 'loading symbols from %s...' % (filename,) - symbols = {} - p = subprocess.Popen(symbollister % filename, shell=True, - stdout=subprocess.PIPE, stderr=subprocess.PIPE) - stdout, stderr = p.communicate() - assert not p.returncode, ('Encountered an error running nm: %s' % - stderr) - for line in stdout.splitlines(True): - match = re_symbolentry.match(line) - if match: - addr = long(match.group(1), 16) - name = match.group(2) - if name.startswith('pypy_g_'): - name = '\xb7' + name[7:] - symbols[addr] = name - print '%d symbols found' % (len(symbols),) - return symbols - -re_addr = re.compile(r'[\s,$]0x([0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]+)') -re_lineaddr = re.compile(r'\s*0?x?([0-9a-fA-F]+)') - -def lineaddresses(line): - result = [] - i = 0 - while 1: - match = re_addr.search(line, i) - if not match: - break - i = match.end() - addr = long(match.group(1), 16) - result.append(addr) - return result - -# ____________________________________________________________ - -class CodeRange(object): - fallthrough = False - - def __init__(self, world, addr, data): - self.world = world - self.addr = addr - self.data = data - - def __repr__(self): - return '' % (hex(self.addr), len(self.data)) - - def touches(self, other): - return (self .addr < other.addr + len(other.data) and - other.addr < self .addr + len(self.data)) - - def update_from_old(self, other): - if other.addr < self.addr: - delta = self.addr - other.addr - assert delta <= len(other.data) - self.addr -= delta - self.data = other.data[:delta] + self.data - self_end = self .addr + len(self .data) - other_end = other.addr + len(other.data) - if other_end > self_end: - extra = other_end - self_end - assert extra <= len(other.data) - self.data += other.data[-extra:] - - def cmpop(op): - def _cmp(self, other): - if not isinstance(other, CodeRange): - return NotImplemented - return op((self.addr, self.data), (other.addr, other.data)) - return _cmp - __lt__ = cmpop(operator.lt) - __le__ = cmpop(operator.le) - __eq__ = cmpop(operator.eq) - __ne__ = cmpop(operator.ne) - __gt__ = cmpop(operator.gt) - __ge__ = cmpop(operator.ge) - del cmpop - - def disassemble(self): - if not hasattr(self, 'text'): - lines = machine_code_dump(self.data, self.addr, self.world.backend_name) - lines = list(lines) - # instead of adding symbol names in the dumps we could - # also make the 0xNNNNNNNN addresses be red and show the - # symbol name when the mouse is over them - logentries = self.world.logentries - symbols = self.world.symbols - for i, line in enumerate(lines): - match = re_lineaddr.match(line) - if match: - addr = long(match.group(1), 16) - logentry = logentries.get(addr) - if logentry: - lines[i] = '\n%s\n%s' % (logentry, lines[i]) - for addr in lineaddresses(line): - sym = symbols.get(addr) - if sym: - lines[i] = '%s\t%s\n' % (lines[i].rstrip(), sym) - self.text = ''.join(lines) - return self.text - - def findjumps(self): - text = self.disassemble() - lines = text.splitlines() - line = '' - for i, line in enumerate(lines): - if '\tj' not in line: # poor heuristic to recognize lines that - continue # could be jump instructions - addrs = list(lineaddresses(line)) - if not addrs: - continue - addr = addrs[-1] - final = '\tjmp' in line - yield i, addr, final - if self.fallthrough and '\tret' not in line: - yield len(lines), self.addr + len(self.data), True - - -class World(object): - - def __init__(self): - self.ranges = [] - self.labeltargets = {} - self.jumps = {} - self.symbols = {} - self.logentries = {} - self.backend_name = None - self.executable_name = None - - def parse(self, f, textonly=True): - for line in f: - if line.startswith('BACKEND '): - self.backend_name = line.split(' ')[1].strip() - elif line.startswith('CODE_DUMP '): - pieces = line.split() - assert pieces[1].startswith('@') - assert pieces[2].startswith('+') - if len(pieces) == 3: - continue # empty line - baseaddr = long(pieces[1][1:], 16) & 0xFFFFFFFFL - offset = int(pieces[2][1:]) - addr = baseaddr + offset - data = pieces[3].replace(':', '').decode('hex') - coderange = CodeRange(self, addr, data) - i = bisect_left(self.ranges, coderange) - j = i - while i>0 and coderange.touches(self.ranges[i-1]): - coderange.update_from_old(self.ranges[i-1]) - i -= 1 - while j= fnext: - sys.stderr.write("%d%%" % int(f*100.0)) - fnext += 0.1 - sys.stderr.write(".") - sys.stderr.write("100%") - # split blocks at labeltargets - t = self.labeltargets - #print t - for r in self.ranges: - #print r.addr, r.addr + len(r.data) - for i in range(r.addr + 1, r.addr + len(r.data)): - if i in t: - #print i - ofs = i - r.addr - self.ranges.append(CodeRange(self, i, r.data[ofs:])) - r.data = r.data[:ofs] - r.fallthrough = True - try: - del r.text - except AttributeError: - pass - break - # hack hack hacked - sys.stderr.write("\n") - - def show(self, showtext=True, showgraph=True): - if showgraph: - g1 = Graph('codedump') - self.ranges.sort() - for r in self.ranges: - disassembled = r.disassemble() - if showtext: - print disassembled - if showgraph: - text, width = tab2columns(disassembled) - text = '0x%x\n\n%s' % (r.addr, text) - g1.emit_node('N_%x' % r.addr, shape="box", label=text, - width=str(width*0.1125)) - for lineno, targetaddr, final in r.findjumps(): - if final: - color = "black" - else: - color = "red" - g1.emit_edge('N_%x' % r.addr, 'N_%x' % targetaddr, - color=color) - sys.stdout.flush() - if showgraph: - g1.display() - - def showtextonly(self): - self.ranges.sort() - for r in self.ranges: - disassembled = r.disassemble() - print disassembled - del r.text - - -def tab2columns(text): - lines = text.split('\n') - columnwidth = [] - for line in lines: - columns = line.split('\t')[:-1] - while len(columnwidth) < len(columns): - columnwidth.append(0) - for i, s in enumerate(columns): - width = len(s.strip()) - if not s.endswith(':'): - width += 2 - columnwidth[i] = max(columnwidth[i], width) - columnwidth.append(1) - result = [] - for line in lines: - columns = line.split('\t') - text = [] - for width, s in zip(columnwidth, columns): - text.append(s.strip().ljust(width)) - result.append(' '.join(text)) - lengths = [len(line) for line in result] - lengths.append(1) - totalwidth = max(lengths) - return '\\l'.join(result), totalwidth - -# ____________________________________________________________ -# XXX pasted from -# http://codespeak.net/svn/user/arigo/hack/misc/graphlib.py -# but needs to be a bit more subtle later - -from rpython.translator.tool.make_dot import DotGen -from dotviewer.graphclient import display_page - -class Graph(DotGen): - - def highlight(self, word, text, linked_to=None): - if not hasattr(self, '_links'): - self._links = {} - self._links_to = {} - self._links[word] = text - if linked_to: - self._links_to[word] = linked_to - - def display(self): - "Display a graph page locally." - display_page(_Page(self)) - - -class NoGraph(Exception): - pass - -class _Page: - def __init__(self, graph_builder): - if callable(graph_builder): - graph = graph_builder() - else: - graph = graph_builder - if graph is None: - raise NoGraph - self.graph_builder = graph_builder - - def content(self): - return _PageContent(self.graph_builder) - -class _PageContent: - fixedfont = True - - def __init__(self, graph_builder): - if callable(graph_builder): - graph = graph_builder() - else: - graph = graph_builder - assert graph is not None - self.graph_builder = graph_builder - self.graph = graph - self.links = getattr(graph, '_links', {}) - if not hasattr(graph, '_source'): - graph._source = graph.generate(target=None) - self.source = graph._source - - def followlink(self, link): - try: - return _Page(self.graph._links_to[link]) - except NoGraph: - return _Page(self.graph_builder) - -# ____________________________________________________________ - -if __name__ == '__main__': - if '--text' in sys.argv: - sys.argv.remove('--text') - showgraph = False - else: - showgraph = True - if len(sys.argv) != 2: - print >> sys.stderr, __doc__ - sys.exit(2) - # - import cStringIO - from rpython.tool import logparser - log1 = logparser.parse_log_file(sys.argv[1]) - text1 = logparser.extract_category(log1, catprefix='jit-backend-dump') - f = cStringIO.StringIO() - f.writelines(text1) - f.seek(0) - del log1, text1 - # - world = World() - world.parse(f) - if showgraph: - world.find_cross_references() - world.show(showtext=True) - else: - world.showtextonly() From noreply at buildbot.pypy.org Mon Feb 18 19:07:12 2013 From: noreply at buildbot.pypy.org (lwassermann) Date: Mon, 18 Feb 2013 19:07:12 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: added three more bytecodes with tests Message-ID: <20130218180712.B21721C0925@cobra.cs.uni-duesseldorf.de> Author: Lars Wassermann Branch: Changeset: r55:bcc14b793a2c Date: 2013-02-18 19:06 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/bcc14b793a2c/ Log: added three more bytecodes with tests diff --git a/spyvm/interpreter.py b/spyvm/interpreter.py --- a/spyvm/interpreter.py +++ b/spyvm/interpreter.py @@ -377,7 +377,6 @@ else: newArray = interp.space.w_Array.as_class_get_shadow(interp.space).new(arraySize) self.push(newArray) - # raise MissingBytecode("not yet implemented: pushNewArray") def experimentalBytecode(self, interp): raise MissingBytecode("experimentalBytecode") @@ -385,17 +384,23 @@ def pushTempAtInTempVectorAt(self, interp): k = self.getbytecode() j = self.getbytecode() - raise MissingBytecode("not yet implemented: pushTempAt k inTempVectorAt j") + context = interp.s_active_context() + indirectTemps = context.gettemp(j) + context.push(indirectTemps.at0(self, k)) def storeTempAtInTempVectorAt(self, interp): k = self.getbytecode() j = self.getbytecode() - raise MissingBytecode("not yet implemented: storeTempAt k inTempVectorAt j") + context = interp.s_active_context() + indirectTemps = context.gettemp(j) + indirectTemps.atput0(self, k, context.top()) def popAndStoreTempAtInTempVectorAt(self, interp): k = self.getbytecode() j = self.getbytecode() - raise MissingBytecode("not yet implemented: popAndstoreTempAt k inTempVectorAt j") + context = interp.s_active_context() + indirectTemps = context.gettemp(j) + indirectTemps.atput0(self, k, context.pop()) def pushClosureNumCopiedNumArgsBlockSize(self, interp): l, k = splitter[4, 4](self.getbytecode()) diff --git a/spyvm/test/test_interpreter.py b/spyvm/test/test_interpreter.py --- a/spyvm/test/test_interpreter.py +++ b/spyvm/test/test_interpreter.py @@ -850,3 +850,38 @@ array = context.pop() assert array.size() == 7 assert array.at0(space, 0) == space.w_nil + +def test_pushTempAt0InTempVectorAt0(bytecode = pushTempAtInTempVectorAt): + interp = new_interpreter(bytecode + chr(0) + chr(0)) + context = interp.s_active_context() + context.push(fakeliterals(space, "jam")) + context.settemp(0, space.w_Array.as_class_get_shadow(interp.space).new(2)) + interp.step(interp.s_active_context()) + assert context.top() == space.w_nil + +def setupTempArrayAndContext(bytecode): + # both indizes are 0-relative + interp = new_interpreter(bytecode + chr(2) + chr(1)) + context = interp.s_active_context() + context.push(fakeliterals(space, "english")) + context.push(fakeliterals(space, "bar")) + temp_array = space.w_Array.as_class_get_shadow(interp.space).new(3) + temp_array.atput0(space, 2, fakeliterals(space, "pub")) + context.settemp(1, temp_array) + interp.step(interp.s_active_context()) + return context, temp_array + +def test_pushTempAt3InTempVectorAt1(bytecode = pushTempAtInTempVectorAt): + context, _ = setupTempArrayAndContext(bytecode) + assert context.top() == fakeliterals(space, "pub") + +def test_storeTempAtInTempVectorAt(bytecode = storeTempAtInTempVectorAt): + context, temp_array = setupTempArrayAndContext(bytecode) + assert context.top() == fakeliterals(space, "bar") + assert temp_array.at0(space, 2) == fakeliterals(space, "bar") + +def test_popAndStoreTempAtInTempVectorAt(bytecode = popAndStoreTempAtInTempVectorAt): + context, temp_array = setupTempArrayAndContext(bytecode) + assert temp_array.at0(space, 2) == fakeliterals(space, "bar") + assert context.top() == fakeliterals(space, "english") + From noreply at buildbot.pypy.org Mon Feb 18 19:17:33 2013 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 18 Feb 2013 19:17:33 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: Reorganize a bit jitframe_trace() for performance, and fix the bug. Message-ID: <20130218181733.2DE4D1C0925@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: jitframe-on-heap Changeset: r61421:fd55850acd3f Date: 2013-02-18 19:17 +0100 http://bitbucket.org/pypy/pypy/changeset/fd55850acd3f/ Log: Reorganize a bit jitframe_trace() for performance, and fix the bug. diff --git a/rpython/jit/backend/llsupport/jitframe.py b/rpython/jit/backend/llsupport/jitframe.py --- a/rpython/jit/backend/llsupport/jitframe.py +++ b/rpython/jit/backend/llsupport/jitframe.py @@ -87,56 +87,64 @@ def jitframe_trace(obj_addr, prev): if prev == llmemory.NULL: - (obj_addr + getofs('jf_gc_trace_state')).signed[0] = 0 + (obj_addr + getofs('jf_gc_trace_state')).signed[0] = -1 return obj_addr + getofs('jf_descr') fld = (obj_addr + getofs('jf_gc_trace_state')).signed[0] - state = fld & 0x7 # 3bits of possible states - if state == 0: - (obj_addr + getofs('jf_gc_trace_state')).signed[0] = 1 - return obj_addr + getofs('jf_force_descr') - elif state == 1: - (obj_addr + getofs('jf_gc_trace_state')).signed[0] = 2 - return obj_addr + getofs('jf_savedata') - elif state == 2: - (obj_addr + getofs('jf_gc_trace_state')).signed[0] = 3 - return obj_addr + getofs('jf_guard_exc') - ll_assert(state == 3, "invalid state") + if fld < 0: + if fld == -1: + (obj_addr + getofs('jf_gc_trace_state')).signed[0] = -2 + return obj_addr + getofs('jf_force_descr') + elif fld == -2: + (obj_addr + getofs('jf_gc_trace_state')).signed[0] = -3 + return obj_addr + getofs('jf_savedata') + elif fld == -3: + (obj_addr + getofs('jf_gc_trace_state')).signed[0] = -4 + return obj_addr + getofs('jf_guard_exc') + else: + if not (obj_addr + getofs('jf_gcmap')).address[0]: + return llmemory.NULL # done + else: + fld = 0 # fall-through # bit pattern # decode the pattern if IS_32BIT: # 32 possible bits - state = (fld >> 3) & 0x1f - no = fld >> (3 + 5) + state = fld & 0x1f + no = fld >> 5 MAX = 32 else: # 64 possible bits - state = (fld >> 3) & 0x3f - no = fld >> (3 + 6) + state = fld & 0x3f + no = fld >> 6 MAX = 64 gcmap = (obj_addr + getofs('jf_gcmap')).address[0] - if not gcmap: - return llmemory.NULL gcmap_lgt = (gcmap + GCMAPLENGTHOFS).signed[0] while no < gcmap_lgt: cur = (gcmap + GCMAPBASEOFS + UNSIGN_SIZE * no).unsigned[0] - while state < MAX and not (cur & (1 << state)): + while not (cur & (1 << state)): state += 1 - if state < MAX: + if state == MAX: + no += 1 + state = 0 + break # next iteration of the outermost loop + else: # found it + index = no * SIZEOFSIGNED * 8 + state # save new state + state += 1 + if state == MAX: + no += 1 + state = 0 if IS_32BIT: - new_state = 3 | ((state + 1) << 3) | (no << 8) + new_state = state | (no << 5) else: - new_state = 3 | ((state + 1) << 3) | (no << 9) + new_state = state | (no << 6) (obj_addr + getofs('jf_gc_trace_state')).signed[0] = new_state - index = no * SIZEOFSIGNED * 8 + state # sanity check frame_lgt = (obj_addr + getofs('jf_frame') + LENGTHOFS).signed[0] ll_assert(index < frame_lgt, "bogus frame field get") return (obj_addr + getofs('jf_frame') + BASEITEMOFS + SIGN_SIZE * (index)) - no += 1 - state = 0 return llmemory.NULL CUSTOMTRACEFUNC = lltype.FuncType([llmemory.Address, llmemory.Address], From noreply at buildbot.pypy.org Mon Feb 18 19:18:17 2013 From: noreply at buildbot.pypy.org (rguillebert) Date: Mon, 18 Feb 2013 19:18:17 +0100 (CET) Subject: [pypy-commit] pypy default: ndarray.__eq__ should return False when shapes are incompatible, add a test for that Message-ID: <20130218181817.DAA2A1C0925@cobra.cs.uni-duesseldorf.de> Author: Romain Guillebert Branch: Changeset: r61422:ddd048d2a8ad Date: 2013-02-18 19:05 +0100 http://bitbucket.org/pypy/pypy/changeset/ddd048d2a8ad/ Log: ndarray.__eq__ should return False when shapes are incompatible, add a test for that diff --git a/pypy/module/micronumpy/test/test_numarray.py b/pypy/module/micronumpy/test/test_numarray.py --- a/pypy/module/micronumpy/test/test_numarray.py +++ b/pypy/module/micronumpy/test/test_numarray.py @@ -1769,6 +1769,12 @@ b = array(a, dtype='d') assert a.dtype is b.dtype + def test_notequal_different_shapes(self): + from _numpypy import array + a = array([1, 2]) + b = array([1, 2, 3, 4]) + assert (a == b) == False + class AppTestMultiDim(BaseNumpyAppTest): def test_init(self): From noreply at buildbot.pypy.org Mon Feb 18 19:18:19 2013 From: noreply at buildbot.pypy.org (rguillebert) Date: Mon, 18 Feb 2013 19:18:19 +0100 (CET) Subject: [pypy-commit] pypy default: merge heads Message-ID: <20130218181819.1707D1C0925@cobra.cs.uni-duesseldorf.de> Author: Romain Guillebert Branch: Changeset: r61423:6f159a1879a5 Date: 2013-02-18 19:17 +0100 http://bitbucket.org/pypy/pypy/changeset/6f159a1879a5/ Log: merge heads diff --git a/pypy/module/micronumpy/test/test_numarray.py b/pypy/module/micronumpy/test/test_numarray.py --- a/pypy/module/micronumpy/test/test_numarray.py +++ b/pypy/module/micronumpy/test/test_numarray.py @@ -1769,6 +1769,12 @@ b = array(a, dtype='d') assert a.dtype is b.dtype + def test_notequal_different_shapes(self): + from _numpypy import array + a = array([1, 2]) + b = array([1, 2, 3, 4]) + assert (a == b) == False + class AppTestMultiDim(BaseNumpyAppTest): def test_init(self): From noreply at buildbot.pypy.org Mon Feb 18 19:19:19 2013 From: noreply at buildbot.pypy.org (fijal) Date: Mon, 18 Feb 2013 19:19:19 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: fix test Message-ID: <20130218181919.CC0B61C0925@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61424:b6c4786a4f7c Date: 2013-02-18 20:18 +0200 http://bitbucket.org/pypy/pypy/changeset/b6c4786a4f7c/ Log: fix test diff --git a/rpython/jit/backend/llsupport/test/test_gc.py b/rpython/jit/backend/llsupport/test/test_gc.py --- a/rpython/jit/backend/llsupport/test/test_gc.py +++ b/rpython/jit/backend/llsupport/test/test_gc.py @@ -328,3 +328,6 @@ all_addrs.append(next) next = jitframe.jitframe_trace(frame_adr, next) # assert did not hang + + lltype.free(frame_info, flavor='raw') + lltype.free(frame.jf_gcmap, flavor='raw') From noreply at buildbot.pypy.org Mon Feb 18 19:52:15 2013 From: noreply at buildbot.pypy.org (amauryfa) Date: Mon, 18 Feb 2013 19:52:15 +0100 (CET) Subject: [pypy-commit] pypy py3k: Implement BytesIO.getbuffer() Message-ID: <20130218185215.4DD1A1C0041@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: py3k Changeset: r61425:ac389af226dc Date: 2013-02-18 19:30 +0100 http://bitbucket.org/pypy/pypy/changeset/ac389af226dc/ Log: Implement BytesIO.getbuffer() diff --git a/lib-python/3.2/test/test_memoryio.py b/lib-python/3.2/test/test_memoryio.py --- a/lib-python/3.2/test/test_memoryio.py +++ b/lib-python/3.2/test/test_memoryio.py @@ -395,8 +395,11 @@ self.assertEqual(bytes(buf), b"1234567890") # Trying to change the size of the BytesIO while a buffer is exported # raises a BufferError. - self.assertRaises(BufferError, memio.write, b'x' * 100) - self.assertRaises(BufferError, memio.truncate) + if support.check_impl_detail(pypy=False): + # PyPy export buffers differently, and allows reallocation + # of the underlying object. + self.assertRaises(BufferError, memio.write, b'x' * 100) + self.assertRaises(BufferError, memio.truncate) # Mutating the buffer updates the BytesIO buf[3:6] = b"abc" self.assertEqual(bytes(buf), b"123abc7890") diff --git a/pypy/module/_io/interp_bytesio.py b/pypy/module/_io/interp_bytesio.py --- a/pypy/module/_io/interp_bytesio.py +++ b/pypy/module/_io/interp_bytesio.py @@ -2,6 +2,7 @@ TypeDef, generic_new_descr, GetSetProperty) from pypy.interpreter.gateway import interp2app, unwrap_spec from pypy.interpreter.error import OperationError, operationerrfmt +from pypy.interpreter.buffer import RWBuffer from rpython.rlib.rarithmetic import r_longlong from pypy.module._io.interp_bufferedio import W_BufferedIOBase from pypy.module._io.interp_iobase import convert_size @@ -14,6 +15,20 @@ builder.append(buffer[i]) return builder.build() +class BytesIOBuffer(RWBuffer): + def __init__(self, w_bytesio): + self.w_bytesio = w_bytesio + + def getlength(self): + return int(self.w_bytesio.string_size) + + def getitem(self, index): + return self.w_bytesio.buf[index] + + def setitem(self, index, char): + self.w_bytesio.buf[index] = char + + class W_BytesIO(W_BufferedIOBase): def __init__(self, space): W_BufferedIOBase.__init__(self, space) @@ -123,6 +138,9 @@ return space.wrap(size) + def getbuffer_w(self, space): + return space.wrap(BytesIOBuffer(self)) + def getvalue_w(self, space): self._check_closed(space) return space.wrapbytes(buffer2string(self.buf, 0, self.string_size)) @@ -213,6 +231,7 @@ readinto = interp2app(W_BytesIO.readinto_w), write = interp2app(W_BytesIO.write_w), truncate = interp2app(W_BytesIO.truncate_w), + getbuffer = interp2app(W_BytesIO.getbuffer_w), getvalue = interp2app(W_BytesIO.getvalue_w), seek = interp2app(W_BytesIO.seek_w), tell = interp2app(W_BytesIO.tell_w), diff --git a/pypy/module/_io/test/test_bytesio.py b/pypy/module/_io/test/test_bytesio.py --- a/pypy/module/_io/test/test_bytesio.py +++ b/pypy/module/_io/test/test_bytesio.py @@ -75,3 +75,20 @@ b = _io.BytesIO(b"hello") b.close() raises(ValueError, b.readinto, bytearray(b"hello")) + + def test_getbuffer(self): + import _io + memio = _io.BytesIO(b"1234567890") + buf = memio.getbuffer() + assert bytes(buf) == b"1234567890" + memio.seek(5) + buf = memio.getbuffer() + assert bytes(buf) == b"1234567890" + # Mutating the buffer updates the BytesIO + buf[3:6] = b"abc" + assert bytes(buf) == b"123abc7890" + assert memio.getvalue() == b"123abc7890" + # After the buffer gets released, we can resize the BytesIO again + del buf + memio.truncate() + From noreply at buildbot.pypy.org Mon Feb 18 19:52:16 2013 From: noreply at buildbot.pypy.org (amauryfa) Date: Mon, 18 Feb 2013 19:52:16 +0100 (CET) Subject: [pypy-commit] pypy py3k: Run -A tests with host python2 (to import pypy directories), but use --python=bin/pypy-c Message-ID: <20130218185216.9C0F91C0041@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: py3k Changeset: r61426:d839be164699 Date: 2013-02-18 19:31 +0100 http://bitbucket.org/pypy/pypy/changeset/d839be164699/ Log: Run -A tests with host python2 (to import pypy directories), but use --python=bin/pypy-c diff --git a/pypy/pytest-A.cfg b/pypy/pytest-A.cfg --- a/pypy/pytest-A.cfg +++ b/pypy/pytest-A.cfg @@ -1,5 +1,5 @@ cherrypick = ['interpreter', 'objspace/test', 'objspace/std', 'module'] -interp = ['goal/pypy-c'] -test_driver = ['test_all.py', '-A'] +interp = ['python'] +test_driver = ['test_all.py', '-A', '--python=goal/pypy-c'] From noreply at buildbot.pypy.org Mon Feb 18 20:00:47 2013 From: noreply at buildbot.pypy.org (lwassermann) Date: Mon, 18 Feb 2013 20:00:47 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: added schematic/test for the last new bytecode: push block closure Message-ID: <20130218190047.9F9181C0041@cobra.cs.uni-duesseldorf.de> Author: Lars Wassermann Branch: Changeset: r56:a18d2886e28e Date: 2013-02-18 20:00 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/a18d2886e28e/ Log: added schematic/test for the last new bytecode: push block closure diff --git a/spyvm/interpreter.py b/spyvm/interpreter.py --- a/spyvm/interpreter.py +++ b/spyvm/interpreter.py @@ -403,10 +403,35 @@ indirectTemps.atput0(self, k, context.pop()) def pushClosureNumCopiedNumArgsBlockSize(self, interp): - l, k = splitter[4, 4](self.getbytecode()) + """ Copied from Blogpost: http://www.mirandabanda.org/cogblog/2008/07/22/closures-part-ii-the-bytecodes/ + ContextPart>>pushClosureCopyNumCopiedValues: numCopied numArgs: numArgs blockSize: blockSize + "Simulate the action of a 'closure copy' bytecode whose result is the + new BlockClosure for the following code" + | copiedValues | + numCopied > 0 + ifTrue: + [copiedValues := Array new: numCopied. + numCopied to: 1 by: -1 do: + [:i| + copiedValues at: i put: self pop]] + ifFalse: + [copiedValues := nil]. + self push: (BlockClosure new + outerContext: self + startpc: pc + numArgs: numArgs + copiedValues: copiedValues). + self jump: blockSize + """ + numArgs, numCopied = splitter[4, 4](self.getbytecode()) j = self.getbytecode() i = self.getbytecode() - raise MissingBytecode("not yet implemented: pushClosureNumCopied l numArgs k blockSize ij") + blockSize = (j << 8) | i + copiedValues = interp.space.w_nil + if numCopied > 0: + copiedValues = interp.space.wrap_list(self.pop_and_return_n(numCopied)) + self.push(interp.space.w_nil) + self.jump(blockSize) def jump(self,offset): self.store_pc(self.pc() + offset) diff --git a/spyvm/test/test_interpreter.py b/spyvm/test/test_interpreter.py --- a/spyvm/test/test_interpreter.py +++ b/spyvm/test/test_interpreter.py @@ -885,3 +885,12 @@ assert temp_array.at0(space, 2) == fakeliterals(space, "bar") assert context.top() == fakeliterals(space, "english") +def test_pushClosureNumCopiedNumArgsBlockSize(bytecode = pushClosureNumCopiedNumArgsBlockSize): + for i in range(0, 65536, 7): + interp = new_interpreter(bytecode + chr(2) + chr(i >> 8) + chr(i & 0xFF)) + context = interp.s_active_context() + pc = context.pc() + # create/find a method with an appropriate blockClosure + interp.step(interp.s_active_context()) + assert context.pc() == pc + 4 + i + # assert that the right blockClosure has been pushed \ No newline at end of file From noreply at buildbot.pypy.org Mon Feb 18 22:29:14 2013 From: noreply at buildbot.pypy.org (mattip) Date: Mon, 18 Feb 2013 22:29:14 +0100 (CET) Subject: [pypy-commit] pypy default: fix python-level min, max for zero-sized arrays Message-ID: <20130218212914.8CB661C3D23@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: Changeset: r61427:3073d4f09fcd Date: 2013-02-18 22:41 +0200 http://bitbucket.org/pypy/pypy/changeset/3073d4f09fcd/ Log: fix python-level min,max for zero-sized arrays diff --git a/pypy/module/micronumpy/app_numpy.py b/pypy/module/micronumpy/app_numpy.py --- a/pypy/module/micronumpy/app_numpy.py +++ b/pypy/module/micronumpy/app_numpy.py @@ -67,11 +67,15 @@ def min(a, axis=None, out=None): if not hasattr(a, "min"): a = _numpypy.array(a) + if a.size < 1: + return _numpypy.array([]) return a.min(axis=axis, out=out) def max(a, axis=None, out=None): if not hasattr(a, "max"): a = _numpypy.array(a) + if a.size < 1: + return _numpypy.array([]) return a.max(axis=axis, out=out) def arange(start, stop=None, step=1, dtype=None): From noreply at buildbot.pypy.org Mon Feb 18 22:29:16 2013 From: noreply at buildbot.pypy.org (mattip) Date: Mon, 18 Feb 2013 22:29:16 +0100 (CET) Subject: [pypy-commit] pypy default: merge heads Message-ID: <20130218212916.1D0E01C3D24@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: Changeset: r61428:dfc4733ab719 Date: 2013-02-18 23:28 +0200 http://bitbucket.org/pypy/pypy/changeset/dfc4733ab719/ Log: merge heads diff --git a/pypy/module/micronumpy/test/test_numarray.py b/pypy/module/micronumpy/test/test_numarray.py --- a/pypy/module/micronumpy/test/test_numarray.py +++ b/pypy/module/micronumpy/test/test_numarray.py @@ -1769,6 +1769,12 @@ b = array(a, dtype='d') assert a.dtype is b.dtype + def test_notequal_different_shapes(self): + from _numpypy import array + a = array([1, 2]) + b = array([1, 2, 3, 4]) + assert (a == b) == False + class AppTestMultiDim(BaseNumpyAppTest): def test_init(self): diff --git a/rpython/rlib/test/test_timer.py b/rpython/rlib/test/test_timer.py deleted file mode 100644 --- a/rpython/rlib/test/test_timer.py +++ /dev/null @@ -1,26 +0,0 @@ -from rpython.rlib.timer import Timer -from rpython.translator.c.test.test_genc import compile -from rpython.annotator.policy import AnnotatorPolicy - - -t = Timer() -t.start("testc") -t.stop("testc") - -def timer_user(): - assert "testc" not in t.timingorder - t.start("testa") - t.stop("testa") - t.start("testb") - t.start("testb") - t.stop("testb") - t.stop("testb") - t.start_name("test", "one") - t.stop_name("test", "one") - t.dump() - - -def test_compile_timer(): - policy = AnnotatorPolicy() - f_compiled = compile(timer_user, [], annotatorpolicy=policy) - f_compiled() diff --git a/rpython/rlib/timer.py b/rpython/rlib/timer.py deleted file mode 100644 --- a/rpython/rlib/timer.py +++ /dev/null @@ -1,77 +0,0 @@ -import time -import os - - -def _create_name(name, generation): - if generation == 0: - return name - else: - return "%s[%s]" % (name, str(generation)) - - -class Timer: - def __init__(self): - self.reset() - - def reset(self): - self.timings = {} - self.levels = {} - self.timingorder = [] - - def _cleanup_(self): - self.reset() - - def start(self, timer): - level = self.levels.setdefault(timer, -1) - new_level = level + 1 - name = _create_name(timer, new_level) - if name not in self.timings: - self.timingorder.append(name) - self.timings[name] = time.time() - self.timings.get(name, 0) - self.levels[timer] = new_level - - def start_name(self, timerone, timertwo): - self.start(timerone + " " + timertwo) - - def stop(self, timer): - level = self.levels.setdefault(timer, -1) - if level == -1: - raise ValueError("Invalid timer name") - if level >= 0: # timer is active - name = _create_name(timer, level) - self.timings[name] = time.time() - self.timings[name] - self.levels[timer] = level - 1 - - def stop_name(self, timerone, timertwo): - self.stop(timerone + " " + timertwo) - - def value(self, timer): - level = self.levels.get(timer, -1) - if level == -1: - result = "%fs" % self.timings[timer] - else: - result = "%fs (still running)" % (time.time() - self.timings[timer]) - return result - - def dump(self): - outlist = [] - for timer in self.timingorder: - value = self.value(timer) - outlist.append("%s = %s" % (timer, value)) - os.write(2, "\n".join(outlist)) - - -class DummyTimer: - def start(self, timer): - pass - def start_name(self, timerone, timertwo): - pass - def stop(self, timer): - pass - def stop_name(self, timerone, timertwo): - pass - def value(self, timer): - return "Timing disabled" - def dump(self): - pass - From noreply at buildbot.pypy.org Tue Feb 19 00:05:40 2013 From: noreply at buildbot.pypy.org (amauryfa) Date: Tue, 19 Feb 2013 00:05:40 +0100 (CET) Subject: [pypy-commit] pypy py3k: Fix bz2 tests when run with the -A option. Message-ID: <20130218230540.C4D751C0041@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: py3k Changeset: r61429:df6d98fbc037 Date: 2013-02-18 23:27 +0100 http://bitbucket.org/pypy/pypy/changeset/df6d98fbc037/ Log: Fix bz2 tests when run with the -A option. diff --git a/pypy/module/bz2/test/test_bz2_compdecomp.py b/pypy/module/bz2/test/test_bz2_compdecomp.py --- a/pypy/module/bz2/test/test_bz2_compdecomp.py +++ b/pypy/module/bz2/test/test_bz2_compdecomp.py @@ -2,10 +2,9 @@ import py -from pypy.interpreter.gateway import interp2app from pypy.module.bz2.test.support import CheckAllocation from pypy.module.bz2 import interp_bz2 -from pypy.interpreter.gateway import interp2app +from pypy.interpreter import gateway import os, py HUGE_OK = False @@ -17,18 +16,17 @@ def setup_module(mod): DATA = 'BZh91AY&SY.\xc8N\x18\x00\x01>_\x80\x00\x10@\x02\xff\xf0\x01\x07n\x00?\xe7\xff\xe00\x01\x99\xaa\x00\xc0\x03F\x86\x8c#&\x83F\x9a\x03\x06\xa6\xd0\xa6\x93M\x0fQ\xa7\xa8\x06\x804hh\x12$\x11\xa4i4\xf14S\xd2\x88\xe5\xcd9gd6\x0b\n\xe9\x9b\xd5\x8a\x99\xf7\x08.K\x8ev\xfb\xf7xw\xbb\xdf\xa1\x92\xf1\xdd|/";\xa2\xba\x9f\xd5\xb1#A\xb6\xf6\xb3o\xc9\xc5y\\\xebO\xe7\x85\x9a\xbc\xb6f8\x952\xd5\xd7"%\x89>V,\xf7\xa6z\xe2\x9f\xa3\xdf\x11\x11"\xd6E)I\xa9\x13^\xca\xf3r\xd0\x03U\x922\xf26\xec\xb6\xed\x8b\xc3U\x13\x9d\xc5\x170\xa4\xfa^\x92\xacDF\x8a\x97\xd6\x19\xfe\xdd\xb8\xbd\x1a\x9a\x19\xa3\x80ankR\x8b\xe5\xd83]\xa9\xc6\x08\x82f\xf6\xb9"6l$\xb8j@\xc0\x8a\xb0l1..\xbak\x83ls\x15\xbc\xf4\xc1\x13\xbe\xf8E\xb8\x9d\r\xa8\x9dk\x84\xd3n\xfa\xacQ\x07\xb1%y\xaav\xb4\x08\xe0z\x1b\x16\xf5\x04\xe9\xcc\xb9\x08z\x1en7.G\xfc]\xc9\x14\xe1B@\xbb!8`' - def decompress(space, w_data): - import popen2 + def decompress(cls, data): + import subprocess import bz2 - data = space.bytes_w(w_data) - pop = popen2.Popen3("bunzip2", capturestderr=1) - pop.tochild.write(data) - pop.tochild.close() - res = pop.fromchild.read() - pop.fromchild.close() + pop = subprocess.Popen("bunzip2", stdin=subprocess.PIPE, + stdout=subprocess.PIPE, stderr=subprocess.PIPE) + pop.stdin.write(data) + stdout, stderr = pop.communicate() + res = stdout if pop.wait() != 0: res = bz2.decompress(data) - return space.wrapbytes(res) + return res mod.TEXT = 'root:x:0:0:root:/root:/bin/bash\nbin:x:1:1:bin:/bin:\ndaemon:x:2:2:daemon:/sbin:\nadm:x:3:4:adm:/var/adm:\nlp:x:4:7:lp:/var/spool/lpd:\nsync:x:5:0:sync:/sbin:/bin/sync\nshutdown:x:6:0:shutdown:/sbin:/sbin/shutdown\nhalt:x:7:0:halt:/sbin:/sbin/halt\nmail:x:8:12:mail:/var/spool/mail:\nnews:x:9:13:news:/var/spool/news:\nuucp:x:10:14:uucp:/var/spool/uucp:\noperator:x:11:0:operator:/root:\ngames:x:12:100:games:/usr/games:\ngopher:x:13:30:gopher:/usr/lib/gopher-data:\nftp:x:14:50:FTP User:/var/ftp:/bin/bash\nnobody:x:65534:65534:Nobody:/home:\npostfix:x:100:101:postfix:/var/spool/postfix:\nniemeyer:x:500:500::/home/niemeyer:/bin/bash\npostgres:x:101:102:PostgreSQL Server:/var/lib/pgsql:/bin/bash\nmysql:x:102:103:MySQL server:/var/lib/mysql:/bin/bash\nwww:x:103:104::/var/www:/bin/false\n' mod.DATA = DATA @@ -48,9 +46,12 @@ def setup_class(cls): cls.w_TEXT = cls.space.wrapbytes(TEXT) if cls.runappdirect: - cls.w_decompress = lambda self, *args: decompress(cls.space, *args) + cls.w_decompress = decompress else: - cls.w_decompress = cls.space.wrap(interp2app(decompress)) + @gateway.unwrap_spec(data=bytes) + def decompress_w(space, data): + return space.wrapbytes(decompress(cls, data)) + cls.w_decompress = cls.space.wrap(gateway.interp2app(decompress_w)) cls.w_HUGE_OK = cls.space.wrap(HUGE_OK) def test_creation(self): @@ -189,9 +190,12 @@ cls.w_TEXT = cls.space.wrapbytes(TEXT) cls.w_DATA = cls.space.wrapbytes(DATA) if cls.runappdirect: - cls.w_decompress = lambda self, *args: decompress(cls.space, *args) + cls.w_decompress = decompress else: - cls.w_decompress = cls.space.wrap(interp2app(decompress)) + @gateway.unwrap_spec(data=bytes) + def decompress_w(space, data): + return space.wrapbytes(decompress(cls, data)) + cls.w_decompress = cls.space.wrap(gateway.interp2app(decompress_w)) cls.w_HUGE_OK = cls.space.wrap(HUGE_OK) def test_compress_function(self): diff --git a/pypy/module/bz2/test/test_bz2_file.py b/pypy/module/bz2/test/test_bz2_file.py --- a/pypy/module/bz2/test/test_bz2_file.py +++ b/pypy/module/bz2/test/test_bz2_file.py @@ -6,7 +6,7 @@ import py -from pypy.interpreter.gateway import unwrap_spec, interp2app +from pypy.interpreter import gateway from pypy.module.bz2.test.support import CheckAllocation @@ -18,29 +18,27 @@ DATA = 'BZh91AY&SY.\xc8N\x18\x00\x01>_\x80\x00\x10@\x02\xff\xf0\x01\x07n\x00?\xe7\xff\xe00\x01\x99\xaa\x00\xc0\x03F\x86\x8c#&\x83F\x9a\x03\x06\xa6\xd0\xa6\x93M\x0fQ\xa7\xa8\x06\x804hh\x12$\x11\xa4i4\xf14S\xd2\x88\xe5\xcd9gd6\x0b\n\xe9\x9b\xd5\x8a\x99\xf7\x08.K\x8ev\xfb\xf7xw\xbb\xdf\xa1\x92\xf1\xdd|/";\xa2\xba\x9f\xd5\xb1#A\xb6\xf6\xb3o\xc9\xc5y\\\xebO\xe7\x85\x9a\xbc\xb6f8\x952\xd5\xd7"%\x89>V,\xf7\xa6z\xe2\x9f\xa3\xdf\x11\x11"\xd6E)I\xa9\x13^\xca\xf3r\xd0\x03U\x922\xf26\xec\xb6\xed\x8b\xc3U\x13\x9d\xc5\x170\xa4\xfa^\x92\xacDF\x8a\x97\xd6\x19\xfe\xdd\xb8\xbd\x1a\x9a\x19\xa3\x80ankR\x8b\xe5\xd83]\xa9\xc6\x08\x82f\xf6\xb9"6l$\xb8j@\xc0\x8a\xb0l1..\xbak\x83ls\x15\xbc\xf4\xc1\x13\xbe\xf8E\xb8\x9d\r\xa8\x9dk\x84\xd3n\xfa\xacQ\x07\xb1%y\xaav\xb4\x08\xe0z\x1b\x16\xf5\x04\xe9\xcc\xb9\x08z\x1en7.G\xfc]\xc9\x14\xe1B@\xbb!8`' DATA_CRLF = 'BZh91AY&SY\xaez\xbbN\x00\x01H\xdf\x80\x00\x12@\x02\xff\xf0\x01\x07n\x00?\xe7\xff\xe0@\x01\xbc\xc6`\x86*\x8d=M\xa9\x9a\x86\xd0L@\x0fI\xa6!\xa1\x13\xc8\x88jdi\x8d@\x03@\x1a\x1a\x0c\x0c\x83 \x00\xc4h2\x19\x01\x82D\x84e\t\xe8\x99\x89\x19\x1ah\x00\r\x1a\x11\xaf\x9b\x0fG\xf5(\x1b\x1f?\t\x12\xcf\xb5\xfc\x95E\x00ps\x89\x12^\xa4\xdd\xa2&\x05(\x87\x04\x98\x89u\xe40%\xb6\x19\'\x8c\xc4\x89\xca\x07\x0e\x1b!\x91UIFU%C\x994!DI\xd2\xfa\xf0\xf1N8W\xde\x13A\xf5\x9cr%?\x9f3;I45A\xd1\x8bT\xb1\xa4\xc7\x8d\x1a\\"\xad\xa1\xabyBg\x15\xb9l\x88\x88\x91k"\x94\xa4\xd4\x89\xae*\xa6\x0b\x10\x0c\xd6\xd4m\xe86\xec\xb5j\x8a\x86j\';\xca.\x01I\xf2\xaaJ\xe8\x88\x8cU+t3\xfb\x0c\n\xa33\x13r2\r\x16\xe0\xb3(\xbf\x1d\x83r\xe7M\xf0D\x1365\xd8\x88\xd3\xa4\x92\xcb2\x06\x04\\\xc1\xb0\xea//\xbek&\xd8\xe6+t\xe5\xa1\x13\xada\x16\xder5"w]\xa2i\xb7[\x97R \xe2IT\xcd;Z\x04dk4\xad\x8a\t\xd3\x81z\x10\xf1:^`\xab\x1f\xc5\xdc\x91N\x14$+\x9e\xae\xd3\x80' - @unwrap_spec(crlf=bool) - def create_temp_file(space, crlf=False): - f = py.test.ensuretemp("bz2").join("foo") - data = (DATA, DATA_CRLF)[crlf] - f.write(data, 'wb') + def create_temp_file(cls, crlf=False): + with open(cls.temppath, 'wb') as f: + data = (cls.DATA, cls.DATA_CRLF)[crlf] + f.write(data) - def create_broken_temp_file(): - f = py.test.ensuretemp("bz2").join("foo") - data = DATA[:100] - f.write(data, 'wb') + def create_broken_temp_file(cls): + with open(cls.temppath, 'wb') as f: + data = cls.DATA[:100] + f.write(data) - @unwrap_spec(data=str) - def decompress(space, data): - import popen2 + def decompress(cls, data): + import subprocess import bz2 - pop = popen2.Popen3("bunzip2", capturestderr=1) - pop.tochild.write(data) - pop.tochild.close() - res = pop.fromchild.read() - pop.fromchild.close() + pop = subprocess.Popen("bunzip2", stdin=subprocess.PIPE, + stdout=subprocess.PIPE, stderr=subprocess.PIPE) + pop.stdin.write(data) + stdout, stderr = pop.communicate() + res = stdout if pop.wait() != 0: res = bz2.decompress(data) - return space.wrapbytes(res) + return res mod.TEXT = 'root:x:0:0:root:/root:/bin/bash\nbin:x:1:1:bin:/bin:\ndaemon:x:2:2:daemon:/sbin:\nadm:x:3:4:adm:/var/adm:\nlp:x:4:7:lp:/var/spool/lpd:\nsync:x:5:0:sync:/sbin:/bin/sync\nshutdown:x:6:0:shutdown:/sbin:/sbin/shutdown\nhalt:x:7:0:halt:/sbin:/sbin/halt\nmail:x:8:12:mail:/var/spool/mail:\nnews:x:9:13:news:/var/spool/news:\nuucp:x:10:14:uucp:/var/spool/uucp:\noperator:x:11:0:operator:/root:\ngames:x:12:100:games:/usr/games:\ngopher:x:13:30:gopher:/usr/lib/gopher-data:\nftp:x:14:50:FTP User:/var/ftp:/bin/bash\nnobody:x:65534:65534:Nobody:/home:\npostfix:x:100:101:postfix:/var/spool/postfix:\nniemeyer:x:500:500::/home/niemeyer:/bin/bash\npostgres:x:101:102:PostgreSQL Server:/var/lib/pgsql:/bin/bash\nmysql:x:102:103:MySQL server:/var/lib/mysql:/bin/bash\nwww:x:103:104::/var/www:/bin/false\n' mod.DATA = DATA @@ -61,18 +59,32 @@ def setup_class(cls): cls.w_TEXT = cls.space.wrapbytes(TEXT) + cls.DATA = DATA cls.w_DATA = cls.space.wrapbytes(DATA) + cls.DATA_CRLF = DATA_CRLF cls.w_DATA_CRLF = cls.space.wrapbytes(DATA_CRLF) - cls.w_temppath = cls.space.wrap( - str(py.test.ensuretemp("bz2").join("foo"))) + cls.temppath = str(py.test.ensuretemp("bz2").join("foo")) + cls.w_temppath = cls.space.wrap(cls.temppath) if cls.runappdirect: cls.w_create_temp_file = create_temp_file - cls.w_create_broken_temp_file = lambda self: create_broken_temp_file() - cls.w_decompress = lambda self, *args: decompress(cls.space, *args) + cls.w_create_broken_temp_file = create_broken_temp_file + cls.w_decompress = decompress else: - cls.w_create_temp_file = cls.space.wrap(interp2app(create_temp_file)) - cls.w_decompress = cls.space.wrap(interp2app(decompress)) - cls.w_create_broken_temp_file = cls.space.wrap(interp2app(create_broken_temp_file)) + @gateway.unwrap_spec(crlf=bool) + def create_temp_file_w(crlf=False): + create_temp_file(cls, crlf) + cls.w_create_temp_file = cls.space.wrap( + gateway.interp2app(create_temp_file_w)) + + @gateway.unwrap_spec(data=bytes) + def decompress_w(space, data): + return space.wrapbytes(decompress(cls, data)) + cls.w_decompress = cls.space.wrap(gateway.interp2app(decompress_w)) + + def create_broken_temp_file_w(): + create_broken_temp_file(cls) + cls.w_create_broken_temp_file = cls.space.wrap( + gateway.interp2app(create_broken_temp_file_w)) cls.w_random_data = cls.space.wrapbytes(RANDOM_DATA) def test_attributes(self): diff --git a/pypy/tool/pytest/apptest.py b/pypy/tool/pytest/apptest.py --- a/pypy/tool/pytest/apptest.py +++ b/pypy/tool/pytest/apptest.py @@ -70,7 +70,7 @@ # "def w_method(self)" code = py.code.Code(value) defs.append(str(code.source())) - defs.append("type(self).%s = w_%s\n" % (symbol, symbol)) + defs.append("type(self).%s = %s\n" % (symbol, value.__name__)) elif isinstance(value, types.ModuleType): name = value.__name__ defs.append("import %s; self.%s = %s\n" % (name, symbol, name)) From noreply at buildbot.pypy.org Tue Feb 19 00:05:42 2013 From: noreply at buildbot.pypy.org (amauryfa) Date: Tue, 19 Feb 2013 00:05:42 +0100 (CET) Subject: [pypy-commit] pypy py3k: Fix most -A tests in module/imp Message-ID: <20130218230542.2B4391C0041@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: py3k Changeset: r61430:31f7184f866f Date: 2013-02-18 23:32 +0100 http://bitbucket.org/pypy/pypy/changeset/31f7184f866f/ Log: Fix most -A tests in module/imp diff --git a/pypy/tool/pytest/apptest.py b/pypy/tool/pytest/apptest.py --- a/pypy/tool/pytest/apptest.py +++ b/pypy/tool/pytest/apptest.py @@ -64,7 +64,15 @@ if isinstance(value, tuple) and isinstance(value[0], py.code.Source): code, args = value defs.append(str(code)) - args = ','.join(repr(arg) for arg in args) + arg_repr = [] + for arg in args: + if isinstance(arg, str): + arg_repr.append("b%r" % arg) + elif isinstance(arg, unicode): + arg_repr.append(repr(arg)[1:]) + else: + arg_repr.append(repr(arg)) + args = ','.join(arg_repr) defs.append("self.%s = anonymous(%s)\n" % (symbol, args)) elif isinstance(value, types.MethodType): # "def w_method(self)" From noreply at buildbot.pypy.org Tue Feb 19 00:05:43 2013 From: noreply at buildbot.pypy.org (amauryfa) Date: Tue, 19 Feb 2013 00:05:43 +0100 (CET) Subject: [pypy-commit] pypy py3k: Fix module/thread tests when run with -A Message-ID: <20130218230543.5A2DA1C0041@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: py3k Changeset: r61431:8cf7d95bda59 Date: 2013-02-18 23:51 +0100 http://bitbucket.org/pypy/pypy/changeset/8cf7d95bda59/ Log: Fix module/thread tests when run with -A diff --git a/pypy/module/thread/test/support.py b/pypy/module/thread/test/support.py --- a/pypy/module/thread/test/support.py +++ b/pypy/module/thread/test/support.py @@ -25,19 +25,20 @@ print '*** timed out ***' -def timeout_killer(pid, delay): +def timeout_killer(cls, pid, delay): def kill(): for x in range(delay * 10): time.sleep(0.1) try: os.kill(pid, 0) - except OSError, e: + except OSError as e: if e.errno == errno.ESRCH: # no such process return raise os.kill(pid, 9) - print "process %s killed!" % (pid,) - thread.start_new_thread(kill, ()) + print("process %s killed!" % (pid,)) + import threading + threading.Thread(target=kill).start() class GenericTestThread: @@ -45,21 +46,22 @@ def setup_class(cls): if cls.runappdirect: - def plain_waitfor(self, condition, delay=1): + cls.w_NORMAL_TIMEOUT = NORMAL_TIMEOUT + def plain_waitfor(cls, condition, delay=1): + import gc + import time adaptivedelay = 0.04 - limit = time.time() + NORMAL_TIMEOUT * delay + limit = time.time() + cls.NORMAL_TIMEOUT * delay while time.time() <= limit: time.sleep(adaptivedelay) gc.collect() if condition(): return adaptivedelay *= 1.05 - print '*** timed out ***' + print('*** timed out ***') cls.w_waitfor = plain_waitfor - def py_timeout_killer(self, *args, **kwargs): - timeout_killer(*args, **kwargs) - cls.w_timeout_killer = cls.space.wrap(py_timeout_killer) + cls.w_timeout_killer = timeout_killer else: @unwrap_spec(delay=int) def py_waitfor(space, w_condition, delay=1): @@ -73,7 +75,7 @@ (k, space.unwrap(v)) for k, v in kwargs_w.iteritems() ]) - timeout_killer(*args, **kwargs) + timeout_killer(cls, *args, **kwargs) cls.w_timeout_killer = cls.space.wrap(interp2app(py_timeout_killer)) cls.w_busywait = cls.space.appexec([], """(): diff --git a/pypy/module/thread/test/test_fork.py b/pypy/module/thread/test/test_fork.py --- a/pypy/module/thread/test/test_fork.py +++ b/pypy/module/thread/test/test_fork.py @@ -21,7 +21,7 @@ run = True done = [] try: - thread.start_new(busy_thread, ()) + _thread.start_new(busy_thread, ()) print('sleep') pid = os.fork() diff --git a/pypy/module/thread/test/test_thread.py b/pypy/module/thread/test/test_thread.py --- a/pypy/module/thread/test/test_thread.py +++ b/pypy/module/thread/test/test_thread.py @@ -224,8 +224,8 @@ if waiting: _thread.interrupt_main() return - print 'tock...', x # <-force the GIL to be released, as - time.sleep(0.01) # time.sleep doesn't do non-translated + print('tock...', x) # <-force the GIL to be released, as + time.sleep(0.01) # time.sleep doesn't do non-translated def busy_wait(): waiting.append(None) From noreply at buildbot.pypy.org Tue Feb 19 02:59:40 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Tue, 19 Feb 2013 02:59:40 +0100 (CET) Subject: [pypy-commit] pypy py3k: fix test_getfilesystemencoding, expect the canonical name Message-ID: <20130219015940.EDB791C0925@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61432:b8b7efb9610e Date: 2013-02-18 15:56 -0800 http://bitbucket.org/pypy/pypy/changeset/b8b7efb9610e/ Log: fix test_getfilesystemencoding, expect the canonical name diff --git a/pypy/module/sys/test/test_sysmodule.py b/pypy/module/sys/test/test_sysmodule.py --- a/pypy/module/sys/test/test_sysmodule.py +++ b/pypy/module/sys/test/test_sysmodule.py @@ -1,4 +1,5 @@ # -*- coding: iso-8859-1 -*- +import codecs import sys def test_stdin_exists(space): @@ -13,7 +14,8 @@ def setup_class(cls): cls.w_appdirect = cls.space.wrap(cls.runappdirect) - cls.w_filesystemenc = cls.space.wrap(sys.getfilesystemencoding()) + filesystemenc = codecs.lookup(sys.getfilesystemencoding()).name + cls.w_filesystemenc = cls.space.wrap(filesystemenc) def test_sys_in_modules(self): import sys From noreply at buildbot.pypy.org Tue Feb 19 02:59:42 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Tue, 19 Feb 2013 02:59:42 +0100 (CET) Subject: [pypy-commit] pypy py3k: fix test_lib_pypy Message-ID: <20130219015942.1BF631C0925@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61433:b7ec66cb08a1 Date: 2013-02-18 17:45 -0800 http://bitbucket.org/pypy/pypy/changeset/b7ec66cb08a1/ Log: fix test_lib_pypy diff --git a/lib_pypy/_functools.py b/lib_pypy/_functools.py --- a/lib_pypy/_functools.py +++ b/lib_pypy/_functools.py @@ -1,5 +1,6 @@ """ Supplies the internal functions for functools.py in the standard library """ -from __pypy__ import builtinify +try: from __pypy__ import builtinify +except ImportError: builtinify = lambda f: f sentinel = object() From noreply at buildbot.pypy.org Tue Feb 19 02:59:43 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Tue, 19 Feb 2013 02:59:43 +0100 (CET) Subject: [pypy-commit] pypy py3k: fix test_newformat.test_sign: update defaults per the new float str Message-ID: <20130219015943.540201C0925@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61434:52765baaf1aa Date: 2013-02-18 17:58 -0800 http://bitbucket.org/pypy/pypy/changeset/52765baaf1aa/ Log: fix test_newformat.test_sign: update defaults per the new float str diff --git a/pypy/objspace/std/newformat.py b/pypy/objspace/std/newformat.py --- a/pypy/objspace/std/newformat.py +++ b/pypy/objspace/std/newformat.py @@ -935,8 +935,8 @@ tp = self._type self._get_locale(tp) if tp == "\0": - tp = "g" - default_precision = 12 + tp = "r" + default_precision = 0 flags |= rfloat.DTSF_ADD_DOT_0 elif tp == "n": tp = "g" @@ -949,6 +949,8 @@ add_pct = False if self._precision == -1: self._precision = default_precision + if tp == "r": + type = "g" result, special = rfloat.double_to_string(value, tp, self._precision, flags) if add_pct: From noreply at buildbot.pypy.org Tue Feb 19 03:55:27 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Tue, 19 Feb 2013 03:55:27 +0100 (CET) Subject: [pypy-commit] pypy default: always inline this like look_inside_iff did Message-ID: <20130219025527.3E9131C0041@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61435:8b318447d03f Date: 2013-02-18 21:53 -0500 http://bitbucket.org/pypy/pypy/changeset/8b318447d03f/ Log: always inline this like look_inside_iff did diff --git a/pypy/module/__builtin__/functional.py b/pypy/module/__builtin__/functional.py --- a/pypy/module/__builtin__/functional.py +++ b/pypy/module/__builtin__/functional.py @@ -203,6 +203,7 @@ return min_max_unroll(space, args, implementation_of) else: return min_max_normal(space, args, implementation_of) +min_max._always_inline = True def max(space, __args__): """max(iterable[, key=func]) -> value From noreply at buildbot.pypy.org Tue Feb 19 03:58:14 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Tue, 19 Feb 2013 03:58:14 +0100 (CET) Subject: [pypy-commit] pypy py3k: 2to3 Message-ID: <20130219025814.ADA0C1C0041@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61436:77234913b6d6 Date: 2013-02-18 18:34 -0800 http://bitbucket.org/pypy/pypy/changeset/77234913b6d6/ Log: 2to3 diff --git a/pypy/objspace/std/test/test_obj.py b/pypy/objspace/std/test/test_obj.py --- a/pypy/objspace/std/test/test_obj.py +++ b/pypy/objspace/std/test/test_obj.py @@ -32,7 +32,7 @@ skip("on CPython >= 2.7, id != hash") import sys o = object() - assert (hash(o) & sys.maxint) == (id(o) & sys.maxint) + assert (hash(o) & sys.maxsize) == (id(o) & sys.maxsize) def test_hash_method(self): o = object() @@ -52,7 +52,7 @@ pass x = X() if self.cpython_behavior and self.cpython_version < (2, 7): - assert (hash(x) & sys.maxint) == (id(x) & sys.maxint) + assert (hash(x) & sys.maxsize) == (id(x) & sys.maxsize) assert hash(x) == object.__hash__(x) def test_reduce_recursion_bug(self): @@ -189,8 +189,8 @@ for i in range(10): l.append(float(i)) l.append(i + 0.1) - l.append(i + sys.maxint) - l.append(i - sys.maxint) + l.append(i + sys.maxsize) + l.append(i - sys.maxsize) l.append(i + 1j) l.append(1 + i * 1j) s = str(i) From noreply at buildbot.pypy.org Tue Feb 19 08:39:55 2013 From: noreply at buildbot.pypy.org (arigo) Date: Tue, 19 Feb 2013 08:39:55 +0100 (CET) Subject: [pypy-commit] pypy stm-thread-2: Hack hack hack at the caching logic. Gives 10%. Message-ID: <20130219073955.C85AF1C054C@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stm-thread-2 Changeset: r61437:5ea34af55891 Date: 2013-02-19 08:23 +0100 http://bitbucket.org/pypy/pypy/changeset/5ea34af55891/ Log: Hack hack hack at the caching logic. Gives 10%. diff --git a/rpython/translator/stm/src_stm/et.c b/rpython/translator/stm/src_stm/et.c --- a/rpython/translator/stm/src_stm/et.c +++ b/rpython/translator/stm/src_stm/et.c @@ -134,18 +134,17 @@ static inline gcptr AddInReadSet(struct tx_descriptor *d, gcptr R) { - switch (fxcache_add(&d->recent_reads_cache, R)) { - - case 0: + if (!fxcache_add(&d->recent_reads_cache, R)) { /* not in the cache: it may be the first time we see it, * so insert it into the list */ gcptrlist_insert(&d->list_of_read_objects, R); - break; + } + // break; - case 2: + // case 2: /* already in the cache, and FX_THRESHOLD reached */ - return Localize(d, R); - } + // return Localize(d, R); + // } return R; } @@ -387,7 +386,6 @@ gcptrlist_clear(&d->list_of_read_objects); gcptrlist_clear(&d->gcroots); g2l_clear(&d->global_to_local); - fxcache_clear(&d->recent_reads_cache); #ifdef RPY_STM_DEBUG_PRINT PYPY_DEBUG_START("stm-abort"); @@ -419,7 +417,7 @@ assert(d->list_of_read_objects.size == 0); assert(d->gcroots.size == 0); assert(!g2l_any_entry(&d->global_to_local)); - assert(fxcache_is_clear(&d->recent_reads_cache)); + fxcache_clear(&d->recent_reads_cache); } void BeginTransaction(jmp_buf* buf) @@ -600,7 +598,6 @@ /* we cannot abort any more from here */ d->setjmp_buf = NULL; gcptrlist_clear(&d->list_of_read_objects); - fxcache_clear(&d->recent_reads_cache); UpdateChainHeads(d, cur_time); diff --git a/rpython/translator/stm/src_stm/lists.c b/rpython/translator/stm/src_stm/lists.c --- a/rpython/translator/stm/src_stm/lists.c +++ b/rpython/translator/stm/src_stm/lists.c @@ -216,6 +216,13 @@ static void _gcptrlist_grow(struct GcPtrList *gcptrlist) { long newalloc = gcptrlist->alloc + (gcptrlist->alloc >> 1) + 16; + + PYPY_DEBUG_START("stm-growth"); + if (PYPY_HAVE_DEBUG_PRINTS) + { + fprintf(PYPY_DEBUG_FILE, "%ld KB\n", newalloc * sizeof(gcptr) / 1024); + } + gcptr *newitems = malloc(newalloc * sizeof(gcptr)); long i; for (i=0; isize; i++) @@ -223,6 +230,8 @@ free(gcptrlist->items); gcptrlist->items = newitems; gcptrlist->alloc = newalloc; + + PYPY_DEBUG_STOP("stm-growth"); } static inline void gcptrlist_insert(struct GcPtrList *gcptrlist, gcptr newitem) @@ -252,61 +261,68 @@ of collisions, old items are discarded. The eviction logic is a bit too simple for now. */ -#define FX_ENTRIES 32 -#define FX_SIZE (FX_ENTRIES * sizeof(revision_t)) -#define FX_THRESHOLD 5 - -#if FX_THRESHOLD >= FX_ENTRIES * 4 /* == lower bound on FX_SIZE */ -# error "if you increase FX_THRESHOLD, you must also increase FX_ENTRIES" -#endif +#define FX_ENTRIES 8192 +#define FX_ASSOC 1 +#define FX_SIZE (FX_ENTRIES * FX_ASSOC * sizeof(revision_t)) struct FXCache { - revision_t cache[FX_ENTRIES]; + char *cache_start; +#if FX_ASSOC > 1 + revision_t nextadd; +#endif + revision_t shift; + revision_t cache[FX_ENTRIES * FX_ASSOC * 2]; }; -static int fxcache_is_clear(struct FXCache *fxcache) -{ - int i; - for (i=0; icache[i]) - return 0; - return 1; -} - static void fxcache_clear(struct FXCache *fxcache) { - memset(fxcache, 0, sizeof(struct FXCache)); + fxcache->shift += FX_ASSOC; + if (fxcache->shift > (FX_ENTRIES - 1) * FX_ASSOC) { + memset(fxcache->cache, 0, 2 * FX_SIZE); + fxcache->shift = 0; + } + fxcache->cache_start = (char *)(fxcache->cache + fxcache->shift); } static inline int fxcache_add(struct FXCache *fxcache, gcptr item) { - /* If 'item' is not in the cache, add it with the value 0 and returns 0. - If it is already, increment its value and returns 1. - If it we reach FX_THRESHOLD, returns 2. + /* If 'item' is not in the cache, add it and returns 0. + If it is already, return 1. */ revision_t uitem = (revision_t)item; revision_t *entry = (revision_t *) - (((char *)fxcache->cache) + (uitem & (FX_SIZE-sizeof(revision_t)))); - revision_t stored_key = uitem & -FX_SIZE; - revision_t value = stored_key ^ *entry; - if (value >= FX_SIZE) - { - /* not in the cache: evict the colliding item (no associativity) */ - *entry = stored_key; - return 0; - } - else - { - /* already in the cache */ - if (value < FX_THRESHOLD) - { - ++value; - ++*entry; - return 1; - } - else - return 2; - } + (fxcache->cache_start + (uitem & (FX_SIZE-sizeof(revision_t)))); + + if (entry[0] == uitem +#if FX_ASSOC >= 2 + || entry[1] == uitem +#if FX_ASSOC >= 4 + || entry[2] == uitem || entry[3] == uitem +#if FX_ASSOC >= 8 + || entry[4] == uitem || entry[5] == uitem + || entry[6] == uitem || entry[7] == uitem +#if FX_ASSOC >= 16 + || entry[8] == uitem || entry[9] == uitem + || entry[10]== uitem || entry[11]== uitem + || entry[12]== uitem || entry[13]== uitem + || entry[14]== uitem || entry[15]== uitem +#if FX_ASSOC >= 32 +#error "FX_ASSOC is too large" +#endif /* 32 */ +#endif /* 16 */ +#endif /* 8 */ +#endif /* 4 */ +#endif /* 2 */ + ) + return 1; + +#if FX_ASSOC > 1 + entry[fxcache->nextadd] = uitem; + fxcache->nextadd = (fxcache->nextadd + 1) & (FX_ASSOC-1); +#else + entry[0] = uitem; +#endif + return 0; } /************************************************************/ From noreply at buildbot.pypy.org Tue Feb 19 08:39:57 2013 From: noreply at buildbot.pypy.org (arigo) Date: Tue, 19 Feb 2013 08:39:57 +0100 (CET) Subject: [pypy-commit] pypy stm-thread-2: Tweak tweak Message-ID: <20130219073957.0D6F01C070E@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stm-thread-2 Changeset: r61438:cadf477fe482 Date: 2013-02-19 08:35 +0100 http://bitbucket.org/pypy/pypy/changeset/cadf477fe482/ Log: Tweak tweak diff --git a/rpython/translator/stm/src_stm/lists.c b/rpython/translator/stm/src_stm/lists.c --- a/rpython/translator/stm/src_stm/lists.c +++ b/rpython/translator/stm/src_stm/lists.c @@ -261,24 +261,20 @@ of collisions, old items are discarded. The eviction logic is a bit too simple for now. */ -#define FX_ENTRIES 8192 -#define FX_ASSOC 1 -#define FX_SIZE (FX_ENTRIES * FX_ASSOC * sizeof(revision_t)) +#define FX_ENTRIES 8192 struct FXCache { char *cache_start; -#if FX_ASSOC > 1 revision_t nextadd; -#endif revision_t shift; - revision_t cache[FX_ENTRIES * FX_ASSOC * 2]; + revision_t cache[FX_ENTRIES * 2 * 2]; }; static void fxcache_clear(struct FXCache *fxcache) { - fxcache->shift += FX_ASSOC; - if (fxcache->shift > (FX_ENTRIES - 1) * FX_ASSOC) { - memset(fxcache->cache, 0, 2 * FX_SIZE); + fxcache->shift += 2; + if (fxcache->shift > FX_ENTRIES - 2) { + memset(fxcache->cache, 0, sizeof(fxcache->cache)); fxcache->shift = 0; } fxcache->cache_start = (char *)(fxcache->cache + fxcache->shift); @@ -291,37 +287,27 @@ */ revision_t uitem = (revision_t)item; revision_t *entry = (revision_t *) - (fxcache->cache_start + (uitem & (FX_SIZE-sizeof(revision_t)))); + (fxcache->cache_start + (uitem & ((FX_ENTRIES-1) * sizeof(revision_t)))); + revision_t current, *entry2; - if (entry[0] == uitem -#if FX_ASSOC >= 2 - || entry[1] == uitem -#if FX_ASSOC >= 4 - || entry[2] == uitem || entry[3] == uitem -#if FX_ASSOC >= 8 - || entry[4] == uitem || entry[5] == uitem - || entry[6] == uitem || entry[7] == uitem -#if FX_ASSOC >= 16 - || entry[8] == uitem || entry[9] == uitem - || entry[10]== uitem || entry[11]== uitem - || entry[12]== uitem || entry[13]== uitem - || entry[14]== uitem || entry[15]== uitem -#if FX_ASSOC >= 32 -#error "FX_ASSOC is too large" -#endif /* 32 */ -#endif /* 16 */ -#endif /* 8 */ -#endif /* 4 */ -#endif /* 2 */ - ) + current = entry[0]; + if (current == uitem) return 1; -#if FX_ASSOC > 1 - entry[fxcache->nextadd] = uitem; - fxcache->nextadd = (fxcache->nextadd + 1) & (FX_ASSOC-1); -#else - entry[0] = uitem; -#endif + entry2 = entry + FX_ENTRIES; + if (entry2[0] == uitem) { + entry2[0] = current; + entry[0] = uitem; + return 1; + } + if (entry2[1] == uitem) { + entry2[1] = current; + entry[0] = uitem; + return 1; + } + + entry2[fxcache->nextadd] = uitem; + fxcache->nextadd = (fxcache->nextadd + 1) & 1; return 0; } From noreply at buildbot.pypy.org Tue Feb 19 08:39:58 2013 From: noreply at buildbot.pypy.org (arigo) Date: Tue, 19 Feb 2013 08:39:58 +0100 (CET) Subject: [pypy-commit] pypy stm-thread-2: Backed out changeset cadf477fe482 Message-ID: <20130219073958.4674C1C054C@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stm-thread-2 Changeset: r61439:cf472783d88e Date: 2013-02-19 08:40 +0100 http://bitbucket.org/pypy/pypy/changeset/cf472783d88e/ Log: Backed out changeset cadf477fe482 I don't understand it at all, but it prevents parallel execution of richards. diff --git a/rpython/translator/stm/src_stm/lists.c b/rpython/translator/stm/src_stm/lists.c --- a/rpython/translator/stm/src_stm/lists.c +++ b/rpython/translator/stm/src_stm/lists.c @@ -261,20 +261,24 @@ of collisions, old items are discarded. The eviction logic is a bit too simple for now. */ -#define FX_ENTRIES 8192 +#define FX_ENTRIES 8192 +#define FX_ASSOC 1 +#define FX_SIZE (FX_ENTRIES * FX_ASSOC * sizeof(revision_t)) struct FXCache { char *cache_start; +#if FX_ASSOC > 1 revision_t nextadd; +#endif revision_t shift; - revision_t cache[FX_ENTRIES * 2 * 2]; + revision_t cache[FX_ENTRIES * FX_ASSOC * 2]; }; static void fxcache_clear(struct FXCache *fxcache) { - fxcache->shift += 2; - if (fxcache->shift > FX_ENTRIES - 2) { - memset(fxcache->cache, 0, sizeof(fxcache->cache)); + fxcache->shift += FX_ASSOC; + if (fxcache->shift > (FX_ENTRIES - 1) * FX_ASSOC) { + memset(fxcache->cache, 0, 2 * FX_SIZE); fxcache->shift = 0; } fxcache->cache_start = (char *)(fxcache->cache + fxcache->shift); @@ -287,27 +291,37 @@ */ revision_t uitem = (revision_t)item; revision_t *entry = (revision_t *) - (fxcache->cache_start + (uitem & ((FX_ENTRIES-1) * sizeof(revision_t)))); - revision_t current, *entry2; + (fxcache->cache_start + (uitem & (FX_SIZE-sizeof(revision_t)))); - current = entry[0]; - if (current == uitem) + if (entry[0] == uitem +#if FX_ASSOC >= 2 + || entry[1] == uitem +#if FX_ASSOC >= 4 + || entry[2] == uitem || entry[3] == uitem +#if FX_ASSOC >= 8 + || entry[4] == uitem || entry[5] == uitem + || entry[6] == uitem || entry[7] == uitem +#if FX_ASSOC >= 16 + || entry[8] == uitem || entry[9] == uitem + || entry[10]== uitem || entry[11]== uitem + || entry[12]== uitem || entry[13]== uitem + || entry[14]== uitem || entry[15]== uitem +#if FX_ASSOC >= 32 +#error "FX_ASSOC is too large" +#endif /* 32 */ +#endif /* 16 */ +#endif /* 8 */ +#endif /* 4 */ +#endif /* 2 */ + ) return 1; - entry2 = entry + FX_ENTRIES; - if (entry2[0] == uitem) { - entry2[0] = current; - entry[0] = uitem; - return 1; - } - if (entry2[1] == uitem) { - entry2[1] = current; - entry[0] = uitem; - return 1; - } - - entry2[fxcache->nextadd] = uitem; - fxcache->nextadd = (fxcache->nextadd + 1) & 1; +#if FX_ASSOC > 1 + entry[fxcache->nextadd] = uitem; + fxcache->nextadd = (fxcache->nextadd + 1) & (FX_ASSOC-1); +#else + entry[0] = uitem; +#endif return 0; } From noreply at buildbot.pypy.org Tue Feb 19 09:21:27 2013 From: noreply at buildbot.pypy.org (fijal) Date: Tue, 19 Feb 2013 09:21:27 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: Fixes for saving registers while reloading frame. Test coming Message-ID: <20130219082127.B9E771C05FF@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61440:ef27c4b585bb Date: 2013-02-19 10:20 +0200 http://bitbucket.org/pypy/pypy/changeset/ef27c4b585bb/ Log: Fixes for saving registers while reloading frame. Test coming diff --git a/rpython/jit/backend/llsupport/test/test_gc_integration.py b/rpython/jit/backend/llsupport/test/test_gc_integration.py --- a/rpython/jit/backend/llsupport/test/test_gc_integration.py +++ b/rpython/jit/backend/llsupport/test/test_gc_integration.py @@ -579,6 +579,10 @@ item = rffi.cast(lltype.Ptr(S), frame.jf_frame[gcmap[0]]) assert item == new_items[2] + def test_shadowstack_collecting_call_float(self): + cpu = self.cpu + xxx + def test_malloc_1(self): cpu = self.cpu sizeof = cpu.sizeof(self.S) diff --git a/rpython/jit/backend/x86/arch.py b/rpython/jit/backend/x86/arch.py --- a/rpython/jit/backend/x86/arch.py +++ b/rpython/jit/backend/x86/arch.py @@ -30,9 +30,9 @@ # start of every frame: the saved value of some registers if WORD == 4: - # ebp + ebx + esi + edi + 6 extra words + return address = 9 words - FRAME_FIXED_SIZE = 11 - PASS_ON_MY_FRAME = 6 + # ebp + ebx + esi + edi + 12 extra words + return address = 17 words + FRAME_FIXED_SIZE = 17 + PASS_ON_MY_FRAME = 12 JITFRAME_FIXED_SIZE = 6 + 8 * 2 # 6 GPR + 8 XMM * 2 WORDS/float else: # rbp + rbx + r12 + r13 + r14 + r15 + 12 extra words + return address = 19 diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -321,8 +321,12 @@ # we're possibly called from the slowpath of malloc, so we have # one extra CALL on the stack, but one less PUSH, # save to store stuff 2 locations away on the stack. + # we have to save all the things that can potentially + # be returned from a call mc.MOV_sr(3 * WORD, eax.value) # save for later + mc.MOVSD_sx(6 * WORD, xmm0.value) if IS_X86_32: + mc.MOV_sr(4 * WORD, edx.value) mc.SUB_ri(esp.value, 2 * WORD) # align mc.MOV_sr(0, ebp.value) else: @@ -351,6 +355,8 @@ else: if IS_X86_32: mc.LEA_rs(esp.value, 2 * WORD) + mc.MOV_rs(edx.value, 4 * WORD) + mc.MOVSD_xs(xmm0.value, 6 * WORD) mc.MOV_rs(eax.value, 3 * WORD) # restore mc.RET() From noreply at buildbot.pypy.org Tue Feb 19 09:26:37 2013 From: noreply at buildbot.pypy.org (amauryfa) Date: Tue, 19 Feb 2013 09:26:37 +0100 (CET) Subject: [pypy-commit] pypy py3k: Fix most -A tests in module/zipimport Message-ID: <20130219082637.E0D161C070E@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: py3k Changeset: r61441:1040bdcae4a0 Date: 2013-02-19 08:48 +0100 http://bitbucket.org/pypy/pypy/changeset/1040bdcae4a0/ Log: Fix most -A tests in module/zipimport diff --git a/pypy/module/zipimport/test/test_zipimport.py b/pypy/module/zipimport/test/test_zipimport.py --- a/pypy/module/zipimport/test/test_zipimport.py +++ b/pypy/module/zipimport/test/test_zipimport.py @@ -74,9 +74,10 @@ w_cache = space.getattr(space.getbuiltinmodule('zipimport'), space.wrap('_zip_directory_cache')) space.call_function(space.getattr(w_cache, space.wrap('clear'))) - self.w_modules = space.call_method( + self.w_modules = space.call_function( + space.w_list, space.getattr(space.getbuiltinmodule('sys'), - space.wrap('modules')), 'copy') + space.wrap('modules'))) def teardown_method(self, meth): space = self.space diff --git a/pypy/tool/pytest/apptest.py b/pypy/tool/pytest/apptest.py --- a/pypy/tool/pytest/apptest.py +++ b/pypy/tool/pytest/apptest.py @@ -88,7 +88,7 @@ elif isinstance(value, unicode): # python2 unicode -> python3 string defs.append("self.%s = %s\n" % (symbol, repr(value)[1:])) - elif isinstance(value, (int, float, list)): + elif isinstance(value, (int, float, list, dict)): defs.append("self.%s = %r\n" % (symbol, value)) source = py.code.Source(target_)[1:] pyfile = udir.join('src.py') diff --git a/pypy/tool/pytest/objspace.py b/pypy/tool/pytest/objspace.py --- a/pypy/tool/pytest/objspace.py +++ b/pypy/tool/pytest/objspace.py @@ -71,7 +71,7 @@ py.test.skip("cannot runappdirect test: space needs %s = %s, "\ "while pypy-c was built with %s" % (key, value, has)) - for name in ('int', 'long', 'str', 'unicode', 'None', 'ValueError', + for name in ('int', 'long', 'str', 'unicode', 'list', 'None', 'ValueError', 'OverflowError'): setattr(self, 'w_' + name, eval(name)) import __builtin__ as __builtin__ @@ -100,6 +100,9 @@ def str_w(self, w_str): return w_str + def bytes_w(self, w_bytes): + return w_bytes + def newdict(self, module=None): return {} From noreply at buildbot.pypy.org Tue Feb 19 09:26:39 2013 From: noreply at buildbot.pypy.org (amauryfa) Date: Tue, 19 Feb 2013 09:26:39 +0100 (CET) Subject: [pypy-commit] pypy py3k: Fix -A tests in module/select Message-ID: <20130219082639.4160F1C070E@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: py3k Changeset: r61442:24ac49ab776d Date: 2013-02-19 09:10 +0100 http://bitbucket.org/pypy/pypy/changeset/24ac49ab776d/ Log: Fix -A tests in module/select diff --git a/pypy/module/select/test/test_select.py b/pypy/module/select/test/test_select.py --- a/pypy/module/select/test/test_select.py +++ b/pypy/module/select/test/test_select.py @@ -267,34 +267,30 @@ "usemodules": ["select", "_socket", "rctime", "thread"], } - def setup_class(cls): - space = cls.space - w_import = space.getattr(space.builtin, space.wrap("__import__")) - w_socketmod = space.call_function(w_import, space.wrap("socket")) - cls.w_sock = cls.space.call_method(w_socketmod, "socket") - cls.w_sock_err = space.getattr(w_socketmod, space.wrap("error")) - - try_ports = [1023] + range(20000, 30000, 437) + def w_make_server(self): + import socket + if hasattr(self, 'sock'): + return self.sock + self.sock = socket.socket() + try_ports = [1023] + list(range(20000, 30000, 437)) for port in try_ports: - print 'binding to port %d:' % (port,), - cls.w_sockaddress = space.wrap(('127.0.0.1', port)) + print('binding to port %d:' % (port,)) + self.sockaddress = ('127.0.0.1', port) try: - space.call_method(cls.w_sock, "bind", cls.w_sockaddress) + self.sock.bind(self.sockaddress) break - except OperationError, e: # should get a "Permission denied" - if not e.match(space, space.getattr(w_socketmod, space.wrap("error"))): - raise - print e - except cls.w_sock_err, e: # should get a "Permission denied" - print e + except socket.error as e: # should get a "Permission denied" + print(e) else: - raise e + raise(e) def w_getpair(self): """Helper method which returns a pair of connected sockets.""" import socket import _thread + self.make_server() + self.sock.listen(1) s2 = socket.socket() _thread.start_new_thread(s2.connect, (self.sockaddress,)) From noreply at buildbot.pypy.org Tue Feb 19 09:26:40 2013 From: noreply at buildbot.pypy.org (amauryfa) Date: Tue, 19 Feb 2013 09:26:40 +0100 (CET) Subject: [pypy-commit] pypy py3k: Fix -A tests in module/_ffi/test/test_struct.py Message-ID: <20130219082640.718EB1C070E@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: py3k Changeset: r61443:aa318e7df3bb Date: 2013-02-19 09:16 +0100 http://bitbucket.org/pypy/pypy/changeset/aa318e7df3bb/ Log: Fix -A tests in module/_ffi/test/test_struct.py diff --git a/pypy/module/_ffi/test/test_struct.py b/pypy/module/_ffi/test/test_struct.py --- a/pypy/module/_ffi/test/test_struct.py +++ b/pypy/module/_ffi/test/test_struct.py @@ -40,23 +40,27 @@ class AppTestStruct(BaseAppTestFFI): + @classmethod + def read_raw_mem(cls, addr, typename, length): + import ctypes + addr = ctypes.cast(addr, ctypes.c_void_p) + c_type = getattr(ctypes, typename) + array_type = ctypes.POINTER(c_type * length) + ptr_array = ctypes.cast(addr, array_type) + array = ptr_array[0] + lst = [array[i] for i in range(length)] + return lst + def setup_class(cls): BaseAppTestFFI.setup_class.im_func(cls) - @unwrap_spec(addr=int, typename=str, length=int) - def read_raw_mem(space, addr, typename, length): - import ctypes - addr = ctypes.cast(addr, ctypes.c_void_p) - c_type = getattr(ctypes, typename) - array_type = ctypes.POINTER(c_type * length) - ptr_array = ctypes.cast(addr, array_type) - array = ptr_array[0] - lst = [array[i] for i in range(length)] - return space.wrap(lst) if cls.runappdirect: - cls.w_read_raw_mem = lambda self, *args: read_raw_mem(cls.space, *args) + cls.w_read_raw_mem = cls.read_raw_mem else: - cls.w_read_raw_mem = cls.space.wrap(interp2app(read_raw_mem)) + @unwrap_spec(addr=int, typename=str, length=int) + def read_raw_mem_w(space, addr, typename, length): + return space.wrap(cls.read_raw_mem(addr, typename, length)) + cls.w_read_raw_mem = cls.space.wrap(interp2app(read_raw_mem_w)) # from rpython.rlib import clibffi from rpython.rlib.rarithmetic import r_uint From noreply at buildbot.pypy.org Tue Feb 19 09:26:41 2013 From: noreply at buildbot.pypy.org (amauryfa) Date: Tue, 19 Feb 2013 09:26:41 +0100 (CET) Subject: [pypy-commit] pypy py3k: Fix many -A tests in module/gc Message-ID: <20130219082641.CDCB11C070E@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: py3k Changeset: r61444:5c2de72cbd70 Date: 2013-02-19 09:24 +0100 http://bitbucket.org/pypy/pypy/changeset/5c2de72cbd70/ Log: Fix many -A tests in module/gc diff --git a/pypy/module/gc/test/test_referents.py b/pypy/module/gc/test/test_referents.py --- a/pypy/module/gc/test/test_referents.py +++ b/pypy/module/gc/test/test_referents.py @@ -8,12 +8,16 @@ cls._backup = [rgc.get_rpy_roots] w = cls.space.wrap space = cls.space - class RandomRPythonObject(object): - pass + if option.runappdirect: + ro = None + else: + class RandomRPythonObject(object): + pass + ro = RandomRPythonObject() l4 = space.newlist([w(4)]) l2 = space.newlist([w(2)]) l7 = space.newlist([w(7)]) - cls.ALL_ROOTS = [l4, space.newlist([l2, l7]), RandomRPythonObject(), + cls.ALL_ROOTS = [l4, space.newlist([l2, l7]), ro, space.newtuple([l7])] cls.w_ALL_ROOTS = cls.space.newlist(cls.ALL_ROOTS) rgc.get_rpy_roots = lambda: ( From noreply at buildbot.pypy.org Tue Feb 19 09:39:09 2013 From: noreply at buildbot.pypy.org (fijal) Date: Tue, 19 Feb 2013 09:39:09 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: finish the test Message-ID: <20130219083909.123851C054C@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61445:2cd61d2ae502 Date: 2013-02-19 10:38 +0200 http://bitbucket.org/pypy/pypy/changeset/2cd61d2ae502/ Log: finish the test diff --git a/rpython/jit/backend/llsupport/test/test_gc_integration.py b/rpython/jit/backend/llsupport/test/test_gc_integration.py --- a/rpython/jit/backend/llsupport/test/test_gc_integration.py +++ b/rpython/jit/backend/llsupport/test/test_gc_integration.py @@ -581,7 +581,32 @@ def test_shadowstack_collecting_call_float(self): cpu = self.cpu - xxx + + def float_return(i, f): + # mark frame for write barrier + frame = rffi.cast(lltype.Ptr(JITFRAME), i) + frame.hdr |= 1 + return 1.2 + f + + FUNC = lltype.FuncType([lltype.Signed, lltype.Float], lltype.Float) + fptr = llhelper(lltype.Ptr(FUNC), float_return) + calldescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, + EffectInfo.MOST_GENERAL) + loop = self.parse(""" + [f0] + i = force_token() + f1 = call(ConstClass(fptr), i, f0, descr=calldescr) + finish(f1, descr=finaldescr) + """, namespace={'fptr': fptr, 'calldescr': calldescr, + 'finaldescr': BasicFinalDescr(1)}) + token = JitCellToken() + cpu.gc_ll_descr.init_nursery(20) + cpu.setup_once() + cpu.compile_loop(loop.inputargs, loop.operations, token) + frame = cpu.execute_token(token, 2.3) + ofs = cpu.get_baseofs_of_frame_field() + f = cpu.read_float_at_mem(frame, ofs) + assert f == 2.3 + 1.2 def test_malloc_1(self): cpu = self.cpu From noreply at buildbot.pypy.org Tue Feb 19 09:44:53 2013 From: noreply at buildbot.pypy.org (fijal) Date: Tue, 19 Feb 2013 09:44:53 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: fix those tests Message-ID: <20130219084453.526281C054C@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61446:b775d183cd6b Date: 2013-02-19 10:42 +0200 http://bitbucket.org/pypy/pypy/changeset/b775d183cd6b/ Log: fix those tests diff --git a/rpython/jit/backend/arm/test/test_runner.py b/rpython/jit/backend/arm/test/test_runner.py --- a/rpython/jit/backend/arm/test/test_runner.py +++ b/rpython/jit/backend/arm/test/test_runner.py @@ -67,7 +67,7 @@ def test_redirect_call_assembler2(self): def assembler_helper(deadframe, virtualizable): - x = self.cpu.get_latest_value_int(deadframe, 0) + x = self.cpu.get_int_value(deadframe, 0) assert x == 11 return 7 @@ -104,11 +104,11 @@ self.cpu.compile_loop(loop3.inputargs, loop3.operations, lt3) self.cpu.compile_loop(loop1.inputargs, loop1.operations, lt1) df = self.cpu.execute_token(lt1, 10) - assert self.cpu.get_latest_value_int(df, 0) == 7 + assert self.cpu.get_int_value(df, 0) == 7 self.cpu.redirect_call_assembler(lt2, lt3) df = self.cpu.execute_token(lt1, 12) - assert self.cpu.get_latest_value_int(df, 0) == 7 + assert self.cpu.get_int_value(df, 0) == 7 SFloat = lltype.GcForwardReference() SFloat.become(lltype.GcStruct('SFloat', ('parent', rclass.OBJECT), @@ -205,7 +205,7 @@ RES = lltype.Signed args = [i+1 for i in range(numargs)] deadframe = self.cpu.execute_token(looptoken, *args) - assert self.cpu.get_latest_value_int(deadframe, 0) == sum(args) + assert self.cpu.get_int_value(deadframe, 0) == sum(args) def test_debugger_on(self): from rpython.rlib import debug From noreply at buildbot.pypy.org Tue Feb 19 09:45:31 2013 From: noreply at buildbot.pypy.org (fijal) Date: Tue, 19 Feb 2013 09:45:31 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: seems to not be needed Message-ID: <20130219084531.50B611C054C@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61447:d23fa8f66359 Date: 2013-02-19 10:44 +0200 http://bitbucket.org/pypy/pypy/changeset/d23fa8f66359/ Log: seems to not be needed diff --git a/rpython/jit/backend/arm/test/test_runner.py b/rpython/jit/backend/arm/test/test_runner.py --- a/rpython/jit/backend/arm/test/test_runner.py +++ b/rpython/jit/backend/arm/test/test_runner.py @@ -179,8 +179,6 @@ def test_compile_loop_many_int_args(self): for numargs in range(2, 30): - for _ in range(numargs): - self.cpu.reserve_some_free_fail_descr_number() ops = [] arglist = "[%s]\n" % ", ".join(["i%d" % i for i in range(numargs)]) ops.append(arglist) @@ -199,7 +197,6 @@ ops = "".join(ops) loop = parse(ops) looptoken = JitCellToken() - done_number = self.cpu.get_fail_descr_number(loop.operations[-1].getdescr()) self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) ARGS = [lltype.Signed] * numargs RES = lltype.Signed From noreply at buildbot.pypy.org Tue Feb 19 09:47:07 2013 From: noreply at buildbot.pypy.org (fijal) Date: Tue, 19 Feb 2013 09:47:07 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: skip this test for now Message-ID: <20130219084707.B9AE21C054C@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61448:cc18440fa530 Date: 2013-02-19 10:46 +0200 http://bitbucket.org/pypy/pypy/changeset/cc18440fa530/ Log: skip this test for now diff --git a/rpython/jit/backend/arm/test/test_runner.py b/rpython/jit/backend/arm/test/test_runner.py --- a/rpython/jit/backend/arm/test/test_runner.py +++ b/rpython/jit/backend/arm/test/test_runner.py @@ -205,6 +205,7 @@ assert self.cpu.get_int_value(deadframe, 0) == sum(args) def test_debugger_on(self): + py.test.skip("I don't care for now") from rpython.rlib import debug targettoken, preambletoken = TargetToken(), TargetToken() From noreply at buildbot.pypy.org Tue Feb 19 10:42:27 2013 From: noreply at buildbot.pypy.org (fijal) Date: Tue, 19 Feb 2013 10:42:27 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: better safe than sorry Message-ID: <20130219094227.917631C054C@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61449:4d773b5d16f7 Date: 2013-02-19 11:40 +0200 http://bitbucket.org/pypy/pypy/changeset/4d773b5d16f7/ Log: better safe than sorry diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -323,11 +323,11 @@ # save to store stuff 2 locations away on the stack. # we have to save all the things that can potentially # be returned from a call - mc.MOV_sr(3 * WORD, eax.value) # save for later - mc.MOVSD_sx(6 * WORD, xmm0.value) + mc.SUB_ri(esp.value, 6 * WORD) # align and reserve some space + mc.MOV_sr(WORD, eax.value) # save for later + mc.MOVSD_sx(3 * WORD, xmm0.value) if IS_X86_32: mc.MOV_sr(4 * WORD, edx.value) - mc.SUB_ri(esp.value, 2 * WORD) # align mc.MOV_sr(0, ebp.value) else: mc.MOV_rr(edi.value, ebp.value) @@ -354,10 +354,10 @@ mc.RET16_i(WORD) else: if IS_X86_32: - mc.LEA_rs(esp.value, 2 * WORD) mc.MOV_rs(edx.value, 4 * WORD) - mc.MOVSD_xs(xmm0.value, 6 * WORD) - mc.MOV_rs(eax.value, 3 * WORD) # restore + mc.MOVSD_xs(xmm0.value, 3 * WORD) + mc.MOV_rs(eax.value, WORD) # restore + mc.LEA_rs(esp.value, 6 * WORD) mc.RET() rawstart = mc.materialize(self.cpu.asmmemmgr, []) From noreply at buildbot.pypy.org Tue Feb 19 11:06:01 2013 From: noreply at buildbot.pypy.org (bivab) Date: Tue, 19 Feb 2013 11:06:01 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: fix emit_guard_call_release_gil, correctly slice arglocs. (test_call_to_c_function now works) Message-ID: <20130219100601.5039D1C05FF@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: jitframe-on-heap Changeset: r61450:37b92dfb2934 Date: 2013-02-19 11:05 +0100 http://bitbucket.org/pypy/pypy/changeset/37b92dfb2934/ Log: fix emit_guard_call_release_gil, correctly slice arglocs. (test_call_to_c_function now works) diff --git a/rpython/jit/backend/arm/opassembler.py b/rpython/jit/backend/arm/opassembler.py --- a/rpython/jit/backend/arm/opassembler.py +++ b/rpython/jit/backend/arm/opassembler.py @@ -1234,7 +1234,7 @@ if gcrootmap: self.call_reacquire_gil(gcrootmap, resloc, fcond) - self._emit_guard_may_force(guard_op, arglocs, numargs) + self._emit_guard_may_force(guard_op, arglocs[numargs+1:], numargs) return fcond def call_release_gil(self, gcrootmap, save_registers, fcond): From noreply at buildbot.pypy.org Tue Feb 19 11:21:22 2013 From: noreply at buildbot.pypy.org (arigo) Date: Tue, 19 Feb 2013 11:21:22 +0100 (CET) Subject: [pypy-commit] pypy stm-thread-2: Improve caching, and reduce the cache's total size. Message-ID: <20130219102122.34BEF1C05FF@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stm-thread-2 Changeset: r61451:17cb3cfea9d6 Date: 2013-02-19 10:45 +0100 http://bitbucket.org/pypy/pypy/changeset/17cb3cfea9d6/ Log: Improve caching, and reduce the cache's total size. diff --git a/rpython/translator/stm/src_stm/lists.c b/rpython/translator/stm/src_stm/lists.c --- a/rpython/translator/stm/src_stm/lists.c +++ b/rpython/translator/stm/src_stm/lists.c @@ -258,22 +258,31 @@ /* The fxcache_xx functions implement a fixed-size set of gcptr's. Moreover the gcptr's in the set are mapped to small integers. In case - of collisions, old items are discarded. The eviction logic is a bit - too simple for now. */ + of collisions, old items are discarded. The cache uses 3-way caching + and the cache entries are aligned to two, which means that the items + 0 and 2 can collide with the bordering cache rows, but not item 1. + + The cache itself uses a total of FX_ENTRIES+1 entries in the 'cache' + array below, starting at 'cache_start'. The reason it is bigger is + that fxcache_clear() simply shifts 'cache_start', making any previous + entries invalid by not being in the correct position any more. +*/ #define FX_ENTRIES 8192 +#define FX_TOTAL (FX_ENTRIES * 2) struct FXCache { char *cache_start; revision_t nextadd; revision_t shift; - revision_t cache[FX_ENTRIES * 2 * 2]; + revision_t cache[FX_TOTAL]; }; static void fxcache_clear(struct FXCache *fxcache) { - fxcache->shift += 2; - if (fxcache->shift > FX_ENTRIES - 2) { + fxcache->shift += 4; + /* FX_ENTRIES+1 entries are needed */ + if (fxcache->shift + FX_ENTRIES + 1 > FX_TOTAL) { memset(fxcache->cache, 0, sizeof(fxcache->cache)); fxcache->shift = 0; } @@ -286,28 +295,28 @@ If it is already, return 1. */ revision_t uitem = (revision_t)item; + /* 'entry' points to 'cache_start[mask of uitem, even-valued]' */ revision_t *entry = (revision_t *) - (fxcache->cache_start + (uitem & ((FX_ENTRIES-1) * sizeof(revision_t)))); - revision_t current, *entry2; + (fxcache->cache_start + (uitem & ((FX_ENTRIES-2) * sizeof(revision_t)))); + revision_t current; - current = entry[0]; + current = entry[1]; /* first look here, the cache-private entry */ if (current == uitem) return 1; - entry2 = entry + FX_ENTRIES; - if (entry2[0] == uitem) { - entry2[0] = current; - entry[0] = uitem; + if (entry[0] == uitem) { + entry[0] = current; /* move from this collidable entry to */ + entry[1] = uitem; /* the cache-private entry */ return 1; } - if (entry2[1] == uitem) { - entry2[1] = current; - entry[0] = uitem; + if (entry[2] == uitem) { + entry[2] = current; /* move from this collidable entry to */ + entry[1] = uitem; /* the cache-private entry */ return 1; } - entry2[fxcache->nextadd] = uitem; - fxcache->nextadd = (fxcache->nextadd + 1) & 1; + entry[fxcache->nextadd] = uitem; + fxcache->nextadd ^= 2; return 0; } From noreply at buildbot.pypy.org Tue Feb 19 11:21:23 2013 From: noreply at buildbot.pypy.org (arigo) Date: Tue, 19 Feb 2013 11:21:23 +0100 (CET) Subject: [pypy-commit] pypy stm-thread-2: dummy merge to get rid of the backout Message-ID: <20130219102123.7417E1C070E@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stm-thread-2 Changeset: r61452:a226996373a5 Date: 2013-02-19 10:46 +0100 http://bitbucket.org/pypy/pypy/changeset/a226996373a5/ Log: dummy merge to get rid of the backout From noreply at buildbot.pypy.org Tue Feb 19 11:21:24 2013 From: noreply at buildbot.pypy.org (arigo) Date: Tue, 19 Feb 2013 11:21:24 +0100 (CET) Subject: [pypy-commit] pypy stm-thread-2: Found it: by making the cache more efficient, len(gcptrlist) doesn't Message-ID: <20130219102124.93FFF1C05FF@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stm-thread-2 Changeset: r61453:33549d9b2cbd Date: 2013-02-19 10:53 +0100 http://bitbucket.org/pypy/pypy/changeset/33549d9b2cbd/ Log: Found it: by making the cache more efficient, len(gcptrlist) doesn't increase much any more, but it was used as an indicator for starting the next transaction. This would make very long transactions for no reason. diff --git a/rpython/translator/stm/src_stm/et.c b/rpython/translator/stm/src_stm/et.c --- a/rpython/translator/stm/src_stm/et.c +++ b/rpython/translator/stm/src_stm/et.c @@ -43,6 +43,7 @@ revision_t start_time; revision_t my_lock; long atomic; /* 0 = not atomic, > 0 atomic */ + long count_reads; long reads_size_limit, reads_size_limit_nonatomic; /* see should_break_tr. */ int active; /* 0 = inactive, 1 = regular, 2 = inevitable */ int readonly_updates; @@ -134,6 +135,7 @@ static inline gcptr AddInReadSet(struct tx_descriptor *d, gcptr R) { + d->count_reads++; if (!fxcache_add(&d->recent_reads_cache, R)) { /* not in the cache: it may be the first time we see it, * so insert it into the list */ @@ -245,6 +247,7 @@ assert(L->h_tid & GCFLAG_NOT_WRITTEN); /* must not be set in the 1st place */ L->h_revision = (revision_t)R; /* back-reference to the original */ g2l_insert(&d->global_to_local, R, L); + d->count_reads++; gcptrlist_insert(&d->list_of_read_objects, R); return L; } @@ -377,7 +380,7 @@ /* upon abort, set the reads size limit to 94% of how much was read so far. This should ensure that, assuming the retry does the same thing, it will commit just before it reaches the conflicting point. */ - limit = d->list_of_read_objects.size; + limit = d->count_reads; if (limit > 0) { limit -= (limit >> 4); d->reads_size_limit_nonatomic = limit; @@ -417,6 +420,7 @@ assert(d->list_of_read_objects.size == 0); assert(d->gcroots.size == 0); assert(!g2l_any_entry(&d->global_to_local)); + d->count_reads = 0; fxcache_clear(&d->recent_reads_cache); } diff --git a/rpython/translator/stm/src_stm/rpyintf.c b/rpython/translator/stm/src_stm/rpyintf.c --- a/rpython/translator/stm/src_stm/rpyintf.c +++ b/rpython/translator/stm/src_stm/rpyintf.c @@ -91,7 +91,7 @@ reads_size_limit_nonatomic to 0 in that case. - finally, the default case: return True if - d->list_of_read_objects.size is + d->count_reads is greater than reads_size_limit == reads_size_limit_nonatomic. */ #ifdef RPY_STM_ASSERT @@ -105,7 +105,7 @@ assert(d->reads_size_limit_nonatomic == 0); #endif - return d->list_of_read_objects.size >= d->reads_size_limit; + return d->count_reads >= d->reads_size_limit; } void stm_set_transaction_length(long length_max) From noreply at buildbot.pypy.org Tue Feb 19 11:21:25 2013 From: noreply at buildbot.pypy.org (arigo) Date: Tue, 19 Feb 2013 11:21:25 +0100 (CET) Subject: [pypy-commit] pypy stm-thread-2: Now we need to increase a bit the checkinterval(). Message-ID: <20130219102125.B3A931C05FF@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stm-thread-2 Changeset: r61454:edea071e1cf5 Date: 2013-02-19 11:21 +0100 http://bitbucket.org/pypy/pypy/changeset/edea071e1cf5/ Log: Now we need to increase a bit the checkinterval(). diff --git a/pypy/module/thread/stm.py b/pypy/module/thread/stm.py --- a/pypy/module/thread/stm.py +++ b/pypy/module/thread/stm.py @@ -19,9 +19,9 @@ """NOT_RPYTHON: set up a mechanism to send to the C code the value set by space.actionflag.setcheckinterval().""" # - # Set the default checkinterval to 50000, found by exploration to + # Set the default checkinterval to 200000, found by exploration to # be a good default value. XXX do some more in-depth tests - space.actionflag.setcheckinterval(50000) + space.actionflag.setcheckinterval(200000) # def setcheckinterval_callback(): self.configure_transaction_length(space) diff --git a/rpython/translator/stm/src_stm/et.c b/rpython/translator/stm/src_stm/et.c --- a/rpython/translator/stm/src_stm/et.c +++ b/rpython/translator/stm/src_stm/et.c @@ -43,8 +43,9 @@ revision_t start_time; revision_t my_lock; long atomic; /* 0 = not atomic, > 0 atomic */ - long count_reads; - long reads_size_limit, reads_size_limit_nonatomic; /* see should_break_tr. */ + unsigned long count_reads; + unsigned long reads_size_limit; /* see should_break_tr. */ + unsigned long reads_size_limit_nonatomic; int active; /* 0 = inactive, 1 = regular, 2 = inevitable */ int readonly_updates; unsigned int num_commits; @@ -369,7 +370,7 @@ static void AbortTransaction(int num) { struct tx_descriptor *d = thread_descriptor; - long limit; + unsigned long limit; assert(d->active); assert(!is_inevitable(d)); assert(num < ABORT_REASONS); @@ -409,9 +410,9 @@ static void update_reads_size_limit(struct tx_descriptor *d) { - /* 'reads_size_limit' is set to LONG_MAX if we are atomic; else + /* 'reads_size_limit' is set to ULONG_MAX if we are atomic; else we copy the value from reads_size_limit_nonatomic. */ - d->reads_size_limit = d->atomic ? LONG_MAX : d->reads_size_limit_nonatomic; + d->reads_size_limit = d->atomic ? ULONG_MAX : d->reads_size_limit_nonatomic; } static void init_transaction(struct tx_descriptor *d) diff --git a/rpython/translator/stm/src_stm/rpyintf.c b/rpython/translator/stm/src_stm/rpyintf.c --- a/rpython/translator/stm/src_stm/rpyintf.c +++ b/rpython/translator/stm/src_stm/rpyintf.c @@ -62,7 +62,7 @@ return is_inevitable(d); } -static long stm_regular_length_limit = LONG_MAX; +static unsigned long stm_regular_length_limit = ULONG_MAX; void stm_add_atomic(long delta) { @@ -84,7 +84,7 @@ /* a single comparison to handle all cases: - if d->atomic, then we should return False. This is done by - forcing reads_size_limit to LONG_MAX as soon as atomic > 0. + forcing reads_size_limit to ULONG_MAX as soon as atomic > 0. - otherwise, if is_inevitable(), then we should return True. This is done by forcing both reads_size_limit and @@ -95,9 +95,9 @@ greater than reads_size_limit == reads_size_limit_nonatomic. */ #ifdef RPY_STM_ASSERT - /* reads_size_limit is LONG_MAX if d->atomic, or else it is equal to + /* reads_size_limit is ULONG_MAX if d->atomic, or else it is equal to reads_size_limit_nonatomic. */ - assert(d->reads_size_limit == (d->atomic ? LONG_MAX : + assert(d->reads_size_limit == (d->atomic ? ULONG_MAX : d->reads_size_limit_nonatomic)); /* if is_inevitable(), reads_size_limit_nonatomic should be 0 (and thus reads_size_limit too, if !d->atomic.) */ @@ -105,13 +105,15 @@ assert(d->reads_size_limit_nonatomic == 0); #endif - return d->count_reads >= d->reads_size_limit; + return d->count_reads > d->reads_size_limit; } void stm_set_transaction_length(long length_max) { struct tx_descriptor *d = thread_descriptor; BecomeInevitable("set_transaction_length"); + if (length_max <= 0) + length_max = 1; stm_regular_length_limit = length_max; } @@ -160,7 +162,7 @@ When such a shortened transaction succeeds, the next one will see its length limit doubled, up to the maximum. */ if (counter == 0) { - long limit = d->reads_size_limit_nonatomic; + unsigned long limit = d->reads_size_limit_nonatomic; if (limit != 0 && limit < (stm_regular_length_limit >> 1)) limit = (limit << 1) | 1; else diff --git a/rpython/translator/stm/test/richards.py b/rpython/translator/stm/test/richards.py --- a/rpython/translator/stm/test/richards.py +++ b/rpython/translator/stm/test/richards.py @@ -439,9 +439,12 @@ if len(sys.argv) > 2: max_num_threads = int(sys.argv[2]) assert max_num_threads <= iterations + if len(sys.argv) > 3: + sys.setcheckinterval(int(sys.argv[3])) else: iterations = 10 num_threads = min(iterations, max_num_threads) - print "Running %d iterations on %d threads" % (iterations, num_threads) + print "Running %d iterations on %d threads; checkinterval=%d" % ( + iterations, num_threads, sys.getcheckinterval()) transaction.set_num_threads(num_threads) main(iterations = iterations) From noreply at buildbot.pypy.org Tue Feb 19 11:52:24 2013 From: noreply at buildbot.pypy.org (arigo) Date: Tue, 19 Feb 2013 11:52:24 +0100 (CET) Subject: [pypy-commit] pypy stm-thread-2: Turn off these costly checks. Message-ID: <20130219105224.7116B1C054C@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stm-thread-2 Changeset: r61455:fe9e743bc504 Date: 2013-02-19 11:52 +0100 http://bitbucket.org/pypy/pypy/changeset/fe9e743bc504/ Log: Turn off these costly checks. diff --git a/rpython/translator/stm/src_stm/rpyintf.c b/rpython/translator/stm/src_stm/rpyintf.c --- a/rpython/translator/stm/src_stm/rpyintf.c +++ b/rpython/translator/stm/src_stm/rpyintf.c @@ -94,7 +94,7 @@ d->count_reads is greater than reads_size_limit == reads_size_limit_nonatomic. */ -#ifdef RPY_STM_ASSERT +#if 0 /* ifdef RPY_STM_ASSERT */ /* reads_size_limit is ULONG_MAX if d->atomic, or else it is equal to reads_size_limit_nonatomic. */ assert(d->reads_size_limit == (d->atomic ? ULONG_MAX : From noreply at buildbot.pypy.org Tue Feb 19 11:53:31 2013 From: noreply at buildbot.pypy.org (bivab) Date: Tue, 19 Feb 2013 11:53:31 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: fix for viewcode's machine detection Message-ID: <20130219105331.451221C054C@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: jitframe-on-heap Changeset: r61456:cdcbff0cbfc0 Date: 2013-02-19 11:51 +0100 http://bitbucket.org/pypy/pypy/changeset/cdcbff0cbfc0/ Log: fix for viewcode's machine detection diff --git a/rpython/jit/backend/tool/viewcode.py b/rpython/jit/backend/tool/viewcode.py --- a/rpython/jit/backend/tool/viewcode.py +++ b/rpython/jit/backend/tool/viewcode.py @@ -69,7 +69,7 @@ 'file': tmpfile, 'origin': originaddr, 'backend': objdump_backend_option[backend_name], - 'machine': 'i386' if backend_name != 'arm' else 'arm', + 'machine': 'i386' if not backend_name.startswith('arm') else 'arm', }, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = p.communicate() assert not p.returncode, ('Encountered an error running objdump: %s' % From noreply at buildbot.pypy.org Tue Feb 19 11:53:32 2013 From: noreply at buildbot.pypy.org (bivab) Date: Tue, 19 Feb 2013 11:53:32 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: fix for test_jump on ARM Message-ID: <20130219105332.8727D1C054C@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: jitframe-on-heap Changeset: r61457:4f99e4952fca Date: 2013-02-19 11:51 +0100 http://bitbucket.org/pypy/pypy/changeset/4f99e4952fca/ Log: fix for test_jump on ARM diff --git a/rpython/jit/backend/arm/test/test_jump.py b/rpython/jit/backend/arm/test/test_jump.py --- a/rpython/jit/backend/arm/test/test_jump.py +++ b/rpython/jit/backend/arm/test/test_jump.py @@ -6,7 +6,8 @@ from rpython.jit.backend.arm.jump import remap_frame_layout, remap_frame_layout_mixed from rpython.jit.metainterp.history import INT -frame_pos = ARMFrameManager.frame_pos +fm = ARMFrameManager(0) +frame_pos = fm.frame_pos class MockAssembler: def __init__(self): From noreply at buildbot.pypy.org Tue Feb 19 11:53:33 2013 From: noreply at buildbot.pypy.org (bivab) Date: Tue, 19 Feb 2013 11:53:33 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: start fixing test_compile_asmlen Message-ID: <20130219105333.B5EEE1C054C@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: jitframe-on-heap Changeset: r61458:11ac43885b18 Date: 2013-02-19 11:52 +0100 http://bitbucket.org/pypy/pypy/changeset/11ac43885b18/ Log: start fixing test_compile_asmlen diff --git a/rpython/jit/backend/arm/test/test_runner.py b/rpython/jit/backend/arm/test/test_runner.py --- a/rpython/jit/backend/arm/test/test_runner.py +++ b/rpython/jit/backend/arm/test/test_runner.py @@ -23,8 +23,7 @@ # for the individual tests see # ====> ../../test/runner_test.py - add_loop_instructions = ['nop', # this is the same as mov r0, r0 - 'adds', 'cmp', 'beq', 'b'] + add_loop_instructions = ['ldr', 'mov', 'adds', 'cmp', 'beq', 'b'] bridge_loop_instructions = ['movw', 'movt', 'bx'] def get_cpu(self): From noreply at buildbot.pypy.org Tue Feb 19 13:33:59 2013 From: noreply at buildbot.pypy.org (lwassermann) Date: Tue, 19 Feb 2013 13:33:59 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: (lwassermann, cfbolz): implemented bytecode 143: pushBlockClosure Message-ID: <20130219123359.405121C05FF@cobra.cs.uni-duesseldorf.de> Author: Lars Wassermann Branch: Changeset: r57:c0ed35e84d1b Date: 2013-02-19 13:24 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/c0ed35e84d1b/ Log: (lwassermann, cfbolz): implemented bytecode 143: pushBlockClosure implemented BlockClosureWrapper diff --git a/spyvm/constants.py b/spyvm/constants.py --- a/spyvm/constants.py +++ b/spyvm/constants.py @@ -42,6 +42,9 @@ MTHDCTX_RECEIVER = 5 MTHDCTX_TEMP_FRAME_START = 6 +# BlockClosure < Object +BLOCKCLOSURE_SIZE = 3 + # ___________________________________________________________________________ # Miscellaneous constants @@ -104,7 +107,7 @@ "Float" : SO_FLOAT_CLASS, "MethodContext" : SO_METHODCONTEXT_CLASS, "BlockContext" : SO_BLOCKCONTEXT_CLASS, - # "BlockClosure" : SO_BLOCKCLOSURE_CLASS, + "BlockClosure" : SO_BLOCKCLOSURE_CLASS, "Point" : SO_POINT_CLASS, "LargePositiveInteger" : SO_LARGEPOSITIVEINTEGER_CLASS, # "Display" : SO_DISPLAY_CLASS, diff --git a/spyvm/interpreter.py b/spyvm/interpreter.py --- a/spyvm/interpreter.py +++ b/spyvm/interpreter.py @@ -423,17 +423,26 @@ copiedValues: copiedValues). self jump: blockSize """ + space = self.space numArgs, numCopied = splitter[4, 4](self.getbytecode()) j = self.getbytecode() i = self.getbytecode() blockSize = (j << 8) | i - copiedValues = interp.space.w_nil + #create new instance of BlockClosure + BlockClosureShadow = space.w_BlockClosure.as_class_get_shadow(space) + w_closure = BlockClosureShadow.new(numCopied) + closure = wrapper.BlockClosureWrapper(space, w_closure) + closure.store_outerContext(self._w_self) + closure.store_startpc(self.pc()) + closure.store_numArgs(numArgs) if numCopied > 0: - copiedValues = interp.space.wrap_list(self.pop_and_return_n(numCopied)) - self.push(interp.space.w_nil) + copiedValues = self.pop_and_return_n(numCopied) + for i0 in range(numCopied): + w_closure.atput0(space, i0, copiedValues[i0]) + self.push(w_closure) self.jump(blockSize) - def jump(self,offset): + def jump(self, offset): self.store_pc(self.pc() + offset) def jumpConditional(self,bool,position): diff --git a/spyvm/objspace.py b/spyvm/objspace.py --- a/spyvm/objspace.py +++ b/spyvm/objspace.py @@ -113,7 +113,9 @@ define_cls("w_Semaphore", "w_LinkedList") define_cls("w_BlockContext", "w_ContextPart", instvarsize=constants.BLKCTX_STACK_START) - + define_cls("w_BlockClosure", "w_Object", + instvarsize=constants.BLOCKCLOSURE_SIZE, + varsized=True) # make better accessors for classes that can be found in special object # table for name in constants.classes_in_special_object_table.keys(): diff --git a/spyvm/test/test_interpreter.py b/spyvm/test/test_interpreter.py --- a/spyvm/test/test_interpreter.py +++ b/spyvm/test/test_interpreter.py @@ -1,6 +1,6 @@ import py from spyvm import model, interpreter, primitives, shadow -from spyvm import objspace +from spyvm import objspace, wrapper mockclass = objspace.bootstrap_class @@ -868,7 +868,7 @@ temp_array = space.w_Array.as_class_get_shadow(interp.space).new(3) temp_array.atput0(space, 2, fakeliterals(space, "pub")) context.settemp(1, temp_array) - interp.step(interp.s_active_context()) + interp.step(context) return context, temp_array def test_pushTempAt3InTempVectorAt1(bytecode = pushTempAtInTempVectorAt): @@ -885,12 +885,28 @@ assert temp_array.at0(space, 2) == fakeliterals(space, "bar") assert context.top() == fakeliterals(space, "english") -def test_pushClosureNumCopiedNumArgsBlockSize(bytecode = pushClosureNumCopiedNumArgsBlockSize): - for i in range(0, 65536, 7): - interp = new_interpreter(bytecode + chr(2) + chr(i >> 8) + chr(i & 0xFF)) - context = interp.s_active_context() - pc = context.pc() - # create/find a method with an appropriate blockClosure - interp.step(interp.s_active_context()) - assert context.pc() == pc + 4 + i - # assert that the right blockClosure has been pushed \ No newline at end of file +def test_pushClosureNumCopied0NumArgsBlockSize(bytecode = pushClosureNumCopiedNumArgsBlockSize): + for i in (0, 0xF0, 0x0FF0, 0xFFF0): + interp = new_interpreter(bytecode + chr(2) + chr(i >> 8) + chr(i & 0xFF)) + context = interp.s_active_context() + pc = context.pc() + # create/find a method with an appropriate blockClosure + interp.step(context) + assert context.pc() == pc + 4 + i + closure = wrapper.BlockClosureWrapper(space, context.top()) + assert closure.startpc() == pc + 4 + assert closure.outerContext() is context._w_self + +def test_pushClosureNumCopied2NumArgsBlockSize(bytecode = pushClosureNumCopiedNumArgsBlockSize): + interp = new_interpreter(bytecode + chr(0x23) + chr(0) + chr(0)) + context = interp.s_active_context() + context.push("english") + context.push("bar") + pc = context.pc() + interp.step(context) + assert context.pc() == pc + 4 + closure = wrapper.BlockClosureWrapper(space, context.top()) + assert closure.startpc() == pc + 4 + assert closure.outerContext() is context._w_self + assert closure.w_self.at0(space, 0) == "english" + assert closure.w_self.at0(space, 1) == "bar" diff --git a/spyvm/wrapper.py b/spyvm/wrapper.py --- a/spyvm/wrapper.py +++ b/spyvm/wrapper.py @@ -204,6 +204,12 @@ x, store_x = make_int_getter_setter(0) y, store_y = make_int_getter_setter(1) + +class BlockClosureWrapper(Wrapper): + outerContext, store_outerContext = make_getter_setter(0) + startpc, store_startpc = make_int_getter_setter(1) + numArgs, store_numArgs = make_int_getter_setter(2) + # XXX Wrappers below are not used yet. class OffsetWrapper(Wrapper): offset_x = make_int_getter(0) @@ -217,4 +223,3 @@ class CursorWrapper(MaskWrapper): offset = make_getter(4) - From noreply at buildbot.pypy.org Tue Feb 19 13:34:00 2013 From: noreply at buildbot.pypy.org (lwassermann) Date: Tue, 19 Feb 2013 13:34:00 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: (lwassermann, cfbolz): added VarsizedWrapper with at0, atput0 Message-ID: <20130219123400.565AA1C05FF@cobra.cs.uni-duesseldorf.de> Author: Lars Wassermann Branch: Changeset: r58:198990598f2b Date: 2013-02-19 13:28 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/198990598f2b/ Log: (lwassermann, cfbolz): added VarsizedWrapper with at0, atput0 diff --git a/spyvm/interpreter.py b/spyvm/interpreter.py --- a/spyvm/interpreter.py +++ b/spyvm/interpreter.py @@ -438,7 +438,7 @@ if numCopied > 0: copiedValues = self.pop_and_return_n(numCopied) for i0 in range(numCopied): - w_closure.atput0(space, i0, copiedValues[i0]) + closure.atput0(i0, copiedValues[i0]) self.push(w_closure) self.jump(blockSize) diff --git a/spyvm/test/test_interpreter.py b/spyvm/test/test_interpreter.py --- a/spyvm/test/test_interpreter.py +++ b/spyvm/test/test_interpreter.py @@ -908,5 +908,5 @@ closure = wrapper.BlockClosureWrapper(space, context.top()) assert closure.startpc() == pc + 4 assert closure.outerContext() is context._w_self - assert closure.w_self.at0(space, 0) == "english" - assert closure.w_self.at0(space, 1) == "bar" + assert closure.at0(0) == "english" + assert closure.at0(1) == "bar" diff --git a/spyvm/wrapper.py b/spyvm/wrapper.py --- a/spyvm/wrapper.py +++ b/spyvm/wrapper.py @@ -22,6 +22,14 @@ except IndexError: raise WrapperException("Unexpected instance layout. Too small") +class VarsizedWrapper(Wrapper): + def at0(self, i0): + return self.w_self.at0(self.space, i0) + + def atput0(self, i0, w_value): + return self.w_self.atput0(self.space, i0, w_value) + + def make_getter(index0): def getter(self): return self.read(index0) @@ -47,7 +55,8 @@ def make_int_getter_setter(index0): return make_int_getter(index0), make_int_setter(index0) - + + class LinkWrapper(Wrapper): next_link, store_next_link = make_getter_setter(0) @@ -205,7 +214,7 @@ y, store_y = make_int_getter_setter(1) -class BlockClosureWrapper(Wrapper): +class BlockClosureWrapper(VarsizedWrapper): outerContext, store_outerContext = make_getter_setter(0) startpc, store_startpc = make_int_getter_setter(1) numArgs, store_numArgs = make_int_getter_setter(2) From noreply at buildbot.pypy.org Tue Feb 19 13:34:01 2013 From: noreply at buildbot.pypy.org (lwassermann) Date: Tue, 19 Feb 2013 13:34:01 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: (cfbolz, lwassermann, krono): be consistent with shadows and rename to _w_self Message-ID: <20130219123401.5034F1C05FF@cobra.cs.uni-duesseldorf.de> Author: Lars Wassermann Branch: Changeset: r59:d9338ab06c51 Date: 2013-02-19 13:33 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/d9338ab06c51/ Log: (cfbolz, lwassermann, krono): be consistent with shadows and rename to _w_self diff --git a/spyvm/test/test_wrapper.py b/spyvm/test/test_wrapper.py --- a/spyvm/test/test_wrapper.py +++ b/spyvm/test/test_wrapper.py @@ -83,7 +83,7 @@ w_first = space.w_nil w_last = space.w_nil for w_process in processes_w[::-1]: - w_first = newprocess(w_first, w_processlist).w_self + w_first = newprocess(w_first, w_processlist)._w_self if w_last is space.w_nil: w_last = w_first pl = wrapper.ProcessListWrapper(space, w_processlist) @@ -100,8 +100,8 @@ w_prioritylist = model.W_PointersObject(None, maxpriority) prioritylist = wrapper.Wrapper(space, w_prioritylist) for i in range(maxpriority): - prioritylist.write(i, new_processlist(prioritydict.get(i, [])).w_self) - + prioritylist.write(i, new_processlist(prioritydict.get(i, []))._w_self) + return prioritylist def new_scheduler(w_process=space.w_nil, prioritydict=None): @@ -109,7 +109,7 @@ w_scheduler = model.W_PointersObject(None, 2) scheduler = wrapper.SchedulerWrapper(space, w_scheduler) scheduler.store_active_process(w_process) - scheduler.write(0, priority_list.w_self) + scheduler.write(0, priority_list._w_self) return scheduler def new_semaphore(excess_signals=0): @@ -118,7 +118,7 @@ semaphore.store_excess_signals(excess_signals) return semaphore - + class TestScheduler(object): def setup_method(self, meth): self.old_scheduler = wrapper.scheduler @@ -133,7 +133,7 @@ process.put_to_sleep() process_list = wrapper.scheduler(space).get_process_list(2) assert process_list.first_link() is process_list.last_link() - assert process_list.first_link() is process.w_self + assert process_list.first_link() is process._w_self def test_suspend_asleep(self): interp, process, old_process = self.make_processes(4, 2, space.w_false, space.w_true) @@ -150,23 +150,23 @@ assert process_list.first_link() is process_list.last_link() assert process_list.first_link() is space.w_nil assert old_process.my_list() is space.w_nil - assert wrapper.scheduler(space).active_process() is process.w_self + assert wrapper.scheduler(space).active_process() is process._w_self def new_process_consistency(self, process, old_process, interp, old_active_context, new_active_context): scheduler = wrapper.scheduler(space) assert interp.w_active_context() is new_active_context - assert scheduler.active_process() is process.w_self + assert scheduler.active_process() is process._w_self priority_list = wrapper.scheduler(space).get_process_list(process.priority()) assert priority_list.first_link() is priority_list.last_link() # activate does not remove the process from the process_list. # The caller of activate is responsible - assert priority_list.first_link() is process.w_self + assert priority_list.first_link() is process._w_self def old_process_consistency(self, old_process, old_process_context): assert old_process.suspended_context() is old_process_context priority_list = wrapper.scheduler(space).get_process_list(old_process.priority()) - assert priority_list.first_link() is old_process.w_self + assert priority_list.first_link() is old_process._w_self def make_processes(self, sleepingpriority, runningpriority, sleepingcontext, runningcontext): @@ -176,7 +176,7 @@ w_suspended_context=sleepingcontext) sleeping.put_to_sleep() running = new_process(priority=runningpriority) - scheduler.store_active_process(running.w_self) + scheduler.store_active_process(running._w_self) interp.store_w_active_context(runningcontext) return interp, sleeping, running @@ -187,7 +187,7 @@ process.activate(interp) self.new_process_consistency(process, old_process, interp, space.w_true, space.w_false) - + def test_resume(self): interp, process, old_process = self.make_processes(4, 2, space.w_false, space.w_true) process.resume(interp) @@ -213,17 +213,17 @@ process.put_to_sleep() old_process.put_to_sleep() highest = wrapper.scheduler(space).highest_priority_process() - assert highest is process.w_self + assert highest is process._w_self highest = wrapper.scheduler(space).highest_priority_process() - assert highest is old_process.w_self + assert highest is old_process._w_self py.test.raises(FatalError, wrapper.scheduler(space).highest_priority_process) def test_semaphore_wait(self): semaphore = new_semaphore() interp, process, old_process = self.make_processes(4, 2, space.w_false, space.w_true) semaphore.wait(interp) - assert semaphore.first_link() is old_process.w_self - assert wrapper.scheduler(space).active_process() is process.w_self + assert semaphore.first_link() is old_process._w_self + assert wrapper.scheduler(space).active_process() is process._w_self def test_semaphore_signal_wait(self): semaphore = new_semaphore() @@ -232,10 +232,10 @@ interp, process, old_process = self.make_processes(4, 2, space.w_false, space.w_true) semaphore.wait(interp) assert semaphore.is_empty_list() - assert wrapper.scheduler(space).active_process() is old_process.w_self + assert wrapper.scheduler(space).active_process() is old_process._w_self semaphore.wait(interp) - assert semaphore.first_link() is old_process.w_self - assert wrapper.scheduler(space).active_process() is process.w_self + assert semaphore.first_link() is old_process._w_self + assert wrapper.scheduler(space).active_process() is process._w_self py.test.raises(FatalError, semaphore.wait, interp) @@ -244,19 +244,19 @@ interp, process, old_process = self.make_processes(4, 2, space.w_false, space.w_true) semaphore.wait(interp) - assert wrapper.scheduler(space).active_process() is process.w_self + assert wrapper.scheduler(space).active_process() is process._w_self semaphore.signal(interp) - assert wrapper.scheduler(space).active_process() is process.w_self + assert wrapper.scheduler(space).active_process() is process._w_self process_list = wrapper.scheduler(space).get_process_list(old_process.priority()) - assert process_list.remove_first_link_of_list() is old_process.w_self + assert process_list.remove_first_link_of_list() is old_process._w_self - process.write(2, space.wrap_int(1)) + process.write(2, space.wrap_int(1)) old_process.resume(interp) - assert wrapper.scheduler(space).active_process() is old_process.w_self + assert wrapper.scheduler(space).active_process() is old_process._w_self semaphore.wait(interp) - assert wrapper.scheduler(space).active_process() is process.w_self + assert wrapper.scheduler(space).active_process() is process._w_self semaphore.signal(interp) - assert wrapper.scheduler(space).active_process() is old_process.w_self + assert wrapper.scheduler(space).active_process() is old_process._w_self process_list = wrapper.scheduler(space).get_process_list(process.priority()) - assert process_list.first_link() is process.w_self + assert process_list.first_link() is process._w_self diff --git a/spyvm/wrapper.py b/spyvm/wrapper.py --- a/spyvm/wrapper.py +++ b/spyvm/wrapper.py @@ -5,29 +5,29 @@ def __init__(self, space, w_self): if not isinstance(w_self, model.W_PointersObject): raise WrapperException("Unexpected instance given to wrapper") - self.w_self = w_self + self._w_self = w_self self.space = space def read(self, index0): try: - return self.w_self.fetch(self.space, index0) + return self._w_self.fetch(self.space, index0) # XXX Index error never raised after translation except IndexError: raise WrapperException("Unexpected instance layout. Too small") def write(self, index0, w_new): try: - self.w_self.store(self.space, index0, w_new) + self._w_self.store(self.space, index0, w_new) # XXX Index error never raised after translation except IndexError: raise WrapperException("Unexpected instance layout. Too small") class VarsizedWrapper(Wrapper): def at0(self, i0): - return self.w_self.at0(self.space, i0) + return self._w_self.at0(self.space, i0) def atput0(self, i0, w_value): - return self.w_self.atput0(self.space, i0, w_value) + return self._w_self.atput0(self.space, i0, w_value) def make_getter(index0): @@ -69,11 +69,11 @@ sched = scheduler(self.space) priority = self.priority() process_list = sched.get_process_list(priority) - process_list.add_process(self.w_self) + process_list.add_process(self._w_self) def activate(self, interp): sched = scheduler(self.space) - sched.store_active_process(self.w_self) + sched.store_active_process(self._w_self) interp.store_w_active_context(self.suspended_context()) self.store_suspended_context(interp.space.w_nil) self.store_my_list(interp.space.w_nil) @@ -94,7 +94,7 @@ self.put_to_sleep() def is_active_process(self): - return self.w_self.is_same_object(scheduler(self.space).active_process()) + return self._w_self.is_same_object(scheduler(self.space).active_process()) def suspend(self, interp): if self.is_active_process(): @@ -103,7 +103,7 @@ process = ProcessWrapper(self.space, w_process).activate(interp) else: process_list = ProcessListWrapper(self.space, self.my_list()) - process_list.remove(self.w_self) + process_list.remove(self._w_self) self.store_my_list(interp.space.w_nil) class LinkedListWrapper(Wrapper): @@ -145,7 +145,7 @@ w_tail = LinkWrapper(self.space, w_next).next_link() current.store_next_link(w_tail) if w_tail.is_same_object(self.space.w_nil): - self.store_last_link(current.w_self) + self.store_last_link(current._w_self) return current = LinkWrapper(self.space, w_next) w_next = current.next_link() @@ -154,7 +154,7 @@ class ProcessListWrapper(LinkedListWrapper): def add_process(self, w_process): self.add_last_link(w_process) - ProcessWrapper(self.space, w_process).store_my_list(self.w_self) + ProcessWrapper(self.space, w_process).store_my_list(self._w_self) class AssociationWrapper(Wrapper): key = make_getter(0) From noreply at buildbot.pypy.org Tue Feb 19 14:03:17 2013 From: noreply at buildbot.pypy.org (lwassermann) Date: Tue, 19 Feb 2013 14:03:17 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: (cfbolz, krono, lwassermann): added methodname guessing to compiledMethod for debugging Message-ID: <20130219130317.58F931C05FF@cobra.cs.uni-duesseldorf.de> Author: Lars Wassermann Branch: Changeset: r60:385df11cafb3 Date: 2013-02-19 14:02 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/385df11cafb3/ Log: (cfbolz, krono, lwassermann): added methodname guessing to compiledMethod for debugging diff --git a/spyvm/interpreter.py b/spyvm/interpreter.py --- a/spyvm/interpreter.py +++ b/spyvm/interpreter.py @@ -17,7 +17,8 @@ def get_printable_location(pc, self, method): bc = ord(method.bytecode[pc]) - return '%d: [%s]%s' % (pc, hex(bc), BYTECODE_NAMES[bc]) + name = method._w_self._likely_methodname + return '%d: [%s]%s (%s)' % (pc, hex(bc), BYTECODE_NAMES[bc], name) class Interpreter(object): diff --git a/spyvm/model.py b/spyvm/model.py --- a/spyvm/model.py +++ b/spyvm/model.py @@ -463,6 +463,7 @@ ### the last byte in the method. _shadow = None + _likely_methodname = "" def __init__(self, bytecount=0, header=0): self.setheader(header) diff --git a/spyvm/shadow.py b/spyvm/shadow.py --- a/spyvm/shadow.py +++ b/spyvm/shadow.py @@ -282,6 +282,7 @@ raise ClassShadowError("the methoddict must contain " "CompiledMethods only for now") self.methoddict[selector] = w_compiledmethod + w_compiledmethod._likely_methodname = selector class AbstractRedirectingShadow(AbstractShadow): @@ -716,10 +717,12 @@ class CompiledMethodShadow(object): - _immutable_fields_ = ["bytecode", "literals[*]", "bytecodeoffset", + _immutable_fields_ = ["_w_self", "bytecode", + "literals[*]", "bytecodeoffset", "literalsize", "tempsize", "w_compiledin"] def __init__(self, w_compiledmethod): + self._w_self = w_compiledmethod self.bytecode = "".join(w_compiledmethod.bytes) self.literals = w_compiledmethod.literals self.bytecodeoffset = w_compiledmethod.bytecodeoffset() From noreply at buildbot.pypy.org Tue Feb 19 14:03:18 2013 From: noreply at buildbot.pypy.org (lwassermann) Date: Tue, 19 Feb 2013 14:03:18 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: (cfbolz, krono, lwassermann): refactored new bytecodes Message-ID: <20130219130318.621751C05FF@cobra.cs.uni-duesseldorf.de> Author: Lars Wassermann Branch: Changeset: r61:2489fd0ee551 Date: 2013-02-19 14:03 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/2489fd0ee551/ Log: (cfbolz, krono, lwassermann): refactored new bytecodes diff --git a/spyvm/interpreter.py b/spyvm/interpreter.py --- a/spyvm/interpreter.py +++ b/spyvm/interpreter.py @@ -382,26 +382,23 @@ def experimentalBytecode(self, interp): raise MissingBytecode("experimentalBytecode") + def _extract_index_and_temps(self): + index_in_array = self.getbytecode() + index_of_array = self.getbytecode() + w_indirectTemps = self.gettemp(index_of_array) + return index_in_array, w_indirectTemps + def pushTempAtInTempVectorAt(self, interp): - k = self.getbytecode() - j = self.getbytecode() - context = interp.s_active_context() - indirectTemps = context.gettemp(j) - context.push(indirectTemps.at0(self, k)) + index_in_array, w_indirectTemps = self._extract_index_and_temps() + self.push(w_indirectTemps.at0(self.space, index_in_array)) def storeTempAtInTempVectorAt(self, interp): - k = self.getbytecode() - j = self.getbytecode() - context = interp.s_active_context() - indirectTemps = context.gettemp(j) - indirectTemps.atput0(self, k, context.top()) + index_in_array, w_indirectTemps = self._extract_index_and_temps() + w_indirectTemps.atput0(self.space, index_in_array, self.top()) def popAndStoreTempAtInTempVectorAt(self, interp): - k = self.getbytecode() - j = self.getbytecode() - context = interp.s_active_context() - indirectTemps = context.gettemp(j) - indirectTemps.atput0(self, k, context.pop()) + index_in_array, w_indirectTemps = self._extract_index_and_temps() + w_indirectTemps.atput0(self.space, index_in_array, self.pop()) def pushClosureNumCopiedNumArgsBlockSize(self, interp): """ Copied from Blogpost: http://www.mirandabanda.org/cogblog/2008/07/22/closures-part-ii-the-bytecodes/ diff --git a/spyvm/todo.txt b/spyvm/todo.txt --- a/spyvm/todo.txt +++ b/spyvm/todo.txt @@ -23,5 +23,4 @@ [ ] Fix invalidation of methoddictshadow when the w_self of its values array changes Lars ToDo -[ ] Tests for the new bytecodes. -[ ] Guess method names for JIT debugging, e.g. changing MethodDictShadow +[ ] different image with BlockClosure instead of BlockContext From noreply at buildbot.pypy.org Tue Feb 19 15:38:15 2013 From: noreply at buildbot.pypy.org (krono) Date: Tue, 19 Feb 2013 15:38:15 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: re-layout sources. images to own directory Message-ID: <20130219143815.6A7861C0CA3@cobra.cs.uni-duesseldorf.de> Author: Tobias Pape Branch: Changeset: r62:2fd7f3f6574e Date: 2013-02-19 15:37 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/2fd7f3f6574e/ Log: re-layout sources. images to own directory diff --git a/images/bootstrapped.changes.xz b/images/bootstrapped.changes.xz new file mode 100644 index 0000000000000000000000000000000000000000..735fc4cc1abdb061d63a5235f6418128faebf6d7 GIT binary patch [cut] diff --git a/images/bootstrapped.image b/images/bootstrapped.image new file mode 100644 index 0000000000000000000000000000000000000000..f344005f8f168c645ac07fe82dbf985d5a767b02 GIT binary patch [cut] diff --git a/spyvm/mini.image b/images/mini.image rename from spyvm/mini.image rename to images/mini.image diff --git a/spyvm/minitest.image b/images/minitest.image rename from spyvm/minitest.image rename to images/minitest.image diff --git a/spyvm/running-something-mini.image b/images/running-something-mini.image rename from spyvm/running-something-mini.image rename to images/running-something-mini.image diff --git a/spyvm/test/test_miniimage.py b/spyvm/test/test_miniimage.py --- a/spyvm/test/test_miniimage.py +++ b/spyvm/test/test_miniimage.py @@ -12,7 +12,8 @@ def setup_module(module, filename='mini.image'): space = objspace.ObjSpace() - module.mini_image = py.path.local(__file__).dirpath().dirpath().join(filename) + from spyvm.tool.analyseimage import image_dir + module.mini_image = image_dir.join(filename) module.reader = open_miniimage(space) reader.initialize() module.image = squeakimage.SqueakImage() diff --git a/spyvm/tool/analyseimage.py b/spyvm/tool/analyseimage.py --- a/spyvm/tool/analyseimage.py +++ b/spyvm/tool/analyseimage.py @@ -5,8 +5,10 @@ from spyvm import interpreter import sys -mini_image = py.path.local(__file__).dirpath().dirpath().join('mini.image') -minitest_image = py.path.local(__file__).dirpath().dirpath().join('minitest.image') +image_dir = py.path.local(__file__).dirpath().dirpath().dirpath('images') + +mini_image = image_dir.join('mini.image') +minitest_image = image_dir.join('minitest.image') def get_miniimage(space): return squeakimage.ImageReader(space, squeakimage.Stream(mini_image.open())) diff --git a/spyvm/targetimageloadingsmalltalk.py b/targetimageloadingsmalltalk.py rename from spyvm/targetimageloadingsmalltalk.py rename to targetimageloadingsmalltalk.py --- a/spyvm/targetimageloadingsmalltalk.py +++ b/targetimageloadingsmalltalk.py @@ -1,4 +1,3 @@ -import autopath1 import sys import os from spyvm import model, interpreter, primitives, shadow diff --git a/spyvm/targettinybenchsmalltalk.py b/targettinybenchsmalltalk.py rename from spyvm/targettinybenchsmalltalk.py rename to targettinybenchsmalltalk.py From noreply at buildbot.pypy.org Tue Feb 19 15:52:45 2013 From: noreply at buildbot.pypy.org (rguillebert) Date: Tue, 19 Feb 2013 15:52:45 +0100 (CET) Subject: [pypy-commit] pypy default: ndarray.__eq__ should return False when the shapes don't agree Message-ID: <20130219145245.2669A1C0CA3@cobra.cs.uni-duesseldorf.de> Author: Romain Guillebert Branch: Changeset: r61459:2dab420716b2 Date: 2013-02-19 15:51 +0100 http://bitbucket.org/pypy/pypy/changeset/2dab420716b2/ Log: ndarray.__eq__ should return False when the shapes don't agree diff --git a/pypy/module/micronumpy/interp_numarray.py b/pypy/module/micronumpy/interp_numarray.py --- a/pypy/module/micronumpy/interp_numarray.py +++ b/pypy/module/micronumpy/interp_numarray.py @@ -627,7 +627,16 @@ w_remainder = self.descr_mod(space, w_other) return space.newtuple([w_quotient, w_remainder]) - descr_eq = _binop_impl("equal") + _descr_eq = _binop_impl("equal") + + def descr_eq(self, space, w_other): + try: + return self._descr_eq(space, w_other) + except OperationError, e: + if e.match(space, space.w_ValueError): + return space.w_False + raise e + descr_ne = _binop_impl("not_equal") descr_lt = _binop_impl("less") descr_le = _binop_impl("less_equal") From noreply at buildbot.pypy.org Tue Feb 19 16:14:04 2013 From: noreply at buildbot.pypy.org (krono) Date: Tue, 19 Feb 2013 16:14:04 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: enable to read (not support) cog-byte-reversal saved images (6505) Message-ID: <20130219151404.5B53B1C054C@cobra.cs.uni-duesseldorf.de> Author: Tobias Pape Branch: Changeset: r63:f8278cad1ec7 Date: 2013-02-19 16:13 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/f8278cad1ec7/ Log: enable to read (not support) cog-byte-reversal saved images (6505) diff --git a/spyvm/squeakimage.py b/spyvm/squeakimage.py --- a/spyvm/squeakimage.py +++ b/spyvm/squeakimage.py @@ -69,9 +69,12 @@ # ____________________________________________________________ +# XXX hack to read Cog images. +# TODO implement Cog float byte reversal +SUPPORTED_VERSIONS = [6502, 6505] + class ImageReader(object): - def __init__(self, space, stream): self.space = space self.stream = stream @@ -94,10 +97,10 @@ def read_header(self): # 1 word version version = self.stream.peek() - if version != 0x1966: + if version not in SUPPORTED_VERSIONS: self.stream.swap = True version = self.stream.peek() - if version != 0x1966: + if version not in SUPPORTED_VERSIONS: raise CorruptImageError version = self.stream.next() #------ From noreply at buildbot.pypy.org Tue Feb 19 17:07:41 2013 From: noreply at buildbot.pypy.org (stepahn) Date: Tue, 19 Feb 2013 17:07:41 +0100 (CET) Subject: [pypy-commit] lang-js default: re-enabeld jit-viewer Message-ID: <20130219160741.33F7B1C054C@cobra.cs.uni-duesseldorf.de> Author: Stephan Branch: Changeset: r356:22529703a4ae Date: 2013-02-19 12:59 +0100 http://bitbucket.org/pypy/lang-js/changeset/22529703a4ae/ Log: re-enabeld jit-viewer diff --git a/test/jit_view.py b/test/jit_view.py --- a/test/jit_view.py +++ b/test/jit_view.py @@ -1,4 +1,4 @@ -from pypy import conftest +from rpython import conftest class o: From noreply at buildbot.pypy.org Tue Feb 19 17:07:42 2013 From: noreply at buildbot.pypy.org (stepahn) Date: Tue, 19 Feb 2013 17:07:42 +0100 (CET) Subject: [pypy-commit] lang-js default: use unicodedb from rpython Message-ID: <20130219160742.52E8D1C054C@cobra.cs.uni-duesseldorf.de> Author: Stephan Branch: Changeset: r357:36100f4aa72b Date: 2013-02-19 13:00 +0100 http://bitbucket.org/pypy/lang-js/changeset/36100f4aa72b/ Log: use unicodedb from rpython diff --git a/js/builtins/js_global.py b/js/builtins/js_global.py --- a/js/builtins/js_global.py +++ b/js/builtins/js_global.py @@ -3,7 +3,7 @@ from rpython.rlib.rfloat import NAN, INFINITY, isnan, isinf from js.builtins import get_arg from js.object_space import w_return -from pypy.module.unicodedata import unicodedb +from rpython.rlib.unicodedata import unicodedb def setup(global_object): diff --git a/js/builtins/string.py b/js/builtins/string.py --- a/js/builtins/string.py +++ b/js/builtins/string.py @@ -291,7 +291,7 @@ # 15.5.4.16 @w_return def to_lower_case(this, args): - from pypy.module.unicodedata import unicodedb + from rpython.rlib.unicodedata import unicodedb string = this.to_string() builder = UnicodeBuilder(len(string)) @@ -305,7 +305,7 @@ # 15.5.4.18 @w_return def to_upper_case(this, args): - from pypy.module.unicodedata import unicodedb + from rpython.rlib.unicodedata import unicodedb string = this.to_string() builder = UnicodeBuilder(len(string)) From noreply at buildbot.pypy.org Tue Feb 19 17:07:43 2013 From: noreply at buildbot.pypy.org (stepahn) Date: Tue, 19 Feb 2013 17:07:43 +0100 (CET) Subject: [pypy-commit] lang-js default: added translatable date and time functions Message-ID: <20130219160743.58EFC1C054C@cobra.cs.uni-duesseldorf.de> Author: Stephan Branch: Changeset: r358:0eca2e45608b Date: 2013-02-19 13:02 +0100 http://bitbucket.org/pypy/lang-js/changeset/0eca2e45608b/ Log: added translatable date and time functions diff --git a/js/builtins/date.py b/js/builtins/date.py --- a/js/builtins/date.py +++ b/js/builtins/date.py @@ -1,9 +1,16 @@ from rpython.rlib.rfloat import NAN, isnan -from rpython.rlib.objectmodel import we_are_translated -import datetime from js.builtins import get_arg -from js.object_space import w_return, hide_on_translate, _w +from js.object_space import w_return, _w +from js import rtime + +fMSEC = 1 +fSEC = 2 +fMIN = 3 +fHOUR = 4 +fDAY = 1 +fMONTH = 2 +fYEAR = 3 def setup(global_object): @@ -103,14 +110,9 @@ @w_return def to_string(this, args): - if not we_are_translated(): - d = w_date_to_datetime(this) - local = to_local(d) - - s = local.strftime('%a %b %d %Y %H:%M:%S GMT%z (%Z)') - return s - - return this.PrimitiveValue().to_string() + t = make_jstime(this) + s = t.strftime('%a %b %d %Y %H:%M:%S GMT%z (%Z)', local=True) + return s # 15.9.5.8 @@ -127,146 +129,121 @@ # 15.9.5.10 @w_return - at hide_on_translate(0) def get_full_year(this, args): - d = w_date_to_datetime(this) - local = to_local(d) - return local.year + t = make_jstime(this) + return t.year(local=True) # 15.9.5.11 @w_return - at hide_on_translate(0) def get_utc_full_year(this, args): - d = w_date_to_datetime(this) - return d.year + t = make_jstime(this) + return t.year() # 15.9.5.12 @w_return - at hide_on_translate(0) def get_month(this, args): - d = w_date_to_datetime(this) - local = to_local(d) - return local.month + t = make_jstime(this) + return t.month(local=True) # 15.9.5.13 @w_return - at hide_on_translate(0) def get_utc_month(this, args): - d = w_date_to_datetime(this) - return d.day + t = make_jstime(this) + return t.month() # 15.9.5.14 @w_return - at hide_on_translate(0) def get_date(this, args): - d = w_date_to_datetime(this) - local = to_local(d) - return local.day + t = make_jstime(this) + return t.day(local=True) # 15.9.5.15 @w_return - at hide_on_translate(0) def get_utc_date(this, args): - d = w_date_to_datetime(this) - return d.day + t = make_jstime(this) + return t.day() # 15.9.5.16 @w_return - at hide_on_translate(0) def get_day(this, args): - d = w_date_to_datetime(this) - local = to_local(d) - return local.weekday() + t = make_jstime(this) + return t.wday(local=True) # 15.9.5.17 @w_return - at hide_on_translate(0) def get_utc_day(this, args): - d = w_date_to_datetime(this) - return d.weekday() + t = make_jstime(this) + return t.wday() # 15.9.5.18 @w_return - at hide_on_translate(0) def get_hours(this, args): - d = w_date_to_datetime(this) - local = to_local(d) - return local.hour + t = make_jstime(this) + return t.hour(local=True) # 15.9.5.19 @w_return - at hide_on_translate(0) def get_utc_hours(this, args): - d = w_date_to_datetime(this) - return d.hour + t = make_jstime(this) + return t.hour() # 15.9.5.20 @w_return - at hide_on_translate(0) def get_minutes(this, args): - d = w_date_to_datetime(this) - local = to_local(d) - return local.minute + t = make_jstime(this) + return t.min(local=True) # 15.9.5.21 @w_return - at hide_on_translate(0) def get_utc_minutes(this, args): - d = w_date_to_datetime(this) - return d.minute + t = make_jstime(this) + return t.min() # 15.9.5.22 @w_return - at hide_on_translate(0) def get_seconds(this, args): - d = w_date_to_datetime(this) - local = to_local(d) - return local.second + t = make_jstime(this) + return t.sec(local=True) # 15.9.5.23 @w_return - at hide_on_translate(0) def get_utc_seconds(this, args): - d = w_date_to_datetime(this) - return d.second + t = make_jstime(this) + return t.sec() # 15.9.5.24 @w_return - at hide_on_translate(0) def get_milliseconds(this, args): - d = w_date_to_datetime(this) - local = to_local(d) - return local.microsecond / 1000 + t = make_jstime(this) + return t.msec(local=True) # 15.9.5.25 @w_return - at hide_on_translate(0) def get_utc_milliseconds(this, args): - d = w_date_to_datetime(this) - return d.microsecond / 1000 + t = make_jstime(this) + return t.msec() # 15.9.5.26 @w_return - at hide_on_translate(0) def get_timezone_offset(this, args): - d = w_date_to_datetime(this) - offset = -1 * (d.utcoffset().total_seconds() / 60) + t = make_jstime(this) + offset = -1 * t.utc_offset() / 60 return offset @@ -290,154 +267,137 @@ # 15.9.5.28 @w_return - at hide_on_translate(0) def set_milliseconds(this, args): - time_args = to_timeargs(args, 1) - return set_datetime(this, time_args) + time_args = to_timeargs(args, fMSEC) + return change_wdate(this, time_args, local=True) # 15.9.5.29 @w_return - at hide_on_translate(0) def set_utc_milliseconds(this, args): - time_args = to_timeargs(args, 1) - return set_utc_datetime(this, time_args) + time_args = to_timeargs(args, fMSEC) + return change_wdate(this, time_args) # 15.9.5.30 @w_return - at hide_on_translate(0) def set_seconds(this, args): - time_args = to_timeargs(args, 2) - return set_datetime(this, time_args) + time_args = to_timeargs(args, fSEC) + return change_wdate(this, time_args, local=True) # 15.9.5.30 @w_return - at hide_on_translate(0) def set_utc_seconds(this, args): - time_args = to_timeargs(args, 2) - return set_utc_datetime(this, time_args) + time_args = to_timeargs(args, fSEC) + return change_wdate(this, time_args) # 15.9.5.32 @w_return - at hide_on_translate(0) def set_minutes(this, args): - time_args = to_timeargs(args, 3) - return set_datetime(this, time_args) + time_args = to_timeargs(args, fMIN) + return change_wdate(this, time_args, local=True) # 15.9.5.33 @w_return - at hide_on_translate(0) def set_utc_minutes(this, args): - time_args = to_timeargs(args, 3) - return set_utc_datetime(this, time_args) + time_args = to_timeargs(args, fMIN) + return change_wdate(this, time_args) # 15.9.5.34 @w_return - at hide_on_translate(0) def set_hours(this, args): - time_args = to_timeargs(args, 4) - return set_datetime(this, time_args) + time_args = to_timeargs(args, fHOUR) + return change_wdate(this, time_args, local=True) # 15.9.5.35 @w_return - at hide_on_translate(0) def set_utc_hours(this, args): - time_args = to_timeargs(args, 4) - return set_utc_datetime(this, time_args) + time_args = to_timeargs(args, fHOUR) + return change_wdate(this, time_args) # 15.9.5.36 @w_return - at hide_on_translate(0) def set_date(this, args): - date_args = to_dateargs(args, 1) - return set_datetime(this, date_args) + date_args = to_dateargs(args, fDAY) + return change_wdate(this, date_args, local=True) # 15.9.5.37 @w_return - at hide_on_translate(0) def set_utc_date(this, args): - date_args = to_dateargs(args, 1) - return set_utc_datetime(this, date_args) + date_args = to_dateargs(args, fDAY) + return change_wdate(this, date_args) # 15.9.5.38 @w_return - at hide_on_translate(0) def set_month(this, args): - date_args = to_dateargs(args, 2) - return set_datetime(this, date_args) + date_args = to_dateargs(args, fMONTH) + return change_wdate(this, date_args, local=True) # 15.9.5.39 @w_return - at hide_on_translate(0) def set_utc_month(this, args): - date_args = to_dateargs(args, 2) - return set_utc_datetime(this, date_args) + date_args = to_dateargs(args, fMONTH) + return change_wdate(this, date_args) # 15.9.5.38 @w_return - at hide_on_translate(0) def set_full_year(this, args): - date_args = to_dateargs(args, 3) - return set_datetime(this, date_args) + date_args = to_dateargs(args, fYEAR) + return change_wdate(this, date_args, local=True) # 15.9.5.39 @w_return - at hide_on_translate(0) def set_utc_full_year(this, args): - date_args = to_dateargs(args, 3) - return set_utc_datetime(this, date_args) + date_args = to_dateargs(args, fYEAR) + return change_wdate(this, date_args) # B.2.4 @w_return - at hide_on_translate(0) def get_year(this, args): - d = w_date_to_datetime(this) - local = to_local(d) - y = local.year - 1900 + t = make_jstime(this) + y = t.year(local=True) - 1900 return y # B.2.5 @w_return - at hide_on_translate(0) def set_year(this, args): arg0 = get_arg(args, 0) year = arg0.ToInteger() if isnan(year) or year < 0 or year > 99: - this.set_primitive_value(NAN) + this.set_primitive_value(_w(NAN)) return NAN y = year + 1900 - - return set_datetime(this, [y]) + c = JsDateChange() + c.set_year(y) + change_wdate(this, c) + return y # 15.9.5.42 @w_return - at hide_on_translate(0) def to_utc_string(this, args): - d = w_date_to_datetime(this) - s = d.strftime('%c %z') + t = make_jstime(this) + s = t.strftime('%c %z') return s # B.2.6 @w_return - at hide_on_translate(0) def to_gmt_string(this, args): return to_utc_string(this, args) @@ -456,105 +416,247 @@ ####### helper -def to_timeargs(args, count): - a = argv(args) - rfilled = rfill_args(a, count) - lfilled = lfill_args(rfilled, 7) - return lfilled +def to_timeargs(args, fill): + a = w_argi(args) + c = JsDateChange() + ac = len(a) + if fill == fMSEC: + c.set_msecond(a[0]) + elif fill == fSEC: + c.set_second(a[0]) + if ac > 1: + c.set_msecond(a[1]) + elif fill == fMIN: + c.set_minute(a[0]) + if ac > 1: + c.set_second(a[1]) + if ac > 2: + c.set_msecond(a[2]) + elif fill == fHOUR: + c.set_hour(a[0]) + if ac > 1: + c.set_minute(a[1]) + if ac > 2: + c.set_second(a[2]) + if ac > 3: + c.set_msecond(a[3]) -def to_dateargs(args, count): - a = argv(args) - rfilled = rfill_args(a, count) - lfilled = lfill_args(rfilled, 3) - return lfilled + return c -def set_datetime(this, args): - d = w_date_to_datetime(this) - local = to_local(d) - new_d = change_datetime(local, *args) +def to_dateargs(args, fill): + a = w_argi(args) + c = JsDateChange() + ac = len(a) - u = datetime_to_msecs(new_d) - this.set_primitive_value(u) + if fill == fDAY: + c.set_day(a[0]) + elif fill == fMONTH: + c.set_month(a[0]) + if ac > 1: + c.set_day(a[1]) + elif fill == fYEAR: + c.year = a[0] + if ac > 1: + c.set_month(a[1]) + if ac > 2: + c.set_day(a[2]) - return u + return c -def set_utc_datetime(this, args): - d = w_date_to_datetime(this) - new_d = change_datetime(d, *args) +class JsDateChange(object): + year = 0 + has_year = False + month = 0 + has_month = False + day = 0 + has_day = False + hour = 0 + has_hour = False + minute = 0 + has_minute = False + second = 0 + has_second = False + msecond = 0 + has_msecond = False - u = datetime_to_msecs(new_d) - this.set_primitive_value(u) + def set_year(self, year): + self.has_year = True + self.year = year - return u + def set_month(self, month): + self.has_month = True + self.month = month + def set_day(self, day): + self.has_day = True + self.day = day -def argv(args): - return [arg.ToInteger() for arg in args] + def set_hour(self, hour): + self.has_hour = True + self.hour = hour + def set_minute(self, minute): + self.has_minute = True + self.minute = minute -def lfill_args(args, count): - if count > 0: - missing = count - len(args) - return ([None] * missing) + args - return args + def set_second(self, second): + self.has_second = True + self.second = second + def set_msecond(self, msecond): + self.has_msecond = True + self.msecond = msecond -def rfill_args(args, count): - if count > 0: - missing = count - len(args) - return args + ([None] * missing) - return args +def change_wdate(w_date, time_change, local=False): + t = make_jstime(w_date) + if time_change.has_year: + t.set_year(time_change.year, local) -def change_datetime(d, year=None, month=None, day=None, hour=None, minute=None, second=None, ms=None): - args = {} - if year is not None: - args['year'] = year - if month is not None: - args['month'] = month - if day is not None: - args['day'] = day - if hour is not None: - args['hour'] = hour - if minute is not None: - args['minute'] = minute - if second is not None: - args['second'] = second - if ms is not None: - mu_sec = ms * 1000 - args['microsecond'] = mu_sec - return d.replace(**args) + if time_change.has_month: + t.set_month(time_change.month, local) + if time_change.has_day: + t.set_day(time_change.day, local) -def w_date_to_datetime(w_date): - msecs = w_date.PrimitiveValue().ToInteger() - return msecs_to_datetime(msecs) + if time_change.has_hour: + t.set_hour(time_change.hour, local) + if time_change.has_minute: + t.set_min(time_change.minute, local) -def msecs_to_datetime(timestamp_msecs): - from dateutil.tz import tzutc + if time_change.has_second: + t.set_sec(time_change.second, local) - seconds_since_epoch = timestamp_msecs / 1000 - msecs = timestamp_msecs - seconds_since_epoch * 1000 - timestamp = seconds_since_epoch + (msecs / 1000.0) - utc = datetime.datetime.utcfromtimestamp(timestamp) - utc = utc.replace(tzinfo=tzutc()) + if time_change.has_msecond: + t.set_msec(time_change.msecond, local) - return utc + w_t = _w(t.to_msec_epoc()) + w_date.set_primitive_value(w_t) + return w_t -def datetime_to_msecs(d): - from time import mktime - timestamp = int(mktime(d.utctimetuple())) - msecs = timestamp * 1000 - msecs += (d.microsecond / 1000) - return msecs +def w_argi(args): + argi = [] + for arg in args: + a = arg.ToInteger() + assert isinstance(a, int) + argi += [a] + return argi -def to_local(datetime): - from dateutil.tz import tzlocal - return datetime.astimezone(tzlocal()) + +def _change_tuple(t, idx, value): + assert len(t) == 9 + l = list(t) + l[idx] = value + return (l[0], l[1], l[2], l[3], l[4], l[5], l[6], l[7], l[8]) + + +def _get_tuple_at(t, idx): + l = list(t) + return l[idx] + + +class JsTime(object): + def __init__(self, msec_timestamp): + self._timep = msec_timestamp / 1000 + self._msec = msec_timestamp - self._timep * 1000 + + def __str__(self): + return 'JsTime(%d)' % (self.to_msec_epoc(), ) + + def _get_time(self, local): + if local: + return self.localtime() + return self.gmtime() + + def gmtime(self): + return rtime.gmtime(self._timep) + + def localtime(self): + return rtime.localtime(self._timep) + + def _set_time(self, tm, local): + if local: + self._timep = int(rtime.mktime(tm)) + else: + self._timep = int(rtime.timegm(tm)) + + def _update_time(self, component, value, local): + tm = self._get_time(local) + new_tm = _change_tuple(tm, component, value) + self._set_time(new_tm, local) + + def _get_time_component(self, component, local): + return _get_tuple_at(self._get_time(local), component) + + def _get_timestamp(self): + return self._timep + + def to_msec_epoc(self): + return (self._get_timestamp() * 1000) + (self.msec()) + + def year(self, local=False): + return self._get_time_component(rtime.tmYEAR, local) + + def set_year(self, year, local=False): + self._update_time(rtime.tmYEAR, year, local) + + def month(self, local=False): + return self._get_time_component(rtime.tmMONTH, local) + + def set_month(self, month, local=False): + self._update_time(rtime.tmMONTH, month, local) + + def day(self, local=False): + return self._get_time_component(rtime.tmDAY, local) + + def set_day(self, day, local=False): + self._update_time(rtime.tmDAY, day, local) + + def hour(self, local=False): + return self._get_time_component(rtime.tmHOUR, local) + + def set_hour(self, hour, local=False): + self._update_time(rtime.tmHOUR, hour, local) + + def min(self, local=False): + return self._get_time_component(rtime.tmMIN, local) + + def set_min(self, min, local=False): + self._update_time(rtime.tmMIN, min, local) + + def sec(self, local=False): + return self._get_time_component(rtime.tmSEC, local) + + def set_sec(self, sec, local=False): + self._update_time(rtime.tmSEC, sec, local) + + def msec(self, local=False): + return self._msec + + def set_msec(self, msec, local=False): + assert msec < 1000 + self._msec = msec + + def wday(self, local=False): + return self._get_time_component(rtime.tmWDAY, local) + + def strftime(self, format, local=False): + tm = self._get_time(local) + s = rtime.strftime(format, tm) + return s + + def utc_offset(self): + o = rtime.mktime(self.localtime()) - rtime.mktime(self.gmtime()) + return o + + +def make_jstime(w_obj): + msecs = w_obj.PrimitiveValue().ToInteger() + return JsTime(msecs) diff --git a/js/rtime.py b/js/rtime.py new file mode 100644 --- /dev/null +++ b/js/rtime.py @@ -0,0 +1,187 @@ +# see pypy/module/rctime/interp_time.py +import os + +from rpython.rtyper.lltypesystem import rffi, lltype +from rpython.rlib.rarithmetic import intmask +from pypy.module.rctime.interp_time import c_gmtime, c_localtime, c_mktime, glob_buf, _POSIX, _CYGWIN, _WIN, c_tzset, c_strftime + +tmYEAR = 0 +tmMONTH = 1 +tmDAY = 2 +tmHOUR = 3 +tmMIN = 4 +tmSEC = 5 +tmWDAY = 6 + + +def _tm_to_tuple(t): + time_tuple = ( + rffi.getintfield(t, 'c_tm_year') + 1900, + rffi.getintfield(t, 'c_tm_mon') + 1, # want january == 1 + rffi.getintfield(t, 'c_tm_mday'), + rffi.getintfield(t, 'c_tm_hour'), + rffi.getintfield(t, 'c_tm_min'), + rffi.getintfield(t, 'c_tm_sec'), + ((rffi.getintfield(t, 'c_tm_wday') + 6) % 7), # want monday == 0 + rffi.getintfield(t, 'c_tm_yday') + 1, # want january, 1 == 1 + rffi.getintfield(t, 'c_tm_isdst')) + return time_tuple + + +def _gettmarg(tup): + if len(tup) != 9: + raise Exception("argument must be sequence of length 9, not %d", len(tup)) + + y = tup[0] + tm_mon = tup[1] + if tm_mon == 0: + tm_mon = 1 + tm_mday = tup[2] + if tm_mday == 0: + tm_mday = 1 + tm_yday = tup[7] + if tm_yday == 0: + tm_yday = 1 + rffi.setintfield(glob_buf, 'c_tm_mon', tm_mon) + rffi.setintfield(glob_buf, 'c_tm_mday', tm_mday) + rffi.setintfield(glob_buf, 'c_tm_hour', tup[3]) + rffi.setintfield(glob_buf, 'c_tm_min', tup[4]) + rffi.setintfield(glob_buf, 'c_tm_sec', tup[5]) + rffi.setintfield(glob_buf, 'c_tm_wday', tup[6]) + rffi.setintfield(glob_buf, 'c_tm_yday', tm_yday) + rffi.setintfield(glob_buf, 'c_tm_isdst', tup[8]) + if _POSIX: + if _CYGWIN: + pass + else: + # actually never happens, but makes annotator happy + glob_buf.c_tm_zone = lltype.nullptr(rffi.CCHARP.TO) + rffi.setintfield(glob_buf, 'c_tm_gmtoff', 0) + + if y < 1900: + if 69 <= y <= 99: + y += 1900 + elif 0 <= y <= 68: + y += 2000 + else: + raise Exception("year out of range") + + # tm_wday does not need checking of its upper-bound since taking "% + # 7" in gettmarg() automatically restricts the range. + if rffi.getintfield(glob_buf, 'c_tm_wday') < -1: + raise Exception("day of week out of range") + + rffi.setintfield(glob_buf, 'c_tm_year', y - 1900) + rffi.setintfield(glob_buf, 'c_tm_mon', rffi.getintfield(glob_buf, 'c_tm_mon') - 1) + rffi.setintfield(glob_buf, 'c_tm_wday', (rffi.getintfield(glob_buf, 'c_tm_wday') + 1) % 7) + rffi.setintfield(glob_buf, 'c_tm_yday', rffi.getintfield(glob_buf, 'c_tm_yday') - 1) + + return glob_buf + + +def gmtime(time_t): + seconds = time_t + t_ref = lltype.malloc(rffi.TIME_TP.TO, 1, flavor='raw') + t_ref[0] = seconds + p = c_gmtime(t_ref) + lltype.free(t_ref, flavor='raw') + return _tm_to_tuple(p) + + +def localtime(time_t): + seconds = time_t + t_ref = lltype.malloc(rffi.TIME_TP.TO, 1, flavor='raw') + t_ref[0] = seconds + p = c_localtime(t_ref) + lltype.free(t_ref, flavor='raw') + return _tm_to_tuple(p) + + +def mktime(tup): + buf = _gettmarg(tup) + rffi.setintfield(buf, "c_tm_wday", -1) + tt = c_mktime(buf) + if tt == -1 and rffi.getintfield(buf, "c_tm_wday") == -1: + raise Exception('mktime argument out of range') + + return float(tt) + + +def tzset(): + c_tzset() + + +def timegm(tup): + tz = os.environ.get('TZ') + os.environ['TZ'] = '' + tzset() + + try: + tt = mktime(tup) + finally: + if tz: + os.environ['TZ'] = tz + else: + del os.environ['TZ'] + tzset() + + return tt + + +def strftime(format, time_t): + """strftime(format[, tuple]) -> string + + Convert a time tuple to a string according to a format specification. + See the library reference manual for formatting codes. When the time tuple + is not present, current time as returned by localtime() is used.""" + buf_value = _gettmarg(time_t) + + # Checks added to make sure strftime() does not crash Python by + # indexing blindly into some array for a textual representation + # by some bad index (fixes bug #897625). + # No check for year since handled in gettmarg(). + if rffi.getintfield(buf_value, 'c_tm_mon') < 0 or rffi.getintfield(buf_value, 'c_tm_mon') > 11: + raise Exception("month out of range") + if rffi.getintfield(buf_value, 'c_tm_mday') < 1 or rffi.getintfield(buf_value, 'c_tm_mday') > 31: + raise Exception("day of month out of range") + if rffi.getintfield(buf_value, 'c_tm_hour') < 0 or rffi.getintfield(buf_value, 'c_tm_hour') > 23: + raise Exception("hour out of range") + if rffi.getintfield(buf_value, 'c_tm_min') < 0 or rffi.getintfield(buf_value, 'c_tm_min') > 59: + raise Exception("minute out of range") + if rffi.getintfield(buf_value, 'c_tm_sec') < 0 or rffi.getintfield(buf_value, 'c_tm_sec') > 61: + raise Exception("seconds out of range") + if rffi.getintfield(buf_value, 'c_tm_yday') < 0 or rffi.getintfield(buf_value, 'c_tm_yday') > 365: + raise Exception("day of year out of range") + if rffi.getintfield(buf_value, 'c_tm_isdst') < -1 or rffi.getintfield(buf_value, 'c_tm_isdst') > 1: + raise Exception("daylight savings flag out of range") + + if _WIN: + # check that the format string contains only valid directives + length = len(format) + i = 0 + while i < length: + if format[i] == '%': + i += 1 + if i < length and format[i] == '#': + # not documented by python + i += 1 + if i >= length or format[i] not in "aAbBcdHIjmMpSUwWxXyYzZ%": + raise Exception("invalid format string") + i += 1 + + i = 1024 + while True: + outbuf = lltype.malloc(rffi.CCHARP.TO, i, flavor='raw') + try: + buflen = c_strftime(outbuf, i, format, buf_value) + if buflen > 0 or i >= 256 * len(format): + # if the buffer is 256 times as long as the format, + # it's probably not failing for lack of room! + # More likely, the format yields an empty result, + # e.g. an empty format, or %Z when the timezone + # is unknown. + result = rffi.charp2strn(outbuf, intmask(buflen)) + return result + finally: + lltype.free(outbuf, flavor='raw') + i += i diff --git a/test/test_js_time.py b/test/test_js_time.py new file mode 100644 --- /dev/null +++ b/test/test_js_time.py @@ -0,0 +1,97 @@ +from js.builtins.date import JsTime + + +class TestJsTime(object): + # Sun, 17 Feb 2013 14:58:35 GMT + T = 1361113115765 + + def _new_t(self): + return JsTime(self.T) + + def test_to_msecs(self): + t = self._new_t() + assert t.to_msec_epoc() == self.T + + def test_year(self): + t = self._new_t() + assert t.year() == 2013 + + def test_month(self): + t = self._new_t() + assert t.month() == 2 + + def test_day(self): + t = self._new_t() + assert t.day() == 17 + + def test_hour(self): + t = self._new_t() + assert t.hour() == 14 + + def test_min(self): + t = self._new_t() + assert t.min() == 58 + + def test_sec(self): + t = self._new_t() + assert t.sec() == 35 + + def test_set_year(self): + t = self._new_t() + t.set_year(2012) + assert t.year() == 2012 + + def test_set_month(self): + t = self._new_t() + t.set_month(4) + assert t.month() == 4 + + def test_set_month_local(self): + t = self._new_t() + t.set_month(4, local=True) + assert t.month(local=True) == 4 + + def test_set_day(self): + t = self._new_t() + t.set_day(23) + assert t.day() == 23 + + def test_set_day_local(self): + t = self._new_t() + t.set_day(23, local=True) + assert t.day(local=True) == 23 + + def test_set_hour(self): + t = self._new_t() + t.set_hour(23) + assert t.hour() == 23 + + def test_set_hour_local(self): + t = self._new_t() + t.set_hour(23, local=True) + assert t.hour(local=True) == 23 + + def test_set_min(self): + t = self._new_t() + t.set_min(42) + assert t.min() == 42 + + def test_set_min_local(self): + t = self._new_t() + t.set_min(42, local=True) + assert t.min(local=True) == 42 + + def test_set_sec(self): + t = self._new_t() + t.set_sec(42) + assert t.sec() == 42 + + def test_set_sec_local(self): + t = self._new_t() + t.set_sec(42, local=True) + assert t.sec(local=True) == 42 + + def test_set_msec(self): + t = self._new_t() + t.set_msec(42) + assert t.msec() == 42 From noreply at buildbot.pypy.org Tue Feb 19 20:17:45 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Tue, 19 Feb 2013 20:17:45 +0100 (CET) Subject: [pypy-commit] pypy py3k: revert the 'reset to g' from 52765baaf1aa, as we're backed by rpython's Message-ID: <20130219191745.4A2921C054C@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61460:63a6abfa0512 Date: 2013-02-19 10:55 -0800 http://bitbucket.org/pypy/pypy/changeset/63a6abfa0512/ Log: revert the 'reset to g' from 52765baaf1aa, as we're backed by rpython's rfloat.double_to_string we need 'r' diff --git a/pypy/objspace/std/newformat.py b/pypy/objspace/std/newformat.py --- a/pypy/objspace/std/newformat.py +++ b/pypy/objspace/std/newformat.py @@ -935,9 +935,9 @@ tp = self._type self._get_locale(tp) if tp == "\0": + flags |= rfloat.DTSF_ADD_DOT_0 tp = "r" default_precision = 0 - flags |= rfloat.DTSF_ADD_DOT_0 elif tp == "n": tp = "g" value = space.float_w(w_float) @@ -949,8 +949,6 @@ add_pct = False if self._precision == -1: self._precision = default_precision - if tp == "r": - type = "g" result, special = rfloat.double_to_string(value, tp, self._precision, flags) if add_pct: From noreply at buildbot.pypy.org Tue Feb 19 20:17:46 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Tue, 19 Feb 2013 20:17:46 +0100 (CET) Subject: [pypy-commit] pypy py3k: cache UnsupportedOperation to avoid issues w/ io being frozen, fix __module__ Message-ID: <20130219191746.B547D1C054C@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61461:9813b8a36001 Date: 2013-02-19 10:57 -0800 http://bitbucket.org/pypy/pypy/changeset/9813b8a36001/ Log: cache UnsupportedOperation to avoid issues w/ io being frozen, fix __module__ again diff --git a/pypy/module/_io/__init__.py b/pypy/module/_io/__init__.py --- a/pypy/module/_io/__init__.py +++ b/pypy/module/_io/__init__.py @@ -9,6 +9,8 @@ interpleveldefs = { 'DEFAULT_BUFFER_SIZE': 'space.wrap(interp_iobase.DEFAULT_BUFFER_SIZE)', 'BlockingIOError': 'interp_io.W_BlockingIOError', + 'UnsupportedOperation': + 'space.fromcache(interp_io.Cache).w_unsupportedoperation', '_IOBase': 'interp_iobase.W_IOBase', '_RawIOBase': 'interp_iobase.W_RawIOBase', '_BufferedIOBase': 'interp_bufferedio.W_BufferedIOBase', @@ -27,16 +29,6 @@ 'IncrementalNewlineDecoder': 'interp_textio.W_IncrementalNewlineDecoder', } - def init(self, space): - MixedModule.init(self, space) - w_UnsupportedOperation = space.call_function( - space.w_type, - space.wrap('UnsupportedOperation'), - space.newtuple([space.w_ValueError, space.w_IOError]), - space.newdict()) - space.setattr(self, space.wrap('UnsupportedOperation'), - w_UnsupportedOperation) - def shutdown(self, space): # at shutdown, flush all open streams. Ignore I/O errors. from pypy.module._io.interp_iobase import get_autoflushher diff --git a/pypy/module/_io/interp_io.py b/pypy/module/_io/interp_io.py --- a/pypy/module/_io/interp_io.py +++ b/pypy/module/_io/interp_io.py @@ -10,6 +10,12 @@ from rpython.rtyper.module.ll_os_stat import STAT_FIELD_TYPES +class Cache: + def __init__(self, space): + self.w_unsupportedoperation = space.new_exception_class( + "io.UnsupportedOperation", + space.newtuple([space.w_ValueError, space.w_IOError])) + class W_BlockingIOError(W_IOError): def __init__(self, space): W_IOError.__init__(self, space) @@ -22,6 +28,7 @@ W_BlockingIOError.typedef = TypeDef( 'BlockingIOError', W_IOError.typedef, + __module__ = 'io', __doc__ = ("Exception raised when I/O would block " "on a non-blocking I/O stream"), __new__ = generic_new_descr(W_BlockingIOError), diff --git a/pypy/module/_io/test/test_io.py b/pypy/module/_io/test/test_io.py --- a/pypy/module/_io/test/test_io.py +++ b/pypy/module/_io/test/test_io.py @@ -373,5 +373,5 @@ def test_mod(self): import _io - assert all(t.__module__ == '_io' for t in dir(_io) + assert all(t.__module__ in ('io', '_io') for t in vars(_io).values() if isinstance(t, type)) From noreply at buildbot.pypy.org Tue Feb 19 20:17:48 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Tue, 19 Feb 2013 20:17:48 +0100 (CET) Subject: [pypy-commit] pypy py3k: attempt to fix test_fork.test_nested_import_lock_fork (the test seems to Message-ID: <20130219191748.31D9C1C054C@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61462:91f21023331b Date: 2013-02-19 11:11 -0800 http://bitbucket.org/pypy/pypy/changeset/91f21023331b/ Log: attempt to fix test_fork.test_nested_import_lock_fork (the test seems to require translation) diff --git a/pypy/module/imp/importing.py b/pypy/module/imp/importing.py --- a/pypy/module/imp/importing.py +++ b/pypy/module/imp/importing.py @@ -786,9 +786,18 @@ def reinit_lock(self): # Called after fork() to ensure that newly created child # processes do not share locks with the parent - self.lock = None - self.lockowner = None - self.lockcounter = 0 + if self.lockcounter > 1: + # Forked as a side effect of import + self.lock = self.space.allocate_lock() + me = self.space.getexecutioncontext() + self.lock.acquire(True) + # XXX: can the previous line fail? + self.lockowner = me + self.lockcounter -= 1 + else: + self.lock = None + self.lockowner = None + self.lockcounter = 0 def getimportlock(space): return space.fromcache(ImportRLock) diff --git a/pypy/module/thread/test/test_fork.py b/pypy/module/thread/test/test_fork.py --- a/pypy/module/thread/test/test_fork.py +++ b/pypy/module/thread/test/test_fork.py @@ -1,6 +1,8 @@ from pypy.module.thread.test.support import GenericTestThread class AppTestFork(GenericTestThread): + spaceconfig = dict(usemodules=GenericTestThread.spaceconfig['usemodules'] + ('imp',)) + def test_fork_with_thread(self): # XXX This test depends on a multicore machine, as busy_thread must # aquire the GIL the instant that the main thread releases it. @@ -84,3 +86,45 @@ # if 9, process was killed by timer. # if 42<<8, os._exit(42) was correctly reached. assert feedback == [42<<8] + + def test_nested_import_lock_fork(self): + """Check fork() in main thread works while the main thread is doing an import""" + # Issue 9573: this used to trigger RuntimeError in the child process + import imp + import os + import time + + def fork_with_import_lock(level): + release = 0 + in_child = False + try: + try: + for i in range(level): + imp.acquire_lock() + release += 1 + pid = os.fork() + in_child = not pid + finally: + for i in range(release): + imp.release_lock() + except RuntimeError: + if in_child: + if verbose > 1: + print("RuntimeError in child") + os._exit(1) + raise + if in_child: + os._exit(0) + + for i in range(10): + spid, status = os.waitpid(pid, os.WNOHANG) + if spid == pid: + break + time.sleep(1.0) + assert spid == pid + assert status == 0 + + # Check this works with various levels of nested + # import in the main thread + for level in range(5): + fork_with_import_lock(level) From noreply at buildbot.pypy.org Tue Feb 19 20:17:49 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Tue, 19 Feb 2013 20:17:49 +0100 (CET) Subject: [pypy-commit] pypy py3k: fix some IOError -> UnsupportedOperation Message-ID: <20130219191749.8FD841C054C@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61463:5bdfc3da631a Date: 2013-02-19 11:12 -0800 http://bitbucket.org/pypy/pypy/changeset/5bdfc3da631a/ Log: fix some IOError -> UnsupportedOperation diff --git a/pypy/module/_io/interp_textio.py b/pypy/module/_io/interp_textio.py --- a/pypy/module/_io/interp_textio.py +++ b/pypy/module/_io/interp_textio.py @@ -716,7 +716,7 @@ self._check_closed(space) if not self.w_encoder: - raise OperationError(space.w_IOError, space.wrap("not writable")) + self._unsupportedoperation(space, "not writable") text = space.unicode_w(w_text) textlen = len(text) @@ -817,8 +817,8 @@ if whence == 1: # seek relative to current position if not space.is_true(space.eq(w_pos, space.wrap(0))): - raise OperationError(space.w_IOError, space.wrap( - "can't do nonzero cur-relative seeks")) + self._unsupportedoperation( + space, "can't do nonzero cur-relative seeks") # Seeking to the current position should attempt to sync the # underlying buffer with the current position. w_pos = space.call_method(self, "tell") @@ -826,8 +826,8 @@ elif whence == 2: # seek relative to end of file if not space.is_true(space.eq(w_pos, space.wrap(0))): - raise OperationError(space.w_IOError, space.wrap( - "can't do nonzero end-relative seeks")) + self._unsupportedoperation( + space, "can't do nonzero end-relative seeks") space.call_method(self, "flush") self._set_decoded_chars(None) self.snapshot = None diff --git a/pypy/module/_io/test/test_textio.py b/pypy/module/_io/test/test_textio.py --- a/pypy/module/_io/test/test_textio.py +++ b/pypy/module/_io/test/test_textio.py @@ -42,6 +42,21 @@ txt = _io.TextIOWrapper(UnReadable()) raises(IOError, txt.read) + def test_unwritable(self): + import _io + class UnWritable(_io.BytesIO): + def writable(self): + return False + txt = _io.TextIOWrapper(UnWritable()) + raises(_io.UnsupportedOperation, txt.write, "blah") + raises(_io.UnsupportedOperation, txt.writelines, ["blah\n"]) + + def test_invalid_seek(self): + import _io + t = _io.TextIOWrapper(_io.BytesIO(b"\xc3\xa9\n\n")) + raises(_io.UnsupportedOperation, t.seek, 1, 1) + raises(_io.UnsupportedOperation, t.seek, 1, 2) + def test_unseekable(self): import _io class Unseekable(_io.BytesIO): From noreply at buildbot.pypy.org Tue Feb 19 20:24:34 2013 From: noreply at buildbot.pypy.org (fijal) Date: Tue, 19 Feb 2013 20:24:34 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: a failing test Message-ID: <20130219192434.78E171C054C@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61464:ee50f2d7022a Date: 2013-02-19 15:43 +0200 http://bitbucket.org/pypy/pypy/changeset/ee50f2d7022a/ Log: a failing test diff --git a/rpython/jit/backend/llsupport/llmodel.py b/rpython/jit/backend/llsupport/llmodel.py --- a/rpython/jit/backend/llsupport/llmodel.py +++ b/rpython/jit/backend/llsupport/llmodel.py @@ -79,6 +79,8 @@ base_ofs = self.get_baseofs_of_frame_field() def realloc_frame(frame, size): + if not we_are_translated(): + assert not self._exception_emulator[0] frame = lltype.cast_opaque_ptr(jitframe.JITFRAMEPTR, frame) if size > frame.jf_frame_info.jfi_frame_depth: # update the frame_info size, which is for whatever reason diff --git a/rpython/jit/backend/test/runner_test.py b/rpython/jit/backend/test/runner_test.py --- a/rpython/jit/backend/test/runner_test.py +++ b/rpython/jit/backend/test/runner_test.py @@ -3796,3 +3796,62 @@ frame = lltype.cast_opaque_ptr(jitframe.JITFRAMEPTR, frame) assert len(frame.jf_frame) == frame.jf_frame_info.jfi_frame_depth + + def test_compile_bridge_while_running_guard_no_exc(self): + xtp = lltype.malloc(rclass.OBJECT_VTABLE, immortal=True) + xtp.subclassrange_min = 1 + xtp.subclassrange_max = 3 + X = lltype.GcStruct('X', ('parent', rclass.OBJECT), + hints={'vtable': xtp._obj}) + xptr = lltype.cast_opaque_ptr(llmemory.GCREF, lltype.malloc(X)) + def raising(): + bridge = parse(""" + [i1, i2] + guard_exception(ConstClass(xtp), descr=faildescr2) [i1, i2] + i3 = int_add(i1, i2) + i4 = int_add(i1, i3) + i5 = int_add(i1, i4) + i6 = int_add(i4, i5) + i7 = int_add(i6, i5) + i8 = int_add(i5, 1) + i9 = int_add(i8, 1) + force_spill(i1) + force_spill(i2) + force_spill(i3) + force_spill(i4) + force_spill(i5) + force_spill(i6) + force_spill(i7) + force_spill(i8) + force_spill(i9) + guard_true(i9) [i3, i4, i5, i6, i7, i8, i9] + finish(i9, descr=finaldescr) + """, namespace={'finaldescr': BasicFinalDescr(42), + 'faildescr2': BasicFailDescr(1), + 'xtp': xtp + }) + self.cpu.compile_bridge(faildescr, bridge.inputargs, + bridge.operations, looptoken) + raise LLException(xtp, xptr) + + faildescr = BasicFailDescr(0) + FUNC = self.FuncType([], lltype.Void) + raising_ptr = llhelper(lltype.Ptr(FUNC), raising) + calldescr = self.cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, + EffectInfo.MOST_GENERAL) + + looptoken = JitCellToken() + loop = parse(""" + [i0, i1, i2] + call(ConstClass(raising_ptr), descr=calldescr) + guard_no_exception(descr=faildescr) [i1, i2] + finish(i2, descr=finaldescr2) + """, namespace={'raising_ptr': raising_ptr, + 'calldescr': calldescr, + 'faildescr': faildescr, + 'finaldescr2': BasicFinalDescr(1)}) + + self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) + frame = self.cpu.execute_token(looptoken, 1, 2, 3) + descr = self.cpu.get_latest_descr(frame) + assert descr.identifier == 42 From noreply at buildbot.pypy.org Tue Feb 19 20:24:35 2013 From: noreply at buildbot.pypy.org (fijal) Date: Tue, 19 Feb 2013 20:24:35 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: store and restore exceptions around things that can call with exception set Message-ID: <20130219192435.BACB91C054C@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61465:de3007aed4f3 Date: 2013-02-19 21:22 +0200 http://bitbucket.org/pypy/pypy/changeset/de3007aed4f3/ Log: store and restore exceptions around things that can call with exception set diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -138,25 +138,31 @@ mc.MOV_rs(ecx.value, WORD) gcmap_ofs = self.cpu.get_ofs_of_frame_field('jf_gcmap') mc.MOV_br(gcmap_ofs, ecx.value) + if IS_X86_64: - # this is size that we're after, sanity checking only mc.MOV_rs(esi.value, WORD*2) # push first arg mc.MOV_rr(edi.value, ebp.value) align = align_stack_words(1) mc.SUB_ri(esp.value, (align - 1) * WORD) + exc0, exc1 = ebx, r12 # callee saved regs for storing exc else: align = align_stack_words(3) mc.MOV_rs(eax.value, WORD * 2) mc.SUB_ri(esp.value, (align - 1) * WORD) mc.MOV_sr(WORD, eax.value) mc.MOV_sr(0, ebp.value) + exc0, exc1 = esi, edi # callee saved regs for storing exc # align + self._store_and_reset_exception(mc, exc0, exc1) + mc.CALL(imm(self.cpu.realloc_frame)) + self._restore_exception(mc, exc0, exc1) mc.ADD_ri(esp.value, (align - 1) * WORD) mc.MOV_rr(ebp.value, eax.value) + gcrootmap = self.cpu.gc_ll_descr.gcrootmap if gcrootmap and gcrootmap.is_shadow_stack: self._load_shadowstack_top_in_ebx(mc, gcrootmap) @@ -224,7 +230,7 @@ # # read and reset the current exception - self._store_and_reset_exception(eax) + self._store_and_reset_exception(self.mc, eax) ofs = self.cpu.get_ofs_of_frame_field('jf_guard_exc') self.mc.MOV_br(ofs, eax.value) propagate_exception_descr = rffi.cast(lltype.Signed, @@ -289,6 +295,7 @@ def _build_wb_slowpath(self, withcards, withfloats=False, for_frame=False): descr = self.cpu.gc_ll_descr.write_barrier_descr + exc0, exc1 = None, None if descr is None: return if not withcards: @@ -329,8 +336,11 @@ if IS_X86_32: mc.MOV_sr(4 * WORD, edx.value) mc.MOV_sr(0, ebp.value) + exc0, exc1 = esi, edi else: mc.MOV_rr(edi.value, ebp.value) + exc0, exc1 = ebx, r12 + self._store_and_reset_exception(mc, exc0, exc1) mc.CALL(imm(func)) # @@ -357,6 +367,7 @@ mc.MOV_rs(edx.value, 4 * WORD) mc.MOVSD_xs(xmm0.value, 3 * WORD) mc.MOV_rs(eax.value, WORD) # restore + self._restore_exception(mc, exc0, exc1) mc.LEA_rs(esp.value, 6 * WORD) mc.RET() @@ -1709,13 +1720,22 @@ self.mc.MOV(loc1, heap(self.cpu.pos_exception())) self.mc.CMP(loc1, loc) self.implement_guard(guard_token, 'NE') - self._store_and_reset_exception(resloc) + self._store_and_reset_exception(self.mc, resloc) - def _store_and_reset_exception(self, resloc=None): - if resloc is not None: - self.mc.MOV(resloc, heap(self.cpu.pos_exc_value())) - self.mc.MOV(heap(self.cpu.pos_exception()), imm0) - self.mc.MOV(heap(self.cpu.pos_exc_value()), imm0) + def _store_and_reset_exception(self, mc, excvalloc=None, exctploc=None): + if excvalloc is not None: + assert excvalloc.is_reg() + mc.MOV(excvalloc, heap(self.cpu.pos_exc_value())) + if exctploc is not None: + assert exctploc.is_reg() + mc.MOV(exctploc, heap(self.cpu.pos_exception())) + + mc.MOV(heap(self.cpu.pos_exception()), imm0) + mc.MOV(heap(self.cpu.pos_exc_value()), imm0) + + def _restore_exception(self, mc, excvalloc, exctploc): + mc.MOV(heap(self.cpu.pos_exc_value()), excvalloc) + mc.MOV(heap(self.cpu.pos_exception()), exctploc) def _gen_guard_overflow(self, guard_op, guard_token): guard_opnum = guard_op.getopnum() From noreply at buildbot.pypy.org Tue Feb 19 20:24:37 2013 From: noreply at buildbot.pypy.org (fijal) Date: Tue, 19 Feb 2013 20:24:37 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: merge Message-ID: <20130219192437.0913B1C054C@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61466:d19b75514eb9 Date: 2013-02-19 21:23 +0200 http://bitbucket.org/pypy/pypy/changeset/d19b75514eb9/ Log: merge diff --git a/rpython/jit/backend/arm/opassembler.py b/rpython/jit/backend/arm/opassembler.py --- a/rpython/jit/backend/arm/opassembler.py +++ b/rpython/jit/backend/arm/opassembler.py @@ -1234,7 +1234,7 @@ if gcrootmap: self.call_reacquire_gil(gcrootmap, resloc, fcond) - self._emit_guard_may_force(guard_op, arglocs, numargs) + self._emit_guard_may_force(guard_op, arglocs[numargs+1:], numargs) return fcond def call_release_gil(self, gcrootmap, save_registers, fcond): diff --git a/rpython/jit/backend/arm/test/test_jump.py b/rpython/jit/backend/arm/test/test_jump.py --- a/rpython/jit/backend/arm/test/test_jump.py +++ b/rpython/jit/backend/arm/test/test_jump.py @@ -6,7 +6,8 @@ from rpython.jit.backend.arm.jump import remap_frame_layout, remap_frame_layout_mixed from rpython.jit.metainterp.history import INT -frame_pos = ARMFrameManager.frame_pos +fm = ARMFrameManager(0) +frame_pos = fm.frame_pos class MockAssembler: def __init__(self): diff --git a/rpython/jit/backend/arm/test/test_runner.py b/rpython/jit/backend/arm/test/test_runner.py --- a/rpython/jit/backend/arm/test/test_runner.py +++ b/rpython/jit/backend/arm/test/test_runner.py @@ -23,8 +23,7 @@ # for the individual tests see # ====> ../../test/runner_test.py - add_loop_instructions = ['nop', # this is the same as mov r0, r0 - 'adds', 'cmp', 'beq', 'b'] + add_loop_instructions = ['ldr', 'mov', 'adds', 'cmp', 'beq', 'b'] bridge_loop_instructions = ['movw', 'movt', 'bx'] def get_cpu(self): diff --git a/rpython/jit/backend/tool/viewcode.py b/rpython/jit/backend/tool/viewcode.py --- a/rpython/jit/backend/tool/viewcode.py +++ b/rpython/jit/backend/tool/viewcode.py @@ -69,7 +69,7 @@ 'file': tmpfile, 'origin': originaddr, 'backend': objdump_backend_option[backend_name], - 'machine': 'i386' if backend_name != 'arm' else 'arm', + 'machine': 'i386' if not backend_name.startswith('arm') else 'arm', }, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = p.communicate() assert not p.returncode, ('Encountered an error running objdump: %s' % From noreply at buildbot.pypy.org Tue Feb 19 22:17:20 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Tue, 19 Feb 2013 22:17:20 +0100 (CET) Subject: [pypy-commit] pypy py3k: merge default Message-ID: <20130219211720.3C2E71C054C@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61467:157047561a6d Date: 2013-02-19 13:07 -0800 http://bitbucket.org/pypy/pypy/changeset/157047561a6d/ Log: merge default diff too long, truncating to 2000 out of 2945 lines diff --git a/pypy/doc/getting-started-dev.rst b/pypy/doc/getting-started-dev.rst --- a/pypy/doc/getting-started-dev.rst +++ b/pypy/doc/getting-started-dev.rst @@ -58,8 +58,7 @@ only use low level types that are available in C (e.g. int). The compiled version is now in a ``.so`` library. You can run it say using ctypes: - >>> from ctypes import CDLL - >>> f = CDLL(lib) + >>> f = get_c_function(lib, snippet.is_perfect_number) >>> f(5) 0 >>> f(6) diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst --- a/pypy/doc/whatsnew-head.rst +++ b/pypy/doc/whatsnew-head.rst @@ -19,7 +19,7 @@ .. branch: numpypy-longdouble Long double support for numpypy .. branch: numpypy-real-as-view -Convert real, imag from ufuncs to views. This involves the beginning of +Convert real, imag from ufuncs to views. This involves the beginning of view() functionality .. branch: signatures @@ -57,7 +57,11 @@ .. branch: cleanup-tests Consolidated the lib_pypy/pypy_test and pypy/module/test_lib_pypy tests into -+one directory for reduced confusion and so they all run nightly. +one directory for reduced confusion and so they all run nightly. .. branch: unquote-faster .. branch: urlparse-unquote-faster + +.. branch: signal-and-thread +Add "__pypy__.thread.signals_enabled", a context manager. Can be used in a +non-main thread to enable the processing of signal handlers in that thread. diff --git a/pypy/interpreter/miscutils.py b/pypy/interpreter/miscutils.py --- a/pypy/interpreter/miscutils.py +++ b/pypy/interpreter/miscutils.py @@ -20,10 +20,10 @@ def signals_enabled(self): return True - def enable_signals(self): + def enable_signals(self, space): pass - def disable_signals(self): + def disable_signals(self, space): pass def getallvalues(self): diff --git a/pypy/interpreter/pycode.py b/pypy/interpreter/pycode.py --- a/pypy/interpreter/pycode.py +++ b/pypy/interpreter/pycode.py @@ -67,16 +67,17 @@ kwargname = None return Signature(argnames, varargname, kwargname, kwonlyargs) + class PyCode(eval.Code): "CPython-style code objects." _immutable_ = True _immutable_fields_ = ["co_consts_w[*]", "co_names_w[*]", "co_varnames[*]", - "co_freevars[*]", "co_cellvars[*]"] + "co_freevars[*]", "co_cellvars[*]", "_args_as_cellvars[*]"] def __init__(self, space, argcount, kwonlyargcount, nlocals, stacksize, flags, code, consts, names, varnames, filename, name, firstlineno, lnotab, freevars, cellvars, - hidden_applevel=False, magic = default_magic): + hidden_applevel=False, magic=default_magic): """Initialize a new code object from parameters given by the pypy compiler""" self.space = space @@ -105,8 +106,6 @@ def _initialize(self): self._init_flags() - # Precompute what arguments need to be copied into cellvars - self._args_as_cellvars = [] if self.co_cellvars: argcount = self.co_argcount @@ -125,16 +124,22 @@ # produced by CPython are loaded by PyPy. Note that CPython # contains the following bad-looking nested loops at *every* # function call! - argvars = self.co_varnames + + # Precompute what arguments need to be copied into cellvars + args_as_cellvars = [] + argvars = self.co_varnames cellvars = self.co_cellvars for i in range(len(cellvars)): cellname = cellvars[i] for j in range(argcount): if cellname == argvars[j]: # argument j has the same name as the cell var i - while len(self._args_as_cellvars) <= i: - self._args_as_cellvars.append(-1) # pad - self._args_as_cellvars[i] = j + while len(args_as_cellvars) <= i: + args_as_cellvars.append(-1) # pad + args_as_cellvars[i] = j + self._args_as_cellvars = args_as_cellvars[:] + else: + self._args_as_cellvars = [] self._compute_flatcall() diff --git a/pypy/module/__builtin__/functional.py b/pypy/module/__builtin__/functional.py --- a/pypy/module/__builtin__/functional.py +++ b/pypy/module/__builtin__/functional.py @@ -103,56 +103,77 @@ w_stop = w_length return w_start, w_stop, w_step +min_jitdriver = jit.JitDriver(name='min', + greens=['w_type'], reds='auto') +max_jitdriver = jit.JitDriver(name='max', + greens=['w_type'], reds='auto') + +def make_min_max(unroll): + @specialize.arg(2) + def min_max_impl(space, args, implementation_of): + if implementation_of == "max": + compare = space.gt + jitdriver = max_jitdriver + else: + compare = space.lt + jitdriver = min_jitdriver + args_w = args.arguments_w + if len(args_w) > 1: + w_sequence = space.newtuple(args_w) + elif len(args_w): + w_sequence = args_w[0] + else: + msg = "%s() expects at least one argument" % (implementation_of,) + raise OperationError(space.w_TypeError, space.wrap(msg)) + w_key = None + kwds = args.keywords + if kwds: + if kwds[0] == "key" and len(kwds) == 1: + w_key = args.keywords_w[0] + else: + msg = "%s() got unexpected keyword argument" % (implementation_of,) + raise OperationError(space.w_TypeError, space.wrap(msg)) + + w_iter = space.iter(w_sequence) + w_type = space.type(w_iter) + w_max_item = None + w_max_val = None + while True: + if not unroll: + jitdriver.jit_merge_point(w_type=w_type) + try: + w_item = space.next(w_iter) + except OperationError, e: + if not e.match(space, space.w_StopIteration): + raise + break + if w_key is not None: + w_compare_with = space.call_function(w_key, w_item) + else: + w_compare_with = w_item + if w_max_item is None or \ + space.is_true(compare(w_compare_with, w_max_val)): + w_max_item = w_item + w_max_val = w_compare_with + if w_max_item is None: + msg = "arg is an empty sequence" + raise OperationError(space.w_ValueError, space.wrap(msg)) + return w_max_item + if unroll: + min_max_impl = jit.unroll_safe(min_max_impl) + return min_max_impl + +min_max_unroll = make_min_max(True) +min_max_normal = make_min_max(False) @specialize.arg(2) - at jit.look_inside_iff(lambda space, args, implementation_of: - jit.isconstant(len(args.arguments_w)) and - len(args.arguments_w) == 2 -) def min_max(space, args, implementation_of): - if implementation_of == "max": - compare = space.gt + if not jit.we_are_jitted() or (jit.isconstant(len(args.arguments_w)) and + len(args.arguments_w) == 2): + return min_max_unroll(space, args, implementation_of) else: - compare = space.lt - args_w = args.arguments_w - if len(args_w) > 1: - w_sequence = space.newtuple(args_w) - elif len(args_w): - w_sequence = args_w[0] - else: - msg = "%s() expects at least one argument" % (implementation_of,) - raise OperationError(space.w_TypeError, space.wrap(msg)) - w_key = None - kwds = args.keywords - if kwds: - if kwds[0] == "key" and len(kwds) == 1: - w_key = args.keywords_w[0] - else: - msg = "%s() got unexpected keyword argument" % (implementation_of,) - raise OperationError(space.w_TypeError, space.wrap(msg)) - - w_iter = space.iter(w_sequence) - w_max_item = None - w_max_val = None - while True: - try: - w_item = space.next(w_iter) - except OperationError, e: - if not e.match(space, space.w_StopIteration): - raise - break - if w_key is not None: - w_compare_with = space.call_function(w_key, w_item) - else: - w_compare_with = w_item - if w_max_item is None or \ - space.is_true(compare(w_compare_with, w_max_val)): - w_max_item = w_item - w_max_val = w_compare_with - if w_max_item is None: - msg = "arg is an empty sequence" - raise OperationError(space.w_ValueError, space.wrap(msg)) - return w_max_item + return min_max_normal(space, args, implementation_of) +min_max._always_inline = True def max(space, __args__): """max(iterable[, key=func]) -> value diff --git a/pypy/module/__pypy__/interp_signal.py b/pypy/module/__pypy__/interp_signal.py --- a/pypy/module/__pypy__/interp_signal.py +++ b/pypy/module/__pypy__/interp_signal.py @@ -1,6 +1,6 @@ def signals_enter(space): - space.threadlocals.enable_signals() + space.threadlocals.enable_signals(space) def signals_exit(space, w_ignored1=None, w_ignored2=None, w_ignored3=None): - space.threadlocals.disable_signals() + space.threadlocals.disable_signals(space) diff --git a/pypy/module/__pypy__/test/test_signal.py b/pypy/module/__pypy__/test/test_signal.py --- a/pypy/module/__pypy__/test/test_signal.py +++ b/pypy/module/__pypy__/test/test_signal.py @@ -1,5 +1,7 @@ import sys +from pypy.module.thread.test.support import GenericTestThread + class AppTestMinimal: spaceconfig = dict(usemodules=['__pypy__']) @@ -11,9 +13,17 @@ # assert did not crash -class AppTestThreadSignal: +class AppTestThreadSignal(GenericTestThread): spaceconfig = dict(usemodules=['__pypy__', 'thread', 'signal', 'time']) + def test_exit_twice(self): + import __pypy__, thread + __pypy__.thread._signals_exit() + try: + raises(thread.error, __pypy__.thread._signals_exit) + finally: + __pypy__.thread._signals_enter() + def test_enable_signals(self): import __pypy__, _thread, signal, time @@ -48,6 +58,37 @@ finally: __pypy__.thread._signals_enter() + def test_thread_fork_signals(self): + import __pypy__ + import os, thread, signal + + if not hasattr(os, 'fork'): + skip("No fork on this platform") + + def fork(): + with __pypy__.thread.signals_enabled: + return os.fork() + + def threadfunction(): + pid = fork() + if pid == 0: + print 'in child' + # signal() only works from the 'main' thread + signal.signal(signal.SIGUSR1, signal.SIG_IGN) + os._exit(42) + else: + self.timeout_killer(pid, 5) + exitcode = os.waitpid(pid, 0)[1] + feedback.append(exitcode) + + feedback = [] + thread.start_new_thread(threadfunction, ()) + self.waitfor(lambda: feedback) + # if 0, an (unraisable) exception was raised from the forked thread. + # if 9, process was killed by timer. + # if 42<<8, os._exit(42) was correctly reached. + assert feedback == [42<<8] + class AppTestThreadSignalLock: spaceconfig = dict(usemodules=['__pypy__', 'thread', 'signal']) diff --git a/pypy/module/_cffi_backend/newtype.py b/pypy/module/_cffi_backend/newtype.py --- a/pypy/module/_cffi_backend/newtype.py +++ b/pypy/module/_cffi_backend/newtype.py @@ -264,8 +264,8 @@ # ____________________________________________________________ - at unwrap_spec(name=str) -def new_enum_type(space, name, w_enumerators, w_enumvalues): + at unwrap_spec(name=str, basectype=ctypeobj.W_CType) +def new_enum_type(space, name, w_enumerators, w_enumvalues, basectype): enumerators_w = space.fixedview(w_enumerators) enumvalues_w = space.fixedview(w_enumvalues) if len(enumerators_w) != len(enumvalues_w): @@ -273,53 +273,26 @@ space.wrap("tuple args must have the same size")) enumerators = [space.str_w(w) for w in enumerators_w] # - smallest_value = 0 - largest_value = r_uint(0) - i = 0 + if (not isinstance(basectype, ctypeprim.W_CTypePrimitiveSigned) and + not isinstance(basectype, ctypeprim.W_CTypePrimitiveUnsigned)): + raise OperationError(space.w_TypeError, + space.wrap("expected a primitive signed or unsigned base type")) + # + lvalue = lltype.malloc(rffi.CCHARP.TO, basectype.size, flavor='raw') try: for w in enumvalues_w: - try: - ulvalue = space.uint_w(w) - except OperationError, e: - if not e.match(space, space.w_ValueError): - raise - lvalue = space.int_w(w) - if lvalue < smallest_value: - smallest_value = lvalue - else: - if ulvalue > largest_value: - largest_value = ulvalue - i += 1 # 'i' is here for the exception case, see below - except OperationError, e: - if not e.match(space, space.w_OverflowError): - raise - raise operationerrfmt(space.w_OverflowError, - "enum '%s' declaration for '%s' does not fit " - "a long or unsigned long", - name, enumerators[i]) + # detects out-of-range or badly typed values + basectype.convert_from_object(lvalue, w) + finally: + lltype.free(lvalue, flavor='raw') # - if smallest_value < 0: - if (smallest_value >= intmask(most_neg_value_of(rffi.INT)) and - largest_value <= r_uint(most_pos_value_of(rffi.INT))): - size = rffi.sizeof(rffi.INT) - align = alignment(rffi.INT) - elif largest_value <= r_uint(most_pos_value_of(rffi.LONG)): - size = rffi.sizeof(rffi.LONG) - align = alignment(rffi.LONG) - else: - raise operationerrfmt(space.w_OverflowError, - "enum '%s' values don't all fit into either 'long' " - "or 'unsigned long'", name) + size = basectype.size + align = basectype.align + if isinstance(basectype, ctypeprim.W_CTypePrimitiveSigned): enumvalues = [space.int_w(w) for w in enumvalues_w] ctype = ctypeenum.W_CTypeEnumSigned(space, name, size, align, enumerators, enumvalues) else: - if largest_value <= r_uint(most_pos_value_of(rffi.UINT)): - size = rffi.sizeof(rffi.UINT) - align = alignment(rffi.UINT) - else: - size = rffi.sizeof(rffi.ULONG) - align = alignment(rffi.ULONG) enumvalues = [space.uint_w(w) for w in enumvalues_w] ctype = ctypeenum.W_CTypeEnumUnsigned(space, name, size, align, enumerators, enumvalues) diff --git a/pypy/module/_cffi_backend/test/_backend_test_c.py b/pypy/module/_cffi_backend/test/_backend_test_c.py --- a/pypy/module/_cffi_backend/test/_backend_test_c.py +++ b/pypy/module/_cffi_backend/test/_backend_test_c.py @@ -1264,25 +1264,29 @@ py.test.raises(TypeError, callback, BFunc, cb, -42) def test_enum_type(): - BEnum = new_enum_type("foo", (), ()) + BUInt = new_primitive_type("unsigned int") + BEnum = new_enum_type("foo", (), (), BUInt) assert repr(BEnum) == "" assert BEnum.kind == "enum" assert BEnum.cname == "enum foo" assert BEnum.elements == {} # - BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, -20)) + BInt = new_primitive_type("int") + BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, -20), BInt) assert BEnum.kind == "enum" assert BEnum.elements == {-20: 'ab', 0: 'def', 1: 'c'} # 'elements' is not the real dict, but merely a copy BEnum.elements[2] = '??' assert BEnum.elements == {-20: 'ab', 0: 'def', 1: 'c'} # - BEnum = new_enum_type("bar", ('ab', 'cd'), (5, 5)) + BEnum = new_enum_type("bar", ('ab', 'cd'), (5, 5), BUInt) assert BEnum.elements == {5: 'ab'} assert BEnum.relements == {'ab': 5, 'cd': 5} def test_cast_to_enum(): - BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, -20)) + BInt = new_primitive_type("int") + BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, -20), BInt) + assert sizeof(BEnum) == sizeof(BInt) e = cast(BEnum, 0) assert repr(e) == "" assert repr(cast(BEnum, -42)) == "" @@ -1294,18 +1298,27 @@ assert int(cast(BEnum, -242 + 2**128)) == -242 assert string(cast(BEnum, -242 + 2**128)) == '-242' # - BEnum = new_enum_type("bar", ('def', 'c', 'ab'), (0, 1, 20)) + BUInt = new_primitive_type("unsigned int") + BEnum = new_enum_type("bar", ('def', 'c', 'ab'), (0, 1, 20), BUInt) e = cast(BEnum, -1) assert repr(e) == "" # unsigned int + # + BLong = new_primitive_type("long") + BEnum = new_enum_type("baz", (), (), BLong) + assert sizeof(BEnum) == sizeof(BLong) + e = cast(BEnum, -1) + assert repr(e) == "" def test_enum_with_non_injective_mapping(): - BEnum = new_enum_type("foo", ('ab', 'cd'), (7, 7)) + BInt = new_primitive_type("int") + BEnum = new_enum_type("foo", ('ab', 'cd'), (7, 7), BInt) e = cast(BEnum, 7) assert repr(e) == "" assert string(e) == 'ab' def test_enum_in_struct(): - BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, -20)) + BInt = new_primitive_type("int") + BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, -20), BInt) BStruct = new_struct_type("bar") BStructPtr = new_pointer_type(BStruct) complete_struct_or_union(BStruct, [('a1', BEnum, -1)]) @@ -1318,7 +1331,7 @@ "unsupported operand type for int(): 'NoneType'" in str(e.value)) #PyPy py.test.raises(TypeError, 'p.a1 = "def"') if sys.version_info < (3,): - BEnum2 = new_enum_type(unicode("foo"), (unicode('abc'),), (5,)) + BEnum2 = new_enum_type(unicode("foo"), (unicode('abc'),), (5,), BInt) assert string(cast(BEnum2, 5)) == 'abc' assert type(string(cast(BEnum2, 5))) is str @@ -1327,66 +1340,25 @@ max_int = max_uint // 2 max_ulong = 2 ** (size_of_long()*8) - 1 max_long = max_ulong // 2 - # 'unsigned int' case - e = new_enum_type("foo", ('a', 'b'), (0, 3)) - assert sizeof(e) == size_of_int() - assert int(cast(e, -1)) == max_uint # 'e' is unsigned - e = new_enum_type("foo", ('a', 'b'), (0, max_uint)) - assert sizeof(e) == size_of_int() - assert int(cast(e, -1)) == max_uint - assert e.elements == {0: 'a', max_uint: 'b'} - assert e.relements == {'a': 0, 'b': max_uint} - # 'signed int' case - e = new_enum_type("foo", ('a', 'b'), (-1, max_int)) - assert sizeof(e) == size_of_int() - assert int(cast(e, -1)) == -1 - assert e.elements == {-1: 'a', max_int: 'b'} - assert e.relements == {'a': -1, 'b': max_int} - e = new_enum_type("foo", ('a', 'b'), (-max_int-1, max_int)) - assert sizeof(e) == size_of_int() - assert int(cast(e, -1)) == -1 - assert e.elements == {-max_int-1: 'a', max_int: 'b'} - assert e.relements == {'a': -max_int-1, 'b': max_int} - # 'unsigned long' case - e = new_enum_type("foo", ('a', 'b'), (0, max_long)) - assert sizeof(e) == size_of_long() - assert int(cast(e, -1)) == max_ulong # 'e' is unsigned - e = new_enum_type("foo", ('a', 'b'), (0, max_ulong)) - assert sizeof(e) == size_of_long() - assert int(cast(e, -1)) == max_ulong - assert e.elements == {0: 'a', max_ulong: 'b'} - assert e.relements == {'a': 0, 'b': max_ulong} - # 'signed long' case - e = new_enum_type("foo", ('a', 'b'), (-1, max_long)) - assert sizeof(e) == size_of_long() - assert int(cast(e, -1)) == -1 - assert e.elements == {-1: 'a', max_long: 'b'} - assert e.relements == {'a': -1, 'b': max_long} - e = new_enum_type("foo", ('a', 'b'), (-max_long-1, max_long)) - assert sizeof(e) == size_of_long() - assert int(cast(e, -1)) == -1 - assert e.elements == {-max_long-1: 'a', max_long: 'b'} - assert e.relements == {'a': -max_long-1, 'b': max_long} - # overflow: both negative items and items larger than max_long - e = py.test.raises(OverflowError, new_enum_type, "foo", ('a', 'b'), - (-1, max_long + 1)) - assert str(e.value) == ( - "enum 'foo' values don't all fit into either 'long' " - "or 'unsigned long'") - # overflow: items smaller than -max_long-1 - e = py.test.raises(OverflowError, new_enum_type, "foo", ('a', 'b'), - (-max_long-2, 5)) - assert str(e.value) == ( - "enum 'foo' declaration for 'a' does not fit a long or unsigned long") - # overflow: items larger than max_ulong - e = py.test.raises(OverflowError, new_enum_type, "foo", ('a', 'b'), - (5, max_ulong+1)) - assert str(e.value) == ( - "enum 'foo' declaration for 'b' does not fit a long or unsigned long") + for BPrimitive in [new_primitive_type("int"), + new_primitive_type("unsigned int"), + new_primitive_type("long"), + new_primitive_type("unsigned long")]: + for x in [max_uint, max_int, max_ulong, max_long]: + for testcase in [x, x+1, -x-1, -x-2]: + if int(cast(BPrimitive, testcase)) == testcase: + # fits + BEnum = new_enum_type("foo", ("AA",), (testcase,), + BPrimitive) + assert int(cast(BEnum, testcase)) == testcase + else: + # overflows + py.test.raises(OverflowError, new_enum_type, + "foo", ("AA",), (testcase,), BPrimitive) def test_callback_returning_enum(): BInt = new_primitive_type("int") - BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, -20)) + BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, -20), BInt) def cb(n): if n & 1: return cast(BEnum, n) @@ -1402,7 +1374,8 @@ def test_callback_returning_enum_unsigned(): BInt = new_primitive_type("int") - BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, 20)) + BUInt = new_primitive_type("unsigned int") + BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, 20), BUInt) def cb(n): if n & 1: return cast(BEnum, n) diff --git a/pypy/module/micronumpy/app_numpy.py b/pypy/module/micronumpy/app_numpy.py --- a/pypy/module/micronumpy/app_numpy.py +++ b/pypy/module/micronumpy/app_numpy.py @@ -67,11 +67,15 @@ def min(a, axis=None, out=None): if not hasattr(a, "min"): a = _numpypy.array(a) + if a.size < 1: + return _numpypy.array([]) return a.min(axis=axis, out=out) def max(a, axis=None, out=None): if not hasattr(a, "max"): a = _numpypy.array(a) + if a.size < 1: + return _numpypy.array([]) return a.max(axis=axis, out=out) def arange(start, stop=None, step=1, dtype=None): diff --git a/pypy/module/micronumpy/interp_numarray.py b/pypy/module/micronumpy/interp_numarray.py --- a/pypy/module/micronumpy/interp_numarray.py +++ b/pypy/module/micronumpy/interp_numarray.py @@ -627,7 +627,16 @@ w_remainder = self.descr_mod(space, w_other) return space.newtuple([w_quotient, w_remainder]) - descr_eq = _binop_impl("equal") + _descr_eq = _binop_impl("equal") + + def descr_eq(self, space, w_other): + try: + return self._descr_eq(space, w_other) + except OperationError, e: + if e.match(space, space.w_ValueError): + return space.w_False + raise e + descr_ne = _binop_impl("not_equal") descr_lt = _binop_impl("less") descr_le = _binop_impl("less_equal") diff --git a/pypy/module/micronumpy/test/test_numarray.py b/pypy/module/micronumpy/test/test_numarray.py --- a/pypy/module/micronumpy/test/test_numarray.py +++ b/pypy/module/micronumpy/test/test_numarray.py @@ -1,5 +1,5 @@ - -import py, sys +import py +import sys from pypy.conftest import option from pypy.module.micronumpy.appbridge import get_appbridge_cache @@ -7,6 +7,7 @@ from pypy.module.micronumpy.interp_numarray import W_NDimArray from pypy.module.micronumpy.test.test_base import BaseNumpyAppTest + class MockDtype(object): class itemtype(object): @staticmethod @@ -24,9 +25,11 @@ def create_slice(a, chunks): return Chunks(chunks).apply(W_NDimArray(a)).implementation + def create_array(*args, **kwargs): return W_NDimArray.from_shape(*args, **kwargs).implementation + class TestNumArrayDirect(object): def newslice(self, *args): return self.space.newslice(*[self.space.wrap(arg) for arg in args]) @@ -1202,7 +1205,7 @@ assert d.shape == (3, 3) assert d.dtype == dtype('int32') assert (d == [[1, 0, 0], [0, 1, 0], [0, 0, 1]]).all() - + def test_eye(self): from _numpypy import eye from _numpypy import int32, dtype @@ -1232,9 +1235,6 @@ assert g.shape == (3, 4) assert (g == [[0, 0, 0, 0], [1, 0, 0, 0], [0, 1, 0, 0]]).all() - - - def test_prod(self): from _numpypy import array a = array(range(1, 6)) @@ -1473,6 +1473,11 @@ assert len(a) == 6 assert (a == [0,1,2,3,4,5]).all() assert a.dtype is dtype(int) + a = concatenate((a1, a2), axis=1) + assert (a == [0,1,2,3,4,5]).all() + a = concatenate((a1, a2), axis=-1) + assert (a == [0,1,2,3,4,5]).all() + b1 = array([[1, 2], [3, 4]]) b2 = array([[5, 6]]) b = concatenate((b1, b2), axis=0) @@ -1488,16 +1493,29 @@ f = concatenate((f1, [2], f1, [7])) assert (f == [0,1,2,0,1,7]).all() - bad_axis = raises(IndexError, concatenate, (a1,a2), axis=1) - assert str(bad_axis.value) == "axis 1 out of bounds [0, 1)" + g1 = array([[0,1,2]]) + g2 = array([[3,4,5]]) + g = concatenate((g1, g2), axis=-2) + assert (g == [[0,1,2],[3,4,5]]).all() + exc = raises(IndexError, concatenate, (g1, g2), axis=2) + assert str(exc.value) == "axis 2 out of bounds [0, 2)" + exc = raises(IndexError, concatenate, (g1, g2), axis=-3) + assert str(exc.value) == "axis -3 out of bounds [0, 2)" - concat_zero = raises(ValueError, concatenate, ()) - assert str(concat_zero.value) == \ - "need at least one array to concatenate" + exc = raises(ValueError, concatenate, ()) + assert str(exc.value) == \ + "need at least one array to concatenate" - dims_disagree = raises(ValueError, concatenate, (a1, b1), axis=0) - assert str(dims_disagree.value) == \ - "all the input arrays must have same number of dimensions" + exc = raises(ValueError, concatenate, (a1, b1), axis=0) + assert str(exc.value) == \ + "all the input arrays must have same number of dimensions" + + g1 = array([0,1,2]) + g2 = array([[3,4,5]]) + exc = raises(ValueError, concatenate, (g1, g2), axis=2) + assert str(exc.value) == \ + "all the input arrays must have same number of dimensions" + a = array([1, 2, 3, 4, 5, 6]) a = (a + a)[::2] b = concatenate((a[:3], a[-3:])) @@ -1583,7 +1601,7 @@ [[3, 9], [6, 12]]])).all() assert (x.swapaxes(1, 2) == array([[[1, 4], [2, 5], [3, 6]], [[7, 10], [8, 11],[9, 12]]])).all() - + # test slice assert (x[0:1,0:2].swapaxes(0,2) == array([[[1], [4]], [[2], [5]], [[3], [6]]])).all() @@ -1745,13 +1763,19 @@ assert a[1] == 0xff assert len(a.data) == 16 - def test_explicit_dtype_conversion(self): from _numpypy import array a = array([1.0, 2.0]) b = array(a, dtype='d') assert a.dtype is b.dtype + def test_notequal_different_shapes(self): + from _numpypy import array + a = array([1, 2]) + b = array([1, 2, 3, 4]) + assert (a == b) == False + + class AppTestMultiDim(BaseNumpyAppTest): def test_init(self): import _numpypy @@ -2043,6 +2067,7 @@ False, False, True, False, False, False]).all() assert ((b > range(12)) == [False, True, True,False, True, True, False, False, True, False, False, False]).all() + def test_flatiter_view(self): from _numpypy import arange a = arange(10).reshape(5, 2) @@ -2263,10 +2288,10 @@ a = arange(12).reshape(2, 3, 2) assert (a.diagonal(0, 0, 1) == [[0, 8], [1, 9]]).all() assert a.diagonal(3, 0, 1).shape == (2, 0) - assert (a.diagonal(1, 0, 1) == [[2, 10], [3, 11]]).all() - assert (a.diagonal(0, 2, 1) == [[0, 3], [6, 9]]).all() - assert (a.diagonal(2, 2, 1) == [[4], [10]]).all() - assert (a.diagonal(1, 2, 1) == [[2, 5], [8, 11]]).all() + assert (a.diagonal(1, 0, 1) == [[2, 10], [3, 11]]).all() + assert (a.diagonal(0, 2, 1) == [[0, 3], [6, 9]]).all() + assert (a.diagonal(2, 2, 1) == [[4], [10]]).all() + assert (a.diagonal(1, 2, 1) == [[2, 5], [8, 11]]).all() def test_diagonal_axis_neg_ofs(self): from _numpypy import arange @@ -2274,6 +2299,7 @@ assert (a.diagonal(-1, 0, 1) == [[6], [7]]).all() assert a.diagonal(-2, 0, 1).shape == (2, 0) + class AppTestSupport(BaseNumpyAppTest): def setup_class(cls): import struct @@ -2444,6 +2470,7 @@ assert (a.argsort(axis=0) == [[1, 0, 0], [0, 1, 1]]).all() assert (a.argsort(axis=1) == [[2, 1, 0], [0, 1, 2]]).all() + class AppTestRanges(BaseNumpyAppTest): def test_arange(self): from _numpypy import arange, dtype @@ -2490,6 +2517,7 @@ cache.w_array_repr = cls.old_array_repr cache.w_array_str = cls.old_array_str + class AppTestRecordDtype(BaseNumpyAppTest): def test_zeros(self): from _numpypy import zeros, integer @@ -2660,4 +2688,3 @@ assert x.__pypy_data__ is obj del x.__pypy_data__ assert x.__pypy_data__ is None - diff --git a/pypy/module/micronumpy/types.py b/pypy/module/micronumpy/types.py --- a/pypy/module/micronumpy/types.py +++ b/pypy/module/micronumpy/types.py @@ -1530,8 +1530,8 @@ def byteswap(self, w_v): value = self.unbox(w_v) - result = StringBuilder(12) - pack_float80(result, value, not native_is_bigendian) + result = StringBuilder(10) + pack_float80(result, value, 10, not native_is_bigendian) return self.box(unpack_float80(result.build(), native_is_bigendian)) NonNativeFloat96 = Float96 @@ -1560,8 +1560,8 @@ def byteswap(self, w_v): value = self.unbox(w_v) - result = StringBuilder(16) - pack_float80(result, value, not native_is_bigendian) + result = StringBuilder(10) + pack_float80(result, value, 10, not native_is_bigendian) return self.box(unpack_float80(result.build(), native_is_bigendian)) NonNativeFloat128 = Float128 diff --git a/pypy/module/signal/interp_signal.py b/pypy/module/signal/interp_signal.py --- a/pypy/module/signal/interp_signal.py +++ b/pypy/module/signal/interp_signal.py @@ -32,8 +32,7 @@ p = pypysig_getaddr_occurred() p.c_value = value - @staticmethod - def rearm_ticker(): + def rearm_ticker(self): p = pypysig_getaddr_occurred() p.c_value = -1 @@ -71,7 +70,7 @@ if self.fire_in_another_thread: if self.space.threadlocals.signals_enabled(): self.fire_in_another_thread = False - SignalActionFlag.rearm_ticker() + self.space.actionflag.rearm_ticker() # this occurs when we just switched to the main thread # and there is a signal pending: we force the ticker to # -1, which should ensure perform() is called quickly. diff --git a/pypy/module/test_lib_pypy/numpypy/test_numpy.py b/pypy/module/test_lib_pypy/numpypy/test_numpy.py --- a/pypy/module/test_lib_pypy/numpypy/test_numpy.py +++ b/pypy/module/test_lib_pypy/numpypy/test_numpy.py @@ -14,9 +14,21 @@ import numpy # works after 'numpypy' has been imported def test_min_max_after_import(self): + import __builtin__ + from numpypy import * + assert min is __builtin__.min + assert max is __builtin__.max + assert min(1, 100) == 1 assert min(100, 1) == 1 assert max(1, 100) == 100 assert max(100, 1) == 100 + + assert min(4, 3, 2, 1) == 1 + assert max(1, 2, 3, 4) == 4 + + from numpypy import min, max + assert min is not __builtin__.min + assert max is not __builtin__.max diff --git a/pypy/module/thread/test/test_thread.py b/pypy/module/thread/test/test_thread.py --- a/pypy/module/thread/test/test_thread.py +++ b/pypy/module/thread/test/test_thread.py @@ -220,18 +220,18 @@ import signal def f(): - for x in range(50): + for x in range(5): if waiting: _thread.interrupt_main() return print('tock...', x) # <-force the GIL to be released, as - time.sleep(0.01) # time.sleep doesn't do non-translated + time.sleep(0.1) # time.sleep doesn't do non-translated def busy_wait(): waiting.append(None) - for x in range(100): + for x in range(10): print('tick...', x) # <-force the GIL to be released, as - time.sleep(0.01) # time.sleep doesn't do non-translated + time.sleep(0.1) # time.sleep doesn't do non-translated waiting.pop() # This is normally called by app_main.py diff --git a/pypy/module/thread/threadlocals.py b/pypy/module/thread/threadlocals.py --- a/pypy/module/thread/threadlocals.py +++ b/pypy/module/thread/threadlocals.py @@ -1,4 +1,9 @@ from rpython.rlib import rthread +from pypy.module.thread.error import wrap_thread_error +from pypy.interpreter.executioncontext import ExecutionContext + + +ExecutionContext._signals_enabled = 0 # default value class OSThreadLocals: @@ -9,12 +14,11 @@ def __init__(self): self._valuedict = {} # {thread_ident: ExecutionContext()} - self._signalsenabled = {} # {thread_ident: number-of-times} self._cleanup_() def _cleanup_(self): self._valuedict.clear() - self._signalsenabled.clear() + self._mainthreadident = 0 self._mostrecentkey = 0 # fast minicaching for the common case self._mostrecentvalue = None # fast minicaching for the common case @@ -33,8 +37,9 @@ def setvalue(self, value): ident = rthread.get_ident() if value is not None: - if len(self._valuedict) == 0: - self._signalsenabled[ident] = 1 # the main thread is enabled + if self._mainthreadident == 0: + value._signals_enabled = 1 # the main thread is enabled + self._mainthreadident = ident self._valuedict[ident] = value else: try: @@ -46,23 +51,20 @@ self._mostrecentvalue = value def signals_enabled(self): - return rthread.get_ident() in self._signalsenabled + ec = self.getvalue() + return ec._signals_enabled - def enable_signals(self): - ident = rthread.get_ident() - old = self._signalsenabled.get(ident, 0) - self._signalsenabled[ident] = old + 1 + def enable_signals(self, space): + ec = self.getvalue() + ec._signals_enabled += 1 - def disable_signals(self): - ident = rthread.get_ident() - try: - new = self._signalsenabled[ident] - 1 - except KeyError: - return - if new > 0: - self._signalsenabled[ident] = new - else: - del self._signalsenabled[ident] + def disable_signals(self, space): + ec = self.getvalue() + new = ec._signals_enabled - 1 + if new < 0: + raise wrap_thread_error(space, + "cannot disable signals in thread not enabled for signals") + ec._signals_enabled = new def getallvalues(self): return self._valuedict @@ -77,13 +79,10 @@ def reinit_threads(self, space): "Called in the child process after a fork()" - # clear the _signalsenabled dictionary for all other threads - # (which are now dead); and for the current thread, force an - # enable_signals() if necessary. That's a hack but I cannot - # figure out a non-hackish way to handle thread+signal+fork :-( ident = rthread.get_ident() - old = self._signalsenabled.get(ident, 0) - self._signalsenabled.clear() - if old == 0: - old = 1 - self._signalsenabled[ident] = old + ec = self.getvalue() + if ident != self._mainthreadident: + ec._signals_enabled += 1 + self._cleanup_() + self._mainthreadident = ident + self.setvalue(ec) diff --git a/pypy/objspace/descroperation.py b/pypy/objspace/descroperation.py --- a/pypy/objspace/descroperation.py +++ b/pypy/objspace/descroperation.py @@ -6,6 +6,7 @@ from pypy.interpreter.typedef import default_identity_hash from rpython.tool.sourcetools import compile2, func_with_new_name from rpython.rlib.objectmodel import specialize +from rpython.rlib import jit def object_getattribute(space): "Utility that returns the app-level descriptor object.__getattribute__." @@ -120,6 +121,9 @@ def descr__init__(space, w_obj, __args__): pass +contains_jitdriver = jit.JitDriver(name='contains', + greens=['w_type'], reds='auto') + class DescrOperation(object): _mixin_ = True @@ -410,7 +414,9 @@ def sequence_contains(space, w_container, w_item): w_iter = space.iter(w_container) + w_type = space.type(w_iter) while 1: + contains_jitdriver.jit_merge_point(w_type=w_type) try: w_next = space.next(w_iter) except OperationError, e: diff --git a/rpython/bin/translatorshell.py b/rpython/bin/translatorshell.py --- a/rpython/bin/translatorshell.py +++ b/rpython/bin/translatorshell.py @@ -15,9 +15,10 @@ t.view() # graph + annotations under the mouse t.rtype() # use low level operations - f = t.compile_c() # C compilation + lib = t.compile_c() # C compilation as a library + f = get_c_function(lib, func) # get the function out of the library assert f(arg) == func(arg) # sanity check (for C) - + Some functions are provided for the benefit of interactive testing. Try dir(snippet) for list of current snippets. @@ -31,6 +32,13 @@ import py + +def get_c_function(lib, f): + from ctypes import CDLL + name = f.__name__ + return getattr(CDLL(lib.strpath), 'pypy_g_' + name) + + def setup_readline(): import readline try: diff --git a/rpython/rlib/rstruct/ieee.py b/rpython/rlib/rstruct/ieee.py --- a/rpython/rlib/rstruct/ieee.py +++ b/rpython/rlib/rstruct/ieee.py @@ -25,26 +25,23 @@ return int_part def float_unpack(Q, size): - """Convert a 16-bit, 32-bit 64-bit integer created + """Convert a 16-bit, 32-bit, or 64-bit integer created by float_pack into a Python float.""" if size == 8: MIN_EXP = -1021 # = sys.float_info.min_exp MAX_EXP = 1024 # = sys.float_info.max_exp MANT_DIG = 53 # = sys.float_info.mant_dig BITS = 64 - one = r_ulonglong(1) elif size == 4: MIN_EXP = -125 # C's FLT_MIN_EXP MAX_EXP = 128 # FLT_MAX_EXP MANT_DIG = 24 # FLT_MANT_DIG BITS = 32 - one = r_ulonglong(1) elif size == 2: MIN_EXP = -13 MAX_EXP = 16 MANT_DIG = 11 BITS = 16 - one = r_ulonglong(1) else: raise ValueError("invalid size value") @@ -56,6 +53,7 @@ raise ValueError("input '%r' out of range '%r'" % (Q, Q>>BITS)) # extract pieces with assumed 1.mant values + one = r_ulonglong(1) sign = rarithmetic.intmask(Q >> BITS - 1) exp = rarithmetic.intmask((Q & ((one << BITS - 1) - (one << MANT_DIG - 1))) >> MANT_DIG - 1) mant = Q & ((one << MANT_DIG - 1) - 1) @@ -72,27 +70,32 @@ result = math.ldexp(mant, exp + MIN_EXP - MANT_DIG - 1) return -result if sign else result -def float_unpack80(QQ): +def float_unpack80(QQ, size): '''Unpack a (mant, exp) tuple of r_ulonglong in 80-bit extended format into a long double float ''' - MIN_EXP = -16381 - MAX_EXP = 16384 - MANT_DIG = 64 - TOPBITS = 80 - 64 - one = r_ulonglong(1) + if size == 10 or size == 12 or size == 16: + MIN_EXP = -16381 + MAX_EXP = 16384 + MANT_DIG = 64 + TOP_BITS = 80 - 64 + else: + raise ValueError("invalid size value") + if len(QQ) != 2: raise ValueError("QQ must be two 64 bit uints") + if not objectmodel.we_are_translated(): # This tests generates wrong code when translated: # with gcc, shifting a 64bit int by 64 bits does # not change the value. - if QQ[1] >> TOPBITS: - raise ValueError("input '%r' out of range '%r'" % (QQ, QQ[1]>>TOPBITS)) + if QQ[1] >> TOP_BITS: + raise ValueError("input '%r' out of range '%r'" % (QQ, QQ[1]>>TOP_BITS)) # extract pieces with explicit one in MANT_DIG - sign = rarithmetic.intmask(QQ[1] >> TOPBITS - 1) - exp = rarithmetic.intmask((QQ[1] & ((one << TOPBITS - 1) - 1))) + one = r_ulonglong(1) + sign = rarithmetic.intmask(QQ[1] >> TOP_BITS - 1) + exp = rarithmetic.intmask((QQ[1] & ((one << TOP_BITS - 1) - 1))) mant = QQ[0] if exp == MAX_EXP - MIN_EXP + 2: @@ -171,14 +174,18 @@ sign = r_ulonglong(sign) return ((sign << BITS - 1) | (exp << MANT_DIG - 1)) | mant -def float_pack80(x): +def float_pack80(x, size): """Convert a Python float or longfloat x into two 64-bit unsigned integers with 80 bit extended representation.""" - MIN_EXP = -16381 - MAX_EXP = 16384 - MANT_DIG = 64 - BITS = 80 x = float(x) # longfloat not really supported + if size == 10 or size == 12 or size == 16: + MIN_EXP = -16381 + MAX_EXP = 16384 + MANT_DIG = 64 + BITS = 80 + else: + raise ValueError("invalid size value") + sign = rfloat.copysign(1.0, x) < 0.0 if not rfloat.isfinite(x): if rfloat.isinf(x): @@ -235,32 +242,34 @@ result.append("".join(l)) @jit.unroll_safe -def pack_float80(result, x, be): +def pack_float80(result, x, size, be): l = [] - unsigned = float_pack80(x) + unsigned = float_pack80(x, size) for i in range(8): l.append(chr((unsigned[0] >> (i * 8)) & 0xFF)) for i in range(2): l.append(chr((unsigned[1] >> (i * 8)) & 0xFF)) + for i in range(size - 10): + l.append('\x00') if be: l.reverse() result.append("".join(l)) + at jit.unroll_safe def unpack_float(s, be): unsigned = r_ulonglong(0) - for i in range(len(s)): - c = ord(s[len(s) - 1 - i if be else i]) + for i in range(min(len(s), 8)): + c = ord(s[-i - 1 if be else i]) unsigned |= r_ulonglong(c) << (i * 8) return float_unpack(unsigned, len(s)) + at jit.unroll_safe def unpack_float80(s, be): - if len(s) != 10: - raise ValueError QQ = [r_ulonglong(0), r_ulonglong(0)] for i in range(8): - c = ord(s[9 - i if be else i]) + c = ord(s[-i - 1 if be else i]) QQ[0] |= r_ulonglong(c) << (i * 8) for i in range(8, 10): - c = ord(s[9 - i if be else i]) + c = ord(s[-i - 1 if be else i]) QQ[1] |= r_ulonglong(c) << ((i - 8) * 8) - return float_unpack80(QQ) + return float_unpack80(QQ, len(s)) diff --git a/rpython/rlib/rstruct/test/test_ieee.py b/rpython/rlib/rstruct/test/test_ieee.py --- a/rpython/rlib/rstruct/test/test_ieee.py +++ b/rpython/rlib/rstruct/test/test_ieee.py @@ -8,6 +8,55 @@ from rpython.translator.c.test.test_genc import compile +class TestFloatSpecific: + def test_halffloat_exact(self): + #testcases generated from numpy.float16(x).view('uint16') + cases = [[0, 0], [10, 18688], [-10, 51456], [10e3, 28898], + [float('inf'), 31744], [-float('inf'), 64512]] + for c, h in cases: + hbit = ieee.float_pack(c, 2) + assert hbit == h + assert c == ieee.float_unpack(h, 2) + + def test_halffloat_inexact(self): + #testcases generated from numpy.float16(x).view('uint16') + cases = [[10.001, 18688, 10.], [-10.001, 51456, -10], + [0.027588, 10000, 0.027587890625], + [22001, 30047, 22000]] + for c, h, f in cases: + hbit = ieee.float_pack(c, 2) + assert hbit == h + assert f == ieee.float_unpack(h, 2) + + def test_halffloat_overunderflow(self): + import math + cases = [[670000, float('inf')], [-67000, -float('inf')], + [1e-08, 0], [-1e-8, -0.]] + for f1, f2 in cases: + try: + f_out = ieee.float_unpack(ieee.float_pack(f1, 2), 2) + except OverflowError: + f_out = math.copysign(float('inf'), f1) + assert f_out == f2 + assert math.copysign(1., f_out) == math.copysign(1., f2) + + def test_float80_exact(self): + s = [] + ieee.pack_float80(s, -1., 16, False) + assert repr(s[-1]) == repr('\x00\x00\x00\x00\x00\x00\x00\x80\xff\xbf\x00\x00\x00\x00\x00\x00') + ieee.pack_float80(s, -1., 16, True) + assert repr(s[-1]) == repr('\x00\x00\x00\x00\x00\x00\xbf\xff\x80\x00\x00\x00\x00\x00\x00\x00') + ieee.pack_float80(s, -123.456, 16, False) + assert repr(s[-1]) == repr('\x00\xb8\xf3\xfd\xd4x\xe9\xf6\x05\xc0\x00\x00\x00\x00\x00\x00') + ieee.pack_float80(s, -123.456, 16, True) + assert repr(s[-1]) == repr('\x00\x00\x00\x00\x00\x00\xc0\x05\xf6\xe9x\xd4\xfd\xf3\xb8\x00') + + x = ieee.unpack_float80('\x00\x00\x00\x00\x00\x00\x00\x80\xff?\xc8\x01\x00\x00\x00\x00', False) + assert x == 1.0 + x = ieee.unpack_float80('\x00\x00\x7f\x83\xe1\x91?\xff\x80\x00\x00\x00\x00\x00\x00\x00', True) + assert x == 1.0 + + class TestFloatPacking: def setup_class(cls): if sys.version_info < (2, 6): @@ -15,25 +64,20 @@ def check_float(self, x): # check roundtrip - Q = ieee.float_pack(x, 8) - y = ieee.float_unpack(Q, 8) - assert repr(x) == repr(y), '%r != %r, Q=%r' % (x, y, Q) + for size in [10, 12, 16]: + for be in [False, True]: + Q = [] + ieee.pack_float80(Q, x, size, be) + Q = Q[0] + y = ieee.unpack_float80(Q, be) + assert repr(x) == repr(y), '%r != %r, Q=%r' % (x, y, Q) - Q = ieee.float_pack80(x) - y = ieee.float_unpack80(Q) - assert repr(x) == repr(y), '%r != %r, Q=%r' % (x, y, Q) - - Q = [] - ieee.pack_float(Q, x, 8, False) - Q = Q[0] - y = ieee.unpack_float(Q, False) - assert repr(x) == repr(y), '%r != %r, Q=%r' % (x, y, Q) - - Q = [] - ieee.pack_float80(Q, x, False) - Q = Q[0] - y = ieee.unpack_float80(Q, False) - assert repr(x) == repr(y), '%r != %r, Q=%r' % (x, y, Q) + for be in [False, True]: + Q = [] + ieee.pack_float(Q, x, 8, be) + Q = Q[0] + y = ieee.unpack_float(Q, be) + assert repr(x) == repr(y), '%r != %r, Q=%r' % (x, y, Q) # check that packing agrees with the struct module struct_pack8 = struct.unpack('= 0: # timer is active - name = _create_name(timer, level) - self.timings[name] = time.time() - self.timings[name] - self.levels[timer] = level - 1 - - def stop_name(self, timerone, timertwo): - self.stop(timerone + " " + timertwo) - - def value(self, timer): - level = self.levels.get(timer, -1) - if level == -1: - result = "%fs" % self.timings[timer] - else: - result = "%fs (still running)" % (time.time() - self.timings[timer]) - return result - - def dump(self): - outlist = [] - for timer in self.timingorder: - value = self.value(timer) - outlist.append("%s = %s" % (timer, value)) - os.write(2, "\n".join(outlist)) - - -class DummyTimer: - def start(self, timer): - pass - def start_name(self, timerone, timertwo): - pass - def stop(self, timer): - pass - def stop_name(self, timerone, timertwo): - pass - def value(self, timer): - return "Timing disabled" - def dump(self): - pass - diff --git a/rpython/rtyper/annlowlevel.py b/rpython/rtyper/annlowlevel.py --- a/rpython/rtyper/annlowlevel.py +++ b/rpython/rtyper/annlowlevel.py @@ -2,18 +2,18 @@ The code needed to flow and annotate low-level helpers -- the ll_*() functions """ -import types -from rpython.tool.sourcetools import valid_identifier from rpython.annotator import model as annmodel from rpython.annotator.policy import AnnotatorPolicy, Sig from rpython.annotator.specialize import flatten_star_args +from rpython.flowspace.model import Constant +from rpython.rlib.objectmodel import specialize +from rpython.rtyper import extregistry from rpython.rtyper.lltypesystem import lltype from rpython.rtyper.ootypesystem import ootype -from rpython.rtyper import extregistry -from rpython.flowspace.model import Constant +from rpython.rtyper.rmodel import warning +from rpython.tool.sourcetools import valid_identifier from rpython.translator.simplify import get_functype -from rpython.rtyper.rmodel import warning -from rpython.rlib.objectmodel import specialize + class KeyComp(object): def __init__(self, val): @@ -34,7 +34,7 @@ if compact is None: s = repr(val) else: - s = compact() + s = compact() return s + 'Const' __repr__ = __str__ @@ -90,7 +90,7 @@ args_s[:] = [l2a(a2l(s)) for s in args_s] return LowLevelAnnotatorPolicy.default_specialize(funcdesc, args_s) specialize__semierased = staticmethod(specialize__semierased) - + specialize__ll = default_specialize def specialize__ll_and_arg(funcdesc, args_s, *argindices): @@ -103,7 +103,7 @@ def annotate_lowlevel_helper(annotator, ll_function, args_s, policy=None): if policy is None: - policy= LowLevelAnnotatorPolicy() + policy = LowLevelAnnotatorPolicy() return annotator.annotate_helper(ll_function, args_s, policy) # ___________________________________________________________________ @@ -380,7 +380,7 @@ else: FUNC = F.TO resultcls = annmodel.SomePtr - + args_s = [annmodel.lltype_to_annotation(T) for T in FUNC.ARGS] key = (llhelper, s_callable.const) s_res = self.bookkeeper.emulate_pbc_call(key, s_callable, args_s) @@ -603,7 +603,7 @@ assert s.islower() def expand(s_self, *args_s): assert isinstance(s_self, annmodel.SomePtr) - return getattr(s_self.ll_ptrtype.TO, s.upper()) + return getattr(s_self.ll_ptrtype.TO, s.upper()) return expand def typemeth_placeholder_sigarg(s): @@ -622,10 +622,10 @@ def expand(s_TYPE, *args_s): assert isinstance(s_TYPE, annmodel.SomePBC) assert s_TYPE.is_constant() - return getattr(s_TYPE.const, s.upper()) + return getattr(s_TYPE.const, s.upper()) return expand - + class ADTInterface(object): def __init__(self, base, sigtemplates): diff --git a/rpython/rtyper/exceptiondata.py b/rpython/rtyper/exceptiondata.py --- a/rpython/rtyper/exceptiondata.py +++ b/rpython/rtyper/exceptiondata.py @@ -1,6 +1,6 @@ -from rpython.rtyper import rclass from rpython.annotator import model as annmodel from rpython.rlib import rstackovf +from rpython.rtyper import rclass # the exceptions that can be implicitely raised by some operations @@ -38,16 +38,16 @@ r_instance = rclass.getinstancerepr(rtyper, None) r_type.setup() r_instance.setup() - self.r_exception_type = r_type + self.r_exception_type = r_type self.r_exception_value = r_instance - self.lltype_of_exception_type = r_type.lowleveltype + self.lltype_of_exception_type = r_type.lowleveltype self.lltype_of_exception_value = r_instance.lowleveltype self.rtyper = rtyper def make_standard_exceptions(self, rtyper): bk = rtyper.annotator.bookkeeper for cls in self.standardexceptions: - classdef = bk.getuniqueclassdef(cls) + bk.getuniqueclassdef(cls) def finish(self, rtyper): bk = rtyper.annotator.bookkeeper diff --git a/rpython/rtyper/llinterp.py b/rpython/rtyper/llinterp.py --- a/rpython/rtyper/llinterp.py +++ b/rpython/rtyper/llinterp.py @@ -1,17 +1,21 @@ -from rpython.flowspace.model import FunctionGraph, Constant, Variable, c_last_exception -from rpython.rlib.rarithmetic import intmask, r_uint, ovfcheck, r_longlong, r_longlonglong -from rpython.rlib.rarithmetic import r_ulonglong, is_valid_int -from rpython.rtyper.lltypesystem import lltype, llmemory, lloperation, llheap -from rpython.rtyper.lltypesystem import rclass +import cStringIO +import os +import sys +import traceback + +import py + +from rpython.flowspace.model import (FunctionGraph, Constant, Variable, + c_last_exception) +from rpython.rlib import rstackovf +from rpython.rlib.objectmodel import (ComputedIntSymbolic, CDefinedIntSymbolic, + Symbolic) +# intmask is used in an exec'd code block +from rpython.rlib.rarithmetic import (ovfcheck, is_valid_int, intmask, + r_uint, r_longlong, r_ulonglong, r_longlonglong) +from rpython.rtyper.lltypesystem import lltype, llmemory, lloperation, llheap, rclass from rpython.rtyper.ootypesystem import ootype -from rpython.rlib.objectmodel import ComputedIntSymbolic, CDefinedIntSymbolic -from rpython.rlib.objectmodel import Symbolic -from rpython.rlib import rstackovf -import sys, os -import math -import py -import traceback, cStringIO log = py.log.Producer('llinterp') @@ -19,6 +23,7 @@ def __init__(self, *args): "NOT_RPYTHON" Exception.__init__(self, *args) + def __str__(self): etype = self.args[0] #evalue = self.args[1] @@ -42,7 +47,7 @@ return ''.join(etype.name).rstrip('\x00') else: # ootype! - return etype._INSTANCE._name.split(".")[-1] + return etype._INSTANCE._name.split(".")[-1] class LLInterpreter(object): """ low level interpreter working with concrete values. """ @@ -336,7 +341,7 @@ evalue = exc_data.exc_value if tracer: tracer.dump('raise') - exc_data.exc_type = lltype.typeOf(etype )._defl() + exc_data.exc_type = lltype.typeOf(etype)._defl() exc_data.exc_value = lltype.typeOf(evalue)._defl() from rpython.translator import exceptiontransform T = resultvar.concretetype @@ -641,7 +646,6 @@ if ITEMTYPE is not lltype.Void: array[index] = item - def perform_call(self, f, ARGS, args): fobj = self.llinterpreter.typer.type_system.deref(f) has_callable = getattr(fobj, '_callable', None) is not None @@ -652,11 +656,11 @@ return self.invoke_callable_with_pyexceptions(f, *args) args_v = graph.getargs() if len(ARGS) != len(args_v): - raise TypeError("graph with %d args called with wrong func ptr type: %r" %(len(args_v), ARGS)) + raise TypeError("graph with %d args called with wrong func ptr type: %r" %(len(args_v), ARGS)) for T, v in zip(ARGS, args_v): if not lltype.isCompatibleType(T, v.concretetype): raise TypeError("graph with %r args called with wrong func ptr type: %r" % - (tuple([v.concretetype for v in args_v]), ARGS)) + (tuple([v.concretetype for v in args_v]), ARGS)) frame = self.newsubframe(graph, args) return frame.eval() @@ -670,7 +674,7 @@ if graphs is not None: obj = self.llinterpreter.typer.type_system.deref(f) if hasattr(obj, 'graph'): - assert obj.graph in graphs + assert obj.graph in graphs else: pass #log.warn("op_indirect_call with graphs=None:", f) @@ -1052,7 +1056,7 @@ if x^y < 0 and x%%y != 0: r += 1 return r - '''%locals() + ''' % locals() elif operator == '%': ## overflow check on % does not work with emulated int code = '''%(checkfn)s(x // y) @@ -1060,9 +1064,9 @@ if x^y < 0 and x%%y != 0: r -= y return r - '''%locals() + ''' % locals() else: - code = 'return %(checkfn)s(x %(operator)s y)'%locals() + code = 'return %(checkfn)s(x %(operator)s y)' % locals() exec py.code.Source(""" def %(fn)s(self, x, y): assert isinstance(x, %(xtype)s) @@ -1094,7 +1098,7 @@ _makefunc2('op_lllong_floordiv_zer', '//', 'r_longlonglong') _makefunc2('op_lllong_mod_zer', '%', 'r_longlonglong') - + def op_int_add_nonneg_ovf(self, x, y): if isinstance(y, int): assert y >= 0 @@ -1114,9 +1118,9 @@ def op_check_and_clear_exc(self): exc_data = self.llinterpreter.get_transformed_exc_data(self.graph) assert exc_data - etype = exc_data.exc_type + etype = exc_data.exc_type evalue = exc_data.exc_value - exc_data.exc_type = lltype.typeOf(etype )._defl() + exc_data.exc_type = lltype.typeOf(etype)._defl() exc_data.exc_value = lltype.typeOf(evalue)._defl() return bool(etype) @@ -1125,7 +1129,7 @@ def op_new(self, INST): assert isinstance(INST, (ootype.Instance, ootype.BuiltinType)) return ootype.new(INST) - + def op_oonewarray(self, ARRAY, length): assert isinstance(ARRAY, ootype.Array) assert is_valid_int(length) @@ -1139,7 +1143,7 @@ eq_name, interp_eq = \ wrap_callable(self.llinterpreter, eq_func, eq_obj, eq_method_name) EQ_FUNC = ootype.StaticMethod([DICT._KEYTYPE, DICT._KEYTYPE], ootype.Bool) - sm_eq = ootype.static_meth(EQ_FUNC, eq_name, _callable=interp_eq) + sm_eq = ootype.static_meth(EQ_FUNC, eq_name, _callable=interp_eq) hash_name, interp_hash = \ wrap_callable(self.llinterpreter, hash_func, hash_obj, hash_method_name) diff --git a/rpython/rtyper/raddress.py b/rpython/rtyper/raddress.py --- a/rpython/rtyper/raddress.py +++ b/rpython/rtyper/raddress.py @@ -1,18 +1,18 @@ # rtyping of memory address operations -from rpython.tool.pairtype import pairtype from rpython.annotator import model as annmodel -from rpython.rtyper.lltypesystem.llmemory import NULL, Address, \ - cast_adr_to_int, fakeaddress, sizeof +from rpython.rlib.rarithmetic import r_uint +from rpython.rtyper.lltypesystem import lltype +from rpython.rtyper.lltypesystem.llmemory import (NULL, Address, + cast_adr_to_int, fakeaddress, sizeof) from rpython.rtyper.rmodel import Repr, IntegerRepr from rpython.rtyper.rptr import PtrRepr -from rpython.rtyper.lltypesystem import lltype -from rpython.rlib.rarithmetic import r_uint +from rpython.tool.pairtype import pairtype class __extend__(annmodel.SomeAddress): def rtyper_makerepr(self, rtyper): return address_repr - + def rtyper_makekey(self): return self.__class__, @@ -141,5 +141,3 @@ def convert_from_to((r_ptr, r_addr), v, llops): return llops.genop('cast_ptr_to_adr', [v], resulttype=Address) - - diff --git a/rpython/rtyper/rbool.py b/rpython/rtyper/rbool.py --- a/rpython/rtyper/rbool.py +++ b/rpython/rtyper/rbool.py @@ -1,14 +1,14 @@ +from rpython.annotator import model as annmodel +from rpython.rtyper.error import TyperError +from rpython.rtyper.lltypesystem.lltype import Signed, Unsigned, Bool, Float +from rpython.rtyper.rmodel import IntegerRepr, BoolRepr, log from rpython.tool.pairtype import pairtype -from rpython.annotator import model as annmodel -from rpython.rtyper.lltypesystem.lltype import Signed, Unsigned, Bool, Float -from rpython.rtyper.error import TyperError -from rpython.rtyper.rmodel import IntegerRepr, BoolRepr -from rpython.rtyper.rmodel import log class __extend__(annmodel.SomeBool): def rtyper_makerepr(self, rtyper): return bool_repr + def rtyper_makekey(self): return self.__class__, diff --git a/rpython/rtyper/rbuilder.py b/rpython/rtyper/rbuilder.py --- a/rpython/rtyper/rbuilder.py +++ b/rpython/rtyper/rbuilder.py @@ -1,7 +1,7 @@ +from rpython.annotator.model import SomeChar, SomeUnicodeCodePoint +from rpython.rlib.rstring import INIT_SIZE +from rpython.rtyper.lltypesystem import lltype from rpython.rtyper.rmodel import Repr -from rpython.rtyper.lltypesystem import lltype -from rpython.rlib.rstring import INIT_SIZE -from rpython.annotator.model import SomeChar, SomeUnicodeCodePoint class AbstractStringBuilderRepr(Repr): diff --git a/rpython/rtyper/rbytearray.py b/rpython/rtyper/rbytearray.py --- a/rpython/rtyper/rbytearray.py +++ b/rpython/rtyper/rbytearray.py @@ -1,9 +1,9 @@ +from rpython.annotator import model as annmodel +from rpython.rtyper.lltypesystem import lltype +from rpython.rtyper.rmodel import IntegerRepr +from rpython.rtyper.rstr import AbstractStringRepr +from rpython.tool.pairtype import pairtype -from rpython.annotator import model as annmodel -from rpython.tool.pairtype import pairtype -from rpython.rtyper.rstr import AbstractStringRepr -from rpython.rtyper.rmodel import IntegerRepr -from rpython.rtyper.lltypesystem import lltype class AbstractByteArrayRepr(AbstractStringRepr): pass diff --git a/rpython/rtyper/rclass.py b/rpython/rtyper/rclass.py --- a/rpython/rtyper/rclass.py +++ b/rpython/rtyper/rclass.py @@ -1,10 +1,9 @@ import types -from rpython.annotator import model as annmodel -#from rpython.annotator.classdef import isclassdef -from rpython.annotator import description + +from rpython.annotator import description, model as annmodel from rpython.rtyper.error import TyperError +from rpython.rtyper.lltypesystem.lltype import Void from rpython.rtyper.rmodel import Repr, getgcflavor, inputconst -from rpython.rtyper.lltypesystem.lltype import Void class FieldListAccessor(object): @@ -76,7 +75,7 @@ def buildinstancerepr(rtyper, classdef, gcflavor='gc'): from rpython.rlib.objectmodel import UnboxedValue from rpython.flowspace.model import Constant - + if classdef is None: unboxed = [] virtualizable2 = False @@ -137,7 +136,7 @@ if self.classdef.commonbase(subclassdef) != self.classdef: raise TyperError("not a subclass of %r: %r" % ( self.classdef.name, desc)) - + r_subclass = getclassrepr(self.rtyper, subclassdef) return r_subclass.getruntime(self.lowleveltype) @@ -170,12 +169,14 @@ class __extend__(annmodel.SomeInstance): def rtyper_makerepr(self, rtyper): return getinstancerepr(rtyper, self.classdef) + def rtyper_makekey(self): return self.__class__, self.classdef class __extend__(annmodel.SomeType): def rtyper_makerepr(self, rtyper): return get_type_repr(rtyper) + def rtyper_makekey(self): return self.__class__, @@ -390,8 +391,8 @@ s_unbound_attr = clsdef.find_attribute(meth_name).getvalue() s_attr = clsdef.lookup_filter(s_unbound_attr, meth_name, hop.args_s[0].flags) - if s_attr.is_constant(): - xxx # does that even happen? + # does that even happen? + assert not s_attr.is_constant() if '__iter__' in self.allinstancefields: raise Exception("__iter__ on instance disallowed") r_method = self.rtyper.makerepr(s_attr) diff --git a/rpython/rtyper/rcontrollerentry.py b/rpython/rtyper/rcontrollerentry.py --- a/rpython/rtyper/rcontrollerentry.py +++ b/rpython/rtyper/rcontrollerentry.py @@ -1,7 +1,7 @@ +from rpython.flowspace.model import Constant +from rpython.rtyper.error import TyperError +from rpython.rtyper.rmodel import Repr from rpython.tool.pairtype import pairtype -from rpython.flowspace.model import Constant -from rpython.rtyper.rmodel import Repr -from rpython.rtyper.error import TyperError class ControlledInstanceRepr(Repr): diff --git a/rpython/rtyper/rdict.py b/rpython/rtyper/rdict.py --- a/rpython/rtyper/rdict.py +++ b/rpython/rtyper/rdict.py @@ -1,6 +1,6 @@ from rpython.annotator import model as annmodel +from rpython.rtyper import rmodel from rpython.rtyper.lltypesystem import lltype -from rpython.rtyper import rmodel class __extend__(annmodel.SomeDict): @@ -83,4 +83,3 @@ From noreply at buildbot.pypy.org Tue Feb 19 22:17:21 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Tue, 19 Feb 2013 22:17:21 +0100 (CET) Subject: [pypy-commit] pypy py3k: 2to3 Message-ID: <20130219211721.9CD3C1C054C@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61468:5c54a69052f7 Date: 2013-02-19 13:16 -0800 http://bitbucket.org/pypy/pypy/changeset/5c54a69052f7/ Log: 2to3 diff --git a/pypy/module/__pypy__/test/test_signal.py b/pypy/module/__pypy__/test/test_signal.py --- a/pypy/module/__pypy__/test/test_signal.py +++ b/pypy/module/__pypy__/test/test_signal.py @@ -17,10 +17,10 @@ spaceconfig = dict(usemodules=['__pypy__', 'thread', 'signal', 'time']) def test_exit_twice(self): - import __pypy__, thread + import __pypy__, _thread __pypy__.thread._signals_exit() try: - raises(thread.error, __pypy__.thread._signals_exit) + raises(_thread.error, __pypy__.thread._signals_exit) finally: __pypy__.thread._signals_enter() @@ -60,7 +60,7 @@ def test_thread_fork_signals(self): import __pypy__ - import os, thread, signal + import os, _thread, signal if not hasattr(os, 'fork'): skip("No fork on this platform") @@ -72,7 +72,7 @@ def threadfunction(): pid = fork() if pid == 0: - print 'in child' + print('in child') # signal() only works from the 'main' thread signal.signal(signal.SIGUSR1, signal.SIG_IGN) os._exit(42) @@ -82,7 +82,7 @@ feedback.append(exitcode) feedback = [] - thread.start_new_thread(threadfunction, ()) + _thread.start_new_thread(threadfunction, ()) self.waitfor(lambda: feedback) # if 0, an (unraisable) exception was raised from the forked thread. # if 9, process was killed by timer. From noreply at buildbot.pypy.org Tue Feb 19 22:18:05 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Tue, 19 Feb 2013 22:18:05 +0100 (CET) Subject: [pypy-commit] pypy default: have space.warn take wrapped messages (eases py3k branch's usage) and accept a Message-ID: <20130219211805.1C93E1C054C@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: Changeset: r61469:081d9478f7b9 Date: 2013-02-19 13:17 -0800 http://bitbucket.org/pypy/pypy/changeset/081d9478f7b9/ Log: have space.warn take wrapped messages (eases py3k branch's usage) and accept a stacklevel, cleanup diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -1494,10 +1494,11 @@ ) return fd - def warn(self, msg, w_warningcls): - self.appexec([self.wrap(msg), w_warningcls], """(msg, warningcls): + def warn(self, w_msg, w_warningcls, stacklevel=2): + self.appexec([w_msg, w_warningcls, self.wrap(stacklevel)], + """(msg, warningcls, stacklevel): import _warnings - _warnings.warn(msg, warningcls, stacklevel=2) + _warnings.warn(msg, warningcls, stacklevel=stacklevel) """) diff --git a/pypy/interpreter/pyopcode.py b/pypy/interpreter/pyopcode.py --- a/pypy/interpreter/pyopcode.py +++ b/pypy/interpreter/pyopcode.py @@ -776,17 +776,16 @@ @jit.unroll_safe def cmp_exc_match(self, w_1, w_2): - if self.space.is_true(self.space.isinstance(w_2, self.space.w_tuple)): - for w_t in self.space.fixedview(w_2): - if self.space.is_true(self.space.isinstance(w_t, - self.space.w_str)): - self.space.warn("catching of string exceptions is " - "deprecated", - self.space.w_DeprecationWarning) - elif self.space.is_true(self.space.isinstance(w_2, self.space.w_str)): - self.space.warn("catching of string exceptions is deprecated", - self.space.w_DeprecationWarning) - return self.space.newbool(self.space.exception_match(w_1, w_2)) + space = self.space + if space.is_true(space.isinstance(w_2, space.w_tuple)): + for w_t in space.fixedview(w_2): + if space.is_true(space.isinstance(w_t, space.w_str)): + msg = "catching of string exceptions is deprecated" + space.warn(space.wrap(msg), space.w_DeprecationWarning) + elif space.is_true(space.isinstance(w_2, space.w_str)): + msg = "catching of string exceptions is deprecated" + space.warn(space.wrap(msg), space.w_DeprecationWarning) + return space.newbool(space.exception_match(w_1, w_2)) def COMPARE_OP(self, testnum, next_instr): w_2 = self.popvalue() diff --git a/pypy/module/__builtin__/interp_classobj.py b/pypy/module/__builtin__/interp_classobj.py --- a/pypy/module/__builtin__/interp_classobj.py +++ b/pypy/module/__builtin__/interp_classobj.py @@ -154,9 +154,9 @@ return elif name == "__del__": if self.lookup(space, name) is None: - msg = ("a __del__ method added to an existing class " - "will not be called") - space.warn(msg, space.w_RuntimeWarning) + msg = ("a __del__ method added to an existing class will " + "not be called") + space.warn(space.wrap(msg), space.w_RuntimeWarning) space.setitem(self.w_dict, w_attr, w_value) def descr_delattr(self, space, w_attr): @@ -395,9 +395,9 @@ cache = space.fromcache(Cache) if (not isinstance(self, cache.cls_with_del) and self.getdictvalue(space, '__del__') is None): - msg = ("a __del__ method added to an instance " - "with no __del__ in the class will not be called") - space.warn(msg, space.w_RuntimeWarning) + msg = ("a __del__ method added to an instance with no " + "__del__ in the class will not be called") + space.warn(space.wrap(msg), space.w_RuntimeWarning) if w_meth is not None: space.call_function(w_meth, w_name, w_value) else: @@ -454,11 +454,9 @@ else: w_as_str = self.descr_str(space) if space.len_w(w_format_spec) > 0: - space.warn( - ("object.__format__ with a non-empty format string is " - "deprecated"), - space.w_PendingDeprecationWarning - ) + msg = ("object.__format__ with a non-empty format string is " + "deprecated") + space.warn(space.wrap(msg), space.w_PendingDeprecationWarning) return space.format(w_as_str, w_format_spec) def descr_len(self, space): diff --git a/pypy/module/_io/interp_bufferedio.py b/pypy/module/_io/interp_bufferedio.py --- a/pypy/module/_io/interp_bufferedio.py +++ b/pypy/module/_io/interp_bufferedio.py @@ -76,7 +76,7 @@ raise NotImplementedError def _deprecated_max_buffer_size(self, space): - space.warn("max_buffer_size is deprecated", + space.warn(space.wrap("max_buffer_size is deprecated"), space.w_DeprecationWarning) def read_w(self, space, w_size=None): diff --git a/pypy/module/cpyext/import_.py b/pypy/module/cpyext/import_.py --- a/pypy/module/cpyext/import_.py +++ b/pypy/module/cpyext/import_.py @@ -46,8 +46,9 @@ @cpython_api([CONST_STRING], PyObject) def PyImport_ImportModuleNoBlock(space, name): - space.warn('PyImport_ImportModuleNoBlock() is not non-blocking', - space.w_RuntimeWarning) + space.warn( + space.wrap('PyImport_ImportModuleNoBlock() is not non-blocking'), + space.w_RuntimeWarning) return PyImport_Import(space, space.wrap(rffi.charp2str(name))) @cpython_api([PyObject], PyObject) diff --git a/pypy/module/exceptions/interp_exceptions.py b/pypy/module/exceptions/interp_exceptions.py --- a/pypy/module/exceptions/interp_exceptions.py +++ b/pypy/module/exceptions/interp_exceptions.py @@ -176,8 +176,8 @@ if self.w_message is None: raise OperationError(space.w_AttributeError, space.wrap("message was deleted")) - space.warn("BaseException.message has been deprecated as of Python 2.6", - space.w_DeprecationWarning) + msg = "BaseException.message has been deprecated as of Python 2.6" + space.warn(space.wrap(msg), space.w_DeprecationWarning) return self.w_message def descr_message_set(self, space, w_new): diff --git a/pypy/module/imp/importing.py b/pypy/module/imp/importing.py --- a/pypy/module/imp/importing.py +++ b/pypy/module/imp/importing.py @@ -174,9 +174,9 @@ "Parent module '%s' not loaded, " "cannot perform relative import" % ctxt_package)) else: - space.warn("Parent module '%s' not found " - "while handling absolute import" % ctxt_package, - space.w_RuntimeWarning) + msg = ("Parent module '%s' not found while handling absolute " + "import" % ctxt_package) + space.warn(space.wrap(msg), space.w_RuntimeWarning) rel_modulename = ctxt_package[:dot_position] rel_level = rel_modulename.count('.') + 1 @@ -533,9 +533,9 @@ if modtype in (PY_SOURCE, PY_COMPILED): return FindInfo(PKG_DIRECTORY, filepart, None) else: - msg = "Not importing directory " +\ - "'%s' missing __init__.py" % (filepart,) - space.warn(msg, space.w_ImportWarning) + msg = ("Not importing directory '%s' missing __init__.py" % + (filepart,)) + space.warn(space.wrap(msg), space.w_ImportWarning) modtype, suffix, filemode = find_modtype(space, filepart) try: if modtype in (PY_SOURCE, PY_COMPILED, C_EXTENSION): diff --git a/pypy/module/struct/formatiterator.py b/pypy/module/struct/formatiterator.py --- a/pypy/module/struct/formatiterator.py +++ b/pypy/module/struct/formatiterator.py @@ -84,11 +84,10 @@ def _maybe_float(self, w_obj): space = self.space if space.is_true(space.isinstance(w_obj, space.w_float)): - space.warn("struct: integer argument expected, got float", - space.w_DeprecationWarning) + msg = "struct: integer argument expected, got float" else: - space.warn("integer argument expected, got non-integer", - space.w_DeprecationWarning) + msg = "integer argument expected, got non-integer" + space.warn(space.wrap(msg), space.w_DeprecationWarning) return space.int(w_obj) # wrapped float -> wrapped int or long else: diff --git a/pypy/objspace/std/complexobject.py b/pypy/objspace/std/complexobject.py --- a/pypy/objspace/std/complexobject.py +++ b/pypy/objspace/std/complexobject.py @@ -80,10 +80,8 @@ return W_ComplexObject(rr, ir) def divmod(self, space, other): - space.warn( - "complex divmod(), // and % are deprecated", - space.w_DeprecationWarning - ) + space.warn(space.wrap("complex divmod(), // and % are deprecated"), + space.w_DeprecationWarning) w_div = self.div(other) div = math.floor(w_div.realval) w_mod = self.sub( diff --git a/pypy/objspace/std/objecttype.py b/pypy/objspace/std/objecttype.py --- a/pypy/objspace/std/objecttype.py +++ b/pypy/objspace/std/objecttype.py @@ -126,11 +126,8 @@ msg = "format_spec must be a string" raise OperationError(space.w_TypeError, space.wrap(msg)) if space.len_w(w_format_spec) > 0: - space.warn( - ("object.__format__ with a non-empty format string is " - "deprecated"), - space.w_PendingDeprecationWarning - ) + msg = "object.__format__ with a non-empty format string is deprecated" + space.warn(space.wrap(msg), space.w_PendingDeprecationWarning) return space.format(w_as_str, w_format_spec) def descr___subclasshook__(space, __args__): diff --git a/pypy/objspace/std/typeobject.py b/pypy/objspace/std/typeobject.py --- a/pypy/objspace/std/typeobject.py +++ b/pypy/objspace/std/typeobject.py @@ -295,8 +295,9 @@ msg = "can't set attributes on type object '%s'" raise operationerrfmt(space.w_TypeError, msg, w_self.name) if name == "__del__" and name not in w_self.dict_w: - msg = "a __del__ method added to an existing type will not be called" - space.warn(msg, space.w_RuntimeWarning) + msg = ("a __del__ method added to an existing type will not be " + "called") + space.warn(space.wrap(msg), space.w_RuntimeWarning) if space.config.objspace.std.withtypeversion: version_tag = w_self.version_tag() if version_tag is not None: diff --git a/pypy/objspace/std/unicodeobject.py b/pypy/objspace/std/unicodeobject.py --- a/pypy/objspace/std/unicodeobject.py +++ b/pypy/objspace/std/unicodeobject.py @@ -119,13 +119,10 @@ w_uni2 = uni_from_str(space, w_str) except OperationError, e: if e.match(space, space.w_UnicodeDecodeError): - if inverse: - msg = "Unicode unequal comparison failed to convert both " \ - "arguments to Unicode - interpreting them as being unequal" - else : - msg = "Unicode equal comparison failed to convert both " \ - "arguments to Unicode - interpreting them as being unequal" - space.warn(msg, space.w_UnicodeWarning) + msg = ("Unicode %s comparison failed to convert both arguments to " + "Unicode - interpreting them as being unequal" % + "unequal" if inverse else "equal") + space.warn(space.wrap(msg), space.w_UnicodeWarning) return space.newbool(inverse) raise result = space.eq(w_uni, w_uni2) From noreply at buildbot.pypy.org Tue Feb 19 22:18:07 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Tue, 19 Feb 2013 22:18:07 +0100 (CET) Subject: [pypy-commit] pypy default: stub out a method for emitting warnings on implicit closing by __del__ Message-ID: <20130219211807.DEAC71C054C@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: Changeset: r61470:65f3a63f53d0 Date: 2013-02-19 13:17 -0800 http://bitbucket.org/pypy/pypy/changeset/65f3a63f53d0/ Log: stub out a method for emitting warnings on implicit closing by __del__ diff --git a/rpython/rlib/rsocket.py b/rpython/rlib/rsocket.py --- a/rpython/rlib/rsocket.py +++ b/rpython/rlib/rsocket.py @@ -497,8 +497,15 @@ def __del__(self): fd = self.fd if fd != _c.INVALID_SOCKET: - self.fd = _c.INVALID_SOCKET - _c.socketclose(fd) + try: + self._dealloc_warn() + finally: + self.fd = _c.INVALID_SOCKET + _c.socketclose(fd) + + def _dealloc_warn(self): + """Called when implicitly closed via the deconstructor""" + pass if hasattr(_c, 'fcntl'): def _setblocking(self, block): From noreply at buildbot.pypy.org Tue Feb 19 23:13:45 2013 From: noreply at buildbot.pypy.org (fijal) Date: Tue, 19 Feb 2013 23:13:45 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: fix? Message-ID: <20130219221345.7B8FB1C054C@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61471:fae3e9491cd4 Date: 2013-02-20 00:12 +0200 http://bitbucket.org/pypy/pypy/changeset/fae3e9491cd4/ Log: fix? diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -330,7 +330,7 @@ # save to store stuff 2 locations away on the stack. # we have to save all the things that can potentially # be returned from a call - mc.SUB_ri(esp.value, 6 * WORD) # align and reserve some space + mc.SUB_ri(esp.value, 10 * WORD) # align and reserve some space mc.MOV_sr(WORD, eax.value) # save for later mc.MOVSD_sx(3 * WORD, xmm0.value) if IS_X86_32: @@ -340,6 +340,8 @@ else: mc.MOV_rr(edi.value, ebp.value) exc0, exc1 = ebx, r12 + mc.MOV_sr(WORD * 5, exc0.value) + mc.MOV_sr(WORD * 6, exc1.value) self._store_and_reset_exception(mc, exc0, exc1) mc.CALL(imm(func)) @@ -368,7 +370,9 @@ mc.MOVSD_xs(xmm0.value, 3 * WORD) mc.MOV_rs(eax.value, WORD) # restore self._restore_exception(mc, exc0, exc1) - mc.LEA_rs(esp.value, 6 * WORD) + mc.MOV_rs(exc0.value, WORD * 5) + mc.MOV_rs(exc1.value, WORD * 6) + mc.LEA_rs(esp.value, 10 * WORD) mc.RET() rawstart = mc.materialize(self.cpu.asmmemmgr, []) From noreply at buildbot.pypy.org Tue Feb 19 23:15:40 2013 From: noreply at buildbot.pypy.org (fijal) Date: Tue, 19 Feb 2013 23:15:40 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: RPython Message-ID: <20130219221540.B00C01C054C@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61472:39d8dcea0457 Date: 2013-02-20 00:14 +0200 http://bitbucket.org/pypy/pypy/changeset/39d8dcea0457/ Log: RPython diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -340,8 +340,8 @@ else: mc.MOV_rr(edi.value, ebp.value) exc0, exc1 = ebx, r12 - mc.MOV_sr(WORD * 5, exc0.value) - mc.MOV_sr(WORD * 6, exc1.value) + mc.MOV(RawStackLoc(WORD * 5), exc0) + mc.MOV(RawStackLoc(WORD * 6), exc1) self._store_and_reset_exception(mc, exc0, exc1) mc.CALL(imm(func)) @@ -370,8 +370,8 @@ mc.MOVSD_xs(xmm0.value, 3 * WORD) mc.MOV_rs(eax.value, WORD) # restore self._restore_exception(mc, exc0, exc1) - mc.MOV_rs(exc0.value, WORD * 5) - mc.MOV_rs(exc1.value, WORD * 6) + mc.MOV(exc0, RawStackLoc(WORD * 5)) + mc.MOV(exc1, RawStackLoc(WORD * 6)) mc.LEA_rs(esp.value, 10 * WORD) mc.RET() From noreply at buildbot.pypy.org Tue Feb 19 23:48:19 2013 From: noreply at buildbot.pypy.org (arigo) Date: Tue, 19 Feb 2013 23:48:19 +0100 (CET) Subject: [pypy-commit] pypy stm-thread-2: Add comments Message-ID: <20130219224820.016561C05FF@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stm-thread-2 Changeset: r61473:a47a7cd9a488 Date: 2013-02-19 15:27 +0100 http://bitbucket.org/pypy/pypy/changeset/a47a7cd9a488/ Log: Add comments diff --git a/rpython/translator/stm/writebarrier.py b/rpython/translator/stm/writebarrier.py --- a/rpython/translator/stm/writebarrier.py +++ b/rpython/translator/stm/writebarrier.py @@ -10,13 +10,13 @@ ]) MORE_PRECISE_CATEGORIES = { - 'P': 'PGORLWN', - 'G': 'GN', - 'O': 'ORLWN', - 'R': 'RLWN', - 'L': 'LWN', - 'W': 'WN', - 'N': 'N'} + 'P': 'PGORLWN', # Pointer: the most general category + 'G': 'GN', # Global: known to be a non-local pointer + 'O': 'ORLWN', # Old: used to be read-ready, but maybe someone wrote + 'R': 'RLWN', # Read-ready: direct reads from there are ok + 'L': 'LWN', # Local: a local pointer + 'W': 'WN', # Write-ready: direct writes here are ok + 'N': 'N'} # NULL (the other categories also all contain NULL) def unwraplist(list_v): for v in list_v: From noreply at buildbot.pypy.org Tue Feb 19 23:48:21 2013 From: noreply at buildbot.pypy.org (arigo) Date: Tue, 19 Feb 2013 23:48:21 +0100 (CET) Subject: [pypy-commit] pypy stm-thread-2: Change the ThreadLocalRef to not be a cache any more. Now the GC should Message-ID: <20130219224821.5B5481C05FF@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stm-thread-2 Changeset: r61474:dfd6ba64bc51 Date: 2013-02-19 17:34 +0100 http://bitbucket.org/pypy/pypy/changeset/dfd6ba64bc51/ Log: Change the ThreadLocalRef to not be a cache any more. Now the GC should correctly follow and update the references we store there. diff --git a/rpython/rlib/rstm.py b/rpython/rlib/rstm.py --- a/rpython/rlib/rstm.py +++ b/rpython/rlib/rstm.py @@ -107,16 +107,14 @@ # ____________________________________________________________ class ThreadLocalReference(object): - _ALL = weakref.WeakKeyDictionary() _COUNT = 0 def __init__(self, Cls): "NOT_RPYTHON: must be prebuilt" self.Cls = Cls - self.local = thread._local() + self.local = thread._local() # <- NOT_RPYTHON self.unique_id = ThreadLocalReference._COUNT ThreadLocalReference._COUNT += 1 - ThreadLocalReference._ALL[self] = True def _freeze_(self): return True @@ -124,8 +122,7 @@ @specialize.arg(0) def get(self): if we_are_translated(): - ptr = llop.stm_threadlocalref_get(llmemory.Address, self.unique_id) - ptr = rffi.cast(rclass.OBJECTPTR, ptr) + ptr = llop.stm_threadlocalref_get(rclass.OBJECTPTR, self.unique_id) return cast_base_ptr_to_instance(self.Cls, ptr) else: return getattr(self.local, 'value', None) @@ -135,16 +132,6 @@ assert isinstance(value, self.Cls) or value is None if we_are_translated(): ptr = cast_instance_to_base_ptr(value) - ptr = rffi.cast(llmemory.Address, ptr) llop.stm_threadlocalref_set(lltype.Void, self.unique_id, ptr) else: self.local.value = value - - @staticmethod - def flush_all_in_this_thread(): - if we_are_translated(): - # NB. this line is repeated in stmtls.py - llop.stm_threadlocalref_flush(lltype.Void) - else: - for tlref in ThreadLocalReference._ALL.keys(): - tlref.local.value = None diff --git a/rpython/rlib/test/test_rstm.py b/rpython/rlib/test/test_rstm.py --- a/rpython/rlib/test/test_rstm.py +++ b/rpython/rlib/test/test_rstm.py @@ -10,10 +10,9 @@ x = FooBar() results.append(t.get() is None) t.set(x) + results.append(t.get() is x) time.sleep(0.2) results.append(t.get() is x) - ThreadLocalReference.flush_all_in_this_thread() - results.append(t.get() is None) for i in range(5): thread.start_new_thread(subthread, ()) time.sleep(0.5) diff --git a/rpython/rtyper/lltypesystem/lloperation.py b/rpython/rtyper/lltypesystem/lloperation.py --- a/rpython/rtyper/lltypesystem/lloperation.py +++ b/rpython/rtyper/lltypesystem/lloperation.py @@ -431,7 +431,8 @@ #'stm_jit_invoke_code': LLOp(canmallocgc=True), 'stm_threadlocalref_get': LLOp(sideeffects=False), 'stm_threadlocalref_set': LLOp(), - 'stm_threadlocalref_flush': LLOp(), + 'stm_threadlocalref_count': LLOp(sideeffects=False), + 'stm_threadlocalref_addr': LLOp(sideeffects=False), # __________ address operations __________ diff --git a/rpython/rtyper/memory/gc/stmtls.py b/rpython/rtyper/memory/gc/stmtls.py --- a/rpython/rtyper/memory/gc/stmtls.py +++ b/rpython/rtyper/memory/gc/stmtls.py @@ -179,10 +179,6 @@ # debug_start("gc-local") # - # First clear all thread-local caches, because they might - # contain pointers to objects that are about to move. - llop.stm_threadlocalref_flush(lltype.Void) - # if end_of_transaction: self.detect_flag_combination = GCFLAG_LOCAL_COPY | GCFLAG_VISITED else: @@ -207,6 +203,9 @@ # Find the roots that are living in raw structures. self.collect_from_raw_structures() # + # Find the roots in the THREADLOCALREF structure. + self.collect_from_threadlocalref() + # # Also find the roots that are the local copy of global objects. self.collect_roots_from_tldict() # @@ -359,6 +358,15 @@ self.gc.root_walker.walk_current_nongc_roots( StmGCTLS._trace_drag_out1, self) + def collect_from_threadlocalref(self): + if not we_are_translated(): + return + i = llop.stm_threadlocalref_count(lltype.Signed) + while i > 0: + i -= 1 + root = llop.stm_threadlocalref_addr(llmemory.Address, i) + self._trace_drag_out(root, None) + def trace_and_drag_out_of_nursery(self, obj): # This is called to fix the references inside 'obj', to ensure that # they are global. If necessary, the referenced objects are copied diff --git a/rpython/translator/stm/test/test_ztranslated.py b/rpython/translator/stm/test/test_ztranslated.py --- a/rpython/translator/stm/test/test_ztranslated.py +++ b/rpython/translator/stm/test/test_ztranslated.py @@ -1,5 +1,8 @@ import py from rpython.rlib import rstm, rgc +from rpython.rtyper.lltypesystem import lltype, llmemory +from rpython.rtyper.lltypesystem.lloperation import llop +from rpython.rtyper.annlowlevel import cast_instance_to_base_ptr from rpython.translator.stm.test.support import NoGcCompiledSTMTests from rpython.translator.stm.test.support import CompiledSTMTests from rpython.translator.stm.test import targetdemo2 @@ -114,8 +117,12 @@ assert t.get() is None t.set(x) assert t.get() is x - rstm.ThreadLocalReference.flush_all_in_this_thread() - assert t.get() is None + assert llop.stm_threadlocalref_count(lltype.Signed) == 1 + p = llop.stm_threadlocalref_addr(llmemory.Address, 0) + adr = p.address[0] + adr2 = cast_instance_to_base_ptr(x) + adr2 = llmemory.cast_ptr_to_adr(adr2) + assert adr == adr2 print "ok" return 0 t, cbuilder = self.compile(main) diff --git a/rpython/translator/stm/threadlocalref.py b/rpython/translator/stm/threadlocalref.py --- a/rpython/translator/stm/threadlocalref.py +++ b/rpython/translator/stm/threadlocalref.py @@ -20,15 +20,12 @@ ids.add(op.args[0].value) # ids = sorted(ids) - fields = [('ptr%d' % id1, llmemory.Address) for id1 in ids] - kwds = {'hints': {'stm_thread_local': True}} - S = lltype.Struct('THREADLOCALREF', *fields, **kwds) + ARRAY = lltype.FixedSizeArray(llmemory.Address, len(ids)) + S = lltype.Struct('THREADLOCALREF', ('ptr', ARRAY), + hints={'stm_thread_local': True}) ll_threadlocalref = lltype.malloc(S, immortal=True) c_threadlocalref = Constant(ll_threadlocalref, lltype.Ptr(S)) - c_fieldnames = {} - for id1 in ids: - fieldname = 'ptr%d' % id1 - c_fieldnames[id1] = Constant(fieldname, lltype.Void) + c_fieldname = Constant('ptr', lltype.Void) c_null = Constant(llmemory.NULL, llmemory.Address) # for graph in graphs: @@ -36,24 +33,37 @@ for i in range(len(block.operations)-1, -1, -1): op = block.operations[i] if op.opname == 'stm_threadlocalref_set': - id1 = op.args[0].value - op = SpaceOperation('setfield', [c_threadlocalref, - c_fieldnames[id1], - op.args[1]], - op.result) + v_array = varoftype(lltype.Ptr(ARRAY)) + ops = [ + SpaceOperation('getfield', [c_threadlocalref, + c_fieldname], + v_array), + SpaceOperation('setarrayitem', [v_array, + op.args[0], + op.args[1]], + op.result)] + block.operations[i:i+1] = ops + elif op.opname == 'stm_threadlocalref_get': + v_array = varoftype(lltype.Ptr(ARRAY)) + ops = [ + SpaceOperation('getfield', [c_threadlocalref, + c_fieldname], + v_array), + SpaceOperation('getarrayitem', [v_array, + op.args[0]], + op.result)] + block.operations[i:i+1] = ops + elif op.opname == 'stm_threadlocalref_addr': + v_array = varoftype(lltype.Ptr(ARRAY)) + ops = [ + SpaceOperation('getfield', [c_threadlocalref, + c_fieldname], + v_array), + SpaceOperation('direct_ptradd', [v_array, + op.args[0]], + op.result)] + block.operations[i:i+1] = ops + elif op.opname == 'stm_threadlocalref_count': + c_count = Constant(len(ids), lltype.Signed) + op = SpaceOperation('same_as', [c_count], op.result) block.operations[i] = op - elif op.opname == 'stm_threadlocalref_get': - id1 = op.args[0].value - op = SpaceOperation('getfield', [c_threadlocalref, - c_fieldnames[id1]], - op.result) - block.operations[i] = op - elif op.opname == 'stm_threadlocalref_flush': - extra = [] - for id1 in ids: - op = SpaceOperation('setfield', [c_threadlocalref, - c_fieldnames[id1], - c_null], - varoftype(lltype.Void)) - extra.append(op) - block.operations[i:i+1] = extra From noreply at buildbot.pypy.org Tue Feb 19 23:48:22 2013 From: noreply at buildbot.pypy.org (arigo) Date: Tue, 19 Feb 2013 23:48:22 +0100 (CET) Subject: [pypy-commit] pypy stm-thread-2: Don't use a dict at all to store the executioncontext. Message-ID: <20130219224822.8B9ED1C05FF@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stm-thread-2 Changeset: r61475:beecf13099d5 Date: 2013-02-19 17:43 +0100 http://bitbucket.org/pypy/pypy/changeset/beecf13099d5/ Log: Don't use a dict at all to store the executioncontext. diff --git a/pypy/module/sys/currentframes.py b/pypy/module/sys/currentframes.py --- a/pypy/module/sys/currentframes.py +++ b/pypy/module/sys/currentframes.py @@ -49,7 +49,12 @@ w_result = space.newdict() w_fake_frame = app.wget(space, "fake_frame") w_fake_code = app.wget(space, "fake_code") - ecs = space.threadlocals.getallvalues() + try: + ecs = space.threadlocals.getallvalues() + except ValueError: + raise OperationError(space.w_RuntimeError, + space.wrap("sys._current_frames() not supported" + " on this configuration")) for thread_ident, ec in ecs.items(): vref = ec.topframeref frames = [] diff --git a/pypy/module/thread/stm.py b/pypy/module/thread/stm.py --- a/pypy/module/thread/stm.py +++ b/pypy/module/thread/stm.py @@ -15,6 +15,8 @@ class STMThreadLocals(OSThreadLocals): + use_dict = False + def initialize(self, space): """NOT_RPYTHON: set up a mechanism to send to the C code the value set by space.actionflag.setcheckinterval().""" @@ -30,16 +32,14 @@ space.actionflag.setcheckinterval_callback = setcheckinterval_callback self.threads_running = False - def clear_cache(self): - ec_cache.set(None) + def getvalue(self): + return ec_cache.get() - def getvalue(self): - value = ec_cache.get() - if value is None: - ident = rthread.get_ident() - value = self._valuedict.get(ident, None) - ec_cache.set(value) - return value + def setvalue(self, value): + ec_cache.set(value) + + def getallvalues(self): + raise ValueError def setup_threads(self, space): self.threads_running = True diff --git a/pypy/module/thread/threadlocals.py b/pypy/module/thread/threadlocals.py --- a/pypy/module/thread/threadlocals.py +++ b/pypy/module/thread/threadlocals.py @@ -12,14 +12,18 @@ a thread finishes. This works as long as the thread was started by os_thread.bootstrap().""" + use_dict = True + def __init__(self): - self._valuedict = {} # {thread_ident: ExecutionContext()} + if self.use_dict: + self._valuedict = {} # {thread_ident: ExecutionContext()} self._cleanup_() def _cleanup_(self): - self._valuedict.clear() + if self.use_dict: + self._valuedict.clear() + self.clear_cache() self._mainthreadident = 0 - self.clear_cache() def clear_cache(self): # Cache function: fast minicaching for the common case. Relies @@ -41,6 +45,7 @@ return result def setvalue(self, value): + # Overridden in stm.py. ident = rthread.get_ident() if value is not None: if len(self._valuedict) == 0: @@ -72,6 +77,7 @@ ec._signals_enabled = new def getallvalues(self): + # Overridden in stm.py. return self._valuedict def leave_thread(self, space): From noreply at buildbot.pypy.org Tue Feb 19 23:48:23 2013 From: noreply at buildbot.pypy.org (arigo) Date: Tue, 19 Feb 2013 23:48:23 +0100 (CET) Subject: [pypy-commit] pypy stm-thread-2: merge heads Message-ID: <20130219224823.BBFB81C05FF@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stm-thread-2 Changeset: r61476:1ed1bcec48fd Date: 2013-02-19 17:45 +0100 http://bitbucket.org/pypy/pypy/changeset/1ed1bcec48fd/ Log: merge heads diff --git a/rpython/translator/stm/src_stm/rpyintf.c b/rpython/translator/stm/src_stm/rpyintf.c --- a/rpython/translator/stm/src_stm/rpyintf.c +++ b/rpython/translator/stm/src_stm/rpyintf.c @@ -94,7 +94,7 @@ d->count_reads is greater than reads_size_limit == reads_size_limit_nonatomic. */ -#ifdef RPY_STM_ASSERT +#if 0 /* ifdef RPY_STM_ASSERT */ /* reads_size_limit is ULONG_MAX if d->atomic, or else it is equal to reads_size_limit_nonatomic. */ assert(d->reads_size_limit == (d->atomic ? ULONG_MAX : From noreply at buildbot.pypy.org Tue Feb 19 23:48:24 2013 From: noreply at buildbot.pypy.org (arigo) Date: Tue, 19 Feb 2013 23:48:24 +0100 (CET) Subject: [pypy-commit] pypy stm-thread-2: Fixes Message-ID: <20130219224824.E696B1C05FF@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stm-thread-2 Changeset: r61477:b441cc9474a3 Date: 2013-02-19 19:00 +0100 http://bitbucket.org/pypy/pypy/changeset/b441cc9474a3/ Log: Fixes diff --git a/pypy/module/signal/interp_signal.py b/pypy/module/signal/interp_signal.py --- a/pypy/module/signal/interp_signal.py +++ b/pypy/module/signal/interp_signal.py @@ -170,7 +170,7 @@ space.wrap("invalid signal value")) if not space.threadlocals.signals_enabled(): raise OperationError(space.w_ValueError, - space.wrap("signal only works in main thread " + space.wrap("signal() only works in main thread " "or with __pypy__.thread.enable_signals()")) check_signum_in_range(space, signum) @@ -203,7 +203,7 @@ if not space.threadlocals.signals_enabled(): raise OperationError( space.w_ValueError, - space.wrap("set_wakeup_fd only works in main thread " + space.wrap("set_wakeup_fd() only works in main thread " "or with __pypy__.thread.enable_signals()")) old_fd = pypysig_set_wakeup_fd(fd) return space.wrap(intmask(old_fd)) diff --git a/pypy/module/thread/stm.py b/pypy/module/thread/stm.py --- a/pypy/module/thread/stm.py +++ b/pypy/module/thread/stm.py @@ -31,11 +31,16 @@ assert space.actionflag.setcheckinterval_callback is None space.actionflag.setcheckinterval_callback = setcheckinterval_callback self.threads_running = False + self.seen_main_ec = False def getvalue(self): return ec_cache.get() def setvalue(self, value): + if not self.seen_main_ec: + value._signals_enabled = 1 # the main thread is enabled + self._mainthreadident = rthread.get_ident() + self.seen_main_ec = True ec_cache.set(value) def getallvalues(self): @@ -51,6 +56,11 @@ def reinit_threads(self, space): self.setup_threads(space) + ident = rthread.get_ident() + if ident != self._mainthreadident: + ec = self.getvalue() + ec._signals_enabled += 1 + self._mainthreadident = ident def configure_transaction_length(self, space): if self.threads_running: From noreply at buildbot.pypy.org Tue Feb 19 23:48:26 2013 From: noreply at buildbot.pypy.org (arigo) Date: Tue, 19 Feb 2013 23:48:26 +0100 (CET) Subject: [pypy-commit] pypy stm-thread-2: Support undoing changes done to the thread-local structure in case of Message-ID: <20130219224826.265B61C05FF@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stm-thread-2 Changeset: r61478:d33ea9274810 Date: 2013-02-19 22:54 +0100 http://bitbucket.org/pypy/pypy/changeset/d33ea9274810/ Log: Support undoing changes done to the thread-local structure in case of aborts. diff --git a/rpython/rtyper/lltypesystem/lloperation.py b/rpython/rtyper/lltypesystem/lloperation.py --- a/rpython/rtyper/lltypesystem/lloperation.py +++ b/rpython/rtyper/lltypesystem/lloperation.py @@ -431,8 +431,9 @@ #'stm_jit_invoke_code': LLOp(canmallocgc=True), 'stm_threadlocalref_get': LLOp(sideeffects=False), 'stm_threadlocalref_set': LLOp(), - 'stm_threadlocalref_count': LLOp(sideeffects=False), - 'stm_threadlocalref_addr': LLOp(sideeffects=False), + 'stm_threadlocalref_llset': LLOp(), + 'stm_threadlocalref_llcount': LLOp(sideeffects=False), + 'stm_threadlocalref_lladdr': LLOp(sideeffects=False), # __________ address operations __________ diff --git a/rpython/rtyper/memory/gc/stmtls.py b/rpython/rtyper/memory/gc/stmtls.py --- a/rpython/rtyper/memory/gc/stmtls.py +++ b/rpython/rtyper/memory/gc/stmtls.py @@ -361,10 +361,10 @@ def collect_from_threadlocalref(self): if not we_are_translated(): return - i = llop.stm_threadlocalref_count(lltype.Signed) + i = llop.stm_threadlocalref_llcount(lltype.Signed) while i > 0: i -= 1 - root = llop.stm_threadlocalref_addr(llmemory.Address, i) + root = llop.stm_threadlocalref_lladdr(llmemory.Address, i) self._trace_drag_out(root, None) def trace_and_drag_out_of_nursery(self, obj): diff --git a/rpython/translator/stm/inevitable.py b/rpython/translator/stm/inevitable.py --- a/rpython/translator/stm/inevitable.py +++ b/rpython/translator/stm/inevitable.py @@ -15,8 +15,9 @@ 'jit_record_known_class', 'gc_identityhash', 'gc_id', 'gc_adr_of_root_stack_top', - 'weakref_create', 'weakref_deref', + 'stm_threadlocalref_get', 'stm_threadlocalref_set', + 'stm_threadlocalref_count', 'stm_threadlocalref_addr', ]) ALWAYS_ALLOW_OPERATIONS |= set(lloperation.enum_tryfold_ops()) diff --git a/rpython/translator/stm/src_stm/et.c b/rpython/translator/stm/src_stm/et.c --- a/rpython/translator/stm/src_stm/et.c +++ b/rpython/translator/stm/src_stm/et.c @@ -54,6 +54,7 @@ struct GcPtrList list_of_read_objects; struct GcPtrList gcroots; struct G2L global_to_local; + struct GcPtrList undolog; struct FXCache recent_reads_cache; }; @@ -378,6 +379,16 @@ CancelLocks(d); + if (d->undolog.size > 0) { + gcptr *item = d->undolog.items; + long i; + for (i=d->undolog.size; i>=0; i-=2) { + void **addr = (void **)(item[i-2]); + void *oldvalue = (void *)(item[i-1]); + *addr = oldvalue; + } + } + /* upon abort, set the reads size limit to 94% of how much was read so far. This should ensure that, assuming the retry does the same thing, it will commit just before it reaches the conflicting point. */ @@ -423,6 +434,7 @@ assert(!g2l_any_entry(&d->global_to_local)); d->count_reads = 0; fxcache_clear(&d->recent_reads_cache); + gcptrlist_clear(&d->undolog); } void BeginTransaction(jmp_buf* buf) @@ -771,6 +783,15 @@ /************************************************************/ +void stm_ThreadLocalRef_LLSet(void **addr, void *newvalue) +{ + struct tx_descriptor *d = thread_descriptor; + gcptrlist_insert2(&d->undolog, (gcptr)addr, (gcptr)*addr); + *addr = newvalue; +} + +/************************************************************/ + int DescriptorInit(void) { if (thread_descriptor == NULL) diff --git a/rpython/translator/stm/src_stm/et.h b/rpython/translator/stm/src_stm/et.h --- a/rpython/translator/stm/src_stm/et.h +++ b/rpython/translator/stm/src_stm/et.h @@ -74,6 +74,9 @@ #define STM_PTR_EQ(P1, P2) \ stm_PtrEq((gcptr)(P1), (gcptr)(P2)) +#define OP_STM_THREADLOCALREF_LLSET(P, X, IGNORED) \ + stm_ThreadLocalRef_LLSet((void **)(P), (void *)(X)) + /* special usage only */ #define OP_STM_READ_BARRIER(P, R) R = STM_BARRIER_P2R(P) #define OP_STM_WRITE_BARRIER(P, W) W = STM_BARRIER_P2W(P) @@ -99,6 +102,8 @@ void *stm_WriteBarrierFromReady(void *); //gcptr _NonTransactionalReadBarrier(gcptr); +void stm_ThreadLocalRef_LLSet(void **P, void *X); + extern void *pypy_g__stm_duplicate(void *); extern void pypy_g__stm_enum_callback(void *, void *); diff --git a/rpython/translator/stm/test/test_ztranslated.py b/rpython/translator/stm/test/test_ztranslated.py --- a/rpython/translator/stm/test/test_ztranslated.py +++ b/rpython/translator/stm/test/test_ztranslated.py @@ -117,8 +117,8 @@ assert t.get() is None t.set(x) assert t.get() is x - assert llop.stm_threadlocalref_count(lltype.Signed) == 1 - p = llop.stm_threadlocalref_addr(llmemory.Address, 0) + assert llop.stm_threadlocalref_llcount(lltype.Signed) == 1 + p = llop.stm_threadlocalref_lladdr(llmemory.Address, 0) adr = p.address[0] adr2 = cast_instance_to_base_ptr(x) adr2 = llmemory.cast_ptr_to_adr(adr2) diff --git a/rpython/translator/stm/threadlocalref.py b/rpython/translator/stm/threadlocalref.py --- a/rpython/translator/stm/threadlocalref.py +++ b/rpython/translator/stm/threadlocalref.py @@ -28,20 +28,24 @@ c_fieldname = Constant('ptr', lltype.Void) c_null = Constant(llmemory.NULL, llmemory.Address) # + def getaddr(v_num, v_result): + v_array = varoftype(lltype.Ptr(ARRAY)) + ops = [ + SpaceOperation('getfield', [c_threadlocalref, c_fieldname], + v_array), + SpaceOperation('direct_ptradd', [v_array, v_num], v_result)] + return ops + # for graph in graphs: for block in graph.iterblocks(): for i in range(len(block.operations)-1, -1, -1): op = block.operations[i] if op.opname == 'stm_threadlocalref_set': - v_array = varoftype(lltype.Ptr(ARRAY)) - ops = [ - SpaceOperation('getfield', [c_threadlocalref, - c_fieldname], - v_array), - SpaceOperation('setarrayitem', [v_array, - op.args[0], - op.args[1]], - op.result)] + v_addr = varoftype(lltype.Ptr(ARRAY)) + ops = getaddr(op.args[0], v_addr) + ops.append(SpaceOperation('stm_threadlocalref_llset', + [v_addr, op.args[1]], + op.result)) block.operations[i:i+1] = ops elif op.opname == 'stm_threadlocalref_get': v_array = varoftype(lltype.Ptr(ARRAY)) @@ -53,17 +57,9 @@ op.args[0]], op.result)] block.operations[i:i+1] = ops - elif op.opname == 'stm_threadlocalref_addr': - v_array = varoftype(lltype.Ptr(ARRAY)) - ops = [ - SpaceOperation('getfield', [c_threadlocalref, - c_fieldname], - v_array), - SpaceOperation('direct_ptradd', [v_array, - op.args[0]], - op.result)] - block.operations[i:i+1] = ops - elif op.opname == 'stm_threadlocalref_count': + elif op.opname == 'stm_threadlocalref_lladdr': + block.operations[i:i+1] = getaddr(op.args[0], op.result) + elif op.opname == 'stm_threadlocalref_llcount': c_count = Constant(len(ids), lltype.Signed) op = SpaceOperation('same_as', [c_count], op.result) block.operations[i] = op From noreply at buildbot.pypy.org Tue Feb 19 23:48:27 2013 From: noreply at buildbot.pypy.org (arigo) Date: Tue, 19 Feb 2013 23:48:27 +0100 (CET) Subject: [pypy-commit] pypy stm-thread-2: Fixes Message-ID: <20130219224827.5464F1C05FF@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stm-thread-2 Changeset: r61479:16fca4fe4397 Date: 2013-02-19 23:48 +0100 http://bitbucket.org/pypy/pypy/changeset/16fca4fe4397/ Log: Fixes diff --git a/pypy/module/sys/currentframes.py b/pypy/module/sys/currentframes.py --- a/pypy/module/sys/currentframes.py +++ b/pypy/module/sys/currentframes.py @@ -2,6 +2,7 @@ Implementation of the 'sys._current_frames()' routine. """ from pypy.interpreter import gateway +from pypy.interpreter.error import OperationError app = gateway.applevel(''' "NOT_RPYTHON" diff --git a/pypy/module/thread/stm.py b/pypy/module/thread/stm.py --- a/pypy/module/thread/stm.py +++ b/pypy/module/thread/stm.py @@ -37,7 +37,7 @@ return ec_cache.get() def setvalue(self, value): - if not self.seen_main_ec: + if not self.seen_main_ec and value is not None: value._signals_enabled = 1 # the main thread is enabled self._mainthreadident = rthread.get_ident() self.seen_main_ec = True diff --git a/rpython/rtyper/memory/gc/stmtls.py b/rpython/rtyper/memory/gc/stmtls.py --- a/rpython/rtyper/memory/gc/stmtls.py +++ b/rpython/rtyper/memory/gc/stmtls.py @@ -365,7 +365,8 @@ while i > 0: i -= 1 root = llop.stm_threadlocalref_lladdr(llmemory.Address, i) - self._trace_drag_out(root, None) + if self.points_to_valid_gc_object(root): + self._trace_drag_out(root, None) def trace_and_drag_out_of_nursery(self, obj): # This is called to fix the references inside 'obj', to ensure that From noreply at buildbot.pypy.org Tue Feb 19 23:49:16 2013 From: noreply at buildbot.pypy.org (fijal) Date: Tue, 19 Feb 2013 23:49:16 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: fixes for moving GC Message-ID: <20130219224916.E04A61C05FF@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61480:f1af42073d1b Date: 2013-02-20 00:48 +0200 http://bitbucket.org/pypy/pypy/changeset/f1af42073d1b/ Log: fixes for moving GC diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -145,20 +145,18 @@ mc.MOV_rr(edi.value, ebp.value) align = align_stack_words(1) mc.SUB_ri(esp.value, (align - 1) * WORD) - exc0, exc1 = ebx, r12 # callee saved regs for storing exc else: align = align_stack_words(3) mc.MOV_rs(eax.value, WORD * 2) mc.SUB_ri(esp.value, (align - 1) * WORD) mc.MOV_sr(WORD, eax.value) mc.MOV_sr(0, ebp.value) - exc0, exc1 = esi, edi # callee saved regs for storing exc # align - self._store_and_reset_exception(mc, exc0, exc1) + self._store_and_reset_exception(mc, None, ebx, ecx) mc.CALL(imm(self.cpu.realloc_frame)) - self._restore_exception(mc, exc0, exc1) + self._restore_exception(mc, None, ebx, ecx) mc.ADD_ri(esp.value, (align - 1) * WORD) mc.MOV_rr(ebp.value, eax.value) @@ -342,6 +340,10 @@ exc0, exc1 = ebx, r12 mc.MOV(RawStackLoc(WORD * 5), exc0) mc.MOV(RawStackLoc(WORD * 6), exc1) + # note that it's save to store the exception in register, + # since the call to write barrier can't collect + # (and this is assumed a bit left and right here, like lack + # of _reload_frame_if_necessary) self._store_and_reset_exception(mc, exc0, exc1) mc.CALL(imm(func)) @@ -1726,19 +1728,34 @@ self.implement_guard(guard_token, 'NE') self._store_and_reset_exception(self.mc, resloc) - def _store_and_reset_exception(self, mc, excvalloc=None, exctploc=None): + def _store_and_reset_exception(self, mc, excvalloc=None, exctploc=None, + tmploc=None): + """ Resest the exception. If excvalloc is None, then store it on the + frame in jf_guard_exc + """ if excvalloc is not None: assert excvalloc.is_reg() mc.MOV(excvalloc, heap(self.cpu.pos_exc_value())) - if exctploc is not None: - assert exctploc.is_reg() - mc.MOV(exctploc, heap(self.cpu.pos_exception())) + elif tmploc is not None: # if both are None, just ignore + ofs = self.cpu.get_ofs_of_frame_field('jf_guard_exc') + mc.MOV(tmploc, heap(self.cpu.pos_exc_value())) + mc.MOV(RawStackLoc(ofs), tmploc) + if exctploc is not None: + assert exctploc.is_reg() + mc.MOV(exctploc, heap(self.cpu.pos_exception())) mc.MOV(heap(self.cpu.pos_exception()), imm0) mc.MOV(heap(self.cpu.pos_exc_value()), imm0) - def _restore_exception(self, mc, excvalloc, exctploc): - mc.MOV(heap(self.cpu.pos_exc_value()), excvalloc) + def _restore_exception(self, mc, excvalloc, exctploc, tmploc=None): + if excvalloc is not None: + mc.MOV(heap(self.cpu.pos_exc_value()), excvalloc) + else: + assert tmploc is not None + ofs = self.cpu.get_ofs_of_frame_field('jf_guard_exc') + mc.MOV(tmploc, RawStackLoc(ofs)) + mc.MOV_bi(ofs, 0) + mc.MOV(heap(self.cpu.pos_exc_value()), tmploc) mc.MOV(heap(self.cpu.pos_exception()), exctploc) def _gen_guard_overflow(self, guard_op, guard_token): From noreply at buildbot.pypy.org Tue Feb 19 23:50:15 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Tue, 19 Feb 2013 23:50:15 +0100 (CET) Subject: [pypy-commit] pypy py3k: merge default Message-ID: <20130219225015.624341C05FF@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61481:38799d78b6dc Date: 2013-02-19 14:10 -0800 http://bitbucket.org/pypy/pypy/changeset/38799d78b6dc/ Log: merge default diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -1519,10 +1519,11 @@ ) return fd - def warn(self, msg, w_warningcls): - self.appexec([self.wrap(msg), w_warningcls], """(msg, warningcls): + def warn(self, w_msg, w_warningcls, stacklevel=2): + self.appexec([w_msg, w_warningcls, self.wrap(stacklevel)], + """(msg, warningcls, stacklevel): import _warnings - _warnings.warn(msg, warningcls, stacklevel=2) + _warnings.warn(msg, warningcls, stacklevel=stacklevel) """) diff --git a/pypy/module/cpyext/import_.py b/pypy/module/cpyext/import_.py --- a/pypy/module/cpyext/import_.py +++ b/pypy/module/cpyext/import_.py @@ -46,8 +46,9 @@ @cpython_api([CONST_STRING], PyObject) def PyImport_ImportModuleNoBlock(space, name): - space.warn('PyImport_ImportModuleNoBlock() is not non-blocking', - space.w_RuntimeWarning) + space.warn( + space.wrap('PyImport_ImportModuleNoBlock() is not non-blocking'), + space.w_RuntimeWarning) return PyImport_Import(space, space.wrap(rffi.charp2str(name))) @cpython_api([PyObject], PyObject) diff --git a/pypy/module/exceptions/interp_exceptions.py b/pypy/module/exceptions/interp_exceptions.py --- a/pypy/module/exceptions/interp_exceptions.py +++ b/pypy/module/exceptions/interp_exceptions.py @@ -215,8 +215,8 @@ if self.w_message is None: raise OperationError(space.w_AttributeError, space.wrap("message was deleted")) - space.warn("BaseException.message has been deprecated as of Python 2.6", - space.w_DeprecationWarning) + msg = "BaseException.message has been deprecated as of Python 2.6" + space.warn(space.wrap(msg), space.w_DeprecationWarning) return self.w_message def descr_message_set(self, space, w_new): diff --git a/pypy/module/imp/importing.py b/pypy/module/imp/importing.py --- a/pypy/module/imp/importing.py +++ b/pypy/module/imp/importing.py @@ -167,9 +167,9 @@ "Parent module '%s' not loaded, " "cannot perform relative import" % ctxt_package)) else: - space.warn("Parent module '%s' not found " - "while handling absolute import" % ctxt_package, - space.w_RuntimeWarning) + msg = ("Parent module '%s' not found while handling absolute " + "import" % ctxt_package) + space.warn(space.wrap(msg), space.w_RuntimeWarning) rel_modulename = ctxt_package[:dot_position] rel_level = rel_modulename.count('.') + 1 @@ -510,9 +510,9 @@ if modtype in (PY_SOURCE, PY_COMPILED): return FindInfo(PKG_DIRECTORY, filepart, None) else: - msg = "Not importing directory " +\ - "'%s' missing __init__.py" % (filepart,) - space.warn(msg, space.w_ImportWarning) + msg = ("Not importing directory '%s' missing __init__.py" % + (filepart,)) + space.warn(space.wrap(msg), space.w_ImportWarning) modtype, suffix, filemode = find_modtype(space, filepart) try: if modtype in (PY_SOURCE, PY_COMPILED, C_EXTENSION): diff --git a/pypy/module/struct/formatiterator.py b/pypy/module/struct/formatiterator.py --- a/pypy/module/struct/formatiterator.py +++ b/pypy/module/struct/formatiterator.py @@ -83,11 +83,10 @@ def _maybe_float(self, w_obj): space = self.space if space.is_true(space.isinstance(w_obj, space.w_float)): - space.warn("struct: integer argument expected, got float", - space.w_DeprecationWarning) + msg = "struct: integer argument expected, got float" else: - space.warn("integer argument expected, got non-integer", - space.w_DeprecationWarning) + msg = "integer argument expected, got non-integer" + space.warn(space.wrap(msg), space.w_DeprecationWarning) return space.int(w_obj) # wrapped float -> wrapped int or long else: diff --git a/pypy/objspace/std/objecttype.py b/pypy/objspace/std/objecttype.py --- a/pypy/objspace/std/objecttype.py +++ b/pypy/objspace/std/objecttype.py @@ -123,11 +123,8 @@ msg = "format_spec must be a string" raise OperationError(space.w_TypeError, space.wrap(msg)) if space.len_w(w_format_spec) > 0: - space.warn( - ("object.__format__ with a non-empty format string is " - "deprecated"), - space.w_PendingDeprecationWarning - ) + msg = "object.__format__ with a non-empty format string is deprecated" + space.warn(space.wrap(msg), space.w_PendingDeprecationWarning) return space.format(w_as_str, w_format_spec) def descr___subclasshook__(space, __args__): diff --git a/pypy/objspace/std/typeobject.py b/pypy/objspace/std/typeobject.py --- a/pypy/objspace/std/typeobject.py +++ b/pypy/objspace/std/typeobject.py @@ -293,8 +293,9 @@ msg = "can't set attributes on type object '%s'" raise operationerrfmt(space.w_TypeError, msg, w_self.name) if name == "__del__" and name not in w_self.dict_w: - msg = "a __del__ method added to an existing type will not be called" - space.warn(msg, space.w_RuntimeWarning) + msg = ("a __del__ method added to an existing type will not be " + "called") + space.warn(space.wrap(msg), space.w_RuntimeWarning) if space.config.objspace.std.withtypeversion: version_tag = w_self.version_tag() if version_tag is not None: diff --git a/rpython/rlib/rsocket.py b/rpython/rlib/rsocket.py --- a/rpython/rlib/rsocket.py +++ b/rpython/rlib/rsocket.py @@ -497,8 +497,15 @@ def __del__(self): fd = self.fd if fd != _c.INVALID_SOCKET: - self.fd = _c.INVALID_SOCKET - _c.socketclose(fd) + try: + self._dealloc_warn() + finally: + self.fd = _c.INVALID_SOCKET + _c.socketclose(fd) + + def _dealloc_warn(self): + """Called when implicitly closed via the deconstructor""" + pass if hasattr(_c, 'fcntl'): def _setblocking(self, block): From noreply at buildbot.pypy.org Tue Feb 19 23:50:16 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Tue, 19 Feb 2013 23:50:16 +0100 (CET) Subject: [pypy-commit] pypy py3k: update to the new warn API Message-ID: <20130219225016.C8EBF1C05FF@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61482:e23b1d81372f Date: 2013-02-19 14:30 -0800 http://bitbucket.org/pypy/pypy/changeset/e23b1d81372f/ Log: update to the new warn API diff --git a/pypy/module/_io/interp_bufferedio.py b/pypy/module/_io/interp_bufferedio.py --- a/pypy/module/_io/interp_bufferedio.py +++ b/pypy/module/_io/interp_bufferedio.py @@ -105,7 +105,8 @@ return space.wrap(len(data)) def _complain_about_max_buffer_size(self, space): - space.warn("max_buffer_size is deprecated", space.w_DeprecationWarning) + space.warn(space.wrap("max_buffer_size is deprecated"), + space.w_DeprecationWarning) W_BufferedIOBase.typedef = TypeDef( '_BufferedIOBase', W_IOBase.typedef, diff --git a/pypy/module/_io/interp_fileio.py b/pypy/module/_io/interp_fileio.py --- a/pypy/module/_io/interp_fileio.py +++ b/pypy/module/_io/interp_fileio.py @@ -249,14 +249,9 @@ def _dealloc_warn_w(self, space, w_source): if self.fd >= 0 and self.closefd: try: - r = space.unicode_w(space.repr(w_source)) - # TODO: space.warn is currently typed to str - #space.warn(u"unclosed file %s" % r, space.w_ResourceWarning) - msg = u"unclosed file %s" % r - space.appexec([space.wrap(msg), space.w_ResourceWarning], - """(msg, warningcls): - import _warnings - _warnings.warn(msg, warningcls, stacklevel=2)""") + msg = (u"unclosed file %s" % + space.unicode_w(space.repr(w_source))) + space.warn(space.wrap(msg), space.w_ResourceWarning) except OperationError as e: # Spurious errors can appear at shutdown if e.match(space, space.w_Warning): diff --git a/pypy/module/array/interp_array.py b/pypy/module/array/interp_array.py --- a/pypy/module/array/interp_array.py +++ b/pypy/module/array/interp_array.py @@ -575,8 +575,8 @@ self.fromstring(space.bufferstr_w(w_s)) def array_fromstring__Array_ANY(space, self, w_s): - space.warn("fromstring() is deprecated. Use frombytes() instead.", - self.space.w_DeprecationWarning) + msg = "fromstring() is deprecated. Use frombytes() instead." + space.warn(space.wrap(msg), self.space.w_DeprecationWarning) self.fromstring(space.str_w(w_s)) def array_tobytes__Array(space, self): @@ -586,8 +586,8 @@ return self.space.wrapbytes(s) def array_tostring__Array(space, self): - space.warn("tostring() is deprecated. Use tobytes() instead.", - space.w_DeprecationWarning) + msg = "tostring() is deprecated. Use tobytes() instead." + space.warn(space.wrap(msg), space.w_DeprecationWarning) return array_tobytes__Array(space, self) def array_fromfile__Array_ANY_ANY(space, self, w_f, w_n): diff --git a/pypy/module/rctime/interp_time.py b/pypy/module/rctime/interp_time.py --- a/pypy/module/rctime/interp_time.py +++ b/pypy/module/rctime/interp_time.py @@ -444,7 +444,7 @@ else: raise OperationError(space.w_ValueError, space.wrap("year out of range")) - space.warn("Century info guessed for a 2-digit year.", + space.warn(space.wrap("Century info guessed for a 2-digit year."), space.w_DeprecationWarning) # tm_wday does not need checking of its upper-bound since taking "% diff --git a/pypy/objspace/std/stringobject.py b/pypy/objspace/std/stringobject.py --- a/pypy/objspace/std/stringobject.py +++ b/pypy/objspace/std/stringobject.py @@ -972,7 +972,8 @@ def str__String(space, w_str): if space.sys.get_flag('bytes_warning'): - space.warn("str() on a bytes instance", space.w_BytesWarning) + space.warn(space.wrap("str() on a bytes instance"), + space.w_BytesWarning) return repr__String(space, w_str) def ord__String(space, w_str): From noreply at buildbot.pypy.org Tue Feb 19 23:50:18 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Tue, 19 Feb 2013 23:50:18 +0100 (CET) Subject: [pypy-commit] pypy py3k: add a dealloc warning to sockets Message-ID: <20130219225018.11C3A1C05FF@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61483:bcbd82aac4ba Date: 2013-02-19 14:49 -0800 http://bitbucket.org/pypy/pypy/changeset/bcbd82aac4ba/ Log: add a dealloc warning to sockets diff --git a/pypy/module/_socket/interp_socket.py b/pypy/module/_socket/interp_socket.py --- a/pypy/module/_socket/interp_socket.py +++ b/pypy/module/_socket/interp_socket.py @@ -136,6 +136,10 @@ class W_RSocket(Wrappable, RSocket): + + # for _dealloc_warn + space = None + def descr_new(space, w_subtype, __args__): sock = space.allocate_instance(W_RSocket, w_subtype) return space.wrap(sock) @@ -150,9 +154,23 @@ fd=space.c_filedescriptor_w(w_fileno)) else: W_RSocket.__init__(self, family, type, proto) + self.space = space except SocketError, e: raise converted_error(space, e) + def _dealloc_warn(self): + space = self.space + if not space: + return + try: + msg = (u"unclosed %s" % + space.unicode_w(space.repr(space.wrap(self)))) + space.warn(space.wrap(msg), space.w_ResourceWarning) + except OperationError as e: + # Spurious errors can appear at shutdown + if e.match(space, space.w_Warning): + e.write_unraisable(space, '', space.wrap(self)) + def _accept_w(self, space): """_accept() -> (socket object, address info) diff --git a/pypy/module/_socket/test/test_sock_app.py b/pypy/module/_socket/test/test_sock_app.py --- a/pypy/module/_socket/test/test_sock_app.py +++ b/pypy/module/_socket/test/test_sock_app.py @@ -554,6 +554,20 @@ socket.socket.__init__(self, family=socket.AF_INET6) assert Socket_IPV6().family == socket.AF_INET6 + def test_dealloc_warn(self): + import _socket + import gc + import warnings + + s = _socket.socket(_socket.AF_INET, _socket.SOCK_STREAM) + r = repr(s) + with warnings.catch_warnings(record=True) as w: + warnings.simplefilter('always') + s = None + gc.collect() + assert len(w) == 1 + assert r in str(w[0]) + class AppTestSocketTCP: def setup_class(cls): From noreply at buildbot.pypy.org Wed Feb 20 05:47:31 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Wed, 20 Feb 2013 05:47:31 +0100 (CET) Subject: [pypy-commit] pypy py3k: tighten getnameinfo to only accept IP addresses Message-ID: <20130220044731.E55981C05FF@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61484:afdc1895393f Date: 2013-02-19 20:39 -0800 http://bitbucket.org/pypy/pypy/changeset/afdc1895393f/ Log: tighten getnameinfo to only accept IP addresses diff --git a/pypy/module/_socket/interp_func.py b/pypy/module/_socket/interp_func.py --- a/pypy/module/_socket/interp_func.py +++ b/pypy/module/_socket/interp_func.py @@ -1,5 +1,6 @@ from pypy.interpreter.gateway import unwrap_spec, WrappedDefault -from pypy.module._socket.interp_socket import converted_error, W_RSocket, addr_as_object, ipaddr_from_object +from pypy.module._socket.interp_socket import ( + converted_error, W_RSocket, addr_as_object, ipaddr_from_object, get_error) from rpython.rlib import rsocket from rpython.rlib.rsocket import SocketError, INVALID_SOCKET from pypy.interpreter.error import OperationError @@ -120,7 +121,16 @@ Get host and port for a sockaddr.""" try: - addr = ipaddr_from_object(space, w_sockaddr) + w_host, w_port = space.fixedview(w_sockaddr, 2) + host = space.str_w(w_host) + port = str(space.int_w(w_port)) + lst = rsocket.getaddrinfo(host, port, rsocket.AF_UNSPEC, + rsocket.SOCK_DGRAM, 0, + rsocket.AI_NUMERICHOST) + if len(lst) > 1: + raise OperationError(get_error(space, 'error'), + "sockaddr resolved to multiple addresses") + addr = lst[0][4] host, servport = rsocket.getnameinfo(addr, flags) except SocketError, e: raise converted_error(space, e) diff --git a/pypy/module/_socket/test/test_sock_app.py b/pypy/module/_socket/test/test_sock_app.py --- a/pypy/module/_socket/test/test_sock_app.py +++ b/pypy/module/_socket/test/test_sock_app.py @@ -262,12 +262,18 @@ ]))) def test_getnameinfo(): + from pypy.module._socket.interp_socket import get_error host = "127.0.0.1" port = 25 info = socket.getnameinfo((host, port), 0) w_l = space.appexec([w_socket, space.wrap(host), space.wrap(port)], "(_socket, host, port): return _socket.getnameinfo((host, port), 0)") assert space.unwrap(w_l) == info + sockaddr = space.newtuple([space.wrap('mail.python.org'), space.wrap(0)]) + space.raises_w(get_error(space, 'error'), space.appexec, + [w_socket, sockaddr, space.wrap(0)], + "(_socket, sockaddr, flags): return _socket.getnameinfo(sockaddr, flags)") + def test_timeout(): space.appexec([w_socket, space.wrap(25.4)], From noreply at buildbot.pypy.org Wed Feb 20 07:58:20 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Wed, 20 Feb 2013 07:58:20 +0100 (CET) Subject: [pypy-commit] pypy py3k: kill tuple raising leftovers, cleanup docs Message-ID: <20130220065820.4F8381C12F5@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61485:1c71ee0c15d8 Date: 2013-02-19 22:57 -0800 http://bitbucket.org/pypy/pypy/changeset/1c71ee0c15d8/ Log: kill tuple raising leftovers, cleanup docs diff --git a/pypy/interpreter/error.py b/pypy/interpreter/error.py --- a/pypy/interpreter/error.py +++ b/pypy/interpreter/error.py @@ -164,26 +164,19 @@ # # In the following table, 'Class' means a subclass of BaseException # and 'inst' is an instance of either 'Class' or a subclass of it. - # Or 'Class' can also be an old-style class and 'inst' an old-style - # instance of it. # - # The flow object space only deals with non-advanced case. Old-style - # classes and instances *are* advanced. + # The flow object space only deals with non-advanced case. # # input (w_type, w_value)... becomes... advanced case? # --------------------------------------------------------------------- - # (tuple, w_value) (tuple[0], w_value) yes # (Class, None) (Class, Class()) no # (Class, inst) (inst.__class__, inst) no # (Class, tuple) (Class, Class(*tuple)) yes # (Class, x) (Class, Class(x)) no - # ("string", ...) ("string", ...) deprecated # (inst, None) (inst.__class__, inst) no # w_type = self.w_type w_value = self.get_w_value(space) - while space.is_true(space.isinstance(w_type, space.w_tuple)): - w_type = space.getitem(w_type, space.wrap(0)) if space.exception_is_valid_obj_as_class_w(w_type): # this is for all cases of the form (Class, something) diff --git a/pypy/interpreter/pyopcode.py b/pypy/interpreter/pyopcode.py --- a/pypy/interpreter/pyopcode.py +++ b/pypy/interpreter/pyopcode.py @@ -1161,7 +1161,7 @@ """Raised when exiting a frame via a 'yield' statement.""" class RaiseWithExplicitTraceback(Exception): - """Raised at interp-level by a 0- or 3-arguments 'raise' statement.""" + """Raised at interp-level by a 0-argument 'raise' statement.""" def __init__(self, operr): self.operr = operr From noreply at buildbot.pypy.org Wed Feb 20 09:22:47 2013 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 20 Feb 2013 09:22:47 +0100 (CET) Subject: [pypy-commit] pypy stm-thread-2: Argh, forgot that count_reads can be much bigger than the limit if the Message-ID: <20130220082247.9B6001C0884@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stm-thread-2 Changeset: r61486:372747b348cd Date: 2013-02-20 09:22 +0100 http://bitbucket.org/pypy/pypy/changeset/372747b348cd/ Log: Argh, forgot that count_reads can be much bigger than the limit if the transaction is atomic. diff --git a/rpython/translator/stm/src_stm/et.c b/rpython/translator/stm/src_stm/et.c --- a/rpython/translator/stm/src_stm/et.c +++ b/rpython/translator/stm/src_stm/et.c @@ -391,8 +391,12 @@ /* upon abort, set the reads size limit to 94% of how much was read so far. This should ensure that, assuming the retry does the same - thing, it will commit just before it reaches the conflicting point. */ + thing, it will commit just before it reaches the conflicting point. + Note that we should never *increase* the read length limit here. */ limit = d->count_reads; + if (limit > d->reads_size_limit_nonatomic) { /* can occur if atomic */ + limit = d->reads_size_limit_nonatomic; + } if (limit > 0) { limit -= (limit >> 4); d->reads_size_limit_nonatomic = limit; From noreply at buildbot.pypy.org Wed Feb 20 09:22:48 2013 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 20 Feb 2013 09:22:48 +0100 (CET) Subject: [pypy-commit] pypy stm-thread-2: Oups. Message-ID: <20130220082248.BB27F1C0884@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stm-thread-2 Changeset: r61487:434440c32cf4 Date: 2013-02-20 09:22 +0100 http://bitbucket.org/pypy/pypy/changeset/434440c32cf4/ Log: Oups. diff --git a/rpython/rtyper/memory/gc/stmtls.py b/rpython/rtyper/memory/gc/stmtls.py --- a/rpython/rtyper/memory/gc/stmtls.py +++ b/rpython/rtyper/memory/gc/stmtls.py @@ -365,7 +365,7 @@ while i > 0: i -= 1 root = llop.stm_threadlocalref_lladdr(llmemory.Address, i) - if self.points_to_valid_gc_object(root): + if self.gc.points_to_valid_gc_object(root): self._trace_drag_out(root, None) def trace_and_drag_out_of_nursery(self, obj): From noreply at buildbot.pypy.org Wed Feb 20 10:43:38 2013 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 20 Feb 2013 10:43:38 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: fix, thanks armin Message-ID: <20130220094338.E1D9E1C0041@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61488:cfe720378860 Date: 2013-02-20 11:42 +0200 http://bitbucket.org/pypy/pypy/changeset/cfe720378860/ Log: fix, thanks armin diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -338,8 +338,8 @@ else: mc.MOV_rr(edi.value, ebp.value) exc0, exc1 = ebx, r12 - mc.MOV(RawStackLoc(WORD * 5), exc0) - mc.MOV(RawStackLoc(WORD * 6), exc1) + mc.MOV(RawEspLoc(WORD * 5), exc0) + mc.MOV(RawEspLoc(WORD * 6), exc1) # note that it's save to store the exception in register, # since the call to write barrier can't collect # (and this is assumed a bit left and right here, like lack @@ -372,8 +372,8 @@ mc.MOVSD_xs(xmm0.value, 3 * WORD) mc.MOV_rs(eax.value, WORD) # restore self._restore_exception(mc, exc0, exc1) - mc.MOV(exc0, RawStackLoc(WORD * 5)) - mc.MOV(exc1, RawStackLoc(WORD * 6)) + mc.MOV(exc0, RawEspLoc(WORD * 5)) + mc.MOV(exc1, RawEspLoc(WORD * 6)) mc.LEA_rs(esp.value, 10 * WORD) mc.RET() From noreply at buildbot.pypy.org Wed Feb 20 10:44:20 2013 From: noreply at buildbot.pypy.org (lwassermann) Date: Wed, 20 Feb 2013 10:44:20 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: renamed the new primitives to their interpreterVM equivalents Message-ID: <20130220094420.49C911C0041@cobra.cs.uni-duesseldorf.de> Author: Lars Wassermann Branch: Changeset: r64:ce77fd4f5f06 Date: 2013-02-20 10:40 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/ce77fd4f5f06/ Log: renamed the new primitives to their interpreterVM equivalents diff --git a/spyvm/interpreter.py b/spyvm/interpreter.py --- a/spyvm/interpreter.py +++ b/spyvm/interpreter.py @@ -370,7 +370,7 @@ self.pop() # closure bytecodes - def pushNewArrayPopIntoArray(self, interp): + def pushNewArrayBytecode(self, interp): arraySize, popIntoArray = splitter[7, 1](self.getbytecode()) newArray = None if popIntoArray == 1: @@ -388,19 +388,19 @@ w_indirectTemps = self.gettemp(index_of_array) return index_in_array, w_indirectTemps - def pushTempAtInTempVectorAt(self, interp): + def pushRemoteTempLongBytecode(self, interp): index_in_array, w_indirectTemps = self._extract_index_and_temps() self.push(w_indirectTemps.at0(self.space, index_in_array)) - def storeTempAtInTempVectorAt(self, interp): + def storeRemoteTempLongBytecode(self, interp): index_in_array, w_indirectTemps = self._extract_index_and_temps() w_indirectTemps.atput0(self.space, index_in_array, self.top()) - def popAndStoreTempAtInTempVectorAt(self, interp): + def storeAndPopRemoteTempLongBytecode(self, interp): index_in_array, w_indirectTemps = self._extract_index_and_temps() w_indirectTemps.atput0(self.space, index_in_array, self.pop()) - def pushClosureNumCopiedNumArgsBlockSize(self, interp): + def pushClosureCopyCopiedValuesBytecode(self, interp): """ Copied from Blogpost: http://www.mirandabanda.org/cogblog/2008/07/22/closures-part-ii-the-bytecodes/ ContextPart>>pushClosureCopyNumCopiedValues: numCopied numArgs: numArgs blockSize: blockSize "Simulate the action of a 'closure copy' bytecode whose result is the @@ -572,12 +572,12 @@ (135, "popStackBytecode"), (136, "duplicateTopBytecode"), (137, "pushActiveContextBytecode"), - (138, "pushNewArrayPopIntoArray"), + (138, "pushNewArrayBytecode"), (139, "experimentalBytecode"), - (140, "pushTempAtInTempVectorAt"), - (141, "storeTempAtInTempVectorAt"), - (142, "popAndStoreTempAtInTempVectorAt"), - (143, "pushClosureNumCopiedNumArgsBlockSize"), + (140, "pushRemoteTempLongBytecode"), + (141, "storeRemoteTempLongBytecode"), + (142, "storeAndPopRemoteTempLongBytecode"), + (143, "pushClosureCopyCopiedValuesBytecode"), (144, 151, "shortUnconditionalJump"), (152, 159, "shortConditionalJump"), (160, 167, "longUnconditionalJump"), diff --git a/spyvm/test/test_interpreter.py b/spyvm/test/test_interpreter.py --- a/spyvm/test/test_interpreter.py +++ b/spyvm/test/test_interpreter.py @@ -831,7 +831,7 @@ option.bc_trace = bc_trace # Closure Bytecodes -def test_bc_pushNewArrayPopIntoArray(bytecode=pushNewArrayPopIntoArray): +def test_bc_pushNewArrayBytecode(bytecode=pushNewArrayBytecode): interp = new_interpreter(bytecode + chr(0x83)) context = interp.s_active_context() context.push(fakeliterals(space, "egg")) @@ -843,7 +843,7 @@ assert array.at0(space, 1) == fakeliterals(space, "bar") assert array.at0(space, 2) == fakeliterals(space, "baz") -def test_bc_pushNewArray(bytecode=pushNewArrayPopIntoArray): +def test_bc_pushNewArray(bytecode=pushNewArrayBytecode): interp = new_interpreter(bytecode + chr(0x07)) context = interp.s_active_context() interp.step(interp.s_active_context()) @@ -851,7 +851,7 @@ assert array.size() == 7 assert array.at0(space, 0) == space.w_nil -def test_pushTempAt0InTempVectorAt0(bytecode = pushTempAtInTempVectorAt): +def test_bc_pushRemoteTempLongBytecode(bytecode = pushRemoteTempLongBytecode): interp = new_interpreter(bytecode + chr(0) + chr(0)) context = interp.s_active_context() context.push(fakeliterals(space, "jam")) @@ -871,21 +871,21 @@ interp.step(context) return context, temp_array -def test_pushTempAt3InTempVectorAt1(bytecode = pushTempAtInTempVectorAt): +def test_bc_pushRemoteTempLongBytecode2(bytecode = pushRemoteTempLongBytecode): context, _ = setupTempArrayAndContext(bytecode) assert context.top() == fakeliterals(space, "pub") -def test_storeTempAtInTempVectorAt(bytecode = storeTempAtInTempVectorAt): +def test_bc_storeRemoteTempLongBytecode(bytecode = storeRemoteTempLongBytecode): context, temp_array = setupTempArrayAndContext(bytecode) assert context.top() == fakeliterals(space, "bar") assert temp_array.at0(space, 2) == fakeliterals(space, "bar") -def test_popAndStoreTempAtInTempVectorAt(bytecode = popAndStoreTempAtInTempVectorAt): +def test_bc_storeAndPopRemoteTempLongBytecode(bytecode = storeAndPopRemoteTempLongBytecode): context, temp_array = setupTempArrayAndContext(bytecode) assert temp_array.at0(space, 2) == fakeliterals(space, "bar") assert context.top() == fakeliterals(space, "english") -def test_pushClosureNumCopied0NumArgsBlockSize(bytecode = pushClosureNumCopiedNumArgsBlockSize): +def test_bc_pushClosureCopyCopied0ValuesBytecode(bytecode = pushClosureCopyCopiedValuesBytecode): for i in (0, 0xF0, 0x0FF0, 0xFFF0): interp = new_interpreter(bytecode + chr(2) + chr(i >> 8) + chr(i & 0xFF)) context = interp.s_active_context() @@ -897,7 +897,7 @@ assert closure.startpc() == pc + 4 assert closure.outerContext() is context._w_self -def test_pushClosureNumCopied2NumArgsBlockSize(bytecode = pushClosureNumCopiedNumArgsBlockSize): +def test_bc_pushClosureCopyCopied2ValuesBytecode(bytecode = pushClosureCopyCopiedValuesBytecode): interp = new_interpreter(bytecode + chr(0x23) + chr(0) + chr(0)) context = interp.s_active_context() context.push("english") diff --git a/spyvm/todo.txt b/spyvm/todo.txt --- a/spyvm/todo.txt +++ b/spyvm/todo.txt @@ -22,5 +22,3 @@ Shadows: [ ] Fix invalidation of methoddictshadow when the w_self of its values array changes -Lars ToDo -[ ] different image with BlockClosure instead of BlockContext From noreply at buildbot.pypy.org Wed Feb 20 10:51:34 2013 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 20 Feb 2013 10:51:34 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: rename confusing locs Message-ID: <20130220095134.5A2771C0041@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61489:9ce793904fa2 Date: 2013-02-20 11:50 +0200 http://bitbucket.org/pypy/pypy/changeset/9ce793904fa2/ Log: rename confusing locs diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -19,8 +19,8 @@ from rpython.jit.backend.x86.regloc import (eax, ecx, edx, ebx, esp, ebp, esi, xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, r8, r9, r10, r11, edi, r12, r13, r14, r15, X86_64_SCRATCH_REG, X86_64_XMM_SCRATCH_REG, - RegLoc, StackLoc, ConstFloatLoc, ImmedLoc, AddressLoc, imm, - imm0, imm1, FloatImmedLoc, RawStackLoc, RawEspLoc) + RegLoc, FrameLoc, ConstFloatLoc, ImmedLoc, AddressLoc, imm, + imm0, imm1, FloatImmedLoc, RawEbpLoc, RawEspLoc) from rpython.rlib.objectmodel import we_are_translated, specialize from rpython.jit.backend.x86 import rx86, codebuf from rpython.jit.metainterp.resoperation import rop, ResOperation @@ -884,7 +884,7 @@ if isinstance(loc, RegLoc) and loc.is_xmm: self.mc.SUB_ri(esp.value, 8) # = size of doubles self.mc.MOVSD_sx(0, loc.value) - elif WORD == 4 and isinstance(loc, StackLoc) and loc.get_width() == 8: + elif WORD == 4 and isinstance(loc, FrameLoc) and loc.get_width() == 8: # XXX evil trick self.mc.PUSH_b(loc.value + 4) self.mc.PUSH_b(loc.value) @@ -895,7 +895,7 @@ if isinstance(loc, RegLoc) and loc.is_xmm: self.mc.MOVSD_xs(loc.value, 0) self.mc.ADD_ri(esp.value, 8) # = size of doubles - elif WORD == 4 and isinstance(loc, StackLoc) and loc.get_width() == 8: + elif WORD == 4 and isinstance(loc, FrameLoc) and loc.get_width() == 8: # XXX evil trick self.mc.POP_b(loc.value) self.mc.POP_b(loc.value + 4) @@ -903,14 +903,14 @@ self.mc.POP(loc) def regalloc_immedmem2mem(self, from_loc, to_loc): - # move a ConstFloatLoc directly to a StackLoc, as two MOVs + # move a ConstFloatLoc directly to a FrameLoc, as two MOVs # (even on x86-64, because the immediates are encoded as 32 bits) assert isinstance(from_loc, ConstFloatLoc) low_part = rffi.cast(rffi.CArrayPtr(rffi.INT), from_loc.value)[0] high_part = rffi.cast(rffi.CArrayPtr(rffi.INT), from_loc.value)[1] low_part = intmask(low_part) high_part = intmask(high_part) - if isinstance(to_loc, RawStackLoc): + if isinstance(to_loc, RawEbpLoc): self.mc.MOV32_bi(to_loc.value, low_part) self.mc.MOV32_bi(to_loc.value + 4, high_part) else: @@ -1196,7 +1196,7 @@ for src, dst in singlefloats: if isinstance(dst, RawEspLoc): # XXX too much special logic - if isinstance(src, RawStackLoc): + if isinstance(src, RawEbpLoc): self.mc.MOV32(X86_64_SCRATCH_REG, src) self.mc.MOV32(dst, X86_64_SCRATCH_REG) else: @@ -1426,7 +1426,7 @@ assert isinstance(resloc, RegLoc) if isinstance(loc, RegLoc): self.mc.MOVD_rx(resloc.value, loc.value) - elif isinstance(loc, StackLoc): + elif isinstance(loc, FrameLoc): self.mc.MOV_rb(resloc.value, loc.value) else: not_implemented("llong_to_int: %s" % (loc,)) @@ -1739,7 +1739,7 @@ elif tmploc is not None: # if both are None, just ignore ofs = self.cpu.get_ofs_of_frame_field('jf_guard_exc') mc.MOV(tmploc, heap(self.cpu.pos_exc_value())) - mc.MOV(RawStackLoc(ofs), tmploc) + mc.MOV(RawEbpLoc(ofs), tmploc) if exctploc is not None: assert exctploc.is_reg() mc.MOV(exctploc, heap(self.cpu.pos_exception())) @@ -1753,7 +1753,7 @@ else: assert tmploc is not None ofs = self.cpu.get_ofs_of_frame_field('jf_guard_exc') - mc.MOV(tmploc, RawStackLoc(ofs)) + mc.MOV(tmploc, RawEbpLoc(ofs)) mc.MOV_bi(ofs, 0) mc.MOV(heap(self.cpu.pos_exc_value()), tmploc) mc.MOV(heap(self.cpu.pos_exception()), exctploc) @@ -1890,7 +1890,7 @@ def new_stack_loc(self, i, pos, tp): base_ofs = self.cpu.get_baseofs_of_frame_field() - return StackLoc(i, get_ebp_ofs(base_ofs, i), tp) + return FrameLoc(i, get_ebp_ofs(base_ofs, i), tp) def setup_failure_recovery(self): self.failure_recovery_code = [0, 0, 0, 0] @@ -1983,7 +1983,7 @@ else: [fail_descr_loc] = arglocs ofs = self.cpu.get_ofs_of_frame_field('jf_descr') - self.mov(fail_descr_loc, RawStackLoc(ofs)) + self.mov(fail_descr_loc, RawEbpLoc(ofs)) arglist = op.getarglist() if arglist and arglist[0].type == REF: gcmap = self.gcmap_for_finish @@ -2027,7 +2027,7 @@ argtypes=descr.get_arg_types(), callconv=descr.get_call_conv()) - if IS_X86_32 and isinstance(resloc, StackLoc) and resloc.type == FLOAT: + if IS_X86_32 and isinstance(resloc, FrameLoc) and resloc.type == FLOAT: # a float or a long long return if descr.get_result_type() == 'L': self.mc.MOV_br(resloc.value, eax.value) # long long @@ -2227,7 +2227,8 @@ return self.mc.get_relative_pos() def _call_assembler_patch_je(self, result_loc, je_location): - if IS_X86_32 and isinstance(result_loc, StackLoc) and result_loc.type == FLOAT: + if (IS_X86_32 and isinstance(result_loc, FrameLoc) and + result_loc.type == FLOAT): self.mc.FSTPL_b(result_loc.value) self.mc.JMP_l8(0) # jump to done, patched later jmp_location = self.mc.get_relative_pos() @@ -2498,7 +2499,7 @@ return AddressLoc(loc, imm0, 0, offset) def raw_stack(offset, type=INT): - return RawStackLoc(offset, type) + return RawEbpLoc(offset, type) def heap(addr): return AddressLoc(ImmedLoc(addr), imm0, 0, 0) diff --git a/rpython/jit/backend/x86/jump.py b/rpython/jit/backend/x86/jump.py --- a/rpython/jit/backend/x86/jump.py +++ b/rpython/jit/backend/x86/jump.py @@ -1,7 +1,5 @@ -import sys -from rpython.tool.pairtype import extendabletype + from rpython.jit.backend.x86.regloc import ImmediateAssemblerLocation -from rpython.jit.backend.x86.regloc import RegLoc, StackLoc def remap_frame_layout(assembler, src_locations, dst_locations, tmpreg): pending_dests = len(dst_locations) diff --git a/rpython/jit/backend/x86/regalloc.py b/rpython/jit/backend/x86/regalloc.py --- a/rpython/jit/backend/x86/regalloc.py +++ b/rpython/jit/backend/x86/regalloc.py @@ -106,7 +106,7 @@ self.base_ofs = base_ofs def frame_pos(self, i, box_type): - return StackLoc(i, get_ebp_ofs(self.base_ofs, i), box_type) + return FrameLoc(i, get_ebp_ofs(self.base_ofs, i), box_type) @staticmethod def frame_size(box_type): @@ -117,7 +117,7 @@ @staticmethod def get_loc_index(loc): - assert isinstance(loc, StackLoc) + assert isinstance(loc, FrameLoc) return loc.position if WORD == 4: @@ -872,7 +872,7 @@ gcmap[val // WORD // 8] |= r_uint(1) << (val % (WORD * 8)) for box, loc in self.fm.bindings.iteritems(): if box.type == REF: - assert isinstance(loc, StackLoc) + assert isinstance(loc, FrameLoc) val = loc.position + JITFRAME_FIXED_SIZE gcmap[val // WORD // 8] |= r_uint(1) << (val % (WORD * 8)) for i in range(len(gcmap)): @@ -1195,7 +1195,7 @@ box = jump_op.getarg(i) if isinstance(box, Box): loc = arglocs[i] - if isinstance(loc, StackLoc): + if isinstance(loc, FrameLoc): self.fm.hint_frame_locations[box] = loc def consider_jump(self, op): diff --git a/rpython/jit/backend/x86/regloc.py b/rpython/jit/backend/x86/regloc.py --- a/rpython/jit/backend/x86/regloc.py +++ b/rpython/jit/backend/x86/regloc.py @@ -11,7 +11,7 @@ # # This module adds support for "locations", which can be either in a Const, -# or a RegLoc or a StackLoc. It also adds operations like mc.ADD(), which +# or a RegLoc or a FrameLoc. It also adds operations like mc.ADD(), which # take two locations as arguments, decode them, and calls the right # mc.ADD_rr()/ADD_rb()/ADD_ri(). # @@ -51,7 +51,7 @@ def get_position(self): raise NotImplementedError # only for stack -class RawStackLoc(AssemblerLocation): +class RawEbpLoc(AssemblerLocation): """ The same as stack location, but does not know it's position. Mostly usable for raw frame access """ @@ -77,7 +77,7 @@ return self.type == FLOAT def add_offset(self, ofs): - return RawStackLoc(self.value + ofs) + return RawEbpLoc(self.value + ofs) def is_stack(self): return True @@ -110,7 +110,7 @@ def is_float(self): return self.type == FLOAT -class StackLoc(RawStackLoc): +class FrameLoc(RawEbpLoc): _immutable_ = True def __init__(self, position, ebp_offset, type): diff --git a/rpython/jit/backend/x86/test/test_jump.py b/rpython/jit/backend/x86/test/test_jump.py --- a/rpython/jit/backend/x86/test/test_jump.py +++ b/rpython/jit/backend/x86/test/test_jump.py @@ -23,7 +23,7 @@ def regalloc_immedmem2mem(self, from_loc, to_loc): assert isinstance(from_loc, ConstFloatLoc) - assert isinstance(to_loc, StackLoc) + assert isinstance(to_loc, FrameLoc) self.ops.append(('immedmem2mem', from_loc, to_loc)) def got(self, expected): @@ -34,7 +34,7 @@ continue assert len(op1) == len(op2) for x, y in zip(op1, op2): - if isinstance(x, StackLoc) and isinstance(y, MODRM): + if isinstance(x, FrameLoc) and isinstance(y, MODRM): assert x.byte == y.byte assert x.extradata == y.extradata else: @@ -262,7 +262,7 @@ while len(result) < count: x = fn() keys = [x._getregkey()] - if isinstance(x, StackLoc) and x.get_width() > WORD: + if isinstance(x, FrameLoc) and x.get_width() > WORD: keys.append(keys[0] + WORD) for key in keys: if key in seen: @@ -288,7 +288,7 @@ regs2[loc.value] = newvalue else: regs1[loc.value] = 'value-int-%d' % i - elif isinstance(loc, StackLoc): + elif isinstance(loc, FrameLoc): stack[loc.value] = 'value-width%d-%d' % (loc.get_width(), i) if loc.get_width() > WORD: stack[loc.value+WORD] = 'value-hiword-%d' % i @@ -318,7 +318,7 @@ return regs2[loc.value] else: return regs1[loc.value] - if isinstance(loc, StackLoc): + if isinstance(loc, FrameLoc): got = stack[loc.value] if loc.get_width() > WORD: got = (got, stack[loc.value+WORD]) @@ -339,7 +339,7 @@ regs2[loc.value] = newvalue else: regs1[loc.value] = newvalue - elif isinstance(loc, StackLoc): + elif isinstance(loc, FrameLoc): if loc.get_width() > WORD: newval1, newval2 = newvalue stack[loc.value] = newval1 @@ -360,23 +360,23 @@ assert isinstance(dst, RegLoc) assert dst.is_xmm else: - assert isinstance(src, (RegLoc, StackLoc, ImmedLoc)) - assert isinstance(dst, (RegLoc, StackLoc)) - assert not (isinstance(src, StackLoc) and - isinstance(dst, StackLoc)) + assert isinstance(src, (RegLoc, FrameLoc, ImmedLoc)) + assert isinstance(dst, (RegLoc, FrameLoc)) + assert not (isinstance(src, FrameLoc) and + isinstance(dst, FrameLoc)) write(dst, read(src)) elif op[0] == 'push': src, = op[1:] - assert isinstance(src, (RegLoc, StackLoc)) + assert isinstance(src, (RegLoc, FrameLoc)) extrapushes.append(read(src)) elif op[0] == 'pop': dst, = op[1:] - assert isinstance(dst, (RegLoc, StackLoc)) + assert isinstance(dst, (RegLoc, FrameLoc)) write(dst, extrapushes.pop()) elif op[0] == 'immedmem2mem': src, dst = op[1:] assert isinstance(src, ConstFloatLoc) - assert isinstance(dst, StackLoc) + assert isinstance(dst, FrameLoc) write(dst, read(src, 8)) else: assert 0, "unknown op: %r" % (op,) @@ -406,8 +406,8 @@ def regalloc_immedmem2mem(self, x, y): print "?????????????????????????" def main(): - srclocs = [StackLoc(9999, x, 'i') for x,y in CASE] - dstlocs = [StackLoc(9999, y, 'i') for x,y in CASE] + srclocs = [FrameLoc(9999, x, 'i') for x,y in CASE] + dstlocs = [FrameLoc(9999, y, 'i') for x,y in CASE] remap_frame_layout(FakeAssembler(), srclocs, dstlocs, eax) # it works when run directly main() From noreply at buildbot.pypy.org Wed Feb 20 10:52:15 2013 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 20 Feb 2013 10:52:15 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: add types Message-ID: <20130220095215.367EC1C0041@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61490:13c993c618c1 Date: 2013-02-20 11:51 +0200 http://bitbucket.org/pypy/pypy/changeset/13c993c618c1/ Log: add types diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -338,8 +338,8 @@ else: mc.MOV_rr(edi.value, ebp.value) exc0, exc1 = ebx, r12 - mc.MOV(RawEspLoc(WORD * 5), exc0) - mc.MOV(RawEspLoc(WORD * 6), exc1) + mc.MOV(RawEspLoc(WORD * 5, REF), exc0) + mc.MOV(RawEspLoc(WORD * 6, INT), exc1) # note that it's save to store the exception in register, # since the call to write barrier can't collect # (and this is assumed a bit left and right here, like lack @@ -372,8 +372,8 @@ mc.MOVSD_xs(xmm0.value, 3 * WORD) mc.MOV_rs(eax.value, WORD) # restore self._restore_exception(mc, exc0, exc1) - mc.MOV(exc0, RawEspLoc(WORD * 5)) - mc.MOV(exc1, RawEspLoc(WORD * 6)) + mc.MOV(exc0, RawEspLoc(WORD * 5, REF)) + mc.MOV(exc1, RawEspLoc(WORD * 6, INT)) mc.LEA_rs(esp.value, 10 * WORD) mc.RET() From noreply at buildbot.pypy.org Wed Feb 20 10:54:44 2013 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 20 Feb 2013 10:54:44 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: missed one Message-ID: <20130220095444.BEE581C0041@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61491:da724c1d1a50 Date: 2013-02-20 11:53 +0200 http://bitbucket.org/pypy/pypy/changeset/da724c1d1a50/ Log: missed one diff --git a/rpython/jit/backend/x86/jump.py b/rpython/jit/backend/x86/jump.py --- a/rpython/jit/backend/x86/jump.py +++ b/rpython/jit/backend/x86/jump.py @@ -1,5 +1,6 @@ -from rpython.jit.backend.x86.regloc import ImmediateAssemblerLocation +from rpython.jit.backend.x86.regloc import ImmediateAssemblerLocation,\ + FrameLoc def remap_frame_layout(assembler, src_locations, dst_locations, tmpreg): pending_dests = len(dst_locations) @@ -94,7 +95,7 @@ for i in range(len(src_locations2)): loc = src_locations2[i] dstloc = dst_locations2[i] - if isinstance(loc, StackLoc): + if isinstance(loc, FrameLoc): key = loc._getregkey() if (key in dst_keys or (loc.get_width() > WORD and (key + WORD) in dst_keys)): From noreply at buildbot.pypy.org Wed Feb 20 12:03:34 2013 From: noreply at buildbot.pypy.org (lwassermann) Date: Wed, 20 Feb 2013 12:03:34 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: refactored pushClosureCopyCopiedValuesBytecode via MethodExtract for the primitive closureCopyWithCopiedValues(200) Message-ID: <20130220110334.57BFB1C137F@cobra.cs.uni-duesseldorf.de> Author: Lars Wassermann Branch: Changeset: r65:ab075701b725 Date: 2013-02-20 12:00 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/ab075701b725/ Log: refactored pushClosureCopyCopiedValuesBytecode via MethodExtract for the primitive closureCopyWithCopiedValues(200) diff --git a/spyvm/interpreter.py b/spyvm/interpreter.py --- a/spyvm/interpreter.py +++ b/spyvm/interpreter.py @@ -400,6 +400,15 @@ index_in_array, w_indirectTemps = self._extract_index_and_temps() w_indirectTemps.atput0(self.space, index_in_array, self.pop()) + def _newClosure(self, numArgs, pc, numCopied): + BlockClosureShadow = self.space.w_BlockClosure.as_class_get_shadow(self.space) + w_closure = BlockClosureShadow.new(numCopied) + closure = wrapper.BlockClosureWrapper(self.space, w_closure) + closure.store_outerContext(self._w_self) + closure.store_startpc(pc) + closure.store_numArgs(numArgs) + return closure, w_closure + def pushClosureCopyCopiedValuesBytecode(self, interp): """ Copied from Blogpost: http://www.mirandabanda.org/cogblog/2008/07/22/closures-part-ii-the-bytecodes/ ContextPart>>pushClosureCopyNumCopiedValues: numCopied numArgs: numArgs blockSize: blockSize @@ -427,12 +436,7 @@ i = self.getbytecode() blockSize = (j << 8) | i #create new instance of BlockClosure - BlockClosureShadow = space.w_BlockClosure.as_class_get_shadow(space) - w_closure = BlockClosureShadow.new(numCopied) - closure = wrapper.BlockClosureWrapper(space, w_closure) - closure.store_outerContext(self._w_self) - closure.store_startpc(self.pc()) - closure.store_numArgs(numArgs) + closure, w_closure = self._newClosure(numArgs, self.pc(), numCopied) if numCopied > 0: copiedValues = self.pop_and_return_n(numCopied) for i0 in range(numCopied): From noreply at buildbot.pypy.org Wed Feb 20 12:03:35 2013 From: noreply at buildbot.pypy.org (lwassermann) Date: Wed, 20 Feb 2013 12:03:35 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: added new closure primitive numbers, added new unwrap spec list Message-ID: <20130220110335.7DDFA1C1382@cobra.cs.uni-duesseldorf.de> Author: Lars Wassermann Branch: Changeset: r66:0aa0ef3aab2d Date: 2013-02-20 12:03 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/0aa0ef3aab2d/ Log: added new closure primitive numbers, added new unwrap spec list diff --git a/spyvm/objspace.py b/spyvm/objspace.py --- a/spyvm/objspace.py +++ b/spyvm/objspace.py @@ -254,6 +254,14 @@ elif isinstance(w_v, model.W_SmallInteger): return float(w_v.value) raise UnwrappingError() + def unwrap_array(self, w_array): + # Check that our argument has pointers format and the class: + if not w_array.getclass(self).is_same_object(self.w_Array): + raise PrimitiveFailedError() + assert isinstance(w_array, model.W_PointersObject) + + return [w_array.at0(self, i) for i in range(w_array.size())] + def _freeze_(self): return True diff --git a/spyvm/primitives.py b/spyvm/primitives.py --- a/spyvm/primitives.py +++ b/spyvm/primitives.py @@ -97,6 +97,9 @@ elif spec is str: assert isinstance(w_arg, model.W_BytesObject) args += (w_arg.as_string(), ) + elif spec is list: + assert isinstance(w_arg, model.W_PointersObject) + args += (interp.space.unwrap_array(w_arg), ) elif spec is char: args += (unwrap_char(w_arg), ) else: @@ -829,25 +832,20 @@ frame.pop() finalize_block_ctx(interp, s_block_ctx, frame.w_self()) - at expose_primitive(VALUE_WITH_ARGS, unwrap_spec=[object, object], + at expose_primitive(VALUE_WITH_ARGS, unwrap_spec=[object, list], no_result=True) -def func(interp, w_block_ctx, w_args): +def func(interp, w_block_ctx, l_args): assert isinstance(w_block_ctx, model.W_PointersObject) s_block_ctx = w_block_ctx.as_blockcontext_get_shadow(interp.space) exp_arg_cnt = s_block_ctx.expected_argument_count() - # Check that our arguments have pointers format and the right size: - if not w_args.getclass(interp.space).is_same_object( - interp.space.w_Array): - raise PrimitiveFailedError() - if w_args.size() != exp_arg_cnt: + if len(l_args) != exp_arg_cnt: raise PrimitiveFailedError() - assert isinstance(w_args, model.W_PointersObject) # Push all the items from the array for i in range(exp_arg_cnt): - s_block_ctx.push(w_args.at0(interp.space, i)) + s_block_ctx.push(l_args[i]) # XXX Check original logic. Image does not test this anyway # because falls back to value + internal implementation @@ -913,6 +911,21 @@ return w_rcvr # ___________________________________________________________________________ +# BlockClosure Primitives + +CLOSURE_COPY_WITH_COPIED_VALUES = 200 +CLOSURE_VALUE = 201 +CLOSURE_VALUE_ = 202 +CLOSURE_VALUE_VALUE = 203 +CLOSURE_VALUE_VALUE_VALUE = 204 +CLOSURE_VALUE_VALUE_VALUE_VALUE = 205 +CLOSURE_VALUE_WITH_ARGS = 206 #valueWithArguments: + + at expose_primitive(CLOSURE_VALUE_WITH_ARGS, unwrap_spec=[object, list]) +def func(interp, w_block_closure, l_args): + pass + +# ___________________________________________________________________________ # PrimitiveLoadInstVar # # These are some wacky bytecodes in squeak. They are defined to do From noreply at buildbot.pypy.org Wed Feb 20 12:05:24 2013 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 20 Feb 2013 12:05:24 +0100 (CET) Subject: [pypy-commit] pypy stm-thread-2: Tweak thread-locals to change the approach, at least with STM: Message-ID: <20130220110524.93DED1C137F@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stm-thread-2 Changeset: r61492:7239bb513111 Date: 2013-02-20 11:24 +0100 http://bitbucket.org/pypy/pypy/changeset/7239bb513111/ Log: Tweak thread-locals to change the approach, at least with STM: store the dict inside a weak-key-dictionary on the executioncontext. diff --git a/pypy/interpreter/executioncontext.py b/pypy/interpreter/executioncontext.py --- a/pypy/interpreter/executioncontext.py +++ b/pypy/interpreter/executioncontext.py @@ -37,10 +37,9 @@ self.profilefunc = None # if not None, no JIT self.w_profilefuncarg = None # - config = self.space.config - if config.translation.stm and config.objspace.std.withmethodcache: - from pypy.objspace.std.typeobject import MethodCache - self._methodcache = MethodCache(self.space) + if self.space.config.translation.stm: + from pypy.module.thread.stm import initialize_execution_context + initialize_execution_context(self) def gettopframe(self): return self.topframeref() diff --git a/pypy/module/thread/__init__.py b/pypy/module/thread/__init__.py --- a/pypy/module/thread/__init__.py +++ b/pypy/module/thread/__init__.py @@ -18,7 +18,6 @@ 'allocate_lock': 'os_lock.allocate_lock', 'allocate': 'os_lock.allocate_lock', # obsolete synonym 'LockType': 'os_lock.Lock', - '_local': 'os_local.Local', 'error': 'space.fromcache(error.Cache).w_error', } @@ -38,3 +37,12 @@ from pypy.module.posix.interp_posix import add_fork_hook from pypy.module.thread.os_thread import reinit_threads add_fork_hook('child', reinit_threads) + + def setup_after_space_initialization(self): + "NOT_RPYTHON" + if self.space.config.translation.stm: + self.extra_interpdef('_local', 'stm.STMLocal') + else: + self.extra_interpdef('_local', 'os_local.Local') + if not self.space.config.translating: + self.extra_interpdef('_untranslated_stmlocal', 'stm.STMLocal') diff --git a/pypy/module/thread/os_local.py b/pypy/module/thread/os_local.py --- a/pypy/module/thread/os_local.py +++ b/pypy/module/thread/os_local.py @@ -32,13 +32,11 @@ self.dicts[ec] = w_dict self._register_in_ec(ec) # cache the last seen dict, works because we are protected by the GIL - if self.can_cache(): - self.last_dict = w_dict - self.last_ec = ec - - def can_cache(self): - # can't cache with STM! The cache causes conflicts - return not self.space.config.translation.stm + self.last_dict = w_dict + self.last_ec = ec + # note that this class can't be used with STM! + # The cache causes conflicts. See STMLocal instead. + assert not self.space.config.translation.stm def _register_in_ec(self, ec): if not self.space.config.translation.rweakref: @@ -69,15 +67,14 @@ def getdict(self, space): ec = space.getexecutioncontext() - if self.can_cache() and ec is self.last_ec: + if ec is self.last_ec: return self.last_dict try: w_dict = self.dicts[ec] except KeyError: w_dict = self.create_new_dict(ec) - if self.can_cache(): - self.last_ec = ec - self.last_dict = w_dict + self.last_ec = ec + self.last_dict = w_dict return w_dict def descr_local__new__(space, w_subtype, __args__): diff --git a/pypy/module/thread/stm.py b/pypy/module/thread/stm.py --- a/pypy/module/thread/stm.py +++ b/pypy/module/thread/stm.py @@ -2,20 +2,32 @@ Software Transactional Memory emulation of the GIL. """ -from pypy.module.thread.threadlocals import OSThreadLocals +from pypy.module.thread.threadlocals import BaseThreadLocals from pypy.module.thread.error import wrap_thread_error from pypy.interpreter.executioncontext import ExecutionContext +from pypy.interpreter.gateway import Wrappable, W_Root, interp2app +from pypy.interpreter.typedef import TypeDef, GetSetProperty, descr_get_dict from rpython.rlib import rthread from rpython.rlib import rstm -from rpython.rlib.objectmodel import invoke_around_extcall +from rpython.rlib import rweakref +from rpython.rlib import jit +from rpython.rlib.objectmodel import invoke_around_extcall, we_are_translated ec_cache = rstm.ThreadLocalReference(ExecutionContext) +def initialize_execution_context(ec): + ec._thread_local_dicts = rweakref.RWeakKeyDictionary(STMLocal, W_Root) + if ec.space.config.objspace.std.withmethodcache: + from pypy.objspace.std.typeobject import MethodCache + ec._methodcache = MethodCache(ec.space) -class STMThreadLocals(OSThreadLocals): +def _fill_untranslated(ec): + if not we_are_translated() and not hasattr(ec, '_thread_local_dicts'): + initialize_execution_context(ec) - use_dict = False + +class STMThreadLocals(BaseThreadLocals): def initialize(self, space): """NOT_RPYTHON: set up a mechanism to send to the C code the value @@ -46,6 +58,9 @@ def getallvalues(self): raise ValueError + def leave_thread(self, space): + self.setvalue(None) + def setup_threads(self, space): self.threads_running = True self.configure_transaction_length(space) @@ -67,6 +82,8 @@ interval = space.actionflag.getcheckinterval() rstm.set_transaction_length(interval) +# ____________________________________________________________ + class STMLock(rthread.Lock): def __init__(self, space, ll_lock): @@ -86,3 +103,66 @@ def allocate_stm_lock(space): return STMLock(space, rthread.allocate_ll_lock()) + +# ____________________________________________________________ + + +class STMLocal(Wrappable): + """Thread-local data""" + + @jit.dont_look_inside + def __init__(self, space, initargs): + self.space = space + self.initargs = initargs + # The app-level __init__() will be called by the general + # instance-creation logic. It causes getdict() to be + # immediately called. If we don't prepare and set a w_dict + # for the current thread, then this would in cause getdict() + # to call __init__() a second time. + ec = space.getexecutioncontext() + _fill_untranslated(ec) + w_dict = space.newdict(instance=True) + ec._thread_local_dicts.set(self, w_dict) + + @jit.dont_look_inside + def create_new_dict(self, ec): + # create a new dict for this thread + space = self.space + w_dict = space.newdict(instance=True) + ec._thread_local_dicts.set(self, w_dict) + # call __init__ + try: + w_self = space.wrap(self) + w_type = space.type(w_self) + w_init = space.getattr(w_type, space.wrap("__init__")) + space.call_obj_args(w_init, w_self, self.initargs) + except: + # failed, forget w_dict and propagate the exception + ec._thread_local_dicts.set(self, None) + raise + # ready + return w_dict + + def getdict(self, space): + ec = space.getexecutioncontext() + _fill_untranslated(ec) + w_dict = ec._thread_local_dicts.get(self) + if w_dict is None: + w_dict = self.create_new_dict(ec) + return w_dict + + def descr_local__new__(space, w_subtype, __args__): + local = space.allocate_instance(STMLocal, w_subtype) + STMLocal.__init__(local, space, __args__) + return space.wrap(local) + + def descr_local__init__(self, space): + # No arguments allowed + pass + +STMLocal.typedef = TypeDef("thread._local", + __doc__ = "Thread-local data", + __new__ = interp2app(STMLocal.descr_local__new__.im_func), + __init__ = interp2app(STMLocal.descr_local__init__), + __dict__ = GetSetProperty(descr_get_dict, cls=STMLocal), + ) diff --git a/pypy/module/thread/test/test_local.py b/pypy/module/thread/test/test_local.py --- a/pypy/module/thread/test/test_local.py +++ b/pypy/module/thread/test/test_local.py @@ -3,9 +3,16 @@ class AppTestLocal(GenericTestThread): + def setup_class(cls): + GenericTestThread.setup_class.im_func(cls) + cls.w__local = cls.space.appexec([], """(): + import thread + return thread._local + """) + def test_local_1(self): import thread - from thread import _local as tlsobject + tlsobject = self._local freed = [] class X: def __del__(self): @@ -51,10 +58,10 @@ tags = ['???', 1, 2, 3, 4, 5, 54321] seen = [] - raises(TypeError, thread._local, a=1) - raises(TypeError, thread._local, 1) + raises(TypeError, self._local, a=1) + raises(TypeError, self._local, 1) - class X(thread._local): + class X(self._local): def __init__(self, n): assert n == 42 self.tag = tags.pop() @@ -74,7 +81,7 @@ def test_local_setdict(self): import thread - x = thread._local() + x = self._local() # XXX: On Cpython these are AttributeErrors raises(TypeError, "x.__dict__ = 42") raises(TypeError, "x.__dict__ = {}") @@ -91,7 +98,7 @@ def test_local_is_not_immortal(self): import thread, gc, time - class Local(thread._local): + class Local(self._local): def __del__(self): done.append('del') done = [] diff --git a/pypy/module/thread/test/test_stm.py b/pypy/module/thread/test/test_stm.py new file mode 100644 --- /dev/null +++ b/pypy/module/thread/test/test_stm.py @@ -0,0 +1,11 @@ +from pypy.module.thread.test import test_local + + +class AppTestSTMLocal(test_local.AppTestLocal): + + def setup_class(cls): + test_local.AppTestLocal.setup_class.im_func(cls) + cls.w__local = cls.space.appexec([], """(): + import thread + return thread._untranslated_stmlocal + """) diff --git a/pypy/module/thread/threadlocals.py b/pypy/module/thread/threadlocals.py --- a/pypy/module/thread/threadlocals.py +++ b/pypy/module/thread/threadlocals.py @@ -6,59 +6,14 @@ ExecutionContext._signals_enabled = 0 # default value -class OSThreadLocals: - """Thread-local storage for OS-level threads. - For memory management, this version depends on explicit notification when - a thread finishes. This works as long as the thread was started by - os_thread.bootstrap().""" +class BaseThreadLocals(object): + _mainthreadident = 0 - use_dict = True + def initialize(self, space): + pass - def __init__(self): - if self.use_dict: - self._valuedict = {} # {thread_ident: ExecutionContext()} - self._cleanup_() - - def _cleanup_(self): - if self.use_dict: - self._valuedict.clear() - self.clear_cache() - self._mainthreadident = 0 - - def clear_cache(self): - # Cache function: fast minicaching for the common case. Relies - # on the GIL; overridden in stm.py. - self._mostrecentkey = 0 - self._mostrecentvalue = None - - def getvalue(self): - # Overridden in stm.py. - ident = rthread.get_ident() - if ident == self._mostrecentkey: - result = self._mostrecentvalue - else: - value = self._valuedict.get(ident, None) - # slow path: update the minicache - self._mostrecentkey = ident - self._mostrecentvalue = value - result = value - return result - - def setvalue(self, value): - # Overridden in stm.py. - ident = rthread.get_ident() - if value is not None: - if len(self._valuedict) == 0: - value._signals_enabled = 1 # the main thread is enabled - self._mainthreadident = ident - self._valuedict[ident] = value - else: - try: - del self._valuedict[ident] - except KeyError: - pass - # clear the minicache to prevent it from containing an outdated value - self.clear_cache() + def setup_threads(self, space): + pass def signals_enabled(self): ec = self.getvalue() @@ -76,8 +31,56 @@ "cannot disable signals in thread not enabled for signals") ec._signals_enabled = new + +class OSThreadLocals(BaseThreadLocals): + """Thread-local storage for OS-level threads. + For memory management, this version depends on explicit notification when + a thread finishes. This works as long as the thread was started by + os_thread.bootstrap().""" + + def __init__(self): + self._valuedict = {} # {thread_ident: ExecutionContext()} + self._cleanup_() + + def _cleanup_(self): + self._valuedict.clear() + self._clear_cache() + self._mainthreadident = 0 + + def _clear_cache(self): + # Cache function: fast minicaching for the common case. Relies + # on the GIL. + self._mostrecentkey = 0 + self._mostrecentvalue = None + + def getvalue(self): + ident = rthread.get_ident() + if ident == self._mostrecentkey: + result = self._mostrecentvalue + else: + value = self._valuedict.get(ident, None) + # slow path: update the minicache + self._mostrecentkey = ident + self._mostrecentvalue = value + result = value + return result + + def setvalue(self, value): + ident = rthread.get_ident() + if value is not None: + if len(self._valuedict) == 0: + value._signals_enabled = 1 # the main thread is enabled + self._mainthreadident = ident + self._valuedict[ident] = value + else: + try: + del self._valuedict[ident] + except KeyError: + pass + # clear the minicache to prevent it from containing an outdated value + self._clear_cache() + def getallvalues(self): - # Overridden in stm.py. return self._valuedict def leave_thread(self, space): From noreply at buildbot.pypy.org Wed Feb 20 13:06:34 2013 From: noreply at buildbot.pypy.org (timfel) Date: Wed, 20 Feb 2013 13:06:34 +0100 (CET) Subject: [pypy-commit] pypy default: (timfel, cfbolz) move float_as_integer_ratio into rlib and add test, because Ruby needs it, too Message-ID: <20130220120634.95EE61C137A@cobra.cs.uni-duesseldorf.de> Author: Tim Felgentreff Branch: Changeset: r61493:67e7e4a54f22 Date: 2013-02-20 12:56 +0100 http://bitbucket.org/pypy/pypy/changeset/67e7e4a54f22/ Log: (timfel, cfbolz) move float_as_integer_ratio into rlib and add test, because Ruby needs it, too diff --git a/pypy/objspace/std/floatobject.py b/pypy/objspace/std/floatobject.py --- a/pypy/objspace/std/floatobject.py +++ b/pypy/objspace/std/floatobject.py @@ -10,7 +10,7 @@ from rpython.rlib.rarithmetic import ovfcheck_float_to_int, intmask, LONG_BIT from rpython.rlib.rfloat import ( isinf, isnan, isfinite, INFINITY, NAN, copysign, formatd, - DTSF_ADD_DOT_0, DTSF_STR_PRECISION) + DTSF_ADD_DOT_0, DTSF_STR_PRECISION, float_as_rbigint_ratio) from rpython.rlib.rbigint import rbigint from rpython.rlib import rfloat from rpython.tool.sourcetools import func_with_new_name @@ -553,27 +553,18 @@ def float_as_integer_ratio__Float(space, w_float): value = w_float.floatval - if isinf(value): + try: + num, den = float_as_rbigint_ratio(value) + except OverflowError: w_msg = space.wrap("cannot pass infinity to as_integer_ratio()") raise OperationError(space.w_OverflowError, w_msg) - elif isnan(value): + except ValueError: w_msg = space.wrap("cannot pass nan to as_integer_ratio()") raise OperationError(space.w_ValueError, w_msg) - float_part, exp = math.frexp(value) - for i in range(300): - if float_part == math.floor(float_part): - break - float_part *= 2.0 - exp -= 1 - w_num = W_LongObject.fromfloat(space, float_part) - w_den = space.newlong(1) - w_exp = space.newlong(abs(exp)) - w_exp = space.lshift(w_den, w_exp) - if exp > 0: - w_num = space.mul(w_num, w_exp) - else: - w_den = w_exp - # Try to return int. + + w_num = space.newlong_from_rbigint(num) + w_den = space.newlong_from_rbigint(den) + # Try to return int return space.newtuple([space.int(w_num), space.int(w_den)]) def float_is_integer__Float(space, w_float): diff --git a/rpython/rlib/rfloat.py b/rpython/rlib/rfloat.py --- a/rpython/rlib/rfloat.py +++ b/rpython/rlib/rfloat.py @@ -419,3 +419,25 @@ def isfinite(x): "NOT_RPYTHON" return not isinf(x) and not isnan(x) + +def float_as_rbigint_ratio(value): + from rpython.rlib.rbigint import rbigint + + if isinf(value): + raise OverflowError("cannot pass infinity to as_integer_ratio()") + elif isnan(value): + raise ValueError("cannot pass nan to as_integer_ratio()") + float_part, exp_int = math.frexp(value) + for i in range(300): + if float_part == math.floor(float_part): + break + float_part *= 2.0 + exp_int -= 1 + num = rbigint.fromfloat(float_part) + den = rbigint.fromint(1) + exp = den.lshift(abs(exp_int)) + if exp_int > 0: + num = num.mul(exp) + else: + den = exp + return num, den diff --git a/rpython/rlib/test/test_rfloat.py b/rpython/rlib/test/test_rfloat.py new file mode 100644 --- /dev/null +++ b/rpython/rlib/test/test_rfloat.py @@ -0,0 +1,23 @@ +import sys, py + +from rpython.rlib.rfloat import float_as_rbigint_ratio +from rpython.rlib.rbigint import rbigint + + +def test_float_as_rbigint_ratio(): + for f, ratio in [ + (0.875, (7, 8)), + (-0.875, (-7, 8)), + (0.0, (0, 1)), + (11.5, (23, 2)), + ]: + num, den = float_as_rbigint_ratio(f) + assert num.eq(rbigint.fromint(ratio[0])) + assert den.eq(rbigint.fromint(ratio[1])) + + with py.test.raises(OverflowError): + float_as_rbigint_ratio(float('inf')) + with py.test.raises(OverflowError): + float_as_rbigint_ratio(float('-inf')) + with py.test.raises(ValueError): + float_as_rbigint_ratio(float('nan')) From noreply at buildbot.pypy.org Wed Feb 20 13:42:06 2013 From: noreply at buildbot.pypy.org (cfbolz) Date: Wed, 20 Feb 2013 13:42:06 +0100 (CET) Subject: [pypy-commit] pypy default: move some tests to the newly created rlib/test/test_rfloat.py Message-ID: <20130220124206.4436C1C0884@cobra.cs.uni-duesseldorf.de> Author: Carl Friedrich Bolz Branch: Changeset: r61494:d71d48cdf597 Date: 2013-02-20 13:41 +0100 http://bitbucket.org/pypy/pypy/changeset/d71d48cdf597/ Log: move some tests to the newly created rlib/test/test_rfloat.py diff --git a/rpython/rlib/test/test_rfloat.py b/rpython/rlib/test/test_rfloat.py --- a/rpython/rlib/test/test_rfloat.py +++ b/rpython/rlib/test/test_rfloat.py @@ -1,8 +1,116 @@ import sys, py from rpython.rlib.rfloat import float_as_rbigint_ratio +from rpython.rlib.rfloat import break_up_float +from rpython.rlib.rfloat import copysign +from rpython.rlib.rfloat import round_away +from rpython.rlib.rfloat import round_double from rpython.rlib.rbigint import rbigint +def test_copysign(): + assert copysign(1, 1) == 1 + assert copysign(-1, 1) == 1 + assert copysign(-1, -1) == -1 + assert copysign(1, -1) == -1 + assert copysign(1, -0.) == -1 + +def test_round_away(): + assert round_away(.1) == 0. + assert round_away(.5) == 1. + assert round_away(.7) == 1. + assert round_away(1.) == 1. + assert round_away(-.5) == -1. + assert round_away(-.1) == 0. + assert round_away(-.7) == -1. + assert round_away(0.) == 0. + +def test_round_double(): + def almost_equal(x, y): + assert round(abs(x-y), 7) == 0 + + almost_equal(round_double(0.125, 2), 0.13) + almost_equal(round_double(0.375, 2), 0.38) + almost_equal(round_double(0.625, 2), 0.63) + almost_equal(round_double(0.875, 2), 0.88) + almost_equal(round_double(-0.125, 2), -0.13) + almost_equal(round_double(-0.375, 2), -0.38) + almost_equal(round_double(-0.625, 2), -0.63) + almost_equal(round_double(-0.875, 2), -0.88) + + almost_equal(round_double(0.25, 1), 0.3) + almost_equal(round_double(0.75, 1), 0.8) + almost_equal(round_double(-0.25, 1), -0.3) + almost_equal(round_double(-0.75, 1), -0.8) + + round_double(-6.5, 0) == -7.0 + round_double(-5.5, 0) == -6.0 + round_double(-1.5, 0) == -2.0 + round_double(-0.5, 0) == -1.0 + round_double(0.5, 0) == 1.0 + round_double(1.5, 0) == 2.0 + round_double(2.5, 0) == 3.0 + round_double(3.5, 0) == 4.0 + round_double(4.5, 0) == 5.0 + round_double(5.5, 0) == 6.0 + round_double(6.5, 0) == 7.0 + + round_double(-25.0, -1) == -30.0 + round_double(-15.0, -1) == -20.0 + round_double(-5.0, -1) == -10.0 + round_double(5.0, -1) == 10.0 + round_double(15.0, -1) == 20.0 + round_double(25.0, -1) == 30.0 + round_double(35.0, -1) == 40.0 + round_double(45.0, -1) == 50.0 + round_double(55.0, -1) == 60.0 + round_double(65.0, -1) == 70.0 + round_double(75.0, -1) == 80.0 + round_double(85.0, -1) == 90.0 + round_double(95.0, -1) == 100.0 + round_double(12325.0, -1) == 12330.0 + + round_double(350.0, -2) == 400.0 + round_double(450.0, -2) == 500.0 + + almost_equal(round_double(0.5e21, -21), 1e21) + almost_equal(round_double(1.5e21, -21), 2e21) + almost_equal(round_double(2.5e21, -21), 3e21) + almost_equal(round_double(5.5e21, -21), 6e21) + almost_equal(round_double(8.5e21, -21), 9e21) + + almost_equal(round_double(-1.5e22, -22), -2e22) + almost_equal(round_double(-0.5e22, -22), -1e22) + almost_equal(round_double(0.5e22, -22), 1e22) + almost_equal(round_double(1.5e22, -22), 2e22) + +def test_round_half_even(): + from rpython.rlib import rfloat + for func in (rfloat.round_double_short_repr, + rfloat.round_double_fallback_repr): + # 2.x behavior + assert func(2.5, 0, False) == 3.0 + # 3.x behavior + assert func(2.5, 0, True) == 2.0 + +def test_break_up_float(): + assert break_up_float('1') == ('', '1', '', '') + assert break_up_float('+1') == ('+', '1', '', '') + assert break_up_float('-1') == ('-', '1', '', '') + + assert break_up_float('.5') == ('', '', '5', '') + + assert break_up_float('1.2e3') == ('', '1', '2', '3') + assert break_up_float('1.2e+3') == ('', '1', '2', '+3') + assert break_up_float('1.2e-3') == ('', '1', '2', '-3') + + # some that will get thrown out on return: + assert break_up_float('.') == ('', '', '', '') + assert break_up_float('+') == ('+', '', '', '') + assert break_up_float('-') == ('-', '', '', '') + assert break_up_float('e1') == ('', '', '', '1') + + py.test.raises(ValueError, break_up_float, 'e') + def test_float_as_rbigint_ratio(): for f, ratio in [ diff --git a/rpython/rtyper/test/test_rfloat.py b/rpython/rtyper/test/test_rfloat.py --- a/rpython/rtyper/test/test_rfloat.py +++ b/rpython/rtyper/test/test_rfloat.py @@ -216,26 +216,6 @@ # https://bugzilla.novell.com/show_bug.cgi?id=692493 assert not self.interpret(fn, [1e200, 1e200]) # nan - def test_break_up_float(self): - from rpython.rlib.rfloat import break_up_float - assert break_up_float('1') == ('', '1', '', '') - assert break_up_float('+1') == ('+', '1', '', '') - assert break_up_float('-1') == ('-', '1', '', '') - - assert break_up_float('.5') == ('', '', '5', '') - - assert break_up_float('1.2e3') == ('', '1', '2', '3') - assert break_up_float('1.2e+3') == ('', '1', '2', '+3') - assert break_up_float('1.2e-3') == ('', '1', '2', '-3') - - # some that will get thrown out on return: - assert break_up_float('.') == ('', '', '', '') - assert break_up_float('+') == ('+', '', '', '') - assert break_up_float('-') == ('-', '', '', '') - assert break_up_float('e1') == ('', '', '', '1') - - py.test.raises(ValueError, break_up_float, 'e') - def test_formatd(self): from rpython.rlib.rfloat import formatd def f(x): @@ -296,93 +276,6 @@ assert self.interpret(func, [0]) == 1e23 assert self.interpret(func, [1]) == -1e23 - def test_copysign(self): - from rpython.rlib.rfloat import copysign - assert copysign(1, 1) == 1 - assert copysign(-1, 1) == 1 - assert copysign(-1, -1) == -1 - assert copysign(1, -1) == -1 - assert copysign(1, -0.) == -1 - - def test_round_away(self): - from rpython.rlib.rfloat import round_away - assert round_away(.1) == 0. - assert round_away(.5) == 1. - assert round_away(.7) == 1. - assert round_away(1.) == 1. - assert round_away(-.5) == -1. - assert round_away(-.1) == 0. - assert round_away(-.7) == -1. - assert round_away(0.) == 0. - - def test_round_double(self): - from rpython.rlib.rfloat import round_double - def almost_equal(x, y): - assert round(abs(x-y), 7) == 0 - - almost_equal(round_double(0.125, 2), 0.13) - almost_equal(round_double(0.375, 2), 0.38) - almost_equal(round_double(0.625, 2), 0.63) - almost_equal(round_double(0.875, 2), 0.88) - almost_equal(round_double(-0.125, 2), -0.13) - almost_equal(round_double(-0.375, 2), -0.38) - almost_equal(round_double(-0.625, 2), -0.63) - almost_equal(round_double(-0.875, 2), -0.88) - - almost_equal(round_double(0.25, 1), 0.3) - almost_equal(round_double(0.75, 1), 0.8) - almost_equal(round_double(-0.25, 1), -0.3) - almost_equal(round_double(-0.75, 1), -0.8) - - round_double(-6.5, 0) == -7.0 - round_double(-5.5, 0) == -6.0 - round_double(-1.5, 0) == -2.0 - round_double(-0.5, 0) == -1.0 - round_double(0.5, 0) == 1.0 - round_double(1.5, 0) == 2.0 - round_double(2.5, 0) == 3.0 - round_double(3.5, 0) == 4.0 - round_double(4.5, 0) == 5.0 - round_double(5.5, 0) == 6.0 - round_double(6.5, 0) == 7.0 - - round_double(-25.0, -1) == -30.0 - round_double(-15.0, -1) == -20.0 - round_double(-5.0, -1) == -10.0 - round_double(5.0, -1) == 10.0 - round_double(15.0, -1) == 20.0 - round_double(25.0, -1) == 30.0 - round_double(35.0, -1) == 40.0 - round_double(45.0, -1) == 50.0 - round_double(55.0, -1) == 60.0 - round_double(65.0, -1) == 70.0 - round_double(75.0, -1) == 80.0 - round_double(85.0, -1) == 90.0 - round_double(95.0, -1) == 100.0 - round_double(12325.0, -1) == 12330.0 - - round_double(350.0, -2) == 400.0 - round_double(450.0, -2) == 500.0 - - almost_equal(round_double(0.5e21, -21), 1e21) - almost_equal(round_double(1.5e21, -21), 2e21) - almost_equal(round_double(2.5e21, -21), 3e21) - almost_equal(round_double(5.5e21, -21), 6e21) - almost_equal(round_double(8.5e21, -21), 9e21) - - almost_equal(round_double(-1.5e22, -22), -2e22) - almost_equal(round_double(-0.5e22, -22), -1e22) - almost_equal(round_double(0.5e22, -22), 1e22) - almost_equal(round_double(1.5e22, -22), 2e22) - - def test_round_half_even(self): - from rpython.rlib import rfloat - for func in (rfloat.round_double_short_repr, - rfloat.round_double_fallback_repr): - # 2.x behavior - assert func(2.5, 0, False) == 3.0 - # 3.x behavior - assert func(2.5, 0, True) == 2.0 class TestLLtype(BaseTestRfloat, LLRtypeMixin): From noreply at buildbot.pypy.org Wed Feb 20 15:44:20 2013 From: noreply at buildbot.pypy.org (lwassermann) Date: Wed, 20 Feb 2013 15:44:20 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: moved createClosure from contextPart to objectsSpace Message-ID: <20130220144420.A04D31C0264@cobra.cs.uni-duesseldorf.de> Author: Lars Wassermann Branch: Changeset: r67:256ad8186a3b Date: 2013-02-20 15:42 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/256ad8186a3b/ Log: moved createClosure from contextPart to objectsSpace diff --git a/spyvm/interpreter.py b/spyvm/interpreter.py --- a/spyvm/interpreter.py +++ b/spyvm/interpreter.py @@ -400,15 +400,6 @@ index_in_array, w_indirectTemps = self._extract_index_and_temps() w_indirectTemps.atput0(self.space, index_in_array, self.pop()) - def _newClosure(self, numArgs, pc, numCopied): - BlockClosureShadow = self.space.w_BlockClosure.as_class_get_shadow(self.space) - w_closure = BlockClosureShadow.new(numCopied) - closure = wrapper.BlockClosureWrapper(self.space, w_closure) - closure.store_outerContext(self._w_self) - closure.store_startpc(pc) - closure.store_numArgs(numArgs) - return closure, w_closure - def pushClosureCopyCopiedValuesBytecode(self, interp): """ Copied from Blogpost: http://www.mirandabanda.org/cogblog/2008/07/22/closures-part-ii-the-bytecodes/ ContextPart>>pushClosureCopyNumCopiedValues: numCopied numArgs: numArgs blockSize: blockSize @@ -436,11 +427,8 @@ i = self.getbytecode() blockSize = (j << 8) | i #create new instance of BlockClosure - closure, w_closure = self._newClosure(numArgs, self.pc(), numCopied) - if numCopied > 0: - copiedValues = self.pop_and_return_n(numCopied) - for i0 in range(numCopied): - closure.atput0(i0, copiedValues[i0]) + w_closure, closure = space.newClosure(self._w_self, self.pc(), numArgs, + self.pop_and_return_n(numCopied)) self.push(w_closure) self.jump(blockSize) diff --git a/spyvm/objspace.py b/spyvm/objspace.py --- a/spyvm/objspace.py +++ b/spyvm/objspace.py @@ -1,6 +1,4 @@ -from spyvm import constants -from spyvm import model -from spyvm import shadow +from spyvm import constants, model, shadow, wrapper from spyvm.error import UnwrappingError, WrappingError from rpython.rlib.objectmodel import instantiate from rpython.rlib.rarithmetic import intmask, r_uint @@ -265,6 +263,16 @@ def _freeze_(self): return True + def newClosure(self, outerContext, pc, numArgs, copiedValues): + BlockClosureShadow = self.w_BlockClosure.as_class_get_shadow(self) + w_closure = BlockClosureShadow.new(len(copiedValues)) + closure = wrapper.BlockClosureWrapper(self, w_closure) + closure.store_outerContext(outerContext) + closure.store_startpc(pc) + closure.store_numArgs(numArgs) + for i0 in range(len(copiedValues)): + closure.atput0(i0, copiedValues[i0]) + return w_closure, closure def bootstrap_class(space, instsize, w_superclass=None, w_metaclass=None, name='?', format=shadow.POINTERS, varsized=False): diff --git a/spyvm/primitives.py b/spyvm/primitives.py --- a/spyvm/primitives.py +++ b/spyvm/primitives.py @@ -834,18 +834,18 @@ @expose_primitive(VALUE_WITH_ARGS, unwrap_spec=[object, list], no_result=True) -def func(interp, w_block_ctx, l_args): +def func(interp, w_block_ctx, args_w): assert isinstance(w_block_ctx, model.W_PointersObject) s_block_ctx = w_block_ctx.as_blockcontext_get_shadow(interp.space) exp_arg_cnt = s_block_ctx.expected_argument_count() - if len(l_args) != exp_arg_cnt: + if len(args_w) != exp_arg_cnt: raise PrimitiveFailedError() # Push all the items from the array for i in range(exp_arg_cnt): - s_block_ctx.push(l_args[i]) + s_block_ctx.push(args_w[i]) # XXX Check original logic. Image does not test this anyway # because falls back to value + internal implementation diff --git a/spyvm/test/test_primitives.py b/spyvm/test/test_primitives.py --- a/spyvm/test/test_primitives.py +++ b/spyvm/test/test_primitives.py @@ -30,6 +30,7 @@ if isinstance(x, model.W_Object): return x if isinstance(x, str) and len(x) == 1: return space.wrap_char(x) if isinstance(x, str): return space.wrap_string(x) + if isinstance(x, list): return space.wrap_list(x) raise NotImplementedError def mock(stack): From noreply at buildbot.pypy.org Wed Feb 20 15:44:21 2013 From: noreply at buildbot.pypy.org (lwassermann) Date: Wed, 20 Feb 2013 15:44:21 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: unified new primitives, next step is pushing/saving the temporaries Message-ID: <20130220144421.BC47F1C0884@cobra.cs.uni-duesseldorf.de> Author: Lars Wassermann Branch: Changeset: r68:87da260898cd Date: 2013-02-20 15:43 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/87da260898cd/ Log: unified new primitives, next step is pushing/saving the temporaries diff --git a/spyvm/primitives.py b/spyvm/primitives.py --- a/spyvm/primitives.py +++ b/spyvm/primitives.py @@ -920,10 +920,69 @@ CLOSURE_VALUE_VALUE_VALUE = 204 CLOSURE_VALUE_VALUE_VALUE_VALUE = 205 CLOSURE_VALUE_WITH_ARGS = 206 #valueWithArguments: +CLOSURE_VALUE_NO_CONTEXT_SWITCH = 221 +CLOSURE_VALUE_NO_CONTEXT_SWITCH_ = 222 + + at expose_primitive(CLOSURE_COPY_WITH_COPIED_VALUES, unwrap_spec=[object, int, list]) +def func(interp, outerContext, numArgs, copiedValues): + frame = interp.s_active_context() + w_context, s_context = interp.space.newClosure(outerContext, frame.pc(), + numArgs, copiedValues) + frame.push(w_context) + + +def activateClosure(w_block_closure, args_w, mayContextSwitch=True): + if not w_block_closure.getclass(interp.space).is_same_object( + interp.space.w_BlockClosure): + raise PrimitiveFailedError() + if not w_block_closure.numArgs == len(args_w): + raise PrimitiveFailedError() + if not w_block_closure.outerContext.getclass(interp.space).issubclass( + interp.space.w_ContextPart): + raise PrimitiveFailedError() + w_closureMethod = w_block_closure.w_method() + assert isinstance(w_closureMethod, W_CompiledMethod) + assert w_block_closure is not w_block_closure.outerContext + numCopied = w_block_closure.size() + + s_block_closure = w_block_closure.as_blockclosure_get_shadow(interp.space) + s_block_closure.push_all(args_w) + + s_block_closure.store_pc(s_block_closure.initialip()) + s_block_closure.store_w_sender(frame) + + + at expose_primitive(CLOSURE_VALUE, unwrap_spec=[object]) +def func(interp, w_block_closure): + activateClosure(w_block_closure, []) + + at expose_primitive(CLOSURE_VALUE_, unwrap_spec=[object, object]) +def func(interp, w_block_closure, w_a0): + activateClosure(w_block_closure, [w_a0]) + + at expose_primitive(CLOSURE_VALUE_VALUE, unwrap_spec=[object, object, object]) +def func(interp, w_block_closure, w_a0, w_a1): + activateClosure(w_block_closure, [w_a0, w_a1]) + + at expose_primitive(CLOSURE_VALUE_VALUE_VALUE, unwrap_spec=[object, object, object, object]) +def func(interp, w_block_closure, w_a0, w_a1, w_a2): + activateClosure(w_block_closure, [w_a0, w_a1, w_a2]) + + at expose_primitive(CLOSURE_VALUE_VALUE_VALUE_VALUE, unwrap_spec=[object, object, object, object, object]) +def func(interp, w_block_closure, w_a0, w_a1, w_a2, w_a3): + activateClosure(w_block_closure, [w_a0, w_a1, w_a2, w_a3]) @expose_primitive(CLOSURE_VALUE_WITH_ARGS, unwrap_spec=[object, list]) -def func(interp, w_block_closure, l_args): - pass +def func(interp, w_block_closure, args_w): + activateClosure(w_block_closure, args_w) + + at expose_primitive(CLOSURE_VALUE_NO_CONTEXT_SWITCH, unwrap_spec=[object]) +def func(interp, w_block_closure): + activateClosure(w_block_closure, [], mayContextSwitch=False) + + at expose_primitive(CLOSURE_VALUE_NO_CONTEXT_SWITCH_, unwrap_spec=[object, object]) +def func(interp, w_block_closure, w_a0): + activateClosure(w_block_closure, [w_a0], mayContextSwitch=False) # ___________________________________________________________________________ # PrimitiveLoadInstVar From noreply at buildbot.pypy.org Wed Feb 20 15:57:22 2013 From: noreply at buildbot.pypy.org (cfbolz) Date: Wed, 20 Feb 2013 15:57:22 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: simplify logic slightly Message-ID: <20130220145722.DC8C31C061A@cobra.cs.uni-duesseldorf.de> Author: Carl Friedrich Bolz Branch: Changeset: r69:fd4d9700e7b6 Date: 2013-02-19 16:55 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/fd4d9700e7b6/ Log: simplify logic slightly diff --git a/spyvm/model.py b/spyvm/model.py --- a/spyvm/model.py +++ b/spyvm/model.py @@ -308,10 +308,9 @@ @objectmodel.specialize.arg(2) def as_special_get_shadow(self, space, TheClass): shadow = self._shadow - if shadow is None: - shadow = self.attach_shadow_of_class(space, TheClass) - elif not isinstance(shadow, TheClass): - shadow.detach_shadow() + if not isinstance(shadow, TheClass): + if shadow is not None: + shadow.detach_shadow() shadow = self.attach_shadow_of_class(space, TheClass) shadow.sync_shadow() return shadow From noreply at buildbot.pypy.org Wed Feb 20 15:57:24 2013 From: noreply at buildbot.pypy.org (cfbolz) Date: Wed, 20 Feb 2013 15:57:24 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: remove the fixedstack class and just put the functionality into ContextPartShadow Message-ID: <20130220145724.1046C1C061A@cobra.cs.uni-duesseldorf.de> Author: Carl Friedrich Bolz Branch: Changeset: r70:4f3d226d130b Date: 2013-02-19 18:20 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/4f3d226d130b/ Log: remove the fixedstack class and just put the functionality into ContextPartShadow diff --git a/spyvm/fixedstack.py b/spyvm/fixedstack.py deleted file mode 100644 --- a/spyvm/fixedstack.py +++ /dev/null @@ -1,68 +0,0 @@ -""" -A Fixed stack for SPy. -""" - -import types - -from rpython.rlib import jit -from rpython.rlib.rarithmetic import r_uint - -class FixedStack(object): - # _annspecialcase_ = "specialize:ctr_location" # polymorphic - - def __init__(self): - pass - - def setup(self, stacksize): - self.ptr = r_uint(0) # we point after the last element - self.items = [None] * stacksize - - def clone(self): - # this is only needed if we support flow space - s = self.__class__() - s.setup(len(self.items)) - for item in self.items[:self.ptr]: - try: - item = item.clone() - except AttributeError: - pass - s.push(item) - return s - - def push(self, item): - ptr = jit.promote(self.ptr) - self.items[ptr] = item - self.ptr = ptr + 1 - - def pop(self): - ptr = jit.promote(self.ptr) - 1 - ret = self.items[ptr] # you get OverflowError if the stack is empty - self.items[ptr] = None - self.ptr = ptr - return ret - - @jit.unroll_safe - def drop(self, n): - jit.promote(self.ptr) - while n > 0: - n -= 1 - self.ptr -= 1 - self.items[self.ptr] = None - - def top(self, position=0): - # for a fixed stack, we assume correct indices - rpos = r_uint(position) - return self.items[self.ptr + ~rpos] - - def set_top(self, value, position=0): - # for a fixed stack, we assume correct indices - rpos = r_uint(position) - self.items[self.ptr + ~rpos] = value - - def depth(self): - return self.ptr - - def empty(self): - return not self.ptr - - diff --git a/spyvm/shadow.py b/spyvm/shadow.py --- a/spyvm/shadow.py +++ b/spyvm/shadow.py @@ -317,10 +317,8 @@ __metaclass__ = extendabletype def __init__(self, space, w_self): - from spyvm.fixedstack import FixedStack self._w_sender = space.w_nil - self._stack = FixedStack() self.currentBytecode = -1 AbstractRedirectingShadow.__init__(self, space, w_self) @@ -339,7 +337,7 @@ if n0 == constants.CTXPART_STACKP_INDEX: return self.wrap_stackpointer() if self.stackstart() <= n0 < self.external_stackpointer(): - return self._stack.top(self.stackdepth() - (n0-self.stackstart()) - 1) + return self.peek(self.stackdepth() - (n0-self.stackstart()) - 1) if self.external_stackpointer() <= n0 < self.stackend(): return self.space.w_nil else: @@ -354,7 +352,7 @@ if n0 == constants.CTXPART_STACKP_INDEX: return self.unwrap_store_stackpointer(w_value) if self.stackstart() <= n0 < self.external_stackpointer(): - return self._stack.set_top(w_value, + return self.set_top(w_value, self.stackdepth() - (n0-self.stackstart()) - 1) return if self.external_stackpointer() <= n0 < self.stackend(): @@ -375,10 +373,10 @@ if size < depth: # TODO Warn back to user assert size >= 0 - self._stack.drop(depth - size) + self.pop_n(depth - size) else: for i in range(depth, size): - self._stack.push(self.space.w_nil) + self.push(self.space.w_nil) def wrap_stackpointer(self): return self.space.wrap_int(self.stackdepth() + @@ -478,17 +476,24 @@ # ______________________________________________________________________ # Stack Manipulation def init_stack(self): - self._stack.setup(self.stackend() - self.stackstart()) + self._stack_ptr = rarithmetic.r_uint(0) # we point after the last element + self._stack_items = [None] * (self.stackend() - self.stackstart()) def stack(self): """NOT_RPYTHON""" # purely for testing - return self._stack.items[:self.stackdepth()] + return self._stack_items[:self.stackdepth()] def pop(self): - return self._stack.pop() + ptr = jit.promote(self._stack_ptr) - 1 + ret = self._stack_items[ptr] # you get OverflowError if the stack is empty + self._stack_items[ptr] = None + self._stack_ptr = ptr + return ret def push(self, w_v): - self._stack.push(w_v) + ptr = jit.promote(self._stack_ptr) + self._stack_items[ptr] = w_v + self._stack_ptr = ptr + 1 def push_all(self, lst): for elt in lst: @@ -496,18 +501,28 @@ def top(self): return self.peek(0) - + + def set_top(self, value, position=0): + rpos = rarithmetic.r_uint(position) + self._stack_items[self._stack_ptr + ~rpos] = value + def peek(self, idx): - return self._stack.top(idx) + rpos = rarithmetic.r_uint(idx) + return self._stack_items[self._stack_ptr + ~rpos] + @jit.unroll_safe def pop_n(self, n): - self._stack.drop(n) + jit.promote(self._stack_ptr) + while n > 0: + n -= 1 + self._stack_ptr -= 1 + self._stack_items[self._stack_ptr] = None def stackdepth(self): - return rarithmetic.intmask(self._stack.depth()) + return rarithmetic.intmask(self._stack_ptr) def pop_and_return_n(self, n): - result = [self._stack.top(i) for i in range(n - 1, -1, -1)] + result = [self.peek(i) for i in range(n - 1, -1, -1)] self.pop_n(n) return result From noreply at buildbot.pypy.org Wed Feb 20 15:57:25 2013 From: noreply at buildbot.pypy.org (cfbolz) Date: Wed, 20 Feb 2013 15:57:25 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: unify temp list and stack Message-ID: <20130220145725.2AC461C061A@cobra.cs.uni-duesseldorf.de> Author: Carl Friedrich Bolz Branch: Changeset: r71:f6a2cd506f60 Date: 2013-02-20 15:03 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/f6a2cd506f60/ Log: unify temp list and stack diff --git a/spyvm/shadow.py b/spyvm/shadow.py --- a/spyvm/shadow.py +++ b/spyvm/shadow.py @@ -473,26 +473,31 @@ def settemp(self, index, w_value): self.s_home().settemp(index, w_value) + @jit.unroll_safe + def init_stack_and_temps(self): + stacksize = self.stackend() - self.stackstart() + tempsize = self.tempsize() + self._temps_and_stack = [None] * (stacksize + tempsize) + for i in range(tempsize): + self._temps_and_stack[i] = self.space.w_nil + self._stack_ptr = rarithmetic.r_uint(tempsize) # we point after the last element + # ______________________________________________________________________ # Stack Manipulation - def init_stack(self): - self._stack_ptr = rarithmetic.r_uint(0) # we point after the last element - self._stack_items = [None] * (self.stackend() - self.stackstart()) - def stack(self): """NOT_RPYTHON""" # purely for testing - return self._stack_items[:self.stackdepth()] + return self._temps_and_stack[self.tempsize():self._stack_ptr] def pop(self): ptr = jit.promote(self._stack_ptr) - 1 - ret = self._stack_items[ptr] # you get OverflowError if the stack is empty - self._stack_items[ptr] = None + ret = self._temps_and_stack[ptr] # you get OverflowError if the stack is empty + self._temps_and_stack[ptr] = None self._stack_ptr = ptr return ret def push(self, w_v): ptr = jit.promote(self._stack_ptr) - self._stack_items[ptr] = w_v + self._temps_and_stack[ptr] = w_v self._stack_ptr = ptr + 1 def push_all(self, lst): @@ -504,11 +509,11 @@ def set_top(self, value, position=0): rpos = rarithmetic.r_uint(position) - self._stack_items[self._stack_ptr + ~rpos] = value + self._temps_and_stack[self._stack_ptr + ~rpos] = value def peek(self, idx): rpos = rarithmetic.r_uint(idx) - return self._stack_items[self._stack_ptr + ~rpos] + return self._temps_and_stack[self._stack_ptr + ~rpos] @jit.unroll_safe def pop_n(self, n): @@ -516,10 +521,10 @@ while n > 0: n -= 1 self._stack_ptr -= 1 - self._stack_items[self._stack_ptr] = None + self._temps_and_stack[self._stack_ptr] = None def stackdepth(self): - return rarithmetic.intmask(self._stack_ptr) + return rarithmetic.intmask(self._stack_ptr - self.tempsize()) def pop_and_return_n(self, n): result = [self.peek(i) for i in range(n - 1, -1, -1)] @@ -548,7 +553,7 @@ s_result.store_initialip(initialip) s_result.store_w_home(w_home) s_result.store_pc(initialip) - s_result.init_stack() + s_result.init_stack_and_temps() return w_result def fetch(self, n0): @@ -574,7 +579,7 @@ def attach_shadow(self): # Make sure the home context is updated first self.copy_from_w_self(constants.BLKCTX_HOME_INDEX) - self.init_stack() + self.init_stack_and_temps() ContextPartShadow.attach_shadow(self) def unwrap_store_initialip(self, w_value): @@ -649,10 +654,9 @@ s_result.store_w_sender(w_sender) s_result.store_w_receiver(w_receiver) s_result.store_pc(0) - s_result._temps = [space.w_nil] * w_method.tempsize + s_result.init_stack_and_temps() for i in range(len(arguments)): s_result.settemp(i, arguments[i]) - s_result.init_stack() return w_result def fetch(self, n0): @@ -687,9 +691,7 @@ def attach_shadow(self): # Make sure the method is updated first self.copy_from_w_self(constants.MTHDCTX_METHOD) - self.init_stack() - # And that there is space for the temps - self._temps = [self.space.w_nil] * self.tempsize() + self.init_stack_and_temps() ContextPartShadow.attach_shadow(self) def tempsize(self): @@ -709,10 +711,10 @@ self._w_receiver = w_receiver def gettemp(self, index0): - return self._temps[index0] + return self._temps_and_stack[index0] def settemp(self, index0, w_value): - self._temps[index0] = w_value + self._temps_and_stack[index0] = w_value def w_home(self): return self.w_self() diff --git a/spyvm/test/test_primitives.py b/spyvm/test/test_primitives.py --- a/spyvm/test/test_primitives.py +++ b/spyvm/test/test_primitives.py @@ -16,7 +16,7 @@ def __init__(self, stack): self._vars = [None] * 6 + stack s_self = self.as_blockcontext_get_shadow() - s_self.init_stack() + s_self.init_stack_and_temps() s_self.reset_stack() s_self.push_all(stack) s_self.store_expected_argument_count(0) From noreply at buildbot.pypy.org Wed Feb 20 15:57:26 2013 From: noreply at buildbot.pypy.org (cfbolz) Date: Wed, 20 Feb 2013 15:57:26 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: these are safe Message-ID: <20130220145726.497ED1C061A@cobra.cs.uni-duesseldorf.de> Author: Carl Friedrich Bolz Branch: Changeset: r72:2708bf50a548 Date: 2013-02-20 15:54 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/2708bf50a548/ Log: these are safe diff --git a/spyvm/shadow.py b/spyvm/shadow.py --- a/spyvm/shadow.py +++ b/spyvm/shadow.py @@ -526,6 +526,7 @@ def stackdepth(self): return rarithmetic.intmask(self._stack_ptr - self.tempsize()) + @jit.unroll_safe def pop_and_return_n(self, n): result = [self.peek(i) for i in range(n - 1, -1, -1)] self.pop_n(n) @@ -637,6 +638,7 @@ ContextPartShadow.__init__(self, space, w_self) @staticmethod + @jit.unroll_safe def make_context(space, w_method, w_receiver, arguments, w_sender=None): # From blue book: normal mc have place for 12 temps+maxstack From noreply at buildbot.pypy.org Wed Feb 20 15:57:27 2013 From: noreply at buildbot.pypy.org (cfbolz) Date: Wed, 20 Feb 2013 15:57:27 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: merge Message-ID: <20130220145727.614281C061A@cobra.cs.uni-duesseldorf.de> Author: Carl Friedrich Bolz Branch: Changeset: r73:13fb55f6a092 Date: 2013-02-20 15:56 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/13fb55f6a092/ Log: merge diff --git a/spyvm/interpreter.py b/spyvm/interpreter.py --- a/spyvm/interpreter.py +++ b/spyvm/interpreter.py @@ -370,7 +370,7 @@ self.pop() # closure bytecodes - def pushNewArrayPopIntoArray(self, interp): + def pushNewArrayBytecode(self, interp): arraySize, popIntoArray = splitter[7, 1](self.getbytecode()) newArray = None if popIntoArray == 1: @@ -388,19 +388,19 @@ w_indirectTemps = self.gettemp(index_of_array) return index_in_array, w_indirectTemps - def pushTempAtInTempVectorAt(self, interp): + def pushRemoteTempLongBytecode(self, interp): index_in_array, w_indirectTemps = self._extract_index_and_temps() self.push(w_indirectTemps.at0(self.space, index_in_array)) - def storeTempAtInTempVectorAt(self, interp): + def storeRemoteTempLongBytecode(self, interp): index_in_array, w_indirectTemps = self._extract_index_and_temps() w_indirectTemps.atput0(self.space, index_in_array, self.top()) - def popAndStoreTempAtInTempVectorAt(self, interp): + def storeAndPopRemoteTempLongBytecode(self, interp): index_in_array, w_indirectTemps = self._extract_index_and_temps() w_indirectTemps.atput0(self.space, index_in_array, self.pop()) - def pushClosureNumCopiedNumArgsBlockSize(self, interp): + def pushClosureCopyCopiedValuesBytecode(self, interp): """ Copied from Blogpost: http://www.mirandabanda.org/cogblog/2008/07/22/closures-part-ii-the-bytecodes/ ContextPart>>pushClosureCopyNumCopiedValues: numCopied numArgs: numArgs blockSize: blockSize "Simulate the action of a 'closure copy' bytecode whose result is the @@ -427,16 +427,8 @@ i = self.getbytecode() blockSize = (j << 8) | i #create new instance of BlockClosure - BlockClosureShadow = space.w_BlockClosure.as_class_get_shadow(space) - w_closure = BlockClosureShadow.new(numCopied) - closure = wrapper.BlockClosureWrapper(space, w_closure) - closure.store_outerContext(self._w_self) - closure.store_startpc(self.pc()) - closure.store_numArgs(numArgs) - if numCopied > 0: - copiedValues = self.pop_and_return_n(numCopied) - for i0 in range(numCopied): - closure.atput0(i0, copiedValues[i0]) + w_closure, closure = space.newClosure(self._w_self, self.pc(), numArgs, + self.pop_and_return_n(numCopied)) self.push(w_closure) self.jump(blockSize) @@ -572,12 +564,12 @@ (135, "popStackBytecode"), (136, "duplicateTopBytecode"), (137, "pushActiveContextBytecode"), - (138, "pushNewArrayPopIntoArray"), + (138, "pushNewArrayBytecode"), (139, "experimentalBytecode"), - (140, "pushTempAtInTempVectorAt"), - (141, "storeTempAtInTempVectorAt"), - (142, "popAndStoreTempAtInTempVectorAt"), - (143, "pushClosureNumCopiedNumArgsBlockSize"), + (140, "pushRemoteTempLongBytecode"), + (141, "storeRemoteTempLongBytecode"), + (142, "storeAndPopRemoteTempLongBytecode"), + (143, "pushClosureCopyCopiedValuesBytecode"), (144, 151, "shortUnconditionalJump"), (152, 159, "shortConditionalJump"), (160, 167, "longUnconditionalJump"), diff --git a/spyvm/objspace.py b/spyvm/objspace.py --- a/spyvm/objspace.py +++ b/spyvm/objspace.py @@ -1,6 +1,4 @@ -from spyvm import constants -from spyvm import model -from spyvm import shadow +from spyvm import constants, model, shadow, wrapper from spyvm.error import UnwrappingError, WrappingError from rpython.rlib.objectmodel import instantiate from rpython.rlib.rarithmetic import intmask, r_uint @@ -254,9 +252,27 @@ elif isinstance(w_v, model.W_SmallInteger): return float(w_v.value) raise UnwrappingError() + def unwrap_array(self, w_array): + # Check that our argument has pointers format and the class: + if not w_array.getclass(self).is_same_object(self.w_Array): + raise PrimitiveFailedError() + assert isinstance(w_array, model.W_PointersObject) + + return [w_array.at0(self, i) for i in range(w_array.size())] + def _freeze_(self): return True + def newClosure(self, outerContext, pc, numArgs, copiedValues): + BlockClosureShadow = self.w_BlockClosure.as_class_get_shadow(self) + w_closure = BlockClosureShadow.new(len(copiedValues)) + closure = wrapper.BlockClosureWrapper(self, w_closure) + closure.store_outerContext(outerContext) + closure.store_startpc(pc) + closure.store_numArgs(numArgs) + for i0 in range(len(copiedValues)): + closure.atput0(i0, copiedValues[i0]) + return w_closure, closure def bootstrap_class(space, instsize, w_superclass=None, w_metaclass=None, name='?', format=shadow.POINTERS, varsized=False): diff --git a/spyvm/primitives.py b/spyvm/primitives.py --- a/spyvm/primitives.py +++ b/spyvm/primitives.py @@ -97,6 +97,9 @@ elif spec is str: assert isinstance(w_arg, model.W_BytesObject) args += (w_arg.as_string(), ) + elif spec is list: + assert isinstance(w_arg, model.W_PointersObject) + args += (interp.space.unwrap_array(w_arg), ) elif spec is char: args += (unwrap_char(w_arg), ) else: @@ -829,25 +832,20 @@ frame.pop() finalize_block_ctx(interp, s_block_ctx, frame.w_self()) - at expose_primitive(VALUE_WITH_ARGS, unwrap_spec=[object, object], + at expose_primitive(VALUE_WITH_ARGS, unwrap_spec=[object, list], no_result=True) -def func(interp, w_block_ctx, w_args): +def func(interp, w_block_ctx, args_w): assert isinstance(w_block_ctx, model.W_PointersObject) s_block_ctx = w_block_ctx.as_blockcontext_get_shadow(interp.space) exp_arg_cnt = s_block_ctx.expected_argument_count() - # Check that our arguments have pointers format and the right size: - if not w_args.getclass(interp.space).is_same_object( - interp.space.w_Array): - raise PrimitiveFailedError() - if w_args.size() != exp_arg_cnt: + if len(args_w) != exp_arg_cnt: raise PrimitiveFailedError() - assert isinstance(w_args, model.W_PointersObject) # Push all the items from the array for i in range(exp_arg_cnt): - s_block_ctx.push(w_args.at0(interp.space, i)) + s_block_ctx.push(args_w[i]) # XXX Check original logic. Image does not test this anyway # because falls back to value + internal implementation @@ -913,6 +911,80 @@ return w_rcvr # ___________________________________________________________________________ +# BlockClosure Primitives + +CLOSURE_COPY_WITH_COPIED_VALUES = 200 +CLOSURE_VALUE = 201 +CLOSURE_VALUE_ = 202 +CLOSURE_VALUE_VALUE = 203 +CLOSURE_VALUE_VALUE_VALUE = 204 +CLOSURE_VALUE_VALUE_VALUE_VALUE = 205 +CLOSURE_VALUE_WITH_ARGS = 206 #valueWithArguments: +CLOSURE_VALUE_NO_CONTEXT_SWITCH = 221 +CLOSURE_VALUE_NO_CONTEXT_SWITCH_ = 222 + + at expose_primitive(CLOSURE_COPY_WITH_COPIED_VALUES, unwrap_spec=[object, int, list]) +def func(interp, outerContext, numArgs, copiedValues): + frame = interp.s_active_context() + w_context, s_context = interp.space.newClosure(outerContext, frame.pc(), + numArgs, copiedValues) + frame.push(w_context) + + +def activateClosure(w_block_closure, args_w, mayContextSwitch=True): + if not w_block_closure.getclass(interp.space).is_same_object( + interp.space.w_BlockClosure): + raise PrimitiveFailedError() + if not w_block_closure.numArgs == len(args_w): + raise PrimitiveFailedError() + if not w_block_closure.outerContext.getclass(interp.space).issubclass( + interp.space.w_ContextPart): + raise PrimitiveFailedError() + w_closureMethod = w_block_closure.w_method() + assert isinstance(w_closureMethod, W_CompiledMethod) + assert w_block_closure is not w_block_closure.outerContext + numCopied = w_block_closure.size() + + s_block_closure = w_block_closure.as_blockclosure_get_shadow(interp.space) + s_block_closure.push_all(args_w) + + s_block_closure.store_pc(s_block_closure.initialip()) + s_block_closure.store_w_sender(frame) + + + at expose_primitive(CLOSURE_VALUE, unwrap_spec=[object]) +def func(interp, w_block_closure): + activateClosure(w_block_closure, []) + + at expose_primitive(CLOSURE_VALUE_, unwrap_spec=[object, object]) +def func(interp, w_block_closure, w_a0): + activateClosure(w_block_closure, [w_a0]) + + at expose_primitive(CLOSURE_VALUE_VALUE, unwrap_spec=[object, object, object]) +def func(interp, w_block_closure, w_a0, w_a1): + activateClosure(w_block_closure, [w_a0, w_a1]) + + at expose_primitive(CLOSURE_VALUE_VALUE_VALUE, unwrap_spec=[object, object, object, object]) +def func(interp, w_block_closure, w_a0, w_a1, w_a2): + activateClosure(w_block_closure, [w_a0, w_a1, w_a2]) + + at expose_primitive(CLOSURE_VALUE_VALUE_VALUE_VALUE, unwrap_spec=[object, object, object, object, object]) +def func(interp, w_block_closure, w_a0, w_a1, w_a2, w_a3): + activateClosure(w_block_closure, [w_a0, w_a1, w_a2, w_a3]) + + at expose_primitive(CLOSURE_VALUE_WITH_ARGS, unwrap_spec=[object, list]) +def func(interp, w_block_closure, args_w): + activateClosure(w_block_closure, args_w) + + at expose_primitive(CLOSURE_VALUE_NO_CONTEXT_SWITCH, unwrap_spec=[object]) +def func(interp, w_block_closure): + activateClosure(w_block_closure, [], mayContextSwitch=False) + + at expose_primitive(CLOSURE_VALUE_NO_CONTEXT_SWITCH_, unwrap_spec=[object, object]) +def func(interp, w_block_closure, w_a0): + activateClosure(w_block_closure, [w_a0], mayContextSwitch=False) + +# ___________________________________________________________________________ # PrimitiveLoadInstVar # # These are some wacky bytecodes in squeak. They are defined to do diff --git a/spyvm/test/test_interpreter.py b/spyvm/test/test_interpreter.py --- a/spyvm/test/test_interpreter.py +++ b/spyvm/test/test_interpreter.py @@ -831,7 +831,7 @@ option.bc_trace = bc_trace # Closure Bytecodes -def test_bc_pushNewArrayPopIntoArray(bytecode=pushNewArrayPopIntoArray): +def test_bc_pushNewArrayBytecode(bytecode=pushNewArrayBytecode): interp = new_interpreter(bytecode + chr(0x83)) context = interp.s_active_context() context.push(fakeliterals(space, "egg")) @@ -843,7 +843,7 @@ assert array.at0(space, 1) == fakeliterals(space, "bar") assert array.at0(space, 2) == fakeliterals(space, "baz") -def test_bc_pushNewArray(bytecode=pushNewArrayPopIntoArray): +def test_bc_pushNewArray(bytecode=pushNewArrayBytecode): interp = new_interpreter(bytecode + chr(0x07)) context = interp.s_active_context() interp.step(interp.s_active_context()) @@ -851,7 +851,7 @@ assert array.size() == 7 assert array.at0(space, 0) == space.w_nil -def test_pushTempAt0InTempVectorAt0(bytecode = pushTempAtInTempVectorAt): +def test_bc_pushRemoteTempLongBytecode(bytecode = pushRemoteTempLongBytecode): interp = new_interpreter(bytecode + chr(0) + chr(0)) context = interp.s_active_context() context.push(fakeliterals(space, "jam")) @@ -871,21 +871,21 @@ interp.step(context) return context, temp_array -def test_pushTempAt3InTempVectorAt1(bytecode = pushTempAtInTempVectorAt): +def test_bc_pushRemoteTempLongBytecode2(bytecode = pushRemoteTempLongBytecode): context, _ = setupTempArrayAndContext(bytecode) assert context.top() == fakeliterals(space, "pub") -def test_storeTempAtInTempVectorAt(bytecode = storeTempAtInTempVectorAt): +def test_bc_storeRemoteTempLongBytecode(bytecode = storeRemoteTempLongBytecode): context, temp_array = setupTempArrayAndContext(bytecode) assert context.top() == fakeliterals(space, "bar") assert temp_array.at0(space, 2) == fakeliterals(space, "bar") -def test_popAndStoreTempAtInTempVectorAt(bytecode = popAndStoreTempAtInTempVectorAt): +def test_bc_storeAndPopRemoteTempLongBytecode(bytecode = storeAndPopRemoteTempLongBytecode): context, temp_array = setupTempArrayAndContext(bytecode) assert temp_array.at0(space, 2) == fakeliterals(space, "bar") assert context.top() == fakeliterals(space, "english") -def test_pushClosureNumCopied0NumArgsBlockSize(bytecode = pushClosureNumCopiedNumArgsBlockSize): +def test_bc_pushClosureCopyCopied0ValuesBytecode(bytecode = pushClosureCopyCopiedValuesBytecode): for i in (0, 0xF0, 0x0FF0, 0xFFF0): interp = new_interpreter(bytecode + chr(2) + chr(i >> 8) + chr(i & 0xFF)) context = interp.s_active_context() @@ -897,7 +897,7 @@ assert closure.startpc() == pc + 4 assert closure.outerContext() is context._w_self -def test_pushClosureNumCopied2NumArgsBlockSize(bytecode = pushClosureNumCopiedNumArgsBlockSize): +def test_bc_pushClosureCopyCopied2ValuesBytecode(bytecode = pushClosureCopyCopiedValuesBytecode): interp = new_interpreter(bytecode + chr(0x23) + chr(0) + chr(0)) context = interp.s_active_context() context.push("english") diff --git a/spyvm/test/test_primitives.py b/spyvm/test/test_primitives.py --- a/spyvm/test/test_primitives.py +++ b/spyvm/test/test_primitives.py @@ -30,6 +30,7 @@ if isinstance(x, model.W_Object): return x if isinstance(x, str) and len(x) == 1: return space.wrap_char(x) if isinstance(x, str): return space.wrap_string(x) + if isinstance(x, list): return space.wrap_list(x) raise NotImplementedError def mock(stack): diff --git a/spyvm/todo.txt b/spyvm/todo.txt --- a/spyvm/todo.txt +++ b/spyvm/todo.txt @@ -22,5 +22,3 @@ Shadows: [ ] Fix invalidation of methoddictshadow when the w_self of its values array changes -Lars ToDo -[ ] different image with BlockClosure instead of BlockContext From noreply at buildbot.pypy.org Wed Feb 20 16:11:08 2013 From: noreply at buildbot.pypy.org (cfbolz) Date: Wed, 20 Feb 2013 16:11:08 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: fix some problems, but then give up and just raise an error instead. Tests! Message-ID: <20130220151108.CA7291C0041@cobra.cs.uni-duesseldorf.de> Author: Carl Friedrich Bolz Branch: Changeset: r74:bef2b64e6be7 Date: 2013-02-20 16:10 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/bef2b64e6be7/ Log: fix some problems, but then give up and just raise an error instead. Tests! diff --git a/spyvm/primitives.py b/spyvm/primitives.py --- a/spyvm/primitives.py +++ b/spyvm/primitives.py @@ -931,7 +931,8 @@ frame.push(w_context) -def activateClosure(w_block_closure, args_w, mayContextSwitch=True): +def activateClosure(interp, w_block_closure, args_w, mayContextSwitch=True): + raise PrimitiveFailedError if not w_block_closure.getclass(interp.space).is_same_object( interp.space.w_BlockClosure): raise PrimitiveFailedError() @@ -941,7 +942,7 @@ interp.space.w_ContextPart): raise PrimitiveFailedError() w_closureMethod = w_block_closure.w_method() - assert isinstance(w_closureMethod, W_CompiledMethod) + assert isinstance(w_closureMethod, model.W_CompiledMethod) assert w_block_closure is not w_block_closure.outerContext numCopied = w_block_closure.size() @@ -949,40 +950,41 @@ s_block_closure.push_all(args_w) s_block_closure.store_pc(s_block_closure.initialip()) + frame = interp.s_active_context() s_block_closure.store_w_sender(frame) @expose_primitive(CLOSURE_VALUE, unwrap_spec=[object]) def func(interp, w_block_closure): - activateClosure(w_block_closure, []) + activateClosure(interp, w_block_closure, []) @expose_primitive(CLOSURE_VALUE_, unwrap_spec=[object, object]) def func(interp, w_block_closure, w_a0): - activateClosure(w_block_closure, [w_a0]) + activateClosure(interp, w_block_closure, [w_a0]) @expose_primitive(CLOSURE_VALUE_VALUE, unwrap_spec=[object, object, object]) def func(interp, w_block_closure, w_a0, w_a1): - activateClosure(w_block_closure, [w_a0, w_a1]) + activateClosure(interp, w_block_closure, [w_a0, w_a1]) @expose_primitive(CLOSURE_VALUE_VALUE_VALUE, unwrap_spec=[object, object, object, object]) def func(interp, w_block_closure, w_a0, w_a1, w_a2): - activateClosure(w_block_closure, [w_a0, w_a1, w_a2]) + activateClosure(interp, w_block_closure, [w_a0, w_a1, w_a2]) @expose_primitive(CLOSURE_VALUE_VALUE_VALUE_VALUE, unwrap_spec=[object, object, object, object, object]) def func(interp, w_block_closure, w_a0, w_a1, w_a2, w_a3): - activateClosure(w_block_closure, [w_a0, w_a1, w_a2, w_a3]) + activateClosure(interp, w_block_closure, [w_a0, w_a1, w_a2, w_a3]) @expose_primitive(CLOSURE_VALUE_WITH_ARGS, unwrap_spec=[object, list]) def func(interp, w_block_closure, args_w): - activateClosure(w_block_closure, args_w) + activateClosure(interp, w_block_closure, args_w) @expose_primitive(CLOSURE_VALUE_NO_CONTEXT_SWITCH, unwrap_spec=[object]) def func(interp, w_block_closure): - activateClosure(w_block_closure, [], mayContextSwitch=False) + activateClosure(interp, w_block_closure, [], mayContextSwitch=False) @expose_primitive(CLOSURE_VALUE_NO_CONTEXT_SWITCH_, unwrap_spec=[object, object]) def func(interp, w_block_closure, w_a0): - activateClosure(w_block_closure, [w_a0], mayContextSwitch=False) + activateClosure(interp, w_block_closure, [w_a0], mayContextSwitch=False) # ___________________________________________________________________________ # PrimitiveLoadInstVar From noreply at buildbot.pypy.org Wed Feb 20 16:15:55 2013 From: noreply at buildbot.pypy.org (krono) Date: Wed, 20 Feb 2013 16:15:55 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: Refactor image version identification Message-ID: <20130220151555.085161C1439@cobra.cs.uni-duesseldorf.de> Author: Tobias Pape Branch: Changeset: r75:072c0a42c109 Date: 2013-02-20 16:06 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/072c0a42c109/ Log: Refactor image version identification diff --git a/spyvm/squeakimage.py b/spyvm/squeakimage.py --- a/spyvm/squeakimage.py +++ b/spyvm/squeakimage.py @@ -6,19 +6,39 @@ from rpython.rlib import objectmodel -def chrs2int(b): +def chrs2int(b, unsigned): assert len(b) == 4 first = ord(b[0]) # big endian - if first & 0x80 != 0: - first = first - 0x100 - return first << 24 | ord(b[1]) << 16 | ord(b[2]) << 8 | ord(b[3]) + if not unsigned: + if first & 0x80 != 0: + first = first - 0x100 + return (first << 24 | ord(b[1]) << 16 | ord(b[2]) << 8 | ord(b[3])) -def swapped_chrs2int(b): +def swapped_chrs2int(b, unsigned): assert len(b) == 4 first = ord(b[3]) # little endian - if first & 0x80 != 0: - first = first - 0x100 - return first << 24 | ord(b[2]) << 16 | ord(b[1]) << 8 | ord(b[0]) + if not unsigned: + if first & 0x80 != 0: + first = first - 0x100 + return (first << 24 | ord(b[2]) << 16 | ord(b[1]) << 8 | ord(b[0])) + +def chrs2long(b, unsigned): + assert len(b) == 8 + first = ord(b[0]) # big endian + if not unsigned: + if first & 0x80 != 0: + first = first - 0x100 + return ( first << 56 | ord(b[1]) << 48 | ord(b[2]) << 40 | ord(b[3]) << 32 + | ord(b[4]) << 24 | ord(b[5]) << 16 | ord(b[6]) << 8 | ord(b[7]) ) + +def swapped_chrs2long(b, unsigned): + assert len(b) == 8 + first = ord(b[7]) # little endian + if not unsigned: + if first & 0x80 != 0: + first = first - 0x100 + return ( first << 56 | ord(b[6]) << 48 | ord(b[5]) << 40 | ord(b[4]) << 32 + | ord(b[3]) << 24 | ord(b[2]) << 16 | ord(b[1]) << 8 | ord(b[0]) ) # ____________________________________________________________ @@ -32,24 +52,51 @@ self.data = inputfile.read() finally: inputfile.close() - self.swap = False - self.pos = 0 - self.count = 0 + self.reset() def peek(self): if self.pos >= len(self.data): raise IndexError - if self.swap: - return swapped_chrs2int( self.data[self.pos:self.pos+4] ) + data_peek = self.data[self.pos:self.pos + self.word_size] + if self.use_long_read: + if self.swap: + return swapped_chrs2long(data_peek, False) + else: + return chrs2long(data_peek, False) else: - return chrs2int( self.data[self.pos:self.pos+4] ) + if self.swap: + return swapped_chrs2int(data_peek, False) + else: + return chrs2int(data_peek, False) + + def peek_unsigned(self): + if self.pos >= len(self.data): + raise IndexError + data_peek = self.data[self.pos:self.pos + self.word_size] + if self.use_long_read: + if self.swap: + return swapped_chrs2long(data_peek, True) + else: + return chrs2long(data_peek, True) + else: + if self.swap: + return swapped_chrs2int(data_peek, True) + else: + return chrs2int(data_peek, True) + def next(self): integer = self.peek() - self.pos += 4 - self.count += 4 + self.pos += self.word_size + self.count += self.word_size return integer + def reset(self): + self.swap = False + self.pos = 0 + self.count = 0 + self.be_32bit() + def reset_count(self): self.count = 0 @@ -59,25 +106,114 @@ self.pos += jump self.count += jump + def skipwords(self, jump): + self.skipbytes(jump * self.word_size) + assert (self.pos + jump) <= len(self.data) + self.pos += jump + self.count += jump + + + def length(self): + return len(self.data) + def close(self): pass # already closed + def be_64bit(self): + self.word_size = 8 + self.use_long_read = True + + def be_32bit(self): + self.word_size = 4 + self.use_long_read = False class CorruptImageError(Exception): pass +class UnsupportedImageError(Exception): + pass + # ____________________________________________________________ -# XXX hack to read Cog images. -# TODO implement Cog float byte reversal -SUPPORTED_VERSIONS = [6502, 6505] +class ImageVersion(object): + + def __init__(self, magic, is_big_endian, is_64bit, has_closures, has_floats_reversed): + self.magic = magic + self.is_big_endian = is_big_endian + self.is_64bit = is_64bit + self.has_closures = has_closures + self.has_floats_reversed = has_floats_reversed + +image_versions = { + 0x00001966: ImageVersion(6502, True, False, False, False), + 0x66190000: ImageVersion(6502, False, False, False, False), + 0x00001968: ImageVersion(6504, True, False, True, False), + 0x68190000: ImageVersion(6504, False, False, True, False), + 0x00001969: ImageVersion(6505, True, False, True, True ), + 0x69190000: ImageVersion(6505, False, False, True, True ), + 0x000109A0: ImageVersion(68000, True, True, False, False), + 0xA009010000000000: ImageVersion(68000, False, True, False, False), + 0x00000000000109A2: ImageVersion(68002, True, True, True, False), + 0xA209010000000000: ImageVersion(68002, False, True, True, False), + 0x00000000000109A3: ImageVersion(68003, True, True, True, True ), + 0xA309010000000000: ImageVersion(68003, False, True, True, True ), +} + + +def version(magic): + ver = image_versions.get(magic, None) + if ver is None: + raise CorruptImageError + # if ver.is_64bit or ver.has_floats_reversed: + # raise UnsupportedImageError + return ver + +possible_image_offset = 512 + +def version_from_stream(stream): + # 32 bit + try: + return version(stream.peek_unsigned()) + except CorruptImageError as e: + if stream.length() > possible_image_offset + 4: + stream.skipbytes(possible_image_offset) + try: + return version(stream.peek_unsigned()) + except CorruptImageError: + pass # raise original error + # 64 bit + stream.reset() + stream.be_64bit() + try: + v = version(stream.peek_unsigned()) + assert v.is_64bit + return v + except CorruptImageError as e: + if stream.length() > possible_image_offset + 4: + stream.skipbytes(possible_image_offset) + try: + v = version(stream.peek_unsigned()) + assert v.is_64bit + return v + except CorruptImageError: + pass # raise original error + raise + + + +def reader_for_image(space, stream): + ver = version_from_stream(stream) + if not ver.is_big_endian: + stream.swap = True + return ImageReader(space, stream, ver) class ImageReader(object): - def __init__(self, space, stream): + def __init__(self, space, stream, version): self.space = space self.stream = stream + self.version = version # dictionary mapping old address to chunk object self.chunks = {} self.chunklist = [] @@ -94,15 +230,13 @@ self.init_w_objects() self.fillin_w_objects() + def read_version(self): + # 1 word version + magic = self.stream.next() + assert self.version.magic == magic + def read_header(self): - # 1 word version - version = self.stream.peek() - if version not in SUPPORTED_VERSIONS: - self.stream.swap = True - version = self.stream.peek() - if version not in SUPPORTED_VERSIONS: - raise CorruptImageError - version = self.stream.next() + self.read_version() #------ # 1 word headersize headersize = self.stream.next() @@ -118,8 +252,7 @@ print "savedwindowssize", savedwindowssize fullscreenflag = self.stream.next() extravmmemory = self.stream.next() - # we called 9 times next, 1 word = 4 byte - self.stream.skipbytes(headersize - (9 * 4)) + self.stream.skipbytes(headersize - self.stream.pos) def read_body(self): import sys diff --git a/spyvm/test/test_miniimage.py b/spyvm/test/test_miniimage.py --- a/spyvm/test/test_miniimage.py +++ b/spyvm/test/test_miniimage.py @@ -21,7 +21,7 @@ module.space = space def open_miniimage(space): - return squeakimage.ImageReader(space, squeakimage.Stream(mini_image.open())) + return squeakimage.reader_for_image(space, squeakimage.Stream(mini_image.open())) def get_reader(): return reader diff --git a/spyvm/test/test_squeakimage.py b/spyvm/test/test_squeakimage.py --- a/spyvm/test/test_squeakimage.py +++ b/spyvm/test/test_squeakimage.py @@ -1,15 +1,16 @@ import py from spyvm import squeakimage -from spyvm.squeakimage import chrs2int +from spyvm.squeakimage import chrs2int, chrs2long, swapped_chrs2long from spyvm import objspace +from struct import pack + space = objspace.ObjSpace() # ----- helpers ---------------------------------------------- def ints2str(*ints): - import struct - return struct.pack(">" + "i" * len(ints), *ints) + return pack(">" + "i" * len(ints), *ints) def joinbits(values, lengths): result = 0 @@ -18,21 +19,37 @@ result += each return result -def imagereader_mock(string): +def imagestream_mock(string): import StringIO f = StringIO.StringIO(string) - stream = squeakimage.Stream(f) - return squeakimage.ImageReader(space, stream) + return squeakimage.Stream(f) +def imagereader_mock(string): + stream = imagestream_mock(string) + return squeakimage.reader_for_image(space, stream) + + +SIMPLE_VERSION_HEADER = pack(">i", 6502) +SIMPLE_VERSION_HEADER_LE = pack("Q", 68002), False) + assert 68002 == swapped_chrs2long(pack("i", header_size) # 2 64 byte header + + pack(">i", 0) # 3 no body + + pack(">i", 0) # 4 old base addresss unset + + pack(">i", 0) # 5 no spl objs array + + "\x12\x34\x56\x78" # 6 last hash + + pack(">h", 480) # 7 window 480 height + + pack(">h", 640) # window 640 width + + pack(">i", 0) # 8 not fullscreen + + pack(">i", 0) # 9 no extra memory + + ("\x00" * (header_size - (9 * word_size)))) + r = imagereader_mock(image_1) + # does not raise + r.read_header() + assert r.stream.pos == len(image_1) + + image_2 = (SIMPLE_VERSION_HEADER_LE # 1 + + pack("Q", 68002) # 1 version + + pack(">q", header_size) # 2 64 byte header + + pack(">q", 0) # 3 no body + + pack(">q", 0) # 4 old base addresss unset + + pack(">q", 0) # 5 no spl objs array + + ("\x12\x34\x56\x78" * 2)# 6 last hash + + pack(">H", 480) # 7 window 480 height + + pack(">H", 640) # window 640 width + + pack(">i", 0) # pad + + pack(">q", 0) # 8 not fullscreen + + pack(">q", 0) # 9 no extra memory + + ("\x00" * (header_size - (9 * word_size)))) + r = imagereader_mock(image_1) + # does not raise + r.read_header() + assert r.stream.pos == len(image_1) + + image_2 = (pack("i", 0) # pad + + pack(">q", 0) # 8 not fullscreen + + pack("" return -1 - reader = squeakimage.ImageReader(space, squeakimage.Stream(DummyFile(filename))) + reader = squeakimage.reader_for_image(space, squeakimage.Stream(DummyFile(filename))) reader.initialize() image = squeakimage.SqueakImage() image.from_reader(space, reader) From noreply at buildbot.pypy.org Wed Feb 20 16:15:56 2013 From: noreply at buildbot.pypy.org (krono) Date: Wed, 20 Feb 2013 16:15:56 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: merge Message-ID: <20130220151556.3EFA91C1439@cobra.cs.uni-duesseldorf.de> Author: Tobias Pape Branch: Changeset: r76:77ba2d81ffc9 Date: 2013-02-20 16:09 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/77ba2d81ffc9/ Log: merge diff --git a/spyvm/fixedstack.py b/spyvm/fixedstack.py deleted file mode 100644 --- a/spyvm/fixedstack.py +++ /dev/null @@ -1,68 +0,0 @@ -""" -A Fixed stack for SPy. -""" - -import types - -from rpython.rlib import jit -from rpython.rlib.rarithmetic import r_uint - -class FixedStack(object): - # _annspecialcase_ = "specialize:ctr_location" # polymorphic - - def __init__(self): - pass - - def setup(self, stacksize): - self.ptr = r_uint(0) # we point after the last element - self.items = [None] * stacksize - - def clone(self): - # this is only needed if we support flow space - s = self.__class__() - s.setup(len(self.items)) - for item in self.items[:self.ptr]: - try: - item = item.clone() - except AttributeError: - pass - s.push(item) - return s - - def push(self, item): - ptr = jit.promote(self.ptr) - self.items[ptr] = item - self.ptr = ptr + 1 - - def pop(self): - ptr = jit.promote(self.ptr) - 1 - ret = self.items[ptr] # you get OverflowError if the stack is empty - self.items[ptr] = None - self.ptr = ptr - return ret - - @jit.unroll_safe - def drop(self, n): - jit.promote(self.ptr) - while n > 0: - n -= 1 - self.ptr -= 1 - self.items[self.ptr] = None - - def top(self, position=0): - # for a fixed stack, we assume correct indices - rpos = r_uint(position) - return self.items[self.ptr + ~rpos] - - def set_top(self, value, position=0): - # for a fixed stack, we assume correct indices - rpos = r_uint(position) - self.items[self.ptr + ~rpos] = value - - def depth(self): - return self.ptr - - def empty(self): - return not self.ptr - - diff --git a/spyvm/interpreter.py b/spyvm/interpreter.py --- a/spyvm/interpreter.py +++ b/spyvm/interpreter.py @@ -370,7 +370,7 @@ self.pop() # closure bytecodes - def pushNewArrayPopIntoArray(self, interp): + def pushNewArrayBytecode(self, interp): arraySize, popIntoArray = splitter[7, 1](self.getbytecode()) newArray = None if popIntoArray == 1: @@ -388,19 +388,19 @@ w_indirectTemps = self.gettemp(index_of_array) return index_in_array, w_indirectTemps - def pushTempAtInTempVectorAt(self, interp): + def pushRemoteTempLongBytecode(self, interp): index_in_array, w_indirectTemps = self._extract_index_and_temps() self.push(w_indirectTemps.at0(self.space, index_in_array)) - def storeTempAtInTempVectorAt(self, interp): + def storeRemoteTempLongBytecode(self, interp): index_in_array, w_indirectTemps = self._extract_index_and_temps() w_indirectTemps.atput0(self.space, index_in_array, self.top()) - def popAndStoreTempAtInTempVectorAt(self, interp): + def storeAndPopRemoteTempLongBytecode(self, interp): index_in_array, w_indirectTemps = self._extract_index_and_temps() w_indirectTemps.atput0(self.space, index_in_array, self.pop()) - def pushClosureNumCopiedNumArgsBlockSize(self, interp): + def pushClosureCopyCopiedValuesBytecode(self, interp): """ Copied from Blogpost: http://www.mirandabanda.org/cogblog/2008/07/22/closures-part-ii-the-bytecodes/ ContextPart>>pushClosureCopyNumCopiedValues: numCopied numArgs: numArgs blockSize: blockSize "Simulate the action of a 'closure copy' bytecode whose result is the @@ -427,16 +427,8 @@ i = self.getbytecode() blockSize = (j << 8) | i #create new instance of BlockClosure - BlockClosureShadow = space.w_BlockClosure.as_class_get_shadow(space) - w_closure = BlockClosureShadow.new(numCopied) - closure = wrapper.BlockClosureWrapper(space, w_closure) - closure.store_outerContext(self._w_self) - closure.store_startpc(self.pc()) - closure.store_numArgs(numArgs) - if numCopied > 0: - copiedValues = self.pop_and_return_n(numCopied) - for i0 in range(numCopied): - closure.atput0(i0, copiedValues[i0]) + w_closure, closure = space.newClosure(self._w_self, self.pc(), numArgs, + self.pop_and_return_n(numCopied)) self.push(w_closure) self.jump(blockSize) @@ -572,12 +564,12 @@ (135, "popStackBytecode"), (136, "duplicateTopBytecode"), (137, "pushActiveContextBytecode"), - (138, "pushNewArrayPopIntoArray"), + (138, "pushNewArrayBytecode"), (139, "experimentalBytecode"), - (140, "pushTempAtInTempVectorAt"), - (141, "storeTempAtInTempVectorAt"), - (142, "popAndStoreTempAtInTempVectorAt"), - (143, "pushClosureNumCopiedNumArgsBlockSize"), + (140, "pushRemoteTempLongBytecode"), + (141, "storeRemoteTempLongBytecode"), + (142, "storeAndPopRemoteTempLongBytecode"), + (143, "pushClosureCopyCopiedValuesBytecode"), (144, 151, "shortUnconditionalJump"), (152, 159, "shortConditionalJump"), (160, 167, "longUnconditionalJump"), diff --git a/spyvm/model.py b/spyvm/model.py --- a/spyvm/model.py +++ b/spyvm/model.py @@ -308,10 +308,9 @@ @objectmodel.specialize.arg(2) def as_special_get_shadow(self, space, TheClass): shadow = self._shadow - if shadow is None: - shadow = self.attach_shadow_of_class(space, TheClass) - elif not isinstance(shadow, TheClass): - shadow.detach_shadow() + if not isinstance(shadow, TheClass): + if shadow is not None: + shadow.detach_shadow() shadow = self.attach_shadow_of_class(space, TheClass) shadow.sync_shadow() return shadow diff --git a/spyvm/objspace.py b/spyvm/objspace.py --- a/spyvm/objspace.py +++ b/spyvm/objspace.py @@ -1,6 +1,4 @@ -from spyvm import constants -from spyvm import model -from spyvm import shadow +from spyvm import constants, model, shadow, wrapper from spyvm.error import UnwrappingError, WrappingError from rpython.rlib.objectmodel import instantiate from rpython.rlib.rarithmetic import intmask, r_uint @@ -254,9 +252,27 @@ elif isinstance(w_v, model.W_SmallInteger): return float(w_v.value) raise UnwrappingError() + def unwrap_array(self, w_array): + # Check that our argument has pointers format and the class: + if not w_array.getclass(self).is_same_object(self.w_Array): + raise PrimitiveFailedError() + assert isinstance(w_array, model.W_PointersObject) + + return [w_array.at0(self, i) for i in range(w_array.size())] + def _freeze_(self): return True + def newClosure(self, outerContext, pc, numArgs, copiedValues): + BlockClosureShadow = self.w_BlockClosure.as_class_get_shadow(self) + w_closure = BlockClosureShadow.new(len(copiedValues)) + closure = wrapper.BlockClosureWrapper(self, w_closure) + closure.store_outerContext(outerContext) + closure.store_startpc(pc) + closure.store_numArgs(numArgs) + for i0 in range(len(copiedValues)): + closure.atput0(i0, copiedValues[i0]) + return w_closure, closure def bootstrap_class(space, instsize, w_superclass=None, w_metaclass=None, name='?', format=shadow.POINTERS, varsized=False): diff --git a/spyvm/primitives.py b/spyvm/primitives.py --- a/spyvm/primitives.py +++ b/spyvm/primitives.py @@ -97,6 +97,9 @@ elif spec is str: assert isinstance(w_arg, model.W_BytesObject) args += (w_arg.as_string(), ) + elif spec is list: + assert isinstance(w_arg, model.W_PointersObject) + args += (interp.space.unwrap_array(w_arg), ) elif spec is char: args += (unwrap_char(w_arg), ) else: @@ -829,25 +832,20 @@ frame.pop() finalize_block_ctx(interp, s_block_ctx, frame.w_self()) - at expose_primitive(VALUE_WITH_ARGS, unwrap_spec=[object, object], + at expose_primitive(VALUE_WITH_ARGS, unwrap_spec=[object, list], no_result=True) -def func(interp, w_block_ctx, w_args): +def func(interp, w_block_ctx, args_w): assert isinstance(w_block_ctx, model.W_PointersObject) s_block_ctx = w_block_ctx.as_blockcontext_get_shadow(interp.space) exp_arg_cnt = s_block_ctx.expected_argument_count() - # Check that our arguments have pointers format and the right size: - if not w_args.getclass(interp.space).is_same_object( - interp.space.w_Array): - raise PrimitiveFailedError() - if w_args.size() != exp_arg_cnt: + if len(args_w) != exp_arg_cnt: raise PrimitiveFailedError() - assert isinstance(w_args, model.W_PointersObject) # Push all the items from the array for i in range(exp_arg_cnt): - s_block_ctx.push(w_args.at0(interp.space, i)) + s_block_ctx.push(args_w[i]) # XXX Check original logic. Image does not test this anyway # because falls back to value + internal implementation @@ -913,6 +911,80 @@ return w_rcvr # ___________________________________________________________________________ +# BlockClosure Primitives + +CLOSURE_COPY_WITH_COPIED_VALUES = 200 +CLOSURE_VALUE = 201 +CLOSURE_VALUE_ = 202 +CLOSURE_VALUE_VALUE = 203 +CLOSURE_VALUE_VALUE_VALUE = 204 +CLOSURE_VALUE_VALUE_VALUE_VALUE = 205 +CLOSURE_VALUE_WITH_ARGS = 206 #valueWithArguments: +CLOSURE_VALUE_NO_CONTEXT_SWITCH = 221 +CLOSURE_VALUE_NO_CONTEXT_SWITCH_ = 222 + + at expose_primitive(CLOSURE_COPY_WITH_COPIED_VALUES, unwrap_spec=[object, int, list]) +def func(interp, outerContext, numArgs, copiedValues): + frame = interp.s_active_context() + w_context, s_context = interp.space.newClosure(outerContext, frame.pc(), + numArgs, copiedValues) + frame.push(w_context) + + +def activateClosure(w_block_closure, args_w, mayContextSwitch=True): + if not w_block_closure.getclass(interp.space).is_same_object( + interp.space.w_BlockClosure): + raise PrimitiveFailedError() + if not w_block_closure.numArgs == len(args_w): + raise PrimitiveFailedError() + if not w_block_closure.outerContext.getclass(interp.space).issubclass( + interp.space.w_ContextPart): + raise PrimitiveFailedError() + w_closureMethod = w_block_closure.w_method() + assert isinstance(w_closureMethod, W_CompiledMethod) + assert w_block_closure is not w_block_closure.outerContext + numCopied = w_block_closure.size() + + s_block_closure = w_block_closure.as_blockclosure_get_shadow(interp.space) + s_block_closure.push_all(args_w) + + s_block_closure.store_pc(s_block_closure.initialip()) + s_block_closure.store_w_sender(frame) + + + at expose_primitive(CLOSURE_VALUE, unwrap_spec=[object]) +def func(interp, w_block_closure): + activateClosure(w_block_closure, []) + + at expose_primitive(CLOSURE_VALUE_, unwrap_spec=[object, object]) +def func(interp, w_block_closure, w_a0): + activateClosure(w_block_closure, [w_a0]) + + at expose_primitive(CLOSURE_VALUE_VALUE, unwrap_spec=[object, object, object]) +def func(interp, w_block_closure, w_a0, w_a1): + activateClosure(w_block_closure, [w_a0, w_a1]) + + at expose_primitive(CLOSURE_VALUE_VALUE_VALUE, unwrap_spec=[object, object, object, object]) +def func(interp, w_block_closure, w_a0, w_a1, w_a2): + activateClosure(w_block_closure, [w_a0, w_a1, w_a2]) + + at expose_primitive(CLOSURE_VALUE_VALUE_VALUE_VALUE, unwrap_spec=[object, object, object, object, object]) +def func(interp, w_block_closure, w_a0, w_a1, w_a2, w_a3): + activateClosure(w_block_closure, [w_a0, w_a1, w_a2, w_a3]) + + at expose_primitive(CLOSURE_VALUE_WITH_ARGS, unwrap_spec=[object, list]) +def func(interp, w_block_closure, args_w): + activateClosure(w_block_closure, args_w) + + at expose_primitive(CLOSURE_VALUE_NO_CONTEXT_SWITCH, unwrap_spec=[object]) +def func(interp, w_block_closure): + activateClosure(w_block_closure, [], mayContextSwitch=False) + + at expose_primitive(CLOSURE_VALUE_NO_CONTEXT_SWITCH_, unwrap_spec=[object, object]) +def func(interp, w_block_closure, w_a0): + activateClosure(w_block_closure, [w_a0], mayContextSwitch=False) + +# ___________________________________________________________________________ # PrimitiveLoadInstVar # # These are some wacky bytecodes in squeak. They are defined to do diff --git a/spyvm/shadow.py b/spyvm/shadow.py --- a/spyvm/shadow.py +++ b/spyvm/shadow.py @@ -317,10 +317,8 @@ __metaclass__ = extendabletype def __init__(self, space, w_self): - from spyvm.fixedstack import FixedStack self._w_sender = space.w_nil - self._stack = FixedStack() self.currentBytecode = -1 AbstractRedirectingShadow.__init__(self, space, w_self) @@ -339,7 +337,7 @@ if n0 == constants.CTXPART_STACKP_INDEX: return self.wrap_stackpointer() if self.stackstart() <= n0 < self.external_stackpointer(): - return self._stack.top(self.stackdepth() - (n0-self.stackstart()) - 1) + return self.peek(self.stackdepth() - (n0-self.stackstart()) - 1) if self.external_stackpointer() <= n0 < self.stackend(): return self.space.w_nil else: @@ -354,7 +352,7 @@ if n0 == constants.CTXPART_STACKP_INDEX: return self.unwrap_store_stackpointer(w_value) if self.stackstart() <= n0 < self.external_stackpointer(): - return self._stack.set_top(w_value, + return self.set_top(w_value, self.stackdepth() - (n0-self.stackstart()) - 1) return if self.external_stackpointer() <= n0 < self.stackend(): @@ -375,10 +373,10 @@ if size < depth: # TODO Warn back to user assert size >= 0 - self._stack.drop(depth - size) + self.pop_n(depth - size) else: for i in range(depth, size): - self._stack.push(self.space.w_nil) + self.push(self.space.w_nil) def wrap_stackpointer(self): return self.space.wrap_int(self.stackdepth() + @@ -475,20 +473,32 @@ def settemp(self, index, w_value): self.s_home().settemp(index, w_value) + @jit.unroll_safe + def init_stack_and_temps(self): + stacksize = self.stackend() - self.stackstart() + tempsize = self.tempsize() + self._temps_and_stack = [None] * (stacksize + tempsize) + for i in range(tempsize): + self._temps_and_stack[i] = self.space.w_nil + self._stack_ptr = rarithmetic.r_uint(tempsize) # we point after the last element + # ______________________________________________________________________ # Stack Manipulation - def init_stack(self): - self._stack.setup(self.stackend() - self.stackstart()) - def stack(self): """NOT_RPYTHON""" # purely for testing - return self._stack.items[:self.stackdepth()] + return self._temps_and_stack[self.tempsize():self._stack_ptr] def pop(self): - return self._stack.pop() + ptr = jit.promote(self._stack_ptr) - 1 + ret = self._temps_and_stack[ptr] # you get OverflowError if the stack is empty + self._temps_and_stack[ptr] = None + self._stack_ptr = ptr + return ret def push(self, w_v): - self._stack.push(w_v) + ptr = jit.promote(self._stack_ptr) + self._temps_and_stack[ptr] = w_v + self._stack_ptr = ptr + 1 def push_all(self, lst): for elt in lst: @@ -496,18 +506,29 @@ def top(self): return self.peek(0) - + + def set_top(self, value, position=0): + rpos = rarithmetic.r_uint(position) + self._temps_and_stack[self._stack_ptr + ~rpos] = value + def peek(self, idx): - return self._stack.top(idx) + rpos = rarithmetic.r_uint(idx) + return self._temps_and_stack[self._stack_ptr + ~rpos] + @jit.unroll_safe def pop_n(self, n): - self._stack.drop(n) + jit.promote(self._stack_ptr) + while n > 0: + n -= 1 + self._stack_ptr -= 1 + self._temps_and_stack[self._stack_ptr] = None def stackdepth(self): - return rarithmetic.intmask(self._stack.depth()) + return rarithmetic.intmask(self._stack_ptr - self.tempsize()) + @jit.unroll_safe def pop_and_return_n(self, n): - result = [self._stack.top(i) for i in range(n - 1, -1, -1)] + result = [self.peek(i) for i in range(n - 1, -1, -1)] self.pop_n(n) return result @@ -533,7 +554,7 @@ s_result.store_initialip(initialip) s_result.store_w_home(w_home) s_result.store_pc(initialip) - s_result.init_stack() + s_result.init_stack_and_temps() return w_result def fetch(self, n0): @@ -559,7 +580,7 @@ def attach_shadow(self): # Make sure the home context is updated first self.copy_from_w_self(constants.BLKCTX_HOME_INDEX) - self.init_stack() + self.init_stack_and_temps() ContextPartShadow.attach_shadow(self) def unwrap_store_initialip(self, w_value): @@ -617,6 +638,7 @@ ContextPartShadow.__init__(self, space, w_self) @staticmethod + @jit.unroll_safe def make_context(space, w_method, w_receiver, arguments, w_sender=None): # From blue book: normal mc have place for 12 temps+maxstack @@ -634,10 +656,9 @@ s_result.store_w_sender(w_sender) s_result.store_w_receiver(w_receiver) s_result.store_pc(0) - s_result._temps = [space.w_nil] * w_method.tempsize + s_result.init_stack_and_temps() for i in range(len(arguments)): s_result.settemp(i, arguments[i]) - s_result.init_stack() return w_result def fetch(self, n0): @@ -672,9 +693,7 @@ def attach_shadow(self): # Make sure the method is updated first self.copy_from_w_self(constants.MTHDCTX_METHOD) - self.init_stack() - # And that there is space for the temps - self._temps = [self.space.w_nil] * self.tempsize() + self.init_stack_and_temps() ContextPartShadow.attach_shadow(self) def tempsize(self): @@ -694,10 +713,10 @@ self._w_receiver = w_receiver def gettemp(self, index0): - return self._temps[index0] + return self._temps_and_stack[index0] def settemp(self, index0, w_value): - self._temps[index0] = w_value + self._temps_and_stack[index0] = w_value def w_home(self): return self.w_self() diff --git a/spyvm/test/test_interpreter.py b/spyvm/test/test_interpreter.py --- a/spyvm/test/test_interpreter.py +++ b/spyvm/test/test_interpreter.py @@ -831,7 +831,7 @@ option.bc_trace = bc_trace # Closure Bytecodes -def test_bc_pushNewArrayPopIntoArray(bytecode=pushNewArrayPopIntoArray): +def test_bc_pushNewArrayBytecode(bytecode=pushNewArrayBytecode): interp = new_interpreter(bytecode + chr(0x83)) context = interp.s_active_context() context.push(fakeliterals(space, "egg")) @@ -843,7 +843,7 @@ assert array.at0(space, 1) == fakeliterals(space, "bar") assert array.at0(space, 2) == fakeliterals(space, "baz") -def test_bc_pushNewArray(bytecode=pushNewArrayPopIntoArray): +def test_bc_pushNewArray(bytecode=pushNewArrayBytecode): interp = new_interpreter(bytecode + chr(0x07)) context = interp.s_active_context() interp.step(interp.s_active_context()) @@ -851,7 +851,7 @@ assert array.size() == 7 assert array.at0(space, 0) == space.w_nil -def test_pushTempAt0InTempVectorAt0(bytecode = pushTempAtInTempVectorAt): +def test_bc_pushRemoteTempLongBytecode(bytecode = pushRemoteTempLongBytecode): interp = new_interpreter(bytecode + chr(0) + chr(0)) context = interp.s_active_context() context.push(fakeliterals(space, "jam")) @@ -871,21 +871,21 @@ interp.step(context) return context, temp_array -def test_pushTempAt3InTempVectorAt1(bytecode = pushTempAtInTempVectorAt): +def test_bc_pushRemoteTempLongBytecode2(bytecode = pushRemoteTempLongBytecode): context, _ = setupTempArrayAndContext(bytecode) assert context.top() == fakeliterals(space, "pub") -def test_storeTempAtInTempVectorAt(bytecode = storeTempAtInTempVectorAt): +def test_bc_storeRemoteTempLongBytecode(bytecode = storeRemoteTempLongBytecode): context, temp_array = setupTempArrayAndContext(bytecode) assert context.top() == fakeliterals(space, "bar") assert temp_array.at0(space, 2) == fakeliterals(space, "bar") -def test_popAndStoreTempAtInTempVectorAt(bytecode = popAndStoreTempAtInTempVectorAt): +def test_bc_storeAndPopRemoteTempLongBytecode(bytecode = storeAndPopRemoteTempLongBytecode): context, temp_array = setupTempArrayAndContext(bytecode) assert temp_array.at0(space, 2) == fakeliterals(space, "bar") assert context.top() == fakeliterals(space, "english") -def test_pushClosureNumCopied0NumArgsBlockSize(bytecode = pushClosureNumCopiedNumArgsBlockSize): +def test_bc_pushClosureCopyCopied0ValuesBytecode(bytecode = pushClosureCopyCopiedValuesBytecode): for i in (0, 0xF0, 0x0FF0, 0xFFF0): interp = new_interpreter(bytecode + chr(2) + chr(i >> 8) + chr(i & 0xFF)) context = interp.s_active_context() @@ -897,7 +897,7 @@ assert closure.startpc() == pc + 4 assert closure.outerContext() is context._w_self -def test_pushClosureNumCopied2NumArgsBlockSize(bytecode = pushClosureNumCopiedNumArgsBlockSize): +def test_bc_pushClosureCopyCopied2ValuesBytecode(bytecode = pushClosureCopyCopiedValuesBytecode): interp = new_interpreter(bytecode + chr(0x23) + chr(0) + chr(0)) context = interp.s_active_context() context.push("english") diff --git a/spyvm/test/test_primitives.py b/spyvm/test/test_primitives.py --- a/spyvm/test/test_primitives.py +++ b/spyvm/test/test_primitives.py @@ -16,7 +16,7 @@ def __init__(self, stack): self._vars = [None] * 6 + stack s_self = self.as_blockcontext_get_shadow() - s_self.init_stack() + s_self.init_stack_and_temps() s_self.reset_stack() s_self.push_all(stack) s_self.store_expected_argument_count(0) @@ -30,6 +30,7 @@ if isinstance(x, model.W_Object): return x if isinstance(x, str) and len(x) == 1: return space.wrap_char(x) if isinstance(x, str): return space.wrap_string(x) + if isinstance(x, list): return space.wrap_list(x) raise NotImplementedError def mock(stack): diff --git a/spyvm/todo.txt b/spyvm/todo.txt --- a/spyvm/todo.txt +++ b/spyvm/todo.txt @@ -22,5 +22,3 @@ Shadows: [ ] Fix invalidation of methoddictshadow when the w_self of its values array changes -Lars ToDo -[ ] different image with BlockClosure instead of BlockContext From noreply at buildbot.pypy.org Wed Feb 20 16:15:57 2013 From: noreply at buildbot.pypy.org (krono) Date: Wed, 20 Feb 2013 16:15:57 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: mege Message-ID: <20130220151557.485981C1439@cobra.cs.uni-duesseldorf.de> Author: Tobias Pape Branch: Changeset: r77:1c23ae6a6081 Date: 2013-02-20 16:15 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/1c23ae6a6081/ Log: mege diff --git a/spyvm/primitives.py b/spyvm/primitives.py --- a/spyvm/primitives.py +++ b/spyvm/primitives.py @@ -931,7 +931,8 @@ frame.push(w_context) -def activateClosure(w_block_closure, args_w, mayContextSwitch=True): +def activateClosure(interp, w_block_closure, args_w, mayContextSwitch=True): + raise PrimitiveFailedError if not w_block_closure.getclass(interp.space).is_same_object( interp.space.w_BlockClosure): raise PrimitiveFailedError() @@ -941,7 +942,7 @@ interp.space.w_ContextPart): raise PrimitiveFailedError() w_closureMethod = w_block_closure.w_method() - assert isinstance(w_closureMethod, W_CompiledMethod) + assert isinstance(w_closureMethod, model.W_CompiledMethod) assert w_block_closure is not w_block_closure.outerContext numCopied = w_block_closure.size() @@ -949,40 +950,41 @@ s_block_closure.push_all(args_w) s_block_closure.store_pc(s_block_closure.initialip()) + frame = interp.s_active_context() s_block_closure.store_w_sender(frame) @expose_primitive(CLOSURE_VALUE, unwrap_spec=[object]) def func(interp, w_block_closure): - activateClosure(w_block_closure, []) + activateClosure(interp, w_block_closure, []) @expose_primitive(CLOSURE_VALUE_, unwrap_spec=[object, object]) def func(interp, w_block_closure, w_a0): - activateClosure(w_block_closure, [w_a0]) + activateClosure(interp, w_block_closure, [w_a0]) @expose_primitive(CLOSURE_VALUE_VALUE, unwrap_spec=[object, object, object]) def func(interp, w_block_closure, w_a0, w_a1): - activateClosure(w_block_closure, [w_a0, w_a1]) + activateClosure(interp, w_block_closure, [w_a0, w_a1]) @expose_primitive(CLOSURE_VALUE_VALUE_VALUE, unwrap_spec=[object, object, object, object]) def func(interp, w_block_closure, w_a0, w_a1, w_a2): - activateClosure(w_block_closure, [w_a0, w_a1, w_a2]) + activateClosure(interp, w_block_closure, [w_a0, w_a1, w_a2]) @expose_primitive(CLOSURE_VALUE_VALUE_VALUE_VALUE, unwrap_spec=[object, object, object, object, object]) def func(interp, w_block_closure, w_a0, w_a1, w_a2, w_a3): - activateClosure(w_block_closure, [w_a0, w_a1, w_a2, w_a3]) + activateClosure(interp, w_block_closure, [w_a0, w_a1, w_a2, w_a3]) @expose_primitive(CLOSURE_VALUE_WITH_ARGS, unwrap_spec=[object, list]) def func(interp, w_block_closure, args_w): - activateClosure(w_block_closure, args_w) + activateClosure(interp, w_block_closure, args_w) @expose_primitive(CLOSURE_VALUE_NO_CONTEXT_SWITCH, unwrap_spec=[object]) def func(interp, w_block_closure): - activateClosure(w_block_closure, [], mayContextSwitch=False) + activateClosure(interp, w_block_closure, [], mayContextSwitch=False) @expose_primitive(CLOSURE_VALUE_NO_CONTEXT_SWITCH_, unwrap_spec=[object, object]) def func(interp, w_block_closure, w_a0): - activateClosure(w_block_closure, [w_a0], mayContextSwitch=False) + activateClosure(interp, w_block_closure, [w_a0], mayContextSwitch=False) # ___________________________________________________________________________ # PrimitiveLoadInstVar From noreply at buildbot.pypy.org Wed Feb 20 16:33:09 2013 From: noreply at buildbot.pypy.org (rguillebert) Date: Wed, 20 Feb 2013 16:33:09 +0100 (CET) Subject: [pypy-commit] pypy default: Return False when comparing two ndarrays which have non-agreeing shapes Message-ID: <20130220153309.F1BAA1C1E4F@cobra.cs.uni-duesseldorf.de> Author: Romain Guillebert Branch: Changeset: r61495:602298f4e786 Date: 2013-02-20 15:34 +0100 http://bitbucket.org/pypy/pypy/changeset/602298f4e786/ Log: Return False when comparing two ndarrays which have non-agreeing shapes diff --git a/pypy/module/micronumpy/interp_numarray.py b/pypy/module/micronumpy/interp_numarray.py --- a/pypy/module/micronumpy/interp_numarray.py +++ b/pypy/module/micronumpy/interp_numarray.py @@ -250,7 +250,7 @@ ret = self.implementation.get_imag(self) if ret: return W_NDimArray(ret) - raise OperationError(space.w_NotImplementedError, + raise OperationError(space.w_NotImplementedError, space.wrap('imag not implemented for this dtype')) def descr_set_real(self, space, w_value): @@ -261,7 +261,7 @@ def descr_set_imag(self, space, w_value): # if possible, copy (broadcast) values into self if not self.get_dtype().is_complex_type(): - raise OperationError(space.w_TypeError, + raise OperationError(space.w_TypeError, space.wrap('array does not have imaginary part to set')) tmp = self.implementation.get_imag(self) tmp.setslice(space, convert_to_array(space, w_value)) @@ -302,11 +302,11 @@ @unwrap_spec(axis1=int, axis2=int) def descr_swapaxes(self, space, axis1, axis2): """a.swapaxes(axis1, axis2) - + Return a view of the array with `axis1` and `axis2` interchanged. - + Refer to `numpy.swapaxes` for full documentation. - + See Also -------- numpy.swapaxes : equivalent function @@ -439,7 +439,7 @@ ret = impl.base() if ret is None: return space.w_None - return ret + return ret @unwrap_spec(inplace=bool) def descr_byteswap(self, space, inplace=False): @@ -492,7 +492,7 @@ "axis1 and axis2 cannot be the same")) return interp_arrayops.diagonal(space, self.implementation, offset, axis1, axis2) - + def descr_dump(self, space, w_file): raise OperationError(space.w_NotImplementedError, space.wrap( "dump not implemented yet")) @@ -509,7 +509,7 @@ raise OperationError(space.w_NotImplementedError, space.wrap( "setting flags not implemented yet")) - @unwrap_spec(offset=int) + @unwrap_spec(offset=int) def descr_getfield(self, space, w_dtype, offset): raise OperationError(space.w_NotImplementedError, space.wrap( "getfield not implemented yet")) @@ -518,7 +518,7 @@ raise OperationError(space.w_NotImplementedError, space.wrap( "itemset not implemented yet")) - @unwrap_spec(neworder=str) + @unwrap_spec(neworder=str) def descr_newbyteorder(self, space, neworder): raise OperationError(space.w_NotImplementedError, space.wrap( "newbyteorder not implemented yet")) @@ -551,7 +551,7 @@ raise OperationError(space.w_NotImplementedError, space.wrap( "setfield not implemented yet")) - def descr_setflags(self, space, w_write=None, w_align=None, w_uic=None): + def descr_setflags(self, space, w_write=None, w_align=None, w_uic=None): raise OperationError(space.w_NotImplementedError, space.wrap( "setflags not implemented yet")) @@ -572,7 +572,7 @@ "tofile not implemented yet")) def descr_trace(self, space, w_offset=0, w_axis1=0, w_axis2=1, - w_dtype=None, w_out=None): + w_dtype=None, w_out=None): raise OperationError(space.w_NotImplementedError, space.wrap( "trace not implemented yet")) @@ -627,21 +627,23 @@ w_remainder = self.descr_mod(space, w_other) return space.newtuple([w_quotient, w_remainder]) - _descr_eq = _binop_impl("equal") + def _binop_comp_impl(ufunc): + def impl(self, space, w_other, w_out=None): + try: + return ufunc(self, space, w_other, w_out) + except OperationError, e: + if e.match(space, space.w_ValueError): + return space.w_False + raise e - def descr_eq(self, space, w_other): - try: - return self._descr_eq(space, w_other) - except OperationError, e: - if e.match(space, space.w_ValueError): - return space.w_False - raise e + return func_with_new_name(impl, ufunc.func_name) - descr_ne = _binop_impl("not_equal") - descr_lt = _binop_impl("less") - descr_le = _binop_impl("less_equal") - descr_gt = _binop_impl("greater") - descr_ge = _binop_impl("greater_equal") + descr_eq = _binop_comp_impl(_binop_impl("equal")) + descr_ne = _binop_comp_impl(_binop_impl("not_equal")) + descr_lt = _binop_comp_impl(_binop_impl("less")) + descr_le = _binop_comp_impl(_binop_impl("less_equal")) + descr_gt = _binop_comp_impl(_binop_impl("greater")) + descr_ge = _binop_comp_impl(_binop_impl("greater_equal")) def _binop_right_impl(ufunc_name): def impl(self, space, w_other, w_out=None): @@ -707,7 +709,7 @@ if space.is_none(w_out): out = None elif not isinstance(w_out, W_NDimArray): - raise OperationError(space.w_TypeError, space.wrap( + raise OperationError(space.w_TypeError, space.wrap( 'output must be an array')) else: out = w_out @@ -727,7 +729,7 @@ descr_cumsum = _reduce_ufunc_impl('add', cumultative=True) descr_cumprod = _reduce_ufunc_impl('multiply', cumultative=True) - + def descr_mean(self, space, w_axis=None, w_out=None): if space.is_none(w_axis): w_denom = space.wrap(self.get_size()) @@ -872,7 +874,7 @@ swapaxes = interp2app(W_NDimArray.descr_swapaxes), flat = GetSetProperty(W_NDimArray.descr_get_flatiter), item = interp2app(W_NDimArray.descr_item), - real = GetSetProperty(W_NDimArray.descr_get_real, + real = GetSetProperty(W_NDimArray.descr_get_real, W_NDimArray.descr_set_real), imag = GetSetProperty(W_NDimArray.descr_get_imag, W_NDimArray.descr_set_imag), @@ -932,7 +934,7 @@ dtype) #if dtype is interp_dtype.get_dtype_cache(space).w_float64dtype: # break - + if dtype is None: dtype = interp_dtype.get_dtype_cache(space).w_float64dtype if ndmin > len(shape): From noreply at buildbot.pypy.org Wed Feb 20 16:33:11 2013 From: noreply at buildbot.pypy.org (rguillebert) Date: Wed, 20 Feb 2013 16:33:11 +0100 (CET) Subject: [pypy-commit] pypy default: merge heads Message-ID: <20130220153311.47E741C1E4F@cobra.cs.uni-duesseldorf.de> Author: Romain Guillebert Branch: Changeset: r61496:974e7fe3c1d5 Date: 2013-02-20 16:31 +0100 http://bitbucket.org/pypy/pypy/changeset/974e7fe3c1d5/ Log: merge heads diff --git a/pypy/objspace/std/floatobject.py b/pypy/objspace/std/floatobject.py --- a/pypy/objspace/std/floatobject.py +++ b/pypy/objspace/std/floatobject.py @@ -10,7 +10,7 @@ from rpython.rlib.rarithmetic import ovfcheck_float_to_int, intmask, LONG_BIT from rpython.rlib.rfloat import ( isinf, isnan, isfinite, INFINITY, NAN, copysign, formatd, - DTSF_ADD_DOT_0, DTSF_STR_PRECISION) + DTSF_ADD_DOT_0, DTSF_STR_PRECISION, float_as_rbigint_ratio) from rpython.rlib.rbigint import rbigint from rpython.rlib import rfloat from rpython.tool.sourcetools import func_with_new_name @@ -553,27 +553,18 @@ def float_as_integer_ratio__Float(space, w_float): value = w_float.floatval - if isinf(value): + try: + num, den = float_as_rbigint_ratio(value) + except OverflowError: w_msg = space.wrap("cannot pass infinity to as_integer_ratio()") raise OperationError(space.w_OverflowError, w_msg) - elif isnan(value): + except ValueError: w_msg = space.wrap("cannot pass nan to as_integer_ratio()") raise OperationError(space.w_ValueError, w_msg) - float_part, exp = math.frexp(value) - for i in range(300): - if float_part == math.floor(float_part): - break - float_part *= 2.0 - exp -= 1 - w_num = W_LongObject.fromfloat(space, float_part) - w_den = space.newlong(1) - w_exp = space.newlong(abs(exp)) - w_exp = space.lshift(w_den, w_exp) - if exp > 0: - w_num = space.mul(w_num, w_exp) - else: - w_den = w_exp - # Try to return int. + + w_num = space.newlong_from_rbigint(num) + w_den = space.newlong_from_rbigint(den) + # Try to return int return space.newtuple([space.int(w_num), space.int(w_den)]) def float_is_integer__Float(space, w_float): diff --git a/rpython/rlib/rfloat.py b/rpython/rlib/rfloat.py --- a/rpython/rlib/rfloat.py +++ b/rpython/rlib/rfloat.py @@ -419,3 +419,25 @@ def isfinite(x): "NOT_RPYTHON" return not isinf(x) and not isnan(x) + +def float_as_rbigint_ratio(value): + from rpython.rlib.rbigint import rbigint + + if isinf(value): + raise OverflowError("cannot pass infinity to as_integer_ratio()") + elif isnan(value): + raise ValueError("cannot pass nan to as_integer_ratio()") + float_part, exp_int = math.frexp(value) + for i in range(300): + if float_part == math.floor(float_part): + break + float_part *= 2.0 + exp_int -= 1 + num = rbigint.fromfloat(float_part) + den = rbigint.fromint(1) + exp = den.lshift(abs(exp_int)) + if exp_int > 0: + num = num.mul(exp) + else: + den = exp + return num, den diff --git a/rpython/rlib/test/test_rfloat.py b/rpython/rlib/test/test_rfloat.py new file mode 100644 --- /dev/null +++ b/rpython/rlib/test/test_rfloat.py @@ -0,0 +1,131 @@ +import sys, py + +from rpython.rlib.rfloat import float_as_rbigint_ratio +from rpython.rlib.rfloat import break_up_float +from rpython.rlib.rfloat import copysign +from rpython.rlib.rfloat import round_away +from rpython.rlib.rfloat import round_double +from rpython.rlib.rbigint import rbigint + +def test_copysign(): + assert copysign(1, 1) == 1 + assert copysign(-1, 1) == 1 + assert copysign(-1, -1) == -1 + assert copysign(1, -1) == -1 + assert copysign(1, -0.) == -1 + +def test_round_away(): + assert round_away(.1) == 0. + assert round_away(.5) == 1. + assert round_away(.7) == 1. + assert round_away(1.) == 1. + assert round_away(-.5) == -1. + assert round_away(-.1) == 0. + assert round_away(-.7) == -1. + assert round_away(0.) == 0. + +def test_round_double(): + def almost_equal(x, y): + assert round(abs(x-y), 7) == 0 + + almost_equal(round_double(0.125, 2), 0.13) + almost_equal(round_double(0.375, 2), 0.38) + almost_equal(round_double(0.625, 2), 0.63) + almost_equal(round_double(0.875, 2), 0.88) + almost_equal(round_double(-0.125, 2), -0.13) + almost_equal(round_double(-0.375, 2), -0.38) + almost_equal(round_double(-0.625, 2), -0.63) + almost_equal(round_double(-0.875, 2), -0.88) + + almost_equal(round_double(0.25, 1), 0.3) + almost_equal(round_double(0.75, 1), 0.8) + almost_equal(round_double(-0.25, 1), -0.3) + almost_equal(round_double(-0.75, 1), -0.8) + + round_double(-6.5, 0) == -7.0 + round_double(-5.5, 0) == -6.0 + round_double(-1.5, 0) == -2.0 + round_double(-0.5, 0) == -1.0 + round_double(0.5, 0) == 1.0 + round_double(1.5, 0) == 2.0 + round_double(2.5, 0) == 3.0 + round_double(3.5, 0) == 4.0 + round_double(4.5, 0) == 5.0 + round_double(5.5, 0) == 6.0 + round_double(6.5, 0) == 7.0 + + round_double(-25.0, -1) == -30.0 + round_double(-15.0, -1) == -20.0 + round_double(-5.0, -1) == -10.0 + round_double(5.0, -1) == 10.0 + round_double(15.0, -1) == 20.0 + round_double(25.0, -1) == 30.0 + round_double(35.0, -1) == 40.0 + round_double(45.0, -1) == 50.0 + round_double(55.0, -1) == 60.0 + round_double(65.0, -1) == 70.0 + round_double(75.0, -1) == 80.0 + round_double(85.0, -1) == 90.0 + round_double(95.0, -1) == 100.0 + round_double(12325.0, -1) == 12330.0 + + round_double(350.0, -2) == 400.0 + round_double(450.0, -2) == 500.0 + + almost_equal(round_double(0.5e21, -21), 1e21) + almost_equal(round_double(1.5e21, -21), 2e21) + almost_equal(round_double(2.5e21, -21), 3e21) + almost_equal(round_double(5.5e21, -21), 6e21) + almost_equal(round_double(8.5e21, -21), 9e21) + + almost_equal(round_double(-1.5e22, -22), -2e22) + almost_equal(round_double(-0.5e22, -22), -1e22) + almost_equal(round_double(0.5e22, -22), 1e22) + almost_equal(round_double(1.5e22, -22), 2e22) + +def test_round_half_even(): + from rpython.rlib import rfloat + for func in (rfloat.round_double_short_repr, + rfloat.round_double_fallback_repr): + # 2.x behavior + assert func(2.5, 0, False) == 3.0 + # 3.x behavior + assert func(2.5, 0, True) == 2.0 + +def test_break_up_float(): + assert break_up_float('1') == ('', '1', '', '') + assert break_up_float('+1') == ('+', '1', '', '') + assert break_up_float('-1') == ('-', '1', '', '') + + assert break_up_float('.5') == ('', '', '5', '') + + assert break_up_float('1.2e3') == ('', '1', '2', '3') + assert break_up_float('1.2e+3') == ('', '1', '2', '+3') + assert break_up_float('1.2e-3') == ('', '1', '2', '-3') + + # some that will get thrown out on return: + assert break_up_float('.') == ('', '', '', '') + assert break_up_float('+') == ('+', '', '', '') + assert break_up_float('-') == ('-', '', '', '') + assert break_up_float('e1') == ('', '', '', '1') + + py.test.raises(ValueError, break_up_float, 'e') + + +def test_float_as_rbigint_ratio(): + for f, ratio in [ + (0.875, (7, 8)), + (-0.875, (-7, 8)), + (0.0, (0, 1)), + (11.5, (23, 2)), + ]: + num, den = float_as_rbigint_ratio(f) + assert num.eq(rbigint.fromint(ratio[0])) + assert den.eq(rbigint.fromint(ratio[1])) + + with py.test.raises(OverflowError): + float_as_rbigint_ratio(float('inf')) + with py.test.raises(OverflowError): + float_as_rbigint_ratio(float('-inf')) + with py.test.raises(ValueError): + float_as_rbigint_ratio(float('nan')) diff --git a/rpython/rtyper/test/test_rfloat.py b/rpython/rtyper/test/test_rfloat.py --- a/rpython/rtyper/test/test_rfloat.py +++ b/rpython/rtyper/test/test_rfloat.py @@ -216,26 +216,6 @@ # https://bugzilla.novell.com/show_bug.cgi?id=692493 assert not self.interpret(fn, [1e200, 1e200]) # nan - def test_break_up_float(self): - from rpython.rlib.rfloat import break_up_float - assert break_up_float('1') == ('', '1', '', '') - assert break_up_float('+1') == ('+', '1', '', '') - assert break_up_float('-1') == ('-', '1', '', '') - - assert break_up_float('.5') == ('', '', '5', '') - - assert break_up_float('1.2e3') == ('', '1', '2', '3') - assert break_up_float('1.2e+3') == ('', '1', '2', '+3') - assert break_up_float('1.2e-3') == ('', '1', '2', '-3') - - # some that will get thrown out on return: - assert break_up_float('.') == ('', '', '', '') - assert break_up_float('+') == ('+', '', '', '') - assert break_up_float('-') == ('-', '', '', '') - assert break_up_float('e1') == ('', '', '', '1') - - py.test.raises(ValueError, break_up_float, 'e') - def test_formatd(self): from rpython.rlib.rfloat import formatd def f(x): @@ -296,93 +276,6 @@ assert self.interpret(func, [0]) == 1e23 assert self.interpret(func, [1]) == -1e23 - def test_copysign(self): - from rpython.rlib.rfloat import copysign - assert copysign(1, 1) == 1 - assert copysign(-1, 1) == 1 - assert copysign(-1, -1) == -1 - assert copysign(1, -1) == -1 - assert copysign(1, -0.) == -1 - - def test_round_away(self): - from rpython.rlib.rfloat import round_away - assert round_away(.1) == 0. - assert round_away(.5) == 1. - assert round_away(.7) == 1. - assert round_away(1.) == 1. - assert round_away(-.5) == -1. - assert round_away(-.1) == 0. - assert round_away(-.7) == -1. - assert round_away(0.) == 0. - - def test_round_double(self): - from rpython.rlib.rfloat import round_double - def almost_equal(x, y): - assert round(abs(x-y), 7) == 0 - - almost_equal(round_double(0.125, 2), 0.13) - almost_equal(round_double(0.375, 2), 0.38) - almost_equal(round_double(0.625, 2), 0.63) - almost_equal(round_double(0.875, 2), 0.88) - almost_equal(round_double(-0.125, 2), -0.13) - almost_equal(round_double(-0.375, 2), -0.38) - almost_equal(round_double(-0.625, 2), -0.63) - almost_equal(round_double(-0.875, 2), -0.88) - - almost_equal(round_double(0.25, 1), 0.3) - almost_equal(round_double(0.75, 1), 0.8) - almost_equal(round_double(-0.25, 1), -0.3) - almost_equal(round_double(-0.75, 1), -0.8) - - round_double(-6.5, 0) == -7.0 - round_double(-5.5, 0) == -6.0 - round_double(-1.5, 0) == -2.0 - round_double(-0.5, 0) == -1.0 - round_double(0.5, 0) == 1.0 - round_double(1.5, 0) == 2.0 - round_double(2.5, 0) == 3.0 - round_double(3.5, 0) == 4.0 - round_double(4.5, 0) == 5.0 - round_double(5.5, 0) == 6.0 - round_double(6.5, 0) == 7.0 - - round_double(-25.0, -1) == -30.0 - round_double(-15.0, -1) == -20.0 - round_double(-5.0, -1) == -10.0 - round_double(5.0, -1) == 10.0 - round_double(15.0, -1) == 20.0 - round_double(25.0, -1) == 30.0 - round_double(35.0, -1) == 40.0 - round_double(45.0, -1) == 50.0 - round_double(55.0, -1) == 60.0 - round_double(65.0, -1) == 70.0 - round_double(75.0, -1) == 80.0 - round_double(85.0, -1) == 90.0 - round_double(95.0, -1) == 100.0 - round_double(12325.0, -1) == 12330.0 - - round_double(350.0, -2) == 400.0 - round_double(450.0, -2) == 500.0 - - almost_equal(round_double(0.5e21, -21), 1e21) - almost_equal(round_double(1.5e21, -21), 2e21) - almost_equal(round_double(2.5e21, -21), 3e21) - almost_equal(round_double(5.5e21, -21), 6e21) - almost_equal(round_double(8.5e21, -21), 9e21) - - almost_equal(round_double(-1.5e22, -22), -2e22) - almost_equal(round_double(-0.5e22, -22), -1e22) - almost_equal(round_double(0.5e22, -22), 1e22) - almost_equal(round_double(1.5e22, -22), 2e22) - - def test_round_half_even(self): - from rpython.rlib import rfloat - for func in (rfloat.round_double_short_repr, - rfloat.round_double_fallback_repr): - # 2.x behavior - assert func(2.5, 0, False) == 3.0 - # 3.x behavior - assert func(2.5, 0, True) == 2.0 class TestLLtype(BaseTestRfloat, LLRtypeMixin): From noreply at buildbot.pypy.org Wed Feb 20 17:32:23 2013 From: noreply at buildbot.pypy.org (krono) Date: Wed, 20 Feb 2013 17:32:23 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: simplify image header peek logic. rpython does not get literal numbers >64bit, either Message-ID: <20130220163223.523D61C1439@cobra.cs.uni-duesseldorf.de> Author: Tobias Pape Branch: Changeset: r78:d87c899dda98 Date: 2013-02-20 17:32 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/d87c899dda98/ Log: simplify image header peek logic. rpython does not get literal numbers >64bit, either diff --git a/spyvm/squeakimage.py b/spyvm/squeakimage.py --- a/spyvm/squeakimage.py +++ b/spyvm/squeakimage.py @@ -6,37 +6,33 @@ from rpython.rlib import objectmodel -def chrs2int(b, unsigned): +def chrs2int(b): assert len(b) == 4 first = ord(b[0]) # big endian - if not unsigned: - if first & 0x80 != 0: - first = first - 0x100 + if first & 0x80 != 0: + first = first - 0x100 return (first << 24 | ord(b[1]) << 16 | ord(b[2]) << 8 | ord(b[3])) -def swapped_chrs2int(b, unsigned): +def swapped_chrs2int(b): assert len(b) == 4 first = ord(b[3]) # little endian - if not unsigned: - if first & 0x80 != 0: - first = first - 0x100 + if first & 0x80 != 0: + first = first - 0x100 return (first << 24 | ord(b[2]) << 16 | ord(b[1]) << 8 | ord(b[0])) -def chrs2long(b, unsigned): +def chrs2long(b): assert len(b) == 8 first = ord(b[0]) # big endian - if not unsigned: - if first & 0x80 != 0: - first = first - 0x100 + if first & 0x80 != 0: + first = first - 0x100 return ( first << 56 | ord(b[1]) << 48 | ord(b[2]) << 40 | ord(b[3]) << 32 | ord(b[4]) << 24 | ord(b[5]) << 16 | ord(b[6]) << 8 | ord(b[7]) ) -def swapped_chrs2long(b, unsigned): +def swapped_chrs2long(b): assert len(b) == 8 first = ord(b[7]) # little endian - if not unsigned: - if first & 0x80 != 0: - first = first - 0x100 + if first & 0x80 != 0: + first = first - 0x100 return ( first << 56 | ord(b[6]) << 48 | ord(b[5]) << 40 | ord(b[4]) << 32 | ord(b[3]) << 24 | ord(b[2]) << 16 | ord(b[1]) << 8 | ord(b[0]) ) @@ -60,29 +56,14 @@ data_peek = self.data[self.pos:self.pos + self.word_size] if self.use_long_read: if self.swap: - return swapped_chrs2long(data_peek, False) + return swapped_chrs2long(data_peek) else: - return chrs2long(data_peek, False) + return chrs2long(data_peek) else: if self.swap: - return swapped_chrs2int(data_peek, False) + return swapped_chrs2int(data_peek) else: - return chrs2int(data_peek, False) - - def peek_unsigned(self): - if self.pos >= len(self.data): - raise IndexError - data_peek = self.data[self.pos:self.pos + self.word_size] - if self.use_long_read: - if self.swap: - return swapped_chrs2long(data_peek, True) - else: - return chrs2long(data_peek, True) - else: - if self.swap: - return swapped_chrs2int(data_peek, True) - else: - return chrs2int(data_peek, True) + return chrs2int(data_peek) def next(self): @@ -152,12 +133,18 @@ 0x68190000: ImageVersion(6504, False, False, True, False), 0x00001969: ImageVersion(6505, True, False, True, True ), 0x69190000: ImageVersion(6505, False, False, True, True ), - 0x000109A0: ImageVersion(68000, True, True, False, False), - 0xA009010000000000: ImageVersion(68000, False, True, False, False), + 0x00000000000109A0: ImageVersion(68000, True, True, False, False), + -0x5ff6ff0000000000: + # signed version of 0xA009010000000000: + ImageVersion(68000, False, True, False, False), 0x00000000000109A2: ImageVersion(68002, True, True, True, False), - 0xA209010000000000: ImageVersion(68002, False, True, True, False), + -0x5df6ff0000000000: + # signed version of 0xA209010000000000: + ImageVersion(68002, False, True, True, False), 0x00000000000109A3: ImageVersion(68003, True, True, True, True ), - 0xA309010000000000: ImageVersion(68003, False, True, True, True ), + -0x5cf6ff0000000000: + # signed version of 0xA309010000000000: + ImageVersion(68003, False, True, True, True ), } @@ -174,26 +161,26 @@ def version_from_stream(stream): # 32 bit try: - return version(stream.peek_unsigned()) + return version(stream.peek()) except CorruptImageError as e: if stream.length() > possible_image_offset + 4: stream.skipbytes(possible_image_offset) try: - return version(stream.peek_unsigned()) + return version(stream.peek()) except CorruptImageError: pass # raise original error # 64 bit stream.reset() stream.be_64bit() try: - v = version(stream.peek_unsigned()) + v = version(stream.peek()) assert v.is_64bit return v except CorruptImageError as e: if stream.length() > possible_image_offset + 4: stream.skipbytes(possible_image_offset) try: - v = version(stream.peek_unsigned()) + v = version(stream.peek()) assert v.is_64bit return v except CorruptImageError: diff --git a/spyvm/test/test_squeakimage.py b/spyvm/test/test_squeakimage.py --- a/spyvm/test/test_squeakimage.py +++ b/spyvm/test/test_squeakimage.py @@ -35,18 +35,14 @@ # ----- tests ------------------------------------------------ def test_chrs2int(): - assert 1 == chrs2int('\x00\x00\x00\x01', False) - assert -1 == chrs2int('\xFF\xFF\xFF\xFF', False) - assert 1 == chrs2int('\x00\x00\x00\x01', True) - assert 0xFFFFFFFF == chrs2int('\xFF\xFF\xFF\xFF', True) + assert 1 == chrs2int('\x00\x00\x00\x01') + assert -1 == chrs2int('\xFF\xFF\xFF\xFF') def test_chrs2long(): - assert 1 == chrs2long('\x00\x00\x00\x00\x00\x00\x00\x01', False) - assert -1 == chrs2long('\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF', False) - assert 1 == chrs2long('\x00\x00\x00\x00\x00\x00\x00\x01', True) - assert 0xFFFFFFFFFFFFFFFF == chrs2long('\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF', True) - assert 68002 == chrs2long(pack(">Q", 68002), False) - assert 68002 == swapped_chrs2long(pack("Q", 68002)) + assert 68002 == swapped_chrs2long(pack(" Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61497:cd6fe2babfd9 Date: 2013-02-20 18:52 +0100 http://bitbucket.org/pypy/pypy/changeset/cd6fe2babfd9/ Log: (arigo, fijal, alex lurking) Implement asmgcc for this branch diff --git a/rpython/jit/backend/llsupport/assembler.py b/rpython/jit/backend/llsupport/assembler.py --- a/rpython/jit/backend/llsupport/assembler.py +++ b/rpython/jit/backend/llsupport/assembler.py @@ -64,7 +64,7 @@ self._build_wb_slowpath(True) self._build_wb_slowpath(False, for_frame=True) # only one of those - self._build_stack_check_failure() + self.build_frame_realloc_slowpath() if self.cpu.supports_floats: self._build_failure_recovery(False, withfloats=True) self._build_failure_recovery(True, withfloats=True) diff --git a/rpython/jit/backend/llsupport/gc.py b/rpython/jit/backend/llsupport/gc.py --- a/rpython/jit/backend/llsupport/gc.py +++ b/rpython/jit/backend/llsupport/gc.py @@ -120,7 +120,7 @@ descrs = JitFrameDescrs() descrs.arraydescr = cpu.arraydescrof(jitframe.JITFRAME) for name in ['jf_descr', 'jf_guard_exc', 'jf_force_descr', - 'jf_frame_info', 'jf_gcmap']: + 'jf_frame_info', 'jf_gcmap', 'jf_extra_stack_depth']: setattr(descrs, name, cpu.fielddescrof(jitframe.JITFRAME, name)) descrs.jfi_frame_size = cpu.fielddescrof(jitframe.JITFRAMEINFO, 'jfi_frame_size') @@ -373,7 +373,6 @@ translator = self.translator self.layoutbuilder = framework.TransformerLayoutBuilder(translator) self.layoutbuilder.delay_encoding() - # XXX this can probably die horrible death translator._jit2gc = {'layoutbuilder': self.layoutbuilder} def _setup_gcclass(self): @@ -391,6 +390,8 @@ def _setup_tid(self): self.fielddescr_tid = get_field_descr(self, self.GCClass.HDR, 'tid') + frame_tid = self.layoutbuilder.get_type_id(jitframe.JITFRAME) + self.translator._jit2gc['frame_tid'] = frame_tid def _setup_write_barrier(self): self.WB_FUNCPTR = lltype.Ptr(lltype.FuncType( diff --git a/rpython/jit/backend/llsupport/jitframe.py b/rpython/jit/backend/llsupport/jitframe.py --- a/rpython/jit/backend/llsupport/jitframe.py +++ b/rpython/jit/backend/llsupport/jitframe.py @@ -55,6 +55,8 @@ ('jf_force_descr', llmemory.GCREF), # a map of GC pointers ('jf_gcmap', lltype.Ptr(GCMAP)), + # how much we decrease stack pointer. Used around calls and malloc slowpath + ('jf_extra_stack_depth', lltype.Signed), # For the front-end: a GCREF for the savedata ('jf_savedata', llmemory.GCREF), # For GUARD_(NO)_EXCEPTION and GUARD_NOT_FORCED: the exception we @@ -84,6 +86,7 @@ LENGTHOFS = llmemory.arraylengthoffset(JITFRAME.jf_frame) SIGN_SIZE = llmemory.sizeof(lltype.Signed) UNSIGN_SIZE = llmemory.sizeof(lltype.Unsigned) +STACK_DEPTH_OFS = getofs('jf_extra_stack_depth') def jitframe_trace(obj_addr, prev): if prev == llmemory.NULL: diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -131,7 +131,7 @@ self.float_const_neg_addr = float_constants self.float_const_abs_addr = float_constants + 16 - def _build_stack_check_failure(self): + def build_frame_realloc_slowpath(self): mc = codebuf.MachineCodeBlockWrapper() self._push_all_regs_to_frame(mc, [], self.cpu.supports_floats) # this is the gcmap stored by push_gcmap(mov=True) in _check_stack_frame @@ -153,12 +153,15 @@ mc.MOV_sr(0, ebp.value) # align + extra_ofs = self.cpu.get_ofs_of_frame_field('jf_extra_stack_depth') + mc.MOV_bi(extra_ofs, align * WORD) self._store_and_reset_exception(mc, None, ebx, ecx) mc.CALL(imm(self.cpu.realloc_frame)) self._restore_exception(mc, None, ebx, ecx) mc.ADD_ri(esp.value, (align - 1) * WORD) mc.MOV_rr(ebp.value, eax.value) + mc.MOV_bi(extra_ofs, 0) gcrootmap = self.cpu.gc_ll_descr.gcrootmap @@ -169,7 +172,7 @@ mc.MOV_bi(gcmap_ofs, 0) self._pop_all_regs_from_frame(mc, [], self.cpu.supports_floats) mc.RET() - self._stack_check_failure = mc.materialize(self.cpu.asmmemmgr, []) + self._frame_realloc_slowpath = mc.materialize(self.cpu.asmmemmgr, []) def _build_malloc_slowpath(self): """ While arriving on slowpath, we have a gcpattern on stack, @@ -182,8 +185,6 @@ mc.MOV_rs(ecx.value, WORD) mc.MOV_br(ofs, ecx.value) addr = self.cpu.gc_ll_descr.get_malloc_slowpath_addr() - # XXX investigate if we need to save callee-saved registers - # on the frame mc.SUB_rr(edi.value, eax.value) # compute the size we want # the arg is already in edi mc.SUB_ri(esp.value, 16 - WORD) @@ -194,6 +195,8 @@ elif hasattr(self.cpu.gc_ll_descr, 'passes_frame'): # for tests only mc.MOV_rr(esi.value, ebp.value) + extra_ofs = self.cpu.get_ofs_of_frame_field('jf_extra_stack_depth') + mc.MOV_bi(extra_ofs, 16) mc.CALL(imm(addr)) mc.ADD_ri(esp.value, 16 - WORD) mc.TEST_rr(eax.value, eax.value) @@ -202,6 +205,7 @@ # nursery_free_adr = self.cpu.gc_ll_descr.get_nursery_free_addr() self._reload_frame_if_necessary(mc) + mc.MOV_bi(extra_ofs, 0) self._pop_all_regs_from_frame(mc, [eax, edi], self.cpu.supports_floats) mc.MOV(edi, heap(nursery_free_adr)) # load this in EDI # clear the gc pattern @@ -643,7 +647,7 @@ mc.MOV_si(WORD, expected_size) ofs2 = mc.get_relative_pos() - 4 self.push_gcmap(mc, gcmap, mov=True) - mc.CALL(imm(self._stack_check_failure)) + mc.CALL(imm(self._frame_realloc_slowpath)) # patch the JG above offset = mc.get_relative_pos() - jg_location assert 0 < offset <= 127 @@ -815,10 +819,6 @@ return rst def _call_header_shadowstack(self, gcrootmap): - # we don't *really* have to do it, since we have the frame - # being referenced by the caller. However, we still do it - # to provide a place where we can read the frame from, in case - # we need to reload it after a collection rst = self._load_shadowstack_top_in_ebx(self.mc, gcrootmap) self.mc.MOV_mr((ebx.value, 0), ebp.value) # MOV [ebx], ebp self.mc.ADD_ri(ebx.value, WORD) @@ -1091,6 +1091,9 @@ stack_depth = align_stack_words(stack_depth) align = (stack_depth - PASS_ON_MY_FRAME) self.mc.SUB_ri(esp.value, align * WORD) + if can_collect: + ofs = self.cpu.get_ofs_of_frame_field('jf_extra_stack_depth') + self.mc.MOV_bi(ofs, align * WORD) else: align = 0 p = 0 @@ -1121,7 +1124,9 @@ self.mc.CALL(x) if can_collect: self._reload_frame_if_necessary(self.mc) - if can_collect: + if align: + ofs = self.cpu.get_ofs_of_frame_field('jf_extra_stack_depth') + self.mc.MOV_bi(ofs, 0) self.pop_gcmap(self.mc) # if callconv != FFI_DEFAULT_ABI: @@ -1161,6 +1166,9 @@ if stack_depth > PASS_ON_MY_FRAME: stack_depth = align_stack_words(stack_depth) align = (stack_depth - PASS_ON_MY_FRAME) + if can_collect: + ofs = self.cpu.get_ofs_of_frame_field('jf_extra_stack_depth') + self.mc.MOV_bi(ofs, align * WORD) self.mc.SUB_ri(esp.value, align * WORD) for i in range(start, len(arglocs)): loc = arglocs[i] @@ -1221,6 +1229,9 @@ self.mc.CALL(x) if can_collect: self._reload_frame_if_necessary(self.mc) + if align: + ofs = self.cpu.get_ofs_of_frame_field('jf_extra_stack_depth') + self.mc.MOV_bi(ofs, 0) if align: self.mc.ADD_ri(esp.value, align * WORD) if can_collect: diff --git a/rpython/jit/backend/x86/regalloc.py b/rpython/jit/backend/x86/regalloc.py --- a/rpython/jit/backend/x86/regalloc.py +++ b/rpython/jit/backend/x86/regalloc.py @@ -723,7 +723,8 @@ # - at least the non-callee-saved registers # # - for shadowstack, we assume that any call can collect, and we - # save also the callee-saved registers that contain GC pointers. + # save also the callee-saved registers that contain GC pointers + # XXX for asmgcc too for now. # # - for CALL_MAY_FORCE or CALL_ASSEMBLER, we have to save all regs # anyway, in case we need to do cpu.force(). The issue is that @@ -734,7 +735,8 @@ self.xrm.before_call(force_store, save_all_regs=save_all_regs) if not save_all_regs: gcrootmap = self.assembler.cpu.gc_ll_descr.gcrootmap - if gcrootmap and gcrootmap.is_shadow_stack: + # we save all the registers for shadowstack and asmgcc for now + if gcrootmap: # and gcrootmap.is_shadow_stack: save_all_regs = 2 self.rm.before_call(force_store, save_all_regs=save_all_regs) if op.result is not None: diff --git a/rpython/rtyper/memory/gctransform/asmgcroot.py b/rpython/rtyper/memory/gctransform/asmgcroot.py --- a/rpython/rtyper/memory/gctransform/asmgcroot.py +++ b/rpython/rtyper/memory/gctransform/asmgcroot.py @@ -135,15 +135,10 @@ self.walk_stack_from() self._asm_callback = _asm_callback self._shape_decompressor = ShapeDecompressor() - if hasattr(gctransformer.translator, '_jit2gc'): + self._with_jit = hasattr(gctransformer.translator, '_jit2gc') + if self._with_jit: jit2gc = gctransformer.translator._jit2gc - self._extra_gcmapstart = jit2gc['gcmapstart'] - self._extra_gcmapend = jit2gc['gcmapend'] - self._extra_mark_sorted = jit2gc['gcmarksorted'] - else: - self._extra_gcmapstart = lambda: llmemory.NULL - self._extra_gcmapend = lambda: llmemory.NULL - self._extra_mark_sorted = lambda: True + self.frame_tid = jit2gc['frame_tid'] def need_stacklet_support(self, gctransformer, getfn): # stacklet support: BIG HACK for rlib.rstacklet @@ -359,12 +354,12 @@ # try to locate the caller function based on retaddr. # set up self._shape_decompressor. # - self.locate_caller_based_on_retaddr(retaddr) + ebp_in_caller = callee.regs_stored_at[INDEX_OF_EBP].address[0] + self.locate_caller_based_on_retaddr(retaddr, ebp_in_caller) # # found! Enumerate the GC roots in the caller frame # collect_stack_root = self.gcdata._gc_collect_stack_root - ebp_in_caller = callee.regs_stored_at[INDEX_OF_EBP].address[0] gc = self.gc while True: location = self._shape_decompressor.next() @@ -391,46 +386,40 @@ # of the entry point, stop walking" return caller.frame_address != llmemory.NULL - def locate_caller_based_on_retaddr(self, retaddr): + def locate_caller_based_on_retaddr(self, retaddr, ebp_in_caller): gcmapstart = llop.gc_asmgcroot_static(llmemory.Address, 0) gcmapend = llop.gc_asmgcroot_static(llmemory.Address, 1) item = search_in_gcmap(gcmapstart, gcmapend, retaddr) if item: self._shape_decompressor.setpos(item.signed[1]) return - gcmapstart2 = self._extra_gcmapstart() - gcmapend2 = self._extra_gcmapend() - if gcmapstart2 != gcmapend2: - # we have a non-empty JIT-produced table to look in - item = search_in_gcmap2(gcmapstart2, gcmapend2, retaddr) + + if not self._shape_decompressor.sorted: + # the item may have been not found because the main array was + # not sorted. Sort it and try again. + win32_follow_gcmap_jmp(gcmapstart, gcmapend) + sort_gcmap(gcmapstart, gcmapend) + self._shape_decompressor.sorted = True + item = search_in_gcmap(gcmapstart, gcmapend, retaddr) if item: - self._shape_decompressor.setaddr(item) + self._shape_decompressor.setpos(item.signed[1]) return - # maybe the JIT-produced table is not sorted? - was_already_sorted = self._extra_mark_sorted() - if not was_already_sorted: - sort_gcmap(gcmapstart2, gcmapend2) - item = search_in_gcmap2(gcmapstart2, gcmapend2, retaddr) - if item: - self._shape_decompressor.setaddr(item) - return - # there is a rare risk that the array contains *two* entries - # with the same key, one of which is dead (null value), and we - # found the dead one above. Solve this case by replacing all - # dead keys with nulls, sorting again, and then trying again. - replace_dead_entries_with_nulls(gcmapstart2, gcmapend2) - sort_gcmap(gcmapstart2, gcmapend2) - item = search_in_gcmap2(gcmapstart2, gcmapend2, retaddr) - if item: - self._shape_decompressor.setaddr(item) - return - # the item may have been not found because the main array was - # not sorted. Sort it and try again. - win32_follow_gcmap_jmp(gcmapstart, gcmapend) - sort_gcmap(gcmapstart, gcmapend) - item = search_in_gcmap(gcmapstart, gcmapend, retaddr) - if item: - self._shape_decompressor.setpos(item.signed[1]) + + if self._with_jit: + # item not found. We assume that it's a JIT-generated + # location -- but we check for consistency that ebp points + # to a JITFRAME object. + from rpython.jit.backend.llsupport.jitframe import STACK_DEPTH_OFS + + tid = self.gc.get_type_id(ebp_in_caller) + ll_assert(rffi.cast(lltype.Signed, tid) == + rffi.cast(lltype.Signed, self.frame_tid), + "found a stack frame that does not belong " + "anywhere I know, bug in asmgcc") + # fish the depth + extra_stack_depth = (ebp_in_caller + STACK_DEPTH_OFS).signed[0] + extra_stack_depth //= rffi.sizeof(lltype.Signed) + self._shape_decompressor.setjitframe(extra_stack_depth) return llop.debug_fatalerror(lltype.Void, "cannot find gc roots!") @@ -561,27 +550,83 @@ class ShapeDecompressor: _alloc_flavor_ = "raw" + sorted = False + def setpos(self, pos): if pos < 0: pos = ~ pos # can ignore this "range" marker here gccallshapes = llop.gc_asmgcroot_static(llmemory.Address, 2) self.addr = gccallshapes + pos - def setaddr(self, addr): - self.addr = addr + def setjitframe(self, extra_stack_depth): + self.addr = llmemory.NULL + self.jit_index = 0 + self.extra_stack_depth = extra_stack_depth def next(self): - value = 0 addr = self.addr - while True: - b = ord(addr.char[0]) - addr += 1 - value += b - if b < 0x80: - break - value = (value - 0x80) << 7 - self.addr = addr - return value + if addr: + # case "outside the jit" + value = 0 + while True: + b = ord(addr.char[0]) + addr += 1 + value += b + if b < 0x80: + break + value = (value - 0x80) << 7 + self.addr = addr + return value + else: + # case "in the jit" + from rpython.jit.backend.x86.arch import FRAME_FIXED_SIZE + from rpython.jit.backend.x86.arch import PASS_ON_MY_FRAME + index = self.jit_index + self.jit_index = index + 1 + if index == 0: + # the jitframe is an object in EBP + return LOC_REG | ((INDEX_OF_EBP + 1) << 2) + if index == 1: + return 0 + # the remaining returned values should be: + # saved %rbp + # saved %r15 or on 32bit: + # saved %r14 saved %ebp + # saved %r13 saved %edi + # saved %r12 saved %esi + # saved %rbx saved %ebx + # return addr return addr + if IS_64_BITS: + stack_depth = PASS_ON_MY_FRAME + self.extra_stack_depth + if index == 2: # rbp + return LOC_ESP_PLUS | (stack_depth << 2) + if index == 3: # r15 + return LOC_ESP_PLUS | ((stack_depth + 5) << 2) + if index == 4: # r14 + return LOC_ESP_PLUS | ((stack_depth + 4) << 2) + if index == 5: # r13 + return LOC_ESP_PLUS | ((stack_depth + 3) << 2) + if index == 6: # r12 + return LOC_ESP_PLUS | ((stack_depth + 2) << 2) + if index == 7: # rbx + return LOC_ESP_PLUS | ((stack_depth + 1) << 2) + if index == 8: # return addr + return (LOC_ESP_PLUS | + ((FRAME_FIXED_SIZE + self.extra_stack_depth) << 2)) + else: + if index == 2: # ebp + return LOC_ESP_PLUS | (stack_depth << 2) + if index == 3: # edi + return LOC_ESP_PLUS | ((stack_depth + 3) << 2) + if index == 4: # esi + return LOC_ESP_PLUS | ((stack_depth + 2) << 2) + if index == 5: # ebx + return LOC_ESP_PLUS | ((stack_depth + 1) << 2) + if index == 6: # return addr + return (LOC_ESP_PLUS | + ((FRAME_FIXED_SIZE + self.extra_stack_depth) << 2)) + llop.debug_fatalerror(lltype.Void, "asmgcroot: invalid index") + return 0 # annotator fix # ____________________________________________________________ From noreply at buildbot.pypy.org Wed Feb 20 20:36:48 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Wed, 20 Feb 2013 20:36:48 +0100 (CET) Subject: [pypy-commit] pypy py3k: oops Message-ID: <20130220193648.AB8CE1C13D5@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61498:30731ccb78fe Date: 2013-02-20 11:33 -0800 http://bitbucket.org/pypy/pypy/changeset/30731ccb78fe/ Log: oops diff --git a/pypy/module/_socket/interp_func.py b/pypy/module/_socket/interp_func.py --- a/pypy/module/_socket/interp_func.py +++ b/pypy/module/_socket/interp_func.py @@ -128,8 +128,9 @@ rsocket.SOCK_DGRAM, 0, rsocket.AI_NUMERICHOST) if len(lst) > 1: - raise OperationError(get_error(space, 'error'), - "sockaddr resolved to multiple addresses") + raise OperationError( + get_error(space, 'error'), + space.wrap("sockaddr resolved to multiple addresses")) addr = lst[0][4] host, servport = rsocket.getnameinfo(addr, flags) except SocketError, e: From noreply at buildbot.pypy.org Wed Feb 20 20:36:50 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Wed, 20 Feb 2013 20:36:50 +0100 (CET) Subject: [pypy-commit] pypy py3k: try to workaround W_RSocket.__del__ failing Message-ID: <20130220193650.0D87A1C1439@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61499:e8123a0eeb5b Date: 2013-02-20 11:33 -0800 http://bitbucket.org/pypy/pypy/changeset/e8123a0eeb5b/ Log: try to workaround W_RSocket.__del__ failing check_graph_of_del_does_not_call_too_much (translation) diff --git a/pypy/module/_socket/interp_socket.py b/pypy/module/_socket/interp_socket.py --- a/pypy/module/_socket/interp_socket.py +++ b/pypy/module/_socket/interp_socket.py @@ -158,6 +158,15 @@ except SocketError, e: raise converted_error(space, e) + def __del__(self): + self.clear_all_weakrefs() + if self.space: + self.enqueue_for_destruction(self.space, W_RSocket.destructor, + 'internal __del__ of ') + + def destructor(self): + RSocket.__del__(self) + def _dealloc_warn(self): space = self.space if not space: From noreply at buildbot.pypy.org Wed Feb 20 20:46:33 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Wed, 20 Feb 2013 20:46:33 +0100 (CET) Subject: [pypy-commit] pypy py3k: I'm a socket Message-ID: <20130220194633.66ECD1C3C2D@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61500:fce6563268a5 Date: 2013-02-20 11:46 -0800 http://bitbucket.org/pypy/pypy/changeset/fce6563268a5/ Log: I'm a socket diff --git a/pypy/module/_socket/interp_socket.py b/pypy/module/_socket/interp_socket.py --- a/pypy/module/_socket/interp_socket.py +++ b/pypy/module/_socket/interp_socket.py @@ -165,6 +165,7 @@ 'internal __del__ of ') def destructor(self): + assert isinstance(self, W_RSocket) RSocket.__del__(self) def _dealloc_warn(self): From noreply at buildbot.pypy.org Wed Feb 20 21:19:53 2013 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 20 Feb 2013 21:19:53 +0100 (CET) Subject: [pypy-commit] cffi default: Small documentation fixes. Message-ID: <20130220201953.80F841C13D5@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r1161:c2d972f7e64a Date: 2013-02-20 21:19 +0100 http://bitbucket.org/cffi/cffi/changeset/c2d972f7e64a/ Log: Small documentation fixes. diff --git a/doc/source/index.rst b/doc/source/index.rst --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -1050,7 +1050,13 @@ defined in another part for its own usage. Note that the include() method has no effect on functions, constants and global variables, which must anyway be accessed directly from the ``lib`` object returned by the -original FFI instance. *New in version 0.5.* +original FFI instance. *Note that you should only use one ffi object +per library; the intended usage of ffi.include() is if you want to +interface with several inter-dependent libraries.* For only one +library, make one ``ffi`` object. (If the source becomes too large, +split it up e.g. by collecting the cdef/verify strings from multiple +Python modules, as long as you call ``ffi.verify()`` only once.) *New +in version 0.5.* .. "versionadded:: 0.5" --- inlined in the previous paragraph @@ -1216,10 +1222,11 @@ Enum types follow the GCC rules: they are defined as the first of ``unsigned int``, ``int``, ``unsigned long`` or ``long`` that fits all numeric values. Note that the first choice is unsigned. In CFFI - 0.5 and before, it was always ``int``. *Unimplemented: if the very - large values are not declared, the enum size will be incorrectly - deduced! Work around this by making sure that you name the largest - value and/or any negative value in the cdef.* + 0.5 and before, enums were always ``int``. *Unimplemented: if the enum + has very large values in C not declared in CFFI, the enum will incorrectly + be considered as an int even though it is really a long! Work around + this by naming the largest value. A similar but less important problem + involves negative values.* Debugging dlopen'ed C libraries From noreply at buildbot.pypy.org Wed Feb 20 23:19:32 2013 From: noreply at buildbot.pypy.org (amauryfa) Date: Wed, 20 Feb 2013 23:19:32 +0100 (CET) Subject: [pypy-commit] pypy py3k: Fix cffi support for FILE* Message-ID: <20130220221932.6F1E11C13D5@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: py3k Changeset: r61501:a09cb059a3bb Date: 2013-02-19 22:38 +0100 http://bitbucket.org/pypy/pypy/changeset/a09cb059a3bb/ Log: Fix cffi support for FILE* diff --git a/pypy/module/_cffi_backend/ctypeptr.py b/pypy/module/_cffi_backend/ctypeptr.py --- a/pypy/module/_cffi_backend/ctypeptr.py +++ b/pypy/module/_cffi_backend/ctypeptr.py @@ -2,6 +2,8 @@ Pointers. """ +import os + from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.error import wrap_oserror from rpython.rtyper.lltypesystem import lltype, rffi @@ -247,11 +249,10 @@ return W_CTypePtrBase.cast(self, w_ob) def prepare_file(self, w_ob): - from pypy.module._file.interp_file import W_File - from pypy.module._cffi_backend import ctypefunc + from pypy.module._io.interp_iobase import W_IOBase ob = self.space.interpclass_w(w_ob) - if isinstance(ob, W_File): - return prepare_file_argument(self.space, ob) + if isinstance(ob, W_IOBase): + return prepare_iofile_argument(self.space, w_ob) else: return lltype.nullptr(rffi.CCHARP.TO) @@ -350,15 +351,21 @@ def close(self): rffi_fclose(self.llf) -def prepare_file_argument(space, fileobj): - fileobj.direct_flush() +def prepare_iofile_argument(space, w_fileobj): + fileobj = space.interpclass_w(w_fileobj) + from pypy.module._io.interp_iobase import W_IOBase + assert isinstance(fileobj, W_IOBase) + space.call_method(w_fileobj, "flush") if fileobj.cffi_fileobj is None: - fd = fileobj.direct_fileno() + fd = space.int_w(space.call_method(w_fileobj, "fileno")) if fd < 0: raise OperationError(space.w_ValueError, space.wrap("file has no OS file descriptor")) + fd = os.dup(fd) + mode = space.str_w(space.getattr(w_fileobj, space.wrap("mode"))) try: - fileobj.cffi_fileobj = CffiFileObj(fd, fileobj.mode) + fileobj.cffi_fileobj = CffiFileObj(fd, mode) except OSError, e: raise wrap_oserror(space, e) return fileobj.cffi_fileobj.llf + diff --git a/pypy/module/_cffi_backend/test/_backend_test_c.py b/pypy/module/_cffi_backend/test/_backend_test_c.py --- a/pypy/module/_cffi_backend/test/_backend_test_c.py +++ b/pypy/module/_cffi_backend/test/_backend_test_c.py @@ -2480,13 +2480,13 @@ assert len(p) == 4 assert list(p) == [b"f", b"o", b"o", b"\x00"] -# XXX hack -if sys.version_info >= (3,): - try: - import posix, io - posix.fdopen = io.open - except ImportError: - pass # win32 +import io +fdopen_funcs = [io.open] +try: + import posix + fdopen_funcs.append(posix.fdopen) +except (ImportError, AttributeError): # win32, or py3k + pass def test_FILE(): if sys.platform == "win32": @@ -2503,22 +2503,22 @@ fputs = ll.load_function(BFunc, "fputs") fscanf = ll.load_function(BFunc2, "fscanf") # - import posix - fdr, fdw = posix.pipe() - fr1 = posix.fdopen(fdr, 'rb', 256) - fw1 = posix.fdopen(fdw, 'wb', 256) - # - fw1.write(b"X") - res = fputs(b"hello world\n", fw1) - assert res >= 0 - fw1.flush() # should not be needed - # - p = newp(new_array_type(BCharP, 100), None) - res = fscanf(fr1, b"%s\n", p) - assert res == 1 - assert string(p) == b"Xhello" - fr1.close() - fw1.close() + for fdopen in fdopen_funcs: + fdr, fdw = posix.pipe() + fr1 = fdopen(fdr, 'rb', 256) + fw1 = fdopen(fdw, 'wb', 256) + # + fw1.write(b"X") + res = fputs(b"hello world\n", fw1) + assert res >= 0 + fw1.flush() # should not be needed + # + p = newp(new_array_type(BCharP, 100), None) + res = fscanf(fr1, b"%s\n", p) + assert res == 1 + assert string(p) == b"Xhello" + fr1.close() + fw1.close() def test_FILE_only_for_FILE_arg(): if sys.platform == "win32": @@ -2533,15 +2533,15 @@ ll = find_and_load_library('c') fputs = ll.load_function(BFunc, "fputs") # - import posix - fdr, fdw = posix.pipe() - fr1 = posix.fdopen(fdr, 'r') - fw1 = posix.fdopen(fdw, 'w') - # - e = py.test.raises(TypeError, fputs, b"hello world\n", fw1) - assert str(e.value).startswith( - "initializer for ctype 'struct NOT_FILE *' must " - "be a cdata pointer, not ") + for fdopen in fdopen_funcs: + fdr, fdw = posix.pipe() + fr1 = fdopen(fdr, 'r') + fw1 = fdopen(fdw, 'w') + # + e = py.test.raises(TypeError, fputs, b"hello world\n", fw1) + assert str(e.value).startswith( + "initializer for ctype 'struct NOT_FILE *' must " + "be a cdata pointer, not ") def test_FILE_object(): if sys.platform == "win32": @@ -2558,22 +2558,23 @@ fputs = ll.load_function(BFunc, "fputs") fileno = ll.load_function(BFunc2, "fileno") # - import posix - fdr, fdw = posix.pipe() - fw1 = posix.fdopen(fdw, 'wb', 256) - # - fw1p = cast(BFILEP, fw1) - fw1.write(b"X") - fw1.flush() - res = fputs(b"hello\n", fw1p) - assert res >= 0 - res = fileno(fw1p) - assert (res == fdw) == (sys.version_info < (3,)) - fw1.close() - # - data = posix.read(fdr, 256) - assert data == b"Xhello\n" - posix.close(fdr) + for fdopen in fdopen_funcs: + fdr, fdw = posix.pipe() + fw1 = fdopen(fdw, 'wb', 256) + # + fw1p = cast(BFILEP, fw1) + fw1.write(b"X") + fw1.flush() + res = fputs(b"hello\n", fw1p) + assert res >= 0 + res = fileno(fw1p) + if fdopen is not io.open and 'PY_DOT_PY' not in globals(): + assert res == fdw + fw1.close() + # + data = posix.read(fdr, 256) + assert data == b"Xhello\n" + posix.close(fdr) def test_GetLastError(): if sys.platform != "win32": diff --git a/pypy/module/_io/interp_iobase.py b/pypy/module/_io/interp_iobase.py --- a/pypy/module/_io/interp_iobase.py +++ b/pypy/module/_io/interp_iobase.py @@ -37,6 +37,8 @@ raise unsupported(space, "File or stream is not seekable") class W_IOBase(Wrappable): + cffi_fileobj = None # pypy/module/_cffi_backend + def __init__(self, space): # XXX: IOBase thinks it has to maintain its own internal state in # `__IOBase_closed` and call flush() by itself, but it is redundant @@ -106,6 +108,12 @@ def close_w(self, space): if self._CLOSED(): return + + cffifo = self.cffi_fileobj + self.cffi_fileobj = None + if cffifo is not None: + cffifo.close() + try: space.call_method(self, "flush") finally: From noreply at buildbot.pypy.org Wed Feb 20 23:19:33 2013 From: noreply at buildbot.pypy.org (amauryfa) Date: Wed, 20 Feb 2013 23:19:33 +0100 (CET) Subject: [pypy-commit] pypy py3k: Fix test_ztranslation: we need to mock another function Message-ID: <20130220221933.CAF311C13D5@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: py3k Changeset: r61502:c2cadefab792 Date: 2013-02-20 23:10 +0100 http://bitbucket.org/pypy/pypy/changeset/c2cadefab792/ Log: Fix test_ztranslation: we need to mock another function diff --git a/pypy/module/_cffi_backend/test/test_ztranslation.py b/pypy/module/_cffi_backend/test/test_ztranslation.py --- a/pypy/module/_cffi_backend/test/test_ztranslation.py +++ b/pypy/module/_cffi_backend/test/test_ztranslation.py @@ -6,15 +6,15 @@ from pypy.module._cffi_backend import misc def test_checkmodule(): - # prepare_file_argument() is not working without translating the _file - # module too - def dummy_prepare_file_argument(space, fileobj): + # W_CTypePointer.prepare_file() is not working without translating + # the _io module too + def dummy_prepare_file(self, w_ob): return lltype.nullptr(rffi.CCHARP.TO) - old = ctypeptr.prepare_file_argument + old = ctypeptr.W_CTypePointer.prepare_file try: - ctypeptr.prepare_file_argument = dummy_prepare_file_argument + ctypeptr.W_CTypePointer.prepare_file = dummy_prepare_file # checkmodule('_cffi_backend') # finally: - ctypeptr.prepare_file_argument = old + ctypeptr.W_CTypePointer.prepare_file = old From noreply at buildbot.pypy.org Wed Feb 20 23:19:35 2013 From: noreply at buildbot.pypy.org (amauryfa) Date: Wed, 20 Feb 2013 23:19:35 +0100 (CET) Subject: [pypy-commit] pypy py3k: Push and pull until test.py -A passes _cffi_backend module. Message-ID: <20130220221935.1B88D1C13D5@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: py3k Changeset: r61503:eaa77dc66d18 Date: 2013-02-20 23:17 +0100 http://bitbucket.org/pypy/pypy/changeset/eaa77dc66d18/ Log: Push and pull until test.py -A passes _cffi_backend module. diff --git a/pypy/module/_cffi_backend/test/test_c.py b/pypy/module/_cffi_backend/test/test_c.py --- a/pypy/module/_cffi_backend/test/test_c.py +++ b/pypy/module/_cffi_backend/test/test_c.py @@ -36,47 +36,60 @@ testfuncs_w = [] keepalive_funcs = [] - def find_and_load_library_for_test(space, w_name, w_is_global=None): - if w_is_global is None: - w_is_global = space.wrap(0) - if space.is_w(w_name, space.w_None): - path = None - else: - import ctypes.util - path = ctypes.util.find_library(space.str_w(w_name)) - return space.appexec([space.wrap(path), w_is_global], - """(path, is_global): - import _cffi_backend - return _cffi_backend.load_library(path, is_global)""") - test_lib_c = tmpdir.join('_test_lib.c') src_test_lib_c = py.path.local(__file__).dirpath().join('_test_lib.c') src_test_lib_c.copy(test_lib_c) eci = ExternalCompilationInfo() - test_lib = host.compile([test_lib_c], eci, standalone=False) + test_lib = str(host.compile([test_lib_c], eci, standalone=False)) - cdll = ctypes.CDLL(str(test_lib)) + cdll = ctypes.CDLL(test_lib) cdll.gettestfunc.restype = ctypes.c_void_p - def testfunc_for_test(space, w_num): - if hasattr(space, 'int_w'): - w_num = space.int_w(w_num) - addr = cdll.gettestfunc(w_num) - return space.wrap(addr) - space = cls.space if cls.runappdirect: - def interp2app(func): - def run(*args): - return func(space, *args) - return run + def find_and_load_library_for_test(name, is_global=False): + if name is None: + path = None + else: + import ctypes.util + path = ctypes.util.find_library(name) + import _cffi_backend + return _cffi_backend.load_library(path, is_global) + + def w_testfunc_for_test(num): + import ctypes + cdll = ctypes.CDLL(str(self.test_lib)) + cdll.gettestfunc.restype = ctypes.c_void_p + return cdll.gettestfunc(num) + + cls.w_test_lib = space.wrap(test_lib) + cls.w_func = find_and_load_library_for_test + cls.w_testfunc = w_testfunc_for_test else: - interp2app = gateway.interp2app + def find_and_load_library_for_test(space, w_name, w_is_global=None): + if w_is_global is None: + w_is_global = space.wrap(0) + if space.is_w(w_name, space.w_None): + path = None + else: + import ctypes.util + path = ctypes.util.find_library(space.str_w(w_name)) + return space.appexec([space.wrap(path), w_is_global], + """(path, is_global): + import _cffi_backend + return _cffi_backend.load_library(path, is_global)""") - w_func = space.wrap(interp2app(find_and_load_library_for_test)) - w_testfunc = space.wrap(interp2app(testfunc_for_test)) - space.appexec([space.wrap(str(tmpdir)), w_func, w_testfunc, - space.wrap(sys.version[:3])], + def testfunc_for_test(space, w_num): + if hasattr(space, 'int_w'): + w_num = space.int_w(w_num) + addr = cdll.gettestfunc(w_num) + return space.wrap(addr) + + cls.w_func = space.wrap(gateway.interp2app(find_and_load_library_for_test)) + cls.w_testfunc = space.wrap(gateway.interp2app(testfunc_for_test)) + cls.w_zz_init = space.appexec( + [space.wrap(str(tmpdir)), cls.w_func, cls.w_testfunc, + space.wrap(sys.version[:3])], """(path, func, testfunc, underlying_version): import sys sys.path.append(path) diff --git a/pypy/tool/pytest/apptest.py b/pypy/tool/pytest/apptest.py --- a/pypy/tool/pytest/apptest.py +++ b/pypy/tool/pytest/apptest.py @@ -36,6 +36,7 @@ def skip(message): print(message) raise SystemExit(0) + __builtins__.skip = skip class ExceptionWrapper: pass def raises(exc, func, *args, **kwargs): @@ -55,12 +56,13 @@ return res else: raise AssertionError("DID NOT RAISE") + __builtins__.raises = raises class Test: pass self = Test() """ defs = [] - for symbol, value in definitions.items(): + for symbol, value in sorted(definitions.items()): if isinstance(value, tuple) and isinstance(value[0], py.code.Source): code, args = value defs.append(str(code)) @@ -70,6 +72,10 @@ arg_repr.append("b%r" % arg) elif isinstance(arg, unicode): arg_repr.append(repr(arg)[1:]) + elif isinstance(arg, types.FunctionType): + arg_repr.append(arg.__name__) + elif isinstance(arg, types.MethodType): + arg_repr.append(arg.__name__) else: arg_repr.append(repr(arg)) args = ','.join(arg_repr) From noreply at buildbot.pypy.org Wed Feb 20 23:19:36 2013 From: noreply at buildbot.pypy.org (amauryfa) Date: Wed, 20 Feb 2013 23:19:36 +0100 (CET) Subject: [pypy-commit] pypy py3k: Enable _cffi_backend module. Message-ID: <20130220221936.490211C13D5@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: py3k Changeset: r61504:dd4c44e4c8fc Date: 2013-02-20 23:18 +0100 http://bitbucket.org/pypy/pypy/changeset/dd4c44e4c8fc/ Log: Enable _cffi_backend module. diff --git a/pypy/config/pypyoption.py b/pypy/config/pypyoption.py --- a/pypy/config/pypyoption.py +++ b/pypy/config/pypyoption.py @@ -35,7 +35,7 @@ "thread", "itertools", "pyexpat", "_ssl", "cpyext", "array", "_bisect", "binascii", "_multiprocessing", '_warnings', "_collections", "_multibytecodec", "_ffi", - "_continuation", "_csv", # "micronumpy", "_cffi_backend", + "_continuation", "_csv", "_cffi_backend", # "micronumpy", "_posixsubprocess", ] )) From noreply at buildbot.pypy.org Thu Feb 21 00:32:08 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Thu, 21 Feb 2013 00:32:08 +0100 (CET) Subject: [pypy-commit] pypy default: Remove verify_fd from interp_fileio and replace it with a call to rposix.validate_fd(). Message-ID: <20130220233208.E2A461C13D5@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: Changeset: r61505:b82871fad050 Date: 2013-02-21 00:30 +0100 http://bitbucket.org/pypy/pypy/changeset/b82871fad050/ Log: Remove verify_fd from interp_fileio and replace it with a call to rposix.validate_fd(). diff --git a/pypy/module/_io/interp_fileio.py b/pypy/module/_io/interp_fileio.py --- a/pypy/module/_io/interp_fileio.py +++ b/pypy/module/_io/interp_fileio.py @@ -3,6 +3,7 @@ from pypy.interpreter.error import OperationError, wrap_oserror, wrap_oserror2 from rpython.rlib.rarithmetic import r_longlong from rpython.rlib.rstring import StringBuilder +from rpython.rlib.rposix import validate_fd from os import O_RDONLY, O_WRONLY, O_RDWR, O_CREAT, O_TRUNC import sys, os, stat, errno from pypy.module._io.interp_iobase import W_RawIOBase, convert_size @@ -117,9 +118,6 @@ return currentsize + BIGCHUNK return currentsize + SMALLCHUNK -def verify_fd(fd): - return - class W_FileIO(W_RawIOBase): def __init__(self, space): W_RawIOBase.__init__(self, space) @@ -156,7 +154,7 @@ fd_is_own = False try: if fd >= 0: - verify_fd(fd) + validate_fd(fd) try: os.fstat(fd) except OSError, e: @@ -237,7 +235,7 @@ self.fd = -1 try: - verify_fd(fd) + validate_fd(fd) os.close(fd) except OSError, e: raise wrap_oserror(space, e, From noreply at buildbot.pypy.org Thu Feb 21 00:33:38 2013 From: noreply at buildbot.pypy.org (amauryfa) Date: Thu, 21 Feb 2013 00:33:38 +0100 (CET) Subject: [pypy-commit] pypy py3k: Fixes for _rawffi tests Message-ID: <20130220233338.527091C13D5@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: py3k Changeset: r61506:eed851e3809b Date: 2013-02-21 00:19 +0100 http://bitbucket.org/pypy/pypy/changeset/eed851e3809b/ Log: Fixes for _rawffi tests diff --git a/pypy/tool/pytest/apptest.py b/pypy/tool/pytest/apptest.py --- a/pypy/tool/pytest/apptest.py +++ b/pypy/tool/pytest/apptest.py @@ -24,6 +24,35 @@ self.excinfo = excinfo +def py3k_repr(value): + "return the repr() that py3k would give for an object.""" + if isinstance(value, str): + # python2 string -> Bytes string + return "b" + repr(value) + elif isinstance(value, unicode): + # python2 unicode -> python3 string + return repr(value)[1:] + elif isinstance(value, list): + return '[' + ', '.join(py3k_repr(item) for item in value) + ']' + elif isinstance(value, tuple): + return '(' + ', '.join(py3k_repr(item) for item in value) + ',)' + elif isinstance(value, dict): + return '{' + ', '.join('%s: %s' % (py3k_repr(key), py3k_repr(value)) + for key, value in value.items()) + '}' + elif isinstance(value, long): + return repr(value)[:-1] + elif isinstance(value, float): + r = repr(value) + if r in ('nan', 'inf', '-inf'): + return "float(%r)" % r + else: + return r + elif isinstance(value, type): + return type.__name__ + else: + return repr(value) + + def run_with_python(python_, target_, **definitions): if python_ is None: py.test.skip("Cannot find the default python3 interpreter to run with -A") @@ -37,6 +66,7 @@ print(message) raise SystemExit(0) __builtins__.skip = skip + __builtins__.py3k_skip = skip class ExceptionWrapper: pass def raises(exc, func, *args, **kwargs): @@ -68,17 +98,13 @@ defs.append(str(code)) arg_repr = [] for arg in args: - if isinstance(arg, str): - arg_repr.append("b%r" % arg) - elif isinstance(arg, unicode): - arg_repr.append(repr(arg)[1:]) - elif isinstance(arg, types.FunctionType): + if isinstance(arg, types.FunctionType): arg_repr.append(arg.__name__) elif isinstance(arg, types.MethodType): arg_repr.append(arg.__name__) else: - arg_repr.append(repr(arg)) - args = ','.join(arg_repr) + arg_repr.append(py3k_repr(arg)) + args = ', '.join(arg_repr) defs.append("self.%s = anonymous(%s)\n" % (symbol, args)) elif isinstance(value, types.MethodType): # "def w_method(self)" @@ -88,14 +114,8 @@ elif isinstance(value, types.ModuleType): name = value.__name__ defs.append("import %s; self.%s = %s\n" % (name, symbol, name)) - elif isinstance(value, str): - # python2 string -> Bytes string - defs.append("self.%s = b%r\n" % (symbol, value)) - elif isinstance(value, unicode): - # python2 unicode -> python3 string - defs.append("self.%s = %s\n" % (symbol, repr(value)[1:])) - elif isinstance(value, (int, float, list, dict)): - defs.append("self.%s = %r\n" % (symbol, value)) + elif isinstance(value, (str, unicode, int, float, list, dict)): + defs.append("self.%s = %s\n" % (symbol, py3k_repr(value))) source = py.code.Source(target_)[1:] pyfile = udir.join('src.py') source = helpers + '\n'.join(defs) + 'if 1:\n' + str(source) From noreply at buildbot.pypy.org Thu Feb 21 00:33:39 2013 From: noreply at buildbot.pypy.org (amauryfa) Date: Thu, 21 Feb 2013 00:33:39 +0100 (CET) Subject: [pypy-commit] pypy py3k: Fixes for applevel tests in sys modules: Message-ID: <20130220233339.97EFB1C13D5@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: py3k Changeset: r61507:89fa26e89071 Date: 2013-02-21 00:33 +0100 http://bitbucket.org/pypy/pypy/changeset/89fa26e89071/ Log: Fixes for applevel tests in sys modules: put test code in a function with a the same name. Also add the traceback to the assertion message. diff --git a/pypy/tool/pytest/apptest.py b/pypy/tool/pytest/apptest.py --- a/pypy/tool/pytest/apptest.py +++ b/pypy/tool/pytest/apptest.py @@ -118,16 +118,20 @@ defs.append("self.%s = %s\n" % (symbol, py3k_repr(value))) source = py.code.Source(target_)[1:] pyfile = udir.join('src.py') - source = helpers + '\n'.join(defs) + 'if 1:\n' + str(source) + target_name = target_.__name__ with pyfile.open('w') as f: - f.write(source) + f.write(helpers) + f.write('\n'.join(defs)) + f.write('def %s():\n' % target_name) + f.write(str(source)) + f.write("\n%s()\n" % target_name) res, stdout, stderr = runsubprocess.run_subprocess( python_, [str(pyfile)]) - print source + print pyfile.read() print >> sys.stdout, stdout print >> sys.stderr, stderr if res > 0: - raise AssertionError("Subprocess failed") + raise AssertionError("Subprocess failed:\n" + stderr) def extract_docstring_if_empty_function(fn): From noreply at buildbot.pypy.org Thu Feb 21 00:37:16 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Thu, 21 Feb 2013 00:37:16 +0100 (CET) Subject: [pypy-commit] pypy py3k: Set sys.std{in, out, err} to None when opening the file descriptors fails instead of raising an error which cannot be printed anyway. Message-ID: <20130220233716.CB8031C13D5@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: py3k Changeset: r61508:28caf27da451 Date: 2013-02-18 13:40 +0100 http://bitbucket.org/pypy/pypy/changeset/28caf27da451/ Log: Set sys.std{in,out,err} to None when opening the file descriptors fails instead of raising an error which cannot be printed anyway. diff --git a/pypy/interpreter/app_main.py b/pypy/interpreter/app_main.py --- a/pypy/interpreter/app_main.py +++ b/pypy/interpreter/app_main.py @@ -274,7 +274,10 @@ newline = None else: newline = '\n' - buf = io.open(fd, mode, buffering, closefd=False) + try: + buf = io.open(fd, mode, buffering, closefd=False) + except OSError: + return None if buffering: raw = buf.raw diff --git a/pypy/interpreter/test2/test_app_main.py b/pypy/interpreter/test2/test_app_main.py --- a/pypy/interpreter/test2/test_app_main.py +++ b/pypy/interpreter/test2/test_app_main.py @@ -760,6 +760,49 @@ child_out_err.close() child_in.close() + # these tests are ported from the stdlib test suite + + def _test_no_stdio(self, streams): + code = """if 1: + import os, sys + for i, s in enumerate({streams}): + if getattr(sys, s) is not None: + os._exit(i + 1) + os._exit(42)""".format(streams=streams) + def preexec(): + if 'stdin' in streams: + os.close(0) + if 'stdout' in streams: + os.close(1) + if 'stderr' in streams: + os.close(2) + p = subprocess.Popen( + [python3, app_main, "-E", "-c", code], + stdin=subprocess.PIPE, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + preexec_fn=preexec) + out, err = p.communicate() + err = re.sub(br"\[\d+ refs\]\r?\n?$", b"", err).strip() + assert err == b'' + assert p.returncode == 42 + + @py.test.mark.skipif("os.name != 'posix'") + def test_no_stdin(self): + self._test_no_stdio(['stdin']) + + @py.test.mark.skipif("os.name != 'posix'") + def test_no_stdout(self): + self._test_no_stdio(['stdout']) + + @py.test.mark.skipif("os.name != 'posix'") + def test_no_stderr(self): + self._test_no_stdio(['stderr']) + + @py.test.mark.skipif("os.name != 'posix'") + def test_no_std_streams(self): + self._test_no_stdio(['stdin', 'stdout', 'stderr']) + def test_proper_sys_path(self, tmpdir): data = self.run('-c "import _ctypes"', python_flags='-S') if data.startswith('Traceback'): From noreply at buildbot.pypy.org Thu Feb 21 00:37:18 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Thu, 21 Feb 2013 00:37:18 +0100 (CET) Subject: [pypy-commit] pypy py3k: Only ignore EBADF. Message-ID: <20130220233718.1A52E1C13D5@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: py3k Changeset: r61509:ec409daee065 Date: 2013-02-20 14:07 +0100 http://bitbucket.org/pypy/pypy/changeset/ec409daee065/ Log: Only ignore EBADF. diff --git a/pypy/interpreter/app_main.py b/pypy/interpreter/app_main.py --- a/pypy/interpreter/app_main.py +++ b/pypy/interpreter/app_main.py @@ -19,6 +19,7 @@ from __future__ import print_function, unicode_literals +import errno import sys DEBUG = False # dump exceptions before calling the except hook @@ -276,7 +277,9 @@ newline = '\n' try: buf = io.open(fd, mode, buffering, closefd=False) - except OSError: + except OSError as e: + if e.errno != errno.EBADF: + raise return None if buffering: From noreply at buildbot.pypy.org Thu Feb 21 00:37:19 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Thu, 21 Feb 2013 00:37:19 +0100 (CET) Subject: [pypy-commit] pypy py3k: hg merge py3k Message-ID: <20130220233719.6E5731C13D5@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: py3k Changeset: r61510:2383a5b7c9b3 Date: 2013-02-21 00:35 +0100 http://bitbucket.org/pypy/pypy/changeset/2383a5b7c9b3/ Log: hg merge py3k diff --git a/pypy/config/pypyoption.py b/pypy/config/pypyoption.py --- a/pypy/config/pypyoption.py +++ b/pypy/config/pypyoption.py @@ -35,7 +35,7 @@ "thread", "itertools", "pyexpat", "_ssl", "cpyext", "array", "_bisect", "binascii", "_multiprocessing", '_warnings', "_collections", "_multibytecodec", "_ffi", - "_continuation", "_csv", # "micronumpy", "_cffi_backend", + "_continuation", "_csv", "_cffi_backend", # "micronumpy", "_posixsubprocess", ] )) diff --git a/pypy/interpreter/error.py b/pypy/interpreter/error.py --- a/pypy/interpreter/error.py +++ b/pypy/interpreter/error.py @@ -164,26 +164,19 @@ # # In the following table, 'Class' means a subclass of BaseException # and 'inst' is an instance of either 'Class' or a subclass of it. - # Or 'Class' can also be an old-style class and 'inst' an old-style - # instance of it. # - # The flow object space only deals with non-advanced case. Old-style - # classes and instances *are* advanced. + # The flow object space only deals with non-advanced case. # # input (w_type, w_value)... becomes... advanced case? # --------------------------------------------------------------------- - # (tuple, w_value) (tuple[0], w_value) yes # (Class, None) (Class, Class()) no # (Class, inst) (inst.__class__, inst) no # (Class, tuple) (Class, Class(*tuple)) yes # (Class, x) (Class, Class(x)) no - # ("string", ...) ("string", ...) deprecated # (inst, None) (inst.__class__, inst) no # w_type = self.w_type w_value = self.get_w_value(space) - while space.is_true(space.isinstance(w_type, space.w_tuple)): - w_type = space.getitem(w_type, space.wrap(0)) if space.exception_is_valid_obj_as_class_w(w_type): # this is for all cases of the form (Class, something) diff --git a/pypy/interpreter/pyopcode.py b/pypy/interpreter/pyopcode.py --- a/pypy/interpreter/pyopcode.py +++ b/pypy/interpreter/pyopcode.py @@ -1161,7 +1161,7 @@ """Raised when exiting a frame via a 'yield' statement.""" class RaiseWithExplicitTraceback(Exception): - """Raised at interp-level by a 0- or 3-arguments 'raise' statement.""" + """Raised at interp-level by a 0-argument 'raise' statement.""" def __init__(self, operr): self.operr = operr diff --git a/pypy/module/_cffi_backend/ctypeptr.py b/pypy/module/_cffi_backend/ctypeptr.py --- a/pypy/module/_cffi_backend/ctypeptr.py +++ b/pypy/module/_cffi_backend/ctypeptr.py @@ -2,6 +2,8 @@ Pointers. """ +import os + from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.error import wrap_oserror from rpython.rtyper.lltypesystem import lltype, rffi @@ -247,11 +249,10 @@ return W_CTypePtrBase.cast(self, w_ob) def prepare_file(self, w_ob): - from pypy.module._file.interp_file import W_File - from pypy.module._cffi_backend import ctypefunc + from pypy.module._io.interp_iobase import W_IOBase ob = self.space.interpclass_w(w_ob) - if isinstance(ob, W_File): - return prepare_file_argument(self.space, ob) + if isinstance(ob, W_IOBase): + return prepare_iofile_argument(self.space, w_ob) else: return lltype.nullptr(rffi.CCHARP.TO) @@ -350,15 +351,21 @@ def close(self): rffi_fclose(self.llf) -def prepare_file_argument(space, fileobj): - fileobj.direct_flush() +def prepare_iofile_argument(space, w_fileobj): + fileobj = space.interpclass_w(w_fileobj) + from pypy.module._io.interp_iobase import W_IOBase + assert isinstance(fileobj, W_IOBase) + space.call_method(w_fileobj, "flush") if fileobj.cffi_fileobj is None: - fd = fileobj.direct_fileno() + fd = space.int_w(space.call_method(w_fileobj, "fileno")) if fd < 0: raise OperationError(space.w_ValueError, space.wrap("file has no OS file descriptor")) + fd = os.dup(fd) + mode = space.str_w(space.getattr(w_fileobj, space.wrap("mode"))) try: - fileobj.cffi_fileobj = CffiFileObj(fd, fileobj.mode) + fileobj.cffi_fileobj = CffiFileObj(fd, mode) except OSError, e: raise wrap_oserror(space, e) return fileobj.cffi_fileobj.llf + diff --git a/pypy/module/_cffi_backend/test/_backend_test_c.py b/pypy/module/_cffi_backend/test/_backend_test_c.py --- a/pypy/module/_cffi_backend/test/_backend_test_c.py +++ b/pypy/module/_cffi_backend/test/_backend_test_c.py @@ -2480,13 +2480,13 @@ assert len(p) == 4 assert list(p) == [b"f", b"o", b"o", b"\x00"] -# XXX hack -if sys.version_info >= (3,): - try: - import posix, io - posix.fdopen = io.open - except ImportError: - pass # win32 +import io +fdopen_funcs = [io.open] +try: + import posix + fdopen_funcs.append(posix.fdopen) +except (ImportError, AttributeError): # win32, or py3k + pass def test_FILE(): if sys.platform == "win32": @@ -2503,22 +2503,22 @@ fputs = ll.load_function(BFunc, "fputs") fscanf = ll.load_function(BFunc2, "fscanf") # - import posix - fdr, fdw = posix.pipe() - fr1 = posix.fdopen(fdr, 'rb', 256) - fw1 = posix.fdopen(fdw, 'wb', 256) - # - fw1.write(b"X") - res = fputs(b"hello world\n", fw1) - assert res >= 0 - fw1.flush() # should not be needed - # - p = newp(new_array_type(BCharP, 100), None) - res = fscanf(fr1, b"%s\n", p) - assert res == 1 - assert string(p) == b"Xhello" - fr1.close() - fw1.close() + for fdopen in fdopen_funcs: + fdr, fdw = posix.pipe() + fr1 = fdopen(fdr, 'rb', 256) + fw1 = fdopen(fdw, 'wb', 256) + # + fw1.write(b"X") + res = fputs(b"hello world\n", fw1) + assert res >= 0 + fw1.flush() # should not be needed + # + p = newp(new_array_type(BCharP, 100), None) + res = fscanf(fr1, b"%s\n", p) + assert res == 1 + assert string(p) == b"Xhello" + fr1.close() + fw1.close() def test_FILE_only_for_FILE_arg(): if sys.platform == "win32": @@ -2533,15 +2533,15 @@ ll = find_and_load_library('c') fputs = ll.load_function(BFunc, "fputs") # - import posix - fdr, fdw = posix.pipe() - fr1 = posix.fdopen(fdr, 'r') - fw1 = posix.fdopen(fdw, 'w') - # - e = py.test.raises(TypeError, fputs, b"hello world\n", fw1) - assert str(e.value).startswith( - "initializer for ctype 'struct NOT_FILE *' must " - "be a cdata pointer, not ") + for fdopen in fdopen_funcs: + fdr, fdw = posix.pipe() + fr1 = fdopen(fdr, 'r') + fw1 = fdopen(fdw, 'w') + # + e = py.test.raises(TypeError, fputs, b"hello world\n", fw1) + assert str(e.value).startswith( + "initializer for ctype 'struct NOT_FILE *' must " + "be a cdata pointer, not ") def test_FILE_object(): if sys.platform == "win32": @@ -2558,22 +2558,23 @@ fputs = ll.load_function(BFunc, "fputs") fileno = ll.load_function(BFunc2, "fileno") # - import posix - fdr, fdw = posix.pipe() - fw1 = posix.fdopen(fdw, 'wb', 256) - # - fw1p = cast(BFILEP, fw1) - fw1.write(b"X") - fw1.flush() - res = fputs(b"hello\n", fw1p) - assert res >= 0 - res = fileno(fw1p) - assert (res == fdw) == (sys.version_info < (3,)) - fw1.close() - # - data = posix.read(fdr, 256) - assert data == b"Xhello\n" - posix.close(fdr) + for fdopen in fdopen_funcs: + fdr, fdw = posix.pipe() + fw1 = fdopen(fdw, 'wb', 256) + # + fw1p = cast(BFILEP, fw1) + fw1.write(b"X") + fw1.flush() + res = fputs(b"hello\n", fw1p) + assert res >= 0 + res = fileno(fw1p) + if fdopen is not io.open and 'PY_DOT_PY' not in globals(): + assert res == fdw + fw1.close() + # + data = posix.read(fdr, 256) + assert data == b"Xhello\n" + posix.close(fdr) def test_GetLastError(): if sys.platform != "win32": diff --git a/pypy/module/_cffi_backend/test/test_c.py b/pypy/module/_cffi_backend/test/test_c.py --- a/pypy/module/_cffi_backend/test/test_c.py +++ b/pypy/module/_cffi_backend/test/test_c.py @@ -36,47 +36,60 @@ testfuncs_w = [] keepalive_funcs = [] - def find_and_load_library_for_test(space, w_name, w_is_global=None): - if w_is_global is None: - w_is_global = space.wrap(0) - if space.is_w(w_name, space.w_None): - path = None - else: - import ctypes.util - path = ctypes.util.find_library(space.str_w(w_name)) - return space.appexec([space.wrap(path), w_is_global], - """(path, is_global): - import _cffi_backend - return _cffi_backend.load_library(path, is_global)""") - test_lib_c = tmpdir.join('_test_lib.c') src_test_lib_c = py.path.local(__file__).dirpath().join('_test_lib.c') src_test_lib_c.copy(test_lib_c) eci = ExternalCompilationInfo() - test_lib = host.compile([test_lib_c], eci, standalone=False) + test_lib = str(host.compile([test_lib_c], eci, standalone=False)) - cdll = ctypes.CDLL(str(test_lib)) + cdll = ctypes.CDLL(test_lib) cdll.gettestfunc.restype = ctypes.c_void_p - def testfunc_for_test(space, w_num): - if hasattr(space, 'int_w'): - w_num = space.int_w(w_num) - addr = cdll.gettestfunc(w_num) - return space.wrap(addr) - space = cls.space if cls.runappdirect: - def interp2app(func): - def run(*args): - return func(space, *args) - return run + def find_and_load_library_for_test(name, is_global=False): + if name is None: + path = None + else: + import ctypes.util + path = ctypes.util.find_library(name) + import _cffi_backend + return _cffi_backend.load_library(path, is_global) + + def w_testfunc_for_test(num): + import ctypes + cdll = ctypes.CDLL(str(self.test_lib)) + cdll.gettestfunc.restype = ctypes.c_void_p + return cdll.gettestfunc(num) + + cls.w_test_lib = space.wrap(test_lib) + cls.w_func = find_and_load_library_for_test + cls.w_testfunc = w_testfunc_for_test else: - interp2app = gateway.interp2app + def find_and_load_library_for_test(space, w_name, w_is_global=None): + if w_is_global is None: + w_is_global = space.wrap(0) + if space.is_w(w_name, space.w_None): + path = None + else: + import ctypes.util + path = ctypes.util.find_library(space.str_w(w_name)) + return space.appexec([space.wrap(path), w_is_global], + """(path, is_global): + import _cffi_backend + return _cffi_backend.load_library(path, is_global)""") - w_func = space.wrap(interp2app(find_and_load_library_for_test)) - w_testfunc = space.wrap(interp2app(testfunc_for_test)) - space.appexec([space.wrap(str(tmpdir)), w_func, w_testfunc, - space.wrap(sys.version[:3])], + def testfunc_for_test(space, w_num): + if hasattr(space, 'int_w'): + w_num = space.int_w(w_num) + addr = cdll.gettestfunc(w_num) + return space.wrap(addr) + + cls.w_func = space.wrap(gateway.interp2app(find_and_load_library_for_test)) + cls.w_testfunc = space.wrap(gateway.interp2app(testfunc_for_test)) + cls.w_zz_init = space.appexec( + [space.wrap(str(tmpdir)), cls.w_func, cls.w_testfunc, + space.wrap(sys.version[:3])], """(path, func, testfunc, underlying_version): import sys sys.path.append(path) diff --git a/pypy/module/_cffi_backend/test/test_ztranslation.py b/pypy/module/_cffi_backend/test/test_ztranslation.py --- a/pypy/module/_cffi_backend/test/test_ztranslation.py +++ b/pypy/module/_cffi_backend/test/test_ztranslation.py @@ -6,15 +6,15 @@ from pypy.module._cffi_backend import misc def test_checkmodule(): - # prepare_file_argument() is not working without translating the _file - # module too - def dummy_prepare_file_argument(space, fileobj): + # W_CTypePointer.prepare_file() is not working without translating + # the _io module too + def dummy_prepare_file(self, w_ob): return lltype.nullptr(rffi.CCHARP.TO) - old = ctypeptr.prepare_file_argument + old = ctypeptr.W_CTypePointer.prepare_file try: - ctypeptr.prepare_file_argument = dummy_prepare_file_argument + ctypeptr.W_CTypePointer.prepare_file = dummy_prepare_file # checkmodule('_cffi_backend') # finally: - ctypeptr.prepare_file_argument = old + ctypeptr.W_CTypePointer.prepare_file = old diff --git a/pypy/module/_io/interp_iobase.py b/pypy/module/_io/interp_iobase.py --- a/pypy/module/_io/interp_iobase.py +++ b/pypy/module/_io/interp_iobase.py @@ -37,6 +37,8 @@ raise unsupported(space, "File or stream is not seekable") class W_IOBase(Wrappable): + cffi_fileobj = None # pypy/module/_cffi_backend + def __init__(self, space): # XXX: IOBase thinks it has to maintain its own internal state in # `__IOBase_closed` and call flush() by itself, but it is redundant @@ -106,6 +108,12 @@ def close_w(self, space): if self._CLOSED(): return + + cffifo = self.cffi_fileobj + self.cffi_fileobj = None + if cffifo is not None: + cffifo.close() + try: space.call_method(self, "flush") finally: diff --git a/pypy/module/_socket/interp_func.py b/pypy/module/_socket/interp_func.py --- a/pypy/module/_socket/interp_func.py +++ b/pypy/module/_socket/interp_func.py @@ -1,5 +1,6 @@ from pypy.interpreter.gateway import unwrap_spec, WrappedDefault -from pypy.module._socket.interp_socket import converted_error, W_RSocket, addr_as_object, ipaddr_from_object +from pypy.module._socket.interp_socket import ( + converted_error, W_RSocket, addr_as_object, ipaddr_from_object, get_error) from rpython.rlib import rsocket from rpython.rlib.rsocket import SocketError, INVALID_SOCKET from pypy.interpreter.error import OperationError @@ -120,7 +121,17 @@ Get host and port for a sockaddr.""" try: - addr = ipaddr_from_object(space, w_sockaddr) + w_host, w_port = space.fixedview(w_sockaddr, 2) + host = space.str_w(w_host) + port = str(space.int_w(w_port)) + lst = rsocket.getaddrinfo(host, port, rsocket.AF_UNSPEC, + rsocket.SOCK_DGRAM, 0, + rsocket.AI_NUMERICHOST) + if len(lst) > 1: + raise OperationError( + get_error(space, 'error'), + space.wrap("sockaddr resolved to multiple addresses")) + addr = lst[0][4] host, servport = rsocket.getnameinfo(addr, flags) except SocketError, e: raise converted_error(space, e) diff --git a/pypy/module/_socket/interp_socket.py b/pypy/module/_socket/interp_socket.py --- a/pypy/module/_socket/interp_socket.py +++ b/pypy/module/_socket/interp_socket.py @@ -158,6 +158,16 @@ except SocketError, e: raise converted_error(space, e) + def __del__(self): + self.clear_all_weakrefs() + if self.space: + self.enqueue_for_destruction(self.space, W_RSocket.destructor, + 'internal __del__ of ') + + def destructor(self): + assert isinstance(self, W_RSocket) + RSocket.__del__(self) + def _dealloc_warn(self): space = self.space if not space: diff --git a/pypy/module/_socket/test/test_sock_app.py b/pypy/module/_socket/test/test_sock_app.py --- a/pypy/module/_socket/test/test_sock_app.py +++ b/pypy/module/_socket/test/test_sock_app.py @@ -262,12 +262,18 @@ ]))) def test_getnameinfo(): + from pypy.module._socket.interp_socket import get_error host = "127.0.0.1" port = 25 info = socket.getnameinfo((host, port), 0) w_l = space.appexec([w_socket, space.wrap(host), space.wrap(port)], "(_socket, host, port): return _socket.getnameinfo((host, port), 0)") assert space.unwrap(w_l) == info + sockaddr = space.newtuple([space.wrap('mail.python.org'), space.wrap(0)]) + space.raises_w(get_error(space, 'error'), space.appexec, + [w_socket, sockaddr, space.wrap(0)], + "(_socket, sockaddr, flags): return _socket.getnameinfo(sockaddr, flags)") + def test_timeout(): space.appexec([w_socket, space.wrap(25.4)], diff --git a/pypy/tool/pytest/apptest.py b/pypy/tool/pytest/apptest.py --- a/pypy/tool/pytest/apptest.py +++ b/pypy/tool/pytest/apptest.py @@ -24,6 +24,35 @@ self.excinfo = excinfo +def py3k_repr(value): + "return the repr() that py3k would give for an object.""" + if isinstance(value, str): + # python2 string -> Bytes string + return "b" + repr(value) + elif isinstance(value, unicode): + # python2 unicode -> python3 string + return repr(value)[1:] + elif isinstance(value, list): + return '[' + ', '.join(py3k_repr(item) for item in value) + ']' + elif isinstance(value, tuple): + return '(' + ', '.join(py3k_repr(item) for item in value) + ',)' + elif isinstance(value, dict): + return '{' + ', '.join('%s: %s' % (py3k_repr(key), py3k_repr(value)) + for key, value in value.items()) + '}' + elif isinstance(value, long): + return repr(value)[:-1] + elif isinstance(value, float): + r = repr(value) + if r in ('nan', 'inf', '-inf'): + return "float(%r)" % r + else: + return r + elif isinstance(value, type): + return type.__name__ + else: + return repr(value) + + def run_with_python(python_, target_, **definitions): if python_ is None: py.test.skip("Cannot find the default python3 interpreter to run with -A") @@ -36,6 +65,8 @@ def skip(message): print(message) raise SystemExit(0) + __builtins__.skip = skip + __builtins__.py3k_skip = skip class ExceptionWrapper: pass def raises(exc, func, *args, **kwargs): @@ -55,24 +86,25 @@ return res else: raise AssertionError("DID NOT RAISE") + __builtins__.raises = raises class Test: pass self = Test() """ defs = [] - for symbol, value in definitions.items(): + for symbol, value in sorted(definitions.items()): if isinstance(value, tuple) and isinstance(value[0], py.code.Source): code, args = value defs.append(str(code)) arg_repr = [] for arg in args: - if isinstance(arg, str): - arg_repr.append("b%r" % arg) - elif isinstance(arg, unicode): - arg_repr.append(repr(arg)[1:]) + if isinstance(arg, types.FunctionType): + arg_repr.append(arg.__name__) + elif isinstance(arg, types.MethodType): + arg_repr.append(arg.__name__) else: - arg_repr.append(repr(arg)) - args = ','.join(arg_repr) + arg_repr.append(py3k_repr(arg)) + args = ', '.join(arg_repr) defs.append("self.%s = anonymous(%s)\n" % (symbol, args)) elif isinstance(value, types.MethodType): # "def w_method(self)" @@ -82,26 +114,24 @@ elif isinstance(value, types.ModuleType): name = value.__name__ defs.append("import %s; self.%s = %s\n" % (name, symbol, name)) - elif isinstance(value, str): - # python2 string -> Bytes string - defs.append("self.%s = b%r\n" % (symbol, value)) - elif isinstance(value, unicode): - # python2 unicode -> python3 string - defs.append("self.%s = %s\n" % (symbol, repr(value)[1:])) - elif isinstance(value, (int, float, list, dict)): - defs.append("self.%s = %r\n" % (symbol, value)) + elif isinstance(value, (str, unicode, int, float, list, dict)): + defs.append("self.%s = %s\n" % (symbol, py3k_repr(value))) source = py.code.Source(target_)[1:] pyfile = udir.join('src.py') - source = helpers + '\n'.join(defs) + 'if 1:\n' + str(source) + target_name = target_.__name__ with pyfile.open('w') as f: - f.write(source) + f.write(helpers) + f.write('\n'.join(defs)) + f.write('def %s():\n' % target_name) + f.write(str(source)) + f.write("\n%s()\n" % target_name) res, stdout, stderr = runsubprocess.run_subprocess( python_, [str(pyfile)]) - print source + print pyfile.read() print >> sys.stdout, stdout print >> sys.stderr, stderr if res > 0: - raise AssertionError("Subprocess failed") + raise AssertionError("Subprocess failed:\n" + stderr) def extract_docstring_if_empty_function(fn): From noreply at buildbot.pypy.org Thu Feb 21 00:37:20 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Thu, 21 Feb 2013 00:37:20 +0100 (CET) Subject: [pypy-commit] pypy py3k: hg merge default Message-ID: <20130220233720.C1AAD1C13D5@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: py3k Changeset: r61511:60e8bbf6448f Date: 2013-02-21 00:36 +0100 http://bitbucket.org/pypy/pypy/changeset/60e8bbf6448f/ Log: hg merge default diff --git a/pypy/module/_io/interp_fileio.py b/pypy/module/_io/interp_fileio.py --- a/pypy/module/_io/interp_fileio.py +++ b/pypy/module/_io/interp_fileio.py @@ -3,6 +3,7 @@ from pypy.interpreter.error import OperationError, wrap_oserror, wrap_oserror2 from rpython.rlib.rarithmetic import r_longlong from rpython.rlib.rstring import StringBuilder +from rpython.rlib.rposix import validate_fd from os import O_RDONLY, O_WRONLY, O_RDWR, O_CREAT, O_TRUNC import sys, os, stat, errno from pypy.module._io.interp_iobase import W_RawIOBase, convert_size @@ -117,9 +118,6 @@ return currentsize + BIGCHUNK return currentsize + SMALLCHUNK -def verify_fd(fd): - return - class W_FileIO(W_RawIOBase): def __init__(self, space): W_RawIOBase.__init__(self, space) @@ -156,7 +154,7 @@ fd_is_own = False try: if fd >= 0: - verify_fd(fd) + validate_fd(fd) try: os.fstat(fd) except OSError, e: @@ -233,7 +231,7 @@ self.fd = -1 try: - verify_fd(fd) + validate_fd(fd) os.close(fd) except OSError, e: raise wrap_oserror(space, e, diff --git a/pypy/module/micronumpy/interp_numarray.py b/pypy/module/micronumpy/interp_numarray.py --- a/pypy/module/micronumpy/interp_numarray.py +++ b/pypy/module/micronumpy/interp_numarray.py @@ -250,7 +250,7 @@ ret = self.implementation.get_imag(self) if ret: return W_NDimArray(ret) - raise OperationError(space.w_NotImplementedError, + raise OperationError(space.w_NotImplementedError, space.wrap('imag not implemented for this dtype')) def descr_set_real(self, space, w_value): @@ -261,7 +261,7 @@ def descr_set_imag(self, space, w_value): # if possible, copy (broadcast) values into self if not self.get_dtype().is_complex_type(): - raise OperationError(space.w_TypeError, + raise OperationError(space.w_TypeError, space.wrap('array does not have imaginary part to set')) tmp = self.implementation.get_imag(self) tmp.setslice(space, convert_to_array(space, w_value)) @@ -302,11 +302,11 @@ @unwrap_spec(axis1=int, axis2=int) def descr_swapaxes(self, space, axis1, axis2): """a.swapaxes(axis1, axis2) - + Return a view of the array with `axis1` and `axis2` interchanged. - + Refer to `numpy.swapaxes` for full documentation. - + See Also -------- numpy.swapaxes : equivalent function @@ -439,7 +439,7 @@ ret = impl.base() if ret is None: return space.w_None - return ret + return ret @unwrap_spec(inplace=bool) def descr_byteswap(self, space, inplace=False): @@ -492,7 +492,7 @@ "axis1 and axis2 cannot be the same")) return interp_arrayops.diagonal(space, self.implementation, offset, axis1, axis2) - + def descr_dump(self, space, w_file): raise OperationError(space.w_NotImplementedError, space.wrap( "dump not implemented yet")) @@ -509,7 +509,7 @@ raise OperationError(space.w_NotImplementedError, space.wrap( "setting flags not implemented yet")) - @unwrap_spec(offset=int) + @unwrap_spec(offset=int) def descr_getfield(self, space, w_dtype, offset): raise OperationError(space.w_NotImplementedError, space.wrap( "getfield not implemented yet")) @@ -518,7 +518,7 @@ raise OperationError(space.w_NotImplementedError, space.wrap( "itemset not implemented yet")) - @unwrap_spec(neworder=str) + @unwrap_spec(neworder=str) def descr_newbyteorder(self, space, neworder): raise OperationError(space.w_NotImplementedError, space.wrap( "newbyteorder not implemented yet")) @@ -551,7 +551,7 @@ raise OperationError(space.w_NotImplementedError, space.wrap( "setfield not implemented yet")) - def descr_setflags(self, space, w_write=None, w_align=None, w_uic=None): + def descr_setflags(self, space, w_write=None, w_align=None, w_uic=None): raise OperationError(space.w_NotImplementedError, space.wrap( "setflags not implemented yet")) @@ -572,7 +572,7 @@ "tofile not implemented yet")) def descr_trace(self, space, w_offset=0, w_axis1=0, w_axis2=1, - w_dtype=None, w_out=None): + w_dtype=None, w_out=None): raise OperationError(space.w_NotImplementedError, space.wrap( "trace not implemented yet")) @@ -627,21 +627,23 @@ w_remainder = self.descr_mod(space, w_other) return space.newtuple([w_quotient, w_remainder]) - _descr_eq = _binop_impl("equal") + def _binop_comp_impl(ufunc): + def impl(self, space, w_other, w_out=None): + try: + return ufunc(self, space, w_other, w_out) + except OperationError, e: + if e.match(space, space.w_ValueError): + return space.w_False + raise e - def descr_eq(self, space, w_other): - try: - return self._descr_eq(space, w_other) - except OperationError, e: - if e.match(space, space.w_ValueError): - return space.w_False - raise e + return func_with_new_name(impl, ufunc.func_name) - descr_ne = _binop_impl("not_equal") - descr_lt = _binop_impl("less") - descr_le = _binop_impl("less_equal") - descr_gt = _binop_impl("greater") - descr_ge = _binop_impl("greater_equal") + descr_eq = _binop_comp_impl(_binop_impl("equal")) + descr_ne = _binop_comp_impl(_binop_impl("not_equal")) + descr_lt = _binop_comp_impl(_binop_impl("less")) + descr_le = _binop_comp_impl(_binop_impl("less_equal")) + descr_gt = _binop_comp_impl(_binop_impl("greater")) + descr_ge = _binop_comp_impl(_binop_impl("greater_equal")) def _binop_right_impl(ufunc_name): def impl(self, space, w_other, w_out=None): @@ -707,7 +709,7 @@ if space.is_none(w_out): out = None elif not isinstance(w_out, W_NDimArray): - raise OperationError(space.w_TypeError, space.wrap( + raise OperationError(space.w_TypeError, space.wrap( 'output must be an array')) else: out = w_out @@ -727,7 +729,7 @@ descr_cumsum = _reduce_ufunc_impl('add', cumultative=True) descr_cumprod = _reduce_ufunc_impl('multiply', cumultative=True) - + def descr_mean(self, space, w_axis=None, w_out=None): if space.is_none(w_axis): w_denom = space.wrap(self.get_size()) @@ -872,7 +874,7 @@ swapaxes = interp2app(W_NDimArray.descr_swapaxes), flat = GetSetProperty(W_NDimArray.descr_get_flatiter), item = interp2app(W_NDimArray.descr_item), - real = GetSetProperty(W_NDimArray.descr_get_real, + real = GetSetProperty(W_NDimArray.descr_get_real, W_NDimArray.descr_set_real), imag = GetSetProperty(W_NDimArray.descr_get_imag, W_NDimArray.descr_set_imag), @@ -932,7 +934,7 @@ dtype) #if dtype is interp_dtype.get_dtype_cache(space).w_float64dtype: # break - + if dtype is None: dtype = interp_dtype.get_dtype_cache(space).w_float64dtype if ndmin > len(shape): diff --git a/pypy/objspace/std/floatobject.py b/pypy/objspace/std/floatobject.py --- a/pypy/objspace/std/floatobject.py +++ b/pypy/objspace/std/floatobject.py @@ -10,7 +10,7 @@ from rpython.rlib.rarithmetic import ovfcheck_float_to_int, intmask, LONG_BIT from rpython.rlib.rfloat import ( isinf, isnan, isfinite, INFINITY, NAN, copysign, formatd, - DTSF_ADD_DOT_0, DTSF_STR_PRECISION) + DTSF_ADD_DOT_0, DTSF_STR_PRECISION, float_as_rbigint_ratio) from rpython.rlib.rbigint import rbigint from rpython.rlib import rfloat from rpython.tool.sourcetools import func_with_new_name @@ -544,27 +544,18 @@ def float_as_integer_ratio__Float(space, w_float): value = w_float.floatval - if isinf(value): + try: + num, den = float_as_rbigint_ratio(value) + except OverflowError: w_msg = space.wrap("cannot pass infinity to as_integer_ratio()") raise OperationError(space.w_OverflowError, w_msg) - elif isnan(value): + except ValueError: w_msg = space.wrap("cannot pass nan to as_integer_ratio()") raise OperationError(space.w_ValueError, w_msg) - float_part, exp = math.frexp(value) - for i in range(300): - if float_part == math.floor(float_part): - break - float_part *= 2.0 - exp -= 1 - w_num = W_LongObject.fromfloat(space, float_part) - w_den = space.newlong(1) - w_exp = space.newlong(abs(exp)) - w_exp = space.lshift(w_den, w_exp) - if exp > 0: - w_num = space.mul(w_num, w_exp) - else: - w_den = w_exp - # Try to return int. + + w_num = space.newlong_from_rbigint(num) + w_den = space.newlong_from_rbigint(den) + # Try to return int return space.newtuple([space.int(w_num), space.int(w_den)]) def float_is_integer__Float(space, w_float): diff --git a/rpython/rlib/rfloat.py b/rpython/rlib/rfloat.py --- a/rpython/rlib/rfloat.py +++ b/rpython/rlib/rfloat.py @@ -419,3 +419,25 @@ def isfinite(x): "NOT_RPYTHON" return not isinf(x) and not isnan(x) + +def float_as_rbigint_ratio(value): + from rpython.rlib.rbigint import rbigint + + if isinf(value): + raise OverflowError("cannot pass infinity to as_integer_ratio()") + elif isnan(value): + raise ValueError("cannot pass nan to as_integer_ratio()") + float_part, exp_int = math.frexp(value) + for i in range(300): + if float_part == math.floor(float_part): + break + float_part *= 2.0 + exp_int -= 1 + num = rbigint.fromfloat(float_part) + den = rbigint.fromint(1) + exp = den.lshift(abs(exp_int)) + if exp_int > 0: + num = num.mul(exp) + else: + den = exp + return num, den diff --git a/rpython/rlib/test/test_rfloat.py b/rpython/rlib/test/test_rfloat.py new file mode 100644 --- /dev/null +++ b/rpython/rlib/test/test_rfloat.py @@ -0,0 +1,131 @@ +import sys, py + +from rpython.rlib.rfloat import float_as_rbigint_ratio +from rpython.rlib.rfloat import break_up_float +from rpython.rlib.rfloat import copysign +from rpython.rlib.rfloat import round_away +from rpython.rlib.rfloat import round_double +from rpython.rlib.rbigint import rbigint + +def test_copysign(): + assert copysign(1, 1) == 1 + assert copysign(-1, 1) == 1 + assert copysign(-1, -1) == -1 + assert copysign(1, -1) == -1 + assert copysign(1, -0.) == -1 + +def test_round_away(): + assert round_away(.1) == 0. + assert round_away(.5) == 1. + assert round_away(.7) == 1. + assert round_away(1.) == 1. + assert round_away(-.5) == -1. + assert round_away(-.1) == 0. + assert round_away(-.7) == -1. + assert round_away(0.) == 0. + +def test_round_double(): + def almost_equal(x, y): + assert round(abs(x-y), 7) == 0 + + almost_equal(round_double(0.125, 2), 0.13) + almost_equal(round_double(0.375, 2), 0.38) + almost_equal(round_double(0.625, 2), 0.63) + almost_equal(round_double(0.875, 2), 0.88) + almost_equal(round_double(-0.125, 2), -0.13) + almost_equal(round_double(-0.375, 2), -0.38) + almost_equal(round_double(-0.625, 2), -0.63) + almost_equal(round_double(-0.875, 2), -0.88) + + almost_equal(round_double(0.25, 1), 0.3) + almost_equal(round_double(0.75, 1), 0.8) + almost_equal(round_double(-0.25, 1), -0.3) + almost_equal(round_double(-0.75, 1), -0.8) + + round_double(-6.5, 0) == -7.0 + round_double(-5.5, 0) == -6.0 + round_double(-1.5, 0) == -2.0 + round_double(-0.5, 0) == -1.0 + round_double(0.5, 0) == 1.0 + round_double(1.5, 0) == 2.0 + round_double(2.5, 0) == 3.0 + round_double(3.5, 0) == 4.0 + round_double(4.5, 0) == 5.0 + round_double(5.5, 0) == 6.0 + round_double(6.5, 0) == 7.0 + + round_double(-25.0, -1) == -30.0 + round_double(-15.0, -1) == -20.0 + round_double(-5.0, -1) == -10.0 + round_double(5.0, -1) == 10.0 + round_double(15.0, -1) == 20.0 + round_double(25.0, -1) == 30.0 + round_double(35.0, -1) == 40.0 + round_double(45.0, -1) == 50.0 + round_double(55.0, -1) == 60.0 + round_double(65.0, -1) == 70.0 + round_double(75.0, -1) == 80.0 + round_double(85.0, -1) == 90.0 + round_double(95.0, -1) == 100.0 + round_double(12325.0, -1) == 12330.0 + + round_double(350.0, -2) == 400.0 + round_double(450.0, -2) == 500.0 + + almost_equal(round_double(0.5e21, -21), 1e21) + almost_equal(round_double(1.5e21, -21), 2e21) + almost_equal(round_double(2.5e21, -21), 3e21) + almost_equal(round_double(5.5e21, -21), 6e21) + almost_equal(round_double(8.5e21, -21), 9e21) + + almost_equal(round_double(-1.5e22, -22), -2e22) + almost_equal(round_double(-0.5e22, -22), -1e22) + almost_equal(round_double(0.5e22, -22), 1e22) + almost_equal(round_double(1.5e22, -22), 2e22) + +def test_round_half_even(): + from rpython.rlib import rfloat + for func in (rfloat.round_double_short_repr, + rfloat.round_double_fallback_repr): + # 2.x behavior + assert func(2.5, 0, False) == 3.0 + # 3.x behavior + assert func(2.5, 0, True) == 2.0 + +def test_break_up_float(): + assert break_up_float('1') == ('', '1', '', '') + assert break_up_float('+1') == ('+', '1', '', '') + assert break_up_float('-1') == ('-', '1', '', '') + + assert break_up_float('.5') == ('', '', '5', '') + + assert break_up_float('1.2e3') == ('', '1', '2', '3') + assert break_up_float('1.2e+3') == ('', '1', '2', '+3') + assert break_up_float('1.2e-3') == ('', '1', '2', '-3') + + # some that will get thrown out on return: + assert break_up_float('.') == ('', '', '', '') + assert break_up_float('+') == ('+', '', '', '') + assert break_up_float('-') == ('-', '', '', '') + assert break_up_float('e1') == ('', '', '', '1') + + py.test.raises(ValueError, break_up_float, 'e') + + +def test_float_as_rbigint_ratio(): + for f, ratio in [ + (0.875, (7, 8)), + (-0.875, (-7, 8)), + (0.0, (0, 1)), + (11.5, (23, 2)), + ]: + num, den = float_as_rbigint_ratio(f) + assert num.eq(rbigint.fromint(ratio[0])) + assert den.eq(rbigint.fromint(ratio[1])) + + with py.test.raises(OverflowError): + float_as_rbigint_ratio(float('inf')) + with py.test.raises(OverflowError): + float_as_rbigint_ratio(float('-inf')) + with py.test.raises(ValueError): + float_as_rbigint_ratio(float('nan')) diff --git a/rpython/rtyper/test/test_rfloat.py b/rpython/rtyper/test/test_rfloat.py --- a/rpython/rtyper/test/test_rfloat.py +++ b/rpython/rtyper/test/test_rfloat.py @@ -216,26 +216,6 @@ # https://bugzilla.novell.com/show_bug.cgi?id=692493 assert not self.interpret(fn, [1e200, 1e200]) # nan - def test_break_up_float(self): - from rpython.rlib.rfloat import break_up_float - assert break_up_float('1') == ('', '1', '', '') - assert break_up_float('+1') == ('+', '1', '', '') - assert break_up_float('-1') == ('-', '1', '', '') - - assert break_up_float('.5') == ('', '', '5', '') - - assert break_up_float('1.2e3') == ('', '1', '2', '3') - assert break_up_float('1.2e+3') == ('', '1', '2', '+3') - assert break_up_float('1.2e-3') == ('', '1', '2', '-3') - - # some that will get thrown out on return: - assert break_up_float('.') == ('', '', '', '') - assert break_up_float('+') == ('+', '', '', '') - assert break_up_float('-') == ('-', '', '', '') - assert break_up_float('e1') == ('', '', '', '1') - - py.test.raises(ValueError, break_up_float, 'e') - def test_formatd(self): from rpython.rlib.rfloat import formatd def f(x): @@ -296,93 +276,6 @@ assert self.interpret(func, [0]) == 1e23 assert self.interpret(func, [1]) == -1e23 - def test_copysign(self): - from rpython.rlib.rfloat import copysign - assert copysign(1, 1) == 1 - assert copysign(-1, 1) == 1 - assert copysign(-1, -1) == -1 - assert copysign(1, -1) == -1 - assert copysign(1, -0.) == -1 - - def test_round_away(self): - from rpython.rlib.rfloat import round_away - assert round_away(.1) == 0. - assert round_away(.5) == 1. - assert round_away(.7) == 1. - assert round_away(1.) == 1. - assert round_away(-.5) == -1. - assert round_away(-.1) == 0. - assert round_away(-.7) == -1. - assert round_away(0.) == 0. - - def test_round_double(self): - from rpython.rlib.rfloat import round_double - def almost_equal(x, y): - assert round(abs(x-y), 7) == 0 - - almost_equal(round_double(0.125, 2), 0.13) - almost_equal(round_double(0.375, 2), 0.38) - almost_equal(round_double(0.625, 2), 0.63) - almost_equal(round_double(0.875, 2), 0.88) - almost_equal(round_double(-0.125, 2), -0.13) - almost_equal(round_double(-0.375, 2), -0.38) - almost_equal(round_double(-0.625, 2), -0.63) - almost_equal(round_double(-0.875, 2), -0.88) - - almost_equal(round_double(0.25, 1), 0.3) - almost_equal(round_double(0.75, 1), 0.8) - almost_equal(round_double(-0.25, 1), -0.3) - almost_equal(round_double(-0.75, 1), -0.8) - - round_double(-6.5, 0) == -7.0 - round_double(-5.5, 0) == -6.0 - round_double(-1.5, 0) == -2.0 - round_double(-0.5, 0) == -1.0 - round_double(0.5, 0) == 1.0 - round_double(1.5, 0) == 2.0 - round_double(2.5, 0) == 3.0 - round_double(3.5, 0) == 4.0 - round_double(4.5, 0) == 5.0 - round_double(5.5, 0) == 6.0 - round_double(6.5, 0) == 7.0 - - round_double(-25.0, -1) == -30.0 - round_double(-15.0, -1) == -20.0 - round_double(-5.0, -1) == -10.0 - round_double(5.0, -1) == 10.0 - round_double(15.0, -1) == 20.0 - round_double(25.0, -1) == 30.0 - round_double(35.0, -1) == 40.0 - round_double(45.0, -1) == 50.0 - round_double(55.0, -1) == 60.0 - round_double(65.0, -1) == 70.0 - round_double(75.0, -1) == 80.0 - round_double(85.0, -1) == 90.0 - round_double(95.0, -1) == 100.0 - round_double(12325.0, -1) == 12330.0 - - round_double(350.0, -2) == 400.0 - round_double(450.0, -2) == 500.0 - - almost_equal(round_double(0.5e21, -21), 1e21) - almost_equal(round_double(1.5e21, -21), 2e21) - almost_equal(round_double(2.5e21, -21), 3e21) - almost_equal(round_double(5.5e21, -21), 6e21) - almost_equal(round_double(8.5e21, -21), 9e21) - - almost_equal(round_double(-1.5e22, -22), -2e22) - almost_equal(round_double(-0.5e22, -22), -1e22) - almost_equal(round_double(0.5e22, -22), 1e22) - almost_equal(round_double(1.5e22, -22), 2e22) - - def test_round_half_even(self): - from rpython.rlib import rfloat - for func in (rfloat.round_double_short_repr, - rfloat.round_double_fallback_repr): - # 2.x behavior - assert func(2.5, 0, False) == 3.0 - # 3.x behavior - assert func(2.5, 0, True) == 2.0 class TestLLtype(BaseTestRfloat, LLRtypeMixin): From noreply at buildbot.pypy.org Thu Feb 21 01:06:51 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Thu, 21 Feb 2013 01:06:51 +0100 (CET) Subject: [pypy-commit] pypy py3k: As the comment states, this test is too strong indeed. Message-ID: <20130221000651.2DF631C3C2D@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: py3k Changeset: r61512:177135a9fa92 Date: 2013-02-21 01:06 +0100 http://bitbucket.org/pypy/pypy/changeset/177135a9fa92/ Log: As the comment states, this test is too strong indeed. diff --git a/lib-python/3.2/test/pickletester.py b/lib-python/3.2/test/pickletester.py --- a/lib-python/3.2/test/pickletester.py +++ b/lib-python/3.2/test/pickletester.py @@ -1107,6 +1107,7 @@ self.assertEqual(list(loaded.keys()), ["key"]) self.assertEqual(loaded["key"].value, "Set-Cookie: key=value") + @impl_detail("This test is too strong indeed", pypy=False) def test_pickle_to_2x(self): # Pickle non-trivial data with protocol 2, expecting that it yields # the same result as Python 2.x did. From noreply at buildbot.pypy.org Thu Feb 21 01:15:25 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Thu, 21 Feb 2013 01:15:25 +0100 (CET) Subject: [pypy-commit] pypy default: backout 65f3a63f53d0: this isn't needed, use enqueue_for_destruction instead Message-ID: <20130221001525.3B6CB1C3C2D@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: Changeset: r61513:d1a7a5386ab0 Date: 2013-02-20 16:08 -0800 http://bitbucket.org/pypy/pypy/changeset/d1a7a5386ab0/ Log: backout 65f3a63f53d0: this isn't needed, use enqueue_for_destruction instead diff --git a/rpython/rlib/rsocket.py b/rpython/rlib/rsocket.py --- a/rpython/rlib/rsocket.py +++ b/rpython/rlib/rsocket.py @@ -497,15 +497,8 @@ def __del__(self): fd = self.fd if fd != _c.INVALID_SOCKET: - try: - self._dealloc_warn() - finally: - self.fd = _c.INVALID_SOCKET - _c.socketclose(fd) - - def _dealloc_warn(self): - """Called when implicitly closed via the deconstructor""" - pass + self.fd = _c.INVALID_SOCKET + _c.socketclose(fd) if hasattr(_c, 'fcntl'): def _setblocking(self, block): From noreply at buildbot.pypy.org Thu Feb 21 01:15:26 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Thu, 21 Feb 2013 01:15:26 +0100 (CET) Subject: [pypy-commit] pypy py3k: merge default Message-ID: <20130221001526.A3B3C1C3C2D@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61514:b8956f10796f Date: 2013-02-20 16:09 -0800 http://bitbucket.org/pypy/pypy/changeset/b8956f10796f/ Log: merge default diff --git a/rpython/rlib/rsocket.py b/rpython/rlib/rsocket.py --- a/rpython/rlib/rsocket.py +++ b/rpython/rlib/rsocket.py @@ -497,15 +497,8 @@ def __del__(self): fd = self.fd if fd != _c.INVALID_SOCKET: - try: - self._dealloc_warn() - finally: - self.fd = _c.INVALID_SOCKET - _c.socketclose(fd) - - def _dealloc_warn(self): - """Called when implicitly closed via the deconstructor""" - pass + self.fd = _c.INVALID_SOCKET + _c.socketclose(fd) if hasattr(_c, 'fcntl'): def _setblocking(self, block): From noreply at buildbot.pypy.org Thu Feb 21 01:15:27 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Thu, 21 Feb 2013 01:15:27 +0100 (CET) Subject: [pypy-commit] pypy py3k: fix BufferedReader.seek to always check the underlying raw's seekability Message-ID: <20130221001527.EF5511C3C2D@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61515:de6b3b05077e Date: 2013-02-20 16:11 -0800 http://bitbucket.org/pypy/pypy/changeset/de6b3b05077e/ Log: fix BufferedReader.seek to always check the underlying raw's seekability diff --git a/pypy/module/_io/interp_bufferedio.py b/pypy/module/_io/interp_bufferedio.py --- a/pypy/module/_io/interp_bufferedio.py +++ b/pypy/module/_io/interp_bufferedio.py @@ -266,6 +266,7 @@ raise operationerrfmt(space.w_ValueError, "whence must be between 0 and 2, not %d", whence) self._check_closed(space, "seek of closed file") + check_seekable_w(space, self.w_raw) if whence != 2 and self.readable: # Check if seeking leaves us inside the current buffer, so as to # return quickly if possible. Also, we needn't take the lock in diff --git a/pypy/module/_io/test/test_bufferedio.py b/pypy/module/_io/test/test_bufferedio.py --- a/pypy/module/_io/test/test_bufferedio.py +++ b/pypy/module/_io/test/test_bufferedio.py @@ -223,9 +223,12 @@ raise _io.UnsupportedOperation("not seekable") def tell(self, *args): raise _io.UnsupportedOperation("not seekable") - bufio = _io.BufferedReader(Unseekable()) + bufio = _io.BufferedReader(Unseekable(b"A" * 10)) raises(_io.UnsupportedOperation, bufio.tell) raises(_io.UnsupportedOperation, bufio.seek, 0) + bufio.read(1) + raises(_io.UnsupportedOperation, bufio.seek, 0) + raises(_io.UnsupportedOperation, bufio.tell) class AppTestBufferedReaderWithThreads(AppTestBufferedReader): spaceconfig = dict(usemodules=['_io', 'thread']) From noreply at buildbot.pypy.org Thu Feb 21 01:15:29 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Thu, 21 Feb 2013 01:15:29 +0100 (CET) Subject: [pypy-commit] pypy py3k: cleanup destruction now that we're fully responsible for it Message-ID: <20130221001529.2DB601C3C2D@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61516:bb1736dca67c Date: 2013-02-20 16:12 -0800 http://bitbucket.org/pypy/pypy/changeset/bb1736dca67c/ Log: cleanup destruction now that we're fully responsible for it diff --git a/pypy/module/_socket/interp_socket.py b/pypy/module/_socket/interp_socket.py --- a/pypy/module/_socket/interp_socket.py +++ b/pypy/module/_socket/interp_socket.py @@ -166,12 +166,14 @@ def destructor(self): assert isinstance(self, W_RSocket) - RSocket.__del__(self) + if self.fd != rsocket.INVALID_SOCKET: + try: + self._dealloc_warn() + finally: + self.close_w(self.space) def _dealloc_warn(self): space = self.space - if not space: - return try: msg = (u"unclosed %s" % space.unicode_w(space.repr(space.wrap(self)))) From noreply at buildbot.pypy.org Thu Feb 21 01:15:30 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Thu, 21 Feb 2013 01:15:30 +0100 (CET) Subject: [pypy-commit] pypy py3k: fix getnameinfo's handling of ipv6 addrs Message-ID: <20130221001530.4A98A1C3C2D@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61517:073c18fd3eb3 Date: 2013-02-20 16:13 -0800 http://bitbucket.org/pypy/pypy/changeset/073c18fd3eb3/ Log: fix getnameinfo's handling of ipv6 addrs diff --git a/pypy/module/_socket/interp_func.py b/pypy/module/_socket/interp_func.py --- a/pypy/module/_socket/interp_func.py +++ b/pypy/module/_socket/interp_func.py @@ -1,6 +1,6 @@ from pypy.interpreter.gateway import unwrap_spec, WrappedDefault from pypy.module._socket.interp_socket import ( - converted_error, W_RSocket, addr_as_object, ipaddr_from_object, get_error) + converted_error, W_RSocket, addr_as_object, fill_from_object, get_error) from rpython.rlib import rsocket from rpython.rlib.rsocket import SocketError, INVALID_SOCKET from pypy.interpreter.error import OperationError @@ -121,9 +121,8 @@ Get host and port for a sockaddr.""" try: - w_host, w_port = space.fixedview(w_sockaddr, 2) - host = space.str_w(w_host) - port = str(space.int_w(w_port)) + host = space.str_w((space.getitem(w_sockaddr, space.wrap(0)))) + port = str(space.int_w(space.getitem(w_sockaddr, space.wrap(1)))) lst = rsocket.getaddrinfo(host, port, rsocket.AF_UNSPEC, rsocket.SOCK_DGRAM, 0, rsocket.AI_NUMERICHOST) @@ -132,6 +131,7 @@ get_error(space, 'error'), space.wrap("sockaddr resolved to multiple addresses")) addr = lst[0][4] + fill_from_object(addr, space, w_sockaddr) host, servport = rsocket.getnameinfo(addr, flags) except SocketError, e: raise converted_error(space, e) diff --git a/pypy/module/_socket/test/test_sock_app.py b/pypy/module/_socket/test/test_sock_app.py --- a/pypy/module/_socket/test/test_sock_app.py +++ b/pypy/module/_socket/test/test_sock_app.py @@ -273,7 +273,12 @@ space.raises_w(get_error(space, 'error'), space.appexec, [w_socket, sockaddr, space.wrap(0)], "(_socket, sockaddr, flags): return _socket.getnameinfo(sockaddr, flags)") - + if socket.has_ipv6: + sockaddr = space.newtuple([space.wrap('::1'), space.wrap(0), + space.wrap(0xffffffff)]) + space.raises_w(space.w_OverflowError, space.appexec, + [w_socket, sockaddr, space.wrap(0)], + "(_socket, sockaddr, flags): return _socket.getnameinfo(sockaddr, flags)") def test_timeout(): space.appexec([w_socket, space.wrap(25.4)], From noreply at buildbot.pypy.org Thu Feb 21 01:15:31 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Thu, 21 Feb 2013 01:15:31 +0100 (CET) Subject: [pypy-commit] pypy py3k: redo the 'reset to g' from 52765baaf1aa so it actually works this time Message-ID: <20130221001531.832AA1C3C2D@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61518:27567bc935f6 Date: 2013-02-20 16:14 -0800 http://bitbucket.org/pypy/pypy/changeset/27567bc935f6/ Log: redo the 'reset to g' from 52765baaf1aa so it actually works this time diff --git a/pypy/objspace/std/newformat.py b/pypy/objspace/std/newformat.py --- a/pypy/objspace/std/newformat.py +++ b/pypy/objspace/std/newformat.py @@ -949,6 +949,8 @@ add_pct = False if self._precision == -1: self._precision = default_precision + elif tp == "r": + tp = "g" result, special = rfloat.double_to_string(value, tp, self._precision, flags) if add_pct: diff --git a/pypy/objspace/std/test/test_floatobject.py b/pypy/objspace/std/test/test_floatobject.py --- a/pypy/objspace/std/test/test_floatobject.py +++ b/pypy/objspace/std/test/test_floatobject.py @@ -444,6 +444,9 @@ def test_format(self): f = 1.1234e200 assert f.__format__("G") == "1.1234E+200" + assert 123.456.__format__('.4') == '123.5' + assert 1234.56.__format__('.4') == '1.235e+03' + assert 12345.6.__format__('.4') == '1.235e+04' def test_float_real(self): class A(float): pass From noreply at buildbot.pypy.org Thu Feb 21 01:22:32 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Thu, 21 Feb 2013 01:22:32 +0100 (CET) Subject: [pypy-commit] pypy py3k: PyPy's pure python implementation raises IndexError in this case. Message-ID: <20130221002232.626B21C3C2D@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: py3k Changeset: r61519:2cf493ed28e2 Date: 2013-02-21 01:16 +0100 http://bitbucket.org/pypy/pypy/changeset/2cf493ed28e2/ Log: PyPy's pure python implementation raises IndexError in this case. diff --git a/lib-python/3.2/test/pickletester.py b/lib-python/3.2/test/pickletester.py --- a/lib-python/3.2/test/pickletester.py +++ b/lib-python/3.2/test/pickletester.py @@ -1387,7 +1387,8 @@ self.assertRaises(EOFError, pickle.loads, s) # Test issue7455 s = b'0' - self.assertRaises(pickle.UnpicklingError, pickle.loads, s) + self.assertRaises((pickle.UnpicklingError, IndexError), + pickle.loads, s) class AbstractPersistentPicklerTests(unittest.TestCase): From noreply at buildbot.pypy.org Thu Feb 21 01:22:33 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Thu, 21 Feb 2013 01:22:33 +0100 (CET) Subject: [pypy-commit] pypy py3k: PyPy doesn't mask the exception. Message-ID: <20130221002233.943D11C3C2D@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: py3k Changeset: r61520:18dcd071de5c Date: 2013-02-21 01:19 +0100 http://bitbucket.org/pypy/pypy/changeset/18dcd071de5c/ Log: PyPy doesn't mask the exception. diff --git a/lib-python/3.2/test/pickletester.py b/lib-python/3.2/test/pickletester.py --- a/lib-python/3.2/test/pickletester.py +++ b/lib-python/3.2/test/pickletester.py @@ -8,7 +8,7 @@ from test.support import ( TestFailed, TESTFN, run_with_locale, - _2G, _4G, bigmemtest, impl_detail + _2G, _4G, bigmemtest, impl_detail, check_impl_detail ) from pickle import bytes_types @@ -1039,9 +1039,14 @@ x = BadGetattr() for proto in 0, 1: self.assertRaises(RuntimeError, self.dumps, x, proto) - # protocol 2 don't raise a RuntimeError. - d = self.dumps(x, 2) - self.assertRaises(RuntimeError, self.loads, d) + if check_impl_detail(cpython=True): + # protocol 2 don't raise a RuntimeError. + d = self.dumps(x, 2) + self.assertRaises(RuntimeError, self.loads, d) + else: + # PyPy doesn't mask the exception + for proto in 2, 3: + self.assertRaises(RuntimeError, self.dumps, x, proto) def test_reduce_bad_iterator(self): # Issue4176: crash when 4th and 5th items of __reduce__() From noreply at buildbot.pypy.org Thu Feb 21 01:22:34 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Thu, 21 Feb 2013 01:22:34 +0100 (CET) Subject: [pypy-commit] pypy py3k: hg merge py3k Message-ID: <20130221002234.CF5351C3C2D@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: py3k Changeset: r61521:f79af72713a4 Date: 2013-02-21 01:22 +0100 http://bitbucket.org/pypy/pypy/changeset/f79af72713a4/ Log: hg merge py3k diff --git a/pypy/module/_io/interp_bufferedio.py b/pypy/module/_io/interp_bufferedio.py --- a/pypy/module/_io/interp_bufferedio.py +++ b/pypy/module/_io/interp_bufferedio.py @@ -266,6 +266,7 @@ raise operationerrfmt(space.w_ValueError, "whence must be between 0 and 2, not %d", whence) self._check_closed(space, "seek of closed file") + check_seekable_w(space, self.w_raw) if whence != 2 and self.readable: # Check if seeking leaves us inside the current buffer, so as to # return quickly if possible. Also, we needn't take the lock in diff --git a/pypy/module/_io/test/test_bufferedio.py b/pypy/module/_io/test/test_bufferedio.py --- a/pypy/module/_io/test/test_bufferedio.py +++ b/pypy/module/_io/test/test_bufferedio.py @@ -223,9 +223,12 @@ raise _io.UnsupportedOperation("not seekable") def tell(self, *args): raise _io.UnsupportedOperation("not seekable") - bufio = _io.BufferedReader(Unseekable()) + bufio = _io.BufferedReader(Unseekable(b"A" * 10)) raises(_io.UnsupportedOperation, bufio.tell) raises(_io.UnsupportedOperation, bufio.seek, 0) + bufio.read(1) + raises(_io.UnsupportedOperation, bufio.seek, 0) + raises(_io.UnsupportedOperation, bufio.tell) class AppTestBufferedReaderWithThreads(AppTestBufferedReader): spaceconfig = dict(usemodules=['_io', 'thread']) diff --git a/pypy/module/_socket/interp_func.py b/pypy/module/_socket/interp_func.py --- a/pypy/module/_socket/interp_func.py +++ b/pypy/module/_socket/interp_func.py @@ -1,6 +1,6 @@ from pypy.interpreter.gateway import unwrap_spec, WrappedDefault from pypy.module._socket.interp_socket import ( - converted_error, W_RSocket, addr_as_object, ipaddr_from_object, get_error) + converted_error, W_RSocket, addr_as_object, fill_from_object, get_error) from rpython.rlib import rsocket from rpython.rlib.rsocket import SocketError, INVALID_SOCKET from pypy.interpreter.error import OperationError @@ -121,9 +121,8 @@ Get host and port for a sockaddr.""" try: - w_host, w_port = space.fixedview(w_sockaddr, 2) - host = space.str_w(w_host) - port = str(space.int_w(w_port)) + host = space.str_w((space.getitem(w_sockaddr, space.wrap(0)))) + port = str(space.int_w(space.getitem(w_sockaddr, space.wrap(1)))) lst = rsocket.getaddrinfo(host, port, rsocket.AF_UNSPEC, rsocket.SOCK_DGRAM, 0, rsocket.AI_NUMERICHOST) @@ -132,6 +131,7 @@ get_error(space, 'error'), space.wrap("sockaddr resolved to multiple addresses")) addr = lst[0][4] + fill_from_object(addr, space, w_sockaddr) host, servport = rsocket.getnameinfo(addr, flags) except SocketError, e: raise converted_error(space, e) diff --git a/pypy/module/_socket/interp_socket.py b/pypy/module/_socket/interp_socket.py --- a/pypy/module/_socket/interp_socket.py +++ b/pypy/module/_socket/interp_socket.py @@ -166,12 +166,14 @@ def destructor(self): assert isinstance(self, W_RSocket) - RSocket.__del__(self) + if self.fd != rsocket.INVALID_SOCKET: + try: + self._dealloc_warn() + finally: + self.close_w(self.space) def _dealloc_warn(self): space = self.space - if not space: - return try: msg = (u"unclosed %s" % space.unicode_w(space.repr(space.wrap(self)))) diff --git a/pypy/module/_socket/test/test_sock_app.py b/pypy/module/_socket/test/test_sock_app.py --- a/pypy/module/_socket/test/test_sock_app.py +++ b/pypy/module/_socket/test/test_sock_app.py @@ -273,7 +273,12 @@ space.raises_w(get_error(space, 'error'), space.appexec, [w_socket, sockaddr, space.wrap(0)], "(_socket, sockaddr, flags): return _socket.getnameinfo(sockaddr, flags)") - + if socket.has_ipv6: + sockaddr = space.newtuple([space.wrap('::1'), space.wrap(0), + space.wrap(0xffffffff)]) + space.raises_w(space.w_OverflowError, space.appexec, + [w_socket, sockaddr, space.wrap(0)], + "(_socket, sockaddr, flags): return _socket.getnameinfo(sockaddr, flags)") def test_timeout(): space.appexec([w_socket, space.wrap(25.4)], diff --git a/pypy/objspace/std/newformat.py b/pypy/objspace/std/newformat.py --- a/pypy/objspace/std/newformat.py +++ b/pypy/objspace/std/newformat.py @@ -949,6 +949,8 @@ add_pct = False if self._precision == -1: self._precision = default_precision + elif tp == "r": + tp = "g" result, special = rfloat.double_to_string(value, tp, self._precision, flags) if add_pct: diff --git a/pypy/objspace/std/test/test_floatobject.py b/pypy/objspace/std/test/test_floatobject.py --- a/pypy/objspace/std/test/test_floatobject.py +++ b/pypy/objspace/std/test/test_floatobject.py @@ -444,6 +444,9 @@ def test_format(self): f = 1.1234e200 assert f.__format__("G") == "1.1234E+200" + assert 123.456.__format__('.4') == '123.5' + assert 1234.56.__format__('.4') == '1.235e+03' + assert 12345.6.__format__('.4') == '1.235e+04' def test_float_real(self): class A(float): pass diff --git a/rpython/rlib/rsocket.py b/rpython/rlib/rsocket.py --- a/rpython/rlib/rsocket.py +++ b/rpython/rlib/rsocket.py @@ -497,15 +497,8 @@ def __del__(self): fd = self.fd if fd != _c.INVALID_SOCKET: - try: - self._dealloc_warn() - finally: - self.fd = _c.INVALID_SOCKET - _c.socketclose(fd) - - def _dealloc_warn(self): - """Called when implicitly closed via the deconstructor""" - pass + self.fd = _c.INVALID_SOCKET + _c.socketclose(fd) if hasattr(_c, 'fcntl'): def _setblocking(self, block): From noreply at buildbot.pypy.org Thu Feb 21 05:18:00 2013 From: noreply at buildbot.pypy.org (modcloth) Date: Thu, 21 Feb 2013 05:18:00 +0100 (CET) Subject: [pypy-commit] pypy coding-guide-update-rlib-refs: Updating some file/import refs to point at new locations in rpython. Message-ID: <20130221041800.4C75E1C13D5@cobra.cs.uni-duesseldorf.de> Author: Dan Buch Branch: coding-guide-update-rlib-refs Changeset: r61522:d250f67daf8b Date: 2013-02-20 23:12 -0500 http://bitbucket.org/pypy/pypy/changeset/d250f67daf8b/ Log: Updating some file/import refs to point at new locations in rpython. diff --git a/pypy/doc/coding-guide.rst b/pypy/doc/coding-guide.rst --- a/pypy/doc/coding-guide.rst +++ b/pypy/doc/coding-guide.rst @@ -303,7 +303,7 @@ dicts with a unique key type only, provided it is hashable. Custom hash functions and custom equality will not be honored. - Use ``pypy.rlib.objectmodel.r_dict`` for custom hash functions. + Use ``rpython.rlib.objectmodel.r_dict`` for custom hash functions. **list comprehensions** @@ -365,7 +365,7 @@ We use normal integers for signed arithmetic. It means that before translation we get longs in case of overflow, and after translation we get a silent wrap-around. Whenever we need more control, we use the following -helpers (which live the `pypy/rlib/rarithmetic.py`_): +helpers (which live the `rpython/rlib/rarithmetic.py`_): **ovfcheck()** From noreply at buildbot.pypy.org Thu Feb 21 05:18:01 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Thu, 21 Feb 2013 05:18:01 +0100 (CET) Subject: [pypy-commit] pypy default: Merged in modcloth/pypy/coding-guide-update-rlib-refs (pull request #124) Message-ID: <20130221041801.6EB5E1C13D5@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r61523:91bfd223d006 Date: 2013-02-20 20:17 -0800 http://bitbucket.org/pypy/pypy/changeset/91bfd223d006/ Log: Merged in modcloth/pypy/coding-guide-update-rlib-refs (pull request #124) Updating some file/import refs to point at new locations in rpython. diff --git a/pypy/doc/coding-guide.rst b/pypy/doc/coding-guide.rst --- a/pypy/doc/coding-guide.rst +++ b/pypy/doc/coding-guide.rst @@ -303,7 +303,7 @@ dicts with a unique key type only, provided it is hashable. Custom hash functions and custom equality will not be honored. - Use ``pypy.rlib.objectmodel.r_dict`` for custom hash functions. + Use ``rpython.rlib.objectmodel.r_dict`` for custom hash functions. **list comprehensions** @@ -365,7 +365,7 @@ We use normal integers for signed arithmetic. It means that before translation we get longs in case of overflow, and after translation we get a silent wrap-around. Whenever we need more control, we use the following -helpers (which live the `pypy/rlib/rarithmetic.py`_): +helpers (which live the `rpython/rlib/rarithmetic.py`_): **ovfcheck()** From noreply at buildbot.pypy.org Thu Feb 21 06:47:52 2013 From: noreply at buildbot.pypy.org (modcloth) Date: Thu, 21 Feb 2013 06:47:52 +0100 (CET) Subject: [pypy-commit] pypy rlib-doc-rpython-refs: Updating refs in rlib docs for files moved into rpython Message-ID: <20130221054752.5EC371C0228@cobra.cs.uni-duesseldorf.de> Author: Dan Buch Branch: rlib-doc-rpython-refs Changeset: r61524:c3e62afcf5c3 Date: 2013-02-21 00:33 -0500 http://bitbucket.org/pypy/pypy/changeset/c3e62afcf5c3/ Log: Updating refs in rlib docs for files moved into rpython diff --git a/pypy/doc/rlib.rst b/pypy/doc/rlib.rst --- a/pypy/doc/rlib.rst +++ b/pypy/doc/rlib.rst @@ -7,18 +7,18 @@ .. contents:: -This page lists some of the modules in `pypy/rlib`_ together with some hints +This page lists some of the modules in `rpython/rlib`_ together with some hints for what they can be used for. The modules here will make up some general library useful for RPython programs (since most of the standard library modules are not RPython). Most of these modules are somewhat rough still and are likely to change at some point. Usually it is useful to look at the tests in -`pypy/rlib/test`_ to get an impression of how to use a module. +`rpython/rlib/test`_ to get an impression of how to use a module. ``listsort`` ============ -The `pypy/rlib/listsort.py`_ module contains an implementation of the timsort sorting algorithm +The `rpython/rlib/listsort.py`_ module contains an implementation of the timsort sorting algorithm (the sort method of lists is not RPython). To use it, subclass from the ``listsort.TimSort`` class and override the ``lt`` method to change the comparison behaviour. The constructor of ``TimSort`` takes a list as an @@ -30,7 +30,7 @@ ``nonconst`` ============ -The `pypy/rlib/nonconst.py`_ module is useful mostly for tests. The `flow object space`_ and +The `rpython/rlib/nonconst.py`_ module is useful mostly for tests. The `flow object space`_ and the `annotator`_ do quite some constant folding, which is sometimes not desired in a test. To prevent constant folding on a certain value, use the ``NonConst`` class. The constructor of ``NonConst`` takes an arbitrary value. The instance of @@ -44,7 +44,7 @@ ``objectmodel`` =============== -The `pypy/rlib/objectmodel.py`_ module is a mixed bag of various functionality. Some of the +The `rpython/rlib/objectmodel.py`_ module is a mixed bag of various functionality. Some of the more useful ones are: ``ComputedIntSymbolic``: @@ -94,7 +94,7 @@ ``rarithmetic`` =============== -The `pypy/rlib/rarithmetic.py`_ module contains functionality to handle the small differences +The `rpython/rlib/rarithmetic.py`_ module contains functionality to handle the small differences in the behaviour of arithmetic code in regular Python and RPython code. Most of them are already described in the `coding guide`_ @@ -104,7 +104,7 @@ ``rbigint`` =========== -The `pypy/rlib/rbigint.py`_ module contains a full RPython implementation of the Python ``long`` +The `rpython/rlib/rbigint.py`_ module contains a full RPython implementation of the Python ``long`` type (which itself is not supported in RPython). The ``rbigint`` class contains that implementation. To construct ``rbigint`` instances use the static methods ``fromint``, ``frombool``, ``fromfloat`` and ``fromdecimalstr``. To convert back @@ -118,7 +118,7 @@ ``rrandom`` =========== -The `pypy/rlib/rrandom.py`_ module contains an implementation of the mersenne twister random +The `rpython/rlib/rrandom.py`_ module contains an implementation of the mersenne twister random number generator. It contains one class ``Random`` which most importantly has a ``random`` method which returns a pseudo-random floating point number between 0.0 and 1.0. @@ -126,7 +126,7 @@ ``rsocket`` =========== -The `pypy/rlib/rsocket.py`_ module contains an RPython implementation of the functionality of +The `rpython/rlib/rsocket.py`_ module contains an RPython implementation of the functionality of the socket standard library with a slightly different interface. The difficulty with the Python socket API is that addresses are not "well-typed" objects: depending on the address family they are tuples, or strings, and @@ -137,7 +137,7 @@ ``streamio`` ============ -The `pypy/rlib/streamio.py`_ contains an RPython stream I/O implementation (which was started +The `rpython/rlib/streamio.py`_ contains an RPython stream I/O implementation (which was started by Guido van Rossum as `sio.py`_ in the CPython sandbox as a prototype for the upcoming new file implementation in Python 3000). @@ -146,7 +146,7 @@ ``unroll`` ========== -The `pypy/rlib/unroll.py`_ module most importantly contains the function ``unrolling_iterable`` +The `rpython/rlib/unroll.py`_ module most importantly contains the function ``unrolling_iterable`` which wraps an iterator. Looping over the iterator in RPython code will not produce a loop in the resulting flow graph but will unroll the loop instead. @@ -154,7 +154,7 @@ ``parsing`` =========== -The `pypy/rlib/parsing/`_ module is a still in-development module to generate tokenizers and +The `rpython/rlib/parsing/`_ module is a still in-development module to generate tokenizers and parsers in RPython. It is still highly experimental and only really used by the `Prolog interpreter`_ (although in slightly non-standard ways). The easiest way to specify a tokenizer/grammar is to write it down using regular expressions and @@ -204,7 +204,7 @@ anything except a. To parse a regular expression and to get a matcher for it, you can use the -function ``make_runner(s)`` in the ``pypy.rlib.parsing.regexparse`` module. It +function ``make_runner(s)`` in the ``rpython.rlib.parsing.regexparse`` module. It returns a object with a ``recognize(input)`` method that returns True or False depending on whether ``input`` matches the string or not. @@ -213,7 +213,7 @@ EBNF ---- -To describe a tokenizer and a grammar the ``pypy.rlib.parsing.ebnfparse`` +To describe a tokenizer and a grammar the ``rpython.rlib.parsing.ebnfparse`` defines a syntax for doing that. The syntax file contains a sequence or rules. Every rule either describes a @@ -295,7 +295,7 @@ The parsing process builds up a tree consisting of instances of ``Symbol`` and ``Nonterminal``, the former corresponding to tokens, the latter to nonterminal -symbols. Both classes live in the `pypy/rlib/parsing/tree.py`_ module. You can use +symbols. Both classes live in the `rpython/rlib/parsing/tree.py`_ module. You can use the ``view()`` method ``Nonterminal`` instances to get a pygame view of the parse tree. @@ -310,7 +310,7 @@ ++++++++ To write tree visitors for the parse trees that are RPython, there is a special -baseclass ``RPythonVisitor`` in `pypy/rlib/parsing/tree.py`_ to use. If your +baseclass ``RPythonVisitor`` in `rpython/rlib/parsing/tree.py`_ to use. If your class uses this, it will grow a ``dispatch(node)`` method, that calls an appropriate ``visit_`` method, depending on the ``node`` argument. Here the is replaced by the ``symbol`` attribute of the visited node. From noreply at buildbot.pypy.org Thu Feb 21 06:47:53 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Thu, 21 Feb 2013 06:47:53 +0100 (CET) Subject: [pypy-commit] pypy default: Merged in modcloth/pypy/rlib-doc-rpython-refs (pull request #125) Message-ID: <20130221054753.99AEC1C0228@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r61525:9d6c61b0172b Date: 2013-02-20 21:47 -0800 http://bitbucket.org/pypy/pypy/changeset/9d6c61b0172b/ Log: Merged in modcloth/pypy/rlib-doc-rpython-refs (pull request #125) Updating refs in rlib docs for files moved into rpython diff --git a/pypy/doc/rlib.rst b/pypy/doc/rlib.rst --- a/pypy/doc/rlib.rst +++ b/pypy/doc/rlib.rst @@ -7,18 +7,18 @@ .. contents:: -This page lists some of the modules in `pypy/rlib`_ together with some hints +This page lists some of the modules in `rpython/rlib`_ together with some hints for what they can be used for. The modules here will make up some general library useful for RPython programs (since most of the standard library modules are not RPython). Most of these modules are somewhat rough still and are likely to change at some point. Usually it is useful to look at the tests in -`pypy/rlib/test`_ to get an impression of how to use a module. +`rpython/rlib/test`_ to get an impression of how to use a module. ``listsort`` ============ -The `pypy/rlib/listsort.py`_ module contains an implementation of the timsort sorting algorithm +The `rpython/rlib/listsort.py`_ module contains an implementation of the timsort sorting algorithm (the sort method of lists is not RPython). To use it, subclass from the ``listsort.TimSort`` class and override the ``lt`` method to change the comparison behaviour. The constructor of ``TimSort`` takes a list as an @@ -30,7 +30,7 @@ ``nonconst`` ============ -The `pypy/rlib/nonconst.py`_ module is useful mostly for tests. The `flow object space`_ and +The `rpython/rlib/nonconst.py`_ module is useful mostly for tests. The `flow object space`_ and the `annotator`_ do quite some constant folding, which is sometimes not desired in a test. To prevent constant folding on a certain value, use the ``NonConst`` class. The constructor of ``NonConst`` takes an arbitrary value. The instance of @@ -44,7 +44,7 @@ ``objectmodel`` =============== -The `pypy/rlib/objectmodel.py`_ module is a mixed bag of various functionality. Some of the +The `rpython/rlib/objectmodel.py`_ module is a mixed bag of various functionality. Some of the more useful ones are: ``ComputedIntSymbolic``: @@ -94,7 +94,7 @@ ``rarithmetic`` =============== -The `pypy/rlib/rarithmetic.py`_ module contains functionality to handle the small differences +The `rpython/rlib/rarithmetic.py`_ module contains functionality to handle the small differences in the behaviour of arithmetic code in regular Python and RPython code. Most of them are already described in the `coding guide`_ @@ -104,7 +104,7 @@ ``rbigint`` =========== -The `pypy/rlib/rbigint.py`_ module contains a full RPython implementation of the Python ``long`` +The `rpython/rlib/rbigint.py`_ module contains a full RPython implementation of the Python ``long`` type (which itself is not supported in RPython). The ``rbigint`` class contains that implementation. To construct ``rbigint`` instances use the static methods ``fromint``, ``frombool``, ``fromfloat`` and ``fromdecimalstr``. To convert back @@ -118,7 +118,7 @@ ``rrandom`` =========== -The `pypy/rlib/rrandom.py`_ module contains an implementation of the mersenne twister random +The `rpython/rlib/rrandom.py`_ module contains an implementation of the mersenne twister random number generator. It contains one class ``Random`` which most importantly has a ``random`` method which returns a pseudo-random floating point number between 0.0 and 1.0. @@ -126,7 +126,7 @@ ``rsocket`` =========== -The `pypy/rlib/rsocket.py`_ module contains an RPython implementation of the functionality of +The `rpython/rlib/rsocket.py`_ module contains an RPython implementation of the functionality of the socket standard library with a slightly different interface. The difficulty with the Python socket API is that addresses are not "well-typed" objects: depending on the address family they are tuples, or strings, and @@ -137,7 +137,7 @@ ``streamio`` ============ -The `pypy/rlib/streamio.py`_ contains an RPython stream I/O implementation (which was started +The `rpython/rlib/streamio.py`_ contains an RPython stream I/O implementation (which was started by Guido van Rossum as `sio.py`_ in the CPython sandbox as a prototype for the upcoming new file implementation in Python 3000). @@ -146,7 +146,7 @@ ``unroll`` ========== -The `pypy/rlib/unroll.py`_ module most importantly contains the function ``unrolling_iterable`` +The `rpython/rlib/unroll.py`_ module most importantly contains the function ``unrolling_iterable`` which wraps an iterator. Looping over the iterator in RPython code will not produce a loop in the resulting flow graph but will unroll the loop instead. @@ -154,7 +154,7 @@ ``parsing`` =========== -The `pypy/rlib/parsing/`_ module is a still in-development module to generate tokenizers and +The `rpython/rlib/parsing/`_ module is a still in-development module to generate tokenizers and parsers in RPython. It is still highly experimental and only really used by the `Prolog interpreter`_ (although in slightly non-standard ways). The easiest way to specify a tokenizer/grammar is to write it down using regular expressions and @@ -204,7 +204,7 @@ anything except a. To parse a regular expression and to get a matcher for it, you can use the -function ``make_runner(s)`` in the ``pypy.rlib.parsing.regexparse`` module. It +function ``make_runner(s)`` in the ``rpython.rlib.parsing.regexparse`` module. It returns a object with a ``recognize(input)`` method that returns True or False depending on whether ``input`` matches the string or not. @@ -213,7 +213,7 @@ EBNF ---- -To describe a tokenizer and a grammar the ``pypy.rlib.parsing.ebnfparse`` +To describe a tokenizer and a grammar the ``rpython.rlib.parsing.ebnfparse`` defines a syntax for doing that. The syntax file contains a sequence or rules. Every rule either describes a @@ -295,7 +295,7 @@ The parsing process builds up a tree consisting of instances of ``Symbol`` and ``Nonterminal``, the former corresponding to tokens, the latter to nonterminal -symbols. Both classes live in the `pypy/rlib/parsing/tree.py`_ module. You can use +symbols. Both classes live in the `rpython/rlib/parsing/tree.py`_ module. You can use the ``view()`` method ``Nonterminal`` instances to get a pygame view of the parse tree. @@ -310,7 +310,7 @@ ++++++++ To write tree visitors for the parse trees that are RPython, there is a special -baseclass ``RPythonVisitor`` in `pypy/rlib/parsing/tree.py`_ to use. If your +baseclass ``RPythonVisitor`` in `rpython/rlib/parsing/tree.py`_ to use. If your class uses this, it will grow a ``dispatch(node)`` method, that calls an appropriate ``visit_`` method, depending on the ``node`` argument. Here the is replaced by the ``symbol`` attribute of the visited node. From noreply at buildbot.pypy.org Thu Feb 21 07:23:54 2013 From: noreply at buildbot.pypy.org (arigo) Date: Thu, 21 Feb 2013 07:23:54 +0100 (CET) Subject: [pypy-commit] pypy default: Englichifed Message-ID: <20130221062354.E83B81C1265@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r61526:8c960946b101 Date: 2013-02-21 07:23 +0100 http://bitbucket.org/pypy/pypy/changeset/8c960946b101/ Log: Englichifed diff --git a/pypy/doc/coding-guide.rst b/pypy/doc/coding-guide.rst --- a/pypy/doc/coding-guide.rst +++ b/pypy/doc/coding-guide.rst @@ -365,7 +365,7 @@ We use normal integers for signed arithmetic. It means that before translation we get longs in case of overflow, and after translation we get a silent wrap-around. Whenever we need more control, we use the following -helpers (which live the `rpython/rlib/rarithmetic.py`_): +helpers (which live in `rpython/rlib/rarithmetic.py`_): **ovfcheck()** From noreply at buildbot.pypy.org Thu Feb 21 10:44:09 2013 From: noreply at buildbot.pypy.org (fijal) Date: Thu, 21 Feb 2013 10:44:09 +0100 (CET) Subject: [pypy-commit] pypy default: try to make those tests actually test anything Message-ID: <20130221094409.29A301C0228@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r61527:7ef29ceaae85 Date: 2013-02-21 11:40 +0200 http://bitbucket.org/pypy/pypy/changeset/7ef29ceaae85/ Log: try to make those tests actually test anything diff --git a/rpython/jit/backend/x86/test/test_zrpy_gc.py b/rpython/jit/backend/x86/test/test_zrpy_gc.py --- a/rpython/jit/backend/x86/test/test_zrpy_gc.py +++ b/rpython/jit/backend/x86/test/test_zrpy_gc.py @@ -5,10 +5,9 @@ """ import weakref -import py, os -from rpython.annotator import policy as annpolicy +import os from rpython.rlib import rgc -from rpython.rtyper.lltypesystem import lltype, llmemory, rffi +from rpython.rtyper.lltypesystem import lltype from rpython.rlib.jit import JitDriver, dont_look_inside from rpython.rlib.jit import elidable, unroll_safe from rpython.jit.backend.llsupport.gc import GcLLDescr_framework diff --git a/rpython/jit/backend/x86/test/test_zrpy_releasegil.py b/rpython/jit/backend/x86/test/test_zrpy_releasegil.py --- a/rpython/jit/backend/x86/test/test_zrpy_releasegil.py +++ b/rpython/jit/backend/x86/test/test_zrpy_releasegil.py @@ -1,13 +1,13 @@ from rpython.rtyper.lltypesystem import lltype, llmemory, rffi from rpython.rlib.jit import dont_look_inside +from rpython.rlib.objectmodel import invoke_around_extcall from rpython.jit.metainterp.optimizeopt import ALL_OPTS_NAMES -from rpython.rlib.libffi import CDLL, types, ArgChain, clibffi -from rpython.rtyper.lltypesystem.ll2ctypes import libc_name from rpython.rtyper.annlowlevel import llhelper from rpython.jit.backend.x86.test.test_zrpy_gc import BaseFrameworkTests from rpython.jit.backend.x86.test.test_zrpy_gc import check +from rpython.tool.udir import udir class ReleaseGILTests(BaseFrameworkTests): @@ -15,35 +15,33 @@ def define_simple(self): class Glob: - pass + def __init__(self): + self.events = [] glob = Glob() # - def f42(n): - c_strchr = glob.c_strchr - raw = rffi.str2charp("foobar" + chr((n & 63) + 32)) - argchain = ArgChain() - argchain = argchain.arg(rffi.cast(lltype.Signed, raw)) - argchain = argchain.arg(rffi.cast(rffi.INT, ord('b'))) - res = c_strchr.call(argchain, rffi.CCHARP) - check(rffi.charp2str(res) == "bar" + chr((n & 63) + 32)) - rffi.free_charp(raw) - # + + c_strchr = rffi.llexternal('strchr', [rffi.CCHARP, lltype.Signed], + rffi.CCHARP) + + def func(): + glob.events.append("x") + def before(n, x): - libc = CDLL(libc_name) - c_strchr = libc.getpointer('strchr', [types.pointer, types.sint], - types.pointer) - glob.c_strchr = c_strchr + invoke_around_extcall(func, func) return (n, None, None, None, None, None, None, None, None, None, None, None) # def f(n, x, *args): - f42(n) + a = rffi.str2charp(str(n)) + c_strchr(a, ord('0')) + lltype.free(a, flavor='raw') n -= 1 return (n, x) + args return before, f, None def test_simple(self): self.run('simple') + assert 'call_release_gil' in udir.join('test_zrpy_gc.log').read() def define_close_stack(self): # @@ -66,30 +64,23 @@ @dont_look_inside def free1(p): llmemory.raw_free(p) + + c_qsort = rffi.llexternal('qsort', [rffi.VOIDP, rffi.SIZE_T, + rffi.SIZE_T, CALLBACK], lltype.Void) # def f42(): length = len(glob.lst) - c_qsort = glob.c_qsort raw = alloc1() fn = llhelper(CALLBACK, rffi._make_wrapper_for(CALLBACK, callback)) - argchain = ArgChain() - argchain = argchain.arg(rffi.cast(lltype.Signed, raw)) - argchain = argchain.arg(rffi.cast(rffi.SIZE_T, 2)) - argchain = argchain.arg(rffi.cast(rffi.SIZE_T, 8)) - argchain = argchain.arg(rffi.cast(lltype.Signed, fn)) - c_qsort.call(argchain, lltype.Void) + c_qsort(rffi.cast(rffi.VOIDP, raw), rffi.cast(rffi.SIZE_T, 2), + rffi.cast(rffi.SIZE_T, 8), fn) free1(raw) check(len(glob.lst) > length) del glob.lst[:] # def before(n, x): - libc = CDLL(libc_name) - types_size_t = clibffi.cast_type_to_ffitype(rffi.SIZE_T) - c_qsort = libc.getpointer('qsort', [types.pointer, types_size_t, - types_size_t, types.pointer], - types.void) - glob.c_qsort = c_qsort glob.lst = [] + return (n, None, None, None, None, None, None, None, None, None, None, None) # @@ -101,6 +92,7 @@ def test_close_stack(self): self.run('close_stack') + assert 'call_release_gil' in udir.join('test_zrpy_gc.log').read() class TestShadowStack(ReleaseGILTests): From noreply at buildbot.pypy.org Thu Feb 21 10:44:10 2013 From: noreply at buildbot.pypy.org (fijal) Date: Thu, 21 Feb 2013 10:44:10 +0100 (CET) Subject: [pypy-commit] pypy default: make sure we don't collect Message-ID: <20130221094410.7A91A1C0228@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r61528:51827b238db8 Date: 2013-02-21 11:43 +0200 http://bitbucket.org/pypy/pypy/changeset/51827b238db8/ Log: make sure we don't collect diff --git a/rpython/jit/backend/x86/test/test_zrpy_releasegil.py b/rpython/jit/backend/x86/test/test_zrpy_releasegil.py --- a/rpython/jit/backend/x86/test/test_zrpy_releasegil.py +++ b/rpython/jit/backend/x86/test/test_zrpy_releasegil.py @@ -16,7 +16,7 @@ def define_simple(self): class Glob: def __init__(self): - self.events = [] + glob.event = 0 glob = Glob() # @@ -24,7 +24,7 @@ rffi.CCHARP) def func(): - glob.events.append("x") + glob.event += 1 def before(n, x): invoke_around_extcall(func, func) From noreply at buildbot.pypy.org Thu Feb 21 10:44:12 2013 From: noreply at buildbot.pypy.org (fijal) Date: Thu, 21 Feb 2013 10:44:12 +0100 (CET) Subject: [pypy-commit] pypy default: merge Message-ID: <20130221094412.62EC71C0228@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r61529:42ae84d5dfef Date: 2013-02-21 11:43 +0200 http://bitbucket.org/pypy/pypy/changeset/42ae84d5dfef/ Log: merge diff --git a/pypy/doc/coding-guide.rst b/pypy/doc/coding-guide.rst --- a/pypy/doc/coding-guide.rst +++ b/pypy/doc/coding-guide.rst @@ -303,7 +303,7 @@ dicts with a unique key type only, provided it is hashable. Custom hash functions and custom equality will not be honored. - Use ``pypy.rlib.objectmodel.r_dict`` for custom hash functions. + Use ``rpython.rlib.objectmodel.r_dict`` for custom hash functions. **list comprehensions** @@ -365,7 +365,7 @@ We use normal integers for signed arithmetic. It means that before translation we get longs in case of overflow, and after translation we get a silent wrap-around. Whenever we need more control, we use the following -helpers (which live the `pypy/rlib/rarithmetic.py`_): +helpers (which live in `rpython/rlib/rarithmetic.py`_): **ovfcheck()** diff --git a/pypy/doc/rlib.rst b/pypy/doc/rlib.rst --- a/pypy/doc/rlib.rst +++ b/pypy/doc/rlib.rst @@ -7,18 +7,18 @@ .. contents:: -This page lists some of the modules in `pypy/rlib`_ together with some hints +This page lists some of the modules in `rpython/rlib`_ together with some hints for what they can be used for. The modules here will make up some general library useful for RPython programs (since most of the standard library modules are not RPython). Most of these modules are somewhat rough still and are likely to change at some point. Usually it is useful to look at the tests in -`pypy/rlib/test`_ to get an impression of how to use a module. +`rpython/rlib/test`_ to get an impression of how to use a module. ``listsort`` ============ -The `pypy/rlib/listsort.py`_ module contains an implementation of the timsort sorting algorithm +The `rpython/rlib/listsort.py`_ module contains an implementation of the timsort sorting algorithm (the sort method of lists is not RPython). To use it, subclass from the ``listsort.TimSort`` class and override the ``lt`` method to change the comparison behaviour. The constructor of ``TimSort`` takes a list as an @@ -30,7 +30,7 @@ ``nonconst`` ============ -The `pypy/rlib/nonconst.py`_ module is useful mostly for tests. The `flow object space`_ and +The `rpython/rlib/nonconst.py`_ module is useful mostly for tests. The `flow object space`_ and the `annotator`_ do quite some constant folding, which is sometimes not desired in a test. To prevent constant folding on a certain value, use the ``NonConst`` class. The constructor of ``NonConst`` takes an arbitrary value. The instance of @@ -44,7 +44,7 @@ ``objectmodel`` =============== -The `pypy/rlib/objectmodel.py`_ module is a mixed bag of various functionality. Some of the +The `rpython/rlib/objectmodel.py`_ module is a mixed bag of various functionality. Some of the more useful ones are: ``ComputedIntSymbolic``: @@ -94,7 +94,7 @@ ``rarithmetic`` =============== -The `pypy/rlib/rarithmetic.py`_ module contains functionality to handle the small differences +The `rpython/rlib/rarithmetic.py`_ module contains functionality to handle the small differences in the behaviour of arithmetic code in regular Python and RPython code. Most of them are already described in the `coding guide`_ @@ -104,7 +104,7 @@ ``rbigint`` =========== -The `pypy/rlib/rbigint.py`_ module contains a full RPython implementation of the Python ``long`` +The `rpython/rlib/rbigint.py`_ module contains a full RPython implementation of the Python ``long`` type (which itself is not supported in RPython). The ``rbigint`` class contains that implementation. To construct ``rbigint`` instances use the static methods ``fromint``, ``frombool``, ``fromfloat`` and ``fromdecimalstr``. To convert back @@ -118,7 +118,7 @@ ``rrandom`` =========== -The `pypy/rlib/rrandom.py`_ module contains an implementation of the mersenne twister random +The `rpython/rlib/rrandom.py`_ module contains an implementation of the mersenne twister random number generator. It contains one class ``Random`` which most importantly has a ``random`` method which returns a pseudo-random floating point number between 0.0 and 1.0. @@ -126,7 +126,7 @@ ``rsocket`` =========== -The `pypy/rlib/rsocket.py`_ module contains an RPython implementation of the functionality of +The `rpython/rlib/rsocket.py`_ module contains an RPython implementation of the functionality of the socket standard library with a slightly different interface. The difficulty with the Python socket API is that addresses are not "well-typed" objects: depending on the address family they are tuples, or strings, and @@ -137,7 +137,7 @@ ``streamio`` ============ -The `pypy/rlib/streamio.py`_ contains an RPython stream I/O implementation (which was started +The `rpython/rlib/streamio.py`_ contains an RPython stream I/O implementation (which was started by Guido van Rossum as `sio.py`_ in the CPython sandbox as a prototype for the upcoming new file implementation in Python 3000). @@ -146,7 +146,7 @@ ``unroll`` ========== -The `pypy/rlib/unroll.py`_ module most importantly contains the function ``unrolling_iterable`` +The `rpython/rlib/unroll.py`_ module most importantly contains the function ``unrolling_iterable`` which wraps an iterator. Looping over the iterator in RPython code will not produce a loop in the resulting flow graph but will unroll the loop instead. @@ -154,7 +154,7 @@ ``parsing`` =========== -The `pypy/rlib/parsing/`_ module is a still in-development module to generate tokenizers and +The `rpython/rlib/parsing/`_ module is a still in-development module to generate tokenizers and parsers in RPython. It is still highly experimental and only really used by the `Prolog interpreter`_ (although in slightly non-standard ways). The easiest way to specify a tokenizer/grammar is to write it down using regular expressions and @@ -204,7 +204,7 @@ anything except a. To parse a regular expression and to get a matcher for it, you can use the -function ``make_runner(s)`` in the ``pypy.rlib.parsing.regexparse`` module. It +function ``make_runner(s)`` in the ``rpython.rlib.parsing.regexparse`` module. It returns a object with a ``recognize(input)`` method that returns True or False depending on whether ``input`` matches the string or not. @@ -213,7 +213,7 @@ EBNF ---- -To describe a tokenizer and a grammar the ``pypy.rlib.parsing.ebnfparse`` +To describe a tokenizer and a grammar the ``rpython.rlib.parsing.ebnfparse`` defines a syntax for doing that. The syntax file contains a sequence or rules. Every rule either describes a @@ -295,7 +295,7 @@ The parsing process builds up a tree consisting of instances of ``Symbol`` and ``Nonterminal``, the former corresponding to tokens, the latter to nonterminal -symbols. Both classes live in the `pypy/rlib/parsing/tree.py`_ module. You can use +symbols. Both classes live in the `rpython/rlib/parsing/tree.py`_ module. You can use the ``view()`` method ``Nonterminal`` instances to get a pygame view of the parse tree. @@ -310,7 +310,7 @@ ++++++++ To write tree visitors for the parse trees that are RPython, there is a special -baseclass ``RPythonVisitor`` in `pypy/rlib/parsing/tree.py`_ to use. If your +baseclass ``RPythonVisitor`` in `rpython/rlib/parsing/tree.py`_ to use. If your class uses this, it will grow a ``dispatch(node)`` method, that calls an appropriate ``visit_`` method, depending on the ``node`` argument. Here the is replaced by the ``symbol`` attribute of the visited node. diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -1494,10 +1494,11 @@ ) return fd - def warn(self, msg, w_warningcls): - self.appexec([self.wrap(msg), w_warningcls], """(msg, warningcls): + def warn(self, w_msg, w_warningcls, stacklevel=2): + self.appexec([w_msg, w_warningcls, self.wrap(stacklevel)], + """(msg, warningcls, stacklevel): import _warnings - _warnings.warn(msg, warningcls, stacklevel=2) + _warnings.warn(msg, warningcls, stacklevel=stacklevel) """) diff --git a/pypy/interpreter/pyopcode.py b/pypy/interpreter/pyopcode.py --- a/pypy/interpreter/pyopcode.py +++ b/pypy/interpreter/pyopcode.py @@ -776,17 +776,16 @@ @jit.unroll_safe def cmp_exc_match(self, w_1, w_2): - if self.space.is_true(self.space.isinstance(w_2, self.space.w_tuple)): - for w_t in self.space.fixedview(w_2): - if self.space.is_true(self.space.isinstance(w_t, - self.space.w_str)): - self.space.warn("catching of string exceptions is " - "deprecated", - self.space.w_DeprecationWarning) - elif self.space.is_true(self.space.isinstance(w_2, self.space.w_str)): - self.space.warn("catching of string exceptions is deprecated", - self.space.w_DeprecationWarning) - return self.space.newbool(self.space.exception_match(w_1, w_2)) + space = self.space + if space.is_true(space.isinstance(w_2, space.w_tuple)): + for w_t in space.fixedview(w_2): + if space.is_true(space.isinstance(w_t, space.w_str)): + msg = "catching of string exceptions is deprecated" + space.warn(space.wrap(msg), space.w_DeprecationWarning) + elif space.is_true(space.isinstance(w_2, space.w_str)): + msg = "catching of string exceptions is deprecated" + space.warn(space.wrap(msg), space.w_DeprecationWarning) + return space.newbool(space.exception_match(w_1, w_2)) def COMPARE_OP(self, testnum, next_instr): w_2 = self.popvalue() diff --git a/pypy/module/__builtin__/functional.py b/pypy/module/__builtin__/functional.py --- a/pypy/module/__builtin__/functional.py +++ b/pypy/module/__builtin__/functional.py @@ -203,6 +203,7 @@ return min_max_unroll(space, args, implementation_of) else: return min_max_normal(space, args, implementation_of) +min_max._always_inline = True def max(space, __args__): """max(iterable[, key=func]) -> value diff --git a/pypy/module/__builtin__/interp_classobj.py b/pypy/module/__builtin__/interp_classobj.py --- a/pypy/module/__builtin__/interp_classobj.py +++ b/pypy/module/__builtin__/interp_classobj.py @@ -154,9 +154,9 @@ return elif name == "__del__": if self.lookup(space, name) is None: - msg = ("a __del__ method added to an existing class " - "will not be called") - space.warn(msg, space.w_RuntimeWarning) + msg = ("a __del__ method added to an existing class will " + "not be called") + space.warn(space.wrap(msg), space.w_RuntimeWarning) space.setitem(self.w_dict, w_attr, w_value) def descr_delattr(self, space, w_attr): @@ -395,9 +395,9 @@ cache = space.fromcache(Cache) if (not isinstance(self, cache.cls_with_del) and self.getdictvalue(space, '__del__') is None): - msg = ("a __del__ method added to an instance " - "with no __del__ in the class will not be called") - space.warn(msg, space.w_RuntimeWarning) + msg = ("a __del__ method added to an instance with no " + "__del__ in the class will not be called") + space.warn(space.wrap(msg), space.w_RuntimeWarning) if w_meth is not None: space.call_function(w_meth, w_name, w_value) else: @@ -454,11 +454,9 @@ else: w_as_str = self.descr_str(space) if space.len_w(w_format_spec) > 0: - space.warn( - ("object.__format__ with a non-empty format string is " - "deprecated"), - space.w_PendingDeprecationWarning - ) + msg = ("object.__format__ with a non-empty format string is " + "deprecated") + space.warn(space.wrap(msg), space.w_PendingDeprecationWarning) return space.format(w_as_str, w_format_spec) def descr_len(self, space): diff --git a/pypy/module/_io/interp_bufferedio.py b/pypy/module/_io/interp_bufferedio.py --- a/pypy/module/_io/interp_bufferedio.py +++ b/pypy/module/_io/interp_bufferedio.py @@ -76,7 +76,7 @@ raise NotImplementedError def _deprecated_max_buffer_size(self, space): - space.warn("max_buffer_size is deprecated", + space.warn(space.wrap("max_buffer_size is deprecated"), space.w_DeprecationWarning) def read_w(self, space, w_size=None): diff --git a/pypy/module/_io/interp_fileio.py b/pypy/module/_io/interp_fileio.py --- a/pypy/module/_io/interp_fileio.py +++ b/pypy/module/_io/interp_fileio.py @@ -3,6 +3,7 @@ from pypy.interpreter.error import OperationError, wrap_oserror, wrap_oserror2 from rpython.rlib.rarithmetic import r_longlong from rpython.rlib.rstring import StringBuilder +from rpython.rlib.rposix import validate_fd from os import O_RDONLY, O_WRONLY, O_RDWR, O_CREAT, O_TRUNC import sys, os, stat, errno from pypy.module._io.interp_iobase import W_RawIOBase, convert_size @@ -117,9 +118,6 @@ return currentsize + BIGCHUNK return currentsize + SMALLCHUNK -def verify_fd(fd): - return - class W_FileIO(W_RawIOBase): def __init__(self, space): W_RawIOBase.__init__(self, space) @@ -156,7 +154,7 @@ fd_is_own = False try: if fd >= 0: - verify_fd(fd) + validate_fd(fd) try: os.fstat(fd) except OSError, e: @@ -237,7 +235,7 @@ self.fd = -1 try: - verify_fd(fd) + validate_fd(fd) os.close(fd) except OSError, e: raise wrap_oserror(space, e, diff --git a/pypy/module/cpyext/import_.py b/pypy/module/cpyext/import_.py --- a/pypy/module/cpyext/import_.py +++ b/pypy/module/cpyext/import_.py @@ -46,8 +46,9 @@ @cpython_api([CONST_STRING], PyObject) def PyImport_ImportModuleNoBlock(space, name): - space.warn('PyImport_ImportModuleNoBlock() is not non-blocking', - space.w_RuntimeWarning) + space.warn( + space.wrap('PyImport_ImportModuleNoBlock() is not non-blocking'), + space.w_RuntimeWarning) return PyImport_Import(space, space.wrap(rffi.charp2str(name))) @cpython_api([PyObject], PyObject) diff --git a/pypy/module/exceptions/interp_exceptions.py b/pypy/module/exceptions/interp_exceptions.py --- a/pypy/module/exceptions/interp_exceptions.py +++ b/pypy/module/exceptions/interp_exceptions.py @@ -176,8 +176,8 @@ if self.w_message is None: raise OperationError(space.w_AttributeError, space.wrap("message was deleted")) - space.warn("BaseException.message has been deprecated as of Python 2.6", - space.w_DeprecationWarning) + msg = "BaseException.message has been deprecated as of Python 2.6" + space.warn(space.wrap(msg), space.w_DeprecationWarning) return self.w_message def descr_message_set(self, space, w_new): diff --git a/pypy/module/imp/importing.py b/pypy/module/imp/importing.py --- a/pypy/module/imp/importing.py +++ b/pypy/module/imp/importing.py @@ -174,9 +174,9 @@ "Parent module '%s' not loaded, " "cannot perform relative import" % ctxt_package)) else: - space.warn("Parent module '%s' not found " - "while handling absolute import" % ctxt_package, - space.w_RuntimeWarning) + msg = ("Parent module '%s' not found while handling absolute " + "import" % ctxt_package) + space.warn(space.wrap(msg), space.w_RuntimeWarning) rel_modulename = ctxt_package[:dot_position] rel_level = rel_modulename.count('.') + 1 @@ -533,9 +533,9 @@ if modtype in (PY_SOURCE, PY_COMPILED): return FindInfo(PKG_DIRECTORY, filepart, None) else: - msg = "Not importing directory " +\ - "'%s' missing __init__.py" % (filepart,) - space.warn(msg, space.w_ImportWarning) + msg = ("Not importing directory '%s' missing __init__.py" % + (filepart,)) + space.warn(space.wrap(msg), space.w_ImportWarning) modtype, suffix, filemode = find_modtype(space, filepart) try: if modtype in (PY_SOURCE, PY_COMPILED, C_EXTENSION): diff --git a/pypy/module/micronumpy/app_numpy.py b/pypy/module/micronumpy/app_numpy.py --- a/pypy/module/micronumpy/app_numpy.py +++ b/pypy/module/micronumpy/app_numpy.py @@ -67,11 +67,15 @@ def min(a, axis=None, out=None): if not hasattr(a, "min"): a = _numpypy.array(a) + if a.size < 1: + return _numpypy.array([]) return a.min(axis=axis, out=out) def max(a, axis=None, out=None): if not hasattr(a, "max"): a = _numpypy.array(a) + if a.size < 1: + return _numpypy.array([]) return a.max(axis=axis, out=out) def arange(start, stop=None, step=1, dtype=None): diff --git a/pypy/module/micronumpy/interp_numarray.py b/pypy/module/micronumpy/interp_numarray.py --- a/pypy/module/micronumpy/interp_numarray.py +++ b/pypy/module/micronumpy/interp_numarray.py @@ -250,7 +250,7 @@ ret = self.implementation.get_imag(self) if ret: return W_NDimArray(ret) - raise OperationError(space.w_NotImplementedError, + raise OperationError(space.w_NotImplementedError, space.wrap('imag not implemented for this dtype')) def descr_set_real(self, space, w_value): @@ -261,7 +261,7 @@ def descr_set_imag(self, space, w_value): # if possible, copy (broadcast) values into self if not self.get_dtype().is_complex_type(): - raise OperationError(space.w_TypeError, + raise OperationError(space.w_TypeError, space.wrap('array does not have imaginary part to set')) tmp = self.implementation.get_imag(self) tmp.setslice(space, convert_to_array(space, w_value)) @@ -302,11 +302,11 @@ @unwrap_spec(axis1=int, axis2=int) def descr_swapaxes(self, space, axis1, axis2): """a.swapaxes(axis1, axis2) - + Return a view of the array with `axis1` and `axis2` interchanged. - + Refer to `numpy.swapaxes` for full documentation. - + See Also -------- numpy.swapaxes : equivalent function @@ -439,7 +439,7 @@ ret = impl.base() if ret is None: return space.w_None - return ret + return ret @unwrap_spec(inplace=bool) def descr_byteswap(self, space, inplace=False): @@ -492,7 +492,7 @@ "axis1 and axis2 cannot be the same")) return interp_arrayops.diagonal(space, self.implementation, offset, axis1, axis2) - + def descr_dump(self, space, w_file): raise OperationError(space.w_NotImplementedError, space.wrap( "dump not implemented yet")) @@ -509,7 +509,7 @@ raise OperationError(space.w_NotImplementedError, space.wrap( "setting flags not implemented yet")) - @unwrap_spec(offset=int) + @unwrap_spec(offset=int) def descr_getfield(self, space, w_dtype, offset): raise OperationError(space.w_NotImplementedError, space.wrap( "getfield not implemented yet")) @@ -518,7 +518,7 @@ raise OperationError(space.w_NotImplementedError, space.wrap( "itemset not implemented yet")) - @unwrap_spec(neworder=str) + @unwrap_spec(neworder=str) def descr_newbyteorder(self, space, neworder): raise OperationError(space.w_NotImplementedError, space.wrap( "newbyteorder not implemented yet")) @@ -551,7 +551,7 @@ raise OperationError(space.w_NotImplementedError, space.wrap( "setfield not implemented yet")) - def descr_setflags(self, space, w_write=None, w_align=None, w_uic=None): + def descr_setflags(self, space, w_write=None, w_align=None, w_uic=None): raise OperationError(space.w_NotImplementedError, space.wrap( "setflags not implemented yet")) @@ -572,7 +572,7 @@ "tofile not implemented yet")) def descr_trace(self, space, w_offset=0, w_axis1=0, w_axis2=1, - w_dtype=None, w_out=None): + w_dtype=None, w_out=None): raise OperationError(space.w_NotImplementedError, space.wrap( "trace not implemented yet")) @@ -627,12 +627,23 @@ w_remainder = self.descr_mod(space, w_other) return space.newtuple([w_quotient, w_remainder]) - descr_eq = _binop_impl("equal") - descr_ne = _binop_impl("not_equal") - descr_lt = _binop_impl("less") - descr_le = _binop_impl("less_equal") - descr_gt = _binop_impl("greater") - descr_ge = _binop_impl("greater_equal") + def _binop_comp_impl(ufunc): + def impl(self, space, w_other, w_out=None): + try: + return ufunc(self, space, w_other, w_out) + except OperationError, e: + if e.match(space, space.w_ValueError): + return space.w_False + raise e + + return func_with_new_name(impl, ufunc.func_name) + + descr_eq = _binop_comp_impl(_binop_impl("equal")) + descr_ne = _binop_comp_impl(_binop_impl("not_equal")) + descr_lt = _binop_comp_impl(_binop_impl("less")) + descr_le = _binop_comp_impl(_binop_impl("less_equal")) + descr_gt = _binop_comp_impl(_binop_impl("greater")) + descr_ge = _binop_comp_impl(_binop_impl("greater_equal")) def _binop_right_impl(ufunc_name): def impl(self, space, w_other, w_out=None): @@ -698,7 +709,7 @@ if space.is_none(w_out): out = None elif not isinstance(w_out, W_NDimArray): - raise OperationError(space.w_TypeError, space.wrap( + raise OperationError(space.w_TypeError, space.wrap( 'output must be an array')) else: out = w_out @@ -718,7 +729,7 @@ descr_cumsum = _reduce_ufunc_impl('add', cumultative=True) descr_cumprod = _reduce_ufunc_impl('multiply', cumultative=True) - + def descr_mean(self, space, w_axis=None, w_out=None): if space.is_none(w_axis): w_denom = space.wrap(self.get_size()) @@ -863,7 +874,7 @@ swapaxes = interp2app(W_NDimArray.descr_swapaxes), flat = GetSetProperty(W_NDimArray.descr_get_flatiter), item = interp2app(W_NDimArray.descr_item), - real = GetSetProperty(W_NDimArray.descr_get_real, + real = GetSetProperty(W_NDimArray.descr_get_real, W_NDimArray.descr_set_real), imag = GetSetProperty(W_NDimArray.descr_get_imag, W_NDimArray.descr_set_imag), @@ -923,7 +934,7 @@ dtype) #if dtype is interp_dtype.get_dtype_cache(space).w_float64dtype: # break - + if dtype is None: dtype = interp_dtype.get_dtype_cache(space).w_float64dtype if ndmin > len(shape): diff --git a/pypy/module/struct/formatiterator.py b/pypy/module/struct/formatiterator.py --- a/pypy/module/struct/formatiterator.py +++ b/pypy/module/struct/formatiterator.py @@ -84,11 +84,10 @@ def _maybe_float(self, w_obj): space = self.space if space.is_true(space.isinstance(w_obj, space.w_float)): - space.warn("struct: integer argument expected, got float", - space.w_DeprecationWarning) + msg = "struct: integer argument expected, got float" else: - space.warn("integer argument expected, got non-integer", - space.w_DeprecationWarning) + msg = "integer argument expected, got non-integer" + space.warn(space.wrap(msg), space.w_DeprecationWarning) return space.int(w_obj) # wrapped float -> wrapped int or long else: diff --git a/pypy/objspace/std/complexobject.py b/pypy/objspace/std/complexobject.py --- a/pypy/objspace/std/complexobject.py +++ b/pypy/objspace/std/complexobject.py @@ -80,10 +80,8 @@ return W_ComplexObject(rr, ir) def divmod(self, space, other): - space.warn( - "complex divmod(), // and % are deprecated", - space.w_DeprecationWarning - ) + space.warn(space.wrap("complex divmod(), // and % are deprecated"), + space.w_DeprecationWarning) w_div = self.div(other) div = math.floor(w_div.realval) w_mod = self.sub( diff --git a/pypy/objspace/std/floatobject.py b/pypy/objspace/std/floatobject.py --- a/pypy/objspace/std/floatobject.py +++ b/pypy/objspace/std/floatobject.py @@ -10,7 +10,7 @@ from rpython.rlib.rarithmetic import ovfcheck_float_to_int, intmask, LONG_BIT from rpython.rlib.rfloat import ( isinf, isnan, isfinite, INFINITY, NAN, copysign, formatd, - DTSF_ADD_DOT_0, DTSF_STR_PRECISION) + DTSF_ADD_DOT_0, DTSF_STR_PRECISION, float_as_rbigint_ratio) from rpython.rlib.rbigint import rbigint from rpython.rlib import rfloat from rpython.tool.sourcetools import func_with_new_name @@ -553,27 +553,18 @@ def float_as_integer_ratio__Float(space, w_float): value = w_float.floatval - if isinf(value): + try: + num, den = float_as_rbigint_ratio(value) + except OverflowError: w_msg = space.wrap("cannot pass infinity to as_integer_ratio()") raise OperationError(space.w_OverflowError, w_msg) - elif isnan(value): + except ValueError: w_msg = space.wrap("cannot pass nan to as_integer_ratio()") raise OperationError(space.w_ValueError, w_msg) - float_part, exp = math.frexp(value) - for i in range(300): - if float_part == math.floor(float_part): - break - float_part *= 2.0 - exp -= 1 - w_num = W_LongObject.fromfloat(space, float_part) - w_den = space.newlong(1) - w_exp = space.newlong(abs(exp)) - w_exp = space.lshift(w_den, w_exp) - if exp > 0: - w_num = space.mul(w_num, w_exp) - else: - w_den = w_exp - # Try to return int. + + w_num = space.newlong_from_rbigint(num) + w_den = space.newlong_from_rbigint(den) + # Try to return int return space.newtuple([space.int(w_num), space.int(w_den)]) def float_is_integer__Float(space, w_float): diff --git a/pypy/objspace/std/objecttype.py b/pypy/objspace/std/objecttype.py --- a/pypy/objspace/std/objecttype.py +++ b/pypy/objspace/std/objecttype.py @@ -126,11 +126,8 @@ msg = "format_spec must be a string" raise OperationError(space.w_TypeError, space.wrap(msg)) if space.len_w(w_format_spec) > 0: - space.warn( - ("object.__format__ with a non-empty format string is " - "deprecated"), - space.w_PendingDeprecationWarning - ) + msg = "object.__format__ with a non-empty format string is deprecated" + space.warn(space.wrap(msg), space.w_PendingDeprecationWarning) return space.format(w_as_str, w_format_spec) def descr___subclasshook__(space, __args__): diff --git a/pypy/objspace/std/typeobject.py b/pypy/objspace/std/typeobject.py --- a/pypy/objspace/std/typeobject.py +++ b/pypy/objspace/std/typeobject.py @@ -295,8 +295,9 @@ msg = "can't set attributes on type object '%s'" raise operationerrfmt(space.w_TypeError, msg, w_self.name) if name == "__del__" and name not in w_self.dict_w: - msg = "a __del__ method added to an existing type will not be called" - space.warn(msg, space.w_RuntimeWarning) + msg = ("a __del__ method added to an existing type will not be " + "called") + space.warn(space.wrap(msg), space.w_RuntimeWarning) if space.config.objspace.std.withtypeversion: version_tag = w_self.version_tag() if version_tag is not None: diff --git a/pypy/objspace/std/unicodeobject.py b/pypy/objspace/std/unicodeobject.py --- a/pypy/objspace/std/unicodeobject.py +++ b/pypy/objspace/std/unicodeobject.py @@ -119,13 +119,10 @@ w_uni2 = uni_from_str(space, w_str) except OperationError, e: if e.match(space, space.w_UnicodeDecodeError): - if inverse: - msg = "Unicode unequal comparison failed to convert both " \ - "arguments to Unicode - interpreting them as being unequal" - else : - msg = "Unicode equal comparison failed to convert both " \ - "arguments to Unicode - interpreting them as being unequal" - space.warn(msg, space.w_UnicodeWarning) + msg = ("Unicode %s comparison failed to convert both arguments to " + "Unicode - interpreting them as being unequal" % + "unequal" if inverse else "equal") + space.warn(space.wrap(msg), space.w_UnicodeWarning) return space.newbool(inverse) raise result = space.eq(w_uni, w_uni2) diff --git a/rpython/rlib/rfloat.py b/rpython/rlib/rfloat.py --- a/rpython/rlib/rfloat.py +++ b/rpython/rlib/rfloat.py @@ -419,3 +419,25 @@ def isfinite(x): "NOT_RPYTHON" return not isinf(x) and not isnan(x) + +def float_as_rbigint_ratio(value): + from rpython.rlib.rbigint import rbigint + + if isinf(value): + raise OverflowError("cannot pass infinity to as_integer_ratio()") + elif isnan(value): + raise ValueError("cannot pass nan to as_integer_ratio()") + float_part, exp_int = math.frexp(value) + for i in range(300): + if float_part == math.floor(float_part): + break + float_part *= 2.0 + exp_int -= 1 + num = rbigint.fromfloat(float_part) + den = rbigint.fromint(1) + exp = den.lshift(abs(exp_int)) + if exp_int > 0: + num = num.mul(exp) + else: + den = exp + return num, den diff --git a/rpython/rlib/test/test_rfloat.py b/rpython/rlib/test/test_rfloat.py new file mode 100644 --- /dev/null +++ b/rpython/rlib/test/test_rfloat.py @@ -0,0 +1,131 @@ +import sys, py + +from rpython.rlib.rfloat import float_as_rbigint_ratio +from rpython.rlib.rfloat import break_up_float +from rpython.rlib.rfloat import copysign +from rpython.rlib.rfloat import round_away +from rpython.rlib.rfloat import round_double +from rpython.rlib.rbigint import rbigint + +def test_copysign(): + assert copysign(1, 1) == 1 + assert copysign(-1, 1) == 1 + assert copysign(-1, -1) == -1 + assert copysign(1, -1) == -1 + assert copysign(1, -0.) == -1 + +def test_round_away(): + assert round_away(.1) == 0. + assert round_away(.5) == 1. + assert round_away(.7) == 1. + assert round_away(1.) == 1. + assert round_away(-.5) == -1. + assert round_away(-.1) == 0. + assert round_away(-.7) == -1. + assert round_away(0.) == 0. + +def test_round_double(): + def almost_equal(x, y): + assert round(abs(x-y), 7) == 0 + + almost_equal(round_double(0.125, 2), 0.13) + almost_equal(round_double(0.375, 2), 0.38) + almost_equal(round_double(0.625, 2), 0.63) + almost_equal(round_double(0.875, 2), 0.88) + almost_equal(round_double(-0.125, 2), -0.13) + almost_equal(round_double(-0.375, 2), -0.38) + almost_equal(round_double(-0.625, 2), -0.63) + almost_equal(round_double(-0.875, 2), -0.88) + + almost_equal(round_double(0.25, 1), 0.3) + almost_equal(round_double(0.75, 1), 0.8) + almost_equal(round_double(-0.25, 1), -0.3) + almost_equal(round_double(-0.75, 1), -0.8) + + round_double(-6.5, 0) == -7.0 + round_double(-5.5, 0) == -6.0 + round_double(-1.5, 0) == -2.0 + round_double(-0.5, 0) == -1.0 + round_double(0.5, 0) == 1.0 + round_double(1.5, 0) == 2.0 + round_double(2.5, 0) == 3.0 + round_double(3.5, 0) == 4.0 + round_double(4.5, 0) == 5.0 + round_double(5.5, 0) == 6.0 + round_double(6.5, 0) == 7.0 + + round_double(-25.0, -1) == -30.0 + round_double(-15.0, -1) == -20.0 + round_double(-5.0, -1) == -10.0 + round_double(5.0, -1) == 10.0 + round_double(15.0, -1) == 20.0 + round_double(25.0, -1) == 30.0 + round_double(35.0, -1) == 40.0 + round_double(45.0, -1) == 50.0 + round_double(55.0, -1) == 60.0 + round_double(65.0, -1) == 70.0 + round_double(75.0, -1) == 80.0 + round_double(85.0, -1) == 90.0 + round_double(95.0, -1) == 100.0 + round_double(12325.0, -1) == 12330.0 + + round_double(350.0, -2) == 400.0 + round_double(450.0, -2) == 500.0 + + almost_equal(round_double(0.5e21, -21), 1e21) + almost_equal(round_double(1.5e21, -21), 2e21) + almost_equal(round_double(2.5e21, -21), 3e21) + almost_equal(round_double(5.5e21, -21), 6e21) + almost_equal(round_double(8.5e21, -21), 9e21) + + almost_equal(round_double(-1.5e22, -22), -2e22) + almost_equal(round_double(-0.5e22, -22), -1e22) + almost_equal(round_double(0.5e22, -22), 1e22) + almost_equal(round_double(1.5e22, -22), 2e22) + +def test_round_half_even(): + from rpython.rlib import rfloat + for func in (rfloat.round_double_short_repr, + rfloat.round_double_fallback_repr): + # 2.x behavior + assert func(2.5, 0, False) == 3.0 + # 3.x behavior + assert func(2.5, 0, True) == 2.0 + +def test_break_up_float(): + assert break_up_float('1') == ('', '1', '', '') + assert break_up_float('+1') == ('+', '1', '', '') + assert break_up_float('-1') == ('-', '1', '', '') + + assert break_up_float('.5') == ('', '', '5', '') + + assert break_up_float('1.2e3') == ('', '1', '2', '3') + assert break_up_float('1.2e+3') == ('', '1', '2', '+3') + assert break_up_float('1.2e-3') == ('', '1', '2', '-3') + + # some that will get thrown out on return: + assert break_up_float('.') == ('', '', '', '') + assert break_up_float('+') == ('+', '', '', '') + assert break_up_float('-') == ('-', '', '', '') + assert break_up_float('e1') == ('', '', '', '1') + + py.test.raises(ValueError, break_up_float, 'e') + + +def test_float_as_rbigint_ratio(): + for f, ratio in [ + (0.875, (7, 8)), + (-0.875, (-7, 8)), + (0.0, (0, 1)), + (11.5, (23, 2)), + ]: + num, den = float_as_rbigint_ratio(f) + assert num.eq(rbigint.fromint(ratio[0])) + assert den.eq(rbigint.fromint(ratio[1])) + + with py.test.raises(OverflowError): + float_as_rbigint_ratio(float('inf')) + with py.test.raises(OverflowError): + float_as_rbigint_ratio(float('-inf')) + with py.test.raises(ValueError): + float_as_rbigint_ratio(float('nan')) diff --git a/rpython/rtyper/test/test_rfloat.py b/rpython/rtyper/test/test_rfloat.py --- a/rpython/rtyper/test/test_rfloat.py +++ b/rpython/rtyper/test/test_rfloat.py @@ -216,26 +216,6 @@ # https://bugzilla.novell.com/show_bug.cgi?id=692493 assert not self.interpret(fn, [1e200, 1e200]) # nan - def test_break_up_float(self): - from rpython.rlib.rfloat import break_up_float - assert break_up_float('1') == ('', '1', '', '') - assert break_up_float('+1') == ('+', '1', '', '') - assert break_up_float('-1') == ('-', '1', '', '') - - assert break_up_float('.5') == ('', '', '5', '') - - assert break_up_float('1.2e3') == ('', '1', '2', '3') - assert break_up_float('1.2e+3') == ('', '1', '2', '+3') - assert break_up_float('1.2e-3') == ('', '1', '2', '-3') - - # some that will get thrown out on return: - assert break_up_float('.') == ('', '', '', '') - assert break_up_float('+') == ('+', '', '', '') - assert break_up_float('-') == ('-', '', '', '') - assert break_up_float('e1') == ('', '', '', '1') - - py.test.raises(ValueError, break_up_float, 'e') - def test_formatd(self): from rpython.rlib.rfloat import formatd def f(x): @@ -296,93 +276,6 @@ assert self.interpret(func, [0]) == 1e23 assert self.interpret(func, [1]) == -1e23 - def test_copysign(self): - from rpython.rlib.rfloat import copysign - assert copysign(1, 1) == 1 - assert copysign(-1, 1) == 1 - assert copysign(-1, -1) == -1 - assert copysign(1, -1) == -1 - assert copysign(1, -0.) == -1 - - def test_round_away(self): - from rpython.rlib.rfloat import round_away - assert round_away(.1) == 0. - assert round_away(.5) == 1. - assert round_away(.7) == 1. - assert round_away(1.) == 1. - assert round_away(-.5) == -1. - assert round_away(-.1) == 0. - assert round_away(-.7) == -1. - assert round_away(0.) == 0. - - def test_round_double(self): - from rpython.rlib.rfloat import round_double - def almost_equal(x, y): - assert round(abs(x-y), 7) == 0 - - almost_equal(round_double(0.125, 2), 0.13) - almost_equal(round_double(0.375, 2), 0.38) - almost_equal(round_double(0.625, 2), 0.63) - almost_equal(round_double(0.875, 2), 0.88) - almost_equal(round_double(-0.125, 2), -0.13) - almost_equal(round_double(-0.375, 2), -0.38) - almost_equal(round_double(-0.625, 2), -0.63) - almost_equal(round_double(-0.875, 2), -0.88) - - almost_equal(round_double(0.25, 1), 0.3) - almost_equal(round_double(0.75, 1), 0.8) - almost_equal(round_double(-0.25, 1), -0.3) - almost_equal(round_double(-0.75, 1), -0.8) - - round_double(-6.5, 0) == -7.0 - round_double(-5.5, 0) == -6.0 - round_double(-1.5, 0) == -2.0 - round_double(-0.5, 0) == -1.0 - round_double(0.5, 0) == 1.0 - round_double(1.5, 0) == 2.0 - round_double(2.5, 0) == 3.0 - round_double(3.5, 0) == 4.0 - round_double(4.5, 0) == 5.0 - round_double(5.5, 0) == 6.0 - round_double(6.5, 0) == 7.0 - - round_double(-25.0, -1) == -30.0 - round_double(-15.0, -1) == -20.0 - round_double(-5.0, -1) == -10.0 - round_double(5.0, -1) == 10.0 - round_double(15.0, -1) == 20.0 - round_double(25.0, -1) == 30.0 - round_double(35.0, -1) == 40.0 - round_double(45.0, -1) == 50.0 - round_double(55.0, -1) == 60.0 - round_double(65.0, -1) == 70.0 - round_double(75.0, -1) == 80.0 - round_double(85.0, -1) == 90.0 - round_double(95.0, -1) == 100.0 - round_double(12325.0, -1) == 12330.0 - - round_double(350.0, -2) == 400.0 - round_double(450.0, -2) == 500.0 - - almost_equal(round_double(0.5e21, -21), 1e21) - almost_equal(round_double(1.5e21, -21), 2e21) - almost_equal(round_double(2.5e21, -21), 3e21) - almost_equal(round_double(5.5e21, -21), 6e21) - almost_equal(round_double(8.5e21, -21), 9e21) - - almost_equal(round_double(-1.5e22, -22), -2e22) - almost_equal(round_double(-0.5e22, -22), -1e22) - almost_equal(round_double(0.5e22, -22), 1e22) - almost_equal(round_double(1.5e22, -22), 2e22) - - def test_round_half_even(self): - from rpython.rlib import rfloat - for func in (rfloat.round_double_short_repr, - rfloat.round_double_fallback_repr): - # 2.x behavior - assert func(2.5, 0, False) == 3.0 - # 3.x behavior - assert func(2.5, 0, True) == 2.0 class TestLLtype(BaseTestRfloat, LLRtypeMixin): From noreply at buildbot.pypy.org Thu Feb 21 10:48:22 2013 From: noreply at buildbot.pypy.org (fijal) Date: Thu, 21 Feb 2013 10:48:22 +0100 (CET) Subject: [pypy-commit] pypy default: fix Message-ID: <20130221094822.AFFCE1C0228@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r61530:b1d924aa5a40 Date: 2013-02-21 11:47 +0200 http://bitbucket.org/pypy/pypy/changeset/b1d924aa5a40/ Log: fix diff --git a/rpython/jit/backend/x86/test/test_zrpy_releasegil.py b/rpython/jit/backend/x86/test/test_zrpy_releasegil.py --- a/rpython/jit/backend/x86/test/test_zrpy_releasegil.py +++ b/rpython/jit/backend/x86/test/test_zrpy_releasegil.py @@ -16,7 +16,7 @@ def define_simple(self): class Glob: def __init__(self): - glob.event = 0 + self.event = 0 glob = Glob() # diff --git a/rpython/rtyper/test/test_rptr.py b/rpython/rtyper/test/test_rptr.py --- a/rpython/rtyper/test/test_rptr.py +++ b/rpython/rtyper/test/test_rptr.py @@ -336,6 +336,21 @@ res = interpret(f, []) assert res == 1 +def test_interior_ptr_convert(): + S = lltype.Struct("S", ("x", lltype.Signed)) + T = lltype.GcArray(S) + def f(i): + t = lltype.malloc(T, 2) + if i: + x = t[0] + else: + x = t[1] + x.x = 3 + return t[0].x + + res = interpret(f, [13]) + assert res == 3 + def test_interior_ptr_with_field_and_index(): S = lltype.Struct("S", ('x', lltype.Signed)) T = lltype.GcStruct("T", ('items', lltype.Array(S))) From noreply at buildbot.pypy.org Thu Feb 21 10:55:56 2013 From: noreply at buildbot.pypy.org (fijal) Date: Thu, 21 Feb 2013 10:55:56 +0100 (CET) Subject: [pypy-commit] pypy default: fix the filename Message-ID: <20130221095556.19D231C0228@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r61531:4202dd240cc5 Date: 2013-02-21 11:54 +0200 http://bitbucket.org/pypy/pypy/changeset/4202dd240cc5/ Log: fix the filename diff --git a/rpython/jit/backend/x86/test/test_zrpy_releasegil.py b/rpython/jit/backend/x86/test/test_zrpy_releasegil.py --- a/rpython/jit/backend/x86/test/test_zrpy_releasegil.py +++ b/rpython/jit/backend/x86/test/test_zrpy_releasegil.py @@ -41,7 +41,7 @@ def test_simple(self): self.run('simple') - assert 'call_release_gil' in udir.join('test_zrpy_gc.log').read() + assert 'call_release_gil' in udir.join('TestCompileFramework.log').read() def define_close_stack(self): # @@ -92,7 +92,7 @@ def test_close_stack(self): self.run('close_stack') - assert 'call_release_gil' in udir.join('test_zrpy_gc.log').read() + assert 'call_release_gil' in udir.join('TestCompileFramework.log').read() class TestShadowStack(ReleaseGILTests): From noreply at buildbot.pypy.org Thu Feb 21 11:03:55 2013 From: noreply at buildbot.pypy.org (fijal) Date: Thu, 21 Feb 2013 11:03:55 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: merge default Message-ID: <20130221100355.B806A1C0228@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61532:e7aebccb738e Date: 2013-02-21 12:02 +0200 http://bitbucket.org/pypy/pypy/changeset/e7aebccb738e/ Log: merge default diff too long, truncating to 2000 out of 2427 lines diff --git a/lib_pypy/datetime.py b/lib_pypy/datetime.py --- a/lib_pypy/datetime.py +++ b/lib_pypy/datetime.py @@ -271,6 +271,8 @@ raise ValueError("%s()=%d, must be in -1439..1439" % (name, offset)) def _check_int_field(value): + if isinstance(value, int): + return value if not isinstance(value, float): try: value = value.__int__() @@ -279,7 +281,7 @@ else: if isinstance(value, (int, long)): return value - raise TypeError('integer argument expected') + raise TypeError('an integer is required') def _check_date_fields(year, month, day): year = _check_int_field(year) @@ -457,6 +459,8 @@ felt like it. """ + __slots__ = '_days', '_seconds', '_microseconds' + def __new__(cls, days=0, seconds=0, microseconds=0, # XXX The following should only be used as keyword args: milliseconds=0, minutes=0, hours=0, weeks=0): @@ -770,6 +774,8 @@ year, month, day """ + __slots__ = '_year', '_month', '_day' + def __new__(cls, year, month=None, day=None): """Constructor. @@ -777,7 +783,7 @@ year, month, day (required, base 1) """ - if isinstance(year, str): + if isinstance(year, str) and len(year) == 4: # Pickle support self = object.__new__(cls) self.__setstate(year) @@ -1063,6 +1069,8 @@ Subclasses must override the name(), utcoffset() and dst() methods. """ + __slots__ = () + def tzname(self, dt): "datetime -> string name of time zone." raise NotImplementedError("tzinfo subclass must override tzname()") @@ -1155,6 +1163,8 @@ hour, minute, second, microsecond, tzinfo """ + __slots__ = '_hour', '_minute', '_second', '_microsecond', '_tzinfo' + def __new__(cls, hour=0, minute=0, second=0, microsecond=0, tzinfo=None): """Constructor. @@ -1457,9 +1467,11 @@ instance of a tzinfo subclass. The remaining arguments may be ints or longs. """ + __slots__ = date.__slots__ + time.__slots__ + def __new__(cls, year, month=None, day=None, hour=0, minute=0, second=0, microsecond=0, tzinfo=None): - if isinstance(year, str): + if isinstance(year, str) and len(year) == 10: # Pickle support self = date.__new__(cls, year[:4]) self.__setstate(year, month) diff --git a/pypy/doc/coding-guide.rst b/pypy/doc/coding-guide.rst --- a/pypy/doc/coding-guide.rst +++ b/pypy/doc/coding-guide.rst @@ -303,7 +303,7 @@ dicts with a unique key type only, provided it is hashable. Custom hash functions and custom equality will not be honored. - Use ``pypy.rlib.objectmodel.r_dict`` for custom hash functions. + Use ``rpython.rlib.objectmodel.r_dict`` for custom hash functions. **list comprehensions** @@ -365,7 +365,7 @@ We use normal integers for signed arithmetic. It means that before translation we get longs in case of overflow, and after translation we get a silent wrap-around. Whenever we need more control, we use the following -helpers (which live the `pypy/rlib/rarithmetic.py`_): +helpers (which live in `rpython/rlib/rarithmetic.py`_): **ovfcheck()** diff --git a/pypy/doc/getting-started-dev.rst b/pypy/doc/getting-started-dev.rst --- a/pypy/doc/getting-started-dev.rst +++ b/pypy/doc/getting-started-dev.rst @@ -58,8 +58,7 @@ only use low level types that are available in C (e.g. int). The compiled version is now in a ``.so`` library. You can run it say using ctypes: - >>> from ctypes import CDLL - >>> f = CDLL(lib) + >>> f = get_c_function(lib, snippet.is_perfect_number) >>> f(5) 0 >>> f(6) diff --git a/pypy/doc/rlib.rst b/pypy/doc/rlib.rst --- a/pypy/doc/rlib.rst +++ b/pypy/doc/rlib.rst @@ -7,18 +7,18 @@ .. contents:: -This page lists some of the modules in `pypy/rlib`_ together with some hints +This page lists some of the modules in `rpython/rlib`_ together with some hints for what they can be used for. The modules here will make up some general library useful for RPython programs (since most of the standard library modules are not RPython). Most of these modules are somewhat rough still and are likely to change at some point. Usually it is useful to look at the tests in -`pypy/rlib/test`_ to get an impression of how to use a module. +`rpython/rlib/test`_ to get an impression of how to use a module. ``listsort`` ============ -The `pypy/rlib/listsort.py`_ module contains an implementation of the timsort sorting algorithm +The `rpython/rlib/listsort.py`_ module contains an implementation of the timsort sorting algorithm (the sort method of lists is not RPython). To use it, subclass from the ``listsort.TimSort`` class and override the ``lt`` method to change the comparison behaviour. The constructor of ``TimSort`` takes a list as an @@ -30,7 +30,7 @@ ``nonconst`` ============ -The `pypy/rlib/nonconst.py`_ module is useful mostly for tests. The `flow object space`_ and +The `rpython/rlib/nonconst.py`_ module is useful mostly for tests. The `flow object space`_ and the `annotator`_ do quite some constant folding, which is sometimes not desired in a test. To prevent constant folding on a certain value, use the ``NonConst`` class. The constructor of ``NonConst`` takes an arbitrary value. The instance of @@ -44,7 +44,7 @@ ``objectmodel`` =============== -The `pypy/rlib/objectmodel.py`_ module is a mixed bag of various functionality. Some of the +The `rpython/rlib/objectmodel.py`_ module is a mixed bag of various functionality. Some of the more useful ones are: ``ComputedIntSymbolic``: @@ -94,7 +94,7 @@ ``rarithmetic`` =============== -The `pypy/rlib/rarithmetic.py`_ module contains functionality to handle the small differences +The `rpython/rlib/rarithmetic.py`_ module contains functionality to handle the small differences in the behaviour of arithmetic code in regular Python and RPython code. Most of them are already described in the `coding guide`_ @@ -104,7 +104,7 @@ ``rbigint`` =========== -The `pypy/rlib/rbigint.py`_ module contains a full RPython implementation of the Python ``long`` +The `rpython/rlib/rbigint.py`_ module contains a full RPython implementation of the Python ``long`` type (which itself is not supported in RPython). The ``rbigint`` class contains that implementation. To construct ``rbigint`` instances use the static methods ``fromint``, ``frombool``, ``fromfloat`` and ``fromdecimalstr``. To convert back @@ -118,7 +118,7 @@ ``rrandom`` =========== -The `pypy/rlib/rrandom.py`_ module contains an implementation of the mersenne twister random +The `rpython/rlib/rrandom.py`_ module contains an implementation of the mersenne twister random number generator. It contains one class ``Random`` which most importantly has a ``random`` method which returns a pseudo-random floating point number between 0.0 and 1.0. @@ -126,7 +126,7 @@ ``rsocket`` =========== -The `pypy/rlib/rsocket.py`_ module contains an RPython implementation of the functionality of +The `rpython/rlib/rsocket.py`_ module contains an RPython implementation of the functionality of the socket standard library with a slightly different interface. The difficulty with the Python socket API is that addresses are not "well-typed" objects: depending on the address family they are tuples, or strings, and @@ -137,7 +137,7 @@ ``streamio`` ============ -The `pypy/rlib/streamio.py`_ contains an RPython stream I/O implementation (which was started +The `rpython/rlib/streamio.py`_ contains an RPython stream I/O implementation (which was started by Guido van Rossum as `sio.py`_ in the CPython sandbox as a prototype for the upcoming new file implementation in Python 3000). @@ -146,7 +146,7 @@ ``unroll`` ========== -The `pypy/rlib/unroll.py`_ module most importantly contains the function ``unrolling_iterable`` +The `rpython/rlib/unroll.py`_ module most importantly contains the function ``unrolling_iterable`` which wraps an iterator. Looping over the iterator in RPython code will not produce a loop in the resulting flow graph but will unroll the loop instead. @@ -154,7 +154,7 @@ ``parsing`` =========== -The `pypy/rlib/parsing/`_ module is a still in-development module to generate tokenizers and +The `rpython/rlib/parsing/`_ module is a still in-development module to generate tokenizers and parsers in RPython. It is still highly experimental and only really used by the `Prolog interpreter`_ (although in slightly non-standard ways). The easiest way to specify a tokenizer/grammar is to write it down using regular expressions and @@ -204,7 +204,7 @@ anything except a. To parse a regular expression and to get a matcher for it, you can use the -function ``make_runner(s)`` in the ``pypy.rlib.parsing.regexparse`` module. It +function ``make_runner(s)`` in the ``rpython.rlib.parsing.regexparse`` module. It returns a object with a ``recognize(input)`` method that returns True or False depending on whether ``input`` matches the string or not. @@ -213,7 +213,7 @@ EBNF ---- -To describe a tokenizer and a grammar the ``pypy.rlib.parsing.ebnfparse`` +To describe a tokenizer and a grammar the ``rpython.rlib.parsing.ebnfparse`` defines a syntax for doing that. The syntax file contains a sequence or rules. Every rule either describes a @@ -295,7 +295,7 @@ The parsing process builds up a tree consisting of instances of ``Symbol`` and ``Nonterminal``, the former corresponding to tokens, the latter to nonterminal -symbols. Both classes live in the `pypy/rlib/parsing/tree.py`_ module. You can use +symbols. Both classes live in the `rpython/rlib/parsing/tree.py`_ module. You can use the ``view()`` method ``Nonterminal`` instances to get a pygame view of the parse tree. @@ -310,7 +310,7 @@ ++++++++ To write tree visitors for the parse trees that are RPython, there is a special -baseclass ``RPythonVisitor`` in `pypy/rlib/parsing/tree.py`_ to use. If your +baseclass ``RPythonVisitor`` in `rpython/rlib/parsing/tree.py`_ to use. If your class uses this, it will grow a ``dispatch(node)`` method, that calls an appropriate ``visit_`` method, depending on the ``node`` argument. Here the is replaced by the ``symbol`` attribute of the visited node. diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -1494,10 +1494,11 @@ ) return fd - def warn(self, msg, w_warningcls): - self.appexec([self.wrap(msg), w_warningcls], """(msg, warningcls): + def warn(self, w_msg, w_warningcls, stacklevel=2): + self.appexec([w_msg, w_warningcls, self.wrap(stacklevel)], + """(msg, warningcls, stacklevel): import _warnings - _warnings.warn(msg, warningcls, stacklevel=2) + _warnings.warn(msg, warningcls, stacklevel=stacklevel) """) diff --git a/pypy/interpreter/pyopcode.py b/pypy/interpreter/pyopcode.py --- a/pypy/interpreter/pyopcode.py +++ b/pypy/interpreter/pyopcode.py @@ -776,17 +776,16 @@ @jit.unroll_safe def cmp_exc_match(self, w_1, w_2): - if self.space.is_true(self.space.isinstance(w_2, self.space.w_tuple)): - for w_t in self.space.fixedview(w_2): - if self.space.is_true(self.space.isinstance(w_t, - self.space.w_str)): - self.space.warn("catching of string exceptions is " - "deprecated", - self.space.w_DeprecationWarning) - elif self.space.is_true(self.space.isinstance(w_2, self.space.w_str)): - self.space.warn("catching of string exceptions is deprecated", - self.space.w_DeprecationWarning) - return self.space.newbool(self.space.exception_match(w_1, w_2)) + space = self.space + if space.is_true(space.isinstance(w_2, space.w_tuple)): + for w_t in space.fixedview(w_2): + if space.is_true(space.isinstance(w_t, space.w_str)): + msg = "catching of string exceptions is deprecated" + space.warn(space.wrap(msg), space.w_DeprecationWarning) + elif space.is_true(space.isinstance(w_2, space.w_str)): + msg = "catching of string exceptions is deprecated" + space.warn(space.wrap(msg), space.w_DeprecationWarning) + return space.newbool(space.exception_match(w_1, w_2)) def COMPARE_OP(self, testnum, next_instr): w_2 = self.popvalue() diff --git a/pypy/module/__builtin__/functional.py b/pypy/module/__builtin__/functional.py --- a/pypy/module/__builtin__/functional.py +++ b/pypy/module/__builtin__/functional.py @@ -133,56 +133,77 @@ v = v.add(step) return space.newlist(res_w) +min_jitdriver = jit.JitDriver(name='min', + greens=['w_type'], reds='auto') +max_jitdriver = jit.JitDriver(name='max', + greens=['w_type'], reds='auto') + +def make_min_max(unroll): + @specialize.arg(2) + def min_max_impl(space, args, implementation_of): + if implementation_of == "max": + compare = space.gt + jitdriver = max_jitdriver + else: + compare = space.lt + jitdriver = min_jitdriver + args_w = args.arguments_w + if len(args_w) > 1: + w_sequence = space.newtuple(args_w) + elif len(args_w): + w_sequence = args_w[0] + else: + msg = "%s() expects at least one argument" % (implementation_of,) + raise OperationError(space.w_TypeError, space.wrap(msg)) + w_key = None + kwds = args.keywords + if kwds: + if kwds[0] == "key" and len(kwds) == 1: + w_key = args.keywords_w[0] + else: + msg = "%s() got unexpected keyword argument" % (implementation_of,) + raise OperationError(space.w_TypeError, space.wrap(msg)) + + w_iter = space.iter(w_sequence) + w_type = space.type(w_iter) + w_max_item = None + w_max_val = None + while True: + if not unroll: + jitdriver.jit_merge_point(w_type=w_type) + try: + w_item = space.next(w_iter) + except OperationError, e: + if not e.match(space, space.w_StopIteration): + raise + break + if w_key is not None: + w_compare_with = space.call_function(w_key, w_item) + else: + w_compare_with = w_item + if w_max_item is None or \ + space.is_true(compare(w_compare_with, w_max_val)): + w_max_item = w_item + w_max_val = w_compare_with + if w_max_item is None: + msg = "arg is an empty sequence" + raise OperationError(space.w_ValueError, space.wrap(msg)) + return w_max_item + if unroll: + min_max_impl = jit.unroll_safe(min_max_impl) + return min_max_impl + +min_max_unroll = make_min_max(True) +min_max_normal = make_min_max(False) @specialize.arg(2) - at jit.look_inside_iff(lambda space, args, implementation_of: - jit.isconstant(len(args.arguments_w)) and - len(args.arguments_w) == 2 -) def min_max(space, args, implementation_of): - if implementation_of == "max": - compare = space.gt + if not jit.we_are_jitted() or (jit.isconstant(len(args.arguments_w)) and + len(args.arguments_w) == 2): + return min_max_unroll(space, args, implementation_of) else: - compare = space.lt - args_w = args.arguments_w - if len(args_w) > 1: - w_sequence = space.newtuple(args_w) - elif len(args_w): - w_sequence = args_w[0] - else: - msg = "%s() expects at least one argument" % (implementation_of,) - raise OperationError(space.w_TypeError, space.wrap(msg)) - w_key = None - kwds = args.keywords - if kwds: - if kwds[0] == "key" and len(kwds) == 1: - w_key = args.keywords_w[0] - else: - msg = "%s() got unexpected keyword argument" % (implementation_of,) - raise OperationError(space.w_TypeError, space.wrap(msg)) - - w_iter = space.iter(w_sequence) - w_max_item = None - w_max_val = None - while True: - try: - w_item = space.next(w_iter) - except OperationError, e: - if not e.match(space, space.w_StopIteration): - raise - break - if w_key is not None: - w_compare_with = space.call_function(w_key, w_item) - else: - w_compare_with = w_item - if w_max_item is None or \ - space.is_true(compare(w_compare_with, w_max_val)): - w_max_item = w_item - w_max_val = w_compare_with - if w_max_item is None: - msg = "arg is an empty sequence" - raise OperationError(space.w_ValueError, space.wrap(msg)) - return w_max_item + return min_max_normal(space, args, implementation_of) +min_max._always_inline = True def max(space, __args__): """max(iterable[, key=func]) -> value diff --git a/pypy/module/__builtin__/interp_classobj.py b/pypy/module/__builtin__/interp_classobj.py --- a/pypy/module/__builtin__/interp_classobj.py +++ b/pypy/module/__builtin__/interp_classobj.py @@ -154,9 +154,9 @@ return elif name == "__del__": if self.lookup(space, name) is None: - msg = ("a __del__ method added to an existing class " - "will not be called") - space.warn(msg, space.w_RuntimeWarning) + msg = ("a __del__ method added to an existing class will " + "not be called") + space.warn(space.wrap(msg), space.w_RuntimeWarning) space.setitem(self.w_dict, w_attr, w_value) def descr_delattr(self, space, w_attr): @@ -395,9 +395,9 @@ cache = space.fromcache(Cache) if (not isinstance(self, cache.cls_with_del) and self.getdictvalue(space, '__del__') is None): - msg = ("a __del__ method added to an instance " - "with no __del__ in the class will not be called") - space.warn(msg, space.w_RuntimeWarning) + msg = ("a __del__ method added to an instance with no " + "__del__ in the class will not be called") + space.warn(space.wrap(msg), space.w_RuntimeWarning) if w_meth is not None: space.call_function(w_meth, w_name, w_value) else: @@ -454,11 +454,9 @@ else: w_as_str = self.descr_str(space) if space.len_w(w_format_spec) > 0: - space.warn( - ("object.__format__ with a non-empty format string is " - "deprecated"), - space.w_PendingDeprecationWarning - ) + msg = ("object.__format__ with a non-empty format string is " + "deprecated") + space.warn(space.wrap(msg), space.w_PendingDeprecationWarning) return space.format(w_as_str, w_format_spec) def descr_len(self, space): diff --git a/pypy/module/_io/interp_bufferedio.py b/pypy/module/_io/interp_bufferedio.py --- a/pypy/module/_io/interp_bufferedio.py +++ b/pypy/module/_io/interp_bufferedio.py @@ -76,7 +76,7 @@ raise NotImplementedError def _deprecated_max_buffer_size(self, space): - space.warn("max_buffer_size is deprecated", + space.warn(space.wrap("max_buffer_size is deprecated"), space.w_DeprecationWarning) def read_w(self, space, w_size=None): diff --git a/pypy/module/_io/interp_fileio.py b/pypy/module/_io/interp_fileio.py --- a/pypy/module/_io/interp_fileio.py +++ b/pypy/module/_io/interp_fileio.py @@ -3,6 +3,7 @@ from pypy.interpreter.error import OperationError, wrap_oserror, wrap_oserror2 from rpython.rlib.rarithmetic import r_longlong from rpython.rlib.rstring import StringBuilder +from rpython.rlib.rposix import validate_fd from os import O_RDONLY, O_WRONLY, O_RDWR, O_CREAT, O_TRUNC import sys, os, stat, errno from pypy.module._io.interp_iobase import W_RawIOBase, convert_size @@ -117,9 +118,6 @@ return currentsize + BIGCHUNK return currentsize + SMALLCHUNK -def verify_fd(fd): - return - class W_FileIO(W_RawIOBase): def __init__(self, space): W_RawIOBase.__init__(self, space) @@ -156,7 +154,7 @@ fd_is_own = False try: if fd >= 0: - verify_fd(fd) + validate_fd(fd) try: os.fstat(fd) except OSError, e: @@ -237,7 +235,7 @@ self.fd = -1 try: - verify_fd(fd) + validate_fd(fd) os.close(fd) except OSError, e: raise wrap_oserror(space, e, diff --git a/pypy/module/cpyext/import_.py b/pypy/module/cpyext/import_.py --- a/pypy/module/cpyext/import_.py +++ b/pypy/module/cpyext/import_.py @@ -46,8 +46,9 @@ @cpython_api([CONST_STRING], PyObject) def PyImport_ImportModuleNoBlock(space, name): - space.warn('PyImport_ImportModuleNoBlock() is not non-blocking', - space.w_RuntimeWarning) + space.warn( + space.wrap('PyImport_ImportModuleNoBlock() is not non-blocking'), + space.w_RuntimeWarning) return PyImport_Import(space, space.wrap(rffi.charp2str(name))) @cpython_api([PyObject], PyObject) diff --git a/pypy/module/exceptions/interp_exceptions.py b/pypy/module/exceptions/interp_exceptions.py --- a/pypy/module/exceptions/interp_exceptions.py +++ b/pypy/module/exceptions/interp_exceptions.py @@ -176,8 +176,8 @@ if self.w_message is None: raise OperationError(space.w_AttributeError, space.wrap("message was deleted")) - space.warn("BaseException.message has been deprecated as of Python 2.6", - space.w_DeprecationWarning) + msg = "BaseException.message has been deprecated as of Python 2.6" + space.warn(space.wrap(msg), space.w_DeprecationWarning) return self.w_message def descr_message_set(self, space, w_new): diff --git a/pypy/module/imp/importing.py b/pypy/module/imp/importing.py --- a/pypy/module/imp/importing.py +++ b/pypy/module/imp/importing.py @@ -174,9 +174,9 @@ "Parent module '%s' not loaded, " "cannot perform relative import" % ctxt_package)) else: - space.warn("Parent module '%s' not found " - "while handling absolute import" % ctxt_package, - space.w_RuntimeWarning) + msg = ("Parent module '%s' not found while handling absolute " + "import" % ctxt_package) + space.warn(space.wrap(msg), space.w_RuntimeWarning) rel_modulename = ctxt_package[:dot_position] rel_level = rel_modulename.count('.') + 1 @@ -533,9 +533,9 @@ if modtype in (PY_SOURCE, PY_COMPILED): return FindInfo(PKG_DIRECTORY, filepart, None) else: - msg = "Not importing directory " +\ - "'%s' missing __init__.py" % (filepart,) - space.warn(msg, space.w_ImportWarning) + msg = ("Not importing directory '%s' missing __init__.py" % + (filepart,)) + space.warn(space.wrap(msg), space.w_ImportWarning) modtype, suffix, filemode = find_modtype(space, filepart) try: if modtype in (PY_SOURCE, PY_COMPILED, C_EXTENSION): diff --git a/pypy/module/micronumpy/app_numpy.py b/pypy/module/micronumpy/app_numpy.py --- a/pypy/module/micronumpy/app_numpy.py +++ b/pypy/module/micronumpy/app_numpy.py @@ -67,11 +67,15 @@ def min(a, axis=None, out=None): if not hasattr(a, "min"): a = _numpypy.array(a) + if a.size < 1: + return _numpypy.array([]) return a.min(axis=axis, out=out) def max(a, axis=None, out=None): if not hasattr(a, "max"): a = _numpypy.array(a) + if a.size < 1: + return _numpypy.array([]) return a.max(axis=axis, out=out) def arange(start, stop=None, step=1, dtype=None): diff --git a/pypy/module/micronumpy/interp_numarray.py b/pypy/module/micronumpy/interp_numarray.py --- a/pypy/module/micronumpy/interp_numarray.py +++ b/pypy/module/micronumpy/interp_numarray.py @@ -250,7 +250,7 @@ ret = self.implementation.get_imag(self) if ret: return W_NDimArray(ret) - raise OperationError(space.w_NotImplementedError, + raise OperationError(space.w_NotImplementedError, space.wrap('imag not implemented for this dtype')) def descr_set_real(self, space, w_value): @@ -261,7 +261,7 @@ def descr_set_imag(self, space, w_value): # if possible, copy (broadcast) values into self if not self.get_dtype().is_complex_type(): - raise OperationError(space.w_TypeError, + raise OperationError(space.w_TypeError, space.wrap('array does not have imaginary part to set')) tmp = self.implementation.get_imag(self) tmp.setslice(space, convert_to_array(space, w_value)) @@ -302,11 +302,11 @@ @unwrap_spec(axis1=int, axis2=int) def descr_swapaxes(self, space, axis1, axis2): """a.swapaxes(axis1, axis2) - + Return a view of the array with `axis1` and `axis2` interchanged. - + Refer to `numpy.swapaxes` for full documentation. - + See Also -------- numpy.swapaxes : equivalent function @@ -439,7 +439,7 @@ ret = impl.base() if ret is None: return space.w_None - return ret + return ret @unwrap_spec(inplace=bool) def descr_byteswap(self, space, inplace=False): @@ -492,7 +492,7 @@ "axis1 and axis2 cannot be the same")) return interp_arrayops.diagonal(space, self.implementation, offset, axis1, axis2) - + def descr_dump(self, space, w_file): raise OperationError(space.w_NotImplementedError, space.wrap( "dump not implemented yet")) @@ -509,7 +509,7 @@ raise OperationError(space.w_NotImplementedError, space.wrap( "setting flags not implemented yet")) - @unwrap_spec(offset=int) + @unwrap_spec(offset=int) def descr_getfield(self, space, w_dtype, offset): raise OperationError(space.w_NotImplementedError, space.wrap( "getfield not implemented yet")) @@ -518,7 +518,7 @@ raise OperationError(space.w_NotImplementedError, space.wrap( "itemset not implemented yet")) - @unwrap_spec(neworder=str) + @unwrap_spec(neworder=str) def descr_newbyteorder(self, space, neworder): raise OperationError(space.w_NotImplementedError, space.wrap( "newbyteorder not implemented yet")) @@ -551,7 +551,7 @@ raise OperationError(space.w_NotImplementedError, space.wrap( "setfield not implemented yet")) - def descr_setflags(self, space, w_write=None, w_align=None, w_uic=None): + def descr_setflags(self, space, w_write=None, w_align=None, w_uic=None): raise OperationError(space.w_NotImplementedError, space.wrap( "setflags not implemented yet")) @@ -572,7 +572,7 @@ "tofile not implemented yet")) def descr_trace(self, space, w_offset=0, w_axis1=0, w_axis2=1, - w_dtype=None, w_out=None): + w_dtype=None, w_out=None): raise OperationError(space.w_NotImplementedError, space.wrap( "trace not implemented yet")) @@ -627,12 +627,23 @@ w_remainder = self.descr_mod(space, w_other) return space.newtuple([w_quotient, w_remainder]) - descr_eq = _binop_impl("equal") - descr_ne = _binop_impl("not_equal") - descr_lt = _binop_impl("less") - descr_le = _binop_impl("less_equal") - descr_gt = _binop_impl("greater") - descr_ge = _binop_impl("greater_equal") + def _binop_comp_impl(ufunc): + def impl(self, space, w_other, w_out=None): + try: + return ufunc(self, space, w_other, w_out) + except OperationError, e: + if e.match(space, space.w_ValueError): + return space.w_False + raise e + + return func_with_new_name(impl, ufunc.func_name) + + descr_eq = _binop_comp_impl(_binop_impl("equal")) + descr_ne = _binop_comp_impl(_binop_impl("not_equal")) + descr_lt = _binop_comp_impl(_binop_impl("less")) + descr_le = _binop_comp_impl(_binop_impl("less_equal")) + descr_gt = _binop_comp_impl(_binop_impl("greater")) + descr_ge = _binop_comp_impl(_binop_impl("greater_equal")) def _binop_right_impl(ufunc_name): def impl(self, space, w_other, w_out=None): @@ -698,7 +709,7 @@ if space.is_none(w_out): out = None elif not isinstance(w_out, W_NDimArray): - raise OperationError(space.w_TypeError, space.wrap( + raise OperationError(space.w_TypeError, space.wrap( 'output must be an array')) else: out = w_out @@ -718,7 +729,7 @@ descr_cumsum = _reduce_ufunc_impl('add', cumultative=True) descr_cumprod = _reduce_ufunc_impl('multiply', cumultative=True) - + def descr_mean(self, space, w_axis=None, w_out=None): if space.is_none(w_axis): w_denom = space.wrap(self.get_size()) @@ -863,7 +874,7 @@ swapaxes = interp2app(W_NDimArray.descr_swapaxes), flat = GetSetProperty(W_NDimArray.descr_get_flatiter), item = interp2app(W_NDimArray.descr_item), - real = GetSetProperty(W_NDimArray.descr_get_real, + real = GetSetProperty(W_NDimArray.descr_get_real, W_NDimArray.descr_set_real), imag = GetSetProperty(W_NDimArray.descr_get_imag, W_NDimArray.descr_set_imag), @@ -923,7 +934,7 @@ dtype) #if dtype is interp_dtype.get_dtype_cache(space).w_float64dtype: # break - + if dtype is None: dtype = interp_dtype.get_dtype_cache(space).w_float64dtype if ndmin > len(shape): diff --git a/pypy/module/micronumpy/test/test_numarray.py b/pypy/module/micronumpy/test/test_numarray.py --- a/pypy/module/micronumpy/test/test_numarray.py +++ b/pypy/module/micronumpy/test/test_numarray.py @@ -1769,6 +1769,12 @@ b = array(a, dtype='d') assert a.dtype is b.dtype + def test_notequal_different_shapes(self): + from _numpypy import array + a = array([1, 2]) + b = array([1, 2, 3, 4]) + assert (a == b) == False + class AppTestMultiDim(BaseNumpyAppTest): def test_init(self): diff --git a/pypy/module/struct/formatiterator.py b/pypy/module/struct/formatiterator.py --- a/pypy/module/struct/formatiterator.py +++ b/pypy/module/struct/formatiterator.py @@ -84,11 +84,10 @@ def _maybe_float(self, w_obj): space = self.space if space.is_true(space.isinstance(w_obj, space.w_float)): - space.warn("struct: integer argument expected, got float", - space.w_DeprecationWarning) + msg = "struct: integer argument expected, got float" else: - space.warn("integer argument expected, got non-integer", - space.w_DeprecationWarning) + msg = "integer argument expected, got non-integer" + space.warn(space.wrap(msg), space.w_DeprecationWarning) return space.int(w_obj) # wrapped float -> wrapped int or long else: diff --git a/pypy/module/test_lib_pypy/test_datetime.py b/pypy/module/test_lib_pypy/test_datetime.py --- a/pypy/module/test_lib_pypy/test_datetime.py +++ b/pypy/module/test_lib_pypy/test_datetime.py @@ -9,6 +9,26 @@ expected = "datetime.datetime(1, 2, 3, 0, 0)" assert repr(datetime.datetime(1,2,3)) == expected +def test_attributes(): + a = datetime.date.today() + raises(AttributeError, 'a.abc = 1') + a = datetime.time() + raises(AttributeError, 'a.abc = 1') + a = datetime.tzinfo() + raises(AttributeError, 'a.abc = 1') + a = datetime.datetime.utcnow() + raises(AttributeError, 'a.abc = 1') + a = datetime.timedelta() + raises(AttributeError, 'a.abc = 1') + +def test_unpickle(): + e = raises(TypeError, datetime.date, '123') + assert e.value.args[0] == 'an integer is required' + e = raises(TypeError, datetime.time, '123') + assert e.value.args[0] == 'an integer is required' + e = raises(TypeError, datetime.datetime, '123') + assert e.value.args[0] == 'an integer is required' + def test_strptime(): import time, sys if sys.version_info < (2, 6): diff --git a/pypy/objspace/descroperation.py b/pypy/objspace/descroperation.py --- a/pypy/objspace/descroperation.py +++ b/pypy/objspace/descroperation.py @@ -7,6 +7,7 @@ from rpython.tool.sourcetools import compile2, func_with_new_name from pypy.module.__builtin__.interp_classobj import W_InstanceObject from rpython.rlib.objectmodel import specialize +from rpython.rlib import jit def object_getattribute(space): "Utility that returns the app-level descriptor object.__getattribute__." @@ -118,6 +119,9 @@ def descr__init__(space, w_obj, __args__): pass +contains_jitdriver = jit.JitDriver(name='contains', + greens=['w_type'], reds='auto') + class DescrOperation(object): _mixin_ = True @@ -421,7 +425,9 @@ def _contains(space, w_container, w_item): w_iter = space.iter(w_container) + w_type = space.type(w_iter) while 1: + contains_jitdriver.jit_merge_point(w_type=w_type) try: w_next = space.next(w_iter) except OperationError, e: diff --git a/pypy/objspace/std/complexobject.py b/pypy/objspace/std/complexobject.py --- a/pypy/objspace/std/complexobject.py +++ b/pypy/objspace/std/complexobject.py @@ -80,10 +80,8 @@ return W_ComplexObject(rr, ir) def divmod(self, space, other): - space.warn( - "complex divmod(), // and % are deprecated", - space.w_DeprecationWarning - ) + space.warn(space.wrap("complex divmod(), // and % are deprecated"), + space.w_DeprecationWarning) w_div = self.div(other) div = math.floor(w_div.realval) w_mod = self.sub( diff --git a/pypy/objspace/std/floatobject.py b/pypy/objspace/std/floatobject.py --- a/pypy/objspace/std/floatobject.py +++ b/pypy/objspace/std/floatobject.py @@ -10,7 +10,7 @@ from rpython.rlib.rarithmetic import ovfcheck_float_to_int, intmask, LONG_BIT from rpython.rlib.rfloat import ( isinf, isnan, isfinite, INFINITY, NAN, copysign, formatd, - DTSF_ADD_DOT_0, DTSF_STR_PRECISION) + DTSF_ADD_DOT_0, DTSF_STR_PRECISION, float_as_rbigint_ratio) from rpython.rlib.rbigint import rbigint from rpython.rlib import rfloat from rpython.tool.sourcetools import func_with_new_name @@ -553,27 +553,18 @@ def float_as_integer_ratio__Float(space, w_float): value = w_float.floatval - if isinf(value): + try: + num, den = float_as_rbigint_ratio(value) + except OverflowError: w_msg = space.wrap("cannot pass infinity to as_integer_ratio()") raise OperationError(space.w_OverflowError, w_msg) - elif isnan(value): + except ValueError: w_msg = space.wrap("cannot pass nan to as_integer_ratio()") raise OperationError(space.w_ValueError, w_msg) - float_part, exp = math.frexp(value) - for i in range(300): - if float_part == math.floor(float_part): - break - float_part *= 2.0 - exp -= 1 - w_num = W_LongObject.fromfloat(space, float_part) - w_den = space.newlong(1) - w_exp = space.newlong(abs(exp)) - w_exp = space.lshift(w_den, w_exp) - if exp > 0: - w_num = space.mul(w_num, w_exp) - else: - w_den = w_exp - # Try to return int. + + w_num = space.newlong_from_rbigint(num) + w_den = space.newlong_from_rbigint(den) + # Try to return int return space.newtuple([space.int(w_num), space.int(w_den)]) def float_is_integer__Float(space, w_float): diff --git a/pypy/objspace/std/objecttype.py b/pypy/objspace/std/objecttype.py --- a/pypy/objspace/std/objecttype.py +++ b/pypy/objspace/std/objecttype.py @@ -126,11 +126,8 @@ msg = "format_spec must be a string" raise OperationError(space.w_TypeError, space.wrap(msg)) if space.len_w(w_format_spec) > 0: - space.warn( - ("object.__format__ with a non-empty format string is " - "deprecated"), - space.w_PendingDeprecationWarning - ) + msg = "object.__format__ with a non-empty format string is deprecated" + space.warn(space.wrap(msg), space.w_PendingDeprecationWarning) return space.format(w_as_str, w_format_spec) def descr___subclasshook__(space, __args__): diff --git a/pypy/objspace/std/typeobject.py b/pypy/objspace/std/typeobject.py --- a/pypy/objspace/std/typeobject.py +++ b/pypy/objspace/std/typeobject.py @@ -295,8 +295,9 @@ msg = "can't set attributes on type object '%s'" raise operationerrfmt(space.w_TypeError, msg, w_self.name) if name == "__del__" and name not in w_self.dict_w: - msg = "a __del__ method added to an existing type will not be called" - space.warn(msg, space.w_RuntimeWarning) + msg = ("a __del__ method added to an existing type will not be " + "called") + space.warn(space.wrap(msg), space.w_RuntimeWarning) if space.config.objspace.std.withtypeversion: version_tag = w_self.version_tag() if version_tag is not None: diff --git a/pypy/objspace/std/unicodeobject.py b/pypy/objspace/std/unicodeobject.py --- a/pypy/objspace/std/unicodeobject.py +++ b/pypy/objspace/std/unicodeobject.py @@ -119,13 +119,10 @@ w_uni2 = uni_from_str(space, w_str) except OperationError, e: if e.match(space, space.w_UnicodeDecodeError): - if inverse: - msg = "Unicode unequal comparison failed to convert both " \ - "arguments to Unicode - interpreting them as being unequal" - else : - msg = "Unicode equal comparison failed to convert both " \ - "arguments to Unicode - interpreting them as being unequal" - space.warn(msg, space.w_UnicodeWarning) + msg = ("Unicode %s comparison failed to convert both arguments to " + "Unicode - interpreting them as being unequal" % + "unequal" if inverse else "equal") + space.warn(space.wrap(msg), space.w_UnicodeWarning) return space.newbool(inverse) raise result = space.eq(w_uni, w_uni2) diff --git a/rpython/bin/translatorshell.py b/rpython/bin/translatorshell.py --- a/rpython/bin/translatorshell.py +++ b/rpython/bin/translatorshell.py @@ -15,9 +15,10 @@ t.view() # graph + annotations under the mouse t.rtype() # use low level operations - f = t.compile_c() # C compilation + lib = t.compile_c() # C compilation as a library + f = get_c_function(lib, func) # get the function out of the library assert f(arg) == func(arg) # sanity check (for C) - + Some functions are provided for the benefit of interactive testing. Try dir(snippet) for list of current snippets. @@ -31,6 +32,13 @@ import py + +def get_c_function(lib, f): + from ctypes import CDLL + name = f.__name__ + return getattr(CDLL(lib.strpath), 'pypy_g_' + name) + + def setup_readline(): import readline try: diff --git a/rpython/jit/backend/x86/test/test_zrpy_releasegil.py b/rpython/jit/backend/x86/test/test_zrpy_releasegil.py --- a/rpython/jit/backend/x86/test/test_zrpy_releasegil.py +++ b/rpython/jit/backend/x86/test/test_zrpy_releasegil.py @@ -1,18 +1,99 @@ from rpython.rtyper.lltypesystem import lltype, llmemory, rffi from rpython.rlib.jit import dont_look_inside +from rpython.rlib.objectmodel import invoke_around_extcall from rpython.jit.metainterp.optimizeopt import ALL_OPTS_NAMES -from rpython.rlib.libffi import CDLL, types, ArgChain, clibffi -from rpython.rtyper.lltypesystem.ll2ctypes import libc_name from rpython.rtyper.annlowlevel import llhelper from rpython.jit.backend.x86.test.test_zrpy_gc import BaseFrameworkTests from rpython.jit.backend.x86.test.test_zrpy_gc import check +from rpython.tool.udir import udir class ReleaseGILTests(BaseFrameworkTests): compile_kwds = dict(enable_opts=ALL_OPTS_NAMES, thread=True) + def define_simple(self): + class Glob: + def __init__(self): + self.event = 0 + glob = Glob() + # + + c_strchr = rffi.llexternal('strchr', [rffi.CCHARP, lltype.Signed], + rffi.CCHARP) + + def func(): + glob.event += 1 + + def before(n, x): + invoke_around_extcall(func, func) + return (n, None, None, None, None, None, + None, None, None, None, None, None) + # + def f(n, x, *args): + a = rffi.str2charp(str(n)) + c_strchr(a, ord('0')) + lltype.free(a, flavor='raw') + n -= 1 + return (n, x) + args + return before, f, None + + def test_simple(self): + self.run('simple') + assert 'call_release_gil' in udir.join('TestCompileFramework.log').read() + + def define_close_stack(self): + # + class Glob(object): + pass + glob = Glob() + class X(object): + pass + # + def callback(p1, p2): + for i in range(100): + glob.lst.append(X()) + return rffi.cast(rffi.INT, 1) + CALLBACK = lltype.Ptr(lltype.FuncType([lltype.Signed, + lltype.Signed], rffi.INT)) + # + @dont_look_inside + def alloc1(): + return llmemory.raw_malloc(16) + @dont_look_inside + def free1(p): + llmemory.raw_free(p) + + c_qsort = rffi.llexternal('qsort', [rffi.VOIDP, rffi.SIZE_T, + rffi.SIZE_T, CALLBACK], lltype.Void) + # + def f42(): + length = len(glob.lst) + raw = alloc1() + fn = llhelper(CALLBACK, rffi._make_wrapper_for(CALLBACK, callback)) + c_qsort(rffi.cast(rffi.VOIDP, raw), rffi.cast(rffi.SIZE_T, 2), + rffi.cast(rffi.SIZE_T, 8), fn) + free1(raw) + check(len(glob.lst) > length) + del glob.lst[:] + # + def before(n, x): + glob.lst = [] + + return (n, None, None, None, None, None, + None, None, None, None, None, None) + # + def f(n, x, *args): + f42() + n -= 1 + return (n, x) + args + return before, f, None + + def test_close_stack(self): + self.run('close_stack') + assert 'call_release_gil' in udir.join('TestCompileFramework.log').read() + class TestShadowStack(ReleaseGILTests): gcrootfinder = "shadowstack" diff --git a/rpython/rlib/rfloat.py b/rpython/rlib/rfloat.py --- a/rpython/rlib/rfloat.py +++ b/rpython/rlib/rfloat.py @@ -419,3 +419,25 @@ def isfinite(x): "NOT_RPYTHON" return not isinf(x) and not isnan(x) + +def float_as_rbigint_ratio(value): + from rpython.rlib.rbigint import rbigint + + if isinf(value): + raise OverflowError("cannot pass infinity to as_integer_ratio()") + elif isnan(value): + raise ValueError("cannot pass nan to as_integer_ratio()") + float_part, exp_int = math.frexp(value) + for i in range(300): + if float_part == math.floor(float_part): + break + float_part *= 2.0 + exp_int -= 1 + num = rbigint.fromfloat(float_part) + den = rbigint.fromint(1) + exp = den.lshift(abs(exp_int)) + if exp_int > 0: + num = num.mul(exp) + else: + den = exp + return num, den diff --git a/rpython/rlib/test/test_rarithmetic.py b/rpython/rlib/test/test_rarithmetic.py --- a/rpython/rlib/test/test_rarithmetic.py +++ b/rpython/rlib/test/test_rarithmetic.py @@ -395,16 +395,18 @@ assert not int_between(1, 1, 1) # these can't be prebuilt on 32bit -L1 = 0x0102030405060708L -L2 = 0x0807060504030201L +U1 = r_ulonglong(0x0102030405060708L) +U2 = r_ulonglong(0x0807060504030201L) +S1 = r_longlong(0x0102030405060708L) +S2 = r_longlong(0x0807060504030201L) def test_byteswap(): from rpython.rtyper.lltypesystem import rffi, lltype assert rffi.cast(lltype.Signed, byteswap(rffi.cast(rffi.USHORT, 0x0102))) == 0x0201 assert rffi.cast(lltype.Signed, byteswap(rffi.cast(rffi.INT, 0x01020304))) == 0x04030201 - assert byteswap(rffi.cast(rffi.LONGLONG, L1)) == L2 - assert byteswap(rffi.cast(rffi.ULONGLONG, L1)) == L2 + assert byteswap(U1) == U2 + assert byteswap(S1) == S2 assert ((byteswap(2.3) - 1.903598566252326e+185) / 1e185) < 0.000001 assert (rffi.cast(lltype.Float, byteswap(rffi.cast(lltype.SingleFloat, 2.3))) - 4.173496037651603e-08) < 1e-16 diff --git a/rpython/rlib/test/test_rfloat.py b/rpython/rlib/test/test_rfloat.py new file mode 100644 --- /dev/null +++ b/rpython/rlib/test/test_rfloat.py @@ -0,0 +1,131 @@ +import sys, py + +from rpython.rlib.rfloat import float_as_rbigint_ratio +from rpython.rlib.rfloat import break_up_float +from rpython.rlib.rfloat import copysign +from rpython.rlib.rfloat import round_away +from rpython.rlib.rfloat import round_double +from rpython.rlib.rbigint import rbigint + +def test_copysign(): + assert copysign(1, 1) == 1 + assert copysign(-1, 1) == 1 + assert copysign(-1, -1) == -1 + assert copysign(1, -1) == -1 + assert copysign(1, -0.) == -1 + +def test_round_away(): + assert round_away(.1) == 0. + assert round_away(.5) == 1. + assert round_away(.7) == 1. + assert round_away(1.) == 1. + assert round_away(-.5) == -1. + assert round_away(-.1) == 0. + assert round_away(-.7) == -1. + assert round_away(0.) == 0. + +def test_round_double(): + def almost_equal(x, y): + assert round(abs(x-y), 7) == 0 + + almost_equal(round_double(0.125, 2), 0.13) + almost_equal(round_double(0.375, 2), 0.38) + almost_equal(round_double(0.625, 2), 0.63) + almost_equal(round_double(0.875, 2), 0.88) + almost_equal(round_double(-0.125, 2), -0.13) + almost_equal(round_double(-0.375, 2), -0.38) + almost_equal(round_double(-0.625, 2), -0.63) + almost_equal(round_double(-0.875, 2), -0.88) + + almost_equal(round_double(0.25, 1), 0.3) + almost_equal(round_double(0.75, 1), 0.8) + almost_equal(round_double(-0.25, 1), -0.3) + almost_equal(round_double(-0.75, 1), -0.8) + + round_double(-6.5, 0) == -7.0 + round_double(-5.5, 0) == -6.0 + round_double(-1.5, 0) == -2.0 + round_double(-0.5, 0) == -1.0 + round_double(0.5, 0) == 1.0 + round_double(1.5, 0) == 2.0 + round_double(2.5, 0) == 3.0 + round_double(3.5, 0) == 4.0 + round_double(4.5, 0) == 5.0 + round_double(5.5, 0) == 6.0 + round_double(6.5, 0) == 7.0 + + round_double(-25.0, -1) == -30.0 + round_double(-15.0, -1) == -20.0 + round_double(-5.0, -1) == -10.0 + round_double(5.0, -1) == 10.0 + round_double(15.0, -1) == 20.0 + round_double(25.0, -1) == 30.0 + round_double(35.0, -1) == 40.0 + round_double(45.0, -1) == 50.0 + round_double(55.0, -1) == 60.0 + round_double(65.0, -1) == 70.0 + round_double(75.0, -1) == 80.0 + round_double(85.0, -1) == 90.0 + round_double(95.0, -1) == 100.0 + round_double(12325.0, -1) == 12330.0 + + round_double(350.0, -2) == 400.0 + round_double(450.0, -2) == 500.0 + + almost_equal(round_double(0.5e21, -21), 1e21) + almost_equal(round_double(1.5e21, -21), 2e21) + almost_equal(round_double(2.5e21, -21), 3e21) + almost_equal(round_double(5.5e21, -21), 6e21) + almost_equal(round_double(8.5e21, -21), 9e21) + + almost_equal(round_double(-1.5e22, -22), -2e22) + almost_equal(round_double(-0.5e22, -22), -1e22) + almost_equal(round_double(0.5e22, -22), 1e22) + almost_equal(round_double(1.5e22, -22), 2e22) + +def test_round_half_even(): + from rpython.rlib import rfloat + for func in (rfloat.round_double_short_repr, + rfloat.round_double_fallback_repr): + # 2.x behavior + assert func(2.5, 0, False) == 3.0 + # 3.x behavior + assert func(2.5, 0, True) == 2.0 + +def test_break_up_float(): + assert break_up_float('1') == ('', '1', '', '') + assert break_up_float('+1') == ('+', '1', '', '') + assert break_up_float('-1') == ('-', '1', '', '') + + assert break_up_float('.5') == ('', '', '5', '') + + assert break_up_float('1.2e3') == ('', '1', '2', '3') + assert break_up_float('1.2e+3') == ('', '1', '2', '+3') + assert break_up_float('1.2e-3') == ('', '1', '2', '-3') + + # some that will get thrown out on return: + assert break_up_float('.') == ('', '', '', '') + assert break_up_float('+') == ('+', '', '', '') + assert break_up_float('-') == ('-', '', '', '') + assert break_up_float('e1') == ('', '', '', '1') + + py.test.raises(ValueError, break_up_float, 'e') + + +def test_float_as_rbigint_ratio(): + for f, ratio in [ + (0.875, (7, 8)), + (-0.875, (-7, 8)), + (0.0, (0, 1)), + (11.5, (23, 2)), + ]: + num, den = float_as_rbigint_ratio(f) + assert num.eq(rbigint.fromint(ratio[0])) + assert den.eq(rbigint.fromint(ratio[1])) + + with py.test.raises(OverflowError): + float_as_rbigint_ratio(float('inf')) + with py.test.raises(OverflowError): + float_as_rbigint_ratio(float('-inf')) + with py.test.raises(ValueError): + float_as_rbigint_ratio(float('nan')) diff --git a/rpython/rlib/test/test_timer.py b/rpython/rlib/test/test_timer.py deleted file mode 100644 --- a/rpython/rlib/test/test_timer.py +++ /dev/null @@ -1,26 +0,0 @@ -from rpython.rlib.timer import Timer -from rpython.translator.c.test.test_genc import compile -from rpython.annotator.policy import AnnotatorPolicy - - -t = Timer() -t.start("testc") -t.stop("testc") - -def timer_user(): - assert "testc" not in t.timingorder - t.start("testa") - t.stop("testa") - t.start("testb") - t.start("testb") - t.stop("testb") - t.stop("testb") - t.start_name("test", "one") - t.stop_name("test", "one") - t.dump() - - -def test_compile_timer(): - policy = AnnotatorPolicy() - f_compiled = compile(timer_user, [], annotatorpolicy=policy) - f_compiled() diff --git a/rpython/rlib/timer.py b/rpython/rlib/timer.py deleted file mode 100644 --- a/rpython/rlib/timer.py +++ /dev/null @@ -1,77 +0,0 @@ -import time -import os - - -def _create_name(name, generation): - if generation == 0: - return name - else: - return "%s[%s]" % (name, str(generation)) - - -class Timer: - def __init__(self): - self.reset() - - def reset(self): - self.timings = {} - self.levels = {} - self.timingorder = [] - - def _cleanup_(self): - self.reset() - - def start(self, timer): - level = self.levels.setdefault(timer, -1) - new_level = level + 1 - name = _create_name(timer, new_level) - if name not in self.timings: - self.timingorder.append(name) - self.timings[name] = time.time() - self.timings.get(name, 0) - self.levels[timer] = new_level - - def start_name(self, timerone, timertwo): - self.start(timerone + " " + timertwo) - - def stop(self, timer): - level = self.levels.setdefault(timer, -1) - if level == -1: - raise ValueError("Invalid timer name") - if level >= 0: # timer is active - name = _create_name(timer, level) - self.timings[name] = time.time() - self.timings[name] - self.levels[timer] = level - 1 - - def stop_name(self, timerone, timertwo): - self.stop(timerone + " " + timertwo) - - def value(self, timer): - level = self.levels.get(timer, -1) - if level == -1: - result = "%fs" % self.timings[timer] - else: - result = "%fs (still running)" % (time.time() - self.timings[timer]) - return result - - def dump(self): - outlist = [] - for timer in self.timingorder: - value = self.value(timer) - outlist.append("%s = %s" % (timer, value)) - os.write(2, "\n".join(outlist)) - - -class DummyTimer: - def start(self, timer): - pass - def start_name(self, timerone, timertwo): - pass - def stop(self, timer): - pass - def stop_name(self, timerone, timertwo): - pass - def value(self, timer): - return "Timing disabled" - def dump(self): - pass - diff --git a/rpython/rtyper/llinterp.py b/rpython/rtyper/llinterp.py --- a/rpython/rtyper/llinterp.py +++ b/rpython/rtyper/llinterp.py @@ -11,7 +11,8 @@ from rpython.rlib.objectmodel import (ComputedIntSymbolic, CDefinedIntSymbolic, Symbolic) # intmask is used in an exec'd code block -from rpython.rlib.rarithmetic import ovfcheck, is_valid_int, intmask +from rpython.rlib.rarithmetic import (ovfcheck, is_valid_int, intmask, + r_uint, r_longlong, r_ulonglong, r_longlonglong) from rpython.rtyper.lltypesystem import lltype, llmemory, lloperation, llheap, rclass from rpython.rtyper.ootypesystem import ootype diff --git a/rpython/rtyper/rint.py b/rpython/rtyper/rint.py --- a/rpython/rtyper/rint.py +++ b/rpython/rtyper/rint.py @@ -1,17 +1,16 @@ import sys -from rpython.tool.pairtype import pairtype + from rpython.annotator import model as annmodel from rpython.flowspace.operation import op_appendices -from rpython.rtyper.lltypesystem.lltype import Signed, Unsigned, Bool, Float, \ - Void, Char, UniChar, malloc, UnsignedLongLong, \ - SignedLongLong, build_number, Number, cast_primitive, typeOf, \ - SignedLongLongLong -from rpython.rtyper.rmodel import IntegerRepr, inputconst -from rpython.rlib.rarithmetic import intmask, r_int, r_uint, r_ulonglong, \ - r_longlong, is_emulated_long -from rpython.rtyper.error import TyperError, MissingRTypeOperation -from rpython.rtyper.rmodel import log from rpython.rlib import objectmodel +from rpython.rlib.rarithmetic import intmask, r_int, r_longlong +from rpython.rtyper.error import TyperError +from rpython.rtyper.lltypesystem.lltype import (Signed, Unsigned, Bool, Float, + Char, UniChar, UnsignedLongLong, SignedLongLong, build_number, Number, + cast_primitive, typeOf, SignedLongLongLong) +from rpython.rtyper.rmodel import IntegerRepr, inputconst, log +from rpython.tool.pairtype import pairtype + _integer_reprs = {} def getintegerrepr(lltype, prefix=None): @@ -128,7 +127,7 @@ #comparisons: eq is_ ne lt le gt ge - def rtype_eq(_, hop): + def rtype_eq(_, hop): return _rtype_compare_template(hop, 'eq') rtype_is_ = rtype_eq @@ -259,7 +258,7 @@ get_ll_le_function = get_ll_eq_function def get_ll_ge_function(self): - return None + return None def get_ll_hash_function(self): if (sys.maxint == 2147483647 and @@ -279,7 +278,7 @@ ll_dummy_value = -1 def rtype_chr(_, hop): - vlist = hop.inputargs(Signed) + vlist = hop.inputargs(Signed) if hop.has_implicit_exception(ValueError): hop.exception_is_here() hop.gendirectcall(ll_check_chr, vlist[0]) @@ -301,8 +300,8 @@ vlist = hop.inputargs(self) return hop.genop(self.opprefix + 'is_true', vlist, resulttype=Bool) - #Unary arithmetic operations - + #Unary arithmetic operations + def rtype_abs(self, hop): self = self.as_int vlist = hop.inputargs(self) @@ -325,7 +324,7 @@ self = self.as_int vlist = hop.inputargs(self) return hop.genop(self.opprefix + 'invert', vlist, resulttype=self) - + def rtype_neg(self, hop): self = self.as_int vlist = hop.inputargs(self) diff --git a/rpython/rtyper/rmodel.py b/rpython/rtyper/rmodel.py --- a/rpython/rtyper/rmodel.py +++ b/rpython/rtyper/rmodel.py @@ -1,20 +1,18 @@ +from rpython.annotator import model as annmodel, unaryop, binaryop, description +from rpython.flowspace.model import Constant +from rpython.rtyper.error import TyperError, MissingRTypeOperation +from rpython.rtyper.lltypesystem import lltype +from rpython.rtyper.lltypesystem.lltype import (Void, Bool, Float, typeOf, + LowLevelType, isCompatibleType) from rpython.tool.pairtype import pairtype, extendabletype, pair -from rpython.annotator import model as annmodel, unaryop, binaryop -from rpython.annotator import description -from rpython.flowspace.model import Constant -from rpython.rtyper.lltypesystem.lltype import \ - Void, Bool, Float, Signed, Char, UniChar, \ - typeOf, LowLevelType, Ptr, isCompatibleType -from rpython.rtyper.lltypesystem import lltype, llmemory -from rpython.rtyper.ootypesystem import ootype -from rpython.rtyper.error import TyperError, MissingRTypeOperation -# initialization states for Repr instances -class setupstate(object): - NOTINITIALIZED = 0 +# initialization states for Repr instances + +class setupstate(object): + NOTINITIALIZED = 0 INPROGRESS = 1 - BROKEN = 2 + BROKEN = 2 FINISHED = 3 DELAYED = 4 @@ -27,7 +25,7 @@ iterating over. """ __metaclass__ = extendabletype - _initialized = setupstate.NOTINITIALIZED + _initialized = setupstate.NOTINITIALIZED def __repr__(self): return '<%s %s>' % (self.__class__.__name__, self.lowleveltype) @@ -35,31 +33,31 @@ def compact_repr(self): return '%s %s' % (self.__class__.__name__.replace('Repr','R'), self.lowleveltype._short_name()) - def setup(self): + def setup(self): """ call _setup_repr() and keep track of the initializiation status to e.g. detect recursive _setup_repr invocations. - the '_initialized' attr has four states: + the '_initialized' attr has four states: """ - if self._initialized == setupstate.FINISHED: - return - elif self._initialized == setupstate.BROKEN: + if self._initialized == setupstate.FINISHED: + return + elif self._initialized == setupstate.BROKEN: raise BrokenReprTyperError( "cannot setup already failed Repr: %r" %(self,)) - elif self._initialized == setupstate.INPROGRESS: + elif self._initialized == setupstate.INPROGRESS: raise AssertionError( "recursive invocation of Repr setup(): %r" %(self,)) elif self._initialized == setupstate.DELAYED: raise AssertionError( "Repr setup() is delayed and cannot be called yet: %r" %(self,)) - assert self._initialized == setupstate.NOTINITIALIZED - self._initialized = setupstate.INPROGRESS - try: - self._setup_repr() - except TyperError, e: - self._initialized = setupstate.BROKEN - raise - else: - self._initialized = setupstate.FINISHED + assert self._initialized == setupstate.NOTINITIALIZED + self._initialized = setupstate.INPROGRESS + try: + self._setup_repr() + except TyperError, e: + self._initialized = setupstate.BROKEN + raise + else: + self._initialized = setupstate.FINISHED def _setup_repr(self): "For recursive data structure, which must be initialized in two steps." @@ -68,15 +66,15 @@ """Same as setup(), called a bit later, for effects that are only needed after the typer finished (as opposed to needed for other parts of the typer itself).""" - if self._initialized == setupstate.BROKEN: + if self._initialized == setupstate.BROKEN: raise BrokenReprTyperError("cannot perform setup_final_touch " "on failed Repr: %r" %(self,)) assert self._initialized == setupstate.FINISHED, ( "setup_final() on repr with state %s: %r" % (self._initialized, self)) - self._setup_repr_final() + self._setup_repr_final() - def _setup_repr_final(self): + def _setup_repr_final(self): pass def is_setup_delayed(self): @@ -98,8 +96,8 @@ def __getattr__(self, name): # Assume that when an attribute is missing, it's because setup() needs # to be called - if not (name[:2] == '__' == name[-2:]): - if self._initialized == setupstate.NOTINITIALIZED: + if not (name[:2] == '__' == name[-2:]): + if self._initialized == setupstate.NOTINITIALIZED: self.setup() try: return self.__dict__[name] @@ -119,7 +117,7 @@ else: raise TyperError("convert_desc_or_const expects a Desc" "or Constant: %r" % desc_or_const) - + def convert_const(self, value): "Convert the given constant value to the low-level repr of 'self'." if self.lowleveltype is not Void: @@ -137,12 +135,12 @@ values of this Repr. This can return None to mean that simply using '==' is fine. """ - raise TyperError, 'no equality function for %r' % self + raise TyperError('no equality function for %r' % self) def get_ll_hash_function(self): """Return a hash(x) function for low-level values of this Repr. """ - raise TyperError, 'no hashing function for %r' % self + raise TyperError('no hashing function for %r' % self) def get_ll_fasthash_function(self): """Return a 'fast' hash(x) function for low-level values of this @@ -272,12 +270,15 @@ r_baseiter = r_container.make_iterator_repr() return EnumerateIteratorRepr(r_baseiter) return r_container.make_iterator_repr(*self.variant) + def rtyper_makekey_ex(self, rtyper): return self.__class__, rtyper.makekey(self.s_container), self.variant + class __extend__(annmodel.SomeImpossibleValue): def rtyper_makerepr(self, rtyper): return impossible_repr + def rtyper_makekey(self): return self.__class__, @@ -285,14 +286,14 @@ class __extend__(pairtype(Repr, Repr)): - + def rtype_is_((robj1, robj2), hop): if hop.s_result.is_constant(): return inputconst(Bool, hop.s_result.const) return hop.rtyper.type_system.generic_is(robj1, robj2, hop) # default implementation for checked getitems - + def rtype_getitem_idx_key((r_c1, r_o1), hop): return pair(r_c1, r_o1).rtype_getitem(hop) @@ -343,7 +344,7 @@ return self._opprefix opprefix = property(_get_opprefix) - + class BoolRepr(IntegerRepr): lowleveltype = Bool # NB. no 'opprefix' here. Use 'as_int' systematically. @@ -411,9 +412,9 @@ c.concretetype = lltype return c -class BrokenReprTyperError(TyperError): - """ raised when trying to setup a Repr whose setup - has failed already. +class BrokenReprTyperError(TyperError): + """ raised when trying to setup a Repr whose setup + has failed already. """ def mangle(prefix, name): @@ -489,6 +490,3 @@ def warning(msg): log.WARNING(msg) - - - diff --git a/rpython/rtyper/rpbc.py b/rpython/rtyper/rpbc.py --- a/rpython/rtyper/rpbc.py +++ b/rpython/rtyper/rpbc.py @@ -1,18 +1,15 @@ import types -import sys + +from rpython.annotator import model as annmodel, description +from rpython.flowspace.model import Constant +from rpython.rtyper import rclass, callparse +from rpython.rtyper.annlowlevel import llstr +from rpython.rtyper.error import TyperError +from rpython.rtyper.lltypesystem.lltype import typeOf, Void, Bool +from rpython.rtyper.rmodel import (Repr, inputconst, CanBeNull, mangle, + inputdesc, warning, impossible_repr) from rpython.tool.pairtype import pair, pairtype -from rpython.annotator import model as annmodel -from rpython.annotator import description -from rpython.flowspace.model import Constant -from rpython.rtyper.lltypesystem.lltype import \ - typeOf, Void, Bool, nullptr, frozendict, Ptr, Struct, malloc -from rpython.rtyper.error import TyperError -from rpython.rtyper.rmodel import Repr, inputconst, CanBeNull, \ - mangle, inputdesc, warning, impossible_repr -from rpython.rtyper import rclass -from rpython.rtyper.annlowlevel import llstr, llunicode -from rpython.rtyper import callparse def small_cand(rtyper, s_pbc): if 1 < len(s_pbc.descriptions) < rtyper.getconfig().translation.withsmallfuncsets and \ @@ -26,7 +23,7 @@ class __extend__(annmodel.SomePBC): def rtyper_makerepr(self, rtyper): if self.isNone(): - return none_frozen_pbc_repr + return none_frozen_pbc_repr kind = self.getKind() if issubclass(kind, description.FunctionDesc): sample = self.any_description() @@ -50,7 +47,7 @@ elif issubclass(kind, description.MethodOfFrozenDesc): getRepr = rtyper.type_system.rpbc.MethodOfFrozenPBCRepr else: - raise TyperError("unexpected PBC kind %r"%(kind,)) + raise TyperError("unexpected PBC kind %r" % (kind,)) return getRepr(rtyper, self) @@ -82,7 +79,7 @@ """ concretetable = {} # (shape,index): row, maybe with duplicates uniquerows = [] # list of rows, without duplicates - + def lookuprow(row): # a 'matching' row is one that has the same llfn, expect # that it may have more or less 'holes' @@ -333,15 +330,15 @@ return hop.llops.convertvar(v, rresult, hop.r_result) class __extend__(pairtype(AbstractFunctionsPBCRepr, AbstractFunctionsPBCRepr)): - def convert_from_to((r_fpbc1, r_fpbc2), v, llops): - # this check makes sense because both source and dest repr are FunctionsPBCRepr - if r_fpbc1.lowleveltype == r_fpbc2.lowleveltype: - return v - if r_fpbc1.lowleveltype is Void: - return inputconst(r_fpbc2, r_fpbc1.s_pbc.const) - if r_fpbc2.lowleveltype is Void: - return inputconst(Void, None) - return NotImplemented + def convert_from_to((r_fpbc1, r_fpbc2), v, llops): + # this check makes sense because both source and dest repr are FunctionsPBCRepr + if r_fpbc1.lowleveltype == r_fpbc2.lowleveltype: + return v + if r_fpbc1.lowleveltype is Void: + return inputconst(r_fpbc2, r_fpbc1.s_pbc.const) + if r_fpbc2.lowleveltype is Void: + return inputconst(Void, None) + return NotImplemented class OverriddenFunctionPBCRepr(Repr): def __init__(self, rtyper, s_pbc): @@ -377,7 +374,7 @@ result = rtyper.type_system.rpbc.MultipleFrozenPBCRepr(rtyper, access) rtyper.pbc_reprs[access] = result - rtyper.add_pendingsetup(result) + rtyper.add_pendingsetup(result) return result @@ -429,7 +426,7 @@ def convert_const(self, pbc): if pbc is None: - return self.null_instance() + return self.null_instance() if isinstance(pbc, types.MethodType) and pbc.im_self is None: value = pbc.im_func # unbound method -> bare function frozendesc = self.rtyper.annotator.bookkeeper.getdesc(pbc) @@ -455,7 +452,7 @@ mangled_name = mangle('pbc', attr) fields.append((mangled_name, r_value.lowleveltype)) self.fieldmap[attr] = mangled_name, r_value - return fields + return fields def convert_desc(self, frozendesc): if (self.access_set is not None and @@ -525,7 +522,7 @@ # XXX sort this out #call_families = rtyper.annotator.getpbccallfamilies() #call_families.find((None, self.function)) - + if s_pbc.can_be_none(): raise TyperError("unsupported: variable of type " "method-of-frozen-PBC or None") @@ -534,7 +531,7 @@ for desc in s_pbc.descriptions: assert desc.funcdesc is self.funcdesc im_selves.append(desc.frozendesc) - + self.s_im_self = annmodel.SomePBC(im_selves) self.r_im_self = rtyper.getrepr(self.s_im_self) self.lowleveltype = self.r_im_self.lowleveltype @@ -548,7 +545,7 @@ def convert_desc(self, mdesc): if mdesc.funcdesc is not self.funcdesc: - raise TyperError("not a method bound on %r: %r" % (self.funcdesc, + raise TyperError("not a method bound on %r: %r" % (self.funcdesc, mdesc)) return self.r_im_self.convert_desc(mdesc.frozendesc) @@ -615,7 +612,7 @@ def convert_from_to((r_from, _), v, llops): return inputconst(Void, None) - + def rtype_is_((robj1, rnone2), hop): if hop.s_result.is_constant(): return hop.inputconst(Bool, hop.s_result.const) @@ -666,7 +663,7 @@ def convert_desc(self, desc): if desc not in self.s_pbc.descriptions: - raise TyperError("%r not in %r" % (cls, self)) + raise TyperError("%r not in %r" % (desc, self)) if self.lowleveltype is Void: return None subclassdef = desc.getuniqueclassdef() @@ -726,7 +723,7 @@ s_init = classdef.classdesc.s_read_attribute('__init__') v_init = Constant("init-func-dummy") # this value not really used - if (isinstance(s_init, annmodel.SomeImpossibleValue) and + if (isinstance(s_init, annmodel.SomeImpossibleValue) and classdef.classdesc.is_exception_class() and classdef.has_no_attrs()): # special case for instanciating simple built-in @@ -753,7 +750,7 @@ else: s_init = access_set.s_value v_init = r_class.getpbcfield(vtypeptr, access_set, '__init__', - hop.llops) + hop.llops) v_instance = self._instantiate_runtime_class(hop, vtypeptr, r_instance) if isinstance(s_init, annmodel.SomeImpossibleValue): @@ -771,7 +768,6 @@ return v_instance - class __extend__(pairtype(AbstractClassesPBCRepr, rclass.AbstractClassRepr)): def convert_from_to((r_clspbc, r_cls), v, llops): # turn a PBC of classes to a standard pointer-to-vtable class repr @@ -904,4 +900,3 @@ for cdef1 in classdef.getmro(): for attrname in cdef1.attrs: yield cdef1, attrname - diff --git a/rpython/rtyper/rptr.py b/rpython/rtyper/rptr.py --- a/rpython/rtyper/rptr.py +++ b/rpython/rtyper/rptr.py @@ -1,10 +1,10 @@ -from rpython.tool.pairtype import pairtype from rpython.annotator import model as annmodel from rpython.flowspace import model as flowmodel +from rpython.rlib.rarithmetic import r_uint +from rpython.rtyper.error import TyperError from rpython.rtyper.lltypesystem import lltype -from rpython.rtyper.error import TyperError from rpython.rtyper.rmodel import Repr, IntegerRepr -from rpython.rlib.rarithmetic import r_uint +from rpython.tool.pairtype import pairtype class __extend__(annmodel.SomePtr): @@ -345,4 +345,3 @@ if r_from.lowleveltype == r_to.lowleveltype: return v return NotImplemented - diff --git a/rpython/rtyper/rrange.py b/rpython/rtyper/rrange.py --- a/rpython/rtyper/rrange.py +++ b/rpython/rtyper/rrange.py @@ -1,9 +1,9 @@ -from rpython.tool.pairtype import pairtype +from rpython.flowspace.model import Constant from rpython.rtyper.error import TyperError from rpython.rtyper.lltypesystem.lltype import Signed, Void, Ptr +from rpython.rtyper.rlist import dum_nocheck, dum_checkidx from rpython.rtyper.rmodel import Repr, IntegerRepr, IteratorRepr -from rpython.flowspace.model import Constant -from rpython.rtyper.rlist import dum_nocheck, dum_checkidx +from rpython.tool.pairtype import pairtype class AbstractRangeRepr(Repr): @@ -54,9 +54,9 @@ def _ll_rangelen(start, stop, step): if step > 0: - result = (stop - start + (step-1)) // step + result = (stop - start + (step - 1)) // step else: - result = (start - stop - (step+1)) // (-step) + result = (start - stop - (step + 1)) // (-step) if result < 0: result = 0 return result diff --git a/rpython/rtyper/rstr.py b/rpython/rtyper/rstr.py --- a/rpython/rtyper/rstr.py +++ b/rpython/rtyper/rstr.py @@ -1,16 +1,15 @@ -from rpython.tool.staticmethods import StaticMethods +from rpython.annotator import model as annmodel +from rpython.rlib import jit +from rpython.rtyper import rint +from rpython.rtyper.error import TyperError +from rpython.rtyper.lltypesystem.lltype import (Signed, Bool, Void, UniChar, + typeOf) +from rpython.rtyper.rmodel import IntegerRepr, IteratorRepr, inputconst, Repr +from rpython.rtyper.rtuple import AbstractTupleRepr from rpython.tool.pairtype import pairtype, pair from rpython.tool.sourcetools import func_with_new_name -from rpython.annotator import model as annmodel -from rpython.rlib import jit -from rpython.rlib.nonconst import NonConstant -from rpython.rtyper.error import TyperError -from rpython.rtyper.rmodel import IntegerRepr, IteratorRepr -from rpython.rtyper.rmodel import inputconst, Repr -from rpython.rtyper.rtuple import AbstractTupleRepr -from rpython.rtyper import rint -from rpython.rtyper.lltypesystem.lltype import Signed, Bool, Void, UniChar,\ - cast_primitive, typeOf +from rpython.tool.staticmethods import StaticMethods + class AbstractStringRepr(Repr): @@ -37,7 +36,7 @@ def ll_raise_unicode_exception_decode(self, errors, encoding, msg, s, startingpos, endingpos): raise UnicodeDecodeError(encoding, s, startingpos, endingpos, msg) - + class AbstractCharRepr(AbstractStringRepr): def rtype_method_lower(self, hop): @@ -87,7 +86,7 @@ def ll_raise_unicode_exception_encode(self, errors, encoding, msg, u, startingpos, endingpos): raise UnicodeEncodeError(encoding, u, startingpos, endingpos, msg) - + class __extend__(annmodel.SomeString): def rtyper_makerepr(self, rtyper): return rtyper.type_system.rstr.string_repr @@ -356,8 +355,8 @@ hop.exception_is_here() return hop.gendirectcall(self.ll.ll_int, v_str, c_base) if not hop.args_r[1] == rint.signed_repr: - raise TyperError, 'base needs to be an int' - v_str, v_base= hop.inputargs(string_repr, rint.signed_repr) + raise TyperError('base needs to be an int') + v_str, v_base = hop.inputargs(string_repr, rint.signed_repr) hop.exception_is_here() From noreply at buildbot.pypy.org Thu Feb 21 11:13:46 2013 From: noreply at buildbot.pypy.org (fijal) Date: Thu, 21 Feb 2013 11:13:46 +0100 (CET) Subject: [pypy-commit] pypy default: missing rtyper_makekey Message-ID: <20130221101346.51BF61C0228@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r61533:63466cc2d5a8 Date: 2013-02-21 12:12 +0200 http://bitbucket.org/pypy/pypy/changeset/63466cc2d5a8/ Log: missing rtyper_makekey diff --git a/rpython/rtyper/rptr.py b/rpython/rtyper/rptr.py --- a/rpython/rtyper/rptr.py +++ b/rpython/rtyper/rptr.py @@ -23,6 +23,8 @@ def rtyper_makerepr(self, rtyper): return InteriorPtrRepr(self.ll_ptrtype) + def rtyper_makekey(self): + return self.__class__, self.ll_ptrtype class PtrRepr(Repr): From noreply at buildbot.pypy.org Thu Feb 21 11:14:10 2013 From: noreply at buildbot.pypy.org (fijal) Date: Thu, 21 Feb 2013 11:14:10 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: merge default Message-ID: <20130221101410.5F51F1C0228@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61534:506c40ccbb06 Date: 2013-02-21 12:13 +0200 http://bitbucket.org/pypy/pypy/changeset/506c40ccbb06/ Log: merge default diff --git a/rpython/rtyper/rptr.py b/rpython/rtyper/rptr.py --- a/rpython/rtyper/rptr.py +++ b/rpython/rtyper/rptr.py @@ -23,6 +23,8 @@ def rtyper_makerepr(self, rtyper): return InteriorPtrRepr(self.ll_ptrtype) + def rtyper_makekey(self): + return self.__class__, self.ll_ptrtype class PtrRepr(Repr): From noreply at buildbot.pypy.org Thu Feb 21 14:46:26 2013 From: noreply at buildbot.pypy.org (fijal) Date: Thu, 21 Feb 2013 14:46:26 +0100 (CET) Subject: [pypy-commit] pypy default: fix formatting? Message-ID: <20130221134626.8E8C31C0237@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r61535:82eec7c33061 Date: 2013-02-21 15:45 +0200 http://bitbucket.org/pypy/pypy/changeset/82eec7c33061/ Log: fix formatting? diff --git a/pypy/doc/index.rst b/pypy/doc/index.rst --- a/pypy/doc/index.rst +++ b/pypy/doc/index.rst @@ -295,8 +295,7 @@ ``*/test/`` many directories have a test subdirectory containing test modules (see `Testing in PyPy`_) -``_cache/`` holds cache files from internally `translating application - level to interpreterlevel`_ code. +``_cache/`` holds cache files from internally `translating application level to interpreterlevel`_ code. ================================ =========================================== .. _`bytecode interpreter`: interpreter.html From noreply at buildbot.pypy.org Thu Feb 21 14:50:08 2013 From: noreply at buildbot.pypy.org (bivab) Date: Thu, 21 Feb 2013 14:50:08 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: port changes to storing and restoring exception info Message-ID: <20130221135008.DFAF61C0237@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: jitframe-on-heap Changeset: r61536:affdcf6df46c Date: 2013-02-21 14:25 +0100 http://bitbucket.org/pypy/pypy/changeset/affdcf6df46c/ Log: port changes to storing and restoring exception info diff --git a/rpython/jit/backend/arm/assembler.py b/rpython/jit/backend/arm/assembler.py --- a/rpython/jit/backend/arm/assembler.py +++ b/rpython/jit/backend/arm/assembler.py @@ -200,12 +200,28 @@ rawstart = mc.materialize(self.cpu.asmmemmgr, []) self.propagate_exception_path = rawstart - def _store_and_reset_exception(self, mc, resloc): - assert resloc is not r.ip - tmpreg = r.lr # use lr as a second temporary reg + def _store_and_reset_exception(self, mc, excvalloc=None, exctploc=None, + on_frame=False): + """ Resest the exception. If excvalloc is None, then store it on the + frame in jf_guard_exc + """ + assert excvalloc is not r.ip + assert exctploc is not r.ip + tmpreg = r.lr mc.gen_load_int(r.ip.value, self.cpu.pos_exc_value()) - if resloc is not None: # store - self.load_reg(mc, resloc, r.ip, 0) + if excvalloc is not None: # store + assert excvalloc.is_reg() + self.load_reg(mc, excvalloc, r.ip) + if on_frame: + # store exc_value in JITFRAME + ofs = self.cpu.get_ofs_of_frame_field('jf_guard_exc') + assert check_imm_arg(ofs) + self.store_reg(mc, r.ip, r.fp, ofs) + if exctploc is not None: + # store pos_exception in exctploc + assert exctploc.is_reg() + mc.gen_load_int(r.ip.value, self.cpu.pos_exception()) + self.load_reg(mc, exctploc, r.ip) # reset exception mc.gen_load_int(tmpreg.value, 0) @@ -215,6 +231,23 @@ mc.gen_load_int(r.ip.value, self.cpu.pos_exception()) self.store_reg(mc, tmpreg, r.ip, 0) + def _restore_exception(self, mc, excvalloc, exctploc): + assert excvalloc is not r.ip + assert exctploc is not r.ip + tmpreg = r.lr # use lr as a second temporary reg + mc.gen_load_int(r.ip.value, self.cpu.pos_exc_value()) + if excvalloc is not None: + assert excvalloc.is_reg() + self.store_reg(mc, excvalloc, r.ip) + else: + # load exc_value from JITFRAME and put it in pos_exc_value + ofs = self.cpu.get_ofs_of_frame_field('jf_guard_exc') + self.load_reg(mc, tmpreg, r.fp, ofs) + self.store_reg(mc, tmpreg, r.ip) + + mc.gen_load_int(r.ip.value, self.cpu.pos_exception()) + self.store_reg(mc, exctploc, r.ip) + def _build_stack_check_slowpath(self): _, _, slowpathaddr = self.cpu.insert_stack_check() if slowpathaddr == 0 or not self.cpu.propagate_exception_descr: @@ -742,11 +775,20 @@ # set first arg, which is the old jitframe address mc.MOV_rr(r.r0.value, r.fp.value) + + # store a possibly present exception + # we use a callee saved reg here as a tmp for the exc. + self._store_and_reset_exception(mc, None, r.fp, on_frame=True) + # call realloc_frame, it takes two arguments # arg0: the old jitframe # arg1: the new size # mc.BL(self.cpu.realloc_frame) + + # restore a possibly present exception + self._restore_exception(mc, None, r.fp) + # set fp to the new jitframe mc.MOV_rr(r.fp.value, r.r0.value) From noreply at buildbot.pypy.org Thu Feb 21 14:50:10 2013 From: noreply at buildbot.pypy.org (bivab) Date: Thu, 21 Feb 2013 14:50:10 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: set ofs by default to 0 in store_reg and load_reg Message-ID: <20130221135010.0FF931C0237@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: jitframe-on-heap Changeset: r61537:3e38be380144 Date: 2013-02-21 14:26 +0100 http://bitbucket.org/pypy/pypy/changeset/3e38be380144/ Log: set ofs by default to 0 in store_reg and load_reg diff --git a/rpython/jit/backend/arm/assembler.py b/rpython/jit/backend/arm/assembler.py --- a/rpython/jit/backend/arm/assembler.py +++ b/rpython/jit/backend/arm/assembler.py @@ -993,7 +993,7 @@ self.mc.gen_load_int(r.ip.value, value.getint()) self.mc.VLDR(loc.value, r.ip.value) - def load_reg(self, mc, target, base, ofs, cond=c.AL, helper=r.ip): + def load_reg(self, mc, target, base, ofs=0, cond=c.AL, helper=r.ip): if target.is_vfp_reg(): return self._load_vfp_reg(mc, target, base, ofs, cond, helper) elif target.is_reg(): @@ -1014,7 +1014,7 @@ mc.gen_load_int(helper.value, ofs, cond=cond) mc.LDR_rr(target.value, base.value, helper.value, cond=cond) - def store_reg(self, mc, source, base, ofs, cond=c.AL, helper=r.ip): + def store_reg(self, mc, source, base, ofs=0, cond=c.AL, helper=r.ip): if source.is_vfp_reg(): return self._store_vfp_reg(mc, source, base, ofs, cond, helper) else: From noreply at buildbot.pypy.org Thu Feb 21 14:50:11 2013 From: noreply at buildbot.pypy.org (bivab) Date: Thu, 21 Feb 2013 14:50:11 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: rename _build_stack_check_failure to build_frame_realloc_slowpath Message-ID: <20130221135011.3FBB61C0237@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: jitframe-on-heap Changeset: r61538:5e490176a2ba Date: 2013-02-21 14:27 +0100 http://bitbucket.org/pypy/pypy/changeset/5e490176a2ba/ Log: rename _build_stack_check_failure to build_frame_realloc_slowpath diff --git a/rpython/jit/backend/arm/assembler.py b/rpython/jit/backend/arm/assembler.py --- a/rpython/jit/backend/arm/assembler.py +++ b/rpython/jit/backend/arm/assembler.py @@ -740,7 +740,7 @@ self.push_gcmap(mc, gcmap, push=True) - self.mc.BL(self._stack_check_failure) + self.mc.BL(self._frame_realloc_slowpath) # patch jg_location above currpos = self.mc.currpos() @@ -749,7 +749,7 @@ return stack_check_cmp_ofs - def _build_stack_check_failure(self): + def build_frame_realloc_slowpath(self): # this code should do the following steps # a) store all registers in the jitframe # b) fish for the arguments passed by the caller @@ -805,7 +805,7 @@ # restore registers self._pop_all_regs_from_jitframe(mc, [], self.cpu.supports_floats) mc.POP([r.ip.value, r.pc.value]) # return - self._stack_check_failure = mc.materialize(self.cpu.asmmemmgr, []) + self._frame_realloc_slowpath = mc.materialize(self.cpu.asmmemmgr, []) def _load_shadowstack_top(self, mc, reg, gcrootmap): rst = gcrootmap.get_root_stack_top_addr() From noreply at buildbot.pypy.org Thu Feb 21 14:50:12 2013 From: noreply at buildbot.pypy.org (bivab) Date: Thu, 21 Feb 2013 14:50:12 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: in progress: update wb_slowpath Message-ID: <20130221135012.79BB21C0237@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: jitframe-on-heap Changeset: r61539:2366da3f56c9 Date: 2013-02-21 14:29 +0100 http://bitbucket.org/pypy/pypy/changeset/2366da3f56c9/ Log: in progress: update wb_slowpath diff --git a/rpython/jit/backend/arm/assembler.py b/rpython/jit/backend/arm/assembler.py --- a/rpython/jit/backend/arm/assembler.py +++ b/rpython/jit/backend/arm/assembler.py @@ -312,12 +312,20 @@ # It must keep stack alignment accordingly. mc = ARMv7Builder() # - if withfloats: - floats = r.caller_vfp_resp + exc0 = exc1 = None + mc.PUSH([r.ip.value, r.lr.value]) # push two words to keep alignment + if not for_frame: + self._push_all_regs_to_jitframe(mc, [], withfloats, callee_only=True) else: - floats = [] - with saved_registers(mc, r.caller_resp + [r.ip, r.lr], floats): - mc.BL(func) + # we're possibly called from the slowpath of malloc + # save the caller saved registers + # assuming we do not collect here + exc0, exc1 = r.r4, r.r5 + mc.PUSH([gpr.value for gpr in r.caller_resp] + [exc0.value, exc1.value]) + mc.VPUSH([vfpr.value for vfpr in r.caller_vfp_resp]) + + self._store_and_reset_exception(mc, exc0, exc1) + mc.BL(func) # if withcards: # A final TEST8 before the RET, for the caller. Careful to @@ -327,10 +335,20 @@ imm=descr.jit_wb_if_flag_byteofs) mc.TST_ri(r.ip.value, imm=0x80) # - mc.MOV_rr(r.pc.value, r.lr.value) + if not for_frame: + self._pop_all_regs_from_jitframe(mc, [], withfloats, callee_only=True) + else: + self._restore_exception(mc, exc0, exc1) + mc.VPOP([vfpr.value for vfpr in r.caller_vfp_resp]) + mc.POP([gpr.value for gpr in r.caller_resp] + + [exc0.value, exc1.value]) + mc.POP([r.ip.value, r.pc.value]) # rawstart = mc.materialize(self.cpu.asmmemmgr, []) - self.wb_slowpath[withcards + 2 * withfloats] = rawstart + if for_frame: + self.wb_slowpath[4] = rawstart + else: + self.wb_slowpath[withcards + 2 * withfloats] = rawstart def _build_malloc_slowpath(self): return # XXX fix me From noreply at buildbot.pypy.org Thu Feb 21 14:50:14 2013 From: noreply at buildbot.pypy.org (bivab) Date: Thu, 21 Feb 2013 14:50:14 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: merge heads Message-ID: <20130221135014.684041C0237@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: jitframe-on-heap Changeset: r61540:2b3c042db410 Date: 2013-02-21 14:49 +0100 http://bitbucket.org/pypy/pypy/changeset/2b3c042db410/ Log: merge heads diff too long, truncating to 2000 out of 2436 lines diff --git a/lib_pypy/datetime.py b/lib_pypy/datetime.py --- a/lib_pypy/datetime.py +++ b/lib_pypy/datetime.py @@ -271,6 +271,8 @@ raise ValueError("%s()=%d, must be in -1439..1439" % (name, offset)) def _check_int_field(value): + if isinstance(value, int): + return value if not isinstance(value, float): try: value = value.__int__() @@ -279,7 +281,7 @@ else: if isinstance(value, (int, long)): return value - raise TypeError('integer argument expected') + raise TypeError('an integer is required') def _check_date_fields(year, month, day): year = _check_int_field(year) @@ -457,6 +459,8 @@ felt like it. """ + __slots__ = '_days', '_seconds', '_microseconds' + def __new__(cls, days=0, seconds=0, microseconds=0, # XXX The following should only be used as keyword args: milliseconds=0, minutes=0, hours=0, weeks=0): @@ -770,6 +774,8 @@ year, month, day """ + __slots__ = '_year', '_month', '_day' + def __new__(cls, year, month=None, day=None): """Constructor. @@ -777,7 +783,7 @@ year, month, day (required, base 1) """ - if isinstance(year, str): + if isinstance(year, str) and len(year) == 4: # Pickle support self = object.__new__(cls) self.__setstate(year) @@ -1063,6 +1069,8 @@ Subclasses must override the name(), utcoffset() and dst() methods. """ + __slots__ = () + def tzname(self, dt): "datetime -> string name of time zone." raise NotImplementedError("tzinfo subclass must override tzname()") @@ -1155,6 +1163,8 @@ hour, minute, second, microsecond, tzinfo """ + __slots__ = '_hour', '_minute', '_second', '_microsecond', '_tzinfo' + def __new__(cls, hour=0, minute=0, second=0, microsecond=0, tzinfo=None): """Constructor. @@ -1457,9 +1467,11 @@ instance of a tzinfo subclass. The remaining arguments may be ints or longs. """ + __slots__ = date.__slots__ + time.__slots__ + def __new__(cls, year, month=None, day=None, hour=0, minute=0, second=0, microsecond=0, tzinfo=None): - if isinstance(year, str): + if isinstance(year, str) and len(year) == 10: # Pickle support self = date.__new__(cls, year[:4]) self.__setstate(year, month) diff --git a/pypy/doc/coding-guide.rst b/pypy/doc/coding-guide.rst --- a/pypy/doc/coding-guide.rst +++ b/pypy/doc/coding-guide.rst @@ -303,7 +303,7 @@ dicts with a unique key type only, provided it is hashable. Custom hash functions and custom equality will not be honored. - Use ``pypy.rlib.objectmodel.r_dict`` for custom hash functions. + Use ``rpython.rlib.objectmodel.r_dict`` for custom hash functions. **list comprehensions** @@ -365,7 +365,7 @@ We use normal integers for signed arithmetic. It means that before translation we get longs in case of overflow, and after translation we get a silent wrap-around. Whenever we need more control, we use the following -helpers (which live the `pypy/rlib/rarithmetic.py`_): +helpers (which live in `rpython/rlib/rarithmetic.py`_): **ovfcheck()** diff --git a/pypy/doc/getting-started-dev.rst b/pypy/doc/getting-started-dev.rst --- a/pypy/doc/getting-started-dev.rst +++ b/pypy/doc/getting-started-dev.rst @@ -58,8 +58,7 @@ only use low level types that are available in C (e.g. int). The compiled version is now in a ``.so`` library. You can run it say using ctypes: - >>> from ctypes import CDLL - >>> f = CDLL(lib) + >>> f = get_c_function(lib, snippet.is_perfect_number) >>> f(5) 0 >>> f(6) diff --git a/pypy/doc/rlib.rst b/pypy/doc/rlib.rst --- a/pypy/doc/rlib.rst +++ b/pypy/doc/rlib.rst @@ -7,18 +7,18 @@ .. contents:: -This page lists some of the modules in `pypy/rlib`_ together with some hints +This page lists some of the modules in `rpython/rlib`_ together with some hints for what they can be used for. The modules here will make up some general library useful for RPython programs (since most of the standard library modules are not RPython). Most of these modules are somewhat rough still and are likely to change at some point. Usually it is useful to look at the tests in -`pypy/rlib/test`_ to get an impression of how to use a module. +`rpython/rlib/test`_ to get an impression of how to use a module. ``listsort`` ============ -The `pypy/rlib/listsort.py`_ module contains an implementation of the timsort sorting algorithm +The `rpython/rlib/listsort.py`_ module contains an implementation of the timsort sorting algorithm (the sort method of lists is not RPython). To use it, subclass from the ``listsort.TimSort`` class and override the ``lt`` method to change the comparison behaviour. The constructor of ``TimSort`` takes a list as an @@ -30,7 +30,7 @@ ``nonconst`` ============ -The `pypy/rlib/nonconst.py`_ module is useful mostly for tests. The `flow object space`_ and +The `rpython/rlib/nonconst.py`_ module is useful mostly for tests. The `flow object space`_ and the `annotator`_ do quite some constant folding, which is sometimes not desired in a test. To prevent constant folding on a certain value, use the ``NonConst`` class. The constructor of ``NonConst`` takes an arbitrary value. The instance of @@ -44,7 +44,7 @@ ``objectmodel`` =============== -The `pypy/rlib/objectmodel.py`_ module is a mixed bag of various functionality. Some of the +The `rpython/rlib/objectmodel.py`_ module is a mixed bag of various functionality. Some of the more useful ones are: ``ComputedIntSymbolic``: @@ -94,7 +94,7 @@ ``rarithmetic`` =============== -The `pypy/rlib/rarithmetic.py`_ module contains functionality to handle the small differences +The `rpython/rlib/rarithmetic.py`_ module contains functionality to handle the small differences in the behaviour of arithmetic code in regular Python and RPython code. Most of them are already described in the `coding guide`_ @@ -104,7 +104,7 @@ ``rbigint`` =========== -The `pypy/rlib/rbigint.py`_ module contains a full RPython implementation of the Python ``long`` +The `rpython/rlib/rbigint.py`_ module contains a full RPython implementation of the Python ``long`` type (which itself is not supported in RPython). The ``rbigint`` class contains that implementation. To construct ``rbigint`` instances use the static methods ``fromint``, ``frombool``, ``fromfloat`` and ``fromdecimalstr``. To convert back @@ -118,7 +118,7 @@ ``rrandom`` =========== -The `pypy/rlib/rrandom.py`_ module contains an implementation of the mersenne twister random +The `rpython/rlib/rrandom.py`_ module contains an implementation of the mersenne twister random number generator. It contains one class ``Random`` which most importantly has a ``random`` method which returns a pseudo-random floating point number between 0.0 and 1.0. @@ -126,7 +126,7 @@ ``rsocket`` =========== -The `pypy/rlib/rsocket.py`_ module contains an RPython implementation of the functionality of +The `rpython/rlib/rsocket.py`_ module contains an RPython implementation of the functionality of the socket standard library with a slightly different interface. The difficulty with the Python socket API is that addresses are not "well-typed" objects: depending on the address family they are tuples, or strings, and @@ -137,7 +137,7 @@ ``streamio`` ============ -The `pypy/rlib/streamio.py`_ contains an RPython stream I/O implementation (which was started +The `rpython/rlib/streamio.py`_ contains an RPython stream I/O implementation (which was started by Guido van Rossum as `sio.py`_ in the CPython sandbox as a prototype for the upcoming new file implementation in Python 3000). @@ -146,7 +146,7 @@ ``unroll`` ========== -The `pypy/rlib/unroll.py`_ module most importantly contains the function ``unrolling_iterable`` +The `rpython/rlib/unroll.py`_ module most importantly contains the function ``unrolling_iterable`` which wraps an iterator. Looping over the iterator in RPython code will not produce a loop in the resulting flow graph but will unroll the loop instead. @@ -154,7 +154,7 @@ ``parsing`` =========== -The `pypy/rlib/parsing/`_ module is a still in-development module to generate tokenizers and +The `rpython/rlib/parsing/`_ module is a still in-development module to generate tokenizers and parsers in RPython. It is still highly experimental and only really used by the `Prolog interpreter`_ (although in slightly non-standard ways). The easiest way to specify a tokenizer/grammar is to write it down using regular expressions and @@ -204,7 +204,7 @@ anything except a. To parse a regular expression and to get a matcher for it, you can use the -function ``make_runner(s)`` in the ``pypy.rlib.parsing.regexparse`` module. It +function ``make_runner(s)`` in the ``rpython.rlib.parsing.regexparse`` module. It returns a object with a ``recognize(input)`` method that returns True or False depending on whether ``input`` matches the string or not. @@ -213,7 +213,7 @@ EBNF ---- -To describe a tokenizer and a grammar the ``pypy.rlib.parsing.ebnfparse`` +To describe a tokenizer and a grammar the ``rpython.rlib.parsing.ebnfparse`` defines a syntax for doing that. The syntax file contains a sequence or rules. Every rule either describes a @@ -295,7 +295,7 @@ The parsing process builds up a tree consisting of instances of ``Symbol`` and ``Nonterminal``, the former corresponding to tokens, the latter to nonterminal -symbols. Both classes live in the `pypy/rlib/parsing/tree.py`_ module. You can use +symbols. Both classes live in the `rpython/rlib/parsing/tree.py`_ module. You can use the ``view()`` method ``Nonterminal`` instances to get a pygame view of the parse tree. @@ -310,7 +310,7 @@ ++++++++ To write tree visitors for the parse trees that are RPython, there is a special -baseclass ``RPythonVisitor`` in `pypy/rlib/parsing/tree.py`_ to use. If your +baseclass ``RPythonVisitor`` in `rpython/rlib/parsing/tree.py`_ to use. If your class uses this, it will grow a ``dispatch(node)`` method, that calls an appropriate ``visit_`` method, depending on the ``node`` argument. Here the is replaced by the ``symbol`` attribute of the visited node. diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -1494,10 +1494,11 @@ ) return fd - def warn(self, msg, w_warningcls): - self.appexec([self.wrap(msg), w_warningcls], """(msg, warningcls): + def warn(self, w_msg, w_warningcls, stacklevel=2): + self.appexec([w_msg, w_warningcls, self.wrap(stacklevel)], + """(msg, warningcls, stacklevel): import _warnings - _warnings.warn(msg, warningcls, stacklevel=2) + _warnings.warn(msg, warningcls, stacklevel=stacklevel) """) diff --git a/pypy/interpreter/pyopcode.py b/pypy/interpreter/pyopcode.py --- a/pypy/interpreter/pyopcode.py +++ b/pypy/interpreter/pyopcode.py @@ -776,17 +776,16 @@ @jit.unroll_safe def cmp_exc_match(self, w_1, w_2): - if self.space.is_true(self.space.isinstance(w_2, self.space.w_tuple)): - for w_t in self.space.fixedview(w_2): - if self.space.is_true(self.space.isinstance(w_t, - self.space.w_str)): - self.space.warn("catching of string exceptions is " - "deprecated", - self.space.w_DeprecationWarning) - elif self.space.is_true(self.space.isinstance(w_2, self.space.w_str)): - self.space.warn("catching of string exceptions is deprecated", - self.space.w_DeprecationWarning) - return self.space.newbool(self.space.exception_match(w_1, w_2)) + space = self.space + if space.is_true(space.isinstance(w_2, space.w_tuple)): + for w_t in space.fixedview(w_2): + if space.is_true(space.isinstance(w_t, space.w_str)): + msg = "catching of string exceptions is deprecated" + space.warn(space.wrap(msg), space.w_DeprecationWarning) + elif space.is_true(space.isinstance(w_2, space.w_str)): + msg = "catching of string exceptions is deprecated" + space.warn(space.wrap(msg), space.w_DeprecationWarning) + return space.newbool(space.exception_match(w_1, w_2)) def COMPARE_OP(self, testnum, next_instr): w_2 = self.popvalue() diff --git a/pypy/module/__builtin__/functional.py b/pypy/module/__builtin__/functional.py --- a/pypy/module/__builtin__/functional.py +++ b/pypy/module/__builtin__/functional.py @@ -133,56 +133,77 @@ v = v.add(step) return space.newlist(res_w) +min_jitdriver = jit.JitDriver(name='min', + greens=['w_type'], reds='auto') +max_jitdriver = jit.JitDriver(name='max', + greens=['w_type'], reds='auto') + +def make_min_max(unroll): + @specialize.arg(2) + def min_max_impl(space, args, implementation_of): + if implementation_of == "max": + compare = space.gt + jitdriver = max_jitdriver + else: + compare = space.lt + jitdriver = min_jitdriver + args_w = args.arguments_w + if len(args_w) > 1: + w_sequence = space.newtuple(args_w) + elif len(args_w): + w_sequence = args_w[0] + else: + msg = "%s() expects at least one argument" % (implementation_of,) + raise OperationError(space.w_TypeError, space.wrap(msg)) + w_key = None + kwds = args.keywords + if kwds: + if kwds[0] == "key" and len(kwds) == 1: + w_key = args.keywords_w[0] + else: + msg = "%s() got unexpected keyword argument" % (implementation_of,) + raise OperationError(space.w_TypeError, space.wrap(msg)) + + w_iter = space.iter(w_sequence) + w_type = space.type(w_iter) + w_max_item = None + w_max_val = None + while True: + if not unroll: + jitdriver.jit_merge_point(w_type=w_type) + try: + w_item = space.next(w_iter) + except OperationError, e: + if not e.match(space, space.w_StopIteration): + raise + break + if w_key is not None: + w_compare_with = space.call_function(w_key, w_item) + else: + w_compare_with = w_item + if w_max_item is None or \ + space.is_true(compare(w_compare_with, w_max_val)): + w_max_item = w_item + w_max_val = w_compare_with + if w_max_item is None: + msg = "arg is an empty sequence" + raise OperationError(space.w_ValueError, space.wrap(msg)) + return w_max_item + if unroll: + min_max_impl = jit.unroll_safe(min_max_impl) + return min_max_impl + +min_max_unroll = make_min_max(True) +min_max_normal = make_min_max(False) @specialize.arg(2) - at jit.look_inside_iff(lambda space, args, implementation_of: - jit.isconstant(len(args.arguments_w)) and - len(args.arguments_w) == 2 -) def min_max(space, args, implementation_of): - if implementation_of == "max": - compare = space.gt + if not jit.we_are_jitted() or (jit.isconstant(len(args.arguments_w)) and + len(args.arguments_w) == 2): + return min_max_unroll(space, args, implementation_of) else: - compare = space.lt - args_w = args.arguments_w - if len(args_w) > 1: - w_sequence = space.newtuple(args_w) - elif len(args_w): - w_sequence = args_w[0] - else: - msg = "%s() expects at least one argument" % (implementation_of,) - raise OperationError(space.w_TypeError, space.wrap(msg)) - w_key = None - kwds = args.keywords - if kwds: - if kwds[0] == "key" and len(kwds) == 1: - w_key = args.keywords_w[0] - else: - msg = "%s() got unexpected keyword argument" % (implementation_of,) - raise OperationError(space.w_TypeError, space.wrap(msg)) - - w_iter = space.iter(w_sequence) - w_max_item = None - w_max_val = None - while True: - try: - w_item = space.next(w_iter) - except OperationError, e: - if not e.match(space, space.w_StopIteration): - raise - break - if w_key is not None: - w_compare_with = space.call_function(w_key, w_item) - else: - w_compare_with = w_item - if w_max_item is None or \ - space.is_true(compare(w_compare_with, w_max_val)): - w_max_item = w_item - w_max_val = w_compare_with - if w_max_item is None: - msg = "arg is an empty sequence" - raise OperationError(space.w_ValueError, space.wrap(msg)) - return w_max_item + return min_max_normal(space, args, implementation_of) +min_max._always_inline = True def max(space, __args__): """max(iterable[, key=func]) -> value diff --git a/pypy/module/__builtin__/interp_classobj.py b/pypy/module/__builtin__/interp_classobj.py --- a/pypy/module/__builtin__/interp_classobj.py +++ b/pypy/module/__builtin__/interp_classobj.py @@ -154,9 +154,9 @@ return elif name == "__del__": if self.lookup(space, name) is None: - msg = ("a __del__ method added to an existing class " - "will not be called") - space.warn(msg, space.w_RuntimeWarning) + msg = ("a __del__ method added to an existing class will " + "not be called") + space.warn(space.wrap(msg), space.w_RuntimeWarning) space.setitem(self.w_dict, w_attr, w_value) def descr_delattr(self, space, w_attr): @@ -395,9 +395,9 @@ cache = space.fromcache(Cache) if (not isinstance(self, cache.cls_with_del) and self.getdictvalue(space, '__del__') is None): - msg = ("a __del__ method added to an instance " - "with no __del__ in the class will not be called") - space.warn(msg, space.w_RuntimeWarning) + msg = ("a __del__ method added to an instance with no " + "__del__ in the class will not be called") + space.warn(space.wrap(msg), space.w_RuntimeWarning) if w_meth is not None: space.call_function(w_meth, w_name, w_value) else: @@ -454,11 +454,9 @@ else: w_as_str = self.descr_str(space) if space.len_w(w_format_spec) > 0: - space.warn( - ("object.__format__ with a non-empty format string is " - "deprecated"), - space.w_PendingDeprecationWarning - ) + msg = ("object.__format__ with a non-empty format string is " + "deprecated") + space.warn(space.wrap(msg), space.w_PendingDeprecationWarning) return space.format(w_as_str, w_format_spec) def descr_len(self, space): diff --git a/pypy/module/_io/interp_bufferedio.py b/pypy/module/_io/interp_bufferedio.py --- a/pypy/module/_io/interp_bufferedio.py +++ b/pypy/module/_io/interp_bufferedio.py @@ -76,7 +76,7 @@ raise NotImplementedError def _deprecated_max_buffer_size(self, space): - space.warn("max_buffer_size is deprecated", + space.warn(space.wrap("max_buffer_size is deprecated"), space.w_DeprecationWarning) def read_w(self, space, w_size=None): diff --git a/pypy/module/_io/interp_fileio.py b/pypy/module/_io/interp_fileio.py --- a/pypy/module/_io/interp_fileio.py +++ b/pypy/module/_io/interp_fileio.py @@ -3,6 +3,7 @@ from pypy.interpreter.error import OperationError, wrap_oserror, wrap_oserror2 from rpython.rlib.rarithmetic import r_longlong from rpython.rlib.rstring import StringBuilder +from rpython.rlib.rposix import validate_fd from os import O_RDONLY, O_WRONLY, O_RDWR, O_CREAT, O_TRUNC import sys, os, stat, errno from pypy.module._io.interp_iobase import W_RawIOBase, convert_size @@ -117,9 +118,6 @@ return currentsize + BIGCHUNK return currentsize + SMALLCHUNK -def verify_fd(fd): - return - class W_FileIO(W_RawIOBase): def __init__(self, space): W_RawIOBase.__init__(self, space) @@ -156,7 +154,7 @@ fd_is_own = False try: if fd >= 0: - verify_fd(fd) + validate_fd(fd) try: os.fstat(fd) except OSError, e: @@ -237,7 +235,7 @@ self.fd = -1 try: - verify_fd(fd) + validate_fd(fd) os.close(fd) except OSError, e: raise wrap_oserror(space, e, diff --git a/pypy/module/cpyext/import_.py b/pypy/module/cpyext/import_.py --- a/pypy/module/cpyext/import_.py +++ b/pypy/module/cpyext/import_.py @@ -46,8 +46,9 @@ @cpython_api([CONST_STRING], PyObject) def PyImport_ImportModuleNoBlock(space, name): - space.warn('PyImport_ImportModuleNoBlock() is not non-blocking', - space.w_RuntimeWarning) + space.warn( + space.wrap('PyImport_ImportModuleNoBlock() is not non-blocking'), + space.w_RuntimeWarning) return PyImport_Import(space, space.wrap(rffi.charp2str(name))) @cpython_api([PyObject], PyObject) diff --git a/pypy/module/exceptions/interp_exceptions.py b/pypy/module/exceptions/interp_exceptions.py --- a/pypy/module/exceptions/interp_exceptions.py +++ b/pypy/module/exceptions/interp_exceptions.py @@ -176,8 +176,8 @@ if self.w_message is None: raise OperationError(space.w_AttributeError, space.wrap("message was deleted")) - space.warn("BaseException.message has been deprecated as of Python 2.6", - space.w_DeprecationWarning) + msg = "BaseException.message has been deprecated as of Python 2.6" + space.warn(space.wrap(msg), space.w_DeprecationWarning) return self.w_message def descr_message_set(self, space, w_new): diff --git a/pypy/module/imp/importing.py b/pypy/module/imp/importing.py --- a/pypy/module/imp/importing.py +++ b/pypy/module/imp/importing.py @@ -174,9 +174,9 @@ "Parent module '%s' not loaded, " "cannot perform relative import" % ctxt_package)) else: - space.warn("Parent module '%s' not found " - "while handling absolute import" % ctxt_package, - space.w_RuntimeWarning) + msg = ("Parent module '%s' not found while handling absolute " + "import" % ctxt_package) + space.warn(space.wrap(msg), space.w_RuntimeWarning) rel_modulename = ctxt_package[:dot_position] rel_level = rel_modulename.count('.') + 1 @@ -533,9 +533,9 @@ if modtype in (PY_SOURCE, PY_COMPILED): return FindInfo(PKG_DIRECTORY, filepart, None) else: - msg = "Not importing directory " +\ - "'%s' missing __init__.py" % (filepart,) - space.warn(msg, space.w_ImportWarning) + msg = ("Not importing directory '%s' missing __init__.py" % + (filepart,)) + space.warn(space.wrap(msg), space.w_ImportWarning) modtype, suffix, filemode = find_modtype(space, filepart) try: if modtype in (PY_SOURCE, PY_COMPILED, C_EXTENSION): diff --git a/pypy/module/micronumpy/app_numpy.py b/pypy/module/micronumpy/app_numpy.py --- a/pypy/module/micronumpy/app_numpy.py +++ b/pypy/module/micronumpy/app_numpy.py @@ -67,11 +67,15 @@ def min(a, axis=None, out=None): if not hasattr(a, "min"): a = _numpypy.array(a) + if a.size < 1: + return _numpypy.array([]) return a.min(axis=axis, out=out) def max(a, axis=None, out=None): if not hasattr(a, "max"): a = _numpypy.array(a) + if a.size < 1: + return _numpypy.array([]) return a.max(axis=axis, out=out) def arange(start, stop=None, step=1, dtype=None): diff --git a/pypy/module/micronumpy/interp_numarray.py b/pypy/module/micronumpy/interp_numarray.py --- a/pypy/module/micronumpy/interp_numarray.py +++ b/pypy/module/micronumpy/interp_numarray.py @@ -250,7 +250,7 @@ ret = self.implementation.get_imag(self) if ret: return W_NDimArray(ret) - raise OperationError(space.w_NotImplementedError, + raise OperationError(space.w_NotImplementedError, space.wrap('imag not implemented for this dtype')) def descr_set_real(self, space, w_value): @@ -261,7 +261,7 @@ def descr_set_imag(self, space, w_value): # if possible, copy (broadcast) values into self if not self.get_dtype().is_complex_type(): - raise OperationError(space.w_TypeError, + raise OperationError(space.w_TypeError, space.wrap('array does not have imaginary part to set')) tmp = self.implementation.get_imag(self) tmp.setslice(space, convert_to_array(space, w_value)) @@ -302,11 +302,11 @@ @unwrap_spec(axis1=int, axis2=int) def descr_swapaxes(self, space, axis1, axis2): """a.swapaxes(axis1, axis2) - + Return a view of the array with `axis1` and `axis2` interchanged. - + Refer to `numpy.swapaxes` for full documentation. - + See Also -------- numpy.swapaxes : equivalent function @@ -439,7 +439,7 @@ ret = impl.base() if ret is None: return space.w_None - return ret + return ret @unwrap_spec(inplace=bool) def descr_byteswap(self, space, inplace=False): @@ -492,7 +492,7 @@ "axis1 and axis2 cannot be the same")) return interp_arrayops.diagonal(space, self.implementation, offset, axis1, axis2) - + def descr_dump(self, space, w_file): raise OperationError(space.w_NotImplementedError, space.wrap( "dump not implemented yet")) @@ -509,7 +509,7 @@ raise OperationError(space.w_NotImplementedError, space.wrap( "setting flags not implemented yet")) - @unwrap_spec(offset=int) + @unwrap_spec(offset=int) def descr_getfield(self, space, w_dtype, offset): raise OperationError(space.w_NotImplementedError, space.wrap( "getfield not implemented yet")) @@ -518,7 +518,7 @@ raise OperationError(space.w_NotImplementedError, space.wrap( "itemset not implemented yet")) - @unwrap_spec(neworder=str) + @unwrap_spec(neworder=str) def descr_newbyteorder(self, space, neworder): raise OperationError(space.w_NotImplementedError, space.wrap( "newbyteorder not implemented yet")) @@ -551,7 +551,7 @@ raise OperationError(space.w_NotImplementedError, space.wrap( "setfield not implemented yet")) - def descr_setflags(self, space, w_write=None, w_align=None, w_uic=None): + def descr_setflags(self, space, w_write=None, w_align=None, w_uic=None): raise OperationError(space.w_NotImplementedError, space.wrap( "setflags not implemented yet")) @@ -572,7 +572,7 @@ "tofile not implemented yet")) def descr_trace(self, space, w_offset=0, w_axis1=0, w_axis2=1, - w_dtype=None, w_out=None): + w_dtype=None, w_out=None): raise OperationError(space.w_NotImplementedError, space.wrap( "trace not implemented yet")) @@ -627,12 +627,23 @@ w_remainder = self.descr_mod(space, w_other) return space.newtuple([w_quotient, w_remainder]) - descr_eq = _binop_impl("equal") - descr_ne = _binop_impl("not_equal") - descr_lt = _binop_impl("less") - descr_le = _binop_impl("less_equal") - descr_gt = _binop_impl("greater") - descr_ge = _binop_impl("greater_equal") + def _binop_comp_impl(ufunc): + def impl(self, space, w_other, w_out=None): + try: + return ufunc(self, space, w_other, w_out) + except OperationError, e: + if e.match(space, space.w_ValueError): + return space.w_False + raise e + + return func_with_new_name(impl, ufunc.func_name) + + descr_eq = _binop_comp_impl(_binop_impl("equal")) + descr_ne = _binop_comp_impl(_binop_impl("not_equal")) + descr_lt = _binop_comp_impl(_binop_impl("less")) + descr_le = _binop_comp_impl(_binop_impl("less_equal")) + descr_gt = _binop_comp_impl(_binop_impl("greater")) + descr_ge = _binop_comp_impl(_binop_impl("greater_equal")) def _binop_right_impl(ufunc_name): def impl(self, space, w_other, w_out=None): @@ -698,7 +709,7 @@ if space.is_none(w_out): out = None elif not isinstance(w_out, W_NDimArray): - raise OperationError(space.w_TypeError, space.wrap( + raise OperationError(space.w_TypeError, space.wrap( 'output must be an array')) else: out = w_out @@ -718,7 +729,7 @@ descr_cumsum = _reduce_ufunc_impl('add', cumultative=True) descr_cumprod = _reduce_ufunc_impl('multiply', cumultative=True) - + def descr_mean(self, space, w_axis=None, w_out=None): if space.is_none(w_axis): w_denom = space.wrap(self.get_size()) @@ -863,7 +874,7 @@ swapaxes = interp2app(W_NDimArray.descr_swapaxes), flat = GetSetProperty(W_NDimArray.descr_get_flatiter), item = interp2app(W_NDimArray.descr_item), - real = GetSetProperty(W_NDimArray.descr_get_real, + real = GetSetProperty(W_NDimArray.descr_get_real, W_NDimArray.descr_set_real), imag = GetSetProperty(W_NDimArray.descr_get_imag, W_NDimArray.descr_set_imag), @@ -923,7 +934,7 @@ dtype) #if dtype is interp_dtype.get_dtype_cache(space).w_float64dtype: # break - + if dtype is None: dtype = interp_dtype.get_dtype_cache(space).w_float64dtype if ndmin > len(shape): diff --git a/pypy/module/micronumpy/test/test_numarray.py b/pypy/module/micronumpy/test/test_numarray.py --- a/pypy/module/micronumpy/test/test_numarray.py +++ b/pypy/module/micronumpy/test/test_numarray.py @@ -1769,6 +1769,12 @@ b = array(a, dtype='d') assert a.dtype is b.dtype + def test_notequal_different_shapes(self): + from _numpypy import array + a = array([1, 2]) + b = array([1, 2, 3, 4]) + assert (a == b) == False + class AppTestMultiDim(BaseNumpyAppTest): def test_init(self): diff --git a/pypy/module/struct/formatiterator.py b/pypy/module/struct/formatiterator.py --- a/pypy/module/struct/formatiterator.py +++ b/pypy/module/struct/formatiterator.py @@ -84,11 +84,10 @@ def _maybe_float(self, w_obj): space = self.space if space.is_true(space.isinstance(w_obj, space.w_float)): - space.warn("struct: integer argument expected, got float", - space.w_DeprecationWarning) + msg = "struct: integer argument expected, got float" else: - space.warn("integer argument expected, got non-integer", - space.w_DeprecationWarning) + msg = "integer argument expected, got non-integer" + space.warn(space.wrap(msg), space.w_DeprecationWarning) return space.int(w_obj) # wrapped float -> wrapped int or long else: diff --git a/pypy/module/test_lib_pypy/test_datetime.py b/pypy/module/test_lib_pypy/test_datetime.py --- a/pypy/module/test_lib_pypy/test_datetime.py +++ b/pypy/module/test_lib_pypy/test_datetime.py @@ -9,6 +9,26 @@ expected = "datetime.datetime(1, 2, 3, 0, 0)" assert repr(datetime.datetime(1,2,3)) == expected +def test_attributes(): + a = datetime.date.today() + raises(AttributeError, 'a.abc = 1') + a = datetime.time() + raises(AttributeError, 'a.abc = 1') + a = datetime.tzinfo() + raises(AttributeError, 'a.abc = 1') + a = datetime.datetime.utcnow() + raises(AttributeError, 'a.abc = 1') + a = datetime.timedelta() + raises(AttributeError, 'a.abc = 1') + +def test_unpickle(): + e = raises(TypeError, datetime.date, '123') + assert e.value.args[0] == 'an integer is required' + e = raises(TypeError, datetime.time, '123') + assert e.value.args[0] == 'an integer is required' + e = raises(TypeError, datetime.datetime, '123') + assert e.value.args[0] == 'an integer is required' + def test_strptime(): import time, sys if sys.version_info < (2, 6): diff --git a/pypy/objspace/descroperation.py b/pypy/objspace/descroperation.py --- a/pypy/objspace/descroperation.py +++ b/pypy/objspace/descroperation.py @@ -7,6 +7,7 @@ from rpython.tool.sourcetools import compile2, func_with_new_name from pypy.module.__builtin__.interp_classobj import W_InstanceObject from rpython.rlib.objectmodel import specialize +from rpython.rlib import jit def object_getattribute(space): "Utility that returns the app-level descriptor object.__getattribute__." @@ -118,6 +119,9 @@ def descr__init__(space, w_obj, __args__): pass +contains_jitdriver = jit.JitDriver(name='contains', + greens=['w_type'], reds='auto') + class DescrOperation(object): _mixin_ = True @@ -421,7 +425,9 @@ def _contains(space, w_container, w_item): w_iter = space.iter(w_container) + w_type = space.type(w_iter) while 1: + contains_jitdriver.jit_merge_point(w_type=w_type) try: w_next = space.next(w_iter) except OperationError, e: diff --git a/pypy/objspace/std/complexobject.py b/pypy/objspace/std/complexobject.py --- a/pypy/objspace/std/complexobject.py +++ b/pypy/objspace/std/complexobject.py @@ -80,10 +80,8 @@ return W_ComplexObject(rr, ir) def divmod(self, space, other): - space.warn( - "complex divmod(), // and % are deprecated", - space.w_DeprecationWarning - ) + space.warn(space.wrap("complex divmod(), // and % are deprecated"), + space.w_DeprecationWarning) w_div = self.div(other) div = math.floor(w_div.realval) w_mod = self.sub( diff --git a/pypy/objspace/std/floatobject.py b/pypy/objspace/std/floatobject.py --- a/pypy/objspace/std/floatobject.py +++ b/pypy/objspace/std/floatobject.py @@ -10,7 +10,7 @@ from rpython.rlib.rarithmetic import ovfcheck_float_to_int, intmask, LONG_BIT from rpython.rlib.rfloat import ( isinf, isnan, isfinite, INFINITY, NAN, copysign, formatd, - DTSF_ADD_DOT_0, DTSF_STR_PRECISION) + DTSF_ADD_DOT_0, DTSF_STR_PRECISION, float_as_rbigint_ratio) from rpython.rlib.rbigint import rbigint from rpython.rlib import rfloat from rpython.tool.sourcetools import func_with_new_name @@ -553,27 +553,18 @@ def float_as_integer_ratio__Float(space, w_float): value = w_float.floatval - if isinf(value): + try: + num, den = float_as_rbigint_ratio(value) + except OverflowError: w_msg = space.wrap("cannot pass infinity to as_integer_ratio()") raise OperationError(space.w_OverflowError, w_msg) - elif isnan(value): + except ValueError: w_msg = space.wrap("cannot pass nan to as_integer_ratio()") raise OperationError(space.w_ValueError, w_msg) - float_part, exp = math.frexp(value) - for i in range(300): - if float_part == math.floor(float_part): - break - float_part *= 2.0 - exp -= 1 - w_num = W_LongObject.fromfloat(space, float_part) - w_den = space.newlong(1) - w_exp = space.newlong(abs(exp)) - w_exp = space.lshift(w_den, w_exp) - if exp > 0: - w_num = space.mul(w_num, w_exp) - else: - w_den = w_exp - # Try to return int. + + w_num = space.newlong_from_rbigint(num) + w_den = space.newlong_from_rbigint(den) + # Try to return int return space.newtuple([space.int(w_num), space.int(w_den)]) def float_is_integer__Float(space, w_float): diff --git a/pypy/objspace/std/objecttype.py b/pypy/objspace/std/objecttype.py --- a/pypy/objspace/std/objecttype.py +++ b/pypy/objspace/std/objecttype.py @@ -126,11 +126,8 @@ msg = "format_spec must be a string" raise OperationError(space.w_TypeError, space.wrap(msg)) if space.len_w(w_format_spec) > 0: - space.warn( - ("object.__format__ with a non-empty format string is " - "deprecated"), - space.w_PendingDeprecationWarning - ) + msg = "object.__format__ with a non-empty format string is deprecated" + space.warn(space.wrap(msg), space.w_PendingDeprecationWarning) return space.format(w_as_str, w_format_spec) def descr___subclasshook__(space, __args__): diff --git a/pypy/objspace/std/typeobject.py b/pypy/objspace/std/typeobject.py --- a/pypy/objspace/std/typeobject.py +++ b/pypy/objspace/std/typeobject.py @@ -295,8 +295,9 @@ msg = "can't set attributes on type object '%s'" raise operationerrfmt(space.w_TypeError, msg, w_self.name) if name == "__del__" and name not in w_self.dict_w: - msg = "a __del__ method added to an existing type will not be called" - space.warn(msg, space.w_RuntimeWarning) + msg = ("a __del__ method added to an existing type will not be " + "called") + space.warn(space.wrap(msg), space.w_RuntimeWarning) if space.config.objspace.std.withtypeversion: version_tag = w_self.version_tag() if version_tag is not None: diff --git a/pypy/objspace/std/unicodeobject.py b/pypy/objspace/std/unicodeobject.py --- a/pypy/objspace/std/unicodeobject.py +++ b/pypy/objspace/std/unicodeobject.py @@ -119,13 +119,10 @@ w_uni2 = uni_from_str(space, w_str) except OperationError, e: if e.match(space, space.w_UnicodeDecodeError): - if inverse: - msg = "Unicode unequal comparison failed to convert both " \ - "arguments to Unicode - interpreting them as being unequal" - else : - msg = "Unicode equal comparison failed to convert both " \ - "arguments to Unicode - interpreting them as being unequal" - space.warn(msg, space.w_UnicodeWarning) + msg = ("Unicode %s comparison failed to convert both arguments to " + "Unicode - interpreting them as being unequal" % + "unequal" if inverse else "equal") + space.warn(space.wrap(msg), space.w_UnicodeWarning) return space.newbool(inverse) raise result = space.eq(w_uni, w_uni2) diff --git a/rpython/bin/translatorshell.py b/rpython/bin/translatorshell.py --- a/rpython/bin/translatorshell.py +++ b/rpython/bin/translatorshell.py @@ -15,9 +15,10 @@ t.view() # graph + annotations under the mouse t.rtype() # use low level operations - f = t.compile_c() # C compilation + lib = t.compile_c() # C compilation as a library + f = get_c_function(lib, func) # get the function out of the library assert f(arg) == func(arg) # sanity check (for C) - + Some functions are provided for the benefit of interactive testing. Try dir(snippet) for list of current snippets. @@ -31,6 +32,13 @@ import py + +def get_c_function(lib, f): + from ctypes import CDLL + name = f.__name__ + return getattr(CDLL(lib.strpath), 'pypy_g_' + name) + + def setup_readline(): import readline try: diff --git a/rpython/jit/backend/x86/test/test_zrpy_releasegil.py b/rpython/jit/backend/x86/test/test_zrpy_releasegil.py --- a/rpython/jit/backend/x86/test/test_zrpy_releasegil.py +++ b/rpython/jit/backend/x86/test/test_zrpy_releasegil.py @@ -1,18 +1,99 @@ from rpython.rtyper.lltypesystem import lltype, llmemory, rffi from rpython.rlib.jit import dont_look_inside +from rpython.rlib.objectmodel import invoke_around_extcall from rpython.jit.metainterp.optimizeopt import ALL_OPTS_NAMES -from rpython.rlib.libffi import CDLL, types, ArgChain, clibffi -from rpython.rtyper.lltypesystem.ll2ctypes import libc_name from rpython.rtyper.annlowlevel import llhelper from rpython.jit.backend.x86.test.test_zrpy_gc import BaseFrameworkTests from rpython.jit.backend.x86.test.test_zrpy_gc import check +from rpython.tool.udir import udir class ReleaseGILTests(BaseFrameworkTests): compile_kwds = dict(enable_opts=ALL_OPTS_NAMES, thread=True) + def define_simple(self): + class Glob: + def __init__(self): + self.event = 0 + glob = Glob() + # + + c_strchr = rffi.llexternal('strchr', [rffi.CCHARP, lltype.Signed], + rffi.CCHARP) + + def func(): + glob.event += 1 + + def before(n, x): + invoke_around_extcall(func, func) + return (n, None, None, None, None, None, + None, None, None, None, None, None) + # + def f(n, x, *args): + a = rffi.str2charp(str(n)) + c_strchr(a, ord('0')) + lltype.free(a, flavor='raw') + n -= 1 + return (n, x) + args + return before, f, None + + def test_simple(self): + self.run('simple') + assert 'call_release_gil' in udir.join('TestCompileFramework.log').read() + + def define_close_stack(self): + # + class Glob(object): + pass + glob = Glob() + class X(object): + pass + # + def callback(p1, p2): + for i in range(100): + glob.lst.append(X()) + return rffi.cast(rffi.INT, 1) + CALLBACK = lltype.Ptr(lltype.FuncType([lltype.Signed, + lltype.Signed], rffi.INT)) + # + @dont_look_inside + def alloc1(): + return llmemory.raw_malloc(16) + @dont_look_inside + def free1(p): + llmemory.raw_free(p) + + c_qsort = rffi.llexternal('qsort', [rffi.VOIDP, rffi.SIZE_T, + rffi.SIZE_T, CALLBACK], lltype.Void) + # + def f42(): + length = len(glob.lst) + raw = alloc1() + fn = llhelper(CALLBACK, rffi._make_wrapper_for(CALLBACK, callback)) + c_qsort(rffi.cast(rffi.VOIDP, raw), rffi.cast(rffi.SIZE_T, 2), + rffi.cast(rffi.SIZE_T, 8), fn) + free1(raw) + check(len(glob.lst) > length) + del glob.lst[:] + # + def before(n, x): + glob.lst = [] + + return (n, None, None, None, None, None, + None, None, None, None, None, None) + # + def f(n, x, *args): + f42() + n -= 1 + return (n, x) + args + return before, f, None + + def test_close_stack(self): + self.run('close_stack') + assert 'call_release_gil' in udir.join('TestCompileFramework.log').read() + class TestShadowStack(ReleaseGILTests): gcrootfinder = "shadowstack" diff --git a/rpython/rlib/rfloat.py b/rpython/rlib/rfloat.py --- a/rpython/rlib/rfloat.py +++ b/rpython/rlib/rfloat.py @@ -419,3 +419,25 @@ def isfinite(x): "NOT_RPYTHON" return not isinf(x) and not isnan(x) + +def float_as_rbigint_ratio(value): + from rpython.rlib.rbigint import rbigint + + if isinf(value): + raise OverflowError("cannot pass infinity to as_integer_ratio()") + elif isnan(value): + raise ValueError("cannot pass nan to as_integer_ratio()") + float_part, exp_int = math.frexp(value) + for i in range(300): + if float_part == math.floor(float_part): + break + float_part *= 2.0 + exp_int -= 1 + num = rbigint.fromfloat(float_part) + den = rbigint.fromint(1) + exp = den.lshift(abs(exp_int)) + if exp_int > 0: + num = num.mul(exp) + else: + den = exp + return num, den diff --git a/rpython/rlib/test/test_rarithmetic.py b/rpython/rlib/test/test_rarithmetic.py --- a/rpython/rlib/test/test_rarithmetic.py +++ b/rpython/rlib/test/test_rarithmetic.py @@ -395,16 +395,18 @@ assert not int_between(1, 1, 1) # these can't be prebuilt on 32bit -L1 = 0x0102030405060708L -L2 = 0x0807060504030201L +U1 = r_ulonglong(0x0102030405060708L) +U2 = r_ulonglong(0x0807060504030201L) +S1 = r_longlong(0x0102030405060708L) +S2 = r_longlong(0x0807060504030201L) def test_byteswap(): from rpython.rtyper.lltypesystem import rffi, lltype assert rffi.cast(lltype.Signed, byteswap(rffi.cast(rffi.USHORT, 0x0102))) == 0x0201 assert rffi.cast(lltype.Signed, byteswap(rffi.cast(rffi.INT, 0x01020304))) == 0x04030201 - assert byteswap(rffi.cast(rffi.LONGLONG, L1)) == L2 - assert byteswap(rffi.cast(rffi.ULONGLONG, L1)) == L2 + assert byteswap(U1) == U2 + assert byteswap(S1) == S2 assert ((byteswap(2.3) - 1.903598566252326e+185) / 1e185) < 0.000001 assert (rffi.cast(lltype.Float, byteswap(rffi.cast(lltype.SingleFloat, 2.3))) - 4.173496037651603e-08) < 1e-16 diff --git a/rpython/rlib/test/test_rfloat.py b/rpython/rlib/test/test_rfloat.py new file mode 100644 --- /dev/null +++ b/rpython/rlib/test/test_rfloat.py @@ -0,0 +1,131 @@ +import sys, py + +from rpython.rlib.rfloat import float_as_rbigint_ratio +from rpython.rlib.rfloat import break_up_float +from rpython.rlib.rfloat import copysign +from rpython.rlib.rfloat import round_away +from rpython.rlib.rfloat import round_double +from rpython.rlib.rbigint import rbigint + +def test_copysign(): + assert copysign(1, 1) == 1 + assert copysign(-1, 1) == 1 + assert copysign(-1, -1) == -1 + assert copysign(1, -1) == -1 + assert copysign(1, -0.) == -1 + +def test_round_away(): + assert round_away(.1) == 0. + assert round_away(.5) == 1. + assert round_away(.7) == 1. + assert round_away(1.) == 1. + assert round_away(-.5) == -1. + assert round_away(-.1) == 0. + assert round_away(-.7) == -1. + assert round_away(0.) == 0. + +def test_round_double(): + def almost_equal(x, y): + assert round(abs(x-y), 7) == 0 + + almost_equal(round_double(0.125, 2), 0.13) + almost_equal(round_double(0.375, 2), 0.38) + almost_equal(round_double(0.625, 2), 0.63) + almost_equal(round_double(0.875, 2), 0.88) + almost_equal(round_double(-0.125, 2), -0.13) + almost_equal(round_double(-0.375, 2), -0.38) + almost_equal(round_double(-0.625, 2), -0.63) + almost_equal(round_double(-0.875, 2), -0.88) + + almost_equal(round_double(0.25, 1), 0.3) + almost_equal(round_double(0.75, 1), 0.8) + almost_equal(round_double(-0.25, 1), -0.3) + almost_equal(round_double(-0.75, 1), -0.8) + + round_double(-6.5, 0) == -7.0 + round_double(-5.5, 0) == -6.0 + round_double(-1.5, 0) == -2.0 + round_double(-0.5, 0) == -1.0 + round_double(0.5, 0) == 1.0 + round_double(1.5, 0) == 2.0 + round_double(2.5, 0) == 3.0 + round_double(3.5, 0) == 4.0 + round_double(4.5, 0) == 5.0 + round_double(5.5, 0) == 6.0 + round_double(6.5, 0) == 7.0 + + round_double(-25.0, -1) == -30.0 + round_double(-15.0, -1) == -20.0 + round_double(-5.0, -1) == -10.0 + round_double(5.0, -1) == 10.0 + round_double(15.0, -1) == 20.0 + round_double(25.0, -1) == 30.0 + round_double(35.0, -1) == 40.0 + round_double(45.0, -1) == 50.0 + round_double(55.0, -1) == 60.0 + round_double(65.0, -1) == 70.0 + round_double(75.0, -1) == 80.0 + round_double(85.0, -1) == 90.0 + round_double(95.0, -1) == 100.0 + round_double(12325.0, -1) == 12330.0 + + round_double(350.0, -2) == 400.0 + round_double(450.0, -2) == 500.0 + + almost_equal(round_double(0.5e21, -21), 1e21) + almost_equal(round_double(1.5e21, -21), 2e21) + almost_equal(round_double(2.5e21, -21), 3e21) + almost_equal(round_double(5.5e21, -21), 6e21) + almost_equal(round_double(8.5e21, -21), 9e21) + + almost_equal(round_double(-1.5e22, -22), -2e22) + almost_equal(round_double(-0.5e22, -22), -1e22) + almost_equal(round_double(0.5e22, -22), 1e22) + almost_equal(round_double(1.5e22, -22), 2e22) + +def test_round_half_even(): + from rpython.rlib import rfloat + for func in (rfloat.round_double_short_repr, + rfloat.round_double_fallback_repr): + # 2.x behavior + assert func(2.5, 0, False) == 3.0 + # 3.x behavior + assert func(2.5, 0, True) == 2.0 + +def test_break_up_float(): + assert break_up_float('1') == ('', '1', '', '') + assert break_up_float('+1') == ('+', '1', '', '') + assert break_up_float('-1') == ('-', '1', '', '') + + assert break_up_float('.5') == ('', '', '5', '') + + assert break_up_float('1.2e3') == ('', '1', '2', '3') + assert break_up_float('1.2e+3') == ('', '1', '2', '+3') + assert break_up_float('1.2e-3') == ('', '1', '2', '-3') + + # some that will get thrown out on return: + assert break_up_float('.') == ('', '', '', '') + assert break_up_float('+') == ('+', '', '', '') + assert break_up_float('-') == ('-', '', '', '') + assert break_up_float('e1') == ('', '', '', '1') + + py.test.raises(ValueError, break_up_float, 'e') + + +def test_float_as_rbigint_ratio(): + for f, ratio in [ + (0.875, (7, 8)), + (-0.875, (-7, 8)), + (0.0, (0, 1)), + (11.5, (23, 2)), + ]: + num, den = float_as_rbigint_ratio(f) + assert num.eq(rbigint.fromint(ratio[0])) + assert den.eq(rbigint.fromint(ratio[1])) + + with py.test.raises(OverflowError): + float_as_rbigint_ratio(float('inf')) + with py.test.raises(OverflowError): + float_as_rbigint_ratio(float('-inf')) + with py.test.raises(ValueError): + float_as_rbigint_ratio(float('nan')) diff --git a/rpython/rlib/test/test_timer.py b/rpython/rlib/test/test_timer.py deleted file mode 100644 --- a/rpython/rlib/test/test_timer.py +++ /dev/null @@ -1,26 +0,0 @@ -from rpython.rlib.timer import Timer -from rpython.translator.c.test.test_genc import compile -from rpython.annotator.policy import AnnotatorPolicy - - -t = Timer() -t.start("testc") -t.stop("testc") - -def timer_user(): - assert "testc" not in t.timingorder - t.start("testa") - t.stop("testa") - t.start("testb") - t.start("testb") - t.stop("testb") - t.stop("testb") - t.start_name("test", "one") - t.stop_name("test", "one") - t.dump() - - -def test_compile_timer(): - policy = AnnotatorPolicy() - f_compiled = compile(timer_user, [], annotatorpolicy=policy) - f_compiled() diff --git a/rpython/rlib/timer.py b/rpython/rlib/timer.py deleted file mode 100644 --- a/rpython/rlib/timer.py +++ /dev/null @@ -1,77 +0,0 @@ -import time -import os - - -def _create_name(name, generation): - if generation == 0: - return name - else: - return "%s[%s]" % (name, str(generation)) - - -class Timer: - def __init__(self): - self.reset() - - def reset(self): - self.timings = {} - self.levels = {} - self.timingorder = [] - - def _cleanup_(self): - self.reset() - - def start(self, timer): - level = self.levels.setdefault(timer, -1) - new_level = level + 1 - name = _create_name(timer, new_level) - if name not in self.timings: - self.timingorder.append(name) - self.timings[name] = time.time() - self.timings.get(name, 0) - self.levels[timer] = new_level - - def start_name(self, timerone, timertwo): - self.start(timerone + " " + timertwo) - - def stop(self, timer): - level = self.levels.setdefault(timer, -1) - if level == -1: - raise ValueError("Invalid timer name") - if level >= 0: # timer is active - name = _create_name(timer, level) - self.timings[name] = time.time() - self.timings[name] - self.levels[timer] = level - 1 - - def stop_name(self, timerone, timertwo): - self.stop(timerone + " " + timertwo) - - def value(self, timer): - level = self.levels.get(timer, -1) - if level == -1: - result = "%fs" % self.timings[timer] - else: - result = "%fs (still running)" % (time.time() - self.timings[timer]) - return result - - def dump(self): - outlist = [] - for timer in self.timingorder: - value = self.value(timer) - outlist.append("%s = %s" % (timer, value)) - os.write(2, "\n".join(outlist)) - - -class DummyTimer: - def start(self, timer): - pass - def start_name(self, timerone, timertwo): - pass - def stop(self, timer): - pass - def stop_name(self, timerone, timertwo): - pass - def value(self, timer): - return "Timing disabled" - def dump(self): - pass - diff --git a/rpython/rtyper/llinterp.py b/rpython/rtyper/llinterp.py --- a/rpython/rtyper/llinterp.py +++ b/rpython/rtyper/llinterp.py @@ -11,7 +11,8 @@ from rpython.rlib.objectmodel import (ComputedIntSymbolic, CDefinedIntSymbolic, Symbolic) # intmask is used in an exec'd code block -from rpython.rlib.rarithmetic import ovfcheck, is_valid_int, intmask +from rpython.rlib.rarithmetic import (ovfcheck, is_valid_int, intmask, + r_uint, r_longlong, r_ulonglong, r_longlonglong) from rpython.rtyper.lltypesystem import lltype, llmemory, lloperation, llheap, rclass from rpython.rtyper.ootypesystem import ootype diff --git a/rpython/rtyper/rint.py b/rpython/rtyper/rint.py --- a/rpython/rtyper/rint.py +++ b/rpython/rtyper/rint.py @@ -1,17 +1,16 @@ import sys -from rpython.tool.pairtype import pairtype + from rpython.annotator import model as annmodel from rpython.flowspace.operation import op_appendices -from rpython.rtyper.lltypesystem.lltype import Signed, Unsigned, Bool, Float, \ - Void, Char, UniChar, malloc, UnsignedLongLong, \ - SignedLongLong, build_number, Number, cast_primitive, typeOf, \ - SignedLongLongLong -from rpython.rtyper.rmodel import IntegerRepr, inputconst -from rpython.rlib.rarithmetic import intmask, r_int, r_uint, r_ulonglong, \ - r_longlong, is_emulated_long -from rpython.rtyper.error import TyperError, MissingRTypeOperation -from rpython.rtyper.rmodel import log from rpython.rlib import objectmodel +from rpython.rlib.rarithmetic import intmask, r_int, r_longlong +from rpython.rtyper.error import TyperError +from rpython.rtyper.lltypesystem.lltype import (Signed, Unsigned, Bool, Float, + Char, UniChar, UnsignedLongLong, SignedLongLong, build_number, Number, + cast_primitive, typeOf, SignedLongLongLong) +from rpython.rtyper.rmodel import IntegerRepr, inputconst, log +from rpython.tool.pairtype import pairtype + _integer_reprs = {} def getintegerrepr(lltype, prefix=None): @@ -128,7 +127,7 @@ #comparisons: eq is_ ne lt le gt ge - def rtype_eq(_, hop): + def rtype_eq(_, hop): return _rtype_compare_template(hop, 'eq') rtype_is_ = rtype_eq @@ -259,7 +258,7 @@ get_ll_le_function = get_ll_eq_function def get_ll_ge_function(self): - return None + return None def get_ll_hash_function(self): if (sys.maxint == 2147483647 and @@ -279,7 +278,7 @@ ll_dummy_value = -1 def rtype_chr(_, hop): - vlist = hop.inputargs(Signed) + vlist = hop.inputargs(Signed) if hop.has_implicit_exception(ValueError): hop.exception_is_here() hop.gendirectcall(ll_check_chr, vlist[0]) @@ -301,8 +300,8 @@ vlist = hop.inputargs(self) return hop.genop(self.opprefix + 'is_true', vlist, resulttype=Bool) - #Unary arithmetic operations - + #Unary arithmetic operations + def rtype_abs(self, hop): self = self.as_int vlist = hop.inputargs(self) @@ -325,7 +324,7 @@ self = self.as_int vlist = hop.inputargs(self) return hop.genop(self.opprefix + 'invert', vlist, resulttype=self) - + def rtype_neg(self, hop): self = self.as_int vlist = hop.inputargs(self) diff --git a/rpython/rtyper/rmodel.py b/rpython/rtyper/rmodel.py --- a/rpython/rtyper/rmodel.py +++ b/rpython/rtyper/rmodel.py @@ -1,20 +1,18 @@ +from rpython.annotator import model as annmodel, unaryop, binaryop, description +from rpython.flowspace.model import Constant +from rpython.rtyper.error import TyperError, MissingRTypeOperation +from rpython.rtyper.lltypesystem import lltype +from rpython.rtyper.lltypesystem.lltype import (Void, Bool, Float, typeOf, + LowLevelType, isCompatibleType) from rpython.tool.pairtype import pairtype, extendabletype, pair -from rpython.annotator import model as annmodel, unaryop, binaryop -from rpython.annotator import description -from rpython.flowspace.model import Constant -from rpython.rtyper.lltypesystem.lltype import \ - Void, Bool, Float, Signed, Char, UniChar, \ - typeOf, LowLevelType, Ptr, isCompatibleType -from rpython.rtyper.lltypesystem import lltype, llmemory -from rpython.rtyper.ootypesystem import ootype -from rpython.rtyper.error import TyperError, MissingRTypeOperation -# initialization states for Repr instances -class setupstate(object): - NOTINITIALIZED = 0 +# initialization states for Repr instances + +class setupstate(object): + NOTINITIALIZED = 0 INPROGRESS = 1 - BROKEN = 2 + BROKEN = 2 FINISHED = 3 DELAYED = 4 @@ -27,7 +25,7 @@ iterating over. """ __metaclass__ = extendabletype - _initialized = setupstate.NOTINITIALIZED + _initialized = setupstate.NOTINITIALIZED def __repr__(self): return '<%s %s>' % (self.__class__.__name__, self.lowleveltype) @@ -35,31 +33,31 @@ def compact_repr(self): return '%s %s' % (self.__class__.__name__.replace('Repr','R'), self.lowleveltype._short_name()) - def setup(self): + def setup(self): """ call _setup_repr() and keep track of the initializiation status to e.g. detect recursive _setup_repr invocations. - the '_initialized' attr has four states: + the '_initialized' attr has four states: """ - if self._initialized == setupstate.FINISHED: - return - elif self._initialized == setupstate.BROKEN: + if self._initialized == setupstate.FINISHED: + return + elif self._initialized == setupstate.BROKEN: raise BrokenReprTyperError( "cannot setup already failed Repr: %r" %(self,)) - elif self._initialized == setupstate.INPROGRESS: + elif self._initialized == setupstate.INPROGRESS: raise AssertionError( "recursive invocation of Repr setup(): %r" %(self,)) elif self._initialized == setupstate.DELAYED: raise AssertionError( "Repr setup() is delayed and cannot be called yet: %r" %(self,)) - assert self._initialized == setupstate.NOTINITIALIZED - self._initialized = setupstate.INPROGRESS - try: - self._setup_repr() - except TyperError, e: - self._initialized = setupstate.BROKEN - raise - else: - self._initialized = setupstate.FINISHED + assert self._initialized == setupstate.NOTINITIALIZED + self._initialized = setupstate.INPROGRESS + try: + self._setup_repr() + except TyperError, e: + self._initialized = setupstate.BROKEN + raise + else: + self._initialized = setupstate.FINISHED def _setup_repr(self): "For recursive data structure, which must be initialized in two steps." @@ -68,15 +66,15 @@ """Same as setup(), called a bit later, for effects that are only needed after the typer finished (as opposed to needed for other parts of the typer itself).""" - if self._initialized == setupstate.BROKEN: + if self._initialized == setupstate.BROKEN: raise BrokenReprTyperError("cannot perform setup_final_touch " "on failed Repr: %r" %(self,)) assert self._initialized == setupstate.FINISHED, ( "setup_final() on repr with state %s: %r" % (self._initialized, self)) - self._setup_repr_final() + self._setup_repr_final() - def _setup_repr_final(self): + def _setup_repr_final(self): pass def is_setup_delayed(self): @@ -98,8 +96,8 @@ def __getattr__(self, name): # Assume that when an attribute is missing, it's because setup() needs # to be called - if not (name[:2] == '__' == name[-2:]): - if self._initialized == setupstate.NOTINITIALIZED: + if not (name[:2] == '__' == name[-2:]): + if self._initialized == setupstate.NOTINITIALIZED: self.setup() try: return self.__dict__[name] @@ -119,7 +117,7 @@ else: raise TyperError("convert_desc_or_const expects a Desc" "or Constant: %r" % desc_or_const) - + def convert_const(self, value): "Convert the given constant value to the low-level repr of 'self'." if self.lowleveltype is not Void: @@ -137,12 +135,12 @@ values of this Repr. This can return None to mean that simply using '==' is fine. """ - raise TyperError, 'no equality function for %r' % self + raise TyperError('no equality function for %r' % self) def get_ll_hash_function(self): """Return a hash(x) function for low-level values of this Repr. """ - raise TyperError, 'no hashing function for %r' % self + raise TyperError('no hashing function for %r' % self) def get_ll_fasthash_function(self): """Return a 'fast' hash(x) function for low-level values of this @@ -272,12 +270,15 @@ r_baseiter = r_container.make_iterator_repr() return EnumerateIteratorRepr(r_baseiter) return r_container.make_iterator_repr(*self.variant) + def rtyper_makekey_ex(self, rtyper): return self.__class__, rtyper.makekey(self.s_container), self.variant + class __extend__(annmodel.SomeImpossibleValue): def rtyper_makerepr(self, rtyper): return impossible_repr + def rtyper_makekey(self): return self.__class__, @@ -285,14 +286,14 @@ class __extend__(pairtype(Repr, Repr)): - + def rtype_is_((robj1, robj2), hop): if hop.s_result.is_constant(): return inputconst(Bool, hop.s_result.const) return hop.rtyper.type_system.generic_is(robj1, robj2, hop) # default implementation for checked getitems - + def rtype_getitem_idx_key((r_c1, r_o1), hop): return pair(r_c1, r_o1).rtype_getitem(hop) @@ -343,7 +344,7 @@ return self._opprefix opprefix = property(_get_opprefix) - + class BoolRepr(IntegerRepr): lowleveltype = Bool # NB. no 'opprefix' here. Use 'as_int' systematically. @@ -411,9 +412,9 @@ c.concretetype = lltype return c -class BrokenReprTyperError(TyperError): - """ raised when trying to setup a Repr whose setup - has failed already. +class BrokenReprTyperError(TyperError): + """ raised when trying to setup a Repr whose setup + has failed already. """ def mangle(prefix, name): @@ -489,6 +490,3 @@ def warning(msg): log.WARNING(msg) - - - diff --git a/rpython/rtyper/rpbc.py b/rpython/rtyper/rpbc.py --- a/rpython/rtyper/rpbc.py +++ b/rpython/rtyper/rpbc.py @@ -1,18 +1,15 @@ import types -import sys + +from rpython.annotator import model as annmodel, description +from rpython.flowspace.model import Constant +from rpython.rtyper import rclass, callparse +from rpython.rtyper.annlowlevel import llstr +from rpython.rtyper.error import TyperError +from rpython.rtyper.lltypesystem.lltype import typeOf, Void, Bool +from rpython.rtyper.rmodel import (Repr, inputconst, CanBeNull, mangle, + inputdesc, warning, impossible_repr) from rpython.tool.pairtype import pair, pairtype -from rpython.annotator import model as annmodel -from rpython.annotator import description -from rpython.flowspace.model import Constant -from rpython.rtyper.lltypesystem.lltype import \ - typeOf, Void, Bool, nullptr, frozendict, Ptr, Struct, malloc -from rpython.rtyper.error import TyperError -from rpython.rtyper.rmodel import Repr, inputconst, CanBeNull, \ - mangle, inputdesc, warning, impossible_repr -from rpython.rtyper import rclass -from rpython.rtyper.annlowlevel import llstr, llunicode -from rpython.rtyper import callparse def small_cand(rtyper, s_pbc): if 1 < len(s_pbc.descriptions) < rtyper.getconfig().translation.withsmallfuncsets and \ @@ -26,7 +23,7 @@ class __extend__(annmodel.SomePBC): def rtyper_makerepr(self, rtyper): if self.isNone(): - return none_frozen_pbc_repr + return none_frozen_pbc_repr kind = self.getKind() if issubclass(kind, description.FunctionDesc): sample = self.any_description() @@ -50,7 +47,7 @@ elif issubclass(kind, description.MethodOfFrozenDesc): getRepr = rtyper.type_system.rpbc.MethodOfFrozenPBCRepr else: - raise TyperError("unexpected PBC kind %r"%(kind,)) + raise TyperError("unexpected PBC kind %r" % (kind,)) return getRepr(rtyper, self) @@ -82,7 +79,7 @@ """ concretetable = {} # (shape,index): row, maybe with duplicates uniquerows = [] # list of rows, without duplicates - + def lookuprow(row): # a 'matching' row is one that has the same llfn, expect # that it may have more or less 'holes' @@ -333,15 +330,15 @@ return hop.llops.convertvar(v, rresult, hop.r_result) class __extend__(pairtype(AbstractFunctionsPBCRepr, AbstractFunctionsPBCRepr)): - def convert_from_to((r_fpbc1, r_fpbc2), v, llops): - # this check makes sense because both source and dest repr are FunctionsPBCRepr - if r_fpbc1.lowleveltype == r_fpbc2.lowleveltype: - return v - if r_fpbc1.lowleveltype is Void: - return inputconst(r_fpbc2, r_fpbc1.s_pbc.const) - if r_fpbc2.lowleveltype is Void: - return inputconst(Void, None) - return NotImplemented + def convert_from_to((r_fpbc1, r_fpbc2), v, llops): + # this check makes sense because both source and dest repr are FunctionsPBCRepr + if r_fpbc1.lowleveltype == r_fpbc2.lowleveltype: + return v + if r_fpbc1.lowleveltype is Void: + return inputconst(r_fpbc2, r_fpbc1.s_pbc.const) + if r_fpbc2.lowleveltype is Void: + return inputconst(Void, None) + return NotImplemented class OverriddenFunctionPBCRepr(Repr): def __init__(self, rtyper, s_pbc): @@ -377,7 +374,7 @@ result = rtyper.type_system.rpbc.MultipleFrozenPBCRepr(rtyper, access) rtyper.pbc_reprs[access] = result - rtyper.add_pendingsetup(result) + rtyper.add_pendingsetup(result) return result @@ -429,7 +426,7 @@ def convert_const(self, pbc): if pbc is None: - return self.null_instance() + return self.null_instance() if isinstance(pbc, types.MethodType) and pbc.im_self is None: value = pbc.im_func # unbound method -> bare function frozendesc = self.rtyper.annotator.bookkeeper.getdesc(pbc) @@ -455,7 +452,7 @@ mangled_name = mangle('pbc', attr) fields.append((mangled_name, r_value.lowleveltype)) self.fieldmap[attr] = mangled_name, r_value - return fields + return fields def convert_desc(self, frozendesc): if (self.access_set is not None and @@ -525,7 +522,7 @@ # XXX sort this out #call_families = rtyper.annotator.getpbccallfamilies() #call_families.find((None, self.function)) - + if s_pbc.can_be_none(): raise TyperError("unsupported: variable of type " "method-of-frozen-PBC or None") @@ -534,7 +531,7 @@ for desc in s_pbc.descriptions: assert desc.funcdesc is self.funcdesc im_selves.append(desc.frozendesc) - + self.s_im_self = annmodel.SomePBC(im_selves) self.r_im_self = rtyper.getrepr(self.s_im_self) self.lowleveltype = self.r_im_self.lowleveltype @@ -548,7 +545,7 @@ def convert_desc(self, mdesc): if mdesc.funcdesc is not self.funcdesc: - raise TyperError("not a method bound on %r: %r" % (self.funcdesc, + raise TyperError("not a method bound on %r: %r" % (self.funcdesc, mdesc)) return self.r_im_self.convert_desc(mdesc.frozendesc) @@ -615,7 +612,7 @@ def convert_from_to((r_from, _), v, llops): return inputconst(Void, None) - + def rtype_is_((robj1, rnone2), hop): if hop.s_result.is_constant(): return hop.inputconst(Bool, hop.s_result.const) @@ -666,7 +663,7 @@ def convert_desc(self, desc): if desc not in self.s_pbc.descriptions: - raise TyperError("%r not in %r" % (cls, self)) + raise TyperError("%r not in %r" % (desc, self)) if self.lowleveltype is Void: return None subclassdef = desc.getuniqueclassdef() @@ -726,7 +723,7 @@ s_init = classdef.classdesc.s_read_attribute('__init__') v_init = Constant("init-func-dummy") # this value not really used - if (isinstance(s_init, annmodel.SomeImpossibleValue) and + if (isinstance(s_init, annmodel.SomeImpossibleValue) and classdef.classdesc.is_exception_class() and classdef.has_no_attrs()): # special case for instanciating simple built-in @@ -753,7 +750,7 @@ else: s_init = access_set.s_value v_init = r_class.getpbcfield(vtypeptr, access_set, '__init__', - hop.llops) + hop.llops) v_instance = self._instantiate_runtime_class(hop, vtypeptr, r_instance) if isinstance(s_init, annmodel.SomeImpossibleValue): @@ -771,7 +768,6 @@ return v_instance - class __extend__(pairtype(AbstractClassesPBCRepr, rclass.AbstractClassRepr)): def convert_from_to((r_clspbc, r_cls), v, llops): # turn a PBC of classes to a standard pointer-to-vtable class repr @@ -904,4 +900,3 @@ for cdef1 in classdef.getmro(): for attrname in cdef1.attrs: yield cdef1, attrname - diff --git a/rpython/rtyper/rptr.py b/rpython/rtyper/rptr.py --- a/rpython/rtyper/rptr.py +++ b/rpython/rtyper/rptr.py @@ -1,10 +1,10 @@ -from rpython.tool.pairtype import pairtype from rpython.annotator import model as annmodel from rpython.flowspace import model as flowmodel +from rpython.rlib.rarithmetic import r_uint +from rpython.rtyper.error import TyperError from rpython.rtyper.lltypesystem import lltype -from rpython.rtyper.error import TyperError from rpython.rtyper.rmodel import Repr, IntegerRepr -from rpython.rlib.rarithmetic import r_uint +from rpython.tool.pairtype import pairtype class __extend__(annmodel.SomePtr): @@ -23,6 +23,8 @@ def rtyper_makerepr(self, rtyper): return InteriorPtrRepr(self.ll_ptrtype) + def rtyper_makekey(self): + return self.__class__, self.ll_ptrtype class PtrRepr(Repr): @@ -345,4 +347,3 @@ if r_from.lowleveltype == r_to.lowleveltype: return v return NotImplemented - diff --git a/rpython/rtyper/rrange.py b/rpython/rtyper/rrange.py --- a/rpython/rtyper/rrange.py +++ b/rpython/rtyper/rrange.py @@ -1,9 +1,9 @@ -from rpython.tool.pairtype import pairtype +from rpython.flowspace.model import Constant from rpython.rtyper.error import TyperError from rpython.rtyper.lltypesystem.lltype import Signed, Void, Ptr +from rpython.rtyper.rlist import dum_nocheck, dum_checkidx from rpython.rtyper.rmodel import Repr, IntegerRepr, IteratorRepr -from rpython.flowspace.model import Constant -from rpython.rtyper.rlist import dum_nocheck, dum_checkidx +from rpython.tool.pairtype import pairtype class AbstractRangeRepr(Repr): @@ -54,9 +54,9 @@ def _ll_rangelen(start, stop, step): if step > 0: - result = (stop - start + (step-1)) // step + result = (stop - start + (step - 1)) // step else: - result = (start - stop - (step+1)) // (-step) + result = (start - stop - (step + 1)) // (-step) if result < 0: result = 0 return result diff --git a/rpython/rtyper/rstr.py b/rpython/rtyper/rstr.py --- a/rpython/rtyper/rstr.py +++ b/rpython/rtyper/rstr.py @@ -1,16 +1,15 @@ -from rpython.tool.staticmethods import StaticMethods +from rpython.annotator import model as annmodel +from rpython.rlib import jit +from rpython.rtyper import rint +from rpython.rtyper.error import TyperError +from rpython.rtyper.lltypesystem.lltype import (Signed, Bool, Void, UniChar, + typeOf) +from rpython.rtyper.rmodel import IntegerRepr, IteratorRepr, inputconst, Repr +from rpython.rtyper.rtuple import AbstractTupleRepr from rpython.tool.pairtype import pairtype, pair from rpython.tool.sourcetools import func_with_new_name -from rpython.annotator import model as annmodel -from rpython.rlib import jit -from rpython.rlib.nonconst import NonConstant -from rpython.rtyper.error import TyperError -from rpython.rtyper.rmodel import IntegerRepr, IteratorRepr -from rpython.rtyper.rmodel import inputconst, Repr -from rpython.rtyper.rtuple import AbstractTupleRepr -from rpython.rtyper import rint -from rpython.rtyper.lltypesystem.lltype import Signed, Bool, Void, UniChar,\ - cast_primitive, typeOf +from rpython.tool.staticmethods import StaticMethods + class AbstractStringRepr(Repr): @@ -37,7 +36,7 @@ def ll_raise_unicode_exception_decode(self, errors, encoding, msg, s, startingpos, endingpos): raise UnicodeDecodeError(encoding, s, startingpos, endingpos, msg) - + class AbstractCharRepr(AbstractStringRepr): def rtype_method_lower(self, hop): @@ -87,7 +86,7 @@ def ll_raise_unicode_exception_encode(self, errors, encoding, msg, u, startingpos, endingpos): raise UnicodeEncodeError(encoding, u, startingpos, endingpos, msg) - + class __extend__(annmodel.SomeString): def rtyper_makerepr(self, rtyper): return rtyper.type_system.rstr.string_repr From noreply at buildbot.pypy.org Thu Feb 21 14:51:22 2013 From: noreply at buildbot.pypy.org (fijal) Date: Thu, 21 Feb 2013 14:51:22 +0100 (CET) Subject: [pypy-commit] pypy default: update whatsnew Message-ID: <20130221135122.6A7391C0237@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r61541:7d20db5b18b5 Date: 2013-02-21 15:50 +0200 http://bitbucket.org/pypy/pypy/changeset/7d20db5b18b5/ Log: update whatsnew diff --git a/pypy/doc/tool/makeref.py b/pypy/doc/tool/makeref.py --- a/pypy/doc/tool/makeref.py +++ b/pypy/doc/tool/makeref.py @@ -3,8 +3,8 @@ py.path.local(__file__) import pypy pypydir = py.path.local(pypy.__file__).dirpath() -distdir = pypydir.dirpath() -issue_url = 'http://codespeak.net/issue/pypy-dev/' +distdir = pypydir.dirpath() +issue_url = 'http://bugs.pypy.org/issue/pypy-dev/' bitbucket_url = 'https://bitbucket.org/pypy/pypy/src/default/' import urllib2, posixpath diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst --- a/pypy/doc/whatsnew-head.rst +++ b/pypy/doc/whatsnew-head.rst @@ -65,3 +65,6 @@ .. branch: signal-and-thread Add "__pypy__.thread.signals_enabled", a context manager. Can be used in a non-main thread to enable the processing of signal handlers in that thread. + +.. branch: coding-guide-update-rlib-refs +.. branch: rlib-doc-rpython-refs From noreply at buildbot.pypy.org Thu Feb 21 14:52:59 2013 From: noreply at buildbot.pypy.org (fijal) Date: Thu, 21 Feb 2013 14:52:59 +0100 (CET) Subject: [pypy-commit] pypy default: fix urls? Message-ID: <20130221135259.E71391C0237@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r61542:516c661ff236 Date: 2013-02-21 15:52 +0200 http://bitbucket.org/pypy/pypy/changeset/516c661ff236/ Log: fix urls? diff --git a/pypy/doc/tool/makeref.py b/pypy/doc/tool/makeref.py --- a/pypy/doc/tool/makeref.py +++ b/pypy/doc/tool/makeref.py @@ -1,8 +1,7 @@ import py -py.path.local(__file__) import pypy -pypydir = py.path.local(pypy.__file__).dirpath() +pypydir = py.path.local(pypy.__file__).join('..', '..') distdir = pypydir.dirpath() issue_url = 'http://bugs.pypy.org/issue/pypy-dev/' bitbucket_url = 'https://bitbucket.org/pypy/pypy/src/default/' From noreply at buildbot.pypy.org Thu Feb 21 14:58:42 2013 From: noreply at buildbot.pypy.org (fijal) Date: Thu, 21 Feb 2013 14:58:42 +0100 (CET) Subject: [pypy-commit] pypy default: another attempt Message-ID: <20130221135842.222081C0237@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r61543:df826a8d4cfb Date: 2013-02-21 15:57 +0200 http://bitbucket.org/pypy/pypy/changeset/df826a8d4cfb/ Log: another attempt diff --git a/pypy/doc/index.rst b/pypy/doc/index.rst --- a/pypy/doc/index.rst +++ b/pypy/doc/index.rst @@ -296,7 +296,7 @@ modules (see `Testing in PyPy`_) ``_cache/`` holds cache files from internally `translating application level to interpreterlevel`_ code. -================================ =========================================== +================================ ============================================================================================ .. _`bytecode interpreter`: interpreter.html .. _`translating application level to interpreterlevel`: geninterp.html From noreply at buildbot.pypy.org Thu Feb 21 14:58:46 2013 From: noreply at buildbot.pypy.org (stepahn) Date: Thu, 21 Feb 2013 14:58:46 +0100 (CET) Subject: [pypy-commit] lang-js default: optimized declarative binding initialization Message-ID: <20130221135846.A8C961C0237@cobra.cs.uni-duesseldorf.de> Author: Stephan Branch: Changeset: r359:1e753170a6e1 Date: 2013-02-21 14:56 +0100 http://bitbucket.org/pypy/lang-js/changeset/1e753170a6e1/ Log: optimized declarative binding initialization diff --git a/js/astbuilder.py b/js/astbuilder.py --- a/js/astbuilder.py +++ b/js/astbuilder.py @@ -320,7 +320,8 @@ pos = self.get_pos(node) body = self.dispatch(node.children[0]) scope = self.current_scope() - return operations.Program(pos, body, scope) + final_scope = scope.finalize() + return operations.Program(pos, body, final_scope) def visit_variablestatement(self, node): pos = self.get_pos(node) @@ -362,6 +363,7 @@ funcname = u'' scope = self.current_scope() + final_scope = scope.finalize() self.exit_scope() @@ -371,7 +373,7 @@ #assert isinstance(f, unicode) funcindex = self.declare_symbol(f) - funcobj = operations.FunctionStatement(pos, funcname, funcindex, functionbody, scope) + funcobj = operations.FunctionStatement(pos, funcname, funcindex, functionbody, final_scope) if declaration: self.declare_function(funcname, funcobj) diff --git a/js/jscode.py b/js/jscode.py --- a/js/jscode.py +++ b/js/jscode.py @@ -28,7 +28,7 @@ pass from js.symbol_map import SymbolMap -empty_symbols = SymbolMap() +empty_symbols = SymbolMap().finalize() class JsCode(object): @@ -60,9 +60,8 @@ def symbols(self): return self._symbols.get_symbols() - @jit.unroll_safe def params(self): - return [p for p in self.parameters] + return self._symbols.parameters @jit.elidable def estimated_stack_size(self): diff --git a/js/symbol_map.py b/js/symbol_map.py --- a/js/symbol_map.py +++ b/js/symbol_map.py @@ -7,7 +7,6 @@ self.functions = [] self.variables = [] self.parameters = [] - self.next_index = 0 def add_symbol(self, identifyer): idx = self.symbols.lookup(identifyer) @@ -47,3 +46,25 @@ def len(self): return self.symbols.len() + + def finalize(self): + return FinalSymbolMap(self.symbols, self.functions, self.variables, self.parameters) + + +class FinalSymbolMap(object): + _immutable_fields_ = ['symbols', 'functions[*]', 'variables[*]', 'parameters[*]'] + + def __init__(self, symbols, functions, variables, parameters): + self.symbols = symbols + self.functions = functions[:] + self.variables = variables[:] + self.parameters = parameters[:] + + def get_index(self, identifyer): + return self.symbols.lookup(identifyer) + + def get_symbols(self): + return self.symbols.keys() + + def len(self): + return self.symbols.len() diff --git a/test/jit_view.py b/test/jit_view.py --- a/test/jit_view.py +++ b/test/jit_view.py @@ -126,6 +126,25 @@ code = """ (function () { var i = 0; + function g(b) { + return b + 1; + } + function f(a) { + return g(a); + } + while(i < 100) { + i = f(i); + } + return i; + })(); + """ + + self.run(code, 100) + + def test_double_nested_func_call_in_loop(self): + code = """ + (function () { + var i = 0; function f(a) { function g(b) { return b + 1; diff --git a/test/test_jsfunction.py b/test/test_jsfunction.py --- a/test/test_jsfunction.py +++ b/test/test_jsfunction.py @@ -47,10 +47,9 @@ def test_foo3(self): symbol_map = SymbolMap() - var_idx = symbol_map.add_variable(u'a') + var_idx = symbol_map.add_parameter(u'a') code = JsCode(symbol_map) - code.parameters = [u'a'] code.emit('LOAD_VARIABLE', var_idx, u'a') code.emit('RETURN') From noreply at buildbot.pypy.org Thu Feb 21 14:58:47 2013 From: noreply at buildbot.pypy.org (stepahn) Date: Thu, 21 Feb 2013 14:58:47 +0100 (CET) Subject: [pypy-commit] lang-js default: optimized property access Message-ID: <20130221135847.DE3901C0237@cobra.cs.uni-duesseldorf.de> Author: Stephan Branch: Changeset: r360:33a38e14a318 Date: 2013-02-21 14:57 +0100 http://bitbucket.org/pypy/lang-js/changeset/33a38e14a318/ Log: optimized property access diff --git a/js/jsobj.py b/js/jsobj.py --- a/js/jsobj.py +++ b/js/jsobj.py @@ -2,7 +2,7 @@ from rpython.rlib.rarithmetic import intmask from rpython.rlib.rfloat import isnan, isinf, NAN, formatd, INFINITY from rpython.rlib.objectmodel import enforceargs -from rpython.rlib import jit +from rpython.rlib import jit, debug from js.property_descriptor import PropertyDescriptor, DataPropertyDescriptor, AccessorPropertyDescriptor, is_data_descriptor, is_generic_descriptor, is_accessor_descriptor from js.property import DataProperty, AccessorProperty @@ -179,7 +179,7 @@ def __init__(self): from js.object_space import newnull self._property_map_ = new_map() - self._property_slots_ = [] + self._property_slots_ = debug.make_sure_not_resized([]) self._prototype_ = newnull() W_BasicObject.define_own_property(self, u'__proto__', proto_desc) @@ -242,7 +242,8 @@ if self._property_map_.not_found(idx): return - del(self._property_slots_[idx]) + assert idx >= 0 + self._property_slots_ = self._property_slots_[:idx] + self._property_slots_[idx + 1:] self._property_map_ = self._property_map_.delete(name) def _add_prop(self, name, value): @@ -253,7 +254,7 @@ idx = self._property_map_.index if idx >= len(self._property_slots_): - self._property_slots_ += ([None] * (1 + idx - len(self._property_slots_))) + self._property_slots_ = self._property_slots_ + ([None] * (1 + idx - len(self._property_slots_))) self._property_slots_[idx] = value @@ -479,7 +480,7 @@ return reject(throw, p) # 12 prop = self._get_prop(p) - self._set_prop(p, prop.update_with_descriptor(desc)) + prop.update_with_descriptor(desc) # 13 return True diff --git a/js/property.py b/js/property.py --- a/js/property.py +++ b/js/property.py @@ -7,8 +7,6 @@ # 8.6.1 class Property(object): - _immutable_fields_ = ['value', 'writable', 'getter', 'setter', 'enumerable', 'configurable'] - def __init__(self, value=None, writable=NOT_SET, getter=None, setter=None, enumerable=NOT_SET, configurable=NOT_SET): self.value = value self.writable = writable @@ -41,26 +39,18 @@ assert isinstance(desc, PropertyDescriptor) if desc.has_set_value(): - value = desc.value - else: - value = self.value + self.value = desc.value if desc.has_set_writable(): - writable = desc.writable - else: - writable = self.writable + self.writable = desc.writable if desc.has_set_enumerable(): - enumerable = desc.enumerable - else: - enumerable = self.enumerable + self.enumerable = desc.enumerable if desc.has_set_configurable(): - configurable = desc.configurable - else: - configurable = self.configurable + self.configurable = desc.configurable - return DataProperty(value, writable, enumerable, configurable) + return self def to_property_descriptor(self): return DataPropertyDescriptor(self.value, self.writable, self.enumerable, self.configurable) @@ -77,26 +67,18 @@ assert isinstance(desc, PropertyDescriptor) if desc.has_set_getter(): - getter = desc.getter - else: - getter = self.getter + self.getter = desc.getter if desc.has_set_setter(): - setter = desc.setter - else: - setter = self.setter + self.setter = desc.setter if desc.has_set_enumerable(): - enumerable = desc.enumerable - else: - enumerable = self.enumerable + self.enumerable = desc.enumerable if desc.has_set_configurable(): - configurable = desc.configurable - else: - configurable = self.configurable + self.configurable = desc.configurable - return AccessorProperty(getter, setter, enumerable, configurable) + return self def to_property_descriptor(self): return AccessorPropertyDescriptor(self.getter, self.setter, self.enumerable, self.configurable) diff --git a/test/jit_view.py b/test/jit_view.py --- a/test/jit_view.py +++ b/test/jit_view.py @@ -62,6 +62,20 @@ self.run(code, 100) + def test_simple_object_alloc_loop_in_func_loop(self): + code = """ + function f() { + var i = 0; + while(i < 100) { + i = {foo: i}.foo + 1; + } + return x.i; + } + return f(); + """ + + self.run(code, 100) + def test_object_alloc_loop_in_func_loop(self): code = """ function f() { From noreply at buildbot.pypy.org Thu Feb 21 15:03:25 2013 From: noreply at buildbot.pypy.org (fijal) Date: Thu, 21 Feb 2013 15:03:25 +0100 (CET) Subject: [pypy-commit] pypy default: another try Message-ID: <20130221140325.F19611C0237@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r61544:8cd74634f441 Date: 2013-02-21 16:02 +0200 http://bitbucket.org/pypy/pypy/changeset/8cd74634f441/ Log: another try diff --git a/pypy/doc/index.rst b/pypy/doc/index.rst --- a/pypy/doc/index.rst +++ b/pypy/doc/index.rst @@ -217,9 +217,9 @@ Here is a fully referenced alphabetical two-level deep directory overview of PyPy: -================================ =========================================== +================================ ================================================================================================= Directory explanation/links -================================ =========================================== +================================ ================================================================================================= `pypy/bin/`_ command-line scripts, mainly `pyinteractive.py`_ @@ -296,7 +296,7 @@ modules (see `Testing in PyPy`_) ``_cache/`` holds cache files from internally `translating application level to interpreterlevel`_ code. -================================ ============================================================================================ +================================ ================================================================================================= .. _`bytecode interpreter`: interpreter.html .. _`translating application level to interpreterlevel`: geninterp.html From noreply at buildbot.pypy.org Thu Feb 21 15:08:19 2013 From: noreply at buildbot.pypy.org (fijal) Date: Thu, 21 Feb 2013 15:08:19 +0100 (CET) Subject: [pypy-commit] pypy default: cleanup Message-ID: <20130221140819.18E071C0237@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r61545:4295043dccea Date: 2013-02-21 16:07 +0200 http://bitbucket.org/pypy/pypy/changeset/4295043dccea/ Log: cleanup diff --git a/pypy/doc/index.rst b/pypy/doc/index.rst --- a/pypy/doc/index.rst +++ b/pypy/doc/index.rst @@ -217,17 +217,21 @@ Here is a fully referenced alphabetical two-level deep directory overview of PyPy: -================================ ================================================================================================= +================================ ============================================ Directory explanation/links -================================ ================================================================================================= +================================ ============================================ -`pypy/bin/`_ command-line scripts, mainly `pyinteractive.py`_ +`pypy/bin/`_ command-line scripts, mainly + `pyinteractive.py`_ -`pypy/config/`_ handles the numerous options for building and running PyPy +`pypy/config/`_ handles the numerous options for building + and running PyPy -`pypy/doc/`_ text versions of PyPy developer documentation +`pypy/doc/`_ text versions of PyPy developer + documentation -`pypy/doc/config/`_ documentation for the numerous translation options +`pypy/doc/config/`_ documentation for the numerous translation + options `pypy/doc/discussion/`_ drafts of ideas and documentation @@ -238,19 +242,24 @@ `pypy/interpreter/pyparser/`_ interpreter-level Python source parser -`pypy/interpreter/astcompiler/`_ interpreter-level bytecode compiler, via an AST - representation +`pypy/interpreter/astcompiler/`_ interpreter-level bytecode compiler, + via an AST representation -`pypy/module/`_ contains `mixed modules`_ implementing core modules with +`pypy/module/`_ contains `mixed modules`_ + implementing core modules with both application and interpreter level code. - Not all are finished and working. Use the ``--withmod-xxx`` - or ``--allworkingmodules`` translation options. + Not all are finished and working. Use + the ``--withmod-xxx`` + or ``--allworkingmodules`` translation + options. `pypy/objspace/`_ `object space`_ implementations -`pypy/objspace/std/`_ the StdObjSpace_ implementing CPython's objects and types +`pypy/objspace/std/`_ the StdObjSpace_ implementing CPython's + objects and types -`pypy/tool/`_ various utilities and hacks used from various places +`pypy/tool/`_ various utilities and hacks used + from various places `pypy/tool/algo/`_ general-purpose algorithmic and mathematic tools @@ -258,48 +267,58 @@ `pypy/tool/pytest/`_ support code for our `testing methods`_ -`rpython/annotator/`_ `type inferencing code`_ for `RPython`_ programs +`rpython/annotator/`_ `type inferencing code`_ for + `RPython`_ programs `rpython/config/`_ handles the numerous options for RPython -`rpython/flowspace/`_ the FlowObjSpace_ implementing `abstract interpretation`_ +`rpython/flowspace/`_ the FlowObjSpace_ implementing + `abstract interpretation`_ - -`rpython/rlib/`_ a `"standard library"`_ for RPython_ programs +`rpython/rlib/`_ a `"standard library"`_ for RPython_ + programs `rpython/rtyper/`_ the `RPython Typer`_ -`rpython/rtyper/lltypesystem/`_ the `low-level type system`_ for C-like backends +`rpython/rtyper/lltypesystem/`_ the `low-level type system`_ for + C-like backends -`rpython/rtyper/ootypesystem/`_ the `object-oriented type system`_ for OO backends +`rpython/rtyper/ootypesystem/`_ the `object-oriented type system`_ + for OO backends -`rpython/rtyper/memory/`_ the `garbage collector`_ construction framework +`rpython/rtyper/memory/`_ the `garbage collector`_ construction + framework `rpython/translator/`_ translation_ backends and support code -`rpython/translator/backendopt/`_ general optimizations that run before a backend generates code +`rpython/translator/backendopt/`_ general optimizations that run before a + backend generates code -`rpython/translator/c/`_ the `GenC backend`_, producing C code from an +`rpython/translator/c/`_ the `GenC backend`_, producing C code + from an RPython program (generally via the rtyper_) -`rpython/translator/cli/`_ the `CLI backend`_ for `.NET`_ (Microsoft CLR or Mono_) +`rpython/translator/cli/`_ the `CLI backend`_ for `.NET`_ + (Microsoft CLR or Mono_) -`pypy/goal/`_ our `main PyPy-translation scripts`_ live here +`pypy/goal/`_ our `main PyPy-translation scripts`_ + live here `rpython/translator/jvm/`_ the Java backend -`rpython/translator/tool/`_ helper tools for translation, including the Pygame - `graph viewer`_ +`rpython/translator/tool/`_ helper tools for translation -``*/test/`` many directories have a test subdirectory containing test +`dotviewer/`_ `graph viewer`_ + +``*/test/`` many directories have a test subdirectory + containing test modules (see `Testing in PyPy`_) -``_cache/`` holds cache files from internally `translating application level to interpreterlevel`_ code. -================================ ================================================================================================= +``_cache/`` holds cache files from various purposes +================================ ============================================ .. _`bytecode interpreter`: interpreter.html -.. _`translating application level to interpreterlevel`: geninterp.html .. _`Testing in PyPy`: coding-guide.html#testing-in-pypy .. _`mixed modules`: coding-guide.html#mixed-modules .. _`modules`: coding-guide.html#modules From noreply at buildbot.pypy.org Thu Feb 21 15:11:17 2013 From: noreply at buildbot.pypy.org (fijal) Date: Thu, 21 Feb 2013 15:11:17 +0100 (CET) Subject: [pypy-commit] pypy default: try with an extra enter Message-ID: <20130221141117.462B71C0228@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r61546:d57cfb317484 Date: 2013-02-21 16:10 +0200 http://bitbucket.org/pypy/pypy/changeset/d57cfb317484/ Log: try with an extra enter diff --git a/pypy/doc/index.rst b/pypy/doc/index.rst --- a/pypy/doc/index.rst +++ b/pypy/doc/index.rst @@ -316,6 +316,7 @@ modules (see `Testing in PyPy`_) ``_cache/`` holds cache files from various purposes + ================================ ============================================ .. _`bytecode interpreter`: interpreter.html From noreply at buildbot.pypy.org Thu Feb 21 15:20:38 2013 From: noreply at buildbot.pypy.org (fijal) Date: Thu, 21 Feb 2013 15:20:38 +0100 (CET) Subject: [pypy-commit] pypy default: fight with links Message-ID: <20130221142038.9CB681C0228@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r61547:a9263de83cad Date: 2013-02-21 16:19 +0200 http://bitbucket.org/pypy/pypy/changeset/a9263de83cad/ Log: fight with links diff --git a/pypy/doc/_ref.txt b/pypy/doc/_ref.txt --- a/pypy/doc/_ref.txt +++ b/pypy/doc/_ref.txt @@ -1,24 +1,18 @@ .. _`ctypes_configure/doc/sample.py`: https://bitbucket.org/pypy/pypy/src/default/ctypes_configure/doc/sample.py -.. _`demo/`: https://bitbucket.org/pypy/pypy/src/default/demo/ +.. _`dotviewer/`: https://bitbucket.org/pypy/pypy/src/default/dotviewer/ .. _`lib-python/`: https://bitbucket.org/pypy/pypy/src/default/lib-python/ .. _`lib-python/2.7/dis.py`: https://bitbucket.org/pypy/pypy/src/default/lib-python/2.7/dis.py .. _`lib_pypy/`: https://bitbucket.org/pypy/pypy/src/default/lib_pypy/ .. _`lib_pypy/greenlet.py`: https://bitbucket.org/pypy/pypy/src/default/lib_pypy/greenlet.py .. _`lib_pypy/pypy_test/`: https://bitbucket.org/pypy/pypy/src/default/lib_pypy/pypy_test/ .. _`lib_pypy/tputil.py`: https://bitbucket.org/pypy/pypy/src/default/lib_pypy/tputil.py -.. _`pypy/annotation`: -.. _`pypy/annotation/`: https://bitbucket.org/pypy/pypy/src/default/pypy/annotation/ -.. _`pypy/annotation/annrpython.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/annotation/annrpython.py -.. _`pypy/annotation/binaryop.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/annotation/binaryop.py -.. _`pypy/annotation/builtin.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/annotation/builtin.py .. _`pypy/bin/`: https://bitbucket.org/pypy/pypy/src/default/pypy/bin/ -.. _`pypy/bin/translatorshell.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/bin/translatorshell.py .. _`pypy/config/`: https://bitbucket.org/pypy/pypy/src/default/pypy/config/ .. _`pypy/config/pypyoption.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/config/pypyoption.py -.. _`pypy/config/translationoption.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/config/translationoption.py .. _`pypy/doc/`: https://bitbucket.org/pypy/pypy/src/default/pypy/doc/ .. _`pypy/doc/config/`: https://bitbucket.org/pypy/pypy/src/default/pypy/doc/config/ .. _`pypy/doc/discussion/`: https://bitbucket.org/pypy/pypy/src/default/pypy/doc/discussion/ +.. _`pypy/goal/`: https://bitbucket.org/pypy/pypy/src/default/pypy/goal/ .. _`pypy/interpreter`: .. _`pypy/interpreter/`: https://bitbucket.org/pypy/pypy/src/default/pypy/interpreter/ .. _`pypy/interpreter/argument.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/interpreter/argument.py @@ -54,11 +48,8 @@ .. _`pypy/module`: .. _`pypy/module/`: https://bitbucket.org/pypy/pypy/src/default/pypy/module/ .. _`pypy/module/__builtin__/__init__.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/module/__builtin__/__init__.py -.. _`pypy/objspace`: .. _`pypy/objspace/`: https://bitbucket.org/pypy/pypy/src/default/pypy/objspace/ -.. _`pypy/objspace/flow`: .. _`pypy/objspace/flow/`: https://bitbucket.org/pypy/pypy/src/default/pypy/objspace/flow/ -.. _`pypy/objspace/flow/model.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/objspace/flow/model.py .. _`pypy/objspace/std`: .. _`pypy/objspace/std/`: https://bitbucket.org/pypy/pypy/src/default/pypy/objspace/std/ .. _`pypy/objspace/std/listtype.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/objspace/std/listtype.py @@ -70,49 +61,55 @@ .. _`pypy/objspace/std/transparent.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/objspace/std/transparent.py .. _`pypy/objspace/std/tupleobject.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/objspace/std/tupleobject.py .. _`pypy/objspace/std/tupletype.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/objspace/std/tupletype.py -.. _`pypy/rlib`: -.. _`pypy/rlib/`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/ -.. _`pypy/rlib/listsort.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/listsort.py -.. _`pypy/rlib/nonconst.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/nonconst.py -.. _`pypy/rlib/objectmodel.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/objectmodel.py -.. _`pypy/rlib/parsing/`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/parsing/ -.. _`pypy/rlib/parsing/tree.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/parsing/tree.py -.. _`pypy/rlib/rarithmetic.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/rarithmetic.py -.. _`pypy/rlib/rbigint.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/rbigint.py -.. _`pypy/rlib/rrandom.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/rrandom.py -.. _`pypy/rlib/rsocket.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/rsocket.py -.. _`pypy/rlib/streamio.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/streamio.py -.. _`pypy/rlib/test`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/test/ -.. _`pypy/rlib/unroll.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/unroll.py -.. _`pypy/rpython`: -.. _`pypy/rpython/`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/ -.. _`pypy/rpython/lltypesystem/`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/lltypesystem/ -.. _`pypy/rpython/lltypesystem/lltype.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/lltypesystem/lltype.py -.. _`pypy/rpython/memory/`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/memory/ -.. _`pypy/rpython/memory/gc/generation.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/memory/gc/generation.py -.. _`pypy/rpython/memory/gc/hybrid.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/memory/gc/hybrid.py -.. _`pypy/rpython/memory/gc/markcompact.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/memory/gc/markcompact.py -.. _`pypy/rpython/memory/gc/marksweep.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/memory/gc/marksweep.py -.. _`pypy/rpython/memory/gc/minimarkpage.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/memory/gc/minimarkpage.py -.. _`pypy/rpython/memory/gc/semispace.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/memory/gc/semispace.py -.. _`pypy/rpython/ootypesystem/`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/ootypesystem/ -.. _`pypy/rpython/ootypesystem/ootype.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/ootypesystem/ootype.py -.. _`pypy/rpython/rint.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/rint.py -.. _`pypy/rpython/rlist.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/rlist.py -.. _`pypy/rpython/rmodel.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/rmodel.py -.. _`pypy/rpython/rtyper.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/rtyper.py -.. _`pypy/rpython/test/test_llinterp.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/test/test_llinterp.py .. _`pypy/tool/`: https://bitbucket.org/pypy/pypy/src/default/pypy/tool/ .. _`pypy/tool/algo/`: https://bitbucket.org/pypy/pypy/src/default/pypy/tool/algo/ .. _`pypy/tool/pytest/`: https://bitbucket.org/pypy/pypy/src/default/pypy/tool/pytest/ -.. _`pypy/tool/traceconfig.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/tool/traceconfig.py -.. _`pypy/translator`: -.. _`pypy/translator/`: https://bitbucket.org/pypy/pypy/src/default/pypy/translator/ -.. _`pypy/translator/backendopt/`: https://bitbucket.org/pypy/pypy/src/default/pypy/translator/backendopt/ -.. _`pypy/translator/c/`: https://bitbucket.org/pypy/pypy/src/default/pypy/translator/c/ -.. _`pypy/translator/c/src/stacklet/`: https://bitbucket.org/pypy/pypy/src/default/pypy/translator/c/src/stacklet/ -.. _`pypy/translator/c/src/stacklet/stacklet.h`: https://bitbucket.org/pypy/pypy/src/default/pypy/translator/c/src/stacklet/stacklet.h -.. _`pypy/translator/cli/`: https://bitbucket.org/pypy/pypy/src/default/pypy/translator/cli/ -.. _`pypy/translator/goal/`: https://bitbucket.org/pypy/pypy/src/default/pypy/translator/goal/ -.. _`pypy/translator/jvm/`: https://bitbucket.org/pypy/pypy/src/default/pypy/translator/jvm/ -.. _`pypy/translator/tool/`: https://bitbucket.org/pypy/pypy/src/default/pypy/translator/tool/ +.. _`rpython/annotator`: +.. _`rpython/annotator/`: https://bitbucket.org/pypy/pypy/src/default/rpython/annotator/ +.. _`rpython/annotator/annrpython.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/annotator/annrpython.py +.. _`rpython/annotator/binaryop.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/annotator/binaryop.py +.. _`rpython/annotator/builtin.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/annotator/builtin.py +.. _`rpython/bin/translatorshell.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/bin/translatorshell.py +.. _`rpython/config/`: https://bitbucket.org/pypy/pypy/src/default/rpython/config/ +.. _`rpython/config/translationoption.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/config/translationoption.py +.. _`rpython/flowspace/`: https://bitbucket.org/pypy/pypy/src/default/rpython/flowspace/ +.. _`rpython/flowspace/model.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/flowspace/model.py +.. _`rpython/rlib`: +.. _`rpython/rlib/`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/ +.. _`rpython/rlib/listsort.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/listsort.py +.. _`rpython/rlib/nonconst.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/nonconst.py +.. _`rpython/rlib/objectmodel.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/objectmodel.py +.. _`rpython/rlib/parsing/`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/parsing/ +.. _`rpython/rlib/parsing/tree.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/parsing/tree.py +.. _`rpython/rlib/rarithmetic.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/rarithmetic.py +.. _`rpython/rlib/rbigint.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/rbigint.py +.. _`rpython/rlib/rrandom.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/rrandom.py +.. _`rpython/rlib/rsocket.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/rsocket.py +.. _`rpython/rlib/streamio.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/streamio.py +.. _`rpython/rlib/test`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/test/ +.. _`rpython/rlib/unroll.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/unroll.py +.. _`rpython/rtyper`: +.. _`rpython/rtyper/`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/ +.. _`rpython/rtyper/lltypesystem/`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/lltypesystem/ +.. _`rpython/rtyper/lltypesystem/lltype.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/lltypesystem/lltype.py +.. _`rpython/rtyper/memory/`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/memory/ +.. _`rpython/rtyper/memory/gc/generation.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/memory/gc/generation.py +.. _`rpython/rtyper/memory/gc/hybrid.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/memory/gc/hybrid.py +.. _`rpython/rtyper/memory/gc/minimarkpage.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/memory/gc/minimarkpage.py +.. _`rpython/rtyper/memory/gc/semispace.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/memory/gc/semispace.py +.. _`rpython/rtyper/ootypesystem/`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/ootypesystem/ +.. _`rpython/rtyper/ootypesystem/ootype.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/ootypesystem/ootype.py +.. _`rpython/rtyper/rint.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/rint.py +.. _`rpython/rtyper/rlist.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/rlist.py +.. _`rpython/rtyper/rmodel.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/rmodel.py +.. _`rpython/rtyper/rtyper.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/rtyper.py +.. _`rpython/rtyper/test/test_llinterp.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/test/test_llinterp.py +.. _`rpython/translator`: +.. _`rpython/translator/`: https://bitbucket.org/pypy/pypy/src/default/rpython/translator/ +.. _`rpython/translator/backendopt/`: https://bitbucket.org/pypy/pypy/src/default/rpython/translator/backendopt/ +.. _`rpython/translator/c/`: https://bitbucket.org/pypy/pypy/src/default/rpython/translator/c/ +.. _`rpython/translator/c/src/stacklet/`: https://bitbucket.org/pypy/pypy/src/default/rpython/translator/c/src/stacklet/ +.. _`rpython/translator/c/src/stacklet/stacklet.h`: https://bitbucket.org/pypy/pypy/src/default/rpython/translator/c/src/stacklet/stacklet.h +.. _`rpython/translator/cli/`: https://bitbucket.org/pypy/pypy/src/default/rpython/translator/cli/ +.. _`rpython/translator/jvm/`: https://bitbucket.org/pypy/pypy/src/default/rpython/translator/jvm/ +.. _`rpython/translator/tool/`: https://bitbucket.org/pypy/pypy/src/default/rpython/translator/tool/ diff --git a/pypy/doc/coding-guide.rst b/pypy/doc/coding-guide.rst --- a/pypy/doc/coding-guide.rst +++ b/pypy/doc/coding-guide.rst @@ -328,7 +328,7 @@ **builtin functions** A number of builtin functions can be used. The precise set can be - found in `pypy/annotation/builtin.py`_ (see ``def builtin_xxx()``). + found in `rpython/annotator/builtin.py`_ (see ``def builtin_xxx()``). Some builtin functions may be limited in what they support, though. ``int, float, str, ord, chr``... are available as simple conversion diff --git a/pypy/doc/configuration.rst b/pypy/doc/configuration.rst --- a/pypy/doc/configuration.rst +++ b/pypy/doc/configuration.rst @@ -188,7 +188,7 @@ toolchain`_ toolchain, have two separate sets of options. The translation toolchain options can be found on the ``config`` attribute of all ``TranslationContext`` -instances and are described in `pypy/config/translationoption.py`_. The interpreter options +instances and are described in `rpython/config/translationoption.py`_. The interpreter options are attached to the object space, also under the name ``config`` and are described in `pypy/config/pypyoption.py`_. diff --git a/pypy/doc/garbage_collection.rst b/pypy/doc/garbage_collection.rst --- a/pypy/doc/garbage_collection.rst +++ b/pypy/doc/garbage_collection.rst @@ -42,7 +42,7 @@ Two arenas of equal size, with only one arena in use and getting filled with new objects. When the arena is full, the live objects are copied into the other arena using Cheney's algorithm. The old arena is then -cleared. See `pypy/rpython/memory/gc/semispace.py`_. +cleared. See `rpython/rtyper/memory/gc/semispace.py`_. On Unix the clearing is done by reading ``/dev/zero`` into the arena, which is extremely memory efficient at least on Linux: it lets the @@ -55,7 +55,7 @@ Generational GC --------------- -This is a two-generations GC. See `pypy/rpython/memory/gc/generation.py`_. +This is a two-generations GC. See `rpython/rtyper/memory/gc/generation.py`_. It is implemented as a subclass of the Semispace copying collector. It adds a nursery, which is a chunk of the current semispace. Its size is @@ -86,7 +86,7 @@ Each generation is collected much less often than the previous one. The division of the generations is slightly more complicated than just nursery / semispace / external; see the diagram at the start of the -source code, in `pypy/rpython/memory/gc/hybrid.py`_. +source code, in `rpython/rtyper/memory/gc/hybrid.py`_. Mark & Compact GC ----------------- @@ -161,7 +161,7 @@ to the old stage. The dying case 2 objects are immediately freed. - The old stage is an area of memory containing old (small) objects. It - is handled by `pypy/rpython/memory/gc/minimarkpage.py`_. It is organized + is handled by `rpython/rtyper/memory/gc/minimarkpage.py`_. It is organized as "arenas" of 256KB or 512KB, subdivided into "pages" of 4KB or 8KB. Each page can either be free, or contain small objects of all the same size. Furthermore at any point in time each object location can be diff --git a/pypy/doc/getting-started-dev.rst b/pypy/doc/getting-started-dev.rst --- a/pypy/doc/getting-started-dev.rst +++ b/pypy/doc/getting-started-dev.rst @@ -172,23 +172,23 @@ ``xxxobject.py`` contain respectively the definition of the type and its (default) implementation. -* `pypy/translator`_ contains the code analysis and generation stuff. +* `rpython/translator`_ contains the code analysis and generation stuff. Start reading from translator.py, from which it should be easy to follow the pieces of code involved in the various translation phases. -* `pypy/annotation`_ contains the data model for the type annotation that +* `rpython/annotator`_ contains the data model for the type annotation that can be inferred about a graph. The graph "walker" that uses this is in - `pypy/annotation/annrpython.py`_. + `rpython/annotator/annrpython.py`_. -* `pypy/rpython`_ contains the code of the RPython typer. The typer transforms +* `rpython/rtyper`_ contains the code of the RPython typer. The typer transforms annotated flow graphs in a way that makes them very similar to C code so that they can be easy translated. The graph transformations are controlled - by the code in `pypy/rpython/rtyper.py`_. The object model that is used can - be found in `pypy/rpython/lltypesystem/lltype.py`_. For each RPython type + by the code in `rpython/rtyper/rtyper.py`_. The object model that is used can + be found in `rpython/rtyper/lltypesystem/lltype.py`_. For each RPython type there is a file rxxxx.py that contains the low level functions needed for this type. -* `pypy/rlib`_ contains the `RPython standard library`_, things that you can +* `rpython/rlib`_ contains the `RPython standard library`_, things that you can use from rpython. .. _`RPython standard library`: rlib.html @@ -319,10 +319,10 @@ Demos ------- -The `demo/`_ directory contains examples of various aspects of PyPy, -ranging from running regular Python programs (that we used as compliance goals) -over experimental distribution mechanisms to examples translating -sufficiently static programs into low level code. +The `example-interpreter`_ repository contains an example interpreter +written using the RPython translation toolchain. + +.. _`example-interpreter`: https://bitbucket.org/pypy/example-interpreter Additional Tools for running (and hacking) PyPy ----------------------------------------------- diff --git a/pypy/doc/rtyper.rst b/pypy/doc/rtyper.rst --- a/pypy/doc/rtyper.rst +++ b/pypy/doc/rtyper.rst @@ -4,7 +4,7 @@ .. contents:: -The RPython Typer lives in the directory `pypy/rpython/`_. +The RPython Typer lives in the directory `rpython/rtyper/`_. Overview @@ -52,7 +52,7 @@ where -- in C notation -- all three variables v1, v2 and v3 are typed ``int``. This is done by attaching an attribute ``concretetype`` to v1, v2 and v3 (which might be instances of Variable or possibly Constant). In our model, -this ``concretetype`` is ``pypy.rpython.lltypesystem.lltype.Signed``. Of +this ``concretetype`` is ``rpython.rtyper.lltypesystem.lltype.Signed``. Of course, the purpose of replacing the operation called ``add`` with ``int_add`` is that code generators no longer have to worry about what kind of addition (or concatenation maybe?) it means. @@ -66,7 +66,7 @@ each operation. In both cases the analysis of an operation depends on the annotations of its input arguments. This is reflected in the usage of the same ``__extend__`` syntax in the source files (compare e.g. -`pypy/annotation/binaryop.py`_ and `pypy/rpython/rint.py`_). +`rpython/annotator/binaryop.py`_ and `rpython/rtyper/rint.py`_). The analogy stops here, though: while it runs, the Annotator is in the middle of computing the annotations, so it might need to reflow and generalize until @@ -104,7 +104,7 @@ implementations for the same high-level operations. This is the reason for turning representations into explicit objects. -The base Repr class is defined in `pypy/rpython/rmodel.py`_. Most of the +The base Repr class is defined in `rpython/rtyper/rmodel.py`_. Most of the ``rpython/r*.py`` files define one or a few subclasses of Repr. The method getrepr() of the RTyper will build and cache a single Repr instance per SomeXxx() instance; moreover, two SomeXxx() instances that are equal get the @@ -131,9 +131,9 @@ The RPython Typer uses a standard low-level model which we believe can correspond rather directly to various target languages such as C. This model is implemented in the first part of -`pypy/rpython/lltypesystem/lltype.py`_. +`rpython/rtyper/lltypesystem/lltype.py`_. -The second part of `pypy/rpython/lltypesystem/lltype.py`_ is a runnable +The second part of `rpython/rtyper/lltypesystem/lltype.py`_ is a runnable implementation of these types, for testing purposes. It allows us to write and test plain Python code using a malloc() function to obtain and manipulate structures and arrays. This is useful for example to implement and test @@ -147,7 +147,7 @@ Here is a quick tour: - >>> from pypy.rpython.lltypesystem.lltype import * + >>> from rpython.rtyper.lltypesystem.lltype import * Here are a few primitive low-level types, and the typeOf() function to figure them out: @@ -191,7 +191,7 @@ types like list in this elementary world. The ``malloc()`` function is a kind of placeholder, which must eventually be provided by the code generator for the target platform; but as we have just seen its Python implementation in -`pypy/rpython/lltypesystem/lltype.py`_ works too, which is primarily useful for +`rpython/rtyper/lltypesystem/lltype.py`_ works too, which is primarily useful for testing, interactive exploring, etc. The argument to ``malloc()`` is the structure type directly, but it returns a @@ -245,7 +245,7 @@ +++++++++++++++ Structure types are built as instances of -``pypy.rpython.lltypesystem.lltype.Struct``:: +``rpython.rtyper.lltypesystem.lltype.Struct``:: MyStructType = Struct('somename', ('field1', Type1), ('field2', Type2)...) MyStructType = GcStruct('somename', ('field1', Type1), ('field2', Type2)...) @@ -277,7 +277,7 @@ +++++++++++ An array type is built as an instance of -``pypy.rpython.lltypesystem.lltype.Array``:: +``rpython.rtyper.lltypesystem.lltype.Array``:: MyIntArray = Array(Signed) MyOtherArray = Array(MyItemType) @@ -316,7 +316,7 @@ with care: the bigger structure of which they are part of could be freed while the Ptr to the substructure is still in use. In general, it is a good idea to avoid passing around pointers to inlined substructures of malloc()ed structures. -(The testing implementation of `pypy/rpython/lltypesystem/lltype.py`_ checks to some +(The testing implementation of `rpython/rtyper/lltypesystem/lltype.py`_ checks to some extent that you are not trying to use a pointer to a structure after its container has been freed, using weak references. But pointers to non-GC structures are not officially meant to be weak references: using them after what @@ -429,7 +429,7 @@ change needed to the Annotator to allow it to perform type inference of our very-low-level snippets of code. -See for example `pypy/rpython/rlist.py`_. +See for example `rpython/rtyper/rlist.py`_. .. _`oo type`: @@ -441,10 +441,10 @@ targeting low level backends such as C, but it is not good enough for targeting higher level backends such as .NET CLI or Java JVM, so a new object oriented model has been introduced. This model is -implemented in the first part of `pypy/rpython/ootypesystem/ootype.py`_. +implemented in the first part of `rpython/rtyper/ootypesystem/ootype.py`_. As for the low-level typesystem, the second part of -`pypy/rpython/ootypesystem/ootype.py`_ is a runnable implementation of +`rpython/rtyper/ootypesystem/ootype.py`_ is a runnable implementation of these types, for testing purposes. @@ -751,7 +751,7 @@ The LLInterpreter is a simple piece of code that is able to interpret flow graphs. This is very useful for testing purposes, especially if you work on the RPython Typer. The most useful interface for it is the ``interpret`` -function in the file `pypy/rpython/test/test_llinterp.py`_. It takes as +function in the file `rpython/rtyper/test/test_llinterp.py`_. It takes as arguments a function and a list of arguments with which the function is supposed to be called. Then it generates the flow graph, annotates it according to the types of the arguments you passed to it and runs the diff --git a/pypy/doc/stackless.rst b/pypy/doc/stackless.rst --- a/pypy/doc/stackless.rst +++ b/pypy/doc/stackless.rst @@ -29,7 +29,7 @@ on 32-bit or a complete megabyte on 64-bit. Moreover, the feature is only available (so far) on x86 and x86-64 CPUs; for other CPUs you need to add a short page of custom assembler to -`pypy/translator/c/src/stacklet/`_. +`rpython/translator/c/src/stacklet/`_. Theory @@ -271,7 +271,7 @@ Continulets are internally implemented using stacklets, which is the generic RPython-level building block for "one-shot continuations". For more information about them please see the documentation in the C source -at `pypy/translator/c/src/stacklet/stacklet.h`_. +at `rpython/translator/c/src/stacklet/stacklet.h`_. The module ``pypy.rlib.rstacklet`` is a thin wrapper around the above functions. The key point is that new() and switch() always return a diff --git a/pypy/doc/tool/makeref.py b/pypy/doc/tool/makeref.py --- a/pypy/doc/tool/makeref.py +++ b/pypy/doc/tool/makeref.py @@ -1,7 +1,7 @@ import py import pypy -pypydir = py.path.local(pypy.__file__).join('..', '..') +pypydir = py.path.local(pypy.__file__).join('..') distdir = pypydir.dirpath() issue_url = 'http://bugs.pypy.org/issue/pypy-dev/' bitbucket_url = 'https://bitbucket.org/pypy/pypy/src/default/' diff --git a/pypy/doc/translation.rst b/pypy/doc/translation.rst --- a/pypy/doc/translation.rst +++ b/pypy/doc/translation.rst @@ -90,7 +90,7 @@ (although these steps are not quite as distinct as you might think from this presentation). -There is an `interactive interface`_ called `pypy/bin/translatorshell.py`_ to the +There is an `interactive interface`_ called `rpython/bin/translatorshell.py`_ to the translation process which allows you to interactively work through these stages. @@ -116,7 +116,7 @@ which are the basic data structures of the translation process. -All these types are defined in `pypy/objspace/flow/model.py`_ (which is a rather +All these types are defined in `rpython/flowspace/model.py`_ (which is a rather important module in the PyPy source base, to reinforce the point). The flow graph of a function is represented by the class ``FunctionGraph``. From noreply at buildbot.pypy.org Thu Feb 21 15:31:38 2013 From: noreply at buildbot.pypy.org (fijal) Date: Thu, 21 Feb 2013 15:31:38 +0100 (CET) Subject: [pypy-commit] pypy default: maybe Message-ID: <20130221143138.704BF1C0228@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r61548:d268fdd09079 Date: 2013-02-21 16:30 +0200 http://bitbucket.org/pypy/pypy/changeset/d268fdd09079/ Log: maybe diff --git a/pypy/doc/_ref.txt b/pypy/doc/_ref.txt --- a/pypy/doc/_ref.txt +++ b/pypy/doc/_ref.txt @@ -7,6 +7,7 @@ .. _`lib_pypy/pypy_test/`: https://bitbucket.org/pypy/pypy/src/default/lib_pypy/pypy_test/ .. _`lib_pypy/tputil.py`: https://bitbucket.org/pypy/pypy/src/default/lib_pypy/tputil.py .. _`pypy/bin/`: https://bitbucket.org/pypy/pypy/src/default/pypy/bin/ +.. _`pypy/bin/pyinteractive.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/bin/pyinteractive.py .. _`pypy/config/`: https://bitbucket.org/pypy/pypy/src/default/pypy/config/ .. _`pypy/config/pypyoption.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/config/pypyoption.py .. _`pypy/doc/`: https://bitbucket.org/pypy/pypy/src/default/pypy/doc/ diff --git a/pypy/doc/index.rst b/pypy/doc/index.rst --- a/pypy/doc/index.rst +++ b/pypy/doc/index.rst @@ -222,7 +222,7 @@ ================================ ============================================ `pypy/bin/`_ command-line scripts, mainly - `pyinteractive.py`_ + `pypy/bin/pyinteractive.py`_ `pypy/config/`_ handles the numerous options for building and running PyPy @@ -316,7 +316,6 @@ modules (see `Testing in PyPy`_) ``_cache/`` holds cache files from various purposes - ================================ ============================================ .. _`bytecode interpreter`: interpreter.html From noreply at buildbot.pypy.org Thu Feb 21 16:03:50 2013 From: noreply at buildbot.pypy.org (fijal) Date: Thu, 21 Feb 2013 16:03:50 +0100 (CET) Subject: [pypy-commit] pypy default: (tos9) another approach Message-ID: <20130221150350.D11CC1C1265@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r61549:a72c3e886452 Date: 2013-02-21 17:02 +0200 http://bitbucket.org/pypy/pypy/changeset/a72c3e886452/ Log: (tos9) another approach diff --git a/pypy/doc/index.rst b/pypy/doc/index.rst --- a/pypy/doc/index.rst +++ b/pypy/doc/index.rst @@ -217,10 +217,9 @@ Here is a fully referenced alphabetical two-level deep directory overview of PyPy: -================================ ============================================ +================================= ============================================ Directory explanation/links -================================ ============================================ - +================================= ============================================ `pypy/bin/`_ command-line scripts, mainly `pypy/bin/pyinteractive.py`_ @@ -316,7 +315,7 @@ modules (see `Testing in PyPy`_) ``_cache/`` holds cache files from various purposes -================================ ============================================ +================================= ============================================ .. _`bytecode interpreter`: interpreter.html .. _`Testing in PyPy`: coding-guide.html#testing-in-pypy From noreply at buildbot.pypy.org Thu Feb 21 16:25:14 2013 From: noreply at buildbot.pypy.org (fijal) Date: Thu, 21 Feb 2013 16:25:14 +0100 (CET) Subject: [pypy-commit] pypy default: we most likely want caching here too Message-ID: <20130221152514.3E80E1C0237@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r61550:c3d37dbae146 Date: 2013-02-21 17:24 +0200 http://bitbucket.org/pypy/pypy/changeset/c3d37dbae146/ Log: we most likely want caching here too diff --git a/rpython/rtyper/rclass.py b/rpython/rtyper/rclass.py --- a/rpython/rtyper/rclass.py +++ b/rpython/rtyper/rclass.py @@ -395,7 +395,7 @@ assert not s_attr.is_constant() if '__iter__' in self.allinstancefields: raise Exception("__iter__ on instance disallowed") - r_method = self.rtyper.makerepr(s_attr) + r_method = self.rtyper.getrepr(s_attr) r_method.get_method_from_instance(self, vinst, hop.llops) hop2 = hop.copy() hop2.spaceop.opname = 'simple_call' From noreply at buildbot.pypy.org Thu Feb 21 16:26:55 2013 From: noreply at buildbot.pypy.org (fijal) Date: Thu, 21 Feb 2013 16:26:55 +0100 (CET) Subject: [pypy-commit] pypy default: give up and implement this convert_from_to Message-ID: <20130221152655.4DC1D1C0237@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r61551:705665c5ba31 Date: 2013-02-21 17:25 +0200 http://bitbucket.org/pypy/pypy/changeset/705665c5ba31/ Log: give up and implement this convert_from_to diff --git a/rpython/rtyper/rptr.py b/rpython/rtyper/rptr.py --- a/rpython/rtyper/rptr.py +++ b/rpython/rtyper/rptr.py @@ -347,3 +347,10 @@ if r_from.lowleveltype == r_to.lowleveltype: return v return NotImplemented + +class __extend__(pairtype(InteriorPtrRepr, InteriorPtrRepr)): + + def convert_from_to((r_from, r_to), v, llops): + if r_from.__dict__ == r_to.__dict__: + return v + return NotImplemented From noreply at buildbot.pypy.org Thu Feb 21 17:03:18 2013 From: noreply at buildbot.pypy.org (fijal) Date: Thu, 21 Feb 2013 17:03:18 +0100 (CET) Subject: [pypy-commit] pypy default: maybe, just maybe, get rid of the crashes with InteriorPtr Message-ID: <20130221160318.905521C1265@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r61552:e176b19b813a Date: 2013-02-21 18:02 +0200 http://bitbucket.org/pypy/pypy/changeset/e176b19b813a/ Log: maybe, just maybe, get rid of the crashes with InteriorPtr diff --git a/rpython/rtyper/lltypesystem/rdict.py b/rpython/rtyper/lltypesystem/rdict.py --- a/rpython/rtyper/lltypesystem/rdict.py +++ b/rpython/rtyper/lltypesystem/rdict.py @@ -385,48 +385,60 @@ # be direct_call'ed from rtyped flow graphs, which means that they will # get flowed and annotated, mostly with SomePtr. + at objectmodel.enforceargs(None, int) def ll_everused_from_flag(entries, i): return entries[i].f_everused + at objectmodel.enforceargs(None, int) def ll_everused_from_key(entries, i): return bool(entries[i].key) + at objectmodel.enforceargs(None, int) def ll_everused_from_value(entries, i): return bool(entries[i].value) + at objectmodel.enforceargs(None, int) def ll_valid_from_flag(entries, i): return entries[i].f_valid + at objectmodel.enforceargs(None, int) def ll_mark_deleted_in_flag(entries, i): entries[i].f_valid = False + at objectmodel.enforceargs(None, int) def ll_valid_from_key(entries, i): ENTRIES = lltype.typeOf(entries).TO dummy = ENTRIES.dummy_obj.ll_dummy_value return entries.everused(i) and entries[i].key != dummy + at objectmodel.enforceargs(None, int) def ll_mark_deleted_in_key(entries, i): ENTRIES = lltype.typeOf(entries).TO dummy = ENTRIES.dummy_obj.ll_dummy_value entries[i].key = dummy + at objectmodel.enforceargs(None, int) def ll_valid_from_value(entries, i): ENTRIES = lltype.typeOf(entries).TO dummy = ENTRIES.dummy_obj.ll_dummy_value return entries.everused(i) and entries[i].value != dummy + at objectmodel.enforceargs(None, int) def ll_mark_deleted_in_value(entries, i): ENTRIES = lltype.typeOf(entries).TO dummy = ENTRIES.dummy_obj.ll_dummy_value entries[i].value = dummy + at objectmodel.enforceargs(None, int) def ll_hash_from_cache(entries, i): return entries[i].f_hash + at objectmodel.enforceargs(None, int) def ll_hash_recomputed(entries, i): ENTRIES = lltype.typeOf(entries).TO return ENTRIES.fasthashfn(entries[i].key) + at objectmodel.enforceargs(None, int) def ll_get_value(d, i): return d.entries[i].value From noreply at buildbot.pypy.org Thu Feb 21 17:33:57 2013 From: noreply at buildbot.pypy.org (fijal) Date: Thu, 21 Feb 2013 17:33:57 +0100 (CET) Subject: [pypy-commit] pypy default: this is not valid RPython Message-ID: <20130221163357.D6D7D1C12DC@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r61553:800659282a1a Date: 2013-02-21 18:32 +0200 http://bitbucket.org/pypy/pypy/changeset/800659282a1a/ Log: this is not valid RPython diff --git a/rpython/jit/metainterp/pyjitpl.py b/rpython/jit/metainterp/pyjitpl.py --- a/rpython/jit/metainterp/pyjitpl.py +++ b/rpython/jit/metainterp/pyjitpl.py @@ -1082,7 +1082,7 @@ def opimpl_debug_fatalerror(self, box): from rpython.rtyper.lltypesystem import rstr, lloperation msg = box.getref(lltype.Ptr(rstr.STR)) - lloperation.llop.debug_fatalerror(msg) + lloperation.llop.debug_fatalerror(lltype.Void, msg) @arguments("box", "box", "box", "box", "box") def opimpl_jit_debug(self, stringbox, arg1box, arg2box, arg3box, arg4box): From noreply at buildbot.pypy.org Thu Feb 21 17:58:44 2013 From: noreply at buildbot.pypy.org (jerith) Date: Thu, 21 Feb 2013 17:58:44 +0100 (CET) Subject: [pypy-commit] pypy enumerate-rstr: Make enumerate() work with rstr. Message-ID: <20130221165844.EE5B01C0228@cobra.cs.uni-duesseldorf.de> Author: Jeremy Thurgood Branch: enumerate-rstr Changeset: r61554:c0e310c1482e Date: 2013-02-21 18:57 +0200 http://bitbucket.org/pypy/pypy/changeset/c0e310c1482e/ Log: Make enumerate() work with rstr. diff --git a/rpython/rtyper/lltypesystem/rlist.py b/rpython/rtyper/lltypesystem/rlist.py --- a/rpython/rtyper/lltypesystem/rlist.py +++ b/rpython/rtyper/lltypesystem/rlist.py @@ -419,6 +419,7 @@ def __init__(self, r_list): self.r_list = r_list + self.external_item_repr = r_list.external_item_repr self.lowleveltype = Ptr(GcStruct('listiter', ('list', r_list.lowleveltype), ('index', Signed))) diff --git a/rpython/rtyper/lltypesystem/rstr.py b/rpython/rtyper/lltypesystem/rstr.py --- a/rpython/rtyper/lltypesystem/rstr.py +++ b/rpython/rtyper/lltypesystem/rstr.py @@ -1054,15 +1054,18 @@ def __init__(self): self.ll_striter = ll_striter self.ll_strnext = ll_strnext + self.ll_getnextindex = ll_getnextindex class StringIteratorRepr(BaseStringIteratorRepr): + external_item_repr = char_repr lowleveltype = Ptr(GcStruct('stringiter', ('string', string_repr.lowleveltype), ('index', Signed))) class UnicodeIteratorRepr(BaseStringIteratorRepr): + external_item_repr = unichar_repr lowleveltype = Ptr(GcStruct('unicodeiter', ('string', unicode_repr.lowleveltype), ('index', Signed))) @@ -1087,6 +1090,9 @@ iter.index = index + 1 return chars[index] +def ll_getnextindex(iter): + return iter.index + string_repr.iterator_repr = StringIteratorRepr() unicode_repr.iterator_repr = UnicodeIteratorRepr() diff --git a/rpython/rtyper/rrange.py b/rpython/rtyper/rrange.py --- a/rpython/rtyper/rrange.py +++ b/rpython/rtyper/rrange.py @@ -207,7 +207,7 @@ v_index = hop.gendirectcall(self.ll_getnextindex, v_enumerate) hop2 = hop.copy() hop2.args_r = [self.r_baseiter] - r_item_src = self.r_baseiter.r_list.external_item_repr + r_item_src = self.r_baseiter.external_item_repr r_item_dst = hop.r_result.items_r[1] v_item = self.r_baseiter.rtype_next(hop2) v_item = hop.llops.convertvar(v_item, r_item_src, r_item_dst) From noreply at buildbot.pypy.org Thu Feb 21 18:15:03 2013 From: noreply at buildbot.pypy.org (jerith) Date: Thu, 21 Feb 2013 18:15:03 +0100 (CET) Subject: [pypy-commit] pypy enumerate-rstr: Some tests for enumerating rstrs. Message-ID: <20130221171503.9CDB41C0228@cobra.cs.uni-duesseldorf.de> Author: Jeremy Thurgood Branch: enumerate-rstr Changeset: r61555:7563dcd4e19e Date: 2013-02-21 19:14 +0200 http://bitbucket.org/pypy/pypy/changeset/7563dcd4e19e/ Log: Some tests for enumerating rstrs. diff --git a/rpython/annotator/test/test_annrpython.py b/rpython/annotator/test/test_annrpython.py --- a/rpython/annotator/test/test_annrpython.py +++ b/rpython/annotator/test/test_annrpython.py @@ -3585,6 +3585,26 @@ s = a.build_types(f, []) assert isinstance(s, annmodel.SomeChar) + def test_enumerate_str(self): + def f(): + for i, x in enumerate('abcd'): + if i == 2: + return x + return '?' + a = self.RPythonAnnotator() + s = a.build_types(f, []) + assert isinstance(s, annmodel.SomeChar) + + def test_enumerate_unicode(self): + def f(): + for i, x in enumerate(u'abcd'): + if i == 2: + return x + return '?' + a = self.RPythonAnnotator() + s = a.build_types(f, []) + assert isinstance(s, annmodel.SomeUnicodeCodePoint) + def test_context_manager(self): class C: def __init__(self): From noreply at buildbot.pypy.org Thu Feb 21 19:36:48 2013 From: noreply at buildbot.pypy.org (jerith) Date: Thu, 21 Feb 2013 19:36:48 +0100 (CET) Subject: [pypy-commit] pypy enumerate-rstr: Backed out changeset 7563dcd4e19e Message-ID: <20130221183648.C12F91C3C7B@cobra.cs.uni-duesseldorf.de> Author: Jeremy Thurgood Branch: enumerate-rstr Changeset: r61556:537fe824215d Date: 2013-02-21 20:33 +0200 http://bitbucket.org/pypy/pypy/changeset/537fe824215d/ Log: Backed out changeset 7563dcd4e19e diff --git a/rpython/annotator/test/test_annrpython.py b/rpython/annotator/test/test_annrpython.py --- a/rpython/annotator/test/test_annrpython.py +++ b/rpython/annotator/test/test_annrpython.py @@ -3585,26 +3585,6 @@ s = a.build_types(f, []) assert isinstance(s, annmodel.SomeChar) - def test_enumerate_str(self): - def f(): - for i, x in enumerate('abcd'): - if i == 2: - return x - return '?' - a = self.RPythonAnnotator() - s = a.build_types(f, []) - assert isinstance(s, annmodel.SomeChar) - - def test_enumerate_unicode(self): - def f(): - for i, x in enumerate(u'abcd'): - if i == 2: - return x - return '?' - a = self.RPythonAnnotator() - s = a.build_types(f, []) - assert isinstance(s, annmodel.SomeUnicodeCodePoint) - def test_context_manager(self): class C: def __init__(self): From noreply at buildbot.pypy.org Thu Feb 21 19:36:50 2013 From: noreply at buildbot.pypy.org (jerith) Date: Thu, 21 Feb 2013 19:36:50 +0100 (CET) Subject: [pypy-commit] pypy enumerate-rstr: Proper tests and some oothingies. Message-ID: <20130221183650.217431C3C7C@cobra.cs.uni-duesseldorf.de> Author: Jeremy Thurgood Branch: enumerate-rstr Changeset: r61557:5671340d830e Date: 2013-02-21 20:36 +0200 http://bitbucket.org/pypy/pypy/changeset/5671340d830e/ Log: Proper tests and some oothingies. diff --git a/rpython/rtyper/ootypesystem/rstr.py b/rpython/rtyper/ootypesystem/rstr.py --- a/rpython/rtyper/ootypesystem/rstr.py +++ b/rpython/rtyper/ootypesystem/rstr.py @@ -428,14 +428,17 @@ class StringIteratorRepr(AbstractStringIteratorRepr): + external_item_repr = char_repr lowleveltype = ootype.Record({'string': string_repr.lowleveltype, 'index': ootype.Signed}) def __init__(self): self.ll_striter = ll_striter self.ll_strnext = ll_strnext + self.ll_getnextindex = ll_getnextindex class UnicodeIteratorRepr(AbstractStringIteratorRepr): + external_item_repr = unichar_repr lowleveltype = ootype.Record({'string': unicode_repr.lowleveltype, 'index': ootype.Signed}) @@ -463,6 +466,9 @@ iter.index = index + 1 return string.ll_stritem_nonneg(index) +def ll_getnextindex(iter): + return iter.index + StringRepr.string_iterator_repr = StringIteratorRepr() UnicodeRepr.string_iterator_repr = UnicodeIteratorRepr() diff --git a/rpython/rtyper/test/test_rstr.py b/rpython/rtyper/test/test_rstr.py --- a/rpython/rtyper/test/test_rstr.py +++ b/rpython/rtyper/test/test_rstr.py @@ -1035,6 +1035,17 @@ got = self.interpret(f, [7]) assert self.ll_to_string(got) == 'None' + def test_enumerate(self): + const = self.const + def fn(n): + s = const('abcde') + for i, x in enumerate(s): + if i == n: + return x + return 'x' + res = self.interpret(fn, [2]) + assert res == 'c' + def FIXME_test_str_to_pystringobj(): def f(n): From noreply at buildbot.pypy.org Thu Feb 21 22:14:10 2013 From: noreply at buildbot.pypy.org (mattip) Date: Thu, 21 Feb 2013 22:14:10 +0100 (CET) Subject: [pypy-commit] pypy numpypy-disable-longdouble: remove longdouble and related dtypes, start to move tests accordingly Message-ID: <20130221211410.B69341C0228@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: numpypy-disable-longdouble Changeset: r61559:5980ccbb798c Date: 2013-02-14 11:05 +0200 http://bitbucket.org/pypy/pypy/changeset/5980ccbb798c/ Log: remove longdouble and related dtypes, start to move tests accordingly diff --git a/pypy/module/micronumpy/__init__.py b/pypy/module/micronumpy/__init__.py --- a/pypy/module/micronumpy/__init__.py +++ b/pypy/module/micronumpy/__init__.py @@ -62,8 +62,8 @@ 'float16': 'interp_boxes.W_Float16Box', 'float32': 'interp_boxes.W_Float32Box', 'float64': 'interp_boxes.W_Float64Box', - 'longdouble': 'interp_boxes.W_LongDoubleBox', - 'longfloat': 'interp_boxes.W_LongDoubleBox', + # 'longdouble': 'interp_boxes.W_LongDoubleBox', + # 'longfloat': 'interp_boxes.W_LongDoubleBox', 'intp': 'types.IntP.BoxType', 'uintp': 'types.UIntP.BoxType', 'flexible': 'interp_boxes.W_FlexibleBox', @@ -76,8 +76,8 @@ 'complex_': 'interp_boxes.W_Complex128Box', 'complex128': 'interp_boxes.W_Complex128Box', 'complex64': 'interp_boxes.W_Complex64Box', - 'clongdouble': 'interp_boxes.W_CLongDoubleBox', - 'clongfloat': 'interp_boxes.W_CLongDoubleBox', + # 'clongdouble': 'interp_boxes.W_CLongDoubleBox', + # 'clongfloat': 'interp_boxes.W_CLongDoubleBox', } # ufuncs @@ -172,9 +172,9 @@ 'arange': 'app_numpy.arange', } -if long_double_size == 16: +if 0 and long_double_size == 16: Module.interpleveldefs['float128'] = 'interp_boxes.W_Float128Box' Module.interpleveldefs['complex256'] = 'interp_boxes.W_Complex256Box' -elif long_double_size == 12: +elif 0 and long_double_size == 12: Module.interpleveldefs['float96'] = 'interp_boxes.W_Float96Box' Module.interpleveldefs['complex192'] = 'interp_boxes.W_Complex192Box' diff --git a/pypy/module/micronumpy/interp_dtype.py b/pypy/module/micronumpy/interp_dtype.py --- a/pypy/module/micronumpy/interp_dtype.py +++ b/pypy/module/micronumpy/interp_dtype.py @@ -474,7 +474,7 @@ aliases=["complex"], float_type = self.w_float64dtype, ) - if interp_boxes.long_double_size == 12: + if 0 and interp_boxes.long_double_size == 12: self.w_float96dtype = W_Dtype( types.Float96(), num=13, @@ -497,7 +497,7 @@ ) self.w_longdouble = self.w_float96dtype self.w_clongdouble = self.w_complex192dtype - elif interp_boxes.long_double_size == 16: + elif 0 and interp_boxes.long_double_size == 16: self.w_float128dtype = W_Dtype( types.Float128(), num=13, @@ -520,7 +520,7 @@ ) self.w_longdouble = self.w_float128dtype self.w_clongdouble = self.w_complex256dtype - else: + elif 0: self.w_float64dtype.aliases += ["longdouble", "longfloat"] self.w_complex128dtype.aliases += ["clongdouble", "clongfloat"] self.w_longdouble = self.w_float64dtype @@ -604,15 +604,19 @@ self.w_int32dtype, self.w_uint32dtype, self.w_int64dtype, self.w_uint64dtype, self.w_float16dtype, - self.w_float32dtype, self.w_float64dtype, self.w_longdouble, - self.w_complex64dtype, self.w_complex128dtype, self.w_clongdouble, + self.w_float32dtype, self.w_float64dtype, + # self.w_longdouble, + self.w_complex64dtype, self.w_complex128dtype, + # self.w_clongdouble, self.w_stringdtype, self.w_unicodedtype, self.w_voiddtype, self.w_intpdtype, self.w_uintpdtype, ] self.float_dtypes_by_num_bytes = sorted( (dtype.itemtype.get_element_size(), dtype) for dtype in [self.w_float16dtype, self.w_float32dtype, - self.w_float64dtype, self.w_longdouble] + self.w_float64dtype, + # self.w_longdouble, + ] ) self.dtypes_by_num = {} self.dtypes_by_name = {} @@ -655,7 +659,7 @@ 'LONGLONG': self.w_int64dtype, 'SHORT': self.w_int16dtype, 'VOID': self.w_voiddtype, - 'LONGDOUBLE': self.w_longdouble, + #'LONGDOUBLE': self.w_longdouble, 'UBYTE': self.w_uint8dtype, 'UINTP': self.w_ulongdtype, 'ULONG': self.w_ulongdtype, @@ -678,7 +682,7 @@ 'USHORT': self.w_uint16dtype, 'FLOAT': self.w_float32dtype, 'BOOL': self.w_booldtype, - 'CLONGDOUBLE': self.w_clongdouble, + #'CLONGDOUBLE': self.w_clongdouble, } typeinfo_partial = { 'Generic': interp_boxes.W_GenericBox, diff --git a/pypy/module/micronumpy/test/test_dtypes.py b/pypy/module/micronumpy/test/test_dtypes.py --- a/pypy/module/micronumpy/test/test_dtypes.py +++ b/pypy/module/micronumpy/test/test_dtypes.py @@ -14,7 +14,7 @@ from rpython.rtyper.lltypesystem import rffi ptr_size = rffi.sizeof(rffi.CCHARP) cls.w_ptr_size = cls.space.wrap(ptr_size) - + class AppTestDtypes(BaseAppTestDtypes): def test_dtype(self): from _numpypy import dtype @@ -530,19 +530,6 @@ assert isnan(numpy.float64(None)) assert isnan(numpy.longdouble(None)) - def test_longfloat(self): - import _numpypy as numpy - # it can be float96 or float128 - if numpy.longfloat != numpy.float64: - assert numpy.longfloat.mro()[1:] == [numpy.floating, - numpy.inexact, numpy.number, - numpy.generic, object] - a = numpy.array([1, 2, 3], numpy.longdouble) - assert type(a[1]) is numpy.longdouble - assert numpy.float64(12) == numpy.longdouble(12) - assert numpy.float64(12) == numpy.longfloat(12) - raises(ValueError, numpy.longfloat, '23.2df') - def test_complex_floating(self): import _numpypy as numpy @@ -821,3 +808,48 @@ assert typeinfo['LONGLONG'] == ('q', 9, 64, 8, 9223372036854775807L, -9223372036854775808L, int64) assert typeinfo['VOID'] == ('V', 20, 0, 1, void) assert typeinfo['BOOL'] == ('?', 0, 8, 1, 1, 0, bool_) + +class AppTestNoLongDoubleDtypes(BaseNumpyAppTest): + def setup_class(cls): + from pypy.module.micronumpy import Module + if Module.interpleveldefs.get('longfloat', None): + py.test.skip('longdouble exists, skip these tests') + if option.runappdirect and '__pypy__' not in sys.builtin_module_names: + py.test.skip("pypy only test for no longdouble support") + BaseNumpyAppTest.setup_class.im_func(cls) + + def test_nolongfloat(self): + import _numpypy + from _numpypy import dtype + assert not getattr(_numpypy, 'longdouble', False) + assert not getattr(_numpypy, 'float128', False) + assert not getattr(_numpypy, 'float96', False) + raises(TypeError, dtype, 'longdouble') + raises(TypeError, dtype, 'clongdouble') + raises(TypeError, dtype, 'longfloat') + raises(TypeError, dtype, 'clongfloat') + raises(TypeError, dtype, 'float128') + raises(TypeError, dtype, 'float96') + +class AppTestLongDoubleDtypes(BaseNumpyAppTest): + def setup_class(cls): + from pypy.module.micronumpy import Module + print dir(Module.interpleveldefs) + if not Module.interpleveldefs.get('longfloat', None): + py.test.skip('no longdouble types yet') + BaseNumpyAppTest.setup_class.im_func(cls) + + def test_longfloat(self): + import _numpypy as numpy + # it can be float96 or float128 + if numpy.longfloat != numpy.float64: + assert numpy.longfloat.mro()[1:] == [numpy.floating, + numpy.inexact, numpy.number, + numpy.generic, object] + a = numpy.array([1, 2, 3], numpy.longdouble) + assert type(a[1]) is numpy.longdouble + assert numpy.float64(12) == numpy.longdouble(12) + assert numpy.float64(12) == numpy.longfloat(12) + raises(ValueError, numpy.longfloat, '23.2df') + + From noreply at buildbot.pypy.org Thu Feb 21 22:14:11 2013 From: noreply at buildbot.pypy.org (mattip) Date: Thu, 21 Feb 2013 22:14:11 +0100 (CET) Subject: [pypy-commit] pypy numpypy-disable-longdouble: remove longfloat from types, interp_boxes, adjust more tests Message-ID: <20130221211411.F03DC1C0228@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: numpypy-disable-longdouble Changeset: r61560:10579024f6bc Date: 2013-02-14 11:28 +0200 http://bitbucket.org/pypy/pypy/changeset/10579024f6bc/ Log: remove longfloat from types, interp_boxes, adjust more tests diff --git a/pypy/module/micronumpy/interp_boxes.py b/pypy/module/micronumpy/interp_boxes.py --- a/pypy/module/micronumpy/interp_boxes.py +++ b/pypy/module/micronumpy/interp_boxes.py @@ -335,7 +335,7 @@ descr__new__, _get_dtype = new_dtype_getter("complex128") _COMPONENTS_BOX = W_Float64Box -if long_double_size == 12: +if 0 and long_double_size == 12: class W_Float96Box(W_FloatingBox, PrimitiveBox): descr__new__, _get_dtype = new_dtype_getter("float96") @@ -347,7 +347,7 @@ W_CLongDoubleBox = W_Complex192Box -elif long_double_size == 16: +elif 0 and long_double_size == 16: class W_Float128Box(W_FloatingBox, PrimitiveBox): descr__new__, _get_dtype = new_dtype_getter("float128") W_LongDoubleBox = W_Float128Box @@ -358,7 +358,7 @@ W_CLongDoubleBox = W_Complex256Box -else: +elif 0: W_LongDoubleBox = W_Float64Box W_CLongDoubleBox = W_Complex64Box @@ -526,7 +526,7 @@ __new__ = interp2app(W_Float64Box.descr__new__.im_func), ) -if long_double_size == 12: +if 0 and long_double_size == 12: W_Float96Box.typedef = TypeDef("float96", (W_FloatingBox.typedef), __module__ = "numpypy", @@ -540,7 +540,7 @@ imag = GetSetProperty(W_ComplexFloatingBox.descr_get_imag), ) -elif long_double_size == 16: +elif 0 and long_double_size == 16: W_Float128Box.typedef = TypeDef("float128", (W_FloatingBox.typedef), __module__ = "numpypy", diff --git a/pypy/module/micronumpy/interp_ufuncs.py b/pypy/module/micronumpy/interp_ufuncs.py --- a/pypy/module/micronumpy/interp_ufuncs.py +++ b/pypy/module/micronumpy/interp_ufuncs.py @@ -400,7 +400,7 @@ return interp_dtype.get_dtype_cache(space).w_complex64dtype elif dt2.num == 15: return interp_dtype.get_dtype_cache(space).w_complex128dtype - elif dt2.num == 16: + elif 0 and dt2.num == 16: return interp_dtype.get_dtype_cache(space).w_clongdouble else: raise OperationError(space.w_TypeError, space.wrap("Unsupported types")) diff --git a/pypy/module/micronumpy/test/test_complex.py b/pypy/module/micronumpy/test/test_complex.py --- a/pypy/module/micronumpy/test/test_complex.py +++ b/pypy/module/micronumpy/test/test_complex.py @@ -496,15 +496,21 @@ def test_basic(self): from _numpypy import (complex128, complex64, add, array, dtype, subtract as sub, multiply, divide, negative, abs, floor_divide, - real, imag, sign, clongfloat) + real, imag, sign) from _numpypy import (equal, not_equal, greater, greater_equal, less, less_equal, isnan) + complex_dtypes = [complex64, complex128] + try: + from _numpypy import clongfloat + complex_dtypes.append(clongfloat) + except: + pass assert real(4.0) == 4.0 assert imag(0.0) == 0.0 a = array([complex(3.0, 4.0)]) b = a.real assert b.dtype == dtype(float) - for complex_ in complex64, complex128, clongfloat: + for complex_ in complex_dtypes: O = complex(0, 0) c0 = complex_(complex(2.5, 0)) diff --git a/pypy/module/micronumpy/types.py b/pypy/module/micronumpy/types.py --- a/pypy/module/micronumpy/types.py +++ b/pypy/module/micronumpy/types.py @@ -1515,7 +1515,7 @@ NonNativeComplex128 = Complex128 -if interp_boxes.long_double_size == 12: +if 0 and interp_boxes.long_double_size == 12: class Float96(BaseType, Float): _attrs_ = () @@ -1545,7 +1545,7 @@ NonNativeComplex192 = Complex192 -elif interp_boxes.long_double_size == 16: +elif 0 and interp_boxes.long_double_size == 16: class Float128(BaseType, Float): _attrs_ = () From noreply at buildbot.pypy.org Thu Feb 21 22:14:13 2013 From: noreply at buildbot.pypy.org (mattip) Date: Thu, 21 Feb 2013 22:14:13 +0100 (CET) Subject: [pypy-commit] pypy numpypy-disable-longdouble: fix complex tests Message-ID: <20130221211413.402921C0228@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: numpypy-disable-longdouble Changeset: r61561:20e3e8514b54 Date: 2013-02-14 11:34 +0200 http://bitbucket.org/pypy/pypy/changeset/20e3e8514b54/ Log: fix complex tests diff --git a/pypy/module/micronumpy/test/test_complex.py b/pypy/module/micronumpy/test/test_complex.py --- a/pypy/module/micronumpy/test/test_complex.py +++ b/pypy/module/micronumpy/test/test_complex.py @@ -196,8 +196,13 @@ raises(TypeError, signbit, complex(1,1)) def test_reciprocal(self): - from _numpypy import array, reciprocal, complex64, complex128, clongdouble - + from _numpypy import array, reciprocal, complex64, complex128 + c_and_relerr = [(complex64, 2e-7), (complex128, 2e-15)] + try: + from _numpypy import clongdouble + c_and_relerr.append((clongdouble, 2e-30)) + except: + pass # no longdouble yet inf = float('inf') nan = float('nan') #complex @@ -212,7 +217,7 @@ complex(-r, i), -0j, 0j, cnan, cnan, cnan, cnan] - for c, rel_err in ((complex64, 2e-7), (complex128, 2e-15), (clongdouble, 2e-15)): + for c, rel_err in c_and_relerr: actual = reciprocal(array([orig], dtype=c)) for b, a, e in zip(orig, actual, expected): assert (a[0].real - e.real) < rel_err @@ -232,12 +237,18 @@ raises(TypeError, copysign, a, b) def test_exp2(self): - from _numpypy import array, exp2, complex128, complex64, clongfloat + from _numpypy import array, exp2, complex128, complex64 + c_and_relerr = [(complex64, 2e-7), (complex128, 2e-15)] + try: + from _numpypy import clongdouble + c_and_relerr.append((clongdouble, 2e-30)) + except: + pass # no longdouble yet inf = float('inf') ninf = -float('inf') nan = float('nan') cmpl = complex - for c,rel_err in ((complex128, 2e-15), (complex64, 1e-7), (clongfloat, 2e-15)): + for c,rel_err in c_and_relerr: a = [cmpl(-5., 0), cmpl(-5., -5.), cmpl(-5., 5.), cmpl(0., -5.), cmpl(0., 0.), cmpl(0., 5.), cmpl(-0., -5.), cmpl(-0., 0.), cmpl(-0., 5.), From noreply at buildbot.pypy.org Thu Feb 21 22:14:14 2013 From: noreply at buildbot.pypy.org (mattip) Date: Thu, 21 Feb 2013 22:14:14 +0100 (CET) Subject: [pypy-commit] pypy numpypy-disable-longdouble: rearrange remaining tests to skip longdouble Message-ID: <20130221211414.79EB11C0228@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: numpypy-disable-longdouble Changeset: r61562:ea0500012d37 Date: 2013-02-14 11:58 +0200 http://bitbucket.org/pypy/pypy/changeset/ea0500012d37/ Log: rearrange remaining tests to skip longdouble diff --git a/pypy/module/micronumpy/test/test_dtypes.py b/pypy/module/micronumpy/test/test_dtypes.py --- a/pypy/module/micronumpy/test/test_dtypes.py +++ b/pypy/module/micronumpy/test/test_dtypes.py @@ -43,13 +43,6 @@ raises(TypeError, lambda: dtype("int8") == 3) assert dtype(bool) == bool - def test_dtype_aliases(self): - from _numpypy import dtype - assert dtype('longfloat').num in (12, 13) - assert dtype('longdouble').num in (12, 13) - assert dtype('clongfloat').num in (15, 16) - assert dtype('clongdouble').num in (15, 16) - def test_dtype_with_types(self): from _numpypy import dtype @@ -154,8 +147,6 @@ '?', 'b', 'B', 'h', 'H', 'i', 'I', 'l', 'L', 'q', 'Q', 'f', 'd', 'e' ] - if array([0], dtype='longdouble').itemsize > 8: - types += ['g', 'G'] a = array([True], '?') for t in types: assert (a + array([0], t)).dtype is dtype(t) @@ -271,7 +262,6 @@ (numpy.float16, 10.), (numpy.float32, 2.0), (numpy.float64, 4.32), - (numpy.longdouble, 4.32), ]: assert hash(tp(value)) == hash(value) @@ -528,7 +518,6 @@ from math import isnan assert isnan(numpy.float32(None)) assert isnan(numpy.float64(None)) - assert isnan(numpy.longdouble(None)) def test_complex_floating(self): import _numpypy as numpy @@ -789,12 +778,6 @@ a = array([1, 2, 3], dtype=self.non_native_prefix + 'f2') assert a[0] == 1 assert (a + a)[1] == 4 - a = array([1, 2, 3], dtype=self.non_native_prefix + 'g') # longdouble - assert a[0] == 1 - assert (a + a)[1] == 4 - a = array([1, 2, 3], dtype=self.non_native_prefix + 'G') # clongdouble - assert a[0] == 1 - assert (a + a)[1] == 4 class AppTestPyPyOnly(BaseNumpyAppTest): def setup_class(cls): @@ -852,4 +835,37 @@ assert numpy.float64(12) == numpy.longfloat(12) raises(ValueError, numpy.longfloat, '23.2df') + def test_dtype_aliases(self): + from _numpypy import dtype + assert dtype('longfloat').num in (12, 13) + assert dtype('longdouble').num in (12, 13) + assert dtype('clongfloat').num in (15, 16) + assert dtype('clongdouble').num in (15, 16) + def test_bool_binop_types(self): + from _numpypy import array, dtype + types = ['g', 'G'] + a = array([True], '?') + for t in types: + assert (a + array([0], t)).dtype is dtype(t) + + def test_hash(self): + import _numpypy as numpy + for tp, value in [ + (numpy.longdouble, 4.32), + ]: + assert hash(tp(value)) == hash(value) + + def test_float_None(self): + import _numpypy as numpy + from math import isnan + assert isnan(numpy.longdouble(None)) + + def test_non_native(self): + from _numpypy import array + a = array([1, 2, 3], dtype=self.non_native_prefix + 'g') # longdouble + assert a[0] == 1 + assert (a + a)[1] == 4 + a = array([1, 2, 3], dtype=self.non_native_prefix + 'G') # clongdouble + assert a[0] == 1 + assert (a + a)[1] == 4 diff --git a/pypy/module/micronumpy/test/test_numarray.py b/pypy/module/micronumpy/test/test_numarray.py --- a/pypy/module/micronumpy/test/test_numarray.py +++ b/pypy/module/micronumpy/test/test_numarray.py @@ -1735,15 +1735,6 @@ i2 = (i+1) * a.dtype.itemsize assert list(reversed(s1[i1:i2])) == s2[i1:i2] - a = array([1, -1, 10000], dtype='longfloat') - s1 = map(ord, a.tostring()) - s2 = map(ord, a.byteswap().tostring()) - assert a.dtype.itemsize >= 8 - for i in range(a.size): - i1 = i * a.dtype.itemsize - i2 = (i+1) * a.dtype.itemsize - assert list(reversed(s1[i1:i2])) == s2[i1:i2] - def test_clip(self): from _numpypy import array a = array([1, 2, 17, -3, 12]) @@ -2378,7 +2369,7 @@ def test_fromstring_types(self): from _numpypy import (fromstring, int8, int16, int32, int64, uint8, - uint16, uint32, float16, float32, float64, longfloat, array) + uint16, uint32, float16, float32, float64, array) a = fromstring('\xFF', dtype=int8) assert a[0] == -1 b = fromstring('\xFF', dtype=uint8) @@ -2401,18 +2392,6 @@ assert j[0] == 12 k = fromstring(self.float16val, dtype=float16) assert k[0] == float16(5.) - dt = array([5],dtype=longfloat).dtype - if dt.itemsize == 12: - from _numpypy import float96 - m = fromstring('\x00\x00\x00\x00\x00\x00\x00\xa0\x01@\x00\x00', dtype=float96) - elif dt.itemsize==16: - from _numpypy import float128 - m = fromstring('\x00\x00\x00\x00\x00\x00\x00\xa0\x01@\x00\x00\x00\x00\x00\x00', dtype=float128) - elif dt.itemsize == 8: - skip('longfloat is float64') - else: - skip('unknown itemsize for longfloat') - assert m[0] == longfloat(5.) def test_fromstring_invalid(self): from _numpypy import fromstring, uint16, uint8 @@ -2687,3 +2666,40 @@ assert x.__pypy_data__ is obj del x.__pypy_data__ assert x.__pypy_data__ is None + +class AppTestLongDoubleDtypes(BaseNumpyAppTest): + def setup_class(cls): + from pypy.module.micronumpy import Module + print dir(Module.interpleveldefs) + if not Module.interpleveldefs.get('longfloat', None): + py.test.skip('no longdouble types yet') + BaseNumpyAppTest.setup_class.im_func(cls) + + def test_byteswap(self): + from _numpypy import array + + a = array([1, -1, 10000], dtype='longfloat') + s1 = map(ord, a.tostring()) + s2 = map(ord, a.byteswap().tostring()) + assert a.dtype.itemsize >= 8 + for i in range(a.size): + i1 = i * a.dtype.itemsize + i2 = (i+1) * a.dtype.itemsize + assert list(reversed(s1[i1:i2])) == s2[i1:i2] + + def test_fromstring_types(self): + from _numpypy import (fromstring, longfloat, array) + dt = array([5],dtype=longfloat).dtype + if dt.itemsize == 12: + from _numpypy import float96 + m = fromstring('\x00\x00\x00\x00\x00\x00\x00\xa0\x01@\x00\x00', dtype=float96) + elif dt.itemsize==16: + from _numpypy import float128 + m = fromstring('\x00\x00\x00\x00\x00\x00\x00\xa0\x01@\x00\x00\x00\x00\x00\x00', dtype=float128) + elif dt.itemsize == 8: + skip('longfloat is float64') + else: + skip('unknown itemsize for longfloat') + assert m[0] == longfloat(5.) + + From noreply at buildbot.pypy.org Thu Feb 21 22:41:56 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Thu, 21 Feb 2013 22:41:56 +0100 (CET) Subject: [pypy-commit] pypy py3k: merge default Message-ID: <20130221214156.A6DAB1C124F@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61563:42449723af3a Date: 2013-02-21 12:55 -0800 http://bitbucket.org/pypy/pypy/changeset/42449723af3a/ Log: merge default diff --git a/pypy/doc/_ref.txt b/pypy/doc/_ref.txt --- a/pypy/doc/_ref.txt +++ b/pypy/doc/_ref.txt @@ -1,24 +1,19 @@ .. _`ctypes_configure/doc/sample.py`: https://bitbucket.org/pypy/pypy/src/default/ctypes_configure/doc/sample.py -.. _`demo/`: https://bitbucket.org/pypy/pypy/src/default/demo/ +.. _`dotviewer/`: https://bitbucket.org/pypy/pypy/src/default/dotviewer/ .. _`lib-python/`: https://bitbucket.org/pypy/pypy/src/default/lib-python/ .. _`lib-python/2.7/dis.py`: https://bitbucket.org/pypy/pypy/src/default/lib-python/2.7/dis.py .. _`lib_pypy/`: https://bitbucket.org/pypy/pypy/src/default/lib_pypy/ .. _`lib_pypy/greenlet.py`: https://bitbucket.org/pypy/pypy/src/default/lib_pypy/greenlet.py .. _`lib_pypy/pypy_test/`: https://bitbucket.org/pypy/pypy/src/default/lib_pypy/pypy_test/ .. _`lib_pypy/tputil.py`: https://bitbucket.org/pypy/pypy/src/default/lib_pypy/tputil.py -.. _`pypy/annotation`: -.. _`pypy/annotation/`: https://bitbucket.org/pypy/pypy/src/default/pypy/annotation/ -.. _`pypy/annotation/annrpython.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/annotation/annrpython.py -.. _`pypy/annotation/binaryop.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/annotation/binaryop.py -.. _`pypy/annotation/builtin.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/annotation/builtin.py .. _`pypy/bin/`: https://bitbucket.org/pypy/pypy/src/default/pypy/bin/ -.. _`pypy/bin/translatorshell.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/bin/translatorshell.py +.. _`pypy/bin/pyinteractive.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/bin/pyinteractive.py .. _`pypy/config/`: https://bitbucket.org/pypy/pypy/src/default/pypy/config/ .. _`pypy/config/pypyoption.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/config/pypyoption.py -.. _`pypy/config/translationoption.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/config/translationoption.py .. _`pypy/doc/`: https://bitbucket.org/pypy/pypy/src/default/pypy/doc/ .. _`pypy/doc/config/`: https://bitbucket.org/pypy/pypy/src/default/pypy/doc/config/ .. _`pypy/doc/discussion/`: https://bitbucket.org/pypy/pypy/src/default/pypy/doc/discussion/ +.. _`pypy/goal/`: https://bitbucket.org/pypy/pypy/src/default/pypy/goal/ .. _`pypy/interpreter`: .. _`pypy/interpreter/`: https://bitbucket.org/pypy/pypy/src/default/pypy/interpreter/ .. _`pypy/interpreter/argument.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/interpreter/argument.py @@ -54,11 +49,8 @@ .. _`pypy/module`: .. _`pypy/module/`: https://bitbucket.org/pypy/pypy/src/default/pypy/module/ .. _`pypy/module/__builtin__/__init__.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/module/__builtin__/__init__.py -.. _`pypy/objspace`: .. _`pypy/objspace/`: https://bitbucket.org/pypy/pypy/src/default/pypy/objspace/ -.. _`pypy/objspace/flow`: .. _`pypy/objspace/flow/`: https://bitbucket.org/pypy/pypy/src/default/pypy/objspace/flow/ -.. _`pypy/objspace/flow/model.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/objspace/flow/model.py .. _`pypy/objspace/std`: .. _`pypy/objspace/std/`: https://bitbucket.org/pypy/pypy/src/default/pypy/objspace/std/ .. _`pypy/objspace/std/listtype.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/objspace/std/listtype.py @@ -70,49 +62,55 @@ .. _`pypy/objspace/std/transparent.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/objspace/std/transparent.py .. _`pypy/objspace/std/tupleobject.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/objspace/std/tupleobject.py .. _`pypy/objspace/std/tupletype.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/objspace/std/tupletype.py -.. _`pypy/rlib`: -.. _`pypy/rlib/`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/ -.. _`pypy/rlib/listsort.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/listsort.py -.. _`pypy/rlib/nonconst.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/nonconst.py -.. _`pypy/rlib/objectmodel.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/objectmodel.py -.. _`pypy/rlib/parsing/`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/parsing/ -.. _`pypy/rlib/parsing/tree.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/parsing/tree.py -.. _`pypy/rlib/rarithmetic.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/rarithmetic.py -.. _`pypy/rlib/rbigint.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/rbigint.py -.. _`pypy/rlib/rrandom.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/rrandom.py -.. _`pypy/rlib/rsocket.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/rsocket.py -.. _`pypy/rlib/streamio.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/streamio.py -.. _`pypy/rlib/test`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/test/ -.. _`pypy/rlib/unroll.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/unroll.py -.. _`pypy/rpython`: -.. _`pypy/rpython/`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/ -.. _`pypy/rpython/lltypesystem/`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/lltypesystem/ -.. _`pypy/rpython/lltypesystem/lltype.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/lltypesystem/lltype.py -.. _`pypy/rpython/memory/`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/memory/ -.. _`pypy/rpython/memory/gc/generation.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/memory/gc/generation.py -.. _`pypy/rpython/memory/gc/hybrid.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/memory/gc/hybrid.py -.. _`pypy/rpython/memory/gc/markcompact.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/memory/gc/markcompact.py -.. _`pypy/rpython/memory/gc/marksweep.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/memory/gc/marksweep.py -.. _`pypy/rpython/memory/gc/minimarkpage.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/memory/gc/minimarkpage.py -.. _`pypy/rpython/memory/gc/semispace.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/memory/gc/semispace.py -.. _`pypy/rpython/ootypesystem/`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/ootypesystem/ -.. _`pypy/rpython/ootypesystem/ootype.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/ootypesystem/ootype.py -.. _`pypy/rpython/rint.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/rint.py -.. _`pypy/rpython/rlist.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/rlist.py -.. _`pypy/rpython/rmodel.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/rmodel.py -.. _`pypy/rpython/rtyper.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/rtyper.py -.. _`pypy/rpython/test/test_llinterp.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/test/test_llinterp.py .. _`pypy/tool/`: https://bitbucket.org/pypy/pypy/src/default/pypy/tool/ .. _`pypy/tool/algo/`: https://bitbucket.org/pypy/pypy/src/default/pypy/tool/algo/ .. _`pypy/tool/pytest/`: https://bitbucket.org/pypy/pypy/src/default/pypy/tool/pytest/ -.. _`pypy/tool/traceconfig.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/tool/traceconfig.py -.. _`pypy/translator`: -.. _`pypy/translator/`: https://bitbucket.org/pypy/pypy/src/default/pypy/translator/ -.. _`pypy/translator/backendopt/`: https://bitbucket.org/pypy/pypy/src/default/pypy/translator/backendopt/ -.. _`pypy/translator/c/`: https://bitbucket.org/pypy/pypy/src/default/pypy/translator/c/ -.. _`pypy/translator/c/src/stacklet/`: https://bitbucket.org/pypy/pypy/src/default/pypy/translator/c/src/stacklet/ -.. _`pypy/translator/c/src/stacklet/stacklet.h`: https://bitbucket.org/pypy/pypy/src/default/pypy/translator/c/src/stacklet/stacklet.h -.. _`pypy/translator/cli/`: https://bitbucket.org/pypy/pypy/src/default/pypy/translator/cli/ -.. _`pypy/translator/goal/`: https://bitbucket.org/pypy/pypy/src/default/pypy/translator/goal/ -.. _`pypy/translator/jvm/`: https://bitbucket.org/pypy/pypy/src/default/pypy/translator/jvm/ -.. _`pypy/translator/tool/`: https://bitbucket.org/pypy/pypy/src/default/pypy/translator/tool/ +.. _`rpython/annotator`: +.. _`rpython/annotator/`: https://bitbucket.org/pypy/pypy/src/default/rpython/annotator/ +.. _`rpython/annotator/annrpython.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/annotator/annrpython.py +.. _`rpython/annotator/binaryop.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/annotator/binaryop.py +.. _`rpython/annotator/builtin.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/annotator/builtin.py +.. _`rpython/bin/translatorshell.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/bin/translatorshell.py +.. _`rpython/config/`: https://bitbucket.org/pypy/pypy/src/default/rpython/config/ +.. _`rpython/config/translationoption.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/config/translationoption.py +.. _`rpython/flowspace/`: https://bitbucket.org/pypy/pypy/src/default/rpython/flowspace/ +.. _`rpython/flowspace/model.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/flowspace/model.py +.. _`rpython/rlib`: +.. _`rpython/rlib/`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/ +.. _`rpython/rlib/listsort.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/listsort.py +.. _`rpython/rlib/nonconst.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/nonconst.py +.. _`rpython/rlib/objectmodel.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/objectmodel.py +.. _`rpython/rlib/parsing/`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/parsing/ +.. _`rpython/rlib/parsing/tree.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/parsing/tree.py +.. _`rpython/rlib/rarithmetic.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/rarithmetic.py +.. _`rpython/rlib/rbigint.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/rbigint.py +.. _`rpython/rlib/rrandom.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/rrandom.py +.. _`rpython/rlib/rsocket.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/rsocket.py +.. _`rpython/rlib/streamio.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/streamio.py +.. _`rpython/rlib/test`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/test/ +.. _`rpython/rlib/unroll.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/unroll.py +.. _`rpython/rtyper`: +.. _`rpython/rtyper/`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/ +.. _`rpython/rtyper/lltypesystem/`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/lltypesystem/ +.. _`rpython/rtyper/lltypesystem/lltype.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/lltypesystem/lltype.py +.. _`rpython/rtyper/memory/`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/memory/ +.. _`rpython/rtyper/memory/gc/generation.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/memory/gc/generation.py +.. _`rpython/rtyper/memory/gc/hybrid.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/memory/gc/hybrid.py +.. _`rpython/rtyper/memory/gc/minimarkpage.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/memory/gc/minimarkpage.py +.. _`rpython/rtyper/memory/gc/semispace.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/memory/gc/semispace.py +.. _`rpython/rtyper/ootypesystem/`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/ootypesystem/ +.. _`rpython/rtyper/ootypesystem/ootype.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/ootypesystem/ootype.py +.. _`rpython/rtyper/rint.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/rint.py +.. _`rpython/rtyper/rlist.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/rlist.py +.. _`rpython/rtyper/rmodel.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/rmodel.py +.. _`rpython/rtyper/rtyper.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/rtyper.py +.. _`rpython/rtyper/test/test_llinterp.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/test/test_llinterp.py +.. _`rpython/translator`: +.. _`rpython/translator/`: https://bitbucket.org/pypy/pypy/src/default/rpython/translator/ +.. _`rpython/translator/backendopt/`: https://bitbucket.org/pypy/pypy/src/default/rpython/translator/backendopt/ +.. _`rpython/translator/c/`: https://bitbucket.org/pypy/pypy/src/default/rpython/translator/c/ +.. _`rpython/translator/c/src/stacklet/`: https://bitbucket.org/pypy/pypy/src/default/rpython/translator/c/src/stacklet/ +.. _`rpython/translator/c/src/stacklet/stacklet.h`: https://bitbucket.org/pypy/pypy/src/default/rpython/translator/c/src/stacklet/stacklet.h +.. _`rpython/translator/cli/`: https://bitbucket.org/pypy/pypy/src/default/rpython/translator/cli/ +.. _`rpython/translator/jvm/`: https://bitbucket.org/pypy/pypy/src/default/rpython/translator/jvm/ +.. _`rpython/translator/tool/`: https://bitbucket.org/pypy/pypy/src/default/rpython/translator/tool/ diff --git a/pypy/doc/coding-guide.rst b/pypy/doc/coding-guide.rst --- a/pypy/doc/coding-guide.rst +++ b/pypy/doc/coding-guide.rst @@ -303,7 +303,7 @@ dicts with a unique key type only, provided it is hashable. Custom hash functions and custom equality will not be honored. - Use ``pypy.rlib.objectmodel.r_dict`` for custom hash functions. + Use ``rpython.rlib.objectmodel.r_dict`` for custom hash functions. **list comprehensions** @@ -328,7 +328,7 @@ **builtin functions** A number of builtin functions can be used. The precise set can be - found in `pypy/annotation/builtin.py`_ (see ``def builtin_xxx()``). + found in `rpython/annotator/builtin.py`_ (see ``def builtin_xxx()``). Some builtin functions may be limited in what they support, though. ``int, float, str, ord, chr``... are available as simple conversion @@ -365,7 +365,7 @@ We use normal integers for signed arithmetic. It means that before translation we get longs in case of overflow, and after translation we get a silent wrap-around. Whenever we need more control, we use the following -helpers (which live the `pypy/rlib/rarithmetic.py`_): +helpers (which live in `rpython/rlib/rarithmetic.py`_): **ovfcheck()** diff --git a/pypy/doc/configuration.rst b/pypy/doc/configuration.rst --- a/pypy/doc/configuration.rst +++ b/pypy/doc/configuration.rst @@ -188,7 +188,7 @@ toolchain`_ toolchain, have two separate sets of options. The translation toolchain options can be found on the ``config`` attribute of all ``TranslationContext`` -instances and are described in `pypy/config/translationoption.py`_. The interpreter options +instances and are described in `rpython/config/translationoption.py`_. The interpreter options are attached to the object space, also under the name ``config`` and are described in `pypy/config/pypyoption.py`_. diff --git a/pypy/doc/garbage_collection.rst b/pypy/doc/garbage_collection.rst --- a/pypy/doc/garbage_collection.rst +++ b/pypy/doc/garbage_collection.rst @@ -42,7 +42,7 @@ Two arenas of equal size, with only one arena in use and getting filled with new objects. When the arena is full, the live objects are copied into the other arena using Cheney's algorithm. The old arena is then -cleared. See `pypy/rpython/memory/gc/semispace.py`_. +cleared. See `rpython/rtyper/memory/gc/semispace.py`_. On Unix the clearing is done by reading ``/dev/zero`` into the arena, which is extremely memory efficient at least on Linux: it lets the @@ -55,7 +55,7 @@ Generational GC --------------- -This is a two-generations GC. See `pypy/rpython/memory/gc/generation.py`_. +This is a two-generations GC. See `rpython/rtyper/memory/gc/generation.py`_. It is implemented as a subclass of the Semispace copying collector. It adds a nursery, which is a chunk of the current semispace. Its size is @@ -86,7 +86,7 @@ Each generation is collected much less often than the previous one. The division of the generations is slightly more complicated than just nursery / semispace / external; see the diagram at the start of the -source code, in `pypy/rpython/memory/gc/hybrid.py`_. +source code, in `rpython/rtyper/memory/gc/hybrid.py`_. Mark & Compact GC ----------------- @@ -161,7 +161,7 @@ to the old stage. The dying case 2 objects are immediately freed. - The old stage is an area of memory containing old (small) objects. It - is handled by `pypy/rpython/memory/gc/minimarkpage.py`_. It is organized + is handled by `rpython/rtyper/memory/gc/minimarkpage.py`_. It is organized as "arenas" of 256KB or 512KB, subdivided into "pages" of 4KB or 8KB. Each page can either be free, or contain small objects of all the same size. Furthermore at any point in time each object location can be diff --git a/pypy/doc/getting-started-dev.rst b/pypy/doc/getting-started-dev.rst --- a/pypy/doc/getting-started-dev.rst +++ b/pypy/doc/getting-started-dev.rst @@ -172,23 +172,23 @@ ``xxxobject.py`` contain respectively the definition of the type and its (default) implementation. -* `pypy/translator`_ contains the code analysis and generation stuff. +* `rpython/translator`_ contains the code analysis and generation stuff. Start reading from translator.py, from which it should be easy to follow the pieces of code involved in the various translation phases. -* `pypy/annotation`_ contains the data model for the type annotation that +* `rpython/annotator`_ contains the data model for the type annotation that can be inferred about a graph. The graph "walker" that uses this is in - `pypy/annotation/annrpython.py`_. + `rpython/annotator/annrpython.py`_. -* `pypy/rpython`_ contains the code of the RPython typer. The typer transforms +* `rpython/rtyper`_ contains the code of the RPython typer. The typer transforms annotated flow graphs in a way that makes them very similar to C code so that they can be easy translated. The graph transformations are controlled - by the code in `pypy/rpython/rtyper.py`_. The object model that is used can - be found in `pypy/rpython/lltypesystem/lltype.py`_. For each RPython type + by the code in `rpython/rtyper/rtyper.py`_. The object model that is used can + be found in `rpython/rtyper/lltypesystem/lltype.py`_. For each RPython type there is a file rxxxx.py that contains the low level functions needed for this type. -* `pypy/rlib`_ contains the `RPython standard library`_, things that you can +* `rpython/rlib`_ contains the `RPython standard library`_, things that you can use from rpython. .. _`RPython standard library`: rlib.html @@ -319,10 +319,10 @@ Demos ------- -The `demo/`_ directory contains examples of various aspects of PyPy, -ranging from running regular Python programs (that we used as compliance goals) -over experimental distribution mechanisms to examples translating -sufficiently static programs into low level code. +The `example-interpreter`_ repository contains an example interpreter +written using the RPython translation toolchain. + +.. _`example-interpreter`: https://bitbucket.org/pypy/example-interpreter Additional Tools for running (and hacking) PyPy ----------------------------------------------- diff --git a/pypy/doc/index.rst b/pypy/doc/index.rst --- a/pypy/doc/index.rst +++ b/pypy/doc/index.rst @@ -217,17 +217,20 @@ Here is a fully referenced alphabetical two-level deep directory overview of PyPy: -================================ =========================================== +================================= ============================================ Directory explanation/links -================================ =========================================== +================================= ============================================ +`pypy/bin/`_ command-line scripts, mainly + `pypy/bin/pyinteractive.py`_ -`pypy/bin/`_ command-line scripts, mainly `pyinteractive.py`_ +`pypy/config/`_ handles the numerous options for building + and running PyPy -`pypy/config/`_ handles the numerous options for building and running PyPy +`pypy/doc/`_ text versions of PyPy developer + documentation -`pypy/doc/`_ text versions of PyPy developer documentation - -`pypy/doc/config/`_ documentation for the numerous translation options +`pypy/doc/config/`_ documentation for the numerous translation + options `pypy/doc/discussion/`_ drafts of ideas and documentation @@ -238,19 +241,24 @@ `pypy/interpreter/pyparser/`_ interpreter-level Python source parser -`pypy/interpreter/astcompiler/`_ interpreter-level bytecode compiler, via an AST - representation +`pypy/interpreter/astcompiler/`_ interpreter-level bytecode compiler, + via an AST representation -`pypy/module/`_ contains `mixed modules`_ implementing core modules with +`pypy/module/`_ contains `mixed modules`_ + implementing core modules with both application and interpreter level code. - Not all are finished and working. Use the ``--withmod-xxx`` - or ``--allworkingmodules`` translation options. + Not all are finished and working. Use + the ``--withmod-xxx`` + or ``--allworkingmodules`` translation + options. `pypy/objspace/`_ `object space`_ implementations -`pypy/objspace/std/`_ the StdObjSpace_ implementing CPython's objects and types +`pypy/objspace/std/`_ the StdObjSpace_ implementing CPython's + objects and types -`pypy/tool/`_ various utilities and hacks used from various places +`pypy/tool/`_ various utilities and hacks used + from various places `pypy/tool/algo/`_ general-purpose algorithmic and mathematic tools @@ -258,49 +266,58 @@ `pypy/tool/pytest/`_ support code for our `testing methods`_ -`rpython/annotator/`_ `type inferencing code`_ for `RPython`_ programs +`rpython/annotator/`_ `type inferencing code`_ for + `RPython`_ programs `rpython/config/`_ handles the numerous options for RPython -`rpython/flowspace/`_ the FlowObjSpace_ implementing `abstract interpretation`_ +`rpython/flowspace/`_ the FlowObjSpace_ implementing + `abstract interpretation`_ - -`rpython/rlib/`_ a `"standard library"`_ for RPython_ programs +`rpython/rlib/`_ a `"standard library"`_ for RPython_ + programs `rpython/rtyper/`_ the `RPython Typer`_ -`rpython/rtyper/lltypesystem/`_ the `low-level type system`_ for C-like backends +`rpython/rtyper/lltypesystem/`_ the `low-level type system`_ for + C-like backends -`rpython/rtyper/ootypesystem/`_ the `object-oriented type system`_ for OO backends +`rpython/rtyper/ootypesystem/`_ the `object-oriented type system`_ + for OO backends -`rpython/rtyper/memory/`_ the `garbage collector`_ construction framework +`rpython/rtyper/memory/`_ the `garbage collector`_ construction + framework `rpython/translator/`_ translation_ backends and support code -`rpython/translator/backendopt/`_ general optimizations that run before a backend generates code +`rpython/translator/backendopt/`_ general optimizations that run before a + backend generates code -`rpython/translator/c/`_ the `GenC backend`_, producing C code from an +`rpython/translator/c/`_ the `GenC backend`_, producing C code + from an RPython program (generally via the rtyper_) -`rpython/translator/cli/`_ the `CLI backend`_ for `.NET`_ (Microsoft CLR or Mono_) +`rpython/translator/cli/`_ the `CLI backend`_ for `.NET`_ + (Microsoft CLR or Mono_) -`pypy/goal/`_ our `main PyPy-translation scripts`_ live here +`pypy/goal/`_ our `main PyPy-translation scripts`_ + live here `rpython/translator/jvm/`_ the Java backend -`rpython/translator/tool/`_ helper tools for translation, including the Pygame - `graph viewer`_ +`rpython/translator/tool/`_ helper tools for translation -``*/test/`` many directories have a test subdirectory containing test +`dotviewer/`_ `graph viewer`_ + +``*/test/`` many directories have a test subdirectory + containing test modules (see `Testing in PyPy`_) -``_cache/`` holds cache files from internally `translating application - level to interpreterlevel`_ code. -================================ =========================================== +``_cache/`` holds cache files from various purposes +================================= ============================================ .. _`bytecode interpreter`: interpreter.html -.. _`translating application level to interpreterlevel`: geninterp.html .. _`Testing in PyPy`: coding-guide.html#testing-in-pypy .. _`mixed modules`: coding-guide.html#mixed-modules .. _`modules`: coding-guide.html#modules diff --git a/pypy/doc/rlib.rst b/pypy/doc/rlib.rst --- a/pypy/doc/rlib.rst +++ b/pypy/doc/rlib.rst @@ -7,18 +7,18 @@ .. contents:: -This page lists some of the modules in `pypy/rlib`_ together with some hints +This page lists some of the modules in `rpython/rlib`_ together with some hints for what they can be used for. The modules here will make up some general library useful for RPython programs (since most of the standard library modules are not RPython). Most of these modules are somewhat rough still and are likely to change at some point. Usually it is useful to look at the tests in -`pypy/rlib/test`_ to get an impression of how to use a module. +`rpython/rlib/test`_ to get an impression of how to use a module. ``listsort`` ============ -The `pypy/rlib/listsort.py`_ module contains an implementation of the timsort sorting algorithm +The `rpython/rlib/listsort.py`_ module contains an implementation of the timsort sorting algorithm (the sort method of lists is not RPython). To use it, subclass from the ``listsort.TimSort`` class and override the ``lt`` method to change the comparison behaviour. The constructor of ``TimSort`` takes a list as an @@ -30,7 +30,7 @@ ``nonconst`` ============ -The `pypy/rlib/nonconst.py`_ module is useful mostly for tests. The `flow object space`_ and +The `rpython/rlib/nonconst.py`_ module is useful mostly for tests. The `flow object space`_ and the `annotator`_ do quite some constant folding, which is sometimes not desired in a test. To prevent constant folding on a certain value, use the ``NonConst`` class. The constructor of ``NonConst`` takes an arbitrary value. The instance of @@ -44,7 +44,7 @@ ``objectmodel`` =============== -The `pypy/rlib/objectmodel.py`_ module is a mixed bag of various functionality. Some of the +The `rpython/rlib/objectmodel.py`_ module is a mixed bag of various functionality. Some of the more useful ones are: ``ComputedIntSymbolic``: @@ -94,7 +94,7 @@ ``rarithmetic`` =============== -The `pypy/rlib/rarithmetic.py`_ module contains functionality to handle the small differences +The `rpython/rlib/rarithmetic.py`_ module contains functionality to handle the small differences in the behaviour of arithmetic code in regular Python and RPython code. Most of them are already described in the `coding guide`_ @@ -104,7 +104,7 @@ ``rbigint`` =========== -The `pypy/rlib/rbigint.py`_ module contains a full RPython implementation of the Python ``long`` +The `rpython/rlib/rbigint.py`_ module contains a full RPython implementation of the Python ``long`` type (which itself is not supported in RPython). The ``rbigint`` class contains that implementation. To construct ``rbigint`` instances use the static methods ``fromint``, ``frombool``, ``fromfloat`` and ``fromdecimalstr``. To convert back @@ -118,7 +118,7 @@ ``rrandom`` =========== -The `pypy/rlib/rrandom.py`_ module contains an implementation of the mersenne twister random +The `rpython/rlib/rrandom.py`_ module contains an implementation of the mersenne twister random number generator. It contains one class ``Random`` which most importantly has a ``random`` method which returns a pseudo-random floating point number between 0.0 and 1.0. @@ -126,7 +126,7 @@ ``rsocket`` =========== -The `pypy/rlib/rsocket.py`_ module contains an RPython implementation of the functionality of +The `rpython/rlib/rsocket.py`_ module contains an RPython implementation of the functionality of the socket standard library with a slightly different interface. The difficulty with the Python socket API is that addresses are not "well-typed" objects: depending on the address family they are tuples, or strings, and @@ -137,7 +137,7 @@ ``streamio`` ============ -The `pypy/rlib/streamio.py`_ contains an RPython stream I/O implementation (which was started +The `rpython/rlib/streamio.py`_ contains an RPython stream I/O implementation (which was started by Guido van Rossum as `sio.py`_ in the CPython sandbox as a prototype for the upcoming new file implementation in Python 3000). @@ -146,7 +146,7 @@ ``unroll`` ========== -The `pypy/rlib/unroll.py`_ module most importantly contains the function ``unrolling_iterable`` +The `rpython/rlib/unroll.py`_ module most importantly contains the function ``unrolling_iterable`` which wraps an iterator. Looping over the iterator in RPython code will not produce a loop in the resulting flow graph but will unroll the loop instead. @@ -154,7 +154,7 @@ ``parsing`` =========== -The `pypy/rlib/parsing/`_ module is a still in-development module to generate tokenizers and +The `rpython/rlib/parsing/`_ module is a still in-development module to generate tokenizers and parsers in RPython. It is still highly experimental and only really used by the `Prolog interpreter`_ (although in slightly non-standard ways). The easiest way to specify a tokenizer/grammar is to write it down using regular expressions and @@ -204,7 +204,7 @@ anything except a. To parse a regular expression and to get a matcher for it, you can use the -function ``make_runner(s)`` in the ``pypy.rlib.parsing.regexparse`` module. It +function ``make_runner(s)`` in the ``rpython.rlib.parsing.regexparse`` module. It returns a object with a ``recognize(input)`` method that returns True or False depending on whether ``input`` matches the string or not. @@ -213,7 +213,7 @@ EBNF ---- -To describe a tokenizer and a grammar the ``pypy.rlib.parsing.ebnfparse`` +To describe a tokenizer and a grammar the ``rpython.rlib.parsing.ebnfparse`` defines a syntax for doing that. The syntax file contains a sequence or rules. Every rule either describes a @@ -295,7 +295,7 @@ The parsing process builds up a tree consisting of instances of ``Symbol`` and ``Nonterminal``, the former corresponding to tokens, the latter to nonterminal -symbols. Both classes live in the `pypy/rlib/parsing/tree.py`_ module. You can use +symbols. Both classes live in the `rpython/rlib/parsing/tree.py`_ module. You can use the ``view()`` method ``Nonterminal`` instances to get a pygame view of the parse tree. @@ -310,7 +310,7 @@ ++++++++ To write tree visitors for the parse trees that are RPython, there is a special -baseclass ``RPythonVisitor`` in `pypy/rlib/parsing/tree.py`_ to use. If your +baseclass ``RPythonVisitor`` in `rpython/rlib/parsing/tree.py`_ to use. If your class uses this, it will grow a ``dispatch(node)`` method, that calls an appropriate ``visit_`` method, depending on the ``node`` argument. Here the is replaced by the ``symbol`` attribute of the visited node. diff --git a/pypy/doc/rtyper.rst b/pypy/doc/rtyper.rst --- a/pypy/doc/rtyper.rst +++ b/pypy/doc/rtyper.rst @@ -4,7 +4,7 @@ .. contents:: -The RPython Typer lives in the directory `pypy/rpython/`_. +The RPython Typer lives in the directory `rpython/rtyper/`_. Overview @@ -52,7 +52,7 @@ where -- in C notation -- all three variables v1, v2 and v3 are typed ``int``. This is done by attaching an attribute ``concretetype`` to v1, v2 and v3 (which might be instances of Variable or possibly Constant). In our model, -this ``concretetype`` is ``pypy.rpython.lltypesystem.lltype.Signed``. Of +this ``concretetype`` is ``rpython.rtyper.lltypesystem.lltype.Signed``. Of course, the purpose of replacing the operation called ``add`` with ``int_add`` is that code generators no longer have to worry about what kind of addition (or concatenation maybe?) it means. @@ -66,7 +66,7 @@ each operation. In both cases the analysis of an operation depends on the annotations of its input arguments. This is reflected in the usage of the same ``__extend__`` syntax in the source files (compare e.g. -`pypy/annotation/binaryop.py`_ and `pypy/rpython/rint.py`_). +`rpython/annotator/binaryop.py`_ and `rpython/rtyper/rint.py`_). The analogy stops here, though: while it runs, the Annotator is in the middle of computing the annotations, so it might need to reflow and generalize until @@ -104,7 +104,7 @@ implementations for the same high-level operations. This is the reason for turning representations into explicit objects. -The base Repr class is defined in `pypy/rpython/rmodel.py`_. Most of the +The base Repr class is defined in `rpython/rtyper/rmodel.py`_. Most of the ``rpython/r*.py`` files define one or a few subclasses of Repr. The method getrepr() of the RTyper will build and cache a single Repr instance per SomeXxx() instance; moreover, two SomeXxx() instances that are equal get the @@ -131,9 +131,9 @@ The RPython Typer uses a standard low-level model which we believe can correspond rather directly to various target languages such as C. This model is implemented in the first part of -`pypy/rpython/lltypesystem/lltype.py`_. +`rpython/rtyper/lltypesystem/lltype.py`_. -The second part of `pypy/rpython/lltypesystem/lltype.py`_ is a runnable +The second part of `rpython/rtyper/lltypesystem/lltype.py`_ is a runnable implementation of these types, for testing purposes. It allows us to write and test plain Python code using a malloc() function to obtain and manipulate structures and arrays. This is useful for example to implement and test @@ -147,7 +147,7 @@ Here is a quick tour: - >>> from pypy.rpython.lltypesystem.lltype import * + >>> from rpython.rtyper.lltypesystem.lltype import * Here are a few primitive low-level types, and the typeOf() function to figure them out: @@ -191,7 +191,7 @@ types like list in this elementary world. The ``malloc()`` function is a kind of placeholder, which must eventually be provided by the code generator for the target platform; but as we have just seen its Python implementation in -`pypy/rpython/lltypesystem/lltype.py`_ works too, which is primarily useful for +`rpython/rtyper/lltypesystem/lltype.py`_ works too, which is primarily useful for testing, interactive exploring, etc. The argument to ``malloc()`` is the structure type directly, but it returns a @@ -245,7 +245,7 @@ +++++++++++++++ Structure types are built as instances of -``pypy.rpython.lltypesystem.lltype.Struct``:: +``rpython.rtyper.lltypesystem.lltype.Struct``:: MyStructType = Struct('somename', ('field1', Type1), ('field2', Type2)...) MyStructType = GcStruct('somename', ('field1', Type1), ('field2', Type2)...) @@ -277,7 +277,7 @@ +++++++++++ An array type is built as an instance of -``pypy.rpython.lltypesystem.lltype.Array``:: +``rpython.rtyper.lltypesystem.lltype.Array``:: MyIntArray = Array(Signed) MyOtherArray = Array(MyItemType) @@ -316,7 +316,7 @@ with care: the bigger structure of which they are part of could be freed while the Ptr to the substructure is still in use. In general, it is a good idea to avoid passing around pointers to inlined substructures of malloc()ed structures. -(The testing implementation of `pypy/rpython/lltypesystem/lltype.py`_ checks to some +(The testing implementation of `rpython/rtyper/lltypesystem/lltype.py`_ checks to some extent that you are not trying to use a pointer to a structure after its container has been freed, using weak references. But pointers to non-GC structures are not officially meant to be weak references: using them after what @@ -429,7 +429,7 @@ change needed to the Annotator to allow it to perform type inference of our very-low-level snippets of code. -See for example `pypy/rpython/rlist.py`_. +See for example `rpython/rtyper/rlist.py`_. .. _`oo type`: @@ -441,10 +441,10 @@ targeting low level backends such as C, but it is not good enough for targeting higher level backends such as .NET CLI or Java JVM, so a new object oriented model has been introduced. This model is -implemented in the first part of `pypy/rpython/ootypesystem/ootype.py`_. +implemented in the first part of `rpython/rtyper/ootypesystem/ootype.py`_. As for the low-level typesystem, the second part of -`pypy/rpython/ootypesystem/ootype.py`_ is a runnable implementation of +`rpython/rtyper/ootypesystem/ootype.py`_ is a runnable implementation of these types, for testing purposes. @@ -751,7 +751,7 @@ The LLInterpreter is a simple piece of code that is able to interpret flow graphs. This is very useful for testing purposes, especially if you work on the RPython Typer. The most useful interface for it is the ``interpret`` -function in the file `pypy/rpython/test/test_llinterp.py`_. It takes as +function in the file `rpython/rtyper/test/test_llinterp.py`_. It takes as arguments a function and a list of arguments with which the function is supposed to be called. Then it generates the flow graph, annotates it according to the types of the arguments you passed to it and runs the diff --git a/pypy/doc/stackless.rst b/pypy/doc/stackless.rst --- a/pypy/doc/stackless.rst +++ b/pypy/doc/stackless.rst @@ -29,7 +29,7 @@ on 32-bit or a complete megabyte on 64-bit. Moreover, the feature is only available (so far) on x86 and x86-64 CPUs; for other CPUs you need to add a short page of custom assembler to -`pypy/translator/c/src/stacklet/`_. +`rpython/translator/c/src/stacklet/`_. Theory @@ -271,7 +271,7 @@ Continulets are internally implemented using stacklets, which is the generic RPython-level building block for "one-shot continuations". For more information about them please see the documentation in the C source -at `pypy/translator/c/src/stacklet/stacklet.h`_. +at `rpython/translator/c/src/stacklet/stacklet.h`_. The module ``pypy.rlib.rstacklet`` is a thin wrapper around the above functions. The key point is that new() and switch() always return a diff --git a/pypy/doc/tool/makeref.py b/pypy/doc/tool/makeref.py --- a/pypy/doc/tool/makeref.py +++ b/pypy/doc/tool/makeref.py @@ -1,10 +1,9 @@ import py -py.path.local(__file__) import pypy -pypydir = py.path.local(pypy.__file__).dirpath() -distdir = pypydir.dirpath() -issue_url = 'http://codespeak.net/issue/pypy-dev/' +pypydir = py.path.local(pypy.__file__).join('..') +distdir = pypydir.dirpath() +issue_url = 'http://bugs.pypy.org/issue/pypy-dev/' bitbucket_url = 'https://bitbucket.org/pypy/pypy/src/default/' import urllib2, posixpath diff --git a/pypy/doc/translation.rst b/pypy/doc/translation.rst --- a/pypy/doc/translation.rst +++ b/pypy/doc/translation.rst @@ -90,7 +90,7 @@ (although these steps are not quite as distinct as you might think from this presentation). -There is an `interactive interface`_ called `pypy/bin/translatorshell.py`_ to the +There is an `interactive interface`_ called `rpython/bin/translatorshell.py`_ to the translation process which allows you to interactively work through these stages. @@ -116,7 +116,7 @@ which are the basic data structures of the translation process. -All these types are defined in `pypy/objspace/flow/model.py`_ (which is a rather +All these types are defined in `rpython/flowspace/model.py`_ (which is a rather important module in the PyPy source base, to reinforce the point). The flow graph of a function is represented by the class ``FunctionGraph``. diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst --- a/pypy/doc/whatsnew-head.rst +++ b/pypy/doc/whatsnew-head.rst @@ -65,3 +65,6 @@ .. branch: signal-and-thread Add "__pypy__.thread.signals_enabled", a context manager. Can be used in a non-main thread to enable the processing of signal handlers in that thread. + +.. branch: coding-guide-update-rlib-refs +.. branch: rlib-doc-rpython-refs diff --git a/rpython/jit/backend/x86/test/test_zrpy_gc.py b/rpython/jit/backend/x86/test/test_zrpy_gc.py --- a/rpython/jit/backend/x86/test/test_zrpy_gc.py +++ b/rpython/jit/backend/x86/test/test_zrpy_gc.py @@ -5,10 +5,9 @@ """ import weakref -import py, os -from rpython.annotator import policy as annpolicy +import os from rpython.rlib import rgc -from rpython.rtyper.lltypesystem import lltype, llmemory, rffi +from rpython.rtyper.lltypesystem import lltype from rpython.rlib.jit import JitDriver, dont_look_inside from rpython.rlib.jit import elidable, unroll_safe from rpython.jit.backend.llsupport.gc import GcLLDescr_framework diff --git a/rpython/jit/backend/x86/test/test_zrpy_releasegil.py b/rpython/jit/backend/x86/test/test_zrpy_releasegil.py --- a/rpython/jit/backend/x86/test/test_zrpy_releasegil.py +++ b/rpython/jit/backend/x86/test/test_zrpy_releasegil.py @@ -1,13 +1,13 @@ from rpython.rtyper.lltypesystem import lltype, llmemory, rffi from rpython.rlib.jit import dont_look_inside +from rpython.rlib.objectmodel import invoke_around_extcall from rpython.jit.metainterp.optimizeopt import ALL_OPTS_NAMES -from rpython.rlib.libffi import CDLL, types, ArgChain, clibffi -from rpython.rtyper.lltypesystem.ll2ctypes import libc_name from rpython.rtyper.annlowlevel import llhelper from rpython.jit.backend.x86.test.test_zrpy_gc import BaseFrameworkTests from rpython.jit.backend.x86.test.test_zrpy_gc import check +from rpython.tool.udir import udir class ReleaseGILTests(BaseFrameworkTests): @@ -15,35 +15,33 @@ def define_simple(self): class Glob: - pass + def __init__(self): + self.event = 0 glob = Glob() # - def f42(n): - c_strchr = glob.c_strchr - raw = rffi.str2charp("foobar" + chr((n & 63) + 32)) - argchain = ArgChain() - argchain = argchain.arg(rffi.cast(lltype.Signed, raw)) - argchain = argchain.arg(rffi.cast(rffi.INT, ord('b'))) - res = c_strchr.call(argchain, rffi.CCHARP) - check(rffi.charp2str(res) == "bar" + chr((n & 63) + 32)) - rffi.free_charp(raw) - # + + c_strchr = rffi.llexternal('strchr', [rffi.CCHARP, lltype.Signed], + rffi.CCHARP) + + def func(): + glob.event += 1 + def before(n, x): - libc = CDLL(libc_name) - c_strchr = libc.getpointer('strchr', [types.pointer, types.sint], - types.pointer) - glob.c_strchr = c_strchr + invoke_around_extcall(func, func) return (n, None, None, None, None, None, None, None, None, None, None, None) # def f(n, x, *args): - f42(n) + a = rffi.str2charp(str(n)) + c_strchr(a, ord('0')) + lltype.free(a, flavor='raw') n -= 1 return (n, x) + args return before, f, None def test_simple(self): self.run('simple') + assert 'call_release_gil' in udir.join('TestCompileFramework.log').read() def define_close_stack(self): # @@ -66,30 +64,23 @@ @dont_look_inside def free1(p): llmemory.raw_free(p) + + c_qsort = rffi.llexternal('qsort', [rffi.VOIDP, rffi.SIZE_T, + rffi.SIZE_T, CALLBACK], lltype.Void) # def f42(): length = len(glob.lst) - c_qsort = glob.c_qsort raw = alloc1() fn = llhelper(CALLBACK, rffi._make_wrapper_for(CALLBACK, callback)) - argchain = ArgChain() - argchain = argchain.arg(rffi.cast(lltype.Signed, raw)) - argchain = argchain.arg(rffi.cast(rffi.SIZE_T, 2)) - argchain = argchain.arg(rffi.cast(rffi.SIZE_T, 8)) - argchain = argchain.arg(rffi.cast(lltype.Signed, fn)) - c_qsort.call(argchain, lltype.Void) + c_qsort(rffi.cast(rffi.VOIDP, raw), rffi.cast(rffi.SIZE_T, 2), + rffi.cast(rffi.SIZE_T, 8), fn) free1(raw) check(len(glob.lst) > length) del glob.lst[:] # def before(n, x): - libc = CDLL(libc_name) - types_size_t = clibffi.cast_type_to_ffitype(rffi.SIZE_T) - c_qsort = libc.getpointer('qsort', [types.pointer, types_size_t, - types_size_t, types.pointer], - types.void) - glob.c_qsort = c_qsort glob.lst = [] + return (n, None, None, None, None, None, None, None, None, None, None, None) # @@ -101,6 +92,7 @@ def test_close_stack(self): self.run('close_stack') + assert 'call_release_gil' in udir.join('TestCompileFramework.log').read() class TestShadowStack(ReleaseGILTests): diff --git a/rpython/jit/metainterp/pyjitpl.py b/rpython/jit/metainterp/pyjitpl.py --- a/rpython/jit/metainterp/pyjitpl.py +++ b/rpython/jit/metainterp/pyjitpl.py @@ -1082,7 +1082,7 @@ def opimpl_debug_fatalerror(self, box): from rpython.rtyper.lltypesystem import rstr, lloperation msg = box.getref(lltype.Ptr(rstr.STR)) - lloperation.llop.debug_fatalerror(msg) + lloperation.llop.debug_fatalerror(lltype.Void, msg) @arguments("box", "box", "box", "box", "box") def opimpl_jit_debug(self, stringbox, arg1box, arg2box, arg3box, arg4box): diff --git a/rpython/rtyper/lltypesystem/rdict.py b/rpython/rtyper/lltypesystem/rdict.py --- a/rpython/rtyper/lltypesystem/rdict.py +++ b/rpython/rtyper/lltypesystem/rdict.py @@ -385,48 +385,60 @@ # be direct_call'ed from rtyped flow graphs, which means that they will # get flowed and annotated, mostly with SomePtr. + at objectmodel.enforceargs(None, int) def ll_everused_from_flag(entries, i): return entries[i].f_everused + at objectmodel.enforceargs(None, int) def ll_everused_from_key(entries, i): return bool(entries[i].key) + at objectmodel.enforceargs(None, int) def ll_everused_from_value(entries, i): return bool(entries[i].value) + at objectmodel.enforceargs(None, int) def ll_valid_from_flag(entries, i): return entries[i].f_valid + at objectmodel.enforceargs(None, int) def ll_mark_deleted_in_flag(entries, i): entries[i].f_valid = False + at objectmodel.enforceargs(None, int) def ll_valid_from_key(entries, i): ENTRIES = lltype.typeOf(entries).TO dummy = ENTRIES.dummy_obj.ll_dummy_value return entries.everused(i) and entries[i].key != dummy + at objectmodel.enforceargs(None, int) def ll_mark_deleted_in_key(entries, i): ENTRIES = lltype.typeOf(entries).TO dummy = ENTRIES.dummy_obj.ll_dummy_value entries[i].key = dummy + at objectmodel.enforceargs(None, int) def ll_valid_from_value(entries, i): ENTRIES = lltype.typeOf(entries).TO dummy = ENTRIES.dummy_obj.ll_dummy_value return entries.everused(i) and entries[i].value != dummy + at objectmodel.enforceargs(None, int) def ll_mark_deleted_in_value(entries, i): ENTRIES = lltype.typeOf(entries).TO dummy = ENTRIES.dummy_obj.ll_dummy_value entries[i].value = dummy + at objectmodel.enforceargs(None, int) def ll_hash_from_cache(entries, i): return entries[i].f_hash + at objectmodel.enforceargs(None, int) def ll_hash_recomputed(entries, i): ENTRIES = lltype.typeOf(entries).TO return ENTRIES.fasthashfn(entries[i].key) + at objectmodel.enforceargs(None, int) def ll_get_value(d, i): return d.entries[i].value diff --git a/rpython/rtyper/lltypesystem/rlist.py b/rpython/rtyper/lltypesystem/rlist.py --- a/rpython/rtyper/lltypesystem/rlist.py +++ b/rpython/rtyper/lltypesystem/rlist.py @@ -419,6 +419,7 @@ def __init__(self, r_list): self.r_list = r_list + self.external_item_repr = r_list.external_item_repr self.lowleveltype = Ptr(GcStruct('listiter', ('list', r_list.lowleveltype), ('index', Signed))) diff --git a/rpython/rtyper/lltypesystem/rstr.py b/rpython/rtyper/lltypesystem/rstr.py --- a/rpython/rtyper/lltypesystem/rstr.py +++ b/rpython/rtyper/lltypesystem/rstr.py @@ -1054,15 +1054,18 @@ def __init__(self): self.ll_striter = ll_striter self.ll_strnext = ll_strnext + self.ll_getnextindex = ll_getnextindex class StringIteratorRepr(BaseStringIteratorRepr): + external_item_repr = char_repr lowleveltype = Ptr(GcStruct('stringiter', ('string', string_repr.lowleveltype), ('index', Signed))) class UnicodeIteratorRepr(BaseStringIteratorRepr): + external_item_repr = unichar_repr lowleveltype = Ptr(GcStruct('unicodeiter', ('string', unicode_repr.lowleveltype), ('index', Signed))) @@ -1087,6 +1090,9 @@ iter.index = index + 1 return chars[index] +def ll_getnextindex(iter): + return iter.index + string_repr.iterator_repr = StringIteratorRepr() unicode_repr.iterator_repr = UnicodeIteratorRepr() diff --git a/rpython/rtyper/ootypesystem/rstr.py b/rpython/rtyper/ootypesystem/rstr.py --- a/rpython/rtyper/ootypesystem/rstr.py +++ b/rpython/rtyper/ootypesystem/rstr.py @@ -428,14 +428,17 @@ class StringIteratorRepr(AbstractStringIteratorRepr): + external_item_repr = char_repr lowleveltype = ootype.Record({'string': string_repr.lowleveltype, 'index': ootype.Signed}) def __init__(self): self.ll_striter = ll_striter self.ll_strnext = ll_strnext + self.ll_getnextindex = ll_getnextindex class UnicodeIteratorRepr(AbstractStringIteratorRepr): + external_item_repr = unichar_repr lowleveltype = ootype.Record({'string': unicode_repr.lowleveltype, 'index': ootype.Signed}) @@ -463,6 +466,9 @@ iter.index = index + 1 return string.ll_stritem_nonneg(index) +def ll_getnextindex(iter): + return iter.index + StringRepr.string_iterator_repr = StringIteratorRepr() UnicodeRepr.string_iterator_repr = UnicodeIteratorRepr() diff --git a/rpython/rtyper/rclass.py b/rpython/rtyper/rclass.py --- a/rpython/rtyper/rclass.py +++ b/rpython/rtyper/rclass.py @@ -395,7 +395,7 @@ assert not s_attr.is_constant() if '__iter__' in self.allinstancefields: raise Exception("__iter__ on instance disallowed") - r_method = self.rtyper.makerepr(s_attr) + r_method = self.rtyper.getrepr(s_attr) r_method.get_method_from_instance(self, vinst, hop.llops) hop2 = hop.copy() hop2.spaceop.opname = 'simple_call' diff --git a/rpython/rtyper/rptr.py b/rpython/rtyper/rptr.py --- a/rpython/rtyper/rptr.py +++ b/rpython/rtyper/rptr.py @@ -23,6 +23,8 @@ def rtyper_makerepr(self, rtyper): return InteriorPtrRepr(self.ll_ptrtype) + def rtyper_makekey(self): + return self.__class__, self.ll_ptrtype class PtrRepr(Repr): @@ -345,3 +347,10 @@ if r_from.lowleveltype == r_to.lowleveltype: return v return NotImplemented + +class __extend__(pairtype(InteriorPtrRepr, InteriorPtrRepr)): + + def convert_from_to((r_from, r_to), v, llops): + if r_from.__dict__ == r_to.__dict__: + return v + return NotImplemented diff --git a/rpython/rtyper/rrange.py b/rpython/rtyper/rrange.py --- a/rpython/rtyper/rrange.py +++ b/rpython/rtyper/rrange.py @@ -207,7 +207,7 @@ v_index = hop.gendirectcall(self.ll_getnextindex, v_enumerate) hop2 = hop.copy() hop2.args_r = [self.r_baseiter] - r_item_src = self.r_baseiter.r_list.external_item_repr + r_item_src = self.r_baseiter.external_item_repr r_item_dst = hop.r_result.items_r[1] v_item = self.r_baseiter.rtype_next(hop2) v_item = hop.llops.convertvar(v_item, r_item_src, r_item_dst) diff --git a/rpython/rtyper/test/test_rptr.py b/rpython/rtyper/test/test_rptr.py --- a/rpython/rtyper/test/test_rptr.py +++ b/rpython/rtyper/test/test_rptr.py @@ -336,6 +336,21 @@ res = interpret(f, []) assert res == 1 +def test_interior_ptr_convert(): + S = lltype.Struct("S", ("x", lltype.Signed)) + T = lltype.GcArray(S) + def f(i): + t = lltype.malloc(T, 2) + if i: + x = t[0] + else: + x = t[1] + x.x = 3 + return t[0].x + + res = interpret(f, [13]) + assert res == 3 + def test_interior_ptr_with_field_and_index(): S = lltype.Struct("S", ('x', lltype.Signed)) T = lltype.GcStruct("T", ('items', lltype.Array(S))) diff --git a/rpython/rtyper/test/test_rstr.py b/rpython/rtyper/test/test_rstr.py --- a/rpython/rtyper/test/test_rstr.py +++ b/rpython/rtyper/test/test_rstr.py @@ -1035,6 +1035,17 @@ got = self.interpret(f, [7]) assert self.ll_to_string(got) == 'None' + def test_enumerate(self): + const = self.const + def fn(n): + s = const('abcde') + for i, x in enumerate(s): + if i == n: + return x + return 'x' + res = self.interpret(fn, [2]) + assert res == 'c' + def FIXME_test_str_to_pystringobj(): def f(n): From noreply at buildbot.pypy.org Thu Feb 21 22:41:58 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Thu, 21 Feb 2013 22:41:58 +0100 (CET) Subject: [pypy-commit] pypy py3k: utilize the new rpython enumerate on strs Message-ID: <20130221214158.0EEBE1C124F@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61564:af2f29a59d00 Date: 2013-02-21 12:56 -0800 http://bitbucket.org/pypy/pypy/changeset/af2f29a59d00/ Log: utilize the new rpython enumerate on strs diff --git a/pypy/module/__builtin__/compiling.py b/pypy/module/__builtin__/compiling.py --- a/pypy/module/__builtin__/compiling.py +++ b/pypy/module/__builtin__/compiling.py @@ -82,13 +82,11 @@ "string, bytes or code", consts.PyCF_SOURCE_IS_UTF8) # source.lstrip(' \t') - i = 0 - for c in source: + for i, c in enumerate(source): if c not in ' \t': if i: source = source[i:] break - i += 1 ec = space.getexecutioncontext() code = ec.compiler.compile(source, "", 'eval', flags) From noreply at buildbot.pypy.org Thu Feb 21 22:52:55 2013 From: noreply at buildbot.pypy.org (mattip) Date: Thu, 21 Feb 2013 22:52:55 +0100 (CET) Subject: [pypy-commit] pypy numpy-unify-methods: rename and comment for clarity (hopefully) Message-ID: <20130221215255.619631C1265@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: numpy-unify-methods Changeset: r61566:b286c50e65c2 Date: 2013-02-21 23:32 +0200 http://bitbucket.org/pypy/pypy/changeset/b286c50e65c2/ Log: rename and comment for clarity (hopefully) diff --git a/pypy/module/micronumpy/test/test_ufuncs.py b/pypy/module/micronumpy/test/test_ufuncs.py --- a/pypy/module/micronumpy/test/test_ufuncs.py +++ b/pypy/module/micronumpy/test/test_ufuncs.py @@ -83,34 +83,37 @@ assert min_c_b[i] == min(b[i], c) def test_scalar(self): + # tests that calling all available ufuncs on scalars, none will + # raise uncaught interp-level exceptions, + # and those that are uncallable can be accounted for. import _numpypy as np - def missing_ufuncs(v): - missing = [] + def find_uncallable_ufuncs(v): + uncallable = [] i = 0 for s in dir(np): u = getattr(np, s) if isinstance(u, np.ufunc) and u.nin < 2: try: u(a) - except TypeError, e: + except TypeError: #assert e.message.startswith('ufunc') - missing.append(s) + uncallable.append(s) i+= 1 assert i == 47 #numpy 1.7.0 - return missing + return uncallable a = np.array(0,'int64') - missing = missing_ufuncs(a) - assert len(missing) == 0 + uncallable = find_uncallable_ufuncs(a) + assert len(uncallable) == 0 a = np.array(True,'bool') - missing = missing_ufuncs(a) - assert len(missing) == 0 or missing == ['sign'] # numpy 1.7.0 + uncallable = find_uncallable_ufuncs(a) + assert len(uncallable) == 0 or uncallable == ['sign'] # numpy 1.7.0 a = np.array(1.0,'float') - missing = missing_ufuncs(a) - assert len(missing) == 2 and set(missing) == set(['bitwise_not', 'invert']) + uncallable = find_uncallable_ufuncs(a) + assert len(uncallable) == 2 and set(uncallable) == set(['bitwise_not', 'invert']) a = np.array(1.0,'complex') - missing = missing_ufuncs(a) - assert len(missing) == 14 - assert set(missing) == \ + uncallable = find_uncallable_ufuncs(a) + assert len(uncallable) == 14 + assert set(uncallable) == \ set(['bitwise_not', 'ceil', 'deg2rad', 'degrees', 'fabs', 'floor', 'rad2deg', 'invert', 'spacing', 'radians', 'frexp', 'signbit', 'modf', 'trunc']) From noreply at buildbot.pypy.org Thu Feb 21 22:52:54 2013 From: noreply at buildbot.pypy.org (mattip) Date: Thu, 21 Feb 2013 22:52:54 +0100 (CET) Subject: [pypy-commit] pypy numpy-unify-methods: merge default into branch Message-ID: <20130221215254.325141C124F@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: numpy-unify-methods Changeset: r61565:fdedca0a97ab Date: 2013-02-21 23:20 +0200 http://bitbucket.org/pypy/pypy/changeset/fdedca0a97ab/ Log: merge default into branch diff too long, truncating to 2000 out of 5765 lines diff --git a/lib-python/2.7/test/test_generators.py b/lib-python/2.7/test/test_generators.py --- a/lib-python/2.7/test/test_generators.py +++ b/lib-python/2.7/test/test_generators.py @@ -1501,9 +1501,7 @@ """ coroutine_tests = """\ -A helper function to call gc.collect() without printing ->>> import gc ->>> def gc_collect(): gc.collect() +>>> from test.test_support import gc_collect Sending a value into a started generator: @@ -1823,8 +1821,7 @@ references. We add it to the standard suite so the routine refleak-tests would trigger if it starts being uncleanable again. ->>> import gc ->>> def gc_collect(): gc.collect() +>>> from test.test_support import gc_collect >>> import itertools >>> def leak(): diff --git a/lib_pypy/datetime.py b/lib_pypy/datetime.py --- a/lib_pypy/datetime.py +++ b/lib_pypy/datetime.py @@ -271,6 +271,8 @@ raise ValueError("%s()=%d, must be in -1439..1439" % (name, offset)) def _check_int_field(value): + if isinstance(value, int): + return value if not isinstance(value, float): try: value = value.__int__() @@ -279,7 +281,7 @@ else: if isinstance(value, (int, long)): return value - raise TypeError('integer argument expected') + raise TypeError('an integer is required') def _check_date_fields(year, month, day): year = _check_int_field(year) @@ -457,6 +459,8 @@ felt like it. """ + __slots__ = '_days', '_seconds', '_microseconds' + def __new__(cls, days=0, seconds=0, microseconds=0, # XXX The following should only be used as keyword args: milliseconds=0, minutes=0, hours=0, weeks=0): @@ -770,6 +774,8 @@ year, month, day """ + __slots__ = '_year', '_month', '_day' + def __new__(cls, year, month=None, day=None): """Constructor. @@ -777,7 +783,7 @@ year, month, day (required, base 1) """ - if isinstance(year, str): + if isinstance(year, str) and len(year) == 4: # Pickle support self = object.__new__(cls) self.__setstate(year) @@ -1063,6 +1069,8 @@ Subclasses must override the name(), utcoffset() and dst() methods. """ + __slots__ = () + def tzname(self, dt): "datetime -> string name of time zone." raise NotImplementedError("tzinfo subclass must override tzname()") @@ -1155,6 +1163,8 @@ hour, minute, second, microsecond, tzinfo """ + __slots__ = '_hour', '_minute', '_second', '_microsecond', '_tzinfo' + def __new__(cls, hour=0, minute=0, second=0, microsecond=0, tzinfo=None): """Constructor. @@ -1457,9 +1467,11 @@ instance of a tzinfo subclass. The remaining arguments may be ints or longs. """ + __slots__ = date.__slots__ + time.__slots__ + def __new__(cls, year, month=None, day=None, hour=0, minute=0, second=0, microsecond=0, tzinfo=None): - if isinstance(year, str): + if isinstance(year, str) and len(year) == 10: # Pickle support self = date.__new__(cls, year[:4]) self.__setstate(year, month) diff --git a/pypy/doc/_ref.txt b/pypy/doc/_ref.txt --- a/pypy/doc/_ref.txt +++ b/pypy/doc/_ref.txt @@ -1,24 +1,19 @@ .. _`ctypes_configure/doc/sample.py`: https://bitbucket.org/pypy/pypy/src/default/ctypes_configure/doc/sample.py -.. _`demo/`: https://bitbucket.org/pypy/pypy/src/default/demo/ +.. _`dotviewer/`: https://bitbucket.org/pypy/pypy/src/default/dotviewer/ .. _`lib-python/`: https://bitbucket.org/pypy/pypy/src/default/lib-python/ .. _`lib-python/2.7/dis.py`: https://bitbucket.org/pypy/pypy/src/default/lib-python/2.7/dis.py .. _`lib_pypy/`: https://bitbucket.org/pypy/pypy/src/default/lib_pypy/ .. _`lib_pypy/greenlet.py`: https://bitbucket.org/pypy/pypy/src/default/lib_pypy/greenlet.py .. _`lib_pypy/pypy_test/`: https://bitbucket.org/pypy/pypy/src/default/lib_pypy/pypy_test/ .. _`lib_pypy/tputil.py`: https://bitbucket.org/pypy/pypy/src/default/lib_pypy/tputil.py -.. _`pypy/annotation`: -.. _`pypy/annotation/`: https://bitbucket.org/pypy/pypy/src/default/pypy/annotation/ -.. _`pypy/annotation/annrpython.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/annotation/annrpython.py -.. _`pypy/annotation/binaryop.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/annotation/binaryop.py -.. _`pypy/annotation/builtin.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/annotation/builtin.py .. _`pypy/bin/`: https://bitbucket.org/pypy/pypy/src/default/pypy/bin/ -.. _`pypy/bin/translatorshell.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/bin/translatorshell.py +.. _`pypy/bin/pyinteractive.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/bin/pyinteractive.py .. _`pypy/config/`: https://bitbucket.org/pypy/pypy/src/default/pypy/config/ .. _`pypy/config/pypyoption.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/config/pypyoption.py -.. _`pypy/config/translationoption.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/config/translationoption.py .. _`pypy/doc/`: https://bitbucket.org/pypy/pypy/src/default/pypy/doc/ .. _`pypy/doc/config/`: https://bitbucket.org/pypy/pypy/src/default/pypy/doc/config/ .. _`pypy/doc/discussion/`: https://bitbucket.org/pypy/pypy/src/default/pypy/doc/discussion/ +.. _`pypy/goal/`: https://bitbucket.org/pypy/pypy/src/default/pypy/goal/ .. _`pypy/interpreter`: .. _`pypy/interpreter/`: https://bitbucket.org/pypy/pypy/src/default/pypy/interpreter/ .. _`pypy/interpreter/argument.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/interpreter/argument.py @@ -54,11 +49,8 @@ .. _`pypy/module`: .. _`pypy/module/`: https://bitbucket.org/pypy/pypy/src/default/pypy/module/ .. _`pypy/module/__builtin__/__init__.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/module/__builtin__/__init__.py -.. _`pypy/objspace`: .. _`pypy/objspace/`: https://bitbucket.org/pypy/pypy/src/default/pypy/objspace/ -.. _`pypy/objspace/flow`: .. _`pypy/objspace/flow/`: https://bitbucket.org/pypy/pypy/src/default/pypy/objspace/flow/ -.. _`pypy/objspace/flow/model.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/objspace/flow/model.py .. _`pypy/objspace/std`: .. _`pypy/objspace/std/`: https://bitbucket.org/pypy/pypy/src/default/pypy/objspace/std/ .. _`pypy/objspace/std/listtype.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/objspace/std/listtype.py @@ -70,49 +62,55 @@ .. _`pypy/objspace/std/transparent.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/objspace/std/transparent.py .. _`pypy/objspace/std/tupleobject.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/objspace/std/tupleobject.py .. _`pypy/objspace/std/tupletype.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/objspace/std/tupletype.py -.. _`pypy/rlib`: -.. _`pypy/rlib/`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/ -.. _`pypy/rlib/listsort.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/listsort.py -.. _`pypy/rlib/nonconst.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/nonconst.py -.. _`pypy/rlib/objectmodel.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/objectmodel.py -.. _`pypy/rlib/parsing/`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/parsing/ -.. _`pypy/rlib/parsing/tree.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/parsing/tree.py -.. _`pypy/rlib/rarithmetic.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/rarithmetic.py -.. _`pypy/rlib/rbigint.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/rbigint.py -.. _`pypy/rlib/rrandom.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/rrandom.py -.. _`pypy/rlib/rsocket.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/rsocket.py -.. _`pypy/rlib/streamio.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/streamio.py -.. _`pypy/rlib/test`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/test/ -.. _`pypy/rlib/unroll.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/unroll.py -.. _`pypy/rpython`: -.. _`pypy/rpython/`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/ -.. _`pypy/rpython/lltypesystem/`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/lltypesystem/ -.. _`pypy/rpython/lltypesystem/lltype.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/lltypesystem/lltype.py -.. _`pypy/rpython/memory/`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/memory/ -.. _`pypy/rpython/memory/gc/generation.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/memory/gc/generation.py -.. _`pypy/rpython/memory/gc/hybrid.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/memory/gc/hybrid.py -.. _`pypy/rpython/memory/gc/markcompact.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/memory/gc/markcompact.py -.. _`pypy/rpython/memory/gc/marksweep.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/memory/gc/marksweep.py -.. _`pypy/rpython/memory/gc/minimarkpage.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/memory/gc/minimarkpage.py -.. _`pypy/rpython/memory/gc/semispace.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/memory/gc/semispace.py -.. _`pypy/rpython/ootypesystem/`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/ootypesystem/ -.. _`pypy/rpython/ootypesystem/ootype.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/ootypesystem/ootype.py -.. _`pypy/rpython/rint.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/rint.py -.. _`pypy/rpython/rlist.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/rlist.py -.. _`pypy/rpython/rmodel.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/rmodel.py -.. _`pypy/rpython/rtyper.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/rtyper.py -.. _`pypy/rpython/test/test_llinterp.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/test/test_llinterp.py .. _`pypy/tool/`: https://bitbucket.org/pypy/pypy/src/default/pypy/tool/ .. _`pypy/tool/algo/`: https://bitbucket.org/pypy/pypy/src/default/pypy/tool/algo/ .. _`pypy/tool/pytest/`: https://bitbucket.org/pypy/pypy/src/default/pypy/tool/pytest/ -.. _`pypy/tool/traceconfig.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/tool/traceconfig.py -.. _`pypy/translator`: -.. _`pypy/translator/`: https://bitbucket.org/pypy/pypy/src/default/pypy/translator/ -.. _`pypy/translator/backendopt/`: https://bitbucket.org/pypy/pypy/src/default/pypy/translator/backendopt/ -.. _`pypy/translator/c/`: https://bitbucket.org/pypy/pypy/src/default/pypy/translator/c/ -.. _`pypy/translator/c/src/stacklet/`: https://bitbucket.org/pypy/pypy/src/default/pypy/translator/c/src/stacklet/ -.. _`pypy/translator/c/src/stacklet/stacklet.h`: https://bitbucket.org/pypy/pypy/src/default/pypy/translator/c/src/stacklet/stacklet.h -.. _`pypy/translator/cli/`: https://bitbucket.org/pypy/pypy/src/default/pypy/translator/cli/ -.. _`pypy/translator/goal/`: https://bitbucket.org/pypy/pypy/src/default/pypy/translator/goal/ -.. _`pypy/translator/jvm/`: https://bitbucket.org/pypy/pypy/src/default/pypy/translator/jvm/ -.. _`pypy/translator/tool/`: https://bitbucket.org/pypy/pypy/src/default/pypy/translator/tool/ +.. _`rpython/annotator`: +.. _`rpython/annotator/`: https://bitbucket.org/pypy/pypy/src/default/rpython/annotator/ +.. _`rpython/annotator/annrpython.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/annotator/annrpython.py +.. _`rpython/annotator/binaryop.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/annotator/binaryop.py +.. _`rpython/annotator/builtin.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/annotator/builtin.py +.. _`rpython/bin/translatorshell.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/bin/translatorshell.py +.. _`rpython/config/`: https://bitbucket.org/pypy/pypy/src/default/rpython/config/ +.. _`rpython/config/translationoption.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/config/translationoption.py +.. _`rpython/flowspace/`: https://bitbucket.org/pypy/pypy/src/default/rpython/flowspace/ +.. _`rpython/flowspace/model.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/flowspace/model.py +.. _`rpython/rlib`: +.. _`rpython/rlib/`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/ +.. _`rpython/rlib/listsort.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/listsort.py +.. _`rpython/rlib/nonconst.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/nonconst.py +.. _`rpython/rlib/objectmodel.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/objectmodel.py +.. _`rpython/rlib/parsing/`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/parsing/ +.. _`rpython/rlib/parsing/tree.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/parsing/tree.py +.. _`rpython/rlib/rarithmetic.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/rarithmetic.py +.. _`rpython/rlib/rbigint.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/rbigint.py +.. _`rpython/rlib/rrandom.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/rrandom.py +.. _`rpython/rlib/rsocket.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/rsocket.py +.. _`rpython/rlib/streamio.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/streamio.py +.. _`rpython/rlib/test`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/test/ +.. _`rpython/rlib/unroll.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/unroll.py +.. _`rpython/rtyper`: +.. _`rpython/rtyper/`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/ +.. _`rpython/rtyper/lltypesystem/`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/lltypesystem/ +.. _`rpython/rtyper/lltypesystem/lltype.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/lltypesystem/lltype.py +.. _`rpython/rtyper/memory/`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/memory/ +.. _`rpython/rtyper/memory/gc/generation.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/memory/gc/generation.py +.. _`rpython/rtyper/memory/gc/hybrid.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/memory/gc/hybrid.py +.. _`rpython/rtyper/memory/gc/minimarkpage.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/memory/gc/minimarkpage.py +.. _`rpython/rtyper/memory/gc/semispace.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/memory/gc/semispace.py +.. _`rpython/rtyper/ootypesystem/`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/ootypesystem/ +.. _`rpython/rtyper/ootypesystem/ootype.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/ootypesystem/ootype.py +.. _`rpython/rtyper/rint.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/rint.py +.. _`rpython/rtyper/rlist.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/rlist.py +.. _`rpython/rtyper/rmodel.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/rmodel.py +.. _`rpython/rtyper/rtyper.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/rtyper.py +.. _`rpython/rtyper/test/test_llinterp.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/test/test_llinterp.py +.. _`rpython/translator`: +.. _`rpython/translator/`: https://bitbucket.org/pypy/pypy/src/default/rpython/translator/ +.. _`rpython/translator/backendopt/`: https://bitbucket.org/pypy/pypy/src/default/rpython/translator/backendopt/ +.. _`rpython/translator/c/`: https://bitbucket.org/pypy/pypy/src/default/rpython/translator/c/ +.. _`rpython/translator/c/src/stacklet/`: https://bitbucket.org/pypy/pypy/src/default/rpython/translator/c/src/stacklet/ +.. _`rpython/translator/c/src/stacklet/stacklet.h`: https://bitbucket.org/pypy/pypy/src/default/rpython/translator/c/src/stacklet/stacklet.h +.. _`rpython/translator/cli/`: https://bitbucket.org/pypy/pypy/src/default/rpython/translator/cli/ +.. _`rpython/translator/jvm/`: https://bitbucket.org/pypy/pypy/src/default/rpython/translator/jvm/ +.. _`rpython/translator/tool/`: https://bitbucket.org/pypy/pypy/src/default/rpython/translator/tool/ diff --git a/pypy/doc/coding-guide.rst b/pypy/doc/coding-guide.rst --- a/pypy/doc/coding-guide.rst +++ b/pypy/doc/coding-guide.rst @@ -303,7 +303,7 @@ dicts with a unique key type only, provided it is hashable. Custom hash functions and custom equality will not be honored. - Use ``pypy.rlib.objectmodel.r_dict`` for custom hash functions. + Use ``rpython.rlib.objectmodel.r_dict`` for custom hash functions. **list comprehensions** @@ -328,7 +328,7 @@ **builtin functions** A number of builtin functions can be used. The precise set can be - found in `pypy/annotation/builtin.py`_ (see ``def builtin_xxx()``). + found in `rpython/annotator/builtin.py`_ (see ``def builtin_xxx()``). Some builtin functions may be limited in what they support, though. ``int, float, str, ord, chr``... are available as simple conversion @@ -365,7 +365,7 @@ We use normal integers for signed arithmetic. It means that before translation we get longs in case of overflow, and after translation we get a silent wrap-around. Whenever we need more control, we use the following -helpers (which live the `pypy/rlib/rarithmetic.py`_): +helpers (which live in `rpython/rlib/rarithmetic.py`_): **ovfcheck()** diff --git a/pypy/doc/configuration.rst b/pypy/doc/configuration.rst --- a/pypy/doc/configuration.rst +++ b/pypy/doc/configuration.rst @@ -188,7 +188,7 @@ toolchain`_ toolchain, have two separate sets of options. The translation toolchain options can be found on the ``config`` attribute of all ``TranslationContext`` -instances and are described in `pypy/config/translationoption.py`_. The interpreter options +instances and are described in `rpython/config/translationoption.py`_. The interpreter options are attached to the object space, also under the name ``config`` and are described in `pypy/config/pypyoption.py`_. diff --git a/pypy/doc/garbage_collection.rst b/pypy/doc/garbage_collection.rst --- a/pypy/doc/garbage_collection.rst +++ b/pypy/doc/garbage_collection.rst @@ -42,7 +42,7 @@ Two arenas of equal size, with only one arena in use and getting filled with new objects. When the arena is full, the live objects are copied into the other arena using Cheney's algorithm. The old arena is then -cleared. See `pypy/rpython/memory/gc/semispace.py`_. +cleared. See `rpython/rtyper/memory/gc/semispace.py`_. On Unix the clearing is done by reading ``/dev/zero`` into the arena, which is extremely memory efficient at least on Linux: it lets the @@ -55,7 +55,7 @@ Generational GC --------------- -This is a two-generations GC. See `pypy/rpython/memory/gc/generation.py`_. +This is a two-generations GC. See `rpython/rtyper/memory/gc/generation.py`_. It is implemented as a subclass of the Semispace copying collector. It adds a nursery, which is a chunk of the current semispace. Its size is @@ -86,7 +86,7 @@ Each generation is collected much less often than the previous one. The division of the generations is slightly more complicated than just nursery / semispace / external; see the diagram at the start of the -source code, in `pypy/rpython/memory/gc/hybrid.py`_. +source code, in `rpython/rtyper/memory/gc/hybrid.py`_. Mark & Compact GC ----------------- @@ -161,7 +161,7 @@ to the old stage. The dying case 2 objects are immediately freed. - The old stage is an area of memory containing old (small) objects. It - is handled by `pypy/rpython/memory/gc/minimarkpage.py`_. It is organized + is handled by `rpython/rtyper/memory/gc/minimarkpage.py`_. It is organized as "arenas" of 256KB or 512KB, subdivided into "pages" of 4KB or 8KB. Each page can either be free, or contain small objects of all the same size. Furthermore at any point in time each object location can be diff --git a/pypy/doc/getting-started-dev.rst b/pypy/doc/getting-started-dev.rst --- a/pypy/doc/getting-started-dev.rst +++ b/pypy/doc/getting-started-dev.rst @@ -58,8 +58,7 @@ only use low level types that are available in C (e.g. int). The compiled version is now in a ``.so`` library. You can run it say using ctypes: - >>> from ctypes import CDLL - >>> f = CDLL(lib) + >>> f = get_c_function(lib, snippet.is_perfect_number) >>> f(5) 0 >>> f(6) @@ -173,23 +172,23 @@ ``xxxobject.py`` contain respectively the definition of the type and its (default) implementation. -* `pypy/translator`_ contains the code analysis and generation stuff. +* `rpython/translator`_ contains the code analysis and generation stuff. Start reading from translator.py, from which it should be easy to follow the pieces of code involved in the various translation phases. -* `pypy/annotation`_ contains the data model for the type annotation that +* `rpython/annotator`_ contains the data model for the type annotation that can be inferred about a graph. The graph "walker" that uses this is in - `pypy/annotation/annrpython.py`_. + `rpython/annotator/annrpython.py`_. -* `pypy/rpython`_ contains the code of the RPython typer. The typer transforms +* `rpython/rtyper`_ contains the code of the RPython typer. The typer transforms annotated flow graphs in a way that makes them very similar to C code so that they can be easy translated. The graph transformations are controlled - by the code in `pypy/rpython/rtyper.py`_. The object model that is used can - be found in `pypy/rpython/lltypesystem/lltype.py`_. For each RPython type + by the code in `rpython/rtyper/rtyper.py`_. The object model that is used can + be found in `rpython/rtyper/lltypesystem/lltype.py`_. For each RPython type there is a file rxxxx.py that contains the low level functions needed for this type. -* `pypy/rlib`_ contains the `RPython standard library`_, things that you can +* `rpython/rlib`_ contains the `RPython standard library`_, things that you can use from rpython. .. _`RPython standard library`: rlib.html @@ -320,10 +319,10 @@ Demos ------- -The `demo/`_ directory contains examples of various aspects of PyPy, -ranging from running regular Python programs (that we used as compliance goals) -over experimental distribution mechanisms to examples translating -sufficiently static programs into low level code. +The `example-interpreter`_ repository contains an example interpreter +written using the RPython translation toolchain. + +.. _`example-interpreter`: https://bitbucket.org/pypy/example-interpreter Additional Tools for running (and hacking) PyPy ----------------------------------------------- diff --git a/pypy/doc/index.rst b/pypy/doc/index.rst --- a/pypy/doc/index.rst +++ b/pypy/doc/index.rst @@ -217,17 +217,20 @@ Here is a fully referenced alphabetical two-level deep directory overview of PyPy: -================================ =========================================== +================================= ============================================ Directory explanation/links -================================ =========================================== +================================= ============================================ +`pypy/bin/`_ command-line scripts, mainly + `pypy/bin/pyinteractive.py`_ -`pypy/bin/`_ command-line scripts, mainly `pyinteractive.py`_ +`pypy/config/`_ handles the numerous options for building + and running PyPy -`pypy/config/`_ handles the numerous options for building and running PyPy +`pypy/doc/`_ text versions of PyPy developer + documentation -`pypy/doc/`_ text versions of PyPy developer documentation - -`pypy/doc/config/`_ documentation for the numerous translation options +`pypy/doc/config/`_ documentation for the numerous translation + options `pypy/doc/discussion/`_ drafts of ideas and documentation @@ -238,19 +241,24 @@ `pypy/interpreter/pyparser/`_ interpreter-level Python source parser -`pypy/interpreter/astcompiler/`_ interpreter-level bytecode compiler, via an AST - representation +`pypy/interpreter/astcompiler/`_ interpreter-level bytecode compiler, + via an AST representation -`pypy/module/`_ contains `mixed modules`_ implementing core modules with +`pypy/module/`_ contains `mixed modules`_ + implementing core modules with both application and interpreter level code. - Not all are finished and working. Use the ``--withmod-xxx`` - or ``--allworkingmodules`` translation options. + Not all are finished and working. Use + the ``--withmod-xxx`` + or ``--allworkingmodules`` translation + options. `pypy/objspace/`_ `object space`_ implementations -`pypy/objspace/std/`_ the StdObjSpace_ implementing CPython's objects and types +`pypy/objspace/std/`_ the StdObjSpace_ implementing CPython's + objects and types -`pypy/tool/`_ various utilities and hacks used from various places +`pypy/tool/`_ various utilities and hacks used + from various places `pypy/tool/algo/`_ general-purpose algorithmic and mathematic tools @@ -258,49 +266,58 @@ `pypy/tool/pytest/`_ support code for our `testing methods`_ -`rpython/annotator/`_ `type inferencing code`_ for `RPython`_ programs +`rpython/annotator/`_ `type inferencing code`_ for + `RPython`_ programs `rpython/config/`_ handles the numerous options for RPython -`rpython/flowspace/`_ the FlowObjSpace_ implementing `abstract interpretation`_ +`rpython/flowspace/`_ the FlowObjSpace_ implementing + `abstract interpretation`_ - -`rpython/rlib/`_ a `"standard library"`_ for RPython_ programs +`rpython/rlib/`_ a `"standard library"`_ for RPython_ + programs `rpython/rtyper/`_ the `RPython Typer`_ -`rpython/rtyper/lltypesystem/`_ the `low-level type system`_ for C-like backends +`rpython/rtyper/lltypesystem/`_ the `low-level type system`_ for + C-like backends -`rpython/rtyper/ootypesystem/`_ the `object-oriented type system`_ for OO backends +`rpython/rtyper/ootypesystem/`_ the `object-oriented type system`_ + for OO backends -`rpython/rtyper/memory/`_ the `garbage collector`_ construction framework +`rpython/rtyper/memory/`_ the `garbage collector`_ construction + framework `rpython/translator/`_ translation_ backends and support code -`rpython/translator/backendopt/`_ general optimizations that run before a backend generates code +`rpython/translator/backendopt/`_ general optimizations that run before a + backend generates code -`rpython/translator/c/`_ the `GenC backend`_, producing C code from an +`rpython/translator/c/`_ the `GenC backend`_, producing C code + from an RPython program (generally via the rtyper_) -`rpython/translator/cli/`_ the `CLI backend`_ for `.NET`_ (Microsoft CLR or Mono_) +`rpython/translator/cli/`_ the `CLI backend`_ for `.NET`_ + (Microsoft CLR or Mono_) -`pypy/goal/`_ our `main PyPy-translation scripts`_ live here +`pypy/goal/`_ our `main PyPy-translation scripts`_ + live here `rpython/translator/jvm/`_ the Java backend -`rpython/translator/tool/`_ helper tools for translation, including the Pygame - `graph viewer`_ +`rpython/translator/tool/`_ helper tools for translation -``*/test/`` many directories have a test subdirectory containing test +`dotviewer/`_ `graph viewer`_ + +``*/test/`` many directories have a test subdirectory + containing test modules (see `Testing in PyPy`_) -``_cache/`` holds cache files from internally `translating application - level to interpreterlevel`_ code. -================================ =========================================== +``_cache/`` holds cache files from various purposes +================================= ============================================ .. _`bytecode interpreter`: interpreter.html -.. _`translating application level to interpreterlevel`: geninterp.html .. _`Testing in PyPy`: coding-guide.html#testing-in-pypy .. _`mixed modules`: coding-guide.html#mixed-modules .. _`modules`: coding-guide.html#modules diff --git a/pypy/doc/rlib.rst b/pypy/doc/rlib.rst --- a/pypy/doc/rlib.rst +++ b/pypy/doc/rlib.rst @@ -7,18 +7,18 @@ .. contents:: -This page lists some of the modules in `pypy/rlib`_ together with some hints +This page lists some of the modules in `rpython/rlib`_ together with some hints for what they can be used for. The modules here will make up some general library useful for RPython programs (since most of the standard library modules are not RPython). Most of these modules are somewhat rough still and are likely to change at some point. Usually it is useful to look at the tests in -`pypy/rlib/test`_ to get an impression of how to use a module. +`rpython/rlib/test`_ to get an impression of how to use a module. ``listsort`` ============ -The `pypy/rlib/listsort.py`_ module contains an implementation of the timsort sorting algorithm +The `rpython/rlib/listsort.py`_ module contains an implementation of the timsort sorting algorithm (the sort method of lists is not RPython). To use it, subclass from the ``listsort.TimSort`` class and override the ``lt`` method to change the comparison behaviour. The constructor of ``TimSort`` takes a list as an @@ -30,7 +30,7 @@ ``nonconst`` ============ -The `pypy/rlib/nonconst.py`_ module is useful mostly for tests. The `flow object space`_ and +The `rpython/rlib/nonconst.py`_ module is useful mostly for tests. The `flow object space`_ and the `annotator`_ do quite some constant folding, which is sometimes not desired in a test. To prevent constant folding on a certain value, use the ``NonConst`` class. The constructor of ``NonConst`` takes an arbitrary value. The instance of @@ -44,7 +44,7 @@ ``objectmodel`` =============== -The `pypy/rlib/objectmodel.py`_ module is a mixed bag of various functionality. Some of the +The `rpython/rlib/objectmodel.py`_ module is a mixed bag of various functionality. Some of the more useful ones are: ``ComputedIntSymbolic``: @@ -94,7 +94,7 @@ ``rarithmetic`` =============== -The `pypy/rlib/rarithmetic.py`_ module contains functionality to handle the small differences +The `rpython/rlib/rarithmetic.py`_ module contains functionality to handle the small differences in the behaviour of arithmetic code in regular Python and RPython code. Most of them are already described in the `coding guide`_ @@ -104,7 +104,7 @@ ``rbigint`` =========== -The `pypy/rlib/rbigint.py`_ module contains a full RPython implementation of the Python ``long`` +The `rpython/rlib/rbigint.py`_ module contains a full RPython implementation of the Python ``long`` type (which itself is not supported in RPython). The ``rbigint`` class contains that implementation. To construct ``rbigint`` instances use the static methods ``fromint``, ``frombool``, ``fromfloat`` and ``fromdecimalstr``. To convert back @@ -118,7 +118,7 @@ ``rrandom`` =========== -The `pypy/rlib/rrandom.py`_ module contains an implementation of the mersenne twister random +The `rpython/rlib/rrandom.py`_ module contains an implementation of the mersenne twister random number generator. It contains one class ``Random`` which most importantly has a ``random`` method which returns a pseudo-random floating point number between 0.0 and 1.0. @@ -126,7 +126,7 @@ ``rsocket`` =========== -The `pypy/rlib/rsocket.py`_ module contains an RPython implementation of the functionality of +The `rpython/rlib/rsocket.py`_ module contains an RPython implementation of the functionality of the socket standard library with a slightly different interface. The difficulty with the Python socket API is that addresses are not "well-typed" objects: depending on the address family they are tuples, or strings, and @@ -137,7 +137,7 @@ ``streamio`` ============ -The `pypy/rlib/streamio.py`_ contains an RPython stream I/O implementation (which was started +The `rpython/rlib/streamio.py`_ contains an RPython stream I/O implementation (which was started by Guido van Rossum as `sio.py`_ in the CPython sandbox as a prototype for the upcoming new file implementation in Python 3000). @@ -146,7 +146,7 @@ ``unroll`` ========== -The `pypy/rlib/unroll.py`_ module most importantly contains the function ``unrolling_iterable`` +The `rpython/rlib/unroll.py`_ module most importantly contains the function ``unrolling_iterable`` which wraps an iterator. Looping over the iterator in RPython code will not produce a loop in the resulting flow graph but will unroll the loop instead. @@ -154,7 +154,7 @@ ``parsing`` =========== -The `pypy/rlib/parsing/`_ module is a still in-development module to generate tokenizers and +The `rpython/rlib/parsing/`_ module is a still in-development module to generate tokenizers and parsers in RPython. It is still highly experimental and only really used by the `Prolog interpreter`_ (although in slightly non-standard ways). The easiest way to specify a tokenizer/grammar is to write it down using regular expressions and @@ -204,7 +204,7 @@ anything except a. To parse a regular expression and to get a matcher for it, you can use the -function ``make_runner(s)`` in the ``pypy.rlib.parsing.regexparse`` module. It +function ``make_runner(s)`` in the ``rpython.rlib.parsing.regexparse`` module. It returns a object with a ``recognize(input)`` method that returns True or False depending on whether ``input`` matches the string or not. @@ -213,7 +213,7 @@ EBNF ---- -To describe a tokenizer and a grammar the ``pypy.rlib.parsing.ebnfparse`` +To describe a tokenizer and a grammar the ``rpython.rlib.parsing.ebnfparse`` defines a syntax for doing that. The syntax file contains a sequence or rules. Every rule either describes a @@ -295,7 +295,7 @@ The parsing process builds up a tree consisting of instances of ``Symbol`` and ``Nonterminal``, the former corresponding to tokens, the latter to nonterminal -symbols. Both classes live in the `pypy/rlib/parsing/tree.py`_ module. You can use +symbols. Both classes live in the `rpython/rlib/parsing/tree.py`_ module. You can use the ``view()`` method ``Nonterminal`` instances to get a pygame view of the parse tree. @@ -310,7 +310,7 @@ ++++++++ To write tree visitors for the parse trees that are RPython, there is a special -baseclass ``RPythonVisitor`` in `pypy/rlib/parsing/tree.py`_ to use. If your +baseclass ``RPythonVisitor`` in `rpython/rlib/parsing/tree.py`_ to use. If your class uses this, it will grow a ``dispatch(node)`` method, that calls an appropriate ``visit_`` method, depending on the ``node`` argument. Here the is replaced by the ``symbol`` attribute of the visited node. diff --git a/pypy/doc/rtyper.rst b/pypy/doc/rtyper.rst --- a/pypy/doc/rtyper.rst +++ b/pypy/doc/rtyper.rst @@ -4,7 +4,7 @@ .. contents:: -The RPython Typer lives in the directory `pypy/rpython/`_. +The RPython Typer lives in the directory `rpython/rtyper/`_. Overview @@ -52,7 +52,7 @@ where -- in C notation -- all three variables v1, v2 and v3 are typed ``int``. This is done by attaching an attribute ``concretetype`` to v1, v2 and v3 (which might be instances of Variable or possibly Constant). In our model, -this ``concretetype`` is ``pypy.rpython.lltypesystem.lltype.Signed``. Of +this ``concretetype`` is ``rpython.rtyper.lltypesystem.lltype.Signed``. Of course, the purpose of replacing the operation called ``add`` with ``int_add`` is that code generators no longer have to worry about what kind of addition (or concatenation maybe?) it means. @@ -66,7 +66,7 @@ each operation. In both cases the analysis of an operation depends on the annotations of its input arguments. This is reflected in the usage of the same ``__extend__`` syntax in the source files (compare e.g. -`pypy/annotation/binaryop.py`_ and `pypy/rpython/rint.py`_). +`rpython/annotator/binaryop.py`_ and `rpython/rtyper/rint.py`_). The analogy stops here, though: while it runs, the Annotator is in the middle of computing the annotations, so it might need to reflow and generalize until @@ -104,7 +104,7 @@ implementations for the same high-level operations. This is the reason for turning representations into explicit objects. -The base Repr class is defined in `pypy/rpython/rmodel.py`_. Most of the +The base Repr class is defined in `rpython/rtyper/rmodel.py`_. Most of the ``rpython/r*.py`` files define one or a few subclasses of Repr. The method getrepr() of the RTyper will build and cache a single Repr instance per SomeXxx() instance; moreover, two SomeXxx() instances that are equal get the @@ -131,9 +131,9 @@ The RPython Typer uses a standard low-level model which we believe can correspond rather directly to various target languages such as C. This model is implemented in the first part of -`pypy/rpython/lltypesystem/lltype.py`_. +`rpython/rtyper/lltypesystem/lltype.py`_. -The second part of `pypy/rpython/lltypesystem/lltype.py`_ is a runnable +The second part of `rpython/rtyper/lltypesystem/lltype.py`_ is a runnable implementation of these types, for testing purposes. It allows us to write and test plain Python code using a malloc() function to obtain and manipulate structures and arrays. This is useful for example to implement and test @@ -147,7 +147,7 @@ Here is a quick tour: - >>> from pypy.rpython.lltypesystem.lltype import * + >>> from rpython.rtyper.lltypesystem.lltype import * Here are a few primitive low-level types, and the typeOf() function to figure them out: @@ -191,7 +191,7 @@ types like list in this elementary world. The ``malloc()`` function is a kind of placeholder, which must eventually be provided by the code generator for the target platform; but as we have just seen its Python implementation in -`pypy/rpython/lltypesystem/lltype.py`_ works too, which is primarily useful for +`rpython/rtyper/lltypesystem/lltype.py`_ works too, which is primarily useful for testing, interactive exploring, etc. The argument to ``malloc()`` is the structure type directly, but it returns a @@ -245,7 +245,7 @@ +++++++++++++++ Structure types are built as instances of -``pypy.rpython.lltypesystem.lltype.Struct``:: +``rpython.rtyper.lltypesystem.lltype.Struct``:: MyStructType = Struct('somename', ('field1', Type1), ('field2', Type2)...) MyStructType = GcStruct('somename', ('field1', Type1), ('field2', Type2)...) @@ -277,7 +277,7 @@ +++++++++++ An array type is built as an instance of -``pypy.rpython.lltypesystem.lltype.Array``:: +``rpython.rtyper.lltypesystem.lltype.Array``:: MyIntArray = Array(Signed) MyOtherArray = Array(MyItemType) @@ -316,7 +316,7 @@ with care: the bigger structure of which they are part of could be freed while the Ptr to the substructure is still in use. In general, it is a good idea to avoid passing around pointers to inlined substructures of malloc()ed structures. -(The testing implementation of `pypy/rpython/lltypesystem/lltype.py`_ checks to some +(The testing implementation of `rpython/rtyper/lltypesystem/lltype.py`_ checks to some extent that you are not trying to use a pointer to a structure after its container has been freed, using weak references. But pointers to non-GC structures are not officially meant to be weak references: using them after what @@ -429,7 +429,7 @@ change needed to the Annotator to allow it to perform type inference of our very-low-level snippets of code. -See for example `pypy/rpython/rlist.py`_. +See for example `rpython/rtyper/rlist.py`_. .. _`oo type`: @@ -441,10 +441,10 @@ targeting low level backends such as C, but it is not good enough for targeting higher level backends such as .NET CLI or Java JVM, so a new object oriented model has been introduced. This model is -implemented in the first part of `pypy/rpython/ootypesystem/ootype.py`_. +implemented in the first part of `rpython/rtyper/ootypesystem/ootype.py`_. As for the low-level typesystem, the second part of -`pypy/rpython/ootypesystem/ootype.py`_ is a runnable implementation of +`rpython/rtyper/ootypesystem/ootype.py`_ is a runnable implementation of these types, for testing purposes. @@ -751,7 +751,7 @@ The LLInterpreter is a simple piece of code that is able to interpret flow graphs. This is very useful for testing purposes, especially if you work on the RPython Typer. The most useful interface for it is the ``interpret`` -function in the file `pypy/rpython/test/test_llinterp.py`_. It takes as +function in the file `rpython/rtyper/test/test_llinterp.py`_. It takes as arguments a function and a list of arguments with which the function is supposed to be called. Then it generates the flow graph, annotates it according to the types of the arguments you passed to it and runs the diff --git a/pypy/doc/stackless.rst b/pypy/doc/stackless.rst --- a/pypy/doc/stackless.rst +++ b/pypy/doc/stackless.rst @@ -29,7 +29,7 @@ on 32-bit or a complete megabyte on 64-bit. Moreover, the feature is only available (so far) on x86 and x86-64 CPUs; for other CPUs you need to add a short page of custom assembler to -`pypy/translator/c/src/stacklet/`_. +`rpython/translator/c/src/stacklet/`_. Theory @@ -271,7 +271,7 @@ Continulets are internally implemented using stacklets, which is the generic RPython-level building block for "one-shot continuations". For more information about them please see the documentation in the C source -at `pypy/translator/c/src/stacklet/stacklet.h`_. +at `rpython/translator/c/src/stacklet/stacklet.h`_. The module ``pypy.rlib.rstacklet`` is a thin wrapper around the above functions. The key point is that new() and switch() always return a diff --git a/pypy/doc/tool/makeref.py b/pypy/doc/tool/makeref.py --- a/pypy/doc/tool/makeref.py +++ b/pypy/doc/tool/makeref.py @@ -1,10 +1,9 @@ import py -py.path.local(__file__) import pypy -pypydir = py.path.local(pypy.__file__).dirpath() -distdir = pypydir.dirpath() -issue_url = 'http://codespeak.net/issue/pypy-dev/' +pypydir = py.path.local(pypy.__file__).join('..') +distdir = pypydir.dirpath() +issue_url = 'http://bugs.pypy.org/issue/pypy-dev/' bitbucket_url = 'https://bitbucket.org/pypy/pypy/src/default/' import urllib2, posixpath diff --git a/pypy/doc/translation.rst b/pypy/doc/translation.rst --- a/pypy/doc/translation.rst +++ b/pypy/doc/translation.rst @@ -90,7 +90,7 @@ (although these steps are not quite as distinct as you might think from this presentation). -There is an `interactive interface`_ called `pypy/bin/translatorshell.py`_ to the +There is an `interactive interface`_ called `rpython/bin/translatorshell.py`_ to the translation process which allows you to interactively work through these stages. @@ -116,7 +116,7 @@ which are the basic data structures of the translation process. -All these types are defined in `pypy/objspace/flow/model.py`_ (which is a rather +All these types are defined in `rpython/flowspace/model.py`_ (which is a rather important module in the PyPy source base, to reinforce the point). The flow graph of a function is represented by the class ``FunctionGraph``. diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst --- a/pypy/doc/whatsnew-head.rst +++ b/pypy/doc/whatsnew-head.rst @@ -19,7 +19,7 @@ .. branch: numpypy-longdouble Long double support for numpypy .. branch: numpypy-real-as-view -Convert real, imag from ufuncs to views. This involves the beginning of +Convert real, imag from ufuncs to views. This involves the beginning of view() functionality .. branch: signatures @@ -57,7 +57,14 @@ .. branch: cleanup-tests Consolidated the lib_pypy/pypy_test and pypy/module/test_lib_pypy tests into -+one directory for reduced confusion and so they all run nightly. +one directory for reduced confusion and so they all run nightly. .. branch: unquote-faster .. branch: urlparse-unquote-faster + +.. branch: signal-and-thread +Add "__pypy__.thread.signals_enabled", a context manager. Can be used in a +non-main thread to enable the processing of signal handlers in that thread. + +.. branch: coding-guide-update-rlib-refs +.. branch: rlib-doc-rpython-refs diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -1494,10 +1494,11 @@ ) return fd - def warn(self, msg, w_warningcls): - self.appexec([self.wrap(msg), w_warningcls], """(msg, warningcls): + def warn(self, w_msg, w_warningcls, stacklevel=2): + self.appexec([w_msg, w_warningcls, self.wrap(stacklevel)], + """(msg, warningcls, stacklevel): import _warnings - _warnings.warn(msg, warningcls, stacklevel=2) + _warnings.warn(msg, warningcls, stacklevel=stacklevel) """) diff --git a/pypy/interpreter/miscutils.py b/pypy/interpreter/miscutils.py --- a/pypy/interpreter/miscutils.py +++ b/pypy/interpreter/miscutils.py @@ -17,8 +17,14 @@ def setvalue(self, value): self._value = value - def ismainthread(self): + def signals_enabled(self): return True + def enable_signals(self, space): + pass + + def disable_signals(self, space): + pass + def getallvalues(self): return {0: self._value} diff --git a/pypy/interpreter/pycode.py b/pypy/interpreter/pycode.py --- a/pypy/interpreter/pycode.py +++ b/pypy/interpreter/pycode.py @@ -53,16 +53,17 @@ kwargname = None return Signature(argnames, varargname, kwargname) + class PyCode(eval.Code): "CPython-style code objects." _immutable_ = True _immutable_fields_ = ["co_consts_w[*]", "co_names_w[*]", "co_varnames[*]", - "co_freevars[*]", "co_cellvars[*]"] + "co_freevars[*]", "co_cellvars[*]", "_args_as_cellvars[*]"] def __init__(self, space, argcount, nlocals, stacksize, flags, code, consts, names, varnames, filename, name, firstlineno, lnotab, freevars, cellvars, - hidden_applevel=False, magic = default_magic): + hidden_applevel=False, magic=default_magic): """Initialize a new code object from parameters given by the pypy compiler""" self.space = space @@ -89,8 +90,6 @@ def _initialize(self): self._init_flags() - # Precompute what arguments need to be copied into cellvars - self._args_as_cellvars = [] if self.co_cellvars: argcount = self.co_argcount @@ -108,16 +107,22 @@ # produced by CPython are loaded by PyPy. Note that CPython # contains the following bad-looking nested loops at *every* # function call! - argvars = self.co_varnames + + # Precompute what arguments need to be copied into cellvars + args_as_cellvars = [] + argvars = self.co_varnames cellvars = self.co_cellvars for i in range(len(cellvars)): cellname = cellvars[i] for j in range(argcount): if cellname == argvars[j]: # argument j has the same name as the cell var i - while len(self._args_as_cellvars) <= i: - self._args_as_cellvars.append(-1) # pad - self._args_as_cellvars[i] = j + while len(args_as_cellvars) <= i: + args_as_cellvars.append(-1) # pad + args_as_cellvars[i] = j + self._args_as_cellvars = args_as_cellvars[:] + else: + self._args_as_cellvars = [] self._compute_flatcall() diff --git a/pypy/interpreter/pyopcode.py b/pypy/interpreter/pyopcode.py --- a/pypy/interpreter/pyopcode.py +++ b/pypy/interpreter/pyopcode.py @@ -776,17 +776,16 @@ @jit.unroll_safe def cmp_exc_match(self, w_1, w_2): - if self.space.is_true(self.space.isinstance(w_2, self.space.w_tuple)): - for w_t in self.space.fixedview(w_2): - if self.space.is_true(self.space.isinstance(w_t, - self.space.w_str)): - self.space.warn("catching of string exceptions is " - "deprecated", - self.space.w_DeprecationWarning) - elif self.space.is_true(self.space.isinstance(w_2, self.space.w_str)): - self.space.warn("catching of string exceptions is deprecated", - self.space.w_DeprecationWarning) - return self.space.newbool(self.space.exception_match(w_1, w_2)) + space = self.space + if space.is_true(space.isinstance(w_2, space.w_tuple)): + for w_t in space.fixedview(w_2): + if space.is_true(space.isinstance(w_t, space.w_str)): + msg = "catching of string exceptions is deprecated" + space.warn(space.wrap(msg), space.w_DeprecationWarning) + elif space.is_true(space.isinstance(w_2, space.w_str)): + msg = "catching of string exceptions is deprecated" + space.warn(space.wrap(msg), space.w_DeprecationWarning) + return space.newbool(space.exception_match(w_1, w_2)) def COMPARE_OP(self, testnum, next_instr): w_2 = self.popvalue() diff --git a/pypy/interpreter/test2/test_app_main.py b/pypy/interpreter/test2/test_app_main.py --- a/pypy/interpreter/test2/test_app_main.py +++ b/pypy/interpreter/test2/test_app_main.py @@ -208,11 +208,6 @@ These tests require pexpect (UNIX-only). http://pexpect.sourceforge.net/ """ - def setup_class(cls): - # some tests need to be able to import test2, change the cwd - goal_dir = os.path.abspath(os.path.join(os.path.realpath(os.path.dirname(__file__)), '..')) - os.chdir(goal_dir) - def _spawn(self, *args, **kwds): try: import pexpect @@ -456,13 +451,14 @@ child.expect('789') # expect to see it before the timeout hits child.sendline('X') - def test_options_i_m(self): + def test_options_i_m(self, monkeypatch): if sys.platform == "win32": skip("close_fds is not supported on Windows platforms") if not hasattr(runpy, '_run_module_as_main'): skip("requires CPython >= 2.6") p = os.path.join(os.path.realpath(os.path.dirname(__file__)), 'mymodule.py') p = os.path.abspath(p) + monkeypatch.chdir(os.path.dirname(app_main)) child = self.spawn(['-i', '-m', 'test2.mymodule', 'extra']) @@ -562,12 +558,13 @@ child.sendline('Not at all. They could be carried.') child.expect('A five ounce bird could not carry a one pound coconut.') - def test_no_space_before_argument(self): + def test_no_space_before_argument(self, monkeypatch): if not hasattr(runpy, '_run_module_as_main'): skip("requires CPython >= 2.6") child = self.spawn(['-cprint "hel" + "lo"']) child.expect('hello') + monkeypatch.chdir(os.path.dirname(app_main)) child = self.spawn(['-mtest2.mymodule']) child.expect('mymodule running') @@ -667,11 +664,12 @@ '-c "import sys; print sys.warnoptions"') assert "['ignore', 'default', 'once', 'error']" in data - def test_option_m(self): + def test_option_m(self, monkeypatch): if not hasattr(runpy, '_run_module_as_main'): skip("requires CPython >= 2.6") p = os.path.join(os.path.realpath(os.path.dirname(__file__)), 'mymodule.py') p = os.path.abspath(p) + monkeypatch.chdir(os.path.dirname(app_main)) data = self.run('-m test2.mymodule extra') assert 'mymodule running' in data assert 'Name: __main__' in data diff --git a/pypy/module/__builtin__/functional.py b/pypy/module/__builtin__/functional.py --- a/pypy/module/__builtin__/functional.py +++ b/pypy/module/__builtin__/functional.py @@ -133,56 +133,77 @@ v = v.add(step) return space.newlist(res_w) +min_jitdriver = jit.JitDriver(name='min', + greens=['w_type'], reds='auto') +max_jitdriver = jit.JitDriver(name='max', + greens=['w_type'], reds='auto') + +def make_min_max(unroll): + @specialize.arg(2) + def min_max_impl(space, args, implementation_of): + if implementation_of == "max": + compare = space.gt + jitdriver = max_jitdriver + else: + compare = space.lt + jitdriver = min_jitdriver + args_w = args.arguments_w + if len(args_w) > 1: + w_sequence = space.newtuple(args_w) + elif len(args_w): + w_sequence = args_w[0] + else: + msg = "%s() expects at least one argument" % (implementation_of,) + raise OperationError(space.w_TypeError, space.wrap(msg)) + w_key = None + kwds = args.keywords + if kwds: + if kwds[0] == "key" and len(kwds) == 1: + w_key = args.keywords_w[0] + else: + msg = "%s() got unexpected keyword argument" % (implementation_of,) + raise OperationError(space.w_TypeError, space.wrap(msg)) + + w_iter = space.iter(w_sequence) + w_type = space.type(w_iter) + w_max_item = None + w_max_val = None + while True: + if not unroll: + jitdriver.jit_merge_point(w_type=w_type) + try: + w_item = space.next(w_iter) + except OperationError, e: + if not e.match(space, space.w_StopIteration): + raise + break + if w_key is not None: + w_compare_with = space.call_function(w_key, w_item) + else: + w_compare_with = w_item + if w_max_item is None or \ + space.is_true(compare(w_compare_with, w_max_val)): + w_max_item = w_item + w_max_val = w_compare_with + if w_max_item is None: + msg = "arg is an empty sequence" + raise OperationError(space.w_ValueError, space.wrap(msg)) + return w_max_item + if unroll: + min_max_impl = jit.unroll_safe(min_max_impl) + return min_max_impl + +min_max_unroll = make_min_max(True) +min_max_normal = make_min_max(False) @specialize.arg(2) - at jit.look_inside_iff(lambda space, args, implementation_of: - jit.isconstant(len(args.arguments_w)) and - len(args.arguments_w) == 2 -) def min_max(space, args, implementation_of): - if implementation_of == "max": - compare = space.gt + if not jit.we_are_jitted() or (jit.isconstant(len(args.arguments_w)) and + len(args.arguments_w) == 2): + return min_max_unroll(space, args, implementation_of) else: - compare = space.lt - args_w = args.arguments_w - if len(args_w) > 1: - w_sequence = space.newtuple(args_w) - elif len(args_w): - w_sequence = args_w[0] - else: - msg = "%s() expects at least one argument" % (implementation_of,) - raise OperationError(space.w_TypeError, space.wrap(msg)) - w_key = None - kwds = args.keywords - if kwds: - if kwds[0] == "key" and len(kwds) == 1: - w_key = args.keywords_w[0] - else: - msg = "%s() got unexpected keyword argument" % (implementation_of,) - raise OperationError(space.w_TypeError, space.wrap(msg)) - - w_iter = space.iter(w_sequence) - w_max_item = None - w_max_val = None - while True: - try: - w_item = space.next(w_iter) - except OperationError, e: - if not e.match(space, space.w_StopIteration): - raise - break - if w_key is not None: - w_compare_with = space.call_function(w_key, w_item) - else: - w_compare_with = w_item - if w_max_item is None or \ - space.is_true(compare(w_compare_with, w_max_val)): - w_max_item = w_item - w_max_val = w_compare_with - if w_max_item is None: - msg = "arg is an empty sequence" - raise OperationError(space.w_ValueError, space.wrap(msg)) - return w_max_item + return min_max_normal(space, args, implementation_of) +min_max._always_inline = True def max(space, __args__): """max(iterable[, key=func]) -> value diff --git a/pypy/module/__builtin__/interp_classobj.py b/pypy/module/__builtin__/interp_classobj.py --- a/pypy/module/__builtin__/interp_classobj.py +++ b/pypy/module/__builtin__/interp_classobj.py @@ -154,9 +154,9 @@ return elif name == "__del__": if self.lookup(space, name) is None: - msg = ("a __del__ method added to an existing class " - "will not be called") - space.warn(msg, space.w_RuntimeWarning) + msg = ("a __del__ method added to an existing class will " + "not be called") + space.warn(space.wrap(msg), space.w_RuntimeWarning) space.setitem(self.w_dict, w_attr, w_value) def descr_delattr(self, space, w_attr): @@ -395,9 +395,9 @@ cache = space.fromcache(Cache) if (not isinstance(self, cache.cls_with_del) and self.getdictvalue(space, '__del__') is None): - msg = ("a __del__ method added to an instance " - "with no __del__ in the class will not be called") - space.warn(msg, space.w_RuntimeWarning) + msg = ("a __del__ method added to an instance with no " + "__del__ in the class will not be called") + space.warn(space.wrap(msg), space.w_RuntimeWarning) if w_meth is not None: space.call_function(w_meth, w_name, w_value) else: @@ -454,11 +454,9 @@ else: w_as_str = self.descr_str(space) if space.len_w(w_format_spec) > 0: - space.warn( - ("object.__format__ with a non-empty format string is " - "deprecated"), - space.w_PendingDeprecationWarning - ) + msg = ("object.__format__ with a non-empty format string is " + "deprecated") + space.warn(space.wrap(msg), space.w_PendingDeprecationWarning) return space.format(w_as_str, w_format_spec) def descr_len(self, space): diff --git a/pypy/module/__pypy__/__init__.py b/pypy/module/__pypy__/__init__.py --- a/pypy/module/__pypy__/__init__.py +++ b/pypy/module/__pypy__/__init__.py @@ -26,6 +26,16 @@ interpleveldefs[name] = "space.wrap(interp_time.%s)" % name +class ThreadModule(MixedModule): + appleveldefs = { + 'signals_enabled': 'app_signal.signals_enabled', + } + interpleveldefs = { + '_signals_enter': 'interp_signal.signals_enter', + '_signals_exit': 'interp_signal.signals_exit', + } + + class Module(MixedModule): appleveldefs = { } @@ -54,6 +64,7 @@ submodules = { "builders": BuildersModule, "time": TimeModule, + "thread": ThreadModule, } def setup_after_space_initialization(self): diff --git a/pypy/module/__pypy__/app_signal.py b/pypy/module/__pypy__/app_signal.py new file mode 100644 --- /dev/null +++ b/pypy/module/__pypy__/app_signal.py @@ -0,0 +1,14 @@ +import __pypy__.thread + +class SignalsEnabled(object): + '''A context manager to use in non-main threads: +enables receiving signals in a "with" statement. More precisely, if a +signal is received by the process, then the signal handler might be +called either in the main thread (as usual) or within another thread +that is within a "with signals_enabled:". This other thread should be +ready to handle unexpected exceptions that the signal handler might +raise --- notably KeyboardInterrupt.''' + __enter__ = __pypy__.thread._signals_enter + __exit__ = __pypy__.thread._signals_exit + +signals_enabled = SignalsEnabled() diff --git a/pypy/module/__pypy__/interp_signal.py b/pypy/module/__pypy__/interp_signal.py new file mode 100644 --- /dev/null +++ b/pypy/module/__pypy__/interp_signal.py @@ -0,0 +1,6 @@ + +def signals_enter(space): + space.threadlocals.enable_signals(space) + +def signals_exit(space, w_ignored1=None, w_ignored2=None, w_ignored3=None): + space.threadlocals.disable_signals(space) diff --git a/pypy/module/__pypy__/test/test_signal.py b/pypy/module/__pypy__/test/test_signal.py new file mode 100644 --- /dev/null +++ b/pypy/module/__pypy__/test/test_signal.py @@ -0,0 +1,122 @@ +import sys + +from pypy.module.thread.test.support import GenericTestThread + + +class AppTestMinimal: + spaceconfig = dict(usemodules=['__pypy__']) + + def test_signal(self): + from __pypy__ import thread + with thread.signals_enabled: + pass + # assert did not crash + + +class AppTestThreadSignal(GenericTestThread): + spaceconfig = dict(usemodules=['__pypy__', 'thread', 'signal', 'time']) + + def test_exit_twice(self): + import __pypy__, thread + __pypy__.thread._signals_exit() + try: + raises(thread.error, __pypy__.thread._signals_exit) + finally: + __pypy__.thread._signals_enter() + + def test_enable_signals(self): + import __pypy__, thread, signal, time + + def subthread(): + try: + with __pypy__.thread.signals_enabled: + thread.interrupt_main() + for i in range(10): + print 'x' + time.sleep(0.1) + except BaseException, e: + interrupted.append(e) + finally: + done.append(None) + + # This is normally called by app_main.py + signal.signal(signal.SIGINT, signal.default_int_handler) + + for i in range(10): + __pypy__.thread._signals_exit() + try: + done = [] + interrupted = [] + thread.start_new_thread(subthread, ()) + for i in range(10): + if len(done): break + print '.' + time.sleep(0.1) + assert len(done) == 1 + assert len(interrupted) == 1 + assert 'KeyboardInterrupt' in interrupted[0].__class__.__name__ + finally: + __pypy__.thread._signals_enter() + + def test_thread_fork_signals(self): + import __pypy__ + import os, thread, signal + + if not hasattr(os, 'fork'): + skip("No fork on this platform") + + def fork(): + with __pypy__.thread.signals_enabled: + return os.fork() + + def threadfunction(): + pid = fork() + if pid == 0: + print 'in child' + # signal() only works from the 'main' thread + signal.signal(signal.SIGUSR1, signal.SIG_IGN) + os._exit(42) + else: + self.timeout_killer(pid, 5) + exitcode = os.waitpid(pid, 0)[1] + feedback.append(exitcode) + + feedback = [] + thread.start_new_thread(threadfunction, ()) + self.waitfor(lambda: feedback) + # if 0, an (unraisable) exception was raised from the forked thread. + # if 9, process was killed by timer. + # if 42<<8, os._exit(42) was correctly reached. + assert feedback == [42<<8] + + +class AppTestThreadSignalLock: + spaceconfig = dict(usemodules=['__pypy__', 'thread', 'signal']) + + def setup_class(cls): + if (not cls.runappdirect or + '__pypy__' not in sys.builtin_module_names): + import py + py.test.skip("this is only a test for -A runs on top of pypy") + + def test_enable_signals(self): + import __pypy__, thread, signal, time + + interrupted = [] + lock = thread.allocate_lock() + lock.acquire() + + def subthread(): + try: + time.sleep(0.25) + with __pypy__.thread.signals_enabled: + thread.interrupt_main() + except BaseException, e: + interrupted.append(e) + finally: + lock.release() + + thread.start_new_thread(subthread, ()) + lock.acquire() + assert len(interrupted) == 1 + assert 'KeyboardInterrupt' in interrupted[0].__class__.__name__ diff --git a/pypy/module/_cffi_backend/newtype.py b/pypy/module/_cffi_backend/newtype.py --- a/pypy/module/_cffi_backend/newtype.py +++ b/pypy/module/_cffi_backend/newtype.py @@ -264,8 +264,8 @@ # ____________________________________________________________ - at unwrap_spec(name=str) -def new_enum_type(space, name, w_enumerators, w_enumvalues): + at unwrap_spec(name=str, basectype=ctypeobj.W_CType) +def new_enum_type(space, name, w_enumerators, w_enumvalues, basectype): enumerators_w = space.fixedview(w_enumerators) enumvalues_w = space.fixedview(w_enumvalues) if len(enumerators_w) != len(enumvalues_w): @@ -273,53 +273,26 @@ space.wrap("tuple args must have the same size")) enumerators = [space.str_w(w) for w in enumerators_w] # - smallest_value = 0 - largest_value = r_uint(0) - i = 0 + if (not isinstance(basectype, ctypeprim.W_CTypePrimitiveSigned) and + not isinstance(basectype, ctypeprim.W_CTypePrimitiveUnsigned)): + raise OperationError(space.w_TypeError, + space.wrap("expected a primitive signed or unsigned base type")) + # + lvalue = lltype.malloc(rffi.CCHARP.TO, basectype.size, flavor='raw') try: for w in enumvalues_w: - try: - ulvalue = space.uint_w(w) - except OperationError, e: - if not e.match(space, space.w_ValueError): - raise - lvalue = space.int_w(w) - if lvalue < smallest_value: - smallest_value = lvalue - else: - if ulvalue > largest_value: - largest_value = ulvalue - i += 1 # 'i' is here for the exception case, see below - except OperationError, e: - if not e.match(space, space.w_OverflowError): - raise - raise operationerrfmt(space.w_OverflowError, - "enum '%s' declaration for '%s' does not fit " - "a long or unsigned long", - name, enumerators[i]) + # detects out-of-range or badly typed values + basectype.convert_from_object(lvalue, w) + finally: + lltype.free(lvalue, flavor='raw') # - if smallest_value < 0: - if (smallest_value >= intmask(most_neg_value_of(rffi.INT)) and - largest_value <= r_uint(most_pos_value_of(rffi.INT))): - size = rffi.sizeof(rffi.INT) - align = alignment(rffi.INT) - elif largest_value <= r_uint(most_pos_value_of(rffi.LONG)): - size = rffi.sizeof(rffi.LONG) - align = alignment(rffi.LONG) - else: - raise operationerrfmt(space.w_OverflowError, - "enum '%s' values don't all fit into either 'long' " - "or 'unsigned long'", name) + size = basectype.size + align = basectype.align + if isinstance(basectype, ctypeprim.W_CTypePrimitiveSigned): enumvalues = [space.int_w(w) for w in enumvalues_w] ctype = ctypeenum.W_CTypeEnumSigned(space, name, size, align, enumerators, enumvalues) else: - if largest_value <= r_uint(most_pos_value_of(rffi.UINT)): - size = rffi.sizeof(rffi.UINT) - align = alignment(rffi.UINT) - else: - size = rffi.sizeof(rffi.ULONG) - align = alignment(rffi.ULONG) enumvalues = [space.uint_w(w) for w in enumvalues_w] ctype = ctypeenum.W_CTypeEnumUnsigned(space, name, size, align, enumerators, enumvalues) diff --git a/pypy/module/_cffi_backend/test/_backend_test_c.py b/pypy/module/_cffi_backend/test/_backend_test_c.py --- a/pypy/module/_cffi_backend/test/_backend_test_c.py +++ b/pypy/module/_cffi_backend/test/_backend_test_c.py @@ -1264,25 +1264,29 @@ py.test.raises(TypeError, callback, BFunc, cb, -42) def test_enum_type(): - BEnum = new_enum_type("foo", (), ()) + BUInt = new_primitive_type("unsigned int") + BEnum = new_enum_type("foo", (), (), BUInt) assert repr(BEnum) == "" assert BEnum.kind == "enum" assert BEnum.cname == "enum foo" assert BEnum.elements == {} # - BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, -20)) + BInt = new_primitive_type("int") + BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, -20), BInt) assert BEnum.kind == "enum" assert BEnum.elements == {-20: 'ab', 0: 'def', 1: 'c'} # 'elements' is not the real dict, but merely a copy BEnum.elements[2] = '??' assert BEnum.elements == {-20: 'ab', 0: 'def', 1: 'c'} # - BEnum = new_enum_type("bar", ('ab', 'cd'), (5, 5)) + BEnum = new_enum_type("bar", ('ab', 'cd'), (5, 5), BUInt) assert BEnum.elements == {5: 'ab'} assert BEnum.relements == {'ab': 5, 'cd': 5} def test_cast_to_enum(): - BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, -20)) + BInt = new_primitive_type("int") + BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, -20), BInt) + assert sizeof(BEnum) == sizeof(BInt) e = cast(BEnum, 0) assert repr(e) == "" assert repr(cast(BEnum, -42)) == "" @@ -1294,18 +1298,27 @@ assert int(cast(BEnum, -242 + 2**128)) == -242 assert string(cast(BEnum, -242 + 2**128)) == '-242' # - BEnum = new_enum_type("bar", ('def', 'c', 'ab'), (0, 1, 20)) + BUInt = new_primitive_type("unsigned int") + BEnum = new_enum_type("bar", ('def', 'c', 'ab'), (0, 1, 20), BUInt) e = cast(BEnum, -1) assert repr(e) == "" # unsigned int + # + BLong = new_primitive_type("long") + BEnum = new_enum_type("baz", (), (), BLong) + assert sizeof(BEnum) == sizeof(BLong) + e = cast(BEnum, -1) + assert repr(e) == "" def test_enum_with_non_injective_mapping(): - BEnum = new_enum_type("foo", ('ab', 'cd'), (7, 7)) + BInt = new_primitive_type("int") + BEnum = new_enum_type("foo", ('ab', 'cd'), (7, 7), BInt) e = cast(BEnum, 7) assert repr(e) == "" assert string(e) == 'ab' def test_enum_in_struct(): - BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, -20)) + BInt = new_primitive_type("int") + BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, -20), BInt) BStruct = new_struct_type("bar") BStructPtr = new_pointer_type(BStruct) complete_struct_or_union(BStruct, [('a1', BEnum, -1)]) @@ -1318,7 +1331,7 @@ "unsupported operand type for int(): 'NoneType'" in str(e.value)) #PyPy py.test.raises(TypeError, 'p.a1 = "def"') if sys.version_info < (3,): - BEnum2 = new_enum_type(unicode("foo"), (unicode('abc'),), (5,)) + BEnum2 = new_enum_type(unicode("foo"), (unicode('abc'),), (5,), BInt) assert string(cast(BEnum2, 5)) == 'abc' assert type(string(cast(BEnum2, 5))) is str @@ -1327,66 +1340,25 @@ max_int = max_uint // 2 max_ulong = 2 ** (size_of_long()*8) - 1 max_long = max_ulong // 2 - # 'unsigned int' case - e = new_enum_type("foo", ('a', 'b'), (0, 3)) - assert sizeof(e) == size_of_int() - assert int(cast(e, -1)) == max_uint # 'e' is unsigned - e = new_enum_type("foo", ('a', 'b'), (0, max_uint)) - assert sizeof(e) == size_of_int() - assert int(cast(e, -1)) == max_uint - assert e.elements == {0: 'a', max_uint: 'b'} - assert e.relements == {'a': 0, 'b': max_uint} - # 'signed int' case - e = new_enum_type("foo", ('a', 'b'), (-1, max_int)) - assert sizeof(e) == size_of_int() - assert int(cast(e, -1)) == -1 - assert e.elements == {-1: 'a', max_int: 'b'} - assert e.relements == {'a': -1, 'b': max_int} - e = new_enum_type("foo", ('a', 'b'), (-max_int-1, max_int)) - assert sizeof(e) == size_of_int() - assert int(cast(e, -1)) == -1 - assert e.elements == {-max_int-1: 'a', max_int: 'b'} - assert e.relements == {'a': -max_int-1, 'b': max_int} - # 'unsigned long' case - e = new_enum_type("foo", ('a', 'b'), (0, max_long)) - assert sizeof(e) == size_of_long() - assert int(cast(e, -1)) == max_ulong # 'e' is unsigned - e = new_enum_type("foo", ('a', 'b'), (0, max_ulong)) - assert sizeof(e) == size_of_long() - assert int(cast(e, -1)) == max_ulong - assert e.elements == {0: 'a', max_ulong: 'b'} - assert e.relements == {'a': 0, 'b': max_ulong} - # 'signed long' case - e = new_enum_type("foo", ('a', 'b'), (-1, max_long)) - assert sizeof(e) == size_of_long() - assert int(cast(e, -1)) == -1 - assert e.elements == {-1: 'a', max_long: 'b'} - assert e.relements == {'a': -1, 'b': max_long} - e = new_enum_type("foo", ('a', 'b'), (-max_long-1, max_long)) - assert sizeof(e) == size_of_long() - assert int(cast(e, -1)) == -1 - assert e.elements == {-max_long-1: 'a', max_long: 'b'} - assert e.relements == {'a': -max_long-1, 'b': max_long} - # overflow: both negative items and items larger than max_long - e = py.test.raises(OverflowError, new_enum_type, "foo", ('a', 'b'), - (-1, max_long + 1)) - assert str(e.value) == ( - "enum 'foo' values don't all fit into either 'long' " - "or 'unsigned long'") - # overflow: items smaller than -max_long-1 - e = py.test.raises(OverflowError, new_enum_type, "foo", ('a', 'b'), - (-max_long-2, 5)) - assert str(e.value) == ( - "enum 'foo' declaration for 'a' does not fit a long or unsigned long") - # overflow: items larger than max_ulong - e = py.test.raises(OverflowError, new_enum_type, "foo", ('a', 'b'), - (5, max_ulong+1)) - assert str(e.value) == ( - "enum 'foo' declaration for 'b' does not fit a long or unsigned long") + for BPrimitive in [new_primitive_type("int"), + new_primitive_type("unsigned int"), + new_primitive_type("long"), + new_primitive_type("unsigned long")]: + for x in [max_uint, max_int, max_ulong, max_long]: + for testcase in [x, x+1, -x-1, -x-2]: + if int(cast(BPrimitive, testcase)) == testcase: + # fits + BEnum = new_enum_type("foo", ("AA",), (testcase,), + BPrimitive) + assert int(cast(BEnum, testcase)) == testcase + else: + # overflows + py.test.raises(OverflowError, new_enum_type, + "foo", ("AA",), (testcase,), BPrimitive) def test_callback_returning_enum(): BInt = new_primitive_type("int") - BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, -20)) + BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, -20), BInt) def cb(n): if n & 1: return cast(BEnum, n) @@ -1402,9 +1374,9 @@ def test_callback_returning_enum_unsigned(): BInt = new_primitive_type("int") - BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, 20)) + BUInt = new_primitive_type("unsigned int") + BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, 20), BUInt) def cb(n): - print n if n & 1: return cast(BEnum, n) else: diff --git a/pypy/module/_io/interp_bufferedio.py b/pypy/module/_io/interp_bufferedio.py --- a/pypy/module/_io/interp_bufferedio.py +++ b/pypy/module/_io/interp_bufferedio.py @@ -76,7 +76,7 @@ raise NotImplementedError def _deprecated_max_buffer_size(self, space): - space.warn("max_buffer_size is deprecated", + space.warn(space.wrap("max_buffer_size is deprecated"), space.w_DeprecationWarning) def read_w(self, space, w_size=None): diff --git a/pypy/module/_io/interp_fileio.py b/pypy/module/_io/interp_fileio.py --- a/pypy/module/_io/interp_fileio.py +++ b/pypy/module/_io/interp_fileio.py @@ -3,6 +3,7 @@ from pypy.interpreter.error import OperationError, wrap_oserror, wrap_oserror2 from rpython.rlib.rarithmetic import r_longlong from rpython.rlib.rstring import StringBuilder +from rpython.rlib.rposix import validate_fd from os import O_RDONLY, O_WRONLY, O_RDWR, O_CREAT, O_TRUNC import sys, os, stat, errno from pypy.module._io.interp_iobase import W_RawIOBase, convert_size @@ -117,9 +118,6 @@ return currentsize + BIGCHUNK return currentsize + SMALLCHUNK -def verify_fd(fd): - return - class W_FileIO(W_RawIOBase): def __init__(self, space): W_RawIOBase.__init__(self, space) @@ -156,7 +154,7 @@ fd_is_own = False try: if fd >= 0: - verify_fd(fd) + validate_fd(fd) try: os.fstat(fd) except OSError, e: @@ -237,7 +235,7 @@ self.fd = -1 try: - verify_fd(fd) + validate_fd(fd) os.close(fd) except OSError, e: raise wrap_oserror(space, e, diff --git a/pypy/module/cpyext/import_.py b/pypy/module/cpyext/import_.py --- a/pypy/module/cpyext/import_.py +++ b/pypy/module/cpyext/import_.py @@ -46,8 +46,9 @@ @cpython_api([CONST_STRING], PyObject) def PyImport_ImportModuleNoBlock(space, name): - space.warn('PyImport_ImportModuleNoBlock() is not non-blocking', - space.w_RuntimeWarning) + space.warn( + space.wrap('PyImport_ImportModuleNoBlock() is not non-blocking'), + space.w_RuntimeWarning) return PyImport_Import(space, space.wrap(rffi.charp2str(name))) @cpython_api([PyObject], PyObject) diff --git a/pypy/module/exceptions/interp_exceptions.py b/pypy/module/exceptions/interp_exceptions.py --- a/pypy/module/exceptions/interp_exceptions.py +++ b/pypy/module/exceptions/interp_exceptions.py @@ -176,8 +176,8 @@ if self.w_message is None: raise OperationError(space.w_AttributeError, space.wrap("message was deleted")) - space.warn("BaseException.message has been deprecated as of Python 2.6", - space.w_DeprecationWarning) + msg = "BaseException.message has been deprecated as of Python 2.6" + space.warn(space.wrap(msg), space.w_DeprecationWarning) return self.w_message def descr_message_set(self, space, w_new): diff --git a/pypy/module/gc/test/test_ztranslation.py b/pypy/module/gc/test/test_ztranslation.py new file mode 100644 --- /dev/null +++ b/pypy/module/gc/test/test_ztranslation.py @@ -0,0 +1,4 @@ +from pypy.objspace.fake.checkmodule import checkmodule + +def test_checkmodule(): + checkmodule('gc') diff --git a/pypy/module/imp/importing.py b/pypy/module/imp/importing.py --- a/pypy/module/imp/importing.py +++ b/pypy/module/imp/importing.py @@ -174,9 +174,9 @@ "Parent module '%s' not loaded, " "cannot perform relative import" % ctxt_package)) else: - space.warn("Parent module '%s' not found " - "while handling absolute import" % ctxt_package, - space.w_RuntimeWarning) + msg = ("Parent module '%s' not found while handling absolute " + "import" % ctxt_package) + space.warn(space.wrap(msg), space.w_RuntimeWarning) rel_modulename = ctxt_package[:dot_position] rel_level = rel_modulename.count('.') + 1 @@ -533,9 +533,9 @@ if modtype in (PY_SOURCE, PY_COMPILED): return FindInfo(PKG_DIRECTORY, filepart, None) else: - msg = "Not importing directory " +\ - "'%s' missing __init__.py" % (filepart,) - space.warn(msg, space.w_ImportWarning) + msg = ("Not importing directory '%s' missing __init__.py" % + (filepart,)) + space.warn(space.wrap(msg), space.w_ImportWarning) modtype, suffix, filemode = find_modtype(space, filepart) try: if modtype in (PY_SOURCE, PY_COMPILED, C_EXTENSION): diff --git a/pypy/module/micronumpy/app_numpy.py b/pypy/module/micronumpy/app_numpy.py --- a/pypy/module/micronumpy/app_numpy.py +++ b/pypy/module/micronumpy/app_numpy.py @@ -67,11 +67,15 @@ def min(a, axis=None, out=None): if not hasattr(a, "min"): a = _numpypy.array(a) + if a.size < 1: + return _numpypy.array([]) return a.min(axis=axis, out=out) def max(a, axis=None, out=None): if not hasattr(a, "max"): a = _numpypy.array(a) + if a.size < 1: + return _numpypy.array([]) return a.max(axis=axis, out=out) def arange(start, stop=None, step=1, dtype=None): diff --git a/pypy/module/micronumpy/interp_numarray.py b/pypy/module/micronumpy/interp_numarray.py --- a/pypy/module/micronumpy/interp_numarray.py +++ b/pypy/module/micronumpy/interp_numarray.py @@ -250,7 +250,7 @@ ret = self.implementation.get_imag(self) if ret: return W_NDimArray(ret) - raise OperationError(space.w_NotImplementedError, + raise OperationError(space.w_NotImplementedError, space.wrap('imag not implemented for this dtype')) def descr_set_real(self, space, w_value): @@ -261,7 +261,7 @@ def descr_set_imag(self, space, w_value): # if possible, copy (broadcast) values into self if not self.get_dtype().is_complex_type(): - raise OperationError(space.w_TypeError, + raise OperationError(space.w_TypeError, space.wrap('array does not have imaginary part to set')) tmp = self.implementation.get_imag(self) tmp.setslice(space, convert_to_array(space, w_value)) @@ -302,11 +302,11 @@ @unwrap_spec(axis1=int, axis2=int) def descr_swapaxes(self, space, axis1, axis2): """a.swapaxes(axis1, axis2) - + Return a view of the array with `axis1` and `axis2` interchanged. - + Refer to `numpy.swapaxes` for full documentation. - + See Also -------- numpy.swapaxes : equivalent function @@ -439,7 +439,7 @@ ret = impl.base() if ret is None: return space.w_None - return ret + return ret @unwrap_spec(inplace=bool) def descr_byteswap(self, space, inplace=False): @@ -492,7 +492,7 @@ "axis1 and axis2 cannot be the same")) return interp_arrayops.diagonal(space, self.implementation, offset, axis1, axis2) - + def descr_dump(self, space, w_file): raise OperationError(space.w_NotImplementedError, space.wrap( "dump not implemented yet")) @@ -509,7 +509,7 @@ raise OperationError(space.w_NotImplementedError, space.wrap( "setting flags not implemented yet")) - @unwrap_spec(offset=int) + @unwrap_spec(offset=int) def descr_getfield(self, space, w_dtype, offset): raise OperationError(space.w_NotImplementedError, space.wrap( "getfield not implemented yet")) @@ -518,7 +518,7 @@ raise OperationError(space.w_NotImplementedError, space.wrap( "itemset not implemented yet")) - @unwrap_spec(neworder=str) + @unwrap_spec(neworder=str) def descr_newbyteorder(self, space, neworder): raise OperationError(space.w_NotImplementedError, space.wrap( "newbyteorder not implemented yet")) @@ -551,7 +551,7 @@ raise OperationError(space.w_NotImplementedError, space.wrap( "setfield not implemented yet")) - def descr_setflags(self, space, w_write=None, w_align=None, w_uic=None): + def descr_setflags(self, space, w_write=None, w_align=None, w_uic=None): raise OperationError(space.w_NotImplementedError, space.wrap( "setflags not implemented yet")) @@ -572,7 +572,7 @@ "tofile not implemented yet")) def descr_trace(self, space, w_offset=0, w_axis1=0, w_axis2=1, - w_dtype=None, w_out=None): + w_dtype=None, w_out=None): raise OperationError(space.w_NotImplementedError, space.wrap( "trace not implemented yet")) @@ -627,12 +627,23 @@ w_remainder = self.descr_mod(space, w_other) return space.newtuple([w_quotient, w_remainder]) - descr_eq = _binop_impl("equal") - descr_ne = _binop_impl("not_equal") - descr_lt = _binop_impl("less") - descr_le = _binop_impl("less_equal") - descr_gt = _binop_impl("greater") - descr_ge = _binop_impl("greater_equal") + def _binop_comp_impl(ufunc): + def impl(self, space, w_other, w_out=None): + try: + return ufunc(self, space, w_other, w_out) + except OperationError, e: + if e.match(space, space.w_ValueError): + return space.w_False + raise e + + return func_with_new_name(impl, ufunc.func_name) + + descr_eq = _binop_comp_impl(_binop_impl("equal")) + descr_ne = _binop_comp_impl(_binop_impl("not_equal")) + descr_lt = _binop_comp_impl(_binop_impl("less")) + descr_le = _binop_comp_impl(_binop_impl("less_equal")) + descr_gt = _binop_comp_impl(_binop_impl("greater")) + descr_ge = _binop_comp_impl(_binop_impl("greater_equal")) def _binop_right_impl(ufunc_name): def impl(self, space, w_other, w_out=None): @@ -698,7 +709,7 @@ if space.is_none(w_out): out = None elif not isinstance(w_out, W_NDimArray): - raise OperationError(space.w_TypeError, space.wrap( + raise OperationError(space.w_TypeError, space.wrap( 'output must be an array')) else: out = w_out @@ -718,7 +729,7 @@ descr_cumsum = _reduce_ufunc_impl('add', cumultative=True) descr_cumprod = _reduce_ufunc_impl('multiply', cumultative=True) - + def descr_mean(self, space, w_axis=None, w_out=None): if space.is_none(w_axis): w_denom = space.wrap(self.get_size()) @@ -863,7 +874,7 @@ swapaxes = interp2app(W_NDimArray.descr_swapaxes), flat = GetSetProperty(W_NDimArray.descr_get_flatiter), item = interp2app(W_NDimArray.descr_item), - real = GetSetProperty(W_NDimArray.descr_get_real, + real = GetSetProperty(W_NDimArray.descr_get_real, W_NDimArray.descr_set_real), imag = GetSetProperty(W_NDimArray.descr_get_imag, W_NDimArray.descr_set_imag), @@ -923,7 +934,7 @@ dtype) #if dtype is interp_dtype.get_dtype_cache(space).w_float64dtype: # break - + if dtype is None: dtype = interp_dtype.get_dtype_cache(space).w_float64dtype if ndmin > len(shape): diff --git a/pypy/module/micronumpy/test/test_module.py b/pypy/module/micronumpy/test/test_module.py --- a/pypy/module/micronumpy/test/test_module.py +++ b/pypy/module/micronumpy/test/test_module.py @@ -13,11 +13,13 @@ assert sum(array(range(10))) == 45 def test_min(self): - from _numpypy import array, min + from _numpypy import array, min, zeros assert min(range(10)) == 0 assert min(array(range(10))) == 0 + assert list(min(zeros((0, 2)), axis=1)) == [] def test_max(self): - from _numpypy import array, max + from _numpypy import array, max, zeros assert max(range(10)) == 9 assert max(array(range(10))) == 9 + assert list(max(zeros((0, 2)), axis=1)) == [] diff --git a/pypy/module/micronumpy/test/test_numarray.py b/pypy/module/micronumpy/test/test_numarray.py --- a/pypy/module/micronumpy/test/test_numarray.py +++ b/pypy/module/micronumpy/test/test_numarray.py @@ -1,5 +1,5 @@ - -import py, sys +import py +import sys from pypy.conftest import option from pypy.module.micronumpy.appbridge import get_appbridge_cache From noreply at buildbot.pypy.org Thu Feb 21 22:52:56 2013 From: noreply at buildbot.pypy.org (mattip) Date: Thu, 21 Feb 2013 22:52:56 +0100 (CET) Subject: [pypy-commit] pypy numpy-unify-methods: remove nonsense Message-ID: <20130221215256.981D61C124F@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: numpy-unify-methods Changeset: r61567:4ef81c9388b0 Date: 2013-02-21 23:41 +0200 http://bitbucket.org/pypy/pypy/changeset/4ef81c9388b0/ Log: remove nonsense diff --git a/pypy/module/micronumpy/test/test_ufuncs.py b/pypy/module/micronumpy/test/test_ufuncs.py --- a/pypy/module/micronumpy/test/test_ufuncs.py +++ b/pypy/module/micronumpy/test/test_ufuncs.py @@ -99,7 +99,6 @@ #assert e.message.startswith('ufunc') uncallable.append(s) i+= 1 - assert i == 47 #numpy 1.7.0 return uncallable a = np.array(0,'int64') uncallable = find_uncallable_ufuncs(a) From noreply at buildbot.pypy.org Thu Feb 21 22:52:57 2013 From: noreply at buildbot.pypy.org (mattip) Date: Thu, 21 Feb 2013 22:52:57 +0100 (CET) Subject: [pypy-commit] pypy numpy-unify-methods: fix list of non-callable ufuncs for complex Message-ID: <20130221215257.D189A1C124F@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: numpy-unify-methods Changeset: r61568:2c821fe56f19 Date: 2013-02-21 23:52 +0200 http://bitbucket.org/pypy/pypy/changeset/2c821fe56f19/ Log: fix list of non-callable ufuncs for complex diff --git a/pypy/module/micronumpy/test/test_ufuncs.py b/pypy/module/micronumpy/test/test_ufuncs.py --- a/pypy/module/micronumpy/test/test_ufuncs.py +++ b/pypy/module/micronumpy/test/test_ufuncs.py @@ -111,11 +111,11 @@ assert len(uncallable) == 2 and set(uncallable) == set(['bitwise_not', 'invert']) a = np.array(1.0,'complex') uncallable = find_uncallable_ufuncs(a) - assert len(uncallable) == 14 + assert len(uncallable) == 13 assert set(uncallable) == \ set(['bitwise_not', 'ceil', 'deg2rad', 'degrees', 'fabs', 'floor', - 'rad2deg', 'invert', 'spacing', 'radians', 'frexp', 'signbit', - 'modf', 'trunc']) + 'rad2deg', 'invert', 'isneginf', 'isposinf', 'radians', 'signbit', + 'trunc']) def test_int_only(self): from _numpypy import bitwise_and, array From noreply at buildbot.pypy.org Thu Feb 21 23:20:08 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Thu, 21 Feb 2013 23:20:08 +0100 (CET) Subject: [pypy-commit] pypy default: Add a readline() implementation for _io.BytesIO which should be faster than _io._BufferedIOBase's one. Message-ID: <20130221222008.990311C0228@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: Changeset: r61569:da67e5b7be9e Date: 2013-02-21 23:17 +0100 http://bitbucket.org/pypy/pypy/changeset/da67e5b7be9e/ Log: Add a readline() implementation for _io.BytesIO which should be faster than _io._BufferedIOBase's one. diff --git a/pypy/module/_io/interp_bytesio.py b/pypy/module/_io/interp_bytesio.py --- a/pypy/module/_io/interp_bytesio.py +++ b/pypy/module/_io/interp_bytesio.py @@ -52,6 +52,25 @@ self.pos += size return space.wrap(output) + def readline_w(self, space, w_limit=None): + self._check_closed(space) + limit = convert_size(space, w_limit) + + cur_pos = self.pos + if limit < 0: + end_pos = self.string_size + else: + end_pos = min(cur_pos + limit, self.string_size) + while cur_pos != end_pos: + if self.buf[cur_pos] == '\n': + cur_pos += 1 + break + cur_pos += 1 + + output = buffer2string(self.buf, self.pos, cur_pos) + self.pos = cur_pos + return space.wrap(output) + def read1_w(self, space, w_size): return self.read_w(space, w_size) @@ -209,6 +228,7 @@ read = interp2app(W_BytesIO.read_w), read1 = interp2app(W_BytesIO.read1_w), + readline = interp2app(W_BytesIO.readline_w), readinto = interp2app(W_BytesIO.readinto_w), write = interp2app(W_BytesIO.write_w), truncate = interp2app(W_BytesIO.truncate_w), diff --git a/pypy/module/_io/test/test_bytesio.py b/pypy/module/_io/test/test_bytesio.py --- a/pypy/module/_io/test/test_bytesio.py +++ b/pypy/module/_io/test/test_bytesio.py @@ -75,3 +75,19 @@ b = _io.BytesIO("hello") b.close() raises(ValueError, b.readinto, bytearray("hello")) + + def test_readline(self): + import _io + f = _io.BytesIO(b'abc\ndef\nxyzzy\nfoo\x00bar\nanother line') + assert f.readline() == b'abc\n' + assert f.readline(10) == b'def\n' + assert f.readline(2) == b'xy' + assert f.readline(4) == b'zzy\n' + assert f.readline() == b'foo\x00bar\n' + assert f.readline(None) == b'another line' + raises(TypeError, f.readline, 5.3) + + def test_overread(self): + import _io + f = _io.BytesIO(b'abc') + assert f.readline(10) == b'abc' From noreply at buildbot.pypy.org Thu Feb 21 23:28:47 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Thu, 21 Feb 2013 23:28:47 +0100 (CET) Subject: [pypy-commit] pypy py3k: hg merge default Message-ID: <20130221222847.B971E1C0237@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: py3k Changeset: r61570:1988eaba1a6d Date: 2013-02-21 23:26 +0100 http://bitbucket.org/pypy/pypy/changeset/1988eaba1a6d/ Log: hg merge default diff --git a/pypy/module/_io/interp_bytesio.py b/pypy/module/_io/interp_bytesio.py --- a/pypy/module/_io/interp_bytesio.py +++ b/pypy/module/_io/interp_bytesio.py @@ -67,6 +67,25 @@ self.pos += size return space.wrapbytes(output) + def readline_w(self, space, w_limit=None): + self._check_closed(space) + limit = convert_size(space, w_limit) + + cur_pos = self.pos + if limit < 0: + end_pos = self.string_size + else: + end_pos = min(cur_pos + limit, self.string_size) + while cur_pos != end_pos: + if self.buf[cur_pos] == '\n': + cur_pos += 1 + break + cur_pos += 1 + + output = buffer2string(self.buf, self.pos, cur_pos) + self.pos = cur_pos + return space.wrap(output) + def read1_w(self, space, w_size): return self.read_w(space, w_size) @@ -228,6 +247,7 @@ read = interp2app(W_BytesIO.read_w), read1 = interp2app(W_BytesIO.read1_w), + readline = interp2app(W_BytesIO.readline_w), readinto = interp2app(W_BytesIO.readinto_w), write = interp2app(W_BytesIO.write_w), truncate = interp2app(W_BytesIO.truncate_w), diff --git a/pypy/module/_io/test/test_bytesio.py b/pypy/module/_io/test/test_bytesio.py --- a/pypy/module/_io/test/test_bytesio.py +++ b/pypy/module/_io/test/test_bytesio.py @@ -92,3 +92,18 @@ del buf memio.truncate() + def test_readline(self): + import _io + f = _io.BytesIO(b'abc\ndef\nxyzzy\nfoo\x00bar\nanother line') + assert f.readline() == b'abc\n' + assert f.readline(10) == b'def\n' + assert f.readline(2) == b'xy' + assert f.readline(4) == b'zzy\n' + assert f.readline() == b'foo\x00bar\n' + assert f.readline(None) == b'another line' + raises(TypeError, f.readline, 5.3) + + def test_overread(self): + import _io + f = _io.BytesIO(b'abc') + assert f.readline(10) == b'abc' From noreply at buildbot.pypy.org Thu Feb 21 23:28:48 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Thu, 21 Feb 2013 23:28:48 +0100 (CET) Subject: [pypy-commit] pypy py3k: Adapt for py3k. Message-ID: <20130221222848.DE9D51C0237@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: py3k Changeset: r61571:a67c05d6af91 Date: 2013-02-21 23:28 +0100 http://bitbucket.org/pypy/pypy/changeset/a67c05d6af91/ Log: Adapt for py3k. diff --git a/pypy/module/_io/interp_bytesio.py b/pypy/module/_io/interp_bytesio.py --- a/pypy/module/_io/interp_bytesio.py +++ b/pypy/module/_io/interp_bytesio.py @@ -84,7 +84,7 @@ output = buffer2string(self.buf, self.pos, cur_pos) self.pos = cur_pos - return space.wrap(output) + return space.wrapbytes(output) def read1_w(self, space, w_size): return self.read_w(space, w_size) From noreply at buildbot.pypy.org Thu Feb 21 23:42:41 2013 From: noreply at buildbot.pypy.org (amauryfa) Date: Thu, 21 Feb 2013 23:42:41 +0100 (CET) Subject: [pypy-commit] pypy py3k: Fix docstring-only test functions (a hack to test python3-only syntax) Message-ID: <20130221224241.384EE1C124F@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: py3k Changeset: r61572:01ed12fd958d Date: 2013-02-21 23:41 +0100 http://bitbucket.org/pypy/pypy/changeset/01ed12fd958d/ Log: Fix docstring-only test functions (a hack to test python3-only syntax) diff --git a/pypy/tool/pytest/apptest.py b/pypy/tool/pytest/apptest.py --- a/pypy/tool/pytest/apptest.py +++ b/pypy/tool/pytest/apptest.py @@ -118,7 +118,11 @@ defs.append("self.%s = %s\n" % (symbol, py3k_repr(value))) source = py.code.Source(target_)[1:] pyfile = udir.join('src.py') - target_name = target_.__name__ + if isinstance(target_, str): + # Special case of a docstring; the function name is the first word. + target_name = target_.split('(', 1)[0] + else: + target_name = target_.__name__ with pyfile.open('w') as f: f.write(helpers) f.write('\n'.join(defs)) From noreply at buildbot.pypy.org Fri Feb 22 01:23:09 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Fri, 22 Feb 2013 01:23:09 +0100 (CET) Subject: [pypy-commit] pypy py3k: Don't avoid returning -1 as hash value. Message-ID: <20130222002309.54EF21C0228@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: py3k Changeset: r61573:235bcc368b18 Date: 2013-02-22 01:22 +0100 http://bitbucket.org/pypy/pypy/changeset/235bcc368b18/ Log: Don't avoid returning -1 as hash value. diff --git a/lib-python/3.2/decimal.py b/lib-python/3.2/decimal.py --- a/lib-python/3.2/decimal.py +++ b/lib-python/3.2/decimal.py @@ -959,7 +959,7 @@ exp_hash = pow(_PyHASH_10INV, -self._exp, _PyHASH_MODULUS) hash_ = int(self._int) * exp_hash % _PyHASH_MODULUS ans = hash_ if self >= 0 else -hash_ - return -2 if ans == -1 else ans + return ans def as_tuple(self): """Represents the number as a triple tuple. From noreply at buildbot.pypy.org Fri Feb 22 01:26:25 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Fri, 22 Feb 2013 01:26:25 +0100 (CET) Subject: [pypy-commit] pypy py3k: Same here. Message-ID: <20130222002625.D61631C0228@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: py3k Changeset: r61574:a20722978155 Date: 2013-02-22 01:25 +0100 http://bitbucket.org/pypy/pypy/changeset/a20722978155/ Log: Same here. diff --git a/lib-python/3.2/fractions.py b/lib-python/3.2/fractions.py --- a/lib-python/3.2/fractions.py +++ b/lib-python/3.2/fractions.py @@ -547,7 +547,7 @@ else: hash_ = abs(self._numerator) * dinv % _PyHASH_MODULUS result = hash_ if self >= 0 else -hash_ - return -2 if result == -1 else result + return result def __eq__(a, b): """a == b""" From noreply at buildbot.pypy.org Fri Feb 22 01:38:41 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Fri, 22 Feb 2013 01:38:41 +0100 (CET) Subject: [pypy-commit] pypy py3k: hg backout a20722978155 Message-ID: <20130222003841.710701C1393@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: py3k Changeset: r61575:60ad835b0972 Date: 2013-02-22 01:36 +0100 http://bitbucket.org/pypy/pypy/changeset/60ad835b0972/ Log: hg backout a20722978155 diff --git a/lib-python/3.2/fractions.py b/lib-python/3.2/fractions.py --- a/lib-python/3.2/fractions.py +++ b/lib-python/3.2/fractions.py @@ -547,7 +547,7 @@ else: hash_ = abs(self._numerator) * dinv % _PyHASH_MODULUS result = hash_ if self >= 0 else -hash_ - return result + return -2 if result == -1 else result def __eq__(a, b): """a == b""" From noreply at buildbot.pypy.org Fri Feb 22 01:38:42 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Fri, 22 Feb 2013 01:38:42 +0100 (CET) Subject: [pypy-commit] pypy py3k: hg backout 235bcc368b18 Message-ID: <20130222003842.C19561C1393@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: py3k Changeset: r61576:fa5cde0dc7f0 Date: 2013-02-22 01:37 +0100 http://bitbucket.org/pypy/pypy/changeset/fa5cde0dc7f0/ Log: hg backout 235bcc368b18 diff --git a/lib-python/3.2/decimal.py b/lib-python/3.2/decimal.py --- a/lib-python/3.2/decimal.py +++ b/lib-python/3.2/decimal.py @@ -959,7 +959,7 @@ exp_hash = pow(_PyHASH_10INV, -self._exp, _PyHASH_MODULUS) hash_ = int(self._int) * exp_hash % _PyHASH_MODULUS ans = hash_ if self >= 0 else -hash_ - return ans + return -2 if ans == -1 else ans def as_tuple(self): """Represents the number as a triple tuple. From noreply at buildbot.pypy.org Fri Feb 22 01:41:26 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Fri, 22 Feb 2013 01:41:26 +0100 (CET) Subject: [pypy-commit] pypy py3k: ensure __cached__ Message-ID: <20130222004126.2295F1C0237@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61577:130ac0517e82 Date: 2013-02-21 16:01 -0800 http://bitbucket.org/pypy/pypy/changeset/130ac0517e82/ Log: ensure __cached__ diff --git a/pypy/interpreter/app_main.py b/pypy/interpreter/app_main.py --- a/pypy/interpreter/app_main.py +++ b/pypy/interpreter/app_main.py @@ -584,6 +584,7 @@ 'exec') exec_(co_python_startup, mainmodule.__dict__) mainmodule.__file__ = python_startup + mainmodule.__cached__ = None run_toplevel(run_it) try: del mainmodule.__file__ @@ -597,12 +598,14 @@ co_stdin = compile(sys.stdin.read(), '', 'exec') exec_(co_stdin, mainmodule.__dict__) mainmodule.__file__ = '' + mainmodule.__cached__ = None success = run_toplevel(run_it) else: # handle the common case where a filename is specified # on the command-line. filename = sys.argv[0] mainmodule.__file__ = filename + mainmodule.__cached__ = None sys.path.insert(0, sys.pypy_resolvedirof(filename)) # assume it's a pyc file only if its name says so. # CPython goes to great lengths to detect other cases diff --git a/pypy/interpreter/test2/test_app_main.py b/pypy/interpreter/test2/test_app_main.py --- a/pypy/interpreter/test2/test_app_main.py +++ b/pypy/interpreter/test2/test_app_main.py @@ -66,6 +66,7 @@ print('hello') print('Name:', __name__) print('File:', __file__) + print('Cached:', __cached__) import sys print('Exec:', sys.executable) print('Argv:', sys.argv) From noreply at buildbot.pypy.org Fri Feb 22 01:41:27 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Fri, 22 Feb 2013 01:41:27 +0100 (CET) Subject: [pypy-commit] pypy py3k: make __file/cached__ overwriting optional in _run_compiled_module as app_main Message-ID: <20130222004127.7D8141C0237@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61578:8632713d526b Date: 2013-02-21 16:03 -0800 http://bitbucket.org/pypy/pypy/changeset/8632713d526b/ Log: make __file/cached__ overwriting optional in _run_compiled_module as app_main doesn't want it diff --git a/pypy/interpreter/app_main.py b/pypy/interpreter/app_main.py --- a/pypy/interpreter/app_main.py +++ b/pypy/interpreter/app_main.py @@ -615,7 +615,7 @@ filename = filename.lower() if filename.endswith('.pyc') or filename.endswith('.pyo'): args = (imp._run_compiled_module, '__main__', - sys.argv[0], None, mainmodule) + sys.argv[0], None, mainmodule, False) else: # maybe it's the name of a directory or a zip file filename = sys.argv[0] @@ -762,7 +762,7 @@ # add an emulator for these pypy-only or 2.7-only functions # (for test_pyc_commandline_argument) import imp, runpy - def _run_compiled_module(modulename, filename, file, module): + def _run_compiled_module(modulename, filename, file, module, write_paths): import os assert modulename == '__main__' assert os.path.isfile(filename) diff --git a/pypy/module/imp/importing.py b/pypy/module/imp/importing.py --- a/pypy/module/imp/importing.py +++ b/pypy/module/imp/importing.py @@ -856,17 +856,19 @@ pycode = ec.compiler.compile(source, pathname, 'exec', 0) return pycode -def exec_code_module(space, w_mod, code_w, pathname, cpathname): +def exec_code_module(space, w_mod, code_w, pathname, cpathname, + write_paths=True): w_dict = space.getattr(w_mod, space.wrap('__dict__')) space.call_method(w_dict, 'setdefault', space.wrap('__builtins__'), space.wrap(space.builtin)) - if pathname is not None: - w_pathname = get_sourcefile(space, pathname) - else: - w_pathname = space.wrap(code_w.co_filename) - space.setitem(w_dict, space.wrap("__file__"), w_pathname) - space.setitem(w_dict, space.wrap("__cached__"), space.wrap(cpathname)) + if write_paths: + if pathname is not None: + w_pathname = get_sourcefile(space, pathname) + else: + w_pathname = space.wrap(code_w.co_filename) + space.setitem(w_dict, space.wrap("__file__"), w_pathname) + space.setitem(w_dict, space.wrap("__cached__"), space.wrap(cpathname)) code_w.exec_code(space, w_dict, w_dict) def rightmost_sep(filename): @@ -1065,7 +1067,7 @@ @jit.dont_look_inside def load_compiled_module(space, w_modulename, w_mod, cpathname, magic, - timestamp, source): + timestamp, source, write_paths=True): """ Load a module from a compiled file, execute it, and return its module object. @@ -1076,7 +1078,7 @@ "Bad magic number in %s", cpathname) #print "loading pyc file:", cpathname code_w = read_compiled_module(space, cpathname, source) - exec_code_module(space, w_mod, code_w, cpathname, cpathname) + exec_code_module(space, w_mod, code_w, cpathname, cpathname, write_paths) return w_mod diff --git a/pypy/module/imp/interp_imp.py b/pypy/module/imp/interp_imp.py --- a/pypy/module/imp/interp_imp.py +++ b/pypy/module/imp/interp_imp.py @@ -138,8 +138,9 @@ stream.close() return w_mod - at unwrap_spec(filename='str0') -def _run_compiled_module(space, w_modulename, filename, w_file, w_module): + at unwrap_spec(filename='str0', write_paths=bool) +def _run_compiled_module(space, w_modulename, filename, w_file, w_module, + write_paths=True): # the function 'imp._run_compiled_module' is a pypy-only extension stream = get_file(space, w_file, filename, 'rb') @@ -148,7 +149,7 @@ importing.load_compiled_module( space, w_modulename, w_module, filename, magic, timestamp, - stream.readall()) + stream.readall(), write_paths) if space.is_none(w_file): stream.close() From noreply at buildbot.pypy.org Fri Feb 22 01:41:28 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Fri, 22 Feb 2013 01:41:28 +0100 (CET) Subject: [pypy-commit] pypy py3k: merge upstream Message-ID: <20130222004128.B17DC1C0237@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61579:80cbaa6d2c4e Date: 2013-02-21 16:40 -0800 http://bitbucket.org/pypy/pypy/changeset/80cbaa6d2c4e/ Log: merge upstream From noreply at buildbot.pypy.org Fri Feb 22 01:41:30 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Fri, 22 Feb 2013 01:41:30 +0100 (CET) Subject: [pypy-commit] pypy py3k: kill stupid softspace because it's stupid Message-ID: <20130222004130.056CA1C0237@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61580:442dad67f48e Date: 2013-02-21 16:40 -0800 http://bitbucket.org/pypy/pypy/changeset/442dad67f48e/ Log: kill stupid softspace because it's stupid diff --git a/pypy/interpreter/app_main.py b/pypy/interpreter/app_main.py --- a/pypy/interpreter/app_main.py +++ b/pypy/interpreter/app_main.py @@ -47,24 +47,11 @@ """Calls f() and handles all OperationErrors. Intended use is to run the main program or one interactive statement. run_protected() handles details like forwarding exceptions to - sys.excepthook(), catching SystemExit, printing a newline after - sys.stdout if needed, etc. + sys.excepthook(), catching SystemExit, etc. """ try: # run it f(*fargs, **fkwds) - - # we arrive here if no exception is raised. stdout cosmetics... - try: - stdout = sys.stdout - softspace = stdout.softspace - except AttributeError: - pass - # Don't crash if user defined stdout doesn't have softspace - else: - if softspace: - stdout.write('\n') - except SystemExit as e: handle_sys_exit(e) except: diff --git a/pypy/interpreter/main.py b/pypy/interpreter/main.py --- a/pypy/interpreter/main.py +++ b/pypy/interpreter/main.py @@ -95,25 +95,11 @@ """Calls f() and handle all OperationErrors. Intended use is to run the main program or one interactive statement. run_protected() handles details like forwarding exceptions to - sys.excepthook(), catching SystemExit, printing a newline after - sys.stdout if needed, etc. + sys.excepthook(), catching SystemExit, etc. """ try: # run it f() - - # we arrive here if no exception is raised. stdout cosmetics... - try: - w_stdout = space.sys.get('stdout') - w_softspace = space.getattr(w_stdout, space.wrap('softspace')) - except OperationError, e: - if not e.match(space, space.w_AttributeError): - raise - # Don't crash if user defined stdout doesn't have softspace - else: - if space.is_true(w_softspace): - space.call_method(w_stdout, 'write', space.wrap('\n')) - except OperationError, operationerr: operationerr.normalize_exception(space) w_type = operationerr.w_type diff --git a/pypy/interpreter/pyopcode.py b/pypy/interpreter/pyopcode.py --- a/pypy/interpreter/pyopcode.py +++ b/pypy/interpreter/pyopcode.py @@ -1472,43 +1472,20 @@ displayhook(obj) def print_item_to(x, stream): - if file_softspace(stream, False): - stream.write(" ") - # give to write() an argument which is either a string or a unicode # (and let it deals itself with unicode handling) if not isinstance(x, str): x = str(x) stream.write(x) - # add a softspace unless we just printed a string which ends in a '\t' - # or '\n' -- or more generally any whitespace character but ' ' - if x: - lastchar = x[-1] - if lastchar.isspace() and lastchar != ' ': - return - file_softspace(stream, True) - def print_item(x): print_item_to(x, sys_stdout()) def print_newline_to(stream): stream.write("\n") - file_softspace(stream, False) def print_newline(): print_newline_to(sys_stdout()) - - def file_softspace(file, newflag): - try: - softspace = file.softspace - except AttributeError: - softspace = 0 - try: - file.softspace = newflag - except AttributeError: - pass - return softspace ''', filename=__file__) sys_stdout = app.interphook('sys_stdout') @@ -1517,7 +1494,6 @@ print_item_to = app.interphook('print_item_to') print_newline = app.interphook('print_newline') print_newline_to= app.interphook('print_newline_to') -file_softspace = app.interphook('file_softspace') app = gateway.applevel(r''' def find_metaclass(bases, namespace, globals, builtin): diff --git a/pypy/interpreter/test/test_interpreter.py b/pypy/interpreter/test/test_interpreter.py --- a/pypy/interpreter/test/test_interpreter.py +++ b/pypy/interpreter/test/test_interpreter.py @@ -308,7 +308,6 @@ assert out.data == [(str, chr(0xa2)), (str, "\n")] del out.data[:] del out.encoding - # we don't care about softspace anymore print("foo\t", "bar\n", "trick", "baz\n") assert out.data == [(str, "foo\t"), (str, " "), diff --git a/pypy/module/__builtin__/test/test_rawinput.py b/pypy/module/__builtin__/test/test_rawinput.py --- a/pypy/module/__builtin__/test/test_rawinput.py +++ b/pypy/module/__builtin__/test/test_rawinput.py @@ -51,52 +51,3 @@ finally: sys.stdin = stdin assert result == 'foo' - - def test_softspace(self): - import sys - import io - fin = io.StringIO() - fout = io.StringIO() - - fin.write("Coconuts\n") - fin.seek(0) - - sys_stdin_orig = sys.stdin - sys_stdout_orig = sys.stdout - - sys.stdin = fin - sys.stdout = fout - - print("test", end='') - input("test") - - sys.stdin = sys_stdin_orig - sys.stdout = sys_stdout_orig - - fout.seek(0) - assert fout.read() == "testtest" - - def test_softspace_carryover(self): - import sys - import io - fin = io.StringIO() - fout = io.StringIO() - - fin.write("Coconuts\n") - fin.seek(0) - - sys_stdin_orig = sys.stdin - sys_stdout_orig = sys.stdout - - sys.stdin = fin - sys.stdout = fout - - print("test", end='') - input("test") - print("test", end='') - - sys.stdin = sys_stdin_orig - sys.stdout = sys_stdout_orig - - fout.seek(0) - assert fout.read() == "testtesttest" diff --git a/pypy/module/cpyext/pyfile.py b/pypy/module/cpyext/pyfile.py --- a/pypy/module/cpyext/pyfile.py +++ b/pypy/module/cpyext/pyfile.py @@ -81,27 +81,3 @@ def PyFile_Name(space, w_p): """Return the name of the file specified by p as a string object.""" return borrow_from(w_p, space.getattr(w_p, space.wrap("name"))) - - at cpython_api([PyObject, rffi.INT_real], rffi.INT_real, error=CANNOT_FAIL) -def PyFile_SoftSpace(space, w_p, newflag): - """ - This function exists for internal use by the interpreter. Set the - softspace attribute of p to newflag and return the previous value. - p does not have to be a file object for this function to work - properly; any object is supported (thought its only interesting if - the softspace attribute can be set). This function clears any - errors, and will return 0 as the previous value if the attribute - either does not exist or if there were errors in retrieving it. - There is no way to detect errors from this function, but doing so - should not be needed.""" - try: - if rffi.cast(lltype.Signed, newflag): - w_newflag = space.w_True - else: - w_newflag = space.w_False - oldflag = space.int_w(space.getattr(w_p, space.wrap("softspace"))) - space.setattr(w_p, space.wrap("softspace"), w_newflag) - return oldflag - except OperationError, e: - return 0 - diff --git a/pypy/module/cpyext/test/test_pyfile.py b/pypy/module/cpyext/test/test_pyfile.py --- a/pypy/module/cpyext/test/test_pyfile.py +++ b/pypy/module/cpyext/test/test_pyfile.py @@ -83,19 +83,3 @@ out, err = capfd.readouterr() out = out.replace('\r\n', '\n') assert out == "test\n'test\\n'" - - def test_file_softspace(self, space, api, capfd): - w_stdout = space.sys.get("stdout") - assert api.PyFile_SoftSpace(w_stdout, 1) == 0 - assert api.PyFile_SoftSpace(w_stdout, 0) == 1 - - api.PyFile_SoftSpace(w_stdout, 1) - w_ns = space.newdict() - space.exec_("print 1,", w_ns, w_ns) - space.exec_("print 2,", w_ns, w_ns) - api.PyFile_SoftSpace(w_stdout, 0) - space.exec_("print 3", w_ns, w_ns) - space.call_method(w_stdout, "flush") - out, err = capfd.readouterr() - out = out.replace('\r\n', '\n') - assert out == " 1 23\n" From noreply at buildbot.pypy.org Fri Feb 22 01:59:07 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Fri, 22 Feb 2013 01:59:07 +0100 (CET) Subject: [pypy-commit] pypy py3k-newhash: modernize float's hash Message-ID: <20130222005907.B4A4C1C0237@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k-newhash Changeset: r61581:32410af09b82 Date: 2013-02-21 16:42 -0800 http://bitbucket.org/pypy/pypy/changeset/32410af09b82/ Log: modernize float's hash diff --git a/pypy/module/sys/system.py b/pypy/module/sys/system.py --- a/pypy/module/sys/system.py +++ b/pypy/module/sys/system.py @@ -2,7 +2,7 @@ from pypy.interpreter import gateway from rpython.rlib import rfloat, rbigint from rpython.rtyper.lltypesystem import rffi, lltype -from pypy.objspace.std.floatobject import HASH_INF, HASH_NAN +from pypy.objspace.std.floatobject import HASH_INF, HASH_MODULUS, HASH_NAN from pypy.objspace.std.complexobject import HASH_IMAG @@ -65,11 +65,9 @@ return space.call_function(w_int_info, space.newtuple(info_w)) def get_hash_info(space): - # XXX our _hash_float() always give values that fit in 32bit - modulus = (1 << 31) - 1 # Must be a prime number info_w = [ space.wrap(8 * rffi.sizeof(lltype.Signed)), - space.wrap(modulus), + space.wrap(HASH_MODULUS), space.wrap(HASH_INF), space.wrap(HASH_NAN), space.wrap(HASH_IMAG), diff --git a/pypy/objspace/std/complexobject.py b/pypy/objspace/std/complexobject.py --- a/pypy/objspace/std/complexobject.py +++ b/pypy/objspace/std/complexobject.py @@ -129,7 +129,7 @@ hashreal = _hash_float(space, w_value.realval) hashimg = _hash_float(space, w_value.imagval) combined = intmask(hashreal + HASH_IMAG * hashimg) - return space.newint(combined) + return space.newint(-2 if combined == -1 else combined) def add__Complex_Complex(space, w_complex1, w_complex2): return W_ComplexObject(w_complex1.realval + w_complex2.realval, diff --git a/pypy/objspace/std/floatobject.py b/pypy/objspace/std/floatobject.py --- a/pypy/objspace/std/floatobject.py +++ b/pypy/objspace/std/floatobject.py @@ -1,4 +1,5 @@ import operator +import sys from pypy.interpreter import gateway from pypy.interpreter.error import OperationError from pypy.objspace.std import model, newformat @@ -7,10 +8,11 @@ from pypy.objspace.std.register_all import register_all from pypy.objspace.std.noneobject import W_NoneObject from pypy.objspace.std.longobject import W_LongObject -from rpython.rlib.rarithmetic import ovfcheck_float_to_int, intmask, LONG_BIT +from rpython.rlib.rarithmetic import ( + LONG_BIT, intmask, ovfcheck_float_to_int, r_uint) from rpython.rlib.rfloat import ( isinf, isnan, isfinite, INFINITY, NAN, copysign, formatd, - DTSF_ADD_DOT_0, DTSF_STR_PRECISION, float_as_rbigint_ratio) + DTSF_ADD_DOT_0, float_as_rbigint_ratio) from rpython.rlib.rbigint import rbigint from rpython.rlib import rfloat from rpython.tool.sourcetools import func_with_new_name @@ -21,6 +23,8 @@ HASH_INF = 314159 HASH_NAN = 0 +HASH_BITS = 61 if sys.maxsize > 2 ** 31 - 1 else 31 +HASH_MODULUS = (1 << HASH_BITS) - 1 class W_AbstractFloatObject(W_Object): __slots__ = () @@ -284,51 +288,37 @@ return space.wrap(_hash_float(space, w_value.floatval)) def _hash_float(space, v): - if isnan(v): + if not isfinite(v): + if isinf(v): + return HASH_INF if v > 0 else -HASH_INF return HASH_NAN - # This is designed so that Python numbers of different types - # that compare equal hash to the same value; otherwise comparisons - # of mapping keys will turn out weird. - fractpart, intpart = math.modf(v) + m, e = math.frexp(v) - if fractpart == 0.0: - # This must return the same hash as an equal int or long. - try: - x = ovfcheck_float_to_int(intpart) - # Fits in a C long == a Python int, so is its own hash. - return x - except OverflowError: - # Convert to long and use its hash. - try: - w_lval = W_LongObject.fromfloat(space, v) - except (OverflowError, ValueError): - # can't convert to long int -- arbitrary - if v < 0: - return -HASH_INF - else: - return HASH_INF - return space.int_w(space.hash(w_lval)) + sign = 1 + if m < 0: + sign = -1 + m = -m - # The fractional part is non-zero, so we don't have to worry about - # making this match the hash of some other type. - # Use frexp to get at the bits in the double. - # Since the VAX D double format has 56 mantissa bits, which is the - # most of any double format in use, each of these parts may have as - # many as (but no more than) 56 significant bits. - # So, assuming sizeof(long) >= 4, each part can be broken into two - # longs; frexp and multiplication are used to do that. - # Also, since the Cray double format has 15 exponent bits, which is - # the most of any double format in use, shifting the exponent field - # left by 15 won't overflow a long (again assuming sizeof(long) >= 4). + # process 28 bits at a time; this should work well both for binary + # and hexadecimal floating point. + x = r_uint(0) + while m: + x = ((x << 28) & HASH_MODULUS) | x >> (HASH_BITS - 28) + m *= 268435456.0 # 2**28 + e -= 28 + y = int(m) # pull out integer part + m -= y + x += y + if x >= HASH_MODULUS: + x -= HASH_MODULUS - v, expo = math.frexp(v) - v *= 2147483648.0 # 2**31 - hipart = int(v) # take the top 32 bits - v = (v - hipart) * 2147483648.0 # get the next 32 bits - x = intmask(hipart + int(v) + (expo << 15)) - return x + # adjust for the exponent; first reduce it modulo HASH_BITS + e = e % HASH_BITS if e >= 0 else HASH_BITS - 1 - ((-1 - e) % HASH_BITS) + x = ((x << e) & HASH_MODULUS) | x >> (HASH_BITS - e) + x = intmask(intmask(x) * sign) + return -2 if x == -1 else x def add__Float_Float(space, w_float1, w_float2): diff --git a/pypy/objspace/std/test/test_floatobject.py b/pypy/objspace/std/test/test_floatobject.py --- a/pypy/objspace/std/test/test_floatobject.py +++ b/pypy/objspace/std/test/test_floatobject.py @@ -100,16 +100,27 @@ # these are taken from standard Python, which produces # the same but for -1. import math + import sys + + assert hash(-1.0) == -2 + assert hash(-2.0) == -2 + assert hash(-3.0) == -3 assert hash(42.0) == 42 - assert hash(42.125) == 1413677056 - assert hash(math.ldexp(0.125, 1000)) in ( - 32, # answer on 32-bit machines - 137438953472) # answer on 64-bit machines - # testing special overflow values - inf = 1e200 * 1e200 + if sys.maxsize > 2 ** 31 - 1: + assert hash(42.125) == 288230376151711786 + assert hash(math.ldexp(0.125, 1000)) == 2097152 + assert hash(3.141593) == 326491229203594243 + assert hash(2.5) == 1152921504606846978 + else: + assert hash(42.125) == 268435498 + assert hash(math.ldexp(0.125, 1000)) == 32 + assert hash(3.141593) == 671854639 + assert hash(2.5) == 1073741826 + inf = float('inf') + nan = float('nan') assert hash(inf) == 314159 assert hash(-inf) == -314159 - assert hash(inf/inf) == 0 + assert hash(nan) == 0 def test_int_float(self): assert int(42.1234) == 42 From noreply at buildbot.pypy.org Fri Feb 22 03:39:15 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Fri, 22 Feb 2013 03:39:15 +0100 (CET) Subject: [pypy-commit] pypy py3k: Implement str.format_map(). Message-ID: <20130222023915.9AE0A1C0228@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: py3k Changeset: r61582:53becf146b8d Date: 2013-02-22 03:26 +0100 http://bitbucket.org/pypy/pypy/changeset/53becf146b8d/ Log: Implement str.format_map(). diff --git a/pypy/objspace/std/newformat.py b/pypy/objspace/std/newformat.py --- a/pypy/objspace/std/newformat.py +++ b/pypy/objspace/std/newformat.py @@ -53,8 +53,9 @@ self.empty = u"" if is_unicode else "" self.template = template - def build(self, args): - self.args, self.kwargs = args.unpack() + def build(self, args, w_kwargs): + self.args = args + self.w_kwargs = w_kwargs self.auto_numbering = 0 self.auto_numbering_state = ANS_INIT return self._build_string(0, len(self.template), 2) @@ -212,11 +213,12 @@ raise OperationError(space.w_KeyError, space.wrap(kwarg)) else: arg_key = kwarg - try: - w_arg = self.kwargs[arg_key] - except KeyError: - raise OperationError(space.w_KeyError, space.wrap(arg_key)) + w_arg = space.getitem(self.w_kwargs, space.wrap(arg_key)) else: + if self.args is None: + w_msg = space.wrap("Format string contains positional " + "fields") + raise OperationError(space.w_ValueError, w_msg) try: w_arg = self.args[index] except IndexError: @@ -374,14 +376,14 @@ return UnicodeTemplateFormatter(space, True, template) -def format_method(space, w_string, args, is_unicode): +def format_method(space, w_string, args, w_kwargs, is_unicode): if is_unicode: template = unicode_template_formatter(space, space.unicode_w(w_string)) - return space.wrap(template.build(args)) + return space.wrap(template.build(args, w_kwargs)) else: template = str_template_formatter(space, space.bytes_w(w_string)) - return space.wrap(template.build(args)) + return space.wrap(template.build(args, w_kwargs)) class NumberSpec(object): diff --git a/pypy/objspace/std/test/test_unicodeobject.py b/pypy/objspace/std/test/test_unicodeobject.py --- a/pypy/objspace/std/test/test_unicodeobject.py +++ b/pypy/objspace/std/test/test_unicodeobject.py @@ -872,3 +872,12 @@ assert b == 'hello \u1234' assert '%s' % S('mar\xe7') == 'mar\xe7' + + def test_format_new(self): + assert '0{0}1{b}2'.format('A', b='B') == '0A1B2' + + def test_format_map(self): + assert '0{a}1'.format_map({'a': 'A'}) == '0A1' + + def test_format_map_positional(self): + raises(ValueError, '{}'.format_map, {}) diff --git a/pypy/objspace/std/unicodeobject.py b/pypy/objspace/std/unicodeobject.py --- a/pypy/objspace/std/unicodeobject.py +++ b/pypy/objspace/std/unicodeobject.py @@ -867,7 +867,16 @@ return mod_format(space, w_format, w_values, do_unicode=True) def unicode_format__Unicode(space, w_unicode, __args__): - return newformat.format_method(space, w_unicode, __args__, True) + w_kwds = space.newdict() + if __args__.keywords: + for i in range(len(__args__.keywords)): + space.setitem(w_kwds, space.wrap(__args__.keywords[i]), + __args__.keywords_w[i]) + return newformat.format_method(space, w_unicode, __args__.arguments_w, + w_kwds, True) + +def unicode_format_map__Unicode_ANY(space, w_unicode, w_mapping): + return newformat.format_method(space, w_unicode, None, w_mapping, True) def format__Unicode_ANY(space, w_unicode, w_spec): return newformat.run_formatter(space, w_spec, "format_string", w_unicode) diff --git a/pypy/objspace/std/unicodetype.py b/pypy/objspace/std/unicodetype.py --- a/pypy/objspace/std/unicodetype.py +++ b/pypy/objspace/std/unicodetype.py @@ -64,6 +64,8 @@ ' size of 8 characters is assumed.') unicode_format = SMM('format', 1, general__args__=True, doc='S.format() -> new style formating') +unicode_format_map = SMM('format_map', 2, + doc='S.format_map(mapping) -> str') unicode_isalnum = SMM('isalnum', 1, doc='S.isalnum() -> bool\n\nReturn True if all' ' characters in S are alphanumeric\nand there is' From noreply at buildbot.pypy.org Fri Feb 22 04:13:54 2013 From: noreply at buildbot.pypy.org (modcloth) Date: Fri, 22 Feb 2013 04:13:54 +0100 (CET) Subject: [pypy-commit] pypy clean-up-remaining-pypy-rlib-refs: Cleaning up remaining 'pypy[./]rlib' references Message-ID: <20130222031354.BB7F51C0228@cobra.cs.uni-duesseldorf.de> Author: Dan Buch Branch: clean-up-remaining-pypy-rlib-refs Changeset: r61583:69715240f0db Date: 2013-02-21 22:03 -0500 http://bitbucket.org/pypy/pypy/changeset/69715240f0db/ Log: Cleaning up remaining 'pypy[./]rlib' references diff --git a/pypy/doc/ctypes-implementation.rst b/pypy/doc/ctypes-implementation.rst --- a/pypy/doc/ctypes-implementation.rst +++ b/pypy/doc/ctypes-implementation.rst @@ -38,7 +38,7 @@ in dynamic libraries through libffi. Freeing objects in most cases and making sure that objects referring to each other are kept alive is responsibility of the higher levels. -This module uses bindings to libffi which are defined in ``pypy/rlib/libffi.py``. +This module uses bindings to libffi which are defined in ``rpython/rlib/libffi.py``. We tried to keep this module as small as possible. It is conceivable that other implementations (e.g. Jython) could use our ctypes diff --git a/pypy/doc/discussion/improve-rpython.rst b/pypy/doc/discussion/improve-rpython.rst --- a/pypy/doc/discussion/improve-rpython.rst +++ b/pypy/doc/discussion/improve-rpython.rst @@ -39,7 +39,7 @@ - Allocate variables on the stack, and pass their address ("by reference") to llexternal functions. For a typical usage, see - `pypy.rlib.rsocket.RSocket.getsockopt_int`. + `rpython.rlib.rsocket.RSocket.getsockopt_int`. Extensible type system for llexternal ------------------------------------- diff --git a/pypy/doc/stackless.rst b/pypy/doc/stackless.rst --- a/pypy/doc/stackless.rst +++ b/pypy/doc/stackless.rst @@ -273,7 +273,7 @@ more information about them please see the documentation in the C source at `rpython/translator/c/src/stacklet/stacklet.h`_. -The module ``pypy.rlib.rstacklet`` is a thin wrapper around the above +The module ``rpython.rlib.rstacklet`` is a thin wrapper around the above functions. The key point is that new() and switch() always return a fresh stacklet handle (or an empty one), and switch() additionally consumes one. It makes no sense to have code in which the returned diff --git a/rpython/translator/c/src/mem.h b/rpython/translator/c/src/mem.h --- a/rpython/translator/c/src/mem.h +++ b/rpython/translator/c/src/mem.h @@ -4,7 +4,7 @@ #include -/* used by pypy.rlib.rstack, but also by asmgcc */ +/* used by rpython.rlib.rstack, but also by asmgcc */ #define OP_STACK_CURRENT(r) r = (Signed)&r diff --git a/rpython/translator/c/src/stack.h b/rpython/translator/c/src/stack.h --- a/rpython/translator/c/src/stack.h +++ b/rpython/translator/c/src/stack.h @@ -18,7 +18,7 @@ char LL_stack_too_big_slowpath(long); /* returns 0 (ok) or 1 (too big) */ void LL_stack_set_length_fraction(double); -/* some macros referenced from pypy.rlib.rstack */ +/* some macros referenced from rpython.rlib.rstack */ #define LL_stack_get_end() ((long)_LLstacktoobig_stack_end) #define LL_stack_get_length() _LLstacktoobig_stack_length #define LL_stack_get_end_adr() ((long)&_LLstacktoobig_stack_end) /* JIT */ From noreply at buildbot.pypy.org Fri Feb 22 04:13:56 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Fri, 22 Feb 2013 04:13:56 +0100 (CET) Subject: [pypy-commit] pypy default: Merged in modcloth/pypy/clean-up-remaining-pypy-rlib-refs (pull request #127) Message-ID: <20130222031356.2673F1C0228@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r61584:8888df8a2aa4 Date: 2013-02-21 19:13 -0800 http://bitbucket.org/pypy/pypy/changeset/8888df8a2aa4/ Log: Merged in modcloth/pypy/clean-up-remaining-pypy-rlib-refs (pull request #127) Cleaning up remaining 'pypy[./]rlib' references diff --git a/pypy/doc/ctypes-implementation.rst b/pypy/doc/ctypes-implementation.rst --- a/pypy/doc/ctypes-implementation.rst +++ b/pypy/doc/ctypes-implementation.rst @@ -38,7 +38,7 @@ in dynamic libraries through libffi. Freeing objects in most cases and making sure that objects referring to each other are kept alive is responsibility of the higher levels. -This module uses bindings to libffi which are defined in ``pypy/rlib/libffi.py``. +This module uses bindings to libffi which are defined in ``rpython/rlib/libffi.py``. We tried to keep this module as small as possible. It is conceivable that other implementations (e.g. Jython) could use our ctypes diff --git a/pypy/doc/discussion/improve-rpython.rst b/pypy/doc/discussion/improve-rpython.rst --- a/pypy/doc/discussion/improve-rpython.rst +++ b/pypy/doc/discussion/improve-rpython.rst @@ -39,7 +39,7 @@ - Allocate variables on the stack, and pass their address ("by reference") to llexternal functions. For a typical usage, see - `pypy.rlib.rsocket.RSocket.getsockopt_int`. + `rpython.rlib.rsocket.RSocket.getsockopt_int`. Extensible type system for llexternal ------------------------------------- diff --git a/pypy/doc/stackless.rst b/pypy/doc/stackless.rst --- a/pypy/doc/stackless.rst +++ b/pypy/doc/stackless.rst @@ -273,7 +273,7 @@ more information about them please see the documentation in the C source at `rpython/translator/c/src/stacklet/stacklet.h`_. -The module ``pypy.rlib.rstacklet`` is a thin wrapper around the above +The module ``rpython.rlib.rstacklet`` is a thin wrapper around the above functions. The key point is that new() and switch() always return a fresh stacklet handle (or an empty one), and switch() additionally consumes one. It makes no sense to have code in which the returned diff --git a/rpython/translator/c/src/mem.h b/rpython/translator/c/src/mem.h --- a/rpython/translator/c/src/mem.h +++ b/rpython/translator/c/src/mem.h @@ -4,7 +4,7 @@ #include -/* used by pypy.rlib.rstack, but also by asmgcc */ +/* used by rpython.rlib.rstack, but also by asmgcc */ #define OP_STACK_CURRENT(r) r = (Signed)&r diff --git a/rpython/translator/c/src/stack.h b/rpython/translator/c/src/stack.h --- a/rpython/translator/c/src/stack.h +++ b/rpython/translator/c/src/stack.h @@ -18,7 +18,7 @@ char LL_stack_too_big_slowpath(long); /* returns 0 (ok) or 1 (too big) */ void LL_stack_set_length_fraction(double); -/* some macros referenced from pypy.rlib.rstack */ +/* some macros referenced from rpython.rlib.rstack */ #define LL_stack_get_end() ((long)_LLstacktoobig_stack_end) #define LL_stack_get_length() _LLstacktoobig_stack_length #define LL_stack_get_end_adr() ((long)&_LLstacktoobig_stack_end) /* JIT */ From noreply at buildbot.pypy.org Fri Feb 22 08:37:29 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Fri, 22 Feb 2013 08:37:29 +0100 (CET) Subject: [pypy-commit] pypy py3k-newhash: fix translation Message-ID: <20130222073729.694681C01BF@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k-newhash Changeset: r61585:51531d96fa0e Date: 2013-02-21 23:36 -0800 http://bitbucket.org/pypy/pypy/changeset/51531d96fa0e/ Log: fix translation diff --git a/pypy/objspace/std/floatobject.py b/pypy/objspace/std/floatobject.py --- a/pypy/objspace/std/floatobject.py +++ b/pypy/objspace/std/floatobject.py @@ -307,7 +307,7 @@ x = ((x << 28) & HASH_MODULUS) | x >> (HASH_BITS - 28) m *= 268435456.0 # 2**28 e -= 28 - y = int(m) # pull out integer part + y = r_uint(m) # pull out integer part m -= y x += y if x >= HASH_MODULUS: From noreply at buildbot.pypy.org Fri Feb 22 10:12:42 2013 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 22 Feb 2013 10:12:42 +0100 (CET) Subject: [pypy-commit] pypy stm-thread-2: Add a missing include. Message-ID: <20130222091242.4E65D1C01BF@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stm-thread-2 Changeset: r61586:56d318570490 Date: 2013-02-21 10:28 +0100 http://bitbucket.org/pypy/pypy/changeset/56d318570490/ Log: Add a missing include. diff --git a/rpython/rtyper/lltypesystem/llarena.py b/rpython/rtyper/lltypesystem/llarena.py --- a/rpython/rtyper/lltypesystem/llarena.py +++ b/rpython/rtyper/lltypesystem/llarena.py @@ -418,7 +418,7 @@ from rpython.rtyper.tool import rffi_platform from rpython.translator.tool.cbuild import ExternalCompilationInfo - _eci = ExternalCompilationInfo(includes=['sys/mman.h']) + _eci = ExternalCompilationInfo(includes=['sys/mman.h', 'unistd.h']) MADV_DONTNEED = rffi_platform.getconstantinteger('MADV_DONTNEED', '#include ') linux_madvise = rffi.llexternal('madvise', From noreply at buildbot.pypy.org Fri Feb 22 10:12:43 2013 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 22 Feb 2013 10:12:43 +0100 (CET) Subject: [pypy-commit] pypy stm-thread-2: Implement abortinfo and lastabortinfo. This should give a way Message-ID: <20130222091243.A6C911C0228@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stm-thread-2 Changeset: r61587:63749585b64c Date: 2013-02-21 22:15 +0100 http://bitbucket.org/pypy/pypy/changeset/63749585b64c/ Log: Implement abortinfo and lastabortinfo. This should give a way for the RPython program to register its position, and in case of abort, to read the position of the last aborted transaction. diff --git a/rpython/rlib/rstm.py b/rpython/rlib/rstm.py --- a/rpython/rlib/rstm.py +++ b/rpython/rlib/rstm.py @@ -4,10 +4,11 @@ from rpython.rlib.objectmodel import keepalive_until_here, specialize from rpython.rlib.objectmodel import we_are_translated from rpython.rlib.rposix import get_errno, set_errno -from rpython.rtyper.lltypesystem import lltype, llmemory, rffi, rclass +from rpython.rtyper.lltypesystem import lltype, llmemory, rffi, rclass, rstr from rpython.rtyper.lltypesystem.lloperation import llop from rpython.rtyper.annlowlevel import cast_instance_to_base_ptr, llhelper from rpython.rtyper.annlowlevel import cast_base_ptr_to_instance +from rpython.rtyper.extregistry import ExtRegistryEntry def is_inevitable(): @@ -32,6 +33,22 @@ def is_atomic(): return stmgcintf.StmOperations.get_atomic() +def abort_info_push(instance, fieldnames): + "Special-cased below." + +def abort_info_pop(count): + stmgcintf.StmOperations.abort_info_pop(count) + +def inspect_abort_info(): + p = stmgcintf.StmOperations.inspect_abort_info() + if p: + return rffi.charp2str(p) + else: + return None + +def abort_and_retry(): + stmgcintf.StmOperations.abort_and_retry() + def before_external_call(): if not is_atomic(): e = get_errno() @@ -106,6 +123,45 @@ # ____________________________________________________________ +class AbortInfoPush(ExtRegistryEntry): + _about_ = abort_info_push + + def compute_result_annotation(self, s_instance, s_fieldnames): + from rpython.annotator.model import SomeInstance + assert isinstance(s_instance, SomeInstance) + assert s_fieldnames.is_constant() + assert isinstance(s_fieldnames.const, tuple) # tuple of names + + def specialize_call(self, hop): + fieldnames = hop.args_s[1].const + lst = [len(fieldnames)] + v_instance = hop.inputarg(hop.args_r[0], arg=0) + STRUCT = v_instance.concretetype.TO + for fieldname in fieldnames: + fieldname = 'inst_' + fieldname + TYPE = getattr(STRUCT, fieldname) #xxx check also in parent structs + if TYPE == lltype.Signed: + kind = 0 + elif TYPE == lltype.Unsigned: + kind = 1 + elif TYPE == lltype.Ptr(rstr.STR): + kind = 2 + else: + raise NotImplementedError( + "abort_info_push(%s, %r): field of type %r" + % (STRUCT.__name__, fieldname, TYPE)) + lst.append(kind) + lst.append(llmemory.offsetof(STRUCT, fieldname)) + ARRAY = rffi.CArray(lltype.Signed) + array = lltype.malloc(ARRAY, len(lst), flavor='raw', immortal=True) + for i in range(len(lst)): + array[i] = lst[i] + hop.exception_cannot_occur() + c_array = hop.inputconst(lltype.Ptr(ARRAY), array) + hop.genop('stm_abort_info_push', [v_instance, c_array]) + +# ____________________________________________________________ + class ThreadLocalReference(object): _COUNT = 0 diff --git a/rpython/rtyper/lltypesystem/lloperation.py b/rpython/rtyper/lltypesystem/lloperation.py --- a/rpython/rtyper/lltypesystem/lloperation.py +++ b/rpython/rtyper/lltypesystem/lloperation.py @@ -431,9 +431,12 @@ #'stm_jit_invoke_code': LLOp(canmallocgc=True), 'stm_threadlocalref_get': LLOp(sideeffects=False), 'stm_threadlocalref_set': LLOp(), - 'stm_threadlocalref_llset': LLOp(), + 'stm_threadlocalref_llset': LLOp(), 'stm_threadlocalref_llcount': LLOp(sideeffects=False), 'stm_threadlocalref_lladdr': LLOp(sideeffects=False), + 'stm_abort_info_push': LLOp(), + 'stm_extraref_llcount': LLOp(sideeffects=False), + 'stm_extraref_lladdr': LLOp(sideeffects=False), # __________ address operations __________ diff --git a/rpython/rtyper/memory/gc/stmtls.py b/rpython/rtyper/memory/gc/stmtls.py --- a/rpython/rtyper/memory/gc/stmtls.py +++ b/rpython/rtyper/memory/gc/stmtls.py @@ -203,8 +203,9 @@ # Find the roots that are living in raw structures. self.collect_from_raw_structures() # - # Find the roots in the THREADLOCALREF structure. - self.collect_from_threadlocalref() + # Find the roots in the THREADLOCALREF structure, and + # the other extra roots hold by C code + self.collect_from_threadlocalref_and_misc() # # Also find the roots that are the local copy of global objects. self.collect_roots_from_tldict() @@ -358,7 +359,7 @@ self.gc.root_walker.walk_current_nongc_roots( StmGCTLS._trace_drag_out1, self) - def collect_from_threadlocalref(self): + def collect_from_threadlocalref_and_misc(self): if not we_are_translated(): return i = llop.stm_threadlocalref_llcount(lltype.Signed) @@ -367,6 +368,12 @@ root = llop.stm_threadlocalref_lladdr(llmemory.Address, i) if self.gc.points_to_valid_gc_object(root): self._trace_drag_out(root, None) + i = llop.stm_extraref_llcount(lltype.Signed) + while i > 0: + i -= 1 + root = llop.stm_extraref_lladdr(llmemory.Address, i) + if self.gc.points_to_valid_gc_object(root): + self._trace_drag_out(root, None) def trace_and_drag_out_of_nursery(self, obj): # This is called to fix the references inside 'obj', to ensure that diff --git a/rpython/translator/c/funcgen.py b/rpython/translator/c/funcgen.py --- a/rpython/translator/c/funcgen.py +++ b/rpython/translator/c/funcgen.py @@ -590,6 +590,9 @@ OP_STM_BECOME_INEVITABLE = _OP_STM OP_STM_BARRIER = _OP_STM OP_STM_PTR_EQ = _OP_STM + OP_STM_ABORT_INFO_PUSH = _OP_STM + OP_STM_EXTRAREF_LLCOUNT = _OP_STM + OP_STM_EXTRAREF_LLADDR = _OP_STM def OP_PTR_NONZERO(self, op): diff --git a/rpython/translator/stm/funcgen.py b/rpython/translator/stm/funcgen.py --- a/rpython/translator/stm/funcgen.py +++ b/rpython/translator/stm/funcgen.py @@ -38,6 +38,20 @@ ##def stm_jit_invoke_code(funcgen, op): ## return funcgen.OP_DIRECT_CALL(op) +def stm_abort_info_push(funcgen, op): + arg0 = funcgen.expr(op.args[0]) + arg1 = funcgen.expr(op.args[1]) + return 'stm_abort_info_push(%s, %s);' % (arg0, arg1) + +def stm_extraref_llcount(funcgen, op): + result = funcgen.expr(op.result) + return '%s = stm_extraref_llcount();' % (result,) + +def stm_extraref_lladdr(funcgen, op): + arg0 = funcgen.expr(op.args[0]) + result = funcgen.expr(op.result) + return '%s = stm_extraref_lladdr(%s);' % (result, arg0) + def _stm_nogc_init_function(): """Called at process start-up when running with no GC.""" StmOperations.descriptor_init() diff --git a/rpython/translator/stm/src_stm/et.c b/rpython/translator/stm/src_stm/et.c --- a/rpython/translator/stm/src_stm/et.c +++ b/rpython/translator/stm/src_stm/et.c @@ -55,6 +55,8 @@ struct GcPtrList gcroots; struct G2L global_to_local; struct GcPtrList undolog; + struct GcPtrList abortinfo; + char *lastabortinfo; struct FXCache recent_reads_cache; }; @@ -368,10 +370,13 @@ spinloop(); } +size_t _stm_decode_abort_info(struct tx_descriptor *d, char *output); + static void AbortTransaction(int num) { struct tx_descriptor *d = thread_descriptor; unsigned long limit; + size_t size; assert(d->active); assert(!is_inevitable(d)); assert(num < ABORT_REASONS); @@ -379,6 +384,16 @@ CancelLocks(d); + /* decode the 'abortinfo' and produce a human-readable summary in + the string 'lastabortinfo' */ + size = _stm_decode_abort_info(d, NULL); + free(d->lastabortinfo); + d->lastabortinfo = malloc(size); + if (d->lastabortinfo != NULL) + _stm_decode_abort_info(d, d->lastabortinfo); + + /* run the undo log in reverse order, cancelling the values set by + stm_ThreadLocalRef_LLSet(). */ if (d->undolog.size > 0) { gcptr *item = d->undolog.items; long i; @@ -439,6 +454,7 @@ d->count_reads = 0; fxcache_clear(&d->recent_reads_cache); gcptrlist_clear(&d->undolog); + gcptrlist_clear(&d->abortinfo); } void BeginTransaction(jmp_buf* buf) diff --git a/rpython/translator/stm/src_stm/et.h b/rpython/translator/stm/src_stm/et.h --- a/rpython/translator/stm/src_stm/et.h +++ b/rpython/translator/stm/src_stm/et.h @@ -122,6 +122,11 @@ void stm_perform_transaction(long(*callback)(void*, long), void *arg, void *save_and_restore); void stm_abort_and_retry(void); +void stm_abort_info_push(void *, void *); +void stm_abort_info_pop(long); +char *stm_inspect_abort_info(void); +long stm_extraref_llcount(void); +gcptr stm_extraref_lladdr(long); #ifdef USING_NO_GC_AT_ALL # define OP_GC_ADR_OF_ROOT_STACK_TOP(r) r = NULL diff --git a/rpython/translator/stm/src_stm/lists.c b/rpython/translator/stm/src_stm/lists.c --- a/rpython/translator/stm/src_stm/lists.c +++ b/rpython/translator/stm/src_stm/lists.c @@ -254,6 +254,11 @@ gcptrlist->size = i + 2; } +static void gcptrlist_reduce_size(struct GcPtrList *gcptrlist, long newsize) +{ + gcptrlist->size = newsize; +} + /************************************************************/ /* The fxcache_xx functions implement a fixed-size set of gcptr's. diff --git a/rpython/translator/stm/src_stm/rpyintf.c b/rpython/translator/stm/src_stm/rpyintf.c --- a/rpython/translator/stm/src_stm/rpyintf.c +++ b/rpython/translator/stm/src_stm/rpyintf.c @@ -196,6 +196,83 @@ AbortTransaction(4); /* manual abort */ } +void stm_abort_info_push(void *obj, void *fieldoffsets) +{ + struct tx_descriptor *d = thread_descriptor; + gcptrlist_insert2(&d->abortinfo, (gcptr)obj, (gcptr)fieldoffsets); +} + +void stm_abort_info_pop(long count) +{ + struct tx_descriptor *d = thread_descriptor; + long newsize = d->abortinfo.size - 2 * count; + gcptrlist_reduce_size(&d->abortinfo, newsize < 0 ? 0 : newsize); +} + +size_t _stm_decode_abort_info(struct tx_descriptor *d, char *output) +{ + size_t totalsize = 0; + long i; +#define WRITE(c) { totalsize++; if (output) *output++=(c); } + for (i=0; iabortinfo.size; i+=2) { + char *object = (char*)d->abortinfo.items[i+0]; + long *fieldoffsets = (long*)d->abortinfo.items[i+1]; + long j; + for (j=0; j 0) { + WRITE(*result); + result++; + res_size--; + } + WRITE('\n'); + } + } + WRITE('\0'); /* final null character */ +#undef WRITE + return totalsize; +} + +char *stm_inspect_abort_info(void) +{ + struct tx_descriptor *d = thread_descriptor; + return d->lastabortinfo; +} + +long stm_extraref_llcount(void) +{ + struct tx_descriptor *d = thread_descriptor; + return d->abortinfo.size / 2; +} + +gcptr stm_extraref_lladdr(long index) +{ + struct tx_descriptor *d = thread_descriptor; + return d->abortinfo.items[index * 2]; +} + #ifdef USING_NO_GC_AT_ALL static __thread gcptr stm_nogc_chained_list; void stm_nogc_start_transaction(void) diff --git a/rpython/translator/stm/stmgcintf.py b/rpython/translator/stm/stmgcintf.py --- a/rpython/translator/stm/stmgcintf.py +++ b/rpython/translator/stm/stmgcintf.py @@ -68,5 +68,10 @@ set_transaction_length = smexternal('stm_set_transaction_length', [lltype.Signed], lltype.Void) + abort_info_pop = smexternal('stm_abort_info_pop', + [lltype.Signed], lltype.Void) + inspect_abort_info = smexternal('stm_inspect_abort_info', + [], rffi.CCHARP) + # for testing - abort_and_retry = smexternal('stm_abort_and_retry', [], lltype.Void) + abort_and_retry = smexternal('stm_abort_and_retry', [], lltype.Void) diff --git a/rpython/translator/stm/test/test_ztranslated.py b/rpython/translator/stm/test/test_ztranslated.py --- a/rpython/translator/stm/test/test_ztranslated.py +++ b/rpython/translator/stm/test/test_ztranslated.py @@ -128,3 +128,32 @@ t, cbuilder = self.compile(main) data = cbuilder.cmdexec('') assert 'ok\n' in data + + def test_abort_info(self): + from rpython.rtyper.lltypesystem.rclass import OBJECTPTR + + class Foobar(object): + pass + globf = Foobar() + + def check(_, retry_counter): + globf.xy = 100 + retry_counter + rstm.abort_info_push(globf, ('xy', 'yx')) + if retry_counter < 3: + rstm.abort_and_retry() + # + print rstm.inspect_abort_info() + # + rstm.abort_info_pop(2) + return 0 + + PS = lltype.Ptr(lltype.GcStruct('S', ('got_exception', OBJECTPTR))) + perform_transaction = rstm.make_perform_transaction(check, PS) + + def main(argv): + globf.yx = 'hi there %d' % len(argv) + perform_transaction(lltype.nullptr(PS.TO)) + return 0 + t, cbuilder = self.compile(main) + data = cbuilder.cmdexec('a b') + assert '102\nhi there 3\n\n' in data From noreply at buildbot.pypy.org Fri Feb 22 10:12:45 2013 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 22 Feb 2013 10:12:45 +0100 (CET) Subject: [pypy-commit] pypy stm-thread-2: Switch to encoding/decoding following the bittorrent file format. Message-ID: <20130222091245.150E01C01BF@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stm-thread-2 Changeset: r61588:5813171b4407 Date: 2013-02-22 10:12 +0100 http://bitbucket.org/pypy/pypy/changeset/5813171b4407/ Log: Switch to encoding/decoding following the bittorrent file format. It's a convenient format that requires minimal effort and no escaping pain. diff --git a/pypy/interpreter/executioncontext.py b/pypy/interpreter/executioncontext.py --- a/pypy/interpreter/executioncontext.py +++ b/pypy/interpreter/executioncontext.py @@ -60,6 +60,9 @@ return frame def enter(self, frame): + if self.space.config.translation.stm: + from pypy.module.thread.stm import enter_frame + enter_frame(self, frame) frame.f_backref = self.topframeref self.topframeref = jit.virtual_ref(frame) @@ -84,6 +87,10 @@ if self.w_tracefunc is not None and not frame.hide(): self.space.frame_trace_action.fire() + if self.space.config.translation.stm: + from pypy.module.thread.stm import leave_frame + leave_frame(self, frame) + # ________________________________________________________________ def c_call_trace(self, frame, w_func, args=None): diff --git a/pypy/module/__pypy__/__init__.py b/pypy/module/__pypy__/__init__.py --- a/pypy/module/__pypy__/__init__.py +++ b/pypy/module/__pypy__/__init__.py @@ -39,6 +39,8 @@ '_atomic_enter': 'interp_atomic.atomic_enter', '_exclusive_atomic_enter': 'interp_atomic.exclusive_atomic_enter', '_atomic_exit': 'interp_atomic.atomic_exit', + '_raw_last_abort_info': 'interp_atomic.raw_last_abort_info', + 'last_abort_info': 'interp_atomic.last_abort_info', } diff --git a/pypy/module/__pypy__/interp_atomic.py b/pypy/module/__pypy__/interp_atomic.py --- a/pypy/module/__pypy__/interp_atomic.py +++ b/pypy/module/__pypy__/interp_atomic.py @@ -1,5 +1,6 @@ from pypy.interpreter.error import OperationError from pypy.module.thread.error import wrap_thread_error +from rpython.rtyper.lltypesystem import rffi @@ -39,3 +40,53 @@ return raise wrap_thread_error(space, "atomic.__exit__(): more exits than enters") + +def raw_last_abort_info(space): + return space.wrap(rstm.inspect_abort_info()) + +def last_abort_info(space): + p = rstm.inspect_abort_info() + if not p: + return space.w_None + assert p[0] == 'l' + w_obj, p = bdecode(space, p) + return w_obj + +def bdecode(space, p): + return decoder[p[0]](space, p) + +def bdecodeint(space, p): + p = rffi.ptradd(p, 1) + n = 0 + while p[n] != 'e': + n += 1 + return (space.int(space.wrap(rffi.charpsize2str(p, n))), + rffi.ptradd(p, n + 1)) + +def bdecodelist(space, p): + p = rffi.ptradd(p, 1) + w_list = space.newlist() + while p[0] != 'e': + w_obj, p = bdecode(space, p) + space.call_method(w_list, 'append', w_obj) + return (w_list, rffi.ptradd(p, 1)) + +def bdecodestr(space, p): + length = 0 + n = 0 + while p[n] != ':': + c = p[n] + n += 1 + assert '0' <= c <= '9' + length = length * 10 + (ord(c) - ord('0')) + n += 1 + p = rffi.ptradd(p, n) + return (space.wrap(rffi.charpsize2str(p, length)), + rffi.ptradd(p, length)) + +decoder = {'i': bdecodeint, + 'l': bdecodelist, + #'d': bdecodedict, + } +for c in '0123456789': + decoder[c] = bdecodestr diff --git a/pypy/module/__pypy__/test/test_atomic.py b/pypy/module/__pypy__/test/test_atomic.py --- a/pypy/module/__pypy__/test/test_atomic.py +++ b/pypy/module/__pypy__/test/test_atomic.py @@ -1,5 +1,37 @@ from __future__ import with_statement from pypy.module.thread.test.support import GenericTestThread +from pypy.module.__pypy__.interp_atomic import bdecode +from rpython.rtyper.lltypesystem import rffi + + +def test_bdecode(): + class FakeSpace: + def wrap(self, x): + assert isinstance(x, str) + return x + def int(self, x): + assert isinstance(x, str) + return int(x) + def newlist(self): + return [] + def call_method(self, w_obj, method, *args): + assert method == 'append' + w_obj.append(*args) + + space = FakeSpace() + + def bdec(s): + p = rffi.str2charp(s) + w_obj, q = bdecode(space, p) + assert q == rffi.ptradd(p, len(s)) + rffi.free_charp(p) + return w_obj + + assert bdec("i123e") == 123 + assert bdec("i-123e") == -123 + assert bdec('12:+"*-%&/()=?\x00') == '+"*-%&/()=?\x00' + assert bdec("li123eli456eee") == [123, [456]] + assert bdec("l5:abcdei2ee") == ["abcde", 2] class AppTestAtomic(GenericTestThread): diff --git a/pypy/module/thread/stm.py b/pypy/module/thread/stm.py --- a/pypy/module/thread/stm.py +++ b/pypy/module/thread/stm.py @@ -17,6 +17,7 @@ ec_cache = rstm.ThreadLocalReference(ExecutionContext) def initialize_execution_context(ec): + """Called from ExecutionContext.__init__().""" ec._thread_local_dicts = rweakref.RWeakKeyDictionary(STMLocal, W_Root) if ec.space.config.objspace.std.withmethodcache: from pypy.objspace.std.typeobject import MethodCache @@ -26,6 +27,16 @@ if not we_are_translated() and not hasattr(ec, '_thread_local_dicts'): initialize_execution_context(ec) +def enter_frame(ec, frame): + """Called from ExecutionContext.enter().""" + rstm.abort_info_push(frame.pycode, ('[', 'co_filename', 'co_name', + 'co_firstlineno', 'co_lnotab')) + rstm.abort_info_push(frame, ('last_instr', ']')) + +def leave_frame(ec, frame): + """Called from ExecutionContext.leave().""" + rstm.abort_info_pop(2) + class STMThreadLocals(BaseThreadLocals): diff --git a/rpython/rlib/rstm.py b/rpython/rlib/rstm.py --- a/rpython/rlib/rstm.py +++ b/rpython/rlib/rstm.py @@ -39,12 +39,8 @@ def abort_info_pop(count): stmgcintf.StmOperations.abort_info_pop(count) -def inspect_abort_info(): - p = stmgcintf.StmOperations.inspect_abort_info() - if p: - return rffi.charp2str(p) - else: - return None +def charp_inspect_abort_info(): + return stmgcintf.StmOperations.inspect_abort_info() def abort_and_retry(): stmgcintf.StmOperations.abort_and_retry() @@ -134,30 +130,37 @@ def specialize_call(self, hop): fieldnames = hop.args_s[1].const - lst = [len(fieldnames)] + lst = [] v_instance = hop.inputarg(hop.args_r[0], arg=0) STRUCT = v_instance.concretetype.TO for fieldname in fieldnames: + if fieldname == '[': + lst.append(-2) # start of sublist + continue + if fieldname == ']': + lst.append(-1) # end of sublist + continue fieldname = 'inst_' + fieldname TYPE = getattr(STRUCT, fieldname) #xxx check also in parent structs if TYPE == lltype.Signed: - kind = 0 + kind = 1 elif TYPE == lltype.Unsigned: - kind = 1 + kind = 2 elif TYPE == lltype.Ptr(rstr.STR): - kind = 2 + kind = 3 else: raise NotImplementedError( "abort_info_push(%s, %r): field of type %r" % (STRUCT.__name__, fieldname, TYPE)) lst.append(kind) lst.append(llmemory.offsetof(STRUCT, fieldname)) + lst.append(0) ARRAY = rffi.CArray(lltype.Signed) array = lltype.malloc(ARRAY, len(lst), flavor='raw', immortal=True) for i in range(len(lst)): array[i] = lst[i] + c_array = hop.inputconst(lltype.Ptr(ARRAY), array) hop.exception_cannot_occur() - c_array = hop.inputconst(lltype.Ptr(ARRAY), array) hop.genop('stm_abort_info_push', [v_instance, c_array]) # ____________________________________________________________ diff --git a/rpython/translator/stm/src_stm/rpyintf.c b/rpython/translator/stm/src_stm/rpyintf.c --- a/rpython/translator/stm/src_stm/rpyintf.c +++ b/rpython/translator/stm/src_stm/rpyintf.c @@ -211,45 +211,65 @@ size_t _stm_decode_abort_info(struct tx_descriptor *d, char *output) { + /* re-encodes the abort info as a single string. + For convenience (no escaping needed, no limit on integer + sizes, etc.) we follow the bittorrent format. */ size_t totalsize = 0; long i; #define WRITE(c) { totalsize++; if (output) *output++=(c); } +#define WRITE_BUF(p, sz) { totalsize += (sz); \ + if (output) { \ + memcpy(output, (p), (sz)); output += (sz); \ + } \ + } + WRITE('l'); for (i=0; iabortinfo.size; i+=2) { char *object = (char*)d->abortinfo.items[i+0]; long *fieldoffsets = (long*)d->abortinfo.items[i+1]; - long j; - for (j=0; j 0) { - WRITE(*result); - result++; - res_size--; - } - WRITE('\n'); } } + WRITE('e'); WRITE('\0'); /* final null character */ #undef WRITE return totalsize; diff --git a/rpython/translator/stm/test/test_ztranslated.py b/rpython/translator/stm/test/test_ztranslated.py --- a/rpython/translator/stm/test/test_ztranslated.py +++ b/rpython/translator/stm/test/test_ztranslated.py @@ -1,6 +1,6 @@ import py from rpython.rlib import rstm, rgc -from rpython.rtyper.lltypesystem import lltype, llmemory +from rpython.rtyper.lltypesystem import lltype, llmemory, rffi from rpython.rtyper.lltypesystem.lloperation import llop from rpython.rtyper.annlowlevel import cast_instance_to_base_ptr from rpython.translator.stm.test.support import NoGcCompiledSTMTests @@ -138,11 +138,11 @@ def check(_, retry_counter): globf.xy = 100 + retry_counter - rstm.abort_info_push(globf, ('xy', 'yx')) + rstm.abort_info_push(globf, ('xy', '[', 'yx', ']')) if retry_counter < 3: rstm.abort_and_retry() # - print rstm.inspect_abort_info() + print rffi.charp2str(rstm.charp_inspect_abort_info()) # rstm.abort_info_pop(2) return 0 @@ -156,4 +156,4 @@ return 0 t, cbuilder = self.compile(main) data = cbuilder.cmdexec('a b') - assert '102\nhi there 3\n\n' in data + assert 'li102el10:hi there 3ee\n' in data From noreply at buildbot.pypy.org Fri Feb 22 10:32:03 2013 From: noreply at buildbot.pypy.org (lwassermann) Date: Fri, 22 Feb 2013 10:32:03 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: added constants for the different field of MethodClosure Message-ID: <20130222093203.2E9F21C01BF@cobra.cs.uni-duesseldorf.de> Author: Lars Wassermann Branch: Changeset: r79:5d56ed9018f7 Date: 2013-02-21 19:42 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/5d56ed9018f7/ Log: added constants for the different field of MethodClosure patched some mocking methods to use them for block closure testing diff --git a/spyvm/constants.py b/spyvm/constants.py --- a/spyvm/constants.py +++ b/spyvm/constants.py @@ -38,12 +38,15 @@ # MethodContext < ContextPart MTHDCTX_METHOD = 3 -MTHDCTX_RECEIVER_MAP = 4 +MTHDCTX_CLOSURE_OR_NIL = 4 MTHDCTX_RECEIVER = 5 MTHDCTX_TEMP_FRAME_START = 6 # BlockClosure < Object -BLOCKCLOSURE_SIZE = 3 +BLKCLSR_OUTER_CONTEXT = 0 +BLKCLSR_STARTPC = 1 +BLKCLSR_NUMARGS = 2 +BLKCLSR_SIZE = 3 # ___________________________________________________________________________ # Miscellaneous constants diff --git a/spyvm/objspace.py b/spyvm/objspace.py --- a/spyvm/objspace.py +++ b/spyvm/objspace.py @@ -112,7 +112,7 @@ define_cls("w_BlockContext", "w_ContextPart", instvarsize=constants.BLKCTX_STACK_START) define_cls("w_BlockClosure", "w_Object", - instvarsize=constants.BLOCKCLOSURE_SIZE, + instvarsize=constants.BLKCLSR_SIZE, varsized=True) # make better accessors for classes that can be found in special object # table @@ -255,7 +255,7 @@ def unwrap_array(self, w_array): # Check that our argument has pointers format and the class: if not w_array.getclass(self).is_same_object(self.w_Array): - raise PrimitiveFailedError() + raise UnwrappingError() assert isinstance(w_array, model.W_PointersObject) return [w_array.at0(self, i) for i in range(w_array.size())] diff --git a/spyvm/shadow.py b/spyvm/shadow.py --- a/spyvm/shadow.py +++ b/spyvm/shadow.py @@ -633,7 +633,7 @@ class MethodContextShadow(ContextPartShadow): def __init__(self, space, w_self): - self.w_receiver_map = space.w_nil + self.w_closure_or_nil = space.w_nil self._w_receiver = None ContextPartShadow.__init__(self, space, w_self) @@ -651,6 +651,9 @@ # XXX could hack some more to never have to create the _vars of w_result s_result = MethodContextShadow(space, w_result) w_result.store_shadow(s_result) + if closure is not None: + s_result.w_closure_or_nil = closure._w_self + s_result.store_w_method(w_method) if w_sender: s_result.store_w_sender(w_sender) @@ -664,12 +667,11 @@ def fetch(self, n0): if n0 == constants.MTHDCTX_METHOD: return self.w_method() - if n0 == constants.MTHDCTX_RECEIVER_MAP: - return self.w_receiver_map + if n0 == constants.MTHDCTX_CLOSURE_OR_NIL: + return self.w_closure_or_nil if n0 == constants.MTHDCTX_RECEIVER: return self.w_receiver() - if (0 <= n0-constants.MTHDCTX_TEMP_FRAME_START < - self.tempsize()): + if (0 <= n0-constants.MTHDCTX_TEMP_FRAME_START < self.tempsize()): return self.gettemp(n0-constants.MTHDCTX_TEMP_FRAME_START) else: return ContextPartShadow.fetch(self, n0) @@ -677,8 +679,8 @@ def store(self, n0, w_value): if n0 == constants.MTHDCTX_METHOD: return self.store_w_method(w_value) - if n0 == constants.MTHDCTX_RECEIVER_MAP: - self.w_receiver_map = w_value + if n0 == constants.MTHDCTX_CLOSURE_OR_NIL: + self.w_closure_or_nil = w_value return if n0 == constants.MTHDCTX_RECEIVER: self.store_w_receiver(w_value) diff --git a/spyvm/test/test_primitives.py b/spyvm/test/test_primitives.py --- a/spyvm/test/test_primitives.py +++ b/spyvm/test/test_primitives.py @@ -2,9 +2,7 @@ import math from spyvm.primitives import prim_table, PrimitiveFailedError from spyvm import model, shadow, interpreter -from spyvm import constants -from spyvm import primitives -from spyvm import objspace +from spyvm import constants, primitives, objspace, wrapper from rpython.rlib.rfloat import INFINITY, NAN, isinf, isnan @@ -20,6 +18,7 @@ s_self.reset_stack() s_self.push_all(stack) s_self.store_expected_argument_count(0) + def as_blockcontext_get_shadow(self): self._shadow = shadow.BlockContextShadow(space, self) return self._shadow @@ -33,15 +32,20 @@ if isinstance(x, list): return space.wrap_list(x) raise NotImplementedError -def mock(stack): +def mock(stack, context = None): mapped_stack = [wrap(x) for x in stack] - frame = MockFrame(mapped_stack) + if context is None: + frame = MockFrame(mapped_stack) + else: + frame = context + for i in range(len(stack)): + frame.as_context_get_shadow(space).push(stack[i]) interp = interpreter.Interpreter(space) interp.store_w_active_context(frame) return (interp, len(stack)) -def prim(code, stack): - interp, argument_count = mock(stack) +def prim(code, stack, context = None): + interp, argument_count = mock(stack, context) prim_table[code](interp, argument_count-1) res = interp.s_active_context().pop() assert not interp.s_active_context().stackdepth() # check args are consumed diff --git a/spyvm/test/test_shadow.py b/spyvm/test/test_shadow.py --- a/spyvm/test/test_shadow.py +++ b/spyvm/test/test_shadow.py @@ -87,7 +87,7 @@ w_object.store(space, constants.CTXPART_STACKP_INDEX, space.wrap_int(method.tempsize+stackpointer)) w_object.store(space, constants.MTHDCTX_METHOD, method) # XXX - w_object.store(space, constants.MTHDCTX_RECEIVER_MAP, '???') + w_object.store(space, constants.MTHDCTX_CLOSURE_OR_NIL, space.w_nil) w_object.store(space, constants.MTHDCTX_RECEIVER, 'receiver') w_object.store(space, constants.MTHDCTX_TEMP_FRAME_START, 'el') diff --git a/spyvm/wrapper.py b/spyvm/wrapper.py --- a/spyvm/wrapper.py +++ b/spyvm/wrapper.py @@ -1,4 +1,4 @@ -from spyvm import model +from spyvm import model, constants from spyvm.error import FatalError, WrapperException class Wrapper(object): From noreply at buildbot.pypy.org Fri Feb 22 10:32:04 2013 From: noreply at buildbot.pypy.org (lwassermann) Date: Fri, 22 Feb 2013 10:32:04 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: added two tests for block copy primitive and activation of a BlockClosure with value Message-ID: <20130222093204.570051C01BF@cobra.cs.uni-duesseldorf.de> Author: Lars Wassermann Branch: Changeset: r80:816b5ce0926c Date: 2013-02-21 19:46 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/816b5ce0926c/ Log: added two tests for block copy primitive and activation of a BlockClosure with value implemented the test diff --git a/spyvm/objspace.py b/spyvm/objspace.py --- a/spyvm/objspace.py +++ b/spyvm/objspace.py @@ -265,12 +265,13 @@ def newClosure(self, outerContext, pc, numArgs, copiedValues): BlockClosureShadow = self.w_BlockClosure.as_class_get_shadow(self) - w_closure = BlockClosureShadow.new(len(copiedValues)) + numCopied = 0 if copiedValues is self.w_nil else len(copiedValues) + w_closure = BlockClosureShadow.new(numCopied) closure = wrapper.BlockClosureWrapper(self, w_closure) closure.store_outerContext(outerContext) closure.store_startpc(pc) closure.store_numArgs(numArgs) - for i0 in range(len(copiedValues)): + for i0 in range(numCopied): closure.atput0(i0, copiedValues[i0]) return w_closure, closure diff --git a/spyvm/primitives.py b/spyvm/primitives.py --- a/spyvm/primitives.py +++ b/spyvm/primitives.py @@ -928,61 +928,64 @@ frame = interp.s_active_context() w_context, s_context = interp.space.newClosure(outerContext, frame.pc(), numArgs, copiedValues) - frame.push(w_context) + return w_context -def activateClosure(interp, w_block_closure, args_w, mayContextSwitch=True): - raise PrimitiveFailedError - if not w_block_closure.getclass(interp.space).is_same_object( - interp.space.w_BlockClosure): +def activateClosure(interp, w_block, args_w, mayContextSwitch=True): + space = interp.space + if not w_block.getclass(space).is_same_object( + space.w_BlockClosure): raise PrimitiveFailedError() - if not w_block_closure.numArgs == len(args_w): + block = wrapper.BlockClosureWrapper(space, w_block) + if not block.numArgs() == len(args_w): raise PrimitiveFailedError() - if not w_block_closure.outerContext.getclass(interp.space).issubclass( - interp.space.w_ContextPart): + outer_ctxt_class = block.outerContext().getclass(space) + if not (outer_ctxt_class is space.w_MethodContext + or outer_ctxt_class is space.w_BlockContext + or outer_ctxt_class is space.w_BlockClosure): raise PrimitiveFailedError() - w_closureMethod = w_block_closure.w_method() + + # additionally to the smalltalk implementation, this also pushes + # args and copiedValues + w_new_frame = block.asContextWithSender( + interp.w_active_context(), args_w) + w_closureMethod = w_new_frame.get_shadow(space).w_method() + assert isinstance(w_closureMethod, model.W_CompiledMethod) - assert w_block_closure is not w_block_closure.outerContext - numCopied = w_block_closure.size() + assert w_block is not block.outerContext() - s_block_closure = w_block_closure.as_blockclosure_get_shadow(interp.space) - s_block_closure.push_all(args_w) + interp.store_w_active_context(w_new_frame) - s_block_closure.store_pc(s_block_closure.initialip()) - frame = interp.s_active_context() - s_block_closure.store_w_sender(frame) - - at expose_primitive(CLOSURE_VALUE, unwrap_spec=[object]) + at expose_primitive(CLOSURE_VALUE, unwrap_spec=[object], no_result=True) def func(interp, w_block_closure): activateClosure(interp, w_block_closure, []) - at expose_primitive(CLOSURE_VALUE_, unwrap_spec=[object, object]) + at expose_primitive(CLOSURE_VALUE_, unwrap_spec=[object, object], no_result=True) def func(interp, w_block_closure, w_a0): activateClosure(interp, w_block_closure, [w_a0]) - at expose_primitive(CLOSURE_VALUE_VALUE, unwrap_spec=[object, object, object]) + at expose_primitive(CLOSURE_VALUE_VALUE, unwrap_spec=[object, object, object], no_result=True) def func(interp, w_block_closure, w_a0, w_a1): activateClosure(interp, w_block_closure, [w_a0, w_a1]) - at expose_primitive(CLOSURE_VALUE_VALUE_VALUE, unwrap_spec=[object, object, object, object]) + at expose_primitive(CLOSURE_VALUE_VALUE_VALUE, unwrap_spec=[object, object, object, object], no_result=True) def func(interp, w_block_closure, w_a0, w_a1, w_a2): activateClosure(interp, w_block_closure, [w_a0, w_a1, w_a2]) - at expose_primitive(CLOSURE_VALUE_VALUE_VALUE_VALUE, unwrap_spec=[object, object, object, object, object]) + at expose_primitive(CLOSURE_VALUE_VALUE_VALUE_VALUE, unwrap_spec=[object, object, object, object, object], no_result=True) def func(interp, w_block_closure, w_a0, w_a1, w_a2, w_a3): activateClosure(interp, w_block_closure, [w_a0, w_a1, w_a2, w_a3]) - at expose_primitive(CLOSURE_VALUE_WITH_ARGS, unwrap_spec=[object, list]) + at expose_primitive(CLOSURE_VALUE_WITH_ARGS, unwrap_spec=[object, list], no_result=True) def func(interp, w_block_closure, args_w): activateClosure(interp, w_block_closure, args_w) - at expose_primitive(CLOSURE_VALUE_NO_CONTEXT_SWITCH, unwrap_spec=[object]) + at expose_primitive(CLOSURE_VALUE_NO_CONTEXT_SWITCH, unwrap_spec=[object], no_result=True) def func(interp, w_block_closure): activateClosure(interp, w_block_closure, [], mayContextSwitch=False) - at expose_primitive(CLOSURE_VALUE_NO_CONTEXT_SWITCH_, unwrap_spec=[object, object]) + at expose_primitive(CLOSURE_VALUE_NO_CONTEXT_SWITCH_, unwrap_spec=[object, object], no_result=True) def func(interp, w_block_closure, w_a0): activateClosure(interp, w_block_closure, [w_a0], mayContextSwitch=False) diff --git a/spyvm/shadow.py b/spyvm/shadow.py --- a/spyvm/shadow.py +++ b/spyvm/shadow.py @@ -640,7 +640,7 @@ @staticmethod @jit.unroll_safe def make_context(space, w_method, w_receiver, - arguments, w_sender=None): + arguments, w_sender=None, closure=None, pc=0): # From blue book: normal mc have place for 12 temps+maxstack # mc for methods with islarge flag turned on 32 size = 12 + w_method.islarge * 20 + w_method.argsize @@ -658,10 +658,15 @@ if w_sender: s_result.store_w_sender(w_sender) s_result.store_w_receiver(w_receiver) - s_result.store_pc(0) + s_result.store_pc(pc) s_result.init_stack_and_temps() - for i in range(len(arguments)): - s_result.settemp(i, arguments[i]) + + argc = len(arguments) + for i0 in range(argc): + s_result.settemp(i0, arguments[i0]) + if closure is not None: + for i0 in range(closure.size()): + s_result.settemp(i0+argc, closure.at0(i0)) return w_result def fetch(self, n0): @@ -699,7 +704,11 @@ ContextPartShadow.attach_shadow(self) def tempsize(self): - return self.method().tempsize + if self.w_closure_or_nil == self.space.w_nil: + return self.method().tempsize + else: + return wrapper.BlockClosureWrapper(self.space, + self.w_closure_or_nil).tempsize() def w_method(self): return self._w_method diff --git a/spyvm/test/test_interpreter.py b/spyvm/test/test_interpreter.py --- a/spyvm/test/test_interpreter.py +++ b/spyvm/test/test_interpreter.py @@ -67,7 +67,7 @@ return lit return [fakeliteral(lit) for lit in literals] -def new_interpreter(bytes, receiver=space.w_nil): +def new_interpreter(bytes, receiver=space.w_nil, space=space): assert isinstance(bytes, str) w_method = model.W_CompiledMethod(len(bytes)) w_method.islarge = 1 diff --git a/spyvm/test/test_primitives.py b/spyvm/test/test_primitives.py --- a/spyvm/test/test_primitives.py +++ b/spyvm/test/test_primitives.py @@ -443,6 +443,31 @@ assert space.unwrap_char(w_c) == os.path.sep +def test_primitive_closure_copyClosure(): + from test_interpreter import new_interpreter + interp = new_interpreter("") + w_block = prim(200, map(wrap, ["anActiveContext", 2, [wrap(1), wrap(2)]]), + interp.w_active_context()) + assert w_block is not space.w_nil + w_w_block = wrapper.BlockClosureWrapper(space, w_block) + assert w_w_block.startpc() is 0 + assert w_w_block.at0(0) == wrap(1) + assert w_w_block.at0(1) == wrap(2) + assert w_w_block.numArgs() is 2 + +def test_primitive_closure_value(): + from test_interpreter import new_interpreter + interp = new_interpreter("", + space=space) + s_initial_context = interp.s_active_context() + + closure, _ = space.newClosure(interp.w_active_context(), 4, 0, space.w_nil) + s_initial_context.push(closure) + + prim_table[201](interp, 0) + assert interp.s_active_context().w_closure_or_nil is closure + assert interp.s_active_context().s_sender() is s_initial_context + assert interp.s_active_context().w_receiver() is space.w_nil # Note: # primitives.NEXT is unimplemented as it is a performance optimization diff --git a/spyvm/wrapper.py b/spyvm/wrapper.py --- a/spyvm/wrapper.py +++ b/spyvm/wrapper.py @@ -215,9 +215,29 @@ class BlockClosureWrapper(VarsizedWrapper): - outerContext, store_outerContext = make_getter_setter(0) - startpc, store_startpc = make_int_getter_setter(1) - numArgs, store_numArgs = make_int_getter_setter(2) + outerContext, store_outerContext = make_getter_setter(constants.BLKCLSR_OUTER_CONTEXT) + startpc, store_startpc = make_int_getter_setter(constants.BLKCLSR_STARTPC) + numArgs, store_numArgs = make_int_getter_setter(constants.BLKCLSR_NUMARGS) + + def asContextWithSender(self, w_aContext, arguments): + from spyvm import shadow + s_outerContext = self.outerContext().get_shadow(self.space) + w_method = s_outerContext.w_method() + w_receiver = s_outerContext.w_receiver() + w_new_frame = shadow.MethodContextShadow.make_context(self.space , w_method, w_receiver, + arguments, w_sender=w_aContext, pc=self.startpc(), closure=self) + return w_new_frame + + def tempsize(self): + # We ignore the number of temps a block has, because the first + # bytecodes of the block will initialize them for us. We will only + # use this information for decinding where the stack pointer should be + # initialy. + # For a finding the correct number, see BlockClosure>#numTemps in an Image. + return self.size() + self.numArgs() + + def size(self): + return self._w_self.size() - constants.BLKCLSR_SIZE # XXX Wrappers below are not used yet. class OffsetWrapper(Wrapper): From noreply at buildbot.pypy.org Fri Feb 22 10:32:05 2013 From: noreply at buildbot.pypy.org (lwassermann) Date: Fri, 22 Feb 2013 10:32:05 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: refactored newClosure to RPython Message-ID: <20130222093205.683CC1C01BF@cobra.cs.uni-duesseldorf.de> Author: Lars Wassermann Branch: Changeset: r81:0b69628b3e93 Date: 2013-02-21 20:26 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/0b69628b3e93/ Log: refactored newClosure to RPython different from the squeak-image, newClosure expects an empty list instead of w_nil, if there are no copiedValues diff --git a/spyvm/interpreter.py b/spyvm/interpreter.py --- a/spyvm/interpreter.py +++ b/spyvm/interpreter.py @@ -427,7 +427,7 @@ i = self.getbytecode() blockSize = (j << 8) | i #create new instance of BlockClosure - w_closure, closure = space.newClosure(self._w_self, self.pc(), numArgs, + w_closure = space.newClosure(self._w_self, self.pc(), numArgs, self.pop_and_return_n(numCopied)) self.push(w_closure) self.jump(blockSize) diff --git a/spyvm/objspace.py b/spyvm/objspace.py --- a/spyvm/objspace.py +++ b/spyvm/objspace.py @@ -265,7 +265,7 @@ def newClosure(self, outerContext, pc, numArgs, copiedValues): BlockClosureShadow = self.w_BlockClosure.as_class_get_shadow(self) - numCopied = 0 if copiedValues is self.w_nil else len(copiedValues) + numCopied = len(copiedValues) w_closure = BlockClosureShadow.new(numCopied) closure = wrapper.BlockClosureWrapper(self, w_closure) closure.store_outerContext(outerContext) @@ -273,7 +273,7 @@ closure.store_numArgs(numArgs) for i0 in range(numCopied): closure.atput0(i0, copiedValues[i0]) - return w_closure, closure + return w_closure def bootstrap_class(space, instsize, w_superclass=None, w_metaclass=None, name='?', format=shadow.POINTERS, varsized=False): diff --git a/spyvm/primitives.py b/spyvm/primitives.py --- a/spyvm/primitives.py +++ b/spyvm/primitives.py @@ -926,7 +926,7 @@ @expose_primitive(CLOSURE_COPY_WITH_COPIED_VALUES, unwrap_spec=[object, int, list]) def func(interp, outerContext, numArgs, copiedValues): frame = interp.s_active_context() - w_context, s_context = interp.space.newClosure(outerContext, frame.pc(), + w_context = interp.space.newClosure(outerContext, frame.pc(), numArgs, copiedValues) return w_context diff --git a/spyvm/test/test_primitives.py b/spyvm/test/test_primitives.py --- a/spyvm/test/test_primitives.py +++ b/spyvm/test/test_primitives.py @@ -461,7 +461,7 @@ space=space) s_initial_context = interp.s_active_context() - closure, _ = space.newClosure(interp.w_active_context(), 4, 0, space.w_nil) + closure = space.newClosure(interp.w_active_context(), 4, 0, []) s_initial_context.push(closure) prim_table[201](interp, 0) From noreply at buildbot.pypy.org Fri Feb 22 10:32:06 2013 From: noreply at buildbot.pypy.org (lwassermann) Date: Fri, 22 Feb 2013 10:32:06 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: added more tests for block closures Message-ID: <20130222093206.6F1D21C01BF@cobra.cs.uni-duesseldorf.de> Author: Lars Wassermann Branch: Changeset: r82:e3c5446909d2 Date: 2013-02-22 10:28 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/e3c5446909d2/ Log: added more tests for block closures diff --git a/spyvm/test/test_primitives.py b/spyvm/test/test_primitives.py --- a/spyvm/test/test_primitives.py +++ b/spyvm/test/test_primitives.py @@ -455,19 +455,45 @@ assert w_w_block.at0(1) == wrap(2) assert w_w_block.numArgs() is 2 -def test_primitive_closure_value(): +def build_up_closure_environment(args, copiedValues=[]): from test_interpreter import new_interpreter interp = new_interpreter("", space=space) s_initial_context = interp.s_active_context() - closure = space.newClosure(interp.w_active_context(), 4, 0, []) - s_initial_context.push(closure) + size_arguments = len(args) + closure = space.newClosure(interp.w_active_context(), 4, #pc + size_arguments, copiedValues) + s_initial_context.push_all([closure] + args) + prim_table[201 + size_arguments](interp, size_arguments) + return interp, s_initial_context, closure, interp.s_active_context() - prim_table[201](interp, 0) - assert interp.s_active_context().w_closure_or_nil is closure - assert interp.s_active_context().s_sender() is s_initial_context - assert interp.s_active_context().w_receiver() is space.w_nil +def test_primitive_closure_value(): + interp, s_initial_context, closure, s_new_context = build_up_closure_environment([]) + + assert s_new_context.w_closure_or_nil is closure + assert s_new_context.s_sender() is s_initial_context + assert s_new_context.w_receiver() is space.w_nil + +def test_primitive_closure_value_value(): + interp, s_initial_context, closure, s_new_context = build_up_closure_environment(["first arg", "second arg"]) + + assert s_new_context.w_closure_or_nil is closure + assert s_new_context.s_sender() is s_initial_context + assert s_new_context.w_receiver() is space.w_nil + assert s_new_context.gettemp(0) == "first arg" + assert s_new_context.gettemp(1) == "second arg" + +def test_primitive_closure_value_value_with_temps(): + interp, s_initial_context, closure, s_new_context = build_up_closure_environment(["first arg", "second arg"], + copiedValues=['some value']) + + assert s_new_context.w_closure_or_nil is closure + assert s_new_context.s_sender() is s_initial_context + assert s_new_context.w_receiver() is space.w_nil + assert s_new_context.gettemp(0) == "first arg" + assert s_new_context.gettemp(1) == "second arg" + assert s_new_context.gettemp(2) == "some value" # Note: # primitives.NEXT is unimplemented as it is a performance optimization From noreply at buildbot.pypy.org Fri Feb 22 10:32:07 2013 From: noreply at buildbot.pypy.org (lwassermann) Date: Fri, 22 Feb 2013 10:32:07 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: merge Message-ID: <20130222093207.851AA1C01BF@cobra.cs.uni-duesseldorf.de> Author: Lars Wassermann Branch: Changeset: r83:6010b06d29b2 Date: 2013-02-22 10:31 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/6010b06d29b2/ Log: merge diff --git a/spyvm/squeakimage.py b/spyvm/squeakimage.py --- a/spyvm/squeakimage.py +++ b/spyvm/squeakimage.py @@ -6,37 +6,33 @@ from rpython.rlib import objectmodel -def chrs2int(b, unsigned): +def chrs2int(b): assert len(b) == 4 first = ord(b[0]) # big endian - if not unsigned: - if first & 0x80 != 0: - first = first - 0x100 + if first & 0x80 != 0: + first = first - 0x100 return (first << 24 | ord(b[1]) << 16 | ord(b[2]) << 8 | ord(b[3])) -def swapped_chrs2int(b, unsigned): +def swapped_chrs2int(b): assert len(b) == 4 first = ord(b[3]) # little endian - if not unsigned: - if first & 0x80 != 0: - first = first - 0x100 + if first & 0x80 != 0: + first = first - 0x100 return (first << 24 | ord(b[2]) << 16 | ord(b[1]) << 8 | ord(b[0])) -def chrs2long(b, unsigned): +def chrs2long(b): assert len(b) == 8 first = ord(b[0]) # big endian - if not unsigned: - if first & 0x80 != 0: - first = first - 0x100 + if first & 0x80 != 0: + first = first - 0x100 return ( first << 56 | ord(b[1]) << 48 | ord(b[2]) << 40 | ord(b[3]) << 32 | ord(b[4]) << 24 | ord(b[5]) << 16 | ord(b[6]) << 8 | ord(b[7]) ) -def swapped_chrs2long(b, unsigned): +def swapped_chrs2long(b): assert len(b) == 8 first = ord(b[7]) # little endian - if not unsigned: - if first & 0x80 != 0: - first = first - 0x100 + if first & 0x80 != 0: + first = first - 0x100 return ( first << 56 | ord(b[6]) << 48 | ord(b[5]) << 40 | ord(b[4]) << 32 | ord(b[3]) << 24 | ord(b[2]) << 16 | ord(b[1]) << 8 | ord(b[0]) ) @@ -60,29 +56,14 @@ data_peek = self.data[self.pos:self.pos + self.word_size] if self.use_long_read: if self.swap: - return swapped_chrs2long(data_peek, False) + return swapped_chrs2long(data_peek) else: - return chrs2long(data_peek, False) + return chrs2long(data_peek) else: if self.swap: - return swapped_chrs2int(data_peek, False) + return swapped_chrs2int(data_peek) else: - return chrs2int(data_peek, False) - - def peek_unsigned(self): - if self.pos >= len(self.data): - raise IndexError - data_peek = self.data[self.pos:self.pos + self.word_size] - if self.use_long_read: - if self.swap: - return swapped_chrs2long(data_peek, True) - else: - return chrs2long(data_peek, True) - else: - if self.swap: - return swapped_chrs2int(data_peek, True) - else: - return chrs2int(data_peek, True) + return chrs2int(data_peek) def next(self): @@ -152,12 +133,18 @@ 0x68190000: ImageVersion(6504, False, False, True, False), 0x00001969: ImageVersion(6505, True, False, True, True ), 0x69190000: ImageVersion(6505, False, False, True, True ), - 0x000109A0: ImageVersion(68000, True, True, False, False), - 0xA009010000000000: ImageVersion(68000, False, True, False, False), + 0x00000000000109A0: ImageVersion(68000, True, True, False, False), + -0x5ff6ff0000000000: + # signed version of 0xA009010000000000: + ImageVersion(68000, False, True, False, False), 0x00000000000109A2: ImageVersion(68002, True, True, True, False), - 0xA209010000000000: ImageVersion(68002, False, True, True, False), + -0x5df6ff0000000000: + # signed version of 0xA209010000000000: + ImageVersion(68002, False, True, True, False), 0x00000000000109A3: ImageVersion(68003, True, True, True, True ), - 0xA309010000000000: ImageVersion(68003, False, True, True, True ), + -0x5cf6ff0000000000: + # signed version of 0xA309010000000000: + ImageVersion(68003, False, True, True, True ), } @@ -174,26 +161,26 @@ def version_from_stream(stream): # 32 bit try: - return version(stream.peek_unsigned()) + return version(stream.peek()) except CorruptImageError as e: if stream.length() > possible_image_offset + 4: stream.skipbytes(possible_image_offset) try: - return version(stream.peek_unsigned()) + return version(stream.peek()) except CorruptImageError: pass # raise original error # 64 bit stream.reset() stream.be_64bit() try: - v = version(stream.peek_unsigned()) + v = version(stream.peek()) assert v.is_64bit return v except CorruptImageError as e: if stream.length() > possible_image_offset + 4: stream.skipbytes(possible_image_offset) try: - v = version(stream.peek_unsigned()) + v = version(stream.peek()) assert v.is_64bit return v except CorruptImageError: diff --git a/spyvm/test/test_squeakimage.py b/spyvm/test/test_squeakimage.py --- a/spyvm/test/test_squeakimage.py +++ b/spyvm/test/test_squeakimage.py @@ -35,18 +35,14 @@ # ----- tests ------------------------------------------------ def test_chrs2int(): - assert 1 == chrs2int('\x00\x00\x00\x01', False) - assert -1 == chrs2int('\xFF\xFF\xFF\xFF', False) - assert 1 == chrs2int('\x00\x00\x00\x01', True) - assert 0xFFFFFFFF == chrs2int('\xFF\xFF\xFF\xFF', True) + assert 1 == chrs2int('\x00\x00\x00\x01') + assert -1 == chrs2int('\xFF\xFF\xFF\xFF') def test_chrs2long(): - assert 1 == chrs2long('\x00\x00\x00\x00\x00\x00\x00\x01', False) - assert -1 == chrs2long('\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF', False) - assert 1 == chrs2long('\x00\x00\x00\x00\x00\x00\x00\x01', True) - assert 0xFFFFFFFFFFFFFFFF == chrs2long('\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF', True) - assert 68002 == chrs2long(pack(">Q", 68002), False) - assert 68002 == swapped_chrs2long(pack("Q", 68002)) + assert 68002 == swapped_chrs2long(pack(" Author: Armin Rigo Branch: stm-thread-2 Changeset: r61589:6d0d79768e97 Date: 2013-02-22 10:17 +0100 http://bitbucket.org/pypy/pypy/changeset/6d0d79768e97/ Log: Fixes diff --git a/pypy/module/__pypy__/interp_atomic.py b/pypy/module/__pypy__/interp_atomic.py --- a/pypy/module/__pypy__/interp_atomic.py +++ b/pypy/module/__pypy__/interp_atomic.py @@ -65,11 +65,11 @@ def bdecodelist(space, p): p = rffi.ptradd(p, 1) - w_list = space.newlist() + objects_w = [] while p[0] != 'e': w_obj, p = bdecode(space, p) - space.call_method(w_list, 'append', w_obj) - return (w_list, rffi.ptradd(p, 1)) + objects_w.append(w_obj) + return (space.newlist(objects_w), rffi.ptradd(p, 1)) def bdecodestr(space, p): length = 0 diff --git a/pypy/module/__pypy__/test/test_atomic.py b/pypy/module/__pypy__/test/test_atomic.py --- a/pypy/module/__pypy__/test/test_atomic.py +++ b/pypy/module/__pypy__/test/test_atomic.py @@ -12,11 +12,9 @@ def int(self, x): assert isinstance(x, str) return int(x) - def newlist(self): - return [] - def call_method(self, w_obj, method, *args): - assert method == 'append' - w_obj.append(*args) + def newlist(self, lst): + assert isinstance(lst, list) + return lst space = FakeSpace() diff --git a/rpython/rlib/rstm.py b/rpython/rlib/rstm.py --- a/rpython/rlib/rstm.py +++ b/rpython/rlib/rstm.py @@ -37,7 +37,8 @@ "Special-cased below." def abort_info_pop(count): - stmgcintf.StmOperations.abort_info_pop(count) + if we_are_translated(): + stmgcintf.StmOperations.abort_info_pop(count) def charp_inspect_abort_info(): return stmgcintf.StmOperations.inspect_abort_info() From noreply at buildbot.pypy.org Fri Feb 22 11:17:39 2013 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 22 Feb 2013 11:17:39 +0100 (CET) Subject: [pypy-commit] pypy stm-thread-2: Use charp_inspect_abort_info(). Message-ID: <20130222101739.9710D1C1367@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stm-thread-2 Changeset: r61590:0155e5adde15 Date: 2013-02-22 11:14 +0100 http://bitbucket.org/pypy/pypy/changeset/0155e5adde15/ Log: Use charp_inspect_abort_info(). diff --git a/pypy/module/__pypy__/__init__.py b/pypy/module/__pypy__/__init__.py --- a/pypy/module/__pypy__/__init__.py +++ b/pypy/module/__pypy__/__init__.py @@ -39,7 +39,6 @@ '_atomic_enter': 'interp_atomic.atomic_enter', '_exclusive_atomic_enter': 'interp_atomic.exclusive_atomic_enter', '_atomic_exit': 'interp_atomic.atomic_exit', - '_raw_last_abort_info': 'interp_atomic.raw_last_abort_info', 'last_abort_info': 'interp_atomic.last_abort_info', } diff --git a/pypy/module/__pypy__/interp_atomic.py b/pypy/module/__pypy__/interp_atomic.py --- a/pypy/module/__pypy__/interp_atomic.py +++ b/pypy/module/__pypy__/interp_atomic.py @@ -41,15 +41,14 @@ raise wrap_thread_error(space, "atomic.__exit__(): more exits than enters") -def raw_last_abort_info(space): - return space.wrap(rstm.inspect_abort_info()) - def last_abort_info(space): - p = rstm.inspect_abort_info() + from rpython.rlib.rstm import charp_inspect_abort_info + p = charp_inspect_abort_info() if not p: return space.w_None assert p[0] == 'l' w_obj, p = bdecode(space, p) + assert p[0] == '\0' return w_obj def bdecode(space, p): From noreply at buildbot.pypy.org Fri Feb 22 11:17:40 2013 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 22 Feb 2013 11:17:40 +0100 (CET) Subject: [pypy-commit] pypy stm-thread-2: Fix for fields that actually belong to parent classes Message-ID: <20130222101740.D0C771C1367@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stm-thread-2 Changeset: r61591:7d37f41f86cb Date: 2013-02-22 11:14 +0100 http://bitbucket.org/pypy/pypy/changeset/7d37f41f86cb/ Log: Fix for fields that actually belong to parent classes diff --git a/rpython/rlib/rstm.py b/rpython/rlib/rstm.py --- a/rpython/rlib/rstm.py +++ b/rpython/rlib/rstm.py @@ -133,7 +133,6 @@ fieldnames = hop.args_s[1].const lst = [] v_instance = hop.inputarg(hop.args_r[0], arg=0) - STRUCT = v_instance.concretetype.TO for fieldname in fieldnames: if fieldname == '[': lst.append(-2) # start of sublist @@ -142,7 +141,10 @@ lst.append(-1) # end of sublist continue fieldname = 'inst_' + fieldname - TYPE = getattr(STRUCT, fieldname) #xxx check also in parent structs + STRUCT = v_instance.concretetype.TO + while not hasattr(STRUCT, fieldname): + STRUCT = STRUCT.super + TYPE = getattr(STRUCT, fieldname) if TYPE == lltype.Signed: kind = 1 elif TYPE == lltype.Unsigned: diff --git a/rpython/translator/stm/test/test_ztranslated.py b/rpython/translator/stm/test/test_ztranslated.py --- a/rpython/translator/stm/test/test_ztranslated.py +++ b/rpython/translator/stm/test/test_ztranslated.py @@ -132,7 +132,9 @@ def test_abort_info(self): from rpython.rtyper.lltypesystem.rclass import OBJECTPTR - class Foobar(object): + class Parent(object): + pass + class Foobar(Parent): pass globf = Foobar() @@ -151,6 +153,7 @@ perform_transaction = rstm.make_perform_transaction(check, PS) def main(argv): + Parent().xy = 0 globf.yx = 'hi there %d' % len(argv) perform_transaction(lltype.nullptr(PS.TO)) return 0 From noreply at buildbot.pypy.org Fri Feb 22 11:46:39 2013 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 22 Feb 2013 11:46:39 +0100 (CET) Subject: [pypy-commit] pypy default: we need nonneg here Message-ID: <20130222104639.B3F061C01BF@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r61592:8752e5648e16 Date: 2013-02-22 12:34 +0200 http://bitbucket.org/pypy/pypy/changeset/8752e5648e16/ Log: we need nonneg here diff --git a/rpython/rtyper/lltypesystem/rdict.py b/rpython/rtyper/lltypesystem/rdict.py --- a/rpython/rtyper/lltypesystem/rdict.py +++ b/rpython/rtyper/lltypesystem/rdict.py @@ -8,6 +8,7 @@ from rpython.rlib.rarithmetic import r_uint, intmask, LONG_BIT from rpython.rtyper import rmodel from rpython.rtyper.error import TyperError +from rpython.annotator.model import SomeInteger HIGHEST_BIT = intmask(1 << (LONG_BIT - 1)) @@ -385,39 +386,39 @@ # be direct_call'ed from rtyped flow graphs, which means that they will # get flowed and annotated, mostly with SomePtr. - at objectmodel.enforceargs(None, int) + at objectmodel.enforceargs(None, SomeInteger(nonneg=True)) def ll_everused_from_flag(entries, i): return entries[i].f_everused - at objectmodel.enforceargs(None, int) + at objectmodel.enforceargs(None, SomeInteger(nonneg=True)) def ll_everused_from_key(entries, i): return bool(entries[i].key) - at objectmodel.enforceargs(None, int) + at objectmodel.enforceargs(None, SomeInteger(nonneg=True)) def ll_everused_from_value(entries, i): return bool(entries[i].value) - at objectmodel.enforceargs(None, int) + at objectmodel.enforceargs(None, SomeInteger(nonneg=True)) def ll_valid_from_flag(entries, i): return entries[i].f_valid - at objectmodel.enforceargs(None, int) + at objectmodel.enforceargs(None, SomeInteger(nonneg=True)) def ll_mark_deleted_in_flag(entries, i): entries[i].f_valid = False - at objectmodel.enforceargs(None, int) + at objectmodel.enforceargs(None, SomeInteger(nonneg=True)) def ll_valid_from_key(entries, i): ENTRIES = lltype.typeOf(entries).TO dummy = ENTRIES.dummy_obj.ll_dummy_value return entries.everused(i) and entries[i].key != dummy - at objectmodel.enforceargs(None, int) + at objectmodel.enforceargs(None, SomeInteger(nonneg=True)) def ll_mark_deleted_in_key(entries, i): ENTRIES = lltype.typeOf(entries).TO dummy = ENTRIES.dummy_obj.ll_dummy_value entries[i].key = dummy - at objectmodel.enforceargs(None, int) + at objectmodel.enforceargs(None, SomeInteger(nonneg=True)) def ll_valid_from_value(entries, i): ENTRIES = lltype.typeOf(entries).TO dummy = ENTRIES.dummy_obj.ll_dummy_value @@ -585,6 +586,7 @@ direct_compare = not hasattr(ENTRIES, 'no_direct_compare') mask = len(entries) - 1 i = hash & mask + assert i >= 0 # do the first try before any looping if entries.valid(i): checkingkey = entries[i].key From noreply at buildbot.pypy.org Fri Feb 22 11:46:41 2013 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 22 Feb 2013 11:46:41 +0100 (CET) Subject: [pypy-commit] pypy default: enforce those things to be unsigned Message-ID: <20130222104641.0F8EF1C01BF@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r61593:0e57c3ef3cb4 Date: 2013-02-22 12:43 +0200 http://bitbucket.org/pypy/pypy/changeset/0e57c3ef3cb4/ Log: enforce those things to be unsigned diff --git a/rpython/rlib/objectmodel.py b/rpython/rlib/objectmodel.py --- a/rpython/rlib/objectmodel.py +++ b/rpython/rlib/objectmodel.py @@ -153,7 +153,8 @@ else: return type(arg) def typecheck(*args): - from rpython.annotator.model import SomeList, SomeDict, SomeChar + from rpython.annotator.model import SomeList, SomeDict, SomeChar,\ + SomeInteger for i, (expected_type, arg) in enumerate(zip(types, args)): if expected_type is None: continue @@ -167,6 +168,9 @@ if isinstance(s_expected, SomeChar) and ( isinstance(arg, str) and len(arg) == 1): # a char continue + if (isinstance(s_expected, SomeInteger) and + isinstance(arg, s_expected.knowntype)): + continue # s_argtype = get_annotation(get_type_descr_of_argument(arg)) if not s_expected.contains(s_argtype): diff --git a/rpython/rtyper/lltypesystem/rdict.py b/rpython/rtyper/lltypesystem/rdict.py --- a/rpython/rtyper/lltypesystem/rdict.py +++ b/rpython/rtyper/lltypesystem/rdict.py @@ -526,6 +526,7 @@ @jit.look_inside_iff(lambda d, i: jit.isvirtual(d) and jit.isconstant(i)) def _ll_dict_del(d, i): + assert i >= 0 d.entries.mark_deleted(i) d.num_items -= 1 # clear the key and the value if they are GC pointers @@ -617,6 +618,7 @@ i = r_uint(i) i = (i << 2) + i + perturb + 1 i = intmask(i) & mask + assert i >= 0 # keep 'i' as a signed number here, to consistently pass signed # arguments to the small helper methods. if not entries.everused(i): @@ -650,11 +652,13 @@ entries = d.entries mask = len(entries) - 1 i = hash & mask + assert i >= 0 perturb = r_uint(hash) while entries.everused(i): i = r_uint(i) i = (i << 2) + i + perturb + 1 i = intmask(i) & mask + assert i >= 0 perturb >>= PERTURB_SHIFT return i @@ -747,6 +751,7 @@ if dict: entries = dict.entries index = iter.index + assert index >= 0 entries_len = len(entries) while index < entries_len: entry = entries[index] From noreply at buildbot.pypy.org Fri Feb 22 11:46:42 2013 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 22 Feb 2013 11:46:42 +0100 (CET) Subject: [pypy-commit] pypy default: merge Message-ID: <20130222104642.67C6D1C01BF@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r61594:874f26aca217 Date: 2013-02-22 12:44 +0200 http://bitbucket.org/pypy/pypy/changeset/874f26aca217/ Log: merge diff --git a/pypy/doc/ctypes-implementation.rst b/pypy/doc/ctypes-implementation.rst --- a/pypy/doc/ctypes-implementation.rst +++ b/pypy/doc/ctypes-implementation.rst @@ -38,7 +38,7 @@ in dynamic libraries through libffi. Freeing objects in most cases and making sure that objects referring to each other are kept alive is responsibility of the higher levels. -This module uses bindings to libffi which are defined in ``pypy/rlib/libffi.py``. +This module uses bindings to libffi which are defined in ``rpython/rlib/libffi.py``. We tried to keep this module as small as possible. It is conceivable that other implementations (e.g. Jython) could use our ctypes diff --git a/pypy/doc/discussion/improve-rpython.rst b/pypy/doc/discussion/improve-rpython.rst --- a/pypy/doc/discussion/improve-rpython.rst +++ b/pypy/doc/discussion/improve-rpython.rst @@ -39,7 +39,7 @@ - Allocate variables on the stack, and pass their address ("by reference") to llexternal functions. For a typical usage, see - `pypy.rlib.rsocket.RSocket.getsockopt_int`. + `rpython.rlib.rsocket.RSocket.getsockopt_int`. Extensible type system for llexternal ------------------------------------- diff --git a/pypy/doc/stackless.rst b/pypy/doc/stackless.rst --- a/pypy/doc/stackless.rst +++ b/pypy/doc/stackless.rst @@ -273,7 +273,7 @@ more information about them please see the documentation in the C source at `rpython/translator/c/src/stacklet/stacklet.h`_. -The module ``pypy.rlib.rstacklet`` is a thin wrapper around the above +The module ``rpython.rlib.rstacklet`` is a thin wrapper around the above functions. The key point is that new() and switch() always return a fresh stacklet handle (or an empty one), and switch() additionally consumes one. It makes no sense to have code in which the returned diff --git a/pypy/module/_io/interp_bytesio.py b/pypy/module/_io/interp_bytesio.py --- a/pypy/module/_io/interp_bytesio.py +++ b/pypy/module/_io/interp_bytesio.py @@ -52,6 +52,25 @@ self.pos += size return space.wrap(output) + def readline_w(self, space, w_limit=None): + self._check_closed(space) + limit = convert_size(space, w_limit) + + cur_pos = self.pos + if limit < 0: + end_pos = self.string_size + else: + end_pos = min(cur_pos + limit, self.string_size) + while cur_pos != end_pos: + if self.buf[cur_pos] == '\n': + cur_pos += 1 + break + cur_pos += 1 + + output = buffer2string(self.buf, self.pos, cur_pos) + self.pos = cur_pos + return space.wrap(output) + def read1_w(self, space, w_size): return self.read_w(space, w_size) @@ -209,6 +228,7 @@ read = interp2app(W_BytesIO.read_w), read1 = interp2app(W_BytesIO.read1_w), + readline = interp2app(W_BytesIO.readline_w), readinto = interp2app(W_BytesIO.readinto_w), write = interp2app(W_BytesIO.write_w), truncate = interp2app(W_BytesIO.truncate_w), diff --git a/pypy/module/_io/test/test_bytesio.py b/pypy/module/_io/test/test_bytesio.py --- a/pypy/module/_io/test/test_bytesio.py +++ b/pypy/module/_io/test/test_bytesio.py @@ -75,3 +75,19 @@ b = _io.BytesIO("hello") b.close() raises(ValueError, b.readinto, bytearray("hello")) + + def test_readline(self): + import _io + f = _io.BytesIO(b'abc\ndef\nxyzzy\nfoo\x00bar\nanother line') + assert f.readline() == b'abc\n' + assert f.readline(10) == b'def\n' + assert f.readline(2) == b'xy' + assert f.readline(4) == b'zzy\n' + assert f.readline() == b'foo\x00bar\n' + assert f.readline(None) == b'another line' + raises(TypeError, f.readline, 5.3) + + def test_overread(self): + import _io + f = _io.BytesIO(b'abc') + assert f.readline(10) == b'abc' diff --git a/rpython/rtyper/lltypesystem/rlist.py b/rpython/rtyper/lltypesystem/rlist.py --- a/rpython/rtyper/lltypesystem/rlist.py +++ b/rpython/rtyper/lltypesystem/rlist.py @@ -419,6 +419,7 @@ def __init__(self, r_list): self.r_list = r_list + self.external_item_repr = r_list.external_item_repr self.lowleveltype = Ptr(GcStruct('listiter', ('list', r_list.lowleveltype), ('index', Signed))) diff --git a/rpython/rtyper/lltypesystem/rstr.py b/rpython/rtyper/lltypesystem/rstr.py --- a/rpython/rtyper/lltypesystem/rstr.py +++ b/rpython/rtyper/lltypesystem/rstr.py @@ -1054,15 +1054,18 @@ def __init__(self): self.ll_striter = ll_striter self.ll_strnext = ll_strnext + self.ll_getnextindex = ll_getnextindex class StringIteratorRepr(BaseStringIteratorRepr): + external_item_repr = char_repr lowleveltype = Ptr(GcStruct('stringiter', ('string', string_repr.lowleveltype), ('index', Signed))) class UnicodeIteratorRepr(BaseStringIteratorRepr): + external_item_repr = unichar_repr lowleveltype = Ptr(GcStruct('unicodeiter', ('string', unicode_repr.lowleveltype), ('index', Signed))) @@ -1087,6 +1090,9 @@ iter.index = index + 1 return chars[index] +def ll_getnextindex(iter): + return iter.index + string_repr.iterator_repr = StringIteratorRepr() unicode_repr.iterator_repr = UnicodeIteratorRepr() diff --git a/rpython/rtyper/ootypesystem/rstr.py b/rpython/rtyper/ootypesystem/rstr.py --- a/rpython/rtyper/ootypesystem/rstr.py +++ b/rpython/rtyper/ootypesystem/rstr.py @@ -428,14 +428,17 @@ class StringIteratorRepr(AbstractStringIteratorRepr): + external_item_repr = char_repr lowleveltype = ootype.Record({'string': string_repr.lowleveltype, 'index': ootype.Signed}) def __init__(self): self.ll_striter = ll_striter self.ll_strnext = ll_strnext + self.ll_getnextindex = ll_getnextindex class UnicodeIteratorRepr(AbstractStringIteratorRepr): + external_item_repr = unichar_repr lowleveltype = ootype.Record({'string': unicode_repr.lowleveltype, 'index': ootype.Signed}) @@ -463,6 +466,9 @@ iter.index = index + 1 return string.ll_stritem_nonneg(index) +def ll_getnextindex(iter): + return iter.index + StringRepr.string_iterator_repr = StringIteratorRepr() UnicodeRepr.string_iterator_repr = UnicodeIteratorRepr() diff --git a/rpython/rtyper/rrange.py b/rpython/rtyper/rrange.py --- a/rpython/rtyper/rrange.py +++ b/rpython/rtyper/rrange.py @@ -207,7 +207,7 @@ v_index = hop.gendirectcall(self.ll_getnextindex, v_enumerate) hop2 = hop.copy() hop2.args_r = [self.r_baseiter] - r_item_src = self.r_baseiter.r_list.external_item_repr + r_item_src = self.r_baseiter.external_item_repr r_item_dst = hop.r_result.items_r[1] v_item = self.r_baseiter.rtype_next(hop2) v_item = hop.llops.convertvar(v_item, r_item_src, r_item_dst) diff --git a/rpython/rtyper/test/test_rstr.py b/rpython/rtyper/test/test_rstr.py --- a/rpython/rtyper/test/test_rstr.py +++ b/rpython/rtyper/test/test_rstr.py @@ -1035,6 +1035,17 @@ got = self.interpret(f, [7]) assert self.ll_to_string(got) == 'None' + def test_enumerate(self): + const = self.const + def fn(n): + s = const('abcde') + for i, x in enumerate(s): + if i == n: + return x + return 'x' + res = self.interpret(fn, [2]) + assert res == 'c' + def FIXME_test_str_to_pystringobj(): def f(n): diff --git a/rpython/translator/c/src/mem.h b/rpython/translator/c/src/mem.h --- a/rpython/translator/c/src/mem.h +++ b/rpython/translator/c/src/mem.h @@ -4,7 +4,7 @@ #include -/* used by pypy.rlib.rstack, but also by asmgcc */ +/* used by rpython.rlib.rstack, but also by asmgcc */ #define OP_STACK_CURRENT(r) r = (Signed)&r diff --git a/rpython/translator/c/src/stack.h b/rpython/translator/c/src/stack.h --- a/rpython/translator/c/src/stack.h +++ b/rpython/translator/c/src/stack.h @@ -18,7 +18,7 @@ char LL_stack_too_big_slowpath(long); /* returns 0 (ok) or 1 (too big) */ void LL_stack_set_length_fraction(double); -/* some macros referenced from pypy.rlib.rstack */ +/* some macros referenced from rpython.rlib.rstack */ #define LL_stack_get_end() ((long)_LLstacktoobig_stack_end) #define LL_stack_get_length() _LLstacktoobig_stack_length #define LL_stack_get_end_adr() ((long)&_LLstacktoobig_stack_end) /* JIT */ From noreply at buildbot.pypy.org Fri Feb 22 11:47:56 2013 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 22 Feb 2013 11:47:56 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: merge default Message-ID: <20130222104756.41E1B1C01BF@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61595:28dc8f51844f Date: 2013-02-22 12:47 +0200 http://bitbucket.org/pypy/pypy/changeset/28dc8f51844f/ Log: merge default diff --git a/pypy/doc/_ref.txt b/pypy/doc/_ref.txt --- a/pypy/doc/_ref.txt +++ b/pypy/doc/_ref.txt @@ -1,24 +1,19 @@ .. _`ctypes_configure/doc/sample.py`: https://bitbucket.org/pypy/pypy/src/default/ctypes_configure/doc/sample.py -.. _`demo/`: https://bitbucket.org/pypy/pypy/src/default/demo/ +.. _`dotviewer/`: https://bitbucket.org/pypy/pypy/src/default/dotviewer/ .. _`lib-python/`: https://bitbucket.org/pypy/pypy/src/default/lib-python/ .. _`lib-python/2.7/dis.py`: https://bitbucket.org/pypy/pypy/src/default/lib-python/2.7/dis.py .. _`lib_pypy/`: https://bitbucket.org/pypy/pypy/src/default/lib_pypy/ .. _`lib_pypy/greenlet.py`: https://bitbucket.org/pypy/pypy/src/default/lib_pypy/greenlet.py .. _`lib_pypy/pypy_test/`: https://bitbucket.org/pypy/pypy/src/default/lib_pypy/pypy_test/ .. _`lib_pypy/tputil.py`: https://bitbucket.org/pypy/pypy/src/default/lib_pypy/tputil.py -.. _`pypy/annotation`: -.. _`pypy/annotation/`: https://bitbucket.org/pypy/pypy/src/default/pypy/annotation/ -.. _`pypy/annotation/annrpython.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/annotation/annrpython.py -.. _`pypy/annotation/binaryop.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/annotation/binaryop.py -.. _`pypy/annotation/builtin.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/annotation/builtin.py .. _`pypy/bin/`: https://bitbucket.org/pypy/pypy/src/default/pypy/bin/ -.. _`pypy/bin/translatorshell.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/bin/translatorshell.py +.. _`pypy/bin/pyinteractive.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/bin/pyinteractive.py .. _`pypy/config/`: https://bitbucket.org/pypy/pypy/src/default/pypy/config/ .. _`pypy/config/pypyoption.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/config/pypyoption.py -.. _`pypy/config/translationoption.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/config/translationoption.py .. _`pypy/doc/`: https://bitbucket.org/pypy/pypy/src/default/pypy/doc/ .. _`pypy/doc/config/`: https://bitbucket.org/pypy/pypy/src/default/pypy/doc/config/ .. _`pypy/doc/discussion/`: https://bitbucket.org/pypy/pypy/src/default/pypy/doc/discussion/ +.. _`pypy/goal/`: https://bitbucket.org/pypy/pypy/src/default/pypy/goal/ .. _`pypy/interpreter`: .. _`pypy/interpreter/`: https://bitbucket.org/pypy/pypy/src/default/pypy/interpreter/ .. _`pypy/interpreter/argument.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/interpreter/argument.py @@ -54,11 +49,8 @@ .. _`pypy/module`: .. _`pypy/module/`: https://bitbucket.org/pypy/pypy/src/default/pypy/module/ .. _`pypy/module/__builtin__/__init__.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/module/__builtin__/__init__.py -.. _`pypy/objspace`: .. _`pypy/objspace/`: https://bitbucket.org/pypy/pypy/src/default/pypy/objspace/ -.. _`pypy/objspace/flow`: .. _`pypy/objspace/flow/`: https://bitbucket.org/pypy/pypy/src/default/pypy/objspace/flow/ -.. _`pypy/objspace/flow/model.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/objspace/flow/model.py .. _`pypy/objspace/std`: .. _`pypy/objspace/std/`: https://bitbucket.org/pypy/pypy/src/default/pypy/objspace/std/ .. _`pypy/objspace/std/listtype.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/objspace/std/listtype.py @@ -70,49 +62,55 @@ .. _`pypy/objspace/std/transparent.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/objspace/std/transparent.py .. _`pypy/objspace/std/tupleobject.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/objspace/std/tupleobject.py .. _`pypy/objspace/std/tupletype.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/objspace/std/tupletype.py -.. _`pypy/rlib`: -.. _`pypy/rlib/`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/ -.. _`pypy/rlib/listsort.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/listsort.py -.. _`pypy/rlib/nonconst.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/nonconst.py -.. _`pypy/rlib/objectmodel.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/objectmodel.py -.. _`pypy/rlib/parsing/`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/parsing/ -.. _`pypy/rlib/parsing/tree.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/parsing/tree.py -.. _`pypy/rlib/rarithmetic.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/rarithmetic.py -.. _`pypy/rlib/rbigint.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/rbigint.py -.. _`pypy/rlib/rrandom.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/rrandom.py -.. _`pypy/rlib/rsocket.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/rsocket.py -.. _`pypy/rlib/streamio.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/streamio.py -.. _`pypy/rlib/test`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/test/ -.. _`pypy/rlib/unroll.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/unroll.py -.. _`pypy/rpython`: -.. _`pypy/rpython/`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/ -.. _`pypy/rpython/lltypesystem/`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/lltypesystem/ -.. _`pypy/rpython/lltypesystem/lltype.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/lltypesystem/lltype.py -.. _`pypy/rpython/memory/`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/memory/ -.. _`pypy/rpython/memory/gc/generation.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/memory/gc/generation.py -.. _`pypy/rpython/memory/gc/hybrid.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/memory/gc/hybrid.py -.. _`pypy/rpython/memory/gc/markcompact.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/memory/gc/markcompact.py -.. _`pypy/rpython/memory/gc/marksweep.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/memory/gc/marksweep.py -.. _`pypy/rpython/memory/gc/minimarkpage.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/memory/gc/minimarkpage.py -.. _`pypy/rpython/memory/gc/semispace.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/memory/gc/semispace.py -.. _`pypy/rpython/ootypesystem/`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/ootypesystem/ -.. _`pypy/rpython/ootypesystem/ootype.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/ootypesystem/ootype.py -.. _`pypy/rpython/rint.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/rint.py -.. _`pypy/rpython/rlist.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/rlist.py -.. _`pypy/rpython/rmodel.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/rmodel.py -.. _`pypy/rpython/rtyper.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/rtyper.py -.. _`pypy/rpython/test/test_llinterp.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/test/test_llinterp.py .. _`pypy/tool/`: https://bitbucket.org/pypy/pypy/src/default/pypy/tool/ .. _`pypy/tool/algo/`: https://bitbucket.org/pypy/pypy/src/default/pypy/tool/algo/ .. _`pypy/tool/pytest/`: https://bitbucket.org/pypy/pypy/src/default/pypy/tool/pytest/ -.. _`pypy/tool/traceconfig.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/tool/traceconfig.py -.. _`pypy/translator`: -.. _`pypy/translator/`: https://bitbucket.org/pypy/pypy/src/default/pypy/translator/ -.. _`pypy/translator/backendopt/`: https://bitbucket.org/pypy/pypy/src/default/pypy/translator/backendopt/ -.. _`pypy/translator/c/`: https://bitbucket.org/pypy/pypy/src/default/pypy/translator/c/ -.. _`pypy/translator/c/src/stacklet/`: https://bitbucket.org/pypy/pypy/src/default/pypy/translator/c/src/stacklet/ -.. _`pypy/translator/c/src/stacklet/stacklet.h`: https://bitbucket.org/pypy/pypy/src/default/pypy/translator/c/src/stacklet/stacklet.h -.. _`pypy/translator/cli/`: https://bitbucket.org/pypy/pypy/src/default/pypy/translator/cli/ -.. _`pypy/translator/goal/`: https://bitbucket.org/pypy/pypy/src/default/pypy/translator/goal/ -.. _`pypy/translator/jvm/`: https://bitbucket.org/pypy/pypy/src/default/pypy/translator/jvm/ -.. _`pypy/translator/tool/`: https://bitbucket.org/pypy/pypy/src/default/pypy/translator/tool/ +.. _`rpython/annotator`: +.. _`rpython/annotator/`: https://bitbucket.org/pypy/pypy/src/default/rpython/annotator/ +.. _`rpython/annotator/annrpython.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/annotator/annrpython.py +.. _`rpython/annotator/binaryop.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/annotator/binaryop.py +.. _`rpython/annotator/builtin.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/annotator/builtin.py +.. _`rpython/bin/translatorshell.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/bin/translatorshell.py +.. _`rpython/config/`: https://bitbucket.org/pypy/pypy/src/default/rpython/config/ +.. _`rpython/config/translationoption.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/config/translationoption.py +.. _`rpython/flowspace/`: https://bitbucket.org/pypy/pypy/src/default/rpython/flowspace/ +.. _`rpython/flowspace/model.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/flowspace/model.py +.. _`rpython/rlib`: +.. _`rpython/rlib/`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/ +.. _`rpython/rlib/listsort.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/listsort.py +.. _`rpython/rlib/nonconst.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/nonconst.py +.. _`rpython/rlib/objectmodel.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/objectmodel.py +.. _`rpython/rlib/parsing/`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/parsing/ +.. _`rpython/rlib/parsing/tree.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/parsing/tree.py +.. _`rpython/rlib/rarithmetic.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/rarithmetic.py +.. _`rpython/rlib/rbigint.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/rbigint.py +.. _`rpython/rlib/rrandom.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/rrandom.py +.. _`rpython/rlib/rsocket.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/rsocket.py +.. _`rpython/rlib/streamio.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/streamio.py +.. _`rpython/rlib/test`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/test/ +.. _`rpython/rlib/unroll.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/unroll.py +.. _`rpython/rtyper`: +.. _`rpython/rtyper/`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/ +.. _`rpython/rtyper/lltypesystem/`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/lltypesystem/ +.. _`rpython/rtyper/lltypesystem/lltype.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/lltypesystem/lltype.py +.. _`rpython/rtyper/memory/`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/memory/ +.. _`rpython/rtyper/memory/gc/generation.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/memory/gc/generation.py +.. _`rpython/rtyper/memory/gc/hybrid.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/memory/gc/hybrid.py +.. _`rpython/rtyper/memory/gc/minimarkpage.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/memory/gc/minimarkpage.py +.. _`rpython/rtyper/memory/gc/semispace.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/memory/gc/semispace.py +.. _`rpython/rtyper/ootypesystem/`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/ootypesystem/ +.. _`rpython/rtyper/ootypesystem/ootype.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/ootypesystem/ootype.py +.. _`rpython/rtyper/rint.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/rint.py +.. _`rpython/rtyper/rlist.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/rlist.py +.. _`rpython/rtyper/rmodel.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/rmodel.py +.. _`rpython/rtyper/rtyper.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/rtyper.py +.. _`rpython/rtyper/test/test_llinterp.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/test/test_llinterp.py +.. _`rpython/translator`: +.. _`rpython/translator/`: https://bitbucket.org/pypy/pypy/src/default/rpython/translator/ +.. _`rpython/translator/backendopt/`: https://bitbucket.org/pypy/pypy/src/default/rpython/translator/backendopt/ +.. _`rpython/translator/c/`: https://bitbucket.org/pypy/pypy/src/default/rpython/translator/c/ +.. _`rpython/translator/c/src/stacklet/`: https://bitbucket.org/pypy/pypy/src/default/rpython/translator/c/src/stacklet/ +.. _`rpython/translator/c/src/stacklet/stacklet.h`: https://bitbucket.org/pypy/pypy/src/default/rpython/translator/c/src/stacklet/stacklet.h +.. _`rpython/translator/cli/`: https://bitbucket.org/pypy/pypy/src/default/rpython/translator/cli/ +.. _`rpython/translator/jvm/`: https://bitbucket.org/pypy/pypy/src/default/rpython/translator/jvm/ +.. _`rpython/translator/tool/`: https://bitbucket.org/pypy/pypy/src/default/rpython/translator/tool/ diff --git a/pypy/doc/coding-guide.rst b/pypy/doc/coding-guide.rst --- a/pypy/doc/coding-guide.rst +++ b/pypy/doc/coding-guide.rst @@ -328,7 +328,7 @@ **builtin functions** A number of builtin functions can be used. The precise set can be - found in `pypy/annotation/builtin.py`_ (see ``def builtin_xxx()``). + found in `rpython/annotator/builtin.py`_ (see ``def builtin_xxx()``). Some builtin functions may be limited in what they support, though. ``int, float, str, ord, chr``... are available as simple conversion diff --git a/pypy/doc/configuration.rst b/pypy/doc/configuration.rst --- a/pypy/doc/configuration.rst +++ b/pypy/doc/configuration.rst @@ -188,7 +188,7 @@ toolchain`_ toolchain, have two separate sets of options. The translation toolchain options can be found on the ``config`` attribute of all ``TranslationContext`` -instances and are described in `pypy/config/translationoption.py`_. The interpreter options +instances and are described in `rpython/config/translationoption.py`_. The interpreter options are attached to the object space, also under the name ``config`` and are described in `pypy/config/pypyoption.py`_. diff --git a/pypy/doc/ctypes-implementation.rst b/pypy/doc/ctypes-implementation.rst --- a/pypy/doc/ctypes-implementation.rst +++ b/pypy/doc/ctypes-implementation.rst @@ -38,7 +38,7 @@ in dynamic libraries through libffi. Freeing objects in most cases and making sure that objects referring to each other are kept alive is responsibility of the higher levels. -This module uses bindings to libffi which are defined in ``pypy/rlib/libffi.py``. +This module uses bindings to libffi which are defined in ``rpython/rlib/libffi.py``. We tried to keep this module as small as possible. It is conceivable that other implementations (e.g. Jython) could use our ctypes diff --git a/pypy/doc/discussion/improve-rpython.rst b/pypy/doc/discussion/improve-rpython.rst --- a/pypy/doc/discussion/improve-rpython.rst +++ b/pypy/doc/discussion/improve-rpython.rst @@ -39,7 +39,7 @@ - Allocate variables on the stack, and pass their address ("by reference") to llexternal functions. For a typical usage, see - `pypy.rlib.rsocket.RSocket.getsockopt_int`. + `rpython.rlib.rsocket.RSocket.getsockopt_int`. Extensible type system for llexternal ------------------------------------- diff --git a/pypy/doc/garbage_collection.rst b/pypy/doc/garbage_collection.rst --- a/pypy/doc/garbage_collection.rst +++ b/pypy/doc/garbage_collection.rst @@ -42,7 +42,7 @@ Two arenas of equal size, with only one arena in use and getting filled with new objects. When the arena is full, the live objects are copied into the other arena using Cheney's algorithm. The old arena is then -cleared. See `pypy/rpython/memory/gc/semispace.py`_. +cleared. See `rpython/rtyper/memory/gc/semispace.py`_. On Unix the clearing is done by reading ``/dev/zero`` into the arena, which is extremely memory efficient at least on Linux: it lets the @@ -55,7 +55,7 @@ Generational GC --------------- -This is a two-generations GC. See `pypy/rpython/memory/gc/generation.py`_. +This is a two-generations GC. See `rpython/rtyper/memory/gc/generation.py`_. It is implemented as a subclass of the Semispace copying collector. It adds a nursery, which is a chunk of the current semispace. Its size is @@ -86,7 +86,7 @@ Each generation is collected much less often than the previous one. The division of the generations is slightly more complicated than just nursery / semispace / external; see the diagram at the start of the -source code, in `pypy/rpython/memory/gc/hybrid.py`_. +source code, in `rpython/rtyper/memory/gc/hybrid.py`_. Mark & Compact GC ----------------- @@ -161,7 +161,7 @@ to the old stage. The dying case 2 objects are immediately freed. - The old stage is an area of memory containing old (small) objects. It - is handled by `pypy/rpython/memory/gc/minimarkpage.py`_. It is organized + is handled by `rpython/rtyper/memory/gc/minimarkpage.py`_. It is organized as "arenas" of 256KB or 512KB, subdivided into "pages" of 4KB or 8KB. Each page can either be free, or contain small objects of all the same size. Furthermore at any point in time each object location can be diff --git a/pypy/doc/getting-started-dev.rst b/pypy/doc/getting-started-dev.rst --- a/pypy/doc/getting-started-dev.rst +++ b/pypy/doc/getting-started-dev.rst @@ -172,23 +172,23 @@ ``xxxobject.py`` contain respectively the definition of the type and its (default) implementation. -* `pypy/translator`_ contains the code analysis and generation stuff. +* `rpython/translator`_ contains the code analysis and generation stuff. Start reading from translator.py, from which it should be easy to follow the pieces of code involved in the various translation phases. -* `pypy/annotation`_ contains the data model for the type annotation that +* `rpython/annotator`_ contains the data model for the type annotation that can be inferred about a graph. The graph "walker" that uses this is in - `pypy/annotation/annrpython.py`_. + `rpython/annotator/annrpython.py`_. -* `pypy/rpython`_ contains the code of the RPython typer. The typer transforms +* `rpython/rtyper`_ contains the code of the RPython typer. The typer transforms annotated flow graphs in a way that makes them very similar to C code so that they can be easy translated. The graph transformations are controlled - by the code in `pypy/rpython/rtyper.py`_. The object model that is used can - be found in `pypy/rpython/lltypesystem/lltype.py`_. For each RPython type + by the code in `rpython/rtyper/rtyper.py`_. The object model that is used can + be found in `rpython/rtyper/lltypesystem/lltype.py`_. For each RPython type there is a file rxxxx.py that contains the low level functions needed for this type. -* `pypy/rlib`_ contains the `RPython standard library`_, things that you can +* `rpython/rlib`_ contains the `RPython standard library`_, things that you can use from rpython. .. _`RPython standard library`: rlib.html @@ -319,10 +319,10 @@ Demos ------- -The `demo/`_ directory contains examples of various aspects of PyPy, -ranging from running regular Python programs (that we used as compliance goals) -over experimental distribution mechanisms to examples translating -sufficiently static programs into low level code. +The `example-interpreter`_ repository contains an example interpreter +written using the RPython translation toolchain. + +.. _`example-interpreter`: https://bitbucket.org/pypy/example-interpreter Additional Tools for running (and hacking) PyPy ----------------------------------------------- diff --git a/pypy/doc/index.rst b/pypy/doc/index.rst --- a/pypy/doc/index.rst +++ b/pypy/doc/index.rst @@ -217,17 +217,20 @@ Here is a fully referenced alphabetical two-level deep directory overview of PyPy: -================================ =========================================== +================================= ============================================ Directory explanation/links -================================ =========================================== +================================= ============================================ +`pypy/bin/`_ command-line scripts, mainly + `pypy/bin/pyinteractive.py`_ -`pypy/bin/`_ command-line scripts, mainly `pyinteractive.py`_ +`pypy/config/`_ handles the numerous options for building + and running PyPy -`pypy/config/`_ handles the numerous options for building and running PyPy +`pypy/doc/`_ text versions of PyPy developer + documentation -`pypy/doc/`_ text versions of PyPy developer documentation - -`pypy/doc/config/`_ documentation for the numerous translation options +`pypy/doc/config/`_ documentation for the numerous translation + options `pypy/doc/discussion/`_ drafts of ideas and documentation @@ -238,19 +241,24 @@ `pypy/interpreter/pyparser/`_ interpreter-level Python source parser -`pypy/interpreter/astcompiler/`_ interpreter-level bytecode compiler, via an AST - representation +`pypy/interpreter/astcompiler/`_ interpreter-level bytecode compiler, + via an AST representation -`pypy/module/`_ contains `mixed modules`_ implementing core modules with +`pypy/module/`_ contains `mixed modules`_ + implementing core modules with both application and interpreter level code. - Not all are finished and working. Use the ``--withmod-xxx`` - or ``--allworkingmodules`` translation options. + Not all are finished and working. Use + the ``--withmod-xxx`` + or ``--allworkingmodules`` translation + options. `pypy/objspace/`_ `object space`_ implementations -`pypy/objspace/std/`_ the StdObjSpace_ implementing CPython's objects and types +`pypy/objspace/std/`_ the StdObjSpace_ implementing CPython's + objects and types -`pypy/tool/`_ various utilities and hacks used from various places +`pypy/tool/`_ various utilities and hacks used + from various places `pypy/tool/algo/`_ general-purpose algorithmic and mathematic tools @@ -258,49 +266,58 @@ `pypy/tool/pytest/`_ support code for our `testing methods`_ -`rpython/annotator/`_ `type inferencing code`_ for `RPython`_ programs +`rpython/annotator/`_ `type inferencing code`_ for + `RPython`_ programs `rpython/config/`_ handles the numerous options for RPython -`rpython/flowspace/`_ the FlowObjSpace_ implementing `abstract interpretation`_ +`rpython/flowspace/`_ the FlowObjSpace_ implementing + `abstract interpretation`_ - -`rpython/rlib/`_ a `"standard library"`_ for RPython_ programs +`rpython/rlib/`_ a `"standard library"`_ for RPython_ + programs `rpython/rtyper/`_ the `RPython Typer`_ -`rpython/rtyper/lltypesystem/`_ the `low-level type system`_ for C-like backends +`rpython/rtyper/lltypesystem/`_ the `low-level type system`_ for + C-like backends -`rpython/rtyper/ootypesystem/`_ the `object-oriented type system`_ for OO backends +`rpython/rtyper/ootypesystem/`_ the `object-oriented type system`_ + for OO backends -`rpython/rtyper/memory/`_ the `garbage collector`_ construction framework +`rpython/rtyper/memory/`_ the `garbage collector`_ construction + framework `rpython/translator/`_ translation_ backends and support code -`rpython/translator/backendopt/`_ general optimizations that run before a backend generates code +`rpython/translator/backendopt/`_ general optimizations that run before a + backend generates code -`rpython/translator/c/`_ the `GenC backend`_, producing C code from an +`rpython/translator/c/`_ the `GenC backend`_, producing C code + from an RPython program (generally via the rtyper_) -`rpython/translator/cli/`_ the `CLI backend`_ for `.NET`_ (Microsoft CLR or Mono_) +`rpython/translator/cli/`_ the `CLI backend`_ for `.NET`_ + (Microsoft CLR or Mono_) -`pypy/goal/`_ our `main PyPy-translation scripts`_ live here +`pypy/goal/`_ our `main PyPy-translation scripts`_ + live here `rpython/translator/jvm/`_ the Java backend -`rpython/translator/tool/`_ helper tools for translation, including the Pygame - `graph viewer`_ +`rpython/translator/tool/`_ helper tools for translation -``*/test/`` many directories have a test subdirectory containing test +`dotviewer/`_ `graph viewer`_ + +``*/test/`` many directories have a test subdirectory + containing test modules (see `Testing in PyPy`_) -``_cache/`` holds cache files from internally `translating application - level to interpreterlevel`_ code. -================================ =========================================== +``_cache/`` holds cache files from various purposes +================================= ============================================ .. _`bytecode interpreter`: interpreter.html -.. _`translating application level to interpreterlevel`: geninterp.html .. _`Testing in PyPy`: coding-guide.html#testing-in-pypy .. _`mixed modules`: coding-guide.html#mixed-modules .. _`modules`: coding-guide.html#modules diff --git a/pypy/doc/rtyper.rst b/pypy/doc/rtyper.rst --- a/pypy/doc/rtyper.rst +++ b/pypy/doc/rtyper.rst @@ -4,7 +4,7 @@ .. contents:: -The RPython Typer lives in the directory `pypy/rpython/`_. +The RPython Typer lives in the directory `rpython/rtyper/`_. Overview @@ -52,7 +52,7 @@ where -- in C notation -- all three variables v1, v2 and v3 are typed ``int``. This is done by attaching an attribute ``concretetype`` to v1, v2 and v3 (which might be instances of Variable or possibly Constant). In our model, -this ``concretetype`` is ``pypy.rpython.lltypesystem.lltype.Signed``. Of +this ``concretetype`` is ``rpython.rtyper.lltypesystem.lltype.Signed``. Of course, the purpose of replacing the operation called ``add`` with ``int_add`` is that code generators no longer have to worry about what kind of addition (or concatenation maybe?) it means. @@ -66,7 +66,7 @@ each operation. In both cases the analysis of an operation depends on the annotations of its input arguments. This is reflected in the usage of the same ``__extend__`` syntax in the source files (compare e.g. -`pypy/annotation/binaryop.py`_ and `pypy/rpython/rint.py`_). +`rpython/annotator/binaryop.py`_ and `rpython/rtyper/rint.py`_). The analogy stops here, though: while it runs, the Annotator is in the middle of computing the annotations, so it might need to reflow and generalize until @@ -104,7 +104,7 @@ implementations for the same high-level operations. This is the reason for turning representations into explicit objects. -The base Repr class is defined in `pypy/rpython/rmodel.py`_. Most of the +The base Repr class is defined in `rpython/rtyper/rmodel.py`_. Most of the ``rpython/r*.py`` files define one or a few subclasses of Repr. The method getrepr() of the RTyper will build and cache a single Repr instance per SomeXxx() instance; moreover, two SomeXxx() instances that are equal get the @@ -131,9 +131,9 @@ The RPython Typer uses a standard low-level model which we believe can correspond rather directly to various target languages such as C. This model is implemented in the first part of -`pypy/rpython/lltypesystem/lltype.py`_. +`rpython/rtyper/lltypesystem/lltype.py`_. -The second part of `pypy/rpython/lltypesystem/lltype.py`_ is a runnable +The second part of `rpython/rtyper/lltypesystem/lltype.py`_ is a runnable implementation of these types, for testing purposes. It allows us to write and test plain Python code using a malloc() function to obtain and manipulate structures and arrays. This is useful for example to implement and test @@ -147,7 +147,7 @@ Here is a quick tour: - >>> from pypy.rpython.lltypesystem.lltype import * + >>> from rpython.rtyper.lltypesystem.lltype import * Here are a few primitive low-level types, and the typeOf() function to figure them out: @@ -191,7 +191,7 @@ types like list in this elementary world. The ``malloc()`` function is a kind of placeholder, which must eventually be provided by the code generator for the target platform; but as we have just seen its Python implementation in -`pypy/rpython/lltypesystem/lltype.py`_ works too, which is primarily useful for +`rpython/rtyper/lltypesystem/lltype.py`_ works too, which is primarily useful for testing, interactive exploring, etc. The argument to ``malloc()`` is the structure type directly, but it returns a @@ -245,7 +245,7 @@ +++++++++++++++ Structure types are built as instances of -``pypy.rpython.lltypesystem.lltype.Struct``:: +``rpython.rtyper.lltypesystem.lltype.Struct``:: MyStructType = Struct('somename', ('field1', Type1), ('field2', Type2)...) MyStructType = GcStruct('somename', ('field1', Type1), ('field2', Type2)...) @@ -277,7 +277,7 @@ +++++++++++ An array type is built as an instance of -``pypy.rpython.lltypesystem.lltype.Array``:: +``rpython.rtyper.lltypesystem.lltype.Array``:: MyIntArray = Array(Signed) MyOtherArray = Array(MyItemType) @@ -316,7 +316,7 @@ with care: the bigger structure of which they are part of could be freed while the Ptr to the substructure is still in use. In general, it is a good idea to avoid passing around pointers to inlined substructures of malloc()ed structures. -(The testing implementation of `pypy/rpython/lltypesystem/lltype.py`_ checks to some +(The testing implementation of `rpython/rtyper/lltypesystem/lltype.py`_ checks to some extent that you are not trying to use a pointer to a structure after its container has been freed, using weak references. But pointers to non-GC structures are not officially meant to be weak references: using them after what @@ -429,7 +429,7 @@ change needed to the Annotator to allow it to perform type inference of our very-low-level snippets of code. -See for example `pypy/rpython/rlist.py`_. +See for example `rpython/rtyper/rlist.py`_. .. _`oo type`: @@ -441,10 +441,10 @@ targeting low level backends such as C, but it is not good enough for targeting higher level backends such as .NET CLI or Java JVM, so a new object oriented model has been introduced. This model is -implemented in the first part of `pypy/rpython/ootypesystem/ootype.py`_. +implemented in the first part of `rpython/rtyper/ootypesystem/ootype.py`_. As for the low-level typesystem, the second part of -`pypy/rpython/ootypesystem/ootype.py`_ is a runnable implementation of +`rpython/rtyper/ootypesystem/ootype.py`_ is a runnable implementation of these types, for testing purposes. @@ -751,7 +751,7 @@ The LLInterpreter is a simple piece of code that is able to interpret flow graphs. This is very useful for testing purposes, especially if you work on the RPython Typer. The most useful interface for it is the ``interpret`` -function in the file `pypy/rpython/test/test_llinterp.py`_. It takes as +function in the file `rpython/rtyper/test/test_llinterp.py`_. It takes as arguments a function and a list of arguments with which the function is supposed to be called. Then it generates the flow graph, annotates it according to the types of the arguments you passed to it and runs the diff --git a/pypy/doc/stackless.rst b/pypy/doc/stackless.rst --- a/pypy/doc/stackless.rst +++ b/pypy/doc/stackless.rst @@ -29,7 +29,7 @@ on 32-bit or a complete megabyte on 64-bit. Moreover, the feature is only available (so far) on x86 and x86-64 CPUs; for other CPUs you need to add a short page of custom assembler to -`pypy/translator/c/src/stacklet/`_. +`rpython/translator/c/src/stacklet/`_. Theory @@ -271,9 +271,9 @@ Continulets are internally implemented using stacklets, which is the generic RPython-level building block for "one-shot continuations". For more information about them please see the documentation in the C source -at `pypy/translator/c/src/stacklet/stacklet.h`_. +at `rpython/translator/c/src/stacklet/stacklet.h`_. -The module ``pypy.rlib.rstacklet`` is a thin wrapper around the above +The module ``rpython.rlib.rstacklet`` is a thin wrapper around the above functions. The key point is that new() and switch() always return a fresh stacklet handle (or an empty one), and switch() additionally consumes one. It makes no sense to have code in which the returned diff --git a/pypy/doc/tool/makeref.py b/pypy/doc/tool/makeref.py --- a/pypy/doc/tool/makeref.py +++ b/pypy/doc/tool/makeref.py @@ -1,10 +1,9 @@ import py -py.path.local(__file__) import pypy -pypydir = py.path.local(pypy.__file__).dirpath() -distdir = pypydir.dirpath() -issue_url = 'http://codespeak.net/issue/pypy-dev/' +pypydir = py.path.local(pypy.__file__).join('..') +distdir = pypydir.dirpath() +issue_url = 'http://bugs.pypy.org/issue/pypy-dev/' bitbucket_url = 'https://bitbucket.org/pypy/pypy/src/default/' import urllib2, posixpath diff --git a/pypy/doc/translation.rst b/pypy/doc/translation.rst --- a/pypy/doc/translation.rst +++ b/pypy/doc/translation.rst @@ -90,7 +90,7 @@ (although these steps are not quite as distinct as you might think from this presentation). -There is an `interactive interface`_ called `pypy/bin/translatorshell.py`_ to the +There is an `interactive interface`_ called `rpython/bin/translatorshell.py`_ to the translation process which allows you to interactively work through these stages. @@ -116,7 +116,7 @@ which are the basic data structures of the translation process. -All these types are defined in `pypy/objspace/flow/model.py`_ (which is a rather +All these types are defined in `rpython/flowspace/model.py`_ (which is a rather important module in the PyPy source base, to reinforce the point). The flow graph of a function is represented by the class ``FunctionGraph``. diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst --- a/pypy/doc/whatsnew-head.rst +++ b/pypy/doc/whatsnew-head.rst @@ -65,3 +65,6 @@ .. branch: signal-and-thread Add "__pypy__.thread.signals_enabled", a context manager. Can be used in a non-main thread to enable the processing of signal handlers in that thread. + +.. branch: coding-guide-update-rlib-refs +.. branch: rlib-doc-rpython-refs diff --git a/pypy/module/_io/interp_bytesio.py b/pypy/module/_io/interp_bytesio.py --- a/pypy/module/_io/interp_bytesio.py +++ b/pypy/module/_io/interp_bytesio.py @@ -52,6 +52,25 @@ self.pos += size return space.wrap(output) + def readline_w(self, space, w_limit=None): + self._check_closed(space) + limit = convert_size(space, w_limit) + + cur_pos = self.pos + if limit < 0: + end_pos = self.string_size + else: + end_pos = min(cur_pos + limit, self.string_size) + while cur_pos != end_pos: + if self.buf[cur_pos] == '\n': + cur_pos += 1 + break + cur_pos += 1 + + output = buffer2string(self.buf, self.pos, cur_pos) + self.pos = cur_pos + return space.wrap(output) + def read1_w(self, space, w_size): return self.read_w(space, w_size) @@ -209,6 +228,7 @@ read = interp2app(W_BytesIO.read_w), read1 = interp2app(W_BytesIO.read1_w), + readline = interp2app(W_BytesIO.readline_w), readinto = interp2app(W_BytesIO.readinto_w), write = interp2app(W_BytesIO.write_w), truncate = interp2app(W_BytesIO.truncate_w), diff --git a/pypy/module/_io/test/test_bytesio.py b/pypy/module/_io/test/test_bytesio.py --- a/pypy/module/_io/test/test_bytesio.py +++ b/pypy/module/_io/test/test_bytesio.py @@ -75,3 +75,19 @@ b = _io.BytesIO("hello") b.close() raises(ValueError, b.readinto, bytearray("hello")) + + def test_readline(self): + import _io + f = _io.BytesIO(b'abc\ndef\nxyzzy\nfoo\x00bar\nanother line') + assert f.readline() == b'abc\n' + assert f.readline(10) == b'def\n' + assert f.readline(2) == b'xy' + assert f.readline(4) == b'zzy\n' + assert f.readline() == b'foo\x00bar\n' + assert f.readline(None) == b'another line' + raises(TypeError, f.readline, 5.3) + + def test_overread(self): + import _io + f = _io.BytesIO(b'abc') + assert f.readline(10) == b'abc' diff --git a/rpython/jit/metainterp/pyjitpl.py b/rpython/jit/metainterp/pyjitpl.py --- a/rpython/jit/metainterp/pyjitpl.py +++ b/rpython/jit/metainterp/pyjitpl.py @@ -1082,7 +1082,7 @@ def opimpl_debug_fatalerror(self, box): from rpython.rtyper.lltypesystem import rstr, lloperation msg = box.getref(lltype.Ptr(rstr.STR)) - lloperation.llop.debug_fatalerror(msg) + lloperation.llop.debug_fatalerror(lltype.Void, msg) @arguments("box", "box", "box", "box", "box") def opimpl_jit_debug(self, stringbox, arg1box, arg2box, arg3box, arg4box): diff --git a/rpython/rlib/objectmodel.py b/rpython/rlib/objectmodel.py --- a/rpython/rlib/objectmodel.py +++ b/rpython/rlib/objectmodel.py @@ -153,7 +153,8 @@ else: return type(arg) def typecheck(*args): - from rpython.annotator.model import SomeList, SomeDict, SomeChar + from rpython.annotator.model import SomeList, SomeDict, SomeChar,\ + SomeInteger for i, (expected_type, arg) in enumerate(zip(types, args)): if expected_type is None: continue @@ -167,6 +168,9 @@ if isinstance(s_expected, SomeChar) and ( isinstance(arg, str) and len(arg) == 1): # a char continue + if (isinstance(s_expected, SomeInteger) and + isinstance(arg, s_expected.knowntype)): + continue # s_argtype = get_annotation(get_type_descr_of_argument(arg)) if not s_expected.contains(s_argtype): diff --git a/rpython/rtyper/lltypesystem/rdict.py b/rpython/rtyper/lltypesystem/rdict.py --- a/rpython/rtyper/lltypesystem/rdict.py +++ b/rpython/rtyper/lltypesystem/rdict.py @@ -8,6 +8,7 @@ from rpython.rlib.rarithmetic import r_uint, intmask, LONG_BIT from rpython.rtyper import rmodel from rpython.rtyper.error import TyperError +from rpython.annotator.model import SomeInteger HIGHEST_BIT = intmask(1 << (LONG_BIT - 1)) @@ -385,48 +386,60 @@ # be direct_call'ed from rtyped flow graphs, which means that they will # get flowed and annotated, mostly with SomePtr. + at objectmodel.enforceargs(None, SomeInteger(nonneg=True)) def ll_everused_from_flag(entries, i): return entries[i].f_everused + at objectmodel.enforceargs(None, SomeInteger(nonneg=True)) def ll_everused_from_key(entries, i): return bool(entries[i].key) + at objectmodel.enforceargs(None, SomeInteger(nonneg=True)) def ll_everused_from_value(entries, i): return bool(entries[i].value) + at objectmodel.enforceargs(None, SomeInteger(nonneg=True)) def ll_valid_from_flag(entries, i): return entries[i].f_valid + at objectmodel.enforceargs(None, SomeInteger(nonneg=True)) def ll_mark_deleted_in_flag(entries, i): entries[i].f_valid = False + at objectmodel.enforceargs(None, SomeInteger(nonneg=True)) def ll_valid_from_key(entries, i): ENTRIES = lltype.typeOf(entries).TO dummy = ENTRIES.dummy_obj.ll_dummy_value return entries.everused(i) and entries[i].key != dummy + at objectmodel.enforceargs(None, SomeInteger(nonneg=True)) def ll_mark_deleted_in_key(entries, i): ENTRIES = lltype.typeOf(entries).TO dummy = ENTRIES.dummy_obj.ll_dummy_value entries[i].key = dummy + at objectmodel.enforceargs(None, SomeInteger(nonneg=True)) def ll_valid_from_value(entries, i): ENTRIES = lltype.typeOf(entries).TO dummy = ENTRIES.dummy_obj.ll_dummy_value return entries.everused(i) and entries[i].value != dummy + at objectmodel.enforceargs(None, int) def ll_mark_deleted_in_value(entries, i): ENTRIES = lltype.typeOf(entries).TO dummy = ENTRIES.dummy_obj.ll_dummy_value entries[i].value = dummy + at objectmodel.enforceargs(None, int) def ll_hash_from_cache(entries, i): return entries[i].f_hash + at objectmodel.enforceargs(None, int) def ll_hash_recomputed(entries, i): ENTRIES = lltype.typeOf(entries).TO return ENTRIES.fasthashfn(entries[i].key) + at objectmodel.enforceargs(None, int) def ll_get_value(d, i): return d.entries[i].value @@ -513,6 +526,7 @@ @jit.look_inside_iff(lambda d, i: jit.isvirtual(d) and jit.isconstant(i)) def _ll_dict_del(d, i): + assert i >= 0 d.entries.mark_deleted(i) d.num_items -= 1 # clear the key and the value if they are GC pointers @@ -573,6 +587,7 @@ direct_compare = not hasattr(ENTRIES, 'no_direct_compare') mask = len(entries) - 1 i = hash & mask + assert i >= 0 # do the first try before any looping if entries.valid(i): checkingkey = entries[i].key @@ -603,6 +618,7 @@ i = r_uint(i) i = (i << 2) + i + perturb + 1 i = intmask(i) & mask + assert i >= 0 # keep 'i' as a signed number here, to consistently pass signed # arguments to the small helper methods. if not entries.everused(i): @@ -636,11 +652,13 @@ entries = d.entries mask = len(entries) - 1 i = hash & mask + assert i >= 0 perturb = r_uint(hash) while entries.everused(i): i = r_uint(i) i = (i << 2) + i + perturb + 1 i = intmask(i) & mask + assert i >= 0 perturb >>= PERTURB_SHIFT return i @@ -733,6 +751,7 @@ if dict: entries = dict.entries index = iter.index + assert index >= 0 entries_len = len(entries) while index < entries_len: entry = entries[index] diff --git a/rpython/rtyper/lltypesystem/rlist.py b/rpython/rtyper/lltypesystem/rlist.py --- a/rpython/rtyper/lltypesystem/rlist.py +++ b/rpython/rtyper/lltypesystem/rlist.py @@ -419,6 +419,7 @@ def __init__(self, r_list): self.r_list = r_list + self.external_item_repr = r_list.external_item_repr self.lowleveltype = Ptr(GcStruct('listiter', ('list', r_list.lowleveltype), ('index', Signed))) diff --git a/rpython/rtyper/lltypesystem/rstr.py b/rpython/rtyper/lltypesystem/rstr.py --- a/rpython/rtyper/lltypesystem/rstr.py +++ b/rpython/rtyper/lltypesystem/rstr.py @@ -1054,15 +1054,18 @@ def __init__(self): self.ll_striter = ll_striter self.ll_strnext = ll_strnext + self.ll_getnextindex = ll_getnextindex class StringIteratorRepr(BaseStringIteratorRepr): + external_item_repr = char_repr lowleveltype = Ptr(GcStruct('stringiter', ('string', string_repr.lowleveltype), ('index', Signed))) class UnicodeIteratorRepr(BaseStringIteratorRepr): + external_item_repr = unichar_repr lowleveltype = Ptr(GcStruct('unicodeiter', ('string', unicode_repr.lowleveltype), ('index', Signed))) @@ -1087,6 +1090,9 @@ iter.index = index + 1 return chars[index] +def ll_getnextindex(iter): + return iter.index + string_repr.iterator_repr = StringIteratorRepr() unicode_repr.iterator_repr = UnicodeIteratorRepr() diff --git a/rpython/rtyper/ootypesystem/rstr.py b/rpython/rtyper/ootypesystem/rstr.py --- a/rpython/rtyper/ootypesystem/rstr.py +++ b/rpython/rtyper/ootypesystem/rstr.py @@ -428,14 +428,17 @@ class StringIteratorRepr(AbstractStringIteratorRepr): + external_item_repr = char_repr lowleveltype = ootype.Record({'string': string_repr.lowleveltype, 'index': ootype.Signed}) def __init__(self): self.ll_striter = ll_striter self.ll_strnext = ll_strnext + self.ll_getnextindex = ll_getnextindex class UnicodeIteratorRepr(AbstractStringIteratorRepr): + external_item_repr = unichar_repr lowleveltype = ootype.Record({'string': unicode_repr.lowleveltype, 'index': ootype.Signed}) @@ -463,6 +466,9 @@ iter.index = index + 1 return string.ll_stritem_nonneg(index) +def ll_getnextindex(iter): + return iter.index + StringRepr.string_iterator_repr = StringIteratorRepr() UnicodeRepr.string_iterator_repr = UnicodeIteratorRepr() diff --git a/rpython/rtyper/rclass.py b/rpython/rtyper/rclass.py --- a/rpython/rtyper/rclass.py +++ b/rpython/rtyper/rclass.py @@ -395,7 +395,7 @@ assert not s_attr.is_constant() if '__iter__' in self.allinstancefields: raise Exception("__iter__ on instance disallowed") - r_method = self.rtyper.makerepr(s_attr) + r_method = self.rtyper.getrepr(s_attr) r_method.get_method_from_instance(self, vinst, hop.llops) hop2 = hop.copy() hop2.spaceop.opname = 'simple_call' diff --git a/rpython/rtyper/rptr.py b/rpython/rtyper/rptr.py --- a/rpython/rtyper/rptr.py +++ b/rpython/rtyper/rptr.py @@ -347,3 +347,10 @@ if r_from.lowleveltype == r_to.lowleveltype: return v return NotImplemented + +class __extend__(pairtype(InteriorPtrRepr, InteriorPtrRepr)): + + def convert_from_to((r_from, r_to), v, llops): + if r_from.__dict__ == r_to.__dict__: + return v + return NotImplemented diff --git a/rpython/rtyper/rrange.py b/rpython/rtyper/rrange.py --- a/rpython/rtyper/rrange.py +++ b/rpython/rtyper/rrange.py @@ -207,7 +207,7 @@ v_index = hop.gendirectcall(self.ll_getnextindex, v_enumerate) hop2 = hop.copy() hop2.args_r = [self.r_baseiter] - r_item_src = self.r_baseiter.r_list.external_item_repr + r_item_src = self.r_baseiter.external_item_repr r_item_dst = hop.r_result.items_r[1] v_item = self.r_baseiter.rtype_next(hop2) v_item = hop.llops.convertvar(v_item, r_item_src, r_item_dst) diff --git a/rpython/rtyper/test/test_rstr.py b/rpython/rtyper/test/test_rstr.py --- a/rpython/rtyper/test/test_rstr.py +++ b/rpython/rtyper/test/test_rstr.py @@ -1035,6 +1035,17 @@ got = self.interpret(f, [7]) assert self.ll_to_string(got) == 'None' + def test_enumerate(self): + const = self.const + def fn(n): + s = const('abcde') + for i, x in enumerate(s): + if i == n: + return x + return 'x' + res = self.interpret(fn, [2]) + assert res == 'c' + def FIXME_test_str_to_pystringobj(): def f(n): diff --git a/rpython/translator/c/src/mem.h b/rpython/translator/c/src/mem.h --- a/rpython/translator/c/src/mem.h +++ b/rpython/translator/c/src/mem.h @@ -4,7 +4,7 @@ #include -/* used by pypy.rlib.rstack, but also by asmgcc */ +/* used by rpython.rlib.rstack, but also by asmgcc */ #define OP_STACK_CURRENT(r) r = (Signed)&r diff --git a/rpython/translator/c/src/stack.h b/rpython/translator/c/src/stack.h --- a/rpython/translator/c/src/stack.h +++ b/rpython/translator/c/src/stack.h @@ -18,7 +18,7 @@ char LL_stack_too_big_slowpath(long); /* returns 0 (ok) or 1 (too big) */ void LL_stack_set_length_fraction(double); -/* some macros referenced from pypy.rlib.rstack */ +/* some macros referenced from rpython.rlib.rstack */ #define LL_stack_get_end() ((long)_LLstacktoobig_stack_end) #define LL_stack_get_length() _LLstacktoobig_stack_length #define LL_stack_get_end_adr() ((long)&_LLstacktoobig_stack_end) /* JIT */ From noreply at buildbot.pypy.org Fri Feb 22 11:51:43 2013 From: noreply at buildbot.pypy.org (cfbolz) Date: Fri, 22 Feb 2013 11:51:43 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: (cfbolz, lwassermann around): stop using unwrapped strings as values and just Message-ID: <20130222105143.ABBC31C01BF@cobra.cs.uni-duesseldorf.de> Author: Carl Friedrich Bolz Branch: Changeset: r84:235293a3b353 Date: 2013-02-21 15:44 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/235293a3b353/ Log: (cfbolz, lwassermann around): stop using unwrapped strings as values and just compare them by identity, which Squeak guarantees to be unique. this actually makes the behaviour more correct, because now doing nasty stuff like manually changing the symbol won't break method dicts. diff --git a/spyvm/constants.py b/spyvm/constants.py --- a/spyvm/constants.py +++ b/spyvm/constants.py @@ -62,7 +62,7 @@ SO_SMALLINTEGER_CLASS = 5 SO_STRING_CLASS = 6 SO_ARRAY_CLASS = 7 -SO_SMALLTALK = 8 # Deperacted +SO_SMALLTALK = 8 # Deprecated SO_FLOAT_CLASS = 9 SO_METHODCONTEXT_CLASS = 10 SO_BLOCKCONTEXT_CLASS = 11 @@ -128,9 +128,25 @@ "false": SO_FALSE, "charactertable": SO_CHARACTER_TABLE_ARRAY, "schedulerassociationpointer" : SO_SCHEDULERASSOCIATIONPOINTER, + "special_selectors": SO_SPECIAL_SELECTORS_ARRAY, "smalltalkdict" : SO_SMALLTALK, } LONG_BIT = 32 TAGGED_MAXINT = 2 ** (LONG_BIT - 2) - 1 TAGGED_MININT = -2 ** (LONG_BIT - 2) + + +# Entries into SO_SPECIAL_SELECTORS_ARRAY: +#(#+ 1 #- 1 #< 1 #> 1 #<= 1 #>= 1 #= 1 #~= 1 #* 1 #/ 1 #\\ 1 #@ 1 #bitShift: 1 #// 1 #bitAnd: 1 #bitOr: 1 #at: 1 #at:put: 2 #size 0 #next 0 #nextPut: 1 #atEnd 0 #== 1 #class 0 #blockCopy: 1 #value 0 #value: 1 #do: 1 #new 0 #new: 1 #x 0 #y 0) + + +SPECIAL_SELECTORS = ['+', '-', '<', '>', '<=', '>=', '=', '~=', '*', '/', '\\\\', + '@', 'bitShift:', '//', 'bitAnd:', 'bitOr:', 'at:', + 'at:put:', 'size', 'next', 'nextPut:', 'atEnd', '==', + 'class', 'blockCopy:', 'value', 'value:', 'do:', 'new', + 'new:', 'x', 'y'] + +def find_selectorindex(selector): + return SPECIAL_SELECTORS.index(selector) * 2 +find_selectorindex._annspecialcase_ = "specialize:memo" diff --git a/spyvm/interpreter.py b/spyvm/interpreter.py --- a/spyvm/interpreter.py +++ b/spyvm/interpreter.py @@ -115,13 +115,14 @@ # else that the user put in a class in an 'at:' method. # The rule of thumb is that primitives with only int and float # in their unwrap_spec are safe. + # XXX move next line out of callPrimitive? func = primitives.prim_table[primitive] try: func(interp, argcount) return except primitives.PrimitiveFailedError: pass - self._sendSelfSelector(selector, argcount, interp) + self._sendSelfSelectorSpecial(selector, argcount, interp) return callPrimitive # ___________________________________________________________________________ @@ -194,31 +195,31 @@ # send, return bytecodes def sendLiteralSelectorBytecode(self, interp): - selector = self.method().getliteralsymbol(self.currentBytecode & 15) + w_selector = self.method().getliteral(self.currentBytecode & 15) argcount = ((self.currentBytecode >> 4) & 3) - 1 - self._sendSelfSelector(selector, argcount, interp) + self._sendSelfSelector(w_selector, argcount, interp) - def _sendSelfSelector(self, selector, argcount, interp): + def _sendSelfSelector(self, w_selector, argcount, interp): receiver = self.peek(argcount) - self._sendSelector(selector, argcount, interp, + self._sendSelector(w_selector, argcount, interp, receiver, receiver.shadow_of_my_class(self.space)) - def _sendSuperSelector(self, selector, argcount, interp): + def _sendSuperSelector(self, w_selector, argcount, interp): w_compiledin = self.method().w_compiledin assert isinstance(w_compiledin, model.W_PointersObject) s_compiledin = w_compiledin.as_class_get_shadow(self.space) - self._sendSelector(selector, argcount, interp, self.w_receiver(), + self._sendSelector(w_selector, argcount, interp, self.w_receiver(), s_compiledin.s_superclass()) - def _sendSelector(self, selector, argcount, interp, + def _sendSelector(self, w_selector, argcount, interp, receiver, receiverclassshadow): if interp.should_trace(): print "%sSending selector %r to %r with: %r" % ( - interp._last_indent, selector, receiver, + interp._last_indent, w_selector.as_string(), receiver, [self.peek(argcount-1-i) for i in range(argcount)]) pass assert argcount >= 0 - method = receiverclassshadow.lookup(selector) + method = receiverclassshadow.lookup(w_selector) # XXX catch MethodNotFound here and send doesNotUnderstand: # AK shouln't that be done in lookup itself, please check what spec says about DNU in case of super sends. if method.primitive: @@ -242,7 +243,7 @@ return except primitives.PrimitiveFailedError: if interp.should_trace(True): - print "PRIMITIVE FAILED: %d %s" % (method.primitive, selector,) + print "PRIMITIVE FAILED: %d %s" % (method.primitive, w_selector.as_string(),) pass # ignore this error and fall back to the Smalltalk version arguments = self.pop_and_return_n(argcount) frame = method.create_frame(self.space, receiver, arguments, @@ -317,12 +318,12 @@ def getExtendedSelectorArgcount(self): descriptor = self.getbytecode() - return ((self.method().getliteralsymbol(descriptor & 31)), + return ((self.method().getliteral(descriptor & 31)), (descriptor >> 5)) def singleExtendedSendBytecode(self, interp): - selector, argcount = self.getExtendedSelectorArgcount() - self._sendSelfSelector(selector, argcount, interp) + w_selector, argcount = self.getExtendedSelectorArgcount() + self._sendSelfSelector(w_selector, argcount, interp) def doubleExtendedDoAnythingBytecode(self, interp): second = self.getbytecode() @@ -330,11 +331,11 @@ opType = second >> 5 if opType == 0: # selfsend - self._sendSelfSelector(self.method().getliteralsymbol(third), + self._sendSelfSelector(self.method().getliteral(third), second & 31, interp) elif opType == 1: # supersend - self._sendSuperSelector(self.method().getliteralsymbol(third), + self._sendSuperSelector(self.method().getliteral(third), second & 31, interp) elif opType == 2: # pushReceiver @@ -357,14 +358,14 @@ association.store_value(self.top()) def singleExtendedSuperBytecode(self, interp): - selector, argcount = self.getExtendedSelectorArgcount() - self._sendSuperSelector(selector, argcount, interp) + w_selector, argcount = self.getExtendedSelectorArgcount() + self._sendSuperSelector(w_selector, argcount, interp) def secondExtendedSendBytecode(self, interp): descriptor = self.getbytecode() - selector = self.method().getliteralsymbol(descriptor & 63) + w_selector = self.method().getliteral(descriptor & 63) argcount = descriptor >> 6 - self._sendSelfSelector(selector, argcount, interp) + self._sendSelfSelector(w_selector, argcount, interp) def popStackBytecode(self, interp): self.pop() @@ -479,27 +480,32 @@ bytecodePrimBitAnd = make_call_primitive_bytecode(primitives.BIT_AND, "bitAnd:", 1) bytecodePrimBitOr = make_call_primitive_bytecode(primitives.BIT_OR, "bitOr:", 1) + @objectmodel.specialize.arg(1) + def _sendSelfSelectorSpecial(self, selector, numargs, interp): + w_selector = self.space.get_special_selector(selector) + return self._sendSelfSelector(w_selector, numargs, interp) + def bytecodePrimAt(self, interp): # n.b.: depending on the type of the receiver, this may invoke # primitives.AT, primitives.STRING_AT, or something else for all - # I know. - self._sendSelfSelector("at:", 1, interp) + # I know. + self._sendSelfSelectorSpecial("at:", 1, interp) def bytecodePrimAtPut(self, interp): # n.b. as above - self._sendSelfSelector("at:put:", 2, interp) + self._sendSelfSelectorSpecial("at:put:", 2, interp) def bytecodePrimSize(self, interp): - self._sendSelfSelector("size", 0, interp) + self._sendSelfSelectorSpecial("size", 0, interp) def bytecodePrimNext(self, interp): - self._sendSelfSelector("next", 0, interp) + self._sendSelfSelectorSpecial("next", 0, interp) def bytecodePrimNextPut(self, interp): - self._sendSelfSelector("nextPut:", 1, interp) + self._sendSelfSelectorSpecial("nextPut:", 1, interp) def bytecodePrimAtEnd(self, interp): - self._sendSelfSelector("atEnd", 0, interp) + self._sendSelfSelectorSpecial("atEnd", 0, interp) def bytecodePrimEquivalent(self, interp): # short-circuit: classes cannot override the '==' method, @@ -517,19 +523,19 @@ bytecodePrimValueWithArg = make_call_primitive_bytecode(primitives.VALUE, "value:", 1) def bytecodePrimDo(self, interp): - self._sendSelfSelector("do:", 1, interp) + self._sendSelfSelectorSpecial("do:", 1, interp) def bytecodePrimNew(self, interp): - self._sendSelfSelector("new", 0, interp) + self._sendSelfSelectorSpecial("new", 0, interp) def bytecodePrimNewWithArg(self, interp): - self._sendSelfSelector("new:", 1, interp) + self._sendSelfSelectorSpecial("new:", 1, interp) def bytecodePrimPointX(self, interp): - self._sendSelfSelector("x", 0, interp) + self._sendSelfSelectorSpecial("x", 0, interp) def bytecodePrimPointY(self, interp): - self._sendSelfSelector("y", 0, interp) + self._sendSelfSelectorSpecial("y", 0, interp) BYTECODE_RANGES = [ ( 0, 15, "pushReceiverVariableBytecode"), diff --git a/spyvm/objspace.py b/spyvm/objspace.py --- a/spyvm/objspace.py +++ b/spyvm/objspace.py @@ -1,6 +1,6 @@ from spyvm import constants, model, shadow, wrapper from spyvm.error import UnwrappingError, WrappingError -from rpython.rlib.objectmodel import instantiate +from rpython.rlib.objectmodel import instantiate, specialize from rpython.rlib.rarithmetic import intmask, r_uint class ObjSpace(object): @@ -147,8 +147,11 @@ self.w_zero = model.W_SmallInteger(0) self.w_one = model.W_SmallInteger(1) self.w_two = model.W_SmallInteger(2) + w_special_selectors = model.W_PointersObject( + self.classtable['w_Array'], len(constants.SPECIAL_SELECTORS) * 2) + self.w_special_selectors = w_special_selectors + self.objtable = {} - for name in constants.objects_in_special_object_table: name = "w_" + name try: @@ -156,6 +159,11 @@ except KeyError, e: self.objtable[name] = None + @specialize.arg(1) + def get_special_selector(self, selector): + i0 = constants.find_selectorindex(selector) + return self.w_special_selectors.at0(self, i0) + # methods for wrapping and unwrapping stuff def wrap_int(self, val): @@ -255,7 +263,7 @@ def unwrap_array(self, w_array): # Check that our argument has pointers format and the class: if not w_array.getclass(self).is_same_object(self.w_Array): - raise PrimitiveFailedError() + raise UnwrappingError() assert isinstance(w_array, model.W_PointersObject) return [w_array.at0(self, i) for i in range(w_array.size())] diff --git a/spyvm/primitives.py b/spyvm/primitives.py --- a/spyvm/primitives.py +++ b/spyvm/primitives.py @@ -856,10 +856,10 @@ raise PrimitiveFailedError() @expose_primitive(PERFORM_WITH_ARGS, - unwrap_spec=[object, str, object], + unwrap_spec=[object, object, object], no_result=True) -def func(interp, w_rcvr, sel, w_args): - w_method = w_rcvr.shadow_of_my_class(interp.space).lookup(sel) +def func(interp, w_rcvr, w_sel, w_args): + w_method = w_rcvr.shadow_of_my_class(interp.space).lookup(w_sel) assert w_method w_frame = w_method.create_frame(interp.space, w_rcvr, diff --git a/spyvm/shadow.py b/spyvm/shadow.py --- a/spyvm/shadow.py +++ b/spyvm/shadow.py @@ -232,15 +232,15 @@ def __repr__(self): return "" % (self.name or '?',) - def lookup(self, selector): + def lookup(self, w_selector): look_in_shadow = self while look_in_shadow is not None: try: - w_method = look_in_shadow.s_methoddict().methoddict[selector] + w_method = look_in_shadow.s_methoddict().methoddict[w_selector] return w_method except KeyError, e: look_in_shadow = look_in_shadow.s_superclass() - raise MethodNotFound(self, selector) + raise MethodNotFound(self, w_selector) def initialize_methoddict(self): "NOT_RPYTHON" # this is only for testing. @@ -249,10 +249,11 @@ self.w_methoddict._store(1, model.W_PointersObject(None, 0)) self.s_methoddict().invalid = False - def installmethod(self, selector, w_method): + def installmethod(self, w_selector, w_method): "NOT_RPYTHON" # this is only for testing. + assert not isinstance(w_selector, str) self.initialize_methoddict() - self.s_methoddict().methoddict[selector] = w_method + self.s_methoddict().methoddict[w_selector] = w_method if isinstance(w_method, model.W_CompiledMethod): method = w_method.as_compiledmethod_get_shadow(self.space) method.w_compiledin = self.w_self() @@ -276,12 +277,12 @@ if not w_selector.is_same_object(self.space.w_nil): if not isinstance(w_selector, model.W_BytesObject): raise ClassShadowError("bogus selector in method dict") - selector = w_selector.as_string() w_compiledmethod = w_values._fetch(i) if not isinstance(w_compiledmethod, model.W_CompiledMethod): raise ClassShadowError("the methoddict must contain " "CompiledMethods only for now") - self.methoddict[selector] = w_compiledmethod + self.methoddict[w_selector] = w_compiledmethod + selector = w_selector.as_string() w_compiledmethod._likely_methodname = selector @@ -738,7 +739,8 @@ class CompiledMethodShadow(object): _immutable_fields_ = ["_w_self", "bytecode", "literals[*]", "bytecodeoffset", - "literalsize", "tempsize", "w_compiledin"] + "literalsize", "tempsize", "primitive", + "w_compiledin"] def __init__(self, w_compiledmethod): self._w_self = w_compiledmethod @@ -747,6 +749,7 @@ self.bytecodeoffset = w_compiledmethod.bytecodeoffset() self.literalsize = w_compiledmethod.getliteralsize() self.tempsize = w_compiledmethod.gettempsize() + self.primitive = w_compiledmethod.primitive self.w_compiledin = None if self.literals: diff --git a/spyvm/test/jit.py b/spyvm/test/jit.py --- a/spyvm/test/jit.py +++ b/spyvm/test/jit.py @@ -77,4 +77,4 @@ def interp_w(): interp.interpret() - self.meta_interp(interp_w, [], listcomp=True, listops=True, backendopt=True) \ No newline at end of file + self.meta_interp(interp_w, [], listcomp=True, listops=True, backendopt=True) diff --git a/spyvm/test/test_interpreter.py b/spyvm/test/test_interpreter.py --- a/spyvm/test/test_interpreter.py +++ b/spyvm/test/test_interpreter.py @@ -1,6 +1,6 @@ import py from spyvm import model, interpreter, primitives, shadow -from spyvm import objspace, wrapper +from spyvm import objspace, wrapper, constants mockclass = objspace.bootstrap_class @@ -25,7 +25,7 @@ globals()[name] = make_getter(entry) setup() -def run_with_faked_methods(methods, func, active_context=None): +def run_with_faked_primitive_methods(methods, func, active_context=None): # Install faked compiled methods that just invoke the primitive: for (w_class, primnum, argsize, methname) in methods: @@ -33,8 +33,17 @@ prim_meth = model.W_CompiledMethod(0) prim_meth.primitive = primnum prim_meth.argsize = argsize - s_class.installmethod(methname, prim_meth) - + symbol = fakesymbol(methname) + # somewhat evil: + try: + index = constants.find_selectorindex(methname) + except ValueError: + pass + else: + space.w_special_selectors.atput0(space, index, symbol) + assert space.get_special_selector(methname) is symbol + s_class.installmethod(symbol, prim_meth) + assert space.w_nil._shadow is None try: func(active_context) if active_context else func() @@ -43,7 +52,7 @@ assert space.w_nil._shadow is None for (w_class, _, _, methname) in methods: s_class = w_class.as_class_get_shadow(space) - del s_class.s_methoddict().methoddict[methname] + del s_class.s_methoddict().methoddict[fakesymbol(methname)] def fakesymbol(s, _cache={}): try: @@ -349,7 +358,7 @@ w_metaclass=w_fakeclassclass) interp = new_interpreter(bytecodePrimNew) interp.s_active_context().push(w_fakeclass) - run_with_faked_methods( + run_with_faked_primitive_methods( [[w_fakeclassclass, primitives.NEW, 0, "new"]], interp.step, interp.s_active_context()) @@ -365,7 +374,7 @@ interp = new_interpreter(bytecodePrimNewWithArg) interp.s_active_context().push(w_fakeclass) interp.s_active_context().push(space.w_two) - run_with_faked_methods( + run_with_faked_primitive_methods( [[w_fakeclassclass, primitives.NEW_WITH_ARG, 1, "new:"]], interp.step, interp.s_active_context()) @@ -379,7 +388,7 @@ w_fakeinst = w_fakeclass.as_class_get_shadow(space).new(5) interp = new_interpreter(bytecodePrimSize) interp.s_active_context().push(w_fakeinst) - run_with_faked_methods( + run_with_faked_primitive_methods( [[w_fakeclass, primitives.SIZE, 0, "size"]], interp.step, interp.s_active_context()) @@ -399,16 +408,18 @@ shadow = w_class.as_class_get_shadow(space) w_method = model.W_CompiledMethod(2) w_method.bytes = pushConstantOneBytecode + bytecode - shadow.installmethod("foo", w_method) + literals = fakeliterals(space, "foo") + w_foo = literals[0] + shadow.installmethod(w_foo, w_method) interp = new_interpreter(bytecodes) - interp.w_active_context().as_methodcontext_get_shadow(space).w_method().setliterals(fakeliterals(space, "foo")) + interp.w_active_context().as_methodcontext_get_shadow(space).w_method().setliterals(literals) interp.s_active_context().push(w_object) callerContext = interp.w_active_context() interp.step(interp.s_active_context()) assert interp.s_active_context().w_sender() == callerContext assert interp.s_active_context().stack() == [] assert interp.w_active_context().as_methodcontext_get_shadow(space).w_receiver().is_same_object(w_object) - assert interp.w_active_context().as_methodcontext_get_shadow(space).w_method().is_same_object(shadow.s_methoddict().methoddict["foo"]) + assert interp.w_active_context().as_methodcontext_get_shadow(space).w_method().is_same_object(shadow.s_methoddict().methoddict[w_foo]) assert callerContext.as_context_get_shadow(space).stack() == [] interp.step(interp.s_active_context()) interp.step(interp.s_active_context()) @@ -428,11 +439,12 @@ method.bytes = bytecode method.argsize = 1 method.tempsize = 1 - method.setliterals(fakeliterals(space, "fib:")) - shadow.installmethod("fib:", method) + literals = fakeliterals(space, "fib:") + method.setliterals(literals) + shadow.installmethod(literals[0], method) w_object = shadow.new() interp = new_interpreter(sendLiteralSelectorBytecode(16) + returnTopFromMethod) - interp.w_active_context().as_methodcontext_get_shadow(space).w_method().setliterals(fakeliterals(space, "fib:")) + interp.w_active_context().as_methodcontext_get_shadow(space).w_method().setliterals(literals) interp.s_active_context().push(w_object) interp.s_active_context().push(space.wrap_int(8)) result = interp.interpret() @@ -442,7 +454,7 @@ def test(): interp = new_interpreter(sendLiteralSelectorBytecode(1 + 16)) - interp.w_active_context().as_methodcontext_get_shadow(space).w_method().setliterals(fakeliterals(space, "foo", "sub")) + interp.w_active_context().as_methodcontext_get_shadow(space).w_method().setliterals(fakeliterals(space, "foo", "-")) interp.s_active_context().push(space.wrap_int(50)) interp.s_active_context().push(space.wrap_int(8)) callerContext = interp.w_active_context() @@ -452,9 +464,9 @@ w_result = interp.s_active_context().pop() assert space.unwrap_int(w_result) == 42 - run_with_faked_methods( + run_with_faked_primitive_methods( [[space.w_SmallInteger, primitives.SUBTRACT, - 1, "sub"]], + 1, "-"]], test) def test_makePoint(): @@ -568,13 +580,16 @@ w_method.argsize = 1 w_method.tempsize = 1 w_method.literalsize = 1 - shadow.installmethod("+", w_method) - + w_symbol = fakesymbol("+") + shadow.installmethod(w_symbol, w_method) + # slightly evil + space.w_special_selectors.atput0(space, constants.find_selectorindex("+"), w_symbol) + w_object = shadow.new() interp.s_active_context().push(w_object) interp.s_active_context().push(space.w_one) interp.step(interp.s_active_context()) - assert interp.w_active_context().as_methodcontext_get_shadow(space).w_method() == shadow.s_methoddict().methoddict["+"] + assert interp.w_active_context().as_methodcontext_get_shadow(space).w_method() == shadow.s_methoddict().methoddict[w_symbol] assert interp.s_active_context().w_receiver() is w_object assert interp.w_active_context().as_methodcontext_get_shadow(space).gettemp(0).is_same_object(space.w_one) assert interp.s_active_context().stack() == [] @@ -609,17 +624,19 @@ # which does a call to its super meth1 = model.W_CompiledMethod(2) meth1.bytes = pushReceiverBytecode + bytecode - meth1.setliterals(fakeliterals(space, "foo")) - w_class.as_class_get_shadow(space).installmethod("foo", meth1) + literals = fakeliterals(space, "foo") + foo = literals[0] + meth1.setliterals(literals) + w_class.as_class_get_shadow(space).installmethod(foo, meth1) # and that one again to its super meth2 = model.W_CompiledMethod(2) meth2.bytes = pushReceiverBytecode + bytecode - meth2.setliterals(fakeliterals(space, "foo")) - w_super.as_class_get_shadow(space).installmethod("foo", meth2) + meth2.setliterals(fakeliterals(space, foo)) + w_super.as_class_get_shadow(space).installmethod(foo, meth2) meth3 = model.W_CompiledMethod(0) - w_supersuper.as_class_get_shadow(space).installmethod("foo", meth3) + w_supersuper.as_class_get_shadow(space).installmethod(foo, meth3) interp = new_interpreter(bytecodes) - interp.w_active_context().as_methodcontext_get_shadow(space).w_method().setliterals(fakeliterals(space, "foo")) + interp.w_active_context().as_methodcontext_get_shadow(space).w_method().setliterals(literals) interp.s_active_context().push(w_object) interp.step(interp.s_active_context()) for w_specificclass in [w_super, w_supersuper]: @@ -629,7 +646,7 @@ assert interp.s_active_context().w_sender() == callerContext assert interp.s_active_context().stack() == [] assert interp.w_active_context().as_methodcontext_get_shadow(space).w_receiver() == w_object - meth = w_specificclass.as_class_get_shadow(space).s_methoddict().methoddict["foo"] + meth = w_specificclass.as_class_get_shadow(space).s_methoddict().methoddict[foo] assert interp.w_active_context().as_methodcontext_get_shadow(space).w_method() == meth assert callerContext.as_context_get_shadow(space).stack() == [] @@ -703,7 +720,7 @@ [ 137, 119, 200, 164, 6, 105, 104, 16, 17, 176, 125, 33, 34, 240, 124 ], fakeliterals(space, "value:value:", space.wrap_int(3), space.wrap_int(4))).value == 7 - run_with_faked_methods( + run_with_faked_primitive_methods( [[space.w_BlockContext, primitives.VALUE, 2, "value:value:"]], test) @@ -741,7 +758,7 @@ 125, 33, 224, 124 ], fakeliterals(space, "valueWithArguments:", [3, 2])).value == 1 - run_with_faked_methods( + run_with_faked_primitive_methods( [[space.w_BlockContext, primitives.VALUE_WITH_ARGS, 1, "valueWithArguments:"]], test) @@ -752,7 +769,7 @@ assert interpret_bc( [ 32, 118, 192, 124], fakeliterals(space, "a")) == space.wrap_char("a") - run_with_faked_methods( + run_with_faked_primitive_methods( [[space.w_String, primitives.STRING_AT, 1, "at:"]], test) @@ -762,7 +779,7 @@ assert interpret_bc( [ 32, 118, 33, 193, 124 ], fakeliterals(space, "a", space.wrap_char("b"))) == space.wrap_char("b") - run_with_faked_methods( + run_with_faked_primitive_methods( [[space.w_String, primitives.STRING_AT_PUT, 2, "at:put:"]], test) @@ -777,7 +794,7 @@ [112, 118, 192, 124], fakeliterals(space, ), receiver=w_fakeinst)) == "b" - run_with_faked_methods( + run_with_faked_primitive_methods( [[w_fakeclass, primitives.AT, 1, "at:"]], test) @@ -794,7 +811,7 @@ receiver=w_fakeinst)) == "b" assert space.unwrap_char(w_fakeinst.fetch(space, 0)) == "a" assert space.unwrap_char(w_fakeinst.fetch(space, 1)) == "b" - run_with_faked_methods( + run_with_faked_primitive_methods( [[w_fakeclass, primitives.AT_PUT, 2, "at:put:"]], test) @@ -816,7 +833,7 @@ [112, 119, 33, 240, 124], oalp, receiver=prim_meth).value == 3 assert interpret_bc( [112, 119, 224, 124], oal, receiver=prim_meth).value == 3 - run_with_faked_methods( + run_with_faked_primitive_methods( [[space.w_CompiledMethod, primitives.OBJECT_AT, 1, "objectAt:"], [space.w_CompiledMethod, primitives.OBJECT_AT_PUT, 2, "objectAt:put:"]], test) diff --git a/spyvm/test/test_miniimage.py b/spyvm/test/test_miniimage.py --- a/spyvm/test/test_miniimage.py +++ b/spyvm/test/test_miniimage.py @@ -17,9 +17,23 @@ module.reader = open_miniimage(space) reader.initialize() module.image = squeakimage.SqueakImage() - module.image.from_reader(space, get_reader()) + module.image.from_reader(space, reader) module.space = space - + +def find_symbol(name): + w_dnu = image.special(constants.SO_DOES_NOT_UNDERSTAND) + assert str(w_dnu) == "doesNotUnderstand:" + w_Symbol = w_dnu.getclass(space) + for chunk in reader.chunklist: + w_obj = chunk.g_object.w_object + if not isinstance(w_obj, model.W_BytesObject): + continue + if not w_obj.getclass(space).is_same_object(w_Symbol): + continue + if w_obj.as_string() == name: + return w_obj + return perform(space.wrap_string(name), "asSymbol") + def open_miniimage(space): return squeakimage.ImageReader(space, squeakimage.Stream(mini_image.open())) @@ -192,7 +206,7 @@ # Should get this from w_object w_smallint_class = image.special(constants.SO_SMALLINTEGER_CLASS) s_class = w_object.shadow_of_my_class(space) - w_method = s_class.lookup("abs") + w_method = s_class.lookup(find_symbol("abs")) assert w_method w_frame = w_method.create_frame(space, w_object, []) @@ -286,7 +300,11 @@ def perform(w_receiver, selector, *arguments_w): interp = interpreter.Interpreter(space) s_class = w_receiver.shadow_of_my_class(space) - w_method = s_class.lookup(selector) + if isinstance(selector, str): + w_selector = find_symbol(selector) + else: + w_selector = selector + w_method = s_class.lookup(w_selector) assert w_method w_frame = w_method.create_frame(space, w_receiver, list(arguments_w)) interp.store_w_active_context(w_frame) diff --git a/spyvm/test/test_model.py b/spyvm/test/test_model.py --- a/spyvm/test/test_model.py +++ b/spyvm/test/test_model.py @@ -6,6 +6,8 @@ mockclass = objspace.bootstrap_class space = objspace.ObjSpace() +w_foo = space.wrap_string("foo") +w_bar = space.wrap_string("bar") def joinbits(values, lengths): result = 0 @@ -59,29 +61,29 @@ def test_method_lookup(): w_class = mockclass(space, 0) shadow = w_class.as_class_get_shadow(space) - shadow.installmethod("foo", 1) - shadow.installmethod("bar", 2) + shadow.installmethod(w_foo, 1) + shadow.installmethod(w_bar, 2) w_subclass = mockclass(space, 0, w_superclass=w_class) subshadow = w_subclass.as_class_get_shadow(space) assert subshadow.s_superclass() is shadow - subshadow.installmethod("foo", 3) + subshadow.installmethod(w_foo, 3) shadow.initialize_methoddict() subshadow.initialize_methoddict() - assert shadow.lookup("foo") == 1 - assert shadow.lookup("bar") == 2 + assert shadow.lookup(w_foo) == 1 + assert shadow.lookup(w_bar) == 2 py.test.raises(MethodNotFound, shadow.lookup, "zork") - assert subshadow.lookup("foo") == 3 - assert subshadow.lookup("bar") == 2 + assert subshadow.lookup(w_foo) == 3 + assert subshadow.lookup(w_bar) == 2 py.test.raises(MethodNotFound, subshadow.lookup, "zork") def test_w_compiledin(): w_super = mockclass(space, 0) w_class = mockclass(space, 0, w_superclass=w_super) supershadow = w_super.as_class_get_shadow(space) - supershadow.installmethod("foo", model.W_CompiledMethod(0)) + supershadow.installmethod(w_foo, model.W_CompiledMethod(0)) classshadow = w_class.as_class_get_shadow(space) classshadow.initialize_methoddict() - assert classshadow.lookup("foo").as_compiledmethod_get_shadow(space).w_compiledin is w_super + assert classshadow.lookup(w_foo).as_compiledmethod_get_shadow(space).w_compiledin is w_super def test_compiledmethod_setchar(): w_method = model.W_CompiledMethod(3) diff --git a/spyvm/test/test_shadow.py b/spyvm/test/test_shadow.py --- a/spyvm/test/test_shadow.py +++ b/spyvm/test/test_shadow.py @@ -69,7 +69,10 @@ 'bar': model.W_CompiledMethod(0)} w_class = build_smalltalk_class("Demo", 0x90, methods=methods) classshadow = w_class.as_class_get_shadow(space) - assert classshadow.s_methoddict().methoddict == methods + methoddict = classshadow.s_methoddict().methoddict + assert len(methods) == len(methoddict) + for w_key, value in methoddict.items(): + assert methods[w_key.as_string()] is value def method(tempsize=3,argsize=2, bytes="abcde"): w_m = model.W_CompiledMethod() From noreply at buildbot.pypy.org Fri Feb 22 11:51:44 2013 From: noreply at buildbot.pypy.org (cfbolz) Date: Fri, 22 Feb 2013 11:51:44 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: move logic to the image reader Message-ID: <20130222105144.B30731C01BF@cobra.cs.uni-duesseldorf.de> Author: Carl Friedrich Bolz Branch: Changeset: r85:19453007f92c Date: 2013-02-21 17:07 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/19453007f92c/ Log: move logic to the image reader diff --git a/spyvm/squeakimage.py b/spyvm/squeakimage.py --- a/spyvm/squeakimage.py +++ b/spyvm/squeakimage.py @@ -223,6 +223,25 @@ for name, idx in constants.objects_in_special_object_table.items(): space.objtable["w_" + name] = self.special_objects[idx] + self.w_asSymbol = self.find_asSymbol(space, reader) + + def find_asSymbol(self, space, reader): + w_dnu = self.special(constants.SO_DOES_NOT_UNDERSTAND) + assert w_dnu.as_string() == "doesNotUnderstand:" + w_Symbol = w_dnu.getclass(space) + w_obj = None + # bit annoying that we have to hunt through the image :-( + for chunk in reader.chunklist: + w_obj = chunk.g_object.w_object + if not isinstance(w_obj, model.W_BytesObject): + continue + if not w_obj.getclass(space).is_same_object(w_Symbol): + continue + if w_obj.as_string() == "asSymbol": + break + assert w_obj is not None + return w_obj + def special(self, index): return self.special_objects[index] diff --git a/spyvm/test/test_miniimage.py b/spyvm/test/test_miniimage.py --- a/spyvm/test/test_miniimage.py +++ b/spyvm/test/test_miniimage.py @@ -21,17 +21,8 @@ module.space = space def find_symbol(name): - w_dnu = image.special(constants.SO_DOES_NOT_UNDERSTAND) - assert str(w_dnu) == "doesNotUnderstand:" - w_Symbol = w_dnu.getclass(space) - for chunk in reader.chunklist: - w_obj = chunk.g_object.w_object - if not isinstance(w_obj, model.W_BytesObject): - continue - if not w_obj.getclass(space).is_same_object(w_Symbol): - continue - if w_obj.as_string() == name: - return w_obj + if name == "asSymbol": + return image.w_asSymbol return perform(space.wrap_string(name), "asSymbol") def open_miniimage(space): @@ -298,6 +289,9 @@ assert space.unwrap_int(w_result) == 42 def perform(w_receiver, selector, *arguments_w): + return perform_with_space(space, w_receiver, selector, *arguments_w) + +def perform_with_space(space, w_receiver, selector, *arguments_w): interp = interpreter.Interpreter(space) s_class = w_receiver.shadow_of_my_class(space) if isinstance(selector, str): From noreply at buildbot.pypy.org Fri Feb 22 11:51:45 2013 From: noreply at buildbot.pypy.org (cfbolz) Date: Fri, 22 Feb 2013 11:51:45 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: move some of the infrastructure to run simple performs from rpython to interpreter.py Message-ID: <20130222105145.BC6EF1C01BF@cobra.cs.uni-duesseldorf.de> Author: Carl Friedrich Bolz Branch: Changeset: r86:f8aedf50f65c Date: 2013-02-22 11:49 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/f8aedf50f65c/ Log: move some of the infrastructure to run simple performs from rpython to interpreter.py diff --git a/spyvm/interpreter.py b/spyvm/interpreter.py --- a/spyvm/interpreter.py +++ b/spyvm/interpreter.py @@ -32,9 +32,10 @@ get_printable_location=get_printable_location ) - def __init__(self, space, image_name=""): + def __init__(self, space, image=None, image_name=""): self._w_active_context = None self.space = space + self.image = image self.image_name = image_name def w_active_context(self): @@ -101,6 +102,22 @@ s_active_context=s_active_context) self.step(s_active_context) + def perform(self, w_receiver, selector, *arguments_w): + if selector == "asSymbol": + w_selector = self.image.w_asSymbol + else: + w_selector = self.perform(self.space.wrap_string(selector), "asSymbol") + s_class = w_receiver.shadow_of_my_class(self.space) + w_method = s_class.lookup(w_selector) + assert w_method + w_frame = w_method.create_frame(self.space, w_receiver, list(arguments_w)) + self.store_w_active_context(w_frame) + while True: + try: + self.loop() + except ReturnFromTopLevel, e: + return e.object + class ReturnFromTopLevel(Exception): def __init__(self, object): diff --git a/spyvm/test/jit.py b/spyvm/test/jit.py --- a/spyvm/test/jit.py +++ b/spyvm/test/jit.py @@ -49,32 +49,20 @@ sys.setrecursionlimit(100000) class TestLLtype(LLJitMixin): - def test_miniloop(self): - def miniloop(): - from spyvm import objspace - space = objspace.ObjSpace() - image = create_testimage(space) - interp = interpreter.Interpreter(space) + from spyvm import objspace + space = objspace.ObjSpace() + image = create_testimage(space) + interp = interpreter.Interpreter(space, image) + + + counter = 0 + + def interp_w(): w_object = model.W_SmallInteger(0) - - s_class = w_object.shadow_of_my_class(space) - w_method = s_class.lookup("loopTest") - - assert w_method - w_frame = w_method.create_frame(space, w_object, []) - interp.store_w_active_context(w_frame) - - counter = 0 - - from spyvm.interpreter import BYTECODE_TABLE - return interp - - interp = miniloop() - def interp_w(): - interp.interpret() + interp.perform(w_object, "loopTest") self.meta_interp(interp_w, [], listcomp=True, listops=True, backendopt=True) diff --git a/spyvm/test/test_miniimage.py b/spyvm/test/test_miniimage.py --- a/spyvm/test/test_miniimage.py +++ b/spyvm/test/test_miniimage.py @@ -19,6 +19,7 @@ module.image = squeakimage.SqueakImage() module.image.from_reader(space, reader) module.space = space + module.interp = interpreter.Interpreter(space, image) def find_symbol(name): if name == "asSymbol": @@ -188,30 +189,13 @@ -def test_lookup_abs_in_integer(int=10): - image = get_image() - interp = interpreter.Interpreter(space) +def test_lookup_abs_in_integer(): + for value in [10, -3, 0]: - w_object = model.W_SmallInteger(int) + w_object = model.W_SmallInteger(value) + w_res = interp.perform(w_object, "abs") + assert w_res.value == abs(value) - # Should get this from w_object - w_smallint_class = image.special(constants.SO_SMALLINTEGER_CLASS) - s_class = w_object.shadow_of_my_class(space) - w_method = s_class.lookup(find_symbol("abs")) - - assert w_method - w_frame = w_method.create_frame(space, w_object, []) - interp.store_w_active_context(w_frame) - - while True: - try: - interp.step(interp.s_active_context()) - except interpreter.ReturnFromTopLevel, e: - assert e.object.value == abs(int) - return - -def test_lookup_neg_abs_in_integer(): - test_lookup_abs_in_integer(-3) def test_map_mirrors_to_classtable(): w_compiledmethod_class = image.special(constants.SO_COMPILEDMETHOD_CLASS) @@ -289,25 +273,8 @@ assert space.unwrap_int(w_result) == 42 def perform(w_receiver, selector, *arguments_w): - return perform_with_space(space, w_receiver, selector, *arguments_w) + return interp.perform(w_receiver, selector, *arguments_w) -def perform_with_space(space, w_receiver, selector, *arguments_w): - interp = interpreter.Interpreter(space) - s_class = w_receiver.shadow_of_my_class(space) - if isinstance(selector, str): - w_selector = find_symbol(selector) - else: - w_selector = selector - w_method = s_class.lookup(w_selector) - assert w_method - w_frame = w_method.create_frame(space, w_receiver, list(arguments_w)) - interp.store_w_active_context(w_frame) - while True: - try: - interp.step(interp.s_active_context()) - #print interp.s_active_context.stack - except interpreter.ReturnFromTopLevel, e: - return e.object def test_step_forged_image(): from spyvm import wrapper From noreply at buildbot.pypy.org Fri Feb 22 11:51:46 2013 From: noreply at buildbot.pypy.org (cfbolz) Date: Fri, 22 Feb 2013 11:51:46 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: merge Message-ID: <20130222105146.D79691C01BF@cobra.cs.uni-duesseldorf.de> Author: Carl Friedrich Bolz Branch: Changeset: r87:2ece4888b751 Date: 2013-02-22 11:50 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/2ece4888b751/ Log: merge diff --git a/spyvm/constants.py b/spyvm/constants.py --- a/spyvm/constants.py +++ b/spyvm/constants.py @@ -38,12 +38,15 @@ # MethodContext < ContextPart MTHDCTX_METHOD = 3 -MTHDCTX_RECEIVER_MAP = 4 +MTHDCTX_CLOSURE_OR_NIL = 4 MTHDCTX_RECEIVER = 5 MTHDCTX_TEMP_FRAME_START = 6 # BlockClosure < Object -BLOCKCLOSURE_SIZE = 3 +BLKCLSR_OUTER_CONTEXT = 0 +BLKCLSR_STARTPC = 1 +BLKCLSR_NUMARGS = 2 +BLKCLSR_SIZE = 3 # ___________________________________________________________________________ # Miscellaneous constants diff --git a/spyvm/interpreter.py b/spyvm/interpreter.py --- a/spyvm/interpreter.py +++ b/spyvm/interpreter.py @@ -445,7 +445,7 @@ i = self.getbytecode() blockSize = (j << 8) | i #create new instance of BlockClosure - w_closure, closure = space.newClosure(self._w_self, self.pc(), numArgs, + w_closure = space.newClosure(self._w_self, self.pc(), numArgs, self.pop_and_return_n(numCopied)) self.push(w_closure) self.jump(blockSize) diff --git a/spyvm/objspace.py b/spyvm/objspace.py --- a/spyvm/objspace.py +++ b/spyvm/objspace.py @@ -112,7 +112,7 @@ define_cls("w_BlockContext", "w_ContextPart", instvarsize=constants.BLKCTX_STACK_START) define_cls("w_BlockClosure", "w_Object", - instvarsize=constants.BLOCKCLOSURE_SIZE, + instvarsize=constants.BLKCLSR_SIZE, varsized=True) # make better accessors for classes that can be found in special object # table @@ -273,14 +273,15 @@ def newClosure(self, outerContext, pc, numArgs, copiedValues): BlockClosureShadow = self.w_BlockClosure.as_class_get_shadow(self) - w_closure = BlockClosureShadow.new(len(copiedValues)) + numCopied = len(copiedValues) + w_closure = BlockClosureShadow.new(numCopied) closure = wrapper.BlockClosureWrapper(self, w_closure) closure.store_outerContext(outerContext) closure.store_startpc(pc) closure.store_numArgs(numArgs) - for i0 in range(len(copiedValues)): + for i0 in range(numCopied): closure.atput0(i0, copiedValues[i0]) - return w_closure, closure + return w_closure def bootstrap_class(space, instsize, w_superclass=None, w_metaclass=None, name='?', format=shadow.POINTERS, varsized=False): diff --git a/spyvm/primitives.py b/spyvm/primitives.py --- a/spyvm/primitives.py +++ b/spyvm/primitives.py @@ -926,63 +926,66 @@ @expose_primitive(CLOSURE_COPY_WITH_COPIED_VALUES, unwrap_spec=[object, int, list]) def func(interp, outerContext, numArgs, copiedValues): frame = interp.s_active_context() - w_context, s_context = interp.space.newClosure(outerContext, frame.pc(), + w_context = interp.space.newClosure(outerContext, frame.pc(), numArgs, copiedValues) - frame.push(w_context) + return w_context -def activateClosure(interp, w_block_closure, args_w, mayContextSwitch=True): - raise PrimitiveFailedError - if not w_block_closure.getclass(interp.space).is_same_object( - interp.space.w_BlockClosure): +def activateClosure(interp, w_block, args_w, mayContextSwitch=True): + space = interp.space + if not w_block.getclass(space).is_same_object( + space.w_BlockClosure): raise PrimitiveFailedError() - if not w_block_closure.numArgs == len(args_w): + block = wrapper.BlockClosureWrapper(space, w_block) + if not block.numArgs() == len(args_w): raise PrimitiveFailedError() - if not w_block_closure.outerContext.getclass(interp.space).issubclass( - interp.space.w_ContextPart): + outer_ctxt_class = block.outerContext().getclass(space) + if not (outer_ctxt_class is space.w_MethodContext + or outer_ctxt_class is space.w_BlockContext + or outer_ctxt_class is space.w_BlockClosure): raise PrimitiveFailedError() - w_closureMethod = w_block_closure.w_method() + + # additionally to the smalltalk implementation, this also pushes + # args and copiedValues + w_new_frame = block.asContextWithSender( + interp.w_active_context(), args_w) + w_closureMethod = w_new_frame.get_shadow(space).w_method() + assert isinstance(w_closureMethod, model.W_CompiledMethod) - assert w_block_closure is not w_block_closure.outerContext - numCopied = w_block_closure.size() + assert w_block is not block.outerContext() - s_block_closure = w_block_closure.as_blockclosure_get_shadow(interp.space) - s_block_closure.push_all(args_w) + interp.store_w_active_context(w_new_frame) - s_block_closure.store_pc(s_block_closure.initialip()) - frame = interp.s_active_context() - s_block_closure.store_w_sender(frame) - - at expose_primitive(CLOSURE_VALUE, unwrap_spec=[object]) + at expose_primitive(CLOSURE_VALUE, unwrap_spec=[object], no_result=True) def func(interp, w_block_closure): activateClosure(interp, w_block_closure, []) - at expose_primitive(CLOSURE_VALUE_, unwrap_spec=[object, object]) + at expose_primitive(CLOSURE_VALUE_, unwrap_spec=[object, object], no_result=True) def func(interp, w_block_closure, w_a0): activateClosure(interp, w_block_closure, [w_a0]) - at expose_primitive(CLOSURE_VALUE_VALUE, unwrap_spec=[object, object, object]) + at expose_primitive(CLOSURE_VALUE_VALUE, unwrap_spec=[object, object, object], no_result=True) def func(interp, w_block_closure, w_a0, w_a1): activateClosure(interp, w_block_closure, [w_a0, w_a1]) - at expose_primitive(CLOSURE_VALUE_VALUE_VALUE, unwrap_spec=[object, object, object, object]) + at expose_primitive(CLOSURE_VALUE_VALUE_VALUE, unwrap_spec=[object, object, object, object], no_result=True) def func(interp, w_block_closure, w_a0, w_a1, w_a2): activateClosure(interp, w_block_closure, [w_a0, w_a1, w_a2]) - at expose_primitive(CLOSURE_VALUE_VALUE_VALUE_VALUE, unwrap_spec=[object, object, object, object, object]) + at expose_primitive(CLOSURE_VALUE_VALUE_VALUE_VALUE, unwrap_spec=[object, object, object, object, object], no_result=True) def func(interp, w_block_closure, w_a0, w_a1, w_a2, w_a3): activateClosure(interp, w_block_closure, [w_a0, w_a1, w_a2, w_a3]) - at expose_primitive(CLOSURE_VALUE_WITH_ARGS, unwrap_spec=[object, list]) + at expose_primitive(CLOSURE_VALUE_WITH_ARGS, unwrap_spec=[object, list], no_result=True) def func(interp, w_block_closure, args_w): activateClosure(interp, w_block_closure, args_w) - at expose_primitive(CLOSURE_VALUE_NO_CONTEXT_SWITCH, unwrap_spec=[object]) + at expose_primitive(CLOSURE_VALUE_NO_CONTEXT_SWITCH, unwrap_spec=[object], no_result=True) def func(interp, w_block_closure): activateClosure(interp, w_block_closure, [], mayContextSwitch=False) - at expose_primitive(CLOSURE_VALUE_NO_CONTEXT_SWITCH_, unwrap_spec=[object, object]) + at expose_primitive(CLOSURE_VALUE_NO_CONTEXT_SWITCH_, unwrap_spec=[object, object], no_result=True) def func(interp, w_block_closure, w_a0): activateClosure(interp, w_block_closure, [w_a0], mayContextSwitch=False) diff --git a/spyvm/shadow.py b/spyvm/shadow.py --- a/spyvm/shadow.py +++ b/spyvm/shadow.py @@ -634,14 +634,14 @@ class MethodContextShadow(ContextPartShadow): def __init__(self, space, w_self): - self.w_receiver_map = space.w_nil + self.w_closure_or_nil = space.w_nil self._w_receiver = None ContextPartShadow.__init__(self, space, w_self) @staticmethod @jit.unroll_safe def make_context(space, w_method, w_receiver, - arguments, w_sender=None): + arguments, w_sender=None, closure=None, pc=0): # From blue book: normal mc have place for 12 temps+maxstack # mc for methods with islarge flag turned on 32 size = 12 + w_method.islarge * 20 + w_method.argsize @@ -652,25 +652,32 @@ # XXX could hack some more to never have to create the _vars of w_result s_result = MethodContextShadow(space, w_result) w_result.store_shadow(s_result) + if closure is not None: + s_result.w_closure_or_nil = closure._w_self + s_result.store_w_method(w_method) if w_sender: s_result.store_w_sender(w_sender) s_result.store_w_receiver(w_receiver) - s_result.store_pc(0) + s_result.store_pc(pc) s_result.init_stack_and_temps() - for i in range(len(arguments)): - s_result.settemp(i, arguments[i]) + + argc = len(arguments) + for i0 in range(argc): + s_result.settemp(i0, arguments[i0]) + if closure is not None: + for i0 in range(closure.size()): + s_result.settemp(i0+argc, closure.at0(i0)) return w_result def fetch(self, n0): if n0 == constants.MTHDCTX_METHOD: return self.w_method() - if n0 == constants.MTHDCTX_RECEIVER_MAP: - return self.w_receiver_map + if n0 == constants.MTHDCTX_CLOSURE_OR_NIL: + return self.w_closure_or_nil if n0 == constants.MTHDCTX_RECEIVER: return self.w_receiver() - if (0 <= n0-constants.MTHDCTX_TEMP_FRAME_START < - self.tempsize()): + if (0 <= n0-constants.MTHDCTX_TEMP_FRAME_START < self.tempsize()): return self.gettemp(n0-constants.MTHDCTX_TEMP_FRAME_START) else: return ContextPartShadow.fetch(self, n0) @@ -678,8 +685,8 @@ def store(self, n0, w_value): if n0 == constants.MTHDCTX_METHOD: return self.store_w_method(w_value) - if n0 == constants.MTHDCTX_RECEIVER_MAP: - self.w_receiver_map = w_value + if n0 == constants.MTHDCTX_CLOSURE_OR_NIL: + self.w_closure_or_nil = w_value return if n0 == constants.MTHDCTX_RECEIVER: self.store_w_receiver(w_value) @@ -698,7 +705,11 @@ ContextPartShadow.attach_shadow(self) def tempsize(self): - return self.method().tempsize + if self.w_closure_or_nil == self.space.w_nil: + return self.method().tempsize + else: + return wrapper.BlockClosureWrapper(self.space, + self.w_closure_or_nil).tempsize() def w_method(self): return self._w_method diff --git a/spyvm/squeakimage.py b/spyvm/squeakimage.py --- a/spyvm/squeakimage.py +++ b/spyvm/squeakimage.py @@ -11,14 +11,30 @@ first = ord(b[0]) # big endian if first & 0x80 != 0: first = first - 0x100 - return first << 24 | ord(b[1]) << 16 | ord(b[2]) << 8 | ord(b[3]) + return (first << 24 | ord(b[1]) << 16 | ord(b[2]) << 8 | ord(b[3])) def swapped_chrs2int(b): assert len(b) == 4 first = ord(b[3]) # little endian if first & 0x80 != 0: first = first - 0x100 - return first << 24 | ord(b[2]) << 16 | ord(b[1]) << 8 | ord(b[0]) + return (first << 24 | ord(b[2]) << 16 | ord(b[1]) << 8 | ord(b[0])) + +def chrs2long(b): + assert len(b) == 8 + first = ord(b[0]) # big endian + if first & 0x80 != 0: + first = first - 0x100 + return ( first << 56 | ord(b[1]) << 48 | ord(b[2]) << 40 | ord(b[3]) << 32 + | ord(b[4]) << 24 | ord(b[5]) << 16 | ord(b[6]) << 8 | ord(b[7]) ) + +def swapped_chrs2long(b): + assert len(b) == 8 + first = ord(b[7]) # little endian + if first & 0x80 != 0: + first = first - 0x100 + return ( first << 56 | ord(b[6]) << 48 | ord(b[5]) << 40 | ord(b[4]) << 32 + | ord(b[3]) << 24 | ord(b[2]) << 16 | ord(b[1]) << 8 | ord(b[0]) ) # ____________________________________________________________ @@ -32,24 +48,36 @@ self.data = inputfile.read() finally: inputfile.close() - self.swap = False - self.pos = 0 - self.count = 0 + self.reset() def peek(self): if self.pos >= len(self.data): raise IndexError - if self.swap: - return swapped_chrs2int( self.data[self.pos:self.pos+4] ) + data_peek = self.data[self.pos:self.pos + self.word_size] + if self.use_long_read: + if self.swap: + return swapped_chrs2long(data_peek) + else: + return chrs2long(data_peek) else: - return chrs2int( self.data[self.pos:self.pos+4] ) + if self.swap: + return swapped_chrs2int(data_peek) + else: + return chrs2int(data_peek) + def next(self): integer = self.peek() - self.pos += 4 - self.count += 4 + self.pos += self.word_size + self.count += self.word_size return integer + def reset(self): + self.swap = False + self.pos = 0 + self.count = 0 + self.be_32bit() + def reset_count(self): self.count = 0 @@ -59,25 +87,120 @@ self.pos += jump self.count += jump + def skipwords(self, jump): + self.skipbytes(jump * self.word_size) + assert (self.pos + jump) <= len(self.data) + self.pos += jump + self.count += jump + + + def length(self): + return len(self.data) + def close(self): pass # already closed + def be_64bit(self): + self.word_size = 8 + self.use_long_read = True + + def be_32bit(self): + self.word_size = 4 + self.use_long_read = False class CorruptImageError(Exception): pass +class UnsupportedImageError(Exception): + pass + # ____________________________________________________________ -# XXX hack to read Cog images. -# TODO implement Cog float byte reversal -SUPPORTED_VERSIONS = [6502, 6505] +class ImageVersion(object): + + def __init__(self, magic, is_big_endian, is_64bit, has_closures, has_floats_reversed): + self.magic = magic + self.is_big_endian = is_big_endian + self.is_64bit = is_64bit + self.has_closures = has_closures + self.has_floats_reversed = has_floats_reversed + +image_versions = { + 0x00001966: ImageVersion(6502, True, False, False, False), + 0x66190000: ImageVersion(6502, False, False, False, False), + 0x00001968: ImageVersion(6504, True, False, True, False), + 0x68190000: ImageVersion(6504, False, False, True, False), + 0x00001969: ImageVersion(6505, True, False, True, True ), + 0x69190000: ImageVersion(6505, False, False, True, True ), + 0x00000000000109A0: ImageVersion(68000, True, True, False, False), + -0x5ff6ff0000000000: + # signed version of 0xA009010000000000: + ImageVersion(68000, False, True, False, False), + 0x00000000000109A2: ImageVersion(68002, True, True, True, False), + -0x5df6ff0000000000: + # signed version of 0xA209010000000000: + ImageVersion(68002, False, True, True, False), + 0x00000000000109A3: ImageVersion(68003, True, True, True, True ), + -0x5cf6ff0000000000: + # signed version of 0xA309010000000000: + ImageVersion(68003, False, True, True, True ), +} + + +def version(magic): + ver = image_versions.get(magic, None) + if ver is None: + raise CorruptImageError + # if ver.is_64bit or ver.has_floats_reversed: + # raise UnsupportedImageError + return ver + +possible_image_offset = 512 + +def version_from_stream(stream): + # 32 bit + try: + return version(stream.peek()) + except CorruptImageError as e: + if stream.length() > possible_image_offset + 4: + stream.skipbytes(possible_image_offset) + try: + return version(stream.peek()) + except CorruptImageError: + pass # raise original error + # 64 bit + stream.reset() + stream.be_64bit() + try: + v = version(stream.peek()) + assert v.is_64bit + return v + except CorruptImageError as e: + if stream.length() > possible_image_offset + 4: + stream.skipbytes(possible_image_offset) + try: + v = version(stream.peek()) + assert v.is_64bit + return v + except CorruptImageError: + pass # raise original error + raise + + + +def reader_for_image(space, stream): + ver = version_from_stream(stream) + if not ver.is_big_endian: + stream.swap = True + return ImageReader(space, stream, ver) class ImageReader(object): - def __init__(self, space, stream): + def __init__(self, space, stream, version): self.space = space self.stream = stream + self.version = version # dictionary mapping old address to chunk object self.chunks = {} self.chunklist = [] @@ -94,15 +217,13 @@ self.init_w_objects() self.fillin_w_objects() + def read_version(self): + # 1 word version + magic = self.stream.next() + assert self.version.magic == magic + def read_header(self): - # 1 word version - version = self.stream.peek() - if version not in SUPPORTED_VERSIONS: - self.stream.swap = True - version = self.stream.peek() - if version not in SUPPORTED_VERSIONS: - raise CorruptImageError - version = self.stream.next() + self.read_version() #------ # 1 word headersize headersize = self.stream.next() @@ -118,8 +239,7 @@ print "savedwindowssize", savedwindowssize fullscreenflag = self.stream.next() extravmmemory = self.stream.next() - # we called 9 times next, 1 word = 4 byte - self.stream.skipbytes(headersize - (9 * 4)) + self.stream.skipbytes(headersize - self.stream.pos) def read_body(self): import sys diff --git a/spyvm/test/test_interpreter.py b/spyvm/test/test_interpreter.py --- a/spyvm/test/test_interpreter.py +++ b/spyvm/test/test_interpreter.py @@ -76,7 +76,7 @@ return lit return [fakeliteral(lit) for lit in literals] -def new_interpreter(bytes, receiver=space.w_nil): +def new_interpreter(bytes, receiver=space.w_nil, space=space): assert isinstance(bytes, str) w_method = model.W_CompiledMethod(len(bytes)) w_method.islarge = 1 diff --git a/spyvm/test/test_miniimage.py b/spyvm/test/test_miniimage.py --- a/spyvm/test/test_miniimage.py +++ b/spyvm/test/test_miniimage.py @@ -27,7 +27,7 @@ return perform(space.wrap_string(name), "asSymbol") def open_miniimage(space): - return squeakimage.ImageReader(space, squeakimage.Stream(mini_image.open())) + return squeakimage.reader_for_image(space, squeakimage.Stream(mini_image.open())) def get_reader(): return reader diff --git a/spyvm/test/test_primitives.py b/spyvm/test/test_primitives.py --- a/spyvm/test/test_primitives.py +++ b/spyvm/test/test_primitives.py @@ -2,9 +2,7 @@ import math from spyvm.primitives import prim_table, PrimitiveFailedError from spyvm import model, shadow, interpreter -from spyvm import constants -from spyvm import primitives -from spyvm import objspace +from spyvm import constants, primitives, objspace, wrapper from rpython.rlib.rfloat import INFINITY, NAN, isinf, isnan @@ -20,6 +18,7 @@ s_self.reset_stack() s_self.push_all(stack) s_self.store_expected_argument_count(0) + def as_blockcontext_get_shadow(self): self._shadow = shadow.BlockContextShadow(space, self) return self._shadow @@ -33,15 +32,20 @@ if isinstance(x, list): return space.wrap_list(x) raise NotImplementedError -def mock(stack): +def mock(stack, context = None): mapped_stack = [wrap(x) for x in stack] - frame = MockFrame(mapped_stack) + if context is None: + frame = MockFrame(mapped_stack) + else: + frame = context + for i in range(len(stack)): + frame.as_context_get_shadow(space).push(stack[i]) interp = interpreter.Interpreter(space) interp.store_w_active_context(frame) return (interp, len(stack)) -def prim(code, stack): - interp, argument_count = mock(stack) +def prim(code, stack, context = None): + interp, argument_count = mock(stack, context) prim_table[code](interp, argument_count-1) res = interp.s_active_context().pop() assert not interp.s_active_context().stackdepth() # check args are consumed @@ -439,6 +443,57 @@ assert space.unwrap_char(w_c) == os.path.sep +def test_primitive_closure_copyClosure(): + from test_interpreter import new_interpreter + interp = new_interpreter("") + w_block = prim(200, map(wrap, ["anActiveContext", 2, [wrap(1), wrap(2)]]), + interp.w_active_context()) + assert w_block is not space.w_nil + w_w_block = wrapper.BlockClosureWrapper(space, w_block) + assert w_w_block.startpc() is 0 + assert w_w_block.at0(0) == wrap(1) + assert w_w_block.at0(1) == wrap(2) + assert w_w_block.numArgs() is 2 + +def build_up_closure_environment(args, copiedValues=[]): + from test_interpreter import new_interpreter + interp = new_interpreter("", + space=space) + s_initial_context = interp.s_active_context() + + size_arguments = len(args) + closure = space.newClosure(interp.w_active_context(), 4, #pc + size_arguments, copiedValues) + s_initial_context.push_all([closure] + args) + prim_table[201 + size_arguments](interp, size_arguments) + return interp, s_initial_context, closure, interp.s_active_context() + +def test_primitive_closure_value(): + interp, s_initial_context, closure, s_new_context = build_up_closure_environment([]) + + assert s_new_context.w_closure_or_nil is closure + assert s_new_context.s_sender() is s_initial_context + assert s_new_context.w_receiver() is space.w_nil + +def test_primitive_closure_value_value(): + interp, s_initial_context, closure, s_new_context = build_up_closure_environment(["first arg", "second arg"]) + + assert s_new_context.w_closure_or_nil is closure + assert s_new_context.s_sender() is s_initial_context + assert s_new_context.w_receiver() is space.w_nil + assert s_new_context.gettemp(0) == "first arg" + assert s_new_context.gettemp(1) == "second arg" + +def test_primitive_closure_value_value_with_temps(): + interp, s_initial_context, closure, s_new_context = build_up_closure_environment(["first arg", "second arg"], + copiedValues=['some value']) + + assert s_new_context.w_closure_or_nil is closure + assert s_new_context.s_sender() is s_initial_context + assert s_new_context.w_receiver() is space.w_nil + assert s_new_context.gettemp(0) == "first arg" + assert s_new_context.gettemp(1) == "second arg" + assert s_new_context.gettemp(2) == "some value" # Note: # primitives.NEXT is unimplemented as it is a performance optimization diff --git a/spyvm/test/test_shadow.py b/spyvm/test/test_shadow.py --- a/spyvm/test/test_shadow.py +++ b/spyvm/test/test_shadow.py @@ -90,7 +90,7 @@ w_object.store(space, constants.CTXPART_STACKP_INDEX, space.wrap_int(method.tempsize+stackpointer)) w_object.store(space, constants.MTHDCTX_METHOD, method) # XXX - w_object.store(space, constants.MTHDCTX_RECEIVER_MAP, '???') + w_object.store(space, constants.MTHDCTX_CLOSURE_OR_NIL, space.w_nil) w_object.store(space, constants.MTHDCTX_RECEIVER, 'receiver') w_object.store(space, constants.MTHDCTX_TEMP_FRAME_START, 'el') diff --git a/spyvm/test/test_squeakimage.py b/spyvm/test/test_squeakimage.py --- a/spyvm/test/test_squeakimage.py +++ b/spyvm/test/test_squeakimage.py @@ -1,15 +1,16 @@ import py from spyvm import squeakimage -from spyvm.squeakimage import chrs2int +from spyvm.squeakimage import chrs2int, chrs2long, swapped_chrs2long from spyvm import objspace +from struct import pack + space = objspace.ObjSpace() # ----- helpers ---------------------------------------------- def ints2str(*ints): - import struct - return struct.pack(">" + "i" * len(ints), *ints) + return pack(">" + "i" * len(ints), *ints) def joinbits(values, lengths): result = 0 @@ -18,12 +19,18 @@ result += each return result -def imagereader_mock(string): +def imagestream_mock(string): import StringIO f = StringIO.StringIO(string) - stream = squeakimage.Stream(f) - return squeakimage.ImageReader(space, stream) + return squeakimage.Stream(f) +def imagereader_mock(string): + stream = imagestream_mock(string) + return squeakimage.reader_for_image(space, stream) + + +SIMPLE_VERSION_HEADER = pack(">i", 6502) +SIMPLE_VERSION_HEADER_LE = pack("Q", 68002)) + assert 68002 == swapped_chrs2long(pack("i", header_size) # 2 64 byte header + + pack(">i", 0) # 3 no body + + pack(">i", 0) # 4 old base addresss unset + + pack(">i", 0) # 5 no spl objs array + + "\x12\x34\x56\x78" # 6 last hash + + pack(">h", 480) # 7 window 480 height + + pack(">h", 640) # window 640 width + + pack(">i", 0) # 8 not fullscreen + + pack(">i", 0) # 9 no extra memory + + ("\x00" * (header_size - (9 * word_size)))) + r = imagereader_mock(image_1) + # does not raise + r.read_header() + assert r.stream.pos == len(image_1) + + image_2 = (SIMPLE_VERSION_HEADER_LE # 1 + + pack("Q", 68002) # 1 version + + pack(">q", header_size) # 2 64 byte header + + pack(">q", 0) # 3 no body + + pack(">q", 0) # 4 old base addresss unset + + pack(">q", 0) # 5 no spl objs array + + ("\x12\x34\x56\x78" * 2)# 6 last hash + + pack(">H", 480) # 7 window 480 height + + pack(">H", 640) # window 640 width + + pack(">i", 0) # pad + + pack(">q", 0) # 8 not fullscreen + + pack(">q", 0) # 9 no extra memory + + ("\x00" * (header_size - (9 * word_size)))) + r = imagereader_mock(image_1) + # does not raise + r.read_header() + assert r.stream.pos == len(image_1) + + image_2 = (pack("i", 0) # pad + + pack(">q", 0) # 8 not fullscreen + + pack("#numTemps in an Image. + return self.size() + self.numArgs() + + def size(self): + return self._w_self.size() - constants.BLKCLSR_SIZE # XXX Wrappers below are not used yet. class OffsetWrapper(Wrapper): diff --git a/targetimageloadingsmalltalk.py b/targetimageloadingsmalltalk.py --- a/targetimageloadingsmalltalk.py +++ b/targetimageloadingsmalltalk.py @@ -45,7 +45,7 @@ else: print "usage:", argv[0], "" return -1 - reader = squeakimage.ImageReader(space, squeakimage.Stream(DummyFile(filename))) + reader = squeakimage.reader_for_image(space, squeakimage.Stream(DummyFile(filename))) reader.initialize() image = squeakimage.SqueakImage() image.from_reader(space, reader) From noreply at buildbot.pypy.org Fri Feb 22 12:13:53 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Fri, 22 Feb 2013 12:13:53 +0100 (CET) Subject: [pypy-commit] pypy py3k: 2to3 Message-ID: <20130222111353.755A11C0228@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: py3k Changeset: r61596:e198fe7b0d06 Date: 2013-02-22 12:12 +0100 http://bitbucket.org/pypy/pypy/changeset/e198fe7b0d06/ Log: 2to3 diff --git a/pypy/interpreter/test/test_executioncontext.py b/pypy/interpreter/test/test_executioncontext.py --- a/pypy/interpreter/test/test_executioncontext.py +++ b/pypy/interpreter/test/test_executioncontext.py @@ -269,7 +269,7 @@ import gc class X(object): def __del__(self): - print "Called", self.num + print("Called", self.num) def f(): x1 = X(); x1.num = 1 x2 = X(); x2.num = 2 @@ -285,7 +285,7 @@ # test the behavior fixed in r71420: before, only one __del__ # would be called import os, sys - print sys.executable, self.tmpfile + print(sys.executable, self.tmpfile) if sys.platform == "win32": cmdformat = '"%s" "%s"' else: From noreply at buildbot.pypy.org Fri Feb 22 12:55:16 2013 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 22 Feb 2013 12:55:16 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: fix alignment issue Message-ID: <20130222115516.8FA1C1C01BF@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61597:8adfb7e84b81 Date: 2013-02-22 13:54 +0200 http://bitbucket.org/pypy/pypy/changeset/8adfb7e84b81/ Log: fix alignment issue diff --git a/rpython/jit/backend/llsupport/test/test_gc_integration.py b/rpython/jit/backend/llsupport/test/test_gc_integration.py --- a/rpython/jit/backend/llsupport/test/test_gc_integration.py +++ b/rpython/jit/backend/llsupport/test/test_gc_integration.py @@ -383,6 +383,7 @@ ('jf_frame_info', lltype.Ptr(jitframe.JITFRAMEINFO)), ('jf_descr', llmemory.GCREF), ('jf_force_descr', llmemory.GCREF), + ('jf_extra_stack_depth', lltype.Signed), ('jf_guard_exc', llmemory.GCREF), ('jf_gcmap', lltype.Ptr(jitframe.GCMAP)), ('jf_gc_trace_state', lltype.Signed), @@ -460,7 +461,7 @@ descrs = JitFrameDescrs() descrs.arraydescr = cpu.arraydescrof(JITFRAME) for name in ['jf_descr', 'jf_guard_exc', 'jf_force_descr', - 'jf_frame_info', 'jf_gcmap']: + 'jf_frame_info', 'jf_gcmap', 'jf_extra_stack_depth']: setattr(descrs, name, cpu.fielddescrof(JITFRAME, name)) descrs.jfi_frame_depth = cpu.fielddescrof(jitframe.JITFRAMEINFO, 'jfi_frame_depth') diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -204,7 +204,7 @@ jz_location = mc.get_relative_pos() # nursery_free_adr = self.cpu.gc_ll_descr.get_nursery_free_addr() - self._reload_frame_if_necessary(mc) + self._reload_frame_if_necessary(mc, align_stack=True) mc.MOV_bi(extra_ofs, 0) self._pop_all_regs_from_frame(mc, [eax, edi], self.cpu.supports_floats) mc.MOV(edi, heap(nursery_free_adr)) # load this in EDI @@ -327,12 +327,8 @@ else: mc.MOV_rs(edi.value, WORD) else: - # we're possibly called from the slowpath of malloc, so we have - # one extra CALL on the stack, but one less PUSH, - # save to store stuff 2 locations away on the stack. - # we have to save all the things that can potentially - # be returned from a call - mc.SUB_ri(esp.value, 10 * WORD) # align and reserve some space + # we have one word to align + mc.SUB_ri(esp.value, 7 * WORD) # align and reserve some space mc.MOV_sr(WORD, eax.value) # save for later mc.MOVSD_sx(3 * WORD, xmm0.value) if IS_X86_32: @@ -378,7 +374,7 @@ self._restore_exception(mc, exc0, exc1) mc.MOV(exc0, RawEspLoc(WORD * 5, REF)) mc.MOV(exc1, RawEspLoc(WORD * 6, INT)) - mc.LEA_rs(esp.value, 10 * WORD) + mc.LEA_rs(esp.value, 7 * WORD) mc.RET() rawstart = mc.materialize(self.cpu.asmmemmgr, []) @@ -1237,7 +1233,7 @@ if can_collect: self.pop_gcmap(self.mc) - def _reload_frame_if_necessary(self, mc): + def _reload_frame_if_necessary(self, mc, align_stack=False): gcrootmap = self.cpu.gc_ll_descr.gcrootmap if gcrootmap and gcrootmap.is_shadow_stack: rst = gcrootmap.get_root_stack_top_addr() @@ -1248,7 +1244,7 @@ # frame never uses card marking, so we enforce this is not # an array self._write_barrier_fastpath(mc, wbdescr, [ebp], array=False, - is_frame=True) + is_frame=True, align_stack=align_stack) def call(self, addr, args, res): self._emit_call(imm(addr), args) @@ -2281,7 +2277,7 @@ # ------------------- END CALL ASSEMBLER ----------------------- def _write_barrier_fastpath(self, mc, descr, arglocs, array=False, - is_frame=False): + is_frame=False, align_stack=False): # Write code equivalent to write_barrier() in the GC: it checks # a flag in the object at arglocs[0], and if set, it calls a # helper piece of assembler. The latter saves registers as needed @@ -2337,7 +2333,11 @@ # if not is_frame: mc.PUSH(loc_base) + if is_frame and align_stack: + mc.SUB_ri(esp.value, 16 - WORD) # erase the return address mc.CALL(imm(self.wb_slowpath[helper_num])) + if is_frame and align_stack: + mc.ADD_ri(esp.value, 16 - WORD) # erase the return address if card_marking: # The helper ends again with a check of the flag in the object. From noreply at buildbot.pypy.org Fri Feb 22 13:07:32 2013 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 22 Feb 2013 13:07:32 +0100 (CET) Subject: [pypy-commit] pypy stm-thread-2: Test and fix Message-ID: <20130222120732.41E7B1C01BF@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stm-thread-2 Changeset: r61598:62ed6ba35d69 Date: 2013-02-22 12:43 +0100 http://bitbucket.org/pypy/pypy/changeset/62ed6ba35d69/ Log: Test and fix diff --git a/rpython/translator/stm/src_stm/rpyintf.c b/rpython/translator/stm/src_stm/rpyintf.c --- a/rpython/translator/stm/src_stm/rpyintf.c +++ b/rpython/translator/stm/src_stm/rpyintf.c @@ -198,15 +198,20 @@ void stm_abort_info_push(void *obj, void *fieldoffsets) { - struct tx_descriptor *d = thread_descriptor; - gcptrlist_insert2(&d->abortinfo, (gcptr)obj, (gcptr)fieldoffsets); + struct tx_descriptor *d = thread_descriptor; + gcptr P = (gcptr)obj; + if ((P->h_tid & GCFLAG_GLOBAL) && + (P->h_tid & GCFLAG_POSSIBLY_OUTDATED)) { + P = LatestGlobalRevision(d, P, NULL, 0); + } + gcptrlist_insert2(&d->abortinfo, P, (gcptr)fieldoffsets); } void stm_abort_info_pop(long count) { - struct tx_descriptor *d = thread_descriptor; - long newsize = d->abortinfo.size - 2 * count; - gcptrlist_reduce_size(&d->abortinfo, newsize < 0 ? 0 : newsize); + struct tx_descriptor *d = thread_descriptor; + long newsize = d->abortinfo.size - 2 * count; + gcptrlist_reduce_size(&d->abortinfo, newsize < 0 ? 0 : newsize); } size_t _stm_decode_abort_info(struct tx_descriptor *d, char *output) @@ -224,7 +229,7 @@ } WRITE('l'); for (i=0; iabortinfo.size; i+=2) { - char *object = (char*)d->abortinfo.items[i+0]; + char *object = (char *)stm_RepeatReadBarrier(d->abortinfo.items[i+0]); long *fieldoffsets = (long*)d->abortinfo.items[i+1]; long kind, offset; char buffer[32]; @@ -258,10 +263,15 @@ break; case 3: /* pointer to STR */ rps = *(RPyString **)(object + offset); - rps_size = RPyString_Size(rps); - res_size = sprintf(buffer, "%zu:", rps_size); - WRITE_BUF(buffer, res_size); - WRITE_BUF(_RPyString_AsString(rps), rps_size); + if (rps) { + rps_size = RPyString_Size(rps); + res_size = sprintf(buffer, "%zu:", rps_size); + WRITE_BUF(buffer, res_size); + WRITE_BUF(_RPyString_AsString(rps), rps_size); + } + else { + WRITE_BUF("0:", 2); + } break; default: fprintf(stderr, "Fatal RPython error: corrupted abort log\n"); diff --git a/rpython/translator/stm/test/test_ztranslated.py b/rpython/translator/stm/test/test_ztranslated.py --- a/rpython/translator/stm/test/test_ztranslated.py +++ b/rpython/translator/stm/test/test_ztranslated.py @@ -138,9 +138,13 @@ pass globf = Foobar() + def setxy(globf, retry_counter): + if retry_counter > 1: + globf.xy = 100 + retry_counter + def check(_, retry_counter): - globf.xy = 100 + retry_counter rstm.abort_info_push(globf, ('xy', '[', 'yx', ']')) + setxy(globf, retry_counter) if retry_counter < 3: rstm.abort_and_retry() # From noreply at buildbot.pypy.org Fri Feb 22 13:07:33 2013 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 22 Feb 2013 13:07:33 +0100 (CET) Subject: [pypy-commit] pypy stm-thread-2: Fix Message-ID: <20130222120733.799B11C01BF@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stm-thread-2 Changeset: r61599:cf4450c80c67 Date: 2013-02-22 12:50 +0100 http://bitbucket.org/pypy/pypy/changeset/cf4450c80c67/ Log: Fix diff --git a/rpython/translator/stm/funcgen.py b/rpython/translator/stm/funcgen.py --- a/rpython/translator/stm/funcgen.py +++ b/rpython/translator/stm/funcgen.py @@ -50,7 +50,7 @@ def stm_extraref_lladdr(funcgen, op): arg0 = funcgen.expr(op.args[0]) result = funcgen.expr(op.result) - return '%s = stm_extraref_lladdr(%s);' % (result, arg0) + return '%s = (char *)stm_extraref_lladdr(%s);' % (result, arg0) def _stm_nogc_init_function(): """Called at process start-up when running with no GC.""" diff --git a/rpython/translator/stm/src_stm/et.h b/rpython/translator/stm/src_stm/et.h --- a/rpython/translator/stm/src_stm/et.h +++ b/rpython/translator/stm/src_stm/et.h @@ -126,7 +126,7 @@ void stm_abort_info_pop(long); char *stm_inspect_abort_info(void); long stm_extraref_llcount(void); -gcptr stm_extraref_lladdr(long); +gcptr *stm_extraref_lladdr(long); #ifdef USING_NO_GC_AT_ALL # define OP_GC_ADR_OF_ROOT_STACK_TOP(r) r = NULL diff --git a/rpython/translator/stm/src_stm/rpyintf.c b/rpython/translator/stm/src_stm/rpyintf.c --- a/rpython/translator/stm/src_stm/rpyintf.c +++ b/rpython/translator/stm/src_stm/rpyintf.c @@ -297,10 +297,10 @@ return d->abortinfo.size / 2; } -gcptr stm_extraref_lladdr(long index) +gcptr *stm_extraref_lladdr(long index) { struct tx_descriptor *d = thread_descriptor; - return d->abortinfo.items[index * 2]; + return &d->abortinfo.items[index * 2]; } #ifdef USING_NO_GC_AT_ALL From noreply at buildbot.pypy.org Fri Feb 22 13:34:15 2013 From: noreply at buildbot.pypy.org (RonnyPfannschmidt) Date: Fri, 22 Feb 2013 13:34:15 +0100 (CET) Subject: [pypy-commit] pypy pytest-update: merge default Message-ID: <20130222123415.838931C0228@cobra.cs.uni-duesseldorf.de> Author: Ronny Pfannschmidt Branch: pytest-update Changeset: r61600:d79c78a22eec Date: 2013-02-22 13:33 +0100 http://bitbucket.org/pypy/pypy/changeset/d79c78a22eec/ Log: merge default diff too long, truncating to 2000 out of 6880 lines diff --git a/lib-python/2.7/test/test_generators.py b/lib-python/2.7/test/test_generators.py --- a/lib-python/2.7/test/test_generators.py +++ b/lib-python/2.7/test/test_generators.py @@ -1501,9 +1501,7 @@ """ coroutine_tests = """\ -A helper function to call gc.collect() without printing ->>> import gc ->>> def gc_collect(): gc.collect() +>>> from test.test_support import gc_collect Sending a value into a started generator: @@ -1823,8 +1821,7 @@ references. We add it to the standard suite so the routine refleak-tests would trigger if it starts being uncleanable again. ->>> import gc ->>> def gc_collect(): gc.collect() +>>> from test.test_support import gc_collect >>> import itertools >>> def leak(): diff --git a/lib-python/2.7/urllib.py b/lib-python/2.7/urllib.py --- a/lib-python/2.7/urllib.py +++ b/lib-python/2.7/urllib.py @@ -1205,15 +1205,17 @@ # fastpath if len(res) == 1: return s - s = res[0] - for item in res[1:]: + res_list = [res[0]] + for j in xrange(1, len(res)): + item = res[j] try: - s += _hextochr[item[:2]] + item[2:] + x = _hextochr[item[:2]] + item[2:] except KeyError: - s += '%' + item + x = '%' + item except UnicodeDecodeError: - s += unichr(int(item[:2], 16)) + item[2:] - return s + x = unichr(int(item[:2], 16)) + item[2:] + res_list.append(x) + return ''.join(res_list) def unquote_plus(s): """unquote('%7e/abc+def') -> '~/abc def'""" diff --git a/lib-python/2.7/urlparse.py b/lib-python/2.7/urlparse.py --- a/lib-python/2.7/urlparse.py +++ b/lib-python/2.7/urlparse.py @@ -321,15 +321,17 @@ # fastpath if len(res) == 1: return s - s = res[0] - for item in res[1:]: + res_list = [res[0]] + for j in xrange(1, len(res)): + item = res[j] try: - s += _hextochr[item[:2]] + item[2:] + x = _hextochr[item[:2]] + item[2:] except KeyError: - s += '%' + item + x = '%' + item except UnicodeDecodeError: - s += unichr(int(item[:2], 16)) + item[2:] - return s + x = unichr(int(item[:2], 16)) + item[2:] + res_list.append(x) + return ''.join(res_list) def parse_qs(qs, keep_blank_values=0, strict_parsing=0): """Parse a query given as a string argument. diff --git a/lib-python/conftest.py b/lib-python/conftest.py --- a/lib-python/conftest.py +++ b/lib-python/conftest.py @@ -272,7 +272,7 @@ RegrTest('test_inspect.py'), RegrTest('test_int.py', core=True), RegrTest('test_int_literal.py', core=True), - RegrTest('test_io.py'), + RegrTest('test_io.py', usemodules='array binascii'), RegrTest('test_ioctl.py'), RegrTest('test_isinstance.py', core=True), RegrTest('test_iter.py', core=True), diff --git a/lib_pypy/datetime.py b/lib_pypy/datetime.py --- a/lib_pypy/datetime.py +++ b/lib_pypy/datetime.py @@ -271,6 +271,8 @@ raise ValueError("%s()=%d, must be in -1439..1439" % (name, offset)) def _check_int_field(value): + if isinstance(value, int): + return value if not isinstance(value, float): try: value = value.__int__() @@ -279,7 +281,7 @@ else: if isinstance(value, (int, long)): return value - raise TypeError('integer argument expected') + raise TypeError('an integer is required') def _check_date_fields(year, month, day): year = _check_int_field(year) @@ -457,6 +459,8 @@ felt like it. """ + __slots__ = '_days', '_seconds', '_microseconds' + def __new__(cls, days=0, seconds=0, microseconds=0, # XXX The following should only be used as keyword args: milliseconds=0, minutes=0, hours=0, weeks=0): @@ -770,6 +774,8 @@ year, month, day """ + __slots__ = '_year', '_month', '_day' + def __new__(cls, year, month=None, day=None): """Constructor. @@ -777,7 +783,7 @@ year, month, day (required, base 1) """ - if isinstance(year, str): + if isinstance(year, str) and len(year) == 4: # Pickle support self = object.__new__(cls) self.__setstate(year) @@ -1063,6 +1069,8 @@ Subclasses must override the name(), utcoffset() and dst() methods. """ + __slots__ = () + def tzname(self, dt): "datetime -> string name of time zone." raise NotImplementedError("tzinfo subclass must override tzname()") @@ -1155,6 +1163,8 @@ hour, minute, second, microsecond, tzinfo """ + __slots__ = '_hour', '_minute', '_second', '_microsecond', '_tzinfo' + def __new__(cls, hour=0, minute=0, second=0, microsecond=0, tzinfo=None): """Constructor. @@ -1457,9 +1467,11 @@ instance of a tzinfo subclass. The remaining arguments may be ints or longs. """ + __slots__ = date.__slots__ + time.__slots__ + def __new__(cls, year, month=None, day=None, hour=0, minute=0, second=0, microsecond=0, tzinfo=None): - if isinstance(year, str): + if isinstance(year, str) and len(year) == 10: # Pickle support self = date.__new__(cls, year[:4]) self.__setstate(year, month) diff --git a/pypy/doc/_ref.txt b/pypy/doc/_ref.txt --- a/pypy/doc/_ref.txt +++ b/pypy/doc/_ref.txt @@ -1,24 +1,19 @@ .. _`ctypes_configure/doc/sample.py`: https://bitbucket.org/pypy/pypy/src/default/ctypes_configure/doc/sample.py -.. _`demo/`: https://bitbucket.org/pypy/pypy/src/default/demo/ +.. _`dotviewer/`: https://bitbucket.org/pypy/pypy/src/default/dotviewer/ .. _`lib-python/`: https://bitbucket.org/pypy/pypy/src/default/lib-python/ .. _`lib-python/2.7/dis.py`: https://bitbucket.org/pypy/pypy/src/default/lib-python/2.7/dis.py .. _`lib_pypy/`: https://bitbucket.org/pypy/pypy/src/default/lib_pypy/ .. _`lib_pypy/greenlet.py`: https://bitbucket.org/pypy/pypy/src/default/lib_pypy/greenlet.py .. _`lib_pypy/pypy_test/`: https://bitbucket.org/pypy/pypy/src/default/lib_pypy/pypy_test/ .. _`lib_pypy/tputil.py`: https://bitbucket.org/pypy/pypy/src/default/lib_pypy/tputil.py -.. _`pypy/annotation`: -.. _`pypy/annotation/`: https://bitbucket.org/pypy/pypy/src/default/pypy/annotation/ -.. _`pypy/annotation/annrpython.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/annotation/annrpython.py -.. _`pypy/annotation/binaryop.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/annotation/binaryop.py -.. _`pypy/annotation/builtin.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/annotation/builtin.py .. _`pypy/bin/`: https://bitbucket.org/pypy/pypy/src/default/pypy/bin/ -.. _`pypy/bin/translatorshell.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/bin/translatorshell.py +.. _`pypy/bin/pyinteractive.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/bin/pyinteractive.py .. _`pypy/config/`: https://bitbucket.org/pypy/pypy/src/default/pypy/config/ .. _`pypy/config/pypyoption.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/config/pypyoption.py -.. _`pypy/config/translationoption.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/config/translationoption.py .. _`pypy/doc/`: https://bitbucket.org/pypy/pypy/src/default/pypy/doc/ .. _`pypy/doc/config/`: https://bitbucket.org/pypy/pypy/src/default/pypy/doc/config/ .. _`pypy/doc/discussion/`: https://bitbucket.org/pypy/pypy/src/default/pypy/doc/discussion/ +.. _`pypy/goal/`: https://bitbucket.org/pypy/pypy/src/default/pypy/goal/ .. _`pypy/interpreter`: .. _`pypy/interpreter/`: https://bitbucket.org/pypy/pypy/src/default/pypy/interpreter/ .. _`pypy/interpreter/argument.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/interpreter/argument.py @@ -54,11 +49,8 @@ .. _`pypy/module`: .. _`pypy/module/`: https://bitbucket.org/pypy/pypy/src/default/pypy/module/ .. _`pypy/module/__builtin__/__init__.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/module/__builtin__/__init__.py -.. _`pypy/objspace`: .. _`pypy/objspace/`: https://bitbucket.org/pypy/pypy/src/default/pypy/objspace/ -.. _`pypy/objspace/flow`: .. _`pypy/objspace/flow/`: https://bitbucket.org/pypy/pypy/src/default/pypy/objspace/flow/ -.. _`pypy/objspace/flow/model.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/objspace/flow/model.py .. _`pypy/objspace/std`: .. _`pypy/objspace/std/`: https://bitbucket.org/pypy/pypy/src/default/pypy/objspace/std/ .. _`pypy/objspace/std/listtype.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/objspace/std/listtype.py @@ -70,49 +62,55 @@ .. _`pypy/objspace/std/transparent.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/objspace/std/transparent.py .. _`pypy/objspace/std/tupleobject.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/objspace/std/tupleobject.py .. _`pypy/objspace/std/tupletype.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/objspace/std/tupletype.py -.. _`pypy/rlib`: -.. _`pypy/rlib/`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/ -.. _`pypy/rlib/listsort.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/listsort.py -.. _`pypy/rlib/nonconst.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/nonconst.py -.. _`pypy/rlib/objectmodel.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/objectmodel.py -.. _`pypy/rlib/parsing/`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/parsing/ -.. _`pypy/rlib/parsing/tree.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/parsing/tree.py -.. _`pypy/rlib/rarithmetic.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/rarithmetic.py -.. _`pypy/rlib/rbigint.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/rbigint.py -.. _`pypy/rlib/rrandom.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/rrandom.py -.. _`pypy/rlib/rsocket.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/rsocket.py -.. _`pypy/rlib/streamio.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/streamio.py -.. _`pypy/rlib/test`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/test/ -.. _`pypy/rlib/unroll.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/unroll.py -.. _`pypy/rpython`: -.. _`pypy/rpython/`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/ -.. _`pypy/rpython/lltypesystem/`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/lltypesystem/ -.. _`pypy/rpython/lltypesystem/lltype.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/lltypesystem/lltype.py -.. _`pypy/rpython/memory/`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/memory/ -.. _`pypy/rpython/memory/gc/generation.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/memory/gc/generation.py -.. _`pypy/rpython/memory/gc/hybrid.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/memory/gc/hybrid.py -.. _`pypy/rpython/memory/gc/markcompact.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/memory/gc/markcompact.py -.. _`pypy/rpython/memory/gc/marksweep.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/memory/gc/marksweep.py -.. _`pypy/rpython/memory/gc/minimarkpage.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/memory/gc/minimarkpage.py -.. _`pypy/rpython/memory/gc/semispace.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/memory/gc/semispace.py -.. _`pypy/rpython/ootypesystem/`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/ootypesystem/ -.. _`pypy/rpython/ootypesystem/ootype.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/ootypesystem/ootype.py -.. _`pypy/rpython/rint.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/rint.py -.. _`pypy/rpython/rlist.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/rlist.py -.. _`pypy/rpython/rmodel.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/rmodel.py -.. _`pypy/rpython/rtyper.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/rtyper.py -.. _`pypy/rpython/test/test_llinterp.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/test/test_llinterp.py .. _`pypy/tool/`: https://bitbucket.org/pypy/pypy/src/default/pypy/tool/ .. _`pypy/tool/algo/`: https://bitbucket.org/pypy/pypy/src/default/pypy/tool/algo/ .. _`pypy/tool/pytest/`: https://bitbucket.org/pypy/pypy/src/default/pypy/tool/pytest/ -.. _`pypy/tool/traceconfig.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/tool/traceconfig.py -.. _`pypy/translator`: -.. _`pypy/translator/`: https://bitbucket.org/pypy/pypy/src/default/pypy/translator/ -.. _`pypy/translator/backendopt/`: https://bitbucket.org/pypy/pypy/src/default/pypy/translator/backendopt/ -.. _`pypy/translator/c/`: https://bitbucket.org/pypy/pypy/src/default/pypy/translator/c/ -.. _`pypy/translator/c/src/stacklet/`: https://bitbucket.org/pypy/pypy/src/default/pypy/translator/c/src/stacklet/ -.. _`pypy/translator/c/src/stacklet/stacklet.h`: https://bitbucket.org/pypy/pypy/src/default/pypy/translator/c/src/stacklet/stacklet.h -.. _`pypy/translator/cli/`: https://bitbucket.org/pypy/pypy/src/default/pypy/translator/cli/ -.. _`pypy/translator/goal/`: https://bitbucket.org/pypy/pypy/src/default/pypy/translator/goal/ -.. _`pypy/translator/jvm/`: https://bitbucket.org/pypy/pypy/src/default/pypy/translator/jvm/ -.. _`pypy/translator/tool/`: https://bitbucket.org/pypy/pypy/src/default/pypy/translator/tool/ +.. _`rpython/annotator`: +.. _`rpython/annotator/`: https://bitbucket.org/pypy/pypy/src/default/rpython/annotator/ +.. _`rpython/annotator/annrpython.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/annotator/annrpython.py +.. _`rpython/annotator/binaryop.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/annotator/binaryop.py +.. _`rpython/annotator/builtin.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/annotator/builtin.py +.. _`rpython/bin/translatorshell.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/bin/translatorshell.py +.. _`rpython/config/`: https://bitbucket.org/pypy/pypy/src/default/rpython/config/ +.. _`rpython/config/translationoption.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/config/translationoption.py +.. _`rpython/flowspace/`: https://bitbucket.org/pypy/pypy/src/default/rpython/flowspace/ +.. _`rpython/flowspace/model.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/flowspace/model.py +.. _`rpython/rlib`: +.. _`rpython/rlib/`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/ +.. _`rpython/rlib/listsort.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/listsort.py +.. _`rpython/rlib/nonconst.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/nonconst.py +.. _`rpython/rlib/objectmodel.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/objectmodel.py +.. _`rpython/rlib/parsing/`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/parsing/ +.. _`rpython/rlib/parsing/tree.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/parsing/tree.py +.. _`rpython/rlib/rarithmetic.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/rarithmetic.py +.. _`rpython/rlib/rbigint.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/rbigint.py +.. _`rpython/rlib/rrandom.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/rrandom.py +.. _`rpython/rlib/rsocket.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/rsocket.py +.. _`rpython/rlib/streamio.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/streamio.py +.. _`rpython/rlib/test`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/test/ +.. _`rpython/rlib/unroll.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/unroll.py +.. _`rpython/rtyper`: +.. _`rpython/rtyper/`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/ +.. _`rpython/rtyper/lltypesystem/`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/lltypesystem/ +.. _`rpython/rtyper/lltypesystem/lltype.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/lltypesystem/lltype.py +.. _`rpython/rtyper/memory/`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/memory/ +.. _`rpython/rtyper/memory/gc/generation.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/memory/gc/generation.py +.. _`rpython/rtyper/memory/gc/hybrid.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/memory/gc/hybrid.py +.. _`rpython/rtyper/memory/gc/minimarkpage.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/memory/gc/minimarkpage.py +.. _`rpython/rtyper/memory/gc/semispace.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/memory/gc/semispace.py +.. _`rpython/rtyper/ootypesystem/`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/ootypesystem/ +.. _`rpython/rtyper/ootypesystem/ootype.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/ootypesystem/ootype.py +.. _`rpython/rtyper/rint.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/rint.py +.. _`rpython/rtyper/rlist.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/rlist.py +.. _`rpython/rtyper/rmodel.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/rmodel.py +.. _`rpython/rtyper/rtyper.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/rtyper.py +.. _`rpython/rtyper/test/test_llinterp.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/test/test_llinterp.py +.. _`rpython/translator`: +.. _`rpython/translator/`: https://bitbucket.org/pypy/pypy/src/default/rpython/translator/ +.. _`rpython/translator/backendopt/`: https://bitbucket.org/pypy/pypy/src/default/rpython/translator/backendopt/ +.. _`rpython/translator/c/`: https://bitbucket.org/pypy/pypy/src/default/rpython/translator/c/ +.. _`rpython/translator/c/src/stacklet/`: https://bitbucket.org/pypy/pypy/src/default/rpython/translator/c/src/stacklet/ +.. _`rpython/translator/c/src/stacklet/stacklet.h`: https://bitbucket.org/pypy/pypy/src/default/rpython/translator/c/src/stacklet/stacklet.h +.. _`rpython/translator/cli/`: https://bitbucket.org/pypy/pypy/src/default/rpython/translator/cli/ +.. _`rpython/translator/jvm/`: https://bitbucket.org/pypy/pypy/src/default/rpython/translator/jvm/ +.. _`rpython/translator/tool/`: https://bitbucket.org/pypy/pypy/src/default/rpython/translator/tool/ diff --git a/pypy/doc/coding-guide.rst b/pypy/doc/coding-guide.rst --- a/pypy/doc/coding-guide.rst +++ b/pypy/doc/coding-guide.rst @@ -303,7 +303,7 @@ dicts with a unique key type only, provided it is hashable. Custom hash functions and custom equality will not be honored. - Use ``pypy.rlib.objectmodel.r_dict`` for custom hash functions. + Use ``rpython.rlib.objectmodel.r_dict`` for custom hash functions. **list comprehensions** @@ -328,7 +328,7 @@ **builtin functions** A number of builtin functions can be used. The precise set can be - found in `pypy/annotation/builtin.py`_ (see ``def builtin_xxx()``). + found in `rpython/annotator/builtin.py`_ (see ``def builtin_xxx()``). Some builtin functions may be limited in what they support, though. ``int, float, str, ord, chr``... are available as simple conversion @@ -365,7 +365,7 @@ We use normal integers for signed arithmetic. It means that before translation we get longs in case of overflow, and after translation we get a silent wrap-around. Whenever we need more control, we use the following -helpers (which live the `pypy/rlib/rarithmetic.py`_): +helpers (which live in `rpython/rlib/rarithmetic.py`_): **ovfcheck()** diff --git a/pypy/doc/configuration.rst b/pypy/doc/configuration.rst --- a/pypy/doc/configuration.rst +++ b/pypy/doc/configuration.rst @@ -188,7 +188,7 @@ toolchain`_ toolchain, have two separate sets of options. The translation toolchain options can be found on the ``config`` attribute of all ``TranslationContext`` -instances and are described in `pypy/config/translationoption.py`_. The interpreter options +instances and are described in `rpython/config/translationoption.py`_. The interpreter options are attached to the object space, also under the name ``config`` and are described in `pypy/config/pypyoption.py`_. diff --git a/pypy/doc/ctypes-implementation.rst b/pypy/doc/ctypes-implementation.rst --- a/pypy/doc/ctypes-implementation.rst +++ b/pypy/doc/ctypes-implementation.rst @@ -38,7 +38,7 @@ in dynamic libraries through libffi. Freeing objects in most cases and making sure that objects referring to each other are kept alive is responsibility of the higher levels. -This module uses bindings to libffi which are defined in ``pypy/rlib/libffi.py``. +This module uses bindings to libffi which are defined in ``rpython/rlib/libffi.py``. We tried to keep this module as small as possible. It is conceivable that other implementations (e.g. Jython) could use our ctypes diff --git a/pypy/doc/discussion/improve-rpython.rst b/pypy/doc/discussion/improve-rpython.rst --- a/pypy/doc/discussion/improve-rpython.rst +++ b/pypy/doc/discussion/improve-rpython.rst @@ -39,7 +39,7 @@ - Allocate variables on the stack, and pass their address ("by reference") to llexternal functions. For a typical usage, see - `pypy.rlib.rsocket.RSocket.getsockopt_int`. + `rpython.rlib.rsocket.RSocket.getsockopt_int`. Extensible type system for llexternal ------------------------------------- diff --git a/pypy/doc/garbage_collection.rst b/pypy/doc/garbage_collection.rst --- a/pypy/doc/garbage_collection.rst +++ b/pypy/doc/garbage_collection.rst @@ -42,7 +42,7 @@ Two arenas of equal size, with only one arena in use and getting filled with new objects. When the arena is full, the live objects are copied into the other arena using Cheney's algorithm. The old arena is then -cleared. See `pypy/rpython/memory/gc/semispace.py`_. +cleared. See `rpython/rtyper/memory/gc/semispace.py`_. On Unix the clearing is done by reading ``/dev/zero`` into the arena, which is extremely memory efficient at least on Linux: it lets the @@ -55,7 +55,7 @@ Generational GC --------------- -This is a two-generations GC. See `pypy/rpython/memory/gc/generation.py`_. +This is a two-generations GC. See `rpython/rtyper/memory/gc/generation.py`_. It is implemented as a subclass of the Semispace copying collector. It adds a nursery, which is a chunk of the current semispace. Its size is @@ -86,7 +86,7 @@ Each generation is collected much less often than the previous one. The division of the generations is slightly more complicated than just nursery / semispace / external; see the diagram at the start of the -source code, in `pypy/rpython/memory/gc/hybrid.py`_. +source code, in `rpython/rtyper/memory/gc/hybrid.py`_. Mark & Compact GC ----------------- @@ -161,7 +161,7 @@ to the old stage. The dying case 2 objects are immediately freed. - The old stage is an area of memory containing old (small) objects. It - is handled by `pypy/rpython/memory/gc/minimarkpage.py`_. It is organized + is handled by `rpython/rtyper/memory/gc/minimarkpage.py`_. It is organized as "arenas" of 256KB or 512KB, subdivided into "pages" of 4KB or 8KB. Each page can either be free, or contain small objects of all the same size. Furthermore at any point in time each object location can be diff --git a/pypy/doc/getting-started-dev.rst b/pypy/doc/getting-started-dev.rst --- a/pypy/doc/getting-started-dev.rst +++ b/pypy/doc/getting-started-dev.rst @@ -58,8 +58,7 @@ only use low level types that are available in C (e.g. int). The compiled version is now in a ``.so`` library. You can run it say using ctypes: - >>> from ctypes import CDLL - >>> f = CDLL(lib) + >>> f = get_c_function(lib, snippet.is_perfect_number) >>> f(5) 0 >>> f(6) @@ -173,23 +172,23 @@ ``xxxobject.py`` contain respectively the definition of the type and its (default) implementation. -* `pypy/translator`_ contains the code analysis and generation stuff. +* `rpython/translator`_ contains the code analysis and generation stuff. Start reading from translator.py, from which it should be easy to follow the pieces of code involved in the various translation phases. -* `pypy/annotation`_ contains the data model for the type annotation that +* `rpython/annotator`_ contains the data model for the type annotation that can be inferred about a graph. The graph "walker" that uses this is in - `pypy/annotation/annrpython.py`_. + `rpython/annotator/annrpython.py`_. -* `pypy/rpython`_ contains the code of the RPython typer. The typer transforms +* `rpython/rtyper`_ contains the code of the RPython typer. The typer transforms annotated flow graphs in a way that makes them very similar to C code so that they can be easy translated. The graph transformations are controlled - by the code in `pypy/rpython/rtyper.py`_. The object model that is used can - be found in `pypy/rpython/lltypesystem/lltype.py`_. For each RPython type + by the code in `rpython/rtyper/rtyper.py`_. The object model that is used can + be found in `rpython/rtyper/lltypesystem/lltype.py`_. For each RPython type there is a file rxxxx.py that contains the low level functions needed for this type. -* `pypy/rlib`_ contains the `RPython standard library`_, things that you can +* `rpython/rlib`_ contains the `RPython standard library`_, things that you can use from rpython. .. _`RPython standard library`: rlib.html @@ -320,10 +319,10 @@ Demos ------- -The `demo/`_ directory contains examples of various aspects of PyPy, -ranging from running regular Python programs (that we used as compliance goals) -over experimental distribution mechanisms to examples translating -sufficiently static programs into low level code. +The `example-interpreter`_ repository contains an example interpreter +written using the RPython translation toolchain. + +.. _`example-interpreter`: https://bitbucket.org/pypy/example-interpreter Additional Tools for running (and hacking) PyPy ----------------------------------------------- diff --git a/pypy/doc/index.rst b/pypy/doc/index.rst --- a/pypy/doc/index.rst +++ b/pypy/doc/index.rst @@ -217,17 +217,20 @@ Here is a fully referenced alphabetical two-level deep directory overview of PyPy: -================================ =========================================== +================================= ============================================ Directory explanation/links -================================ =========================================== +================================= ============================================ +`pypy/bin/`_ command-line scripts, mainly + `pypy/bin/pyinteractive.py`_ -`pypy/bin/`_ command-line scripts, mainly `pyinteractive.py`_ +`pypy/config/`_ handles the numerous options for building + and running PyPy -`pypy/config/`_ handles the numerous options for building and running PyPy +`pypy/doc/`_ text versions of PyPy developer + documentation -`pypy/doc/`_ text versions of PyPy developer documentation - -`pypy/doc/config/`_ documentation for the numerous translation options +`pypy/doc/config/`_ documentation for the numerous translation + options `pypy/doc/discussion/`_ drafts of ideas and documentation @@ -238,19 +241,24 @@ `pypy/interpreter/pyparser/`_ interpreter-level Python source parser -`pypy/interpreter/astcompiler/`_ interpreter-level bytecode compiler, via an AST - representation +`pypy/interpreter/astcompiler/`_ interpreter-level bytecode compiler, + via an AST representation -`pypy/module/`_ contains `mixed modules`_ implementing core modules with +`pypy/module/`_ contains `mixed modules`_ + implementing core modules with both application and interpreter level code. - Not all are finished and working. Use the ``--withmod-xxx`` - or ``--allworkingmodules`` translation options. + Not all are finished and working. Use + the ``--withmod-xxx`` + or ``--allworkingmodules`` translation + options. `pypy/objspace/`_ `object space`_ implementations -`pypy/objspace/std/`_ the StdObjSpace_ implementing CPython's objects and types +`pypy/objspace/std/`_ the StdObjSpace_ implementing CPython's + objects and types -`pypy/tool/`_ various utilities and hacks used from various places +`pypy/tool/`_ various utilities and hacks used + from various places `pypy/tool/algo/`_ general-purpose algorithmic and mathematic tools @@ -258,49 +266,58 @@ `pypy/tool/pytest/`_ support code for our `testing methods`_ -`rpython/annotator/`_ `type inferencing code`_ for `RPython`_ programs +`rpython/annotator/`_ `type inferencing code`_ for + `RPython`_ programs `rpython/config/`_ handles the numerous options for RPython -`rpython/flowspace/`_ the FlowObjSpace_ implementing `abstract interpretation`_ +`rpython/flowspace/`_ the FlowObjSpace_ implementing + `abstract interpretation`_ - -`rpython/rlib/`_ a `"standard library"`_ for RPython_ programs +`rpython/rlib/`_ a `"standard library"`_ for RPython_ + programs `rpython/rtyper/`_ the `RPython Typer`_ -`rpython/rtyper/lltypesystem/`_ the `low-level type system`_ for C-like backends +`rpython/rtyper/lltypesystem/`_ the `low-level type system`_ for + C-like backends -`rpython/rtyper/ootypesystem/`_ the `object-oriented type system`_ for OO backends +`rpython/rtyper/ootypesystem/`_ the `object-oriented type system`_ + for OO backends -`rpython/rtyper/memory/`_ the `garbage collector`_ construction framework +`rpython/rtyper/memory/`_ the `garbage collector`_ construction + framework `rpython/translator/`_ translation_ backends and support code -`rpython/translator/backendopt/`_ general optimizations that run before a backend generates code +`rpython/translator/backendopt/`_ general optimizations that run before a + backend generates code -`rpython/translator/c/`_ the `GenC backend`_, producing C code from an +`rpython/translator/c/`_ the `GenC backend`_, producing C code + from an RPython program (generally via the rtyper_) -`rpython/translator/cli/`_ the `CLI backend`_ for `.NET`_ (Microsoft CLR or Mono_) +`rpython/translator/cli/`_ the `CLI backend`_ for `.NET`_ + (Microsoft CLR or Mono_) -`pypy/goal/`_ our `main PyPy-translation scripts`_ live here +`pypy/goal/`_ our `main PyPy-translation scripts`_ + live here `rpython/translator/jvm/`_ the Java backend -`rpython/translator/tool/`_ helper tools for translation, including the Pygame - `graph viewer`_ +`rpython/translator/tool/`_ helper tools for translation -``*/test/`` many directories have a test subdirectory containing test +`dotviewer/`_ `graph viewer`_ + +``*/test/`` many directories have a test subdirectory + containing test modules (see `Testing in PyPy`_) -``_cache/`` holds cache files from internally `translating application - level to interpreterlevel`_ code. -================================ =========================================== +``_cache/`` holds cache files from various purposes +================================= ============================================ .. _`bytecode interpreter`: interpreter.html -.. _`translating application level to interpreterlevel`: geninterp.html .. _`Testing in PyPy`: coding-guide.html#testing-in-pypy .. _`mixed modules`: coding-guide.html#mixed-modules .. _`modules`: coding-guide.html#modules diff --git a/pypy/doc/rlib.rst b/pypy/doc/rlib.rst --- a/pypy/doc/rlib.rst +++ b/pypy/doc/rlib.rst @@ -7,18 +7,18 @@ .. contents:: -This page lists some of the modules in `pypy/rlib`_ together with some hints +This page lists some of the modules in `rpython/rlib`_ together with some hints for what they can be used for. The modules here will make up some general library useful for RPython programs (since most of the standard library modules are not RPython). Most of these modules are somewhat rough still and are likely to change at some point. Usually it is useful to look at the tests in -`pypy/rlib/test`_ to get an impression of how to use a module. +`rpython/rlib/test`_ to get an impression of how to use a module. ``listsort`` ============ -The `pypy/rlib/listsort.py`_ module contains an implementation of the timsort sorting algorithm +The `rpython/rlib/listsort.py`_ module contains an implementation of the timsort sorting algorithm (the sort method of lists is not RPython). To use it, subclass from the ``listsort.TimSort`` class and override the ``lt`` method to change the comparison behaviour. The constructor of ``TimSort`` takes a list as an @@ -30,7 +30,7 @@ ``nonconst`` ============ -The `pypy/rlib/nonconst.py`_ module is useful mostly for tests. The `flow object space`_ and +The `rpython/rlib/nonconst.py`_ module is useful mostly for tests. The `flow object space`_ and the `annotator`_ do quite some constant folding, which is sometimes not desired in a test. To prevent constant folding on a certain value, use the ``NonConst`` class. The constructor of ``NonConst`` takes an arbitrary value. The instance of @@ -44,7 +44,7 @@ ``objectmodel`` =============== -The `pypy/rlib/objectmodel.py`_ module is a mixed bag of various functionality. Some of the +The `rpython/rlib/objectmodel.py`_ module is a mixed bag of various functionality. Some of the more useful ones are: ``ComputedIntSymbolic``: @@ -94,7 +94,7 @@ ``rarithmetic`` =============== -The `pypy/rlib/rarithmetic.py`_ module contains functionality to handle the small differences +The `rpython/rlib/rarithmetic.py`_ module contains functionality to handle the small differences in the behaviour of arithmetic code in regular Python and RPython code. Most of them are already described in the `coding guide`_ @@ -104,7 +104,7 @@ ``rbigint`` =========== -The `pypy/rlib/rbigint.py`_ module contains a full RPython implementation of the Python ``long`` +The `rpython/rlib/rbigint.py`_ module contains a full RPython implementation of the Python ``long`` type (which itself is not supported in RPython). The ``rbigint`` class contains that implementation. To construct ``rbigint`` instances use the static methods ``fromint``, ``frombool``, ``fromfloat`` and ``fromdecimalstr``. To convert back @@ -118,7 +118,7 @@ ``rrandom`` =========== -The `pypy/rlib/rrandom.py`_ module contains an implementation of the mersenne twister random +The `rpython/rlib/rrandom.py`_ module contains an implementation of the mersenne twister random number generator. It contains one class ``Random`` which most importantly has a ``random`` method which returns a pseudo-random floating point number between 0.0 and 1.0. @@ -126,7 +126,7 @@ ``rsocket`` =========== -The `pypy/rlib/rsocket.py`_ module contains an RPython implementation of the functionality of +The `rpython/rlib/rsocket.py`_ module contains an RPython implementation of the functionality of the socket standard library with a slightly different interface. The difficulty with the Python socket API is that addresses are not "well-typed" objects: depending on the address family they are tuples, or strings, and @@ -137,7 +137,7 @@ ``streamio`` ============ -The `pypy/rlib/streamio.py`_ contains an RPython stream I/O implementation (which was started +The `rpython/rlib/streamio.py`_ contains an RPython stream I/O implementation (which was started by Guido van Rossum as `sio.py`_ in the CPython sandbox as a prototype for the upcoming new file implementation in Python 3000). @@ -146,7 +146,7 @@ ``unroll`` ========== -The `pypy/rlib/unroll.py`_ module most importantly contains the function ``unrolling_iterable`` +The `rpython/rlib/unroll.py`_ module most importantly contains the function ``unrolling_iterable`` which wraps an iterator. Looping over the iterator in RPython code will not produce a loop in the resulting flow graph but will unroll the loop instead. @@ -154,7 +154,7 @@ ``parsing`` =========== -The `pypy/rlib/parsing/`_ module is a still in-development module to generate tokenizers and +The `rpython/rlib/parsing/`_ module is a still in-development module to generate tokenizers and parsers in RPython. It is still highly experimental and only really used by the `Prolog interpreter`_ (although in slightly non-standard ways). The easiest way to specify a tokenizer/grammar is to write it down using regular expressions and @@ -204,7 +204,7 @@ anything except a. To parse a regular expression and to get a matcher for it, you can use the -function ``make_runner(s)`` in the ``pypy.rlib.parsing.regexparse`` module. It +function ``make_runner(s)`` in the ``rpython.rlib.parsing.regexparse`` module. It returns a object with a ``recognize(input)`` method that returns True or False depending on whether ``input`` matches the string or not. @@ -213,7 +213,7 @@ EBNF ---- -To describe a tokenizer and a grammar the ``pypy.rlib.parsing.ebnfparse`` +To describe a tokenizer and a grammar the ``rpython.rlib.parsing.ebnfparse`` defines a syntax for doing that. The syntax file contains a sequence or rules. Every rule either describes a @@ -295,7 +295,7 @@ The parsing process builds up a tree consisting of instances of ``Symbol`` and ``Nonterminal``, the former corresponding to tokens, the latter to nonterminal -symbols. Both classes live in the `pypy/rlib/parsing/tree.py`_ module. You can use +symbols. Both classes live in the `rpython/rlib/parsing/tree.py`_ module. You can use the ``view()`` method ``Nonterminal`` instances to get a pygame view of the parse tree. @@ -310,7 +310,7 @@ ++++++++ To write tree visitors for the parse trees that are RPython, there is a special -baseclass ``RPythonVisitor`` in `pypy/rlib/parsing/tree.py`_ to use. If your +baseclass ``RPythonVisitor`` in `rpython/rlib/parsing/tree.py`_ to use. If your class uses this, it will grow a ``dispatch(node)`` method, that calls an appropriate ``visit_`` method, depending on the ``node`` argument. Here the is replaced by the ``symbol`` attribute of the visited node. diff --git a/pypy/doc/rtyper.rst b/pypy/doc/rtyper.rst --- a/pypy/doc/rtyper.rst +++ b/pypy/doc/rtyper.rst @@ -4,7 +4,7 @@ .. contents:: -The RPython Typer lives in the directory `pypy/rpython/`_. +The RPython Typer lives in the directory `rpython/rtyper/`_. Overview @@ -52,7 +52,7 @@ where -- in C notation -- all three variables v1, v2 and v3 are typed ``int``. This is done by attaching an attribute ``concretetype`` to v1, v2 and v3 (which might be instances of Variable or possibly Constant). In our model, -this ``concretetype`` is ``pypy.rpython.lltypesystem.lltype.Signed``. Of +this ``concretetype`` is ``rpython.rtyper.lltypesystem.lltype.Signed``. Of course, the purpose of replacing the operation called ``add`` with ``int_add`` is that code generators no longer have to worry about what kind of addition (or concatenation maybe?) it means. @@ -66,7 +66,7 @@ each operation. In both cases the analysis of an operation depends on the annotations of its input arguments. This is reflected in the usage of the same ``__extend__`` syntax in the source files (compare e.g. -`pypy/annotation/binaryop.py`_ and `pypy/rpython/rint.py`_). +`rpython/annotator/binaryop.py`_ and `rpython/rtyper/rint.py`_). The analogy stops here, though: while it runs, the Annotator is in the middle of computing the annotations, so it might need to reflow and generalize until @@ -104,7 +104,7 @@ implementations for the same high-level operations. This is the reason for turning representations into explicit objects. -The base Repr class is defined in `pypy/rpython/rmodel.py`_. Most of the +The base Repr class is defined in `rpython/rtyper/rmodel.py`_. Most of the ``rpython/r*.py`` files define one or a few subclasses of Repr. The method getrepr() of the RTyper will build and cache a single Repr instance per SomeXxx() instance; moreover, two SomeXxx() instances that are equal get the @@ -131,9 +131,9 @@ The RPython Typer uses a standard low-level model which we believe can correspond rather directly to various target languages such as C. This model is implemented in the first part of -`pypy/rpython/lltypesystem/lltype.py`_. +`rpython/rtyper/lltypesystem/lltype.py`_. -The second part of `pypy/rpython/lltypesystem/lltype.py`_ is a runnable +The second part of `rpython/rtyper/lltypesystem/lltype.py`_ is a runnable implementation of these types, for testing purposes. It allows us to write and test plain Python code using a malloc() function to obtain and manipulate structures and arrays. This is useful for example to implement and test @@ -147,7 +147,7 @@ Here is a quick tour: - >>> from pypy.rpython.lltypesystem.lltype import * + >>> from rpython.rtyper.lltypesystem.lltype import * Here are a few primitive low-level types, and the typeOf() function to figure them out: @@ -191,7 +191,7 @@ types like list in this elementary world. The ``malloc()`` function is a kind of placeholder, which must eventually be provided by the code generator for the target platform; but as we have just seen its Python implementation in -`pypy/rpython/lltypesystem/lltype.py`_ works too, which is primarily useful for +`rpython/rtyper/lltypesystem/lltype.py`_ works too, which is primarily useful for testing, interactive exploring, etc. The argument to ``malloc()`` is the structure type directly, but it returns a @@ -245,7 +245,7 @@ +++++++++++++++ Structure types are built as instances of -``pypy.rpython.lltypesystem.lltype.Struct``:: +``rpython.rtyper.lltypesystem.lltype.Struct``:: MyStructType = Struct('somename', ('field1', Type1), ('field2', Type2)...) MyStructType = GcStruct('somename', ('field1', Type1), ('field2', Type2)...) @@ -277,7 +277,7 @@ +++++++++++ An array type is built as an instance of -``pypy.rpython.lltypesystem.lltype.Array``:: +``rpython.rtyper.lltypesystem.lltype.Array``:: MyIntArray = Array(Signed) MyOtherArray = Array(MyItemType) @@ -316,7 +316,7 @@ with care: the bigger structure of which they are part of could be freed while the Ptr to the substructure is still in use. In general, it is a good idea to avoid passing around pointers to inlined substructures of malloc()ed structures. -(The testing implementation of `pypy/rpython/lltypesystem/lltype.py`_ checks to some +(The testing implementation of `rpython/rtyper/lltypesystem/lltype.py`_ checks to some extent that you are not trying to use a pointer to a structure after its container has been freed, using weak references. But pointers to non-GC structures are not officially meant to be weak references: using them after what @@ -429,7 +429,7 @@ change needed to the Annotator to allow it to perform type inference of our very-low-level snippets of code. -See for example `pypy/rpython/rlist.py`_. +See for example `rpython/rtyper/rlist.py`_. .. _`oo type`: @@ -441,10 +441,10 @@ targeting low level backends such as C, but it is not good enough for targeting higher level backends such as .NET CLI or Java JVM, so a new object oriented model has been introduced. This model is -implemented in the first part of `pypy/rpython/ootypesystem/ootype.py`_. +implemented in the first part of `rpython/rtyper/ootypesystem/ootype.py`_. As for the low-level typesystem, the second part of -`pypy/rpython/ootypesystem/ootype.py`_ is a runnable implementation of +`rpython/rtyper/ootypesystem/ootype.py`_ is a runnable implementation of these types, for testing purposes. @@ -751,7 +751,7 @@ The LLInterpreter is a simple piece of code that is able to interpret flow graphs. This is very useful for testing purposes, especially if you work on the RPython Typer. The most useful interface for it is the ``interpret`` -function in the file `pypy/rpython/test/test_llinterp.py`_. It takes as +function in the file `rpython/rtyper/test/test_llinterp.py`_. It takes as arguments a function and a list of arguments with which the function is supposed to be called. Then it generates the flow graph, annotates it according to the types of the arguments you passed to it and runs the diff --git a/pypy/doc/stackless.rst b/pypy/doc/stackless.rst --- a/pypy/doc/stackless.rst +++ b/pypy/doc/stackless.rst @@ -29,7 +29,7 @@ on 32-bit or a complete megabyte on 64-bit. Moreover, the feature is only available (so far) on x86 and x86-64 CPUs; for other CPUs you need to add a short page of custom assembler to -`pypy/translator/c/src/stacklet/`_. +`rpython/translator/c/src/stacklet/`_. Theory @@ -271,9 +271,9 @@ Continulets are internally implemented using stacklets, which is the generic RPython-level building block for "one-shot continuations". For more information about them please see the documentation in the C source -at `pypy/translator/c/src/stacklet/stacklet.h`_. +at `rpython/translator/c/src/stacklet/stacklet.h`_. -The module ``pypy.rlib.rstacklet`` is a thin wrapper around the above +The module ``rpython.rlib.rstacklet`` is a thin wrapper around the above functions. The key point is that new() and switch() always return a fresh stacklet handle (or an empty one), and switch() additionally consumes one. It makes no sense to have code in which the returned diff --git a/pypy/doc/tool/makeref.py b/pypy/doc/tool/makeref.py --- a/pypy/doc/tool/makeref.py +++ b/pypy/doc/tool/makeref.py @@ -1,10 +1,9 @@ import py -py.path.local(__file__) import pypy -pypydir = py.path.local(pypy.__file__).dirpath() -distdir = pypydir.dirpath() -issue_url = 'http://codespeak.net/issue/pypy-dev/' +pypydir = py.path.local(pypy.__file__).join('..') +distdir = pypydir.dirpath() +issue_url = 'http://bugs.pypy.org/issue/pypy-dev/' bitbucket_url = 'https://bitbucket.org/pypy/pypy/src/default/' import urllib2, posixpath diff --git a/pypy/doc/translation.rst b/pypy/doc/translation.rst --- a/pypy/doc/translation.rst +++ b/pypy/doc/translation.rst @@ -90,7 +90,7 @@ (although these steps are not quite as distinct as you might think from this presentation). -There is an `interactive interface`_ called `pypy/bin/translatorshell.py`_ to the +There is an `interactive interface`_ called `rpython/bin/translatorshell.py`_ to the translation process which allows you to interactively work through these stages. @@ -116,7 +116,7 @@ which are the basic data structures of the translation process. -All these types are defined in `pypy/objspace/flow/model.py`_ (which is a rather +All these types are defined in `rpython/flowspace/model.py`_ (which is a rather important module in the PyPy source base, to reinforce the point). The flow graph of a function is represented by the class ``FunctionGraph``. diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst --- a/pypy/doc/whatsnew-head.rst +++ b/pypy/doc/whatsnew-head.rst @@ -19,7 +19,7 @@ .. branch: numpypy-longdouble Long double support for numpypy .. branch: numpypy-real-as-view -Convert real, imag from ufuncs to views. This involves the beginning of +Convert real, imag from ufuncs to views. This involves the beginning of view() functionality .. branch: signatures @@ -57,4 +57,14 @@ .. branch: cleanup-tests Consolidated the lib_pypy/pypy_test and pypy/module/test_lib_pypy tests into -+one directory for reduced confusion and so they all run nightly. +one directory for reduced confusion and so they all run nightly. + +.. branch: unquote-faster +.. branch: urlparse-unquote-faster + +.. branch: signal-and-thread +Add "__pypy__.thread.signals_enabled", a context manager. Can be used in a +non-main thread to enable the processing of signal handlers in that thread. + +.. branch: coding-guide-update-rlib-refs +.. branch: rlib-doc-rpython-refs diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -1494,10 +1494,11 @@ ) return fd - def warn(self, msg, w_warningcls): - self.appexec([self.wrap(msg), w_warningcls], """(msg, warningcls): + def warn(self, w_msg, w_warningcls, stacklevel=2): + self.appexec([w_msg, w_warningcls, self.wrap(stacklevel)], + """(msg, warningcls, stacklevel): import _warnings - _warnings.warn(msg, warningcls, stacklevel=2) + _warnings.warn(msg, warningcls, stacklevel=stacklevel) """) diff --git a/pypy/interpreter/miscutils.py b/pypy/interpreter/miscutils.py --- a/pypy/interpreter/miscutils.py +++ b/pypy/interpreter/miscutils.py @@ -17,8 +17,14 @@ def setvalue(self, value): self._value = value - def ismainthread(self): + def signals_enabled(self): return True + def enable_signals(self, space): + pass + + def disable_signals(self, space): + pass + def getallvalues(self): return {0: self._value} diff --git a/pypy/interpreter/pycode.py b/pypy/interpreter/pycode.py --- a/pypy/interpreter/pycode.py +++ b/pypy/interpreter/pycode.py @@ -53,16 +53,17 @@ kwargname = None return Signature(argnames, varargname, kwargname) + class PyCode(eval.Code): "CPython-style code objects." _immutable_ = True _immutable_fields_ = ["co_consts_w[*]", "co_names_w[*]", "co_varnames[*]", - "co_freevars[*]", "co_cellvars[*]"] + "co_freevars[*]", "co_cellvars[*]", "_args_as_cellvars[*]"] def __init__(self, space, argcount, nlocals, stacksize, flags, code, consts, names, varnames, filename, name, firstlineno, lnotab, freevars, cellvars, - hidden_applevel=False, magic = default_magic): + hidden_applevel=False, magic=default_magic): """Initialize a new code object from parameters given by the pypy compiler""" self.space = space @@ -89,8 +90,6 @@ def _initialize(self): self._init_flags() - # Precompute what arguments need to be copied into cellvars - self._args_as_cellvars = [] if self.co_cellvars: argcount = self.co_argcount @@ -108,16 +107,22 @@ # produced by CPython are loaded by PyPy. Note that CPython # contains the following bad-looking nested loops at *every* # function call! - argvars = self.co_varnames + + # Precompute what arguments need to be copied into cellvars + args_as_cellvars = [] + argvars = self.co_varnames cellvars = self.co_cellvars for i in range(len(cellvars)): cellname = cellvars[i] for j in range(argcount): if cellname == argvars[j]: # argument j has the same name as the cell var i - while len(self._args_as_cellvars) <= i: - self._args_as_cellvars.append(-1) # pad - self._args_as_cellvars[i] = j + while len(args_as_cellvars) <= i: + args_as_cellvars.append(-1) # pad + args_as_cellvars[i] = j + self._args_as_cellvars = args_as_cellvars[:] + else: + self._args_as_cellvars = [] self._compute_flatcall() diff --git a/pypy/interpreter/pyopcode.py b/pypy/interpreter/pyopcode.py --- a/pypy/interpreter/pyopcode.py +++ b/pypy/interpreter/pyopcode.py @@ -776,17 +776,16 @@ @jit.unroll_safe def cmp_exc_match(self, w_1, w_2): - if self.space.is_true(self.space.isinstance(w_2, self.space.w_tuple)): - for w_t in self.space.fixedview(w_2): - if self.space.is_true(self.space.isinstance(w_t, - self.space.w_str)): - self.space.warn("catching of string exceptions is " - "deprecated", - self.space.w_DeprecationWarning) - elif self.space.is_true(self.space.isinstance(w_2, self.space.w_str)): - self.space.warn("catching of string exceptions is deprecated", - self.space.w_DeprecationWarning) - return self.space.newbool(self.space.exception_match(w_1, w_2)) + space = self.space + if space.is_true(space.isinstance(w_2, space.w_tuple)): + for w_t in space.fixedview(w_2): + if space.is_true(space.isinstance(w_t, space.w_str)): + msg = "catching of string exceptions is deprecated" + space.warn(space.wrap(msg), space.w_DeprecationWarning) + elif space.is_true(space.isinstance(w_2, space.w_str)): + msg = "catching of string exceptions is deprecated" + space.warn(space.wrap(msg), space.w_DeprecationWarning) + return space.newbool(space.exception_match(w_1, w_2)) def COMPARE_OP(self, testnum, next_instr): w_2 = self.popvalue() diff --git a/pypy/interpreter/test2/test_app_main.py b/pypy/interpreter/test2/test_app_main.py --- a/pypy/interpreter/test2/test_app_main.py +++ b/pypy/interpreter/test2/test_app_main.py @@ -208,11 +208,6 @@ These tests require pexpect (UNIX-only). http://pexpect.sourceforge.net/ """ - def setup_class(cls): - # some tests need to be able to import test2, change the cwd - goal_dir = os.path.abspath(os.path.join(os.path.realpath(os.path.dirname(__file__)), '..')) - os.chdir(goal_dir) - def _spawn(self, *args, **kwds): try: import pexpect @@ -456,13 +451,14 @@ child.expect('789') # expect to see it before the timeout hits child.sendline('X') - def test_options_i_m(self): + def test_options_i_m(self, monkeypatch): if sys.platform == "win32": skip("close_fds is not supported on Windows platforms") if not hasattr(runpy, '_run_module_as_main'): skip("requires CPython >= 2.6") p = os.path.join(os.path.realpath(os.path.dirname(__file__)), 'mymodule.py') p = os.path.abspath(p) + monkeypatch.chdir(os.path.dirname(app_main)) child = self.spawn(['-i', '-m', 'test2.mymodule', 'extra']) @@ -562,12 +558,13 @@ child.sendline('Not at all. They could be carried.') child.expect('A five ounce bird could not carry a one pound coconut.') - def test_no_space_before_argument(self): + def test_no_space_before_argument(self, monkeypatch): if not hasattr(runpy, '_run_module_as_main'): skip("requires CPython >= 2.6") child = self.spawn(['-cprint "hel" + "lo"']) child.expect('hello') + monkeypatch.chdir(os.path.dirname(app_main)) child = self.spawn(['-mtest2.mymodule']) child.expect('mymodule running') @@ -667,11 +664,12 @@ '-c "import sys; print sys.warnoptions"') assert "['ignore', 'default', 'once', 'error']" in data - def test_option_m(self): + def test_option_m(self, monkeypatch): if not hasattr(runpy, '_run_module_as_main'): skip("requires CPython >= 2.6") p = os.path.join(os.path.realpath(os.path.dirname(__file__)), 'mymodule.py') p = os.path.abspath(p) + monkeypatch.chdir(os.path.dirname(app_main)) data = self.run('-m test2.mymodule extra') assert 'mymodule running' in data assert 'Name: __main__' in data diff --git a/pypy/module/__builtin__/functional.py b/pypy/module/__builtin__/functional.py --- a/pypy/module/__builtin__/functional.py +++ b/pypy/module/__builtin__/functional.py @@ -133,56 +133,77 @@ v = v.add(step) return space.newlist(res_w) +min_jitdriver = jit.JitDriver(name='min', + greens=['w_type'], reds='auto') +max_jitdriver = jit.JitDriver(name='max', + greens=['w_type'], reds='auto') + +def make_min_max(unroll): + @specialize.arg(2) + def min_max_impl(space, args, implementation_of): + if implementation_of == "max": + compare = space.gt + jitdriver = max_jitdriver + else: + compare = space.lt + jitdriver = min_jitdriver + args_w = args.arguments_w + if len(args_w) > 1: + w_sequence = space.newtuple(args_w) + elif len(args_w): + w_sequence = args_w[0] + else: + msg = "%s() expects at least one argument" % (implementation_of,) + raise OperationError(space.w_TypeError, space.wrap(msg)) + w_key = None + kwds = args.keywords + if kwds: + if kwds[0] == "key" and len(kwds) == 1: + w_key = args.keywords_w[0] + else: + msg = "%s() got unexpected keyword argument" % (implementation_of,) + raise OperationError(space.w_TypeError, space.wrap(msg)) + + w_iter = space.iter(w_sequence) + w_type = space.type(w_iter) + w_max_item = None + w_max_val = None + while True: + if not unroll: + jitdriver.jit_merge_point(w_type=w_type) + try: + w_item = space.next(w_iter) + except OperationError, e: + if not e.match(space, space.w_StopIteration): + raise + break + if w_key is not None: + w_compare_with = space.call_function(w_key, w_item) + else: + w_compare_with = w_item + if w_max_item is None or \ + space.is_true(compare(w_compare_with, w_max_val)): + w_max_item = w_item + w_max_val = w_compare_with + if w_max_item is None: + msg = "arg is an empty sequence" + raise OperationError(space.w_ValueError, space.wrap(msg)) + return w_max_item + if unroll: + min_max_impl = jit.unroll_safe(min_max_impl) + return min_max_impl + +min_max_unroll = make_min_max(True) +min_max_normal = make_min_max(False) @specialize.arg(2) - at jit.look_inside_iff(lambda space, args, implementation_of: - jit.isconstant(len(args.arguments_w)) and - len(args.arguments_w) == 2 -) def min_max(space, args, implementation_of): - if implementation_of == "max": - compare = space.gt + if not jit.we_are_jitted() or (jit.isconstant(len(args.arguments_w)) and + len(args.arguments_w) == 2): + return min_max_unroll(space, args, implementation_of) else: - compare = space.lt - args_w = args.arguments_w - if len(args_w) > 1: - w_sequence = space.newtuple(args_w) - elif len(args_w): - w_sequence = args_w[0] - else: - msg = "%s() expects at least one argument" % (implementation_of,) - raise OperationError(space.w_TypeError, space.wrap(msg)) - w_key = None - kwds = args.keywords - if kwds: - if kwds[0] == "key" and len(kwds) == 1: - w_key = args.keywords_w[0] - else: - msg = "%s() got unexpected keyword argument" % (implementation_of,) - raise OperationError(space.w_TypeError, space.wrap(msg)) - - w_iter = space.iter(w_sequence) - w_max_item = None - w_max_val = None - while True: - try: - w_item = space.next(w_iter) - except OperationError, e: - if not e.match(space, space.w_StopIteration): - raise - break - if w_key is not None: - w_compare_with = space.call_function(w_key, w_item) - else: - w_compare_with = w_item - if w_max_item is None or \ - space.is_true(compare(w_compare_with, w_max_val)): - w_max_item = w_item - w_max_val = w_compare_with - if w_max_item is None: - msg = "arg is an empty sequence" - raise OperationError(space.w_ValueError, space.wrap(msg)) - return w_max_item + return min_max_normal(space, args, implementation_of) +min_max._always_inline = True def max(space, __args__): """max(iterable[, key=func]) -> value diff --git a/pypy/module/__builtin__/interp_classobj.py b/pypy/module/__builtin__/interp_classobj.py --- a/pypy/module/__builtin__/interp_classobj.py +++ b/pypy/module/__builtin__/interp_classobj.py @@ -154,9 +154,9 @@ return elif name == "__del__": if self.lookup(space, name) is None: - msg = ("a __del__ method added to an existing class " - "will not be called") - space.warn(msg, space.w_RuntimeWarning) + msg = ("a __del__ method added to an existing class will " + "not be called") + space.warn(space.wrap(msg), space.w_RuntimeWarning) space.setitem(self.w_dict, w_attr, w_value) def descr_delattr(self, space, w_attr): @@ -395,9 +395,9 @@ cache = space.fromcache(Cache) if (not isinstance(self, cache.cls_with_del) and self.getdictvalue(space, '__del__') is None): - msg = ("a __del__ method added to an instance " - "with no __del__ in the class will not be called") - space.warn(msg, space.w_RuntimeWarning) + msg = ("a __del__ method added to an instance with no " + "__del__ in the class will not be called") + space.warn(space.wrap(msg), space.w_RuntimeWarning) if w_meth is not None: space.call_function(w_meth, w_name, w_value) else: @@ -454,11 +454,9 @@ else: w_as_str = self.descr_str(space) if space.len_w(w_format_spec) > 0: - space.warn( - ("object.__format__ with a non-empty format string is " - "deprecated"), - space.w_PendingDeprecationWarning - ) + msg = ("object.__format__ with a non-empty format string is " + "deprecated") + space.warn(space.wrap(msg), space.w_PendingDeprecationWarning) return space.format(w_as_str, w_format_spec) def descr_len(self, space): diff --git a/pypy/module/__pypy__/__init__.py b/pypy/module/__pypy__/__init__.py --- a/pypy/module/__pypy__/__init__.py +++ b/pypy/module/__pypy__/__init__.py @@ -26,6 +26,16 @@ interpleveldefs[name] = "space.wrap(interp_time.%s)" % name +class ThreadModule(MixedModule): + appleveldefs = { + 'signals_enabled': 'app_signal.signals_enabled', + } + interpleveldefs = { + '_signals_enter': 'interp_signal.signals_enter', + '_signals_exit': 'interp_signal.signals_exit', + } + + class Module(MixedModule): appleveldefs = { } @@ -54,6 +64,7 @@ submodules = { "builders": BuildersModule, "time": TimeModule, + "thread": ThreadModule, } def setup_after_space_initialization(self): diff --git a/pypy/module/__pypy__/app_signal.py b/pypy/module/__pypy__/app_signal.py new file mode 100644 --- /dev/null +++ b/pypy/module/__pypy__/app_signal.py @@ -0,0 +1,14 @@ +import __pypy__.thread + +class SignalsEnabled(object): + '''A context manager to use in non-main threads: +enables receiving signals in a "with" statement. More precisely, if a +signal is received by the process, then the signal handler might be +called either in the main thread (as usual) or within another thread +that is within a "with signals_enabled:". This other thread should be +ready to handle unexpected exceptions that the signal handler might +raise --- notably KeyboardInterrupt.''' + __enter__ = __pypy__.thread._signals_enter + __exit__ = __pypy__.thread._signals_exit + +signals_enabled = SignalsEnabled() diff --git a/pypy/module/__pypy__/interp_signal.py b/pypy/module/__pypy__/interp_signal.py new file mode 100644 --- /dev/null +++ b/pypy/module/__pypy__/interp_signal.py @@ -0,0 +1,6 @@ + +def signals_enter(space): + space.threadlocals.enable_signals(space) + +def signals_exit(space, w_ignored1=None, w_ignored2=None, w_ignored3=None): + space.threadlocals.disable_signals(space) diff --git a/pypy/module/__pypy__/test/test_signal.py b/pypy/module/__pypy__/test/test_signal.py new file mode 100644 --- /dev/null +++ b/pypy/module/__pypy__/test/test_signal.py @@ -0,0 +1,122 @@ +import sys + +from pypy.module.thread.test.support import GenericTestThread + + +class AppTestMinimal: + spaceconfig = dict(usemodules=['__pypy__']) + + def test_signal(self): + from __pypy__ import thread + with thread.signals_enabled: + pass + # assert did not crash + + +class AppTestThreadSignal(GenericTestThread): + spaceconfig = dict(usemodules=['__pypy__', 'thread', 'signal', 'time']) + + def test_exit_twice(self): + import __pypy__, thread + __pypy__.thread._signals_exit() + try: + raises(thread.error, __pypy__.thread._signals_exit) + finally: + __pypy__.thread._signals_enter() + + def test_enable_signals(self): + import __pypy__, thread, signal, time + + def subthread(): + try: + with __pypy__.thread.signals_enabled: + thread.interrupt_main() + for i in range(10): + print 'x' + time.sleep(0.1) + except BaseException, e: + interrupted.append(e) + finally: + done.append(None) + + # This is normally called by app_main.py + signal.signal(signal.SIGINT, signal.default_int_handler) + + for i in range(10): + __pypy__.thread._signals_exit() + try: + done = [] + interrupted = [] + thread.start_new_thread(subthread, ()) + for i in range(10): + if len(done): break + print '.' + time.sleep(0.1) + assert len(done) == 1 + assert len(interrupted) == 1 + assert 'KeyboardInterrupt' in interrupted[0].__class__.__name__ + finally: + __pypy__.thread._signals_enter() + + def test_thread_fork_signals(self): + import __pypy__ + import os, thread, signal + + if not hasattr(os, 'fork'): + skip("No fork on this platform") + + def fork(): + with __pypy__.thread.signals_enabled: + return os.fork() + + def threadfunction(): + pid = fork() + if pid == 0: + print 'in child' + # signal() only works from the 'main' thread + signal.signal(signal.SIGUSR1, signal.SIG_IGN) + os._exit(42) + else: + self.timeout_killer(pid, 5) + exitcode = os.waitpid(pid, 0)[1] + feedback.append(exitcode) + + feedback = [] + thread.start_new_thread(threadfunction, ()) + self.waitfor(lambda: feedback) + # if 0, an (unraisable) exception was raised from the forked thread. + # if 9, process was killed by timer. + # if 42<<8, os._exit(42) was correctly reached. + assert feedback == [42<<8] + + +class AppTestThreadSignalLock: + spaceconfig = dict(usemodules=['__pypy__', 'thread', 'signal']) + + def setup_class(cls): + if (not cls.runappdirect or + '__pypy__' not in sys.builtin_module_names): + import py + py.test.skip("this is only a test for -A runs on top of pypy") + + def test_enable_signals(self): + import __pypy__, thread, signal, time + + interrupted = [] + lock = thread.allocate_lock() + lock.acquire() + + def subthread(): + try: + time.sleep(0.25) + with __pypy__.thread.signals_enabled: + thread.interrupt_main() + except BaseException, e: + interrupted.append(e) + finally: + lock.release() + + thread.start_new_thread(subthread, ()) + lock.acquire() + assert len(interrupted) == 1 + assert 'KeyboardInterrupt' in interrupted[0].__class__.__name__ diff --git a/pypy/module/_cffi_backend/__init__.py b/pypy/module/_cffi_backend/__init__.py --- a/pypy/module/_cffi_backend/__init__.py +++ b/pypy/module/_cffi_backend/__init__.py @@ -7,7 +7,7 @@ appleveldefs = { } interpleveldefs = { - '__version__': 'space.wrap("0.4")', + '__version__': 'space.wrap("0.6")', 'load_library': 'libraryobj.load_library', diff --git a/pypy/module/_cffi_backend/cdataobj.py b/pypy/module/_cffi_backend/cdataobj.py --- a/pypy/module/_cffi_backend/cdataobj.py +++ b/pypy/module/_cffi_backend/cdataobj.py @@ -119,9 +119,12 @@ def getitem(self, w_index): space = self.space - i = space.getindex_w(w_index, space.w_IndexError) - ctype = self.ctype._check_subscript_index(self, i) - w_o = self._do_getitem(ctype, i) + if space.isinstance_w(w_index, space.w_slice): + w_o = self._do_getslice(w_index) + else: + i = space.getindex_w(w_index, space.w_IndexError) + ctype = self.ctype._check_subscript_index(self, i) + w_o = self._do_getitem(ctype, i) keepalive_until_here(self) return w_o @@ -132,14 +135,100 @@ def setitem(self, w_index, w_value): space = self.space - i = space.getindex_w(w_index, space.w_IndexError) - ctype = self.ctype._check_subscript_index(self, i) - ctitem = ctype.ctitem - ctitem.convert_from_object( - rffi.ptradd(self._cdata, i * ctitem.size), - w_value) + if space.isinstance_w(w_index, space.w_slice): + self._do_setslice(w_index, w_value) + else: + i = space.getindex_w(w_index, space.w_IndexError) + ctype = self.ctype._check_subscript_index(self, i) + ctitem = ctype.ctitem + ctitem.convert_from_object( + rffi.ptradd(self._cdata, i * ctitem.size), + w_value) keepalive_until_here(self) + def _do_getslicearg(self, w_slice): + from pypy.module._cffi_backend.ctypeptr import W_CTypePointer + from pypy.objspace.std.sliceobject import W_SliceObject + assert isinstance(w_slice, W_SliceObject) + space = self.space + # + if space.is_w(w_slice.w_start, space.w_None): + raise OperationError(space.w_IndexError, + space.wrap("slice start must be specified")) + start = space.int_w(w_slice.w_start) + # + if space.is_w(w_slice.w_stop, space.w_None): + raise OperationError(space.w_IndexError, + space.wrap("slice stop must be specified")) + stop = space.int_w(w_slice.w_stop) + # + if not space.is_w(w_slice.w_step, space.w_None): + raise OperationError(space.w_IndexError, + space.wrap("slice with step not supported")) + # + if start > stop: + raise OperationError(space.w_IndexError, + space.wrap("slice start > stop")) + # + ctype = self.ctype._check_slice_index(self, start, stop) + assert isinstance(ctype, W_CTypePointer) + # + return ctype, start, stop - start + + def _do_getslice(self, w_slice): + ctptr, start, length = self._do_getslicearg(w_slice) + # + space = self.space + ctarray = ctptr.cache_array_type + if ctarray is None: + from pypy.module._cffi_backend import newtype + ctarray = newtype.new_array_type(space, ctptr, space.w_None) + ctptr.cache_array_type = ctarray + # + p = rffi.ptradd(self._cdata, start * ctarray.ctitem.size) + return W_CDataSliced(space, p, ctarray, length) + + def _do_setslice(self, w_slice, w_value): + ctptr, start, length = self._do_getslicearg(w_slice) + ctitem = ctptr.ctitem + ctitemsize = ctitem.size + cdata = rffi.ptradd(self._cdata, start * ctitemsize) + # + if isinstance(w_value, W_CData): + from pypy.module._cffi_backend import ctypearray + ctv = w_value.ctype + if (isinstance(ctv, ctypearray.W_CTypeArray) and + ctv.ctitem is ctitem and + w_value.get_array_length() == length): + # fast path: copying from exactly the correct type + s = w_value._cdata + for i in range(ctitemsize * length): + cdata[i] = s[i] + keepalive_until_here(w_value) + return + # + space = self.space + w_iter = space.iter(w_value) + for i in range(length): + try: + w_item = space.next(w_iter) + except OperationError, e: + if not e.match(space, space.w_StopIteration): + raise + raise operationerrfmt(space.w_ValueError, + "need %d values to unpack, got %d", + length, i) + ctitem.convert_from_object(cdata, w_item) + cdata = rffi.ptradd(cdata, ctitemsize) + try: + space.next(w_iter) + except OperationError, e: + if not e.match(space, space.w_StopIteration): + raise + else: + raise operationerrfmt(space.w_ValueError, + "got more than %d values to unpack", length) + def _add_or_sub(self, w_other, sign): space = self.space i = sign * space.getindex_w(w_other, space.w_OverflowError) @@ -281,6 +370,22 @@ return self.structobj +class W_CDataSliced(W_CData): + """Subclass with an explicit length, for slices.""" + _attrs_ = ['length'] + _immutable_fields_ = ['length'] + + def __init__(self, space, cdata, ctype, length): + W_CData.__init__(self, space, cdata, ctype) + self.length = length + + def _repr_extra(self): + return "sliced length %d" % (self.length,) + + def get_array_length(self): + return self.length + + W_CData.typedef = TypeDef( 'CData', __module__ = '_cffi_backend', diff --git a/pypy/module/_cffi_backend/ctypearray.py b/pypy/module/_cffi_backend/ctypearray.py --- a/pypy/module/_cffi_backend/ctypearray.py +++ b/pypy/module/_cffi_backend/ctypearray.py @@ -76,6 +76,17 @@ self.name, i, w_cdata.get_array_length()) return self + def _check_slice_index(self, w_cdata, start, stop): + space = self.space + if start < 0: + raise OperationError(space.w_IndexError, + space.wrap("negative index not supported")) + if stop > w_cdata.get_array_length(): + raise operationerrfmt(space.w_IndexError, + "index too large (expected %d <= %d)", + stop, w_cdata.get_array_length()) + return self.ctptr + def convert_from_object(self, cdata, w_ob): self.convert_array_from_object(cdata, w_ob) diff --git a/pypy/module/_cffi_backend/ctypeenum.py b/pypy/module/_cffi_backend/ctypeenum.py --- a/pypy/module/_cffi_backend/ctypeenum.py +++ b/pypy/module/_cffi_backend/ctypeenum.py @@ -6,23 +6,19 @@ from rpython.rtyper.lltypesystem import rffi from rpython.rlib.rarithmetic import intmask, r_ulonglong from rpython.rlib.objectmodel import keepalive_until_here +from rpython.rlib.objectmodel import specialize from pypy.module._cffi_backend.ctypeprim import W_CTypePrimitiveSigned +from pypy.module._cffi_backend.ctypeprim import W_CTypePrimitiveUnsigned from pypy.module._cffi_backend import misc -class W_CTypeEnum(W_CTypePrimitiveSigned): - _attrs_ = ['enumerators2values', 'enumvalues2erators'] - _immutable_fields_ = ['enumerators2values', 'enumvalues2erators'] - kind = "enum" +class _Mixin_Enum(object): + _mixin_ = True - def __init__(self, space, name, enumerators, enumvalues): - from pypy.module._cffi_backend.newtype import alignment + def __init__(self, space, name, size, align, enumerators, enumvalues): name = "enum " + name - size = rffi.sizeof(rffi.INT) - align = alignment(rffi.INT) - W_CTypePrimitiveSigned.__init__(self, space, size, - name, len(name), align) + self._super.__init__(self, space, size, name, len(name), align) self.enumerators2values = {} # str -> int self.enumvalues2erators = {} # int -> str for i in range(len(enumerators)-1, -1, -1): @@ -44,55 +40,46 @@ space.setitem(w_dct, space.wrap(enumerator), space.wrap(enumvalue)) return w_dct - return W_CTypePrimitiveSigned._fget(self, attrchar) + return self._super._fget(self, attrchar) + + def extra_repr(self, cdata): + value = self._get_value(cdata) + try: + s = self.enumvalues2erators[value] + except KeyError: + return str(value) + else: + return '%s: %s' % (value, s) def string(self, cdataobj, maxlen): - w_result = self.convert_to_object(cdataobj._cdata) + value = self._get_value(cdataobj._cdata) keepalive_until_here(cdataobj) - return w_result + try: + s = self.enumvalues2erators[value] + except KeyError: + s = str(value) + return self.space.wrap(s) - def convert_to_object(self, cdata): - value = misc.read_raw_long_data(cdata, self.size) - try: - enumerator = self.enumvalues2erators[value] - except KeyError: - enumerator = '#%d' % (value,) - return self.space.wrap(enumerator) - def convert_from_object(self, cdata, w_ob): - space = self.space - try: - return W_CTypePrimitiveSigned.convert_from_object(self, cdata, - w_ob) - except OperationError, e: - if not e.match(space, space.w_TypeError): - raise - if space.isinstance_w(w_ob, space.w_basestring): - value = self.convert_enum_string_to_int(space.str_w(w_ob)) - value = r_ulonglong(value) - misc.write_raw_integer_data(cdata, value, self.size) - else: - raise self._convert_error("str or int", w_ob) +class W_CTypeEnumSigned(_Mixin_Enum, W_CTypePrimitiveSigned): + _attrs_ = ['enumerators2values', 'enumvalues2erators'] + _immutable_fields_ = ['enumerators2values', 'enumvalues2erators'] + kind = "enum" + _super = W_CTypePrimitiveSigned - def cast_str(self, w_ob): - space = self.space - return self.convert_enum_string_to_int(space.str_w(w_ob)) + def _get_value(self, cdata): + # returns a signed long + assert self.value_fits_long + return misc.read_raw_long_data(cdata, self.size) - def cast_unicode(self, w_ob): - return self.cast_str(w_ob) - def convert_enum_string_to_int(self, s): - space = self.space - if s.startswith('#'): - try: - return int(s[1:]) - except ValueError: - raise OperationError(space.w_ValueError, - space.wrap("invalid literal after '#'")) - else: - try: - return self.enumerators2values[s] - except KeyError: - raise operationerrfmt(space.w_ValueError, - "'%s' is not an enumerator for %s", - s, self.name) +class W_CTypeEnumUnsigned(_Mixin_Enum, W_CTypePrimitiveUnsigned): + _attrs_ = ['enumerators2values', 'enumvalues2erators'] + _immutable_fields_ = ['enumerators2values', 'enumvalues2erators'] + kind = "enum" + _super = W_CTypePrimitiveUnsigned + + def _get_value(self, cdata): + # returns an unsigned long + assert self.value_fits_ulong + return misc.read_raw_ulong_data(cdata, self.size) diff --git a/pypy/module/_cffi_backend/ctypeobj.py b/pypy/module/_cffi_backend/ctypeobj.py --- a/pypy/module/_cffi_backend/ctypeobj.py +++ b/pypy/module/_cffi_backend/ctypeobj.py @@ -93,12 +93,18 @@ "not %s", self.name, expected, space.type(w_got).getname(space)) - def _check_subscript_index(self, w_cdata, i): + def _cannot_index(self): space = self.space raise operationerrfmt(space.w_TypeError, "cdata of type '%s' cannot be indexed", self.name) + def _check_subscript_index(self, w_cdata, i): + raise self._cannot_index() + + def _check_slice_index(self, w_cdata, start, stop): + raise self._cannot_index() + def string(self, cdataobj, maxlen): space = self.space raise operationerrfmt(space.w_TypeError, diff --git a/pypy/module/_cffi_backend/ctypeprim.py b/pypy/module/_cffi_backend/ctypeprim.py --- a/pypy/module/_cffi_backend/ctypeprim.py +++ b/pypy/module/_cffi_backend/ctypeprim.py @@ -171,9 +171,7 @@ self.vrangemax = (r_uint(1) << sh) - 1 def int(self, cdata): - # enums: really call convert_to_object() just below, - # and not the one overridden in W_CTypeEnum. - return W_CTypePrimitiveSigned.convert_to_object(self, cdata) + return self.convert_to_object(cdata) def convert_to_object(self, cdata): if self.value_fits_long: diff --git a/pypy/module/_cffi_backend/ctypeptr.py b/pypy/module/_cffi_backend/ctypeptr.py --- a/pypy/module/_cffi_backend/ctypeptr.py +++ b/pypy/module/_cffi_backend/ctypeptr.py @@ -174,9 +174,10 @@ class W_CTypePointer(W_CTypePtrBase): - _attrs_ = ['is_file'] - _immutable_fields_ = ['is_file'] + _attrs_ = ['is_file', 'cache_array_type'] + _immutable_fields_ = ['is_file', 'cache_array_type?'] kind = "pointer" + cache_array_type = None def __init__(self, space, ctitem): from pypy.module._cffi_backend import ctypearray @@ -185,7 +186,8 @@ extra = "(*)" # obscure case: see test_array_add else: extra = " *" - self.is_file = (ctitem.name == "struct _IO_FILE") + self.is_file = (ctitem.name == "struct _IO_FILE" or + ctitem.name == "struct $FILE") W_CTypePtrBase.__init__(self, space, size, extra, 2, ctitem) def newp(self, w_init): @@ -224,6 +226,9 @@ self.name) return self + def _check_slice_index(self, w_cdata, start, stop): + return self + def add(self, cdata, i): space = self.space ctitem = self.ctitem diff --git a/pypy/module/_cffi_backend/newtype.py b/pypy/module/_cffi_backend/newtype.py --- a/pypy/module/_cffi_backend/newtype.py +++ b/pypy/module/_cffi_backend/newtype.py @@ -1,7 +1,8 @@ from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.gateway import unwrap_spec from rpython.rtyper.lltypesystem import lltype, rffi -from rpython.rlib.rarithmetic import ovfcheck +from rpython.rlib.rarithmetic import ovfcheck, r_uint, intmask +from rpython.rlib.rarithmetic import most_neg_value_of, most_pos_value_of from rpython.rlib.objectmodel import specialize from pypy.module._cffi_backend import ctypeobj, ctypeprim, ctypeptr, ctypearray @@ -263,26 +264,38 @@ # ____________________________________________________________ - at unwrap_spec(name=str) -def new_enum_type(space, name, w_enumerators, w_enumvalues): + at unwrap_spec(name=str, basectype=ctypeobj.W_CType) +def new_enum_type(space, name, w_enumerators, w_enumvalues, basectype): enumerators_w = space.fixedview(w_enumerators) enumvalues_w = space.fixedview(w_enumvalues) if len(enumerators_w) != len(enumvalues_w): raise OperationError(space.w_ValueError, space.wrap("tuple args must have the same size")) enumerators = [space.str_w(w) for w in enumerators_w] - enumvalues = [] + # + if (not isinstance(basectype, ctypeprim.W_CTypePrimitiveSigned) and + not isinstance(basectype, ctypeprim.W_CTypePrimitiveUnsigned)): + raise OperationError(space.w_TypeError, + space.wrap("expected a primitive signed or unsigned base type")) + # + lvalue = lltype.malloc(rffi.CCHARP.TO, basectype.size, flavor='raw') try: for w in enumvalues_w: - enumvalues.append(space.c_int_w(w)) - except OperationError, e: - if not e.match(space, space.w_OverflowError): - raise - i = len(enumvalues) - raise operationerrfmt(space.w_OverflowError, - "enum '%s' declaration for '%s' does not fit an int", - name, enumerators[i]) - ctype = ctypeenum.W_CTypeEnum(space, name, enumerators, enumvalues) + # detects out-of-range or badly typed values + basectype.convert_from_object(lvalue, w) + finally: + lltype.free(lvalue, flavor='raw') + # + size = basectype.size + align = basectype.align + if isinstance(basectype, ctypeprim.W_CTypePrimitiveSigned): + enumvalues = [space.int_w(w) for w in enumvalues_w] + ctype = ctypeenum.W_CTypeEnumSigned(space, name, size, align, + enumerators, enumvalues) + else: + enumvalues = [space.uint_w(w) for w in enumvalues_w] + ctype = ctypeenum.W_CTypeEnumUnsigned(space, name, size, align, + enumerators, enumvalues) return ctype # ____________________________________________________________ @@ -302,8 +315,13 @@ # if ((fresult.size < 0 and not isinstance(fresult, ctypevoid.W_CTypeVoid)) or isinstance(fresult, ctypearray.W_CTypeArray)): - raise operationerrfmt(space.w_TypeError, - "invalid result type: '%s'", fresult.name) + if (isinstance(fresult, ctypestruct.W_CTypeStructOrUnion) and + fresult.size < 0): + raise operationerrfmt(space.w_TypeError, + "result type '%s' is opaque", fresult.name) + else: + raise operationerrfmt(space.w_TypeError, + "invalid result type: '%s'", fresult.name) # fct = ctypefunc.W_CTypeFunc(space, fargs, fresult, ellipsis) return fct diff --git a/pypy/module/_cffi_backend/test/_backend_test_c.py b/pypy/module/_cffi_backend/test/_backend_test_c.py --- a/pypy/module/_cffi_backend/test/_backend_test_c.py +++ b/pypy/module/_cffi_backend/test/_backend_test_c.py @@ -1264,80 +1264,130 @@ py.test.raises(TypeError, callback, BFunc, cb, -42) def test_enum_type(): - BEnum = new_enum_type("foo", (), ()) + BUInt = new_primitive_type("unsigned int") + BEnum = new_enum_type("foo", (), (), BUInt) assert repr(BEnum) == "" assert BEnum.kind == "enum" assert BEnum.cname == "enum foo" assert BEnum.elements == {} # - BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, -20)) + BInt = new_primitive_type("int") + BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, -20), BInt) assert BEnum.kind == "enum" assert BEnum.elements == {-20: 'ab', 0: 'def', 1: 'c'} # 'elements' is not the real dict, but merely a copy BEnum.elements[2] = '??' assert BEnum.elements == {-20: 'ab', 0: 'def', 1: 'c'} # From noreply at buildbot.pypy.org Fri Feb 22 13:53:45 2013 From: noreply at buildbot.pypy.org (mattip) Date: Fri, 22 Feb 2013 13:53:45 +0100 (CET) Subject: [pypy-commit] pypy default: add __all__ to numpypy,_numpypy Message-ID: <20130222125345.23B8B1C448A@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: Changeset: r61601:33e6916b90d8 Date: 2013-02-22 13:09 +0200 http://bitbucket.org/pypy/pypy/changeset/33e6916b90d8/ Log: add __all__ to numpypy,_numpypy diff --git a/lib_pypy/numpypy/__init__.py b/lib_pypy/numpypy/__init__.py --- a/lib_pypy/numpypy/__init__.py +++ b/lib_pypy/numpypy/__init__.py @@ -1,5 +1,8 @@ from _numpypy import * from .core import * +import _numpypy + +__all__ = _numpypy.__all__ import sys sys.modules.setdefault('numpy', sys.modules['numpypy']) diff --git a/pypy/module/micronumpy/__init__.py b/pypy/module/micronumpy/__init__.py --- a/pypy/module/micronumpy/__init__.py +++ b/pypy/module/micronumpy/__init__.py @@ -171,6 +171,11 @@ 'max': 'app_numpy.max', 'arange': 'app_numpy.arange', } + def setup_after_space_initialization(self): + space = self.space + w_all = space.wrap(sorted(Module.interpleveldefs.keys() + \ + Module.appleveldefs.keys())) + space.setitem(self.w_dict, space.new_interned_str('__all__'), w_all) if long_double_size == 16: Module.interpleveldefs['float128'] = 'interp_boxes.W_Float128Box' From noreply at buildbot.pypy.org Fri Feb 22 13:53:46 2013 From: noreply at buildbot.pypy.org (mattip) Date: Fri, 22 Feb 2013 13:53:46 +0100 (CET) Subject: [pypy-commit] pypy default: remove and expose functions differently, fix test to pass Message-ID: <20130222125346.B34EA1C448A@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: Changeset: r61602:74231eb5eee9 Date: 2013-02-22 14:03 +0200 http://bitbucket.org/pypy/pypy/changeset/74231eb5eee9/ Log: remove and expose functions differently, fix test to pass diff --git a/lib_pypy/numpypy/core/__init__.py b/lib_pypy/numpypy/core/__init__.py --- a/lib_pypy/numpypy/core/__init__.py +++ b/lib_pypy/numpypy/core/__init__.py @@ -1,3 +1,5 @@ from .fromnumeric import * from .numeric import * from .shape_base import * + +from _numpypy import abs, max, min diff --git a/pypy/module/micronumpy/__init__.py b/pypy/module/micronumpy/__init__.py --- a/pypy/module/micronumpy/__init__.py +++ b/pypy/module/micronumpy/__init__.py @@ -173,8 +173,16 @@ } def setup_after_space_initialization(self): space = self.space - w_all = space.wrap(sorted(Module.interpleveldefs.keys() + \ - Module.appleveldefs.keys())) + alllist = sorted(Module.interpleveldefs.keys() + \ + Module.appleveldefs.keys()) + # found by set(numpypy.__all__) - set(numpy.__all__) + alllist.remove('min') + alllist.remove('max') + alllist.remove('bool') + alllist.remove('int') + alllist.remove('abs') + alllist.remove('typeinfo') + w_all = space.wrap(alllist) space.setitem(self.w_dict, space.new_interned_str('__all__'), w_all) if long_double_size == 16: diff --git a/pypy/module/test_lib_pypy/numpypy/test_numpy.py b/pypy/module/test_lib_pypy/numpypy/test_numpy.py --- a/pypy/module/test_lib_pypy/numpypy/test_numpy.py +++ b/pypy/module/test_lib_pypy/numpypy/test_numpy.py @@ -11,6 +11,7 @@ def test_min_max_after_import(self): import __builtin__ + from __builtin__ import * from numpypy import * assert min is __builtin__.min From noreply at buildbot.pypy.org Fri Feb 22 13:53:47 2013 From: noreply at buildbot.pypy.org (mattip) Date: Fri, 22 Feb 2013 13:53:47 +0100 (CET) Subject: [pypy-commit] pypy default: merge heads Message-ID: <20130222125347.F0BFF1C448A@cobra.cs.uni-duesseldorf.de> Author: mattip Branch: Changeset: r61603:f5e56471a998 Date: 2013-02-22 14:43 +0200 http://bitbucket.org/pypy/pypy/changeset/f5e56471a998/ Log: merge heads diff --git a/rpython/rlib/objectmodel.py b/rpython/rlib/objectmodel.py --- a/rpython/rlib/objectmodel.py +++ b/rpython/rlib/objectmodel.py @@ -153,7 +153,8 @@ else: return type(arg) def typecheck(*args): - from rpython.annotator.model import SomeList, SomeDict, SomeChar + from rpython.annotator.model import SomeList, SomeDict, SomeChar,\ + SomeInteger for i, (expected_type, arg) in enumerate(zip(types, args)): if expected_type is None: continue @@ -167,6 +168,9 @@ if isinstance(s_expected, SomeChar) and ( isinstance(arg, str) and len(arg) == 1): # a char continue + if (isinstance(s_expected, SomeInteger) and + isinstance(arg, s_expected.knowntype)): + continue # s_argtype = get_annotation(get_type_descr_of_argument(arg)) if not s_expected.contains(s_argtype): diff --git a/rpython/rtyper/lltypesystem/rdict.py b/rpython/rtyper/lltypesystem/rdict.py --- a/rpython/rtyper/lltypesystem/rdict.py +++ b/rpython/rtyper/lltypesystem/rdict.py @@ -8,6 +8,7 @@ from rpython.rlib.rarithmetic import r_uint, intmask, LONG_BIT from rpython.rtyper import rmodel from rpython.rtyper.error import TyperError +from rpython.annotator.model import SomeInteger HIGHEST_BIT = intmask(1 << (LONG_BIT - 1)) @@ -385,39 +386,39 @@ # be direct_call'ed from rtyped flow graphs, which means that they will # get flowed and annotated, mostly with SomePtr. - at objectmodel.enforceargs(None, int) + at objectmodel.enforceargs(None, SomeInteger(nonneg=True)) def ll_everused_from_flag(entries, i): return entries[i].f_everused - at objectmodel.enforceargs(None, int) + at objectmodel.enforceargs(None, SomeInteger(nonneg=True)) def ll_everused_from_key(entries, i): return bool(entries[i].key) - at objectmodel.enforceargs(None, int) + at objectmodel.enforceargs(None, SomeInteger(nonneg=True)) def ll_everused_from_value(entries, i): return bool(entries[i].value) - at objectmodel.enforceargs(None, int) + at objectmodel.enforceargs(None, SomeInteger(nonneg=True)) def ll_valid_from_flag(entries, i): return entries[i].f_valid - at objectmodel.enforceargs(None, int) + at objectmodel.enforceargs(None, SomeInteger(nonneg=True)) def ll_mark_deleted_in_flag(entries, i): entries[i].f_valid = False - at objectmodel.enforceargs(None, int) + at objectmodel.enforceargs(None, SomeInteger(nonneg=True)) def ll_valid_from_key(entries, i): ENTRIES = lltype.typeOf(entries).TO dummy = ENTRIES.dummy_obj.ll_dummy_value return entries.everused(i) and entries[i].key != dummy - at objectmodel.enforceargs(None, int) + at objectmodel.enforceargs(None, SomeInteger(nonneg=True)) def ll_mark_deleted_in_key(entries, i): ENTRIES = lltype.typeOf(entries).TO dummy = ENTRIES.dummy_obj.ll_dummy_value entries[i].key = dummy - at objectmodel.enforceargs(None, int) + at objectmodel.enforceargs(None, SomeInteger(nonneg=True)) def ll_valid_from_value(entries, i): ENTRIES = lltype.typeOf(entries).TO dummy = ENTRIES.dummy_obj.ll_dummy_value @@ -525,6 +526,7 @@ @jit.look_inside_iff(lambda d, i: jit.isvirtual(d) and jit.isconstant(i)) def _ll_dict_del(d, i): + assert i >= 0 d.entries.mark_deleted(i) d.num_items -= 1 # clear the key and the value if they are GC pointers @@ -585,6 +587,7 @@ direct_compare = not hasattr(ENTRIES, 'no_direct_compare') mask = len(entries) - 1 i = hash & mask + assert i >= 0 # do the first try before any looping if entries.valid(i): checkingkey = entries[i].key @@ -615,6 +618,7 @@ i = r_uint(i) i = (i << 2) + i + perturb + 1 i = intmask(i) & mask + assert i >= 0 # keep 'i' as a signed number here, to consistently pass signed # arguments to the small helper methods. if not entries.everused(i): @@ -648,11 +652,13 @@ entries = d.entries mask = len(entries) - 1 i = hash & mask + assert i >= 0 perturb = r_uint(hash) while entries.everused(i): i = r_uint(i) i = (i << 2) + i + perturb + 1 i = intmask(i) & mask + assert i >= 0 perturb >>= PERTURB_SHIFT return i @@ -745,6 +751,7 @@ if dict: entries = dict.entries index = iter.index + assert index >= 0 entries_len = len(entries) while index < entries_len: entry = entries[index] From noreply at buildbot.pypy.org Fri Feb 22 14:02:23 2013 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 22 Feb 2013 14:02:23 +0100 (CET) Subject: [pypy-commit] cffi release-0.5: Mark the release 0.5. Message-ID: <20130222130223.EFF921C448A@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: release-0.5 Changeset: r1162:614a488a6ac5 Date: 2013-02-22 14:02 +0100 http://bitbucket.org/cffi/cffi/changeset/614a488a6ac5/ Log: Mark the release 0.5. From noreply at buildbot.pypy.org Fri Feb 22 14:10:04 2013 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 22 Feb 2013 14:10:04 +0100 (CET) Subject: [pypy-commit] cffi default: Skip running this file on top of PyPy. Message-ID: <20130222131004.56A8A1C448A@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r1163:b5273fb333c4 Date: 2013-02-22 14:09 +0100 http://bitbucket.org/cffi/cffi/changeset/b5273fb333c4/ Log: Skip running this file on top of PyPy. diff --git a/c/test_c.py b/c/test_c.py --- a/c/test_c.py +++ b/c/test_c.py @@ -1,6 +1,9 @@ import py def _setup_path(): import os, sys + if '__pypy__' in sys.builtin_module_names: + py.test.skip("_cffi_backend.c: not tested on top of pypy, " + "use pypy/module/_cffi_backend/test/ instead.") sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..')) _setup_path() from _cffi_backend import * From noreply at buildbot.pypy.org Fri Feb 22 14:20:18 2013 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 22 Feb 2013 14:20:18 +0100 (CET) Subject: [pypy-commit] cffi default: (lazka, arigo) Change dlopen() to accept either a full path or a library Message-ID: <20130222132018.9E0531C448A@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r1164:f0a4aaf197fe Date: 2013-02-22 14:19 +0100 http://bitbucket.org/cffi/cffi/changeset/f0a4aaf197fe/ Log: (lazka, arigo) Change dlopen() to accept either a full path or a library name. diff --git a/cffi/api.py b/cffi/api.py --- a/cffi/api.py +++ b/cffi/api.py @@ -345,17 +345,17 @@ name = libname if name is None: name = 'c' # on Posix only - if os.path.sep in name or ( - os.path.altsep is not None and os.path.altsep in name): - path = name - else: + backend = ffi._backend + try: + if '.' not in name and '/' not in name: + raise OSError + backendlib = backend.load_library(name, flags) + except OSError: import ctypes.util path = ctypes.util.find_library(name) if path is None: raise OSError("library not found: %r" % (name,)) - # - backend = ffi._backend - backendlib = backend.load_library(path, flags) + backendlib = backend.load_library(path, flags) # def make_accessor(name): key = 'function ' + name diff --git a/doc/source/index.rst b/doc/source/index.rst --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -439,9 +439,9 @@ The ``libpath`` is the file name of the shared library, which can contain a full path or not (in which case it is searched in standard -locations, as described in ``man dlopen``). Alternatively, if -``libpath`` is None, it returns the standard C library (which can be -used to access the functions of glibc, on Linux). +locations, as described in ``man dlopen``), with extensions or not. +Alternatively, if ``libpath`` is None, it returns the standard C library +(which can be used to access the functions of glibc, on Linux). This gives ABI-level access to the library: you need to have all types declared manually exactly as they were while the library was made. No diff --git a/testing/test_function.py b/testing/test_function.py --- a/testing/test_function.py +++ b/testing/test_function.py @@ -69,6 +69,17 @@ x = m.sin(1.23) assert x is None + def test_dlopen_filename(self): + if not os.path.exists('/ib/libm.so.6'): + py.test.skip("/lib/libm.so.6 does not exist") + ffi = FFI(backend=self.Backend()) + ffi.cdef(""" + double cos(double x); + """) + m = ffi.dlopen("/lib/libm.so.6") + x = m.cos(1.23) + assert x == math.cos(1.23) + def test_dlopen_flags(self): ffi = FFI(backend=self.Backend()) ffi.cdef(""" From noreply at buildbot.pypy.org Fri Feb 22 14:21:40 2013 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 22 Feb 2013 14:21:40 +0100 (CET) Subject: [pypy-commit] pypy stm-thread-2: Test and fix Message-ID: <20130222132140.019501C448A@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stm-thread-2 Changeset: r61605:6f3fb622e2f6 Date: 2013-02-22 13:41 +0100 http://bitbucket.org/pypy/pypy/changeset/6f3fb622e2f6/ Log: Test and fix diff --git a/pypy/module/__pypy__/interp_atomic.py b/pypy/module/__pypy__/interp_atomic.py --- a/pypy/module/__pypy__/interp_atomic.py +++ b/pypy/module/__pypy__/interp_atomic.py @@ -59,7 +59,8 @@ n = 0 while p[n] != 'e': n += 1 - return (space.int(space.wrap(rffi.charpsize2str(p, n))), + return (space.call_function(space.w_int, + space.wrap(rffi.charpsize2str(p, n))), rffi.ptradd(p, n + 1)) def bdecodelist(space, p): diff --git a/pypy/module/__pypy__/test/test_atomic.py b/pypy/module/__pypy__/test/test_atomic.py --- a/pypy/module/__pypy__/test/test_atomic.py +++ b/pypy/module/__pypy__/test/test_atomic.py @@ -4,32 +4,21 @@ from rpython.rtyper.lltypesystem import rffi -def test_bdecode(): - class FakeSpace: - def wrap(self, x): - assert isinstance(x, str) - return x - def int(self, x): - assert isinstance(x, str) - return int(x) - def newlist(self, lst): - assert isinstance(lst, list) - return lst +def test_bdecode(space): - space = FakeSpace() - - def bdec(s): + def bdec(s, expected): p = rffi.str2charp(s) w_obj, q = bdecode(space, p) assert q == rffi.ptradd(p, len(s)) rffi.free_charp(p) - return w_obj + w_expected = space.wrap(expected) + assert space.eq_w(w_obj, w_expected) - assert bdec("i123e") == 123 - assert bdec("i-123e") == -123 - assert bdec('12:+"*-%&/()=?\x00') == '+"*-%&/()=?\x00' - assert bdec("li123eli456eee") == [123, [456]] - assert bdec("l5:abcdei2ee") == ["abcde", 2] + bdec("i123e", 123) + bdec("i-123e", -123) + bdec('12:+"*-%&/()=?\x00', '+"*-%&/()=?\x00') + bdec("li123eli456eee", [123, [456]]) + bdec("l5:abcdei2ee", ["abcde", 2]) class AppTestAtomic(GenericTestThread): From noreply at buildbot.pypy.org Fri Feb 22 14:22:54 2013 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 22 Feb 2013 14:22:54 +0100 (CET) Subject: [pypy-commit] pypy stm-thread-2: Don't show the hidden_applevel frames. Message-ID: <20130222132254.2CB751C448A@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stm-thread-2 Changeset: r61606:b7e9b01e26eb Date: 2013-02-22 14:22 +0100 http://bitbucket.org/pypy/pypy/changeset/b7e9b01e26eb/ Log: Don't show the hidden_applevel frames. diff --git a/pypy/module/thread/stm.py b/pypy/module/thread/stm.py --- a/pypy/module/thread/stm.py +++ b/pypy/module/thread/stm.py @@ -29,12 +29,16 @@ def enter_frame(ec, frame): """Called from ExecutionContext.enter().""" + if frame.hide(): + return rstm.abort_info_push(frame.pycode, ('[', 'co_filename', 'co_name', 'co_firstlineno', 'co_lnotab')) rstm.abort_info_push(frame, ('last_instr', ']')) def leave_frame(ec, frame): """Called from ExecutionContext.leave().""" + if frame.hide(): + return rstm.abort_info_pop(2) From noreply at buildbot.pypy.org Fri Feb 22 14:33:15 2013 From: noreply at buildbot.pypy.org (RonnyPfannschmidt) Date: Fri, 22 Feb 2013 14:33:15 +0100 (CET) Subject: [pypy-commit] pypy refine-testrunner: some whitespace fixes Message-ID: <20130222133315.9ABB01C448D@cobra.cs.uni-duesseldorf.de> Author: Ronny Pfannschmidt Branch: refine-testrunner Changeset: r61607:6e6b7860748d Date: 2013-02-22 14:19 +0100 http://bitbucket.org/pypy/pypy/changeset/6e6b7860748d/ Log: some whitespace fixes diff --git a/testrunner/runner.py b/testrunner/runner.py --- a/testrunner/runner.py +++ b/testrunner/runner.py @@ -151,7 +151,7 @@ test_driver = [pytestpath] cherrypick = None - + def __init__(self, root, out): self.root = root self.out = out @@ -160,7 +160,7 @@ self.parallel_runs = 1 self.timeout = None self.cherrypick = None - + @classmethod def from_options(cls, opts, out): root = py.path.local(opts.root) @@ -176,7 +176,6 @@ self.runfunc = self.run return self - def log(self, fmt, *args): self.out.write((fmt % args) + '\n') @@ -199,7 +198,7 @@ def collect_testdirs(self, testdirs, p=None): if p is None: p = self.root - + reldir = self.reltoroot(p) entries = [p1 for p1 in p.listdir() if p1.check(dotfile=0)] entries.sort() diff --git a/testrunner/test/test_runner.py b/testrunner/test/test_runner.py --- a/testrunner/test/test_runner.py +++ b/testrunner/test/test_runner.py @@ -22,7 +22,6 @@ def pytest_funcarg__fakerun(self, request): return FakeRun() - def test_explicit(self, fakerun): res = runner.execute_test('/wd', 'test_one', 'out', 'LOGFILE', runfunc=fakerun, @@ -38,7 +37,7 @@ 'test_one'] - assert fakerun.called == (expected, '/wd', 'out', 'secs') + assert fakerun.called == (expected, '/wd', 'out', 'secs') assert res == 0 def test_explicit_win32(self, fakerun): @@ -64,7 +63,6 @@ test_driver=['driver', 'darg']) assert res == 1 - fakerun.exitcode = -signal.SIGSEGV res = runner.execute_test('/wd', 'test_one', 'out', 'LOGFILE', runfunc=fakerun, From noreply at buildbot.pypy.org Fri Feb 22 14:33:17 2013 From: noreply at buildbot.pypy.org (RonnyPfannschmidt) Date: Fri, 22 Feb 2013 14:33:17 +0100 (CET) Subject: [pypy-commit] pypy refine-testrunner: reenable junitxml output Message-ID: <20130222133317.058941C448D@cobra.cs.uni-duesseldorf.de> Author: Ronny Pfannschmidt Branch: refine-testrunner Changeset: r61608:7e90c4f418c3 Date: 2013-02-22 14:32 +0100 http://bitbucket.org/pypy/pypy/changeset/7e90c4f418c3/ Log: reenable junitxml output diff --git a/testrunner/runner.py b/testrunner/runner.py --- a/testrunner/runner.py +++ b/testrunner/runner.py @@ -14,7 +14,7 @@ args = interp + test_driver args += ['-p', 'resultlog', '--resultlog=%s' % logfname, - #'--junitxml=%s.junit' % logfname, + '--junitxml=%s.junit' % logfname, test] args = map(str, args) diff --git a/testrunner/test/test_runner.py b/testrunner/test/test_runner.py --- a/testrunner/test/test_runner.py +++ b/testrunner/test/test_runner.py @@ -33,7 +33,7 @@ 'driver', 'darg', '-p', 'resultlog', '--resultlog=LOGFILE', - #'--junitxml=LOGFILE.junit', + '--junitxml=LOGFILE.junit', 'test_one'] @@ -51,7 +51,7 @@ 'driver', 'darg', '-p', 'resultlog', '--resultlog=LOGFILE', - #'--junitxml=LOGFILE.junit', + '--junitxml=LOGFILE.junit', 'test_one'] assert args == expected From noreply at buildbot.pypy.org Fri Feb 22 16:00:51 2013 From: noreply at buildbot.pypy.org (amauryfa) Date: Fri, 22 Feb 2013 16:00:51 +0100 (CET) Subject: [pypy-commit] pypy default: Add a specific implementation of io.BufferedRandom.readline() Message-ID: <20130222150051.457641C479A@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: Changeset: r61609:fc116fc3fc9a Date: 2013-02-19 15:43 +0100 http://bitbucket.org/pypy/pypy/changeset/fc116fc3fc9a/ Log: Add a specific implementation of io.BufferedRandom.readline() it is most probably faster than the all-purpose IOBase.readline. diff --git a/pypy/module/_io/interp_bufferedio.py b/pypy/module/_io/interp_bufferedio.py --- a/pypy/module/_io/interp_bufferedio.py +++ b/pypy/module/_io/interp_bufferedio.py @@ -631,6 +631,71 @@ return res return None + def readline_w(self, space, w_limit=None): + self._check_init(space) + self._check_closed(space, "readline of closed file") + + limit = convert_size(space, w_limit) + + # First, try to find a line in the buffer. This can run + # unlocked because the calls to the C API are simple enough + # that they can't trigger any thread switch. + have = self._readahead() + if limit >= 0 and have > limit: + have = limit + for pos in range(self.pos, self.pos+have): + if self.buffer[pos] == '\n': + break + else: + pos = -1 + if pos >= 0: + w_res = space.wrap(''.join(self.buffer[self.pos:pos+1])) + self.pos = pos + 1 + return w_res + if have == limit: + w_res = space.wrap(''.join(self.buffer[self.pos:self.pos+have])) + self.pos += have + return w_res + + written = 0 + with self.lock: + # Now we try to get some more from the raw stream + chunks = [] + if have > 0: + chunks.extend(self.buffer[self.pos:self.pos+have]) + written += have + self.pos += have + if limit >= 0: + limit -= have + if self.writable: + self._flush_and_rewind_unlocked(space) + + while True: + self._reader_reset_buf() + have = self._fill_buffer(space) + if have == 0: + break + if limit >= 0 and have > limit: + have = limit + pos = 0 + while pos < have: + c = self.buffer[pos] + pos += 1 + if c == '\n': + self.pos = pos + found = True + break + chunks.extend(self.buffer[0:pos]) + if found: + break + if have == limit: + self.pos = have + break + written += have + if limit >= 0: + limit -= have + return space.wrap(''.join(chunks)) + # ____________________________________________________ # Write methods @@ -968,6 +1033,7 @@ read = interp2app(W_BufferedRandom.read_w), peek = interp2app(W_BufferedRandom.peek_w), read1 = interp2app(W_BufferedRandom.read1_w), + readline = interp2app(W_BufferedRandom.readline_w), write = interp2app(W_BufferedRandom.write_w), flush = interp2app(W_BufferedRandom.flush_w), diff --git a/pypy/module/_io/test/test_bufferedio.py b/pypy/module/_io/test/test_bufferedio.py --- a/pypy/module/_io/test/test_bufferedio.py +++ b/pypy/module/_io/test/test_bufferedio.py @@ -631,6 +631,19 @@ f.flush() assert raw.getvalue() == b'1b\n2def\n3\n' + def test_readline(self): + import _io as io + with io.BytesIO(b"abc\ndef\nxyzzy\nfoo\x00bar\nanother line") as raw: + with io.BufferedRandom(raw) as f: + assert f.readline() == b"abc\n" + assert f.readline(10) == b"def\n" + assert f.readline(2) == b"xy" + assert f.readline(4) == b"zzy\n" + assert f.readline() == b"foo\x00bar\n" + assert f.readline(None) == b"another line" + raises(TypeError, f.readline, 5.3) + + class TestNonReentrantLock: spaceconfig = dict(usemodules=['thread']) From noreply at buildbot.pypy.org Fri Feb 22 16:00:52 2013 From: noreply at buildbot.pypy.org (amauryfa) Date: Fri, 22 Feb 2013 16:00:52 +0100 (CET) Subject: [pypy-commit] pypy default: Test and fix Message-ID: <20130222150052.987E91C478E@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: Changeset: r61610:19d28dd680a1 Date: 2013-02-22 15:37 +0100 http://bitbucket.org/pypy/pypy/changeset/19d28dd680a1/ Log: Test and fix diff --git a/pypy/module/_io/interp_bufferedio.py b/pypy/module/_io/interp_bufferedio.py --- a/pypy/module/_io/interp_bufferedio.py +++ b/pypy/module/_io/interp_bufferedio.py @@ -678,6 +678,7 @@ if limit >= 0 and have > limit: have = limit pos = 0 + found = False while pos < have: c = self.buffer[pos] pos += 1 diff --git a/pypy/module/_io/test/test_bufferedio.py b/pypy/module/_io/test/test_bufferedio.py --- a/pypy/module/_io/test/test_bufferedio.py +++ b/pypy/module/_io/test/test_bufferedio.py @@ -634,7 +634,7 @@ def test_readline(self): import _io as io with io.BytesIO(b"abc\ndef\nxyzzy\nfoo\x00bar\nanother line") as raw: - with io.BufferedRandom(raw) as f: + with io.BufferedRandom(raw, buffer_size=10) as f: assert f.readline() == b"abc\n" assert f.readline(10) == b"def\n" assert f.readline(2) == b"xy" From noreply at buildbot.pypy.org Fri Feb 22 16:40:30 2013 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 22 Feb 2013 16:40:30 +0100 (CET) Subject: [pypy-commit] cffi default: (lazka) improve the test, and fix a typo (bad arigo) Message-ID: <20130222154030.DB0451C4799@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r1165:54a7e200479b Date: 2013-02-22 16:40 +0100 http://bitbucket.org/cffi/cffi/changeset/54a7e200479b/ Log: (lazka) improve the test, and fix a typo (bad arigo) diff --git a/testing/test_function.py b/testing/test_function.py --- a/testing/test_function.py +++ b/testing/test_function.py @@ -1,6 +1,7 @@ import py from cffi import FFI import math, os, sys +import ctypes.util from cffi.backend_ctypes import CTypesBackend from testing.udir import udir @@ -70,13 +71,18 @@ assert x is None def test_dlopen_filename(self): - if not os.path.exists('/ib/libm.so.6'): - py.test.skip("/lib/libm.so.6 does not exist") + path = ctypes.util.find_library("m") + if not path: + py.test.skip("libm not found") ffi = FFI(backend=self.Backend()) ffi.cdef(""" double cos(double x); """) - m = ffi.dlopen("/lib/libm.so.6") + m = ffi.dlopen(path) + x = m.cos(1.23) + assert x == math.cos(1.23) + + m = ffi.dlopen(os.path.basename(path)) x = m.cos(1.23) assert x == math.cos(1.23) From noreply at buildbot.pypy.org Fri Feb 22 16:51:25 2013 From: noreply at buildbot.pypy.org (jerith) Date: Fri, 22 Feb 2013 16:51:25 +0100 (CET) Subject: [pypy-commit] pypy default: Fix enumerating oo rlists. Message-ID: <20130222155125.B34E21C479F@cobra.cs.uni-duesseldorf.de> Author: Jeremy Thurgood Branch: Changeset: r61611:12bfeabef144 Date: 2013-02-22 17:20 +0200 http://bitbucket.org/pypy/pypy/changeset/12bfeabef144/ Log: Fix enumerating oo rlists. diff --git a/rpython/rtyper/ootypesystem/rlist.py b/rpython/rtyper/ootypesystem/rlist.py --- a/rpython/rtyper/ootypesystem/rlist.py +++ b/rpython/rtyper/ootypesystem/rlist.py @@ -241,6 +241,7 @@ def __init__(self, r_list): self.r_list = r_list + self.external_item_repr = r_list.external_item_repr self.lowleveltype = ootype.Record( {"iterable": r_list.lowleveltype, "index": ootype.Signed}) self.ll_listiter = ll_listiter From noreply at buildbot.pypy.org Fri Feb 22 16:51:26 2013 From: noreply at buildbot.pypy.org (jerith) Date: Fri, 22 Feb 2013 16:51:26 +0100 (CET) Subject: [pypy-commit] pypy default: Fix enumerating oo unicode rstrs and add whatsnew. Message-ID: <20130222155126.F3FB81C479F@cobra.cs.uni-duesseldorf.de> Author: Jeremy Thurgood Branch: Changeset: r61612:e4ab0b234c2b Date: 2013-02-22 17:47 +0200 http://bitbucket.org/pypy/pypy/changeset/e4ab0b234c2b/ Log: Fix enumerating oo unicode rstrs and add whatsnew. diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst --- a/pypy/doc/whatsnew-head.rst +++ b/pypy/doc/whatsnew-head.rst @@ -68,3 +68,6 @@ .. branch: coding-guide-update-rlib-refs .. branch: rlib-doc-rpython-refs + +.. branch: enumerate-rstr +Support enumerate() over rstr types. diff --git a/rpython/rtyper/ootypesystem/rstr.py b/rpython/rtyper/ootypesystem/rstr.py --- a/rpython/rtyper/ootypesystem/rstr.py +++ b/rpython/rtyper/ootypesystem/rstr.py @@ -445,6 +445,7 @@ def __init__(self): self.ll_striter = ll_unicodeiter self.ll_strnext = ll_strnext + self.ll_getnextindex = ll_getnextindex def ll_striter(string): iter = ootype.new(string_repr.string_iterator_repr.lowleveltype) From noreply at buildbot.pypy.org Fri Feb 22 16:57:52 2013 From: noreply at buildbot.pypy.org (amauryfa) Date: Fri, 22 Feb 2013 16:57:52 +0100 (CET) Subject: [pypy-commit] pypy missing-os-functions: hg merge default Message-ID: <20130222155752.27B121C4763@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: missing-os-functions Changeset: r61613:69e12d1c8fd1 Date: 2013-02-22 16:09 +0100 http://bitbucket.org/pypy/pypy/changeset/69e12d1c8fd1/ Log: hg merge default diff too long, truncating to 2000 out of 6964 lines diff --git a/lib-python/2.7/test/test_generators.py b/lib-python/2.7/test/test_generators.py --- a/lib-python/2.7/test/test_generators.py +++ b/lib-python/2.7/test/test_generators.py @@ -1501,9 +1501,7 @@ """ coroutine_tests = """\ -A helper function to call gc.collect() without printing ->>> import gc ->>> def gc_collect(): gc.collect() +>>> from test.test_support import gc_collect Sending a value into a started generator: @@ -1823,8 +1821,7 @@ references. We add it to the standard suite so the routine refleak-tests would trigger if it starts being uncleanable again. ->>> import gc ->>> def gc_collect(): gc.collect() +>>> from test.test_support import gc_collect >>> import itertools >>> def leak(): diff --git a/lib-python/conftest.py b/lib-python/conftest.py --- a/lib-python/conftest.py +++ b/lib-python/conftest.py @@ -272,7 +272,7 @@ RegrTest('test_inspect.py'), RegrTest('test_int.py', core=True), RegrTest('test_int_literal.py', core=True), - RegrTest('test_io.py'), + RegrTest('test_io.py', usemodules='array binascii'), RegrTest('test_ioctl.py'), RegrTest('test_isinstance.py', core=True), RegrTest('test_iter.py', core=True), diff --git a/lib_pypy/datetime.py b/lib_pypy/datetime.py --- a/lib_pypy/datetime.py +++ b/lib_pypy/datetime.py @@ -271,6 +271,8 @@ raise ValueError("%s()=%d, must be in -1439..1439" % (name, offset)) def _check_int_field(value): + if isinstance(value, int): + return value if not isinstance(value, float): try: value = value.__int__() @@ -279,7 +281,7 @@ else: if isinstance(value, (int, long)): return value - raise TypeError('integer argument expected') + raise TypeError('an integer is required') def _check_date_fields(year, month, day): year = _check_int_field(year) @@ -457,6 +459,8 @@ felt like it. """ + __slots__ = '_days', '_seconds', '_microseconds' + def __new__(cls, days=0, seconds=0, microseconds=0, # XXX The following should only be used as keyword args: milliseconds=0, minutes=0, hours=0, weeks=0): @@ -770,6 +774,8 @@ year, month, day """ + __slots__ = '_year', '_month', '_day' + def __new__(cls, year, month=None, day=None): """Constructor. @@ -777,7 +783,7 @@ year, month, day (required, base 1) """ - if isinstance(year, str): + if isinstance(year, str) and len(year) == 4: # Pickle support self = object.__new__(cls) self.__setstate(year) @@ -1063,6 +1069,8 @@ Subclasses must override the name(), utcoffset() and dst() methods. """ + __slots__ = () + def tzname(self, dt): "datetime -> string name of time zone." raise NotImplementedError("tzinfo subclass must override tzname()") @@ -1155,6 +1163,8 @@ hour, minute, second, microsecond, tzinfo """ + __slots__ = '_hour', '_minute', '_second', '_microsecond', '_tzinfo' + def __new__(cls, hour=0, minute=0, second=0, microsecond=0, tzinfo=None): """Constructor. @@ -1457,9 +1467,11 @@ instance of a tzinfo subclass. The remaining arguments may be ints or longs. """ + __slots__ = date.__slots__ + time.__slots__ + def __new__(cls, year, month=None, day=None, hour=0, minute=0, second=0, microsecond=0, tzinfo=None): - if isinstance(year, str): + if isinstance(year, str) and len(year) == 10: # Pickle support self = date.__new__(cls, year[:4]) self.__setstate(year, month) diff --git a/lib_pypy/numpypy/__init__.py b/lib_pypy/numpypy/__init__.py --- a/lib_pypy/numpypy/__init__.py +++ b/lib_pypy/numpypy/__init__.py @@ -1,5 +1,8 @@ from _numpypy import * from .core import * +import _numpypy + +__all__ = _numpypy.__all__ import sys sys.modules.setdefault('numpy', sys.modules['numpypy']) diff --git a/lib_pypy/numpypy/core/__init__.py b/lib_pypy/numpypy/core/__init__.py --- a/lib_pypy/numpypy/core/__init__.py +++ b/lib_pypy/numpypy/core/__init__.py @@ -1,3 +1,5 @@ from .fromnumeric import * from .numeric import * from .shape_base import * + +from _numpypy import abs, max, min diff --git a/pypy/doc/_ref.txt b/pypy/doc/_ref.txt --- a/pypy/doc/_ref.txt +++ b/pypy/doc/_ref.txt @@ -1,24 +1,19 @@ .. _`ctypes_configure/doc/sample.py`: https://bitbucket.org/pypy/pypy/src/default/ctypes_configure/doc/sample.py -.. _`demo/`: https://bitbucket.org/pypy/pypy/src/default/demo/ +.. _`dotviewer/`: https://bitbucket.org/pypy/pypy/src/default/dotviewer/ .. _`lib-python/`: https://bitbucket.org/pypy/pypy/src/default/lib-python/ .. _`lib-python/2.7/dis.py`: https://bitbucket.org/pypy/pypy/src/default/lib-python/2.7/dis.py .. _`lib_pypy/`: https://bitbucket.org/pypy/pypy/src/default/lib_pypy/ .. _`lib_pypy/greenlet.py`: https://bitbucket.org/pypy/pypy/src/default/lib_pypy/greenlet.py .. _`lib_pypy/pypy_test/`: https://bitbucket.org/pypy/pypy/src/default/lib_pypy/pypy_test/ .. _`lib_pypy/tputil.py`: https://bitbucket.org/pypy/pypy/src/default/lib_pypy/tputil.py -.. _`pypy/annotation`: -.. _`pypy/annotation/`: https://bitbucket.org/pypy/pypy/src/default/pypy/annotation/ -.. _`pypy/annotation/annrpython.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/annotation/annrpython.py -.. _`pypy/annotation/binaryop.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/annotation/binaryop.py -.. _`pypy/annotation/builtin.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/annotation/builtin.py .. _`pypy/bin/`: https://bitbucket.org/pypy/pypy/src/default/pypy/bin/ -.. _`pypy/bin/translatorshell.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/bin/translatorshell.py +.. _`pypy/bin/pyinteractive.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/bin/pyinteractive.py .. _`pypy/config/`: https://bitbucket.org/pypy/pypy/src/default/pypy/config/ .. _`pypy/config/pypyoption.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/config/pypyoption.py -.. _`pypy/config/translationoption.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/config/translationoption.py .. _`pypy/doc/`: https://bitbucket.org/pypy/pypy/src/default/pypy/doc/ .. _`pypy/doc/config/`: https://bitbucket.org/pypy/pypy/src/default/pypy/doc/config/ .. _`pypy/doc/discussion/`: https://bitbucket.org/pypy/pypy/src/default/pypy/doc/discussion/ +.. _`pypy/goal/`: https://bitbucket.org/pypy/pypy/src/default/pypy/goal/ .. _`pypy/interpreter`: .. _`pypy/interpreter/`: https://bitbucket.org/pypy/pypy/src/default/pypy/interpreter/ .. _`pypy/interpreter/argument.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/interpreter/argument.py @@ -54,11 +49,8 @@ .. _`pypy/module`: .. _`pypy/module/`: https://bitbucket.org/pypy/pypy/src/default/pypy/module/ .. _`pypy/module/__builtin__/__init__.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/module/__builtin__/__init__.py -.. _`pypy/objspace`: .. _`pypy/objspace/`: https://bitbucket.org/pypy/pypy/src/default/pypy/objspace/ -.. _`pypy/objspace/flow`: .. _`pypy/objspace/flow/`: https://bitbucket.org/pypy/pypy/src/default/pypy/objspace/flow/ -.. _`pypy/objspace/flow/model.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/objspace/flow/model.py .. _`pypy/objspace/std`: .. _`pypy/objspace/std/`: https://bitbucket.org/pypy/pypy/src/default/pypy/objspace/std/ .. _`pypy/objspace/std/listtype.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/objspace/std/listtype.py @@ -70,49 +62,55 @@ .. _`pypy/objspace/std/transparent.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/objspace/std/transparent.py .. _`pypy/objspace/std/tupleobject.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/objspace/std/tupleobject.py .. _`pypy/objspace/std/tupletype.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/objspace/std/tupletype.py -.. _`pypy/rlib`: -.. _`pypy/rlib/`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/ -.. _`pypy/rlib/listsort.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/listsort.py -.. _`pypy/rlib/nonconst.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/nonconst.py -.. _`pypy/rlib/objectmodel.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/objectmodel.py -.. _`pypy/rlib/parsing/`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/parsing/ -.. _`pypy/rlib/parsing/tree.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/parsing/tree.py -.. _`pypy/rlib/rarithmetic.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/rarithmetic.py -.. _`pypy/rlib/rbigint.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/rbigint.py -.. _`pypy/rlib/rrandom.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/rrandom.py -.. _`pypy/rlib/rsocket.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/rsocket.py -.. _`pypy/rlib/streamio.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/streamio.py -.. _`pypy/rlib/test`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/test/ -.. _`pypy/rlib/unroll.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/unroll.py -.. _`pypy/rpython`: -.. _`pypy/rpython/`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/ -.. _`pypy/rpython/lltypesystem/`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/lltypesystem/ -.. _`pypy/rpython/lltypesystem/lltype.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/lltypesystem/lltype.py -.. _`pypy/rpython/memory/`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/memory/ -.. _`pypy/rpython/memory/gc/generation.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/memory/gc/generation.py -.. _`pypy/rpython/memory/gc/hybrid.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/memory/gc/hybrid.py -.. _`pypy/rpython/memory/gc/markcompact.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/memory/gc/markcompact.py -.. _`pypy/rpython/memory/gc/marksweep.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/memory/gc/marksweep.py -.. _`pypy/rpython/memory/gc/minimarkpage.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/memory/gc/minimarkpage.py -.. _`pypy/rpython/memory/gc/semispace.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/memory/gc/semispace.py -.. _`pypy/rpython/ootypesystem/`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/ootypesystem/ -.. _`pypy/rpython/ootypesystem/ootype.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/ootypesystem/ootype.py -.. _`pypy/rpython/rint.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/rint.py -.. _`pypy/rpython/rlist.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/rlist.py -.. _`pypy/rpython/rmodel.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/rmodel.py -.. _`pypy/rpython/rtyper.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/rtyper.py -.. _`pypy/rpython/test/test_llinterp.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/test/test_llinterp.py .. _`pypy/tool/`: https://bitbucket.org/pypy/pypy/src/default/pypy/tool/ .. _`pypy/tool/algo/`: https://bitbucket.org/pypy/pypy/src/default/pypy/tool/algo/ .. _`pypy/tool/pytest/`: https://bitbucket.org/pypy/pypy/src/default/pypy/tool/pytest/ -.. _`pypy/tool/traceconfig.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/tool/traceconfig.py -.. _`pypy/translator`: -.. _`pypy/translator/`: https://bitbucket.org/pypy/pypy/src/default/pypy/translator/ -.. _`pypy/translator/backendopt/`: https://bitbucket.org/pypy/pypy/src/default/pypy/translator/backendopt/ -.. _`pypy/translator/c/`: https://bitbucket.org/pypy/pypy/src/default/pypy/translator/c/ -.. _`pypy/translator/c/src/stacklet/`: https://bitbucket.org/pypy/pypy/src/default/pypy/translator/c/src/stacklet/ -.. _`pypy/translator/c/src/stacklet/stacklet.h`: https://bitbucket.org/pypy/pypy/src/default/pypy/translator/c/src/stacklet/stacklet.h -.. _`pypy/translator/cli/`: https://bitbucket.org/pypy/pypy/src/default/pypy/translator/cli/ -.. _`pypy/translator/goal/`: https://bitbucket.org/pypy/pypy/src/default/pypy/translator/goal/ -.. _`pypy/translator/jvm/`: https://bitbucket.org/pypy/pypy/src/default/pypy/translator/jvm/ -.. _`pypy/translator/tool/`: https://bitbucket.org/pypy/pypy/src/default/pypy/translator/tool/ +.. _`rpython/annotator`: +.. _`rpython/annotator/`: https://bitbucket.org/pypy/pypy/src/default/rpython/annotator/ +.. _`rpython/annotator/annrpython.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/annotator/annrpython.py +.. _`rpython/annotator/binaryop.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/annotator/binaryop.py +.. _`rpython/annotator/builtin.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/annotator/builtin.py +.. _`rpython/bin/translatorshell.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/bin/translatorshell.py +.. _`rpython/config/`: https://bitbucket.org/pypy/pypy/src/default/rpython/config/ +.. _`rpython/config/translationoption.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/config/translationoption.py +.. _`rpython/flowspace/`: https://bitbucket.org/pypy/pypy/src/default/rpython/flowspace/ +.. _`rpython/flowspace/model.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/flowspace/model.py +.. _`rpython/rlib`: +.. _`rpython/rlib/`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/ +.. _`rpython/rlib/listsort.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/listsort.py +.. _`rpython/rlib/nonconst.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/nonconst.py +.. _`rpython/rlib/objectmodel.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/objectmodel.py +.. _`rpython/rlib/parsing/`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/parsing/ +.. _`rpython/rlib/parsing/tree.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/parsing/tree.py +.. _`rpython/rlib/rarithmetic.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/rarithmetic.py +.. _`rpython/rlib/rbigint.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/rbigint.py +.. _`rpython/rlib/rrandom.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/rrandom.py +.. _`rpython/rlib/rsocket.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/rsocket.py +.. _`rpython/rlib/streamio.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/streamio.py +.. _`rpython/rlib/test`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/test/ +.. _`rpython/rlib/unroll.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/unroll.py +.. _`rpython/rtyper`: +.. _`rpython/rtyper/`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/ +.. _`rpython/rtyper/lltypesystem/`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/lltypesystem/ +.. _`rpython/rtyper/lltypesystem/lltype.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/lltypesystem/lltype.py +.. _`rpython/rtyper/memory/`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/memory/ +.. _`rpython/rtyper/memory/gc/generation.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/memory/gc/generation.py +.. _`rpython/rtyper/memory/gc/hybrid.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/memory/gc/hybrid.py +.. _`rpython/rtyper/memory/gc/minimarkpage.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/memory/gc/minimarkpage.py +.. _`rpython/rtyper/memory/gc/semispace.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/memory/gc/semispace.py +.. _`rpython/rtyper/ootypesystem/`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/ootypesystem/ +.. _`rpython/rtyper/ootypesystem/ootype.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/ootypesystem/ootype.py +.. _`rpython/rtyper/rint.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/rint.py +.. _`rpython/rtyper/rlist.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/rlist.py +.. _`rpython/rtyper/rmodel.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/rmodel.py +.. _`rpython/rtyper/rtyper.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/rtyper.py +.. _`rpython/rtyper/test/test_llinterp.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/test/test_llinterp.py +.. _`rpython/translator`: +.. _`rpython/translator/`: https://bitbucket.org/pypy/pypy/src/default/rpython/translator/ +.. _`rpython/translator/backendopt/`: https://bitbucket.org/pypy/pypy/src/default/rpython/translator/backendopt/ +.. _`rpython/translator/c/`: https://bitbucket.org/pypy/pypy/src/default/rpython/translator/c/ +.. _`rpython/translator/c/src/stacklet/`: https://bitbucket.org/pypy/pypy/src/default/rpython/translator/c/src/stacklet/ +.. _`rpython/translator/c/src/stacklet/stacklet.h`: https://bitbucket.org/pypy/pypy/src/default/rpython/translator/c/src/stacklet/stacklet.h +.. _`rpython/translator/cli/`: https://bitbucket.org/pypy/pypy/src/default/rpython/translator/cli/ +.. _`rpython/translator/jvm/`: https://bitbucket.org/pypy/pypy/src/default/rpython/translator/jvm/ +.. _`rpython/translator/tool/`: https://bitbucket.org/pypy/pypy/src/default/rpython/translator/tool/ diff --git a/pypy/doc/coding-guide.rst b/pypy/doc/coding-guide.rst --- a/pypy/doc/coding-guide.rst +++ b/pypy/doc/coding-guide.rst @@ -303,7 +303,7 @@ dicts with a unique key type only, provided it is hashable. Custom hash functions and custom equality will not be honored. - Use ``pypy.rlib.objectmodel.r_dict`` for custom hash functions. + Use ``rpython.rlib.objectmodel.r_dict`` for custom hash functions. **list comprehensions** @@ -328,7 +328,7 @@ **builtin functions** A number of builtin functions can be used. The precise set can be - found in `pypy/annotation/builtin.py`_ (see ``def builtin_xxx()``). + found in `rpython/annotator/builtin.py`_ (see ``def builtin_xxx()``). Some builtin functions may be limited in what they support, though. ``int, float, str, ord, chr``... are available as simple conversion @@ -365,7 +365,7 @@ We use normal integers for signed arithmetic. It means that before translation we get longs in case of overflow, and after translation we get a silent wrap-around. Whenever we need more control, we use the following -helpers (which live the `pypy/rlib/rarithmetic.py`_): +helpers (which live in `rpython/rlib/rarithmetic.py`_): **ovfcheck()** diff --git a/pypy/doc/configuration.rst b/pypy/doc/configuration.rst --- a/pypy/doc/configuration.rst +++ b/pypy/doc/configuration.rst @@ -188,7 +188,7 @@ toolchain`_ toolchain, have two separate sets of options. The translation toolchain options can be found on the ``config`` attribute of all ``TranslationContext`` -instances and are described in `pypy/config/translationoption.py`_. The interpreter options +instances and are described in `rpython/config/translationoption.py`_. The interpreter options are attached to the object space, also under the name ``config`` and are described in `pypy/config/pypyoption.py`_. diff --git a/pypy/doc/ctypes-implementation.rst b/pypy/doc/ctypes-implementation.rst --- a/pypy/doc/ctypes-implementation.rst +++ b/pypy/doc/ctypes-implementation.rst @@ -38,7 +38,7 @@ in dynamic libraries through libffi. Freeing objects in most cases and making sure that objects referring to each other are kept alive is responsibility of the higher levels. -This module uses bindings to libffi which are defined in ``pypy/rlib/libffi.py``. +This module uses bindings to libffi which are defined in ``rpython/rlib/libffi.py``. We tried to keep this module as small as possible. It is conceivable that other implementations (e.g. Jython) could use our ctypes diff --git a/pypy/doc/discussion/improve-rpython.rst b/pypy/doc/discussion/improve-rpython.rst --- a/pypy/doc/discussion/improve-rpython.rst +++ b/pypy/doc/discussion/improve-rpython.rst @@ -39,7 +39,7 @@ - Allocate variables on the stack, and pass their address ("by reference") to llexternal functions. For a typical usage, see - `pypy.rlib.rsocket.RSocket.getsockopt_int`. + `rpython.rlib.rsocket.RSocket.getsockopt_int`. Extensible type system for llexternal ------------------------------------- diff --git a/pypy/doc/garbage_collection.rst b/pypy/doc/garbage_collection.rst --- a/pypy/doc/garbage_collection.rst +++ b/pypy/doc/garbage_collection.rst @@ -42,7 +42,7 @@ Two arenas of equal size, with only one arena in use and getting filled with new objects. When the arena is full, the live objects are copied into the other arena using Cheney's algorithm. The old arena is then -cleared. See `pypy/rpython/memory/gc/semispace.py`_. +cleared. See `rpython/rtyper/memory/gc/semispace.py`_. On Unix the clearing is done by reading ``/dev/zero`` into the arena, which is extremely memory efficient at least on Linux: it lets the @@ -55,7 +55,7 @@ Generational GC --------------- -This is a two-generations GC. See `pypy/rpython/memory/gc/generation.py`_. +This is a two-generations GC. See `rpython/rtyper/memory/gc/generation.py`_. It is implemented as a subclass of the Semispace copying collector. It adds a nursery, which is a chunk of the current semispace. Its size is @@ -86,7 +86,7 @@ Each generation is collected much less often than the previous one. The division of the generations is slightly more complicated than just nursery / semispace / external; see the diagram at the start of the -source code, in `pypy/rpython/memory/gc/hybrid.py`_. +source code, in `rpython/rtyper/memory/gc/hybrid.py`_. Mark & Compact GC ----------------- @@ -161,7 +161,7 @@ to the old stage. The dying case 2 objects are immediately freed. - The old stage is an area of memory containing old (small) objects. It - is handled by `pypy/rpython/memory/gc/minimarkpage.py`_. It is organized + is handled by `rpython/rtyper/memory/gc/minimarkpage.py`_. It is organized as "arenas" of 256KB or 512KB, subdivided into "pages" of 4KB or 8KB. Each page can either be free, or contain small objects of all the same size. Furthermore at any point in time each object location can be diff --git a/pypy/doc/getting-started-dev.rst b/pypy/doc/getting-started-dev.rst --- a/pypy/doc/getting-started-dev.rst +++ b/pypy/doc/getting-started-dev.rst @@ -58,8 +58,7 @@ only use low level types that are available in C (e.g. int). The compiled version is now in a ``.so`` library. You can run it say using ctypes: - >>> from ctypes import CDLL - >>> f = CDLL(lib) + >>> f = get_c_function(lib, snippet.is_perfect_number) >>> f(5) 0 >>> f(6) @@ -173,23 +172,23 @@ ``xxxobject.py`` contain respectively the definition of the type and its (default) implementation. -* `pypy/translator`_ contains the code analysis and generation stuff. +* `rpython/translator`_ contains the code analysis and generation stuff. Start reading from translator.py, from which it should be easy to follow the pieces of code involved in the various translation phases. -* `pypy/annotation`_ contains the data model for the type annotation that +* `rpython/annotator`_ contains the data model for the type annotation that can be inferred about a graph. The graph "walker" that uses this is in - `pypy/annotation/annrpython.py`_. + `rpython/annotator/annrpython.py`_. -* `pypy/rpython`_ contains the code of the RPython typer. The typer transforms +* `rpython/rtyper`_ contains the code of the RPython typer. The typer transforms annotated flow graphs in a way that makes them very similar to C code so that they can be easy translated. The graph transformations are controlled - by the code in `pypy/rpython/rtyper.py`_. The object model that is used can - be found in `pypy/rpython/lltypesystem/lltype.py`_. For each RPython type + by the code in `rpython/rtyper/rtyper.py`_. The object model that is used can + be found in `rpython/rtyper/lltypesystem/lltype.py`_. For each RPython type there is a file rxxxx.py that contains the low level functions needed for this type. -* `pypy/rlib`_ contains the `RPython standard library`_, things that you can +* `rpython/rlib`_ contains the `RPython standard library`_, things that you can use from rpython. .. _`RPython standard library`: rlib.html @@ -320,10 +319,10 @@ Demos ------- -The `demo/`_ directory contains examples of various aspects of PyPy, -ranging from running regular Python programs (that we used as compliance goals) -over experimental distribution mechanisms to examples translating -sufficiently static programs into low level code. +The `example-interpreter`_ repository contains an example interpreter +written using the RPython translation toolchain. + +.. _`example-interpreter`: https://bitbucket.org/pypy/example-interpreter Additional Tools for running (and hacking) PyPy ----------------------------------------------- diff --git a/pypy/doc/index.rst b/pypy/doc/index.rst --- a/pypy/doc/index.rst +++ b/pypy/doc/index.rst @@ -217,17 +217,20 @@ Here is a fully referenced alphabetical two-level deep directory overview of PyPy: -================================ =========================================== +================================= ============================================ Directory explanation/links -================================ =========================================== +================================= ============================================ +`pypy/bin/`_ command-line scripts, mainly + `pypy/bin/pyinteractive.py`_ -`pypy/bin/`_ command-line scripts, mainly `pyinteractive.py`_ +`pypy/config/`_ handles the numerous options for building + and running PyPy -`pypy/config/`_ handles the numerous options for building and running PyPy +`pypy/doc/`_ text versions of PyPy developer + documentation -`pypy/doc/`_ text versions of PyPy developer documentation - -`pypy/doc/config/`_ documentation for the numerous translation options +`pypy/doc/config/`_ documentation for the numerous translation + options `pypy/doc/discussion/`_ drafts of ideas and documentation @@ -238,19 +241,24 @@ `pypy/interpreter/pyparser/`_ interpreter-level Python source parser -`pypy/interpreter/astcompiler/`_ interpreter-level bytecode compiler, via an AST - representation +`pypy/interpreter/astcompiler/`_ interpreter-level bytecode compiler, + via an AST representation -`pypy/module/`_ contains `mixed modules`_ implementing core modules with +`pypy/module/`_ contains `mixed modules`_ + implementing core modules with both application and interpreter level code. - Not all are finished and working. Use the ``--withmod-xxx`` - or ``--allworkingmodules`` translation options. + Not all are finished and working. Use + the ``--withmod-xxx`` + or ``--allworkingmodules`` translation + options. `pypy/objspace/`_ `object space`_ implementations -`pypy/objspace/std/`_ the StdObjSpace_ implementing CPython's objects and types +`pypy/objspace/std/`_ the StdObjSpace_ implementing CPython's + objects and types -`pypy/tool/`_ various utilities and hacks used from various places +`pypy/tool/`_ various utilities and hacks used + from various places `pypy/tool/algo/`_ general-purpose algorithmic and mathematic tools @@ -258,49 +266,58 @@ `pypy/tool/pytest/`_ support code for our `testing methods`_ -`rpython/annotator/`_ `type inferencing code`_ for `RPython`_ programs +`rpython/annotator/`_ `type inferencing code`_ for + `RPython`_ programs `rpython/config/`_ handles the numerous options for RPython -`rpython/flowspace/`_ the FlowObjSpace_ implementing `abstract interpretation`_ +`rpython/flowspace/`_ the FlowObjSpace_ implementing + `abstract interpretation`_ - -`rpython/rlib/`_ a `"standard library"`_ for RPython_ programs +`rpython/rlib/`_ a `"standard library"`_ for RPython_ + programs `rpython/rtyper/`_ the `RPython Typer`_ -`rpython/rtyper/lltypesystem/`_ the `low-level type system`_ for C-like backends +`rpython/rtyper/lltypesystem/`_ the `low-level type system`_ for + C-like backends -`rpython/rtyper/ootypesystem/`_ the `object-oriented type system`_ for OO backends +`rpython/rtyper/ootypesystem/`_ the `object-oriented type system`_ + for OO backends -`rpython/rtyper/memory/`_ the `garbage collector`_ construction framework +`rpython/rtyper/memory/`_ the `garbage collector`_ construction + framework `rpython/translator/`_ translation_ backends and support code -`rpython/translator/backendopt/`_ general optimizations that run before a backend generates code +`rpython/translator/backendopt/`_ general optimizations that run before a + backend generates code -`rpython/translator/c/`_ the `GenC backend`_, producing C code from an +`rpython/translator/c/`_ the `GenC backend`_, producing C code + from an RPython program (generally via the rtyper_) -`rpython/translator/cli/`_ the `CLI backend`_ for `.NET`_ (Microsoft CLR or Mono_) +`rpython/translator/cli/`_ the `CLI backend`_ for `.NET`_ + (Microsoft CLR or Mono_) -`pypy/goal/`_ our `main PyPy-translation scripts`_ live here +`pypy/goal/`_ our `main PyPy-translation scripts`_ + live here `rpython/translator/jvm/`_ the Java backend -`rpython/translator/tool/`_ helper tools for translation, including the Pygame - `graph viewer`_ +`rpython/translator/tool/`_ helper tools for translation -``*/test/`` many directories have a test subdirectory containing test +`dotviewer/`_ `graph viewer`_ + +``*/test/`` many directories have a test subdirectory + containing test modules (see `Testing in PyPy`_) -``_cache/`` holds cache files from internally `translating application - level to interpreterlevel`_ code. -================================ =========================================== +``_cache/`` holds cache files from various purposes +================================= ============================================ .. _`bytecode interpreter`: interpreter.html -.. _`translating application level to interpreterlevel`: geninterp.html .. _`Testing in PyPy`: coding-guide.html#testing-in-pypy .. _`mixed modules`: coding-guide.html#mixed-modules .. _`modules`: coding-guide.html#modules diff --git a/pypy/doc/rlib.rst b/pypy/doc/rlib.rst --- a/pypy/doc/rlib.rst +++ b/pypy/doc/rlib.rst @@ -7,18 +7,18 @@ .. contents:: -This page lists some of the modules in `pypy/rlib`_ together with some hints +This page lists some of the modules in `rpython/rlib`_ together with some hints for what they can be used for. The modules here will make up some general library useful for RPython programs (since most of the standard library modules are not RPython). Most of these modules are somewhat rough still and are likely to change at some point. Usually it is useful to look at the tests in -`pypy/rlib/test`_ to get an impression of how to use a module. +`rpython/rlib/test`_ to get an impression of how to use a module. ``listsort`` ============ -The `pypy/rlib/listsort.py`_ module contains an implementation of the timsort sorting algorithm +The `rpython/rlib/listsort.py`_ module contains an implementation of the timsort sorting algorithm (the sort method of lists is not RPython). To use it, subclass from the ``listsort.TimSort`` class and override the ``lt`` method to change the comparison behaviour. The constructor of ``TimSort`` takes a list as an @@ -30,7 +30,7 @@ ``nonconst`` ============ -The `pypy/rlib/nonconst.py`_ module is useful mostly for tests. The `flow object space`_ and +The `rpython/rlib/nonconst.py`_ module is useful mostly for tests. The `flow object space`_ and the `annotator`_ do quite some constant folding, which is sometimes not desired in a test. To prevent constant folding on a certain value, use the ``NonConst`` class. The constructor of ``NonConst`` takes an arbitrary value. The instance of @@ -44,7 +44,7 @@ ``objectmodel`` =============== -The `pypy/rlib/objectmodel.py`_ module is a mixed bag of various functionality. Some of the +The `rpython/rlib/objectmodel.py`_ module is a mixed bag of various functionality. Some of the more useful ones are: ``ComputedIntSymbolic``: @@ -94,7 +94,7 @@ ``rarithmetic`` =============== -The `pypy/rlib/rarithmetic.py`_ module contains functionality to handle the small differences +The `rpython/rlib/rarithmetic.py`_ module contains functionality to handle the small differences in the behaviour of arithmetic code in regular Python and RPython code. Most of them are already described in the `coding guide`_ @@ -104,7 +104,7 @@ ``rbigint`` =========== -The `pypy/rlib/rbigint.py`_ module contains a full RPython implementation of the Python ``long`` +The `rpython/rlib/rbigint.py`_ module contains a full RPython implementation of the Python ``long`` type (which itself is not supported in RPython). The ``rbigint`` class contains that implementation. To construct ``rbigint`` instances use the static methods ``fromint``, ``frombool``, ``fromfloat`` and ``fromdecimalstr``. To convert back @@ -118,7 +118,7 @@ ``rrandom`` =========== -The `pypy/rlib/rrandom.py`_ module contains an implementation of the mersenne twister random +The `rpython/rlib/rrandom.py`_ module contains an implementation of the mersenne twister random number generator. It contains one class ``Random`` which most importantly has a ``random`` method which returns a pseudo-random floating point number between 0.0 and 1.0. @@ -126,7 +126,7 @@ ``rsocket`` =========== -The `pypy/rlib/rsocket.py`_ module contains an RPython implementation of the functionality of +The `rpython/rlib/rsocket.py`_ module contains an RPython implementation of the functionality of the socket standard library with a slightly different interface. The difficulty with the Python socket API is that addresses are not "well-typed" objects: depending on the address family they are tuples, or strings, and @@ -137,7 +137,7 @@ ``streamio`` ============ -The `pypy/rlib/streamio.py`_ contains an RPython stream I/O implementation (which was started +The `rpython/rlib/streamio.py`_ contains an RPython stream I/O implementation (which was started by Guido van Rossum as `sio.py`_ in the CPython sandbox as a prototype for the upcoming new file implementation in Python 3000). @@ -146,7 +146,7 @@ ``unroll`` ========== -The `pypy/rlib/unroll.py`_ module most importantly contains the function ``unrolling_iterable`` +The `rpython/rlib/unroll.py`_ module most importantly contains the function ``unrolling_iterable`` which wraps an iterator. Looping over the iterator in RPython code will not produce a loop in the resulting flow graph but will unroll the loop instead. @@ -154,7 +154,7 @@ ``parsing`` =========== -The `pypy/rlib/parsing/`_ module is a still in-development module to generate tokenizers and +The `rpython/rlib/parsing/`_ module is a still in-development module to generate tokenizers and parsers in RPython. It is still highly experimental and only really used by the `Prolog interpreter`_ (although in slightly non-standard ways). The easiest way to specify a tokenizer/grammar is to write it down using regular expressions and @@ -204,7 +204,7 @@ anything except a. To parse a regular expression and to get a matcher for it, you can use the -function ``make_runner(s)`` in the ``pypy.rlib.parsing.regexparse`` module. It +function ``make_runner(s)`` in the ``rpython.rlib.parsing.regexparse`` module. It returns a object with a ``recognize(input)`` method that returns True or False depending on whether ``input`` matches the string or not. @@ -213,7 +213,7 @@ EBNF ---- -To describe a tokenizer and a grammar the ``pypy.rlib.parsing.ebnfparse`` +To describe a tokenizer and a grammar the ``rpython.rlib.parsing.ebnfparse`` defines a syntax for doing that. The syntax file contains a sequence or rules. Every rule either describes a @@ -295,7 +295,7 @@ The parsing process builds up a tree consisting of instances of ``Symbol`` and ``Nonterminal``, the former corresponding to tokens, the latter to nonterminal -symbols. Both classes live in the `pypy/rlib/parsing/tree.py`_ module. You can use +symbols. Both classes live in the `rpython/rlib/parsing/tree.py`_ module. You can use the ``view()`` method ``Nonterminal`` instances to get a pygame view of the parse tree. @@ -310,7 +310,7 @@ ++++++++ To write tree visitors for the parse trees that are RPython, there is a special -baseclass ``RPythonVisitor`` in `pypy/rlib/parsing/tree.py`_ to use. If your +baseclass ``RPythonVisitor`` in `rpython/rlib/parsing/tree.py`_ to use. If your class uses this, it will grow a ``dispatch(node)`` method, that calls an appropriate ``visit_`` method, depending on the ``node`` argument. Here the is replaced by the ``symbol`` attribute of the visited node. diff --git a/pypy/doc/rtyper.rst b/pypy/doc/rtyper.rst --- a/pypy/doc/rtyper.rst +++ b/pypy/doc/rtyper.rst @@ -4,7 +4,7 @@ .. contents:: -The RPython Typer lives in the directory `pypy/rpython/`_. +The RPython Typer lives in the directory `rpython/rtyper/`_. Overview @@ -52,7 +52,7 @@ where -- in C notation -- all three variables v1, v2 and v3 are typed ``int``. This is done by attaching an attribute ``concretetype`` to v1, v2 and v3 (which might be instances of Variable or possibly Constant). In our model, -this ``concretetype`` is ``pypy.rpython.lltypesystem.lltype.Signed``. Of +this ``concretetype`` is ``rpython.rtyper.lltypesystem.lltype.Signed``. Of course, the purpose of replacing the operation called ``add`` with ``int_add`` is that code generators no longer have to worry about what kind of addition (or concatenation maybe?) it means. @@ -66,7 +66,7 @@ each operation. In both cases the analysis of an operation depends on the annotations of its input arguments. This is reflected in the usage of the same ``__extend__`` syntax in the source files (compare e.g. -`pypy/annotation/binaryop.py`_ and `pypy/rpython/rint.py`_). +`rpython/annotator/binaryop.py`_ and `rpython/rtyper/rint.py`_). The analogy stops here, though: while it runs, the Annotator is in the middle of computing the annotations, so it might need to reflow and generalize until @@ -104,7 +104,7 @@ implementations for the same high-level operations. This is the reason for turning representations into explicit objects. -The base Repr class is defined in `pypy/rpython/rmodel.py`_. Most of the +The base Repr class is defined in `rpython/rtyper/rmodel.py`_. Most of the ``rpython/r*.py`` files define one or a few subclasses of Repr. The method getrepr() of the RTyper will build and cache a single Repr instance per SomeXxx() instance; moreover, two SomeXxx() instances that are equal get the @@ -131,9 +131,9 @@ The RPython Typer uses a standard low-level model which we believe can correspond rather directly to various target languages such as C. This model is implemented in the first part of -`pypy/rpython/lltypesystem/lltype.py`_. +`rpython/rtyper/lltypesystem/lltype.py`_. -The second part of `pypy/rpython/lltypesystem/lltype.py`_ is a runnable +The second part of `rpython/rtyper/lltypesystem/lltype.py`_ is a runnable implementation of these types, for testing purposes. It allows us to write and test plain Python code using a malloc() function to obtain and manipulate structures and arrays. This is useful for example to implement and test @@ -147,7 +147,7 @@ Here is a quick tour: - >>> from pypy.rpython.lltypesystem.lltype import * + >>> from rpython.rtyper.lltypesystem.lltype import * Here are a few primitive low-level types, and the typeOf() function to figure them out: @@ -191,7 +191,7 @@ types like list in this elementary world. The ``malloc()`` function is a kind of placeholder, which must eventually be provided by the code generator for the target platform; but as we have just seen its Python implementation in -`pypy/rpython/lltypesystem/lltype.py`_ works too, which is primarily useful for +`rpython/rtyper/lltypesystem/lltype.py`_ works too, which is primarily useful for testing, interactive exploring, etc. The argument to ``malloc()`` is the structure type directly, but it returns a @@ -245,7 +245,7 @@ +++++++++++++++ Structure types are built as instances of -``pypy.rpython.lltypesystem.lltype.Struct``:: +``rpython.rtyper.lltypesystem.lltype.Struct``:: MyStructType = Struct('somename', ('field1', Type1), ('field2', Type2)...) MyStructType = GcStruct('somename', ('field1', Type1), ('field2', Type2)...) @@ -277,7 +277,7 @@ +++++++++++ An array type is built as an instance of -``pypy.rpython.lltypesystem.lltype.Array``:: +``rpython.rtyper.lltypesystem.lltype.Array``:: MyIntArray = Array(Signed) MyOtherArray = Array(MyItemType) @@ -316,7 +316,7 @@ with care: the bigger structure of which they are part of could be freed while the Ptr to the substructure is still in use. In general, it is a good idea to avoid passing around pointers to inlined substructures of malloc()ed structures. -(The testing implementation of `pypy/rpython/lltypesystem/lltype.py`_ checks to some +(The testing implementation of `rpython/rtyper/lltypesystem/lltype.py`_ checks to some extent that you are not trying to use a pointer to a structure after its container has been freed, using weak references. But pointers to non-GC structures are not officially meant to be weak references: using them after what @@ -429,7 +429,7 @@ change needed to the Annotator to allow it to perform type inference of our very-low-level snippets of code. -See for example `pypy/rpython/rlist.py`_. +See for example `rpython/rtyper/rlist.py`_. .. _`oo type`: @@ -441,10 +441,10 @@ targeting low level backends such as C, but it is not good enough for targeting higher level backends such as .NET CLI or Java JVM, so a new object oriented model has been introduced. This model is -implemented in the first part of `pypy/rpython/ootypesystem/ootype.py`_. +implemented in the first part of `rpython/rtyper/ootypesystem/ootype.py`_. As for the low-level typesystem, the second part of -`pypy/rpython/ootypesystem/ootype.py`_ is a runnable implementation of +`rpython/rtyper/ootypesystem/ootype.py`_ is a runnable implementation of these types, for testing purposes. @@ -751,7 +751,7 @@ The LLInterpreter is a simple piece of code that is able to interpret flow graphs. This is very useful for testing purposes, especially if you work on the RPython Typer. The most useful interface for it is the ``interpret`` -function in the file `pypy/rpython/test/test_llinterp.py`_. It takes as +function in the file `rpython/rtyper/test/test_llinterp.py`_. It takes as arguments a function and a list of arguments with which the function is supposed to be called. Then it generates the flow graph, annotates it according to the types of the arguments you passed to it and runs the diff --git a/pypy/doc/stackless.rst b/pypy/doc/stackless.rst --- a/pypy/doc/stackless.rst +++ b/pypy/doc/stackless.rst @@ -29,7 +29,7 @@ on 32-bit or a complete megabyte on 64-bit. Moreover, the feature is only available (so far) on x86 and x86-64 CPUs; for other CPUs you need to add a short page of custom assembler to -`pypy/translator/c/src/stacklet/`_. +`rpython/translator/c/src/stacklet/`_. Theory @@ -271,9 +271,9 @@ Continulets are internally implemented using stacklets, which is the generic RPython-level building block for "one-shot continuations". For more information about them please see the documentation in the C source -at `pypy/translator/c/src/stacklet/stacklet.h`_. +at `rpython/translator/c/src/stacklet/stacklet.h`_. -The module ``pypy.rlib.rstacklet`` is a thin wrapper around the above +The module ``rpython.rlib.rstacklet`` is a thin wrapper around the above functions. The key point is that new() and switch() always return a fresh stacklet handle (or an empty one), and switch() additionally consumes one. It makes no sense to have code in which the returned diff --git a/pypy/doc/tool/makeref.py b/pypy/doc/tool/makeref.py --- a/pypy/doc/tool/makeref.py +++ b/pypy/doc/tool/makeref.py @@ -1,10 +1,9 @@ import py -py.path.local(__file__) import pypy -pypydir = py.path.local(pypy.__file__).dirpath() -distdir = pypydir.dirpath() -issue_url = 'http://codespeak.net/issue/pypy-dev/' +pypydir = py.path.local(pypy.__file__).join('..') +distdir = pypydir.dirpath() +issue_url = 'http://bugs.pypy.org/issue/pypy-dev/' bitbucket_url = 'https://bitbucket.org/pypy/pypy/src/default/' import urllib2, posixpath diff --git a/pypy/doc/translation.rst b/pypy/doc/translation.rst --- a/pypy/doc/translation.rst +++ b/pypy/doc/translation.rst @@ -90,7 +90,7 @@ (although these steps are not quite as distinct as you might think from this presentation). -There is an `interactive interface`_ called `pypy/bin/translatorshell.py`_ to the +There is an `interactive interface`_ called `rpython/bin/translatorshell.py`_ to the translation process which allows you to interactively work through these stages. @@ -116,7 +116,7 @@ which are the basic data structures of the translation process. -All these types are defined in `pypy/objspace/flow/model.py`_ (which is a rather +All these types are defined in `rpython/flowspace/model.py`_ (which is a rather important module in the PyPy source base, to reinforce the point). The flow graph of a function is represented by the class ``FunctionGraph``. diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst --- a/pypy/doc/whatsnew-head.rst +++ b/pypy/doc/whatsnew-head.rst @@ -19,7 +19,7 @@ .. branch: numpypy-longdouble Long double support for numpypy .. branch: numpypy-real-as-view -Convert real, imag from ufuncs to views. This involves the beginning of +Convert real, imag from ufuncs to views. This involves the beginning of view() functionality .. branch: signatures @@ -57,4 +57,14 @@ .. branch: cleanup-tests Consolidated the lib_pypy/pypy_test and pypy/module/test_lib_pypy tests into -+one directory for reduced confusion and so they all run nightly. +one directory for reduced confusion and so they all run nightly. + +.. branch: unquote-faster +.. branch: urlparse-unquote-faster + +.. branch: signal-and-thread +Add "__pypy__.thread.signals_enabled", a context manager. Can be used in a +non-main thread to enable the processing of signal handlers in that thread. + +.. branch: coding-guide-update-rlib-refs +.. branch: rlib-doc-rpython-refs diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -1494,10 +1494,11 @@ ) return fd - def warn(self, msg, w_warningcls): - self.appexec([self.wrap(msg), w_warningcls], """(msg, warningcls): + def warn(self, w_msg, w_warningcls, stacklevel=2): + self.appexec([w_msg, w_warningcls, self.wrap(stacklevel)], + """(msg, warningcls, stacklevel): import _warnings - _warnings.warn(msg, warningcls, stacklevel=2) + _warnings.warn(msg, warningcls, stacklevel=stacklevel) """) diff --git a/pypy/interpreter/miscutils.py b/pypy/interpreter/miscutils.py --- a/pypy/interpreter/miscutils.py +++ b/pypy/interpreter/miscutils.py @@ -17,8 +17,14 @@ def setvalue(self, value): self._value = value - def ismainthread(self): + def signals_enabled(self): return True + def enable_signals(self, space): + pass + + def disable_signals(self, space): + pass + def getallvalues(self): return {0: self._value} diff --git a/pypy/interpreter/pycode.py b/pypy/interpreter/pycode.py --- a/pypy/interpreter/pycode.py +++ b/pypy/interpreter/pycode.py @@ -53,16 +53,17 @@ kwargname = None return Signature(argnames, varargname, kwargname) + class PyCode(eval.Code): "CPython-style code objects." _immutable_ = True _immutable_fields_ = ["co_consts_w[*]", "co_names_w[*]", "co_varnames[*]", - "co_freevars[*]", "co_cellvars[*]"] + "co_freevars[*]", "co_cellvars[*]", "_args_as_cellvars[*]"] def __init__(self, space, argcount, nlocals, stacksize, flags, code, consts, names, varnames, filename, name, firstlineno, lnotab, freevars, cellvars, - hidden_applevel=False, magic = default_magic): + hidden_applevel=False, magic=default_magic): """Initialize a new code object from parameters given by the pypy compiler""" self.space = space @@ -89,8 +90,6 @@ def _initialize(self): self._init_flags() - # Precompute what arguments need to be copied into cellvars - self._args_as_cellvars = [] if self.co_cellvars: argcount = self.co_argcount @@ -108,16 +107,22 @@ # produced by CPython are loaded by PyPy. Note that CPython # contains the following bad-looking nested loops at *every* # function call! - argvars = self.co_varnames + + # Precompute what arguments need to be copied into cellvars + args_as_cellvars = [] + argvars = self.co_varnames cellvars = self.co_cellvars for i in range(len(cellvars)): cellname = cellvars[i] for j in range(argcount): if cellname == argvars[j]: # argument j has the same name as the cell var i - while len(self._args_as_cellvars) <= i: - self._args_as_cellvars.append(-1) # pad - self._args_as_cellvars[i] = j + while len(args_as_cellvars) <= i: + args_as_cellvars.append(-1) # pad + args_as_cellvars[i] = j + self._args_as_cellvars = args_as_cellvars[:] + else: + self._args_as_cellvars = [] self._compute_flatcall() diff --git a/pypy/interpreter/pyopcode.py b/pypy/interpreter/pyopcode.py --- a/pypy/interpreter/pyopcode.py +++ b/pypy/interpreter/pyopcode.py @@ -776,17 +776,16 @@ @jit.unroll_safe def cmp_exc_match(self, w_1, w_2): - if self.space.is_true(self.space.isinstance(w_2, self.space.w_tuple)): - for w_t in self.space.fixedview(w_2): - if self.space.is_true(self.space.isinstance(w_t, - self.space.w_str)): - self.space.warn("catching of string exceptions is " - "deprecated", - self.space.w_DeprecationWarning) - elif self.space.is_true(self.space.isinstance(w_2, self.space.w_str)): - self.space.warn("catching of string exceptions is deprecated", - self.space.w_DeprecationWarning) - return self.space.newbool(self.space.exception_match(w_1, w_2)) + space = self.space + if space.is_true(space.isinstance(w_2, space.w_tuple)): + for w_t in space.fixedview(w_2): + if space.is_true(space.isinstance(w_t, space.w_str)): + msg = "catching of string exceptions is deprecated" + space.warn(space.wrap(msg), space.w_DeprecationWarning) + elif space.is_true(space.isinstance(w_2, space.w_str)): + msg = "catching of string exceptions is deprecated" + space.warn(space.wrap(msg), space.w_DeprecationWarning) + return space.newbool(space.exception_match(w_1, w_2)) def COMPARE_OP(self, testnum, next_instr): w_2 = self.popvalue() diff --git a/pypy/interpreter/test2/test_app_main.py b/pypy/interpreter/test2/test_app_main.py --- a/pypy/interpreter/test2/test_app_main.py +++ b/pypy/interpreter/test2/test_app_main.py @@ -208,11 +208,6 @@ These tests require pexpect (UNIX-only). http://pexpect.sourceforge.net/ """ - def setup_class(cls): - # some tests need to be able to import test2, change the cwd - goal_dir = os.path.abspath(os.path.join(os.path.realpath(os.path.dirname(__file__)), '..')) - os.chdir(goal_dir) - def _spawn(self, *args, **kwds): try: import pexpect @@ -456,13 +451,14 @@ child.expect('789') # expect to see it before the timeout hits child.sendline('X') - def test_options_i_m(self): + def test_options_i_m(self, monkeypatch): if sys.platform == "win32": skip("close_fds is not supported on Windows platforms") if not hasattr(runpy, '_run_module_as_main'): skip("requires CPython >= 2.6") p = os.path.join(os.path.realpath(os.path.dirname(__file__)), 'mymodule.py') p = os.path.abspath(p) + monkeypatch.chdir(os.path.dirname(app_main)) child = self.spawn(['-i', '-m', 'test2.mymodule', 'extra']) @@ -562,12 +558,13 @@ child.sendline('Not at all. They could be carried.') child.expect('A five ounce bird could not carry a one pound coconut.') - def test_no_space_before_argument(self): + def test_no_space_before_argument(self, monkeypatch): if not hasattr(runpy, '_run_module_as_main'): skip("requires CPython >= 2.6") child = self.spawn(['-cprint "hel" + "lo"']) child.expect('hello') + monkeypatch.chdir(os.path.dirname(app_main)) child = self.spawn(['-mtest2.mymodule']) child.expect('mymodule running') @@ -667,11 +664,12 @@ '-c "import sys; print sys.warnoptions"') assert "['ignore', 'default', 'once', 'error']" in data - def test_option_m(self): + def test_option_m(self, monkeypatch): if not hasattr(runpy, '_run_module_as_main'): skip("requires CPython >= 2.6") p = os.path.join(os.path.realpath(os.path.dirname(__file__)), 'mymodule.py') p = os.path.abspath(p) + monkeypatch.chdir(os.path.dirname(app_main)) data = self.run('-m test2.mymodule extra') assert 'mymodule running' in data assert 'Name: __main__' in data diff --git a/pypy/module/__builtin__/functional.py b/pypy/module/__builtin__/functional.py --- a/pypy/module/__builtin__/functional.py +++ b/pypy/module/__builtin__/functional.py @@ -133,56 +133,77 @@ v = v.add(step) return space.newlist(res_w) +min_jitdriver = jit.JitDriver(name='min', + greens=['w_type'], reds='auto') +max_jitdriver = jit.JitDriver(name='max', + greens=['w_type'], reds='auto') + +def make_min_max(unroll): + @specialize.arg(2) + def min_max_impl(space, args, implementation_of): + if implementation_of == "max": + compare = space.gt + jitdriver = max_jitdriver + else: + compare = space.lt + jitdriver = min_jitdriver + args_w = args.arguments_w + if len(args_w) > 1: + w_sequence = space.newtuple(args_w) + elif len(args_w): + w_sequence = args_w[0] + else: + msg = "%s() expects at least one argument" % (implementation_of,) + raise OperationError(space.w_TypeError, space.wrap(msg)) + w_key = None + kwds = args.keywords + if kwds: + if kwds[0] == "key" and len(kwds) == 1: + w_key = args.keywords_w[0] + else: + msg = "%s() got unexpected keyword argument" % (implementation_of,) + raise OperationError(space.w_TypeError, space.wrap(msg)) + + w_iter = space.iter(w_sequence) + w_type = space.type(w_iter) + w_max_item = None + w_max_val = None + while True: + if not unroll: + jitdriver.jit_merge_point(w_type=w_type) + try: + w_item = space.next(w_iter) + except OperationError, e: + if not e.match(space, space.w_StopIteration): + raise + break + if w_key is not None: + w_compare_with = space.call_function(w_key, w_item) + else: + w_compare_with = w_item + if w_max_item is None or \ + space.is_true(compare(w_compare_with, w_max_val)): + w_max_item = w_item + w_max_val = w_compare_with + if w_max_item is None: + msg = "arg is an empty sequence" + raise OperationError(space.w_ValueError, space.wrap(msg)) + return w_max_item + if unroll: + min_max_impl = jit.unroll_safe(min_max_impl) + return min_max_impl + +min_max_unroll = make_min_max(True) +min_max_normal = make_min_max(False) @specialize.arg(2) - at jit.look_inside_iff(lambda space, args, implementation_of: - jit.isconstant(len(args.arguments_w)) and - len(args.arguments_w) == 2 -) def min_max(space, args, implementation_of): - if implementation_of == "max": - compare = space.gt + if not jit.we_are_jitted() or (jit.isconstant(len(args.arguments_w)) and + len(args.arguments_w) == 2): + return min_max_unroll(space, args, implementation_of) else: - compare = space.lt - args_w = args.arguments_w - if len(args_w) > 1: - w_sequence = space.newtuple(args_w) - elif len(args_w): - w_sequence = args_w[0] - else: - msg = "%s() expects at least one argument" % (implementation_of,) - raise OperationError(space.w_TypeError, space.wrap(msg)) - w_key = None - kwds = args.keywords - if kwds: - if kwds[0] == "key" and len(kwds) == 1: - w_key = args.keywords_w[0] - else: - msg = "%s() got unexpected keyword argument" % (implementation_of,) - raise OperationError(space.w_TypeError, space.wrap(msg)) - - w_iter = space.iter(w_sequence) - w_max_item = None - w_max_val = None - while True: - try: - w_item = space.next(w_iter) - except OperationError, e: - if not e.match(space, space.w_StopIteration): - raise - break - if w_key is not None: - w_compare_with = space.call_function(w_key, w_item) - else: - w_compare_with = w_item - if w_max_item is None or \ - space.is_true(compare(w_compare_with, w_max_val)): - w_max_item = w_item - w_max_val = w_compare_with - if w_max_item is None: - msg = "arg is an empty sequence" - raise OperationError(space.w_ValueError, space.wrap(msg)) - return w_max_item + return min_max_normal(space, args, implementation_of) +min_max._always_inline = True def max(space, __args__): """max(iterable[, key=func]) -> value diff --git a/pypy/module/__builtin__/interp_classobj.py b/pypy/module/__builtin__/interp_classobj.py --- a/pypy/module/__builtin__/interp_classobj.py +++ b/pypy/module/__builtin__/interp_classobj.py @@ -154,9 +154,9 @@ return elif name == "__del__": if self.lookup(space, name) is None: - msg = ("a __del__ method added to an existing class " - "will not be called") - space.warn(msg, space.w_RuntimeWarning) + msg = ("a __del__ method added to an existing class will " + "not be called") + space.warn(space.wrap(msg), space.w_RuntimeWarning) space.setitem(self.w_dict, w_attr, w_value) def descr_delattr(self, space, w_attr): @@ -395,9 +395,9 @@ cache = space.fromcache(Cache) if (not isinstance(self, cache.cls_with_del) and self.getdictvalue(space, '__del__') is None): - msg = ("a __del__ method added to an instance " - "with no __del__ in the class will not be called") - space.warn(msg, space.w_RuntimeWarning) + msg = ("a __del__ method added to an instance with no " + "__del__ in the class will not be called") + space.warn(space.wrap(msg), space.w_RuntimeWarning) if w_meth is not None: space.call_function(w_meth, w_name, w_value) else: @@ -454,11 +454,9 @@ else: w_as_str = self.descr_str(space) if space.len_w(w_format_spec) > 0: - space.warn( - ("object.__format__ with a non-empty format string is " - "deprecated"), - space.w_PendingDeprecationWarning - ) + msg = ("object.__format__ with a non-empty format string is " + "deprecated") + space.warn(space.wrap(msg), space.w_PendingDeprecationWarning) return space.format(w_as_str, w_format_spec) def descr_len(self, space): diff --git a/pypy/module/__pypy__/__init__.py b/pypy/module/__pypy__/__init__.py --- a/pypy/module/__pypy__/__init__.py +++ b/pypy/module/__pypy__/__init__.py @@ -26,6 +26,16 @@ interpleveldefs[name] = "space.wrap(interp_time.%s)" % name +class ThreadModule(MixedModule): + appleveldefs = { + 'signals_enabled': 'app_signal.signals_enabled', + } + interpleveldefs = { + '_signals_enter': 'interp_signal.signals_enter', + '_signals_exit': 'interp_signal.signals_exit', + } + + class Module(MixedModule): appleveldefs = { } @@ -54,6 +64,7 @@ submodules = { "builders": BuildersModule, "time": TimeModule, + "thread": ThreadModule, } def setup_after_space_initialization(self): diff --git a/pypy/module/__pypy__/app_signal.py b/pypy/module/__pypy__/app_signal.py new file mode 100644 --- /dev/null +++ b/pypy/module/__pypy__/app_signal.py @@ -0,0 +1,14 @@ +import __pypy__.thread + +class SignalsEnabled(object): + '''A context manager to use in non-main threads: +enables receiving signals in a "with" statement. More precisely, if a +signal is received by the process, then the signal handler might be +called either in the main thread (as usual) or within another thread +that is within a "with signals_enabled:". This other thread should be +ready to handle unexpected exceptions that the signal handler might +raise --- notably KeyboardInterrupt.''' + __enter__ = __pypy__.thread._signals_enter + __exit__ = __pypy__.thread._signals_exit + +signals_enabled = SignalsEnabled() diff --git a/pypy/module/__pypy__/interp_signal.py b/pypy/module/__pypy__/interp_signal.py new file mode 100644 --- /dev/null +++ b/pypy/module/__pypy__/interp_signal.py @@ -0,0 +1,6 @@ + +def signals_enter(space): + space.threadlocals.enable_signals(space) + +def signals_exit(space, w_ignored1=None, w_ignored2=None, w_ignored3=None): + space.threadlocals.disable_signals(space) diff --git a/pypy/module/__pypy__/test/test_signal.py b/pypy/module/__pypy__/test/test_signal.py new file mode 100644 --- /dev/null +++ b/pypy/module/__pypy__/test/test_signal.py @@ -0,0 +1,122 @@ +import sys + +from pypy.module.thread.test.support import GenericTestThread + + +class AppTestMinimal: + spaceconfig = dict(usemodules=['__pypy__']) + + def test_signal(self): + from __pypy__ import thread + with thread.signals_enabled: + pass + # assert did not crash + + +class AppTestThreadSignal(GenericTestThread): + spaceconfig = dict(usemodules=['__pypy__', 'thread', 'signal', 'time']) + + def test_exit_twice(self): + import __pypy__, thread + __pypy__.thread._signals_exit() + try: + raises(thread.error, __pypy__.thread._signals_exit) + finally: + __pypy__.thread._signals_enter() + + def test_enable_signals(self): + import __pypy__, thread, signal, time + + def subthread(): + try: + with __pypy__.thread.signals_enabled: + thread.interrupt_main() + for i in range(10): + print 'x' + time.sleep(0.1) + except BaseException, e: + interrupted.append(e) + finally: + done.append(None) + + # This is normally called by app_main.py + signal.signal(signal.SIGINT, signal.default_int_handler) + + for i in range(10): + __pypy__.thread._signals_exit() + try: + done = [] + interrupted = [] + thread.start_new_thread(subthread, ()) + for i in range(10): + if len(done): break + print '.' + time.sleep(0.1) + assert len(done) == 1 + assert len(interrupted) == 1 + assert 'KeyboardInterrupt' in interrupted[0].__class__.__name__ + finally: + __pypy__.thread._signals_enter() + + def test_thread_fork_signals(self): + import __pypy__ + import os, thread, signal + + if not hasattr(os, 'fork'): + skip("No fork on this platform") + + def fork(): + with __pypy__.thread.signals_enabled: + return os.fork() + + def threadfunction(): + pid = fork() + if pid == 0: + print 'in child' + # signal() only works from the 'main' thread + signal.signal(signal.SIGUSR1, signal.SIG_IGN) + os._exit(42) + else: + self.timeout_killer(pid, 5) + exitcode = os.waitpid(pid, 0)[1] + feedback.append(exitcode) + + feedback = [] + thread.start_new_thread(threadfunction, ()) + self.waitfor(lambda: feedback) + # if 0, an (unraisable) exception was raised from the forked thread. + # if 9, process was killed by timer. + # if 42<<8, os._exit(42) was correctly reached. + assert feedback == [42<<8] + + +class AppTestThreadSignalLock: + spaceconfig = dict(usemodules=['__pypy__', 'thread', 'signal']) + + def setup_class(cls): + if (not cls.runappdirect or + '__pypy__' not in sys.builtin_module_names): + import py + py.test.skip("this is only a test for -A runs on top of pypy") + + def test_enable_signals(self): + import __pypy__, thread, signal, time + + interrupted = [] + lock = thread.allocate_lock() + lock.acquire() + + def subthread(): + try: + time.sleep(0.25) + with __pypy__.thread.signals_enabled: + thread.interrupt_main() + except BaseException, e: + interrupted.append(e) + finally: + lock.release() + + thread.start_new_thread(subthread, ()) + lock.acquire() + assert len(interrupted) == 1 + assert 'KeyboardInterrupt' in interrupted[0].__class__.__name__ diff --git a/pypy/module/_cffi_backend/__init__.py b/pypy/module/_cffi_backend/__init__.py --- a/pypy/module/_cffi_backend/__init__.py +++ b/pypy/module/_cffi_backend/__init__.py @@ -7,7 +7,7 @@ appleveldefs = { } interpleveldefs = { - '__version__': 'space.wrap("0.4")', + '__version__': 'space.wrap("0.6")', 'load_library': 'libraryobj.load_library', diff --git a/pypy/module/_cffi_backend/cdataobj.py b/pypy/module/_cffi_backend/cdataobj.py --- a/pypy/module/_cffi_backend/cdataobj.py +++ b/pypy/module/_cffi_backend/cdataobj.py @@ -119,9 +119,12 @@ def getitem(self, w_index): space = self.space - i = space.getindex_w(w_index, space.w_IndexError) - ctype = self.ctype._check_subscript_index(self, i) - w_o = self._do_getitem(ctype, i) + if space.isinstance_w(w_index, space.w_slice): + w_o = self._do_getslice(w_index) + else: + i = space.getindex_w(w_index, space.w_IndexError) + ctype = self.ctype._check_subscript_index(self, i) + w_o = self._do_getitem(ctype, i) keepalive_until_here(self) return w_o @@ -132,14 +135,100 @@ def setitem(self, w_index, w_value): space = self.space - i = space.getindex_w(w_index, space.w_IndexError) - ctype = self.ctype._check_subscript_index(self, i) - ctitem = ctype.ctitem - ctitem.convert_from_object( - rffi.ptradd(self._cdata, i * ctitem.size), - w_value) + if space.isinstance_w(w_index, space.w_slice): + self._do_setslice(w_index, w_value) + else: + i = space.getindex_w(w_index, space.w_IndexError) + ctype = self.ctype._check_subscript_index(self, i) + ctitem = ctype.ctitem + ctitem.convert_from_object( + rffi.ptradd(self._cdata, i * ctitem.size), + w_value) keepalive_until_here(self) + def _do_getslicearg(self, w_slice): + from pypy.module._cffi_backend.ctypeptr import W_CTypePointer + from pypy.objspace.std.sliceobject import W_SliceObject + assert isinstance(w_slice, W_SliceObject) + space = self.space + # + if space.is_w(w_slice.w_start, space.w_None): + raise OperationError(space.w_IndexError, + space.wrap("slice start must be specified")) + start = space.int_w(w_slice.w_start) + # + if space.is_w(w_slice.w_stop, space.w_None): + raise OperationError(space.w_IndexError, + space.wrap("slice stop must be specified")) + stop = space.int_w(w_slice.w_stop) + # + if not space.is_w(w_slice.w_step, space.w_None): + raise OperationError(space.w_IndexError, + space.wrap("slice with step not supported")) + # + if start > stop: + raise OperationError(space.w_IndexError, + space.wrap("slice start > stop")) + # + ctype = self.ctype._check_slice_index(self, start, stop) + assert isinstance(ctype, W_CTypePointer) + # + return ctype, start, stop - start + + def _do_getslice(self, w_slice): + ctptr, start, length = self._do_getslicearg(w_slice) + # + space = self.space + ctarray = ctptr.cache_array_type + if ctarray is None: + from pypy.module._cffi_backend import newtype + ctarray = newtype.new_array_type(space, ctptr, space.w_None) + ctptr.cache_array_type = ctarray + # + p = rffi.ptradd(self._cdata, start * ctarray.ctitem.size) + return W_CDataSliced(space, p, ctarray, length) + + def _do_setslice(self, w_slice, w_value): + ctptr, start, length = self._do_getslicearg(w_slice) + ctitem = ctptr.ctitem + ctitemsize = ctitem.size + cdata = rffi.ptradd(self._cdata, start * ctitemsize) + # + if isinstance(w_value, W_CData): + from pypy.module._cffi_backend import ctypearray + ctv = w_value.ctype + if (isinstance(ctv, ctypearray.W_CTypeArray) and + ctv.ctitem is ctitem and + w_value.get_array_length() == length): + # fast path: copying from exactly the correct type + s = w_value._cdata + for i in range(ctitemsize * length): + cdata[i] = s[i] + keepalive_until_here(w_value) + return + # + space = self.space + w_iter = space.iter(w_value) + for i in range(length): + try: + w_item = space.next(w_iter) + except OperationError, e: + if not e.match(space, space.w_StopIteration): + raise + raise operationerrfmt(space.w_ValueError, + "need %d values to unpack, got %d", + length, i) + ctitem.convert_from_object(cdata, w_item) + cdata = rffi.ptradd(cdata, ctitemsize) + try: + space.next(w_iter) + except OperationError, e: + if not e.match(space, space.w_StopIteration): + raise + else: + raise operationerrfmt(space.w_ValueError, + "got more than %d values to unpack", length) + def _add_or_sub(self, w_other, sign): space = self.space i = sign * space.getindex_w(w_other, space.w_OverflowError) @@ -281,6 +370,22 @@ return self.structobj +class W_CDataSliced(W_CData): + """Subclass with an explicit length, for slices.""" + _attrs_ = ['length'] + _immutable_fields_ = ['length'] + + def __init__(self, space, cdata, ctype, length): + W_CData.__init__(self, space, cdata, ctype) + self.length = length + + def _repr_extra(self): + return "sliced length %d" % (self.length,) + + def get_array_length(self): + return self.length + + W_CData.typedef = TypeDef( 'CData', __module__ = '_cffi_backend', diff --git a/pypy/module/_cffi_backend/ctypearray.py b/pypy/module/_cffi_backend/ctypearray.py --- a/pypy/module/_cffi_backend/ctypearray.py +++ b/pypy/module/_cffi_backend/ctypearray.py @@ -76,6 +76,17 @@ self.name, i, w_cdata.get_array_length()) return self + def _check_slice_index(self, w_cdata, start, stop): + space = self.space + if start < 0: + raise OperationError(space.w_IndexError, + space.wrap("negative index not supported")) + if stop > w_cdata.get_array_length(): + raise operationerrfmt(space.w_IndexError, + "index too large (expected %d <= %d)", + stop, w_cdata.get_array_length()) + return self.ctptr + def convert_from_object(self, cdata, w_ob): self.convert_array_from_object(cdata, w_ob) diff --git a/pypy/module/_cffi_backend/ctypeenum.py b/pypy/module/_cffi_backend/ctypeenum.py --- a/pypy/module/_cffi_backend/ctypeenum.py +++ b/pypy/module/_cffi_backend/ctypeenum.py @@ -6,23 +6,19 @@ from rpython.rtyper.lltypesystem import rffi from rpython.rlib.rarithmetic import intmask, r_ulonglong from rpython.rlib.objectmodel import keepalive_until_here +from rpython.rlib.objectmodel import specialize from pypy.module._cffi_backend.ctypeprim import W_CTypePrimitiveSigned +from pypy.module._cffi_backend.ctypeprim import W_CTypePrimitiveUnsigned from pypy.module._cffi_backend import misc -class W_CTypeEnum(W_CTypePrimitiveSigned): - _attrs_ = ['enumerators2values', 'enumvalues2erators'] - _immutable_fields_ = ['enumerators2values', 'enumvalues2erators'] - kind = "enum" +class _Mixin_Enum(object): + _mixin_ = True - def __init__(self, space, name, enumerators, enumvalues): - from pypy.module._cffi_backend.newtype import alignment + def __init__(self, space, name, size, align, enumerators, enumvalues): name = "enum " + name - size = rffi.sizeof(rffi.INT) - align = alignment(rffi.INT) - W_CTypePrimitiveSigned.__init__(self, space, size, - name, len(name), align) + self._super.__init__(self, space, size, name, len(name), align) self.enumerators2values = {} # str -> int self.enumvalues2erators = {} # int -> str for i in range(len(enumerators)-1, -1, -1): @@ -44,55 +40,46 @@ space.setitem(w_dct, space.wrap(enumerator), space.wrap(enumvalue)) return w_dct - return W_CTypePrimitiveSigned._fget(self, attrchar) + return self._super._fget(self, attrchar) + + def extra_repr(self, cdata): + value = self._get_value(cdata) + try: + s = self.enumvalues2erators[value] + except KeyError: + return str(value) + else: + return '%s: %s' % (value, s) def string(self, cdataobj, maxlen): - w_result = self.convert_to_object(cdataobj._cdata) + value = self._get_value(cdataobj._cdata) keepalive_until_here(cdataobj) - return w_result + try: + s = self.enumvalues2erators[value] + except KeyError: + s = str(value) + return self.space.wrap(s) - def convert_to_object(self, cdata): - value = misc.read_raw_long_data(cdata, self.size) - try: - enumerator = self.enumvalues2erators[value] - except KeyError: - enumerator = '#%d' % (value,) - return self.space.wrap(enumerator) - def convert_from_object(self, cdata, w_ob): - space = self.space - try: - return W_CTypePrimitiveSigned.convert_from_object(self, cdata, - w_ob) - except OperationError, e: - if not e.match(space, space.w_TypeError): - raise - if space.isinstance_w(w_ob, space.w_basestring): - value = self.convert_enum_string_to_int(space.str_w(w_ob)) - value = r_ulonglong(value) - misc.write_raw_integer_data(cdata, value, self.size) - else: - raise self._convert_error("str or int", w_ob) +class W_CTypeEnumSigned(_Mixin_Enum, W_CTypePrimitiveSigned): + _attrs_ = ['enumerators2values', 'enumvalues2erators'] + _immutable_fields_ = ['enumerators2values', 'enumvalues2erators'] + kind = "enum" + _super = W_CTypePrimitiveSigned - def cast_str(self, w_ob): - space = self.space - return self.convert_enum_string_to_int(space.str_w(w_ob)) + def _get_value(self, cdata): + # returns a signed long + assert self.value_fits_long + return misc.read_raw_long_data(cdata, self.size) - def cast_unicode(self, w_ob): - return self.cast_str(w_ob) - def convert_enum_string_to_int(self, s): - space = self.space - if s.startswith('#'): - try: - return int(s[1:]) - except ValueError: - raise OperationError(space.w_ValueError, - space.wrap("invalid literal after '#'")) - else: - try: - return self.enumerators2values[s] - except KeyError: - raise operationerrfmt(space.w_ValueError, - "'%s' is not an enumerator for %s", - s, self.name) +class W_CTypeEnumUnsigned(_Mixin_Enum, W_CTypePrimitiveUnsigned): + _attrs_ = ['enumerators2values', 'enumvalues2erators'] + _immutable_fields_ = ['enumerators2values', 'enumvalues2erators'] + kind = "enum" + _super = W_CTypePrimitiveUnsigned + + def _get_value(self, cdata): + # returns an unsigned long + assert self.value_fits_ulong + return misc.read_raw_ulong_data(cdata, self.size) diff --git a/pypy/module/_cffi_backend/ctypeobj.py b/pypy/module/_cffi_backend/ctypeobj.py --- a/pypy/module/_cffi_backend/ctypeobj.py +++ b/pypy/module/_cffi_backend/ctypeobj.py @@ -93,12 +93,18 @@ "not %s", self.name, expected, space.type(w_got).getname(space)) - def _check_subscript_index(self, w_cdata, i): + def _cannot_index(self): space = self.space raise operationerrfmt(space.w_TypeError, "cdata of type '%s' cannot be indexed", self.name) + def _check_subscript_index(self, w_cdata, i): + raise self._cannot_index() + + def _check_slice_index(self, w_cdata, start, stop): + raise self._cannot_index() + def string(self, cdataobj, maxlen): space = self.space raise operationerrfmt(space.w_TypeError, diff --git a/pypy/module/_cffi_backend/ctypeprim.py b/pypy/module/_cffi_backend/ctypeprim.py --- a/pypy/module/_cffi_backend/ctypeprim.py +++ b/pypy/module/_cffi_backend/ctypeprim.py @@ -171,9 +171,7 @@ self.vrangemax = (r_uint(1) << sh) - 1 def int(self, cdata): - # enums: really call convert_to_object() just below, - # and not the one overridden in W_CTypeEnum. - return W_CTypePrimitiveSigned.convert_to_object(self, cdata) + return self.convert_to_object(cdata) def convert_to_object(self, cdata): if self.value_fits_long: diff --git a/pypy/module/_cffi_backend/ctypeptr.py b/pypy/module/_cffi_backend/ctypeptr.py --- a/pypy/module/_cffi_backend/ctypeptr.py +++ b/pypy/module/_cffi_backend/ctypeptr.py @@ -174,9 +174,10 @@ class W_CTypePointer(W_CTypePtrBase): - _attrs_ = ['is_file'] - _immutable_fields_ = ['is_file'] + _attrs_ = ['is_file', 'cache_array_type'] + _immutable_fields_ = ['is_file', 'cache_array_type?'] kind = "pointer" + cache_array_type = None def __init__(self, space, ctitem): from pypy.module._cffi_backend import ctypearray @@ -185,7 +186,8 @@ extra = "(*)" # obscure case: see test_array_add else: extra = " *" - self.is_file = (ctitem.name == "struct _IO_FILE") + self.is_file = (ctitem.name == "struct _IO_FILE" or + ctitem.name == "struct $FILE") W_CTypePtrBase.__init__(self, space, size, extra, 2, ctitem) def newp(self, w_init): @@ -224,6 +226,9 @@ self.name) return self + def _check_slice_index(self, w_cdata, start, stop): + return self + def add(self, cdata, i): space = self.space ctitem = self.ctitem diff --git a/pypy/module/_cffi_backend/newtype.py b/pypy/module/_cffi_backend/newtype.py --- a/pypy/module/_cffi_backend/newtype.py +++ b/pypy/module/_cffi_backend/newtype.py @@ -1,7 +1,8 @@ from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.gateway import unwrap_spec from rpython.rtyper.lltypesystem import lltype, rffi -from rpython.rlib.rarithmetic import ovfcheck +from rpython.rlib.rarithmetic import ovfcheck, r_uint, intmask +from rpython.rlib.rarithmetic import most_neg_value_of, most_pos_value_of from rpython.rlib.objectmodel import specialize from pypy.module._cffi_backend import ctypeobj, ctypeprim, ctypeptr, ctypearray @@ -263,26 +264,38 @@ # ____________________________________________________________ - at unwrap_spec(name=str) -def new_enum_type(space, name, w_enumerators, w_enumvalues): + at unwrap_spec(name=str, basectype=ctypeobj.W_CType) +def new_enum_type(space, name, w_enumerators, w_enumvalues, basectype): enumerators_w = space.fixedview(w_enumerators) enumvalues_w = space.fixedview(w_enumvalues) if len(enumerators_w) != len(enumvalues_w): raise OperationError(space.w_ValueError, space.wrap("tuple args must have the same size")) enumerators = [space.str_w(w) for w in enumerators_w] - enumvalues = [] + # + if (not isinstance(basectype, ctypeprim.W_CTypePrimitiveSigned) and + not isinstance(basectype, ctypeprim.W_CTypePrimitiveUnsigned)): + raise OperationError(space.w_TypeError, + space.wrap("expected a primitive signed or unsigned base type")) + # + lvalue = lltype.malloc(rffi.CCHARP.TO, basectype.size, flavor='raw') try: for w in enumvalues_w: - enumvalues.append(space.c_int_w(w)) - except OperationError, e: - if not e.match(space, space.w_OverflowError): - raise - i = len(enumvalues) - raise operationerrfmt(space.w_OverflowError, - "enum '%s' declaration for '%s' does not fit an int", - name, enumerators[i]) - ctype = ctypeenum.W_CTypeEnum(space, name, enumerators, enumvalues) + # detects out-of-range or badly typed values + basectype.convert_from_object(lvalue, w) + finally: + lltype.free(lvalue, flavor='raw') + # + size = basectype.size + align = basectype.align + if isinstance(basectype, ctypeprim.W_CTypePrimitiveSigned): + enumvalues = [space.int_w(w) for w in enumvalues_w] + ctype = ctypeenum.W_CTypeEnumSigned(space, name, size, align, + enumerators, enumvalues) + else: + enumvalues = [space.uint_w(w) for w in enumvalues_w] + ctype = ctypeenum.W_CTypeEnumUnsigned(space, name, size, align, + enumerators, enumvalues) return ctype # ____________________________________________________________ @@ -302,8 +315,13 @@ # if ((fresult.size < 0 and not isinstance(fresult, ctypevoid.W_CTypeVoid)) or isinstance(fresult, ctypearray.W_CTypeArray)): - raise operationerrfmt(space.w_TypeError, - "invalid result type: '%s'", fresult.name) + if (isinstance(fresult, ctypestruct.W_CTypeStructOrUnion) and + fresult.size < 0): + raise operationerrfmt(space.w_TypeError, + "result type '%s' is opaque", fresult.name) + else: + raise operationerrfmt(space.w_TypeError, + "invalid result type: '%s'", fresult.name) # fct = ctypefunc.W_CTypeFunc(space, fargs, fresult, ellipsis) return fct diff --git a/pypy/module/_cffi_backend/test/_backend_test_c.py b/pypy/module/_cffi_backend/test/_backend_test_c.py --- a/pypy/module/_cffi_backend/test/_backend_test_c.py +++ b/pypy/module/_cffi_backend/test/_backend_test_c.py @@ -1264,80 +1264,130 @@ py.test.raises(TypeError, callback, BFunc, cb, -42) def test_enum_type(): - BEnum = new_enum_type("foo", (), ()) + BUInt = new_primitive_type("unsigned int") + BEnum = new_enum_type("foo", (), (), BUInt) assert repr(BEnum) == "" assert BEnum.kind == "enum" assert BEnum.cname == "enum foo" assert BEnum.elements == {} # - BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, -20)) + BInt = new_primitive_type("int") + BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, -20), BInt) assert BEnum.kind == "enum" assert BEnum.elements == {-20: 'ab', 0: 'def', 1: 'c'} # 'elements' is not the real dict, but merely a copy BEnum.elements[2] = '??' assert BEnum.elements == {-20: 'ab', 0: 'def', 1: 'c'} # - BEnum = new_enum_type("bar", ('ab', 'cd'), (5, 5)) + BEnum = new_enum_type("bar", ('ab', 'cd'), (5, 5), BUInt) assert BEnum.elements == {5: 'ab'} assert BEnum.relements == {'ab': 5, 'cd': 5} def test_cast_to_enum(): - BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, -20)) + BInt = new_primitive_type("int") + BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, -20), BInt) + assert sizeof(BEnum) == sizeof(BInt) e = cast(BEnum, 0) - assert repr(e) == "" + assert repr(e) == "" + assert repr(cast(BEnum, -42)) == "" + assert repr(cast(BEnum, -20)) == "" assert string(e) == 'def' assert string(cast(BEnum, -20)) == 'ab' - assert string(cast(BEnum, 'c')) == 'c' - assert int(cast(BEnum, 'c')) == 1 - assert int(cast(BEnum, 'def')) == 0 + assert int(cast(BEnum, 1)) == 1 + assert int(cast(BEnum, 0)) == 0 assert int(cast(BEnum, -242 + 2**128)) == -242 - assert string(cast(BEnum, -242 + 2**128)) == '#-242' - assert string(cast(BEnum, '#-20')) == 'ab' - assert repr(cast(BEnum, '#-20')) == "" - assert repr(cast(BEnum, '#-21')) == "" + assert string(cast(BEnum, -242 + 2**128)) == '-242' + # + BUInt = new_primitive_type("unsigned int") + BEnum = new_enum_type("bar", ('def', 'c', 'ab'), (0, 1, 20), BUInt) + e = cast(BEnum, -1) + assert repr(e) == "" # unsigned int From noreply at buildbot.pypy.org Fri Feb 22 16:57:53 2013 From: noreply at buildbot.pypy.org (amauryfa) Date: Fri, 22 Feb 2013 16:57:53 +0100 (CET) Subject: [pypy-commit] pypy missing-os-functions: Correctly detects the presence of fchmod and fchown. Message-ID: <20130222155753.746091C4763@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: missing-os-functions Changeset: r61614:5e890c5dac82 Date: 2013-02-22 16:57 +0100 http://bitbucket.org/pypy/pypy/changeset/5e890c5dac82/ Log: Correctly detects the presence of fchmod and fchown. Tests run and pass even with an old pypy which does (yet) not provide the functions. os.fchmod and os.fchown are not used anymore, they could probably be removed from ll_os.py diff --git a/pypy/module/posix/__init__.py b/pypy/module/posix/__init__.py --- a/pypy/module/posix/__init__.py +++ b/pypy/module/posix/__init__.py @@ -1,6 +1,7 @@ # Package initialisation from pypy.interpreter.mixedmodule import MixedModule from rpython.rtyper.module.ll_os import RegisterOs +from rpython.rlib import rposix import os, sys exec 'import %s as posix' % os.name @@ -95,7 +96,7 @@ } for name in ''' - wait wait3 wait4 chown lchown fchown fchmod ftruncate + wait wait3 wait4 chown lchown ftruncate fsync fdatasync fchdir putenv unsetenv killpg getpid link symlink readlink fork openpty forkpty waitpid execv execve uname sysconf fpathconf @@ -108,6 +109,12 @@ if hasattr(posix, name): interpleveldefs[name] = 'interp_posix.%s' % (name,) + for name in '''fchmod fchown + '''.split(): + symbol = 'HAS_' + name.upper() + if getattr(rposix, symbol): + interpleveldefs[name] = 'interp_posix.%s' % (name,) + for constant in ''' F_OK R_OK W_OK X_OK NGROUPS_MAX TMP_MAX WNOHANG WCONTINUED WUNTRACED diff --git a/pypy/module/posix/interp_posix.py b/pypy/module/posix/interp_posix.py --- a/pypy/module/posix/interp_posix.py +++ b/pypy/module/posix/interp_posix.py @@ -20,6 +20,10 @@ c_int = "c_int" +def oserror_from_errno(space): + errno = rposix.get_errno() + return wrap_oserror(space, OSError(errno, "OSError")) + # CPython 2.7 semantics are too messy to follow exactly, # e.g. setuid(-2) works on 32-bit but not on 64-bit. As a result, # we decided to just accept any 'int', i.e. any C signed long, and @@ -586,10 +590,9 @@ """Change the access permissions of the file given by file descriptor fd.""" fd = space.c_filedescriptor_w(w_fd) - try: - os.fchmod(fd, mode) - except OSError, e: - raise wrap_oserror(space, e) + res = rposix.c_fchmod(fd, mode) + if res == -1: + raise oserror_from_errno(space) def rename(space, w_old, w_new): "Rename a file or directory." @@ -1153,10 +1156,9 @@ fd = space.c_filedescriptor_w(w_fd) check_uid_range(space, uid) check_uid_range(space, gid) - try: - os.fchown(fd, uid, gid) - except OSError, e: - raise wrap_oserror(space, e) + res = rposix.c_fchown(fd, uid, gid) + if res == -1: + raise oserror_from_errno(space) def getloadavg(space): try: diff --git a/pypy/module/posix/test/test_posix2.py b/pypy/module/posix/test/test_posix2.py --- a/pypy/module/posix/test/test_posix2.py +++ b/pypy/module/posix/test/test_posix2.py @@ -6,6 +6,7 @@ from rpython.tool.udir import udir from pypy.tool.pytest.objspace import gettestobjspace from pypy.conftest import pypydir +from rpython.rlib import rposix from rpython.rtyper.module.ll_os import RegisterOs from rpython.translator.c.test.test_extfunc import need_sparse_files import os @@ -833,7 +834,7 @@ os.symlink('foobar', self.path) os.lchown(self.path, os.getuid(), os.getgid()) - if hasattr(os, 'fchown'): + if rposix.HAS_FCHOWN: def test_fchown(self): os = self.posix f = open(self.path, "w") @@ -856,7 +857,7 @@ os.chmod(self.path, 0200) assert (os.stat(self.path).st_mode & 0777) == 0200 - if hasattr(os, 'fchmod'): + if rposix.HAS_FCHMOD: def test_fchmod(self): os = self.posix f = open(self.path, "w") diff --git a/rpython/rlib/rposix.py b/rpython/rlib/rposix.py --- a/rpython/rlib/rposix.py +++ b/rpython/rlib/rposix.py @@ -1,6 +1,7 @@ import os from rpython.rtyper.lltypesystem.rffi import CConstant, CExternVariable, INT from rpython.rtyper.lltypesystem import ll2ctypes, rffi +from rpython.rtyper.tool import rffi_platform from rpython.translator.tool.cbuild import ExternalCompilationInfo from rpython.rlib.rarithmetic import intmask from rpython.rlib.objectmodel import specialize @@ -83,14 +84,23 @@ else: separate_module_sources = [] export_symbols = [] - includes=['errno.h','stdio.h'] -errno_eci = ExternalCompilationInfo( + includes=['errno.h', 'stdio.h', 'unistd.h', 'sys/stat.h'] +rposix_eci = ExternalCompilationInfo( includes=includes, separate_module_sources=separate_module_sources, export_symbols=export_symbols, ) -_get_errno, _set_errno = CExternVariable(INT, 'errno', errno_eci, +class CConfig: + _compilation_info_ = rposix_eci + + HAS_FCHMOD = rffi_platform.Has("fchmod") + HAS_FCHOWN = rffi_platform.Has("fchown") + +globals().update(rffi_platform.configure(CConfig)) + + +_get_errno, _set_errno = CExternVariable(INT, 'errno', rposix_eci, CConstantErrno, sandboxsafe=True, _nowrapper=True, c_type='int') # the default wrapper for set_errno is not suitable for use in critical places @@ -105,7 +115,7 @@ if os.name == 'nt': is_valid_fd = rffi.llexternal( "_PyVerify_fd", [rffi.INT], rffi.INT, - compilation_info=errno_eci, + compilation_info=rposix_eci, ) @jit.dont_look_inside def validate_fd(fd): @@ -127,6 +137,15 @@ except OSError: pass +# Expose posix functions +def external(name, args, result): + return rffi.llexternal(name, args, result, + compilation_info=CConfig._compilation_info_) + +c_fchmod = external('fchmod', [rffi.INT, rffi.MODE_T], rffi.INT) +c_fchown = external('fchown', [rffi.INT, rffi.INT, rffi.INT], rffi.INT) + + #___________________________________________________________________ # Wrappers around posix functions, that accept either strings, or # instances with a "as_bytes()" method. From noreply at buildbot.pypy.org Fri Feb 22 17:17:26 2013 From: noreply at buildbot.pypy.org (amauryfa) Date: Fri, 22 Feb 2013 17:17:26 +0100 (CET) Subject: [pypy-commit] pypy default: Add the new readline implementation to BufferedReader as well Message-ID: <20130222161726.6B1491C4763@cobra.cs.uni-duesseldorf.de> Author: Amaury Forgeot d'Arc Branch: Changeset: r61615:2f19cd9ecb9c Date: 2013-02-22 17:16 +0100 http://bitbucket.org/pypy/pypy/changeset/2f19cd9ecb9c/ Log: Add the new readline implementation to BufferedReader as well diff --git a/pypy/module/_io/interp_bufferedio.py b/pypy/module/_io/interp_bufferedio.py --- a/pypy/module/_io/interp_bufferedio.py +++ b/pypy/module/_io/interp_bufferedio.py @@ -861,6 +861,7 @@ peek = interp2app(W_BufferedReader.peek_w), read1 = interp2app(W_BufferedReader.read1_w), raw = interp_attrproperty_w("w_raw", cls=W_BufferedReader), + readline = interp2app(W_BufferedReader.readline_w), # from the mixin class __repr__ = interp2app(W_BufferedReader.repr_w), From noreply at buildbot.pypy.org Fri Feb 22 17:23:31 2013 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 22 Feb 2013 17:23:31 +0100 (CET) Subject: [pypy-commit] pypy default: some misses Message-ID: <20130222162331.824361C47A0@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r61616:47700c7e20d3 Date: 2013-02-22 18:21 +0200 http://bitbucket.org/pypy/pypy/changeset/47700c7e20d3/ Log: some misses diff --git a/rpython/rtyper/lltypesystem/rdict.py b/rpython/rtyper/lltypesystem/rdict.py --- a/rpython/rtyper/lltypesystem/rdict.py +++ b/rpython/rtyper/lltypesystem/rdict.py @@ -424,22 +424,22 @@ dummy = ENTRIES.dummy_obj.ll_dummy_value return entries.everused(i) and entries[i].value != dummy - at objectmodel.enforceargs(None, int) + at objectmodel.enforceargs(None, SomeInteger(nonneg=True)) def ll_mark_deleted_in_value(entries, i): ENTRIES = lltype.typeOf(entries).TO dummy = ENTRIES.dummy_obj.ll_dummy_value entries[i].value = dummy - at objectmodel.enforceargs(None, int) + at objectmodel.enforceargs(None, SomeInteger(nonneg=True)) def ll_hash_from_cache(entries, i): return entries[i].f_hash - at objectmodel.enforceargs(None, int) + at objectmodel.enforceargs(None, SomeInteger(nonneg=True)) def ll_hash_recomputed(entries, i): ENTRIES = lltype.typeOf(entries).TO return ENTRIES.fasthashfn(entries[i].key) - at objectmodel.enforceargs(None, int) + at objectmodel.enforceargs(None, SomeInteger(nonneg=True)) def ll_get_value(d, i): return d.entries[i].value From noreply at buildbot.pypy.org Fri Feb 22 17:23:32 2013 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 22 Feb 2013 17:23:32 +0100 (CET) Subject: [pypy-commit] pypy default: merge Message-ID: <20130222162332.A7BC01C47A0@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r61617:306c896faeb1 Date: 2013-02-22 18:22 +0200 http://bitbucket.org/pypy/pypy/changeset/306c896faeb1/ Log: merge diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst --- a/pypy/doc/whatsnew-head.rst +++ b/pypy/doc/whatsnew-head.rst @@ -68,3 +68,6 @@ .. branch: coding-guide-update-rlib-refs .. branch: rlib-doc-rpython-refs + +.. branch: enumerate-rstr +Support enumerate() over rstr types. diff --git a/pypy/module/_io/interp_bufferedio.py b/pypy/module/_io/interp_bufferedio.py --- a/pypy/module/_io/interp_bufferedio.py +++ b/pypy/module/_io/interp_bufferedio.py @@ -861,6 +861,7 @@ peek = interp2app(W_BufferedReader.peek_w), read1 = interp2app(W_BufferedReader.read1_w), raw = interp_attrproperty_w("w_raw", cls=W_BufferedReader), + readline = interp2app(W_BufferedReader.readline_w), # from the mixin class __repr__ = interp2app(W_BufferedReader.repr_w), diff --git a/rpython/rtyper/ootypesystem/rlist.py b/rpython/rtyper/ootypesystem/rlist.py --- a/rpython/rtyper/ootypesystem/rlist.py +++ b/rpython/rtyper/ootypesystem/rlist.py @@ -241,6 +241,7 @@ def __init__(self, r_list): self.r_list = r_list + self.external_item_repr = r_list.external_item_repr self.lowleveltype = ootype.Record( {"iterable": r_list.lowleveltype, "index": ootype.Signed}) self.ll_listiter = ll_listiter diff --git a/rpython/rtyper/ootypesystem/rstr.py b/rpython/rtyper/ootypesystem/rstr.py --- a/rpython/rtyper/ootypesystem/rstr.py +++ b/rpython/rtyper/ootypesystem/rstr.py @@ -445,6 +445,7 @@ def __init__(self): self.ll_striter = ll_unicodeiter self.ll_strnext = ll_strnext + self.ll_getnextindex = ll_getnextindex def ll_striter(string): iter = ootype.new(string_repr.string_iterator_repr.lowleveltype) From noreply at buildbot.pypy.org Fri Feb 22 17:48:59 2013 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 22 Feb 2013 17:48:59 +0100 (CET) Subject: [pypy-commit] pypy stm-thread-2: Extend the last_abort_info with bits and pieces from the tx_descriptor Message-ID: <20130222164859.B28B21C4763@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stm-thread-2 Changeset: r61618:e8d90c408313 Date: 2013-02-22 16:33 +0100 http://bitbucket.org/pypy/pypy/changeset/e8d90c408313/ Log: Extend the last_abort_info with bits and pieces from the tx_descriptor as well as a timing of the real time lost in the aborted transaction. diff --git a/rpython/translator/stm/src_stm/et.c b/rpython/translator/stm/src_stm/et.c --- a/rpython/translator/stm/src_stm/et.c +++ b/rpython/translator/stm/src_stm/et.c @@ -10,6 +10,7 @@ #include #include #include +#include #ifndef RPY_STM /* for tests, a few custom defines */ @@ -48,6 +49,7 @@ unsigned long reads_size_limit_nonatomic; int active; /* 0 = inactive, 1 = regular, 2 = inevitable */ int readonly_updates; + struct timespec start_real_time; unsigned int num_commits; unsigned int num_aborts[ABORT_REASONS]; unsigned int num_spinloops[SPINLOOP_REASONS]; @@ -370,13 +372,16 @@ spinloop(); } -size_t _stm_decode_abort_info(struct tx_descriptor *d, char *output); +size_t _stm_decode_abort_info(struct tx_descriptor *d, long long elapsed_time, + int abort_reason, char *output); static void AbortTransaction(int num) { struct tx_descriptor *d = thread_descriptor; unsigned long limit; size_t size; + struct timespec now; + long long elapsed_time; assert(d->active); assert(!is_inevitable(d)); assert(num < ABORT_REASONS); @@ -384,13 +389,28 @@ CancelLocks(d); + /* compute the elapsed time */ + if (d->start_real_time.tv_nsec != -1 && + clock_gettime(CLOCK_MONOTONIC, &now) >= 0) { + elapsed_time = now.tv_sec - d->start_real_time.tv_sec; + elapsed_time *= 1000000000; + elapsed_time += now.tv_nsec - d->start_real_time.tv_nsec; + } + else { + elapsed_time = -1; + } + /* decode the 'abortinfo' and produce a human-readable summary in the string 'lastabortinfo' */ - size = _stm_decode_abort_info(d, NULL); + size = _stm_decode_abort_info(d, elapsed_time, num, NULL); free(d->lastabortinfo); d->lastabortinfo = malloc(size); if (d->lastabortinfo != NULL) - _stm_decode_abort_info(d, d->lastabortinfo); + if (_stm_decode_abort_info(d, elapsed_time, num, d->lastabortinfo) != size) + { + fprintf(stderr, "during stm abort: object mutated unexpectedly\n"); + abort(); + } /* run the undo log in reverse order, cancelling the values set by stm_ThreadLocalRef_LLSet(). */ @@ -447,6 +467,9 @@ static void init_transaction(struct tx_descriptor *d) { + if (clock_gettime(CLOCK_MONOTONIC, &d->start_real_time) < 0) { + d->start_real_time.tv_nsec = -1; + } assert(d->active == 0); assert(d->list_of_read_objects.size == 0); assert(d->gcroots.size == 0); diff --git a/rpython/translator/stm/src_stm/rpyintf.c b/rpython/translator/stm/src_stm/rpyintf.c --- a/rpython/translator/stm/src_stm/rpyintf.c +++ b/rpython/translator/stm/src_stm/rpyintf.c @@ -214,13 +214,16 @@ gcptrlist_reduce_size(&d->abortinfo, newsize < 0 ? 0 : newsize); } -size_t _stm_decode_abort_info(struct tx_descriptor *d, char *output) +size_t _stm_decode_abort_info(struct tx_descriptor *d, long long elapsed_time, + int abort_reason, char *output) { /* re-encodes the abort info as a single string. For convenience (no escaping needed, no limit on integer sizes, etc.) we follow the bittorrent format. */ size_t totalsize = 0; long i; + char buffer[32]; + size_t res_size; #define WRITE(c) { totalsize++; if (output) *output++=(c); } #define WRITE_BUF(p, sz) { totalsize += (sz); \ if (output) { \ @@ -228,12 +231,28 @@ } \ } WRITE('l'); + WRITE('l'); + res_size = sprintf(buffer, "i%llde", (long long)elapsed_time); + WRITE_BUF(buffer, res_size); + res_size = sprintf(buffer, "i%de", (int)abort_reason); + WRITE_BUF(buffer, res_size); + res_size = sprintf(buffer, "i%lde", (long)(d->my_lock - LOCKED)); + WRITE_BUF(buffer, res_size); + res_size = sprintf(buffer, "i%lde", (long)d->atomic); + WRITE_BUF(buffer, res_size); + res_size = sprintf(buffer, "i%de", (int)d->active); + WRITE_BUF(buffer, res_size); + res_size = sprintf(buffer, "i%lue", (unsigned long)d->count_reads); + WRITE_BUF(buffer, res_size); + res_size = sprintf(buffer, "i%lue", + (unsigned long)d->reads_size_limit_nonatomic); + WRITE_BUF(buffer, res_size); + WRITE('e'); for (i=0; iabortinfo.size; i+=2) { char *object = (char *)stm_RepeatReadBarrier(d->abortinfo.items[i+0]); long *fieldoffsets = (long*)d->abortinfo.items[i+1]; long kind, offset; - char buffer[32]; - size_t res_size, rps_size; + size_t rps_size; RPyString *rps; while (1) { diff --git a/rpython/translator/stm/test/test_ztranslated.py b/rpython/translator/stm/test/test_ztranslated.py --- a/rpython/translator/stm/test/test_ztranslated.py +++ b/rpython/translator/stm/test/test_ztranslated.py @@ -143,7 +143,7 @@ globf.xy = 100 + retry_counter def check(_, retry_counter): - rstm.abort_info_push(globf, ('xy', '[', 'yx', ']')) + rstm.abort_info_push(globf, ('[', 'xy', ']', 'yx')) setxy(globf, retry_counter) if retry_counter < 3: rstm.abort_and_retry() @@ -163,4 +163,4 @@ return 0 t, cbuilder = self.compile(main) data = cbuilder.cmdexec('a b') - assert 'li102el10:hi there 3ee\n' in data + assert 'li102ee10:hi there 3e\n' in data From noreply at buildbot.pypy.org Fri Feb 22 17:49:01 2013 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 22 Feb 2013 17:49:01 +0100 (CET) Subject: [pypy-commit] pypy stm-thread-2: Keep the abort info corresponding to the longest aborted transaction, Message-ID: <20130222164901.7D2F91C4763@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stm-thread-2 Changeset: r61619:181f9b1e8484 Date: 2013-02-22 17:03 +0100 http://bitbucket.org/pypy/pypy/changeset/181f9b1e8484/ Log: Keep the abort info corresponding to the longest aborted transaction, in case there are several aborts before charp_inspect_abort_info() is called. diff --git a/rpython/translator/stm/src_stm/et.c b/rpython/translator/stm/src_stm/et.c --- a/rpython/translator/stm/src_stm/et.c +++ b/rpython/translator/stm/src_stm/et.c @@ -58,7 +58,8 @@ struct G2L global_to_local; struct GcPtrList undolog; struct GcPtrList abortinfo; - char *lastabortinfo; + char *longest_abort_info; + long long longest_abort_info_time; struct FXCache recent_reads_cache; }; @@ -395,22 +396,34 @@ elapsed_time = now.tv_sec - d->start_real_time.tv_sec; elapsed_time *= 1000000000; elapsed_time += now.tv_nsec - d->start_real_time.tv_nsec; + if (elapsed_time < 1) + elapsed_time = 1; } else { - elapsed_time = -1; + elapsed_time = 1; } - /* decode the 'abortinfo' and produce a human-readable summary in - the string 'lastabortinfo' */ - size = _stm_decode_abort_info(d, elapsed_time, num, NULL); - free(d->lastabortinfo); - d->lastabortinfo = malloc(size); - if (d->lastabortinfo != NULL) - if (_stm_decode_abort_info(d, elapsed_time, num, d->lastabortinfo) != size) - { - fprintf(stderr, "during stm abort: object mutated unexpectedly\n"); - abort(); - } + if (elapsed_time >= d->longest_abort_info_time) + { + /* decode the 'abortinfo' and produce a human-readable summary in + the string 'longest_abort_info' */ + size = _stm_decode_abort_info(d, elapsed_time, num, NULL); + free(d->longest_abort_info); + d->longest_abort_info = malloc(size); + if (d->longest_abort_info == NULL) + d->longest_abort_info_time = 0; /* out of memory! */ + else + { + if (_stm_decode_abort_info(d, elapsed_time, + num, d->longest_abort_info) != size) + { + fprintf(stderr, + "during stm abort: object mutated unexpectedly\n"); + abort(); + } + d->longest_abort_info_time = elapsed_time; + } + } /* run the undo log in reverse order, cancelling the values set by stm_ThreadLocalRef_LLSet(). */ diff --git a/rpython/translator/stm/src_stm/rpyintf.c b/rpython/translator/stm/src_stm/rpyintf.c --- a/rpython/translator/stm/src_stm/rpyintf.c +++ b/rpython/translator/stm/src_stm/rpyintf.c @@ -307,7 +307,10 @@ char *stm_inspect_abort_info(void) { struct tx_descriptor *d = thread_descriptor; - return d->lastabortinfo; + if (d->longest_abort_info_time <= 0) + return NULL; + d->longest_abort_info_time = 0; + return d->longest_abort_info; } long stm_extraref_llcount(void) diff --git a/rpython/translator/stm/test/test_ztranslated.py b/rpython/translator/stm/test/test_ztranslated.py --- a/rpython/translator/stm/test/test_ztranslated.py +++ b/rpython/translator/stm/test/test_ztranslated.py @@ -143,12 +143,14 @@ globf.xy = 100 + retry_counter def check(_, retry_counter): + last = rstm.charp_inspect_abort_info() rstm.abort_info_push(globf, ('[', 'xy', ']', 'yx')) setxy(globf, retry_counter) if retry_counter < 3: rstm.abort_and_retry() # - print rffi.charp2str(rstm.charp_inspect_abort_info()) + print rffi.charp2str(last) + print int(bool(rstm.charp_inspect_abort_info())) # rstm.abort_info_pop(2) return 0 @@ -158,9 +160,10 @@ def main(argv): Parent().xy = 0 + globf.xy = -2 globf.yx = 'hi there %d' % len(argv) perform_transaction(lltype.nullptr(PS.TO)) return 0 t, cbuilder = self.compile(main) data = cbuilder.cmdexec('a b') - assert 'li102ee10:hi there 3e\n' in data + assert 'li102ee10:hi there 3e\n0\n' in data From noreply at buildbot.pypy.org Fri Feb 22 17:49:02 2013 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 22 Feb 2013 17:49:02 +0100 (CET) Subject: [pypy-commit] pypy stm-thread-2: Tweaks Message-ID: <20130222164902.B37311C4763@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stm-thread-2 Changeset: r61620:166e672afd5d Date: 2013-02-22 17:05 +0100 http://bitbucket.org/pypy/pypy/changeset/166e672afd5d/ Log: Tweaks diff --git a/lib_pypy/transaction.py b/lib_pypy/transaction.py --- a/lib_pypy/transaction.py +++ b/lib_pypy/transaction.py @@ -40,6 +40,13 @@ pass signals_enabled = _SignalsEnabled() +try: + from __pypy__.thread import last_abort_info +except ImportError: + # Not a STM-enabled PyPy. + def last_abort_info(): + return None + def set_num_threads(num): """Set the number of threads to use.""" @@ -215,6 +222,9 @@ with atomic: if got_exception: return # return early if already an exc. to reraise + info = last_abort_info() + if info is not None: + print info f(*args, **kwds) except: got_exception[:] = sys.exc_info() diff --git a/pypy/module/__pypy__/__init__.py b/pypy/module/__pypy__/__init__.py --- a/pypy/module/__pypy__/__init__.py +++ b/pypy/module/__pypy__/__init__.py @@ -40,6 +40,7 @@ '_exclusive_atomic_enter': 'interp_atomic.exclusive_atomic_enter', '_atomic_exit': 'interp_atomic.atomic_exit', 'last_abort_info': 'interp_atomic.last_abort_info', + 'discard_last_abort_info': 'interp_atomic.discard_last_abort_info', } diff --git a/pypy/module/__pypy__/interp_atomic.py b/pypy/module/__pypy__/interp_atomic.py --- a/pypy/module/__pypy__/interp_atomic.py +++ b/pypy/module/__pypy__/interp_atomic.py @@ -51,6 +51,10 @@ assert p[0] == '\0' return w_obj +def discard_last_abort_info(space): + from rpython.rlib.rstm import charp_inspect_abort_info + charp_inspect_abort_info() + def bdecode(space, p): return decoder[p[0]](space, p) From noreply at buildbot.pypy.org Fri Feb 22 17:49:03 2013 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 22 Feb 2013 17:49:03 +0100 (CET) Subject: [pypy-commit] pypy stm-thread-2: Write the traceback-on-abort logic. The lnotab handling needs fixing. Message-ID: <20130222164903.E85261C4763@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stm-thread-2 Changeset: r61621:8d8fb39ff944 Date: 2013-02-22 17:49 +0100 http://bitbucket.org/pypy/pypy/changeset/8d8fb39ff944/ Log: Write the traceback-on-abort logic. The lnotab handling needs fixing. diff --git a/lib_pypy/transaction.py b/lib_pypy/transaction.py --- a/lib_pypy/transaction.py +++ b/lib_pypy/transaction.py @@ -12,7 +12,7 @@ """ from __future__ import with_statement -import sys, thread, collections +import sys, thread, collections, cStringIO, linecache try: from __pypy__.thread import atomic @@ -218,14 +218,16 @@ # this is a staticmethod in order to make sure that we don't # accidentally use 'self' in the atomic block. try: - with signals_enabled: - with atomic: - if got_exception: - return # return early if already an exc. to reraise - info = last_abort_info() - if info is not None: - print info - f(*args, **kwds) + while True: + with signals_enabled: + with atomic: + info = last_abort_info() + if info is None: + if not got_exception: + f(*args, **kwds) + # else return early if already an exc to reraise + return + report_abort_info(info) except: got_exception[:] = sys.exc_info() @@ -241,3 +243,31 @@ self.pending = collections.deque() _thread_local = _ThreadLocal() + + +def report_abort_info(info): + header = info[0] + f = cStringIO.StringIO() + if len(info) > 1: + print >> f, 'Traceback from detected conflict:' + for tb in info[1:]: + filename = tb[0] + coname = tb[1] + lineno = tb[2] + lnotab = tb[3] + bytecodenum = tb[-1] + for i in range(0, len(lnotab), 2): + if bytecodenum < 0: + break + bytecodenum -= ord(lnotab[i]) + lineno += ord(lnotab[i+1]) + print >> f, ' File "%s", line %d, in %s' % ( + filename, lineno, coname) + line = linecache.getline(filename,lineno) + if line: print >> f, ' ' + line.strip() + print >> f, 'Transaction aborted, %g seconds lost (th%d' % ( + header[0] * 1E-9, header[2]), + print >> f, 'abrt%d %s%s%d/%d)' % ( + header[1], 'atom '*header[3], 'inev '*(header[4]>1), + header[5], header[6]) + sys.stderr.write(f.getvalue()) From noreply at buildbot.pypy.org Fri Feb 22 17:59:25 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Fri, 22 Feb 2013 17:59:25 +0100 (CET) Subject: [pypy-commit] pypy default: Rollback 47700c7e20d3 Message-ID: <20130222165925.BAE3C1C4763@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r61622:931450125526 Date: 2013-02-22 08:56 -0800 http://bitbucket.org/pypy/pypy/changeset/931450125526/ Log: Rollback 47700c7e20d3 diff --git a/rpython/rtyper/lltypesystem/rdict.py b/rpython/rtyper/lltypesystem/rdict.py --- a/rpython/rtyper/lltypesystem/rdict.py +++ b/rpython/rtyper/lltypesystem/rdict.py @@ -424,22 +424,22 @@ dummy = ENTRIES.dummy_obj.ll_dummy_value return entries.everused(i) and entries[i].value != dummy - at objectmodel.enforceargs(None, SomeInteger(nonneg=True)) + at objectmodel.enforceargs(None, int) def ll_mark_deleted_in_value(entries, i): ENTRIES = lltype.typeOf(entries).TO dummy = ENTRIES.dummy_obj.ll_dummy_value entries[i].value = dummy - at objectmodel.enforceargs(None, SomeInteger(nonneg=True)) + at objectmodel.enforceargs(None, int) def ll_hash_from_cache(entries, i): return entries[i].f_hash - at objectmodel.enforceargs(None, SomeInteger(nonneg=True)) + at objectmodel.enforceargs(None, int) def ll_hash_recomputed(entries, i): ENTRIES = lltype.typeOf(entries).TO return ENTRIES.fasthashfn(entries[i].key) - at objectmodel.enforceargs(None, SomeInteger(nonneg=True)) + at objectmodel.enforceargs(None, int) def ll_get_value(d, i): return d.entries[i].value From noreply at buildbot.pypy.org Fri Feb 22 18:00:48 2013 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 22 Feb 2013 18:00:48 +0100 (CET) Subject: [pypy-commit] pypy default: an attempt to fix the translation Message-ID: <20130222170048.350DB1C47A1@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r61623:82aec8b61b1d Date: 2013-02-22 18:58 +0200 http://bitbucket.org/pypy/pypy/changeset/82aec8b61b1d/ Log: an attempt to fix the translation diff --git a/rpython/rtyper/lltypesystem/rdict.py b/rpython/rtyper/lltypesystem/rdict.py --- a/rpython/rtyper/lltypesystem/rdict.py +++ b/rpython/rtyper/lltypesystem/rdict.py @@ -439,7 +439,6 @@ ENTRIES = lltype.typeOf(entries).TO return ENTRIES.fasthashfn(entries[i].key) - at objectmodel.enforceargs(None, SomeInteger(nonneg=True)) def ll_get_value(d, i): return d.entries[i].value From noreply at buildbot.pypy.org Fri Feb 22 18:00:49 2013 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 22 Feb 2013 18:00:49 +0100 (CET) Subject: [pypy-commit] pypy default: merge and attempt to fix it Message-ID: <20130222170049.7F7CA1C47A1@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r61624:5c003abc38f8 Date: 2013-02-22 18:59 +0200 http://bitbucket.org/pypy/pypy/changeset/5c003abc38f8/ Log: merge and attempt to fix it From noreply at buildbot.pypy.org Fri Feb 22 18:40:33 2013 From: noreply at buildbot.pypy.org (fijal) Date: Fri, 22 Feb 2013 18:40:33 +0100 (CET) Subject: [pypy-commit] pypy default: give up and use r_uint here Message-ID: <20130222174033.3331B1C47A0@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r61625:4c2efe56c1db Date: 2013-02-22 19:39 +0200 http://bitbucket.org/pypy/pypy/changeset/4c2efe56c1db/ Log: give up and use r_uint here diff --git a/rpython/rtyper/lltypesystem/rdict.py b/rpython/rtyper/lltypesystem/rdict.py --- a/rpython/rtyper/lltypesystem/rdict.py +++ b/rpython/rtyper/lltypesystem/rdict.py @@ -11,8 +11,8 @@ from rpython.annotator.model import SomeInteger -HIGHEST_BIT = intmask(1 << (LONG_BIT - 1)) -MASK = intmask(HIGHEST_BIT - 1) +HIGHEST_BIT = r_uint(intmask(1 << (LONG_BIT - 1))) +MASK = r_uint(intmask(HIGHEST_BIT - 1)) # ____________________________________________________________ # @@ -386,55 +386,44 @@ # be direct_call'ed from rtyped flow graphs, which means that they will # get flowed and annotated, mostly with SomePtr. - at objectmodel.enforceargs(None, SomeInteger(nonneg=True)) def ll_everused_from_flag(entries, i): return entries[i].f_everused - at objectmodel.enforceargs(None, SomeInteger(nonneg=True)) def ll_everused_from_key(entries, i): return bool(entries[i].key) - at objectmodel.enforceargs(None, SomeInteger(nonneg=True)) def ll_everused_from_value(entries, i): return bool(entries[i].value) - at objectmodel.enforceargs(None, SomeInteger(nonneg=True)) def ll_valid_from_flag(entries, i): return entries[i].f_valid - at objectmodel.enforceargs(None, SomeInteger(nonneg=True)) def ll_mark_deleted_in_flag(entries, i): entries[i].f_valid = False - at objectmodel.enforceargs(None, SomeInteger(nonneg=True)) def ll_valid_from_key(entries, i): ENTRIES = lltype.typeOf(entries).TO dummy = ENTRIES.dummy_obj.ll_dummy_value return entries.everused(i) and entries[i].key != dummy - at objectmodel.enforceargs(None, SomeInteger(nonneg=True)) def ll_mark_deleted_in_key(entries, i): ENTRIES = lltype.typeOf(entries).TO dummy = ENTRIES.dummy_obj.ll_dummy_value entries[i].key = dummy - at objectmodel.enforceargs(None, SomeInteger(nonneg=True)) def ll_valid_from_value(entries, i): ENTRIES = lltype.typeOf(entries).TO dummy = ENTRIES.dummy_obj.ll_dummy_value return entries.everused(i) and entries[i].value != dummy - at objectmodel.enforceargs(None, SomeInteger(nonneg=True)) def ll_mark_deleted_in_value(entries, i): ENTRIES = lltype.typeOf(entries).TO dummy = ENTRIES.dummy_obj.ll_dummy_value entries[i].value = dummy - at objectmodel.enforceargs(None, SomeInteger(nonneg=True)) def ll_hash_from_cache(entries, i): return entries[i].f_hash - at objectmodel.enforceargs(None, SomeInteger(nonneg=True)) def ll_hash_recomputed(entries, i): ENTRIES = lltype.typeOf(entries).TO return ENTRIES.fasthashfn(entries[i].key) @@ -525,7 +514,6 @@ @jit.look_inside_iff(lambda d, i: jit.isvirtual(d) and jit.isconstant(i)) def _ll_dict_del(d, i): - assert i >= 0 d.entries.mark_deleted(i) d.num_items -= 1 # clear the key and the value if they are GC pointers @@ -585,8 +573,7 @@ ENTRIES = lltype.typeOf(entries).TO direct_compare = not hasattr(ENTRIES, 'no_direct_compare') mask = len(entries) - 1 - i = hash & mask - assert i >= 0 + i = r_uint(hash & mask) # do the first try before any looping if entries.valid(i): checkingkey = entries[i].key @@ -605,7 +592,7 @@ return i # found the entry freeslot = -1 elif entries.everused(i): - freeslot = i + freeslot = intmask(i) else: return i | HIGHEST_BIT # pristine entry -- lookup failed @@ -614,16 +601,14 @@ perturb = r_uint(hash) while 1: # compute the next index using unsigned arithmetic - i = r_uint(i) i = (i << 2) + i + perturb + 1 - i = intmask(i) & mask - assert i >= 0 + i = i & mask # keep 'i' as a signed number here, to consistently pass signed # arguments to the small helper methods. if not entries.everused(i): if freeslot == -1: - freeslot = i - return freeslot | HIGHEST_BIT + freeslot = intmask(i) + return r_uint(freeslot) | HIGHEST_BIT elif entries.valid(i): checkingkey = entries[i].key if direct_compare and checkingkey == key: @@ -641,7 +626,7 @@ if found: return i # found the entry elif freeslot == -1: - freeslot = i + freeslot = intmask(i) perturb >>= PERTURB_SHIFT def ll_dict_lookup_clean(d, hash): @@ -650,14 +635,11 @@ # It only finds the next free slot for the given hash. entries = d.entries mask = len(entries) - 1 - i = hash & mask - assert i >= 0 + i = r_uint(hash & mask) perturb = r_uint(hash) while entries.everused(i): - i = r_uint(i) i = (i << 2) + i + perturb + 1 - i = intmask(i) & mask - assert i >= 0 + i = i & mask perturb >>= PERTURB_SHIFT return i @@ -926,14 +908,14 @@ r = lltype.malloc(ELEM.TO) r.item0 = recast(ELEM.TO.item0, entry.key) r.item1 = recast(ELEM.TO.item1, entry.value) - _ll_dict_del(dic, i) + _ll_dict_del(dic, r_uint(i)) return r def ll_pop(dic, key): i = ll_dict_lookup(dic, key, dic.keyhash(key)) if not i & HIGHEST_BIT: - value = ll_get_value(dic, i) - _ll_dict_del(dic, i) + value = ll_get_value(dic, r_uint(i)) + _ll_dict_del(dic, r_uint(i)) return value else: raise KeyError From noreply at buildbot.pypy.org Fri Feb 22 21:27:59 2013 From: noreply at buildbot.pypy.org (arigo) Date: Fri, 22 Feb 2013 21:27:59 +0100 (CET) Subject: [pypy-commit] pypy stm-thread-2: Fix the logic. Message-ID: <20130222202759.C20801C47A1@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stm-thread-2 Changeset: r61626:0c01fc86d431 Date: 2013-02-22 21:28 +0100 http://bitbucket.org/pypy/pypy/changeset/0c01fc86d431/ Log: Fix the logic. diff --git a/lib_pypy/transaction.py b/lib_pypy/transaction.py --- a/lib_pypy/transaction.py +++ b/lib_pypy/transaction.py @@ -257,15 +257,15 @@ lnotab = tb[3] bytecodenum = tb[-1] for i in range(0, len(lnotab), 2): + bytecodenum -= ord(lnotab[i]) if bytecodenum < 0: break - bytecodenum -= ord(lnotab[i]) lineno += ord(lnotab[i+1]) print >> f, ' File "%s", line %d, in %s' % ( filename, lineno, coname) line = linecache.getline(filename,lineno) if line: print >> f, ' ' + line.strip() - print >> f, 'Transaction aborted, %g seconds lost (th%d' % ( + print >> f, 'Transaction aborted, %.6f seconds lost (th%d' % ( header[0] * 1E-9, header[2]), print >> f, 'abrt%d %s%s%d/%d)' % ( header[1], 'atom '*header[3], 'inev '*(header[4]>1), From noreply at buildbot.pypy.org Sat Feb 23 00:30:04 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Sat, 23 Feb 2013 00:30:04 +0100 (CET) Subject: [pypy-commit] pypy py3k: cpython issue8202: include -m in the initial argv (more like -c does) Message-ID: <20130222233004.559461C4763@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61627:680b7dc2e00a Date: 2013-02-22 15:21 -0800 http://bitbucket.org/pypy/pypy/changeset/680b7dc2e00a/ Log: cpython issue8202: include -m in the initial argv (more like -c does) diff --git a/pypy/interpreter/app_main.py b/pypy/interpreter/app_main.py --- a/pypy/interpreter/app_main.py +++ b/pypy/interpreter/app_main.py @@ -322,8 +322,8 @@ return ['-c'] + list(iterargv) def m_option(options, runmodule, iterargv): - options["run_module"] = True - return [runmodule] + list(iterargv) + options["run_module"] = runmodule + return ['-m'] + list(iterargv) def W_option(options, warnoption, iterargv): options["warnoptions"].append(warnoption) @@ -534,12 +534,12 @@ def run_it(): exec_(run_command, mainmodule.__dict__) success = run_toplevel(run_it) - elif run_module: + elif run_module != 0: # handle the "-m" command # '' on sys.path is required also here sys.path.insert(0, '') import runpy - success = run_toplevel(runpy._run_module_as_main, sys.argv[0]) + success = run_toplevel(runpy._run_module_as_main, run_module) elif run_stdin: # handle the case where no command/filename/module is specified # on the command-line. diff --git a/pypy/interpreter/test2/test_app_main.py b/pypy/interpreter/test2/test_app_main.py --- a/pypy/interpreter/test2/test_app_main.py +++ b/pypy/interpreter/test2/test_app_main.py @@ -151,14 +151,14 @@ no_site=1) self.check(['-Scpass'], {}, sys_argv=['-c'], run_command='pass', no_site=1) self.check(['-c', '', ''], {}, sys_argv=['-c', ''], run_command='') - self.check(['-mfoo', 'bar', 'baz'], {}, sys_argv=['foo', 'bar', 'baz'], - run_module=True) - self.check(['-m', 'foo', 'bar', 'baz'], {}, sys_argv=['foo', 'bar', 'baz'], - run_module=True) - self.check(['-Smfoo', 'bar', 'baz'], {}, sys_argv=['foo', 'bar', 'baz'], - run_module=True, no_site=1) - self.check(['-Sm', 'foo', 'bar', 'baz'], {}, sys_argv=['foo', 'bar', 'baz'], - run_module=True, no_site=1) + self.check(['-mfoo', 'bar', 'baz'], {}, sys_argv=['-m', 'bar', 'baz'], + run_module='foo') + self.check(['-m', 'foo', 'bar', 'baz'], {}, sys_argv=['-m', 'bar', 'baz'], + run_module='foo') + self.check(['-Smfoo', 'bar', 'baz'], {}, sys_argv=['-m', 'bar', 'baz'], + run_module='foo', no_site=1) + self.check(['-Sm', 'foo', 'bar', 'baz'], {}, sys_argv=['-m', 'bar', 'baz'], + run_module='foo', no_site=1) self.check(['-', 'foo', 'bar'], {}, sys_argv=['-', 'foo', 'bar'], run_stdin=True) self.check(['foo', 'bar'], {}, sys_argv=['foo', 'bar']) @@ -694,6 +694,17 @@ assert ('File: ' + p) in data assert ('Argv: ' + repr([p, 'extra'])) in data + def test_option_m_package(self, monkeypatch): + if not hasattr(runpy, '_run_module_as_main'): + skip("requires CPython >= 2.6") + p = os.path.join(os.path.realpath(os.path.dirname(__file__)), + 'mypackage', '__main__.py') + p = os.path.abspath(p) + monkeypatch.chdir(os.path.dirname(app_main)) + data = self.run('-m test2.mypackage extra') + assert "__init__ argv: ['-m', 'extra']" in data + assert "__main__ argv: [%r, 'extra']" % p in data + def test_pythoninspect_doesnt_override_isatty(self): os.environ['PYTHONINSPECT_'] = '1' try: From noreply at buildbot.pypy.org Sat Feb 23 00:30:05 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Sat, 23 Feb 2013 00:30:05 +0100 (CET) Subject: [pypy-commit] pypy py3k: add sys._xoptions Message-ID: <20130222233005.956361C4763@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61628:5fae4dd9855f Date: 2013-02-22 15:28 -0800 http://bitbucket.org/pypy/pypy/changeset/5fae4dd9855f/ Log: add sys._xoptions diff --git a/pypy/interpreter/app_main.py b/pypy/interpreter/app_main.py --- a/pypy/interpreter/app_main.py +++ b/pypy/interpreter/app_main.py @@ -11,6 +11,7 @@ -h, --help show this help message and exit -m mod library module to be run as a script (terminates option list) -W arg warning control (arg is action:message:category:module:lineno) + -X opt set implementation-specific option -E ignore environment variables (such as PYTHONPATH) -R ignored (see http://bugs.python.org/issue14621) --version print the PyPy version @@ -325,6 +326,9 @@ options["run_module"] = runmodule return ['-m'] + list(iterargv) +def X_option(options, xoption, iterargv): + options["_xoptions"].append(xoption) + def W_option(options, warnoption, iterargv): options["warnoptions"].append(warnoption) @@ -353,6 +357,7 @@ '--help': (print_help, None), 'm': (m_option, Ellipsis), 'W': (W_option, Ellipsis), + 'X': (X_option, Ellipsis), 'V': (print_version, None), '--version': (print_version, None), '--info': (print_info, None), @@ -382,6 +387,7 @@ import os options = default_options.copy() options['warnoptions'] = [] + options['_xoptions'] = [] iterargv = iter(argv) argv = None @@ -445,6 +451,9 @@ sys.flags = type(sys.flags)(flags) sys.dont_write_bytecode = bool(sys.flags.dont_write_bytecode) + sys._xoptions = dict(x.split('=', 1) if '=' in x else (x, True) + for x in options['_xoptions']) + ## if not we_are_translated(): ## for key in sorted(options): ## print '%40s: %s' % (key, options[key]) diff --git a/pypy/interpreter/test2/test_app_main.py b/pypy/interpreter/test2/test_app_main.py --- a/pypy/interpreter/test2/test_app_main.py +++ b/pypy/interpreter/test2/test_app_main.py @@ -170,6 +170,10 @@ self.check(['-Wbog'], {}, sys_argv=[''], warnoptions=['bog'], run_stdin=True) self.check(['-W', 'ab', '-SWc'], {}, sys_argv=[''], warnoptions=['ab', 'c'], run_stdin=True, no_site=1) + self.check(['-X', 'foo'], {}, sys_argv=[''], _xoptions=['foo'], + run_stdin=True) + self.check(['-X', 'foo=bar', '-Xbaz'], {}, sys_argv=[''], + _xoptions=['foo=bar', 'baz'], run_stdin=True) self.check([], {'PYTHONDEBUG': '1'}, sys_argv=[''], run_stdin=True, debug=1) self.check([], {'PYTHONDONTWRITEBYTECODE': '1'}, sys_argv=[''], run_stdin=True, dont_write_bytecode=1) @@ -705,6 +709,13 @@ assert "__init__ argv: ['-m', 'extra']" in data assert "__main__ argv: [%r, 'extra']" % p in data + def test_xoptions(self): + data = self.run('-Xfoo -Xbar=baz -Xquux=cdrom.com=FreeBSD -Xx=X,d=e ' + '-c "import sys;print(sorted(sys._xoptions.items()))"') + expected = ("[('bar', 'baz'), ('foo', True), " + "('quux', 'cdrom.com=FreeBSD'), ('x', 'X,d=e')]") + assert expected in data + def test_pythoninspect_doesnt_override_isatty(self): os.environ['PYTHONINSPECT_'] = '1' try: diff --git a/pypy/module/sys/__init__.py b/pypy/module/sys/__init__.py --- a/pypy/module/sys/__init__.py +++ b/pypy/module/sys/__init__.py @@ -92,6 +92,7 @@ 'callstats' : 'app.callstats', 'copyright' : 'app.copyright_str', 'flags' : 'app.null_sysflags', + '_xoptions' : 'app.null__xoptions', } def setbuiltinmodule(self, w_module, name): diff --git a/pypy/module/sys/app.py b/pypy/module/sys/app.py --- a/pypy/module/sys/app.py +++ b/pypy/module/sys/app.py @@ -104,3 +104,4 @@ hash_randomization = structseqfield(12) null_sysflags = sysflags((0,)*13) +null__xoptions = {} From noreply at buildbot.pypy.org Sat Feb 23 01:23:48 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sat, 23 Feb 2013 01:23:48 +0100 (CET) Subject: [pypy-commit] pypy default: unused imports Message-ID: <20130223002348.CF3B31C47A0@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61629:9628d130c23a Date: 2013-02-22 19:12 -0500 http://bitbucket.org/pypy/pypy/changeset/9628d130c23a/ Log: unused imports diff --git a/rpython/rtyper/lltypesystem/rdict.py b/rpython/rtyper/lltypesystem/rdict.py --- a/rpython/rtyper/lltypesystem/rdict.py +++ b/rpython/rtyper/lltypesystem/rdict.py @@ -1,14 +1,12 @@ from rpython.tool.pairtype import pairtype from rpython.flowspace.model import Constant -from rpython.rtyper.rdict import (AbstractDictRepr, AbstractDictIteratorRepr, - rtype_newdict) +from rpython.rtyper.rdict import AbstractDictRepr, AbstractDictIteratorRepr from rpython.rtyper.lltypesystem import lltype from rpython.rlib import objectmodel, jit from rpython.rlib.debug import ll_assert from rpython.rlib.rarithmetic import r_uint, intmask, LONG_BIT from rpython.rtyper import rmodel from rpython.rtyper.error import TyperError -from rpython.annotator.model import SomeInteger HIGHEST_BIT = r_uint(intmask(1 << (LONG_BIT - 1))) From noreply at buildbot.pypy.org Sat Feb 23 01:23:50 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sat, 23 Feb 2013 01:23:50 +0100 (CET) Subject: [pypy-commit] pypy default: fix whatsnew Message-ID: <20130223002350.0D7EB1C47A1@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61630:020ca3b84fdb Date: 2013-02-22 19:22 -0500 http://bitbucket.org/pypy/pypy/changeset/020ca3b84fdb/ Log: fix whatsnew diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst --- a/pypy/doc/whatsnew-head.rst +++ b/pypy/doc/whatsnew-head.rst @@ -68,6 +68,7 @@ .. branch: coding-guide-update-rlib-refs .. branch: rlib-doc-rpython-refs +.. branch: clean-up-remaining-pypy-rlib-refs .. branch: enumerate-rstr Support enumerate() over rstr types. From noreply at buildbot.pypy.org Sat Feb 23 01:36:48 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sat, 23 Feb 2013 01:36:48 +0100 (CET) Subject: [pypy-commit] pypy default: fix b82871fad050: the validate_fd is done by ll_os calls Message-ID: <20130223003648.E3D7E1C47A0@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61631:a9b2317162ca Date: 2013-02-22 19:36 -0500 http://bitbucket.org/pypy/pypy/changeset/a9b2317162ca/ Log: fix b82871fad050: the validate_fd is done by ll_os calls diff --git a/pypy/module/_io/interp_fileio.py b/pypy/module/_io/interp_fileio.py --- a/pypy/module/_io/interp_fileio.py +++ b/pypy/module/_io/interp_fileio.py @@ -3,7 +3,6 @@ from pypy.interpreter.error import OperationError, wrap_oserror, wrap_oserror2 from rpython.rlib.rarithmetic import r_longlong from rpython.rlib.rstring import StringBuilder -from rpython.rlib.rposix import validate_fd from os import O_RDONLY, O_WRONLY, O_RDWR, O_CREAT, O_TRUNC import sys, os, stat, errno from pypy.module._io.interp_iobase import W_RawIOBase, convert_size @@ -154,7 +153,6 @@ fd_is_own = False try: if fd >= 0: - validate_fd(fd) try: os.fstat(fd) except OSError, e: @@ -235,7 +233,6 @@ self.fd = -1 try: - validate_fd(fd) os.close(fd) except OSError, e: raise wrap_oserror(space, e, From noreply at buildbot.pypy.org Sat Feb 23 01:42:09 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Sat, 23 Feb 2013 01:42:09 +0100 (CET) Subject: [pypy-commit] pypy default: Fix Message-ID: <20130223004209.D6AC61C47A0@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r61632:79705a5e9d37 Date: 2013-02-22 16:41 -0800 http://bitbucket.org/pypy/pypy/changeset/79705a5e9d37/ Log: Fix diff --git a/rpython/rtyper/lltypesystem/rdict.py b/rpython/rtyper/lltypesystem/rdict.py --- a/rpython/rtyper/lltypesystem/rdict.py +++ b/rpython/rtyper/lltypesystem/rdict.py @@ -1,6 +1,8 @@ from rpython.tool.pairtype import pairtype from rpython.flowspace.model import Constant -from rpython.rtyper.rdict import AbstractDictRepr, AbstractDictIteratorRepr +# rtype_newdict is accessed through this module in other places +from rpython.rtyper.rdict import (AbstractDictRepr, AbstractDictIteratorRepr, + rtype_newdict) from rpython.rtyper.lltypesystem import lltype from rpython.rlib import objectmodel, jit from rpython.rlib.debug import ll_assert From noreply at buildbot.pypy.org Sat Feb 23 01:57:19 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sat, 23 Feb 2013 01:57:19 +0100 (CET) Subject: [pypy-commit] pypy default: a more correct simplification for this import Message-ID: <20130223005719.B4AF21C4763@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61633:25d39ec60174 Date: 2013-02-22 19:55 -0500 http://bitbucket.org/pypy/pypy/changeset/25d39ec60174/ Log: a more correct simplification for this import diff --git a/rpython/rtyper/lltypesystem/rdict.py b/rpython/rtyper/lltypesystem/rdict.py --- a/rpython/rtyper/lltypesystem/rdict.py +++ b/rpython/rtyper/lltypesystem/rdict.py @@ -1,8 +1,6 @@ from rpython.tool.pairtype import pairtype from rpython.flowspace.model import Constant -# rtype_newdict is accessed through this module in other places -from rpython.rtyper.rdict import (AbstractDictRepr, AbstractDictIteratorRepr, - rtype_newdict) +from rpython.rtyper.rdict import AbstractDictRepr, AbstractDictIteratorRepr from rpython.rtyper.lltypesystem import lltype from rpython.rlib import objectmodel, jit from rpython.rlib.debug import ll_assert diff --git a/rpython/rtyper/ootypesystem/rdict.py b/rpython/rtyper/ootypesystem/rdict.py --- a/rpython/rtyper/ootypesystem/rdict.py +++ b/rpython/rtyper/ootypesystem/rdict.py @@ -7,8 +7,6 @@ from rpython.rtyper.ootypesystem import ootype from rpython.rlib import objectmodel from rpython.rtyper import rmodel, llinterp -# This is needed by other things, don't remove! -from rpython.rtyper.rdict import rtype_newdict class DictRepr(AbstractDictRepr): diff --git a/rpython/rtyper/rtyper.py b/rpython/rtyper/rtyper.py --- a/rpython/rtyper/rtyper.py +++ b/rpython/rtyper/rtyper.py @@ -624,7 +624,7 @@ return rlist.rtype_newlist(hop) def translate_op_newdict(self, hop): - return self.type_system.rdict.rtype_newdict(hop) + return rdict.rtype_newdict(hop) def translate_op_alloc_and_set(self, hop): return rlist.rtype_alloc_and_set(hop) From noreply at buildbot.pypy.org Sat Feb 23 02:03:02 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sat, 23 Feb 2013 02:03:02 +0100 (CET) Subject: [pypy-commit] pypy default: also unused imports Message-ID: <20130223010302.A68871C47A0@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61634:84511ebb7104 Date: 2013-02-22 20:02 -0500 http://bitbucket.org/pypy/pypy/changeset/84511ebb7104/ Log: also unused imports diff --git a/rpython/rtyper/ootypesystem/rlist.py b/rpython/rtyper/ootypesystem/rlist.py --- a/rpython/rtyper/ootypesystem/rlist.py +++ b/rpython/rtyper/ootypesystem/rlist.py @@ -1,6 +1,6 @@ from rpython.tool.pairtype import pairtype from rpython.rtyper.rlist import AbstractBaseListRepr, AbstractListRepr, \ - AbstractListIteratorRepr, AbstractFixedSizeListRepr, rtype_newlist, rtype_alloc_and_set + AbstractListIteratorRepr, AbstractFixedSizeListRepr from rpython.rtyper.rmodel import Repr, IntegerRepr from rpython.rtyper.rmodel import inputconst, externalvsinternal from rpython.rtyper.lltypesystem.lltype import Signed, Void From noreply at buildbot.pypy.org Sat Feb 23 03:25:51 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sat, 23 Feb 2013 03:25:51 +0100 (CET) Subject: [pypy-commit] pypy default: consolidate duplicate numpypy implementations of sum/min/max Message-ID: <20130223022551.96DA71C47A0@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61635:df3dbf3213d3 Date: 2013-02-22 21:25 -0500 http://bitbucket.org/pypy/pypy/changeset/df3dbf3213d3/ Log: consolidate duplicate numpypy implementations of sum/min/max diff --git a/lib_pypy/numpypy/__init__.py b/lib_pypy/numpypy/__init__.py --- a/lib_pypy/numpypy/__init__.py +++ b/lib_pypy/numpypy/__init__.py @@ -1,7 +1,7 @@ from _numpypy import * from .core import * + import _numpypy - __all__ = _numpypy.__all__ import sys diff --git a/lib_pypy/numpypy/core/__init__.py b/lib_pypy/numpypy/core/__init__.py --- a/lib_pypy/numpypy/core/__init__.py +++ b/lib_pypy/numpypy/core/__init__.py @@ -2,4 +2,5 @@ from .numeric import * from .shape_base import * -from _numpypy import abs, max, min +from _numpypy import abs +from .fromnumeric import amax as max, amin as min diff --git a/lib_pypy/numpypy/core/fromnumeric.py b/lib_pypy/numpypy/core/fromnumeric.py --- a/lib_pypy/numpypy/core/fromnumeric.py +++ b/lib_pypy/numpypy/core/fromnumeric.py @@ -1360,10 +1360,9 @@ """ assert dtype is None - assert out is None if not hasattr(a, "sum"): a = numpypy.array(a) - return a.sum(axis=axis) + return a.sum(axis=axis, out=out) def product (a, axis=None, dtype=None, out=None): @@ -1720,11 +1719,11 @@ 4.0 """ - assert axis is None - assert out is None if not hasattr(a, "max"): a = numpypy.array(a) - return a.max() + if a.size < 1: + return numpypy.array([]) + return a.max(axis=axis, out=out) def amin(a, axis=None, out=None): @@ -1782,12 +1781,11 @@ 0.0 """ - # amin() is equivalent to min() - assert axis is None - assert out is None if not hasattr(a, 'min'): a = numpypy.array(a) - return a.min() + if a.size < 1: + return numpypy.array([]) + return a.min(axis=axis, out=out) def alen(a): """ diff --git a/pypy/module/micronumpy/__init__.py b/pypy/module/micronumpy/__init__.py --- a/pypy/module/micronumpy/__init__.py +++ b/pypy/module/micronumpy/__init__.py @@ -164,25 +164,20 @@ appleveldefs = { 'average': 'app_numpy.average', - 'sum': 'app_numpy.sum', - 'min': 'app_numpy.min', 'identity': 'app_numpy.identity', 'eye': 'app_numpy.eye', - 'max': 'app_numpy.max', 'arange': 'app_numpy.arange', } def setup_after_space_initialization(self): space = self.space - alllist = sorted(Module.interpleveldefs.keys() + \ + all_list = sorted(Module.interpleveldefs.keys() + \ Module.appleveldefs.keys()) # found by set(numpypy.__all__) - set(numpy.__all__) - alllist.remove('min') - alllist.remove('max') - alllist.remove('bool') - alllist.remove('int') - alllist.remove('abs') - alllist.remove('typeinfo') - w_all = space.wrap(alllist) + all_list.remove('bool') + all_list.remove('int') + all_list.remove('abs') + all_list.remove('typeinfo') + w_all = space.wrap(all_list) space.setitem(self.w_dict, space.new_interned_str('__all__'), w_all) if long_double_size == 16: diff --git a/pypy/module/micronumpy/app_numpy.py b/pypy/module/micronumpy/app_numpy.py --- a/pypy/module/micronumpy/app_numpy.py +++ b/pypy/module/micronumpy/app_numpy.py @@ -35,49 +35,6 @@ mi += 1 return a -def sum(a,axis=None, out=None): - '''sum(a, axis=None) - Sum of array elements over a given axis. - - Parameters - ---------- - a : array_like - Elements to sum. - axis : integer, optional - Axis over which the sum is taken. By default `axis` is None, - and all elements are summed. - - Returns - ------- - sum_along_axis : ndarray - An array with the same shape as `a`, with the specified - axis removed. If `a` is a 0-d array, or if `axis` is None, a scalar - is returned. If an output array is specified, a reference to - `out` is returned. - - See Also - -------- - ndarray.sum : Equivalent method. - ''' - # TODO: add to doc (once it's implemented): cumsum : Cumulative sum of array elements. - if not hasattr(a, "sum"): - a = _numpypy.array(a) - return a.sum(axis=axis, out=out) - -def min(a, axis=None, out=None): - if not hasattr(a, "min"): - a = _numpypy.array(a) - if a.size < 1: - return _numpypy.array([]) - return a.min(axis=axis, out=out) - -def max(a, axis=None, out=None): - if not hasattr(a, "max"): - a = _numpypy.array(a) - if a.size < 1: - return _numpypy.array([]) - return a.max(axis=axis, out=out) - def arange(start, stop=None, step=1, dtype=None): '''arange([start], stop[, step], dtype=None) Generate values in the half-interval [start, stop). diff --git a/pypy/module/micronumpy/test/test_module.py b/pypy/module/micronumpy/test/test_module.py --- a/pypy/module/micronumpy/test/test_module.py +++ b/pypy/module/micronumpy/test/test_module.py @@ -6,20 +6,3 @@ from _numpypy import array, average assert average(range(10)) == 4.5 assert average(array(range(10))) == 4.5 - - def test_sum(self): - from _numpypy import array, sum - assert sum(range(10)) == 45 - assert sum(array(range(10))) == 45 - - def test_min(self): - from _numpypy import array, min, zeros - assert min(range(10)) == 0 - assert min(array(range(10))) == 0 - assert list(min(zeros((0, 2)), axis=1)) == [] - - def test_max(self): - from _numpypy import array, max, zeros - assert max(range(10)) == 9 - assert max(array(range(10))) == 9 - assert list(max(zeros((0, 2)), axis=1)) == [] diff --git a/pypy/module/micronumpy/test/test_outarg.py b/pypy/module/micronumpy/test/test_outarg.py --- a/pypy/module/micronumpy/test/test_outarg.py +++ b/pypy/module/micronumpy/test/test_outarg.py @@ -83,22 +83,9 @@ b = add(10, 10, out=out) assert b==out assert b.dtype == out.dtype - - def test_applevel(self): - from _numpypy import array, sum, max, min - a = array([[1, 2], [3, 4]]) - out = array([[0, 0], [0, 0]]) - c = sum(a, axis=0, out=out[0]) - assert (c == [4, 6]).all() - assert (c == out[0]).all() - assert (c != out[1]).all() - c = max(a, axis=1, out=out[0]) - assert (c == [2, 4]).all() - assert (c == out[0]).all() - assert (c != out[1]).all() - + def test_ufunc_cast(self): - from _numpypy import array, negative, add, sum + from _numpypy import array, negative, add a = array(16, dtype = int) c = array(0, dtype = float) b = negative(a, out=c) @@ -106,7 +93,7 @@ b = add(a, a, out=c) assert b == c d = array([16, 16], dtype=int) - b = sum(d, out=c) + b = d.sum(out=c) assert b == c #cast_error = raises(TypeError, negative, c, a) #assert str(cast_error.value) == \ diff --git a/pypy/module/test_lib_pypy/numpypy/core/test_fromnumeric.py b/pypy/module/test_lib_pypy/numpypy/core/test_fromnumeric.py --- a/pypy/module/test_lib_pypy/numpypy/core/test_fromnumeric.py +++ b/pypy/module/test_lib_pypy/numpypy/core/test_fromnumeric.py @@ -45,9 +45,19 @@ # If the accumulator is too small, overflow occurs: # assert ones(128, dtype=int8).sum(dtype=int8) == -128 + assert sum(range(10)) == 45 + assert sum(array(range(10))) == 45 + + a = array([[1, 2], [3, 4]]) + out = array([[0, 0], [0, 0]]) + c = sum(a, axis=0, out=out[0]) + assert (c == [4, 6]).all() + assert (c == out[0]).all() + assert (c != out[1]).all() + def test_amin(self): # tests taken from numpy/core/fromnumeric.py docstring - from numpypy import array, arange, amin + from numpypy import array, arange, amin, zeros a = arange(4).reshape((2,2)) assert amin(a) == 0 # # Minima along the first axis @@ -60,9 +70,20 @@ # assert amin(b) == nan # assert nanmin(b) == 0.0 + assert amin(range(10)) == 0 + assert amin(array(range(10))) == 0 + assert list(amin(zeros((0, 2)), axis=1)) == [] + + a = array([[1, 2], [3, 4]]) + out = array([[0, 0], [0, 0]]) + c = amin(a, axis=1, out=out[0]) + assert (c == [1, 3]).all() + assert (c == out[0]).all() + assert (c != out[1]).all() + def test_amax(self): # tests taken from numpy/core/fromnumeric.py docstring - from numpypy import array, arange, amax + from numpypy import array, arange, amax, zeros a = arange(4).reshape((2,2)) assert amax(a) == 3 # assert (amax(a, axis=0) == array([2, 3])).all() @@ -73,6 +94,17 @@ # assert amax(b) == nan # assert nanmax(b) == 4.0 + assert amax(range(10)) == 9 + assert amax(array(range(10))) == 9 + assert list(amax(zeros((0, 2)), axis=1)) == [] + + a = array([[1, 2], [3, 4]]) + out = array([[0, 0], [0, 0]]) + c = amax(a, axis=1, out=out[0]) + assert (c == [2, 4]).all() + assert (c == out[0]).all() + assert (c != out[1]).all() + def test_alen(self): # tests taken from numpy/core/fromnumeric.py docstring from numpypy import array, zeros, alen diff --git a/pypy/module/test_lib_pypy/numpypy/test_numpy.py b/pypy/module/test_lib_pypy/numpypy/test_numpy.py --- a/pypy/module/test_lib_pypy/numpypy/test_numpy.py +++ b/pypy/module/test_lib_pypy/numpypy/test_numpy.py @@ -26,6 +26,8 @@ assert min(4, 3, 2, 1) == 1 assert max(1, 2, 3, 4) == 4 - from numpypy import min, max + from numpypy import min, max, amin, amax assert min is not __builtin__.min assert max is not __builtin__.max + assert min is amin + assert max is amax From noreply at buildbot.pypy.org Sat Feb 23 03:47:56 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sat, 23 Feb 2013 03:47:56 +0100 (CET) Subject: [pypy-commit] pypy default: add this test for numpypy.sum also Message-ID: <20130223024756.B6C5C1C4763@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61636:a6ca90ce76e9 Date: 2013-02-22 21:38 -0500 http://bitbucket.org/pypy/pypy/changeset/a6ca90ce76e9/ Log: add this test for numpypy.sum also diff --git a/pypy/module/test_lib_pypy/numpypy/core/test_fromnumeric.py b/pypy/module/test_lib_pypy/numpypy/core/test_fromnumeric.py --- a/pypy/module/test_lib_pypy/numpypy/core/test_fromnumeric.py +++ b/pypy/module/test_lib_pypy/numpypy/core/test_fromnumeric.py @@ -36,7 +36,7 @@ def test_sum(self): # tests taken from numpy/core/fromnumeric.py docstring - from numpypy import array, sum, ones + from numpypy import array, sum, ones, zeros assert sum([0.5, 1.5])== 2.0 assert sum([[0, 1], [0, 5]]) == 6 # assert sum([0.5, 0.7, 0.2, 1.5], dtype=int32) == 1 @@ -47,6 +47,7 @@ assert sum(range(10)) == 45 assert sum(array(range(10))) == 45 + assert list(sum(zeros((0, 2)), axis=1)) == [] a = array([[1, 2], [3, 4]]) out = array([[0, 0], [0, 0]]) From noreply at buildbot.pypy.org Sat Feb 23 03:47:58 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sat, 23 Feb 2013 03:47:58 +0100 (CET) Subject: [pypy-commit] pypy default: update numarray min/max tests to show why the app-level workaround is the wrong approach Message-ID: <20130223024758.029D21C4763@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61637:25681452af3c Date: 2013-02-22 21:47 -0500 http://bitbucket.org/pypy/pypy/changeset/25681452af3c/ Log: update numarray min/max tests to show why the app-level workaround is the wrong approach diff --git a/pypy/module/micronumpy/test/test_numarray.py b/pypy/module/micronumpy/test/test_numarray.py --- a/pypy/module/micronumpy/test/test_numarray.py +++ b/pypy/module/micronumpy/test/test_numarray.py @@ -1141,7 +1141,7 @@ assert (a.mean(1) == [0.5, 2.5, 4.5, 6.5, 8.5]).all() def test_sum(self): - from _numpypy import array + from _numpypy import array, zeros a = array(range(5)) assert a.sum() == 10 assert a[:4].sum() == 6 @@ -1156,6 +1156,8 @@ assert b == d assert b is d + assert list(zeros((0, 2)).sum(axis=1)) == [] + def test_reduce_nd(self): from numpypy import arange, array, multiply a = arange(15).reshape(5, 3) @@ -1242,24 +1244,28 @@ assert a[:4].prod() == 24.0 def test_max(self): - from _numpypy import array + from _numpypy import array, zeros a = array([-1.2, 3.4, 5.7, -3.0, 2.7]) assert a.max() == 5.7 b = array([]) raises(ValueError, "b.max()") + assert list(zeros((0, 2)).max(axis=1)) == [] + def test_max_add(self): from _numpypy import array a = array([-1.2, 3.4, 5.7, -3.0, 2.7]) assert (a + a).max() == 11.4 def test_min(self): - from _numpypy import array + from _numpypy import array, zeros a = array([-1.2, 3.4, 5.7, -3.0, 2.7]) assert a.min() == -3.0 b = array([]) raises(ValueError, "b.min()") + assert list(zeros((0, 2)).min(axis=1)) == [] + def test_argmax(self): from _numpypy import array a = array([-1.2, 3.4, 5.7, -3.0, 2.7]) From noreply at buildbot.pypy.org Sat Feb 23 05:27:40 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Sat, 23 Feb 2013 05:27:40 +0100 (CET) Subject: [pypy-commit] pypy py3k: support __context__ and __traceback__, be stricter about __cause__ Message-ID: <20130223042740.130A01C47A1@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61638:f2d371471588 Date: 2013-02-22 20:26 -0800 http://bitbucket.org/pypy/pypy/changeset/f2d371471588/ Log: support __context__ and __traceback__, be stricter about __cause__ diff --git a/pypy/interpreter/error.py b/pypy/interpreter/error.py --- a/pypy/interpreter/error.py +++ b/pypy/interpreter/error.py @@ -24,16 +24,43 @@ def __init__(self, w_type, w_value, tb=None, w_cause=None): assert w_type is not None - self.setup(w_type) - self._w_value = w_value + self.setup(w_type, w_value) self._application_traceback = tb self.w_cause = w_cause - def setup(self, w_type): + def setup(self, w_type, w_value=None): + from pypy.objspace.std.typeobject import W_TypeObject self.w_type = w_type + self._w_value = w_value + if isinstance(w_type, W_TypeObject): + self.setup_context(w_type.space) if not we_are_translated(): self.debug_excs = [] + def setup_context(self, space): + # Implicit exception chaining + last_operror = space.getexecutioncontext().sys_exc_info() + if last_operror is None: + return + + # We must normalize the value right now to check for cycles + self.normalize_exception(space) + w_value = self.get_w_value(space) + w_last_value = last_operror.get_w_value(space) + if not space.is_w(w_value, w_last_value): + # Avoid reference cycles through the context chain. This is + # O(chain length) but context chains are usually very short. + w_obj = w_last_value + while True: + w_context = space.getattr(w_obj, space.wrap('__context__')) + if space.is_w(w_context, space.w_None): + break + if space.is_w(w_context, w_value): + space.setattr(w_obj, space.wrap('__context__'), space.w_None) + break + w_obj = w_context + space.setattr(w_value, space.wrap('__context__'), w_last_value) + def clear(self, space): self.w_type = space.w_None self._w_value = space.w_None @@ -199,8 +226,21 @@ w_value = space.call_function(w_type, w_value) w_type = self._exception_getclass(space, w_value) if self.w_cause: + # ensure w_cause is of a valid type + self._exception_getclass(space, self.w_cause, "exception causes") space.setattr(w_value, space.wrap("__cause__"), self.w_cause) - + if self._application_traceback: + from pypy.interpreter.pytraceback import PyTraceback + from pypy.module.exceptions.interp_exceptions import W_BaseException + tb = self._application_traceback + if (isinstance(w_value, W_BaseException) and + isinstance(tb, PyTraceback)): + # traceback hasn't escaped yet + w_value.w_traceback = tb + else: + # traceback has escaped + space.setattr(w_value, space.wrap("__traceback__"), + space.wrap(self.get_traceback())) else: # the only case left here is (inst, None), from a 'raise inst'. w_inst = w_type @@ -215,13 +255,12 @@ self.w_type = w_type self._w_value = w_value - def _exception_getclass(self, space, w_inst): + def _exception_getclass(self, space, w_inst, what="exceptions"): w_type = space.exception_getclass(w_inst) if not space.exception_is_valid_class_w(w_type): typename = w_type.getname(space) - msg = ("exceptions must be classes or instances deriving from " - "BaseException, not %s") - raise operationerrfmt(space.w_TypeError, msg, typename) + msg = "%s must derive from BaseException, not %s" + raise operationerrfmt(space.w_TypeError, msg, what, typename) return w_type def write_unraisable(self, space, where, w_object=None, @@ -336,12 +375,12 @@ # class OpErrFmt(OperationError): def __init__(self, w_type, strings, *args): - self.setup(w_type) assert len(args) == len(strings) - 1 self.xstrings = strings for i, fmt, attr in entries: setattr(self, attr, args[i]) assert w_type is not None + self.setup(w_type) def _compute_value(self): lst = [None] * (len(formats) + len(formats) + 1) for i, fmt, attr in entries: diff --git a/pypy/interpreter/pyopcode.py b/pypy/interpreter/pyopcode.py --- a/pypy/interpreter/pyopcode.py +++ b/pypy/interpreter/pyopcode.py @@ -480,11 +480,12 @@ # re-raise, no new traceback obj will be attached self.last_exception = operror raise RaiseWithExplicitTraceback(operror) - w_value = w_cause = space.w_None if nbargs == 2: w_cause = self.popvalue() if space.exception_is_valid_obj_as_class_w(w_cause): w_cause = space.call_function(w_cause) + else: + w_cause = None w_value = self.popvalue() if space.exception_is_valid_obj_as_class_w(w_value): w_type = w_value diff --git a/pypy/interpreter/test/test_interpreter.py b/pypy/interpreter/test/test_interpreter.py --- a/pypy/interpreter/test/test_interpreter.py +++ b/pypy/interpreter/test/test_interpreter.py @@ -73,8 +73,7 @@ raise 1 ''', 'f', []) assert "TypeError:" in x - assert ("exceptions must be classes or instances deriving from " - "BaseException, not ") in x + assert "exceptions must derive from BaseException" in x def test_except2(self): x = self.codetest(''' diff --git a/pypy/interpreter/test/test_raise.py b/pypy/interpreter/test/test_raise.py --- a/pypy/interpreter/test/test_raise.py +++ b/pypy/interpreter/test/test_raise.py @@ -79,21 +79,6 @@ assert sys.exc_info()[0] is ValueError assert sys.exc_info() == (None, None, None) - def test_raise_with___traceback__(self): - import sys - try: - raise ValueError - except: - exc_type,exc_val,exc_tb = sys.exc_info() - try: - exc_val.__traceback__ = exc_tb - raise exc_val - except: - exc_type2,exc_val2,exc_tb2 = sys.exc_info() - assert exc_type is exc_type2 - assert exc_val is exc_val2 - assert exc_tb is exc_tb2.tb_next - def test_reraise_1(self): raises(IndexError, """ import sys @@ -321,6 +306,111 @@ break assert sys.exc_info() == (None, None, None) +class AppTestRaiseContext: + + def test_instance_context(self): + context = IndexError() + try: + try: + raise context + except: + raise OSError() + except OSError as e: + assert e.__context__ is context + else: + fail('No exception raised') + + def test_class_context(self): + context = IndexError + try: + try: + raise context + except: + raise OSError() + except OSError as e: + assert e.__context__ != context + assert isinstance(e.__context__, context) + else: + fail('No exception raised') + + def test_internal_exception(self): + try: + try: + 1/0 + except: + xyzzy + except NameError as e: + assert isinstance(e.__context__, ZeroDivisionError) + else: + fail("No exception raised") + + def test_cycle_broken(self): + try: + try: + 1/0 + except ZeroDivisionError as e: + raise e + except ZeroDivisionError as e: + assert e.__context__ is None + else: + fail("No exception raised") + + def test_reraise_cycle_broken(self): + try: + try: + xyzzy + except NameError as a: + try: + 1/0 + except ZeroDivisionError: + raise a + except NameError as e: + assert e.__context__.__context__ is None + else: + fail("No exception raised") + +class AppTestTraceback: + + def test_raise_with___traceback__(self): + import sys + try: + raise ValueError + except: + exc_type,exc_val,exc_tb = sys.exc_info() + try: + exc_val.__traceback__ = exc_tb + raise exc_val + except: + exc_type2,exc_val2,exc_tb2 = sys.exc_info() + assert exc_type is exc_type2 + assert exc_val is exc_val2 + assert exc_tb is exc_tb2.tb_next + + def test_sets_traceback(self): + import types + try: + raise IndexError() + except IndexError as e: + assert isinstance(e.__traceback__, types.TracebackType) + else: + fail("No exception raised") + + def test_accepts_traceback(self): + import sys + def get_tb(): + try: + raise OSError() + except: + return sys.exc_info()[2] + tb = get_tb() + try: + raise IndexError().with_traceback(tb) + except IndexError as e: + assert e.__traceback__ != tb + assert e.__traceback__.tb_next is tb + else: + fail("No exception raised") + def test_invalid_reraise(self): try: raise @@ -328,3 +418,27 @@ assert "No active exception" in str(e) else: fail("Expected RuntimeError") + + def test_invalid_cause(self): + """ + try: + raise IndexError from 5 + except TypeError as e: + assert "exception cause" in str(e) + else: + fail("Expected TypeError") + """ + + def test_invalid_cause_setter(self): + """ + class Setter(BaseException): + def set_cause(self, cause): + self.cause = cause + __cause__ = property(fset=set_cause) + try: + raise Setter from 5 + except TypeError as e: + assert "exception cause" in str(e) + else: + fail("Expected TypeError") + """ diff --git a/pypy/module/exceptions/interp_exceptions.py b/pypy/module/exceptions/interp_exceptions.py --- a/pypy/module/exceptions/interp_exceptions.py +++ b/pypy/module/exceptions/interp_exceptions.py @@ -171,7 +171,12 @@ self.w_context = w_newcontext def descr_gettraceback(self, space): - return self.w_traceback + from pypy.interpreter.pytraceback import PyTraceback + tb = self.w_traceback + if tb is not None and isinstance(tb, PyTraceback): + # tb escapes to app level (see OperationError.get_traceback) + tb.frame.mark_as_escaped() + return tb def descr_settraceback(self, space, w_newtraceback): msg = '__traceback__ must be a traceback or None' From noreply at buildbot.pypy.org Sat Feb 23 08:14:09 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sat, 23 Feb 2013 08:14:09 +0100 (CET) Subject: [pypy-commit] pypy default: move _numpypy.identity to numpypy.core.numeric Message-ID: <20130223071409.79DAC1C0327@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61639:88878ea32353 Date: 2013-02-23 00:50 -0500 http://bitbucket.org/pypy/pypy/changeset/88878ea32353/ Log: move _numpypy.identity to numpypy.core.numeric diff --git a/lib_pypy/numpypy/core/numeric.py b/lib_pypy/numpypy/core/numeric.py --- a/lib_pypy/numpypy/core/numeric.py +++ b/lib_pypy/numpypy/core/numeric.py @@ -501,3 +501,34 @@ a = asarray(a) b = asarray(b) return a.ravel()[:,newaxis]*b.ravel()[newaxis,:] + +def identity(n, dtype=None): + """ + Return the identity array. + + The identity array is a square array with ones on + the main diagonal. + + Parameters + ---------- + n : int + Number of rows (and columns) in `n` x `n` output. + dtype : data-type, optional + Data-type of the output. Defaults to ``float``. + + Returns + ------- + out : ndarray + `n` x `n` array with its main diagonal set to one, + and all other elements 0. + + Examples + -------- + >>> np.identity(3) + array([[ 1., 0., 0.], + [ 0., 1., 0.], + [ 0., 0., 1.]]) + + """ + from _numpypy import eye + return eye(n, dtype=dtype) diff --git a/pypy/module/micronumpy/__init__.py b/pypy/module/micronumpy/__init__.py --- a/pypy/module/micronumpy/__init__.py +++ b/pypy/module/micronumpy/__init__.py @@ -164,7 +164,6 @@ appleveldefs = { 'average': 'app_numpy.average', - 'identity': 'app_numpy.identity', 'eye': 'app_numpy.eye', 'arange': 'app_numpy.arange', } diff --git a/pypy/module/micronumpy/app_numpy.py b/pypy/module/micronumpy/app_numpy.py --- a/pypy/module/micronumpy/app_numpy.py +++ b/pypy/module/micronumpy/app_numpy.py @@ -9,12 +9,6 @@ a = _numpypy.array(a) return a.mean() -def identity(n, dtype=None): - a = _numpypy.zeros((n, n), dtype=dtype) - for i in range(n): - a[i][i] = 1 - return a - def eye(n, m=None, k=0, dtype=None): if m is None: m = n diff --git a/pypy/module/micronumpy/test/test_numarray.py b/pypy/module/micronumpy/test/test_numarray.py --- a/pypy/module/micronumpy/test/test_numarray.py +++ b/pypy/module/micronumpy/test/test_numarray.py @@ -1188,26 +1188,6 @@ assert (array([[1,2],[3,4]]).prod(0) == [3, 8]).all() assert (array([[1,2],[3,4]]).prod(1) == [2, 12]).all() - def test_identity(self): - from _numpypy import identity, array - from _numpypy import int32, float64, dtype - a = identity(0) - assert len(a) == 0 - assert a.dtype == dtype('float64') - assert a.shape == (0, 0) - b = identity(1, dtype=int32) - assert len(b) == 1 - assert b[0][0] == 1 - assert b.shape == (1, 1) - assert b.dtype == dtype('int32') - c = identity(2) - assert c.shape == (2, 2) - assert (c == [[1, 0], [0, 1]]).all() - d = identity(3, dtype='int32') - assert d.shape == (3, 3) - assert d.dtype == dtype('int32') - assert (d == [[1, 0, 0], [0, 1, 0], [0, 0, 1]]).all() - def test_eye(self): from _numpypy import eye from _numpypy import int32, dtype diff --git a/pypy/module/test_lib_pypy/numpypy/core/test_numeric.py b/pypy/module/test_lib_pypy/numpypy/core/test_numeric.py --- a/pypy/module/test_lib_pypy/numpypy/core/test_numeric.py +++ b/pypy/module/test_lib_pypy/numpypy/core/test_numeric.py @@ -20,6 +20,7 @@ assert base_repr(-12, 10, 4) == '-000012' assert base_repr(-12, 4) == '-30' + class AppTestRepr(BaseNumpyAppTest): def test_repr(self): from numpypy import array @@ -146,10 +147,10 @@ def test_equal(self): from _numpypy import array from numpypy import array_equal - + a = [1, 2, 3] b = [1, 2, 3] - + assert array_equal(a, b) assert array_equal(a, array(b)) assert array_equal(array(a), b) @@ -158,10 +159,10 @@ def test_not_equal(self): from _numpypy import array from numpypy import array_equal - + a = [1, 2, 3] b = [1, 2, 4] - + assert not array_equal(a, b) assert not array_equal(a, array(b)) assert not array_equal(array(a), b) @@ -170,17 +171,17 @@ def test_mismatched_shape(self): from _numpypy import array from numpypy import array_equal - + a = [1, 2, 3] b = [[1, 2, 3], [1, 2, 3]] - + assert not array_equal(a, b) assert not array_equal(a, array(b)) assert not array_equal(array(a), b) assert not array_equal(array(a), array(b)) + class AppTestNumeric(BaseNumpyAppTest): - def test_outer(self): from _numpypy import array from numpypy import outer @@ -192,3 +193,22 @@ [12, 15, 18]]) assert (res == expected).all() + def test_identity(self): + from _numpypy import array, int32, float64, dtype + from numpypy import identity + a = identity(0) + assert len(a) == 0 + assert a.dtype == dtype('float64') + assert a.shape == (0, 0) + b = identity(1, dtype=int32) + assert len(b) == 1 + assert b[0][0] == 1 + assert b.shape == (1, 1) + assert b.dtype == dtype('int32') + c = identity(2) + assert c.shape == (2, 2) + assert (c == [[1, 0], [0, 1]]).all() + d = identity(3, dtype='int32') + assert d.shape == (3, 3) + assert d.dtype == dtype('int32') + assert (d == [[1, 0, 0], [0, 1, 0], [0, 0, 1]]).all() From noreply at buildbot.pypy.org Sat Feb 23 08:14:10 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sat, 23 Feb 2013 08:14:10 +0100 (CET) Subject: [pypy-commit] pypy default: move _numpypy.average to numpypy.lib.function_base Message-ID: <20130223071410.B51EE1C0327@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61640:5e8977235753 Date: 2013-02-23 01:19 -0500 http://bitbucket.org/pypy/pypy/changeset/5e8977235753/ Log: move _numpypy.average to numpypy.lib.function_base diff --git a/lib_pypy/numpypy/__init__.py b/lib_pypy/numpypy/__init__.py --- a/lib_pypy/numpypy/__init__.py +++ b/lib_pypy/numpypy/__init__.py @@ -1,5 +1,6 @@ from _numpypy import * from .core import * +from .lib import * import _numpypy __all__ = _numpypy.__all__ diff --git a/lib_pypy/numpypy/lib/__init__.py b/lib_pypy/numpypy/lib/__init__.py new file mode 100644 --- /dev/null +++ b/lib_pypy/numpypy/lib/__init__.py @@ -0,0 +1,1 @@ +from .function_base import * diff --git a/lib_pypy/numpypy/lib/function_base.py b/lib_pypy/numpypy/lib/function_base.py new file mode 100644 --- /dev/null +++ b/lib_pypy/numpypy/lib/function_base.py @@ -0,0 +1,8 @@ +from _numpypy import array + +def average(a): + # This implements a weighted average, for now we don't implement the + # weighting, just the average part! + if not hasattr(a, "mean"): + a = array(a) + return a.mean() diff --git a/pypy/module/micronumpy/__init__.py b/pypy/module/micronumpy/__init__.py --- a/pypy/module/micronumpy/__init__.py +++ b/pypy/module/micronumpy/__init__.py @@ -163,7 +163,6 @@ interpleveldefs[exposed] = "interp_ufuncs.get(space).%s" % impl appleveldefs = { - 'average': 'app_numpy.average', 'eye': 'app_numpy.eye', 'arange': 'app_numpy.arange', } diff --git a/pypy/module/micronumpy/app_numpy.py b/pypy/module/micronumpy/app_numpy.py --- a/pypy/module/micronumpy/app_numpy.py +++ b/pypy/module/micronumpy/app_numpy.py @@ -2,13 +2,6 @@ import _numpypy -def average(a): - # This implements a weighted average, for now we don't implement the - # weighting, just the average part! - if not hasattr(a, "mean"): - a = _numpypy.array(a) - return a.mean() - def eye(n, m=None, k=0, dtype=None): if m is None: m = n diff --git a/pypy/module/micronumpy/test/test_module.py b/pypy/module/micronumpy/test/test_module.py deleted file mode 100644 --- a/pypy/module/micronumpy/test/test_module.py +++ /dev/null @@ -1,8 +0,0 @@ -from pypy.module.micronumpy.test.test_base import BaseNumpyAppTest - - -class AppTestNumPyModule(BaseNumpyAppTest): - def test_average(self): - from _numpypy import array, average - assert average(range(10)) == 4.5 - assert average(array(range(10))) == 4.5 diff --git a/pypy/module/test_lib_pypy/numpypy/lib/test_function_base.py b/pypy/module/test_lib_pypy/numpypy/lib/test_function_base.py new file mode 100644 --- /dev/null +++ b/pypy/module/test_lib_pypy/numpypy/lib/test_function_base.py @@ -0,0 +1,7 @@ +from pypy.module.micronumpy.test.test_base import BaseNumpyAppTest + +class AppTestFunctionBase(BaseNumpyAppTest): + def test_average(self): + from numpypy import array, average + assert average(range(10)) == 4.5 + assert average(array(range(10))) == 4.5 From noreply at buildbot.pypy.org Sat Feb 23 08:14:11 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sat, 23 Feb 2013 08:14:11 +0100 (CET) Subject: [pypy-commit] pypy default: move _numpypy.eye to numpypy.lib.twodim_base Message-ID: <20130223071411.E96841C0327@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61641:79a8a52dba4d Date: 2013-02-23 01:30 -0500 http://bitbucket.org/pypy/pypy/changeset/79a8a52dba4d/ Log: move _numpypy.eye to numpypy.lib.twodim_base diff --git a/lib_pypy/numpypy/core/numeric.py b/lib_pypy/numpypy/core/numeric.py --- a/lib_pypy/numpypy/core/numeric.py +++ b/lib_pypy/numpypy/core/numeric.py @@ -530,5 +530,5 @@ [ 0., 0., 1.]]) """ - from _numpypy import eye + from numpy import eye return eye(n, dtype=dtype) diff --git a/lib_pypy/numpypy/lib/__init__.py b/lib_pypy/numpypy/lib/__init__.py --- a/lib_pypy/numpypy/lib/__init__.py +++ b/lib_pypy/numpypy/lib/__init__.py @@ -1,1 +1,2 @@ from .function_base import * +from .twodim_base import * diff --git a/lib_pypy/numpypy/lib/twodim_base.py b/lib_pypy/numpypy/lib/twodim_base.py new file mode 100644 --- /dev/null +++ b/lib_pypy/numpypy/lib/twodim_base.py @@ -0,0 +1,52 @@ +from _numpypy import zeros + +def eye(N, M=None, k=0, dtype=float): + """ + Return a 2-D array with ones on the diagonal and zeros elsewhere. + + Parameters + ---------- + N : int + Number of rows in the output. + M : int, optional + Number of columns in the output. If None, defaults to `N`. + k : int, optional + Index of the diagonal: 0 (the default) refers to the main diagonal, + a positive value refers to an upper diagonal, and a negative value + to a lower diagonal. + dtype : data-type, optional + Data-type of the returned array. + + Returns + ------- + I : ndarray of shape (N,M) + An array where all elements are equal to zero, except for the `k`-th + diagonal, whose values are equal to one. + + See Also + -------- + identity : (almost) equivalent function + diag : diagonal 2-D array from a 1-D array specified by the user. + + Examples + -------- + >>> np.eye(2, dtype=int) + array([[1, 0], + [0, 1]]) + >>> np.eye(3, k=1) + array([[ 0., 1., 0.], + [ 0., 0., 1.], + [ 0., 0., 0.]]) + + """ + if M is None: + M = N + m = zeros((N, M), dtype=dtype) + if k >= M: + return m + if k >= 0: + i = k + else: + i = (-k) * M + m[:M-k].flat[i::M+1] = 1 + return m diff --git a/pypy/module/micronumpy/__init__.py b/pypy/module/micronumpy/__init__.py --- a/pypy/module/micronumpy/__init__.py +++ b/pypy/module/micronumpy/__init__.py @@ -163,7 +163,6 @@ interpleveldefs[exposed] = "interp_ufuncs.get(space).%s" % impl appleveldefs = { - 'eye': 'app_numpy.eye', 'arange': 'app_numpy.arange', } def setup_after_space_initialization(self): diff --git a/pypy/module/micronumpy/app_numpy.py b/pypy/module/micronumpy/app_numpy.py --- a/pypy/module/micronumpy/app_numpy.py +++ b/pypy/module/micronumpy/app_numpy.py @@ -2,26 +2,6 @@ import _numpypy -def eye(n, m=None, k=0, dtype=None): - if m is None: - m = n - a = _numpypy.zeros((n, m), dtype=dtype) - ni = 0 - mi = 0 - - if k < 0: - p = n + k - ni = -k - else: - p = n - k - mi = k - - while ni < n and mi < m: - a[ni][mi] = 1 - ni += 1 - mi += 1 - return a - def arange(start, stop=None, step=1, dtype=None): '''arange([start], stop[, step], dtype=None) Generate values in the half-interval [start, stop). diff --git a/pypy/module/micronumpy/test/test_complex.py b/pypy/module/micronumpy/test/test_complex.py --- a/pypy/module/micronumpy/test/test_complex.py +++ b/pypy/module/micronumpy/test/test_complex.py @@ -382,7 +382,7 @@ def test_conjugate(self): from _numpypy import conj, conjugate, complex128, complex64 - import _numpypy as np + import numpypy as np c0 = complex128(complex(2.5, 0)) c1 = complex64(complex(1, 2)) diff --git a/pypy/module/micronumpy/test/test_numarray.py b/pypy/module/micronumpy/test/test_numarray.py --- a/pypy/module/micronumpy/test/test_numarray.py +++ b/pypy/module/micronumpy/test/test_numarray.py @@ -1188,35 +1188,6 @@ assert (array([[1,2],[3,4]]).prod(0) == [3, 8]).all() assert (array([[1,2],[3,4]]).prod(1) == [2, 12]).all() - def test_eye(self): - from _numpypy import eye - from _numpypy import int32, dtype - a = eye(0) - assert len(a) == 0 - assert a.dtype == dtype('float64') - assert a.shape == (0, 0) - b = eye(1, dtype=int32) - assert len(b) == 1 - assert b[0][0] == 1 - assert b.shape == (1, 1) - assert b.dtype == dtype('int32') - c = eye(2) - assert c.shape == (2, 2) - assert (c == [[1, 0], [0, 1]]).all() - d = eye(3, dtype='int32') - assert d.shape == (3, 3) - assert d.dtype == dtype('int32') - assert (d == [[1, 0, 0], [0, 1, 0], [0, 0, 1]]).all() - e = eye(3, 4) - assert e.shape == (3, 4) - assert (e == [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0]]).all() - f = eye(2, 4, k=3) - assert f.shape == (2, 4) - assert (f == [[0, 0, 0, 1], [0, 0, 0, 0]]).all() - g = eye(3, 4, k=-1) - assert g.shape == (3, 4) - assert (g == [[0, 0, 0, 0], [1, 0, 0, 0], [0, 1, 0, 0]]).all() - def test_prod(self): from _numpypy import array a = array(range(1, 6)) diff --git a/pypy/module/test_lib_pypy/numpypy/lib/test_twodim_base.py b/pypy/module/test_lib_pypy/numpypy/lib/test_twodim_base.py new file mode 100644 --- /dev/null +++ b/pypy/module/test_lib_pypy/numpypy/lib/test_twodim_base.py @@ -0,0 +1,31 @@ +from pypy.module.micronumpy.test.test_base import BaseNumpyAppTest + +class AppTestFunctionBase(BaseNumpyAppTest): + def test_eye(self): + from _numpypy import int32, dtype + from numpypy import eye + a = eye(0) + assert len(a) == 0 + assert a.dtype == dtype('float64') + assert a.shape == (0, 0) + b = eye(1, dtype=int32) + assert len(b) == 1 + assert b[0][0] == 1 + assert b.shape == (1, 1) + assert b.dtype == dtype('int32') + c = eye(2) + assert c.shape == (2, 2) + assert (c == [[1, 0], [0, 1]]).all() + d = eye(3, dtype='int32') + assert d.shape == (3, 3) + assert d.dtype == dtype('int32') + assert (d == [[1, 0, 0], [0, 1, 0], [0, 0, 1]]).all() + e = eye(3, 4) + assert e.shape == (3, 4) + assert (e == [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0]]).all() + f = eye(2, 4, k=3) + assert f.shape == (2, 4) + assert (f == [[0, 0, 0, 1], [0, 0, 0, 0]]).all() + g = eye(3, 4, k=-1) + assert g.shape == (3, 4) + assert (g == [[0, 0, 0, 0], [1, 0, 0, 0], [0, 1, 0, 0]]).all() From noreply at buildbot.pypy.org Sat Feb 23 08:14:13 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sat, 23 Feb 2013 08:14:13 +0100 (CET) Subject: [pypy-commit] pypy default: test and fix for passing out=None to ndarray.clip/choose Message-ID: <20130223071413.3245D1C0327@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61642:34f8c678ef62 Date: 2013-02-23 02:03 -0500 http://bitbucket.org/pypy/pypy/changeset/34f8c678ef62/ Log: test and fix for passing out=None to ndarray.clip/choose diff --git a/pypy/module/micronumpy/interp_numarray.py b/pypy/module/micronumpy/interp_numarray.py --- a/pypy/module/micronumpy/interp_numarray.py +++ b/pypy/module/micronumpy/interp_numarray.py @@ -453,13 +453,13 @@ @unwrap_spec(mode=str) def descr_choose(self, space, w_choices, mode='raise', w_out=None): - if w_out is not None and not isinstance(w_out, W_NDimArray): + if not space.is_none(w_out) and not isinstance(w_out, W_NDimArray): raise OperationError(space.w_TypeError, space.wrap( "return arrays must be of ArrayType")) return interp_arrayops.choose(space, self, w_choices, w_out, mode) def descr_clip(self, space, w_min, w_max, w_out=None): - if w_out is not None and not isinstance(w_out, W_NDimArray): + if not space.is_none(w_out) and not isinstance(w_out, W_NDimArray): raise OperationError(space.w_TypeError, space.wrap( "return arrays must be of ArrayType")) min = convert_to_array(space, w_min) diff --git a/pypy/module/micronumpy/test/test_arrayops.py b/pypy/module/micronumpy/test/test_arrayops.py --- a/pypy/module/micronumpy/test/test_arrayops.py +++ b/pypy/module/micronumpy/test/test_arrayops.py @@ -99,10 +99,13 @@ def test_choose_out(self): from _numpypy import array a, b, c = array([1, 2, 3]), [4, 5, 6], 13 + r = array([2, 1, 0]).choose([a, b, c], out=None) + assert (r == [13, 5, 3]).all() + assert (a == [1, 2, 3]).all() r = array([2, 1, 0]).choose([a, b, c], out=a) assert (r == [13, 5, 3]).all() assert (a == [13, 5, 3]).all() - + def test_choose_modes(self): from _numpypy import array a, b, c = array([1, 2, 3]), [4, 5, 6], 13 diff --git a/pypy/module/micronumpy/test/test_numarray.py b/pypy/module/micronumpy/test/test_numarray.py --- a/pypy/module/micronumpy/test/test_numarray.py +++ b/pypy/module/micronumpy/test/test_numarray.py @@ -1705,7 +1705,8 @@ from _numpypy import array a = array([1, 2, 17, -3, 12]) assert (a.clip(-2, 13) == [1, 2, 13, -2, 12]).all() - assert (a.clip(-1, 1) == [1, 1, 1, -1, 1]).all() + assert (a.clip(-1, 1, out=None) == [1, 1, 1, -1, 1]).all() + assert (a == [1, 2, 17, -3, 12]).all() assert (a.clip(-1, [1, 2, 3, 4, 5]) == [1, 2, 3, -1, 5]).all() assert (a.clip(-2, 13, out=a) == [1, 2, 13, -2, 12]).all() assert (a == [1, 2, 13, -2, 12]).all() From noreply at buildbot.pypy.org Sat Feb 23 08:14:14 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sat, 23 Feb 2013 08:14:14 +0100 (CET) Subject: [pypy-commit] pypy default: enable and test numpypy.clip Message-ID: <20130223071414.69BDD1C0327@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61643:affc77ddf372 Date: 2013-02-23 02:06 -0500 http://bitbucket.org/pypy/pypy/changeset/affc77ddf372/ Log: enable and test numpypy.clip diff --git a/lib_pypy/numpypy/core/fromnumeric.py b/lib_pypy/numpypy/core/fromnumeric.py --- a/lib_pypy/numpypy/core/fromnumeric.py +++ b/lib_pypy/numpypy/core/fromnumeric.py @@ -1290,7 +1290,9 @@ array([3, 4, 2, 3, 4, 5, 6, 7, 8, 8]) """ - raise NotImplementedError('Waiting on interp level method') + if not hasattr(a, 'clip'): + a = numpypy.array(a) + return a.clip(a_min, a_max, out=out) def sum(a, axis=None, dtype=None, out=None): diff --git a/pypy/module/test_lib_pypy/numpypy/core/test_fromnumeric.py b/pypy/module/test_lib_pypy/numpypy/core/test_fromnumeric.py --- a/pypy/module/test_lib_pypy/numpypy/core/test_fromnumeric.py +++ b/pypy/module/test_lib_pypy/numpypy/core/test_fromnumeric.py @@ -34,6 +34,20 @@ # a = array([(1, 2), (3, 4)], dtype=[('x', 'i4'), ('y', 'i4')]) # assert shape(a) == (2,) + def test_clip(self): + import numpypy as np + a = np.arange(10) + b = np.clip(a, 1, 8) + assert (b == [1, 1, 2, 3, 4, 5, 6, 7, 8, 8]).all() + assert (a == [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]).all() + b = np.clip(a, 3, 6, out=a) + assert (b == [3, 3, 3, 3, 4, 5, 6, 6, 6, 6]).all() + assert (a == [3, 3, 3, 3, 4, 5, 6, 6, 6, 6]).all() + a = np.arange(10) + b = np.clip(a, [3,4,1,1,1,4,4,4,4,4], 8) + assert (b == [3, 4, 2, 3, 4, 5, 6, 7, 8, 8]).all() + assert (a == [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]).all() + def test_sum(self): # tests taken from numpy/core/fromnumeric.py docstring from numpypy import array, sum, ones, zeros From noreply at buildbot.pypy.org Sat Feb 23 08:30:12 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Sat, 23 Feb 2013 08:30:12 +0100 (CET) Subject: [pypy-commit] pypy default: some pep8 and dead import cleanups to _cffi_backend Message-ID: <20130223073012.BCB181C008F@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r61644:e921c3cbf287 Date: 2013-02-22 23:27 -0800 http://bitbucket.org/pypy/pypy/changeset/e921c3cbf287/ Log: some pep8 and dead import cleanups to _cffi_backend diff --git a/pypy/module/_cffi_backend/cbuffer.py b/pypy/module/_cffi_backend/cbuffer.py --- a/pypy/module/_cffi_backend/cbuffer.py +++ b/pypy/module/_cffi_backend/cbuffer.py @@ -1,10 +1,11 @@ -from pypy.interpreter.error import operationerrfmt from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.buffer import RWBuffer +from pypy.interpreter.error import operationerrfmt from pypy.interpreter.gateway import unwrap_spec, interp2app from pypy.interpreter.typedef import TypeDef, make_weakref_descr +from pypy.module._cffi_backend import cdataobj, ctypeptr, ctypearray + from rpython.rtyper.lltypesystem import rffi -from pypy.module._cffi_backend import cdataobj, ctypeptr, ctypearray class LLBuffer(RWBuffer): diff --git a/pypy/module/_cffi_backend/ccallback.py b/pypy/module/_cffi_backend/ccallback.py --- a/pypy/module/_cffi_backend/ccallback.py +++ b/pypy/module/_cffi_backend/ccallback.py @@ -2,18 +2,17 @@ Callbacks. """ import os + +from rpython.rlib import clibffi, rweakref, jit +from rpython.rlib.objectmodel import compute_unique_id, keepalive_until_here +from rpython.rtyper.lltypesystem import lltype, rffi + from pypy.interpreter.error import OperationError, operationerrfmt -from rpython.rtyper.lltypesystem import lltype, llmemory, rffi -from rpython.rlib.objectmodel import compute_unique_id, keepalive_until_here -from rpython.rlib import clibffi, rweakref -from rpython.rlib import jit - +from pypy.module._cffi_backend import cerrno, misc from pypy.module._cffi_backend.cdataobj import W_CData -from pypy.module._cffi_backend.ctypefunc import SIZE_OF_FFI_ARG, BIG_ENDIAN -from pypy.module._cffi_backend.ctypefunc import W_CTypeFunc +from pypy.module._cffi_backend.ctypefunc import SIZE_OF_FFI_ARG, BIG_ENDIAN, W_CTypeFunc from pypy.module._cffi_backend.ctypeprim import W_CTypePrimitiveSigned from pypy.module._cffi_backend.ctypevoid import W_CTypeVoid -from pypy.module._cffi_backend import cerrno, misc # ____________________________________________________________ @@ -152,6 +151,7 @@ STDERR = 2 + @jit.jit_callback("CFFI") def invoke_callback(ffi_cif, ll_res, ll_args, ll_userdata): """ Callback specification. diff --git a/pypy/module/_cffi_backend/cdataobj.py b/pypy/module/_cffi_backend/cdataobj.py --- a/pypy/module/_cffi_backend/cdataobj.py +++ b/pypy/module/_cffi_backend/cdataobj.py @@ -1,11 +1,13 @@ import operator + +from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.error import OperationError, operationerrfmt -from pypy.interpreter.baseobjspace import Wrappable -from pypy.interpreter.gateway import interp2app, unwrap_spec +from pypy.interpreter.gateway import interp2app from pypy.interpreter.typedef import TypeDef, make_weakref_descr + +from rpython.rlib import objectmodel, rgc +from rpython.rlib.objectmodel import keepalive_until_here, specialize from rpython.rtyper.lltypesystem import lltype, rffi -from rpython.rlib.objectmodel import keepalive_until_here, specialize -from rpython.rlib import objectmodel, rgc from rpython.tool.sourcetools import func_with_new_name from pypy.module._cffi_backend import misc diff --git a/pypy/module/_cffi_backend/cerrno.py b/pypy/module/_cffi_backend/cerrno.py --- a/pypy/module/_cffi_backend/cerrno.py +++ b/pypy/module/_cffi_backend/cerrno.py @@ -1,5 +1,7 @@ import sys + from rpython.rlib import rposix + from pypy.interpreter.executioncontext import ExecutionContext from pypy.interpreter.gateway import unwrap_spec diff --git a/pypy/module/_cffi_backend/ctypearray.py b/pypy/module/_cffi_backend/ctypearray.py --- a/pypy/module/_cffi_backend/ctypearray.py +++ b/pypy/module/_cffi_backend/ctypearray.py @@ -2,18 +2,17 @@ Arrays. """ +from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.error import OperationError, operationerrfmt -from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.gateway import interp2app from pypy.interpreter.typedef import TypeDef + from rpython.rtyper.lltypesystem import rffi from rpython.rlib.objectmodel import keepalive_until_here from rpython.rlib.rarithmetic import ovfcheck -from pypy.module._cffi_backend.ctypeprim import W_CTypePrimitiveChar -from pypy.module._cffi_backend.ctypeprim import W_CTypePrimitiveUniChar +from pypy.module._cffi_backend import cdataobj from pypy.module._cffi_backend.ctypeptr import W_CTypePtrOrArray -from pypy.module._cffi_backend import cdataobj class W_CTypeArray(W_CTypePtrOrArray): diff --git a/pypy/module/_cffi_backend/ctypeenum.py b/pypy/module/_cffi_backend/ctypeenum.py --- a/pypy/module/_cffi_backend/ctypeenum.py +++ b/pypy/module/_cffi_backend/ctypeenum.py @@ -2,15 +2,11 @@ Enums. """ -from pypy.interpreter.error import OperationError, operationerrfmt -from rpython.rtyper.lltypesystem import rffi -from rpython.rlib.rarithmetic import intmask, r_ulonglong from rpython.rlib.objectmodel import keepalive_until_here -from rpython.rlib.objectmodel import specialize -from pypy.module._cffi_backend.ctypeprim import W_CTypePrimitiveSigned -from pypy.module._cffi_backend.ctypeprim import W_CTypePrimitiveUnsigned from pypy.module._cffi_backend import misc +from pypy.module._cffi_backend.ctypeprim import (W_CTypePrimitiveSigned, + W_CTypePrimitiveUnsigned) class _Mixin_Enum(object): diff --git a/pypy/module/_cffi_backend/ctypefunc.py b/pypy/module/_cffi_backend/ctypefunc.py --- a/pypy/module/_cffi_backend/ctypefunc.py +++ b/pypy/module/_cffi_backend/ctypefunc.py @@ -4,25 +4,21 @@ import sys from pypy.interpreter.error import OperationError, operationerrfmt + +from rpython.rlib import jit, clibffi, jit_libffi +from rpython.rlib.jit_libffi import (CIF_DESCRIPTION, CIF_DESCRIPTION_P, + FFI_TYPE, FFI_TYPE_P, FFI_TYPE_PP, SIZE_OF_FFI_ARG) +from rpython.rlib.objectmodel import we_are_translated, instantiate from rpython.rtyper.lltypesystem import lltype, llmemory, rffi -from rpython.rlib import jit, clibffi, jit_libffi -from rpython.rlib.jit_libffi import CIF_DESCRIPTION, CIF_DESCRIPTION_P -from rpython.rlib.jit_libffi import FFI_TYPE, FFI_TYPE_P, FFI_TYPE_PP -from rpython.rlib.jit_libffi import SIZE_OF_FFI_ARG -from rpython.rlib.objectmodel import we_are_translated, instantiate -from rpython.rlib.objectmodel import keepalive_until_here +from pypy.module._cffi_backend import ctypearray, cdataobj, cerrno from pypy.module._cffi_backend.ctypeobj import W_CType from pypy.module._cffi_backend.ctypeptr import W_CTypePtrBase, W_CTypePointer from pypy.module._cffi_backend.ctypevoid import W_CTypeVoid from pypy.module._cffi_backend.ctypestruct import W_CTypeStruct -from pypy.module._cffi_backend.ctypestruct import W_CTypeStructOrUnion -from pypy.module._cffi_backend.ctypeprim import W_CTypePrimitiveSigned -from pypy.module._cffi_backend.ctypeprim import W_CTypePrimitiveUnsigned -from pypy.module._cffi_backend.ctypeprim import W_CTypePrimitiveCharOrUniChar -from pypy.module._cffi_backend.ctypeprim import W_CTypePrimitiveFloat -from pypy.module._cffi_backend.ctypeprim import W_CTypePrimitiveLongDouble -from pypy.module._cffi_backend import ctypearray, cdataobj, cerrno +from pypy.module._cffi_backend.ctypeprim import (W_CTypePrimitiveSigned, + W_CTypePrimitiveUnsigned, W_CTypePrimitiveCharOrUniChar, + W_CTypePrimitiveFloat, W_CTypePrimitiveLongDouble) class W_CTypeFunc(W_CTypePtrBase): @@ -97,7 +93,6 @@ return self.space.wrap(clibffi.FFI_DEFAULT_ABI) # XXX return W_CTypePtrBase._fget(self, attrchar) - def call(self, funcaddr, args_w): if self.cif_descr: # regular case: this function does not take '...' arguments @@ -270,7 +265,6 @@ self.bufferp = rffi.ptradd(result, size) return result - def fb_fill_type(self, ctype, is_result_type): return ctype._get_ffi_type(self, is_result_type) @@ -357,7 +351,6 @@ return ffistruct - def fb_build(self): # Build a CIF_DESCRIPTION. Actually this computes the size and # allocates a larger amount of data. It starts with a @@ -387,7 +380,6 @@ if self.atypes: self.atypes[i] = atype - def align_arg(self, n): return (n + 7) & ~7 diff --git a/pypy/module/_cffi_backend/ctypeobj.py b/pypy/module/_cffi_backend/ctypeobj.py --- a/pypy/module/_cffi_backend/ctypeobj.py +++ b/pypy/module/_cffi_backend/ctypeobj.py @@ -1,9 +1,8 @@ +from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.error import OperationError, operationerrfmt -from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.gateway import interp2app -from pypy.interpreter.typedef import TypeDef -from pypy.interpreter.typedef import make_weakref_descr -from pypy.interpreter.typedef import GetSetProperty, interp_attrproperty +from pypy.interpreter.typedef import TypeDef, make_weakref_descr, GetSetProperty + from rpython.rtyper.lltypesystem import lltype, llmemory, rffi from rpython.rlib.objectmodel import we_are_translated diff --git a/pypy/module/_cffi_backend/ctypeprim.py b/pypy/module/_cffi_backend/ctypeprim.py --- a/pypy/module/_cffi_backend/ctypeprim.py +++ b/pypy/module/_cffi_backend/ctypeprim.py @@ -3,13 +3,14 @@ """ from pypy.interpreter.error import operationerrfmt -from rpython.rtyper.lltypesystem import lltype, rffi + from rpython.rlib.rarithmetic import r_uint, r_ulonglong, intmask from rpython.rlib.objectmodel import keepalive_until_here from rpython.rlib import jit +from rpython.rtyper.lltypesystem import lltype, rffi +from pypy.module._cffi_backend import cdataobj, misc from pypy.module._cffi_backend.ctypeobj import W_CType -from pypy.module._cffi_backend import cdataobj, misc class W_CTypePrimitive(W_CType): diff --git a/pypy/module/_cffi_backend/ctypeptr.py b/pypy/module/_cffi_backend/ctypeptr.py --- a/pypy/module/_cffi_backend/ctypeptr.py +++ b/pypy/module/_cffi_backend/ctypeptr.py @@ -2,15 +2,15 @@ Pointers. """ -from pypy.interpreter.error import OperationError, operationerrfmt -from pypy.interpreter.error import wrap_oserror -from rpython.rtyper.lltypesystem import lltype, rffi +from pypy.interpreter.error import OperationError, operationerrfmt, wrap_oserror + +from rpython.rlib import rposix from rpython.rlib.objectmodel import keepalive_until_here from rpython.rlib.rarithmetic import ovfcheck -from rpython.rlib import rposix +from rpython.rtyper.lltypesystem import lltype, rffi +from pypy.module._cffi_backend import cdataobj, misc, ctypeprim, ctypevoid from pypy.module._cffi_backend.ctypeobj import W_CType -from pypy.module._cffi_backend import cdataobj, misc, ctypeprim, ctypevoid class W_CTypePtrOrArray(W_CType): @@ -336,19 +336,22 @@ rffi_fdopen = rffi.llexternal("fdopen", [rffi.INT, rffi.CCHARP], rffi.CCHARP) -rffi_setbuf = rffi.llexternal("setbuf", [rffi.CCHARP,rffi.CCHARP], lltype.Void) +rffi_setbuf = rffi.llexternal("setbuf", [rffi.CCHARP, rffi.CCHARP], lltype.Void) rffi_fclose = rffi.llexternal("fclose", [rffi.CCHARP], rffi.INT) class CffiFileObj(object): _immutable_ = True + def __init__(self, fd, mode): self.llf = rffi_fdopen(fd, mode) if not self.llf: raise OSError(rposix.get_errno(), "fdopen failed") rffi_setbuf(self.llf, lltype.nullptr(rffi.CCHARP.TO)) + def close(self): rffi_fclose(self.llf) + def prepare_file_argument(space, fileobj): fileobj.direct_flush() if fileobj.cffi_fileobj is None: diff --git a/pypy/module/_cffi_backend/ctypestruct.py b/pypy/module/_cffi_backend/ctypestruct.py --- a/pypy/module/_cffi_backend/ctypestruct.py +++ b/pypy/module/_cffi_backend/ctypestruct.py @@ -3,15 +3,16 @@ """ from pypy.interpreter.error import OperationError, operationerrfmt -from rpython.rtyper.lltypesystem import lltype, rffi from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.typedef import TypeDef, interp_attrproperty + +from rpython.rlib import jit from rpython.rlib.objectmodel import keepalive_until_here from rpython.rlib.rarithmetic import r_uint, r_ulonglong, r_longlong, intmask -from rpython.rlib import jit +from rpython.rtyper.lltypesystem import rffi +from pypy.module._cffi_backend import cdataobj, ctypeprim, misc from pypy.module._cffi_backend.ctypeobj import W_CType -from pypy.module._cffi_backend import cdataobj, ctypeprim, misc class W_CTypeStructOrUnion(W_CType): @@ -141,6 +142,7 @@ class W_CTypeStruct(W_CTypeStructOrUnion): kind = "struct" + class W_CTypeUnion(W_CTypeStructOrUnion): kind = "union" @@ -241,8 +243,8 @@ # value = misc.as_long_long(space, w_ob) if isinstance(ctype, ctypeprim.W_CTypePrimitiveSigned): - fmin = -(r_longlong(1) << (self.bitsize-1)) - fmax = (r_longlong(1) << (self.bitsize-1)) - 1 + fmin = -(r_longlong(1) << (self.bitsize - 1)) + fmax = (r_longlong(1) << (self.bitsize - 1)) - 1 if fmax == 0: fmax = 1 # special case to let "int x:1" receive "1" else: diff --git a/pypy/module/_cffi_backend/libraryobj.py b/pypy/module/_cffi_backend/libraryobj.py --- a/pypy/module/_cffi_backend/libraryobj.py +++ b/pypy/module/_cffi_backend/libraryobj.py @@ -1,9 +1,11 @@ from __future__ import with_statement -from pypy.interpreter.error import OperationError, operationerrfmt + from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.error import operationerrfmt from pypy.interpreter.gateway import interp2app, unwrap_spec from pypy.interpreter.typedef import TypeDef -from rpython.rtyper.lltypesystem import lltype, rffi + +from rpython.rtyper.lltypesystem import rffi from rpython.rlib.rdynload import DLLHANDLE, dlopen, dlsym, dlclose, DLOpenError from pypy.module._cffi_backend.cdataobj import W_CData diff --git a/pypy/module/_cffi_backend/misc.py b/pypy/module/_cffi_backend/misc.py --- a/pypy/module/_cffi_backend/misc.py +++ b/pypy/module/_cffi_backend/misc.py @@ -1,10 +1,12 @@ from __future__ import with_statement -from pypy.interpreter.error import OperationError, operationerrfmt -from rpython.rtyper.lltypesystem import lltype, llmemory, rffi + +from pypy.interpreter.error import OperationError + +from rpython.rlib import jit +from rpython.rlib.objectmodel import keepalive_until_here, specialize from rpython.rlib.rarithmetic import r_uint, r_ulonglong, is_signed_integer_type from rpython.rlib.unroll import unrolling_iterable -from rpython.rlib.objectmodel import keepalive_until_here, specialize -from rpython.rlib import jit +from rpython.rtyper.lltypesystem import lltype, llmemory, rffi from rpython.translator.tool.cbuild import ExternalCompilationInfo # ____________________________________________________________ @@ -43,14 +45,14 @@ def read_raw_unsigned_data(target, size): for TP, TPP in _prim_unsigned_types: if size == rffi.sizeof(TP): - return rffi.cast(lltype.UnsignedLongLong, rffi.cast(TPP,target)[0]) + return rffi.cast(lltype.UnsignedLongLong, rffi.cast(TPP, target)[0]) raise NotImplementedError("bad integer size") def read_raw_ulong_data(target, size): for TP, TPP in _prim_unsigned_types: if size == rffi.sizeof(TP): assert rffi.sizeof(TP) <= rffi.sizeof(lltype.Unsigned) - return rffi.cast(lltype.Unsigned, rffi.cast(TPP,target)[0]) + return rffi.cast(lltype.Unsigned, rffi.cast(TPP, target)[0]) raise NotImplementedError("bad integer size") def read_raw_float_data(target, size): diff --git a/pypy/module/_cffi_backend/newtype.py b/pypy/module/_cffi_backend/newtype.py --- a/pypy/module/_cffi_backend/newtype.py +++ b/pypy/module/_cffi_backend/newtype.py @@ -1,12 +1,12 @@ from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.gateway import unwrap_spec + +from rpython.rlib.objectmodel import specialize +from rpython.rlib.rarithmetic import ovfcheck from rpython.rtyper.lltypesystem import lltype, rffi -from rpython.rlib.rarithmetic import ovfcheck, r_uint, intmask -from rpython.rlib.rarithmetic import most_neg_value_of, most_pos_value_of -from rpython.rlib.objectmodel import specialize -from pypy.module._cffi_backend import ctypeobj, ctypeprim, ctypeptr, ctypearray -from pypy.module._cffi_backend import ctypestruct, ctypevoid, ctypeenum +from pypy.module._cffi_backend import (ctypeobj, ctypeprim, ctypeptr, + ctypearray, ctypestruct, ctypevoid, ctypeenum) @specialize.memo() @@ -167,7 +167,7 @@ # if foffset < 0: # align this field to its own 'falign' by inserting padding - offset = (offset + falign - 1) & ~(falign-1) + offset = (offset + falign - 1) & ~(falign - 1) else: # a forced field position: ignore the offset just computed, # except to know if we must set 'custom_field_pos' @@ -178,7 +178,7 @@ fbitsize == 8 * ftype.size and not isinstance(ftype, ctypeprim.W_CTypePrimitiveCharOrUniChar)): fbitsize = -1 - if isinstance(ftype, ctypearray.W_CTypeArray) and ftype.length==0: + if isinstance(ftype, ctypearray.W_CTypeArray) and ftype.length == 0: bitshift = ctypestruct.W_CField.BS_EMPTY_ARRAY else: bitshift = ctypestruct.W_CField.BS_REGULAR @@ -241,7 +241,7 @@ # as 1 instead. But for ctypes support, we allow the manually- # specified totalsize to be zero in this case. if totalsize < 0: - offset = (offset + alignment - 1) & ~(alignment-1) + offset = (offset + alignment - 1) & ~(alignment - 1) totalsize = offset or 1 elif totalsize < offset: raise operationerrfmt(space.w_TypeError, From noreply at buildbot.pypy.org Sat Feb 23 08:30:13 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Sat, 23 Feb 2013 08:30:13 +0100 (CET) Subject: [pypy-commit] pypy default: merged upstream Message-ID: <20130223073013.ECC961C008F@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r61645:18b9462c447b Date: 2013-02-22 23:29 -0800 http://bitbucket.org/pypy/pypy/changeset/18b9462c447b/ Log: merged upstream diff --git a/lib_pypy/numpypy/__init__.py b/lib_pypy/numpypy/__init__.py --- a/lib_pypy/numpypy/__init__.py +++ b/lib_pypy/numpypy/__init__.py @@ -1,5 +1,6 @@ from _numpypy import * from .core import * +from .lib import * import _numpypy __all__ = _numpypy.__all__ diff --git a/lib_pypy/numpypy/core/fromnumeric.py b/lib_pypy/numpypy/core/fromnumeric.py --- a/lib_pypy/numpypy/core/fromnumeric.py +++ b/lib_pypy/numpypy/core/fromnumeric.py @@ -1290,7 +1290,9 @@ array([3, 4, 2, 3, 4, 5, 6, 7, 8, 8]) """ - raise NotImplementedError('Waiting on interp level method') + if not hasattr(a, 'clip'): + a = numpypy.array(a) + return a.clip(a_min, a_max, out=out) def sum(a, axis=None, dtype=None, out=None): diff --git a/lib_pypy/numpypy/core/numeric.py b/lib_pypy/numpypy/core/numeric.py --- a/lib_pypy/numpypy/core/numeric.py +++ b/lib_pypy/numpypy/core/numeric.py @@ -501,3 +501,34 @@ a = asarray(a) b = asarray(b) return a.ravel()[:,newaxis]*b.ravel()[newaxis,:] + +def identity(n, dtype=None): + """ + Return the identity array. + + The identity array is a square array with ones on + the main diagonal. + + Parameters + ---------- + n : int + Number of rows (and columns) in `n` x `n` output. + dtype : data-type, optional + Data-type of the output. Defaults to ``float``. + + Returns + ------- + out : ndarray + `n` x `n` array with its main diagonal set to one, + and all other elements 0. + + Examples + -------- + >>> np.identity(3) + array([[ 1., 0., 0.], + [ 0., 1., 0.], + [ 0., 0., 1.]]) + + """ + from numpy import eye + return eye(n, dtype=dtype) diff --git a/lib_pypy/numpypy/lib/__init__.py b/lib_pypy/numpypy/lib/__init__.py new file mode 100644 --- /dev/null +++ b/lib_pypy/numpypy/lib/__init__.py @@ -0,0 +1,2 @@ +from .function_base import * +from .twodim_base import * diff --git a/lib_pypy/numpypy/lib/function_base.py b/lib_pypy/numpypy/lib/function_base.py new file mode 100644 --- /dev/null +++ b/lib_pypy/numpypy/lib/function_base.py @@ -0,0 +1,8 @@ +from _numpypy import array + +def average(a): + # This implements a weighted average, for now we don't implement the + # weighting, just the average part! + if not hasattr(a, "mean"): + a = array(a) + return a.mean() diff --git a/lib_pypy/numpypy/lib/twodim_base.py b/lib_pypy/numpypy/lib/twodim_base.py new file mode 100644 --- /dev/null +++ b/lib_pypy/numpypy/lib/twodim_base.py @@ -0,0 +1,52 @@ +from _numpypy import zeros + +def eye(N, M=None, k=0, dtype=float): + """ + Return a 2-D array with ones on the diagonal and zeros elsewhere. + + Parameters + ---------- + N : int + Number of rows in the output. + M : int, optional + Number of columns in the output. If None, defaults to `N`. + k : int, optional + Index of the diagonal: 0 (the default) refers to the main diagonal, + a positive value refers to an upper diagonal, and a negative value + to a lower diagonal. + dtype : data-type, optional + Data-type of the returned array. + + Returns + ------- + I : ndarray of shape (N,M) + An array where all elements are equal to zero, except for the `k`-th + diagonal, whose values are equal to one. + + See Also + -------- + identity : (almost) equivalent function + diag : diagonal 2-D array from a 1-D array specified by the user. + + Examples + -------- + >>> np.eye(2, dtype=int) + array([[1, 0], + [0, 1]]) + >>> np.eye(3, k=1) + array([[ 0., 1., 0.], + [ 0., 0., 1.], + [ 0., 0., 0.]]) + + """ + if M is None: + M = N + m = zeros((N, M), dtype=dtype) + if k >= M: + return m + if k >= 0: + i = k + else: + i = (-k) * M + m[:M-k].flat[i::M+1] = 1 + return m diff --git a/pypy/module/micronumpy/__init__.py b/pypy/module/micronumpy/__init__.py --- a/pypy/module/micronumpy/__init__.py +++ b/pypy/module/micronumpy/__init__.py @@ -163,9 +163,6 @@ interpleveldefs[exposed] = "interp_ufuncs.get(space).%s" % impl appleveldefs = { - 'average': 'app_numpy.average', - 'identity': 'app_numpy.identity', - 'eye': 'app_numpy.eye', 'arange': 'app_numpy.arange', } def setup_after_space_initialization(self): diff --git a/pypy/module/micronumpy/app_numpy.py b/pypy/module/micronumpy/app_numpy.py --- a/pypy/module/micronumpy/app_numpy.py +++ b/pypy/module/micronumpy/app_numpy.py @@ -2,39 +2,6 @@ import _numpypy -def average(a): - # This implements a weighted average, for now we don't implement the - # weighting, just the average part! - if not hasattr(a, "mean"): - a = _numpypy.array(a) - return a.mean() - -def identity(n, dtype=None): - a = _numpypy.zeros((n, n), dtype=dtype) - for i in range(n): - a[i][i] = 1 - return a - -def eye(n, m=None, k=0, dtype=None): - if m is None: - m = n - a = _numpypy.zeros((n, m), dtype=dtype) - ni = 0 - mi = 0 - - if k < 0: - p = n + k - ni = -k - else: - p = n - k - mi = k - - while ni < n and mi < m: - a[ni][mi] = 1 - ni += 1 - mi += 1 - return a - def arange(start, stop=None, step=1, dtype=None): '''arange([start], stop[, step], dtype=None) Generate values in the half-interval [start, stop). diff --git a/pypy/module/micronumpy/interp_numarray.py b/pypy/module/micronumpy/interp_numarray.py --- a/pypy/module/micronumpy/interp_numarray.py +++ b/pypy/module/micronumpy/interp_numarray.py @@ -453,13 +453,13 @@ @unwrap_spec(mode=str) def descr_choose(self, space, w_choices, mode='raise', w_out=None): - if w_out is not None and not isinstance(w_out, W_NDimArray): + if not space.is_none(w_out) and not isinstance(w_out, W_NDimArray): raise OperationError(space.w_TypeError, space.wrap( "return arrays must be of ArrayType")) return interp_arrayops.choose(space, self, w_choices, w_out, mode) def descr_clip(self, space, w_min, w_max, w_out=None): - if w_out is not None and not isinstance(w_out, W_NDimArray): + if not space.is_none(w_out) and not isinstance(w_out, W_NDimArray): raise OperationError(space.w_TypeError, space.wrap( "return arrays must be of ArrayType")) min = convert_to_array(space, w_min) diff --git a/pypy/module/micronumpy/test/test_arrayops.py b/pypy/module/micronumpy/test/test_arrayops.py --- a/pypy/module/micronumpy/test/test_arrayops.py +++ b/pypy/module/micronumpy/test/test_arrayops.py @@ -99,10 +99,13 @@ def test_choose_out(self): from _numpypy import array a, b, c = array([1, 2, 3]), [4, 5, 6], 13 + r = array([2, 1, 0]).choose([a, b, c], out=None) + assert (r == [13, 5, 3]).all() + assert (a == [1, 2, 3]).all() r = array([2, 1, 0]).choose([a, b, c], out=a) assert (r == [13, 5, 3]).all() assert (a == [13, 5, 3]).all() - + def test_choose_modes(self): from _numpypy import array a, b, c = array([1, 2, 3]), [4, 5, 6], 13 diff --git a/pypy/module/micronumpy/test/test_complex.py b/pypy/module/micronumpy/test/test_complex.py --- a/pypy/module/micronumpy/test/test_complex.py +++ b/pypy/module/micronumpy/test/test_complex.py @@ -382,7 +382,7 @@ def test_conjugate(self): from _numpypy import conj, conjugate, complex128, complex64 - import _numpypy as np + import numpypy as np c0 = complex128(complex(2.5, 0)) c1 = complex64(complex(1, 2)) diff --git a/pypy/module/micronumpy/test/test_module.py b/pypy/module/micronumpy/test/test_module.py deleted file mode 100644 --- a/pypy/module/micronumpy/test/test_module.py +++ /dev/null @@ -1,8 +0,0 @@ -from pypy.module.micronumpy.test.test_base import BaseNumpyAppTest - - -class AppTestNumPyModule(BaseNumpyAppTest): - def test_average(self): - from _numpypy import array, average - assert average(range(10)) == 4.5 - assert average(array(range(10))) == 4.5 diff --git a/pypy/module/micronumpy/test/test_numarray.py b/pypy/module/micronumpy/test/test_numarray.py --- a/pypy/module/micronumpy/test/test_numarray.py +++ b/pypy/module/micronumpy/test/test_numarray.py @@ -1188,55 +1188,6 @@ assert (array([[1,2],[3,4]]).prod(0) == [3, 8]).all() assert (array([[1,2],[3,4]]).prod(1) == [2, 12]).all() - def test_identity(self): - from _numpypy import identity, array - from _numpypy import int32, float64, dtype - a = identity(0) - assert len(a) == 0 - assert a.dtype == dtype('float64') - assert a.shape == (0, 0) - b = identity(1, dtype=int32) - assert len(b) == 1 - assert b[0][0] == 1 - assert b.shape == (1, 1) - assert b.dtype == dtype('int32') - c = identity(2) - assert c.shape == (2, 2) - assert (c == [[1, 0], [0, 1]]).all() - d = identity(3, dtype='int32') - assert d.shape == (3, 3) - assert d.dtype == dtype('int32') - assert (d == [[1, 0, 0], [0, 1, 0], [0, 0, 1]]).all() - - def test_eye(self): - from _numpypy import eye - from _numpypy import int32, dtype - a = eye(0) - assert len(a) == 0 - assert a.dtype == dtype('float64') - assert a.shape == (0, 0) - b = eye(1, dtype=int32) - assert len(b) == 1 - assert b[0][0] == 1 - assert b.shape == (1, 1) - assert b.dtype == dtype('int32') - c = eye(2) - assert c.shape == (2, 2) - assert (c == [[1, 0], [0, 1]]).all() - d = eye(3, dtype='int32') - assert d.shape == (3, 3) - assert d.dtype == dtype('int32') - assert (d == [[1, 0, 0], [0, 1, 0], [0, 0, 1]]).all() - e = eye(3, 4) - assert e.shape == (3, 4) - assert (e == [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0]]).all() - f = eye(2, 4, k=3) - assert f.shape == (2, 4) - assert (f == [[0, 0, 0, 1], [0, 0, 0, 0]]).all() - g = eye(3, 4, k=-1) - assert g.shape == (3, 4) - assert (g == [[0, 0, 0, 0], [1, 0, 0, 0], [0, 1, 0, 0]]).all() - def test_prod(self): from _numpypy import array a = array(range(1, 6)) @@ -1754,7 +1705,8 @@ from _numpypy import array a = array([1, 2, 17, -3, 12]) assert (a.clip(-2, 13) == [1, 2, 13, -2, 12]).all() - assert (a.clip(-1, 1) == [1, 1, 1, -1, 1]).all() + assert (a.clip(-1, 1, out=None) == [1, 1, 1, -1, 1]).all() + assert (a == [1, 2, 17, -3, 12]).all() assert (a.clip(-1, [1, 2, 3, 4, 5]) == [1, 2, 3, -1, 5]).all() assert (a.clip(-2, 13, out=a) == [1, 2, 13, -2, 12]).all() assert (a == [1, 2, 13, -2, 12]).all() diff --git a/pypy/module/test_lib_pypy/numpypy/core/test_fromnumeric.py b/pypy/module/test_lib_pypy/numpypy/core/test_fromnumeric.py --- a/pypy/module/test_lib_pypy/numpypy/core/test_fromnumeric.py +++ b/pypy/module/test_lib_pypy/numpypy/core/test_fromnumeric.py @@ -34,6 +34,20 @@ # a = array([(1, 2), (3, 4)], dtype=[('x', 'i4'), ('y', 'i4')]) # assert shape(a) == (2,) + def test_clip(self): + import numpypy as np + a = np.arange(10) + b = np.clip(a, 1, 8) + assert (b == [1, 1, 2, 3, 4, 5, 6, 7, 8, 8]).all() + assert (a == [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]).all() + b = np.clip(a, 3, 6, out=a) + assert (b == [3, 3, 3, 3, 4, 5, 6, 6, 6, 6]).all() + assert (a == [3, 3, 3, 3, 4, 5, 6, 6, 6, 6]).all() + a = np.arange(10) + b = np.clip(a, [3,4,1,1,1,4,4,4,4,4], 8) + assert (b == [3, 4, 2, 3, 4, 5, 6, 7, 8, 8]).all() + assert (a == [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]).all() + def test_sum(self): # tests taken from numpy/core/fromnumeric.py docstring from numpypy import array, sum, ones, zeros diff --git a/pypy/module/test_lib_pypy/numpypy/core/test_numeric.py b/pypy/module/test_lib_pypy/numpypy/core/test_numeric.py --- a/pypy/module/test_lib_pypy/numpypy/core/test_numeric.py +++ b/pypy/module/test_lib_pypy/numpypy/core/test_numeric.py @@ -20,6 +20,7 @@ assert base_repr(-12, 10, 4) == '-000012' assert base_repr(-12, 4) == '-30' + class AppTestRepr(BaseNumpyAppTest): def test_repr(self): from numpypy import array @@ -146,10 +147,10 @@ def test_equal(self): from _numpypy import array from numpypy import array_equal - + a = [1, 2, 3] b = [1, 2, 3] - + assert array_equal(a, b) assert array_equal(a, array(b)) assert array_equal(array(a), b) @@ -158,10 +159,10 @@ def test_not_equal(self): from _numpypy import array from numpypy import array_equal - + a = [1, 2, 3] b = [1, 2, 4] - + assert not array_equal(a, b) assert not array_equal(a, array(b)) assert not array_equal(array(a), b) @@ -170,17 +171,17 @@ def test_mismatched_shape(self): from _numpypy import array from numpypy import array_equal - + a = [1, 2, 3] b = [[1, 2, 3], [1, 2, 3]] - + assert not array_equal(a, b) assert not array_equal(a, array(b)) assert not array_equal(array(a), b) assert not array_equal(array(a), array(b)) + class AppTestNumeric(BaseNumpyAppTest): - def test_outer(self): from _numpypy import array from numpypy import outer @@ -192,3 +193,22 @@ [12, 15, 18]]) assert (res == expected).all() + def test_identity(self): + from _numpypy import array, int32, float64, dtype + from numpypy import identity + a = identity(0) + assert len(a) == 0 + assert a.dtype == dtype('float64') + assert a.shape == (0, 0) + b = identity(1, dtype=int32) + assert len(b) == 1 + assert b[0][0] == 1 + assert b.shape == (1, 1) + assert b.dtype == dtype('int32') + c = identity(2) + assert c.shape == (2, 2) + assert (c == [[1, 0], [0, 1]]).all() + d = identity(3, dtype='int32') + assert d.shape == (3, 3) + assert d.dtype == dtype('int32') + assert (d == [[1, 0, 0], [0, 1, 0], [0, 0, 1]]).all() diff --git a/pypy/module/test_lib_pypy/numpypy/lib/test_function_base.py b/pypy/module/test_lib_pypy/numpypy/lib/test_function_base.py new file mode 100644 --- /dev/null +++ b/pypy/module/test_lib_pypy/numpypy/lib/test_function_base.py @@ -0,0 +1,7 @@ +from pypy.module.micronumpy.test.test_base import BaseNumpyAppTest + +class AppTestFunctionBase(BaseNumpyAppTest): + def test_average(self): + from numpypy import array, average + assert average(range(10)) == 4.5 + assert average(array(range(10))) == 4.5 diff --git a/pypy/module/test_lib_pypy/numpypy/lib/test_twodim_base.py b/pypy/module/test_lib_pypy/numpypy/lib/test_twodim_base.py new file mode 100644 --- /dev/null +++ b/pypy/module/test_lib_pypy/numpypy/lib/test_twodim_base.py @@ -0,0 +1,31 @@ +from pypy.module.micronumpy.test.test_base import BaseNumpyAppTest + +class AppTestFunctionBase(BaseNumpyAppTest): + def test_eye(self): + from _numpypy import int32, dtype + from numpypy import eye + a = eye(0) + assert len(a) == 0 + assert a.dtype == dtype('float64') + assert a.shape == (0, 0) + b = eye(1, dtype=int32) + assert len(b) == 1 + assert b[0][0] == 1 + assert b.shape == (1, 1) + assert b.dtype == dtype('int32') + c = eye(2) + assert c.shape == (2, 2) + assert (c == [[1, 0], [0, 1]]).all() + d = eye(3, dtype='int32') + assert d.shape == (3, 3) + assert d.dtype == dtype('int32') + assert (d == [[1, 0, 0], [0, 1, 0], [0, 0, 1]]).all() + e = eye(3, 4) + assert e.shape == (3, 4) + assert (e == [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0]]).all() + f = eye(2, 4, k=3) + assert f.shape == (2, 4) + assert (f == [[0, 0, 0, 1], [0, 0, 0, 0]]).all() + g = eye(3, 4, k=-1) + assert g.shape == (3, 4) + assert (g == [[0, 0, 0, 0], [1, 0, 0, 0], [0, 1, 0, 0]]).all() From noreply at buildbot.pypy.org Sat Feb 23 09:25:40 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sat, 23 Feb 2013 09:25:40 +0100 (CET) Subject: [pypy-commit] pypy default: fix translation after 34f8c678ef62 Message-ID: <20130223082540.BE1661C4828@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61647:dc621a04b30d Date: 2013-02-23 03:21 -0500 http://bitbucket.org/pypy/pypy/changeset/dc621a04b30d/ Log: fix translation after 34f8c678ef62 diff --git a/pypy/module/micronumpy/interp_numarray.py b/pypy/module/micronumpy/interp_numarray.py --- a/pypy/module/micronumpy/interp_numarray.py +++ b/pypy/module/micronumpy/interp_numarray.py @@ -453,13 +453,17 @@ @unwrap_spec(mode=str) def descr_choose(self, space, w_choices, mode='raise', w_out=None): - if not space.is_none(w_out) and not isinstance(w_out, W_NDimArray): + if space.is_none(w_out): + w_out = None + elif not isinstance(w_out, W_NDimArray): raise OperationError(space.w_TypeError, space.wrap( "return arrays must be of ArrayType")) return interp_arrayops.choose(space, self, w_choices, w_out, mode) def descr_clip(self, space, w_min, w_max, w_out=None): - if not space.is_none(w_out) and not isinstance(w_out, W_NDimArray): + if space.is_none(w_out): + w_out = None + elif not isinstance(w_out, W_NDimArray): raise OperationError(space.w_TypeError, space.wrap( "return arrays must be of ArrayType")) min = convert_to_array(space, w_min) From noreply at buildbot.pypy.org Sat Feb 23 09:25:39 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sat, 23 Feb 2013 09:25:39 +0100 (CET) Subject: [pypy-commit] pypy default: clean up numpypy __builtin__ aliases Message-ID: <20130223082539.6AAC01C47A9@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61646:247421a6850b Date: 2013-02-23 02:48 -0500 http://bitbucket.org/pypy/pypy/changeset/247421a6850b/ Log: clean up numpypy __builtin__ aliases diff --git a/lib_pypy/numpypy/__init__.py b/lib_pypy/numpypy/__init__.py --- a/lib_pypy/numpypy/__init__.py +++ b/lib_pypy/numpypy/__init__.py @@ -2,6 +2,8 @@ from .core import * from .lib import * +from __builtin__ import bool, int, long, float, complex, object, unicode, str + import _numpypy __all__ = _numpypy.__all__ diff --git a/pypy/module/micronumpy/__init__.py b/pypy/module/micronumpy/__init__.py --- a/pypy/module/micronumpy/__init__.py +++ b/pypy/module/micronumpy/__init__.py @@ -27,9 +27,6 @@ 'True_': 'types.Bool.True', 'False_': 'types.Bool.False', - 'bool': 'space.w_bool', - 'int': 'space.w_int', - 'typeinfo': 'interp_dtype.get_dtype_cache(space).w_typeinfo', 'generic': 'interp_boxes.W_GenericBox', @@ -170,8 +167,6 @@ all_list = sorted(Module.interpleveldefs.keys() + \ Module.appleveldefs.keys()) # found by set(numpypy.__all__) - set(numpy.__all__) - all_list.remove('bool') - all_list.remove('int') all_list.remove('abs') all_list.remove('typeinfo') w_all = space.wrap(all_list) diff --git a/pypy/module/micronumpy/test/test_dtypes.py b/pypy/module/micronumpy/test/test_dtypes.py --- a/pypy/module/micronumpy/test/test_dtypes.py +++ b/pypy/module/micronumpy/test/test_dtypes.py @@ -638,9 +638,6 @@ def test_various_types(self): import _numpypy as numpy - assert numpy.bool is bool - assert numpy.int is int - assert numpy.int16 is numpy.short assert numpy.int8 is numpy.byte assert numpy.bool_ is numpy.bool8 diff --git a/pypy/module/test_lib_pypy/numpypy/test_numpy.py b/pypy/module/test_lib_pypy/numpypy/test_numpy.py --- a/pypy/module/test_lib_pypy/numpypy/test_numpy.py +++ b/pypy/module/test_lib_pypy/numpypy/test_numpy.py @@ -31,3 +31,13 @@ assert max is not __builtin__.max assert min is amin assert max is amax + + def test_builtin_aliases(self): + import __builtin__ + import numpypy + from numpypy import * + + for name in ['bool', 'int', 'long', 'float', 'complex', 'object', + 'unicode', 'str']: + assert name not in locals() + assert getattr(numpypy, name) is getattr(__builtin__, name) From noreply at buildbot.pypy.org Sat Feb 23 10:03:26 2013 From: noreply at buildbot.pypy.org (cfbolz) Date: Sat, 23 Feb 2013 10:03:26 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: don't need two loops Message-ID: <20130223090326.6CC431C0CA3@cobra.cs.uni-duesseldorf.de> Author: Carl Friedrich Bolz Branch: Changeset: r88:021a75dd6522 Date: 2013-02-23 09:39 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/021a75dd6522/ Log: don't need two loops diff --git a/spyvm/interpreter.py b/spyvm/interpreter.py --- a/spyvm/interpreter.py +++ b/spyvm/interpreter.py @@ -112,11 +112,10 @@ assert w_method w_frame = w_method.create_frame(self.space, w_receiver, list(arguments_w)) self.store_w_active_context(w_frame) - while True: - try: - self.loop() - except ReturnFromTopLevel, e: - return e.object + try: + self.loop() + except ReturnFromTopLevel, e: + return e.object class ReturnFromTopLevel(Exception): From noreply at buildbot.pypy.org Sat Feb 23 10:03:27 2013 From: noreply at buildbot.pypy.org (cfbolz) Date: Sat, 23 Feb 2013 10:03:27 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: don't store the current bytecode on the frame anymore Message-ID: <20130223090327.897311C0CA3@cobra.cs.uni-duesseldorf.de> Author: Carl Friedrich Bolz Branch: Changeset: r89:8ad314c5020a Date: 2013-02-23 09:40 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/8ad314c5020a/ Log: don't store the current bytecode on the frame anymore diff --git a/spyvm/interpreter.py b/spyvm/interpreter.py --- a/spyvm/interpreter.py +++ b/spyvm/interpreter.py @@ -65,7 +65,7 @@ """NOT_RPYTHON: only for testing""" if s_active_context is None: # tests only s_active_context = self.s_active_context() - next = s_active_context.getNextBytecode() + next = s_active_context.getbytecode() bytecodeimpl = BYTECODE_TABLE[next] if self.should_trace(): @@ -89,7 +89,7 @@ s_active_context.pc(), next, bytecodeimpl.__name__,) - bytecodeimpl(s_active_context, self) + bytecodeimpl(s_active_context, self, next) def loop(self): while True: @@ -123,7 +123,7 @@ self.object = object def make_call_primitive_bytecode(primitive, selector, argcount): - def callPrimitive(self, interp): + def callPrimitive(self, interp, current_bytecode): # WARNING: this is used for bytecodes for which it is safe to # directly call the primitive. In general, it is not safe: for # example, depending on the type of the receiver, bytecodePrimAt @@ -149,70 +149,70 @@ # __extend__ adds new methods to the ContextPartShadow class class __extend__(ContextPartShadow): # push bytecodes - def pushReceiverVariableBytecode(self, interp): - index = self.currentBytecode & 15 + def pushReceiverVariableBytecode(self, interp, current_bytecode): + index = current_bytecode & 15 self.push(self.w_receiver().fetch(self.space, index)) - def pushTemporaryVariableBytecode(self, interp): - index = self.currentBytecode & 15 + def pushTemporaryVariableBytecode(self, interp, current_bytecode): + index = current_bytecode & 15 self.push(self.gettemp(index)) - def pushLiteralConstantBytecode(self, interp): - index = self.currentBytecode & 31 + def pushLiteralConstantBytecode(self, interp, current_bytecode): + index = current_bytecode & 31 self.push(self.method().getliteral(index)) - def pushLiteralVariableBytecode(self, interp): + def pushLiteralVariableBytecode(self, interp, current_bytecode): # this bytecode assumes that literals[index] is an Association # which is an object with two named vars, and fetches the second # named var (the value). - index = self.currentBytecode & 31 + index = current_bytecode & 31 w_association = self.method().getliteral(index) association = wrapper.AssociationWrapper(self.space, w_association) self.push(association.value()) - def storeAndPopReceiverVariableBytecode(self, interp): - index = self.currentBytecode & 7 + def storeAndPopReceiverVariableBytecode(self, interp, current_bytecode): + index = current_bytecode & 7 self.w_receiver().store(self.space, index, self.pop()) - def storeAndPopTemporaryVariableBytecode(self, interp): - index = self.currentBytecode & 7 + def storeAndPopTemporaryVariableBytecode(self, interp, current_bytecode): + index = current_bytecode & 7 self.settemp(index, self.pop()) # push bytecodes - def pushReceiverBytecode(self, interp): + def pushReceiverBytecode(self, interp, current_bytecode): self.push(self.w_receiver()) - def pushConstantTrueBytecode(self, interp): + def pushConstantTrueBytecode(self, interp, current_bytecode): self.push(interp.space.w_true) - def pushConstantFalseBytecode(self, interp): + def pushConstantFalseBytecode(self, interp, current_bytecode): self.push(interp.space.w_false) - def pushConstantNilBytecode(self, interp): + def pushConstantNilBytecode(self, interp, current_bytecode): self.push(interp.space.w_nil) - def pushConstantMinusOneBytecode(self, interp): + def pushConstantMinusOneBytecode(self, interp, current_bytecode): self.push(interp.space.w_minus_one) - def pushConstantZeroBytecode(self, interp): + def pushConstantZeroBytecode(self, interp, current_bytecode): self.push(interp.space.w_zero) - def pushConstantOneBytecode(self, interp): + def pushConstantOneBytecode(self, interp, current_bytecode): self.push(interp.space.w_one) - def pushConstantTwoBytecode(self, interp): + def pushConstantTwoBytecode(self, interp, current_bytecode): self.push(interp.space.w_two) - def pushActiveContextBytecode(self, interp): + def pushActiveContextBytecode(self, interp, current_bytecode): self.push(self.w_self()) - def duplicateTopBytecode(self, interp): + def duplicateTopBytecode(self, interp, current_bytecode): self.push(self.top()) # send, return bytecodes - def sendLiteralSelectorBytecode(self, interp): - w_selector = self.method().getliteral(self.currentBytecode & 15) - argcount = ((self.currentBytecode >> 4) & 3) - 1 + def sendLiteralSelectorBytecode(self, interp, current_bytecode): + w_selector = self.method().getliteral(current_bytecode & 15) + argcount = ((current_bytecode >> 4) & 3) - 1 self._sendSelfSelector(w_selector, argcount, interp) def _sendSelfSelector(self, w_selector, argcount, interp): @@ -274,25 +274,25 @@ w_return_to.as_context_get_shadow(self.space).push(object) interp.store_w_active_context(w_return_to) - def returnReceiver(self, interp): + def returnReceiver(self, interp, current_bytecode): self._return(self.w_receiver(), interp, self.s_home().w_sender()) - def returnTrue(self, interp): + def returnTrue(self, interp, current_bytecode): self._return(interp.space.w_true, interp, self.s_home().w_sender()) - def returnFalse(self, interp): + def returnFalse(self, interp, current_bytecode): self._return(interp.space.w_false, interp, self.s_home().w_sender()) - def returnNil(self, interp): + def returnNil(self, interp, current_bytecode): self._return(interp.space.w_nil, interp, self.s_home().w_sender()) - def returnTopFromMethod(self, interp): + def returnTopFromMethod(self, interp, current_bytecode): self._return(self.top(), interp, self.s_home().w_sender()) - def returnTopFromBlock(self, interp): + def returnTopFromBlock(self, interp, current_bytecode): self._return(self.top(), interp, self.w_sender()) - def unknownBytecode(self, interp): + def unknownBytecode(self, interp, current_bytecode): raise MissingBytecode("unknownBytecode") def extendedVariableTypeAndIndex(self): @@ -300,7 +300,7 @@ descriptor = self.getbytecode() return ((descriptor >> 6) & 3), (descriptor & 63) - def extendedPushBytecode(self, interp): + def extendedPushBytecode(self, interp, current_bytecode): variableType, variableIndex = self.extendedVariableTypeAndIndex() if variableType == 0: self.push(self.w_receiver().fetch(self.space, variableIndex)) @@ -315,7 +315,7 @@ else: assert 0 - def extendedStoreBytecode(self, interp): + def extendedStoreBytecode(self, interp, current_bytecode): variableType, variableIndex = self.extendedVariableTypeAndIndex() if variableType == 0: self.w_receiver().store(self.space, variableIndex, self.top()) @@ -328,8 +328,8 @@ association = wrapper.AssociationWrapper(self.space, w_association) association.store_value(self.top()) - def extendedStoreAndPopBytecode(self, interp): - self.extendedStoreBytecode(interp) + def extendedStoreAndPopBytecode(self, interp, current_bytecode): + self.extendedStoreBytecode(interp, current_bytecode) self.pop() def getExtendedSelectorArgcount(self): @@ -337,11 +337,11 @@ return ((self.method().getliteral(descriptor & 31)), (descriptor >> 5)) - def singleExtendedSendBytecode(self, interp): + def singleExtendedSendBytecode(self, interp, current_bytecode): w_selector, argcount = self.getExtendedSelectorArgcount() self._sendSelfSelector(w_selector, argcount, interp) - def doubleExtendedDoAnythingBytecode(self, interp): + def doubleExtendedDoAnythingBytecode(self, interp, current_bytecode): second = self.getbytecode() third = self.getbytecode() opType = second >> 5 @@ -373,21 +373,21 @@ association = wrapper.AssociationWrapper(self.space, w_association) association.store_value(self.top()) - def singleExtendedSuperBytecode(self, interp): + def singleExtendedSuperBytecode(self, interp, current_bytecode): w_selector, argcount = self.getExtendedSelectorArgcount() self._sendSuperSelector(w_selector, argcount, interp) - def secondExtendedSendBytecode(self, interp): + def secondExtendedSendBytecode(self, interp, current_bytecode): descriptor = self.getbytecode() w_selector = self.method().getliteral(descriptor & 63) argcount = descriptor >> 6 self._sendSelfSelector(w_selector, argcount, interp) - def popStackBytecode(self, interp): + def popStackBytecode(self, interp, current_bytecode): self.pop() # closure bytecodes - def pushNewArrayBytecode(self, interp): + def pushNewArrayBytecode(self, interp, current_bytecode): arraySize, popIntoArray = splitter[7, 1](self.getbytecode()) newArray = None if popIntoArray == 1: @@ -396,7 +396,7 @@ newArray = interp.space.w_Array.as_class_get_shadow(interp.space).new(arraySize) self.push(newArray) - def experimentalBytecode(self, interp): + def experimentalBytecode(self, interp, current_bytecode): raise MissingBytecode("experimentalBytecode") def _extract_index_and_temps(self): @@ -405,19 +405,19 @@ w_indirectTemps = self.gettemp(index_of_array) return index_in_array, w_indirectTemps - def pushRemoteTempLongBytecode(self, interp): + def pushRemoteTempLongBytecode(self, interp, current_bytecode): index_in_array, w_indirectTemps = self._extract_index_and_temps() self.push(w_indirectTemps.at0(self.space, index_in_array)) - def storeRemoteTempLongBytecode(self, interp): + def storeRemoteTempLongBytecode(self, interp, current_bytecode): index_in_array, w_indirectTemps = self._extract_index_and_temps() w_indirectTemps.atput0(self.space, index_in_array, self.top()) - def storeAndPopRemoteTempLongBytecode(self, interp): + def storeAndPopRemoteTempLongBytecode(self, interp, current_bytecode): index_in_array, w_indirectTemps = self._extract_index_and_temps() w_indirectTemps.atput0(self.space, index_in_array, self.pop()) - def pushClosureCopyCopiedValuesBytecode(self, interp): + def pushClosureCopyCopiedValuesBytecode(self, interp, current_bytecode): """ Copied from Blogpost: http://www.mirandabanda.org/cogblog/2008/07/22/closures-part-ii-the-bytecodes/ ContextPart>>pushClosureCopyNumCopiedValues: numCopied numArgs: numArgs blockSize: blockSize "Simulate the action of a 'closure copy' bytecode whose result is the @@ -453,30 +453,31 @@ self.store_pc(self.pc() + offset) def jumpConditional(self,bool,position): - if self.top() == bool: + if self.top() == bool: # XXX this seems wrong? self.jump(position) self.pop() - def shortJumpPosition(self): - return (self.currentBytecode & 7) + 1 + def shortJumpPosition(self, current_bytecode): + return (current_bytecode & 7) + 1 - def shortUnconditionalJump(self, interp): - self.jump(self.shortJumpPosition()) + def shortUnconditionalJump(self, interp, current_bytecode): + self.jump(self.shortJumpPosition(current_bytecode)) - def shortConditionalJump(self, interp): - self.jumpConditional(interp.space.w_false, self.shortJumpPosition()) + def shortConditionalJump(self, interp, current_bytecode): + self.jumpConditional( + interp.space.w_false, self.shortJumpPosition(current_bytecode)) - def longUnconditionalJump(self, interp): - self.jump((((self.currentBytecode & 7) - 4) << 8) + self.getbytecode()) + def longUnconditionalJump(self, interp, current_bytecode): + self.jump((((current_bytecode & 7) - 4) << 8) + self.getbytecode()) - def longJumpPosition(self): - return ((self.currentBytecode & 3) << 8) + self.getbytecode() + def longJumpPosition(self, current_bytecode): + return ((current_bytecode & 3) << 8) + self.getbytecode() - def longJumpIfTrue(self, interp): - self.jumpConditional(interp.space.w_true, self.longJumpPosition()) + def longJumpIfTrue(self, interp, current_bytecode): + self.jumpConditional(interp.space.w_true, self.longJumpPosition(current_bytecode)) - def longJumpIfFalse(self, interp): - self.jumpConditional(interp.space.w_false, self.longJumpPosition()) + def longJumpIfFalse(self, interp, current_bytecode): + self.jumpConditional(interp.space.w_false, self.longJumpPosition(current_bytecode)) bytecodePrimAdd = make_call_primitive_bytecode(primitives.ADD, "+", 1) @@ -501,34 +502,34 @@ w_selector = self.space.get_special_selector(selector) return self._sendSelfSelector(w_selector, numargs, interp) - def bytecodePrimAt(self, interp): + def bytecodePrimAt(self, interp, current_bytecode): # n.b.: depending on the type of the receiver, this may invoke # primitives.AT, primitives.STRING_AT, or something else for all # I know. self._sendSelfSelectorSpecial("at:", 1, interp) - def bytecodePrimAtPut(self, interp): + def bytecodePrimAtPut(self, interp, current_bytecode): # n.b. as above self._sendSelfSelectorSpecial("at:put:", 2, interp) - def bytecodePrimSize(self, interp): + def bytecodePrimSize(self, interp, current_bytecode): self._sendSelfSelectorSpecial("size", 0, interp) - def bytecodePrimNext(self, interp): + def bytecodePrimNext(self, interp, current_bytecode): self._sendSelfSelectorSpecial("next", 0, interp) - def bytecodePrimNextPut(self, interp): + def bytecodePrimNextPut(self, interp, current_bytecode): self._sendSelfSelectorSpecial("nextPut:", 1, interp) - def bytecodePrimAtEnd(self, interp): + def bytecodePrimAtEnd(self, interp, current_bytecode): self._sendSelfSelectorSpecial("atEnd", 0, interp) - def bytecodePrimEquivalent(self, interp): + def bytecodePrimEquivalent(self, interp, current_bytecode): # short-circuit: classes cannot override the '==' method, # which cannot fail primitives.prim_table[primitives.EQUIVALENT](interp, 1) - def bytecodePrimClass(self, interp): + def bytecodePrimClass(self, interp, current_bytecode): # short-circuit: classes cannot override the 'class' method, # which cannot fail primitives.prim_table[primitives.CLASS](interp, 0) @@ -538,19 +539,19 @@ bytecodePrimValue = make_call_primitive_bytecode(primitives.VALUE, "value", 0) bytecodePrimValueWithArg = make_call_primitive_bytecode(primitives.VALUE, "value:", 1) - def bytecodePrimDo(self, interp): + def bytecodePrimDo(self, interp, current_bytecode): self._sendSelfSelectorSpecial("do:", 1, interp) - def bytecodePrimNew(self, interp): + def bytecodePrimNew(self, interp, current_bytecode): self._sendSelfSelectorSpecial("new", 0, interp) - def bytecodePrimNewWithArg(self, interp): + def bytecodePrimNewWithArg(self, interp, current_bytecode): self._sendSelfSelectorSpecial("new:", 1, interp) - def bytecodePrimPointX(self, interp): + def bytecodePrimPointX(self, interp, current_bytecode): self._sendSelfSelectorSpecial("x", 0, interp) - def bytecodePrimPointY(self, interp): + def bytecodePrimPointY(self, interp, current_bytecode): self._sendSelfSelectorSpecial("y", 0, interp) BYTECODE_RANGES = [ @@ -669,7 +670,7 @@ # list lookup and an indirect call but as a switch. code = ["def bytecode_step_translated(self, context):"] - code.append(" bytecode = context.getNextBytecode()") + code.append(" bytecode = context.getbytecode()") prefix = "" for entry in BYTECODE_RANGES: if len(entry) == 2: @@ -679,7 +680,7 @@ cond = " or ".join(["bytecode == %s" % (i, ) for i in numbers]) code.append(" %sif %s:" % (prefix, cond, )) - code.append(" context.%s(self)" % (entry[-1], )) + code.append(" context.%s(self, bytecode)" % (entry[-1], )) prefix = "el" code.append("bytecode_step_translated._always_inline_ = True") source = py.code.Source("\n".join(code)) diff --git a/spyvm/shadow.py b/spyvm/shadow.py --- a/spyvm/shadow.py +++ b/spyvm/shadow.py @@ -320,7 +320,6 @@ def __init__(self, space, w_self): self._w_sender = space.w_nil - self.currentBytecode = -1 AbstractRedirectingShadow.__init__(self, space, w_self) @@ -459,10 +458,6 @@ self._pc += 1 return currentBytecode - def getNextBytecode(self): - self.currentBytecode = self.getbytecode() - return self.currentBytecode - # ______________________________________________________________________ # Temporary Variables # diff --git a/spyvm/test/test_interpreter.py b/spyvm/test/test_interpreter.py --- a/spyvm/test/test_interpreter.py +++ b/spyvm/test/test_interpreter.py @@ -103,9 +103,9 @@ assert s_frame.gettemp(2) is space.w_nil s_frame.settemp(2, "spam") assert s_frame.gettemp(2) == "spam" - assert s_frame.getNextBytecode() == ord("h") - assert s_frame.getNextBytecode() == ord("e") - assert s_frame.getNextBytecode() == ord("l") + assert s_frame.getbytecode() == ord("h") + assert s_frame.getbytecode() == ord("e") + assert s_frame.getbytecode() == ord("l") def test_push_pop(): interp = new_interpreter("") From noreply at buildbot.pypy.org Sat Feb 23 10:03:28 2013 From: noreply at buildbot.pypy.org (cfbolz) Date: Sat, 23 Feb 2013 10:03:28 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: don't JIT asSymbol Message-ID: <20130223090328.AC13C1C0CA3@cobra.cs.uni-duesseldorf.de> Author: Carl Friedrich Bolz Branch: Changeset: r90:2ec11c7e3be3 Date: 2013-02-23 09:41 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/2ec11c7e3be3/ Log: don't JIT asSymbol diff --git a/spyvm/test/jit.py b/spyvm/test/jit.py --- a/spyvm/test/jit.py +++ b/spyvm/test/jit.py @@ -60,9 +60,14 @@ counter = 0 + w_selector = interp.perform(space.wrap_string("loopTest"), "asSymbol") + w_object = model.W_SmallInteger(0) + s_class = w_object.shadow_of_my_class(space) + w_method = s_class.lookup(w_selector) + w_frame = w_method.create_frame(space, w_object, []) + interp.store_w_active_context(w_frame) + def interp_w(): - - w_object = model.W_SmallInteger(0) - interp.perform(w_object, "loopTest") + interp.loop() self.meta_interp(interp_w, [], listcomp=True, listops=True, backendopt=True) From noreply at buildbot.pypy.org Sat Feb 23 10:03:29 2013 From: noreply at buildbot.pypy.org (cfbolz) Date: Sat, 23 Feb 2013 10:03:29 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: change AbstractCachingShadow to simply create a new shadow instead of updating Message-ID: <20130223090329.BF6ED1C0CA3@cobra.cs.uni-duesseldorf.de> Author: Carl Friedrich Bolz Branch: Changeset: r91:7f7dc5c5b8e8 Date: 2013-02-23 09:45 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/7f7dc5c5b8e8/ Log: change AbstractCachingShadow to simply create a new shadow instead of updating the old one. This makes it possible to make these shadows immutable. diff --git a/spyvm/model.py b/spyvm/model.py --- a/spyvm/model.py +++ b/spyvm/model.py @@ -18,7 +18,7 @@ from spyvm.tool.bitmanipulation import splitter from spyvm import constants, error -from rpython.rlib import rrandom, objectmodel +from rpython.rlib import rrandom, objectmodel, jit from rpython.rlib.rarithmetic import intmask, r_uint from rpython.tool.pairtype import extendabletype from rpython.rlib.objectmodel import instantiate @@ -321,7 +321,7 @@ def as_class_get_shadow(self, space): from spyvm.shadow import ClassShadow - return self.as_special_get_shadow(space, ClassShadow) + return jit.promote(self.as_special_get_shadow(space, ClassShadow)) def as_blockcontext_get_shadow(self, space): from spyvm.shadow import BlockContextShadow diff --git a/spyvm/shadow.py b/spyvm/shadow.py --- a/spyvm/shadow.py +++ b/spyvm/shadow.py @@ -27,8 +27,6 @@ class AbstractCachingShadow(AbstractShadow): def __init__(self, space, w_self): AbstractShadow.__init__(self, space, w_self) - self.invalid = True - self.invalidate_shadow() def detach_shadow(self): self.invalidate_shadow() @@ -36,19 +34,16 @@ def invalidate_shadow(self): """This should get called whenever the base Smalltalk object changes.""" - if not self.invalid: - self.invalid = True + self._w_self.store_shadow(None) def attach_shadow(self): self.update_shadow() def sync_shadow(self): - if self.invalid: - self.update_shadow() + pass def update_shadow(self): self.w_self().store_shadow(self) - self.invalid = False self.sync_cache() def sync_cache(self): @@ -77,14 +72,13 @@ """A shadow for Smalltalk objects that are classes (i.e. used as the class of another Smalltalk object). """ + + _immutable_fields_ = ["name", "instance_size", "instance_varsized", "instance_kind", "w_methoddict", "s_methoddict", "w_superclass"] + name = None def __init__(self, space, w_self): self.name = "" AbstractCachingShadow.__init__(self, space, w_self) - def invalidate_shadow(self): - AbstractCachingShadow.invalidate_shadow(self) - self.w_methoddict = None - self.w_superclass = None def getname(self): return "%s class" % (self.name or '?',) @@ -235,11 +229,10 @@ def lookup(self, w_selector): look_in_shadow = self while look_in_shadow is not None: - try: - w_method = look_in_shadow.s_methoddict().methoddict[w_selector] + w_method = look_in_shadow.s_methoddict().find_selector(w_selector) + if w_method is not None: return w_method - except KeyError, e: - look_in_shadow = look_in_shadow.s_superclass() + look_in_shadow = look_in_shadow.s_superclass() raise MethodNotFound(self, w_selector) def initialize_methoddict(self): @@ -260,9 +253,9 @@ class MethodDictionaryShadow(AbstractCachingShadow): - def invalidate_shadow(self): - AbstractCachingShadow.invalidate_shadow(self) - self.methoddict = None + @jit.elidable + def find_selector(self, w_selector): + return self.methoddict.get(w_selector, None) def sync_cache(self): w_values = self.w_self()._fetch(constants.METHODDICT_VALUES_INDEX) diff --git a/spyvm/test/test_shadow.py b/spyvm/test/test_shadow.py --- a/spyvm/test/test_shadow.py +++ b/spyvm/test/test_shadow.py @@ -178,9 +178,7 @@ s_object.detach_shadow() s_classshadow = shadow.ClassShadow(space, w_object) w_object._shadow = s_classshadow - s_classshadow.invalid = False s_newobject = w_object.as_blockcontext_get_shadow(space) - assert s_classshadow.invalid assert ([s_newobject.fetch(i) for i in range(s_newobject.size())] == [s_object.fetch(i) for i in range(s_newobject.size())]) assert w_object._shadow is s_newobject From noreply at buildbot.pypy.org Sat Feb 23 10:17:46 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sat, 23 Feb 2013 10:17:46 +0100 (CET) Subject: [pypy-commit] pypy default: clean up numpypy imports/__all__ Message-ID: <20130223091746.5C9B81C0327@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61648:5187fcde6e20 Date: 2013-02-23 04:16 -0500 http://bitbucket.org/pypy/pypy/changeset/5187fcde6e20/ Log: clean up numpypy imports/__all__ diff --git a/lib_pypy/numpypy/__init__.py b/lib_pypy/numpypy/__init__.py --- a/lib_pypy/numpypy/__init__.py +++ b/lib_pypy/numpypy/__init__.py @@ -1,11 +1,14 @@ -from _numpypy import * -from .core import * -from .lib import * +import core +from core import * +import lib +from lib import * from __builtin__ import bool, int, long, float, complex, object, unicode, str +from core import abs, max, min -import _numpypy -__all__ = _numpypy.__all__ +__all__ = [] +__all__ += core.__all__ +__all__ += lib.__all__ import sys sys.modules.setdefault('numpy', sys.modules['numpypy']) diff --git a/lib_pypy/numpypy/core/__init__.py b/lib_pypy/numpypy/core/__init__.py --- a/lib_pypy/numpypy/core/__init__.py +++ b/lib_pypy/numpypy/core/__init__.py @@ -1,6 +1,17 @@ -from .fromnumeric import * -from .numeric import * -from .shape_base import * +import _numpypy +from _numpypy import * +import numeric +from numeric import * +import fromnumeric +from fromnumeric import * +import shape_base +from shape_base import * -from _numpypy import abs -from .fromnumeric import amax as max, amin as min +from fromnumeric import amax as max, amin as min +from _numpypy import absolute as abs + +__all__ = [] +__all__ += _numpypy.__all__ +__all__ += numeric.__all__ +__all__ += fromnumeric.__all__ +__all__ += shape_base.__all__ diff --git a/lib_pypy/numpypy/core/numeric.py b/lib_pypy/numpypy/core/numeric.py --- a/lib_pypy/numpypy/core/numeric.py +++ b/lib_pypy/numpypy/core/numeric.py @@ -1,3 +1,6 @@ +__all__ = ['asanyarray', 'base_repr', + 'array_repr', 'array_str', 'set_string_function', + 'array_equal', 'asarray', 'outer', 'identity'] from _numpypy import array, ndarray, int_, float_, bool_, flexible #, complex_# , longlong from _numpypy import concatenate diff --git a/lib_pypy/numpypy/core/shape_base.py b/lib_pypy/numpypy/core/shape_base.py --- a/lib_pypy/numpypy/core/shape_base.py +++ b/lib_pypy/numpypy/core/shape_base.py @@ -1,3 +1,5 @@ +__all__ = ['atleast_1d', 'atleast_2d', 'atleast_3d', 'vstack', 'hstack', 'dstack'] + import _numpypy from numeric import array, asanyarray, newaxis diff --git a/lib_pypy/numpypy/lib/__init__.py b/lib_pypy/numpypy/lib/__init__.py --- a/lib_pypy/numpypy/lib/__init__.py +++ b/lib_pypy/numpypy/lib/__init__.py @@ -1,2 +1,8 @@ -from .function_base import * -from .twodim_base import * +import function_base +from function_base import * +import twodim_base +from twodim_base import * + +__all__ = [] +__all__ += function_base.__all__ +__all__ += twodim_base.__all__ diff --git a/lib_pypy/numpypy/lib/function_base.py b/lib_pypy/numpypy/lib/function_base.py --- a/lib_pypy/numpypy/lib/function_base.py +++ b/lib_pypy/numpypy/lib/function_base.py @@ -1,3 +1,5 @@ +__all__ = ['average'] + from _numpypy import array def average(a): diff --git a/lib_pypy/numpypy/lib/twodim_base.py b/lib_pypy/numpypy/lib/twodim_base.py --- a/lib_pypy/numpypy/lib/twodim_base.py +++ b/lib_pypy/numpypy/lib/twodim_base.py @@ -1,3 +1,5 @@ +__all__ = ['eye'] + from _numpypy import zeros def eye(N, M=None, k=0, dtype=float): diff --git a/pypy/module/micronumpy/__init__.py b/pypy/module/micronumpy/__init__.py --- a/pypy/module/micronumpy/__init__.py +++ b/pypy/module/micronumpy/__init__.py @@ -79,7 +79,6 @@ # ufuncs for exposed, impl in [ - ("abs", "absolute"), ("absolute", "absolute"), ("add", "add"), ("arccos", "arccos"), @@ -167,7 +166,6 @@ all_list = sorted(Module.interpleveldefs.keys() + \ Module.appleveldefs.keys()) # found by set(numpypy.__all__) - set(numpy.__all__) - all_list.remove('abs') all_list.remove('typeinfo') w_all = space.wrap(all_list) space.setitem(self.w_dict, space.new_interned_str('__all__'), w_all) diff --git a/pypy/module/micronumpy/test/test_complex.py b/pypy/module/micronumpy/test/test_complex.py --- a/pypy/module/micronumpy/test/test_complex.py +++ b/pypy/module/micronumpy/test/test_complex.py @@ -495,8 +495,8 @@ def test_basic(self): from _numpypy import (complex128, complex64, add, array, dtype, - subtract as sub, multiply, divide, negative, abs, floor_divide, - real, imag, sign, clongfloat) + subtract as sub, multiply, divide, negative, absolute as abs, + floor_divide, real, imag, sign, clongfloat) from _numpypy import (equal, not_equal, greater, greater_equal, less, less_equal, isnan) assert real(4.0) == 4.0 From noreply at buildbot.pypy.org Sat Feb 23 10:29:21 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sat, 23 Feb 2013 10:29:21 +0100 (CET) Subject: [pypy-commit] pypy default: name this test class correctly Message-ID: <20130223092921.28E771C008F@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61649:8f07112d9aa4 Date: 2013-02-23 04:27 -0500 http://bitbucket.org/pypy/pypy/changeset/8f07112d9aa4/ Log: name this test class correctly diff --git a/pypy/module/test_lib_pypy/numpypy/lib/test_twodim_base.py b/pypy/module/test_lib_pypy/numpypy/lib/test_twodim_base.py --- a/pypy/module/test_lib_pypy/numpypy/lib/test_twodim_base.py +++ b/pypy/module/test_lib_pypy/numpypy/lib/test_twodim_base.py @@ -1,6 +1,6 @@ from pypy.module.micronumpy.test.test_base import BaseNumpyAppTest -class AppTestFunctionBase(BaseNumpyAppTest): +class AppTestTwoDimBase(BaseNumpyAppTest): def test_eye(self): from _numpypy import int32, dtype from numpypy import eye From noreply at buildbot.pypy.org Sat Feb 23 10:44:48 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sat, 23 Feb 2013 10:44:48 +0100 (CET) Subject: [pypy-commit] pypy default: move dstack where it is upstream Message-ID: <20130223094448.E31D41C0327@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61650:123c142f665f Date: 2013-02-23 04:30 -0500 http://bitbucket.org/pypy/pypy/changeset/123c142f665f/ Log: move dstack where it is upstream diff --git a/lib_pypy/numpypy/core/shape_base.py b/lib_pypy/numpypy/core/shape_base.py --- a/lib_pypy/numpypy/core/shape_base.py +++ b/lib_pypy/numpypy/core/shape_base.py @@ -1,4 +1,4 @@ -__all__ = ['atleast_1d', 'atleast_2d', 'atleast_3d', 'vstack', 'hstack', 'dstack'] +__all__ = ['atleast_1d', 'atleast_2d', 'atleast_3d', 'vstack', 'hstack'] import _numpypy from numeric import array, asanyarray, newaxis @@ -273,53 +273,3 @@ return _numpypy.concatenate(arrs, 0) else: return _numpypy.concatenate(arrs, 1) - -def dstack(tup): - """ - Stack arrays in sequence depth wise (along third axis). - - Takes a sequence of arrays and stack them along the third axis - to make a single array. Rebuilds arrays divided by `dsplit`. - This is a simple way to stack 2D arrays (images) into a single - 3D array for processing. - - Parameters - ---------- - tup : sequence of arrays - Arrays to stack. All of them must have the same shape along all - but the third axis. - - Returns - ------- - stacked : ndarray - The array formed by stacking the given arrays. - - See Also - -------- - vstack : Stack along first axis. - hstack : Stack along second axis. - concatenate : Join arrays. - dsplit : Split array along third axis. - - Notes - ----- - Equivalent to ``np.concatenate(tup, axis=2)``. - - Examples - -------- - >>> a = np.array((1,2,3)) - >>> b = np.array((2,3,4)) - >>> np.dstack((a,b)) - array([[[1, 2], - [2, 3], - [3, 4]]]) - - >>> a = np.array([[1],[2],[3]]) - >>> b = np.array([[2],[3],[4]]) - >>> np.dstack((a,b)) - array([[[1, 2]], - [[2, 3]], - [[3, 4]]]) - - """ - return _numpypy.concatenate(map(atleast_3d,tup),2) diff --git a/lib_pypy/numpypy/lib/__init__.py b/lib_pypy/numpypy/lib/__init__.py --- a/lib_pypy/numpypy/lib/__init__.py +++ b/lib_pypy/numpypy/lib/__init__.py @@ -1,8 +1,11 @@ import function_base from function_base import * +import shape_base +from shape_base import * import twodim_base from twodim_base import * __all__ = [] __all__ += function_base.__all__ +__all__ += shape_base.__all__ __all__ += twodim_base.__all__ diff --git a/lib_pypy/numpypy/lib/shape_base.py b/lib_pypy/numpypy/lib/shape_base.py new file mode 100644 --- /dev/null +++ b/lib_pypy/numpypy/lib/shape_base.py @@ -0,0 +1,54 @@ +__all__ = ['dstack'] + +import numpypy.core.numeric as _nx +from numpypy.core import atleast_3d + +def dstack(tup): + """ + Stack arrays in sequence depth wise (along third axis). + + Takes a sequence of arrays and stack them along the third axis + to make a single array. Rebuilds arrays divided by `dsplit`. + This is a simple way to stack 2D arrays (images) into a single + 3D array for processing. + + Parameters + ---------- + tup : sequence of arrays + Arrays to stack. All of them must have the same shape along all + but the third axis. + + Returns + ------- + stacked : ndarray + The array formed by stacking the given arrays. + + See Also + -------- + vstack : Stack along first axis. + hstack : Stack along second axis. + concatenate : Join arrays. + dsplit : Split array along third axis. + + Notes + ----- + Equivalent to ``np.concatenate(tup, axis=2)``. + + Examples + -------- + >>> a = np.array((1,2,3)) + >>> b = np.array((2,3,4)) + >>> np.dstack((a,b)) + array([[[1, 2], + [2, 3], + [3, 4]]]) + + >>> a = np.array([[1],[2],[3]]) + >>> b = np.array([[2],[3],[4]]) + >>> np.dstack((a,b)) + array([[[1, 2]], + [[2, 3]], + [[3, 4]]]) + + """ + return _nx.concatenate(map(atleast_3d,tup),2) diff --git a/pypy/module/test_lib_pypy/numpypy/core/test_shape_base.py b/pypy/module/test_lib_pypy/numpypy/core/test_shape_base.py --- a/pypy/module/test_lib_pypy/numpypy/core/test_shape_base.py +++ b/pypy/module/test_lib_pypy/numpypy/core/test_shape_base.py @@ -129,35 +129,3 @@ np.ones((a.shape[0], a.shape[1] + b.shape[1], a.shape[2]))) - - def test_dstack(self): - import numpypy as np - a = np.array((1, 2, 3)) - b = np.array((2, 3, 4)) - c = np.dstack((a, b)) - assert np.array_equal(c, [[[1, 2], [2, 3], [3, 4]]]) - - a = np.array([[1], [2], [3]]) - b = np.array([[2], [3], [4]]) - c = np.dstack((a, b)) - assert np.array_equal(c, [[[1, 2]], [[2, 3]], [[3, 4]]]) - - #skip("https://bugs.pypy.org/issue1394") - for shape1, shape2 in [[(4, 2, 3), (4, 2, 7)], - [(7, 2, 0), (7, 2, 10)], - [(7, 2, 0), (7, 2, 0)]]: - a, b = np.ones(shape1), np.ones(shape2) - assert np.all(np.dstack((a, b)) == - np.ones((a.shape[0], - a.shape[1], - a.shape[2] + b.shape[2]))) - - for shape1, shape2 in [[(4, 2, 3, 5), (4, 2, 7, 5)], - [(7, 2, 0, 5), (7, 2, 10, 5)], - [(7, 2, 0, 5), (7, 2, 0, 5)]]: - a, b = np.ones(shape1), np.ones(shape2) - assert np.all(np.dstack((a, b)) == - np.ones((a.shape[0], - a.shape[1], - a.shape[2] + b.shape[2], - a.shape[3]))) diff --git a/pypy/module/test_lib_pypy/numpypy/lib/test_shape_base_lib.py b/pypy/module/test_lib_pypy/numpypy/lib/test_shape_base_lib.py new file mode 100644 --- /dev/null +++ b/pypy/module/test_lib_pypy/numpypy/lib/test_shape_base_lib.py @@ -0,0 +1,34 @@ +from pypy.module.micronumpy.test.test_base import BaseNumpyAppTest + +class AppTestShapeBase(BaseNumpyAppTest): + def test_dstack(self): + import numpypy as np + a = np.array((1, 2, 3)) + b = np.array((2, 3, 4)) + c = np.dstack((a, b)) + assert np.array_equal(c, [[[1, 2], [2, 3], [3, 4]]]) + + a = np.array([[1], [2], [3]]) + b = np.array([[2], [3], [4]]) + c = np.dstack((a, b)) + assert np.array_equal(c, [[[1, 2]], [[2, 3]], [[3, 4]]]) + + #skip("https://bugs.pypy.org/issue1394") + for shape1, shape2 in [[(4, 2, 3), (4, 2, 7)], + [(7, 2, 0), (7, 2, 10)], + [(7, 2, 0), (7, 2, 0)]]: + a, b = np.ones(shape1), np.ones(shape2) + assert np.all(np.dstack((a, b)) == + np.ones((a.shape[0], + a.shape[1], + a.shape[2] + b.shape[2]))) + + for shape1, shape2 in [[(4, 2, 3, 5), (4, 2, 7, 5)], + [(7, 2, 0, 5), (7, 2, 10, 5)], + [(7, 2, 0, 5), (7, 2, 0, 5)]]: + a, b = np.ones(shape1), np.ones(shape2) + assert np.all(np.dstack((a, b)) == + np.ones((a.shape[0], + a.shape[1], + a.shape[2] + b.shape[2], + a.shape[3]))) From noreply at buildbot.pypy.org Sat Feb 23 11:04:31 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sat, 23 Feb 2013 11:04:31 +0100 (CET) Subject: [pypy-commit] pypy stm-thread-2: Kill an old, unused list. Message-ID: <20130223100431.A8B0C1C0327@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stm-thread-2 Changeset: r61651:fe27582d1791 Date: 2013-02-23 09:40 +0100 http://bitbucket.org/pypy/pypy/changeset/fe27582d1791/ Log: Kill an old, unused list. diff --git a/rpython/rtyper/memory/gc/stmgc.py b/rpython/rtyper/memory/gc/stmgc.py --- a/rpython/rtyper/memory/gc/stmgc.py +++ b/rpython/rtyper/memory/gc/stmgc.py @@ -321,7 +321,6 @@ tls = self.get_tls() try: localobj = tls.duplicate_obj(obj, self.get_size(obj)) - tls.copied_local_objects.append(localobj) # XXX KILL except MemoryError: # should not really let the exception propagate. # XXX do something slightly better, like abort the transaction diff --git a/rpython/rtyper/memory/gc/stmtls.py b/rpython/rtyper/memory/gc/stmtls.py --- a/rpython/rtyper/memory/gc/stmtls.py +++ b/rpython/rtyper/memory/gc/stmtls.py @@ -51,7 +51,6 @@ # --- a thread-local allocator for the shared area from rpython.rtyper.memory.gc.stmshared import StmGCThreadLocalAllocator self.sharedarea_tls = StmGCThreadLocalAllocator(self.gc.sharedarea) - self.copied_local_objects = self.AddressStack() # XXX KILL # --- the LOCAL objects which are weakrefs. They are also listed # in the appropriate place, like sharedarea_tls, if needed. self.local_weakrefs = self.AddressStack() @@ -63,7 +62,6 @@ self._cleanup_state() self._unregister_with_C_code() self.local_weakrefs.delete() - self.copied_local_objects.delete() self.sharedarea_tls.delete() self._free_nursery(self.nursery_start) free_non_gc_object(self) @@ -290,8 +288,6 @@ ll_assert(hdr.tid & GCFLAG_LOCAL_COPY == 0,"already LOCAL_COPY [1]") hdr.tid |= GCFLAG_GLOBAL | GCFLAG_NOT_WRITTEN self._clear_revision_for_global_object(hdr) - # - self.copied_local_objects.clear() def _clear_revision_for_global_object(self, hdr): # Reset the 'revision' to initialize a newly global object. @@ -310,8 +306,6 @@ # free the old unused local objects still allocated in the # StmGCThreadLocalAllocator self.sharedarea_tls.free_and_clear() - # free these ones too - self.sharedarea_tls.free_and_clear_list(self.copied_local_objects) # forget the local weakrefs. self.local_weakrefs.clear() From noreply at buildbot.pypy.org Sat Feb 23 11:04:33 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sat, 23 Feb 2013 11:04:33 +0100 (CET) Subject: [pypy-commit] pypy default: Move the 'rpython.rtyper.memory' subpackage to simply 'rpython.memory'. Message-ID: <20130223100433.3682E1C0327@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r61652:99168b9efe53 Date: 2013-02-23 11:04 +0100 http://bitbucket.org/pypy/pypy/changeset/99168b9efe53/ Log: Move the 'rpython.rtyper.memory' subpackage to simply 'rpython.memory'. diff --git a/pypy/doc/garbage_collection.rst b/pypy/doc/garbage_collection.rst --- a/pypy/doc/garbage_collection.rst +++ b/pypy/doc/garbage_collection.rst @@ -42,7 +42,7 @@ Two arenas of equal size, with only one arena in use and getting filled with new objects. When the arena is full, the live objects are copied into the other arena using Cheney's algorithm. The old arena is then -cleared. See `rpython/rtyper/memory/gc/semispace.py`_. +cleared. See `rpython/memory/gc/semispace.py`_. On Unix the clearing is done by reading ``/dev/zero`` into the arena, which is extremely memory efficient at least on Linux: it lets the @@ -55,7 +55,7 @@ Generational GC --------------- -This is a two-generations GC. See `rpython/rtyper/memory/gc/generation.py`_. +This is a two-generations GC. See `rpython/memory/gc/generation.py`_. It is implemented as a subclass of the Semispace copying collector. It adds a nursery, which is a chunk of the current semispace. Its size is @@ -86,7 +86,7 @@ Each generation is collected much less often than the previous one. The division of the generations is slightly more complicated than just nursery / semispace / external; see the diagram at the start of the -source code, in `rpython/rtyper/memory/gc/hybrid.py`_. +source code, in `rpython/memory/gc/hybrid.py`_. Mark & Compact GC ----------------- @@ -161,7 +161,7 @@ to the old stage. The dying case 2 objects are immediately freed. - The old stage is an area of memory containing old (small) objects. It - is handled by `rpython/rtyper/memory/gc/minimarkpage.py`_. It is organized + is handled by `rpython/memory/gc/minimarkpage.py`_. It is organized as "arenas" of 256KB or 512KB, subdivided into "pages" of 4KB or 8KB. Each page can either be free, or contain small objects of all the same size. Furthermore at any point in time each object location can be diff --git a/pypy/doc/index.rst b/pypy/doc/index.rst --- a/pypy/doc/index.rst +++ b/pypy/doc/index.rst @@ -286,7 +286,7 @@ `rpython/rtyper/ootypesystem/`_ the `object-oriented type system`_ for OO backends -`rpython/rtyper/memory/`_ the `garbage collector`_ construction +`rpython/memory/`_ the `garbage collector`_ construction framework `rpython/translator/`_ translation_ backends and support code diff --git a/rpython/jit/backend/arm/regalloc.py b/rpython/jit/backend/arm/regalloc.py --- a/rpython/jit/backend/arm/regalloc.py +++ b/rpython/jit/backend/arm/regalloc.py @@ -736,7 +736,7 @@ classptr = y_val # here, we have to go back from 'classptr' to the value expected # from reading the 16 bits in the object header - from rpython.rtyper.memory.gctypelayout import GCData + from rpython.memory.gctypelayout import GCData sizeof_ti = rffi.sizeof(GCData.TYPE_INFO) type_info_group = llop.gc_get_type_info_group(llmemory.Address) type_info_group = rffi.cast(lltype.Signed, type_info_group) diff --git a/rpython/jit/backend/llsupport/gc.py b/rpython/jit/backend/llsupport/gc.py --- a/rpython/jit/backend/llsupport/gc.py +++ b/rpython/jit/backend/llsupport/gc.py @@ -17,7 +17,7 @@ from rpython.jit.backend.llsupport.descr import get_array_descr from rpython.jit.backend.llsupport.descr import get_call_descr from rpython.jit.backend.llsupport.rewrite import GcRewriterAssembler -from rpython.rtyper.memory.gctransform import asmgcroot +from rpython.memory.gctransform import asmgcroot # ____________________________________________________________ @@ -698,7 +698,7 @@ def _make_layoutbuilder(self): # make a TransformerLayoutBuilder and save it on the translator # where it can be fished and reused by the FrameworkGCTransformer - from rpython.rtyper.memory.gctransform import framework + from rpython.memory.gctransform import framework translator = self.translator self.layoutbuilder = framework.TransformerLayoutBuilder(translator) self.layoutbuilder.delay_encoding() @@ -706,7 +706,7 @@ self.gcrootmap.add_jit2gc_hooks(translator._jit2gc) def _setup_gcclass(self): - from rpython.rtyper.memory.gcheader import GCHeaderBuilder + from rpython.memory.gcheader import GCHeaderBuilder self.GCClass = self.layoutbuilder.GCClass self.moving_gc = self.GCClass.moving_gc self.HDRPTR = lltype.Ptr(self.GCClass.HDR) @@ -727,7 +727,7 @@ self.write_barrier_descr = WriteBarrierDescr(self) def _make_functions(self, really_not_translated): - from rpython.rtyper.memory.gctypelayout import check_typeid + from rpython.memory.gctypelayout import check_typeid llop1 = self.llop1 (self.standard_array_basesize, _, self.standard_array_length_ofs) = \ symbolic.get_array_token(lltype.GcArray(lltype.Signed), @@ -813,7 +813,7 @@ [lltype.Signed] * 2) def _bh_malloc(self, sizedescr): - from rpython.rtyper.memory.gctypelayout import check_typeid + from rpython.memory.gctypelayout import check_typeid llop1 = self.llop1 type_id = llop.extract_ushort(llgroup.HALFWORD, sizedescr.tid) check_typeid(type_id) @@ -822,7 +822,7 @@ False, False, False) def _bh_malloc_array(self, num_elem, arraydescr): - from rpython.rtyper.memory.gctypelayout import check_typeid + from rpython.memory.gctypelayout import check_typeid llop1 = self.llop1 type_id = llop.extract_ushort(llgroup.HALFWORD, arraydescr.tid) check_typeid(type_id) diff --git a/rpython/jit/backend/llsupport/test/test_symbolic.py b/rpython/jit/backend/llsupport/test/test_symbolic.py --- a/rpython/jit/backend/llsupport/test/test_symbolic.py +++ b/rpython/jit/backend/llsupport/test/test_symbolic.py @@ -1,7 +1,7 @@ import py from rpython.jit.backend.llsupport.symbolic import * from rpython.rtyper.lltypesystem import lltype, rffi -from rpython.rtyper.memory.lltypelayout import convert_offset_to_int +from rpython.memory.lltypelayout import convert_offset_to_int WORD = rffi.sizeof(lltype.Signed) diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -426,7 +426,7 @@ @rgc.no_collect def _release_gil_asmgcc(css): # similar to trackgcroot.py:pypy_asm_stackwalk, first part - from rpython.rtyper.memory.gctransform import asmgcroot + from rpython.memory.gctransform import asmgcroot new = rffi.cast(asmgcroot.ASM_FRAMEDATA_HEAD_PTR, css) next = asmgcroot.gcrootanchor.next new.next = next @@ -446,7 +446,7 @@ if after: after() # similar to trackgcroot.py:pypy_asm_stackwalk, second part - from rpython.rtyper.memory.gctransform import asmgcroot + from rpython.memory.gctransform import asmgcroot old = rffi.cast(asmgcroot.ASM_FRAMEDATA_HEAD_PTR, css) prev = old.prev next = old.next @@ -1786,7 +1786,7 @@ # from reading the half-word in the object header. Note that # this half-word is at offset 0 on a little-endian machine; # it would be at offset 2 or 4 on a big-endian machine. - from rpython.rtyper.memory.gctypelayout import GCData + from rpython.memory.gctypelayout import GCData sizeof_ti = rffi.sizeof(GCData.TYPE_INFO) type_info_group = llop.gc_get_type_info_group(llmemory.Address) type_info_group = rffi.cast(lltype.Signed, type_info_group) @@ -2296,7 +2296,7 @@ # like %eax that would be destroyed by this call, *and* they are # used by arglocs for the *next* call, then trouble; for now we # will just push/pop them. - from rpython.rtyper.memory.gctransform import asmgcroot + from rpython.memory.gctransform import asmgcroot css = self._regalloc.close_stack_struct if css == 0: use_words = (2 + max(asmgcroot.INDEX_OF_EBP, diff --git a/rpython/rtyper/memory/__init__.py b/rpython/memory/__init__.py rename from rpython/rtyper/memory/__init__.py rename to rpython/memory/__init__.py diff --git a/rpython/rtyper/memory/gc/__init__.py b/rpython/memory/gc/__init__.py rename from rpython/rtyper/memory/gc/__init__.py rename to rpython/memory/gc/__init__.py diff --git a/rpython/rtyper/memory/gc/base.py b/rpython/memory/gc/base.py rename from rpython/rtyper/memory/gc/base.py rename to rpython/memory/gc/base.py --- a/rpython/rtyper/memory/gc/base.py +++ b/rpython/memory/gc/base.py @@ -1,10 +1,10 @@ from rpython.rtyper.lltypesystem import lltype, llmemory, llarena, rffi from rpython.rtyper.lltypesystem.lloperation import llop from rpython.rlib.debug import ll_assert -from rpython.rtyper.memory.gcheader import GCHeaderBuilder -from rpython.rtyper.memory.support import DEFAULT_CHUNK_SIZE -from rpython.rtyper.memory.support import get_address_stack, get_address_deque -from rpython.rtyper.memory.support import AddressDict, null_address_dict +from rpython.memory.gcheader import GCHeaderBuilder +from rpython.memory.support import DEFAULT_CHUNK_SIZE +from rpython.memory.support import get_address_stack, get_address_deque +from rpython.memory.support import AddressDict, null_address_dict from rpython.rtyper.lltypesystem.llmemory import NULL, raw_malloc_usage TYPEID_MAP = lltype.GcStruct('TYPEID_MAP', ('count', lltype.Signed), @@ -41,7 +41,7 @@ def post_setup(self): # More stuff that needs to be initialized when the GC is already # fully working. (Only called by gctransform/framework for now.) - from rpython.rtyper.memory.gc import env + from rpython.memory.gc import env self.DEBUG = env.read_from_env('PYPY_GC_DEBUG') def _teardown(self): @@ -302,7 +302,7 @@ """ if self.DEBUG: from rpython.rlib.objectmodel import we_are_translated - from rpython.rtyper.memory.support import AddressDict + from rpython.memory.support import AddressDict self._debug_seen = AddressDict() self._debug_pending = self.AddressStack() if not we_are_translated(): @@ -434,7 +434,7 @@ except KeyError: raise ValueError("unknown value for translation.gc: %r" % ( config.translation.gc,)) - module = __import__("rpython.rtyper.memory.gc." + modulename, + module = __import__("rpython.memory.gc." + modulename, globals(), locals(), [classname]) GCClass = getattr(module, classname) return GCClass, GCClass.TRANSLATION_PARAMS diff --git a/rpython/rtyper/memory/gc/env.py b/rpython/memory/gc/env.py rename from rpython/rtyper/memory/gc/env.py rename to rpython/memory/gc/env.py diff --git a/rpython/rtyper/memory/gc/generation.py b/rpython/memory/gc/generation.py rename from rpython/rtyper/memory/gc/generation.py rename to rpython/memory/gc/generation.py --- a/rpython/rtyper/memory/gc/generation.py +++ b/rpython/memory/gc/generation.py @@ -1,8 +1,8 @@ import sys -from rpython.rtyper.memory.gc.semispace import SemiSpaceGC -from rpython.rtyper.memory.gc.semispace import GCFLAG_EXTERNAL, GCFLAG_FORWARDED -from rpython.rtyper.memory.gc.semispace import GC_HASH_TAKEN_ADDR -from rpython.rtyper.memory.gc import env +from rpython.memory.gc.semispace import SemiSpaceGC +from rpython.memory.gc.semispace import GCFLAG_EXTERNAL, GCFLAG_FORWARDED +from rpython.memory.gc.semispace import GC_HASH_TAKEN_ADDR +from rpython.memory.gc import env from rpython.rtyper.lltypesystem.llmemory import NULL, raw_malloc_usage from rpython.rtyper.lltypesystem import lltype, llmemory, llarena from rpython.rlib.objectmodel import free_non_gc_object diff --git a/rpython/rtyper/memory/gc/hybrid.py b/rpython/memory/gc/hybrid.py rename from rpython/rtyper/memory/gc/hybrid.py rename to rpython/memory/gc/hybrid.py --- a/rpython/rtyper/memory/gc/hybrid.py +++ b/rpython/memory/gc/hybrid.py @@ -1,12 +1,12 @@ import sys -from rpython.rtyper.memory.gc.semispace import SemiSpaceGC -from rpython.rtyper.memory.gc.generation import GenerationGC, WORD -from rpython.rtyper.memory.gc.semispace import GCFLAG_EXTERNAL, GCFLAG_FORWARDED -from rpython.rtyper.memory.gc.semispace import GCFLAG_HASHMASK -from rpython.rtyper.memory.gc.generation import GCFLAG_NO_YOUNG_PTRS -from rpython.rtyper.memory.gc.generation import GCFLAG_NO_HEAP_PTRS -from rpython.rtyper.memory.gc.semispace import GC_HASH_TAKEN_ADDR -from rpython.rtyper.memory.gc.semispace import GC_HASH_HASFIELD +from rpython.memory.gc.semispace import SemiSpaceGC +from rpython.memory.gc.generation import GenerationGC, WORD +from rpython.memory.gc.semispace import GCFLAG_EXTERNAL, GCFLAG_FORWARDED +from rpython.memory.gc.semispace import GCFLAG_HASHMASK +from rpython.memory.gc.generation import GCFLAG_NO_YOUNG_PTRS +from rpython.memory.gc.generation import GCFLAG_NO_HEAP_PTRS +from rpython.memory.gc.semispace import GC_HASH_TAKEN_ADDR +from rpython.memory.gc.semispace import GC_HASH_HASFIELD from rpython.rtyper.lltypesystem import lltype, llmemory, llarena from rpython.rtyper.lltypesystem.llmemory import raw_malloc_usage from rpython.rtyper.lltypesystem.lloperation import llop diff --git a/rpython/rtyper/memory/gc/inspector.py b/rpython/memory/gc/inspector.py rename from rpython/rtyper/memory/gc/inspector.py rename to rpython/memory/gc/inspector.py --- a/rpython/rtyper/memory/gc/inspector.py +++ b/rpython/memory/gc/inspector.py @@ -6,7 +6,7 @@ from rpython.rtyper.module.ll_os import underscore_on_windows from rpython.rlib import rposix, rgc -from rpython.rtyper.memory.support import AddressDict, get_address_stack +from rpython.memory.support import AddressDict, get_address_stack # ---------- implementation of rpython.rlib.rgc.get_rpy_roots() ---------- diff --git a/rpython/rtyper/memory/gc/minimark.py b/rpython/memory/gc/minimark.py rename from rpython/rtyper/memory/gc/minimark.py rename to rpython/memory/gc/minimark.py --- a/rpython/rtyper/memory/gc/minimark.py +++ b/rpython/memory/gc/minimark.py @@ -46,9 +46,9 @@ from rpython.rtyper.lltypesystem import lltype, llmemory, llarena, llgroup from rpython.rtyper.lltypesystem.lloperation import llop from rpython.rtyper.lltypesystem.llmemory import raw_malloc_usage -from rpython.rtyper.memory.gc.base import GCBase, MovingGCBase -from rpython.rtyper.memory.gc import env -from rpython.rtyper.memory.support import mangle_hash +from rpython.memory.gc.base import GCBase, MovingGCBase +from rpython.memory.gc import env +from rpython.memory.support import mangle_hash from rpython.rlib.rarithmetic import ovfcheck, LONG_BIT, intmask, r_uint from rpython.rlib.rarithmetic import LONG_BIT_SHIFT from rpython.rlib.debug import ll_assert, debug_print, debug_start, debug_stop @@ -254,7 +254,7 @@ # # The ArenaCollection() handles the nonmovable objects allocation. if ArenaCollectionClass is None: - from rpython.rtyper.memory.gc import minimarkpage + from rpython.memory.gc import minimarkpage ArenaCollectionClass = minimarkpage.ArenaCollection self.ac = ArenaCollectionClass(arena_size, page_size, small_request_threshold) diff --git a/rpython/rtyper/memory/gc/minimarkpage.py b/rpython/memory/gc/minimarkpage.py rename from rpython/rtyper/memory/gc/minimarkpage.py rename to rpython/memory/gc/minimarkpage.py diff --git a/rpython/rtyper/memory/gc/minimarktest.py b/rpython/memory/gc/minimarktest.py rename from rpython/rtyper/memory/gc/minimarktest.py rename to rpython/memory/gc/minimarktest.py diff --git a/rpython/rtyper/memory/gc/semispace.py b/rpython/memory/gc/semispace.py rename from rpython/rtyper/memory/gc/semispace.py rename to rpython/memory/gc/semispace.py --- a/rpython/rtyper/memory/gc/semispace.py +++ b/rpython/memory/gc/semispace.py @@ -1,15 +1,15 @@ from rpython.rtyper.lltypesystem.llmemory import raw_malloc, raw_free from rpython.rtyper.lltypesystem.llmemory import raw_memcopy, raw_memclear from rpython.rtyper.lltypesystem.llmemory import NULL, raw_malloc_usage -from rpython.rtyper.memory.support import get_address_stack, get_address_deque -from rpython.rtyper.memory.support import AddressDict +from rpython.memory.support import get_address_stack, get_address_deque +from rpython.memory.support import AddressDict from rpython.rtyper.lltypesystem import lltype, llmemory, llarena, rffi, llgroup from rpython.rlib.objectmodel import free_non_gc_object from rpython.rlib.debug import ll_assert, have_debug_prints from rpython.rlib.debug import debug_print, debug_start, debug_stop from rpython.rtyper.lltypesystem.lloperation import llop from rpython.rlib.rarithmetic import ovfcheck, LONG_BIT -from rpython.rtyper.memory.gc.base import MovingGCBase, ARRAY_TYPEID_MAP,\ +from rpython.memory.gc.base import MovingGCBase, ARRAY_TYPEID_MAP,\ TYPEID_MAP import sys, os diff --git a/rpython/rtyper/memory/gc/test/__init__.py b/rpython/memory/gc/test/__init__.py rename from rpython/rtyper/memory/gc/test/__init__.py rename to rpython/memory/gc/test/__init__.py diff --git a/rpython/rtyper/memory/gc/test/test_direct.py b/rpython/memory/gc/test/test_direct.py rename from rpython/rtyper/memory/gc/test/test_direct.py rename to rpython/memory/gc/test/test_direct.py --- a/rpython/rtyper/memory/gc/test/test_direct.py +++ b/rpython/memory/gc/test/test_direct.py @@ -8,7 +8,7 @@ import py from rpython.rtyper.lltypesystem import lltype, llmemory -from rpython.rtyper.memory.gctypelayout import TypeLayoutBuilder +from rpython.memory.gctypelayout import TypeLayoutBuilder from rpython.rlib.rarithmetic import LONG_BIT, is_valid_int WORD = LONG_BIT // 8 @@ -365,7 +365,7 @@ assert p[i-1] == chr(i) class TestSemiSpaceGC(DirectGCTest): - from rpython.rtyper.memory.gc.semispace import SemiSpaceGC as GCClass + from rpython.memory.gc.semispace import SemiSpaceGC as GCClass def test_shrink_array(self): S1 = lltype.GcStruct('S1', ('h', lltype.Char), @@ -384,7 +384,7 @@ class TestGenerationGC(TestSemiSpaceGC): - from rpython.rtyper.memory.gc.generation import GenerationGC as GCClass + from rpython.memory.gc.generation import GenerationGC as GCClass def test_collect_gen(self): gc = self.gc @@ -430,7 +430,7 @@ class TestHybridGC(TestGenerationGC): - from rpython.rtyper.memory.gc.hybrid import HybridGC as GCClass + from rpython.memory.gc.hybrid import HybridGC as GCClass GC_PARAMS = {'space_size': 48*WORD, 'min_nursery_size': 12*WORD, @@ -480,8 +480,8 @@ class TestMiniMarkGCSimple(DirectGCTest): - from rpython.rtyper.memory.gc.minimark import MiniMarkGC as GCClass - from rpython.rtyper.memory.gc.minimarktest import SimpleArenaCollection + from rpython.memory.gc.minimark import MiniMarkGC as GCClass + from rpython.memory.gc.minimarktest import SimpleArenaCollection # test the GC itself, providing a simple class for ArenaCollection GC_PARAMS = {'ArenaCollectionClass': SimpleArenaCollection} @@ -507,7 +507,7 @@ test_card_marker.GC_PARAMS = {"card_page_indices": 4} def test_writebarrier_before_copy(self): - from rpython.rtyper.memory.gc import minimark + from rpython.memory.gc import minimark largeobj_size = self.gc.nonlarge_max + 1 self.gc.next_major_collection_threshold = 99999.0 p_src = self.malloc(VAR, largeobj_size) @@ -546,7 +546,7 @@ def test_writebarrier_before_copy_preserving_cards(self): from rpython.rtyper.lltypesystem import llarena - from rpython.rtyper.memory.gc import minimark + from rpython.memory.gc import minimark tid = self.get_type_id(VAR) largeobj_size = self.gc.nonlarge_max + 1 self.gc.next_major_collection_threshold = 99999.0 @@ -582,4 +582,4 @@ class TestMiniMarkGCFull(DirectGCTest): - from rpython.rtyper.memory.gc.minimark import MiniMarkGC as GCClass + from rpython.memory.gc.minimark import MiniMarkGC as GCClass diff --git a/rpython/rtyper/memory/gc/test/test_env.py b/rpython/memory/gc/test/test_env.py rename from rpython/rtyper/memory/gc/test/test_env.py rename to rpython/memory/gc/test/test_env.py --- a/rpython/rtyper/memory/gc/test/test_env.py +++ b/rpython/memory/gc/test/test_env.py @@ -1,5 +1,5 @@ import os, py -from rpython.rtyper.memory.gc import env +from rpython.memory.gc import env from rpython.rlib.rarithmetic import r_uint from rpython.tool.udir import udir diff --git a/rpython/rtyper/memory/gc/test/test_inspector.py b/rpython/memory/gc/test/test_inspector.py rename from rpython/rtyper/memory/gc/test/test_inspector.py rename to rpython/memory/gc/test/test_inspector.py --- a/rpython/rtyper/memory/gc/test/test_inspector.py +++ b/rpython/memory/gc/test/test_inspector.py @@ -1,7 +1,7 @@ import os from rpython.tool.udir import udir -from rpython.rtyper.memory.gc.test.test_direct import BaseDirectGCTest, S -from rpython.rtyper.memory.gc import inspector +from rpython.memory.gc.test.test_direct import BaseDirectGCTest, S +from rpython.memory.gc import inspector from rpython.rtyper.lltypesystem import llmemory @@ -39,10 +39,10 @@ class TestHybridGC(InspectorTest): - from rpython.rtyper.memory.gc.hybrid import HybridGC as GCClass + from rpython.memory.gc.hybrid import HybridGC as GCClass class TestMiniMarkGCSimple(InspectorTest): - from rpython.rtyper.memory.gc.minimark import MiniMarkGC as GCClass - from rpython.rtyper.memory.gc.minimarktest import SimpleArenaCollection + from rpython.memory.gc.minimark import MiniMarkGC as GCClass + from rpython.memory.gc.minimarktest import SimpleArenaCollection GC_PARAMS = {'ArenaCollectionClass': SimpleArenaCollection, "card_page_indices": 4} diff --git a/rpython/rtyper/memory/gc/test/test_minimark.py b/rpython/memory/gc/test/test_minimark.py rename from rpython/rtyper/memory/gc/test/test_minimark.py rename to rpython/memory/gc/test/test_minimark.py --- a/rpython/rtyper/memory/gc/test/test_minimark.py +++ b/rpython/memory/gc/test/test_minimark.py @@ -1,5 +1,5 @@ from rpython.rtyper.lltypesystem import llmemory -from rpython.rtyper.memory.gc.minimark import MiniMarkGC +from rpython.memory.gc.minimark import MiniMarkGC from rpython.rlib.rarithmetic import LONG_BIT # Note that most tests are in test_direct.py. diff --git a/rpython/rtyper/memory/gc/test/test_minimarkpage.py b/rpython/memory/gc/test/test_minimarkpage.py rename from rpython/rtyper/memory/gc/test/test_minimarkpage.py rename to rpython/memory/gc/test/test_minimarkpage.py --- a/rpython/rtyper/memory/gc/test/test_minimarkpage.py +++ b/rpython/memory/gc/test/test_minimarkpage.py @@ -1,8 +1,8 @@ import py -from rpython.rtyper.memory.gc.minimarkpage import ArenaCollection -from rpython.rtyper.memory.gc.minimarkpage import PAGE_HEADER, PAGE_PTR -from rpython.rtyper.memory.gc.minimarkpage import PAGE_NULL, WORD -from rpython.rtyper.memory.gc.minimarkpage import _dummy_size +from rpython.memory.gc.minimarkpage import ArenaCollection +from rpython.memory.gc.minimarkpage import PAGE_HEADER, PAGE_PTR +from rpython.memory.gc.minimarkpage import PAGE_NULL, WORD +from rpython.memory.gc.minimarkpage import _dummy_size from rpython.rtyper.lltypesystem import lltype, llmemory, llarena from rpython.rtyper.lltypesystem.llmemory import cast_ptr_to_adr diff --git a/rpython/rtyper/memory/gcheader.py b/rpython/memory/gcheader.py rename from rpython/rtyper/memory/gcheader.py rename to rpython/memory/gcheader.py diff --git a/rpython/rtyper/memory/gctransform/__init__.py b/rpython/memory/gctransform/__init__.py rename from rpython/rtyper/memory/gctransform/__init__.py rename to rpython/memory/gctransform/__init__.py diff --git a/rpython/rtyper/memory/gctransform/asmgcroot.py b/rpython/memory/gctransform/asmgcroot.py rename from rpython/rtyper/memory/gctransform/asmgcroot.py rename to rpython/memory/gctransform/asmgcroot.py --- a/rpython/rtyper/memory/gctransform/asmgcroot.py +++ b/rpython/memory/gctransform/asmgcroot.py @@ -4,7 +4,7 @@ from rpython.rtyper.annlowlevel import llhelper from rpython.rtyper.lltypesystem import lltype, llmemory, rffi from rpython.rtyper.lltypesystem.lloperation import llop -from rpython.rtyper.memory.gctransform.framework import ( +from rpython.memory.gctransform.framework import ( BaseFrameworkGCTransformer, BaseRootWalker) from rpython.rtyper.rbuiltin import gen_cast from rpython.translator.unsimplify import copyvar @@ -160,8 +160,8 @@ # all ASM_FRAMEDATA structures that do no belong to the current # thread after a fork(). from rpython.rlib import rthread - from rpython.rtyper.memory.support import AddressDict - from rpython.rtyper.memory.support import copy_without_null_values + from rpython.memory.support import AddressDict + from rpython.memory.support import copy_without_null_values from rpython.annotator import model as annmodel gcdata = self.gcdata diff --git a/rpython/rtyper/memory/gctransform/boehm.py b/rpython/memory/gctransform/boehm.py rename from rpython/rtyper/memory/gctransform/boehm.py rename to rpython/memory/gctransform/boehm.py --- a/rpython/rtyper/memory/gctransform/boehm.py +++ b/rpython/memory/gctransform/boehm.py @@ -1,5 +1,5 @@ -from rpython.rtyper.memory.gctransform.transform import GCTransformer, mallocHelpers -from rpython.rtyper.memory.gctransform.support import (get_rtti, +from rpython.memory.gctransform.transform import GCTransformer, mallocHelpers +from rpython.memory.gctransform.support import (get_rtti, _static_deallocator_body_for_type, LLTransformerOp, ll_call_destructor) from rpython.rtyper.lltypesystem import lltype, llmemory from rpython.flowspace.model import Constant diff --git a/rpython/rtyper/memory/gctransform/framework.py b/rpython/memory/gctransform/framework.py rename from rpython/rtyper/memory/gctransform/framework.py rename to rpython/memory/gctransform/framework.py --- a/rpython/rtyper/memory/gctransform/framework.py +++ b/rpython/memory/gctransform/framework.py @@ -3,11 +3,11 @@ from rpython.rtyper import rmodel, annlowlevel from rpython.rtyper.lltypesystem import lltype, llmemory, rffi, llgroup from rpython.rtyper.lltypesystem.lloperation import LL_OPERATIONS -from rpython.rtyper.memory import gctypelayout -from rpython.rtyper.memory.gctransform.log import log -from rpython.rtyper.memory.gctransform.support import get_rtti, ll_call_destructor -from rpython.rtyper.memory.gctransform.transform import GCTransformer -from rpython.rtyper.memory.gctypelayout import ll_weakref_deref, WEAKREF, \ +from rpython.memory import gctypelayout +from rpython.memory.gctransform.log import log +from rpython.memory.gctransform.support import get_rtti, ll_call_destructor +from rpython.memory.gctransform.transform import GCTransformer +from rpython.memory.gctypelayout import ll_weakref_deref, WEAKREF, \ WEAKREFPTR from rpython.tool.sourcetools import func_with_new_name from rpython.translator.backendopt import graphanalyze @@ -129,9 +129,9 @@ root_stack_depth = None # for tests to override def __init__(self, translator): - from rpython.rtyper.memory.gc.base import choose_gc_from_config - from rpython.rtyper.memory.gc.base import ARRAY_TYPEID_MAP - from rpython.rtyper.memory.gc import inspector + from rpython.memory.gc.base import choose_gc_from_config + from rpython.memory.gc.base import ARRAY_TYPEID_MAP + from rpython.memory.gc import inspector super(BaseFrameworkGCTransformer, self).__init__(translator, inline=True) @@ -1209,7 +1209,7 @@ def __init__(self, translator, GCClass=None): if GCClass is None: - from rpython.rtyper.memory.gc.base import choose_gc_from_config + from rpython.memory.gc.base import choose_gc_from_config GCClass, _ = choose_gc_from_config(translator.config) if translator.config.translation.gcremovetypeptr: lltype2vtable = translator.rtyper.lltype2vtable diff --git a/rpython/rtyper/memory/gctransform/log.py b/rpython/memory/gctransform/log.py rename from rpython/rtyper/memory/gctransform/log.py rename to rpython/memory/gctransform/log.py diff --git a/rpython/rtyper/memory/gctransform/refcounting.py b/rpython/memory/gctransform/refcounting.py rename from rpython/rtyper/memory/gctransform/refcounting.py rename to rpython/memory/gctransform/refcounting.py --- a/rpython/rtyper/memory/gctransform/refcounting.py +++ b/rpython/memory/gctransform/refcounting.py @@ -1,11 +1,11 @@ -from rpython.rtyper.memory.gctransform.transform import GCTransformer, mallocHelpers -from rpython.rtyper.memory.gctransform.support import find_gc_ptrs_in_type, \ +from rpython.memory.gctransform.transform import GCTransformer, mallocHelpers +from rpython.memory.gctransform.support import find_gc_ptrs_in_type, \ get_rtti, _static_deallocator_body_for_type, LLTransformerOp, ll_call_destructor from rpython.rtyper.lltypesystem import lltype, llmemory from rpython.rtyper.lltypesystem.lloperation import llop from rpython.translator.backendopt.support import var_needsgc from rpython.rtyper import rmodel -from rpython.rtyper.memory.gcheader import GCHeaderBuilder +from rpython.memory.gcheader import GCHeaderBuilder from rpython.rlib.rarithmetic import ovfcheck from rpython.rtyper.rbuiltin import gen_cast import sys diff --git a/rpython/rtyper/memory/gctransform/shadowstack.py b/rpython/memory/gctransform/shadowstack.py rename from rpython/rtyper/memory/gctransform/shadowstack.py rename to rpython/memory/gctransform/shadowstack.py --- a/rpython/rtyper/memory/gctransform/shadowstack.py +++ b/rpython/memory/gctransform/shadowstack.py @@ -4,7 +4,7 @@ from rpython.rtyper import rmodel from rpython.rtyper.annlowlevel import llhelper from rpython.rtyper.lltypesystem import lltype, llmemory -from rpython.rtyper.memory.gctransform.framework import ( +from rpython.memory.gctransform.framework import ( BaseFrameworkGCTransformer, BaseRootWalker, sizeofaddr) from rpython.rtyper.rbuiltin import gen_cast diff --git a/rpython/rtyper/memory/gctransform/statistics.py b/rpython/memory/gctransform/statistics.py rename from rpython/rtyper/memory/gctransform/statistics.py rename to rpython/memory/gctransform/statistics.py diff --git a/rpython/rtyper/memory/gctransform/support.py b/rpython/memory/gctransform/support.py rename from rpython/rtyper/memory/gctransform/support.py rename to rpython/memory/gctransform/support.py diff --git a/rpython/rtyper/memory/gctransform/test/__init__.py b/rpython/memory/gctransform/test/__init__.py rename from rpython/rtyper/memory/gctransform/test/__init__.py rename to rpython/memory/gctransform/test/__init__.py diff --git a/rpython/rtyper/memory/gctransform/test/test_boehm.py b/rpython/memory/gctransform/test/test_boehm.py rename from rpython/rtyper/memory/gctransform/test/test_boehm.py rename to rpython/memory/gctransform/test/test_boehm.py --- a/rpython/rtyper/memory/gctransform/test/test_boehm.py +++ b/rpython/memory/gctransform/test/test_boehm.py @@ -1,10 +1,10 @@ -from rpython.rtyper.memory.gctransform.boehm import BoehmGCTransformer -from rpython.rtyper.memory.gctransform.test.test_transform import rtype_and_transform, getops -from rpython.rtyper.memory.gctransform.test.test_refcounting import make_deallocator +from rpython.memory.gctransform.boehm import BoehmGCTransformer +from rpython.memory.gctransform.test.test_transform import rtype_and_transform, getops +from rpython.memory.gctransform.test.test_refcounting import make_deallocator from rpython.rtyper.lltypesystem import lltype from rpython.translator.translator import graphof from rpython.translator.c.gc import BoehmGcPolicy -from rpython.rtyper.memory.gctransform.test.test_transform import LLInterpedTranformerTests +from rpython.memory.gctransform.test.test_transform import LLInterpedTranformerTests class TestLLInterpedBoehm(LLInterpedTranformerTests): diff --git a/rpython/rtyper/memory/gctransform/test/test_framework.py b/rpython/memory/gctransform/test/test_framework.py rename from rpython/rtyper/memory/gctransform/test/test_framework.py rename to rpython/memory/gctransform/test/test_framework.py --- a/rpython/rtyper/memory/gctransform/test/test_framework.py +++ b/rpython/memory/gctransform/test/test_framework.py @@ -3,13 +3,13 @@ from rpython.flowspace.model import Constant, SpaceOperation from rpython.rtyper.lltypesystem import lltype, rffi from rpython.rtyper.lltypesystem.lloperation import llop -from rpython.rtyper.memory.gc.semispace import SemiSpaceGC -from rpython.rtyper.memory.gctransform.framework import (CollectAnalyzer, +from rpython.memory.gc.semispace import SemiSpaceGC +from rpython.memory.gctransform.framework import (CollectAnalyzer, find_initializing_stores, find_clean_setarrayitems) -from rpython.rtyper.memory.gctransform.shadowstack import ( +from rpython.memory.gctransform.shadowstack import ( ShadowStackFrameworkGCTransformer) -from rpython.rtyper.memory.gctransform.test.test_transform import rtype -from rpython.rtyper.memory.gctransform.transform import GcHighLevelOp +from rpython.memory.gctransform.test.test_transform import rtype +from rpython.memory.gctransform.transform import GcHighLevelOp from rpython.rtyper.rtyper import LowLevelOpList from rpython.translator.backendopt.all import backend_optimizations from rpython.translator.c.gc import BasicFrameworkGcPolicy diff --git a/rpython/rtyper/memory/gctransform/test/test_refcounting.py b/rpython/memory/gctransform/test/test_refcounting.py rename from rpython/rtyper/memory/gctransform/test/test_refcounting.py rename to rpython/memory/gctransform/test/test_refcounting.py --- a/rpython/rtyper/memory/gctransform/test/test_refcounting.py +++ b/rpython/memory/gctransform/test/test_refcounting.py @@ -1,7 +1,7 @@ import py -from rpython.rtyper.memory.gctransform.test.test_transform import rtype, rtype_and_transform, getops -from rpython.rtyper.memory.gctransform.test.test_transform import LLInterpedTranformerTests -from rpython.rtyper.memory.gctransform.refcounting import RefcountingGCTransformer +from rpython.memory.gctransform.test.test_transform import rtype, rtype_and_transform, getops +from rpython.memory.gctransform.test.test_transform import LLInterpedTranformerTests +from rpython.memory.gctransform.refcounting import RefcountingGCTransformer from rpython.rtyper.lltypesystem import lltype from rpython.translator.translator import TranslationContext, graphof from rpython.translator.c.gc import RefcountingGcPolicy diff --git a/rpython/rtyper/memory/gctransform/test/test_statistics.py b/rpython/memory/gctransform/test/test_statistics.py rename from rpython/rtyper/memory/gctransform/test/test_statistics.py rename to rpython/memory/gctransform/test/test_statistics.py --- a/rpython/rtyper/memory/gctransform/test/test_statistics.py +++ b/rpython/memory/gctransform/test/test_statistics.py @@ -1,7 +1,7 @@ from rpython.rtyper.lltypesystem import lltype -from rpython.rtyper.memory.gctransform.test.test_transform import \ +from rpython.memory.gctransform.test.test_transform import \ rtype -from rpython.rtyper.memory.gctransform.statistics import \ +from rpython.memory.gctransform.statistics import \ relevant_gcvars_graph, relevant_gcvars, filter_for_nongcptr from rpython.translator.translator import graphof diff --git a/rpython/rtyper/memory/gctransform/test/test_transform.py b/rpython/memory/gctransform/test/test_transform.py rename from rpython/rtyper/memory/gctransform/test/test_transform.py rename to rpython/memory/gctransform/test/test_transform.py --- a/rpython/rtyper/memory/gctransform/test/test_transform.py +++ b/rpython/memory/gctransform/test/test_transform.py @@ -1,4 +1,4 @@ -from rpython.rtyper.memory.gctransform.transform import BaseGCTransformer +from rpython.memory.gctransform.transform import BaseGCTransformer from rpython.flowspace.model import c_last_exception, Variable from rpython.translator.backendopt.support import var_needsgc from rpython.translator.translator import TranslationContext, graphof diff --git a/rpython/rtyper/memory/gctransform/transform.py b/rpython/memory/gctransform/transform.py rename from rpython/rtyper/memory/gctransform/transform.py rename to rpython/memory/gctransform/transform.py --- a/rpython/rtyper/memory/gctransform/transform.py +++ b/rpython/memory/gctransform/transform.py @@ -355,7 +355,7 @@ hop.rename('cast_ptr_to_int') def gct_gc_heap_stats(self, hop): - from rpython.rtyper.memory.gc.base import ARRAY_TYPEID_MAP + from rpython.memory.gc.base import ARRAY_TYPEID_MAP return hop.cast_result(rmodel.inputconst(lltype.Ptr(ARRAY_TYPEID_MAP), lltype.nullptr(ARRAY_TYPEID_MAP))) diff --git a/rpython/rtyper/memory/gctypelayout.py b/rpython/memory/gctypelayout.py rename from rpython/rtyper/memory/gctypelayout.py rename to rpython/memory/gctypelayout.py diff --git a/rpython/rtyper/memory/gcwrapper.py b/rpython/memory/gcwrapper.py rename from rpython/rtyper/memory/gcwrapper.py rename to rpython/memory/gcwrapper.py --- a/rpython/rtyper/memory/gcwrapper.py +++ b/rpython/memory/gcwrapper.py @@ -2,7 +2,7 @@ from rpython.rtyper.lltypesystem import lltype, llmemory, llheap from rpython.rtyper import llinterp from rpython.rtyper.annlowlevel import llhelper -from rpython.rtyper.memory import gctypelayout +from rpython.memory import gctypelayout from rpython.flowspace.model import Constant @@ -205,7 +205,7 @@ super(DirectRunLayoutBuilder, self).__init__(GCClass, lltype2vtable) def make_finalizer_funcptr_for_type(self, TYPE): - from rpython.rtyper.memory.gctransform.support import get_rtti + from rpython.memory.gctransform.support import get_rtti rtti = get_rtti(TYPE) if rtti is not None and hasattr(rtti._obj, 'destructor_funcptr'): destrptr = rtti._obj.destructor_funcptr @@ -228,7 +228,7 @@ return llhelper(gctypelayout.GCData.FINALIZER_OR_CT, ll_finalizer), light def make_custom_trace_funcptr_for_type(self, TYPE): - from rpython.rtyper.memory.gctransform.support import get_rtti + from rpython.memory.gctransform.support import get_rtti rtti = get_rtti(TYPE) if rtti is not None and hasattr(rtti._obj, 'custom_trace_funcptr'): return rtti._obj.custom_trace_funcptr diff --git a/rpython/rtyper/memory/lldict.py b/rpython/memory/lldict.py rename from rpython/rtyper/memory/lldict.py rename to rpython/memory/lldict.py --- a/rpython/rtyper/memory/lldict.py +++ b/rpython/memory/lldict.py @@ -1,7 +1,7 @@ from rpython.rtyper.lltypesystem import lltype, llmemory from rpython.rtyper.lltypesystem import rdict from rpython.rlib.objectmodel import we_are_translated -from rpython.rtyper.memory.support import mangle_hash +from rpython.memory.support import mangle_hash # This is a low-level AddressDict, reusing a lot of the logic from rdict.py. # xxx this is very dependent on the details of rdict.py diff --git a/rpython/rtyper/memory/lltypelayout.py b/rpython/memory/lltypelayout.py rename from rpython/rtyper/memory/lltypelayout.py rename to rpython/memory/lltypelayout.py diff --git a/rpython/rtyper/memory/support.py b/rpython/memory/support.py rename from rpython/rtyper/memory/support.py rename to rpython/memory/support.py --- a/rpython/rtyper/memory/support.py +++ b/rpython/memory/support.py @@ -268,13 +268,13 @@ def AddressDict(length_estimate=0): if we_are_translated(): - from rpython.rtyper.memory import lldict + from rpython.memory import lldict return lldict.newdict(length_estimate) else: return BasicAddressDict() def null_address_dict(): - from rpython.rtyper.memory import lldict + from rpython.memory import lldict return lltype.nullptr(lldict.DICT) class BasicAddressDict(object): @@ -333,7 +333,7 @@ if not we_are_translated(): # when not translated, return a dict of the same kind as 'dict' if not isinstance(dict, BasicAddressDict): - from rpython.rtyper.memory.lldict import newdict + from rpython.memory.lldict import newdict result = newdict(dict.length()) dict.foreach(_get_updater(surviving, updated_address), result) return result @@ -354,7 +354,7 @@ if not we_are_translated(): # when not translated, return a dict of the same kind as 'dict' if not isinstance(dict, BasicAddressDict): - from rpython.rtyper.memory.lldict import newdict + from rpython.memory.lldict import newdict result = newdict() dict.foreach(_null_value_checker, result) return result diff --git a/rpython/rtyper/memory/test/__init__.py b/rpython/memory/test/__init__.py rename from rpython/rtyper/memory/test/__init__.py rename to rpython/memory/test/__init__.py diff --git a/rpython/rtyper/memory/test/snippet.py b/rpython/memory/test/snippet.py rename from rpython/rtyper/memory/test/snippet.py rename to rpython/memory/test/snippet.py diff --git a/rpython/rtyper/memory/test/test_gc.py b/rpython/memory/test/test_gc.py rename from rpython/rtyper/memory/test/test_gc.py rename to rpython/memory/test/test_gc.py --- a/rpython/rtyper/memory/test/test_gc.py +++ b/rpython/memory/test/test_gc.py @@ -1,8 +1,8 @@ import py import sys -from rpython.rtyper.memory import gcwrapper -from rpython.rtyper.memory.test import snippet +from rpython.memory import gcwrapper +from rpython.memory.test import snippet from rpython.rtyper.test.test_llinterp import get_interpreter from rpython.rtyper.lltypesystem import lltype from rpython.rtyper.lltypesystem.lloperation import llop @@ -804,7 +804,7 @@ class TestSemiSpaceGC(GCTest, snippet.SemiSpaceGCTests): - from rpython.rtyper.memory.gc.semispace import SemiSpaceGC as GCClass + from rpython.memory.gc.semispace import SemiSpaceGC as GCClass GC_CAN_MOVE = True GC_CAN_MALLOC_NONMOVABLE = False GC_CAN_SHRINK_ARRAY = True @@ -814,10 +814,10 @@ GC_PARAMS = {'space_size': 16*WORD} class TestGenerationalGC(TestSemiSpaceGC): - from rpython.rtyper.memory.gc.generation import GenerationGC as GCClass + from rpython.memory.gc.generation import GenerationGC as GCClass class TestHybridGC(TestGenerationalGC): - from rpython.rtyper.memory.gc.hybrid import HybridGC as GCClass + from rpython.memory.gc.hybrid import HybridGC as GCClass GC_CAN_MALLOC_NONMOVABLE = True GC_CAN_SHRINK_BIG_ARRAY = False @@ -886,7 +886,7 @@ py.test.skip("Not supported") class TestHybridGCSmallHeap(GCTest): - from rpython.rtyper.memory.gc.hybrid import HybridGC as GCClass + from rpython.memory.gc.hybrid import HybridGC as GCClass GC_CAN_MOVE = False # with this size of heap, stuff gets allocated # in 3rd gen. GC_CAN_MALLOC_NONMOVABLE = True @@ -936,7 +936,7 @@ class TestMiniMarkGC(TestSemiSpaceGC): - from rpython.rtyper.memory.gc.minimark import MiniMarkGC as GCClass + from rpython.memory.gc.minimark import MiniMarkGC as GCClass GC_CAN_SHRINK_BIG_ARRAY = False GC_CAN_MALLOC_NONMOVABLE = True BUT_HOW_BIG_IS_A_BIG_STRING = 11*WORD diff --git a/rpython/rtyper/memory/test/test_gctypelayout.py b/rpython/memory/test/test_gctypelayout.py rename from rpython/rtyper/memory/test/test_gctypelayout.py rename to rpython/memory/test/test_gctypelayout.py --- a/rpython/rtyper/memory/test/test_gctypelayout.py +++ b/rpython/memory/test/test_gctypelayout.py @@ -1,7 +1,7 @@ import py -from rpython.rtyper.memory.gctypelayout import TypeLayoutBuilder, GCData -from rpython.rtyper.memory.gctypelayout import offsets_to_gc_pointers -from rpython.rtyper.memory.gctypelayout import gc_pointers_inside +from rpython.memory.gctypelayout import TypeLayoutBuilder, GCData +from rpython.memory.gctypelayout import offsets_to_gc_pointers +from rpython.memory.gctypelayout import gc_pointers_inside from rpython.rtyper.lltypesystem import lltype, llmemory, rclass from rpython.rtyper.test.test_llinterp import get_interpreter from rpython.rtyper.rclass import IR_IMMUTABLE, IR_QUASIIMMUTABLE diff --git a/rpython/rtyper/memory/test/test_lldict.py b/rpython/memory/test/test_lldict.py rename from rpython/rtyper/memory/test/test_lldict.py rename to rpython/memory/test/test_lldict.py --- a/rpython/rtyper/memory/test/test_lldict.py +++ b/rpython/memory/test/test_lldict.py @@ -1,6 +1,6 @@ import random, sys from rpython.rtyper.lltypesystem import lltype, llmemory -from rpython.rtyper.memory import support, lldict +from rpython.memory import support, lldict class TestLLAddressDict: diff --git a/rpython/rtyper/memory/test/test_support.py b/rpython/memory/test/test_support.py rename from rpython/rtyper/memory/test/test_support.py rename to rpython/memory/test/test_support.py --- a/rpython/rtyper/memory/test/test_support.py +++ b/rpython/memory/test/test_support.py @@ -1,6 +1,6 @@ from rpython.rlib.objectmodel import free_non_gc_object -from rpython.rtyper.memory.support import get_address_stack -from rpython.rtyper.memory.support import get_address_deque +from rpython.memory.support import get_address_stack +from rpython.memory.support import get_address_deque from rpython.rtyper.test.test_llinterp import interpret from rpython.rtyper.lltypesystem import lltype, llmemory diff --git a/rpython/rtyper/memory/test/test_transformed_gc.py b/rpython/memory/test/test_transformed_gc.py rename from rpython/rtyper/memory/test/test_transformed_gc.py rename to rpython/memory/test/test_transformed_gc.py --- a/rpython/rtyper/memory/test/test_transformed_gc.py +++ b/rpython/memory/test/test_transformed_gc.py @@ -4,7 +4,7 @@ from rpython.translator.c import gc from rpython.annotator import model as annmodel from rpython.rtyper.lltypesystem import lltype, llmemory, rffi, llgroup -from rpython.rtyper.memory.gctransform import framework, shadowstack +from rpython.memory.gctransform import framework, shadowstack from rpython.rtyper.lltypesystem.lloperation import llop, void from rpython.rlib.objectmodel import compute_unique_id, we_are_translated from rpython.rlib.debug import ll_assert @@ -912,7 +912,7 @@ class gcpolicy(gc.BasicFrameworkGcPolicy): class transformerclass(shadowstack.ShadowStackFrameworkGCTransformer): - from rpython.rtyper.memory.gc.semispace import SemiSpaceGC as GCClass + from rpython.memory.gc.semispace import SemiSpaceGC as GCClass GC_PARAMS = {'space_size': 512*WORD, 'translated_to_c': False} root_stack_depth = 200 @@ -923,7 +923,7 @@ class gcpolicy(gc.BasicFrameworkGcPolicy): class transformerclass(shadowstack.ShadowStackFrameworkGCTransformer): - from rpython.rtyper.memory.gc.generation import GenerationGC as \ + from rpython.memory.gc.generation import GenerationGC as \ GCClass GC_PARAMS = {'space_size': 512*WORD, 'nursery_size': 32*WORD, @@ -1109,11 +1109,11 @@ class gcpolicy(gc.BasicFrameworkGcPolicy): class transformerclass(shadowstack.ShadowStackFrameworkGCTransformer): - from rpython.rtyper.memory.gc.generation import GenerationGC + from rpython.memory.gc.generation import GenerationGC class GCClass(GenerationGC): __ready = False def setup(self): - from rpython.rtyper.memory.gc.generation import GenerationGC + from rpython.memory.gc.generation import GenerationGC GenerationGC.setup(self) self.__ready = True def semispace_collect(self, size_changing=False): @@ -1154,7 +1154,7 @@ class gcpolicy(gc.BasicFrameworkGcPolicy): class transformerclass(shadowstack.ShadowStackFrameworkGCTransformer): - from rpython.rtyper.memory.gc.hybrid import HybridGC as GCClass + from rpython.memory.gc.hybrid import HybridGC as GCClass GC_PARAMS = {'space_size': 512*WORD, 'nursery_size': 32*WORD, 'large_object': 8*WORD, @@ -1223,7 +1223,7 @@ class gcpolicy(gc.BasicFrameworkGcPolicy): class transformerclass(shadowstack.ShadowStackFrameworkGCTransformer): - from rpython.rtyper.memory.gc.minimark import MiniMarkGC as GCClass + from rpython.memory.gc.minimark import MiniMarkGC as GCClass GC_PARAMS = {'nursery_size': 32*WORD, 'page_size': 16*WORD, 'arena_size': 64*WORD, @@ -1340,7 +1340,7 @@ class gcpolicy(gc.BasicFrameworkGcPolicy): class transformerclass(shadowstack.ShadowStackFrameworkGCTransformer): - from rpython.rtyper.memory.gc.generation import GenerationGC as \ + from rpython.memory.gc.generation import GenerationGC as \ GCClass GC_PARAMS = {'space_size': 512*WORD, 'nursery_size': 32*WORD, diff --git a/rpython/rlib/_stacklet_asmgcc.py b/rpython/rlib/_stacklet_asmgcc.py --- a/rpython/rlib/_stacklet_asmgcc.py +++ b/rpython/rlib/_stacklet_asmgcc.py @@ -14,7 +14,7 @@ if _stackletrootwalker is not None: return _stackletrootwalker - from rpython.rtyper.memory.gctransform.asmgcroot import ( + from rpython.memory.gctransform.asmgcroot import ( WALKFRAME, CALLEE_SAVED_REGS, INDEX_OF_EBP, sizeofaddr) assert _asmstackrootwalker is not None, "should have been monkey-patched" diff --git a/rpython/rlib/rgc.py b/rpython/rlib/rgc.py --- a/rpython/rlib/rgc.py +++ b/rpython/rlib/rgc.py @@ -96,11 +96,11 @@ def compute_result_annotation(self): from rpython.annotator import model as annmodel - from rpython.rtyper.memory.gc.base import ARRAY_TYPEID_MAP + from rpython.memory.gc.base import ARRAY_TYPEID_MAP return annmodel.SomePtr(lltype.Ptr(ARRAY_TYPEID_MAP)) def specialize_call(self, hop): - from rpython.rtyper.memory.gc.base import ARRAY_TYPEID_MAP + from rpython.memory.gc.base import ARRAY_TYPEID_MAP hop.exception_is_here() return hop.genop('gc_heap_stats', [], resulttype=hop.r_result) diff --git a/rpython/rtyper/lltypesystem/llarena.py b/rpython/rtyper/lltypesystem/llarena.py --- a/rpython/rtyper/lltypesystem/llarena.py +++ b/rpython/rtyper/lltypesystem/llarena.py @@ -355,7 +355,7 @@ For debugging this can check that reserved ranges of bytes don't overlap. The size must be symbolic; in non-translated version this is used to know what type of lltype object to allocate.""" - from rpython.rtyper.memory.lltypelayout import memory_alignment + from rpython.memory.lltypelayout import memory_alignment addr = getfakearenaaddress(addr) letter = 'x' if llmemory.raw_malloc_usage(size) == 1: diff --git a/rpython/rtyper/lltypesystem/llmemory.py b/rpython/rtyper/lltypesystem/llmemory.py --- a/rpython/rtyper/lltypesystem/llmemory.py +++ b/rpython/rtyper/lltypesystem/llmemory.py @@ -798,7 +798,7 @@ def raw_free(adr): # try to free the whole object if 'adr' is the address of the header - from rpython.rtyper.memory.gcheader import GCHeaderBuilder + from rpython.memory.gcheader import GCHeaderBuilder try: objectptr = GCHeaderBuilder.object_from_header(adr.ptr) except KeyError: @@ -811,7 +811,7 @@ def raw_malloc_usage(size): if isinstance(size, AddressOffset): # ouah - from rpython.rtyper.memory.lltypelayout import convert_offset_to_int + from rpython.memory.lltypelayout import convert_offset_to_int size = convert_offset_to_int(size) return size diff --git a/rpython/rtyper/lltypesystem/rdict.py b/rpython/rtyper/lltypesystem/rdict.py --- a/rpython/rtyper/lltypesystem/rdict.py +++ b/rpython/rtyper/lltypesystem/rdict.py @@ -665,7 +665,7 @@ d.resize_counter = n * 2 return d -# rpython.rtyper.memory.lldict uses a dict based on Struct and Array +# rpython.memory.lldict uses a dict based on Struct and Array # instead of GcStruct and GcArray, which is done by using different # 'allocate' and 'delete' adtmethod implementations than the ones below def _ll_malloc_dict(DICT): diff --git a/rpython/rtyper/lltypesystem/test/test_llarena.py b/rpython/rtyper/lltypesystem/test/test_llarena.py --- a/rpython/rtyper/lltypesystem/test/test_llarena.py +++ b/rpython/rtyper/lltypesystem/test/test_llarena.py @@ -220,7 +220,7 @@ assert llmemory.cast_adr_to_int(a+1) == llmemory.cast_adr_to_int(a1) + 1 def test_replace_object_with_stub(): - from rpython.rtyper.memory.gcheader import GCHeaderBuilder + from rpython.memory.gcheader import GCHeaderBuilder HDR = lltype.Struct('HDR', ('x', lltype.Signed)) S = lltype.GcStruct('S', ('y', lltype.Signed), ('z', lltype.Signed)) STUB = lltype.GcStruct('STUB', ('t', lltype.Char)) @@ -271,7 +271,7 @@ assert res == 42 def test_shrink_obj(): - from rpython.rtyper.memory.gcheader import GCHeaderBuilder + from rpython.memory.gcheader import GCHeaderBuilder HDR = lltype.Struct('HDR', ('h', lltype.Signed)) gcheaderbuilder = GCHeaderBuilder(HDR) size_gc_header = gcheaderbuilder.size_gc_header diff --git a/rpython/rtyper/lltypesystem/test/test_llmemory.py b/rpython/rtyper/lltypesystem/test/test_llmemory.py --- a/rpython/rtyper/lltypesystem/test/test_llmemory.py +++ b/rpython/rtyper/lltypesystem/test/test_llmemory.py @@ -362,7 +362,7 @@ py.test.raises(IndexError, "item_adr.signed[0]") def test_raw_malloc_gcstruct(): - from rpython.rtyper.memory import gcheader + from rpython.memory import gcheader HDR = lltype.Struct('header', ('a', lltype.Signed)) builder = gcheader.GCHeaderBuilder(HDR) gchdr = builder.size_gc_header @@ -445,7 +445,7 @@ str(p_u) def test_raw_free_with_hdr(): - from rpython.rtyper.memory.gcheader import GCHeaderBuilder + from rpython.memory.gcheader import GCHeaderBuilder HDR = lltype.Struct('h', ('t', lltype.Signed)) gh = GCHeaderBuilder(HDR).size_gc_header diff --git a/rpython/rtyper/test/test_nongc.py b/rpython/rtyper/test/test_nongc.py --- a/rpython/rtyper/test/test_nongc.py +++ b/rpython/rtyper/test/test_nongc.py @@ -230,6 +230,6 @@ assert isinstance(s, annmodel.SomeAddress) rtyper = RPythonTyper(a) rtyper.specialize() -## from rpython.rtyper.memory.lladdress import _address +## from rpython.memory.lladdress import _address ## res = interpret(malloc_and_free, [_address()]) ## assert res == _address() diff --git a/rpython/translator/backendopt/test/test_removenoops.py b/rpython/translator/backendopt/test/test_removenoops.py --- a/rpython/translator/backendopt/test/test_removenoops.py +++ b/rpython/translator/backendopt/test/test_removenoops.py @@ -2,7 +2,7 @@ remove_unaryops, remove_duplicate_casts from rpython.translator.backendopt.inline import simple_inline_function from rpython.translator.translator import TranslationContext, graphof -from rpython.rtyper.memory.gctransform.test.test_transform import getops +from rpython.memory.gctransform.test.test_transform import getops from rpython.translator.test.snippet import simple_method from rpython.translator.backendopt.all import backend_optimizations from rpython.translator.backendopt.all import INLINE_THRESHOLD_FOR_TEST diff --git a/rpython/translator/c/gc.py b/rpython/translator/c/gc.py --- a/rpython/translator/c/gc.py +++ b/rpython/translator/c/gc.py @@ -103,7 +103,7 @@ class RefcountingGcPolicy(BasicGcPolicy): def gettransformer(self): - from rpython.rtyper.memory.gctransform import refcounting + from rpython.memory.gctransform import refcounting return refcounting.RefcountingGCTransformer(self.db.translator) def common_gcheader_initdata(self, defnode): @@ -191,7 +191,7 @@ class BoehmGcPolicy(BasicGcPolicy): def gettransformer(self): - from rpython.rtyper.memory.gctransform import boehm + from rpython.memory.gctransform import boehm return boehm.BoehmGCTransformer(self.db.translator) def common_gcheader_initdata(self, defnode): @@ -244,11 +244,11 @@ yield 'boehm_gc_startup_code();' def get_real_weakref_type(self): - from rpython.rtyper.memory.gctransform import boehm + from rpython.memory.gctransform import boehm return boehm.WEAKLINK def convert_weakref_to(self, ptarget): - from rpython.rtyper.memory.gctransform import boehm + from rpython.memory.gctransform import boehm return boehm.convert_weakref_to(ptarget) def OP_GC__COLLECT(self, funcgen, op): @@ -341,11 +341,11 @@ yield '%s();' % (self.db.get(fnptr),) def get_real_weakref_type(self): - from rpython.rtyper.memory.gctypelayout import WEAKREF + from rpython.memory.gctypelayout import WEAKREF return WEAKREF def convert_weakref_to(self, ptarget): - from rpython.rtyper.memory.gctypelayout import convert_weakref_to + from rpython.memory.gctypelayout import convert_weakref_to return convert_weakref_to(ptarget) def OP_GC_RELOAD_POSSIBLY_MOVED(self, funcgen, op): @@ -434,13 +434,13 @@ class ShadowStackFrameworkGcPolicy(BasicFrameworkGcPolicy): def gettransformer(self): - from rpython.rtyper.memory.gctransform import shadowstack + from rpython.memory.gctransform import shadowstack return shadowstack.ShadowStackFrameworkGCTransformer(self.db.translator) class AsmGcRootFrameworkGcPolicy(BasicFrameworkGcPolicy): def gettransformer(self): - from rpython.rtyper.memory.gctransform import asmgcroot + from rpython.memory.gctransform import asmgcroot return asmgcroot.AsmGcRootFrameworkGCTransformer(self.db.translator) def GC_KEEPALIVE(self, funcgen, v): diff --git a/rpython/translator/c/test/test_newgc.py b/rpython/translator/c/test/test_newgc.py --- a/rpython/translator/c/test/test_newgc.py +++ b/rpython/translator/c/test/test_newgc.py @@ -11,7 +11,7 @@ from rpython.rlib.rstring import StringBuilder from rpython.rtyper.lltypesystem import lltype, llmemory, rffi from rpython.rtyper.lltypesystem.lloperation import llop -from rpython.rtyper.memory.test import snippet +from rpython.memory.test import snippet from rpython.tool.udir import udir from rpython.translator.interactive import Translation diff --git a/rpython/translator/test/test_stackcheck.py b/rpython/translator/test/test_stackcheck.py --- a/rpython/translator/test/test_stackcheck.py +++ b/rpython/translator/test/test_stackcheck.py @@ -2,7 +2,7 @@ from rpython.translator.translator import TranslationContext, graphof from rpython.translator.backendopt.all import backend_optimizations from rpython.translator.transform import insert_ll_stackcheck -from rpython.rtyper.memory.gctransform import shadowstack +from rpython.memory.gctransform import shadowstack def _follow_path_naive(block, cur_path, accum): cur_path = (cur_path, block) @@ -95,7 +95,7 @@ check(f_graph, 'f') class GCTransform(shadowstack.ShadowStackFrameworkGCTransformer): - from rpython.rtyper.memory.gc.generation import GenerationGC as \ + from rpython.memory.gc.generation import GenerationGC as \ GCClass GC_PARAMS = {} diff --git a/rpython/translator/tool/lltracker.py b/rpython/translator/tool/lltracker.py --- a/rpython/translator/tool/lltracker.py +++ b/rpython/translator/tool/lltracker.py @@ -5,7 +5,7 @@ import sys, os import gc from rpython.rtyper.lltypesystem import lltype, llmemory -from rpython.rtyper.memory.gcheader import header2obj +from rpython.memory.gcheader import header2obj from rpython.translator.tool.reftracker import BaseRefTrackerPage, MARKER from rpython.tool.uid import uid from rpython.tool.identity_dict import identity_dict diff --git a/rpython/translator/tool/staticsizereport.py b/rpython/translator/tool/staticsizereport.py --- a/rpython/translator/tool/staticsizereport.py +++ b/rpython/translator/tool/staticsizereport.py @@ -4,7 +4,7 @@ from rpython.tool.ansicolor import red, yellow, green from rpython.rtyper.lltypesystem.lltype import typeOf, _ptr, Ptr, ContainerType from rpython.rtyper.lltypesystem import llmemory -from rpython.rtyper.memory.lltypelayout import convert_offset_to_int +from rpython.memory.lltypelayout import convert_offset_to_int class Info: pass From noreply at buildbot.pypy.org Sat Feb 23 11:13:37 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sat, 23 Feb 2013 11:13:37 +0100 (CET) Subject: [pypy-commit] pypy stm-thread-2: hg merge default Message-ID: <20130223101337.8A32B1C008F@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stm-thread-2 Changeset: r61653:243ae6541766 Date: 2013-02-23 11:12 +0100 http://bitbucket.org/pypy/pypy/changeset/243ae6541766/ Log: hg merge default diff too long, truncating to 2000 out of 7199 lines diff --git a/lib_pypy/datetime.py b/lib_pypy/datetime.py --- a/lib_pypy/datetime.py +++ b/lib_pypy/datetime.py @@ -271,6 +271,8 @@ raise ValueError("%s()=%d, must be in -1439..1439" % (name, offset)) def _check_int_field(value): + if isinstance(value, int): + return value if not isinstance(value, float): try: value = value.__int__() @@ -279,7 +281,7 @@ else: if isinstance(value, (int, long)): return value - raise TypeError('integer argument expected') + raise TypeError('an integer is required') def _check_date_fields(year, month, day): year = _check_int_field(year) @@ -457,6 +459,8 @@ felt like it. """ + __slots__ = '_days', '_seconds', '_microseconds' + def __new__(cls, days=0, seconds=0, microseconds=0, # XXX The following should only be used as keyword args: milliseconds=0, minutes=0, hours=0, weeks=0): @@ -770,6 +774,8 @@ year, month, day """ + __slots__ = '_year', '_month', '_day' + def __new__(cls, year, month=None, day=None): """Constructor. @@ -777,7 +783,7 @@ year, month, day (required, base 1) """ - if isinstance(year, str): + if isinstance(year, str) and len(year) == 4: # Pickle support self = object.__new__(cls) self.__setstate(year) @@ -1063,6 +1069,8 @@ Subclasses must override the name(), utcoffset() and dst() methods. """ + __slots__ = () + def tzname(self, dt): "datetime -> string name of time zone." raise NotImplementedError("tzinfo subclass must override tzname()") @@ -1155,6 +1163,8 @@ hour, minute, second, microsecond, tzinfo """ + __slots__ = '_hour', '_minute', '_second', '_microsecond', '_tzinfo' + def __new__(cls, hour=0, minute=0, second=0, microsecond=0, tzinfo=None): """Constructor. @@ -1457,9 +1467,11 @@ instance of a tzinfo subclass. The remaining arguments may be ints or longs. """ + __slots__ = date.__slots__ + time.__slots__ + def __new__(cls, year, month=None, day=None, hour=0, minute=0, second=0, microsecond=0, tzinfo=None): - if isinstance(year, str): + if isinstance(year, str) and len(year) == 10: # Pickle support self = date.__new__(cls, year[:4]) self.__setstate(year, month) diff --git a/lib_pypy/numpypy/__init__.py b/lib_pypy/numpypy/__init__.py --- a/lib_pypy/numpypy/__init__.py +++ b/lib_pypy/numpypy/__init__.py @@ -1,5 +1,14 @@ -from _numpypy import * -from .core import * +import core +from core import * +import lib +from lib import * + +from __builtin__ import bool, int, long, float, complex, object, unicode, str +from core import abs, max, min + +__all__ = [] +__all__ += core.__all__ +__all__ += lib.__all__ import sys sys.modules.setdefault('numpy', sys.modules['numpypy']) diff --git a/lib_pypy/numpypy/core/__init__.py b/lib_pypy/numpypy/core/__init__.py --- a/lib_pypy/numpypy/core/__init__.py +++ b/lib_pypy/numpypy/core/__init__.py @@ -1,3 +1,17 @@ -from .fromnumeric import * -from .numeric import * -from .shape_base import * +import _numpypy +from _numpypy import * +import numeric +from numeric import * +import fromnumeric +from fromnumeric import * +import shape_base +from shape_base import * + +from fromnumeric import amax as max, amin as min +from _numpypy import absolute as abs + +__all__ = [] +__all__ += _numpypy.__all__ +__all__ += numeric.__all__ +__all__ += fromnumeric.__all__ +__all__ += shape_base.__all__ diff --git a/lib_pypy/numpypy/core/fromnumeric.py b/lib_pypy/numpypy/core/fromnumeric.py --- a/lib_pypy/numpypy/core/fromnumeric.py +++ b/lib_pypy/numpypy/core/fromnumeric.py @@ -1290,7 +1290,9 @@ array([3, 4, 2, 3, 4, 5, 6, 7, 8, 8]) """ - raise NotImplementedError('Waiting on interp level method') + if not hasattr(a, 'clip'): + a = numpypy.array(a) + return a.clip(a_min, a_max, out=out) def sum(a, axis=None, dtype=None, out=None): @@ -1360,10 +1362,9 @@ """ assert dtype is None - assert out is None if not hasattr(a, "sum"): a = numpypy.array(a) - return a.sum(axis=axis) + return a.sum(axis=axis, out=out) def product (a, axis=None, dtype=None, out=None): @@ -1720,11 +1721,11 @@ 4.0 """ - assert axis is None - assert out is None if not hasattr(a, "max"): a = numpypy.array(a) - return a.max() + if a.size < 1: + return numpypy.array([]) + return a.max(axis=axis, out=out) def amin(a, axis=None, out=None): @@ -1782,12 +1783,11 @@ 0.0 """ - # amin() is equivalent to min() - assert axis is None - assert out is None if not hasattr(a, 'min'): a = numpypy.array(a) - return a.min() + if a.size < 1: + return numpypy.array([]) + return a.min(axis=axis, out=out) def alen(a): """ diff --git a/lib_pypy/numpypy/core/numeric.py b/lib_pypy/numpypy/core/numeric.py --- a/lib_pypy/numpypy/core/numeric.py +++ b/lib_pypy/numpypy/core/numeric.py @@ -1,3 +1,6 @@ +__all__ = ['asanyarray', 'base_repr', + 'array_repr', 'array_str', 'set_string_function', + 'array_equal', 'asarray', 'outer', 'identity'] from _numpypy import array, ndarray, int_, float_, bool_, flexible #, complex_# , longlong from _numpypy import concatenate @@ -501,3 +504,34 @@ a = asarray(a) b = asarray(b) return a.ravel()[:,newaxis]*b.ravel()[newaxis,:] + +def identity(n, dtype=None): + """ + Return the identity array. + + The identity array is a square array with ones on + the main diagonal. + + Parameters + ---------- + n : int + Number of rows (and columns) in `n` x `n` output. + dtype : data-type, optional + Data-type of the output. Defaults to ``float``. + + Returns + ------- + out : ndarray + `n` x `n` array with its main diagonal set to one, + and all other elements 0. + + Examples + -------- + >>> np.identity(3) + array([[ 1., 0., 0.], + [ 0., 1., 0.], + [ 0., 0., 1.]]) + + """ + from numpy import eye + return eye(n, dtype=dtype) diff --git a/lib_pypy/numpypy/core/shape_base.py b/lib_pypy/numpypy/core/shape_base.py --- a/lib_pypy/numpypy/core/shape_base.py +++ b/lib_pypy/numpypy/core/shape_base.py @@ -1,3 +1,5 @@ +__all__ = ['atleast_1d', 'atleast_2d', 'atleast_3d', 'vstack', 'hstack'] + import _numpypy from numeric import array, asanyarray, newaxis @@ -271,53 +273,3 @@ return _numpypy.concatenate(arrs, 0) else: return _numpypy.concatenate(arrs, 1) - -def dstack(tup): - """ - Stack arrays in sequence depth wise (along third axis). - - Takes a sequence of arrays and stack them along the third axis - to make a single array. Rebuilds arrays divided by `dsplit`. - This is a simple way to stack 2D arrays (images) into a single - 3D array for processing. - - Parameters - ---------- - tup : sequence of arrays - Arrays to stack. All of them must have the same shape along all - but the third axis. - - Returns - ------- - stacked : ndarray - The array formed by stacking the given arrays. - - See Also - -------- - vstack : Stack along first axis. - hstack : Stack along second axis. - concatenate : Join arrays. - dsplit : Split array along third axis. - - Notes - ----- - Equivalent to ``np.concatenate(tup, axis=2)``. - - Examples - -------- - >>> a = np.array((1,2,3)) - >>> b = np.array((2,3,4)) - >>> np.dstack((a,b)) - array([[[1, 2], - [2, 3], - [3, 4]]]) - - >>> a = np.array([[1],[2],[3]]) - >>> b = np.array([[2],[3],[4]]) - >>> np.dstack((a,b)) - array([[[1, 2]], - [[2, 3]], - [[3, 4]]]) - - """ - return _numpypy.concatenate(map(atleast_3d,tup),2) diff --git a/lib_pypy/numpypy/lib/__init__.py b/lib_pypy/numpypy/lib/__init__.py new file mode 100644 --- /dev/null +++ b/lib_pypy/numpypy/lib/__init__.py @@ -0,0 +1,11 @@ +import function_base +from function_base import * +import shape_base +from shape_base import * +import twodim_base +from twodim_base import * + +__all__ = [] +__all__ += function_base.__all__ +__all__ += shape_base.__all__ +__all__ += twodim_base.__all__ diff --git a/lib_pypy/numpypy/lib/function_base.py b/lib_pypy/numpypy/lib/function_base.py new file mode 100644 --- /dev/null +++ b/lib_pypy/numpypy/lib/function_base.py @@ -0,0 +1,10 @@ +__all__ = ['average'] + +from _numpypy import array + +def average(a): + # This implements a weighted average, for now we don't implement the + # weighting, just the average part! + if not hasattr(a, "mean"): + a = array(a) + return a.mean() diff --git a/lib_pypy/numpypy/lib/shape_base.py b/lib_pypy/numpypy/lib/shape_base.py new file mode 100644 --- /dev/null +++ b/lib_pypy/numpypy/lib/shape_base.py @@ -0,0 +1,54 @@ +__all__ = ['dstack'] + +import numpypy.core.numeric as _nx +from numpypy.core import atleast_3d + +def dstack(tup): + """ + Stack arrays in sequence depth wise (along third axis). + + Takes a sequence of arrays and stack them along the third axis + to make a single array. Rebuilds arrays divided by `dsplit`. + This is a simple way to stack 2D arrays (images) into a single + 3D array for processing. + + Parameters + ---------- + tup : sequence of arrays + Arrays to stack. All of them must have the same shape along all + but the third axis. + + Returns + ------- + stacked : ndarray + The array formed by stacking the given arrays. + + See Also + -------- + vstack : Stack along first axis. + hstack : Stack along second axis. + concatenate : Join arrays. + dsplit : Split array along third axis. + + Notes + ----- + Equivalent to ``np.concatenate(tup, axis=2)``. + + Examples + -------- + >>> a = np.array((1,2,3)) + >>> b = np.array((2,3,4)) + >>> np.dstack((a,b)) + array([[[1, 2], + [2, 3], + [3, 4]]]) + + >>> a = np.array([[1],[2],[3]]) + >>> b = np.array([[2],[3],[4]]) + >>> np.dstack((a,b)) + array([[[1, 2]], + [[2, 3]], + [[3, 4]]]) + + """ + return _nx.concatenate(map(atleast_3d,tup),2) diff --git a/lib_pypy/numpypy/lib/twodim_base.py b/lib_pypy/numpypy/lib/twodim_base.py new file mode 100644 --- /dev/null +++ b/lib_pypy/numpypy/lib/twodim_base.py @@ -0,0 +1,54 @@ +__all__ = ['eye'] + +from _numpypy import zeros + +def eye(N, M=None, k=0, dtype=float): + """ + Return a 2-D array with ones on the diagonal and zeros elsewhere. + + Parameters + ---------- + N : int + Number of rows in the output. + M : int, optional + Number of columns in the output. If None, defaults to `N`. + k : int, optional + Index of the diagonal: 0 (the default) refers to the main diagonal, + a positive value refers to an upper diagonal, and a negative value + to a lower diagonal. + dtype : data-type, optional + Data-type of the returned array. + + Returns + ------- + I : ndarray of shape (N,M) + An array where all elements are equal to zero, except for the `k`-th + diagonal, whose values are equal to one. + + See Also + -------- + identity : (almost) equivalent function + diag : diagonal 2-D array from a 1-D array specified by the user. + + Examples + -------- + >>> np.eye(2, dtype=int) + array([[1, 0], + [0, 1]]) + >>> np.eye(3, k=1) + array([[ 0., 1., 0.], + [ 0., 0., 1.], + [ 0., 0., 0.]]) + + """ + if M is None: + M = N + m = zeros((N, M), dtype=dtype) + if k >= M: + return m + if k >= 0: + i = k + else: + i = (-k) * M + m[:M-k].flat[i::M+1] = 1 + return m diff --git a/pypy/doc/_ref.txt b/pypy/doc/_ref.txt --- a/pypy/doc/_ref.txt +++ b/pypy/doc/_ref.txt @@ -1,5 +1,5 @@ .. _`ctypes_configure/doc/sample.py`: https://bitbucket.org/pypy/pypy/src/default/ctypes_configure/doc/sample.py -.. _`demo/`: https://bitbucket.org/pypy/pypy/src/default/demo/ +.. _`dotviewer/`: https://bitbucket.org/pypy/pypy/src/default/dotviewer/ .. _`lib-python/`: https://bitbucket.org/pypy/pypy/src/default/lib-python/ .. _`lib-python/2.7/dis.py`: https://bitbucket.org/pypy/pypy/src/default/lib-python/2.7/dis.py .. _`lib_pypy/`: https://bitbucket.org/pypy/pypy/src/default/lib_pypy/ @@ -7,19 +7,14 @@ .. _`lib_pypy/pypy_test/`: https://bitbucket.org/pypy/pypy/src/default/lib_pypy/pypy_test/ .. _`lib_pypy/tputil.py`: https://bitbucket.org/pypy/pypy/src/default/lib_pypy/tputil.py .. _`lib_pypy/transaction.py`: https://bitbucket.org/pypy/pypy/src/default/lib_pypy/transaction.py -.. _`pypy/annotation`: -.. _`pypy/annotation/`: https://bitbucket.org/pypy/pypy/src/default/pypy/annotation/ -.. _`pypy/annotation/annrpython.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/annotation/annrpython.py -.. _`pypy/annotation/binaryop.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/annotation/binaryop.py -.. _`pypy/annotation/builtin.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/annotation/builtin.py .. _`pypy/bin/`: https://bitbucket.org/pypy/pypy/src/default/pypy/bin/ -.. _`pypy/bin/translatorshell.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/bin/translatorshell.py +.. _`pypy/bin/pyinteractive.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/bin/pyinteractive.py .. _`pypy/config/`: https://bitbucket.org/pypy/pypy/src/default/pypy/config/ .. _`pypy/config/pypyoption.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/config/pypyoption.py -.. _`pypy/config/translationoption.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/config/translationoption.py .. _`pypy/doc/`: https://bitbucket.org/pypy/pypy/src/default/pypy/doc/ .. _`pypy/doc/config/`: https://bitbucket.org/pypy/pypy/src/default/pypy/doc/config/ .. _`pypy/doc/discussion/`: https://bitbucket.org/pypy/pypy/src/default/pypy/doc/discussion/ +.. _`pypy/goal/`: https://bitbucket.org/pypy/pypy/src/default/pypy/goal/ .. _`pypy/interpreter`: .. _`pypy/interpreter/`: https://bitbucket.org/pypy/pypy/src/default/pypy/interpreter/ .. _`pypy/interpreter/argument.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/interpreter/argument.py @@ -55,11 +50,8 @@ .. _`pypy/module`: .. _`pypy/module/`: https://bitbucket.org/pypy/pypy/src/default/pypy/module/ .. _`pypy/module/__builtin__/__init__.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/module/__builtin__/__init__.py -.. _`pypy/objspace`: .. _`pypy/objspace/`: https://bitbucket.org/pypy/pypy/src/default/pypy/objspace/ -.. _`pypy/objspace/flow`: .. _`pypy/objspace/flow/`: https://bitbucket.org/pypy/pypy/src/default/pypy/objspace/flow/ -.. _`pypy/objspace/flow/model.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/objspace/flow/model.py .. _`pypy/objspace/std`: .. _`pypy/objspace/std/`: https://bitbucket.org/pypy/pypy/src/default/pypy/objspace/std/ .. _`pypy/objspace/std/listtype.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/objspace/std/listtype.py @@ -71,49 +63,55 @@ .. _`pypy/objspace/std/transparent.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/objspace/std/transparent.py .. _`pypy/objspace/std/tupleobject.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/objspace/std/tupleobject.py .. _`pypy/objspace/std/tupletype.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/objspace/std/tupletype.py -.. _`pypy/rlib`: -.. _`pypy/rlib/`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/ -.. _`pypy/rlib/listsort.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/listsort.py -.. _`pypy/rlib/nonconst.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/nonconst.py -.. _`pypy/rlib/objectmodel.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/objectmodel.py -.. _`pypy/rlib/parsing/`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/parsing/ -.. _`pypy/rlib/parsing/tree.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/parsing/tree.py -.. _`pypy/rlib/rarithmetic.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/rarithmetic.py -.. _`pypy/rlib/rbigint.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/rbigint.py -.. _`pypy/rlib/rrandom.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/rrandom.py -.. _`pypy/rlib/rsocket.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/rsocket.py -.. _`pypy/rlib/streamio.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/streamio.py -.. _`pypy/rlib/test`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/test/ -.. _`pypy/rlib/unroll.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rlib/unroll.py -.. _`pypy/rpython`: -.. _`pypy/rpython/`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/ -.. _`pypy/rpython/lltypesystem/`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/lltypesystem/ -.. _`pypy/rpython/lltypesystem/lltype.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/lltypesystem/lltype.py -.. _`pypy/rpython/memory/`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/memory/ -.. _`pypy/rpython/memory/gc/generation.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/memory/gc/generation.py -.. _`pypy/rpython/memory/gc/hybrid.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/memory/gc/hybrid.py -.. _`pypy/rpython/memory/gc/markcompact.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/memory/gc/markcompact.py -.. _`pypy/rpython/memory/gc/marksweep.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/memory/gc/marksweep.py -.. _`pypy/rpython/memory/gc/minimarkpage.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/memory/gc/minimarkpage.py -.. _`pypy/rpython/memory/gc/semispace.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/memory/gc/semispace.py -.. _`pypy/rpython/ootypesystem/`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/ootypesystem/ -.. _`pypy/rpython/ootypesystem/ootype.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/ootypesystem/ootype.py -.. _`pypy/rpython/rint.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/rint.py -.. _`pypy/rpython/rlist.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/rlist.py -.. _`pypy/rpython/rmodel.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/rmodel.py -.. _`pypy/rpython/rtyper.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/rtyper.py -.. _`pypy/rpython/test/test_llinterp.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/rpython/test/test_llinterp.py .. _`pypy/tool/`: https://bitbucket.org/pypy/pypy/src/default/pypy/tool/ .. _`pypy/tool/algo/`: https://bitbucket.org/pypy/pypy/src/default/pypy/tool/algo/ .. _`pypy/tool/pytest/`: https://bitbucket.org/pypy/pypy/src/default/pypy/tool/pytest/ -.. _`pypy/tool/traceconfig.py`: https://bitbucket.org/pypy/pypy/src/default/pypy/tool/traceconfig.py -.. _`pypy/translator`: -.. _`pypy/translator/`: https://bitbucket.org/pypy/pypy/src/default/pypy/translator/ -.. _`pypy/translator/backendopt/`: https://bitbucket.org/pypy/pypy/src/default/pypy/translator/backendopt/ -.. _`pypy/translator/c/`: https://bitbucket.org/pypy/pypy/src/default/pypy/translator/c/ -.. _`pypy/translator/c/src/stacklet/`: https://bitbucket.org/pypy/pypy/src/default/pypy/translator/c/src/stacklet/ -.. _`pypy/translator/c/src/stacklet/stacklet.h`: https://bitbucket.org/pypy/pypy/src/default/pypy/translator/c/src/stacklet/stacklet.h -.. _`pypy/translator/cli/`: https://bitbucket.org/pypy/pypy/src/default/pypy/translator/cli/ -.. _`pypy/translator/goal/`: https://bitbucket.org/pypy/pypy/src/default/pypy/translator/goal/ -.. _`pypy/translator/jvm/`: https://bitbucket.org/pypy/pypy/src/default/pypy/translator/jvm/ -.. _`pypy/translator/tool/`: https://bitbucket.org/pypy/pypy/src/default/pypy/translator/tool/ +.. _`rpython/annotator`: +.. _`rpython/annotator/`: https://bitbucket.org/pypy/pypy/src/default/rpython/annotator/ +.. _`rpython/annotator/annrpython.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/annotator/annrpython.py +.. _`rpython/annotator/binaryop.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/annotator/binaryop.py +.. _`rpython/annotator/builtin.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/annotator/builtin.py +.. _`rpython/bin/translatorshell.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/bin/translatorshell.py +.. _`rpython/config/`: https://bitbucket.org/pypy/pypy/src/default/rpython/config/ +.. _`rpython/config/translationoption.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/config/translationoption.py +.. _`rpython/flowspace/`: https://bitbucket.org/pypy/pypy/src/default/rpython/flowspace/ +.. _`rpython/flowspace/model.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/flowspace/model.py +.. _`rpython/rlib`: +.. _`rpython/rlib/`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/ +.. _`rpython/rlib/listsort.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/listsort.py +.. _`rpython/rlib/nonconst.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/nonconst.py +.. _`rpython/rlib/objectmodel.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/objectmodel.py +.. _`rpython/rlib/parsing/`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/parsing/ +.. _`rpython/rlib/parsing/tree.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/parsing/tree.py +.. _`rpython/rlib/rarithmetic.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/rarithmetic.py +.. _`rpython/rlib/rbigint.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/rbigint.py +.. _`rpython/rlib/rrandom.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/rrandom.py +.. _`rpython/rlib/rsocket.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/rsocket.py +.. _`rpython/rlib/streamio.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/streamio.py +.. _`rpython/rlib/test`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/test/ +.. _`rpython/rlib/unroll.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rlib/unroll.py +.. _`rpython/rtyper`: +.. _`rpython/rtyper/`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/ +.. _`rpython/rtyper/lltypesystem/`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/lltypesystem/ +.. _`rpython/rtyper/lltypesystem/lltype.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/lltypesystem/lltype.py +.. _`rpython/rtyper/memory/`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/memory/ +.. _`rpython/rtyper/memory/gc/generation.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/memory/gc/generation.py +.. _`rpython/rtyper/memory/gc/hybrid.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/memory/gc/hybrid.py +.. _`rpython/rtyper/memory/gc/minimarkpage.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/memory/gc/minimarkpage.py +.. _`rpython/rtyper/memory/gc/semispace.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/memory/gc/semispace.py +.. _`rpython/rtyper/ootypesystem/`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/ootypesystem/ +.. _`rpython/rtyper/ootypesystem/ootype.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/ootypesystem/ootype.py +.. _`rpython/rtyper/rint.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/rint.py +.. _`rpython/rtyper/rlist.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/rlist.py +.. _`rpython/rtyper/rmodel.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/rmodel.py +.. _`rpython/rtyper/rtyper.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/rtyper.py +.. _`rpython/rtyper/test/test_llinterp.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/test/test_llinterp.py +.. _`rpython/translator`: +.. _`rpython/translator/`: https://bitbucket.org/pypy/pypy/src/default/rpython/translator/ +.. _`rpython/translator/backendopt/`: https://bitbucket.org/pypy/pypy/src/default/rpython/translator/backendopt/ +.. _`rpython/translator/c/`: https://bitbucket.org/pypy/pypy/src/default/rpython/translator/c/ +.. _`rpython/translator/c/src/stacklet/`: https://bitbucket.org/pypy/pypy/src/default/rpython/translator/c/src/stacklet/ +.. _`rpython/translator/c/src/stacklet/stacklet.h`: https://bitbucket.org/pypy/pypy/src/default/rpython/translator/c/src/stacklet/stacklet.h +.. _`rpython/translator/cli/`: https://bitbucket.org/pypy/pypy/src/default/rpython/translator/cli/ +.. _`rpython/translator/jvm/`: https://bitbucket.org/pypy/pypy/src/default/rpython/translator/jvm/ +.. _`rpython/translator/tool/`: https://bitbucket.org/pypy/pypy/src/default/rpython/translator/tool/ diff --git a/pypy/doc/coding-guide.rst b/pypy/doc/coding-guide.rst --- a/pypy/doc/coding-guide.rst +++ b/pypy/doc/coding-guide.rst @@ -303,7 +303,7 @@ dicts with a unique key type only, provided it is hashable. Custom hash functions and custom equality will not be honored. - Use ``pypy.rlib.objectmodel.r_dict`` for custom hash functions. + Use ``rpython.rlib.objectmodel.r_dict`` for custom hash functions. **list comprehensions** @@ -328,7 +328,7 @@ **builtin functions** A number of builtin functions can be used. The precise set can be - found in `pypy/annotation/builtin.py`_ (see ``def builtin_xxx()``). + found in `rpython/annotator/builtin.py`_ (see ``def builtin_xxx()``). Some builtin functions may be limited in what they support, though. ``int, float, str, ord, chr``... are available as simple conversion @@ -365,7 +365,7 @@ We use normal integers for signed arithmetic. It means that before translation we get longs in case of overflow, and after translation we get a silent wrap-around. Whenever we need more control, we use the following -helpers (which live the `pypy/rlib/rarithmetic.py`_): +helpers (which live in `rpython/rlib/rarithmetic.py`_): **ovfcheck()** diff --git a/pypy/doc/configuration.rst b/pypy/doc/configuration.rst --- a/pypy/doc/configuration.rst +++ b/pypy/doc/configuration.rst @@ -188,7 +188,7 @@ toolchain`_ toolchain, have two separate sets of options. The translation toolchain options can be found on the ``config`` attribute of all ``TranslationContext`` -instances and are described in `pypy/config/translationoption.py`_. The interpreter options +instances and are described in `rpython/config/translationoption.py`_. The interpreter options are attached to the object space, also under the name ``config`` and are described in `pypy/config/pypyoption.py`_. diff --git a/pypy/doc/ctypes-implementation.rst b/pypy/doc/ctypes-implementation.rst --- a/pypy/doc/ctypes-implementation.rst +++ b/pypy/doc/ctypes-implementation.rst @@ -38,7 +38,7 @@ in dynamic libraries through libffi. Freeing objects in most cases and making sure that objects referring to each other are kept alive is responsibility of the higher levels. -This module uses bindings to libffi which are defined in ``pypy/rlib/libffi.py``. +This module uses bindings to libffi which are defined in ``rpython/rlib/libffi.py``. We tried to keep this module as small as possible. It is conceivable that other implementations (e.g. Jython) could use our ctypes diff --git a/pypy/doc/discussion/improve-rpython.rst b/pypy/doc/discussion/improve-rpython.rst --- a/pypy/doc/discussion/improve-rpython.rst +++ b/pypy/doc/discussion/improve-rpython.rst @@ -39,7 +39,7 @@ - Allocate variables on the stack, and pass their address ("by reference") to llexternal functions. For a typical usage, see - `pypy.rlib.rsocket.RSocket.getsockopt_int`. + `rpython.rlib.rsocket.RSocket.getsockopt_int`. Extensible type system for llexternal ------------------------------------- diff --git a/pypy/doc/garbage_collection.rst b/pypy/doc/garbage_collection.rst --- a/pypy/doc/garbage_collection.rst +++ b/pypy/doc/garbage_collection.rst @@ -42,7 +42,7 @@ Two arenas of equal size, with only one arena in use and getting filled with new objects. When the arena is full, the live objects are copied into the other arena using Cheney's algorithm. The old arena is then -cleared. See `pypy/rpython/memory/gc/semispace.py`_. +cleared. See `rpython/memory/gc/semispace.py`_. On Unix the clearing is done by reading ``/dev/zero`` into the arena, which is extremely memory efficient at least on Linux: it lets the @@ -55,7 +55,7 @@ Generational GC --------------- -This is a two-generations GC. See `pypy/rpython/memory/gc/generation.py`_. +This is a two-generations GC. See `rpython/memory/gc/generation.py`_. It is implemented as a subclass of the Semispace copying collector. It adds a nursery, which is a chunk of the current semispace. Its size is @@ -86,7 +86,7 @@ Each generation is collected much less often than the previous one. The division of the generations is slightly more complicated than just nursery / semispace / external; see the diagram at the start of the -source code, in `pypy/rpython/memory/gc/hybrid.py`_. +source code, in `rpython/memory/gc/hybrid.py`_. Mark & Compact GC ----------------- @@ -161,7 +161,7 @@ to the old stage. The dying case 2 objects are immediately freed. - The old stage is an area of memory containing old (small) objects. It - is handled by `pypy/rpython/memory/gc/minimarkpage.py`_. It is organized + is handled by `rpython/memory/gc/minimarkpage.py`_. It is organized as "arenas" of 256KB or 512KB, subdivided into "pages" of 4KB or 8KB. Each page can either be free, or contain small objects of all the same size. Furthermore at any point in time each object location can be diff --git a/pypy/doc/getting-started-dev.rst b/pypy/doc/getting-started-dev.rst --- a/pypy/doc/getting-started-dev.rst +++ b/pypy/doc/getting-started-dev.rst @@ -58,8 +58,7 @@ only use low level types that are available in C (e.g. int). The compiled version is now in a ``.so`` library. You can run it say using ctypes: - >>> from ctypes import CDLL - >>> f = CDLL(lib) + >>> f = get_c_function(lib, snippet.is_perfect_number) >>> f(5) 0 >>> f(6) @@ -173,23 +172,23 @@ ``xxxobject.py`` contain respectively the definition of the type and its (default) implementation. -* `pypy/translator`_ contains the code analysis and generation stuff. +* `rpython/translator`_ contains the code analysis and generation stuff. Start reading from translator.py, from which it should be easy to follow the pieces of code involved in the various translation phases. -* `pypy/annotation`_ contains the data model for the type annotation that +* `rpython/annotator`_ contains the data model for the type annotation that can be inferred about a graph. The graph "walker" that uses this is in - `pypy/annotation/annrpython.py`_. + `rpython/annotator/annrpython.py`_. -* `pypy/rpython`_ contains the code of the RPython typer. The typer transforms +* `rpython/rtyper`_ contains the code of the RPython typer. The typer transforms annotated flow graphs in a way that makes them very similar to C code so that they can be easy translated. The graph transformations are controlled - by the code in `pypy/rpython/rtyper.py`_. The object model that is used can - be found in `pypy/rpython/lltypesystem/lltype.py`_. For each RPython type + by the code in `rpython/rtyper/rtyper.py`_. The object model that is used can + be found in `rpython/rtyper/lltypesystem/lltype.py`_. For each RPython type there is a file rxxxx.py that contains the low level functions needed for this type. -* `pypy/rlib`_ contains the `RPython standard library`_, things that you can +* `rpython/rlib`_ contains the `RPython standard library`_, things that you can use from rpython. .. _`RPython standard library`: rlib.html @@ -320,10 +319,10 @@ Demos ------- -The `demo/`_ directory contains examples of various aspects of PyPy, -ranging from running regular Python programs (that we used as compliance goals) -over experimental distribution mechanisms to examples translating -sufficiently static programs into low level code. +The `example-interpreter`_ repository contains an example interpreter +written using the RPython translation toolchain. + +.. _`example-interpreter`: https://bitbucket.org/pypy/example-interpreter Additional Tools for running (and hacking) PyPy ----------------------------------------------- diff --git a/pypy/doc/index.rst b/pypy/doc/index.rst --- a/pypy/doc/index.rst +++ b/pypy/doc/index.rst @@ -217,17 +217,20 @@ Here is a fully referenced alphabetical two-level deep directory overview of PyPy: -================================ =========================================== +================================= ============================================ Directory explanation/links -================================ =========================================== +================================= ============================================ +`pypy/bin/`_ command-line scripts, mainly + `pypy/bin/pyinteractive.py`_ -`pypy/bin/`_ command-line scripts, mainly `pyinteractive.py`_ +`pypy/config/`_ handles the numerous options for building + and running PyPy -`pypy/config/`_ handles the numerous options for building and running PyPy +`pypy/doc/`_ text versions of PyPy developer + documentation -`pypy/doc/`_ text versions of PyPy developer documentation - -`pypy/doc/config/`_ documentation for the numerous translation options +`pypy/doc/config/`_ documentation for the numerous translation + options `pypy/doc/discussion/`_ drafts of ideas and documentation @@ -238,19 +241,24 @@ `pypy/interpreter/pyparser/`_ interpreter-level Python source parser -`pypy/interpreter/astcompiler/`_ interpreter-level bytecode compiler, via an AST - representation +`pypy/interpreter/astcompiler/`_ interpreter-level bytecode compiler, + via an AST representation -`pypy/module/`_ contains `mixed modules`_ implementing core modules with +`pypy/module/`_ contains `mixed modules`_ + implementing core modules with both application and interpreter level code. - Not all are finished and working. Use the ``--withmod-xxx`` - or ``--allworkingmodules`` translation options. + Not all are finished and working. Use + the ``--withmod-xxx`` + or ``--allworkingmodules`` translation + options. `pypy/objspace/`_ `object space`_ implementations -`pypy/objspace/std/`_ the StdObjSpace_ implementing CPython's objects and types +`pypy/objspace/std/`_ the StdObjSpace_ implementing CPython's + objects and types -`pypy/tool/`_ various utilities and hacks used from various places +`pypy/tool/`_ various utilities and hacks used + from various places `pypy/tool/algo/`_ general-purpose algorithmic and mathematic tools @@ -258,49 +266,58 @@ `pypy/tool/pytest/`_ support code for our `testing methods`_ -`rpython/annotator/`_ `type inferencing code`_ for `RPython`_ programs +`rpython/annotator/`_ `type inferencing code`_ for + `RPython`_ programs `rpython/config/`_ handles the numerous options for RPython -`rpython/flowspace/`_ the FlowObjSpace_ implementing `abstract interpretation`_ +`rpython/flowspace/`_ the FlowObjSpace_ implementing + `abstract interpretation`_ - -`rpython/rlib/`_ a `"standard library"`_ for RPython_ programs +`rpython/rlib/`_ a `"standard library"`_ for RPython_ + programs `rpython/rtyper/`_ the `RPython Typer`_ -`rpython/rtyper/lltypesystem/`_ the `low-level type system`_ for C-like backends +`rpython/rtyper/lltypesystem/`_ the `low-level type system`_ for + C-like backends -`rpython/rtyper/ootypesystem/`_ the `object-oriented type system`_ for OO backends +`rpython/rtyper/ootypesystem/`_ the `object-oriented type system`_ + for OO backends -`rpython/rtyper/memory/`_ the `garbage collector`_ construction framework +`rpython/memory/`_ the `garbage collector`_ construction + framework `rpython/translator/`_ translation_ backends and support code -`rpython/translator/backendopt/`_ general optimizations that run before a backend generates code +`rpython/translator/backendopt/`_ general optimizations that run before a + backend generates code -`rpython/translator/c/`_ the `GenC backend`_, producing C code from an +`rpython/translator/c/`_ the `GenC backend`_, producing C code + from an RPython program (generally via the rtyper_) -`rpython/translator/cli/`_ the `CLI backend`_ for `.NET`_ (Microsoft CLR or Mono_) +`rpython/translator/cli/`_ the `CLI backend`_ for `.NET`_ + (Microsoft CLR or Mono_) -`pypy/goal/`_ our `main PyPy-translation scripts`_ live here +`pypy/goal/`_ our `main PyPy-translation scripts`_ + live here `rpython/translator/jvm/`_ the Java backend -`rpython/translator/tool/`_ helper tools for translation, including the Pygame - `graph viewer`_ +`rpython/translator/tool/`_ helper tools for translation -``*/test/`` many directories have a test subdirectory containing test +`dotviewer/`_ `graph viewer`_ + +``*/test/`` many directories have a test subdirectory + containing test modules (see `Testing in PyPy`_) -``_cache/`` holds cache files from internally `translating application - level to interpreterlevel`_ code. -================================ =========================================== +``_cache/`` holds cache files from various purposes +================================= ============================================ .. _`bytecode interpreter`: interpreter.html -.. _`translating application level to interpreterlevel`: geninterp.html .. _`Testing in PyPy`: coding-guide.html#testing-in-pypy .. _`mixed modules`: coding-guide.html#mixed-modules .. _`modules`: coding-guide.html#modules diff --git a/pypy/doc/rlib.rst b/pypy/doc/rlib.rst --- a/pypy/doc/rlib.rst +++ b/pypy/doc/rlib.rst @@ -7,18 +7,18 @@ .. contents:: -This page lists some of the modules in `pypy/rlib`_ together with some hints +This page lists some of the modules in `rpython/rlib`_ together with some hints for what they can be used for. The modules here will make up some general library useful for RPython programs (since most of the standard library modules are not RPython). Most of these modules are somewhat rough still and are likely to change at some point. Usually it is useful to look at the tests in -`pypy/rlib/test`_ to get an impression of how to use a module. +`rpython/rlib/test`_ to get an impression of how to use a module. ``listsort`` ============ -The `pypy/rlib/listsort.py`_ module contains an implementation of the timsort sorting algorithm +The `rpython/rlib/listsort.py`_ module contains an implementation of the timsort sorting algorithm (the sort method of lists is not RPython). To use it, subclass from the ``listsort.TimSort`` class and override the ``lt`` method to change the comparison behaviour. The constructor of ``TimSort`` takes a list as an @@ -30,7 +30,7 @@ ``nonconst`` ============ -The `pypy/rlib/nonconst.py`_ module is useful mostly for tests. The `flow object space`_ and +The `rpython/rlib/nonconst.py`_ module is useful mostly for tests. The `flow object space`_ and the `annotator`_ do quite some constant folding, which is sometimes not desired in a test. To prevent constant folding on a certain value, use the ``NonConst`` class. The constructor of ``NonConst`` takes an arbitrary value. The instance of @@ -44,7 +44,7 @@ ``objectmodel`` =============== -The `pypy/rlib/objectmodel.py`_ module is a mixed bag of various functionality. Some of the +The `rpython/rlib/objectmodel.py`_ module is a mixed bag of various functionality. Some of the more useful ones are: ``ComputedIntSymbolic``: @@ -94,7 +94,7 @@ ``rarithmetic`` =============== -The `pypy/rlib/rarithmetic.py`_ module contains functionality to handle the small differences +The `rpython/rlib/rarithmetic.py`_ module contains functionality to handle the small differences in the behaviour of arithmetic code in regular Python and RPython code. Most of them are already described in the `coding guide`_ @@ -104,7 +104,7 @@ ``rbigint`` =========== -The `pypy/rlib/rbigint.py`_ module contains a full RPython implementation of the Python ``long`` +The `rpython/rlib/rbigint.py`_ module contains a full RPython implementation of the Python ``long`` type (which itself is not supported in RPython). The ``rbigint`` class contains that implementation. To construct ``rbigint`` instances use the static methods ``fromint``, ``frombool``, ``fromfloat`` and ``fromdecimalstr``. To convert back @@ -118,7 +118,7 @@ ``rrandom`` =========== -The `pypy/rlib/rrandom.py`_ module contains an implementation of the mersenne twister random +The `rpython/rlib/rrandom.py`_ module contains an implementation of the mersenne twister random number generator. It contains one class ``Random`` which most importantly has a ``random`` method which returns a pseudo-random floating point number between 0.0 and 1.0. @@ -126,7 +126,7 @@ ``rsocket`` =========== -The `pypy/rlib/rsocket.py`_ module contains an RPython implementation of the functionality of +The `rpython/rlib/rsocket.py`_ module contains an RPython implementation of the functionality of the socket standard library with a slightly different interface. The difficulty with the Python socket API is that addresses are not "well-typed" objects: depending on the address family they are tuples, or strings, and @@ -137,7 +137,7 @@ ``streamio`` ============ -The `pypy/rlib/streamio.py`_ contains an RPython stream I/O implementation (which was started +The `rpython/rlib/streamio.py`_ contains an RPython stream I/O implementation (which was started by Guido van Rossum as `sio.py`_ in the CPython sandbox as a prototype for the upcoming new file implementation in Python 3000). @@ -146,7 +146,7 @@ ``unroll`` ========== -The `pypy/rlib/unroll.py`_ module most importantly contains the function ``unrolling_iterable`` +The `rpython/rlib/unroll.py`_ module most importantly contains the function ``unrolling_iterable`` which wraps an iterator. Looping over the iterator in RPython code will not produce a loop in the resulting flow graph but will unroll the loop instead. @@ -154,7 +154,7 @@ ``parsing`` =========== -The `pypy/rlib/parsing/`_ module is a still in-development module to generate tokenizers and +The `rpython/rlib/parsing/`_ module is a still in-development module to generate tokenizers and parsers in RPython. It is still highly experimental and only really used by the `Prolog interpreter`_ (although in slightly non-standard ways). The easiest way to specify a tokenizer/grammar is to write it down using regular expressions and @@ -204,7 +204,7 @@ anything except a. To parse a regular expression and to get a matcher for it, you can use the -function ``make_runner(s)`` in the ``pypy.rlib.parsing.regexparse`` module. It +function ``make_runner(s)`` in the ``rpython.rlib.parsing.regexparse`` module. It returns a object with a ``recognize(input)`` method that returns True or False depending on whether ``input`` matches the string or not. @@ -213,7 +213,7 @@ EBNF ---- -To describe a tokenizer and a grammar the ``pypy.rlib.parsing.ebnfparse`` +To describe a tokenizer and a grammar the ``rpython.rlib.parsing.ebnfparse`` defines a syntax for doing that. The syntax file contains a sequence or rules. Every rule either describes a @@ -295,7 +295,7 @@ The parsing process builds up a tree consisting of instances of ``Symbol`` and ``Nonterminal``, the former corresponding to tokens, the latter to nonterminal -symbols. Both classes live in the `pypy/rlib/parsing/tree.py`_ module. You can use +symbols. Both classes live in the `rpython/rlib/parsing/tree.py`_ module. You can use the ``view()`` method ``Nonterminal`` instances to get a pygame view of the parse tree. @@ -310,7 +310,7 @@ ++++++++ To write tree visitors for the parse trees that are RPython, there is a special -baseclass ``RPythonVisitor`` in `pypy/rlib/parsing/tree.py`_ to use. If your +baseclass ``RPythonVisitor`` in `rpython/rlib/parsing/tree.py`_ to use. If your class uses this, it will grow a ``dispatch(node)`` method, that calls an appropriate ``visit_`` method, depending on the ``node`` argument. Here the is replaced by the ``symbol`` attribute of the visited node. diff --git a/pypy/doc/rtyper.rst b/pypy/doc/rtyper.rst --- a/pypy/doc/rtyper.rst +++ b/pypy/doc/rtyper.rst @@ -4,7 +4,7 @@ .. contents:: -The RPython Typer lives in the directory `pypy/rpython/`_. +The RPython Typer lives in the directory `rpython/rtyper/`_. Overview @@ -52,7 +52,7 @@ where -- in C notation -- all three variables v1, v2 and v3 are typed ``int``. This is done by attaching an attribute ``concretetype`` to v1, v2 and v3 (which might be instances of Variable or possibly Constant). In our model, -this ``concretetype`` is ``pypy.rpython.lltypesystem.lltype.Signed``. Of +this ``concretetype`` is ``rpython.rtyper.lltypesystem.lltype.Signed``. Of course, the purpose of replacing the operation called ``add`` with ``int_add`` is that code generators no longer have to worry about what kind of addition (or concatenation maybe?) it means. @@ -66,7 +66,7 @@ each operation. In both cases the analysis of an operation depends on the annotations of its input arguments. This is reflected in the usage of the same ``__extend__`` syntax in the source files (compare e.g. -`pypy/annotation/binaryop.py`_ and `pypy/rpython/rint.py`_). +`rpython/annotator/binaryop.py`_ and `rpython/rtyper/rint.py`_). The analogy stops here, though: while it runs, the Annotator is in the middle of computing the annotations, so it might need to reflow and generalize until @@ -104,7 +104,7 @@ implementations for the same high-level operations. This is the reason for turning representations into explicit objects. -The base Repr class is defined in `pypy/rpython/rmodel.py`_. Most of the +The base Repr class is defined in `rpython/rtyper/rmodel.py`_. Most of the ``rpython/r*.py`` files define one or a few subclasses of Repr. The method getrepr() of the RTyper will build and cache a single Repr instance per SomeXxx() instance; moreover, two SomeXxx() instances that are equal get the @@ -131,9 +131,9 @@ The RPython Typer uses a standard low-level model which we believe can correspond rather directly to various target languages such as C. This model is implemented in the first part of -`pypy/rpython/lltypesystem/lltype.py`_. +`rpython/rtyper/lltypesystem/lltype.py`_. -The second part of `pypy/rpython/lltypesystem/lltype.py`_ is a runnable +The second part of `rpython/rtyper/lltypesystem/lltype.py`_ is a runnable implementation of these types, for testing purposes. It allows us to write and test plain Python code using a malloc() function to obtain and manipulate structures and arrays. This is useful for example to implement and test @@ -147,7 +147,7 @@ Here is a quick tour: - >>> from pypy.rpython.lltypesystem.lltype import * + >>> from rpython.rtyper.lltypesystem.lltype import * Here are a few primitive low-level types, and the typeOf() function to figure them out: @@ -191,7 +191,7 @@ types like list in this elementary world. The ``malloc()`` function is a kind of placeholder, which must eventually be provided by the code generator for the target platform; but as we have just seen its Python implementation in -`pypy/rpython/lltypesystem/lltype.py`_ works too, which is primarily useful for +`rpython/rtyper/lltypesystem/lltype.py`_ works too, which is primarily useful for testing, interactive exploring, etc. The argument to ``malloc()`` is the structure type directly, but it returns a @@ -245,7 +245,7 @@ +++++++++++++++ Structure types are built as instances of -``pypy.rpython.lltypesystem.lltype.Struct``:: +``rpython.rtyper.lltypesystem.lltype.Struct``:: MyStructType = Struct('somename', ('field1', Type1), ('field2', Type2)...) MyStructType = GcStruct('somename', ('field1', Type1), ('field2', Type2)...) @@ -277,7 +277,7 @@ +++++++++++ An array type is built as an instance of -``pypy.rpython.lltypesystem.lltype.Array``:: +``rpython.rtyper.lltypesystem.lltype.Array``:: MyIntArray = Array(Signed) MyOtherArray = Array(MyItemType) @@ -316,7 +316,7 @@ with care: the bigger structure of which they are part of could be freed while the Ptr to the substructure is still in use. In general, it is a good idea to avoid passing around pointers to inlined substructures of malloc()ed structures. -(The testing implementation of `pypy/rpython/lltypesystem/lltype.py`_ checks to some +(The testing implementation of `rpython/rtyper/lltypesystem/lltype.py`_ checks to some extent that you are not trying to use a pointer to a structure after its container has been freed, using weak references. But pointers to non-GC structures are not officially meant to be weak references: using them after what @@ -429,7 +429,7 @@ change needed to the Annotator to allow it to perform type inference of our very-low-level snippets of code. -See for example `pypy/rpython/rlist.py`_. +See for example `rpython/rtyper/rlist.py`_. .. _`oo type`: @@ -441,10 +441,10 @@ targeting low level backends such as C, but it is not good enough for targeting higher level backends such as .NET CLI or Java JVM, so a new object oriented model has been introduced. This model is -implemented in the first part of `pypy/rpython/ootypesystem/ootype.py`_. +implemented in the first part of `rpython/rtyper/ootypesystem/ootype.py`_. As for the low-level typesystem, the second part of -`pypy/rpython/ootypesystem/ootype.py`_ is a runnable implementation of +`rpython/rtyper/ootypesystem/ootype.py`_ is a runnable implementation of these types, for testing purposes. @@ -751,7 +751,7 @@ The LLInterpreter is a simple piece of code that is able to interpret flow graphs. This is very useful for testing purposes, especially if you work on the RPython Typer. The most useful interface for it is the ``interpret`` -function in the file `pypy/rpython/test/test_llinterp.py`_. It takes as +function in the file `rpython/rtyper/test/test_llinterp.py`_. It takes as arguments a function and a list of arguments with which the function is supposed to be called. Then it generates the flow graph, annotates it according to the types of the arguments you passed to it and runs the diff --git a/pypy/doc/stackless.rst b/pypy/doc/stackless.rst --- a/pypy/doc/stackless.rst +++ b/pypy/doc/stackless.rst @@ -29,7 +29,7 @@ on 32-bit or a complete megabyte on 64-bit. Moreover, the feature is only available (so far) on x86 and x86-64 CPUs; for other CPUs you need to add a short page of custom assembler to -`pypy/translator/c/src/stacklet/`_. +`rpython/translator/c/src/stacklet/`_. Theory @@ -271,9 +271,9 @@ Continulets are internally implemented using stacklets, which is the generic RPython-level building block for "one-shot continuations". For more information about them please see the documentation in the C source -at `pypy/translator/c/src/stacklet/stacklet.h`_. +at `rpython/translator/c/src/stacklet/stacklet.h`_. -The module ``pypy.rlib.rstacklet`` is a thin wrapper around the above +The module ``rpython.rlib.rstacklet`` is a thin wrapper around the above functions. The key point is that new() and switch() always return a fresh stacklet handle (or an empty one), and switch() additionally consumes one. It makes no sense to have code in which the returned diff --git a/pypy/doc/tool/makeref.py b/pypy/doc/tool/makeref.py --- a/pypy/doc/tool/makeref.py +++ b/pypy/doc/tool/makeref.py @@ -1,10 +1,9 @@ import py -py.path.local(__file__) import pypy -pypydir = py.path.local(pypy.__file__).dirpath() -distdir = pypydir.dirpath() -issue_url = 'http://codespeak.net/issue/pypy-dev/' +pypydir = py.path.local(pypy.__file__).join('..') +distdir = pypydir.dirpath() +issue_url = 'http://bugs.pypy.org/issue/pypy-dev/' bitbucket_url = 'https://bitbucket.org/pypy/pypy/src/default/' import urllib2, posixpath diff --git a/pypy/doc/translation.rst b/pypy/doc/translation.rst --- a/pypy/doc/translation.rst +++ b/pypy/doc/translation.rst @@ -90,7 +90,7 @@ (although these steps are not quite as distinct as you might think from this presentation). -There is an `interactive interface`_ called `pypy/bin/translatorshell.py`_ to the +There is an `interactive interface`_ called `rpython/bin/translatorshell.py`_ to the translation process which allows you to interactively work through these stages. @@ -116,7 +116,7 @@ which are the basic data structures of the translation process. -All these types are defined in `pypy/objspace/flow/model.py`_ (which is a rather +All these types are defined in `rpython/flowspace/model.py`_ (which is a rather important module in the PyPy source base, to reinforce the point). The flow graph of a function is represented by the class ``FunctionGraph``. diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst --- a/pypy/doc/whatsnew-head.rst +++ b/pypy/doc/whatsnew-head.rst @@ -65,3 +65,10 @@ .. branch: signal-and-thread Add "__pypy__.thread.signals_enabled", a context manager. Can be used in a non-main thread to enable the processing of signal handlers in that thread. + +.. branch: coding-guide-update-rlib-refs +.. branch: rlib-doc-rpython-refs +.. branch: clean-up-remaining-pypy-rlib-refs + +.. branch: enumerate-rstr +Support enumerate() over rstr types. diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -1498,10 +1498,11 @@ ) return fd - def warn(self, msg, w_warningcls): - self.appexec([self.wrap(msg), w_warningcls], """(msg, warningcls): + def warn(self, w_msg, w_warningcls, stacklevel=2): + self.appexec([w_msg, w_warningcls, self.wrap(stacklevel)], + """(msg, warningcls, stacklevel): import _warnings - _warnings.warn(msg, warningcls, stacklevel=2) + _warnings.warn(msg, warningcls, stacklevel=stacklevel) """) diff --git a/pypy/interpreter/pycode.py b/pypy/interpreter/pycode.py --- a/pypy/interpreter/pycode.py +++ b/pypy/interpreter/pycode.py @@ -53,16 +53,17 @@ kwargname = None return Signature(argnames, varargname, kwargname) + class PyCode(eval.Code): "CPython-style code objects." _immutable_ = True _immutable_fields_ = ["co_consts_w[*]", "co_names_w[*]", "co_varnames[*]", - "co_freevars[*]", "co_cellvars[*]"] + "co_freevars[*]", "co_cellvars[*]", "_args_as_cellvars[*]"] def __init__(self, space, argcount, nlocals, stacksize, flags, code, consts, names, varnames, filename, name, firstlineno, lnotab, freevars, cellvars, - hidden_applevel=False, magic = default_magic): + hidden_applevel=False, magic=default_magic): """Initialize a new code object from parameters given by the pypy compiler""" self.space = space @@ -89,8 +90,6 @@ def _initialize(self): self._init_flags() - # Precompute what arguments need to be copied into cellvars - self._args_as_cellvars = [] if self.co_cellvars: argcount = self.co_argcount @@ -108,16 +107,22 @@ # produced by CPython are loaded by PyPy. Note that CPython # contains the following bad-looking nested loops at *every* # function call! - argvars = self.co_varnames + + # Precompute what arguments need to be copied into cellvars + args_as_cellvars = [] + argvars = self.co_varnames cellvars = self.co_cellvars for i in range(len(cellvars)): cellname = cellvars[i] for j in range(argcount): if cellname == argvars[j]: # argument j has the same name as the cell var i - while len(self._args_as_cellvars) <= i: - self._args_as_cellvars.append(-1) # pad - self._args_as_cellvars[i] = j + while len(args_as_cellvars) <= i: + args_as_cellvars.append(-1) # pad + args_as_cellvars[i] = j + self._args_as_cellvars = args_as_cellvars[:] + else: + self._args_as_cellvars = [] self._compute_flatcall() diff --git a/pypy/interpreter/pyopcode.py b/pypy/interpreter/pyopcode.py --- a/pypy/interpreter/pyopcode.py +++ b/pypy/interpreter/pyopcode.py @@ -800,17 +800,16 @@ @jit.unroll_safe def cmp_exc_match(self, w_1, w_2): - if self.space.is_true(self.space.isinstance(w_2, self.space.w_tuple)): - for w_t in self.space.fixedview(w_2): - if self.space.is_true(self.space.isinstance(w_t, - self.space.w_str)): - self.space.warn("catching of string exceptions is " - "deprecated", - self.space.w_DeprecationWarning) - elif self.space.is_true(self.space.isinstance(w_2, self.space.w_str)): - self.space.warn("catching of string exceptions is deprecated", - self.space.w_DeprecationWarning) - return self.space.newbool(self.space.exception_match(w_1, w_2)) + space = self.space + if space.is_true(space.isinstance(w_2, space.w_tuple)): + for w_t in space.fixedview(w_2): + if space.is_true(space.isinstance(w_t, space.w_str)): + msg = "catching of string exceptions is deprecated" + space.warn(space.wrap(msg), space.w_DeprecationWarning) + elif space.is_true(space.isinstance(w_2, space.w_str)): + msg = "catching of string exceptions is deprecated" + space.warn(space.wrap(msg), space.w_DeprecationWarning) + return space.newbool(space.exception_match(w_1, w_2)) def COMPARE_OP(self, testnum, next_instr): w_2 = self.popvalue() diff --git a/pypy/module/__builtin__/functional.py b/pypy/module/__builtin__/functional.py --- a/pypy/module/__builtin__/functional.py +++ b/pypy/module/__builtin__/functional.py @@ -133,56 +133,77 @@ v = v.add(step) return space.newlist(res_w) +min_jitdriver = jit.JitDriver(name='min', + greens=['w_type'], reds='auto') +max_jitdriver = jit.JitDriver(name='max', + greens=['w_type'], reds='auto') + +def make_min_max(unroll): + @specialize.arg(2) + def min_max_impl(space, args, implementation_of): + if implementation_of == "max": + compare = space.gt + jitdriver = max_jitdriver + else: + compare = space.lt + jitdriver = min_jitdriver + args_w = args.arguments_w + if len(args_w) > 1: + w_sequence = space.newtuple(args_w) + elif len(args_w): + w_sequence = args_w[0] + else: + msg = "%s() expects at least one argument" % (implementation_of,) + raise OperationError(space.w_TypeError, space.wrap(msg)) + w_key = None + kwds = args.keywords + if kwds: + if kwds[0] == "key" and len(kwds) == 1: + w_key = args.keywords_w[0] + else: + msg = "%s() got unexpected keyword argument" % (implementation_of,) + raise OperationError(space.w_TypeError, space.wrap(msg)) + + w_iter = space.iter(w_sequence) + w_type = space.type(w_iter) + w_max_item = None + w_max_val = None + while True: + if not unroll: + jitdriver.jit_merge_point(w_type=w_type) + try: + w_item = space.next(w_iter) + except OperationError, e: + if not e.match(space, space.w_StopIteration): + raise + break + if w_key is not None: + w_compare_with = space.call_function(w_key, w_item) + else: + w_compare_with = w_item + if w_max_item is None or \ + space.is_true(compare(w_compare_with, w_max_val)): + w_max_item = w_item + w_max_val = w_compare_with + if w_max_item is None: + msg = "arg is an empty sequence" + raise OperationError(space.w_ValueError, space.wrap(msg)) + return w_max_item + if unroll: + min_max_impl = jit.unroll_safe(min_max_impl) + return min_max_impl + +min_max_unroll = make_min_max(True) +min_max_normal = make_min_max(False) @specialize.arg(2) - at jit.look_inside_iff(lambda space, args, implementation_of: - jit.isconstant(len(args.arguments_w)) and - len(args.arguments_w) == 2 -) def min_max(space, args, implementation_of): - if implementation_of == "max": - compare = space.gt + if not jit.we_are_jitted() or (jit.isconstant(len(args.arguments_w)) and + len(args.arguments_w) == 2): + return min_max_unroll(space, args, implementation_of) else: - compare = space.lt - args_w = args.arguments_w - if len(args_w) > 1: - w_sequence = space.newtuple(args_w) - elif len(args_w): - w_sequence = args_w[0] - else: - msg = "%s() expects at least one argument" % (implementation_of,) - raise OperationError(space.w_TypeError, space.wrap(msg)) - w_key = None - kwds = args.keywords - if kwds: - if kwds[0] == "key" and len(kwds) == 1: - w_key = args.keywords_w[0] - else: - msg = "%s() got unexpected keyword argument" % (implementation_of,) - raise OperationError(space.w_TypeError, space.wrap(msg)) - - w_iter = space.iter(w_sequence) - w_max_item = None - w_max_val = None - while True: - try: - w_item = space.next(w_iter) - except OperationError, e: - if not e.match(space, space.w_StopIteration): - raise - break - if w_key is not None: - w_compare_with = space.call_function(w_key, w_item) - else: - w_compare_with = w_item - if w_max_item is None or \ - space.is_true(compare(w_compare_with, w_max_val)): - w_max_item = w_item - w_max_val = w_compare_with - if w_max_item is None: - msg = "arg is an empty sequence" - raise OperationError(space.w_ValueError, space.wrap(msg)) - return w_max_item + return min_max_normal(space, args, implementation_of) +min_max._always_inline = True def max(space, __args__): """max(iterable[, key=func]) -> value diff --git a/pypy/module/__builtin__/interp_classobj.py b/pypy/module/__builtin__/interp_classobj.py --- a/pypy/module/__builtin__/interp_classobj.py +++ b/pypy/module/__builtin__/interp_classobj.py @@ -154,9 +154,9 @@ return elif name == "__del__": if self.lookup(space, name) is None: - msg = ("a __del__ method added to an existing class " - "will not be called") - space.warn(msg, space.w_RuntimeWarning) + msg = ("a __del__ method added to an existing class will " + "not be called") + space.warn(space.wrap(msg), space.w_RuntimeWarning) space.setitem(self.w_dict, w_attr, w_value) def descr_delattr(self, space, w_attr): @@ -395,9 +395,9 @@ cache = space.fromcache(Cache) if (not isinstance(self, cache.cls_with_del) and self.getdictvalue(space, '__del__') is None): - msg = ("a __del__ method added to an instance " - "with no __del__ in the class will not be called") - space.warn(msg, space.w_RuntimeWarning) + msg = ("a __del__ method added to an instance with no " + "__del__ in the class will not be called") + space.warn(space.wrap(msg), space.w_RuntimeWarning) if w_meth is not None: space.call_function(w_meth, w_name, w_value) else: @@ -454,11 +454,9 @@ else: w_as_str = self.descr_str(space) if space.len_w(w_format_spec) > 0: - space.warn( - ("object.__format__ with a non-empty format string is " - "deprecated"), - space.w_PendingDeprecationWarning - ) + msg = ("object.__format__ with a non-empty format string is " + "deprecated") + space.warn(space.wrap(msg), space.w_PendingDeprecationWarning) return space.format(w_as_str, w_format_spec) def descr_len(self, space): diff --git a/pypy/module/__pypy__/test/test_signal.py b/pypy/module/__pypy__/test/test_signal.py --- a/pypy/module/__pypy__/test/test_signal.py +++ b/pypy/module/__pypy__/test/test_signal.py @@ -17,12 +17,12 @@ spaceconfig = dict(usemodules=['__pypy__', 'thread', 'signal', 'time']) def test_exit_twice(self): - from __pypy__ import thread - thread._signals_exit() + import __pypy__, thread + __pypy__.thread._signals_exit() try: - raises(KeyError, thread._signals_exit) + raises(thread.error, __pypy__.thread._signals_exit) finally: - thread._signals_enter() + __pypy__.thread._signals_enter() def test_enable_signals(self): import __pypy__, thread, signal, time diff --git a/pypy/module/_cffi_backend/cbuffer.py b/pypy/module/_cffi_backend/cbuffer.py --- a/pypy/module/_cffi_backend/cbuffer.py +++ b/pypy/module/_cffi_backend/cbuffer.py @@ -1,10 +1,11 @@ -from pypy.interpreter.error import operationerrfmt from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.buffer import RWBuffer +from pypy.interpreter.error import operationerrfmt from pypy.interpreter.gateway import unwrap_spec, interp2app from pypy.interpreter.typedef import TypeDef, make_weakref_descr +from pypy.module._cffi_backend import cdataobj, ctypeptr, ctypearray + from rpython.rtyper.lltypesystem import rffi -from pypy.module._cffi_backend import cdataobj, ctypeptr, ctypearray class LLBuffer(RWBuffer): diff --git a/pypy/module/_cffi_backend/ccallback.py b/pypy/module/_cffi_backend/ccallback.py --- a/pypy/module/_cffi_backend/ccallback.py +++ b/pypy/module/_cffi_backend/ccallback.py @@ -2,18 +2,17 @@ Callbacks. """ import os + +from rpython.rlib import clibffi, rweakref, jit +from rpython.rlib.objectmodel import compute_unique_id, keepalive_until_here +from rpython.rtyper.lltypesystem import lltype, rffi + from pypy.interpreter.error import OperationError, operationerrfmt -from rpython.rtyper.lltypesystem import lltype, llmemory, rffi -from rpython.rlib.objectmodel import compute_unique_id, keepalive_until_here -from rpython.rlib import clibffi, rweakref -from rpython.rlib import jit - +from pypy.module._cffi_backend import cerrno, misc from pypy.module._cffi_backend.cdataobj import W_CData -from pypy.module._cffi_backend.ctypefunc import SIZE_OF_FFI_ARG, BIG_ENDIAN -from pypy.module._cffi_backend.ctypefunc import W_CTypeFunc +from pypy.module._cffi_backend.ctypefunc import SIZE_OF_FFI_ARG, BIG_ENDIAN, W_CTypeFunc from pypy.module._cffi_backend.ctypeprim import W_CTypePrimitiveSigned from pypy.module._cffi_backend.ctypevoid import W_CTypeVoid -from pypy.module._cffi_backend import cerrno, misc # ____________________________________________________________ @@ -152,6 +151,7 @@ STDERR = 2 + @jit.jit_callback("CFFI") def invoke_callback(ffi_cif, ll_res, ll_args, ll_userdata): """ Callback specification. diff --git a/pypy/module/_cffi_backend/cdataobj.py b/pypy/module/_cffi_backend/cdataobj.py --- a/pypy/module/_cffi_backend/cdataobj.py +++ b/pypy/module/_cffi_backend/cdataobj.py @@ -1,11 +1,13 @@ import operator + +from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.error import OperationError, operationerrfmt -from pypy.interpreter.baseobjspace import Wrappable -from pypy.interpreter.gateway import interp2app, unwrap_spec +from pypy.interpreter.gateway import interp2app from pypy.interpreter.typedef import TypeDef, make_weakref_descr + +from rpython.rlib import objectmodel, rgc +from rpython.rlib.objectmodel import keepalive_until_here, specialize from rpython.rtyper.lltypesystem import lltype, rffi -from rpython.rlib.objectmodel import keepalive_until_here, specialize -from rpython.rlib import objectmodel, rgc from rpython.tool.sourcetools import func_with_new_name from pypy.module._cffi_backend import misc diff --git a/pypy/module/_cffi_backend/cerrno.py b/pypy/module/_cffi_backend/cerrno.py --- a/pypy/module/_cffi_backend/cerrno.py +++ b/pypy/module/_cffi_backend/cerrno.py @@ -1,5 +1,7 @@ import sys + from rpython.rlib import rposix + from pypy.interpreter.executioncontext import ExecutionContext from pypy.interpreter.gateway import unwrap_spec diff --git a/pypy/module/_cffi_backend/ctypearray.py b/pypy/module/_cffi_backend/ctypearray.py --- a/pypy/module/_cffi_backend/ctypearray.py +++ b/pypy/module/_cffi_backend/ctypearray.py @@ -2,18 +2,17 @@ Arrays. """ +from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.error import OperationError, operationerrfmt -from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.gateway import interp2app from pypy.interpreter.typedef import TypeDef + from rpython.rtyper.lltypesystem import rffi from rpython.rlib.objectmodel import keepalive_until_here from rpython.rlib.rarithmetic import ovfcheck -from pypy.module._cffi_backend.ctypeprim import W_CTypePrimitiveChar -from pypy.module._cffi_backend.ctypeprim import W_CTypePrimitiveUniChar +from pypy.module._cffi_backend import cdataobj from pypy.module._cffi_backend.ctypeptr import W_CTypePtrOrArray -from pypy.module._cffi_backend import cdataobj class W_CTypeArray(W_CTypePtrOrArray): diff --git a/pypy/module/_cffi_backend/ctypeenum.py b/pypy/module/_cffi_backend/ctypeenum.py --- a/pypy/module/_cffi_backend/ctypeenum.py +++ b/pypy/module/_cffi_backend/ctypeenum.py @@ -2,15 +2,11 @@ Enums. """ -from pypy.interpreter.error import OperationError, operationerrfmt -from rpython.rtyper.lltypesystem import rffi -from rpython.rlib.rarithmetic import intmask, r_ulonglong from rpython.rlib.objectmodel import keepalive_until_here -from rpython.rlib.objectmodel import specialize -from pypy.module._cffi_backend.ctypeprim import W_CTypePrimitiveSigned -from pypy.module._cffi_backend.ctypeprim import W_CTypePrimitiveUnsigned from pypy.module._cffi_backend import misc +from pypy.module._cffi_backend.ctypeprim import (W_CTypePrimitiveSigned, + W_CTypePrimitiveUnsigned) class _Mixin_Enum(object): diff --git a/pypy/module/_cffi_backend/ctypefunc.py b/pypy/module/_cffi_backend/ctypefunc.py --- a/pypy/module/_cffi_backend/ctypefunc.py +++ b/pypy/module/_cffi_backend/ctypefunc.py @@ -4,25 +4,21 @@ import sys from pypy.interpreter.error import OperationError, operationerrfmt + +from rpython.rlib import jit, clibffi, jit_libffi +from rpython.rlib.jit_libffi import (CIF_DESCRIPTION, CIF_DESCRIPTION_P, + FFI_TYPE, FFI_TYPE_P, FFI_TYPE_PP, SIZE_OF_FFI_ARG) +from rpython.rlib.objectmodel import we_are_translated, instantiate from rpython.rtyper.lltypesystem import lltype, llmemory, rffi -from rpython.rlib import jit, clibffi, jit_libffi -from rpython.rlib.jit_libffi import CIF_DESCRIPTION, CIF_DESCRIPTION_P -from rpython.rlib.jit_libffi import FFI_TYPE, FFI_TYPE_P, FFI_TYPE_PP -from rpython.rlib.jit_libffi import SIZE_OF_FFI_ARG -from rpython.rlib.objectmodel import we_are_translated, instantiate -from rpython.rlib.objectmodel import keepalive_until_here +from pypy.module._cffi_backend import ctypearray, cdataobj, cerrno from pypy.module._cffi_backend.ctypeobj import W_CType from pypy.module._cffi_backend.ctypeptr import W_CTypePtrBase, W_CTypePointer from pypy.module._cffi_backend.ctypevoid import W_CTypeVoid from pypy.module._cffi_backend.ctypestruct import W_CTypeStruct -from pypy.module._cffi_backend.ctypestruct import W_CTypeStructOrUnion -from pypy.module._cffi_backend.ctypeprim import W_CTypePrimitiveSigned -from pypy.module._cffi_backend.ctypeprim import W_CTypePrimitiveUnsigned -from pypy.module._cffi_backend.ctypeprim import W_CTypePrimitiveCharOrUniChar -from pypy.module._cffi_backend.ctypeprim import W_CTypePrimitiveFloat -from pypy.module._cffi_backend.ctypeprim import W_CTypePrimitiveLongDouble -from pypy.module._cffi_backend import ctypearray, cdataobj, cerrno +from pypy.module._cffi_backend.ctypeprim import (W_CTypePrimitiveSigned, + W_CTypePrimitiveUnsigned, W_CTypePrimitiveCharOrUniChar, + W_CTypePrimitiveFloat, W_CTypePrimitiveLongDouble) class W_CTypeFunc(W_CTypePtrBase): @@ -97,7 +93,6 @@ return self.space.wrap(clibffi.FFI_DEFAULT_ABI) # XXX return W_CTypePtrBase._fget(self, attrchar) - def call(self, funcaddr, args_w): if self.cif_descr: # regular case: this function does not take '...' arguments @@ -270,7 +265,6 @@ self.bufferp = rffi.ptradd(result, size) return result - def fb_fill_type(self, ctype, is_result_type): return ctype._get_ffi_type(self, is_result_type) @@ -357,7 +351,6 @@ return ffistruct - def fb_build(self): # Build a CIF_DESCRIPTION. Actually this computes the size and # allocates a larger amount of data. It starts with a @@ -387,7 +380,6 @@ if self.atypes: self.atypes[i] = atype - def align_arg(self, n): return (n + 7) & ~7 diff --git a/pypy/module/_cffi_backend/ctypeobj.py b/pypy/module/_cffi_backend/ctypeobj.py --- a/pypy/module/_cffi_backend/ctypeobj.py +++ b/pypy/module/_cffi_backend/ctypeobj.py @@ -1,9 +1,8 @@ +from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.error import OperationError, operationerrfmt -from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.gateway import interp2app -from pypy.interpreter.typedef import TypeDef -from pypy.interpreter.typedef import make_weakref_descr -from pypy.interpreter.typedef import GetSetProperty, interp_attrproperty +from pypy.interpreter.typedef import TypeDef, make_weakref_descr, GetSetProperty + from rpython.rtyper.lltypesystem import lltype, llmemory, rffi from rpython.rlib.objectmodel import we_are_translated diff --git a/pypy/module/_cffi_backend/ctypeprim.py b/pypy/module/_cffi_backend/ctypeprim.py --- a/pypy/module/_cffi_backend/ctypeprim.py +++ b/pypy/module/_cffi_backend/ctypeprim.py @@ -3,13 +3,14 @@ """ from pypy.interpreter.error import operationerrfmt -from rpython.rtyper.lltypesystem import lltype, rffi + from rpython.rlib.rarithmetic import r_uint, r_ulonglong, intmask from rpython.rlib.objectmodel import keepalive_until_here from rpython.rlib import jit +from rpython.rtyper.lltypesystem import lltype, rffi +from pypy.module._cffi_backend import cdataobj, misc from pypy.module._cffi_backend.ctypeobj import W_CType -from pypy.module._cffi_backend import cdataobj, misc class W_CTypePrimitive(W_CType): diff --git a/pypy/module/_cffi_backend/ctypeptr.py b/pypy/module/_cffi_backend/ctypeptr.py --- a/pypy/module/_cffi_backend/ctypeptr.py +++ b/pypy/module/_cffi_backend/ctypeptr.py @@ -2,15 +2,15 @@ Pointers. """ -from pypy.interpreter.error import OperationError, operationerrfmt -from pypy.interpreter.error import wrap_oserror -from rpython.rtyper.lltypesystem import lltype, rffi +from pypy.interpreter.error import OperationError, operationerrfmt, wrap_oserror + +from rpython.rlib import rposix from rpython.rlib.objectmodel import keepalive_until_here from rpython.rlib.rarithmetic import ovfcheck -from rpython.rlib import rposix +from rpython.rtyper.lltypesystem import lltype, rffi +from pypy.module._cffi_backend import cdataobj, misc, ctypeprim, ctypevoid from pypy.module._cffi_backend.ctypeobj import W_CType -from pypy.module._cffi_backend import cdataobj, misc, ctypeprim, ctypevoid class W_CTypePtrOrArray(W_CType): @@ -336,19 +336,22 @@ rffi_fdopen = rffi.llexternal("fdopen", [rffi.INT, rffi.CCHARP], rffi.CCHARP) -rffi_setbuf = rffi.llexternal("setbuf", [rffi.CCHARP,rffi.CCHARP], lltype.Void) +rffi_setbuf = rffi.llexternal("setbuf", [rffi.CCHARP, rffi.CCHARP], lltype.Void) rffi_fclose = rffi.llexternal("fclose", [rffi.CCHARP], rffi.INT) class CffiFileObj(object): _immutable_ = True + def __init__(self, fd, mode): self.llf = rffi_fdopen(fd, mode) if not self.llf: raise OSError(rposix.get_errno(), "fdopen failed") rffi_setbuf(self.llf, lltype.nullptr(rffi.CCHARP.TO)) + def close(self): rffi_fclose(self.llf) + def prepare_file_argument(space, fileobj): fileobj.direct_flush() if fileobj.cffi_fileobj is None: diff --git a/pypy/module/_cffi_backend/ctypestruct.py b/pypy/module/_cffi_backend/ctypestruct.py --- a/pypy/module/_cffi_backend/ctypestruct.py +++ b/pypy/module/_cffi_backend/ctypestruct.py @@ -3,15 +3,16 @@ """ from pypy.interpreter.error import OperationError, operationerrfmt -from rpython.rtyper.lltypesystem import lltype, rffi from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.typedef import TypeDef, interp_attrproperty + +from rpython.rlib import jit from rpython.rlib.objectmodel import keepalive_until_here from rpython.rlib.rarithmetic import r_uint, r_ulonglong, r_longlong, intmask -from rpython.rlib import jit +from rpython.rtyper.lltypesystem import rffi +from pypy.module._cffi_backend import cdataobj, ctypeprim, misc from pypy.module._cffi_backend.ctypeobj import W_CType -from pypy.module._cffi_backend import cdataobj, ctypeprim, misc class W_CTypeStructOrUnion(W_CType): @@ -141,6 +142,7 @@ class W_CTypeStruct(W_CTypeStructOrUnion): kind = "struct" + class W_CTypeUnion(W_CTypeStructOrUnion): kind = "union" @@ -241,8 +243,8 @@ # value = misc.as_long_long(space, w_ob) if isinstance(ctype, ctypeprim.W_CTypePrimitiveSigned): - fmin = -(r_longlong(1) << (self.bitsize-1)) - fmax = (r_longlong(1) << (self.bitsize-1)) - 1 + fmin = -(r_longlong(1) << (self.bitsize - 1)) + fmax = (r_longlong(1) << (self.bitsize - 1)) - 1 if fmax == 0: fmax = 1 # special case to let "int x:1" receive "1" else: diff --git a/pypy/module/_cffi_backend/libraryobj.py b/pypy/module/_cffi_backend/libraryobj.py --- a/pypy/module/_cffi_backend/libraryobj.py +++ b/pypy/module/_cffi_backend/libraryobj.py @@ -1,9 +1,11 @@ from __future__ import with_statement -from pypy.interpreter.error import OperationError, operationerrfmt + from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.error import operationerrfmt from pypy.interpreter.gateway import interp2app, unwrap_spec from pypy.interpreter.typedef import TypeDef -from rpython.rtyper.lltypesystem import lltype, rffi + +from rpython.rtyper.lltypesystem import rffi from rpython.rlib.rdynload import DLLHANDLE, dlopen, dlsym, dlclose, DLOpenError from pypy.module._cffi_backend.cdataobj import W_CData diff --git a/pypy/module/_cffi_backend/misc.py b/pypy/module/_cffi_backend/misc.py --- a/pypy/module/_cffi_backend/misc.py +++ b/pypy/module/_cffi_backend/misc.py @@ -1,10 +1,12 @@ from __future__ import with_statement -from pypy.interpreter.error import OperationError, operationerrfmt -from rpython.rtyper.lltypesystem import lltype, llmemory, rffi + +from pypy.interpreter.error import OperationError + +from rpython.rlib import jit +from rpython.rlib.objectmodel import keepalive_until_here, specialize from rpython.rlib.rarithmetic import r_uint, r_ulonglong, is_signed_integer_type from rpython.rlib.unroll import unrolling_iterable -from rpython.rlib.objectmodel import keepalive_until_here, specialize -from rpython.rlib import jit +from rpython.rtyper.lltypesystem import lltype, llmemory, rffi from rpython.translator.tool.cbuild import ExternalCompilationInfo # ____________________________________________________________ @@ -43,14 +45,14 @@ def read_raw_unsigned_data(target, size): for TP, TPP in _prim_unsigned_types: if size == rffi.sizeof(TP): - return rffi.cast(lltype.UnsignedLongLong, rffi.cast(TPP,target)[0]) + return rffi.cast(lltype.UnsignedLongLong, rffi.cast(TPP, target)[0]) raise NotImplementedError("bad integer size") def read_raw_ulong_data(target, size): for TP, TPP in _prim_unsigned_types: if size == rffi.sizeof(TP): assert rffi.sizeof(TP) <= rffi.sizeof(lltype.Unsigned) - return rffi.cast(lltype.Unsigned, rffi.cast(TPP,target)[0]) + return rffi.cast(lltype.Unsigned, rffi.cast(TPP, target)[0]) raise NotImplementedError("bad integer size") def read_raw_float_data(target, size): diff --git a/pypy/module/_cffi_backend/newtype.py b/pypy/module/_cffi_backend/newtype.py --- a/pypy/module/_cffi_backend/newtype.py +++ b/pypy/module/_cffi_backend/newtype.py @@ -1,12 +1,12 @@ from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.gateway import unwrap_spec + +from rpython.rlib.objectmodel import specialize +from rpython.rlib.rarithmetic import ovfcheck from rpython.rtyper.lltypesystem import lltype, rffi -from rpython.rlib.rarithmetic import ovfcheck, r_uint, intmask -from rpython.rlib.rarithmetic import most_neg_value_of, most_pos_value_of -from rpython.rlib.objectmodel import specialize -from pypy.module._cffi_backend import ctypeobj, ctypeprim, ctypeptr, ctypearray -from pypy.module._cffi_backend import ctypestruct, ctypevoid, ctypeenum +from pypy.module._cffi_backend import (ctypeobj, ctypeprim, ctypeptr, + ctypearray, ctypestruct, ctypevoid, ctypeenum) @specialize.memo() @@ -167,7 +167,7 @@ # if foffset < 0: # align this field to its own 'falign' by inserting padding - offset = (offset + falign - 1) & ~(falign-1) + offset = (offset + falign - 1) & ~(falign - 1) else: # a forced field position: ignore the offset just computed, # except to know if we must set 'custom_field_pos' @@ -178,7 +178,7 @@ fbitsize == 8 * ftype.size and not isinstance(ftype, ctypeprim.W_CTypePrimitiveCharOrUniChar)): fbitsize = -1 - if isinstance(ftype, ctypearray.W_CTypeArray) and ftype.length==0: + if isinstance(ftype, ctypearray.W_CTypeArray) and ftype.length == 0: bitshift = ctypestruct.W_CField.BS_EMPTY_ARRAY else: bitshift = ctypestruct.W_CField.BS_REGULAR @@ -241,7 +241,7 @@ # as 1 instead. But for ctypes support, we allow the manually- # specified totalsize to be zero in this case. if totalsize < 0: - offset = (offset + alignment - 1) & ~(alignment-1) + offset = (offset + alignment - 1) & ~(alignment - 1) totalsize = offset or 1 elif totalsize < offset: raise operationerrfmt(space.w_TypeError, diff --git a/pypy/module/_io/interp_bufferedio.py b/pypy/module/_io/interp_bufferedio.py --- a/pypy/module/_io/interp_bufferedio.py +++ b/pypy/module/_io/interp_bufferedio.py @@ -76,7 +76,7 @@ raise NotImplementedError def _deprecated_max_buffer_size(self, space): - space.warn("max_buffer_size is deprecated", + space.warn(space.wrap("max_buffer_size is deprecated"), space.w_DeprecationWarning) def read_w(self, space, w_size=None): @@ -631,6 +631,72 @@ return res return None + def readline_w(self, space, w_limit=None): + self._check_init(space) + self._check_closed(space, "readline of closed file") + + limit = convert_size(space, w_limit) + + # First, try to find a line in the buffer. This can run + # unlocked because the calls to the C API are simple enough + # that they can't trigger any thread switch. + have = self._readahead() + if limit >= 0 and have > limit: + have = limit + for pos in range(self.pos, self.pos+have): + if self.buffer[pos] == '\n': + break + else: + pos = -1 + if pos >= 0: + w_res = space.wrap(''.join(self.buffer[self.pos:pos+1])) + self.pos = pos + 1 + return w_res + if have == limit: + w_res = space.wrap(''.join(self.buffer[self.pos:self.pos+have])) + self.pos += have + return w_res + From noreply at buildbot.pypy.org Sat Feb 23 11:16:05 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sat, 23 Feb 2013 11:16:05 +0100 (CET) Subject: [pypy-commit] pypy default: expose typeinfo/set_string_function in the proper place Message-ID: <20130223101605.D79B31C0327@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61654:18b23b47b95f Date: 2013-02-23 05:13 -0500 http://bitbucket.org/pypy/pypy/changeset/18b23b47b95f/ Log: expose typeinfo/set_string_function in the proper place diff --git a/lib_pypy/numpypy/core/__init__.py b/lib_pypy/numpypy/core/__init__.py --- a/lib_pypy/numpypy/core/__init__.py +++ b/lib_pypy/numpypy/core/__init__.py @@ -6,6 +6,7 @@ from fromnumeric import * import shape_base from shape_base import * +import multiarray from fromnumeric import amax as max, amin as min from _numpypy import absolute as abs diff --git a/lib_pypy/numpypy/core/multiarray.py b/lib_pypy/numpypy/core/multiarray.py new file mode 100644 --- /dev/null +++ b/lib_pypy/numpypy/core/multiarray.py @@ -0,0 +1,1 @@ +from _numpypy import set_string_function, typeinfo diff --git a/lib_pypy/numpypy/core/numeric.py b/lib_pypy/numpypy/core/numeric.py --- a/lib_pypy/numpypy/core/numeric.py +++ b/lib_pypy/numpypy/core/numeric.py @@ -7,7 +7,7 @@ from .fromnumeric import any import math import sys -import _numpypy as multiarray # ARGH +import multiarray from numpypy.core.arrayprint import array2string newaxis = None diff --git a/pypy/module/micronumpy/__init__.py b/pypy/module/micronumpy/__init__.py --- a/pypy/module/micronumpy/__init__.py +++ b/pypy/module/micronumpy/__init__.py @@ -166,6 +166,7 @@ all_list = sorted(Module.interpleveldefs.keys() + \ Module.appleveldefs.keys()) # found by set(numpypy.__all__) - set(numpy.__all__) + all_list.remove('set_string_function') all_list.remove('typeinfo') w_all = space.wrap(all_list) space.setitem(self.w_dict, space.new_interned_str('__all__'), w_all) diff --git a/pypy/module/test_lib_pypy/numpypy/test_numpy.py b/pypy/module/test_lib_pypy/numpypy/test_numpy.py --- a/pypy/module/test_lib_pypy/numpypy/test_numpy.py +++ b/pypy/module/test_lib_pypy/numpypy/test_numpy.py @@ -41,3 +41,13 @@ 'unicode', 'str']: assert name not in locals() assert getattr(numpypy, name) is getattr(__builtin__, name) + + def test_typeinfo(self): + import numpypy + assert 'typeinfo' not in dir(numpypy) + assert 'typeinfo' in dir(numpypy.core.multiarray) + + def test_set_string_function(self): + import numpypy + assert numpypy.set_string_function is not \ + numpypy.core.multiarray.set_string_function From noreply at buildbot.pypy.org Sat Feb 23 11:53:55 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sat, 23 Feb 2013 11:53:55 +0100 (CET) Subject: [pypy-commit] pypy default: allow these tests to run against host numpy with -A Message-ID: <20130223105355.3535B1C482A@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61655:179e0ebf74a9 Date: 2013-02-23 05:53 -0500 http://bitbucket.org/pypy/pypy/changeset/179e0ebf74a9/ Log: allow these tests to run against host numpy with -A diff --git a/pypy/module/test_lib_pypy/numpypy/test_numpy.py b/pypy/module/test_lib_pypy/numpypy/test_numpy.py --- a/pypy/module/test_lib_pypy/numpypy/test_numpy.py +++ b/pypy/module/test_lib_pypy/numpypy/test_numpy.py @@ -1,4 +1,6 @@ -class AppTestNumpy: +from pypy.module.micronumpy.test.test_base import BaseNumpyAppTest + +class AppTestNumpy(BaseNumpyAppTest): spaceconfig = dict(usemodules=['micronumpy']) def test_imports(self): From noreply at buildbot.pypy.org Sat Feb 23 12:45:41 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Sat, 23 Feb 2013 12:45:41 +0100 (CET) Subject: [pypy-commit] pypy rpython-doc: Start a branch in which the RPython documentation is separated. Message-ID: <20130223114541.490F51C0327@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: rpython-doc Changeset: r61657:55ac4281d998 Date: 2013-02-23 12:44 +0100 http://bitbucket.org/pypy/pypy/changeset/55ac4281d998/ Log: Start a branch in which the RPython documentation is separated. From noreply at buildbot.pypy.org Sat Feb 23 12:45:42 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Sat, 23 Feb 2013 12:45:42 +0100 (CET) Subject: [pypy-commit] pypy rpython-doc: Add initial directory structure. Message-ID: <20130223114542.7506A1C0327@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: rpython-doc Changeset: r61658:7ddc05ebcbf9 Date: 2013-02-23 12:44 +0100 http://bitbucket.org/pypy/pypy/changeset/7ddc05ebcbf9/ Log: Add initial directory structure. diff --git a/rpython/doc/Makefile b/rpython/doc/Makefile new file mode 100644 --- /dev/null +++ b/rpython/doc/Makefile @@ -0,0 +1,153 @@ +# Makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +PAPER = +BUILDDIR = _build + +# Internal variables. +PAPEROPT_a4 = -D latex_paper_size=a4 +PAPEROPT_letter = -D latex_paper_size=letter +ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . +# the i18n builder cannot share the environment and doctrees with the others +I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . + +.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext + +help: + @echo "Please use \`make ' where is one of" + @echo " html to make standalone HTML files" + @echo " dirhtml to make HTML files named index.html in directories" + @echo " singlehtml to make a single large HTML file" + @echo " pickle to make pickle files" + @echo " json to make JSON files" + @echo " htmlhelp to make HTML files and a HTML help project" + @echo " qthelp to make HTML files and a qthelp project" + @echo " devhelp to make HTML files and a Devhelp project" + @echo " epub to make an epub" + @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" + @echo " latexpdf to make LaTeX files and run them through pdflatex" + @echo " text to make text files" + @echo " man to make manual pages" + @echo " texinfo to make Texinfo files" + @echo " info to make Texinfo files and run them through makeinfo" + @echo " gettext to make PO message catalogs" + @echo " changes to make an overview of all changed/added/deprecated items" + @echo " linkcheck to check all external links for integrity" + @echo " doctest to run all doctests embedded in the documentation (if enabled)" + +clean: + -rm -rf $(BUILDDIR)/* + +html: + $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." + +dirhtml: + $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." + +singlehtml: + $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml + @echo + @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." + +pickle: + $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle + @echo + @echo "Build finished; now you can process the pickle files." + +json: + $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json + @echo + @echo "Build finished; now you can process the JSON files." + +htmlhelp: + $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp + @echo + @echo "Build finished; now you can run HTML Help Workshop with the" \ + ".hhp project file in $(BUILDDIR)/htmlhelp." + +qthelp: + $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp + @echo + @echo "Build finished; now you can run "qcollectiongenerator" with the" \ + ".qhcp project file in $(BUILDDIR)/qthelp, like this:" + @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/RPython.qhcp" + @echo "To view the help file:" + @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/RPython.qhc" + +devhelp: + $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp + @echo + @echo "Build finished." + @echo "To view the help file:" + @echo "# mkdir -p $$HOME/.local/share/devhelp/RPython" + @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/RPython" + @echo "# devhelp" + +epub: + $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub + @echo + @echo "Build finished. The epub file is in $(BUILDDIR)/epub." + +latex: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo + @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." + @echo "Run \`make' in that directory to run these through (pdf)latex" \ + "(use \`make latexpdf' here to do that automatically)." + +latexpdf: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo "Running LaTeX files through pdflatex..." + $(MAKE) -C $(BUILDDIR)/latex all-pdf + @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." + +text: + $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text + @echo + @echo "Build finished. The text files are in $(BUILDDIR)/text." + +man: + $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man + @echo + @echo "Build finished. The manual pages are in $(BUILDDIR)/man." + +texinfo: + $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo + @echo + @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." + @echo "Run \`make' in that directory to run these through makeinfo" \ + "(use \`make info' here to do that automatically)." + +info: + $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo + @echo "Running Texinfo files through makeinfo..." + make -C $(BUILDDIR)/texinfo info + @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." + +gettext: + $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale + @echo + @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." + +changes: + $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes + @echo + @echo "The overview file is in $(BUILDDIR)/changes." + +linkcheck: + $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck + @echo + @echo "Link check complete; look for any errors in the above output " \ + "or in $(BUILDDIR)/linkcheck/output.txt." + +doctest: + $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest + @echo "Testing of doctests in the sources finished, look at the " \ + "results in $(BUILDDIR)/doctest/output.txt." diff --git a/rpython/doc/conf.py b/rpython/doc/conf.py new file mode 100644 --- /dev/null +++ b/rpython/doc/conf.py @@ -0,0 +1,242 @@ +# -*- coding: utf-8 -*- +# +# RPython documentation build configuration file, created by +# sphinx-quickstart on Sat Feb 23 12:41:19 2013. +# +# This file is execfile()d with the current directory set to its containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +import sys, os + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +#sys.path.insert(0, os.path.abspath('.')) + +# -- General configuration ----------------------------------------------------- + +# If your documentation needs a minimal Sphinx version, state it here. +#needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be extensions +# coming with Sphinx (named 'sphinx.ext.*') or your custom ones. +extensions = [] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix of source filenames. +source_suffix = '.rst' + +# The encoding of source files. +#source_encoding = 'utf-8-sig' + +# The master toctree document. +master_doc = 'index' + +# General information about the project. +project = u'RPython' +copyright = u'2013, The PyPy Project' + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The short X.Y version. +version = '2.0' +# The full version, including alpha/beta/rc tags. +release = '2.0-beta1' + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +#language = None + +# There are two options for replacing |today|: either, you set today to some +# non-false value, then it is used: +#today = '' +# Else, today_fmt is used as the format for a strftime call. +#today_fmt = '%B %d, %Y' + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +exclude_patterns = ['_build'] + +# The reST default role (used for this markup: `text`) to use for all documents. +#default_role = None + +# If true, '()' will be appended to :func: etc. cross-reference text. +#add_function_parentheses = True + +# If true, the current module name will be prepended to all description +# unit titles (such as .. function::). +#add_module_names = True + +# If true, sectionauthor and moduleauthor directives will be shown in the +# output. They are ignored by default. +#show_authors = False + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + +# A list of ignored prefixes for module index sorting. +#modindex_common_prefix = [] + + +# -- Options for HTML output --------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +html_theme = 'default' + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +#html_theme_options = {} + +# Add any paths that contain custom themes here, relative to this directory. +#html_theme_path = [] + +# The name for this set of Sphinx documents. If None, it defaults to +# " v documentation". +#html_title = None + +# A shorter title for the navigation bar. Default is the same as html_title. +#html_short_title = None + +# The name of an image file (relative to this directory) to place at the top +# of the sidebar. +#html_logo = None + +# The name of an image file (within the static path) to use as favicon of the +# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 +# pixels large. +#html_favicon = None + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] + +# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, +# using the given strftime format. +#html_last_updated_fmt = '%b %d, %Y' + +# If true, SmartyPants will be used to convert quotes and dashes to +# typographically correct entities. +#html_use_smartypants = True + +# Custom sidebar templates, maps document names to template names. +#html_sidebars = {} + +# Additional templates that should be rendered to pages, maps page names to +# template names. +#html_additional_pages = {} + +# If false, no module index is generated. +#html_domain_indices = True + +# If false, no index is generated. +#html_use_index = True + +# If true, the index is split into individual pages for each letter. +#html_split_index = False + +# If true, links to the reST sources are added to the pages. +#html_show_sourcelink = True + +# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. +#html_show_sphinx = True + +# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. +#html_show_copyright = True + +# If true, an OpenSearch description file will be output, and all pages will +# contain a tag referring to it. The value of this option must be the +# base URL from which the finished HTML is served. +#html_use_opensearch = '' + +# This is the file name suffix for HTML files (e.g. ".xhtml"). +#html_file_suffix = None + +# Output file base name for HTML help builder. +htmlhelp_basename = 'RPythondoc' + + +# -- Options for LaTeX output -------------------------------------------------- + +latex_elements = { +# The paper size ('letterpaper' or 'a4paper'). +#'papersize': 'letterpaper', + +# The font size ('10pt', '11pt' or '12pt'). +#'pointsize': '10pt', + +# Additional stuff for the LaTeX preamble. +#'preamble': '', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, author, documentclass [howto/manual]). +latex_documents = [ + ('index', 'RPython.tex', u'RPython Documentation', + u'The PyPy Project', 'manual'), +] + +# The name of an image file (relative to this directory) to place at the top of +# the title page. +#latex_logo = None + +# For "manual" documents, if this is true, then toplevel headings are parts, +# not chapters. +#latex_use_parts = False + +# If true, show page references after internal links. +#latex_show_pagerefs = False + +# If true, show URL addresses after external links. +#latex_show_urls = False + +# Documents to append as an appendix to all manuals. +#latex_appendices = [] + +# If false, no module index is generated. +#latex_domain_indices = True + + +# -- Options for manual page output -------------------------------------------- + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + ('index', 'rpython', u'RPython Documentation', + [u'The PyPy Project'], 1) +] + +# If true, show URL addresses after external links. +#man_show_urls = False + + +# -- Options for Texinfo output ------------------------------------------------ + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + ('index', 'RPython', u'RPython Documentation', + u'The PyPy Project', 'RPython', 'One line description of project.', + 'Miscellaneous'), +] + +# Documents to append as an appendix to all manuals. +#texinfo_appendices = [] + +# If false, no module index is generated. +#texinfo_domain_indices = True + +# How to display URL addresses: 'footnote', 'no', or 'inline'. +#texinfo_show_urls = 'footnote' diff --git a/rpython/doc/index.rst b/rpython/doc/index.rst new file mode 100644 --- /dev/null +++ b/rpython/doc/index.rst @@ -0,0 +1,22 @@ +.. RPython documentation master file, created by + sphinx-quickstart on Sat Feb 23 12:41:19 2013. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +Welcome to RPython's documentation! +=================================== + +Contents: + +.. toctree:: + :maxdepth: 2 + + + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` + diff --git a/rpython/doc/make.bat b/rpython/doc/make.bat new file mode 100644 --- /dev/null +++ b/rpython/doc/make.bat @@ -0,0 +1,190 @@ + at ECHO OFF + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set BUILDDIR=_build +set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% . +set I18NSPHINXOPTS=%SPHINXOPTS% . +if NOT "%PAPER%" == "" ( + set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% + set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS% +) + +if "%1" == "" goto help + +if "%1" == "help" ( + :help + echo.Please use `make ^` where ^ is one of + echo. html to make standalone HTML files + echo. dirhtml to make HTML files named index.html in directories + echo. singlehtml to make a single large HTML file + echo. pickle to make pickle files + echo. json to make JSON files + echo. htmlhelp to make HTML files and a HTML help project + echo. qthelp to make HTML files and a qthelp project + echo. devhelp to make HTML files and a Devhelp project + echo. epub to make an epub + echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter + echo. text to make text files + echo. man to make manual pages + echo. texinfo to make Texinfo files + echo. gettext to make PO message catalogs + echo. changes to make an overview over all changed/added/deprecated items + echo. linkcheck to check all external links for integrity + echo. doctest to run all doctests embedded in the documentation if enabled + goto end +) + +if "%1" == "clean" ( + for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i + del /q /s %BUILDDIR%\* + goto end +) + +if "%1" == "html" ( + %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The HTML pages are in %BUILDDIR%/html. + goto end +) + +if "%1" == "dirhtml" ( + %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. + goto end +) + +if "%1" == "singlehtml" ( + %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml. + goto end +) + +if "%1" == "pickle" ( + %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can process the pickle files. + goto end +) + +if "%1" == "json" ( + %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can process the JSON files. + goto end +) + +if "%1" == "htmlhelp" ( + %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can run HTML Help Workshop with the ^ +.hhp project file in %BUILDDIR%/htmlhelp. + goto end +) + +if "%1" == "qthelp" ( + %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can run "qcollectiongenerator" with the ^ +.qhcp project file in %BUILDDIR%/qthelp, like this: + echo.^> qcollectiongenerator %BUILDDIR%\qthelp\RPython.qhcp + echo.To view the help file: + echo.^> assistant -collectionFile %BUILDDIR%\qthelp\RPython.ghc + goto end +) + +if "%1" == "devhelp" ( + %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. + goto end +) + +if "%1" == "epub" ( + %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The epub file is in %BUILDDIR%/epub. + goto end +) + +if "%1" == "latex" ( + %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. + goto end +) + +if "%1" == "text" ( + %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The text files are in %BUILDDIR%/text. + goto end +) + +if "%1" == "man" ( + %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The manual pages are in %BUILDDIR%/man. + goto end +) + +if "%1" == "texinfo" ( + %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo. + goto end +) + +if "%1" == "gettext" ( + %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The message catalogs are in %BUILDDIR%/locale. + goto end +) + +if "%1" == "changes" ( + %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes + if errorlevel 1 exit /b 1 + echo. + echo.The overview file is in %BUILDDIR%/changes. + goto end +) + +if "%1" == "linkcheck" ( + %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck + if errorlevel 1 exit /b 1 + echo. + echo.Link check complete; look for any errors in the above output ^ +or in %BUILDDIR%/linkcheck/output.txt. + goto end +) + +if "%1" == "doctest" ( + %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest + if errorlevel 1 exit /b 1 + echo. + echo.Testing of doctests in the sources finished, look at the ^ +results in %BUILDDIR%/doctest/output.txt. + goto end +) + +:end From noreply at buildbot.pypy.org Sat Feb 23 12:45:45 2013 From: noreply at buildbot.pypy.org (cfbolz) Date: Sat, 23 Feb 2013 12:45:45 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: huge refactoring: remove the storage of the current frame on the interpreter. Message-ID: <20130223114545.761151C0327@cobra.cs.uni-duesseldorf.de> Author: Carl Friedrich Bolz Branch: Changeset: r92:91aa1165c8e2 Date: 2013-02-23 12:45 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/91aa1165c8e2/ Log: huge refactoring: remove the storage of the current frame on the interpreter. instead, just hand it around as an argument/result everywhere. this is a bit annoying in places, but makes the generated JIT code much better. - the bytecode implementations now return the new frame, if they set one up - the primitives now get and return a frame diff too long, truncating to 2000 out of 2377 lines diff --git a/spyvm/interpreter.py b/spyvm/interpreter.py --- a/spyvm/interpreter.py +++ b/spyvm/interpreter.py @@ -33,24 +33,13 @@ ) def __init__(self, space, image=None, image_name=""): - self._w_active_context = None self.space = space self.image = image self.image_name = image_name - def w_active_context(self): - return self._w_active_context - - def store_w_active_context(self, w_context): - assert isinstance(w_context, model.W_PointersObject) - self._w_active_context = w_context - - def s_active_context(self): - return self.w_active_context().as_context_get_shadow(self.space) - - def interpret(self): + def interpret_with_w_frame(self, w_frame): try: - self.loop() + self.loop(w_frame) except ReturnFromTopLevel, e: return e.object @@ -61,10 +50,8 @@ return conftest.option.bc_trace return conftest.option.prim_trace - def step(self, s_active_context=None): + def step(self, s_active_context): """NOT_RPYTHON: only for testing""" - if s_active_context is None: # tests only - s_active_context = self.s_active_context() next = s_active_context.getbytecode() bytecodeimpl = BYTECODE_TABLE[next] @@ -89,18 +76,20 @@ s_active_context.pc(), next, bytecodeimpl.__name__,) - bytecodeimpl(s_active_context, self, next) + return bytecodeimpl(s_active_context, self, next) - def loop(self): + def loop(self, w_active_context): + s_active_context = w_active_context.as_context_get_shadow(self.space) while True: - s_active_context = self.s_active_context() pc = s_active_context._pc method = s_active_context.method() self.jit_driver.jit_merge_point( pc=pc, self=self, method=method, s_active_context=s_active_context) - self.step(s_active_context) + w_new_context = self.step(s_active_context) + if w_new_context is not None: + s_active_context = w_new_context.as_context_get_shadow(self.space) def perform(self, w_receiver, selector, *arguments_w): if selector == "asSymbol": @@ -111,9 +100,8 @@ w_method = s_class.lookup(w_selector) assert w_method w_frame = w_method.create_frame(self.space, w_receiver, list(arguments_w)) - self.store_w_active_context(w_frame) try: - self.loop() + self.loop(w_frame) except ReturnFromTopLevel, e: return e.object @@ -134,11 +122,10 @@ # XXX move next line out of callPrimitive? func = primitives.prim_table[primitive] try: - func(interp, argcount) - return + return func(interp, self, argcount) except primitives.PrimitiveFailedError: pass - self._sendSelfSelectorSpecial(selector, argcount, interp) + return self._sendSelfSelectorSpecial(selector, argcount, interp) return callPrimitive # ___________________________________________________________________________ @@ -213,19 +200,19 @@ def sendLiteralSelectorBytecode(self, interp, current_bytecode): w_selector = self.method().getliteral(current_bytecode & 15) argcount = ((current_bytecode >> 4) & 3) - 1 - self._sendSelfSelector(w_selector, argcount, interp) + return self._sendSelfSelector(w_selector, argcount, interp) def _sendSelfSelector(self, w_selector, argcount, interp): receiver = self.peek(argcount) - self._sendSelector(w_selector, argcount, interp, - receiver, receiver.shadow_of_my_class(self.space)) + return self._sendSelector(w_selector, argcount, interp, + receiver, receiver.shadow_of_my_class(self.space)) def _sendSuperSelector(self, w_selector, argcount, interp): w_compiledin = self.method().w_compiledin assert isinstance(w_compiledin, model.W_PointersObject) s_compiledin = w_compiledin.as_class_get_shadow(self.space) - self._sendSelector(w_selector, argcount, interp, self.w_receiver(), - s_compiledin.s_superclass()) + return self._sendSelector(w_selector, argcount, interp, self.w_receiver(), + s_compiledin.s_superclass()) def _sendSelector(self, w_selector, argcount, interp, receiver, receiverclassshadow): @@ -247,50 +234,48 @@ for i, func in primitives.unrolling_prim_table: if i == code: try: - func(interp, argcount) - return + return func(interp, self, argcount) except primitives.PrimitiveFailedError: break else: func = primitives.prim_table[code] try: # note: argcount does not include rcvr - func(interp, argcount) - return + return func(interp, self, argcount) except primitives.PrimitiveFailedError: if interp.should_trace(True): print "PRIMITIVE FAILED: %d %s" % (method.primitive, w_selector.as_string(),) pass # ignore this error and fall back to the Smalltalk version arguments = self.pop_and_return_n(argcount) - frame = method.create_frame(self.space, receiver, arguments, - self.w_self()) + w_frame = method.create_frame(self.space, receiver, arguments, + self.w_self()) self.pop() - interp.store_w_active_context(frame) + return w_frame def _return(self, object, interp, w_return_to): # for tests, when returning from the top-level context if w_return_to.is_same_object(self.space.w_nil): raise ReturnFromTopLevel(object) w_return_to.as_context_get_shadow(self.space).push(object) - interp.store_w_active_context(w_return_to) + return w_return_to def returnReceiver(self, interp, current_bytecode): - self._return(self.w_receiver(), interp, self.s_home().w_sender()) + return self._return(self.w_receiver(), interp, self.s_home().w_sender()) def returnTrue(self, interp, current_bytecode): - self._return(interp.space.w_true, interp, self.s_home().w_sender()) + return self._return(interp.space.w_true, interp, self.s_home().w_sender()) def returnFalse(self, interp, current_bytecode): - self._return(interp.space.w_false, interp, self.s_home().w_sender()) + return self._return(interp.space.w_false, interp, self.s_home().w_sender()) def returnNil(self, interp, current_bytecode): - self._return(interp.space.w_nil, interp, self.s_home().w_sender()) + return self._return(interp.space.w_nil, interp, self.s_home().w_sender()) def returnTopFromMethod(self, interp, current_bytecode): - self._return(self.top(), interp, self.s_home().w_sender()) + return self._return(self.top(), interp, self.s_home().w_sender()) def returnTopFromBlock(self, interp, current_bytecode): - self._return(self.top(), interp, self.w_sender()) + return self._return(self.top(), interp, self.w_sender()) def unknownBytecode(self, interp, current_bytecode): raise MissingBytecode("unknownBytecode") @@ -339,7 +324,7 @@ def singleExtendedSendBytecode(self, interp, current_bytecode): w_selector, argcount = self.getExtendedSelectorArgcount() - self._sendSelfSelector(w_selector, argcount, interp) + return self._sendSelfSelector(w_selector, argcount, interp) def doubleExtendedDoAnythingBytecode(self, interp, current_bytecode): second = self.getbytecode() @@ -347,12 +332,12 @@ opType = second >> 5 if opType == 0: # selfsend - self._sendSelfSelector(self.method().getliteral(third), - second & 31, interp) + return self._sendSelfSelector(self.method().getliteral(third), + second & 31, interp) elif opType == 1: # supersend - self._sendSuperSelector(self.method().getliteral(third), - second & 31, interp) + return self._sendSuperSelector(self.method().getliteral(third), + second & 31, interp) elif opType == 2: # pushReceiver self.push(self.w_receiver().fetch(self.space, third)) @@ -375,13 +360,13 @@ def singleExtendedSuperBytecode(self, interp, current_bytecode): w_selector, argcount = self.getExtendedSelectorArgcount() - self._sendSuperSelector(w_selector, argcount, interp) + return self._sendSuperSelector(w_selector, argcount, interp) def secondExtendedSendBytecode(self, interp, current_bytecode): descriptor = self.getbytecode() w_selector = self.method().getliteral(descriptor & 63) argcount = descriptor >> 6 - self._sendSelfSelector(w_selector, argcount, interp) + return self._sendSelfSelector(w_selector, argcount, interp) def popStackBytecode(self, interp, current_bytecode): self.pop() @@ -506,33 +491,33 @@ # n.b.: depending on the type of the receiver, this may invoke # primitives.AT, primitives.STRING_AT, or something else for all # I know. - self._sendSelfSelectorSpecial("at:", 1, interp) + return self._sendSelfSelectorSpecial("at:", 1, interp) def bytecodePrimAtPut(self, interp, current_bytecode): # n.b. as above - self._sendSelfSelectorSpecial("at:put:", 2, interp) + return self._sendSelfSelectorSpecial("at:put:", 2, interp) def bytecodePrimSize(self, interp, current_bytecode): - self._sendSelfSelectorSpecial("size", 0, interp) + return self._sendSelfSelectorSpecial("size", 0, interp) def bytecodePrimNext(self, interp, current_bytecode): - self._sendSelfSelectorSpecial("next", 0, interp) + return self._sendSelfSelectorSpecial("next", 0, interp) def bytecodePrimNextPut(self, interp, current_bytecode): - self._sendSelfSelectorSpecial("nextPut:", 1, interp) + return self._sendSelfSelectorSpecial("nextPut:", 1, interp) def bytecodePrimAtEnd(self, interp, current_bytecode): - self._sendSelfSelectorSpecial("atEnd", 0, interp) + return self._sendSelfSelectorSpecial("atEnd", 0, interp) def bytecodePrimEquivalent(self, interp, current_bytecode): # short-circuit: classes cannot override the '==' method, # which cannot fail - primitives.prim_table[primitives.EQUIVALENT](interp, 1) + primitives.prim_table[primitives.EQUIVALENT](interp, self, 1) def bytecodePrimClass(self, interp, current_bytecode): # short-circuit: classes cannot override the 'class' method, # which cannot fail - primitives.prim_table[primitives.CLASS](interp, 0) + primitives.prim_table[primitives.CLASS](interp, self, 0) bytecodePrimBlockCopy = make_call_primitive_bytecode(primitives.BLOCK_COPY, "blockCopy:", 1) @@ -540,19 +525,19 @@ bytecodePrimValueWithArg = make_call_primitive_bytecode(primitives.VALUE, "value:", 1) def bytecodePrimDo(self, interp, current_bytecode): - self._sendSelfSelectorSpecial("do:", 1, interp) + return self._sendSelfSelectorSpecial("do:", 1, interp) def bytecodePrimNew(self, interp, current_bytecode): - self._sendSelfSelectorSpecial("new", 0, interp) + return self._sendSelfSelectorSpecial("new", 0, interp) def bytecodePrimNewWithArg(self, interp, current_bytecode): - self._sendSelfSelectorSpecial("new:", 1, interp) + return self._sendSelfSelectorSpecial("new:", 1, interp) def bytecodePrimPointX(self, interp, current_bytecode): - self._sendSelfSelectorSpecial("x", 0, interp) + return self._sendSelfSelectorSpecial("x", 0, interp) def bytecodePrimPointY(self, interp, current_bytecode): - self._sendSelfSelectorSpecial("y", 0, interp) + return self._sendSelfSelectorSpecial("y", 0, interp) BYTECODE_RANGES = [ ( 0, 15, "pushReceiverVariableBytecode"), @@ -680,7 +665,7 @@ cond = " or ".join(["bytecode == %s" % (i, ) for i in numbers]) code.append(" %sif %s:" % (prefix, cond, )) - code.append(" context.%s(self, bytecode)" % (entry[-1], )) + code.append(" return context.%s(self, bytecode)" % (entry[-1], )) prefix = "el" code.append("bytecode_step_translated._always_inline_ = True") source = py.code.Source("\n".join(code)) diff --git a/spyvm/primitives.py b/spyvm/primitives.py --- a/spyvm/primitives.py +++ b/spyvm/primitives.py @@ -26,7 +26,7 @@ # arguments, an interp and an argument_count # completes, and returns a result, or throws a PrimitiveFailedError. def make_failing(code): - def raise_failing_default(interp, argument_count): + def raise_failing_default(interp, s_frame, argument_count): # print "Primitive failed", code raise PrimitiveFailedError return raise_failing_default @@ -43,7 +43,7 @@ index1_0 = object() char = object() -def expose_primitive(code, unwrap_spec=None, no_result=False): +def expose_primitive(code, unwrap_spec=None, no_result=False, result_is_new_frame=False): # some serious magic, don't look from rpython.rlib.unroll import unrolling_iterable # heuristics to give it a nice name @@ -56,6 +56,7 @@ else: name = key + assert not (no_result and result_is_new_frame) # Because methods always have a receiver, an unwrap_spec of [] is a bug assert unwrap_spec is None or unwrap_spec @@ -63,21 +64,20 @@ assert code not in prim_table func.func_name = "prim_" + name if unwrap_spec is None: - def wrapped(interp, argument_count_m1): - w_result = func(interp, argument_count_m1) + def wrapped(interp, s_frame, argument_count_m1): + w_result = func(interp, s_frame, argument_count_m1) + if result_is_new_frame: + return w_result if not no_result: assert w_result is not None - interp.s_active_context().push(w_result) - return w_result + s_frame.push(w_result) else: len_unwrap_spec = len(unwrap_spec) assert (len_unwrap_spec == len(inspect.getargspec(func)[0]) + 1, "wrong number of arguments") unrolling_unwrap_spec = unrolling_iterable(enumerate(unwrap_spec)) - def wrapped(interp, argument_count_m1): + def wrapped(interp, s_frame, argument_count_m1): argument_count = argument_count_m1 + 1 # to account for the rcvr - frame = interp.w_active_context() - s_frame = frame.as_context_get_shadow(interp.space) assert argument_count == len_unwrap_spec if s_frame.stackdepth() < len_unwrap_spec: # XXX shouldn't this be a crash instead? @@ -105,14 +105,15 @@ else: raise NotImplementedError( "unknown unwrap_spec %s" % (spec, )) - w_result = func(interp, *args) + w_result = func(interp, s_frame, *args) # After calling primitive, reload context-shadow in case it # needs to be updated - new_s_frame = interp.s_active_context() - frame.as_context_get_shadow(interp.space).pop_n(len_unwrap_spec) # only if no exception occurs! - if not no_result: + s_frame.pop_n(len_unwrap_spec) # only if no exception occurs! + if result_is_new_frame: + return w_result + elif not no_result: assert w_result is not None - new_s_frame.push(w_result) + s_frame.push(w_result) wrapped.func_name = "wrap_prim_" + name prim_table[code] = wrapped prim_table_implemented_only.append((code, wrapped)) @@ -143,7 +144,7 @@ for (code,op) in math_ops.items(): def make_func(op): @expose_primitive(code, unwrap_spec=[int, int]) - def func(interp, receiver, argument): + def func(interp, s_frame, receiver, argument): try: res = rarithmetic.ovfcheck(op(receiver, argument)) except OverflowError: @@ -159,14 +160,14 @@ for (code,op) in bitwise_binary_ops.items(): def make_func(op): @expose_primitive(code, unwrap_spec=[int, int]) - def func(interp, receiver, argument): + def func(interp, s_frame, receiver, argument): res = op(receiver, argument) return interp.space.wrap_int(res) make_func(op) # #/ -- return the result of a division, only succeed if the division is exact @expose_primitive(DIVIDE, unwrap_spec=[int, int]) -def func(interp, receiver, argument): +def func(interp, s_frame, receiver, argument): if argument == 0: raise PrimitiveFailedError() if receiver % argument != 0: @@ -175,28 +176,28 @@ # #\\ -- return the remainder of a division @expose_primitive(MOD, unwrap_spec=[int, int]) -def func(interp, receiver, argument): +def func(interp, s_frame, receiver, argument): if argument == 0: raise PrimitiveFailedError() return interp.space.wrap_int(receiver % argument) # #// -- return the result of a division, rounded towards negative zero @expose_primitive(DIV, unwrap_spec=[int, int]) -def func(interp, receiver, argument): +def func(interp, s_frame, receiver, argument): if argument == 0: raise PrimitiveFailedError() return interp.space.wrap_int(receiver // argument) # #// -- return the result of a division, rounded towards negative infinite @expose_primitive(QUO, unwrap_spec=[int, int]) -def func(interp, receiver, argument): +def func(interp, s_frame, receiver, argument): if argument == 0: raise PrimitiveFailedError() return interp.space.wrap_int(receiver // argument) # #bitShift: -- return the shifted value @expose_primitive(BIT_SHIFT, unwrap_spec=[int, int]) -def func(interp, receiver, argument): +def func(interp, s_frame, receiver, argument): # TODO: 1 << 100 will overflow to 0. Catch this gracefully by Primitive # Failing! Use ovfcheck_lfshift @@ -242,40 +243,40 @@ for (code,op) in math_ops.items(): def make_func(op): @expose_primitive(code, unwrap_spec=[float, float]) - def func(interp, v1, v2): + def func(interp, s_frame, v1, v2): w_res = interp.space.wrap_float(op(v1, v2)) return w_res make_func(op) @expose_primitive(FLOAT_TRUNCATED, unwrap_spec=[float]) -def func(interp, f): +def func(interp, s_frame, f): w_res = interp.space.wrap_int(int(f)) return w_res @expose_primitive(FLOAT_TIMES_TWO_POWER, unwrap_spec=[float, int]) -def func(interp, rcvr, arg): +def func(interp, s_frame, rcvr, arg): w_res = interp.space.wrap_float(math.ldexp(rcvr, arg)) return w_res @expose_primitive(FLOAT_SQUARE_ROOT, unwrap_spec=[float]) -def func(interp, f): +def func(interp, s_frame, f): if f < 0.0: raise PrimitiveFailedError w_res = interp.space.wrap_float(math.sqrt(f)) return w_res @expose_primitive(FLOAT_SIN, unwrap_spec=[float]) -def func(interp, f): +def func(interp, s_frame, f): w_res = interp.space.wrap_float(math.sin(f)) return w_res @expose_primitive(FLOAT_ARCTAN, unwrap_spec=[float]) -def func(interp, f): +def func(interp, s_frame, f): w_res = interp.space.wrap_float(math.atan(f)) return w_res @expose_primitive(FLOAT_LOG_N, unwrap_spec=[float]) -def func(interp, f): +def func(interp, s_frame, f): if f == 0: res = -rfloat.INFINITY elif f < 0: @@ -285,14 +286,14 @@ return interp.space.wrap_float(res) @expose_primitive(FLOAT_EXP, unwrap_spec=[float]) -def func(interp, f): +def func(interp, s_frame, f): w_res = interp.space.wrap_float(math.exp(f)) return w_res MAKE_POINT = 18 @expose_primitive(MAKE_POINT, unwrap_spec=[int, int]) -def func(interp, x, y): +def func(interp, s_frame, x, y): w_res = interp.space.w_Point.as_class_get_shadow(interp.space).new(2) point = wrapper.PointWrapper(interp.space, w_res) point.store_x(x) @@ -315,24 +316,24 @@ STRING_AT_PUT = 64 @expose_primitive(AT, unwrap_spec=[object, index1_0]) -def func(interp, w_obj, n0): +def func(interp, s_frame, w_obj, n0): n0 = assert_valid_index(interp.space, n0, w_obj) return w_obj.at0(interp.space, n0) @expose_primitive(AT_PUT, unwrap_spec=[object, index1_0, object]) -def func(interp, w_obj, n0, w_val): +def func(interp, s_frame, w_obj, n0, w_val): n0 = assert_valid_index(interp.space, n0, w_obj) w_obj.atput0(interp.space, n0, w_val) return w_val @expose_primitive(SIZE, unwrap_spec=[object]) -def func(interp, w_obj): +def func(interp, s_frame, w_obj): if not w_obj.shadow_of_my_class(interp.space).isvariable(): raise PrimitiveFailedError() return interp.space.wrap_int(w_obj.primsize(interp.space)) @expose_primitive(STRING_AT, unwrap_spec=[object, index1_0]) -def func(interp, w_obj, n0): +def func(interp, s_frame, w_obj, n0): n0 = assert_valid_index(interp.space, n0, w_obj) # XXX I am not sure this is correct, but it un-breaks translation: # make sure that getbyte is only performed on W_BytesObjects @@ -341,7 +342,7 @@ return interp.space.wrap_char(w_obj.getchar(n0)) @expose_primitive(STRING_AT_PUT, unwrap_spec=[object, index1_0, object]) -def func(interp, w_obj, n0, w_val): +def func(interp, s_frame, w_obj, n0, w_val): val = interp.space.unwrap_char(w_val) n0 = assert_valid_index(interp.space, n0, w_obj) if not (isinstance(w_obj, model.W_CompiledMethod) or @@ -374,13 +375,13 @@ NEW_METHOD = 79 @expose_primitive(OBJECT_AT, unwrap_spec=[object, index1_0]) -def func(interp, w_rcvr, n0): +def func(interp, s_frame, w_rcvr, n0): if not isinstance(w_rcvr, model.W_CompiledMethod): raise PrimitiveFailedError() return w_rcvr.literalat0(interp.space, n0) @expose_primitive(OBJECT_AT_PUT, unwrap_spec=[object, index1_0, object]) -def func(interp, w_rcvr, n0, w_value): +def func(interp, s_frame, w_rcvr, n0, w_value): if not isinstance(w_rcvr, model.W_CompiledMethod): raise PrimitiveFailedError() #assert_bounds(n0, 0, len(w_rcvr.literals)) @@ -388,7 +389,7 @@ return w_value @expose_primitive(NEW, unwrap_spec=[object]) -def func(interp, w_cls): +def func(interp, s_frame, w_cls): assert isinstance(w_cls, model.W_PointersObject) s_class = w_cls.as_class_get_shadow(interp.space) if s_class.isvariable(): @@ -396,7 +397,7 @@ return s_class.new() @expose_primitive(NEW_WITH_ARG, unwrap_spec=[object, int]) -def func(interp, w_cls, size): +def func(interp, s_frame, w_cls, size): assert isinstance(w_cls, model.W_PointersObject) s_class = w_cls.as_class_get_shadow(interp.space) if not s_class.isvariable(): @@ -404,11 +405,11 @@ return s_class.new(size) @expose_primitive(ARRAY_BECOME_ONE_WAY, unwrap_spec=[object, object]) -def func(interp, w_obj1, w_obj2): +def func(interp, s_frame, w_obj1, w_obj2): raise PrimitiveNotYetWrittenError @expose_primitive(INST_VAR_AT, unwrap_spec=[object, index1_0]) -def func(interp, w_rcvr, n0): +def func(interp, s_frame, w_rcvr, n0): "Fetches a fixed field from the object, and fails otherwise" s_class = w_rcvr.shadow_of_my_class(interp.space) assert_bounds(n0, 0, s_class.instsize()) @@ -418,7 +419,7 @@ return w_rcvr.fetch(interp.space, n0) @expose_primitive(INST_VAR_AT_PUT, unwrap_spec=[object, index1_0, object]) -def func(interp, w_rcvr, n0, w_value): +def func(interp, s_frame, w_rcvr, n0, w_value): "Stores a value into a fixed field from the object, and fails otherwise" s_class = w_rcvr.shadow_of_my_class(interp.space) assert_bounds(n0, 0, s_class.instsize()) @@ -428,32 +429,32 @@ return w_value @expose_primitive(AS_OOP, unwrap_spec=[object]) -def func(interp, w_rcvr): +def func(interp, s_frame, w_rcvr): if isinstance(w_rcvr, model.W_SmallInteger): raise PrimitiveFailedError() return interp.space.wrap_int(w_rcvr.gethash()) @expose_primitive(STORE_STACKP, unwrap_spec=[object, object]) -def func(interp, w_obj1, w_obj2): +def func(interp, s_frame, w_obj1, w_obj2): # This primitive seems to resize the stack. I don't think this is # really relevant in our implementation. raise PrimitiveNotYetWrittenError() @expose_primitive(SOME_INSTANCE, unwrap_spec=[object]) -def func(interp, w_class): +def func(interp, s_frame, w_class): # This primitive returns some instance of the class on the stack. # Not sure quite how to do this; maintain a weak list of all # existing instances or something? raise PrimitiveNotYetWrittenError() @expose_primitive(NEXT_INSTANCE, unwrap_spec=[object]) -def func(interp, w_obj): +def func(interp, s_frame, w_obj): # This primitive is used to iterate through all instances of a class: # it returns the "next" instance after w_obj. raise PrimitiveNotYetWrittenError() @expose_primitive(NEW_METHOD, unwrap_spec=[object, int, int]) -def func(interp, w_class, bytecount, header): +def func(interp, s_frame, w_class, bytecount, header): # We ignore w_class because W_CompiledMethod is special w_method = model.W_CompiledMethod(bytecount, header) return w_method @@ -484,19 +485,19 @@ @expose_primitive(BE_CURSOR, unwrap_spec=[object]) -def func(interp, w_rcvr): +def func(interp, s_frame, w_rcvr): # TODO: Use info from cursor object. interp.space.objtable['w_cursor'] = w_rcvr return w_rcvr @expose_primitive(BE_DISPLAY, unwrap_spec=[object]) -def func(interp, w_rcvr): +def func(interp, s_frame, w_rcvr): interp.space.objtable['w_display'] = w_rcvr return w_rcvr @expose_primitive(SCREEN_SIZE, unwrap_spec=[object]) -def func(interp, w_rcvr): +def func(interp, s_frame, w_rcvr): # XXX get the real screen size w_res = interp.space.w_Point.as_class_get_shadow(interp.space).new(2) point = wrapper.PointWrapper(interp.space, w_res) @@ -515,27 +516,27 @@ CHANGE_CLASS = 115 # Blue Book: primitiveOopsLeft @expose_primitive(EQUIVALENT, unwrap_spec=[object, object]) -def func(interp, w_arg, w_rcvr): +def func(interp, s_frame, w_arg, w_rcvr): return interp.space.wrap_bool(w_arg.is_same_object(w_rcvr)) @expose_primitive(CLASS, unwrap_spec=[object]) -def func(interp, w_obj): +def func(interp, s_frame, w_obj): return w_obj.getclass(interp.space) @expose_primitive(BYTES_LEFT, unwrap_spec=[object]) -def func(interp, w_rcvr): +def func(interp, s_frame, w_rcvr): raise PrimitiveNotYetWrittenError() @expose_primitive(QUIT, unwrap_spec=[object]) -def func(interp, w_rcvr): +def func(interp, s_frame, w_rcvr): raise PrimitiveNotYetWrittenError() @expose_primitive(EXIT_TO_DEBUGGER, unwrap_spec=[object]) -def func(interp, w_rcvr): +def func(interp, s_frame, w_rcvr): raise PrimitiveNotYetWrittenError() @expose_primitive(CHANGE_CLASS, unwrap_spec=[object, object], no_result=True) -def func(interp, w_arg, w_rcvr): +def func(interp, s_frame, w_arg, w_rcvr): w_arg_class = w_arg.getclass(interp.space) w_rcvr_class = w_rcvr.getclass(interp.space) @@ -572,22 +573,22 @@ SIGNAL_AT_BYTES_LEFT = 125 @expose_primitive(IMAGE_NAME) -def func(interp, argument_count): +def func(interp, s_frame, argument_count): if argument_count == 0: - interp.s_active_context().pop() + s_frame.pop() return interp.space.wrap_string(interp.image_name) elif argument_count == 1: pass # XXX raise PrimitiveFailedError @expose_primitive(LOW_SPACE_SEMAPHORE, unwrap_spec=[object, object]) -def func(interp, w_reciver, i): +def func(interp, s_frame, w_reciver, i): # dont know when the space runs out return w_reciver @expose_primitive(SIGNAL_AT_BYTES_LEFT, unwrap_spec=[object, int]) -def func(interp, w_reciver, i): +def func(interp, s_frame, w_reciver, i): # dont know when the space runs out return w_reciver @@ -600,7 +601,7 @@ CLONE = 148 @expose_primitive(BECOME, unwrap_spec=[object, object]) -def func(interp, w_rcvr, w_new): +def func(interp, s_frame, w_rcvr, w_new): if w_rcvr.size() != w_new.size(): raise PrimitiveFailedError w_lefts = [] @@ -623,13 +624,13 @@ @expose_primitive(INC_GC, unwrap_spec=[object]) @expose_primitive(FULL_GC, unwrap_spec=[object]) @jit.dont_look_inside -def func(interp, w_arg): # Squeak pops the arg and ignores it ... go figure +def func(interp, s_frame, w_arg): # Squeak pops the arg and ignores it ... go figure from rpython.rlib import rgc rgc.collect() return fake_bytes_left(interp) @expose_primitive(CLONE, unwrap_spec=[object]) -def func(interp, w_arg): +def func(interp, s_frame, w_arg): return w_arg.clone(interp.space) #____________________________________________________________________________ @@ -638,7 +639,7 @@ SECONDS_CLOCK = 137 @expose_primitive(MILLISECOND_CLOCK, unwrap_spec=[object]) -def func(interp, w_arg): +def func(interp, s_frame, w_arg): import time import math return interp.space.wrap_int(int(math.fmod(time.time()*1000, constants.TAGGED_MAXINT/2))) @@ -647,7 +648,7 @@ secs_between_1901_and_1970 = rarithmetic.r_uint((69 * 365 + 17) * 24 * 3600) @expose_primitive(SECONDS_CLOCK, unwrap_spec=[object]) -def func(interp, w_arg): +def func(interp, s_frame, w_arg): import time sec_since_epoch = rarithmetic.r_uint(time.time()) sec_since_1901 = sec_since_epoch + secs_between_1901_and_1970 @@ -674,7 +675,7 @@ @expose_primitive(DIRECTORY_DELIMITOR, unwrap_spec=[object]) -def func(interp, _): +def func(interp, s_frame, _): import os.path return interp.space.wrap_char(os.path.sep) @@ -707,7 +708,7 @@ for (code,op) in bool_ops.items(): def make_func(op): @expose_primitive(code, unwrap_spec=[int, int]) - def func(interp, v1, v2): + def func(interp, s_frame, v1, v2): res = op(v1, v2) w_res = interp.space.wrap_bool(res) return w_res @@ -716,7 +717,7 @@ for (code,op) in bool_ops.items(): def make_func(op): @expose_primitive(code+_FLOAT_OFFSET, unwrap_spec=[float, float]) - def func(interp, v1, v2): + def func(interp, s_frame, v1, v2): res = op(v1, v2) w_res = interp.space.wrap_bool(res) return w_res @@ -735,14 +736,15 @@ PUSH_TWO = 263 @expose_primitive(PUSH_SELF, unwrap_spec=[object]) -def func(interp, w_self): +def func(interp, s_frame, w_self): # no-op really return w_self def make_push_const_func(code, name): @expose_primitive(code, unwrap_spec=[object]) - def func(interp, w_ignored): + def func(interp, s_frame, w_ignored): return getattr(interp.space, name) + return func for (code, name) in [ (PUSH_TRUE, "w_true"), @@ -770,8 +772,7 @@ FLUSH_CACHE = 89 @expose_primitive(BLOCK_COPY, unwrap_spec=[object, int]) -def func(interp, w_context, argcnt): - frame = interp.s_active_context() +def func(interp, s_frame, w_context, argcnt): # From B.B.: If receiver is a MethodContext, then it becomes # the new BlockContext's home context. Otherwise, the home @@ -782,31 +783,28 @@ # The block bytecodes are stored inline: so we skip past the # byteodes to invoke this primitive to find them (hence +2) - initialip = frame.pc() + 2 + initialip = s_frame.pc() + 2 w_new_context = shadow.BlockContextShadow.make_context( interp.space, w_method_context, interp.space.w_nil, argcnt, initialip) return w_new_context -def finalize_block_ctx(interp, s_block_ctx, frame): +def finalize_block_ctx(interp, s_block_ctx, w_frame): # Set some fields s_block_ctx.store_pc(s_block_ctx.initialip()) - s_block_ctx.store_w_sender(frame) - interp.store_w_active_context(s_block_ctx.w_self()) - - at expose_primitive(VALUE, no_result=True) -def func(interp, argument_count): + s_block_ctx.store_w_sender(w_frame) + return s_block_ctx.w_self() + + at expose_primitive(VALUE, result_is_new_frame=True) +def func(interp, s_frame, argument_count): # argument_count does NOT include the receiver. # This means that for argument_count == 3 the stack looks like: # 3 2 1 Top # Rcvr | Arg 0 | Arg1 | Arg 2 # - - frame = interp.s_active_context() - # Validate that we have a block on the stack and that it received # the proper number of arguments: - w_block_ctx = frame.peek(argument_count) + w_block_ctx = s_frame.peek(argument_count) # XXX need to check this since VALUE is called on all sorts of objects. if not w_block_ctx.getclass(interp.space).is_same_object( @@ -823,18 +821,18 @@ # Initialize the block stack with the arguments that were # pushed. Also pop the receiver. - block_args = frame.pop_and_return_n(exp_arg_cnt) + block_args = s_frame.pop_and_return_n(exp_arg_cnt) # Reset stack of blockcontext to [] s_block_ctx.reset_stack() s_block_ctx.push_all(block_args) - frame.pop() - finalize_block_ctx(interp, s_block_ctx, frame.w_self()) - + s_frame.pop() + return finalize_block_ctx(interp, s_block_ctx, s_frame.w_self()) + @expose_primitive(VALUE_WITH_ARGS, unwrap_spec=[object, list], - no_result=True) -def func(interp, w_block_ctx, args_w): + result_is_new_frame=True) +def func(interp, s_frame, w_block_ctx, args_w): assert isinstance(w_block_ctx, model.W_PointersObject) s_block_ctx = w_block_ctx.as_blockcontext_get_shadow(interp.space) @@ -849,63 +847,63 @@ # XXX Check original logic. Image does not test this anyway # because falls back to value + internal implementation - finalize_block_ctx(interp, s_block_ctx, interp.w_active_context()) + return finalize_block_ctx(interp, s_block_ctx, s_frame.w_self()) @expose_primitive(PERFORM) -def func(interp, argcount): +def func(interp, s_frame, argcount): raise PrimitiveFailedError() @expose_primitive(PERFORM_WITH_ARGS, unwrap_spec=[object, object, object], - no_result=True) -def func(interp, w_rcvr, w_sel, w_args): + result_is_new_frame=True) +def func(interp, s_frame, w_rcvr, w_sel, w_args): w_method = w_rcvr.shadow_of_my_class(interp.space).lookup(w_sel) assert w_method w_frame = w_method.create_frame(interp.space, w_rcvr, [w_args.fetch(interp.space, i) for i in range(w_args.size())]) - w_frame.as_context_get_shadow(interp.space).store_w_sender(interp.w_active_context()) - interp.store_w_active_context(w_frame) + w_frame.as_context_get_shadow(interp.space).store_w_sender(s_frame.w_self()) + return w_frame @expose_primitive(SIGNAL, unwrap_spec=[object]) -def func(interp, w_rcvr): +def func(interp, s_frame, w_rcvr): # XXX we might want to disable this check if not w_rcvr.getclass(interp.space).is_same_object( interp.space.w_Semaphore): raise PrimitiveFailedError() - wrapper.SemaphoreWrapper(interp.space, w_rcvr).signal(interp) - return w_rcvr - + s_frame.push(w_rcvr) # w_rcvr is the result in the old frame + return wrapper.SemaphoreWrapper(interp.space, w_rcvr).signal(s_frame.w_self()) + @expose_primitive(WAIT, unwrap_spec=[object]) -def func(interp, w_rcvr): +def func(interp, s_frame, w_rcvr): # XXX we might want to disable this check if not w_rcvr.getclass(interp.space).is_same_object( interp.space.w_Semaphore): raise PrimitiveFailedError() - wrapper.SemaphoreWrapper(interp.space, w_rcvr).wait(interp) - return w_rcvr - - at expose_primitive(RESUME, unwrap_spec=[object]) -def func(interp, w_rcvr,): + s_frame.push(w_rcvr) # w_rcvr is the result in the old frame + return wrapper.SemaphoreWrapper(interp.space, w_rcvr).wait(s_frame.w_self()) + + at expose_primitive(RESUME, unwrap_spec=[object], result_is_new_frame=True) +def func(interp, s_frame, w_rcvr,): # XXX we might want to disable this check if not w_rcvr.getclass(interp.space).is_same_object( interp.space.w_Process): raise PrimitiveFailedError() - wrapper.ProcessWrapper(interp.space, w_rcvr).resume(interp) - return w_rcvr - + s_frame.push(w_rcvr) # w_rcvr is the result in the old frame + return wrapper.ProcessWrapper(interp.space, w_rcvr).resume(s_frame.w_self()) + @expose_primitive(SUSPEND, unwrap_spec=[object]) -def func(interp, w_rcvr): +def func(interp, s_frame, w_rcvr, result_is_new_frame=True): # XXX we might want to disable this check if not w_rcvr.getclass(interp.space).is_same_object( interp.space.w_Process): raise PrimitiveFailedError() - wrapper.ProcessWrapper(interp.space, w_rcvr).suspend(interp) - return w_rcvr - + s_frame.push(w_rcvr) # w_rcvr is the result in the old frame + return wrapper.ProcessWrapper(interp.space, w_rcvr).suspend(s_frame.w_self()) + @expose_primitive(FLUSH_CACHE, unwrap_spec=[object]) -def func(interp, w_rcvr): +def func(interp, s_frame, w_rcvr): # XXX we currently don't care about bad flushes :) XXX # raise PrimitiveNotYetWrittenError() return w_rcvr @@ -924,14 +922,13 @@ CLOSURE_VALUE_NO_CONTEXT_SWITCH_ = 222 @expose_primitive(CLOSURE_COPY_WITH_COPIED_VALUES, unwrap_spec=[object, int, list]) -def func(interp, outerContext, numArgs, copiedValues): - frame = interp.s_active_context() - w_context = interp.space.newClosure(outerContext, frame.pc(), +def func(interp, s_frame, outerContext, numArgs, copiedValues): + w_context = interp.space.newClosure(outerContext, s_frame.pc(), numArgs, copiedValues) return w_context -def activateClosure(interp, w_block, args_w, mayContextSwitch=True): +def activateClosure(interp, s_frame, w_block, args_w, mayContextSwitch=True): space = interp.space if not w_block.getclass(space).is_same_object( space.w_BlockClosure): @@ -948,46 +945,46 @@ # additionally to the smalltalk implementation, this also pushes # args and copiedValues w_new_frame = block.asContextWithSender( - interp.w_active_context(), args_w) + s_frame.w_self(), args_w) w_closureMethod = w_new_frame.get_shadow(space).w_method() assert isinstance(w_closureMethod, model.W_CompiledMethod) assert w_block is not block.outerContext() - interp.store_w_active_context(w_new_frame) + return w_new_frame - at expose_primitive(CLOSURE_VALUE, unwrap_spec=[object], no_result=True) -def func(interp, w_block_closure): - activateClosure(interp, w_block_closure, []) + at expose_primitive(CLOSURE_VALUE, unwrap_spec=[object], result_is_new_frame=True) +def func(interp, s_frame, w_block_closure): + return activateClosure(interp, s_frame, w_block_closure, []) - at expose_primitive(CLOSURE_VALUE_, unwrap_spec=[object, object], no_result=True) -def func(interp, w_block_closure, w_a0): - activateClosure(interp, w_block_closure, [w_a0]) + at expose_primitive(CLOSURE_VALUE_, unwrap_spec=[object, object], result_is_new_frame=True) +def func(interp, s_frame, w_block_closure, w_a0): + return activateClosure(interp, s_frame, w_block_closure, [w_a0]) - at expose_primitive(CLOSURE_VALUE_VALUE, unwrap_spec=[object, object, object], no_result=True) -def func(interp, w_block_closure, w_a0, w_a1): - activateClosure(interp, w_block_closure, [w_a0, w_a1]) + at expose_primitive(CLOSURE_VALUE_VALUE, unwrap_spec=[object, object, object], result_is_new_frame=True) +def func(interp, s_frame, w_block_closure, w_a0, w_a1): + return activateClosure(interp, s_frame, w_block_closure, [w_a0, w_a1]) - at expose_primitive(CLOSURE_VALUE_VALUE_VALUE, unwrap_spec=[object, object, object, object], no_result=True) -def func(interp, w_block_closure, w_a0, w_a1, w_a2): - activateClosure(interp, w_block_closure, [w_a0, w_a1, w_a2]) + at expose_primitive(CLOSURE_VALUE_VALUE_VALUE, unwrap_spec=[object, object, object, object], result_is_new_frame=True) +def func(interp, s_frame, w_block_closure, w_a0, w_a1, w_a2): + return activateClosure(interp, s_frame, w_block_closure, [w_a0, w_a1, w_a2]) - at expose_primitive(CLOSURE_VALUE_VALUE_VALUE_VALUE, unwrap_spec=[object, object, object, object, object], no_result=True) -def func(interp, w_block_closure, w_a0, w_a1, w_a2, w_a3): - activateClosure(interp, w_block_closure, [w_a0, w_a1, w_a2, w_a3]) + at expose_primitive(CLOSURE_VALUE_VALUE_VALUE_VALUE, unwrap_spec=[object, object, object, object, object], result_is_new_frame=True) +def func(interp, s_frame, w_block_closure, w_a0, w_a1, w_a2, w_a3): + return activateClosure(interp, s_frame, w_block_closure, [w_a0, w_a1, w_a2, w_a3]) - at expose_primitive(CLOSURE_VALUE_WITH_ARGS, unwrap_spec=[object, list], no_result=True) -def func(interp, w_block_closure, args_w): - activateClosure(interp, w_block_closure, args_w) + at expose_primitive(CLOSURE_VALUE_WITH_ARGS, unwrap_spec=[object, list], result_is_new_frame=True) +def func(interp, s_frame, w_block_closure, args_w): + return activateClosure(interp, s_frame, w_block_closure, args_w) - at expose_primitive(CLOSURE_VALUE_NO_CONTEXT_SWITCH, unwrap_spec=[object], no_result=True) -def func(interp, w_block_closure): - activateClosure(interp, w_block_closure, [], mayContextSwitch=False) + at expose_primitive(CLOSURE_VALUE_NO_CONTEXT_SWITCH, unwrap_spec=[object], result_is_new_frame=True) +def func(interp, s_frame, w_block_closure): + return activateClosure(interp, s_frame, w_block_closure, [], mayContextSwitch=False) - at expose_primitive(CLOSURE_VALUE_NO_CONTEXT_SWITCH_, unwrap_spec=[object, object], no_result=True) -def func(interp, w_block_closure, w_a0): - activateClosure(interp, w_block_closure, [w_a0], mayContextSwitch=False) + at expose_primitive(CLOSURE_VALUE_NO_CONTEXT_SWITCH_, unwrap_spec=[object, object], result_is_new_frame=True) +def func(interp, s_frame, w_block_closure, w_a0): + return activateClosure(interp, s_frame, w_block_closure, [w_a0], mayContextSwitch=False) # ___________________________________________________________________________ # PrimitiveLoadInstVar @@ -1002,7 +999,7 @@ for i in range(264, 520): def make_prim(i): @expose_primitive(i, unwrap_spec=[object]) - def func(interp, w_object): + def func(interp, s_frame, w_object): return w_object.fetch(interp.space, i - 264) globals()["INST_VAR_AT_%d" % (i-264)] = i make_prim(i) diff --git a/spyvm/shadow.py b/spyvm/shadow.py --- a/spyvm/shadow.py +++ b/spyvm/shadow.py @@ -502,7 +502,7 @@ def peek(self, idx): rpos = rarithmetic.r_uint(idx) - return self._temps_and_stack[self._stack_ptr + ~rpos] + return self._temps_and_stack[jit.promote(self._stack_ptr) + ~rpos] @jit.unroll_safe def pop_n(self, n): diff --git a/spyvm/test/jit.py b/spyvm/test/jit.py --- a/spyvm/test/jit.py +++ b/spyvm/test/jit.py @@ -65,9 +65,8 @@ s_class = w_object.shadow_of_my_class(space) w_method = s_class.lookup(w_selector) w_frame = w_method.create_frame(space, w_object, []) - interp.store_w_active_context(w_frame) def interp_w(): - interp.loop() + interp.loop(w_frame) self.meta_interp(interp_w, [], listcomp=True, listops=True, backendopt=True) diff --git a/spyvm/test/test_interpreter.py b/spyvm/test/test_interpreter.py --- a/spyvm/test/test_interpreter.py +++ b/spyvm/test/test_interpreter.py @@ -5,6 +5,7 @@ mockclass = objspace.bootstrap_class space = objspace.ObjSpace() +interp = interpreter.Interpreter(space) # expose the bytecode's values as global constants. # Bytecodes that have a whole range are exposed as global functions: @@ -76,7 +77,7 @@ return lit return [fakeliteral(lit) for lit in literals] -def new_interpreter(bytes, receiver=space.w_nil, space=space): +def new_frame(bytes, receiver=space.w_nil, space=space): assert isinstance(bytes, str) w_method = model.W_CompiledMethod(len(bytes)) w_method.islarge = 1 @@ -85,9 +86,7 @@ w_method.tempsize=8 w_method.setliterals([model.W_PointersObject(None, 2)]) w_frame = w_method.create_frame(space, receiver, ["foo", "bar"]) - interp = interpreter.Interpreter(space) - interp.store_w_active_context(w_frame) - return interp + return w_frame, w_frame.as_context_get_shadow(space) def test_create_frame(): w_method = model.W_CompiledMethod(len("hello")) @@ -108,8 +107,7 @@ assert s_frame.getbytecode() == ord("l") def test_push_pop(): - interp = new_interpreter("") - frame = interp.s_active_context() + _, frame = new_frame("") frame.push(12) frame.push(34) frame.push(56) @@ -123,15 +121,15 @@ assert frame.top() == 12 def test_unknownBytecode(): - interp = new_interpreter(unknownBytecode) - py.test.raises(interpreter.MissingBytecode, interp.interpret) + w_frame, s_frame = new_frame(unknownBytecode) + py.test.raises(interpreter.MissingBytecode, interp.step, s_frame) # push bytecodes def test_pushReceiverBytecode(): - interp = new_interpreter(pushReceiverBytecode) - interp.step(interp.s_active_context()) - assert interp.s_active_context().top().is_same_object( - interp.w_active_context().as_methodcontext_get_shadow(space).w_receiver()) + w_frame, s_frame = new_frame(pushReceiverBytecode) + interp.step(s_frame) + assert s_frame.top().is_same_object( + s_frame.w_receiver()) def test_pushReceiverVariableBytecode(bytecode = (pushReceiverVariableBytecode(0) + pushReceiverVariableBytecode(1) + @@ -140,31 +138,33 @@ w_demo.store(space, 0, "egg") w_demo.store(space, 1, "bar") w_demo.store(space, 2, "baz") - interp = new_interpreter(bytecode, receiver = w_demo) - interp.step(interp.s_active_context()) - interp.step(interp.s_active_context()) - interp.step(interp.s_active_context()) - assert interp.s_active_context().stack() == ["egg", "bar", "baz"] + w_frame, s_frame = new_frame(bytecode, receiver = w_demo) + s_frame = w_frame.as_context_get_shadow(space) + interp.step(s_frame) + interp.step(s_frame) + interp.step(s_frame) + assert s_frame.stack() == ["egg", "bar", "baz"] def test_pushTemporaryVariableBytecode(bytecode=(pushTemporaryVariableBytecode(0) + pushTemporaryVariableBytecode(1) + pushTemporaryVariableBytecode(2))): - interp = new_interpreter(bytecode) - interp.w_active_context().as_methodcontext_get_shadow(space).settemp(2, "temp") - interp.step(interp.s_active_context()) - interp.step(interp.s_active_context()) - interp.step(interp.s_active_context()) - assert interp.s_active_context().stack() == ["foo", "bar", "temp"] + w_frame, s_frame = new_frame(bytecode) + s_frame = w_frame.as_context_get_shadow(space) + s_frame.settemp(2, "temp") + interp.step(s_frame) + interp.step(s_frame) + interp.step(s_frame) + assert s_frame.stack() == ["foo", "bar", "temp"] def test_pushLiteralConstantBytecode(bytecode=pushLiteralConstantBytecode(0) + pushLiteralConstantBytecode(1) + pushLiteralConstantBytecode(2)): - interp = new_interpreter(bytecode) - interp.w_active_context().as_methodcontext_get_shadow(space).w_method().setliterals(fakeliterals(space, "a", "b", "c")) - interp.step(interp.s_active_context()) - interp.step(interp.s_active_context()) - interp.step(interp.s_active_context()) - assert interp.s_active_context().stack() == [fakesymbol("a"), + w_frame, s_frame = new_frame(bytecode) + s_frame.w_method().setliterals(fakeliterals(space, "a", "b", "c")) + interp.step(s_frame) + interp.step(s_frame) + interp.step(s_frame) + assert s_frame.stack() == [fakesymbol("a"), fakesymbol("b"), fakesymbol("c")] @@ -172,24 +172,24 @@ w_association = mockclass(space, 2).as_class_get_shadow(space).new() w_association.store(space, 0, "mykey") w_association.store(space, 1, "myvalue") - interp = new_interpreter(bytecode) - interp.w_active_context().as_methodcontext_get_shadow(space).w_method().setliterals( fakeliterals(space, w_association)) - interp.step(interp.s_active_context()) - assert interp.s_active_context().stack() == ["myvalue"] + w_frame, s_frame = new_frame(bytecode) + s_frame.w_method().setliterals( fakeliterals(space, w_association)) + interp.step(s_frame) + assert s_frame.stack() == ["myvalue"] def test_storeAndPopReceiverVariableBytecode(bytecode=storeAndPopReceiverVariableBytecode, popped=True): shadow = mockclass(space, 8).as_class_get_shadow(space) for index in range(8): w_object = shadow.new() - interp = new_interpreter(pushConstantTrueBytecode + bytecode(index)) - interp.w_active_context().as_methodcontext_get_shadow(space).store_w_receiver(w_object) - interp.step(interp.s_active_context()) - interp.step(interp.s_active_context()) + w_frame, s_frame = new_frame(pushConstantTrueBytecode + bytecode(index)) + s_frame.store_w_receiver(w_object) + interp.step(s_frame) + interp.step(s_frame) if popped: - assert interp.s_active_context().stack() == [] + assert s_frame.stack() == [] else: - assert interp.s_active_context().stack() == [space.w_true] + assert s_frame.stack() == [space.w_true] for test_index in range(8): if test_index == index: @@ -199,171 +199,170 @@ def test_storeAndPopTemporaryVariableBytecode(bytecode=storeAndPopTemporaryVariableBytecode): for index in range(8): - interp = new_interpreter(pushConstantTrueBytecode + bytecode(index)) - #interp.w_active_context().as_methodcontext_get_shadow(space).temps = [None] * 8 - interp.step(interp.s_active_context()) - interp.step(interp.s_active_context()) - assert interp.s_active_context().stack() == [] - interp.w_active_context().as_methodcontext_get_shadow(space) + w_frame, s_frame = new_frame(pushConstantTrueBytecode + bytecode(index)) + #s_frame.temps = [None] * 8 + interp.step(s_frame) + interp.step(s_frame) + assert s_frame.stack() == [] for test_index in range(8): - print interp.w_active_context()._vars + print w_frame._vars if test_index == index: - assert interp.s_active_context().gettemp(test_index) == space.w_true + assert s_frame.gettemp(test_index) == space.w_true else: - assert interp.s_active_context().gettemp(test_index) != space.w_true + assert s_frame.gettemp(test_index) != space.w_true def test_pushConstantTrueBytecode(): - interp = new_interpreter(pushConstantTrueBytecode) - interp.step(interp.s_active_context()) - assert interp.s_active_context().pop().is_same_object(space.w_true) - assert interp.s_active_context().stack() == [] + w_frame, s_frame = new_frame(pushConstantTrueBytecode) + interp.step(s_frame) + assert s_frame.pop().is_same_object(space.w_true) + assert s_frame.stack() == [] def test_pushConstantFalseBytecode(): - interp = new_interpreter(pushConstantFalseBytecode) - interp.step(interp.s_active_context()) - assert interp.s_active_context().pop().is_same_object(space.w_false) - assert interp.s_active_context().stack() == [] + w_frame, s_frame = new_frame(pushConstantFalseBytecode) + interp.step(s_frame) + assert s_frame.pop().is_same_object(space.w_false) + assert s_frame.stack() == [] def test_pushConstantNilBytecode(): - interp = new_interpreter(pushConstantNilBytecode) - interp.step(interp.s_active_context()) - assert interp.s_active_context().pop().is_same_object(space.w_nil) - assert interp.s_active_context().stack() == [] + w_frame, s_frame = new_frame(pushConstantNilBytecode) + interp.step(s_frame) + assert s_frame.pop().is_same_object(space.w_nil) + assert s_frame.stack() == [] def test_pushConstantMinusOneBytecode(): - interp = new_interpreter(pushConstantMinusOneBytecode) - interp.step(interp.s_active_context()) - assert interp.s_active_context().pop().is_same_object(space.w_minus_one) - assert interp.s_active_context().stack() == [] + w_frame, s_frame = new_frame(pushConstantMinusOneBytecode) + interp.step(s_frame) + assert s_frame.pop().is_same_object(space.w_minus_one) + assert s_frame.stack() == [] def test_pushConstantZeroBytecode(): - interp = new_interpreter(pushConstantZeroBytecode) - interp.step(interp.s_active_context()) - assert interp.s_active_context().pop().is_same_object(space.w_zero) - assert interp.s_active_context().stack() == [] - + w_frame, s_frame = new_frame(pushConstantZeroBytecode) + interp.step(s_frame) + assert s_frame.pop().is_same_object(space.w_zero) + assert s_frame.stack() == [] + def test_pushConstantOneBytecode(): - interp = new_interpreter(pushConstantOneBytecode) - interp.step(interp.s_active_context()) - assert interp.s_active_context().pop().is_same_object(space.w_one) - assert interp.s_active_context().stack() == [] + w_frame, s_frame = new_frame(pushConstantOneBytecode) + interp.step(s_frame) + assert s_frame.pop().is_same_object(space.w_one) + assert s_frame.stack() == [] def test_pushConstantTwoBytecode(): - interp = new_interpreter(pushConstantTwoBytecode) - interp.step(interp.s_active_context()) - assert interp.s_active_context().pop().is_same_object(space.w_two) - assert interp.s_active_context().stack() == [] + w_frame, s_frame = new_frame(pushConstantTwoBytecode) + interp.step(s_frame) + assert s_frame.pop().is_same_object(space.w_two) + assert s_frame.stack() == [] def test_pushActiveContextBytecode(): - interp = new_interpreter(pushActiveContextBytecode) - interp.step(interp.s_active_context()) - assert interp.s_active_context().pop() == interp.w_active_context() - assert interp.s_active_context().stack() == [] + w_frame, s_frame = new_frame(pushActiveContextBytecode) + interp.step(s_frame) + assert s_frame.pop() == w_frame + assert s_frame.stack() == [] def test_duplicateTopBytecode(): - interp = new_interpreter(pushConstantZeroBytecode + duplicateTopBytecode) - interp.step(interp.s_active_context()) - interp.step(interp.s_active_context()) - assert interp.s_active_context().stack() == [space.w_zero, space.w_zero] + w_frame, s_frame = new_frame(pushConstantZeroBytecode + duplicateTopBytecode) + interp.step(s_frame) + interp.step(s_frame) + assert s_frame.stack() == [space.w_zero, space.w_zero] def test_bytecodePrimBitAnd(): - interp = new_interpreter(pushConstantOneBytecode + pushConstantTwoBytecode + bytecodePrimBitAnd) - interp.step(interp.s_active_context()) - interp.step(interp.s_active_context()) - interp.step(interp.s_active_context()) - assert interp.s_active_context().pop().value == 0 - assert interp.s_active_context().stack() == [] + w_frame, s_frame = new_frame(pushConstantOneBytecode + pushConstantTwoBytecode + bytecodePrimBitAnd) + interp.step(s_frame) + interp.step(s_frame) + interp.step(s_frame) + assert s_frame.pop().value == 0 + assert s_frame.stack() == [] def test_bytecodePrimBitOr(): - interp = new_interpreter(pushConstantOneBytecode + pushConstantTwoBytecode + bytecodePrimBitOr) - interp.step(interp.s_active_context()) - interp.step(interp.s_active_context()) - interp.step(interp.s_active_context()) - assert interp.s_active_context().pop().value == 3 - assert interp.s_active_context().stack() == [] + w_frame, s_frame = new_frame(pushConstantOneBytecode + pushConstantTwoBytecode + bytecodePrimBitOr) + interp.step(s_frame) + interp.step(s_frame) + interp.step(s_frame) + assert s_frame.pop().value == 3 + assert s_frame.stack() == [] def test_bytecodePrimBitShift(): - interp = new_interpreter(pushConstantOneBytecode + pushConstantTwoBytecode + bytecodePrimBitShift) - interp.step(interp.s_active_context()) - interp.step(interp.s_active_context()) - interp.step(interp.s_active_context()) - assert interp.s_active_context().pop().value == 4 - assert interp.s_active_context().stack() == [] + w_frame, s_frame = new_frame(pushConstantOneBytecode + pushConstantTwoBytecode + bytecodePrimBitShift) + interp.step(s_frame) + interp.step(s_frame) + interp.step(s_frame) + assert s_frame.pop().value == 4 + assert s_frame.stack() == [] def test_bytecodePrimClass(): - interp = new_interpreter(pushConstantOneBytecode + bytecodePrimClass) - interp.step(interp.s_active_context()) - interp.step(interp.s_active_context()) - assert interp.s_active_context().pop() == space.w_SmallInteger - assert interp.s_active_context().stack() == [] + w_frame, s_frame = new_frame(pushConstantOneBytecode + bytecodePrimClass) + interp.step(s_frame) + interp.step(s_frame) + assert s_frame.pop() == space.w_SmallInteger + assert s_frame.stack() == [] def test_bytecodePrimSubtract(): - interp = new_interpreter(pushConstantOneBytecode + pushConstantTwoBytecode + bytecodePrimSubtract) - interp.step(interp.s_active_context()) - interp.step(interp.s_active_context()) - interp.step(interp.s_active_context()) - assert interp.s_active_context().pop().value == -1 - assert interp.s_active_context().stack() == [] + w_frame, s_frame = new_frame(pushConstantOneBytecode + pushConstantTwoBytecode + bytecodePrimSubtract) + interp.step(s_frame) + interp.step(s_frame) + interp.step(s_frame) + assert s_frame.pop().value == -1 + assert s_frame.stack() == [] def test_bytecodePrimMultiply(): - interp = new_interpreter(pushConstantMinusOneBytecode + pushConstantTwoBytecode + bytecodePrimMultiply) - interp.step(interp.s_active_context()) - interp.step(interp.s_active_context()) - interp.step(interp.s_active_context()) - assert interp.s_active_context().pop().value == -2 - assert interp.s_active_context().stack() == [] + w_frame, s_frame = new_frame(pushConstantMinusOneBytecode + pushConstantTwoBytecode + bytecodePrimMultiply) + interp.step(s_frame) + interp.step(s_frame) + interp.step(s_frame) + assert s_frame.pop().value == -2 + assert s_frame.stack() == [] def test_bytecodePrimDivide(): - interp = new_interpreter(pushConstantTwoBytecode + pushConstantMinusOneBytecode + bytecodePrimDivide) - interp.step(interp.s_active_context()) - interp.step(interp.s_active_context()) - interp.step(interp.s_active_context()) - assert interp.s_active_context().pop().value == -2 - assert interp.s_active_context().stack() == [] + w_frame, s_frame = new_frame(pushConstantTwoBytecode + pushConstantMinusOneBytecode + bytecodePrimDivide) + interp.step(s_frame) + interp.step(s_frame) + interp.step(s_frame) + assert s_frame.pop().value == -2 + assert s_frame.stack() == [] def test_bytecodePrimDiv(): - interp = new_interpreter(pushConstantTwoBytecode + pushConstantMinusOneBytecode + bytecodePrimDiv) - interp.step(interp.s_active_context()) - interp.step(interp.s_active_context()) - interp.step(interp.s_active_context()) - assert interp.s_active_context().pop().value == -2 - assert interp.s_active_context().stack() == [] + w_frame, s_frame = new_frame(pushConstantTwoBytecode + pushConstantMinusOneBytecode + bytecodePrimDiv) + interp.step(s_frame) + interp.step(s_frame) + interp.step(s_frame) + assert s_frame.pop().value == -2 + assert s_frame.stack() == [] def test_bytecodePrimMod(): - interp = new_interpreter(pushConstantTwoBytecode + pushConstantMinusOneBytecode + bytecodePrimMod) - interp.step(interp.s_active_context()) - interp.step(interp.s_active_context()) - interp.step(interp.s_active_context()) - assert interp.s_active_context().pop().value == 0 - assert interp.s_active_context().stack() == [] + w_frame, s_frame = new_frame(pushConstantTwoBytecode + pushConstantMinusOneBytecode + bytecodePrimMod) + interp.step(s_frame) + interp.step(s_frame) + interp.step(s_frame) + assert s_frame.pop().value == 0 + assert s_frame.stack() == [] def test_bytecodePrimEquivalent(): - interp = new_interpreter(pushConstantTwoBytecode + pushConstantMinusOneBytecode + bytecodePrimEquivalent) - interp.step(interp.s_active_context()) - interp.step(interp.s_active_context()) - interp.step(interp.s_active_context()) - assert interp.s_active_context().pop() == space.w_false - assert interp.s_active_context().stack() == [] + w_frame, s_frame = new_frame(pushConstantTwoBytecode + pushConstantMinusOneBytecode + bytecodePrimEquivalent) + interp.step(s_frame) + interp.step(s_frame) + interp.step(s_frame) + assert s_frame.pop() == space.w_false + assert s_frame.stack() == [] - interp = new_interpreter(pushConstantOneBytecode + pushConstantOneBytecode + bytecodePrimEquivalent) - interp.step(interp.s_active_context()) - interp.step(interp.s_active_context()) - interp.step(interp.s_active_context()) - assert interp.s_active_context().pop() == space.w_true - assert interp.s_active_context().stack() == [] + w_frame, s_frame = new_frame(pushConstantOneBytecode + pushConstantOneBytecode + bytecodePrimEquivalent) + interp.step(s_frame) + interp.step(s_frame) + interp.step(s_frame) + assert s_frame.pop() == space.w_true + assert s_frame.stack() == [] def test_bytecodePrimNew(): w_fakeclassclass = mockclass(space, 10, name='fakeclassclass') w_fakeclass = mockclass(space, 1, name='fakeclass', varsized=False, w_metaclass=w_fakeclassclass) - interp = new_interpreter(bytecodePrimNew) - interp.s_active_context().push(w_fakeclass) + w_frame, s_frame = new_frame(bytecodePrimNew) + s_frame.push(w_fakeclass) run_with_faked_primitive_methods( [[w_fakeclassclass, primitives.NEW, 0, "new"]], interp.step, - interp.s_active_context()) - w_fakeinst = interp.s_active_context().pop() - assert interp.s_active_context().stack() == [] + s_frame) + w_fakeinst = s_frame.pop() + assert s_frame.stack() == [] assert w_fakeinst.getclass(space).is_same_object(w_fakeclass) assert w_fakeinst.size() == 1 @@ -371,29 +370,29 @@ w_fakeclassclass = mockclass(space, 10, name='fakeclassclass') w_fakeclass = mockclass(space, 1, name='fakeclass', varsized=True, w_metaclass=w_fakeclassclass) - interp = new_interpreter(bytecodePrimNewWithArg) - interp.s_active_context().push(w_fakeclass) - interp.s_active_context().push(space.w_two) + w_frame, s_frame = new_frame(bytecodePrimNewWithArg) + s_frame.push(w_fakeclass) + s_frame.push(space.w_two) run_with_faked_primitive_methods( [[w_fakeclassclass, primitives.NEW_WITH_ARG, 1, "new:"]], interp.step, - interp.s_active_context()) - w_fakeinst = interp.s_active_context().pop() - assert interp.s_active_context().stack() == [] + s_frame) + w_fakeinst = s_frame.pop() + assert s_frame.stack() == [] assert w_fakeinst.getclass(space).is_same_object(w_fakeclass) assert w_fakeinst.size() == 3 def test_bytecodePrimSize(): w_fakeclass = mockclass(space, 2, name='fakeclass', varsized=True) w_fakeinst = w_fakeclass.as_class_get_shadow(space).new(5) - interp = new_interpreter(bytecodePrimSize) - interp.s_active_context().push(w_fakeinst) + w_frame, s_frame = new_frame(bytecodePrimSize) + s_frame.push(w_fakeinst) run_with_faked_primitive_methods( [[w_fakeclass, primitives.SIZE, 0, "size"]], interp.step, - interp.s_active_context()) - assert interp.s_active_context().pop().value == 5 - assert interp.s_active_context().stack() == [] + s_frame) + assert s_frame.pop().value == 5 + assert s_frame.stack() == [] # w_class - the class from which the method is going to be called # (and on which it is going to be installed) @@ -411,20 +410,21 @@ literals = fakeliterals(space, "foo") w_foo = literals[0] shadow.installmethod(w_foo, w_method) - interp = new_interpreter(bytecodes) - interp.w_active_context().as_methodcontext_get_shadow(space).w_method().setliterals(literals) - interp.s_active_context().push(w_object) - callerContext = interp.w_active_context() - interp.step(interp.s_active_context()) - assert interp.s_active_context().w_sender() == callerContext - assert interp.s_active_context().stack() == [] - assert interp.w_active_context().as_methodcontext_get_shadow(space).w_receiver().is_same_object(w_object) - assert interp.w_active_context().as_methodcontext_get_shadow(space).w_method().is_same_object(shadow.s_methoddict().methoddict[w_foo]) - assert callerContext.as_context_get_shadow(space).stack() == [] - interp.step(interp.s_active_context()) - interp.step(interp.s_active_context()) - assert interp.w_active_context() == callerContext - assert interp.s_active_context().stack() == [result] + w_frame, s_frame = new_frame(bytecodes) + s_frame.w_method().setliterals(literals) + s_frame.push(w_object) + w_active_context = interp.step(s_frame) + s_active_context = w_active_context.as_context_get_shadow(space) + assert s_active_context.w_sender() == w_frame + assert s_active_context.stack() == [] + assert w_active_context.as_methodcontext_get_shadow(space).w_receiver().is_same_object(w_object) + assert w_active_context.as_methodcontext_get_shadow(space).w_method().is_same_object(shadow.s_methoddict().methoddict[w_foo]) + assert s_frame.stack() == [] + interp.step(s_active_context) + w_active_context = interp.step(s_active_context) + s_active_context = w_active_context.as_context_get_shadow(space) + assert w_active_context == w_frame + assert s_active_context.stack() == [result] def test_sendLiteralSelectorBytecode(): w_class = mockclass(space, 0) @@ -443,25 +443,24 @@ method.setliterals(literals) shadow.installmethod(literals[0], method) w_object = shadow.new() - interp = new_interpreter(sendLiteralSelectorBytecode(16) + returnTopFromMethod) - interp.w_active_context().as_methodcontext_get_shadow(space).w_method().setliterals(literals) - interp.s_active_context().push(w_object) - interp.s_active_context().push(space.wrap_int(8)) - result = interp.interpret() + w_frame, s_frame = new_frame(sendLiteralSelectorBytecode(16) + returnTopFromMethod) + s_frame.w_method().setliterals(literals) + s_frame.push(w_object) + s_frame.push(space.wrap_int(8)) + result = interp.interpret_with_w_frame(w_frame) assert space.unwrap_int(result) == 34 def test_send_to_primitive(): def test(): - interp = new_interpreter(sendLiteralSelectorBytecode(1 + 16)) - interp.w_active_context().as_methodcontext_get_shadow(space).w_method().setliterals(fakeliterals(space, "foo", "-")) - interp.s_active_context().push(space.wrap_int(50)) - interp.s_active_context().push(space.wrap_int(8)) - callerContext = interp.w_active_context() - interp.step(interp.s_active_context()) - assert interp.w_active_context() is callerContext - assert len(interp.s_active_context().stack()) == 1 - w_result = interp.s_active_context().pop() + w_frame, s_frame = new_frame(sendLiteralSelectorBytecode(1 + 16)) + s_frame.w_method().setliterals(fakeliterals(space, "foo", "-")) + s_frame.push(space.wrap_int(50)) + s_frame.push(space.wrap_int(8)) + w_new_frame = interp.step(s_frame) + assert w_new_frame is None + assert len(s_frame.stack()) == 1 + w_result = s_frame.pop() assert space.unwrap_int(w_result) == 42 run_with_faked_primitive_methods( @@ -470,72 +469,72 @@ test) def test_makePoint(): - interp = new_interpreter(pushConstantZeroBytecode + + w_frame, s_frame = new_frame(pushConstantZeroBytecode + pushConstantOneBytecode + bytecodePrimMakePoint) - interp.step(interp.s_active_context()) - interp.step(interp.s_active_context()) - interp.step(interp.s_active_context()) - w_point = interp.s_active_context().top() + interp.step(s_frame) + interp.step(s_frame) + interp.step(s_frame) + w_point = s_frame.top() from spyvm.wrapper import PointWrapper point = PointWrapper(interp.space, w_point) assert point.x() == 0 assert point.y() == 1 def test_longJumpIfTrue(): - interp = new_interpreter(longJumpIfTrue(0) + chr(15) + longJumpIfTrue(0) + chr(15)) - interp.s_active_context().push(space.w_false) - pc = interp.s_active_context().pc() + 2 - interp.step(interp.s_active_context()) - assert interp.s_active_context().pc() == pc - interp.s_active_context().push(space.w_true) - pc = interp.s_active_context().pc() + 2 - interp.step(interp.s_active_context()) - assert interp.s_active_context().pc() == pc + 15 + w_frame, s_frame = new_frame(longJumpIfTrue(0) + chr(15) + longJumpIfTrue(0) + chr(15)) + s_frame.push(space.w_false) + pc = s_frame.pc() + 2 + interp.step(s_frame) + assert s_frame.pc() == pc + s_frame.push(space.w_true) + pc = s_frame.pc() + 2 + interp.step(s_frame) + assert s_frame.pc() == pc + 15 def test_longJumpIfFalse(): - interp = new_interpreter(pushConstantTrueBytecode + longJumpIfFalse(0) + chr(15) + + w_frame, s_frame = new_frame(pushConstantTrueBytecode + longJumpIfFalse(0) + chr(15) + pushConstantFalseBytecode + longJumpIfFalse(0) + chr(15)) - interp.step(interp.s_active_context()) - pc = interp.s_active_context().pc() + 2 - interp.step(interp.s_active_context()) - assert interp.s_active_context().pc() == pc - interp.step(interp.s_active_context()) - pc = interp.s_active_context().pc() + 2 - interp.step(interp.s_active_context()) - assert interp.s_active_context().pc() == pc + 15 + interp.step(s_frame) + pc = s_frame.pc() + 2 + interp.step(s_frame) + assert s_frame.pc() == pc + interp.step(s_frame) + pc = s_frame.pc() + 2 + interp.step(s_frame) + assert s_frame.pc() == pc + 15 def test_longUnconditionalJump(): - interp = new_interpreter(longUnconditionalJump(4) + chr(15)) - pc = interp.s_active_context().pc() + 2 - interp.step(interp.s_active_context()) - assert interp.s_active_context().pc() == pc + 15 + w_frame, s_frame = new_frame(longUnconditionalJump(4) + chr(15)) + pc = s_frame.pc() + 2 + interp.step(s_frame) + assert s_frame.pc() == pc + 15 def test_shortUnconditionalJump(): - interp = new_interpreter(chr(145)) - pc = interp.s_active_context().pc() + 1 - interp.step(interp.s_active_context()) - assert interp.s_active_context().pc() == pc + 2 + w_frame, s_frame = new_frame(chr(145)) + pc = s_frame.pc() + 1 + interp.step(s_frame) + assert s_frame.pc() == pc + 2 def test_shortConditionalJump(): - interp = new_interpreter(pushConstantTrueBytecode + shortConditionalJump(3) + + w_frame, s_frame = new_frame(pushConstantTrueBytecode + shortConditionalJump(3) + pushConstantFalseBytecode + shortConditionalJump(3)) - interp.step(interp.s_active_context()) - pc = interp.s_active_context().pc() + 1 - interp.step(interp.s_active_context()) - assert interp.s_active_context().pc() == pc - interp.step(interp.s_active_context()) - pc = interp.s_active_context().pc() + 1 - interp.step(interp.s_active_context()) - assert interp.s_active_context().pc() == pc + 4 + interp.step(s_frame) + pc = s_frame.pc() + 1 + interp.step(s_frame) + assert s_frame.pc() == pc + interp.step(s_frame) + pc = s_frame.pc() + 1 + interp.step(s_frame) + assert s_frame.pc() == pc + 4 def test_popStackBytecode(): - interp = new_interpreter(pushConstantTrueBytecode + + w_frame, s_frame = new_frame(pushConstantTrueBytecode + popStackBytecode) - interp.step(interp.s_active_context()) - assert interp.s_active_context().stack() == [space.w_true] - interp.step(interp.s_active_context()) - assert interp.s_active_context().stack() == [] + interp.step(s_frame) + assert s_frame.stack() == [space.w_true] + interp.step(s_frame) + assert s_frame.stack() == [] def test_extendedPushBytecode(): test_pushReceiverVariableBytecode(extendedPushBytecode + chr((0<<6) + 0) + @@ -556,10 +555,10 @@ w_association = mockclass(space, 2).as_class_get_shadow(space).new() w_association.store(space, 0, "mykey") w_association.store(space, 1, "myvalue") - interp = new_interpreter(pushConstantOneBytecode + bytecode) - interp.w_active_context().as_methodcontext_get_shadow(space).w_method().setliterals(fakeliterals(space, w_association)) - interp.step(interp.s_active_context()) - interp.step(interp.s_active_context()) + w_frame, s_frame = new_frame(pushConstantOneBytecode + bytecode) + s_frame.w_method().setliterals(fakeliterals(space, w_association)) + interp.step(s_frame) + interp.step(s_frame) assert w_association.fetch(space, 1).is_same_object(space.w_one) def test_extendedStoreAndPopBytecode(): @@ -574,7 +573,7 @@ storeAssociation(extendedStoreAndPopBytecode + chr((3<<6) + 0)) def test_callPrimitiveAndPush_fallback(): - interp = new_interpreter(bytecodePrimAdd) + w_frame, s_frame = new_frame(bytecodePrimAdd) shadow = mockclass(space, 0).as_class_get_shadow(space) w_method = model.W_CompiledMethod(0) w_method.argsize = 1 @@ -586,26 +585,27 @@ space.w_special_selectors.atput0(space, constants.find_selectorindex("+"), w_symbol) w_object = shadow.new() - interp.s_active_context().push(w_object) - interp.s_active_context().push(space.w_one) - interp.step(interp.s_active_context()) - assert interp.w_active_context().as_methodcontext_get_shadow(space).w_method() == shadow.s_methoddict().methoddict[w_symbol] - assert interp.s_active_context().w_receiver() is w_object - assert interp.w_active_context().as_methodcontext_get_shadow(space).gettemp(0).is_same_object(space.w_one) - assert interp.s_active_context().stack() == [] + s_frame.push(w_object) + s_frame.push(space.w_one) + w_active_context = interp.step(s_frame) + s_active_context = w_active_context.as_context_get_shadow(space) + assert w_active_context.as_methodcontext_get_shadow(space).w_method() == shadow.s_methoddict().methoddict[w_symbol] + assert s_active_context.w_receiver() is w_object + assert w_active_context.as_methodcontext_get_shadow(space).gettemp(0).is_same_object(space.w_one) + assert s_active_context.stack() == [] def test_bytecodePrimBool(): - interp = new_interpreter(bytecodePrimLessThan + + w_frame, s_frame = new_frame(bytecodePrimLessThan + bytecodePrimGreaterThan + bytecodePrimLessOrEqual + bytecodePrimGreaterOrEqual + bytecodePrimEqual + bytecodePrimNotEqual) for i in range(6): - interp.s_active_context().push(space.w_one) - interp.s_active_context().push(space.w_two) - interp.step(interp.s_active_context()) - assert interp.s_active_context().stack() == [space.w_true, space.w_false, + s_frame.push(space.w_one) + s_frame.push(space.w_two) + interp.step(s_frame) + assert s_frame.stack() == [space.w_true, space.w_false, space.w_true, space.w_false, space.w_false, space.w_true] @@ -635,20 +635,23 @@ w_super.as_class_get_shadow(space).installmethod(foo, meth2) meth3 = model.W_CompiledMethod(0) w_supersuper.as_class_get_shadow(space).installmethod(foo, meth3) - interp = new_interpreter(bytecodes) - interp.w_active_context().as_methodcontext_get_shadow(space).w_method().setliterals(literals) - interp.s_active_context().push(w_object) - interp.step(interp.s_active_context()) + w_frame, s_frame = new_frame(bytecodes) + s_frame.w_method().setliterals(literals) + s_frame.push(w_object) + w_active_context = interp.step(s_frame) + s_active_context = w_active_context.as_context_get_shadow(space) for w_specificclass in [w_super, w_supersuper]: - callerContext = interp.w_active_context() - interp.step(interp.s_active_context()) - interp.step(interp.s_active_context()) - assert interp.s_active_context().w_sender() == callerContext - assert interp.s_active_context().stack() == [] - assert interp.w_active_context().as_methodcontext_get_shadow(space).w_receiver() == w_object + w_caller_context = w_active_context + s_caller_context = s_active_context + interp.step(s_active_context) + w_active_context = interp.step(s_active_context) + s_active_context = w_active_context.as_context_get_shadow(space) + assert s_active_context.w_sender() == w_caller_context + assert s_active_context.stack() == [] + assert w_active_context.as_methodcontext_get_shadow(space).w_receiver() == w_object meth = w_specificclass.as_class_get_shadow(space).s_methoddict().methoddict[foo] - assert interp.w_active_context().as_methodcontext_get_shadow(space).w_method() == meth - assert callerContext.as_context_get_shadow(space).stack() == [] + assert s_active_context.w_method() == meth + assert s_caller_context.stack() == [] def test_secondExtendedSendBytecode(): w_class = mockclass(space, 0) @@ -681,9 +684,9 @@ def interpret_bc(bcodes, literals, receiver=space.w_nil): bcode = "".join([chr(x) for x in bcodes]) - interp = new_interpreter(bcode, receiver=receiver) - interp.w_active_context().as_methodcontext_get_shadow(space).w_method().setliterals(literals) - return interp.interpret() + w_frame, s_frame = new_frame(bcode, receiver=receiver) + s_frame.w_method().setliterals(literals) + return interp.interpret_with_w_frame(w_frame) # tests: bytecodePrimValue & bytecodePrimValueWithArg def test_bc_3_plus_4(): @@ -849,44 +852,39 @@ # Closure Bytecodes def test_bc_pushNewArrayBytecode(bytecode=pushNewArrayBytecode): - interp = new_interpreter(bytecode + chr(0x83)) - context = interp.s_active_context() - context.push(fakeliterals(space, "egg")) - context.push(fakeliterals(space, "bar")) - context.push(fakeliterals(space, "baz")) - interp.step(interp.s_active_context()) - array = context.pop() + w_frame, s_frame = new_frame(bytecode + chr(0x83)) + s_frame.push(fakeliterals(space, "egg")) + s_frame.push(fakeliterals(space, "bar")) + s_frame.push(fakeliterals(space, "baz")) + interp.step(s_frame) + array = s_frame.pop() assert array.at0(space, 0) == fakeliterals(space, "egg") assert array.at0(space, 1) == fakeliterals(space, "bar") assert array.at0(space, 2) == fakeliterals(space, "baz") def test_bc_pushNewArray(bytecode=pushNewArrayBytecode): - interp = new_interpreter(bytecode + chr(0x07)) - context = interp.s_active_context() - interp.step(interp.s_active_context()) - array = context.pop() + w_frame, s_frame = new_frame(bytecode + chr(0x07)) + interp.step(s_frame) + array = s_frame.pop() assert array.size() == 7 assert array.at0(space, 0) == space.w_nil def test_bc_pushRemoteTempLongBytecode(bytecode = pushRemoteTempLongBytecode): - interp = new_interpreter(bytecode + chr(0) + chr(0)) - context = interp.s_active_context() - context.push(fakeliterals(space, "jam")) - context.settemp(0, space.w_Array.as_class_get_shadow(interp.space).new(2)) - interp.step(interp.s_active_context()) - assert context.top() == space.w_nil + w_frame, s_frame = new_frame(bytecode + chr(0) + chr(0)) + s_frame.settemp(0, space.w_Array.as_class_get_shadow(interp.space).new(2)) + interp.step(s_frame) + assert s_frame.top() == space.w_nil def setupTempArrayAndContext(bytecode): # both indizes are 0-relative - interp = new_interpreter(bytecode + chr(2) + chr(1)) - context = interp.s_active_context() - context.push(fakeliterals(space, "english")) - context.push(fakeliterals(space, "bar")) + w_frame, s_frame = new_frame(bytecode + chr(2) + chr(1)) + s_frame.push(fakeliterals(space, "english")) + s_frame.push(fakeliterals(space, "bar")) temp_array = space.w_Array.as_class_get_shadow(interp.space).new(3) temp_array.atput0(space, 2, fakeliterals(space, "pub")) - context.settemp(1, temp_array) - interp.step(context) - return context, temp_array + s_frame.settemp(1, temp_array) + interp.step(s_frame) + return s_frame, temp_array def test_bc_pushRemoteTempLongBytecode2(bytecode = pushRemoteTempLongBytecode): context, _ = setupTempArrayAndContext(bytecode) @@ -904,26 +902,24 @@ def test_bc_pushClosureCopyCopied0ValuesBytecode(bytecode = pushClosureCopyCopiedValuesBytecode): for i in (0, 0xF0, 0x0FF0, 0xFFF0): - interp = new_interpreter(bytecode + chr(2) + chr(i >> 8) + chr(i & 0xFF)) - context = interp.s_active_context() - pc = context.pc() + w_frame, s_frame = new_frame(bytecode + chr(2) + chr(i >> 8) + chr(i & 0xFF)) + pc = s_frame.pc() # create/find a method with an appropriate blockClosure - interp.step(context) - assert context.pc() == pc + 4 + i - closure = wrapper.BlockClosureWrapper(space, context.top()) + interp.step(s_frame) + assert s_frame.pc() == pc + 4 + i + closure = wrapper.BlockClosureWrapper(space, s_frame.top()) assert closure.startpc() == pc + 4 - assert closure.outerContext() is context._w_self + assert closure.outerContext() is s_frame._w_self def test_bc_pushClosureCopyCopied2ValuesBytecode(bytecode = pushClosureCopyCopiedValuesBytecode): - interp = new_interpreter(bytecode + chr(0x23) + chr(0) + chr(0)) - context = interp.s_active_context() - context.push("english") - context.push("bar") - pc = context.pc() - interp.step(context) - assert context.pc() == pc + 4 - closure = wrapper.BlockClosureWrapper(space, context.top()) + w_frame, s_frame = new_frame(bytecode + chr(0x23) + chr(0) + chr(0)) + s_frame.push("english") + s_frame.push("bar") + pc = s_frame.pc() + interp.step(s_frame) + assert s_frame.pc() == pc + 4 + closure = wrapper.BlockClosureWrapper(space, s_frame.top()) assert closure.startpc() == pc + 4 - assert closure.outerContext() is context._w_self + assert closure.outerContext() is s_frame._w_self assert closure.at0(0) == "english" assert closure.at0(1) == "bar" diff --git a/spyvm/test/test_miniimage.py b/spyvm/test/test_miniimage.py --- a/spyvm/test/test_miniimage.py +++ b/spyvm/test/test_miniimage.py @@ -211,12 +211,11 @@ py.test.skip("This method actually runs an image. Fails since no graphical primitives yet") from spyvm import wrapper ap = wrapper.ProcessWrapper(space, wrapper.scheduler(space).active_process()) - s_ctx = ap.suspended_context().as_methodcontext_get_shadow(space) + w_ctx = ap.suspended_context() ap.store_suspended_context(space.w_nil) interp = interpreter.Interpreter(space) - interp.store_w_active_context(s_ctx.w_self()) - interp.interpret() + interp.interpret_with_w_frame(w_ctx) def test_compile_method(): sourcecode = """fib From noreply at buildbot.pypy.org Sat Feb 23 13:31:42 2013 From: noreply at buildbot.pypy.org (RonnyPfannschmidt) Date: Sat, 23 Feb 2013 13:31:42 +0100 (CET) Subject: [pypy-commit] pypy refine-testrunner: factor out win32 interp path fixing Message-ID: <20130223123142.70E221C47A9@cobra.cs.uni-duesseldorf.de> Author: Ronny Pfannschmidt Branch: refine-testrunner Changeset: r61659:1ddcbccea251 Date: 2013-02-22 14:49 +0100 http://bitbucket.org/pypy/pypy/changeset/1ddcbccea251/ Log: factor out win32 interp path fixing diff --git a/testrunner/runner.py b/testrunner/runner.py --- a/testrunner/runner.py +++ b/testrunner/runner.py @@ -1,14 +1,21 @@ -import sys, os, thread, Queue +import sys +import os +import thread +import Queue import py import util - -import optparse - READ_MODE = 'rU' WRITE_MODE = 'wb' +def fix_interppath_in_win32(path, cwd, _win32): + if (_win32 and not os.path.isabs(path) and + ('\\' in path or '/' in path)): + path = os.path.join(str(cwd), path) + return path + + def execute_args(cwd, test, logfname, interp, test_driver, _win32=(sys.platform=='win32')): args = interp + test_driver @@ -19,12 +26,7 @@ args = map(str, args) - interp0 = args[0] - if (_win32 and not os.path.isabs(interp0) and - ('\\' in interp0 or '/' in interp0)): - args[0] = os.path.join(str(cwd), interp0) - - + args[0] = fix_interppath_in_win32(args[0], cwd, _win32) return args @@ -124,13 +126,13 @@ run_param.log("++ starting %s [%d started in total]", res[1], started) continue - + testname, somefailed, logdata, output = res[1:] done += 1 failure = failure or somefailed heading = "__ %s [%d done in total] " % (testname, done) - + run_param.log(heading.ljust(79, '_')) run_param.log(output.rstrip()) @@ -224,7 +226,6 @@ def main(opts, args, RunParamClass): - if opts.logfile is None: print "no logfile specified" sys.exit(2) @@ -255,10 +256,9 @@ else: run_param.collect_testdirs(testdirs) - if opts.dry_run: run_param.log("%s", run_param.__dict__) - + res = execute_tests(run_param, testdirs, logfile) if res: From noreply at buildbot.pypy.org Sat Feb 23 13:31:43 2013 From: noreply at buildbot.pypy.org (RonnyPfannschmidt) Date: Sat, 23 Feb 2013 13:31:43 +0100 (CET) Subject: [pypy-commit] pypy refine-testrunner: better pytest path finding for testrunner Message-ID: <20130223123143.908C11C47A9@cobra.cs.uni-duesseldorf.de> Author: Ronny Pfannschmidt Branch: refine-testrunner Changeset: r61660:e14a978b599b Date: 2013-02-22 16:48 +0100 http://bitbucket.org/pypy/pypy/changeset/e14a978b599b/ Log: better pytest path finding for testrunner diff --git a/testrunner/runner.py b/testrunner/runner.py --- a/testrunner/runner.py +++ b/testrunner/runner.py @@ -146,10 +146,8 @@ run = staticmethod(util.run) dry_run = staticmethod(util.dry_run) - pytestpath = os.path.abspath(os.path.join('py', 'bin', 'py.test')) - if not os.path.exists(pytestpath): - pytestpath = os.path.abspath(os.path.join('pytest.py')) - assert os.path.exists(pytestpath) + pytestpath = py.path.local(__file__).dirpath().dirpath().join('pytest.py') + assert pytestpath.check() test_driver = [pytestpath] cherrypick = None From noreply at buildbot.pypy.org Sat Feb 23 13:31:44 2013 From: noreply at buildbot.pypy.org (RonnyPfannschmidt) Date: Sat, 23 Feb 2013 13:31:44 +0100 (CET) Subject: [pypy-commit] pypy refine-testrunner: testrunner test cleanup Message-ID: <20130223123144.D4B201C47A9@cobra.cs.uni-duesseldorf.de> Author: Ronny Pfannschmidt Branch: refine-testrunner Changeset: r61661:424366f16a10 Date: 2013-02-22 18:00 +0100 http://bitbucket.org/pypy/pypy/changeset/424366f16a10/ Log: testrunner test cleanup diff --git a/testrunner/test/test_runner.py b/testrunner/test/test_runner.py --- a/testrunner/test/test_runner.py +++ b/testrunner/test/test_runner.py @@ -41,33 +41,40 @@ assert res == 0 def test_explicit_win32(self, fakerun): - args = runner.execute_args('/wd', 'test_one', 'LOGFILE', - interp=['./INTERP', 'IARG'], - test_driver=['driver', 'darg'], - _win32=True - ) + args = runner.execute_args( + '/wd', 'test_one', 'LOGFILE', + interp=['./INTERP', 'IARG'], + test_driver=['driver', 'darg'], + _win32=True + ) - expected = ['/wd' + os.sep + './INTERP', 'IARG', - 'driver', 'darg', - '-p', 'resultlog', - '--resultlog=LOGFILE', - '--junitxml=LOGFILE.junit', - 'test_one'] + expected = [ + '/wd' + os.sep + './INTERP', 'IARG', + 'driver', 'darg', + '-p', 'resultlog', + '--resultlog=LOGFILE', + '--junitxml=LOGFILE.junit', + 'test_one' + ] assert args == expected def test_error(self, fakerun): fakerun.exitcode = 1 - res = runner.execute_test('/wd', 'test_one', 'out', 'LOGFILE', - runfunc=fakerun, - interp=['INTERP', 'IARG'], - test_driver=['driver', 'darg']) + res = runner.execute_test( + '/wd', 'test_one', 'out', 'LOGFILE', + runfunc=fakerun, + interp=['INTERP', 'IARG'], + test_driver=['driver', 'darg'] + ) assert res == 1 fakerun.exitcode = -signal.SIGSEGV - res = runner.execute_test('/wd', 'test_one', 'out', 'LOGFILE', - runfunc=fakerun, - interp=['INTERP', 'IARG'], - test_driver=['driver', 'darg']) + res = runner.execute_test( + '/wd', 'test_one', 'out', 'LOGFILE', + runfunc=fakerun, + interp=['INTERP', 'IARG'], + test_driver=['driver', 'darg'] + ) assert res == -signal.SIGSEGV From noreply at buildbot.pypy.org Sat Feb 23 13:31:46 2013 From: noreply at buildbot.pypy.org (RonnyPfannschmidt) Date: Sat, 23 Feb 2013 13:31:46 +0100 (CET) Subject: [pypy-commit] pypy refine-testrunner: testrunner: simplify error detection Message-ID: <20130223123146.038C81C47A9@cobra.cs.uni-duesseldorf.de> Author: Ronny Pfannschmidt Branch: refine-testrunner Changeset: r61662:4c6c90e3c69c Date: 2013-02-22 18:07 +0100 http://bitbucket.org/pypy/pypy/changeset/4c6c90e3c69c/ Log: testrunner: simplify error detection diff --git a/testrunner/util.py b/testrunner/util.py --- a/testrunner/util.py +++ b/testrunner/util.py @@ -92,9 +92,7 @@ # contains "F", "E" or "P" then it's a regular failure, otherwise # we have to report it. for line in logdata.splitlines(): - if (line.startswith('F ') or - line.startswith('E ') or - line.startswith('P ')): + if line[:2] in ('F ', 'E ', 'P '): return False return True From noreply at buildbot.pypy.org Sat Feb 23 13:31:47 2013 From: noreply at buildbot.pypy.org (RonnyPfannschmidt) Date: Sat, 23 Feb 2013 13:31:47 +0100 (CET) Subject: [pypy-commit] pypy refine-testrunner: shuffle opening the log output around Message-ID: <20130223123147.3B1691C47A9@cobra.cs.uni-duesseldorf.de> Author: Ronny Pfannschmidt Branch: refine-testrunner Changeset: r61663:0417a7978d7d Date: 2013-02-23 13:28 +0100 http://bitbucket.org/pypy/pypy/changeset/0417a7978d7d/ Log: shuffle opening the log output around diff --git a/testrunner/runner.py b/testrunner/runner.py --- a/testrunner/runner.py +++ b/testrunner/runner.py @@ -33,7 +33,8 @@ def execute_test(cwd, test, out, logfname, interp, test_driver, runfunc, timeout=None): args = execute_args(cwd, test, logfname, interp, test_driver) - exitcode = runfunc(args, cwd, out, timeout=timeout) + with out.open('w') as fp: + exitcode = runfunc(args, cwd, fp, timeout=timeout) return exitcode diff --git a/testrunner/util.py b/testrunner/util.py --- a/testrunner/util.py +++ b/testrunner/util.py @@ -136,29 +136,27 @@ def run(args, cwd, out, timeout=None): - with out.open('w') as f: - try: - p = subprocess.Popen(args, cwd=str(cwd), stdout=f, stderr=f) - except Exception, e: - f.write("Failed to run %s with cwd='%s' timeout=%s:\n" - " %s\n" - % (args, cwd, timeout, e)) - return RUNFAILED + try: + p = subprocess.Popen(args, cwd=str(cwd), stdout=f, stderr=f) + except Exception, e: + f.write("Failed to run %s with cwd='%s' timeout=%s:\n" + " %s\n" + % (args, cwd, timeout, e)) + return RUNFAILED - if timeout is None: - return p.wait() - else: - returncode = busywait(p, timeout) - if returncode is not None: - return returncode - # timeout! - _kill(p.pid, SIGTERM) - if busywait(p, 10) is None: - _kill(p.pid, SIGKILL) - return TIMEDOUT + if timeout is None: + return p.wait() + else: + returncode = busywait(p, timeout) + if returncode is not None: + return returncode + # timeout! + _kill(p.pid, SIGTERM) + if busywait(p, 10) is None: + _kill(p.pid, SIGKILL) + return TIMEDOUT def dry_run(args, cwd, out, timeout=None): - with out.open('w') as f: - f.write("run %s with cwd='%s' timeout=%s\n" % (args, cwd, timeout)) + out.write("run %s with cwd='%s' timeout=%s\n" % (args, cwd, timeout)) return 0 From noreply at buildbot.pypy.org Sat Feb 23 13:33:49 2013 From: noreply at buildbot.pypy.org (fijal) Date: Sat, 23 Feb 2013 13:33:49 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: some paranoia Message-ID: <20130223123349.A1A091C47A9@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61664:7a646f691e22 Date: 2013-02-23 14:32 +0200 http://bitbucket.org/pypy/pypy/changeset/7a646f691e22/ Log: some paranoia diff --git a/rpython/jit/backend/llsupport/llmodel.py b/rpython/jit/backend/llsupport/llmodel.py --- a/rpython/jit/backend/llsupport/llmodel.py +++ b/rpython/jit/backend/llsupport/llmodel.py @@ -92,6 +92,7 @@ new_frame.jf_frame[i] = frame.jf_frame[i] i += 1 new_frame.jf_savedata = frame.jf_savedata + new_frame.jf_guard_exc = frame.jf_guard_exc # all other fields are empty llop.gc_assume_young_pointers(lltype.Void, new_frame) return lltype.cast_opaque_ptr(llmemory.GCREF, new_frame) diff --git a/rpython/rtyper/lltypesystem/rdict.py b/rpython/rtyper/lltypesystem/rdict.py --- a/rpython/rtyper/lltypesystem/rdict.py +++ b/rpython/rtyper/lltypesystem/rdict.py @@ -526,7 +526,6 @@ @jit.look_inside_iff(lambda d, i: jit.isvirtual(d) and jit.isconstant(i)) def _ll_dict_del(d, i): - assert i >= 0 d.entries.mark_deleted(i) d.num_items -= 1 # clear the key and the value if they are GC pointers From noreply at buildbot.pypy.org Sat Feb 23 13:41:29 2013 From: noreply at buildbot.pypy.org (fijal) Date: Sat, 23 Feb 2013 13:41:29 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: some more paranoia Message-ID: <20130223124129.057E01C0327@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61665:27751eafab1d Date: 2013-02-23 14:40 +0200 http://bitbucket.org/pypy/pypy/changeset/27751eafab1d/ Log: some more paranoia diff --git a/rpython/jit/backend/llsupport/llmodel.py b/rpython/jit/backend/llsupport/llmodel.py --- a/rpython/jit/backend/llsupport/llmodel.py +++ b/rpython/jit/backend/llsupport/llmodel.py @@ -79,23 +79,26 @@ base_ofs = self.get_baseofs_of_frame_field() def realloc_frame(frame, size): - if not we_are_translated(): - assert not self._exception_emulator[0] - frame = lltype.cast_opaque_ptr(jitframe.JITFRAMEPTR, frame) - if size > frame.jf_frame_info.jfi_frame_depth: - # update the frame_info size, which is for whatever reason - # not up to date - frame.jf_frame_info.set_frame_depth(base_ofs, size) - new_frame = jitframe.JITFRAME.allocate(frame.jf_frame_info) - i = 0 - while i < len(frame.jf_frame): - new_frame.jf_frame[i] = frame.jf_frame[i] - i += 1 - new_frame.jf_savedata = frame.jf_savedata - new_frame.jf_guard_exc = frame.jf_guard_exc - # all other fields are empty - llop.gc_assume_young_pointers(lltype.Void, new_frame) - return lltype.cast_opaque_ptr(llmemory.GCREF, new_frame) + try: + if not we_are_translated(): + assert not self._exception_emulator[0] + frame = lltype.cast_opaque_ptr(jitframe.JITFRAMEPTR, frame) + if size > frame.jf_frame_info.jfi_frame_depth: + # update the frame_info size, which is for whatever reason + # not up to date + frame.jf_frame_info.set_frame_depth(base_ofs, size) + new_frame = jitframe.JITFRAME.allocate(frame.jf_frame_info) + i = 0 + while i < len(frame.jf_frame): + new_frame.jf_frame[i] = frame.jf_frame[i] + i += 1 + new_frame.jf_savedata = frame.jf_savedata + new_frame.jf_guard_exc = frame.jf_guard_exc + # all other fields are empty + llop.gc_assume_young_pointers(lltype.Void, new_frame) + return lltype.cast_opaque_ptr(llmemory.GCREF, new_frame) + except Exception, e: + print "Unhandled exception", e, "in realloc_frame" if not translate_support_code: fptr = llhelper(FUNC_TP, realloc_frame) From noreply at buildbot.pypy.org Sat Feb 23 13:52:16 2013 From: noreply at buildbot.pypy.org (fijal) Date: Sat, 23 Feb 2013 13:52:16 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: merge default Message-ID: <20130223125216.6CAE11C0CA3@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61666:6a8d393151bc Date: 2013-02-23 14:51 +0200 http://bitbucket.org/pypy/pypy/changeset/6a8d393151bc/ Log: merge default diff too long, truncating to 2000 out of 17102 lines diff --git a/lib_pypy/numpypy/__init__.py b/lib_pypy/numpypy/__init__.py --- a/lib_pypy/numpypy/__init__.py +++ b/lib_pypy/numpypy/__init__.py @@ -1,5 +1,14 @@ -from _numpypy import * -from .core import * +import core +from core import * +import lib +from lib import * + +from __builtin__ import bool, int, long, float, complex, object, unicode, str +from core import abs, max, min + +__all__ = [] +__all__ += core.__all__ +__all__ += lib.__all__ import sys sys.modules.setdefault('numpy', sys.modules['numpypy']) diff --git a/lib_pypy/numpypy/core/__init__.py b/lib_pypy/numpypy/core/__init__.py --- a/lib_pypy/numpypy/core/__init__.py +++ b/lib_pypy/numpypy/core/__init__.py @@ -1,3 +1,18 @@ -from .fromnumeric import * -from .numeric import * -from .shape_base import * +import _numpypy +from _numpypy import * +import numeric +from numeric import * +import fromnumeric +from fromnumeric import * +import shape_base +from shape_base import * +import multiarray + +from fromnumeric import amax as max, amin as min +from _numpypy import absolute as abs + +__all__ = [] +__all__ += _numpypy.__all__ +__all__ += numeric.__all__ +__all__ += fromnumeric.__all__ +__all__ += shape_base.__all__ diff --git a/lib_pypy/numpypy/core/fromnumeric.py b/lib_pypy/numpypy/core/fromnumeric.py --- a/lib_pypy/numpypy/core/fromnumeric.py +++ b/lib_pypy/numpypy/core/fromnumeric.py @@ -1290,7 +1290,9 @@ array([3, 4, 2, 3, 4, 5, 6, 7, 8, 8]) """ - raise NotImplementedError('Waiting on interp level method') + if not hasattr(a, 'clip'): + a = numpypy.array(a) + return a.clip(a_min, a_max, out=out) def sum(a, axis=None, dtype=None, out=None): @@ -1360,10 +1362,9 @@ """ assert dtype is None - assert out is None if not hasattr(a, "sum"): a = numpypy.array(a) - return a.sum(axis=axis) + return a.sum(axis=axis, out=out) def product (a, axis=None, dtype=None, out=None): @@ -1720,11 +1721,11 @@ 4.0 """ - assert axis is None - assert out is None if not hasattr(a, "max"): a = numpypy.array(a) - return a.max() + if a.size < 1: + return numpypy.array([]) + return a.max(axis=axis, out=out) def amin(a, axis=None, out=None): @@ -1782,12 +1783,11 @@ 0.0 """ - # amin() is equivalent to min() - assert axis is None - assert out is None if not hasattr(a, 'min'): a = numpypy.array(a) - return a.min() + if a.size < 1: + return numpypy.array([]) + return a.min(axis=axis, out=out) def alen(a): """ diff --git a/lib_pypy/numpypy/core/multiarray.py b/lib_pypy/numpypy/core/multiarray.py new file mode 100644 --- /dev/null +++ b/lib_pypy/numpypy/core/multiarray.py @@ -0,0 +1,1 @@ +from _numpypy import set_string_function, typeinfo diff --git a/lib_pypy/numpypy/core/numeric.py b/lib_pypy/numpypy/core/numeric.py --- a/lib_pypy/numpypy/core/numeric.py +++ b/lib_pypy/numpypy/core/numeric.py @@ -1,10 +1,13 @@ +__all__ = ['asanyarray', 'base_repr', + 'array_repr', 'array_str', 'set_string_function', + 'array_equal', 'asarray', 'outer', 'identity'] from _numpypy import array, ndarray, int_, float_, bool_, flexible #, complex_# , longlong from _numpypy import concatenate from .fromnumeric import any import math import sys -import _numpypy as multiarray # ARGH +import multiarray from numpypy.core.arrayprint import array2string newaxis = None @@ -501,3 +504,34 @@ a = asarray(a) b = asarray(b) return a.ravel()[:,newaxis]*b.ravel()[newaxis,:] + +def identity(n, dtype=None): + """ + Return the identity array. + + The identity array is a square array with ones on + the main diagonal. + + Parameters + ---------- + n : int + Number of rows (and columns) in `n` x `n` output. + dtype : data-type, optional + Data-type of the output. Defaults to ``float``. + + Returns + ------- + out : ndarray + `n` x `n` array with its main diagonal set to one, + and all other elements 0. + + Examples + -------- + >>> np.identity(3) + array([[ 1., 0., 0.], + [ 0., 1., 0.], + [ 0., 0., 1.]]) + + """ + from numpy import eye + return eye(n, dtype=dtype) diff --git a/lib_pypy/numpypy/core/shape_base.py b/lib_pypy/numpypy/core/shape_base.py --- a/lib_pypy/numpypy/core/shape_base.py +++ b/lib_pypy/numpypy/core/shape_base.py @@ -1,3 +1,5 @@ +__all__ = ['atleast_1d', 'atleast_2d', 'atleast_3d', 'vstack', 'hstack'] + import _numpypy from numeric import array, asanyarray, newaxis @@ -271,53 +273,3 @@ return _numpypy.concatenate(arrs, 0) else: return _numpypy.concatenate(arrs, 1) - -def dstack(tup): - """ - Stack arrays in sequence depth wise (along third axis). - - Takes a sequence of arrays and stack them along the third axis - to make a single array. Rebuilds arrays divided by `dsplit`. - This is a simple way to stack 2D arrays (images) into a single - 3D array for processing. - - Parameters - ---------- - tup : sequence of arrays - Arrays to stack. All of them must have the same shape along all - but the third axis. - - Returns - ------- - stacked : ndarray - The array formed by stacking the given arrays. - - See Also - -------- - vstack : Stack along first axis. - hstack : Stack along second axis. - concatenate : Join arrays. - dsplit : Split array along third axis. - - Notes - ----- - Equivalent to ``np.concatenate(tup, axis=2)``. - - Examples - -------- - >>> a = np.array((1,2,3)) - >>> b = np.array((2,3,4)) - >>> np.dstack((a,b)) - array([[[1, 2], - [2, 3], - [3, 4]]]) - - >>> a = np.array([[1],[2],[3]]) - >>> b = np.array([[2],[3],[4]]) - >>> np.dstack((a,b)) - array([[[1, 2]], - [[2, 3]], - [[3, 4]]]) - - """ - return _numpypy.concatenate(map(atleast_3d,tup),2) diff --git a/lib_pypy/numpypy/lib/__init__.py b/lib_pypy/numpypy/lib/__init__.py new file mode 100644 --- /dev/null +++ b/lib_pypy/numpypy/lib/__init__.py @@ -0,0 +1,11 @@ +import function_base +from function_base import * +import shape_base +from shape_base import * +import twodim_base +from twodim_base import * + +__all__ = [] +__all__ += function_base.__all__ +__all__ += shape_base.__all__ +__all__ += twodim_base.__all__ diff --git a/lib_pypy/numpypy/lib/function_base.py b/lib_pypy/numpypy/lib/function_base.py new file mode 100644 --- /dev/null +++ b/lib_pypy/numpypy/lib/function_base.py @@ -0,0 +1,10 @@ +__all__ = ['average'] + +from _numpypy import array + +def average(a): + # This implements a weighted average, for now we don't implement the + # weighting, just the average part! + if not hasattr(a, "mean"): + a = array(a) + return a.mean() diff --git a/lib_pypy/numpypy/lib/shape_base.py b/lib_pypy/numpypy/lib/shape_base.py new file mode 100644 --- /dev/null +++ b/lib_pypy/numpypy/lib/shape_base.py @@ -0,0 +1,54 @@ +__all__ = ['dstack'] + +import numpypy.core.numeric as _nx +from numpypy.core import atleast_3d + +def dstack(tup): + """ + Stack arrays in sequence depth wise (along third axis). + + Takes a sequence of arrays and stack them along the third axis + to make a single array. Rebuilds arrays divided by `dsplit`. + This is a simple way to stack 2D arrays (images) into a single + 3D array for processing. + + Parameters + ---------- + tup : sequence of arrays + Arrays to stack. All of them must have the same shape along all + but the third axis. + + Returns + ------- + stacked : ndarray + The array formed by stacking the given arrays. + + See Also + -------- + vstack : Stack along first axis. + hstack : Stack along second axis. + concatenate : Join arrays. + dsplit : Split array along third axis. + + Notes + ----- + Equivalent to ``np.concatenate(tup, axis=2)``. + + Examples + -------- + >>> a = np.array((1,2,3)) + >>> b = np.array((2,3,4)) + >>> np.dstack((a,b)) + array([[[1, 2], + [2, 3], + [3, 4]]]) + + >>> a = np.array([[1],[2],[3]]) + >>> b = np.array([[2],[3],[4]]) + >>> np.dstack((a,b)) + array([[[1, 2]], + [[2, 3]], + [[3, 4]]]) + + """ + return _nx.concatenate(map(atleast_3d,tup),2) diff --git a/lib_pypy/numpypy/lib/twodim_base.py b/lib_pypy/numpypy/lib/twodim_base.py new file mode 100644 --- /dev/null +++ b/lib_pypy/numpypy/lib/twodim_base.py @@ -0,0 +1,54 @@ +__all__ = ['eye'] + +from _numpypy import zeros + +def eye(N, M=None, k=0, dtype=float): + """ + Return a 2-D array with ones on the diagonal and zeros elsewhere. + + Parameters + ---------- + N : int + Number of rows in the output. + M : int, optional + Number of columns in the output. If None, defaults to `N`. + k : int, optional + Index of the diagonal: 0 (the default) refers to the main diagonal, + a positive value refers to an upper diagonal, and a negative value + to a lower diagonal. + dtype : data-type, optional + Data-type of the returned array. + + Returns + ------- + I : ndarray of shape (N,M) + An array where all elements are equal to zero, except for the `k`-th + diagonal, whose values are equal to one. + + See Also + -------- + identity : (almost) equivalent function + diag : diagonal 2-D array from a 1-D array specified by the user. + + Examples + -------- + >>> np.eye(2, dtype=int) + array([[1, 0], + [0, 1]]) + >>> np.eye(3, k=1) + array([[ 0., 1., 0.], + [ 0., 0., 1.], + [ 0., 0., 0.]]) + + """ + if M is None: + M = N + m = zeros((N, M), dtype=dtype) + if k >= M: + return m + if k >= 0: + i = k + else: + i = (-k) * M + m[:M-k].flat[i::M+1] = 1 + return m diff --git a/pypy/doc/garbage_collection.rst b/pypy/doc/garbage_collection.rst --- a/pypy/doc/garbage_collection.rst +++ b/pypy/doc/garbage_collection.rst @@ -42,7 +42,7 @@ Two arenas of equal size, with only one arena in use and getting filled with new objects. When the arena is full, the live objects are copied into the other arena using Cheney's algorithm. The old arena is then -cleared. See `rpython/rtyper/memory/gc/semispace.py`_. +cleared. See `rpython/memory/gc/semispace.py`_. On Unix the clearing is done by reading ``/dev/zero`` into the arena, which is extremely memory efficient at least on Linux: it lets the @@ -55,7 +55,7 @@ Generational GC --------------- -This is a two-generations GC. See `rpython/rtyper/memory/gc/generation.py`_. +This is a two-generations GC. See `rpython/memory/gc/generation.py`_. It is implemented as a subclass of the Semispace copying collector. It adds a nursery, which is a chunk of the current semispace. Its size is @@ -86,7 +86,7 @@ Each generation is collected much less often than the previous one. The division of the generations is slightly more complicated than just nursery / semispace / external; see the diagram at the start of the -source code, in `rpython/rtyper/memory/gc/hybrid.py`_. +source code, in `rpython/memory/gc/hybrid.py`_. Mark & Compact GC ----------------- @@ -161,7 +161,7 @@ to the old stage. The dying case 2 objects are immediately freed. - The old stage is an area of memory containing old (small) objects. It - is handled by `rpython/rtyper/memory/gc/minimarkpage.py`_. It is organized + is handled by `rpython/memory/gc/minimarkpage.py`_. It is organized as "arenas" of 256KB or 512KB, subdivided into "pages" of 4KB or 8KB. Each page can either be free, or contain small objects of all the same size. Furthermore at any point in time each object location can be diff --git a/pypy/doc/index.rst b/pypy/doc/index.rst --- a/pypy/doc/index.rst +++ b/pypy/doc/index.rst @@ -286,7 +286,7 @@ `rpython/rtyper/ootypesystem/`_ the `object-oriented type system`_ for OO backends -`rpython/rtyper/memory/`_ the `garbage collector`_ construction +`rpython/memory/`_ the `garbage collector`_ construction framework `rpython/translator/`_ translation_ backends and support code diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst --- a/pypy/doc/whatsnew-head.rst +++ b/pypy/doc/whatsnew-head.rst @@ -68,3 +68,7 @@ .. branch: coding-guide-update-rlib-refs .. branch: rlib-doc-rpython-refs +.. branch: clean-up-remaining-pypy-rlib-refs + +.. branch: enumerate-rstr +Support enumerate() over rstr types. diff --git a/pypy/module/_cffi_backend/cbuffer.py b/pypy/module/_cffi_backend/cbuffer.py --- a/pypy/module/_cffi_backend/cbuffer.py +++ b/pypy/module/_cffi_backend/cbuffer.py @@ -1,10 +1,11 @@ -from pypy.interpreter.error import operationerrfmt from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.buffer import RWBuffer +from pypy.interpreter.error import operationerrfmt from pypy.interpreter.gateway import unwrap_spec, interp2app from pypy.interpreter.typedef import TypeDef, make_weakref_descr +from pypy.module._cffi_backend import cdataobj, ctypeptr, ctypearray + from rpython.rtyper.lltypesystem import rffi -from pypy.module._cffi_backend import cdataobj, ctypeptr, ctypearray class LLBuffer(RWBuffer): diff --git a/pypy/module/_cffi_backend/ccallback.py b/pypy/module/_cffi_backend/ccallback.py --- a/pypy/module/_cffi_backend/ccallback.py +++ b/pypy/module/_cffi_backend/ccallback.py @@ -2,18 +2,17 @@ Callbacks. """ import os + +from rpython.rlib import clibffi, rweakref, jit +from rpython.rlib.objectmodel import compute_unique_id, keepalive_until_here +from rpython.rtyper.lltypesystem import lltype, rffi + from pypy.interpreter.error import OperationError, operationerrfmt -from rpython.rtyper.lltypesystem import lltype, llmemory, rffi -from rpython.rlib.objectmodel import compute_unique_id, keepalive_until_here -from rpython.rlib import clibffi, rweakref -from rpython.rlib import jit - +from pypy.module._cffi_backend import cerrno, misc from pypy.module._cffi_backend.cdataobj import W_CData -from pypy.module._cffi_backend.ctypefunc import SIZE_OF_FFI_ARG, BIG_ENDIAN -from pypy.module._cffi_backend.ctypefunc import W_CTypeFunc +from pypy.module._cffi_backend.ctypefunc import SIZE_OF_FFI_ARG, BIG_ENDIAN, W_CTypeFunc from pypy.module._cffi_backend.ctypeprim import W_CTypePrimitiveSigned from pypy.module._cffi_backend.ctypevoid import W_CTypeVoid -from pypy.module._cffi_backend import cerrno, misc # ____________________________________________________________ @@ -152,6 +151,7 @@ STDERR = 2 + @jit.jit_callback("CFFI") def invoke_callback(ffi_cif, ll_res, ll_args, ll_userdata): """ Callback specification. diff --git a/pypy/module/_cffi_backend/cdataobj.py b/pypy/module/_cffi_backend/cdataobj.py --- a/pypy/module/_cffi_backend/cdataobj.py +++ b/pypy/module/_cffi_backend/cdataobj.py @@ -1,11 +1,13 @@ import operator + +from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.error import OperationError, operationerrfmt -from pypy.interpreter.baseobjspace import Wrappable -from pypy.interpreter.gateway import interp2app, unwrap_spec +from pypy.interpreter.gateway import interp2app from pypy.interpreter.typedef import TypeDef, make_weakref_descr + +from rpython.rlib import objectmodel, rgc +from rpython.rlib.objectmodel import keepalive_until_here, specialize from rpython.rtyper.lltypesystem import lltype, rffi -from rpython.rlib.objectmodel import keepalive_until_here, specialize -from rpython.rlib import objectmodel, rgc from rpython.tool.sourcetools import func_with_new_name from pypy.module._cffi_backend import misc diff --git a/pypy/module/_cffi_backend/cerrno.py b/pypy/module/_cffi_backend/cerrno.py --- a/pypy/module/_cffi_backend/cerrno.py +++ b/pypy/module/_cffi_backend/cerrno.py @@ -1,5 +1,7 @@ import sys + from rpython.rlib import rposix + from pypy.interpreter.executioncontext import ExecutionContext from pypy.interpreter.gateway import unwrap_spec diff --git a/pypy/module/_cffi_backend/ctypearray.py b/pypy/module/_cffi_backend/ctypearray.py --- a/pypy/module/_cffi_backend/ctypearray.py +++ b/pypy/module/_cffi_backend/ctypearray.py @@ -2,18 +2,17 @@ Arrays. """ +from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.error import OperationError, operationerrfmt -from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.gateway import interp2app from pypy.interpreter.typedef import TypeDef + from rpython.rtyper.lltypesystem import rffi from rpython.rlib.objectmodel import keepalive_until_here from rpython.rlib.rarithmetic import ovfcheck -from pypy.module._cffi_backend.ctypeprim import W_CTypePrimitiveChar -from pypy.module._cffi_backend.ctypeprim import W_CTypePrimitiveUniChar +from pypy.module._cffi_backend import cdataobj from pypy.module._cffi_backend.ctypeptr import W_CTypePtrOrArray -from pypy.module._cffi_backend import cdataobj class W_CTypeArray(W_CTypePtrOrArray): diff --git a/pypy/module/_cffi_backend/ctypeenum.py b/pypy/module/_cffi_backend/ctypeenum.py --- a/pypy/module/_cffi_backend/ctypeenum.py +++ b/pypy/module/_cffi_backend/ctypeenum.py @@ -2,15 +2,11 @@ Enums. """ -from pypy.interpreter.error import OperationError, operationerrfmt -from rpython.rtyper.lltypesystem import rffi -from rpython.rlib.rarithmetic import intmask, r_ulonglong from rpython.rlib.objectmodel import keepalive_until_here -from rpython.rlib.objectmodel import specialize -from pypy.module._cffi_backend.ctypeprim import W_CTypePrimitiveSigned -from pypy.module._cffi_backend.ctypeprim import W_CTypePrimitiveUnsigned from pypy.module._cffi_backend import misc +from pypy.module._cffi_backend.ctypeprim import (W_CTypePrimitiveSigned, + W_CTypePrimitiveUnsigned) class _Mixin_Enum(object): diff --git a/pypy/module/_cffi_backend/ctypefunc.py b/pypy/module/_cffi_backend/ctypefunc.py --- a/pypy/module/_cffi_backend/ctypefunc.py +++ b/pypy/module/_cffi_backend/ctypefunc.py @@ -4,25 +4,21 @@ import sys from pypy.interpreter.error import OperationError, operationerrfmt + +from rpython.rlib import jit, clibffi, jit_libffi +from rpython.rlib.jit_libffi import (CIF_DESCRIPTION, CIF_DESCRIPTION_P, + FFI_TYPE, FFI_TYPE_P, FFI_TYPE_PP, SIZE_OF_FFI_ARG) +from rpython.rlib.objectmodel import we_are_translated, instantiate from rpython.rtyper.lltypesystem import lltype, llmemory, rffi -from rpython.rlib import jit, clibffi, jit_libffi -from rpython.rlib.jit_libffi import CIF_DESCRIPTION, CIF_DESCRIPTION_P -from rpython.rlib.jit_libffi import FFI_TYPE, FFI_TYPE_P, FFI_TYPE_PP -from rpython.rlib.jit_libffi import SIZE_OF_FFI_ARG -from rpython.rlib.objectmodel import we_are_translated, instantiate -from rpython.rlib.objectmodel import keepalive_until_here +from pypy.module._cffi_backend import ctypearray, cdataobj, cerrno from pypy.module._cffi_backend.ctypeobj import W_CType from pypy.module._cffi_backend.ctypeptr import W_CTypePtrBase, W_CTypePointer from pypy.module._cffi_backend.ctypevoid import W_CTypeVoid from pypy.module._cffi_backend.ctypestruct import W_CTypeStruct -from pypy.module._cffi_backend.ctypestruct import W_CTypeStructOrUnion -from pypy.module._cffi_backend.ctypeprim import W_CTypePrimitiveSigned -from pypy.module._cffi_backend.ctypeprim import W_CTypePrimitiveUnsigned -from pypy.module._cffi_backend.ctypeprim import W_CTypePrimitiveCharOrUniChar -from pypy.module._cffi_backend.ctypeprim import W_CTypePrimitiveFloat -from pypy.module._cffi_backend.ctypeprim import W_CTypePrimitiveLongDouble -from pypy.module._cffi_backend import ctypearray, cdataobj, cerrno +from pypy.module._cffi_backend.ctypeprim import (W_CTypePrimitiveSigned, + W_CTypePrimitiveUnsigned, W_CTypePrimitiveCharOrUniChar, + W_CTypePrimitiveFloat, W_CTypePrimitiveLongDouble) class W_CTypeFunc(W_CTypePtrBase): @@ -97,7 +93,6 @@ return self.space.wrap(clibffi.FFI_DEFAULT_ABI) # XXX return W_CTypePtrBase._fget(self, attrchar) - def call(self, funcaddr, args_w): if self.cif_descr: # regular case: this function does not take '...' arguments @@ -270,7 +265,6 @@ self.bufferp = rffi.ptradd(result, size) return result - def fb_fill_type(self, ctype, is_result_type): return ctype._get_ffi_type(self, is_result_type) @@ -357,7 +351,6 @@ return ffistruct - def fb_build(self): # Build a CIF_DESCRIPTION. Actually this computes the size and # allocates a larger amount of data. It starts with a @@ -387,7 +380,6 @@ if self.atypes: self.atypes[i] = atype - def align_arg(self, n): return (n + 7) & ~7 diff --git a/pypy/module/_cffi_backend/ctypeobj.py b/pypy/module/_cffi_backend/ctypeobj.py --- a/pypy/module/_cffi_backend/ctypeobj.py +++ b/pypy/module/_cffi_backend/ctypeobj.py @@ -1,9 +1,8 @@ +from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.error import OperationError, operationerrfmt -from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.gateway import interp2app -from pypy.interpreter.typedef import TypeDef -from pypy.interpreter.typedef import make_weakref_descr -from pypy.interpreter.typedef import GetSetProperty, interp_attrproperty +from pypy.interpreter.typedef import TypeDef, make_weakref_descr, GetSetProperty + from rpython.rtyper.lltypesystem import lltype, llmemory, rffi from rpython.rlib.objectmodel import we_are_translated diff --git a/pypy/module/_cffi_backend/ctypeprim.py b/pypy/module/_cffi_backend/ctypeprim.py --- a/pypy/module/_cffi_backend/ctypeprim.py +++ b/pypy/module/_cffi_backend/ctypeprim.py @@ -3,13 +3,14 @@ """ from pypy.interpreter.error import operationerrfmt -from rpython.rtyper.lltypesystem import lltype, rffi + from rpython.rlib.rarithmetic import r_uint, r_ulonglong, intmask from rpython.rlib.objectmodel import keepalive_until_here from rpython.rlib import jit +from rpython.rtyper.lltypesystem import lltype, rffi +from pypy.module._cffi_backend import cdataobj, misc from pypy.module._cffi_backend.ctypeobj import W_CType -from pypy.module._cffi_backend import cdataobj, misc class W_CTypePrimitive(W_CType): diff --git a/pypy/module/_cffi_backend/ctypeptr.py b/pypy/module/_cffi_backend/ctypeptr.py --- a/pypy/module/_cffi_backend/ctypeptr.py +++ b/pypy/module/_cffi_backend/ctypeptr.py @@ -2,15 +2,15 @@ Pointers. """ -from pypy.interpreter.error import OperationError, operationerrfmt -from pypy.interpreter.error import wrap_oserror -from rpython.rtyper.lltypesystem import lltype, rffi +from pypy.interpreter.error import OperationError, operationerrfmt, wrap_oserror + +from rpython.rlib import rposix from rpython.rlib.objectmodel import keepalive_until_here from rpython.rlib.rarithmetic import ovfcheck -from rpython.rlib import rposix +from rpython.rtyper.lltypesystem import lltype, rffi +from pypy.module._cffi_backend import cdataobj, misc, ctypeprim, ctypevoid from pypy.module._cffi_backend.ctypeobj import W_CType -from pypy.module._cffi_backend import cdataobj, misc, ctypeprim, ctypevoid class W_CTypePtrOrArray(W_CType): @@ -336,19 +336,22 @@ rffi_fdopen = rffi.llexternal("fdopen", [rffi.INT, rffi.CCHARP], rffi.CCHARP) -rffi_setbuf = rffi.llexternal("setbuf", [rffi.CCHARP,rffi.CCHARP], lltype.Void) +rffi_setbuf = rffi.llexternal("setbuf", [rffi.CCHARP, rffi.CCHARP], lltype.Void) rffi_fclose = rffi.llexternal("fclose", [rffi.CCHARP], rffi.INT) class CffiFileObj(object): _immutable_ = True + def __init__(self, fd, mode): self.llf = rffi_fdopen(fd, mode) if not self.llf: raise OSError(rposix.get_errno(), "fdopen failed") rffi_setbuf(self.llf, lltype.nullptr(rffi.CCHARP.TO)) + def close(self): rffi_fclose(self.llf) + def prepare_file_argument(space, fileobj): fileobj.direct_flush() if fileobj.cffi_fileobj is None: diff --git a/pypy/module/_cffi_backend/ctypestruct.py b/pypy/module/_cffi_backend/ctypestruct.py --- a/pypy/module/_cffi_backend/ctypestruct.py +++ b/pypy/module/_cffi_backend/ctypestruct.py @@ -3,15 +3,16 @@ """ from pypy.interpreter.error import OperationError, operationerrfmt -from rpython.rtyper.lltypesystem import lltype, rffi from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.typedef import TypeDef, interp_attrproperty + +from rpython.rlib import jit from rpython.rlib.objectmodel import keepalive_until_here from rpython.rlib.rarithmetic import r_uint, r_ulonglong, r_longlong, intmask -from rpython.rlib import jit +from rpython.rtyper.lltypesystem import rffi +from pypy.module._cffi_backend import cdataobj, ctypeprim, misc from pypy.module._cffi_backend.ctypeobj import W_CType -from pypy.module._cffi_backend import cdataobj, ctypeprim, misc class W_CTypeStructOrUnion(W_CType): @@ -141,6 +142,7 @@ class W_CTypeStruct(W_CTypeStructOrUnion): kind = "struct" + class W_CTypeUnion(W_CTypeStructOrUnion): kind = "union" @@ -241,8 +243,8 @@ # value = misc.as_long_long(space, w_ob) if isinstance(ctype, ctypeprim.W_CTypePrimitiveSigned): - fmin = -(r_longlong(1) << (self.bitsize-1)) - fmax = (r_longlong(1) << (self.bitsize-1)) - 1 + fmin = -(r_longlong(1) << (self.bitsize - 1)) + fmax = (r_longlong(1) << (self.bitsize - 1)) - 1 if fmax == 0: fmax = 1 # special case to let "int x:1" receive "1" else: diff --git a/pypy/module/_cffi_backend/libraryobj.py b/pypy/module/_cffi_backend/libraryobj.py --- a/pypy/module/_cffi_backend/libraryobj.py +++ b/pypy/module/_cffi_backend/libraryobj.py @@ -1,9 +1,11 @@ from __future__ import with_statement -from pypy.interpreter.error import OperationError, operationerrfmt + from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.error import operationerrfmt from pypy.interpreter.gateway import interp2app, unwrap_spec from pypy.interpreter.typedef import TypeDef -from rpython.rtyper.lltypesystem import lltype, rffi + +from rpython.rtyper.lltypesystem import rffi from rpython.rlib.rdynload import DLLHANDLE, dlopen, dlsym, dlclose, DLOpenError from pypy.module._cffi_backend.cdataobj import W_CData diff --git a/pypy/module/_cffi_backend/misc.py b/pypy/module/_cffi_backend/misc.py --- a/pypy/module/_cffi_backend/misc.py +++ b/pypy/module/_cffi_backend/misc.py @@ -1,10 +1,12 @@ from __future__ import with_statement -from pypy.interpreter.error import OperationError, operationerrfmt -from rpython.rtyper.lltypesystem import lltype, llmemory, rffi + +from pypy.interpreter.error import OperationError + +from rpython.rlib import jit +from rpython.rlib.objectmodel import keepalive_until_here, specialize from rpython.rlib.rarithmetic import r_uint, r_ulonglong, is_signed_integer_type from rpython.rlib.unroll import unrolling_iterable -from rpython.rlib.objectmodel import keepalive_until_here, specialize -from rpython.rlib import jit +from rpython.rtyper.lltypesystem import lltype, llmemory, rffi from rpython.translator.tool.cbuild import ExternalCompilationInfo # ____________________________________________________________ @@ -43,14 +45,14 @@ def read_raw_unsigned_data(target, size): for TP, TPP in _prim_unsigned_types: if size == rffi.sizeof(TP): - return rffi.cast(lltype.UnsignedLongLong, rffi.cast(TPP,target)[0]) + return rffi.cast(lltype.UnsignedLongLong, rffi.cast(TPP, target)[0]) raise NotImplementedError("bad integer size") def read_raw_ulong_data(target, size): for TP, TPP in _prim_unsigned_types: if size == rffi.sizeof(TP): assert rffi.sizeof(TP) <= rffi.sizeof(lltype.Unsigned) - return rffi.cast(lltype.Unsigned, rffi.cast(TPP,target)[0]) + return rffi.cast(lltype.Unsigned, rffi.cast(TPP, target)[0]) raise NotImplementedError("bad integer size") def read_raw_float_data(target, size): diff --git a/pypy/module/_cffi_backend/newtype.py b/pypy/module/_cffi_backend/newtype.py --- a/pypy/module/_cffi_backend/newtype.py +++ b/pypy/module/_cffi_backend/newtype.py @@ -1,12 +1,12 @@ from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.gateway import unwrap_spec + +from rpython.rlib.objectmodel import specialize +from rpython.rlib.rarithmetic import ovfcheck from rpython.rtyper.lltypesystem import lltype, rffi -from rpython.rlib.rarithmetic import ovfcheck, r_uint, intmask -from rpython.rlib.rarithmetic import most_neg_value_of, most_pos_value_of -from rpython.rlib.objectmodel import specialize -from pypy.module._cffi_backend import ctypeobj, ctypeprim, ctypeptr, ctypearray -from pypy.module._cffi_backend import ctypestruct, ctypevoid, ctypeenum +from pypy.module._cffi_backend import (ctypeobj, ctypeprim, ctypeptr, + ctypearray, ctypestruct, ctypevoid, ctypeenum) @specialize.memo() @@ -167,7 +167,7 @@ # if foffset < 0: # align this field to its own 'falign' by inserting padding - offset = (offset + falign - 1) & ~(falign-1) + offset = (offset + falign - 1) & ~(falign - 1) else: # a forced field position: ignore the offset just computed, # except to know if we must set 'custom_field_pos' @@ -178,7 +178,7 @@ fbitsize == 8 * ftype.size and not isinstance(ftype, ctypeprim.W_CTypePrimitiveCharOrUniChar)): fbitsize = -1 - if isinstance(ftype, ctypearray.W_CTypeArray) and ftype.length==0: + if isinstance(ftype, ctypearray.W_CTypeArray) and ftype.length == 0: bitshift = ctypestruct.W_CField.BS_EMPTY_ARRAY else: bitshift = ctypestruct.W_CField.BS_REGULAR @@ -241,7 +241,7 @@ # as 1 instead. But for ctypes support, we allow the manually- # specified totalsize to be zero in this case. if totalsize < 0: - offset = (offset + alignment - 1) & ~(alignment-1) + offset = (offset + alignment - 1) & ~(alignment - 1) totalsize = offset or 1 elif totalsize < offset: raise operationerrfmt(space.w_TypeError, diff --git a/pypy/module/_io/interp_bufferedio.py b/pypy/module/_io/interp_bufferedio.py --- a/pypy/module/_io/interp_bufferedio.py +++ b/pypy/module/_io/interp_bufferedio.py @@ -631,6 +631,72 @@ return res return None + def readline_w(self, space, w_limit=None): + self._check_init(space) + self._check_closed(space, "readline of closed file") + + limit = convert_size(space, w_limit) + + # First, try to find a line in the buffer. This can run + # unlocked because the calls to the C API are simple enough + # that they can't trigger any thread switch. + have = self._readahead() + if limit >= 0 and have > limit: + have = limit + for pos in range(self.pos, self.pos+have): + if self.buffer[pos] == '\n': + break + else: + pos = -1 + if pos >= 0: + w_res = space.wrap(''.join(self.buffer[self.pos:pos+1])) + self.pos = pos + 1 + return w_res + if have == limit: + w_res = space.wrap(''.join(self.buffer[self.pos:self.pos+have])) + self.pos += have + return w_res + + written = 0 + with self.lock: + # Now we try to get some more from the raw stream + chunks = [] + if have > 0: + chunks.extend(self.buffer[self.pos:self.pos+have]) + written += have + self.pos += have + if limit >= 0: + limit -= have + if self.writable: + self._flush_and_rewind_unlocked(space) + + while True: + self._reader_reset_buf() + have = self._fill_buffer(space) + if have == 0: + break + if limit >= 0 and have > limit: + have = limit + pos = 0 + found = False + while pos < have: + c = self.buffer[pos] + pos += 1 + if c == '\n': + self.pos = pos + found = True + break + chunks.extend(self.buffer[0:pos]) + if found: + break + if have == limit: + self.pos = have + break + written += have + if limit >= 0: + limit -= have + return space.wrap(''.join(chunks)) + # ____________________________________________________ # Write methods @@ -795,6 +861,7 @@ peek = interp2app(W_BufferedReader.peek_w), read1 = interp2app(W_BufferedReader.read1_w), raw = interp_attrproperty_w("w_raw", cls=W_BufferedReader), + readline = interp2app(W_BufferedReader.readline_w), # from the mixin class __repr__ = interp2app(W_BufferedReader.repr_w), @@ -968,6 +1035,7 @@ read = interp2app(W_BufferedRandom.read_w), peek = interp2app(W_BufferedRandom.peek_w), read1 = interp2app(W_BufferedRandom.read1_w), + readline = interp2app(W_BufferedRandom.readline_w), write = interp2app(W_BufferedRandom.write_w), flush = interp2app(W_BufferedRandom.flush_w), diff --git a/pypy/module/_io/interp_fileio.py b/pypy/module/_io/interp_fileio.py --- a/pypy/module/_io/interp_fileio.py +++ b/pypy/module/_io/interp_fileio.py @@ -3,7 +3,6 @@ from pypy.interpreter.error import OperationError, wrap_oserror, wrap_oserror2 from rpython.rlib.rarithmetic import r_longlong from rpython.rlib.rstring import StringBuilder -from rpython.rlib.rposix import validate_fd from os import O_RDONLY, O_WRONLY, O_RDWR, O_CREAT, O_TRUNC import sys, os, stat, errno from pypy.module._io.interp_iobase import W_RawIOBase, convert_size @@ -154,7 +153,6 @@ fd_is_own = False try: if fd >= 0: - validate_fd(fd) try: os.fstat(fd) except OSError, e: @@ -235,7 +233,6 @@ self.fd = -1 try: - validate_fd(fd) os.close(fd) except OSError, e: raise wrap_oserror(space, e, diff --git a/pypy/module/_io/test/test_bufferedio.py b/pypy/module/_io/test/test_bufferedio.py --- a/pypy/module/_io/test/test_bufferedio.py +++ b/pypy/module/_io/test/test_bufferedio.py @@ -631,6 +631,19 @@ f.flush() assert raw.getvalue() == b'1b\n2def\n3\n' + def test_readline(self): + import _io as io + with io.BytesIO(b"abc\ndef\nxyzzy\nfoo\x00bar\nanother line") as raw: + with io.BufferedRandom(raw, buffer_size=10) as f: + assert f.readline() == b"abc\n" + assert f.readline(10) == b"def\n" + assert f.readline(2) == b"xy" + assert f.readline(4) == b"zzy\n" + assert f.readline() == b"foo\x00bar\n" + assert f.readline(None) == b"another line" + raises(TypeError, f.readline, 5.3) + + class TestNonReentrantLock: spaceconfig = dict(usemodules=['thread']) diff --git a/pypy/module/micronumpy/__init__.py b/pypy/module/micronumpy/__init__.py --- a/pypy/module/micronumpy/__init__.py +++ b/pypy/module/micronumpy/__init__.py @@ -27,9 +27,6 @@ 'True_': 'types.Bool.True', 'False_': 'types.Bool.False', - 'bool': 'space.w_bool', - 'int': 'space.w_int', - 'typeinfo': 'interp_dtype.get_dtype_cache(space).w_typeinfo', 'generic': 'interp_boxes.W_GenericBox', @@ -82,7 +79,6 @@ # ufuncs for exposed, impl in [ - ("abs", "absolute"), ("absolute", "absolute"), ("add", "add"), ("arccos", "arccos"), @@ -163,14 +159,17 @@ interpleveldefs[exposed] = "interp_ufuncs.get(space).%s" % impl appleveldefs = { - 'average': 'app_numpy.average', - 'sum': 'app_numpy.sum', - 'min': 'app_numpy.min', - 'identity': 'app_numpy.identity', - 'eye': 'app_numpy.eye', - 'max': 'app_numpy.max', 'arange': 'app_numpy.arange', } + def setup_after_space_initialization(self): + space = self.space + all_list = sorted(Module.interpleveldefs.keys() + \ + Module.appleveldefs.keys()) + # found by set(numpypy.__all__) - set(numpy.__all__) + all_list.remove('set_string_function') + all_list.remove('typeinfo') + w_all = space.wrap(all_list) + space.setitem(self.w_dict, space.new_interned_str('__all__'), w_all) if long_double_size == 16: Module.interpleveldefs['float128'] = 'interp_boxes.W_Float128Box' diff --git a/pypy/module/micronumpy/app_numpy.py b/pypy/module/micronumpy/app_numpy.py --- a/pypy/module/micronumpy/app_numpy.py +++ b/pypy/module/micronumpy/app_numpy.py @@ -2,82 +2,6 @@ import _numpypy -def average(a): - # This implements a weighted average, for now we don't implement the - # weighting, just the average part! - if not hasattr(a, "mean"): - a = _numpypy.array(a) - return a.mean() - -def identity(n, dtype=None): - a = _numpypy.zeros((n, n), dtype=dtype) - for i in range(n): - a[i][i] = 1 - return a - -def eye(n, m=None, k=0, dtype=None): - if m is None: - m = n - a = _numpypy.zeros((n, m), dtype=dtype) - ni = 0 - mi = 0 - - if k < 0: - p = n + k - ni = -k - else: - p = n - k - mi = k - - while ni < n and mi < m: - a[ni][mi] = 1 - ni += 1 - mi += 1 - return a - -def sum(a,axis=None, out=None): - '''sum(a, axis=None) - Sum of array elements over a given axis. - - Parameters - ---------- - a : array_like - Elements to sum. - axis : integer, optional - Axis over which the sum is taken. By default `axis` is None, - and all elements are summed. - - Returns - ------- - sum_along_axis : ndarray - An array with the same shape as `a`, with the specified - axis removed. If `a` is a 0-d array, or if `axis` is None, a scalar - is returned. If an output array is specified, a reference to - `out` is returned. - - See Also - -------- - ndarray.sum : Equivalent method. - ''' - # TODO: add to doc (once it's implemented): cumsum : Cumulative sum of array elements. - if not hasattr(a, "sum"): - a = _numpypy.array(a) - return a.sum(axis=axis, out=out) - -def min(a, axis=None, out=None): - if not hasattr(a, "min"): - a = _numpypy.array(a) - if a.size < 1: - return _numpypy.array([]) - return a.min(axis=axis, out=out) - -def max(a, axis=None, out=None): - if not hasattr(a, "max"): - a = _numpypy.array(a) - if a.size < 1: - return _numpypy.array([]) - return a.max(axis=axis, out=out) - def arange(start, stop=None, step=1, dtype=None): '''arange([start], stop[, step], dtype=None) Generate values in the half-interval [start, stop). diff --git a/pypy/module/micronumpy/interp_numarray.py b/pypy/module/micronumpy/interp_numarray.py --- a/pypy/module/micronumpy/interp_numarray.py +++ b/pypy/module/micronumpy/interp_numarray.py @@ -453,13 +453,17 @@ @unwrap_spec(mode=str) def descr_choose(self, space, w_choices, mode='raise', w_out=None): - if w_out is not None and not isinstance(w_out, W_NDimArray): + if space.is_none(w_out): + w_out = None + elif not isinstance(w_out, W_NDimArray): raise OperationError(space.w_TypeError, space.wrap( "return arrays must be of ArrayType")) return interp_arrayops.choose(space, self, w_choices, w_out, mode) def descr_clip(self, space, w_min, w_max, w_out=None): - if w_out is not None and not isinstance(w_out, W_NDimArray): + if space.is_none(w_out): + w_out = None + elif not isinstance(w_out, W_NDimArray): raise OperationError(space.w_TypeError, space.wrap( "return arrays must be of ArrayType")) min = convert_to_array(space, w_min) diff --git a/pypy/module/micronumpy/test/test_arrayops.py b/pypy/module/micronumpy/test/test_arrayops.py --- a/pypy/module/micronumpy/test/test_arrayops.py +++ b/pypy/module/micronumpy/test/test_arrayops.py @@ -99,10 +99,13 @@ def test_choose_out(self): from _numpypy import array a, b, c = array([1, 2, 3]), [4, 5, 6], 13 + r = array([2, 1, 0]).choose([a, b, c], out=None) + assert (r == [13, 5, 3]).all() + assert (a == [1, 2, 3]).all() r = array([2, 1, 0]).choose([a, b, c], out=a) assert (r == [13, 5, 3]).all() assert (a == [13, 5, 3]).all() - + def test_choose_modes(self): from _numpypy import array a, b, c = array([1, 2, 3]), [4, 5, 6], 13 diff --git a/pypy/module/micronumpy/test/test_complex.py b/pypy/module/micronumpy/test/test_complex.py --- a/pypy/module/micronumpy/test/test_complex.py +++ b/pypy/module/micronumpy/test/test_complex.py @@ -382,7 +382,7 @@ def test_conjugate(self): from _numpypy import conj, conjugate, complex128, complex64 - import _numpypy as np + import numpypy as np c0 = complex128(complex(2.5, 0)) c1 = complex64(complex(1, 2)) @@ -495,8 +495,8 @@ def test_basic(self): from _numpypy import (complex128, complex64, add, array, dtype, - subtract as sub, multiply, divide, negative, abs, floor_divide, - real, imag, sign, clongfloat) + subtract as sub, multiply, divide, negative, absolute as abs, + floor_divide, real, imag, sign, clongfloat) from _numpypy import (equal, not_equal, greater, greater_equal, less, less_equal, isnan) assert real(4.0) == 4.0 diff --git a/pypy/module/micronumpy/test/test_dtypes.py b/pypy/module/micronumpy/test/test_dtypes.py --- a/pypy/module/micronumpy/test/test_dtypes.py +++ b/pypy/module/micronumpy/test/test_dtypes.py @@ -638,9 +638,6 @@ def test_various_types(self): import _numpypy as numpy - assert numpy.bool is bool - assert numpy.int is int - assert numpy.int16 is numpy.short assert numpy.int8 is numpy.byte assert numpy.bool_ is numpy.bool8 diff --git a/pypy/module/micronumpy/test/test_module.py b/pypy/module/micronumpy/test/test_module.py deleted file mode 100644 --- a/pypy/module/micronumpy/test/test_module.py +++ /dev/null @@ -1,25 +0,0 @@ -from pypy.module.micronumpy.test.test_base import BaseNumpyAppTest - - -class AppTestNumPyModule(BaseNumpyAppTest): - def test_average(self): - from _numpypy import array, average - assert average(range(10)) == 4.5 - assert average(array(range(10))) == 4.5 - - def test_sum(self): - from _numpypy import array, sum - assert sum(range(10)) == 45 - assert sum(array(range(10))) == 45 - - def test_min(self): - from _numpypy import array, min, zeros - assert min(range(10)) == 0 - assert min(array(range(10))) == 0 - assert list(min(zeros((0, 2)), axis=1)) == [] - - def test_max(self): - from _numpypy import array, max, zeros - assert max(range(10)) == 9 - assert max(array(range(10))) == 9 - assert list(max(zeros((0, 2)), axis=1)) == [] diff --git a/pypy/module/micronumpy/test/test_numarray.py b/pypy/module/micronumpy/test/test_numarray.py --- a/pypy/module/micronumpy/test/test_numarray.py +++ b/pypy/module/micronumpy/test/test_numarray.py @@ -1141,7 +1141,7 @@ assert (a.mean(1) == [0.5, 2.5, 4.5, 6.5, 8.5]).all() def test_sum(self): - from _numpypy import array + from _numpypy import array, zeros a = array(range(5)) assert a.sum() == 10 assert a[:4].sum() == 6 @@ -1156,6 +1156,8 @@ assert b == d assert b is d + assert list(zeros((0, 2)).sum(axis=1)) == [] + def test_reduce_nd(self): from numpypy import arange, array, multiply a = arange(15).reshape(5, 3) @@ -1186,55 +1188,6 @@ assert (array([[1,2],[3,4]]).prod(0) == [3, 8]).all() assert (array([[1,2],[3,4]]).prod(1) == [2, 12]).all() - def test_identity(self): - from _numpypy import identity, array - from _numpypy import int32, float64, dtype - a = identity(0) - assert len(a) == 0 - assert a.dtype == dtype('float64') - assert a.shape == (0, 0) - b = identity(1, dtype=int32) - assert len(b) == 1 - assert b[0][0] == 1 - assert b.shape == (1, 1) - assert b.dtype == dtype('int32') - c = identity(2) - assert c.shape == (2, 2) - assert (c == [[1, 0], [0, 1]]).all() - d = identity(3, dtype='int32') - assert d.shape == (3, 3) - assert d.dtype == dtype('int32') - assert (d == [[1, 0, 0], [0, 1, 0], [0, 0, 1]]).all() - - def test_eye(self): - from _numpypy import eye - from _numpypy import int32, dtype - a = eye(0) - assert len(a) == 0 - assert a.dtype == dtype('float64') - assert a.shape == (0, 0) - b = eye(1, dtype=int32) - assert len(b) == 1 - assert b[0][0] == 1 - assert b.shape == (1, 1) - assert b.dtype == dtype('int32') - c = eye(2) - assert c.shape == (2, 2) - assert (c == [[1, 0], [0, 1]]).all() - d = eye(3, dtype='int32') - assert d.shape == (3, 3) - assert d.dtype == dtype('int32') - assert (d == [[1, 0, 0], [0, 1, 0], [0, 0, 1]]).all() - e = eye(3, 4) - assert e.shape == (3, 4) - assert (e == [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0]]).all() - f = eye(2, 4, k=3) - assert f.shape == (2, 4) - assert (f == [[0, 0, 0, 1], [0, 0, 0, 0]]).all() - g = eye(3, 4, k=-1) - assert g.shape == (3, 4) - assert (g == [[0, 0, 0, 0], [1, 0, 0, 0], [0, 1, 0, 0]]).all() - def test_prod(self): from _numpypy import array a = array(range(1, 6)) @@ -1242,24 +1195,28 @@ assert a[:4].prod() == 24.0 def test_max(self): - from _numpypy import array + from _numpypy import array, zeros a = array([-1.2, 3.4, 5.7, -3.0, 2.7]) assert a.max() == 5.7 b = array([]) raises(ValueError, "b.max()") + assert list(zeros((0, 2)).max(axis=1)) == [] + def test_max_add(self): from _numpypy import array a = array([-1.2, 3.4, 5.7, -3.0, 2.7]) assert (a + a).max() == 11.4 def test_min(self): - from _numpypy import array + from _numpypy import array, zeros a = array([-1.2, 3.4, 5.7, -3.0, 2.7]) assert a.min() == -3.0 b = array([]) raises(ValueError, "b.min()") + assert list(zeros((0, 2)).min(axis=1)) == [] + def test_argmax(self): from _numpypy import array a = array([-1.2, 3.4, 5.7, -3.0, 2.7]) @@ -1748,7 +1705,8 @@ from _numpypy import array a = array([1, 2, 17, -3, 12]) assert (a.clip(-2, 13) == [1, 2, 13, -2, 12]).all() - assert (a.clip(-1, 1) == [1, 1, 1, -1, 1]).all() + assert (a.clip(-1, 1, out=None) == [1, 1, 1, -1, 1]).all() + assert (a == [1, 2, 17, -3, 12]).all() assert (a.clip(-1, [1, 2, 3, 4, 5]) == [1, 2, 3, -1, 5]).all() assert (a.clip(-2, 13, out=a) == [1, 2, 13, -2, 12]).all() assert (a == [1, 2, 13, -2, 12]).all() diff --git a/pypy/module/micronumpy/test/test_outarg.py b/pypy/module/micronumpy/test/test_outarg.py --- a/pypy/module/micronumpy/test/test_outarg.py +++ b/pypy/module/micronumpy/test/test_outarg.py @@ -83,22 +83,9 @@ b = add(10, 10, out=out) assert b==out assert b.dtype == out.dtype - - def test_applevel(self): - from _numpypy import array, sum, max, min - a = array([[1, 2], [3, 4]]) - out = array([[0, 0], [0, 0]]) - c = sum(a, axis=0, out=out[0]) - assert (c == [4, 6]).all() - assert (c == out[0]).all() - assert (c != out[1]).all() - c = max(a, axis=1, out=out[0]) - assert (c == [2, 4]).all() - assert (c == out[0]).all() - assert (c != out[1]).all() - + def test_ufunc_cast(self): - from _numpypy import array, negative, add, sum + from _numpypy import array, negative, add a = array(16, dtype = int) c = array(0, dtype = float) b = negative(a, out=c) @@ -106,7 +93,7 @@ b = add(a, a, out=c) assert b == c d = array([16, 16], dtype=int) - b = sum(d, out=c) + b = d.sum(out=c) assert b == c #cast_error = raises(TypeError, negative, c, a) #assert str(cast_error.value) == \ diff --git a/pypy/module/test_lib_pypy/numpypy/core/test_fromnumeric.py b/pypy/module/test_lib_pypy/numpypy/core/test_fromnumeric.py --- a/pypy/module/test_lib_pypy/numpypy/core/test_fromnumeric.py +++ b/pypy/module/test_lib_pypy/numpypy/core/test_fromnumeric.py @@ -34,9 +34,23 @@ # a = array([(1, 2), (3, 4)], dtype=[('x', 'i4'), ('y', 'i4')]) # assert shape(a) == (2,) + def test_clip(self): + import numpypy as np + a = np.arange(10) + b = np.clip(a, 1, 8) + assert (b == [1, 1, 2, 3, 4, 5, 6, 7, 8, 8]).all() + assert (a == [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]).all() + b = np.clip(a, 3, 6, out=a) + assert (b == [3, 3, 3, 3, 4, 5, 6, 6, 6, 6]).all() + assert (a == [3, 3, 3, 3, 4, 5, 6, 6, 6, 6]).all() + a = np.arange(10) + b = np.clip(a, [3,4,1,1,1,4,4,4,4,4], 8) + assert (b == [3, 4, 2, 3, 4, 5, 6, 7, 8, 8]).all() + assert (a == [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]).all() + def test_sum(self): # tests taken from numpy/core/fromnumeric.py docstring - from numpypy import array, sum, ones + from numpypy import array, sum, ones, zeros assert sum([0.5, 1.5])== 2.0 assert sum([[0, 1], [0, 5]]) == 6 # assert sum([0.5, 0.7, 0.2, 1.5], dtype=int32) == 1 @@ -45,9 +59,20 @@ # If the accumulator is too small, overflow occurs: # assert ones(128, dtype=int8).sum(dtype=int8) == -128 + assert sum(range(10)) == 45 + assert sum(array(range(10))) == 45 + assert list(sum(zeros((0, 2)), axis=1)) == [] + + a = array([[1, 2], [3, 4]]) + out = array([[0, 0], [0, 0]]) + c = sum(a, axis=0, out=out[0]) + assert (c == [4, 6]).all() + assert (c == out[0]).all() + assert (c != out[1]).all() + def test_amin(self): # tests taken from numpy/core/fromnumeric.py docstring - from numpypy import array, arange, amin + from numpypy import array, arange, amin, zeros a = arange(4).reshape((2,2)) assert amin(a) == 0 # # Minima along the first axis @@ -60,9 +85,20 @@ # assert amin(b) == nan # assert nanmin(b) == 0.0 + assert amin(range(10)) == 0 + assert amin(array(range(10))) == 0 + assert list(amin(zeros((0, 2)), axis=1)) == [] + + a = array([[1, 2], [3, 4]]) + out = array([[0, 0], [0, 0]]) + c = amin(a, axis=1, out=out[0]) + assert (c == [1, 3]).all() + assert (c == out[0]).all() + assert (c != out[1]).all() + def test_amax(self): # tests taken from numpy/core/fromnumeric.py docstring - from numpypy import array, arange, amax + from numpypy import array, arange, amax, zeros a = arange(4).reshape((2,2)) assert amax(a) == 3 # assert (amax(a, axis=0) == array([2, 3])).all() @@ -73,6 +109,17 @@ # assert amax(b) == nan # assert nanmax(b) == 4.0 + assert amax(range(10)) == 9 + assert amax(array(range(10))) == 9 + assert list(amax(zeros((0, 2)), axis=1)) == [] + + a = array([[1, 2], [3, 4]]) + out = array([[0, 0], [0, 0]]) + c = amax(a, axis=1, out=out[0]) + assert (c == [2, 4]).all() + assert (c == out[0]).all() + assert (c != out[1]).all() + def test_alen(self): # tests taken from numpy/core/fromnumeric.py docstring from numpypy import array, zeros, alen diff --git a/pypy/module/test_lib_pypy/numpypy/core/test_numeric.py b/pypy/module/test_lib_pypy/numpypy/core/test_numeric.py --- a/pypy/module/test_lib_pypy/numpypy/core/test_numeric.py +++ b/pypy/module/test_lib_pypy/numpypy/core/test_numeric.py @@ -20,6 +20,7 @@ assert base_repr(-12, 10, 4) == '-000012' assert base_repr(-12, 4) == '-30' + class AppTestRepr(BaseNumpyAppTest): def test_repr(self): from numpypy import array @@ -146,10 +147,10 @@ def test_equal(self): from _numpypy import array from numpypy import array_equal - + a = [1, 2, 3] b = [1, 2, 3] - + assert array_equal(a, b) assert array_equal(a, array(b)) assert array_equal(array(a), b) @@ -158,10 +159,10 @@ def test_not_equal(self): from _numpypy import array from numpypy import array_equal - + a = [1, 2, 3] b = [1, 2, 4] - + assert not array_equal(a, b) assert not array_equal(a, array(b)) assert not array_equal(array(a), b) @@ -170,17 +171,17 @@ def test_mismatched_shape(self): from _numpypy import array from numpypy import array_equal - + a = [1, 2, 3] b = [[1, 2, 3], [1, 2, 3]] - + assert not array_equal(a, b) assert not array_equal(a, array(b)) assert not array_equal(array(a), b) assert not array_equal(array(a), array(b)) + class AppTestNumeric(BaseNumpyAppTest): - def test_outer(self): from _numpypy import array from numpypy import outer @@ -192,3 +193,22 @@ [12, 15, 18]]) assert (res == expected).all() + def test_identity(self): + from _numpypy import array, int32, float64, dtype + from numpypy import identity + a = identity(0) + assert len(a) == 0 + assert a.dtype == dtype('float64') + assert a.shape == (0, 0) + b = identity(1, dtype=int32) + assert len(b) == 1 + assert b[0][0] == 1 + assert b.shape == (1, 1) + assert b.dtype == dtype('int32') + c = identity(2) + assert c.shape == (2, 2) + assert (c == [[1, 0], [0, 1]]).all() + d = identity(3, dtype='int32') + assert d.shape == (3, 3) + assert d.dtype == dtype('int32') + assert (d == [[1, 0, 0], [0, 1, 0], [0, 0, 1]]).all() diff --git a/pypy/module/test_lib_pypy/numpypy/core/test_shape_base.py b/pypy/module/test_lib_pypy/numpypy/core/test_shape_base.py --- a/pypy/module/test_lib_pypy/numpypy/core/test_shape_base.py +++ b/pypy/module/test_lib_pypy/numpypy/core/test_shape_base.py @@ -129,35 +129,3 @@ np.ones((a.shape[0], a.shape[1] + b.shape[1], a.shape[2]))) - - def test_dstack(self): - import numpypy as np - a = np.array((1, 2, 3)) - b = np.array((2, 3, 4)) - c = np.dstack((a, b)) - assert np.array_equal(c, [[[1, 2], [2, 3], [3, 4]]]) - - a = np.array([[1], [2], [3]]) - b = np.array([[2], [3], [4]]) - c = np.dstack((a, b)) - assert np.array_equal(c, [[[1, 2]], [[2, 3]], [[3, 4]]]) - - #skip("https://bugs.pypy.org/issue1394") - for shape1, shape2 in [[(4, 2, 3), (4, 2, 7)], - [(7, 2, 0), (7, 2, 10)], - [(7, 2, 0), (7, 2, 0)]]: - a, b = np.ones(shape1), np.ones(shape2) - assert np.all(np.dstack((a, b)) == - np.ones((a.shape[0], - a.shape[1], - a.shape[2] + b.shape[2]))) - - for shape1, shape2 in [[(4, 2, 3, 5), (4, 2, 7, 5)], - [(7, 2, 0, 5), (7, 2, 10, 5)], - [(7, 2, 0, 5), (7, 2, 0, 5)]]: - a, b = np.ones(shape1), np.ones(shape2) - assert np.all(np.dstack((a, b)) == - np.ones((a.shape[0], - a.shape[1], - a.shape[2] + b.shape[2], - a.shape[3]))) diff --git a/pypy/module/test_lib_pypy/numpypy/lib/test_function_base.py b/pypy/module/test_lib_pypy/numpypy/lib/test_function_base.py new file mode 100644 --- /dev/null +++ b/pypy/module/test_lib_pypy/numpypy/lib/test_function_base.py @@ -0,0 +1,7 @@ +from pypy.module.micronumpy.test.test_base import BaseNumpyAppTest + +class AppTestFunctionBase(BaseNumpyAppTest): + def test_average(self): + from numpypy import array, average + assert average(range(10)) == 4.5 + assert average(array(range(10))) == 4.5 diff --git a/pypy/module/test_lib_pypy/numpypy/lib/test_shape_base_lib.py b/pypy/module/test_lib_pypy/numpypy/lib/test_shape_base_lib.py new file mode 100644 --- /dev/null +++ b/pypy/module/test_lib_pypy/numpypy/lib/test_shape_base_lib.py @@ -0,0 +1,34 @@ +from pypy.module.micronumpy.test.test_base import BaseNumpyAppTest + +class AppTestShapeBase(BaseNumpyAppTest): + def test_dstack(self): + import numpypy as np + a = np.array((1, 2, 3)) + b = np.array((2, 3, 4)) + c = np.dstack((a, b)) + assert np.array_equal(c, [[[1, 2], [2, 3], [3, 4]]]) + + a = np.array([[1], [2], [3]]) + b = np.array([[2], [3], [4]]) + c = np.dstack((a, b)) + assert np.array_equal(c, [[[1, 2]], [[2, 3]], [[3, 4]]]) + + #skip("https://bugs.pypy.org/issue1394") + for shape1, shape2 in [[(4, 2, 3), (4, 2, 7)], + [(7, 2, 0), (7, 2, 10)], + [(7, 2, 0), (7, 2, 0)]]: + a, b = np.ones(shape1), np.ones(shape2) + assert np.all(np.dstack((a, b)) == + np.ones((a.shape[0], + a.shape[1], + a.shape[2] + b.shape[2]))) + + for shape1, shape2 in [[(4, 2, 3, 5), (4, 2, 7, 5)], + [(7, 2, 0, 5), (7, 2, 10, 5)], + [(7, 2, 0, 5), (7, 2, 0, 5)]]: + a, b = np.ones(shape1), np.ones(shape2) + assert np.all(np.dstack((a, b)) == + np.ones((a.shape[0], + a.shape[1], + a.shape[2] + b.shape[2], + a.shape[3]))) diff --git a/pypy/module/test_lib_pypy/numpypy/lib/test_twodim_base.py b/pypy/module/test_lib_pypy/numpypy/lib/test_twodim_base.py new file mode 100644 --- /dev/null +++ b/pypy/module/test_lib_pypy/numpypy/lib/test_twodim_base.py @@ -0,0 +1,31 @@ +from pypy.module.micronumpy.test.test_base import BaseNumpyAppTest + +class AppTestTwoDimBase(BaseNumpyAppTest): + def test_eye(self): + from _numpypy import int32, dtype + from numpypy import eye + a = eye(0) + assert len(a) == 0 + assert a.dtype == dtype('float64') + assert a.shape == (0, 0) + b = eye(1, dtype=int32) + assert len(b) == 1 + assert b[0][0] == 1 + assert b.shape == (1, 1) + assert b.dtype == dtype('int32') + c = eye(2) + assert c.shape == (2, 2) + assert (c == [[1, 0], [0, 1]]).all() + d = eye(3, dtype='int32') + assert d.shape == (3, 3) + assert d.dtype == dtype('int32') + assert (d == [[1, 0, 0], [0, 1, 0], [0, 0, 1]]).all() + e = eye(3, 4) + assert e.shape == (3, 4) + assert (e == [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0]]).all() + f = eye(2, 4, k=3) + assert f.shape == (2, 4) + assert (f == [[0, 0, 0, 1], [0, 0, 0, 0]]).all() + g = eye(3, 4, k=-1) + assert g.shape == (3, 4) + assert (g == [[0, 0, 0, 0], [1, 0, 0, 0], [0, 1, 0, 0]]).all() diff --git a/pypy/module/test_lib_pypy/numpypy/test_numpy.py b/pypy/module/test_lib_pypy/numpypy/test_numpy.py --- a/pypy/module/test_lib_pypy/numpypy/test_numpy.py +++ b/pypy/module/test_lib_pypy/numpypy/test_numpy.py @@ -1,4 +1,6 @@ -class AppTestNumpy: +from pypy.module.micronumpy.test.test_base import BaseNumpyAppTest + +class AppTestNumpy(BaseNumpyAppTest): spaceconfig = dict(usemodules=['micronumpy']) def test_imports(self): @@ -11,6 +13,7 @@ def test_min_max_after_import(self): import __builtin__ + from __builtin__ import * from numpypy import * assert min is __builtin__.min @@ -25,6 +28,28 @@ assert min(4, 3, 2, 1) == 1 assert max(1, 2, 3, 4) == 4 - from numpypy import min, max + from numpypy import min, max, amin, amax assert min is not __builtin__.min assert max is not __builtin__.max + assert min is amin + assert max is amax + + def test_builtin_aliases(self): + import __builtin__ + import numpypy + from numpypy import * + + for name in ['bool', 'int', 'long', 'float', 'complex', 'object', + 'unicode', 'str']: + assert name not in locals() + assert getattr(numpypy, name) is getattr(__builtin__, name) + + def test_typeinfo(self): + import numpypy + assert 'typeinfo' not in dir(numpypy) + assert 'typeinfo' in dir(numpypy.core.multiarray) + + def test_set_string_function(self): + import numpypy + assert numpypy.set_string_function is not \ + numpypy.core.multiarray.set_string_function diff --git a/rpython/jit/backend/arm/regalloc.py b/rpython/jit/backend/arm/regalloc.py --- a/rpython/jit/backend/arm/regalloc.py +++ b/rpython/jit/backend/arm/regalloc.py @@ -697,7 +697,7 @@ classptr = y_val # here, we have to go back from 'classptr' to the value expected # from reading the 16 bits in the object header - from rpython.rtyper.memory.gctypelayout import GCData + from rpython.memory.gctypelayout import GCData sizeof_ti = rffi.sizeof(GCData.TYPE_INFO) type_info_group = llop.gc_get_type_info_group(llmemory.Address) type_info_group = rffi.cast(lltype.Signed, type_info_group) diff --git a/rpython/jit/backend/llsupport/gc.py b/rpython/jit/backend/llsupport/gc.py --- a/rpython/jit/backend/llsupport/gc.py +++ b/rpython/jit/backend/llsupport/gc.py @@ -17,7 +17,7 @@ from rpython.jit.backend.llsupport.descr import get_array_descr from rpython.jit.backend.llsupport.descr import get_call_descr from rpython.jit.backend.llsupport.rewrite import GcRewriterAssembler -from rpython.rtyper.memory.gctransform import asmgcroot +from rpython.memory.gctransform import asmgcroot # ____________________________________________________________ @@ -369,14 +369,14 @@ def _make_layoutbuilder(self): # make a TransformerLayoutBuilder and save it on the translator # where it can be fished and reused by the FrameworkGCTransformer - from rpython.rtyper.memory.gctransform import framework + from rpython.memory.gctransform import framework translator = self.translator self.layoutbuilder = framework.TransformerLayoutBuilder(translator) self.layoutbuilder.delay_encoding() translator._jit2gc = {'layoutbuilder': self.layoutbuilder} def _setup_gcclass(self): - from rpython.rtyper.memory.gcheader import GCHeaderBuilder + from rpython.memory.gcheader import GCHeaderBuilder self.GCClass = self.layoutbuilder.GCClass self.moving_gc = self.GCClass.moving_gc self.HDRPTR = lltype.Ptr(self.GCClass.HDR) @@ -399,7 +399,7 @@ self.write_barrier_descr = WriteBarrierDescr(self) def _make_functions(self, really_not_translated): - from rpython.rtyper.memory.gctypelayout import check_typeid + from rpython.memory.gctypelayout import check_typeid llop1 = self.llop1 (self.standard_array_basesize, _, self.standard_array_length_ofs) = \ symbolic.get_array_token(lltype.GcArray(lltype.Signed), @@ -485,7 +485,7 @@ [lltype.Signed] * 2) def _bh_malloc(self, sizedescr): - from rpython.rtyper.memory.gctypelayout import check_typeid + from rpython.memory.gctypelayout import check_typeid llop1 = self.llop1 type_id = llop.extract_ushort(llgroup.HALFWORD, sizedescr.tid) check_typeid(type_id) @@ -494,7 +494,7 @@ False, False, False) def _bh_malloc_array(self, num_elem, arraydescr): - from rpython.rtyper.memory.gctypelayout import check_typeid + from rpython.memory.gctypelayout import check_typeid llop1 = self.llop1 type_id = llop.extract_ushort(llgroup.HALFWORD, arraydescr.tid) check_typeid(type_id) diff --git a/rpython/jit/backend/llsupport/test/test_symbolic.py b/rpython/jit/backend/llsupport/test/test_symbolic.py --- a/rpython/jit/backend/llsupport/test/test_symbolic.py +++ b/rpython/jit/backend/llsupport/test/test_symbolic.py @@ -1,7 +1,7 @@ import py from rpython.jit.backend.llsupport.symbolic import * from rpython.rtyper.lltypesystem import lltype, rffi -from rpython.rtyper.memory.lltypelayout import convert_offset_to_int +from rpython.memory.lltypelayout import convert_offset_to_int WORD = rffi.sizeof(lltype.Signed) diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -387,7 +387,7 @@ @rgc.no_collect def _release_gil_asmgcc(css): # similar to trackgcroot.py:pypy_asm_stackwalk, first part - from rpython.rtyper.memory.gctransform import asmgcroot + from rpython.memory.gctransform import asmgcroot new = rffi.cast(asmgcroot.ASM_FRAMEDATA_HEAD_PTR, css) next = asmgcroot.gcrootanchor.next new.next = next @@ -407,7 +407,7 @@ if after: after() # similar to trackgcroot.py:pypy_asm_stackwalk, second part - from rpython.rtyper.memory.gctransform import asmgcroot + from rpython.memory.gctransform import asmgcroot old = rffi.cast(asmgcroot.ASM_FRAMEDATA_HEAD_PTR, css) prev = old.prev next = old.next @@ -1823,7 +1823,7 @@ # from reading the half-word in the object header. Note that # this half-word is at offset 0 on a little-endian machine; # it would be at offset 2 or 4 on a big-endian machine. - from rpython.rtyper.memory.gctypelayout import GCData + from rpython.memory.gctypelayout import GCData sizeof_ti = rffi.sizeof(GCData.TYPE_INFO) type_info_group = llop.gc_get_type_info_group(llmemory.Address) type_info_group = rffi.cast(lltype.Signed, type_info_group) @@ -2128,7 +2128,7 @@ # will just push/pop them. raise NotImplementedError xxx - from rpython.rtyper.memory.gctransform import asmgcroot + from rpython.memory.gctransform import asmgcroot css = self._regalloc.close_stack_struct if css == 0: use_words = (2 + max(asmgcroot.INDEX_OF_EBP, diff --git a/rpython/rtyper/memory/__init__.py b/rpython/memory/__init__.py rename from rpython/rtyper/memory/__init__.py rename to rpython/memory/__init__.py diff --git a/rpython/rtyper/memory/gc/__init__.py b/rpython/memory/gc/__init__.py rename from rpython/rtyper/memory/gc/__init__.py rename to rpython/memory/gc/__init__.py diff --git a/rpython/memory/gc/base.py b/rpython/memory/gc/base.py new file mode 100644 --- /dev/null +++ b/rpython/memory/gc/base.py @@ -0,0 +1,454 @@ +from rpython.rtyper.lltypesystem import lltype, llmemory, llarena, rffi +from rpython.rtyper.lltypesystem.lloperation import llop +from rpython.rlib.debug import ll_assert +from rpython.memory.gcheader import GCHeaderBuilder +from rpython.memory.support import DEFAULT_CHUNK_SIZE +from rpython.memory.support import get_address_stack, get_address_deque +from rpython.memory.support import AddressDict, null_address_dict +from rpython.rtyper.lltypesystem.llmemory import NULL, raw_malloc_usage + +TYPEID_MAP = lltype.GcStruct('TYPEID_MAP', ('count', lltype.Signed), + ('size', lltype.Signed), + ('links', lltype.Array(lltype.Signed))) +ARRAY_TYPEID_MAP = lltype.GcArray(lltype.Ptr(TYPEID_MAP)) + +class GCBase(object): + _alloc_flavor_ = "raw" + moving_gc = False + needs_write_barrier = False + malloc_zero_filled = False + prebuilt_gc_objects_are_static_roots = True + object_minimal_size = 0 + gcflag_extra = 0 # or a real GC flag that is always 0 when not collecting + + def __init__(self, config, chunk_size=DEFAULT_CHUNK_SIZE, + translated_to_c=True): + self.gcheaderbuilder = GCHeaderBuilder(self.HDR) + self.AddressStack = get_address_stack(chunk_size) + self.AddressDeque = get_address_deque(chunk_size) + self.AddressDict = AddressDict + self.null_address_dict = null_address_dict + self.config = config + assert isinstance(translated_to_c, bool) + self.translated_to_c = translated_to_c + + def setup(self): + # all runtime mutable values' setup should happen here + # and in its overriden versions! for the benefit of test_transformed_gc + self.finalizer_lock_count = 0 + self.run_finalizers = self.AddressDeque() + + def post_setup(self): + # More stuff that needs to be initialized when the GC is already + # fully working. (Only called by gctransform/framework for now.) + from rpython.memory.gc import env + self.DEBUG = env.read_from_env('PYPY_GC_DEBUG') + + def _teardown(self): + pass + + def can_malloc_nonmovable(self): + return not self.moving_gc + + def can_optimize_clean_setarrayitems(self): + return True # False in case of card marking + + # The following flag enables costly consistency checks after each + # collection. It is automatically set to True by test_gc.py. The + # checking logic is translatable, so the flag can be set to True + # here before translation. At run-time, if PYPY_GC_DEBUG is set, + # then it is also set to True. + DEBUG = False + + def set_query_functions(self, is_varsize, has_gcptr_in_varsize, + is_gcarrayofgcptr, + getfinalizer, + getlightfinalizer, + offsets_to_gc_pointers, + fixed_size, varsize_item_sizes, + varsize_offset_to_variable_part, + varsize_offset_to_length, + varsize_offsets_to_gcpointers_in_var_part, + weakpointer_offset, + member_index, + is_rpython_class, + has_custom_trace, + get_custom_trace, + fast_path_tracing): + self.getfinalizer = getfinalizer + self.getlightfinalizer = getlightfinalizer + self.is_varsize = is_varsize + self.has_gcptr_in_varsize = has_gcptr_in_varsize + self.is_gcarrayofgcptr = is_gcarrayofgcptr + self.offsets_to_gc_pointers = offsets_to_gc_pointers + self.fixed_size = fixed_size + self.varsize_item_sizes = varsize_item_sizes + self.varsize_offset_to_variable_part = varsize_offset_to_variable_part + self.varsize_offset_to_length = varsize_offset_to_length + self.varsize_offsets_to_gcpointers_in_var_part = varsize_offsets_to_gcpointers_in_var_part + self.weakpointer_offset = weakpointer_offset + self.member_index = member_index + self.is_rpython_class = is_rpython_class + self.has_custom_trace = has_custom_trace + self.get_custom_trace = get_custom_trace + self.fast_path_tracing = fast_path_tracing + + def get_member_index(self, type_id): + return self.member_index(type_id) + + def set_root_walker(self, root_walker): + self.root_walker = root_walker + + def write_barrier(self, newvalue, addr_struct): + pass + + def size_gc_header(self, typeid=0): + return self.gcheaderbuilder.size_gc_header + + def header(self, addr): + addr -= self.gcheaderbuilder.size_gc_header + return llmemory.cast_adr_to_ptr(addr, lltype.Ptr(self.HDR)) + + def _get_size_for_typeid(self, obj, typeid): + size = self.fixed_size(typeid) + if self.is_varsize(typeid): + lenaddr = obj + self.varsize_offset_to_length(typeid) + length = lenaddr.signed[0] + size += length * self.varsize_item_sizes(typeid) + size = llarena.round_up_for_allocation(size) + # XXX maybe we should parametrize round_up_for_allocation() + # per GC; if we do, we also need to fix the call in + # gctypelayout.encode_type_shape() + return size + + def get_size(self, obj): From noreply at buildbot.pypy.org Sat Feb 23 14:00:04 2013 From: noreply at buildbot.pypy.org (cfbolz) Date: Sat, 23 Feb 2013 14:00:04 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: be more efficient, this is used all the time Message-ID: <20130223130004.D8F7B1C0CA3@cobra.cs.uni-duesseldorf.de> Author: Carl Friedrich Bolz Branch: Changeset: r93:458404cbe54c Date: 2013-02-23 13:58 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/458404cbe54c/ Log: be more efficient, this is used all the time diff --git a/spyvm/objspace.py b/spyvm/objspace.py --- a/spyvm/objspace.py +++ b/spyvm/objspace.py @@ -1,7 +1,7 @@ from spyvm import constants, model, shadow, wrapper from spyvm.error import UnwrappingError, WrappingError from rpython.rlib.objectmodel import instantiate, specialize -from rpython.rlib.rarithmetic import intmask, r_uint +from rpython.rlib.rarithmetic import intmask, r_uint, int_between class ObjSpace(object): def __init__(self): @@ -168,7 +168,7 @@ def wrap_int(self, val): from spyvm import constants - if constants.TAGGED_MININT <= val <= constants.TAGGED_MAXINT: + if int_between(constants.TAGGED_MININT, val, constants.TAGGED_MAXINT + 1): return model.W_SmallInteger(val) raise WrappingError("integer too large to fit into a tagged pointer") From noreply at buildbot.pypy.org Sat Feb 23 14:00:06 2013 From: noreply at buildbot.pypy.org (cfbolz) Date: Sat, 23 Feb 2013 14:00:06 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: make .lookup return a CompiledMethodShadow directly Message-ID: <20130223130006.03ACD1C0CA3@cobra.cs.uni-duesseldorf.de> Author: Carl Friedrich Bolz Branch: Changeset: r94:8ce3304768eb Date: 2013-02-23 13:59 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/8ce3304768eb/ Log: make .lookup return a CompiledMethodShadow directly diff --git a/spyvm/interpreter.py b/spyvm/interpreter.py --- a/spyvm/interpreter.py +++ b/spyvm/interpreter.py @@ -97,9 +97,9 @@ else: w_selector = self.perform(self.space.wrap_string(selector), "asSymbol") s_class = w_receiver.shadow_of_my_class(self.space) - w_method = s_class.lookup(w_selector) - assert w_method - w_frame = w_method.create_frame(self.space, w_receiver, list(arguments_w)) + s_method = s_class.lookup(w_selector) + assert s_method + w_frame = s_method.create_frame(self.space, w_receiver, list(arguments_w)) try: self.loop(w_frame) except ReturnFromTopLevel, e: @@ -222,12 +222,12 @@ [self.peek(argcount-1-i) for i in range(argcount)]) pass assert argcount >= 0 - method = receiverclassshadow.lookup(w_selector) + s_method = receiverclassshadow.lookup(w_selector) # XXX catch MethodNotFound here and send doesNotUnderstand: # AK shouln't that be done in lookup itself, please check what spec says about DNU in case of super sends. - if method.primitive: + if s_method.primitive: # the primitive pushes the result (if any) onto the stack itself - code = method.primitive + code = s_method.primitive if interp.should_trace(): print "%sActually calling primitive %d" % (interp._last_indent, code,) if False: #objectmodel.we_are_translated(): @@ -244,10 +244,10 @@ return func(interp, self, argcount) except primitives.PrimitiveFailedError: if interp.should_trace(True): - print "PRIMITIVE FAILED: %d %s" % (method.primitive, w_selector.as_string(),) + print "PRIMITIVE FAILED: %d %s" % (s_method.primitive, w_selector.as_string(),) pass # ignore this error and fall back to the Smalltalk version arguments = self.pop_and_return_n(argcount) - w_frame = method.create_frame(self.space, receiver, arguments, + w_frame = s_method.create_frame(self.space, receiver, arguments, self.w_self()) self.pop() return w_frame diff --git a/spyvm/model.py b/spyvm/model.py --- a/spyvm/model.py +++ b/spyvm/model.py @@ -244,10 +244,13 @@ _shadow = None # Default value + @jit.unroll_safe def __init__(self, w_class, size): """Create new object with size = fixed + variable size.""" W_AbstractObjectWithClassReference.__init__(self, w_class) - self._vars = [w_nil] * size + vars = self._vars = [None] * size + for i in range(size): # do it by hand for the JIT's sake + vars[i] = w_nil def at0(self, space, index0): # To test, at0 = in varsize part @@ -486,13 +489,6 @@ def getclass(self, space): return space.w_CompiledMethod - def create_frame(self, space, receiver, arguments, sender = None): - from spyvm import shadow - assert len(arguments) == self.argsize - w_new = shadow.MethodContextShadow.make_context( - space, self, receiver, arguments, sender) - return w_new - def __str__(self): from spyvm.interpreter import BYTECODE_TABLE j = 1 diff --git a/spyvm/primitives.py b/spyvm/primitives.py --- a/spyvm/primitives.py +++ b/spyvm/primitives.py @@ -857,10 +857,11 @@ unwrap_spec=[object, object, object], result_is_new_frame=True) def func(interp, s_frame, w_rcvr, w_sel, w_args): - w_method = w_rcvr.shadow_of_my_class(interp.space).lookup(w_sel) - assert w_method + s_method = w_rcvr.shadow_of_my_class(interp.space).lookup(w_sel) + assert s_method - w_frame = w_method.create_frame(interp.space, w_rcvr, + w_frame = s_method.create_frame( + interp.space, w_rcvr, [w_args.fetch(interp.space, i) for i in range(w_args.size())]) w_frame.as_context_get_shadow(interp.space).store_w_sender(s_frame.w_self()) diff --git a/spyvm/shadow.py b/spyvm/shadow.py --- a/spyvm/shadow.py +++ b/spyvm/shadow.py @@ -176,7 +176,7 @@ return w_new def s_methoddict(self): - return self.w_methoddict.as_methoddict_get_shadow(self.space) + return jit.promote(self.w_methoddict.as_methoddict_get_shadow(self.space)) def s_superclass(self): if self.w_superclass is None: @@ -226,12 +226,14 @@ def __repr__(self): return "" % (self.name or '?',) + @jit.unroll_safe def lookup(self, w_selector): look_in_shadow = self + jit.promote(w_selector) while look_in_shadow is not None: w_method = look_in_shadow.s_methoddict().find_selector(w_selector) if w_method is not None: - return w_method + return w_method.as_compiledmethod_get_shadow(self.space) look_in_shadow = look_in_shadow.s_superclass() raise MethodNotFound(self, w_selector) @@ -628,11 +630,11 @@ @staticmethod @jit.unroll_safe - def make_context(space, w_method, w_receiver, + def make_context(space, s_method, w_receiver, arguments, w_sender=None, closure=None, pc=0): # From blue book: normal mc have place for 12 temps+maxstack # mc for methods with islarge flag turned on 32 - size = 12 + w_method.islarge * 20 + w_method.argsize + size = 12 + s_method.islarge * 20 + s_method.argsize w_result = space.w_MethodContext.as_class_get_shadow(space).new(size) assert isinstance(w_result, model.W_PointersObject) # create and attach a shadow manually, to not have to carefully put things @@ -643,7 +645,7 @@ if closure is not None: s_result.w_closure_or_nil = closure._w_self - s_result.store_w_method(w_method) + s_result.store_w_method(s_method.w_self()) if w_sender: s_result.store_w_sender(w_sender) s_result.store_w_receiver(w_receiver) @@ -739,6 +741,7 @@ _immutable_fields_ = ["_w_self", "bytecode", "literals[*]", "bytecodeoffset", "literalsize", "tempsize", "primitive", + "argsize", "islarge", "w_compiledin"] def __init__(self, w_compiledmethod): @@ -749,6 +752,8 @@ self.literalsize = w_compiledmethod.getliteralsize() self.tempsize = w_compiledmethod.gettempsize() self.primitive = w_compiledmethod.primitive + self.argsize = w_compiledmethod.argsize + self.islarge = w_compiledmethod.islarge self.w_compiledin = None if self.literals: @@ -763,6 +768,9 @@ association = wrapper.AssociationWrapper(None, w_association) self.w_compiledin = association.value() + def w_self(self): + return self._w_self + def getliteral(self, index): return self.literals[index] @@ -770,3 +778,9 @@ w_literal = self.getliteral(index) assert isinstance(w_literal, model.W_BytesObject) return w_literal.as_string() # XXX performance issue here + + def create_frame(self, space, receiver, arguments, sender = None): + assert len(arguments) == self.argsize + w_new = MethodContextShadow.make_context( + space, self, receiver, arguments, sender) + return w_new diff --git a/spyvm/test/jit.py b/spyvm/test/jit.py --- a/spyvm/test/jit.py +++ b/spyvm/test/jit.py @@ -63,8 +63,8 @@ w_selector = interp.perform(space.wrap_string("loopTest"), "asSymbol") w_object = model.W_SmallInteger(0) s_class = w_object.shadow_of_my_class(space) - w_method = s_class.lookup(w_selector) - w_frame = w_method.create_frame(space, w_object, []) + s_method = s_class.lookup(w_selector) + w_frame = s_method.create_frame(space, w_object, []) def interp_w(): interp.loop(w_frame) diff --git a/spyvm/test/test_interpreter.py b/spyvm/test/test_interpreter.py --- a/spyvm/test/test_interpreter.py +++ b/spyvm/test/test_interpreter.py @@ -85,7 +85,7 @@ w_method.argsize=2 w_method.tempsize=8 w_method.setliterals([model.W_PointersObject(None, 2)]) - w_frame = w_method.create_frame(space, receiver, ["foo", "bar"]) + w_frame = w_method.as_compiledmethod_get_shadow(space).create_frame(space, receiver, ["foo", "bar"]) return w_frame, w_frame.as_context_get_shadow(space) def test_create_frame(): @@ -94,7 +94,7 @@ w_method.islarge = 1 w_method.argsize=2 w_method.tempsize=8 - w_frame = w_method.create_frame(space, "receiver", ["foo", "bar"]) + w_frame = w_method.as_compiledmethod_get_shadow(space).create_frame(space, "receiver", ["foo", "bar"]) s_frame = w_frame.as_context_get_shadow(space) assert s_frame.w_receiver() == "receiver" assert s_frame.gettemp(0) == "foo" diff --git a/spyvm/test/test_model.py b/spyvm/test/test_model.py --- a/spyvm/test/test_model.py +++ b/spyvm/test/test_model.py @@ -59,14 +59,19 @@ py.test.raises(IndexError, lambda: w_bytes.getword(20)) def test_method_lookup(): - w_class = mockclass(space, 0) + class mockmethod(object): + def __init__(self, val): + self.val = val + def as_compiledmethod_get_shadow(self, space): + return self.val + w_class = mockclass(space, mockmethod(0)) shadow = w_class.as_class_get_shadow(space) - shadow.installmethod(w_foo, 1) - shadow.installmethod(w_bar, 2) + shadow.installmethod(w_foo, mockmethod(1)) + shadow.installmethod(w_bar, mockmethod(2)) w_subclass = mockclass(space, 0, w_superclass=w_class) subshadow = w_subclass.as_class_get_shadow(space) assert subshadow.s_superclass() is shadow - subshadow.installmethod(w_foo, 3) + subshadow.installmethod(w_foo, mockmethod(3)) shadow.initialize_methoddict() subshadow.initialize_methoddict() assert shadow.lookup(w_foo) == 1 @@ -83,7 +88,7 @@ supershadow.installmethod(w_foo, model.W_CompiledMethod(0)) classshadow = w_class.as_class_get_shadow(space) classshadow.initialize_methoddict() - assert classshadow.lookup(w_foo).as_compiledmethod_get_shadow(space).w_compiledin is w_super + assert classshadow.lookup(w_foo).w_compiledin is w_super def test_compiledmethod_setchar(): w_method = model.W_CompiledMethod(3) diff --git a/spyvm/wrapper.py b/spyvm/wrapper.py --- a/spyvm/wrapper.py +++ b/spyvm/wrapper.py @@ -227,9 +227,9 @@ def asContextWithSender(self, w_aContext, arguments): from spyvm import shadow s_outerContext = self.outerContext().get_shadow(self.space) - w_method = s_outerContext.w_method() + s_method = s_outerContext.w_method().as_compiledmethod_get_shadow(self.space) w_receiver = s_outerContext.w_receiver() - w_new_frame = shadow.MethodContextShadow.make_context(self.space , w_method, w_receiver, + w_new_frame = shadow.MethodContextShadow.make_context(self.space, s_method, w_receiver, arguments, w_sender=w_aContext, pc=self.startpc(), closure=self) return w_new_frame From noreply at buildbot.pypy.org Sat Feb 23 14:14:57 2013 From: noreply at buildbot.pypy.org (fijal) Date: Sat, 23 Feb 2013 14:14:57 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: oops Message-ID: <20130223131457.1EC1F1C0327@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61667:897c6c46467a Date: 2013-02-23 15:14 +0200 http://bitbucket.org/pypy/pypy/changeset/897c6c46467a/ Log: oops diff --git a/rpython/jit/backend/llsupport/llmodel.py b/rpython/jit/backend/llsupport/llmodel.py --- a/rpython/jit/backend/llsupport/llmodel.py +++ b/rpython/jit/backend/llsupport/llmodel.py @@ -99,6 +99,7 @@ return lltype.cast_opaque_ptr(llmemory.GCREF, new_frame) except Exception, e: print "Unhandled exception", e, "in realloc_frame" + return lltype.nullptr(llmemory.GCREF.TO) if not translate_support_code: fptr = llhelper(FUNC_TP, realloc_frame) From noreply at buildbot.pypy.org Sat Feb 23 14:21:42 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Sat, 23 Feb 2013 14:21:42 +0100 (CET) Subject: [pypy-commit] pypy rpython-doc: Add build dir to .hgignore. Message-ID: <20130223132142.82DEE1C482D@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: rpython-doc Changeset: r61668:3dbb6fbf38dc Date: 2013-02-23 12:53 +0100 http://bitbucket.org/pypy/pypy/changeset/3dbb6fbf38dc/ Log: Add build dir to .hgignore. diff --git a/.hgignore b/.hgignore --- a/.hgignore +++ b/.hgignore @@ -81,6 +81,7 @@ ^pypy/doc/image/lattice3\.png$ ^pypy/doc/image/stackless_informal\.png$ ^pypy/doc/image/parsing_example.+\.png$ +^rpython/doc/_build/.*$ ^pypy/module/test_lib_pypy/ctypes_tests/_ctypes_test\.o$ ^compiled ^.git/ From noreply at buildbot.pypy.org Sat Feb 23 14:21:43 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Sat, 23 Feb 2013 14:21:43 +0100 (CET) Subject: [pypy-commit] pypy rpython-doc: Move some .rst files into the new directory. Message-ID: <20130223132143.DF7621C482D@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: rpython-doc Changeset: r61669:65282b96edcd Date: 2013-02-23 13:44 +0100 http://bitbucket.org/pypy/pypy/changeset/65282b96edcd/ Log: Move some .rst files into the new directory. diff --git a/pypy/doc/cli-backend.rst b/rpython/doc/cli-backend.rst rename from pypy/doc/cli-backend.rst rename to rpython/doc/cli-backend.rst diff --git a/pypy/doc/dot-net.rst b/rpython/doc/dot-net.rst rename from pypy/doc/dot-net.rst rename to rpython/doc/dot-net.rst diff --git a/pypy/doc/garbage_collection.rst b/rpython/doc/garbage_collection.rst rename from pypy/doc/garbage_collection.rst rename to rpython/doc/garbage_collection.rst diff --git a/pypy/doc/rffi.rst b/rpython/doc/rffi.rst rename from pypy/doc/rffi.rst rename to rpython/doc/rffi.rst diff --git a/pypy/doc/rlib.rst b/rpython/doc/rlib.rst rename from pypy/doc/rlib.rst rename to rpython/doc/rlib.rst diff --git a/pypy/doc/rtyper.rst b/rpython/doc/rtyper.rst rename from pypy/doc/rtyper.rst rename to rpython/doc/rtyper.rst diff --git a/pypy/doc/translation.rst b/rpython/doc/translation.rst rename from pypy/doc/translation.rst rename to rpython/doc/translation.rst diff --git a/pypy/doc/windows.rst b/rpython/doc/windows.rst rename from pypy/doc/windows.rst rename to rpython/doc/windows.rst From noreply at buildbot.pypy.org Sat Feb 23 14:38:28 2013 From: noreply at buildbot.pypy.org (cpher) Date: Sat, 23 Feb 2013 14:38:28 +0100 (CET) Subject: [pypy-commit] pypy default: Use the correct path after the split Message-ID: <20130223133828.5BC6B1C0327@cobra.cs.uni-duesseldorf.de> Author: Christopher Pope Branch: Changeset: r61670:c6c3dda18101 Date: 2013-02-22 21:05 -0500 http://bitbucket.org/pypy/pypy/changeset/c6c3dda18101/ Log: Use the correct path after the split diff --git a/pypy/doc/getting-started-dev.rst b/pypy/doc/getting-started-dev.rst --- a/pypy/doc/getting-started-dev.rst +++ b/pypy/doc/getting-started-dev.rst @@ -20,7 +20,7 @@ To start the interactive translator shell do:: - cd pypy + cd rpython python bin/translatorshell.py Test snippets of translatable code are provided in the file From noreply at buildbot.pypy.org Sat Feb 23 14:38:29 2013 From: noreply at buildbot.pypy.org (cpher) Date: Sat, 23 Feb 2013 14:38:29 +0100 (CET) Subject: [pypy-commit] pypy default: Call the translator RPython, not PyPy Message-ID: <20130223133829.959AE1C0327@cobra.cs.uni-duesseldorf.de> Author: Christopher Pope Branch: Changeset: r61671:aabe989738c2 Date: 2013-02-22 21:16 -0500 http://bitbucket.org/pypy/pypy/changeset/aabe989738c2/ Log: Call the translator RPython, not PyPy diff --git a/pypy/doc/faq.rst b/pypy/doc/faq.rst --- a/pypy/doc/faq.rst +++ b/pypy/doc/faq.rst @@ -202,20 +202,20 @@ Be sure to enable it again if you need it! -The PyPy translation tool chain -=============================== +The RPython translation tool chain +=================================== ---------------------------------------------- -Can PyPy compile normal Python programs to C? ---------------------------------------------- +------------------------------------------------ +Can RPython compile normal Python programs to C? +------------------------------------------------ -No, PyPy is not a Python compiler. +No, RPython is not a Python compiler. In Python, it is mostly impossible to *prove* anything about the types that a program will manipulate by doing a static analysis. It should be clear if you are familiar with Python, but if in doubt see [BRETT]_. -If you want a fast Python program, please use our JIT_ instead. +If you want a fast Python program, please use the PyPy JIT_ instead. .. _JIT: jit/index.html From noreply at buildbot.pypy.org Sat Feb 23 14:38:30 2013 From: noreply at buildbot.pypy.org (cpher) Date: Sat, 23 Feb 2013 14:38:30 +0100 (CET) Subject: [pypy-commit] pypy default: Fixes for grammar Message-ID: <20130223133830.BEBEC1C0327@cobra.cs.uni-duesseldorf.de> Author: Christopher Pope Branch: Changeset: r61672:7091022dc2f3 Date: 2013-02-22 21:29 -0500 http://bitbucket.org/pypy/pypy/changeset/7091022dc2f3/ Log: Fixes for grammar diff --git a/pypy/doc/faq.rst b/pypy/doc/faq.rst --- a/pypy/doc/faq.rst +++ b/pypy/doc/faq.rst @@ -300,8 +300,8 @@ Do I have to rewrite my programs in RPython? -------------------------------------------- -No. And you shouldn't try. First and foremost, RPython is a language -that is designed to write interpreters in. It is a restricted subset of +No, and you shouldn't try. First and foremost, RPython is a language +designed for writing interpreters. It is a restricted subset of Python. If you program is not an interpreter but tries to do "real things", like use *any* part of the standard Python library or *any* 3rd-party library, then it is not RPython to start with. You should @@ -381,8 +381,8 @@ No, you have to rebuild the entire interpreter. This means two things: -* It is imperative to use test-driven development. You have to test - exhaustively your module in pure Python, before even attempting to +* It is imperative to use test-driven development. You have to exhaustively + test your module in pure Python, before even attempting to translate it. Once you translate it, you should have only a few typing issues left to fix, but otherwise the result should work out of the box. From noreply at buildbot.pypy.org Sat Feb 23 14:38:31 2013 From: noreply at buildbot.pypy.org (cpher) Date: Sat, 23 Feb 2013 14:38:31 +0100 (CET) Subject: [pypy-commit] pypy default: Grammar, kill a spurious space Message-ID: <20130223133831.DD2561C0327@cobra.cs.uni-duesseldorf.de> Author: Christopher Pope Branch: Changeset: r61673:644e270d4638 Date: 2013-02-22 21:58 -0500 http://bitbucket.org/pypy/pypy/changeset/644e270d4638/ Log: Grammar, kill a spurious space diff --git a/pypy/doc/cpython_differences.rst b/pypy/doc/cpython_differences.rst --- a/pypy/doc/cpython_differences.rst +++ b/pypy/doc/cpython_differences.rst @@ -134,7 +134,7 @@ ``ReferenceError`` at any place that uses them. (Or, better yet, don't use ``weakref.proxy()`` at all; use ``weakref.ref()``.) -There are a few extra implications for the difference in the GC. Most +There are a few extra implications from the difference in the GC. Most notably, if an object has a ``__del__``, the ``__del__`` is never called more than once in PyPy; but CPython will call the same ``__del__`` several times if the object is resurrected and dies again. The ``__del__`` methods are @@ -156,7 +156,7 @@ .. __: http://bugs.pypy.org/issue736 -Using the default GC called ``minimark``, the built-in function ``id()`` +Using the default GC (called ``minimark``), the built-in function ``id()`` works like it does in CPython. With other GCs it returns numbers that are not real addresses (because an object can move around several times) and calling it a lot can lead to performance problem. @@ -286,7 +286,7 @@ ------------- * Hash randomization (``-R``) is ignored in PyPy. As documented in - http://bugs.python.org/issue14621 , some of us believe it has no + http://bugs.python.org/issue14621, some of us believe it has no purpose in CPython either. * ``sys.setrecursionlimit(n)`` sets the limit only approximately, From noreply at buildbot.pypy.org Sat Feb 23 14:38:33 2013 From: noreply at buildbot.pypy.org (cpher) Date: Sat, 23 Feb 2013 14:38:33 +0100 (CET) Subject: [pypy-commit] pypy default: Un-mangle this sentence Message-ID: <20130223133833.14E181C0327@cobra.cs.uni-duesseldorf.de> Author: Christopher Pope Branch: Changeset: r61674:aad55cecd55f Date: 2013-02-22 22:05 -0500 http://bitbucket.org/pypy/pypy/changeset/aad55cecd55f/ Log: Un-mangle this sentence diff --git a/pypy/doc/interpreter.rst b/pypy/doc/interpreter.rst --- a/pypy/doc/interpreter.rst +++ b/pypy/doc/interpreter.rst @@ -38,8 +38,8 @@ calling its ``frame.eval()`` method. This main entry point initialize appropriate namespaces and then interprets each bytecode instruction. Python's standard library contains -the `lib-python/2.7/dis.py`_ module which allows to view -the Virtual's machine bytecode instructions:: +the `lib-python/2.7/dis.py`_ module which allows to inspection +of the virtual machine's bytecode instructions:: >>> import dis >>> def f(x): From noreply at buildbot.pypy.org Sat Feb 23 14:38:34 2013 From: noreply at buildbot.pypy.org (cpher) Date: Sat, 23 Feb 2013 14:38:34 +0100 (CET) Subject: [pypy-commit] pypy default: Fix grammar Message-ID: <20130223133834.3B3D71C0327@cobra.cs.uni-duesseldorf.de> Author: Christopher Pope Branch: Changeset: r61675:f87c2b620472 Date: 2013-02-22 22:10 -0500 http://bitbucket.org/pypy/pypy/changeset/f87c2b620472/ Log: Fix grammar diff --git a/pypy/doc/interpreter.rst b/pypy/doc/interpreter.rst --- a/pypy/doc/interpreter.rst +++ b/pypy/doc/interpreter.rst @@ -25,7 +25,7 @@ compact bytecode format as CPython 2.7, with minor differences in the bytecode set. Our bytecode compiler is implemented as a chain of flexible passes (tokenizer, lexer, parser, -abstract syntax tree builder, bytecode generator). The latter passes +abstract syntax tree builder and bytecode generator). The latter passes are based on the ``compiler`` package from the standard library of CPython, with various improvements and bug fixes. The bytecode compiler (living under `pypy/interpreter/astcompiler/`_) is now integrated and is @@ -50,10 +50,10 @@ 6 BINARY_ADD 7 RETURN_VALUE -CPython as well as PyPy are stack-based virtual machines, i.e. -they don't have registers but put object to and pull objects +CPython and PyPy are stack-based virtual machines, i.e. +they don't have registers but instead push object to and pull objects from a stack. The bytecode interpreter is only responsible -for implementing control flow and putting and pulling black +for implementing control flow and pushing and pulling black box objects to and from this value stack. The bytecode interpreter does not know how to perform operations on those black box (`wrapped`_) objects for which it delegates to the `object @@ -75,8 +75,8 @@ on ``OperationErrors``. The interpreter implementation offers mechanisms to allow a -caller to be unaware if a particular function invocation leads -to bytecode interpretation or is executed directly at +caller to be unaware of whether a particular function invocation +leads to bytecode interpretation or is executed directly at interpreter-level. The two basic kinds of `Gateway classes`_ expose either an interpreter-level function to application-level execution (``interp2app``) or allow From noreply at buildbot.pypy.org Sat Feb 23 14:38:35 2013 From: noreply at buildbot.pypy.org (fijal) Date: Sat, 23 Feb 2013 14:38:35 +0100 (CET) Subject: [pypy-commit] pypy default: Merged in cpher/pypy (pull request #128) Message-ID: <20130223133835.5D67B1C0327@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r61676:572046a663a0 Date: 2013-02-23 15:38 +0200 http://bitbucket.org/pypy/pypy/changeset/572046a663a0/ Log: Merged in cpher/pypy (pull request #128) Minor doc fixes diff --git a/pypy/doc/cpython_differences.rst b/pypy/doc/cpython_differences.rst --- a/pypy/doc/cpython_differences.rst +++ b/pypy/doc/cpython_differences.rst @@ -134,7 +134,7 @@ ``ReferenceError`` at any place that uses them. (Or, better yet, don't use ``weakref.proxy()`` at all; use ``weakref.ref()``.) -There are a few extra implications for the difference in the GC. Most +There are a few extra implications from the difference in the GC. Most notably, if an object has a ``__del__``, the ``__del__`` is never called more than once in PyPy; but CPython will call the same ``__del__`` several times if the object is resurrected and dies again. The ``__del__`` methods are @@ -156,7 +156,7 @@ .. __: http://bugs.pypy.org/issue736 -Using the default GC called ``minimark``, the built-in function ``id()`` +Using the default GC (called ``minimark``), the built-in function ``id()`` works like it does in CPython. With other GCs it returns numbers that are not real addresses (because an object can move around several times) and calling it a lot can lead to performance problem. @@ -286,7 +286,7 @@ ------------- * Hash randomization (``-R``) is ignored in PyPy. As documented in - http://bugs.python.org/issue14621 , some of us believe it has no + http://bugs.python.org/issue14621, some of us believe it has no purpose in CPython either. * ``sys.setrecursionlimit(n)`` sets the limit only approximately, diff --git a/pypy/doc/faq.rst b/pypy/doc/faq.rst --- a/pypy/doc/faq.rst +++ b/pypy/doc/faq.rst @@ -202,20 +202,20 @@ Be sure to enable it again if you need it! -The PyPy translation tool chain -=============================== +The RPython translation tool chain +=================================== ---------------------------------------------- -Can PyPy compile normal Python programs to C? ---------------------------------------------- +------------------------------------------------ +Can RPython compile normal Python programs to C? +------------------------------------------------ -No, PyPy is not a Python compiler. +No, RPython is not a Python compiler. In Python, it is mostly impossible to *prove* anything about the types that a program will manipulate by doing a static analysis. It should be clear if you are familiar with Python, but if in doubt see [BRETT]_. -If you want a fast Python program, please use our JIT_ instead. +If you want a fast Python program, please use the PyPy JIT_ instead. .. _JIT: jit/index.html @@ -300,8 +300,8 @@ Do I have to rewrite my programs in RPython? -------------------------------------------- -No. And you shouldn't try. First and foremost, RPython is a language -that is designed to write interpreters in. It is a restricted subset of +No, and you shouldn't try. First and foremost, RPython is a language +designed for writing interpreters. It is a restricted subset of Python. If you program is not an interpreter but tries to do "real things", like use *any* part of the standard Python library or *any* 3rd-party library, then it is not RPython to start with. You should @@ -381,8 +381,8 @@ No, you have to rebuild the entire interpreter. This means two things: -* It is imperative to use test-driven development. You have to test - exhaustively your module in pure Python, before even attempting to +* It is imperative to use test-driven development. You have to exhaustively + test your module in pure Python, before even attempting to translate it. Once you translate it, you should have only a few typing issues left to fix, but otherwise the result should work out of the box. diff --git a/pypy/doc/getting-started-dev.rst b/pypy/doc/getting-started-dev.rst --- a/pypy/doc/getting-started-dev.rst +++ b/pypy/doc/getting-started-dev.rst @@ -20,7 +20,7 @@ To start the interactive translator shell do:: - cd pypy + cd rpython python bin/translatorshell.py Test snippets of translatable code are provided in the file diff --git a/pypy/doc/interpreter.rst b/pypy/doc/interpreter.rst --- a/pypy/doc/interpreter.rst +++ b/pypy/doc/interpreter.rst @@ -25,7 +25,7 @@ compact bytecode format as CPython 2.7, with minor differences in the bytecode set. Our bytecode compiler is implemented as a chain of flexible passes (tokenizer, lexer, parser, -abstract syntax tree builder, bytecode generator). The latter passes +abstract syntax tree builder and bytecode generator). The latter passes are based on the ``compiler`` package from the standard library of CPython, with various improvements and bug fixes. The bytecode compiler (living under `pypy/interpreter/astcompiler/`_) is now integrated and is @@ -38,8 +38,8 @@ calling its ``frame.eval()`` method. This main entry point initialize appropriate namespaces and then interprets each bytecode instruction. Python's standard library contains -the `lib-python/2.7/dis.py`_ module which allows to view -the Virtual's machine bytecode instructions:: +the `lib-python/2.7/dis.py`_ module which allows to inspection +of the virtual machine's bytecode instructions:: >>> import dis >>> def f(x): @@ -50,10 +50,10 @@ 6 BINARY_ADD 7 RETURN_VALUE -CPython as well as PyPy are stack-based virtual machines, i.e. -they don't have registers but put object to and pull objects +CPython and PyPy are stack-based virtual machines, i.e. +they don't have registers but instead push object to and pull objects from a stack. The bytecode interpreter is only responsible -for implementing control flow and putting and pulling black +for implementing control flow and pushing and pulling black box objects to and from this value stack. The bytecode interpreter does not know how to perform operations on those black box (`wrapped`_) objects for which it delegates to the `object @@ -75,8 +75,8 @@ on ``OperationErrors``. The interpreter implementation offers mechanisms to allow a -caller to be unaware if a particular function invocation leads -to bytecode interpretation or is executed directly at +caller to be unaware of whether a particular function invocation +leads to bytecode interpretation or is executed directly at interpreter-level. The two basic kinds of `Gateway classes`_ expose either an interpreter-level function to application-level execution (``interp2app``) or allow From noreply at buildbot.pypy.org Sat Feb 23 14:52:03 2013 From: noreply at buildbot.pypy.org (fijal) Date: Sat, 23 Feb 2013 14:52:03 +0100 (CET) Subject: [pypy-commit] pypy default: resurrect bpnn for docs purposes Message-ID: <20130223135203.7F34B1C0327@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r61677:c415462480c9 Date: 2013-02-23 15:35 +0200 http://bitbucket.org/pypy/pypy/changeset/c415462480c9/ Log: resurrect bpnn for docs purposes diff --git a/rpython/translator/goal/bpnn.py b/rpython/translator/goal/bpnn.py new file mode 100644 --- /dev/null +++ b/rpython/translator/goal/bpnn.py @@ -0,0 +1,214 @@ +#!/usr/bin/env python +""" + Translator Demo + + To analyse and type-annotate the functions and class defined in + this module, starting from the entry point function demo(), + use the following command line: + + ../pypy/translator/goal/translate.py bpnn.py + + Insert '--help' before 'bpnn.py' for a list of translation options, + or see the Overview of Command Line Options for translation at + http://codespeak.net/pypy/dist/pypy/doc/config/commandline.html +""" +# Back-Propagation Neural Networks +# +# Written in Python. See http://www.python.org/ +# +# Neil Schemenauer +# +# Modifications to the original (Armin Rigo): +# * import random from PyPy's lib, which is Python 2.2's plain +# Python implementation +# * print a doc about how to start the Translator + +import sys +import math +import time + +import autopath +from rpython.rlib import rrandom + +PRINT_IT = True + +random = rrandom.Random(1) + +# calculate a random number where: a <= rand < b +def rand(a, b): + return (b-a)*random.random() + a + +# Make a matrix (we could use NumPy to speed this up) +def makeMatrix(I, J, fill=0.0): + m = [] + for i in range(I): + m.append([fill]*J) + return m + +class NN: + + def __init__(self, ni, nh, no): + # number of input, hidden, and output nodes + self.ni = ni + 1 # +1 for bias node + self.nh = nh + self.no = no + + # activations for nodes + self.ai = [1.0]*self.ni + self.ah = [1.0]*self.nh + self.ao = [1.0]*self.no + + # create weights + self.wi = makeMatrix(self.ni, self.nh) + self.wo = makeMatrix(self.nh, self.no) + # set them to random vaules + for i in range(self.ni): + for j in range(self.nh): + self.wi[i][j] = rand(-2.0, 2.0) + for j in range(self.nh): + for k in range(self.no): + self.wo[j][k] = rand(-2.0, 2.0) + + # last change in weights for momentum + self.ci = makeMatrix(self.ni, self.nh) + self.co = makeMatrix(self.nh, self.no) + + def update(self, inputs): + if len(inputs) != self.ni-1: + raise ValueError, 'wrong number of inputs' + + # input activations + for i in range(self.ni-1): + #self.ai[i] = 1.0/(1.0+math.exp(-inputs[i])) + self.ai[i] = inputs[i] + + # hidden activations + for j in range(self.nh): + sum = 0.0 + for i in range(self.ni): + sum = sum + self.ai[i] * self.wi[i][j] + self.ah[j] = 1.0/(1.0+math.exp(-sum)) + + # output activations + for k in range(self.no): + sum = 0.0 + for j in range(self.nh): + sum = sum + self.ah[j] * self.wo[j][k] + self.ao[k] = 1.0/(1.0+math.exp(-sum)) + + return self.ao[:] + + + def backPropagate(self, targets, N, M): + if len(targets) != self.no: + raise ValueError, 'wrong number of target values' + + # calculate error terms for output + output_deltas = [0.0] * self.no + for k in range(self.no): + ao = self.ao[k] + output_deltas[k] = ao*(1-ao)*(targets[k]-ao) + + # calculate error terms for hidden + hidden_deltas = [0.0] * self.nh + for j in range(self.nh): + sum = 0.0 + for k in range(self.no): + sum = sum + output_deltas[k]*self.wo[j][k] + hidden_deltas[j] = self.ah[j]*(1-self.ah[j])*sum + + # update output weights + for j in range(self.nh): + for k in range(self.no): + change = output_deltas[k]*self.ah[j] + self.wo[j][k] = self.wo[j][k] + N*change + M*self.co[j][k] + self.co[j][k] = change + #print N*change, M*self.co[j][k] + + # update input weights + for i in range(self.ni): + for j in range(self.nh): + change = hidden_deltas[j]*self.ai[i] + self.wi[i][j] = self.wi[i][j] + N*change + M*self.ci[i][j] + self.ci[i][j] = change + + # calculate error + error = 0.0 + for k in range(len(targets)): + delta = targets[k]-self.ao[k] + error = error + 0.5*delta*delta + return error + + + def test(self, patterns): + for p in patterns: + if PRINT_IT: + print p[0], '->', self.update(p[0]) + + def weights(self): + if PRINT_IT: + print 'Input weights:' + for i in range(self.ni): + print self.wi[i] + print + print 'Output weights:' + for j in range(self.nh): + print self.wo[j] + + def train(self, patterns, iterations=2000, N=0.5, M=0.1): + # N: learning rate + # M: momentum factor + for i in xrange(iterations): + error = 0.0 + for p in patterns: + inputs = p[0] + targets = p[1] + self.update(inputs) + error = error + self.backPropagate(targets, N, M) + if PRINT_IT and i % 100 == 0: + print 'error', error + + +def demo(): + # Teach network XOR function + pat = [ + [[0,0], [0]], + [[0,1], [1]], + [[1,0], [1]], + [[1,1], [0]] + ] + + # create a network with two input, two hidden, and two output nodes + n = NN(2, 3, 1) + # train it with some patterns + n.train(pat, 2000) + # test it + n.test(pat) + + +# __________ Entry point for stand-alone builds __________ + +import time + +def entry_point(argv): + if len(argv) > 1: + N = int(argv[1]) + else: + N = 200 + T = time.time() + for i in range(N): + demo() + t1 = time.time() - T + print "%d iterations, %s milliseconds per iteration" % (N, 1000.0*t1/N) + return 0 + +# _____ Define and setup target ___ + +def target(*args): + return entry_point, None + +if __name__ == '__main__': + if len(sys.argv) == 1: + sys.argv.append('1') + entry_point(sys.argv) + print __doc__ From noreply at buildbot.pypy.org Sat Feb 23 14:52:05 2013 From: noreply at buildbot.pypy.org (fijal) Date: Sat, 23 Feb 2013 14:52:05 +0100 (CET) Subject: [pypy-commit] pypy default: merge Message-ID: <20130223135205.221D61C0327@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r61678:b1fac3c02e27 Date: 2013-02-23 15:51 +0200 http://bitbucket.org/pypy/pypy/changeset/b1fac3c02e27/ Log: merge diff too long, truncating to 2000 out of 3032 lines diff --git a/lib_pypy/numpypy/__init__.py b/lib_pypy/numpypy/__init__.py --- a/lib_pypy/numpypy/__init__.py +++ b/lib_pypy/numpypy/__init__.py @@ -1,8 +1,14 @@ -from _numpypy import * -from .core import * -import _numpypy +import core +from core import * +import lib +from lib import * -__all__ = _numpypy.__all__ +from __builtin__ import bool, int, long, float, complex, object, unicode, str +from core import abs, max, min + +__all__ = [] +__all__ += core.__all__ +__all__ += lib.__all__ import sys sys.modules.setdefault('numpy', sys.modules['numpypy']) diff --git a/lib_pypy/numpypy/core/__init__.py b/lib_pypy/numpypy/core/__init__.py --- a/lib_pypy/numpypy/core/__init__.py +++ b/lib_pypy/numpypy/core/__init__.py @@ -1,5 +1,18 @@ -from .fromnumeric import * -from .numeric import * -from .shape_base import * +import _numpypy +from _numpypy import * +import numeric +from numeric import * +import fromnumeric +from fromnumeric import * +import shape_base +from shape_base import * +import multiarray -from _numpypy import abs, max, min +from fromnumeric import amax as max, amin as min +from _numpypy import absolute as abs + +__all__ = [] +__all__ += _numpypy.__all__ +__all__ += numeric.__all__ +__all__ += fromnumeric.__all__ +__all__ += shape_base.__all__ diff --git a/lib_pypy/numpypy/core/fromnumeric.py b/lib_pypy/numpypy/core/fromnumeric.py --- a/lib_pypy/numpypy/core/fromnumeric.py +++ b/lib_pypy/numpypy/core/fromnumeric.py @@ -1290,7 +1290,9 @@ array([3, 4, 2, 3, 4, 5, 6, 7, 8, 8]) """ - raise NotImplementedError('Waiting on interp level method') + if not hasattr(a, 'clip'): + a = numpypy.array(a) + return a.clip(a_min, a_max, out=out) def sum(a, axis=None, dtype=None, out=None): @@ -1360,10 +1362,9 @@ """ assert dtype is None - assert out is None if not hasattr(a, "sum"): a = numpypy.array(a) - return a.sum(axis=axis) + return a.sum(axis=axis, out=out) def product (a, axis=None, dtype=None, out=None): @@ -1720,11 +1721,11 @@ 4.0 """ - assert axis is None - assert out is None if not hasattr(a, "max"): a = numpypy.array(a) - return a.max() + if a.size < 1: + return numpypy.array([]) + return a.max(axis=axis, out=out) def amin(a, axis=None, out=None): @@ -1782,12 +1783,11 @@ 0.0 """ - # amin() is equivalent to min() - assert axis is None - assert out is None if not hasattr(a, 'min'): a = numpypy.array(a) - return a.min() + if a.size < 1: + return numpypy.array([]) + return a.min(axis=axis, out=out) def alen(a): """ diff --git a/lib_pypy/numpypy/core/multiarray.py b/lib_pypy/numpypy/core/multiarray.py new file mode 100644 --- /dev/null +++ b/lib_pypy/numpypy/core/multiarray.py @@ -0,0 +1,1 @@ +from _numpypy import set_string_function, typeinfo diff --git a/lib_pypy/numpypy/core/numeric.py b/lib_pypy/numpypy/core/numeric.py --- a/lib_pypy/numpypy/core/numeric.py +++ b/lib_pypy/numpypy/core/numeric.py @@ -1,10 +1,13 @@ +__all__ = ['asanyarray', 'base_repr', + 'array_repr', 'array_str', 'set_string_function', + 'array_equal', 'asarray', 'outer', 'identity'] from _numpypy import array, ndarray, int_, float_, bool_, flexible #, complex_# , longlong from _numpypy import concatenate from .fromnumeric import any import math import sys -import _numpypy as multiarray # ARGH +import multiarray from numpypy.core.arrayprint import array2string newaxis = None @@ -501,3 +504,34 @@ a = asarray(a) b = asarray(b) return a.ravel()[:,newaxis]*b.ravel()[newaxis,:] + +def identity(n, dtype=None): + """ + Return the identity array. + + The identity array is a square array with ones on + the main diagonal. + + Parameters + ---------- + n : int + Number of rows (and columns) in `n` x `n` output. + dtype : data-type, optional + Data-type of the output. Defaults to ``float``. + + Returns + ------- + out : ndarray + `n` x `n` array with its main diagonal set to one, + and all other elements 0. + + Examples + -------- + >>> np.identity(3) + array([[ 1., 0., 0.], + [ 0., 1., 0.], + [ 0., 0., 1.]]) + + """ + from numpy import eye + return eye(n, dtype=dtype) diff --git a/lib_pypy/numpypy/core/shape_base.py b/lib_pypy/numpypy/core/shape_base.py --- a/lib_pypy/numpypy/core/shape_base.py +++ b/lib_pypy/numpypy/core/shape_base.py @@ -1,3 +1,5 @@ +__all__ = ['atleast_1d', 'atleast_2d', 'atleast_3d', 'vstack', 'hstack'] + import _numpypy from numeric import array, asanyarray, newaxis @@ -271,53 +273,3 @@ return _numpypy.concatenate(arrs, 0) else: return _numpypy.concatenate(arrs, 1) - -def dstack(tup): - """ - Stack arrays in sequence depth wise (along third axis). - - Takes a sequence of arrays and stack them along the third axis - to make a single array. Rebuilds arrays divided by `dsplit`. - This is a simple way to stack 2D arrays (images) into a single - 3D array for processing. - - Parameters - ---------- - tup : sequence of arrays - Arrays to stack. All of them must have the same shape along all - but the third axis. - - Returns - ------- - stacked : ndarray - The array formed by stacking the given arrays. - - See Also - -------- - vstack : Stack along first axis. - hstack : Stack along second axis. - concatenate : Join arrays. - dsplit : Split array along third axis. - - Notes - ----- - Equivalent to ``np.concatenate(tup, axis=2)``. - - Examples - -------- - >>> a = np.array((1,2,3)) - >>> b = np.array((2,3,4)) - >>> np.dstack((a,b)) - array([[[1, 2], - [2, 3], - [3, 4]]]) - - >>> a = np.array([[1],[2],[3]]) - >>> b = np.array([[2],[3],[4]]) - >>> np.dstack((a,b)) - array([[[1, 2]], - [[2, 3]], - [[3, 4]]]) - - """ - return _numpypy.concatenate(map(atleast_3d,tup),2) diff --git a/lib_pypy/numpypy/lib/__init__.py b/lib_pypy/numpypy/lib/__init__.py new file mode 100644 --- /dev/null +++ b/lib_pypy/numpypy/lib/__init__.py @@ -0,0 +1,11 @@ +import function_base +from function_base import * +import shape_base +from shape_base import * +import twodim_base +from twodim_base import * + +__all__ = [] +__all__ += function_base.__all__ +__all__ += shape_base.__all__ +__all__ += twodim_base.__all__ diff --git a/lib_pypy/numpypy/lib/function_base.py b/lib_pypy/numpypy/lib/function_base.py new file mode 100644 --- /dev/null +++ b/lib_pypy/numpypy/lib/function_base.py @@ -0,0 +1,10 @@ +__all__ = ['average'] + +from _numpypy import array + +def average(a): + # This implements a weighted average, for now we don't implement the + # weighting, just the average part! + if not hasattr(a, "mean"): + a = array(a) + return a.mean() diff --git a/lib_pypy/numpypy/lib/shape_base.py b/lib_pypy/numpypy/lib/shape_base.py new file mode 100644 --- /dev/null +++ b/lib_pypy/numpypy/lib/shape_base.py @@ -0,0 +1,54 @@ +__all__ = ['dstack'] + +import numpypy.core.numeric as _nx +from numpypy.core import atleast_3d + +def dstack(tup): + """ + Stack arrays in sequence depth wise (along third axis). + + Takes a sequence of arrays and stack them along the third axis + to make a single array. Rebuilds arrays divided by `dsplit`. + This is a simple way to stack 2D arrays (images) into a single + 3D array for processing. + + Parameters + ---------- + tup : sequence of arrays + Arrays to stack. All of them must have the same shape along all + but the third axis. + + Returns + ------- + stacked : ndarray + The array formed by stacking the given arrays. + + See Also + -------- + vstack : Stack along first axis. + hstack : Stack along second axis. + concatenate : Join arrays. + dsplit : Split array along third axis. + + Notes + ----- + Equivalent to ``np.concatenate(tup, axis=2)``. + + Examples + -------- + >>> a = np.array((1,2,3)) + >>> b = np.array((2,3,4)) + >>> np.dstack((a,b)) + array([[[1, 2], + [2, 3], + [3, 4]]]) + + >>> a = np.array([[1],[2],[3]]) + >>> b = np.array([[2],[3],[4]]) + >>> np.dstack((a,b)) + array([[[1, 2]], + [[2, 3]], + [[3, 4]]]) + + """ + return _nx.concatenate(map(atleast_3d,tup),2) diff --git a/lib_pypy/numpypy/lib/twodim_base.py b/lib_pypy/numpypy/lib/twodim_base.py new file mode 100644 --- /dev/null +++ b/lib_pypy/numpypy/lib/twodim_base.py @@ -0,0 +1,54 @@ +__all__ = ['eye'] + +from _numpypy import zeros + +def eye(N, M=None, k=0, dtype=float): + """ + Return a 2-D array with ones on the diagonal and zeros elsewhere. + + Parameters + ---------- + N : int + Number of rows in the output. + M : int, optional + Number of columns in the output. If None, defaults to `N`. + k : int, optional + Index of the diagonal: 0 (the default) refers to the main diagonal, + a positive value refers to an upper diagonal, and a negative value + to a lower diagonal. + dtype : data-type, optional + Data-type of the returned array. + + Returns + ------- + I : ndarray of shape (N,M) + An array where all elements are equal to zero, except for the `k`-th + diagonal, whose values are equal to one. + + See Also + -------- + identity : (almost) equivalent function + diag : diagonal 2-D array from a 1-D array specified by the user. + + Examples + -------- + >>> np.eye(2, dtype=int) + array([[1, 0], + [0, 1]]) + >>> np.eye(3, k=1) + array([[ 0., 1., 0.], + [ 0., 0., 1.], + [ 0., 0., 0.]]) + + """ + if M is None: + M = N + m = zeros((N, M), dtype=dtype) + if k >= M: + return m + if k >= 0: + i = k + else: + i = (-k) * M + m[:M-k].flat[i::M+1] = 1 + return m diff --git a/pypy/doc/cpython_differences.rst b/pypy/doc/cpython_differences.rst --- a/pypy/doc/cpython_differences.rst +++ b/pypy/doc/cpython_differences.rst @@ -134,7 +134,7 @@ ``ReferenceError`` at any place that uses them. (Or, better yet, don't use ``weakref.proxy()`` at all; use ``weakref.ref()``.) -There are a few extra implications for the difference in the GC. Most +There are a few extra implications from the difference in the GC. Most notably, if an object has a ``__del__``, the ``__del__`` is never called more than once in PyPy; but CPython will call the same ``__del__`` several times if the object is resurrected and dies again. The ``__del__`` methods are @@ -156,7 +156,7 @@ .. __: http://bugs.pypy.org/issue736 -Using the default GC called ``minimark``, the built-in function ``id()`` +Using the default GC (called ``minimark``), the built-in function ``id()`` works like it does in CPython. With other GCs it returns numbers that are not real addresses (because an object can move around several times) and calling it a lot can lead to performance problem. @@ -286,7 +286,7 @@ ------------- * Hash randomization (``-R``) is ignored in PyPy. As documented in - http://bugs.python.org/issue14621 , some of us believe it has no + http://bugs.python.org/issue14621, some of us believe it has no purpose in CPython either. * ``sys.setrecursionlimit(n)`` sets the limit only approximately, diff --git a/pypy/doc/faq.rst b/pypy/doc/faq.rst --- a/pypy/doc/faq.rst +++ b/pypy/doc/faq.rst @@ -202,20 +202,20 @@ Be sure to enable it again if you need it! -The PyPy translation tool chain -=============================== +The RPython translation tool chain +=================================== ---------------------------------------------- -Can PyPy compile normal Python programs to C? ---------------------------------------------- +------------------------------------------------ +Can RPython compile normal Python programs to C? +------------------------------------------------ -No, PyPy is not a Python compiler. +No, RPython is not a Python compiler. In Python, it is mostly impossible to *prove* anything about the types that a program will manipulate by doing a static analysis. It should be clear if you are familiar with Python, but if in doubt see [BRETT]_. -If you want a fast Python program, please use our JIT_ instead. +If you want a fast Python program, please use the PyPy JIT_ instead. .. _JIT: jit/index.html @@ -300,8 +300,8 @@ Do I have to rewrite my programs in RPython? -------------------------------------------- -No. And you shouldn't try. First and foremost, RPython is a language -that is designed to write interpreters in. It is a restricted subset of +No, and you shouldn't try. First and foremost, RPython is a language +designed for writing interpreters. It is a restricted subset of Python. If you program is not an interpreter but tries to do "real things", like use *any* part of the standard Python library or *any* 3rd-party library, then it is not RPython to start with. You should @@ -381,8 +381,8 @@ No, you have to rebuild the entire interpreter. This means two things: -* It is imperative to use test-driven development. You have to test - exhaustively your module in pure Python, before even attempting to +* It is imperative to use test-driven development. You have to exhaustively + test your module in pure Python, before even attempting to translate it. Once you translate it, you should have only a few typing issues left to fix, but otherwise the result should work out of the box. diff --git a/pypy/doc/garbage_collection.rst b/pypy/doc/garbage_collection.rst --- a/pypy/doc/garbage_collection.rst +++ b/pypy/doc/garbage_collection.rst @@ -42,7 +42,7 @@ Two arenas of equal size, with only one arena in use and getting filled with new objects. When the arena is full, the live objects are copied into the other arena using Cheney's algorithm. The old arena is then -cleared. See `rpython/rtyper/memory/gc/semispace.py`_. +cleared. See `rpython/memory/gc/semispace.py`_. On Unix the clearing is done by reading ``/dev/zero`` into the arena, which is extremely memory efficient at least on Linux: it lets the @@ -55,7 +55,7 @@ Generational GC --------------- -This is a two-generations GC. See `rpython/rtyper/memory/gc/generation.py`_. +This is a two-generations GC. See `rpython/memory/gc/generation.py`_. It is implemented as a subclass of the Semispace copying collector. It adds a nursery, which is a chunk of the current semispace. Its size is @@ -86,7 +86,7 @@ Each generation is collected much less often than the previous one. The division of the generations is slightly more complicated than just nursery / semispace / external; see the diagram at the start of the -source code, in `rpython/rtyper/memory/gc/hybrid.py`_. +source code, in `rpython/memory/gc/hybrid.py`_. Mark & Compact GC ----------------- @@ -161,7 +161,7 @@ to the old stage. The dying case 2 objects are immediately freed. - The old stage is an area of memory containing old (small) objects. It - is handled by `rpython/rtyper/memory/gc/minimarkpage.py`_. It is organized + is handled by `rpython/memory/gc/minimarkpage.py`_. It is organized as "arenas" of 256KB or 512KB, subdivided into "pages" of 4KB or 8KB. Each page can either be free, or contain small objects of all the same size. Furthermore at any point in time each object location can be diff --git a/pypy/doc/getting-started-dev.rst b/pypy/doc/getting-started-dev.rst --- a/pypy/doc/getting-started-dev.rst +++ b/pypy/doc/getting-started-dev.rst @@ -20,7 +20,7 @@ To start the interactive translator shell do:: - cd pypy + cd rpython python bin/translatorshell.py Test snippets of translatable code are provided in the file diff --git a/pypy/doc/index.rst b/pypy/doc/index.rst --- a/pypy/doc/index.rst +++ b/pypy/doc/index.rst @@ -286,7 +286,7 @@ `rpython/rtyper/ootypesystem/`_ the `object-oriented type system`_ for OO backends -`rpython/rtyper/memory/`_ the `garbage collector`_ construction +`rpython/memory/`_ the `garbage collector`_ construction framework `rpython/translator/`_ translation_ backends and support code diff --git a/pypy/doc/interpreter.rst b/pypy/doc/interpreter.rst --- a/pypy/doc/interpreter.rst +++ b/pypy/doc/interpreter.rst @@ -25,7 +25,7 @@ compact bytecode format as CPython 2.7, with minor differences in the bytecode set. Our bytecode compiler is implemented as a chain of flexible passes (tokenizer, lexer, parser, -abstract syntax tree builder, bytecode generator). The latter passes +abstract syntax tree builder and bytecode generator). The latter passes are based on the ``compiler`` package from the standard library of CPython, with various improvements and bug fixes. The bytecode compiler (living under `pypy/interpreter/astcompiler/`_) is now integrated and is @@ -38,8 +38,8 @@ calling its ``frame.eval()`` method. This main entry point initialize appropriate namespaces and then interprets each bytecode instruction. Python's standard library contains -the `lib-python/2.7/dis.py`_ module which allows to view -the Virtual's machine bytecode instructions:: +the `lib-python/2.7/dis.py`_ module which allows to inspection +of the virtual machine's bytecode instructions:: >>> import dis >>> def f(x): @@ -50,10 +50,10 @@ 6 BINARY_ADD 7 RETURN_VALUE -CPython as well as PyPy are stack-based virtual machines, i.e. -they don't have registers but put object to and pull objects +CPython and PyPy are stack-based virtual machines, i.e. +they don't have registers but instead push object to and pull objects from a stack. The bytecode interpreter is only responsible -for implementing control flow and putting and pulling black +for implementing control flow and pushing and pulling black box objects to and from this value stack. The bytecode interpreter does not know how to perform operations on those black box (`wrapped`_) objects for which it delegates to the `object @@ -75,8 +75,8 @@ on ``OperationErrors``. The interpreter implementation offers mechanisms to allow a -caller to be unaware if a particular function invocation leads -to bytecode interpretation or is executed directly at +caller to be unaware of whether a particular function invocation +leads to bytecode interpretation or is executed directly at interpreter-level. The two basic kinds of `Gateway classes`_ expose either an interpreter-level function to application-level execution (``interp2app``) or allow diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst --- a/pypy/doc/whatsnew-head.rst +++ b/pypy/doc/whatsnew-head.rst @@ -68,6 +68,7 @@ .. branch: coding-guide-update-rlib-refs .. branch: rlib-doc-rpython-refs +.. branch: clean-up-remaining-pypy-rlib-refs .. branch: enumerate-rstr Support enumerate() over rstr types. diff --git a/pypy/module/_cffi_backend/cbuffer.py b/pypy/module/_cffi_backend/cbuffer.py --- a/pypy/module/_cffi_backend/cbuffer.py +++ b/pypy/module/_cffi_backend/cbuffer.py @@ -1,10 +1,11 @@ -from pypy.interpreter.error import operationerrfmt from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.buffer import RWBuffer +from pypy.interpreter.error import operationerrfmt from pypy.interpreter.gateway import unwrap_spec, interp2app from pypy.interpreter.typedef import TypeDef, make_weakref_descr +from pypy.module._cffi_backend import cdataobj, ctypeptr, ctypearray + from rpython.rtyper.lltypesystem import rffi -from pypy.module._cffi_backend import cdataobj, ctypeptr, ctypearray class LLBuffer(RWBuffer): diff --git a/pypy/module/_cffi_backend/ccallback.py b/pypy/module/_cffi_backend/ccallback.py --- a/pypy/module/_cffi_backend/ccallback.py +++ b/pypy/module/_cffi_backend/ccallback.py @@ -2,18 +2,17 @@ Callbacks. """ import os + +from rpython.rlib import clibffi, rweakref, jit +from rpython.rlib.objectmodel import compute_unique_id, keepalive_until_here +from rpython.rtyper.lltypesystem import lltype, rffi + from pypy.interpreter.error import OperationError, operationerrfmt -from rpython.rtyper.lltypesystem import lltype, llmemory, rffi -from rpython.rlib.objectmodel import compute_unique_id, keepalive_until_here -from rpython.rlib import clibffi, rweakref -from rpython.rlib import jit - +from pypy.module._cffi_backend import cerrno, misc from pypy.module._cffi_backend.cdataobj import W_CData -from pypy.module._cffi_backend.ctypefunc import SIZE_OF_FFI_ARG, BIG_ENDIAN -from pypy.module._cffi_backend.ctypefunc import W_CTypeFunc +from pypy.module._cffi_backend.ctypefunc import SIZE_OF_FFI_ARG, BIG_ENDIAN, W_CTypeFunc from pypy.module._cffi_backend.ctypeprim import W_CTypePrimitiveSigned from pypy.module._cffi_backend.ctypevoid import W_CTypeVoid -from pypy.module._cffi_backend import cerrno, misc # ____________________________________________________________ @@ -152,6 +151,7 @@ STDERR = 2 + @jit.jit_callback("CFFI") def invoke_callback(ffi_cif, ll_res, ll_args, ll_userdata): """ Callback specification. diff --git a/pypy/module/_cffi_backend/cdataobj.py b/pypy/module/_cffi_backend/cdataobj.py --- a/pypy/module/_cffi_backend/cdataobj.py +++ b/pypy/module/_cffi_backend/cdataobj.py @@ -1,11 +1,13 @@ import operator + +from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.error import OperationError, operationerrfmt -from pypy.interpreter.baseobjspace import Wrappable -from pypy.interpreter.gateway import interp2app, unwrap_spec +from pypy.interpreter.gateway import interp2app from pypy.interpreter.typedef import TypeDef, make_weakref_descr + +from rpython.rlib import objectmodel, rgc +from rpython.rlib.objectmodel import keepalive_until_here, specialize from rpython.rtyper.lltypesystem import lltype, rffi -from rpython.rlib.objectmodel import keepalive_until_here, specialize -from rpython.rlib import objectmodel, rgc from rpython.tool.sourcetools import func_with_new_name from pypy.module._cffi_backend import misc diff --git a/pypy/module/_cffi_backend/cerrno.py b/pypy/module/_cffi_backend/cerrno.py --- a/pypy/module/_cffi_backend/cerrno.py +++ b/pypy/module/_cffi_backend/cerrno.py @@ -1,5 +1,7 @@ import sys + from rpython.rlib import rposix + from pypy.interpreter.executioncontext import ExecutionContext from pypy.interpreter.gateway import unwrap_spec diff --git a/pypy/module/_cffi_backend/ctypearray.py b/pypy/module/_cffi_backend/ctypearray.py --- a/pypy/module/_cffi_backend/ctypearray.py +++ b/pypy/module/_cffi_backend/ctypearray.py @@ -2,18 +2,17 @@ Arrays. """ +from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.error import OperationError, operationerrfmt -from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.gateway import interp2app from pypy.interpreter.typedef import TypeDef + from rpython.rtyper.lltypesystem import rffi from rpython.rlib.objectmodel import keepalive_until_here from rpython.rlib.rarithmetic import ovfcheck -from pypy.module._cffi_backend.ctypeprim import W_CTypePrimitiveChar -from pypy.module._cffi_backend.ctypeprim import W_CTypePrimitiveUniChar +from pypy.module._cffi_backend import cdataobj from pypy.module._cffi_backend.ctypeptr import W_CTypePtrOrArray -from pypy.module._cffi_backend import cdataobj class W_CTypeArray(W_CTypePtrOrArray): diff --git a/pypy/module/_cffi_backend/ctypeenum.py b/pypy/module/_cffi_backend/ctypeenum.py --- a/pypy/module/_cffi_backend/ctypeenum.py +++ b/pypy/module/_cffi_backend/ctypeenum.py @@ -2,15 +2,11 @@ Enums. """ -from pypy.interpreter.error import OperationError, operationerrfmt -from rpython.rtyper.lltypesystem import rffi -from rpython.rlib.rarithmetic import intmask, r_ulonglong from rpython.rlib.objectmodel import keepalive_until_here -from rpython.rlib.objectmodel import specialize -from pypy.module._cffi_backend.ctypeprim import W_CTypePrimitiveSigned -from pypy.module._cffi_backend.ctypeprim import W_CTypePrimitiveUnsigned from pypy.module._cffi_backend import misc +from pypy.module._cffi_backend.ctypeprim import (W_CTypePrimitiveSigned, + W_CTypePrimitiveUnsigned) class _Mixin_Enum(object): diff --git a/pypy/module/_cffi_backend/ctypefunc.py b/pypy/module/_cffi_backend/ctypefunc.py --- a/pypy/module/_cffi_backend/ctypefunc.py +++ b/pypy/module/_cffi_backend/ctypefunc.py @@ -4,25 +4,21 @@ import sys from pypy.interpreter.error import OperationError, operationerrfmt + +from rpython.rlib import jit, clibffi, jit_libffi +from rpython.rlib.jit_libffi import (CIF_DESCRIPTION, CIF_DESCRIPTION_P, + FFI_TYPE, FFI_TYPE_P, FFI_TYPE_PP, SIZE_OF_FFI_ARG) +from rpython.rlib.objectmodel import we_are_translated, instantiate from rpython.rtyper.lltypesystem import lltype, llmemory, rffi -from rpython.rlib import jit, clibffi, jit_libffi -from rpython.rlib.jit_libffi import CIF_DESCRIPTION, CIF_DESCRIPTION_P -from rpython.rlib.jit_libffi import FFI_TYPE, FFI_TYPE_P, FFI_TYPE_PP -from rpython.rlib.jit_libffi import SIZE_OF_FFI_ARG -from rpython.rlib.objectmodel import we_are_translated, instantiate -from rpython.rlib.objectmodel import keepalive_until_here +from pypy.module._cffi_backend import ctypearray, cdataobj, cerrno from pypy.module._cffi_backend.ctypeobj import W_CType from pypy.module._cffi_backend.ctypeptr import W_CTypePtrBase, W_CTypePointer from pypy.module._cffi_backend.ctypevoid import W_CTypeVoid from pypy.module._cffi_backend.ctypestruct import W_CTypeStruct -from pypy.module._cffi_backend.ctypestruct import W_CTypeStructOrUnion -from pypy.module._cffi_backend.ctypeprim import W_CTypePrimitiveSigned -from pypy.module._cffi_backend.ctypeprim import W_CTypePrimitiveUnsigned -from pypy.module._cffi_backend.ctypeprim import W_CTypePrimitiveCharOrUniChar -from pypy.module._cffi_backend.ctypeprim import W_CTypePrimitiveFloat -from pypy.module._cffi_backend.ctypeprim import W_CTypePrimitiveLongDouble -from pypy.module._cffi_backend import ctypearray, cdataobj, cerrno +from pypy.module._cffi_backend.ctypeprim import (W_CTypePrimitiveSigned, + W_CTypePrimitiveUnsigned, W_CTypePrimitiveCharOrUniChar, + W_CTypePrimitiveFloat, W_CTypePrimitiveLongDouble) class W_CTypeFunc(W_CTypePtrBase): @@ -97,7 +93,6 @@ return self.space.wrap(clibffi.FFI_DEFAULT_ABI) # XXX return W_CTypePtrBase._fget(self, attrchar) - def call(self, funcaddr, args_w): if self.cif_descr: # regular case: this function does not take '...' arguments @@ -270,7 +265,6 @@ self.bufferp = rffi.ptradd(result, size) return result - def fb_fill_type(self, ctype, is_result_type): return ctype._get_ffi_type(self, is_result_type) @@ -357,7 +351,6 @@ return ffistruct - def fb_build(self): # Build a CIF_DESCRIPTION. Actually this computes the size and # allocates a larger amount of data. It starts with a @@ -387,7 +380,6 @@ if self.atypes: self.atypes[i] = atype - def align_arg(self, n): return (n + 7) & ~7 diff --git a/pypy/module/_cffi_backend/ctypeobj.py b/pypy/module/_cffi_backend/ctypeobj.py --- a/pypy/module/_cffi_backend/ctypeobj.py +++ b/pypy/module/_cffi_backend/ctypeobj.py @@ -1,9 +1,8 @@ +from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.error import OperationError, operationerrfmt -from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.gateway import interp2app -from pypy.interpreter.typedef import TypeDef -from pypy.interpreter.typedef import make_weakref_descr -from pypy.interpreter.typedef import GetSetProperty, interp_attrproperty +from pypy.interpreter.typedef import TypeDef, make_weakref_descr, GetSetProperty + from rpython.rtyper.lltypesystem import lltype, llmemory, rffi from rpython.rlib.objectmodel import we_are_translated diff --git a/pypy/module/_cffi_backend/ctypeprim.py b/pypy/module/_cffi_backend/ctypeprim.py --- a/pypy/module/_cffi_backend/ctypeprim.py +++ b/pypy/module/_cffi_backend/ctypeprim.py @@ -3,13 +3,14 @@ """ from pypy.interpreter.error import operationerrfmt -from rpython.rtyper.lltypesystem import lltype, rffi + from rpython.rlib.rarithmetic import r_uint, r_ulonglong, intmask from rpython.rlib.objectmodel import keepalive_until_here from rpython.rlib import jit +from rpython.rtyper.lltypesystem import lltype, rffi +from pypy.module._cffi_backend import cdataobj, misc from pypy.module._cffi_backend.ctypeobj import W_CType -from pypy.module._cffi_backend import cdataobj, misc class W_CTypePrimitive(W_CType): diff --git a/pypy/module/_cffi_backend/ctypeptr.py b/pypy/module/_cffi_backend/ctypeptr.py --- a/pypy/module/_cffi_backend/ctypeptr.py +++ b/pypy/module/_cffi_backend/ctypeptr.py @@ -2,15 +2,15 @@ Pointers. """ -from pypy.interpreter.error import OperationError, operationerrfmt -from pypy.interpreter.error import wrap_oserror -from rpython.rtyper.lltypesystem import lltype, rffi +from pypy.interpreter.error import OperationError, operationerrfmt, wrap_oserror + +from rpython.rlib import rposix from rpython.rlib.objectmodel import keepalive_until_here from rpython.rlib.rarithmetic import ovfcheck -from rpython.rlib import rposix +from rpython.rtyper.lltypesystem import lltype, rffi +from pypy.module._cffi_backend import cdataobj, misc, ctypeprim, ctypevoid from pypy.module._cffi_backend.ctypeobj import W_CType -from pypy.module._cffi_backend import cdataobj, misc, ctypeprim, ctypevoid class W_CTypePtrOrArray(W_CType): @@ -336,19 +336,22 @@ rffi_fdopen = rffi.llexternal("fdopen", [rffi.INT, rffi.CCHARP], rffi.CCHARP) -rffi_setbuf = rffi.llexternal("setbuf", [rffi.CCHARP,rffi.CCHARP], lltype.Void) +rffi_setbuf = rffi.llexternal("setbuf", [rffi.CCHARP, rffi.CCHARP], lltype.Void) rffi_fclose = rffi.llexternal("fclose", [rffi.CCHARP], rffi.INT) class CffiFileObj(object): _immutable_ = True + def __init__(self, fd, mode): self.llf = rffi_fdopen(fd, mode) if not self.llf: raise OSError(rposix.get_errno(), "fdopen failed") rffi_setbuf(self.llf, lltype.nullptr(rffi.CCHARP.TO)) + def close(self): rffi_fclose(self.llf) + def prepare_file_argument(space, fileobj): fileobj.direct_flush() if fileobj.cffi_fileobj is None: diff --git a/pypy/module/_cffi_backend/ctypestruct.py b/pypy/module/_cffi_backend/ctypestruct.py --- a/pypy/module/_cffi_backend/ctypestruct.py +++ b/pypy/module/_cffi_backend/ctypestruct.py @@ -3,15 +3,16 @@ """ from pypy.interpreter.error import OperationError, operationerrfmt -from rpython.rtyper.lltypesystem import lltype, rffi from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.typedef import TypeDef, interp_attrproperty + +from rpython.rlib import jit from rpython.rlib.objectmodel import keepalive_until_here from rpython.rlib.rarithmetic import r_uint, r_ulonglong, r_longlong, intmask -from rpython.rlib import jit +from rpython.rtyper.lltypesystem import rffi +from pypy.module._cffi_backend import cdataobj, ctypeprim, misc from pypy.module._cffi_backend.ctypeobj import W_CType -from pypy.module._cffi_backend import cdataobj, ctypeprim, misc class W_CTypeStructOrUnion(W_CType): @@ -141,6 +142,7 @@ class W_CTypeStruct(W_CTypeStructOrUnion): kind = "struct" + class W_CTypeUnion(W_CTypeStructOrUnion): kind = "union" @@ -241,8 +243,8 @@ # value = misc.as_long_long(space, w_ob) if isinstance(ctype, ctypeprim.W_CTypePrimitiveSigned): - fmin = -(r_longlong(1) << (self.bitsize-1)) - fmax = (r_longlong(1) << (self.bitsize-1)) - 1 + fmin = -(r_longlong(1) << (self.bitsize - 1)) + fmax = (r_longlong(1) << (self.bitsize - 1)) - 1 if fmax == 0: fmax = 1 # special case to let "int x:1" receive "1" else: diff --git a/pypy/module/_cffi_backend/libraryobj.py b/pypy/module/_cffi_backend/libraryobj.py --- a/pypy/module/_cffi_backend/libraryobj.py +++ b/pypy/module/_cffi_backend/libraryobj.py @@ -1,9 +1,11 @@ from __future__ import with_statement -from pypy.interpreter.error import OperationError, operationerrfmt + from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.error import operationerrfmt from pypy.interpreter.gateway import interp2app, unwrap_spec from pypy.interpreter.typedef import TypeDef -from rpython.rtyper.lltypesystem import lltype, rffi + +from rpython.rtyper.lltypesystem import rffi from rpython.rlib.rdynload import DLLHANDLE, dlopen, dlsym, dlclose, DLOpenError from pypy.module._cffi_backend.cdataobj import W_CData diff --git a/pypy/module/_cffi_backend/misc.py b/pypy/module/_cffi_backend/misc.py --- a/pypy/module/_cffi_backend/misc.py +++ b/pypy/module/_cffi_backend/misc.py @@ -1,10 +1,12 @@ from __future__ import with_statement -from pypy.interpreter.error import OperationError, operationerrfmt -from rpython.rtyper.lltypesystem import lltype, llmemory, rffi + +from pypy.interpreter.error import OperationError + +from rpython.rlib import jit +from rpython.rlib.objectmodel import keepalive_until_here, specialize from rpython.rlib.rarithmetic import r_uint, r_ulonglong, is_signed_integer_type from rpython.rlib.unroll import unrolling_iterable -from rpython.rlib.objectmodel import keepalive_until_here, specialize -from rpython.rlib import jit +from rpython.rtyper.lltypesystem import lltype, llmemory, rffi from rpython.translator.tool.cbuild import ExternalCompilationInfo # ____________________________________________________________ @@ -43,14 +45,14 @@ def read_raw_unsigned_data(target, size): for TP, TPP in _prim_unsigned_types: if size == rffi.sizeof(TP): - return rffi.cast(lltype.UnsignedLongLong, rffi.cast(TPP,target)[0]) + return rffi.cast(lltype.UnsignedLongLong, rffi.cast(TPP, target)[0]) raise NotImplementedError("bad integer size") def read_raw_ulong_data(target, size): for TP, TPP in _prim_unsigned_types: if size == rffi.sizeof(TP): assert rffi.sizeof(TP) <= rffi.sizeof(lltype.Unsigned) - return rffi.cast(lltype.Unsigned, rffi.cast(TPP,target)[0]) + return rffi.cast(lltype.Unsigned, rffi.cast(TPP, target)[0]) raise NotImplementedError("bad integer size") def read_raw_float_data(target, size): diff --git a/pypy/module/_cffi_backend/newtype.py b/pypy/module/_cffi_backend/newtype.py --- a/pypy/module/_cffi_backend/newtype.py +++ b/pypy/module/_cffi_backend/newtype.py @@ -1,12 +1,12 @@ from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.gateway import unwrap_spec + +from rpython.rlib.objectmodel import specialize +from rpython.rlib.rarithmetic import ovfcheck from rpython.rtyper.lltypesystem import lltype, rffi -from rpython.rlib.rarithmetic import ovfcheck, r_uint, intmask -from rpython.rlib.rarithmetic import most_neg_value_of, most_pos_value_of -from rpython.rlib.objectmodel import specialize -from pypy.module._cffi_backend import ctypeobj, ctypeprim, ctypeptr, ctypearray -from pypy.module._cffi_backend import ctypestruct, ctypevoid, ctypeenum +from pypy.module._cffi_backend import (ctypeobj, ctypeprim, ctypeptr, + ctypearray, ctypestruct, ctypevoid, ctypeenum) @specialize.memo() @@ -167,7 +167,7 @@ # if foffset < 0: # align this field to its own 'falign' by inserting padding - offset = (offset + falign - 1) & ~(falign-1) + offset = (offset + falign - 1) & ~(falign - 1) else: # a forced field position: ignore the offset just computed, # except to know if we must set 'custom_field_pos' @@ -178,7 +178,7 @@ fbitsize == 8 * ftype.size and not isinstance(ftype, ctypeprim.W_CTypePrimitiveCharOrUniChar)): fbitsize = -1 - if isinstance(ftype, ctypearray.W_CTypeArray) and ftype.length==0: + if isinstance(ftype, ctypearray.W_CTypeArray) and ftype.length == 0: bitshift = ctypestruct.W_CField.BS_EMPTY_ARRAY else: bitshift = ctypestruct.W_CField.BS_REGULAR @@ -241,7 +241,7 @@ # as 1 instead. But for ctypes support, we allow the manually- # specified totalsize to be zero in this case. if totalsize < 0: - offset = (offset + alignment - 1) & ~(alignment-1) + offset = (offset + alignment - 1) & ~(alignment - 1) totalsize = offset or 1 elif totalsize < offset: raise operationerrfmt(space.w_TypeError, diff --git a/pypy/module/_io/interp_fileio.py b/pypy/module/_io/interp_fileio.py --- a/pypy/module/_io/interp_fileio.py +++ b/pypy/module/_io/interp_fileio.py @@ -3,7 +3,6 @@ from pypy.interpreter.error import OperationError, wrap_oserror, wrap_oserror2 from rpython.rlib.rarithmetic import r_longlong from rpython.rlib.rstring import StringBuilder -from rpython.rlib.rposix import validate_fd from os import O_RDONLY, O_WRONLY, O_RDWR, O_CREAT, O_TRUNC import sys, os, stat, errno from pypy.module._io.interp_iobase import W_RawIOBase, convert_size @@ -154,7 +153,6 @@ fd_is_own = False try: if fd >= 0: - validate_fd(fd) try: os.fstat(fd) except OSError, e: @@ -235,7 +233,6 @@ self.fd = -1 try: - validate_fd(fd) os.close(fd) except OSError, e: raise wrap_oserror(space, e, diff --git a/pypy/module/micronumpy/__init__.py b/pypy/module/micronumpy/__init__.py --- a/pypy/module/micronumpy/__init__.py +++ b/pypy/module/micronumpy/__init__.py @@ -27,9 +27,6 @@ 'True_': 'types.Bool.True', 'False_': 'types.Bool.False', - 'bool': 'space.w_bool', - 'int': 'space.w_int', - 'typeinfo': 'interp_dtype.get_dtype_cache(space).w_typeinfo', 'generic': 'interp_boxes.W_GenericBox', @@ -82,7 +79,6 @@ # ufuncs for exposed, impl in [ - ("abs", "absolute"), ("absolute", "absolute"), ("add", "add"), ("arccos", "arccos"), @@ -163,26 +159,16 @@ interpleveldefs[exposed] = "interp_ufuncs.get(space).%s" % impl appleveldefs = { - 'average': 'app_numpy.average', - 'sum': 'app_numpy.sum', - 'min': 'app_numpy.min', - 'identity': 'app_numpy.identity', - 'eye': 'app_numpy.eye', - 'max': 'app_numpy.max', 'arange': 'app_numpy.arange', } def setup_after_space_initialization(self): space = self.space - alllist = sorted(Module.interpleveldefs.keys() + \ + all_list = sorted(Module.interpleveldefs.keys() + \ Module.appleveldefs.keys()) # found by set(numpypy.__all__) - set(numpy.__all__) - alllist.remove('min') - alllist.remove('max') - alllist.remove('bool') - alllist.remove('int') - alllist.remove('abs') - alllist.remove('typeinfo') - w_all = space.wrap(alllist) + all_list.remove('set_string_function') + all_list.remove('typeinfo') + w_all = space.wrap(all_list) space.setitem(self.w_dict, space.new_interned_str('__all__'), w_all) if long_double_size == 16: diff --git a/pypy/module/micronumpy/app_numpy.py b/pypy/module/micronumpy/app_numpy.py --- a/pypy/module/micronumpy/app_numpy.py +++ b/pypy/module/micronumpy/app_numpy.py @@ -2,82 +2,6 @@ import _numpypy -def average(a): - # This implements a weighted average, for now we don't implement the - # weighting, just the average part! - if not hasattr(a, "mean"): - a = _numpypy.array(a) - return a.mean() - -def identity(n, dtype=None): - a = _numpypy.zeros((n, n), dtype=dtype) - for i in range(n): - a[i][i] = 1 - return a - -def eye(n, m=None, k=0, dtype=None): - if m is None: - m = n - a = _numpypy.zeros((n, m), dtype=dtype) - ni = 0 - mi = 0 - - if k < 0: - p = n + k - ni = -k - else: - p = n - k - mi = k - - while ni < n and mi < m: - a[ni][mi] = 1 - ni += 1 - mi += 1 - return a - -def sum(a,axis=None, out=None): - '''sum(a, axis=None) - Sum of array elements over a given axis. - - Parameters - ---------- - a : array_like - Elements to sum. - axis : integer, optional - Axis over which the sum is taken. By default `axis` is None, - and all elements are summed. - - Returns - ------- - sum_along_axis : ndarray - An array with the same shape as `a`, with the specified - axis removed. If `a` is a 0-d array, or if `axis` is None, a scalar - is returned. If an output array is specified, a reference to - `out` is returned. - - See Also - -------- - ndarray.sum : Equivalent method. - ''' - # TODO: add to doc (once it's implemented): cumsum : Cumulative sum of array elements. - if not hasattr(a, "sum"): - a = _numpypy.array(a) - return a.sum(axis=axis, out=out) - -def min(a, axis=None, out=None): - if not hasattr(a, "min"): - a = _numpypy.array(a) - if a.size < 1: - return _numpypy.array([]) - return a.min(axis=axis, out=out) - -def max(a, axis=None, out=None): - if not hasattr(a, "max"): - a = _numpypy.array(a) - if a.size < 1: - return _numpypy.array([]) - return a.max(axis=axis, out=out) - def arange(start, stop=None, step=1, dtype=None): '''arange([start], stop[, step], dtype=None) Generate values in the half-interval [start, stop). diff --git a/pypy/module/micronumpy/interp_numarray.py b/pypy/module/micronumpy/interp_numarray.py --- a/pypy/module/micronumpy/interp_numarray.py +++ b/pypy/module/micronumpy/interp_numarray.py @@ -453,13 +453,17 @@ @unwrap_spec(mode=str) def descr_choose(self, space, w_choices, mode='raise', w_out=None): - if w_out is not None and not isinstance(w_out, W_NDimArray): + if space.is_none(w_out): + w_out = None + elif not isinstance(w_out, W_NDimArray): raise OperationError(space.w_TypeError, space.wrap( "return arrays must be of ArrayType")) return interp_arrayops.choose(space, self, w_choices, w_out, mode) def descr_clip(self, space, w_min, w_max, w_out=None): - if w_out is not None and not isinstance(w_out, W_NDimArray): + if space.is_none(w_out): + w_out = None + elif not isinstance(w_out, W_NDimArray): raise OperationError(space.w_TypeError, space.wrap( "return arrays must be of ArrayType")) min = convert_to_array(space, w_min) diff --git a/pypy/module/micronumpy/test/test_arrayops.py b/pypy/module/micronumpy/test/test_arrayops.py --- a/pypy/module/micronumpy/test/test_arrayops.py +++ b/pypy/module/micronumpy/test/test_arrayops.py @@ -99,10 +99,13 @@ def test_choose_out(self): from _numpypy import array a, b, c = array([1, 2, 3]), [4, 5, 6], 13 + r = array([2, 1, 0]).choose([a, b, c], out=None) + assert (r == [13, 5, 3]).all() + assert (a == [1, 2, 3]).all() r = array([2, 1, 0]).choose([a, b, c], out=a) assert (r == [13, 5, 3]).all() assert (a == [13, 5, 3]).all() - + def test_choose_modes(self): from _numpypy import array a, b, c = array([1, 2, 3]), [4, 5, 6], 13 diff --git a/pypy/module/micronumpy/test/test_complex.py b/pypy/module/micronumpy/test/test_complex.py --- a/pypy/module/micronumpy/test/test_complex.py +++ b/pypy/module/micronumpy/test/test_complex.py @@ -382,7 +382,7 @@ def test_conjugate(self): from _numpypy import conj, conjugate, complex128, complex64 - import _numpypy as np + import numpypy as np c0 = complex128(complex(2.5, 0)) c1 = complex64(complex(1, 2)) @@ -495,8 +495,8 @@ def test_basic(self): from _numpypy import (complex128, complex64, add, array, dtype, - subtract as sub, multiply, divide, negative, abs, floor_divide, - real, imag, sign, clongfloat) + subtract as sub, multiply, divide, negative, absolute as abs, + floor_divide, real, imag, sign, clongfloat) from _numpypy import (equal, not_equal, greater, greater_equal, less, less_equal, isnan) assert real(4.0) == 4.0 diff --git a/pypy/module/micronumpy/test/test_dtypes.py b/pypy/module/micronumpy/test/test_dtypes.py --- a/pypy/module/micronumpy/test/test_dtypes.py +++ b/pypy/module/micronumpy/test/test_dtypes.py @@ -638,9 +638,6 @@ def test_various_types(self): import _numpypy as numpy - assert numpy.bool is bool - assert numpy.int is int - assert numpy.int16 is numpy.short assert numpy.int8 is numpy.byte assert numpy.bool_ is numpy.bool8 diff --git a/pypy/module/micronumpy/test/test_module.py b/pypy/module/micronumpy/test/test_module.py deleted file mode 100644 --- a/pypy/module/micronumpy/test/test_module.py +++ /dev/null @@ -1,25 +0,0 @@ -from pypy.module.micronumpy.test.test_base import BaseNumpyAppTest - - -class AppTestNumPyModule(BaseNumpyAppTest): - def test_average(self): - from _numpypy import array, average - assert average(range(10)) == 4.5 - assert average(array(range(10))) == 4.5 - - def test_sum(self): - from _numpypy import array, sum - assert sum(range(10)) == 45 - assert sum(array(range(10))) == 45 - - def test_min(self): - from _numpypy import array, min, zeros - assert min(range(10)) == 0 - assert min(array(range(10))) == 0 - assert list(min(zeros((0, 2)), axis=1)) == [] - - def test_max(self): - from _numpypy import array, max, zeros - assert max(range(10)) == 9 - assert max(array(range(10))) == 9 - assert list(max(zeros((0, 2)), axis=1)) == [] diff --git a/pypy/module/micronumpy/test/test_numarray.py b/pypy/module/micronumpy/test/test_numarray.py --- a/pypy/module/micronumpy/test/test_numarray.py +++ b/pypy/module/micronumpy/test/test_numarray.py @@ -1141,7 +1141,7 @@ assert (a.mean(1) == [0.5, 2.5, 4.5, 6.5, 8.5]).all() def test_sum(self): - from _numpypy import array + from _numpypy import array, zeros a = array(range(5)) assert a.sum() == 10 assert a[:4].sum() == 6 @@ -1156,6 +1156,8 @@ assert b == d assert b is d + assert list(zeros((0, 2)).sum(axis=1)) == [] + def test_reduce_nd(self): from numpypy import arange, array, multiply a = arange(15).reshape(5, 3) @@ -1186,55 +1188,6 @@ assert (array([[1,2],[3,4]]).prod(0) == [3, 8]).all() assert (array([[1,2],[3,4]]).prod(1) == [2, 12]).all() - def test_identity(self): - from _numpypy import identity, array - from _numpypy import int32, float64, dtype - a = identity(0) - assert len(a) == 0 - assert a.dtype == dtype('float64') - assert a.shape == (0, 0) - b = identity(1, dtype=int32) - assert len(b) == 1 - assert b[0][0] == 1 - assert b.shape == (1, 1) - assert b.dtype == dtype('int32') - c = identity(2) - assert c.shape == (2, 2) - assert (c == [[1, 0], [0, 1]]).all() - d = identity(3, dtype='int32') - assert d.shape == (3, 3) - assert d.dtype == dtype('int32') - assert (d == [[1, 0, 0], [0, 1, 0], [0, 0, 1]]).all() - - def test_eye(self): - from _numpypy import eye - from _numpypy import int32, dtype - a = eye(0) - assert len(a) == 0 - assert a.dtype == dtype('float64') - assert a.shape == (0, 0) - b = eye(1, dtype=int32) - assert len(b) == 1 - assert b[0][0] == 1 - assert b.shape == (1, 1) - assert b.dtype == dtype('int32') - c = eye(2) - assert c.shape == (2, 2) - assert (c == [[1, 0], [0, 1]]).all() - d = eye(3, dtype='int32') - assert d.shape == (3, 3) - assert d.dtype == dtype('int32') - assert (d == [[1, 0, 0], [0, 1, 0], [0, 0, 1]]).all() - e = eye(3, 4) - assert e.shape == (3, 4) - assert (e == [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0]]).all() - f = eye(2, 4, k=3) - assert f.shape == (2, 4) - assert (f == [[0, 0, 0, 1], [0, 0, 0, 0]]).all() - g = eye(3, 4, k=-1) - assert g.shape == (3, 4) - assert (g == [[0, 0, 0, 0], [1, 0, 0, 0], [0, 1, 0, 0]]).all() - def test_prod(self): from _numpypy import array a = array(range(1, 6)) @@ -1242,24 +1195,28 @@ assert a[:4].prod() == 24.0 def test_max(self): - from _numpypy import array + from _numpypy import array, zeros a = array([-1.2, 3.4, 5.7, -3.0, 2.7]) assert a.max() == 5.7 b = array([]) raises(ValueError, "b.max()") + assert list(zeros((0, 2)).max(axis=1)) == [] + def test_max_add(self): from _numpypy import array a = array([-1.2, 3.4, 5.7, -3.0, 2.7]) assert (a + a).max() == 11.4 def test_min(self): - from _numpypy import array + from _numpypy import array, zeros a = array([-1.2, 3.4, 5.7, -3.0, 2.7]) assert a.min() == -3.0 b = array([]) raises(ValueError, "b.min()") + assert list(zeros((0, 2)).min(axis=1)) == [] + def test_argmax(self): from _numpypy import array a = array([-1.2, 3.4, 5.7, -3.0, 2.7]) @@ -1748,7 +1705,8 @@ from _numpypy import array a = array([1, 2, 17, -3, 12]) assert (a.clip(-2, 13) == [1, 2, 13, -2, 12]).all() - assert (a.clip(-1, 1) == [1, 1, 1, -1, 1]).all() + assert (a.clip(-1, 1, out=None) == [1, 1, 1, -1, 1]).all() + assert (a == [1, 2, 17, -3, 12]).all() assert (a.clip(-1, [1, 2, 3, 4, 5]) == [1, 2, 3, -1, 5]).all() assert (a.clip(-2, 13, out=a) == [1, 2, 13, -2, 12]).all() assert (a == [1, 2, 13, -2, 12]).all() diff --git a/pypy/module/micronumpy/test/test_outarg.py b/pypy/module/micronumpy/test/test_outarg.py --- a/pypy/module/micronumpy/test/test_outarg.py +++ b/pypy/module/micronumpy/test/test_outarg.py @@ -83,22 +83,9 @@ b = add(10, 10, out=out) assert b==out assert b.dtype == out.dtype - - def test_applevel(self): - from _numpypy import array, sum, max, min - a = array([[1, 2], [3, 4]]) - out = array([[0, 0], [0, 0]]) - c = sum(a, axis=0, out=out[0]) - assert (c == [4, 6]).all() - assert (c == out[0]).all() - assert (c != out[1]).all() - c = max(a, axis=1, out=out[0]) - assert (c == [2, 4]).all() - assert (c == out[0]).all() - assert (c != out[1]).all() - + def test_ufunc_cast(self): - from _numpypy import array, negative, add, sum + from _numpypy import array, negative, add a = array(16, dtype = int) c = array(0, dtype = float) b = negative(a, out=c) @@ -106,7 +93,7 @@ b = add(a, a, out=c) assert b == c d = array([16, 16], dtype=int) - b = sum(d, out=c) + b = d.sum(out=c) assert b == c #cast_error = raises(TypeError, negative, c, a) #assert str(cast_error.value) == \ diff --git a/pypy/module/test_lib_pypy/numpypy/core/test_fromnumeric.py b/pypy/module/test_lib_pypy/numpypy/core/test_fromnumeric.py --- a/pypy/module/test_lib_pypy/numpypy/core/test_fromnumeric.py +++ b/pypy/module/test_lib_pypy/numpypy/core/test_fromnumeric.py @@ -34,9 +34,23 @@ # a = array([(1, 2), (3, 4)], dtype=[('x', 'i4'), ('y', 'i4')]) # assert shape(a) == (2,) + def test_clip(self): + import numpypy as np + a = np.arange(10) + b = np.clip(a, 1, 8) + assert (b == [1, 1, 2, 3, 4, 5, 6, 7, 8, 8]).all() + assert (a == [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]).all() + b = np.clip(a, 3, 6, out=a) + assert (b == [3, 3, 3, 3, 4, 5, 6, 6, 6, 6]).all() + assert (a == [3, 3, 3, 3, 4, 5, 6, 6, 6, 6]).all() + a = np.arange(10) + b = np.clip(a, [3,4,1,1,1,4,4,4,4,4], 8) + assert (b == [3, 4, 2, 3, 4, 5, 6, 7, 8, 8]).all() + assert (a == [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]).all() + def test_sum(self): # tests taken from numpy/core/fromnumeric.py docstring - from numpypy import array, sum, ones + from numpypy import array, sum, ones, zeros assert sum([0.5, 1.5])== 2.0 assert sum([[0, 1], [0, 5]]) == 6 # assert sum([0.5, 0.7, 0.2, 1.5], dtype=int32) == 1 @@ -45,9 +59,20 @@ # If the accumulator is too small, overflow occurs: # assert ones(128, dtype=int8).sum(dtype=int8) == -128 + assert sum(range(10)) == 45 + assert sum(array(range(10))) == 45 + assert list(sum(zeros((0, 2)), axis=1)) == [] + + a = array([[1, 2], [3, 4]]) + out = array([[0, 0], [0, 0]]) + c = sum(a, axis=0, out=out[0]) + assert (c == [4, 6]).all() + assert (c == out[0]).all() + assert (c != out[1]).all() + def test_amin(self): # tests taken from numpy/core/fromnumeric.py docstring - from numpypy import array, arange, amin + from numpypy import array, arange, amin, zeros a = arange(4).reshape((2,2)) assert amin(a) == 0 # # Minima along the first axis @@ -60,9 +85,20 @@ # assert amin(b) == nan # assert nanmin(b) == 0.0 + assert amin(range(10)) == 0 + assert amin(array(range(10))) == 0 + assert list(amin(zeros((0, 2)), axis=1)) == [] + + a = array([[1, 2], [3, 4]]) + out = array([[0, 0], [0, 0]]) + c = amin(a, axis=1, out=out[0]) + assert (c == [1, 3]).all() + assert (c == out[0]).all() + assert (c != out[1]).all() + def test_amax(self): # tests taken from numpy/core/fromnumeric.py docstring - from numpypy import array, arange, amax + from numpypy import array, arange, amax, zeros a = arange(4).reshape((2,2)) assert amax(a) == 3 # assert (amax(a, axis=0) == array([2, 3])).all() @@ -73,6 +109,17 @@ # assert amax(b) == nan # assert nanmax(b) == 4.0 + assert amax(range(10)) == 9 + assert amax(array(range(10))) == 9 + assert list(amax(zeros((0, 2)), axis=1)) == [] + + a = array([[1, 2], [3, 4]]) + out = array([[0, 0], [0, 0]]) + c = amax(a, axis=1, out=out[0]) + assert (c == [2, 4]).all() + assert (c == out[0]).all() + assert (c != out[1]).all() + def test_alen(self): # tests taken from numpy/core/fromnumeric.py docstring from numpypy import array, zeros, alen diff --git a/pypy/module/test_lib_pypy/numpypy/core/test_numeric.py b/pypy/module/test_lib_pypy/numpypy/core/test_numeric.py --- a/pypy/module/test_lib_pypy/numpypy/core/test_numeric.py +++ b/pypy/module/test_lib_pypy/numpypy/core/test_numeric.py @@ -20,6 +20,7 @@ assert base_repr(-12, 10, 4) == '-000012' assert base_repr(-12, 4) == '-30' + class AppTestRepr(BaseNumpyAppTest): def test_repr(self): from numpypy import array @@ -146,10 +147,10 @@ def test_equal(self): from _numpypy import array from numpypy import array_equal - + a = [1, 2, 3] b = [1, 2, 3] - + assert array_equal(a, b) assert array_equal(a, array(b)) assert array_equal(array(a), b) @@ -158,10 +159,10 @@ def test_not_equal(self): from _numpypy import array from numpypy import array_equal - + a = [1, 2, 3] b = [1, 2, 4] - + assert not array_equal(a, b) assert not array_equal(a, array(b)) assert not array_equal(array(a), b) @@ -170,17 +171,17 @@ def test_mismatched_shape(self): from _numpypy import array from numpypy import array_equal - + a = [1, 2, 3] b = [[1, 2, 3], [1, 2, 3]] - + assert not array_equal(a, b) assert not array_equal(a, array(b)) assert not array_equal(array(a), b) assert not array_equal(array(a), array(b)) + class AppTestNumeric(BaseNumpyAppTest): - def test_outer(self): from _numpypy import array from numpypy import outer @@ -192,3 +193,22 @@ [12, 15, 18]]) assert (res == expected).all() + def test_identity(self): + from _numpypy import array, int32, float64, dtype + from numpypy import identity + a = identity(0) + assert len(a) == 0 + assert a.dtype == dtype('float64') + assert a.shape == (0, 0) + b = identity(1, dtype=int32) + assert len(b) == 1 + assert b[0][0] == 1 + assert b.shape == (1, 1) + assert b.dtype == dtype('int32') + c = identity(2) + assert c.shape == (2, 2) + assert (c == [[1, 0], [0, 1]]).all() + d = identity(3, dtype='int32') + assert d.shape == (3, 3) + assert d.dtype == dtype('int32') + assert (d == [[1, 0, 0], [0, 1, 0], [0, 0, 1]]).all() diff --git a/pypy/module/test_lib_pypy/numpypy/core/test_shape_base.py b/pypy/module/test_lib_pypy/numpypy/core/test_shape_base.py --- a/pypy/module/test_lib_pypy/numpypy/core/test_shape_base.py +++ b/pypy/module/test_lib_pypy/numpypy/core/test_shape_base.py @@ -129,35 +129,3 @@ np.ones((a.shape[0], a.shape[1] + b.shape[1], a.shape[2]))) - - def test_dstack(self): - import numpypy as np - a = np.array((1, 2, 3)) - b = np.array((2, 3, 4)) - c = np.dstack((a, b)) - assert np.array_equal(c, [[[1, 2], [2, 3], [3, 4]]]) - - a = np.array([[1], [2], [3]]) - b = np.array([[2], [3], [4]]) - c = np.dstack((a, b)) - assert np.array_equal(c, [[[1, 2]], [[2, 3]], [[3, 4]]]) - - #skip("https://bugs.pypy.org/issue1394") - for shape1, shape2 in [[(4, 2, 3), (4, 2, 7)], - [(7, 2, 0), (7, 2, 10)], - [(7, 2, 0), (7, 2, 0)]]: - a, b = np.ones(shape1), np.ones(shape2) - assert np.all(np.dstack((a, b)) == - np.ones((a.shape[0], - a.shape[1], - a.shape[2] + b.shape[2]))) - - for shape1, shape2 in [[(4, 2, 3, 5), (4, 2, 7, 5)], - [(7, 2, 0, 5), (7, 2, 10, 5)], - [(7, 2, 0, 5), (7, 2, 0, 5)]]: - a, b = np.ones(shape1), np.ones(shape2) - assert np.all(np.dstack((a, b)) == - np.ones((a.shape[0], - a.shape[1], - a.shape[2] + b.shape[2], - a.shape[3]))) diff --git a/pypy/module/test_lib_pypy/numpypy/lib/test_function_base.py b/pypy/module/test_lib_pypy/numpypy/lib/test_function_base.py new file mode 100644 --- /dev/null +++ b/pypy/module/test_lib_pypy/numpypy/lib/test_function_base.py @@ -0,0 +1,7 @@ +from pypy.module.micronumpy.test.test_base import BaseNumpyAppTest + +class AppTestFunctionBase(BaseNumpyAppTest): + def test_average(self): + from numpypy import array, average + assert average(range(10)) == 4.5 + assert average(array(range(10))) == 4.5 diff --git a/pypy/module/test_lib_pypy/numpypy/lib/test_shape_base_lib.py b/pypy/module/test_lib_pypy/numpypy/lib/test_shape_base_lib.py new file mode 100644 --- /dev/null +++ b/pypy/module/test_lib_pypy/numpypy/lib/test_shape_base_lib.py @@ -0,0 +1,34 @@ +from pypy.module.micronumpy.test.test_base import BaseNumpyAppTest + +class AppTestShapeBase(BaseNumpyAppTest): + def test_dstack(self): + import numpypy as np + a = np.array((1, 2, 3)) + b = np.array((2, 3, 4)) + c = np.dstack((a, b)) + assert np.array_equal(c, [[[1, 2], [2, 3], [3, 4]]]) + + a = np.array([[1], [2], [3]]) + b = np.array([[2], [3], [4]]) + c = np.dstack((a, b)) + assert np.array_equal(c, [[[1, 2]], [[2, 3]], [[3, 4]]]) + + #skip("https://bugs.pypy.org/issue1394") + for shape1, shape2 in [[(4, 2, 3), (4, 2, 7)], + [(7, 2, 0), (7, 2, 10)], + [(7, 2, 0), (7, 2, 0)]]: + a, b = np.ones(shape1), np.ones(shape2) + assert np.all(np.dstack((a, b)) == + np.ones((a.shape[0], + a.shape[1], + a.shape[2] + b.shape[2]))) + + for shape1, shape2 in [[(4, 2, 3, 5), (4, 2, 7, 5)], + [(7, 2, 0, 5), (7, 2, 10, 5)], + [(7, 2, 0, 5), (7, 2, 0, 5)]]: + a, b = np.ones(shape1), np.ones(shape2) + assert np.all(np.dstack((a, b)) == + np.ones((a.shape[0], + a.shape[1], + a.shape[2] + b.shape[2], + a.shape[3]))) diff --git a/pypy/module/test_lib_pypy/numpypy/lib/test_twodim_base.py b/pypy/module/test_lib_pypy/numpypy/lib/test_twodim_base.py new file mode 100644 --- /dev/null +++ b/pypy/module/test_lib_pypy/numpypy/lib/test_twodim_base.py @@ -0,0 +1,31 @@ +from pypy.module.micronumpy.test.test_base import BaseNumpyAppTest + +class AppTestTwoDimBase(BaseNumpyAppTest): + def test_eye(self): + from _numpypy import int32, dtype + from numpypy import eye + a = eye(0) + assert len(a) == 0 + assert a.dtype == dtype('float64') + assert a.shape == (0, 0) + b = eye(1, dtype=int32) + assert len(b) == 1 + assert b[0][0] == 1 + assert b.shape == (1, 1) + assert b.dtype == dtype('int32') + c = eye(2) + assert c.shape == (2, 2) + assert (c == [[1, 0], [0, 1]]).all() + d = eye(3, dtype='int32') + assert d.shape == (3, 3) + assert d.dtype == dtype('int32') + assert (d == [[1, 0, 0], [0, 1, 0], [0, 0, 1]]).all() + e = eye(3, 4) + assert e.shape == (3, 4) + assert (e == [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0]]).all() + f = eye(2, 4, k=3) + assert f.shape == (2, 4) + assert (f == [[0, 0, 0, 1], [0, 0, 0, 0]]).all() + g = eye(3, 4, k=-1) + assert g.shape == (3, 4) + assert (g == [[0, 0, 0, 0], [1, 0, 0, 0], [0, 1, 0, 0]]).all() diff --git a/pypy/module/test_lib_pypy/numpypy/test_numpy.py b/pypy/module/test_lib_pypy/numpypy/test_numpy.py --- a/pypy/module/test_lib_pypy/numpypy/test_numpy.py +++ b/pypy/module/test_lib_pypy/numpypy/test_numpy.py @@ -1,4 +1,6 @@ -class AppTestNumpy: +from pypy.module.micronumpy.test.test_base import BaseNumpyAppTest + +class AppTestNumpy(BaseNumpyAppTest): spaceconfig = dict(usemodules=['micronumpy']) def test_imports(self): @@ -26,6 +28,28 @@ assert min(4, 3, 2, 1) == 1 assert max(1, 2, 3, 4) == 4 - from numpypy import min, max + from numpypy import min, max, amin, amax assert min is not __builtin__.min assert max is not __builtin__.max + assert min is amin + assert max is amax + + def test_builtin_aliases(self): + import __builtin__ + import numpypy + from numpypy import * + + for name in ['bool', 'int', 'long', 'float', 'complex', 'object', + 'unicode', 'str']: + assert name not in locals() + assert getattr(numpypy, name) is getattr(__builtin__, name) + + def test_typeinfo(self): + import numpypy + assert 'typeinfo' not in dir(numpypy) + assert 'typeinfo' in dir(numpypy.core.multiarray) + + def test_set_string_function(self): + import numpypy + assert numpypy.set_string_function is not \ + numpypy.core.multiarray.set_string_function diff --git a/rpython/jit/backend/arm/regalloc.py b/rpython/jit/backend/arm/regalloc.py --- a/rpython/jit/backend/arm/regalloc.py +++ b/rpython/jit/backend/arm/regalloc.py @@ -736,7 +736,7 @@ classptr = y_val # here, we have to go back from 'classptr' to the value expected # from reading the 16 bits in the object header - from rpython.rtyper.memory.gctypelayout import GCData + from rpython.memory.gctypelayout import GCData sizeof_ti = rffi.sizeof(GCData.TYPE_INFO) type_info_group = llop.gc_get_type_info_group(llmemory.Address) type_info_group = rffi.cast(lltype.Signed, type_info_group) diff --git a/rpython/jit/backend/llsupport/gc.py b/rpython/jit/backend/llsupport/gc.py --- a/rpython/jit/backend/llsupport/gc.py +++ b/rpython/jit/backend/llsupport/gc.py @@ -17,7 +17,7 @@ from rpython.jit.backend.llsupport.descr import get_array_descr from rpython.jit.backend.llsupport.descr import get_call_descr from rpython.jit.backend.llsupport.rewrite import GcRewriterAssembler -from rpython.rtyper.memory.gctransform import asmgcroot +from rpython.memory.gctransform import asmgcroot # ____________________________________________________________ @@ -698,7 +698,7 @@ def _make_layoutbuilder(self): # make a TransformerLayoutBuilder and save it on the translator # where it can be fished and reused by the FrameworkGCTransformer - from rpython.rtyper.memory.gctransform import framework + from rpython.memory.gctransform import framework translator = self.translator self.layoutbuilder = framework.TransformerLayoutBuilder(translator) self.layoutbuilder.delay_encoding() @@ -706,7 +706,7 @@ self.gcrootmap.add_jit2gc_hooks(translator._jit2gc) def _setup_gcclass(self): - from rpython.rtyper.memory.gcheader import GCHeaderBuilder + from rpython.memory.gcheader import GCHeaderBuilder self.GCClass = self.layoutbuilder.GCClass self.moving_gc = self.GCClass.moving_gc self.HDRPTR = lltype.Ptr(self.GCClass.HDR) @@ -727,7 +727,7 @@ self.write_barrier_descr = WriteBarrierDescr(self) def _make_functions(self, really_not_translated): - from rpython.rtyper.memory.gctypelayout import check_typeid + from rpython.memory.gctypelayout import check_typeid llop1 = self.llop1 (self.standard_array_basesize, _, self.standard_array_length_ofs) = \ symbolic.get_array_token(lltype.GcArray(lltype.Signed), @@ -813,7 +813,7 @@ [lltype.Signed] * 2) def _bh_malloc(self, sizedescr): - from rpython.rtyper.memory.gctypelayout import check_typeid + from rpython.memory.gctypelayout import check_typeid llop1 = self.llop1 type_id = llop.extract_ushort(llgroup.HALFWORD, sizedescr.tid) check_typeid(type_id) @@ -822,7 +822,7 @@ False, False, False) def _bh_malloc_array(self, num_elem, arraydescr): - from rpython.rtyper.memory.gctypelayout import check_typeid + from rpython.memory.gctypelayout import check_typeid llop1 = self.llop1 type_id = llop.extract_ushort(llgroup.HALFWORD, arraydescr.tid) check_typeid(type_id) diff --git a/rpython/jit/backend/llsupport/test/test_symbolic.py b/rpython/jit/backend/llsupport/test/test_symbolic.py --- a/rpython/jit/backend/llsupport/test/test_symbolic.py +++ b/rpython/jit/backend/llsupport/test/test_symbolic.py @@ -1,7 +1,7 @@ import py from rpython.jit.backend.llsupport.symbolic import * from rpython.rtyper.lltypesystem import lltype, rffi -from rpython.rtyper.memory.lltypelayout import convert_offset_to_int +from rpython.memory.lltypelayout import convert_offset_to_int WORD = rffi.sizeof(lltype.Signed) diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -426,7 +426,7 @@ @rgc.no_collect def _release_gil_asmgcc(css): # similar to trackgcroot.py:pypy_asm_stackwalk, first part - from rpython.rtyper.memory.gctransform import asmgcroot + from rpython.memory.gctransform import asmgcroot new = rffi.cast(asmgcroot.ASM_FRAMEDATA_HEAD_PTR, css) next = asmgcroot.gcrootanchor.next new.next = next @@ -446,7 +446,7 @@ if after: after() # similar to trackgcroot.py:pypy_asm_stackwalk, second part - from rpython.rtyper.memory.gctransform import asmgcroot + from rpython.memory.gctransform import asmgcroot old = rffi.cast(asmgcroot.ASM_FRAMEDATA_HEAD_PTR, css) prev = old.prev next = old.next @@ -1786,7 +1786,7 @@ # from reading the half-word in the object header. Note that # this half-word is at offset 0 on a little-endian machine; # it would be at offset 2 or 4 on a big-endian machine. - from rpython.rtyper.memory.gctypelayout import GCData + from rpython.memory.gctypelayout import GCData sizeof_ti = rffi.sizeof(GCData.TYPE_INFO) type_info_group = llop.gc_get_type_info_group(llmemory.Address) type_info_group = rffi.cast(lltype.Signed, type_info_group) @@ -2296,7 +2296,7 @@ # like %eax that would be destroyed by this call, *and* they are # used by arglocs for the *next* call, then trouble; for now we # will just push/pop them. - from rpython.rtyper.memory.gctransform import asmgcroot + from rpython.memory.gctransform import asmgcroot css = self._regalloc.close_stack_struct if css == 0: use_words = (2 + max(asmgcroot.INDEX_OF_EBP, diff --git a/rpython/rtyper/memory/__init__.py b/rpython/memory/__init__.py rename from rpython/rtyper/memory/__init__.py rename to rpython/memory/__init__.py diff --git a/rpython/rtyper/memory/gc/__init__.py b/rpython/memory/gc/__init__.py rename from rpython/rtyper/memory/gc/__init__.py rename to rpython/memory/gc/__init__.py diff --git a/rpython/rtyper/memory/gc/base.py b/rpython/memory/gc/base.py rename from rpython/rtyper/memory/gc/base.py rename to rpython/memory/gc/base.py --- a/rpython/rtyper/memory/gc/base.py +++ b/rpython/memory/gc/base.py @@ -1,10 +1,10 @@ from rpython.rtyper.lltypesystem import lltype, llmemory, llarena, rffi from rpython.rtyper.lltypesystem.lloperation import llop from rpython.rlib.debug import ll_assert -from rpython.rtyper.memory.gcheader import GCHeaderBuilder -from rpython.rtyper.memory.support import DEFAULT_CHUNK_SIZE -from rpython.rtyper.memory.support import get_address_stack, get_address_deque -from rpython.rtyper.memory.support import AddressDict, null_address_dict +from rpython.memory.gcheader import GCHeaderBuilder +from rpython.memory.support import DEFAULT_CHUNK_SIZE +from rpython.memory.support import get_address_stack, get_address_deque +from rpython.memory.support import AddressDict, null_address_dict from rpython.rtyper.lltypesystem.llmemory import NULL, raw_malloc_usage TYPEID_MAP = lltype.GcStruct('TYPEID_MAP', ('count', lltype.Signed), @@ -41,7 +41,7 @@ def post_setup(self): # More stuff that needs to be initialized when the GC is already # fully working. (Only called by gctransform/framework for now.) - from rpython.rtyper.memory.gc import env + from rpython.memory.gc import env self.DEBUG = env.read_from_env('PYPY_GC_DEBUG') def _teardown(self): @@ -302,7 +302,7 @@ """ if self.DEBUG: from rpython.rlib.objectmodel import we_are_translated - from rpython.rtyper.memory.support import AddressDict + from rpython.memory.support import AddressDict self._debug_seen = AddressDict() self._debug_pending = self.AddressStack() if not we_are_translated(): @@ -434,7 +434,7 @@ except KeyError: raise ValueError("unknown value for translation.gc: %r" % ( config.translation.gc,)) - module = __import__("rpython.rtyper.memory.gc." + modulename, + module = __import__("rpython.memory.gc." + modulename, globals(), locals(), [classname]) GCClass = getattr(module, classname) return GCClass, GCClass.TRANSLATION_PARAMS diff --git a/rpython/rtyper/memory/gc/env.py b/rpython/memory/gc/env.py rename from rpython/rtyper/memory/gc/env.py rename to rpython/memory/gc/env.py diff --git a/rpython/rtyper/memory/gc/generation.py b/rpython/memory/gc/generation.py rename from rpython/rtyper/memory/gc/generation.py rename to rpython/memory/gc/generation.py --- a/rpython/rtyper/memory/gc/generation.py +++ b/rpython/memory/gc/generation.py @@ -1,8 +1,8 @@ import sys -from rpython.rtyper.memory.gc.semispace import SemiSpaceGC -from rpython.rtyper.memory.gc.semispace import GCFLAG_EXTERNAL, GCFLAG_FORWARDED -from rpython.rtyper.memory.gc.semispace import GC_HASH_TAKEN_ADDR -from rpython.rtyper.memory.gc import env +from rpython.memory.gc.semispace import SemiSpaceGC +from rpython.memory.gc.semispace import GCFLAG_EXTERNAL, GCFLAG_FORWARDED +from rpython.memory.gc.semispace import GC_HASH_TAKEN_ADDR +from rpython.memory.gc import env from rpython.rtyper.lltypesystem.llmemory import NULL, raw_malloc_usage from rpython.rtyper.lltypesystem import lltype, llmemory, llarena from rpython.rlib.objectmodel import free_non_gc_object diff --git a/rpython/rtyper/memory/gc/hybrid.py b/rpython/memory/gc/hybrid.py rename from rpython/rtyper/memory/gc/hybrid.py rename to rpython/memory/gc/hybrid.py --- a/rpython/rtyper/memory/gc/hybrid.py +++ b/rpython/memory/gc/hybrid.py @@ -1,12 +1,12 @@ import sys -from rpython.rtyper.memory.gc.semispace import SemiSpaceGC -from rpython.rtyper.memory.gc.generation import GenerationGC, WORD -from rpython.rtyper.memory.gc.semispace import GCFLAG_EXTERNAL, GCFLAG_FORWARDED -from rpython.rtyper.memory.gc.semispace import GCFLAG_HASHMASK -from rpython.rtyper.memory.gc.generation import GCFLAG_NO_YOUNG_PTRS -from rpython.rtyper.memory.gc.generation import GCFLAG_NO_HEAP_PTRS -from rpython.rtyper.memory.gc.semispace import GC_HASH_TAKEN_ADDR -from rpython.rtyper.memory.gc.semispace import GC_HASH_HASFIELD +from rpython.memory.gc.semispace import SemiSpaceGC +from rpython.memory.gc.generation import GenerationGC, WORD +from rpython.memory.gc.semispace import GCFLAG_EXTERNAL, GCFLAG_FORWARDED +from rpython.memory.gc.semispace import GCFLAG_HASHMASK +from rpython.memory.gc.generation import GCFLAG_NO_YOUNG_PTRS +from rpython.memory.gc.generation import GCFLAG_NO_HEAP_PTRS +from rpython.memory.gc.semispace import GC_HASH_TAKEN_ADDR +from rpython.memory.gc.semispace import GC_HASH_HASFIELD from rpython.rtyper.lltypesystem import lltype, llmemory, llarena from rpython.rtyper.lltypesystem.llmemory import raw_malloc_usage from rpython.rtyper.lltypesystem.lloperation import llop diff --git a/rpython/rtyper/memory/gc/inspector.py b/rpython/memory/gc/inspector.py rename from rpython/rtyper/memory/gc/inspector.py rename to rpython/memory/gc/inspector.py --- a/rpython/rtyper/memory/gc/inspector.py From noreply at buildbot.pypy.org Sat Feb 23 14:58:02 2013 From: noreply at buildbot.pypy.org (fijal) Date: Sat, 23 Feb 2013 14:58:02 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: remove those debug prints Message-ID: <20130223135802.1AB411C0CA3@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61679:1f412de06308 Date: 2013-02-23 15:57 +0200 http://bitbucket.org/pypy/pypy/changeset/1f412de06308/ Log: remove those debug prints diff --git a/rpython/jit/backend/llsupport/gcmap.py b/rpython/jit/backend/llsupport/gcmap.py --- a/rpython/jit/backend/llsupport/gcmap.py +++ b/rpython/jit/backend/llsupport/gcmap.py @@ -3,14 +3,12 @@ from rpython.jit.backend.llsupport import jitframe from rpython.rlib.rarithmetic import r_uint from rpython.jit.backend.llsupport.symbolic import WORD -from rpython.rlib.debug import debug_print def allocate_gcmap(assembler, frame_depth, fixed_size): size = frame_depth + fixed_size malloc_size = (size // WORD // 8 + 1) + 1 rawgcmap = assembler.datablockwrapper.malloc_aligned(WORD * malloc_size, WORD) - debug_print("gcmap: %x, len %d" % (rawgcmap, malloc_size - 1)) # set the length field rffi.cast(rffi.CArrayPtr(lltype.Signed), rawgcmap)[0] = malloc_size - 1 gcmap = rffi.cast(lltype.Ptr(jitframe.GCMAP), rawgcmap) diff --git a/rpython/jit/backend/x86/regalloc.py b/rpython/jit/backend/x86/regalloc.py --- a/rpython/jit/backend/x86/regalloc.py +++ b/rpython/jit/backend/x86/regalloc.py @@ -29,7 +29,6 @@ from rpython.jit.backend.x86.arch import IS_X86_32, IS_X86_64 from rpython.jit.backend.x86 import rx86 from rpython.rlib.rarithmetic import r_longlong, r_uint -from rpython.rlib.debug import debug_print, debug_start, debug_stop class X86RegisterManager(RegisterManager): @@ -863,7 +862,6 @@ def get_gcmap(self, forbidden_regs=[], noregs=False): frame_depth = self.fm.get_frame_depth() gcmap = allocate_gcmap(self.assembler, frame_depth, JITFRAME_FIXED_SIZE) - debug_start("jit-backend-gcmap") for box, loc in self.rm.reg_bindings.iteritems(): if loc in forbidden_regs: continue @@ -877,9 +875,6 @@ assert isinstance(loc, FrameLoc) val = loc.position + JITFRAME_FIXED_SIZE gcmap[val // WORD // 8] |= r_uint(1) << (val % (WORD * 8)) - for i in range(len(gcmap)): - debug_print(str(gcmap[i])) - debug_stop('jit-backend-gcmap') return gcmap From noreply at buildbot.pypy.org Sat Feb 23 15:03:24 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sat, 23 Feb 2013 15:03:24 +0100 (CET) Subject: [pypy-commit] cffi default: typo Message-ID: <20130223140324.06F3E1C0327@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r1166:49104377cf81 Date: 2013-02-23 15:03 +0100 http://bitbucket.org/cffi/cffi/changeset/49104377cf81/ Log: typo diff --git a/doc/source/index.rst b/doc/source/index.rst --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -716,7 +716,7 @@ cdata objects don't have ownership: they are merely references to existing memory. -As an exception the above rule, dereferencing a pointer that owns a +As an exception to the above rule, dereferencing a pointer that owns a *struct* or *union* object returns a cdata struct or union object that "co-owns" the same memory. Thus in this case there are two objects that can keep the same memory alive. This is done for cases where From noreply at buildbot.pypy.org Sat Feb 23 15:20:10 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sat, 23 Feb 2013 15:20:10 +0100 (CET) Subject: [pypy-commit] cffi default: update Message-ID: <20130223142010.33AF31C0327@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r1167:04a15b0fd6d7 Date: 2013-02-23 15:16 +0100 http://bitbucket.org/cffi/cffi/changeset/04a15b0fd6d7/ Log: update diff --git a/doc/source/index.rst b/doc/source/index.rst --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -1144,7 +1144,7 @@ a number of attributes for introspection: ``kind`` and ``cname`` are always present, and depending on the kind they may also have ``item``, ``length``, ``fields``, ``args``, ``result``, ``ellipsis``, - ``abi`` and ``elements``. + ``abi``, ``elements`` and ``relements``. ``ffi.sizeof("C type" or cdata object)``: return the size of the argument in bytes. The argument can be either a C type, or a cdata object, From noreply at buildbot.pypy.org Sat Feb 23 15:41:06 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sat, 23 Feb 2013 15:41:06 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: 32-bit fix Message-ID: <20130223144106.19FEB1C0327@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: jitframe-on-heap Changeset: r61680:7bdd7a5b4bb7 Date: 2013-02-23 15:34 +0100 http://bitbucket.org/pypy/pypy/changeset/7bdd7a5b4bb7/ Log: 32-bit fix diff --git a/rpython/memory/gctransform/asmgcroot.py b/rpython/memory/gctransform/asmgcroot.py --- a/rpython/memory/gctransform/asmgcroot.py +++ b/rpython/memory/gctransform/asmgcroot.py @@ -596,8 +596,8 @@ # saved %r12 saved %esi # saved %rbx saved %ebx # return addr return addr + stack_depth = PASS_ON_MY_FRAME + self.extra_stack_depth if IS_64_BITS: - stack_depth = PASS_ON_MY_FRAME + self.extra_stack_depth if index == 2: # rbp return LOC_ESP_PLUS | (stack_depth << 2) if index == 3: # r15 From noreply at buildbot.pypy.org Sat Feb 23 16:47:42 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Sat, 23 Feb 2013 16:47:42 +0100 (CET) Subject: [pypy-commit] pypy rpython-doc: hg merge default Message-ID: <20130223154742.06F5F1C008F@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: rpython-doc Changeset: r61681:4ae3996cfab2 Date: 2013-02-23 15:29 +0100 http://bitbucket.org/pypy/pypy/changeset/4ae3996cfab2/ Log: hg merge default diff --git a/pypy/doc/cpython_differences.rst b/pypy/doc/cpython_differences.rst --- a/pypy/doc/cpython_differences.rst +++ b/pypy/doc/cpython_differences.rst @@ -134,7 +134,7 @@ ``ReferenceError`` at any place that uses them. (Or, better yet, don't use ``weakref.proxy()`` at all; use ``weakref.ref()``.) -There are a few extra implications for the difference in the GC. Most +There are a few extra implications from the difference in the GC. Most notably, if an object has a ``__del__``, the ``__del__`` is never called more than once in PyPy; but CPython will call the same ``__del__`` several times if the object is resurrected and dies again. The ``__del__`` methods are @@ -156,7 +156,7 @@ .. __: http://bugs.pypy.org/issue736 -Using the default GC called ``minimark``, the built-in function ``id()`` +Using the default GC (called ``minimark``), the built-in function ``id()`` works like it does in CPython. With other GCs it returns numbers that are not real addresses (because an object can move around several times) and calling it a lot can lead to performance problem. @@ -286,7 +286,7 @@ ------------- * Hash randomization (``-R``) is ignored in PyPy. As documented in - http://bugs.python.org/issue14621 , some of us believe it has no + http://bugs.python.org/issue14621, some of us believe it has no purpose in CPython either. * ``sys.setrecursionlimit(n)`` sets the limit only approximately, diff --git a/pypy/doc/faq.rst b/pypy/doc/faq.rst --- a/pypy/doc/faq.rst +++ b/pypy/doc/faq.rst @@ -202,20 +202,20 @@ Be sure to enable it again if you need it! -The PyPy translation tool chain -=============================== +The RPython translation tool chain +=================================== ---------------------------------------------- -Can PyPy compile normal Python programs to C? ---------------------------------------------- +------------------------------------------------ +Can RPython compile normal Python programs to C? +------------------------------------------------ -No, PyPy is not a Python compiler. +No, RPython is not a Python compiler. In Python, it is mostly impossible to *prove* anything about the types that a program will manipulate by doing a static analysis. It should be clear if you are familiar with Python, but if in doubt see [BRETT]_. -If you want a fast Python program, please use our JIT_ instead. +If you want a fast Python program, please use the PyPy JIT_ instead. .. _JIT: jit/index.html @@ -300,8 +300,8 @@ Do I have to rewrite my programs in RPython? -------------------------------------------- -No. And you shouldn't try. First and foremost, RPython is a language -that is designed to write interpreters in. It is a restricted subset of +No, and you shouldn't try. First and foremost, RPython is a language +designed for writing interpreters. It is a restricted subset of Python. If you program is not an interpreter but tries to do "real things", like use *any* part of the standard Python library or *any* 3rd-party library, then it is not RPython to start with. You should @@ -381,8 +381,8 @@ No, you have to rebuild the entire interpreter. This means two things: -* It is imperative to use test-driven development. You have to test - exhaustively your module in pure Python, before even attempting to +* It is imperative to use test-driven development. You have to exhaustively + test your module in pure Python, before even attempting to translate it. Once you translate it, you should have only a few typing issues left to fix, but otherwise the result should work out of the box. diff --git a/pypy/doc/getting-started-dev.rst b/pypy/doc/getting-started-dev.rst --- a/pypy/doc/getting-started-dev.rst +++ b/pypy/doc/getting-started-dev.rst @@ -20,7 +20,7 @@ To start the interactive translator shell do:: - cd pypy + cd rpython python bin/translatorshell.py Test snippets of translatable code are provided in the file diff --git a/pypy/doc/interpreter.rst b/pypy/doc/interpreter.rst --- a/pypy/doc/interpreter.rst +++ b/pypy/doc/interpreter.rst @@ -25,7 +25,7 @@ compact bytecode format as CPython 2.7, with minor differences in the bytecode set. Our bytecode compiler is implemented as a chain of flexible passes (tokenizer, lexer, parser, -abstract syntax tree builder, bytecode generator). The latter passes +abstract syntax tree builder and bytecode generator). The latter passes are based on the ``compiler`` package from the standard library of CPython, with various improvements and bug fixes. The bytecode compiler (living under `pypy/interpreter/astcompiler/`_) is now integrated and is @@ -38,8 +38,8 @@ calling its ``frame.eval()`` method. This main entry point initialize appropriate namespaces and then interprets each bytecode instruction. Python's standard library contains -the `lib-python/2.7/dis.py`_ module which allows to view -the Virtual's machine bytecode instructions:: +the `lib-python/2.7/dis.py`_ module which allows to inspection +of the virtual machine's bytecode instructions:: >>> import dis >>> def f(x): @@ -50,10 +50,10 @@ 6 BINARY_ADD 7 RETURN_VALUE -CPython as well as PyPy are stack-based virtual machines, i.e. -they don't have registers but put object to and pull objects +CPython and PyPy are stack-based virtual machines, i.e. +they don't have registers but instead push object to and pull objects from a stack. The bytecode interpreter is only responsible -for implementing control flow and putting and pulling black +for implementing control flow and pushing and pulling black box objects to and from this value stack. The bytecode interpreter does not know how to perform operations on those black box (`wrapped`_) objects for which it delegates to the `object @@ -75,8 +75,8 @@ on ``OperationErrors``. The interpreter implementation offers mechanisms to allow a -caller to be unaware if a particular function invocation leads -to bytecode interpretation or is executed directly at +caller to be unaware of whether a particular function invocation +leads to bytecode interpretation or is executed directly at interpreter-level. The two basic kinds of `Gateway classes`_ expose either an interpreter-level function to application-level execution (``interp2app``) or allow diff --git a/pypy/module/test_lib_pypy/numpypy/test_numpy.py b/pypy/module/test_lib_pypy/numpypy/test_numpy.py --- a/pypy/module/test_lib_pypy/numpypy/test_numpy.py +++ b/pypy/module/test_lib_pypy/numpypy/test_numpy.py @@ -1,4 +1,6 @@ -class AppTestNumpy: +from pypy.module.micronumpy.test.test_base import BaseNumpyAppTest + +class AppTestNumpy(BaseNumpyAppTest): spaceconfig = dict(usemodules=['micronumpy']) def test_imports(self): diff --git a/rpython/translator/goal/bpnn.py b/rpython/translator/goal/bpnn.py new file mode 100644 --- /dev/null +++ b/rpython/translator/goal/bpnn.py @@ -0,0 +1,214 @@ +#!/usr/bin/env python +""" + Translator Demo + + To analyse and type-annotate the functions and class defined in + this module, starting from the entry point function demo(), + use the following command line: + + ../pypy/translator/goal/translate.py bpnn.py + + Insert '--help' before 'bpnn.py' for a list of translation options, + or see the Overview of Command Line Options for translation at + http://codespeak.net/pypy/dist/pypy/doc/config/commandline.html +""" +# Back-Propagation Neural Networks +# +# Written in Python. See http://www.python.org/ +# +# Neil Schemenauer +# +# Modifications to the original (Armin Rigo): +# * import random from PyPy's lib, which is Python 2.2's plain +# Python implementation +# * print a doc about how to start the Translator + +import sys +import math +import time + +import autopath +from rpython.rlib import rrandom + +PRINT_IT = True + +random = rrandom.Random(1) + +# calculate a random number where: a <= rand < b +def rand(a, b): + return (b-a)*random.random() + a + +# Make a matrix (we could use NumPy to speed this up) +def makeMatrix(I, J, fill=0.0): + m = [] + for i in range(I): + m.append([fill]*J) + return m + +class NN: + + def __init__(self, ni, nh, no): + # number of input, hidden, and output nodes + self.ni = ni + 1 # +1 for bias node + self.nh = nh + self.no = no + + # activations for nodes + self.ai = [1.0]*self.ni + self.ah = [1.0]*self.nh + self.ao = [1.0]*self.no + + # create weights + self.wi = makeMatrix(self.ni, self.nh) + self.wo = makeMatrix(self.nh, self.no) + # set them to random vaules + for i in range(self.ni): + for j in range(self.nh): + self.wi[i][j] = rand(-2.0, 2.0) + for j in range(self.nh): + for k in range(self.no): + self.wo[j][k] = rand(-2.0, 2.0) + + # last change in weights for momentum + self.ci = makeMatrix(self.ni, self.nh) + self.co = makeMatrix(self.nh, self.no) + + def update(self, inputs): + if len(inputs) != self.ni-1: + raise ValueError, 'wrong number of inputs' + + # input activations + for i in range(self.ni-1): + #self.ai[i] = 1.0/(1.0+math.exp(-inputs[i])) + self.ai[i] = inputs[i] + + # hidden activations + for j in range(self.nh): + sum = 0.0 + for i in range(self.ni): + sum = sum + self.ai[i] * self.wi[i][j] + self.ah[j] = 1.0/(1.0+math.exp(-sum)) + + # output activations + for k in range(self.no): + sum = 0.0 + for j in range(self.nh): + sum = sum + self.ah[j] * self.wo[j][k] + self.ao[k] = 1.0/(1.0+math.exp(-sum)) + + return self.ao[:] + + + def backPropagate(self, targets, N, M): + if len(targets) != self.no: + raise ValueError, 'wrong number of target values' + + # calculate error terms for output + output_deltas = [0.0] * self.no + for k in range(self.no): + ao = self.ao[k] + output_deltas[k] = ao*(1-ao)*(targets[k]-ao) + + # calculate error terms for hidden + hidden_deltas = [0.0] * self.nh + for j in range(self.nh): + sum = 0.0 + for k in range(self.no): + sum = sum + output_deltas[k]*self.wo[j][k] + hidden_deltas[j] = self.ah[j]*(1-self.ah[j])*sum + + # update output weights + for j in range(self.nh): + for k in range(self.no): + change = output_deltas[k]*self.ah[j] + self.wo[j][k] = self.wo[j][k] + N*change + M*self.co[j][k] + self.co[j][k] = change + #print N*change, M*self.co[j][k] + + # update input weights + for i in range(self.ni): + for j in range(self.nh): + change = hidden_deltas[j]*self.ai[i] + self.wi[i][j] = self.wi[i][j] + N*change + M*self.ci[i][j] + self.ci[i][j] = change + + # calculate error + error = 0.0 + for k in range(len(targets)): + delta = targets[k]-self.ao[k] + error = error + 0.5*delta*delta + return error + + + def test(self, patterns): + for p in patterns: + if PRINT_IT: + print p[0], '->', self.update(p[0]) + + def weights(self): + if PRINT_IT: + print 'Input weights:' + for i in range(self.ni): + print self.wi[i] + print + print 'Output weights:' + for j in range(self.nh): + print self.wo[j] + + def train(self, patterns, iterations=2000, N=0.5, M=0.1): + # N: learning rate + # M: momentum factor + for i in xrange(iterations): + error = 0.0 + for p in patterns: + inputs = p[0] + targets = p[1] + self.update(inputs) + error = error + self.backPropagate(targets, N, M) + if PRINT_IT and i % 100 == 0: + print 'error', error + + +def demo(): + # Teach network XOR function + pat = [ + [[0,0], [0]], + [[0,1], [1]], + [[1,0], [1]], + [[1,1], [0]] + ] + + # create a network with two input, two hidden, and two output nodes + n = NN(2, 3, 1) + # train it with some patterns + n.train(pat, 2000) + # test it + n.test(pat) + + +# __________ Entry point for stand-alone builds __________ + +import time + +def entry_point(argv): + if len(argv) > 1: + N = int(argv[1]) + else: + N = 200 + T = time.time() + for i in range(N): + demo() + t1 = time.time() - T + print "%d iterations, %s milliseconds per iteration" % (N, 1000.0*t1/N) + return 0 + +# _____ Define and setup target ___ + +def target(*args): + return entry_point, None + +if __name__ == '__main__': + if len(sys.argv) == 1: + sys.argv.append('1') + entry_point(sys.argv) + print __doc__ From noreply at buildbot.pypy.org Sat Feb 23 16:47:43 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Sat, 23 Feb 2013 16:47:43 +0100 (CET) Subject: [pypy-commit] pypy rpython-doc: Separate RPython section from pypy/doc/coding-guide.rst. Message-ID: <20130223154743.3900C1C0CA3@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: rpython-doc Changeset: r61682:833074049d18 Date: 2013-02-23 15:37 +0100 http://bitbucket.org/pypy/pypy/changeset/833074049d18/ Log: Separate RPython section from pypy/doc/coding-guide.rst. diff --git a/pypy/doc/coding-guide.rst b/pypy/doc/coding-guide.rst --- a/pypy/doc/coding-guide.rst +++ b/pypy/doc/coding-guide.rst @@ -172,296 +172,6 @@ enables the code generator to emit efficient machine level replacements for pure integer objects, for instance. -RPython -================= - -RPython Definition ------------------- - -RPython is a restricted subset of Python that is amenable to static analysis. -Although there are additions to the language and some things might surprisingly -work, this is a rough list of restrictions that should be considered. Note -that there are tons of special cased restrictions that you'll encounter -as you go. The exact definition is "RPython is everything that our translation -toolchain can accept" :) - -.. _`wrapped object`: coding-guide.html#wrapping-rules - -Flow restrictions -------------------------- - -**variables** - - variables should contain values of at most one type as described in - `Object restrictions`_ at each control flow point, that means for - example that joining control paths using the same variable to - contain both a string and a int must be avoided. It is allowed to - mix None (basically with the role of a null pointer) with many other - types: `wrapped objects`, class instances, lists, dicts, strings, etc. - but *not* with int, floats or tuples. - -**constants** - - all module globals are considered constants. Their binding must not - be changed at run-time. Moreover, global (i.e. prebuilt) lists and - dictionaries are supposed to be immutable: modifying e.g. a global - list will give inconsistent results. However, global instances don't - have this restriction, so if you need mutable global state, store it - in the attributes of some prebuilt singleton instance. - - - -**control structures** - - all allowed, ``for`` loops restricted to builtin types, generators - very restricted. - -**range** - - ``range`` and ``xrange`` are identical. ``range`` does not necessarily create an array, - only if the result is modified. It is allowed everywhere and completely - implemented. The only visible difference to CPython is the inaccessibility - of the ``xrange`` fields start, stop and step. - -**definitions** - - run-time definition of classes or functions is not allowed. - -**generators** - - generators are supported, but their exact scope is very limited. you can't - merge two different generator in one control point. - -**exceptions** - -+ fully supported -+ see below `Exception rules`_ for restrictions on exceptions raised by built-in operations - - -Object restrictions -------------------------- - -We are using - -**integer, float, boolean** - - works. - -**strings** - - a lot of, but not all string methods are supported and those that are - supported, not necesarilly accept all arguments. Indexes can be - negative. In case they are not, then you get slightly more efficient - code if the translator can prove that they are non-negative. When - slicing a string it is necessary to prove that the slice start and - stop indexes are non-negative. There is no implicit str-to-unicode cast - anywhere. Simple string formatting using the ``%`` operator works, as long - as the format string is known at translation time; the only supported - formatting specifiers are ``%s``, ``%d``, ``%x``, ``%o``, ``%f``, plus - ``%r`` but only for user-defined instances. Modifiers such as conversion - flags, precision, length etc. are not supported. Moreover, it is forbidden - to mix unicode and strings when formatting. - -**tuples** - - no variable-length tuples; use them to store or return pairs or n-tuples of - values. Each combination of types for elements and length constitute - a separate and not mixable type. - -**lists** - - lists are used as an allocated array. Lists are over-allocated, so list.append() - is reasonably fast. However, if you use a fixed-size list, the code - is more efficient. Annotator can figure out most of the time that your - list is fixed-size, even when you use list comprehension. - Negative or out-of-bound indexes are only allowed for the - most common operations, as follows: - - - *indexing*: - positive and negative indexes are allowed. Indexes are checked when requested - by an IndexError exception clause. - - - *slicing*: - the slice start must be within bounds. The stop doesn't need to, but it must - not be smaller than the start. All negative indexes are disallowed, except for - the [:-1] special case. No step. Slice deletion follows the same rules. - - - *slice assignment*: - only supports ``lst[x:y] = sublist``, if ``len(sublist) == y - x``. - In other words, slice assignment cannot change the total length of the list, - but just replace items. - - - *other operators*: - ``+``, ``+=``, ``in``, ``*``, ``*=``, ``==``, ``!=`` work as expected. - - - *methods*: - append, index, insert, extend, reverse, pop. The index used in pop() follows - the same rules as for *indexing* above. The index used in insert() must be within - bounds and not negative. - -**dicts** - - dicts with a unique key type only, provided it is hashable. Custom - hash functions and custom equality will not be honored. - Use ``rpython.rlib.objectmodel.r_dict`` for custom hash functions. - - -**list comprehensions** - - May be used to create allocated, initialized arrays. - -**functions** - -+ statically called functions may use defaults and a variable number of - arguments (which may be passed as a list instead of a tuple, so write code - that does not depend on it being a tuple). - -+ dynamic dispatch enforces the use of signatures that are equal for all - possible called function, or at least "compatible enough". This - concerns mainly method calls, when the method is overridden or in any - way given different definitions in different classes. It also concerns - the less common case of explicitly manipulated function objects. - Describing the exact compatibility rules is rather involved (but if you - break them, you should get explicit errors from the rtyper and not - obscure crashes.) - -**builtin functions** - - A number of builtin functions can be used. The precise set can be - found in `rpython/annotator/builtin.py`_ (see ``def builtin_xxx()``). - Some builtin functions may be limited in what they support, though. - - ``int, float, str, ord, chr``... are available as simple conversion - functions. Note that ``int, float, str``... have a special meaning as - a type inside of isinstance only. - -**classes** - -+ methods and other class attributes do not change after startup -+ single inheritance is fully supported -+ simple mixins work too, but the mixed in class needs a ``_mixin_ = True`` - class attribute - -+ classes are first-class objects too - -**objects** - - Normal rules apply. Special methods are not honoured, except ``__init__``, - ``__del__`` and ``__iter__``. - -This layout makes the number of types to take care about quite limited. - - -Integer Types -------------------------- - -While implementing the integer type, we stumbled over the problem that -integers are quite in flux in CPython right now. Starting with Python 2.4, -integers mutate into longs on overflow. In contrast, we need -a way to perform wrap-around machine-sized arithmetic by default, while still -being able to check for overflow when we need it explicitly. Moreover, we need -a consistent behavior before and after translation. - -We use normal integers for signed arithmetic. It means that before -translation we get longs in case of overflow, and after translation we get a -silent wrap-around. Whenever we need more control, we use the following -helpers (which live in `rpython/rlib/rarithmetic.py`_): - -**ovfcheck()** - - This special function should only be used with a single arithmetic operation - as its argument, e.g. ``z = ovfcheck(x+y)``. Its intended meaning is to - perform the given operation in overflow-checking mode. - - At run-time, in Python, the ovfcheck() function itself checks the result - and raises OverflowError if it is a ``long``. But the code generators use - ovfcheck() as a hint: they replace the whole ``ovfcheck(x+y)`` expression - with a single overflow-checking addition in C. - -**intmask()** - - This function is used for wrap-around arithmetic. It returns the lower bits - of its argument, masking away anything that doesn't fit in a C "signed long int". - Its purpose is, in Python, to convert from a Python ``long`` that resulted from a - previous operation back to a Python ``int``. The code generators ignore - intmask() entirely, as they are doing wrap-around signed arithmetic all the time - by default anyway. (We have no equivalent of the "int" versus "long int" - distinction of C at the moment and assume "long ints" everywhere.) - -**r_uint** - - In a few cases (e.g. hash table manipulation), we need machine-sized unsigned - arithmetic. For these cases there is the r_uint class, which is a pure - Python implementation of word-sized unsigned integers that silently wrap - around. ("word-sized" and "machine-sized" are used equivalently and mean - the native size, which you get using "unsigned long" in C.) - The purpose of this class (as opposed to helper functions as above) - is consistent typing: both Python and the annotator will propagate r_uint - instances in the program and interpret all the operations between them as - unsigned. Instances of r_uint are special-cased by the code generators to - use the appropriate low-level type and operations. - Mixing of (signed) integers and r_uint in operations produces r_uint that - means unsigned results. To convert back from r_uint to signed integers, use - intmask(). - - -Exception rules ---------------------- - -Exceptions are by default not generated for simple cases.:: - - #!/usr/bin/python - - lst = [1,2,3,4,5] - item = lst[i] # this code is not checked for out-of-bound access - - try: - item = lst[i] - except IndexError: - # complain - -Code with no exception handlers does not raise exceptions (after it has been -translated, that is. When you run it on top of CPython, it may raise -exceptions, of course). By supplying an exception handler, you ask for error -checking. Without, you assure the system that the operation cannot fail. -This rule does not apply to *function calls*: any called function is -assumed to be allowed to raise any exception. - -For example:: - - x = 5.1 - x = x + 1.2 # not checked for float overflow - try: - x = x + 1.2 - except OverflowError: - # float result too big - -But:: - - z = some_function(x, y) # can raise any exception - try: - z = some_other_function(x, y) - except IndexError: - # only catches explicitly-raised IndexErrors in some_other_function() - # other exceptions can be raised, too, and will not be caught here. - -The ovfcheck() function described above follows the same rule: in case of -overflow, it explicitly raise OverflowError, which can be caught anywhere. - -Exceptions explicitly raised or re-raised will always be generated. - -PyPy is debuggable on top of CPython ------------------------------------- - -PyPy has the advantage that it is runnable on standard -CPython. That means, we can run all of PyPy with all exception -handling enabled, so we might catch cases where we failed to -adhere to our implicit assertions. - -.. _`wrapping rules`: -.. _`wrapped`: - - Wrapping rules ============== diff --git a/rpython/doc/rpython.rst b/rpython/doc/rpython.rst new file mode 100644 --- /dev/null +++ b/rpython/doc/rpython.rst @@ -0,0 +1,283 @@ +======= +RPython +======= + +RPython Definition +------------------ + +RPython is a restricted subset of Python that is amenable to static analysis. +Although there are additions to the language and some things might surprisingly +work, this is a rough list of restrictions that should be considered. Note +that there are tons of special cased restrictions that you'll encounter +as you go. The exact definition is "RPython is everything that our translation +toolchain can accept" :) + + +Flow restrictions +------------------------- + +**variables** + + variables should contain values of at most one type as described in + `Object restrictions`_ at each control flow point, that means for + example that joining control paths using the same variable to + contain both a string and a int must be avoided. It is allowed to + mix None (basically with the role of a null pointer) with many other + types: wrapped objects, class instances, lists, dicts, strings, etc. + but *not* with int, floats or tuples. + +**constants** + + all module globals are considered constants. Their binding must not + be changed at run-time. Moreover, global (i.e. prebuilt) lists and + dictionaries are supposed to be immutable: modifying e.g. a global + list will give inconsistent results. However, global instances don't + have this restriction, so if you need mutable global state, store it + in the attributes of some prebuilt singleton instance. + +**control structures** + + all allowed, ``for`` loops restricted to builtin types, generators + very restricted. + +**range** + + ``range`` and ``xrange`` are identical. ``range`` does not necessarily create an array, + only if the result is modified. It is allowed everywhere and completely + implemented. The only visible difference to CPython is the inaccessibility + of the ``xrange`` fields start, stop and step. + +**definitions** + + run-time definition of classes or functions is not allowed. + +**generators** + + generators are supported, but their exact scope is very limited. you can't + merge two different generator in one control point. + +**exceptions** + ++ fully supported ++ see below `Exception rules`_ for restrictions on exceptions raised by built-in operations + + +Object restrictions +------------------------- + +We are using + +**integer, float, boolean** + + works. + +**strings** + + a lot of, but not all string methods are supported and those that are + supported, not necesarilly accept all arguments. Indexes can be + negative. In case they are not, then you get slightly more efficient + code if the translator can prove that they are non-negative. When + slicing a string it is necessary to prove that the slice start and + stop indexes are non-negative. There is no implicit str-to-unicode cast + anywhere. Simple string formatting using the ``%`` operator works, as long + as the format string is known at translation time; the only supported + formatting specifiers are ``%s``, ``%d``, ``%x``, ``%o``, ``%f``, plus + ``%r`` but only for user-defined instances. Modifiers such as conversion + flags, precision, length etc. are not supported. Moreover, it is forbidden + to mix unicode and strings when formatting. + +**tuples** + + no variable-length tuples; use them to store or return pairs or n-tuples of + values. Each combination of types for elements and length constitute + a separate and not mixable type. + +**lists** + + lists are used as an allocated array. Lists are over-allocated, so list.append() + is reasonably fast. However, if you use a fixed-size list, the code + is more efficient. Annotator can figure out most of the time that your + list is fixed-size, even when you use list comprehension. + Negative or out-of-bound indexes are only allowed for the + most common operations, as follows: + + - *indexing*: + positive and negative indexes are allowed. Indexes are checked when requested + by an IndexError exception clause. + + - *slicing*: + the slice start must be within bounds. The stop doesn't need to, but it must + not be smaller than the start. All negative indexes are disallowed, except for + the [:-1] special case. No step. Slice deletion follows the same rules. + + - *slice assignment*: + only supports ``lst[x:y] = sublist``, if ``len(sublist) == y - x``. + In other words, slice assignment cannot change the total length of the list, + but just replace items. + + - *other operators*: + ``+``, ``+=``, ``in``, ``*``, ``*=``, ``==``, ``!=`` work as expected. + + - *methods*: + append, index, insert, extend, reverse, pop. The index used in pop() follows + the same rules as for *indexing* above. The index used in insert() must be within + bounds and not negative. + +**dicts** + + dicts with a unique key type only, provided it is hashable. Custom + hash functions and custom equality will not be honored. + Use ``rpython.rlib.objectmodel.r_dict`` for custom hash functions. + +**list comprehensions** + + May be used to create allocated, initialized arrays. + +**functions** + ++ statically called functions may use defaults and a variable number of + arguments (which may be passed as a list instead of a tuple, so write code + that does not depend on it being a tuple). + ++ dynamic dispatch enforces the use of signatures that are equal for all + possible called function, or at least "compatible enough". This + concerns mainly method calls, when the method is overridden or in any + way given different definitions in different classes. It also concerns + the less common case of explicitly manipulated function objects. + Describing the exact compatibility rules is rather involved (but if you + break them, you should get explicit errors from the rtyper and not + obscure crashes.) + +**builtin functions** + + A number of builtin functions can be used. The precise set can be + found in `rpython/annotator/builtin.py`_ (see ``def builtin_xxx()``). + Some builtin functions may be limited in what they support, though. + + ``int, float, str, ord, chr``... are available as simple conversion + functions. Note that ``int, float, str``... have a special meaning as + a type inside of isinstance only. + +**classes** + ++ methods and other class attributes do not change after startup ++ single inheritance is fully supported ++ simple mixins work too, but the mixed in class needs a ``_mixin_ = True`` + class attribute + ++ classes are first-class objects too + +**objects** + + Normal rules apply. Special methods are not honoured, except ``__init__``, + ``__del__`` and ``__iter__``. + +This layout makes the number of types to take care about quite limited. + + +Integer Types +------------------------- + +While implementing the integer type, we stumbled over the problem that +integers are quite in flux in CPython right now. Starting with Python 2.4, +integers mutate into longs on overflow. In contrast, we need +a way to perform wrap-around machine-sized arithmetic by default, while still +being able to check for overflow when we need it explicitly. Moreover, we need +a consistent behavior before and after translation. + +We use normal integers for signed arithmetic. It means that before +translation we get longs in case of overflow, and after translation we get a +silent wrap-around. Whenever we need more control, we use the following +helpers (which live in `rpython/rlib/rarithmetic.py`_): + +**ovfcheck()** + + This special function should only be used with a single arithmetic operation + as its argument, e.g. ``z = ovfcheck(x+y)``. Its intended meaning is to + perform the given operation in overflow-checking mode. + + At run-time, in Python, the ovfcheck() function itself checks the result + and raises OverflowError if it is a ``long``. But the code generators use + ovfcheck() as a hint: they replace the whole ``ovfcheck(x+y)`` expression + with a single overflow-checking addition in C. + +**intmask()** + + This function is used for wrap-around arithmetic. It returns the lower bits + of its argument, masking away anything that doesn't fit in a C "signed long int". + Its purpose is, in Python, to convert from a Python ``long`` that resulted from a + previous operation back to a Python ``int``. The code generators ignore + intmask() entirely, as they are doing wrap-around signed arithmetic all the time + by default anyway. (We have no equivalent of the "int" versus "long int" + distinction of C at the moment and assume "long ints" everywhere.) + +**r_uint** + + In a few cases (e.g. hash table manipulation), we need machine-sized unsigned + arithmetic. For these cases there is the r_uint class, which is a pure + Python implementation of word-sized unsigned integers that silently wrap + around. ("word-sized" and "machine-sized" are used equivalently and mean + the native size, which you get using "unsigned long" in C.) + The purpose of this class (as opposed to helper functions as above) + is consistent typing: both Python and the annotator will propagate r_uint + instances in the program and interpret all the operations between them as + unsigned. Instances of r_uint are special-cased by the code generators to + use the appropriate low-level type and operations. + Mixing of (signed) integers and r_uint in operations produces r_uint that + means unsigned results. To convert back from r_uint to signed integers, use + intmask(). + + +Exception rules +--------------------- + +Exceptions are by default not generated for simple cases.:: + + #!/usr/bin/python + + lst = [1,2,3,4,5] + item = lst[i] # this code is not checked for out-of-bound access + + try: + item = lst[i] + except IndexError: + # complain + +Code with no exception handlers does not raise exceptions (after it has been +translated, that is. When you run it on top of CPython, it may raise +exceptions, of course). By supplying an exception handler, you ask for error +checking. Without, you assure the system that the operation cannot fail. +This rule does not apply to *function calls*: any called function is +assumed to be allowed to raise any exception. + +For example:: + + x = 5.1 + x = x + 1.2 # not checked for float overflow + try: + x = x + 1.2 + except OverflowError: + # float result too big + +But:: + + z = some_function(x, y) # can raise any exception + try: + z = some_other_function(x, y) + except IndexError: + # only catches explicitly-raised IndexErrors in some_other_function() + # other exceptions can be raised, too, and will not be caught here. + +The ovfcheck() function described above follows the same rule: in case of +overflow, it explicitly raise OverflowError, which can be caught anywhere. + +Exceptions explicitly raised or re-raised will always be generated. + + +PyPy is debuggable on top of CPython +------------------------------------ + +PyPy has the advantage that it is runnable on standard +CPython. That means, we can run all of PyPy with all exception +handling enabled, so we might catch cases where we failed to +adhere to our implicit assertions. From noreply at buildbot.pypy.org Sat Feb 23 16:47:44 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Sat, 23 Feb 2013 16:47:44 +0100 (CET) Subject: [pypy-commit] pypy rpython-doc: Add graphviz extension. Message-ID: <20130223154744.66FFB1C47A9@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: rpython-doc Changeset: r61683:b1f6262a1111 Date: 2013-02-23 15:48 +0100 http://bitbucket.org/pypy/pypy/changeset/b1f6262a1111/ Log: Add graphviz extension. diff --git a/rpython/doc/conf.py b/rpython/doc/conf.py --- a/rpython/doc/conf.py +++ b/rpython/doc/conf.py @@ -25,7 +25,7 @@ # Add any Sphinx extension module names here, as strings. They can be extensions # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. -extensions = [] +extensions = ['sphinx.ext.graphviz'] # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] From noreply at buildbot.pypy.org Sat Feb 23 16:47:45 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Sat, 23 Feb 2013 16:47:45 +0100 (CET) Subject: [pypy-commit] pypy rpython-doc: Move some images with their source files to rpython/doc. Message-ID: <20130223154745.B788B1C4828@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: rpython-doc Changeset: r61684:cd4c1b26cf89 Date: 2013-02-23 15:50 +0100 http://bitbucket.org/pypy/pypy/changeset/cd4c1b26cf89/ Log: Move some images with their source files to rpython/doc. diff --git a/pypy/doc/image/bpnn_update.png b/rpython/doc/_static/bpnn_update.png rename from pypy/doc/image/bpnn_update.png rename to rpython/doc/_static/bpnn_update.png diff --git a/pypy/doc/image/pypy-translation-0.9.graffle b/rpython/doc/_static/pypy-translation-0.9.graffle rename from pypy/doc/image/pypy-translation-0.9.graffle rename to rpython/doc/_static/pypy-translation-0.9.graffle diff --git a/pypy/doc/image/pypy-translation-0.9.png b/rpython/doc/_static/pypy-translation-0.9.png rename from pypy/doc/image/pypy-translation-0.9.png rename to rpython/doc/_static/pypy-translation-0.9.png diff --git a/pypy/doc/image/translation-detail-0.9.graffle b/rpython/doc/_static/translation-detail-0.9.graffle rename from pypy/doc/image/translation-detail-0.9.graffle rename to rpython/doc/_static/translation-detail-0.9.graffle diff --git a/pypy/doc/image/translation-detail-0.9.png b/rpython/doc/_static/translation-detail-0.9.png rename from pypy/doc/image/translation-detail-0.9.png rename to rpython/doc/_static/translation-detail-0.9.png diff --git a/pypy/doc/image/translation-greyscale-small.pdf b/rpython/doc/_static/translation-greyscale-small.pdf rename from pypy/doc/image/translation-greyscale-small.pdf rename to rpython/doc/_static/translation-greyscale-small.pdf diff --git a/pypy/doc/image/translation-greyscale-small.png b/rpython/doc/_static/translation-greyscale-small.png rename from pypy/doc/image/translation-greyscale-small.png rename to rpython/doc/_static/translation-greyscale-small.png diff --git a/pypy/doc/image/translation-greyscale-small.sxd b/rpython/doc/_static/translation-greyscale-small.sxd rename from pypy/doc/image/translation-greyscale-small.sxd rename to rpython/doc/_static/translation-greyscale-small.sxd diff --git a/pypy/doc/image/translation.pdf b/rpython/doc/_static/translation.pdf rename from pypy/doc/image/translation.pdf rename to rpython/doc/_static/translation.pdf diff --git a/pypy/doc/image/translation.sxd b/rpython/doc/_static/translation.sxd rename from pypy/doc/image/translation.sxd rename to rpython/doc/_static/translation.sxd diff --git a/rpython/doc/translation.rst b/rpython/doc/translation.rst --- a/rpython/doc/translation.rst +++ b/rpython/doc/translation.rst @@ -96,7 +96,7 @@ The following figure gives a simplified overview (`PDF color version`_): - .. image:: image/translation-greyscale-small.png + .. image:: _static/translation-greyscale-small.png .. _`PDF color version`: https://bitbucket.org/pypy/pypy/raw/default/pypy/doc/image/translation.pdf @@ -130,7 +130,7 @@ inspect the graphs at various stages of the translation process (very useful to try to work out why things are breaking). It looks like this: - .. image:: image/bpnn_update.png + .. image:: _static/bpnn_update.png It is recommended to play with ``python bin/translatorshell.py`` on a few examples to get an idea of the structure of flow graphs. The following describes @@ -720,7 +720,7 @@ The following image summarizes the various parts of the toolchain as of the 0.9 release, with the default translation to C highlighted: -.. image:: image/pypy-translation-0.9.png +.. image:: _static/pypy-translation-0.9.png :align: center A detail that has not yet been emphasized is the interaction of the @@ -734,7 +734,7 @@ following picture attempts to summarize the components involved in performing each step of the default translation process: -.. image:: image/translation-detail-0.9.png +.. image:: _static/translation-detail-0.9.png :align: center .. _`low-level helpers`: glossary.html#low-level-helper From noreply at buildbot.pypy.org Sat Feb 23 16:47:47 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Sat, 23 Feb 2013 16:47:47 +0100 (CET) Subject: [pypy-commit] pypy rpython-doc: Make use of sphinx' extlinks extension. Message-ID: <20130223154747.0050B1C4829@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: rpython-doc Changeset: r61685:596e8be030a5 Date: 2013-02-23 16:46 +0100 http://bitbucket.org/pypy/pypy/changeset/596e8be030a5/ Log: Make use of sphinx' extlinks extension. diff --git a/rpython/doc/conf.py b/rpython/doc/conf.py --- a/rpython/doc/conf.py +++ b/rpython/doc/conf.py @@ -25,7 +25,7 @@ # Add any Sphinx extension module names here, as strings. They can be extensions # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. -extensions = ['sphinx.ext.graphviz'] +extensions = ['sphinx.ext.extlinks', 'sphinx.ext.graphviz'] # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] @@ -240,3 +240,5 @@ # How to display URL addresses: 'footnote', 'no', or 'inline'. #texinfo_show_urls = 'footnote' + +extlinks = {'source': ('https://bitbucket.org/pypy/pypy/src/default/%s', '')} diff --git a/rpython/doc/garbage_collection.rst b/rpython/doc/garbage_collection.rst --- a/rpython/doc/garbage_collection.rst +++ b/rpython/doc/garbage_collection.rst @@ -42,7 +42,7 @@ Two arenas of equal size, with only one arena in use and getting filled with new objects. When the arena is full, the live objects are copied into the other arena using Cheney's algorithm. The old arena is then -cleared. See `rpython/memory/gc/semispace.py`_. +cleared. See :source:`rpython/memory/gc/semispace.py`. On Unix the clearing is done by reading ``/dev/zero`` into the arena, which is extremely memory efficient at least on Linux: it lets the @@ -55,7 +55,7 @@ Generational GC --------------- -This is a two-generations GC. See `rpython/memory/gc/generation.py`_. +This is a two-generations GC. See :source:`rpython/memory/gc/generation.py`. It is implemented as a subclass of the Semispace copying collector. It adds a nursery, which is a chunk of the current semispace. Its size is @@ -86,7 +86,7 @@ Each generation is collected much less often than the previous one. The division of the generations is slightly more complicated than just nursery / semispace / external; see the diagram at the start of the -source code, in `rpython/memory/gc/hybrid.py`_. +source code, in :source:`rpython/memory/gc/hybrid.py`. Mark & Compact GC ----------------- @@ -161,7 +161,7 @@ to the old stage. The dying case 2 objects are immediately freed. - The old stage is an area of memory containing old (small) objects. It - is handled by `rpython/memory/gc/minimarkpage.py`_. It is organized + is handled by :source:`rpython/memory/gc/minimarkpage.py`. It is organized as "arenas" of 256KB or 512KB, subdivided into "pages" of 4KB or 8KB. Each page can either be free, or contain small objects of all the same size. Furthermore at any point in time each object location can be @@ -209,5 +209,3 @@ next minor collection, we move it there, and so its id() and hash() are preserved. If the object dies then the pre-reserved location becomes free garbage, to be collected at the next major collection. - -.. include:: _ref.txt diff --git a/rpython/doc/rlib.rst b/rpython/doc/rlib.rst --- a/rpython/doc/rlib.rst +++ b/rpython/doc/rlib.rst @@ -7,18 +7,18 @@ .. contents:: -This page lists some of the modules in `rpython/rlib`_ together with some hints +This page lists some of the modules in :source:`rpython/rlib` together with some hints for what they can be used for. The modules here will make up some general library useful for RPython programs (since most of the standard library modules are not RPython). Most of these modules are somewhat rough still and are likely to change at some point. Usually it is useful to look at the tests in -`rpython/rlib/test`_ to get an impression of how to use a module. +:source:`rpython/rlib/test` to get an impression of how to use a module. ``listsort`` ============ -The `rpython/rlib/listsort.py`_ module contains an implementation of the timsort sorting algorithm +The :source:`rpython/rlib/listsort.py` module contains an implementation of the timsort sorting algorithm (the sort method of lists is not RPython). To use it, subclass from the ``listsort.TimSort`` class and override the ``lt`` method to change the comparison behaviour. The constructor of ``TimSort`` takes a list as an @@ -30,7 +30,7 @@ ``nonconst`` ============ -The `rpython/rlib/nonconst.py`_ module is useful mostly for tests. The `flow object space`_ and +The :source:`rpython/rlib/nonconst.py` module is useful mostly for tests. The `flow object space`_ and the `annotator`_ do quite some constant folding, which is sometimes not desired in a test. To prevent constant folding on a certain value, use the ``NonConst`` class. The constructor of ``NonConst`` takes an arbitrary value. The instance of @@ -44,7 +44,7 @@ ``objectmodel`` =============== -The `rpython/rlib/objectmodel.py`_ module is a mixed bag of various functionality. Some of the +The :source:`rpython/rlib/objectmodel.py` module is a mixed bag of various functionality. Some of the more useful ones are: ``ComputedIntSymbolic``: @@ -94,7 +94,7 @@ ``rarithmetic`` =============== -The `rpython/rlib/rarithmetic.py`_ module contains functionality to handle the small differences +The :source:`rpython/rlib/rarithmetic.py` module contains functionality to handle the small differences in the behaviour of arithmetic code in regular Python and RPython code. Most of them are already described in the `coding guide`_ @@ -104,7 +104,7 @@ ``rbigint`` =========== -The `rpython/rlib/rbigint.py`_ module contains a full RPython implementation of the Python ``long`` +The :source:`rpython/rlib/rbigint.py` module contains a full RPython implementation of the Python ``long`` type (which itself is not supported in RPython). The ``rbigint`` class contains that implementation. To construct ``rbigint`` instances use the static methods ``fromint``, ``frombool``, ``fromfloat`` and ``fromdecimalstr``. To convert back @@ -118,7 +118,7 @@ ``rrandom`` =========== -The `rpython/rlib/rrandom.py`_ module contains an implementation of the mersenne twister random +The :source:`rpython/rlib/rrandom.py` module contains an implementation of the mersenne twister random number generator. It contains one class ``Random`` which most importantly has a ``random`` method which returns a pseudo-random floating point number between 0.0 and 1.0. @@ -126,7 +126,7 @@ ``rsocket`` =========== -The `rpython/rlib/rsocket.py`_ module contains an RPython implementation of the functionality of +The :source:`rpython/rlib/rsocket.py` module contains an RPython implementation of the functionality of the socket standard library with a slightly different interface. The difficulty with the Python socket API is that addresses are not "well-typed" objects: depending on the address family they are tuples, or strings, and @@ -137,7 +137,7 @@ ``streamio`` ============ -The `rpython/rlib/streamio.py`_ contains an RPython stream I/O implementation (which was started +The :source:`rpython/rlib/streamio.py` contains an RPython stream I/O implementation (which was started by Guido van Rossum as `sio.py`_ in the CPython sandbox as a prototype for the upcoming new file implementation in Python 3000). @@ -146,7 +146,7 @@ ``unroll`` ========== -The `rpython/rlib/unroll.py`_ module most importantly contains the function ``unrolling_iterable`` +The :source:`rpython/rlib/unroll.py` module most importantly contains the function ``unrolling_iterable`` which wraps an iterator. Looping over the iterator in RPython code will not produce a loop in the resulting flow graph but will unroll the loop instead. @@ -154,7 +154,7 @@ ``parsing`` =========== -The `rpython/rlib/parsing/`_ module is a still in-development module to generate tokenizers and +The :source:`rpython/rlib/parsing/` module is a still in-development module to generate tokenizers and parsers in RPython. It is still highly experimental and only really used by the `Prolog interpreter`_ (although in slightly non-standard ways). The easiest way to specify a tokenizer/grammar is to write it down using regular expressions and @@ -295,7 +295,7 @@ The parsing process builds up a tree consisting of instances of ``Symbol`` and ``Nonterminal``, the former corresponding to tokens, the latter to nonterminal -symbols. Both classes live in the `rpython/rlib/parsing/tree.py`_ module. You can use +symbols. Both classes live in the :source:`rpython/rlib/parsing/tree.py` module. You can use the ``view()`` method ``Nonterminal`` instances to get a pygame view of the parse tree. @@ -310,7 +310,7 @@ ++++++++ To write tree visitors for the parse trees that are RPython, there is a special -baseclass ``RPythonVisitor`` in `rpython/rlib/parsing/tree.py`_ to use. If your +baseclass ``RPythonVisitor`` in :source:`rpython/rlib/parsing/tree.py` to use. If your class uses this, it will grow a ``dispatch(node)`` method, that calls an appropriate ``visit_`` method, depending on the ``node`` argument. Here the is replaced by the ``symbol`` attribute of the visited node. @@ -648,5 +648,3 @@ .. _`Prolog interpreter`: https://bitbucket.org/cfbolz/pyrolog/ .. _`json format`: http://www.json.org - -.. include:: _ref.txt diff --git a/rpython/doc/rtyper.rst b/rpython/doc/rtyper.rst --- a/rpython/doc/rtyper.rst +++ b/rpython/doc/rtyper.rst @@ -4,7 +4,7 @@ .. contents:: -The RPython Typer lives in the directory `rpython/rtyper/`_. +The RPython Typer lives in the directory :source:`rpython/rtyper/`. Overview @@ -66,7 +66,7 @@ each operation. In both cases the analysis of an operation depends on the annotations of its input arguments. This is reflected in the usage of the same ``__extend__`` syntax in the source files (compare e.g. -`rpython/annotator/binaryop.py`_ and `rpython/rtyper/rint.py`_). +:source:`rpython/annotator/binaryop.py` and :source:`rpython/rtyper/rint.py`). The analogy stops here, though: while it runs, the Annotator is in the middle of computing the annotations, so it might need to reflow and generalize until @@ -104,7 +104,7 @@ implementations for the same high-level operations. This is the reason for turning representations into explicit objects. -The base Repr class is defined in `rpython/rtyper/rmodel.py`_. Most of the +The base Repr class is defined in :source:`rpython/rtyper/rmodel.py`. Most of the ``rpython/r*.py`` files define one or a few subclasses of Repr. The method getrepr() of the RTyper will build and cache a single Repr instance per SomeXxx() instance; moreover, two SomeXxx() instances that are equal get the @@ -131,9 +131,9 @@ The RPython Typer uses a standard low-level model which we believe can correspond rather directly to various target languages such as C. This model is implemented in the first part of -`rpython/rtyper/lltypesystem/lltype.py`_. +:source:`rpython/rtyper/lltypesystem/lltype.py`. -The second part of `rpython/rtyper/lltypesystem/lltype.py`_ is a runnable +The second part of :source:`rpython/rtyper/lltypesystem/lltype.py` is a runnable implementation of these types, for testing purposes. It allows us to write and test plain Python code using a malloc() function to obtain and manipulate structures and arrays. This is useful for example to implement and test @@ -191,7 +191,7 @@ types like list in this elementary world. The ``malloc()`` function is a kind of placeholder, which must eventually be provided by the code generator for the target platform; but as we have just seen its Python implementation in -`rpython/rtyper/lltypesystem/lltype.py`_ works too, which is primarily useful for +:source:`rpython/rtyper/lltypesystem/lltype.py` works too, which is primarily useful for testing, interactive exploring, etc. The argument to ``malloc()`` is the structure type directly, but it returns a @@ -316,7 +316,7 @@ with care: the bigger structure of which they are part of could be freed while the Ptr to the substructure is still in use. In general, it is a good idea to avoid passing around pointers to inlined substructures of malloc()ed structures. -(The testing implementation of `rpython/rtyper/lltypesystem/lltype.py`_ checks to some +(The testing implementation of :source:`rpython/rtyper/lltypesystem/lltype.py` checks to some extent that you are not trying to use a pointer to a structure after its container has been freed, using weak references. But pointers to non-GC structures are not officially meant to be weak references: using them after what @@ -429,7 +429,7 @@ change needed to the Annotator to allow it to perform type inference of our very-low-level snippets of code. -See for example `rpython/rtyper/rlist.py`_. +See for example :source:`rpython/rtyper/rlist.py`. .. _`oo type`: @@ -441,10 +441,10 @@ targeting low level backends such as C, but it is not good enough for targeting higher level backends such as .NET CLI or Java JVM, so a new object oriented model has been introduced. This model is -implemented in the first part of `rpython/rtyper/ootypesystem/ootype.py`_. +implemented in the first part of :source:`rpython/rtyper/ootypesystem/ootype.py`. As for the low-level typesystem, the second part of -`rpython/rtyper/ootypesystem/ootype.py`_ is a runnable implementation of +:source:`rpython/rtyper/ootypesystem/ootype.py` is a runnable implementation of these types, for testing purposes. @@ -751,7 +751,7 @@ The LLInterpreter is a simple piece of code that is able to interpret flow graphs. This is very useful for testing purposes, especially if you work on the RPython Typer. The most useful interface for it is the ``interpret`` -function in the file `rpython/rtyper/test/test_llinterp.py`_. It takes as +function in the file :source:`rpython/rtyper/test/test_llinterp.py`. It takes as arguments a function and a list of arguments with which the function is supposed to be called. Then it generates the flow graph, annotates it according to the types of the arguments you passed to it and runs the @@ -791,5 +791,3 @@ assert res == ~3 .. _annotator: translation.html#the-annotation-pass - -.. include:: _ref.txt diff --git a/rpython/doc/translation.rst b/rpython/doc/translation.rst --- a/rpython/doc/translation.rst +++ b/rpython/doc/translation.rst @@ -90,7 +90,7 @@ (although these steps are not quite as distinct as you might think from this presentation). -There is an `interactive interface`_ called `rpython/bin/translatorshell.py`_ to the +There is an `interactive interface`_ called :source:`rpython/bin/translatorshell.py` to the translation process which allows you to interactively work through these stages. @@ -116,7 +116,7 @@ which are the basic data structures of the translation process. -All these types are defined in `rpython/flowspace/model.py`_ (which is a rather +All these types are defined in :source:`rpython/flowspace/model.py` (which is a rather important module in the PyPy source base, to reinforce the point). The flow graph of a function is represented by the class ``FunctionGraph``. @@ -744,5 +744,3 @@ translation step to declare that it needs to be able to call each of a collection of functions (which may refer to each other in a mutually recursive fashion) and annotate and rtype them all at once. - -.. include:: _ref.txt From noreply at buildbot.pypy.org Sat Feb 23 18:05:07 2013 From: noreply at buildbot.pypy.org (stefanor) Date: Sat, 23 Feb 2013 18:05:07 +0100 (CET) Subject: [pypy-commit] pypy default: Remove unused function def that caused an IndentationError if we even tried to byte-compile it Message-ID: <20130223170507.7DB171C4828@cobra.cs.uni-duesseldorf.de> Author: Stefano Rivera Branch: Changeset: r61686:d2124ec84344 Date: 2013-02-23 19:04 +0200 http://bitbucket.org/pypy/pypy/changeset/d2124ec84344/ Log: Remove unused function def that caused an IndentationError if we even tried to byte-compile it diff --git a/rpython/translator/goal/old_queries.py b/rpython/translator/goal/old_queries.py --- a/rpython/translator/goal/old_queries.py +++ b/rpython/translator/goal/old_queries.py @@ -414,7 +414,6 @@ links = 0 ops = 0 count = Counter() - def visit(block): for block in graph.iterblocks(): count.blocks += 1 count.ops += len(block.operations) From noreply at buildbot.pypy.org Sat Feb 23 18:10:11 2013 From: noreply at buildbot.pypy.org (stefanor) Date: Sat, 23 Feb 2013 18:10:11 +0100 (CET) Subject: [pypy-commit] pypy default: Actually, kill old_queries, it's already dead Message-ID: <20130223171011.D345D1C008F@cobra.cs.uni-duesseldorf.de> Author: Stefano Rivera Branch: Changeset: r61687:254255f6e583 Date: 2013-02-23 19:09 +0200 http://bitbucket.org/pypy/pypy/changeset/254255f6e583/ Log: Actually, kill old_queries, it's already dead diff --git a/rpython/translator/goal/old_queries.py b/rpython/translator/goal/old_queries.py deleted file mode 100644 --- a/rpython/translator/goal/old_queries.py +++ /dev/null @@ -1,482 +0,0 @@ -# functions to query information out of the translator and annotator from the debug prompt of translate -import types -import re - -import rpython.annotator.model as annmodel -import rpython.flowspace.model as flowmodel - - -class typerep(object): - - def __init__(self, x): - self.typ = getattr(x, '__class__', type(x)) - self.bound = None - if hasattr(x, 'im_self'): - self.bound = x.im_self is not None - elif hasattr(x, '__self__'): - self.bound = x.__self__ is not None - - def __hash__(self): - return hash(self.typ) - - def __cmp__(self, other): - return cmp((self.typ.__name__, self.bound, self.typ), (other.typ.__name__, other.bound, other.typ)) - - def __str__(self): - if self.bound is None: - s = self.typ.__name__ - elif self.bound: - s = 'bound-%s' % self.typ.__name__ - else: - s = 'unbound-%s' % self.typ.__name__ - - if self.typ.__module__ == '__builtin__': - s = "*%s*" % s - - return s - -def typereps(bunch): - t = dict.fromkeys([typerep(x) for x in bunch]).keys() - t.sort() - return t - -def roots(classes): - # find independent hierarchy roots in classes, - # preserve None if it's part of classes - work = list(classes) - res = [] - - notbound = False - - while None in work: - work.remove(None) - notbound = True - - if len(work) == 1: - return notbound, classes[0] - - while work: - cand = work.pop() - for cls in work: - if issubclass(cls, cand): - continue - if issubclass(cand, cls): - cand = cls - continue - res.append(cand) - work = [cls for cls in work if not issubclass(cls, cand)] - - - for x in res: - for y in res: - if x != y: - assert not issubclass(x, y), "%s %s %s" % (classes, x,y) - assert not issubclass(y, x), "%s %s %s" % (classes, x,y) - - return notbound, tuple(res) - -def callablereps(bunch): - callables = [func for clsdef, func in bunch] - classes = [clsdef and clsdef.cls for clsdef, func in bunch] - return roots(classes), tuple(typereps(callables)) - -def prettyfunc(func): - descr = "(%s:%s)" % (getattr(func, '__module__', None) or '?', func.func_code.co_firstlineno) - funcname = getattr(func, '__name__', None) or 'UNKNOWN' - cls = getattr(func, 'class_', None) - if cls: - funcname = "%s.%s" % (cls.__name__, funcname) - return descr+funcname - -def prettycallable((cls, obj)): - if cls is None or cls == (True, ()): - cls = None - else: - notbound = False - if isinstance(cls, tuple) and isinstance(cls[0], bool): - notbound, cls = cls - if isinstance(cls, tuple): - cls = "[%s]" % '|'.join([x.__name__ for x in cls]) - else: - cls = cls.__name__ - if notbound: - cls = "_|%s" % cls - - if isinstance(obj, types.FunctionType): - obj = prettyfunc(obj) - elif isinstance(obj, tuple): - obj = "[%s]" % '|'.join([str(x) for x in obj]) - else: - obj = str(obj) - if obj.startswith('<'): - obj = obj[1:-1] - - if cls is None: - return str(obj) - else: - return "%s::%s" % (cls, obj) - - -def prettybunch(bunch): - if len(bunch) == 1: - parts = ["one", iter(bunch).next()] - else: - parts = ["of type(s)"] + typereps(bunch) - return ' '.join(map(str, parts)) - -def pbcaccess(translator): - annotator = translator.annotator - for inf in annotator.getpbcaccesssets().root_info.itervalues(): - objs = inf.objects - print len(objs), prettybunch(objs), inf.attrs.keys() - -# PBCs -def pbcs(translator): - bk = translator.annotator.bookkeeper - xs = bk.pbccache.keys() - funcs = [x for x in xs if isinstance(x, types.FunctionType)] - staticmethods = [x for x in xs if isinstance(x, staticmethod)] - binstancemethods = [x for x in xs if isinstance(x, types.MethodType) and x.im_self] - ubinstancemethods = [x for x in xs if isinstance(x, types.MethodType) and not x.im_self] - typs = [x for x in xs if isinstance(x, (type, types.ClassType))] - rest = [x for x in xs if not isinstance(x, (types.FunctionType, staticmethod, types.MethodType, type, types.ClassType))] - for objs in (funcs, staticmethods, binstancemethods, ubinstancemethods, typs, rest): - print len(objs), prettybunch(objs) - -# mutable captured "constants") -def mutables(translator): - bk = translator.annotator.bookkeeper - xs = bk.seen_mutable.keys() - print len(xs), prettybunch(xs) - -def prettypatt(patts): - accum = [] - patts.sort() - for (sh_cnt, sh_ks, sh_st, sh_stst) in patts: - arg = [] - arg.append("+%d" % sh_cnt) - for kw in sh_ks: - arg.append("%s=" % kw) - if sh_st: - arg.append('*') - if sh_stst: - arg.append('**') - accum.append("(%s)" % ', '.join(arg)) - return ' '.join(accum) - -def pbccallsanity(translator): - callb = translator.annotator.getpbccallables() - bk = translator.annotator.bookkeeper - typs = [x for x in callb if isinstance(x, (type, types.ClassType))] - for t in typs: - assert len(callb[t]) == 1 - assert callb[t] == {(None,t): True} - print len(typs), "of ",prettycallable(callablereps([(None, Exception), (None, object)])) - ubm = [x for x in callb if isinstance(x, types.MethodType) and x.im_self is None] - assert len(ubm) == 0 - bm = [x for x in callb if isinstance(x, types.MethodType) and x.im_self is not None] - frompbc = 0 - notfrompbc = [] - for b in bm: - assert len(callb[b]) == 1 - assert callb[b] == {(None,b): True} - if b.im_class in bk.pbctypes or (b.im_class is None and b.im_self in bk.pbccache): - frompbc += 1 - else: - notfrompbc.append(b) - class A: - def m(): - pass - print frompbc, "of", prettycallable(callablereps([(None, A().m)])), "from PBCs" - print len(bm)-frompbc, "of", prettycallable(callablereps([(None, A().m)])), "not from PBCs" - if len(notfrompbc) < 40: - for b in notfrompbc: - print " "*4, prettycallable((None, b)) - fs = [x for x in callb if isinstance(x, types.FunctionType)] - assert len(fs) + len(typs) + frompbc + len(notfrompbc) == len(callb) - plain = [] - r = [] - for x in fs: - if len(callb[x]) == 1 and callb[x].keys()[0][0] == None: - r.extend(callb[x].keys()) - plain.append(x) - print len(plain), "of", prettycallable(callablereps(r)) - r = [] - for x in fs: - if x not in plain and len(callb[x]) == 1: - r.extend(callb[x].keys()) - print len(r), "of", prettycallable(callablereps(r)) - r = [] - b_nb = [] - for x in fs: - if len(callb[x]) == 2 and [1 for clsdef, f in callb[x].keys() if clsdef is None]: - r.extend(callb[x].keys()) - b_nb.append(x) - print len(r), "of", prettycallable(callablereps(r)) - print "- other -" - for x in fs: - if len(callb[x]) >= 2 and x not in b_nb: - print ' '.join([prettycallable((classdef and classdef.cls, func)) for (classdef,func) in callb[x].keys()]) - -def pretty_els(objs): - accum = [] - for classdef, obj in objs: - cls = classdef and classdef.cls - accum.append(prettycallable((cls, obj))) - els = ' '.join(accum) - if len(accum) == 1: - return els - else: - return "{%s}" % els - -def pbccall(translator): - fams = translator.annotator.getpbccallfamilies().root_info.itervalues() - one_pattern_fams = {} - rest = [] - for fam in fams: - shapes = fam.patterns - - if len(shapes) != 1: - rest.append((len(fam.objects), fam.objects, shapes.keys())) - else: - kinds = callablereps(fam.objects) - - flavor = tuple(kinds), shapes.keys()[0] - - cntrs = one_pattern_fams.setdefault(flavor, [0,0]) - cntrs[0] += 1 - cntrs[1] += len(fam.objects) - - def pretty_nfam(nfam): - if nfam == 1: - return "1 family" - else: - return "%d families" % nfam - - def pretty_nels(kinds, nels, nfam): - if nels == 1 or nels == nfam: - return "one %s" % prettycallable(kinds) - else: - return "in total %d %s" % (nels, prettycallable(kinds)) - - items = one_pattern_fams.items() - - items.sort(lambda a,b: cmp((a[0][1],a[1][1]), (b[0][1],b[1][1]))) # sort by pattern and then by els - - for (kinds, patt), (nfam, nels) in items: - print pretty_nfam(nfam), "with", pretty_nels(kinds, nels, nfam), "with one call-pattern:", prettypatt([patt]) - - print "- many patterns -" - - manycallb = False - rest.sort(lambda a,b: cmp((a[0],a[2]), (b[0],b[2]))) - - for n, objs, patts in rest: - if len(objs) > 1 and not manycallb: - manycallb = True - print " - many callables, many patterns -" - print "family of", pretty_els(objs), "with call-patterns:", prettypatt(patts) - -def pbcbmsanity(translator): - callb = translator.annotator.getpbccallables() - bk = translator.annotator.bookkeeper - bmeths = [x for x in callb if isinstance(x, types.MethodType) and x.im_self is not None] - print "%d bound-methods" % len(bmeths) - fams = translator.annotator.getpbccallfamilies() - plural_bm_families = {} - one_el = 0 - for bm in bmeths: - notpbc = bm.im_self not in bk.pbccache - freestanding = bm.im_func in callb - if notpbc or freestanding: - print "! %s," % bm, - if notpbc: - print "of non-PBC %s,", - if freestanding: - print "found freestanding too" - bm_fam = fams[(None, bm)] - if len(bm_fam.objects) == 1: - one_el += 1 - else: - plural_bm_families[bm_fam] = True - print "%d families of one bound-method" % one_el - print "%d families with more than just one bound-method" % len(plural_bm_families) - for bm_fam in plural_bm_families: - print pretty_els(bm_fam.objects) - return plural_bm_families - -class Counters(dict): - - def __getitem__(self, outcome): - if (isinstance(outcome, annmodel.SomeObject) or - isinstance(outcome, tuple) and outcome and - isinstance(outcome[0], annmodel.SomeObject)): - for k in self.iterkeys(): - if k == outcome: - outcome = k - break - else: - raise KeyError - return dict.__getitem__(self, outcome) - - def get(self, outcome, defl): - try: - return self[outcome] - except KeyError: - return defl - - def __setitem__(self, outcome, c): - if (isinstance(outcome, annmodel.SomeObject) or - isinstance(outcome, tuple) and outcome and - isinstance(outcome[0], annmodel.SomeObject)): - for k in self.iterkeys(): - if k == outcome: - outcome = k - break - return dict.__setitem__(self, outcome, c) - - -def keyrepr(k): - if isinstance(k, tuple): - return "(%s)" % ', '.join([keyrepr(x) for x in k]) - else: - return str(k) - -def statsfor(t, category): - stats = t.annotator.bookkeeper.stats - for_category = stats.classify[category] - print "%s total = %d" % (category, len(for_category)) - counters = Counters() - for pos, outcome in for_category.iteritems(): - counters[outcome] = counters.get(outcome, 0) + 1 - - w = max([len(keyrepr(o)) for o in counters.keys()])+1 - if w < 60: - for outcome, n in counters.iteritems(): - print "%*s | %d" % (w, keyrepr(outcome), n) - else: - for outcome, n in counters.iteritems(): - print "%s | %d" % (keyrepr(outcome), n) - -def statsforstrformat(t): - stats = t.annotator.bookkeeper.stats - stats = stats.classify['strformat'] - result = {} - for fmt, args in stats.itervalues(): - fmts = re.findall("%l?.", fmt) - if not isinstance(args, tuple): - args = (args,) - for f, a in zip(fmts, args): - result[(f,a)] = result.get((f,a), 0) + 1 - for (f,a), c in result.iteritems(): - print "%s %s %d" % (f, keyrepr(a), c) - -def statbuiltins(t): - stats = t.annotator.bookkeeper.stats.classify - for k in stats: - if k.startswith('__builtin__'): - statsfor(t, k) - -def dicts(t): - ann = t.annotator - r = [] - - def sdicts(): - for so in ann.bindings.itervalues(): - if isinstance(so, annmodel.SomeDict): - yield so - for so in ann.bookkeeper.immutable_cache.itervalues(): - if isinstance(so, annmodel.SomeDict): - yield so - - for so in sdicts(): - sk, sv = so.dictdef.dictkey.s_value, so.dictdef.dictvalue.s_value - for x in r: - if x == (sk, sv): - break - else: - r.append((sk, sv)) - - for x in r: - print x - -# debug helper -def tryout(f, *args): - try: - f(*args) - except: - import traceback - traceback.print_exc() - -def graph_footprint(graph): - class Counter: - blocks = 0 - links = 0 - ops = 0 - count = Counter() - for block in graph.iterblocks(): - count.blocks += 1 - count.ops += len(block.operations) - count.links = len(list(graph.iterlinks())) - return count.blocks, count.links, count.ops - -# better used before backends opts -def duplication(t): - d = {} - funcs = t.flowgraphs.keys() - print len(funcs) - for f in funcs: - fingerprint = f.func_code, graph_footprint(t.flowgraphs[f]) - d.setdefault(fingerprint ,[]).append(f) - l = [] - for fingerprint, funcs in d.iteritems(): - if len(funcs) > 1: - l.append((fingerprint[0].co_name, len(funcs))) - l.sort() - for name, c in l: - print name, c - -def backcalls(t): - g = {} - for caller, callee in t.callgraph.itervalues(): - g.setdefault(caller,[]).append(callee) - - back = [] - color = {} - WHITE, GRAY, BLACK = 0,1,2 - - def visit(fcur,witness=[]): - color[fcur] = GRAY - for f in dict.fromkeys(g.get(fcur, [])): - fcolor = color.get(f, WHITE) - if fcolor == WHITE: - visit(f,witness+[f]) - elif fcolor == GRAY: - print "*", witness, f - back.append((fcur, f)) - color[fcur] = BLACK - - visit(t.entrypoint, [t.entrypoint]) - - return back - -# - -def worstblocks_topten(t, n=10): - from rpython.tool.ansi_print import ansi_print - ann = t.annotator - h = [(count, block) for block, count in ann.reflowcounter.iteritems()] - h.sort() - if not h: - print "annotator should have been run with debug collecting enabled" - return - print - ansi_print(',----------------------- Top %d Most Reflown Blocks -----------------------.' % n, 36) - for i in range(n): - if not h: - break - count, block = h.pop() - ansi_print(' #%3d: reflown %d times |' % (i+1, count), 36) - t.about(block) - ansi_print("`----------------------------------------------------------------------------'", 36) - print From noreply at buildbot.pypy.org Sat Feb 23 21:10:22 2013 From: noreply at buildbot.pypy.org (cfbolz) Date: Sat, 23 Feb 2013 21:10:22 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: make targetimageloadingsmalltalk work again, and make it possible to run other methods on int Message-ID: <20130223201022.CA1281C008F@cobra.cs.uni-duesseldorf.de> Author: Carl Friedrich Bolz Branch: Changeset: r95:99ab6630753a Date: 2013-02-23 21:09 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/99ab6630753a/ Log: make targetimageloadingsmalltalk work again, and make it possible to run other methods on int diff --git a/targetimageloadingsmalltalk.py b/targetimageloadingsmalltalk.py --- a/targetimageloadingsmalltalk.py +++ b/targetimageloadingsmalltalk.py @@ -8,26 +8,14 @@ def tinyBenchmarks(space, image_name): interp = interpreter.Interpreter(space, image_name=image_name) - - w_object = model.W_SmallInteger(0) - - s_class = w_object.shadow_of_my_class(space) - w_method = s_class.lookup("tinyBenchmarks") - - assert w_method - w_frame = w_method.create_frame(space, w_object, []) - interp.store_w_active_context(w_frame) - - counter = 0 - - from spyvm.interpreter import BYTECODE_TABLE return interp -def run_benchmarks(interp): +def run_benchmarks(interp, number, benchmark): counter = 0 + w_object = model.W_SmallInteger(number) try: - interp.loop() + interp.perform(w_object, "tinyBenchmarks") except interpreter.ReturnFromTopLevel, e: w_result = e.object @@ -42,6 +30,12 @@ def entry_point(argv): if len(argv) > 1: filename = argv[1] + if len(argv) > 3: + number = int(argv[2]) + benchmark = argv[3] + else: + number = 0 + benchmark = "tinyBenchmarks" else: print "usage:", argv[0], "" return -1 @@ -49,8 +43,8 @@ reader.initialize() image = squeakimage.SqueakImage() image.from_reader(space, reader) - interp = tinyBenchmarks(space, filename) - run_benchmarks(interp) + interp = interpreter.Interpreter(space, image, filename) + run_benchmarks(interp, number, benchmark) return 0 # _____ Define and setup target ___ @@ -58,6 +52,11 @@ def target(*args): return entry_point, None +def jitpolicy(self): + from rpython.jit.codewriter.policy import JitPolicy + return JitPolicy() + + class DummyFile: def __init__(self,filename): import os From noreply at buildbot.pypy.org Sat Feb 23 21:12:59 2013 From: noreply at buildbot.pypy.org (mattip) Date: Sat, 23 Feb 2013 21:12:59 +0100 (CET) Subject: [pypy-commit] pypy numpypy-disable-longdouble: merge default into branch Message-ID: <20130223201259.8E6FD1C0327@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: numpypy-disable-longdouble Changeset: r61688:c055de682cef Date: 2013-02-23 21:26 +0200 http://bitbucket.org/pypy/pypy/changeset/c055de682cef/ Log: merge default into branch diff too long, truncating to 2000 out of 4281 lines diff --git a/lib_pypy/numpypy/__init__.py b/lib_pypy/numpypy/__init__.py --- a/lib_pypy/numpypy/__init__.py +++ b/lib_pypy/numpypy/__init__.py @@ -1,5 +1,14 @@ -from _numpypy import * -from .core import * +import core +from core import * +import lib +from lib import * + +from __builtin__ import bool, int, long, float, complex, object, unicode, str +from core import abs, max, min + +__all__ = [] +__all__ += core.__all__ +__all__ += lib.__all__ import sys sys.modules.setdefault('numpy', sys.modules['numpypy']) diff --git a/lib_pypy/numpypy/core/__init__.py b/lib_pypy/numpypy/core/__init__.py --- a/lib_pypy/numpypy/core/__init__.py +++ b/lib_pypy/numpypy/core/__init__.py @@ -1,3 +1,18 @@ -from .fromnumeric import * -from .numeric import * -from .shape_base import * +import _numpypy +from _numpypy import * +import numeric +from numeric import * +import fromnumeric +from fromnumeric import * +import shape_base +from shape_base import * +import multiarray + +from fromnumeric import amax as max, amin as min +from _numpypy import absolute as abs + +__all__ = [] +__all__ += _numpypy.__all__ +__all__ += numeric.__all__ +__all__ += fromnumeric.__all__ +__all__ += shape_base.__all__ diff --git a/lib_pypy/numpypy/core/fromnumeric.py b/lib_pypy/numpypy/core/fromnumeric.py --- a/lib_pypy/numpypy/core/fromnumeric.py +++ b/lib_pypy/numpypy/core/fromnumeric.py @@ -1290,7 +1290,9 @@ array([3, 4, 2, 3, 4, 5, 6, 7, 8, 8]) """ - raise NotImplementedError('Waiting on interp level method') + if not hasattr(a, 'clip'): + a = numpypy.array(a) + return a.clip(a_min, a_max, out=out) def sum(a, axis=None, dtype=None, out=None): @@ -1360,10 +1362,9 @@ """ assert dtype is None - assert out is None if not hasattr(a, "sum"): a = numpypy.array(a) - return a.sum(axis=axis) + return a.sum(axis=axis, out=out) def product (a, axis=None, dtype=None, out=None): @@ -1720,11 +1721,11 @@ 4.0 """ - assert axis is None - assert out is None if not hasattr(a, "max"): a = numpypy.array(a) - return a.max() + if a.size < 1: + return numpypy.array([]) + return a.max(axis=axis, out=out) def amin(a, axis=None, out=None): @@ -1782,12 +1783,11 @@ 0.0 """ - # amin() is equivalent to min() - assert axis is None - assert out is None if not hasattr(a, 'min'): a = numpypy.array(a) - return a.min() + if a.size < 1: + return numpypy.array([]) + return a.min(axis=axis, out=out) def alen(a): """ diff --git a/lib_pypy/numpypy/core/multiarray.py b/lib_pypy/numpypy/core/multiarray.py new file mode 100644 --- /dev/null +++ b/lib_pypy/numpypy/core/multiarray.py @@ -0,0 +1,1 @@ +from _numpypy import set_string_function, typeinfo diff --git a/lib_pypy/numpypy/core/numeric.py b/lib_pypy/numpypy/core/numeric.py --- a/lib_pypy/numpypy/core/numeric.py +++ b/lib_pypy/numpypy/core/numeric.py @@ -1,10 +1,13 @@ +__all__ = ['asanyarray', 'base_repr', + 'array_repr', 'array_str', 'set_string_function', + 'array_equal', 'asarray', 'outer', 'identity'] from _numpypy import array, ndarray, int_, float_, bool_, flexible #, complex_# , longlong from _numpypy import concatenate from .fromnumeric import any import math import sys -import _numpypy as multiarray # ARGH +import multiarray from numpypy.core.arrayprint import array2string newaxis = None @@ -501,3 +504,34 @@ a = asarray(a) b = asarray(b) return a.ravel()[:,newaxis]*b.ravel()[newaxis,:] + +def identity(n, dtype=None): + """ + Return the identity array. + + The identity array is a square array with ones on + the main diagonal. + + Parameters + ---------- + n : int + Number of rows (and columns) in `n` x `n` output. + dtype : data-type, optional + Data-type of the output. Defaults to ``float``. + + Returns + ------- + out : ndarray + `n` x `n` array with its main diagonal set to one, + and all other elements 0. + + Examples + -------- + >>> np.identity(3) + array([[ 1., 0., 0.], + [ 0., 1., 0.], + [ 0., 0., 1.]]) + + """ + from numpy import eye + return eye(n, dtype=dtype) diff --git a/lib_pypy/numpypy/core/shape_base.py b/lib_pypy/numpypy/core/shape_base.py --- a/lib_pypy/numpypy/core/shape_base.py +++ b/lib_pypy/numpypy/core/shape_base.py @@ -1,3 +1,5 @@ +__all__ = ['atleast_1d', 'atleast_2d', 'atleast_3d', 'vstack', 'hstack'] + import _numpypy from numeric import array, asanyarray, newaxis @@ -271,53 +273,3 @@ return _numpypy.concatenate(arrs, 0) else: return _numpypy.concatenate(arrs, 1) - -def dstack(tup): - """ - Stack arrays in sequence depth wise (along third axis). - - Takes a sequence of arrays and stack them along the third axis - to make a single array. Rebuilds arrays divided by `dsplit`. - This is a simple way to stack 2D arrays (images) into a single - 3D array for processing. - - Parameters - ---------- - tup : sequence of arrays - Arrays to stack. All of them must have the same shape along all - but the third axis. - - Returns - ------- - stacked : ndarray - The array formed by stacking the given arrays. - - See Also - -------- - vstack : Stack along first axis. - hstack : Stack along second axis. - concatenate : Join arrays. - dsplit : Split array along third axis. - - Notes - ----- - Equivalent to ``np.concatenate(tup, axis=2)``. - - Examples - -------- - >>> a = np.array((1,2,3)) - >>> b = np.array((2,3,4)) - >>> np.dstack((a,b)) - array([[[1, 2], - [2, 3], - [3, 4]]]) - - >>> a = np.array([[1],[2],[3]]) - >>> b = np.array([[2],[3],[4]]) - >>> np.dstack((a,b)) - array([[[1, 2]], - [[2, 3]], - [[3, 4]]]) - - """ - return _numpypy.concatenate(map(atleast_3d,tup),2) diff --git a/lib_pypy/numpypy/lib/__init__.py b/lib_pypy/numpypy/lib/__init__.py new file mode 100644 --- /dev/null +++ b/lib_pypy/numpypy/lib/__init__.py @@ -0,0 +1,11 @@ +import function_base +from function_base import * +import shape_base +from shape_base import * +import twodim_base +from twodim_base import * + +__all__ = [] +__all__ += function_base.__all__ +__all__ += shape_base.__all__ +__all__ += twodim_base.__all__ diff --git a/lib_pypy/numpypy/lib/function_base.py b/lib_pypy/numpypy/lib/function_base.py new file mode 100644 --- /dev/null +++ b/lib_pypy/numpypy/lib/function_base.py @@ -0,0 +1,10 @@ +__all__ = ['average'] + +from _numpypy import array + +def average(a): + # This implements a weighted average, for now we don't implement the + # weighting, just the average part! + if not hasattr(a, "mean"): + a = array(a) + return a.mean() diff --git a/lib_pypy/numpypy/lib/shape_base.py b/lib_pypy/numpypy/lib/shape_base.py new file mode 100644 --- /dev/null +++ b/lib_pypy/numpypy/lib/shape_base.py @@ -0,0 +1,54 @@ +__all__ = ['dstack'] + +import numpypy.core.numeric as _nx +from numpypy.core import atleast_3d + +def dstack(tup): + """ + Stack arrays in sequence depth wise (along third axis). + + Takes a sequence of arrays and stack them along the third axis + to make a single array. Rebuilds arrays divided by `dsplit`. + This is a simple way to stack 2D arrays (images) into a single + 3D array for processing. + + Parameters + ---------- + tup : sequence of arrays + Arrays to stack. All of them must have the same shape along all + but the third axis. + + Returns + ------- + stacked : ndarray + The array formed by stacking the given arrays. + + See Also + -------- + vstack : Stack along first axis. + hstack : Stack along second axis. + concatenate : Join arrays. + dsplit : Split array along third axis. + + Notes + ----- + Equivalent to ``np.concatenate(tup, axis=2)``. + + Examples + -------- + >>> a = np.array((1,2,3)) + >>> b = np.array((2,3,4)) + >>> np.dstack((a,b)) + array([[[1, 2], + [2, 3], + [3, 4]]]) + + >>> a = np.array([[1],[2],[3]]) + >>> b = np.array([[2],[3],[4]]) + >>> np.dstack((a,b)) + array([[[1, 2]], + [[2, 3]], + [[3, 4]]]) + + """ + return _nx.concatenate(map(atleast_3d,tup),2) diff --git a/lib_pypy/numpypy/lib/twodim_base.py b/lib_pypy/numpypy/lib/twodim_base.py new file mode 100644 --- /dev/null +++ b/lib_pypy/numpypy/lib/twodim_base.py @@ -0,0 +1,54 @@ +__all__ = ['eye'] + +from _numpypy import zeros + +def eye(N, M=None, k=0, dtype=float): + """ + Return a 2-D array with ones on the diagonal and zeros elsewhere. + + Parameters + ---------- + N : int + Number of rows in the output. + M : int, optional + Number of columns in the output. If None, defaults to `N`. + k : int, optional + Index of the diagonal: 0 (the default) refers to the main diagonal, + a positive value refers to an upper diagonal, and a negative value + to a lower diagonal. + dtype : data-type, optional + Data-type of the returned array. + + Returns + ------- + I : ndarray of shape (N,M) + An array where all elements are equal to zero, except for the `k`-th + diagonal, whose values are equal to one. + + See Also + -------- + identity : (almost) equivalent function + diag : diagonal 2-D array from a 1-D array specified by the user. + + Examples + -------- + >>> np.eye(2, dtype=int) + array([[1, 0], + [0, 1]]) + >>> np.eye(3, k=1) + array([[ 0., 1., 0.], + [ 0., 0., 1.], + [ 0., 0., 0.]]) + + """ + if M is None: + M = N + m = zeros((N, M), dtype=dtype) + if k >= M: + return m + if k >= 0: + i = k + else: + i = (-k) * M + m[:M-k].flat[i::M+1] = 1 + return m diff --git a/pypy/doc/cpython_differences.rst b/pypy/doc/cpython_differences.rst --- a/pypy/doc/cpython_differences.rst +++ b/pypy/doc/cpython_differences.rst @@ -134,7 +134,7 @@ ``ReferenceError`` at any place that uses them. (Or, better yet, don't use ``weakref.proxy()`` at all; use ``weakref.ref()``.) -There are a few extra implications for the difference in the GC. Most +There are a few extra implications from the difference in the GC. Most notably, if an object has a ``__del__``, the ``__del__`` is never called more than once in PyPy; but CPython will call the same ``__del__`` several times if the object is resurrected and dies again. The ``__del__`` methods are @@ -156,7 +156,7 @@ .. __: http://bugs.pypy.org/issue736 -Using the default GC called ``minimark``, the built-in function ``id()`` +Using the default GC (called ``minimark``), the built-in function ``id()`` works like it does in CPython. With other GCs it returns numbers that are not real addresses (because an object can move around several times) and calling it a lot can lead to performance problem. @@ -286,7 +286,7 @@ ------------- * Hash randomization (``-R``) is ignored in PyPy. As documented in - http://bugs.python.org/issue14621 , some of us believe it has no + http://bugs.python.org/issue14621, some of us believe it has no purpose in CPython either. * ``sys.setrecursionlimit(n)`` sets the limit only approximately, diff --git a/pypy/doc/ctypes-implementation.rst b/pypy/doc/ctypes-implementation.rst --- a/pypy/doc/ctypes-implementation.rst +++ b/pypy/doc/ctypes-implementation.rst @@ -38,7 +38,7 @@ in dynamic libraries through libffi. Freeing objects in most cases and making sure that objects referring to each other are kept alive is responsibility of the higher levels. -This module uses bindings to libffi which are defined in ``pypy/rlib/libffi.py``. +This module uses bindings to libffi which are defined in ``rpython/rlib/libffi.py``. We tried to keep this module as small as possible. It is conceivable that other implementations (e.g. Jython) could use our ctypes diff --git a/pypy/doc/discussion/improve-rpython.rst b/pypy/doc/discussion/improve-rpython.rst --- a/pypy/doc/discussion/improve-rpython.rst +++ b/pypy/doc/discussion/improve-rpython.rst @@ -39,7 +39,7 @@ - Allocate variables on the stack, and pass their address ("by reference") to llexternal functions. For a typical usage, see - `pypy.rlib.rsocket.RSocket.getsockopt_int`. + `rpython.rlib.rsocket.RSocket.getsockopt_int`. Extensible type system for llexternal ------------------------------------- diff --git a/pypy/doc/faq.rst b/pypy/doc/faq.rst --- a/pypy/doc/faq.rst +++ b/pypy/doc/faq.rst @@ -202,20 +202,20 @@ Be sure to enable it again if you need it! -The PyPy translation tool chain -=============================== +The RPython translation tool chain +=================================== ---------------------------------------------- -Can PyPy compile normal Python programs to C? ---------------------------------------------- +------------------------------------------------ +Can RPython compile normal Python programs to C? +------------------------------------------------ -No, PyPy is not a Python compiler. +No, RPython is not a Python compiler. In Python, it is mostly impossible to *prove* anything about the types that a program will manipulate by doing a static analysis. It should be clear if you are familiar with Python, but if in doubt see [BRETT]_. -If you want a fast Python program, please use our JIT_ instead. +If you want a fast Python program, please use the PyPy JIT_ instead. .. _JIT: jit/index.html @@ -300,8 +300,8 @@ Do I have to rewrite my programs in RPython? -------------------------------------------- -No. And you shouldn't try. First and foremost, RPython is a language -that is designed to write interpreters in. It is a restricted subset of +No, and you shouldn't try. First and foremost, RPython is a language +designed for writing interpreters. It is a restricted subset of Python. If you program is not an interpreter but tries to do "real things", like use *any* part of the standard Python library or *any* 3rd-party library, then it is not RPython to start with. You should @@ -381,8 +381,8 @@ No, you have to rebuild the entire interpreter. This means two things: -* It is imperative to use test-driven development. You have to test - exhaustively your module in pure Python, before even attempting to +* It is imperative to use test-driven development. You have to exhaustively + test your module in pure Python, before even attempting to translate it. Once you translate it, you should have only a few typing issues left to fix, but otherwise the result should work out of the box. diff --git a/pypy/doc/garbage_collection.rst b/pypy/doc/garbage_collection.rst --- a/pypy/doc/garbage_collection.rst +++ b/pypy/doc/garbage_collection.rst @@ -42,7 +42,7 @@ Two arenas of equal size, with only one arena in use and getting filled with new objects. When the arena is full, the live objects are copied into the other arena using Cheney's algorithm. The old arena is then -cleared. See `rpython/rtyper/memory/gc/semispace.py`_. +cleared. See `rpython/memory/gc/semispace.py`_. On Unix the clearing is done by reading ``/dev/zero`` into the arena, which is extremely memory efficient at least on Linux: it lets the @@ -55,7 +55,7 @@ Generational GC --------------- -This is a two-generations GC. See `rpython/rtyper/memory/gc/generation.py`_. +This is a two-generations GC. See `rpython/memory/gc/generation.py`_. It is implemented as a subclass of the Semispace copying collector. It adds a nursery, which is a chunk of the current semispace. Its size is @@ -86,7 +86,7 @@ Each generation is collected much less often than the previous one. The division of the generations is slightly more complicated than just nursery / semispace / external; see the diagram at the start of the -source code, in `rpython/rtyper/memory/gc/hybrid.py`_. +source code, in `rpython/memory/gc/hybrid.py`_. Mark & Compact GC ----------------- @@ -161,7 +161,7 @@ to the old stage. The dying case 2 objects are immediately freed. - The old stage is an area of memory containing old (small) objects. It - is handled by `rpython/rtyper/memory/gc/minimarkpage.py`_. It is organized + is handled by `rpython/memory/gc/minimarkpage.py`_. It is organized as "arenas" of 256KB or 512KB, subdivided into "pages" of 4KB or 8KB. Each page can either be free, or contain small objects of all the same size. Furthermore at any point in time each object location can be diff --git a/pypy/doc/getting-started-dev.rst b/pypy/doc/getting-started-dev.rst --- a/pypy/doc/getting-started-dev.rst +++ b/pypy/doc/getting-started-dev.rst @@ -20,7 +20,7 @@ To start the interactive translator shell do:: - cd pypy + cd rpython python bin/translatorshell.py Test snippets of translatable code are provided in the file diff --git a/pypy/doc/index.rst b/pypy/doc/index.rst --- a/pypy/doc/index.rst +++ b/pypy/doc/index.rst @@ -286,7 +286,7 @@ `rpython/rtyper/ootypesystem/`_ the `object-oriented type system`_ for OO backends -`rpython/rtyper/memory/`_ the `garbage collector`_ construction +`rpython/memory/`_ the `garbage collector`_ construction framework `rpython/translator/`_ translation_ backends and support code diff --git a/pypy/doc/interpreter.rst b/pypy/doc/interpreter.rst --- a/pypy/doc/interpreter.rst +++ b/pypy/doc/interpreter.rst @@ -25,7 +25,7 @@ compact bytecode format as CPython 2.7, with minor differences in the bytecode set. Our bytecode compiler is implemented as a chain of flexible passes (tokenizer, lexer, parser, -abstract syntax tree builder, bytecode generator). The latter passes +abstract syntax tree builder and bytecode generator). The latter passes are based on the ``compiler`` package from the standard library of CPython, with various improvements and bug fixes. The bytecode compiler (living under `pypy/interpreter/astcompiler/`_) is now integrated and is @@ -38,8 +38,8 @@ calling its ``frame.eval()`` method. This main entry point initialize appropriate namespaces and then interprets each bytecode instruction. Python's standard library contains -the `lib-python/2.7/dis.py`_ module which allows to view -the Virtual's machine bytecode instructions:: +the `lib-python/2.7/dis.py`_ module which allows to inspection +of the virtual machine's bytecode instructions:: >>> import dis >>> def f(x): @@ -50,10 +50,10 @@ 6 BINARY_ADD 7 RETURN_VALUE -CPython as well as PyPy are stack-based virtual machines, i.e. -they don't have registers but put object to and pull objects +CPython and PyPy are stack-based virtual machines, i.e. +they don't have registers but instead push object to and pull objects from a stack. The bytecode interpreter is only responsible -for implementing control flow and putting and pulling black +for implementing control flow and pushing and pulling black box objects to and from this value stack. The bytecode interpreter does not know how to perform operations on those black box (`wrapped`_) objects for which it delegates to the `object @@ -75,8 +75,8 @@ on ``OperationErrors``. The interpreter implementation offers mechanisms to allow a -caller to be unaware if a particular function invocation leads -to bytecode interpretation or is executed directly at +caller to be unaware of whether a particular function invocation +leads to bytecode interpretation or is executed directly at interpreter-level. The two basic kinds of `Gateway classes`_ expose either an interpreter-level function to application-level execution (``interp2app``) or allow diff --git a/pypy/doc/stackless.rst b/pypy/doc/stackless.rst --- a/pypy/doc/stackless.rst +++ b/pypy/doc/stackless.rst @@ -273,7 +273,7 @@ more information about them please see the documentation in the C source at `rpython/translator/c/src/stacklet/stacklet.h`_. -The module ``pypy.rlib.rstacklet`` is a thin wrapper around the above +The module ``rpython.rlib.rstacklet`` is a thin wrapper around the above functions. The key point is that new() and switch() always return a fresh stacklet handle (or an empty one), and switch() additionally consumes one. It makes no sense to have code in which the returned diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst --- a/pypy/doc/whatsnew-head.rst +++ b/pypy/doc/whatsnew-head.rst @@ -68,3 +68,7 @@ .. branch: coding-guide-update-rlib-refs .. branch: rlib-doc-rpython-refs +.. branch: clean-up-remaining-pypy-rlib-refs + +.. branch: enumerate-rstr +Support enumerate() over rstr types. diff --git a/pypy/module/_cffi_backend/cbuffer.py b/pypy/module/_cffi_backend/cbuffer.py --- a/pypy/module/_cffi_backend/cbuffer.py +++ b/pypy/module/_cffi_backend/cbuffer.py @@ -1,10 +1,11 @@ -from pypy.interpreter.error import operationerrfmt from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.buffer import RWBuffer +from pypy.interpreter.error import operationerrfmt from pypy.interpreter.gateway import unwrap_spec, interp2app from pypy.interpreter.typedef import TypeDef, make_weakref_descr +from pypy.module._cffi_backend import cdataobj, ctypeptr, ctypearray + from rpython.rtyper.lltypesystem import rffi -from pypy.module._cffi_backend import cdataobj, ctypeptr, ctypearray class LLBuffer(RWBuffer): diff --git a/pypy/module/_cffi_backend/ccallback.py b/pypy/module/_cffi_backend/ccallback.py --- a/pypy/module/_cffi_backend/ccallback.py +++ b/pypy/module/_cffi_backend/ccallback.py @@ -2,18 +2,17 @@ Callbacks. """ import os + +from rpython.rlib import clibffi, rweakref, jit +from rpython.rlib.objectmodel import compute_unique_id, keepalive_until_here +from rpython.rtyper.lltypesystem import lltype, rffi + from pypy.interpreter.error import OperationError, operationerrfmt -from rpython.rtyper.lltypesystem import lltype, llmemory, rffi -from rpython.rlib.objectmodel import compute_unique_id, keepalive_until_here -from rpython.rlib import clibffi, rweakref -from rpython.rlib import jit - +from pypy.module._cffi_backend import cerrno, misc from pypy.module._cffi_backend.cdataobj import W_CData -from pypy.module._cffi_backend.ctypefunc import SIZE_OF_FFI_ARG, BIG_ENDIAN -from pypy.module._cffi_backend.ctypefunc import W_CTypeFunc +from pypy.module._cffi_backend.ctypefunc import SIZE_OF_FFI_ARG, BIG_ENDIAN, W_CTypeFunc from pypy.module._cffi_backend.ctypeprim import W_CTypePrimitiveSigned from pypy.module._cffi_backend.ctypevoid import W_CTypeVoid -from pypy.module._cffi_backend import cerrno, misc # ____________________________________________________________ @@ -152,6 +151,7 @@ STDERR = 2 + @jit.jit_callback("CFFI") def invoke_callback(ffi_cif, ll_res, ll_args, ll_userdata): """ Callback specification. diff --git a/pypy/module/_cffi_backend/cdataobj.py b/pypy/module/_cffi_backend/cdataobj.py --- a/pypy/module/_cffi_backend/cdataobj.py +++ b/pypy/module/_cffi_backend/cdataobj.py @@ -1,11 +1,13 @@ import operator + +from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.error import OperationError, operationerrfmt -from pypy.interpreter.baseobjspace import Wrappable -from pypy.interpreter.gateway import interp2app, unwrap_spec +from pypy.interpreter.gateway import interp2app from pypy.interpreter.typedef import TypeDef, make_weakref_descr + +from rpython.rlib import objectmodel, rgc +from rpython.rlib.objectmodel import keepalive_until_here, specialize from rpython.rtyper.lltypesystem import lltype, rffi -from rpython.rlib.objectmodel import keepalive_until_here, specialize -from rpython.rlib import objectmodel, rgc from rpython.tool.sourcetools import func_with_new_name from pypy.module._cffi_backend import misc diff --git a/pypy/module/_cffi_backend/cerrno.py b/pypy/module/_cffi_backend/cerrno.py --- a/pypy/module/_cffi_backend/cerrno.py +++ b/pypy/module/_cffi_backend/cerrno.py @@ -1,5 +1,7 @@ import sys + from rpython.rlib import rposix + from pypy.interpreter.executioncontext import ExecutionContext from pypy.interpreter.gateway import unwrap_spec diff --git a/pypy/module/_cffi_backend/ctypearray.py b/pypy/module/_cffi_backend/ctypearray.py --- a/pypy/module/_cffi_backend/ctypearray.py +++ b/pypy/module/_cffi_backend/ctypearray.py @@ -2,18 +2,17 @@ Arrays. """ +from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.error import OperationError, operationerrfmt -from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.gateway import interp2app from pypy.interpreter.typedef import TypeDef + from rpython.rtyper.lltypesystem import rffi from rpython.rlib.objectmodel import keepalive_until_here from rpython.rlib.rarithmetic import ovfcheck -from pypy.module._cffi_backend.ctypeprim import W_CTypePrimitiveChar -from pypy.module._cffi_backend.ctypeprim import W_CTypePrimitiveUniChar +from pypy.module._cffi_backend import cdataobj from pypy.module._cffi_backend.ctypeptr import W_CTypePtrOrArray -from pypy.module._cffi_backend import cdataobj class W_CTypeArray(W_CTypePtrOrArray): diff --git a/pypy/module/_cffi_backend/ctypeenum.py b/pypy/module/_cffi_backend/ctypeenum.py --- a/pypy/module/_cffi_backend/ctypeenum.py +++ b/pypy/module/_cffi_backend/ctypeenum.py @@ -2,15 +2,11 @@ Enums. """ -from pypy.interpreter.error import OperationError, operationerrfmt -from rpython.rtyper.lltypesystem import rffi -from rpython.rlib.rarithmetic import intmask, r_ulonglong from rpython.rlib.objectmodel import keepalive_until_here -from rpython.rlib.objectmodel import specialize -from pypy.module._cffi_backend.ctypeprim import W_CTypePrimitiveSigned -from pypy.module._cffi_backend.ctypeprim import W_CTypePrimitiveUnsigned from pypy.module._cffi_backend import misc +from pypy.module._cffi_backend.ctypeprim import (W_CTypePrimitiveSigned, + W_CTypePrimitiveUnsigned) class _Mixin_Enum(object): diff --git a/pypy/module/_cffi_backend/ctypefunc.py b/pypy/module/_cffi_backend/ctypefunc.py --- a/pypy/module/_cffi_backend/ctypefunc.py +++ b/pypy/module/_cffi_backend/ctypefunc.py @@ -4,25 +4,21 @@ import sys from pypy.interpreter.error import OperationError, operationerrfmt + +from rpython.rlib import jit, clibffi, jit_libffi +from rpython.rlib.jit_libffi import (CIF_DESCRIPTION, CIF_DESCRIPTION_P, + FFI_TYPE, FFI_TYPE_P, FFI_TYPE_PP, SIZE_OF_FFI_ARG) +from rpython.rlib.objectmodel import we_are_translated, instantiate from rpython.rtyper.lltypesystem import lltype, llmemory, rffi -from rpython.rlib import jit, clibffi, jit_libffi -from rpython.rlib.jit_libffi import CIF_DESCRIPTION, CIF_DESCRIPTION_P -from rpython.rlib.jit_libffi import FFI_TYPE, FFI_TYPE_P, FFI_TYPE_PP -from rpython.rlib.jit_libffi import SIZE_OF_FFI_ARG -from rpython.rlib.objectmodel import we_are_translated, instantiate -from rpython.rlib.objectmodel import keepalive_until_here +from pypy.module._cffi_backend import ctypearray, cdataobj, cerrno from pypy.module._cffi_backend.ctypeobj import W_CType from pypy.module._cffi_backend.ctypeptr import W_CTypePtrBase, W_CTypePointer from pypy.module._cffi_backend.ctypevoid import W_CTypeVoid from pypy.module._cffi_backend.ctypestruct import W_CTypeStruct -from pypy.module._cffi_backend.ctypestruct import W_CTypeStructOrUnion -from pypy.module._cffi_backend.ctypeprim import W_CTypePrimitiveSigned -from pypy.module._cffi_backend.ctypeprim import W_CTypePrimitiveUnsigned -from pypy.module._cffi_backend.ctypeprim import W_CTypePrimitiveCharOrUniChar -from pypy.module._cffi_backend.ctypeprim import W_CTypePrimitiveFloat -from pypy.module._cffi_backend.ctypeprim import W_CTypePrimitiveLongDouble -from pypy.module._cffi_backend import ctypearray, cdataobj, cerrno +from pypy.module._cffi_backend.ctypeprim import (W_CTypePrimitiveSigned, + W_CTypePrimitiveUnsigned, W_CTypePrimitiveCharOrUniChar, + W_CTypePrimitiveFloat, W_CTypePrimitiveLongDouble) class W_CTypeFunc(W_CTypePtrBase): @@ -97,7 +93,6 @@ return self.space.wrap(clibffi.FFI_DEFAULT_ABI) # XXX return W_CTypePtrBase._fget(self, attrchar) - def call(self, funcaddr, args_w): if self.cif_descr: # regular case: this function does not take '...' arguments @@ -270,7 +265,6 @@ self.bufferp = rffi.ptradd(result, size) return result - def fb_fill_type(self, ctype, is_result_type): return ctype._get_ffi_type(self, is_result_type) @@ -357,7 +351,6 @@ return ffistruct - def fb_build(self): # Build a CIF_DESCRIPTION. Actually this computes the size and # allocates a larger amount of data. It starts with a @@ -387,7 +380,6 @@ if self.atypes: self.atypes[i] = atype - def align_arg(self, n): return (n + 7) & ~7 diff --git a/pypy/module/_cffi_backend/ctypeobj.py b/pypy/module/_cffi_backend/ctypeobj.py --- a/pypy/module/_cffi_backend/ctypeobj.py +++ b/pypy/module/_cffi_backend/ctypeobj.py @@ -1,9 +1,8 @@ +from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.error import OperationError, operationerrfmt -from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.gateway import interp2app -from pypy.interpreter.typedef import TypeDef -from pypy.interpreter.typedef import make_weakref_descr -from pypy.interpreter.typedef import GetSetProperty, interp_attrproperty +from pypy.interpreter.typedef import TypeDef, make_weakref_descr, GetSetProperty + from rpython.rtyper.lltypesystem import lltype, llmemory, rffi from rpython.rlib.objectmodel import we_are_translated diff --git a/pypy/module/_cffi_backend/ctypeprim.py b/pypy/module/_cffi_backend/ctypeprim.py --- a/pypy/module/_cffi_backend/ctypeprim.py +++ b/pypy/module/_cffi_backend/ctypeprim.py @@ -3,13 +3,14 @@ """ from pypy.interpreter.error import operationerrfmt -from rpython.rtyper.lltypesystem import lltype, rffi + from rpython.rlib.rarithmetic import r_uint, r_ulonglong, intmask from rpython.rlib.objectmodel import keepalive_until_here from rpython.rlib import jit +from rpython.rtyper.lltypesystem import lltype, rffi +from pypy.module._cffi_backend import cdataobj, misc from pypy.module._cffi_backend.ctypeobj import W_CType -from pypy.module._cffi_backend import cdataobj, misc class W_CTypePrimitive(W_CType): diff --git a/pypy/module/_cffi_backend/ctypeptr.py b/pypy/module/_cffi_backend/ctypeptr.py --- a/pypy/module/_cffi_backend/ctypeptr.py +++ b/pypy/module/_cffi_backend/ctypeptr.py @@ -2,15 +2,15 @@ Pointers. """ -from pypy.interpreter.error import OperationError, operationerrfmt -from pypy.interpreter.error import wrap_oserror -from rpython.rtyper.lltypesystem import lltype, rffi +from pypy.interpreter.error import OperationError, operationerrfmt, wrap_oserror + +from rpython.rlib import rposix from rpython.rlib.objectmodel import keepalive_until_here from rpython.rlib.rarithmetic import ovfcheck -from rpython.rlib import rposix +from rpython.rtyper.lltypesystem import lltype, rffi +from pypy.module._cffi_backend import cdataobj, misc, ctypeprim, ctypevoid from pypy.module._cffi_backend.ctypeobj import W_CType -from pypy.module._cffi_backend import cdataobj, misc, ctypeprim, ctypevoid class W_CTypePtrOrArray(W_CType): @@ -336,19 +336,22 @@ rffi_fdopen = rffi.llexternal("fdopen", [rffi.INT, rffi.CCHARP], rffi.CCHARP) -rffi_setbuf = rffi.llexternal("setbuf", [rffi.CCHARP,rffi.CCHARP], lltype.Void) +rffi_setbuf = rffi.llexternal("setbuf", [rffi.CCHARP, rffi.CCHARP], lltype.Void) rffi_fclose = rffi.llexternal("fclose", [rffi.CCHARP], rffi.INT) class CffiFileObj(object): _immutable_ = True + def __init__(self, fd, mode): self.llf = rffi_fdopen(fd, mode) if not self.llf: raise OSError(rposix.get_errno(), "fdopen failed") rffi_setbuf(self.llf, lltype.nullptr(rffi.CCHARP.TO)) + def close(self): rffi_fclose(self.llf) + def prepare_file_argument(space, fileobj): fileobj.direct_flush() if fileobj.cffi_fileobj is None: diff --git a/pypy/module/_cffi_backend/ctypestruct.py b/pypy/module/_cffi_backend/ctypestruct.py --- a/pypy/module/_cffi_backend/ctypestruct.py +++ b/pypy/module/_cffi_backend/ctypestruct.py @@ -3,15 +3,16 @@ """ from pypy.interpreter.error import OperationError, operationerrfmt -from rpython.rtyper.lltypesystem import lltype, rffi from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.typedef import TypeDef, interp_attrproperty + +from rpython.rlib import jit from rpython.rlib.objectmodel import keepalive_until_here from rpython.rlib.rarithmetic import r_uint, r_ulonglong, r_longlong, intmask -from rpython.rlib import jit +from rpython.rtyper.lltypesystem import rffi +from pypy.module._cffi_backend import cdataobj, ctypeprim, misc from pypy.module._cffi_backend.ctypeobj import W_CType -from pypy.module._cffi_backend import cdataobj, ctypeprim, misc class W_CTypeStructOrUnion(W_CType): @@ -141,6 +142,7 @@ class W_CTypeStruct(W_CTypeStructOrUnion): kind = "struct" + class W_CTypeUnion(W_CTypeStructOrUnion): kind = "union" @@ -241,8 +243,8 @@ # value = misc.as_long_long(space, w_ob) if isinstance(ctype, ctypeprim.W_CTypePrimitiveSigned): - fmin = -(r_longlong(1) << (self.bitsize-1)) - fmax = (r_longlong(1) << (self.bitsize-1)) - 1 + fmin = -(r_longlong(1) << (self.bitsize - 1)) + fmax = (r_longlong(1) << (self.bitsize - 1)) - 1 if fmax == 0: fmax = 1 # special case to let "int x:1" receive "1" else: diff --git a/pypy/module/_cffi_backend/libraryobj.py b/pypy/module/_cffi_backend/libraryobj.py --- a/pypy/module/_cffi_backend/libraryobj.py +++ b/pypy/module/_cffi_backend/libraryobj.py @@ -1,9 +1,11 @@ from __future__ import with_statement -from pypy.interpreter.error import OperationError, operationerrfmt + from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.error import operationerrfmt from pypy.interpreter.gateway import interp2app, unwrap_spec from pypy.interpreter.typedef import TypeDef -from rpython.rtyper.lltypesystem import lltype, rffi + +from rpython.rtyper.lltypesystem import rffi from rpython.rlib.rdynload import DLLHANDLE, dlopen, dlsym, dlclose, DLOpenError from pypy.module._cffi_backend.cdataobj import W_CData diff --git a/pypy/module/_cffi_backend/misc.py b/pypy/module/_cffi_backend/misc.py --- a/pypy/module/_cffi_backend/misc.py +++ b/pypy/module/_cffi_backend/misc.py @@ -1,10 +1,12 @@ from __future__ import with_statement -from pypy.interpreter.error import OperationError, operationerrfmt -from rpython.rtyper.lltypesystem import lltype, llmemory, rffi + +from pypy.interpreter.error import OperationError + +from rpython.rlib import jit +from rpython.rlib.objectmodel import keepalive_until_here, specialize from rpython.rlib.rarithmetic import r_uint, r_ulonglong, is_signed_integer_type from rpython.rlib.unroll import unrolling_iterable -from rpython.rlib.objectmodel import keepalive_until_here, specialize -from rpython.rlib import jit +from rpython.rtyper.lltypesystem import lltype, llmemory, rffi from rpython.translator.tool.cbuild import ExternalCompilationInfo # ____________________________________________________________ @@ -43,14 +45,14 @@ def read_raw_unsigned_data(target, size): for TP, TPP in _prim_unsigned_types: if size == rffi.sizeof(TP): - return rffi.cast(lltype.UnsignedLongLong, rffi.cast(TPP,target)[0]) + return rffi.cast(lltype.UnsignedLongLong, rffi.cast(TPP, target)[0]) raise NotImplementedError("bad integer size") def read_raw_ulong_data(target, size): for TP, TPP in _prim_unsigned_types: if size == rffi.sizeof(TP): assert rffi.sizeof(TP) <= rffi.sizeof(lltype.Unsigned) - return rffi.cast(lltype.Unsigned, rffi.cast(TPP,target)[0]) + return rffi.cast(lltype.Unsigned, rffi.cast(TPP, target)[0]) raise NotImplementedError("bad integer size") def read_raw_float_data(target, size): diff --git a/pypy/module/_cffi_backend/newtype.py b/pypy/module/_cffi_backend/newtype.py --- a/pypy/module/_cffi_backend/newtype.py +++ b/pypy/module/_cffi_backend/newtype.py @@ -1,12 +1,12 @@ from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.gateway import unwrap_spec + +from rpython.rlib.objectmodel import specialize +from rpython.rlib.rarithmetic import ovfcheck from rpython.rtyper.lltypesystem import lltype, rffi -from rpython.rlib.rarithmetic import ovfcheck, r_uint, intmask -from rpython.rlib.rarithmetic import most_neg_value_of, most_pos_value_of -from rpython.rlib.objectmodel import specialize -from pypy.module._cffi_backend import ctypeobj, ctypeprim, ctypeptr, ctypearray -from pypy.module._cffi_backend import ctypestruct, ctypevoid, ctypeenum +from pypy.module._cffi_backend import (ctypeobj, ctypeprim, ctypeptr, + ctypearray, ctypestruct, ctypevoid, ctypeenum) @specialize.memo() @@ -167,7 +167,7 @@ # if foffset < 0: # align this field to its own 'falign' by inserting padding - offset = (offset + falign - 1) & ~(falign-1) + offset = (offset + falign - 1) & ~(falign - 1) else: # a forced field position: ignore the offset just computed, # except to know if we must set 'custom_field_pos' @@ -178,7 +178,7 @@ fbitsize == 8 * ftype.size and not isinstance(ftype, ctypeprim.W_CTypePrimitiveCharOrUniChar)): fbitsize = -1 - if isinstance(ftype, ctypearray.W_CTypeArray) and ftype.length==0: + if isinstance(ftype, ctypearray.W_CTypeArray) and ftype.length == 0: bitshift = ctypestruct.W_CField.BS_EMPTY_ARRAY else: bitshift = ctypestruct.W_CField.BS_REGULAR @@ -241,7 +241,7 @@ # as 1 instead. But for ctypes support, we allow the manually- # specified totalsize to be zero in this case. if totalsize < 0: - offset = (offset + alignment - 1) & ~(alignment-1) + offset = (offset + alignment - 1) & ~(alignment - 1) totalsize = offset or 1 elif totalsize < offset: raise operationerrfmt(space.w_TypeError, diff --git a/pypy/module/_io/interp_bufferedio.py b/pypy/module/_io/interp_bufferedio.py --- a/pypy/module/_io/interp_bufferedio.py +++ b/pypy/module/_io/interp_bufferedio.py @@ -631,6 +631,72 @@ return res return None + def readline_w(self, space, w_limit=None): + self._check_init(space) + self._check_closed(space, "readline of closed file") + + limit = convert_size(space, w_limit) + + # First, try to find a line in the buffer. This can run + # unlocked because the calls to the C API are simple enough + # that they can't trigger any thread switch. + have = self._readahead() + if limit >= 0 and have > limit: + have = limit + for pos in range(self.pos, self.pos+have): + if self.buffer[pos] == '\n': + break + else: + pos = -1 + if pos >= 0: + w_res = space.wrap(''.join(self.buffer[self.pos:pos+1])) + self.pos = pos + 1 + return w_res + if have == limit: + w_res = space.wrap(''.join(self.buffer[self.pos:self.pos+have])) + self.pos += have + return w_res + + written = 0 + with self.lock: + # Now we try to get some more from the raw stream + chunks = [] + if have > 0: + chunks.extend(self.buffer[self.pos:self.pos+have]) + written += have + self.pos += have + if limit >= 0: + limit -= have + if self.writable: + self._flush_and_rewind_unlocked(space) + + while True: + self._reader_reset_buf() + have = self._fill_buffer(space) + if have == 0: + break + if limit >= 0 and have > limit: + have = limit + pos = 0 + found = False + while pos < have: + c = self.buffer[pos] + pos += 1 + if c == '\n': + self.pos = pos + found = True + break + chunks.extend(self.buffer[0:pos]) + if found: + break + if have == limit: + self.pos = have + break + written += have + if limit >= 0: + limit -= have + return space.wrap(''.join(chunks)) + # ____________________________________________________ # Write methods @@ -795,6 +861,7 @@ peek = interp2app(W_BufferedReader.peek_w), read1 = interp2app(W_BufferedReader.read1_w), raw = interp_attrproperty_w("w_raw", cls=W_BufferedReader), + readline = interp2app(W_BufferedReader.readline_w), # from the mixin class __repr__ = interp2app(W_BufferedReader.repr_w), @@ -968,6 +1035,7 @@ read = interp2app(W_BufferedRandom.read_w), peek = interp2app(W_BufferedRandom.peek_w), read1 = interp2app(W_BufferedRandom.read1_w), + readline = interp2app(W_BufferedRandom.readline_w), write = interp2app(W_BufferedRandom.write_w), flush = interp2app(W_BufferedRandom.flush_w), diff --git a/pypy/module/_io/interp_bytesio.py b/pypy/module/_io/interp_bytesio.py --- a/pypy/module/_io/interp_bytesio.py +++ b/pypy/module/_io/interp_bytesio.py @@ -52,6 +52,25 @@ self.pos += size return space.wrap(output) + def readline_w(self, space, w_limit=None): + self._check_closed(space) + limit = convert_size(space, w_limit) + + cur_pos = self.pos + if limit < 0: + end_pos = self.string_size + else: + end_pos = min(cur_pos + limit, self.string_size) + while cur_pos != end_pos: + if self.buf[cur_pos] == '\n': + cur_pos += 1 + break + cur_pos += 1 + + output = buffer2string(self.buf, self.pos, cur_pos) + self.pos = cur_pos + return space.wrap(output) + def read1_w(self, space, w_size): return self.read_w(space, w_size) @@ -209,6 +228,7 @@ read = interp2app(W_BytesIO.read_w), read1 = interp2app(W_BytesIO.read1_w), + readline = interp2app(W_BytesIO.readline_w), readinto = interp2app(W_BytesIO.readinto_w), write = interp2app(W_BytesIO.write_w), truncate = interp2app(W_BytesIO.truncate_w), diff --git a/pypy/module/_io/interp_fileio.py b/pypy/module/_io/interp_fileio.py --- a/pypy/module/_io/interp_fileio.py +++ b/pypy/module/_io/interp_fileio.py @@ -3,7 +3,6 @@ from pypy.interpreter.error import OperationError, wrap_oserror, wrap_oserror2 from rpython.rlib.rarithmetic import r_longlong from rpython.rlib.rstring import StringBuilder -from rpython.rlib.rposix import validate_fd from os import O_RDONLY, O_WRONLY, O_RDWR, O_CREAT, O_TRUNC import sys, os, stat, errno from pypy.module._io.interp_iobase import W_RawIOBase, convert_size @@ -154,7 +153,6 @@ fd_is_own = False try: if fd >= 0: - validate_fd(fd) try: os.fstat(fd) except OSError, e: @@ -235,7 +233,6 @@ self.fd = -1 try: - validate_fd(fd) os.close(fd) except OSError, e: raise wrap_oserror(space, e, diff --git a/pypy/module/_io/test/test_bufferedio.py b/pypy/module/_io/test/test_bufferedio.py --- a/pypy/module/_io/test/test_bufferedio.py +++ b/pypy/module/_io/test/test_bufferedio.py @@ -631,6 +631,19 @@ f.flush() assert raw.getvalue() == b'1b\n2def\n3\n' + def test_readline(self): + import _io as io + with io.BytesIO(b"abc\ndef\nxyzzy\nfoo\x00bar\nanother line") as raw: + with io.BufferedRandom(raw, buffer_size=10) as f: + assert f.readline() == b"abc\n" + assert f.readline(10) == b"def\n" + assert f.readline(2) == b"xy" + assert f.readline(4) == b"zzy\n" + assert f.readline() == b"foo\x00bar\n" + assert f.readline(None) == b"another line" + raises(TypeError, f.readline, 5.3) + + class TestNonReentrantLock: spaceconfig = dict(usemodules=['thread']) diff --git a/pypy/module/_io/test/test_bytesio.py b/pypy/module/_io/test/test_bytesio.py --- a/pypy/module/_io/test/test_bytesio.py +++ b/pypy/module/_io/test/test_bytesio.py @@ -75,3 +75,19 @@ b = _io.BytesIO("hello") b.close() raises(ValueError, b.readinto, bytearray("hello")) + + def test_readline(self): + import _io + f = _io.BytesIO(b'abc\ndef\nxyzzy\nfoo\x00bar\nanother line') + assert f.readline() == b'abc\n' + assert f.readline(10) == b'def\n' + assert f.readline(2) == b'xy' + assert f.readline(4) == b'zzy\n' + assert f.readline() == b'foo\x00bar\n' + assert f.readline(None) == b'another line' + raises(TypeError, f.readline, 5.3) + + def test_overread(self): + import _io + f = _io.BytesIO(b'abc') + assert f.readline(10) == b'abc' diff --git a/pypy/module/micronumpy/__init__.py b/pypy/module/micronumpy/__init__.py --- a/pypy/module/micronumpy/__init__.py +++ b/pypy/module/micronumpy/__init__.py @@ -27,9 +27,6 @@ 'True_': 'types.Bool.True', 'False_': 'types.Bool.False', - 'bool': 'space.w_bool', - 'int': 'space.w_int', - 'typeinfo': 'interp_dtype.get_dtype_cache(space).w_typeinfo', 'generic': 'interp_boxes.W_GenericBox', @@ -82,7 +79,6 @@ # ufuncs for exposed, impl in [ - ("abs", "absolute"), ("absolute", "absolute"), ("add", "add"), ("arccos", "arccos"), @@ -163,14 +159,17 @@ interpleveldefs[exposed] = "interp_ufuncs.get(space).%s" % impl appleveldefs = { - 'average': 'app_numpy.average', - 'sum': 'app_numpy.sum', - 'min': 'app_numpy.min', - 'identity': 'app_numpy.identity', - 'eye': 'app_numpy.eye', - 'max': 'app_numpy.max', 'arange': 'app_numpy.arange', } + def setup_after_space_initialization(self): + space = self.space + all_list = sorted(Module.interpleveldefs.keys() + \ + Module.appleveldefs.keys()) + # found by set(numpypy.__all__) - set(numpy.__all__) + all_list.remove('set_string_function') + all_list.remove('typeinfo') + w_all = space.wrap(all_list) + space.setitem(self.w_dict, space.new_interned_str('__all__'), w_all) if 0 and long_double_size == 16: Module.interpleveldefs['float128'] = 'interp_boxes.W_Float128Box' diff --git a/pypy/module/micronumpy/app_numpy.py b/pypy/module/micronumpy/app_numpy.py --- a/pypy/module/micronumpy/app_numpy.py +++ b/pypy/module/micronumpy/app_numpy.py @@ -2,82 +2,6 @@ import _numpypy -def average(a): - # This implements a weighted average, for now we don't implement the - # weighting, just the average part! - if not hasattr(a, "mean"): - a = _numpypy.array(a) - return a.mean() - -def identity(n, dtype=None): - a = _numpypy.zeros((n, n), dtype=dtype) - for i in range(n): - a[i][i] = 1 - return a - -def eye(n, m=None, k=0, dtype=None): - if m is None: - m = n - a = _numpypy.zeros((n, m), dtype=dtype) - ni = 0 - mi = 0 - - if k < 0: - p = n + k - ni = -k - else: - p = n - k - mi = k - - while ni < n and mi < m: - a[ni][mi] = 1 - ni += 1 - mi += 1 - return a - -def sum(a,axis=None, out=None): - '''sum(a, axis=None) - Sum of array elements over a given axis. - - Parameters - ---------- - a : array_like - Elements to sum. - axis : integer, optional - Axis over which the sum is taken. By default `axis` is None, - and all elements are summed. - - Returns - ------- - sum_along_axis : ndarray - An array with the same shape as `a`, with the specified - axis removed. If `a` is a 0-d array, or if `axis` is None, a scalar - is returned. If an output array is specified, a reference to - `out` is returned. - - See Also - -------- - ndarray.sum : Equivalent method. - ''' - # TODO: add to doc (once it's implemented): cumsum : Cumulative sum of array elements. - if not hasattr(a, "sum"): - a = _numpypy.array(a) - return a.sum(axis=axis, out=out) - -def min(a, axis=None, out=None): - if not hasattr(a, "min"): - a = _numpypy.array(a) - if a.size < 1: - return _numpypy.array([]) - return a.min(axis=axis, out=out) - -def max(a, axis=None, out=None): - if not hasattr(a, "max"): - a = _numpypy.array(a) - if a.size < 1: - return _numpypy.array([]) - return a.max(axis=axis, out=out) - def arange(start, stop=None, step=1, dtype=None): '''arange([start], stop[, step], dtype=None) Generate values in the half-interval [start, stop). diff --git a/pypy/module/micronumpy/interp_numarray.py b/pypy/module/micronumpy/interp_numarray.py --- a/pypy/module/micronumpy/interp_numarray.py +++ b/pypy/module/micronumpy/interp_numarray.py @@ -453,13 +453,17 @@ @unwrap_spec(mode=str) def descr_choose(self, space, w_choices, mode='raise', w_out=None): - if w_out is not None and not isinstance(w_out, W_NDimArray): + if space.is_none(w_out): + w_out = None + elif not isinstance(w_out, W_NDimArray): raise OperationError(space.w_TypeError, space.wrap( "return arrays must be of ArrayType")) return interp_arrayops.choose(space, self, w_choices, w_out, mode) def descr_clip(self, space, w_min, w_max, w_out=None): - if w_out is not None and not isinstance(w_out, W_NDimArray): + if space.is_none(w_out): + w_out = None + elif not isinstance(w_out, W_NDimArray): raise OperationError(space.w_TypeError, space.wrap( "return arrays must be of ArrayType")) min = convert_to_array(space, w_min) diff --git a/pypy/module/micronumpy/test/test_arrayops.py b/pypy/module/micronumpy/test/test_arrayops.py --- a/pypy/module/micronumpy/test/test_arrayops.py +++ b/pypy/module/micronumpy/test/test_arrayops.py @@ -99,10 +99,13 @@ def test_choose_out(self): from _numpypy import array a, b, c = array([1, 2, 3]), [4, 5, 6], 13 + r = array([2, 1, 0]).choose([a, b, c], out=None) + assert (r == [13, 5, 3]).all() + assert (a == [1, 2, 3]).all() r = array([2, 1, 0]).choose([a, b, c], out=a) assert (r == [13, 5, 3]).all() assert (a == [13, 5, 3]).all() - + def test_choose_modes(self): from _numpypy import array a, b, c = array([1, 2, 3]), [4, 5, 6], 13 diff --git a/pypy/module/micronumpy/test/test_complex.py b/pypy/module/micronumpy/test/test_complex.py --- a/pypy/module/micronumpy/test/test_complex.py +++ b/pypy/module/micronumpy/test/test_complex.py @@ -393,7 +393,7 @@ def test_conjugate(self): from _numpypy import conj, conjugate, complex128, complex64 - import _numpypy as np + import numpypy as np c0 = complex128(complex(2.5, 0)) c1 = complex64(complex(1, 2)) @@ -506,8 +506,8 @@ def test_basic(self): from _numpypy import (complex128, complex64, add, array, dtype, - subtract as sub, multiply, divide, negative, abs, floor_divide, - real, imag, sign) + subtract as sub, multiply, divide, negative, absolute as abs, + floor_divide, real, imag, sign) from _numpypy import (equal, not_equal, greater, greater_equal, less, less_equal, isnan) complex_dtypes = [complex64, complex128] diff --git a/pypy/module/micronumpy/test/test_dtypes.py b/pypy/module/micronumpy/test/test_dtypes.py --- a/pypy/module/micronumpy/test/test_dtypes.py +++ b/pypy/module/micronumpy/test/test_dtypes.py @@ -614,9 +614,6 @@ def test_various_types(self): import _numpypy as numpy - assert numpy.bool is bool - assert numpy.int is int - assert numpy.int16 is numpy.short assert numpy.int8 is numpy.byte assert numpy.bool_ is numpy.bool8 diff --git a/pypy/module/micronumpy/test/test_module.py b/pypy/module/micronumpy/test/test_module.py deleted file mode 100644 --- a/pypy/module/micronumpy/test/test_module.py +++ /dev/null @@ -1,25 +0,0 @@ -from pypy.module.micronumpy.test.test_base import BaseNumpyAppTest - - -class AppTestNumPyModule(BaseNumpyAppTest): - def test_average(self): - from _numpypy import array, average - assert average(range(10)) == 4.5 - assert average(array(range(10))) == 4.5 - - def test_sum(self): - from _numpypy import array, sum - assert sum(range(10)) == 45 - assert sum(array(range(10))) == 45 - - def test_min(self): - from _numpypy import array, min, zeros - assert min(range(10)) == 0 - assert min(array(range(10))) == 0 - assert list(min(zeros((0, 2)), axis=1)) == [] - - def test_max(self): - from _numpypy import array, max, zeros - assert max(range(10)) == 9 - assert max(array(range(10))) == 9 - assert list(max(zeros((0, 2)), axis=1)) == [] diff --git a/pypy/module/micronumpy/test/test_numarray.py b/pypy/module/micronumpy/test/test_numarray.py --- a/pypy/module/micronumpy/test/test_numarray.py +++ b/pypy/module/micronumpy/test/test_numarray.py @@ -1141,7 +1141,7 @@ assert (a.mean(1) == [0.5, 2.5, 4.5, 6.5, 8.5]).all() def test_sum(self): - from _numpypy import array + from _numpypy import array, zeros a = array(range(5)) assert a.sum() == 10 assert a[:4].sum() == 6 @@ -1156,6 +1156,8 @@ assert b == d assert b is d + assert list(zeros((0, 2)).sum(axis=1)) == [] + def test_reduce_nd(self): from numpypy import arange, array, multiply a = arange(15).reshape(5, 3) @@ -1186,55 +1188,6 @@ assert (array([[1,2],[3,4]]).prod(0) == [3, 8]).all() assert (array([[1,2],[3,4]]).prod(1) == [2, 12]).all() - def test_identity(self): - from _numpypy import identity, array - from _numpypy import int32, float64, dtype - a = identity(0) - assert len(a) == 0 - assert a.dtype == dtype('float64') - assert a.shape == (0, 0) - b = identity(1, dtype=int32) - assert len(b) == 1 - assert b[0][0] == 1 - assert b.shape == (1, 1) - assert b.dtype == dtype('int32') - c = identity(2) - assert c.shape == (2, 2) - assert (c == [[1, 0], [0, 1]]).all() - d = identity(3, dtype='int32') - assert d.shape == (3, 3) - assert d.dtype == dtype('int32') - assert (d == [[1, 0, 0], [0, 1, 0], [0, 0, 1]]).all() - - def test_eye(self): - from _numpypy import eye - from _numpypy import int32, dtype - a = eye(0) - assert len(a) == 0 - assert a.dtype == dtype('float64') - assert a.shape == (0, 0) - b = eye(1, dtype=int32) - assert len(b) == 1 - assert b[0][0] == 1 - assert b.shape == (1, 1) - assert b.dtype == dtype('int32') - c = eye(2) - assert c.shape == (2, 2) - assert (c == [[1, 0], [0, 1]]).all() - d = eye(3, dtype='int32') - assert d.shape == (3, 3) - assert d.dtype == dtype('int32') - assert (d == [[1, 0, 0], [0, 1, 0], [0, 0, 1]]).all() - e = eye(3, 4) - assert e.shape == (3, 4) - assert (e == [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0]]).all() - f = eye(2, 4, k=3) - assert f.shape == (2, 4) - assert (f == [[0, 0, 0, 1], [0, 0, 0, 0]]).all() - g = eye(3, 4, k=-1) - assert g.shape == (3, 4) - assert (g == [[0, 0, 0, 0], [1, 0, 0, 0], [0, 1, 0, 0]]).all() - def test_prod(self): from _numpypy import array a = array(range(1, 6)) @@ -1242,24 +1195,28 @@ assert a[:4].prod() == 24.0 def test_max(self): - from _numpypy import array + from _numpypy import array, zeros a = array([-1.2, 3.4, 5.7, -3.0, 2.7]) assert a.max() == 5.7 b = array([]) raises(ValueError, "b.max()") + assert list(zeros((0, 2)).max(axis=1)) == [] + def test_max_add(self): from _numpypy import array a = array([-1.2, 3.4, 5.7, -3.0, 2.7]) assert (a + a).max() == 11.4 def test_min(self): - from _numpypy import array + from _numpypy import array, zeros a = array([-1.2, 3.4, 5.7, -3.0, 2.7]) assert a.min() == -3.0 b = array([]) raises(ValueError, "b.min()") + assert list(zeros((0, 2)).min(axis=1)) == [] + def test_argmax(self): from _numpypy import array a = array([-1.2, 3.4, 5.7, -3.0, 2.7]) @@ -1739,7 +1696,8 @@ from _numpypy import array a = array([1, 2, 17, -3, 12]) assert (a.clip(-2, 13) == [1, 2, 13, -2, 12]).all() - assert (a.clip(-1, 1) == [1, 1, 1, -1, 1]).all() + assert (a.clip(-1, 1, out=None) == [1, 1, 1, -1, 1]).all() + assert (a == [1, 2, 17, -3, 12]).all() assert (a.clip(-1, [1, 2, 3, 4, 5]) == [1, 2, 3, -1, 5]).all() assert (a.clip(-2, 13, out=a) == [1, 2, 13, -2, 12]).all() assert (a == [1, 2, 13, -2, 12]).all() diff --git a/pypy/module/micronumpy/test/test_outarg.py b/pypy/module/micronumpy/test/test_outarg.py --- a/pypy/module/micronumpy/test/test_outarg.py +++ b/pypy/module/micronumpy/test/test_outarg.py @@ -83,22 +83,9 @@ b = add(10, 10, out=out) assert b==out assert b.dtype == out.dtype - - def test_applevel(self): - from _numpypy import array, sum, max, min - a = array([[1, 2], [3, 4]]) - out = array([[0, 0], [0, 0]]) - c = sum(a, axis=0, out=out[0]) - assert (c == [4, 6]).all() - assert (c == out[0]).all() - assert (c != out[1]).all() - c = max(a, axis=1, out=out[0]) - assert (c == [2, 4]).all() - assert (c == out[0]).all() - assert (c != out[1]).all() - + def test_ufunc_cast(self): - from _numpypy import array, negative, add, sum + from _numpypy import array, negative, add a = array(16, dtype = int) c = array(0, dtype = float) b = negative(a, out=c) @@ -106,7 +93,7 @@ b = add(a, a, out=c) assert b == c d = array([16, 16], dtype=int) - b = sum(d, out=c) + b = d.sum(out=c) assert b == c #cast_error = raises(TypeError, negative, c, a) #assert str(cast_error.value) == \ diff --git a/pypy/module/test_lib_pypy/numpypy/core/test_fromnumeric.py b/pypy/module/test_lib_pypy/numpypy/core/test_fromnumeric.py --- a/pypy/module/test_lib_pypy/numpypy/core/test_fromnumeric.py +++ b/pypy/module/test_lib_pypy/numpypy/core/test_fromnumeric.py @@ -34,9 +34,23 @@ # a = array([(1, 2), (3, 4)], dtype=[('x', 'i4'), ('y', 'i4')]) # assert shape(a) == (2,) + def test_clip(self): + import numpypy as np + a = np.arange(10) + b = np.clip(a, 1, 8) + assert (b == [1, 1, 2, 3, 4, 5, 6, 7, 8, 8]).all() + assert (a == [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]).all() + b = np.clip(a, 3, 6, out=a) + assert (b == [3, 3, 3, 3, 4, 5, 6, 6, 6, 6]).all() + assert (a == [3, 3, 3, 3, 4, 5, 6, 6, 6, 6]).all() + a = np.arange(10) + b = np.clip(a, [3,4,1,1,1,4,4,4,4,4], 8) + assert (b == [3, 4, 2, 3, 4, 5, 6, 7, 8, 8]).all() + assert (a == [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]).all() + def test_sum(self): # tests taken from numpy/core/fromnumeric.py docstring - from numpypy import array, sum, ones + from numpypy import array, sum, ones, zeros assert sum([0.5, 1.5])== 2.0 assert sum([[0, 1], [0, 5]]) == 6 # assert sum([0.5, 0.7, 0.2, 1.5], dtype=int32) == 1 @@ -45,9 +59,20 @@ # If the accumulator is too small, overflow occurs: # assert ones(128, dtype=int8).sum(dtype=int8) == -128 + assert sum(range(10)) == 45 + assert sum(array(range(10))) == 45 + assert list(sum(zeros((0, 2)), axis=1)) == [] + + a = array([[1, 2], [3, 4]]) + out = array([[0, 0], [0, 0]]) + c = sum(a, axis=0, out=out[0]) + assert (c == [4, 6]).all() + assert (c == out[0]).all() + assert (c != out[1]).all() + def test_amin(self): # tests taken from numpy/core/fromnumeric.py docstring - from numpypy import array, arange, amin + from numpypy import array, arange, amin, zeros a = arange(4).reshape((2,2)) assert amin(a) == 0 # # Minima along the first axis @@ -60,9 +85,20 @@ # assert amin(b) == nan # assert nanmin(b) == 0.0 + assert amin(range(10)) == 0 + assert amin(array(range(10))) == 0 + assert list(amin(zeros((0, 2)), axis=1)) == [] + + a = array([[1, 2], [3, 4]]) + out = array([[0, 0], [0, 0]]) + c = amin(a, axis=1, out=out[0]) + assert (c == [1, 3]).all() + assert (c == out[0]).all() + assert (c != out[1]).all() + def test_amax(self): # tests taken from numpy/core/fromnumeric.py docstring - from numpypy import array, arange, amax + from numpypy import array, arange, amax, zeros a = arange(4).reshape((2,2)) assert amax(a) == 3 # assert (amax(a, axis=0) == array([2, 3])).all() @@ -73,6 +109,17 @@ # assert amax(b) == nan # assert nanmax(b) == 4.0 + assert amax(range(10)) == 9 + assert amax(array(range(10))) == 9 + assert list(amax(zeros((0, 2)), axis=1)) == [] + + a = array([[1, 2], [3, 4]]) + out = array([[0, 0], [0, 0]]) + c = amax(a, axis=1, out=out[0]) + assert (c == [2, 4]).all() + assert (c == out[0]).all() + assert (c != out[1]).all() + def test_alen(self): # tests taken from numpy/core/fromnumeric.py docstring from numpypy import array, zeros, alen diff --git a/pypy/module/test_lib_pypy/numpypy/core/test_numeric.py b/pypy/module/test_lib_pypy/numpypy/core/test_numeric.py --- a/pypy/module/test_lib_pypy/numpypy/core/test_numeric.py +++ b/pypy/module/test_lib_pypy/numpypy/core/test_numeric.py @@ -20,6 +20,7 @@ assert base_repr(-12, 10, 4) == '-000012' assert base_repr(-12, 4) == '-30' + class AppTestRepr(BaseNumpyAppTest): def test_repr(self): from numpypy import array @@ -146,10 +147,10 @@ def test_equal(self): from _numpypy import array from numpypy import array_equal - + a = [1, 2, 3] b = [1, 2, 3] - + assert array_equal(a, b) assert array_equal(a, array(b)) assert array_equal(array(a), b) @@ -158,10 +159,10 @@ def test_not_equal(self): from _numpypy import array from numpypy import array_equal - + a = [1, 2, 3] b = [1, 2, 4] - + assert not array_equal(a, b) assert not array_equal(a, array(b)) assert not array_equal(array(a), b) @@ -170,17 +171,17 @@ def test_mismatched_shape(self): from _numpypy import array from numpypy import array_equal - + a = [1, 2, 3] b = [[1, 2, 3], [1, 2, 3]] - + assert not array_equal(a, b) assert not array_equal(a, array(b)) assert not array_equal(array(a), b) assert not array_equal(array(a), array(b)) + class AppTestNumeric(BaseNumpyAppTest): - def test_outer(self): from _numpypy import array from numpypy import outer @@ -192,3 +193,22 @@ [12, 15, 18]]) assert (res == expected).all() + def test_identity(self): + from _numpypy import array, int32, float64, dtype + from numpypy import identity + a = identity(0) + assert len(a) == 0 + assert a.dtype == dtype('float64') + assert a.shape == (0, 0) + b = identity(1, dtype=int32) + assert len(b) == 1 + assert b[0][0] == 1 + assert b.shape == (1, 1) + assert b.dtype == dtype('int32') + c = identity(2) + assert c.shape == (2, 2) + assert (c == [[1, 0], [0, 1]]).all() + d = identity(3, dtype='int32') + assert d.shape == (3, 3) + assert d.dtype == dtype('int32') + assert (d == [[1, 0, 0], [0, 1, 0], [0, 0, 1]]).all() diff --git a/pypy/module/test_lib_pypy/numpypy/core/test_shape_base.py b/pypy/module/test_lib_pypy/numpypy/core/test_shape_base.py --- a/pypy/module/test_lib_pypy/numpypy/core/test_shape_base.py +++ b/pypy/module/test_lib_pypy/numpypy/core/test_shape_base.py @@ -129,35 +129,3 @@ np.ones((a.shape[0], a.shape[1] + b.shape[1], a.shape[2]))) - - def test_dstack(self): - import numpypy as np - a = np.array((1, 2, 3)) - b = np.array((2, 3, 4)) - c = np.dstack((a, b)) - assert np.array_equal(c, [[[1, 2], [2, 3], [3, 4]]]) - - a = np.array([[1], [2], [3]]) - b = np.array([[2], [3], [4]]) - c = np.dstack((a, b)) - assert np.array_equal(c, [[[1, 2]], [[2, 3]], [[3, 4]]]) - - #skip("https://bugs.pypy.org/issue1394") - for shape1, shape2 in [[(4, 2, 3), (4, 2, 7)], - [(7, 2, 0), (7, 2, 10)], - [(7, 2, 0), (7, 2, 0)]]: - a, b = np.ones(shape1), np.ones(shape2) - assert np.all(np.dstack((a, b)) == - np.ones((a.shape[0], - a.shape[1], - a.shape[2] + b.shape[2]))) - - for shape1, shape2 in [[(4, 2, 3, 5), (4, 2, 7, 5)], - [(7, 2, 0, 5), (7, 2, 10, 5)], - [(7, 2, 0, 5), (7, 2, 0, 5)]]: - a, b = np.ones(shape1), np.ones(shape2) - assert np.all(np.dstack((a, b)) == - np.ones((a.shape[0], - a.shape[1], - a.shape[2] + b.shape[2], - a.shape[3]))) diff --git a/pypy/module/test_lib_pypy/numpypy/lib/test_function_base.py b/pypy/module/test_lib_pypy/numpypy/lib/test_function_base.py new file mode 100644 --- /dev/null +++ b/pypy/module/test_lib_pypy/numpypy/lib/test_function_base.py @@ -0,0 +1,7 @@ +from pypy.module.micronumpy.test.test_base import BaseNumpyAppTest + +class AppTestFunctionBase(BaseNumpyAppTest): + def test_average(self): + from numpypy import array, average + assert average(range(10)) == 4.5 + assert average(array(range(10))) == 4.5 diff --git a/pypy/module/test_lib_pypy/numpypy/lib/test_shape_base_lib.py b/pypy/module/test_lib_pypy/numpypy/lib/test_shape_base_lib.py new file mode 100644 --- /dev/null +++ b/pypy/module/test_lib_pypy/numpypy/lib/test_shape_base_lib.py @@ -0,0 +1,34 @@ +from pypy.module.micronumpy.test.test_base import BaseNumpyAppTest + +class AppTestShapeBase(BaseNumpyAppTest): + def test_dstack(self): + import numpypy as np + a = np.array((1, 2, 3)) + b = np.array((2, 3, 4)) + c = np.dstack((a, b)) + assert np.array_equal(c, [[[1, 2], [2, 3], [3, 4]]]) + + a = np.array([[1], [2], [3]]) + b = np.array([[2], [3], [4]]) + c = np.dstack((a, b)) + assert np.array_equal(c, [[[1, 2]], [[2, 3]], [[3, 4]]]) + + #skip("https://bugs.pypy.org/issue1394") + for shape1, shape2 in [[(4, 2, 3), (4, 2, 7)], + [(7, 2, 0), (7, 2, 10)], + [(7, 2, 0), (7, 2, 0)]]: + a, b = np.ones(shape1), np.ones(shape2) + assert np.all(np.dstack((a, b)) == + np.ones((a.shape[0], + a.shape[1], + a.shape[2] + b.shape[2]))) + + for shape1, shape2 in [[(4, 2, 3, 5), (4, 2, 7, 5)], + [(7, 2, 0, 5), (7, 2, 10, 5)], + [(7, 2, 0, 5), (7, 2, 0, 5)]]: + a, b = np.ones(shape1), np.ones(shape2) + assert np.all(np.dstack((a, b)) == + np.ones((a.shape[0], + a.shape[1], + a.shape[2] + b.shape[2], + a.shape[3]))) diff --git a/pypy/module/test_lib_pypy/numpypy/lib/test_twodim_base.py b/pypy/module/test_lib_pypy/numpypy/lib/test_twodim_base.py new file mode 100644 --- /dev/null +++ b/pypy/module/test_lib_pypy/numpypy/lib/test_twodim_base.py @@ -0,0 +1,31 @@ +from pypy.module.micronumpy.test.test_base import BaseNumpyAppTest + +class AppTestTwoDimBase(BaseNumpyAppTest): + def test_eye(self): + from _numpypy import int32, dtype + from numpypy import eye + a = eye(0) + assert len(a) == 0 + assert a.dtype == dtype('float64') + assert a.shape == (0, 0) + b = eye(1, dtype=int32) + assert len(b) == 1 + assert b[0][0] == 1 + assert b.shape == (1, 1) + assert b.dtype == dtype('int32') + c = eye(2) + assert c.shape == (2, 2) + assert (c == [[1, 0], [0, 1]]).all() + d = eye(3, dtype='int32') + assert d.shape == (3, 3) + assert d.dtype == dtype('int32') + assert (d == [[1, 0, 0], [0, 1, 0], [0, 0, 1]]).all() + e = eye(3, 4) + assert e.shape == (3, 4) + assert (e == [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0]]).all() + f = eye(2, 4, k=3) + assert f.shape == (2, 4) + assert (f == [[0, 0, 0, 1], [0, 0, 0, 0]]).all() + g = eye(3, 4, k=-1) + assert g.shape == (3, 4) + assert (g == [[0, 0, 0, 0], [1, 0, 0, 0], [0, 1, 0, 0]]).all() diff --git a/pypy/module/test_lib_pypy/numpypy/test_numpy.py b/pypy/module/test_lib_pypy/numpypy/test_numpy.py --- a/pypy/module/test_lib_pypy/numpypy/test_numpy.py +++ b/pypy/module/test_lib_pypy/numpypy/test_numpy.py @@ -1,4 +1,6 @@ -class AppTestNumpy: +from pypy.module.micronumpy.test.test_base import BaseNumpyAppTest + +class AppTestNumpy(BaseNumpyAppTest): spaceconfig = dict(usemodules=['micronumpy']) def test_imports(self): @@ -11,6 +13,7 @@ def test_min_max_after_import(self): import __builtin__ + from __builtin__ import * from numpypy import * assert min is __builtin__.min @@ -25,6 +28,28 @@ assert min(4, 3, 2, 1) == 1 assert max(1, 2, 3, 4) == 4 - from numpypy import min, max + from numpypy import min, max, amin, amax assert min is not __builtin__.min assert max is not __builtin__.max + assert min is amin + assert max is amax + + def test_builtin_aliases(self): + import __builtin__ + import numpypy + from numpypy import * + + for name in ['bool', 'int', 'long', 'float', 'complex', 'object', + 'unicode', 'str']: + assert name not in locals() + assert getattr(numpypy, name) is getattr(__builtin__, name) + + def test_typeinfo(self): + import numpypy + assert 'typeinfo' not in dir(numpypy) + assert 'typeinfo' in dir(numpypy.core.multiarray) + + def test_set_string_function(self): + import numpypy + assert numpypy.set_string_function is not \ + numpypy.core.multiarray.set_string_function diff --git a/rpython/jit/backend/arm/regalloc.py b/rpython/jit/backend/arm/regalloc.py --- a/rpython/jit/backend/arm/regalloc.py +++ b/rpython/jit/backend/arm/regalloc.py @@ -736,7 +736,7 @@ classptr = y_val # here, we have to go back from 'classptr' to the value expected # from reading the 16 bits in the object header - from rpython.rtyper.memory.gctypelayout import GCData + from rpython.memory.gctypelayout import GCData sizeof_ti = rffi.sizeof(GCData.TYPE_INFO) type_info_group = llop.gc_get_type_info_group(llmemory.Address) type_info_group = rffi.cast(lltype.Signed, type_info_group) diff --git a/rpython/jit/backend/llsupport/gc.py b/rpython/jit/backend/llsupport/gc.py --- a/rpython/jit/backend/llsupport/gc.py +++ b/rpython/jit/backend/llsupport/gc.py From noreply at buildbot.pypy.org Sat Feb 23 21:13:01 2013 From: noreply at buildbot.pypy.org (mattip) Date: Sat, 23 Feb 2013 21:13:01 +0100 (CET) Subject: [pypy-commit] pypy numpypy-disable-longdouble: use flag ENABLED_LONG_DOUBLE instead of '0' Message-ID: <20130223201301.1EDB01C0327@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: numpypy-disable-longdouble Changeset: r61689:3963e0671b45 Date: 2013-02-23 21:51 +0200 http://bitbucket.org/pypy/pypy/changeset/3963e0671b45/ Log: use flag ENABLED_LONG_DOUBLE instead of '0' diff --git a/pypy/module/micronumpy/__init__.py b/pypy/module/micronumpy/__init__.py --- a/pypy/module/micronumpy/__init__.py +++ b/pypy/module/micronumpy/__init__.py @@ -1,5 +1,5 @@ from pypy.interpreter.mixedmodule import MixedModule -from pypy.module.micronumpy.interp_boxes import long_double_size +from pypy.module.micronumpy.interp_boxes import long_double_size, ENABLED_LONG_DOUBLE class Module(MixedModule): @@ -59,8 +59,6 @@ 'float16': 'interp_boxes.W_Float16Box', 'float32': 'interp_boxes.W_Float32Box', 'float64': 'interp_boxes.W_Float64Box', - # 'longdouble': 'interp_boxes.W_LongDoubleBox', - # 'longfloat': 'interp_boxes.W_LongDoubleBox', 'intp': 'types.IntP.BoxType', 'uintp': 'types.UIntP.BoxType', 'flexible': 'interp_boxes.W_FlexibleBox', @@ -73,8 +71,6 @@ 'complex_': 'interp_boxes.W_Complex128Box', 'complex128': 'interp_boxes.W_Complex128Box', 'complex64': 'interp_boxes.W_Complex64Box', - # 'clongdouble': 'interp_boxes.W_CLongDoubleBox', - # 'clongfloat': 'interp_boxes.W_CLongDoubleBox', } # ufuncs @@ -171,9 +167,22 @@ w_all = space.wrap(all_list) space.setitem(self.w_dict, space.new_interned_str('__all__'), w_all) -if 0 and long_double_size == 16: - Module.interpleveldefs['float128'] = 'interp_boxes.W_Float128Box' - Module.interpleveldefs['complex256'] = 'interp_boxes.W_Complex256Box' -elif 0 and long_double_size == 12: - Module.interpleveldefs['float96'] = 'interp_boxes.W_Float96Box' - Module.interpleveldefs['complex192'] = 'interp_boxes.W_Complex192Box' +if ENABLED_LONG_DOUBLE: + long_double_dtypes = [ + ('longdouble', 'interp_boxes.W_LongDoubleBox'), + ('longfloat', 'interp_boxes.W_LongDoubleBox'), + ('clongdouble', 'interp_boxes.W_CLongDoubleBox'), + ('clongfloat', 'interp_boxes.W_CLongDoubleBox'), + ] + if long_double_size == 16: + long_double_dtypes += [ + ('float128', 'interp_boxes.W_Float128Box'), + ('complex256', 'interp_boxes.W_Complex256Box'), + ] + elif long_double_size == 12: + long_double_dtypes += [ + ('float96', 'interp_boxes.W_Float96Box'), + ('complex192', 'interp_boxes.W_Complex192Box'), + ] + for dt, box in long_double_dtypes: + Module.interpleveldefs[dt] = box diff --git a/pypy/module/micronumpy/interp_boxes.py b/pypy/module/micronumpy/interp_boxes.py --- a/pypy/module/micronumpy/interp_boxes.py +++ b/pypy/module/micronumpy/interp_boxes.py @@ -16,10 +16,12 @@ MIXIN_64 = (int_typedef,) if LONG_BIT == 64 else () # Is this the proper place for this? +ENABLED_LONG_DOUBLE = False long_double_size = rffi.sizeof_c_type('long double', ignore_errors=True) + import os if long_double_size == 8 and os.name == 'nt': - # this is a lie, or maybe a wish + # this is a lie, or maybe a wish, MS fakes longdouble math with double long_double_size = 12 @@ -335,7 +337,7 @@ descr__new__, _get_dtype = new_dtype_getter("complex128") _COMPONENTS_BOX = W_Float64Box -if 0 and long_double_size == 12: +if ENABLED_LONG_DOUBLE and long_double_size == 12: class W_Float96Box(W_FloatingBox, PrimitiveBox): descr__new__, _get_dtype = new_dtype_getter("float96") @@ -347,7 +349,7 @@ W_CLongDoubleBox = W_Complex192Box -elif 0 and long_double_size == 16: +elif ENABLED_LONG_DOUBLE and long_double_size == 16: class W_Float128Box(W_FloatingBox, PrimitiveBox): descr__new__, _get_dtype = new_dtype_getter("float128") W_LongDoubleBox = W_Float128Box @@ -358,7 +360,7 @@ W_CLongDoubleBox = W_Complex256Box -elif 0: +elif ENABLED_LONG_DOUBLE: W_LongDoubleBox = W_Float64Box W_CLongDoubleBox = W_Complex64Box @@ -526,7 +528,7 @@ __new__ = interp2app(W_Float64Box.descr__new__.im_func), ) -if 0 and long_double_size == 12: +if ENABLED_LONG_DOUBLE and long_double_size == 12: W_Float96Box.typedef = TypeDef("float96", (W_FloatingBox.typedef), __module__ = "numpypy", @@ -540,7 +542,7 @@ imag = GetSetProperty(W_ComplexFloatingBox.descr_get_imag), ) -elif 0 and long_double_size == 16: +elif ENABLED_LONG_DOUBLE and long_double_size == 16: W_Float128Box.typedef = TypeDef("float128", (W_FloatingBox.typedef), __module__ = "numpypy", diff --git a/pypy/module/micronumpy/interp_dtype.py b/pypy/module/micronumpy/interp_dtype.py --- a/pypy/module/micronumpy/interp_dtype.py +++ b/pypy/module/micronumpy/interp_dtype.py @@ -474,7 +474,7 @@ aliases=["complex"], float_type = self.w_float64dtype, ) - if 0 and interp_boxes.long_double_size == 12: + if interp_boxes.ENABLED_LONG_DOUBLE and interp_boxes.long_double_size == 12: self.w_float96dtype = W_Dtype( types.Float96(), num=13, @@ -497,7 +497,7 @@ ) self.w_longdouble = self.w_float96dtype self.w_clongdouble = self.w_complex192dtype - elif 0 and interp_boxes.long_double_size == 16: + elif interp_boxes.ENABLED_LONG_DOUBLE and interp_boxes.long_double_size == 16: self.w_float128dtype = W_Dtype( types.Float128(), num=13, @@ -520,7 +520,7 @@ ) self.w_longdouble = self.w_float128dtype self.w_clongdouble = self.w_complex256dtype - elif 0: + elif interp_boxes.ENABLED_LONG_DOUBLE: self.w_float64dtype.aliases += ["longdouble", "longfloat"] self.w_complex128dtype.aliases += ["clongdouble", "clongfloat"] self.w_longdouble = self.w_float64dtype @@ -596,27 +596,27 @@ char=UINTPLTR, w_box_type = space.gettypefor(uintp_box), ) + float_dtypes = [self.w_float16dtype, + self.w_float32dtype, self.w_float64dtype, + ] + complex_dtypes = [self.w_complex64dtype, self.w_complex128dtype] + if interp_boxes.ENABLED_LONG_DOUBLE: + float_dtypes.append(self.w_longdouble) + complex_dtypes.append(self.w_clongdouble) self.builtin_dtypes = [ self.w_booldtype, self.w_int8dtype, self.w_uint8dtype, self.w_int16dtype, self.w_uint16dtype, self.w_longdtype, self.w_ulongdtype, self.w_int32dtype, self.w_uint32dtype, - self.w_int64dtype, self.w_uint64dtype, - self.w_float16dtype, - self.w_float32dtype, self.w_float64dtype, - # self.w_longdouble, - self.w_complex64dtype, self.w_complex128dtype, - # self.w_clongdouble, + self.w_int64dtype, self.w_uint64dtype] + \ + float_dtypes + complex_dtypes + [ self.w_stringdtype, self.w_unicodedtype, self.w_voiddtype, self.w_intpdtype, self.w_uintpdtype, ] self.float_dtypes_by_num_bytes = sorted( (dtype.itemtype.get_element_size(), dtype) - for dtype in [self.w_float16dtype, self.w_float32dtype, - self.w_float64dtype, - # self.w_longdouble, - ] + for dtype in float_dtypes ) self.dtypes_by_num = {} self.dtypes_by_name = {} @@ -659,7 +659,6 @@ 'LONGLONG': self.w_int64dtype, 'SHORT': self.w_int16dtype, 'VOID': self.w_voiddtype, - #'LONGDOUBLE': self.w_longdouble, 'UBYTE': self.w_uint8dtype, 'UINTP': self.w_ulongdtype, 'ULONG': self.w_ulongdtype, @@ -682,8 +681,11 @@ 'USHORT': self.w_uint16dtype, 'FLOAT': self.w_float32dtype, 'BOOL': self.w_booldtype, - #'CLONGDOUBLE': self.w_clongdouble, } + if interp_boxes.ENABLED_LONG_DOUBLE: + typeinfo_full['LONGDOUBLE'] = self.w_longdouble + typeinfo_full['CLONGDOUBLE'] = self.w_clongdouble + typeinfo_partial = { 'Generic': interp_boxes.W_GenericBox, 'Character': interp_boxes.W_CharacterBox, diff --git a/pypy/module/micronumpy/interp_ufuncs.py b/pypy/module/micronumpy/interp_ufuncs.py --- a/pypy/module/micronumpy/interp_ufuncs.py +++ b/pypy/module/micronumpy/interp_ufuncs.py @@ -400,7 +400,7 @@ return interp_dtype.get_dtype_cache(space).w_complex64dtype elif dt2.num == 15: return interp_dtype.get_dtype_cache(space).w_complex128dtype - elif 0 and dt2.num == 16: + elif interp_boxes.ENABLED_LONG_DOUBLE and dt2.num == 16: return interp_dtype.get_dtype_cache(space).w_clongdouble else: raise OperationError(space.w_TypeError, space.wrap("Unsupported types")) diff --git a/pypy/module/micronumpy/types.py b/pypy/module/micronumpy/types.py --- a/pypy/module/micronumpy/types.py +++ b/pypy/module/micronumpy/types.py @@ -1515,7 +1515,7 @@ NonNativeComplex128 = Complex128 -if 0 and interp_boxes.long_double_size == 12: +if interp_boxes.ENABLED_LONG_DOUBLE and interp_boxes.long_double_size == 12: class Float96(BaseType, Float): _attrs_ = () @@ -1545,7 +1545,7 @@ NonNativeComplex192 = Complex192 -elif 0 and interp_boxes.long_double_size == 16: +elif interp_boxes.ENABLED_LONG_DOUBLE and interp_boxes.long_double_size == 16: class Float128(BaseType, Float): _attrs_ = () From noreply at buildbot.pypy.org Sat Feb 23 21:13:02 2013 From: noreply at buildbot.pypy.org (mattip) Date: Sat, 23 Feb 2013 21:13:02 +0100 (CET) Subject: [pypy-commit] pypy numpypy-disable-longdouble: document this branch Message-ID: <20130223201302.5E3DC1C0327@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: numpypy-disable-longdouble Changeset: r61690:da500f70542a Date: 2013-02-23 22:10 +0200 http://bitbucket.org/pypy/pypy/changeset/da500f70542a/ Log: document this branch diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst --- a/pypy/doc/whatsnew-head.rst +++ b/pypy/doc/whatsnew-head.rst @@ -18,6 +18,9 @@ .. branch: numpypy-longdouble Long double support for numpypy +.. branch: numpypy-disable-longdouble +Since r_longdouble support is missing, disable all longdouble and derivative +dtypes using ENABLED_LONG_DOUBLE = False .. branch: numpypy-real-as-view Convert real, imag from ufuncs to views. This involves the beginning of view() functionality From noreply at buildbot.pypy.org Sat Feb 23 21:13:03 2013 From: noreply at buildbot.pypy.org (mattip) Date: Sat, 23 Feb 2013 21:13:03 +0100 (CET) Subject: [pypy-commit] pypy numpypy-disable-longdouble: close about-to-be-merged branch Message-ID: <20130223201303.C43B21C0327@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: numpypy-disable-longdouble Changeset: r61691:177d25d5f3d9 Date: 2013-02-23 22:11 +0200 http://bitbucket.org/pypy/pypy/changeset/177d25d5f3d9/ Log: close about-to-be-merged branch From noreply at buildbot.pypy.org Sat Feb 23 21:13:05 2013 From: noreply at buildbot.pypy.org (mattip) Date: Sat, 23 Feb 2013 21:13:05 +0100 (CET) Subject: [pypy-commit] pypy default: merge numpypy-disable-longdouble which uses a flag to disable dtypes dependent on a functioning r_longdouble Message-ID: <20130223201305.41F511C0327@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: Changeset: r61692:fd88268ab032 Date: 2013-02-23 22:12 +0200 http://bitbucket.org/pypy/pypy/changeset/fd88268ab032/ Log: merge numpypy-disable-longdouble which uses a flag to disable dtypes dependent on a functioning r_longdouble diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst --- a/pypy/doc/whatsnew-head.rst +++ b/pypy/doc/whatsnew-head.rst @@ -18,6 +18,9 @@ .. branch: numpypy-longdouble Long double support for numpypy +.. branch: numpypy-disable-longdouble +Since r_longdouble support is missing, disable all longdouble and derivative +dtypes using ENABLED_LONG_DOUBLE = False .. branch: numpypy-real-as-view Convert real, imag from ufuncs to views. This involves the beginning of view() functionality diff --git a/pypy/module/micronumpy/__init__.py b/pypy/module/micronumpy/__init__.py --- a/pypy/module/micronumpy/__init__.py +++ b/pypy/module/micronumpy/__init__.py @@ -1,5 +1,5 @@ from pypy.interpreter.mixedmodule import MixedModule -from pypy.module.micronumpy.interp_boxes import long_double_size +from pypy.module.micronumpy.interp_boxes import long_double_size, ENABLED_LONG_DOUBLE class Module(MixedModule): @@ -59,8 +59,6 @@ 'float16': 'interp_boxes.W_Float16Box', 'float32': 'interp_boxes.W_Float32Box', 'float64': 'interp_boxes.W_Float64Box', - 'longdouble': 'interp_boxes.W_LongDoubleBox', - 'longfloat': 'interp_boxes.W_LongDoubleBox', 'intp': 'types.IntP.BoxType', 'uintp': 'types.UIntP.BoxType', 'flexible': 'interp_boxes.W_FlexibleBox', @@ -73,8 +71,6 @@ 'complex_': 'interp_boxes.W_Complex128Box', 'complex128': 'interp_boxes.W_Complex128Box', 'complex64': 'interp_boxes.W_Complex64Box', - 'clongdouble': 'interp_boxes.W_CLongDoubleBox', - 'clongfloat': 'interp_boxes.W_CLongDoubleBox', } # ufuncs @@ -171,9 +167,22 @@ w_all = space.wrap(all_list) space.setitem(self.w_dict, space.new_interned_str('__all__'), w_all) -if long_double_size == 16: - Module.interpleveldefs['float128'] = 'interp_boxes.W_Float128Box' - Module.interpleveldefs['complex256'] = 'interp_boxes.W_Complex256Box' -elif long_double_size == 12: - Module.interpleveldefs['float96'] = 'interp_boxes.W_Float96Box' - Module.interpleveldefs['complex192'] = 'interp_boxes.W_Complex192Box' +if ENABLED_LONG_DOUBLE: + long_double_dtypes = [ + ('longdouble', 'interp_boxes.W_LongDoubleBox'), + ('longfloat', 'interp_boxes.W_LongDoubleBox'), + ('clongdouble', 'interp_boxes.W_CLongDoubleBox'), + ('clongfloat', 'interp_boxes.W_CLongDoubleBox'), + ] + if long_double_size == 16: + long_double_dtypes += [ + ('float128', 'interp_boxes.W_Float128Box'), + ('complex256', 'interp_boxes.W_Complex256Box'), + ] + elif long_double_size == 12: + long_double_dtypes += [ + ('float96', 'interp_boxes.W_Float96Box'), + ('complex192', 'interp_boxes.W_Complex192Box'), + ] + for dt, box in long_double_dtypes: + Module.interpleveldefs[dt] = box diff --git a/pypy/module/micronumpy/interp_boxes.py b/pypy/module/micronumpy/interp_boxes.py --- a/pypy/module/micronumpy/interp_boxes.py +++ b/pypy/module/micronumpy/interp_boxes.py @@ -16,10 +16,12 @@ MIXIN_64 = (int_typedef,) if LONG_BIT == 64 else () # Is this the proper place for this? +ENABLED_LONG_DOUBLE = False long_double_size = rffi.sizeof_c_type('long double', ignore_errors=True) + import os if long_double_size == 8 and os.name == 'nt': - # this is a lie, or maybe a wish + # this is a lie, or maybe a wish, MS fakes longdouble math with double long_double_size = 12 @@ -335,7 +337,7 @@ descr__new__, _get_dtype = new_dtype_getter("complex128") _COMPONENTS_BOX = W_Float64Box -if long_double_size == 12: +if ENABLED_LONG_DOUBLE and long_double_size == 12: class W_Float96Box(W_FloatingBox, PrimitiveBox): descr__new__, _get_dtype = new_dtype_getter("float96") @@ -347,7 +349,7 @@ W_CLongDoubleBox = W_Complex192Box -elif long_double_size == 16: +elif ENABLED_LONG_DOUBLE and long_double_size == 16: class W_Float128Box(W_FloatingBox, PrimitiveBox): descr__new__, _get_dtype = new_dtype_getter("float128") W_LongDoubleBox = W_Float128Box @@ -358,7 +360,7 @@ W_CLongDoubleBox = W_Complex256Box -else: +elif ENABLED_LONG_DOUBLE: W_LongDoubleBox = W_Float64Box W_CLongDoubleBox = W_Complex64Box @@ -526,7 +528,7 @@ __new__ = interp2app(W_Float64Box.descr__new__.im_func), ) -if long_double_size == 12: +if ENABLED_LONG_DOUBLE and long_double_size == 12: W_Float96Box.typedef = TypeDef("float96", (W_FloatingBox.typedef), __module__ = "numpypy", @@ -540,7 +542,7 @@ imag = GetSetProperty(W_ComplexFloatingBox.descr_get_imag), ) -elif long_double_size == 16: +elif ENABLED_LONG_DOUBLE and long_double_size == 16: W_Float128Box.typedef = TypeDef("float128", (W_FloatingBox.typedef), __module__ = "numpypy", diff --git a/pypy/module/micronumpy/interp_dtype.py b/pypy/module/micronumpy/interp_dtype.py --- a/pypy/module/micronumpy/interp_dtype.py +++ b/pypy/module/micronumpy/interp_dtype.py @@ -474,7 +474,7 @@ aliases=["complex"], float_type = self.w_float64dtype, ) - if interp_boxes.long_double_size == 12: + if interp_boxes.ENABLED_LONG_DOUBLE and interp_boxes.long_double_size == 12: self.w_float96dtype = W_Dtype( types.Float96(), num=13, @@ -497,7 +497,7 @@ ) self.w_longdouble = self.w_float96dtype self.w_clongdouble = self.w_complex192dtype - elif interp_boxes.long_double_size == 16: + elif interp_boxes.ENABLED_LONG_DOUBLE and interp_boxes.long_double_size == 16: self.w_float128dtype = W_Dtype( types.Float128(), num=13, @@ -520,7 +520,7 @@ ) self.w_longdouble = self.w_float128dtype self.w_clongdouble = self.w_complex256dtype - else: + elif interp_boxes.ENABLED_LONG_DOUBLE: self.w_float64dtype.aliases += ["longdouble", "longfloat"] self.w_complex128dtype.aliases += ["clongdouble", "clongfloat"] self.w_longdouble = self.w_float64dtype @@ -596,23 +596,27 @@ char=UINTPLTR, w_box_type = space.gettypefor(uintp_box), ) + float_dtypes = [self.w_float16dtype, + self.w_float32dtype, self.w_float64dtype, + ] + complex_dtypes = [self.w_complex64dtype, self.w_complex128dtype] + if interp_boxes.ENABLED_LONG_DOUBLE: + float_dtypes.append(self.w_longdouble) + complex_dtypes.append(self.w_clongdouble) self.builtin_dtypes = [ self.w_booldtype, self.w_int8dtype, self.w_uint8dtype, self.w_int16dtype, self.w_uint16dtype, self.w_longdtype, self.w_ulongdtype, self.w_int32dtype, self.w_uint32dtype, - self.w_int64dtype, self.w_uint64dtype, - self.w_float16dtype, - self.w_float32dtype, self.w_float64dtype, self.w_longdouble, - self.w_complex64dtype, self.w_complex128dtype, self.w_clongdouble, + self.w_int64dtype, self.w_uint64dtype] + \ + float_dtypes + complex_dtypes + [ self.w_stringdtype, self.w_unicodedtype, self.w_voiddtype, self.w_intpdtype, self.w_uintpdtype, ] self.float_dtypes_by_num_bytes = sorted( (dtype.itemtype.get_element_size(), dtype) - for dtype in [self.w_float16dtype, self.w_float32dtype, - self.w_float64dtype, self.w_longdouble] + for dtype in float_dtypes ) self.dtypes_by_num = {} self.dtypes_by_name = {} @@ -655,7 +659,6 @@ 'LONGLONG': self.w_int64dtype, 'SHORT': self.w_int16dtype, 'VOID': self.w_voiddtype, - 'LONGDOUBLE': self.w_longdouble, 'UBYTE': self.w_uint8dtype, 'UINTP': self.w_ulongdtype, 'ULONG': self.w_ulongdtype, @@ -678,8 +681,11 @@ 'USHORT': self.w_uint16dtype, 'FLOAT': self.w_float32dtype, 'BOOL': self.w_booldtype, - 'CLONGDOUBLE': self.w_clongdouble, } + if interp_boxes.ENABLED_LONG_DOUBLE: + typeinfo_full['LONGDOUBLE'] = self.w_longdouble + typeinfo_full['CLONGDOUBLE'] = self.w_clongdouble + typeinfo_partial = { 'Generic': interp_boxes.W_GenericBox, 'Character': interp_boxes.W_CharacterBox, diff --git a/pypy/module/micronumpy/interp_ufuncs.py b/pypy/module/micronumpy/interp_ufuncs.py --- a/pypy/module/micronumpy/interp_ufuncs.py +++ b/pypy/module/micronumpy/interp_ufuncs.py @@ -400,7 +400,7 @@ return interp_dtype.get_dtype_cache(space).w_complex64dtype elif dt2.num == 15: return interp_dtype.get_dtype_cache(space).w_complex128dtype - elif dt2.num == 16: + elif interp_boxes.ENABLED_LONG_DOUBLE and dt2.num == 16: return interp_dtype.get_dtype_cache(space).w_clongdouble else: raise OperationError(space.w_TypeError, space.wrap("Unsupported types")) diff --git a/pypy/module/micronumpy/test/test_complex.py b/pypy/module/micronumpy/test/test_complex.py --- a/pypy/module/micronumpy/test/test_complex.py +++ b/pypy/module/micronumpy/test/test_complex.py @@ -196,8 +196,13 @@ raises(TypeError, signbit, complex(1,1)) def test_reciprocal(self): - from _numpypy import array, reciprocal, complex64, complex128, clongdouble - + from _numpypy import array, reciprocal, complex64, complex128 + c_and_relerr = [(complex64, 2e-7), (complex128, 2e-15)] + try: + from _numpypy import clongdouble + c_and_relerr.append((clongdouble, 2e-30)) + except: + pass # no longdouble yet inf = float('inf') nan = float('nan') #complex @@ -212,7 +217,7 @@ complex(-r, i), -0j, 0j, cnan, cnan, cnan, cnan] - for c, rel_err in ((complex64, 2e-7), (complex128, 2e-15), (clongdouble, 2e-15)): + for c, rel_err in c_and_relerr: actual = reciprocal(array([orig], dtype=c)) for b, a, e in zip(orig, actual, expected): assert (a[0].real - e.real) < rel_err @@ -232,12 +237,18 @@ raises(TypeError, copysign, a, b) def test_exp2(self): - from _numpypy import array, exp2, complex128, complex64, clongfloat + from _numpypy import array, exp2, complex128, complex64 + c_and_relerr = [(complex64, 2e-7), (complex128, 2e-15)] + try: + from _numpypy import clongdouble + c_and_relerr.append((clongdouble, 2e-30)) + except: + pass # no longdouble yet inf = float('inf') ninf = -float('inf') nan = float('nan') cmpl = complex - for c,rel_err in ((complex128, 2e-15), (complex64, 1e-7), (clongfloat, 2e-15)): + for c,rel_err in c_and_relerr: a = [cmpl(-5., 0), cmpl(-5., -5.), cmpl(-5., 5.), cmpl(0., -5.), cmpl(0., 0.), cmpl(0., 5.), cmpl(-0., -5.), cmpl(-0., 0.), cmpl(-0., 5.), @@ -496,15 +507,21 @@ def test_basic(self): from _numpypy import (complex128, complex64, add, array, dtype, subtract as sub, multiply, divide, negative, absolute as abs, - floor_divide, real, imag, sign, clongfloat) + floor_divide, real, imag, sign) from _numpypy import (equal, not_equal, greater, greater_equal, less, less_equal, isnan) + complex_dtypes = [complex64, complex128] + try: + from _numpypy import clongfloat + complex_dtypes.append(clongfloat) + except: + pass assert real(4.0) == 4.0 assert imag(0.0) == 0.0 a = array([complex(3.0, 4.0)]) b = a.real assert b.dtype == dtype(float) - for complex_ in complex64, complex128, clongfloat: + for complex_ in complex_dtypes: O = complex(0, 0) c0 = complex_(complex(2.5, 0)) diff --git a/pypy/module/micronumpy/test/test_dtypes.py b/pypy/module/micronumpy/test/test_dtypes.py --- a/pypy/module/micronumpy/test/test_dtypes.py +++ b/pypy/module/micronumpy/test/test_dtypes.py @@ -14,7 +14,7 @@ from rpython.rtyper.lltypesystem import rffi ptr_size = rffi.sizeof(rffi.CCHARP) cls.w_ptr_size = cls.space.wrap(ptr_size) - + class AppTestDtypes(BaseAppTestDtypes): def test_dtype(self): from _numpypy import dtype @@ -43,13 +43,6 @@ raises(TypeError, lambda: dtype("int8") == 3) assert dtype(bool) == bool - def test_dtype_aliases(self): - from _numpypy import dtype - assert dtype('longfloat').num in (12, 13) - assert dtype('longdouble').num in (12, 13) - assert dtype('clongfloat').num in (15, 16) - assert dtype('clongdouble').num in (15, 16) - def test_dtype_with_types(self): from _numpypy import dtype @@ -154,8 +147,6 @@ '?', 'b', 'B', 'h', 'H', 'i', 'I', 'l', 'L', 'q', 'Q', 'f', 'd', 'e' ] - if array([0], dtype='longdouble').itemsize > 8: - types += ['g', 'G'] a = array([True], '?') for t in types: assert (a + array([0], t)).dtype is dtype(t) @@ -271,7 +262,6 @@ (numpy.float16, 10.), (numpy.float32, 2.0), (numpy.float64, 4.32), - (numpy.longdouble, 4.32), ]: assert hash(tp(value)) == hash(value) @@ -528,20 +518,6 @@ from math import isnan assert isnan(numpy.float32(None)) assert isnan(numpy.float64(None)) - assert isnan(numpy.longdouble(None)) - - def test_longfloat(self): - import _numpypy as numpy - # it can be float96 or float128 - if numpy.longfloat != numpy.float64: - assert numpy.longfloat.mro()[1:] == [numpy.floating, - numpy.inexact, numpy.number, - numpy.generic, object] - a = numpy.array([1, 2, 3], numpy.longdouble) - assert type(a[1]) is numpy.longdouble - assert numpy.float64(12) == numpy.longdouble(12) - assert numpy.float64(12) == numpy.longfloat(12) - raises(ValueError, numpy.longfloat, '23.2df') def test_complex_floating(self): import _numpypy as numpy @@ -799,12 +775,6 @@ a = array([1, 2, 3], dtype=self.non_native_prefix + 'f2') assert a[0] == 1 assert (a + a)[1] == 4 - a = array([1, 2, 3], dtype=self.non_native_prefix + 'g') # longdouble - assert a[0] == 1 - assert (a + a)[1] == 4 - a = array([1, 2, 3], dtype=self.non_native_prefix + 'G') # clongdouble - assert a[0] == 1 - assert (a + a)[1] == 4 class AppTestPyPyOnly(BaseNumpyAppTest): def setup_class(cls): @@ -818,3 +788,81 @@ assert typeinfo['LONGLONG'] == ('q', 9, 64, 8, 9223372036854775807L, -9223372036854775808L, int64) assert typeinfo['VOID'] == ('V', 20, 0, 1, void) assert typeinfo['BOOL'] == ('?', 0, 8, 1, 1, 0, bool_) + +class AppTestNoLongDoubleDtypes(BaseNumpyAppTest): + def setup_class(cls): + from pypy.module.micronumpy import Module + if Module.interpleveldefs.get('longfloat', None): + py.test.skip('longdouble exists, skip these tests') + if option.runappdirect and '__pypy__' not in sys.builtin_module_names: + py.test.skip("pypy only test for no longdouble support") + BaseNumpyAppTest.setup_class.im_func(cls) + + def test_nolongfloat(self): + import _numpypy + from _numpypy import dtype + assert not getattr(_numpypy, 'longdouble', False) + assert not getattr(_numpypy, 'float128', False) + assert not getattr(_numpypy, 'float96', False) + raises(TypeError, dtype, 'longdouble') + raises(TypeError, dtype, 'clongdouble') + raises(TypeError, dtype, 'longfloat') + raises(TypeError, dtype, 'clongfloat') + raises(TypeError, dtype, 'float128') + raises(TypeError, dtype, 'float96') + +class AppTestLongDoubleDtypes(BaseNumpyAppTest): + def setup_class(cls): + from pypy.module.micronumpy import Module + print dir(Module.interpleveldefs) + if not Module.interpleveldefs.get('longfloat', None): + py.test.skip('no longdouble types yet') + BaseNumpyAppTest.setup_class.im_func(cls) + + def test_longfloat(self): + import _numpypy as numpy + # it can be float96 or float128 + if numpy.longfloat != numpy.float64: + assert numpy.longfloat.mro()[1:] == [numpy.floating, + numpy.inexact, numpy.number, + numpy.generic, object] + a = numpy.array([1, 2, 3], numpy.longdouble) + assert type(a[1]) is numpy.longdouble + assert numpy.float64(12) == numpy.longdouble(12) + assert numpy.float64(12) == numpy.longfloat(12) + raises(ValueError, numpy.longfloat, '23.2df') + + def test_dtype_aliases(self): + from _numpypy import dtype + assert dtype('longfloat').num in (12, 13) + assert dtype('longdouble').num in (12, 13) + assert dtype('clongfloat').num in (15, 16) + assert dtype('clongdouble').num in (15, 16) + + def test_bool_binop_types(self): + from _numpypy import array, dtype + types = ['g', 'G'] + a = array([True], '?') + for t in types: + assert (a + array([0], t)).dtype is dtype(t) + + def test_hash(self): + import _numpypy as numpy + for tp, value in [ + (numpy.longdouble, 4.32), + ]: + assert hash(tp(value)) == hash(value) + + def test_float_None(self): + import _numpypy as numpy + from math import isnan + assert isnan(numpy.longdouble(None)) + + def test_non_native(self): + from _numpypy import array + a = array([1, 2, 3], dtype=self.non_native_prefix + 'g') # longdouble + assert a[0] == 1 + assert (a + a)[1] == 4 + a = array([1, 2, 3], dtype=self.non_native_prefix + 'G') # clongdouble + assert a[0] == 1 + assert (a + a)[1] == 4 diff --git a/pypy/module/micronumpy/test/test_numarray.py b/pypy/module/micronumpy/test/test_numarray.py --- a/pypy/module/micronumpy/test/test_numarray.py +++ b/pypy/module/micronumpy/test/test_numarray.py @@ -1692,15 +1692,6 @@ i2 = (i+1) * a.dtype.itemsize assert list(reversed(s1[i1:i2])) == s2[i1:i2] - a = array([1, -1, 10000], dtype='longfloat') - s1 = map(ord, a.tostring()) - s2 = map(ord, a.byteswap().tostring()) - assert a.dtype.itemsize >= 8 - for i in range(a.size): - i1 = i * a.dtype.itemsize - i2 = (i+1) * a.dtype.itemsize - assert list(reversed(s1[i1:i2])) == s2[i1:i2] - def test_clip(self): from _numpypy import array a = array([1, 2, 17, -3, 12]) @@ -2336,7 +2327,7 @@ def test_fromstring_types(self): from _numpypy import (fromstring, int8, int16, int32, int64, uint8, - uint16, uint32, float16, float32, float64, longfloat, array) + uint16, uint32, float16, float32, float64, array) a = fromstring('\xFF', dtype=int8) assert a[0] == -1 b = fromstring('\xFF', dtype=uint8) @@ -2359,18 +2350,6 @@ assert j[0] == 12 k = fromstring(self.float16val, dtype=float16) assert k[0] == float16(5.) - dt = array([5],dtype=longfloat).dtype - if dt.itemsize == 12: - from _numpypy import float96 - m = fromstring('\x00\x00\x00\x00\x00\x00\x00\xa0\x01@\x00\x00', dtype=float96) - elif dt.itemsize==16: - from _numpypy import float128 - m = fromstring('\x00\x00\x00\x00\x00\x00\x00\xa0\x01@\x00\x00\x00\x00\x00\x00', dtype=float128) - elif dt.itemsize == 8: - skip('longfloat is float64') - else: - skip('unknown itemsize for longfloat') - assert m[0] == longfloat(5.) def test_fromstring_invalid(self): from _numpypy import fromstring, uint16, uint8 @@ -2645,3 +2624,40 @@ assert x.__pypy_data__ is obj del x.__pypy_data__ assert x.__pypy_data__ is None + +class AppTestLongDoubleDtypes(BaseNumpyAppTest): + def setup_class(cls): + from pypy.module.micronumpy import Module + print dir(Module.interpleveldefs) + if not Module.interpleveldefs.get('longfloat', None): + py.test.skip('no longdouble types yet') + BaseNumpyAppTest.setup_class.im_func(cls) + + def test_byteswap(self): + from _numpypy import array + + a = array([1, -1, 10000], dtype='longfloat') + s1 = map(ord, a.tostring()) + s2 = map(ord, a.byteswap().tostring()) + assert a.dtype.itemsize >= 8 + for i in range(a.size): + i1 = i * a.dtype.itemsize + i2 = (i+1) * a.dtype.itemsize + assert list(reversed(s1[i1:i2])) == s2[i1:i2] + + def test_fromstring_types(self): + from _numpypy import (fromstring, longfloat, array) + dt = array([5],dtype=longfloat).dtype + if dt.itemsize == 12: + from _numpypy import float96 + m = fromstring('\x00\x00\x00\x00\x00\x00\x00\xa0\x01@\x00\x00', dtype=float96) + elif dt.itemsize==16: + from _numpypy import float128 + m = fromstring('\x00\x00\x00\x00\x00\x00\x00\xa0\x01@\x00\x00\x00\x00\x00\x00', dtype=float128) + elif dt.itemsize == 8: + skip('longfloat is float64') + else: + skip('unknown itemsize for longfloat') + assert m[0] == longfloat(5.) + + diff --git a/pypy/module/micronumpy/types.py b/pypy/module/micronumpy/types.py --- a/pypy/module/micronumpy/types.py +++ b/pypy/module/micronumpy/types.py @@ -1515,7 +1515,7 @@ NonNativeComplex128 = Complex128 -if interp_boxes.long_double_size == 12: +if interp_boxes.ENABLED_LONG_DOUBLE and interp_boxes.long_double_size == 12: class Float96(BaseType, Float): _attrs_ = () @@ -1545,7 +1545,7 @@ NonNativeComplex192 = Complex192 -elif interp_boxes.long_double_size == 16: +elif interp_boxes.ENABLED_LONG_DOUBLE and interp_boxes.long_double_size == 16: class Float128(BaseType, Float): _attrs_ = () From noreply at buildbot.pypy.org Sat Feb 23 21:40:08 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Sat, 23 Feb 2013 21:40:08 +0100 (CET) Subject: [pypy-commit] pypy rpython-doc: Separate RPython FAQ entries. Message-ID: <20130223204008.04A231C0CA3@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: rpython-doc Changeset: r61693:67621cc8a2cc Date: 2013-02-23 18:13 +0100 http://bitbucket.org/pypy/pypy/changeset/67621cc8a2cc/ Log: Separate RPython FAQ entries. diff --git a/pypy/doc/faq.rst b/pypy/doc/faq.rst --- a/pypy/doc/faq.rst +++ b/pypy/doc/faq.rst @@ -200,208 +200,3 @@ This will disable SELinux's protection and allow PyPy to configure correctly. Be sure to enable it again if you need it! - - -The RPython translation tool chain -=================================== - ------------------------------------------------- -Can RPython compile normal Python programs to C? ------------------------------------------------- - -No, RPython is not a Python compiler. - -In Python, it is mostly impossible to *prove* anything about the types -that a program will manipulate by doing a static analysis. It should be -clear if you are familiar with Python, but if in doubt see [BRETT]_. - -If you want a fast Python program, please use the PyPy JIT_ instead. - -.. _JIT: jit/index.html - -.. [BRETT] Brett Cannon, - Localized Type Inference of Atomic Types in Python, - http://citeseer.ist.psu.edu/viewdoc/summary?doi=10.1.1.90.3231 - -.. _`PyPy's RPython`: - ------------------------------- -What is this RPython language? ------------------------------- - -RPython is a restricted subset of the Python language. It is used for -implementing dynamic language interpreters within the PyPy toolchain. The -restrictions ensure that type inference (and so, ultimately, translation -to other languages) of RPython programs is possible. - -The property of "being RPython" always applies to a full program, not to single -functions or modules (the translation toolchain does a full program analysis). -The translation toolchain follows all calls -recursively and discovers what belongs to the program and what does not. - -RPython program restrictions mostly limit the ability -to mix types in arbitrary ways. RPython does not allow the binding of two -different types in the same variable. In this respect (and in some others) it -feels a bit like Java. Other features not allowed in RPython are the use of -special methods (``__xxx__``) except ``__init__`` and ``__del__``, and the -use of reflection capabilities (e.g. ``__dict__``). - -You cannot use most existing standard library modules from RPython. The -exceptions are -some functions in ``os``, ``math`` and ``time`` that have native support. - -To read more about the RPython limitations read the `RPython description`_. - -.. _`RPython description`: coding-guide.html#restricted-python - ---------------------------------------------------------------- -Does RPython have anything to do with Zope's Restricted Python? ---------------------------------------------------------------- - -No. `Zope's RestrictedPython`_ aims to provide a sandboxed -execution environment for CPython. `PyPy's RPython`_ is the implementation -language for dynamic language interpreters. However, PyPy also provides -a robust `sandboxed Python Interpreter`_. - -.. _`sandboxed Python Interpreter`: sandbox.html -.. _`Zope's RestrictedPython`: http://pypi.python.org/pypi/RestrictedPython - ------------------------------------------------------- -What's the ``"NOT_RPYTHON"`` I see in some docstrings? ------------------------------------------------------- - -If you put "NOT_RPYTHON" into the docstring of a function and that function is -found while trying to translate an RPython program, the translation process -stops and reports this as an error. You can therefore mark functions as -"NOT_RPYTHON" to make sure that they are never analyzed. - - -------------------------------------------------------------------- -Couldn't we simply take a Python syntax tree and turn it into Lisp? -------------------------------------------------------------------- - -It's not necessarily nonsense, but it's not really The PyPy Way. It's -pretty hard, without some kind of type inference, to translate this -Python:: - - a + b - -into anything significantly more efficient than this Common Lisp:: - - (py:add a b) - -And making type inference possible is what RPython is all about. - -You could make ``#'py:add`` a generic function and see if a given CLOS -implementation is fast enough to give a useful speed (but I think the -coercion rules would probably drive you insane first). -- mwh - --------------------------------------------- -Do I have to rewrite my programs in RPython? --------------------------------------------- - -No, and you shouldn't try. First and foremost, RPython is a language -designed for writing interpreters. It is a restricted subset of -Python. If you program is not an interpreter but tries to do "real -things", like use *any* part of the standard Python library or *any* -3rd-party library, then it is not RPython to start with. You should -only look at RPython if you try to `write your own interpreter`__. - -.. __: `how do I compile my own interpreters`_ - -If your goal is to speed up Python code, then look at the regular PyPy, -which is a full and compliant Python 2.7 interpreter (which happens to -be written in RPython). Not only is it not necessary for you to rewrite -your code in RPython, it might not give you any speed improvements even -if you manage to. - -Yes, it is possible with enough effort to compile small self-contained -pieces of RPython code doing a few performance-sensitive things. But -this case is not interesting for us. If you needed to rewrite the code -in RPython, you could as well have rewritten it in C for example. The -latter is a much more supported, much more documented language `:-)` - ---------------------------------------------------- -Which backends are there for the RPython toolchain? ---------------------------------------------------- - -Currently, there are backends for C_, the CLI_, and the JVM_. -All of these can translate the entire PyPy interpreter. -To learn more about backends take a look at the `translation document`_. - -.. _C: translation.html#the-c-back-end -.. _CLI: cli-backend.html -.. _JVM: translation.html#genjvm -.. _`translation document`: translation.html - ------------------- -Could we use LLVM? ------------------- - -In theory yes. But we tried to use it 5 or 6 times already, as a -translation backend or as a JIT backend --- and failed each time. - -In more details: using LLVM as a (static) translation backend is -pointless nowadays because you can generate C code and compile it with -clang. (Note that compiling PyPy with clang gives a result that is not -faster than compiling it with gcc.) We might in theory get extra -benefits from LLVM's GC integration, but this requires more work on the -LLVM side before it would be remotely useful. Anyway, it could be -interfaced via a custom primitive in the C code. - -On the other hand, using LLVM as our JIT backend looks interesting as -well --- but again we made an attempt, and it failed: LLVM has no way to -patch the generated machine code. - -So the position of the core PyPy developers is that if anyone wants to -make an N+1'th attempt with LLVM, he is welcome, and he will receive a -bit of help on the IRC channel, but he is left with the burden of proof -that it works. - ----------------------- -How do I compile PyPy? ----------------------- - -See the `getting-started`_ guide. - -.. _`getting-started`: getting-started-python.html - -.. _`how do I compile my own interpreters`: - -------------------------------------- -How do I compile my own interpreters? -------------------------------------- -Begin by reading `Andrew Brown's tutorial`_ . - -.. _`Andrew Brown's tutorial`: http://morepypy.blogspot.com/2011/04/tutorial-writing-interpreter-with-pypy.html - ---------------------------------------------------------- -Can RPython modules for PyPy be translated independently? ---------------------------------------------------------- - -No, you have to rebuild the entire interpreter. This means two things: - -* It is imperative to use test-driven development. You have to exhaustively - test your module in pure Python, before even attempting to - translate it. Once you translate it, you should have only a few typing - issues left to fix, but otherwise the result should work out of the box. - -* Second, and perhaps most important: do you have a really good reason - for writing the module in RPython in the first place? Nowadays you - should really look at alternatives, like writing it in pure Python, - using ctypes if it needs to call C code. Other alternatives are being - developed too (as of summer 2011), like a Cython binding. - -In this context it is not that important to be able to translate -RPython modules independently of translating the complete interpreter. -(It could be done given enough efforts, but it's a really serious -undertaking. Consider it as quite unlikely for now.) - ----------------------------------------------------------- -Why does PyPy draw a Mandelbrot fractal while translating? ----------------------------------------------------------- - -Because it's fun. - -.. include:: _ref.txt - diff --git a/rpython/doc/faq.rst b/rpython/doc/faq.rst new file mode 100644 --- /dev/null +++ b/rpython/doc/faq.rst @@ -0,0 +1,207 @@ +========================== +Frequently Asked Questions +========================== + +.. contents:: + + +The RPython translation tool chain +================================== + +------------------------------------------------ +Can RPython compile normal Python programs to C? +------------------------------------------------ + +No, RPython is not a Python compiler. + +In Python, it is mostly impossible to *prove* anything about the types +that a program will manipulate by doing a static analysis. It should be +clear if you are familiar with Python, but if in doubt see [BRETT]_. + +If you want a fast Python program, please use the PyPy JIT_ instead. + +.. _JIT: jit/index.html + +.. [BRETT] Brett Cannon, + Localized Type Inference of Atomic Types in Python, + http://citeseer.ist.psu.edu/viewdoc/summary?doi=10.1.1.90.3231 + +.. _`PyPy's RPython`: + +------------------------------ +What is this RPython language? +------------------------------ + +RPython is a restricted subset of the Python language. It is used for +implementing dynamic language interpreters within the PyPy toolchain. The +restrictions ensure that type inference (and so, ultimately, translation +to other languages) of RPython programs is possible. + +The property of "being RPython" always applies to a full program, not to single +functions or modules (the translation toolchain does a full program analysis). +The translation toolchain follows all calls +recursively and discovers what belongs to the program and what does not. + +RPython program restrictions mostly limit the ability +to mix types in arbitrary ways. RPython does not allow the binding of two +different types in the same variable. In this respect (and in some others) it +feels a bit like Java. Other features not allowed in RPython are the use of +special methods (``__xxx__``) except ``__init__`` and ``__del__``, and the +use of reflection capabilities (e.g. ``__dict__``). + +You cannot use most existing standard library modules from RPython. The +exceptions are +some functions in ``os``, ``math`` and ``time`` that have native support. + +To read more about the RPython limitations read the `RPython description`_. + +.. _`RPython description`: coding-guide.html#restricted-python + +--------------------------------------------------------------- +Does RPython have anything to do with Zope's Restricted Python? +--------------------------------------------------------------- + +No. `Zope's RestrictedPython`_ aims to provide a sandboxed +execution environment for CPython. `PyPy's RPython`_ is the implementation +language for dynamic language interpreters. However, PyPy also provides +a robust `sandboxed Python Interpreter`_. + +.. _`sandboxed Python Interpreter`: sandbox.html +.. _`Zope's RestrictedPython`: http://pypi.python.org/pypi/RestrictedPython + +------------------------------------------------------ +What's the ``"NOT_RPYTHON"`` I see in some docstrings? +------------------------------------------------------ + +If you put "NOT_RPYTHON" into the docstring of a function and that function is +found while trying to translate an RPython program, the translation process +stops and reports this as an error. You can therefore mark functions as +"NOT_RPYTHON" to make sure that they are never analyzed. + + +------------------------------------------------------------------- +Couldn't we simply take a Python syntax tree and turn it into Lisp? +------------------------------------------------------------------- + +It's not necessarily nonsense, but it's not really The PyPy Way. It's +pretty hard, without some kind of type inference, to translate this +Python:: + + a + b + +into anything significantly more efficient than this Common Lisp:: + + (py:add a b) + +And making type inference possible is what RPython is all about. + +You could make ``#'py:add`` a generic function and see if a given CLOS +implementation is fast enough to give a useful speed (but I think the +coercion rules would probably drive you insane first). -- mwh + +-------------------------------------------- +Do I have to rewrite my programs in RPython? +-------------------------------------------- + +No, and you shouldn't try. First and foremost, RPython is a language +designed for writing interpreters. It is a restricted subset of +Python. If you program is not an interpreter but tries to do "real +things", like use *any* part of the standard Python library or *any* +3rd-party library, then it is not RPython to start with. You should +only look at RPython if you try to `write your own interpreter`__. + +.. __: `how do I compile my own interpreters`_ + +If your goal is to speed up Python code, then look at the regular PyPy, +which is a full and compliant Python 2.7 interpreter (which happens to +be written in RPython). Not only is it not necessary for you to rewrite +your code in RPython, it might not give you any speed improvements even +if you manage to. + +Yes, it is possible with enough effort to compile small self-contained +pieces of RPython code doing a few performance-sensitive things. But +this case is not interesting for us. If you needed to rewrite the code +in RPython, you could as well have rewritten it in C for example. The +latter is a much more supported, much more documented language `:-)` + +--------------------------------------------------- +Which backends are there for the RPython toolchain? +--------------------------------------------------- + +Currently, there are backends for C_, the CLI_, and the JVM_. +All of these can translate the entire PyPy interpreter. +To learn more about backends take a look at the `translation document`_. + +.. _C: translation.html#the-c-back-end +.. _CLI: cli-backend.html +.. _JVM: translation.html#genjvm +.. _`translation document`: translation.html + +------------------ +Could we use LLVM? +------------------ + +In theory yes. But we tried to use it 5 or 6 times already, as a +translation backend or as a JIT backend --- and failed each time. + +In more details: using LLVM as a (static) translation backend is +pointless nowadays because you can generate C code and compile it with +clang. (Note that compiling PyPy with clang gives a result that is not +faster than compiling it with gcc.) We might in theory get extra +benefits from LLVM's GC integration, but this requires more work on the +LLVM side before it would be remotely useful. Anyway, it could be +interfaced via a custom primitive in the C code. + +On the other hand, using LLVM as our JIT backend looks interesting as +well --- but again we made an attempt, and it failed: LLVM has no way to +patch the generated machine code. + +So the position of the core PyPy developers is that if anyone wants to +make an N+1'th attempt with LLVM, he is welcome, and he will receive a +bit of help on the IRC channel, but he is left with the burden of proof +that it works. + +---------------------- +How do I compile PyPy? +---------------------- + +See the `getting-started`_ guide. + +.. _`getting-started`: getting-started-python.html + +.. _`how do I compile my own interpreters`: + +------------------------------------- +How do I compile my own interpreters? +------------------------------------- +Begin by reading `Andrew Brown's tutorial`_ . + +.. _`Andrew Brown's tutorial`: http://morepypy.blogspot.com/2011/04/tutorial-writing-interpreter-with-pypy.html + +--------------------------------------------------------- +Can RPython modules for PyPy be translated independently? +--------------------------------------------------------- + +No, you have to rebuild the entire interpreter. This means two things: + +* It is imperative to use test-driven development. You have to exhaustively + test your module in pure Python, before even attempting to + translate it. Once you translate it, you should have only a few typing + issues left to fix, but otherwise the result should work out of the box. + +* Second, and perhaps most important: do you have a really good reason + for writing the module in RPython in the first place? Nowadays you + should really look at alternatives, like writing it in pure Python, + using ctypes if it needs to call C code. Other alternatives are being + developed too (as of summer 2011), like a Cython binding. + +In this context it is not that important to be able to translate +RPython modules independently of translating the complete interpreter. +(It could be done given enough efforts, but it's a really serious +undertaking. Consider it as quite unlikely for now.) + +---------------------------------------------------------- +Why does PyPy draw a Mandelbrot fractal while translating? +---------------------------------------------------------- + +Because it's fun. From noreply at buildbot.pypy.org Sat Feb 23 21:40:09 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Sat, 23 Feb 2013 21:40:09 +0100 (CET) Subject: [pypy-commit] pypy rpython-doc: Remove rpython/doc/dot-net.rst. Message-ID: <20130223204009.5963C1C0CA3@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: rpython-doc Changeset: r61694:429434b97ea5 Date: 2013-02-23 18:15 +0100 http://bitbucket.org/pypy/pypy/changeset/429434b97ea5/ Log: Remove rpython/doc/dot-net.rst. diff --git a/rpython/doc/dot-net.rst b/rpython/doc/dot-net.rst deleted file mode 100644 --- a/rpython/doc/dot-net.rst +++ /dev/null @@ -1,11 +0,0 @@ -.NET support -============ - - .. warning:: - - The .NET backend within PyPy is unmaintained. This documentation may be out-of-date. We welcome contributors who are interested in doing the work to get this into shape. - -.. toctree:: - - cli-backend.rst - clr-module.rst From noreply at buildbot.pypy.org Sat Feb 23 21:40:10 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Sat, 23 Feb 2013 21:40:10 +0100 (CET) Subject: [pypy-commit] pypy rpython-doc: Change caption of translation.rst. Message-ID: <20130223204010.84F261C0CA3@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: rpython-doc Changeset: r61695:298d754cde28 Date: 2013-02-23 18:17 +0100 http://bitbucket.org/pypy/pypy/changeset/298d754cde28/ Log: Change caption of translation.rst. diff --git a/rpython/doc/translation.rst b/rpython/doc/translation.rst --- a/rpython/doc/translation.rst +++ b/rpython/doc/translation.rst @@ -1,6 +1,6 @@ -============================= - PyPy - The RPython Toolchain -============================= +===================== +The RPython Toolchain +===================== .. contents:: From noreply at buildbot.pypy.org Sat Feb 23 21:40:11 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Sat, 23 Feb 2013 21:40:11 +0100 (CET) Subject: [pypy-commit] pypy rpython-doc: Use relative path here. Message-ID: <20130223204011.B0F0A1C0CA3@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: rpython-doc Changeset: r61696:cadd752d7f7d Date: 2013-02-23 18:19 +0100 http://bitbucket.org/pypy/pypy/changeset/cadd752d7f7d/ Log: Use relative path here. diff --git a/rpython/doc/translation.rst b/rpython/doc/translation.rst --- a/rpython/doc/translation.rst +++ b/rpython/doc/translation.rst @@ -99,7 +99,7 @@ .. image:: _static/translation-greyscale-small.png -.. _`PDF color version`: https://bitbucket.org/pypy/pypy/raw/default/pypy/doc/image/translation.pdf +.. _`PDF color version`: _static/translation.pdf .. _`bytecode evaluator`: interpreter.html .. _`abstract interpretation`: http://en.wikipedia.org/wiki/Abstract_interpretation .. _`Flow Object Space`: objspace.html#the-flow-object-space From noreply at buildbot.pypy.org Sat Feb 23 21:40:12 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Sat, 23 Feb 2013 21:40:12 +0100 (CET) Subject: [pypy-commit] pypy rpython-doc: Change caption of garbage_collection.rst. Message-ID: <20130223204012.D630A1C0CA3@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: rpython-doc Changeset: r61697:0859711f6b59 Date: 2013-02-23 18:20 +0100 http://bitbucket.org/pypy/pypy/changeset/0859711f6b59/ Log: Change caption of garbage_collection.rst. diff --git a/rpython/doc/garbage_collection.rst b/rpython/doc/garbage_collection.rst --- a/rpython/doc/garbage_collection.rst +++ b/rpython/doc/garbage_collection.rst @@ -1,6 +1,6 @@ -========================== -Garbage Collection in PyPy -========================== +============================= +Garbage Collection in RPython +============================= .. contents:: From noreply at buildbot.pypy.org Sat Feb 23 21:40:14 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Sat, 23 Feb 2013 21:40:14 +0100 (CET) Subject: [pypy-commit] pypy rpython-doc: Fix this link. Message-ID: <20130223204014.213C81C0CA3@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: rpython-doc Changeset: r61698:b46aa4eb4e0d Date: 2013-02-23 18:23 +0100 http://bitbucket.org/pypy/pypy/changeset/b46aa4eb4e0d/ Log: Fix this link. diff --git a/rpython/doc/garbage_collection.rst b/rpython/doc/garbage_collection.rst --- a/rpython/doc/garbage_collection.rst +++ b/rpython/doc/garbage_collection.rst @@ -14,7 +14,7 @@ The present document describes the specific garbage collectors that we wrote in our framework. -.. _`EU-report on this topic`: http://codespeak.net/pypy/extradoc/eu-report/D07.1_Massive_Parallelism_and_Translation_Aspects-2007-02-28.pdf +.. _`EU-report on this topic`: https://bitbucket.org/pypy/extradoc/src/extradoc/eu-report/D07.1_Massive_Parallelism_and_Translation_Aspects-2007-02-28.pdf Garbage collectors currently written for the GC framework From noreply at buildbot.pypy.org Sat Feb 23 21:40:15 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Sat, 23 Feb 2013 21:40:15 +0100 (CET) Subject: [pypy-commit] pypy rpython-doc: s/PyPy/the translator/ here. Message-ID: <20130223204015.530081C0CA3@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: rpython-doc Changeset: r61699:182b1db06bb8 Date: 2013-02-23 18:37 +0100 http://bitbucket.org/pypy/pypy/changeset/182b1db06bb8/ Log: s/PyPy/the translator/ here. diff --git a/rpython/doc/faq.rst b/rpython/doc/faq.rst --- a/rpython/doc/faq.rst +++ b/rpython/doc/faq.rst @@ -200,8 +200,8 @@ (It could be done given enough efforts, but it's a really serious undertaking. Consider it as quite unlikely for now.) ----------------------------------------------------------- -Why does PyPy draw a Mandelbrot fractal while translating? ----------------------------------------------------------- +-------------------------------------------------------------------- +Why does the translator draw a Mandelbrot fractal while translating? +-------------------------------------------------------------------- Because it's fun. From noreply at buildbot.pypy.org Sat Feb 23 21:40:16 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Sat, 23 Feb 2013 21:40:16 +0100 (CET) Subject: [pypy-commit] pypy rpython-doc: Change caption of index page: s/PyPy Development/PyPy Documentation/ Message-ID: <20130223204016.7E47F1C0CA3@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: rpython-doc Changeset: r61700:d9434ad3b880 Date: 2013-02-23 18:51 +0100 http://bitbucket.org/pypy/pypy/changeset/d9434ad3b880/ Log: Change caption of index page: s/PyPy Development/PyPy Documentation/ diff --git a/pypy/doc/index.rst b/pypy/doc/index.rst --- a/pypy/doc/index.rst +++ b/pypy/doc/index.rst @@ -1,5 +1,5 @@ -Welcome to PyPy Development +Welcome to PyPy Documentation ============================================= The PyPy project aims at producing a flexible and fast Python_ From noreply at buildbot.pypy.org Sat Feb 23 21:40:17 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Sat, 23 Feb 2013 21:40:17 +0100 (CET) Subject: [pypy-commit] pypy rpython-doc: Remove cleanup.rst. Message-ID: <20130223204017.B006C1C0CA3@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: rpython-doc Changeset: r61701:de57acc2fa91 Date: 2013-02-23 18:54 +0100 http://bitbucket.org/pypy/pypy/changeset/de57acc2fa91/ Log: Remove cleanup.rst. diff --git a/pypy/doc/cleanup.rst b/pypy/doc/cleanup.rst deleted file mode 100644 --- a/pypy/doc/cleanup.rst +++ /dev/null @@ -1,17 +0,0 @@ -Old documentation that needs review ------------------------------------ - -.. The following stuff is old (and crufty?), and needs further investigation: - -.. doc-index: This needs merging somehow - -.. toctree:: - - distribution.rst - - dot-net.rst - - - - - From noreply at buildbot.pypy.org Sat Feb 23 21:40:18 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Sat, 23 Feb 2013 21:40:18 +0100 (CET) Subject: [pypy-commit] pypy rpython-doc: lib_pypy/distributed was removed from PyPy. Message-ID: <20130223204018.E096C1C0CA3@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: rpython-doc Changeset: r61702:4fe4386768e4 Date: 2013-02-23 18:55 +0100 http://bitbucket.org/pypy/pypy/changeset/4fe4386768e4/ Log: lib_pypy/distributed was removed from PyPy. diff --git a/pypy/doc/distribution.rst b/pypy/doc/distribution.rst deleted file mode 100644 --- a/pypy/doc/distribution.rst +++ /dev/null @@ -1,112 +0,0 @@ -.. include:: needswork.txt - -============================= -lib_pypy/distributed features -============================= - -The 'distributed' library is an attempt to provide transparent, lazy -access to remote objects. This is accomplished using -`transparent proxies`_ and in application level code (so as a pure -python module). - -The implementation uses an RPC-like protocol, which accesses -only members of objects, rather than whole objects. This means it -does not rely on objects being pickleable, nor on having the same -source code available on both sides. On each call, only the members -that are used on the client side are retrieved, objects which -are not used are merely references to their remote counterparts. - -As an example, let's imagine we have a remote object, locally available -under the name `x`. Now we call:: - - >>>> x.foo(1, [1,2,3], y) - -where y is some instance of a local, user-created class. - -Under water, x.\_\_getattribute\_\_ is called, with argument 'foo'. In the -\_\_getattribute\_\_ implementation, the 'foo' attribute is requested, and the -remote side replies by providing a bound method. On the client this bound -method appears as a remote reference: this reference is called with a remote -reference to x as self, the integer 1 which is copied as a primitive type, a -reference to a list and a reference to y. The remote side receives this call, -processes it as a call to the bound method x.foo, where 'x' is resolved as a -local object, 1 as an immutable primitive, [1,2,3] as a reference to a mutable -primitive and y as a reference to a remote object. If the type of y is not -known on the remote side, it is faked with just about enough shape (XXX?!?) to -be able to perform the required operations. The contents of the list are -retrieved when they're needed. - -An advantage of this approach is that a user can have remote references to -internal interpreter types, like frames, code objects and tracebacks. In a demo -directory there is an example of using this to attach pdb.post\_mortem() to a -remote traceback. Another advantage is that there's a minimal amount of data -transferred over the network. On the other hand, there are a large amount of -packages sent to the remote side - hopefully this will be improved in future. - -The 'distributed' lib is uses an abstract network layer, which means you -can provide custom communication channels just by implementing -two functions that send and receive marshallable objects (no pickle needed!). - -Exact rules of copying ----------------------- - -- Immutable primitives are always transferred - -- Mutable primitives are transferred as a reference, but several operations - (like iter()) force them to be transferred fully - -- Builtin exceptions are transferred by name - -- User objects are always faked on the other side, with enough shape - transferred - -XXX finish, basic interface, example, build some stuff on top of greenlets - -Related work comparison ------------------------ - -There are a lot of attempts to incorporate RPC mechanism into -Python, some of them are listed below: - -* `Pyro`_ - Pyro stands for PYthon Remote Objects, it's a mechanism of - implementing remotely accessible objects in pure python (without modifying - interpreter). This is only a remote method call implementation, with - all limitations, so: - - - No attribute access - - - Arguments of calls must be pickleable on one side and unpickleable on - remote side, which means they must share source code, they do not - become remote references - - - Exported objects must inherit from specific class and follow certain - standards, like \_\_init\_\_ shape. - - - Remote tracebacks only as strings - - - Remote calls usually invokes new threads - -* XMLRPC - There are several implementations of xmlrpc protocol in Python, - one even in the standard library. Xmlrpc is cross-language, cross-platform - protocol of communication, which implies great flexibility of tools to - choose, but also implies several limitations, like: - - - No remote tracebacks - - - Only simple types to be passed as function arguments - -* Twisted Perspective Broker - - - involves twisted, which ties user to network stack/programming style - - - event driven programming (might be good, might be bad, but it's fixed) - - - copies object (by pickling), but provides sophisticated layer of - caching to avoid multiple copies of the same object. - - - two way RPC (unlike Pyro) - - - also heavy restrictions on objects - they must subclass certain class - -.. _`Pyro`: http://pyro.sourceforge.net/ -.. _`transparent proxies`: objspace-proxies.html#tproxy From noreply at buildbot.pypy.org Sat Feb 23 21:40:20 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Sat, 23 Feb 2013 21:40:20 +0100 (CET) Subject: [pypy-commit] pypy rpython-doc: Oops. Message-ID: <20130223204020.19CED1C0CA3@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: rpython-doc Changeset: r61703:53783850f248 Date: 2013-02-23 19:07 +0100 http://bitbucket.org/pypy/pypy/changeset/53783850f248/ Log: Oops. diff --git a/rpython/doc/rpython.rst b/rpython/doc/rpython.rst --- a/rpython/doc/rpython.rst +++ b/rpython/doc/rpython.rst @@ -151,7 +151,7 @@ **builtin functions** A number of builtin functions can be used. The precise set can be - found in `rpython/annotator/builtin.py`_ (see ``def builtin_xxx()``). + found in :source:`rpython/annotator/builtin.py` (see ``def builtin_xxx()``). Some builtin functions may be limited in what they support, though. ``int, float, str, ord, chr``... are available as simple conversion @@ -188,7 +188,7 @@ We use normal integers for signed arithmetic. It means that before translation we get longs in case of overflow, and after translation we get a silent wrap-around. Whenever we need more control, we use the following -helpers (which live in `rpython/rlib/rarithmetic.py`_): +helpers (which live in :source:`rpython/rlib/rarithmetic.py`): **ovfcheck()** From noreply at buildbot.pypy.org Sat Feb 23 21:40:21 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Sat, 23 Feb 2013 21:40:21 +0100 (CET) Subject: [pypy-commit] pypy rpython-doc: Title underline was too short. Message-ID: <20130223204021.395A51C0CA3@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: rpython-doc Changeset: r61704:1fc1d8d3ee88 Date: 2013-02-23 19:10 +0100 http://bitbucket.org/pypy/pypy/changeset/1fc1d8d3ee88/ Log: Title underline was too short. diff --git a/rpython/doc/windows.rst b/rpython/doc/windows.rst --- a/rpython/doc/windows.rst +++ b/rpython/doc/windows.rst @@ -63,7 +63,7 @@ INCLUDE, LIB and PATH (for DLLs) environment variables appropriately. Abridged method (for -Ojit builds using Visual Studio 2008) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Download the versions of all the external packages from https://bitbucket.org/pypy/pypy/downloads/local.zip From noreply at buildbot.pypy.org Sat Feb 23 21:40:22 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Sat, 23 Feb 2013 21:40:22 +0100 (CET) Subject: [pypy-commit] pypy rpython-doc: Fix apostrophes. Message-ID: <20130223204022.683BA1C0CA3@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: rpython-doc Changeset: r61705:622ff3b670a4 Date: 2013-02-23 19:13 +0100 http://bitbucket.org/pypy/pypy/changeset/622ff3b670a4/ Log: Fix apostrophes. diff --git a/rpython/doc/windows.rst b/rpython/doc/windows.rst --- a/rpython/doc/windows.rst +++ b/rpython/doc/windows.rst @@ -194,7 +194,7 @@ March 2012, --cc is not a valid option for pytest.py. However if you set an environment variable CC to the compliter exe, testing will use it. -.. _'mingw32 build': http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win32/Automated%20Builds +.. _`mingw32 build`: http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win32/Automated%20Builds .. _`mingw64 build`: http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win64/Automated%20Builds .. _`msys for mingw`: http://sourceforge.net/projects/mingw-w64/files/External%20binary%20packages%20%28Win64%20hosted%29/MSYS%20%2832-bit%29 .. _`libffi source files`: http://sourceware.org/libffi/ From noreply at buildbot.pypy.org Sat Feb 23 21:57:01 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Sat, 23 Feb 2013 21:57:01 +0100 (CET) Subject: [pypy-commit] pypy py3k: adapt buffers' new readline to py3 (return bytes) Message-ID: <20130223205701.054C21C0CA3@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61706:9b6fc11644ca Date: 2013-02-23 12:53 -0800 http://bitbucket.org/pypy/pypy/changeset/9b6fc11644ca/ Log: adapt buffers' new readline to py3 (return bytes) diff --git a/pypy/module/_io/interp_bufferedio.py b/pypy/module/_io/interp_bufferedio.py --- a/pypy/module/_io/interp_bufferedio.py +++ b/pypy/module/_io/interp_bufferedio.py @@ -659,11 +659,11 @@ else: pos = -1 if pos >= 0: - w_res = space.wrap(''.join(self.buffer[self.pos:pos+1])) + w_res = space.wrapbytes(''.join(self.buffer[self.pos:pos+1])) self.pos = pos + 1 return w_res if have == limit: - w_res = space.wrap(''.join(self.buffer[self.pos:self.pos+have])) + w_res = space.wrapbytes(''.join(self.buffer[self.pos:self.pos+have])) self.pos += have return w_res @@ -705,7 +705,7 @@ written += have if limit >= 0: limit -= have - return space.wrap(''.join(chunks)) + return space.wrapbytes(''.join(chunks)) # ____________________________________________________ # Write methods From noreply at buildbot.pypy.org Sat Feb 23 21:57:02 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Sat, 23 Feb 2013 21:57:02 +0100 (CET) Subject: [pypy-commit] pypy py3k: handle unencodable strings in displayhook Message-ID: <20130223205702.441571C0CA3@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61707:34a601ca6d23 Date: 2013-02-23 12:55 -0800 http://bitbucket.org/pypy/pypy/changeset/34a601ca6d23/ Log: handle unencodable strings in displayhook diff --git a/pypy/interpreter/pyopcode.py b/pypy/interpreter/pyopcode.py --- a/pypy/interpreter/pyopcode.py +++ b/pypy/interpreter/pyopcode.py @@ -1477,7 +1477,20 @@ # (and let it deals itself with unicode handling) if not isinstance(x, str): x = str(x) - stream.write(x) + try: + stream.write(x) + except UnicodeEncodeError: + print_unencodable_to(x, stream) + + def print_unencodable_to(x, stream): + encoding = stream.encoding + encoded = x.encode(encoding, 'backslashreplace') + buffer = getattr(stream, 'buffer', None) + if buffer is not None: + buffer.write(encoded) + else: + escaped = encoded.decode(encoding, 'strict') + stream.write(escaped) def print_item(x): print_item_to(x, sys_stdout()) diff --git a/pypy/module/sys/test/test_sysmodule.py b/pypy/module/sys/test/test_sysmodule.py --- a/pypy/module/sys/test/test_sysmodule.py +++ b/pypy/module/sys/test/test_sysmodule.py @@ -170,6 +170,18 @@ sys.stdout = savestdout + def test_original_displayhook_unencodable(self): + import sys, _io + out = _io.BytesIO() + savestdout = sys.stdout + sys.stdout = _io.TextIOWrapper(out, encoding='ascii') + + sys.__displayhook__("a=\xe9 b=\uDC80 c=\U00010000 d=\U0010FFFF") + assert (out.getvalue() == + b"'a=\\xe9 b=\\udc80 c=\\U00010000 d=\\U0010ffff'") + + sys.stdout = savestdout + def test_lost_displayhook(self): import sys olddisplayhook = sys.displayhook From noreply at buildbot.pypy.org Sat Feb 23 23:02:42 2013 From: noreply at buildbot.pypy.org (RonnyPfannschmidt) Date: Sat, 23 Feb 2013 23:02:42 +0100 (CET) Subject: [pypy-commit] pypy refine-testrunner: adapt testrunner tests to shifted file opening semantics Message-ID: <20130223220242.C72A91C0327@cobra.cs.uni-duesseldorf.de> Author: Ronny Pfannschmidt Branch: refine-testrunner Changeset: r61708:ee7e2b34a9d9 Date: 2013-02-23 22:52 +0100 http://bitbucket.org/pypy/pypy/changeset/ee7e2b34a9d9/ Log: adapt testrunner tests to shifted file opening semantics diff --git a/testrunner/test/test_runner.py b/testrunner/test/test_runner.py --- a/testrunner/test/test_runner.py +++ b/testrunner/test/test_runner.py @@ -7,13 +7,26 @@ pytest_script = py.path.local(pypy.__file__).dirpath('test_all.py') - class FakeRun(object): exitcode = 0 + def __call__(self, args, cwd, out, timeout): self.called = (args, cwd, out, timeout) return self.exitcode + def __enter__(self): + return self + + def __exit__(self, *exc): + pass + + def open(self, mode): + assert mode=='w' + return self + + def write(self, data): + pass + @@ -22,8 +35,8 @@ def pytest_funcarg__fakerun(self, request): return FakeRun() - def test_explicit(self, fakerun): - res = runner.execute_test('/wd', 'test_one', 'out', 'LOGFILE', + def test_explicit(self, fakerun, ): + res = runner.execute_test('/wd', 'test_one', fakerun, 'LOGFILE', runfunc=fakerun, interp=['INTERP', 'IARG'], test_driver=['driver', 'darg'], @@ -37,7 +50,7 @@ 'test_one'] - assert fakerun.called == (expected, '/wd', 'out', 'secs') + assert fakerun.called == (expected, '/wd', fakerun, 'secs') assert res == 0 def test_explicit_win32(self, fakerun): @@ -61,7 +74,7 @@ def test_error(self, fakerun): fakerun.exitcode = 1 res = runner.execute_test( - '/wd', 'test_one', 'out', 'LOGFILE', + '/wd', 'test_one', fakerun, 'LOGFILE', runfunc=fakerun, interp=['INTERP', 'IARG'], test_driver=['driver', 'darg'] @@ -70,7 +83,7 @@ fakerun.exitcode = -signal.SIGSEGV res = runner.execute_test( - '/wd', 'test_one', 'out', 'LOGFILE', + '/wd', 'test_one', fakerun, 'LOGFILE', runfunc=fakerun, interp=['INTERP', 'IARG'], test_driver=['driver', 'darg'] diff --git a/testrunner/test/test_util.py b/testrunner/test/test_util.py --- a/testrunner/test/test_util.py +++ b/testrunner/test/test_util.py @@ -1,3 +1,4 @@ +import py import sys import util import signal @@ -51,39 +52,58 @@ tmpdir = request.getfuncargvalue('tmpdir') return tmpdir.ensure('out') - def test_run(self, out): - res = util.run([sys.executable, "-c", "print 42"], '.', out) + def pytest_funcarg__outf(self, request): + out = request.getfuncargvalue('out') + return out.open('w') + + def test_run(self, out, outf): + res = util.run([sys.executable, "-c", "print 42"], '.', outf) assert res == 0 assert out.read() == "42\n" - def test_error(self, out): - res = util.run([sys.executable, "-c", "import sys; sys.exit(3)"], '.', out) + def test_error(self, outf): + res = util.run( + [sys.executable, "-c", "import sys; sys.exit(3)"], + '.', outf) assert res == 3 - def test_signal(self, out): + def test_signal(self, outf): if sys.platform == 'win32': py.test.skip("no death by signal on windows") - res = util.run([sys.executable, "-c", "import os; os.kill(os.getpid(), 9)"], '.', out) + res = util.run( + [sys.executable, "-c", "import os; os.kill(os.getpid(), 9)"], + '.', outf) assert res == -9 - def test_timeout(self, out): - res = util.run([sys.executable, "-c", "while True: pass"], '.', out, timeout=3) + def test_timeout(self, outf): + res = util.run( + [sys.executable, "-c", "while True: pass"], + '.', outf, timeout=3) assert res == -999 - def test_timeout_lock(self, out): - res = util.run([sys.executable, "-c", "import threading; l=threading.Lock(); l.acquire(); l.acquire()"], '.', out, timeout=3) + def test_timeout_lock(self, outf): + res = util.run( + [sys.executable, "-c", + "import threading; l=threading.Lock(); l.acquire(); l.acquire()"], + '.', outf, timeout=3) assert res == -999 - def test_timeout_syscall(self, out): - res = util.run([sys.executable, "-c", "import socket; s=s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM); s.bind(('', 0)); s.recv(1000)"], '.', out, timeout=3) - assert res == -999 + def test_timeout_syscall(self, outf): + res = util.run( + [sys.executable, "-c", + "import socket;" + "s= socket.socket(socket.AF_INET, socket.SOCK_DGRAM);" + "s.bind(('', 0)); s.recv(1000)"], + '.', outf, timeout=3) + assert res == -999 - def test_timeout_success(self, out): - res = util.run([sys.executable, "-c", "print 42"], '.', - out, timeout=2) + def test_timeout_success(self, out, outf): + res = util.run( + [sys.executable, "-c", "print 42"], '.', + outf, timeout=2) assert res == 0 out = out.read() - assert out == "42\n" + assert out == "42\n" diff --git a/testrunner/util.py b/testrunner/util.py --- a/testrunner/util.py +++ b/testrunner/util.py @@ -137,11 +137,12 @@ def run(args, cwd, out, timeout=None): try: - p = subprocess.Popen(args, cwd=str(cwd), stdout=f, stderr=f) + p = subprocess.Popen(args, cwd=str(cwd), stdout=out, stderr=out) except Exception, e: - f.write("Failed to run %s with cwd='%s' timeout=%s:\n" - " %s\n" - % (args, cwd, timeout, e)) + out.write( + "Failed to run %s with cwd='%s' timeout=%s:\n %s\n" % ( + args, cwd, timeout, e + )) return RUNFAILED if timeout is None: From noreply at buildbot.pypy.org Sat Feb 23 23:20:49 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Sat, 23 Feb 2013 23:20:49 +0100 (CET) Subject: [pypy-commit] pypy py3k: special case non BaseException values in excepthook Message-ID: <20130223222049.0F34F1C008F@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61709:ade5d5bcfae9 Date: 2013-02-23 14:17 -0800 http://bitbucket.org/pypy/pypy/changeset/ade5d5bcfae9/ Log: special case non BaseException values in excepthook diff --git a/pypy/module/sys/app.py b/pypy/module/sys/app.py --- a/pypy/module/sys/app.py +++ b/pypy/module/sys/app.py @@ -8,6 +8,10 @@ def excepthook(exctype, value, traceback): """Handle an exception by displaying it with a traceback on sys.stderr.""" + if not isinstance(value, BaseException): + sys.stderr.write("TypeError: print_exception(): Exception expected for " + "value, {} found\n".format(type(value).__name__)) + return # Flush stdout as well, both files may refer to the same file try: diff --git a/pypy/module/sys/test/test_sysmodule.py b/pypy/module/sys/test/test_sysmodule.py --- a/pypy/module/sys/test/test_sysmodule.py +++ b/pypy/module/sys/test/test_sysmodule.py @@ -213,9 +213,14 @@ raise ValueError(42) except ValueError as exc: eh(*sys.exc_info()) + assert err.getvalue().endswith("ValueError: 42\n") + + eh(1, '1', 1) + expected = ("TypeError: print_exception(): Exception expected for " + "value, str found") + assert expected in err.getvalue() sys.stderr = savestderr - assert err.getvalue().endswith("ValueError: 42\n") def test_excepthook_failsafe_path(self): import traceback From noreply at buildbot.pypy.org Sat Feb 23 23:20:50 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Sat, 23 Feb 2013 23:20:50 +0100 (CET) Subject: [pypy-commit] pypy py3k: apply workarounds from 2.7 Message-ID: <20130223222050.42BA01C008F@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61710:86ae6e1c04b9 Date: 2013-02-23 14:18 -0800 http://bitbucket.org/pypy/pypy/changeset/86ae6e1c04b9/ Log: apply workarounds from 2.7 diff --git a/lib-python/3.2/test/test_peepholer.py b/lib-python/3.2/test/test_peepholer.py --- a/lib-python/3.2/test/test_peepholer.py +++ b/lib-python/3.2/test/test_peepholer.py @@ -3,6 +3,7 @@ import sys from io import StringIO import unittest +from test.support import check_impl_detail def disassemble(func): f = StringIO() @@ -43,14 +44,14 @@ def test_global_as_constant(self): # LOAD_GLOBAL None/True/False --> LOAD_CONST None/True/False def f(x): - None + y = None None return x def g(x): - True + y = True return x def h(x): - False + y = False return x for func, name in ((f, 'None'), (g, 'True'), (h, 'False')): asm = disassemble(func) @@ -77,10 +78,13 @@ self.assertIn(elem, asm) def test_pack_unpack(self): + # On PyPy, "a, b = ..." is even more optimized, by removing + # the ROT_TWO. But the ROT_TWO is not removed if assigning + # to more complex expressions, so check that. for line, elem in ( ('a, = a,', 'LOAD_CONST',), - ('a, b = a, b', 'ROT_TWO',), - ('a, b, c = a, b, c', 'ROT_THREE',), + ('a[1], b = a, b', 'ROT_TWO',), + ('a, b[2], c = a, b, c', 'ROT_THREE',), ): asm = dis_single(line) self.assertIn(elem, asm) @@ -88,6 +92,8 @@ self.assertNotIn('UNPACK_TUPLE', asm) def test_folding_of_tuples_of_constants(self): + # On CPython, "a,b,c=1,2,3" turns into "a,b,c=" + # but on PyPy, it turns into "a=1;b=2;c=3". for line, elem in ( ('a = 1,2,3', '((1, 2, 3))'), ('("a","b","c")', "(('a', 'b', 'c'))"), @@ -96,7 +102,8 @@ ('((1, 2), 3, 4)', '(((1, 2), 3, 4))'), ): asm = dis_single(line) - self.assertIn(elem, asm) + self.assert_(elem in asm or ( + line == 'a,b,c = 1,2,3' and 'UNPACK_TUPLE' not in asm)) self.assertNotIn('BUILD_TUPLE', asm) # Bug 1053819: Tuple of constants misidentified when presented with: @@ -196,13 +203,14 @@ self.assertIn('(1000)', asm) def test_binary_subscr_on_unicode(self): - # valid code get optimized - asm = dis_single('"foo"[0]') - self.assertIn("('f')", asm) - self.assertNotIn('BINARY_SUBSCR', asm) - asm = dis_single('"\u0061\uffff"[1]') - self.assertIn("('\\uffff')", asm) - self.assertNotIn('BINARY_SUBSCR', asm) + if check_impl_detail(pypy=False): + # valid code get optimized + asm = dis_single('"foo"[0]') + self.assertIn("('f')", asm) + self.assertNotIn('BINARY_SUBSCR', asm) + asm = dis_single('"\u0061\uffff"[1]') + self.assertIn("('\\uffff')", asm) + self.assertNotIn('BINARY_SUBSCR', asm) # invalid code doesn't get optimized # out of range From noreply at buildbot.pypy.org Sat Feb 23 23:20:51 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Sat, 23 Feb 2013 23:20:51 +0100 (CET) Subject: [pypy-commit] pypy py3k: cpython issue13188: generators now use value.__traceback__ when no traceback Message-ID: <20130223222051.836481C008F@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61711:9d6e4fcf6f60 Date: 2013-02-23 14:19 -0800 http://bitbucket.org/pypy/pypy/changeset/9d6e4fcf6f60/ Log: cpython issue13188: generators now use value.__traceback__ when no traceback was specified diff --git a/pypy/interpreter/generator.py b/pypy/interpreter/generator.py --- a/pypy/interpreter/generator.py +++ b/pypy/interpreter/generator.py @@ -107,6 +107,11 @@ operr = OperationError(w_type, w_val, tb) operr.normalize_exception(space) + if tb is None: + tb = space.getattr(operr.get_w_value(space), + space.wrap('__traceback__')) + if not space.is_w(tb, space.w_None): + operr.set_traceback(tb) return self.send_ex(space.w_None, operr) def descr_next(self): diff --git a/pypy/interpreter/test/test_generator.py b/pypy/interpreter/test/test_generator.py --- a/pypy/interpreter/test/test_generator.py +++ b/pypy/interpreter/test/test_generator.py @@ -163,6 +163,26 @@ raises(StopIteration, next, g) raises(NameError, g.throw, NameError) + def test_throw_tb(self): + def f(): + try: + yield + except: + raise + g = f() + try: + 1/0 + except ZeroDivisionError as v: + try: + g.throw(v) + except Exception as w: + tb = w.__traceback__ + levels = 0 + while tb: + levels += 1 + tb = tb.tb_next + assert levels == 3 + def test_close(self): def f(): yield 1 From noreply at buildbot.pypy.org Sat Feb 23 23:41:06 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sat, 23 Feb 2013 23:41:06 +0100 (CET) Subject: [pypy-commit] pypy default: (mattip) skip these tests as being too pedantic for numpypy Message-ID: <20130223224106.699A01C008F@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61712:6c65a960aff3 Date: 2013-02-23 17:39 -0500 http://bitbucket.org/pypy/pypy/changeset/6c65a960aff3/ Log: (mattip) skip these tests as being too pedantic for numpypy diff --git a/pypy/module/micronumpy/test/test_numarray.py b/pypy/module/micronumpy/test/test_numarray.py --- a/pypy/module/micronumpy/test/test_numarray.py +++ b/pypy/module/micronumpy/test/test_numarray.py @@ -1201,7 +1201,8 @@ b = array([]) raises(ValueError, "b.max()") - assert list(zeros((0, 2)).max(axis=1)) == [] + if 0: # XXX too pedantic + assert list(zeros((0, 2)).max(axis=1)) == [] def test_max_add(self): from _numpypy import array @@ -1215,7 +1216,8 @@ b = array([]) raises(ValueError, "b.min()") - assert list(zeros((0, 2)).min(axis=1)) == [] + if 0: # XXX too pedantic + assert list(zeros((0, 2)).min(axis=1)) == [] def test_argmax(self): from _numpypy import array @@ -1430,10 +1432,11 @@ assert len(a) == 6 assert (a == [0,1,2,3,4,5]).all() assert a.dtype is dtype(int) - a = concatenate((a1, a2), axis=1) - assert (a == [0,1,2,3,4,5]).all() - a = concatenate((a1, a2), axis=-1) - assert (a == [0,1,2,3,4,5]).all() + if 0: # XXX too pedantic + a = concatenate((a1, a2), axis=1) + assert (a == [0,1,2,3,4,5]).all() + a = concatenate((a1, a2), axis=-1) + assert (a == [0,1,2,3,4,5]).all() b1 = array([[1, 2], [3, 4]]) b2 = array([[5, 6]]) @@ -1452,12 +1455,13 @@ g1 = array([[0,1,2]]) g2 = array([[3,4,5]]) - g = concatenate((g1, g2), axis=-2) - assert (g == [[0,1,2],[3,4,5]]).all() + if 0: # XXX too pedantic + g = concatenate((g1, g2), axis=-2) + assert (g == [[0,1,2],[3,4,5]]).all() + exc = raises(IndexError, concatenate, (g1, g2), axis=-3) + assert str(exc.value) == "axis -3 out of bounds [0, 2)" exc = raises(IndexError, concatenate, (g1, g2), axis=2) assert str(exc.value) == "axis 2 out of bounds [0, 2)" - exc = raises(IndexError, concatenate, (g1, g2), axis=-3) - assert str(exc.value) == "axis -3 out of bounds [0, 2)" exc = raises(ValueError, concatenate, ()) assert str(exc.value) == \ @@ -1467,11 +1471,12 @@ assert str(exc.value) == \ "all the input arrays must have same number of dimensions" - g1 = array([0,1,2]) - g2 = array([[3,4,5]]) - exc = raises(ValueError, concatenate, (g1, g2), axis=2) - assert str(exc.value) == \ - "all the input arrays must have same number of dimensions" + if 0: # XXX too pedantic + g1 = array([0,1,2]) + g2 = array([[3,4,5]]) + exc = raises(ValueError, concatenate, (g1, g2), axis=2) + assert str(exc.value) == \ + "all the input arrays must have same number of dimensions" a = array([1, 2, 3, 4, 5, 6]) a = (a + a)[::2] @@ -2511,16 +2516,20 @@ from _numpypy import dtype, array d = dtype([('x', str), ('y', 'int32')]) - assert str(d.fields['x'][0]) == '|S0' + if 0: # XXX too pedantic + assert str(d.fields['x'][0]) == '|S0' assert d.fields['x'][1] == 0 assert str(d.fields['y'][0]) == 'int32' - assert d.fields['y'][1] == 0 - assert d.name == 'void32' + if 0: # XXX too pedantic + assert d.fields['y'][1] == 0 + assert d.name == 'void32' a = array([('a', 2), ('cde', 1)], dtype=d) - assert a[0]['x'] == '\x02' + if 0: # XXX too pedantic + assert a[0]['x'] == '\x02' assert a[0]['y'] == 2 - assert a[1]['x'] == '\x01' + if 0: # XXX too pedantic + assert a[1]['x'] == '\x01' assert a[1]['y'] == 1 d = dtype([('x', 'S1'), ('y', 'int32')]) @@ -2540,8 +2549,9 @@ from _numpypy import array a = array(['abc']) assert str(a.dtype) == '|S3' - a = array(['abc'], 'S') - assert str(a.dtype) == '|S3' + if 0: # XXX too pedantic + a = array(['abc'], 'S') + assert str(a.dtype) == '|S3' a = array(['abc'], 'S3') assert str(a.dtype) == '|S3' a = array(['abcde'], 'S3') From noreply at buildbot.pypy.org Sat Feb 23 23:59:56 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Sat, 23 Feb 2013 23:59:56 +0100 (CET) Subject: [pypy-commit] pypy py3k: PyPy's exception message differs here Message-ID: <20130223225956.18A011C008F@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61713:95434629b695 Date: 2013-02-23 14:59 -0800 http://bitbucket.org/pypy/pypy/changeset/95434629b695/ Log: PyPy's exception message differs here diff --git a/lib-python/3.2/test/test_generators.py b/lib-python/3.2/test/test_generators.py --- a/lib-python/3.2/test/test_generators.py +++ b/lib-python/3.2/test/test_generators.py @@ -1629,17 +1629,17 @@ >>> g.throw("abc") Traceback (most recent call last): ... -TypeError: exceptions must be classes or instances deriving from BaseException, not str +TypeError: exceptions must derive from BaseException, not str >>> g.throw(0) Traceback (most recent call last): ... -TypeError: exceptions must be classes or instances deriving from BaseException, not int +TypeError: exceptions must derive from BaseException, not int >>> g.throw(list) Traceback (most recent call last): ... -TypeError: exceptions must be classes or instances deriving from BaseException, not type +TypeError: exceptions must derive from BaseException, not type >>> def throw(g,exc): ... try: From noreply at buildbot.pypy.org Sun Feb 24 00:44:50 2013 From: noreply at buildbot.pypy.org (mattip) Date: Sun, 24 Feb 2013 00:44:50 +0100 (CET) Subject: [pypy-commit] pypy default: better handling of string dtypes Message-ID: <20130223234450.BCB431C0327@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: Changeset: r61714:ae156bb1fb56 Date: 2013-02-24 01:10 +0200 http://bitbucket.org/pypy/pypy/changeset/ae156bb1fb56/ Log: better handling of string dtypes diff --git a/pypy/module/micronumpy/interp_dtype.py b/pypy/module/micronumpy/interp_dtype.py --- a/pypy/module/micronumpy/interp_dtype.py +++ b/pypy/module/micronumpy/interp_dtype.py @@ -164,8 +164,11 @@ def is_record_type(self): return self.fields is not None + def is_str_or_unicode(self): + return (self.num == 18 or self.num == 19) + def is_flexible_type(self): - return (self.num == 18 or self.num == 19 or self.num == 20) + return (self.is_str_or_unicode() or self.is_record_type()) def __repr__(self): if self.fields is not None: @@ -526,7 +529,7 @@ self.w_longdouble = self.w_float64dtype self.w_clongdouble = self.w_complex128dtype self.w_stringdtype = W_Dtype( - types.StringType(1), + types.StringType(0), num=18, kind=STRINGLTR, name='string', diff --git a/pypy/module/micronumpy/interp_numarray.py b/pypy/module/micronumpy/interp_numarray.py --- a/pypy/module/micronumpy/interp_numarray.py +++ b/pypy/module/micronumpy/interp_numarray.py @@ -932,7 +932,8 @@ return w_object shape, elems_w = find_shape_and_elems(space, w_object, dtype) - if dtype is None: + if dtype is None or ( + dtype.is_str_or_unicode() and dtype.itemtype.get_size() < 1): for w_elem in elems_w: dtype = interp_ufuncs.find_dtype_for_scalar(space, w_elem, dtype) @@ -941,6 +942,9 @@ if dtype is None: dtype = interp_dtype.get_dtype_cache(space).w_float64dtype + if dtype.is_str_or_unicode() and dtype.itemtype.get_size() < 1: + # promote S0 -> S1, U0 -> U1 + dtype = interp_dtype.variable_dtype(space, dtype.char + '1') if ndmin > len(shape): shape = [1] * (ndmin - len(shape)) + shape arr = W_NDimArray.from_shape(shape, dtype, order=order) From noreply at buildbot.pypy.org Sun Feb 24 00:44:52 2013 From: noreply at buildbot.pypy.org (mattip) Date: Sun, 24 Feb 2013 00:44:52 +0100 (CET) Subject: [pypy-commit] pypy default: merge heads Message-ID: <20130223234452.0A5B01C0327@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: Changeset: r61715:b0fd4662f2be Date: 2013-02-24 01:11 +0200 http://bitbucket.org/pypy/pypy/changeset/b0fd4662f2be/ Log: merge heads diff --git a/pypy/module/micronumpy/test/test_numarray.py b/pypy/module/micronumpy/test/test_numarray.py --- a/pypy/module/micronumpy/test/test_numarray.py +++ b/pypy/module/micronumpy/test/test_numarray.py @@ -1201,7 +1201,8 @@ b = array([]) raises(ValueError, "b.max()") - assert list(zeros((0, 2)).max(axis=1)) == [] + if 0: # XXX too pedantic + assert list(zeros((0, 2)).max(axis=1)) == [] def test_max_add(self): from _numpypy import array @@ -1215,7 +1216,8 @@ b = array([]) raises(ValueError, "b.min()") - assert list(zeros((0, 2)).min(axis=1)) == [] + if 0: # XXX too pedantic + assert list(zeros((0, 2)).min(axis=1)) == [] def test_argmax(self): from _numpypy import array @@ -1430,10 +1432,11 @@ assert len(a) == 6 assert (a == [0,1,2,3,4,5]).all() assert a.dtype is dtype(int) - a = concatenate((a1, a2), axis=1) - assert (a == [0,1,2,3,4,5]).all() - a = concatenate((a1, a2), axis=-1) - assert (a == [0,1,2,3,4,5]).all() + if 0: # XXX too pedantic + a = concatenate((a1, a2), axis=1) + assert (a == [0,1,2,3,4,5]).all() + a = concatenate((a1, a2), axis=-1) + assert (a == [0,1,2,3,4,5]).all() b1 = array([[1, 2], [3, 4]]) b2 = array([[5, 6]]) @@ -1452,12 +1455,13 @@ g1 = array([[0,1,2]]) g2 = array([[3,4,5]]) - g = concatenate((g1, g2), axis=-2) - assert (g == [[0,1,2],[3,4,5]]).all() + if 0: # XXX too pedantic + g = concatenate((g1, g2), axis=-2) + assert (g == [[0,1,2],[3,4,5]]).all() + exc = raises(IndexError, concatenate, (g1, g2), axis=-3) + assert str(exc.value) == "axis -3 out of bounds [0, 2)" exc = raises(IndexError, concatenate, (g1, g2), axis=2) assert str(exc.value) == "axis 2 out of bounds [0, 2)" - exc = raises(IndexError, concatenate, (g1, g2), axis=-3) - assert str(exc.value) == "axis -3 out of bounds [0, 2)" exc = raises(ValueError, concatenate, ()) assert str(exc.value) == \ @@ -1467,11 +1471,12 @@ assert str(exc.value) == \ "all the input arrays must have same number of dimensions" - g1 = array([0,1,2]) - g2 = array([[3,4,5]]) - exc = raises(ValueError, concatenate, (g1, g2), axis=2) - assert str(exc.value) == \ - "all the input arrays must have same number of dimensions" + if 0: # XXX too pedantic + g1 = array([0,1,2]) + g2 = array([[3,4,5]]) + exc = raises(ValueError, concatenate, (g1, g2), axis=2) + assert str(exc.value) == \ + "all the input arrays must have same number of dimensions" a = array([1, 2, 3, 4, 5, 6]) a = (a + a)[::2] @@ -2511,16 +2516,20 @@ from _numpypy import dtype, array d = dtype([('x', str), ('y', 'int32')]) - assert str(d.fields['x'][0]) == '|S0' + if 0: # XXX too pedantic + assert str(d.fields['x'][0]) == '|S0' assert d.fields['x'][1] == 0 assert str(d.fields['y'][0]) == 'int32' - assert d.fields['y'][1] == 0 - assert d.name == 'void32' + if 0: # XXX too pedantic + assert d.fields['y'][1] == 0 + assert d.name == 'void32' a = array([('a', 2), ('cde', 1)], dtype=d) - assert a[0]['x'] == '\x02' + if 0: # XXX too pedantic + assert a[0]['x'] == '\x02' assert a[0]['y'] == 2 - assert a[1]['x'] == '\x01' + if 0: # XXX too pedantic + assert a[1]['x'] == '\x01' assert a[1]['y'] == 1 d = dtype([('x', 'S1'), ('y', 'int32')]) @@ -2540,8 +2549,9 @@ from _numpypy import array a = array(['abc']) assert str(a.dtype) == '|S3' - a = array(['abc'], 'S') - assert str(a.dtype) == '|S3' + if 0: # XXX too pedantic + a = array(['abc'], 'S') + assert str(a.dtype) == '|S3' a = array(['abc'], 'S3') assert str(a.dtype) == '|S3' a = array(['abcde'], 'S3') From noreply at buildbot.pypy.org Sun Feb 24 00:44:53 2013 From: noreply at buildbot.pypy.org (mattip) Date: Sun, 24 Feb 2013 00:44:53 +0100 (CET) Subject: [pypy-commit] pypy default: reinstate some pedantic tests, relabel ones that seem improper Message-ID: <20130223234453.2FD201C0327@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: Changeset: r61716:9795be102b9a Date: 2013-02-24 01:31 +0200 http://bitbucket.org/pypy/pypy/changeset/9795be102b9a/ Log: reinstate some pedantic tests, relabel ones that seem improper diff --git a/pypy/module/micronumpy/test/test_numarray.py b/pypy/module/micronumpy/test/test_numarray.py --- a/pypy/module/micronumpy/test/test_numarray.py +++ b/pypy/module/micronumpy/test/test_numarray.py @@ -1432,9 +1432,10 @@ assert len(a) == 6 assert (a == [0,1,2,3,4,5]).all() assert a.dtype is dtype(int) - if 0: # XXX too pedantic + if 0: # XXX why does numpy allow this? a = concatenate((a1, a2), axis=1) assert (a == [0,1,2,3,4,5]).all() + if 0: # segfault a = concatenate((a1, a2), axis=-1) assert (a == [0,1,2,3,4,5]).all() @@ -1455,9 +1456,10 @@ g1 = array([[0,1,2]]) g2 = array([[3,4,5]]) - if 0: # XXX too pedantic + if 0: # segfault g = concatenate((g1, g2), axis=-2) assert (g == [[0,1,2],[3,4,5]]).all() + if 0: # XXX why does numpy allow this? exc = raises(IndexError, concatenate, (g1, g2), axis=-3) assert str(exc.value) == "axis -3 out of bounds [0, 2)" exc = raises(IndexError, concatenate, (g1, g2), axis=2) @@ -2516,19 +2518,17 @@ from _numpypy import dtype, array d = dtype([('x', str), ('y', 'int32')]) - if 0: # XXX too pedantic - assert str(d.fields['x'][0]) == '|S0' + assert str(d.fields['x'][0]) == '|S0' assert d.fields['x'][1] == 0 assert str(d.fields['y'][0]) == 'int32' - if 0: # XXX too pedantic - assert d.fields['y'][1] == 0 - assert d.name == 'void32' + assert d.fields['y'][1] == 0 + assert d.name == 'void32' a = array([('a', 2), ('cde', 1)], dtype=d) - if 0: # XXX too pedantic + if 0: # XXX why does numpy allow this? assert a[0]['x'] == '\x02' assert a[0]['y'] == 2 - if 0: # XXX too pedantic + if 0: # XXX why does numpy allow this? assert a[1]['x'] == '\x01' assert a[1]['y'] == 1 @@ -2549,9 +2549,8 @@ from _numpypy import array a = array(['abc']) assert str(a.dtype) == '|S3' - if 0: # XXX too pedantic - a = array(['abc'], 'S') - assert str(a.dtype) == '|S3' + a = array(['abc'], 'S') + assert str(a.dtype) == '|S3' a = array(['abc'], 'S3') assert str(a.dtype) == '|S3' a = array(['abcde'], 'S3') From noreply at buildbot.pypy.org Sun Feb 24 00:44:54 2013 From: noreply at buildbot.pypy.org (mattip) Date: Sun, 24 Feb 2013 00:44:54 +0100 (CET) Subject: [pypy-commit] pypy default: test, fix segfault for negative axis in concatenate Message-ID: <20130223234454.5FBB81C0327@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: Changeset: r61717:36a9d19e67e4 Date: 2013-02-24 01:43 +0200 http://bitbucket.org/pypy/pypy/changeset/36a9d19e67e4/ Log: test, fix segfault for negative axis in concatenate diff --git a/pypy/module/micronumpy/interp_arrayops.py b/pypy/module/micronumpy/interp_arrayops.py --- a/pypy/module/micronumpy/interp_arrayops.py +++ b/pypy/module/micronumpy/interp_arrayops.py @@ -106,29 +106,32 @@ args_w = [convert_to_array(space, w_arg) for w_arg in args_w] dtype = args_w[0].get_dtype() shape = args_w[0].get_shape()[:] - if len(shape) <= axis: + _axis = axis + if axis < 0: + _axis = len(shape) + axis + if _axis < 0 or len(shape) <= _axis: raise operationerrfmt(space.w_IndexError, "axis %d out of bounds [0, %d)", axis, len(shape)) for arr in args_w[1:]: dtype = interp_ufuncs.find_binop_result_dtype(space, dtype, arr.get_dtype()) - if len(arr.get_shape()) <= axis: + if _axis < 0 or len(arr.get_shape()) <= _axis: raise operationerrfmt(space.w_IndexError, "axis %d out of bounds [0, %d)", axis, len(shape)) for i, axis_size in enumerate(arr.get_shape()): - if len(arr.get_shape()) != len(shape) or (i != axis and axis_size != shape[i]): + if len(arr.get_shape()) != len(shape) or (i != _axis and axis_size != shape[i]): raise OperationError(space.w_ValueError, space.wrap( "all the input arrays must have same number of dimensions")) - elif i == axis: + elif i == _axis: shape[i] += axis_size res = W_NDimArray.from_shape(shape, dtype, 'C') chunks = [Chunk(0, i, 1, i) for i in shape] axis_start = 0 for arr in args_w: - if arr.get_shape()[axis] == 0: + if arr.get_shape()[_axis] == 0: continue - chunks[axis] = Chunk(axis_start, axis_start + arr.get_shape()[axis], 1, - arr.get_shape()[axis]) + chunks[_axis] = Chunk(axis_start, axis_start + arr.get_shape()[_axis], 1, + arr.get_shape()[_axis]) Chunks(chunks).apply(res).implementation.setslice(space, arr) - axis_start += arr.get_shape()[axis] + axis_start += arr.get_shape()[_axis] return res @unwrap_spec(repeats=int) diff --git a/pypy/module/micronumpy/test/test_numarray.py b/pypy/module/micronumpy/test/test_numarray.py --- a/pypy/module/micronumpy/test/test_numarray.py +++ b/pypy/module/micronumpy/test/test_numarray.py @@ -1435,9 +1435,8 @@ if 0: # XXX why does numpy allow this? a = concatenate((a1, a2), axis=1) assert (a == [0,1,2,3,4,5]).all() - if 0: # segfault - a = concatenate((a1, a2), axis=-1) - assert (a == [0,1,2,3,4,5]).all() + a = concatenate((a1, a2), axis=-1) + assert (a == [0,1,2,3,4,5]).all() b1 = array([[1, 2], [3, 4]]) b2 = array([[5, 6]]) @@ -1456,12 +1455,10 @@ g1 = array([[0,1,2]]) g2 = array([[3,4,5]]) - if 0: # segfault - g = concatenate((g1, g2), axis=-2) - assert (g == [[0,1,2],[3,4,5]]).all() - if 0: # XXX why does numpy allow this? - exc = raises(IndexError, concatenate, (g1, g2), axis=-3) - assert str(exc.value) == "axis -3 out of bounds [0, 2)" + g = concatenate((g1, g2), axis=-2) + assert (g == [[0,1,2],[3,4,5]]).all() + exc = raises(IndexError, concatenate, (g1, g2), axis=-3) + assert str(exc.value) == "axis -3 out of bounds [0, 2)" exc = raises(IndexError, concatenate, (g1, g2), axis=2) assert str(exc.value) == "axis 2 out of bounds [0, 2)" From noreply at buildbot.pypy.org Sun Feb 24 00:55:56 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Sun, 24 Feb 2013 00:55:56 +0100 (CET) Subject: [pypy-commit] pypy py3k: make default_factory a property to match cpython Message-ID: <20130223235556.EB3531C0327@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61718:91e89f67c327 Date: 2013-02-23 15:54 -0800 http://bitbucket.org/pypy/pypy/changeset/91e89f67c327/ Log: make default_factory a property to match cpython diff --git a/pypy/module/_collections/app_defaultdict.py b/pypy/module/_collections/app_defaultdict.py --- a/pypy/module/_collections/app_defaultdict.py +++ b/pypy/module/_collections/app_defaultdict.py @@ -20,8 +20,16 @@ raise TypeError("first argument must be callable") else: default_factory = None - self.default_factory = default_factory + self._default_factory = default_factory super(defaultdict, self).__init__(*args, **kwds) + + @property + def default_factory(self): + return self._default_factory + + @default_factory.setter + def default_factory(self, default_factory): + self._default_factory = default_factory def __missing__(self, key): pass # this method is written at interp-level @@ -33,12 +41,12 @@ return "defaultdict(...)" try: recurse.add(id(self)) - return "defaultdict(%s, %s)" % (repr(self.default_factory), super(defaultdict, self).__repr__()) + return "defaultdict(%s, %s)" % (repr(self._default_factory), super(defaultdict, self).__repr__()) finally: recurse.remove(id(self)) def copy(self): - return type(self)(self.default_factory, self) + return type(self)(self._default_factory, self) def __copy__(self): return self.copy() @@ -55,4 +63,4 @@ This API is used by pickle.py and copy.py. """ - return (type(self), (self.default_factory,), None, None, self.iteritems()) + return (type(self), (self._default_factory,), None, None, self.iteritems()) diff --git a/pypy/module/_collections/test/test_defaultdict.py b/pypy/module/_collections/test/test_defaultdict.py --- a/pypy/module/_collections/test/test_defaultdict.py +++ b/pypy/module/_collections/test/test_defaultdict.py @@ -5,6 +5,8 @@ def test_basics(self): from _collections import defaultdict d = defaultdict(list) + assert d.default_factory is list + assert defaultdict.default_factory.__get__(d) is list l = d[5] d[5].append(42) d[5].append(43) From noreply at buildbot.pypy.org Sun Feb 24 00:55:58 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Sun, 24 Feb 2013 00:55:58 +0100 (CET) Subject: [pypy-commit] pypy py3k: another py3 fatality Message-ID: <20130223235558.50F541C0327@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61719:baa18b12d743 Date: 2013-02-23 15:55 -0800 http://bitbucket.org/pypy/pypy/changeset/baa18b12d743/ Log: another py3 fatality diff --git a/pypy/module/__builtin__/app_inspect.py b/pypy/module/__builtin__/app_inspect.py --- a/pypy/module/__builtin__/app_inspect.py +++ b/pypy/module/__builtin__/app_inspect.py @@ -82,22 +82,6 @@ Dict.update(_classdir(obj.__class__)) except AttributeError: pass - - ## Comment from object.c: - ## /* Merge in __members__ and __methods__ (if any). - ## XXX Would like this to go away someday; for now, it's - ## XXX needed to get at im_self etc of method objects. */ - for attr in ['__members__','__methods__']: - try: - l = getattr(obj, attr) - if not isinstance(l, list): - continue - for item in l: - if isinstance(item, types.StringTypes): - Dict[item] = None - except (AttributeError, TypeError): - pass - result = list(Dict.keys()) result.sort() return result From noreply at buildbot.pypy.org Sun Feb 24 00:55:59 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Sun, 24 Feb 2013 00:55:59 +0100 (CET) Subject: [pypy-commit] pypy py3k: apply 2.7 workarounds Message-ID: <20130223235559.7ACBE1C0327@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61720:3a6deaac38e8 Date: 2013-02-23 15:55 -0800 http://bitbucket.org/pypy/pypy/changeset/3a6deaac38e8/ Log: apply 2.7 workarounds diff --git a/lib-python/3.2/test/test_inspect.py b/lib-python/3.2/test/test_inspect.py --- a/lib-python/3.2/test/test_inspect.py +++ b/lib-python/3.2/test/test_inspect.py @@ -10,7 +10,7 @@ import shutil from os.path import normcase -from test.support import run_unittest, TESTFN, DirsOnSysPath +from test.support import check_impl_detail, run_unittest, TESTFN, DirsOnSysPath from test import inspect_fodder as mod from test import inspect_fodder2 as mod2 @@ -80,7 +80,8 @@ def test_excluding_predicates(self): self.istest(inspect.isbuiltin, 'sys.exit') - self.istest(inspect.isbuiltin, '[].append') + if check_impl_detail(): + self.istest(inspect.isbuiltin, '[].append') self.istest(inspect.iscode, 'mod.spam.__code__') self.istest(inspect.isframe, 'tb.tb_frame') self.istest(inspect.isfunction, 'mod.spam') @@ -97,7 +98,8 @@ else: self.assertFalse(inspect.isgetsetdescriptor(type(tb.tb_frame).f_locals)) if hasattr(types, 'MemberDescriptorType'): - self.istest(inspect.ismemberdescriptor, 'datetime.timedelta.days') + self.istest(inspect.ismemberdescriptor, + 'type(lambda: None).__globals__') else: self.assertFalse(inspect.ismemberdescriptor(datetime.timedelta.days)) From noreply at buildbot.pypy.org Sun Feb 24 03:26:39 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Sun, 24 Feb 2013 03:26:39 +0100 (CET) Subject: [pypy-commit] pypy default: some pep8 cleanups Message-ID: <20130224022639.08C9B1C0327@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r61721:a5a05f2f0d81 Date: 2013-02-23 18:26 -0800 http://bitbucket.org/pypy/pypy/changeset/a5a05f2f0d81/ Log: some pep8 cleanups diff --git a/rpython/flowspace/argument.py b/rpython/flowspace/argument.py --- a/rpython/flowspace/argument.py +++ b/rpython/flowspace/argument.py @@ -2,6 +2,7 @@ Arguments objects. """ + class Signature(object): _immutable_ = True _immutable_fields_ = ["argnames[*]"] @@ -57,7 +58,6 @@ return NotImplemented return not self == other - # make it look tuply for its use in the annotator def __len__(self): @@ -72,6 +72,7 @@ return self.kwargname raise IndexError + class ArgumentsForTranslation(object): def __init__(self, space, args_w, keywords=None, keywords_w=None, w_stararg=None, w_starstararg=None): @@ -142,16 +143,15 @@ self.keywords = self.keywords + keywords self.keywords_w = self.keywords_w + keywords_w - def fixedunpack(self, argcount): """The simplest argument parsing: get the 'argcount' arguments, or raise a real ValueError if the length is wrong.""" if self.keywords: - raise ValueError, "no keyword arguments expected" + raise ValueError("no keyword arguments expected") if len(self.arguments_w) > argcount: - raise ValueError, "too many arguments (%d expected)" % argcount + raise ValueError("too many arguments (%d expected)" % argcount) elif len(self.arguments_w) < argcount: - raise ValueError, "not enough arguments (%d expected)" % argcount + raise ValueError("not enough arguments (%d expected)" % argcount) return self.arguments_w def combine_if_necessary(self): @@ -270,7 +270,6 @@ kwds_w[self.keywords[i]] = self.keywords_w[i] return self.arguments_w, kwds_w - def match_signature(self, signature, defaults_w): """Parse args and kwargs according to the signature of a code object, or raise an ArgErr in case of failure. @@ -330,7 +329,7 @@ return ArgumentsForTranslation(self.space, args_w, keywords, keywords_w) @staticmethod - def fromshape(space, (shape_cnt,shape_keys,shape_star,shape_stst), data_w): + def fromshape(space, (shape_cnt, shape_keys, shape_star, shape_stst), data_w): args_w = data_w[:shape_cnt] p = end_keys = shape_cnt + len(shape_keys) if shape_star: @@ -360,7 +359,7 @@ def _rawshape(self, nextra=0): assert not self.combine_has_happened - shape_cnt = len(self.arguments_w)+nextra # Number of positional args + shape_cnt = len(self.arguments_w) + nextra # Number of positional args if self.keywords: shape_keys = self.keywords[:] # List of keywords (strings) shape_keys.sort() @@ -370,6 +369,7 @@ shape_stst = self.w_starstararg is not None # Flag: presence of **kwds return shape_cnt, tuple(shape_keys), shape_star, shape_stst # shape_keys are sorted + def rawshape(args, nextra=0): return args._rawshape(nextra) @@ -380,12 +380,11 @@ # class ArgErr(Exception): - def getmsg(self): raise NotImplementedError + class ArgErrCount(ArgErr): - def __init__(self, got_nargs, nkwds, signature, defaults_w, missing_args): self.signature = signature @@ -432,8 +431,8 @@ num_args) return msg + class ArgErrMultipleValues(ArgErr): - def __init__(self, argname): self.argname = argname @@ -442,8 +441,8 @@ self.argname) return msg + class ArgErrUnknownKwds(ArgErr): - def __init__(self, space, num_remainingkwds, keywords, kwds_mapping, keyword_names_w): name = '' From noreply at buildbot.pypy.org Sun Feb 24 03:30:54 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Sun, 24 Feb 2013 03:30:54 +0100 (CET) Subject: [pypy-commit] pypy default: more pep8 Message-ID: <20130224023054.0DA031C008F@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r61722:3d86bb843b94 Date: 2013-02-23 18:30 -0800 http://bitbucket.org/pypy/pypy/changeset/3d86bb843b94/ Log: more pep8 diff --git a/rpython/flowspace/flowcontext.py b/rpython/flowspace/flowcontext.py --- a/rpython/flowspace/flowcontext.py +++ b/rpython/flowspace/flowcontext.py @@ -9,11 +9,12 @@ from rpython.tool.stdlib_opcode import host_bytecode_spec from rpython.flowspace.argument import ArgumentsForTranslation from rpython.flowspace.model import (Constant, Variable, Block, Link, - UnwrapException, c_last_exception) + c_last_exception) from rpython.flowspace.framestate import (FrameState, recursively_unflatten, - recursively_flatten) + recursively_flatten) from rpython.flowspace.specialcase import (rpython_print_item, - rpython_print_newline) + rpython_print_newline) + class FlowingError(Exception): """ Signals invalid RPython in the function being analysed""" @@ -107,13 +108,12 @@ # ____________________________________________________________ -class Recorder: - +class Recorder(object): def append(self, operation): raise NotImplementedError def guessbool(self, frame, w_condition, **kwds): - raise AssertionError, "cannot guessbool(%s)" % (w_condition,) + raise AssertionError("cannot guessbool(%s)" % (w_condition,)) class BlockRecorder(Recorder): @@ -212,11 +212,13 @@ # ____________________________________________________________ -_unary_ops = [('UNARY_POSITIVE', "pos"), +_unary_ops = [ + ('UNARY_POSITIVE', "pos"), ('UNARY_NEGATIVE', "neg"), ('UNARY_NOT', "not_"), ('UNARY_CONVERT', "repr"), - ('UNARY_INVERT', "invert"),] + ('UNARY_INVERT', "invert"), +] def unaryoperation(OPCODE, op): def UNARY_OP(self, *ignored): @@ -382,7 +384,7 @@ n -= 1 if n < 0: break - values_w[n] = self.locals_stack_w[base+n] + values_w[n] = self.locals_stack_w[base + n] return values_w def dropvalues(self, n): @@ -564,7 +566,7 @@ def replace_in_stack(self, oldvalue, newvalue): w_new = Constant(newvalue) stack_items_w = self.locals_stack_w - for i in range(self.valuestackdepth-1, self.pycode.co_nlocals-1, -1): + for i in range(self.valuestackdepth - 1, self.pycode.co_nlocals - 1, -1): w_v = stack_items_w[i] if isinstance(w_v, Constant): if w_v.value is oldvalue: @@ -665,9 +667,9 @@ raise FSException(space.w_TypeError, space.wrap("raise: no active exception to re-raise")) - w_value = w_traceback = space.w_None + w_value = space.w_None if nbargs >= 3: - w_traceback = self.popvalue() + self.popvalue() if nbargs >= 2: w_value = self.popvalue() if 1: @@ -960,7 +962,7 @@ def call_function(self, oparg, w_star=None, w_starstar=None): n_arguments = oparg & 0xff - n_keywords = (oparg>>8) & 0xff + n_keywords = (oparg >> 8) & 0xff if n_keywords: keywords = [None] * n_keywords keywords_w = [None] * n_keywords @@ -979,7 +981,7 @@ arguments = self.popvalues(n_arguments) args = ArgumentsForTranslation(self.space, arguments, keywords, keywords_w, w_star, w_starstar) - w_function = self.popvalue() + w_function = self.popvalue() w_result = self.space.call_args(w_function, args) self.pushvalue(w_result) @@ -1193,6 +1195,7 @@ """Signals a 'return' statement. Argument is the wrapped object to return.""" kind = 0x01 + def __init__(self, w_returnvalue): self.w_returnvalue = w_returnvalue @@ -1210,6 +1213,7 @@ """Signals an application-level exception (i.e. an OperationException).""" kind = 0x02 + def __init__(self, operr): self.operr = operr @@ -1240,6 +1244,7 @@ """Signals a 'continue' statement. Argument is the bytecode position of the beginning of the loop.""" kind = 0x08 + def __init__(self, jump_to): self.jump_to = jump_to diff --git a/rpython/flowspace/generator.py b/rpython/flowspace/generator.py --- a/rpython/flowspace/generator.py +++ b/rpython/flowspace/generator.py @@ -1,12 +1,11 @@ """Flow graph building for generators""" -from rpython.flowspace.model import Block, Link, SpaceOperation, checkgraph -from rpython.flowspace.model import Variable, Constant -from rpython.translator.unsimplify import insert_empty_startblock -from rpython.translator.unsimplify import split_block +from rpython.flowspace.argument import Signature +from rpython.flowspace.model import (Block, Link, SpaceOperation, Variable, + Constant, checkgraph) +from rpython.translator.unsimplify import insert_empty_startblock, split_block from rpython.translator.simplify import eliminate_empty_blocks, simplify_graph from rpython.tool.sourcetools import func_with_new_name -from rpython.flowspace.argument import Signature class AbstractPosition(object): @@ -113,7 +112,8 @@ mappings = [Entry] # stopblock = Block([]) - v0 = Variable(); v1 = Variable() + v0 = Variable() + v1 = Variable() stopblock.operations = [ SpaceOperation('simple_call', [Constant(StopIteration)], v0), SpaceOperation('type', [v0], v1), diff --git a/rpython/flowspace/model.py b/rpython/flowspace/model.py --- a/rpython/flowspace/model.py +++ b/rpython/flowspace/model.py @@ -4,6 +4,7 @@ # the below object/attribute model evolved from # a discussion in Berlin, 4th of october 2003 import py + from rpython.tool.uid import uid, Hashable from rpython.tool.sourcetools import PY_IDENTIFIER, nice_repr_for_func from rpython.rlib.rarithmetic import is_valid_int, r_longlong, r_ulonglong, r_uint @@ -180,9 +181,9 @@ class Block(object): __slots__ = """inputargs operations exitswitch exits blockcolor""".split() - + def __init__(self, inputargs): - self.inputargs = list(inputargs) # mixed list of variable/const XXX + self.inputargs = list(inputargs) # mixed list of variable/const XXX self.operations = [] # list of SpaceOperation(s) self.exitswitch = None # a variable or # Constant(last_exception), see below @@ -205,7 +206,7 @@ else: txt = "codeless block" return txt - + def __repr__(self): txt = "%s with %d exits" % (str(self), len(self.exits)) if self.exitswitch: @@ -241,7 +242,7 @@ def closeblock(self, *exits): assert self.exits == [], "block already closed" self.recloseblock(*exits) - + def recloseblock(self, *exits): for exit in exits: exit.prevblock = self @@ -274,7 +275,7 @@ def renamed(self): return self._name is not self.dummyname renamed = property(renamed) - + def __init__(self, name=None): self._name = self.dummyname self._nr = -1 @@ -341,7 +342,7 @@ self.offset = offset # offset in code string def __eq__(self, other): - return (self.__class__ is other.__class__ and + return (self.__class__ is other.__class__ and self.opname == other.opname and self.args == other.args and self.result == other.result) diff --git a/rpython/flowspace/specialcase.py b/rpython/flowspace/specialcase.py --- a/rpython/flowspace/specialcase.py +++ b/rpython/flowspace/specialcase.py @@ -20,8 +20,8 @@ elif opname == 'getattr' and len(args_w) == 3: return space.do_operation('simple_call', Constant(getattr), *args_w) else: - raise Exception, "should call %r with exactly %d arguments" % ( - fn, Arity[opname]) + raise Exception("should call %r with exactly %d arguments" % ( + fn, Arity[opname])) # completely replace the call with the underlying # operation and its limited implicit exceptions semantic return getattr(space, opname)(*args_w) @@ -79,4 +79,3 @@ locals: sc_locals} for fn in OperationName: SPECIAL_CASES[fn] = sc_operator - From noreply at buildbot.pypy.org Sun Feb 24 09:18:26 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sun, 24 Feb 2013 09:18:26 +0100 (CET) Subject: [pypy-commit] pypy default: fix array2string for possibly missing long double types Message-ID: <20130224081826.E11511C008F@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61723:7fe38a515d08 Date: 2013-02-24 03:17 -0500 http://bitbucket.org/pypy/pypy/changeset/7fe38a515d08/ Log: fix array2string for possibly missing long double types diff --git a/lib_pypy/numpypy/core/arrayprint.py b/lib_pypy/numpypy/core/arrayprint.py --- a/lib_pypy/numpypy/core/arrayprint.py +++ b/lib_pypy/numpypy/core/arrayprint.py @@ -294,12 +294,12 @@ #else: format_function = formatdict['int'] elif issubclass(dtypeobj, _nt.floating): - if issubclass(dtypeobj, _nt.longfloat): + if hasattr(_nt, 'longfloat') and issubclass(dtypeobj, _nt.longfloat): format_function = formatdict['longfloat'] else: format_function = formatdict['float'] elif issubclass(dtypeobj, _nt.complexfloating): - if issubclass(dtypeobj, _nt.clongfloat): + if hasattr(_nt, 'clongfloat') and issubclass(dtypeobj, _nt.clongfloat): format_function = formatdict['longcomplexfloat'] else: format_function = formatdict['complexfloat'] From noreply at buildbot.pypy.org Sun Feb 24 09:47:44 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sun, 24 Feb 2013 09:47:44 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: A comment Message-ID: <20130224084744.CC4B61C4829@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: jitframe-on-heap Changeset: r61724:6983ff182cad Date: 2013-02-23 16:43 +0100 http://bitbucket.org/pypy/pypy/changeset/6983ff182cad/ Log: A comment diff --git a/rpython/jit/backend/x86/regalloc.py b/rpython/jit/backend/x86/regalloc.py --- a/rpython/jit/backend/x86/regalloc.py +++ b/rpython/jit/backend/x86/regalloc.py @@ -1298,6 +1298,8 @@ # the hints about the expected position of the spilled variables. # XXX we never compile code like that? + # YYY of course, because compute_hint_frame_locations() is disabled. + # re-enable this once we re-enable it! #jump_op = self.final_jump_op #if jump_op is not None and jump_op.getdescr() is descr: # self._compute_hint_frame_locations_from_descr(descr) From noreply at buildbot.pypy.org Sun Feb 24 09:47:45 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sun, 24 Feb 2013 09:47:45 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: asmgcc's call_release_gil: in-progress, the first test passes. Message-ID: <20130224084745.F21421C4829@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: jitframe-on-heap Changeset: r61725:3b36c7c6cacd Date: 2013-02-24 09:47 +0100 http://bitbucket.org/pypy/pypy/changeset/3b36c7c6cacd/ Log: asmgcc's call_release_gil: in-progress, the first test passes. diff --git a/rpython/jit/backend/x86/arch.py b/rpython/jit/backend/x86/arch.py --- a/rpython/jit/backend/x86/arch.py +++ b/rpython/jit/backend/x86/arch.py @@ -40,3 +40,4 @@ PASS_ON_MY_FRAME = 12 JITFRAME_FIXED_SIZE = 28 # 13 GPR + 15 XMM +assert PASS_ON_MY_FRAME >= 11 # asmgcc needs at least JIT_USE_WORDS + 2 diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -65,7 +65,6 @@ self.datablockwrapper = None self.stack_check_slowpath = 0 self.propagate_exception_path = 0 - self.gcrootmap_retaddr_forced = 0 self.teardown() def set_debug(self, v): @@ -1068,11 +1067,18 @@ self.implement_guard(guard_token, checkfalsecond) return genop_cmp_guard_float + def _is_asmgcc(self): + gcrootmap = self.cpu.gc_ll_descr.gcrootmap + return bool(gcrootmap) and not gcrootmap.is_shadow_stack + def _emit_call(self, x, arglocs, start=0, tmp=eax, - argtypes=None, callconv=FFI_DEFAULT_ABI, can_collect=True): + argtypes=None, callconv=FFI_DEFAULT_ABI, can_collect=1, + stack_max=PASS_ON_MY_FRAME): + if can_collect == 1 and not self._is_asmgcc(): + can_collect = 2 # don't bother with jf_extra_stack_depth if IS_X86_64: return self._emit_call_64(x, arglocs, start, argtypes, - can_collect=can_collect) + can_collect, stack_max) stack_depth = 0 n = len(arglocs) for i in range(start, n): @@ -1083,11 +1089,11 @@ else: stack_depth += 1 stack_depth += loc.get_width() // WORD - if stack_depth > PASS_ON_MY_FRAME: + if stack_depth > stack_max: stack_depth = align_stack_words(stack_depth) - align = (stack_depth - PASS_ON_MY_FRAME) + align = (stack_depth - stack_max) self.mc.SUB_ri(esp.value, align * WORD) - if can_collect: + if can_collect == 1: ofs = self.cpu.get_ofs_of_frame_field('jf_extra_stack_depth') self.mc.MOV_bi(ofs, align * WORD) else: @@ -1120,7 +1126,7 @@ self.mc.CALL(x) if can_collect: self._reload_frame_if_necessary(self.mc) - if align: + if align and can_collect == 1: ofs = self.cpu.get_ofs_of_frame_field('jf_extra_stack_depth') self.mc.MOV_bi(ofs, 0) self.pop_gcmap(self.mc) @@ -1137,7 +1143,8 @@ # the called function just added 'p' to ESP, by subtracting it again. self.mc.SUB_ri(esp.value, p) - def _emit_call_64(self, x, arglocs, start, argtypes, can_collect=True): + def _emit_call_64(self, x, arglocs, start, argtypes, + can_collect, stack_max): src_locs = [] dst_locs = [] xmm_src_locs = [] @@ -1159,10 +1166,10 @@ stack_depth = (max(all_args - floats - len(unused_gpr), 0) + max(floats - len(unused_xmm), 0)) align = 0 - if stack_depth > PASS_ON_MY_FRAME: + if stack_depth > stack_max: stack_depth = align_stack_words(stack_depth) - align = (stack_depth - PASS_ON_MY_FRAME) - if can_collect: + align = (stack_depth - stack_max) + if can_collect == 1: ofs = self.cpu.get_ofs_of_frame_field('jf_extra_stack_depth') self.mc.MOV_bi(ofs, align * WORD) self.mc.SUB_ri(esp.value, align * WORD) @@ -1225,7 +1232,7 @@ self.mc.CALL(x) if can_collect: self._reload_frame_if_necessary(self.mc) - if align: + if align and can_collect == 1: ofs = self.cpu.get_ofs_of_frame_field('jf_extra_stack_depth') self.mc.MOV_bi(ofs, 0) if align: @@ -2030,9 +2037,19 @@ descr = op.getdescr() assert isinstance(descr, CallDescr) + stack_max = PASS_ON_MY_FRAME + if self._is_asmgcc() and op.getopnum() == rop.CALL_RELEASE_GIL: + from rpython.memory.gctransform import asmgcroot + stack_max -= asmgcroot.JIT_USE_WORDS + can_collect = 2 # don't write jf_extra_stack_depth + else: + can_collect = 1 + self._emit_call(x, arglocs, 3, tmp=tmp, argtypes=descr.get_arg_types(), - callconv=descr.get_call_conv()) + callconv=descr.get_call_conv(), + can_collect=can_collect, + stack_max=stack_max) if IS_X86_32 and isinstance(resloc, FrameLoc) and resloc.type == FLOAT: # a float or a long long return @@ -2103,79 +2120,36 @@ self._emit_guard_not_forced(guard_token) def call_release_gil(self, gcrootmap, save_registers): - # First, we need to save away the registers listed in - # 'save_registers' that are not callee-save. XXX We assume that - # the XMM registers won't be modified. We store them in - # [ESP+4], [ESP+8], etc.; on x86-32 we leave enough room in [ESP] - # for the single argument to closestack_addr below. - if IS_X86_32: - p = WORD - elif IS_X86_64: - p = 0 - for reg in self._regalloc.rm.save_around_call_regs: - if reg in save_registers: - self.mc.MOV_sr(p, reg.value) - p += WORD - # if gcrootmap.is_shadow_stack: args = [] else: - # note that regalloc.py used save_all_regs=True to save all - # registers, so we don't have to care about saving them (other - # than ebp) in the close_stack_struct. But if they are registers - # like %eax that would be destroyed by this call, *and* they are - # used by arglocs for the *next* call, then trouble; for now we - # will just push/pop them. - raise NotImplementedError - xxx from rpython.memory.gctransform import asmgcroot - css = self._regalloc.close_stack_struct - if css == 0: - use_words = (2 + max(asmgcroot.INDEX_OF_EBP, - asmgcroot.FRAME_PTR) + 1) - pos = self._regalloc.fm.reserve_location_in_frame(use_words) - css = get_ebp_ofs(pos + use_words - 1) - self._regalloc.close_stack_struct = css - # The location where the future CALL will put its return address - # will be [ESP-WORD]. But we can't use that as the next frame's - # top address! As the code after releasegil() runs without the - # GIL, it might not be set yet by the time we need it (very - # unlikely), or it might be overwritten by the following call - # to reaquiregil() (much more likely). So we hack even more - # and use a dummy location containing a dummy value (a pointer - # to itself) which we pretend is the return address :-/ :-/ :-/ - # It prevents us to store any %esp-based stack locations but we - # don't so far. - adr = self.datablockwrapper.malloc_aligned(WORD, WORD) - rffi.cast(rffi.CArrayPtr(lltype.Signed), adr)[0] = adr - self.gcrootmap_retaddr_forced = adr - frame_ptr = css + WORD * (2+asmgcroot.FRAME_PTR) - if rx86.fits_in_32bits(adr): - self.mc.MOV_bi(frame_ptr, adr) # MOV [css.frame], adr - else: - self.mc.MOV_ri(eax.value, adr) # MOV EAX, adr - self.mc.MOV_br(frame_ptr, eax.value) # MOV [css.frame], EAX + # build a 'css' structure on the stack: 2 words for the linkage, + # and 5/7 words as described for asmgcroot.ASM_FRAMEDATA, for a + # total size of JIT_USE_WORDS. This structure is found at + # [ESP+css]. + css = WORD * (PASS_ON_MY_FRAME - asmgcroot.JIT_USE_WORDS) + assert css >= 2 # Save ebp index_of_ebp = css + WORD * (2+asmgcroot.INDEX_OF_EBP) - self.mc.MOV_br(index_of_ebp, ebp.value) # MOV [css.ebp], EBP - # Call the closestack() function (also releasing the GIL) + self.mc.MOV_sr(index_of_ebp, ebp.value) # MOV [css.ebp], EBP + # Save the "return address": we pretend that it's css if IS_X86_32: reg = eax elif IS_X86_64: reg = edi - self.mc.LEA_rb(reg.value, css) + self.mc.LEA_rs(reg.value, css) # LEA reg, [css] + frame_ptr = css + WORD * (2+asmgcroot.FRAME_PTR) + self.mc.MOV_sr(frame_ptr, reg.value) # MOV [css.frame], reg + # Set up jf_extra_stack_depth to pretend that the return address + # was at css, and so our stack frame is supposedly shorter by + # (css+1) words + extra_ofs = self.cpu.get_ofs_of_frame_field('jf_extra_stack_depth') + self.mc.MOV_bi(extra_ofs, (-css-1) * WORD) + # Call the closestack() function (also releasing the GIL) args = [reg] # self._emit_call(imm(self.releasegil_addr), args) - # Finally, restore the registers saved above. - if IS_X86_32: - p = WORD - elif IS_X86_64: - p = 0 - for reg in self._regalloc.rm.save_around_call_regs: - if reg in save_registers: - self.mc.MOV_rs(reg.value, p) - p += WORD def call_reacquire_gil(self, gcrootmap, save_loc): # save the previous result (eax/xmm0) into the stack temporarily. @@ -2187,18 +2161,15 @@ if gcrootmap.is_shadow_stack: args = [] else: - raise NotImplementedError - xxx - assert self.gcrootmap_retaddr_forced == -1, ( - "missing mark_gc_roots() in CALL_RELEASE_GIL") - self.gcrootmap_retaddr_forced = 0 - css = self._regalloc.close_stack_struct - assert css != 0 + from rpython.memory.gctransform import asmgcroot + extra_ofs = self.cpu.get_ofs_of_frame_field('jf_extra_stack_depth') + self.mc.MOV_bi(extra_ofs, 0) + css = WORD * (PASS_ON_MY_FRAME - asmgcroot.JIT_USE_WORDS) if IS_X86_32: reg = eax elif IS_X86_64: reg = edi - self.mc.LEA_rb(reg.value, css) + self.mc.LEA_rs(reg.value, css) args = [reg] self._emit_call(imm(self.reacqgil_addr), args) # restore the result from the stack diff --git a/rpython/jit/backend/x86/regalloc.py b/rpython/jit/backend/x86/regalloc.py --- a/rpython/jit/backend/x86/regalloc.py +++ b/rpython/jit/backend/x86/regalloc.py @@ -141,7 +141,6 @@ self.translate_support_code = translate_support_code # to be read/used by the assembler too self.jump_target_descr = None - self.close_stack_struct = 0 self.final_jump_op = None def _prepare(self, inputargs, operations, allgcrefs): @@ -797,7 +796,17 @@ assert guard_op is not None self._consider_call(op, guard_op) - consider_call_release_gil = consider_call_may_force + def consider_call_release_gil(self, op, guard_op): + # We spill the arguments to the stack, because we need to do 3 calls: + # call_release_gil(), the_real_c_function(), and call_reacquire_gil(). + # The arguments are used on the second call only. XXX we assume + # that the XMM arguments won't be modified by call_release_gil(). + for i in range(op.numargs()): + loc = self.loc(op.getarg(i)) + if loc in self.rm.save_around_call_regs: + self.rm.force_spill_var(op.getarg(i)) + assert guard_op is not None + self._consider_call(op, guard_op) def consider_call_malloc_gc(self, op): self._consider_call(op) diff --git a/rpython/memory/gctransform/asmgcroot.py b/rpython/memory/gctransform/asmgcroot.py --- a/rpython/memory/gctransform/asmgcroot.py +++ b/rpython/memory/gctransform/asmgcroot.py @@ -654,6 +654,8 @@ INDEX_OF_EBP = 3 FRAME_PTR = CALLEE_SAVED_REGS # the frame is at index 4 in the array +JIT_USE_WORDS = 2 + FRAME_PTR + 1 + ASM_CALLBACK_PTR = lltype.Ptr(lltype.FuncType([], lltype.Void)) # used internally by walk_stack_from() From noreply at buildbot.pypy.org Sun Feb 24 10:03:21 2013 From: noreply at buildbot.pypy.org (fijal) Date: Sun, 24 Feb 2013 10:03:21 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: remove _x86_debug_checksum, save 1 word on resume data Message-ID: <20130224090321.824F11C482E@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61726:cd6cffda17eb Date: 2013-02-24 11:02 +0200 http://bitbucket.org/pypy/pypy/changeset/cd6cffda17eb/ Log: remove _x86_debug_checksum, save 1 word on resume data diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -450,7 +450,6 @@ _ll_function_addr (address of the generated func, as an int) _ll_loop_code (debug: addr of the start of the ResOps) _x86_fullsize (debug: full size including failure) - _x86_debug_checksum ''' # XXX this function is too longish and contains some code # duplication with assemble_bridge(). Also, we should think @@ -729,7 +728,6 @@ s = 0 for op in operations: s += op.getopnum() - looptoken._x86_debug_checksum = s newoperations = [] self._append_debugging_code(newoperations, tp, number, diff --git a/rpython/jit/backend/x86/test/test_runner.py b/rpython/jit/backend/x86/test/test_runner.py --- a/rpython/jit/backend/x86/test/test_runner.py +++ b/rpython/jit/backend/x86/test/test_runner.py @@ -565,21 +565,3 @@ l1 = ('debug_print', preambletoken.repr_of_descr() + ':1') l2 = ('debug_print', targettoken.repr_of_descr() + ':9') assert ('jit-backend-counts', [l0, l1, l2]) in dlog - - def test_debugger_checksum(self): - loop = """ - [i0] - label(i0, descr=targettoken) - debug_merge_point('xyz', 0, 0) - i1 = int_add(i0, 1) - i2 = int_ge(i1, 10) - guard_false(i2) [] - jump(i1, descr=targettoken) - """ - ops = parse(loop, namespace={'targettoken': TargetToken()}) - self.cpu.assembler.set_debug(True) - looptoken = JitCellToken() - self.cpu.compile_loop(ops.inputargs, ops.operations, looptoken) - self.cpu.execute_token(looptoken, 0) - assert looptoken._x86_debug_checksum == sum([op.getopnum() - for op in ops.operations]) From noreply at buildbot.pypy.org Sun Feb 24 10:09:17 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sun, 24 Feb 2013 10:09:17 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: Fixes Message-ID: <20130224090917.20C4D1C008F@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: jitframe-on-heap Changeset: r61727:645a8aa47cd1 Date: 2013-02-24 10:09 +0100 http://bitbucket.org/pypy/pypy/changeset/645a8aa47cd1/ Log: Fixes diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -2141,9 +2141,9 @@ self.mc.MOV_sr(frame_ptr, reg.value) # MOV [css.frame], reg # Set up jf_extra_stack_depth to pretend that the return address # was at css, and so our stack frame is supposedly shorter by - # (css+1) words + # (css+WORD) bytes extra_ofs = self.cpu.get_ofs_of_frame_field('jf_extra_stack_depth') - self.mc.MOV_bi(extra_ofs, (-css-1) * WORD) + self.mc.MOV_bi(extra_ofs, -css-WORD) # Call the closestack() function (also releasing the GIL) args = [reg] # @@ -2160,9 +2160,13 @@ args = [] else: from rpython.memory.gctransform import asmgcroot + css = WORD * (PASS_ON_MY_FRAME - asmgcroot.JIT_USE_WORDS) + # Restore ebp + index_of_ebp = css + WORD * (2+asmgcroot.INDEX_OF_EBP) + self.mc.MOV_rs(ebp.value, index_of_ebp) # MOV ESP, [css.ebp] + # extra_ofs = self.cpu.get_ofs_of_frame_field('jf_extra_stack_depth') self.mc.MOV_bi(extra_ofs, 0) - css = WORD * (PASS_ON_MY_FRAME - asmgcroot.JIT_USE_WORDS) if IS_X86_32: reg = eax elif IS_X86_64: From noreply at buildbot.pypy.org Sun Feb 24 10:33:27 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sun, 24 Feb 2013 10:33:27 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: More fixes. Message-ID: <20130224093327.447F51C0255@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: jitframe-on-heap Changeset: r61728:4389f404b89e Date: 2013-02-24 10:33 +0100 http://bitbucket.org/pypy/pypy/changeset/4389f404b89e/ Log: More fixes. diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -1123,7 +1123,8 @@ self.push_gcmap(self.mc, gcmap, store=True) self.mc.CALL(x) if can_collect: - self._reload_frame_if_necessary(self.mc) + if can_collect != 3: + self._reload_frame_if_necessary(self.mc) if align and can_collect == 1: ofs = self.cpu.get_ofs_of_frame_field('jf_extra_stack_depth') self.mc.MOV_bi(ofs, 0) @@ -1229,7 +1230,8 @@ self.push_gcmap(self.mc, gcmap, store=True) self.mc.CALL(x) if can_collect: - self._reload_frame_if_necessary(self.mc) + if can_collect != 3: + self._reload_frame_if_necessary(self.mc) if align and can_collect == 1: ofs = self.cpu.get_ofs_of_frame_field('jf_extra_stack_depth') self.mc.MOV_bi(ofs, 0) @@ -2039,7 +2041,8 @@ if self._is_asmgcc() and op.getopnum() == rop.CALL_RELEASE_GIL: from rpython.memory.gctransform import asmgcroot stack_max -= asmgcroot.JIT_USE_WORDS - can_collect = 2 # don't write jf_extra_stack_depth + can_collect = 3 # asmgcc only: don't write jf_extra_stack_depth, + # and don't call the write barrier on ebp else: can_collect = 1 @@ -2163,7 +2166,11 @@ css = WORD * (PASS_ON_MY_FRAME - asmgcroot.JIT_USE_WORDS) # Restore ebp index_of_ebp = css + WORD * (2+asmgcroot.INDEX_OF_EBP) - self.mc.MOV_rs(ebp.value, index_of_ebp) # MOV ESP, [css.ebp] + self.mc.MOV_rs(ebp.value, index_of_ebp) # MOV EBP, [css.ebp] + wbdescr = self.cpu.gc_ll_descr.write_barrier_descr + assert wbdescr + self._write_barrier_fastpath(self.mc, wbdescr, [ebp], array=False, + is_frame=True) # extra_ofs = self.cpu.get_ofs_of_frame_field('jf_extra_stack_depth') self.mc.MOV_bi(extra_ofs, 0) From noreply at buildbot.pypy.org Sun Feb 24 11:22:25 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sun, 24 Feb 2013 11:22:25 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: Fixes Message-ID: <20130224102225.81D351C0327@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: jitframe-on-heap Changeset: r61729:eac777ca5d2b Date: 2013-02-24 11:18 +0100 http://bitbucket.org/pypy/pypy/changeset/eac777ca5d2b/ Log: Fixes diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -1123,8 +1123,7 @@ self.push_gcmap(self.mc, gcmap, store=True) self.mc.CALL(x) if can_collect: - if can_collect != 3: - self._reload_frame_if_necessary(self.mc) + self._reload_frame_if_necessary(self.mc, can_collect=can_collect) if align and can_collect == 1: ofs = self.cpu.get_ofs_of_frame_field('jf_extra_stack_depth') self.mc.MOV_bi(ofs, 0) @@ -1230,8 +1229,7 @@ self.push_gcmap(self.mc, gcmap, store=True) self.mc.CALL(x) if can_collect: - if can_collect != 3: - self._reload_frame_if_necessary(self.mc) + self._reload_frame_if_necessary(self.mc, can_collect=can_collect) if align and can_collect == 1: ofs = self.cpu.get_ofs_of_frame_field('jf_extra_stack_depth') self.mc.MOV_bi(ofs, 0) @@ -1240,12 +1238,19 @@ if can_collect: self.pop_gcmap(self.mc) - def _reload_frame_if_necessary(self, mc, align_stack=False): + def _reload_frame_if_necessary(self, mc, align_stack=False, can_collect=0): gcrootmap = self.cpu.gc_ll_descr.gcrootmap - if gcrootmap and gcrootmap.is_shadow_stack: - rst = gcrootmap.get_root_stack_top_addr() - mc.MOV(edx, heap(rst)) - mc.MOV(ebp, mem(edx, -WORD)) + if gcrootmap: + if gcrootmap.is_shadow_stack: + rst = gcrootmap.get_root_stack_top_addr() + mc.MOV(ecx, heap(rst)) + mc.MOV(ebp, mem(ecx, -WORD)) + elif can_collect == 3: + # specially for call_release_gil: must reload ebp from the css + from rpython.memory.gctransform import asmgcroot + css = WORD * (PASS_ON_MY_FRAME - asmgcroot.JIT_USE_WORDS) + index_of_ebp = css + WORD * (2+asmgcroot.INDEX_OF_EBP) + mc.MOV_rs(ebp.value, index_of_ebp) # MOV EBP, [css.ebp] wbdescr = self.cpu.gc_ll_descr.write_barrier_descr if gcrootmap and wbdescr: # frame never uses card marking, so we enforce this is not @@ -2042,7 +2047,7 @@ from rpython.memory.gctransform import asmgcroot stack_max -= asmgcroot.JIT_USE_WORDS can_collect = 3 # asmgcc only: don't write jf_extra_stack_depth, - # and don't call the write barrier on ebp + # and reload ebp from the css else: can_collect = 1 @@ -2164,14 +2169,6 @@ else: from rpython.memory.gctransform import asmgcroot css = WORD * (PASS_ON_MY_FRAME - asmgcroot.JIT_USE_WORDS) - # Restore ebp - index_of_ebp = css + WORD * (2+asmgcroot.INDEX_OF_EBP) - self.mc.MOV_rs(ebp.value, index_of_ebp) # MOV EBP, [css.ebp] - wbdescr = self.cpu.gc_ll_descr.write_barrier_descr - assert wbdescr - self._write_barrier_fastpath(self.mc, wbdescr, [ebp], array=False, - is_frame=True) - # extra_ofs = self.cpu.get_ofs_of_frame_field('jf_extra_stack_depth') self.mc.MOV_bi(extra_ofs, 0) if IS_X86_32: From noreply at buildbot.pypy.org Sun Feb 24 16:27:56 2013 From: noreply at buildbot.pypy.org (mattip) Date: Sun, 24 Feb 2013 16:27:56 +0100 (CET) Subject: [pypy-commit] pypy default: fix is_valid_int for r_int and friends for untranslated testing Message-ID: <20130224152756.ABBE41C0337@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: Changeset: r61730:f4e2d6247ba9 Date: 2013-02-24 17:27 +0200 http://bitbucket.org/pypy/pypy/changeset/f4e2d6247ba9/ Log: fix is_valid_int for r_int and friends for untranslated testing diff --git a/rpython/rlib/rarithmetic.py b/rpython/rlib/rarithmetic.py --- a/rpython/rlib/rarithmetic.py +++ b/rpython/rlib/rarithmetic.py @@ -157,7 +157,7 @@ def is_valid_int(r): if objectmodel.we_are_translated(): return isinstance(r, int) - return type(r) in (int, long, bool) and ( + return isinstance(r, (base_int, int, long, bool)) and ( -maxint - 1 <= r <= maxint) is_valid_int._annspecialcase_ = 'specialize:argtype(0)' From noreply at buildbot.pypy.org Sun Feb 24 17:05:53 2013 From: noreply at buildbot.pypy.org (fijal) Date: Sun, 24 Feb 2013 17:05:53 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: yes, pytest is awesome that way Message-ID: <20130224160553.2ADC91C4829@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61731:79d089804160 Date: 2013-02-24 18:01 +0200 http://bitbucket.org/pypy/pypy/changeset/79d089804160/ Log: yes, pytest is awesome that way diff --git a/_pytest/pdb.py b/_pytest/pdb.py --- a/_pytest/pdb.py +++ b/_pytest/pdb.py @@ -72,9 +72,12 @@ tw.sep(">", "entering PDB") # A doctest.UnexpectedException is not useful for post_mortem. # Use the underlying exception instead: - if isinstance(call.excinfo.value, py.std.doctest.UnexpectedException): - tb = call.excinfo.value.exc_info[2] - else: + try: + if isinstance(call.excinfo.value, py.std.doctest.UnexpectedException): + tb = call.excinfo.value.exc_info[2] + else: + tb = call.excinfo._excinfo[2] + except (ImportError, AttributeError): tb = call.excinfo._excinfo[2] post_mortem(tb) rep._pdbshown = True From noreply at buildbot.pypy.org Sun Feb 24 17:05:54 2013 From: noreply at buildbot.pypy.org (fijal) Date: Sun, 24 Feb 2013 17:05:54 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: merge Message-ID: <20130224160554.856641C482A@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61732:3a67f1e597d8 Date: 2013-02-24 18:04 +0200 http://bitbucket.org/pypy/pypy/changeset/3a67f1e597d8/ Log: merge diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -1123,7 +1123,7 @@ self.push_gcmap(self.mc, gcmap, store=True) self.mc.CALL(x) if can_collect: - self._reload_frame_if_necessary(self.mc) + self._reload_frame_if_necessary(self.mc, can_collect=can_collect) if align and can_collect == 1: ofs = self.cpu.get_ofs_of_frame_field('jf_extra_stack_depth') self.mc.MOV_bi(ofs, 0) @@ -1229,7 +1229,7 @@ self.push_gcmap(self.mc, gcmap, store=True) self.mc.CALL(x) if can_collect: - self._reload_frame_if_necessary(self.mc) + self._reload_frame_if_necessary(self.mc, can_collect=can_collect) if align and can_collect == 1: ofs = self.cpu.get_ofs_of_frame_field('jf_extra_stack_depth') self.mc.MOV_bi(ofs, 0) @@ -1238,12 +1238,19 @@ if can_collect: self.pop_gcmap(self.mc) - def _reload_frame_if_necessary(self, mc, align_stack=False): + def _reload_frame_if_necessary(self, mc, align_stack=False, can_collect=0): gcrootmap = self.cpu.gc_ll_descr.gcrootmap - if gcrootmap and gcrootmap.is_shadow_stack: - rst = gcrootmap.get_root_stack_top_addr() - mc.MOV(edx, heap(rst)) - mc.MOV(ebp, mem(edx, -WORD)) + if gcrootmap: + if gcrootmap.is_shadow_stack: + rst = gcrootmap.get_root_stack_top_addr() + mc.MOV(ecx, heap(rst)) + mc.MOV(ebp, mem(ecx, -WORD)) + elif can_collect == 3: + # specially for call_release_gil: must reload ebp from the css + from rpython.memory.gctransform import asmgcroot + css = WORD * (PASS_ON_MY_FRAME - asmgcroot.JIT_USE_WORDS) + index_of_ebp = css + WORD * (2+asmgcroot.INDEX_OF_EBP) + mc.MOV_rs(ebp.value, index_of_ebp) # MOV EBP, [css.ebp] wbdescr = self.cpu.gc_ll_descr.write_barrier_descr if gcrootmap and wbdescr: # frame never uses card marking, so we enforce this is not @@ -2039,7 +2046,8 @@ if self._is_asmgcc() and op.getopnum() == rop.CALL_RELEASE_GIL: from rpython.memory.gctransform import asmgcroot stack_max -= asmgcroot.JIT_USE_WORDS - can_collect = 2 # don't write jf_extra_stack_depth + can_collect = 3 # asmgcc only: don't write jf_extra_stack_depth, + # and reload ebp from the css else: can_collect = 1 @@ -2141,9 +2149,9 @@ self.mc.MOV_sr(frame_ptr, reg.value) # MOV [css.frame], reg # Set up jf_extra_stack_depth to pretend that the return address # was at css, and so our stack frame is supposedly shorter by - # (css+1) words + # (css+WORD) bytes extra_ofs = self.cpu.get_ofs_of_frame_field('jf_extra_stack_depth') - self.mc.MOV_bi(extra_ofs, (-css-1) * WORD) + self.mc.MOV_bi(extra_ofs, -css-WORD) # Call the closestack() function (also releasing the GIL) args = [reg] # @@ -2160,9 +2168,9 @@ args = [] else: from rpython.memory.gctransform import asmgcroot + css = WORD * (PASS_ON_MY_FRAME - asmgcroot.JIT_USE_WORDS) extra_ofs = self.cpu.get_ofs_of_frame_field('jf_extra_stack_depth') self.mc.MOV_bi(extra_ofs, 0) - css = WORD * (PASS_ON_MY_FRAME - asmgcroot.JIT_USE_WORDS) if IS_X86_32: reg = eax elif IS_X86_64: From noreply at buildbot.pypy.org Sun Feb 24 17:16:39 2013 From: noreply at buildbot.pypy.org (fijal) Date: Sun, 24 Feb 2013 17:16:39 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: try to use non-negative numbers when printing Message-ID: <20130224161639.70CC71C0255@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61733:98b9901b29cb Date: 2013-02-24 18:15 +0200 http://bitbucket.org/pypy/pypy/changeset/98b9901b29cb/ Log: try to use non-negative numbers when printing diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -31,7 +31,7 @@ from rpython.jit.backend.x86.jump import remap_frame_layout from rpython.jit.codewriter.effectinfo import EffectInfo from rpython.jit.codewriter import longlong -from rpython.rlib.rarithmetic import intmask +from rpython.rlib.rarithmetic import intmask, r_uint from rpython.rlib.objectmodel import compute_unique_id # darwin requires the stack to be 16 bytes aligned on calls. Same for gcc 4.5.0, @@ -493,9 +493,9 @@ debug_start("jit-backend-addr") debug_print("Loop %d (%s) has address %x to %x (bootstrap %x)" % ( looptoken.number, loopname, - rawstart + looppos, - rawstart + size_excluding_failure_stuff, - rawstart)) + r_uint(rawstart + looppos), + r_uint(rawstart + size_excluding_failure_stuff), + r_uint(rawstart))) debug_stop("jit-backend-addr") self.patch_pending_failure_recoveries(rawstart) # @@ -546,7 +546,8 @@ rawstart = self.materialize_loop(original_loop_token) debug_start("jit-backend-addr") debug_print("bridge out of Guard %x has address %x to %x" % - (descr_number, rawstart, rawstart + codeendpos)) + (descr_number, r_uint(rawstart), + r_uint(rawstart + codeendpos))) debug_stop("jit-backend-addr") self.patch_pending_failure_recoveries(rawstart) # patch the jump from original guard From noreply at buildbot.pypy.org Sun Feb 24 18:27:28 2013 From: noreply at buildbot.pypy.org (fijal) Date: Sun, 24 Feb 2013 18:27:28 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: fix the alignment Message-ID: <20130224172728.4D01C1C008F@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61734:ff4ff668691e Date: 2013-02-24 19:26 +0200 http://bitbucket.org/pypy/pypy/changeset/ff4ff668691e/ Log: fix the alignment diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -265,6 +265,7 @@ # have been used to pass arguments. Note that we pass only # one argument, that is the frame mc.MOV_rr(edi.value, esp.value) + mc.SUB_ri(esp.value, WORD) # if IS_X86_32: mc.SUB_ri(esp.value, 2*WORD) # alignment @@ -273,14 +274,16 @@ # esp is now aligned to a multiple of 16 again mc.CALL(imm(slowpathaddr)) # + if IS_X86_32: + mc.ADD_ri(esp.value, 3*WORD) # alignment + else: + mc.ADD_ri(esp.value, WORD) + # mc.MOV(eax, heap(self.cpu.pos_exception())) mc.TEST_rr(eax.value, eax.value) mc.J_il8(rx86.Conditions['NZ'], 0) jnz_location = mc.get_relative_pos() # - if IS_X86_32: - mc.ADD_ri(esp.value, 3*WORD) # alignment - # mc.RET() # # patch the JNZ above From noreply at buildbot.pypy.org Sun Feb 24 18:42:14 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sun, 24 Feb 2013 18:42:14 +0100 (CET) Subject: [pypy-commit] pypy stm-thread-2: Implement id() by using shadows, like minimark.py. Message-ID: <20130224174214.472901C0337@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stm-thread-2 Changeset: r61735:a1140a91bd3f Date: 2013-02-24 18:41 +0100 http://bitbucket.org/pypy/pypy/changeset/a1140a91bd3f/ Log: Implement id() by using shadows, like minimark.py. diff --git a/rpython/memory/gc/stmgc.py b/rpython/memory/gc/stmgc.py --- a/rpython/memory/gc/stmgc.py +++ b/rpython/memory/gc/stmgc.py @@ -63,7 +63,18 @@ # the LOCAL COPY objects, but only on them. # # - GCFLAG_HASH_FIELD: the object contains an extra field added at the -# end, with the hash value +# end. If GCFLAG_WITH_HASH (usual case), then the field contains +# both the hash and id value given to this object. Otherwise, +# it's a prebuilt object; if GCFLAG_PREBUILT_ORIGINAL then the +# field contains the hash result but the id is the address of the +# object; otherwise the field contains the address of the original +# prebuilt object, where the hash result can be indirectly found. +# +# - GCFLAG_WITH_HASH: the hash/id has been taken. On a nursery object, +# means that it has an entry in 'nursery_objects_shadows'. Otherwise, +# if GCFLAG_HASH_FIELD is set, that field stores the hash/id value. +# Otherwise, means that the hash/id is equal to this exact object's +# address. # # Invariant: between two transactions, all objects visible from the current # thread are always GLOBAL. In particular: @@ -115,9 +126,12 @@ GCFLAG_LOCAL_COPY = first_gcflag << 3 # keep in sync with et.h GCFLAG_VISITED = first_gcflag << 4 # keep in sync with et.h GCFLAG_HASH_FIELD = first_gcflag << 5 -GCFLAG_NEW_HASH = first_gcflag << 6 +GCFLAG_WITH_HASH = first_gcflag << 6 +GCFLAG_PREBUILT_ORIGINAL = first_gcflag << 7 -GCFLAG_PREBUILT = GCFLAG_GLOBAL | GCFLAG_NOT_WRITTEN +GCFLAG_PREBUILT_FLAGS = (GCFLAG_GLOBAL | + GCFLAG_NOT_WRITTEN | + GCFLAG_PREBUILT_ORIGINAL) REV_INITIAL = r_uint(1) @@ -306,7 +320,7 @@ hdr.tid = self.combine(typeid16, flags) def init_gc_object_immortal(self, addr, typeid16, flags=0): - flags |= GCFLAG_PREBUILT + flags |= GCFLAG_PREBUILT_FLAGS self.init_gc_object(addr, typeid16, flags) hdr = llmemory.cast_adr_to_ptr(addr, lltype.Ptr(self.HDR)) hdr.revision = REV_INITIAL @@ -329,7 +343,8 @@ return llmemory.NULL # hdr = self.header(localobj) - hdr.tid &= ~(GCFLAG_GLOBAL | GCFLAG_POSSIBLY_OUTDATED) + hdr.tid &= ~(GCFLAG_GLOBAL | GCFLAG_POSSIBLY_OUTDATED | + GCFLAG_PREBUILT_ORIGINAL) hdr.tid |= (GCFLAG_VISITED | GCFLAG_LOCAL_COPY) return localobj @@ -345,29 +360,88 @@ # ---------- # id() and identityhash() support + def id_or_identityhash(self, gcobj, is_hash): + """Implement the common logic of id() and identityhash() + of an object, given as a GCREF. + """ + # First go to the most up-to-date version of gcobj. It can + # be the latest global version, or the local version if it was + # already modified during this transaction. + gcobj = llop.stm_read_barrier(lltype.typeOf(gcobj), gcobj) + obj = llmemory.cast_ptr_to_adr(gcobj) + # + flags = self.header(obj).tid & (GCFLAG_HASH_FIELD | GCFLAG_WITH_HASH) + # + if flags == GCFLAG_HASH_FIELD | GCFLAG_WITH_HASH: + # 'obj' has already an explicit hash/id field, and is not a + # prebuilt object at all. Return the content of that field. + return self._get_hash_field(obj) + # + elif flags == GCFLAG_HASH_FIELD | 0: + # 'obj' is a prebuilt object with a hash field, or a runtime + # copy of such an object. + if not (self.header(obj).tid & GCFLAG_PREBUILT_ORIGINAL): + # 'obj' is a runtime copy of an original prebuilt object. + # Fetch from the "hash field" the address of this original. + obj = self._get_hash_field(obj) + obj = llmemory.cast_int_to_adr(obj) + ll_assert((self.header(obj).tid & GCFLAG_PREBUILT_ORIGINAL) + != 0, "id/hash: expected a prebuilt_original") + # + if is_hash: + return self._get_hash_field(obj) + # + elif flags == 0 | GCFLAG_WITH_HASH: + # 'obj' doesn't have a hash/id field, but we already took its + # hash/id. If it is a nursery object, go to its shadow. + tls = self.get_tls() + if tls.is_in_nursery(obj): + obj = tls.nursery_objects_shadows.get(obj) + ll_assert(obj != NULL, + "GCFLAG_WITH_HASH on nursery obj but no shadow found") + # + else: # flags == 0, 'obj' has no hash/id at all so far. + # We are going to force one; this is a write operation. + # Note that we cannot get here twice for the same gcobj + # in the same transaction: after stm_write_barrier, the + # stm_read_barrier() above will return the local object + # with GCFLAG_WITH_HASH set. + localgcobj = llop.stm_write_barrier(lltype.typeOf(gcobj),gcobj) + obj = llmemory.cast_ptr_to_adr(localgcobj) + realobj = obj + # + # If 'obj' is a nursery object, we need to make a shadow + tls = self.get_tls() + if tls.is_in_nursery(obj): + size_gc_header = self.gcheaderbuilder.size_gc_header + size = self.get_size(obj) + shadowhdr = tls.sharedarea_tls.malloc_object( + size_gc_header + size) + # XXX must initialize the shadow enough to be considered + # a valid gc object by the next major collection + obj = shadowhdr + size_gc_header + tls.nursery_objects_shadows.setitem(realobj, obj) + # + self.header(realobj).tid |= GCFLAG_WITH_HASH + # + # Cases that fall through are cases where the answer is the + # mangled address of 'obj'. + return self._get_mangled_address(obj) + def id(self, gcobj): - debug_print("XXX: id() not implemented") - return self.identityhash(gcobj) + return self.id_or_identityhash(gcobj, False) def identityhash(self, gcobj): - gcobj = llop.stm_read_barrier(lltype.typeOf(gcobj), gcobj) - obj = llmemory.cast_ptr_to_adr(gcobj) - if not (self.header(obj).tid & (GCFLAG_HASH_FIELD | GCFLAG_NEW_HASH)): - # 'obj' has no hash so far. Force one; this is a write operation. - localgcobj = llop.stm_write_barrier(lltype.typeOf(gcobj), gcobj) - obj = llmemory.cast_ptr_to_adr(localgcobj) - self.header(obj).tid |= GCFLAG_NEW_HASH - # - return self._get_object_hash(obj) + return self.id_or_identityhash(gcobj, True) - def _get_object_hash(self, obj): - if self.header(obj).tid & GCFLAG_HASH_FIELD: - objsize = self.get_size(obj) - obj = llarena.getfakearenaaddress(obj) - return (obj + objsize).signed[0] - else: - # XXX improve hash(nursery_object) - return mangle_hash(llmemory.cast_adr_to_int(obj)) + def _get_hash_field(self, obj): + objsize = self.get_size(obj) + obj = llarena.getfakearenaaddress(obj) + return (obj + objsize).signed[0] + + def _get_mangled_address(self, obj): + i = llmemory.cast_adr_to_int(obj) + return mangle_hash(i) def can_move(self, addr): tls = self.get_tls() diff --git a/rpython/memory/gc/stmtls.py b/rpython/memory/gc/stmtls.py --- a/rpython/memory/gc/stmtls.py +++ b/rpython/memory/gc/stmtls.py @@ -14,7 +14,8 @@ from rpython.memory.gc.stmgc import GCFLAG_LOCAL_COPY from rpython.memory.gc.stmgc import GCFLAG_POSSIBLY_OUTDATED from rpython.memory.gc.stmgc import GCFLAG_NOT_WRITTEN -from rpython.memory.gc.stmgc import GCFLAG_HASH_FIELD, GCFLAG_NEW_HASH +from rpython.memory.gc.stmgc import GCFLAG_HASH_FIELD, GCFLAG_WITH_HASH +from rpython.memory.gc.stmgc import GCFLAG_PREBUILT_ORIGINAL from rpython.memory.gc.stmgc import hdr_revision, set_hdr_revision SIZE_OF_SIGNED = llmemory.sizeof(lltype.Signed) @@ -55,6 +56,11 @@ # in the appropriate place, like sharedarea_tls, if needed. self.local_weakrefs = self.AddressStack() # + # Support for id and identityhash: map nursery objects with + # GCFLAG_HAS_SHADOW to their future location after the next + # local collection. + self.nursery_objects_shadows = self.AddressDict() + # self._register_with_C_code() debug_stop("gc-init") @@ -215,6 +221,10 @@ if self.local_weakrefs.non_empty(): self.update_local_weakrefs() # + # Clear this mapping. + if self.nursery_objects_shadows.length() > 0: + self.nursery_objects_shadows.clear() + # # Visit all previous OLD objects. Free the ones that have not been # visited above, and reset GCFLAG_VISITED on the others. self.mass_free_old_local(previous_sharedarea_tls) @@ -439,7 +449,7 @@ # First visit to 'obj': we must move this YOUNG obj out of the # nursery. This is the common case. Allocate a new location # for it outside the nursery. - newobj = self.duplicate_obj(obj, size) + newobj = self.duplicate_obj(obj, size, from_nursery=True) # # Note that references from 'obj' to other objects in the # nursery are kept unchanged in this step: they are copied @@ -463,18 +473,43 @@ # walk 'pending_list'. self.pending.append(newobj) - def duplicate_obj(self, obj, objsize): + def duplicate_obj(self, obj, objsize, from_nursery=False): size_gc_header = self.gc.gcheaderbuilder.size_gc_header totalsize_without_hash = size_gc_header + objsize hdr = self.gc.header(obj) - has_hash = (hdr.tid & (GCFLAG_HASH_FIELD | GCFLAG_NEW_HASH)) - if has_hash: - newtotalsize = totalsize_without_hash + ( - llmemory.sizeof(lltype.Signed)) + # + make_hash_field = False + has_shadow = False + if from_nursery: + # 'obj' is a nursery object: check if it has a shadow. + # Note that if it does, the shadow doesn't have an extra + # hash field either, but will simply have the same flag + # combination, i.e. (GCFLAG_WITH_HASH & ~GCFLAG_HASH_FIELD). + # So future reads of the hash/id on this new object will + # continue to return the mangled address of this new + # object (which was merely the shadow until now). + ll_assert((hdr.tid & GCFLAG_HASH_FIELD) == 0, + "nursery object with GCFLAG_HASH_FIELD") + if hdr.tid & GCFLAG_WITH_HASH: + has_shadow = True else: - newtotalsize = totalsize_without_hash + # From a non-nursery object: we need a hash field if + # any of the following two flags is already set on 'obj' + if hdr.tid & (GCFLAG_HASH_FIELD|GCFLAG_WITH_HASH): + make_hash_field = True # - newaddr = self.sharedarea_tls.malloc_object(newtotalsize) + if has_shadow: + newobj = self.nursery_objects_shadows.get(obj) + ll_assert(newobj != NULL, + "duplicate_obj: GCFLAG_WITH_HASH but no shadow found") + newaddr = newobj - size_gc_header + else: + if make_hash_field: + newtotalsize = totalsize_without_hash + ( + llmemory.sizeof(lltype.Signed)) + else: + newtotalsize = totalsize_without_hash + newaddr = self.sharedarea_tls.malloc_object(newtotalsize) # # Initialize the copy by doing a memcpy of the bytes. # The object header of localobj will then be fixed by the C code. @@ -484,12 +519,37 @@ totalsize_without_hash) newobj = newaddr + size_gc_header # - if has_hash: - hash = self.gc._get_object_hash(obj) + if make_hash_field: + # we have to write a value inside the new hash field + # + if hdr.tid & GCFLAG_HASH_FIELD: + # + if hdr.tid & GCFLAG_WITH_HASH: + # 'obj' has already an explicit hash/id field, and is not + # a prebuilt object at all. Just propagate the content + # of that field. + hash = self.gc._get_hash_field(obj) + # + elif hdr.tid & GCFLAG_PREBUILT_ORIGINAL: + # 'obj' is an original prebuilt object with a hash field. + # In the new hash field, store the original's address + hash = llmemory.cast_adr_to_int(obj) + else: + # 'obj' is already a modified copy of a prebuilt object. + # Propagate the content of the field. + hash = self.gc._get_hash_field(obj) + # + else: + # No previous field; store in the new field the old mangled + # address, and fix the new tid flags. + newhdr = self.gc.header(newobj) + ll_assert((newhdr.tid & GCFLAG_WITH_HASH) != 0, "gc bug!") + newhdr.tid |= GCFLAG_HASH_FIELD + hash = self.gc._get_mangled_address(obj) + # hashaddr = llarena.getfakearenaaddress(newobj) + objsize llarena.arena_reserve(hashaddr, SIZE_OF_SIGNED) hashaddr.signed[0] = hash - self.gc.header(newobj).tid |= GCFLAG_HASH_FIELD # return newobj diff --git a/rpython/memory/support.py b/rpython/memory/support.py --- a/rpython/memory/support.py +++ b/rpython/memory/support.py @@ -1,6 +1,6 @@ from rpython.rtyper.lltypesystem import lltype, llmemory from rpython.rlib.objectmodel import free_non_gc_object, we_are_translated -from rpython.rlib.rarithmetic import r_uint, LONG_BIT +from rpython.rlib.rarithmetic import r_uint, intmask, LONG_BIT from rpython.rlib.debug import ll_assert from rpython.tool.identity_dict import identity_dict @@ -9,7 +9,9 @@ # To hash pointers in dictionaries. Assumes that i shows some # alignment (to 4, 8, maybe 16 bytes), so we use the following # formula to avoid the trailing bits being always 0. - return i ^ (i >> 4) + # This formula is reversible: two different values of 'i' will + # always give two different results. + return i ^ intmask(r_uint(i) >> 4) # ____________________________________________________________ From noreply at buildbot.pypy.org Sun Feb 24 18:54:27 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Sun, 24 Feb 2013 18:54:27 +0100 (CET) Subject: [pypy-commit] pypy default: style cleanups to resume.py Message-ID: <20130224175427.4B80C1C07B6@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: Changeset: r61736:01ebd2e2a49f Date: 2013-02-24 09:54 -0800 http://bitbucket.org/pypy/pypy/changeset/01ebd2e2a49f/ Log: style cleanups to resume.py diff --git a/rpython/jit/metainterp/resume.py b/rpython/jit/metainterp/resume.py --- a/rpython/jit/metainterp/resume.py +++ b/rpython/jit/metainterp/resume.py @@ -1,19 +1,15 @@ -import sys, os -from rpython.jit.metainterp.history import Box, Const, ConstInt, getkind -from rpython.jit.metainterp.history import BoxInt, BoxPtr, BoxFloat -from rpython.jit.metainterp.history import INT, REF, FLOAT, HOLE -from rpython.jit.metainterp.history import AbstractDescr +from rpython.jit.codewriter.effectinfo import EffectInfo +from rpython.jit.metainterp import jitprof +from rpython.jit.metainterp.history import (Box, Const, ConstInt, getkind, + BoxInt, BoxPtr, BoxFloat, INT, REF, FLOAT, AbstractDescr) from rpython.jit.metainterp.resoperation import rop -from rpython.jit.metainterp import jitprof -from rpython.jit.codewriter.effectinfo import EffectInfo +from rpython.rlib import rarithmetic, rstack +from rpython.rlib.objectmodel import we_are_translated, specialize, compute_unique_id +from rpython.rlib.debug import (have_debug_prints, ll_assert, debug_start, + debug_stop, debug_print) +from rpython.rtyper import annlowlevel from rpython.rtyper.lltypesystem import lltype, llmemory, rffi, rstr -from rpython.rtyper import annlowlevel -from rpython.rlib import rarithmetic, rstack -from rpython.rlib.objectmodel import we_are_translated, specialize -from rpython.rlib.objectmodel import compute_unique_id -from rpython.rlib.debug import have_debug_prints, ll_assert -from rpython.rlib.debug import debug_start, debug_stop, debug_print -from rpython.jit.metainterp.optimize import InvalidLoop + # Logic to encode the chain of frames and the state of the boxes at a # guard operation, and to decode it again. This is a bit advanced, @@ -39,11 +35,11 @@ target = framestack[n] if n == 0: return - back = framestack[n-1] + back = framestack[n - 1] if target.parent_resumedata_frame_info_list is not None: assert target.parent_resumedata_frame_info_list.pc == back.pc return - _ensure_parent_resumedata(framestack, n-1) + _ensure_parent_resumedata(framestack, n - 1) target.parent_resumedata_frame_info_list = FrameInfo( back.parent_resumedata_frame_info_list, back.jitcode, @@ -106,8 +102,8 @@ def untag(value): value = rarithmetic.widen(value) - tagbits = value&TAGMASK - return value>>2, tagbits + tagbits = value & TAGMASK + return value >> 2, tagbits def tagged_eq(x, y): # please rpython :( @@ -126,8 +122,8 @@ TAGBOX = 2 TAGVIRTUAL = 3 -UNASSIGNED = tag(-1<<13, TAGBOX) -UNASSIGNEDVIRTUAL = tag(-1<<13, TAGVIRTUAL) +UNASSIGNED = tag(-1 << 13, TAGBOX) +UNASSIGNEDVIRTUAL = tag(-1 << 13, TAGVIRTUAL) NULLREF = tag(-1, TAGCONST) UNINITIALIZED = tag(-2, TAGCONST) # used for uninitialized string characters @@ -191,7 +187,7 @@ return numb, liveboxes.copy(), v numb1, liveboxes, v = self.number(optimizer, snapshot.prev) - n = len(liveboxes)-v + n = len(liveboxes) - v boxes = snapshot.boxes length = len(boxes) numb = lltype.malloc(NUMBERING, length) @@ -232,7 +228,7 @@ # returns a negative number if box in self.cached_boxes: num = self.cached_boxes[box] - boxes[-num-1] = box + boxes[-num - 1] = box else: boxes.append(box) num = -len(boxes) @@ -261,8 +257,8 @@ _frame_info_placeholder = (None, 0, 0) + class ResumeDataVirtualAdder(object): - def __init__(self, storage, memo): self.storage = storage self.memo = memo @@ -333,7 +329,7 @@ # collect liveboxes and virtuals n = len(liveboxes_from_env) - v - liveboxes = [None]*n + liveboxes = [None] * n self.vfieldboxes = {} for box, tagged in liveboxes_from_env.iteritems(): i, tagbits = untag(tagged) @@ -415,7 +411,7 @@ # xxx heuristic a bit out of thin air failargs_limit = memo.metainterp_sd.options.failargs_limit if nliveboxes > (failargs_limit // 2): - if nholes > nliveboxes//3: + if nholes > nliveboxes // 3: return True return False @@ -434,10 +430,10 @@ raise TagOverflow itemindex = rffi.cast(rffi.INT, itemindex) # - rd_pendingfields[i].lldescr = lldescr - rd_pendingfields[i].num = num + rd_pendingfields[i].lldescr = lldescr + rd_pendingfields[i].num = num rd_pendingfields[i].fieldnum = fieldnum - rd_pendingfields[i].itemindex= itemindex + rd_pendingfields[i].itemindex = itemindex self.storage.rd_pendingfields = rd_pendingfields def _gettagged(self, box): @@ -729,10 +725,10 @@ def _prepare_pendingfields(self, pendingfields): if pendingfields: for i in range(len(pendingfields)): - lldescr = pendingfields[i].lldescr - num = pendingfields[i].num + lldescr = pendingfields[i].lldescr + num = pendingfields[i].num fieldnum = pendingfields[i].fieldnum - itemindex= pendingfields[i].itemindex + itemindex = pendingfields[i].itemindex descr = annlowlevel.cast_base_ptr_to_instance(AbstractDescr, lldescr) struct = self.decode_ref(num) @@ -791,6 +787,7 @@ metainterp.framestack.reverse() return resumereader.liveboxes, virtualizable_boxes, virtualref_boxes + class ResumeDataBoxReader(AbstractResumeDataReader): unique_id = lambda: None @@ -946,8 +943,10 @@ def decode_int(self, tagged): return self.decode_box(tagged, INT) + def decode_ref(self, tagged): return self.decode_box(tagged, REF) + def decode_float(self, tagged): return self.decode_box(tagged, FLOAT) @@ -979,7 +978,7 @@ elif kind == REF: box = BoxPtr(self.cpu.get_latest_value_ref(self.deadframe, num)) elif kind == FLOAT: - box = BoxFloat(self.cpu.get_latest_value_float(self.deadframe,num)) + box = BoxFloat(self.cpu.get_latest_value_float(self.deadframe, num)) else: assert 0, "bad kind: %d" % ord(kind) self.liveboxes[num] = box @@ -987,17 +986,23 @@ def decode_box_of_type(self, TYPE, tagged): kind = getkind(TYPE) - if kind == 'int': kind = INT - elif kind == 'ref': kind = REF - elif kind == 'float': kind = FLOAT - else: raise AssertionError(kind) + if kind == 'int': + kind = INT + elif kind == 'ref': + kind = REF + elif kind == 'float': + kind = FLOAT + else: + raise AssertionError(kind) return self.decode_box(tagged, kind) decode_box_of_type._annspecialcase_ = 'specialize:arg(1)' def write_an_int(self, index, box): self.boxes_i[index] = box + def write_a_ref(self, index, box): self.boxes_r[index] = box + def write_a_float(self, index, box): self.boxes_f[index] = box @@ -1052,6 +1057,7 @@ resumereader.consume_vref_and_vable(vrefinfo, vinfo, ginfo) return resumereader.force_all_virtuals() + class ResumeDataDirectReader(AbstractResumeDataReader): unique_id = lambda: None virtual_default = lltype.nullptr(llmemory.GCREF.TO) @@ -1091,7 +1097,7 @@ assert (end & 1) == 0 for i in range(0, end, 2): virtual = self.decode_ref(numb.nums[i]) - vref = self.decode_ref(numb.nums[i+1]) + vref = self.decode_ref(numb.nums[i + 1]) # For each pair, we store the virtual inside the vref. vrefinfo.continue_tracing(vref, virtual) @@ -1134,7 +1140,8 @@ self.cur_numb = numb.prev if self.resume_after_guard_not_forced != 2: end_vref = self.consume_vable_info(vinfo, numb) - if ginfo is not None: end_vref -= 1 + if ginfo is not None: + end_vref -= 1 self.consume_virtualref_info(vrefinfo, numb, end_vref) def allocate_with_vtable(self, known_class): @@ -1319,10 +1326,10 @@ if storage.rd_pendingfields: debug_print('\tpending setfields') for i in range(len(storage.rd_pendingfields)): - lldescr = storage.rd_pendingfields[i].lldescr - num = storage.rd_pendingfields[i].num + lldescr = storage.rd_pendingfields[i].lldescr + num = storage.rd_pendingfields[i].num fieldnum = storage.rd_pendingfields[i].fieldnum - itemindex= storage.rd_pendingfields[i].itemindex + itemindex = storage.rd_pendingfields[i].itemindex debug_print("\t\t", str(lldescr), str(untag(num)), str(untag(fieldnum)), itemindex) debug_stop("jit-resume") From noreply at buildbot.pypy.org Sun Feb 24 18:56:22 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sun, 24 Feb 2013 18:56:22 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: Fix translation for no-jit cases Message-ID: <20130224175622.1DAA41C008F@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: jitframe-on-heap Changeset: r61737:434115dab59e Date: 2013-02-24 18:51 +0100 http://bitbucket.org/pypy/pypy/changeset/434115dab59e/ Log: Fix translation for no-jit cases diff --git a/rpython/memory/gctransform/asmgcroot.py b/rpython/memory/gctransform/asmgcroot.py --- a/rpython/memory/gctransform/asmgcroot.py +++ b/rpython/memory/gctransform/asmgcroot.py @@ -557,6 +557,7 @@ pos = ~ pos # can ignore this "range" marker here gccallshapes = llop.gc_asmgcroot_static(llmemory.Address, 2) self.addr = gccallshapes + pos + self.jit_index = -1 def setjitframe(self, extra_stack_depth): self.addr = llmemory.NULL @@ -564,9 +565,10 @@ self.extra_stack_depth = extra_stack_depth def next(self): - addr = self.addr - if addr: + index = self.jit_index + if index < 0: # case "outside the jit" + addr = self.addr value = 0 while True: b = ord(addr.char[0]) @@ -581,7 +583,6 @@ # case "in the jit" from rpython.jit.backend.x86.arch import FRAME_FIXED_SIZE from rpython.jit.backend.x86.arch import PASS_ON_MY_FRAME - index = self.jit_index self.jit_index = index + 1 if index == 0: # the jitframe is an object in EBP From noreply at buildbot.pypy.org Sun Feb 24 18:56:23 2013 From: noreply at buildbot.pypy.org (arigo) Date: Sun, 24 Feb 2013 18:56:23 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: Fix Message-ID: <20130224175623.546DB1C008F@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: jitframe-on-heap Changeset: r61738:f3f2ea7536d7 Date: 2013-02-24 18:56 +0100 http://bitbucket.org/pypy/pypy/changeset/f3f2ea7536d7/ Log: Fix diff --git a/rpython/rlib/_stacklet_asmgcc.py b/rpython/rlib/_stacklet_asmgcc.py --- a/rpython/rlib/_stacklet_asmgcc.py +++ b/rpython/rlib/_stacklet_asmgcc.py @@ -77,15 +77,20 @@ callee = self.curframe retaddraddr = self.translateptr(callee.frame_address) retaddr = retaddraddr.address[0] - basewalker.locate_caller_based_on_retaddr(retaddr) + ebp_in_caller = callee.regs_stored_at[INDEX_OF_EBP] + ebp_in_caller = self.translateptr(ebp_in_caller) + ebp_in_caller = ebp_in_caller.address[0] + basewalker.locate_caller_based_on_retaddr(retaddr, + ebp_in_caller) self.enumerating = True + else: + callee = self.curframe + ebp_in_caller = callee.regs_stored_at[INDEX_OF_EBP] + ebp_in_caller = self.translateptr(ebp_in_caller) + ebp_in_caller = ebp_in_caller.address[0] # # not really a loop, but kept this way for similarity # with asmgcroot: - callee = self.curframe - ebp_in_caller = callee.regs_stored_at[INDEX_OF_EBP] - ebp_in_caller = self.translateptr(ebp_in_caller) - ebp_in_caller = ebp_in_caller.address[0] while True: location = basewalker._shape_decompressor.next() if location == 0: From noreply at buildbot.pypy.org Sun Feb 24 19:19:27 2013 From: noreply at buildbot.pypy.org (fijal) Date: Sun, 24 Feb 2013 19:19:27 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: sanity check Message-ID: <20130224181927.4A7D01C008F@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61739:7baba60210b6 Date: 2013-02-24 20:17 +0200 http://bitbucket.org/pypy/pypy/changeset/7baba60210b6/ Log: sanity check diff --git a/rpython/jit/backend/x86/regalloc.py b/rpython/jit/backend/x86/regalloc.py --- a/rpython/jit/backend/x86/regalloc.py +++ b/rpython/jit/backend/x86/regalloc.py @@ -300,11 +300,18 @@ self.assembler.dump('%s <- %s(%s)' % (result_loc, op, arglocs)) self.assembler.regalloc_perform_math(op, arglocs, result_loc) - def locs_for_fail(self, guard_op): - return [self.loc(v) for v in guard_op.getfailargs()] + def locs_for_fail(self, guard_op, no_regs=False): + r = [] + for v in guard_op.getfailargs(): + loc = self.loc(v) + if no_regs and loc is not None: + assert isinstance(loc, FrameLoc) + r.append(loc) + return r - def perform_with_guard(self, op, guard_op, arglocs, result_loc): - faillocs = self.locs_for_fail(guard_op) + def perform_with_guard(self, op, guard_op, arglocs, result_loc, + no_regs=False): + faillocs = self.locs_for_fail(guard_op, no_regs=no_regs) self.rm.position += 1 self.xrm.position += 1 self.assembler.regalloc_perform_with_guard(op, guard_op, faillocs, @@ -745,7 +752,8 @@ else: resloc = None if guard_not_forced_op is not None: - self.perform_with_guard(op, guard_not_forced_op, arglocs, resloc) + self.perform_with_guard(op, guard_not_forced_op, arglocs, resloc, + no_regs=True) else: self.perform(op, arglocs, resloc) From noreply at buildbot.pypy.org Sun Feb 24 19:19:28 2013 From: noreply at buildbot.pypy.org (fijal) Date: Sun, 24 Feb 2013 19:19:28 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: merge Message-ID: <20130224181928.6A7331C008F@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61740:6b58d4c57cd5 Date: 2013-02-24 20:18 +0200 http://bitbucket.org/pypy/pypy/changeset/6b58d4c57cd5/ Log: merge diff --git a/rpython/memory/gctransform/asmgcroot.py b/rpython/memory/gctransform/asmgcroot.py --- a/rpython/memory/gctransform/asmgcroot.py +++ b/rpython/memory/gctransform/asmgcroot.py @@ -557,6 +557,7 @@ pos = ~ pos # can ignore this "range" marker here gccallshapes = llop.gc_asmgcroot_static(llmemory.Address, 2) self.addr = gccallshapes + pos + self.jit_index = -1 def setjitframe(self, extra_stack_depth): self.addr = llmemory.NULL @@ -564,9 +565,10 @@ self.extra_stack_depth = extra_stack_depth def next(self): - addr = self.addr - if addr: + index = self.jit_index + if index < 0: # case "outside the jit" + addr = self.addr value = 0 while True: b = ord(addr.char[0]) @@ -581,7 +583,6 @@ # case "in the jit" from rpython.jit.backend.x86.arch import FRAME_FIXED_SIZE from rpython.jit.backend.x86.arch import PASS_ON_MY_FRAME - index = self.jit_index self.jit_index = index + 1 if index == 0: # the jitframe is an object in EBP diff --git a/rpython/rlib/_stacklet_asmgcc.py b/rpython/rlib/_stacklet_asmgcc.py --- a/rpython/rlib/_stacklet_asmgcc.py +++ b/rpython/rlib/_stacklet_asmgcc.py @@ -77,15 +77,20 @@ callee = self.curframe retaddraddr = self.translateptr(callee.frame_address) retaddr = retaddraddr.address[0] - basewalker.locate_caller_based_on_retaddr(retaddr) + ebp_in_caller = callee.regs_stored_at[INDEX_OF_EBP] + ebp_in_caller = self.translateptr(ebp_in_caller) + ebp_in_caller = ebp_in_caller.address[0] + basewalker.locate_caller_based_on_retaddr(retaddr, + ebp_in_caller) self.enumerating = True + else: + callee = self.curframe + ebp_in_caller = callee.regs_stored_at[INDEX_OF_EBP] + ebp_in_caller = self.translateptr(ebp_in_caller) + ebp_in_caller = ebp_in_caller.address[0] # # not really a loop, but kept this way for similarity # with asmgcroot: - callee = self.curframe - ebp_in_caller = callee.regs_stored_at[INDEX_OF_EBP] - ebp_in_caller = self.translateptr(ebp_in_caller) - ebp_in_caller = ebp_in_caller.address[0] while True: location = basewalker._shape_decompressor.next() if location == 0: From noreply at buildbot.pypy.org Sun Feb 24 19:39:20 2013 From: noreply at buildbot.pypy.org (fijal) Date: Sun, 24 Feb 2013 19:39:20 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: backout this for now until we figure out whats going on Message-ID: <20130224183920.5EF7A1C008F@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61741:29698585f7f7 Date: 2013-02-24 20:38 +0200 http://bitbucket.org/pypy/pypy/changeset/29698585f7f7/ Log: backout this for now until we figure out whats going on diff --git a/rpython/jit/backend/x86/regalloc.py b/rpython/jit/backend/x86/regalloc.py --- a/rpython/jit/backend/x86/regalloc.py +++ b/rpython/jit/backend/x86/regalloc.py @@ -300,18 +300,11 @@ self.assembler.dump('%s <- %s(%s)' % (result_loc, op, arglocs)) self.assembler.regalloc_perform_math(op, arglocs, result_loc) - def locs_for_fail(self, guard_op, no_regs=False): - r = [] - for v in guard_op.getfailargs(): - loc = self.loc(v) - if no_regs and loc is not None: - assert isinstance(loc, FrameLoc) - r.append(loc) - return r + def locs_for_fail(self, guard_op): + return [self.loc(v) for v in guard_op.getfailargs()] - def perform_with_guard(self, op, guard_op, arglocs, result_loc, - no_regs=False): - faillocs = self.locs_for_fail(guard_op, no_regs=no_regs) + def perform_with_guard(self, op, guard_op, arglocs, result_loc): + faillocs = self.locs_for_fail(guard_op) self.rm.position += 1 self.xrm.position += 1 self.assembler.regalloc_perform_with_guard(op, guard_op, faillocs, @@ -752,8 +745,7 @@ else: resloc = None if guard_not_forced_op is not None: - self.perform_with_guard(op, guard_not_forced_op, arglocs, resloc, - no_regs=True) + self.perform_with_guard(op, guard_not_forced_op, arglocs, resloc) else: self.perform(op, arglocs, resloc) From noreply at buildbot.pypy.org Sun Feb 24 19:52:16 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Sun, 24 Feb 2013 19:52:16 +0100 (CET) Subject: [pypy-commit] pypy py3k: hide app_main's frames. this breaks sys.exc_info but py3 offers a workaround Message-ID: <20130224185216.9B8D31C0255@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61742:894b0fa3245b Date: 2013-02-24 10:51 -0800 http://bitbucket.org/pypy/pypy/changeset/894b0fa3245b/ Log: hide app_main's frames. this breaks sys.exc_info but py3 offers a workaround diff --git a/pypy/interpreter/app_main.py b/pypy/interpreter/app_main.py --- a/pypy/interpreter/app_main.py +++ b/pypy/interpreter/app_main.py @@ -20,6 +20,10 @@ from __future__ import print_function, unicode_literals +try: + from __pypy__ import hidden_applevel +except ImportError: + hidden_applevel = lambda f: f import errno import sys @@ -44,6 +48,7 @@ exitcode = 1 raise SystemExit(exitcode) + at hidden_applevel def run_toplevel(f, *fargs, **fkwds): """Calls f() and handles all OperationErrors. Intended use is to run the main program or one interactive statement. @@ -55,13 +60,13 @@ f(*fargs, **fkwds) except SystemExit as e: handle_sys_exit(e) - except: - display_exception() + except BaseException as e: + display_exception(e) return False return True # success -def display_exception(): - etype, evalue, etraceback = sys.exc_info() +def display_exception(e): + etype, evalue, etraceback = type(e), e, e.__traceback__ try: # extra debugging info in case the code below goes very wrong if DEBUG and hasattr(sys, 'stderr'): @@ -87,14 +92,14 @@ hook(etype, evalue, etraceback) return # done - except: + except BaseException as e: try: stderr = sys.stderr except AttributeError: pass # too bad else: print('Error calling sys.excepthook:', file=stderr) - originalexcepthook(*sys.exc_info()) + originalexcepthook(type(e), e, e.__traceback__) print(file=stderr) print('Original exception was:', file=stderr) @@ -463,6 +468,7 @@ # this indirection is needed to be able to import this module on python2, else # we have a SyntaxError: unqualified exec in a nested function + at hidden_applevel def exec_(src, dic): exec(src, dic) @@ -540,6 +546,7 @@ # Put '' on sys.path sys.path.insert(0, '') + @hidden_applevel def run_it(): exec_(run_command, mainmodule.__dict__) success = run_toplevel(run_it) @@ -574,6 +581,7 @@ print("Could not open PYTHONSTARTUP", file=sys.stderr) print("IOError:", e, file=sys.stderr) else: + @hidden_applevel def run_it(): co_python_startup = compile(startup, python_startup, @@ -590,6 +598,7 @@ inspect = True else: # If not interactive, just read and execute stdin normally. + @hidden_applevel def run_it(): co_stdin = compile(sys.stdin.read(), '', 'exec') exec_(co_stdin, mainmodule.__dict__) @@ -624,6 +633,7 @@ args = (runpy._run_module_as_main, '__main__', False) else: # no. That's the normal path, "pypy stuff.py". + @hidden_applevel def execfile(filename, namespace): with open(filename, 'rb') as f: code = f.read() diff --git a/pypy/module/__pypy__/__init__.py b/pypy/module/__pypy__/__init__.py --- a/pypy/module/__pypy__/__init__.py +++ b/pypy/module/__pypy__/__init__.py @@ -49,6 +49,7 @@ 'debug_stop' : 'interp_debug.debug_stop', 'debug_print_once' : 'interp_debug.debug_print_once', 'builtinify' : 'interp_magic.builtinify', + 'hidden_applevel' : 'interp_magic.hidden_applevel', 'lookup_special' : 'interp_magic.lookup_special', 'do_what_I_mean' : 'interp_magic.do_what_I_mean', 'list_strategy' : 'interp_magic.list_strategy', diff --git a/pypy/module/__pypy__/interp_magic.py b/pypy/module/__pypy__/interp_magic.py --- a/pypy/module/__pypy__/interp_magic.py +++ b/pypy/module/__pypy__/interp_magic.py @@ -56,6 +56,13 @@ bltn = BuiltinFunction(func) return space.wrap(bltn) +def hidden_applevel(space, w_func): + """Decorator that hides a function's frame from app-level""" + from pypy.interpreter.function import Function + func = space.interp_w(Function, w_func) + func.getcode().hidden_applevel = True + return w_func + @unwrap_spec(ObjSpace, W_Root, str) def lookup_special(space, w_obj, meth): """Lookup up a special method on an object.""" diff --git a/pypy/module/__pypy__/test/test_special.py b/pypy/module/__pypy__/test/test_special.py --- a/pypy/module/__pypy__/test/test_special.py +++ b/pypy/module/__pypy__/test/test_special.py @@ -26,6 +26,39 @@ assert A.a is A.__dict__['a'] assert A.b is A.__dict__['b'] + def test_hidden_applevel(self): + import __pypy__ + import sys + + @__pypy__.hidden_applevel + def sneak(): (lambda: 1/0)() + try: + sneak() + except ZeroDivisionError as e: + tb = e.__traceback__ + assert tb.tb_frame == sys._getframe() + assert tb.tb_next.tb_frame.f_code.co_name == '' + else: + assert False, 'Expected ZeroDivisionError' + + def test_hidden_applevel_frames(self): + import __pypy__ + import sys + + @__pypy__.hidden_applevel + def test_hidden(): + assert sys._getframe().f_code.co_name != 'test_hidden' + def e(): 1/0 + try: e() + except ZeroDivisionError as e: + assert sys.exc_info() == (None, None, None) + frame = e.__traceback__.tb_frame + assert frame != sys._getframe() + assert frame.f_code.co_name == 'e' + else: assert False + return 2 + assert test_hidden() == 2 + def test_lookup_special(self): from __pypy__ import lookup_special class X(object): From noreply at buildbot.pypy.org Sun Feb 24 20:22:31 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Sun, 24 Feb 2013 20:22:31 +0100 (CET) Subject: [pypy-commit] pypy py3k: fix Message-ID: <20130224192231.363141C0255@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61743:b72e78dce91e Date: 2013-02-24 10:58 -0800 http://bitbucket.org/pypy/pypy/changeset/b72e78dce91e/ Log: fix diff --git a/pypy/interpreter/astcompiler/test/test_astbuilder.py b/pypy/interpreter/astcompiler/test/test_astbuilder.py --- a/pypy/interpreter/astcompiler/test/test_astbuilder.py +++ b/pypy/interpreter/astcompiler/test/test_astbuilder.py @@ -1146,7 +1146,6 @@ assert space.eq_w(s.s, space.wrap(u'Ç')) def test_string_bug(self): - py.test.py3k_skip('fixme') space = self.space source = '# -*- encoding: utf8 -*-\nstuff = "x \xc3\xa9 \\n"\n' info = pyparse.CompileInfo("", "exec") @@ -1154,8 +1153,7 @@ assert info.encoding == "utf8" s = ast_from_node(space, tree, info).body[0].value assert isinstance(s, ast.Str) - expected = ['x', ' ', chr(0xc3), chr(0xa9), ' ', '\n'] - assert space.eq_w(s.s, space.wrap(''.join(expected))) + assert space.eq_w(s.s, space.wrap(u'x \xe9 \n')) def test_number(self): def get_num(s): From noreply at buildbot.pypy.org Sun Feb 24 20:22:32 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Sun, 24 Feb 2013 20:22:32 +0100 (CET) Subject: [pypy-commit] pypy py3k: adapt long suffix tests to py3 Message-ID: <20130224192232.7FEC11C0337@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61744:3ea642ccc985 Date: 2013-02-24 11:21 -0800 http://bitbucket.org/pypy/pypy/changeset/3ea642ccc985/ Log: adapt long suffix tests to py3 diff --git a/pypy/objspace/std/test/test_strutil.py b/pypy/objspace/std/test/test_strutil.py --- a/pypy/objspace/std/test/test_strutil.py +++ b/pypy/objspace/std/test/test_strutil.py @@ -132,14 +132,14 @@ raises(ParseStringError, string_to_int, '-'+s, base) def test_string_to_bigint(self): - assert string_to_bigint('123L').tolong() == 123 - assert string_to_bigint('123L ').tolong() == 123 + assert string_to_bigint('123').tolong() == 123 + assert string_to_bigint('123 ').tolong() == 123 raises(ParseStringError, string_to_bigint, 'L') raises(ParseStringError, string_to_bigint, 'L ') - assert string_to_bigint('123L', 4).tolong() == 27 + assert string_to_bigint('123', 4).tolong() == 27 assert string_to_bigint('123L', 30).tolong() == 27000 + 1800 + 90 + 21 assert string_to_bigint('123L', 22).tolong() == 10648 + 968 + 66 + 21 - assert string_to_bigint('123L', 21).tolong() == 441 + 42 + 3 + assert string_to_bigint('123', 21).tolong() == 441 + 42 + 3 assert string_to_bigint('1891234174197319').tolong() == 1891234174197319 def test_string_to_float(self): From noreply at buildbot.pypy.org Sun Feb 24 22:31:00 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sun, 24 Feb 2013 22:31:00 +0100 (CET) Subject: [pypy-commit] pypy default: update .hgignore for rpython split (patch from justin bogner) Message-ID: <20130224213100.438461C0255@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61745:b0c505757ed6 Date: 2013-02-24 16:29 -0500 http://bitbucket.org/pypy/pypy/changeset/b0c505757ed6/ Log: update .hgignore for rpython split (patch from justin bogner) diff --git a/.hgignore b/.hgignore --- a/.hgignore +++ b/.hgignore @@ -35,39 +35,43 @@ ^pypy/doc/config/.+\.rst$ ^pypy/doc/basicblock\.asc$ ^pypy/doc/.+\.svninfo$ -^pypy/translator/c/src/libffi_msvc/.+\.obj$ -^pypy/translator/c/src/libffi_msvc/.+\.dll$ -^pypy/translator/c/src/libffi_msvc/.+\.lib$ -^pypy/translator/c/src/libffi_msvc/.+\.exp$ -^pypy/translator/c/src/cjkcodecs/.+\.o$ -^pypy/translator/c/src/cjkcodecs/.+\.obj$ -^pypy/translator/jvm/\.project$ -^pypy/translator/jvm/\.classpath$ -^pypy/translator/jvm/eclipse-bin$ -^pypy/translator/jvm/src/pypy/.+\.class$ -^pypy/translator/benchmark/docutils$ -^pypy/translator/benchmark/templess$ -^pypy/translator/benchmark/gadfly$ -^pypy/translator/benchmark/mako$ -^pypy/translator/benchmark/bench-custom\.benchmark_result$ -^pypy/translator/benchmark/shootout_benchmarks$ -^pypy/translator/goal/pypy-translation-snapshot$ -^pypy/translator/goal/pypy-c -^pypy/translator/goal/pypy-jvm -^pypy/translator/goal/pypy-jvm.jar -^pypy/translator/goal/.+\.exe$ -^pypy/translator/goal/.+\.dll$ -^pypy/translator/goal/target.+-c$ +^rpython/translator/c/src/libffi_msvc/.+\.obj$ +^rpython/translator/c/src/libffi_msvc/.+\.dll$ +^rpython/translator/c/src/libffi_msvc/.+\.lib$ +^rpython/translator/c/src/libffi_msvc/.+\.exp$ +^rpython/translator/c/src/cjkcodecs/.+\.o$ +^rpython/translator/c/src/cjkcodecs/.+\.obj$ +^rpython/translator/c/src/stacklet/.+\.o$ +^rpython/translator/c/src/.+\.o$ +^rpython/translator/jvm/\.project$ +^rpython/translator/jvm/\.classpath$ +^rpython/translator/jvm/eclipse-bin$ +^rpython/translator/jvm/src/pypy/.+\.class$ +^rpython/translator/benchmark/docutils$ +^rpython/translator/benchmark/templess$ +^rpython/translator/benchmark/gadfly$ +^rpython/translator/benchmark/mako$ +^rpython/translator/benchmark/bench-custom\.benchmark_result$ +^rpython/translator/benchmark/shootout_benchmarks$ +^rpython/translator/goal/target.+-c$ +^rpython/translator/goal/.+\.exe$ +^rpython/translator/goal/.+\.dll$ +^pypy/goal/pypy-translation-snapshot$ +^pypy/goal/pypy-c +^pypy/goal/pypy-jvm +^pypy/goal/pypy-jvm.jar +^pypy/goal/.+\.exe$ +^pypy/goal/.+\.dll$ ^pypy/_cache$ ^pypy/doc/statistic/.+\.html$ ^pypy/doc/statistic/.+\.eps$ ^pypy/doc/statistic/.+\.pdf$ -^pypy/translator/cli/src/pypylib\.dll$ -^pypy/translator/cli/src/query\.exe$ -^pypy/translator/cli/src/main\.exe$ +^rpython/translator/cli/src/pypylib\.dll$ +^rpython/translator/cli/src/query\.exe$ +^rpython/translator/cli/src/main\.exe$ ^lib_pypy/ctypes_config_cache/_.+_cache\.py$ ^lib_pypy/ctypes_config_cache/_.+_.+_\.py$ -^pypy/translator/cli/query-descriptions$ +^rpython/translator/cli/query-descriptions$ ^pypy/doc/discussion/.+\.html$ ^include/.+\.h$ ^include/.+\.inl$ From noreply at buildbot.pypy.org Sun Feb 24 23:10:11 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Sun, 24 Feb 2013 23:10:11 +0100 (CET) Subject: [pypy-commit] pyrepl default: ensure unix_console.{prepare, restore} maintain state properly for when signal fails (ie in a thread), test Message-ID: <20130224221011.DBA561C008F@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r231:a0a7573023f0 Date: 2013-02-24 17:03 -0500 http://bitbucket.org/pypy/pyrepl/changeset/a0a7573023f0/ Log: ensure unix_console.{prepare,restore} maintain state properly for when signal fails (ie in a thread), test diff --git a/pyrepl/unix_console.py b/pyrepl/unix_console.py --- a/pyrepl/unix_console.py +++ b/pyrepl/unix_console.py @@ -393,6 +393,7 @@ if hasattr(self, 'old_sigwinch'): signal.signal(signal.SIGWINCH, self.old_sigwinch) + del self.old_sigwinch def __sigwinch(self, signum, frame): self.height, self.width = self.getheightwidth() diff --git a/testing/test_bugs.py b/testing/test_bugs.py --- a/testing/test_bugs.py +++ b/testing/test_bugs.py @@ -44,3 +44,29 @@ ('accept', ['']) ] read_spec(spec, HistoricalTestReader) + + +def test_signal_failure(monkeypatch): + import os + import pty + import signal + from pyrepl.unix_console import UnixConsole + + def failing_signal(a, b): + raise ValueError + + def really_failing_signal(a, b): + raise AssertionError + + mfd, sfd = pty.openpty() + try: + c = UnixConsole(sfd, sfd) + c.prepare() + c.restore() + monkeypatch.setattr(signal, 'signal', failing_signal) + c.prepare() + monkeypatch.setattr(signal, 'signal', really_failing_signal) + c.restore() + finally: + os.close(mfd) + os.close(sfd) From noreply at buildbot.pypy.org Sun Feb 24 23:22:12 2013 From: noreply at buildbot.pypy.org (RonnyPfannschmidt) Date: Sun, 24 Feb 2013 23:22:12 +0100 (CET) Subject: [pypy-commit] pyrepl commands-as-functions: merge from default Message-ID: <20130224222212.DE36A1C0337@cobra.cs.uni-duesseldorf.de> Author: Ronny Pfannschmidt Branch: commands-as-functions Changeset: r232:f60cd4b09eb6 Date: 2013-02-24 23:14 +0100 http://bitbucket.org/pypy/pyrepl/changeset/f60cd4b09eb6/ Log: merge from default diff --git a/MANIFEST.in b/MANIFEST.in --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,1 +1,3 @@ include TODO CREDITS CHANGES pythoni encopyright.py LICENSE +include MANIFEST.in +recursive-include testing *.py diff --git a/pyrepl/copy_code.py b/pyrepl/copy_code.py deleted file mode 100644 --- a/pyrepl/copy_code.py +++ /dev/null @@ -1,73 +0,0 @@ -# Copyright 2000-2004 Michael Hudson-Doyle -# -# All Rights Reserved -# -# -# Permission to use, copy, modify, and distribute this software and -# its documentation for any purpose is hereby granted without fee, -# provided that the above copyright notice appear in all copies and -# that both that copyright notice and this permission notice appear in -# supporting documentation. -# -# THE AUTHOR MICHAEL HUDSON DISCLAIMS ALL WARRANTIES WITH REGARD TO -# THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY -# AND FITNESS, IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, -# INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER -# RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF -# CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -from types import CodeType - -def copy_code_with_changes(codeobject, - argcount=None, - nlocals=None, - stacksize=None, - flags=None, - code=None, - consts=None, - names=None, - varnames=None, - filename=None, - name=None, - firstlineno=None, - lnotab=None): - if argcount is None: argcount = codeobject.co_argcount - if nlocals is None: nlocals = codeobject.co_nlocals - if stacksize is None: stacksize = codeobject.co_stacksize - if flags is None: flags = codeobject.co_flags - if code is None: code = codeobject.co_code - if consts is None: consts = codeobject.co_consts - if names is None: names = codeobject.co_names - if varnames is None: varnames = codeobject.co_varnames - if filename is None: filename = codeobject.co_filename - if name is None: name = codeobject.co_name - if firstlineno is None: firstlineno = codeobject.co_firstlineno - if lnotab is None: lnotab = codeobject.co_lnotab - return CodeType(argcount, - nlocals, - stacksize, - flags, - code, - consts, - names, - varnames, - filename, - name, - firstlineno, - lnotab) - -code_attrs=['argcount', - 'nlocals', - 'stacksize', - 'flags', - 'code', - 'consts', - 'names', - 'varnames', - 'filename', - 'name', - 'firstlineno', - 'lnotab'] - - diff --git a/pyrepl/reader.py b/pyrepl/reader.py --- a/pyrepl/reader.py +++ b/pyrepl/reader.py @@ -143,11 +143,11 @@ (r'\M-8', 'digit-arg'), (r'\M-9', 'digit-arg'), #(r'\M-\n', 'insert-nl'), - ('\\\\', 'self-insert')] + \ + ('\\\\', 'self-insert')] + [(c, 'self-insert') - for c in map(chr, range(32, 127)) if c != '\\'] + \ + for c in map(chr, range(32, 127)) if c != '\\'] + [(c, 'self-insert') - for c in map(chr, range(128, 256)) if c.isalpha()] + \ + for c in map(chr, range(128, 256)) if c.isalpha()] + [(r'\', 'up'), (r'\', 'down'), (r'\', 'left'), @@ -244,9 +244,9 @@ self.commands = {} self.msg = '' for v in vars(commands).values(): - if (isinstance(v, type) - and issubclass(v, commands.Command) - and v.__name__[0].islower()): + if (isinstance(v, type) and + issubclass(v, commands.Command) and + v.__name__[0].islower()): self.commands[v.__name__] = v self.commands[v.__name__.replace('_', '-')] = v self.syntax_table = make_default_syntax_table() diff --git a/pyrepl/readline.py b/pyrepl/readline.py --- a/pyrepl/readline.py +++ b/pyrepl/readline.py @@ -26,7 +26,8 @@ extensions for multiline input. """ -import sys, os +import sys +import os from pyrepl import commands from pyrepl.historical_reader import HistoricalReader from pyrepl.completing_reader import CompletingReader @@ -35,41 +36,43 @@ ENCODING = sys.getfilesystemencoding() or 'latin1' # XXX review -__all__ = ['add_history', - 'clear_history', - 'get_begidx', - 'get_completer', - 'get_completer_delims', - 'get_current_history_length', - 'get_endidx', - 'get_history_item', - 'get_history_length', - 'get_line_buffer', - 'insert_text', - 'parse_and_bind', - 'read_history_file', - 'read_init_file', - 'redisplay', - 'remove_history_item', - 'replace_history_item', - 'set_completer', - 'set_completer_delims', - 'set_history_length', - 'set_pre_input_hook', - 'set_startup_hook', - 'write_history_file', - # ---- multiline extensions ---- - 'multiline_input', - ] +__all__ = [ + 'add_history', + 'clear_history', + 'get_begidx', + 'get_completer', + 'get_completer_delims', + 'get_current_history_length', + 'get_endidx', + 'get_history_item', + 'get_history_length', + 'get_line_buffer', + 'insert_text', + 'parse_and_bind', + 'read_history_file', + 'read_init_file', + 'redisplay', + 'remove_history_item', + 'replace_history_item', + 'set_completer', + 'set_completer_delims', + 'set_history_length', + 'set_pre_input_hook', + 'set_startup_hook', + 'write_history_file', + # ---- multiline extensions ---- + 'multiline_input', +] # ____________________________________________________________ + class ReadlineConfig(object): readline_completer = None completer_delims = dict.fromkeys(' \t\n`~!@#$%^&*()-=+[{]}\\|;:\'",<>/?') + class ReadlineAlikeReader(HistoricalReader, CompletingReader): - assume_immutable_completions = False use_brackets = False sort_in_column = True @@ -156,10 +159,11 @@ if self.pos > len(self.buffer): self.pos = len(self.buffer) + class maybe_accept(commands.Command): def do(self): r = self.reader - r.dirty = 1 # this is needed to hide the completion menu, if visible + r.dirty = 1 # this is needed to hide the completion menu, if visible # # if there are already several lines and the cursor # is not on the last one, always insert a new \n. @@ -171,7 +175,6 @@ else: self.finish = 1 -# ____________________________________________________________ class _ReadlineWrapper(object): reader = None @@ -179,9 +182,9 @@ startup_hook = None config = ReadlineConfig() - def __init__(self): - self.f_in = os.dup(0) - self.f_out = os.dup(1) + def __init__(self, f_in=None, f_out=None): + self.f_in = f_in if f_in is not None else os.dup(0) + self.f_out = f_out if f_out is not None else os.dup(1) def get_reader(self): if self.reader is None: @@ -369,6 +372,7 @@ # ____________________________________________________________ # Stubs + def _make_stub(_name, _ret): def stub(*args, **kwds): import warnings @@ -380,16 +384,16 @@ ('read_init_file', None), ('redisplay', None), ('set_pre_input_hook', None), - ]: +]: assert _name not in globals(), _name _make_stub(_name, _ret) -# ____________________________________________________________ def _setup(): global _old_raw_input if _old_raw_input is not None: - return # don't run _setup twice + return + # don't run _setup twice try: f_in = sys.stdin.fileno() diff --git a/pyrepl/simple_interact.py b/pyrepl/simple_interact.py --- a/pyrepl/simple_interact.py +++ b/pyrepl/simple_interact.py @@ -26,6 +26,7 @@ import sys from pyrepl.readline import multiline_input, _error, _get_reader + def check(): # returns False if there is a problem initializing the state try: _get_reader() @@ -33,6 +34,7 @@ return False return True + def run_multiline_interactive_console(mainmodule=None): import code import __main__ diff --git a/pyrepl/unix_console.py b/pyrepl/unix_console.py --- a/pyrepl/unix_console.py +++ b/pyrepl/unix_console.py @@ -19,8 +19,15 @@ # CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -import termios, select, os, struct, errno -import signal, re, time, sys +import termios +import select +import os +import struct +import errno +import signal +import re +import time +import sys from fcntl import ioctl from . import curses from .fancy_termios import tcgetattr, tcsetattr @@ -28,6 +35,7 @@ from .unix_eventqueue import EventQueue from .trace import trace + class InvalidTerminal(RuntimeError): pass @@ -44,16 +52,18 @@ FIONREAD = getattr(termios, "FIONREAD", None) TIOCGWINSZ = getattr(termios, "TIOCGWINSZ", None) + def _my_getstr(cap, optional=0): r = curses.tigetstr(cap) if not optional and r is None: raise InvalidTerminal( - "terminal doesn't have the required '%s' capability"%cap) + "terminal doesn't have the required '%s' capability" % cap) return r + # at this point, can we say: AAAAAAAAAAAAAAAAAAAAAARGH! def maybe_add_baudrate(dict, rate): - name = 'B%d'%rate + name = 'B%d' % rate if hasattr(termios, name): dict[getattr(termios, name)] = rate @@ -74,19 +84,28 @@ class poll: def __init__(self): pass + def register(self, fd, flag): self.fd = fd + def poll(self, timeout=None): - r,w,e = select.select([self.fd],[],[],timeout) + r, w, e = select.select([self.fd], [], [], timeout) return r POLLIN = getattr(select, "POLLIN", None) + +required_curses_tistrings = 'bel clear cup el' +optional_curses_tistrings = ( + 'civis cnorm cub cub1 cud cud1 cud cud1 cuf ' + 'cuf1 cuu cuu1 dch dch1 hpa ich ich1 ind pad ri rmkx smkx') + + class UnixConsole(Console): def __init__(self, f_in=0, f_out=1, term=None, encoding=None): if encoding is None: encoding = sys.getdefaultencoding() - + self.encoding = encoding if isinstance(f_in, int): @@ -98,40 +117,21 @@ self.output_fd = f_out else: self.output_fd = f_out.fileno() - self.pollob = poll() self.pollob.register(self.input_fd, POLLIN) curses.setupterm(term, self.output_fd) self.term = term - - self._bel = _my_getstr("bel") - self._civis = _my_getstr("civis", optional=1) - self._clear = _my_getstr("clear") - self._cnorm = _my_getstr("cnorm", optional=1) - self._cub = _my_getstr("cub", optional=1) - self._cub1 = _my_getstr("cub1", 1) - self._cud = _my_getstr("cud", 1) - self._cud1 = _my_getstr("cud1", 1) - self._cuf = _my_getstr("cuf", 1) - self._cuf1 = _my_getstr("cuf1", 1) - self._cup = _my_getstr("cup") - self._cuu = _my_getstr("cuu", 1) - self._cuu1 = _my_getstr("cuu1", 1) - self._dch1 = _my_getstr("dch1", 1) - self._dch = _my_getstr("dch", 1) - self._el = _my_getstr("el") - self._hpa = _my_getstr("hpa", 1) - self._ich = _my_getstr("ich", 1) - self._ich1 = _my_getstr("ich1", 1) - self._ind = _my_getstr("ind", 1) - self._pad = _my_getstr("pad", 1) - self._ri = _my_getstr("ri", 1) - self._rmkx = _my_getstr("rmkx", 1) - self._smkx = _my_getstr("smkx", 1) - + + for name in required_curses_tistrings.split(): + setattr(self, '_' + name, _my_getstr(name)) + + for name in optional_curses_tistrings.split(): + setattr(self, '_' + name, _my_getstr(name, optional=1)) + ## work out how we're going to sling the cursor around - if 0 and self._hpa: # hpa don't work in windows telnet :-( + # hpa don't work in windows telnet :-( + if 0 and self._hpa: self.__move_x = self.__move_x_hpa elif self._cub and self._cuf: self.__move_x = self.__move_x_cub_cuf @@ -166,9 +166,6 @@ self.event_queue = EventQueue(self.input_fd, self.encoding) self.cursor_visible = 1 - def change_encoding(self, encoding): - self.encoding = encoding - def refresh(self, screen, c_xy): # this function is still too long (over 90 lines) cx, cy = c_xy @@ -181,7 +178,7 @@ self.screen.append("") else: while len(self.screen) < len(screen): - self.screen.append("") + self.screen.append("") if len(screen) > self.height: self.__gone_tall = 1 @@ -191,7 +188,6 @@ old_offset = offset = self.__offset height = self.height - # we make sure the cursor is on the screen, and that we're # using all of the screen if we can if cy < offset: @@ -230,7 +226,7 @@ newscr): if oldline != newline: self.__write_changed_line(y, oldline, newline, px) - + y = len(newscr) while y < len(oldscr): self.__hide_cursor() @@ -240,7 +236,7 @@ y += 1 self.__show_cursor() - + self.screen = screen self.move_cursor(cx, cy) self.flushoutput() @@ -256,11 +252,12 @@ # reuse the oldline as much as possible, but stop as soon as we # encounter an ESCAPE, because it might be the start of an escape # sequene + #XXX unicode check! while x < minlen and oldline[x] == newline[x] and newline[x] != '\x1b': x += 1 if oldline[x:] == newline[x+1:] and self.ich1: - if ( y == self.__posxy[1] and x > self.__posxy[0] - and oldline[px:x] == newline[px+1:x+1] ): + if (y == self.__posxy[1] and x > self.__posxy[0] and + oldline[px:x] == newline[px+1:x+1]): x = px self.__move(x, y) self.__write_code(self.ich1) @@ -288,7 +285,8 @@ self.__write_code(self._el) self.__write(newline[x:]) self.__posxy = len(newline), y - + + #XXX: check for unicode mess if '\x1b' in newline: # ANSI escape characters are present, so we can't assume # anything about the position of the cursor. Moving the cursor @@ -359,13 +357,13 @@ self.__svtermstate = tcgetattr(self.input_fd) raw = self.__svtermstate.copy() raw.iflag |= termios.ICRNL - raw.iflag &=~ (termios.BRKINT | termios.INPCK | + raw.iflag &= ~(termios.BRKINT | termios.INPCK | termios.ISTRIP | termios.IXON) - raw.oflag &=~ (termios.OPOST) - raw.cflag &=~ (termios.CSIZE|termios.PARENB) - raw.cflag |= (termios.CS8) - raw.lflag &=~ (termios.ICANON|termios.ECHO| - termios.IEXTEN|(termios.ISIG*1)) + raw.oflag &= ~termios.OPOST + raw.cflag &= ~(termios.CSIZE | termios.PARENB) + raw.cflag |= (termios.CS8) + raw.lflag &= ~(termios.ICANON | termios.ECHO | + termios.IEXTEN | (termios.ISIG * 1)) raw.cc[termios.VMIN] = 1 raw.cc[termios.VTIME] = 0 tcsetattr(self.input_fd, termios.TCSADRAIN, raw) @@ -374,7 +372,7 @@ self.height, self.width = self.getheightwidth() self.__buffer = [] - + self.__posxy = 0, 0 self.__gone_tall = 0 self.__move = self.__move_short @@ -395,6 +393,7 @@ if hasattr(self, 'old_sigwinch'): signal.signal(signal.SIGWINCH, self.old_sigwinch) + del self.old_sigwinch def __sigwinch(self, signum, frame): self.height, self.width = self.getheightwidth() @@ -403,10 +402,11 @@ def push_char(self, char): trace('push char {char!r}', char=char) self.event_queue.push(char) - + def get_event(self, block=1): while self.event_queue.empty(): - while 1: # All hail Unix! + while 1: + # All hail Unix! try: self.push_char(os.read(self.input_fd, 1)) except (IOError, OSError) as err: @@ -461,7 +461,8 @@ except KeyError: height, width = struct.unpack( "hhhh", ioctl(self.input_fd, TIOCGWINSZ, "\000"*8))[0:2] - if not height: return 25, 80 + if not height: + return 25, 80 return height, width else: def getheightwidth(self): @@ -528,10 +529,12 @@ e2 = self.event_queue.get() e.data += e2.data e.raw += e.raw - + amount = struct.unpack( "i", ioctl(self.input_fd, FIONREAD, "\0\0\0\0"))[0] - raw = unicode(os.read(self.input_fd, amount), self.encoding, 'replace') + data = os.read(self.input_fd, amount) + raw = unicode(data, self.encoding, 'replace') + #XXX: something is wrong here e.data += raw e.raw += raw return e @@ -543,9 +546,11 @@ e2 = self.event_queue.get() e.data += e2.data e.raw += e.raw - + amount = 10000 - raw = unicode(os.read(self.input_fd, amount), self.encoding, 'replace') + data = os.read(self.input_fd, amount) + raw = unicode(data, self.encoding, 'replace') + #XXX: something is wrong here e.data += raw e.raw += raw return e @@ -556,4 +561,3 @@ self.__move = self.__move_tall self.__posxy = 0, 0 self.screen = [] - diff --git a/pyrepl/unix_eventqueue.py b/pyrepl/unix_eventqueue.py --- a/pyrepl/unix_eventqueue.py +++ b/pyrepl/unix_eventqueue.py @@ -100,7 +100,7 @@ self.events.append(event) def push(self, char): - self.buf.append(char) + self.buf.append(ord(char)) if char in self.k: if self.k is self.ck: #sanity check, buffer is empty when a special key comes diff --git a/testing/infrastructure.py b/testing/infrastructure.py --- a/testing/infrastructure.py +++ b/testing/infrastructure.py @@ -21,11 +21,15 @@ from pyrepl.reader import Reader from pyrepl.console import Console, Event + class EqualsAnything(object): def __eq__(self, other): return True + + EA = EqualsAnything() + class TestConsole(Console): height = 24 width = 80 @@ -38,7 +42,7 @@ def refresh(self, screen, xy): if self.next_screen is not None: - assert screen == self.next_screen, "[ %s != %s after %r ]"%( + assert screen == self.next_screen, "[ %s != %s after %r ]" % ( screen, self.next_screen, self.last_event_name) def get_event(self, block=1): @@ -51,18 +55,19 @@ print("event", ev) return Event(*ev) + class TestReader(Reader): def get_prompt(self, lineno, cursor_on_line): return '' - + def refresh(self): Reader.refresh(self) self.dirty = True + def read_spec(test_spec, reader_class=TestReader): # remember to finish your test_spec with 'accept' or similar! con = TestConsole(test_spec, verbose=True) reader = reader_class(con) reader.readline() - diff --git a/testing/test_basic.py b/testing/test_basic.py --- a/testing/test_basic.py +++ b/testing/test_basic.py @@ -24,41 +24,48 @@ read_spec([(('self-insert', 'a'), ['a']), ( 'accept', ['a'])]) + def test_repeat(): read_spec([(('digit-arg', '3'), ['']), (('self-insert', 'a'), ['aaa']), ( 'accept', ['aaa'])]) + def test_kill_line(): read_spec([(('self-insert', 'abc'), ['abc']), ( 'left', None), ( 'kill-line', ['ab']), ( 'accept', ['ab'])]) + def test_unix_line_discard(): read_spec([(('self-insert', 'abc'), ['abc']), ( 'left', None), ( 'unix-word-rubout', ['c']), ( 'accept', ['c'])]) + def test_kill_word(): read_spec([(('self-insert', 'ab cd'), ['ab cd']), ( 'beginning-of-line', ['ab cd']), ( 'kill-word', [' cd']), ( 'accept', [' cd'])]) + def test_backward_kill_word(): read_spec([(('self-insert', 'ab cd'), ['ab cd']), ( 'backward-kill-word', ['ab ']), ( 'accept', ['ab '])]) + def test_yank(): read_spec([(('self-insert', 'ab cd'), ['ab cd']), ( 'backward-kill-word', ['ab ']), ( 'beginning-of-line', ['ab ']), ( 'yank', ['cdab ']), ( 'accept', ['cdab '])]) - + + def test_yank_pop(): read_spec([(('self-insert', 'ab cd'), ['ab cd']), ( 'backward-kill-word', ['ab ']), @@ -68,18 +75,20 @@ ( 'yank-pop', ['cd ']), ( 'accept', ['cd '])]) + def test_interrupt(): with pytest.raises(KeyboardInterrupt): - read_spec([( 'interrupt', [''])]) + read_spec([('interrupt', [''])]) + # test_suspend -- hah - def test_up(): read_spec([(('self-insert', 'ab\ncd'), ['ab', 'cd']), ( 'up', ['ab', 'cd']), (('self-insert', 'e'), ['abe', 'cd']), ( 'accept', ['abe', 'cd'])]) + def test_down(): read_spec([(('self-insert', 'ab\ncd'), ['ab', 'cd']), ( 'up', ['ab', 'cd']), @@ -88,12 +97,14 @@ (('self-insert', 'f'), ['abe', 'cdf']), ( 'accept', ['abe', 'cdf'])]) + def test_left(): read_spec([(('self-insert', 'ab'), ['ab']), ( 'left', ['ab']), (('self-insert', 'c'), ['acb']), ( 'accept', ['acb'])]) + def test_right(): read_spec([(('self-insert', 'ab'), ['ab']), ( 'left', ['ab']), @@ -101,4 +112,3 @@ ( 'right', ['acb']), (('self-insert', 'd'), ['acbd']), ( 'accept', ['acbd'])]) - diff --git a/testing/test_bugs.py b/testing/test_bugs.py --- a/testing/test_bugs.py +++ b/testing/test_bugs.py @@ -25,13 +25,17 @@ import pytest + class HistoricalTestReader(HistoricalReader, TestReader): pass + @pytest.mark.xfail(reason='event missing', run=False) def test_transpose_at_start(): - read_spec([( 'transpose', [EA, '']), - ( 'accept', [''])]) + read_spec([ + ('transpose', [EA, '']), + ('accept', [''])]) + def test_cmd_instantiation_crash(): spec = [ @@ -40,3 +44,29 @@ ('accept', ['']) ] read_spec(spec, HistoricalTestReader) + + +def test_signal_failure(monkeypatch): + import os + import pty + import signal + from pyrepl.unix_console import UnixConsole + + def failing_signal(a, b): + raise ValueError + + def really_failing_signal(a, b): + raise AssertionError + + mfd, sfd = pty.openpty() + try: + c = UnixConsole(sfd, sfd) + c.prepare() + c.restore() + monkeypatch.setattr(signal, 'signal', failing_signal) + c.prepare() + monkeypatch.setattr(signal, 'signal', really_failing_signal) + c.restore() + finally: + os.close(mfd) + os.close(sfd) diff --git a/testing/test_functional.py b/testing/test_functional.py --- a/testing/test_functional.py +++ b/testing/test_functional.py @@ -6,6 +6,7 @@ import pytest import sys + def pytest_funcarg__child(request): try: pexpect = pytest.importorskip('pexpect') @@ -17,8 +18,8 @@ child.sendline('main()') return child + def test_basic(child): child.sendline('a = 3') child.sendline('a') child.expect('3') - diff --git a/testing/test_keymap.py b/testing/test_keymap.py --- a/testing/test_keymap.py +++ b/testing/test_keymap.py @@ -1,4 +1,3 @@ -import pytest from pyrepl.keymap import compile_keymap diff --git a/testing/test_readline.py b/testing/test_readline.py --- a/testing/test_readline.py +++ b/testing/test_readline.py @@ -1,13 +1,15 @@ from pyrepl.readline import _ReadlineWrapper -import os, pty +import os +import pty + def test_raw_input(): - readline_wrapper = _ReadlineWrapper() master, slave = pty.openpty() - readline_wrapper.f_in = slave - os.write(master, 'input\n') - result = readline_wrapper.raw_input('prompt:') + readline_wrapper = _ReadlineWrapper(slave, slave) + os.write(master, b'input\n') + + result = readline_wrapper.get_reader().readline() + #result = readline_wrapper.raw_input('prompt:') assert result == 'input' # A bytes string on python2, a unicode string on python3. assert isinstance(result, str) - diff --git a/testing/test_unix_reader.py b/testing/test_unix_reader.py --- a/testing/test_unix_reader.py +++ b/testing/test_unix_reader.py @@ -1,6 +1,7 @@ from __future__ import unicode_literals from pyrepl.unix_eventqueue import EncodedQueue + def test_simple(): q = EncodedQueue({}, 'utf-8') @@ -13,4 +14,3 @@ assert q.get() is None assert event.data == a assert event.raw == b - From noreply at buildbot.pypy.org Sun Feb 24 23:22:13 2013 From: noreply at buildbot.pypy.org (RonnyPfannschmidt) Date: Sun, 24 Feb 2013 23:22:13 +0100 (CET) Subject: [pypy-commit] pyrepl codecheck-clean: merge from default Message-ID: <20130224222213.EDD831C0337@cobra.cs.uni-duesseldorf.de> Author: Ronny Pfannschmidt Branch: codecheck-clean Changeset: r233:8733583f714d Date: 2013-02-24 23:20 +0100 http://bitbucket.org/pypy/pyrepl/changeset/8733583f714d/ Log: merge from default diff --git a/MANIFEST.in b/MANIFEST.in --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,1 +1,3 @@ include TODO CREDITS CHANGES pythoni encopyright.py LICENSE +include MANIFEST.in +recursive-include testing *.py diff --git a/pyrepl/readline.py b/pyrepl/readline.py --- a/pyrepl/readline.py +++ b/pyrepl/readline.py @@ -182,9 +182,9 @@ startup_hook = None config = ReadlineConfig() - def __init__(self): - self.f_in = os.dup(0) - self.f_out = os.dup(1) + def __init__(self, f_in=None, f_out=None): + self.f_in = f_in if f_in is not None else os.dup(0) + self.f_out = f_out if f_out is not None else os.dup(1) def get_reader(self): if self.reader is None: diff --git a/pyrepl/unix_console.py b/pyrepl/unix_console.py --- a/pyrepl/unix_console.py +++ b/pyrepl/unix_console.py @@ -393,6 +393,7 @@ if hasattr(self, 'old_sigwinch'): signal.signal(signal.SIGWINCH, self.old_sigwinch) + del self.old_sigwinch def __sigwinch(self, signum, frame): self.height, self.width = self.getheightwidth() diff --git a/testing/test_bugs.py b/testing/test_bugs.py --- a/testing/test_bugs.py +++ b/testing/test_bugs.py @@ -44,3 +44,29 @@ ('accept', ['']) ] read_spec(spec, HistoricalTestReader) + + +def test_signal_failure(monkeypatch): + import os + import pty + import signal + from pyrepl.unix_console import UnixConsole + + def failing_signal(a, b): + raise ValueError + + def really_failing_signal(a, b): + raise AssertionError + + mfd, sfd = pty.openpty() + try: + c = UnixConsole(sfd, sfd) + c.prepare() + c.restore() + monkeypatch.setattr(signal, 'signal', failing_signal) + c.prepare() + monkeypatch.setattr(signal, 'signal', really_failing_signal) + c.restore() + finally: + os.close(mfd) + os.close(sfd) diff --git a/testing/test_readline.py b/testing/test_readline.py --- a/testing/test_readline.py +++ b/testing/test_readline.py @@ -4,11 +4,12 @@ def test_raw_input(): - readline_wrapper = _ReadlineWrapper() master, slave = pty.openpty() - readline_wrapper.f_in = slave + readline_wrapper = _ReadlineWrapper(slave, slave) os.write(master, b'input\n') - result = readline_wrapper.raw_input('prompt:') + + result = readline_wrapper.get_reader().readline() + #result = readline_wrapper.raw_input('prompt:') assert result == 'input' # A bytes string on python2, a unicode string on python3. assert isinstance(result, str) From noreply at buildbot.pypy.org Sun Feb 24 23:48:48 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Sun, 24 Feb 2013 23:48:48 +0100 (CET) Subject: [pypy-commit] pypy py3k: workaround cpython implementation details and differing error messages (for now) Message-ID: <20130224224848.D07AD1C008F@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61746:8ca54fddd153 Date: 2013-02-24 14:47 -0800 http://bitbucket.org/pypy/pypy/changeset/8ca54fddd153/ Log: workaround cpython implementation details and differing error messages (for now) diff --git a/lib-python/3.2/inspect.py b/lib-python/3.2/inspect.py --- a/lib-python/3.2/inspect.py +++ b/lib-python/3.2/inspect.py @@ -1117,17 +1117,23 @@ return False return True +_dict_attr = type.__dict__["__dict__"] +if hasattr(_dict_attr, "__objclass__"): + _objclass_check = lambda d, entry: d.__objclass__ is entry +else: + # PyPy __dict__ descriptors are 'generic' and lack __objclass__ + _objclass_check = lambda d, entry: not hasattr(d, "__objclass__") + def _shadowed_dict(klass): - dict_attr = type.__dict__["__dict__"] for entry in _static_getmro(klass): try: - class_dict = dict_attr.__get__(entry)["__dict__"] + class_dict = _dict_attr.__get__(entry)["__dict__"] except KeyError: pass else: if not (type(class_dict) is types.GetSetDescriptorType and class_dict.__name__ == "__dict__" and - class_dict.__objclass__ is entry): + _objclass_check(class_dict, entry)): return class_dict return _sentinel diff --git a/lib-python/3.2/test/test_inspect.py b/lib-python/3.2/test/test_inspect.py --- a/lib-python/3.2/test/test_inspect.py +++ b/lib-python/3.2/test/test_inspect.py @@ -631,7 +631,14 @@ class Empty(object): pass def wrapped(x): - if '__name__' in dir(x) and hasattr(Empty, x.__name__): + xname = None + if '__name__' in dir(x): + xname = x.__name__ + elif isinstance(x, (classmethod, staticmethod)): + # Some of PyPy's standard descriptors are + # class/staticmethods + xname = x.__func__.__name__ + if xname is not None and hasattr(Empty, xname): return False return pred(x) return wrapped @@ -689,7 +696,15 @@ else: self.fail('Exception not raised') self.assertIs(type(ex1), type(ex2)) - self.assertEqual(str(ex1), str(ex2)) + try: + self.assertEqual(str(ex1), str(ex2)) + except AssertionError: + # XXX: PyPy 3.2 produces slightly different error messages, + # to be fixed in 3.3 + assert (str(ex1).startswith('() takes ') and + 'non-keyword' in str(ex1) or + any(name in str(ex2) + for name in ('positional', 'keyword-only'))) del ex1, ex2 def makeCallable(self, signature): From noreply at buildbot.pypy.org Mon Feb 25 00:10:19 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Mon, 25 Feb 2013 00:10:19 +0100 (CET) Subject: [pypy-commit] pypy py3k: re-add sysconfig._parse_makefile (it doesn't hurt), skip features PyPy doesn't support Message-ID: <20130224231019.2CB301C0327@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61747:4567f0b2bd84 Date: 2013-02-24 15:09 -0800 http://bitbucket.org/pypy/pypy/changeset/4567f0b2bd84/ Log: re-add sysconfig._parse_makefile (it doesn't hurt), skip features PyPy doesn't support diff --git a/lib-python/3.2/sysconfig.py b/lib-python/3.2/sysconfig.py --- a/lib-python/3.2/sysconfig.py +++ b/lib-python/3.2/sysconfig.py @@ -209,6 +209,125 @@ return env_base if env_base else joinuser("~", ".local") +def _parse_makefile(filename, vars=None): + """Parse a Makefile-style file. + + A dictionary containing name/value pairs is returned. If an + optional dictionary is passed in as the second argument, it is + used instead of a new dictionary. + """ + import re + # Regexes needed for parsing Makefile (and similar syntaxes, + # like old-style Setup files). + _variable_rx = re.compile("([a-zA-Z][a-zA-Z0-9_]+)\s*=\s*(.*)") + _findvar1_rx = re.compile(r"\$\(([A-Za-z][A-Za-z0-9_]*)\)") + _findvar2_rx = re.compile(r"\${([A-Za-z][A-Za-z0-9_]*)}") + + if vars is None: + vars = {} + done = {} + notdone = {} + + with open(filename, errors="surrogateescape") as f: + lines = f.readlines() + + for line in lines: + if line.startswith('#') or line.strip() == '': + continue + m = _variable_rx.match(line) + if m: + n, v = m.group(1, 2) + v = v.strip() + # `$$' is a literal `$' in make + tmpv = v.replace('$$', '') + + if "$" in tmpv: + notdone[n] = v + else: + try: + v = int(v) + except ValueError: + # insert literal `$' + done[n] = v.replace('$$', '$') + else: + done[n] = v + + # do variable interpolation here + variables = list(notdone.keys()) + + # Variables with a 'PY_' prefix in the makefile. These need to + # be made available without that prefix through sysconfig. + # Special care is needed to ensure that variable expansion works, even + # if the expansion uses the name without a prefix. + renamed_variables = ('CFLAGS', 'LDFLAGS', 'CPPFLAGS') + + while len(variables) > 0: + for name in tuple(variables): + value = notdone[name] + m = _findvar1_rx.search(value) or _findvar2_rx.search(value) + if m is not None: + n = m.group(1) + found = True + if n in done: + item = str(done[n]) + elif n in notdone: + # get it on a subsequent round + found = False + elif n in os.environ: + # do it like make: fall back to environment + item = os.environ[n] + + elif n in renamed_variables: + if name.startswith('PY_') and name[3:] in renamed_variables: + item = "" + + elif 'PY_' + n in notdone: + found = False + + else: + item = str(done['PY_' + n]) + + else: + done[n] = item = "" + + if found: + after = value[m.end():] + value = value[:m.start()] + item + after + if "$" in after: + notdone[name] = value + else: + try: + value = int(value) + except ValueError: + done[name] = value.strip() + else: + done[name] = value + variables.remove(name) + + if name.startswith('PY_') \ + and name[3:] in renamed_variables: + + name = name[3:] + if name not in done: + done[name] = value + + + else: + # bogus variable reference (e.g. "prefix=$/opt/python"); + # just drop it since we can't deal + done[name] = value + variables.remove(name) + + # strip spurious spaces + for k, v in done.items(): + if isinstance(v, str): + done[k] = v.strip() + + # save the results in the global dictionary + vars.update(done) + return vars + + def _init_posix(vars): """Initialize the module as appropriate for POSIX systems.""" return diff --git a/lib-python/3.2/test/test_sysconfig.py b/lib-python/3.2/test/test_sysconfig.py --- a/lib-python/3.2/test/test_sysconfig.py +++ b/lib-python/3.2/test/test_sysconfig.py @@ -12,7 +12,8 @@ from copy import copy, deepcopy from test.support import (run_unittest, TESTFN, unlink, get_attribute, - captured_stdout, skip_unless_symlink) + captured_stdout, skip_unless_symlink, + impl_detail) import sysconfig from sysconfig import (get_paths, get_platform, get_config_vars, @@ -277,6 +278,7 @@ self.assertTrue(len(output.getvalue().split('\n')) > 0) @unittest.skipIf(sys.platform == "win32", "Does not apply to Windows") + @impl_detail("PyPy lacks LDFLAGS/LDSHARED config vars", pypy=False) def test_ldshared_value(self): ldflags = sysconfig.get_config_var('LDFLAGS') ldshared = sysconfig.get_config_var('LDSHARED') @@ -333,6 +335,7 @@ class MakefileTests(unittest.TestCase): @unittest.skipIf(sys.platform.startswith('win'), 'Test is not Windows compatible') + @impl_detail("PyPy lacks sysconfig.get_makefile_filename", pypy=False) def test_get_makefile_filename(self): makefile = sysconfig.get_makefile_filename() self.assertTrue(os.path.isfile(makefile), makefile) From noreply at buildbot.pypy.org Mon Feb 25 01:44:41 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Mon, 25 Feb 2013 01:44:41 +0100 (CET) Subject: [pypy-commit] pypy default: missing import Message-ID: <20130225004441.D900B1C0255@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61748:816b34ae6540 Date: 2013-02-24 19:44 -0500 http://bitbucket.org/pypy/pypy/changeset/816b34ae6540/ Log: missing import diff --git a/rpython/jit/metainterp/test/test_resume.py b/rpython/jit/metainterp/test/test_resume.py --- a/rpython/jit/metainterp/test/test_resume.py +++ b/rpython/jit/metainterp/test/test_resume.py @@ -1,5 +1,6 @@ from __future__ import with_statement import py +import sys from rpython.rtyper.lltypesystem import lltype, llmemory, rffi from rpython.jit.metainterp.optimizeopt.optimizer import OptValue from rpython.jit.metainterp.optimizeopt.virtualize import VirtualValue, VArrayValue From noreply at buildbot.pypy.org Mon Feb 25 07:07:37 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Mon, 25 Feb 2013 07:07:37 +0100 (CET) Subject: [pypy-commit] pypy default: move some numpypy constants to the umath module Message-ID: <20130225060737.8F70B1C026A@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61749:7551c6b88bb8 Date: 2013-02-25 00:52 -0500 http://bitbucket.org/pypy/pypy/changeset/7551c6b88bb8/ Log: move some numpypy constants to the umath module diff --git a/lib_pypy/numpypy/core/__init__.py b/lib_pypy/numpypy/core/__init__.py --- a/lib_pypy/numpypy/core/__init__.py +++ b/lib_pypy/numpypy/core/__init__.py @@ -6,7 +6,6 @@ from fromnumeric import * import shape_base from shape_base import * -import multiarray from fromnumeric import amax as max, amin as min from _numpypy import absolute as abs diff --git a/lib_pypy/numpypy/core/numeric.py b/lib_pypy/numpypy/core/numeric.py --- a/lib_pypy/numpypy/core/numeric.py +++ b/lib_pypy/numpypy/core/numeric.py @@ -1,15 +1,33 @@ -__all__ = ['asanyarray', 'base_repr', +__all__ = [ + 'asanyarray', 'base_repr', 'array_repr', 'array_str', 'set_string_function', - 'array_equal', 'asarray', 'outer', 'identity'] + 'array_equal', 'asarray', 'outer', 'identity', 'little_endian', + 'Inf', 'inf', 'infty', 'Infinity', 'nan', 'NaN', 'False_', 'True_', + ] from _numpypy import array, ndarray, int_, float_, bool_, flexible #, complex_# , longlong from _numpypy import concatenate from .fromnumeric import any -import math import sys import multiarray +import umath +from umath import * from numpypy.core.arrayprint import array2string +def extend_all(module): + adict = {} + for a in __all__: + adict[a] = 1 + try: + mall = getattr(module, '__all__') + except AttributeError: + mall = [k for k in module.__dict__.keys() if not k.startswith('_')] + for a in mall: + if a not in adict: + __all__.append(a) + +extend_all(umath) + newaxis = None # XXX this file to be reviewed @@ -422,15 +440,10 @@ little_endian = (sys.byteorder == 'little') -Inf = inf = infty = Infinity = PINF = float('inf') -NINF = float('-inf') -PZERO = 0.0 -NZERO = -0.0 -nan = NaN = NAN = float('nan') +Inf = inf = infty = Infinity = PINF +nan = NaN = NAN False_ = bool_(False) True_ = bool_(True) -e = math.e -pi = math.pi def outer(a,b): """ diff --git a/lib_pypy/numpypy/core/umath.py b/lib_pypy/numpypy/core/umath.py new file mode 100644 --- /dev/null +++ b/lib_pypy/numpypy/core/umath.py @@ -0,0 +1,10 @@ +import math +e = math.e +pi = math.pi +del math + +PZERO = 0.0 +NZERO = -0.0 +PINF = float('inf') +NINF = float('-inf') +NAN = float('nan') diff --git a/pypy/module/micronumpy/__init__.py b/pypy/module/micronumpy/__init__.py --- a/pypy/module/micronumpy/__init__.py +++ b/pypy/module/micronumpy/__init__.py @@ -23,10 +23,6 @@ 'count_nonzero': 'interp_arrayops.count_nonzero', 'set_string_function': 'appbridge.set_string_function', - - 'True_': 'types.Bool.True', - 'False_': 'types.Bool.False', - 'typeinfo': 'interp_dtype.get_dtype_cache(space).w_typeinfo', 'generic': 'interp_boxes.W_GenericBox', diff --git a/pypy/module/micronumpy/test/test_dtypes.py b/pypy/module/micronumpy/test/test_dtypes.py --- a/pypy/module/micronumpy/test/test_dtypes.py +++ b/pypy/module/micronumpy/test/test_dtypes.py @@ -80,7 +80,8 @@ assert str(d) == "bool" def test_bool_array(self): - from _numpypy import array, False_, True_ + from _numpypy import array + from numpypy import False_, True_ a = array([0, 1, 2, 2.5], dtype='?') assert a[0] is False_ @@ -88,7 +89,8 @@ assert a[i] is True_ def test_copy_array_with_dtype(self): - from _numpypy import array, False_, longlong + from _numpypy import array, longlong + from numpypy import False_ a = array([0, 1, 2, 3], dtype=long) # int on 64-bit, long in 32-bit @@ -102,14 +104,16 @@ assert b[0] is False_ def test_zeros_bool(self): - from _numpypy import zeros, False_ + from _numpypy import zeros + from numpypy import False_ a = zeros(10, dtype=bool) for i in range(10): assert a[i] is False_ def test_ones_bool(self): - from _numpypy import ones, True_ + from _numpypy import ones + from numpypy import True_ a = ones(10, dtype=bool) for i in range(10): @@ -317,7 +321,7 @@ assert int_(4) ** 2 == 16 def test_bool(self): - import _numpypy as numpy + import numpypy as numpy assert numpy.bool_.mro() == [numpy.bool_, numpy.generic, object] assert numpy.bool_(3) is numpy.True_ @@ -634,7 +638,8 @@ def test_operators(self): from operator import truediv - from _numpypy import float64, int_, True_, False_ + from _numpypy import float64, int_ + from numpypy import True_, False_ assert 5 / int_(2) == int_(2) assert truediv(int_(3), int_(2)) == float64(1.5) assert truediv(3, int_(2)) == float64(1.5) diff --git a/pypy/module/micronumpy/test/test_numarray.py b/pypy/module/micronumpy/test/test_numarray.py --- a/pypy/module/micronumpy/test/test_numarray.py +++ b/pypy/module/micronumpy/test/test_numarray.py @@ -780,6 +780,7 @@ def test_mul(self): import _numpypy + from numpypy import False_, True_ a = _numpypy.array(range(5)) b = a * a @@ -790,9 +791,9 @@ a = _numpypy.array(range(5), dtype=bool) b = a * a assert b.dtype is _numpypy.dtype(bool) - assert b[0] is _numpypy.False_ + assert b[0] is False_ for i in range(1, 5): - assert b[i] is _numpypy.True_ + assert b[i] is True_ def test_mul_constant(self): from _numpypy import array diff --git a/pypy/module/test_lib_pypy/numpypy/test_numpy.py b/pypy/module/test_lib_pypy/numpypy/test_numpy.py --- a/pypy/module/test_lib_pypy/numpypy/test_numpy.py +++ b/pypy/module/test_lib_pypy/numpypy/test_numpy.py @@ -53,3 +53,9 @@ import numpypy assert numpypy.set_string_function is not \ numpypy.core.multiarray.set_string_function + + def test_constants(self): + import numpypy + assert numpypy.PZERO == numpypy.NZERO == 0.0 + assert numpypy.inf is float('inf') + assert numpypy.nan is float('nan') From noreply at buildbot.pypy.org Mon Feb 25 09:20:18 2013 From: noreply at buildbot.pypy.org (RonnyPfannschmidt) Date: Mon, 25 Feb 2013 09:20:18 +0100 (CET) Subject: [pypy-commit] pyrepl codecheck-clean: finish codeclean commands Message-ID: <20130225082018.6724F1C0EEA@cobra.cs.uni-duesseldorf.de> Author: Ronny Pfannschmidt Branch: codecheck-clean Changeset: r234:c15e4771846b Date: 2013-02-24 23:29 +0100 http://bitbucket.org/pypy/pyrepl/changeset/c15e4771846b/ Log: finish codeclean commands diff --git a/pyrepl/commands.py b/pyrepl/commands.py --- a/pyrepl/commands.py +++ b/pyrepl/commands.py @@ -19,7 +19,7 @@ # CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -import sys, os +import os # Catgories of actions: # killing @@ -30,6 +30,7 @@ # finishing # [completion] + class Command(object): finish = 0 kills_digit_arg = 1 @@ -42,6 +43,7 @@ def do(self): pass + class KillCommand(Command): def kill_range(self, start, end): if start == end: @@ -60,29 +62,37 @@ r.pos = start r.dirty = 1 + class YankCommand(Command): pass + class MotionCommand(Command): pass + class EditCommand(Command): pass + class FinishCommand(Command): finish = 1 pass + def is_kill(command): return command and issubclass(command, KillCommand) + def is_yank(command): return command and issubclass(command, YankCommand) # etc + class digit_arg(Command): kills_digit_arg = 0 + def do(self): r = self.reader c = self.event[-1] @@ -97,26 +107,30 @@ r.arg = d else: if r.arg < 0: - r.arg = 10*r.arg - d + r.arg = 10 * r.arg - d else: - r.arg = 10*r.arg + d + r.arg = 10 * r.arg + d r.dirty = 1 + class clear_screen(Command): def do(self): r = self.reader r.console.clear() r.dirty = 1 + class refresh(Command): def do(self): self.reader.dirty = 1 + class repaint(Command): def do(self): self.reader.dirty = 1 self.reader.console.repaint_prep() + class kill_line(KillCommand): def do(self): r = self.reader @@ -127,7 +141,8 @@ self.kill_range(r.pos, eol) return else: - self.kill_range(r.pos, eol+1) + self.kill_range(r.pos, eol + 1) + class unix_line_discard(KillCommand): def do(self): @@ -137,24 +152,28 @@ # XXX unix_word_rubout and backward_kill_word should actually # do different things... + class unix_word_rubout(KillCommand): def do(self): r = self.reader for i in range(r.get_arg()): self.kill_range(r.bow(), r.pos) + class kill_word(KillCommand): def do(self): r = self.reader for i in range(r.get_arg()): self.kill_range(r.pos, r.eow()) + class backward_kill_word(KillCommand): def do(self): r = self.reader for i in range(r.get_arg()): self.kill_range(r.bow(), r.pos) + class yank(YankCommand): def do(self): r = self.reader @@ -163,6 +182,7 @@ return r.insert(r.kill_ring[-1]) + class yank_pop(YankCommand): def do(self): r = self.reader @@ -180,12 +200,14 @@ r.pos = r.pos - repl + len(t) r.dirty = 1 + class interrupt(FinishCommand): def do(self): import signal self.reader.console.finish() os.kill(os.getpid(), signal.SIGINT) + class suspend(Command): def do(self): import signal @@ -201,6 +223,7 @@ r.dirty = 1 r.console.screen = [] + class up(MotionCommand): def do(self): r = self.reader @@ -213,7 +236,7 @@ r.pos = 0 r.error("start of buffer") return - bol2 = r.bol(bol1-1) + bol2 = r.bol(bol1 - 1) line_pos = r.pos - bol1 if line_pos > bol1 - bol2 - 1: r.sticky_y = line_pos @@ -221,6 +244,7 @@ else: r.pos = bol2 + line_pos + class down(MotionCommand): def do(self): r = self.reader @@ -236,22 +260,24 @@ r.pos = len(b) r.error("end of buffer") return - eol2 = r.eol(eol1+1) + eol2 = r.eol(eol1 + 1) if r.pos - bol1 > eol2 - eol1 - 1: r.pos = eol2 else: r.pos = eol1 + (r.pos - bol1) + 1 + class left(MotionCommand): def do(self): r = self.reader - for i in range(r.get_arg()): + for i in range(r.get_arg()): p = r.pos - 1 if p >= 0: r.pos = p else: self.reader.error("start of buffer") + class right(MotionCommand): def do(self): r = self.reader @@ -263,45 +289,53 @@ else: self.reader.error("end of buffer") + class beginning_of_line(MotionCommand): def do(self): self.reader.pos = self.reader.bol() + class end_of_line(MotionCommand): def do(self): - r = self.reader self.reader.pos = self.reader.eol() + class home(MotionCommand): def do(self): self.reader.pos = 0 - + + class end(MotionCommand): def do(self): self.reader.pos = len(self.reader.buffer) - + + class forward_word(MotionCommand): def do(self): r = self.reader for i in range(r.get_arg()): r.pos = r.eow() - + + class backward_word(MotionCommand): def do(self): r = self.reader for i in range(r.get_arg()): r.pos = r.bow() + class self_insert(EditCommand): def do(self): r = self.reader r.insert(self.event * r.get_arg()) + class insert_nl(EditCommand): def do(self): r = self.reader r.insert("\n" * r.get_arg()) + class transpose_characters(EditCommand): def do(self): r = self.reader @@ -319,6 +353,7 @@ r.pos = t r.dirty = 1 + class backspace(EditCommand): def do(self): r = self.reader @@ -331,12 +366,13 @@ else: self.reader.error("can't backspace at start") + class delete(EditCommand): def do(self): r = self.reader b = r.buffer - if ( r.pos == 0 and len(b) == 0 # this is something of a hack - and self.event[-1] == "\004"): + if (r.pos == 0 and len(b) == 0 and # this is something of a hack + self.event[-1] == "\004"): r.update_screen() r.console.finish() raise EOFError @@ -347,25 +383,30 @@ else: self.reader.error("end of buffer") + class accept(FinishCommand): def do(self): pass + class help(Command): def do(self): self.reader.msg = self.reader.help_text self.reader.dirty = 1 + class invalid_key(Command): def do(self): pending = self.reader.console.getpending() s = ''.join(self.event) + pending.data - self.reader.error("`%r' not bound"%s) + self.reader.error("`%r' not bound" % s) + class invalid_command(Command): def do(self): s = self.event_name - self.reader.error("command `%s' not known"%s) + self.reader.error("command `%s' not known" % s) + class qIHelp(Command): def do(self): @@ -373,15 +414,17 @@ r.insert((self.event + r.console.getpending().data) * r.get_arg()) r.pop_input_trans() -from pyrepl import input class QITrans(object): def push(self, evt): self.evt = evt + def get(self): return ('qIHelp', self.evt.raw) + class quoted_insert(Command): kills_digit_arg = 0 + def do(self): self.reader.push_input_trans(QITrans()) From noreply at buildbot.pypy.org Mon Feb 25 09:20:19 2013 From: noreply at buildbot.pypy.org (RonnyPfannschmidt) Date: Mon, 25 Feb 2013 09:20:19 +0100 (CET) Subject: [pypy-commit] pyrepl codecheck-clean: clean up the mini curses and the completing reader Message-ID: <20130225082019.B48CF1C0EEA@cobra.cs.uni-duesseldorf.de> Author: Ronny Pfannschmidt Branch: codecheck-clean Changeset: r235:84dcd5060600 Date: 2013-02-25 08:28 +0100 http://bitbucket.org/pypy/pyrepl/changeset/84dcd5060600/ Log: clean up the mini curses and the completing reader diff --git a/pyrepl/completing_reader.py b/pyrepl/completing_reader.py --- a/pyrepl/completing_reader.py +++ b/pyrepl/completing_reader.py @@ -55,7 +55,7 @@ # too bad, we remove the color return stripped[:maxlen] padding = maxlen - len(stripped) - return s + ' '*padding + return s + ' ' * padding def build_menu(cons, wordlist, start, use_brackets, sort_in_column): @@ -67,7 +67,7 @@ padding = 2 maxlen = min(max(map(real_len, wordlist)), cons.width - padding) cols = cons.width / (maxlen + padding) - rows = (len(wordlist) - 1)/cols + 1 + rows = (len(wordlist) - 1) / cols + 1 if sort_in_column: # sort_in_column=False (default) sort_in_column=True @@ -77,8 +77,8 @@ # # "fill" the table with empty words, so we always have the same amout # of rows for each column - missing = cols*rows - len(wordlist) - wordlist = wordlist + ['']*missing + missing = cols * rows - len(wordlist) + wordlist = wordlist + [''] * missing indexes = [(i % cols) * rows + i // cols for i in range(len(wordlist))] wordlist = [wordlist[i] for i in indexes] menu = [] @@ -238,7 +238,7 @@ if self.cmpltn_menu_vis: ly = self.lxy[1] screen[ly:ly] = self.cmpltn_menu - self.screeninfo[ly:ly] = [(0, [])]*len(self.cmpltn_menu) + self.screeninfo[ly:ly] = [(0, [])] * len(self.cmpltn_menu) self.cxy = self.cxy[0], self.cxy[1] + len(self.cmpltn_menu) return screen @@ -259,7 +259,7 @@ p = self.pos - 1 while p >= 0 and st.get(b[p], SW) == SW: p -= 1 - return ''.join(b[p+1:self.pos]) + return ''.join(b[p + 1:self.pos]) def get_completions(self, stem): return [] diff --git a/pyrepl/curses.py b/pyrepl/curses.py --- a/pyrepl/curses.py +++ b/pyrepl/curses.py @@ -19,5 +19,5 @@ # CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - +__all__ = ['setupterm', 'tigetstr', 'tparm', 'error'] from ._minimal_curses import setupterm, tigetstr, tparm, error From noreply at buildbot.pypy.org Mon Feb 25 09:20:20 2013 From: noreply at buildbot.pypy.org (RonnyPfannschmidt) Date: Mon, 25 Feb 2013 09:20:20 +0100 (CET) Subject: [pypy-commit] pyrepl codecheck-clean: more simple cleanups Message-ID: <20130225082020.CCAEF1C0EEA@cobra.cs.uni-duesseldorf.de> Author: Ronny Pfannschmidt Branch: codecheck-clean Changeset: r236:38d594adcc53 Date: 2013-02-25 09:20 +0100 http://bitbucket.org/pypy/pyrepl/changeset/38d594adcc53/ Log: more simple cleanups diff --git a/pyrepl/fancy_termios.py b/pyrepl/fancy_termios.py --- a/pyrepl/fancy_termios.py +++ b/pyrepl/fancy_termios.py @@ -19,10 +19,12 @@ import termios + class TermState: def __init__(self, tuples): self.iflag, self.oflag, self.cflag, self.lflag, \ - self.ispeed, self.ospeed, self.cc = tuples + self.ispeed, self.ospeed, self.cc = tuples + def as_list(self): return [self.iflag, self.oflag, self.cflag, self.lflag, self.ispeed, self.ospeed, self.cc] @@ -30,23 +32,30 @@ def copy(self): return self.__class__(self.as_list()) + def tcgetattr(fd): return TermState(termios.tcgetattr(fd)) + def tcsetattr(fd, when, attrs): termios.tcsetattr(fd, when, attrs.as_list()) + class Term(TermState): + #XXX: fix this mess TS__init__ = TermState.__init__ + def __init__(self, fd=0): self.TS__init__(termios.tcgetattr(fd)) self.fd = fd self.stack = [] + def save(self): - self.stack.append( self.as_list() ) + self.stack.append(self.as_list()) + def set(self, when=termios.TCSANOW): termios.tcsetattr(self.fd, when, self.as_list()) + def restore(self): self.TS__init__(self.stack.pop()) self.set() - diff --git a/pyrepl/historical_reader.py b/pyrepl/historical_reader.py --- a/pyrepl/historical_reader.py +++ b/pyrepl/historical_reader.py @@ -17,15 +17,15 @@ # CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -from pyrepl import reader, commands +from pyrepl import commands from pyrepl.reader import Reader as R isearch_keymap = tuple( - [('\\%03o'%c, 'isearch-end') for c in range(256) if chr(c) != '\\'] + \ + [('\\%03o' % c, 'isearch-end') for c in range(256) if chr(c) != '\\'] + [(c, 'isearch-add-character') - for c in map(chr, range(32, 127)) if c != '\\'] + \ - [('\\%03o'%c, 'isearch-add-character') - for c in range(256) if chr(c).isalpha() and chr(c) != '\\'] + \ + for c in map(chr, range(32, 127)) if c != '\\'] + + [('\\%03o' % c, 'isearch-add-character') + for c in range(256) if chr(c).isalpha() and chr(c) != '\\'] + [('\\\\', 'self-insert'), (r'\C-r', 'isearch-backwards'), (r'\C-s', 'isearch-forwards'), @@ -40,6 +40,7 @@ ISEARCH_DIRECTION_BACKWARDS = 'r' ISEARCH_DIRECTION_FORWARDS = 'f' + class next_history(commands.Command): def do(self): r = self.reader @@ -48,6 +49,7 @@ return r.select_item(r.historyi + 1) + class previous_history(commands.Command): def do(self): r = self.reader @@ -56,6 +58,7 @@ return r.select_item(r.historyi - 1) + class restore_history(commands.Command): def do(self): r = self.reader @@ -65,18 +68,22 @@ r.pos = len(r.buffer) r.dirty = 1 + class first_history(commands.Command): def do(self): self.reader.select_item(0) + class last_history(commands.Command): def do(self): self.reader.select_item(len(self.reader.history)) + class operate_and_get_next(commands.FinishCommand): def do(self): self.reader.next_history = self.reader.historyi + 1 + class yank_arg(commands.Command): def do(self): r = self.reader @@ -104,6 +111,7 @@ r.pos += len(w) - o r.dirty = 1 + class forward_history_isearch(commands.Command): def do(self): r = self.reader @@ -112,7 +120,7 @@ r.isearch_term = '' r.dirty = 1 r.push_input_trans(r.isearch_trans) - + class reverse_history_isearch(commands.Command): def do(self): @@ -123,6 +131,7 @@ r.push_input_trans(r.isearch_trans) r.isearch_start = r.historyi, r.pos + class isearch_cancel(commands.Command): def do(self): r = self.reader @@ -132,6 +141,7 @@ r.pos = r.isearch_start[1] r.dirty = 1 + class isearch_add_character(commands.Command): def do(self): r = self.reader @@ -139,9 +149,10 @@ r.isearch_term += self.event[-1] r.dirty = 1 p = r.pos + len(r.isearch_term) - 1 - if b[p:p+1] != [r.isearch_term[-1]]: + if b[p:p + 1] != [r.isearch_term[-1]]: r.isearch_next() + class isearch_backspace(commands.Command): def do(self): r = self.reader @@ -151,18 +162,21 @@ else: r.error("nothing to rubout") + class isearch_forwards(commands.Command): def do(self): r = self.reader r.isearch_direction = ISEARCH_DIRECTION_FORWARDS r.isearch_next() + class isearch_backwards(commands.Command): def do(self): r = self.reader r.isearch_direction = ISEARCH_DIRECTION_BACKWARDS r.isearch_next() + class isearch_end(commands.Command): def do(self): r = self.reader @@ -171,6 +185,7 @@ r.pop_input_trans() r.dirty = 1 + class HistoricalReader(R): """Adds history support (with incremental history searching) to the Reader class. @@ -199,7 +214,6 @@ (r'\', 'last-history'), (r'\', 'first-history')) - def __init__(self, console): super(HistoricalReader, self).__init__(console) self.history = [] @@ -219,7 +233,7 @@ self.isearch_trans = input.KeymapTranslator( isearch_keymap, invalid_cls=isearch_end, character_cls=isearch_add_character) - + def select_item(self, i): self.transient_history[self.historyi] = self.get_unicode() buf = self.transient_history.get(i) @@ -240,8 +254,8 @@ super(HistoricalReader, self).prepare() try: self.transient_history = {} - if self.next_history is not None \ - and self.next_history < len(self.history): + if self.next_history is not None and \ + self.next_history < len(self.history): self.historyi = self.next_history self.buffer[:] = list(self.history[self.next_history]) self.pos = len(self.buffer) @@ -256,9 +270,8 @@ def get_prompt(self, lineno, cursor_on_line): if cursor_on_line and self.isearch_direction != ISEARCH_DIRECTION_NONE: d = 'rf'[self.isearch_direction == ISEARCH_DIRECTION_FORWARDS] - return "(%s-search `%s') "%(d, self.isearch_term) - else: - return super(HistoricalReader, self).get_prompt(lineno, cursor_on_line) + return "(%s-search `%s') " % (d, self.isearch_term) + return super(HistoricalReader, self).get_prompt(lineno, cursor_on_line) def isearch_next(self): st = self.isearch_term @@ -298,6 +311,7 @@ if ret: self.history.append(ret) + def test(): from pyrepl.unix_console import UnixConsole reader = HistoricalReader(UnixConsole()) @@ -308,5 +322,5 @@ while reader.readline(): pass -if __name__=='__main__': +if __name__ == '__main__': test() diff --git a/pyrepl/input.py b/pyrepl/input.py --- a/pyrepl/input.py +++ b/pyrepl/input.py @@ -40,8 +40,10 @@ class InputTranslator(object): def push(self, evt): pass + def get(self): pass + def empty(self): pass From noreply at buildbot.pypy.org Mon Feb 25 10:52:27 2013 From: noreply at buildbot.pypy.org (lwassermann) Date: Mon, 25 Feb 2013 10:52:27 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: added blockclosure bytecode-based tests Message-ID: <20130225095227.286761C0EF3@cobra.cs.uni-duesseldorf.de> Author: Lars Wassermann Branch: Changeset: r96:8b8742f9cf14 Date: 2013-02-25 10:52 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/8b8742f9cf14/ Log: added blockclosure bytecode-based tests implemented nonlocal return for blockclosures diff --git a/spyvm/error.py b/spyvm/error.py --- a/spyvm/error.py +++ b/spyvm/error.py @@ -22,3 +22,6 @@ class FatalError(SmalltalkException): def __init__(self, msg): self.msg = msg + +class BlockCannotReturnError(PrimitiveFailedError): + pass \ No newline at end of file diff --git a/spyvm/interpreter.py b/spyvm/interpreter.py --- a/spyvm/interpreter.py +++ b/spyvm/interpreter.py @@ -256,6 +256,8 @@ # for tests, when returning from the top-level context if w_return_to.is_same_object(self.space.w_nil): raise ReturnFromTopLevel(object) + # widow this context + self.store_pc(None) w_return_to.as_context_get_shadow(self.space).push(object) return w_return_to @@ -272,6 +274,7 @@ return self._return(interp.space.w_nil, interp, self.s_home().w_sender()) def returnTopFromMethod(self, interp, current_bytecode): + # overwritten in MethodContextShadow return self._return(self.top(), interp, self.s_home().w_sender()) def returnTopFromBlock(self, interp, current_bytecode): diff --git a/spyvm/primitives.py b/spyvm/primitives.py --- a/spyvm/primitives.py +++ b/spyvm/primitives.py @@ -930,6 +930,7 @@ def activateClosure(interp, s_frame, w_block, args_w, mayContextSwitch=True): + # XXX may context switch is ignored space = interp.space if not w_block.getclass(space).is_same_object( space.w_BlockClosure): @@ -939,8 +940,7 @@ raise PrimitiveFailedError() outer_ctxt_class = block.outerContext().getclass(space) if not (outer_ctxt_class is space.w_MethodContext - or outer_ctxt_class is space.w_BlockContext - or outer_ctxt_class is space.w_BlockClosure): + or outer_ctxt_class is space.w_BlockContext): raise PrimitiveFailedError() # additionally to the smalltalk implementation, this also pushes diff --git a/spyvm/shadow.py b/spyvm/shadow.py --- a/spyvm/shadow.py +++ b/spyvm/shadow.py @@ -736,6 +736,19 @@ def myblocksize(self): return self.size() - self.tempsize() + def returnTopFromMethod(self, interp, current_bytecode): + if self.w_closure_or_nil is not self.space.w_nil: + # this is a context for a blockClosure + s_outerContext = self.w_closure_or_nil.fetch(self.space, + constants.BLKCLSR_OUTER_CONTEXT).get_shadow(self.space) + # XXX check whether we can actually return from that context + if s_outerContext.pc() == None: + raise error.BlockCannotReturnError() + s_outerContext._return(self.top(), interp, + s_outerContext.s_home().w_sender()) + else: + return self._return(self.top(), interp, self.s_home().w_sender()) + class CompiledMethodShadow(object): _immutable_fields_ = ["_w_self", "bytecode", diff --git a/spyvm/test/test_interpreter.py b/spyvm/test/test_interpreter.py --- a/spyvm/test/test_interpreter.py +++ b/spyvm/test/test_interpreter.py @@ -923,3 +923,29 @@ assert closure.outerContext() is s_frame._w_self assert closure.at0(0) == "english" assert closure.at0(1) == "bar" + +def test_blockclosure_valuevalue(): + #someTest + # ^ [ :a :b | a + b ] value: 1 value: 2 + def test(): + assert interpret_bc( + [ 0x8f, 2, 0, 4, 16, 17, 0xb0, 0x7d, 0x76, 0x77, 0xf0, 0x7c ], + fakeliterals(space, "value:value:", )).value == 3 + run_with_faked_primitive_methods( + [[space.w_BlockClosure, primitives.CLOSURE_VALUE_VALUE, + 2, "value:value:"]], + test) + +def test_blockclosure_return(): + #someTest + # [ :a :b | ^ a + b ] value: 1 value: 2. + # ^ 1 + def test(): + assert interpret_bc( + [ 0x8f, 2, 0, 4, 16, 17, 0xb0, 0x7c, + 0x76, 0x77, 0xf0, 0x87, 0x76, 0x7c ], + fakeliterals(space, "value:value:", )).value == 3 + run_with_faked_primitive_methods( + [[space.w_BlockClosure, primitives.CLOSURE_VALUE_VALUE, + 2, "value:value:"]], + test) From noreply at buildbot.pypy.org Mon Feb 25 10:52:44 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Mon, 25 Feb 2013 10:52:44 +0100 (CET) Subject: [pypy-commit] pypy default: fix test_exportstruct Message-ID: <20130225095244.B722E1C0EF3@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61750:ee3db3dcb005 Date: 2013-02-25 04:52 -0500 http://bitbucket.org/pypy/pypy/changeset/ee3db3dcb005/ Log: fix test_exportstruct diff --git a/rpython/translator/c/test/test_genc.py b/rpython/translator/c/test/test_genc.py --- a/rpython/translator/c/test/test_genc.py +++ b/rpython/translator/c/test/test_genc.py @@ -483,12 +483,16 @@ assert hasattr(ctypes.CDLL(str(t.driver.c_entryp)), 'foobar') def test_exportstruct(): + from rpython.translator.tool.cbuild import ExternalCompilationInfo from rpython.rlib.exports import export_struct def f(): return 42 FOO = Struct("FOO", ("field1", Signed)) foo = malloc(FOO, flavor="raw") foo.field1 = 43 + # maybe export_struct should add the struct name to eci automatically? + # https://bugs.pypy.org/issue1361 + foo._obj._compilation_info = ExternalCompilationInfo(export_symbols=['BarStruct']) export_struct("BarStruct", foo._obj) t = Translation(f, [], backend="c") t.annotate() From noreply at buildbot.pypy.org Mon Feb 25 12:27:14 2013 From: noreply at buildbot.pypy.org (fijal) Date: Mon, 25 Feb 2013 12:27:14 +0100 (CET) Subject: [pypy-commit] pypy default: a test and a fix Message-ID: <20130225112714.BE21B1C0237@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r61751:c225aecf8a0d Date: 2013-02-25 13:18 +0200 http://bitbucket.org/pypy/pypy/changeset/c225aecf8a0d/ Log: a test and a fix diff --git a/rpython/jit/metainterp/pyjitpl.py b/rpython/jit/metainterp/pyjitpl.py --- a/rpython/jit/metainterp/pyjitpl.py +++ b/rpython/jit/metainterp/pyjitpl.py @@ -1296,7 +1296,7 @@ self.make_result_of_lastop(resbox) # ^^^ this is done before handle_possible_exception() because we # need the box to show up in get_list_of_active_boxes() - if pure and self.metainterp.last_exc_value_box is None: + if pure and self.metainterp.last_exc_value_box is None and resbox: resbox = self.metainterp.record_result_of_call_pure(resbox) exc = exc and not isinstance(resbox, Const) if exc: diff --git a/rpython/jit/metainterp/test/test_call.py b/rpython/jit/metainterp/test/test_call.py --- a/rpython/jit/metainterp/test/test_call.py +++ b/rpython/jit/metainterp/test/test_call.py @@ -25,3 +25,21 @@ res = self.interp_operations(f, [3]) assert res == f(3) + def test_call_elidable_none(self): + d = {} + + @jit.elidable + def f(a): + return d.get(a, None) + + driver = jit.JitDriver(greens = [], reds = ['n']) + + def main(n): + while n > 0: + driver.jit_merge_point(n=n) + f(n) + f(n) + n -= 1 + return 3 + + self.meta_interp(main, [10]) From noreply at buildbot.pypy.org Mon Feb 25 12:27:16 2013 From: noreply at buildbot.pypy.org (fijal) Date: Mon, 25 Feb 2013 12:27:16 +0100 (CET) Subject: [pypy-commit] pypy default: merge Message-ID: <20130225112716.BE0931C0237@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r61752:ac346c279d8f Date: 2013-02-25 13:26 +0200 http://bitbucket.org/pypy/pypy/changeset/ac346c279d8f/ Log: merge diff too long, truncating to 2000 out of 2128 lines diff --git a/.hgignore b/.hgignore --- a/.hgignore +++ b/.hgignore @@ -35,39 +35,43 @@ ^pypy/doc/config/.+\.rst$ ^pypy/doc/basicblock\.asc$ ^pypy/doc/.+\.svninfo$ -^pypy/translator/c/src/libffi_msvc/.+\.obj$ -^pypy/translator/c/src/libffi_msvc/.+\.dll$ -^pypy/translator/c/src/libffi_msvc/.+\.lib$ -^pypy/translator/c/src/libffi_msvc/.+\.exp$ -^pypy/translator/c/src/cjkcodecs/.+\.o$ -^pypy/translator/c/src/cjkcodecs/.+\.obj$ -^pypy/translator/jvm/\.project$ -^pypy/translator/jvm/\.classpath$ -^pypy/translator/jvm/eclipse-bin$ -^pypy/translator/jvm/src/pypy/.+\.class$ -^pypy/translator/benchmark/docutils$ -^pypy/translator/benchmark/templess$ -^pypy/translator/benchmark/gadfly$ -^pypy/translator/benchmark/mako$ -^pypy/translator/benchmark/bench-custom\.benchmark_result$ -^pypy/translator/benchmark/shootout_benchmarks$ -^pypy/translator/goal/pypy-translation-snapshot$ -^pypy/translator/goal/pypy-c -^pypy/translator/goal/pypy-jvm -^pypy/translator/goal/pypy-jvm.jar -^pypy/translator/goal/.+\.exe$ -^pypy/translator/goal/.+\.dll$ -^pypy/translator/goal/target.+-c$ +^rpython/translator/c/src/libffi_msvc/.+\.obj$ +^rpython/translator/c/src/libffi_msvc/.+\.dll$ +^rpython/translator/c/src/libffi_msvc/.+\.lib$ +^rpython/translator/c/src/libffi_msvc/.+\.exp$ +^rpython/translator/c/src/cjkcodecs/.+\.o$ +^rpython/translator/c/src/cjkcodecs/.+\.obj$ +^rpython/translator/c/src/stacklet/.+\.o$ +^rpython/translator/c/src/.+\.o$ +^rpython/translator/jvm/\.project$ +^rpython/translator/jvm/\.classpath$ +^rpython/translator/jvm/eclipse-bin$ +^rpython/translator/jvm/src/pypy/.+\.class$ +^rpython/translator/benchmark/docutils$ +^rpython/translator/benchmark/templess$ +^rpython/translator/benchmark/gadfly$ +^rpython/translator/benchmark/mako$ +^rpython/translator/benchmark/bench-custom\.benchmark_result$ +^rpython/translator/benchmark/shootout_benchmarks$ +^rpython/translator/goal/target.+-c$ +^rpython/translator/goal/.+\.exe$ +^rpython/translator/goal/.+\.dll$ +^pypy/goal/pypy-translation-snapshot$ +^pypy/goal/pypy-c +^pypy/goal/pypy-jvm +^pypy/goal/pypy-jvm.jar +^pypy/goal/.+\.exe$ +^pypy/goal/.+\.dll$ ^pypy/_cache$ ^pypy/doc/statistic/.+\.html$ ^pypy/doc/statistic/.+\.eps$ ^pypy/doc/statistic/.+\.pdf$ -^pypy/translator/cli/src/pypylib\.dll$ -^pypy/translator/cli/src/query\.exe$ -^pypy/translator/cli/src/main\.exe$ +^rpython/translator/cli/src/pypylib\.dll$ +^rpython/translator/cli/src/query\.exe$ +^rpython/translator/cli/src/main\.exe$ ^lib_pypy/ctypes_config_cache/_.+_cache\.py$ ^lib_pypy/ctypes_config_cache/_.+_.+_\.py$ -^pypy/translator/cli/query-descriptions$ +^rpython/translator/cli/query-descriptions$ ^pypy/doc/discussion/.+\.html$ ^include/.+\.h$ ^include/.+\.inl$ diff --git a/lib_pypy/numpypy/core/__init__.py b/lib_pypy/numpypy/core/__init__.py --- a/lib_pypy/numpypy/core/__init__.py +++ b/lib_pypy/numpypy/core/__init__.py @@ -6,7 +6,6 @@ from fromnumeric import * import shape_base from shape_base import * -import multiarray from fromnumeric import amax as max, amin as min from _numpypy import absolute as abs diff --git a/lib_pypy/numpypy/core/arrayprint.py b/lib_pypy/numpypy/core/arrayprint.py --- a/lib_pypy/numpypy/core/arrayprint.py +++ b/lib_pypy/numpypy/core/arrayprint.py @@ -294,12 +294,12 @@ #else: format_function = formatdict['int'] elif issubclass(dtypeobj, _nt.floating): - if issubclass(dtypeobj, _nt.longfloat): + if hasattr(_nt, 'longfloat') and issubclass(dtypeobj, _nt.longfloat): format_function = formatdict['longfloat'] else: format_function = formatdict['float'] elif issubclass(dtypeobj, _nt.complexfloating): - if issubclass(dtypeobj, _nt.clongfloat): + if hasattr(_nt, 'clongfloat') and issubclass(dtypeobj, _nt.clongfloat): format_function = formatdict['longcomplexfloat'] else: format_function = formatdict['complexfloat'] diff --git a/lib_pypy/numpypy/core/numeric.py b/lib_pypy/numpypy/core/numeric.py --- a/lib_pypy/numpypy/core/numeric.py +++ b/lib_pypy/numpypy/core/numeric.py @@ -1,15 +1,33 @@ -__all__ = ['asanyarray', 'base_repr', +__all__ = [ + 'asanyarray', 'base_repr', 'array_repr', 'array_str', 'set_string_function', - 'array_equal', 'asarray', 'outer', 'identity'] + 'array_equal', 'asarray', 'outer', 'identity', 'little_endian', + 'Inf', 'inf', 'infty', 'Infinity', 'nan', 'NaN', 'False_', 'True_', + ] from _numpypy import array, ndarray, int_, float_, bool_, flexible #, complex_# , longlong from _numpypy import concatenate from .fromnumeric import any -import math import sys import multiarray +import umath +from umath import * from numpypy.core.arrayprint import array2string +def extend_all(module): + adict = {} + for a in __all__: + adict[a] = 1 + try: + mall = getattr(module, '__all__') + except AttributeError: + mall = [k for k in module.__dict__.keys() if not k.startswith('_')] + for a in mall: + if a not in adict: + __all__.append(a) + +extend_all(umath) + newaxis = None # XXX this file to be reviewed @@ -422,15 +440,10 @@ little_endian = (sys.byteorder == 'little') -Inf = inf = infty = Infinity = PINF = float('inf') -NINF = float('-inf') -PZERO = 0.0 -NZERO = -0.0 -nan = NaN = NAN = float('nan') +Inf = inf = infty = Infinity = PINF +nan = NaN = NAN False_ = bool_(False) True_ = bool_(True) -e = math.e -pi = math.pi def outer(a,b): """ diff --git a/lib_pypy/numpypy/core/umath.py b/lib_pypy/numpypy/core/umath.py new file mode 100644 --- /dev/null +++ b/lib_pypy/numpypy/core/umath.py @@ -0,0 +1,10 @@ +import math +e = math.e +pi = math.pi +del math + +PZERO = 0.0 +NZERO = -0.0 +PINF = float('inf') +NINF = float('-inf') +NAN = float('nan') diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst --- a/pypy/doc/whatsnew-head.rst +++ b/pypy/doc/whatsnew-head.rst @@ -18,6 +18,9 @@ .. branch: numpypy-longdouble Long double support for numpypy +.. branch: numpypy-disable-longdouble +Since r_longdouble support is missing, disable all longdouble and derivative +dtypes using ENABLED_LONG_DOUBLE = False .. branch: numpypy-real-as-view Convert real, imag from ufuncs to views. This involves the beginning of view() functionality diff --git a/pypy/module/micronumpy/__init__.py b/pypy/module/micronumpy/__init__.py --- a/pypy/module/micronumpy/__init__.py +++ b/pypy/module/micronumpy/__init__.py @@ -1,5 +1,5 @@ from pypy.interpreter.mixedmodule import MixedModule -from pypy.module.micronumpy.interp_boxes import long_double_size +from pypy.module.micronumpy.interp_boxes import long_double_size, ENABLED_LONG_DOUBLE class Module(MixedModule): @@ -23,10 +23,6 @@ 'count_nonzero': 'interp_arrayops.count_nonzero', 'set_string_function': 'appbridge.set_string_function', - - 'True_': 'types.Bool.True', - 'False_': 'types.Bool.False', - 'typeinfo': 'interp_dtype.get_dtype_cache(space).w_typeinfo', 'generic': 'interp_boxes.W_GenericBox', @@ -59,8 +55,6 @@ 'float16': 'interp_boxes.W_Float16Box', 'float32': 'interp_boxes.W_Float32Box', 'float64': 'interp_boxes.W_Float64Box', - 'longdouble': 'interp_boxes.W_LongDoubleBox', - 'longfloat': 'interp_boxes.W_LongDoubleBox', 'intp': 'types.IntP.BoxType', 'uintp': 'types.UIntP.BoxType', 'flexible': 'interp_boxes.W_FlexibleBox', @@ -73,8 +67,6 @@ 'complex_': 'interp_boxes.W_Complex128Box', 'complex128': 'interp_boxes.W_Complex128Box', 'complex64': 'interp_boxes.W_Complex64Box', - 'clongdouble': 'interp_boxes.W_CLongDoubleBox', - 'clongfloat': 'interp_boxes.W_CLongDoubleBox', } # ufuncs @@ -171,9 +163,22 @@ w_all = space.wrap(all_list) space.setitem(self.w_dict, space.new_interned_str('__all__'), w_all) -if long_double_size == 16: - Module.interpleveldefs['float128'] = 'interp_boxes.W_Float128Box' - Module.interpleveldefs['complex256'] = 'interp_boxes.W_Complex256Box' -elif long_double_size == 12: - Module.interpleveldefs['float96'] = 'interp_boxes.W_Float96Box' - Module.interpleveldefs['complex192'] = 'interp_boxes.W_Complex192Box' +if ENABLED_LONG_DOUBLE: + long_double_dtypes = [ + ('longdouble', 'interp_boxes.W_LongDoubleBox'), + ('longfloat', 'interp_boxes.W_LongDoubleBox'), + ('clongdouble', 'interp_boxes.W_CLongDoubleBox'), + ('clongfloat', 'interp_boxes.W_CLongDoubleBox'), + ] + if long_double_size == 16: + long_double_dtypes += [ + ('float128', 'interp_boxes.W_Float128Box'), + ('complex256', 'interp_boxes.W_Complex256Box'), + ] + elif long_double_size == 12: + long_double_dtypes += [ + ('float96', 'interp_boxes.W_Float96Box'), + ('complex192', 'interp_boxes.W_Complex192Box'), + ] + for dt, box in long_double_dtypes: + Module.interpleveldefs[dt] = box diff --git a/pypy/module/micronumpy/interp_arrayops.py b/pypy/module/micronumpy/interp_arrayops.py --- a/pypy/module/micronumpy/interp_arrayops.py +++ b/pypy/module/micronumpy/interp_arrayops.py @@ -106,29 +106,32 @@ args_w = [convert_to_array(space, w_arg) for w_arg in args_w] dtype = args_w[0].get_dtype() shape = args_w[0].get_shape()[:] - if len(shape) <= axis: + _axis = axis + if axis < 0: + _axis = len(shape) + axis + if _axis < 0 or len(shape) <= _axis: raise operationerrfmt(space.w_IndexError, "axis %d out of bounds [0, %d)", axis, len(shape)) for arr in args_w[1:]: dtype = interp_ufuncs.find_binop_result_dtype(space, dtype, arr.get_dtype()) - if len(arr.get_shape()) <= axis: + if _axis < 0 or len(arr.get_shape()) <= _axis: raise operationerrfmt(space.w_IndexError, "axis %d out of bounds [0, %d)", axis, len(shape)) for i, axis_size in enumerate(arr.get_shape()): - if len(arr.get_shape()) != len(shape) or (i != axis and axis_size != shape[i]): + if len(arr.get_shape()) != len(shape) or (i != _axis and axis_size != shape[i]): raise OperationError(space.w_ValueError, space.wrap( "all the input arrays must have same number of dimensions")) - elif i == axis: + elif i == _axis: shape[i] += axis_size res = W_NDimArray.from_shape(shape, dtype, 'C') chunks = [Chunk(0, i, 1, i) for i in shape] axis_start = 0 for arr in args_w: - if arr.get_shape()[axis] == 0: + if arr.get_shape()[_axis] == 0: continue - chunks[axis] = Chunk(axis_start, axis_start + arr.get_shape()[axis], 1, - arr.get_shape()[axis]) + chunks[_axis] = Chunk(axis_start, axis_start + arr.get_shape()[_axis], 1, + arr.get_shape()[_axis]) Chunks(chunks).apply(res).implementation.setslice(space, arr) - axis_start += arr.get_shape()[axis] + axis_start += arr.get_shape()[_axis] return res @unwrap_spec(repeats=int) diff --git a/pypy/module/micronumpy/interp_boxes.py b/pypy/module/micronumpy/interp_boxes.py --- a/pypy/module/micronumpy/interp_boxes.py +++ b/pypy/module/micronumpy/interp_boxes.py @@ -16,10 +16,12 @@ MIXIN_64 = (int_typedef,) if LONG_BIT == 64 else () # Is this the proper place for this? +ENABLED_LONG_DOUBLE = False long_double_size = rffi.sizeof_c_type('long double', ignore_errors=True) + import os if long_double_size == 8 and os.name == 'nt': - # this is a lie, or maybe a wish + # this is a lie, or maybe a wish, MS fakes longdouble math with double long_double_size = 12 @@ -335,7 +337,7 @@ descr__new__, _get_dtype = new_dtype_getter("complex128") _COMPONENTS_BOX = W_Float64Box -if long_double_size == 12: +if ENABLED_LONG_DOUBLE and long_double_size == 12: class W_Float96Box(W_FloatingBox, PrimitiveBox): descr__new__, _get_dtype = new_dtype_getter("float96") @@ -347,7 +349,7 @@ W_CLongDoubleBox = W_Complex192Box -elif long_double_size == 16: +elif ENABLED_LONG_DOUBLE and long_double_size == 16: class W_Float128Box(W_FloatingBox, PrimitiveBox): descr__new__, _get_dtype = new_dtype_getter("float128") W_LongDoubleBox = W_Float128Box @@ -358,7 +360,7 @@ W_CLongDoubleBox = W_Complex256Box -else: +elif ENABLED_LONG_DOUBLE: W_LongDoubleBox = W_Float64Box W_CLongDoubleBox = W_Complex64Box @@ -526,7 +528,7 @@ __new__ = interp2app(W_Float64Box.descr__new__.im_func), ) -if long_double_size == 12: +if ENABLED_LONG_DOUBLE and long_double_size == 12: W_Float96Box.typedef = TypeDef("float96", (W_FloatingBox.typedef), __module__ = "numpypy", @@ -540,7 +542,7 @@ imag = GetSetProperty(W_ComplexFloatingBox.descr_get_imag), ) -elif long_double_size == 16: +elif ENABLED_LONG_DOUBLE and long_double_size == 16: W_Float128Box.typedef = TypeDef("float128", (W_FloatingBox.typedef), __module__ = "numpypy", diff --git a/pypy/module/micronumpy/interp_dtype.py b/pypy/module/micronumpy/interp_dtype.py --- a/pypy/module/micronumpy/interp_dtype.py +++ b/pypy/module/micronumpy/interp_dtype.py @@ -164,8 +164,11 @@ def is_record_type(self): return self.fields is not None + def is_str_or_unicode(self): + return (self.num == 18 or self.num == 19) + def is_flexible_type(self): - return (self.num == 18 or self.num == 19 or self.num == 20) + return (self.is_str_or_unicode() or self.is_record_type()) def __repr__(self): if self.fields is not None: @@ -474,7 +477,7 @@ aliases=["complex"], float_type = self.w_float64dtype, ) - if interp_boxes.long_double_size == 12: + if interp_boxes.ENABLED_LONG_DOUBLE and interp_boxes.long_double_size == 12: self.w_float96dtype = W_Dtype( types.Float96(), num=13, @@ -497,7 +500,7 @@ ) self.w_longdouble = self.w_float96dtype self.w_clongdouble = self.w_complex192dtype - elif interp_boxes.long_double_size == 16: + elif interp_boxes.ENABLED_LONG_DOUBLE and interp_boxes.long_double_size == 16: self.w_float128dtype = W_Dtype( types.Float128(), num=13, @@ -520,13 +523,13 @@ ) self.w_longdouble = self.w_float128dtype self.w_clongdouble = self.w_complex256dtype - else: + elif interp_boxes.ENABLED_LONG_DOUBLE: self.w_float64dtype.aliases += ["longdouble", "longfloat"] self.w_complex128dtype.aliases += ["clongdouble", "clongfloat"] self.w_longdouble = self.w_float64dtype self.w_clongdouble = self.w_complex128dtype self.w_stringdtype = W_Dtype( - types.StringType(1), + types.StringType(0), num=18, kind=STRINGLTR, name='string', @@ -596,23 +599,27 @@ char=UINTPLTR, w_box_type = space.gettypefor(uintp_box), ) + float_dtypes = [self.w_float16dtype, + self.w_float32dtype, self.w_float64dtype, + ] + complex_dtypes = [self.w_complex64dtype, self.w_complex128dtype] + if interp_boxes.ENABLED_LONG_DOUBLE: + float_dtypes.append(self.w_longdouble) + complex_dtypes.append(self.w_clongdouble) self.builtin_dtypes = [ self.w_booldtype, self.w_int8dtype, self.w_uint8dtype, self.w_int16dtype, self.w_uint16dtype, self.w_longdtype, self.w_ulongdtype, self.w_int32dtype, self.w_uint32dtype, - self.w_int64dtype, self.w_uint64dtype, - self.w_float16dtype, - self.w_float32dtype, self.w_float64dtype, self.w_longdouble, - self.w_complex64dtype, self.w_complex128dtype, self.w_clongdouble, + self.w_int64dtype, self.w_uint64dtype] + \ + float_dtypes + complex_dtypes + [ self.w_stringdtype, self.w_unicodedtype, self.w_voiddtype, self.w_intpdtype, self.w_uintpdtype, ] self.float_dtypes_by_num_bytes = sorted( (dtype.itemtype.get_element_size(), dtype) - for dtype in [self.w_float16dtype, self.w_float32dtype, - self.w_float64dtype, self.w_longdouble] + for dtype in float_dtypes ) self.dtypes_by_num = {} self.dtypes_by_name = {} @@ -655,7 +662,6 @@ 'LONGLONG': self.w_int64dtype, 'SHORT': self.w_int16dtype, 'VOID': self.w_voiddtype, - 'LONGDOUBLE': self.w_longdouble, 'UBYTE': self.w_uint8dtype, 'UINTP': self.w_ulongdtype, 'ULONG': self.w_ulongdtype, @@ -678,8 +684,11 @@ 'USHORT': self.w_uint16dtype, 'FLOAT': self.w_float32dtype, 'BOOL': self.w_booldtype, - 'CLONGDOUBLE': self.w_clongdouble, } + if interp_boxes.ENABLED_LONG_DOUBLE: + typeinfo_full['LONGDOUBLE'] = self.w_longdouble + typeinfo_full['CLONGDOUBLE'] = self.w_clongdouble + typeinfo_partial = { 'Generic': interp_boxes.W_GenericBox, 'Character': interp_boxes.W_CharacterBox, diff --git a/pypy/module/micronumpy/interp_numarray.py b/pypy/module/micronumpy/interp_numarray.py --- a/pypy/module/micronumpy/interp_numarray.py +++ b/pypy/module/micronumpy/interp_numarray.py @@ -932,7 +932,8 @@ return w_object shape, elems_w = find_shape_and_elems(space, w_object, dtype) - if dtype is None: + if dtype is None or ( + dtype.is_str_or_unicode() and dtype.itemtype.get_size() < 1): for w_elem in elems_w: dtype = interp_ufuncs.find_dtype_for_scalar(space, w_elem, dtype) @@ -941,6 +942,9 @@ if dtype is None: dtype = interp_dtype.get_dtype_cache(space).w_float64dtype + if dtype.is_str_or_unicode() and dtype.itemtype.get_size() < 1: + # promote S0 -> S1, U0 -> U1 + dtype = interp_dtype.variable_dtype(space, dtype.char + '1') if ndmin > len(shape): shape = [1] * (ndmin - len(shape)) + shape arr = W_NDimArray.from_shape(shape, dtype, order=order) diff --git a/pypy/module/micronumpy/interp_ufuncs.py b/pypy/module/micronumpy/interp_ufuncs.py --- a/pypy/module/micronumpy/interp_ufuncs.py +++ b/pypy/module/micronumpy/interp_ufuncs.py @@ -400,7 +400,7 @@ return interp_dtype.get_dtype_cache(space).w_complex64dtype elif dt2.num == 15: return interp_dtype.get_dtype_cache(space).w_complex128dtype - elif dt2.num == 16: + elif interp_boxes.ENABLED_LONG_DOUBLE and dt2.num == 16: return interp_dtype.get_dtype_cache(space).w_clongdouble else: raise OperationError(space.w_TypeError, space.wrap("Unsupported types")) diff --git a/pypy/module/micronumpy/test/test_complex.py b/pypy/module/micronumpy/test/test_complex.py --- a/pypy/module/micronumpy/test/test_complex.py +++ b/pypy/module/micronumpy/test/test_complex.py @@ -196,8 +196,13 @@ raises(TypeError, signbit, complex(1,1)) def test_reciprocal(self): - from _numpypy import array, reciprocal, complex64, complex128, clongdouble - + from _numpypy import array, reciprocal, complex64, complex128 + c_and_relerr = [(complex64, 2e-7), (complex128, 2e-15)] + try: + from _numpypy import clongdouble + c_and_relerr.append((clongdouble, 2e-30)) + except: + pass # no longdouble yet inf = float('inf') nan = float('nan') #complex @@ -212,7 +217,7 @@ complex(-r, i), -0j, 0j, cnan, cnan, cnan, cnan] - for c, rel_err in ((complex64, 2e-7), (complex128, 2e-15), (clongdouble, 2e-15)): + for c, rel_err in c_and_relerr: actual = reciprocal(array([orig], dtype=c)) for b, a, e in zip(orig, actual, expected): assert (a[0].real - e.real) < rel_err @@ -232,12 +237,18 @@ raises(TypeError, copysign, a, b) def test_exp2(self): - from _numpypy import array, exp2, complex128, complex64, clongfloat + from _numpypy import array, exp2, complex128, complex64 + c_and_relerr = [(complex64, 2e-7), (complex128, 2e-15)] + try: + from _numpypy import clongdouble + c_and_relerr.append((clongdouble, 2e-30)) + except: + pass # no longdouble yet inf = float('inf') ninf = -float('inf') nan = float('nan') cmpl = complex - for c,rel_err in ((complex128, 2e-15), (complex64, 1e-7), (clongfloat, 2e-15)): + for c,rel_err in c_and_relerr: a = [cmpl(-5., 0), cmpl(-5., -5.), cmpl(-5., 5.), cmpl(0., -5.), cmpl(0., 0.), cmpl(0., 5.), cmpl(-0., -5.), cmpl(-0., 0.), cmpl(-0., 5.), @@ -496,15 +507,21 @@ def test_basic(self): from _numpypy import (complex128, complex64, add, array, dtype, subtract as sub, multiply, divide, negative, absolute as abs, - floor_divide, real, imag, sign, clongfloat) + floor_divide, real, imag, sign) from _numpypy import (equal, not_equal, greater, greater_equal, less, less_equal, isnan) + complex_dtypes = [complex64, complex128] + try: + from _numpypy import clongfloat + complex_dtypes.append(clongfloat) + except: + pass assert real(4.0) == 4.0 assert imag(0.0) == 0.0 a = array([complex(3.0, 4.0)]) b = a.real assert b.dtype == dtype(float) - for complex_ in complex64, complex128, clongfloat: + for complex_ in complex_dtypes: O = complex(0, 0) c0 = complex_(complex(2.5, 0)) diff --git a/pypy/module/micronumpy/test/test_dtypes.py b/pypy/module/micronumpy/test/test_dtypes.py --- a/pypy/module/micronumpy/test/test_dtypes.py +++ b/pypy/module/micronumpy/test/test_dtypes.py @@ -14,7 +14,7 @@ from rpython.rtyper.lltypesystem import rffi ptr_size = rffi.sizeof(rffi.CCHARP) cls.w_ptr_size = cls.space.wrap(ptr_size) - + class AppTestDtypes(BaseAppTestDtypes): def test_dtype(self): from _numpypy import dtype @@ -43,13 +43,6 @@ raises(TypeError, lambda: dtype("int8") == 3) assert dtype(bool) == bool - def test_dtype_aliases(self): - from _numpypy import dtype - assert dtype('longfloat').num in (12, 13) - assert dtype('longdouble').num in (12, 13) - assert dtype('clongfloat').num in (15, 16) - assert dtype('clongdouble').num in (15, 16) - def test_dtype_with_types(self): from _numpypy import dtype @@ -87,7 +80,8 @@ assert str(d) == "bool" def test_bool_array(self): - from _numpypy import array, False_, True_ + from _numpypy import array + from numpypy import False_, True_ a = array([0, 1, 2, 2.5], dtype='?') assert a[0] is False_ @@ -95,7 +89,8 @@ assert a[i] is True_ def test_copy_array_with_dtype(self): - from _numpypy import array, False_, longlong + from _numpypy import array, longlong + from numpypy import False_ a = array([0, 1, 2, 3], dtype=long) # int on 64-bit, long in 32-bit @@ -109,14 +104,16 @@ assert b[0] is False_ def test_zeros_bool(self): - from _numpypy import zeros, False_ + from _numpypy import zeros + from numpypy import False_ a = zeros(10, dtype=bool) for i in range(10): assert a[i] is False_ def test_ones_bool(self): - from _numpypy import ones, True_ + from _numpypy import ones + from numpypy import True_ a = ones(10, dtype=bool) for i in range(10): @@ -154,8 +151,6 @@ '?', 'b', 'B', 'h', 'H', 'i', 'I', 'l', 'L', 'q', 'Q', 'f', 'd', 'e' ] - if array([0], dtype='longdouble').itemsize > 8: - types += ['g', 'G'] a = array([True], '?') for t in types: assert (a + array([0], t)).dtype is dtype(t) @@ -271,7 +266,6 @@ (numpy.float16, 10.), (numpy.float32, 2.0), (numpy.float64, 4.32), - (numpy.longdouble, 4.32), ]: assert hash(tp(value)) == hash(value) @@ -327,7 +321,7 @@ assert int_(4) ** 2 == 16 def test_bool(self): - import _numpypy as numpy + import numpypy as numpy assert numpy.bool_.mro() == [numpy.bool_, numpy.generic, object] assert numpy.bool_(3) is numpy.True_ @@ -528,20 +522,6 @@ from math import isnan assert isnan(numpy.float32(None)) assert isnan(numpy.float64(None)) - assert isnan(numpy.longdouble(None)) - - def test_longfloat(self): - import _numpypy as numpy - # it can be float96 or float128 - if numpy.longfloat != numpy.float64: - assert numpy.longfloat.mro()[1:] == [numpy.floating, - numpy.inexact, numpy.number, - numpy.generic, object] - a = numpy.array([1, 2, 3], numpy.longdouble) - assert type(a[1]) is numpy.longdouble - assert numpy.float64(12) == numpy.longdouble(12) - assert numpy.float64(12) == numpy.longfloat(12) - raises(ValueError, numpy.longfloat, '23.2df') def test_complex_floating(self): import _numpypy as numpy @@ -658,7 +638,8 @@ def test_operators(self): from operator import truediv - from _numpypy import float64, int_, True_, False_ + from _numpypy import float64, int_ + from numpypy import True_, False_ assert 5 / int_(2) == int_(2) assert truediv(int_(3), int_(2)) == float64(1.5) assert truediv(3, int_(2)) == float64(1.5) @@ -799,12 +780,6 @@ a = array([1, 2, 3], dtype=self.non_native_prefix + 'f2') assert a[0] == 1 assert (a + a)[1] == 4 - a = array([1, 2, 3], dtype=self.non_native_prefix + 'g') # longdouble - assert a[0] == 1 - assert (a + a)[1] == 4 - a = array([1, 2, 3], dtype=self.non_native_prefix + 'G') # clongdouble - assert a[0] == 1 - assert (a + a)[1] == 4 class AppTestPyPyOnly(BaseNumpyAppTest): def setup_class(cls): @@ -818,3 +793,81 @@ assert typeinfo['LONGLONG'] == ('q', 9, 64, 8, 9223372036854775807L, -9223372036854775808L, int64) assert typeinfo['VOID'] == ('V', 20, 0, 1, void) assert typeinfo['BOOL'] == ('?', 0, 8, 1, 1, 0, bool_) + +class AppTestNoLongDoubleDtypes(BaseNumpyAppTest): + def setup_class(cls): + from pypy.module.micronumpy import Module + if Module.interpleveldefs.get('longfloat', None): + py.test.skip('longdouble exists, skip these tests') + if option.runappdirect and '__pypy__' not in sys.builtin_module_names: + py.test.skip("pypy only test for no longdouble support") + BaseNumpyAppTest.setup_class.im_func(cls) + + def test_nolongfloat(self): + import _numpypy + from _numpypy import dtype + assert not getattr(_numpypy, 'longdouble', False) + assert not getattr(_numpypy, 'float128', False) + assert not getattr(_numpypy, 'float96', False) + raises(TypeError, dtype, 'longdouble') + raises(TypeError, dtype, 'clongdouble') + raises(TypeError, dtype, 'longfloat') + raises(TypeError, dtype, 'clongfloat') + raises(TypeError, dtype, 'float128') + raises(TypeError, dtype, 'float96') + +class AppTestLongDoubleDtypes(BaseNumpyAppTest): + def setup_class(cls): + from pypy.module.micronumpy import Module + print dir(Module.interpleveldefs) + if not Module.interpleveldefs.get('longfloat', None): + py.test.skip('no longdouble types yet') + BaseNumpyAppTest.setup_class.im_func(cls) + + def test_longfloat(self): + import _numpypy as numpy + # it can be float96 or float128 + if numpy.longfloat != numpy.float64: + assert numpy.longfloat.mro()[1:] == [numpy.floating, + numpy.inexact, numpy.number, + numpy.generic, object] + a = numpy.array([1, 2, 3], numpy.longdouble) + assert type(a[1]) is numpy.longdouble + assert numpy.float64(12) == numpy.longdouble(12) + assert numpy.float64(12) == numpy.longfloat(12) + raises(ValueError, numpy.longfloat, '23.2df') + + def test_dtype_aliases(self): + from _numpypy import dtype + assert dtype('longfloat').num in (12, 13) + assert dtype('longdouble').num in (12, 13) + assert dtype('clongfloat').num in (15, 16) + assert dtype('clongdouble').num in (15, 16) + + def test_bool_binop_types(self): + from _numpypy import array, dtype + types = ['g', 'G'] + a = array([True], '?') + for t in types: + assert (a + array([0], t)).dtype is dtype(t) + + def test_hash(self): + import _numpypy as numpy + for tp, value in [ + (numpy.longdouble, 4.32), + ]: + assert hash(tp(value)) == hash(value) + + def test_float_None(self): + import _numpypy as numpy + from math import isnan + assert isnan(numpy.longdouble(None)) + + def test_non_native(self): + from _numpypy import array + a = array([1, 2, 3], dtype=self.non_native_prefix + 'g') # longdouble + assert a[0] == 1 + assert (a + a)[1] == 4 + a = array([1, 2, 3], dtype=self.non_native_prefix + 'G') # clongdouble + assert a[0] == 1 + assert (a + a)[1] == 4 diff --git a/pypy/module/micronumpy/test/test_numarray.py b/pypy/module/micronumpy/test/test_numarray.py --- a/pypy/module/micronumpy/test/test_numarray.py +++ b/pypy/module/micronumpy/test/test_numarray.py @@ -780,6 +780,7 @@ def test_mul(self): import _numpypy + from numpypy import False_, True_ a = _numpypy.array(range(5)) b = a * a @@ -790,9 +791,9 @@ a = _numpypy.array(range(5), dtype=bool) b = a * a assert b.dtype is _numpypy.dtype(bool) - assert b[0] is _numpypy.False_ + assert b[0] is False_ for i in range(1, 5): - assert b[i] is _numpypy.True_ + assert b[i] is True_ def test_mul_constant(self): from _numpypy import array @@ -1201,7 +1202,8 @@ b = array([]) raises(ValueError, "b.max()") - assert list(zeros((0, 2)).max(axis=1)) == [] + if 0: # XXX too pedantic + assert list(zeros((0, 2)).max(axis=1)) == [] def test_max_add(self): from _numpypy import array @@ -1215,7 +1217,8 @@ b = array([]) raises(ValueError, "b.min()") - assert list(zeros((0, 2)).min(axis=1)) == [] + if 0: # XXX too pedantic + assert list(zeros((0, 2)).min(axis=1)) == [] def test_argmax(self): from _numpypy import array @@ -1430,8 +1433,9 @@ assert len(a) == 6 assert (a == [0,1,2,3,4,5]).all() assert a.dtype is dtype(int) - a = concatenate((a1, a2), axis=1) - assert (a == [0,1,2,3,4,5]).all() + if 0: # XXX why does numpy allow this? + a = concatenate((a1, a2), axis=1) + assert (a == [0,1,2,3,4,5]).all() a = concatenate((a1, a2), axis=-1) assert (a == [0,1,2,3,4,5]).all() @@ -1454,10 +1458,10 @@ g2 = array([[3,4,5]]) g = concatenate((g1, g2), axis=-2) assert (g == [[0,1,2],[3,4,5]]).all() + exc = raises(IndexError, concatenate, (g1, g2), axis=-3) + assert str(exc.value) == "axis -3 out of bounds [0, 2)" exc = raises(IndexError, concatenate, (g1, g2), axis=2) assert str(exc.value) == "axis 2 out of bounds [0, 2)" - exc = raises(IndexError, concatenate, (g1, g2), axis=-3) - assert str(exc.value) == "axis -3 out of bounds [0, 2)" exc = raises(ValueError, concatenate, ()) assert str(exc.value) == \ @@ -1467,11 +1471,12 @@ assert str(exc.value) == \ "all the input arrays must have same number of dimensions" - g1 = array([0,1,2]) - g2 = array([[3,4,5]]) - exc = raises(ValueError, concatenate, (g1, g2), axis=2) - assert str(exc.value) == \ - "all the input arrays must have same number of dimensions" + if 0: # XXX too pedantic + g1 = array([0,1,2]) + g2 = array([[3,4,5]]) + exc = raises(ValueError, concatenate, (g1, g2), axis=2) + assert str(exc.value) == \ + "all the input arrays must have same number of dimensions" a = array([1, 2, 3, 4, 5, 6]) a = (a + a)[::2] @@ -1692,15 +1697,6 @@ i2 = (i+1) * a.dtype.itemsize assert list(reversed(s1[i1:i2])) == s2[i1:i2] - a = array([1, -1, 10000], dtype='longfloat') - s1 = map(ord, a.tostring()) - s2 = map(ord, a.byteswap().tostring()) - assert a.dtype.itemsize >= 8 - for i in range(a.size): - i1 = i * a.dtype.itemsize - i2 = (i+1) * a.dtype.itemsize - assert list(reversed(s1[i1:i2])) == s2[i1:i2] - def test_clip(self): from _numpypy import array a = array([1, 2, 17, -3, 12]) @@ -2336,7 +2332,7 @@ def test_fromstring_types(self): from _numpypy import (fromstring, int8, int16, int32, int64, uint8, - uint16, uint32, float16, float32, float64, longfloat, array) + uint16, uint32, float16, float32, float64, array) a = fromstring('\xFF', dtype=int8) assert a[0] == -1 b = fromstring('\xFF', dtype=uint8) @@ -2359,18 +2355,6 @@ assert j[0] == 12 k = fromstring(self.float16val, dtype=float16) assert k[0] == float16(5.) - dt = array([5],dtype=longfloat).dtype - if dt.itemsize == 12: - from _numpypy import float96 - m = fromstring('\x00\x00\x00\x00\x00\x00\x00\xa0\x01@\x00\x00', dtype=float96) - elif dt.itemsize==16: - from _numpypy import float128 - m = fromstring('\x00\x00\x00\x00\x00\x00\x00\xa0\x01@\x00\x00\x00\x00\x00\x00', dtype=float128) - elif dt.itemsize == 8: - skip('longfloat is float64') - else: - skip('unknown itemsize for longfloat') - assert m[0] == longfloat(5.) def test_fromstring_invalid(self): from _numpypy import fromstring, uint16, uint8 @@ -2539,9 +2523,11 @@ assert d.name == 'void32' a = array([('a', 2), ('cde', 1)], dtype=d) - assert a[0]['x'] == '\x02' + if 0: # XXX why does numpy allow this? + assert a[0]['x'] == '\x02' assert a[0]['y'] == 2 - assert a[1]['x'] == '\x01' + if 0: # XXX why does numpy allow this? + assert a[1]['x'] == '\x01' assert a[1]['y'] == 1 d = dtype([('x', 'S1'), ('y', 'int32')]) @@ -2645,3 +2631,40 @@ assert x.__pypy_data__ is obj del x.__pypy_data__ assert x.__pypy_data__ is None + +class AppTestLongDoubleDtypes(BaseNumpyAppTest): + def setup_class(cls): + from pypy.module.micronumpy import Module + print dir(Module.interpleveldefs) + if not Module.interpleveldefs.get('longfloat', None): + py.test.skip('no longdouble types yet') + BaseNumpyAppTest.setup_class.im_func(cls) + + def test_byteswap(self): + from _numpypy import array + + a = array([1, -1, 10000], dtype='longfloat') + s1 = map(ord, a.tostring()) + s2 = map(ord, a.byteswap().tostring()) + assert a.dtype.itemsize >= 8 + for i in range(a.size): + i1 = i * a.dtype.itemsize + i2 = (i+1) * a.dtype.itemsize + assert list(reversed(s1[i1:i2])) == s2[i1:i2] + + def test_fromstring_types(self): + from _numpypy import (fromstring, longfloat, array) + dt = array([5],dtype=longfloat).dtype + if dt.itemsize == 12: + from _numpypy import float96 + m = fromstring('\x00\x00\x00\x00\x00\x00\x00\xa0\x01@\x00\x00', dtype=float96) + elif dt.itemsize==16: + from _numpypy import float128 + m = fromstring('\x00\x00\x00\x00\x00\x00\x00\xa0\x01@\x00\x00\x00\x00\x00\x00', dtype=float128) + elif dt.itemsize == 8: + skip('longfloat is float64') + else: + skip('unknown itemsize for longfloat') + assert m[0] == longfloat(5.) + + diff --git a/pypy/module/micronumpy/types.py b/pypy/module/micronumpy/types.py --- a/pypy/module/micronumpy/types.py +++ b/pypy/module/micronumpy/types.py @@ -1515,7 +1515,7 @@ NonNativeComplex128 = Complex128 -if interp_boxes.long_double_size == 12: +if interp_boxes.ENABLED_LONG_DOUBLE and interp_boxes.long_double_size == 12: class Float96(BaseType, Float): _attrs_ = () @@ -1545,7 +1545,7 @@ NonNativeComplex192 = Complex192 -elif interp_boxes.long_double_size == 16: +elif interp_boxes.ENABLED_LONG_DOUBLE and interp_boxes.long_double_size == 16: class Float128(BaseType, Float): _attrs_ = () diff --git a/pypy/module/test_lib_pypy/numpypy/test_numpy.py b/pypy/module/test_lib_pypy/numpypy/test_numpy.py --- a/pypy/module/test_lib_pypy/numpypy/test_numpy.py +++ b/pypy/module/test_lib_pypy/numpypy/test_numpy.py @@ -53,3 +53,9 @@ import numpypy assert numpypy.set_string_function is not \ numpypy.core.multiarray.set_string_function + + def test_constants(self): + import numpypy + assert numpypy.PZERO == numpypy.NZERO == 0.0 + assert numpypy.inf is float('inf') + assert numpypy.nan is float('nan') diff --git a/rpython/flowspace/argument.py b/rpython/flowspace/argument.py --- a/rpython/flowspace/argument.py +++ b/rpython/flowspace/argument.py @@ -2,6 +2,7 @@ Arguments objects. """ + class Signature(object): _immutable_ = True _immutable_fields_ = ["argnames[*]"] @@ -57,7 +58,6 @@ return NotImplemented return not self == other - # make it look tuply for its use in the annotator def __len__(self): @@ -72,6 +72,7 @@ return self.kwargname raise IndexError + class ArgumentsForTranslation(object): def __init__(self, space, args_w, keywords=None, keywords_w=None, w_stararg=None, w_starstararg=None): @@ -142,16 +143,15 @@ self.keywords = self.keywords + keywords self.keywords_w = self.keywords_w + keywords_w - def fixedunpack(self, argcount): """The simplest argument parsing: get the 'argcount' arguments, or raise a real ValueError if the length is wrong.""" if self.keywords: - raise ValueError, "no keyword arguments expected" + raise ValueError("no keyword arguments expected") if len(self.arguments_w) > argcount: - raise ValueError, "too many arguments (%d expected)" % argcount + raise ValueError("too many arguments (%d expected)" % argcount) elif len(self.arguments_w) < argcount: - raise ValueError, "not enough arguments (%d expected)" % argcount + raise ValueError("not enough arguments (%d expected)" % argcount) return self.arguments_w def combine_if_necessary(self): @@ -270,7 +270,6 @@ kwds_w[self.keywords[i]] = self.keywords_w[i] return self.arguments_w, kwds_w - def match_signature(self, signature, defaults_w): """Parse args and kwargs according to the signature of a code object, or raise an ArgErr in case of failure. @@ -330,7 +329,7 @@ return ArgumentsForTranslation(self.space, args_w, keywords, keywords_w) @staticmethod - def fromshape(space, (shape_cnt,shape_keys,shape_star,shape_stst), data_w): + def fromshape(space, (shape_cnt, shape_keys, shape_star, shape_stst), data_w): args_w = data_w[:shape_cnt] p = end_keys = shape_cnt + len(shape_keys) if shape_star: @@ -360,7 +359,7 @@ def _rawshape(self, nextra=0): assert not self.combine_has_happened - shape_cnt = len(self.arguments_w)+nextra # Number of positional args + shape_cnt = len(self.arguments_w) + nextra # Number of positional args if self.keywords: shape_keys = self.keywords[:] # List of keywords (strings) shape_keys.sort() @@ -370,6 +369,7 @@ shape_stst = self.w_starstararg is not None # Flag: presence of **kwds return shape_cnt, tuple(shape_keys), shape_star, shape_stst # shape_keys are sorted + def rawshape(args, nextra=0): return args._rawshape(nextra) @@ -380,12 +380,11 @@ # class ArgErr(Exception): - def getmsg(self): raise NotImplementedError + class ArgErrCount(ArgErr): - def __init__(self, got_nargs, nkwds, signature, defaults_w, missing_args): self.signature = signature @@ -432,8 +431,8 @@ num_args) return msg + class ArgErrMultipleValues(ArgErr): - def __init__(self, argname): self.argname = argname @@ -442,8 +441,8 @@ self.argname) return msg + class ArgErrUnknownKwds(ArgErr): - def __init__(self, space, num_remainingkwds, keywords, kwds_mapping, keyword_names_w): name = '' diff --git a/rpython/flowspace/flowcontext.py b/rpython/flowspace/flowcontext.py --- a/rpython/flowspace/flowcontext.py +++ b/rpython/flowspace/flowcontext.py @@ -9,11 +9,12 @@ from rpython.tool.stdlib_opcode import host_bytecode_spec from rpython.flowspace.argument import ArgumentsForTranslation from rpython.flowspace.model import (Constant, Variable, Block, Link, - UnwrapException, c_last_exception) + c_last_exception) from rpython.flowspace.framestate import (FrameState, recursively_unflatten, - recursively_flatten) + recursively_flatten) from rpython.flowspace.specialcase import (rpython_print_item, - rpython_print_newline) + rpython_print_newline) + class FlowingError(Exception): """ Signals invalid RPython in the function being analysed""" @@ -107,13 +108,12 @@ # ____________________________________________________________ -class Recorder: - +class Recorder(object): def append(self, operation): raise NotImplementedError def guessbool(self, frame, w_condition, **kwds): - raise AssertionError, "cannot guessbool(%s)" % (w_condition,) + raise AssertionError("cannot guessbool(%s)" % (w_condition,)) class BlockRecorder(Recorder): @@ -212,11 +212,13 @@ # ____________________________________________________________ -_unary_ops = [('UNARY_POSITIVE', "pos"), +_unary_ops = [ + ('UNARY_POSITIVE', "pos"), ('UNARY_NEGATIVE', "neg"), ('UNARY_NOT', "not_"), ('UNARY_CONVERT', "repr"), - ('UNARY_INVERT', "invert"),] + ('UNARY_INVERT', "invert"), +] def unaryoperation(OPCODE, op): def UNARY_OP(self, *ignored): @@ -382,7 +384,7 @@ n -= 1 if n < 0: break - values_w[n] = self.locals_stack_w[base+n] + values_w[n] = self.locals_stack_w[base + n] return values_w def dropvalues(self, n): @@ -564,7 +566,7 @@ def replace_in_stack(self, oldvalue, newvalue): w_new = Constant(newvalue) stack_items_w = self.locals_stack_w - for i in range(self.valuestackdepth-1, self.pycode.co_nlocals-1, -1): + for i in range(self.valuestackdepth - 1, self.pycode.co_nlocals - 1, -1): w_v = stack_items_w[i] if isinstance(w_v, Constant): if w_v.value is oldvalue: @@ -665,9 +667,9 @@ raise FSException(space.w_TypeError, space.wrap("raise: no active exception to re-raise")) - w_value = w_traceback = space.w_None + w_value = space.w_None if nbargs >= 3: - w_traceback = self.popvalue() + self.popvalue() if nbargs >= 2: w_value = self.popvalue() if 1: @@ -960,7 +962,7 @@ def call_function(self, oparg, w_star=None, w_starstar=None): n_arguments = oparg & 0xff - n_keywords = (oparg>>8) & 0xff + n_keywords = (oparg >> 8) & 0xff if n_keywords: keywords = [None] * n_keywords keywords_w = [None] * n_keywords @@ -979,7 +981,7 @@ arguments = self.popvalues(n_arguments) args = ArgumentsForTranslation(self.space, arguments, keywords, keywords_w, w_star, w_starstar) - w_function = self.popvalue() + w_function = self.popvalue() w_result = self.space.call_args(w_function, args) self.pushvalue(w_result) @@ -1193,6 +1195,7 @@ """Signals a 'return' statement. Argument is the wrapped object to return.""" kind = 0x01 + def __init__(self, w_returnvalue): self.w_returnvalue = w_returnvalue @@ -1210,6 +1213,7 @@ """Signals an application-level exception (i.e. an OperationException).""" kind = 0x02 + def __init__(self, operr): self.operr = operr @@ -1240,6 +1244,7 @@ """Signals a 'continue' statement. Argument is the bytecode position of the beginning of the loop.""" kind = 0x08 + def __init__(self, jump_to): self.jump_to = jump_to diff --git a/rpython/flowspace/generator.py b/rpython/flowspace/generator.py --- a/rpython/flowspace/generator.py +++ b/rpython/flowspace/generator.py @@ -1,12 +1,11 @@ """Flow graph building for generators""" -from rpython.flowspace.model import Block, Link, SpaceOperation, checkgraph -from rpython.flowspace.model import Variable, Constant -from rpython.translator.unsimplify import insert_empty_startblock -from rpython.translator.unsimplify import split_block +from rpython.flowspace.argument import Signature +from rpython.flowspace.model import (Block, Link, SpaceOperation, Variable, + Constant, checkgraph) +from rpython.translator.unsimplify import insert_empty_startblock, split_block from rpython.translator.simplify import eliminate_empty_blocks, simplify_graph from rpython.tool.sourcetools import func_with_new_name -from rpython.flowspace.argument import Signature class AbstractPosition(object): @@ -113,7 +112,8 @@ mappings = [Entry] # stopblock = Block([]) - v0 = Variable(); v1 = Variable() + v0 = Variable() + v1 = Variable() stopblock.operations = [ SpaceOperation('simple_call', [Constant(StopIteration)], v0), SpaceOperation('type', [v0], v1), diff --git a/rpython/flowspace/model.py b/rpython/flowspace/model.py --- a/rpython/flowspace/model.py +++ b/rpython/flowspace/model.py @@ -4,6 +4,7 @@ # the below object/attribute model evolved from # a discussion in Berlin, 4th of october 2003 import py + from rpython.tool.uid import uid, Hashable from rpython.tool.sourcetools import PY_IDENTIFIER, nice_repr_for_func from rpython.rlib.rarithmetic import is_valid_int, r_longlong, r_ulonglong, r_uint @@ -180,9 +181,9 @@ class Block(object): __slots__ = """inputargs operations exitswitch exits blockcolor""".split() - + def __init__(self, inputargs): - self.inputargs = list(inputargs) # mixed list of variable/const XXX + self.inputargs = list(inputargs) # mixed list of variable/const XXX self.operations = [] # list of SpaceOperation(s) self.exitswitch = None # a variable or # Constant(last_exception), see below @@ -205,7 +206,7 @@ else: txt = "codeless block" return txt - + def __repr__(self): txt = "%s with %d exits" % (str(self), len(self.exits)) if self.exitswitch: @@ -241,7 +242,7 @@ def closeblock(self, *exits): assert self.exits == [], "block already closed" self.recloseblock(*exits) - + def recloseblock(self, *exits): for exit in exits: exit.prevblock = self @@ -274,7 +275,7 @@ def renamed(self): return self._name is not self.dummyname renamed = property(renamed) - + def __init__(self, name=None): self._name = self.dummyname self._nr = -1 @@ -341,7 +342,7 @@ self.offset = offset # offset in code string def __eq__(self, other): - return (self.__class__ is other.__class__ and + return (self.__class__ is other.__class__ and self.opname == other.opname and self.args == other.args and self.result == other.result) diff --git a/rpython/flowspace/specialcase.py b/rpython/flowspace/specialcase.py --- a/rpython/flowspace/specialcase.py +++ b/rpython/flowspace/specialcase.py @@ -20,8 +20,8 @@ elif opname == 'getattr' and len(args_w) == 3: return space.do_operation('simple_call', Constant(getattr), *args_w) else: - raise Exception, "should call %r with exactly %d arguments" % ( - fn, Arity[opname]) + raise Exception("should call %r with exactly %d arguments" % ( + fn, Arity[opname])) # completely replace the call with the underlying # operation and its limited implicit exceptions semantic return getattr(space, opname)(*args_w) @@ -79,4 +79,3 @@ locals: sc_locals} for fn in OperationName: SPECIAL_CASES[fn] = sc_operator - diff --git a/rpython/jit/metainterp/resume.py b/rpython/jit/metainterp/resume.py --- a/rpython/jit/metainterp/resume.py +++ b/rpython/jit/metainterp/resume.py @@ -1,19 +1,15 @@ -import sys, os -from rpython.jit.metainterp.history import Box, Const, ConstInt, getkind -from rpython.jit.metainterp.history import BoxInt, BoxPtr, BoxFloat -from rpython.jit.metainterp.history import INT, REF, FLOAT, HOLE -from rpython.jit.metainterp.history import AbstractDescr +from rpython.jit.codewriter.effectinfo import EffectInfo +from rpython.jit.metainterp import jitprof +from rpython.jit.metainterp.history import (Box, Const, ConstInt, getkind, + BoxInt, BoxPtr, BoxFloat, INT, REF, FLOAT, AbstractDescr) from rpython.jit.metainterp.resoperation import rop -from rpython.jit.metainterp import jitprof -from rpython.jit.codewriter.effectinfo import EffectInfo +from rpython.rlib import rarithmetic, rstack +from rpython.rlib.objectmodel import we_are_translated, specialize, compute_unique_id +from rpython.rlib.debug import (have_debug_prints, ll_assert, debug_start, + debug_stop, debug_print) +from rpython.rtyper import annlowlevel from rpython.rtyper.lltypesystem import lltype, llmemory, rffi, rstr -from rpython.rtyper import annlowlevel -from rpython.rlib import rarithmetic, rstack -from rpython.rlib.objectmodel import we_are_translated, specialize -from rpython.rlib.objectmodel import compute_unique_id -from rpython.rlib.debug import have_debug_prints, ll_assert -from rpython.rlib.debug import debug_start, debug_stop, debug_print -from rpython.jit.metainterp.optimize import InvalidLoop + # Logic to encode the chain of frames and the state of the boxes at a # guard operation, and to decode it again. This is a bit advanced, @@ -39,11 +35,11 @@ target = framestack[n] if n == 0: return - back = framestack[n-1] + back = framestack[n - 1] if target.parent_resumedata_frame_info_list is not None: assert target.parent_resumedata_frame_info_list.pc == back.pc return - _ensure_parent_resumedata(framestack, n-1) + _ensure_parent_resumedata(framestack, n - 1) target.parent_resumedata_frame_info_list = FrameInfo( back.parent_resumedata_frame_info_list, back.jitcode, @@ -106,8 +102,8 @@ def untag(value): value = rarithmetic.widen(value) - tagbits = value&TAGMASK - return value>>2, tagbits + tagbits = value & TAGMASK + return value >> 2, tagbits def tagged_eq(x, y): # please rpython :( @@ -126,8 +122,8 @@ TAGBOX = 2 TAGVIRTUAL = 3 -UNASSIGNED = tag(-1<<13, TAGBOX) -UNASSIGNEDVIRTUAL = tag(-1<<13, TAGVIRTUAL) +UNASSIGNED = tag(-1 << 13, TAGBOX) +UNASSIGNEDVIRTUAL = tag(-1 << 13, TAGVIRTUAL) NULLREF = tag(-1, TAGCONST) UNINITIALIZED = tag(-2, TAGCONST) # used for uninitialized string characters @@ -191,7 +187,7 @@ return numb, liveboxes.copy(), v numb1, liveboxes, v = self.number(optimizer, snapshot.prev) - n = len(liveboxes)-v + n = len(liveboxes) - v boxes = snapshot.boxes length = len(boxes) numb = lltype.malloc(NUMBERING, length) @@ -232,7 +228,7 @@ # returns a negative number if box in self.cached_boxes: num = self.cached_boxes[box] - boxes[-num-1] = box + boxes[-num - 1] = box else: boxes.append(box) num = -len(boxes) @@ -261,8 +257,8 @@ _frame_info_placeholder = (None, 0, 0) + class ResumeDataVirtualAdder(object): - def __init__(self, storage, memo): self.storage = storage self.memo = memo @@ -333,7 +329,7 @@ # collect liveboxes and virtuals n = len(liveboxes_from_env) - v - liveboxes = [None]*n + liveboxes = [None] * n self.vfieldboxes = {} for box, tagged in liveboxes_from_env.iteritems(): i, tagbits = untag(tagged) @@ -415,7 +411,7 @@ # xxx heuristic a bit out of thin air failargs_limit = memo.metainterp_sd.options.failargs_limit if nliveboxes > (failargs_limit // 2): - if nholes > nliveboxes//3: + if nholes > nliveboxes // 3: return True return False @@ -434,10 +430,10 @@ raise TagOverflow itemindex = rffi.cast(rffi.INT, itemindex) # - rd_pendingfields[i].lldescr = lldescr - rd_pendingfields[i].num = num + rd_pendingfields[i].lldescr = lldescr + rd_pendingfields[i].num = num rd_pendingfields[i].fieldnum = fieldnum - rd_pendingfields[i].itemindex= itemindex + rd_pendingfields[i].itemindex = itemindex self.storage.rd_pendingfields = rd_pendingfields def _gettagged(self, box): @@ -729,10 +725,10 @@ def _prepare_pendingfields(self, pendingfields): if pendingfields: for i in range(len(pendingfields)): - lldescr = pendingfields[i].lldescr - num = pendingfields[i].num + lldescr = pendingfields[i].lldescr + num = pendingfields[i].num fieldnum = pendingfields[i].fieldnum - itemindex= pendingfields[i].itemindex + itemindex = pendingfields[i].itemindex descr = annlowlevel.cast_base_ptr_to_instance(AbstractDescr, lldescr) struct = self.decode_ref(num) @@ -791,6 +787,7 @@ metainterp.framestack.reverse() return resumereader.liveboxes, virtualizable_boxes, virtualref_boxes + class ResumeDataBoxReader(AbstractResumeDataReader): unique_id = lambda: None @@ -946,8 +943,10 @@ def decode_int(self, tagged): return self.decode_box(tagged, INT) + def decode_ref(self, tagged): return self.decode_box(tagged, REF) + def decode_float(self, tagged): return self.decode_box(tagged, FLOAT) @@ -979,7 +978,7 @@ elif kind == REF: box = BoxPtr(self.cpu.get_latest_value_ref(self.deadframe, num)) elif kind == FLOAT: - box = BoxFloat(self.cpu.get_latest_value_float(self.deadframe,num)) + box = BoxFloat(self.cpu.get_latest_value_float(self.deadframe, num)) else: assert 0, "bad kind: %d" % ord(kind) self.liveboxes[num] = box @@ -987,17 +986,23 @@ def decode_box_of_type(self, TYPE, tagged): kind = getkind(TYPE) - if kind == 'int': kind = INT - elif kind == 'ref': kind = REF - elif kind == 'float': kind = FLOAT - else: raise AssertionError(kind) + if kind == 'int': + kind = INT + elif kind == 'ref': + kind = REF + elif kind == 'float': + kind = FLOAT + else: + raise AssertionError(kind) return self.decode_box(tagged, kind) decode_box_of_type._annspecialcase_ = 'specialize:arg(1)' def write_an_int(self, index, box): self.boxes_i[index] = box + def write_a_ref(self, index, box): self.boxes_r[index] = box + def write_a_float(self, index, box): self.boxes_f[index] = box @@ -1052,6 +1057,7 @@ resumereader.consume_vref_and_vable(vrefinfo, vinfo, ginfo) return resumereader.force_all_virtuals() + class ResumeDataDirectReader(AbstractResumeDataReader): unique_id = lambda: None virtual_default = lltype.nullptr(llmemory.GCREF.TO) @@ -1091,7 +1097,7 @@ assert (end & 1) == 0 for i in range(0, end, 2): virtual = self.decode_ref(numb.nums[i]) - vref = self.decode_ref(numb.nums[i+1]) + vref = self.decode_ref(numb.nums[i + 1]) # For each pair, we store the virtual inside the vref. vrefinfo.continue_tracing(vref, virtual) @@ -1134,7 +1140,8 @@ self.cur_numb = numb.prev if self.resume_after_guard_not_forced != 2: end_vref = self.consume_vable_info(vinfo, numb) - if ginfo is not None: end_vref -= 1 + if ginfo is not None: + end_vref -= 1 self.consume_virtualref_info(vrefinfo, numb, end_vref) def allocate_with_vtable(self, known_class): @@ -1319,10 +1326,10 @@ if storage.rd_pendingfields: debug_print('\tpending setfields') for i in range(len(storage.rd_pendingfields)): - lldescr = storage.rd_pendingfields[i].lldescr - num = storage.rd_pendingfields[i].num + lldescr = storage.rd_pendingfields[i].lldescr + num = storage.rd_pendingfields[i].num fieldnum = storage.rd_pendingfields[i].fieldnum - itemindex= storage.rd_pendingfields[i].itemindex + itemindex = storage.rd_pendingfields[i].itemindex debug_print("\t\t", str(lldescr), str(untag(num)), str(untag(fieldnum)), itemindex) debug_stop("jit-resume") diff --git a/rpython/jit/metainterp/test/test_resume.py b/rpython/jit/metainterp/test/test_resume.py --- a/rpython/jit/metainterp/test/test_resume.py +++ b/rpython/jit/metainterp/test/test_resume.py @@ -1,5 +1,6 @@ from __future__ import with_statement import py +import sys from rpython.rtyper.lltypesystem import lltype, llmemory, rffi from rpython.jit.metainterp.optimizeopt.optimizer import OptValue from rpython.jit.metainterp.optimizeopt.virtualize import VirtualValue, VArrayValue diff --git a/rpython/rlib/rarithmetic.py b/rpython/rlib/rarithmetic.py --- a/rpython/rlib/rarithmetic.py +++ b/rpython/rlib/rarithmetic.py @@ -157,7 +157,7 @@ def is_valid_int(r): if objectmodel.we_are_translated(): return isinstance(r, int) - return type(r) in (int, long, bool) and ( + return isinstance(r, (base_int, int, long, bool)) and ( -maxint - 1 <= r <= maxint) is_valid_int._annspecialcase_ = 'specialize:argtype(0)' diff --git a/rpython/translator/c/test/test_genc.py b/rpython/translator/c/test/test_genc.py --- a/rpython/translator/c/test/test_genc.py +++ b/rpython/translator/c/test/test_genc.py @@ -483,12 +483,16 @@ assert hasattr(ctypes.CDLL(str(t.driver.c_entryp)), 'foobar') def test_exportstruct(): + from rpython.translator.tool.cbuild import ExternalCompilationInfo from rpython.rlib.exports import export_struct def f(): return 42 FOO = Struct("FOO", ("field1", Signed)) foo = malloc(FOO, flavor="raw") foo.field1 = 43 + # maybe export_struct should add the struct name to eci automatically? + # https://bugs.pypy.org/issue1361 + foo._obj._compilation_info = ExternalCompilationInfo(export_symbols=['BarStruct']) export_struct("BarStruct", foo._obj) t = Translation(f, [], backend="c") t.annotate() diff --git a/rpython/translator/goal/old_queries.py b/rpython/translator/goal/old_queries.py deleted file mode 100644 --- a/rpython/translator/goal/old_queries.py +++ /dev/null @@ -1,483 +0,0 @@ -# functions to query information out of the translator and annotator from the debug prompt of translate -import types -import re - -import rpython.annotator.model as annmodel -import rpython.flowspace.model as flowmodel - - -class typerep(object): - - def __init__(self, x): - self.typ = getattr(x, '__class__', type(x)) - self.bound = None - if hasattr(x, 'im_self'): - self.bound = x.im_self is not None - elif hasattr(x, '__self__'): - self.bound = x.__self__ is not None - - def __hash__(self): - return hash(self.typ) - - def __cmp__(self, other): - return cmp((self.typ.__name__, self.bound, self.typ), (other.typ.__name__, other.bound, other.typ)) - - def __str__(self): - if self.bound is None: - s = self.typ.__name__ - elif self.bound: - s = 'bound-%s' % self.typ.__name__ - else: - s = 'unbound-%s' % self.typ.__name__ - - if self.typ.__module__ == '__builtin__': - s = "*%s*" % s - - return s - -def typereps(bunch): - t = dict.fromkeys([typerep(x) for x in bunch]).keys() - t.sort() - return t - -def roots(classes): - # find independent hierarchy roots in classes, - # preserve None if it's part of classes - work = list(classes) - res = [] - - notbound = False - - while None in work: - work.remove(None) - notbound = True - - if len(work) == 1: - return notbound, classes[0] - - while work: - cand = work.pop() - for cls in work: - if issubclass(cls, cand): - continue - if issubclass(cand, cls): - cand = cls - continue - res.append(cand) - work = [cls for cls in work if not issubclass(cls, cand)] - - - for x in res: - for y in res: - if x != y: - assert not issubclass(x, y), "%s %s %s" % (classes, x,y) - assert not issubclass(y, x), "%s %s %s" % (classes, x,y) - - return notbound, tuple(res) - -def callablereps(bunch): - callables = [func for clsdef, func in bunch] - classes = [clsdef and clsdef.cls for clsdef, func in bunch] - return roots(classes), tuple(typereps(callables)) - -def prettyfunc(func): - descr = "(%s:%s)" % (getattr(func, '__module__', None) or '?', func.func_code.co_firstlineno) - funcname = getattr(func, '__name__', None) or 'UNKNOWN' - cls = getattr(func, 'class_', None) - if cls: - funcname = "%s.%s" % (cls.__name__, funcname) - return descr+funcname - -def prettycallable((cls, obj)): - if cls is None or cls == (True, ()): - cls = None - else: - notbound = False - if isinstance(cls, tuple) and isinstance(cls[0], bool): - notbound, cls = cls - if isinstance(cls, tuple): - cls = "[%s]" % '|'.join([x.__name__ for x in cls]) - else: - cls = cls.__name__ - if notbound: - cls = "_|%s" % cls - - if isinstance(obj, types.FunctionType): - obj = prettyfunc(obj) - elif isinstance(obj, tuple): - obj = "[%s]" % '|'.join([str(x) for x in obj]) - else: - obj = str(obj) - if obj.startswith('<'): - obj = obj[1:-1] - - if cls is None: - return str(obj) - else: - return "%s::%s" % (cls, obj) - - -def prettybunch(bunch): - if len(bunch) == 1: - parts = ["one", iter(bunch).next()] - else: - parts = ["of type(s)"] + typereps(bunch) - return ' '.join(map(str, parts)) - -def pbcaccess(translator): - annotator = translator.annotator - for inf in annotator.getpbcaccesssets().root_info.itervalues(): - objs = inf.objects - print len(objs), prettybunch(objs), inf.attrs.keys() - -# PBCs -def pbcs(translator): - bk = translator.annotator.bookkeeper - xs = bk.pbccache.keys() - funcs = [x for x in xs if isinstance(x, types.FunctionType)] - staticmethods = [x for x in xs if isinstance(x, staticmethod)] - binstancemethods = [x for x in xs if isinstance(x, types.MethodType) and x.im_self] - ubinstancemethods = [x for x in xs if isinstance(x, types.MethodType) and not x.im_self] - typs = [x for x in xs if isinstance(x, (type, types.ClassType))] - rest = [x for x in xs if not isinstance(x, (types.FunctionType, staticmethod, types.MethodType, type, types.ClassType))] - for objs in (funcs, staticmethods, binstancemethods, ubinstancemethods, typs, rest): - print len(objs), prettybunch(objs) - -# mutable captured "constants") -def mutables(translator): - bk = translator.annotator.bookkeeper - xs = bk.seen_mutable.keys() - print len(xs), prettybunch(xs) - -def prettypatt(patts): - accum = [] - patts.sort() - for (sh_cnt, sh_ks, sh_st, sh_stst) in patts: - arg = [] - arg.append("+%d" % sh_cnt) - for kw in sh_ks: - arg.append("%s=" % kw) - if sh_st: - arg.append('*') - if sh_stst: - arg.append('**') - accum.append("(%s)" % ', '.join(arg)) - return ' '.join(accum) - -def pbccallsanity(translator): - callb = translator.annotator.getpbccallables() - bk = translator.annotator.bookkeeper - typs = [x for x in callb if isinstance(x, (type, types.ClassType))] - for t in typs: - assert len(callb[t]) == 1 - assert callb[t] == {(None,t): True} - print len(typs), "of ",prettycallable(callablereps([(None, Exception), (None, object)])) - ubm = [x for x in callb if isinstance(x, types.MethodType) and x.im_self is None] - assert len(ubm) == 0 - bm = [x for x in callb if isinstance(x, types.MethodType) and x.im_self is not None] - frompbc = 0 - notfrompbc = [] - for b in bm: - assert len(callb[b]) == 1 - assert callb[b] == {(None,b): True} - if b.im_class in bk.pbctypes or (b.im_class is None and b.im_self in bk.pbccache): - frompbc += 1 - else: - notfrompbc.append(b) - class A: - def m(): - pass - print frompbc, "of", prettycallable(callablereps([(None, A().m)])), "from PBCs" - print len(bm)-frompbc, "of", prettycallable(callablereps([(None, A().m)])), "not from PBCs" - if len(notfrompbc) < 40: - for b in notfrompbc: - print " "*4, prettycallable((None, b)) - fs = [x for x in callb if isinstance(x, types.FunctionType)] - assert len(fs) + len(typs) + frompbc + len(notfrompbc) == len(callb) - plain = [] - r = [] - for x in fs: - if len(callb[x]) == 1 and callb[x].keys()[0][0] == None: - r.extend(callb[x].keys()) - plain.append(x) - print len(plain), "of", prettycallable(callablereps(r)) - r = [] - for x in fs: - if x not in plain and len(callb[x]) == 1: - r.extend(callb[x].keys()) - print len(r), "of", prettycallable(callablereps(r)) - r = [] - b_nb = [] - for x in fs: - if len(callb[x]) == 2 and [1 for clsdef, f in callb[x].keys() if clsdef is None]: - r.extend(callb[x].keys()) - b_nb.append(x) - print len(r), "of", prettycallable(callablereps(r)) - print "- other -" - for x in fs: - if len(callb[x]) >= 2 and x not in b_nb: - print ' '.join([prettycallable((classdef and classdef.cls, func)) for (classdef,func) in callb[x].keys()]) - -def pretty_els(objs): - accum = [] - for classdef, obj in objs: - cls = classdef and classdef.cls - accum.append(prettycallable((cls, obj))) - els = ' '.join(accum) - if len(accum) == 1: - return els - else: - return "{%s}" % els - -def pbccall(translator): - fams = translator.annotator.getpbccallfamilies().root_info.itervalues() - one_pattern_fams = {} - rest = [] - for fam in fams: - shapes = fam.patterns - - if len(shapes) != 1: - rest.append((len(fam.objects), fam.objects, shapes.keys())) - else: - kinds = callablereps(fam.objects) - - flavor = tuple(kinds), shapes.keys()[0] - - cntrs = one_pattern_fams.setdefault(flavor, [0,0]) - cntrs[0] += 1 - cntrs[1] += len(fam.objects) - - def pretty_nfam(nfam): - if nfam == 1: - return "1 family" - else: - return "%d families" % nfam - - def pretty_nels(kinds, nels, nfam): - if nels == 1 or nels == nfam: - return "one %s" % prettycallable(kinds) - else: - return "in total %d %s" % (nels, prettycallable(kinds)) - - items = one_pattern_fams.items() - - items.sort(lambda a,b: cmp((a[0][1],a[1][1]), (b[0][1],b[1][1]))) # sort by pattern and then by els - - for (kinds, patt), (nfam, nels) in items: - print pretty_nfam(nfam), "with", pretty_nels(kinds, nels, nfam), "with one call-pattern:", prettypatt([patt]) - - print "- many patterns -" - - manycallb = False - rest.sort(lambda a,b: cmp((a[0],a[2]), (b[0],b[2]))) - - for n, objs, patts in rest: - if len(objs) > 1 and not manycallb: - manycallb = True - print " - many callables, many patterns -" - print "family of", pretty_els(objs), "with call-patterns:", prettypatt(patts) - -def pbcbmsanity(translator): - callb = translator.annotator.getpbccallables() - bk = translator.annotator.bookkeeper - bmeths = [x for x in callb if isinstance(x, types.MethodType) and x.im_self is not None] - print "%d bound-methods" % len(bmeths) - fams = translator.annotator.getpbccallfamilies() - plural_bm_families = {} - one_el = 0 - for bm in bmeths: - notpbc = bm.im_self not in bk.pbccache - freestanding = bm.im_func in callb - if notpbc or freestanding: - print "! %s," % bm, - if notpbc: - print "of non-PBC %s,", - if freestanding: - print "found freestanding too" - bm_fam = fams[(None, bm)] - if len(bm_fam.objects) == 1: - one_el += 1 - else: - plural_bm_families[bm_fam] = True - print "%d families of one bound-method" % one_el - print "%d families with more than just one bound-method" % len(plural_bm_families) - for bm_fam in plural_bm_families: - print pretty_els(bm_fam.objects) - return plural_bm_families - -class Counters(dict): - - def __getitem__(self, outcome): - if (isinstance(outcome, annmodel.SomeObject) or - isinstance(outcome, tuple) and outcome and - isinstance(outcome[0], annmodel.SomeObject)): - for k in self.iterkeys(): - if k == outcome: - outcome = k - break - else: - raise KeyError - return dict.__getitem__(self, outcome) - - def get(self, outcome, defl): - try: - return self[outcome] - except KeyError: - return defl - - def __setitem__(self, outcome, c): - if (isinstance(outcome, annmodel.SomeObject) or - isinstance(outcome, tuple) and outcome and - isinstance(outcome[0], annmodel.SomeObject)): - for k in self.iterkeys(): - if k == outcome: - outcome = k - break - return dict.__setitem__(self, outcome, c) - - -def keyrepr(k): - if isinstance(k, tuple): - return "(%s)" % ', '.join([keyrepr(x) for x in k]) - else: - return str(k) - -def statsfor(t, category): - stats = t.annotator.bookkeeper.stats - for_category = stats.classify[category] - print "%s total = %d" % (category, len(for_category)) - counters = Counters() - for pos, outcome in for_category.iteritems(): - counters[outcome] = counters.get(outcome, 0) + 1 - - w = max([len(keyrepr(o)) for o in counters.keys()])+1 - if w < 60: - for outcome, n in counters.iteritems(): From noreply at buildbot.pypy.org Mon Feb 25 14:12:13 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Mon, 25 Feb 2013 14:12:13 +0100 (CET) Subject: [pypy-commit] pypy default: define this at app-level like numpy Message-ID: <20130225131213.E60E71C008F@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61753:070c49864f5e Date: 2013-02-25 05:50 -0500 http://bitbucket.org/pypy/pypy/changeset/070c49864f5e/ Log: define this at app-level like numpy diff --git a/lib_pypy/numpypy/core/numeric.py b/lib_pypy/numpypy/core/numeric.py --- a/lib_pypy/numpypy/core/numeric.py +++ b/lib_pypy/numpypy/core/numeric.py @@ -1,4 +1,5 @@ __all__ = [ + 'ufunc', 'asanyarray', 'base_repr', 'array_repr', 'array_str', 'set_string_function', 'array_equal', 'asarray', 'outer', 'identity', 'little_endian', @@ -6,7 +7,7 @@ ] from _numpypy import array, ndarray, int_, float_, bool_, flexible #, complex_# , longlong -from _numpypy import concatenate +from _numpypy import concatenate, sin from .fromnumeric import any import sys import multiarray @@ -14,6 +15,8 @@ from umath import * from numpypy.core.arrayprint import array2string +ufunc = type(sin) + def extend_all(module): adict = {} for a in __all__: diff --git a/pypy/module/micronumpy/__init__.py b/pypy/module/micronumpy/__init__.py --- a/pypy/module/micronumpy/__init__.py +++ b/pypy/module/micronumpy/__init__.py @@ -8,7 +8,6 @@ interpleveldefs = { 'ndarray': 'interp_numarray.W_NDimArray', 'dtype': 'interp_dtype.W_Dtype', - 'ufunc': 'interp_ufuncs.W_Ufunc', 'array': 'interp_numarray.array', 'zeros': 'interp_numarray.zeros', diff --git a/pypy/module/micronumpy/test/test_ufuncs.py b/pypy/module/micronumpy/test/test_ufuncs.py --- a/pypy/module/micronumpy/test/test_ufuncs.py +++ b/pypy/module/micronumpy/test/test_ufuncs.py @@ -16,7 +16,7 @@ cls.w_isWindows = cls.space.wrap(os.name == 'nt') def test_ufunc_instance(self): - from _numpypy import add, ufunc + from numpypy import add, ufunc assert isinstance(add, ufunc) assert repr(add) == "" From noreply at buildbot.pypy.org Mon Feb 25 14:12:15 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Mon, 25 Feb 2013 14:12:15 +0100 (CET) Subject: [pypy-commit] pypy cleanup-numpypy-namespace: branch to cleanup numpypy namespaces Message-ID: <20130225131215.435D01C008F@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: cleanup-numpypy-namespace Changeset: r61754:8bc76bcff4cb Date: 2013-02-25 05:42 -0500 http://bitbucket.org/pypy/pypy/changeset/8bc76bcff4cb/ Log: branch to cleanup numpypy namespaces diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst --- a/pypy/doc/whatsnew-head.rst +++ b/pypy/doc/whatsnew-head.rst @@ -75,3 +75,6 @@ .. branch: enumerate-rstr Support enumerate() over rstr types. + +.. branch: cleanup-numpypy-namespace +Cleanup _numpypy and numpypy namespaces to more closely resemble numpy. From noreply at buildbot.pypy.org Mon Feb 25 14:12:16 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Mon, 25 Feb 2013 14:12:16 +0100 (CET) Subject: [pypy-commit] pypy cleanup-numpypy-namespace: split _numpypy into submodules Message-ID: <20130225131216.6FC611C008F@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: cleanup-numpypy-namespace Changeset: r61755:b8c9382cbad4 Date: 2013-02-25 08:04 -0500 http://bitbucket.org/pypy/pypy/changeset/b8c9382cbad4/ Log: split _numpypy into submodules diff --git a/pypy/module/micronumpy/__init__.py b/pypy/module/micronumpy/__init__.py --- a/pypy/module/micronumpy/__init__.py +++ b/pypy/module/micronumpy/__init__.py @@ -2,9 +2,8 @@ from pypy.module.micronumpy.interp_boxes import long_double_size, ENABLED_LONG_DOUBLE -class Module(MixedModule): - applevel_name = '_numpypy' - +class MultiArrayModule(MixedModule): + appleveldefs = {'arange': 'app_numpy.arange'} interpleveldefs = { 'ndarray': 'interp_numarray.W_NDimArray', 'dtype': 'interp_dtype.W_Dtype', @@ -23,7 +22,12 @@ 'set_string_function': 'appbridge.set_string_function', 'typeinfo': 'interp_dtype.get_dtype_cache(space).w_typeinfo', + } + +class NumericTypesModule(MixedModule): + appleveldefs = {} + interpleveldefs = { 'generic': 'interp_boxes.W_GenericBox', 'number': 'interp_boxes.W_NumberBox', 'integer': 'interp_boxes.W_IntegerBox', @@ -67,7 +71,30 @@ 'complex128': 'interp_boxes.W_Complex128Box', 'complex64': 'interp_boxes.W_Complex64Box', } + if ENABLED_LONG_DOUBLE: + long_double_dtypes = [ + ('longdouble', 'interp_boxes.W_LongDoubleBox'), + ('longfloat', 'interp_boxes.W_LongDoubleBox'), + ('clongdouble', 'interp_boxes.W_CLongDoubleBox'), + ('clongfloat', 'interp_boxes.W_CLongDoubleBox'), + ] + if long_double_size == 16: + long_double_dtypes += [ + ('float128', 'interp_boxes.W_Float128Box'), + ('complex256', 'interp_boxes.W_Complex256Box'), + ] + elif long_double_size == 12: + long_double_dtypes += [ + ('float96', 'interp_boxes.W_Float96Box'), + ('complex192', 'interp_boxes.W_Complex192Box'), + ] + for dt, box in long_double_dtypes: + interpleveldefs[dt] = box + +class UMathModule(MixedModule): + appleveldefs = {} + interpleveldefs = {} # ufuncs for exposed, impl in [ ("absolute", "absolute"), @@ -149,35 +176,13 @@ ]: interpleveldefs[exposed] = "interp_ufuncs.get(space).%s" % impl - appleveldefs = { - 'arange': 'app_numpy.arange', + +class Module(MixedModule): + applevel_name = '_numpypy' + appleveldefs = {} + interpleveldefs = {} + submodules = { + 'multiarray': MultiArrayModule, + 'numerictypes': NumericTypesModule, + 'umath': UMathModule, } - def setup_after_space_initialization(self): - space = self.space - all_list = sorted(Module.interpleveldefs.keys() + \ - Module.appleveldefs.keys()) - # found by set(numpypy.__all__) - set(numpy.__all__) - all_list.remove('set_string_function') - all_list.remove('typeinfo') - w_all = space.wrap(all_list) - space.setitem(self.w_dict, space.new_interned_str('__all__'), w_all) - -if ENABLED_LONG_DOUBLE: - long_double_dtypes = [ - ('longdouble', 'interp_boxes.W_LongDoubleBox'), - ('longfloat', 'interp_boxes.W_LongDoubleBox'), - ('clongdouble', 'interp_boxes.W_CLongDoubleBox'), - ('clongfloat', 'interp_boxes.W_CLongDoubleBox'), - ] - if long_double_size == 16: - long_double_dtypes += [ - ('float128', 'interp_boxes.W_Float128Box'), - ('complex256', 'interp_boxes.W_Complex256Box'), - ] - elif long_double_size == 12: - long_double_dtypes += [ - ('float96', 'interp_boxes.W_Float96Box'), - ('complex192', 'interp_boxes.W_Complex192Box'), - ] - for dt, box in long_double_dtypes: - Module.interpleveldefs[dt] = box diff --git a/pypy/module/micronumpy/app_numpy.py b/pypy/module/micronumpy/app_numpy.py --- a/pypy/module/micronumpy/app_numpy.py +++ b/pypy/module/micronumpy/app_numpy.py @@ -10,9 +10,9 @@ stop = start start = 0 if dtype is None: - test = _numpypy.array([start, stop, step, 0]) + test = _numpypy.multiarray.array([start, stop, step, 0]) dtype = test.dtype - arr = _numpypy.zeros(int(math.ceil((stop - start) / step)), dtype=dtype) + arr = _numpypy.multiarray.zeros(int(math.ceil((stop - start) / step)), dtype=dtype) i = start for j in range(arr.size): arr[j] = i From noreply at buildbot.pypy.org Mon Feb 25 14:12:17 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Mon, 25 Feb 2013 14:12:17 +0100 (CET) Subject: [pypy-commit] pypy cleanup-numpypy-namespace: update app-level code for _numpypy submodules Message-ID: <20130225131217.9DE151C008F@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: cleanup-numpypy-namespace Changeset: r61756:5369e4d98df9 Date: 2013-02-25 07:07 -0500 http://bitbucket.org/pypy/pypy/changeset/5369e4d98df9/ Log: update app-level code for _numpypy submodules diff --git a/lib_pypy/numpypy/core/__init__.py b/lib_pypy/numpypy/core/__init__.py --- a/lib_pypy/numpypy/core/__init__.py +++ b/lib_pypy/numpypy/core/__init__.py @@ -1,5 +1,3 @@ -import _numpypy -from _numpypy import * import numeric from numeric import * import fromnumeric @@ -8,10 +6,9 @@ from shape_base import * from fromnumeric import amax as max, amin as min -from _numpypy import absolute as abs +from numeric import absolute as abs __all__ = [] -__all__ += _numpypy.__all__ __all__ += numeric.__all__ __all__ += fromnumeric.__all__ __all__ += shape_base.__all__ diff --git a/lib_pypy/numpypy/core/_methods.py b/lib_pypy/numpypy/core/_methods.py --- a/lib_pypy/numpypy/core/_methods.py +++ b/lib_pypy/numpypy/core/_methods.py @@ -1,11 +1,9 @@ # Array methods which are called by the both the C-code for the method # and the Python code for the NumPy-namespace function -#from numpy.core import multiarray as mu -#from numpy.core import umath as um -import _numpypy as mu -um = mu -from numpy.core.numeric import asanyarray +import multiarray as mu +import umath as um +from numeric import asanyarray def _amax(a, axis=None, out=None, keepdims=False): return um.maximum.reduce(a, axis=axis, diff --git a/lib_pypy/numpypy/core/arrayprint.py b/lib_pypy/numpypy/core/arrayprint.py --- a/lib_pypy/numpypy/core/arrayprint.py +++ b/lib_pypy/numpypy/core/arrayprint.py @@ -13,9 +13,9 @@ # and by Travis Oliphant 2005-8-22 for numpy import sys -import _numpypy as _nt -from _numpypy import maximum, minimum, absolute, not_equal, isnan, isinf -#from _numpypy import format_longfloat, datetime_as_string, datetime_data +import numerictypes as _nt +from umath import maximum, minimum, absolute, not_equal, isnan, isinf +#from multiarray import format_longfloat, datetime_as_string, datetime_data from fromnumeric import ravel diff --git a/lib_pypy/numpypy/core/multiarray.py b/lib_pypy/numpypy/core/multiarray.py --- a/lib_pypy/numpypy/core/multiarray.py +++ b/lib_pypy/numpypy/core/multiarray.py @@ -1,1 +1,1 @@ -from _numpypy import set_string_function, typeinfo +from _numpypy.multiarray import * diff --git a/lib_pypy/numpypy/core/numeric.py b/lib_pypy/numpypy/core/numeric.py --- a/lib_pypy/numpypy/core/numeric.py +++ b/lib_pypy/numpypy/core/numeric.py @@ -1,21 +1,20 @@ __all__ = [ - 'ufunc', - 'asanyarray', 'base_repr', + 'newaxis', 'ufunc', + 'asarray', 'asanyarray', 'base_repr', 'array_repr', 'array_str', 'set_string_function', - 'array_equal', 'asarray', 'outer', 'identity', 'little_endian', + 'array_equal', 'outer', 'identity', 'little_endian', 'Inf', 'inf', 'infty', 'Infinity', 'nan', 'NaN', 'False_', 'True_', ] -from _numpypy import array, ndarray, int_, float_, bool_, flexible #, complex_# , longlong -from _numpypy import concatenate, sin -from .fromnumeric import any import sys import multiarray +from multiarray import * +del set_string_function +del typeinfo import umath from umath import * -from numpypy.core.arrayprint import array2string - -ufunc = type(sin) +import numerictypes +from numerictypes import * def extend_all(module): adict = {} @@ -29,9 +28,13 @@ if a not in adict: __all__.append(a) +extend_all(multiarray) +__all__.remove('typeinfo') extend_all(umath) +extend_all(numerictypes) newaxis = None +ufunc = type(sin) # XXX this file to be reviewed def seterr(**args): @@ -142,6 +145,10 @@ res.append('-') return ''.join(reversed(res or '0')) + +#Use numarray's printing function +from arrayprint import array2string + _typelessdata = [int_, float_]#, complex_] # XXX #if issubclass(intc, int): @@ -327,6 +334,11 @@ else: return multiarray.set_string_function(f, repr) +set_string_function(array_str, 0) +set_string_function(array_repr, 1) + +little_endian = (sys.byteorder == 'little') + def array_equal(a1, a2): """ True if two arrays have the same shape and elements, False otherwise. @@ -438,16 +450,6 @@ """ return array(a, dtype, copy=False, order=order) -set_string_function(array_str, 0) -set_string_function(array_repr, 1) - -little_endian = (sys.byteorder == 'little') - -Inf = inf = infty = Infinity = PINF -nan = NaN = NAN -False_ = bool_(False) -True_ = bool_(True) - def outer(a,b): """ Compute the outer product of two vectors. @@ -551,3 +553,12 @@ """ from numpy import eye return eye(n, dtype=dtype) + +Inf = inf = infty = Infinity = PINF +nan = NaN = NAN +False_ = bool_(False) +True_ = bool_(True) + +import fromnumeric +from fromnumeric import * +extend_all(fromnumeric) diff --git a/lib_pypy/numpypy/core/shape_base.py b/lib_pypy/numpypy/core/shape_base.py --- a/lib_pypy/numpypy/core/shape_base.py +++ b/lib_pypy/numpypy/core/shape_base.py @@ -1,6 +1,6 @@ __all__ = ['atleast_1d', 'atleast_2d', 'atleast_3d', 'vstack', 'hstack'] -import _numpypy +import numeric as _nx from numeric import array, asanyarray, newaxis def atleast_1d(*arys): @@ -223,7 +223,7 @@ [4]]) """ - return _numpypy.concatenate(map(atleast_2d,tup),0) + return _nx.concatenate(map(atleast_2d,tup),0) def hstack(tup): """ @@ -270,6 +270,6 @@ arrs = map(atleast_1d,tup) # As a special case, dimension 0 of 1-dimensional arrays is "horizontal" if arrs[0].ndim == 1: - return _numpypy.concatenate(arrs, 0) + return _nx.concatenate(arrs, 0) else: - return _numpypy.concatenate(arrs, 1) + return _nx.concatenate(arrs, 1) diff --git a/lib_pypy/numpypy/core/umath.py b/lib_pypy/numpypy/core/umath.py --- a/lib_pypy/numpypy/core/umath.py +++ b/lib_pypy/numpypy/core/umath.py @@ -1,3 +1,5 @@ +from _numpypy.umath import * + import math e = math.e pi = math.pi diff --git a/lib_pypy/numpypy/lib/function_base.py b/lib_pypy/numpypy/lib/function_base.py --- a/lib_pypy/numpypy/lib/function_base.py +++ b/lib_pypy/numpypy/lib/function_base.py @@ -1,6 +1,6 @@ __all__ = ['average'] -from _numpypy import array +from ..core.numeric import array def average(a): # This implements a weighted average, for now we don't implement the diff --git a/lib_pypy/numpypy/lib/shape_base.py b/lib_pypy/numpypy/lib/shape_base.py --- a/lib_pypy/numpypy/lib/shape_base.py +++ b/lib_pypy/numpypy/lib/shape_base.py @@ -1,7 +1,7 @@ __all__ = ['dstack'] -import numpypy.core.numeric as _nx -from numpypy.core import atleast_3d +from ..core import numeric as _nx +from ..core import atleast_3d def dstack(tup): """ diff --git a/lib_pypy/numpypy/lib/twodim_base.py b/lib_pypy/numpypy/lib/twodim_base.py --- a/lib_pypy/numpypy/lib/twodim_base.py +++ b/lib_pypy/numpypy/lib/twodim_base.py @@ -1,6 +1,6 @@ __all__ = ['eye'] -from _numpypy import zeros +from ..core.numeric import zeros def eye(N, M=None, k=0, dtype=float): """ From noreply at buildbot.pypy.org Mon Feb 25 14:12:18 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Mon, 25 Feb 2013 14:12:18 +0100 (CET) Subject: [pypy-commit] pypy cleanup-numpypy-namespace: update numpypy tests for submodules Message-ID: <20130225131218.E15DC1C008F@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: cleanup-numpypy-namespace Changeset: r61757:a3aa452cf995 Date: 2013-02-25 07:29 -0500 http://bitbucket.org/pypy/pypy/changeset/a3aa452cf995/ Log: update numpypy tests for submodules diff too long, truncating to 2000 out of 3297 lines diff --git a/pypy/module/micronumpy/test/test_arrayops.py b/pypy/module/micronumpy/test/test_arrayops.py --- a/pypy/module/micronumpy/test/test_arrayops.py +++ b/pypy/module/micronumpy/test/test_arrayops.py @@ -3,26 +3,26 @@ class AppTestNumSupport(BaseNumpyAppTest): def test_where(self): - from _numpypy import where, ones, zeros, array + from numpypy import where, ones, zeros, array a = [1, 2, 3, 0, -3] a = where(array(a) > 0, ones(5), zeros(5)) assert (a == [1, 1, 1, 0, 0]).all() def test_where_differing_dtypes(self): - from _numpypy import array, ones, zeros, where + from numpypy import array, ones, zeros, where a = [1, 2, 3, 0, -3] a = where(array(a) > 0, ones(5, dtype=int), zeros(5, dtype=float)) assert (a == [1, 1, 1, 0, 0]).all() def test_where_broadcast(self): - from _numpypy import array, where + from numpypy import array, where a = where(array([[1, 2, 3], [4, 5, 6]]) > 3, [1, 1, 1], 2) assert (a == [[2, 2, 2], [1, 1, 1]]).all() a = where(True, [1, 1, 1], 2) assert (a == [1, 1, 1]).all() def test_where_errors(self): - from _numpypy import where, array + from numpypy import where, array raises(ValueError, "where([1, 2, 3], [3, 4, 5])") raises(ValueError, "where([1, 2, 3], [3, 4, 5], [6, 7])") assert where(True, 1, 2) == array(1) @@ -35,7 +35,7 @@ # xxx def test_where_invalidates(self): - from _numpypy import where, ones, zeros, array + from numpypy import where, ones, zeros, array a = array([1, 2, 3, 0, -3]) b = where(a > 0, ones(5), zeros(5)) a[0] = 0 @@ -43,7 +43,7 @@ def test_dot(self): - from _numpypy import array, dot, arange + from numpypy import array, dot, arange a = array(range(5)) assert dot(a, a) == 30.0 @@ -74,7 +74,7 @@ assert (dot([[1,2],[3,4]],[5,6]) == [17, 39]).all() def test_dot_constant(self): - from _numpypy import array, dot + from numpypy import array, dot a = array(range(5)) b = a.dot(2.5) for i in xrange(5): @@ -85,19 +85,19 @@ assert c == 12.0 def test_choose_basic(self): - from _numpypy import array + from numpypy import array a, b, c = array([1, 2, 3]), array([4, 5, 6]), array([7, 8, 9]) r = array([2, 1, 0]).choose([a, b, c]) assert (r == [7, 5, 3]).all() def test_choose_broadcast(self): - from _numpypy import array + from numpypy import array a, b, c = array([1, 2, 3]), [4, 5, 6], 13 r = array([2, 1, 0]).choose([a, b, c]) assert (r == [13, 5, 3]).all() def test_choose_out(self): - from _numpypy import array + from numpypy import array a, b, c = array([1, 2, 3]), [4, 5, 6], 13 r = array([2, 1, 0]).choose([a, b, c], out=None) assert (r == [13, 5, 3]).all() @@ -107,7 +107,7 @@ assert (a == [13, 5, 3]).all() def test_choose_modes(self): - from _numpypy import array + from numpypy import array a, b, c = array([1, 2, 3]), [4, 5, 6], 13 raises(ValueError, "array([3, 1, 0]).choose([a, b, c])") raises(ValueError, "array([3, 1, 0]).choose([a, b, c], 'raises')") @@ -119,13 +119,13 @@ assert (r == [4, 5, 3]).all() def test_choose_dtype(self): - from _numpypy import array + from numpypy import array a, b, c = array([1.2, 2, 3]), [4, 5, 6], 13 r = array([2, 1, 0]).choose([a, b, c]) assert r.dtype == float def test_choose_dtype_out(self): - from _numpypy import array + from numpypy import array a, b, c = array([1, 2, 3]), [4, 5, 6], 13 x = array([0, 0, 0], dtype='i2') r = array([2, 1, 0]).choose([a, b, c], out=x) diff --git a/pypy/module/micronumpy/test/test_complex.py b/pypy/module/micronumpy/test/test_complex.py --- a/pypy/module/micronumpy/test/test_complex.py +++ b/pypy/module/micronumpy/test/test_complex.py @@ -132,13 +132,13 @@ cls.w_c_pow = cls.space.wrap(interp2app(cls_c_pow)) def test_fabs(self): - from _numpypy import fabs, complex128 + from numpypy import fabs, complex128 a = complex128(complex(-5., 5.)) raises(TypeError, fabs, a) def test_fmax(self): - from _numpypy import fmax, array + from numpypy import fmax, array nnan, nan, inf, ninf = float('-nan'), float('nan'), float('inf'), float('-inf') a = array((complex(ninf, 10), complex(10, ninf), complex( inf, 10), complex(10, inf), @@ -165,7 +165,7 @@ assert (fmax(a, b) == res).all() def test_fmin(self): - from _numpypy import fmin, array + from numpypy import fmin, array nnan, nan, inf, ninf = float('-nan'), float('nan'), float('inf'), float('-inf') a = array((complex(ninf, 10), complex(10, ninf), complex( inf, 10), complex(10, inf), @@ -192,14 +192,14 @@ assert (fmin(a, b) == res).all() def test_signbit(self): - from _numpypy import signbit + from numpypy import signbit raises(TypeError, signbit, complex(1,1)) def test_reciprocal(self): - from _numpypy import array, reciprocal, complex64, complex128 + from numpypy import array, reciprocal, complex64, complex128 c_and_relerr = [(complex64, 2e-7), (complex128, 2e-15)] try: - from _numpypy import clongdouble + from numpypy import clongdouble c_and_relerr.append((clongdouble, 2e-30)) except: pass # no longdouble yet @@ -224,23 +224,23 @@ assert (a[0].imag - e.imag) < rel_err def test_floorceiltrunc(self): - from _numpypy import array, floor, ceil, trunc + from numpypy import array, floor, ceil, trunc a = array([ complex(-1.4, -1.4), complex(-1.5, -1.5)]) raises(TypeError, floor, a) raises(TypeError, ceil, a) raises(TypeError, trunc, a) def test_copysign(self): - from _numpypy import copysign, complex128 + from numpypy import copysign, complex128 a = complex128(complex(-5., 5.)) b = complex128(complex(0., 0.)) raises(TypeError, copysign, a, b) def test_exp2(self): - from _numpypy import array, exp2, complex128, complex64 + from numpypy import array, exp2, complex128, complex64 c_and_relerr = [(complex64, 2e-7), (complex128, 2e-15)] try: - from _numpypy import clongdouble + from numpypy import clongdouble c_and_relerr.append((clongdouble, 2e-30)) except: pass # no longdouble yet @@ -279,7 +279,7 @@ def test_expm1(self): import math, cmath - from _numpypy import array, expm1, complex128, complex64 + from numpypy import array, expm1, complex128, complex64 inf = float('inf') ninf = -float('inf') nan = float('nan') @@ -318,7 +318,7 @@ self.rAlmostEqual(t1, t2, rel_err=rel_err, msg=msg) def test_not_complex(self): - from _numpypy import (radians, deg2rad, degrees, rad2deg, + from numpypy import (radians, deg2rad, degrees, rad2deg, isneginf, isposinf, logaddexp, logaddexp2, fmod, arctan2) raises(TypeError, radians, complex(90,90)) @@ -333,7 +333,7 @@ raises (TypeError, fmod, complex(90,90), 3) def test_isnan_isinf(self): - from _numpypy import isnan, isinf, array + from numpypy import isnan, isinf, array assert (isnan(array([0.2+2j, complex(float('inf'),0), complex(0,float('inf')), complex(0,float('nan')), complex(float('nan'), 0)], dtype=complex)) == \ @@ -346,7 +346,7 @@ def test_square(self): - from _numpypy import square + from numpypy import square assert square(complex(3, 4)) == complex(3,4) * complex(3, 4) def test_power_complex(self): @@ -355,7 +355,7 @@ nan = float('nan') cmpl = complex from math import copysign - from _numpypy import power, array, complex128, complex64 + from numpypy import power, array, complex128, complex64 # note: in some settings (namely a x86-32 build without the JIT), # gcc optimizes the code in rlib.rcomplex.c_pow() to not truncate # the 10-byte values down to 8-byte values. It ends up with more @@ -392,7 +392,7 @@ self.rAlmostEqual(t1, t2, rel_err=rel_err, msg=msg) def test_conjugate(self): - from _numpypy import conj, conjugate, complex128, complex64 + from numpypy import conj, conjugate, complex128, complex64 import numpypy as np c0 = complex128(complex(2.5, 0)) @@ -416,7 +416,7 @@ def test_logn(self): import math, cmath # log and log10 are tested in math (1:1 from rcomplex) - from _numpypy import log2, array, complex128, complex64, log1p + from numpypy import log2, array, complex128, complex64, log1p inf = float('inf') ninf = -float('inf') nan = float('nan') @@ -473,7 +473,7 @@ self.rAlmostEqual(t1, t2, rel_err=rel_err, msg=msg) def test_logical_ops(self): - from _numpypy import logical_and, logical_or, logical_xor, logical_not + from numpypy import logical_and, logical_or, logical_xor, logical_not c1 = complex(1, 1) c3 = complex(3, 0) @@ -487,7 +487,7 @@ assert (logical_not([c1, c0]) == [False, True]).all() def test_minimum(self): - from _numpypy import array, minimum + from numpypy import array, minimum a = array([-5.0+5j, -5.0-5j, -0.0-10j, 1.0+10j]) b = array([ 3.0+10.0j, 3.0, -2.0+2.0j, -3.0+4.0j]) @@ -496,7 +496,7 @@ assert c[i] == min(a[i], b[i]) def test_maximum(self): - from _numpypy import array, maximum + from numpypy import array, maximum a = array([-5.0+5j, -5.0-5j, -0.0-10j, 1.0+10j]) b = array([ 3.0+10.0j, 3.0, -2.0+2.0j, -3.0+4.0j]) @@ -505,14 +505,14 @@ assert c[i] == max(a[i], b[i]) def test_basic(self): - from _numpypy import (complex128, complex64, add, array, dtype, + from numpypy import (complex128, complex64, add, array, dtype, subtract as sub, multiply, divide, negative, absolute as abs, floor_divide, real, imag, sign) - from _numpypy import (equal, not_equal, greater, greater_equal, less, + from numpypy import (equal, not_equal, greater, greater_equal, less, less_equal, isnan) complex_dtypes = [complex64, complex128] try: - from _numpypy import clongfloat + from numpypy import clongfloat complex_dtypes.append(clongfloat) except: pass @@ -588,15 +588,15 @@ inf_c = complex_(complex(float('inf'), 0.)) assert repr(abs(inf_c)) == 'inf' assert repr(abs(complex(float('nan'), float('nan')))) == 'nan' - # numpy actually raises an AttributeError, - # but _numpypy raises a TypeError + # numpy actually raises an AttributeError, + # but numpypy raises a TypeError raises((TypeError, AttributeError), 'c2.real = 10.') raises((TypeError, AttributeError), 'c2.imag = 10.') assert(real(c2) == 3.0) assert(imag(c2) == 4.0) def test_conj(self): - from _numpypy import array + from numpypy import array a = array([1 + 2j, 1 - 2j]) assert (a.conj() == [1 - 2j, 1 + 2j]).all() @@ -605,7 +605,7 @@ if self.isWindows: skip('windows does not support c99 complex') import sys - import _numpypy as np + import numpypy as np rAlmostEqual = self.rAlmostEqual for complex_, abs_err, testcases in (\ diff --git a/pypy/module/micronumpy/test/test_dtypes.py b/pypy/module/micronumpy/test/test_dtypes.py --- a/pypy/module/micronumpy/test/test_dtypes.py +++ b/pypy/module/micronumpy/test/test_dtypes.py @@ -17,7 +17,7 @@ class AppTestDtypes(BaseAppTestDtypes): def test_dtype(self): - from _numpypy import dtype + from numpypy import dtype d = dtype('?') assert d.num == 0 @@ -36,7 +36,7 @@ raises(KeyError, 'dtype(int)["asdasd"]') def test_dtype_eq(self): - from _numpypy import dtype + from numpypy import dtype assert dtype("int8") == "int8" assert "int8" == dtype("int8") @@ -44,7 +44,7 @@ assert dtype(bool) == bool def test_dtype_with_types(self): - from _numpypy import dtype + from numpypy import dtype assert dtype(bool).num == 0 if self.ptr_size == 4: @@ -66,13 +66,13 @@ assert dtype(float).num == 12 def test_array_dtype_attr(self): - from _numpypy import array, dtype + from numpypy import array, dtype a = array(range(5), long) assert a.dtype is dtype(long) def test_repr_str(self): - from _numpypy import dtype + from numpypy import dtype assert '.dtype' in repr(dtype) d = dtype('?') @@ -80,8 +80,7 @@ assert str(d) == "bool" def test_bool_array(self): - from _numpypy import array - from numpypy import False_, True_ + from numpypy import array, False_, True_ a = array([0, 1, 2, 2.5], dtype='?') assert a[0] is False_ @@ -89,8 +88,7 @@ assert a[i] is True_ def test_copy_array_with_dtype(self): - from _numpypy import array, longlong - from numpypy import False_ + from numpypy import array, longlong, False_ a = array([0, 1, 2, 3], dtype=long) # int on 64-bit, long in 32-bit @@ -104,37 +102,35 @@ assert b[0] is False_ def test_zeros_bool(self): - from _numpypy import zeros - from numpypy import False_ + from numpypy import zeros, False_ a = zeros(10, dtype=bool) for i in range(10): assert a[i] is False_ def test_ones_bool(self): - from _numpypy import ones - from numpypy import True_ + from numpypy import ones, True_ a = ones(10, dtype=bool) for i in range(10): assert a[i] is True_ def test_zeros_long(self): - from _numpypy import zeros, longlong + from numpypy import zeros, longlong a = zeros(10, dtype=long) for i in range(10): assert isinstance(a[i], longlong) assert a[1] == 0 def test_ones_long(self): - from _numpypy import ones, longlong + from numpypy import ones, longlong a = ones(10, dtype=long) for i in range(10): assert isinstance(a[i], longlong) assert a[1] == 1 def test_overflow(self): - from _numpypy import array, dtype + from numpypy import array, dtype assert array([128], 'b')[0] == -128 assert array([256], 'B')[0] == 0 assert array([32768], 'h')[0] == -32768 @@ -146,7 +142,7 @@ raises(OverflowError, "array([2**64], 'Q')") def test_bool_binop_types(self): - from _numpypy import array, dtype + from numpypy import array, dtype types = [ '?', 'b', 'B', 'h', 'H', 'i', 'I', 'l', 'L', 'q', 'Q', 'f', 'd', 'e' @@ -156,7 +152,7 @@ assert (a + array([0], t)).dtype is dtype(t) def test_binop_types(self): - from _numpypy import array, dtype + from numpypy import array, dtype tests = [('b','B','h'), ('b','h','h'), ('b','H','i'), ('b','i','i'), ('b','l','l'), ('b','q','q'), ('b','Q','d'), ('B','h','h'), ('B','H','H'), ('B','i','i'), ('B','I','I'), ('B','l','l'), @@ -180,7 +176,7 @@ assert (d1, d2) == (d1, d2) and d3 is dtype(dout) def test_add_int8(self): - from _numpypy import array, dtype + from numpypy import array, dtype a = array(range(5), dtype="int8") b = a + a @@ -189,7 +185,7 @@ assert b[i] == i * 2 def test_add_int16(self): - from _numpypy import array, dtype + from numpypy import array, dtype a = array(range(5), dtype="int16") b = a + a @@ -198,7 +194,7 @@ assert b[i] == i * 2 def test_add_uint32(self): - from _numpypy import array, dtype + from numpypy import array, dtype a = array(range(5), dtype="I") b = a + a @@ -207,49 +203,49 @@ assert b[i] == i * 2 def test_shape(self): - from _numpypy import dtype + from numpypy import dtype assert dtype(long).shape == () def test_cant_subclass(self): - from _numpypy import dtype + from numpypy import dtype # You can't subclass dtype raises(TypeError, type, "Foo", (dtype,), {}) def test_can_subclass(self): - import _numpypy - class xyz(_numpypy.void): + import numpypy + class xyz(numpypy.void): pass assert True def test_aliases(self): - from _numpypy import dtype + from numpypy import dtype assert dtype("float") is dtype(float) def test_index_int8(self): - from _numpypy import array, int8 + from numpypy import array, int8 a = array(range(10), dtype=int8) b = array([0] * 10, dtype=int8) for idx in b: a[idx] += 1 def test_index_int16(self): - from _numpypy import array, int16 + from numpypy import array, int16 a = array(range(10), dtype=int16) b = array([0] * 10, dtype=int16) for idx in b: a[idx] += 1 def test_index_int32(self): - from _numpypy import array, int32 + from numpypy import array, int32 a = array(range(10), dtype=int32) b = array([0] * 10, dtype=int32) for idx in b: a[idx] += 1 def test_index_int64(self): - from _numpypy import array, int64 + from numpypy import array, int64 a = array(range(10), dtype=int64) b = array([0] * 10, dtype=int64) @@ -257,7 +253,7 @@ a[idx] += 1 def test_hash(self): - import _numpypy as numpy + import numpypy as numpy for tp, value in [ (numpy.int8, 4), (numpy.int16, 5), @@ -272,7 +268,7 @@ class AppTestTypes(BaseAppTestDtypes): def test_abstract_types(self): - import _numpypy as numpy + import numpypy as numpy raises(TypeError, numpy.generic, 0) raises(TypeError, numpy.number, 0) @@ -312,12 +308,12 @@ #assert a.dtype is numpy.dtype('|V4') def test_new(self): - import _numpypy as np + import numpypy as np assert np.int_(4) == 4 assert np.float_(3.4) == 3.4 def test_pow(self): - from _numpypy import int_ + from numpypy import int_ assert int_(4) ** 2 == 16 def test_bool(self): @@ -336,7 +332,7 @@ assert numpy.bool_("False") is numpy.True_ def test_int8(self): - import _numpypy as numpy + import numpypy as numpy assert numpy.int8.mro() == [numpy.int8, numpy.signedinteger, numpy.integer, numpy.number, @@ -360,7 +356,7 @@ assert numpy.int8('128') == -128 def test_uint8(self): - import _numpypy as numpy + import numpypy as numpy assert numpy.uint8.mro() == [numpy.uint8, numpy.unsignedinteger, numpy.integer, numpy.number, @@ -385,7 +381,7 @@ assert numpy.uint8('256') == 0 def test_int16(self): - import _numpypy as numpy + import numpypy as numpy x = numpy.int16(3) assert x == 3 @@ -395,7 +391,7 @@ assert numpy.int16('32768') == -32768 def test_uint16(self): - import _numpypy as numpy + import numpypy as numpy assert numpy.uint16(65535) == 65535 assert numpy.uint16(65536) == 0 @@ -404,7 +400,7 @@ def test_int32(self): import sys - import _numpypy as numpy + import numpypy as numpy x = numpy.int32(23) assert x == 23 @@ -420,7 +416,7 @@ def test_uint32(self): import sys - import _numpypy as numpy + import numpypy as numpy assert numpy.uint32(10) == 10 @@ -431,7 +427,7 @@ assert numpy.uint32('4294967296') == 0 def test_int_(self): - import _numpypy as numpy + import numpypy as numpy assert numpy.int_ is numpy.dtype(int).type assert numpy.int_.mro() == [numpy.int_, numpy.signedinteger, @@ -440,7 +436,7 @@ def test_int64(self): import sys - import _numpypy as numpy + import numpypy as numpy if sys.maxint == 2 ** 63 -1: assert numpy.int64.mro() == [numpy.int64, numpy.signedinteger, @@ -462,7 +458,7 @@ def test_uint64(self): import sys - import _numpypy as numpy + import numpypy as numpy assert numpy.uint64.mro() == [numpy.uint64, numpy.unsignedinteger, numpy.integer, numpy.number, @@ -479,7 +475,7 @@ raises(OverflowError, numpy.uint64(18446744073709551616)) def test_float16(self): - import _numpypy as numpy + import numpypy as numpy assert numpy.float16.mro() == [numpy.float16, numpy.floating, numpy.inexact, numpy.number, numpy.generic, object] @@ -490,7 +486,7 @@ def test_float32(self): - import _numpypy as numpy + import numpypy as numpy assert numpy.float32.mro() == [numpy.float32, numpy.floating, numpy.inexact, numpy.number, @@ -501,7 +497,7 @@ raises(ValueError, numpy.float32, '23.2df') def test_float64(self): - import _numpypy as numpy + import numpypy as numpy assert numpy.float64.mro() == [numpy.float64, numpy.floating, numpy.inexact, numpy.number, @@ -518,20 +514,20 @@ raises(ValueError, numpy.float64, '23.2df') def test_float_None(self): - import _numpypy as numpy + import numpypy as numpy from math import isnan assert isnan(numpy.float32(None)) assert isnan(numpy.float64(None)) def test_complex_floating(self): - import _numpypy as numpy + import numpypy as numpy assert numpy.complexfloating.__mro__ == (numpy.complexfloating, numpy.inexact, numpy.number, numpy.generic, object) def test_complex_format(self): import sys - import _numpypy as numpy + import numpypy as numpy for complex_ in (numpy.complex128, numpy.complex64,): for real, imag, should in [ @@ -571,7 +567,7 @@ assert "{:g}".format(numpy.complex_(0.5+1.5j)) == '{:g}'.format(0.5+1.5j) def test_complex(self): - import _numpypy as numpy + import numpypy as numpy assert numpy.complex_ is numpy.complex128 assert numpy.complex64.__mro__ == (numpy.complex64, @@ -589,7 +585,7 @@ assert d.char == 'F' def test_subclass_type(self): - import _numpypy as numpy + import numpypy as numpy class X(numpy.float64): def m(self): @@ -600,12 +596,12 @@ assert b.m() == 12 def test_long_as_index(self): - from _numpypy import int_, float64 + from numpypy import int_, float64 assert (1, 2, 3)[int_(1)] == 2 raises(TypeError, lambda: (1, 2, 3)[float64(1)]) def test_int(self): - from _numpypy import int32, int64, int_ + from numpypy import int32, int64, int_ import sys assert issubclass(int_, int) if sys.maxint == (1<<31) - 1: @@ -616,7 +612,7 @@ assert int_ is int64 def test_various_types(self): - import _numpypy as numpy + import numpypy as numpy assert numpy.int16 is numpy.short assert numpy.int8 is numpy.byte @@ -629,7 +625,7 @@ assert numpy.uintp is numpy.uint64 def test_mro(self): - import _numpypy as numpy + import numpypy as numpy assert numpy.int16.__mro__ == (numpy.int16, numpy.signedinteger, numpy.integer, numpy.number, @@ -638,8 +634,7 @@ def test_operators(self): from operator import truediv - from _numpypy import float64, int_ - from numpypy import True_, False_ + from numpypy import float64, int_, True_, False_ assert 5 / int_(2) == int_(2) assert truediv(int_(3), int_(2)) == float64(1.5) assert truediv(3, int_(2)) == float64(1.5) @@ -664,7 +659,7 @@ raises(TypeError, lambda: float64(3) & 1) def test_alternate_constructs(self): - from _numpypy import dtype + from numpypy import dtype nnp = self.non_native_prefix byteorder = self.native_prefix assert dtype('i8') == dtype(byteorder + 'i8') == dtype('=i8') # XXX should be equal == dtype(long) @@ -674,23 +669,23 @@ assert dtype(byteorder + 'i8').byteorder == '=' def test_intp(self): - from _numpypy import dtype + from numpypy import dtype assert dtype('p') == dtype('intp') assert dtype('P') == dtype('uintp') def test_alignment(self): - from _numpypy import dtype + from numpypy import dtype assert dtype('i4').alignment == 4 class AppTestStrUnicodeDtypes(BaseNumpyAppTest): def test_str_unicode(self): - from _numpypy import str_, unicode_, character, flexible, generic + from numpypy import str_, unicode_, character, flexible, generic assert str_.mro() == [str_, str, basestring, character, flexible, generic, object] assert unicode_.mro() == [unicode_, unicode, basestring, character, flexible, generic, object] def test_str_dtype(self): - from _numpypy import dtype, str_ + from numpypy import dtype, str_ raises(TypeError, "dtype('Sx')") d = dtype('S8') @@ -702,7 +697,7 @@ assert d.num == 18 def test_unicode_dtype(self): - from _numpypy import dtype, unicode_ + from numpypy import dtype, unicode_ raises(TypeError, "dtype('Ux')") d = dtype('U8') @@ -714,16 +709,16 @@ assert d.num == 19 def test_string_boxes(self): - from _numpypy import str_ + from numpypy import str_ assert isinstance(str_(3), str_) def test_unicode_boxes(self): - from _numpypy import unicode_ + from numpypy import unicode_ assert isinstance(unicode_(3), unicode) class AppTestRecordDtypes(BaseNumpyAppTest): def test_create(self): - from _numpypy import dtype, void + from numpypy import dtype, void raises(ValueError, "dtype([('x', int), ('x', float)])") d = dtype([("x", "int32"), ("y", "int32"), ("z", "int32"), ("value", float)]) @@ -742,7 +737,7 @@ def test_create_from_dict(self): skip("not yet") - from _numpypy import dtype + from numpypy import dtype d = dtype({'names': ['a', 'b', 'c'], }) @@ -766,7 +761,7 @@ cls.w_check_non_native = cls.space.wrap(interp2app(check_non_native)) def test_non_native(self): - from _numpypy import array + from numpypy import array a = array([1, 2, 3], dtype=self.non_native_prefix + 'i2') assert a[0] == 1 assert (a + a)[1] == 4 @@ -788,7 +783,8 @@ BaseNumpyAppTest.setup_class.im_func(cls) def test_typeinfo(self): - from _numpypy import typeinfo, void, number, int64, bool_ + from numpypy import void, number, int64, bool_ + from numpypy.core.multiarray import typeinfo assert typeinfo['Number'] == number assert typeinfo['LONGLONG'] == ('q', 9, 64, 8, 9223372036854775807L, -9223372036854775808L, int64) assert typeinfo['VOID'] == ('V', 20, 0, 1, void) @@ -804,11 +800,11 @@ BaseNumpyAppTest.setup_class.im_func(cls) def test_nolongfloat(self): - import _numpypy - from _numpypy import dtype - assert not getattr(_numpypy, 'longdouble', False) - assert not getattr(_numpypy, 'float128', False) - assert not getattr(_numpypy, 'float96', False) + import numpypy + from numpypy import dtype + assert not getattr(numpypy, 'longdouble', False) + assert not getattr(numpypy, 'float128', False) + assert not getattr(numpypy, 'float96', False) raises(TypeError, dtype, 'longdouble') raises(TypeError, dtype, 'clongdouble') raises(TypeError, dtype, 'longfloat') @@ -825,7 +821,7 @@ BaseNumpyAppTest.setup_class.im_func(cls) def test_longfloat(self): - import _numpypy as numpy + import numpypy as numpy # it can be float96 or float128 if numpy.longfloat != numpy.float64: assert numpy.longfloat.mro()[1:] == [numpy.floating, @@ -838,33 +834,33 @@ raises(ValueError, numpy.longfloat, '23.2df') def test_dtype_aliases(self): - from _numpypy import dtype + from numpypy import dtype assert dtype('longfloat').num in (12, 13) assert dtype('longdouble').num in (12, 13) assert dtype('clongfloat').num in (15, 16) assert dtype('clongdouble').num in (15, 16) def test_bool_binop_types(self): - from _numpypy import array, dtype + from numpypy import array, dtype types = ['g', 'G'] a = array([True], '?') for t in types: assert (a + array([0], t)).dtype is dtype(t) def test_hash(self): - import _numpypy as numpy + import numpypy as numpy for tp, value in [ (numpy.longdouble, 4.32), ]: assert hash(tp(value)) == hash(value) def test_float_None(self): - import _numpypy as numpy + import numpypy as numpy from math import isnan assert isnan(numpy.longdouble(None)) def test_non_native(self): - from _numpypy import array + from numpypy import array a = array([1, 2, 3], dtype=self.non_native_prefix + 'g') # longdouble assert a[0] == 1 assert (a + a)[1] == 4 diff --git a/pypy/module/micronumpy/test/test_numarray.py b/pypy/module/micronumpy/test/test_numarray.py --- a/pypy/module/micronumpy/test/test_numarray.py +++ b/pypy/module/micronumpy/test/test_numarray.py @@ -245,7 +245,7 @@ return CustomIntObject(value) def test_ndarray(self): - from _numpypy import ndarray, array, dtype + from numpypy import ndarray, array, dtype assert type(ndarray) is type assert type(array) is not type @@ -262,24 +262,24 @@ assert a.shape == () def test_ndmin(self): - from _numpypy import array + from numpypy import array arr = array([[[1]]], ndmin=1) assert arr.shape == (1, 1, 1) def test_noop_ndmin(self): - from _numpypy import array + from numpypy import array arr = array([1], ndmin=3) assert arr.shape == (1, 1, 1) def test_type(self): - from _numpypy import array + from numpypy import array ar = array(range(5)) assert type(ar) is type(ar + ar) def test_ndim(self): - from _numpypy import array + from numpypy import array x = array(0.2) assert x.ndim == 0 x = array([1, 2]) @@ -288,12 +288,12 @@ assert x.ndim == 2 x = array([[[1, 2], [3, 4]], [[5, 6], [7, 8]]]) assert x.ndim == 3 - # numpy actually raises an AttributeError, but _numpypy raises an + # numpy actually raises an AttributeError, but numpypy raises an # TypeError raises((TypeError, AttributeError), 'x.ndim = 3') def test_init(self): - from _numpypy import zeros + from numpypy import zeros a = zeros(15) # Check that storage was actually zero'd. assert a[10] == 0.0 @@ -303,7 +303,7 @@ assert zeros(()).shape == () def test_size(self): - from _numpypy import array,arange,cos + from numpypy import array,arange,cos assert array(3).size == 1 a = array([1, 2, 3]) assert a.size == 3 @@ -316,13 +316,13 @@ Test that empty() works. """ - from _numpypy import empty + from numpypy import empty a = empty(2) a[1] = 1.0 assert a[1] == 1.0 def test_ones(self): - from _numpypy import ones + from numpypy import ones a = ones(3) assert len(a) == 3 assert a[0] == 1 @@ -331,7 +331,7 @@ assert a[2] == 4 def test_copy(self): - from _numpypy import arange, array + from numpypy import arange, array a = arange(5) b = a.copy() for i in xrange(5): @@ -357,12 +357,12 @@ assert b[0] == a[0] def test_iterator_init(self): - from _numpypy import array + from numpypy import array a = array(range(5)) assert a[3] == 3 def test_getitem(self): - from _numpypy import array + from numpypy import array a = array(range(5)) raises(IndexError, "a[5]") a = a + a @@ -371,14 +371,14 @@ raises(IndexError, "a[-6]") def test_getitem_float(self): - from _numpypy import array + from numpypy import array a = array([1, 2, 3, 4]) assert a[1.2] == 2 assert a[1.6] == 2 assert a[-1.2] == 4 def test_getitem_tuple(self): - from _numpypy import array + from numpypy import array a = array(range(5)) raises(IndexError, "a[(1,2)]") for i in xrange(5): @@ -388,20 +388,20 @@ assert a[i] == b[i] def test_getitem_nd(self): - from _numpypy import arange + from numpypy import arange a = arange(15).reshape(3, 5) assert a[1, 3] == 8 assert a.T[1, 2] == 11 def test_getitem_obj_index(self): - from _numpypy import arange + from numpypy import arange a = arange(10) assert a[self.CustomIndexObject(1)] == 1 def test_getitem_obj_prefer_index_to_int(self): - from _numpypy import arange + from numpypy import arange a = arange(10) @@ -409,14 +409,14 @@ assert a[self.CustomIndexIntObject(0, 1)] == 0 def test_getitem_obj_int(self): - from _numpypy import arange + from numpypy import arange a = arange(10) assert a[self.CustomIntObject(1)] == 1 def test_setitem(self): - from _numpypy import array + from numpypy import array a = array(range(5)) a[-1] = 5.0 assert a[4] == 5.0 @@ -424,7 +424,7 @@ raises(IndexError, "a[-6] = 3.0") def test_setitem_tuple(self): - from _numpypy import array + from numpypy import array a = array(range(5)) raises(IndexError, "a[(1,2)] = [0,1]") for i in xrange(5): @@ -435,7 +435,7 @@ assert a[i] == i def test_setitem_obj_index(self): - from _numpypy import arange + from numpypy import arange a = arange(10) @@ -443,7 +443,7 @@ assert a[1] == 100 def test_setitem_obj_prefer_index_to_int(self): - from _numpypy import arange + from numpypy import arange a = arange(10) @@ -451,7 +451,7 @@ assert a[0] == 100 def test_setitem_obj_int(self): - from _numpypy import arange + from numpypy import arange a = arange(10) @@ -471,13 +471,13 @@ # numpy will swallow errors in __int__ and __index__ and # just raise IndexError. - from _numpypy import arange + from numpypy import arange a = arange(10) raises(IndexError, "a[ErrorIndex()] == 0") raises(IndexError, "a[ErrorInt()] == 0") def test_setslice_array(self): - from _numpypy import array + from numpypy import array a = array(range(5)) b = array(range(2)) a[1:4:2] = b @@ -488,7 +488,7 @@ assert b[1] == 0. def test_setslice_of_slice_array(self): - from _numpypy import array, zeros + from numpypy import array, zeros a = zeros(5) a[::2] = array([9., 10., 11.]) assert a[0] == 9. @@ -507,7 +507,7 @@ assert a[0] == 3. def test_setslice_list(self): - from _numpypy import array + from numpypy import array a = array(range(5), float) b = [0., 1.] a[1:4:2] = b @@ -515,7 +515,7 @@ assert a[3] == 1. def test_setslice_constant(self): - from _numpypy import array + from numpypy import array a = array(range(5), float) a[1:4:2] = 0. assert a[1] == 0. @@ -523,7 +523,7 @@ def test_newaxis(self): import math - from _numpypy import array, cos, zeros + from numpypy import array, cos, zeros from numpypy.core.numeric import newaxis a = array(range(5)) b = array([range(5)]) @@ -537,7 +537,7 @@ assert ((cos(a)[:,newaxis] * cos(b).T) == expected).all() def test_newaxis_slice(self): - from _numpypy import array + from numpypy import array from numpypy.core.numeric import newaxis a = array(range(5)) @@ -550,7 +550,7 @@ assert (a[newaxis,1:] == c).all() def test_newaxis_assign(self): - from _numpypy import array + from numpypy import array from numpypy.core.numeric import newaxis a = array(range(5)) @@ -558,7 +558,7 @@ assert a[1] == 2 def test_newaxis_virtual(self): - from _numpypy import array + from numpypy import array from numpypy.core.numeric import newaxis a = array(range(5)) @@ -567,7 +567,7 @@ assert (b == c).all() def test_newaxis_then_slice(self): - from _numpypy import array + from numpypy import array from numpypy.core.numeric import newaxis a = array(range(5)) b = a[newaxis] @@ -575,14 +575,14 @@ assert (b[0,1:] == a[1:]).all() def test_slice_then_newaxis(self): - from _numpypy import array + from numpypy import array from numpypy.core.numeric import newaxis a = array(range(5)) b = a[2:] assert (b[newaxis] == [[2, 3, 4]]).all() def test_scalar(self): - from _numpypy import array, dtype + from numpypy import array, dtype a = array(3) raises(IndexError, "a[0]") raises(IndexError, "a[0] = 5") @@ -591,13 +591,13 @@ assert a.dtype is dtype(int) def test_len(self): - from _numpypy import array + from numpypy import array a = array(range(5)) assert len(a) == 5 assert len(a + a) == 5 def test_shape(self): - from _numpypy import array + from numpypy import array a = array(range(5)) assert a.shape == (5,) b = a + a @@ -607,7 +607,7 @@ assert array([]).shape == (0,) def test_set_shape(self): - from _numpypy import array, zeros + from numpypy import array, zeros a = array([]) raises(ValueError, "a.shape = []") a = array(range(12)) @@ -630,7 +630,7 @@ raises(AttributeError, 'a.shape = 6') def test_reshape(self): - from _numpypy import array, zeros + from numpypy import array, zeros a = array(range(12)) exc = raises(ValueError, "b = a.reshape((3, 10))") assert str(exc.value) == "total size of new array must be unchanged" @@ -646,7 +646,7 @@ assert a.reshape((0,)).shape == (0,) def test_slice_reshape(self): - from _numpypy import zeros, arange + from numpypy import zeros, arange a = zeros((4, 2, 3)) b = a[::2, :, :] b.shape = (2, 6) @@ -682,7 +682,7 @@ raises(ValueError, arange(10).reshape, (5, -1, -1)) def test_reshape_varargs(self): - from _numpypy import arange + from numpypy import arange z = arange(96).reshape(12, -1) y = z.reshape(4, 3, 8) assert y.shape == (4, 3, 8) @@ -695,19 +695,19 @@ raises(ValueError, "a.reshape(3)") def test_strides(self): - from _numpypy import array + from numpypy import array a = array([[1.0, 2.0], [3.0, 4.0]]) assert a.strides == (16, 8) assert a[1:].strides == (16, 8) def test_strides_scalar(self): - from _numpypy import array + from numpypy import array a = array(42) assert a.strides == () def test_add(self): - from _numpypy import array + from numpypy import array a = array(range(5)) b = a + a for i in range(5): @@ -720,7 +720,7 @@ assert c[i] == bool(a[i] + b[i]) def test_add_other(self): - from _numpypy import array + from numpypy import array a = array(range(5)) b = array([i for i in reversed(range(5))]) c = a + b @@ -728,14 +728,14 @@ assert c[i] == 4 def test_add_constant(self): - from _numpypy import array + from numpypy import array a = array(range(5)) b = a + 5 for i in range(5): assert b[i] == i + 5 def test_radd(self): - from _numpypy import array + from numpypy import array r = 3 + array(range(3)) for i in range(3): assert r[i] == i + 3 @@ -743,7 +743,7 @@ assert (r == [2, 4]).all() def test_add_list(self): - from _numpypy import array, ndarray + from numpypy import array, ndarray a = array(range(5)) b = list(reversed(range(5))) c = a + b @@ -752,14 +752,14 @@ assert c[i] == 4 def test_subtract(self): - from _numpypy import array + from numpypy import array a = array(range(5)) b = a - a for i in range(5): assert b[i] == 0 def test_subtract_other(self): - from _numpypy import array + from numpypy import array a = array(range(5)) b = array([1, 1, 1, 1, 1]) c = a - b @@ -767,36 +767,35 @@ assert c[i] == i - 1 def test_subtract_constant(self): - from _numpypy import array + from numpypy import array a = array(range(5)) b = a - 5 for i in range(5): assert b[i] == i - 5 def test_scalar_subtract(self): - from _numpypy import int32 + from numpypy import int32 assert int32(2) - 1 == 1 assert 1 - int32(2) == -1 def test_mul(self): - import _numpypy - from numpypy import False_, True_ + import numpypy - a = _numpypy.array(range(5)) + a = numpypy.array(range(5)) b = a * a for i in range(5): assert b[i] == i * i assert b.dtype is a.dtype - a = _numpypy.array(range(5), dtype=bool) + a = numpypy.array(range(5), dtype=bool) b = a * a - assert b.dtype is _numpypy.dtype(bool) - assert b[0] is False_ + assert b.dtype is numpypy.dtype(bool) + assert b[0] is numpypy.False_ for i in range(1, 5): - assert b[i] is True_ + assert b[i] is numpypy.True_ def test_mul_constant(self): - from _numpypy import array + from numpypy import array a = array(range(5)) b = a * 5 for i in range(5): @@ -804,7 +803,7 @@ def test_div(self): from math import isnan - from _numpypy import array, dtype + from numpypy import array, dtype a = array(range(1, 6)) b = a / a @@ -836,7 +835,7 @@ assert c[2] == float('-inf') def test_div_other(self): - from _numpypy import array + from numpypy import array a = array(range(5)) b = array([2, 2, 2, 2, 2], float) c = a / b @@ -844,7 +843,7 @@ assert c[i] == i / 2.0 def test_div_constant(self): - from _numpypy import array + from numpypy import array a = array(range(5)) b = a / 5.0 for i in range(5): @@ -852,7 +851,7 @@ def test_floordiv(self): from math import isnan - from _numpypy import array, dtype + from numpypy import array, dtype a = array(range(1, 6)) b = a // a @@ -882,47 +881,47 @@ assert c[2] == float('-inf') def test_floordiv_other(self): - from _numpypy import array + from numpypy import array a = array(range(5)) b = array([2, 2, 2, 2, 2], float) c = a // b assert (c == [0, 0, 1, 1, 2]).all() def test_rfloordiv(self): - from _numpypy import array + from numpypy import array a = array(range(1, 6)) b = 3 // a assert (b == [3, 1, 1, 0, 0]).all() def test_floordiv_constant(self): - from _numpypy import array + from numpypy import array a = array(range(5)) b = a // 2 assert (b == [0, 0, 1, 1, 2]).all() def test_truediv(self): from operator import truediv - from _numpypy import arange + from numpypy import arange assert (truediv(arange(5), 2) == [0., .5, 1., 1.5, 2.]).all() assert (truediv(2, arange(3)) == [float("inf"), 2., 1.]).all() def test_divmod(self): - from _numpypy import arange + from numpypy import arange a, b = divmod(arange(10), 3) assert (a == [0, 0, 0, 1, 1, 1, 2, 2, 2, 3]).all() assert (b == [0, 1, 2, 0, 1, 2, 0, 1, 2, 0]).all() def test_rdivmod(self): - from _numpypy import arange + from numpypy import arange a, b = divmod(3, arange(1, 5)) assert (a == [3, 1, 1, 0]).all() assert (b == [0, 1, 0, 3]).all() def test_lshift(self): - from _numpypy import array + from numpypy import array a = array([0, 1, 2, 3]) assert (a << 2 == [0, 4, 8, 12]).all() @@ -932,13 +931,13 @@ raises(TypeError, lambda: a << 2) def test_rlshift(self): - from _numpypy import arange + from numpypy import arange a = arange(3) assert (2 << a == [2, 4, 8]).all() def test_rshift(self): - from _numpypy import arange, array + from numpypy import arange, array a = arange(10) assert (a >> 2 == [0, 0, 0, 0, 1, 1, 1, 1, 2, 2]).all() @@ -948,13 +947,13 @@ raises(TypeError, lambda: a >> 1) def test_rrshift(self): - from _numpypy import arange + from numpypy import arange a = arange(5) assert (2 >> a == [2, 1, 0, 0, 0]).all() def test_pow(self): - from _numpypy import array + from numpypy import array a = array(range(5), float) b = a ** a for i in range(5): @@ -964,7 +963,7 @@ assert (a ** 2 == a * a).all() def test_pow_other(self): - from _numpypy import array + from numpypy import array a = array(range(5), float) b = array([2, 2, 2, 2, 2]) c = a ** b @@ -972,14 +971,14 @@ assert c[i] == i ** 2 def test_pow_constant(self): - from _numpypy import array + from numpypy import array a = array(range(5), float) b = a ** 2 for i in range(5): assert b[i] == i ** 2 def test_mod(self): - from _numpypy import array + from numpypy import array a = array(range(1, 6)) b = a % a for i in range(5): @@ -992,7 +991,7 @@ assert b[i] == 1 def test_mod_other(self): - from _numpypy import array + from numpypy import array a = array(range(5)) b = array([2, 2, 2, 2, 2]) c = a % b @@ -1000,38 +999,38 @@ assert c[i] == i % 2 def test_mod_constant(self): - from _numpypy import array + from numpypy import array a = array(range(5)) b = a % 2 for i in range(5): assert b[i] == i % 2 def test_rand(self): - from _numpypy import arange + from numpypy import arange a = arange(5) assert (3 & a == [0, 1, 2, 3, 0]).all() def test_ror(self): - from _numpypy import arange + from numpypy import arange a = arange(5) assert (3 | a == [3, 3, 3, 3, 7]).all() def test_xor(self): - from _numpypy import arange + from numpypy import arange a = arange(5) assert (a ^ 3 == [3, 2, 1, 0, 7]).all() def test_rxor(self): - from _numpypy import arange + from numpypy import arange a = arange(5) assert (3 ^ a == [3, 2, 1, 0, 7]).all() def test_pos(self): - from _numpypy import array + from numpypy import array a = array([1., -2., 3., -4., -5.]) b = +a for i in range(5): @@ -1042,7 +1041,7 @@ assert a[i] == i def test_neg(self): - from _numpypy import array + from numpypy import array a = array([1., -2., 3., -4., -5.]) b = -a for i in range(5): @@ -1053,7 +1052,7 @@ assert a[i] == -i def test_abs(self): - from _numpypy import array + from numpypy import array a = array([1., -2., 3., -4., -5.]) b = abs(a) for i in range(5): @@ -1064,7 +1063,7 @@ assert a[i + 5] == abs(i) def test_auto_force(self): - from _numpypy import array + from numpypy import array a = array(range(5)) b = a - 1 a[2] = 3 @@ -1078,7 +1077,7 @@ assert c[1] == 4 def test_getslice(self): - from _numpypy import array + from numpypy import array a = array(range(5)) s = a[1:5] assert len(s) == 4 @@ -1092,7 +1091,7 @@ assert s[0] == 5 def test_getslice_step(self): - from _numpypy import array + from numpypy import array a = array(range(10)) s = a[1:9:2] assert len(s) == 4 @@ -1100,7 +1099,7 @@ assert s[i] == a[2 * i + 1] def test_slice_update(self): - from _numpypy import array + from numpypy import array a = array(range(5)) s = a[0:3] s[1] = 10 @@ -1110,7 +1109,7 @@ def test_slice_invaidate(self): # check that slice shares invalidation list with - from _numpypy import array + from numpypy import array a = array(range(5)) s = a[0:2] b = array([10, 11]) @@ -1124,7 +1123,7 @@ assert d[1] == 12 def test_mean(self): - from _numpypy import array, arange + from numpypy import array, arange a = array(range(5)) assert a.mean() == 2.0 assert a[:4].mean() == 1.5 @@ -1142,7 +1141,7 @@ assert (a.mean(1) == [0.5, 2.5, 4.5, 6.5, 8.5]).all() def test_sum(self): - from _numpypy import array, zeros + from numpypy import array, zeros a = array(range(5)) assert a.sum() == 10 assert a[:4].sum() == 6 @@ -1190,13 +1189,13 @@ assert (array([[1,2],[3,4]]).prod(1) == [2, 12]).all() def test_prod(self): - from _numpypy import array + from numpypy import array a = array(range(1, 6)) assert a.prod() == 120.0 assert a[:4].prod() == 24.0 def test_max(self): - from _numpypy import array, zeros + from numpypy import array, zeros a = array([-1.2, 3.4, 5.7, -3.0, 2.7]) assert a.max() == 5.7 b = array([]) @@ -1206,12 +1205,12 @@ assert list(zeros((0, 2)).max(axis=1)) == [] def test_max_add(self): - from _numpypy import array + from numpypy import array a = array([-1.2, 3.4, 5.7, -3.0, 2.7]) assert (a + a).max() == 11.4 def test_min(self): - from _numpypy import array, zeros + from numpypy import array, zeros a = array([-1.2, 3.4, 5.7, -3.0, 2.7]) assert a.min() == -3.0 b = array([]) @@ -1221,7 +1220,7 @@ assert list(zeros((0, 2)).min(axis=1)) == [] def test_argmax(self): - from _numpypy import array + from numpypy import array a = array([-1.2, 3.4, 5.7, -3.0, 2.7]) r = a.argmax() assert r == 2 @@ -1242,14 +1241,14 @@ assert a.argmax() == 2 def test_argmin(self): - from _numpypy import array + from numpypy import array a = array([-1.2, 3.4, 5.7, -3.0, 2.7]) assert a.argmin() == 3 b = array([]) raises(ValueError, "b.argmin()") def test_all(self): - from _numpypy import array + from numpypy import array a = array(range(5)) assert a.all() == False a[0] = 3.0 @@ -1258,7 +1257,7 @@ assert b.all() == True def test_any(self): - from _numpypy import array, zeros + from numpypy import array, zeros a = array(range(5)) assert a.any() == True b = zeros(5) @@ -1267,7 +1266,7 @@ assert c.any() == False def test_dtype_guessing(self): - from _numpypy import array, dtype, float64, int8, bool_ + from numpypy import array, dtype, float64, int8, bool_ assert array([True]).dtype is dtype(bool) assert array([True, False]).dtype is dtype(bool) @@ -1284,7 +1283,7 @@ def test_comparison(self): import operator - from _numpypy import array, dtype + from numpypy import array, dtype a = array(range(5)) b = array(range(5), float) @@ -1303,7 +1302,7 @@ assert c[i] == func(b[i], 3) def test_nonzero(self): - from _numpypy import array + from numpypy import array a = array([1, 2]) raises(ValueError, bool, a) raises(ValueError, bool, a == a) @@ -1313,7 +1312,7 @@ assert not bool(array([0])) def test_slice_assignment(self): - from _numpypy import array + from numpypy import array a = array(range(5)) a[::-1] = a assert (a == [4, 3, 2, 1, 0]).all() @@ -1323,7 +1322,7 @@ assert (a == [8, 6, 4, 2, 0]).all() def test_virtual_views(self): - from _numpypy import arange + from numpypy import arange a = arange(15) c = (a + a) d = c[::2] @@ -1341,7 +1340,7 @@ assert b[1] == 2 def test_realimag_views(self): - from _numpypy import arange, array + from numpypy import arange, array a = arange(15) b = a.real b[5]=50 @@ -1377,7 +1376,7 @@ assert a[2].imag == -5 def test_tolist_scalar(self): - from _numpypy import int32, bool_ + from numpypy import int32, bool_ x = int32(23) assert x.tolist() == 23 assert type(x.tolist()) is int @@ -1385,13 +1384,13 @@ assert y.tolist() is True def test_tolist_zerodim(self): - from _numpypy import array + from numpypy import array x = array(3) assert x.tolist() == 3 assert type(x.tolist()) is int def test_tolist_singledim(self): - from _numpypy import array + from numpypy import array a = array(range(5)) assert a.tolist() == [0, 1, 2, 3, 4] assert type(a.tolist()[0]) is int @@ -1399,23 +1398,23 @@ assert b.tolist() == [0.2, 0.4, 0.6] def test_tolist_multidim(self): - from _numpypy import array + from numpypy import array a = array([[1, 2], [3, 4]]) assert a.tolist() == [[1, 2], [3, 4]] def test_tolist_view(self): - from _numpypy import array + from numpypy import array a = array([[1, 2], [3, 4]]) assert (a + a).tolist() == [[2, 4], [6, 8]] def test_tolist_slice(self): - from _numpypy import array + from numpypy import array a = array([[17.1, 27.2], [40.3, 50.3]]) assert a[:, 0].tolist() == [17.1, 40.3] assert a[0].tolist() == [17.1, 27.2] def test_var(self): - from _numpypy import array, arange + from numpypy import array, arange a = array(range(10)) assert a.var() == 8.25 a = array([5.0]) @@ -1484,14 +1483,14 @@ assert (b == [2, 6, 10, 2, 6, 10]).all() def test_std(self): - from _numpypy import array + from numpypy import array a = array(range(10)) assert a.std() == 2.8722813232690143 a = array([5.0]) assert a.std() == 0.0 def test_flatten(self): - from _numpypy import array + from numpypy import array assert array(3).flatten().shape == (1,) a = array([[1, 2], [3, 4]]) @@ -1514,7 +1513,7 @@ assert (a.T.flatten() == [1, 3, 2, 4]).all() def test_itemsize(self): - from _numpypy import ones, dtype, array + from numpypy import ones, dtype, array for obj in [float, bool, int]: assert ones(1, dtype=obj).itemsize == dtype(obj).itemsize @@ -1523,7 +1522,7 @@ assert ones(1)[:].itemsize == 8 def test_nbytes(self): - from _numpypy import array, ones + from numpypy import array, ones assert ones(1).nbytes == 8 assert ones((2, 2)).nbytes == 32 @@ -1532,7 +1531,7 @@ assert array(3.0).nbytes == 8 def test_repeat(self): - from _numpypy import repeat, array + from numpypy import repeat, array assert (repeat([[1, 2], [3, 4]], 3) == [1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4]).all() assert (repeat([[1, 2], [3, 4]], 2, axis=0) == [[1, 2], [1, 2], [3, 4], @@ -1543,7 +1542,7 @@ def test_swapaxes(self): - from _numpypy import array + from numpypy import array # testcases from numpy docstring x = array([[1, 2, 3]]) assert (x.swapaxes(0, 1) == array([[1], [2], [3]])).all() @@ -1629,7 +1628,7 @@ assert _weakref.ref(a) def test_astype(self): - from _numpypy import array, arange + from numpypy import array, arange b = array(1).astype(float) assert b == 1 assert b.dtype == float @@ -1650,7 +1649,7 @@ assert a.itemsize == 3 def test_base(self): - from _numpypy import array + from numpypy import array assert array(1).base is None assert array([1, 2]).base is None a = array([1, 2, 3, 4]) @@ -1658,7 +1657,7 @@ assert b.base is a def test_byteswap(self): - from _numpypy import array + from numpypy import array s1 = array(1.).byteswap().tostring() s2 = array([1.]).byteswap().tostring() @@ -1698,7 +1697,7 @@ assert list(reversed(s1[i1:i2])) == s2[i1:i2] def test_clip(self): - from _numpypy import array + from numpypy import array a = array([1, 2, 17, -3, 12]) assert (a.clip(-2, 13) == [1, 2, 13, -2, 12]).all() assert (a.clip(-1, 1, out=None) == [1, 1, 1, -1, 1]).all() @@ -1708,7 +1707,7 @@ assert (a == [1, 2, 13, -2, 12]).all() def test_data(self): - from _numpypy import array + from numpypy import array a = array([1, 2, 3, 4], dtype='i4') assert a.data[0] == '\x01' assert a.data[1] == '\x00' @@ -1718,13 +1717,13 @@ assert len(a.data) == 16 def test_explicit_dtype_conversion(self): - from _numpypy import array + from numpypy import array a = array([1.0, 2.0]) b = array(a, dtype='d') assert a.dtype is b.dtype def test_notequal_different_shapes(self): - from _numpypy import array + from numpypy import array a = array([1, 2]) b = array([1, 2, 3, 4]) assert (a == b) == False @@ -1732,23 +1731,23 @@ class AppTestMultiDim(BaseNumpyAppTest): def test_init(self): - import _numpypy - a = _numpypy.zeros((2, 2)) + import numpypy + a = numpypy.zeros((2, 2)) assert len(a) == 2 def test_shape(self): - import _numpypy - assert _numpypy.zeros(1).shape == (1,) - assert _numpypy.zeros((2, 2)).shape == (2, 2) - assert _numpypy.zeros((3, 1, 2)).shape == (3, 1, 2) - assert _numpypy.array([[1], [2], [3]]).shape == (3, 1) - assert len(_numpypy.zeros((3, 1, 2))) == 3 - raises(TypeError, len, _numpypy.zeros(())) - raises(ValueError, _numpypy.array, [[1, 2], 3], dtype=float) + import numpypy + assert numpypy.zeros(1).shape == (1,) + assert numpypy.zeros((2, 2)).shape == (2, 2) + assert numpypy.zeros((3, 1, 2)).shape == (3, 1, 2) + assert numpypy.array([[1], [2], [3]]).shape == (3, 1) + assert len(numpypy.zeros((3, 1, 2))) == 3 + raises(TypeError, len, numpypy.zeros(())) + raises(ValueError, numpypy.array, [[1, 2], 3], dtype=float) def test_getsetitem(self): - import _numpypy - a = _numpypy.zeros((2, 3, 1)) + import numpypy + a = numpypy.zeros((2, 3, 1)) raises(IndexError, a.__getitem__, (2, 0, 0)) raises(IndexError, a.__getitem__, (0, 3, 0)) From noreply at buildbot.pypy.org Mon Feb 25 14:12:20 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Mon, 25 Feb 2013 14:12:20 +0100 (CET) Subject: [pypy-commit] pypy cleanup-numpypy-namespace: enable numpypy.{choose, repeat} Message-ID: <20130225131220.1D0711C008F@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: cleanup-numpypy-namespace Changeset: r61758:89d20ee06fb3 Date: 2013-02-25 08:01 -0500 http://bitbucket.org/pypy/pypy/changeset/89d20ee06fb3/ Log: enable numpypy.{choose,repeat} diff --git a/lib_pypy/numpypy/core/fromnumeric.py b/lib_pypy/numpypy/core/fromnumeric.py --- a/lib_pypy/numpypy/core/fromnumeric.py +++ b/lib_pypy/numpypy/core/fromnumeric.py @@ -16,6 +16,7 @@ ###################################################################### import numpypy +from _numpypy import choose, repeat # Module containing non-deprecated functions borrowed from Numeric. __docformat__ = "restructuredtext en" @@ -274,7 +275,7 @@ [-1, -2, -3, -4, -5]]]) """ - raise NotImplementedError('Waiting on interp level method') + return choose(a, choices, out, mode) def repeat(a, repeats, axis=None): @@ -316,7 +317,7 @@ [3, 4]]) """ - raise NotImplementedError('Waiting on interp level method') + return repeat(a, repeats, axis) def put(a, ind, v, mode='raise'): diff --git a/pypy/module/micronumpy/__init__.py b/pypy/module/micronumpy/__init__.py --- a/pypy/module/micronumpy/__init__.py +++ b/pypy/module/micronumpy/__init__.py @@ -16,7 +16,6 @@ 'fromstring': 'interp_support.fromstring', 'flatiter': 'interp_flatiter.W_FlatIterator', 'concatenate': 'interp_arrayops.concatenate', - 'repeat': 'interp_arrayops.repeat', 'where': 'interp_arrayops.where', 'count_nonzero': 'interp_arrayops.count_nonzero', @@ -180,7 +179,10 @@ class Module(MixedModule): applevel_name = '_numpypy' appleveldefs = {} - interpleveldefs = {} + interpleveldefs = { + 'choose': 'interp_arrayops.choose', + 'repeat': 'interp_arrayops.repeat', + } submodules = { 'multiarray': MultiArrayModule, 'numerictypes': NumericTypesModule, diff --git a/pypy/module/micronumpy/interp_arrayops.py b/pypy/module/micronumpy/interp_arrayops.py --- a/pypy/module/micronumpy/interp_arrayops.py +++ b/pypy/module/micronumpy/interp_arrayops.py @@ -135,7 +135,7 @@ return res @unwrap_spec(repeats=int) -def repeat(space, w_arr, repeats, w_axis=None): +def repeat(space, w_arr, repeats, w_axis): arr = convert_to_array(space, w_arr) if space.is_none(w_axis): arr = arr.descr_flatten(space) @@ -161,14 +161,21 @@ def count_nonzero(space, w_obj): return space.wrap(loop.count_all_true(convert_to_array(space, w_obj))) -def choose(space, arr, w_choices, out, mode): + at unwrap_spec(mode=str) +def choose(space, w_arr, w_choices, w_out, mode): + arr = convert_to_array(space, w_arr) choices = [convert_to_array(space, w_item) for w_item in space.listview(w_choices)] if not choices: raise OperationError(space.w_ValueError, space.wrap("choices list cannot be empty")) - shape = shape_agreement_multiple(space, choices + [out]) - out = interp_dtype.dtype_agreement(space, choices, shape, out) + if space.is_none(w_out): + w_out = None + elif not isinstance(w_out, W_NDimArray): + raise OperationError(space.w_TypeError, space.wrap( + "return arrays must be of ArrayType")) + shape = shape_agreement_multiple(space, choices + [w_out]) + out = interp_dtype.dtype_agreement(space, choices, shape, w_out) dtype = out.get_dtype() if mode not in MODES: raise OperationError(space.w_ValueError, diff --git a/pypy/module/micronumpy/interp_numarray.py b/pypy/module/micronumpy/interp_numarray.py --- a/pypy/module/micronumpy/interp_numarray.py +++ b/pypy/module/micronumpy/interp_numarray.py @@ -14,7 +14,7 @@ from pypy.module.micronumpy.appbridge import get_appbridge_cache from pypy.module.micronumpy import loop from pypy.module.micronumpy.dot import match_dot_shapes -from pypy.module.micronumpy.interp_arrayops import repeat +from pypy.module.micronumpy.interp_arrayops import repeat, choose from rpython.tool.sourcetools import func_with_new_name from rpython.rlib import jit from rpython.rlib.rstring import StringBuilder @@ -452,13 +452,8 @@ return res @unwrap_spec(mode=str) - def descr_choose(self, space, w_choices, mode='raise', w_out=None): - if space.is_none(w_out): - w_out = None - elif not isinstance(w_out, W_NDimArray): - raise OperationError(space.w_TypeError, space.wrap( - "return arrays must be of ArrayType")) - return interp_arrayops.choose(space, self, w_choices, w_out, mode) + def descr_choose(self, space, w_choices, w_out=None, mode='raise'): + return choose(space, self, w_choices, w_out, mode) def descr_clip(self, space, w_min, w_max, w_out=None): if space.is_none(w_out): diff --git a/pypy/module/micronumpy/test/test_arrayops.py b/pypy/module/micronumpy/test/test_arrayops.py --- a/pypy/module/micronumpy/test/test_arrayops.py +++ b/pypy/module/micronumpy/test/test_arrayops.py @@ -85,10 +85,12 @@ assert c == 12.0 def test_choose_basic(self): - from numpypy import array + from numpypy import array, choose a, b, c = array([1, 2, 3]), array([4, 5, 6]), array([7, 8, 9]) r = array([2, 1, 0]).choose([a, b, c]) assert (r == [7, 5, 3]).all() + r = choose(array([2, 1, 0]), [a, b, c]) + assert (r == [7, 5, 3]).all() def test_choose_broadcast(self): from numpypy import array @@ -110,7 +112,7 @@ from numpypy import array a, b, c = array([1, 2, 3]), [4, 5, 6], 13 raises(ValueError, "array([3, 1, 0]).choose([a, b, c])") - raises(ValueError, "array([3, 1, 0]).choose([a, b, c], 'raises')") + raises(ValueError, "array([3, 1, 0]).choose([a, b, c], mode='raises')") raises(ValueError, "array([3, 1, 0]).choose([])") raises(ValueError, "array([-1, -2, -3]).choose([a, b, c])") r = array([4, 1, 0]).choose([a, b, c], mode='clip') From noreply at buildbot.pypy.org Mon Feb 25 14:12:21 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Mon, 25 Feb 2013 14:12:21 +0100 (CET) Subject: [pypy-commit] pypy default: merge heads Message-ID: <20130225131221.429B61C0237@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61759:816b7affe3c1 Date: 2013-02-25 08:11 -0500 http://bitbucket.org/pypy/pypy/changeset/816b7affe3c1/ Log: merge heads diff --git a/rpython/jit/metainterp/pyjitpl.py b/rpython/jit/metainterp/pyjitpl.py --- a/rpython/jit/metainterp/pyjitpl.py +++ b/rpython/jit/metainterp/pyjitpl.py @@ -1296,7 +1296,7 @@ self.make_result_of_lastop(resbox) # ^^^ this is done before handle_possible_exception() because we # need the box to show up in get_list_of_active_boxes() - if pure and self.metainterp.last_exc_value_box is None: + if pure and self.metainterp.last_exc_value_box is None and resbox: resbox = self.metainterp.record_result_of_call_pure(resbox) exc = exc and not isinstance(resbox, Const) if exc: diff --git a/rpython/jit/metainterp/test/test_call.py b/rpython/jit/metainterp/test/test_call.py --- a/rpython/jit/metainterp/test/test_call.py +++ b/rpython/jit/metainterp/test/test_call.py @@ -25,3 +25,21 @@ res = self.interp_operations(f, [3]) assert res == f(3) + def test_call_elidable_none(self): + d = {} + + @jit.elidable + def f(a): + return d.get(a, None) + + driver = jit.JitDriver(greens = [], reds = ['n']) + + def main(n): + while n > 0: + driver.jit_merge_point(n=n) + f(n) + f(n) + n -= 1 + return 3 + + self.meta_interp(main, [10]) From noreply at buildbot.pypy.org Mon Feb 25 15:20:20 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Mon, 25 Feb 2013 15:20:20 +0100 (CET) Subject: [pypy-commit] pypy cleanup-numpypy-namespace: fix choose/repeat name clashes Message-ID: <20130225142020.A7F271C0237@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: cleanup-numpypy-namespace Changeset: r61760:409e32c0f00e Date: 2013-02-25 08:36 -0500 http://bitbucket.org/pypy/pypy/changeset/409e32c0f00e/ Log: fix choose/repeat name clashes diff --git a/lib_pypy/numpypy/core/fromnumeric.py b/lib_pypy/numpypy/core/fromnumeric.py --- a/lib_pypy/numpypy/core/fromnumeric.py +++ b/lib_pypy/numpypy/core/fromnumeric.py @@ -16,7 +16,7 @@ ###################################################################### import numpypy -from _numpypy import choose, repeat +import _numpypy # Module containing non-deprecated functions borrowed from Numeric. __docformat__ = "restructuredtext en" @@ -275,7 +275,7 @@ [-1, -2, -3, -4, -5]]]) """ - return choose(a, choices, out, mode) + return _numpypy.choose(a, choices, out, mode) def repeat(a, repeats, axis=None): @@ -317,7 +317,7 @@ [3, 4]]) """ - return repeat(a, repeats, axis) + return _numpypy.repeat(a, repeats, axis) def put(a, ind, v, mode='raise'): From noreply at buildbot.pypy.org Mon Feb 25 15:20:21 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Mon, 25 Feb 2013 15:20:21 +0100 (CET) Subject: [pypy-commit] pypy cleanup-numpypy-namespace: these lines no longer make sense Message-ID: <20130225142021.D5FCD1C0237@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: cleanup-numpypy-namespace Changeset: r61761:946d226a877c Date: 2013-02-25 09:10 -0500 http://bitbucket.org/pypy/pypy/changeset/946d226a877c/ Log: these lines no longer make sense diff --git a/pypy/module/micronumpy/test/test_base.py b/pypy/module/micronumpy/test/test_base.py --- a/pypy/module/micronumpy/test/test_base.py +++ b/pypy/module/micronumpy/test/test_base.py @@ -15,7 +15,6 @@ if '__pypy__' not in sys.builtin_module_names: import numpy sys.modules['numpypy'] = numpy - sys.modules['_numpypy'] = numpy cls.w_non_native_prefix = cls.space.wrap(nonnative_byteorder_prefix) cls.w_native_prefix = cls.space.wrap(byteorder_prefix) diff --git a/pypy/module/micronumpy/test/test_numarray.py b/pypy/module/micronumpy/test/test_numarray.py --- a/pypy/module/micronumpy/test/test_numarray.py +++ b/pypy/module/micronumpy/test/test_numarray.py @@ -2579,7 +2579,6 @@ #assert a == 'x' def test_flexible_repr(self): - # numpypy overrides _numpypy repr with pure python one from numpypy import array a = array(['abc'],'S3') s = repr(a) From noreply at buildbot.pypy.org Mon Feb 25 15:20:23 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Mon, 25 Feb 2013 15:20:23 +0100 (CET) Subject: [pypy-commit] pypy default: fix this test for running against numpy Message-ID: <20130225142023.0DE8F1C0237@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61762:22a6275e2e6e Date: 2013-02-25 09:11 -0500 http://bitbucket.org/pypy/pypy/changeset/22a6275e2e6e/ Log: fix this test for running against numpy diff --git a/pypy/module/test_lib_pypy/numpypy/test_numpy.py b/pypy/module/test_lib_pypy/numpypy/test_numpy.py --- a/pypy/module/test_lib_pypy/numpypy/test_numpy.py +++ b/pypy/module/test_lib_pypy/numpypy/test_numpy.py @@ -55,7 +55,8 @@ numpypy.core.multiarray.set_string_function def test_constants(self): + import math import numpypy assert numpypy.PZERO == numpypy.NZERO == 0.0 - assert numpypy.inf is float('inf') - assert numpypy.nan is float('nan') + assert math.isinf(numpypy.inf) + assert math.isnan(numpypy.nan) From noreply at buildbot.pypy.org Mon Feb 25 15:20:24 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Mon, 25 Feb 2013 15:20:24 +0100 (CET) Subject: [pypy-commit] pypy cleanup-numpypy-namespace: merge default Message-ID: <20130225142024.3CB781C0237@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: cleanup-numpypy-namespace Changeset: r61763:2529b6fb4b71 Date: 2013-02-25 09:11 -0500 http://bitbucket.org/pypy/pypy/changeset/2529b6fb4b71/ Log: merge default diff --git a/pypy/module/test_lib_pypy/numpypy/test_numpy.py b/pypy/module/test_lib_pypy/numpypy/test_numpy.py --- a/pypy/module/test_lib_pypy/numpypy/test_numpy.py +++ b/pypy/module/test_lib_pypy/numpypy/test_numpy.py @@ -55,7 +55,8 @@ numpypy.core.multiarray.set_string_function def test_constants(self): + import math import numpypy assert numpypy.PZERO == numpypy.NZERO == 0.0 - assert numpypy.inf is float('inf') - assert numpypy.nan is float('nan') + assert math.isinf(numpypy.inf) + assert math.isnan(numpypy.nan) diff --git a/rpython/jit/metainterp/pyjitpl.py b/rpython/jit/metainterp/pyjitpl.py --- a/rpython/jit/metainterp/pyjitpl.py +++ b/rpython/jit/metainterp/pyjitpl.py @@ -1296,7 +1296,7 @@ self.make_result_of_lastop(resbox) # ^^^ this is done before handle_possible_exception() because we # need the box to show up in get_list_of_active_boxes() - if pure and self.metainterp.last_exc_value_box is None: + if pure and self.metainterp.last_exc_value_box is None and resbox: resbox = self.metainterp.record_result_of_call_pure(resbox) exc = exc and not isinstance(resbox, Const) if exc: diff --git a/rpython/jit/metainterp/test/test_call.py b/rpython/jit/metainterp/test/test_call.py --- a/rpython/jit/metainterp/test/test_call.py +++ b/rpython/jit/metainterp/test/test_call.py @@ -25,3 +25,21 @@ res = self.interp_operations(f, [3]) assert res == f(3) + def test_call_elidable_none(self): + d = {} + + @jit.elidable + def f(a): + return d.get(a, None) + + driver = jit.JitDriver(greens = [], reds = ['n']) + + def main(n): + while n > 0: + driver.jit_merge_point(n=n) + f(n) + f(n) + n -= 1 + return 3 + + self.meta_interp(main, [10]) From noreply at buildbot.pypy.org Mon Feb 25 15:20:25 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Mon, 25 Feb 2013 15:20:25 +0100 (CET) Subject: [pypy-commit] pypy default: merge cleanup-numpypy-namespace Message-ID: <20130225142025.A12311C0237@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61764:7a2c46bcc15a Date: 2013-02-25 09:19 -0500 http://bitbucket.org/pypy/pypy/changeset/7a2c46bcc15a/ Log: merge cleanup-numpypy-namespace diff too long, truncating to 2000 out of 3788 lines diff --git a/lib_pypy/numpypy/core/__init__.py b/lib_pypy/numpypy/core/__init__.py --- a/lib_pypy/numpypy/core/__init__.py +++ b/lib_pypy/numpypy/core/__init__.py @@ -1,5 +1,3 @@ -import _numpypy -from _numpypy import * import numeric from numeric import * import fromnumeric @@ -8,10 +6,9 @@ from shape_base import * from fromnumeric import amax as max, amin as min -from _numpypy import absolute as abs +from numeric import absolute as abs __all__ = [] -__all__ += _numpypy.__all__ __all__ += numeric.__all__ __all__ += fromnumeric.__all__ __all__ += shape_base.__all__ diff --git a/lib_pypy/numpypy/core/_methods.py b/lib_pypy/numpypy/core/_methods.py --- a/lib_pypy/numpypy/core/_methods.py +++ b/lib_pypy/numpypy/core/_methods.py @@ -1,11 +1,9 @@ # Array methods which are called by the both the C-code for the method # and the Python code for the NumPy-namespace function -#from numpy.core import multiarray as mu -#from numpy.core import umath as um -import _numpypy as mu -um = mu -from numpy.core.numeric import asanyarray +import multiarray as mu +import umath as um +from numeric import asanyarray def _amax(a, axis=None, out=None, keepdims=False): return um.maximum.reduce(a, axis=axis, diff --git a/lib_pypy/numpypy/core/arrayprint.py b/lib_pypy/numpypy/core/arrayprint.py --- a/lib_pypy/numpypy/core/arrayprint.py +++ b/lib_pypy/numpypy/core/arrayprint.py @@ -13,9 +13,9 @@ # and by Travis Oliphant 2005-8-22 for numpy import sys -import _numpypy as _nt -from _numpypy import maximum, minimum, absolute, not_equal, isnan, isinf -#from _numpypy import format_longfloat, datetime_as_string, datetime_data +import numerictypes as _nt +from umath import maximum, minimum, absolute, not_equal, isnan, isinf +#from multiarray import format_longfloat, datetime_as_string, datetime_data from fromnumeric import ravel diff --git a/lib_pypy/numpypy/core/fromnumeric.py b/lib_pypy/numpypy/core/fromnumeric.py --- a/lib_pypy/numpypy/core/fromnumeric.py +++ b/lib_pypy/numpypy/core/fromnumeric.py @@ -16,6 +16,7 @@ ###################################################################### import numpypy +import _numpypy # Module containing non-deprecated functions borrowed from Numeric. __docformat__ = "restructuredtext en" @@ -274,7 +275,7 @@ [-1, -2, -3, -4, -5]]]) """ - raise NotImplementedError('Waiting on interp level method') + return _numpypy.choose(a, choices, out, mode) def repeat(a, repeats, axis=None): @@ -316,7 +317,7 @@ [3, 4]]) """ - raise NotImplementedError('Waiting on interp level method') + return _numpypy.repeat(a, repeats, axis) def put(a, ind, v, mode='raise'): diff --git a/lib_pypy/numpypy/core/multiarray.py b/lib_pypy/numpypy/core/multiarray.py --- a/lib_pypy/numpypy/core/multiarray.py +++ b/lib_pypy/numpypy/core/multiarray.py @@ -1,1 +1,1 @@ -from _numpypy import set_string_function, typeinfo +from _numpypy.multiarray import * diff --git a/lib_pypy/numpypy/core/numeric.py b/lib_pypy/numpypy/core/numeric.py --- a/lib_pypy/numpypy/core/numeric.py +++ b/lib_pypy/numpypy/core/numeric.py @@ -1,21 +1,20 @@ __all__ = [ - 'ufunc', - 'asanyarray', 'base_repr', + 'newaxis', 'ufunc', + 'asarray', 'asanyarray', 'base_repr', 'array_repr', 'array_str', 'set_string_function', - 'array_equal', 'asarray', 'outer', 'identity', 'little_endian', + 'array_equal', 'outer', 'identity', 'little_endian', 'Inf', 'inf', 'infty', 'Infinity', 'nan', 'NaN', 'False_', 'True_', ] -from _numpypy import array, ndarray, int_, float_, bool_, flexible #, complex_# , longlong -from _numpypy import concatenate, sin -from .fromnumeric import any import sys import multiarray +from multiarray import * +del set_string_function +del typeinfo import umath from umath import * -from numpypy.core.arrayprint import array2string - -ufunc = type(sin) +import numerictypes +from numerictypes import * def extend_all(module): adict = {} @@ -29,9 +28,13 @@ if a not in adict: __all__.append(a) +extend_all(multiarray) +__all__.remove('typeinfo') extend_all(umath) +extend_all(numerictypes) newaxis = None +ufunc = type(sin) # XXX this file to be reviewed def seterr(**args): @@ -142,6 +145,10 @@ res.append('-') return ''.join(reversed(res or '0')) + +#Use numarray's printing function +from arrayprint import array2string + _typelessdata = [int_, float_]#, complex_] # XXX #if issubclass(intc, int): @@ -327,6 +334,11 @@ else: return multiarray.set_string_function(f, repr) +set_string_function(array_str, 0) +set_string_function(array_repr, 1) + +little_endian = (sys.byteorder == 'little') + def array_equal(a1, a2): """ True if two arrays have the same shape and elements, False otherwise. @@ -438,16 +450,6 @@ """ return array(a, dtype, copy=False, order=order) -set_string_function(array_str, 0) -set_string_function(array_repr, 1) - -little_endian = (sys.byteorder == 'little') - -Inf = inf = infty = Infinity = PINF -nan = NaN = NAN -False_ = bool_(False) -True_ = bool_(True) - def outer(a,b): """ Compute the outer product of two vectors. @@ -551,3 +553,12 @@ """ from numpy import eye return eye(n, dtype=dtype) + +Inf = inf = infty = Infinity = PINF +nan = NaN = NAN +False_ = bool_(False) +True_ = bool_(True) + +import fromnumeric +from fromnumeric import * +extend_all(fromnumeric) diff --git a/lib_pypy/numpypy/core/shape_base.py b/lib_pypy/numpypy/core/shape_base.py --- a/lib_pypy/numpypy/core/shape_base.py +++ b/lib_pypy/numpypy/core/shape_base.py @@ -1,6 +1,6 @@ __all__ = ['atleast_1d', 'atleast_2d', 'atleast_3d', 'vstack', 'hstack'] -import _numpypy +import numeric as _nx from numeric import array, asanyarray, newaxis def atleast_1d(*arys): @@ -223,7 +223,7 @@ [4]]) """ - return _numpypy.concatenate(map(atleast_2d,tup),0) + return _nx.concatenate(map(atleast_2d,tup),0) def hstack(tup): """ @@ -270,6 +270,6 @@ arrs = map(atleast_1d,tup) # As a special case, dimension 0 of 1-dimensional arrays is "horizontal" if arrs[0].ndim == 1: - return _numpypy.concatenate(arrs, 0) + return _nx.concatenate(arrs, 0) else: - return _numpypy.concatenate(arrs, 1) + return _nx.concatenate(arrs, 1) diff --git a/lib_pypy/numpypy/core/umath.py b/lib_pypy/numpypy/core/umath.py --- a/lib_pypy/numpypy/core/umath.py +++ b/lib_pypy/numpypy/core/umath.py @@ -1,3 +1,5 @@ +from _numpypy.umath import * + import math e = math.e pi = math.pi diff --git a/lib_pypy/numpypy/lib/function_base.py b/lib_pypy/numpypy/lib/function_base.py --- a/lib_pypy/numpypy/lib/function_base.py +++ b/lib_pypy/numpypy/lib/function_base.py @@ -1,6 +1,6 @@ __all__ = ['average'] -from _numpypy import array +from ..core.numeric import array def average(a): # This implements a weighted average, for now we don't implement the diff --git a/lib_pypy/numpypy/lib/shape_base.py b/lib_pypy/numpypy/lib/shape_base.py --- a/lib_pypy/numpypy/lib/shape_base.py +++ b/lib_pypy/numpypy/lib/shape_base.py @@ -1,7 +1,7 @@ __all__ = ['dstack'] -import numpypy.core.numeric as _nx -from numpypy.core import atleast_3d +from ..core import numeric as _nx +from ..core import atleast_3d def dstack(tup): """ diff --git a/lib_pypy/numpypy/lib/twodim_base.py b/lib_pypy/numpypy/lib/twodim_base.py --- a/lib_pypy/numpypy/lib/twodim_base.py +++ b/lib_pypy/numpypy/lib/twodim_base.py @@ -1,6 +1,6 @@ __all__ = ['eye'] -from _numpypy import zeros +from ..core.numeric import zeros def eye(N, M=None, k=0, dtype=float): """ diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst --- a/pypy/doc/whatsnew-head.rst +++ b/pypy/doc/whatsnew-head.rst @@ -75,3 +75,6 @@ .. branch: enumerate-rstr Support enumerate() over rstr types. + +.. branch: cleanup-numpypy-namespace +Cleanup _numpypy and numpypy namespaces to more closely resemble numpy. diff --git a/pypy/module/micronumpy/__init__.py b/pypy/module/micronumpy/__init__.py --- a/pypy/module/micronumpy/__init__.py +++ b/pypy/module/micronumpy/__init__.py @@ -2,9 +2,8 @@ from pypy.module.micronumpy.interp_boxes import long_double_size, ENABLED_LONG_DOUBLE -class Module(MixedModule): - applevel_name = '_numpypy' - +class MultiArrayModule(MixedModule): + appleveldefs = {'arange': 'app_numpy.arange'} interpleveldefs = { 'ndarray': 'interp_numarray.W_NDimArray', 'dtype': 'interp_dtype.W_Dtype', @@ -17,13 +16,17 @@ 'fromstring': 'interp_support.fromstring', 'flatiter': 'interp_flatiter.W_FlatIterator', 'concatenate': 'interp_arrayops.concatenate', - 'repeat': 'interp_arrayops.repeat', 'where': 'interp_arrayops.where', 'count_nonzero': 'interp_arrayops.count_nonzero', 'set_string_function': 'appbridge.set_string_function', 'typeinfo': 'interp_dtype.get_dtype_cache(space).w_typeinfo', + } + +class NumericTypesModule(MixedModule): + appleveldefs = {} + interpleveldefs = { 'generic': 'interp_boxes.W_GenericBox', 'number': 'interp_boxes.W_NumberBox', 'integer': 'interp_boxes.W_IntegerBox', @@ -67,7 +70,30 @@ 'complex128': 'interp_boxes.W_Complex128Box', 'complex64': 'interp_boxes.W_Complex64Box', } + if ENABLED_LONG_DOUBLE: + long_double_dtypes = [ + ('longdouble', 'interp_boxes.W_LongDoubleBox'), + ('longfloat', 'interp_boxes.W_LongDoubleBox'), + ('clongdouble', 'interp_boxes.W_CLongDoubleBox'), + ('clongfloat', 'interp_boxes.W_CLongDoubleBox'), + ] + if long_double_size == 16: + long_double_dtypes += [ + ('float128', 'interp_boxes.W_Float128Box'), + ('complex256', 'interp_boxes.W_Complex256Box'), + ] + elif long_double_size == 12: + long_double_dtypes += [ + ('float96', 'interp_boxes.W_Float96Box'), + ('complex192', 'interp_boxes.W_Complex192Box'), + ] + for dt, box in long_double_dtypes: + interpleveldefs[dt] = box + +class UMathModule(MixedModule): + appleveldefs = {} + interpleveldefs = {} # ufuncs for exposed, impl in [ ("absolute", "absolute"), @@ -149,35 +175,16 @@ ]: interpleveldefs[exposed] = "interp_ufuncs.get(space).%s" % impl - appleveldefs = { - 'arange': 'app_numpy.arange', + +class Module(MixedModule): + applevel_name = '_numpypy' + appleveldefs = {} + interpleveldefs = { + 'choose': 'interp_arrayops.choose', + 'repeat': 'interp_arrayops.repeat', } - def setup_after_space_initialization(self): - space = self.space - all_list = sorted(Module.interpleveldefs.keys() + \ - Module.appleveldefs.keys()) - # found by set(numpypy.__all__) - set(numpy.__all__) - all_list.remove('set_string_function') - all_list.remove('typeinfo') - w_all = space.wrap(all_list) - space.setitem(self.w_dict, space.new_interned_str('__all__'), w_all) - -if ENABLED_LONG_DOUBLE: - long_double_dtypes = [ - ('longdouble', 'interp_boxes.W_LongDoubleBox'), - ('longfloat', 'interp_boxes.W_LongDoubleBox'), - ('clongdouble', 'interp_boxes.W_CLongDoubleBox'), - ('clongfloat', 'interp_boxes.W_CLongDoubleBox'), - ] - if long_double_size == 16: - long_double_dtypes += [ - ('float128', 'interp_boxes.W_Float128Box'), - ('complex256', 'interp_boxes.W_Complex256Box'), - ] - elif long_double_size == 12: - long_double_dtypes += [ - ('float96', 'interp_boxes.W_Float96Box'), - ('complex192', 'interp_boxes.W_Complex192Box'), - ] - for dt, box in long_double_dtypes: - Module.interpleveldefs[dt] = box + submodules = { + 'multiarray': MultiArrayModule, + 'numerictypes': NumericTypesModule, + 'umath': UMathModule, + } diff --git a/pypy/module/micronumpy/app_numpy.py b/pypy/module/micronumpy/app_numpy.py --- a/pypy/module/micronumpy/app_numpy.py +++ b/pypy/module/micronumpy/app_numpy.py @@ -10,9 +10,9 @@ stop = start start = 0 if dtype is None: - test = _numpypy.array([start, stop, step, 0]) + test = _numpypy.multiarray.array([start, stop, step, 0]) dtype = test.dtype - arr = _numpypy.zeros(int(math.ceil((stop - start) / step)), dtype=dtype) + arr = _numpypy.multiarray.zeros(int(math.ceil((stop - start) / step)), dtype=dtype) i = start for j in range(arr.size): arr[j] = i diff --git a/pypy/module/micronumpy/interp_arrayops.py b/pypy/module/micronumpy/interp_arrayops.py --- a/pypy/module/micronumpy/interp_arrayops.py +++ b/pypy/module/micronumpy/interp_arrayops.py @@ -135,7 +135,7 @@ return res @unwrap_spec(repeats=int) -def repeat(space, w_arr, repeats, w_axis=None): +def repeat(space, w_arr, repeats, w_axis): arr = convert_to_array(space, w_arr) if space.is_none(w_axis): arr = arr.descr_flatten(space) @@ -161,14 +161,21 @@ def count_nonzero(space, w_obj): return space.wrap(loop.count_all_true(convert_to_array(space, w_obj))) -def choose(space, arr, w_choices, out, mode): + at unwrap_spec(mode=str) +def choose(space, w_arr, w_choices, w_out, mode): + arr = convert_to_array(space, w_arr) choices = [convert_to_array(space, w_item) for w_item in space.listview(w_choices)] if not choices: raise OperationError(space.w_ValueError, space.wrap("choices list cannot be empty")) - shape = shape_agreement_multiple(space, choices + [out]) - out = interp_dtype.dtype_agreement(space, choices, shape, out) + if space.is_none(w_out): + w_out = None + elif not isinstance(w_out, W_NDimArray): + raise OperationError(space.w_TypeError, space.wrap( + "return arrays must be of ArrayType")) + shape = shape_agreement_multiple(space, choices + [w_out]) + out = interp_dtype.dtype_agreement(space, choices, shape, w_out) dtype = out.get_dtype() if mode not in MODES: raise OperationError(space.w_ValueError, diff --git a/pypy/module/micronumpy/interp_numarray.py b/pypy/module/micronumpy/interp_numarray.py --- a/pypy/module/micronumpy/interp_numarray.py +++ b/pypy/module/micronumpy/interp_numarray.py @@ -14,7 +14,7 @@ from pypy.module.micronumpy.appbridge import get_appbridge_cache from pypy.module.micronumpy import loop from pypy.module.micronumpy.dot import match_dot_shapes -from pypy.module.micronumpy.interp_arrayops import repeat +from pypy.module.micronumpy.interp_arrayops import repeat, choose from rpython.tool.sourcetools import func_with_new_name from rpython.rlib import jit from rpython.rlib.rstring import StringBuilder @@ -452,13 +452,8 @@ return res @unwrap_spec(mode=str) - def descr_choose(self, space, w_choices, mode='raise', w_out=None): - if space.is_none(w_out): - w_out = None - elif not isinstance(w_out, W_NDimArray): - raise OperationError(space.w_TypeError, space.wrap( - "return arrays must be of ArrayType")) - return interp_arrayops.choose(space, self, w_choices, w_out, mode) + def descr_choose(self, space, w_choices, w_out=None, mode='raise'): + return choose(space, self, w_choices, w_out, mode) def descr_clip(self, space, w_min, w_max, w_out=None): if space.is_none(w_out): diff --git a/pypy/module/micronumpy/test/test_arrayops.py b/pypy/module/micronumpy/test/test_arrayops.py --- a/pypy/module/micronumpy/test/test_arrayops.py +++ b/pypy/module/micronumpy/test/test_arrayops.py @@ -3,26 +3,26 @@ class AppTestNumSupport(BaseNumpyAppTest): def test_where(self): - from _numpypy import where, ones, zeros, array + from numpypy import where, ones, zeros, array a = [1, 2, 3, 0, -3] a = where(array(a) > 0, ones(5), zeros(5)) assert (a == [1, 1, 1, 0, 0]).all() def test_where_differing_dtypes(self): - from _numpypy import array, ones, zeros, where + from numpypy import array, ones, zeros, where a = [1, 2, 3, 0, -3] a = where(array(a) > 0, ones(5, dtype=int), zeros(5, dtype=float)) assert (a == [1, 1, 1, 0, 0]).all() def test_where_broadcast(self): - from _numpypy import array, where + from numpypy import array, where a = where(array([[1, 2, 3], [4, 5, 6]]) > 3, [1, 1, 1], 2) assert (a == [[2, 2, 2], [1, 1, 1]]).all() a = where(True, [1, 1, 1], 2) assert (a == [1, 1, 1]).all() def test_where_errors(self): - from _numpypy import where, array + from numpypy import where, array raises(ValueError, "where([1, 2, 3], [3, 4, 5])") raises(ValueError, "where([1, 2, 3], [3, 4, 5], [6, 7])") assert where(True, 1, 2) == array(1) @@ -35,7 +35,7 @@ # xxx def test_where_invalidates(self): - from _numpypy import where, ones, zeros, array + from numpypy import where, ones, zeros, array a = array([1, 2, 3, 0, -3]) b = where(a > 0, ones(5), zeros(5)) a[0] = 0 @@ -43,7 +43,7 @@ def test_dot(self): - from _numpypy import array, dot, arange + from numpypy import array, dot, arange a = array(range(5)) assert dot(a, a) == 30.0 @@ -74,7 +74,7 @@ assert (dot([[1,2],[3,4]],[5,6]) == [17, 39]).all() def test_dot_constant(self): - from _numpypy import array, dot + from numpypy import array, dot a = array(range(5)) b = a.dot(2.5) for i in xrange(5): @@ -85,19 +85,21 @@ assert c == 12.0 def test_choose_basic(self): - from _numpypy import array + from numpypy import array, choose a, b, c = array([1, 2, 3]), array([4, 5, 6]), array([7, 8, 9]) r = array([2, 1, 0]).choose([a, b, c]) assert (r == [7, 5, 3]).all() + r = choose(array([2, 1, 0]), [a, b, c]) + assert (r == [7, 5, 3]).all() def test_choose_broadcast(self): - from _numpypy import array + from numpypy import array a, b, c = array([1, 2, 3]), [4, 5, 6], 13 r = array([2, 1, 0]).choose([a, b, c]) assert (r == [13, 5, 3]).all() def test_choose_out(self): - from _numpypy import array + from numpypy import array a, b, c = array([1, 2, 3]), [4, 5, 6], 13 r = array([2, 1, 0]).choose([a, b, c], out=None) assert (r == [13, 5, 3]).all() @@ -107,10 +109,10 @@ assert (a == [13, 5, 3]).all() def test_choose_modes(self): - from _numpypy import array + from numpypy import array a, b, c = array([1, 2, 3]), [4, 5, 6], 13 raises(ValueError, "array([3, 1, 0]).choose([a, b, c])") - raises(ValueError, "array([3, 1, 0]).choose([a, b, c], 'raises')") + raises(ValueError, "array([3, 1, 0]).choose([a, b, c], mode='raises')") raises(ValueError, "array([3, 1, 0]).choose([])") raises(ValueError, "array([-1, -2, -3]).choose([a, b, c])") r = array([4, 1, 0]).choose([a, b, c], mode='clip') @@ -119,13 +121,13 @@ assert (r == [4, 5, 3]).all() def test_choose_dtype(self): - from _numpypy import array + from numpypy import array a, b, c = array([1.2, 2, 3]), [4, 5, 6], 13 r = array([2, 1, 0]).choose([a, b, c]) assert r.dtype == float def test_choose_dtype_out(self): - from _numpypy import array + from numpypy import array a, b, c = array([1, 2, 3]), [4, 5, 6], 13 x = array([0, 0, 0], dtype='i2') r = array([2, 1, 0]).choose([a, b, c], out=x) diff --git a/pypy/module/micronumpy/test/test_base.py b/pypy/module/micronumpy/test/test_base.py --- a/pypy/module/micronumpy/test/test_base.py +++ b/pypy/module/micronumpy/test/test_base.py @@ -15,7 +15,6 @@ if '__pypy__' not in sys.builtin_module_names: import numpy sys.modules['numpypy'] = numpy - sys.modules['_numpypy'] = numpy cls.w_non_native_prefix = cls.space.wrap(nonnative_byteorder_prefix) cls.w_native_prefix = cls.space.wrap(byteorder_prefix) diff --git a/pypy/module/micronumpy/test/test_complex.py b/pypy/module/micronumpy/test/test_complex.py --- a/pypy/module/micronumpy/test/test_complex.py +++ b/pypy/module/micronumpy/test/test_complex.py @@ -132,13 +132,13 @@ cls.w_c_pow = cls.space.wrap(interp2app(cls_c_pow)) def test_fabs(self): - from _numpypy import fabs, complex128 + from numpypy import fabs, complex128 a = complex128(complex(-5., 5.)) raises(TypeError, fabs, a) def test_fmax(self): - from _numpypy import fmax, array + from numpypy import fmax, array nnan, nan, inf, ninf = float('-nan'), float('nan'), float('inf'), float('-inf') a = array((complex(ninf, 10), complex(10, ninf), complex( inf, 10), complex(10, inf), @@ -165,7 +165,7 @@ assert (fmax(a, b) == res).all() def test_fmin(self): - from _numpypy import fmin, array + from numpypy import fmin, array nnan, nan, inf, ninf = float('-nan'), float('nan'), float('inf'), float('-inf') a = array((complex(ninf, 10), complex(10, ninf), complex( inf, 10), complex(10, inf), @@ -192,14 +192,14 @@ assert (fmin(a, b) == res).all() def test_signbit(self): - from _numpypy import signbit + from numpypy import signbit raises(TypeError, signbit, complex(1,1)) def test_reciprocal(self): - from _numpypy import array, reciprocal, complex64, complex128 + from numpypy import array, reciprocal, complex64, complex128 c_and_relerr = [(complex64, 2e-7), (complex128, 2e-15)] try: - from _numpypy import clongdouble + from numpypy import clongdouble c_and_relerr.append((clongdouble, 2e-30)) except: pass # no longdouble yet @@ -224,23 +224,23 @@ assert (a[0].imag - e.imag) < rel_err def test_floorceiltrunc(self): - from _numpypy import array, floor, ceil, trunc + from numpypy import array, floor, ceil, trunc a = array([ complex(-1.4, -1.4), complex(-1.5, -1.5)]) raises(TypeError, floor, a) raises(TypeError, ceil, a) raises(TypeError, trunc, a) def test_copysign(self): - from _numpypy import copysign, complex128 + from numpypy import copysign, complex128 a = complex128(complex(-5., 5.)) b = complex128(complex(0., 0.)) raises(TypeError, copysign, a, b) def test_exp2(self): - from _numpypy import array, exp2, complex128, complex64 + from numpypy import array, exp2, complex128, complex64 c_and_relerr = [(complex64, 2e-7), (complex128, 2e-15)] try: - from _numpypy import clongdouble + from numpypy import clongdouble c_and_relerr.append((clongdouble, 2e-30)) except: pass # no longdouble yet @@ -279,7 +279,7 @@ def test_expm1(self): import math, cmath - from _numpypy import array, expm1, complex128, complex64 + from numpypy import array, expm1, complex128, complex64 inf = float('inf') ninf = -float('inf') nan = float('nan') @@ -318,7 +318,7 @@ self.rAlmostEqual(t1, t2, rel_err=rel_err, msg=msg) def test_not_complex(self): - from _numpypy import (radians, deg2rad, degrees, rad2deg, + from numpypy import (radians, deg2rad, degrees, rad2deg, isneginf, isposinf, logaddexp, logaddexp2, fmod, arctan2) raises(TypeError, radians, complex(90,90)) @@ -333,7 +333,7 @@ raises (TypeError, fmod, complex(90,90), 3) def test_isnan_isinf(self): - from _numpypy import isnan, isinf, array + from numpypy import isnan, isinf, array assert (isnan(array([0.2+2j, complex(float('inf'),0), complex(0,float('inf')), complex(0,float('nan')), complex(float('nan'), 0)], dtype=complex)) == \ @@ -346,7 +346,7 @@ def test_square(self): - from _numpypy import square + from numpypy import square assert square(complex(3, 4)) == complex(3,4) * complex(3, 4) def test_power_complex(self): @@ -355,7 +355,7 @@ nan = float('nan') cmpl = complex from math import copysign - from _numpypy import power, array, complex128, complex64 + from numpypy import power, array, complex128, complex64 # note: in some settings (namely a x86-32 build without the JIT), # gcc optimizes the code in rlib.rcomplex.c_pow() to not truncate # the 10-byte values down to 8-byte values. It ends up with more @@ -392,7 +392,7 @@ self.rAlmostEqual(t1, t2, rel_err=rel_err, msg=msg) def test_conjugate(self): - from _numpypy import conj, conjugate, complex128, complex64 + from numpypy import conj, conjugate, complex128, complex64 import numpypy as np c0 = complex128(complex(2.5, 0)) @@ -416,7 +416,7 @@ def test_logn(self): import math, cmath # log and log10 are tested in math (1:1 from rcomplex) - from _numpypy import log2, array, complex128, complex64, log1p + from numpypy import log2, array, complex128, complex64, log1p inf = float('inf') ninf = -float('inf') nan = float('nan') @@ -473,7 +473,7 @@ self.rAlmostEqual(t1, t2, rel_err=rel_err, msg=msg) def test_logical_ops(self): - from _numpypy import logical_and, logical_or, logical_xor, logical_not + from numpypy import logical_and, logical_or, logical_xor, logical_not c1 = complex(1, 1) c3 = complex(3, 0) @@ -487,7 +487,7 @@ assert (logical_not([c1, c0]) == [False, True]).all() def test_minimum(self): - from _numpypy import array, minimum + from numpypy import array, minimum a = array([-5.0+5j, -5.0-5j, -0.0-10j, 1.0+10j]) b = array([ 3.0+10.0j, 3.0, -2.0+2.0j, -3.0+4.0j]) @@ -496,7 +496,7 @@ assert c[i] == min(a[i], b[i]) def test_maximum(self): - from _numpypy import array, maximum + from numpypy import array, maximum a = array([-5.0+5j, -5.0-5j, -0.0-10j, 1.0+10j]) b = array([ 3.0+10.0j, 3.0, -2.0+2.0j, -3.0+4.0j]) @@ -505,14 +505,14 @@ assert c[i] == max(a[i], b[i]) def test_basic(self): - from _numpypy import (complex128, complex64, add, array, dtype, + from numpypy import (complex128, complex64, add, array, dtype, subtract as sub, multiply, divide, negative, absolute as abs, floor_divide, real, imag, sign) - from _numpypy import (equal, not_equal, greater, greater_equal, less, + from numpypy import (equal, not_equal, greater, greater_equal, less, less_equal, isnan) complex_dtypes = [complex64, complex128] try: - from _numpypy import clongfloat + from numpypy import clongfloat complex_dtypes.append(clongfloat) except: pass @@ -588,15 +588,15 @@ inf_c = complex_(complex(float('inf'), 0.)) assert repr(abs(inf_c)) == 'inf' assert repr(abs(complex(float('nan'), float('nan')))) == 'nan' - # numpy actually raises an AttributeError, - # but _numpypy raises a TypeError + # numpy actually raises an AttributeError, + # but numpypy raises a TypeError raises((TypeError, AttributeError), 'c2.real = 10.') raises((TypeError, AttributeError), 'c2.imag = 10.') assert(real(c2) == 3.0) assert(imag(c2) == 4.0) def test_conj(self): - from _numpypy import array + from numpypy import array a = array([1 + 2j, 1 - 2j]) assert (a.conj() == [1 - 2j, 1 + 2j]).all() @@ -605,7 +605,7 @@ if self.isWindows: skip('windows does not support c99 complex') import sys - import _numpypy as np + import numpypy as np rAlmostEqual = self.rAlmostEqual for complex_, abs_err, testcases in (\ diff --git a/pypy/module/micronumpy/test/test_dtypes.py b/pypy/module/micronumpy/test/test_dtypes.py --- a/pypy/module/micronumpy/test/test_dtypes.py +++ b/pypy/module/micronumpy/test/test_dtypes.py @@ -17,7 +17,7 @@ class AppTestDtypes(BaseAppTestDtypes): def test_dtype(self): - from _numpypy import dtype + from numpypy import dtype d = dtype('?') assert d.num == 0 @@ -36,7 +36,7 @@ raises(KeyError, 'dtype(int)["asdasd"]') def test_dtype_eq(self): - from _numpypy import dtype + from numpypy import dtype assert dtype("int8") == "int8" assert "int8" == dtype("int8") @@ -44,7 +44,7 @@ assert dtype(bool) == bool def test_dtype_with_types(self): - from _numpypy import dtype + from numpypy import dtype assert dtype(bool).num == 0 if self.ptr_size == 4: @@ -66,13 +66,13 @@ assert dtype(float).num == 12 def test_array_dtype_attr(self): - from _numpypy import array, dtype + from numpypy import array, dtype a = array(range(5), long) assert a.dtype is dtype(long) def test_repr_str(self): - from _numpypy import dtype + from numpypy import dtype assert '.dtype' in repr(dtype) d = dtype('?') @@ -80,8 +80,7 @@ assert str(d) == "bool" def test_bool_array(self): - from _numpypy import array - from numpypy import False_, True_ + from numpypy import array, False_, True_ a = array([0, 1, 2, 2.5], dtype='?') assert a[0] is False_ @@ -89,8 +88,7 @@ assert a[i] is True_ def test_copy_array_with_dtype(self): - from _numpypy import array, longlong - from numpypy import False_ + from numpypy import array, longlong, False_ a = array([0, 1, 2, 3], dtype=long) # int on 64-bit, long in 32-bit @@ -104,37 +102,35 @@ assert b[0] is False_ def test_zeros_bool(self): - from _numpypy import zeros - from numpypy import False_ + from numpypy import zeros, False_ a = zeros(10, dtype=bool) for i in range(10): assert a[i] is False_ def test_ones_bool(self): - from _numpypy import ones - from numpypy import True_ + from numpypy import ones, True_ a = ones(10, dtype=bool) for i in range(10): assert a[i] is True_ def test_zeros_long(self): - from _numpypy import zeros, longlong + from numpypy import zeros, longlong a = zeros(10, dtype=long) for i in range(10): assert isinstance(a[i], longlong) assert a[1] == 0 def test_ones_long(self): - from _numpypy import ones, longlong + from numpypy import ones, longlong a = ones(10, dtype=long) for i in range(10): assert isinstance(a[i], longlong) assert a[1] == 1 def test_overflow(self): - from _numpypy import array, dtype + from numpypy import array, dtype assert array([128], 'b')[0] == -128 assert array([256], 'B')[0] == 0 assert array([32768], 'h')[0] == -32768 @@ -146,7 +142,7 @@ raises(OverflowError, "array([2**64], 'Q')") def test_bool_binop_types(self): - from _numpypy import array, dtype + from numpypy import array, dtype types = [ '?', 'b', 'B', 'h', 'H', 'i', 'I', 'l', 'L', 'q', 'Q', 'f', 'd', 'e' @@ -156,7 +152,7 @@ assert (a + array([0], t)).dtype is dtype(t) def test_binop_types(self): - from _numpypy import array, dtype + from numpypy import array, dtype tests = [('b','B','h'), ('b','h','h'), ('b','H','i'), ('b','i','i'), ('b','l','l'), ('b','q','q'), ('b','Q','d'), ('B','h','h'), ('B','H','H'), ('B','i','i'), ('B','I','I'), ('B','l','l'), @@ -180,7 +176,7 @@ assert (d1, d2) == (d1, d2) and d3 is dtype(dout) def test_add_int8(self): - from _numpypy import array, dtype + from numpypy import array, dtype a = array(range(5), dtype="int8") b = a + a @@ -189,7 +185,7 @@ assert b[i] == i * 2 def test_add_int16(self): - from _numpypy import array, dtype + from numpypy import array, dtype a = array(range(5), dtype="int16") b = a + a @@ -198,7 +194,7 @@ assert b[i] == i * 2 def test_add_uint32(self): - from _numpypy import array, dtype + from numpypy import array, dtype a = array(range(5), dtype="I") b = a + a @@ -207,49 +203,49 @@ assert b[i] == i * 2 def test_shape(self): - from _numpypy import dtype + from numpypy import dtype assert dtype(long).shape == () def test_cant_subclass(self): - from _numpypy import dtype + from numpypy import dtype # You can't subclass dtype raises(TypeError, type, "Foo", (dtype,), {}) def test_can_subclass(self): - import _numpypy - class xyz(_numpypy.void): + import numpypy + class xyz(numpypy.void): pass assert True def test_aliases(self): - from _numpypy import dtype + from numpypy import dtype assert dtype("float") is dtype(float) def test_index_int8(self): - from _numpypy import array, int8 + from numpypy import array, int8 a = array(range(10), dtype=int8) b = array([0] * 10, dtype=int8) for idx in b: a[idx] += 1 def test_index_int16(self): - from _numpypy import array, int16 + from numpypy import array, int16 a = array(range(10), dtype=int16) b = array([0] * 10, dtype=int16) for idx in b: a[idx] += 1 def test_index_int32(self): - from _numpypy import array, int32 + from numpypy import array, int32 a = array(range(10), dtype=int32) b = array([0] * 10, dtype=int32) for idx in b: a[idx] += 1 def test_index_int64(self): - from _numpypy import array, int64 + from numpypy import array, int64 a = array(range(10), dtype=int64) b = array([0] * 10, dtype=int64) @@ -257,7 +253,7 @@ a[idx] += 1 def test_hash(self): - import _numpypy as numpy + import numpypy as numpy for tp, value in [ (numpy.int8, 4), (numpy.int16, 5), @@ -272,7 +268,7 @@ class AppTestTypes(BaseAppTestDtypes): def test_abstract_types(self): - import _numpypy as numpy + import numpypy as numpy raises(TypeError, numpy.generic, 0) raises(TypeError, numpy.number, 0) @@ -312,12 +308,12 @@ #assert a.dtype is numpy.dtype('|V4') def test_new(self): - import _numpypy as np + import numpypy as np assert np.int_(4) == 4 assert np.float_(3.4) == 3.4 def test_pow(self): - from _numpypy import int_ + from numpypy import int_ assert int_(4) ** 2 == 16 def test_bool(self): @@ -336,7 +332,7 @@ assert numpy.bool_("False") is numpy.True_ def test_int8(self): - import _numpypy as numpy + import numpypy as numpy assert numpy.int8.mro() == [numpy.int8, numpy.signedinteger, numpy.integer, numpy.number, @@ -360,7 +356,7 @@ assert numpy.int8('128') == -128 def test_uint8(self): - import _numpypy as numpy + import numpypy as numpy assert numpy.uint8.mro() == [numpy.uint8, numpy.unsignedinteger, numpy.integer, numpy.number, @@ -385,7 +381,7 @@ assert numpy.uint8('256') == 0 def test_int16(self): - import _numpypy as numpy + import numpypy as numpy x = numpy.int16(3) assert x == 3 @@ -395,7 +391,7 @@ assert numpy.int16('32768') == -32768 def test_uint16(self): - import _numpypy as numpy + import numpypy as numpy assert numpy.uint16(65535) == 65535 assert numpy.uint16(65536) == 0 @@ -404,7 +400,7 @@ def test_int32(self): import sys - import _numpypy as numpy + import numpypy as numpy x = numpy.int32(23) assert x == 23 @@ -420,7 +416,7 @@ def test_uint32(self): import sys - import _numpypy as numpy + import numpypy as numpy assert numpy.uint32(10) == 10 @@ -431,7 +427,7 @@ assert numpy.uint32('4294967296') == 0 def test_int_(self): - import _numpypy as numpy + import numpypy as numpy assert numpy.int_ is numpy.dtype(int).type assert numpy.int_.mro() == [numpy.int_, numpy.signedinteger, @@ -440,7 +436,7 @@ def test_int64(self): import sys - import _numpypy as numpy + import numpypy as numpy if sys.maxint == 2 ** 63 -1: assert numpy.int64.mro() == [numpy.int64, numpy.signedinteger, @@ -462,7 +458,7 @@ def test_uint64(self): import sys - import _numpypy as numpy + import numpypy as numpy assert numpy.uint64.mro() == [numpy.uint64, numpy.unsignedinteger, numpy.integer, numpy.number, @@ -479,7 +475,7 @@ raises(OverflowError, numpy.uint64(18446744073709551616)) def test_float16(self): - import _numpypy as numpy + import numpypy as numpy assert numpy.float16.mro() == [numpy.float16, numpy.floating, numpy.inexact, numpy.number, numpy.generic, object] @@ -490,7 +486,7 @@ def test_float32(self): - import _numpypy as numpy + import numpypy as numpy assert numpy.float32.mro() == [numpy.float32, numpy.floating, numpy.inexact, numpy.number, @@ -501,7 +497,7 @@ raises(ValueError, numpy.float32, '23.2df') def test_float64(self): - import _numpypy as numpy + import numpypy as numpy assert numpy.float64.mro() == [numpy.float64, numpy.floating, numpy.inexact, numpy.number, @@ -518,20 +514,20 @@ raises(ValueError, numpy.float64, '23.2df') def test_float_None(self): - import _numpypy as numpy + import numpypy as numpy from math import isnan assert isnan(numpy.float32(None)) assert isnan(numpy.float64(None)) def test_complex_floating(self): - import _numpypy as numpy + import numpypy as numpy assert numpy.complexfloating.__mro__ == (numpy.complexfloating, numpy.inexact, numpy.number, numpy.generic, object) def test_complex_format(self): import sys - import _numpypy as numpy + import numpypy as numpy for complex_ in (numpy.complex128, numpy.complex64,): for real, imag, should in [ @@ -571,7 +567,7 @@ assert "{:g}".format(numpy.complex_(0.5+1.5j)) == '{:g}'.format(0.5+1.5j) def test_complex(self): - import _numpypy as numpy + import numpypy as numpy assert numpy.complex_ is numpy.complex128 assert numpy.complex64.__mro__ == (numpy.complex64, @@ -589,7 +585,7 @@ assert d.char == 'F' def test_subclass_type(self): - import _numpypy as numpy + import numpypy as numpy class X(numpy.float64): def m(self): @@ -600,12 +596,12 @@ assert b.m() == 12 def test_long_as_index(self): - from _numpypy import int_, float64 + from numpypy import int_, float64 assert (1, 2, 3)[int_(1)] == 2 raises(TypeError, lambda: (1, 2, 3)[float64(1)]) def test_int(self): - from _numpypy import int32, int64, int_ + from numpypy import int32, int64, int_ import sys assert issubclass(int_, int) if sys.maxint == (1<<31) - 1: @@ -616,7 +612,7 @@ assert int_ is int64 def test_various_types(self): - import _numpypy as numpy + import numpypy as numpy assert numpy.int16 is numpy.short assert numpy.int8 is numpy.byte @@ -629,7 +625,7 @@ assert numpy.uintp is numpy.uint64 def test_mro(self): - import _numpypy as numpy + import numpypy as numpy assert numpy.int16.__mro__ == (numpy.int16, numpy.signedinteger, numpy.integer, numpy.number, @@ -638,8 +634,7 @@ def test_operators(self): from operator import truediv - from _numpypy import float64, int_ - from numpypy import True_, False_ + from numpypy import float64, int_, True_, False_ assert 5 / int_(2) == int_(2) assert truediv(int_(3), int_(2)) == float64(1.5) assert truediv(3, int_(2)) == float64(1.5) @@ -664,7 +659,7 @@ raises(TypeError, lambda: float64(3) & 1) def test_alternate_constructs(self): - from _numpypy import dtype + from numpypy import dtype nnp = self.non_native_prefix byteorder = self.native_prefix assert dtype('i8') == dtype(byteorder + 'i8') == dtype('=i8') # XXX should be equal == dtype(long) @@ -674,23 +669,23 @@ assert dtype(byteorder + 'i8').byteorder == '=' def test_intp(self): - from _numpypy import dtype + from numpypy import dtype assert dtype('p') == dtype('intp') assert dtype('P') == dtype('uintp') def test_alignment(self): - from _numpypy import dtype + from numpypy import dtype assert dtype('i4').alignment == 4 class AppTestStrUnicodeDtypes(BaseNumpyAppTest): def test_str_unicode(self): - from _numpypy import str_, unicode_, character, flexible, generic + from numpypy import str_, unicode_, character, flexible, generic assert str_.mro() == [str_, str, basestring, character, flexible, generic, object] assert unicode_.mro() == [unicode_, unicode, basestring, character, flexible, generic, object] def test_str_dtype(self): - from _numpypy import dtype, str_ + from numpypy import dtype, str_ raises(TypeError, "dtype('Sx')") d = dtype('S8') @@ -702,7 +697,7 @@ assert d.num == 18 def test_unicode_dtype(self): - from _numpypy import dtype, unicode_ + from numpypy import dtype, unicode_ raises(TypeError, "dtype('Ux')") d = dtype('U8') @@ -714,16 +709,16 @@ assert d.num == 19 def test_string_boxes(self): - from _numpypy import str_ + from numpypy import str_ assert isinstance(str_(3), str_) def test_unicode_boxes(self): - from _numpypy import unicode_ + from numpypy import unicode_ assert isinstance(unicode_(3), unicode) class AppTestRecordDtypes(BaseNumpyAppTest): def test_create(self): - from _numpypy import dtype, void + from numpypy import dtype, void raises(ValueError, "dtype([('x', int), ('x', float)])") d = dtype([("x", "int32"), ("y", "int32"), ("z", "int32"), ("value", float)]) @@ -742,7 +737,7 @@ def test_create_from_dict(self): skip("not yet") - from _numpypy import dtype + from numpypy import dtype d = dtype({'names': ['a', 'b', 'c'], }) @@ -766,7 +761,7 @@ cls.w_check_non_native = cls.space.wrap(interp2app(check_non_native)) def test_non_native(self): - from _numpypy import array + from numpypy import array a = array([1, 2, 3], dtype=self.non_native_prefix + 'i2') assert a[0] == 1 assert (a + a)[1] == 4 @@ -788,7 +783,8 @@ BaseNumpyAppTest.setup_class.im_func(cls) def test_typeinfo(self): - from _numpypy import typeinfo, void, number, int64, bool_ + from numpypy import void, number, int64, bool_ + from numpypy.core.multiarray import typeinfo assert typeinfo['Number'] == number assert typeinfo['LONGLONG'] == ('q', 9, 64, 8, 9223372036854775807L, -9223372036854775808L, int64) assert typeinfo['VOID'] == ('V', 20, 0, 1, void) @@ -804,11 +800,11 @@ BaseNumpyAppTest.setup_class.im_func(cls) def test_nolongfloat(self): - import _numpypy - from _numpypy import dtype - assert not getattr(_numpypy, 'longdouble', False) - assert not getattr(_numpypy, 'float128', False) - assert not getattr(_numpypy, 'float96', False) + import numpypy + from numpypy import dtype + assert not getattr(numpypy, 'longdouble', False) + assert not getattr(numpypy, 'float128', False) + assert not getattr(numpypy, 'float96', False) raises(TypeError, dtype, 'longdouble') raises(TypeError, dtype, 'clongdouble') raises(TypeError, dtype, 'longfloat') @@ -825,7 +821,7 @@ BaseNumpyAppTest.setup_class.im_func(cls) def test_longfloat(self): - import _numpypy as numpy + import numpypy as numpy # it can be float96 or float128 if numpy.longfloat != numpy.float64: assert numpy.longfloat.mro()[1:] == [numpy.floating, @@ -838,33 +834,33 @@ raises(ValueError, numpy.longfloat, '23.2df') def test_dtype_aliases(self): - from _numpypy import dtype + from numpypy import dtype assert dtype('longfloat').num in (12, 13) assert dtype('longdouble').num in (12, 13) assert dtype('clongfloat').num in (15, 16) assert dtype('clongdouble').num in (15, 16) def test_bool_binop_types(self): - from _numpypy import array, dtype + from numpypy import array, dtype types = ['g', 'G'] a = array([True], '?') for t in types: assert (a + array([0], t)).dtype is dtype(t) def test_hash(self): - import _numpypy as numpy + import numpypy as numpy for tp, value in [ (numpy.longdouble, 4.32), ]: assert hash(tp(value)) == hash(value) def test_float_None(self): - import _numpypy as numpy + import numpypy as numpy from math import isnan assert isnan(numpy.longdouble(None)) def test_non_native(self): - from _numpypy import array + from numpypy import array a = array([1, 2, 3], dtype=self.non_native_prefix + 'g') # longdouble assert a[0] == 1 assert (a + a)[1] == 4 diff --git a/pypy/module/micronumpy/test/test_numarray.py b/pypy/module/micronumpy/test/test_numarray.py --- a/pypy/module/micronumpy/test/test_numarray.py +++ b/pypy/module/micronumpy/test/test_numarray.py @@ -245,7 +245,7 @@ return CustomIntObject(value) def test_ndarray(self): - from _numpypy import ndarray, array, dtype + from numpypy import ndarray, array, dtype assert type(ndarray) is type assert type(array) is not type @@ -262,24 +262,24 @@ assert a.shape == () def test_ndmin(self): - from _numpypy import array + from numpypy import array arr = array([[[1]]], ndmin=1) assert arr.shape == (1, 1, 1) def test_noop_ndmin(self): - from _numpypy import array + from numpypy import array arr = array([1], ndmin=3) assert arr.shape == (1, 1, 1) def test_type(self): - from _numpypy import array + from numpypy import array ar = array(range(5)) assert type(ar) is type(ar + ar) def test_ndim(self): - from _numpypy import array + from numpypy import array x = array(0.2) assert x.ndim == 0 x = array([1, 2]) @@ -288,12 +288,12 @@ assert x.ndim == 2 x = array([[[1, 2], [3, 4]], [[5, 6], [7, 8]]]) assert x.ndim == 3 - # numpy actually raises an AttributeError, but _numpypy raises an + # numpy actually raises an AttributeError, but numpypy raises an # TypeError raises((TypeError, AttributeError), 'x.ndim = 3') def test_init(self): - from _numpypy import zeros + from numpypy import zeros a = zeros(15) # Check that storage was actually zero'd. assert a[10] == 0.0 @@ -303,7 +303,7 @@ assert zeros(()).shape == () def test_size(self): - from _numpypy import array,arange,cos + from numpypy import array,arange,cos assert array(3).size == 1 a = array([1, 2, 3]) assert a.size == 3 @@ -316,13 +316,13 @@ Test that empty() works. """ - from _numpypy import empty + from numpypy import empty a = empty(2) a[1] = 1.0 assert a[1] == 1.0 def test_ones(self): - from _numpypy import ones + from numpypy import ones a = ones(3) assert len(a) == 3 assert a[0] == 1 @@ -331,7 +331,7 @@ assert a[2] == 4 def test_copy(self): - from _numpypy import arange, array + from numpypy import arange, array a = arange(5) b = a.copy() for i in xrange(5): @@ -357,12 +357,12 @@ assert b[0] == a[0] def test_iterator_init(self): - from _numpypy import array + from numpypy import array a = array(range(5)) assert a[3] == 3 def test_getitem(self): - from _numpypy import array + from numpypy import array a = array(range(5)) raises(IndexError, "a[5]") a = a + a @@ -371,14 +371,14 @@ raises(IndexError, "a[-6]") def test_getitem_float(self): - from _numpypy import array + from numpypy import array a = array([1, 2, 3, 4]) assert a[1.2] == 2 assert a[1.6] == 2 assert a[-1.2] == 4 def test_getitem_tuple(self): - from _numpypy import array + from numpypy import array a = array(range(5)) raises(IndexError, "a[(1,2)]") for i in xrange(5): @@ -388,20 +388,20 @@ assert a[i] == b[i] def test_getitem_nd(self): - from _numpypy import arange + from numpypy import arange a = arange(15).reshape(3, 5) assert a[1, 3] == 8 assert a.T[1, 2] == 11 def test_getitem_obj_index(self): - from _numpypy import arange + from numpypy import arange a = arange(10) assert a[self.CustomIndexObject(1)] == 1 def test_getitem_obj_prefer_index_to_int(self): - from _numpypy import arange + from numpypy import arange a = arange(10) @@ -409,14 +409,14 @@ assert a[self.CustomIndexIntObject(0, 1)] == 0 def test_getitem_obj_int(self): - from _numpypy import arange + from numpypy import arange a = arange(10) assert a[self.CustomIntObject(1)] == 1 def test_setitem(self): - from _numpypy import array + from numpypy import array a = array(range(5)) a[-1] = 5.0 assert a[4] == 5.0 @@ -424,7 +424,7 @@ raises(IndexError, "a[-6] = 3.0") def test_setitem_tuple(self): - from _numpypy import array + from numpypy import array a = array(range(5)) raises(IndexError, "a[(1,2)] = [0,1]") for i in xrange(5): @@ -435,7 +435,7 @@ assert a[i] == i def test_setitem_obj_index(self): - from _numpypy import arange + from numpypy import arange a = arange(10) @@ -443,7 +443,7 @@ assert a[1] == 100 def test_setitem_obj_prefer_index_to_int(self): - from _numpypy import arange + from numpypy import arange a = arange(10) @@ -451,7 +451,7 @@ assert a[0] == 100 def test_setitem_obj_int(self): - from _numpypy import arange + from numpypy import arange a = arange(10) @@ -471,13 +471,13 @@ # numpy will swallow errors in __int__ and __index__ and # just raise IndexError. - from _numpypy import arange + from numpypy import arange a = arange(10) raises(IndexError, "a[ErrorIndex()] == 0") raises(IndexError, "a[ErrorInt()] == 0") def test_setslice_array(self): - from _numpypy import array + from numpypy import array a = array(range(5)) b = array(range(2)) a[1:4:2] = b @@ -488,7 +488,7 @@ assert b[1] == 0. def test_setslice_of_slice_array(self): - from _numpypy import array, zeros + from numpypy import array, zeros a = zeros(5) a[::2] = array([9., 10., 11.]) assert a[0] == 9. @@ -507,7 +507,7 @@ assert a[0] == 3. def test_setslice_list(self): - from _numpypy import array + from numpypy import array a = array(range(5), float) b = [0., 1.] a[1:4:2] = b @@ -515,7 +515,7 @@ assert a[3] == 1. def test_setslice_constant(self): - from _numpypy import array + from numpypy import array a = array(range(5), float) a[1:4:2] = 0. assert a[1] == 0. @@ -523,7 +523,7 @@ def test_newaxis(self): import math - from _numpypy import array, cos, zeros + from numpypy import array, cos, zeros from numpypy.core.numeric import newaxis a = array(range(5)) b = array([range(5)]) @@ -537,7 +537,7 @@ assert ((cos(a)[:,newaxis] * cos(b).T) == expected).all() def test_newaxis_slice(self): - from _numpypy import array + from numpypy import array from numpypy.core.numeric import newaxis a = array(range(5)) @@ -550,7 +550,7 @@ assert (a[newaxis,1:] == c).all() def test_newaxis_assign(self): - from _numpypy import array + from numpypy import array from numpypy.core.numeric import newaxis a = array(range(5)) @@ -558,7 +558,7 @@ assert a[1] == 2 def test_newaxis_virtual(self): - from _numpypy import array + from numpypy import array from numpypy.core.numeric import newaxis a = array(range(5)) @@ -567,7 +567,7 @@ assert (b == c).all() def test_newaxis_then_slice(self): - from _numpypy import array + from numpypy import array from numpypy.core.numeric import newaxis a = array(range(5)) b = a[newaxis] @@ -575,14 +575,14 @@ assert (b[0,1:] == a[1:]).all() def test_slice_then_newaxis(self): - from _numpypy import array + from numpypy import array from numpypy.core.numeric import newaxis a = array(range(5)) b = a[2:] assert (b[newaxis] == [[2, 3, 4]]).all() def test_scalar(self): - from _numpypy import array, dtype + from numpypy import array, dtype a = array(3) raises(IndexError, "a[0]") raises(IndexError, "a[0] = 5") @@ -591,13 +591,13 @@ assert a.dtype is dtype(int) def test_len(self): - from _numpypy import array + from numpypy import array a = array(range(5)) assert len(a) == 5 assert len(a + a) == 5 def test_shape(self): - from _numpypy import array + from numpypy import array a = array(range(5)) assert a.shape == (5,) b = a + a @@ -607,7 +607,7 @@ assert array([]).shape == (0,) def test_set_shape(self): - from _numpypy import array, zeros + from numpypy import array, zeros a = array([]) raises(ValueError, "a.shape = []") a = array(range(12)) @@ -630,7 +630,7 @@ raises(AttributeError, 'a.shape = 6') def test_reshape(self): - from _numpypy import array, zeros + from numpypy import array, zeros a = array(range(12)) exc = raises(ValueError, "b = a.reshape((3, 10))") assert str(exc.value) == "total size of new array must be unchanged" @@ -646,7 +646,7 @@ assert a.reshape((0,)).shape == (0,) def test_slice_reshape(self): - from _numpypy import zeros, arange + from numpypy import zeros, arange a = zeros((4, 2, 3)) b = a[::2, :, :] b.shape = (2, 6) @@ -682,7 +682,7 @@ raises(ValueError, arange(10).reshape, (5, -1, -1)) def test_reshape_varargs(self): - from _numpypy import arange + from numpypy import arange z = arange(96).reshape(12, -1) y = z.reshape(4, 3, 8) assert y.shape == (4, 3, 8) @@ -695,19 +695,19 @@ raises(ValueError, "a.reshape(3)") def test_strides(self): - from _numpypy import array + from numpypy import array a = array([[1.0, 2.0], [3.0, 4.0]]) assert a.strides == (16, 8) assert a[1:].strides == (16, 8) def test_strides_scalar(self): - from _numpypy import array + from numpypy import array a = array(42) assert a.strides == () def test_add(self): - from _numpypy import array + from numpypy import array a = array(range(5)) b = a + a for i in range(5): @@ -720,7 +720,7 @@ assert c[i] == bool(a[i] + b[i]) def test_add_other(self): - from _numpypy import array + from numpypy import array a = array(range(5)) b = array([i for i in reversed(range(5))]) c = a + b @@ -728,14 +728,14 @@ assert c[i] == 4 def test_add_constant(self): - from _numpypy import array + from numpypy import array a = array(range(5)) b = a + 5 for i in range(5): assert b[i] == i + 5 def test_radd(self): - from _numpypy import array + from numpypy import array r = 3 + array(range(3)) for i in range(3): assert r[i] == i + 3 @@ -743,7 +743,7 @@ assert (r == [2, 4]).all() def test_add_list(self): - from _numpypy import array, ndarray + from numpypy import array, ndarray a = array(range(5)) b = list(reversed(range(5))) c = a + b @@ -752,14 +752,14 @@ assert c[i] == 4 def test_subtract(self): - from _numpypy import array + from numpypy import array a = array(range(5)) b = a - a for i in range(5): assert b[i] == 0 def test_subtract_other(self): - from _numpypy import array + from numpypy import array a = array(range(5)) b = array([1, 1, 1, 1, 1]) c = a - b @@ -767,36 +767,35 @@ assert c[i] == i - 1 def test_subtract_constant(self): - from _numpypy import array + from numpypy import array a = array(range(5)) b = a - 5 for i in range(5): assert b[i] == i - 5 def test_scalar_subtract(self): - from _numpypy import int32 + from numpypy import int32 assert int32(2) - 1 == 1 assert 1 - int32(2) == -1 def test_mul(self): - import _numpypy - from numpypy import False_, True_ + import numpypy - a = _numpypy.array(range(5)) + a = numpypy.array(range(5)) b = a * a for i in range(5): assert b[i] == i * i assert b.dtype is a.dtype - a = _numpypy.array(range(5), dtype=bool) + a = numpypy.array(range(5), dtype=bool) b = a * a - assert b.dtype is _numpypy.dtype(bool) - assert b[0] is False_ + assert b.dtype is numpypy.dtype(bool) + assert b[0] is numpypy.False_ for i in range(1, 5): - assert b[i] is True_ + assert b[i] is numpypy.True_ def test_mul_constant(self): - from _numpypy import array + from numpypy import array a = array(range(5)) b = a * 5 for i in range(5): @@ -804,7 +803,7 @@ def test_div(self): from math import isnan - from _numpypy import array, dtype + from numpypy import array, dtype a = array(range(1, 6)) b = a / a @@ -836,7 +835,7 @@ assert c[2] == float('-inf') def test_div_other(self): - from _numpypy import array + from numpypy import array a = array(range(5)) b = array([2, 2, 2, 2, 2], float) c = a / b @@ -844,7 +843,7 @@ assert c[i] == i / 2.0 def test_div_constant(self): - from _numpypy import array + from numpypy import array a = array(range(5)) b = a / 5.0 for i in range(5): @@ -852,7 +851,7 @@ def test_floordiv(self): from math import isnan - from _numpypy import array, dtype + from numpypy import array, dtype a = array(range(1, 6)) b = a // a @@ -882,47 +881,47 @@ assert c[2] == float('-inf') def test_floordiv_other(self): - from _numpypy import array + from numpypy import array a = array(range(5)) b = array([2, 2, 2, 2, 2], float) c = a // b assert (c == [0, 0, 1, 1, 2]).all() def test_rfloordiv(self): - from _numpypy import array + from numpypy import array a = array(range(1, 6)) b = 3 // a assert (b == [3, 1, 1, 0, 0]).all() def test_floordiv_constant(self): - from _numpypy import array + from numpypy import array a = array(range(5)) b = a // 2 assert (b == [0, 0, 1, 1, 2]).all() def test_truediv(self): from operator import truediv - from _numpypy import arange + from numpypy import arange assert (truediv(arange(5), 2) == [0., .5, 1., 1.5, 2.]).all() assert (truediv(2, arange(3)) == [float("inf"), 2., 1.]).all() def test_divmod(self): - from _numpypy import arange + from numpypy import arange a, b = divmod(arange(10), 3) assert (a == [0, 0, 0, 1, 1, 1, 2, 2, 2, 3]).all() assert (b == [0, 1, 2, 0, 1, 2, 0, 1, 2, 0]).all() def test_rdivmod(self): - from _numpypy import arange + from numpypy import arange a, b = divmod(3, arange(1, 5)) assert (a == [3, 1, 1, 0]).all() assert (b == [0, 1, 0, 3]).all() def test_lshift(self): - from _numpypy import array + from numpypy import array a = array([0, 1, 2, 3]) assert (a << 2 == [0, 4, 8, 12]).all() @@ -932,13 +931,13 @@ raises(TypeError, lambda: a << 2) def test_rlshift(self): - from _numpypy import arange + from numpypy import arange a = arange(3) assert (2 << a == [2, 4, 8]).all() def test_rshift(self): - from _numpypy import arange, array + from numpypy import arange, array a = arange(10) assert (a >> 2 == [0, 0, 0, 0, 1, 1, 1, 1, 2, 2]).all() @@ -948,13 +947,13 @@ raises(TypeError, lambda: a >> 1) def test_rrshift(self): - from _numpypy import arange + from numpypy import arange a = arange(5) assert (2 >> a == [2, 1, 0, 0, 0]).all() def test_pow(self): - from _numpypy import array + from numpypy import array a = array(range(5), float) b = a ** a for i in range(5): From noreply at buildbot.pypy.org Mon Feb 25 15:44:09 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Mon, 25 Feb 2013 15:44:09 +0100 (CET) Subject: [pypy-commit] pypy default: forgot to hg add this file Message-ID: <20130225144409.5F2941C0237@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61765:41a1c4177ead Date: 2013-02-25 09:43 -0500 http://bitbucket.org/pypy/pypy/changeset/41a1c4177ead/ Log: forgot to hg add this file diff --git a/lib_pypy/numpypy/core/numerictypes.py b/lib_pypy/numpypy/core/numerictypes.py new file mode 100644 --- /dev/null +++ b/lib_pypy/numpypy/core/numerictypes.py @@ -0,0 +1,1 @@ +from _numpypy.numerictypes import * From noreply at buildbot.pypy.org Mon Feb 25 16:21:31 2013 From: noreply at buildbot.pypy.org (lwassermann) Date: Mon, 25 Feb 2013 16:21:31 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: changed the sequence of speical objects. now, nil should be first to be matched. If any later special object is also set to nil, nil's w_object will not be overwritten. Message-ID: <20130225152131.617781C0237@cobra.cs.uni-duesseldorf.de> Author: Lars Wassermann Branch: Changeset: r97:2b3b4d9fc7ae Date: 2013-02-25 16:15 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/2b3b4d9fc7ae/ Log: changed the sequence of speical objects. now, nil should be first to be matched. If any later special object is also set to nil, nil's w_object will not be overwritten. diff --git a/spyvm/error.py b/spyvm/error.py --- a/spyvm/error.py +++ b/spyvm/error.py @@ -23,5 +23,5 @@ def __init__(self, msg): self.msg = msg -class BlockCannotReturnError(PrimitiveFailedError): +class BlockCannotReturnError(SmalltalkException): pass \ No newline at end of file diff --git a/spyvm/interpreter.py b/spyvm/interpreter.py --- a/spyvm/interpreter.py +++ b/spyvm/interpreter.py @@ -258,6 +258,8 @@ raise ReturnFromTopLevel(object) # widow this context self.store_pc(None) + self.store_w_sender(self.space.w_nil) + w_return_to.as_context_get_shadow(self.space).push(object) return w_return_to diff --git a/spyvm/primitives.py b/spyvm/primitives.py --- a/spyvm/primitives.py +++ b/spyvm/primitives.py @@ -930,7 +930,7 @@ def activateClosure(interp, s_frame, w_block, args_w, mayContextSwitch=True): - # XXX may context switch is ignored + # XXX mayContextSwitch is ignored space = interp.space if not w_block.getclass(space).is_same_object( space.w_BlockClosure): diff --git a/spyvm/squeakimage.py b/spyvm/squeakimage.py --- a/spyvm/squeakimage.py +++ b/spyvm/squeakimage.py @@ -264,14 +264,22 @@ chunk.g_object.init_w_object() def assign_prebuilt_constants(self): + # assign w_objects for objects that are already in objtable + for name, so_index in constants.objects_in_special_object_table.items(): + w_object = self.space.objtable["w_" + name] + if self.special_object(so_index).w_object is None: + self.special_object(so_index).w_object = w_object + else: + if self.special_object(0).w_object is not self.space.w_nil: + raise Warning('Object found in multiple places in the special objects array') # assign w_objects for objects that are already in classtable for name, so_index in constants.classes_in_special_object_table.items(): w_object = self.space.classtable["w_" + name] - self.special_object(so_index).w_object = w_object - # assign w_objects for objects that are already in objtable - for name, so_index in constants.objects_in_special_object_table.items(): - w_object = self.space.objtable["w_" + name] - self.special_object(so_index).w_object = w_object + if self.special_object(so_index).w_object is None: + self.special_object(so_index).w_object = w_object + else: + if self.special_object(0).w_object is not self.space.w_nil: + raise Warning('Object found in multiple places in the special objects array') def special_object(self, index): special = self.chunks[self.specialobjectspointer].g_object.pointers From noreply at buildbot.pypy.org Mon Feb 25 16:21:32 2013 From: noreply at buildbot.pypy.org (lwassermann) Date: Mon, 25 Feb 2013 16:21:32 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: changed widow flag value from None to -1, for jit-reasons Message-ID: <20130225152132.9042E1C0327@cobra.cs.uni-duesseldorf.de> Author: Lars Wassermann Branch: Changeset: r98:16fe326abaa4 Date: 2013-02-25 16:21 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/16fe326abaa4/ Log: changed widow flag value from None to -1, for jit-reasons diff --git a/spyvm/interpreter.py b/spyvm/interpreter.py --- a/spyvm/interpreter.py +++ b/spyvm/interpreter.py @@ -257,7 +257,7 @@ if w_return_to.is_same_object(self.space.w_nil): raise ReturnFromTopLevel(object) # widow this context - self.store_pc(None) + self.store_pc(-1) self.store_w_sender(self.space.w_nil) w_return_to.as_context_get_shadow(self.space).push(object) diff --git a/spyvm/shadow.py b/spyvm/shadow.py --- a/spyvm/shadow.py +++ b/spyvm/shadow.py @@ -742,7 +742,7 @@ s_outerContext = self.w_closure_or_nil.fetch(self.space, constants.BLKCLSR_OUTER_CONTEXT).get_shadow(self.space) # XXX check whether we can actually return from that context - if s_outerContext.pc() == None: + if s_outerContext.pc() == -1: raise error.BlockCannotReturnError() s_outerContext._return(self.top(), interp, s_outerContext.s_home().w_sender()) From noreply at buildbot.pypy.org Mon Feb 25 17:59:32 2013 From: noreply at buildbot.pypy.org (lwassermann) Date: Mon, 25 Feb 2013 17:59:32 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: added two test cases which fail with the closure-image Message-ID: <20130225165932.314861C4838@cobra.cs.uni-duesseldorf.de> Author: Lars Wassermann Branch: Changeset: r99:584072599dfd Date: 2013-02-25 17:59 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/584072599dfd/ Log: added two test cases which fail with the closure-image diff --git a/spyvm/test/test_bootstrappedimage.py b/spyvm/test/test_bootstrappedimage.py new file mode 100644 --- /dev/null +++ b/spyvm/test/test_bootstrappedimage.py @@ -0,0 +1,26 @@ +import py +from spyvm import squeakimage, model, constants +from spyvm import interpreter, shadow, objspace +from spyvm.test import test_miniimage as testhelper +from spyvm.test.test_miniimage import perform, w + +testhelper.setup_module(testhelper, filename='bootstrapped.image') + +def test_retrieve_symbol(): + py.test.skip("This method will fail, because the bytecodes are not adjusted for blockclosures, yet.") + perform(testhelper.image.w_asSymbol, "asSymbol") + +def test_create_new_symbol(): + py.test.skip("This method is based upon the above.") + #import pdb; pdb.set_trace() + w_result = perform(w("someString"), "asSymbol") + assert w_result is not None + assert w_result.as_string() is "someString" + + +#def test_hazelnut(): +# from spyvm.test import test_miniimage +# setup_module(test_miniimage, filename='bootstrapped.image') +# test_miniimage.test_all_pointers_are_valid() +# test_miniimage.test_become() + #test_miniimage.test_special_classes0() diff --git a/spyvm/test/test_miniimage.py b/spyvm/test/test_miniimage.py --- a/spyvm/test/test_miniimage.py +++ b/spyvm/test/test_miniimage.py @@ -301,3 +301,8 @@ assert s_ctx.top().value == 2 interp.step(s_ctx) assert s_ctx.top().value == 3 + +def test_create_new_symbol(): + w_result = perform(w("someString"), "asSymbol") + assert w_result is not None + assert w_result.as_string() == "someString" From noreply at buildbot.pypy.org Mon Feb 25 18:19:30 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Mon, 25 Feb 2013 18:19:30 +0100 (CET) Subject: [pypy-commit] cffi library-module: Make the library be a ModuleType subclass so that on PyPy it is optimized for the fact that the attribtues are generally never re-assigned. Message-ID: <20130225171930.646051C01A7@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: library-module Changeset: r1168:64a35d32512c Date: 2013-02-24 20:11 -0800 http://bitbucket.org/cffi/cffi/changeset/64a35d32512c/ Log: Make the library be a ModuleType subclass so that on PyPy it is optimized for the fact that the attribtues are generally never re- assigned. diff --git a/cffi/vengine_gen.py b/cffi/vengine_gen.py --- a/cffi/vengine_gen.py +++ b/cffi/vengine_gen.py @@ -1,4 +1,6 @@ -import sys, os, binascii, imp, shutil +import sys +import types + from . import model, ffiplatform @@ -54,12 +56,12 @@ # call loading_gen_struct() to get the struct layout inferred by # the C compiler self._load(module, 'loading') - # + # build the FFILibrary class and instance - class FFILibrary(object): + class FFILibrary(types.ModuleType): _cffi_generic_module = module _cffi_ffi = self.ffi - library = FFILibrary() + library = FFILibrary("") # # finally, call the loaded_gen_xxx() functions. This will set # up the 'library' object. From noreply at buildbot.pypy.org Mon Feb 25 18:19:31 2013 From: noreply at buildbot.pypy.org (alex_gaynor) Date: Mon, 25 Feb 2013 18:19:31 +0100 (CET) Subject: [pypy-commit] cffi library-module: explanatory comment Message-ID: <20130225171931.7F4A11C01A7@cobra.cs.uni-duesseldorf.de> Author: Alex Gaynor Branch: library-module Changeset: r1169:a55ba8973dc5 Date: 2013-02-25 08:14 -0800 http://bitbucket.org/cffi/cffi/changeset/a55ba8973dc5/ Log: explanatory comment diff --git a/cffi/vengine_gen.py b/cffi/vengine_gen.py --- a/cffi/vengine_gen.py +++ b/cffi/vengine_gen.py @@ -57,7 +57,10 @@ # the C compiler self._load(module, 'loading') - # build the FFILibrary class and instance + # build the FFILibrary class and instance, this is a module subclass + # because modules are expected to have usually-constant-attributes and + # in PyPy this means the JIT is able to treat attributes as constant, + # which we want. class FFILibrary(types.ModuleType): _cffi_generic_module = module _cffi_ffi = self.ffi From noreply at buildbot.pypy.org Mon Feb 25 18:19:32 2013 From: noreply at buildbot.pypy.org (fijal) Date: Mon, 25 Feb 2013 18:19:32 +0100 (CET) Subject: [pypy-commit] cffi default: Merged in alex_gaynor/cffi/library-module (pull request #9) Message-ID: <20130225171932.882211C01A7@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r1170:60a2d2c57ca6 Date: 2013-02-25 19:19 +0200 http://bitbucket.org/cffi/cffi/changeset/60a2d2c57ca6/ Log: Merged in alex_gaynor/cffi/library-module (pull request #9) Make the library be a ModuleType subclass so that on PyPy it is optimized for the fact that the attribtues are generally never re- assigned. diff --git a/cffi/vengine_gen.py b/cffi/vengine_gen.py --- a/cffi/vengine_gen.py +++ b/cffi/vengine_gen.py @@ -1,4 +1,6 @@ -import sys, os, binascii, imp, shutil +import sys +import types + from . import model, ffiplatform @@ -54,12 +56,15 @@ # call loading_gen_struct() to get the struct layout inferred by # the C compiler self._load(module, 'loading') - # - # build the FFILibrary class and instance - class FFILibrary(object): + + # build the FFILibrary class and instance, this is a module subclass + # because modules are expected to have usually-constant-attributes and + # in PyPy this means the JIT is able to treat attributes as constant, + # which we want. + class FFILibrary(types.ModuleType): _cffi_generic_module = module _cffi_ffi = self.ffi - library = FFILibrary() + library = FFILibrary("") # # finally, call the loaded_gen_xxx() functions. This will set # up the 'library' object. From noreply at buildbot.pypy.org Mon Feb 25 19:00:45 2013 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 25 Feb 2013 19:00:45 +0100 (CET) Subject: [pypy-commit] pypy stm-thread-2: Attempt again to fix stm_PtrEq(). Message-ID: <20130225180045.710E11C4847@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: stm-thread-2 Changeset: r61766:3172187f8470 Date: 2013-02-25 18:58 +0100 http://bitbucket.org/pypy/pypy/changeset/3172187f8470/ Log: Attempt again to fix stm_PtrEq(). diff --git a/rpython/translator/stm/src_stm/et.c b/rpython/translator/stm/src_stm/et.c --- a/rpython/translator/stm/src_stm/et.c +++ b/rpython/translator/stm/src_stm/et.c @@ -748,65 +748,66 @@ inline static _Bool _PtrEq_Globals(gcptr G1, gcptr G2) { - /* This is a bit lengthy, but (probably) efficient: the idea is to - check if G1 and G2 are pointers in the same chained list of globals - or not. Assumes no partial sharing in the chained lists. Works by - trying to search forward with S1, starting from G1, if it reaches - G2; and conversely with S2, starting from G2, if it reaches G1. */ - gcptr S1 = G1, S2 = G2; + /* This is a mess, because G1 and G2 can be different pointers to "the + same" object, and it's hard to determine that. Description of the + idealized problem: we have chained lists following the 'h_revision' + field from G1 and from G2, and we must return True if the chained + lists end in the same object G and False if they don't. + + It's possible that G1 != G2 but G1->h_revision == G2->h_revision. + This occurs because of random updates done by PossiblyUpdateChain(). + + But the real mess comes from other threads doing concurrent + updates. They can be either done by PossiblyUpdateChain() from + other threads, changing 'h_revision' without warning to point to + what used to be 'h_revision-> ... -> h_revision'. Alternatively, + they can be adding new objects to the so-far root of the tree: + consider the G that used to be the end of both chained lists. Its + 'h_revision' used to be not-a-pointer. But it can suddenly + suddenly turns into a LOCK value, and then later to a pointer to + some new object, making the chained list longer. Worse, once the + list is longer, a PossiblyUpdateChain() might make shortcuts in + it... + + So it means even the following algorithm is flawed: "follow + h_revisions from G1 until we reach G; then follow h_revisions from + G2, and return True/False if we reach/do not reach the same G". + + For now we go with: try to move forward G1 and G2 alternatively, + until we failed three times to move forward one of these. Let's + say the last three steps were "G1 is already at the end", "G2 is + already at the end", "G1 is already at the end". Then we can + return (G1 == G2). This is because we know that G1 was at the end + of the chained list for the whole time during which we checked G2. + + WARNING: THIS ONLY WORKS ON THE X86 MEMORY MODEL, AND NOT ON WEAKER + MODELS! + */ + int blocked_steps = 0; volatile revision_t *vp; revision_t v; + gcptr G3; while (1) { - if (S2 == G1) - return 1; - - /* move forward S1 */ - vp = (volatile revision_t *)&S1->h_revision; + /* try to move G1 forward */ + vp = (volatile revision_t *)&G1->h_revision; v = *vp; - if (v & 1) // "is not a pointer", i.e. - goto s1_end; // "doesn't have a more recent revision" - S1 = (gcptr)v; - - if (S1 == G2) - return 1; - - /* move forward S2 */ - vp = (volatile revision_t *)&S2->h_revision; - v = *vp; - if (v & 1) // "is not a pointer", i.e. - goto s2_end; // "doesn't have a more recent revision" - S2 = (gcptr)v; + if (v & 1) + { + blocked_steps++; + if (blocked_steps == 3) + break; + } + else + { + G1 = (gcptr)v; /* success */ + blocked_steps = 0; + } + /* swap the roles of G1 and G2, then loop */ + G3 = G1; G1 = G2; G2 = G3; } - - s1_end: - while (1) - { - /* move forward S2 */ - vp = (volatile revision_t *)&S2->h_revision; - v = *vp; - if (v & 1) // "is not a pointer", i.e. - return 0; // "doesn't have a more recent revision" - S2 = (gcptr)v; - - if (S2 == G1) - return 1; - } - - s2_end: - while (1) - { - /* move forward S1 */ - vp = (volatile revision_t *)&S1->h_revision; - v = *vp; - if (v & 1) // "is not a pointer", i.e. - return 0; // "doesn't have a more recent revision" - S1 = (gcptr)v; - - if (S1 == G2) - return 1; - } + return G1 == G2; } _Bool stm_PtrEq(gcptr P1, gcptr P2) From noreply at buildbot.pypy.org Mon Feb 25 19:08:42 2013 From: noreply at buildbot.pypy.org (fijal) Date: Mon, 25 Feb 2013 19:08:42 +0100 (CET) Subject: [pypy-commit] pypy default: an attempt to improve string printing Message-ID: <20130225180842.9521A1C484F@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r61767:5575406012fe Date: 2013-02-25 19:09 +0100 http://bitbucket.org/pypy/pypy/changeset/5575406012fe/ Log: an attempt to improve string printing diff --git a/pypy/tool/gdb_pypy.py b/pypy/tool/gdb_pypy.py --- a/pypy/tool/gdb_pypy.py +++ b/pypy/tool/gdb_pypy.py @@ -23,6 +23,7 @@ def __init__(self, name, command_class): pass +MAX_DISPLAY_LENGTH = 100 # maximum number of characters displayed in rpy_string def find_field_with_suffix(val, suffix): """ @@ -152,7 +153,15 @@ chars = self.val['rs_chars'] length = int(chars['length']) items = chars['items'] - res = [chr(items[i]) for i in range(length)] + res = [] + for i in range(min(length, MAX_DISPLAY_LENGTH)): + try: + res.append(chr(items[i])) + except ValueError: + # it's a gdb.Value so it has "121 'y'" as repr + res.append(chr(int(str(items[0]).split(" ")[0]))) + if i < length: + res.append('...') string = ''.join(res) return 'r' + repr(string) From noreply at buildbot.pypy.org Mon Feb 25 20:08:06 2013 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 25 Feb 2013 20:08:06 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: Update the comments. Message-ID: <20130225190806.AF5B01C484B@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: jitframe-on-heap Changeset: r61768:69eeabe5c271 Date: 2013-02-25 20:07 +0100 http://bitbucket.org/pypy/pypy/changeset/69eeabe5c271/ Log: Update the comments. diff --git a/rpython/jit/backend/x86/regalloc.py b/rpython/jit/backend/x86/regalloc.py --- a/rpython/jit/backend/x86/regalloc.py +++ b/rpython/jit/backend/x86/regalloc.py @@ -720,9 +720,8 @@ # # - at least the non-callee-saved registers # - # - for shadowstack, we assume that any call can collect, and we + # - we assume that any call can collect, and we # save also the callee-saved registers that contain GC pointers - # XXX for asmgcc too for now. # # - for CALL_MAY_FORCE or CALL_ASSEMBLER, we have to save all regs # anyway, in case we need to do cpu.force(). The issue is that @@ -734,6 +733,9 @@ if not save_all_regs: gcrootmap = self.assembler.cpu.gc_ll_descr.gcrootmap # we save all the registers for shadowstack and asmgcc for now + # --- for asmgcc too: we can't say "register x is a gc ref" + # without distinguishing call sites, which we don't do any + # more for now. if gcrootmap: # and gcrootmap.is_shadow_stack: save_all_regs = 2 self.rm.before_call(force_store, save_all_regs=save_all_regs) From noreply at buildbot.pypy.org Mon Feb 25 20:32:41 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Mon, 25 Feb 2013 20:32:41 +0100 (CET) Subject: [pypy-commit] pypy py3k: 2to3 Message-ID: <20130225193241.6A2D61C483D@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61769:da202b86b4e7 Date: 2013-02-25 11:08 -0800 http://bitbucket.org/pypy/pypy/changeset/da202b86b4e7/ Log: 2to3 diff --git a/pypy/module/unicodedata/test/test_unicodedata.py b/pypy/module/unicodedata/test/test_unicodedata.py --- a/pypy/module/unicodedata/test/test_unicodedata.py +++ b/pypy/module/unicodedata/test/test_unicodedata.py @@ -85,7 +85,7 @@ @py.test.mark.skipif("sys.maxunicode < 0x10ffff") def test_normalize_wide(self): import unicodedata - assert unicodedata.normalize('NFC', '\U000110a5\U000110ba') == u'\U000110ab' + assert unicodedata.normalize('NFC', '\U000110a5\U000110ba') == '\U000110ab' def test_linebreaks(self): linebreaks = (0x0a, 0x0b, 0x0c, 0x0d, 0x85, From noreply at buildbot.pypy.org Mon Feb 25 20:35:18 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Mon, 25 Feb 2013 20:35:18 +0100 (CET) Subject: [pypy-commit] pypy py3k: substitute gc.getreferents for getrefcount (thanks fijal) Message-ID: <20130225193518.39B0C1C4839@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61770:c1f8ea45dc6a Date: 2013-02-25 11:33 -0800 http://bitbucket.org/pypy/pypy/changeset/c1f8ea45dc6a/ Log: substitute gc.getreferents for getrefcount (thanks fijal) diff --git a/lib-python/3.2/test/test_memoryview.py b/lib-python/3.2/test/test_memoryview.py --- a/lib-python/3.2/test/test_memoryview.py +++ b/lib-python/3.2/test/test_memoryview.py @@ -11,7 +11,11 @@ import array import io -getrefcount = sys.getrefcount if hasattr(sys, 'getrefcount') else lambda o: -1 +try: + getrefcount = sys.getrefcount +except AttributeError: + # PyPy + getrefcount = lambda o: len(gc.get_referents(o)) class AbstractMemoryTests: source_bytes = b"abcdef" From noreply at buildbot.pypy.org Mon Feb 25 20:57:22 2013 From: noreply at buildbot.pypy.org (mattip) Date: Mon, 25 Feb 2013 20:57:22 +0100 (CET) Subject: [pypy-commit] pypy default: do not look for ids on chunks with no code Message-ID: <20130225195722.2DDAA1C4845@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: Changeset: r61771:50adf669f221 Date: 2013-02-25 21:56 +0200 http://bitbucket.org/pypy/pypy/changeset/50adf669f221/ Log: do not look for ids on chunks with no code diff --git a/pypy/module/pypyjit/test_pypy_c/model.py b/pypy/module/pypyjit/test_pypy_c/model.py --- a/pypy/module/pypyjit/test_pypy_c/model.py +++ b/pypy/module/pypyjit/test_pypy_c/model.py @@ -117,7 +117,7 @@ # # 2. compute the ids of all the inlined functions for chunk in self.chunks: - if isinstance(chunk, TraceWithIds): + if isinstance(chunk, TraceWithIds) and chunk.code: chunk.compute_ids(ids) def get_set_of_opcodes(self): From noreply at buildbot.pypy.org Mon Feb 25 22:07:08 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Mon, 25 Feb 2013 22:07:08 +0100 (CET) Subject: [pypy-commit] pypy refactor-translator: A branch to refactor/rewrite some parts of the RPython translator. Message-ID: <20130225210708.AD6D71C0327@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: refactor-translator Changeset: r61772:ee9ec2e08c52 Date: 2013-02-25 14:19 +0100 http://bitbucket.org/pypy/pypy/changeset/ee9ec2e08c52/ Log: A branch to refactor/rewrite some parts of the RPython translator. From noreply at buildbot.pypy.org Mon Feb 25 22:07:10 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Mon, 25 Feb 2013 22:07:10 +0100 (CET) Subject: [pypy-commit] pypy refactor-translator: Expose tasks depending on configuration. Message-ID: <20130225210710.153241C0327@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: refactor-translator Changeset: r61773:6533418b7001 Date: 2013-02-25 14:48 +0100 http://bitbucket.org/pypy/pypy/changeset/6533418b7001/ Log: Expose tasks depending on configuration. diff --git a/rpython/translator/driver.py b/rpython/translator/driver.py --- a/rpython/translator/driver.py +++ b/rpython/translator/driver.py @@ -114,28 +114,14 @@ setattr(self, task, proc) backend, ts = self.get_backend_and_type_system() - for task in self.tasks: - explicit_task = task - if task == 'annotate': - expose_task(task) - else: - task, postfix = task.split('_') - if task in ('rtype', 'backendopt', 'llinterpret', - 'pyjitpl'): - if ts: - if ts == postfix: - expose_task(task, explicit_task) - else: - expose_task(explicit_task) - elif task in ('source', 'compile', 'run'): - if backend: - if backend == postfix: - expose_task(task, explicit_task) - elif ts: - if ts == backend_to_typesystem(postfix): - expose_task(explicit_task) - else: - expose_task(explicit_task) + expose_task('annotate') + expose_task('rtype') + if config.translation.jit: + expose_task('pyjitpl') + if not config.translation.backendopt.none: + expose_task('backendopt') + expose_task('source') + expose_task('compile') def set_extra_goals(self, goals): self.extra_goals = goals diff --git a/rpython/translator/test/test_driver.py b/rpython/translator/test/test_driver.py --- a/rpython/translator/test/test_driver.py +++ b/rpython/translator/test/test_driver.py @@ -3,52 +3,20 @@ from rpython.translator.driver import TranslationDriver import optparse -def test_ctr(): + +def test_c_no_jit(): td = TranslationDriver() - expected = ['annotate', 'backendopt', 'llinterpret', 'rtype', 'source', - 'compile', 'pyjitpl'] - assert set(td.exposed) == set(expected) + goals = ['annotate', 'rtype', 'backendopt', 'source', 'compile'] + assert td.exposed == goals - assert td.backend_select_goals(['compile_c']) == ['compile_c'] - assert td.backend_select_goals(['compile']) == ['compile_c'] - assert td.backend_select_goals(['rtype']) == ['rtype_lltype'] - assert td.backend_select_goals(['rtype_lltype']) == ['rtype_lltype'] - assert td.backend_select_goals(['backendopt']) == ['backendopt_lltype'] - assert td.backend_select_goals(['backendopt_lltype']) == [ - 'backendopt_lltype'] - td = TranslationDriver({'backend': None, 'type_system': None}) +def test_c_with_jit(): + td = TranslationDriver({'jit': True}) + goals = ['annotate', 'rtype', 'pyjitpl', 'backendopt', 'source', 'compile'] + assert td.exposed == goals - assert td.backend_select_goals(['compile_c']) == ['compile_c'] - py.test.raises(Exception, td.backend_select_goals, ['compile']) - py.test.raises(Exception, td.backend_select_goals, ['rtype']) - assert td.backend_select_goals(['rtype_lltype']) == ['rtype_lltype'] - py.test.raises(Exception, td.backend_select_goals, ['backendopt']) - assert td.backend_select_goals(['backendopt_lltype']) == [ - 'backendopt_lltype'] - expected = ['annotate', 'backendopt_lltype', - 'backendopt_ootype', - 'llinterpret_lltype', - 'rtype_ootype', 'rtype_lltype', - 'source_cli', 'source_c', - 'compile_cli', 'compile_c', - 'compile_jvm', 'source_jvm', 'run_jvm', - 'pyjitpl_lltype', - 'pyjitpl_ootype'] - assert set(td.exposed) == set(expected) - - td = TranslationDriver({'backend': None, 'type_system': 'lltype'}) - - assert td.backend_select_goals(['compile_c']) == ['compile_c'] - py.test.raises(Exception, td.backend_select_goals, ['compile']) - assert td.backend_select_goals(['rtype_lltype']) == ['rtype_lltype'] - assert td.backend_select_goals(['rtype']) == ['rtype_lltype'] - assert td.backend_select_goals(['backendopt']) == ['backendopt_lltype'] - assert td.backend_select_goals(['backendopt_lltype']) == [ - 'backendopt_lltype'] - - expected = ['annotate', 'backendopt', 'llinterpret', 'rtype', 'source_c', - 'compile_c', 'pyjitpl'] - - assert set(td.exposed) == set(expected) +def test_no_backendopt(): + td = TranslationDriver({'backendopt.none': True}) + goals = ['annotate', 'rtype', 'source', 'compile'] + assert td.exposed == goals From noreply at buildbot.pypy.org Mon Feb 25 22:07:11 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Mon, 25 Feb 2013 22:07:11 +0100 (CET) Subject: [pypy-commit] pypy refactor-translator: Cleanup. Message-ID: <20130225210711.452D71C0327@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: refactor-translator Changeset: r61774:a99438ba2e6b Date: 2013-02-25 14:50 +0100 http://bitbucket.org/pypy/pypy/changeset/a99438ba2e6b/ Log: Cleanup. diff --git a/rpython/translator/driver.py b/rpython/translator/driver.py --- a/rpython/translator/driver.py +++ b/rpython/translator/driver.py @@ -105,15 +105,12 @@ self.exposed = [] # expose tasks - def expose_task(task, backend_goal=None): - if backend_goal is None: - backend_goal = task + def expose_task(task): def proc(): - return self.proceed(backend_goal) + return self.proceed(task) self.exposed.append(task) setattr(self, task, proc) - backend, ts = self.get_backend_and_type_system() expose_task('annotate') expose_task('rtype') if config.translation.jit: From noreply at buildbot.pypy.org Mon Feb 25 22:07:12 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Mon, 25 Feb 2013 22:07:12 +0100 (CET) Subject: [pypy-commit] pypy refactor-translator: Fix interactive translator. Message-ID: <20130225210712.756651C0327@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: refactor-translator Changeset: r61775:318a8ed33733 Date: 2013-02-25 14:58 +0100 http://bitbucket.org/pypy/pypy/changeset/318a8ed33733/ Log: Fix interactive translator. diff --git a/rpython/translator/interactive.py b/rpython/translator/interactive.py --- a/rpython/translator/interactive.py +++ b/rpython/translator/interactive.py @@ -3,8 +3,6 @@ DEFAULTS = { - 'translation.backend': None, - 'translation.type_system': None, 'translation.verbose': True, } @@ -91,61 +89,57 @@ def rtype(self, **kwds): self.update_options(kwds) - ts = self.ensure_type_system() - return getattr(self.driver, 'rtype_' + ts)() + return self.driver.rtype() def backendopt(self, **kwds): self.update_options(kwds) - ts = self.ensure_type_system('lltype') - return getattr(self.driver, 'backendopt_' + ts)() + return self.driver.backendopt() # backend depedent def source(self, **kwds): self.update_options(kwds) - backend = self.ensure_backend() - getattr(self.driver, 'source_' + backend)() + return self.driver.source() def source_c(self, **kwds): self.update_options(kwds) self.ensure_backend('c') - self.driver.source_c() + self.driver.source() def source_cl(self, **kwds): self.update_options(kwds) self.ensure_backend('cl') - self.driver.source_cl() + self.driver.source() def compile(self, **kwds): self.update_options(kwds) - backend = self.ensure_backend() - getattr(self.driver, 'compile_' + backend)() + self.driver.compile() return self.driver.c_entryp def compile_c(self, **kwds): self.update_options(kwds) self.ensure_backend('c') - self.driver.compile_c() + self.driver.compile() return self.driver.c_entryp def compile_cli(self, **kwds): self.update_options(kwds) self.ensure_backend('cli') - self.driver.compile_cli() + self.driver.compile() return self.driver.c_entryp def source_cli(self, **kwds): self.update_options(kwds) self.ensure_backend('cli') - self.driver.source_cli() + self.driver.source() def compile_jvm(self, **kwds): self.update_options(kwds) self.ensure_backend('jvm') - self.driver.compile_jvm() + self.driver.compile() return self.driver.c_entryp def source_jvm(self, **kwds): self.update_options(kwds) self.ensure_backend('jvm') - self.driver.source_jvm() + self.driver.source() diff --git a/rpython/translator/test/test_interactive.py b/rpython/translator/test/test_interactive.py --- a/rpython/translator/test/test_interactive.py +++ b/rpython/translator/test/test_interactive.py @@ -27,7 +27,7 @@ t.annotate() t.rtype() - assert 'rtype_lltype' in t.driver.done + assert 'rtype_lltype' in t.driver.done def test_simple_backendopt(): def f(x, y): @@ -35,7 +35,7 @@ t = Translation(f, [int, int], backend='c') t.backendopt() - + assert 'backendopt_lltype' in t.driver.done def test_simple_source(): @@ -51,9 +51,6 @@ t.source_c() assert 'source_c' in t.driver.done - t = Translation(f, [int, int]) - py.test.raises(Exception, "t.source()") - def test_disable_logic(): def f(x,y): From noreply at buildbot.pypy.org Mon Feb 25 22:07:13 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Mon, 25 Feb 2013 22:07:13 +0100 (CET) Subject: [pypy-commit] pypy refactor-translator: Temporary hack: remove separation of database_c and source_c. Message-ID: <20130225210713.A67E51C0327@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: refactor-translator Changeset: r61776:bd21a6d5a5a3 Date: 2013-02-25 15:20 +0100 http://bitbucket.org/pypy/pypy/changeset/bd21a6d5a5a3/ Log: Temporary hack: remove separation of database_c and source_c. diff --git a/rpython/translator/driver.py b/rpython/translator/driver.py --- a/rpython/translator/driver.py +++ b/rpython/translator/driver.py @@ -418,10 +418,10 @@ i = 'Boehm GC not installed. Try e.g. "translate.py --gc=hybrid"' raise Exception(str(e) + '\n' + i) - @taskdef([STACKCHECKINSERTION, '?'+BACKENDOPT, RTYPE, '?annotate'], - "Creating database for generating c source", - earlycheck = possibly_check_for_boehm) - def task_database_c(self): + #@taskdef([STACKCHECKINSERTION, '?'+BACKENDOPT, RTYPE, '?annotate'], + # "Creating database for generating c source", + # earlycheck = possibly_check_for_boehm) + def _task_database_c(self): """ Create a database for further backend generation """ translator = self.translator @@ -449,10 +449,12 @@ self.cbuilder = cbuilder self.database = database - @taskdef(['database_c'], "Generating c source") + @taskdef([STACKCHECKINSERTION, '?'+BACKENDOPT, RTYPE, '?annotate'], + "Generating c source") def task_source_c(self): """ Create C source files from the generated database """ + self._task_database_c() cbuilder = self.cbuilder database = self.database if self._backend_extra_options.get('c_debug_defines', False): From noreply at buildbot.pypy.org Mon Feb 25 22:07:14 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Mon, 25 Feb 2013 22:07:14 +0100 (CET) Subject: [pypy-commit] pypy refactor-translator: Rename driver.exposed to driver._tasks to avoid confusion. Message-ID: <20130225210714.C1B021C0327@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: refactor-translator Changeset: r61777:aaddddf3e83b Date: 2013-02-25 15:23 +0100 http://bitbucket.org/pypy/pypy/changeset/aaddddf3e83b/ Log: Rename driver.exposed to driver._tasks to avoid confusion. diff --git a/rpython/translator/driver.py b/rpython/translator/driver.py --- a/rpython/translator/driver.py +++ b/rpython/translator/driver.py @@ -102,13 +102,13 @@ self.default_goal = default_goal self.extra_goals = [] - self.exposed = [] + self._tasks = [] # expose tasks def expose_task(task): def proc(): return self.proceed(task) - self.exposed.append(task) + self._tasks.append(task) setattr(self, task, proc) expose_task('annotate') diff --git a/rpython/translator/test/test_driver.py b/rpython/translator/test/test_driver.py --- a/rpython/translator/test/test_driver.py +++ b/rpython/translator/test/test_driver.py @@ -7,16 +7,16 @@ def test_c_no_jit(): td = TranslationDriver() goals = ['annotate', 'rtype', 'backendopt', 'source', 'compile'] - assert td.exposed == goals + assert td._tasks == goals def test_c_with_jit(): td = TranslationDriver({'jit': True}) goals = ['annotate', 'rtype', 'pyjitpl', 'backendopt', 'source', 'compile'] - assert td.exposed == goals + assert td._tasks == goals def test_no_backendopt(): td = TranslationDriver({'backendopt.none': True}) goals = ['annotate', 'rtype', 'source', 'compile'] - assert td.exposed == goals + assert td._tasks == goals From noreply at buildbot.pypy.org Mon Feb 25 22:07:16 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Mon, 25 Feb 2013 22:07:16 +0100 (CET) Subject: [pypy-commit] pypy refactor-translator: Remove the concept of tasks having dependencies. Message-ID: <20130225210716.01F491C0327@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: refactor-translator Changeset: r61778:18df3c1f21a4 Date: 2013-02-25 15:36 +0100 http://bitbucket.org/pypy/pypy/changeset/18df3c1f21a4/ Log: Remove the concept of tasks having dependencies. diff --git a/rpython/translator/driver.py b/rpython/translator/driver.py --- a/rpython/translator/driver.py +++ b/rpython/translator/driver.py @@ -18,10 +18,9 @@ py.log.setconsumer("translation", ansi_log) -def taskdef(deps, title, new_state=None, expected_states=[], - idemp=False, earlycheck=None): +def taskdef(title, new_state=None, expected_states=[], idemp=False, + earlycheck=None): def decorator(taskfunc): - taskfunc.task_deps = deps taskfunc.task_title = title taskfunc.task_newstate = None taskfunc.task_expected_states = expected_states @@ -283,7 +282,7 @@ #import gc; gc.dump_rpy_heap('rpyheap-after-%s.dump' % goal) return res - @taskdef([], "Annotating&simplifying") + @taskdef("Annotating&simplifying") def task_annotate(self): """ Annotate """ @@ -326,7 +325,7 @@ assert not lost, "lost methods, something gone wrong with the annotation of method defs" RTYPE = 'rtype_lltype' - @taskdef(['annotate'], "RTyping") + @taskdef("RTyping") def task_rtype_lltype(self): """ RTyping - lltype version """ @@ -334,7 +333,7 @@ rtyper.specialize(dont_simplify_again=True) OOTYPE = 'rtype_ootype' - @taskdef(['annotate'], "ootyping") + @taskdef("ootyping") def task_rtype_ootype(self): """ RTyping - ootype version """ @@ -342,7 +341,7 @@ rtyper = self.translator.buildrtyper(type_system="ootype") rtyper.specialize(dont_simplify_again=True) - @taskdef([RTYPE], "JIT compiler generation") + @taskdef("JIT compiler generation") def task_pyjitpl_lltype(self): """ Generate bytecodes for JIT and flow the JIT helper functions lltype version @@ -356,7 +355,7 @@ # self.log.info("the JIT compiler was generated") - @taskdef([OOTYPE], "JIT compiler generation") + @taskdef("JIT compiler generation") def task_pyjitpl_ootype(self): """ Generate bytecodes for JIT and flow the JIT helper functions ootype version @@ -370,7 +369,7 @@ # self.log.info("the JIT compiler was generated") - @taskdef([RTYPE], "test of the JIT on the llgraph backend") + @taskdef("test of the JIT on the llgraph backend") def task_jittest_lltype(self): """ Run with the JIT on top of the llgraph backend """ @@ -384,7 +383,7 @@ jittest.jittest(self) BACKENDOPT = 'backendopt_lltype' - @taskdef([RTYPE, '??pyjitpl_lltype', '??jittest_lltype'], "lltype back-end optimisations") + @taskdef("lltype back-end optimisations") def task_backendopt_lltype(self): """ Run all backend optimizations - lltype version """ @@ -392,7 +391,7 @@ backend_optimizations(self.translator) OOBACKENDOPT = 'backendopt_ootype' - @taskdef([OOTYPE], "ootype back-end optimisations") + @taskdef("ootype back-end optimisations") def task_backendopt_ootype(self): """ Run all backend optimizations - ootype version """ @@ -401,7 +400,7 @@ STACKCHECKINSERTION = 'stackcheckinsertion_lltype' - @taskdef(['?'+BACKENDOPT, RTYPE, 'annotate'], "inserting stack checks") + @taskdef("inserting stack checks") def task_stackcheckinsertion_lltype(self): from rpython.translator.transform import insert_ll_stackcheck count = insert_ll_stackcheck(self.translator) @@ -449,8 +448,7 @@ self.cbuilder = cbuilder self.database = database - @taskdef([STACKCHECKINSERTION, '?'+BACKENDOPT, RTYPE, '?annotate'], - "Generating c source") + @taskdef("Generating c source") def task_source_c(self): """ Create C source files from the generated database """ @@ -501,7 +499,7 @@ self.log.info('usession directory: %s' % (udir,)) self.log.info("created: %s" % (self.c_entryp,)) - @taskdef(['source_c'], "Compiling c source") + @taskdef("Compiling c source") def task_compile_c(self): """ Compile the generated C code using either makefile or translator/platform @@ -518,7 +516,7 @@ else: self.c_entryp = cbuilder.get_entry_point() - @taskdef([STACKCHECKINSERTION, '?'+BACKENDOPT, RTYPE], "LLInterpreting") + @taskdef("LLInterpreting") def task_llinterpret_lltype(self): from rpython.rtyper.llinterp import LLInterpreter py.log.setconsumer("llinterp operation", None) @@ -533,7 +531,7 @@ log.llinterpret.event("result -> %s" % v) - @taskdef(["?" + OOBACKENDOPT, OOTYPE], 'Generating CLI source') + @taskdef('Generating CLI source') def task_source_cli(self): from rpython.translator.cli.gencli import GenCli from rpython.translator.cli.entrypoint import get_entrypoint @@ -551,7 +549,7 @@ filename = self.gen.generate_source() self.log.info("Wrote %s" % (filename,)) - @taskdef(['source_cli'], 'Compiling CLI source') + @taskdef('Compiling CLI source') def task_compile_cli(self): from rpython.translator.oosupport.support import unpatch_os from rpython.translator.cli.test.runtest import CliFunctionWrapper @@ -622,7 +620,7 @@ shutil.copy(main_exe, '.') self.log.info("Copied to %s" % os.path.join(os.getcwd(), dllname)) - @taskdef(["?" + OOBACKENDOPT, OOTYPE], 'Generating JVM source') + @taskdef('Generating JVM source') def task_source_jvm(self): from rpython.translator.jvm.genjvm import GenJvm from rpython.translator.jvm.node import EntryPoint @@ -634,7 +632,7 @@ self.jvmsource = self.gen.generate_source() self.log.info("Wrote JVM code") - @taskdef(['source_jvm'], 'Compiling JVM source') + @taskdef('Compiling JVM source') def task_compile_jvm(self): from rpython.translator.oosupport.support import unpatch_os from rpython.translator.jvm.test.runtest import JvmGeneratedSourceWrapper @@ -700,20 +698,17 @@ classlist.close() return filename - @taskdef(['compile_jvm'], 'XXX') + @taskdef('XXX') def task_run_jvm(self): pass - def proceed(self, goals): - if not goals: - if self.default_goal: - goals = [self.default_goal] - else: - self.log.info("nothing to do") - return - elif isinstance(goals, str): - goals = [goals] - goals.extend(self.extra_goals) + def proceed(self, goal): + assert isinstance(goal, str) + goals = [] + for task in self._tasks: + goals.append(task) + if task == goal: + break goals = self.backend_select_goals(goals) return self._execute(goals, task_skip = self._maybe_skip()) diff --git a/rpython/translator/tool/taskengine.py b/rpython/translator/tool/taskengine.py --- a/rpython/translator/tool/taskengine.py +++ b/rpython/translator/tool/taskengine.py @@ -105,7 +105,7 @@ def _execute(self, goals, *args, **kwds): task_skip = kwds.get('task_skip', []) res = None - goals = self._plan(goals, skip=task_skip) + #goals = self._plan(goals, skip=task_skip) for goal in goals: taskcallable, _ = self.tasks[goal] self._event('planned', goal, taskcallable) From noreply at buildbot.pypy.org Mon Feb 25 22:07:17 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Mon, 25 Feb 2013 22:07:17 +0100 (CET) Subject: [pypy-commit] pypy refactor-translator: Cleanup. Message-ID: <20130225210717.216561C0327@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: refactor-translator Changeset: r61779:be4da41d53e8 Date: 2013-02-25 15:41 +0100 http://bitbucket.org/pypy/pypy/changeset/be4da41d53e8/ Log: Cleanup. diff --git a/rpython/translator/driver.py b/rpython/translator/driver.py --- a/rpython/translator/driver.py +++ b/rpython/translator/driver.py @@ -96,8 +96,6 @@ if default_goal: default_goal, = self.backend_select_goals([default_goal]) - if default_goal in self._maybe_skip(): - default_goal = None self.default_goal = default_goal self.extra_goals = [] @@ -152,14 +150,6 @@ def disable(self, to_disable): self._disabled = to_disable - def _maybe_skip(self): - maybe_skip = [] - if self._disabled: - for goal in self.backend_select_goals(self._disabled): - maybe_skip.extend(self._depending_on_closure(goal)) - return dict.fromkeys(maybe_skip).keys() - - def setup(self, entry_point, inputtypes, policy=None, extra={}, empty_translator=None): standalone = inputtypes is None self.standalone = standalone @@ -710,7 +700,7 @@ if task == goal: break goals = self.backend_select_goals(goals) - return self._execute(goals, task_skip = self._maybe_skip()) + return self._execute(goals) def from_targetspec(targetspec_dic, config=None, args=None, empty_translator=None, diff --git a/rpython/translator/tool/taskengine.py b/rpython/translator/tool/taskengine.py --- a/rpython/translator/tool/taskengine.py +++ b/rpython/translator/tool/taskengine.py @@ -16,96 +16,8 @@ tasks[task_name] = task, task_deps - def _plan(self, goals, skip=[]): - skip = [toskip for toskip in skip if toskip not in goals] - - key = (tuple(goals), tuple(skip)) - try: - return self._plan_cache[key] - except KeyError: - pass - constraints = [] - - def subgoals(task_name): - taskcallable, deps = self.tasks[task_name] - for dep in deps: - if dep.startswith('??'): # optional - dep = dep[2:] - if dep not in goals: - continue - if dep.startswith('?'): # suggested - dep = dep[1:] - if dep in skip: - continue - yield dep - - seen = {} - - def consider(subgoal): - if subgoal in seen: - return - else: - seen[subgoal] = True - constraints.append([subgoal]) - deps = subgoals(subgoal) - for dep in deps: - constraints.append([subgoal, dep]) - consider(dep) - - for goal in goals: - consider(goal) - - #sort - - plan = [] - - while True: - cands = dict.fromkeys([constr[0] for constr in constraints if constr]) - if not cands: - break - - for cand in cands: - for constr in constraints: - if cand in constr[1:]: - break - else: - break - else: - raise RuntimeError, "circular dependecy" - - plan.append(cand) - for constr in constraints: - if constr and constr[0] == cand: - del constr[0] - - plan.reverse() - - self._plan_cache[key] = plan - - return plan - - def _depending_on(self, goal): - l = [] - for task_name, (task, task_deps) in self.tasks.iteritems(): - if goal in task_deps: - l.append(task_name) - return l - - def _depending_on_closure(self, goal): - d = {} - def track(goal): - if goal in d: - return - d[goal] = True - for depending in self._depending_on(goal): - track(depending) - track(goal) - return d.keys() - def _execute(self, goals, *args, **kwds): - task_skip = kwds.get('task_skip', []) res = None - #goals = self._plan(goals, skip=task_skip) for goal in goals: taskcallable, _ = self.tasks[goal] self._event('planned', goal, taskcallable) From noreply at buildbot.pypy.org Mon Feb 25 22:07:18 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Mon, 25 Feb 2013 22:07:18 +0100 (CET) Subject: [pypy-commit] pypy refactor-translator: Remove SimpleTaskEngine and move remaining code into TranslationDriver. Message-ID: <20130225210718.534C11C0327@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: refactor-translator Changeset: r61780:04ce742ce3b7 Date: 2013-02-25 15:46 +0100 http://bitbucket.org/pypy/pypy/changeset/04ce742ce3b7/ Log: Remove SimpleTaskEngine and move remaining code into TranslationDriver. diff --git a/rpython/translator/driver.py b/rpython/translator/driver.py --- a/rpython/translator/driver.py +++ b/rpython/translator/driver.py @@ -3,7 +3,6 @@ import shutil from rpython.translator.translator import TranslationContext -from rpython.translator.tool.taskengine import SimpleTaskEngine from rpython.translator.goal import query from rpython.translator.goal.timing import Timer from rpython.annotator.listdef import s_list_of_strings @@ -65,7 +64,7 @@ os._exit(0) -class TranslationDriver(SimpleTaskEngine): +class TranslationDriver(object): _backend_extra_options = {} def __init__(self, setopts=None, default_goal=None, @@ -73,7 +72,6 @@ exe_name=None, extmod_name=None, config=None, overrides=None): self.timer = Timer() - SimpleTaskEngine.__init__(self) self.log = log @@ -99,8 +97,19 @@ self.default_goal = default_goal self.extra_goals = [] + + self.tasks = tasks = {} + + for name in dir(self): + if name.startswith('task_'): + task_name = name[len('task_'):] + task = getattr(self, name) + assert callable(task) + task_deps = getattr(task, 'task_deps', []) + + tasks[task_name] = task, task_deps + self._tasks = [] - # expose tasks def expose_task(task): def proc(): @@ -700,7 +709,17 @@ if task == goal: break goals = self.backend_select_goals(goals) - return self._execute(goals) + + res = None + for goal in goals: + taskcallable, _ = self.tasks[goal] + self._event('planned', goal, taskcallable) + for goal in goals: + taskcallable, _ = self.tasks[goal] + self._event('pre', goal, taskcallable) + res = self._do(goal, taskcallable) + self._event('post', goal, taskcallable) + return res def from_targetspec(targetspec_dic, config=None, args=None, empty_translator=None, diff --git a/rpython/translator/tool/taskengine.py b/rpython/translator/tool/taskengine.py deleted file mode 100644 --- a/rpython/translator/tool/taskengine.py +++ /dev/null @@ -1,48 +0,0 @@ - - -class SimpleTaskEngine(object): - - def __init__(self): - self._plan_cache = {} - - self.tasks = tasks = {} - - for name in dir(self): - if name.startswith('task_'): - task_name = name[len('task_'):] - task = getattr(self, name) - assert callable(task) - task_deps = getattr(task, 'task_deps', []) - - tasks[task_name] = task, task_deps - - def _execute(self, goals, *args, **kwds): - res = None - for goal in goals: - taskcallable, _ = self.tasks[goal] - self._event('planned', goal, taskcallable) - for goal in goals: - taskcallable, _ = self.tasks[goal] - self._event('pre', goal, taskcallable) - try: - res = self._do(goal, taskcallable, *args, **kwds) - except (SystemExit, KeyboardInterrupt): - raise - except: - self._error(goal) - raise - self._event('post', goal, taskcallable) - return res - - def _do(self, goal, func, *args, **kwds): - return func() - - def _event(self, kind, goal, func): - pass - - def _error(self, goal): - pass - - - - diff --git a/rpython/translator/tool/test/test_taskengine.py b/rpython/translator/tool/test/test_taskengine.py deleted file mode 100644 --- a/rpython/translator/tool/test/test_taskengine.py +++ /dev/null @@ -1,150 +0,0 @@ -from rpython.translator.tool.taskengine import SimpleTaskEngine - -def test_simple(): - - class ABC(SimpleTaskEngine): - - def task_A(self): - pass - - task_A.task_deps = ['B', '?C'] - - def task_B(self): - pass - - def task_C(self): - pass - - task_C.task_deps = ['B'] - - def task_D(self): - pass - task_D.task_deps = ['E'] - - def task_E(self): - pass - task_E.task_deps = ['F'] - - def task_F(self): - pass - - abc = ABC() - - assert abc._plan('B') == ['B'] - assert abc._plan('C') == ['B', 'C'] - assert abc._plan('A') == ['B', 'C', 'A'] - assert abc._plan('A', skip=['C']) == ['B', 'A'] - - assert abc._depending_on('C') == [] - assert dict.fromkeys(abc._depending_on('B'), True) == {'A':True, 'C':True} - assert abc._depending_on('A') == [] - - assert abc._depending_on('F') == ['E'] - assert abc._depending_on('E') == ['D'] - assert abc._depending_on('D') == [] - - assert abc._depending_on_closure('C') == ['C'] - assert dict.fromkeys(abc._depending_on_closure('B'), True) == {'A':True, 'C':True, 'B': True} - assert abc._depending_on_closure('A') == ['A'] - - assert dict.fromkeys(abc._depending_on_closure('F'), True) == {'D':True, 'E':True, 'F': True} - assert dict.fromkeys(abc._depending_on_closure('E'), True) == {'D':True, 'E':True} - assert abc._depending_on_closure('D') == ['D'] - - -def test_execute(): - - class ABC(SimpleTaskEngine): - - def __init__(self): - SimpleTaskEngine.__init__(self) - self.done = [] - - def task_A(self): - self.done.append('A') - - task_A.task_deps = ['B', '?C'] - - def task_B(self): - self.done.append('B') - - def task_C(self): - self.done.append('C') - - task_C.task_deps = ['B'] - - def _event(self, kind, goal, taskcallable): - self.done.append((kind, goal)) - - def test(goals, task_skip=[]): - if isinstance(goals, str): - goals = [goals] - abc = ABC() - abc._execute(goals, task_skip=task_skip) - return abc.done - - def trace(goals): - t = [] - for goal in goals: - t.append(('planned', goal)) - for goal in goals: - t.extend([('pre', goal), goal, ('post', goal)]) - return t - - assert test('B') == trace('B') - assert test('C') == trace(['B', 'C']) - assert test('A') == trace(['B', 'C', 'A']) - assert test('A', ['C']) == trace(['B', 'A']) - assert test(['B', 'C']) == trace(['B', 'C']) - assert test(['C', 'B']) == trace(['B', 'C']) - assert test(['B', 'A']) == trace(['B', 'C', 'A']) - assert test(['B', 'A'], ['C']) == trace(['B', 'A']) - assert test(['B', 'A', 'C']) == trace(['B', 'C', 'A']) - assert test(['B', 'A', 'C'], ['C']) == trace(['B', 'C', 'A']) - -def test_driver(): - class Drv(SimpleTaskEngine): - - def task_A(): - pass - task_A.task_deps = [] - - def task_R(): - pass - task_R.task_deps = ['A'] - - def task_b(): - pass - task_b.task_deps = ['R'] - - def task_H(): - pass - task_H.task_deps = ['b'] - - def task_T(): - pass - task_T.task_deps = ['H'] - - def task_B(): - pass - task_B.task_deps = ['R', '??T'] - - def task_D(): - pass - task_D.task_deps = ['R', '?B', '?A', '??T'] - - drv = Drv() - assert drv._plan(['R']) == ['A', 'R'] - assert drv._plan(['B']) == ['A', 'R', 'B'] - assert drv._plan(['D']) == ['A', 'R', 'B', 'D'] - assert drv._plan(['D'], skip=['B']) == ['A', 'R', 'D'] - assert drv._plan(['D', 'R']) == ['A', 'R', 'B', 'D'] - - - assert drv._plan(['H', 'R']) == ['A', 'R', 'b', 'H'] - assert drv._plan(['H']) == ['A', 'R', 'b', 'H'] - assert drv._plan(['T', 'B']) == ['A', 'R', 'b', 'H', 'T', 'B'] - assert drv._plan(['D', 'T']) == ['A', 'R', 'b', 'H', 'T', 'B', 'D'] - assert drv._plan(['D', 'T', 'R']) == ['A', 'R', 'b', 'H', 'T', 'B', 'D'] - assert drv._plan(['D', 'T']) == ['A', 'R', 'b', 'H', 'T', 'B', 'D'] - assert drv._plan(['D', 'T'], skip=['B']) == ['A', 'R', 'b', 'H', 'T', 'D'] From noreply at buildbot.pypy.org Mon Feb 25 22:07:19 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Mon, 25 Feb 2013 22:07:19 +0100 (CET) Subject: [pypy-commit] pypy refactor-translator: Unify some *_lltype and *_ootype tasks. Message-ID: <20130225210719.7B18C1C0327@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: refactor-translator Changeset: r61781:3ada9ee0aac8 Date: 2013-02-25 15:56 +0100 http://bitbucket.org/pypy/pypy/changeset/3ada9ee0aac8/ Log: Unify some *_lltype and *_ootype tasks. diff --git a/rpython/translator/driver.py b/rpython/translator/driver.py --- a/rpython/translator/driver.py +++ b/rpython/translator/driver.py @@ -325,23 +325,15 @@ RTYPE = 'rtype_lltype' @taskdef("RTyping") - def task_rtype_lltype(self): + def task_rtype(self): """ RTyping - lltype version """ - rtyper = self.translator.buildrtyper(type_system='lltype') - rtyper.specialize(dont_simplify_again=True) - - OOTYPE = 'rtype_ootype' - @taskdef("ootyping") - def task_rtype_ootype(self): - """ RTyping - ootype version - """ - # Maybe type_system should simply be an option used in task_rtype - rtyper = self.translator.buildrtyper(type_system="ootype") + type_system = self.config.translation.type_system + rtyper = self.translator.buildrtyper(type_system) rtyper.specialize(dont_simplify_again=True) @taskdef("JIT compiler generation") - def task_pyjitpl_lltype(self): + def task_pyjitpl(self): """ Generate bytecodes for JIT and flow the JIT helper functions lltype version """ @@ -354,22 +346,8 @@ # self.log.info("the JIT compiler was generated") - @taskdef("JIT compiler generation") - def task_pyjitpl_ootype(self): - """ Generate bytecodes for JIT and flow the JIT helper functions - ootype version - """ - get_policy = self.extra['jitpolicy'] - self.jitpolicy = get_policy(self) - # - from rpython.jit.metainterp.warmspot import apply_jit - apply_jit(self.translator, policy=self.jitpolicy, - backend_name='cli', inline=True) #XXX - # - self.log.info("the JIT compiler was generated") - @taskdef("test of the JIT on the llgraph backend") - def task_jittest_lltype(self): + def task_jittest(self): """ Run with the JIT on top of the llgraph backend """ # parent process loop: spawn a child, wait for the child to finish, @@ -383,21 +361,12 @@ BACKENDOPT = 'backendopt_lltype' @taskdef("lltype back-end optimisations") - def task_backendopt_lltype(self): + def task_backendopt(self): """ Run all backend optimizations - lltype version """ from rpython.translator.backendopt.all import backend_optimizations backend_optimizations(self.translator) - OOBACKENDOPT = 'backendopt_ootype' - @taskdef("ootype back-end optimisations") - def task_backendopt_ootype(self): - """ Run all backend optimizations - ootype version - """ - from rpython.translator.backendopt.all import backend_optimizations - backend_optimizations(self.translator) - - STACKCHECKINSERTION = 'stackcheckinsertion_lltype' @taskdef("inserting stack checks") def task_stackcheckinsertion_lltype(self): diff --git a/rpython/translator/interactive.py b/rpython/translator/interactive.py --- a/rpython/translator/interactive.py +++ b/rpython/translator/interactive.py @@ -69,10 +69,6 @@ self.ensure_type_system() return backend - # disable some goals (steps) - def disable(self, to_disable): - self.driver.disable(to_disable) - def set_backend_extra_options(self, **extra_options): for name in extra_options: backend, option = name.split('_', 1) diff --git a/rpython/translator/test/test_interactive.py b/rpython/translator/test/test_interactive.py --- a/rpython/translator/test/test_interactive.py +++ b/rpython/translator/test/test_interactive.py @@ -27,7 +27,7 @@ t.annotate() t.rtype() - assert 'rtype_lltype' in t.driver.done + assert 'rtype' in t.driver.done def test_simple_backendopt(): def f(x, y): @@ -36,7 +36,7 @@ t = Translation(f, [int, int], backend='c') t.backendopt() - assert 'backendopt_lltype' in t.driver.done + assert 'backendopt' in t.driver.done def test_simple_source(): def f(x, y): @@ -52,6 +52,7 @@ assert 'source_c' in t.driver.done def test_disable_logic(): + return # temporary skip def f(x,y): return x+y @@ -84,24 +85,24 @@ t = Translation(f, [int, int]) t.rtype(type_system='lltype') - assert 'rtype_lltype' in t.driver.done + assert 'rtype' in t.driver.done t = Translation(f, [int, int]) t.rtype(type_system='ootype') - assert 'rtype_ootype' in t.driver.done + assert 'rtype' in t.driver.done t = Translation(f, [int, int], type_system='ootype') t.rtype() - assert 'rtype_ootype' in t.driver.done + assert 'rtype' in t.driver.done t = Translation(f, [int, int]) t.rtype(backend='cli') - assert 'rtype_ootype' in t.driver.done + assert 'rtype' in t.driver.done t = Translation(f, [int, int], backend='cli', type_system='ootype') t.rtype() - assert 'rtype_ootype' in t.driver.done + assert 'rtype' in t.driver.done t = Translation(f, [int, int], type_system='lltype') t.annotate() From noreply at buildbot.pypy.org Mon Feb 25 22:07:20 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Mon, 25 Feb 2013 22:07:20 +0100 (CET) Subject: [pypy-commit] pypy refactor-translator: Cleanup. Message-ID: <20130225210720.909D31C0327@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: refactor-translator Changeset: r61782:d257d5992595 Date: 2013-02-25 16:25 +0100 http://bitbucket.org/pypy/pypy/changeset/d257d5992595/ Log: Cleanup. diff --git a/rpython/translator/driver.py b/rpython/translator/driver.py --- a/rpython/translator/driver.py +++ b/rpython/translator/driver.py @@ -17,12 +17,9 @@ py.log.setconsumer("translation", ansi_log) -def taskdef(title, new_state=None, expected_states=[], idemp=False, - earlycheck=None): +def taskdef(title, idemp=False, earlycheck=None): def decorator(taskfunc): taskfunc.task_title = title - taskfunc.task_newstate = None - taskfunc.task_expected_states = expected_states taskfunc.task_idempotent = idemp taskfunc.task_earlycheck = earlycheck return taskfunc @@ -31,13 +28,6 @@ # TODO: # sanity-checks using states -_BACKEND_TO_TYPESYSTEM = { - 'c': 'lltype', -} - -def backend_to_typesystem(backend): - return _BACKEND_TO_TYPESYSTEM.get(backend, 'ootype') - # set of translation steps to profile PROFILE = set([]) @@ -67,8 +57,7 @@ class TranslationDriver(object): _backend_extra_options = {} - def __init__(self, setopts=None, default_goal=None, - disable=[], + def __init__(self, setopts=None, exe_name=None, extmod_name=None, config=None, overrides=None): self.timer = Timer() @@ -90,14 +79,6 @@ self.done = {} - self.disable(disable) - - if default_goal: - default_goal, = self.backend_select_goals([default_goal]) - - self.default_goal = default_goal - self.extra_goals = [] - self.tasks = tasks = {} for name in dir(self): @@ -105,9 +86,7 @@ task_name = name[len('task_'):] task = getattr(self, name) assert callable(task) - task_deps = getattr(task, 'task_deps', []) - - tasks[task_name] = task, task_deps + tasks[task_name] = task self._tasks = [] # expose tasks @@ -126,24 +105,16 @@ expose_task('source') expose_task('compile') - def set_extra_goals(self, goals): - self.extra_goals = goals - def set_backend_extra_options(self, extra_options): self._backend_extra_options = extra_options - + def get_info(self): # XXX more? d = {'backend': self.config.translation.backend} return d - def get_backend_and_type_system(self): - type_system = self.config.translation.type_system + def backend_select_goals(self, goals): backend = self.config.translation.backend - return backend, type_system - - def backend_select_goals(self, goals): - backend, ts = self.get_backend_and_type_system() - postfixes = [''] + ['_'+p for p in (backend, ts) if p] + postfixes = ['', '_' + backend] l = [] for goal in goals: for postfix in postfixes: @@ -156,9 +127,6 @@ l.append(new_goal) return l - def disable(self, to_disable): - self._disabled = to_disable - def setup(self, entry_point, inputtypes, policy=None, extra={}, empty_translator=None): standalone = inputtypes is None self.standalone = standalone @@ -203,7 +171,8 @@ self.secondary_entrypoints = libdef.functions def instrument_result(self, args): - backend, ts = self.get_backend_and_type_system() + backend = self.config.translation.backend + backend = self.config.translation.backend if backend != 'c' or sys.platform == 'win32': raise Exception("instrumentation requires the c backend" " and unix for now") @@ -268,6 +237,7 @@ if not func.task_idempotent: self.done[goal] = True if instrument: + xxx self.proceed('compile') assert False, 'we should not get here' finally: @@ -681,27 +651,31 @@ res = None for goal in goals: - taskcallable, _ = self.tasks[goal] - self._event('planned', goal, taskcallable) + taskcallable = self.tasks[goal] + if taskcallable.task_earlycheck: + func.task_earlycheck(self) for goal in goals: - taskcallable, _ = self.tasks[goal] - self._event('pre', goal, taskcallable) + taskcallable = self.tasks[goal] + fork_before = self.config.translation.fork_before + if fork_before: + fork_before, = self.backend_select_goals([fork_before]) + if not fork_before in self.done and fork_before == goal: + prereq = getattr(self, 'prereq_checkpt_%s' % goal, None) + if prereq: + prereq() + from rpython.translator.goal import unixcheckpoint + unixcheckpoint.restartable_point(auto='run') res = self._do(goal, taskcallable) - self._event('post', goal, taskcallable) return res def from_targetspec(targetspec_dic, config=None, args=None, - empty_translator=None, - disable=[], - default_goal=None): + empty_translator=None): if args is None: args = [] - driver = TranslationDriver(config=config, default_goal=default_goal, - disable=disable) + driver = TranslationDriver(config=config) # patch some attributes of the os module to make sure they # have the same value on every platform. - backend, ts = driver.get_backend_and_type_system() if backend in ('cli', 'jvm'): from rpython.translator.oosupport.support import patch_os driver.old_cli_defs = patch_os() @@ -727,23 +701,6 @@ def prereq_checkpt_rtype(self): assert 'rpython.rtyper.rmodel' not in sys.modules, ( "cannot fork because the rtyper has already been imported") - prereq_checkpt_rtype_lltype = prereq_checkpt_rtype - prereq_checkpt_rtype_ootype = prereq_checkpt_rtype - - # checkpointing support - def _event(self, kind, goal, func): - if kind == 'planned' and func.task_earlycheck: - func.task_earlycheck(self) - if kind == 'pre': - fork_before = self.config.translation.fork_before - if fork_before: - fork_before, = self.backend_select_goals([fork_before]) - if not fork_before in self.done and fork_before == goal: - prereq = getattr(self, 'prereq_checkpt_%s' % goal, None) - if prereq: - prereq() - from rpython.translator.goal import unixcheckpoint - unixcheckpoint.restartable_point(auto='run') def mkexename(name): if sys.platform == 'win32': From noreply at buildbot.pypy.org Mon Feb 25 22:07:21 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Mon, 25 Feb 2013 22:07:21 +0100 (CET) Subject: [pypy-commit] pypy refactor-translator: Replace cbuilder.generate_source(defines=cbuilder.DEBUG_DEFINES) with cbuilder.generate_source(debug_defines=True). Message-ID: <20130225210721.B4A701C0327@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: refactor-translator Changeset: r61783:37c2b24250ea Date: 2013-02-25 16:43 +0100 http://bitbucket.org/pypy/pypy/changeset/37c2b24250ea/ Log: Replace cbuilder.generate_source(defines=cbuilder.DEBUG_DEFINES) with cbuilder.generate_source(debug_defines=True). diff --git a/rpython/jit/backend/arm/test/test_zrpy_gc.py b/rpython/jit/backend/arm/test/test_zrpy_gc.py --- a/rpython/jit/backend/arm/test/test_zrpy_gc.py +++ b/rpython/jit/backend/arm/test/test_zrpy_gc.py @@ -115,7 +115,7 @@ setattr(obj, attr, oldvalue) cbuilder = genc.CStandaloneBuilder(t, f, t.config) - cbuilder.generate_source(defines=cbuilder.DEBUG_DEFINES) + cbuilder.generate_source(debug_defines=True) cbuilder.compile() return cbuilder diff --git a/rpython/jit/backend/x86/test/test_zrpy_gc.py b/rpython/jit/backend/x86/test/test_zrpy_gc.py --- a/rpython/jit/backend/x86/test/test_zrpy_gc.py +++ b/rpython/jit/backend/x86/test/test_zrpy_gc.py @@ -111,7 +111,7 @@ setattr(obj, attr, oldvalue) cbuilder = genc.CStandaloneBuilder(t, f, t.config) - cbuilder.generate_source(defines=cbuilder.DEBUG_DEFINES) + cbuilder.generate_source(debug_defines=True) cbuilder.compile() return cbuilder diff --git a/rpython/translator/c/gcc/test/test_asmgcroot.py b/rpython/translator/c/gcc/test/test_asmgcroot.py --- a/rpython/translator/c/gcc/test/test_asmgcroot.py +++ b/rpython/translator/c/gcc/test/test_asmgcroot.py @@ -58,8 +58,7 @@ cbuilder = CStandaloneBuilder(t, main, config=config, secondary_entrypoints=sec_ep) - c_source_filename = cbuilder.generate_source( - defines = cbuilder.DEBUG_DEFINES) + c_source_filename = cbuilder.generate_source(debug_defines=True) cls._patch_makefile(cbuilder.targetdir) if option.view: t.view() diff --git a/rpython/translator/c/genc.py b/rpython/translator/c/genc.py --- a/rpython/translator/c/genc.py +++ b/rpython/translator/c/genc.py @@ -206,11 +206,6 @@ return gc.name_to_gcpolicy[name] return self.gcpolicy - # use generate_source(defines=DEBUG_DEFINES) to force the #definition - # of the macros that enable debugging assertions - DEBUG_DEFINES = {'RPY_ASSERT': 1, - 'RPY_LL_ASSERT': 1} - def generate_graphs_for_llinterp(self, db=None): # prepare the graphs as when the source is generated, but without # actually generating the source. @@ -224,7 +219,7 @@ funcgen.patch_graph(copy_graph=False) return db - def generate_source(self, db=None, defines={}, exe_name=None): + def generate_source(self, db=None, debug_defines=True, exe_name=None): assert self.c_source_filename is None if db is None: @@ -238,7 +233,10 @@ targetdir = NullPyPathLocal(targetdir) self.targetdir = targetdir - defines = defines.copy() + defines = {} + if debug_defines: + defines['RPY_ASSERT'] = 1 + defines['RPY_LL_ASSERT'] = 1 if self.config.translation.countmallocs: defines['COUNT_OP_MALLOCS'] = 1 if self.config.translation.sandbox: diff --git a/rpython/translator/c/test/test_standalone.py b/rpython/translator/c/test/test_standalone.py --- a/rpython/translator/c/test/test_standalone.py +++ b/rpython/translator/c/test/test_standalone.py @@ -31,7 +31,7 @@ cbuilder = CStandaloneBuilder(t, entry_point, t.config) if debug: - cbuilder.generate_source(defines=cbuilder.DEBUG_DEFINES) + cbuilder.generate_source(debug_defines=True) else: cbuilder.generate_source() cbuilder.compile() @@ -848,7 +848,7 @@ t.buildrtyper().specialize() # cbuilder = CStandaloneBuilder(t, entry_point, t.config) - cbuilder.generate_source(defines=cbuilder.DEBUG_DEFINES) + cbuilder.generate_source(debug_defines=True) cbuilder.compile() # return t, cbuilder diff --git a/rpython/translator/driver.py b/rpython/translator/driver.py --- a/rpython/translator/driver.py +++ b/rpython/translator/driver.py @@ -393,16 +393,13 @@ self._task_database_c() cbuilder = self.cbuilder database = self.database - if self._backend_extra_options.get('c_debug_defines', False): - defines = cbuilder.DEBUG_DEFINES - else: - defines = {} + debug_def = self._backend_extra_options.get('c_debug_defines', False) if self.exe_name is not None: exe_name = self.exe_name % self.get_info() else: exe_name = None - c_source_filename = cbuilder.generate_source(database, defines, - exe_name=exe_name) + c_source_filename = cbuilder.generate_source( + database, debug_defines=debug_def, exe_name=exe_name) self.log.info("written: %s" % (c_source_filename,)) if self.config.translation.dump_static_data_info: from rpython.translator.tool.staticsizereport import dump_static_data_info From noreply at buildbot.pypy.org Mon Feb 25 22:07:22 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Mon, 25 Feb 2013 22:07:22 +0100 (CET) Subject: [pypy-commit] pypy refactor-translator: Cleanup. Message-ID: <20130225210722.E1FF11C0327@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: refactor-translator Changeset: r61784:edde9081e8e4 Date: 2013-02-25 19:24 +0100 http://bitbucket.org/pypy/pypy/changeset/edde9081e8e4/ Log: Cleanup. diff --git a/rpython/translator/driver.py b/rpython/translator/driver.py --- a/rpython/translator/driver.py +++ b/rpython/translator/driver.py @@ -48,7 +48,7 @@ env = os.environ.copy() env['PYPY_INSTRUMENT_COUNTERS'] = str(self.datafile) self.compiler.platform.execute(exe, args, env=env) - + def after(self): # xxx os._exit(0) @@ -172,7 +172,6 @@ def instrument_result(self, args): backend = self.config.translation.backend - backend = self.config.translation.backend if backend != 'c' or sys.platform == 'win32': raise Exception("instrumentation requires the c backend" " and unix for now") @@ -244,11 +243,8 @@ try: debug_stop('translation-task') self.timer.end_event(goal) - except (KeyboardInterrupt, SystemExit): - raise - except: + except Exception: pass - #import gc; gc.dump_rpy_heap('rpyheap-after-%s.dump' % goal) return res @taskdef("Annotating&simplifying") @@ -283,7 +279,6 @@ annotator.simplify() return s - def sanity_check_annotation(self): translator = self.translator irreg = query.qoutput(query.check_exceptblocks_qgen(translator)) @@ -293,10 +288,9 @@ lost = query.qoutput(query.check_methods_qgen(translator)) assert not lost, "lost methods, something gone wrong with the annotation of method defs" - RTYPE = 'rtype_lltype' @taskdef("RTyping") def task_rtype(self): - """ RTyping - lltype version + """ RTyping """ type_system = self.config.translation.type_system rtyper = self.translator.buildrtyper(type_system) @@ -305,7 +299,6 @@ @taskdef("JIT compiler generation") def task_pyjitpl(self): """ Generate bytecodes for JIT and flow the JIT helper functions - lltype version """ get_policy = self.extra['jitpolicy'] self.jitpolicy = get_policy(self) @@ -329,21 +322,18 @@ from rpython.jit.tl import jittest jittest.jittest(self) - BACKENDOPT = 'backendopt_lltype' - @taskdef("lltype back-end optimisations") + @taskdef("back-end optimisations") def task_backendopt(self): - """ Run all backend optimizations - lltype version + """ Run all backend optimizations """ from rpython.translator.backendopt.all import backend_optimizations backend_optimizations(self.translator) - STACKCHECKINSERTION = 'stackcheckinsertion_lltype' @taskdef("inserting stack checks") def task_stackcheckinsertion_lltype(self): from rpython.translator.transform import insert_ll_stackcheck count = insert_ll_stackcheck(self.translator) self.log.info("inserted %d stack checks." % (count,)) - def possibly_check_for_boehm(self): if self.config.translation.gc == "boehm": @@ -355,10 +345,9 @@ i = 'Boehm GC not installed. Try e.g. "translate.py --gc=hybrid"' raise Exception(str(e) + '\n' + i) - #@taskdef([STACKCHECKINSERTION, '?'+BACKENDOPT, RTYPE, '?annotate'], - # "Creating database for generating c source", - # earlycheck = possibly_check_for_boehm) - def _task_database_c(self): + @taskdef("Creating database for generating c source", + earlycheck=possibly_check_for_boehm) + def task_database_c(self): """ Create a database for further backend generation """ translator = self.translator @@ -390,7 +379,7 @@ def task_source_c(self): """ Create C source files from the generated database """ - self._task_database_c() + self.task_database_c() cbuilder = self.cbuilder database = self.database debug_def = self._backend_extra_options.get('c_debug_defines', False) @@ -420,7 +409,9 @@ """ if self.exe_name is not None: exename = self.c_entryp - newexename = mkexename(self.compute_exe_name()) + newexename = self.compute_exe_name() + if sys.platform == 'win32': + newexename = newexename.new(ext='exe') shutil.copy(str(exename), str(newexename)) if self.cbuilder.shared_library_name is not None: soname = self.cbuilder.shared_library_name @@ -455,7 +446,7 @@ def task_llinterpret_lltype(self): from rpython.rtyper.llinterp import LLInterpreter py.log.setconsumer("llinterp operation", None) - + translator = self.translator interp = LLInterpreter(translator.rtyper) bk = translator.annotator.bookkeeper @@ -493,7 +484,7 @@ # restore original os values if hasattr(self, 'old_cli_defs'): unpatch_os(self.old_cli_defs) - + self.log.info("Compiled %s" % filename) if self.standalone and self.exe_name: self.copy_cli_exe() @@ -547,7 +538,7 @@ pypylib_dll = os.path.join(usession_path, 'pypylib.dll') shutil.copy(dllname, '.') shutil.copy(pypylib_dll, '.') - + # main.exe is a stub but is needed right now because it's # referenced by pypylib.dll. Will be removed in the future translator_path, _ = os.path.split(__file__) @@ -676,7 +667,7 @@ if backend in ('cli', 'jvm'): from rpython.translator.oosupport.support import patch_os driver.old_cli_defs = patch_os() - + target = targetspec_dic['target'] spec = target(driver, args) @@ -686,8 +677,8 @@ entry_point, inputtypes = spec policy = None - driver.setup(entry_point, inputtypes, - policy=policy, + driver.setup(entry_point, inputtypes, + policy=policy, extra=targetspec_dic, empty_translator=empty_translator) @@ -698,8 +689,3 @@ def prereq_checkpt_rtype(self): assert 'rpython.rtyper.rmodel' not in sys.modules, ( "cannot fork because the rtyper has already been imported") - -def mkexename(name): - if sys.platform == 'win32': - name = name.new(ext='exe') - return name From noreply at buildbot.pypy.org Mon Feb 25 22:07:24 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Mon, 25 Feb 2013 22:07:24 +0100 (CET) Subject: [pypy-commit] pypy refactor-translator: Temporary remove fork_before support. It's not tested at the moment anyway. Message-ID: <20130225210724.0289F1C0327@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: refactor-translator Changeset: r61785:81203db2cabe Date: 2013-02-25 19:47 +0100 http://bitbucket.org/pypy/pypy/changeset/81203db2cabe/ Log: Temporary remove fork_before support. It's not tested at the moment anyway. diff --git a/rpython/translator/driver.py b/rpython/translator/driver.py --- a/rpython/translator/driver.py +++ b/rpython/translator/driver.py @@ -644,15 +644,6 @@ func.task_earlycheck(self) for goal in goals: taskcallable = self.tasks[goal] - fork_before = self.config.translation.fork_before - if fork_before: - fork_before, = self.backend_select_goals([fork_before]) - if not fork_before in self.done and fork_before == goal: - prereq = getattr(self, 'prereq_checkpt_%s' % goal, None) - if prereq: - prereq() - from rpython.translator.goal import unixcheckpoint - unixcheckpoint.restartable_point(auto='run') res = self._do(goal, taskcallable) return res From noreply at buildbot.pypy.org Mon Feb 25 22:07:25 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Mon, 25 Feb 2013 22:07:25 +0100 (CET) Subject: [pypy-commit] pypy refactor-translator: Refactor. Message-ID: <20130225210725.1810D1C0327@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: refactor-translator Changeset: r61786:b26bc2316815 Date: 2013-02-25 20:01 +0100 http://bitbucket.org/pypy/pypy/changeset/b26bc2316815/ Log: Refactor. diff --git a/rpython/translator/driver.py b/rpython/translator/driver.py --- a/rpython/translator/driver.py +++ b/rpython/translator/driver.py @@ -19,6 +19,8 @@ def taskdef(title, idemp=False, earlycheck=None): def decorator(taskfunc): + assert taskfunc.__name__.startswith('task_') + taskfunc.task_name = taskfunc.__name__[len('task_'):] taskfunc.task_title = title taskfunc.task_idempotent = idemp taskfunc.task_earlycheck = earlycheck @@ -79,21 +81,12 @@ self.done = {} - self.tasks = tasks = {} - - for name in dir(self): - if name.startswith('task_'): - task_name = name[len('task_'):] - task = getattr(self, name) - assert callable(task) - tasks[task_name] = task - - self._tasks = [] + self.tasks = tasks = [] # expose tasks def expose_task(task): def proc(): return self.proceed(task) - self._tasks.append(task) + tasks.append(task) setattr(self, task, proc) expose_task('annotate') @@ -112,21 +105,6 @@ d = {'backend': self.config.translation.backend} return d - def backend_select_goals(self, goals): - backend = self.config.translation.backend - postfixes = ['', '_' + backend] - l = [] - for goal in goals: - for postfix in postfixes: - cand = "%s%s" % (goal, postfix) - if cand in self.tasks: - new_goal = cand - break - else: - raise Exception, "cannot infer complete goal from: %r" % goal - l.append(new_goal) - return l - def setup(self, entry_point, inputtypes, policy=None, extra={}, empty_translator=None): standalone = inputtypes is None self.standalone = standalone @@ -630,21 +608,25 @@ def proceed(self, goal): assert isinstance(goal, str) - goals = [] - for task in self._tasks: - goals.append(task) + + # XXX + tasks = [] + for task in self.tasks: + if task in ('source', 'compile'): + realtask = '%s_%s' % (task, self.config.translation.backend) + else: + realtask = task + taskcallable = getattr(self, 'task_' + realtask) + tasks.append(taskcallable) if task == goal: break - goals = self.backend_select_goals(goals) - res = None - for goal in goals: - taskcallable = self.tasks[goal] + for taskcallable in tasks: if taskcallable.task_earlycheck: func.task_earlycheck(self) - for goal in goals: - taskcallable = self.tasks[goal] - res = self._do(goal, taskcallable) + res = None + for taskcallable in tasks: + res = self._do(taskcallable.task_name, taskcallable) return res def from_targetspec(targetspec_dic, config=None, args=None, diff --git a/rpython/translator/test/test_driver.py b/rpython/translator/test/test_driver.py --- a/rpython/translator/test/test_driver.py +++ b/rpython/translator/test/test_driver.py @@ -6,17 +6,17 @@ def test_c_no_jit(): td = TranslationDriver() - goals = ['annotate', 'rtype', 'backendopt', 'source', 'compile'] - assert td._tasks == goals + names = ['annotate', 'rtype', 'backendopt', 'source', 'compile'] + assert td.tasks == names def test_c_with_jit(): td = TranslationDriver({'jit': True}) - goals = ['annotate', 'rtype', 'pyjitpl', 'backendopt', 'source', 'compile'] - assert td._tasks == goals + names = ['annotate', 'rtype', 'pyjitpl', 'backendopt', 'source', 'compile'] + assert td.tasks == names def test_no_backendopt(): td = TranslationDriver({'backendopt.none': True}) - goals = ['annotate', 'rtype', 'source', 'compile'] - assert td._tasks == goals + names = ['annotate', 'rtype', 'source', 'compile'] + assert td.tasks == names From noreply at buildbot.pypy.org Mon Feb 25 22:07:26 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Mon, 25 Feb 2013 22:07:26 +0100 (CET) Subject: [pypy-commit] pypy refactor-translator: Move backend tasks in its own class (only GenC for now). Message-ID: <20130225210726.2DF8B1C0327@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: refactor-translator Changeset: r61787:3bb9eb90286d Date: 2013-02-25 20:30 +0100 http://bitbucket.org/pypy/pypy/changeset/3bb9eb90286d/ Log: Move backend tasks in its own class (only GenC for now). diff --git a/rpython/translator/driver.py b/rpython/translator/driver.py --- a/rpython/translator/driver.py +++ b/rpython/translator/driver.py @@ -27,6 +27,123 @@ return taskfunc return decorator + +class CBackend(object): + def __init__(self, driver): + self.driver = driver + + def possibly_check_for_boehm(self): + if self.config.translation.gc == "boehm": + from rpython.rtyper.tool.rffi_platform import configure_boehm + from rpython.translator.platform import CompilationError + try: + configure_boehm(self.translator.platform) + except CompilationError, e: + i = 'Boehm GC not installed. Try e.g. "translate.py --gc=hybrid"' + raise Exception(str(e) + '\n' + i) + + @taskdef("Creating database for generating c source", + earlycheck=possibly_check_for_boehm) + def task_database(self): + """ Create a database for further backend generation + """ + translator = self.driver.translator + if translator.annotator is not None: + translator.frozen = True + + if self.driver.standalone: + from rpython.translator.c.genc import CStandaloneBuilder + cbuilder = CStandaloneBuilder(translator, self.driver.entry_point, + config=self.driver.config, + secondary_entrypoints=self.driver.secondary_entrypoints) + else: + from rpython.translator.c.dlltool import CLibraryBuilder + functions = [(self.driver.entry_point, None)] + \ + self.driver.secondary_entrypoints + cbuilder = CLibraryBuilder(translator, self.driver.entry_point, + functions=functions, + name='libtesting', + config=self.driver.config) + cbuilder.modulename = self.driver.extmod_name + database = cbuilder.build_database() + self.driver.log.info("database for generating C source was created") + self.cbuilder = self.driver.cbuilder = cbuilder + self.database = database + + @taskdef("Generating c source") + def task_source(self): + """ Create C source files from the generated database + """ + cbuilder = self.cbuilder + database = self.database + debug_def = self.driver._backend_extra_options.get('c_debug_defines', False) + if self.driver.exe_name is not None: + exe_name = self.driver.exe_name % self.driver.get_info() + else: + exe_name = None + c_source_filename = cbuilder.generate_source( + database, debug_defines=debug_def, exe_name=exe_name) + self.driver.log.info("written: %s" % (c_source_filename,)) + if self.driver.config.translation.dump_static_data_info: + from rpython.translator.tool.staticsizereport import dump_static_data_info + targetdir = cbuilder.targetdir + fname = dump_static_data_info(self.driver.log, database, targetdir) + dstname = self.compute_exe_name() + '.staticdata.info' + shutil.copy(str(fname), str(dstname)) + self.driver.log.info('Static data info written to %s' % dstname) + + @taskdef("Compiling c source") + def task_compile(self): + """ Compile the generated C code using either makefile or + translator/platform + """ + cbuilder = self.cbuilder + kwds = {} + if self.driver.standalone and self.driver.exe_name is not None: + kwds['exe_name'] = self.compute_exe_name().basename + cbuilder.compile(**kwds) + + if self.driver.standalone: + self.driver.c_entryp = cbuilder.executable_name + self.create_exe() + else: + self.driver.c_entryp = cbuilder.get_entry_point() + + def create_exe(self): + """ Copy the compiled executable into translator/goal + """ + if self.driver.exe_name is not None: + exename = self.driver.c_entryp + newexename = self.compute_exe_name() + if sys.platform == 'win32': + newexename = newexename.new(ext='exe') + shutil.copy(str(exename), str(newexename)) + if self.cbuilder.shared_library_name is not None: + soname = self.cbuilder.shared_library_name + newsoname = newexename.new(basename=soname.basename) + shutil.copy(str(soname), str(newsoname)) + self.driver.log.info("copied: %s" % (newsoname,)) + if sys.platform == 'win32': + shutil.copyfile(str(soname.new(ext='lib')), + str(newsoname.new(ext='lib'))) + self.driver.c_entryp = newexename + self.driver.log.info('usession directory: %s' % (udir,)) + self.driver.log.info("created: %s" % (self.driver.c_entryp,)) + + def compute_exe_name(self): + newexename = self.exe_name % self.get_info() + if '/' not in newexename and '\\' not in newexename: + newexename = './' + newexename + return py.path.local(newexename) + + def get_tasks(self): + yield self.task_database + yield self.task_source + yield self.task_compile + +backends = {'c': CBackend} + + # TODO: # sanity-checks using states @@ -87,16 +204,16 @@ def proc(): return self.proceed(task) tasks.append(task) - setattr(self, task, proc) + setattr(self, task.task_name, proc) - expose_task('annotate') - expose_task('rtype') + expose_task(self.task_annotate) + expose_task(self.task_rtype) if config.translation.jit: - expose_task('pyjitpl') + expose_task(self.task_pyjitpl) if not config.translation.backendopt.none: - expose_task('backendopt') - expose_task('source') - expose_task('compile') + expose_task(self.task_backendopt) + for task in backends[config.translation.backend](self).get_tasks(): + expose_task(task) def set_backend_extra_options(self, extra_options): self._backend_extra_options = extra_options @@ -215,7 +332,7 @@ self.done[goal] = True if instrument: xxx - self.proceed('compile') + self.compile() assert False, 'we should not get here' finally: try: @@ -313,113 +430,6 @@ count = insert_ll_stackcheck(self.translator) self.log.info("inserted %d stack checks." % (count,)) - def possibly_check_for_boehm(self): - if self.config.translation.gc == "boehm": - from rpython.rtyper.tool.rffi_platform import configure_boehm - from rpython.translator.platform import CompilationError - try: - configure_boehm(self.translator.platform) - except CompilationError, e: - i = 'Boehm GC not installed. Try e.g. "translate.py --gc=hybrid"' - raise Exception(str(e) + '\n' + i) - - @taskdef("Creating database for generating c source", - earlycheck=possibly_check_for_boehm) - def task_database_c(self): - """ Create a database for further backend generation - """ - translator = self.translator - if translator.annotator is not None: - translator.frozen = True - - standalone = self.standalone - - if standalone: - from rpython.translator.c.genc import CStandaloneBuilder - cbuilder = CStandaloneBuilder(self.translator, self.entry_point, - config=self.config, - secondary_entrypoints=self.secondary_entrypoints) - else: - from rpython.translator.c.dlltool import CLibraryBuilder - functions = [(self.entry_point, None)] + self.secondary_entrypoints - cbuilder = CLibraryBuilder(self.translator, self.entry_point, - functions=functions, - name='libtesting', - config=self.config) - if not standalone: # xxx more messy - cbuilder.modulename = self.extmod_name - database = cbuilder.build_database() - self.log.info("database for generating C source was created") - self.cbuilder = cbuilder - self.database = database - - @taskdef("Generating c source") - def task_source_c(self): - """ Create C source files from the generated database - """ - self.task_database_c() - cbuilder = self.cbuilder - database = self.database - debug_def = self._backend_extra_options.get('c_debug_defines', False) - if self.exe_name is not None: - exe_name = self.exe_name % self.get_info() - else: - exe_name = None - c_source_filename = cbuilder.generate_source( - database, debug_defines=debug_def, exe_name=exe_name) - self.log.info("written: %s" % (c_source_filename,)) - if self.config.translation.dump_static_data_info: - from rpython.translator.tool.staticsizereport import dump_static_data_info - targetdir = cbuilder.targetdir - fname = dump_static_data_info(self.log, database, targetdir) - dstname = self.compute_exe_name() + '.staticdata.info' - shutil.copy(str(fname), str(dstname)) - self.log.info('Static data info written to %s' % dstname) - - def compute_exe_name(self): - newexename = self.exe_name % self.get_info() - if '/' not in newexename and '\\' not in newexename: - newexename = './' + newexename - return py.path.local(newexename) - - def create_exe(self): - """ Copy the compiled executable into translator/goal - """ - if self.exe_name is not None: - exename = self.c_entryp - newexename = self.compute_exe_name() - if sys.platform == 'win32': - newexename = newexename.new(ext='exe') - shutil.copy(str(exename), str(newexename)) - if self.cbuilder.shared_library_name is not None: - soname = self.cbuilder.shared_library_name - newsoname = newexename.new(basename=soname.basename) - shutil.copy(str(soname), str(newsoname)) - self.log.info("copied: %s" % (newsoname,)) - if sys.platform == 'win32': - shutil.copyfile(str(soname.new(ext='lib')), - str(newsoname.new(ext='lib'))) - self.c_entryp = newexename - self.log.info('usession directory: %s' % (udir,)) - self.log.info("created: %s" % (self.c_entryp,)) - - @taskdef("Compiling c source") - def task_compile_c(self): - """ Compile the generated C code using either makefile or - translator/platform - """ - cbuilder = self.cbuilder - kwds = {} - if self.standalone and self.exe_name is not None: - kwds['exe_name'] = self.compute_exe_name().basename - cbuilder.compile(**kwds) - - if self.standalone: - self.c_entryp = cbuilder.executable_name - self.create_exe() - else: - self.c_entryp = cbuilder.get_entry_point() - @taskdef("LLInterpreting") def task_llinterpret_lltype(self): from rpython.rtyper.llinterp import LLInterpreter @@ -607,26 +617,18 @@ pass def proceed(self, goal): - assert isinstance(goal, str) - - # XXX tasks = [] for task in self.tasks: - if task in ('source', 'compile'): - realtask = '%s_%s' % (task, self.config.translation.backend) - else: - realtask = task - taskcallable = getattr(self, 'task_' + realtask) - tasks.append(taskcallable) + tasks.append(task) if task == goal: break - for taskcallable in tasks: - if taskcallable.task_earlycheck: - func.task_earlycheck(self) + for task in tasks: + if task.task_earlycheck: + task.task_earlycheck(self) res = None - for taskcallable in tasks: - res = self._do(taskcallable.task_name, taskcallable) + for task in tasks: + res = self._do(task.task_name, task) return res def from_targetspec(targetspec_dic, config=None, args=None, diff --git a/rpython/translator/test/test_driver.py b/rpython/translator/test/test_driver.py --- a/rpython/translator/test/test_driver.py +++ b/rpython/translator/test/test_driver.py @@ -6,17 +6,19 @@ def test_c_no_jit(): td = TranslationDriver() - names = ['annotate', 'rtype', 'backendopt', 'source', 'compile'] - assert td.tasks == names + names = ['annotate', 'rtype', 'backendopt', 'database', 'source', + 'compile'] + assert [task.task_name for task in td.tasks] == names def test_c_with_jit(): td = TranslationDriver({'jit': True}) - names = ['annotate', 'rtype', 'pyjitpl', 'backendopt', 'source', 'compile'] - assert td.tasks == names + names = ['annotate', 'rtype', 'pyjitpl', 'backendopt', 'database', + 'source', 'compile'] + assert [task.task_name for task in td.tasks] == names def test_no_backendopt(): td = TranslationDriver({'backendopt.none': True}) - names = ['annotate', 'rtype', 'source', 'compile'] - assert td.tasks == names + names = ['annotate', 'rtype', 'database', 'source', 'compile'] + assert [task.task_name for task in td.tasks] == names diff --git a/rpython/translator/test/test_interactive.py b/rpython/translator/test/test_interactive.py --- a/rpython/translator/test/test_interactive.py +++ b/rpython/translator/test/test_interactive.py @@ -45,11 +45,11 @@ t = Translation(f, [int, int], backend='c') t.annotate() t.source() - assert 'source_c' in t.driver.done + assert 'source' in t.driver.done t = Translation(f, [int, int]) t.source_c() - assert 'source_c' in t.driver.done + assert 'source' in t.driver.done def test_disable_logic(): return # temporary skip From noreply at buildbot.pypy.org Mon Feb 25 22:07:27 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Mon, 25 Feb 2013 22:07:27 +0100 (CET) Subject: [pypy-commit] pypy refactor-translator: Kill all redundant task methods in Translation (eg. rtype_lltype, source_c) and the possibility to pass options to the remaining ones. Message-ID: <20130225210727.4C3E41C0327@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: refactor-translator Changeset: r61788:d4dc8f3093c8 Date: 2013-02-25 20:45 +0100 http://bitbucket.org/pypy/pypy/changeset/d4dc8f3093c8/ Log: Kill all redundant task methods in Translation (eg. rtype_lltype, source_c) and the possibility to pass options to the remaining ones. diff --git a/rpython/translator/c/test/test_genc.py b/rpython/translator/c/test/test_genc.py --- a/rpython/translator/c/test/test_genc.py +++ b/rpython/translator/c/test/test_genc.py @@ -116,7 +116,7 @@ t.view() except AttributeError: pass - t.compile_c() + t.compile() ll_res = graphof(t.context, fn).getreturnvar().concretetype def output(stdout): @@ -461,7 +461,7 @@ t = Translation(f, [], backend="c") t.annotate() - t.compile_c() + t.compile() if py.test.config.option.view: t.view() assert hasattr(ctypes.CDLL(str(t.driver.c_entryp)), 'pypy_xyz_f') @@ -477,7 +477,7 @@ t = Translation(f, [], backend="c", secondaryentrypoints="test_entrypoints42") t.annotate() - t.compile_c() + t.compile() if py.test.config.option.view: t.view() assert hasattr(ctypes.CDLL(str(t.driver.c_entryp)), 'foobar') @@ -496,7 +496,7 @@ export_struct("BarStruct", foo._obj) t = Translation(f, [], backend="c") t.annotate() - t.compile_c() + t.compile() if py.test.config.option.view: t.view() assert hasattr(ctypes.CDLL(str(t.driver.c_entryp)), 'BarStruct') @@ -562,7 +562,7 @@ t = Translation(main, [int], backend="c") t.rtype() t.context._graphof(foobar_fn).inhibit_tail_call = True - t.source_c() + t.source() lines = t.driver.cbuilder.c_source_filename.join('..', 'rpython_translator_c_test_test_genc.c').readlines() for i, line in enumerate(lines): diff --git a/rpython/translator/interactive.py b/rpython/translator/interactive.py --- a/rpython/translator/interactive.py +++ b/rpython/translator/interactive.py @@ -46,96 +46,30 @@ self.config.translation.gc = gc self.config.translation.set(**kwds) - def ensure_opt(self, name, value=None, fallback=None): - if value is not None: - self.update_options({name: value}) - return value - val = getattr(self.config.translation, name, None) - if fallback is not None and val is None: - self.update_options({name: fallback}) - return fallback - if val is not None: - return val - raise Exception( - "the %r option should have been specified at this point" % name) - - def ensure_type_system(self, type_system=None): - if self.config.translation.backend is not None: - return self.ensure_opt('type_system') - return self.ensure_opt('type_system', type_system, 'lltype') - - def ensure_backend(self, backend=None): - backend = self.ensure_opt('backend', backend) - self.ensure_type_system() - return backend - def set_backend_extra_options(self, **extra_options): for name in extra_options: backend, option = name.split('_', 1) - self.ensure_backend(backend) + assert self.config.translation.backend == backend self.driver.set_backend_extra_options(extra_options) # backend independent def annotate(self, **kwds): - self.update_options(kwds) return self.driver.annotate() # type system dependent - def rtype(self, **kwds): - self.update_options(kwds) + def rtype(self): return self.driver.rtype() - def backendopt(self, **kwds): - self.update_options(kwds) + def backendopt(self): return self.driver.backendopt() # backend depedent - def source(self, **kwds): - self.update_options(kwds) + def source(self): return self.driver.source() - def source_c(self, **kwds): - self.update_options(kwds) - self.ensure_backend('c') - self.driver.source() - - def source_cl(self, **kwds): - self.update_options(kwds) - self.ensure_backend('cl') - self.driver.source() - - def compile(self, **kwds): - self.update_options(kwds) + def compile(self): self.driver.compile() return self.driver.c_entryp - - def compile_c(self, **kwds): - self.update_options(kwds) - self.ensure_backend('c') - self.driver.compile() - return self.driver.c_entryp - - def compile_cli(self, **kwds): - self.update_options(kwds) - self.ensure_backend('cli') - self.driver.compile() - return self.driver.c_entryp - - def source_cli(self, **kwds): - self.update_options(kwds) - self.ensure_backend('cli') - self.driver.source() - - def compile_jvm(self, **kwds): - self.update_options(kwds) - self.ensure_backend('jvm') - self.driver.compile() - return self.driver.c_entryp - - def source_jvm(self, **kwds): - self.update_options(kwds) - self.ensure_backend('jvm') - self.driver.source() diff --git a/rpython/translator/test/test_interactive.py b/rpython/translator/test/test_interactive.py --- a/rpython/translator/test/test_interactive.py +++ b/rpython/translator/test/test_interactive.py @@ -48,7 +48,7 @@ assert 'source' in t.driver.done t = Translation(f, [int, int]) - t.source_c() + t.source() assert 'source' in t.driver.done def test_disable_logic(): @@ -59,7 +59,7 @@ t = Translation(f, [int, int]) t.disable(['backendopt']) - t.source_c() + t.source() assert 'backendopt' not in t.driver.done @@ -70,7 +70,7 @@ return x+y t = Translation(f, [int, int]) - t.source(backend='c') + t.source() t.compile() dll = ctypes.CDLL(str(t.driver.c_entryp)) @@ -83,32 +83,12 @@ return x+y t = Translation(f, [int, int]) - t.rtype(type_system='lltype') - - assert 'rtype' in t.driver.done - - t = Translation(f, [int, int]) - t.rtype(type_system='ootype') - assert 'rtype' in t.driver.done + t.rtype() t = Translation(f, [int, int], type_system='ootype') t.rtype() - assert 'rtype' in t.driver.done - - t = Translation(f, [int, int]) - t.rtype(backend='cli') assert 'rtype' in t.driver.done - t = Translation(f, [int, int], backend='cli', type_system='ootype') t.rtype() - assert 'rtype' in t.driver.done - - t = Translation(f, [int, int], type_system='lltype') - t.annotate() - py.test.raises(Exception, "t.rtype(backend='cli')") - - t = Translation(f, [int, int], backend='cli') - t.annotate() - py.test.raises(Exception, "t.rtype(type_system='lltype')") - + assert 'rtype' in t.driver.done From noreply at buildbot.pypy.org Mon Feb 25 22:07:28 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Mon, 25 Feb 2013 22:07:28 +0100 (CET) Subject: [pypy-commit] pypy refactor-translator: Don't mask AttributeErrors here. Message-ID: <20130225210728.632101C0327@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: refactor-translator Changeset: r61789:45b3832eecc2 Date: 2013-02-25 21:26 +0100 http://bitbucket.org/pypy/pypy/changeset/45b3832eecc2/ Log: Don't mask AttributeErrors here. diff --git a/rpython/translator/c/test/test_genc.py b/rpython/translator/c/test/test_genc.py --- a/rpython/translator/c/test/test_genc.py +++ b/rpython/translator/c/test/test_genc.py @@ -103,19 +103,13 @@ t.disable(["backendopt_lltype"]) t.driver.config.translation.countmallocs = True t.annotate() - try: - if py.test.config.option.view: - t.view() - except AttributeError: - pass + if py.test.config.option.view: + t.view() t.rtype() if backendopt: t.backendopt() - try: - if py.test.config.option.view: - t.view() - except AttributeError: - pass + if py.test.config.option.view: + t.view() t.compile() ll_res = graphof(t.context, fn).getreturnvar().concretetype From noreply at buildbot.pypy.org Mon Feb 25 22:07:29 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Mon, 25 Feb 2013 22:07:29 +0100 (CET) Subject: [pypy-commit] pypy refactor-translator: Make Translation a factory method for TranslationDriver. Message-ID: <20130225210729.856301C0327@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: refactor-translator Changeset: r61790:37d1bea138cf Date: 2013-02-25 21:27 +0100 http://bitbucket.org/pypy/pypy/changeset/37d1bea138cf/ Log: Make Translation a factory method for TranslationDriver. diff --git a/rpython/translator/interactive.py b/rpython/translator/interactive.py --- a/rpython/translator/interactive.py +++ b/rpython/translator/interactive.py @@ -1,75 +1,13 @@ -from rpython.translator.translator import TranslationContext -from rpython.translator import driver +from rpython.translator.driver import TranslationDriver -DEFAULTS = { - 'translation.verbose': True, -} - -class Translation(object): - - def __init__(self, entry_point, argtypes=None, **kwds): - self.driver = driver.TranslationDriver(overrides=DEFAULTS) - self.config = self.driver.config - - self.entry_point = entry_point - self.context = TranslationContext(config=self.config) - - policy = kwds.pop('policy', None) - self.update_options(kwds) - self.ensure_setup(argtypes, policy) - # for t.view() to work just after construction - graph = self.context.buildflowgraph(entry_point) - self.context._prebuilt_graphs[entry_point] = graph - - def view(self): - self.context.view() - - def viewcg(self): - self.context.viewcg() - - def ensure_setup(self, argtypes=None, policy=None): - standalone = argtypes is None - if standalone: - assert argtypes is None - else: - if argtypes is None: - argtypes = [] - self.driver.setup(self.entry_point, argtypes, policy, - empty_translator=self.context) - self.ann_argtypes = argtypes - self.ann_policy = policy - - def update_options(self, kwds): - gc = kwds.pop('gc', None) - if gc: - self.config.translation.gc = gc - self.config.translation.set(**kwds) - - def set_backend_extra_options(self, **extra_options): - for name in extra_options: - backend, option = name.split('_', 1) - assert self.config.translation.backend == backend - self.driver.set_backend_extra_options(extra_options) - - # backend independent - - def annotate(self, **kwds): - return self.driver.annotate() - - # type system dependent - - def rtype(self): - return self.driver.rtype() - - def backendopt(self): - return self.driver.backendopt() - - # backend depedent - - def source(self): - return self.driver.source() - - def compile(self): - self.driver.compile() - return self.driver.c_entryp +def Translation(entry_point, argtypes=None, policy=None, **kwds): + driver = TranslationDriver(overrides={'translation.verbose': True}) + driver.driver = driver + driver.config.translation.set(**kwds) + driver.setup(entry_point, argtypes, policy) + driver.context = driver.translator + # for t.view() to work just after construction + graph = driver.translator.buildflowgraph(entry_point) + driver.translator._prebuilt_graphs[entry_point] = graph + return driver diff --git a/rpython/translator/test/test_driver.py b/rpython/translator/test/test_driver.py --- a/rpython/translator/test/test_driver.py +++ b/rpython/translator/test/test_driver.py @@ -1,7 +1,5 @@ -import py - from rpython.translator.driver import TranslationDriver -import optparse +from rpython.translator.interactive import Translation def test_c_no_jit(): @@ -22,3 +20,96 @@ td = TranslationDriver({'backendopt.none': True}) names = ['annotate', 'rtype', 'database', 'source', 'compile'] assert [task.task_name for task in td.tasks] == names + + +def test_simple_annotate(): + + def f(x,y): + return x+y + + t = Translation(f, [int, int]) + assert t.context is t.driver.translator + assert t.config is t.driver.config is t.context.config + + s = t.annotate() + assert s.knowntype == int + + t = Translation(f, [int, int]) + s = t.annotate() + assert s.knowntype == int + + +def test_simple_rtype(): + + def f(x,y): + return x+y + + t = Translation(f, [int, int]) + t.annotate() + t.rtype() + + assert 'rtype' in t.driver.done + +def test_simple_backendopt(): + def f(x, y): + return x,y + + t = Translation(f, [int, int], backend='c') + t.backendopt() + + assert 'backendopt' in t.driver.done + +def test_simple_source(): + def f(x, y): + return x,y + + t = Translation(f, [int, int], backend='c') + t.annotate() + t.source() + assert 'source' in t.driver.done + + t = Translation(f, [int, int]) + t.source() + assert 'source' in t.driver.done + +def test_disable_logic(): + return # temporary skip + + def f(x,y): + return x+y + + t = Translation(f, [int, int]) + t.disable(['backendopt']) + t.source() + + assert 'backendopt' not in t.driver.done + +def test_simple_compile_c(): + import ctypes + + def f(x,y): + return x+y + + t = Translation(f, [int, int]) + t.source() + t.compile() + + dll = ctypes.CDLL(str(t.driver.c_entryp)) + f = dll.pypy_g_f + assert f(2, 3) == 5 + +def test_simple_rtype_with_type_system(): + + def f(x,y): + return x+y + + t = Translation(f, [int, int]) + t.rtype() + + t = Translation(f, [int, int], type_system='ootype') + t.rtype() + assert 'rtype' in t.driver.done + + t = Translation(f, [int, int], backend='cli', type_system='ootype') + t.rtype() + assert 'rtype' in t.driver.done diff --git a/rpython/translator/test/test_interactive.py b/rpython/translator/test/test_interactive.py deleted file mode 100644 --- a/rpython/translator/test/test_interactive.py +++ /dev/null @@ -1,94 +0,0 @@ -from rpython.translator.interactive import Translation -import py - -def test_simple_annotate(): - - def f(x,y): - return x+y - - t = Translation(f, [int, int]) - assert t.context is t.driver.translator - assert t.config is t.driver.config is t.context.config - - s = t.annotate() - assert s.knowntype == int - - t = Translation(f, [int, int]) - s = t.annotate() - assert s.knowntype == int - - -def test_simple_rtype(): - - def f(x,y): - return x+y - - t = Translation(f, [int, int]) - t.annotate() - t.rtype() - - assert 'rtype' in t.driver.done - -def test_simple_backendopt(): - def f(x, y): - return x,y - - t = Translation(f, [int, int], backend='c') - t.backendopt() - - assert 'backendopt' in t.driver.done - -def test_simple_source(): - def f(x, y): - return x,y - - t = Translation(f, [int, int], backend='c') - t.annotate() - t.source() - assert 'source' in t.driver.done - - t = Translation(f, [int, int]) - t.source() - assert 'source' in t.driver.done - -def test_disable_logic(): - return # temporary skip - - def f(x,y): - return x+y - - t = Translation(f, [int, int]) - t.disable(['backendopt']) - t.source() - - assert 'backendopt' not in t.driver.done - -def test_simple_compile_c(): - import ctypes - - def f(x,y): - return x+y - - t = Translation(f, [int, int]) - t.source() - t.compile() - - dll = ctypes.CDLL(str(t.driver.c_entryp)) - f = dll.pypy_g_f - assert f(2, 3) == 5 - -def test_simple_rtype_with_type_system(): - - def f(x,y): - return x+y - - t = Translation(f, [int, int]) - t.rtype() - - t = Translation(f, [int, int], type_system='ootype') - t.rtype() - assert 'rtype' in t.driver.done - - t = Translation(f, [int, int], backend='cli', type_system='ootype') - t.rtype() - assert 'rtype' in t.driver.done From noreply at buildbot.pypy.org Mon Feb 25 22:07:30 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Mon, 25 Feb 2013 22:07:30 +0100 (CET) Subject: [pypy-commit] pypy refactor-translator: Remove pypy/goal/multibuild.py. It's undocumented and not working. Message-ID: <20130225210730.AFFE21C0327@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: refactor-translator Changeset: r61791:1f028e3f1806 Date: 2013-02-25 21:46 +0100 http://bitbucket.org/pypy/pypy/changeset/1f028e3f1806/ Log: Remove pypy/goal/multibuild.py. It's undocumented and not working. diff --git a/pypy/goal/multibuild.py b/pypy/goal/multibuild.py deleted file mode 100644 --- a/pypy/goal/multibuild.py +++ /dev/null @@ -1,127 +0,0 @@ -from pypy.config.pypyoption import get_pypy_config -from rpython.translator.goal import translate -from rpython.translator.goal import targetpypystandalone -from rpython.translator.driver import TranslationDriver -import os, sys, traceback, random - -def longoptfromname(config, name): - from pypy.config.makerestdoc import get_cmdline - # begin horror - h, n = config._cfgimpl_get_home_by_path(name) - opt = getattr(h._cfgimpl_descr, n) - # end horror - cmdline = get_cmdline(opt.cmdline, name) - assert cmdline is not None - shortest_long_option = 'X'*1000 - for cmd in cmdline.split(): - if cmd.startswith('--') and len(cmd) < len(shortest_long_option): - shortest_long_option = cmd - return shortest_long_option - -def exe_name_from_options(config, opts): - from pypy.module.sys.version import svn_revision - - backend = config.translation.backend - if not backend: - backend = 'c' - rev = svn_revision() - - nameparts = [] - - for opt, v in opts.iteritems(): - if opt == 'translation.backend': - backend = v - optname = longoptfromname(config, opt).strip('-') - if v is False: - optname = 'no-' + optname - elif v is not True: - optname += '=' + str(v) - nameparts.append(optname) - - suffix = '' - if nameparts: - def k(s): - if s.startswith('no-'): - return s[3:] - else: - return s - nameparts.sort(key=k) - suffix = '-' + '-'.join(nameparts) - - return 'pypy-%s-%d%s'%(backend, rev, suffix) - -def _build(config, exe_name): - driver = TranslationDriver.from_targetspec( - targetpypystandalone.__dict__, - config=config) - driver.exe_name = exe_name - driver.compile() - -def build_pypy_with_options(basedir, opts): - config = get_pypy_config(translate.OVERRIDES, translating=True) - - try: - config.set(**opts) - except: - return exe_name_from_options(config, opts), "didn't configure" - - exe_name = os.path.join(basedir, exe_name_from_options(config, opts)) - - print exe_name, - sys.stdout.flush() - - pid = os.fork() - - if pid == 0: - logfile = open(exe_name + '-log', 'w') - davenull = os.open('/dev/null', os.O_RDONLY) - os.dup2(davenull, 0) - os.dup2(logfile.fileno(), 1) - os.dup2(logfile.fileno(), 2) - try: - try: - r = _build(config, exe_name) - finally: - logfile.close() - except: - os._exit(1) - else: - os._exit(0) - else: - pid, status = os.waitpid(pid, 0) - if status: - r = 'failed' - else: - r = 'succeeded' - print r - return exe_name, r - -def get_options(fname): - def gen_opts(sofar, remaining): - if not remaining: - yield sofar - else: - for (k, v) in remaining[0]: - d2 = sofar.copy() - d2[k] = v - for d in gen_opts(d2, remaining[1:]): - yield d - options = [] - for line in open(fname): - l = [] - optname, options_ = line.split(':') - options.append([(optname.strip(), eval(optval.strip())) for optval in options_.split(',')]) - return gen_opts({}, options) - - -if __name__ == '__main__': - basedir = sys.argv[1] - optionsfile = sys.argv[2] - results = [] - options = list(get_options(optionsfile)) - random.shuffle(options) - for opts in options: - results.append(build_pypy_with_options(basedir, opts)) - out = open(os.path.join(basedir, 'results'), 'w') - for exe, r in results: - print >>out, exe, r From noreply at buildbot.pypy.org Mon Feb 25 22:15:52 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Mon, 25 Feb 2013 22:15:52 +0100 (CET) Subject: [pypy-commit] pypy refactor-translator: Inline TranslationDriver.from_targetspec(). Message-ID: <20130225211552.6F3EB1C0EEA@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: refactor-translator Changeset: r61792:c250ab7f7cea Date: 2013-02-25 22:15 +0100 http://bitbucket.org/pypy/pypy/changeset/c250ab7f7cea/ Log: Inline TranslationDriver.from_targetspec(). diff --git a/rpython/translator/driver.py b/rpython/translator/driver.py --- a/rpython/translator/driver.py +++ b/rpython/translator/driver.py @@ -88,7 +88,7 @@ from rpython.translator.tool.staticsizereport import dump_static_data_info targetdir = cbuilder.targetdir fname = dump_static_data_info(self.driver.log, database, targetdir) - dstname = self.compute_exe_name() + '.staticdata.info' + dstname = self.driver.compute_exe_name() + '.staticdata.info' shutil.copy(str(fname), str(dstname)) self.driver.log.info('Static data info written to %s' % dstname) @@ -100,7 +100,7 @@ cbuilder = self.cbuilder kwds = {} if self.driver.standalone and self.driver.exe_name is not None: - kwds['exe_name'] = self.compute_exe_name().basename + kwds['exe_name'] = self.driver.compute_exe_name().basename cbuilder.compile(**kwds) if self.driver.standalone: @@ -114,7 +114,7 @@ """ if self.driver.exe_name is not None: exename = self.driver.c_entryp - newexename = self.compute_exe_name() + newexename = self.driver.compute_exe_name() if sys.platform == 'win32': newexename = newexename.new(ext='exe') shutil.copy(str(exename), str(newexename)) @@ -130,12 +130,6 @@ self.driver.log.info('usession directory: %s' % (udir,)) self.driver.log.info("created: %s" % (self.driver.c_entryp,)) - def compute_exe_name(self): - newexename = self.exe_name % self.get_info() - if '/' not in newexename and '\\' not in newexename: - newexename = './' + newexename - return py.path.local(newexename) - def get_tasks(self): yield self.task_database yield self.task_source @@ -445,6 +439,12 @@ log.llinterpret.event("result -> %s" % v) + def compute_exe_name(self): + newexename = self.exe_name % self.get_info() + if '/' not in newexename and '\\' not in newexename: + newexename = './' + newexename + return py.path.local(newexename) + @taskdef('Generating CLI source') def task_source_cli(self): from rpython.translator.cli.gencli import GenCli @@ -631,36 +631,6 @@ res = self._do(task.task_name, task) return res - def from_targetspec(targetspec_dic, config=None, args=None, - empty_translator=None): - if args is None: - args = [] - - driver = TranslationDriver(config=config) - # patch some attributes of the os module to make sure they - # have the same value on every platform. - if backend in ('cli', 'jvm'): - from rpython.translator.oosupport.support import patch_os - driver.old_cli_defs = patch_os() - - target = targetspec_dic['target'] - spec = target(driver, args) - - try: - entry_point, inputtypes, policy = spec - except ValueError: - entry_point, inputtypes = spec - policy = None - - driver.setup(entry_point, inputtypes, - policy=policy, - extra=targetspec_dic, - empty_translator=empty_translator) - - return driver - - from_targetspec = staticmethod(from_targetspec) - def prereq_checkpt_rtype(self): assert 'rpython.rtyper.rmodel' not in sys.modules, ( "cannot fork because the rtyper has already been imported") diff --git a/rpython/translator/goal/translate.py b/rpython/translator/goal/translate.py --- a/rpython/translator/goal/translate.py +++ b/rpython/translator/goal/translate.py @@ -277,10 +277,29 @@ pdb_plus_show.start(tb) try: - drv = driver.TranslationDriver.from_targetspec(targetspec_dic, config, args, - empty_translator=t, - disable=translateconfig.skipped_goals, - default_goal='compile') + if args is None: + args = [] + drv = driver.TranslationDriver(config=config) + # patch some attributes of the os module to make sure they + # have the same value on every platform. + if config.translation.backend in ('cli', 'jvm'): + from rpython.translator.oosupport.support import patch_os + drv.old_cli_defs = patch_os() + + target = targetspec_dic['target'] + spec = target(drv, args) + + try: + entry_point, inputtypes, policy = spec + except ValueError: + entry_point, inputtypes = spec + policy = None + + drv.setup(entry_point, inputtypes, + policy=policy, + extra=targetspec_dic, + empty_translator=t) + log_config(translateconfig, "translate.py configuration") if config.translation.jit: if 'jitpolicy' not in targetspec_dic: From noreply at buildbot.pypy.org Mon Feb 25 22:18:24 2013 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 25 Feb 2013 22:18:24 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: Kill an unused field definition Message-ID: <20130225211824.69DA11C0EEA@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: jitframe-on-heap Changeset: r61793:b172e3276b02 Date: 2013-02-25 22:10 +0100 http://bitbucket.org/pypy/pypy/changeset/b172e3276b02/ Log: Kill an unused field definition diff --git a/rpython/memory/gctransform/asmgcroot.py b/rpython/memory/gctransform/asmgcroot.py --- a/rpython/memory/gctransform/asmgcroot.py +++ b/rpython/memory/gctransform/asmgcroot.py @@ -560,7 +560,6 @@ self.jit_index = -1 def setjitframe(self, extra_stack_depth): - self.addr = llmemory.NULL self.jit_index = 0 self.extra_stack_depth = extra_stack_depth From noreply at buildbot.pypy.org Mon Feb 25 22:18:25 2013 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 25 Feb 2013 22:18:25 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: Fix for the case where nursery_cleanup is not an exact divisor of Message-ID: <20130225211825.BE0D41C0EEA@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: jitframe-on-heap Changeset: r61794:fd42d03450f8 Date: 2013-02-25 22:17 +0100 http://bitbucket.org/pypy/pypy/changeset/fd42d03450f8/ Log: Fix for the case where nursery_cleanup is not an exact divisor of nursery_size. diff --git a/rpython/memory/gc/minimark.py b/rpython/memory/gc/minimark.py --- a/rpython/memory/gc/minimark.py +++ b/rpython/memory/gc/minimark.py @@ -223,7 +223,7 @@ def __init__(self, config, read_from_env=False, nursery_size=32*WORD, - nursery_cleanup=8*WORD, + nursery_cleanup=9*WORD, page_size=16*WORD, arena_size=64*WORD, small_request_threshold=5*WORD, @@ -356,11 +356,9 @@ self.debug_tiny_nursery = newsize & ~(WORD-1) newsize = minsize - nursery_cleanup = env.read_from_env('PYPY_GC_NURSERY_CLEANUP') - if nursery_cleanup > 0: - if nursery_cleanup < self.nonlarge_max + 1: - nursery_cleanup = self.nonlarge_max + 1 - self.nursery_cleanup = nursery_cleanup + nurs_cleanup = env.read_from_env('PYPY_GC_NURSERY_CLEANUP') + if nurs_cleanup > 0: + self.nursery_cleanup = nurs_cleanup # major_coll = env.read_float_from_env('PYPY_GC_MAJOR_COLLECT') if major_coll > 1.0: @@ -391,7 +389,16 @@ llarena.arena_free(self.nursery) self.nursery_size = newsize self.allocate_nursery() - + # + if self.nursery_cleanup < self.nonlarge_max + 1: + self.nursery_cleanup = self.nonlarge_max + 1 + # We need exactly initial_cleanup + N*nursery_cleanup = nursery_size. + # We choose the value of initial_cleanup to be between 1x and 2x the + # value of nursery_cleanup. + self.initial_cleanup = self.nursery_cleanup + ( + self.nursery_size % self.nursery_cleanup) + if self.initial_cleanup > self.nursery_size: + self.initial_cleanup = self.nursery_size def _nursery_memory_size(self): extra = self.nonlarge_max + 1 @@ -413,9 +420,9 @@ self.nursery = self._alloc_nursery() # the current position in the nursery: self.nursery_free = self.nursery - self.nursery_top = self.nursery + self.nursery_cleanup # the end of the nursery: - self.nursery_real_top = self.nursery + self.nursery_size + self.nursery_top = self.nursery + self.nursery_size + self.nursery_real_top = self.nursery_top # initialize the threshold self.min_heap_size = max(self.min_heap_size, self.nursery_size * self.major_collection_threshold) @@ -427,6 +434,7 @@ self.next_major_collection_threshold = self.min_heap_size self.set_major_threshold_from(0.0) ll_assert(self.extra_threshold == 0, "extra_threshold set too early") + self.initial_cleanup = self.nursery_size debug_stop("gc-set-nursery-size") @@ -479,7 +487,7 @@ newnurs = self.debug_rotating_nurseries.pop(0) llarena.arena_protect(newnurs, self._nursery_memory_size(), False) self.nursery = newnurs - self.nursery_top = self.nursery + self.nursery_cleanup + self.nursery_top = self.nursery + self.initial_cleanup self.nursery_real_top = self.nursery + self.nursery_size debug_print("switching from nursery", oldnurs, "to nursery", self.nursery, @@ -602,10 +610,14 @@ self.major_collection() def move_nursery_top(self, totalsize): - size = min(self.nursery_real_top - self.nursery_top, - self.nursery_cleanup) + size = self.nursery_cleanup + ll_assert(self.nursery_real_top - self.nursery_top >= size, + "nursery_cleanup not a divisor of nursery_size - initial_cleanup") + ll_assert(llmemory.raw_malloc_usage(totalsize) <= size, + "totalsize > nursery_cleanup") llarena.arena_reset(self.nursery_top, size, 2) self.nursery_top += size + move_nursery_top._always_inline_ = True def collect_and_reserve(self, prev_result, totalsize): """To call when nursery_free overflows nursery_top. @@ -1300,10 +1312,10 @@ # All live nursery objects are out, and the rest dies. Fill # the nursery up to the cleanup point with zeros llarena.arena_reset(self.nursery, self.nursery_size, 0) - llarena.arena_reset(self.nursery, self.nursery_cleanup, 2) + llarena.arena_reset(self.nursery, self.initial_cleanup, 2) self.debug_rotate_nursery() self.nursery_free = self.nursery - self.nursery_top = self.nursery + self.nursery_cleanup + self.nursery_top = self.nursery + self.initial_cleanup self.nursery_real_top = self.nursery + self.nursery_size # debug_print("minor collect, total memory used:", From noreply at buildbot.pypy.org Mon Feb 25 22:18:56 2013 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 25 Feb 2013 22:18:56 +0100 (CET) Subject: [pypy-commit] pypy default: Kill old script of unclear purpose, never used Message-ID: <20130225211856.6DD1A1C0EEA@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r61795:06eb8c33df06 Date: 2013-02-25 22:05 +0100 http://bitbucket.org/pypy/pypy/changeset/06eb8c33df06/ Log: Kill old script of unclear purpose, never used diff --git a/pypy/goal/multibuild.py b/pypy/goal/multibuild.py deleted file mode 100644 --- a/pypy/goal/multibuild.py +++ /dev/null @@ -1,127 +0,0 @@ -from pypy.config.pypyoption import get_pypy_config -from rpython.translator.goal import translate -from rpython.translator.goal import targetpypystandalone -from rpython.translator.driver import TranslationDriver -import os, sys, traceback, random - -def longoptfromname(config, name): - from pypy.config.makerestdoc import get_cmdline - # begin horror - h, n = config._cfgimpl_get_home_by_path(name) - opt = getattr(h._cfgimpl_descr, n) - # end horror - cmdline = get_cmdline(opt.cmdline, name) - assert cmdline is not None - shortest_long_option = 'X'*1000 - for cmd in cmdline.split(): - if cmd.startswith('--') and len(cmd) < len(shortest_long_option): - shortest_long_option = cmd - return shortest_long_option - -def exe_name_from_options(config, opts): - from pypy.module.sys.version import svn_revision - - backend = config.translation.backend - if not backend: - backend = 'c' - rev = svn_revision() - - nameparts = [] - - for opt, v in opts.iteritems(): - if opt == 'translation.backend': - backend = v - optname = longoptfromname(config, opt).strip('-') - if v is False: - optname = 'no-' + optname - elif v is not True: - optname += '=' + str(v) - nameparts.append(optname) - - suffix = '' - if nameparts: - def k(s): - if s.startswith('no-'): - return s[3:] - else: - return s - nameparts.sort(key=k) - suffix = '-' + '-'.join(nameparts) - - return 'pypy-%s-%d%s'%(backend, rev, suffix) - -def _build(config, exe_name): - driver = TranslationDriver.from_targetspec( - targetpypystandalone.__dict__, - config=config) - driver.exe_name = exe_name - driver.compile() - -def build_pypy_with_options(basedir, opts): - config = get_pypy_config(translate.OVERRIDES, translating=True) - - try: - config.set(**opts) - except: - return exe_name_from_options(config, opts), "didn't configure" - - exe_name = os.path.join(basedir, exe_name_from_options(config, opts)) - - print exe_name, - sys.stdout.flush() - - pid = os.fork() - - if pid == 0: - logfile = open(exe_name + '-log', 'w') - davenull = os.open('/dev/null', os.O_RDONLY) - os.dup2(davenull, 0) - os.dup2(logfile.fileno(), 1) - os.dup2(logfile.fileno(), 2) - try: - try: - r = _build(config, exe_name) - finally: - logfile.close() - except: - os._exit(1) - else: - os._exit(0) - else: - pid, status = os.waitpid(pid, 0) - if status: - r = 'failed' - else: - r = 'succeeded' - print r - return exe_name, r - -def get_options(fname): - def gen_opts(sofar, remaining): - if not remaining: - yield sofar - else: - for (k, v) in remaining[0]: - d2 = sofar.copy() - d2[k] = v - for d in gen_opts(d2, remaining[1:]): - yield d - options = [] - for line in open(fname): - l = [] - optname, options_ = line.split(':') - options.append([(optname.strip(), eval(optval.strip())) for optval in options_.split(',')]) - return gen_opts({}, options) - - -if __name__ == '__main__': - basedir = sys.argv[1] - optionsfile = sys.argv[2] - results = [] - options = list(get_options(optionsfile)) - random.shuffle(options) - for opts in options: - results.append(build_pypy_with_options(basedir, opts)) - out = open(os.path.join(basedir, 'results'), 'w') - for exe, r in results: - print >>out, exe, r From noreply at buildbot.pypy.org Mon Feb 25 22:18:58 2013 From: noreply at buildbot.pypy.org (arigo) Date: Mon, 25 Feb 2013 22:18:58 +0100 (CET) Subject: [pypy-commit] pypy default: merge heads Message-ID: <20130225211858.5FAD01C0EEA@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r61796:c2d0d65fbaa9 Date: 2013-02-25 22:18 +0100 http://bitbucket.org/pypy/pypy/changeset/c2d0d65fbaa9/ Log: merge heads diff too long, truncating to 2000 out of 4023 lines diff --git a/.hgignore b/.hgignore --- a/.hgignore +++ b/.hgignore @@ -35,39 +35,43 @@ ^pypy/doc/config/.+\.rst$ ^pypy/doc/basicblock\.asc$ ^pypy/doc/.+\.svninfo$ -^pypy/translator/c/src/libffi_msvc/.+\.obj$ -^pypy/translator/c/src/libffi_msvc/.+\.dll$ -^pypy/translator/c/src/libffi_msvc/.+\.lib$ -^pypy/translator/c/src/libffi_msvc/.+\.exp$ -^pypy/translator/c/src/cjkcodecs/.+\.o$ -^pypy/translator/c/src/cjkcodecs/.+\.obj$ -^pypy/translator/jvm/\.project$ -^pypy/translator/jvm/\.classpath$ -^pypy/translator/jvm/eclipse-bin$ -^pypy/translator/jvm/src/pypy/.+\.class$ -^pypy/translator/benchmark/docutils$ -^pypy/translator/benchmark/templess$ -^pypy/translator/benchmark/gadfly$ -^pypy/translator/benchmark/mako$ -^pypy/translator/benchmark/bench-custom\.benchmark_result$ -^pypy/translator/benchmark/shootout_benchmarks$ -^pypy/translator/goal/pypy-translation-snapshot$ -^pypy/translator/goal/pypy-c -^pypy/translator/goal/pypy-jvm -^pypy/translator/goal/pypy-jvm.jar -^pypy/translator/goal/.+\.exe$ -^pypy/translator/goal/.+\.dll$ -^pypy/translator/goal/target.+-c$ +^rpython/translator/c/src/libffi_msvc/.+\.obj$ +^rpython/translator/c/src/libffi_msvc/.+\.dll$ +^rpython/translator/c/src/libffi_msvc/.+\.lib$ +^rpython/translator/c/src/libffi_msvc/.+\.exp$ +^rpython/translator/c/src/cjkcodecs/.+\.o$ +^rpython/translator/c/src/cjkcodecs/.+\.obj$ +^rpython/translator/c/src/stacklet/.+\.o$ +^rpython/translator/c/src/.+\.o$ +^rpython/translator/jvm/\.project$ +^rpython/translator/jvm/\.classpath$ +^rpython/translator/jvm/eclipse-bin$ +^rpython/translator/jvm/src/pypy/.+\.class$ +^rpython/translator/benchmark/docutils$ +^rpython/translator/benchmark/templess$ +^rpython/translator/benchmark/gadfly$ +^rpython/translator/benchmark/mako$ +^rpython/translator/benchmark/bench-custom\.benchmark_result$ +^rpython/translator/benchmark/shootout_benchmarks$ +^rpython/translator/goal/target.+-c$ +^rpython/translator/goal/.+\.exe$ +^rpython/translator/goal/.+\.dll$ +^pypy/goal/pypy-translation-snapshot$ +^pypy/goal/pypy-c +^pypy/goal/pypy-jvm +^pypy/goal/pypy-jvm.jar +^pypy/goal/.+\.exe$ +^pypy/goal/.+\.dll$ ^pypy/_cache$ ^pypy/doc/statistic/.+\.html$ ^pypy/doc/statistic/.+\.eps$ ^pypy/doc/statistic/.+\.pdf$ -^pypy/translator/cli/src/pypylib\.dll$ -^pypy/translator/cli/src/query\.exe$ -^pypy/translator/cli/src/main\.exe$ +^rpython/translator/cli/src/pypylib\.dll$ +^rpython/translator/cli/src/query\.exe$ +^rpython/translator/cli/src/main\.exe$ ^lib_pypy/ctypes_config_cache/_.+_cache\.py$ ^lib_pypy/ctypes_config_cache/_.+_.+_\.py$ -^pypy/translator/cli/query-descriptions$ +^rpython/translator/cli/query-descriptions$ ^pypy/doc/discussion/.+\.html$ ^include/.+\.h$ ^include/.+\.inl$ diff --git a/lib_pypy/numpypy/core/__init__.py b/lib_pypy/numpypy/core/__init__.py --- a/lib_pypy/numpypy/core/__init__.py +++ b/lib_pypy/numpypy/core/__init__.py @@ -1,18 +1,14 @@ -import _numpypy -from _numpypy import * import numeric from numeric import * import fromnumeric from fromnumeric import * import shape_base from shape_base import * -import multiarray from fromnumeric import amax as max, amin as min -from _numpypy import absolute as abs +from numeric import absolute as abs __all__ = [] -__all__ += _numpypy.__all__ __all__ += numeric.__all__ __all__ += fromnumeric.__all__ __all__ += shape_base.__all__ diff --git a/lib_pypy/numpypy/core/_methods.py b/lib_pypy/numpypy/core/_methods.py --- a/lib_pypy/numpypy/core/_methods.py +++ b/lib_pypy/numpypy/core/_methods.py @@ -1,11 +1,9 @@ # Array methods which are called by the both the C-code for the method # and the Python code for the NumPy-namespace function -#from numpy.core import multiarray as mu -#from numpy.core import umath as um -import _numpypy as mu -um = mu -from numpy.core.numeric import asanyarray +import multiarray as mu +import umath as um +from numeric import asanyarray def _amax(a, axis=None, out=None, keepdims=False): return um.maximum.reduce(a, axis=axis, diff --git a/lib_pypy/numpypy/core/arrayprint.py b/lib_pypy/numpypy/core/arrayprint.py --- a/lib_pypy/numpypy/core/arrayprint.py +++ b/lib_pypy/numpypy/core/arrayprint.py @@ -13,9 +13,9 @@ # and by Travis Oliphant 2005-8-22 for numpy import sys -import _numpypy as _nt -from _numpypy import maximum, minimum, absolute, not_equal, isnan, isinf -#from _numpypy import format_longfloat, datetime_as_string, datetime_data +import numerictypes as _nt +from umath import maximum, minimum, absolute, not_equal, isnan, isinf +#from multiarray import format_longfloat, datetime_as_string, datetime_data from fromnumeric import ravel diff --git a/lib_pypy/numpypy/core/fromnumeric.py b/lib_pypy/numpypy/core/fromnumeric.py --- a/lib_pypy/numpypy/core/fromnumeric.py +++ b/lib_pypy/numpypy/core/fromnumeric.py @@ -16,6 +16,7 @@ ###################################################################### import numpypy +import _numpypy # Module containing non-deprecated functions borrowed from Numeric. __docformat__ = "restructuredtext en" @@ -274,7 +275,7 @@ [-1, -2, -3, -4, -5]]]) """ - raise NotImplementedError('Waiting on interp level method') + return _numpypy.choose(a, choices, out, mode) def repeat(a, repeats, axis=None): @@ -316,7 +317,7 @@ [3, 4]]) """ - raise NotImplementedError('Waiting on interp level method') + return _numpypy.repeat(a, repeats, axis) def put(a, ind, v, mode='raise'): diff --git a/lib_pypy/numpypy/core/multiarray.py b/lib_pypy/numpypy/core/multiarray.py --- a/lib_pypy/numpypy/core/multiarray.py +++ b/lib_pypy/numpypy/core/multiarray.py @@ -1,1 +1,1 @@ -from _numpypy import set_string_function, typeinfo +from _numpypy.multiarray import * diff --git a/lib_pypy/numpypy/core/numeric.py b/lib_pypy/numpypy/core/numeric.py --- a/lib_pypy/numpypy/core/numeric.py +++ b/lib_pypy/numpypy/core/numeric.py @@ -1,16 +1,40 @@ -__all__ = ['asanyarray', 'base_repr', +__all__ = [ + 'newaxis', 'ufunc', + 'asarray', 'asanyarray', 'base_repr', 'array_repr', 'array_str', 'set_string_function', - 'array_equal', 'asarray', 'outer', 'identity'] + 'array_equal', 'outer', 'identity', 'little_endian', + 'Inf', 'inf', 'infty', 'Infinity', 'nan', 'NaN', 'False_', 'True_', + ] -from _numpypy import array, ndarray, int_, float_, bool_, flexible #, complex_# , longlong -from _numpypy import concatenate -from .fromnumeric import any -import math import sys import multiarray -from numpypy.core.arrayprint import array2string +from multiarray import * +del set_string_function +del typeinfo +import umath +from umath import * +import numerictypes +from numerictypes import * + +def extend_all(module): + adict = {} + for a in __all__: + adict[a] = 1 + try: + mall = getattr(module, '__all__') + except AttributeError: + mall = [k for k in module.__dict__.keys() if not k.startswith('_')] + for a in mall: + if a not in adict: + __all__.append(a) + +extend_all(multiarray) +__all__.remove('typeinfo') +extend_all(umath) +extend_all(numerictypes) newaxis = None +ufunc = type(sin) # XXX this file to be reviewed def seterr(**args): @@ -121,6 +145,10 @@ res.append('-') return ''.join(reversed(res or '0')) + +#Use numarray's printing function +from arrayprint import array2string + _typelessdata = [int_, float_]#, complex_] # XXX #if issubclass(intc, int): @@ -306,6 +334,11 @@ else: return multiarray.set_string_function(f, repr) +set_string_function(array_str, 0) +set_string_function(array_repr, 1) + +little_endian = (sys.byteorder == 'little') + def array_equal(a1, a2): """ True if two arrays have the same shape and elements, False otherwise. @@ -417,21 +450,6 @@ """ return array(a, dtype, copy=False, order=order) -set_string_function(array_str, 0) -set_string_function(array_repr, 1) - -little_endian = (sys.byteorder == 'little') - -Inf = inf = infty = Infinity = PINF = float('inf') -NINF = float('-inf') -PZERO = 0.0 -NZERO = -0.0 -nan = NaN = NAN = float('nan') -False_ = bool_(False) -True_ = bool_(True) -e = math.e -pi = math.pi - def outer(a,b): """ Compute the outer product of two vectors. @@ -535,3 +553,12 @@ """ from numpy import eye return eye(n, dtype=dtype) + +Inf = inf = infty = Infinity = PINF +nan = NaN = NAN +False_ = bool_(False) +True_ = bool_(True) + +import fromnumeric +from fromnumeric import * +extend_all(fromnumeric) diff --git a/lib_pypy/numpypy/core/numerictypes.py b/lib_pypy/numpypy/core/numerictypes.py new file mode 100644 --- /dev/null +++ b/lib_pypy/numpypy/core/numerictypes.py @@ -0,0 +1,1 @@ +from _numpypy.numerictypes import * diff --git a/lib_pypy/numpypy/core/shape_base.py b/lib_pypy/numpypy/core/shape_base.py --- a/lib_pypy/numpypy/core/shape_base.py +++ b/lib_pypy/numpypy/core/shape_base.py @@ -1,6 +1,6 @@ __all__ = ['atleast_1d', 'atleast_2d', 'atleast_3d', 'vstack', 'hstack'] -import _numpypy +import numeric as _nx from numeric import array, asanyarray, newaxis def atleast_1d(*arys): @@ -223,7 +223,7 @@ [4]]) """ - return _numpypy.concatenate(map(atleast_2d,tup),0) + return _nx.concatenate(map(atleast_2d,tup),0) def hstack(tup): """ @@ -270,6 +270,6 @@ arrs = map(atleast_1d,tup) # As a special case, dimension 0 of 1-dimensional arrays is "horizontal" if arrs[0].ndim == 1: - return _numpypy.concatenate(arrs, 0) + return _nx.concatenate(arrs, 0) else: - return _numpypy.concatenate(arrs, 1) + return _nx.concatenate(arrs, 1) diff --git a/lib_pypy/numpypy/core/umath.py b/lib_pypy/numpypy/core/umath.py new file mode 100644 --- /dev/null +++ b/lib_pypy/numpypy/core/umath.py @@ -0,0 +1,12 @@ +from _numpypy.umath import * + +import math +e = math.e +pi = math.pi +del math + +PZERO = 0.0 +NZERO = -0.0 +PINF = float('inf') +NINF = float('-inf') +NAN = float('nan') diff --git a/lib_pypy/numpypy/lib/function_base.py b/lib_pypy/numpypy/lib/function_base.py --- a/lib_pypy/numpypy/lib/function_base.py +++ b/lib_pypy/numpypy/lib/function_base.py @@ -1,6 +1,6 @@ __all__ = ['average'] -from _numpypy import array +from ..core.numeric import array def average(a): # This implements a weighted average, for now we don't implement the diff --git a/lib_pypy/numpypy/lib/shape_base.py b/lib_pypy/numpypy/lib/shape_base.py --- a/lib_pypy/numpypy/lib/shape_base.py +++ b/lib_pypy/numpypy/lib/shape_base.py @@ -1,7 +1,7 @@ __all__ = ['dstack'] -import numpypy.core.numeric as _nx -from numpypy.core import atleast_3d +from ..core import numeric as _nx +from ..core import atleast_3d def dstack(tup): """ diff --git a/lib_pypy/numpypy/lib/twodim_base.py b/lib_pypy/numpypy/lib/twodim_base.py --- a/lib_pypy/numpypy/lib/twodim_base.py +++ b/lib_pypy/numpypy/lib/twodim_base.py @@ -1,6 +1,6 @@ __all__ = ['eye'] -from _numpypy import zeros +from ..core.numeric import zeros def eye(N, M=None, k=0, dtype=float): """ diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst --- a/pypy/doc/whatsnew-head.rst +++ b/pypy/doc/whatsnew-head.rst @@ -75,3 +75,6 @@ .. branch: enumerate-rstr Support enumerate() over rstr types. + +.. branch: cleanup-numpypy-namespace +Cleanup _numpypy and numpypy namespaces to more closely resemble numpy. diff --git a/pypy/module/micronumpy/__init__.py b/pypy/module/micronumpy/__init__.py --- a/pypy/module/micronumpy/__init__.py +++ b/pypy/module/micronumpy/__init__.py @@ -2,13 +2,11 @@ from pypy.module.micronumpy.interp_boxes import long_double_size, ENABLED_LONG_DOUBLE -class Module(MixedModule): - applevel_name = '_numpypy' - +class MultiArrayModule(MixedModule): + appleveldefs = {'arange': 'app_numpy.arange'} interpleveldefs = { 'ndarray': 'interp_numarray.W_NDimArray', 'dtype': 'interp_dtype.W_Dtype', - 'ufunc': 'interp_ufuncs.W_Ufunc', 'array': 'interp_numarray.array', 'zeros': 'interp_numarray.zeros', @@ -18,17 +16,17 @@ 'fromstring': 'interp_support.fromstring', 'flatiter': 'interp_flatiter.W_FlatIterator', 'concatenate': 'interp_arrayops.concatenate', - 'repeat': 'interp_arrayops.repeat', 'where': 'interp_arrayops.where', 'count_nonzero': 'interp_arrayops.count_nonzero', 'set_string_function': 'appbridge.set_string_function', + 'typeinfo': 'interp_dtype.get_dtype_cache(space).w_typeinfo', + } - 'True_': 'types.Bool.True', - 'False_': 'types.Bool.False', - 'typeinfo': 'interp_dtype.get_dtype_cache(space).w_typeinfo', - +class NumericTypesModule(MixedModule): + appleveldefs = {} + interpleveldefs = { 'generic': 'interp_boxes.W_GenericBox', 'number': 'interp_boxes.W_NumberBox', 'integer': 'interp_boxes.W_IntegerBox', @@ -72,7 +70,30 @@ 'complex128': 'interp_boxes.W_Complex128Box', 'complex64': 'interp_boxes.W_Complex64Box', } + if ENABLED_LONG_DOUBLE: + long_double_dtypes = [ + ('longdouble', 'interp_boxes.W_LongDoubleBox'), + ('longfloat', 'interp_boxes.W_LongDoubleBox'), + ('clongdouble', 'interp_boxes.W_CLongDoubleBox'), + ('clongfloat', 'interp_boxes.W_CLongDoubleBox'), + ] + if long_double_size == 16: + long_double_dtypes += [ + ('float128', 'interp_boxes.W_Float128Box'), + ('complex256', 'interp_boxes.W_Complex256Box'), + ] + elif long_double_size == 12: + long_double_dtypes += [ + ('float96', 'interp_boxes.W_Float96Box'), + ('complex192', 'interp_boxes.W_Complex192Box'), + ] + for dt, box in long_double_dtypes: + interpleveldefs[dt] = box + +class UMathModule(MixedModule): + appleveldefs = {} + interpleveldefs = {} # ufuncs for exposed, impl in [ ("absolute", "absolute"), @@ -154,35 +175,16 @@ ]: interpleveldefs[exposed] = "interp_ufuncs.get(space).%s" % impl - appleveldefs = { - 'arange': 'app_numpy.arange', + +class Module(MixedModule): + applevel_name = '_numpypy' + appleveldefs = {} + interpleveldefs = { + 'choose': 'interp_arrayops.choose', + 'repeat': 'interp_arrayops.repeat', } - def setup_after_space_initialization(self): - space = self.space - all_list = sorted(Module.interpleveldefs.keys() + \ - Module.appleveldefs.keys()) - # found by set(numpypy.__all__) - set(numpy.__all__) - all_list.remove('set_string_function') - all_list.remove('typeinfo') - w_all = space.wrap(all_list) - space.setitem(self.w_dict, space.new_interned_str('__all__'), w_all) - -if ENABLED_LONG_DOUBLE: - long_double_dtypes = [ - ('longdouble', 'interp_boxes.W_LongDoubleBox'), - ('longfloat', 'interp_boxes.W_LongDoubleBox'), - ('clongdouble', 'interp_boxes.W_CLongDoubleBox'), - ('clongfloat', 'interp_boxes.W_CLongDoubleBox'), - ] - if long_double_size == 16: - long_double_dtypes += [ - ('float128', 'interp_boxes.W_Float128Box'), - ('complex256', 'interp_boxes.W_Complex256Box'), - ] - elif long_double_size == 12: - long_double_dtypes += [ - ('float96', 'interp_boxes.W_Float96Box'), - ('complex192', 'interp_boxes.W_Complex192Box'), - ] - for dt, box in long_double_dtypes: - Module.interpleveldefs[dt] = box + submodules = { + 'multiarray': MultiArrayModule, + 'numerictypes': NumericTypesModule, + 'umath': UMathModule, + } diff --git a/pypy/module/micronumpy/app_numpy.py b/pypy/module/micronumpy/app_numpy.py --- a/pypy/module/micronumpy/app_numpy.py +++ b/pypy/module/micronumpy/app_numpy.py @@ -10,9 +10,9 @@ stop = start start = 0 if dtype is None: - test = _numpypy.array([start, stop, step, 0]) + test = _numpypy.multiarray.array([start, stop, step, 0]) dtype = test.dtype - arr = _numpypy.zeros(int(math.ceil((stop - start) / step)), dtype=dtype) + arr = _numpypy.multiarray.zeros(int(math.ceil((stop - start) / step)), dtype=dtype) i = start for j in range(arr.size): arr[j] = i diff --git a/pypy/module/micronumpy/interp_arrayops.py b/pypy/module/micronumpy/interp_arrayops.py --- a/pypy/module/micronumpy/interp_arrayops.py +++ b/pypy/module/micronumpy/interp_arrayops.py @@ -135,7 +135,7 @@ return res @unwrap_spec(repeats=int) -def repeat(space, w_arr, repeats, w_axis=None): +def repeat(space, w_arr, repeats, w_axis): arr = convert_to_array(space, w_arr) if space.is_none(w_axis): arr = arr.descr_flatten(space) @@ -161,14 +161,21 @@ def count_nonzero(space, w_obj): return space.wrap(loop.count_all_true(convert_to_array(space, w_obj))) -def choose(space, arr, w_choices, out, mode): + at unwrap_spec(mode=str) +def choose(space, w_arr, w_choices, w_out, mode): + arr = convert_to_array(space, w_arr) choices = [convert_to_array(space, w_item) for w_item in space.listview(w_choices)] if not choices: raise OperationError(space.w_ValueError, space.wrap("choices list cannot be empty")) - shape = shape_agreement_multiple(space, choices + [out]) - out = interp_dtype.dtype_agreement(space, choices, shape, out) + if space.is_none(w_out): + w_out = None + elif not isinstance(w_out, W_NDimArray): + raise OperationError(space.w_TypeError, space.wrap( + "return arrays must be of ArrayType")) + shape = shape_agreement_multiple(space, choices + [w_out]) + out = interp_dtype.dtype_agreement(space, choices, shape, w_out) dtype = out.get_dtype() if mode not in MODES: raise OperationError(space.w_ValueError, diff --git a/pypy/module/micronumpy/interp_numarray.py b/pypy/module/micronumpy/interp_numarray.py --- a/pypy/module/micronumpy/interp_numarray.py +++ b/pypy/module/micronumpy/interp_numarray.py @@ -14,7 +14,7 @@ from pypy.module.micronumpy.appbridge import get_appbridge_cache from pypy.module.micronumpy import loop from pypy.module.micronumpy.dot import match_dot_shapes -from pypy.module.micronumpy.interp_arrayops import repeat +from pypy.module.micronumpy.interp_arrayops import repeat, choose from rpython.tool.sourcetools import func_with_new_name from rpython.rlib import jit from rpython.rlib.rstring import StringBuilder @@ -452,13 +452,8 @@ return res @unwrap_spec(mode=str) - def descr_choose(self, space, w_choices, mode='raise', w_out=None): - if space.is_none(w_out): - w_out = None - elif not isinstance(w_out, W_NDimArray): - raise OperationError(space.w_TypeError, space.wrap( - "return arrays must be of ArrayType")) - return interp_arrayops.choose(space, self, w_choices, w_out, mode) + def descr_choose(self, space, w_choices, w_out=None, mode='raise'): + return choose(space, self, w_choices, w_out, mode) def descr_clip(self, space, w_min, w_max, w_out=None): if space.is_none(w_out): diff --git a/pypy/module/micronumpy/test/test_arrayops.py b/pypy/module/micronumpy/test/test_arrayops.py --- a/pypy/module/micronumpy/test/test_arrayops.py +++ b/pypy/module/micronumpy/test/test_arrayops.py @@ -3,26 +3,26 @@ class AppTestNumSupport(BaseNumpyAppTest): def test_where(self): - from _numpypy import where, ones, zeros, array + from numpypy import where, ones, zeros, array a = [1, 2, 3, 0, -3] a = where(array(a) > 0, ones(5), zeros(5)) assert (a == [1, 1, 1, 0, 0]).all() def test_where_differing_dtypes(self): - from _numpypy import array, ones, zeros, where + from numpypy import array, ones, zeros, where a = [1, 2, 3, 0, -3] a = where(array(a) > 0, ones(5, dtype=int), zeros(5, dtype=float)) assert (a == [1, 1, 1, 0, 0]).all() def test_where_broadcast(self): - from _numpypy import array, where + from numpypy import array, where a = where(array([[1, 2, 3], [4, 5, 6]]) > 3, [1, 1, 1], 2) assert (a == [[2, 2, 2], [1, 1, 1]]).all() a = where(True, [1, 1, 1], 2) assert (a == [1, 1, 1]).all() def test_where_errors(self): - from _numpypy import where, array + from numpypy import where, array raises(ValueError, "where([1, 2, 3], [3, 4, 5])") raises(ValueError, "where([1, 2, 3], [3, 4, 5], [6, 7])") assert where(True, 1, 2) == array(1) @@ -35,7 +35,7 @@ # xxx def test_where_invalidates(self): - from _numpypy import where, ones, zeros, array + from numpypy import where, ones, zeros, array a = array([1, 2, 3, 0, -3]) b = where(a > 0, ones(5), zeros(5)) a[0] = 0 @@ -43,7 +43,7 @@ def test_dot(self): - from _numpypy import array, dot, arange + from numpypy import array, dot, arange a = array(range(5)) assert dot(a, a) == 30.0 @@ -74,7 +74,7 @@ assert (dot([[1,2],[3,4]],[5,6]) == [17, 39]).all() def test_dot_constant(self): - from _numpypy import array, dot + from numpypy import array, dot a = array(range(5)) b = a.dot(2.5) for i in xrange(5): @@ -85,19 +85,21 @@ assert c == 12.0 def test_choose_basic(self): - from _numpypy import array + from numpypy import array, choose a, b, c = array([1, 2, 3]), array([4, 5, 6]), array([7, 8, 9]) r = array([2, 1, 0]).choose([a, b, c]) assert (r == [7, 5, 3]).all() + r = choose(array([2, 1, 0]), [a, b, c]) + assert (r == [7, 5, 3]).all() def test_choose_broadcast(self): - from _numpypy import array + from numpypy import array a, b, c = array([1, 2, 3]), [4, 5, 6], 13 r = array([2, 1, 0]).choose([a, b, c]) assert (r == [13, 5, 3]).all() def test_choose_out(self): - from _numpypy import array + from numpypy import array a, b, c = array([1, 2, 3]), [4, 5, 6], 13 r = array([2, 1, 0]).choose([a, b, c], out=None) assert (r == [13, 5, 3]).all() @@ -107,10 +109,10 @@ assert (a == [13, 5, 3]).all() def test_choose_modes(self): - from _numpypy import array + from numpypy import array a, b, c = array([1, 2, 3]), [4, 5, 6], 13 raises(ValueError, "array([3, 1, 0]).choose([a, b, c])") - raises(ValueError, "array([3, 1, 0]).choose([a, b, c], 'raises')") + raises(ValueError, "array([3, 1, 0]).choose([a, b, c], mode='raises')") raises(ValueError, "array([3, 1, 0]).choose([])") raises(ValueError, "array([-1, -2, -3]).choose([a, b, c])") r = array([4, 1, 0]).choose([a, b, c], mode='clip') @@ -119,13 +121,13 @@ assert (r == [4, 5, 3]).all() def test_choose_dtype(self): - from _numpypy import array + from numpypy import array a, b, c = array([1.2, 2, 3]), [4, 5, 6], 13 r = array([2, 1, 0]).choose([a, b, c]) assert r.dtype == float def test_choose_dtype_out(self): - from _numpypy import array + from numpypy import array a, b, c = array([1, 2, 3]), [4, 5, 6], 13 x = array([0, 0, 0], dtype='i2') r = array([2, 1, 0]).choose([a, b, c], out=x) diff --git a/pypy/module/micronumpy/test/test_base.py b/pypy/module/micronumpy/test/test_base.py --- a/pypy/module/micronumpy/test/test_base.py +++ b/pypy/module/micronumpy/test/test_base.py @@ -15,7 +15,6 @@ if '__pypy__' not in sys.builtin_module_names: import numpy sys.modules['numpypy'] = numpy - sys.modules['_numpypy'] = numpy cls.w_non_native_prefix = cls.space.wrap(nonnative_byteorder_prefix) cls.w_native_prefix = cls.space.wrap(byteorder_prefix) diff --git a/pypy/module/micronumpy/test/test_complex.py b/pypy/module/micronumpy/test/test_complex.py --- a/pypy/module/micronumpy/test/test_complex.py +++ b/pypy/module/micronumpy/test/test_complex.py @@ -132,13 +132,13 @@ cls.w_c_pow = cls.space.wrap(interp2app(cls_c_pow)) def test_fabs(self): - from _numpypy import fabs, complex128 + from numpypy import fabs, complex128 a = complex128(complex(-5., 5.)) raises(TypeError, fabs, a) def test_fmax(self): - from _numpypy import fmax, array + from numpypy import fmax, array nnan, nan, inf, ninf = float('-nan'), float('nan'), float('inf'), float('-inf') a = array((complex(ninf, 10), complex(10, ninf), complex( inf, 10), complex(10, inf), @@ -165,7 +165,7 @@ assert (fmax(a, b) == res).all() def test_fmin(self): - from _numpypy import fmin, array + from numpypy import fmin, array nnan, nan, inf, ninf = float('-nan'), float('nan'), float('inf'), float('-inf') a = array((complex(ninf, 10), complex(10, ninf), complex( inf, 10), complex(10, inf), @@ -192,14 +192,14 @@ assert (fmin(a, b) == res).all() def test_signbit(self): - from _numpypy import signbit + from numpypy import signbit raises(TypeError, signbit, complex(1,1)) def test_reciprocal(self): - from _numpypy import array, reciprocal, complex64, complex128 + from numpypy import array, reciprocal, complex64, complex128 c_and_relerr = [(complex64, 2e-7), (complex128, 2e-15)] try: - from _numpypy import clongdouble + from numpypy import clongdouble c_and_relerr.append((clongdouble, 2e-30)) except: pass # no longdouble yet @@ -224,23 +224,23 @@ assert (a[0].imag - e.imag) < rel_err def test_floorceiltrunc(self): - from _numpypy import array, floor, ceil, trunc + from numpypy import array, floor, ceil, trunc a = array([ complex(-1.4, -1.4), complex(-1.5, -1.5)]) raises(TypeError, floor, a) raises(TypeError, ceil, a) raises(TypeError, trunc, a) def test_copysign(self): - from _numpypy import copysign, complex128 + from numpypy import copysign, complex128 a = complex128(complex(-5., 5.)) b = complex128(complex(0., 0.)) raises(TypeError, copysign, a, b) def test_exp2(self): - from _numpypy import array, exp2, complex128, complex64 + from numpypy import array, exp2, complex128, complex64 c_and_relerr = [(complex64, 2e-7), (complex128, 2e-15)] try: - from _numpypy import clongdouble + from numpypy import clongdouble c_and_relerr.append((clongdouble, 2e-30)) except: pass # no longdouble yet @@ -279,7 +279,7 @@ def test_expm1(self): import math, cmath - from _numpypy import array, expm1, complex128, complex64 + from numpypy import array, expm1, complex128, complex64 inf = float('inf') ninf = -float('inf') nan = float('nan') @@ -318,7 +318,7 @@ self.rAlmostEqual(t1, t2, rel_err=rel_err, msg=msg) def test_not_complex(self): - from _numpypy import (radians, deg2rad, degrees, rad2deg, + from numpypy import (radians, deg2rad, degrees, rad2deg, isneginf, isposinf, logaddexp, logaddexp2, fmod, arctan2) raises(TypeError, radians, complex(90,90)) @@ -333,7 +333,7 @@ raises (TypeError, fmod, complex(90,90), 3) def test_isnan_isinf(self): - from _numpypy import isnan, isinf, array + from numpypy import isnan, isinf, array assert (isnan(array([0.2+2j, complex(float('inf'),0), complex(0,float('inf')), complex(0,float('nan')), complex(float('nan'), 0)], dtype=complex)) == \ @@ -346,7 +346,7 @@ def test_square(self): - from _numpypy import square + from numpypy import square assert square(complex(3, 4)) == complex(3,4) * complex(3, 4) def test_power_complex(self): @@ -355,7 +355,7 @@ nan = float('nan') cmpl = complex from math import copysign - from _numpypy import power, array, complex128, complex64 + from numpypy import power, array, complex128, complex64 # note: in some settings (namely a x86-32 build without the JIT), # gcc optimizes the code in rlib.rcomplex.c_pow() to not truncate # the 10-byte values down to 8-byte values. It ends up with more @@ -392,7 +392,7 @@ self.rAlmostEqual(t1, t2, rel_err=rel_err, msg=msg) def test_conjugate(self): - from _numpypy import conj, conjugate, complex128, complex64 + from numpypy import conj, conjugate, complex128, complex64 import numpypy as np c0 = complex128(complex(2.5, 0)) @@ -416,7 +416,7 @@ def test_logn(self): import math, cmath # log and log10 are tested in math (1:1 from rcomplex) - from _numpypy import log2, array, complex128, complex64, log1p + from numpypy import log2, array, complex128, complex64, log1p inf = float('inf') ninf = -float('inf') nan = float('nan') @@ -473,7 +473,7 @@ self.rAlmostEqual(t1, t2, rel_err=rel_err, msg=msg) def test_logical_ops(self): - from _numpypy import logical_and, logical_or, logical_xor, logical_not + from numpypy import logical_and, logical_or, logical_xor, logical_not c1 = complex(1, 1) c3 = complex(3, 0) @@ -487,7 +487,7 @@ assert (logical_not([c1, c0]) == [False, True]).all() def test_minimum(self): - from _numpypy import array, minimum + from numpypy import array, minimum a = array([-5.0+5j, -5.0-5j, -0.0-10j, 1.0+10j]) b = array([ 3.0+10.0j, 3.0, -2.0+2.0j, -3.0+4.0j]) @@ -496,7 +496,7 @@ assert c[i] == min(a[i], b[i]) def test_maximum(self): - from _numpypy import array, maximum + from numpypy import array, maximum a = array([-5.0+5j, -5.0-5j, -0.0-10j, 1.0+10j]) b = array([ 3.0+10.0j, 3.0, -2.0+2.0j, -3.0+4.0j]) @@ -505,14 +505,14 @@ assert c[i] == max(a[i], b[i]) def test_basic(self): - from _numpypy import (complex128, complex64, add, array, dtype, + from numpypy import (complex128, complex64, add, array, dtype, subtract as sub, multiply, divide, negative, absolute as abs, floor_divide, real, imag, sign) - from _numpypy import (equal, not_equal, greater, greater_equal, less, + from numpypy import (equal, not_equal, greater, greater_equal, less, less_equal, isnan) complex_dtypes = [complex64, complex128] try: - from _numpypy import clongfloat + from numpypy import clongfloat complex_dtypes.append(clongfloat) except: pass @@ -588,15 +588,15 @@ inf_c = complex_(complex(float('inf'), 0.)) assert repr(abs(inf_c)) == 'inf' assert repr(abs(complex(float('nan'), float('nan')))) == 'nan' - # numpy actually raises an AttributeError, - # but _numpypy raises a TypeError + # numpy actually raises an AttributeError, + # but numpypy raises a TypeError raises((TypeError, AttributeError), 'c2.real = 10.') raises((TypeError, AttributeError), 'c2.imag = 10.') assert(real(c2) == 3.0) assert(imag(c2) == 4.0) def test_conj(self): - from _numpypy import array + from numpypy import array a = array([1 + 2j, 1 - 2j]) assert (a.conj() == [1 - 2j, 1 + 2j]).all() @@ -605,7 +605,7 @@ if self.isWindows: skip('windows does not support c99 complex') import sys - import _numpypy as np + import numpypy as np rAlmostEqual = self.rAlmostEqual for complex_, abs_err, testcases in (\ diff --git a/pypy/module/micronumpy/test/test_dtypes.py b/pypy/module/micronumpy/test/test_dtypes.py --- a/pypy/module/micronumpy/test/test_dtypes.py +++ b/pypy/module/micronumpy/test/test_dtypes.py @@ -17,7 +17,7 @@ class AppTestDtypes(BaseAppTestDtypes): def test_dtype(self): - from _numpypy import dtype + from numpypy import dtype d = dtype('?') assert d.num == 0 @@ -36,7 +36,7 @@ raises(KeyError, 'dtype(int)["asdasd"]') def test_dtype_eq(self): - from _numpypy import dtype + from numpypy import dtype assert dtype("int8") == "int8" assert "int8" == dtype("int8") @@ -44,7 +44,7 @@ assert dtype(bool) == bool def test_dtype_with_types(self): - from _numpypy import dtype + from numpypy import dtype assert dtype(bool).num == 0 if self.ptr_size == 4: @@ -66,13 +66,13 @@ assert dtype(float).num == 12 def test_array_dtype_attr(self): - from _numpypy import array, dtype + from numpypy import array, dtype a = array(range(5), long) assert a.dtype is dtype(long) def test_repr_str(self): - from _numpypy import dtype + from numpypy import dtype assert '.dtype' in repr(dtype) d = dtype('?') @@ -80,7 +80,7 @@ assert str(d) == "bool" def test_bool_array(self): - from _numpypy import array, False_, True_ + from numpypy import array, False_, True_ a = array([0, 1, 2, 2.5], dtype='?') assert a[0] is False_ @@ -88,7 +88,7 @@ assert a[i] is True_ def test_copy_array_with_dtype(self): - from _numpypy import array, False_, longlong + from numpypy import array, longlong, False_ a = array([0, 1, 2, 3], dtype=long) # int on 64-bit, long in 32-bit @@ -102,35 +102,35 @@ assert b[0] is False_ def test_zeros_bool(self): - from _numpypy import zeros, False_ + from numpypy import zeros, False_ a = zeros(10, dtype=bool) for i in range(10): assert a[i] is False_ def test_ones_bool(self): - from _numpypy import ones, True_ + from numpypy import ones, True_ a = ones(10, dtype=bool) for i in range(10): assert a[i] is True_ def test_zeros_long(self): - from _numpypy import zeros, longlong + from numpypy import zeros, longlong a = zeros(10, dtype=long) for i in range(10): assert isinstance(a[i], longlong) assert a[1] == 0 def test_ones_long(self): - from _numpypy import ones, longlong + from numpypy import ones, longlong a = ones(10, dtype=long) for i in range(10): assert isinstance(a[i], longlong) assert a[1] == 1 def test_overflow(self): - from _numpypy import array, dtype + from numpypy import array, dtype assert array([128], 'b')[0] == -128 assert array([256], 'B')[0] == 0 assert array([32768], 'h')[0] == -32768 @@ -142,7 +142,7 @@ raises(OverflowError, "array([2**64], 'Q')") def test_bool_binop_types(self): - from _numpypy import array, dtype + from numpypy import array, dtype types = [ '?', 'b', 'B', 'h', 'H', 'i', 'I', 'l', 'L', 'q', 'Q', 'f', 'd', 'e' @@ -152,7 +152,7 @@ assert (a + array([0], t)).dtype is dtype(t) def test_binop_types(self): - from _numpypy import array, dtype + from numpypy import array, dtype tests = [('b','B','h'), ('b','h','h'), ('b','H','i'), ('b','i','i'), ('b','l','l'), ('b','q','q'), ('b','Q','d'), ('B','h','h'), ('B','H','H'), ('B','i','i'), ('B','I','I'), ('B','l','l'), @@ -176,7 +176,7 @@ assert (d1, d2) == (d1, d2) and d3 is dtype(dout) def test_add_int8(self): - from _numpypy import array, dtype + from numpypy import array, dtype a = array(range(5), dtype="int8") b = a + a @@ -185,7 +185,7 @@ assert b[i] == i * 2 def test_add_int16(self): - from _numpypy import array, dtype + from numpypy import array, dtype a = array(range(5), dtype="int16") b = a + a @@ -194,7 +194,7 @@ assert b[i] == i * 2 def test_add_uint32(self): - from _numpypy import array, dtype + from numpypy import array, dtype a = array(range(5), dtype="I") b = a + a @@ -203,49 +203,49 @@ assert b[i] == i * 2 def test_shape(self): - from _numpypy import dtype + from numpypy import dtype assert dtype(long).shape == () def test_cant_subclass(self): - from _numpypy import dtype + from numpypy import dtype # You can't subclass dtype raises(TypeError, type, "Foo", (dtype,), {}) def test_can_subclass(self): - import _numpypy - class xyz(_numpypy.void): + import numpypy + class xyz(numpypy.void): pass assert True def test_aliases(self): - from _numpypy import dtype + from numpypy import dtype assert dtype("float") is dtype(float) def test_index_int8(self): - from _numpypy import array, int8 + from numpypy import array, int8 a = array(range(10), dtype=int8) b = array([0] * 10, dtype=int8) for idx in b: a[idx] += 1 def test_index_int16(self): - from _numpypy import array, int16 + from numpypy import array, int16 a = array(range(10), dtype=int16) b = array([0] * 10, dtype=int16) for idx in b: a[idx] += 1 def test_index_int32(self): - from _numpypy import array, int32 + from numpypy import array, int32 a = array(range(10), dtype=int32) b = array([0] * 10, dtype=int32) for idx in b: a[idx] += 1 def test_index_int64(self): - from _numpypy import array, int64 + from numpypy import array, int64 a = array(range(10), dtype=int64) b = array([0] * 10, dtype=int64) @@ -253,7 +253,7 @@ a[idx] += 1 def test_hash(self): - import _numpypy as numpy + import numpypy as numpy for tp, value in [ (numpy.int8, 4), (numpy.int16, 5), @@ -268,7 +268,7 @@ class AppTestTypes(BaseAppTestDtypes): def test_abstract_types(self): - import _numpypy as numpy + import numpypy as numpy raises(TypeError, numpy.generic, 0) raises(TypeError, numpy.number, 0) @@ -308,16 +308,16 @@ #assert a.dtype is numpy.dtype('|V4') def test_new(self): - import _numpypy as np + import numpypy as np assert np.int_(4) == 4 assert np.float_(3.4) == 3.4 def test_pow(self): - from _numpypy import int_ + from numpypy import int_ assert int_(4) ** 2 == 16 def test_bool(self): - import _numpypy as numpy + import numpypy as numpy assert numpy.bool_.mro() == [numpy.bool_, numpy.generic, object] assert numpy.bool_(3) is numpy.True_ @@ -332,7 +332,7 @@ assert numpy.bool_("False") is numpy.True_ def test_int8(self): - import _numpypy as numpy + import numpypy as numpy assert numpy.int8.mro() == [numpy.int8, numpy.signedinteger, numpy.integer, numpy.number, @@ -356,7 +356,7 @@ assert numpy.int8('128') == -128 def test_uint8(self): - import _numpypy as numpy + import numpypy as numpy assert numpy.uint8.mro() == [numpy.uint8, numpy.unsignedinteger, numpy.integer, numpy.number, @@ -381,7 +381,7 @@ assert numpy.uint8('256') == 0 def test_int16(self): - import _numpypy as numpy + import numpypy as numpy x = numpy.int16(3) assert x == 3 @@ -391,7 +391,7 @@ assert numpy.int16('32768') == -32768 def test_uint16(self): - import _numpypy as numpy + import numpypy as numpy assert numpy.uint16(65535) == 65535 assert numpy.uint16(65536) == 0 @@ -400,7 +400,7 @@ def test_int32(self): import sys - import _numpypy as numpy + import numpypy as numpy x = numpy.int32(23) assert x == 23 @@ -416,7 +416,7 @@ def test_uint32(self): import sys - import _numpypy as numpy + import numpypy as numpy assert numpy.uint32(10) == 10 @@ -427,7 +427,7 @@ assert numpy.uint32('4294967296') == 0 def test_int_(self): - import _numpypy as numpy + import numpypy as numpy assert numpy.int_ is numpy.dtype(int).type assert numpy.int_.mro() == [numpy.int_, numpy.signedinteger, @@ -436,7 +436,7 @@ def test_int64(self): import sys - import _numpypy as numpy + import numpypy as numpy if sys.maxint == 2 ** 63 -1: assert numpy.int64.mro() == [numpy.int64, numpy.signedinteger, @@ -458,7 +458,7 @@ def test_uint64(self): import sys - import _numpypy as numpy + import numpypy as numpy assert numpy.uint64.mro() == [numpy.uint64, numpy.unsignedinteger, numpy.integer, numpy.number, @@ -475,7 +475,7 @@ raises(OverflowError, numpy.uint64(18446744073709551616)) def test_float16(self): - import _numpypy as numpy + import numpypy as numpy assert numpy.float16.mro() == [numpy.float16, numpy.floating, numpy.inexact, numpy.number, numpy.generic, object] @@ -486,7 +486,7 @@ def test_float32(self): - import _numpypy as numpy + import numpypy as numpy assert numpy.float32.mro() == [numpy.float32, numpy.floating, numpy.inexact, numpy.number, @@ -497,7 +497,7 @@ raises(ValueError, numpy.float32, '23.2df') def test_float64(self): - import _numpypy as numpy + import numpypy as numpy assert numpy.float64.mro() == [numpy.float64, numpy.floating, numpy.inexact, numpy.number, @@ -514,20 +514,20 @@ raises(ValueError, numpy.float64, '23.2df') def test_float_None(self): - import _numpypy as numpy + import numpypy as numpy from math import isnan assert isnan(numpy.float32(None)) assert isnan(numpy.float64(None)) def test_complex_floating(self): - import _numpypy as numpy + import numpypy as numpy assert numpy.complexfloating.__mro__ == (numpy.complexfloating, numpy.inexact, numpy.number, numpy.generic, object) def test_complex_format(self): import sys - import _numpypy as numpy + import numpypy as numpy for complex_ in (numpy.complex128, numpy.complex64,): for real, imag, should in [ @@ -567,7 +567,7 @@ assert "{:g}".format(numpy.complex_(0.5+1.5j)) == '{:g}'.format(0.5+1.5j) def test_complex(self): - import _numpypy as numpy + import numpypy as numpy assert numpy.complex_ is numpy.complex128 assert numpy.complex64.__mro__ == (numpy.complex64, @@ -585,7 +585,7 @@ assert d.char == 'F' def test_subclass_type(self): - import _numpypy as numpy + import numpypy as numpy class X(numpy.float64): def m(self): @@ -596,12 +596,12 @@ assert b.m() == 12 def test_long_as_index(self): - from _numpypy import int_, float64 + from numpypy import int_, float64 assert (1, 2, 3)[int_(1)] == 2 raises(TypeError, lambda: (1, 2, 3)[float64(1)]) def test_int(self): - from _numpypy import int32, int64, int_ + from numpypy import int32, int64, int_ import sys assert issubclass(int_, int) if sys.maxint == (1<<31) - 1: @@ -612,7 +612,7 @@ assert int_ is int64 def test_various_types(self): - import _numpypy as numpy + import numpypy as numpy assert numpy.int16 is numpy.short assert numpy.int8 is numpy.byte @@ -625,7 +625,7 @@ assert numpy.uintp is numpy.uint64 def test_mro(self): - import _numpypy as numpy + import numpypy as numpy assert numpy.int16.__mro__ == (numpy.int16, numpy.signedinteger, numpy.integer, numpy.number, @@ -634,7 +634,7 @@ def test_operators(self): from operator import truediv - from _numpypy import float64, int_, True_, False_ + from numpypy import float64, int_, True_, False_ assert 5 / int_(2) == int_(2) assert truediv(int_(3), int_(2)) == float64(1.5) assert truediv(3, int_(2)) == float64(1.5) @@ -659,7 +659,7 @@ raises(TypeError, lambda: float64(3) & 1) def test_alternate_constructs(self): - from _numpypy import dtype + from numpypy import dtype nnp = self.non_native_prefix byteorder = self.native_prefix assert dtype('i8') == dtype(byteorder + 'i8') == dtype('=i8') # XXX should be equal == dtype(long) @@ -669,23 +669,23 @@ assert dtype(byteorder + 'i8').byteorder == '=' def test_intp(self): - from _numpypy import dtype + from numpypy import dtype assert dtype('p') == dtype('intp') assert dtype('P') == dtype('uintp') def test_alignment(self): - from _numpypy import dtype + from numpypy import dtype assert dtype('i4').alignment == 4 class AppTestStrUnicodeDtypes(BaseNumpyAppTest): def test_str_unicode(self): - from _numpypy import str_, unicode_, character, flexible, generic + from numpypy import str_, unicode_, character, flexible, generic assert str_.mro() == [str_, str, basestring, character, flexible, generic, object] assert unicode_.mro() == [unicode_, unicode, basestring, character, flexible, generic, object] def test_str_dtype(self): - from _numpypy import dtype, str_ + from numpypy import dtype, str_ raises(TypeError, "dtype('Sx')") d = dtype('S8') @@ -697,7 +697,7 @@ assert d.num == 18 def test_unicode_dtype(self): - from _numpypy import dtype, unicode_ + from numpypy import dtype, unicode_ raises(TypeError, "dtype('Ux')") d = dtype('U8') @@ -709,16 +709,16 @@ assert d.num == 19 def test_string_boxes(self): - from _numpypy import str_ + from numpypy import str_ assert isinstance(str_(3), str_) def test_unicode_boxes(self): - from _numpypy import unicode_ + from numpypy import unicode_ assert isinstance(unicode_(3), unicode) class AppTestRecordDtypes(BaseNumpyAppTest): def test_create(self): - from _numpypy import dtype, void + from numpypy import dtype, void raises(ValueError, "dtype([('x', int), ('x', float)])") d = dtype([("x", "int32"), ("y", "int32"), ("z", "int32"), ("value", float)]) @@ -737,7 +737,7 @@ def test_create_from_dict(self): skip("not yet") - from _numpypy import dtype + from numpypy import dtype d = dtype({'names': ['a', 'b', 'c'], }) @@ -761,7 +761,7 @@ cls.w_check_non_native = cls.space.wrap(interp2app(check_non_native)) def test_non_native(self): - from _numpypy import array + from numpypy import array a = array([1, 2, 3], dtype=self.non_native_prefix + 'i2') assert a[0] == 1 assert (a + a)[1] == 4 @@ -783,7 +783,8 @@ BaseNumpyAppTest.setup_class.im_func(cls) def test_typeinfo(self): - from _numpypy import typeinfo, void, number, int64, bool_ + from numpypy import void, number, int64, bool_ + from numpypy.core.multiarray import typeinfo assert typeinfo['Number'] == number assert typeinfo['LONGLONG'] == ('q', 9, 64, 8, 9223372036854775807L, -9223372036854775808L, int64) assert typeinfo['VOID'] == ('V', 20, 0, 1, void) @@ -799,11 +800,11 @@ BaseNumpyAppTest.setup_class.im_func(cls) def test_nolongfloat(self): - import _numpypy - from _numpypy import dtype - assert not getattr(_numpypy, 'longdouble', False) - assert not getattr(_numpypy, 'float128', False) - assert not getattr(_numpypy, 'float96', False) + import numpypy + from numpypy import dtype + assert not getattr(numpypy, 'longdouble', False) + assert not getattr(numpypy, 'float128', False) + assert not getattr(numpypy, 'float96', False) raises(TypeError, dtype, 'longdouble') raises(TypeError, dtype, 'clongdouble') raises(TypeError, dtype, 'longfloat') @@ -820,7 +821,7 @@ BaseNumpyAppTest.setup_class.im_func(cls) def test_longfloat(self): - import _numpypy as numpy + import numpypy as numpy # it can be float96 or float128 if numpy.longfloat != numpy.float64: assert numpy.longfloat.mro()[1:] == [numpy.floating, @@ -833,33 +834,33 @@ raises(ValueError, numpy.longfloat, '23.2df') def test_dtype_aliases(self): - from _numpypy import dtype + from numpypy import dtype assert dtype('longfloat').num in (12, 13) assert dtype('longdouble').num in (12, 13) assert dtype('clongfloat').num in (15, 16) assert dtype('clongdouble').num in (15, 16) def test_bool_binop_types(self): - from _numpypy import array, dtype + from numpypy import array, dtype types = ['g', 'G'] a = array([True], '?') for t in types: assert (a + array([0], t)).dtype is dtype(t) def test_hash(self): - import _numpypy as numpy + import numpypy as numpy for tp, value in [ (numpy.longdouble, 4.32), ]: assert hash(tp(value)) == hash(value) def test_float_None(self): - import _numpypy as numpy + import numpypy as numpy from math import isnan assert isnan(numpy.longdouble(None)) def test_non_native(self): - from _numpypy import array + from numpypy import array a = array([1, 2, 3], dtype=self.non_native_prefix + 'g') # longdouble assert a[0] == 1 assert (a + a)[1] == 4 diff --git a/pypy/module/micronumpy/test/test_numarray.py b/pypy/module/micronumpy/test/test_numarray.py --- a/pypy/module/micronumpy/test/test_numarray.py +++ b/pypy/module/micronumpy/test/test_numarray.py @@ -245,7 +245,7 @@ return CustomIntObject(value) def test_ndarray(self): - from _numpypy import ndarray, array, dtype + from numpypy import ndarray, array, dtype assert type(ndarray) is type assert type(array) is not type @@ -262,24 +262,24 @@ assert a.shape == () def test_ndmin(self): - from _numpypy import array + from numpypy import array arr = array([[[1]]], ndmin=1) assert arr.shape == (1, 1, 1) def test_noop_ndmin(self): - from _numpypy import array + from numpypy import array arr = array([1], ndmin=3) assert arr.shape == (1, 1, 1) def test_type(self): - from _numpypy import array + from numpypy import array ar = array(range(5)) assert type(ar) is type(ar + ar) def test_ndim(self): - from _numpypy import array + from numpypy import array x = array(0.2) assert x.ndim == 0 x = array([1, 2]) @@ -288,12 +288,12 @@ assert x.ndim == 2 x = array([[[1, 2], [3, 4]], [[5, 6], [7, 8]]]) assert x.ndim == 3 - # numpy actually raises an AttributeError, but _numpypy raises an + # numpy actually raises an AttributeError, but numpypy raises an # TypeError raises((TypeError, AttributeError), 'x.ndim = 3') def test_init(self): - from _numpypy import zeros + from numpypy import zeros a = zeros(15) # Check that storage was actually zero'd. assert a[10] == 0.0 @@ -303,7 +303,7 @@ assert zeros(()).shape == () def test_size(self): - from _numpypy import array,arange,cos + from numpypy import array,arange,cos assert array(3).size == 1 a = array([1, 2, 3]) assert a.size == 3 @@ -316,13 +316,13 @@ Test that empty() works. """ - from _numpypy import empty + from numpypy import empty a = empty(2) a[1] = 1.0 assert a[1] == 1.0 def test_ones(self): - from _numpypy import ones + from numpypy import ones a = ones(3) assert len(a) == 3 assert a[0] == 1 @@ -331,7 +331,7 @@ assert a[2] == 4 def test_copy(self): - from _numpypy import arange, array + from numpypy import arange, array a = arange(5) b = a.copy() for i in xrange(5): @@ -357,12 +357,12 @@ assert b[0] == a[0] def test_iterator_init(self): - from _numpypy import array + from numpypy import array a = array(range(5)) assert a[3] == 3 def test_getitem(self): - from _numpypy import array + from numpypy import array a = array(range(5)) raises(IndexError, "a[5]") a = a + a @@ -371,14 +371,14 @@ raises(IndexError, "a[-6]") def test_getitem_float(self): - from _numpypy import array + from numpypy import array a = array([1, 2, 3, 4]) assert a[1.2] == 2 assert a[1.6] == 2 assert a[-1.2] == 4 def test_getitem_tuple(self): - from _numpypy import array + from numpypy import array a = array(range(5)) raises(IndexError, "a[(1,2)]") for i in xrange(5): @@ -388,20 +388,20 @@ assert a[i] == b[i] def test_getitem_nd(self): - from _numpypy import arange + from numpypy import arange a = arange(15).reshape(3, 5) assert a[1, 3] == 8 assert a.T[1, 2] == 11 def test_getitem_obj_index(self): - from _numpypy import arange + from numpypy import arange a = arange(10) assert a[self.CustomIndexObject(1)] == 1 def test_getitem_obj_prefer_index_to_int(self): - from _numpypy import arange + from numpypy import arange a = arange(10) @@ -409,14 +409,14 @@ assert a[self.CustomIndexIntObject(0, 1)] == 0 def test_getitem_obj_int(self): - from _numpypy import arange + from numpypy import arange a = arange(10) assert a[self.CustomIntObject(1)] == 1 def test_setitem(self): - from _numpypy import array + from numpypy import array a = array(range(5)) a[-1] = 5.0 assert a[4] == 5.0 @@ -424,7 +424,7 @@ raises(IndexError, "a[-6] = 3.0") def test_setitem_tuple(self): - from _numpypy import array + from numpypy import array a = array(range(5)) raises(IndexError, "a[(1,2)] = [0,1]") for i in xrange(5): @@ -435,7 +435,7 @@ assert a[i] == i def test_setitem_obj_index(self): - from _numpypy import arange + from numpypy import arange a = arange(10) @@ -443,7 +443,7 @@ assert a[1] == 100 def test_setitem_obj_prefer_index_to_int(self): - from _numpypy import arange + from numpypy import arange a = arange(10) @@ -451,7 +451,7 @@ assert a[0] == 100 def test_setitem_obj_int(self): - from _numpypy import arange + from numpypy import arange a = arange(10) @@ -471,13 +471,13 @@ # numpy will swallow errors in __int__ and __index__ and # just raise IndexError. - from _numpypy import arange + from numpypy import arange a = arange(10) raises(IndexError, "a[ErrorIndex()] == 0") raises(IndexError, "a[ErrorInt()] == 0") def test_setslice_array(self): - from _numpypy import array + from numpypy import array a = array(range(5)) b = array(range(2)) a[1:4:2] = b @@ -488,7 +488,7 @@ assert b[1] == 0. def test_setslice_of_slice_array(self): - from _numpypy import array, zeros + from numpypy import array, zeros a = zeros(5) a[::2] = array([9., 10., 11.]) assert a[0] == 9. @@ -507,7 +507,7 @@ assert a[0] == 3. def test_setslice_list(self): - from _numpypy import array + from numpypy import array a = array(range(5), float) b = [0., 1.] a[1:4:2] = b @@ -515,7 +515,7 @@ assert a[3] == 1. def test_setslice_constant(self): - from _numpypy import array + from numpypy import array a = array(range(5), float) a[1:4:2] = 0. assert a[1] == 0. @@ -523,7 +523,7 @@ def test_newaxis(self): import math - from _numpypy import array, cos, zeros + from numpypy import array, cos, zeros from numpypy.core.numeric import newaxis a = array(range(5)) b = array([range(5)]) @@ -537,7 +537,7 @@ assert ((cos(a)[:,newaxis] * cos(b).T) == expected).all() def test_newaxis_slice(self): - from _numpypy import array + from numpypy import array from numpypy.core.numeric import newaxis a = array(range(5)) @@ -550,7 +550,7 @@ assert (a[newaxis,1:] == c).all() def test_newaxis_assign(self): - from _numpypy import array + from numpypy import array from numpypy.core.numeric import newaxis a = array(range(5)) @@ -558,7 +558,7 @@ assert a[1] == 2 def test_newaxis_virtual(self): - from _numpypy import array + from numpypy import array from numpypy.core.numeric import newaxis a = array(range(5)) @@ -567,7 +567,7 @@ assert (b == c).all() def test_newaxis_then_slice(self): - from _numpypy import array + from numpypy import array from numpypy.core.numeric import newaxis a = array(range(5)) b = a[newaxis] @@ -575,14 +575,14 @@ assert (b[0,1:] == a[1:]).all() def test_slice_then_newaxis(self): - from _numpypy import array + from numpypy import array from numpypy.core.numeric import newaxis a = array(range(5)) b = a[2:] assert (b[newaxis] == [[2, 3, 4]]).all() def test_scalar(self): - from _numpypy import array, dtype + from numpypy import array, dtype a = array(3) raises(IndexError, "a[0]") raises(IndexError, "a[0] = 5") @@ -591,13 +591,13 @@ assert a.dtype is dtype(int) def test_len(self): - from _numpypy import array + from numpypy import array a = array(range(5)) assert len(a) == 5 assert len(a + a) == 5 def test_shape(self): - from _numpypy import array + from numpypy import array a = array(range(5)) assert a.shape == (5,) b = a + a @@ -607,7 +607,7 @@ assert array([]).shape == (0,) def test_set_shape(self): - from _numpypy import array, zeros + from numpypy import array, zeros a = array([]) raises(ValueError, "a.shape = []") a = array(range(12)) @@ -630,7 +630,7 @@ raises(AttributeError, 'a.shape = 6') def test_reshape(self): - from _numpypy import array, zeros + from numpypy import array, zeros a = array(range(12)) exc = raises(ValueError, "b = a.reshape((3, 10))") assert str(exc.value) == "total size of new array must be unchanged" @@ -646,7 +646,7 @@ assert a.reshape((0,)).shape == (0,) def test_slice_reshape(self): - from _numpypy import zeros, arange + from numpypy import zeros, arange a = zeros((4, 2, 3)) b = a[::2, :, :] b.shape = (2, 6) @@ -682,7 +682,7 @@ raises(ValueError, arange(10).reshape, (5, -1, -1)) def test_reshape_varargs(self): - from _numpypy import arange + from numpypy import arange z = arange(96).reshape(12, -1) y = z.reshape(4, 3, 8) assert y.shape == (4, 3, 8) @@ -695,19 +695,19 @@ raises(ValueError, "a.reshape(3)") def test_strides(self): - from _numpypy import array + from numpypy import array a = array([[1.0, 2.0], [3.0, 4.0]]) assert a.strides == (16, 8) assert a[1:].strides == (16, 8) def test_strides_scalar(self): - from _numpypy import array + from numpypy import array a = array(42) assert a.strides == () def test_add(self): - from _numpypy import array + from numpypy import array a = array(range(5)) b = a + a for i in range(5): @@ -720,7 +720,7 @@ assert c[i] == bool(a[i] + b[i]) def test_add_other(self): - from _numpypy import array + from numpypy import array a = array(range(5)) b = array([i for i in reversed(range(5))]) c = a + b @@ -728,14 +728,14 @@ assert c[i] == 4 def test_add_constant(self): - from _numpypy import array + from numpypy import array a = array(range(5)) b = a + 5 for i in range(5): assert b[i] == i + 5 def test_radd(self): - from _numpypy import array + from numpypy import array r = 3 + array(range(3)) for i in range(3): assert r[i] == i + 3 @@ -743,7 +743,7 @@ assert (r == [2, 4]).all() def test_add_list(self): - from _numpypy import array, ndarray + from numpypy import array, ndarray a = array(range(5)) b = list(reversed(range(5))) c = a + b @@ -752,14 +752,14 @@ assert c[i] == 4 def test_subtract(self): - from _numpypy import array + from numpypy import array a = array(range(5)) b = a - a for i in range(5): assert b[i] == 0 def test_subtract_other(self): - from _numpypy import array + from numpypy import array a = array(range(5)) b = array([1, 1, 1, 1, 1]) c = a - b @@ -767,35 +767,35 @@ assert c[i] == i - 1 def test_subtract_constant(self): - from _numpypy import array + from numpypy import array a = array(range(5)) b = a - 5 for i in range(5): assert b[i] == i - 5 def test_scalar_subtract(self): - from _numpypy import int32 + from numpypy import int32 assert int32(2) - 1 == 1 assert 1 - int32(2) == -1 def test_mul(self): - import _numpypy + import numpypy - a = _numpypy.array(range(5)) + a = numpypy.array(range(5)) b = a * a for i in range(5): assert b[i] == i * i assert b.dtype is a.dtype - a = _numpypy.array(range(5), dtype=bool) + a = numpypy.array(range(5), dtype=bool) b = a * a - assert b.dtype is _numpypy.dtype(bool) - assert b[0] is _numpypy.False_ + assert b.dtype is numpypy.dtype(bool) + assert b[0] is numpypy.False_ for i in range(1, 5): - assert b[i] is _numpypy.True_ + assert b[i] is numpypy.True_ def test_mul_constant(self): - from _numpypy import array + from numpypy import array a = array(range(5)) b = a * 5 for i in range(5): @@ -803,7 +803,7 @@ def test_div(self): from math import isnan - from _numpypy import array, dtype + from numpypy import array, dtype a = array(range(1, 6)) b = a / a @@ -835,7 +835,7 @@ assert c[2] == float('-inf') def test_div_other(self): - from _numpypy import array + from numpypy import array a = array(range(5)) b = array([2, 2, 2, 2, 2], float) From noreply at buildbot.pypy.org Mon Feb 25 23:12:16 2013 From: noreply at buildbot.pypy.org (mattip) Date: Mon, 25 Feb 2013 23:12:16 +0100 (CET) Subject: [pypy-commit] pypy numpy-unify-methods: merge from default Message-ID: <20130225221216.AA2D21C0EEA@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: numpy-unify-methods Changeset: r61797:40195bce7415 Date: 2013-02-25 22:39 +0200 http://bitbucket.org/pypy/pypy/changeset/40195bce7415/ Log: merge from default diff too long, truncating to 2000 out of 9021 lines diff --git a/.hgignore b/.hgignore --- a/.hgignore +++ b/.hgignore @@ -35,39 +35,43 @@ ^pypy/doc/config/.+\.rst$ ^pypy/doc/basicblock\.asc$ ^pypy/doc/.+\.svninfo$ -^pypy/translator/c/src/libffi_msvc/.+\.obj$ -^pypy/translator/c/src/libffi_msvc/.+\.dll$ -^pypy/translator/c/src/libffi_msvc/.+\.lib$ -^pypy/translator/c/src/libffi_msvc/.+\.exp$ -^pypy/translator/c/src/cjkcodecs/.+\.o$ -^pypy/translator/c/src/cjkcodecs/.+\.obj$ -^pypy/translator/jvm/\.project$ -^pypy/translator/jvm/\.classpath$ -^pypy/translator/jvm/eclipse-bin$ -^pypy/translator/jvm/src/pypy/.+\.class$ -^pypy/translator/benchmark/docutils$ -^pypy/translator/benchmark/templess$ -^pypy/translator/benchmark/gadfly$ -^pypy/translator/benchmark/mako$ -^pypy/translator/benchmark/bench-custom\.benchmark_result$ -^pypy/translator/benchmark/shootout_benchmarks$ -^pypy/translator/goal/pypy-translation-snapshot$ -^pypy/translator/goal/pypy-c -^pypy/translator/goal/pypy-jvm -^pypy/translator/goal/pypy-jvm.jar -^pypy/translator/goal/.+\.exe$ -^pypy/translator/goal/.+\.dll$ -^pypy/translator/goal/target.+-c$ +^rpython/translator/c/src/libffi_msvc/.+\.obj$ +^rpython/translator/c/src/libffi_msvc/.+\.dll$ +^rpython/translator/c/src/libffi_msvc/.+\.lib$ +^rpython/translator/c/src/libffi_msvc/.+\.exp$ +^rpython/translator/c/src/cjkcodecs/.+\.o$ +^rpython/translator/c/src/cjkcodecs/.+\.obj$ +^rpython/translator/c/src/stacklet/.+\.o$ +^rpython/translator/c/src/.+\.o$ +^rpython/translator/jvm/\.project$ +^rpython/translator/jvm/\.classpath$ +^rpython/translator/jvm/eclipse-bin$ +^rpython/translator/jvm/src/pypy/.+\.class$ +^rpython/translator/benchmark/docutils$ +^rpython/translator/benchmark/templess$ +^rpython/translator/benchmark/gadfly$ +^rpython/translator/benchmark/mako$ +^rpython/translator/benchmark/bench-custom\.benchmark_result$ +^rpython/translator/benchmark/shootout_benchmarks$ +^rpython/translator/goal/target.+-c$ +^rpython/translator/goal/.+\.exe$ +^rpython/translator/goal/.+\.dll$ +^pypy/goal/pypy-translation-snapshot$ +^pypy/goal/pypy-c +^pypy/goal/pypy-jvm +^pypy/goal/pypy-jvm.jar +^pypy/goal/.+\.exe$ +^pypy/goal/.+\.dll$ ^pypy/_cache$ ^pypy/doc/statistic/.+\.html$ ^pypy/doc/statistic/.+\.eps$ ^pypy/doc/statistic/.+\.pdf$ -^pypy/translator/cli/src/pypylib\.dll$ -^pypy/translator/cli/src/query\.exe$ -^pypy/translator/cli/src/main\.exe$ +^rpython/translator/cli/src/pypylib\.dll$ +^rpython/translator/cli/src/query\.exe$ +^rpython/translator/cli/src/main\.exe$ ^lib_pypy/ctypes_config_cache/_.+_cache\.py$ ^lib_pypy/ctypes_config_cache/_.+_.+_\.py$ -^pypy/translator/cli/query-descriptions$ +^rpython/translator/cli/query-descriptions$ ^pypy/doc/discussion/.+\.html$ ^include/.+\.h$ ^include/.+\.inl$ diff --git a/lib_pypy/numpypy/__init__.py b/lib_pypy/numpypy/__init__.py --- a/lib_pypy/numpypy/__init__.py +++ b/lib_pypy/numpypy/__init__.py @@ -1,5 +1,14 @@ -from _numpypy import * -from .core import * +import core +from core import * +import lib +from lib import * + +from __builtin__ import bool, int, long, float, complex, object, unicode, str +from core import abs, max, min + +__all__ = [] +__all__ += core.__all__ +__all__ += lib.__all__ import sys sys.modules.setdefault('numpy', sys.modules['numpypy']) diff --git a/lib_pypy/numpypy/core/__init__.py b/lib_pypy/numpypy/core/__init__.py --- a/lib_pypy/numpypy/core/__init__.py +++ b/lib_pypy/numpypy/core/__init__.py @@ -1,3 +1,14 @@ -from .fromnumeric import * -from .numeric import * -from .shape_base import * +import numeric +from numeric import * +import fromnumeric +from fromnumeric import * +import shape_base +from shape_base import * + +from fromnumeric import amax as max, amin as min +from numeric import absolute as abs + +__all__ = [] +__all__ += numeric.__all__ +__all__ += fromnumeric.__all__ +__all__ += shape_base.__all__ diff --git a/lib_pypy/numpypy/core/_methods.py b/lib_pypy/numpypy/core/_methods.py --- a/lib_pypy/numpypy/core/_methods.py +++ b/lib_pypy/numpypy/core/_methods.py @@ -1,11 +1,9 @@ # Array methods which are called by the both the C-code for the method # and the Python code for the NumPy-namespace function -#from numpy.core import multiarray as mu -#from numpy.core import umath as um -import _numpypy as mu -um = mu -from numpy.core.numeric import asanyarray +import multiarray as mu +import umath as um +from numeric import asanyarray def _amax(a, axis=None, out=None, keepdims=False): return um.maximum.reduce(a, axis=axis, diff --git a/lib_pypy/numpypy/core/arrayprint.py b/lib_pypy/numpypy/core/arrayprint.py --- a/lib_pypy/numpypy/core/arrayprint.py +++ b/lib_pypy/numpypy/core/arrayprint.py @@ -13,9 +13,9 @@ # and by Travis Oliphant 2005-8-22 for numpy import sys -import _numpypy as _nt -from _numpypy import maximum, minimum, absolute, not_equal, isnan, isinf -#from _numpypy import format_longfloat, datetime_as_string, datetime_data +import numerictypes as _nt +from umath import maximum, minimum, absolute, not_equal, isnan, isinf +#from multiarray import format_longfloat, datetime_as_string, datetime_data from fromnumeric import ravel @@ -294,12 +294,12 @@ #else: format_function = formatdict['int'] elif issubclass(dtypeobj, _nt.floating): - if issubclass(dtypeobj, _nt.longfloat): + if hasattr(_nt, 'longfloat') and issubclass(dtypeobj, _nt.longfloat): format_function = formatdict['longfloat'] else: format_function = formatdict['float'] elif issubclass(dtypeobj, _nt.complexfloating): - if issubclass(dtypeobj, _nt.clongfloat): + if hasattr(_nt, 'clongfloat') and issubclass(dtypeobj, _nt.clongfloat): format_function = formatdict['longcomplexfloat'] else: format_function = formatdict['complexfloat'] diff --git a/lib_pypy/numpypy/core/fromnumeric.py b/lib_pypy/numpypy/core/fromnumeric.py --- a/lib_pypy/numpypy/core/fromnumeric.py +++ b/lib_pypy/numpypy/core/fromnumeric.py @@ -16,6 +16,7 @@ ###################################################################### import numpypy +import _numpypy # Module containing non-deprecated functions borrowed from Numeric. __docformat__ = "restructuredtext en" @@ -274,7 +275,7 @@ [-1, -2, -3, -4, -5]]]) """ - raise NotImplementedError('Waiting on interp level method') + return _numpypy.choose(a, choices, out, mode) def repeat(a, repeats, axis=None): @@ -316,7 +317,7 @@ [3, 4]]) """ - raise NotImplementedError('Waiting on interp level method') + return _numpypy.repeat(a, repeats, axis) def put(a, ind, v, mode='raise'): @@ -1290,7 +1291,9 @@ array([3, 4, 2, 3, 4, 5, 6, 7, 8, 8]) """ - raise NotImplementedError('Waiting on interp level method') + if not hasattr(a, 'clip'): + a = numpypy.array(a) + return a.clip(a_min, a_max, out=out) def sum(a, axis=None, dtype=None, out=None): @@ -1360,10 +1363,9 @@ """ assert dtype is None - assert out is None if not hasattr(a, "sum"): a = numpypy.array(a) - return a.sum(axis=axis) + return a.sum(axis=axis, out=out) def product (a, axis=None, dtype=None, out=None): @@ -1720,11 +1722,11 @@ 4.0 """ - assert axis is None - assert out is None if not hasattr(a, "max"): a = numpypy.array(a) - return a.max() + if a.size < 1: + return numpypy.array([]) + return a.max(axis=axis, out=out) def amin(a, axis=None, out=None): @@ -1782,12 +1784,11 @@ 0.0 """ - # amin() is equivalent to min() - assert axis is None - assert out is None if not hasattr(a, 'min'): a = numpypy.array(a) - return a.min() + if a.size < 1: + return numpypy.array([]) + return a.min(axis=axis, out=out) def alen(a): """ diff --git a/lib_pypy/numpypy/core/multiarray.py b/lib_pypy/numpypy/core/multiarray.py new file mode 100644 --- /dev/null +++ b/lib_pypy/numpypy/core/multiarray.py @@ -0,0 +1,1 @@ +from _numpypy.multiarray import * diff --git a/lib_pypy/numpypy/core/numeric.py b/lib_pypy/numpypy/core/numeric.py --- a/lib_pypy/numpypy/core/numeric.py +++ b/lib_pypy/numpypy/core/numeric.py @@ -1,13 +1,40 @@ +__all__ = [ + 'newaxis', 'ufunc', + 'asarray', 'asanyarray', 'base_repr', + 'array_repr', 'array_str', 'set_string_function', + 'array_equal', 'outer', 'identity', 'little_endian', + 'Inf', 'inf', 'infty', 'Infinity', 'nan', 'NaN', 'False_', 'True_', + ] -from _numpypy import array, ndarray, int_, float_, bool_, flexible #, complex_# , longlong -from _numpypy import concatenate -from .fromnumeric import any -import math import sys -import _numpypy as multiarray # ARGH -from numpypy.core.arrayprint import array2string +import multiarray +from multiarray import * +del set_string_function +del typeinfo +import umath +from umath import * +import numerictypes +from numerictypes import * + +def extend_all(module): + adict = {} + for a in __all__: + adict[a] = 1 + try: + mall = getattr(module, '__all__') + except AttributeError: + mall = [k for k in module.__dict__.keys() if not k.startswith('_')] + for a in mall: + if a not in adict: + __all__.append(a) + +extend_all(multiarray) +__all__.remove('typeinfo') +extend_all(umath) +extend_all(numerictypes) newaxis = None +ufunc = type(sin) # XXX this file to be reviewed def seterr(**args): @@ -118,6 +145,10 @@ res.append('-') return ''.join(reversed(res or '0')) + +#Use numarray's printing function +from arrayprint import array2string + _typelessdata = [int_, float_]#, complex_] # XXX #if issubclass(intc, int): @@ -303,6 +334,11 @@ else: return multiarray.set_string_function(f, repr) +set_string_function(array_str, 0) +set_string_function(array_repr, 1) + +little_endian = (sys.byteorder == 'little') + def array_equal(a1, a2): """ True if two arrays have the same shape and elements, False otherwise. @@ -414,21 +450,6 @@ """ return array(a, dtype, copy=False, order=order) -set_string_function(array_str, 0) -set_string_function(array_repr, 1) - -little_endian = (sys.byteorder == 'little') - -Inf = inf = infty = Infinity = PINF = float('inf') -NINF = float('-inf') -PZERO = 0.0 -NZERO = -0.0 -nan = NaN = NAN = float('nan') -False_ = bool_(False) -True_ = bool_(True) -e = math.e -pi = math.pi - def outer(a,b): """ Compute the outer product of two vectors. @@ -501,3 +522,43 @@ a = asarray(a) b = asarray(b) return a.ravel()[:,newaxis]*b.ravel()[newaxis,:] + +def identity(n, dtype=None): + """ + Return the identity array. + + The identity array is a square array with ones on + the main diagonal. + + Parameters + ---------- + n : int + Number of rows (and columns) in `n` x `n` output. + dtype : data-type, optional + Data-type of the output. Defaults to ``float``. + + Returns + ------- + out : ndarray + `n` x `n` array with its main diagonal set to one, + and all other elements 0. + + Examples + -------- + >>> np.identity(3) + array([[ 1., 0., 0.], + [ 0., 1., 0.], + [ 0., 0., 1.]]) + + """ + from numpy import eye + return eye(n, dtype=dtype) + +Inf = inf = infty = Infinity = PINF +nan = NaN = NAN +False_ = bool_(False) +True_ = bool_(True) + +import fromnumeric +from fromnumeric import * +extend_all(fromnumeric) diff --git a/lib_pypy/numpypy/core/numerictypes.py b/lib_pypy/numpypy/core/numerictypes.py new file mode 100644 --- /dev/null +++ b/lib_pypy/numpypy/core/numerictypes.py @@ -0,0 +1,1 @@ +from _numpypy.numerictypes import * diff --git a/lib_pypy/numpypy/core/shape_base.py b/lib_pypy/numpypy/core/shape_base.py --- a/lib_pypy/numpypy/core/shape_base.py +++ b/lib_pypy/numpypy/core/shape_base.py @@ -1,4 +1,6 @@ -import _numpypy +__all__ = ['atleast_1d', 'atleast_2d', 'atleast_3d', 'vstack', 'hstack'] + +import numeric as _nx from numeric import array, asanyarray, newaxis def atleast_1d(*arys): @@ -221,7 +223,7 @@ [4]]) """ - return _numpypy.concatenate(map(atleast_2d,tup),0) + return _nx.concatenate(map(atleast_2d,tup),0) def hstack(tup): """ @@ -268,56 +270,6 @@ arrs = map(atleast_1d,tup) # As a special case, dimension 0 of 1-dimensional arrays is "horizontal" if arrs[0].ndim == 1: - return _numpypy.concatenate(arrs, 0) + return _nx.concatenate(arrs, 0) else: - return _numpypy.concatenate(arrs, 1) - -def dstack(tup): - """ - Stack arrays in sequence depth wise (along third axis). - - Takes a sequence of arrays and stack them along the third axis - to make a single array. Rebuilds arrays divided by `dsplit`. - This is a simple way to stack 2D arrays (images) into a single - 3D array for processing. - - Parameters - ---------- - tup : sequence of arrays - Arrays to stack. All of them must have the same shape along all - but the third axis. - - Returns - ------- - stacked : ndarray - The array formed by stacking the given arrays. - - See Also - -------- - vstack : Stack along first axis. - hstack : Stack along second axis. - concatenate : Join arrays. - dsplit : Split array along third axis. - - Notes - ----- - Equivalent to ``np.concatenate(tup, axis=2)``. - - Examples - -------- - >>> a = np.array((1,2,3)) - >>> b = np.array((2,3,4)) - >>> np.dstack((a,b)) - array([[[1, 2], - [2, 3], - [3, 4]]]) - - >>> a = np.array([[1],[2],[3]]) - >>> b = np.array([[2],[3],[4]]) - >>> np.dstack((a,b)) - array([[[1, 2]], - [[2, 3]], - [[3, 4]]]) - - """ - return _numpypy.concatenate(map(atleast_3d,tup),2) + return _nx.concatenate(arrs, 1) diff --git a/lib_pypy/numpypy/core/umath.py b/lib_pypy/numpypy/core/umath.py new file mode 100644 --- /dev/null +++ b/lib_pypy/numpypy/core/umath.py @@ -0,0 +1,12 @@ +from _numpypy.umath import * + +import math +e = math.e +pi = math.pi +del math + +PZERO = 0.0 +NZERO = -0.0 +PINF = float('inf') +NINF = float('-inf') +NAN = float('nan') diff --git a/lib_pypy/numpypy/lib/__init__.py b/lib_pypy/numpypy/lib/__init__.py new file mode 100644 --- /dev/null +++ b/lib_pypy/numpypy/lib/__init__.py @@ -0,0 +1,11 @@ +import function_base +from function_base import * +import shape_base +from shape_base import * +import twodim_base +from twodim_base import * + +__all__ = [] +__all__ += function_base.__all__ +__all__ += shape_base.__all__ +__all__ += twodim_base.__all__ diff --git a/lib_pypy/numpypy/lib/function_base.py b/lib_pypy/numpypy/lib/function_base.py new file mode 100644 --- /dev/null +++ b/lib_pypy/numpypy/lib/function_base.py @@ -0,0 +1,10 @@ +__all__ = ['average'] + +from ..core.numeric import array + +def average(a): + # This implements a weighted average, for now we don't implement the + # weighting, just the average part! + if not hasattr(a, "mean"): + a = array(a) + return a.mean() diff --git a/lib_pypy/numpypy/lib/shape_base.py b/lib_pypy/numpypy/lib/shape_base.py new file mode 100644 --- /dev/null +++ b/lib_pypy/numpypy/lib/shape_base.py @@ -0,0 +1,54 @@ +__all__ = ['dstack'] + +from ..core import numeric as _nx +from ..core import atleast_3d + +def dstack(tup): + """ + Stack arrays in sequence depth wise (along third axis). + + Takes a sequence of arrays and stack them along the third axis + to make a single array. Rebuilds arrays divided by `dsplit`. + This is a simple way to stack 2D arrays (images) into a single + 3D array for processing. + + Parameters + ---------- + tup : sequence of arrays + Arrays to stack. All of them must have the same shape along all + but the third axis. + + Returns + ------- + stacked : ndarray + The array formed by stacking the given arrays. + + See Also + -------- + vstack : Stack along first axis. + hstack : Stack along second axis. + concatenate : Join arrays. + dsplit : Split array along third axis. + + Notes + ----- + Equivalent to ``np.concatenate(tup, axis=2)``. + + Examples + -------- + >>> a = np.array((1,2,3)) + >>> b = np.array((2,3,4)) + >>> np.dstack((a,b)) + array([[[1, 2], + [2, 3], + [3, 4]]]) + + >>> a = np.array([[1],[2],[3]]) + >>> b = np.array([[2],[3],[4]]) + >>> np.dstack((a,b)) + array([[[1, 2]], + [[2, 3]], + [[3, 4]]]) + + """ + return _nx.concatenate(map(atleast_3d,tup),2) diff --git a/lib_pypy/numpypy/lib/twodim_base.py b/lib_pypy/numpypy/lib/twodim_base.py new file mode 100644 --- /dev/null +++ b/lib_pypy/numpypy/lib/twodim_base.py @@ -0,0 +1,54 @@ +__all__ = ['eye'] + +from ..core.numeric import zeros + +def eye(N, M=None, k=0, dtype=float): + """ + Return a 2-D array with ones on the diagonal and zeros elsewhere. + + Parameters + ---------- + N : int + Number of rows in the output. + M : int, optional + Number of columns in the output. If None, defaults to `N`. + k : int, optional + Index of the diagonal: 0 (the default) refers to the main diagonal, + a positive value refers to an upper diagonal, and a negative value + to a lower diagonal. + dtype : data-type, optional + Data-type of the returned array. + + Returns + ------- + I : ndarray of shape (N,M) + An array where all elements are equal to zero, except for the `k`-th + diagonal, whose values are equal to one. + + See Also + -------- + identity : (almost) equivalent function + diag : diagonal 2-D array from a 1-D array specified by the user. + + Examples + -------- + >>> np.eye(2, dtype=int) + array([[1, 0], + [0, 1]]) + >>> np.eye(3, k=1) + array([[ 0., 1., 0.], + [ 0., 0., 1.], + [ 0., 0., 0.]]) + + """ + if M is None: + M = N + m = zeros((N, M), dtype=dtype) + if k >= M: + return m + if k >= 0: + i = k + else: + i = (-k) * M + m[:M-k].flat[i::M+1] = 1 + return m diff --git a/pypy/doc/cpython_differences.rst b/pypy/doc/cpython_differences.rst --- a/pypy/doc/cpython_differences.rst +++ b/pypy/doc/cpython_differences.rst @@ -134,7 +134,7 @@ ``ReferenceError`` at any place that uses them. (Or, better yet, don't use ``weakref.proxy()`` at all; use ``weakref.ref()``.) -There are a few extra implications for the difference in the GC. Most +There are a few extra implications from the difference in the GC. Most notably, if an object has a ``__del__``, the ``__del__`` is never called more than once in PyPy; but CPython will call the same ``__del__`` several times if the object is resurrected and dies again. The ``__del__`` methods are @@ -156,7 +156,7 @@ .. __: http://bugs.pypy.org/issue736 -Using the default GC called ``minimark``, the built-in function ``id()`` +Using the default GC (called ``minimark``), the built-in function ``id()`` works like it does in CPython. With other GCs it returns numbers that are not real addresses (because an object can move around several times) and calling it a lot can lead to performance problem. @@ -286,7 +286,7 @@ ------------- * Hash randomization (``-R``) is ignored in PyPy. As documented in - http://bugs.python.org/issue14621 , some of us believe it has no + http://bugs.python.org/issue14621, some of us believe it has no purpose in CPython either. * ``sys.setrecursionlimit(n)`` sets the limit only approximately, diff --git a/pypy/doc/ctypes-implementation.rst b/pypy/doc/ctypes-implementation.rst --- a/pypy/doc/ctypes-implementation.rst +++ b/pypy/doc/ctypes-implementation.rst @@ -38,7 +38,7 @@ in dynamic libraries through libffi. Freeing objects in most cases and making sure that objects referring to each other are kept alive is responsibility of the higher levels. -This module uses bindings to libffi which are defined in ``pypy/rlib/libffi.py``. +This module uses bindings to libffi which are defined in ``rpython/rlib/libffi.py``. We tried to keep this module as small as possible. It is conceivable that other implementations (e.g. Jython) could use our ctypes diff --git a/pypy/doc/discussion/improve-rpython.rst b/pypy/doc/discussion/improve-rpython.rst --- a/pypy/doc/discussion/improve-rpython.rst +++ b/pypy/doc/discussion/improve-rpython.rst @@ -39,7 +39,7 @@ - Allocate variables on the stack, and pass their address ("by reference") to llexternal functions. For a typical usage, see - `pypy.rlib.rsocket.RSocket.getsockopt_int`. + `rpython.rlib.rsocket.RSocket.getsockopt_int`. Extensible type system for llexternal ------------------------------------- diff --git a/pypy/doc/faq.rst b/pypy/doc/faq.rst --- a/pypy/doc/faq.rst +++ b/pypy/doc/faq.rst @@ -202,20 +202,20 @@ Be sure to enable it again if you need it! -The PyPy translation tool chain -=============================== +The RPython translation tool chain +=================================== ---------------------------------------------- -Can PyPy compile normal Python programs to C? ---------------------------------------------- +------------------------------------------------ +Can RPython compile normal Python programs to C? +------------------------------------------------ -No, PyPy is not a Python compiler. +No, RPython is not a Python compiler. In Python, it is mostly impossible to *prove* anything about the types that a program will manipulate by doing a static analysis. It should be clear if you are familiar with Python, but if in doubt see [BRETT]_. -If you want a fast Python program, please use our JIT_ instead. +If you want a fast Python program, please use the PyPy JIT_ instead. .. _JIT: jit/index.html @@ -300,8 +300,8 @@ Do I have to rewrite my programs in RPython? -------------------------------------------- -No. And you shouldn't try. First and foremost, RPython is a language -that is designed to write interpreters in. It is a restricted subset of +No, and you shouldn't try. First and foremost, RPython is a language +designed for writing interpreters. It is a restricted subset of Python. If you program is not an interpreter but tries to do "real things", like use *any* part of the standard Python library or *any* 3rd-party library, then it is not RPython to start with. You should @@ -381,8 +381,8 @@ No, you have to rebuild the entire interpreter. This means two things: -* It is imperative to use test-driven development. You have to test - exhaustively your module in pure Python, before even attempting to +* It is imperative to use test-driven development. You have to exhaustively + test your module in pure Python, before even attempting to translate it. Once you translate it, you should have only a few typing issues left to fix, but otherwise the result should work out of the box. diff --git a/pypy/doc/garbage_collection.rst b/pypy/doc/garbage_collection.rst --- a/pypy/doc/garbage_collection.rst +++ b/pypy/doc/garbage_collection.rst @@ -42,7 +42,7 @@ Two arenas of equal size, with only one arena in use and getting filled with new objects. When the arena is full, the live objects are copied into the other arena using Cheney's algorithm. The old arena is then -cleared. See `rpython/rtyper/memory/gc/semispace.py`_. +cleared. See `rpython/memory/gc/semispace.py`_. On Unix the clearing is done by reading ``/dev/zero`` into the arena, which is extremely memory efficient at least on Linux: it lets the @@ -55,7 +55,7 @@ Generational GC --------------- -This is a two-generations GC. See `rpython/rtyper/memory/gc/generation.py`_. +This is a two-generations GC. See `rpython/memory/gc/generation.py`_. It is implemented as a subclass of the Semispace copying collector. It adds a nursery, which is a chunk of the current semispace. Its size is @@ -86,7 +86,7 @@ Each generation is collected much less often than the previous one. The division of the generations is slightly more complicated than just nursery / semispace / external; see the diagram at the start of the -source code, in `rpython/rtyper/memory/gc/hybrid.py`_. +source code, in `rpython/memory/gc/hybrid.py`_. Mark & Compact GC ----------------- @@ -161,7 +161,7 @@ to the old stage. The dying case 2 objects are immediately freed. - The old stage is an area of memory containing old (small) objects. It - is handled by `rpython/rtyper/memory/gc/minimarkpage.py`_. It is organized + is handled by `rpython/memory/gc/minimarkpage.py`_. It is organized as "arenas" of 256KB or 512KB, subdivided into "pages" of 4KB or 8KB. Each page can either be free, or contain small objects of all the same size. Furthermore at any point in time each object location can be diff --git a/pypy/doc/getting-started-dev.rst b/pypy/doc/getting-started-dev.rst --- a/pypy/doc/getting-started-dev.rst +++ b/pypy/doc/getting-started-dev.rst @@ -20,7 +20,7 @@ To start the interactive translator shell do:: - cd pypy + cd rpython python bin/translatorshell.py Test snippets of translatable code are provided in the file diff --git a/pypy/doc/index.rst b/pypy/doc/index.rst --- a/pypy/doc/index.rst +++ b/pypy/doc/index.rst @@ -286,7 +286,7 @@ `rpython/rtyper/ootypesystem/`_ the `object-oriented type system`_ for OO backends -`rpython/rtyper/memory/`_ the `garbage collector`_ construction +`rpython/memory/`_ the `garbage collector`_ construction framework `rpython/translator/`_ translation_ backends and support code diff --git a/pypy/doc/interpreter.rst b/pypy/doc/interpreter.rst --- a/pypy/doc/interpreter.rst +++ b/pypy/doc/interpreter.rst @@ -25,7 +25,7 @@ compact bytecode format as CPython 2.7, with minor differences in the bytecode set. Our bytecode compiler is implemented as a chain of flexible passes (tokenizer, lexer, parser, -abstract syntax tree builder, bytecode generator). The latter passes +abstract syntax tree builder and bytecode generator). The latter passes are based on the ``compiler`` package from the standard library of CPython, with various improvements and bug fixes. The bytecode compiler (living under `pypy/interpreter/astcompiler/`_) is now integrated and is @@ -38,8 +38,8 @@ calling its ``frame.eval()`` method. This main entry point initialize appropriate namespaces and then interprets each bytecode instruction. Python's standard library contains -the `lib-python/2.7/dis.py`_ module which allows to view -the Virtual's machine bytecode instructions:: +the `lib-python/2.7/dis.py`_ module which allows to inspection +of the virtual machine's bytecode instructions:: >>> import dis >>> def f(x): @@ -50,10 +50,10 @@ 6 BINARY_ADD 7 RETURN_VALUE -CPython as well as PyPy are stack-based virtual machines, i.e. -they don't have registers but put object to and pull objects +CPython and PyPy are stack-based virtual machines, i.e. +they don't have registers but instead push object to and pull objects from a stack. The bytecode interpreter is only responsible -for implementing control flow and putting and pulling black +for implementing control flow and pushing and pulling black box objects to and from this value stack. The bytecode interpreter does not know how to perform operations on those black box (`wrapped`_) objects for which it delegates to the `object @@ -75,8 +75,8 @@ on ``OperationErrors``. The interpreter implementation offers mechanisms to allow a -caller to be unaware if a particular function invocation leads -to bytecode interpretation or is executed directly at +caller to be unaware of whether a particular function invocation +leads to bytecode interpretation or is executed directly at interpreter-level. The two basic kinds of `Gateway classes`_ expose either an interpreter-level function to application-level execution (``interp2app``) or allow diff --git a/pypy/doc/stackless.rst b/pypy/doc/stackless.rst --- a/pypy/doc/stackless.rst +++ b/pypy/doc/stackless.rst @@ -273,7 +273,7 @@ more information about them please see the documentation in the C source at `rpython/translator/c/src/stacklet/stacklet.h`_. -The module ``pypy.rlib.rstacklet`` is a thin wrapper around the above +The module ``rpython.rlib.rstacklet`` is a thin wrapper around the above functions. The key point is that new() and switch() always return a fresh stacklet handle (or an empty one), and switch() additionally consumes one. It makes no sense to have code in which the returned diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst --- a/pypy/doc/whatsnew-head.rst +++ b/pypy/doc/whatsnew-head.rst @@ -18,6 +18,9 @@ .. branch: numpypy-longdouble Long double support for numpypy +.. branch: numpypy-disable-longdouble +Since r_longdouble support is missing, disable all longdouble and derivative +dtypes using ENABLED_LONG_DOUBLE = False .. branch: numpypy-real-as-view Convert real, imag from ufuncs to views. This involves the beginning of view() functionality @@ -68,3 +71,10 @@ .. branch: coding-guide-update-rlib-refs .. branch: rlib-doc-rpython-refs +.. branch: clean-up-remaining-pypy-rlib-refs + +.. branch: enumerate-rstr +Support enumerate() over rstr types. + +.. branch: cleanup-numpypy-namespace +Cleanup _numpypy and numpypy namespaces to more closely resemble numpy. diff --git a/pypy/module/_cffi_backend/cbuffer.py b/pypy/module/_cffi_backend/cbuffer.py --- a/pypy/module/_cffi_backend/cbuffer.py +++ b/pypy/module/_cffi_backend/cbuffer.py @@ -1,10 +1,11 @@ -from pypy.interpreter.error import operationerrfmt from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.buffer import RWBuffer +from pypy.interpreter.error import operationerrfmt from pypy.interpreter.gateway import unwrap_spec, interp2app from pypy.interpreter.typedef import TypeDef, make_weakref_descr +from pypy.module._cffi_backend import cdataobj, ctypeptr, ctypearray + from rpython.rtyper.lltypesystem import rffi -from pypy.module._cffi_backend import cdataobj, ctypeptr, ctypearray class LLBuffer(RWBuffer): diff --git a/pypy/module/_cffi_backend/ccallback.py b/pypy/module/_cffi_backend/ccallback.py --- a/pypy/module/_cffi_backend/ccallback.py +++ b/pypy/module/_cffi_backend/ccallback.py @@ -2,18 +2,17 @@ Callbacks. """ import os + +from rpython.rlib import clibffi, rweakref, jit +from rpython.rlib.objectmodel import compute_unique_id, keepalive_until_here +from rpython.rtyper.lltypesystem import lltype, rffi + from pypy.interpreter.error import OperationError, operationerrfmt -from rpython.rtyper.lltypesystem import lltype, llmemory, rffi -from rpython.rlib.objectmodel import compute_unique_id, keepalive_until_here -from rpython.rlib import clibffi, rweakref -from rpython.rlib import jit - +from pypy.module._cffi_backend import cerrno, misc from pypy.module._cffi_backend.cdataobj import W_CData -from pypy.module._cffi_backend.ctypefunc import SIZE_OF_FFI_ARG, BIG_ENDIAN -from pypy.module._cffi_backend.ctypefunc import W_CTypeFunc +from pypy.module._cffi_backend.ctypefunc import SIZE_OF_FFI_ARG, BIG_ENDIAN, W_CTypeFunc from pypy.module._cffi_backend.ctypeprim import W_CTypePrimitiveSigned from pypy.module._cffi_backend.ctypevoid import W_CTypeVoid -from pypy.module._cffi_backend import cerrno, misc # ____________________________________________________________ @@ -152,6 +151,7 @@ STDERR = 2 + @jit.jit_callback("CFFI") def invoke_callback(ffi_cif, ll_res, ll_args, ll_userdata): """ Callback specification. diff --git a/pypy/module/_cffi_backend/cdataobj.py b/pypy/module/_cffi_backend/cdataobj.py --- a/pypy/module/_cffi_backend/cdataobj.py +++ b/pypy/module/_cffi_backend/cdataobj.py @@ -1,11 +1,13 @@ import operator + +from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.error import OperationError, operationerrfmt -from pypy.interpreter.baseobjspace import Wrappable -from pypy.interpreter.gateway import interp2app, unwrap_spec +from pypy.interpreter.gateway import interp2app from pypy.interpreter.typedef import TypeDef, make_weakref_descr + +from rpython.rlib import objectmodel, rgc +from rpython.rlib.objectmodel import keepalive_until_here, specialize from rpython.rtyper.lltypesystem import lltype, rffi -from rpython.rlib.objectmodel import keepalive_until_here, specialize -from rpython.rlib import objectmodel, rgc from rpython.tool.sourcetools import func_with_new_name from pypy.module._cffi_backend import misc diff --git a/pypy/module/_cffi_backend/cerrno.py b/pypy/module/_cffi_backend/cerrno.py --- a/pypy/module/_cffi_backend/cerrno.py +++ b/pypy/module/_cffi_backend/cerrno.py @@ -1,5 +1,7 @@ import sys + from rpython.rlib import rposix + from pypy.interpreter.executioncontext import ExecutionContext from pypy.interpreter.gateway import unwrap_spec diff --git a/pypy/module/_cffi_backend/ctypearray.py b/pypy/module/_cffi_backend/ctypearray.py --- a/pypy/module/_cffi_backend/ctypearray.py +++ b/pypy/module/_cffi_backend/ctypearray.py @@ -2,18 +2,17 @@ Arrays. """ +from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.error import OperationError, operationerrfmt -from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.gateway import interp2app from pypy.interpreter.typedef import TypeDef + from rpython.rtyper.lltypesystem import rffi from rpython.rlib.objectmodel import keepalive_until_here from rpython.rlib.rarithmetic import ovfcheck -from pypy.module._cffi_backend.ctypeprim import W_CTypePrimitiveChar -from pypy.module._cffi_backend.ctypeprim import W_CTypePrimitiveUniChar +from pypy.module._cffi_backend import cdataobj from pypy.module._cffi_backend.ctypeptr import W_CTypePtrOrArray -from pypy.module._cffi_backend import cdataobj class W_CTypeArray(W_CTypePtrOrArray): diff --git a/pypy/module/_cffi_backend/ctypeenum.py b/pypy/module/_cffi_backend/ctypeenum.py --- a/pypy/module/_cffi_backend/ctypeenum.py +++ b/pypy/module/_cffi_backend/ctypeenum.py @@ -2,15 +2,11 @@ Enums. """ -from pypy.interpreter.error import OperationError, operationerrfmt -from rpython.rtyper.lltypesystem import rffi -from rpython.rlib.rarithmetic import intmask, r_ulonglong from rpython.rlib.objectmodel import keepalive_until_here -from rpython.rlib.objectmodel import specialize -from pypy.module._cffi_backend.ctypeprim import W_CTypePrimitiveSigned -from pypy.module._cffi_backend.ctypeprim import W_CTypePrimitiveUnsigned from pypy.module._cffi_backend import misc +from pypy.module._cffi_backend.ctypeprim import (W_CTypePrimitiveSigned, + W_CTypePrimitiveUnsigned) class _Mixin_Enum(object): diff --git a/pypy/module/_cffi_backend/ctypefunc.py b/pypy/module/_cffi_backend/ctypefunc.py --- a/pypy/module/_cffi_backend/ctypefunc.py +++ b/pypy/module/_cffi_backend/ctypefunc.py @@ -4,25 +4,21 @@ import sys from pypy.interpreter.error import OperationError, operationerrfmt + +from rpython.rlib import jit, clibffi, jit_libffi +from rpython.rlib.jit_libffi import (CIF_DESCRIPTION, CIF_DESCRIPTION_P, + FFI_TYPE, FFI_TYPE_P, FFI_TYPE_PP, SIZE_OF_FFI_ARG) +from rpython.rlib.objectmodel import we_are_translated, instantiate from rpython.rtyper.lltypesystem import lltype, llmemory, rffi -from rpython.rlib import jit, clibffi, jit_libffi -from rpython.rlib.jit_libffi import CIF_DESCRIPTION, CIF_DESCRIPTION_P -from rpython.rlib.jit_libffi import FFI_TYPE, FFI_TYPE_P, FFI_TYPE_PP -from rpython.rlib.jit_libffi import SIZE_OF_FFI_ARG -from rpython.rlib.objectmodel import we_are_translated, instantiate -from rpython.rlib.objectmodel import keepalive_until_here +from pypy.module._cffi_backend import ctypearray, cdataobj, cerrno from pypy.module._cffi_backend.ctypeobj import W_CType from pypy.module._cffi_backend.ctypeptr import W_CTypePtrBase, W_CTypePointer from pypy.module._cffi_backend.ctypevoid import W_CTypeVoid from pypy.module._cffi_backend.ctypestruct import W_CTypeStruct -from pypy.module._cffi_backend.ctypestruct import W_CTypeStructOrUnion -from pypy.module._cffi_backend.ctypeprim import W_CTypePrimitiveSigned -from pypy.module._cffi_backend.ctypeprim import W_CTypePrimitiveUnsigned -from pypy.module._cffi_backend.ctypeprim import W_CTypePrimitiveCharOrUniChar -from pypy.module._cffi_backend.ctypeprim import W_CTypePrimitiveFloat -from pypy.module._cffi_backend.ctypeprim import W_CTypePrimitiveLongDouble -from pypy.module._cffi_backend import ctypearray, cdataobj, cerrno +from pypy.module._cffi_backend.ctypeprim import (W_CTypePrimitiveSigned, + W_CTypePrimitiveUnsigned, W_CTypePrimitiveCharOrUniChar, + W_CTypePrimitiveFloat, W_CTypePrimitiveLongDouble) class W_CTypeFunc(W_CTypePtrBase): @@ -97,7 +93,6 @@ return self.space.wrap(clibffi.FFI_DEFAULT_ABI) # XXX return W_CTypePtrBase._fget(self, attrchar) - def call(self, funcaddr, args_w): if self.cif_descr: # regular case: this function does not take '...' arguments @@ -270,7 +265,6 @@ self.bufferp = rffi.ptradd(result, size) return result - def fb_fill_type(self, ctype, is_result_type): return ctype._get_ffi_type(self, is_result_type) @@ -357,7 +351,6 @@ return ffistruct - def fb_build(self): # Build a CIF_DESCRIPTION. Actually this computes the size and # allocates a larger amount of data. It starts with a @@ -387,7 +380,6 @@ if self.atypes: self.atypes[i] = atype - def align_arg(self, n): return (n + 7) & ~7 diff --git a/pypy/module/_cffi_backend/ctypeobj.py b/pypy/module/_cffi_backend/ctypeobj.py --- a/pypy/module/_cffi_backend/ctypeobj.py +++ b/pypy/module/_cffi_backend/ctypeobj.py @@ -1,9 +1,8 @@ +from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.error import OperationError, operationerrfmt -from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.gateway import interp2app -from pypy.interpreter.typedef import TypeDef -from pypy.interpreter.typedef import make_weakref_descr -from pypy.interpreter.typedef import GetSetProperty, interp_attrproperty +from pypy.interpreter.typedef import TypeDef, make_weakref_descr, GetSetProperty + from rpython.rtyper.lltypesystem import lltype, llmemory, rffi from rpython.rlib.objectmodel import we_are_translated diff --git a/pypy/module/_cffi_backend/ctypeprim.py b/pypy/module/_cffi_backend/ctypeprim.py --- a/pypy/module/_cffi_backend/ctypeprim.py +++ b/pypy/module/_cffi_backend/ctypeprim.py @@ -3,13 +3,14 @@ """ from pypy.interpreter.error import operationerrfmt -from rpython.rtyper.lltypesystem import lltype, rffi + from rpython.rlib.rarithmetic import r_uint, r_ulonglong, intmask from rpython.rlib.objectmodel import keepalive_until_here from rpython.rlib import jit +from rpython.rtyper.lltypesystem import lltype, rffi +from pypy.module._cffi_backend import cdataobj, misc from pypy.module._cffi_backend.ctypeobj import W_CType -from pypy.module._cffi_backend import cdataobj, misc class W_CTypePrimitive(W_CType): diff --git a/pypy/module/_cffi_backend/ctypeptr.py b/pypy/module/_cffi_backend/ctypeptr.py --- a/pypy/module/_cffi_backend/ctypeptr.py +++ b/pypy/module/_cffi_backend/ctypeptr.py @@ -2,15 +2,15 @@ Pointers. """ -from pypy.interpreter.error import OperationError, operationerrfmt -from pypy.interpreter.error import wrap_oserror -from rpython.rtyper.lltypesystem import lltype, rffi +from pypy.interpreter.error import OperationError, operationerrfmt, wrap_oserror + +from rpython.rlib import rposix from rpython.rlib.objectmodel import keepalive_until_here from rpython.rlib.rarithmetic import ovfcheck -from rpython.rlib import rposix +from rpython.rtyper.lltypesystem import lltype, rffi +from pypy.module._cffi_backend import cdataobj, misc, ctypeprim, ctypevoid from pypy.module._cffi_backend.ctypeobj import W_CType -from pypy.module._cffi_backend import cdataobj, misc, ctypeprim, ctypevoid class W_CTypePtrOrArray(W_CType): @@ -336,19 +336,22 @@ rffi_fdopen = rffi.llexternal("fdopen", [rffi.INT, rffi.CCHARP], rffi.CCHARP) -rffi_setbuf = rffi.llexternal("setbuf", [rffi.CCHARP,rffi.CCHARP], lltype.Void) +rffi_setbuf = rffi.llexternal("setbuf", [rffi.CCHARP, rffi.CCHARP], lltype.Void) rffi_fclose = rffi.llexternal("fclose", [rffi.CCHARP], rffi.INT) class CffiFileObj(object): _immutable_ = True + def __init__(self, fd, mode): self.llf = rffi_fdopen(fd, mode) if not self.llf: raise OSError(rposix.get_errno(), "fdopen failed") rffi_setbuf(self.llf, lltype.nullptr(rffi.CCHARP.TO)) + def close(self): rffi_fclose(self.llf) + def prepare_file_argument(space, fileobj): fileobj.direct_flush() if fileobj.cffi_fileobj is None: diff --git a/pypy/module/_cffi_backend/ctypestruct.py b/pypy/module/_cffi_backend/ctypestruct.py --- a/pypy/module/_cffi_backend/ctypestruct.py +++ b/pypy/module/_cffi_backend/ctypestruct.py @@ -3,15 +3,16 @@ """ from pypy.interpreter.error import OperationError, operationerrfmt -from rpython.rtyper.lltypesystem import lltype, rffi from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.typedef import TypeDef, interp_attrproperty + +from rpython.rlib import jit from rpython.rlib.objectmodel import keepalive_until_here from rpython.rlib.rarithmetic import r_uint, r_ulonglong, r_longlong, intmask -from rpython.rlib import jit +from rpython.rtyper.lltypesystem import rffi +from pypy.module._cffi_backend import cdataobj, ctypeprim, misc from pypy.module._cffi_backend.ctypeobj import W_CType -from pypy.module._cffi_backend import cdataobj, ctypeprim, misc class W_CTypeStructOrUnion(W_CType): @@ -141,6 +142,7 @@ class W_CTypeStruct(W_CTypeStructOrUnion): kind = "struct" + class W_CTypeUnion(W_CTypeStructOrUnion): kind = "union" @@ -241,8 +243,8 @@ # value = misc.as_long_long(space, w_ob) if isinstance(ctype, ctypeprim.W_CTypePrimitiveSigned): - fmin = -(r_longlong(1) << (self.bitsize-1)) - fmax = (r_longlong(1) << (self.bitsize-1)) - 1 + fmin = -(r_longlong(1) << (self.bitsize - 1)) + fmax = (r_longlong(1) << (self.bitsize - 1)) - 1 if fmax == 0: fmax = 1 # special case to let "int x:1" receive "1" else: diff --git a/pypy/module/_cffi_backend/libraryobj.py b/pypy/module/_cffi_backend/libraryobj.py --- a/pypy/module/_cffi_backend/libraryobj.py +++ b/pypy/module/_cffi_backend/libraryobj.py @@ -1,9 +1,11 @@ from __future__ import with_statement -from pypy.interpreter.error import OperationError, operationerrfmt + from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.error import operationerrfmt from pypy.interpreter.gateway import interp2app, unwrap_spec from pypy.interpreter.typedef import TypeDef -from rpython.rtyper.lltypesystem import lltype, rffi + +from rpython.rtyper.lltypesystem import rffi from rpython.rlib.rdynload import DLLHANDLE, dlopen, dlsym, dlclose, DLOpenError from pypy.module._cffi_backend.cdataobj import W_CData diff --git a/pypy/module/_cffi_backend/misc.py b/pypy/module/_cffi_backend/misc.py --- a/pypy/module/_cffi_backend/misc.py +++ b/pypy/module/_cffi_backend/misc.py @@ -1,10 +1,12 @@ from __future__ import with_statement -from pypy.interpreter.error import OperationError, operationerrfmt -from rpython.rtyper.lltypesystem import lltype, llmemory, rffi + +from pypy.interpreter.error import OperationError + +from rpython.rlib import jit +from rpython.rlib.objectmodel import keepalive_until_here, specialize from rpython.rlib.rarithmetic import r_uint, r_ulonglong, is_signed_integer_type from rpython.rlib.unroll import unrolling_iterable -from rpython.rlib.objectmodel import keepalive_until_here, specialize -from rpython.rlib import jit +from rpython.rtyper.lltypesystem import lltype, llmemory, rffi from rpython.translator.tool.cbuild import ExternalCompilationInfo # ____________________________________________________________ @@ -43,14 +45,14 @@ def read_raw_unsigned_data(target, size): for TP, TPP in _prim_unsigned_types: if size == rffi.sizeof(TP): - return rffi.cast(lltype.UnsignedLongLong, rffi.cast(TPP,target)[0]) + return rffi.cast(lltype.UnsignedLongLong, rffi.cast(TPP, target)[0]) raise NotImplementedError("bad integer size") def read_raw_ulong_data(target, size): for TP, TPP in _prim_unsigned_types: if size == rffi.sizeof(TP): assert rffi.sizeof(TP) <= rffi.sizeof(lltype.Unsigned) - return rffi.cast(lltype.Unsigned, rffi.cast(TPP,target)[0]) + return rffi.cast(lltype.Unsigned, rffi.cast(TPP, target)[0]) raise NotImplementedError("bad integer size") def read_raw_float_data(target, size): diff --git a/pypy/module/_cffi_backend/newtype.py b/pypy/module/_cffi_backend/newtype.py --- a/pypy/module/_cffi_backend/newtype.py +++ b/pypy/module/_cffi_backend/newtype.py @@ -1,12 +1,12 @@ from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.gateway import unwrap_spec + +from rpython.rlib.objectmodel import specialize +from rpython.rlib.rarithmetic import ovfcheck from rpython.rtyper.lltypesystem import lltype, rffi -from rpython.rlib.rarithmetic import ovfcheck, r_uint, intmask -from rpython.rlib.rarithmetic import most_neg_value_of, most_pos_value_of -from rpython.rlib.objectmodel import specialize -from pypy.module._cffi_backend import ctypeobj, ctypeprim, ctypeptr, ctypearray -from pypy.module._cffi_backend import ctypestruct, ctypevoid, ctypeenum +from pypy.module._cffi_backend import (ctypeobj, ctypeprim, ctypeptr, + ctypearray, ctypestruct, ctypevoid, ctypeenum) @specialize.memo() @@ -167,7 +167,7 @@ # if foffset < 0: # align this field to its own 'falign' by inserting padding - offset = (offset + falign - 1) & ~(falign-1) + offset = (offset + falign - 1) & ~(falign - 1) else: # a forced field position: ignore the offset just computed, # except to know if we must set 'custom_field_pos' @@ -178,7 +178,7 @@ fbitsize == 8 * ftype.size and not isinstance(ftype, ctypeprim.W_CTypePrimitiveCharOrUniChar)): fbitsize = -1 - if isinstance(ftype, ctypearray.W_CTypeArray) and ftype.length==0: + if isinstance(ftype, ctypearray.W_CTypeArray) and ftype.length == 0: bitshift = ctypestruct.W_CField.BS_EMPTY_ARRAY else: bitshift = ctypestruct.W_CField.BS_REGULAR @@ -241,7 +241,7 @@ # as 1 instead. But for ctypes support, we allow the manually- # specified totalsize to be zero in this case. if totalsize < 0: - offset = (offset + alignment - 1) & ~(alignment-1) + offset = (offset + alignment - 1) & ~(alignment - 1) totalsize = offset or 1 elif totalsize < offset: raise operationerrfmt(space.w_TypeError, diff --git a/pypy/module/_io/interp_bufferedio.py b/pypy/module/_io/interp_bufferedio.py --- a/pypy/module/_io/interp_bufferedio.py +++ b/pypy/module/_io/interp_bufferedio.py @@ -631,6 +631,72 @@ return res return None + def readline_w(self, space, w_limit=None): + self._check_init(space) + self._check_closed(space, "readline of closed file") + + limit = convert_size(space, w_limit) + + # First, try to find a line in the buffer. This can run + # unlocked because the calls to the C API are simple enough + # that they can't trigger any thread switch. + have = self._readahead() + if limit >= 0 and have > limit: + have = limit + for pos in range(self.pos, self.pos+have): + if self.buffer[pos] == '\n': + break + else: + pos = -1 + if pos >= 0: + w_res = space.wrap(''.join(self.buffer[self.pos:pos+1])) + self.pos = pos + 1 + return w_res + if have == limit: + w_res = space.wrap(''.join(self.buffer[self.pos:self.pos+have])) + self.pos += have + return w_res + + written = 0 + with self.lock: + # Now we try to get some more from the raw stream + chunks = [] + if have > 0: + chunks.extend(self.buffer[self.pos:self.pos+have]) + written += have + self.pos += have + if limit >= 0: + limit -= have + if self.writable: + self._flush_and_rewind_unlocked(space) + + while True: + self._reader_reset_buf() + have = self._fill_buffer(space) + if have == 0: + break + if limit >= 0 and have > limit: + have = limit + pos = 0 + found = False + while pos < have: + c = self.buffer[pos] + pos += 1 + if c == '\n': + self.pos = pos + found = True + break + chunks.extend(self.buffer[0:pos]) + if found: + break + if have == limit: + self.pos = have + break + written += have + if limit >= 0: + limit -= have + return space.wrap(''.join(chunks)) + # ____________________________________________________ # Write methods @@ -795,6 +861,7 @@ peek = interp2app(W_BufferedReader.peek_w), read1 = interp2app(W_BufferedReader.read1_w), raw = interp_attrproperty_w("w_raw", cls=W_BufferedReader), + readline = interp2app(W_BufferedReader.readline_w), # from the mixin class __repr__ = interp2app(W_BufferedReader.repr_w), @@ -968,6 +1035,7 @@ read = interp2app(W_BufferedRandom.read_w), peek = interp2app(W_BufferedRandom.peek_w), read1 = interp2app(W_BufferedRandom.read1_w), + readline = interp2app(W_BufferedRandom.readline_w), write = interp2app(W_BufferedRandom.write_w), flush = interp2app(W_BufferedRandom.flush_w), diff --git a/pypy/module/_io/interp_bytesio.py b/pypy/module/_io/interp_bytesio.py --- a/pypy/module/_io/interp_bytesio.py +++ b/pypy/module/_io/interp_bytesio.py @@ -52,6 +52,25 @@ self.pos += size return space.wrap(output) + def readline_w(self, space, w_limit=None): + self._check_closed(space) + limit = convert_size(space, w_limit) + + cur_pos = self.pos + if limit < 0: + end_pos = self.string_size + else: + end_pos = min(cur_pos + limit, self.string_size) + while cur_pos != end_pos: + if self.buf[cur_pos] == '\n': + cur_pos += 1 + break + cur_pos += 1 + + output = buffer2string(self.buf, self.pos, cur_pos) + self.pos = cur_pos + return space.wrap(output) + def read1_w(self, space, w_size): return self.read_w(space, w_size) @@ -209,6 +228,7 @@ read = interp2app(W_BytesIO.read_w), read1 = interp2app(W_BytesIO.read1_w), + readline = interp2app(W_BytesIO.readline_w), readinto = interp2app(W_BytesIO.readinto_w), write = interp2app(W_BytesIO.write_w), truncate = interp2app(W_BytesIO.truncate_w), diff --git a/pypy/module/_io/interp_fileio.py b/pypy/module/_io/interp_fileio.py --- a/pypy/module/_io/interp_fileio.py +++ b/pypy/module/_io/interp_fileio.py @@ -3,7 +3,6 @@ from pypy.interpreter.error import OperationError, wrap_oserror, wrap_oserror2 from rpython.rlib.rarithmetic import r_longlong from rpython.rlib.rstring import StringBuilder -from rpython.rlib.rposix import validate_fd from os import O_RDONLY, O_WRONLY, O_RDWR, O_CREAT, O_TRUNC import sys, os, stat, errno from pypy.module._io.interp_iobase import W_RawIOBase, convert_size @@ -154,7 +153,6 @@ fd_is_own = False try: if fd >= 0: - validate_fd(fd) try: os.fstat(fd) except OSError, e: @@ -235,7 +233,6 @@ self.fd = -1 try: - validate_fd(fd) os.close(fd) except OSError, e: raise wrap_oserror(space, e, diff --git a/pypy/module/_io/test/test_bufferedio.py b/pypy/module/_io/test/test_bufferedio.py --- a/pypy/module/_io/test/test_bufferedio.py +++ b/pypy/module/_io/test/test_bufferedio.py @@ -631,6 +631,19 @@ f.flush() assert raw.getvalue() == b'1b\n2def\n3\n' + def test_readline(self): + import _io as io + with io.BytesIO(b"abc\ndef\nxyzzy\nfoo\x00bar\nanother line") as raw: + with io.BufferedRandom(raw, buffer_size=10) as f: + assert f.readline() == b"abc\n" + assert f.readline(10) == b"def\n" + assert f.readline(2) == b"xy" + assert f.readline(4) == b"zzy\n" + assert f.readline() == b"foo\x00bar\n" + assert f.readline(None) == b"another line" + raises(TypeError, f.readline, 5.3) + + class TestNonReentrantLock: spaceconfig = dict(usemodules=['thread']) diff --git a/pypy/module/_io/test/test_bytesio.py b/pypy/module/_io/test/test_bytesio.py --- a/pypy/module/_io/test/test_bytesio.py +++ b/pypy/module/_io/test/test_bytesio.py @@ -75,3 +75,19 @@ b = _io.BytesIO("hello") b.close() raises(ValueError, b.readinto, bytearray("hello")) + + def test_readline(self): + import _io + f = _io.BytesIO(b'abc\ndef\nxyzzy\nfoo\x00bar\nanother line') + assert f.readline() == b'abc\n' + assert f.readline(10) == b'def\n' + assert f.readline(2) == b'xy' + assert f.readline(4) == b'zzy\n' + assert f.readline() == b'foo\x00bar\n' + assert f.readline(None) == b'another line' + raises(TypeError, f.readline, 5.3) + + def test_overread(self): + import _io + f = _io.BytesIO(b'abc') + assert f.readline(10) == b'abc' diff --git a/pypy/module/micronumpy/__init__.py b/pypy/module/micronumpy/__init__.py --- a/pypy/module/micronumpy/__init__.py +++ b/pypy/module/micronumpy/__init__.py @@ -1,14 +1,12 @@ from pypy.interpreter.mixedmodule import MixedModule -from pypy.module.micronumpy.interp_boxes import long_double_size +from pypy.module.micronumpy.interp_boxes import long_double_size, ENABLED_LONG_DOUBLE -class Module(MixedModule): - applevel_name = '_numpypy' - +class MultiArrayModule(MixedModule): + appleveldefs = {'arange': 'app_numpy.arange'} interpleveldefs = { 'ndarray': 'interp_numarray.W_NDimArray', 'dtype': 'interp_dtype.W_Dtype', - 'ufunc': 'interp_ufuncs.W_Ufunc', 'array': 'interp_numarray.array', 'zeros': 'interp_numarray.zeros', @@ -18,20 +16,17 @@ 'fromstring': 'interp_support.fromstring', 'flatiter': 'interp_flatiter.W_FlatIterator', 'concatenate': 'interp_arrayops.concatenate', - 'repeat': 'interp_arrayops.repeat', 'where': 'interp_arrayops.where', 'count_nonzero': 'interp_arrayops.count_nonzero', 'set_string_function': 'appbridge.set_string_function', + 'typeinfo': 'interp_dtype.get_dtype_cache(space).w_typeinfo', + } - 'True_': 'types.Bool.True', - 'False_': 'types.Bool.False', - 'bool': 'space.w_bool', - 'int': 'space.w_int', - - 'typeinfo': 'interp_dtype.get_dtype_cache(space).w_typeinfo', - +class NumericTypesModule(MixedModule): + appleveldefs = {} + interpleveldefs = { 'generic': 'interp_boxes.W_GenericBox', 'number': 'interp_boxes.W_NumberBox', 'integer': 'interp_boxes.W_IntegerBox', @@ -62,8 +57,6 @@ 'float16': 'interp_boxes.W_Float16Box', 'float32': 'interp_boxes.W_Float32Box', 'float64': 'interp_boxes.W_Float64Box', - 'longdouble': 'interp_boxes.W_LongDoubleBox', - 'longfloat': 'interp_boxes.W_LongDoubleBox', 'intp': 'types.IntP.BoxType', 'uintp': 'types.UIntP.BoxType', 'flexible': 'interp_boxes.W_FlexibleBox', @@ -76,13 +69,33 @@ 'complex_': 'interp_boxes.W_Complex128Box', 'complex128': 'interp_boxes.W_Complex128Box', 'complex64': 'interp_boxes.W_Complex64Box', - 'clongdouble': 'interp_boxes.W_CLongDoubleBox', - 'clongfloat': 'interp_boxes.W_CLongDoubleBox', } + if ENABLED_LONG_DOUBLE: + long_double_dtypes = [ + ('longdouble', 'interp_boxes.W_LongDoubleBox'), + ('longfloat', 'interp_boxes.W_LongDoubleBox'), + ('clongdouble', 'interp_boxes.W_CLongDoubleBox'), + ('clongfloat', 'interp_boxes.W_CLongDoubleBox'), + ] + if long_double_size == 16: + long_double_dtypes += [ + ('float128', 'interp_boxes.W_Float128Box'), + ('complex256', 'interp_boxes.W_Complex256Box'), + ] + elif long_double_size == 12: + long_double_dtypes += [ + ('float96', 'interp_boxes.W_Float96Box'), + ('complex192', 'interp_boxes.W_Complex192Box'), + ] + for dt, box in long_double_dtypes: + interpleveldefs[dt] = box + +class UMathModule(MixedModule): + appleveldefs = {} + interpleveldefs = {} # ufuncs for exposed, impl in [ - ("abs", "absolute"), ("absolute", "absolute"), ("add", "add"), ("arccos", "arccos"), @@ -162,19 +175,16 @@ ]: interpleveldefs[exposed] = "interp_ufuncs.get(space).%s" % impl - appleveldefs = { - 'average': 'app_numpy.average', - 'sum': 'app_numpy.sum', - 'min': 'app_numpy.min', - 'identity': 'app_numpy.identity', - 'eye': 'app_numpy.eye', - 'max': 'app_numpy.max', - 'arange': 'app_numpy.arange', + +class Module(MixedModule): + applevel_name = '_numpypy' + appleveldefs = {} + interpleveldefs = { + 'choose': 'interp_arrayops.choose', + 'repeat': 'interp_arrayops.repeat', } - -if long_double_size == 16: - Module.interpleveldefs['float128'] = 'interp_boxes.W_Float128Box' - Module.interpleveldefs['complex256'] = 'interp_boxes.W_Complex256Box' -elif long_double_size == 12: - Module.interpleveldefs['float96'] = 'interp_boxes.W_Float96Box' - Module.interpleveldefs['complex192'] = 'interp_boxes.W_Complex192Box' + submodules = { + 'multiarray': MultiArrayModule, + 'numerictypes': NumericTypesModule, + 'umath': UMathModule, + } diff --git a/pypy/module/micronumpy/app_numpy.py b/pypy/module/micronumpy/app_numpy.py --- a/pypy/module/micronumpy/app_numpy.py +++ b/pypy/module/micronumpy/app_numpy.py @@ -2,82 +2,6 @@ import _numpypy -def average(a): - # This implements a weighted average, for now we don't implement the - # weighting, just the average part! - if not hasattr(a, "mean"): - a = _numpypy.array(a) - return a.mean() - -def identity(n, dtype=None): - a = _numpypy.zeros((n, n), dtype=dtype) - for i in range(n): - a[i][i] = 1 - return a - -def eye(n, m=None, k=0, dtype=None): - if m is None: - m = n - a = _numpypy.zeros((n, m), dtype=dtype) - ni = 0 - mi = 0 - - if k < 0: - p = n + k - ni = -k - else: - p = n - k - mi = k - - while ni < n and mi < m: - a[ni][mi] = 1 - ni += 1 - mi += 1 - return a - -def sum(a,axis=None, out=None): - '''sum(a, axis=None) - Sum of array elements over a given axis. - - Parameters - ---------- - a : array_like - Elements to sum. - axis : integer, optional - Axis over which the sum is taken. By default `axis` is None, - and all elements are summed. - - Returns - ------- - sum_along_axis : ndarray - An array with the same shape as `a`, with the specified - axis removed. If `a` is a 0-d array, or if `axis` is None, a scalar - is returned. If an output array is specified, a reference to - `out` is returned. - - See Also - -------- - ndarray.sum : Equivalent method. - ''' - # TODO: add to doc (once it's implemented): cumsum : Cumulative sum of array elements. - if not hasattr(a, "sum"): - a = _numpypy.array(a) - return a.sum(axis=axis, out=out) - -def min(a, axis=None, out=None): - if not hasattr(a, "min"): - a = _numpypy.array(a) - if a.size < 1: - return _numpypy.array([]) - return a.min(axis=axis, out=out) - -def max(a, axis=None, out=None): - if not hasattr(a, "max"): - a = _numpypy.array(a) - if a.size < 1: - return _numpypy.array([]) - return a.max(axis=axis, out=out) - def arange(start, stop=None, step=1, dtype=None): '''arange([start], stop[, step], dtype=None) Generate values in the half-interval [start, stop). @@ -86,9 +10,9 @@ stop = start start = 0 if dtype is None: - test = _numpypy.array([start, stop, step, 0]) + test = _numpypy.multiarray.array([start, stop, step, 0]) dtype = test.dtype - arr = _numpypy.zeros(int(math.ceil((stop - start) / step)), dtype=dtype) + arr = _numpypy.multiarray.zeros(int(math.ceil((stop - start) / step)), dtype=dtype) i = start for j in range(arr.size): arr[j] = i diff --git a/pypy/module/micronumpy/interp_arrayops.py b/pypy/module/micronumpy/interp_arrayops.py --- a/pypy/module/micronumpy/interp_arrayops.py +++ b/pypy/module/micronumpy/interp_arrayops.py @@ -106,33 +106,36 @@ args_w = [convert_to_array(space, w_arg) for w_arg in args_w] dtype = args_w[0].get_dtype() shape = args_w[0].get_shape()[:] - if len(shape) <= axis: + _axis = axis + if axis < 0: + _axis = len(shape) + axis + if _axis < 0 or len(shape) <= _axis: raise operationerrfmt(space.w_IndexError, "axis %d out of bounds [0, %d)", axis, len(shape)) for arr in args_w[1:]: dtype = interp_ufuncs.find_binop_result_dtype(space, dtype, arr.get_dtype()) - if len(arr.get_shape()) <= axis: + if _axis < 0 or len(arr.get_shape()) <= _axis: raise operationerrfmt(space.w_IndexError, "axis %d out of bounds [0, %d)", axis, len(shape)) for i, axis_size in enumerate(arr.get_shape()): - if len(arr.get_shape()) != len(shape) or (i != axis and axis_size != shape[i]): + if len(arr.get_shape()) != len(shape) or (i != _axis and axis_size != shape[i]): raise OperationError(space.w_ValueError, space.wrap( "all the input arrays must have same number of dimensions")) - elif i == axis: + elif i == _axis: shape[i] += axis_size res = W_NDimArray.from_shape(shape, dtype, 'C') chunks = [Chunk(0, i, 1, i) for i in shape] axis_start = 0 for arr in args_w: - if arr.get_shape()[axis] == 0: + if arr.get_shape()[_axis] == 0: continue - chunks[axis] = Chunk(axis_start, axis_start + arr.get_shape()[axis], 1, - arr.get_shape()[axis]) + chunks[_axis] = Chunk(axis_start, axis_start + arr.get_shape()[_axis], 1, + arr.get_shape()[_axis]) Chunks(chunks).apply(res).implementation.setslice(space, arr) - axis_start += arr.get_shape()[axis] + axis_start += arr.get_shape()[_axis] return res @unwrap_spec(repeats=int) -def repeat(space, w_arr, repeats, w_axis=None): +def repeat(space, w_arr, repeats, w_axis): arr = convert_to_array(space, w_arr) if space.is_none(w_axis): arr = arr.descr_flatten(space) @@ -158,14 +161,21 @@ def count_nonzero(space, w_obj): return space.wrap(loop.count_all_true(convert_to_array(space, w_obj))) -def choose(space, arr, w_choices, out, mode): + at unwrap_spec(mode=str) +def choose(space, w_arr, w_choices, w_out, mode): + arr = convert_to_array(space, w_arr) choices = [convert_to_array(space, w_item) for w_item in space.listview(w_choices)] if not choices: raise OperationError(space.w_ValueError, space.wrap("choices list cannot be empty")) - shape = shape_agreement_multiple(space, choices + [out]) - out = interp_dtype.dtype_agreement(space, choices, shape, out) + if space.is_none(w_out): + w_out = None + elif not isinstance(w_out, W_NDimArray): + raise OperationError(space.w_TypeError, space.wrap( + "return arrays must be of ArrayType")) + shape = shape_agreement_multiple(space, choices + [w_out]) + out = interp_dtype.dtype_agreement(space, choices, shape, w_out) dtype = out.get_dtype() if mode not in MODES: raise OperationError(space.w_ValueError, diff --git a/pypy/module/micronumpy/interp_boxes.py b/pypy/module/micronumpy/interp_boxes.py --- a/pypy/module/micronumpy/interp_boxes.py +++ b/pypy/module/micronumpy/interp_boxes.py @@ -16,10 +16,12 @@ MIXIN_64 = (int_typedef,) if LONG_BIT == 64 else () # Is this the proper place for this? +ENABLED_LONG_DOUBLE = False long_double_size = rffi.sizeof_c_type('long double', ignore_errors=True) + import os if long_double_size == 8 and os.name == 'nt': - # this is a lie, or maybe a wish + # this is a lie, or maybe a wish, MS fakes longdouble math with double long_double_size = 12 @@ -335,7 +337,7 @@ descr__new__, _get_dtype = new_dtype_getter("complex128") _COMPONENTS_BOX = W_Float64Box -if long_double_size == 12: +if ENABLED_LONG_DOUBLE and long_double_size == 12: class W_Float96Box(W_FloatingBox, PrimitiveBox): descr__new__, _get_dtype = new_dtype_getter("float96") @@ -347,7 +349,7 @@ W_CLongDoubleBox = W_Complex192Box -elif long_double_size == 16: +elif ENABLED_LONG_DOUBLE and long_double_size == 16: class W_Float128Box(W_FloatingBox, PrimitiveBox): descr__new__, _get_dtype = new_dtype_getter("float128") W_LongDoubleBox = W_Float128Box @@ -358,7 +360,7 @@ W_CLongDoubleBox = W_Complex256Box -else: +elif ENABLED_LONG_DOUBLE: W_LongDoubleBox = W_Float64Box W_CLongDoubleBox = W_Complex64Box @@ -526,7 +528,7 @@ __new__ = interp2app(W_Float64Box.descr__new__.im_func), ) -if long_double_size == 12: +if ENABLED_LONG_DOUBLE and long_double_size == 12: W_Float96Box.typedef = TypeDef("float96", (W_FloatingBox.typedef), __module__ = "numpypy", @@ -540,7 +542,7 @@ imag = GetSetProperty(W_ComplexFloatingBox.descr_get_imag), ) -elif long_double_size == 16: +elif ENABLED_LONG_DOUBLE and long_double_size == 16: W_Float128Box.typedef = TypeDef("float128", (W_FloatingBox.typedef), __module__ = "numpypy", diff --git a/pypy/module/micronumpy/interp_dtype.py b/pypy/module/micronumpy/interp_dtype.py --- a/pypy/module/micronumpy/interp_dtype.py +++ b/pypy/module/micronumpy/interp_dtype.py @@ -164,8 +164,11 @@ def is_record_type(self): return self.fields is not None + def is_str_or_unicode(self): + return (self.num == 18 or self.num == 19) + def is_flexible_type(self): - return (self.num == 18 or self.num == 19 or self.num == 20) + return (self.is_str_or_unicode() or self.is_record_type()) def __repr__(self): if self.fields is not None: @@ -474,7 +477,7 @@ aliases=["complex"], float_type = self.w_float64dtype, ) - if interp_boxes.long_double_size == 12: + if interp_boxes.ENABLED_LONG_DOUBLE and interp_boxes.long_double_size == 12: self.w_float96dtype = W_Dtype( types.Float96(), num=13, @@ -497,7 +500,7 @@ ) self.w_longdouble = self.w_float96dtype self.w_clongdouble = self.w_complex192dtype - elif interp_boxes.long_double_size == 16: + elif interp_boxes.ENABLED_LONG_DOUBLE and interp_boxes.long_double_size == 16: self.w_float128dtype = W_Dtype( types.Float128(), num=13, @@ -520,13 +523,13 @@ ) self.w_longdouble = self.w_float128dtype self.w_clongdouble = self.w_complex256dtype - else: + elif interp_boxes.ENABLED_LONG_DOUBLE: self.w_float64dtype.aliases += ["longdouble", "longfloat"] self.w_complex128dtype.aliases += ["clongdouble", "clongfloat"] self.w_longdouble = self.w_float64dtype self.w_clongdouble = self.w_complex128dtype self.w_stringdtype = W_Dtype( - types.StringType(1), + types.StringType(0), num=18, kind=STRINGLTR, name='string', @@ -596,23 +599,27 @@ char=UINTPLTR, w_box_type = space.gettypefor(uintp_box), ) + float_dtypes = [self.w_float16dtype, + self.w_float32dtype, self.w_float64dtype, + ] + complex_dtypes = [self.w_complex64dtype, self.w_complex128dtype] + if interp_boxes.ENABLED_LONG_DOUBLE: + float_dtypes.append(self.w_longdouble) + complex_dtypes.append(self.w_clongdouble) self.builtin_dtypes = [ self.w_booldtype, self.w_int8dtype, self.w_uint8dtype, self.w_int16dtype, self.w_uint16dtype, self.w_longdtype, self.w_ulongdtype, self.w_int32dtype, self.w_uint32dtype, - self.w_int64dtype, self.w_uint64dtype, - self.w_float16dtype, - self.w_float32dtype, self.w_float64dtype, self.w_longdouble, - self.w_complex64dtype, self.w_complex128dtype, self.w_clongdouble, + self.w_int64dtype, self.w_uint64dtype] + \ + float_dtypes + complex_dtypes + [ self.w_stringdtype, self.w_unicodedtype, self.w_voiddtype, self.w_intpdtype, self.w_uintpdtype, ] self.float_dtypes_by_num_bytes = sorted( (dtype.itemtype.get_element_size(), dtype) - for dtype in [self.w_float16dtype, self.w_float32dtype, - self.w_float64dtype, self.w_longdouble] + for dtype in float_dtypes ) self.dtypes_by_num = {} self.dtypes_by_name = {} @@ -655,7 +662,6 @@ 'LONGLONG': self.w_int64dtype, 'SHORT': self.w_int16dtype, 'VOID': self.w_voiddtype, - 'LONGDOUBLE': self.w_longdouble, 'UBYTE': self.w_uint8dtype, 'UINTP': self.w_ulongdtype, 'ULONG': self.w_ulongdtype, @@ -678,8 +684,11 @@ 'USHORT': self.w_uint16dtype, 'FLOAT': self.w_float32dtype, 'BOOL': self.w_booldtype, - 'CLONGDOUBLE': self.w_clongdouble, } + if interp_boxes.ENABLED_LONG_DOUBLE: + typeinfo_full['LONGDOUBLE'] = self.w_longdouble + typeinfo_full['CLONGDOUBLE'] = self.w_clongdouble + typeinfo_partial = { 'Generic': interp_boxes.W_GenericBox, 'Character': interp_boxes.W_CharacterBox, diff --git a/pypy/module/micronumpy/interp_numarray.py b/pypy/module/micronumpy/interp_numarray.py --- a/pypy/module/micronumpy/interp_numarray.py +++ b/pypy/module/micronumpy/interp_numarray.py @@ -14,7 +14,7 @@ from pypy.module.micronumpy.appbridge import get_appbridge_cache from pypy.module.micronumpy import loop from pypy.module.micronumpy.dot import match_dot_shapes From noreply at buildbot.pypy.org Mon Feb 25 23:12:17 2013 From: noreply at buildbot.pypy.org (mattip) Date: Mon, 25 Feb 2013 23:12:17 +0100 (CET) Subject: [pypy-commit] pypy numpy-unify-methods: document about-to-be-merged branch Message-ID: <20130225221217.DECAD1C0EEA@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: numpy-unify-methods Changeset: r61798:daae747268b1 Date: 2013-02-25 23:17 +0200 http://bitbucket.org/pypy/pypy/changeset/daae747268b1/ Log: document about-to-be-merged branch diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst --- a/pypy/doc/whatsnew-head.rst +++ b/pypy/doc/whatsnew-head.rst @@ -39,6 +39,7 @@ .. branch: task-decorator .. branch: fix-e4fa0b2 .. branch: win32-fixes +.. branch: numpy-unify-methods .. branch: fix-version-tool .. branch: popen2-removal diff --git a/pypy/module/micronumpy/test/test_ufuncs.py b/pypy/module/micronumpy/test/test_ufuncs.py --- a/pypy/module/micronumpy/test/test_ufuncs.py +++ b/pypy/module/micronumpy/test/test_ufuncs.py @@ -83,13 +83,14 @@ assert min_c_b[i] == min(b[i], c) def test_scalar(self): - # tests that calling all available ufuncs on scalars, none will - # raise uncaught interp-level exceptions, + # tests that by calling all available ufuncs on scalars, none will + # raise uncaught interp-level exceptions, (and crash the test) # and those that are uncallable can be accounted for. - import _numpypy as np + # test on the four base-class dtypes: int, bool, float, complex + # We need this test since they have no common base class. + import numpypy as np def find_uncallable_ufuncs(v): uncallable = [] - i = 0 for s in dir(np): u = getattr(np, s) if isinstance(u, np.ufunc) and u.nin < 2: @@ -98,7 +99,12 @@ except TypeError: #assert e.message.startswith('ufunc') uncallable.append(s) - i+= 1 + elif isinstance(u, np.ufunc) and u.nin ==2: + try: + u(a, a) + except TypeError: + #assert e.message.startswith('ufunc') + uncallable.append(s) return uncallable a = np.array(0,'int64') uncallable = find_uncallable_ufuncs(a) @@ -118,7 +124,7 @@ 'trunc']) def test_int_only(self): - from _numpypy import bitwise_and, array + from numpypy import bitwise_and, array a = array(1.0) raises(TypeError, bitwise_and, a, a) From noreply at buildbot.pypy.org Mon Feb 25 23:12:19 2013 From: noreply at buildbot.pypy.org (mattip) Date: Mon, 25 Feb 2013 23:12:19 +0100 (CET) Subject: [pypy-commit] pypy numpy-unify-methods: close branch before merge Message-ID: <20130225221219.12FE31C0EEA@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: numpy-unify-methods Changeset: r61799:01e4682ce898 Date: 2013-02-25 23:18 +0200 http://bitbucket.org/pypy/pypy/changeset/01e4682ce898/ Log: close branch before merge From noreply at buildbot.pypy.org Mon Feb 25 23:12:20 2013 From: noreply at buildbot.pypy.org (mattip) Date: Mon, 25 Feb 2013 23:12:20 +0100 (CET) Subject: [pypy-commit] pypy default: merge numpy-unify-methods which checks that there exists an implementation or an exception for all single-arg ufuncs on all base numpypy dtypes, and implements the missing ones Message-ID: <20130225221220.36DFD1C0EEA@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: Changeset: r61800:f5a6f7eb7622 Date: 2013-02-25 23:20 +0200 http://bitbucket.org/pypy/pypy/changeset/f5a6f7eb7622/ Log: merge numpy-unify-methods which checks that there exists an implementation or an exception for all single-arg ufuncs on all base numpypy dtypes, and implements the missing ones diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst --- a/pypy/doc/whatsnew-head.rst +++ b/pypy/doc/whatsnew-head.rst @@ -39,6 +39,7 @@ .. branch: task-decorator .. branch: fix-e4fa0b2 .. branch: win32-fixes +.. branch: numpy-unify-methods .. branch: fix-version-tool .. branch: popen2-removal diff --git a/pypy/module/micronumpy/interp_ufuncs.py b/pypy/module/micronumpy/interp_ufuncs.py --- a/pypy/module/micronumpy/interp_ufuncs.py +++ b/pypy/module/micronumpy/interp_ufuncs.py @@ -258,6 +258,9 @@ if w_obj.get_dtype().is_flexible_type(): raise OperationError(space.w_TypeError, space.wrap('Not implemented for this type')) + if self.int_only and not w_obj.get_dtype().is_int_type(): + raise OperationError(space.w_TypeError, space.wrap( + "ufunc %s not supported for the input type" % self.name)) calc_dtype = find_unaryop_result_dtype(space, w_obj.get_dtype(), promote_to_float=self.promote_to_float, @@ -337,6 +340,9 @@ promote_bools=self.promote_bools, allow_complex=self.allow_complex, ) + if self.int_only and not calc_dtype.is_int_type(): + raise OperationError(space.w_TypeError, space.wrap( + "ufunc '%s' not supported for the input types" % self.name)) if space.is_none(w_out): out = None elif not isinstance(w_out, W_NDimArray): diff --git a/pypy/module/micronumpy/test/test_ufuncs.py b/pypy/module/micronumpy/test/test_ufuncs.py --- a/pypy/module/micronumpy/test/test_ufuncs.py +++ b/pypy/module/micronumpy/test/test_ufuncs.py @@ -82,6 +82,52 @@ for i in range(3): assert min_c_b[i] == min(b[i], c) + def test_scalar(self): + # tests that by calling all available ufuncs on scalars, none will + # raise uncaught interp-level exceptions, (and crash the test) + # and those that are uncallable can be accounted for. + # test on the four base-class dtypes: int, bool, float, complex + # We need this test since they have no common base class. + import numpypy as np + def find_uncallable_ufuncs(v): + uncallable = [] + for s in dir(np): + u = getattr(np, s) + if isinstance(u, np.ufunc) and u.nin < 2: + try: + u(a) + except TypeError: + #assert e.message.startswith('ufunc') + uncallable.append(s) + elif isinstance(u, np.ufunc) and u.nin ==2: + try: + u(a, a) + except TypeError: + #assert e.message.startswith('ufunc') + uncallable.append(s) + return uncallable + a = np.array(0,'int64') + uncallable = find_uncallable_ufuncs(a) + assert len(uncallable) == 0 + a = np.array(True,'bool') + uncallable = find_uncallable_ufuncs(a) + assert len(uncallable) == 0 or uncallable == ['sign'] # numpy 1.7.0 + a = np.array(1.0,'float') + uncallable = find_uncallable_ufuncs(a) + assert len(uncallable) == 2 and set(uncallable) == set(['bitwise_not', 'invert']) + a = np.array(1.0,'complex') + uncallable = find_uncallable_ufuncs(a) + assert len(uncallable) == 13 + assert set(uncallable) == \ + set(['bitwise_not', 'ceil', 'deg2rad', 'degrees', 'fabs', 'floor', + 'rad2deg', 'invert', 'isneginf', 'isposinf', 'radians', 'signbit', + 'trunc']) + + def test_int_only(self): + from numpypy import bitwise_and, array + a = array(1.0) + raises(TypeError, bitwise_and, a, a) + def test_negative(self): from numpypy import array, negative @@ -249,13 +295,16 @@ assert (a == ref).all() def test_signbit(self): - from numpypy import signbit + from numpypy import signbit, add assert (signbit([0, 0.0, 1, 1.0, float('inf')]) == [False, False, False, False, False]).all() assert (signbit([-0, -0.0, -1, -1.0, float('-inf')]) == [False, True, True, True, True]).all() + a = add.identity + assert signbit(a) == False + skip('sign of nan is non-determinant') assert (signbit([float('nan'), float('-nan'), -float('nan')]) == [False, True, True]).all() diff --git a/pypy/module/micronumpy/types.py b/pypy/module/micronumpy/types.py --- a/pypy/module/micronumpy/types.py +++ b/pypy/module/micronumpy/types.py @@ -7,6 +7,7 @@ from pypy.objspace.std.floatobject import float2string from pypy.objspace.std.complexobject import str_format from rpython.rlib import rfloat, clibffi, rcomplex +from rpython.rlib.rarithmetic import maxint from rpython.rlib.rawstorage import (alloc_raw_storage, raw_storage_setitem, raw_storage_getitem) from rpython.rlib.objectmodel import specialize @@ -375,6 +376,20 @@ def invert(self, v): return ~v + @raw_unary_op + def isfinite(self, v): + return True + + @raw_unary_op + def signbit(self, v): + return False + + @simple_unary_op + def reciprocal(self, v): + if v: + return 1 + return 0 + NonNativeBool = Bool class Integer(Primitive): @@ -479,6 +494,17 @@ def invert(self, v): return ~v + @simple_unary_op + def reciprocal(self, v): + if v == 0: + # XXX good place to warn + return -maxint + return 1 / v + + @raw_unary_op + def signbit(self, v): + return v < 0 + class NonNativeInteger(NonNativePrimitive, Integer): _mixin_ = True From noreply at buildbot.pypy.org Mon Feb 25 23:12:21 2013 From: noreply at buildbot.pypy.org (mattip) Date: Mon, 25 Feb 2013 23:12:21 +0100 (CET) Subject: [pypy-commit] pypy default: test, implement left, right shift for bool, update test_scalar to reflect added functions Message-ID: <20130225221221.5A4F81C0EEA@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: Changeset: r61801:99bdc2da85bd Date: 2013-02-25 23:49 +0200 http://bitbucket.org/pypy/pypy/changeset/99bdc2da85bd/ Log: test, implement left,right shift for bool, update test_scalar to reflect added functions diff --git a/pypy/module/micronumpy/test/test_ufuncs.py b/pypy/module/micronumpy/test/test_ufuncs.py --- a/pypy/module/micronumpy/test/test_ufuncs.py +++ b/pypy/module/micronumpy/test/test_ufuncs.py @@ -114,14 +114,17 @@ assert len(uncallable) == 0 or uncallable == ['sign'] # numpy 1.7.0 a = np.array(1.0,'float') uncallable = find_uncallable_ufuncs(a) - assert len(uncallable) == 2 and set(uncallable) == set(['bitwise_not', 'invert']) + assert len(uncallable) == 7 and set(uncallable) == set( + ['bitwise_xor', 'bitwise_not', 'invert', 'left_shift', 'bitwise_or', + 'bitwise_and', 'right_shift']) a = np.array(1.0,'complex') uncallable = find_uncallable_ufuncs(a) - assert len(uncallable) == 13 - assert set(uncallable) == \ - set(['bitwise_not', 'ceil', 'deg2rad', 'degrees', 'fabs', 'floor', - 'rad2deg', 'invert', 'isneginf', 'isposinf', 'radians', 'signbit', - 'trunc']) + assert len(uncallable) == 23 + assert set(uncallable) == set(['arctan2', 'bitwise_and', 'bitwise_not', + 'bitwise_or', 'bitwise_xor', 'ceil', 'copysign', 'deg2rad', + 'degrees', 'fabs', 'floor', 'fmod', 'invert', 'isneginf', + 'isposinf', 'left_shift', 'logaddexp', 'logaddexp2', 'rad2deg', + 'radians', 'right_shift', 'signbit', 'trunc']) def test_int_only(self): from numpypy import bitwise_and, array @@ -674,10 +677,12 @@ assert (invert(a) == ~a).all() def test_shift(self): - from numpypy import left_shift, right_shift + from numpypy import left_shift, right_shift, bool assert (left_shift([5, 1], [2, 13]) == [20, 2**13]).all() assert (right_shift(10, range(5)) == [10, 5, 2, 1, 0]).all() + assert left_shift(bool(1), 3) == left_shift(1, 3) + assert right_shift(bool(1), 3) == right_shift(1, 3) def test_comparisons(self): import operator diff --git a/pypy/module/micronumpy/types.py b/pypy/module/micronumpy/types.py --- a/pypy/module/micronumpy/types.py +++ b/pypy/module/micronumpy/types.py @@ -361,6 +361,14 @@ return self.box(True) @simple_binary_op + def lshift(self, v1, v2): + return v1 << v2 + + @simple_binary_op + def rshift(self, v1, v2): + return v1 >> v2 + + @simple_binary_op def bitwise_and(self, v1, v2): return v1 & v2 From noreply at buildbot.pypy.org Mon Feb 25 23:12:22 2013 From: noreply at buildbot.pypy.org (mattip) Date: Mon, 25 Feb 2013 23:12:22 +0100 (CET) Subject: [pypy-commit] pypy default: clean up, fix for -A with numpy Message-ID: <20130225221222.8CD501C0EEA@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: Changeset: r61802:3e276f022ea4 Date: 2013-02-26 00:09 +0200 http://bitbucket.org/pypy/pypy/changeset/3e276f022ea4/ Log: clean up, fix for -A with numpy diff --git a/pypy/module/micronumpy/test/test_ufuncs.py b/pypy/module/micronumpy/test/test_ufuncs.py --- a/pypy/module/micronumpy/test/test_ufuncs.py +++ b/pypy/module/micronumpy/test/test_ufuncs.py @@ -1,18 +1,14 @@ from pypy.conftest import option from pypy.interpreter.gateway import interp2app from pypy.module.micronumpy.test.test_base import BaseNumpyAppTest -from rpython.rlib.rcomplex import c_pow class AppTestUfuncs(BaseNumpyAppTest): def setup_class(cls): - import os + import os, sys BaseNumpyAppTest.setup_class.im_func(cls) - - def cls_c_pow(space, args_w): - return space.wrap(c_pow(*map(space.unwrap, args_w))) - cls.w_c_pow = cls.space.wrap(interp2app(cls_c_pow)) - cls.w_runAppDirect = cls.space.wrap(option.runappdirect) + cls.w_isNumpy = cls.space.wrap(option.runappdirect \ + and '__pypy__' not in sys.builtin_module_names) cls.w_isWindows = cls.space.wrap(os.name == 'nt') def test_ufunc_instance(self): @@ -114,17 +110,20 @@ assert len(uncallable) == 0 or uncallable == ['sign'] # numpy 1.7.0 a = np.array(1.0,'float') uncallable = find_uncallable_ufuncs(a) - assert len(uncallable) == 7 and set(uncallable) == set( + if not self.isNumpy: + assert len(uncallable) == 7 and set(uncallable) == set( ['bitwise_xor', 'bitwise_not', 'invert', 'left_shift', 'bitwise_or', 'bitwise_and', 'right_shift']) a = np.array(1.0,'complex') uncallable = find_uncallable_ufuncs(a) - assert len(uncallable) == 23 - assert set(uncallable) == set(['arctan2', 'bitwise_and', 'bitwise_not', - 'bitwise_or', 'bitwise_xor', 'ceil', 'copysign', 'deg2rad', - 'degrees', 'fabs', 'floor', 'fmod', 'invert', 'isneginf', - 'isposinf', 'left_shift', 'logaddexp', 'logaddexp2', 'rad2deg', - 'radians', 'right_shift', 'signbit', 'trunc']) + if not self.isNumpy: + assert len(uncallable) == 23 + assert set(uncallable) == set(['arctan2', 'bitwise_and', + 'bitwise_not', 'bitwise_or', 'bitwise_xor', 'ceil', + 'copysign', 'deg2rad', 'degrees', 'fabs', 'floor', 'fmod', + 'invert', 'isneginf', 'isposinf', 'left_shift', 'logaddexp', + 'logaddexp2', 'rad2deg', 'radians', 'right_shift', + 'signbit', 'trunc']) def test_int_only(self): from numpypy import bitwise_and, array From noreply at buildbot.pypy.org Mon Feb 25 23:12:23 2013 From: noreply at buildbot.pypy.org (mattip) Date: Mon, 25 Feb 2013 23:12:23 +0100 (CET) Subject: [pypy-commit] pypy default: merge heads Message-ID: <20130225221223.BDB321C0EEA@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: Changeset: r61803:28e14e2cba5a Date: 2013-02-26 00:10 +0200 http://bitbucket.org/pypy/pypy/changeset/28e14e2cba5a/ Log: merge heads diff --git a/pypy/goal/multibuild.py b/pypy/goal/multibuild.py deleted file mode 100644 --- a/pypy/goal/multibuild.py +++ /dev/null @@ -1,127 +0,0 @@ -from pypy.config.pypyoption import get_pypy_config -from rpython.translator.goal import translate -from rpython.translator.goal import targetpypystandalone -from rpython.translator.driver import TranslationDriver -import os, sys, traceback, random - -def longoptfromname(config, name): - from pypy.config.makerestdoc import get_cmdline - # begin horror - h, n = config._cfgimpl_get_home_by_path(name) - opt = getattr(h._cfgimpl_descr, n) - # end horror - cmdline = get_cmdline(opt.cmdline, name) - assert cmdline is not None - shortest_long_option = 'X'*1000 - for cmd in cmdline.split(): - if cmd.startswith('--') and len(cmd) < len(shortest_long_option): - shortest_long_option = cmd - return shortest_long_option - -def exe_name_from_options(config, opts): - from pypy.module.sys.version import svn_revision - - backend = config.translation.backend - if not backend: - backend = 'c' - rev = svn_revision() - - nameparts = [] - - for opt, v in opts.iteritems(): - if opt == 'translation.backend': - backend = v - optname = longoptfromname(config, opt).strip('-') - if v is False: - optname = 'no-' + optname - elif v is not True: - optname += '=' + str(v) - nameparts.append(optname) - - suffix = '' - if nameparts: - def k(s): - if s.startswith('no-'): - return s[3:] - else: - return s - nameparts.sort(key=k) - suffix = '-' + '-'.join(nameparts) - - return 'pypy-%s-%d%s'%(backend, rev, suffix) - -def _build(config, exe_name): - driver = TranslationDriver.from_targetspec( - targetpypystandalone.__dict__, - config=config) - driver.exe_name = exe_name - driver.compile() - -def build_pypy_with_options(basedir, opts): - config = get_pypy_config(translate.OVERRIDES, translating=True) - - try: - config.set(**opts) - except: - return exe_name_from_options(config, opts), "didn't configure" - - exe_name = os.path.join(basedir, exe_name_from_options(config, opts)) - - print exe_name, - sys.stdout.flush() - - pid = os.fork() - - if pid == 0: - logfile = open(exe_name + '-log', 'w') - davenull = os.open('/dev/null', os.O_RDONLY) - os.dup2(davenull, 0) - os.dup2(logfile.fileno(), 1) - os.dup2(logfile.fileno(), 2) - try: - try: - r = _build(config, exe_name) - finally: - logfile.close() - except: - os._exit(1) - else: - os._exit(0) - else: - pid, status = os.waitpid(pid, 0) - if status: - r = 'failed' - else: - r = 'succeeded' - print r - return exe_name, r - -def get_options(fname): - def gen_opts(sofar, remaining): - if not remaining: - yield sofar - else: - for (k, v) in remaining[0]: - d2 = sofar.copy() - d2[k] = v - for d in gen_opts(d2, remaining[1:]): - yield d - options = [] - for line in open(fname): - l = [] - optname, options_ = line.split(':') - options.append([(optname.strip(), eval(optval.strip())) for optval in options_.split(',')]) - return gen_opts({}, options) - - -if __name__ == '__main__': - basedir = sys.argv[1] - optionsfile = sys.argv[2] - results = [] - options = list(get_options(optionsfile)) - random.shuffle(options) - for opts in options: - results.append(build_pypy_with_options(basedir, opts)) - out = open(os.path.join(basedir, 'results'), 'w') - for exe, r in results: - print >>out, exe, r From noreply at buildbot.pypy.org Tue Feb 26 03:36:44 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Tue, 26 Feb 2013 03:36:44 +0100 (CET) Subject: [pypy-commit] pypy default: clean up test_scalar Message-ID: <20130226023644.774C41C0237@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61805:0a070be207fc Date: 2013-02-25 21:20 -0500 http://bitbucket.org/pypy/pypy/changeset/0a070be207fc/ Log: clean up test_scalar diff --git a/pypy/module/micronumpy/test/test_ufuncs.py b/pypy/module/micronumpy/test/test_ufuncs.py --- a/pypy/module/micronumpy/test/test_ufuncs.py +++ b/pypy/module/micronumpy/test/test_ufuncs.py @@ -5,11 +5,10 @@ class AppTestUfuncs(BaseNumpyAppTest): def setup_class(cls): - import os, sys + import sys BaseNumpyAppTest.setup_class.im_func(cls) cls.w_isNumpy = cls.space.wrap(option.runappdirect \ and '__pypy__' not in sys.builtin_module_names) - cls.w_isWindows = cls.space.wrap(os.name == 'nt') def test_ufunc_instance(self): from numpypy import add, ufunc @@ -85,45 +84,29 @@ # test on the four base-class dtypes: int, bool, float, complex # We need this test since they have no common base class. import numpypy as np - def find_uncallable_ufuncs(v): - uncallable = [] + def find_uncallable_ufuncs(a): + uncallable = set() for s in dir(np): u = getattr(np, s) - if isinstance(u, np.ufunc) and u.nin < 2: + if isinstance(u, np.ufunc): try: - u(a) + u(* [a] * u.nin) except TypeError: - #assert e.message.startswith('ufunc') - uncallable.append(s) - elif isinstance(u, np.ufunc) and u.nin ==2: - try: - u(a, a) - except TypeError: - #assert e.message.startswith('ufunc') - uncallable.append(s) + assert s not in uncallable + uncallable.add(s) return uncallable - a = np.array(0,'int64') - uncallable = find_uncallable_ufuncs(a) - assert len(uncallable) == 0 - a = np.array(True,'bool') - uncallable = find_uncallable_ufuncs(a) - assert len(uncallable) == 0 or uncallable == ['sign'] # numpy 1.7.0 - a = np.array(1.0,'float') - uncallable = find_uncallable_ufuncs(a) + assert find_uncallable_ufuncs(np.array(1, 'int')) == set() if not self.isNumpy: - assert len(uncallable) == 7 and set(uncallable) == set( - ['bitwise_xor', 'bitwise_not', 'invert', 'left_shift', 'bitwise_or', - 'bitwise_and', 'right_shift']) - a = np.array(1.0,'complex') - uncallable = find_uncallable_ufuncs(a) - if not self.isNumpy: - assert len(uncallable) == 23 - assert set(uncallable) == set(['arctan2', 'bitwise_and', - 'bitwise_not', 'bitwise_or', 'bitwise_xor', 'ceil', - 'copysign', 'deg2rad', 'degrees', 'fabs', 'floor', 'fmod', - 'invert', 'isneginf', 'isposinf', 'left_shift', 'logaddexp', - 'logaddexp2', 'rad2deg', 'radians', 'right_shift', - 'signbit', 'trunc']) + assert find_uncallable_ufuncs(np.array(1, 'bool')) == set() + assert find_uncallable_ufuncs(np.array(1, 'float')) == set( + ['bitwise_and', 'bitwise_not', 'bitwise_or', 'bitwise_xor', + 'left_shift', 'right_shift', 'invert']) + assert find_uncallable_ufuncs(np.array(1, 'complex')) == set( + ['bitwise_and', 'bitwise_not', 'bitwise_or', 'bitwise_xor', + 'arctan2', 'deg2rad', 'degrees', 'rad2deg', 'radians', + 'fabs', 'fmod', 'invert', 'isneginf', 'isposinf', + 'logaddexp', 'logaddexp2', 'left_shift', 'right_shift', + 'copysign', 'signbit', 'ceil', 'floor', 'trunc']) def test_int_only(self): from numpypy import bitwise_and, array @@ -864,7 +847,7 @@ b = floor_divide(a, 2.5) for i in range(len(a)): assert b[i] == a[i] // 2.5 - + a = array([10+10j, -15-100j, 0+10j], dtype=complex) b = floor_divide(a, 2.5) for i in range(len(a)): From noreply at buildbot.pypy.org Tue Feb 26 03:36:45 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Tue, 26 Feb 2013 03:36:45 +0100 (CET) Subject: [pypy-commit] pypy default: don't special case this for -A, we want to see when behavior differs Message-ID: <20130226023645.A3ACB1C0237@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61806:4229fcf77d6f Date: 2013-02-25 21:09 -0500 http://bitbucket.org/pypy/pypy/changeset/4229fcf77d6f/ Log: don't special case this for -A, we want to see when behavior differs diff --git a/pypy/module/micronumpy/test/test_ufuncs.py b/pypy/module/micronumpy/test/test_ufuncs.py --- a/pypy/module/micronumpy/test/test_ufuncs.py +++ b/pypy/module/micronumpy/test/test_ufuncs.py @@ -4,12 +4,6 @@ class AppTestUfuncs(BaseNumpyAppTest): - def setup_class(cls): - import sys - BaseNumpyAppTest.setup_class.im_func(cls) - cls.w_isNumpy = cls.space.wrap(option.runappdirect \ - and '__pypy__' not in sys.builtin_module_names) - def test_ufunc_instance(self): from numpypy import add, ufunc @@ -96,17 +90,16 @@ uncallable.add(s) return uncallable assert find_uncallable_ufuncs(np.array(1, 'int')) == set() - if not self.isNumpy: - assert find_uncallable_ufuncs(np.array(1, 'bool')) == set() - assert find_uncallable_ufuncs(np.array(1, 'float')) == set( - ['bitwise_and', 'bitwise_not', 'bitwise_or', 'bitwise_xor', - 'left_shift', 'right_shift', 'invert']) - assert find_uncallable_ufuncs(np.array(1, 'complex')) == set( - ['bitwise_and', 'bitwise_not', 'bitwise_or', 'bitwise_xor', - 'arctan2', 'deg2rad', 'degrees', 'rad2deg', 'radians', - 'fabs', 'fmod', 'invert', 'isneginf', 'isposinf', - 'logaddexp', 'logaddexp2', 'left_shift', 'right_shift', - 'copysign', 'signbit', 'ceil', 'floor', 'trunc']) + assert find_uncallable_ufuncs(np.array(1, 'bool')) == set() + assert find_uncallable_ufuncs(np.array(1, 'float')) == set( + ['bitwise_and', 'bitwise_not', 'bitwise_or', 'bitwise_xor', + 'left_shift', 'right_shift', 'invert']) + assert find_uncallable_ufuncs(np.array(1, 'complex')) == set( + ['bitwise_and', 'bitwise_not', 'bitwise_or', 'bitwise_xor', + 'arctan2', 'deg2rad', 'degrees', 'rad2deg', 'radians', + 'fabs', 'fmod', 'invert', 'isneginf', 'isposinf', + 'logaddexp', 'logaddexp2', 'left_shift', 'right_shift', + 'copysign', 'signbit', 'ceil', 'floor', 'trunc']) def test_int_only(self): from numpypy import bitwise_and, array From noreply at buildbot.pypy.org Tue Feb 26 03:42:44 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Tue, 26 Feb 2013 03:42:44 +0100 (CET) Subject: [pypy-commit] pypy default: more small cleanups for test_scalar Message-ID: <20130226024244.205941C0327@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61807:c9510e3d722e Date: 2013-02-25 21:42 -0500 http://bitbucket.org/pypy/pypy/changeset/c9510e3d722e/ Log: more small cleanups for test_scalar diff --git a/pypy/module/micronumpy/test/test_ufuncs.py b/pypy/module/micronumpy/test/test_ufuncs.py --- a/pypy/module/micronumpy/test/test_ufuncs.py +++ b/pypy/module/micronumpy/test/test_ufuncs.py @@ -78,23 +78,24 @@ # test on the four base-class dtypes: int, bool, float, complex # We need this test since they have no common base class. import numpypy as np - def find_uncallable_ufuncs(a): + def find_uncallable_ufuncs(dtype): uncallable = set() + array = np.array(1, dtype) for s in dir(np): u = getattr(np, s) if isinstance(u, np.ufunc): try: - u(* [a] * u.nin) + u(* [array] * u.nin) except TypeError: assert s not in uncallable uncallable.add(s) return uncallable - assert find_uncallable_ufuncs(np.array(1, 'int')) == set() - assert find_uncallable_ufuncs(np.array(1, 'bool')) == set() - assert find_uncallable_ufuncs(np.array(1, 'float')) == set( + assert find_uncallable_ufuncs('int') == set() + assert find_uncallable_ufuncs('bool') == set() + assert find_uncallable_ufuncs('float') == set( ['bitwise_and', 'bitwise_not', 'bitwise_or', 'bitwise_xor', 'left_shift', 'right_shift', 'invert']) - assert find_uncallable_ufuncs(np.array(1, 'complex')) == set( + assert find_uncallable_ufuncs('complex') == set( ['bitwise_and', 'bitwise_not', 'bitwise_or', 'bitwise_xor', 'arctan2', 'deg2rad', 'degrees', 'rad2deg', 'radians', 'fabs', 'fmod', 'invert', 'isneginf', 'isposinf', From noreply at buildbot.pypy.org Tue Feb 26 04:24:05 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Tue, 26 Feb 2013 04:24:05 +0100 (CET) Subject: [pypy-commit] pypy default: fix checkmodule (it was ignoring submodules) Message-ID: <20130226032405.A49011C0EEA@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61808:f29a51d5611b Date: 2013-02-25 22:23 -0500 http://bitbucket.org/pypy/pypy/changeset/f29a51d5611b/ Log: fix checkmodule (it was ignoring submodules) diff --git a/pypy/objspace/fake/checkmodule.py b/pypy/objspace/fake/checkmodule.py --- a/pypy/objspace/fake/checkmodule.py +++ b/pypy/objspace/fake/checkmodule.py @@ -11,5 +11,9 @@ module = mod.Module(space, W_Root()) for name in module.loaders: module._load_lazily(space, name) + for cls in module.submodules.itervalues(): + submod = cls(space, W_Root()) + for name in submod.loaders: + submod._load_lazily(space, name) # space.translates(**{'translation.list_comprehension_operations': True}) From noreply at buildbot.pypy.org Tue Feb 26 05:40:57 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Tue, 26 Feb 2013 05:40:57 +0100 (CET) Subject: [pypy-commit] pypy default: test and fix gdb_pypy.to_string max length logic Message-ID: <20130226044057.88B291C01A7@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61809:1610b141ce75 Date: 2013-02-25 23:39 -0500 http://bitbucket.org/pypy/pypy/changeset/1610b141ce75/ Log: test and fix gdb_pypy.to_string max length logic diff --git a/pypy/tool/gdb_pypy.py b/pypy/tool/gdb_pypy.py --- a/pypy/tool/gdb_pypy.py +++ b/pypy/tool/gdb_pypy.py @@ -160,7 +160,7 @@ except ValueError: # it's a gdb.Value so it has "121 'y'" as repr res.append(chr(int(str(items[0]).split(" ")[0]))) - if i < length: + if length > MAX_DISPLAY_LENGTH: res.append('...') string = ''.join(res) return 'r' + repr(string) diff --git a/pypy/tool/test/test_gdb_pypy.py b/pypy/tool/test/test_gdb_pypy.py --- a/pypy/tool/test/test_gdb_pypy.py +++ b/pypy/tool/test/test_gdb_pypy.py @@ -143,7 +143,7 @@ cmd = gdb_pypy.RPyType(gdb) assert cmd.do_invoke('*myvar', True) == 'GcStruct yyy {}' -def test_pprint_string(): +def test_pprint_string(monkeypatch): d = {'_gcheader': { 'h_tid': 123 }, @@ -156,6 +156,8 @@ p_string = PtrValue(d, type_tag='pypy_rpy_string0') printer = gdb_pypy.RPyStringPrinter.lookup(p_string, FakeGdb) assert printer.to_string() == "r'foobar'" + monkeypatch.setattr(gdb_pypy, 'MAX_DISPLAY_LENGTH', 5) + assert printer.to_string() == "r'fooba...'" def test_pprint_list(): d = {'_gcheader': { @@ -180,4 +182,4 @@ assert printer.to_string() == 'r[40, 41, 42] (len=3, alloc=5)' mylist.type.target().tag = None - assert gdb_pypy.RPyListPrinter.lookup(mylist, FakeGdb) is None \ No newline at end of file + assert gdb_pypy.RPyListPrinter.lookup(mylist, FakeGdb) is None From noreply at buildbot.pypy.org Tue Feb 26 06:19:59 2013 From: noreply at buildbot.pypy.org (mattip) Date: Tue, 26 Feb 2013 06:19:59 +0100 (CET) Subject: [pypy-commit] pypy default: fix translation Message-ID: <20130226051959.EE07E1C01A7@cobra.cs.uni-duesseldorf.de> Author: Matti Picus Branch: Changeset: r61810:1ba981281500 Date: 2013-02-26 07:19 +0200 http://bitbucket.org/pypy/pypy/changeset/1ba981281500/ Log: fix translation diff --git a/pypy/module/micronumpy/types.py b/pypy/module/micronumpy/types.py --- a/pypy/module/micronumpy/types.py +++ b/pypy/module/micronumpy/types.py @@ -507,7 +507,7 @@ if v == 0: # XXX good place to warn return -maxint - return 1 / v + return rffi.cast(self.T, 1) / v @raw_unary_op def signbit(self, v): From noreply at buildbot.pypy.org Tue Feb 26 06:26:23 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Tue, 26 Feb 2013 06:26:23 +0100 (CET) Subject: [pypy-commit] pypy default: lets try this instead, simpler Message-ID: <20130226052623.E0F451C3C1C@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61811:eff360783265 Date: 2013-02-26 00:23 -0500 http://bitbucket.org/pypy/pypy/changeset/eff360783265/ Log: lets try this instead, simpler diff --git a/pypy/module/micronumpy/types.py b/pypy/module/micronumpy/types.py --- a/pypy/module/micronumpy/types.py +++ b/pypy/module/micronumpy/types.py @@ -507,7 +507,9 @@ if v == 0: # XXX good place to warn return -maxint - return rffi.cast(self.T, 1) / v + if v == 1 or v == -1: + return v + return 0 @raw_unary_op def signbit(self, v): From noreply at buildbot.pypy.org Tue Feb 26 09:19:11 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Tue, 26 Feb 2013 09:19:11 +0100 (CET) Subject: [pypy-commit] pypy default: add uint alias, test more aliases Message-ID: <20130226081911.244831C01A7@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61812:7d06b6fb37da Date: 2013-02-26 00:41 -0500 http://bitbucket.org/pypy/pypy/changeset/7d06b6fb37da/ Log: add uint alias, test more aliases diff --git a/pypy/module/micronumpy/interp_dtype.py b/pypy/module/micronumpy/interp_dtype.py --- a/pypy/module/micronumpy/interp_dtype.py +++ b/pypy/module/micronumpy/interp_dtype.py @@ -419,6 +419,7 @@ w_box_type=space.gettypefor(interp_boxes.W_ULongBox), alternate_constructors=[ space.gettypefor(interp_boxes.W_UnsignedIntegerBox), ], + aliases=['uint'], ) self.w_int64dtype = W_Dtype( types.Int64(), diff --git a/pypy/module/micronumpy/test/test_dtypes.py b/pypy/module/micronumpy/test/test_dtypes.py --- a/pypy/module/micronumpy/test/test_dtypes.py +++ b/pypy/module/micronumpy/test/test_dtypes.py @@ -62,8 +62,12 @@ assert dtype('int64').num == 7 assert dtype('uint64').num == 8 assert dtype(int).num == 7 + assert dtype('int').num == 7 + assert dtype('uint').num == 8 assert dtype(long).num == 9 assert dtype(float).num == 12 + assert dtype('float').num == 12 + assert dtype('complex').num == 15 def test_array_dtype_attr(self): from numpypy import array, dtype From noreply at buildbot.pypy.org Tue Feb 26 09:19:12 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Tue, 26 Feb 2013 09:19:12 +0100 (CET) Subject: [pypy-commit] pypy default: remove these unused functions Message-ID: <20130226081912.54C221C01A7@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61813:88da576a2859 Date: 2013-02-26 01:36 -0500 http://bitbucket.org/pypy/pypy/changeset/88da576a2859/ Log: remove these unused functions diff --git a/pypy/module/micronumpy/types.py b/pypy/module/micronumpy/types.py --- a/pypy/module/micronumpy/types.py +++ b/pypy/module/micronumpy/types.py @@ -1754,15 +1754,6 @@ all_int_types = [] all_complex_types = [] -def for_int_computation(v): - return widen(v) - -def for_float_computation(v): - return float(v) - -def for_complex_computation(v): - return float(v[0]), float(v[1]) - def _setup(): # compute alignment for tp in globals().values(): @@ -1812,7 +1803,7 @@ def _write(self, storage, i, offset, value): hbits = float_pack(value,2) raw_storage_setitem(storage, i + offset, - rffi.cast(self._STORAGE_T, hbits)) + rffi.cast(self._STORAGE_T, hbits)) class NonNativeFloat16(BaseType, BaseFloat16): def _read(self, storage, i, offset): @@ -1823,5 +1814,3 @@ hbits = float_pack(value,2) raw_storage_setitem(storage, i + offset, byteswap(rffi.cast(self._STORAGE_T, hbits))) - - From noreply at buildbot.pypy.org Tue Feb 26 09:19:13 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Tue, 26 Feb 2013 09:19:13 +0100 (CET) Subject: [pypy-commit] pypy default: test and fix reciprocal overflow return values Message-ID: <20130226081913.879521C01A7@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61814:22d315119b14 Date: 2013-02-26 02:41 -0500 http://bitbucket.org/pypy/pypy/changeset/22d315119b14/ Log: test and fix reciprocal overflow return values diff --git a/pypy/module/micronumpy/test/test_ufuncs.py b/pypy/module/micronumpy/test/test_ufuncs.py --- a/pypy/module/micronumpy/test/test_ufuncs.py +++ b/pypy/module/micronumpy/test/test_ufuncs.py @@ -299,6 +299,19 @@ for i in range(4): assert b[i] == reference[i] + for dtype in ['int8', 'int16', 'int32', 'int64', + 'uint8', 'uint16', 'uint32', 'uint64']: + reference = [0, -1, 0, 1, 0] + if dtype[0] == 'u': + reference[1] = 0 + elif dtype == 'int32': + reference[2] = -2147483648 + elif dtype == 'int64': + reference[2] = -9223372036854775808 + a = array([-2, -1, 0, 1, 2], dtype) + b = reciprocal(a) + assert (b == reference).all() + def test_subtract(self): from numpypy import array, subtract diff --git a/pypy/module/micronumpy/types.py b/pypy/module/micronumpy/types.py --- a/pypy/module/micronumpy/types.py +++ b/pypy/module/micronumpy/types.py @@ -7,11 +7,11 @@ from pypy.objspace.std.floatobject import float2string from pypy.objspace.std.complexobject import str_format from rpython.rlib import rfloat, clibffi, rcomplex -from rpython.rlib.rarithmetic import maxint from rpython.rlib.rawstorage import (alloc_raw_storage, raw_storage_setitem, raw_storage_getitem) from rpython.rlib.objectmodel import specialize -from rpython.rlib.rarithmetic import widen, byteswap, r_ulonglong +from rpython.rlib.rarithmetic import (widen, byteswap, r_ulonglong, + most_neg_value_of) from rpython.rtyper.lltypesystem import lltype, rffi from rpython.rlib.rstruct.runpack import runpack from rpython.rlib.rstruct.nativefmttable import native_is_bigendian @@ -506,7 +506,9 @@ def reciprocal(self, v): if v == 0: # XXX good place to warn - return -maxint + if self.T in (rffi.INT, rffi.LONG): + return most_neg_value_of(self.T) + return 0 if v == 1 or v == -1: return v return 0 From noreply at buildbot.pypy.org Tue Feb 26 09:19:14 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Tue, 26 Feb 2013 09:19:14 +0100 (CET) Subject: [pypy-commit] pypy default: disable reciprocal until it can translate Message-ID: <20130226081914.B1DB81C01A7@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61815:6df9ec9e24d4 Date: 2013-02-26 03:18 -0500 http://bitbucket.org/pypy/pypy/changeset/6df9ec9e24d4/ Log: disable reciprocal until it can translate diff --git a/pypy/module/micronumpy/types.py b/pypy/module/micronumpy/types.py --- a/pypy/module/micronumpy/types.py +++ b/pypy/module/micronumpy/types.py @@ -502,16 +502,17 @@ def invert(self, v): return ~v - @simple_unary_op - def reciprocal(self, v): - if v == 0: - # XXX good place to warn - if self.T in (rffi.INT, rffi.LONG): - return most_neg_value_of(self.T) + if 0: # XXX breaks translation + @simple_unary_op + def reciprocal(self, v): + if v == 0: + # XXX good place to warn + if self.T in (rffi.INT, rffi.LONG): + return most_neg_value_of(self.T) + return 0 + if v == 1 or v == -1: + return v return 0 - if v == 1 or v == -1: - return v - return 0 @raw_unary_op def signbit(self, v): From noreply at buildbot.pypy.org Tue Feb 26 10:26:10 2013 From: noreply at buildbot.pypy.org (arigo) Date: Tue, 26 Feb 2013 10:26:10 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: Add missing stays_alive(). Otherwise, random registers may be listed incorrectly. Message-ID: <20130226092610.38C141C47A2@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: jitframe-on-heap Changeset: r61816:e02ce6381c9e Date: 2013-02-26 09:52 +0100 http://bitbucket.org/pypy/pypy/changeset/e02ce6381c9e/ Log: Add missing stays_alive(). Otherwise, random registers may be listed incorrectly. diff --git a/rpython/jit/backend/x86/regalloc.py b/rpython/jit/backend/x86/regalloc.py --- a/rpython/jit/backend/x86/regalloc.py +++ b/rpython/jit/backend/x86/regalloc.py @@ -876,13 +876,13 @@ for box, loc in self.rm.reg_bindings.iteritems(): if loc in forbidden_regs: continue - if box.type == REF: + if box.type == REF and self.rm.stays_alive(box): assert not noregs assert isinstance(loc, RegLoc) val = gpr_reg_mgr_cls.all_reg_indexes[loc.value] gcmap[val // WORD // 8] |= r_uint(1) << (val % (WORD * 8)) for box, loc in self.fm.bindings.iteritems(): - if box.type == REF: + if box.type == REF and self.rm.stays_alive(box): assert isinstance(loc, FrameLoc) val = loc.position + JITFRAME_FIXED_SIZE gcmap[val // WORD // 8] |= r_uint(1) << (val % (WORD * 8)) From noreply at buildbot.pypy.org Tue Feb 26 11:52:51 2013 From: noreply at buildbot.pypy.org (lwassermann) Date: Tue, 26 Feb 2013 11:52:51 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: changed the print format of compiled method to include methodname, hex-bytecodes and moved the bytecode number to the front, so that the names are now aligned Message-ID: <20130226105251.C6A711C01A7@cobra.cs.uni-duesseldorf.de> Author: Lars Wassermann Branch: Changeset: r100:9ce049baa49b Date: 2013-02-26 11:52 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/9ce049baa49b/ Log: changed the print format of compiled method to include methodname, hex-bytecodes and moved the bytecode number to the front, so that the names are now aligned diff --git a/spyvm/model.py b/spyvm/model.py --- a/spyvm/model.py +++ b/spyvm/model.py @@ -492,11 +492,12 @@ def __str__(self): from spyvm.interpreter import BYTECODE_TABLE j = 1 - retval = "\n\nBytecode:\n---------------------\n" + retval = "\nMethodname: " + self._likely_methodname + retval += "\nBytecode:------------\n" for i in self.bytes: - retval += str(j) + ": " + BYTECODE_TABLE[ord(i)].__name__ + " " + str(ord(i)) + "\n" + retval += ('%0.2i: 0x%0.2x(%0.3i) ' % (j ,ord(i), ord(i))) + BYTECODE_TABLE[ord(i)].__name__ + "\n" j += 1 - return retval + "\n---------------------\n" + return retval + "---------------------\n" def invariant(self): return (W_Object.invariant(self) and From noreply at buildbot.pypy.org Tue Feb 26 11:55:32 2013 From: noreply at buildbot.pypy.org (bivab) Date: Tue, 26 Feb 2013 11:55:32 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: update cond_call_gc_wb and wb_slowpath Message-ID: <20130226105532.B68661C021F@cobra.cs.uni-duesseldorf.de> Author: David Schneider Branch: jitframe-on-heap Changeset: r61817:9dd6acf62511 Date: 2013-02-26 11:54 +0100 http://bitbucket.org/pypy/pypy/changeset/9dd6acf62511/ Log: update cond_call_gc_wb and wb_slowpath diff --git a/rpython/jit/backend/arm/assembler.py b/rpython/jit/backend/arm/assembler.py --- a/rpython/jit/backend/arm/assembler.py +++ b/rpython/jit/backend/arm/assembler.py @@ -327,6 +327,14 @@ self._store_and_reset_exception(mc, exc0, exc1) mc.BL(func) # + if not for_frame: + self._pop_all_regs_from_jitframe(mc, [], withfloats, callee_only=True) + else: + self._restore_exception(mc, exc0, exc1) + mc.VPOP([vfpr.value for vfpr in r.caller_vfp_resp]) + mc.POP([gpr.value for gpr in r.caller_resp] + + [exc0.value, exc1.value]) + # if withcards: # A final TEST8 before the RET, for the caller. Careful to # not follow this instruction with another one that changes @@ -335,13 +343,6 @@ imm=descr.jit_wb_if_flag_byteofs) mc.TST_ri(r.ip.value, imm=0x80) # - if not for_frame: - self._pop_all_regs_from_jitframe(mc, [], withfloats, callee_only=True) - else: - self._restore_exception(mc, exc0, exc1) - mc.VPOP([vfpr.value for vfpr in r.caller_vfp_resp]) - mc.POP([gpr.value for gpr in r.caller_resp] + - [exc0.value, exc1.value]) mc.POP([r.ip.value, r.pc.value]) # rawstart = mc.materialize(self.cpu.asmmemmgr, []) diff --git a/rpython/jit/backend/arm/opassembler.py b/rpython/jit/backend/arm/opassembler.py --- a/rpython/jit/backend/arm/opassembler.py +++ b/rpython/jit/backend/arm/opassembler.py @@ -547,19 +547,25 @@ emit_op_keepalive = emit_op_debug_merge_point def emit_op_cond_call_gc_wb(self, op, arglocs, regalloc, fcond): + self._write_barrier_fastpath(self.mc, op.getdescr(), arglocs, fcond) + + def emit_op_cond_call_gc_wb_array(self, op, arglocs, regalloc, fcond): + self._write_barrier_fastpath(self.mc, op.getdescr(), arglocs, + fcond, array=True) + + def _write_barrier_fastpath(self, mc, descr, arglocs, fcond, array=False, + is_frame=False): # Write code equivalent to write_barrier() in the GC: it checks # a flag in the object at arglocs[0], and if set, it calls a # helper piece of assembler. The latter saves registers as needed # and call the function jit_remember_young_pointer() from the GC. - descr = op.getdescr() if we_are_translated(): cls = self.cpu.gc_ll_descr.has_write_barrier_class() assert cls is not None and isinstance(descr, cls) # - opnum = op.getopnum() card_marking = False mask = descr.jit_wb_if_flag_singlebyte - if opnum == rop.COND_CALL_GC_WB_ARRAY and descr.jit_wb_cards_set != 0: + if array and descr.jit_wb_cards_set != 0: # assumptions the rest of the function depends on: assert (descr.jit_wb_cards_set_byteofs == descr.jit_wb_if_flag_byteofs) @@ -568,11 +574,13 @@ mask = descr.jit_wb_if_flag_singlebyte | -0x80 # loc_base = arglocs[0] - self.mc.LDRB_ri(r.ip.value, loc_base.value, - imm=descr.jit_wb_if_flag_byteofs) + if is_frame: + assert loc_base is r.fp + else: + self.mc.LDRB_ri(r.ip.value, loc_base.value, + imm=descr.jit_wb_if_flag_byteofs) mask &= 0xFF self.mc.TST_ri(r.ip.value, imm=mask) - jz_location = self.mc.currpos() self.mc.BKPT() @@ -658,8 +666,6 @@ pmc.B_offs(offset, c.EQ) return fcond - emit_op_cond_call_gc_wb_array = emit_op_cond_call_gc_wb - def emit_op_setfield_gc(self, op, arglocs, regalloc, fcond): value_loc, base_loc, ofs, size = arglocs if size.value == 8: From noreply at buildbot.pypy.org Tue Feb 26 12:23:10 2013 From: noreply at buildbot.pypy.org (arigo) Date: Tue, 26 Feb 2013 12:23:10 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: Fix comments Message-ID: <20130226112310.80CC41C01A7@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: jitframe-on-heap Changeset: r61818:14272fdee9cc Date: 2013-02-26 11:22 +0100 http://bitbucket.org/pypy/pypy/changeset/14272fdee9cc/ Log: Fix comments diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -1967,12 +1967,11 @@ self._push_all_regs_to_frame(mc, [], withfloats) if exc: - # We might have an exception pending. Load it into ebx - # (this is a register saved across calls, both if 32 or 64) + # We might have an exception pending. Load it into ebx... mc.MOV(ebx, heap(self.cpu.pos_exc_value())) mc.MOV(heap(self.cpu.pos_exception()), imm0) mc.MOV(heap(self.cpu.pos_exc_value()), imm0) - # save ebx into 'jf_guard_exc' + # ...and save ebx into 'jf_guard_exc' offset = self.cpu.get_ofs_of_frame_field('jf_guard_exc') mc.MOV_br(offset, ebx.value) @@ -1986,7 +1985,7 @@ mc.MOV_br(ofs2, eax.value) mc.POP(eax) mc.MOV_br(ofs, eax.value) - # store the gc pattern + # the return value is the jitframe mc.MOV_rr(eax.value, ebp.value) self._call_footer() From noreply at buildbot.pypy.org Tue Feb 26 12:23:11 2013 From: noreply at buildbot.pypy.org (arigo) Date: Tue, 26 Feb 2013 12:23:11 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: Backout c88fd8172c57: it's nonsense to translate RPython code Message-ID: <20130226112311.BA2A61C01A7@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: jitframe-on-heap Changeset: r61819:315181cc8ad2 Date: 2013-02-26 11:23 +0100 http://bitbucket.org/pypy/pypy/changeset/315181cc8ad2/ Log: Backout c88fd8172c57: it's nonsense to translate RPython code which calls malloc(immortal=True). diff --git a/rpython/annotator/builtin.py b/rpython/annotator/builtin.py --- a/rpython/annotator/builtin.py +++ b/rpython/annotator/builtin.py @@ -405,7 +405,7 @@ from rpython.rtyper.lltypesystem import lltype def malloc(s_T, s_n=None, s_flavor=None, s_zero=None, s_track_allocation=None, - s_add_memory_pressure=None, s_immortal=None): + s_add_memory_pressure=None): assert (s_n is None or s_n.knowntype == int or issubclass(s_n.knowntype, rpython.rlib.rarithmetic.base_int)) assert s_T.is_constant() diff --git a/rpython/rtyper/rbuiltin.py b/rpython/rtyper/rbuiltin.py --- a/rpython/rtyper/rbuiltin.py +++ b/rpython/rtyper/rbuiltin.py @@ -357,7 +357,7 @@ # annotation of low-level types def rtype_malloc(hop, i_flavor=None, i_zero=None, i_track_allocation=None, - i_add_memory_pressure=None, i_immortal=None): + i_add_memory_pressure=None): assert hop.args_s[0].is_constant() vlist = [hop.inputarg(lltype.Void, arg=0)] opname = 'malloc' From noreply at buildbot.pypy.org Tue Feb 26 12:23:12 2013 From: noreply at buildbot.pypy.org (arigo) Date: Tue, 26 Feb 2013 12:23:12 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: Fix Message-ID: <20130226112312.D3FAF1C01A7@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: jitframe-on-heap Changeset: r61820:6ed149cf3475 Date: 2013-02-26 11:56 +0100 http://bitbucket.org/pypy/pypy/changeset/6ed149cf3475/ Log: Fix diff --git a/rpython/rtyper/lltypesystem/opimpl.py b/rpython/rtyper/lltypesystem/opimpl.py --- a/rpython/rtyper/lltypesystem/opimpl.py +++ b/rpython/rtyper/lltypesystem/opimpl.py @@ -529,7 +529,7 @@ assert A.TO.OF.TO._gckind == 'gc' else: assert isinstance(A.TO, lltype.GcStruct) - assert hasattr(A.TO, '_arrayfld') + assert A.TO._arrayfld is not None assert type(source_start) is int assert type(dest_start) is int assert type(length) is int From noreply at buildbot.pypy.org Tue Feb 26 12:23:14 2013 From: noreply at buildbot.pypy.org (arigo) Date: Tue, 26 Feb 2013 12:23:14 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: Fix Message-ID: <20130226112314.006331C01A7@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: jitframe-on-heap Changeset: r61821:a713cf421fcc Date: 2013-02-26 11:59 +0100 http://bitbucket.org/pypy/pypy/changeset/a713cf421fcc/ Log: Fix diff --git a/rpython/rtyper/rbuiltin.py b/rpython/rtyper/rbuiltin.py --- a/rpython/rtyper/rbuiltin.py +++ b/rpython/rtyper/rbuiltin.py @@ -366,10 +366,9 @@ (i_flavor, lltype.Void), (i_zero, None), (i_track_allocation, None), - (i_add_memory_pressure, None), - (i_immortal, None)) + (i_add_memory_pressure, None)) (v_flavor, v_zero, v_track_allocation, - v_add_memory_pressure, v_immortal) = kwds_v + v_add_memory_pressure) = kwds_v flags = {'flavor': 'gc'} if v_flavor is not None: flags['flavor'] = v_flavor.value From noreply at buildbot.pypy.org Tue Feb 26 12:23:15 2013 From: noreply at buildbot.pypy.org (arigo) Date: Tue, 26 Feb 2013 12:23:15 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: Fix Message-ID: <20130226112315.1C1951C01A7@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: jitframe-on-heap Changeset: r61822:f861519ad887 Date: 2013-02-26 12:16 +0100 http://bitbucket.org/pypy/pypy/changeset/f861519ad887/ Log: Fix diff --git a/rpython/memory/gc/minimark.py b/rpython/memory/gc/minimark.py --- a/rpython/memory/gc/minimark.py +++ b/rpython/memory/gc/minimark.py @@ -639,8 +639,14 @@ # The nursery might not be empty now, because of # execute_finalizers(). If it is almost full again, # we need to fix it with another call to minor_collection(). - if self.nursery_free + totalsize > self.nursery_real_top: - self.minor_collection() + if self.nursery_free + totalsize > self.nursery_top: + # + if self.nursery_free + totalsize > self.nursery_real_top: + self.minor_collection() + # then the nursery is empty + else: + # we just need to clean up a bit more of the nursery + self.move_nursery_top(totalsize) # result = self.nursery_free self.nursery_free = result + totalsize From noreply at buildbot.pypy.org Tue Feb 26 12:23:16 2013 From: noreply at buildbot.pypy.org (arigo) Date: Tue, 26 Feb 2013 12:23:16 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: Ah, this is where immortal=True was used in RPython code. Fix. Message-ID: <20130226112316.5AFA11C01A7@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: jitframe-on-heap Changeset: r61823:23d590305060 Date: 2013-02-26 12:21 +0100 http://bitbucket.org/pypy/pypy/changeset/23d590305060/ Log: Ah, this is where immortal=True was used in RPython code. Fix. diff --git a/rpython/jit/backend/llsupport/assembler.py b/rpython/jit/backend/llsupport/assembler.py --- a/rpython/jit/backend/llsupport/assembler.py +++ b/rpython/jit/backend/llsupport/assembler.py @@ -85,7 +85,8 @@ debug_stop('jit-backend-counts') # when finishing, we only have one value at [0], the rest dies self.gcmap_for_finish = lltype.malloc(jitframe.GCMAP, 1, - flavor='raw', immortal=True) + flavor='raw', + track_allocation=False) self.gcmap_for_finish[0] = r_uint(1) def rebuild_faillocs_from_descr(self, descr, inputargs): From noreply at buildbot.pypy.org Tue Feb 26 12:23:17 2013 From: noreply at buildbot.pypy.org (arigo) Date: Tue, 26 Feb 2013 12:23:17 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: merge heads Message-ID: <20130226112317.8522C1C01A7@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: jitframe-on-heap Changeset: r61824:fb824df5e8b8 Date: 2013-02-26 12:23 +0100 http://bitbucket.org/pypy/pypy/changeset/fb824df5e8b8/ Log: merge heads diff --git a/rpython/jit/backend/arm/assembler.py b/rpython/jit/backend/arm/assembler.py --- a/rpython/jit/backend/arm/assembler.py +++ b/rpython/jit/backend/arm/assembler.py @@ -327,6 +327,14 @@ self._store_and_reset_exception(mc, exc0, exc1) mc.BL(func) # + if not for_frame: + self._pop_all_regs_from_jitframe(mc, [], withfloats, callee_only=True) + else: + self._restore_exception(mc, exc0, exc1) + mc.VPOP([vfpr.value for vfpr in r.caller_vfp_resp]) + mc.POP([gpr.value for gpr in r.caller_resp] + + [exc0.value, exc1.value]) + # if withcards: # A final TEST8 before the RET, for the caller. Careful to # not follow this instruction with another one that changes @@ -335,13 +343,6 @@ imm=descr.jit_wb_if_flag_byteofs) mc.TST_ri(r.ip.value, imm=0x80) # - if not for_frame: - self._pop_all_regs_from_jitframe(mc, [], withfloats, callee_only=True) - else: - self._restore_exception(mc, exc0, exc1) - mc.VPOP([vfpr.value for vfpr in r.caller_vfp_resp]) - mc.POP([gpr.value for gpr in r.caller_resp] + - [exc0.value, exc1.value]) mc.POP([r.ip.value, r.pc.value]) # rawstart = mc.materialize(self.cpu.asmmemmgr, []) diff --git a/rpython/jit/backend/arm/opassembler.py b/rpython/jit/backend/arm/opassembler.py --- a/rpython/jit/backend/arm/opassembler.py +++ b/rpython/jit/backend/arm/opassembler.py @@ -547,19 +547,25 @@ emit_op_keepalive = emit_op_debug_merge_point def emit_op_cond_call_gc_wb(self, op, arglocs, regalloc, fcond): + self._write_barrier_fastpath(self.mc, op.getdescr(), arglocs, fcond) + + def emit_op_cond_call_gc_wb_array(self, op, arglocs, regalloc, fcond): + self._write_barrier_fastpath(self.mc, op.getdescr(), arglocs, + fcond, array=True) + + def _write_barrier_fastpath(self, mc, descr, arglocs, fcond, array=False, + is_frame=False): # Write code equivalent to write_barrier() in the GC: it checks # a flag in the object at arglocs[0], and if set, it calls a # helper piece of assembler. The latter saves registers as needed # and call the function jit_remember_young_pointer() from the GC. - descr = op.getdescr() if we_are_translated(): cls = self.cpu.gc_ll_descr.has_write_barrier_class() assert cls is not None and isinstance(descr, cls) # - opnum = op.getopnum() card_marking = False mask = descr.jit_wb_if_flag_singlebyte - if opnum == rop.COND_CALL_GC_WB_ARRAY and descr.jit_wb_cards_set != 0: + if array and descr.jit_wb_cards_set != 0: # assumptions the rest of the function depends on: assert (descr.jit_wb_cards_set_byteofs == descr.jit_wb_if_flag_byteofs) @@ -568,11 +574,13 @@ mask = descr.jit_wb_if_flag_singlebyte | -0x80 # loc_base = arglocs[0] - self.mc.LDRB_ri(r.ip.value, loc_base.value, - imm=descr.jit_wb_if_flag_byteofs) + if is_frame: + assert loc_base is r.fp + else: + self.mc.LDRB_ri(r.ip.value, loc_base.value, + imm=descr.jit_wb_if_flag_byteofs) mask &= 0xFF self.mc.TST_ri(r.ip.value, imm=mask) - jz_location = self.mc.currpos() self.mc.BKPT() @@ -658,8 +666,6 @@ pmc.B_offs(offset, c.EQ) return fcond - emit_op_cond_call_gc_wb_array = emit_op_cond_call_gc_wb - def emit_op_setfield_gc(self, op, arglocs, regalloc, fcond): value_loc, base_loc, ofs, size = arglocs if size.value == 8: From noreply at buildbot.pypy.org Tue Feb 26 12:24:22 2013 From: noreply at buildbot.pypy.org (fijal) Date: Tue, 26 Feb 2013 12:24:22 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: port e02ce6381c9e to ARM, but it still does not work Message-ID: <20130226112422.06ED51C021F@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61825:60be45ca5fc5 Date: 2013-02-26 13:22 +0200 http://bitbucket.org/pypy/pypy/changeset/60be45ca5fc5/ Log: port e02ce6381c9e to ARM, but it still does not work diff --git a/rpython/jit/backend/arm/regalloc.py b/rpython/jit/backend/arm/regalloc.py --- a/rpython/jit/backend/arm/regalloc.py +++ b/rpython/jit/backend/arm/regalloc.py @@ -341,13 +341,13 @@ for box, loc in self.rm.reg_bindings.iteritems(): if loc in forbidden_regs: continue - if box.type == REF: + if box.type == REF and self.fm.stays_alive(box): assert not noregs assert isinstance(loc, RegLoc) val = gpr_reg_mgr_cls.all_reg_indexes[loc.value] gcmap[val // WORD // 8] |= r_uint(1) << (val % (WORD * 8)) for box, loc in self.fm.bindings.iteritems(): - if box.type == REF: + if box.type == REF and self.fm.stays_alive(box): assert isinstance(loc, StackLoc) val = loc.value // WORD gcmap[val // WORD // 8] |= r_uint(1) << (val % (WORD * 8)) From noreply at buildbot.pypy.org Tue Feb 26 12:24:23 2013 From: noreply at buildbot.pypy.org (fijal) Date: Tue, 26 Feb 2013 12:24:23 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: merge Message-ID: <20130226112423.3BF431C021F@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61826:2e268ed9c59d Date: 2013-02-26 13:23 +0200 http://bitbucket.org/pypy/pypy/changeset/2e268ed9c59d/ Log: merge diff --git a/rpython/annotator/builtin.py b/rpython/annotator/builtin.py --- a/rpython/annotator/builtin.py +++ b/rpython/annotator/builtin.py @@ -405,7 +405,7 @@ from rpython.rtyper.lltypesystem import lltype def malloc(s_T, s_n=None, s_flavor=None, s_zero=None, s_track_allocation=None, - s_add_memory_pressure=None, s_immortal=None): + s_add_memory_pressure=None): assert (s_n is None or s_n.knowntype == int or issubclass(s_n.knowntype, rpython.rlib.rarithmetic.base_int)) assert s_T.is_constant() diff --git a/rpython/jit/backend/llsupport/assembler.py b/rpython/jit/backend/llsupport/assembler.py --- a/rpython/jit/backend/llsupport/assembler.py +++ b/rpython/jit/backend/llsupport/assembler.py @@ -85,7 +85,8 @@ debug_stop('jit-backend-counts') # when finishing, we only have one value at [0], the rest dies self.gcmap_for_finish = lltype.malloc(jitframe.GCMAP, 1, - flavor='raw', immortal=True) + flavor='raw', + track_allocation=False) self.gcmap_for_finish[0] = r_uint(1) def rebuild_faillocs_from_descr(self, descr, inputargs): diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -1967,12 +1967,11 @@ self._push_all_regs_to_frame(mc, [], withfloats) if exc: - # We might have an exception pending. Load it into ebx - # (this is a register saved across calls, both if 32 or 64) + # We might have an exception pending. Load it into ebx... mc.MOV(ebx, heap(self.cpu.pos_exc_value())) mc.MOV(heap(self.cpu.pos_exception()), imm0) mc.MOV(heap(self.cpu.pos_exc_value()), imm0) - # save ebx into 'jf_guard_exc' + # ...and save ebx into 'jf_guard_exc' offset = self.cpu.get_ofs_of_frame_field('jf_guard_exc') mc.MOV_br(offset, ebx.value) @@ -1986,7 +1985,7 @@ mc.MOV_br(ofs2, eax.value) mc.POP(eax) mc.MOV_br(ofs, eax.value) - # store the gc pattern + # the return value is the jitframe mc.MOV_rr(eax.value, ebp.value) self._call_footer() diff --git a/rpython/memory/gc/minimark.py b/rpython/memory/gc/minimark.py --- a/rpython/memory/gc/minimark.py +++ b/rpython/memory/gc/minimark.py @@ -639,8 +639,14 @@ # The nursery might not be empty now, because of # execute_finalizers(). If it is almost full again, # we need to fix it with another call to minor_collection(). - if self.nursery_free + totalsize > self.nursery_real_top: - self.minor_collection() + if self.nursery_free + totalsize > self.nursery_top: + # + if self.nursery_free + totalsize > self.nursery_real_top: + self.minor_collection() + # then the nursery is empty + else: + # we just need to clean up a bit more of the nursery + self.move_nursery_top(totalsize) # result = self.nursery_free self.nursery_free = result + totalsize diff --git a/rpython/rtyper/lltypesystem/opimpl.py b/rpython/rtyper/lltypesystem/opimpl.py --- a/rpython/rtyper/lltypesystem/opimpl.py +++ b/rpython/rtyper/lltypesystem/opimpl.py @@ -529,7 +529,7 @@ assert A.TO.OF.TO._gckind == 'gc' else: assert isinstance(A.TO, lltype.GcStruct) - assert hasattr(A.TO, '_arrayfld') + assert A.TO._arrayfld is not None assert type(source_start) is int assert type(dest_start) is int assert type(length) is int diff --git a/rpython/rtyper/rbuiltin.py b/rpython/rtyper/rbuiltin.py --- a/rpython/rtyper/rbuiltin.py +++ b/rpython/rtyper/rbuiltin.py @@ -357,7 +357,7 @@ # annotation of low-level types def rtype_malloc(hop, i_flavor=None, i_zero=None, i_track_allocation=None, - i_add_memory_pressure=None, i_immortal=None): + i_add_memory_pressure=None): assert hop.args_s[0].is_constant() vlist = [hop.inputarg(lltype.Void, arg=0)] opname = 'malloc' @@ -366,10 +366,9 @@ (i_flavor, lltype.Void), (i_zero, None), (i_track_allocation, None), - (i_add_memory_pressure, None), - (i_immortal, None)) + (i_add_memory_pressure, None)) (v_flavor, v_zero, v_track_allocation, - v_add_memory_pressure, v_immortal) = kwds_v + v_add_memory_pressure) = kwds_v flags = {'flavor': 'gc'} if v_flavor is not None: flags['flavor'] = v_flavor.value From noreply at buildbot.pypy.org Tue Feb 26 12:58:13 2013 From: noreply at buildbot.pypy.org (arigo) Date: Tue, 26 Feb 2013 12:58:13 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: Better safe than sorry: fall back to initial_size=nursery_size if Message-ID: <20130226115813.758CA1C021F@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: jitframe-on-heap Changeset: r61827:236f1d990238 Date: 2013-02-26 12:57 +0100 http://bitbucket.org/pypy/pypy/changeset/236f1d990238/ Log: Better safe than sorry: fall back to initial_size=nursery_size if numbers overflow, or if we want a tiny nursery. diff --git a/rpython/memory/gc/minimark.py b/rpython/memory/gc/minimark.py --- a/rpython/memory/gc/minimark.py +++ b/rpython/memory/gc/minimark.py @@ -397,7 +397,8 @@ # value of nursery_cleanup. self.initial_cleanup = self.nursery_cleanup + ( self.nursery_size % self.nursery_cleanup) - if self.initial_cleanup > self.nursery_size: + if (r_uint(self.initial_cleanup) > r_uint(self.nursery_size) or + self.debug_tiny_nursery >= 0): self.initial_cleanup = self.nursery_size def _nursery_memory_size(self): From noreply at buildbot.pypy.org Tue Feb 26 13:57:31 2013 From: noreply at buildbot.pypy.org (lwassermann) Date: Tue, 26 Feb 2013 13:57:31 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: added printing to MethodContextShadow, printing the method with pc-arrow and the stack. Message-ID: <20130226125731.221F71C0327@cobra.cs.uni-duesseldorf.de> Author: Lars Wassermann Branch: Changeset: r101:c60b0b0bebae Date: 2013-02-26 13:57 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/c60b0b0bebae/ Log: added printing to MethodContextShadow, printing the method with pc- arrow and the stack. diff --git a/spyvm/model.py b/spyvm/model.py --- a/spyvm/model.py +++ b/spyvm/model.py @@ -490,11 +490,15 @@ return space.w_CompiledMethod def __str__(self): + return self.as_string() + + def as_string(self, markBytecode=0): from spyvm.interpreter import BYTECODE_TABLE j = 1 retval = "\nMethodname: " + self._likely_methodname retval += "\nBytecode:------------\n" for i in self.bytes: + retval += '->' if j is markBytecode else ' ' retval += ('%0.2i: 0x%0.2x(%0.3i) ' % (j ,ord(i), ord(i))) + BYTECODE_TABLE[ord(i)].__name__ + "\n" j += 1 return retval + "---------------------\n" diff --git a/spyvm/shadow.py b/spyvm/shadow.py --- a/spyvm/shadow.py +++ b/spyvm/shadow.py @@ -317,7 +317,6 @@ self._w_sender = space.w_nil AbstractRedirectingShadow.__init__(self, space, w_self) - @staticmethod def is_block_context(w_pointers, space): method_or_argc = w_pointers.fetch(space, constants.MTHDCTX_METHOD) @@ -749,6 +748,12 @@ else: return self._return(self.top(), interp, self.s_home().w_sender()) + def __str__(self): + retval = '\nMethodContext of:' + retval += self.w_method().as_string(markBytecode=self.pc()) + retval += "Stackptr: %i" % self._stack_ptr + retval += "\nStack : " + str(self.stack()) + return retval class CompiledMethodShadow(object): _immutable_fields_ = ["_w_self", "bytecode", From noreply at buildbot.pypy.org Tue Feb 26 14:51:44 2013 From: noreply at buildbot.pypy.org (arigo) Date: Tue, 26 Feb 2013 14:51:44 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: Complain loudly if we attempt to mutate an lltype which has a cached Message-ID: <20130226135144.D6B221C01A7@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: jitframe-on-heap Changeset: r61828:6a26ae322daa Date: 2013-02-26 14:48 +0100 http://bitbucket.org/pypy/pypy/changeset/6a26ae322daa/ Log: Complain loudly if we attempt to mutate an lltype which has a cached hash already. diff --git a/rpython/rtyper/lltypesystem/lltype.py b/rpython/rtyper/lltypesystem/lltype.py --- a/rpython/rtyper/lltypesystem/lltype.py +++ b/rpython/rtyper/lltypesystem/lltype.py @@ -105,6 +105,23 @@ _is_compatible = __eq__ + def __setattr__(self, attr, nvalue): + try: + LowLevelType.__cached_hash.__get__(self) + except AttributeError: + pass + else: + try: + reprself = repr(self) + except: + try: + reprself = str(self) + except: + reprself = object.__repr__(self) + raise AssertionError("%s: changing the field %r but we already " + "computed the hash" % (reprself, attr)) + object.__setattr__(self, attr, nvalue) + def _enforce(self, value): if typeOf(value) != self: raise TypeError @@ -486,6 +503,10 @@ return obj def __init__(self, OF, length, **kwds): + if hasattr(self, '_name'): + assert self.OF == OF + assert self.length == length + return fields = [('item%d' % i, OF) for i in range(length)] super(FixedSizeArray, self).__init__('array%d' % length, *fields, **kwds) From noreply at buildbot.pypy.org Tue Feb 26 15:10:16 2013 From: noreply at buildbot.pypy.org (lwassermann) Date: Tue, 26 Feb 2013 15:10:16 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: changed the two VALUE-bytecodes to call the correct primitive, according to their receiver class Message-ID: <20130226141016.80D701C04F1@cobra.cs.uni-duesseldorf.de> Author: Lars Wassermann Branch: Changeset: r102:da73d196dd0a Date: 2013-02-26 15:09 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/da73d196dd0a/ Log: changed the two VALUE-bytecodes to call the correct primitive, according to their receiver class diff --git a/spyvm/interpreter.py b/spyvm/interpreter.py --- a/spyvm/interpreter.py +++ b/spyvm/interpreter.py @@ -128,6 +128,22 @@ return self._sendSelfSelectorSpecial(selector, argcount, interp) return callPrimitive +def make_call_primitive_bytecode_classbased(a_class_name, a_primitive, alternative_class_name, alternative_primitive, selector, argcount): + def callPrimitive(self, interp, current_bytecode): + rcvr = self.peek(argcount) + receiver_class = rcvr.getclass(self.space) + try: + if receiver_class is getattr(self.space, a_class_name): + func = primitives.prim_table[a_primitive] + return func(interp, self, argcount) + elif receiver_class is getattr(self.space, alternative_class_name): + func = primitives.prim_table[alternative_primitive] + return func(interp, self, argcount) + except primitives.PrimitiveFailedError: + pass + return self._sendSelfSelectorSpecial(selector, argcount, interp) + return callPrimitive + # ___________________________________________________________________________ # Bytecode Implementations: # @@ -524,10 +540,9 @@ # which cannot fail primitives.prim_table[primitives.CLASS](interp, self, 0) - bytecodePrimBlockCopy = make_call_primitive_bytecode(primitives.BLOCK_COPY, "blockCopy:", 1) - bytecodePrimValue = make_call_primitive_bytecode(primitives.VALUE, "value", 0) - bytecodePrimValueWithArg = make_call_primitive_bytecode(primitives.VALUE, "value:", 1) + bytecodePrimValue = make_call_primitive_bytecode_classbased("w_BlockContext", primitives.VALUE, "w_BlockClosure", primitives.CLOSURE_VALUE, "value", 0) + bytecodePrimValueWithArg = make_call_primitive_bytecode_classbased("w_BlockContext", primitives.VALUE, "w_BlockClosure", primitives.CLOSURE_VALUE_, "value:", 1) def bytecodePrimDo(self, interp, current_bytecode): return self._sendSelfSelectorSpecial("do:", 1, interp) From noreply at buildbot.pypy.org Tue Feb 26 17:23:31 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Tue, 26 Feb 2013 17:23:31 +0100 (CET) Subject: [pypy-commit] pypy default: only check submodules if they exist Message-ID: <20130226162331.473821C3C1C@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61829:4d7cd4dce266 Date: 2013-02-26 11:22 -0500 http://bitbucket.org/pypy/pypy/changeset/4d7cd4dce266/ Log: only check submodules if they exist diff --git a/pypy/objspace/fake/checkmodule.py b/pypy/objspace/fake/checkmodule.py --- a/pypy/objspace/fake/checkmodule.py +++ b/pypy/objspace/fake/checkmodule.py @@ -11,9 +11,10 @@ module = mod.Module(space, W_Root()) for name in module.loaders: module._load_lazily(space, name) - for cls in module.submodules.itervalues(): - submod = cls(space, W_Root()) - for name in submod.loaders: - submod._load_lazily(space, name) + if hasattr(module, 'submodules'): + for cls in module.submodules.itervalues(): + submod = cls(space, W_Root()) + for name in submod.loaders: + submod._load_lazily(space, name) # space.translates(**{'translation.list_comprehension_operations': True}) From noreply at buildbot.pypy.org Tue Feb 26 20:19:21 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Tue, 26 Feb 2013 20:19:21 +0100 (CET) Subject: [pypy-commit] pypy py3k: simplify Message-ID: <20130226191921.EC8A61C04F1@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61830:dabc1457e3cc Date: 2013-02-26 10:43 -0800 http://bitbucket.org/pypy/pypy/changeset/dabc1457e3cc/ Log: simplify diff --git a/pypy/interpreter/app_main.py b/pypy/interpreter/app_main.py --- a/pypy/interpreter/app_main.py +++ b/pypy/interpreter/app_main.py @@ -545,11 +545,7 @@ # handle the "-c" command # Put '' on sys.path sys.path.insert(0, '') - - @hidden_applevel - def run_it(): - exec_(run_command, mainmodule.__dict__) - success = run_toplevel(run_it) + success = run_toplevel(exec_, run_command, mainmodule.__dict__) elif run_module != 0: # handle the "-m" command # '' on sys.path is required also here From noreply at buildbot.pypy.org Tue Feb 26 20:44:13 2013 From: noreply at buildbot.pypy.org (stefanor) Date: Tue, 26 Feb 2013 20:44:13 +0100 (CET) Subject: [pypy-commit] pypy sqlite-cffi: (fijal, jerith, tumbleweed, Murphy, Stuart) Some beginnings of CFFI wrapper for sqlite3 Message-ID: <20130226194413.A9F711C3C1C@cobra.cs.uni-duesseldorf.de> Author: Stefano Rivera Branch: sqlite-cffi Changeset: r61831:7b0e09beff80 Date: 2013-02-26 21:43 +0200 http://bitbucket.org/pypy/pypy/changeset/7b0e09beff80/ Log: (fijal, jerith, tumbleweed, Murphy, Stuart) Some beginnings of CFFI wrapper for sqlite3 diff --git a/lib-python/2.7/test/test_sqlite.py b/lib-python/2.7/test/test_sqlite.py --- a/lib-python/2.7/test/test_sqlite.py +++ b/lib-python/2.7/test/test_sqlite.py @@ -1,7 +1,7 @@ from test.test_support import run_unittest, import_module # Skip test if _sqlite3 module was not built. -import_module('_sqlite3') +#import_module('_sqlite3') from sqlite3.test import (dbapi, types, userfunctions, py25tests, factory, transactions, hooks, regression, diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -23,24 +23,185 @@ # # Note: This software has been modified for use in PyPy. -from ctypes import c_void_p, c_int, c_double, c_int64, c_char_p, c_char, cdll -from ctypes import POINTER, byref, string_at, CFUNCTYPE, cast -from ctypes import sizeof, c_ssize_t from collections import OrderedDict import datetime import sys import weakref from threading import _get_ident as thread_get_ident -names = "sqlite3.dll libsqlite3.so.0 libsqlite3.so libsqlite3.dylib".split() -for name in names: - try: - sqlite = cdll.LoadLibrary(name) - break - except OSError: - continue -else: - raise ImportError("Could not load C-library, tried: %s" %(names,)) +from cffi import FFI + +ffi = FFI() + +ffi.cdef(""" +#define SQLITE_OK ... +#define SQLITE_ERROR ... +#define SQLITE_INTERNAL ... +#define SQLITE_PERM ... +#define SQLITE_ABORT ... +#define SQLITE_BUSY ... +#define SQLITE_LOCKED ... +#define SQLITE_NOMEM ... +#define SQLITE_READONLY ... +#define SQLITE_INTERRUPT ... +#define SQLITE_IOERR ... +#define SQLITE_CORRUPT ... +#define SQLITE_NOTFOUND ... +#define SQLITE_FULL ... +#define SQLITE_CANTOPEN ... +#define SQLITE_PROTOCOL ... +#define SQLITE_EMPTY ... +#define SQLITE_SCHEMA ... +#define SQLITE_TOOBIG ... +#define SQLITE_CONSTRAINT ... +#define SQLITE_MISMATCH ... +#define SQLITE_MISUSE ... +#define SQLITE_NOLFS ... +#define SQLITE_AUTH ... +#define SQLITE_FORMAT ... +#define SQLITE_RANGE ... +#define SQLITE_NOTADB ... +#define SQLITE_ROW ... +#define SQLITE_DONE ... +#define SQLITE_INTEGER ... +#define SQLITE_FLOAT ... +#define SQLITE_BLOB ... +#define SQLITE_NULL ... +#define SQLITE_TEXT ... +#define SQLITE3_TEXT ... + +#define SQLITE_TRANSIENT ... +#define SQLITE_UTF8 ... + +#define SQLITE_DENY ... +#define SQLITE_IGNORE ... + +#define SQLITE_CREATE_INDEX ... +#define SQLITE_CREATE_TABLE ... +#define SQLITE_CREATE_TEMP_INDEX ... +#define SQLITE_CREATE_TEMP_TABLE ... +#define SQLITE_CREATE_TEMP_TRIGGER ... +#define SQLITE_CREATE_TEMP_VIEW ... +#define SQLITE_CREATE_TRIGGER ... +#define SQLITE_CREATE_VIEW ... +#define SQLITE_DELETE ... +#define SQLITE_DROP_INDEX ... +#define SQLITE_DROP_TABLE ... +#define SQLITE_DROP_TEMP_INDEX ... +#define SQLITE_DROP_TEMP_TABLE ... +#define SQLITE_DROP_TEMP_TRIGGER ... +#define SQLITE_DROP_TEMP_VIEW ... +#define SQLITE_DROP_TRIGGER ... +#define SQLITE_DROP_VIEW ... +#define SQLITE_INSERT ... +#define SQLITE_PRAGMA ... +#define SQLITE_READ ... +#define SQLITE_SELECT ... +#define SQLITE_TRANSACTION ... +#define SQLITE_UPDATE ... +#define SQLITE_ATTACH ... +#define SQLITE_DETACH ... +#define SQLITE_ALTER_TABLE ... +#define SQLITE_REINDEX ... +#define SQLITE_ANALYZE ... +#define SQLITE_CREATE_VTABLE ... +#define SQLITE_DROP_VTABLE ... +#define SQLITE_FUNCTION ... + +const char *sqlite3_libversion(void); + +typedef ... sqlite3; +typedef ... sqlite3_stmt; +typedef int64_t sqlite3_int64; +typedef uint64_t sqlite3_uint64; + +int sqlite3_open( + const char *filename, /* Database filename (UTF-8) */ + sqlite3 **ppDb /* OUT: SQLite db handle */ +); + +int sqlite3_close(sqlite3 *); + +int sqlite3_busy_timeout(sqlite3*, int ms); +int sqlite3_prepare_v2( + sqlite3 *db, /* Database handle */ + const char *zSql, /* SQL statement, UTF-8 encoded */ + int nByte, /* Maximum length of zSql in bytes. */ + sqlite3_stmt **ppStmt, /* OUT: Statement handle */ + const char **pzTail /* OUT: Pointer to unused portion of zSql */ +); +int sqlite3_finalize(sqlite3_stmt *pStmt); +int sqlite3_column_count(sqlite3_stmt *pStmt); +const char *sqlite3_column_name(sqlite3_stmt*, int N); +int sqlite3_get_autocommit(sqlite3*); +int sqlite3_reset(sqlite3_stmt *pStmt); +int sqlite3_bind_parameter_count(sqlite3_stmt*); +int sqlite3_step(sqlite3_stmt*); +int sqlite3_errcode(sqlite3 *db); +const char *sqlite3_errmsg(sqlite3*); +int sqlite3_changes(sqlite3*); + +int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*)); +int sqlite3_bind_double(sqlite3_stmt*, int, double); +int sqlite3_bind_int(sqlite3_stmt*, int, int); +int sqlite3_bind_null(sqlite3_stmt*, int); +int sqlite3_bind_text(sqlite3_stmt*, int, const char*, int n, void(*)(void*)); +int sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void(*)(void*)); +int sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n); + +const void *sqlite3_column_blob(sqlite3_stmt*, int iCol); +int sqlite3_column_bytes(sqlite3_stmt*, int iCol); +double sqlite3_column_double(sqlite3_stmt*, int iCol); +int sqlite3_column_int(sqlite3_stmt*, int iCol); +sqlite3_int64 sqlite3_column_int64(sqlite3_stmt*, int iCol); +const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol); +const void *sqlite3_column_text16(sqlite3_stmt*, int iCol); +int sqlite3_column_type(sqlite3_stmt*, int iCol); +""") + +lib = ffi.verify(""" +#include +""", libraries=['sqlite3']) + +exported_sqlite_symbols = [ + 'SQLITE_ALTER_TABLE', + 'SQLITE_ANALYZE', + 'SQLITE_ATTACH', + 'SQLITE_CREATE_INDEX', + 'SQLITE_CREATE_TABLE', + 'SQLITE_CREATE_TEMP_INDEX', + 'SQLITE_CREATE_TEMP_TABLE', + 'SQLITE_CREATE_TEMP_TRIGGER', + 'SQLITE_CREATE_TEMP_VIEW', + 'SQLITE_CREATE_TRIGGER', + 'SQLITE_CREATE_VIEW', + 'SQLITE_DELETE', + 'SQLITE_DENY', + 'SQLITE_DETACH', + 'SQLITE_DROP_INDEX', + 'SQLITE_DROP_TABLE', + 'SQLITE_DROP_TEMP_INDEX', + 'SQLITE_DROP_TEMP_TABLE', + 'SQLITE_DROP_TEMP_TRIGGER', + 'SQLITE_DROP_TEMP_VIEW', + 'SQLITE_DROP_TRIGGER', + 'SQLITE_DROP_VIEW', + 'SQLITE_IGNORE', + 'SQLITE_INSERT', + 'SQLITE_OK', + 'SQLITE_PRAGMA', + 'SQLITE_READ', + 'SQLITE_REINDEX', + 'SQLITE_SELECT', + 'SQLITE_TRANSACTION', + 'SQLITE_UPDATE', +] + +for symbol in exported_sqlite_symbols: + globals()[symbol] = getattr(lib, symbol) + + +# OLD CTYPES STUFF: # pysqlite version information version = "2.6.0" @@ -49,200 +210,8 @@ PARSE_COLNAMES = 1 PARSE_DECLTYPES = 2 - -########################################## -# BEGIN Wrapped SQLite C API and constants -########################################## - -SQLITE_OK = 0 -SQLITE_ERROR = 1 -SQLITE_INTERNAL = 2 -SQLITE_PERM = 3 -SQLITE_ABORT = 4 -SQLITE_BUSY = 5 -SQLITE_LOCKED = 6 -SQLITE_NOMEM = 7 -SQLITE_READONLY = 8 -SQLITE_INTERRUPT = 9 -SQLITE_IOERR = 10 -SQLITE_CORRUPT = 11 -SQLITE_NOTFOUND = 12 -SQLITE_FULL = 13 -SQLITE_CANTOPEN = 14 -SQLITE_PROTOCOL = 15 -SQLITE_EMPTY = 16 -SQLITE_SCHEMA = 17 -SQLITE_TOOBIG = 18 -SQLITE_CONSTRAINT = 19 -SQLITE_MISMATCH = 20 -SQLITE_MISUSE = 21 -SQLITE_NOLFS = 22 -SQLITE_AUTH = 23 -SQLITE_FORMAT = 24 -SQLITE_RANGE = 25 -SQLITE_NOTADB = 26 -SQLITE_ROW = 100 -SQLITE_DONE = 101 -SQLITE_INTEGER = 1 -SQLITE_FLOAT = 2 -SQLITE_BLOB = 4 -SQLITE_NULL = 5 -SQLITE_TEXT = 3 -SQLITE3_TEXT = 3 - -SQLITE_TRANSIENT = cast(-1, c_void_p) -SQLITE_UTF8 = 1 - -SQLITE_DENY = 1 -SQLITE_IGNORE = 2 - -SQLITE_CREATE_INDEX = 1 -SQLITE_CREATE_TABLE = 2 -SQLITE_CREATE_TEMP_INDEX = 3 -SQLITE_CREATE_TEMP_TABLE = 4 -SQLITE_CREATE_TEMP_TRIGGER = 5 -SQLITE_CREATE_TEMP_VIEW = 6 -SQLITE_CREATE_TRIGGER = 7 -SQLITE_CREATE_VIEW = 8 -SQLITE_DELETE = 9 -SQLITE_DROP_INDEX = 10 -SQLITE_DROP_TABLE = 11 -SQLITE_DROP_TEMP_INDEX = 12 -SQLITE_DROP_TEMP_TABLE = 13 -SQLITE_DROP_TEMP_TRIGGER = 14 -SQLITE_DROP_TEMP_VIEW = 15 -SQLITE_DROP_TRIGGER = 16 -SQLITE_DROP_VIEW = 17 -SQLITE_INSERT = 18 -SQLITE_PRAGMA = 19 -SQLITE_READ = 20 -SQLITE_SELECT = 21 -SQLITE_TRANSACTION = 22 -SQLITE_UPDATE = 23 -SQLITE_ATTACH = 24 -SQLITE_DETACH = 25 -SQLITE_ALTER_TABLE = 26 -SQLITE_REINDEX = 27 -SQLITE_ANALYZE = 28 -SQLITE_CREATE_VTABLE = 29 -SQLITE_DROP_VTABLE = 30 -SQLITE_FUNCTION = 31 - -# SQLite C API - -sqlite.sqlite3_value_int.argtypes = [c_void_p] -sqlite.sqlite3_value_int.restype = c_int - -sqlite.sqlite3_value_int64.argtypes = [c_void_p] -sqlite.sqlite3_value_int64.restype = c_int64 - -sqlite.sqlite3_value_blob.argtypes = [c_void_p] -sqlite.sqlite3_value_blob.restype = c_void_p - -sqlite.sqlite3_value_bytes.argtypes = [c_void_p] -sqlite.sqlite3_value_bytes.restype = c_int - -sqlite.sqlite3_value_double.argtypes = [c_void_p] -sqlite.sqlite3_value_double.restype = c_double - -sqlite.sqlite3_value_text.argtypes = [c_void_p] -sqlite.sqlite3_value_text.restype = c_char_p - -sqlite.sqlite3_value_type.argtypes = [c_void_p] -sqlite.sqlite3_value_type.restype = c_int - -sqlite.sqlite3_bind_blob.argtypes = [c_void_p, c_int, c_void_p, c_int,c_void_p] -sqlite.sqlite3_bind_blob.restype = c_int -sqlite.sqlite3_bind_double.argtypes = [c_void_p, c_int, c_double] -sqlite.sqlite3_bind_double.restype = c_int -sqlite.sqlite3_bind_int.argtypes = [c_void_p, c_int, c_int] -sqlite.sqlite3_bind_int.restype = c_int -sqlite.sqlite3_bind_int64.argtypes = [c_void_p, c_int, c_int64] -sqlite.sqlite3_bind_int64.restype = c_int -sqlite.sqlite3_bind_null.argtypes = [c_void_p, c_int] -sqlite.sqlite3_bind_null.restype = c_int -sqlite.sqlite3_bind_parameter_count.argtypes = [c_void_p] -sqlite.sqlite3_bind_parameter_count.restype = c_int -sqlite.sqlite3_bind_parameter_index.argtypes = [c_void_p, c_char_p] -sqlite.sqlite3_bind_parameter_index.restype = c_int -sqlite.sqlite3_bind_parameter_name.argtypes = [c_void_p, c_int] -sqlite.sqlite3_bind_parameter_name.restype = c_char_p -sqlite.sqlite3_bind_text.argtypes = [c_void_p, c_int, c_char_p, c_int,c_void_p] -sqlite.sqlite3_bind_text.restype = c_int -sqlite.sqlite3_busy_timeout.argtypes = [c_void_p, c_int] -sqlite.sqlite3_busy_timeout.restype = c_int -sqlite.sqlite3_changes.argtypes = [c_void_p] -sqlite.sqlite3_changes.restype = c_int -sqlite.sqlite3_close.argtypes = [c_void_p] -sqlite.sqlite3_close.restype = c_int -sqlite.sqlite3_column_blob.argtypes = [c_void_p, c_int] -sqlite.sqlite3_column_blob.restype = c_void_p -sqlite.sqlite3_column_bytes.argtypes = [c_void_p, c_int] -sqlite.sqlite3_column_bytes.restype = c_int -sqlite.sqlite3_column_count.argtypes = [c_void_p] -sqlite.sqlite3_column_count.restype = c_int -sqlite.sqlite3_column_decltype.argtypes = [c_void_p, c_int] -sqlite.sqlite3_column_decltype.restype = c_char_p -sqlite.sqlite3_column_double.argtypes = [c_void_p, c_int] -sqlite.sqlite3_column_double.restype = c_double -sqlite.sqlite3_column_int64.argtypes = [c_void_p, c_int] -sqlite.sqlite3_column_int64.restype = c_int64 -sqlite.sqlite3_column_name.argtypes = [c_void_p, c_int] -sqlite.sqlite3_column_name.restype = c_char_p -sqlite.sqlite3_column_text.argtypes = [c_void_p, c_int] -sqlite.sqlite3_column_text.restype = POINTER(c_char) -sqlite.sqlite3_column_type.argtypes = [c_void_p, c_int] -sqlite.sqlite3_column_type.restype = c_int -sqlite.sqlite3_complete.argtypes = [c_char_p] -sqlite.sqlite3_complete.restype = c_int -sqlite.sqlite3_errcode.restype = c_int -sqlite.sqlite3_errmsg.argtypes = [c_void_p] -sqlite.sqlite3_errmsg.restype = c_char_p -sqlite.sqlite3_finalize.argtypes = [c_void_p] -sqlite.sqlite3_finalize.restype = c_int -sqlite.sqlite3_get_autocommit.argtypes = [c_void_p] -sqlite.sqlite3_get_autocommit.restype = c_int -sqlite.sqlite3_last_insert_rowid.argtypes = [c_void_p] -sqlite.sqlite3_last_insert_rowid.restype = c_int64 -sqlite.sqlite3_libversion.argtypes = [] -sqlite.sqlite3_libversion.restype = c_char_p -sqlite.sqlite3_open.argtypes = [c_char_p, c_void_p] -sqlite.sqlite3_open.restype = c_int -sqlite.sqlite3_prepare.argtypes = [c_void_p, c_char_p, c_int, c_void_p, POINTER(c_char_p)] -sqlite.sqlite3_prepare.restype = c_int -sqlite.sqlite3_prepare_v2.argtypes = [c_void_p, c_char_p, c_int, c_void_p, POINTER(c_char_p)] -sqlite.sqlite3_prepare_v2.restype = c_int -sqlite.sqlite3_step.argtypes = [c_void_p] -sqlite.sqlite3_step.restype = c_int -sqlite.sqlite3_reset.argtypes = [c_void_p] -sqlite.sqlite3_reset.restype = c_int -sqlite.sqlite3_total_changes.argtypes = [c_void_p] -sqlite.sqlite3_total_changes.restype = c_int - -sqlite.sqlite3_result_blob.argtypes = [c_void_p, c_char_p, c_int, c_void_p] -sqlite.sqlite3_result_blob.restype = None -sqlite.sqlite3_result_int64.argtypes = [c_void_p, c_int64] -sqlite.sqlite3_result_int64.restype = None -sqlite.sqlite3_result_null.argtypes = [c_void_p] -sqlite.sqlite3_result_null.restype = None -sqlite.sqlite3_result_double.argtypes = [c_void_p, c_double] -sqlite.sqlite3_result_double.restype = None -sqlite.sqlite3_result_error.argtypes = [c_void_p, c_char_p, c_int] -sqlite.sqlite3_result_error.restype = None -sqlite.sqlite3_result_text.argtypes = [c_void_p, c_char_p, c_int, c_void_p] -sqlite.sqlite3_result_text.restype = None - -HAS_LOAD_EXTENSION = hasattr(sqlite, "sqlite3_enable_load_extension") -if HAS_LOAD_EXTENSION: - sqlite.sqlite3_enable_load_extension.argtypes = [c_void_p, c_int] - sqlite.sqlite3_enable_load_extension.restype = c_int - -########################################## -# END Wrapped SQLite C API and constants -########################################## - # SQLite version information -sqlite_version = sqlite.sqlite3_libversion() +sqlite_version = ffi.string(lib.sqlite3_libversion()) class Error(StandardError): pass @@ -306,12 +275,14 @@ class Connection(object): def __init__(self, database, timeout=5.0, detect_types=0, isolation_level="", check_same_thread=True, factory=None, cached_statements=100): - self.db = c_void_p() - if sqlite.sqlite3_open(database, byref(self.db)) != SQLITE_OK: + #import pdb; pdb.set_trace() + db_star = ffi.new('sqlite3 **') + if lib.sqlite3_open(database, db_star) != lib.SQLITE_OK: raise OperationalError("Could not open database") + self.db = db_star[0] if timeout is not None: timeout = int(timeout * 1000) # pysqlite2 uses timeout in seconds - sqlite.sqlite3_busy_timeout(self.db, timeout) + lib.sqlite3_busy_timeout(self.db, timeout) self.text_factory = unicode_text_factory self.closed = False @@ -342,28 +313,28 @@ if check_same_thread: self.thread_ident = thread_get_ident() - def _get_exception(self, error_code = None): + def _get_exception(self, error_code=None): if error_code is None: - error_code = sqlite.sqlite3_errcode(self.db) - error_message = sqlite.sqlite3_errmsg(self.db) + error_code = lib.sqlite3_errcode(self.db) + error_message = ffi.string(lib.sqlite3_errmsg(self.db)) - if error_code == SQLITE_OK: - raise ValueError("error signalled but got SQLITE_OK") - elif error_code in (SQLITE_INTERNAL, SQLITE_NOTFOUND): + if error_code == lib.SQLITE_OK: + raise ValueError("error signalled but got lib.SQLITE_OK") + elif error_code in (lib.SQLITE_INTERNAL, lib.SQLITE_NOTFOUND): exc = InternalError - elif error_code == SQLITE_NOMEM: + elif error_code == lib.SQLITE_NOMEM: exc = MemoryError - elif error_code in (SQLITE_ERROR, SQLITE_PERM, SQLITE_ABORT, SQLITE_BUSY, SQLITE_LOCKED, - SQLITE_READONLY, SQLITE_INTERRUPT, SQLITE_IOERR, SQLITE_FULL, SQLITE_CANTOPEN, - SQLITE_PROTOCOL, SQLITE_EMPTY, SQLITE_SCHEMA): + elif error_code in (lib.SQLITE_ERROR, lib.SQLITE_PERM, lib.SQLITE_ABORT, lib.SQLITE_BUSY, lib.SQLITE_LOCKED, + lib.SQLITE_READONLY, lib.SQLITE_INTERRUPT, lib.SQLITE_IOERR, lib.SQLITE_FULL, lib.SQLITE_CANTOPEN, + lib.SQLITE_PROTOCOL, lib.SQLITE_EMPTY, lib.SQLITE_SCHEMA): exc = OperationalError - elif error_code == SQLITE_CORRUPT: + elif error_code == lib.SQLITE_CORRUPT: exc = DatabaseError - elif error_code == SQLITE_TOOBIG: + elif error_code == lib.SQLITE_TOOBIG: exc = DataError - elif error_code in (SQLITE_CONSTRAINT, SQLITE_MISMATCH): + elif error_code in (lib.SQLITE_CONSTRAINT, lib.SQLITE_MISMATCH): exc = IntegrityError - elif error_code == SQLITE_MISUSE: + elif error_code == lib.SQLITE_MISUSE: exc = ProgrammingError else: exc = DatabaseError @@ -445,24 +416,25 @@ self._check_closed() if self._isolation_level is None: return - if sqlite.sqlite3_get_autocommit(self.db): + if lib.sqlite3_get_autocommit(self.db): + sql = "BEGIN " + self._isolation_level + statement_star = ffi.new('sqlite3_stmt **') + next_char = ffi.new('char **') + ret = lib.sqlite3_prepare_v2(self.db, sql, -1, statement_star, + next_char) try: - sql = "BEGIN " + self._isolation_level - statement = c_void_p() - next_char = c_char_p() - ret = sqlite.sqlite3_prepare_v2(self.db, sql, -1, byref(statement), next_char) - if ret != SQLITE_OK: + if ret != lib.SQLITE_OK: raise self._get_exception(ret) - ret = sqlite.sqlite3_step(statement) - if ret != SQLITE_DONE: + ret = lib.sqlite3_step(statement_star[0]) + if ret != lib.SQLITE_DONE: raise self._get_exception(ret) finally: - sqlite.sqlite3_finalize(statement) + lib.sqlite3_finalize(statement_star[0]) def commit(self): self._check_thread() self._check_closed() - if sqlite.sqlite3_get_autocommit(self.db): + if lib.sqlite3_get_autocommit(self.db): return for statement in self.statements: @@ -470,23 +442,23 @@ if obj is not None: obj.reset() + sql = "COMMIT" + statement_star = ffi.new('sqlite3_stmt **') + next_char = ffi.new('char **') + ret = lib.sqlite3_prepare_v2(self.db, sql, -1, statement_star, next_char) try: - sql = "COMMIT" - statement = c_void_p() - next_char = c_char_p() - ret = sqlite.sqlite3_prepare_v2(self.db, sql, -1, byref(statement), next_char) - if ret != SQLITE_OK: + if ret != lib.SQLITE_OK: raise self._get_exception(ret) - ret = sqlite.sqlite3_step(statement) - if ret != SQLITE_DONE: + ret = lib.sqlite3_step(statement_star[0]) + if ret != lib.SQLITE_DONE: raise self._get_exception(ret) finally: - sqlite.sqlite3_finalize(statement) + lib.sqlite3_finalize(statement_star[0]) def rollback(self): self._check_thread() self._check_closed() - if sqlite.sqlite3_get_autocommit(self.db): + if lib.sqlite3_get_autocommit(self.db): return for statement in self.statements: @@ -499,13 +471,13 @@ statement = c_void_p() next_char = c_char_p() ret = sqlite.sqlite3_prepare_v2(self.db, sql, -1, byref(statement), next_char) - if ret != SQLITE_OK: + if ret != lib.SQLITE_OK: raise self._get_exception(ret) - ret = sqlite.sqlite3_step(statement) - if ret != SQLITE_DONE: + ret = lib.sqlite3_step(statement) + if ret != lib.SQLITE_DONE: raise self._get_exception(ret) finally: - sqlite.sqlite3_finalize(statement) + lib.sqlite3_finalize(statement) self._reset_cursors() def _check_closed(self): @@ -535,9 +507,9 @@ obj.finalize() self.closed = True - ret = sqlite.sqlite3_close(self.db) + ret = lib.sqlite3_close(self.db) self._reset_cursors() - if ret != SQLITE_OK: + if ret != lib.SQLITE_OK: raise self._get_exception(ret) def create_collation(self, name, callback): @@ -565,10 +537,10 @@ ret = sqlite.sqlite3_create_collation(self.db, name, - SQLITE_UTF8, + lib.SQLITE_UTF8, None, c_collation_callback) - if ret != SQLITE_OK: + if ret != lib.SQLITE_OK: raise self._get_exception(ret) def set_progress_handler(self, callable, nsteps): @@ -593,7 +565,7 @@ ret = sqlite.sqlite3_progress_handler(self.db, nsteps, c_progress_handler, None) - if ret != SQLITE_OK: + if ret != lib.SQLITE_OK: raise self._get_exception(ret) def set_authorizer(self, callback): @@ -607,7 +579,7 @@ try: return int(callback(action, arg1, arg2, dbname, source)) except Exception: - return SQLITE_DENY + return lib.SQLITE_DENY c_authorizer = AUTHORIZER(authorizer) self.func_cache[callback] = c_authorizer, authorizer @@ -615,7 +587,7 @@ ret = sqlite.sqlite3_set_authorizer(self.db, c_authorizer, None) - if ret != SQLITE_OK: + if ret != lib.SQLITE_OK: raise self._get_exception(ret) def create_function(self, name, num_args, callback): @@ -629,11 +601,11 @@ c_closure = FUNC(closure) self.func_cache[callback] = c_closure, closure ret = sqlite.sqlite3_create_function(self.db, name, num_args, - SQLITE_UTF8, None, + lib.SQLITE_UTF8, None, c_closure, cast(None, STEP), cast(None, FINAL)) - if ret != SQLITE_OK: + if ret != lib.SQLITE_OK: raise self.OperationalError("Error creating function") def create_aggregate(self, name, num_args, cls): @@ -699,24 +671,24 @@ step_callback, final_callback) ret = sqlite.sqlite3_create_function(self.db, name, num_args, - SQLITE_UTF8, None, + lib.SQLITE_UTF8, None, cast(None, FUNC), c_step_callback, c_final_callback) - if ret != SQLITE_OK: + if ret != lib.SQLITE_OK: raise self._get_exception(ret) def iterdump(self): from sqlite3.dump import _iterdump return _iterdump(self) - if HAS_LOAD_EXTENSION: + if False and HAS_LOAD_EXTENSION: def enable_load_extension(self, enabled): self._check_thread() self._check_closed() rc = sqlite.sqlite3_enable_load_extension(self.db, int(enabled)) - if rc != SQLITE_OK: + if rc != lib.SQLITE_OK: raise OperationalError("Error enabling load extension") DML, DQL, DDL = range(3) @@ -779,15 +751,15 @@ self.statement.set_params(params) # Actually execute the SQL statement - ret = sqlite.sqlite3_step(self.statement.statement) - if ret not in (SQLITE_DONE, SQLITE_ROW): + ret = lib.sqlite3_step(self.statement.statement) + if ret not in (lib.SQLITE_DONE, lib.SQLITE_ROW): self.statement.reset() raise self.connection._get_exception(ret) if self.statement.kind == DML: self.statement.reset() - if self.statement.kind == DQL and ret == SQLITE_ROW: + if self.statement.kind == DQL and ret == lib.SQLITE_ROW: self.statement._build_row_cast_map() self.statement._readahead(self) else: @@ -796,7 +768,7 @@ self.rowcount = -1 if self.statement.kind == DML: - self.rowcount = sqlite.sqlite3_changes(self.connection.db) + self.rowcount = lib.sqlite3_changes(self.connection.db) return self @@ -818,10 +790,10 @@ self.rowcount = 0 for params in many_params: self.statement.set_params(params) - ret = sqlite.sqlite3_step(self.statement.statement) - if ret != SQLITE_DONE: + ret = lib.sqlite3_step(self.statement.statement) + if ret != lib.SQLITE_DONE: raise self.connection._get_exception(ret) - self.rowcount += sqlite.sqlite3_changes(self.connection.db) + self.rowcount += lib.sqlite3_changes(self.connection.db) return self @@ -837,24 +809,24 @@ self.connection.commit() while True: rc = sqlite.sqlite3_prepare(self.connection.db, c_sql, -1, byref(statement), byref(c_sql)) - if rc != SQLITE_OK: + if rc != lib.SQLITE_OK: raise self.connection._get_exception(rc) - rc = SQLITE_ROW - while rc == SQLITE_ROW: + rc = lib.SQLITE_ROW + while rc == lib.SQLITE_ROW: if not statement: - rc = SQLITE_OK + rc = lib.SQLITE_OK else: - rc = sqlite.sqlite3_step(statement) + rc = lib.sqlite3_step(statement) - if rc != SQLITE_DONE: - sqlite.sqlite3_finalize(statement) - if rc == SQLITE_OK: + if rc != lib.SQLITE_DONE: + lib.sqlite3_finalize(statement) + if rc == lib.SQLITE_OK: return self else: raise self.connection._get_exception(rc) - rc = sqlite.sqlite3_finalize(statement) - if rc != SQLITE_OK: + rc = lib.sqlite3_finalize(statement) + if rc != lib.SQLITE_OK: raise self.connection._get_exception(rc) if not c_sql.value: @@ -951,21 +923,24 @@ # set by set_row_factory self.row_factory = None - self.statement = c_void_p() - next_char = c_char_p() - sql_char = c_char_p(sql) - ret = sqlite.sqlite3_prepare_v2(self.con.db, sql_char, -1, byref(self.statement), byref(next_char)) - if ret == SQLITE_OK and self.statement.value is None: + statement_star = ffi.new('sqlite3_stmt **') + next_char = ffi.new('char **') + ret = lib.sqlite3_prepare_v2(self.con.db, sql, -1, + statement_star, next_char) + self.statement = statement_star[0] + if ret == lib.SQLITE_OK and not self.statement: # an empty statement, we work around that, as it's the least trouble - ret = sqlite.sqlite3_prepare_v2(self.con.db, "select 42", -1, byref(self.statement), byref(next_char)) + ret = lib.sqlite3_prepare_v2(self.con.db, "select 42", -1, + statement_star, next_char) + self.statement = statement_star[0] self.kind = DQL - if ret != SQLITE_OK: + if ret != lib.SQLITE_OK: raise self.con._get_exception(ret) self.con._remember_statement(self) - if _check_remaining_sql(next_char.value): + if _check_remaining_sql(ffi.string(next_char[0])): raise Warning("One and only one statement required: %r" % ( - next_char.value,)) + next_char[0],)) # sql_char should remain alive until here self._build_row_cast_map() @@ -975,7 +950,7 @@ def _build_row_cast_map(self): self.row_cast_map = [] - for i in xrange(sqlite.sqlite3_column_count(self.statement)): + for i in xrange(lib.sqlite3_column_count(self.statement)): converter = None if self.con.detect_types & PARSE_COLNAMES: @@ -1029,23 +1004,24 @@ sqlite.sqlite3_bind_double(self.statement, idx, param) elif isinstance(param, str): self._check_decodable(param) - sqlite.sqlite3_bind_text(self.statement, idx, param, len(param), SQLITE_TRANSIENT) + lib.sqlite3_bind_text(self.statement, idx, param, len(param), + ffi.cast('void *', lib.SQLITE_TRANSIENT)) elif isinstance(param, unicode): param = param.encode("utf-8") - sqlite.sqlite3_bind_text(self.statement, idx, param, len(param), SQLITE_TRANSIENT) + lib.sqlite3_bind_text(self.statement, idx, param, len(param), lib.SQLITE_TRANSIENT) elif type(param) is buffer: - sqlite.sqlite3_bind_blob(self.statement, idx, str(param), len(param), SQLITE_TRANSIENT) + sqlite.sqlite3_bind_blob(self.statement, idx, str(param), len(param), lib.SQLITE_TRANSIENT) else: raise InterfaceError("parameter type %s is not supported" % str(type(param))) def set_params(self, params): - ret = sqlite.sqlite3_reset(self.statement) - if ret != SQLITE_OK: + ret = lib.sqlite3_reset(self.statement) + if ret != lib.SQLITE_OK: raise self.con._get_exception(ret) self.mark_dirty() if params is None: - if sqlite.sqlite3_bind_parameter_count(self.statement) != 0: + if lib.sqlite3_bind_parameter_count(self.statement) != 0: raise ProgrammingError("wrong number of arguments") return @@ -1056,13 +1032,13 @@ params_type = list if params_type == list: - if len(params) != sqlite.sqlite3_bind_parameter_count(self.statement): + if len(params) != lib.sqlite3_bind_parameter_count(self.statement): raise ProgrammingError("wrong number of arguments") for i in range(len(params)): self.set_param(i+1, params[i]) else: - for idx in range(1, sqlite.sqlite3_bind_parameter_count(self.statement) + 1): + for idx in range(1, lib.sqlite3_bind_parameter_count(self.statement) + 1): param_name = sqlite.sqlite3_bind_parameter_name(self.statement, idx) if param_name is None: raise ProgrammingError("need named parameters") @@ -1080,50 +1056,50 @@ raise StopIteration item = self.item - ret = sqlite.sqlite3_step(self.statement) - if ret == SQLITE_DONE: + ret = lib.sqlite3_step(self.statement) + if ret == lib.SQLITE_DONE: self.exhausted = True self.item = None - elif ret != SQLITE_ROW: + elif ret != lib.SQLITE_ROW: exc = self.con._get_exception(ret) - sqlite.sqlite3_reset(self.statement) + lib.sqlite3_reset(self.statement) raise exc self._readahead(cursor) return item def _readahead(self, cursor): - self.column_count = sqlite.sqlite3_column_count(self.statement) + self.column_count = lib.sqlite3_column_count(self.statement) row = [] for i in xrange(self.column_count): - typ = sqlite.sqlite3_column_type(self.statement, i) + typ = lib.sqlite3_column_type(self.statement, i) converter = self.row_cast_map[i] if converter is None: - if typ == SQLITE_INTEGER: - val = sqlite.sqlite3_column_int64(self.statement, i) + if typ == lib.SQLITE_INTEGER: + val = lib.sqlite3_column_int64(self.statement, i) if -sys.maxint-1 <= val <= sys.maxint: val = int(val) - elif typ == SQLITE_FLOAT: - val = sqlite.sqlite3_column_double(self.statement, i) - elif typ == SQLITE_BLOB: - blob_len = sqlite.sqlite3_column_bytes(self.statement, i) - blob = sqlite.sqlite3_column_blob(self.statement, i) - val = buffer(string_at(blob, blob_len)) - elif typ == SQLITE_NULL: + elif typ == lib.SQLITE_FLOAT: + val = lib.sqlite3_column_double(self.statement, i) + elif typ == lib.SQLITE_BLOB: + blob_len = lib.sqlite3_column_bytes(self.statement, i) + blob = lib.sqlite3_column_blob(self.statement, i) + val = ffi.buffer(blob, blob_len)[:] + elif typ == lib.SQLITE_NULL: val = None - elif typ == SQLITE_TEXT: - text_len = sqlite.sqlite3_column_bytes(self.statement, i) - text = sqlite.sqlite3_column_text(self.statement, i) - val = string_at(text, text_len) + elif typ == lib.SQLITE_TEXT: + text_len = lib.sqlite3_column_bytes(self.statement, i) + text = lib.sqlite3_column_text(self.statement, i) + val = ffi.buffer(text, text_len)[:] val = self.con.text_factory(val) else: - blob = sqlite.sqlite3_column_blob(self.statement, i) + blob = lib.sqlite3_column_blob(self.statement, i) if not blob: val = None else: - blob_len = sqlite.sqlite3_column_bytes(self.statement, i) - val = string_at(blob, blob_len) + blob_len = lib.sqlite3_column_bytes(self.statement, i) + val = ffi.buffer(blob, blob_len)[:] val = converter(val) row.append(val) @@ -1134,13 +1110,13 @@ def reset(self): self.row_cast_map = None - ret = sqlite.sqlite3_reset(self.statement) + ret = lib.sqlite3_reset(self.statement) self.in_use = False self.exhausted = False return ret def finalize(self): - sqlite.sqlite3_finalize(self.statement) + lib.sqlite3_finalize(self.statement) self.statement = None self.in_use = False @@ -1148,15 +1124,15 @@ self.in_use = True def __del__(self): - sqlite.sqlite3_finalize(self.statement) + lib.sqlite3_finalize(self.statement) self.statement = None def _get_description(self): if self.kind == DML: return None desc = [] - for i in xrange(sqlite.sqlite3_column_count(self.statement)): - name = sqlite.sqlite3_column_name(self.statement, i).split("[")[0].strip() + for i in xrange(lib.sqlite3_column_count(self.statement)): + name = lib.sqlite3_column_name(self.statement, i).split("[")[0].strip() desc.append((name, None, None, None, None, None, None)) return desc @@ -1239,19 +1215,19 @@ _params = [] for i in range(nargs): typ = sqlite.sqlite3_value_type(params[i]) - if typ == SQLITE_INTEGER: + if typ == lib.SQLITE_INTEGER: val = sqlite.sqlite3_value_int64(params[i]) if -sys.maxint-1 <= val <= sys.maxint: val = int(val) - elif typ == SQLITE_FLOAT: + elif typ == lib.SQLITE_FLOAT: val = sqlite.sqlite3_value_double(params[i]) - elif typ == SQLITE_BLOB: + elif typ == lib.SQLITE_BLOB: blob_len = sqlite.sqlite3_value_bytes(params[i]) blob = sqlite.sqlite3_value_blob(params[i]) val = buffer(string_at(blob, blob_len)) - elif typ == SQLITE_NULL: + elif typ == lib.SQLITE_NULL: val = None - elif typ == SQLITE_TEXT: + elif typ == lib.SQLITE_TEXT: val = sqlite.sqlite3_value_text(params[i]) # XXX changed from con.text_factory val = unicode(val, 'utf-8') @@ -1267,14 +1243,14 @@ sqlite.sqlite3_result_int64(con, int(val)) elif isinstance(val, str): # XXX ignoring unicode issue - sqlite.sqlite3_result_text(con, val, len(val), SQLITE_TRANSIENT) + sqlite.sqlite3_result_text(con, val, len(val), lib.SQLITE_TRANSIENT) elif isinstance(val, unicode): val = val.encode('utf-8') - sqlite.sqlite3_result_text(con, val, len(val), SQLITE_TRANSIENT) + sqlite.sqlite3_result_text(con, val, len(val), lib.SQLITE_TRANSIENT) elif isinstance(val, float): sqlite.sqlite3_result_double(con, val) elif isinstance(val, buffer): - sqlite.sqlite3_result_blob(con, str(val), len(val), SQLITE_TRANSIENT) + sqlite.sqlite3_result_blob(con, str(val), len(val), lib.SQLITE_TRANSIENT) else: raise NotImplementedError @@ -1288,26 +1264,26 @@ else: _convert_result(context, val) -FUNC = CFUNCTYPE(None, c_void_p, c_int, POINTER(c_void_p)) -STEP = CFUNCTYPE(None, c_void_p, c_int, POINTER(c_void_p)) -FINAL = CFUNCTYPE(None, c_void_p) -sqlite.sqlite3_create_function.argtypes = [c_void_p, c_char_p, c_int, c_int, c_void_p, FUNC, STEP, FINAL] -sqlite.sqlite3_create_function.restype = c_int - -sqlite.sqlite3_aggregate_context.argtypes = [c_void_p, c_int] -sqlite.sqlite3_aggregate_context.restype = c_void_p - -COLLATION = CFUNCTYPE(c_int, c_void_p, c_int, c_void_p, c_int, c_void_p) -sqlite.sqlite3_create_collation.argtypes = [c_void_p, c_char_p, c_int, c_void_p, COLLATION] -sqlite.sqlite3_create_collation.restype = c_int - -PROGRESS = CFUNCTYPE(c_int, c_void_p) -sqlite.sqlite3_progress_handler.argtypes = [c_void_p, c_int, PROGRESS, c_void_p] -sqlite.sqlite3_progress_handler.restype = c_int - -AUTHORIZER = CFUNCTYPE(c_int, c_void_p, c_int, c_char_p, c_char_p, c_char_p, c_char_p) -sqlite.sqlite3_set_authorizer.argtypes = [c_void_p, AUTHORIZER, c_void_p] -sqlite.sqlite3_set_authorizer.restype = c_int +#FUNC = CFUNCTYPE(None, c_void_p, c_int, POINTER(c_void_p)) +#STEP = CFUNCTYPE(None, c_void_p, c_int, POINTER(c_void_p)) +#FINAL = CFUNCTYPE(None, c_void_p) +#sqlite.sqlite3_create_function.argtypes = [c_void_p, c_char_p, c_int, c_int, c_void_p, FUNC, STEP, FINAL] +#sqlite.sqlite3_create_function.restype = c_int +# +#sqlite.sqlite3_aggregate_context.argtypes = [c_void_p, c_int] +#sqlite.sqlite3_aggregate_context.restype = c_void_p +# +#COLLATION = CFUNCTYPE(c_int, c_void_p, c_int, c_void_p, c_int, c_void_p) +#sqlite.sqlite3_create_collation.argtypes = [c_void_p, c_char_p, c_int, c_void_p, COLLATION] +#sqlite.sqlite3_create_collation.restype = c_int +# +#PROGRESS = CFUNCTYPE(c_int, c_void_p) +#sqlite.sqlite3_progress_handler.argtypes = [c_void_p, c_int, PROGRESS, c_void_p] +#sqlite.sqlite3_progress_handler.restype = c_int +# +#AUTHORIZER = CFUNCTYPE(c_int, c_void_p, c_int, c_char_p, c_char_p, c_char_p, c_char_p) +#sqlite.sqlite3_set_authorizer.argtypes = [c_void_p, AUTHORIZER, c_void_p] +#sqlite.sqlite3_set_authorizer.restype = c_int converters = {} adapters = {} From noreply at buildbot.pypy.org Wed Feb 27 01:46:12 2013 From: noreply at buildbot.pypy.org (jerith) Date: Wed, 27 Feb 2013 01:46:12 +0100 (CET) Subject: [pypy-commit] pypy sqlite-cffi: More CFFI sqlite3 wrapper. Only a few user function tests still failing. Message-ID: <20130227004612.082801C01A7@cobra.cs.uni-duesseldorf.de> Author: Jeremy Thurgood Branch: sqlite-cffi Changeset: r61832:826b3efd7edf Date: 2013-02-27 02:45 +0200 http://bitbucket.org/pypy/pypy/changeset/826b3efd7edf/ Log: More CFFI sqlite3 wrapper. Only a few user function tests still failing. diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -112,6 +112,8 @@ typedef ... sqlite3; typedef ... sqlite3_stmt; +typedef ... sqlite3_context; +typedef ... sqlite3_value; typedef int64_t sqlite3_int64; typedef uint64_t sqlite3_uint64; @@ -135,7 +137,6 @@ const char *sqlite3_column_name(sqlite3_stmt*, int N); int sqlite3_get_autocommit(sqlite3*); int sqlite3_reset(sqlite3_stmt *pStmt); -int sqlite3_bind_parameter_count(sqlite3_stmt*); int sqlite3_step(sqlite3_stmt*); int sqlite3_errcode(sqlite3 *db); const char *sqlite3_errmsg(sqlite3*); @@ -144,9 +145,11 @@ int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*)); int sqlite3_bind_double(sqlite3_stmt*, int, double); int sqlite3_bind_int(sqlite3_stmt*, int, int); +int sqlite3_bind_int64(sqlite3_stmt*, int, sqlite3_int64); int sqlite3_bind_null(sqlite3_stmt*, int); int sqlite3_bind_text(sqlite3_stmt*, int, const char*, int n, void(*)(void*)); int sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void(*)(void*)); +int sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*); int sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n); const void *sqlite3_column_blob(sqlite3_stmt*, int iCol); @@ -157,6 +160,75 @@ const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol); const void *sqlite3_column_text16(sqlite3_stmt*, int iCol); int sqlite3_column_type(sqlite3_stmt*, int iCol); +const char *sqlite3_column_decltype(sqlite3_stmt*,int); + +void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); +int sqlite3_create_collation( + sqlite3*, + const char *zName, + int eTextRep, + void*, + int(*xCompare)(void*,int,const void*,int,const void*) +); +int sqlite3_set_authorizer( + sqlite3*, + int (*xAuth)(void*,int,const char*,const char*,const char*,const char*), + void *pUserData +); +int sqlite3_create_function( + sqlite3 *db, + const char *zFunctionName, + int nArg, + int eTextRep, + void *pApp, + void (*xFunc)(sqlite3_context*,int,sqlite3_value**), + void (*xStep)(sqlite3_context*,int,sqlite3_value**), + void (*xFinal)(sqlite3_context*) +); +void *sqlite3_aggregate_context(sqlite3_context*, int nBytes); + +sqlite3_int64 sqlite3_last_insert_rowid(sqlite3*); +int sqlite3_bind_parameter_count(sqlite3_stmt*); +const char *sqlite3_bind_parameter_name(sqlite3_stmt*, int); +int sqlite3_total_changes(sqlite3*); + +int sqlite3_prepare( + sqlite3 *db, /* Database handle */ + const char *zSql, /* SQL statement, UTF-8 encoded */ + int nByte, /* Maximum length of zSql in bytes. */ + sqlite3_stmt **ppStmt, /* OUT: Statement handle */ + const char **pzTail /* OUT: Pointer to unused portion of zSql */ +); + +void sqlite3_result_blob(sqlite3_context*, const void*, int, void(*)(void*)); +void sqlite3_result_double(sqlite3_context*, double); +void sqlite3_result_error(sqlite3_context*, const char*, int); +void sqlite3_result_error16(sqlite3_context*, const void*, int); +void sqlite3_result_error_toobig(sqlite3_context*); +void sqlite3_result_error_nomem(sqlite3_context*); +void sqlite3_result_error_code(sqlite3_context*, int); +void sqlite3_result_int(sqlite3_context*, int); +void sqlite3_result_int64(sqlite3_context*, sqlite3_int64); +void sqlite3_result_null(sqlite3_context*); +void sqlite3_result_text(sqlite3_context*, const char*, int, void(*)(void*)); +void sqlite3_result_text16(sqlite3_context*, const void*, int, void(*)(void*)); +void sqlite3_result_text16le(sqlite3_context*,const void*, int,void(*)(void*)); +void sqlite3_result_text16be(sqlite3_context*,const void*, int,void(*)(void*)); +void sqlite3_result_value(sqlite3_context*, sqlite3_value*); +void sqlite3_result_zeroblob(sqlite3_context*, int n); + +const void *sqlite3_value_blob(sqlite3_value*); +int sqlite3_value_bytes(sqlite3_value*); +int sqlite3_value_bytes16(sqlite3_value*); +double sqlite3_value_double(sqlite3_value*); +int sqlite3_value_int(sqlite3_value*); +sqlite3_int64 sqlite3_value_int64(sqlite3_value*); +const unsigned char *sqlite3_value_text(sqlite3_value*); +const void *sqlite3_value_text16(sqlite3_value*); +const void *sqlite3_value_text16le(sqlite3_value*); +const void *sqlite3_value_text16be(sqlite3_value*); +int sqlite3_value_type(sqlite3_value*); +int sqlite3_value_numeric_type(sqlite3_value*); """) lib = ffi.verify(""" @@ -201,7 +273,8 @@ globals()[symbol] = getattr(lib, symbol) -# OLD CTYPES STUFF: +_SQLITE_TRANSIENT = ffi.cast('void *', lib.SQLITE_TRANSIENT) + # pysqlite version information version = "2.6.0" @@ -213,40 +286,52 @@ # SQLite version information sqlite_version = ffi.string(lib.sqlite3_libversion()) + class Error(StandardError): pass + class Warning(StandardError): pass + class InterfaceError(Error): pass + class DatabaseError(Error): pass + class InternalError(DatabaseError): pass + class OperationalError(DatabaseError): pass + class ProgrammingError(DatabaseError): pass + class IntegrityError(DatabaseError): pass + class DataError(DatabaseError): pass + class NotSupportedError(DatabaseError): pass + def connect(database, **kwargs): factory = kwargs.get("factory", Connection) return factory(database, **kwargs) + def unicode_text_factory(x): return unicode(x, 'utf-8') @@ -273,15 +358,17 @@ class Connection(object): - def __init__(self, database, timeout=5.0, detect_types=0, isolation_level="", - check_same_thread=True, factory=None, cached_statements=100): - #import pdb; pdb.set_trace() + def __init__(self, database, timeout=5.0, detect_types=0, + isolation_level="", check_same_thread=True, factory=None, + cached_statements=100): db_star = ffi.new('sqlite3 **') + if isinstance(database, unicode): + database = database.encode("utf-8") if lib.sqlite3_open(database, db_star) != lib.SQLITE_OK: raise OperationalError("Could not open database") self.db = db_star[0] if timeout is not None: - timeout = int(timeout * 1000) # pysqlite2 uses timeout in seconds + timeout = int(timeout * 1000) # pysqlite2 uses timeout in seconds lib.sqlite3_busy_timeout(self.db, timeout) self.text_factory = unicode_text_factory @@ -324,9 +411,12 @@ exc = InternalError elif error_code == lib.SQLITE_NOMEM: exc = MemoryError - elif error_code in (lib.SQLITE_ERROR, lib.SQLITE_PERM, lib.SQLITE_ABORT, lib.SQLITE_BUSY, lib.SQLITE_LOCKED, - lib.SQLITE_READONLY, lib.SQLITE_INTERRUPT, lib.SQLITE_IOERR, lib.SQLITE_FULL, lib.SQLITE_CANTOPEN, - lib.SQLITE_PROTOCOL, lib.SQLITE_EMPTY, lib.SQLITE_SCHEMA): + elif error_code in ( + lib.SQLITE_ERROR, lib.SQLITE_PERM, lib.SQLITE_ABORT, + lib.SQLITE_BUSY, lib.SQLITE_LOCKED, lib.SQLITE_READONLY, + lib.SQLITE_INTERRUPT, lib.SQLITE_IOERR, lib.SQLITE_FULL, + lib.SQLITE_CANTOPEN, lib.SQLITE_PROTOCOL, lib.SQLITE_EMPTY, + lib.SQLITE_SCHEMA): exc = OperationalError elif error_code == lib.SQLITE_CORRUPT: exc = DatabaseError @@ -347,16 +437,17 @@ self.statement_counter += 1 if self.statement_counter % 100 == 0: - self.statements = [ref for ref in self.statements if ref() is not None] + self.statements = [ref for ref in self.statements + if ref() is not None] def _check_thread(self): if not hasattr(self, 'thread_ident'): return if self.thread_ident != thread_get_ident(): raise ProgrammingError( - "SQLite objects created in a thread can only be used in that same thread." - "The object was created in thread id %d and this is thread id %d", - self.thread_ident, thread_get_ident()) + "SQLite objects created in a thread can only be used in that " + "same thread. The object was created in thread id %d and this " + "is thread id %d", self.thread_ident, thread_get_ident()) def _reset_cursors(self): for cursor_ref in self.cursors: @@ -404,6 +495,7 @@ def _get_isolation_level(self): return self._isolation_level + def _set_isolation_level(self, val): if val is None: self.commit() @@ -445,7 +537,8 @@ sql = "COMMIT" statement_star = ffi.new('sqlite3_stmt **') next_char = ffi.new('char **') - ret = lib.sqlite3_prepare_v2(self.db, sql, -1, statement_star, next_char) + ret = lib.sqlite3_prepare_v2(self.db, sql, -1, statement_star, + next_char) try: if ret != lib.SQLITE_OK: raise self._get_exception(ret) @@ -466,18 +559,19 @@ if obj is not None: obj.reset() + sql = "ROLLBACK" + statement_star = ffi.new('sqlite3_stmt **') + next_char = ffi.new('char **') + ret = lib.sqlite3_prepare_v2(self.db, sql, -1, statement_star, + next_char) try: - sql = "ROLLBACK" - statement = c_void_p() - next_char = c_char_p() - ret = sqlite.sqlite3_prepare_v2(self.db, sql, -1, byref(statement), next_char) if ret != lib.SQLITE_OK: raise self._get_exception(ret) - ret = lib.sqlite3_step(statement) + ret = lib.sqlite3_step(statement_star[0]) if ret != lib.SQLITE_DONE: raise self._get_exception(ret) finally: - lib.sqlite3_finalize(statement) + lib.sqlite3_finalize(statement_star[0]) self._reset_cursors() def _check_closed(self): @@ -494,7 +588,7 @@ self.rollback() def _get_total_changes(self): - return sqlite.sqlite3_total_changes(self.db) + return lib.sqlite3_total_changes(self.db) total_changes = property(_get_total_changes) def close(self): @@ -521,25 +615,22 @@ if callback is None: del self._collations[name] - c_collation_callback = cast(None, COLLATION) + collation_callback = ffi.NULL else: if not callable(callback): raise TypeError("parameter must be callable") + @ffi.callback("int(void*, int, const void*, int, const void*)") def collation_callback(context, len1, str1, len2, str2): - text1 = string_at(str1, len1) - text2 = string_at(str2, len2) + text1 = ffi.buffer(str1, len1)[:] + text2 = ffi.buffer(str2, len2)[:] return callback(text1, text2) - c_collation_callback = COLLATION(collation_callback) - self._collations[name] = c_collation_callback + self._collations[name] = collation_callback - - ret = sqlite.sqlite3_create_collation(self.db, name, - lib.SQLITE_UTF8, - None, - c_collation_callback) + ret = lib.sqlite3_create_collation(self.db, name, lib.SQLITE_UTF8, + ffi.NULL, collation_callback) if ret != lib.SQLITE_OK: raise self._get_exception(ret) @@ -547,11 +638,12 @@ self._check_thread() self._check_closed() if callable is None: - c_progress_handler = cast(None, PROGRESS) + progress_handler = ffi.NULL else: try: - c_progress_handler, _ = self.func_cache[callable] + progress_handler = self.func_cache[callable] except KeyError: + @ffi.callback("int(void*)") def progress_handler(userdata): try: ret = callable() @@ -559,34 +651,28 @@ except Exception: # abort query if error occurred return 1 - c_progress_handler = PROGRESS(progress_handler) - self.func_cache[callable] = c_progress_handler, progress_handler - ret = sqlite.sqlite3_progress_handler(self.db, nsteps, - c_progress_handler, - None) - if ret != lib.SQLITE_OK: - raise self._get_exception(ret) + self.func_cache[callable] = progress_handler + lib.sqlite3_progress_handler(self.db, nsteps, progress_handler, + ffi.NULL) def set_authorizer(self, callback): self._check_thread() self._check_closed() try: - c_authorizer, _ = self.func_cache[callback] + authorizer = self.func_cache[callback] except KeyError: + @ffi.callback("int(void*, int, const char*, const char*, " + "const char*, const char*)") def authorizer(userdata, action, arg1, arg2, dbname, source): try: return int(callback(action, arg1, arg2, dbname, source)) except Exception: return lib.SQLITE_DENY - c_authorizer = AUTHORIZER(authorizer) + self.func_cache[callback] = authorizer - self.func_cache[callback] = c_authorizer, authorizer - - ret = sqlite.sqlite3_set_authorizer(self.db, - c_authorizer, - None) + ret = lib.sqlite3_set_authorizer(self.db, authorizer, ffi.NULL) if ret != lib.SQLITE_OK: raise self._get_exception(ret) @@ -594,17 +680,15 @@ self._check_thread() self._check_closed() try: - c_closure, _ = self.func_cache[callback] + closure = self.func_cache[callback] except KeyError: + @ffi.callback("void(sqlite3_context*, int, sqlite3_value**)") def closure(context, nargs, c_params): function_callback(callback, context, nargs, c_params) - c_closure = FUNC(closure) - self.func_cache[callback] = c_closure, closure - ret = sqlite.sqlite3_create_function(self.db, name, num_args, - lib.SQLITE_UTF8, None, - c_closure, - cast(None, STEP), - cast(None, FINAL)) + self.func_cache[callback] = closure + ret = lib.sqlite3_create_function(self.db, name, num_args, + lib.SQLITE_UTF8, ffi.NULL, + closure, ffi.NULL, ffi.NULL) if ret != lib.SQLITE_OK: raise self.OperationalError("Error creating function") @@ -613,14 +697,13 @@ self._check_closed() try: - c_step_callback, c_final_callback, _, _ = self._aggregates[cls] + step_callback, final_callback = self._aggregates[cls] except KeyError: + @ffi.callback("void(sqlite3_context*, int, sqlite3_value**)") def step_callback(context, argc, c_params): - - aggregate_ptr = cast( - sqlite.sqlite3_aggregate_context( - context, sizeof(c_ssize_t)), - POINTER(c_ssize_t)) + res = lib.sqlite3_aggregate_context(context, + ffi.sizeof("size_t")) + aggregate_ptr = ffi.cast("size_t *", res) if not aggregate_ptr[0]: try: @@ -628,7 +711,7 @@ except Exception: msg = ("user-defined aggregate's '__init__' " "method raised error") - sqlite.sqlite3_result_error(context, msg, len(msg)) + lib.sqlite3_result_error(context, msg, len(msg)) return aggregate_id = id(aggregate) self.aggregate_instances[aggregate_id] = aggregate @@ -642,14 +725,13 @@ except Exception: msg = ("user-defined aggregate's 'step' " "method raised error") - sqlite.sqlite3_result_error(context, msg, len(msg)) + lib.sqlite3_result_error(context, msg, len(msg)) + @ffi.callback("void(sqlite3_context*)") def final_callback(context): - - aggregate_ptr = cast( - sqlite.sqlite3_aggregate_context( - context, sizeof(c_ssize_t)), - POINTER(c_ssize_t)) + res = lib.sqlite3_aggregate_context(context, + ffi.sizeof("size_t")) + aggregate_ptr = ffi.cast("size_t", res) if aggregate_ptr[0]: aggregate = self.aggregate_instances[aggregate_ptr[0]] @@ -658,23 +740,17 @@ except Exception: msg = ("user-defined aggregate's 'finalize' " "method raised error") - sqlite.sqlite3_result_error(context, msg, len(msg)) + lib.sqlite3_result_error(context, msg, len(msg)) else: _convert_result(context, val) finally: del self.aggregate_instances[aggregate_ptr[0]] - c_step_callback = STEP(step_callback) - c_final_callback = FINAL(final_callback) + self._aggregates[cls] = step_callback, final_callback - self._aggregates[cls] = (c_step_callback, c_final_callback, - step_callback, final_callback) - - ret = sqlite.sqlite3_create_function(self.db, name, num_args, - lib.SQLITE_UTF8, None, - cast(None, FUNC), - c_step_callback, - c_final_callback) + ret = lib.sqlite3_create_function(self.db, name, num_args, + lib.SQLITE_UTF8, ffi.NULL, ffi.NULL, + step_callback, final_callback) if ret != lib.SQLITE_OK: raise self._get_exception(ret) @@ -682,17 +758,19 @@ from sqlite3.dump import _iterdump return _iterdump(self) - if False and HAS_LOAD_EXTENSION: + if False and lib.HAS_LOAD_EXTENSION: def enable_load_extension(self, enabled): self._check_thread() self._check_closed() - rc = sqlite.sqlite3_enable_load_extension(self.db, int(enabled)) + rc = lib.sqlite3_enable_load_extension(self.db, int(enabled)) if rc != lib.SQLITE_OK: raise OperationalError("Error enabling load extension") + DML, DQL, DDL = range(3) + class CursorLock(object): def __init__(self, cursor): self.cursor = cursor @@ -785,7 +863,8 @@ if self.statement.kind == DML: self.connection._begin() else: - raise ProgrammingError("executemany is only for DML statements") + raise ProgrammingError( + "executemany is only for DML statements") self.rowcount = 0 for params in many_params: @@ -803,33 +882,35 @@ if type(sql) is unicode: sql = sql.encode("utf-8") self._check_closed() - statement = c_void_p() - c_sql = c_char_p(sql) + statement_star = ffi.new('sqlite3_stmt **') + tail = ffi.new('char **') self.connection.commit() while True: - rc = sqlite.sqlite3_prepare(self.connection.db, c_sql, -1, byref(statement), byref(c_sql)) + rc = lib.sqlite3_prepare(self.connection.db, sql, -1, + statement_star, tail) + sql = ffi.string(tail[0]) if rc != lib.SQLITE_OK: raise self.connection._get_exception(rc) rc = lib.SQLITE_ROW while rc == lib.SQLITE_ROW: - if not statement: + if not statement_star[0]: rc = lib.SQLITE_OK else: - rc = lib.sqlite3_step(statement) + rc = lib.sqlite3_step(statement_star[0]) if rc != lib.SQLITE_DONE: - lib.sqlite3_finalize(statement) + lib.sqlite3_finalize(statement_star[0]) if rc == lib.SQLITE_OK: return self else: raise self.connection._get_exception(rc) - rc = lib.sqlite3_finalize(statement) + rc = lib.sqlite3_finalize(statement_star[0]) if rc != lib.SQLITE_OK: raise self.connection._get_exception(rc) - if not c_sql.value: + if not sql: break return self @@ -838,9 +919,9 @@ def _check_reset(self): if self.reset: - raise self.connection.InterfaceError("Cursor needed to be reset because " - "of commit/rollback and can " - "no longer be fetched from.") + raise self.connection.InterfaceError( + "Cursor needed to be reset because of commit/rollback and can " + "no longer be fetched from.") # do all statements def fetchone(self): @@ -882,7 +963,7 @@ return self._description def _getlastrowid(self): - return sqlite.sqlite3_last_insert_rowid(self.connection.db) + return lib.sqlite3_last_insert_rowid(self.connection.db) def close(self): if not self.connection: @@ -896,20 +977,21 @@ def setinputsizes(self, *args): pass + def setoutputsize(self, *args): pass - description = property(_getdescription) lastrowid = property(_getlastrowid) + class Statement(object): def __init__(self, connection, sql): self.statement = None if not isinstance(sql, str): raise ValueError("sql must be a string") self.con = connection - self.sql = sql # DEBUG ONLY + self.sql = sql # DEBUG ONLY first_word = self._statement_kind = sql.lstrip().split(" ")[0].upper() if first_word in ("INSERT", "UPDATE", "DELETE", "REPLACE"): self.kind = DML @@ -929,7 +1011,7 @@ statement_star, next_char) self.statement = statement_star[0] if ret == lib.SQLITE_OK and not self.statement: - # an empty statement, we work around that, as it's the least trouble + # an empty statement, we work around that as it's the least trouble ret = lib.sqlite3_prepare_v2(self.con.db, "select 42", -1, statement_star, next_char) self.statement = statement_star[0] @@ -954,8 +1036,9 @@ converter = None if self.con.detect_types & PARSE_COLNAMES: - colname = sqlite.sqlite3_column_name(self.statement, i) - if colname is not None: + colname = lib.sqlite3_column_name(self.statement, i) + if colname != ffi.NULL: + colname = ffi.string(colname) type_start = -1 key = None for pos in range(len(colname)): @@ -966,9 +1049,11 @@ converter = converters[key.upper()] if converter is None and self.con.detect_types & PARSE_DECLTYPES: - decltype = sqlite.sqlite3_column_decltype(self.statement, i) - if decltype is not None: - decltype = decltype.split()[0] # if multiple words, use first, eg. "INTEGER NOT NULL" => "INTEGER" + decltype = lib.sqlite3_column_decltype(self.statement, i) + if decltype is not ffi.NULL: + # if multiple words, use first, + # eg. "INTEGER NOT NULL" => "INTEGER" + decltype = ffi.string(decltype).split()[0] if '(' in decltype: decltype = decltype[:decltype.index('(')] converter = converters.get(decltype.upper(), None) @@ -976,7 +1061,8 @@ self.row_cast_map.append(converter) def _check_decodable(self, param): - if self.con.text_factory in (unicode, OptimizedUnicode, unicode_text_factory): + if self.con.text_factory in (unicode, OptimizedUnicode, + unicode_text_factory): for c in param: if ord(c) & 0x80 != 0: raise self.con.ProgrammingError( @@ -994,25 +1080,28 @@ param = adapt(param) if param is None: - sqlite.sqlite3_bind_null(self.statement, idx) + lib.sqlite3_bind_null(self.statement, idx) elif type(param) in (bool, int, long): if -2147483648 <= param <= 2147483647: - sqlite.sqlite3_bind_int(self.statement, idx, param) + lib.sqlite3_bind_int(self.statement, idx, param) else: - sqlite.sqlite3_bind_int64(self.statement, idx, param) + lib.sqlite3_bind_int64(self.statement, idx, param) elif type(param) is float: - sqlite.sqlite3_bind_double(self.statement, idx, param) + lib.sqlite3_bind_double(self.statement, idx, param) elif isinstance(param, str): self._check_decodable(param) lib.sqlite3_bind_text(self.statement, idx, param, len(param), - ffi.cast('void *', lib.SQLITE_TRANSIENT)) + _SQLITE_TRANSIENT) elif isinstance(param, unicode): param = param.encode("utf-8") - lib.sqlite3_bind_text(self.statement, idx, param, len(param), lib.SQLITE_TRANSIENT) + lib.sqlite3_bind_text(self.statement, idx, param, len(param), + _SQLITE_TRANSIENT) elif type(param) is buffer: - sqlite.sqlite3_bind_blob(self.statement, idx, str(param), len(param), lib.SQLITE_TRANSIENT) + lib.sqlite3_bind_blob(self.statement, idx, str(param), len(param), + _SQLITE_TRANSIENT) else: - raise InterfaceError("parameter type %s is not supported" % str(type(param))) + raise InterfaceError( + "parameter type %s is not supported" % str(type(param))) def set_params(self, params): ret = lib.sqlite3_reset(self.statement) @@ -1036,17 +1125,19 @@ raise ProgrammingError("wrong number of arguments") for i in range(len(params)): - self.set_param(i+1, params[i]) + self.set_param(i + 1, params[i]) else: - for idx in range(1, lib.sqlite3_bind_parameter_count(self.statement) + 1): - param_name = sqlite.sqlite3_bind_parameter_name(self.statement, idx) - if param_name is None: + param_count = lib.sqlite3_bind_parameter_count(self.statement) + for idx in range(1, param_count + 1): + param_name = lib.sqlite3_bind_parameter_name(self.statement, + idx) + if param_name == ffi.NULL: raise ProgrammingError("need named parameters") - param_name = param_name[1:] + param_name = ffi.string(param_name)[1:] try: param = params[param_name] except KeyError: - raise ProgrammingError("missing parameter '%s'" %param) + raise ProgrammingError("missing parameter '%s'" % param) self.set_param(idx, param) def next(self, cursor): @@ -1078,14 +1169,14 @@ if converter is None: if typ == lib.SQLITE_INTEGER: val = lib.sqlite3_column_int64(self.statement, i) - if -sys.maxint-1 <= val <= sys.maxint: + if -sys.maxint - 1 <= val <= sys.maxint: val = int(val) elif typ == lib.SQLITE_FLOAT: val = lib.sqlite3_column_double(self.statement, i) elif typ == lib.SQLITE_BLOB: blob_len = lib.sqlite3_column_bytes(self.statement, i) blob = lib.sqlite3_column_blob(self.statement, i) - val = ffi.buffer(blob, blob_len)[:] + val = buffer(ffi.buffer(blob, blob_len)) elif typ == lib.SQLITE_NULL: val = None elif typ == lib.SQLITE_TEXT: @@ -1132,10 +1223,12 @@ return None desc = [] for i in xrange(lib.sqlite3_column_count(self.statement)): - name = lib.sqlite3_column_name(self.statement, i).split("[")[0].strip() + name = lib.sqlite3_column_name(self.statement, i) + name = ffi.string(name).split("[")[0].strip() desc.append((name, None, None, None, None, None, None)) return desc + class Row(object): def __init__(self, cursor, values): self.description = cursor.description @@ -1169,6 +1262,7 @@ def __hash__(self): return hash(tuple(self.description)) ^ hash(tuple(self.values)) + def _check_remaining_sql(s): state = "NORMAL" for char in s: @@ -1211,24 +1305,25 @@ return 1 return 0 + def _convert_params(con, nargs, params): - _params = [] + _params = [] for i in range(nargs): - typ = sqlite.sqlite3_value_type(params[i]) + typ = lib.sqlite3_value_type(params[i]) if typ == lib.SQLITE_INTEGER: - val = sqlite.sqlite3_value_int64(params[i]) - if -sys.maxint-1 <= val <= sys.maxint: + val = lib.sqlite3_value_int64(params[i]) + if -sys.maxint - 1 <= val <= sys.maxint: val = int(val) elif typ == lib.SQLITE_FLOAT: - val = sqlite.sqlite3_value_double(params[i]) + val = lib.sqlite3_value_double(params[i]) elif typ == lib.SQLITE_BLOB: - blob_len = sqlite.sqlite3_value_bytes(params[i]) - blob = sqlite.sqlite3_value_blob(params[i]) - val = buffer(string_at(blob, blob_len)) + blob_len = lib.sqlite3_value_bytes(params[i]) + blob = lib.sqlite3_value_blob(params[i]) + val = ffi.buffer(blob, blob_len)[:] elif typ == lib.SQLITE_NULL: val = None elif typ == lib.SQLITE_TEXT: - val = sqlite.sqlite3_value_text(params[i]) + val = lib.sqlite3_value_text(params[i]) # XXX changed from con.text_factory val = unicode(val, 'utf-8') else: @@ -1236,67 +1331,53 @@ _params.append(val) return _params + def _convert_result(con, val): if val is None: - sqlite.sqlite3_result_null(con) + lib.sqlite3_result_null(con) elif isinstance(val, (bool, int, long)): - sqlite.sqlite3_result_int64(con, int(val)) + lib.sqlite3_result_int64(con, int(val)) elif isinstance(val, str): # XXX ignoring unicode issue - sqlite.sqlite3_result_text(con, val, len(val), lib.SQLITE_TRANSIENT) + lib.sqlite3_result_text(con, val, len(val), _SQLITE_TRANSIENT) elif isinstance(val, unicode): val = val.encode('utf-8') - sqlite.sqlite3_result_text(con, val, len(val), lib.SQLITE_TRANSIENT) + lib.sqlite3_result_text(con, val, len(val), _SQLITE_TRANSIENT) elif isinstance(val, float): - sqlite.sqlite3_result_double(con, val) + lib.sqlite3_result_double(con, val) elif isinstance(val, buffer): - sqlite.sqlite3_result_blob(con, str(val), len(val), lib.SQLITE_TRANSIENT) + lib.sqlite3_result_blob(con, str(val), len(val), _SQLITE_TRANSIENT) else: raise NotImplementedError + def function_callback(real_cb, context, nargs, c_params): params = _convert_params(context, nargs, c_params) try: val = real_cb(*params) except Exception: msg = "user-defined function raised exception" - sqlite.sqlite3_result_error(context, msg, len(msg)) + lib.sqlite3_result_error(context, msg, len(msg)) else: _convert_result(context, val) -#FUNC = CFUNCTYPE(None, c_void_p, c_int, POINTER(c_void_p)) -#STEP = CFUNCTYPE(None, c_void_p, c_int, POINTER(c_void_p)) -#FINAL = CFUNCTYPE(None, c_void_p) -#sqlite.sqlite3_create_function.argtypes = [c_void_p, c_char_p, c_int, c_int, c_void_p, FUNC, STEP, FINAL] -#sqlite.sqlite3_create_function.restype = c_int -# -#sqlite.sqlite3_aggregate_context.argtypes = [c_void_p, c_int] -#sqlite.sqlite3_aggregate_context.restype = c_void_p -# -#COLLATION = CFUNCTYPE(c_int, c_void_p, c_int, c_void_p, c_int, c_void_p) -#sqlite.sqlite3_create_collation.argtypes = [c_void_p, c_char_p, c_int, c_void_p, COLLATION] -#sqlite.sqlite3_create_collation.restype = c_int -# -#PROGRESS = CFUNCTYPE(c_int, c_void_p) -#sqlite.sqlite3_progress_handler.argtypes = [c_void_p, c_int, PROGRESS, c_void_p] -#sqlite.sqlite3_progress_handler.restype = c_int -# -#AUTHORIZER = CFUNCTYPE(c_int, c_void_p, c_int, c_char_p, c_char_p, c_char_p, c_char_p) -#sqlite.sqlite3_set_authorizer.argtypes = [c_void_p, AUTHORIZER, c_void_p] -#sqlite.sqlite3_set_authorizer.restype = c_int converters = {} adapters = {} + class PrepareProtocol(object): pass + def register_adapter(typ, callable): adapters[typ, PrepareProtocol] = callable + def register_converter(name, callable): converters[name.upper()] = callable + def register_adapters_and_converters(): def adapt_date(val): return val.isoformat() @@ -1317,15 +1398,16 @@ else: microseconds = 0 - val = datetime.datetime(year, month, day, hours, minutes, seconds, microseconds) + val = datetime.datetime(year, month, day, hours, minutes, seconds, + microseconds) return val - register_adapter(datetime.date, adapt_date) register_adapter(datetime.datetime, adapt_datetime) register_converter("date", convert_date) register_converter("timestamp", convert_timestamp) + def adapt(val, proto=PrepareProtocol): # look for an adapter in the registry adapter = adapters.get((type(val), proto), None) @@ -1356,6 +1438,7 @@ register_adapters_and_converters() + def OptimizedUnicode(s): try: val = unicode(s, "ascii").encode("ascii") From noreply at buildbot.pypy.org Wed Feb 27 08:41:16 2013 From: noreply at buildbot.pypy.org (jerith) Date: Wed, 27 Feb 2013 08:41:16 +0100 (CET) Subject: [pypy-commit] pypy sqlite-cffi: All sqlite tests pass with cffi implementation. Message-ID: <20130227074116.81F4C1C0133@cobra.cs.uni-duesseldorf.de> Author: Jeremy Thurgood Branch: sqlite-cffi Changeset: r61833:622307cc3927 Date: 2013-02-27 09:40 +0200 http://bitbucket.org/pypy/pypy/changeset/622307cc3927/ Log: All sqlite tests pass with cffi implementation. diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -703,7 +703,7 @@ def step_callback(context, argc, c_params): res = lib.sqlite3_aggregate_context(context, ffi.sizeof("size_t")) - aggregate_ptr = ffi.cast("size_t *", res) + aggregate_ptr = ffi.cast("size_t[1]", res) if not aggregate_ptr[0]: try: @@ -731,7 +731,7 @@ def final_callback(context): res = lib.sqlite3_aggregate_context(context, ffi.sizeof("size_t")) - aggregate_ptr = ffi.cast("size_t", res) + aggregate_ptr = ffi.cast("size_t[1]", res) if aggregate_ptr[0]: aggregate = self.aggregate_instances[aggregate_ptr[0]] @@ -987,7 +987,7 @@ class Statement(object): def __init__(self, connection, sql): - self.statement = None + self.statement = ffi.NULL if not isinstance(sql, str): raise ValueError("sql must be a string") self.con = connection @@ -1208,7 +1208,7 @@ def finalize(self): lib.sqlite3_finalize(self.statement) - self.statement = None + self.statement = ffi.NULL self.in_use = False def mark_dirty(self): @@ -1216,7 +1216,7 @@ def __del__(self): lib.sqlite3_finalize(self.statement) - self.statement = None + self.statement = ffi.NULL def _get_description(self): if self.kind == DML: @@ -1319,13 +1319,13 @@ elif typ == lib.SQLITE_BLOB: blob_len = lib.sqlite3_value_bytes(params[i]) blob = lib.sqlite3_value_blob(params[i]) - val = ffi.buffer(blob, blob_len)[:] + val = buffer(ffi.buffer(blob, blob_len)) elif typ == lib.SQLITE_NULL: val = None elif typ == lib.SQLITE_TEXT: val = lib.sqlite3_value_text(params[i]) # XXX changed from con.text_factory - val = unicode(val, 'utf-8') + val = unicode(ffi.string(val), 'utf-8') else: raise NotImplementedError _params.append(val) From noreply at buildbot.pypy.org Wed Feb 27 10:38:36 2013 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 27 Feb 2013 10:38:36 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: a test and a fix (and we're not done yet) Message-ID: <20130227093836.7B13B1C0327@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61834:4f5cc418bac8 Date: 2013-02-27 11:38 +0200 http://bitbucket.org/pypy/pypy/changeset/4f5cc418bac8/ Log: a test and a fix (and we're not done yet) diff --git a/rpython/jit/backend/llsupport/test/test_gc_integration.py b/rpython/jit/backend/llsupport/test/test_gc_integration.py --- a/rpython/jit/backend/llsupport/test/test_gc_integration.py +++ b/rpython/jit/backend/llsupport/test/test_gc_integration.py @@ -651,18 +651,21 @@ invoke_around_extcall(before, after) - def f(x): + def f(frame, x): + # all the gc pointers are alive p1 -> p7 (but not p0) + assert bin(frame.jf_gcmap[0]).count('1') == 7 assert x == 1 return 2 - FUNC = lltype.FuncType([lltype.Signed], lltype.Signed) + FUNC = lltype.FuncType([JITFRAMEPTR, lltype.Signed], lltype.Signed) fptr = llhelper(lltype.Ptr(FUNC), f) calldescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, EffectInfo.MOST_GENERAL) loop = self.parse(""" - [i0] - i1 = call_release_gil(ConstClass(fptr), i0, descr=calldescr) - guard_not_forced(descr=faildescr) [] + [i0, p1, p2, p3, p4, p5, p6, p7] + p0 = force_token() + i1 = call_release_gil(ConstClass(fptr), p0, i0, descr=calldescr) + guard_not_forced(descr=faildescr) [p1, p2, p3, p4, p5, p6, p7] finish(i1, descr=finaldescr) """, namespace={'fptr': fptr, 'calldescr':calldescr, 'faildescr': BasicFailDescr(), @@ -671,7 +674,8 @@ cpu.gc_ll_descr.init_nursery(100) cpu.setup_once() cpu.compile_loop(loop.inputargs, loop.operations, token) - frame = cpu.execute_token(token, 1) + args = [lltype.nullptr(llmemory.GCREF.TO) for i in range(7)] + frame = cpu.execute_token(token, 1, *args) frame = rffi.cast(JITFRAMEPTR, frame) assert frame.jf_frame[0] == 2 assert l == ['before', 'after'] diff --git a/rpython/jit/backend/x86/regalloc.py b/rpython/jit/backend/x86/regalloc.py --- a/rpython/jit/backend/x86/regalloc.py +++ b/rpython/jit/backend/x86/regalloc.py @@ -876,13 +876,13 @@ for box, loc in self.rm.reg_bindings.iteritems(): if loc in forbidden_regs: continue - if box.type == REF and self.rm.stays_alive(box): + if box.type == REF and self.rm.is_still_alive(box): assert not noregs assert isinstance(loc, RegLoc) val = gpr_reg_mgr_cls.all_reg_indexes[loc.value] gcmap[val // WORD // 8] |= r_uint(1) << (val % (WORD * 8)) for box, loc in self.fm.bindings.iteritems(): - if box.type == REF and self.rm.stays_alive(box): + if box.type == REF and self.rm.is_still_alive(box): assert isinstance(loc, FrameLoc) val = loc.position + JITFRAME_FIXED_SIZE gcmap[val // WORD // 8] |= r_uint(1) << (val % (WORD * 8)) From noreply at buildbot.pypy.org Wed Feb 27 10:47:46 2013 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 27 Feb 2013 10:47:46 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: Write some more tests, surprisingly passing Message-ID: <20130227094746.34D541C01A7@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61835:281c51f5311f Date: 2013-02-27 11:47 +0200 http://bitbucket.org/pypy/pypy/changeset/281c51f5311f/ Log: Write some more tests, surprisingly passing diff --git a/rpython/jit/backend/llsupport/test/test_gc_integration.py b/rpython/jit/backend/llsupport/test/test_gc_integration.py --- a/rpython/jit/backend/llsupport/test/test_gc_integration.py +++ b/rpython/jit/backend/llsupport/test/test_gc_integration.py @@ -679,3 +679,39 @@ frame = rffi.cast(JITFRAMEPTR, frame) assert frame.jf_frame[0] == 2 assert l == ['before', 'after'] + + def test_call_may_force_gcmap(self): + cpu = self.cpu + + def f(frame, x): + assert frame.jf_gcmap[0] & 31 == 0 + assert x == 1 + return 2 + + FUNC = lltype.FuncType([JITFRAMEPTR, lltype.Signed], lltype.Signed) + fptr = llhelper(lltype.Ptr(FUNC), f) + calldescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, + EffectInfo.MOST_GENERAL) + + A = lltype.GcArray(lltype.Ptr(lltype.GcArray(lltype.Signed))) + a = lltype.malloc(A, 3, zero=True) + + loop = self.parse(""" + [i0, p0] + pf = force_token() + p1 = getarrayitem_gc(p0, 0, descr=arraydescr) + p2 = getarrayitem_gc(p0, 1, descr=arraydescr) + p3 = getarrayitem_gc(p0, 2, descr=arraydescr) + i3 = call_may_force(ConstClass(fptr), pf, i0, descr=calldescr) + guard_not_forced(descr=faildescr) [p1, p2, p3] + finish(i3, descr=finishdescr) + """, namespace={'fptr': fptr, 'calldescr': calldescr, + 'arraydescr': cpu.arraydescrof(A), + 'faildescr': BasicFailDescr(1), + 'finaldescr': BasicFinalDescr(2)}) + + token = JitCellToken() + cpu.gc_ll_descr.init_nursery(100) + cpu.setup_once() + cpu.compile_loop(loop.inputargs, loop.operations, token) + cpu.execute_token(token, 1, a) From noreply at buildbot.pypy.org Wed Feb 27 10:53:26 2013 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 27 Feb 2013 10:53:26 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: fix Message-ID: <20130227095326.D77421C01A7@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61836:feefc84bc9da Date: 2013-02-27 11:53 +0200 http://bitbucket.org/pypy/pypy/changeset/feefc84bc9da/ Log: fix diff --git a/rpython/jit/backend/llsupport/test/test_gc_integration.py b/rpython/jit/backend/llsupport/test/test_gc_integration.py --- a/rpython/jit/backend/llsupport/test/test_gc_integration.py +++ b/rpython/jit/backend/llsupport/test/test_gc_integration.py @@ -685,10 +685,11 @@ def f(frame, x): assert frame.jf_gcmap[0] & 31 == 0 + frame.jf_descr = frame.jf_force_descr # make guard_not_forced fail assert x == 1 - return 2 + return lltype.nullptr(llmemory.GCREF.TO) - FUNC = lltype.FuncType([JITFRAMEPTR, lltype.Signed], lltype.Signed) + FUNC = lltype.FuncType([JITFRAMEPTR, lltype.Signed], llmemory.GCREF) fptr = llhelper(lltype.Ptr(FUNC), f) calldescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, EffectInfo.MOST_GENERAL) @@ -702,9 +703,9 @@ p1 = getarrayitem_gc(p0, 0, descr=arraydescr) p2 = getarrayitem_gc(p0, 1, descr=arraydescr) p3 = getarrayitem_gc(p0, 2, descr=arraydescr) - i3 = call_may_force(ConstClass(fptr), pf, i0, descr=calldescr) - guard_not_forced(descr=faildescr) [p1, p2, p3] - finish(i3, descr=finishdescr) + px = call_may_force(ConstClass(fptr), pf, i0, descr=calldescr) + guard_not_forced(descr=faildescr) [p1, p2, p3, px] + finish(px, descr=finishdescr) """, namespace={'fptr': fptr, 'calldescr': calldescr, 'arraydescr': cpu.arraydescrof(A), 'faildescr': BasicFailDescr(1), @@ -714,4 +715,6 @@ cpu.gc_ll_descr.init_nursery(100) cpu.setup_once() cpu.compile_loop(loop.inputargs, loop.operations, token) - cpu.execute_token(token, 1, a) + frame = lltype.cast_opaque_ptr(JITFRAMEPTR, + cpu.execute_token(token, 1, a)) + assert bin(frame.jf_gcmap[0]).count('1') == 4 From noreply at buildbot.pypy.org Wed Feb 27 12:22:40 2013 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 27 Feb 2013 12:22:40 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: remove unused imports Message-ID: <20130227112240.8AFD11C3C52@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61837:74664d129663 Date: 2013-02-27 13:22 +0200 http://bitbucket.org/pypy/pypy/changeset/74664d129663/ Log: remove unused imports diff --git a/rpython/jit/backend/arm/opassembler.py b/rpython/jit/backend/arm/opassembler.py --- a/rpython/jit/backend/arm/opassembler.py +++ b/rpython/jit/backend/arm/opassembler.py @@ -26,11 +26,10 @@ from rpython.jit.backend.llsupport.descr import InteriorFieldDescr from rpython.jit.backend.llsupport.assembler import GuardToken, BaseAssembler from rpython.jit.metainterp.history import (Box, AbstractFailDescr, - INT, FLOAT, REF) -from rpython.jit.metainterp.history import JitCellToken, TargetToken + INT, FLOAT) +from rpython.jit.metainterp.history import TargetToken from rpython.jit.metainterp.resoperation import rop from rpython.rlib.objectmodel import we_are_translated -from rpython.rlib import rgc from rpython.rtyper.lltypesystem import rstr, rffi, lltype from rpython.rtyper.annlowlevel import cast_instance_to_gcref From noreply at buildbot.pypy.org Wed Feb 27 12:29:25 2013 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 27 Feb 2013 12:29:25 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: use non-negative numbers Message-ID: <20130227112925.3C91C1C3C52@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61838:fa3ab400bb19 Date: 2013-02-27 13:29 +0200 http://bitbucket.org/pypy/pypy/changeset/fa3ab400bb19/ Log: use non-negative numbers diff --git a/rpython/jit/backend/arm/assembler.py b/rpython/jit/backend/arm/assembler.py --- a/rpython/jit/backend/arm/assembler.py +++ b/rpython/jit/backend/arm/assembler.py @@ -711,7 +711,8 @@ debug_start("jit-backend-addr") debug_print("bridge out of Guard %d has address %x to %x" % - (descr_number, rawstart, rawstart + codeendpos)) + (descr_number, r_uint(rawstart), + r_uint(rawstart + codeendpos))) debug_stop("jit-backend-addr") return AsmInfo(ops_offset, startpos + rawstart, codeendpos - startpos) From noreply at buildbot.pypy.org Wed Feb 27 12:33:42 2013 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 27 Feb 2013 12:33:42 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: be consistently nicer Message-ID: <20130227113342.344EE1C240F@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61839:52f577300225 Date: 2013-02-27 13:33 +0200 http://bitbucket.org/pypy/pypy/changeset/52f577300225/ Log: be consistently nicer diff --git a/rpython/jit/backend/arm/assembler.py b/rpython/jit/backend/arm/assembler.py --- a/rpython/jit/backend/arm/assembler.py +++ b/rpython/jit/backend/arm/assembler.py @@ -636,11 +636,11 @@ self.teardown() debug_start("jit-backend-addr") - debug_print("Loop %d (%s) has address %x to %x (bootstrap %x)" % ( + debug_print("Loop %d (%s) has address 0x%x to 0x%x (bootstrap 0x%x)" % ( looptoken.number, loopname, - rawstart + loop_head, - rawstart + size_excluding_failure_stuff, - rawstart)) + r_uint(rawstart + loop_head), + r_uint(rawstart + size_excluding_failure_stuff), + r_uint(rawstart))) debug_stop("jit-backend-addr") return AsmInfo(ops_offset, rawstart + loop_head, @@ -710,7 +710,7 @@ self.teardown() debug_start("jit-backend-addr") - debug_print("bridge out of Guard %d has address %x to %x" % + debug_print("bridge out of Guard %d has address 0x%x to 0x%x" % (descr_number, r_uint(rawstart), r_uint(rawstart + codeendpos))) debug_stop("jit-backend-addr") diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -494,7 +494,7 @@ rawstart = self.materialize_loop(looptoken) looptoken._ll_loop_code = looppos + rawstart debug_start("jit-backend-addr") - debug_print("Loop %d (%s) has address %x to %x (bootstrap %x)" % ( + debug_print("Loop %d (%s) has address 0x%x to 0x%x (bootstrap 0x%x)" % ( looptoken.number, loopname, r_uint(rawstart + looppos), r_uint(rawstart + size_excluding_failure_stuff), @@ -548,8 +548,8 @@ # rawstart = self.materialize_loop(original_loop_token) debug_start("jit-backend-addr") - debug_print("bridge out of Guard %x has address %x to %x" % - (descr_number, r_uint(rawstart), + debug_print("bridge out of Guard 0x%x has address 0x%x to 0x%x" % + (r_uint(descr_number), r_uint(rawstart), r_uint(rawstart + codeendpos))) debug_stop("jit-backend-addr") self.patch_pending_failure_recoveries(rawstart) diff --git a/rpython/jit/metainterp/logger.py b/rpython/jit/metainterp/logger.py --- a/rpython/jit/metainterp/logger.py +++ b/rpython/jit/metainterp/logger.py @@ -42,7 +42,8 @@ debug_stop("jit-log-compiling-bridge") else: debug_start("jit-log-opt-bridge") - debug_print("# bridge out of Guard", compute_unique_id(descr), + debug_print("# bridge out of Guard", + "%x" % compute_unique_id(descr), "with", len(operations), "ops") logops = self._log_operations(inputargs, operations, ops_offset) debug_stop("jit-log-opt-bridge") @@ -133,7 +134,7 @@ descr = op.getdescr() if is_guard and self.guard_number: hash = compute_unique_id(descr) - r = "" % hash + r = "" % hash else: r = self.repr_of_descr(descr) if args: From noreply at buildbot.pypy.org Wed Feb 27 12:41:10 2013 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 27 Feb 2013 12:41:10 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: fix those tests (I hope) Message-ID: <20130227114110.F18B81C0133@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61840:1bd69b83126f Date: 2013-02-27 13:40 +0200 http://bitbucket.org/pypy/pypy/changeset/1bd69b83126f/ Log: fix those tests (I hope) diff --git a/pypy/tool/jitlogparser/parser.py b/pypy/tool/jitlogparser/parser.py --- a/pypy/tool/jitlogparser/parser.py +++ b/pypy/tool/jitlogparser/parser.py @@ -34,7 +34,7 @@ self.descr = descr self._is_guard = name.startswith('guard_') if self._is_guard: - self.guard_no = int(self.descr[len(') + guard_false(v0, descr=) guard_true(v0, descr=) ''') bridge = parse(''' - # bridge out of Guard 13 + # bridge out of Guard 1a [] int_add(0, 1) ''') LoopStorage().reconnect_loops([main, bridge]) assert adjust_bridges(main, {})[1].name == 'guard_true' - assert adjust_bridges(main, {'loop-13': True})[1].name == 'int_add' + assert adjust_bridges(main, {'loop-1a': True})[1].name == 'int_add' def test_parsing_strliteral(): loop = parse(""" @@ -259,7 +259,7 @@ +348: i32 = int_is_true(i31) +360: i33 = int_or(i27, i32) +364: i34 = int_is_true(i33) -guard_false(i34, descr=) [i1, i22, p2] +guard_false(i34, descr=) [i1, i22, p2] +372: i35 = int_add(i22, 1) debug_merge_point(0, 're StrMatchIn at 92 [17. 4. 0. 20. 393237. 21. 0. 29. 9. 1. 65535. 15. 4. 9. 3. 0. 1. 21. 1. 29. 9. 1. 65535. 15. 4. 9. 2. 0. 1. 1...') +376: jump(i35, i1, p2, p4, descr=TargetToken(1081858656)) @@ -323,7 +323,7 @@ [i7] i9 = int_lt(i7, 1003) label(i9, descr=grrr) - guard_true(i9, descr=) [] + guard_true(i9, descr=) [] i13 = getfield_raw(151937600, descr=) label(i13, descr=asb) i19 = int_lt(i13, 1003) @@ -336,10 +336,10 @@ i0 = int_lt(1, 2) finish(i0) ''') - bridge.comment = 'bridge out of Guard 2 with 1 ops' + bridge.comment = 'bridge out of Guard af with 1 ops' loop.comment = 'Loop 0' loops = split_trace(loop) + split_trace(bridge) - input = ['grrr:123\nasb:12\nbridge 2:1234'] + input = ['grrr:123\nasb:12\nbridge af:1234'] parse_log_counts(input, loops) assert loops[-1].count == 1234 assert loops[1].count == 123 diff --git a/rpython/jit/metainterp/test/test_logger.py b/rpython/jit/metainterp/test/test_logger.py --- a/rpython/jit/metainterp/test/test_logger.py +++ b/rpython/jit/metainterp/test/test_logger.py @@ -166,7 +166,7 @@ loop = pure_parse(inp, namespace=namespace) logger = Logger(self.make_metainterp_sd(), guard_number=True) output = logger.log_loop(loop) - assert re.match("guard_true\(i0, descr=\) \[i0\]", output.splitlines()[-1]) + assert re.match("guard_true\(i0, descr=\) \[i0\]", output.splitlines()[-1]) pure_parse(output) logger = Logger(self.make_metainterp_sd(), guard_number=False) @@ -200,7 +200,7 @@ def test_intro_bridge(self): bare_logger = logger.Logger(self.make_metainterp_sd()) output = capturing(bare_logger.log_bridge, [], [], 3) - assert re.match("# bridge out of Guard \d+ with 0 ops", + assert re.match("# bridge out of Guard [\da-f]+ with 0 ops", output.splitlines()[0]) pure_parse(output) From noreply at buildbot.pypy.org Wed Feb 27 12:44:25 2013 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 27 Feb 2013 12:44:25 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: update the todo Message-ID: <20130227114425.530EA1C04F1@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61841:34a511b52345 Date: 2013-02-27 13:44 +0200 http://bitbucket.org/pypy/pypy/changeset/34a511b52345/ Log: update the todo diff --git a/pypy/TODO b/pypy/TODO --- a/pypy/TODO +++ b/pypy/TODO @@ -1,5 +1,2 @@ -* 32bit x86 * ARM -* asmgcc -* kill jit2gc on translator From noreply at buildbot.pypy.org Wed Feb 27 12:48:49 2013 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 27 Feb 2013 12:48:49 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: fix the loading of frame depth Message-ID: <20130227114849.4F1451C0133@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61842:b7eef86deec4 Date: 2013-02-27 13:48 +0200 http://bitbucket.org/pypy/pypy/changeset/b7eef86deec4/ Log: fix the loading of frame depth diff --git a/rpython/jit/backend/arm/assembler.py b/rpython/jit/backend/arm/assembler.py --- a/rpython/jit/backend/arm/assembler.py +++ b/rpython/jit/backend/arm/assembler.py @@ -742,7 +742,7 @@ """ descrs = self.cpu.gc_ll_descr.getframedescrs(self.cpu) ofs = self.cpu.unpack_fielddescr(descrs.arraydescr.lendescr) - mc.gen_load_int(r.ip.value, ofs) + mc.STR_ri(r.r12.value, r.fp.value, imm=ofs) stack_check_cmp_ofs = mc.currpos() if expected_size == -1: mc.NOP() From noreply at buildbot.pypy.org Wed Feb 27 13:07:33 2013 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 27 Feb 2013 13:07:33 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: write garbage to jitframe so we get crashes of incorrect gcmap quicker Message-ID: <20130227120733.E7C991C04F1@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61843:c4f9e6db0526 Date: 2013-02-27 14:07 +0200 http://bitbucket.org/pypy/pypy/changeset/c4f9e6db0526/ Log: write garbage to jitframe so we get crashes of incorrect gcmap quicker diff --git a/rpython/jit/backend/llsupport/gc.py b/rpython/jit/backend/llsupport/gc.py --- a/rpython/jit/backend/llsupport/gc.py +++ b/rpython/jit/backend/llsupport/gc.py @@ -132,10 +132,10 @@ """ This functions retuns an arraydescr of type for the JITFRAME""" raise NotImplementedError - def malloc_jitframe(self, frame_info): + def malloc_jitframe(self, frame_info, staticsize): """ Allocate a new frame, overwritten by tests """ - frame = jitframe.JITFRAME.allocate(frame_info) + frame = jitframe.JITFRAME.allocate(frame_info, staticsize) llop.gc_assume_young_pointers(lltype.Void, frame) return frame diff --git a/rpython/jit/backend/llsupport/jitframe.py b/rpython/jit/backend/llsupport/jitframe.py --- a/rpython/jit/backend/llsupport/jitframe.py +++ b/rpython/jit/backend/llsupport/jitframe.py @@ -38,9 +38,13 @@ # the JITFRAME that's stored on the heap. See backend//arch.py for # detailed explanation how it is on your architecture -def jitframe_allocate(frame_info): +def jitframe_allocate(frame_info, staticsize): frame = lltype.malloc(JITFRAME, frame_info.jfi_frame_depth, zero=True) frame.jf_frame_info = frame_info + i = 0 + while i < staticsize: + frame.jf_frame[i] = 13 + i += 1 return frame JITFRAME = lltype.GcStruct( diff --git a/rpython/jit/backend/llsupport/llmodel.py b/rpython/jit/backend/llsupport/llmodel.py --- a/rpython/jit/backend/llsupport/llmodel.py +++ b/rpython/jit/backend/llsupport/llmodel.py @@ -210,7 +210,8 @@ func = rffi.cast(FUNCPTR, addr) #llop.debug_print(lltype.Void, ">>>> Entering", addr) frame_info = clt.frame_info - frame = self.gc_ll_descr.malloc_jitframe(frame_info) + frame = self.gc_ll_descr.malloc_jitframe(frame_info, + self.JITFRAME_FIXED_SIZE) ll_frame = lltype.cast_opaque_ptr(llmemory.GCREF, frame) locs = executable_token.compiled_loop_token._ll_initial_locs prev_interpreter = None # help flow space From noreply at buildbot.pypy.org Wed Feb 27 13:27:38 2013 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 27 Feb 2013 13:27:38 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: fix Message-ID: <20130227122738.4A2AC1C0327@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61844:ef7ff4adab1a Date: 2013-02-27 14:27 +0200 http://bitbucket.org/pypy/pypy/changeset/ef7ff4adab1a/ Log: fix diff --git a/rpython/jit/backend/llsupport/llmodel.py b/rpython/jit/backend/llsupport/llmodel.py --- a/rpython/jit/backend/llsupport/llmodel.py +++ b/rpython/jit/backend/llsupport/llmodel.py @@ -87,7 +87,8 @@ # update the frame_info size, which is for whatever reason # not up to date frame.jf_frame_info.set_frame_depth(base_ofs, size) - new_frame = jitframe.JITFRAME.allocate(frame.jf_frame_info) + new_frame = jitframe.JITFRAME.allocate(frame.jf_frame_info, + self.JITFRAME_FIXED_SIZE) i = 0 while i < len(frame.jf_frame): new_frame.jf_frame[i] = frame.jf_frame[i] From noreply at buildbot.pypy.org Wed Feb 27 13:47:49 2013 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 27 Feb 2013 13:47:49 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: like that? Message-ID: <20130227124749.BAFAC1C3C5C@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61845:1d7cd337881c Date: 2013-02-27 14:47 +0200 http://bitbucket.org/pypy/pypy/changeset/1d7cd337881c/ Log: like that? diff --git a/rpython/jit/backend/arm/assembler.py b/rpython/jit/backend/arm/assembler.py --- a/rpython/jit/backend/arm/assembler.py +++ b/rpython/jit/backend/arm/assembler.py @@ -749,7 +749,7 @@ mc.NOP() else: mc.gen_load_int(r.lr.value, expected_size) - mc.CMP_rr(r.ip.value, r.lr.value) + mc.CMP_rr(r.lr.value, r.ip.value) jg_location = mc.currpos() mc.BKPT() @@ -759,7 +759,6 @@ self.push_gcmap(mc, gcmap, push=True) - self.mc.BL(self._frame_realloc_slowpath) # patch jg_location above From noreply at buildbot.pypy.org Wed Feb 27 13:56:28 2013 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 27 Feb 2013 13:56:28 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: er, maybe like that Message-ID: <20130227125628.A83A81C3C5C@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61846:4f1b0ef6ca4a Date: 2013-02-27 14:56 +0200 http://bitbucket.org/pypy/pypy/changeset/4f1b0ef6ca4a/ Log: er, maybe like that diff --git a/rpython/jit/backend/arm/assembler.py b/rpython/jit/backend/arm/assembler.py --- a/rpython/jit/backend/arm/assembler.py +++ b/rpython/jit/backend/arm/assembler.py @@ -181,6 +181,7 @@ return # not supported (for tests, or non-translated) # # + xxxx mc = ARMv7Builder() self._store_and_reset_exception(mc, r.r0) ofs = self.cpu.get_ofs_of_frame_field('jf_guard_exc') @@ -742,7 +743,7 @@ """ descrs = self.cpu.gc_ll_descr.getframedescrs(self.cpu) ofs = self.cpu.unpack_fielddescr(descrs.arraydescr.lendescr) - mc.STR_ri(r.r12.value, r.fp.value, imm=ofs) + mc.LDR_ri(r.r12.value, r.fp.value, imm=ofs) stack_check_cmp_ofs = mc.currpos() if expected_size == -1: mc.NOP() From noreply at buildbot.pypy.org Wed Feb 27 14:07:40 2013 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 27 Feb 2013 14:07:40 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: temporary fix Message-ID: <20130227130740.336DB1C3C5C@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61847:a12dde0f453d Date: 2013-02-27 15:07 +0200 http://bitbucket.org/pypy/pypy/changeset/a12dde0f453d/ Log: temporary fix diff --git a/rpython/jit/backend/llsupport/test/test_gc_integration.py b/rpython/jit/backend/llsupport/test/test_gc_integration.py --- a/rpython/jit/backend/llsupport/test/test_gc_integration.py +++ b/rpython/jit/backend/llsupport/test/test_gc_integration.py @@ -450,7 +450,7 @@ self.frames[-1].hdr |= 1 self.init_nursery() - def malloc_jitframe(self, frame_info): + def malloc_jitframe(self, frame_info, ignored): """ Allocate a new frame, overwritten by tests """ frame = JITFRAME.allocate(frame_info) From noreply at buildbot.pypy.org Wed Feb 27 14:08:33 2013 From: noreply at buildbot.pypy.org (lwassermann) Date: Wed, 27 Feb 2013 14:08:33 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: added STRING_REPLACE primitive(105) and test Message-ID: <20130227130833.2D8ED1C3C5C@cobra.cs.uni-duesseldorf.de> Author: Lars Wassermann Branch: Changeset: r103:c395af8c249f Date: 2013-02-27 14:06 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/c395af8c249f/ Log: added STRING_REPLACE primitive(105) and test diff --git a/spyvm/primitives.py b/spyvm/primitives.py --- a/spyvm/primitives.py +++ b/spyvm/primitives.py @@ -496,6 +496,31 @@ interp.space.objtable['w_display'] = w_rcvr return w_rcvr + at expose_primitive(STRING_REPLACE, unwrap_spec=[object, index1_0, index1_0, object, index1_0]) +def func(interp, s_frame, w_rcvr, start, stop, w_replacement, repStart): + """replaceFrom: start to: stop with: replacement startingAt: repStart + Primitive. This destructively replaces elements from start to stop in the + receiver starting at index, repStart, in the collection, replacement. Answer + the receiver. Range checks are performed in the primitive only. Essential + for Pharo Candle Symbols. + | index repOff | + repOff := repStart - start. + index := start - 1. + [(index := index + 1) <= stop] + whileTrue: [self at: index put: (replacement at: repOff + index)]""" + if (start < 0 or start - 1 > stop or repStart < 0): + raise PrimitiveFailedError() + if w_rcvr.__class__ is not w_replacement.__class__: + raise PrimitiveFailedError() + if (w_rcvr.size() <= stop + or w_replacement.size() < repStart + (stop - start)): + raise PrimitiveFailedError() + repOff = repStart - start + for i0 in range(start, stop + 1): + w_rcvr.atput0(interp.space, i0, w_replacement.at0(interp.space, repOff + i0)) + return w_rcvr + + @expose_primitive(SCREEN_SIZE, unwrap_spec=[object]) def func(interp, s_frame, w_rcvr): # XXX get the real screen size diff --git a/spyvm/test/test_primitives.py b/spyvm/test/test_primitives.py --- a/spyvm/test/test_primitives.py +++ b/spyvm/test/test_primitives.py @@ -446,8 +446,8 @@ from test_interpreter import new_frame w_frame, s_frame = new_frame("", space=space) - w_block = prim(200, map(wrap, ["anActiveContext", 2, [wrap(1), wrap(2)]]), - w_frame) + w_block = prim(primitives.CLOSURE_COPY_WITH_COPIED_VALUES, map(wrap, + ["anActiveContext", 2, [wrap(1), wrap(2)]]), w_frame) assert w_block is not space.w_nil w_w_block = wrapper.BlockClosureWrapper(space, w_block) assert w_w_block.startpc() is 0 @@ -455,6 +455,20 @@ assert w_w_block.at0(1) == wrap(2) assert w_w_block.numArgs() is 2 +def test_primitive_string_copy(): + w_r = prim(primitives.STRING_REPLACE, ["aaaaa", 1, 5, "ababab", 1]) + assert w_r.as_string() == "ababa" + w_r = prim(primitives.STRING_REPLACE, ["aaaaa", 1, 5, "ababab", 2]) + assert w_r.as_string() == "babab" + w_r = prim(primitives.STRING_REPLACE, ["aaaaa", 2, 5, "ccccc", 1]) + assert w_r.as_string() == "acccc" + w_r = prim(primitives.STRING_REPLACE, ["aaaaa", 2, 4, "ccccc", 1]) + assert w_r.as_string() == "accca" + prim_fails(primitives.STRING_REPLACE, ["aaaaa", 0, 4, "ccccc", 1]) + prim_fails(primitives.STRING_REPLACE, ["aaaaa", 1, 6, "ccccc", 2]) + prim_fails(primitives.STRING_REPLACE, ["aaaaa", 2, 6, "ccccc", 1]) + prim_fails(primitives.STRING_REPLACE, [['a', 'b'], 1, 4, "ccccc", 1]) + def build_up_closure_environment(args, copiedValues=[]): from test_interpreter import new_frame w_frame, s_initial_context = new_frame("", @@ -465,7 +479,7 @@ size_arguments, copiedValues) s_initial_context.push_all([closure] + args) interp = interpreter.Interpreter(space) - w_active_context = prim_table[201 + size_arguments](interp, s_initial_context, size_arguments) + w_active_context = prim_table[primitives.CLOSURE_VALUE + size_arguments](interp, s_initial_context, size_arguments) return s_initial_context, closure, w_active_context.as_context_get_shadow(space) def test_primitive_closure_value(): From noreply at buildbot.pypy.org Wed Feb 27 14:08:34 2013 From: noreply at buildbot.pypy.org (lwassermann) Date: Wed, 27 Feb 2013 14:08:34 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: fixed #asSymbol asSymbol test Message-ID: <20130227130834.440AB1C3C5C@cobra.cs.uni-duesseldorf.de> Author: Lars Wassermann Branch: Changeset: r104:bcc60850a290 Date: 2013-02-27 14:08 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/bcc60850a290/ Log: fixed #asSymbol asSymbol test fixed perform method to inquire whether the method to perform is primitive diff --git a/spyvm/interpreter.py b/spyvm/interpreter.py --- a/spyvm/interpreter.py +++ b/spyvm/interpreter.py @@ -96,12 +96,21 @@ w_selector = self.image.w_asSymbol else: w_selector = self.perform(self.space.wrap_string(selector), "asSymbol") - s_class = w_receiver.shadow_of_my_class(self.space) - s_method = s_class.lookup(w_selector) - assert s_method - w_frame = s_method.create_frame(self.space, w_receiver, list(arguments_w)) + + w_method = model.W_CompiledMethod() + w_method.setbytes([chr(124)]) #returnTopFromMethod + s_method = w_method.as_compiledmethod_get_shadow(self.space) + s_frame = MethodContextShadow.make_context( + self.space, s_method, w_receiver, [], None).get_shadow(self.space) + s_frame.push(w_receiver) + s_frame.push_all(list(arguments_w)) try: - self.loop(w_frame) + w_new_frame = s_frame._sendSelfSelector(w_selector, len(arguments_w), self) + if w_new_frame == None: + # which means that we tried to call a primitive method + return s_frame.pop() + else: + self.loop(w_new_frame) except ReturnFromTopLevel, e: return e.object diff --git a/spyvm/shadow.py b/spyvm/shadow.py --- a/spyvm/shadow.py +++ b/spyvm/shadow.py @@ -750,7 +750,7 @@ def __str__(self): retval = '\nMethodContext of:' - retval += self.w_method().as_string(markBytecode=self.pc()) + retval += self.w_method().as_string(markBytecode=self.pc() + 1) retval += "Stackptr: %i" % self._stack_ptr retval += "\nStack : " + str(self.stack()) return retval diff --git a/spyvm/test/test_bootstrappedimage.py b/spyvm/test/test_bootstrappedimage.py --- a/spyvm/test/test_bootstrappedimage.py +++ b/spyvm/test/test_bootstrappedimage.py @@ -7,15 +7,13 @@ testhelper.setup_module(testhelper, filename='bootstrapped.image') def test_retrieve_symbol(): - py.test.skip("This method will fail, because the bytecodes are not adjusted for blockclosures, yet.") - perform(testhelper.image.w_asSymbol, "asSymbol") + w_result = perform(testhelper.image.w_asSymbol, "asSymbol") + assert w_result is testhelper.image.w_asSymbol def test_create_new_symbol(): - py.test.skip("This method is based upon the above.") - #import pdb; pdb.set_trace() w_result = perform(w("someString"), "asSymbol") assert w_result is not None - assert w_result.as_string() is "someString" + assert w_result.as_string() == "someString" #def test_hazelnut(): From noreply at buildbot.pypy.org Wed Feb 27 14:59:53 2013 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 27 Feb 2013 14:59:53 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: improve the test Message-ID: <20130227135953.932241C487F@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61848:e43489a493ba Date: 2013-02-27 15:55 +0200 http://bitbucket.org/pypy/pypy/changeset/e43489a493ba/ Log: improve the test diff --git a/rpython/jit/backend/llsupport/test/test_gc_integration.py b/rpython/jit/backend/llsupport/test/test_gc_integration.py --- a/rpython/jit/backend/llsupport/test/test_gc_integration.py +++ b/rpython/jit/backend/llsupport/test/test_gc_integration.py @@ -683,13 +683,15 @@ def test_call_may_force_gcmap(self): cpu = self.cpu - def f(frame, x): + def f(frame, arg, x): + assert not arg assert frame.jf_gcmap[0] & 31 == 0 frame.jf_descr = frame.jf_force_descr # make guard_not_forced fail assert x == 1 return lltype.nullptr(llmemory.GCREF.TO) - FUNC = lltype.FuncType([JITFRAMEPTR, lltype.Signed], llmemory.GCREF) + FUNC = lltype.FuncType([JITFRAMEPTR, llmemory.GCREF, lltype.Signed], + llmemory.GCREF) fptr = llhelper(lltype.Ptr(FUNC), f) calldescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, EffectInfo.MOST_GENERAL) @@ -703,7 +705,8 @@ p1 = getarrayitem_gc(p0, 0, descr=arraydescr) p2 = getarrayitem_gc(p0, 1, descr=arraydescr) p3 = getarrayitem_gc(p0, 2, descr=arraydescr) - px = call_may_force(ConstClass(fptr), pf, i0, descr=calldescr) + pdying = getarrayitem_gc(p0, 0, descr=arraydescr) + px = call_may_force(ConstClass(fptr), pf, pdying, i0, descr=calldescr) guard_not_forced(descr=faildescr) [p1, p2, p3, px] finish(px, descr=finishdescr) """, namespace={'fptr': fptr, 'calldescr': calldescr, From noreply at buildbot.pypy.org Wed Feb 27 14:59:54 2013 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 27 Feb 2013 14:59:54 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: add one more test Message-ID: <20130227135954.D89D91C4892@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61849:047c3747b269 Date: 2013-02-27 15:59 +0200 http://bitbucket.org/pypy/pypy/changeset/047c3747b269/ Log: add one more test diff --git a/rpython/jit/backend/llsupport/test/test_gc_integration.py b/rpython/jit/backend/llsupport/test/test_gc_integration.py --- a/rpython/jit/backend/llsupport/test/test_gc_integration.py +++ b/rpython/jit/backend/llsupport/test/test_gc_integration.py @@ -721,3 +721,45 @@ frame = lltype.cast_opaque_ptr(JITFRAMEPTR, cpu.execute_token(token, 1, a)) assert bin(frame.jf_gcmap[0]).count('1') == 4 + + def test_call_gcmap_no_guard(self): + cpu = self.cpu + + def f(frame, arg, x): + assert not arg + assert frame.jf_gcmap[0] & 31 == 0 + frame.jf_descr = frame.jf_force_descr # make guard_not_forced fail + assert x == 1 + return lltype.nullptr(llmemory.GCREF.TO) + + FUNC = lltype.FuncType([JITFRAMEPTR, llmemory.GCREF, lltype.Signed], + llmemory.GCREF) + fptr = llhelper(lltype.Ptr(FUNC), f) + calldescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, + EffectInfo.MOST_GENERAL) + + A = lltype.GcArray(lltype.Ptr(lltype.GcArray(lltype.Signed))) + a = lltype.malloc(A, 3, zero=True) + + loop = self.parse(""" + [i0, p0] + pf = force_token() + p1 = getarrayitem_gc(p0, 0, descr=arraydescr) + p2 = getarrayitem_gc(p0, 1, descr=arraydescr) + p3 = getarrayitem_gc(p0, 2, descr=arraydescr) + pdying = getarrayitem_gc(p0, 0, descr=arraydescr) + px = call(ConstClass(fptr), pf, pdying, i0, descr=calldescr) + guard_false(i0, descr=faildescr) [p1, p2, p3, px] + finish(px, descr=finishdescr) + """, namespace={'fptr': fptr, 'calldescr': calldescr, + 'arraydescr': cpu.arraydescrof(A), + 'faildescr': BasicFailDescr(1), + 'finaldescr': BasicFinalDescr(2)}) + + token = JitCellToken() + cpu.gc_ll_descr.init_nursery(100) + cpu.setup_once() + cpu.compile_loop(loop.inputargs, loop.operations, token) + frame = lltype.cast_opaque_ptr(JITFRAMEPTR, + cpu.execute_token(token, 1, a)) + assert bin(frame.jf_gcmap[0]).count('1') == 4 From noreply at buildbot.pypy.org Wed Feb 27 15:02:30 2013 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 27 Feb 2013 15:02:30 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: improve tests Message-ID: <20130227140230.C6C301C487F@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61850:b744e78f638f Date: 2013-02-27 16:02 +0200 http://bitbucket.org/pypy/pypy/changeset/b744e78f638f/ Log: improve tests diff --git a/rpython/jit/backend/llsupport/test/test_gc_integration.py b/rpython/jit/backend/llsupport/test/test_gc_integration.py --- a/rpython/jit/backend/llsupport/test/test_gc_integration.py +++ b/rpython/jit/backend/llsupport/test/test_gc_integration.py @@ -686,6 +686,8 @@ def f(frame, arg, x): assert not arg assert frame.jf_gcmap[0] & 31 == 0 + assert bin(frame.jf_gcmap[0]).count('1') == 3 # p1, p2, p3, but + # not in registers frame.jf_descr = frame.jf_force_descr # make guard_not_forced fail assert x == 1 return lltype.nullptr(llmemory.GCREF.TO) @@ -728,6 +730,7 @@ def f(frame, arg, x): assert not arg assert frame.jf_gcmap[0] & 31 == 0 + assert bin(frame.jf_gcmap[0]).count('1') == 3 # p1, p2, p3 frame.jf_descr = frame.jf_force_descr # make guard_not_forced fail assert x == 1 return lltype.nullptr(llmemory.GCREF.TO) From noreply at buildbot.pypy.org Wed Feb 27 15:39:40 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Wed, 27 Feb 2013 15:39:40 +0100 (CET) Subject: [pypy-commit] pypy refactor-translator: Adapt rpython/translator/goal/translate.py to work with the refactored translation driver. Message-ID: <20130227143940.37F6C1C01A7@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: refactor-translator Changeset: r61851:a39f8d1231fb Date: 2013-02-25 22:51 +0100 http://bitbucket.org/pypy/pypy/changeset/a39f8d1231fb/ Log: Adapt rpython/translator/goal/translate.py to work with the refactored translation driver. diff --git a/rpython/translator/driver.py b/rpython/translator/driver.py --- a/rpython/translator/driver.py +++ b/rpython/translator/driver.py @@ -622,6 +622,8 @@ tasks.append(task) if task == goal: break + else: + raise Exception("No such goal %s." % goal.task_name) for task in tasks: if task.task_earlycheck: diff --git a/rpython/translator/goal/translate.py b/rpython/translator/goal/translate.py --- a/rpython/translator/goal/translate.py +++ b/rpython/translator/goal/translate.py @@ -22,33 +22,6 @@ set_opt_level, final_check_config, OPT_LEVELS, DEFAULT_OPT_LEVEL, set_platform) -GOALS = [ - ("annotate", "do type inference", "-a --annotate", ""), - ("rtype", "do rtyping", "-t --rtype", ""), - ("pyjitpl", "JIT generation step", "--pyjitpl", ""), - ("jittest", "JIT test with llgraph backend", "--jittest", ""), - ("backendopt", "do backend optimizations", "--backendopt", ""), - ("source", "create source", "-s --source", ""), - ("compile", "compile", "-c --compile", " (default goal)"), - ("llinterpret", "interpret the rtyped flow graphs", "--llinterpret", ""), -] - - -def goal_options(): - result = [] - for name, doc, cmdline, extra in GOALS: - optional = False - if name.startswith('?'): - optional = True - name = name[1:] - yesdoc = doc[0].upper() + doc[1:] + extra - result.append(BoolOption(name, yesdoc, default=False, cmdline=cmdline, - negation=False)) - if not optional: - result.append(BoolOption("no_%s" % name, "Don't " + doc, default=False, - cmdline="--no-" + name, negation=False)) - return result - translate_optiondescr = OptionDescription("translate", "XXX", [ StrOption("targetspec", "XXX", default='../../../pypy/goal/targetpypystandalone', cmdline=None), @@ -74,14 +47,9 @@ cmdline="-h --help", negation=False), BoolOption("fullhelp", "show full help message and exit", default=False, cmdline="--full-help", negation=False), - ArbitraryOption("goals", "XXX", - defaultfactory=list), - # xxx default goals ['annotate', 'rtype', 'backendopt', 'source', 'compile'] - ArbitraryOption("skipped_goals", "XXX", - defaultfactory=list), - OptionDescription("goal_options", - "Goals that should be reached during translation", - goal_options()), + ChoiceOption("goal", "stop after goal", ['annotate', 'rtype', 'backendopt', + 'source', 'compile'], + default='compile') ]) import optparse @@ -117,21 +85,6 @@ options, args = opt_parser.parse_args() - # set goals and skipped_goals - reset = False - for name, _, _, _ in GOALS: - if name.startswith('?'): - continue - if getattr(translateconfig.goal_options, name): - if name not in translateconfig.goals: - translateconfig.goals.append(name) - if getattr(translateconfig.goal_options, 'no_' + name): - if name not in translateconfig.skipped_goals: - if not reset: - translateconfig.skipped_goals[:] = [] - reset = True - translateconfig.skipped_goals.append(name) - if args: arg = args[0] args = args[1:] @@ -304,9 +257,6 @@ if config.translation.jit: if 'jitpolicy' not in targetspec_dic: raise Exception('target has no jitpolicy defined.') - if (translateconfig.goals != ['annotate'] and - translateconfig.goals != ['rtype']): - drv.set_extra_goals(['pyjitpl']) # early check: from rpython.jit.backend.detect_cpu import getcpuclassname getcpuclassname(config.translation.jit_backend) @@ -320,8 +270,8 @@ drv.exe_name = targetspec_dic['__name__'] + '-%(backend)s' # Double check to ensure we are not overwriting the current interpreter - goals = translateconfig.goals - if not goals or 'compile' in goals: + goal = translateconfig.goal + if goal == 'compile': try: this_exe = py.path.local(sys.executable).new(ext='') exe_name = drv.compute_exe_name() @@ -333,7 +283,7 @@ pass try: - drv.proceed(goals) + getattr(drv, goal)() finally: drv.timer.pprint() except SystemExit: From noreply at buildbot.pypy.org Wed Feb 27 15:39:41 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Wed, 27 Feb 2013 15:39:41 +0100 (CET) Subject: [pypy-commit] pypy refactor-translator: Do task_stackcheckinsertion_lltype when the type system is lltype. Message-ID: <20130227143941.6A4181C01A7@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: refactor-translator Changeset: r61852:40c8418ff476 Date: 2013-02-25 23:46 +0100 http://bitbucket.org/pypy/pypy/changeset/40c8418ff476/ Log: Do task_stackcheckinsertion_lltype when the type system is lltype. diff --git a/rpython/translator/driver.py b/rpython/translator/driver.py --- a/rpython/translator/driver.py +++ b/rpython/translator/driver.py @@ -206,6 +206,8 @@ expose_task(self.task_pyjitpl) if not config.translation.backendopt.none: expose_task(self.task_backendopt) + if config.translation.type_system == 'lltype': + expose_task(self.task_stackcheckinsertion_lltype) for task in backends[config.translation.backend](self).get_tasks(): expose_task(task) From noreply at buildbot.pypy.org Wed Feb 27 15:39:42 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Wed, 27 Feb 2013 15:39:42 +0100 (CET) Subject: [pypy-commit] pypy refactor-translator: Remove setup_library() from driver. Message-ID: <20130227143942.980731C01A7@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: refactor-translator Changeset: r61853:f0fbe821d9af Date: 2013-02-26 13:49 +0100 http://bitbucket.org/pypy/pypy/changeset/f0fbe821d9af/ Log: Remove setup_library() from driver. diff --git a/rpython/translator/driver.py b/rpython/translator/driver.py --- a/rpython/translator/driver.py +++ b/rpython/translator/driver.py @@ -240,7 +240,6 @@ self.entry_point = entry_point self.translator = translator - self.libdef = None self.secondary_entrypoints = [] if self.config.translation.secondaryentrypoints: @@ -255,12 +254,6 @@ self.translator.driver_instrument_result = self.instrument_result - def setup_library(self, libdef, policy=None, extra={}, empty_translator=None): - """ Used by carbon python only. """ - self.setup(None, None, policy, extra, empty_translator) - self.libdef = libdef - self.secondary_entrypoints = libdef.functions - def instrument_result(self, args): backend = self.config.translation.backend if backend != 'c' or sys.platform == 'win32': @@ -456,10 +449,7 @@ entry_point_graph = self.translator.graphs[0] entry_point = get_entrypoint(entry_point_graph) else: - # library mode - assert self.libdef is not None - bk = self.translator.annotator.bookkeeper - entry_point = self.libdef.get_entrypoint(bk) + raise NotImplementedError self.gen = GenCli(udir, self.translator, entry_point, config=self.config) filename = self.gen.generate_source() From noreply at buildbot.pypy.org Wed Feb 27 15:39:43 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Wed, 27 Feb 2013 15:39:43 +0100 (CET) Subject: [pypy-commit] pypy refactor-translator: Fix tests to work with 40c8418ff476. Message-ID: <20130227143943.B00151C01A7@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: refactor-translator Changeset: r61854:d84fec6b921f Date: 2013-02-26 14:03 +0100 http://bitbucket.org/pypy/pypy/changeset/d84fec6b921f/ Log: Fix tests to work with 40c8418ff476. diff --git a/rpython/translator/test/test_driver.py b/rpython/translator/test/test_driver.py --- a/rpython/translator/test/test_driver.py +++ b/rpython/translator/test/test_driver.py @@ -4,21 +4,22 @@ def test_c_no_jit(): td = TranslationDriver() - names = ['annotate', 'rtype', 'backendopt', 'database', 'source', - 'compile'] + names = ['annotate', 'rtype', 'backendopt', 'stackcheckinsertion_lltype', + 'database', 'source', 'compile'] assert [task.task_name for task in td.tasks] == names def test_c_with_jit(): td = TranslationDriver({'jit': True}) - names = ['annotate', 'rtype', 'pyjitpl', 'backendopt', 'database', - 'source', 'compile'] + names = ['annotate', 'rtype', 'pyjitpl', 'backendopt', + 'stackcheckinsertion_lltype', 'database', 'source', 'compile'] assert [task.task_name for task in td.tasks] == names def test_no_backendopt(): td = TranslationDriver({'backendopt.none': True}) - names = ['annotate', 'rtype', 'database', 'source', 'compile'] + names = ['annotate', 'rtype', 'stackcheckinsertion_lltype', 'database', + 'source', 'compile'] assert [task.task_name for task in td.tasks] == names From noreply at buildbot.pypy.org Wed Feb 27 15:39:45 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Wed, 27 Feb 2013 15:39:45 +0100 (CET) Subject: [pypy-commit] pypy refactor-translator: Unskip test_disable_logic(). Fix. Message-ID: <20130227143945.011B51C01A7@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: refactor-translator Changeset: r61855:7cf9819b7fc5 Date: 2013-02-26 14:21 +0100 http://bitbucket.org/pypy/pypy/changeset/7cf9819b7fc5/ Log: Unskip test_disable_logic(). Fix. diff --git a/rpython/translator/c/test/test_genc.py b/rpython/translator/c/test/test_genc.py --- a/rpython/translator/c/test/test_genc.py +++ b/rpython/translator/c/test/test_genc.py @@ -97,10 +97,11 @@ print "THE RESULT IS:", llrepr_out(res), ";" return 0 + kwds = {} + if not backendopt: + kwds['backendopt.none'] = True t = Translation(entry_point, None, gc=gcpolicy, backend="c", - policy=annotatorpolicy, thread=thread) - if not backendopt: - t.disable(["backendopt_lltype"]) + policy=annotatorpolicy, thread=thread, **kwds) t.driver.config.translation.countmallocs = True t.annotate() if py.test.config.option.view: diff --git a/rpython/translator/driver.py b/rpython/translator/driver.py --- a/rpython/translator/driver.py +++ b/rpython/translator/driver.py @@ -192,25 +192,6 @@ self.done = {} - self.tasks = tasks = [] - # expose tasks - def expose_task(task): - def proc(): - return self.proceed(task) - tasks.append(task) - setattr(self, task.task_name, proc) - - expose_task(self.task_annotate) - expose_task(self.task_rtype) - if config.translation.jit: - expose_task(self.task_pyjitpl) - if not config.translation.backendopt.none: - expose_task(self.task_backendopt) - if config.translation.type_system == 'lltype': - expose_task(self.task_stackcheckinsertion_lltype) - for task in backends[config.translation.backend](self).get_tasks(): - expose_task(task) - def set_backend_extra_options(self, extra_options): self._backend_extra_options = extra_options @@ -254,6 +235,25 @@ self.translator.driver_instrument_result = self.instrument_result + self.tasks = tasks = [] + # expose tasks + def expose_task(task): + def proc(): + return self.proceed(task) + tasks.append(task) + setattr(self, task.task_name, proc) + + expose_task(self.task_annotate) + expose_task(self.task_rtype) + if self.config.translation.jit: + expose_task(self.task_pyjitpl) + if not self.config.translation.backendopt.none: + expose_task(self.task_backendopt) + if self.config.translation.type_system == 'lltype': + expose_task(self.task_stackcheckinsertion_lltype) + for task in backends[self.config.translation.backend](self).get_tasks(): + expose_task(task) + def instrument_result(self, args): backend = self.config.translation.backend if backend != 'c' or sys.platform == 'win32': diff --git a/rpython/translator/test/test_driver.py b/rpython/translator/test/test_driver.py --- a/rpython/translator/test/test_driver.py +++ b/rpython/translator/test/test_driver.py @@ -4,6 +4,7 @@ def test_c_no_jit(): td = TranslationDriver() + td.setup(None, None) names = ['annotate', 'rtype', 'backendopt', 'stackcheckinsertion_lltype', 'database', 'source', 'compile'] assert [task.task_name for task in td.tasks] == names @@ -11,6 +12,7 @@ def test_c_with_jit(): td = TranslationDriver({'jit': True}) + td.setup(None, None) names = ['annotate', 'rtype', 'pyjitpl', 'backendopt', 'stackcheckinsertion_lltype', 'database', 'source', 'compile'] assert [task.task_name for task in td.tasks] == names @@ -18,6 +20,7 @@ def test_no_backendopt(): td = TranslationDriver({'backendopt.none': True}) + td.setup(None, None) names = ['annotate', 'rtype', 'stackcheckinsertion_lltype', 'database', 'source', 'compile'] assert [task.task_name for task in td.tasks] == names @@ -74,13 +77,10 @@ assert 'source' in t.driver.done def test_disable_logic(): - return # temporary skip - def f(x,y): return x+y - t = Translation(f, [int, int]) - t.disable(['backendopt']) + t = Translation(f, [int, int], **{'backendopt.none': True}) t.source() assert 'backendopt' not in t.driver.done @@ -111,6 +111,6 @@ t.rtype() assert 'rtype' in t.driver.done - t = Translation(f, [int, int], backend='cli', type_system='ootype') - t.rtype() - assert 'rtype' in t.driver.done + #t = Translation(f, [int, int], backend='cli', type_system='ootype') + #t.rtype() + #assert 'rtype' in t.driver.done From noreply at buildbot.pypy.org Wed Feb 27 15:39:46 2013 From: noreply at buildbot.pypy.org (Manuel Jacob) Date: Wed, 27 Feb 2013 15:39:46 +0100 (CET) Subject: [pypy-commit] pypy refactor-translator: Set translation.verbose instead of overwriting the default value. Message-ID: <20130227143946.3077E1C01A7@cobra.cs.uni-duesseldorf.de> Author: Manuel Jacob Branch: refactor-translator Changeset: r61856:b33d03608ea5 Date: 2013-02-27 14:45 +0100 http://bitbucket.org/pypy/pypy/changeset/b33d03608ea5/ Log: Set translation.verbose instead of overwriting the default value. diff --git a/rpython/translator/driver.py b/rpython/translator/driver.py --- a/rpython/translator/driver.py +++ b/rpython/translator/driver.py @@ -170,9 +170,8 @@ class TranslationDriver(object): _backend_extra_options = {} - def __init__(self, setopts=None, - exe_name=None, extmod_name=None, - config=None, overrides=None): + def __init__(self, setopts=None, exe_name=None, extmod_name=None, + config=None): self.timer = Timer() self.log = log @@ -181,9 +180,6 @@ from rpython.config.translationoption import get_combined_translation_config config = get_combined_translation_config(translating=True) self.config = config - if overrides is not None: - self.config.override(overrides) - if setopts is not None: self.config.set(**setopts) diff --git a/rpython/translator/interactive.py b/rpython/translator/interactive.py --- a/rpython/translator/interactive.py +++ b/rpython/translator/interactive.py @@ -2,7 +2,7 @@ def Translation(entry_point, argtypes=None, policy=None, **kwds): - driver = TranslationDriver(overrides={'translation.verbose': True}) + driver = TranslationDriver(setopts={'translation.verbose': True}) driver.driver = driver driver.config.translation.set(**kwds) driver.setup(entry_point, argtypes, policy) From noreply at buildbot.pypy.org Wed Feb 27 15:42:51 2013 From: noreply at buildbot.pypy.org (fijal) Date: Wed, 27 Feb 2013 15:42:51 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: fix Message-ID: <20130227144251.078671C01A7@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61857:297a8f917dda Date: 2013-02-27 16:42 +0200 http://bitbucket.org/pypy/pypy/changeset/297a8f917dda/ Log: fix diff --git a/rpython/jit/backend/arm/assembler.py b/rpython/jit/backend/arm/assembler.py --- a/rpython/jit/backend/arm/assembler.py +++ b/rpython/jit/backend/arm/assembler.py @@ -181,13 +181,12 @@ return # not supported (for tests, or non-translated) # # - xxxx mc = ARMv7Builder() self._store_and_reset_exception(mc, r.r0) ofs = self.cpu.get_ofs_of_frame_field('jf_guard_exc') # make sure ofs fits into a register assert check_imm_arg(ofs) - mc.STR_ri(r.r0.value, r.fp.value, imm=ofs) + mc.LDR_ri(r.r0.value, r.fp.value, imm=ofs) propagate_exception_descr = rffi.cast(lltype.Signed, cast_instance_to_gcref(self.cpu.propagate_exception_descr)) # put propagate_exception_descr into frame From noreply at buildbot.pypy.org Wed Feb 27 17:15:40 2013 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 27 Feb 2013 17:15:40 +0100 (CET) Subject: [pypy-commit] pypy kill-flowobjspace: hg merge default Message-ID: <20130227161540.053431C0084@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: kill-flowobjspace Changeset: r61858:35aeba314fd5 Date: 2013-02-27 17:15 +0100 http://bitbucket.org/pypy/pypy/changeset/35aeba314fd5/ Log: hg merge default diff too long, truncating to 2000 out of 20275 lines diff --git a/.hgignore b/.hgignore --- a/.hgignore +++ b/.hgignore @@ -35,39 +35,43 @@ ^pypy/doc/config/.+\.rst$ ^pypy/doc/basicblock\.asc$ ^pypy/doc/.+\.svninfo$ -^pypy/translator/c/src/libffi_msvc/.+\.obj$ -^pypy/translator/c/src/libffi_msvc/.+\.dll$ -^pypy/translator/c/src/libffi_msvc/.+\.lib$ -^pypy/translator/c/src/libffi_msvc/.+\.exp$ -^pypy/translator/c/src/cjkcodecs/.+\.o$ -^pypy/translator/c/src/cjkcodecs/.+\.obj$ -^pypy/translator/jvm/\.project$ -^pypy/translator/jvm/\.classpath$ -^pypy/translator/jvm/eclipse-bin$ -^pypy/translator/jvm/src/pypy/.+\.class$ -^pypy/translator/benchmark/docutils$ -^pypy/translator/benchmark/templess$ -^pypy/translator/benchmark/gadfly$ -^pypy/translator/benchmark/mako$ -^pypy/translator/benchmark/bench-custom\.benchmark_result$ -^pypy/translator/benchmark/shootout_benchmarks$ -^pypy/translator/goal/pypy-translation-snapshot$ -^pypy/translator/goal/pypy-c -^pypy/translator/goal/pypy-jvm -^pypy/translator/goal/pypy-jvm.jar -^pypy/translator/goal/.+\.exe$ -^pypy/translator/goal/.+\.dll$ -^pypy/translator/goal/target.+-c$ +^rpython/translator/c/src/libffi_msvc/.+\.obj$ +^rpython/translator/c/src/libffi_msvc/.+\.dll$ +^rpython/translator/c/src/libffi_msvc/.+\.lib$ +^rpython/translator/c/src/libffi_msvc/.+\.exp$ +^rpython/translator/c/src/cjkcodecs/.+\.o$ +^rpython/translator/c/src/cjkcodecs/.+\.obj$ +^rpython/translator/c/src/stacklet/.+\.o$ +^rpython/translator/c/src/.+\.o$ +^rpython/translator/jvm/\.project$ +^rpython/translator/jvm/\.classpath$ +^rpython/translator/jvm/eclipse-bin$ +^rpython/translator/jvm/src/pypy/.+\.class$ +^rpython/translator/benchmark/docutils$ +^rpython/translator/benchmark/templess$ +^rpython/translator/benchmark/gadfly$ +^rpython/translator/benchmark/mako$ +^rpython/translator/benchmark/bench-custom\.benchmark_result$ +^rpython/translator/benchmark/shootout_benchmarks$ +^rpython/translator/goal/target.+-c$ +^rpython/translator/goal/.+\.exe$ +^rpython/translator/goal/.+\.dll$ +^pypy/goal/pypy-translation-snapshot$ +^pypy/goal/pypy-c +^pypy/goal/pypy-jvm +^pypy/goal/pypy-jvm.jar +^pypy/goal/.+\.exe$ +^pypy/goal/.+\.dll$ ^pypy/_cache$ ^pypy/doc/statistic/.+\.html$ ^pypy/doc/statistic/.+\.eps$ ^pypy/doc/statistic/.+\.pdf$ -^pypy/translator/cli/src/pypylib\.dll$ -^pypy/translator/cli/src/query\.exe$ -^pypy/translator/cli/src/main\.exe$ +^rpython/translator/cli/src/pypylib\.dll$ +^rpython/translator/cli/src/query\.exe$ +^rpython/translator/cli/src/main\.exe$ ^lib_pypy/ctypes_config_cache/_.+_cache\.py$ ^lib_pypy/ctypes_config_cache/_.+_.+_\.py$ -^pypy/translator/cli/query-descriptions$ +^rpython/translator/cli/query-descriptions$ ^pypy/doc/discussion/.+\.html$ ^include/.+\.h$ ^include/.+\.inl$ diff --git a/LICENSE b/LICENSE --- a/LICENSE +++ b/LICENSE @@ -270,3 +270,24 @@ LineBreak-*.txt UnicodeData-*.txt UnihanNumeric-*.txt + +License for 'dotviewer/font/' +============================= + +Copyright (C) 2008 The Android Open Source Project + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +Detailled license information is contained in the NOTICE file in the +directory. + diff --git a/dotviewer/VeraMoBd.ttf b/dotviewer/VeraMoBd.ttf deleted file mode 100644 Binary file dotviewer/VeraMoBd.ttf has changed diff --git a/dotviewer/cyrvetic.ttf b/dotviewer/cyrvetic.ttf deleted file mode 100644 Binary file dotviewer/cyrvetic.ttf has changed diff --git a/dotviewer/drawgraph.py b/dotviewer/drawgraph.py --- a/dotviewer/drawgraph.py +++ b/dotviewer/drawgraph.py @@ -9,9 +9,10 @@ from pygame.locals import * +RAW_ENCODING = "utf-8" this_dir = os.path.dirname(os.path.abspath(__file__)) -FONT = os.path.join(this_dir, 'cyrvetic.ttf') -FIXEDFONT = os.path.join(this_dir, 'VeraMoBd.ttf') +FONT = os.path.join(this_dir, 'font', 'DroidSans.ttf') +FIXEDFONT = os.path.join(this_dir, 'font', 'DroidSansMono.ttf') COLOR = { 'black': (0,0,0), 'white': (255,255,255), @@ -51,6 +52,12 @@ else: return default +def forceunicode(name): + return name if isinstance(name, unicode) else name.decode(RAW_ENCODING) + +def forcestr(name): + return name if isinstance(name, str) else name.encode(RAW_ENCODING) + class GraphLayout: fixedfont = False @@ -106,12 +113,12 @@ class Node: def __init__(self, name, x, y, w, h, label, style, shape, color, fillcolor): - self.name = name + self.name = forceunicode(name) self.x = float(x) self.y = float(y) self.w = float(w) self.h = float(h) - self.label = label + self.label = forceunicode(label) self.style = style self.shape = shape self.color = color @@ -125,8 +132,8 @@ label = None def __init__(self, nodes, tail, head, cnt, *rest): - self.tail = nodes[tail] - self.head = nodes[head] + self.tail = nodes[forceunicode(tail)] + self.head = nodes[forceunicode(head)] cnt = int(cnt) self.points = [(float(rest[i]), float(rest[i+1])) for i in range(0, cnt*2, 2)] @@ -655,11 +662,7 @@ part = parts[i] word = part[0] try: - try: - img = font.render(word, False, *part[1:]) - except pygame.error, e: - # Try *with* anti-aliasing to work around a bug in SDL - img = font.render(word, True, *part[1:]) + img = font.render(word, True, *part[1:]) except pygame.error: del parts[i] # Text has zero width else: diff --git a/dotviewer/font/DroidSans-Bold.ttf b/dotviewer/font/DroidSans-Bold.ttf new file mode 100644 index 0000000000000000000000000000000000000000..d065b64eb1863f83c2c982264f9442f2313a44a9 GIT binary patch [cut] diff --git a/dotviewer/font/DroidSans.ttf b/dotviewer/font/DroidSans.ttf new file mode 100644 index 0000000000000000000000000000000000000000..ad1efca88aed8d9e2d179f27dd713e2a1562fe5f GIT binary patch [cut] diff --git a/dotviewer/font/DroidSansMono.ttf b/dotviewer/font/DroidSansMono.ttf new file mode 100644 index 0000000000000000000000000000000000000000..a007071944f7c90020e798eea53b10065e2b45a5 GIT binary patch [cut] diff --git a/dotviewer/font/NOTICE b/dotviewer/font/NOTICE new file mode 100644 --- /dev/null +++ b/dotviewer/font/NOTICE @@ -0,0 +1,190 @@ + + Copyright (c) 2005-2008, The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + diff --git a/dotviewer/font/README.txt b/dotviewer/font/README.txt new file mode 100644 --- /dev/null +++ b/dotviewer/font/README.txt @@ -0,0 +1,18 @@ +Copyright (C) 2008 The Android Open Source Project + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +########## + +This directory contains the fonts for the platform. They are licensed +under the Apache 2 license. diff --git a/dotviewer/graphclient.py b/dotviewer/graphclient.py --- a/dotviewer/graphclient.py +++ b/dotviewer/graphclient.py @@ -33,8 +33,9 @@ def reload(graph_id): page = getpage(graph_id) if save_tmp_file: + from drawgraph import forcestr f = open(save_tmp_file, 'w') - f.write(page.source) + f.write(forcestr(page.source)) f.close() messages.extend(page_messages(page, graph_id)) send_graph_messages(io, messages) @@ -75,7 +76,8 @@ def page_messages(page, graph_id): import graphparse - return graphparse.parse_dot(graph_id, page.source, page.links, + from drawgraph import forcestr + return graphparse.parse_dot(graph_id, forcestr(page.source), page.links, getattr(page, 'fixedfont', False)) def send_graph_messages(io, messages): diff --git a/dotviewer/graphdisplay.py b/dotviewer/graphdisplay.py --- a/dotviewer/graphdisplay.py +++ b/dotviewer/graphdisplay.py @@ -4,7 +4,7 @@ from pygame.locals import * from drawgraph import GraphRenderer, FIXEDFONT from drawgraph import Node, Edge -from drawgraph import EventQueue, wait_for_events +from drawgraph import EventQueue, wait_for_events, forceunicode, forcestr METAKEYS = dict([ @@ -285,7 +285,7 @@ if e.key == K_ESCAPE: return None elif e.key == K_RETURN: - return text.encode('latin-1') # XXX do better + return forcestr(text) # return encoded unicode elif e.key == K_BACKSPACE: text = text[:-1] elif e.unicode and ord(e.unicode) >= ord(' '): @@ -423,7 +423,7 @@ self.layout.request_reload() def setstatusbar(self, text, fgcolor=None, bgcolor=None): - info = (text, fgcolor or self.STATUSBAR_FGCOLOR, bgcolor or self.STATUSBAR_BGCOLOR) + info = (forceunicode(text), fgcolor or self.STATUSBAR_FGCOLOR, bgcolor or self.STATUSBAR_BGCOLOR) if info != self.statusbarinfo: self.statusbarinfo = info self.must_redraw = True @@ -711,7 +711,7 @@ lines = [] while words: line = words.pop(0) - img = font.render(line or ' ', 1, fgcolor) + img = font.render(line or ' ', True, fgcolor) while words: longerline = line + ' ' + words[0] longerimg = font.render(longerline, 1, fgcolor) @@ -723,7 +723,7 @@ img = longerimg w, h = img.get_size() if h > maxheight: - img = font.render('...', 1, overflowcolor) + img = font.render('...', True, overflowcolor) w, h = img.get_size() while lines and h > maxheight: maxheight += lines.pop().get_size()[1] diff --git a/dotviewer/graphpage.py b/dotviewer/graphpage.py --- a/dotviewer/graphpage.py +++ b/dotviewer/graphpage.py @@ -44,6 +44,8 @@ class DotFileGraphPage(GraphPage): def compute(self, dotfile): - f = open(dotfile, 'r') + import codecs + from drawgraph import RAW_ENCODING + f = codecs.open(dotfile, 'r', RAW_ENCODING) self.source = f.read() f.close() diff --git a/dotviewer/test/test_interactive_unicode.py b/dotviewer/test/test_interactive_unicode.py new file mode 100755 --- /dev/null +++ b/dotviewer/test/test_interactive_unicode.py @@ -0,0 +1,103 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +import py +import sys, os, signal, thread, time, codecs +from dotviewer.conftest import option +from dotviewer.drawgraph import RAW_ENCODING + +SOURCE1 = u"""digraph G{ +λ -> b +b -> μ +} +""" + +FILENAME = 'graph1.dot' + +def setup_module(mod): + if not option.pygame: + py.test.skip("--pygame not enabled") + udir = py.path.local.make_numbered_dir(prefix='usession-dot-', keep=3) + f = codecs.open(str(udir.join(FILENAME)), 'wb', RAW_ENCODING) + f.write(SOURCE1) + f.close() + + from dotviewer import graphclient + mod.pkgdir = py.path.local(graphclient.this_dir) + mod.udir = udir + + try: + del os.environ['GRAPHSERVER'] + except KeyError: + pass + + +def test_dotviewer(): + print "=== dotviewer.py %s" % FILENAME + err = os.system('"%s" "%s"' % (pkgdir.join('dotviewer.py'), + udir.join(FILENAME))) + assert err == 0 + + plain_name = FILENAME.replace('.dot','.plain') + + os.system('dot -Tplain "%s" > "%s"' % (udir.join(FILENAME), + udir.join(plain_name))) + print "=== dotviewer.py %s" % plain_name + err = os.system('"%s" "%s"' % (pkgdir.join('dotviewer.py'), + udir.join(plain_name))) + assert err == 0 + +def test_display_dot_file(): + from dotviewer.graphclient import display_dot_file + print "=== display_dot_file(%s) with GRAPHSERVER=%s" % ( + FILENAME, os.environ.get('GRAPHSERVER', ''),) + display_dot_file(udir.join(FILENAME)) + print "=== display_dot_file finished" + + +def test_graphserver(): + import socket + s = socket.socket() + s.listen(1) + host, port = s.getsockname() # pick a random free port + s.close() + + if hasattr(sys, 'pypy_objspaceclass'): + python = 'python' + else: + python = sys.executable + + cmdargs = [python, str(pkgdir.join('graphserver.py')), + str(port)] + print '* starting:', ' '.join(cmdargs) + pid = os.spawnv(os.P_NOWAIT, cmdargs[0], cmdargs) + try: + time.sleep(1) # hack - wait a bit to make sure the server is up + os.environ['GRAPHSERVER'] = '%s:%d' % (host, port) + try: + test_display_dot_file() + finally: + del os.environ['GRAPHSERVER'] + finally: + os.kill(pid, signal.SIGTERM) + +def test_colors(): + from dotviewer import graphpage, graphclient + class MyPage(graphpage.DotFileGraphPage): + def compute(self, dotfile): + super(MyPage, self).compute(dotfile) + self.links = {'v2721': 'Hello world', + 'v2720': ('Something green', (0, 192, 0)), + } + dotfile = str(udir.join(FILENAME)) + page = MyPage(dotfile) + graphclient.display_page(page) + +def test_fixedfont(): + from dotviewer import graphpage, graphclient + class MyPage(graphpage.DotFileGraphPage): + fixedfont = True + dotfile = str(udir.join(FILENAME)) + page = MyPage(dotfile) + page.fixedfont = True + graphclient.display_page(page) diff --git a/dotviewer/test/test_translator.py b/dotviewer/test/test_translator.py --- a/dotviewer/test/test_translator.py +++ b/dotviewer/test/test_translator.py @@ -22,6 +22,6 @@ def test_annotated(): from rpython.translator.interactive import Translation - t = Translation(is_prime) - t.annotate([int]) + t = Translation(is_prime, [int]) + t.annotate() t.viewcg() diff --git a/dotviewer/test/test_unicode_util.py b/dotviewer/test/test_unicode_util.py new file mode 100755 --- /dev/null +++ b/dotviewer/test/test_unicode_util.py @@ -0,0 +1,57 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +import py +import codecs +from dotviewer.drawgraph import RAW_ENCODING, forcestr, forceunicode + +SOURCE1 = u"""digraph G{ +λ -> b +b -> μ +} +""" + +FILENAME = 'test.dot' + +class TestUnicodeUtil(object): + + def test_idempotent(self): + x = u"a" + assert forceunicode(forcestr(x)) == x + + x = u"λ" + assert forceunicode(forcestr(x)) == x + + assert forceunicode(forcestr(SOURCE1)) == SOURCE1 + + x = "a" + assert forcestr(forceunicode(x)) == x + + # utf-8 encoded. + # fragile, does not consider RAW_ENCODING + # x = "\xef\xbb\xbf\xce\xbb" + # assert forcestr(forceunicode(x)) == x + + def test_does_not_double_encode(self): + x = u"λ" + x_e = forcestr(x) + assert forcestr(x_e) == x_e + + x_u = forceunicode(x_e) + assert forceunicode(x_u) == x_u + + def test_file(self): + udir = py.path.local.make_numbered_dir(prefix='usession-dot-', keep=3) + full_filename = str(udir.join(FILENAME)) + f = codecs.open(full_filename, 'wb', RAW_ENCODING) + f.write(SOURCE1) + f.close() + + with open(full_filename) as f1: + assert forceunicode(f1.read()) == SOURCE1 + + f3 = codecs.open(full_filename, 'r', RAW_ENCODING) + c = f3.read() + f3.close() + result = (c == SOURCE1) + assert result diff --git a/lib-python/2.7/collections.py b/lib-python/2.7/collections.py --- a/lib-python/2.7/collections.py +++ b/lib-python/2.7/collections.py @@ -295,7 +295,7 @@ _fields = %(field_names)r \n def __new__(_cls, %(argtxt)s): 'Create new instance of %(typename)s(%(argtxt)s)' - return tuple.__new__(_cls, (%(argtxt)s)) \n + return _tuple.__new__(_cls, (%(argtxt)s)) \n @classmethod def _make(cls, iterable, new=tuple.__new__, len=len): 'Make a new %(typename)s object from a sequence or iterable' @@ -320,14 +320,14 @@ 'Return self as a plain tuple. Used by copy and pickle.' return tuple(self) \n\n''' % locals() for i, name in enumerate(field_names): - template += " %s = property(lambda self: self[%d], doc='Alias for field number %d')\n" % (name, i, i) + template += " %s = _property(lambda self: self[%d], doc='Alias for field number %d')\n" % (name, i, i) if verbose: print template # Execute the template string in a temporary namespace and # support tracing utilities by setting a value for frame.f_globals['__name__'] - namespace = {'__name__': 'namedtuple_%s' % typename, - 'OrderedDict': OrderedDict} + namespace = dict(__name__='namedtuple_%s' % typename, + OrderedDict=OrderedDict, _property=property, _tuple=tuple) try: exec template in namespace except SyntaxError, e: diff --git a/lib-python/2.7/json/encoder.py b/lib-python/2.7/json/encoder.py --- a/lib-python/2.7/json/encoder.py +++ b/lib-python/2.7/json/encoder.py @@ -138,16 +138,16 @@ self.skipkeys = skipkeys self.ensure_ascii = ensure_ascii if ensure_ascii: - self.encoder = raw_encode_basestring_ascii + self.__encoder = raw_encode_basestring_ascii else: - self.encoder = raw_encode_basestring + self.__encoder = raw_encode_basestring if encoding != 'utf-8': - orig_encoder = self.encoder + orig_encoder = self.__encoder def encoder(o): if isinstance(o, str): o = o.decode(encoding) return orig_encoder(o) - self.encoder = encoder + self.__encoder = encoder self.check_circular = check_circular self.allow_nan = allow_nan self.sort_keys = sort_keys @@ -193,10 +193,10 @@ builder = StringBuilder() else: builder = UnicodeBuilder() - self._encode(o, markers, builder, 0) + self.__encode(o, markers, builder, 0) return builder.build() - def _emit_indent(self, builder, _current_indent_level): + def __emit_indent(self, builder, _current_indent_level): if self.indent is not None: _current_indent_level += 1 newline_indent = '\n' + (' ' * (self.indent * @@ -207,15 +207,15 @@ separator = self.item_separator return separator, _current_indent_level - def _emit_unindent(self, builder, _current_indent_level): + def __emit_unindent(self, builder, _current_indent_level): if self.indent is not None: builder.append('\n') builder.append(' ' * (self.indent * (_current_indent_level - 1))) - def _encode(self, o, markers, builder, _current_indent_level): + def __encode(self, o, markers, builder, _current_indent_level): if isinstance(o, basestring): builder.append('"') - builder.append(self.encoder(o)) + builder.append(self.__encoder(o)) builder.append('"') elif o is None: builder.append('null') @@ -226,46 +226,46 @@ elif isinstance(o, (int, long)): builder.append(str(o)) elif isinstance(o, float): - builder.append(self._floatstr(o)) + builder.append(self.__floatstr(o)) elif isinstance(o, (list, tuple)): if not o: builder.append('[]') return - self._encode_list(o, markers, builder, _current_indent_level) + self.__encode_list(o, markers, builder, _current_indent_level) elif isinstance(o, dict): if not o: builder.append('{}') return - self._encode_dict(o, markers, builder, _current_indent_level) + self.__encode_dict(o, markers, builder, _current_indent_level) else: - self._mark_markers(markers, o) + self.__mark_markers(markers, o) res = self.default(o) - self._encode(res, markers, builder, _current_indent_level) - self._remove_markers(markers, o) + self.__encode(res, markers, builder, _current_indent_level) + self.__remove_markers(markers, o) return res - def _encode_list(self, l, markers, builder, _current_indent_level): - self._mark_markers(markers, l) + def __encode_list(self, l, markers, builder, _current_indent_level): + self.__mark_markers(markers, l) builder.append('[') first = True - separator, _current_indent_level = self._emit_indent(builder, + separator, _current_indent_level = self.__emit_indent(builder, _current_indent_level) for elem in l: if first: first = False else: builder.append(separator) - self._encode(elem, markers, builder, _current_indent_level) + self.__encode(elem, markers, builder, _current_indent_level) del elem # XXX grumble - self._emit_unindent(builder, _current_indent_level) + self.__emit_unindent(builder, _current_indent_level) builder.append(']') - self._remove_markers(markers, l) + self.__remove_markers(markers, l) - def _encode_dict(self, d, markers, builder, _current_indent_level): - self._mark_markers(markers, d) + def __encode_dict(self, d, markers, builder, _current_indent_level): + self.__mark_markers(markers, d) first = True builder.append('{') - separator, _current_indent_level = self._emit_indent(builder, + separator, _current_indent_level = self.__emit_indent(builder, _current_indent_level) if self.sort_keys: items = sorted(d.items(), key=lambda kv: kv[0]) @@ -282,7 +282,7 @@ # JavaScript is weakly typed for these, so it makes sense to # also allow them. Many encoders seem to do something like this. elif isinstance(key, float): - key = self._floatstr(key) + key = self.__floatstr(key) elif key is True: key = 'true' elif key is False: @@ -296,15 +296,15 @@ else: raise TypeError("key " + repr(key) + " is not a string") builder.append('"') - builder.append(self.encoder(key)) + builder.append(self.__encoder(key)) builder.append('"') builder.append(self.key_separator) - self._encode(v, markers, builder, _current_indent_level) + self.__encode(v, markers, builder, _current_indent_level) del key del v # XXX grumble - self._emit_unindent(builder, _current_indent_level) + self.__emit_unindent(builder, _current_indent_level) builder.append('}') - self._remove_markers(markers, d) + self.__remove_markers(markers, d) def iterencode(self, o, _one_shot=False): """Encode the given object and yield each string @@ -320,9 +320,9 @@ markers = {} else: markers = None - return self._iterencode(o, markers, 0) + return self.__iterencode(o, markers, 0) - def _floatstr(self, o): + def __floatstr(self, o): # Check for specials. Note that this type of test is processor # and/or platform-specific, so do tests which don't depend on the # internals. @@ -343,21 +343,21 @@ return text - def _mark_markers(self, markers, o): + def __mark_markers(self, markers, o): if markers is not None: if id(o) in markers: raise ValueError("Circular reference detected") markers[id(o)] = None - def _remove_markers(self, markers, o): + def __remove_markers(self, markers, o): if markers is not None: del markers[id(o)] - def _iterencode_list(self, lst, markers, _current_indent_level): + def __iterencode_list(self, lst, markers, _current_indent_level): if not lst: yield '[]' return - self._mark_markers(markers, lst) + self.__mark_markers(markers, lst) buf = '[' if self.indent is not None: _current_indent_level += 1 @@ -375,7 +375,7 @@ else: buf = separator if isinstance(value, basestring): - yield buf + '"' + self.encoder(value) + '"' + yield buf + '"' + self.__encoder(value) + '"' elif value is None: yield buf + 'null' elif value is True: @@ -385,17 +385,17 @@ elif isinstance(value, (int, long)): yield buf + str(value) elif isinstance(value, float): - yield buf + self._floatstr(value) + yield buf + self.__floatstr(value) else: yield buf if isinstance(value, (list, tuple)): - chunks = self._iterencode_list(value, markers, + chunks = self.__iterencode_list(value, markers, _current_indent_level) elif isinstance(value, dict): - chunks = self._iterencode_dict(value, markers, + chunks = self.__iterencode_dict(value, markers, _current_indent_level) else: - chunks = self._iterencode(value, markers, + chunks = self.__iterencode(value, markers, _current_indent_level) for chunk in chunks: yield chunk @@ -403,13 +403,13 @@ _current_indent_level -= 1 yield '\n' + (' ' * (self.indent * _current_indent_level)) yield ']' - self._remove_markers(markers, lst) + self.__remove_markers(markers, lst) - def _iterencode_dict(self, dct, markers, _current_indent_level): + def __iterencode_dict(self, dct, markers, _current_indent_level): if not dct: yield '{}' return - self._mark_markers(markers, dct) + self.__mark_markers(markers, dct) yield '{' if self.indent is not None: _current_indent_level += 1 @@ -431,7 +431,7 @@ # JavaScript is weakly typed for these, so it makes sense to # also allow them. Many encoders seem to do something like this. elif isinstance(key, float): - key = self._floatstr(key) + key = self.__floatstr(key) elif key is True: key = 'true' elif key is False: @@ -448,10 +448,10 @@ first = False else: yield item_separator - yield '"' + self.encoder(key) + '"' + yield '"' + self.__encoder(key) + '"' yield self.key_separator if isinstance(value, basestring): - yield '"' + self.encoder(value) + '"' + yield '"' + self.__encoder(value) + '"' elif value is None: yield 'null' elif value is True: @@ -461,16 +461,16 @@ elif isinstance(value, (int, long)): yield str(value) elif isinstance(value, float): - yield self._floatstr(value) + yield self.__floatstr(value) else: if isinstance(value, (list, tuple)): - chunks = self._iterencode_list(value, markers, + chunks = self.__iterencode_list(value, markers, _current_indent_level) elif isinstance(value, dict): - chunks = self._iterencode_dict(value, markers, + chunks = self.__iterencode_dict(value, markers, _current_indent_level) else: - chunks = self._iterencode(value, markers, + chunks = self.__iterencode(value, markers, _current_indent_level) for chunk in chunks: yield chunk @@ -478,11 +478,11 @@ _current_indent_level -= 1 yield '\n' + (' ' * (self.indent * _current_indent_level)) yield '}' - self._remove_markers(markers, dct) + self.__remove_markers(markers, dct) - def _iterencode(self, o, markers, _current_indent_level): + def __iterencode(self, o, markers, _current_indent_level): if isinstance(o, basestring): - yield '"' + self.encoder(o) + '"' + yield '"' + self.__encoder(o) + '"' elif o is None: yield 'null' elif o is True: @@ -492,19 +492,19 @@ elif isinstance(o, (int, long)): yield str(o) elif isinstance(o, float): - yield self._floatstr(o) + yield self.__floatstr(o) elif isinstance(o, (list, tuple)): - for chunk in self._iterencode_list(o, markers, + for chunk in self.__iterencode_list(o, markers, _current_indent_level): yield chunk elif isinstance(o, dict): - for chunk in self._iterencode_dict(o, markers, + for chunk in self.__iterencode_dict(o, markers, _current_indent_level): yield chunk else: - self._mark_markers(markers, o) + self.__mark_markers(markers, o) obj = self.default(o) - for chunk in self._iterencode(obj, markers, + for chunk in self.__iterencode(obj, markers, _current_indent_level): yield chunk - self._remove_markers(markers, o) + self.__remove_markers(markers, o) diff --git a/lib-python/2.7/test/test_generators.py b/lib-python/2.7/test/test_generators.py --- a/lib-python/2.7/test/test_generators.py +++ b/lib-python/2.7/test/test_generators.py @@ -1501,9 +1501,7 @@ """ coroutine_tests = """\ -A helper function to call gc.collect() without printing ->>> import gc ->>> def gc_collect(): gc.collect() +>>> from test.test_support import gc_collect Sending a value into a started generator: @@ -1823,8 +1821,7 @@ references. We add it to the standard suite so the routine refleak-tests would trigger if it starts being uncleanable again. ->>> import gc ->>> def gc_collect(): gc.collect() +>>> from test.test_support import gc_collect >>> import itertools >>> def leak(): diff --git a/lib-python/2.7/urllib.py b/lib-python/2.7/urllib.py --- a/lib-python/2.7/urllib.py +++ b/lib-python/2.7/urllib.py @@ -1205,15 +1205,17 @@ # fastpath if len(res) == 1: return s - s = res[0] - for item in res[1:]: + res_list = [res[0]] + for j in xrange(1, len(res)): + item = res[j] try: - s += _hextochr[item[:2]] + item[2:] + x = _hextochr[item[:2]] + item[2:] except KeyError: - s += '%' + item + x = '%' + item except UnicodeDecodeError: - s += unichr(int(item[:2], 16)) + item[2:] - return s + x = unichr(int(item[:2], 16)) + item[2:] + res_list.append(x) + return ''.join(res_list) def unquote_plus(s): """unquote('%7e/abc+def') -> '~/abc def'""" diff --git a/lib-python/2.7/urlparse.py b/lib-python/2.7/urlparse.py --- a/lib-python/2.7/urlparse.py +++ b/lib-python/2.7/urlparse.py @@ -321,15 +321,17 @@ # fastpath if len(res) == 1: return s - s = res[0] - for item in res[1:]: + res_list = [res[0]] + for j in xrange(1, len(res)): + item = res[j] try: - s += _hextochr[item[:2]] + item[2:] + x = _hextochr[item[:2]] + item[2:] except KeyError: - s += '%' + item + x = '%' + item except UnicodeDecodeError: - s += unichr(int(item[:2], 16)) + item[2:] - return s + x = unichr(int(item[:2], 16)) + item[2:] + res_list.append(x) + return ''.join(res_list) def parse_qs(qs, keep_blank_values=0, strict_parsing=0): """Parse a query given as a string argument. diff --git a/lib-python/conftest.py b/lib-python/conftest.py --- a/lib-python/conftest.py +++ b/lib-python/conftest.py @@ -272,7 +272,7 @@ RegrTest('test_inspect.py'), RegrTest('test_int.py', core=True), RegrTest('test_int_literal.py', core=True), - RegrTest('test_io.py'), + RegrTest('test_io.py', usemodules='array binascii'), RegrTest('test_ioctl.py'), RegrTest('test_isinstance.py', core=True), RegrTest('test_iter.py', core=True), diff --git a/lib_pypy/_collections.py b/lib_pypy/_collections.py --- a/lib_pypy/_collections.py +++ b/lib_pypy/_collections.py @@ -157,9 +157,9 @@ def rotate(self, n=1): length = len(self) - if length == 0: + if length <= 1: return - halflen = (length+1) >> 1 + halflen = length >> 1 if n > halflen or n < -halflen: n %= length if n > halflen: diff --git a/lib_pypy/conftest.py b/lib_pypy/conftest.py deleted file mode 100644 --- a/lib_pypy/conftest.py +++ /dev/null @@ -1,2 +0,0 @@ - -from pypy.conftest import * diff --git a/lib_pypy/datetime.py b/lib_pypy/datetime.py --- a/lib_pypy/datetime.py +++ b/lib_pypy/datetime.py @@ -18,7 +18,6 @@ import time as _time import math as _math -import decimal as _decimal MINYEAR = 1 MAXYEAR = 9999 @@ -272,9 +271,17 @@ raise ValueError("%s()=%d, must be in -1439..1439" % (name, offset)) def _check_int_field(value): - if not isinstance(value, (int, long, _decimal.Decimal)): - raise TypeError('integer argument expected') - return int(value) + if isinstance(value, int): + return value + if not isinstance(value, float): + try: + value = value.__int__() + except AttributeError: + pass + else: + if isinstance(value, (int, long)): + return value + raise TypeError('an integer is required') def _check_date_fields(year, month, day): year = _check_int_field(year) @@ -452,6 +459,8 @@ felt like it. """ + __slots__ = '_days', '_seconds', '_microseconds' + def __new__(cls, days=0, seconds=0, microseconds=0, # XXX The following should only be used as keyword args: milliseconds=0, minutes=0, hours=0, weeks=0): @@ -765,6 +774,8 @@ year, month, day """ + __slots__ = '_year', '_month', '_day' + def __new__(cls, year, month=None, day=None): """Constructor. @@ -772,7 +783,7 @@ year, month, day (required, base 1) """ - if isinstance(year, str): + if isinstance(year, str) and len(year) == 4: # Pickle support self = object.__new__(cls) self.__setstate(year) @@ -1058,6 +1069,8 @@ Subclasses must override the name(), utcoffset() and dst() methods. """ + __slots__ = () + def tzname(self, dt): "datetime -> string name of time zone." raise NotImplementedError("tzinfo subclass must override tzname()") @@ -1150,6 +1163,8 @@ hour, minute, second, microsecond, tzinfo """ + __slots__ = '_hour', '_minute', '_second', '_microsecond', '_tzinfo' + def __new__(cls, hour=0, minute=0, second=0, microsecond=0, tzinfo=None): """Constructor. @@ -1452,9 +1467,11 @@ instance of a tzinfo subclass. The remaining arguments may be ints or longs. """ + __slots__ = date.__slots__ + time.__slots__ + def __new__(cls, year, month=None, day=None, hour=0, minute=0, second=0, microsecond=0, tzinfo=None): - if isinstance(year, str): + if isinstance(year, str) and len(year) == 10: # Pickle support self = date.__new__(cls, year[:4]) self.__setstate(year, month) diff --git a/lib_pypy/dbm.py b/lib_pypy/dbm.py --- a/lib_pypy/dbm.py +++ b/lib_pypy/dbm.py @@ -1,4 +1,4 @@ -from ctypes import Structure, c_char_p, c_int, c_void_p, CDLL +from ctypes import Structure, c_char_p, c_int, c_void_p, CDLL, POINTER, c_char import ctypes.util import os, sys @@ -11,7 +11,7 @@ class datum(Structure): _fields_ = [ - ('dptr', c_char_p), + ('dptr', POINTER(c_char)), ('dsize', c_int), ] @@ -126,8 +126,8 @@ libpath = ctypes.util.find_library('db') if not libpath: # XXX this is hopeless... - for c in '56789': - libpath = ctypes.util.find_library('db-4.%s' % c) + for c in ['5.3', '5.2', '5.1', '5.0', '4.9', '4.8', '4.7', '4.6', '4.5']: + libpath = ctypes.util.find_library('db-%s' % c) if libpath: break else: diff --git a/lib_pypy/numpypy/__init__.py b/lib_pypy/numpypy/__init__.py --- a/lib_pypy/numpypy/__init__.py +++ b/lib_pypy/numpypy/__init__.py @@ -1,5 +1,14 @@ -from _numpypy import * -from .core import * +import core +from core import * +import lib +from lib import * + +from __builtin__ import bool, int, long, float, complex, object, unicode, str +from core import abs, max, min + +__all__ = [] +__all__ += core.__all__ +__all__ += lib.__all__ import sys sys.modules.setdefault('numpy', sys.modules['numpypy']) diff --git a/lib_pypy/numpypy/core/__init__.py b/lib_pypy/numpypy/core/__init__.py --- a/lib_pypy/numpypy/core/__init__.py +++ b/lib_pypy/numpypy/core/__init__.py @@ -1,2 +1,14 @@ -from .fromnumeric import * -from .numeric import * +import numeric +from numeric import * +import fromnumeric +from fromnumeric import * +import shape_base +from shape_base import * + +from fromnumeric import amax as max, amin as min +from numeric import absolute as abs + +__all__ = [] +__all__ += numeric.__all__ +__all__ += fromnumeric.__all__ +__all__ += shape_base.__all__ diff --git a/lib_pypy/numpypy/core/_methods.py b/lib_pypy/numpypy/core/_methods.py --- a/lib_pypy/numpypy/core/_methods.py +++ b/lib_pypy/numpypy/core/_methods.py @@ -1,11 +1,9 @@ # Array methods which are called by the both the C-code for the method # and the Python code for the NumPy-namespace function -#from numpy.core import multiarray as mu -#from numpy.core import umath as um -import _numpypy as mu -um = mu -from numpy.core.numeric import asanyarray +import multiarray as mu +import umath as um +from numeric import asanyarray def _amax(a, axis=None, out=None, keepdims=False): return um.maximum.reduce(a, axis=axis, diff --git a/lib_pypy/numpypy/core/arrayprint.py b/lib_pypy/numpypy/core/arrayprint.py --- a/lib_pypy/numpypy/core/arrayprint.py +++ b/lib_pypy/numpypy/core/arrayprint.py @@ -13,9 +13,9 @@ # and by Travis Oliphant 2005-8-22 for numpy import sys -import _numpypy as _nt -from _numpypy import maximum, minimum, absolute, not_equal, isnan, isinf -#from _numpypy import format_longfloat, datetime_as_string, datetime_data +import numerictypes as _nt +from umath import maximum, minimum, absolute, not_equal, isnan, isinf +#from multiarray import format_longfloat, datetime_as_string, datetime_data from fromnumeric import ravel @@ -294,12 +294,12 @@ #else: format_function = formatdict['int'] elif issubclass(dtypeobj, _nt.floating): - if issubclass(dtypeobj, _nt.longfloat): + if hasattr(_nt, 'longfloat') and issubclass(dtypeobj, _nt.longfloat): format_function = formatdict['longfloat'] else: format_function = formatdict['float'] elif issubclass(dtypeobj, _nt.complexfloating): - if issubclass(dtypeobj, _nt.clongfloat): + if hasattr(_nt, 'clongfloat') and issubclass(dtypeobj, _nt.clongfloat): format_function = formatdict['longcomplexfloat'] else: format_function = formatdict['complexfloat'] diff --git a/lib_pypy/numpypy/core/fromnumeric.py b/lib_pypy/numpypy/core/fromnumeric.py --- a/lib_pypy/numpypy/core/fromnumeric.py +++ b/lib_pypy/numpypy/core/fromnumeric.py @@ -16,6 +16,7 @@ ###################################################################### import numpypy +import _numpypy # Module containing non-deprecated functions borrowed from Numeric. __docformat__ = "restructuredtext en" @@ -274,7 +275,7 @@ [-1, -2, -3, -4, -5]]]) """ - raise NotImplementedError('Waiting on interp level method') + return _numpypy.choose(a, choices, out, mode) def repeat(a, repeats, axis=None): @@ -316,7 +317,7 @@ [3, 4]]) """ - raise NotImplementedError('Waiting on interp level method') + return _numpypy.repeat(a, repeats, axis) def put(a, ind, v, mode='raise'): @@ -1290,7 +1291,9 @@ array([3, 4, 2, 3, 4, 5, 6, 7, 8, 8]) """ - raise NotImplementedError('Waiting on interp level method') + if not hasattr(a, 'clip'): + a = numpypy.array(a) + return a.clip(a_min, a_max, out=out) def sum(a, axis=None, dtype=None, out=None): @@ -1360,10 +1363,9 @@ """ assert dtype is None - assert out is None if not hasattr(a, "sum"): a = numpypy.array(a) - return a.sum(axis=axis) + return a.sum(axis=axis, out=out) def product (a, axis=None, dtype=None, out=None): @@ -1720,11 +1722,11 @@ 4.0 """ - assert axis is None - assert out is None if not hasattr(a, "max"): a = numpypy.array(a) - return a.max() + if a.size < 1: + return numpypy.array([]) + return a.max(axis=axis, out=out) def amin(a, axis=None, out=None): @@ -1782,12 +1784,11 @@ 0.0 """ - # amin() is equivalent to min() - assert axis is None - assert out is None if not hasattr(a, 'min'): a = numpypy.array(a) - return a.min() + if a.size < 1: + return numpypy.array([]) + return a.min(axis=axis, out=out) def alen(a): """ diff --git a/lib_pypy/numpypy/core/multiarray.py b/lib_pypy/numpypy/core/multiarray.py new file mode 100644 --- /dev/null +++ b/lib_pypy/numpypy/core/multiarray.py @@ -0,0 +1,1 @@ +from _numpypy.multiarray import * diff --git a/lib_pypy/numpypy/core/numeric.py b/lib_pypy/numpypy/core/numeric.py --- a/lib_pypy/numpypy/core/numeric.py +++ b/lib_pypy/numpypy/core/numeric.py @@ -1,13 +1,40 @@ +__all__ = [ + 'newaxis', 'ufunc', + 'asarray', 'asanyarray', 'base_repr', + 'array_repr', 'array_str', 'set_string_function', + 'array_equal', 'outer', 'identity', 'little_endian', + 'Inf', 'inf', 'infty', 'Infinity', 'nan', 'NaN', 'False_', 'True_', + ] -from _numpypy import array, ndarray, int_, float_, bool_, flexible #, complex_# , longlong -from _numpypy import concatenate -from .fromnumeric import any -import math import sys -import _numpypy as multiarray # ARGH -from numpypy.core.arrayprint import array2string +import multiarray +from multiarray import * +del set_string_function +del typeinfo +import umath +from umath import * +import numerictypes +from numerictypes import * + +def extend_all(module): + adict = {} + for a in __all__: + adict[a] = 1 + try: + mall = getattr(module, '__all__') + except AttributeError: + mall = [k for k in module.__dict__.keys() if not k.startswith('_')] + for a in mall: + if a not in adict: + __all__.append(a) + +extend_all(multiarray) +__all__.remove('typeinfo') +extend_all(umath) +extend_all(numerictypes) newaxis = None +ufunc = type(sin) # XXX this file to be reviewed def seterr(**args): @@ -118,6 +145,10 @@ res.append('-') return ''.join(reversed(res or '0')) + +#Use numarray's printing function +from arrayprint import array2string + _typelessdata = [int_, float_]#, complex_] # XXX #if issubclass(intc, int): @@ -303,6 +334,11 @@ else: return multiarray.set_string_function(f, repr) +set_string_function(array_str, 0) +set_string_function(array_repr, 1) + +little_endian = (sys.byteorder == 'little') + def array_equal(a1, a2): """ True if two arrays have the same shape and elements, False otherwise. @@ -414,17 +450,115 @@ """ return array(a, dtype, copy=False, order=order) -set_string_function(array_str, 0) -set_string_function(array_repr, 1) +def outer(a,b): + """ + Compute the outer product of two vectors. -little_endian = (sys.byteorder == 'little') + Given two vectors, ``a = [a0, a1, ..., aM]`` and + ``b = [b0, b1, ..., bN]``, + the outer product [1]_ is:: -Inf = inf = infty = Infinity = PINF = float('inf') -NINF = float('-inf') -PZERO = 0.0 -NZERO = -0.0 -nan = NaN = NAN = float('nan') + [[a0*b0 a0*b1 ... a0*bN ] + [a1*b0 . + [ ... . + [aM*b0 aM*bN ]] + + Parameters + ---------- + a, b : array_like, shape (M,), (N,) + First and second input vectors. Inputs are flattened if they + are not already 1-dimensional. + + Returns + ------- + out : ndarray, shape (M, N) + ``out[i, j] = a[i] * b[j]`` + + See also + -------- + inner, einsum + + References + ---------- + .. [1] : G. H. Golub and C. F. van Loan, *Matrix Computations*, 3rd + ed., Baltimore, MD, Johns Hopkins University Press, 1996, + pg. 8. + + Examples + -------- + Make a (*very* coarse) grid for computing a Mandelbrot set: + + >>> rl = np.outer(np.ones((5,)), np.linspace(-2, 2, 5)) + >>> rl + array([[-2., -1., 0., 1., 2.], + [-2., -1., 0., 1., 2.], + [-2., -1., 0., 1., 2.], + [-2., -1., 0., 1., 2.], + [-2., -1., 0., 1., 2.]]) + >>> im = np.outer(1j*np.linspace(2, -2, 5), np.ones((5,))) + >>> im + array([[ 0.+2.j, 0.+2.j, 0.+2.j, 0.+2.j, 0.+2.j], + [ 0.+1.j, 0.+1.j, 0.+1.j, 0.+1.j, 0.+1.j], + [ 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j], + [ 0.-1.j, 0.-1.j, 0.-1.j, 0.-1.j, 0.-1.j], + [ 0.-2.j, 0.-2.j, 0.-2.j, 0.-2.j, 0.-2.j]]) + >>> grid = rl + im + >>> grid + array([[-2.+2.j, -1.+2.j, 0.+2.j, 1.+2.j, 2.+2.j], + [-2.+1.j, -1.+1.j, 0.+1.j, 1.+1.j, 2.+1.j], + [-2.+0.j, -1.+0.j, 0.+0.j, 1.+0.j, 2.+0.j], + [-2.-1.j, -1.-1.j, 0.-1.j, 1.-1.j, 2.-1.j], + [-2.-2.j, -1.-2.j, 0.-2.j, 1.-2.j, 2.-2.j]]) + + An example using a "vector" of letters: + + >>> x = np.array(['a', 'b', 'c'], dtype=object) + >>> np.outer(x, [1, 2, 3]) + array([[a, aa, aaa], + [b, bb, bbb], + [c, cc, ccc]], dtype=object) + + """ + a = asarray(a) + b = asarray(b) + return a.ravel()[:,newaxis]*b.ravel()[newaxis,:] + +def identity(n, dtype=None): + """ + Return the identity array. + + The identity array is a square array with ones on + the main diagonal. + + Parameters + ---------- + n : int + Number of rows (and columns) in `n` x `n` output. + dtype : data-type, optional + Data-type of the output. Defaults to ``float``. + + Returns + ------- + out : ndarray + `n` x `n` array with its main diagonal set to one, + and all other elements 0. + + Examples + -------- + >>> np.identity(3) + array([[ 1., 0., 0.], + [ 0., 1., 0.], + [ 0., 0., 1.]]) + + """ + from numpy import eye + return eye(n, dtype=dtype) + +Inf = inf = infty = Infinity = PINF +nan = NaN = NAN False_ = bool_(False) True_ = bool_(True) -e = math.e -pi = math.pi + +import fromnumeric +from fromnumeric import * +extend_all(fromnumeric) diff --git a/lib_pypy/numpypy/core/numerictypes.py b/lib_pypy/numpypy/core/numerictypes.py new file mode 100644 --- /dev/null +++ b/lib_pypy/numpypy/core/numerictypes.py @@ -0,0 +1,1 @@ +from _numpypy.numerictypes import * diff --git a/lib_pypy/numpypy/core/shape_base.py b/lib_pypy/numpypy/core/shape_base.py new file mode 100644 --- /dev/null +++ b/lib_pypy/numpypy/core/shape_base.py @@ -0,0 +1,275 @@ +__all__ = ['atleast_1d', 'atleast_2d', 'atleast_3d', 'vstack', 'hstack'] + +import numeric as _nx +from numeric import array, asanyarray, newaxis + +def atleast_1d(*arys): + """ + Convert inputs to arrays with at least one dimension. + + Scalar inputs are converted to 1-dimensional arrays, whilst + higher-dimensional inputs are preserved. + + Parameters + ---------- + arys1, arys2, ... : array_like + One or more input arrays. + + Returns + ------- + ret : ndarray + An array, or sequence of arrays, each with ``a.ndim >= 1``. + Copies are made only if necessary. + + See Also + -------- + atleast_2d, atleast_3d + + Examples + -------- + >>> np.atleast_1d(1.0) + array([ 1.]) + + >>> x = np.arange(9.0).reshape(3,3) + >>> np.atleast_1d(x) + array([[ 0., 1., 2.], + [ 3., 4., 5.], + [ 6., 7., 8.]]) + >>> np.atleast_1d(x) is x + True + + >>> np.atleast_1d(1, [3, 4]) + [array([1]), array([3, 4])] + + """ + res = [] + for ary in arys: + ary = asanyarray(ary) + if len(ary.shape) == 0 : + result = ary.reshape(1) + else : + result = ary + res.append(result) + if len(res) == 1: + return res[0] + else: + return res + + +def atleast_2d(*arys): + """ + View inputs as arrays with at least two dimensions. + + Parameters + ---------- + arys1, arys2, ... : array_like + One or more array-like sequences. Non-array inputs are converted + to arrays. Arrays that already have two or more dimensions are + preserved. + + Returns + ------- + res, res2, ... : ndarray + An array, or tuple of arrays, each with ``a.ndim >= 2``. + Copies are avoided where possible, and views with two or more + dimensions are returned. + + See Also + -------- + atleast_1d, atleast_3d + + Examples + -------- + >>> np.atleast_2d(3.0) + array([[ 3.]]) + + >>> x = np.arange(3.0) + >>> np.atleast_2d(x) + array([[ 0., 1., 2.]]) + >>> np.atleast_2d(x).base is x + True + + >>> np.atleast_2d(1, [1, 2], [[1, 2]]) + [array([[1]]), array([[1, 2]]), array([[1, 2]])] + + """ + res = [] + for ary in arys: + ary = asanyarray(ary) + if len(ary.shape) == 0 : + result = ary.reshape(1, 1) + elif len(ary.shape) == 1 : + result = ary[newaxis, :] + else : + result = ary + res.append(result) + if len(res) == 1: + return res[0] + else: + return res + +def atleast_3d(*arys): + """ + View inputs as arrays with at least three dimensions. + + Parameters + ---------- + arys1, arys2, ... : array_like + One or more array-like sequences. Non-array inputs are converted to + arrays. Arrays that already have three or more dimensions are + preserved. + + Returns + ------- + res1, res2, ... : ndarray + An array, or tuple of arrays, each with ``a.ndim >= 3``. Copies are + avoided where possible, and views with three or more dimensions are + returned. For example, a 1-D array of shape ``(N,)`` becomes a view + of shape ``(1, N, 1)``, and a 2-D array of shape ``(M, N)`` becomes a + view of shape ``(M, N, 1)``. + + See Also + -------- + atleast_1d, atleast_2d + + Examples + -------- + >>> np.atleast_3d(3.0) + array([[[ 3.]]]) + + >>> x = np.arange(3.0) + >>> np.atleast_3d(x).shape + (1, 3, 1) + + >>> x = np.arange(12.0).reshape(4,3) + >>> np.atleast_3d(x).shape + (4, 3, 1) + >>> np.atleast_3d(x).base is x + True + + >>> for arr in np.atleast_3d([1, 2], [[1, 2]], [[[1, 2]]]): + ... print arr, arr.shape + ... + [[[1] + [2]]] (1, 2, 1) + [[[1] + [2]]] (1, 2, 1) + [[[1 2]]] (1, 1, 2) + + """ + res = [] + for ary in arys: + ary = asanyarray(ary) + if len(ary.shape) == 0: + result = ary.reshape(1,1,1) + elif len(ary.shape) == 1: + result = ary[newaxis,:,newaxis] + elif len(ary.shape) == 2: + result = ary[:,:,newaxis] + else: + result = ary + res.append(result) + if len(res) == 1: + return res[0] + else: + return res + +def vstack(tup): + """ + Stack arrays in sequence vertically (row wise). + + Take a sequence of arrays and stack them vertically to make a single + array. Rebuild arrays divided by `vsplit`. + + Parameters + ---------- + tup : sequence of ndarrays + Tuple containing arrays to be stacked. The arrays must have the same + shape along all but the first axis. + + Returns + ------- + stacked : ndarray + The array formed by stacking the given arrays. + + See Also + -------- + hstack : Stack arrays in sequence horizontally (column wise). + dstack : Stack arrays in sequence depth wise (along third dimension). + concatenate : Join a sequence of arrays together. + vsplit : Split array into a list of multiple sub-arrays vertically. + + Notes + ----- + Equivalent to ``np.concatenate(tup, axis=0)`` if `tup` contains arrays that + are at least 2-dimensional. + + Examples + -------- + >>> a = np.array([1, 2, 3]) + >>> b = np.array([2, 3, 4]) + >>> np.vstack((a,b)) + array([[1, 2, 3], + [2, 3, 4]]) + + >>> a = np.array([[1], [2], [3]]) + >>> b = np.array([[2], [3], [4]]) + >>> np.vstack((a,b)) + array([[1], + [2], + [3], + [2], + [3], + [4]]) + + """ + return _nx.concatenate(map(atleast_2d,tup),0) + +def hstack(tup): + """ + Stack arrays in sequence horizontally (column wise). + + Take a sequence of arrays and stack them horizontally to make + a single array. Rebuild arrays divided by `hsplit`. + + Parameters + ---------- + tup : sequence of ndarrays + All arrays must have the same shape along all but the second axis. + + Returns + ------- + stacked : ndarray + The array formed by stacking the given arrays. + + See Also + -------- + vstack : Stack arrays in sequence vertically (row wise). + dstack : Stack arrays in sequence depth wise (along third axis). + concatenate : Join a sequence of arrays together. + hsplit : Split array along second axis. + + Notes + ----- + Equivalent to ``np.concatenate(tup, axis=1)`` + + Examples + -------- + >>> a = np.array((1,2,3)) + >>> b = np.array((2,3,4)) + >>> np.hstack((a,b)) + array([1, 2, 3, 2, 3, 4]) + >>> a = np.array([[1],[2],[3]]) + >>> b = np.array([[2],[3],[4]]) + >>> np.hstack((a,b)) + array([[1, 2], + [2, 3], + [3, 4]]) + + """ + arrs = map(atleast_1d,tup) + # As a special case, dimension 0 of 1-dimensional arrays is "horizontal" + if arrs[0].ndim == 1: + return _nx.concatenate(arrs, 0) + else: + return _nx.concatenate(arrs, 1) diff --git a/lib_pypy/numpypy/core/umath.py b/lib_pypy/numpypy/core/umath.py new file mode 100644 --- /dev/null +++ b/lib_pypy/numpypy/core/umath.py @@ -0,0 +1,12 @@ +from _numpypy.umath import * + +import math +e = math.e +pi = math.pi +del math + +PZERO = 0.0 +NZERO = -0.0 +PINF = float('inf') +NINF = float('-inf') +NAN = float('nan') diff --git a/lib_pypy/numpypy/lib/__init__.py b/lib_pypy/numpypy/lib/__init__.py new file mode 100644 --- /dev/null +++ b/lib_pypy/numpypy/lib/__init__.py @@ -0,0 +1,11 @@ +import function_base +from function_base import * +import shape_base +from shape_base import * +import twodim_base +from twodim_base import * + +__all__ = [] +__all__ += function_base.__all__ +__all__ += shape_base.__all__ +__all__ += twodim_base.__all__ diff --git a/lib_pypy/numpypy/lib/function_base.py b/lib_pypy/numpypy/lib/function_base.py new file mode 100644 --- /dev/null +++ b/lib_pypy/numpypy/lib/function_base.py @@ -0,0 +1,10 @@ +__all__ = ['average'] + +from ..core.numeric import array + +def average(a): + # This implements a weighted average, for now we don't implement the + # weighting, just the average part! + if not hasattr(a, "mean"): + a = array(a) + return a.mean() diff --git a/lib_pypy/numpypy/lib/shape_base.py b/lib_pypy/numpypy/lib/shape_base.py new file mode 100644 --- /dev/null +++ b/lib_pypy/numpypy/lib/shape_base.py @@ -0,0 +1,54 @@ +__all__ = ['dstack'] + +from ..core import numeric as _nx +from ..core import atleast_3d + +def dstack(tup): + """ + Stack arrays in sequence depth wise (along third axis). + + Takes a sequence of arrays and stack them along the third axis + to make a single array. Rebuilds arrays divided by `dsplit`. + This is a simple way to stack 2D arrays (images) into a single + 3D array for processing. + + Parameters + ---------- + tup : sequence of arrays + Arrays to stack. All of them must have the same shape along all + but the third axis. + + Returns + ------- + stacked : ndarray + The array formed by stacking the given arrays. + + See Also + -------- From noreply at buildbot.pypy.org Wed Feb 27 19:48:25 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Wed, 27 Feb 2013 19:48:25 +0100 (CET) Subject: [pypy-commit] pypy default: apply patch for netbsd support from yamamoto@valinux.co.jp Message-ID: <20130227184825.934B21C088E@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61859:06373bfca341 Date: 2013-02-27 13:44 -0500 http://bitbucket.org/pypy/pypy/changeset/06373bfca341/ Log: apply patch for netbsd support from yamamoto at valinux.co.jp diff --git a/rpython/rlib/rdynload.py b/rpython/rlib/rdynload.py --- a/rpython/rlib/rdynload.py +++ b/rpython/rlib/rdynload.py @@ -15,6 +15,7 @@ _WIN32 = _MSVC or _MINGW _MAC_OS = platform.name == "darwin" _FREEBSD = sys.platform.startswith("freebsd") +_NETBSD = sys.platform.startswith("netbsd") if _WIN32: from rpython.rlib import rwin32 @@ -27,7 +28,7 @@ else: pre_include_bits = [] -if _FREEBSD or _WIN32: +if _FREEBSD or _NETBSD or _WIN32: libraries = [] else: libraries = ['dl'] diff --git a/rpython/rtyper/module/ll_os.py b/rpython/rtyper/module/ll_os.py --- a/rpython/rtyper/module/ll_os.py +++ b/rpython/rtyper/module/ll_os.py @@ -224,9 +224,10 @@ decls = [] defs = [] for name in self.w_star: - data = {'ret_type': 'int', 'name': name} - decls.append((decl_snippet % data).strip()) - defs.append((def_snippet % data).strip()) + if hasattr(os, name): + data = {'ret_type': 'int', 'name': name} + decls.append((decl_snippet % data).strip()) + defs.append((def_snippet % data).strip()) self.compilation_info = self.compilation_info.merge( ExternalCompilationInfo( diff --git a/rpython/rtyper/module/ll_time.py b/rpython/rtyper/module/ll_time.py --- a/rpython/rtyper/module/ll_time.py +++ b/rpython/rtyper/module/ll_time.py @@ -41,7 +41,7 @@ RUSAGE = platform.Struct('struct rusage', [('ru_utime', TIMEVAL), ('ru_stime', TIMEVAL)]) -if sys.platform.startswith('freebsd'): +if sys.platform.startswith('freebsd') or sys.platform.startswith('netbsd'): libraries = ['compat'] else: libraries = [] diff --git a/rpython/translator/platform/__init__.py b/rpython/translator/platform/__init__.py --- a/rpython/translator/platform/__init__.py +++ b/rpython/translator/platform/__init__.py @@ -286,6 +286,13 @@ host_factory = Freebsd else: host_factory = Freebsd_64 +elif sys.platform.startswith('netbsd'): + from rpython.translator.platform.netbsd import Netbsd, Netbsd_64 + import platform + if platform.architecture()[0] == '32bit': + host_factory = Netbsd + else: + host_factory = Netbsd_64 elif "openbsd" in sys.platform: from rpython.translator.platform.openbsd import OpenBSD, OpenBSD_64 import platform diff --git a/rpython/translator/platform/netbsd.py b/rpython/translator/platform/netbsd.py new file mode 100644 --- /dev/null +++ b/rpython/translator/platform/netbsd.py @@ -0,0 +1,55 @@ +"""Support for NetBSD.""" + +import os + +from rpython.translator.platform import posix + +def get_env(key, default): + if key in os.environ: + return os.environ[key] + else: + return default + +def get_env_vector(key, default): + string = get_env(key, default) + # XXX: handle quotes + return string.split() + +class Netbsd(posix.BasePosix): + name = "netbsd" + + link_flags = ['-pthread'] + get_env_vector('LDFLAGS', '') + cflags = ['-O3', '-pthread', '-fomit-frame-pointer' + ] + get_env_vector('CFLAGS', '') + standalone_only = [] + shared_only = [] + so_ext = 'so' + make_cmd = 'gmake' + extra_libs = ('-lrt',) + + def __init__(self, cc=None): + if cc is None: + cc = get_env("CC", "gcc") + super(Netbsd, self).__init__(cc) + + def _args_for_shared(self, args): + return ['-shared'] + args + + def _preprocess_include_dirs(self, include_dirs): + res_incl_dirs = list(include_dirs) + res_incl_dirs.append(os.path.join(get_env("LOCALBASE", "/usr/pkg"), "include")) + return res_incl_dirs + + def _preprocess_library_dirs(self, library_dirs): + res_lib_dirs = list(library_dirs) + res_lib_dirs.append(os.path.join(get_env("LOCALBASE", "/usr/pkg"), "lib")) + return res_lib_dirs + + def _include_dirs_for_libffi(self): + return [os.path.join(get_env("LOCALBASE", "/usr/pkg"), "include")] + + def _library_dirs_for_libffi(self): + return [os.path.join(get_env("LOCALBASE", "/usr/pkg"), "lib")] + +class Netbsd_64(Netbsd): + shared_only = ('-fPIC',) From noreply at buildbot.pypy.org Wed Feb 27 19:54:46 2013 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 27 Feb 2013 19:54:46 +0100 (CET) Subject: [pypy-commit] pypy default: Complain loudly if we attempt to mutate an lltype which has a cached Message-ID: <20130227185446.C4BE41C088E@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r61860:62b9efd10322 Date: 2013-02-26 14:48 +0100 http://bitbucket.org/pypy/pypy/changeset/62b9efd10322/ Log: Complain loudly if we attempt to mutate an lltype which has a cached hash already. diff --git a/rpython/rtyper/lltypesystem/lltype.py b/rpython/rtyper/lltypesystem/lltype.py --- a/rpython/rtyper/lltypesystem/lltype.py +++ b/rpython/rtyper/lltypesystem/lltype.py @@ -105,6 +105,23 @@ _is_compatible = __eq__ + def __setattr__(self, attr, nvalue): + try: + LowLevelType.__cached_hash.__get__(self) + except AttributeError: + pass + else: + try: + reprself = repr(self) + except: + try: + reprself = str(self) + except: + reprself = object.__repr__(self) + raise AssertionError("%s: changing the field %r but we already " + "computed the hash" % (reprself, attr)) + object.__setattr__(self, attr, nvalue) + def _enforce(self, value): if typeOf(value) != self: raise TypeError @@ -486,6 +503,10 @@ return obj def __init__(self, OF, length, **kwds): + if hasattr(self, '_name'): + assert self.OF == OF + assert self.length == length + return fields = [('item%d' % i, OF) for i in range(length)] super(FixedSizeArray, self).__init__('array%d' % length, *fields, **kwds) From noreply at buildbot.pypy.org Wed Feb 27 19:54:48 2013 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 27 Feb 2013 19:54:48 +0100 (CET) Subject: [pypy-commit] pypy kill-flowobjspace: Close branch ready for merging Message-ID: <20130227185448.0050C1C088E@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: kill-flowobjspace Changeset: r61861:01aad6bad767 Date: 2013-02-27 19:52 +0100 http://bitbucket.org/pypy/pypy/changeset/01aad6bad767/ Log: Close branch ready for merging From noreply at buildbot.pypy.org Wed Feb 27 19:54:49 2013 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 27 Feb 2013 19:54:49 +0100 (CET) Subject: [pypy-commit] pypy default: Merge kill-flowobjspace (ronan): Message-ID: <20130227185449.58E4C1C088E@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r61862:a5e13eb34945 Date: 2013-02-27 19:53 +0100 http://bitbucket.org/pypy/pypy/changeset/a5e13eb34945/ Log: Merge kill-flowobjspace (ronan): This is a basically just a bunch of random cleanups. Despite the name, it doesn't kill FlowObjSpace, but it does hide it from public view. Highlights: replaces FlowObjSpace().build_flow(func) with just build_flow(func) cleans up the ArgumentsForTranslation mess in flowspace moves ArgumentsForTranslation to rpython.annotator, since it's not used in flowspace any more diff too long, truncating to 2000 out of 2365 lines diff --git a/rpython/flowspace/argument.py b/rpython/annotator/argument.py copy from rpython/flowspace/argument.py copy to rpython/annotator/argument.py --- a/rpython/flowspace/argument.py +++ b/rpython/annotator/argument.py @@ -1,84 +1,45 @@ """ Arguments objects. """ +from rpython.annotator.model import SomeTuple, SomeObject +# for parsing call arguments +class RPythonCallsSpace(object): + """Pseudo Object Space providing almost no real operation. + For the Arguments class: if it really needs other operations, it means + that the call pattern is too complex for R-Python. + """ + def newtuple(self, items_s): + if len(items_s) == 1 and items_s[0] is Ellipsis: + res = SomeObject() # hack to get a SomeObject as the *arg + res.from_ellipsis = True + return res + else: + return SomeTuple(items_s) -class Signature(object): - _immutable_ = True - _immutable_fields_ = ["argnames[*]"] - __slots__ = ("argnames", "varargname", "kwargname") + def unpackiterable(self, s_obj, expected_length=None): + if isinstance(s_obj, SomeTuple): + return list(s_obj.items) + if (s_obj.__class__ is SomeObject and + getattr(s_obj, 'from_ellipsis', False)): # see newtuple() + return [Ellipsis] + raise CallPatternTooComplex("'*' argument must be SomeTuple") - def __init__(self, argnames, varargname=None, kwargname=None): - self.argnames = argnames - self.varargname = varargname - self.kwargname = kwargname + def is_true(self, s_tup): + assert isinstance(s_tup, SomeTuple) + return bool(s_tup.items) - def find_argname(self, name): - try: - return self.argnames.index(name) - except ValueError: - return -1 - def num_argnames(self): - return len(self.argnames) - - def has_vararg(self): - return self.varargname is not None - - def has_kwarg(self): - return self.kwargname is not None - - def scope_length(self): - scopelen = len(self.argnames) - scopelen += self.has_vararg() - scopelen += self.has_kwarg() - return scopelen - - def getallvarnames(self): - argnames = self.argnames - if self.varargname is not None: - argnames = argnames + [self.varargname] - if self.kwargname is not None: - argnames = argnames + [self.kwargname] - return argnames - - def __repr__(self): - return "Signature(%r, %r, %r)" % ( - self.argnames, self.varargname, self.kwargname) - - def __eq__(self, other): - if not isinstance(other, Signature): - return NotImplemented - return (self.argnames == other.argnames and - self.varargname == other.varargname and - self.kwargname == other.kwargname) - - def __ne__(self, other): - if not isinstance(other, Signature): - return NotImplemented - return not self == other - - # make it look tuply for its use in the annotator - - def __len__(self): - return 3 - - def __getitem__(self, i): - if i == 0: - return self.argnames - if i == 1: - return self.varargname - if i == 2: - return self.kwargname - raise IndexError +class CallPatternTooComplex(Exception): + pass class ArgumentsForTranslation(object): + w_starstararg = None def __init__(self, space, args_w, keywords=None, keywords_w=None, w_stararg=None, w_starstararg=None): self.w_stararg = w_stararg - self.w_starstararg = w_starstararg - self.combine_has_happened = False + assert w_starstararg is None self.space = space assert isinstance(args_w, list) self.arguments_w = args_w @@ -95,53 +56,13 @@ return '%s(%s, %s, %s)' % (name, self.arguments_w, self.keywords, self.keywords_w) - def _combine_wrapped(self, w_stararg, w_starstararg): - "unpack the *arg and **kwd into arguments_w and keywords_w" - if w_stararg is not None: - self._combine_starargs_wrapped(w_stararg) - if w_starstararg is not None: - self._combine_starstarargs_wrapped(w_starstararg) - - def _combine_starargs_wrapped(self, w_stararg): - # unpack the * arguments - space = self.space - args_w = space.unpackiterable(w_stararg) - self.arguments_w = self.arguments_w + args_w - - def _combine_starstarargs_wrapped(self, w_starstararg): - # unpack the ** arguments - space = self.space - keywords, values_w = space.view_as_kwargs(w_starstararg) - if keywords is not None: # this path also taken for empty dicts - if self.keywords is None: - self.keywords = keywords - self.keywords_w = values_w - else: - if set(keywords) & set(self.keywords): - raise TypeError("got multiple values for keyword arguments '%s'", set(keywords) & set(self.keywords)) - self.keywords = self.keywords + keywords - self.keywords_w = self.keywords_w + values_w - return - if space.isinstance_w(w_starstararg, space.w_dict): - keys_w = space.unpackiterable(w_starstararg) + @property + def positional_args(self): + if self.w_stararg is not None: + args_w = self.space.unpackiterable(self.w_stararg) + return self.arguments_w + args_w else: - w_keys = space.call_method(w_starstararg, "keys") - keys_w = space.unpackiterable(w_keys) - keywords_w = [None] * len(keys_w) - keywords = [None] * len(keys_w) - for i, w_key in enumerate(keys_w): - key = space.str_w(w_key) - if key in self.keywords: - raise TypeError("got multiple values for keyword argument '%s'" % key) - keywords[i] = key - keywords_w[i] = space.getitem(w_starstararg, w_key) - self.keyword_names_w = keys_w - if self.keywords is None: - self.keywords = keywords - self.keywords_w = keywords_w - else: - self.keywords = self.keywords + keywords - self.keywords_w = self.keywords_w + keywords_w + return self.arguments_w def fixedunpack(self, argcount): """The simplest argument parsing: get the 'argcount' arguments, @@ -154,12 +75,6 @@ raise ValueError("not enough arguments (%d expected)" % argcount) return self.arguments_w - def combine_if_necessary(self): - if self.combine_has_happened: - return - self._combine_wrapped(self.w_stararg, self.w_starstararg) - self.combine_has_happened = True - def prepend(self, w_firstarg): # used often "Return a new Arguments with a new argument inserted first." return ArgumentsForTranslation(self.space, [w_firstarg] + self.arguments_w, @@ -178,10 +93,9 @@ # args_w = list of the normal actual parameters, wrapped # scope_w = resulting list of wrapped values # - self.combine_if_necessary() co_argcount = signature.num_argnames() # expected formal arguments, without */** - args_w = self.arguments_w + args_w = self.positional_args num_args = len(args_w) keywords = self.keywords or [] num_kwds = len(keywords) @@ -263,12 +177,8 @@ def unpack(self): "Return a ([w1,w2...], {'kw':w3...}) pair." - self.combine_if_necessary() - kwds_w = {} - if self.keywords: - for i in range(len(self.keywords)): - kwds_w[self.keywords[i]] = self.keywords_w[i] - return self.arguments_w, kwds_w + kwds_w = dict(zip(self.keywords, self.keywords_w)) if self.keywords else {} + return self.positional_args, kwds_w def match_signature(self, signature, defaults_w): """Parse args and kwargs according to the signature of a code object, @@ -281,11 +191,11 @@ def unmatch_signature(self, signature, data_w): """kind of inverse of match_signature""" - args_w, kwds_w = self.unpack() - need_cnt = len(args_w) - need_kwds = kwds_w.keys() + need_cnt = len(self.positional_args) + need_kwds = self.keywords or [] space = self.space argnames, varargname, kwargname = signature + assert kwargname is None cnt = len(argnames) data_args_w = data_w[:cnt] if varargname: @@ -293,31 +203,17 @@ cnt += 1 else: data_w_stararg = space.newtuple([]) + assert len(data_w) == cnt unfiltered_kwds_w = {} - if kwargname: - data_w_starargarg = data_w[cnt] - for w_key in space.unpackiterable(data_w_starargarg): - key = space.str_w(w_key) - w_value = space.getitem(data_w_starargarg, w_key) - unfiltered_kwds_w[key] = w_value - cnt += 1 - assert len(data_w) == cnt - - ndata_args_w = len(data_args_w) - if ndata_args_w >= need_cnt: + if len(data_args_w) >= need_cnt: args_w = data_args_w[:need_cnt] for argname, w_arg in zip(argnames[need_cnt:], data_args_w[need_cnt:]): unfiltered_kwds_w[argname] = w_arg assert not space.is_true(data_w_stararg) else: stararg_w = space.unpackiterable(data_w_stararg) - datalen = len(data_args_w) - args_w = [None] * (datalen + len(stararg_w)) - for i in range(0, datalen): - args_w[i] = data_args_w[i] - for i in range(0, len(stararg_w)): - args_w[i + datalen] = stararg_w[i] + args_w = data_args_w + stararg_w assert len(args_w) == need_cnt keywords = [] @@ -358,8 +254,7 @@ return (shape_cnt, shape_keys, shape_star, shape_stst), data_w def _rawshape(self, nextra=0): - assert not self.combine_has_happened - shape_cnt = len(self.arguments_w) + nextra # Number of positional args + shape_cnt = len(self.arguments_w) + nextra # Number of positional args if self.keywords: shape_keys = self.keywords[:] # List of keywords (strings) shape_keys.sort() diff --git a/rpython/annotator/bookkeeper.py b/rpython/annotator/bookkeeper.py --- a/rpython/annotator/bookkeeper.py +++ b/rpython/annotator/bookkeeper.py @@ -19,7 +19,7 @@ from rpython.annotator.dictdef import DictDef from rpython.annotator import description from rpython.annotator.signature import annotationoftype -from rpython.flowspace.argument import ArgumentsForTranslation +from rpython.annotator.argument import ArgumentsForTranslation, RPythonCallsSpace from rpython.rlib.objectmodel import r_dict, Symbolic from rpython.tool.algo.unionfind import UnionFind from rpython.rtyper.lltypesystem import lltype, llmemory @@ -734,51 +734,6 @@ return False else: return True - -# for parsing call arguments -class RPythonCallsSpace(object): - """Pseudo Object Space providing almost no real operation. - For the Arguments class: if it really needs other operations, it means - that the call pattern is too complex for R-Python. - """ - w_tuple = SomeTuple - def newtuple(self, items_s): - if len(items_s) == 1 and items_s[0] is Ellipsis: - res = SomeObject() # hack to get a SomeObject as the *arg - res.from_ellipsis = True - return res - else: - return SomeTuple(items_s) - - def newdict(self): - raise CallPatternTooComplex, "'**' argument" - - def unpackiterable(self, s_obj, expected_length=None): - if isinstance(s_obj, SomeTuple): - if (expected_length is not None and - expected_length != len(s_obj.items)): - raise ValueError - return list(s_obj.items) - if (s_obj.__class__ is SomeObject and - getattr(s_obj, 'from_ellipsis', False)): # see newtuple() - return [Ellipsis] - raise CallPatternTooComplex, "'*' argument must be SomeTuple" - fixedview = unpackiterable - listview = unpackiterable - - def is_w(self, one, other): - return one is other - - def type(self, item): - return type(item) - - def is_true(self, s_tup): - assert isinstance(s_tup, SomeTuple) - return bool(s_tup.items) - -class CallPatternTooComplex(Exception): - pass - # get current bookkeeper def getbookkeeper(): diff --git a/rpython/annotator/description.py b/rpython/annotator/description.py --- a/rpython/annotator/description.py +++ b/rpython/annotator/description.py @@ -3,7 +3,7 @@ from rpython.annotator.signature import enforce_signature_args, enforce_signature_return from rpython.flowspace.model import Constant, FunctionGraph from rpython.flowspace.bytecode import cpython_code_signature -from rpython.flowspace.argument import rawshape, ArgErr +from rpython.annotator.argument import rawshape, ArgErr from rpython.tool.sourcetools import valid_identifier, func_with_new_name from rpython.tool.pairtype import extendabletype diff --git a/rpython/annotator/test/test_annrpython.py b/rpython/annotator/test/test_annrpython.py --- a/rpython/annotator/test/test_annrpython.py +++ b/rpython/annotator/test/test_annrpython.py @@ -13,7 +13,7 @@ from rpython.rlib.rarithmetic import r_uint, base_int, r_longlong, r_ulonglong from rpython.rlib.rarithmetic import r_singlefloat from rpython.rlib import objectmodel -from rpython.flowspace.objspace import FlowObjSpace, FlowingError +from rpython.flowspace.objspace import build_flow, FlowingError from rpython.translator.test import snippet @@ -40,9 +40,6 @@ class TestAnnotateTestCase: - def setup_class(cls): - cls.space = FlowObjSpace() - def teardown_method(self, meth): assert annmodel.s_Bool == annmodel.SomeBool() @@ -60,7 +57,7 @@ except AttributeError: pass name = func.func_name - funcgraph = self.space.build_flow(func) + funcgraph = build_flow(func) funcgraph.source = inspect.getsource(func) return funcgraph @@ -775,7 +772,7 @@ assert isinstance(s, annmodel.SomePBC) assert s.const == myobj - def test_cleanup_protocol(self): + def test_cleanup_protocol(self): class Stuff: def __init__(self): self.called = False @@ -3754,7 +3751,7 @@ def test_join_none_and_nonnull(self): from rpython.rlib.rstring import assert_str0 - + def f(i): a = str(i) a = assert_str0(a) @@ -3798,7 +3795,7 @@ class A(object): def __iter__(self): return self - + def fn(): return iter(A()) @@ -3857,7 +3854,7 @@ return True x = X() - + def f(i): if i: x1 = x diff --git a/rpython/annotator/test/test_argument.py b/rpython/annotator/test/test_argument.py new file mode 100644 --- /dev/null +++ b/rpython/annotator/test/test_argument.py @@ -0,0 +1,171 @@ +# -*- coding: utf-8 -*- +import py +from rpython.annotator.argument import ArgumentsForTranslation, rawshape +from rpython.flowspace.argument import Signature + +class DummySpace(object): + def newtuple(self, items): + return tuple(items) + + def is_true(self, obj): + return bool(obj) + + def unpackiterable(self, it): + return list(it) + + +def make_arguments_for_translation(space, args_w, keywords_w={}, + w_stararg=None, w_starstararg=None): + return ArgumentsForTranslation(space, args_w, keywords_w.keys(), + keywords_w.values(), w_stararg, + w_starstararg) + +class TestArgumentsForTranslation(object): + + def test_prepend(self): + space = DummySpace() + args = ArgumentsForTranslation(space, ["0"]) + args1 = args.prepend("thingy") + assert args1 is not args + assert args1.arguments_w == ["thingy", "0"] + assert args1.keywords is args.keywords + assert args1.keywords_w is args.keywords_w + + def test_fixedunpacked(self): + space = DummySpace() + + args = ArgumentsForTranslation(space, [], ["k"], [1]) + py.test.raises(ValueError, args.fixedunpack, 1) + + args = ArgumentsForTranslation(space, ["a", "b"]) + py.test.raises(ValueError, args.fixedunpack, 0) + py.test.raises(ValueError, args.fixedunpack, 1) + py.test.raises(ValueError, args.fixedunpack, 3) + py.test.raises(ValueError, args.fixedunpack, 4) + + assert args.fixedunpack(2) == ['a', 'b'] + + def test_unmatch_signature(self): + space = DummySpace() + args = make_arguments_for_translation(space, [1,2,3]) + sig = Signature(['a', 'b', 'c'], None, None) + data = args.match_signature(sig, []) + new_args = args.unmatch_signature(sig, data) + assert args.unpack() == new_args.unpack() + + args = make_arguments_for_translation(space, [1]) + sig = Signature(['a', 'b', 'c'], None, None) + data = args.match_signature(sig, [2, 3]) + new_args = args.unmatch_signature(sig, data) + assert args.unpack() == new_args.unpack() + + args = make_arguments_for_translation(space, [1,2,3,4,5]) + sig = Signature(['a', 'b', 'c'], 'r', None) + data = args.match_signature(sig, []) + new_args = args.unmatch_signature(sig, data) + assert args.unpack() == new_args.unpack() + + args = make_arguments_for_translation(space, [1], {'c': 3, 'b': 2}) + sig = Signature(['a', 'b', 'c'], None, None) + data = args.match_signature(sig, []) + new_args = args.unmatch_signature(sig, data) + assert args.unpack() == new_args.unpack() + + args = make_arguments_for_translation(space, [1], {'c': 5}) + sig = Signature(['a', 'b', 'c'], None, None) + data = args.match_signature(sig, [2, 3]) + new_args = args.unmatch_signature(sig, data) + assert args.unpack() == new_args.unpack() + + args = make_arguments_for_translation(space, [1], {'c': 5, 'd': 7}) + sig = Signature(['a', 'b', 'c'], None, 'kw') + py.test.raises(TypeError, args.match_signature, sig, [2, 3]) + + def test_rawshape(self): + space = DummySpace() + args = make_arguments_for_translation(space, [1,2,3]) + assert rawshape(args) == (3, (), False, False) + + args = make_arguments_for_translation(space, [1]) + assert rawshape(args, 2) == (3, (), False, False) + + args = make_arguments_for_translation(space, [1,2,3,4,5]) + assert rawshape(args) == (5, (), False, False) + + args = make_arguments_for_translation(space, [1], {'c': 3, 'b': 2}) + assert rawshape(args) == (1, ('b', 'c'), False, False) + + args = make_arguments_for_translation(space, [1], {'c': 5}) + assert rawshape(args) == (1, ('c', ), False, False) + + args = make_arguments_for_translation(space, [1], {'c': 5, 'd': 7}) + assert rawshape(args) == (1, ('c', 'd'), False, False) + + args = make_arguments_for_translation(space, [1,2,3,4,5], {'e': 5, 'd': 7}) + assert rawshape(args) == (5, ('d', 'e'), False, False) + + + def test_flatten(self): + space = DummySpace() + args = make_arguments_for_translation(space, [1,2,3]) + assert args.flatten() == ((3, (), False, False), [1, 2, 3]) + + args = make_arguments_for_translation(space, [1]) + assert args.flatten() == ((1, (), False, False), [1]) + + args = make_arguments_for_translation(space, [1,2,3,4,5]) + assert args.flatten() == ((5, (), False, False), [1,2,3,4,5]) + + args = make_arguments_for_translation(space, [1], {'c': 3, 'b': 2}) + assert args.flatten() == ((1, ('b', 'c'), False, False), [1, 2, 3]) + + args = make_arguments_for_translation(space, [1], {'c': 5}) + assert args.flatten() == ((1, ('c', ), False, False), [1, 5]) + + args = make_arguments_for_translation(space, [1], {'c': 5, 'd': 7}) + assert args.flatten() == ((1, ('c', 'd'), False, False), [1, 5, 7]) + + args = make_arguments_for_translation(space, [1,2,3,4,5], {'e': 5, 'd': 7}) + assert args.flatten() == ((5, ('d', 'e'), False, False), [1, 2, 3, 4, 5, 7, 5]) + + def test_stararg_flowspace_variable(self): + space = DummySpace() + var = object() + shape = ((2, ('g', ), True, False), [1, 2, 9, var]) + args = make_arguments_for_translation(space, [1,2], {'g': 9}, + w_stararg=var) + assert args.flatten() == shape + + args = ArgumentsForTranslation.fromshape(space, *shape) + assert args.flatten() == shape + + + def test_fromshape(self): + space = DummySpace() + shape = ((3, (), False, False), [1, 2, 3]) + args = ArgumentsForTranslation.fromshape(space, *shape) + assert args.flatten() == shape + + shape = ((1, (), False, False), [1]) + args = ArgumentsForTranslation.fromshape(space, *shape) + assert args.flatten() == shape + + shape = ((5, (), False, False), [1,2,3,4,5]) + args = ArgumentsForTranslation.fromshape(space, *shape) + assert args.flatten() == shape + + shape = ((1, ('b', 'c'), False, False), [1, 2, 3]) + args = ArgumentsForTranslation.fromshape(space, *shape) + assert args.flatten() == shape + + shape = ((1, ('c', ), False, False), [1, 5]) + args = ArgumentsForTranslation.fromshape(space, *shape) + assert args.flatten() == shape + + shape = ((1, ('c', 'd'), False, False), [1, 5, 7]) + args = ArgumentsForTranslation.fromshape(space, *shape) + assert args.flatten() == shape + + shape = ((5, ('d', 'e'), False, False), [1, 2, 3, 4, 5, 7, 5]) + args = ArgumentsForTranslation.fromshape(space, *shape) + assert args.flatten() == shape diff --git a/rpython/flowspace/argument.py b/rpython/flowspace/argument.py --- a/rpython/flowspace/argument.py +++ b/rpython/flowspace/argument.py @@ -73,409 +73,25 @@ raise IndexError -class ArgumentsForTranslation(object): - def __init__(self, space, args_w, keywords=None, keywords_w=None, - w_stararg=None, w_starstararg=None): +class CallSpec(object): + """Represents the arguments passed into a function call, i.e. the + `a, b, *c, **d` part in `return func(a, b, *c, **d)`. + """ + def __init__(self, args_w, keywords=None, w_stararg=None, + w_starstararg=None): self.w_stararg = w_stararg - self.w_starstararg = w_starstararg - self.combine_has_happened = False - self.space = space + assert w_starstararg is None, "No **-unpacking in RPython" assert isinstance(args_w, list) self.arguments_w = args_w - self.keywords = keywords - self.keywords_w = keywords_w - self.keyword_names_w = None - - def __repr__(self): - """ NOT_RPYTHON """ - name = self.__class__.__name__ - if not self.keywords: - return '%s(%s)' % (name, self.arguments_w,) - else: - return '%s(%s, %s, %s)' % (name, self.arguments_w, - self.keywords, self.keywords_w) - - def _combine_wrapped(self, w_stararg, w_starstararg): - "unpack the *arg and **kwd into arguments_w and keywords_w" - if w_stararg is not None: - self._combine_starargs_wrapped(w_stararg) - if w_starstararg is not None: - self._combine_starstarargs_wrapped(w_starstararg) - - def _combine_starargs_wrapped(self, w_stararg): - # unpack the * arguments - space = self.space - args_w = space.unpackiterable(w_stararg) - self.arguments_w = self.arguments_w + args_w - - def _combine_starstarargs_wrapped(self, w_starstararg): - # unpack the ** arguments - space = self.space - keywords, values_w = space.view_as_kwargs(w_starstararg) - if keywords is not None: # this path also taken for empty dicts - if self.keywords is None: - self.keywords = keywords - self.keywords_w = values_w - else: - if set(keywords) & set(self.keywords): - raise TypeError("got multiple values for keyword arguments '%s'", set(keywords) & set(self.keywords)) - self.keywords = self.keywords + keywords - self.keywords_w = self.keywords_w + values_w - return - if space.isinstance_w(w_starstararg, space.w_dict): - keys_w = space.unpackiterable(w_starstararg) - else: - w_keys = space.call_method(w_starstararg, "keys") - keys_w = space.unpackiterable(w_keys) - keywords_w = [None] * len(keys_w) - keywords = [None] * len(keys_w) - for i, w_key in enumerate(keys_w): - key = space.str_w(w_key) - if key in self.keywords: - raise TypeError("got multiple values for keyword argument '%s'" % key) - keywords[i] = key - keywords_w[i] = space.getitem(w_starstararg, w_key) - self.keyword_names_w = keys_w - if self.keywords is None: - self.keywords = keywords - self.keywords_w = keywords_w - else: - self.keywords = self.keywords + keywords - self.keywords_w = self.keywords_w + keywords_w - - def fixedunpack(self, argcount): - """The simplest argument parsing: get the 'argcount' arguments, - or raise a real ValueError if the length is wrong.""" - if self.keywords: - raise ValueError("no keyword arguments expected") - if len(self.arguments_w) > argcount: - raise ValueError("too many arguments (%d expected)" % argcount) - elif len(self.arguments_w) < argcount: - raise ValueError("not enough arguments (%d expected)" % argcount) - return self.arguments_w - - def combine_if_necessary(self): - if self.combine_has_happened: - return - self._combine_wrapped(self.w_stararg, self.w_starstararg) - self.combine_has_happened = True - - def prepend(self, w_firstarg): # used often - "Return a new Arguments with a new argument inserted first." - return ArgumentsForTranslation(self.space, [w_firstarg] + self.arguments_w, - self.keywords, self.keywords_w, self.w_stararg, - self.w_starstararg) - - def copy(self): - return ArgumentsForTranslation(self.space, self.arguments_w, - self.keywords, self.keywords_w, self.w_stararg, - self.w_starstararg) - - def _match_signature(self, scope_w, signature, defaults_w=None): - """Parse args and kwargs according to the signature of a code object, - or raise an ArgErr in case of failure. - """ - # args_w = list of the normal actual parameters, wrapped - # scope_w = resulting list of wrapped values - # - self.combine_if_necessary() - co_argcount = signature.num_argnames() # expected formal arguments, without */** - - args_w = self.arguments_w - num_args = len(args_w) - keywords = self.keywords or [] - num_kwds = len(keywords) - - # put as many positional input arguments into place as available - take = min(num_args, co_argcount) - scope_w[:take] = args_w[:take] - input_argcount = take - - # collect extra positional arguments into the *vararg - if signature.has_vararg(): - if num_args > co_argcount: - starargs_w = args_w[co_argcount:] - else: - starargs_w = [] - scope_w[co_argcount] = self.space.newtuple(starargs_w) - elif num_args > co_argcount: - raise ArgErrCount(num_args, num_kwds, signature, defaults_w, 0) - - # if a **kwargs argument is needed, explode - if signature.has_kwarg(): - raise TypeError("Keyword arguments as **kwargs is not supported by RPython") - - # handle keyword arguments - num_remainingkwds = 0 - keywords_w = self.keywords_w - kwds_mapping = None - if num_kwds: - # kwds_mapping maps target indexes in the scope (minus input_argcount) - # to positions in the keywords_w list - kwds_mapping = [-1] * (co_argcount - input_argcount) - # match the keywords given at the call site to the argument names - # the called function takes - # this function must not take a scope_w, to make the scope not - # escape - num_remainingkwds = len(keywords) - for i, name in enumerate(keywords): - # If name was not encoded as a string, it could be None. In that - # case, it's definitely not going to be in the signature. - if name is None: - continue - j = signature.find_argname(name) - # if j == -1 nothing happens - if j < input_argcount: - # check that no keyword argument conflicts with these. - if j >= 0: - raise ArgErrMultipleValues(name) - else: - kwds_mapping[j - input_argcount] = i # map to the right index - num_remainingkwds -= 1 - - if num_remainingkwds: - if co_argcount == 0: - raise ArgErrCount(num_args, num_kwds, signature, defaults_w, 0) - raise ArgErrUnknownKwds(self.space, num_remainingkwds, keywords, - kwds_mapping, self.keyword_names_w) - - # check for missing arguments and fill them from the kwds, - # or with defaults, if available - missing = 0 - if input_argcount < co_argcount: - def_first = co_argcount - (0 if defaults_w is None else len(defaults_w)) - j = 0 - kwds_index = -1 - for i in range(input_argcount, co_argcount): - if kwds_mapping is not None: - kwds_index = kwds_mapping[j] - j += 1 - if kwds_index >= 0: - scope_w[i] = keywords_w[kwds_index] - continue - defnum = i - def_first - if defnum >= 0: - scope_w[i] = defaults_w[defnum] - else: - missing += 1 - if missing: - raise ArgErrCount(num_args, num_kwds, signature, defaults_w, missing) - - def unpack(self): - "Return a ([w1,w2...], {'kw':w3...}) pair." - self.combine_if_necessary() - kwds_w = {} - if self.keywords: - for i in range(len(self.keywords)): - kwds_w[self.keywords[i]] = self.keywords_w[i] - return self.arguments_w, kwds_w - - def match_signature(self, signature, defaults_w): - """Parse args and kwargs according to the signature of a code object, - or raise an ArgErr in case of failure. - """ - scopelen = signature.scope_length() - scope_w = [None] * scopelen - self._match_signature(scope_w, signature, defaults_w) - return scope_w - - def unmatch_signature(self, signature, data_w): - """kind of inverse of match_signature""" - args_w, kwds_w = self.unpack() - need_cnt = len(args_w) - need_kwds = kwds_w.keys() - space = self.space - argnames, varargname, kwargname = signature - cnt = len(argnames) - data_args_w = data_w[:cnt] - if varargname: - data_w_stararg = data_w[cnt] - cnt += 1 - else: - data_w_stararg = space.newtuple([]) - - unfiltered_kwds_w = {} - if kwargname: - data_w_starargarg = data_w[cnt] - for w_key in space.unpackiterable(data_w_starargarg): - key = space.str_w(w_key) - w_value = space.getitem(data_w_starargarg, w_key) - unfiltered_kwds_w[key] = w_value - cnt += 1 - assert len(data_w) == cnt - - ndata_args_w = len(data_args_w) - if ndata_args_w >= need_cnt: - args_w = data_args_w[:need_cnt] - for argname, w_arg in zip(argnames[need_cnt:], data_args_w[need_cnt:]): - unfiltered_kwds_w[argname] = w_arg - assert not space.is_true(data_w_stararg) - else: - stararg_w = space.unpackiterable(data_w_stararg) - datalen = len(data_args_w) - args_w = [None] * (datalen + len(stararg_w)) - for i in range(0, datalen): - args_w[i] = data_args_w[i] - for i in range(0, len(stararg_w)): - args_w[i + datalen] = stararg_w[i] - assert len(args_w) == need_cnt - - keywords = [] - keywords_w = [] - for key in need_kwds: - keywords.append(key) - keywords_w.append(unfiltered_kwds_w[key]) - - return ArgumentsForTranslation(self.space, args_w, keywords, keywords_w) - - @staticmethod - def fromshape(space, (shape_cnt, shape_keys, shape_star, shape_stst), data_w): - args_w = data_w[:shape_cnt] - p = end_keys = shape_cnt + len(shape_keys) - if shape_star: - w_star = data_w[p] - p += 1 - else: - w_star = None - if shape_stst: - w_starstar = data_w[p] - p += 1 - else: - w_starstar = None - return ArgumentsForTranslation(space, args_w, list(shape_keys), - data_w[shape_cnt:end_keys], w_star, - w_starstar) + self.keywords = keywords or {} def flatten(self): """ Argument <-> list of w_objects together with "shape" information """ - shape_cnt, shape_keys, shape_star, shape_stst = self._rawshape() - data_w = self.arguments_w + [self.keywords_w[self.keywords.index(key)] - for key in shape_keys] + shape_cnt = len(self.arguments_w) # Number of positional args + shape_keys = tuple(sorted(self.keywords)) + shape_star = self.w_stararg is not None # Flag: presence of *arg + shape_stst = False # Flag: presence of **kwds + data_w = self.arguments_w + [self.keywords[key] for key in shape_keys] if shape_star: data_w.append(self.w_stararg) - if shape_stst: - data_w.append(self.w_starstararg) return (shape_cnt, shape_keys, shape_star, shape_stst), data_w - - def _rawshape(self, nextra=0): - assert not self.combine_has_happened - shape_cnt = len(self.arguments_w) + nextra # Number of positional args - if self.keywords: - shape_keys = self.keywords[:] # List of keywords (strings) - shape_keys.sort() - else: - shape_keys = [] - shape_star = self.w_stararg is not None # Flag: presence of *arg - shape_stst = self.w_starstararg is not None # Flag: presence of **kwds - return shape_cnt, tuple(shape_keys), shape_star, shape_stst # shape_keys are sorted - - -def rawshape(args, nextra=0): - return args._rawshape(nextra) - - -# -# ArgErr family of exceptions raised in case of argument mismatch. -# We try to give error messages following CPython's, which are very informative. -# - -class ArgErr(Exception): - def getmsg(self): - raise NotImplementedError - - -class ArgErrCount(ArgErr): - def __init__(self, got_nargs, nkwds, signature, - defaults_w, missing_args): - self.signature = signature - - self.num_defaults = 0 if defaults_w is None else len(defaults_w) - self.missing_args = missing_args - self.num_args = got_nargs - self.num_kwds = nkwds - - def getmsg(self): - n = self.signature.num_argnames() - if n == 0: - msg = "takes no arguments (%d given)" % ( - self.num_args + self.num_kwds) - else: - defcount = self.num_defaults - has_kwarg = self.signature.has_kwarg() - num_args = self.num_args - num_kwds = self.num_kwds - if defcount == 0 and not self.signature.has_vararg(): - msg1 = "exactly" - if not has_kwarg: - num_args += num_kwds - num_kwds = 0 - elif not self.missing_args: - msg1 = "at most" - else: - msg1 = "at least" - has_kwarg = False - n -= defcount - if n == 1: - plural = "" - else: - plural = "s" - if has_kwarg or num_kwds > 0: - msg2 = " non-keyword" - else: - msg2 = "" - msg = "takes %s %d%s argument%s (%d given)" % ( - msg1, - n, - msg2, - plural, - num_args) - return msg - - -class ArgErrMultipleValues(ArgErr): - def __init__(self, argname): - self.argname = argname - - def getmsg(self): - msg = "got multiple values for keyword argument '%s'" % ( - self.argname) - return msg - - -class ArgErrUnknownKwds(ArgErr): - def __init__(self, space, num_remainingkwds, keywords, kwds_mapping, - keyword_names_w): - name = '' - self.num_kwds = num_remainingkwds - if num_remainingkwds == 1: - for i in range(len(keywords)): - if i not in kwds_mapping: - name = keywords[i] - if name is None: - # We'll assume it's unicode. Encode it. - # Careful, I *think* it should not be possible to - # get an IndexError here but you never know. - try: - if keyword_names_w is None: - raise IndexError - # note: negative-based indexing from the end - w_name = keyword_names_w[i - len(keywords)] - except IndexError: - name = '?' - else: - w_enc = space.wrap(space.sys.defaultencoding) - w_err = space.wrap("replace") - w_name = space.call_method(w_name, "encode", w_enc, - w_err) - name = space.str_w(w_name) - break - self.kwd_name = name - - def getmsg(self): - if self.num_kwds == 1: - msg = "got an unexpected keyword argument '%s'" % ( - self.kwd_name) - else: - msg = "got %d unexpected keyword arguments" % ( - self.num_kwds) - return msg diff --git a/rpython/flowspace/bytecode.py b/rpython/flowspace/bytecode.py --- a/rpython/flowspace/bytecode.py +++ b/rpython/flowspace/bytecode.py @@ -36,7 +36,6 @@ code, consts, names, varnames, filename, name, firstlineno, lnotab, freevars): """Initialize a new code object""" - self.co_name = name assert nlocals >= 0 self.co_argcount = argcount self.co_nlocals = nlocals diff --git a/rpython/flowspace/flowcontext.py b/rpython/flowspace/flowcontext.py --- a/rpython/flowspace/flowcontext.py +++ b/rpython/flowspace/flowcontext.py @@ -7,13 +7,14 @@ from rpython.tool.error import source_lines from rpython.tool.stdlib_opcode import host_bytecode_spec -from rpython.flowspace.argument import ArgumentsForTranslation +from rpython.flowspace.argument import CallSpec from rpython.flowspace.model import (Constant, Variable, Block, Link, - c_last_exception) + c_last_exception, SpaceOperation) from rpython.flowspace.framestate import (FrameState, recursively_unflatten, recursively_flatten) from rpython.flowspace.specialcase import (rpython_print_item, rpython_print_newline) +from rpython.flowspace.operation import implicit_exceptions class FlowingError(Exception): @@ -361,11 +362,6 @@ "peek past the bottom of the stack") return self.locals_stack_w[index] - def pushrevvalues(self, n, values_w): # n should be len(values_w) - assert len(values_w) == n - for i in range(n - 1, -1, -1): - self.pushvalue(values_w[i]) - def settopvalue(self, w_object, index_from_top=0): index = self.valuestackdepth + ~index_from_top assert index >= self.pycode.co_nlocals, ( @@ -377,16 +373,6 @@ values_w.reverse() return values_w - def peekvalues(self, n): - values_w = [None] * n - base = self.valuestackdepth - n - while True: - n -= 1 - if n < 0: - break - values_w[n] = self.locals_stack_w[base + n] - return values_w - def dropvalues(self, n): finaldepth = self.valuestackdepth - n for n in range(finaldepth, self.valuestackdepth): @@ -473,6 +459,17 @@ def guessbool(self, w_condition, **kwds): return self.recorder.guessbool(self, w_condition, **kwds) + def do_operation(self, name, *args_w): + spaceop = SpaceOperation(name, args_w, Variable()) + spaceop.offset = self.last_instr + self.record(spaceop) + return spaceop.result + + def do_operation_with_implicit_exceptions(self, name, *args_w): + w_result = self.do_operation(name, *args_w) + self.handle_implicit_exceptions(implicit_exceptions.get(name)) + return w_result + def handle_implicit_exceptions(self, exceptions): """ Catch possible exceptions implicitly. @@ -742,7 +739,7 @@ def YIELD_VALUE(self, _, next_instr): assert self.pycode.is_generator w_result = self.popvalue() - self.space.do_operation('yield', w_result) + self.do_operation('yield', w_result) # XXX yield expressions not supported. This will blow up if the value # isn't popped straightaway. self.pushvalue(None) @@ -753,7 +750,7 @@ def PRINT_ITEM(self, oparg, next_instr): w_item = self.popvalue() - w_s = self.space.do_operation('str', w_item) + w_s = self.do_operation('str', w_item) self.space.appcall(rpython_print_item, w_s) def PRINT_NEWLINE(self, oparg, next_instr): @@ -961,26 +958,18 @@ self.pushvalue(last_val) def call_function(self, oparg, w_star=None, w_starstar=None): + if w_starstar is not None: + raise FlowingError(self, "Dict-unpacking is not RPython") n_arguments = oparg & 0xff n_keywords = (oparg >> 8) & 0xff - if n_keywords: - keywords = [None] * n_keywords - keywords_w = [None] * n_keywords - while True: - n_keywords -= 1 - if n_keywords < 0: - break - w_value = self.popvalue() - w_key = self.popvalue() - key = self.space.str_w(w_key) - keywords[n_keywords] = key - keywords_w[n_keywords] = w_value - else: - keywords = None - keywords_w = None + keywords = {} + for _ in range(n_keywords): + w_value = self.popvalue() + w_key = self.popvalue() + key = self.space.str_w(w_key) + keywords[key] = w_value arguments = self.popvalues(n_arguments) - args = ArgumentsForTranslation(self.space, arguments, keywords, - keywords_w, w_star, w_starstar) + args = CallSpec(arguments, keywords, w_star, w_starstar) w_function = self.popvalue() w_result = self.space.call_args(w_function, args) self.pushvalue(w_result) @@ -1017,8 +1006,9 @@ def UNPACK_SEQUENCE(self, itemcount, next_instr): w_iterable = self.popvalue() - items = self.space.unpackiterable(w_iterable, itemcount) - self.pushrevvalues(itemcount, items) + items = self.space.unpack_sequence(w_iterable, itemcount) + for w_item in reversed(items): + self.pushvalue(w_item) def slice(self, w_start, w_end): w_obj = self.popvalue() diff --git a/rpython/flowspace/objspace.py b/rpython/flowspace/objspace.py --- a/rpython/flowspace/objspace.py +++ b/rpython/flowspace/objspace.py @@ -7,9 +7,9 @@ import types from inspect import CO_NEWLOCALS -from rpython.flowspace.argument import ArgumentsForTranslation +from rpython.flowspace.argument import CallSpec from rpython.flowspace.model import (Constant, Variable, WrapException, - UnwrapException, checkgraph, SpaceOperation) + UnwrapException, checkgraph) from rpython.flowspace.bytecode import HostCode from rpython.flowspace import operation from rpython.flowspace.flowcontext import (FlowSpaceFrame, fixeggblocks, @@ -84,6 +84,9 @@ # objects which should keep their SomeObjectness not_really_const = NOT_REALLY_CONST + def build_flow(self, func): + return build_flow(func, self) + def is_w(self, w_one, w_two): return self.is_true(self.is_(w_one, w_two)) @@ -91,21 +94,20 @@ id = None # real version added by add_operations() def newdict(self, module="ignored"): - return self.do_operation('newdict') + return self.frame.do_operation('newdict') def newtuple(self, args_w): - try: - content = [self.unwrap(w_arg) for w_arg in args_w] - except UnwrapException: - return self.do_operation('newtuple', *args_w) + if all(isinstance(w_arg, Constant) for w_arg in args_w): + content = [w_arg.value for w_arg in args_w] + return Constant(tuple(content)) else: - return Constant(tuple(content)) + return self.frame.do_operation('newtuple', *args_w) def newlist(self, args_w, sizehint=None): - return self.do_operation('newlist', *args_w) + return self.frame.do_operation('newlist', *args_w) def newslice(self, w_start, w_stop, w_step): - return self.do_operation('newslice', w_start, w_stop, w_step) + return self.frame.do_operation('newslice', w_start, w_stop, w_step) def newbool(self, b): if b: @@ -262,59 +264,29 @@ w_type = w_instclass return FSException(w_type, w_value) - def build_flow(self, func): - """ - """ - _assert_rpythonic(func) - code = HostCode._from_code(func.func_code) - if (code.is_generator and - not hasattr(func, '_generator_next_method_of_')): - graph = PyGraph(func, code) - block = graph.startblock - for name, w_value in zip(code.co_varnames, block.framestate.mergeable): - if isinstance(w_value, Variable): - w_value.rename(name) - return bootstrap_generator(graph) - graph = PyGraph(func, code) - frame = self.frame = FlowSpaceFrame(self, graph, code) - frame.build_flow() - fixeggblocks(graph) - checkgraph(graph) - if code.is_generator: - tweak_generator_graph(graph) - return graph + def unpackiterable(self, w_iterable): + if isinstance(w_iterable, Constant): + l = w_iterable.value + return [self.wrap(x) for x in l] + else: + raise UnwrapException("cannot unpack a Variable iterable ") - def unpackiterable(self, w_iterable, expected_length=None): - if not isinstance(w_iterable, Variable): + def unpack_sequence(self, w_iterable, expected_length): + if isinstance(w_iterable, Constant): l = list(self.unwrap(w_iterable)) - if expected_length is not None and len(l) != expected_length: + if len(l) != expected_length: raise ValueError return [self.wrap(x) for x in l] - elif expected_length is None: - raise UnwrapException("cannot unpack a Variable iterable " - "without knowing its length") else: w_len = self.len(w_iterable) w_correct = self.eq(w_len, self.wrap(expected_length)) if not self.is_true(w_correct): e = self.exc_from_raise(self.w_ValueError, self.w_None) raise e - return [self.do_operation('getitem', w_iterable, self.wrap(i)) + return [self.frame.do_operation('getitem', w_iterable, self.wrap(i)) for i in range(expected_length)] # ____________________________________________________________ - def do_operation(self, name, *args_w): - spaceop = SpaceOperation(name, args_w, Variable()) - spaceop.offset = self.frame.last_instr - self.frame.record(spaceop) - return spaceop.result - - def do_operation_with_implicit_exceptions(self, name, *args_w): - w_result = self.do_operation(name, *args_w) - self.frame.handle_implicit_exceptions( - operation.implicit_exceptions.get(name)) - return w_result - def not_(self, w_obj): return self.wrap(not self.is_true(w_obj)) @@ -325,27 +297,21 @@ pass else: return bool(obj) - w_truthvalue = self.do_operation('is_true', w_obj) + w_truthvalue = self.frame.do_operation('is_true', w_obj) return self.frame.guessbool(w_truthvalue) def iter(self, w_iterable): - try: - iterable = self.unwrap(w_iterable) - except UnwrapException: - pass - else: + if isinstance(w_iterable, Constant): + iterable = w_iterable.value if isinstance(iterable, unrolling_iterable): return self.wrap(iterable.get_unroller()) - w_iter = self.do_operation("iter", w_iterable) + w_iter = self.frame.do_operation("iter", w_iterable) return w_iter def next(self, w_iter): frame = self.frame - try: - it = self.unwrap(w_iter) - except UnwrapException: - pass - else: + if isinstance(w_iter, Constant): + it = w_iter.value if isinstance(it, _unroller): try: v, next_unroller = it.step() @@ -354,7 +320,7 @@ else: frame.replace_in_stack(it, next_unroller) return self.wrap(v) - w_item = self.do_operation("next", w_iter) + w_item = frame.do_operation("next", w_iter) frame.handle_implicit_exceptions([StopIteration, RuntimeError]) return w_item @@ -363,8 +329,8 @@ if w_obj is self.frame.w_globals: raise FlowingError(self.frame, "Attempting to modify global variable %r." % (w_key)) - return self.do_operation_with_implicit_exceptions('setitem', w_obj, - w_key, w_val) + return self.frame.do_operation_with_implicit_exceptions('setitem', + w_obj, w_key, w_val) def setitem_str(self, w_obj, key, w_value): return self.setitem(w_obj, self.wrap(key), w_value) @@ -375,7 +341,7 @@ if w_obj in self.not_really_const: const_w = self.not_really_const[w_obj] if w_name not in const_w: - return self.do_operation_with_implicit_exceptions('getattr', + return self.frame.do_operation_with_implicit_exceptions('getattr', w_obj, w_name) try: obj = self.unwrap_for_computation(w_obj) @@ -394,7 +360,7 @@ return self.wrap(result) except WrapException: pass - return self.do_operation_with_implicit_exceptions('getattr', + return self.frame.do_operation_with_implicit_exceptions('getattr', w_obj, w_name) def isinstance_w(self, w_obj, w_type): @@ -414,7 +380,7 @@ if w_module in self.not_really_const: const_w = self.not_really_const[w_obj] if w_name not in const_w: - return self.do_operation_with_implicit_exceptions('getattr', + return self.frame.do_operation_with_implicit_exceptions('getattr', w_obj, w_name) try: return self.wrap(getattr(w_module.value, w_name.value)) @@ -427,39 +393,42 @@ return self.call_function(w_meth, *arg_w) def call_function(self, w_func, *args_w): - args = ArgumentsForTranslation(self, list(args_w)) + args = CallSpec(list(args_w)) return self.call_args(w_func, args) def appcall(self, func, *args_w): """Call an app-level RPython function directly""" w_func = self.wrap(func) - return self.do_operation('simple_call', w_func, *args_w) + return self.frame.do_operation('simple_call', w_func, *args_w) def call_args(self, w_callable, args): - try: - fn = self.unwrap(w_callable) + if isinstance(w_callable, Constant): + fn = w_callable.value if hasattr(fn, "_flowspace_rewrite_directly_as_"): fn = fn._flowspace_rewrite_directly_as_ w_callable = self.wrap(fn) - sc = self.specialcases[fn] # TypeError if 'fn' not hashable - except (UnwrapException, KeyError, TypeError): - pass + try: + sc = self.specialcases[fn] # TypeError if 'fn' not hashable + except (KeyError, TypeError): + pass + else: + assert args.keywords == {}, "should not call %r with keyword arguments" % (fn,) + if args.w_stararg is not None: + args_w = args.arguments_w + self.unpackiterable(args.w_stararg) + else: + args_w = args.arguments_w + return sc(self, fn, args_w) + + if args.keywords or isinstance(args.w_stararg, Variable): + shape, args_w = args.flatten() + w_res = self.frame.do_operation('call_args', w_callable, + Constant(shape), *args_w) else: - return sc(self, fn, args) - - try: - args_w, kwds_w = args.copy().unpack() - except UnwrapException: - args_w, kwds_w = '?', '?' - # NOTE: annrpython needs to know about the following two operations! - if not kwds_w: - # simple case - w_res = self.do_operation('simple_call', w_callable, *args_w) - else: - # general case - shape, args_w = args.flatten() - w_res = self.do_operation('call_args', w_callable, Constant(shape), - *args_w) + if args.w_stararg is not None: + args_w = args.arguments_w + self.unpackiterable(args.w_stararg) + else: + args_w = args.arguments_w + w_res = self.frame.do_operation('simple_call', w_callable, *args_w) # maybe the call has generated an exception (any one) # but, let's say, not if we are calling a built-in class or function @@ -562,11 +531,34 @@ # type cannot sanely appear in flow graph, # store operation with variable result instead pass - w_result = self.do_operation_with_implicit_exceptions(name, *args_w) + w_result = self.frame.do_operation_with_implicit_exceptions(name, *args_w) return w_result setattr(FlowObjSpace, name, generic_operator) - for (name, symbol, arity, specialnames) in operation.MethodTable: make_op(name, arity) + + +def build_flow(func, space=FlowObjSpace()): + """ + Create the flow graph for the function. + """ + _assert_rpythonic(func) + code = HostCode._from_code(func.func_code) + if (code.is_generator and + not hasattr(func, '_generator_next_method_of_')): + graph = PyGraph(func, code) + block = graph.startblock + for name, w_value in zip(code.co_varnames, block.framestate.mergeable): + if isinstance(w_value, Variable): + w_value.rename(name) + return bootstrap_generator(graph) + graph = PyGraph(func, code) + frame = space.frame = FlowSpaceFrame(space, graph, code) + frame.build_flow() + fixeggblocks(graph) + checkgraph(graph) + if code.is_generator: + tweak_generator_graph(graph) + return graph diff --git a/rpython/flowspace/specialcase.py b/rpython/flowspace/specialcase.py --- a/rpython/flowspace/specialcase.py +++ b/rpython/flowspace/specialcase.py @@ -3,22 +3,18 @@ from rpython.rlib.rarithmetic import r_uint from rpython.rlib.objectmodel import we_are_translated -def sc_import(space, fn, args): - args_w, kwds_w = args.unpack() - assert kwds_w == {}, "should not call %r with keyword arguments" % (fn,) +def sc_import(space, fn, args_w): assert len(args_w) > 0 and len(args_w) <= 5, 'import needs 1 to 5 arguments' args = [space.unwrap(arg) for arg in args_w] return space.import_name(*args) -def sc_operator(space, fn, args): - args_w, kwds_w = args.unpack() - assert kwds_w == {}, "should not call %r with keyword arguments" % (fn,) +def sc_operator(space, fn, args_w): opname = OperationName[fn] if len(args_w) != Arity[opname]: if opname == 'pow' and len(args_w) == 2: args_w = args_w + [Constant(None)] elif opname == 'getattr' and len(args_w) == 3: - return space.do_operation('simple_call', Constant(getattr), *args_w) + return space.frame.do_operation('simple_call', Constant(getattr), *args_w) else: raise Exception("should call %r with exactly %d arguments" % ( fn, Arity[opname])) @@ -51,18 +47,16 @@ # _________________________________________________________________________ -def sc_r_uint(space, r_uint, args): +def sc_r_uint(space, r_uint, args_w): # special case to constant-fold r_uint(32-bit-constant) # (normally, the 32-bit constant is a long, and is not allowed to # show up in the flow graphs at all) - args_w, kwds_w = args.unpack() - assert not kwds_w [w_value] = args_w if isinstance(w_value, Constant): return Constant(r_uint(w_value.value)) - return space.do_operation('simple_call', space.wrap(r_uint), w_value) + return space.frame.do_operation('simple_call', space.wrap(r_uint), w_value) -def sc_we_are_translated(space, we_are_translated, args): +def sc_we_are_translated(space, we_are_translated, args_w): return Constant(True) def sc_locals(space, locals, args): diff --git a/rpython/flowspace/test/test_argument.py b/rpython/flowspace/test/test_argument.py --- a/rpython/flowspace/test/test_argument.py +++ b/rpython/flowspace/test/test_argument.py @@ -1,7 +1,6 @@ # -*- coding: utf-8 -*- import py -from rpython.flowspace.argument import (ArgumentsForTranslation, rawshape, - Signature) +from rpython.flowspace.argument import Signature class TestSignature(object): @@ -50,277 +49,3 @@ assert x == ["a", "b", "c"] assert y == "d" assert z == "e" - -class dummy_wrapped_dict(dict): - def __nonzero__(self): - raise NotImplementedError - -class kwargsdict(dict): - pass - -class DummySpace(object): - def newtuple(self, items): - return tuple(items) - - def is_true(self, obj): - if isinstance(obj, dummy_wrapped_dict): - return bool(dict(obj)) - return bool(obj) - - def fixedview(self, it): - return list(it) - - def listview(self, it): - return list(it) - - def unpackiterable(self, it): - return list(it) - - def view_as_kwargs(self, x): - if len(x) == 0: - return [], [] - return None, None - - def newdict(self): - return {} - - def newlist(self, l=[]): - return l - - def setitem(self, obj, key, value): - obj[key] = value - - def getitem(self, obj, key): - return obj[key] - - def wrap(self, obj): - return obj - - def str_w(self, s): - return str(s) - - def len(self, x): - return len(x) - - def int_w(self, x): - return x - - def eq_w(self, x, y): - return x == y - - def isinstance(self, obj, cls): - return isinstance(obj, cls) - isinstance_w = isinstance - - def exception_match(self, w_type1, w_type2): - return issubclass(w_type1, w_type2) - - def call_method(self, obj, name, *args): - method = getattr(obj, name) - return method(*args) - - def type(self, obj): - class Type: - def getname(self, space, default='?'): - return type(obj).__name__ - return Type() - - - w_TypeError = TypeError - w_AttributeError = AttributeError - w_UnicodeEncodeError = UnicodeEncodeError - w_dict = dict - w_str = str - -def make_arguments_for_translation(space, args_w, keywords_w={}, - w_stararg=None, w_starstararg=None): - return ArgumentsForTranslation(space, args_w, keywords_w.keys(), - keywords_w.values(), w_stararg, - w_starstararg) - -class TestArgumentsForTranslation(object): - - def test_prepend(self): - space = DummySpace() - args = ArgumentsForTranslation(space, ["0"]) - args1 = args.prepend("thingy") - assert args1 is not args - assert args1.arguments_w == ["thingy", "0"] - assert args1.keywords is args.keywords - assert args1.keywords_w is args.keywords_w - - def test_fixedunpacked(self): - space = DummySpace() - - args = ArgumentsForTranslation(space, [], ["k"], [1]) - py.test.raises(ValueError, args.fixedunpack, 1) - - args = ArgumentsForTranslation(space, ["a", "b"]) - py.test.raises(ValueError, args.fixedunpack, 0) - py.test.raises(ValueError, args.fixedunpack, 1) - py.test.raises(ValueError, args.fixedunpack, 3) - py.test.raises(ValueError, args.fixedunpack, 4) - - assert args.fixedunpack(2) == ['a', 'b'] - - def test_unmatch_signature(self): - space = DummySpace() - args = make_arguments_for_translation(space, [1,2,3]) - sig = Signature(['a', 'b', 'c'], None, None) - data = args.match_signature(sig, []) - new_args = args.unmatch_signature(sig, data) - assert args.unpack() == new_args.unpack() - - args = make_arguments_for_translation(space, [1]) - sig = Signature(['a', 'b', 'c'], None, None) - data = args.match_signature(sig, [2, 3]) - new_args = args.unmatch_signature(sig, data) - assert args.unpack() == new_args.unpack() - - args = make_arguments_for_translation(space, [1,2,3,4,5]) - sig = Signature(['a', 'b', 'c'], 'r', None) - data = args.match_signature(sig, []) - new_args = args.unmatch_signature(sig, data) - assert args.unpack() == new_args.unpack() - - args = make_arguments_for_translation(space, [1], {'c': 3, 'b': 2}) - sig = Signature(['a', 'b', 'c'], None, None) - data = args.match_signature(sig, []) - new_args = args.unmatch_signature(sig, data) - assert args.unpack() == new_args.unpack() - - args = make_arguments_for_translation(space, [1], {'c': 5}) - sig = Signature(['a', 'b', 'c'], None, None) - data = args.match_signature(sig, [2, 3]) - new_args = args.unmatch_signature(sig, data) - assert args.unpack() == new_args.unpack() - - args = make_arguments_for_translation(space, [1], {'c': 5, 'd': 7}) - sig = Signature(['a', 'b', 'c'], None, 'kw') - py.test.raises(TypeError, args.match_signature, sig, [2, 3]) - - def test_rawshape(self): - space = DummySpace() - args = make_arguments_for_translation(space, [1,2,3]) - assert rawshape(args) == (3, (), False, False) - - args = make_arguments_for_translation(space, [1]) - assert rawshape(args, 2) == (3, (), False, False) - - args = make_arguments_for_translation(space, [1,2,3,4,5]) - assert rawshape(args) == (5, (), False, False) - - args = make_arguments_for_translation(space, [1], {'c': 3, 'b': 2}) - assert rawshape(args) == (1, ('b', 'c'), False, False) - - args = make_arguments_for_translation(space, [1], {'c': 5}) - assert rawshape(args) == (1, ('c', ), False, False) - - args = make_arguments_for_translation(space, [1], {'c': 5, 'd': 7}) - assert rawshape(args) == (1, ('c', 'd'), False, False) - - args = make_arguments_for_translation(space, [1,2,3,4,5], {'e': 5, 'd': 7}) - assert rawshape(args) == (5, ('d', 'e'), False, False) - - args = make_arguments_for_translation(space, [], {}, - w_stararg=[1], - w_starstararg={'c': 5, 'd': 7}) - assert rawshape(args) == (0, (), True, True) - - args = make_arguments_for_translation(space, [1,2], {'g': 9}, - w_stararg=[3,4,5], - w_starstararg={'e': 5, 'd': 7}) - assert rawshape(args) == (2, ('g', ), True, True) - - def test_copy_and_shape(self): - space = DummySpace() - args = ArgumentsForTranslation(space, ['a'], ['x'], [1], - ['w1'], {'y': 'w2'}) - args1 = args.copy() - args.combine_if_necessary() - assert rawshape(args1) == (1, ('x',), True, True) - - - def test_flatten(self): - space = DummySpace() - args = make_arguments_for_translation(space, [1,2,3]) - assert args.flatten() == ((3, (), False, False), [1, 2, 3]) - - args = make_arguments_for_translation(space, [1]) - assert args.flatten() == ((1, (), False, False), [1]) - - args = make_arguments_for_translation(space, [1,2,3,4,5]) - assert args.flatten() == ((5, (), False, False), [1,2,3,4,5]) - - args = make_arguments_for_translation(space, [1], {'c': 3, 'b': 2}) - assert args.flatten() == ((1, ('b', 'c'), False, False), [1, 2, 3]) - - args = make_arguments_for_translation(space, [1], {'c': 5}) - assert args.flatten() == ((1, ('c', ), False, False), [1, 5]) - - args = make_arguments_for_translation(space, [1], {'c': 5, 'd': 7}) - assert args.flatten() == ((1, ('c', 'd'), False, False), [1, 5, 7]) - - args = make_arguments_for_translation(space, [1,2,3,4,5], {'e': 5, 'd': 7}) - assert args.flatten() == ((5, ('d', 'e'), False, False), [1, 2, 3, 4, 5, 7, 5]) - - args = make_arguments_for_translation(space, [], {}, - w_stararg=[1], - w_starstararg={'c': 5, 'd': 7}) - assert args.flatten() == ((0, (), True, True), [[1], {'c': 5, 'd': 7}]) - - args = make_arguments_for_translation(space, [1,2], {'g': 9}, - w_stararg=[3,4,5], - w_starstararg={'e': 5, 'd': 7}) - assert args.flatten() == ((2, ('g', ), True, True), [1, 2, 9, [3, 4, 5], {'e': 5, 'd': 7}]) - - def test_stararg_flowspace_variable(self): - space = DummySpace() - var = object() - shape = ((2, ('g', ), True, False), [1, 2, 9, var]) - args = make_arguments_for_translation(space, [1,2], {'g': 9}, - w_stararg=var) - assert args.flatten() == shape - - args = ArgumentsForTranslation.fromshape(space, *shape) - assert args.flatten() == shape - - - def test_fromshape(self): - space = DummySpace() - shape = ((3, (), False, False), [1, 2, 3]) - args = ArgumentsForTranslation.fromshape(space, *shape) - assert args.flatten() == shape - - shape = ((1, (), False, False), [1]) - args = ArgumentsForTranslation.fromshape(space, *shape) - assert args.flatten() == shape - - shape = ((5, (), False, False), [1,2,3,4,5]) - args = ArgumentsForTranslation.fromshape(space, *shape) - assert args.flatten() == shape - - shape = ((1, ('b', 'c'), False, False), [1, 2, 3]) - args = ArgumentsForTranslation.fromshape(space, *shape) - assert args.flatten() == shape - - shape = ((1, ('c', ), False, False), [1, 5]) - args = ArgumentsForTranslation.fromshape(space, *shape) - assert args.flatten() == shape - - shape = ((1, ('c', 'd'), False, False), [1, 5, 7]) - args = ArgumentsForTranslation.fromshape(space, *shape) - assert args.flatten() == shape - - shape = ((5, ('d', 'e'), False, False), [1, 2, 3, 4, 5, 7, 5]) - args = ArgumentsForTranslation.fromshape(space, *shape) - assert args.flatten() == shape - - shape = ((0, (), True, True), [[1], {'c': 5, 'd': 7}]) - args = ArgumentsForTranslation.fromshape(space, *shape) - assert args.flatten() == shape - - shape = ((2, ('g', ), True, True), [1, 2, 9, [3, 4, 5], {'e': 5, 'd': 7}]) - args = ArgumentsForTranslation.fromshape(space, *shape) - assert args.flatten() == shape - diff --git a/rpython/flowspace/test/test_framestate.py b/rpython/flowspace/test/test_framestate.py --- a/rpython/flowspace/test/test_framestate.py +++ b/rpython/flowspace/test/test_framestate.py @@ -6,9 +6,6 @@ from rpython.flowspace.pygraph import PyGraph class TestFrameState: - def setup_class(cls): - cls.space = FlowObjSpace() - def getframe(self, func): try: func = func.im_func @@ -16,7 +13,7 @@ pass code = HostCode._from_code(func.func_code) graph = PyGraph(func, code) - frame = FlowSpaceFrame(self.space, graph, code) + frame = FlowSpaceFrame(FlowObjSpace(), graph, code) # hack the frame frame.setstate(graph.startblock.framestate) frame.locals_stack_w[frame.pycode.co_nlocals-1] = Constant(None) diff --git a/rpython/flowspace/test/test_generator.py b/rpython/flowspace/test/test_generator.py --- a/rpython/flowspace/test/test_generator.py +++ b/rpython/flowspace/test/test_generator.py @@ -1,5 +1,5 @@ from rpython.conftest import option -from rpython.flowspace.objspace import FlowObjSpace +from rpython.flowspace.objspace import build_flow from rpython.flowspace.model import Variable from rpython.flowspace.generator import (make_generatoriterator_class, replace_graph_with_bootstrap, get_variable_names, attach_next_method) @@ -67,7 +67,7 @@ yield n yield n # - graph = FlowObjSpace().build_flow(func) + graph = build_flow(func) if option.view: graph.show() block = graph.startblock @@ -93,8 +93,7 @@ yield n + 1 z -= 10 # - space = FlowObjSpace() - graph = space.build_flow(f) + graph = build_flow(f) GeneratorIterator = make_generatoriterator_class(graph) replace_graph_with_bootstrap(GeneratorIterator, graph) func1 = attach_next_method(GeneratorIterator, graph) @@ -104,12 +103,12 @@ assert func1._generator_next_method_of_ is GeneratorIterator assert hasattr(GeneratorIterator, 'next') # - graph_next = space.build_flow(GeneratorIterator.next.im_func) + graph_next = build_flow(GeneratorIterator.next.im_func) join_blocks(graph_next) if option.view: graph_next.show() # - graph1 = space.build_flow(func1) + graph1 = build_flow(func1) if option.view: graph1.show() @@ -119,7 +118,7 @@ yield n + 1 z -= 10 # - graph = FlowObjSpace().build_flow(f) + graph = build_flow(f) if option.view: graph.show() block = graph.startblock diff --git a/rpython/flowspace/test/test_objspace.py b/rpython/flowspace/test/test_objspace.py --- a/rpython/flowspace/test/test_objspace.py +++ b/rpython/flowspace/test/test_objspace.py @@ -5,7 +5,7 @@ from rpython.flowspace.model import Constant, mkentrymap, c_last_exception from rpython.translator.simplify import simplify_graph -from rpython.flowspace.objspace import FlowObjSpace +from rpython.flowspace.objspace import build_flow from rpython.flowspace.flowcontext import FlowingError, FlowSpaceFrame from rpython.conftest import option from rpython.tool.stdlib_opcode import host_bytecode_spec @@ -34,7 +34,7 @@ except AttributeError: pass #name = func.func_name - graph = self.space.build_flow(func, **kwds) + graph = build_flow(func, **kwds) graph.source = inspect.getsource(func) self.show(graph) return graph @@ -43,9 +43,6 @@ if option.view: graph.show() - def setup_class(cls): - cls.space = FlowObjSpace() - def all_operations(self, graph): result = {} for node in graph.iterblocks(): @@ -702,6 +699,35 @@ for op in block.operations: assert not op.opname == "call_args" + def test_starstar_call(self): + """Check that CALL_FUNCTION_KW and CALL_FUNCTION_VAR_KW raise a + useful error. + """ + def g(a, b, c): + return a*b*c + def f1(): + return g(**{'a':0}) + with py.test.raises(FlowingError) as excinfo: + graph = self.codetest(f1) + assert 'Dict-unpacking' in str(excinfo.value) + def f2(): + return g(*(0,), **{'c':3}) + with py.test.raises(FlowingError) as excinfo: + graph = self.codetest(f2) + assert 'Dict-unpacking' in str(excinfo.value) + + def test_kwarg_call(self): + def g(x): + return x + def f(): + return g(x=2) + graph = self.codetest(f) + for block in graph.iterblocks(): + for op in block.operations: + assert op.opname == "call_args" + assert op.args == map(Constant, + [g, (0, ('x',), False, False), 2]) + def test_catch_importerror_1(self): def f(): try: @@ -740,7 +766,7 @@ def test_relative_import(self): def f(): - from ..test.test_objspace import FlowObjSpace + from ..objspace import build_flow # Check that the function works in Python assert f() is None self.codetest(f) diff --git a/rpython/rlib/test/test_nonconst.py b/rpython/rlib/test/test_nonconst.py --- a/rpython/rlib/test/test_nonconst.py +++ b/rpython/rlib/test/test_nonconst.py @@ -4,7 +4,6 @@ from rpython.rlib.nonconst import NonConstant -from rpython.flowspace.objspace import FlowObjSpace from rpython.annotator.annrpython import RPythonAnnotator from rpython.conftest import option from rpython.annotator.model import SomeInstance @@ -13,20 +12,20 @@ def nonconst_f(): a = NonConstant(3) return a - + a = RPythonAnnotator() s = a.build_types(nonconst_f, []) assert s.knowntype is int assert not hasattr(s, 'const') #rtyper = a.translator.buildrtyper(type_system="ootype") #rtyper.specialize() - + def test_nonconst_list(): def nonconst_l(): a = NonConstant([1, 2, 3]) return a[0] - + a = RPythonAnnotator() s = a.build_types(nonconst_l, []) From noreply at buildbot.pypy.org Wed Feb 27 19:54:50 2013 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 27 Feb 2013 19:54:50 +0100 (CET) Subject: [pypy-commit] pypy default: merge heads Message-ID: <20130227185450.922121C088E@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r61863:a16f5b9e4808 Date: 2013-02-27 19:55 +0100 http://bitbucket.org/pypy/pypy/changeset/a16f5b9e4808/ Log: merge heads diff --git a/pypy/objspace/fake/checkmodule.py b/pypy/objspace/fake/checkmodule.py --- a/pypy/objspace/fake/checkmodule.py +++ b/pypy/objspace/fake/checkmodule.py @@ -11,9 +11,10 @@ module = mod.Module(space, W_Root()) for name in module.loaders: module._load_lazily(space, name) - for cls in module.submodules.itervalues(): - submod = cls(space, W_Root()) - for name in submod.loaders: - submod._load_lazily(space, name) + if hasattr(module, 'submodules'): + for cls in module.submodules.itervalues(): + submod = cls(space, W_Root()) + for name in submod.loaders: + submod._load_lazily(space, name) # space.translates(**{'translation.list_comprehension_operations': True}) diff --git a/rpython/rlib/rdynload.py b/rpython/rlib/rdynload.py --- a/rpython/rlib/rdynload.py +++ b/rpython/rlib/rdynload.py @@ -15,6 +15,7 @@ _WIN32 = _MSVC or _MINGW _MAC_OS = platform.name == "darwin" _FREEBSD = sys.platform.startswith("freebsd") +_NETBSD = sys.platform.startswith("netbsd") if _WIN32: from rpython.rlib import rwin32 @@ -27,7 +28,7 @@ else: pre_include_bits = [] -if _FREEBSD or _WIN32: +if _FREEBSD or _NETBSD or _WIN32: libraries = [] else: libraries = ['dl'] diff --git a/rpython/rtyper/module/ll_os.py b/rpython/rtyper/module/ll_os.py --- a/rpython/rtyper/module/ll_os.py +++ b/rpython/rtyper/module/ll_os.py @@ -224,9 +224,10 @@ decls = [] defs = [] for name in self.w_star: - data = {'ret_type': 'int', 'name': name} - decls.append((decl_snippet % data).strip()) - defs.append((def_snippet % data).strip()) + if hasattr(os, name): + data = {'ret_type': 'int', 'name': name} + decls.append((decl_snippet % data).strip()) + defs.append((def_snippet % data).strip()) self.compilation_info = self.compilation_info.merge( ExternalCompilationInfo( diff --git a/rpython/rtyper/module/ll_time.py b/rpython/rtyper/module/ll_time.py --- a/rpython/rtyper/module/ll_time.py +++ b/rpython/rtyper/module/ll_time.py @@ -41,7 +41,7 @@ RUSAGE = platform.Struct('struct rusage', [('ru_utime', TIMEVAL), ('ru_stime', TIMEVAL)]) -if sys.platform.startswith('freebsd'): +if sys.platform.startswith('freebsd') or sys.platform.startswith('netbsd'): libraries = ['compat'] else: libraries = [] diff --git a/rpython/translator/platform/__init__.py b/rpython/translator/platform/__init__.py --- a/rpython/translator/platform/__init__.py +++ b/rpython/translator/platform/__init__.py @@ -286,6 +286,13 @@ host_factory = Freebsd else: host_factory = Freebsd_64 +elif sys.platform.startswith('netbsd'): + from rpython.translator.platform.netbsd import Netbsd, Netbsd_64 + import platform + if platform.architecture()[0] == '32bit': + host_factory = Netbsd + else: + host_factory = Netbsd_64 elif "openbsd" in sys.platform: from rpython.translator.platform.openbsd import OpenBSD, OpenBSD_64 import platform diff --git a/rpython/translator/platform/netbsd.py b/rpython/translator/platform/netbsd.py new file mode 100644 --- /dev/null +++ b/rpython/translator/platform/netbsd.py @@ -0,0 +1,55 @@ +"""Support for NetBSD.""" + +import os + +from rpython.translator.platform import posix + +def get_env(key, default): + if key in os.environ: + return os.environ[key] + else: + return default + +def get_env_vector(key, default): + string = get_env(key, default) + # XXX: handle quotes + return string.split() + +class Netbsd(posix.BasePosix): + name = "netbsd" + + link_flags = ['-pthread'] + get_env_vector('LDFLAGS', '') + cflags = ['-O3', '-pthread', '-fomit-frame-pointer' + ] + get_env_vector('CFLAGS', '') + standalone_only = [] + shared_only = [] + so_ext = 'so' + make_cmd = 'gmake' + extra_libs = ('-lrt',) + + def __init__(self, cc=None): + if cc is None: + cc = get_env("CC", "gcc") + super(Netbsd, self).__init__(cc) + + def _args_for_shared(self, args): + return ['-shared'] + args + + def _preprocess_include_dirs(self, include_dirs): + res_incl_dirs = list(include_dirs) + res_incl_dirs.append(os.path.join(get_env("LOCALBASE", "/usr/pkg"), "include")) + return res_incl_dirs + + def _preprocess_library_dirs(self, library_dirs): + res_lib_dirs = list(library_dirs) + res_lib_dirs.append(os.path.join(get_env("LOCALBASE", "/usr/pkg"), "lib")) + return res_lib_dirs + + def _include_dirs_for_libffi(self): + return [os.path.join(get_env("LOCALBASE", "/usr/pkg"), "include")] + + def _library_dirs_for_libffi(self): + return [os.path.join(get_env("LOCALBASE", "/usr/pkg"), "lib")] + +class Netbsd_64(Netbsd): + shared_only = ('-fPIC',) From noreply at buildbot.pypy.org Wed Feb 27 19:54:51 2013 From: noreply at buildbot.pypy.org (arigo) Date: Wed, 27 Feb 2013 19:54:51 +0100 (CET) Subject: [pypy-commit] pypy default: merge heads Message-ID: <20130227185451.DACD81C088E@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r61864:6a7a87dc6323 Date: 2013-02-27 19:55 +0100 http://bitbucket.org/pypy/pypy/changeset/6a7a87dc6323/ Log: merge heads diff too long, truncating to 2000 out of 2365 lines diff --git a/rpython/flowspace/argument.py b/rpython/annotator/argument.py copy from rpython/flowspace/argument.py copy to rpython/annotator/argument.py --- a/rpython/flowspace/argument.py +++ b/rpython/annotator/argument.py @@ -1,84 +1,45 @@ """ Arguments objects. """ +from rpython.annotator.model import SomeTuple, SomeObject +# for parsing call arguments +class RPythonCallsSpace(object): + """Pseudo Object Space providing almost no real operation. + For the Arguments class: if it really needs other operations, it means + that the call pattern is too complex for R-Python. + """ + def newtuple(self, items_s): + if len(items_s) == 1 and items_s[0] is Ellipsis: + res = SomeObject() # hack to get a SomeObject as the *arg + res.from_ellipsis = True + return res + else: + return SomeTuple(items_s) -class Signature(object): - _immutable_ = True - _immutable_fields_ = ["argnames[*]"] - __slots__ = ("argnames", "varargname", "kwargname") + def unpackiterable(self, s_obj, expected_length=None): + if isinstance(s_obj, SomeTuple): + return list(s_obj.items) + if (s_obj.__class__ is SomeObject and + getattr(s_obj, 'from_ellipsis', False)): # see newtuple() + return [Ellipsis] + raise CallPatternTooComplex("'*' argument must be SomeTuple") - def __init__(self, argnames, varargname=None, kwargname=None): - self.argnames = argnames - self.varargname = varargname - self.kwargname = kwargname + def is_true(self, s_tup): + assert isinstance(s_tup, SomeTuple) + return bool(s_tup.items) - def find_argname(self, name): - try: - return self.argnames.index(name) - except ValueError: - return -1 - def num_argnames(self): - return len(self.argnames) - - def has_vararg(self): - return self.varargname is not None - - def has_kwarg(self): - return self.kwargname is not None - - def scope_length(self): - scopelen = len(self.argnames) - scopelen += self.has_vararg() - scopelen += self.has_kwarg() - return scopelen - - def getallvarnames(self): - argnames = self.argnames - if self.varargname is not None: - argnames = argnames + [self.varargname] - if self.kwargname is not None: - argnames = argnames + [self.kwargname] - return argnames - - def __repr__(self): - return "Signature(%r, %r, %r)" % ( - self.argnames, self.varargname, self.kwargname) - - def __eq__(self, other): - if not isinstance(other, Signature): - return NotImplemented - return (self.argnames == other.argnames and - self.varargname == other.varargname and - self.kwargname == other.kwargname) - - def __ne__(self, other): - if not isinstance(other, Signature): - return NotImplemented - return not self == other - - # make it look tuply for its use in the annotator - - def __len__(self): - return 3 - - def __getitem__(self, i): - if i == 0: - return self.argnames - if i == 1: - return self.varargname - if i == 2: - return self.kwargname - raise IndexError +class CallPatternTooComplex(Exception): + pass class ArgumentsForTranslation(object): + w_starstararg = None def __init__(self, space, args_w, keywords=None, keywords_w=None, w_stararg=None, w_starstararg=None): self.w_stararg = w_stararg - self.w_starstararg = w_starstararg - self.combine_has_happened = False + assert w_starstararg is None self.space = space assert isinstance(args_w, list) self.arguments_w = args_w @@ -95,53 +56,13 @@ return '%s(%s, %s, %s)' % (name, self.arguments_w, self.keywords, self.keywords_w) - def _combine_wrapped(self, w_stararg, w_starstararg): - "unpack the *arg and **kwd into arguments_w and keywords_w" - if w_stararg is not None: - self._combine_starargs_wrapped(w_stararg) - if w_starstararg is not None: - self._combine_starstarargs_wrapped(w_starstararg) - - def _combine_starargs_wrapped(self, w_stararg): - # unpack the * arguments - space = self.space - args_w = space.unpackiterable(w_stararg) - self.arguments_w = self.arguments_w + args_w - - def _combine_starstarargs_wrapped(self, w_starstararg): - # unpack the ** arguments - space = self.space - keywords, values_w = space.view_as_kwargs(w_starstararg) - if keywords is not None: # this path also taken for empty dicts - if self.keywords is None: - self.keywords = keywords - self.keywords_w = values_w - else: - if set(keywords) & set(self.keywords): - raise TypeError("got multiple values for keyword arguments '%s'", set(keywords) & set(self.keywords)) - self.keywords = self.keywords + keywords - self.keywords_w = self.keywords_w + values_w - return - if space.isinstance_w(w_starstararg, space.w_dict): - keys_w = space.unpackiterable(w_starstararg) + @property + def positional_args(self): + if self.w_stararg is not None: + args_w = self.space.unpackiterable(self.w_stararg) + return self.arguments_w + args_w else: - w_keys = space.call_method(w_starstararg, "keys") - keys_w = space.unpackiterable(w_keys) - keywords_w = [None] * len(keys_w) - keywords = [None] * len(keys_w) - for i, w_key in enumerate(keys_w): - key = space.str_w(w_key) - if key in self.keywords: - raise TypeError("got multiple values for keyword argument '%s'" % key) - keywords[i] = key - keywords_w[i] = space.getitem(w_starstararg, w_key) - self.keyword_names_w = keys_w - if self.keywords is None: - self.keywords = keywords - self.keywords_w = keywords_w - else: - self.keywords = self.keywords + keywords - self.keywords_w = self.keywords_w + keywords_w + return self.arguments_w def fixedunpack(self, argcount): """The simplest argument parsing: get the 'argcount' arguments, @@ -154,12 +75,6 @@ raise ValueError("not enough arguments (%d expected)" % argcount) return self.arguments_w - def combine_if_necessary(self): - if self.combine_has_happened: - return - self._combine_wrapped(self.w_stararg, self.w_starstararg) - self.combine_has_happened = True - def prepend(self, w_firstarg): # used often "Return a new Arguments with a new argument inserted first." return ArgumentsForTranslation(self.space, [w_firstarg] + self.arguments_w, @@ -178,10 +93,9 @@ # args_w = list of the normal actual parameters, wrapped # scope_w = resulting list of wrapped values # - self.combine_if_necessary() co_argcount = signature.num_argnames() # expected formal arguments, without */** - args_w = self.arguments_w + args_w = self.positional_args num_args = len(args_w) keywords = self.keywords or [] num_kwds = len(keywords) @@ -263,12 +177,8 @@ def unpack(self): "Return a ([w1,w2...], {'kw':w3...}) pair." - self.combine_if_necessary() - kwds_w = {} - if self.keywords: - for i in range(len(self.keywords)): - kwds_w[self.keywords[i]] = self.keywords_w[i] - return self.arguments_w, kwds_w + kwds_w = dict(zip(self.keywords, self.keywords_w)) if self.keywords else {} + return self.positional_args, kwds_w def match_signature(self, signature, defaults_w): """Parse args and kwargs according to the signature of a code object, @@ -281,11 +191,11 @@ def unmatch_signature(self, signature, data_w): """kind of inverse of match_signature""" - args_w, kwds_w = self.unpack() - need_cnt = len(args_w) - need_kwds = kwds_w.keys() + need_cnt = len(self.positional_args) + need_kwds = self.keywords or [] space = self.space argnames, varargname, kwargname = signature + assert kwargname is None cnt = len(argnames) data_args_w = data_w[:cnt] if varargname: @@ -293,31 +203,17 @@ cnt += 1 else: data_w_stararg = space.newtuple([]) + assert len(data_w) == cnt unfiltered_kwds_w = {} - if kwargname: - data_w_starargarg = data_w[cnt] - for w_key in space.unpackiterable(data_w_starargarg): - key = space.str_w(w_key) - w_value = space.getitem(data_w_starargarg, w_key) - unfiltered_kwds_w[key] = w_value - cnt += 1 - assert len(data_w) == cnt - - ndata_args_w = len(data_args_w) - if ndata_args_w >= need_cnt: + if len(data_args_w) >= need_cnt: args_w = data_args_w[:need_cnt] for argname, w_arg in zip(argnames[need_cnt:], data_args_w[need_cnt:]): unfiltered_kwds_w[argname] = w_arg assert not space.is_true(data_w_stararg) else: stararg_w = space.unpackiterable(data_w_stararg) - datalen = len(data_args_w) - args_w = [None] * (datalen + len(stararg_w)) - for i in range(0, datalen): - args_w[i] = data_args_w[i] - for i in range(0, len(stararg_w)): - args_w[i + datalen] = stararg_w[i] + args_w = data_args_w + stararg_w assert len(args_w) == need_cnt keywords = [] @@ -358,8 +254,7 @@ return (shape_cnt, shape_keys, shape_star, shape_stst), data_w def _rawshape(self, nextra=0): - assert not self.combine_has_happened - shape_cnt = len(self.arguments_w) + nextra # Number of positional args + shape_cnt = len(self.arguments_w) + nextra # Number of positional args if self.keywords: shape_keys = self.keywords[:] # List of keywords (strings) shape_keys.sort() diff --git a/rpython/annotator/bookkeeper.py b/rpython/annotator/bookkeeper.py --- a/rpython/annotator/bookkeeper.py +++ b/rpython/annotator/bookkeeper.py @@ -19,7 +19,7 @@ from rpython.annotator.dictdef import DictDef from rpython.annotator import description from rpython.annotator.signature import annotationoftype -from rpython.flowspace.argument import ArgumentsForTranslation +from rpython.annotator.argument import ArgumentsForTranslation, RPythonCallsSpace from rpython.rlib.objectmodel import r_dict, Symbolic from rpython.tool.algo.unionfind import UnionFind from rpython.rtyper.lltypesystem import lltype, llmemory @@ -734,51 +734,6 @@ return False else: return True - -# for parsing call arguments -class RPythonCallsSpace(object): - """Pseudo Object Space providing almost no real operation. - For the Arguments class: if it really needs other operations, it means - that the call pattern is too complex for R-Python. - """ - w_tuple = SomeTuple - def newtuple(self, items_s): - if len(items_s) == 1 and items_s[0] is Ellipsis: - res = SomeObject() # hack to get a SomeObject as the *arg - res.from_ellipsis = True - return res - else: - return SomeTuple(items_s) - - def newdict(self): - raise CallPatternTooComplex, "'**' argument" - - def unpackiterable(self, s_obj, expected_length=None): - if isinstance(s_obj, SomeTuple): - if (expected_length is not None and - expected_length != len(s_obj.items)): - raise ValueError - return list(s_obj.items) - if (s_obj.__class__ is SomeObject and - getattr(s_obj, 'from_ellipsis', False)): # see newtuple() - return [Ellipsis] - raise CallPatternTooComplex, "'*' argument must be SomeTuple" - fixedview = unpackiterable - listview = unpackiterable - - def is_w(self, one, other): - return one is other - - def type(self, item): - return type(item) - - def is_true(self, s_tup): - assert isinstance(s_tup, SomeTuple) - return bool(s_tup.items) - -class CallPatternTooComplex(Exception): - pass - # get current bookkeeper def getbookkeeper(): diff --git a/rpython/annotator/description.py b/rpython/annotator/description.py --- a/rpython/annotator/description.py +++ b/rpython/annotator/description.py @@ -3,7 +3,7 @@ from rpython.annotator.signature import enforce_signature_args, enforce_signature_return from rpython.flowspace.model import Constant, FunctionGraph from rpython.flowspace.bytecode import cpython_code_signature -from rpython.flowspace.argument import rawshape, ArgErr +from rpython.annotator.argument import rawshape, ArgErr from rpython.tool.sourcetools import valid_identifier, func_with_new_name from rpython.tool.pairtype import extendabletype diff --git a/rpython/annotator/test/test_annrpython.py b/rpython/annotator/test/test_annrpython.py --- a/rpython/annotator/test/test_annrpython.py +++ b/rpython/annotator/test/test_annrpython.py @@ -13,7 +13,7 @@ from rpython.rlib.rarithmetic import r_uint, base_int, r_longlong, r_ulonglong from rpython.rlib.rarithmetic import r_singlefloat from rpython.rlib import objectmodel -from rpython.flowspace.objspace import FlowObjSpace, FlowingError +from rpython.flowspace.objspace import build_flow, FlowingError from rpython.translator.test import snippet @@ -40,9 +40,6 @@ class TestAnnotateTestCase: - def setup_class(cls): - cls.space = FlowObjSpace() - def teardown_method(self, meth): assert annmodel.s_Bool == annmodel.SomeBool() @@ -60,7 +57,7 @@ except AttributeError: pass name = func.func_name - funcgraph = self.space.build_flow(func) + funcgraph = build_flow(func) funcgraph.source = inspect.getsource(func) return funcgraph @@ -775,7 +772,7 @@ assert isinstance(s, annmodel.SomePBC) assert s.const == myobj - def test_cleanup_protocol(self): + def test_cleanup_protocol(self): class Stuff: def __init__(self): self.called = False @@ -3754,7 +3751,7 @@ def test_join_none_and_nonnull(self): from rpython.rlib.rstring import assert_str0 - + def f(i): a = str(i) a = assert_str0(a) @@ -3798,7 +3795,7 @@ class A(object): def __iter__(self): return self - + def fn(): return iter(A()) @@ -3857,7 +3854,7 @@ return True x = X() - + def f(i): if i: x1 = x diff --git a/rpython/annotator/test/test_argument.py b/rpython/annotator/test/test_argument.py new file mode 100644 --- /dev/null +++ b/rpython/annotator/test/test_argument.py @@ -0,0 +1,171 @@ +# -*- coding: utf-8 -*- +import py +from rpython.annotator.argument import ArgumentsForTranslation, rawshape +from rpython.flowspace.argument import Signature + +class DummySpace(object): + def newtuple(self, items): + return tuple(items) + + def is_true(self, obj): + return bool(obj) + + def unpackiterable(self, it): + return list(it) + + +def make_arguments_for_translation(space, args_w, keywords_w={}, + w_stararg=None, w_starstararg=None): + return ArgumentsForTranslation(space, args_w, keywords_w.keys(), + keywords_w.values(), w_stararg, + w_starstararg) + +class TestArgumentsForTranslation(object): + + def test_prepend(self): + space = DummySpace() + args = ArgumentsForTranslation(space, ["0"]) + args1 = args.prepend("thingy") + assert args1 is not args + assert args1.arguments_w == ["thingy", "0"] + assert args1.keywords is args.keywords + assert args1.keywords_w is args.keywords_w + + def test_fixedunpacked(self): + space = DummySpace() + + args = ArgumentsForTranslation(space, [], ["k"], [1]) + py.test.raises(ValueError, args.fixedunpack, 1) + + args = ArgumentsForTranslation(space, ["a", "b"]) + py.test.raises(ValueError, args.fixedunpack, 0) + py.test.raises(ValueError, args.fixedunpack, 1) + py.test.raises(ValueError, args.fixedunpack, 3) + py.test.raises(ValueError, args.fixedunpack, 4) + + assert args.fixedunpack(2) == ['a', 'b'] + + def test_unmatch_signature(self): + space = DummySpace() + args = make_arguments_for_translation(space, [1,2,3]) + sig = Signature(['a', 'b', 'c'], None, None) + data = args.match_signature(sig, []) + new_args = args.unmatch_signature(sig, data) + assert args.unpack() == new_args.unpack() + + args = make_arguments_for_translation(space, [1]) + sig = Signature(['a', 'b', 'c'], None, None) + data = args.match_signature(sig, [2, 3]) + new_args = args.unmatch_signature(sig, data) + assert args.unpack() == new_args.unpack() + + args = make_arguments_for_translation(space, [1,2,3,4,5]) + sig = Signature(['a', 'b', 'c'], 'r', None) + data = args.match_signature(sig, []) + new_args = args.unmatch_signature(sig, data) + assert args.unpack() == new_args.unpack() + + args = make_arguments_for_translation(space, [1], {'c': 3, 'b': 2}) + sig = Signature(['a', 'b', 'c'], None, None) + data = args.match_signature(sig, []) + new_args = args.unmatch_signature(sig, data) + assert args.unpack() == new_args.unpack() + + args = make_arguments_for_translation(space, [1], {'c': 5}) + sig = Signature(['a', 'b', 'c'], None, None) + data = args.match_signature(sig, [2, 3]) + new_args = args.unmatch_signature(sig, data) + assert args.unpack() == new_args.unpack() + + args = make_arguments_for_translation(space, [1], {'c': 5, 'd': 7}) + sig = Signature(['a', 'b', 'c'], None, 'kw') + py.test.raises(TypeError, args.match_signature, sig, [2, 3]) + + def test_rawshape(self): + space = DummySpace() + args = make_arguments_for_translation(space, [1,2,3]) + assert rawshape(args) == (3, (), False, False) + + args = make_arguments_for_translation(space, [1]) + assert rawshape(args, 2) == (3, (), False, False) + + args = make_arguments_for_translation(space, [1,2,3,4,5]) + assert rawshape(args) == (5, (), False, False) + + args = make_arguments_for_translation(space, [1], {'c': 3, 'b': 2}) + assert rawshape(args) == (1, ('b', 'c'), False, False) + + args = make_arguments_for_translation(space, [1], {'c': 5}) + assert rawshape(args) == (1, ('c', ), False, False) + + args = make_arguments_for_translation(space, [1], {'c': 5, 'd': 7}) + assert rawshape(args) == (1, ('c', 'd'), False, False) + + args = make_arguments_for_translation(space, [1,2,3,4,5], {'e': 5, 'd': 7}) + assert rawshape(args) == (5, ('d', 'e'), False, False) + + + def test_flatten(self): + space = DummySpace() + args = make_arguments_for_translation(space, [1,2,3]) + assert args.flatten() == ((3, (), False, False), [1, 2, 3]) + + args = make_arguments_for_translation(space, [1]) + assert args.flatten() == ((1, (), False, False), [1]) + + args = make_arguments_for_translation(space, [1,2,3,4,5]) + assert args.flatten() == ((5, (), False, False), [1,2,3,4,5]) + + args = make_arguments_for_translation(space, [1], {'c': 3, 'b': 2}) + assert args.flatten() == ((1, ('b', 'c'), False, False), [1, 2, 3]) + + args = make_arguments_for_translation(space, [1], {'c': 5}) + assert args.flatten() == ((1, ('c', ), False, False), [1, 5]) + + args = make_arguments_for_translation(space, [1], {'c': 5, 'd': 7}) + assert args.flatten() == ((1, ('c', 'd'), False, False), [1, 5, 7]) + + args = make_arguments_for_translation(space, [1,2,3,4,5], {'e': 5, 'd': 7}) + assert args.flatten() == ((5, ('d', 'e'), False, False), [1, 2, 3, 4, 5, 7, 5]) + + def test_stararg_flowspace_variable(self): + space = DummySpace() + var = object() + shape = ((2, ('g', ), True, False), [1, 2, 9, var]) + args = make_arguments_for_translation(space, [1,2], {'g': 9}, + w_stararg=var) + assert args.flatten() == shape + + args = ArgumentsForTranslation.fromshape(space, *shape) + assert args.flatten() == shape + + + def test_fromshape(self): + space = DummySpace() + shape = ((3, (), False, False), [1, 2, 3]) + args = ArgumentsForTranslation.fromshape(space, *shape) + assert args.flatten() == shape + + shape = ((1, (), False, False), [1]) + args = ArgumentsForTranslation.fromshape(space, *shape) + assert args.flatten() == shape + + shape = ((5, (), False, False), [1,2,3,4,5]) + args = ArgumentsForTranslation.fromshape(space, *shape) + assert args.flatten() == shape + + shape = ((1, ('b', 'c'), False, False), [1, 2, 3]) + args = ArgumentsForTranslation.fromshape(space, *shape) + assert args.flatten() == shape + + shape = ((1, ('c', ), False, False), [1, 5]) + args = ArgumentsForTranslation.fromshape(space, *shape) + assert args.flatten() == shape + + shape = ((1, ('c', 'd'), False, False), [1, 5, 7]) + args = ArgumentsForTranslation.fromshape(space, *shape) + assert args.flatten() == shape + + shape = ((5, ('d', 'e'), False, False), [1, 2, 3, 4, 5, 7, 5]) + args = ArgumentsForTranslation.fromshape(space, *shape) + assert args.flatten() == shape diff --git a/rpython/flowspace/argument.py b/rpython/flowspace/argument.py --- a/rpython/flowspace/argument.py +++ b/rpython/flowspace/argument.py @@ -73,409 +73,25 @@ raise IndexError -class ArgumentsForTranslation(object): - def __init__(self, space, args_w, keywords=None, keywords_w=None, - w_stararg=None, w_starstararg=None): +class CallSpec(object): + """Represents the arguments passed into a function call, i.e. the + `a, b, *c, **d` part in `return func(a, b, *c, **d)`. + """ + def __init__(self, args_w, keywords=None, w_stararg=None, + w_starstararg=None): self.w_stararg = w_stararg - self.w_starstararg = w_starstararg - self.combine_has_happened = False - self.space = space + assert w_starstararg is None, "No **-unpacking in RPython" assert isinstance(args_w, list) self.arguments_w = args_w - self.keywords = keywords - self.keywords_w = keywords_w - self.keyword_names_w = None - - def __repr__(self): - """ NOT_RPYTHON """ - name = self.__class__.__name__ - if not self.keywords: - return '%s(%s)' % (name, self.arguments_w,) - else: - return '%s(%s, %s, %s)' % (name, self.arguments_w, - self.keywords, self.keywords_w) - - def _combine_wrapped(self, w_stararg, w_starstararg): - "unpack the *arg and **kwd into arguments_w and keywords_w" - if w_stararg is not None: - self._combine_starargs_wrapped(w_stararg) - if w_starstararg is not None: - self._combine_starstarargs_wrapped(w_starstararg) - - def _combine_starargs_wrapped(self, w_stararg): - # unpack the * arguments - space = self.space - args_w = space.unpackiterable(w_stararg) - self.arguments_w = self.arguments_w + args_w - - def _combine_starstarargs_wrapped(self, w_starstararg): - # unpack the ** arguments - space = self.space - keywords, values_w = space.view_as_kwargs(w_starstararg) - if keywords is not None: # this path also taken for empty dicts - if self.keywords is None: - self.keywords = keywords - self.keywords_w = values_w - else: - if set(keywords) & set(self.keywords): - raise TypeError("got multiple values for keyword arguments '%s'", set(keywords) & set(self.keywords)) - self.keywords = self.keywords + keywords - self.keywords_w = self.keywords_w + values_w - return - if space.isinstance_w(w_starstararg, space.w_dict): - keys_w = space.unpackiterable(w_starstararg) - else: - w_keys = space.call_method(w_starstararg, "keys") - keys_w = space.unpackiterable(w_keys) - keywords_w = [None] * len(keys_w) - keywords = [None] * len(keys_w) - for i, w_key in enumerate(keys_w): - key = space.str_w(w_key) - if key in self.keywords: - raise TypeError("got multiple values for keyword argument '%s'" % key) - keywords[i] = key - keywords_w[i] = space.getitem(w_starstararg, w_key) - self.keyword_names_w = keys_w - if self.keywords is None: - self.keywords = keywords - self.keywords_w = keywords_w - else: - self.keywords = self.keywords + keywords - self.keywords_w = self.keywords_w + keywords_w - - def fixedunpack(self, argcount): - """The simplest argument parsing: get the 'argcount' arguments, - or raise a real ValueError if the length is wrong.""" - if self.keywords: - raise ValueError("no keyword arguments expected") - if len(self.arguments_w) > argcount: - raise ValueError("too many arguments (%d expected)" % argcount) - elif len(self.arguments_w) < argcount: - raise ValueError("not enough arguments (%d expected)" % argcount) - return self.arguments_w - - def combine_if_necessary(self): - if self.combine_has_happened: - return - self._combine_wrapped(self.w_stararg, self.w_starstararg) - self.combine_has_happened = True - - def prepend(self, w_firstarg): # used often - "Return a new Arguments with a new argument inserted first." - return ArgumentsForTranslation(self.space, [w_firstarg] + self.arguments_w, - self.keywords, self.keywords_w, self.w_stararg, - self.w_starstararg) - - def copy(self): - return ArgumentsForTranslation(self.space, self.arguments_w, - self.keywords, self.keywords_w, self.w_stararg, - self.w_starstararg) - - def _match_signature(self, scope_w, signature, defaults_w=None): - """Parse args and kwargs according to the signature of a code object, - or raise an ArgErr in case of failure. - """ - # args_w = list of the normal actual parameters, wrapped - # scope_w = resulting list of wrapped values - # - self.combine_if_necessary() - co_argcount = signature.num_argnames() # expected formal arguments, without */** - - args_w = self.arguments_w - num_args = len(args_w) - keywords = self.keywords or [] - num_kwds = len(keywords) - - # put as many positional input arguments into place as available - take = min(num_args, co_argcount) - scope_w[:take] = args_w[:take] - input_argcount = take - - # collect extra positional arguments into the *vararg - if signature.has_vararg(): - if num_args > co_argcount: - starargs_w = args_w[co_argcount:] - else: - starargs_w = [] - scope_w[co_argcount] = self.space.newtuple(starargs_w) - elif num_args > co_argcount: - raise ArgErrCount(num_args, num_kwds, signature, defaults_w, 0) - - # if a **kwargs argument is needed, explode - if signature.has_kwarg(): - raise TypeError("Keyword arguments as **kwargs is not supported by RPython") - - # handle keyword arguments - num_remainingkwds = 0 - keywords_w = self.keywords_w - kwds_mapping = None - if num_kwds: - # kwds_mapping maps target indexes in the scope (minus input_argcount) - # to positions in the keywords_w list - kwds_mapping = [-1] * (co_argcount - input_argcount) - # match the keywords given at the call site to the argument names - # the called function takes - # this function must not take a scope_w, to make the scope not - # escape - num_remainingkwds = len(keywords) - for i, name in enumerate(keywords): - # If name was not encoded as a string, it could be None. In that - # case, it's definitely not going to be in the signature. - if name is None: - continue - j = signature.find_argname(name) - # if j == -1 nothing happens - if j < input_argcount: - # check that no keyword argument conflicts with these. - if j >= 0: - raise ArgErrMultipleValues(name) - else: - kwds_mapping[j - input_argcount] = i # map to the right index - num_remainingkwds -= 1 - - if num_remainingkwds: - if co_argcount == 0: - raise ArgErrCount(num_args, num_kwds, signature, defaults_w, 0) - raise ArgErrUnknownKwds(self.space, num_remainingkwds, keywords, - kwds_mapping, self.keyword_names_w) - - # check for missing arguments and fill them from the kwds, - # or with defaults, if available - missing = 0 - if input_argcount < co_argcount: - def_first = co_argcount - (0 if defaults_w is None else len(defaults_w)) - j = 0 - kwds_index = -1 - for i in range(input_argcount, co_argcount): - if kwds_mapping is not None: - kwds_index = kwds_mapping[j] - j += 1 - if kwds_index >= 0: - scope_w[i] = keywords_w[kwds_index] - continue - defnum = i - def_first - if defnum >= 0: - scope_w[i] = defaults_w[defnum] - else: - missing += 1 - if missing: - raise ArgErrCount(num_args, num_kwds, signature, defaults_w, missing) - - def unpack(self): - "Return a ([w1,w2...], {'kw':w3...}) pair." - self.combine_if_necessary() - kwds_w = {} - if self.keywords: - for i in range(len(self.keywords)): - kwds_w[self.keywords[i]] = self.keywords_w[i] - return self.arguments_w, kwds_w - - def match_signature(self, signature, defaults_w): - """Parse args and kwargs according to the signature of a code object, - or raise an ArgErr in case of failure. - """ - scopelen = signature.scope_length() - scope_w = [None] * scopelen - self._match_signature(scope_w, signature, defaults_w) - return scope_w - - def unmatch_signature(self, signature, data_w): - """kind of inverse of match_signature""" - args_w, kwds_w = self.unpack() - need_cnt = len(args_w) - need_kwds = kwds_w.keys() - space = self.space - argnames, varargname, kwargname = signature - cnt = len(argnames) - data_args_w = data_w[:cnt] - if varargname: - data_w_stararg = data_w[cnt] - cnt += 1 - else: - data_w_stararg = space.newtuple([]) - - unfiltered_kwds_w = {} - if kwargname: - data_w_starargarg = data_w[cnt] - for w_key in space.unpackiterable(data_w_starargarg): - key = space.str_w(w_key) - w_value = space.getitem(data_w_starargarg, w_key) - unfiltered_kwds_w[key] = w_value - cnt += 1 - assert len(data_w) == cnt - - ndata_args_w = len(data_args_w) - if ndata_args_w >= need_cnt: - args_w = data_args_w[:need_cnt] - for argname, w_arg in zip(argnames[need_cnt:], data_args_w[need_cnt:]): - unfiltered_kwds_w[argname] = w_arg - assert not space.is_true(data_w_stararg) - else: - stararg_w = space.unpackiterable(data_w_stararg) - datalen = len(data_args_w) - args_w = [None] * (datalen + len(stararg_w)) - for i in range(0, datalen): - args_w[i] = data_args_w[i] - for i in range(0, len(stararg_w)): - args_w[i + datalen] = stararg_w[i] - assert len(args_w) == need_cnt - - keywords = [] - keywords_w = [] - for key in need_kwds: - keywords.append(key) - keywords_w.append(unfiltered_kwds_w[key]) - - return ArgumentsForTranslation(self.space, args_w, keywords, keywords_w) - - @staticmethod - def fromshape(space, (shape_cnt, shape_keys, shape_star, shape_stst), data_w): - args_w = data_w[:shape_cnt] - p = end_keys = shape_cnt + len(shape_keys) - if shape_star: - w_star = data_w[p] - p += 1 - else: - w_star = None - if shape_stst: - w_starstar = data_w[p] - p += 1 - else: - w_starstar = None - return ArgumentsForTranslation(space, args_w, list(shape_keys), - data_w[shape_cnt:end_keys], w_star, - w_starstar) + self.keywords = keywords or {} def flatten(self): """ Argument <-> list of w_objects together with "shape" information """ - shape_cnt, shape_keys, shape_star, shape_stst = self._rawshape() - data_w = self.arguments_w + [self.keywords_w[self.keywords.index(key)] - for key in shape_keys] + shape_cnt = len(self.arguments_w) # Number of positional args + shape_keys = tuple(sorted(self.keywords)) + shape_star = self.w_stararg is not None # Flag: presence of *arg + shape_stst = False # Flag: presence of **kwds + data_w = self.arguments_w + [self.keywords[key] for key in shape_keys] if shape_star: data_w.append(self.w_stararg) - if shape_stst: - data_w.append(self.w_starstararg) return (shape_cnt, shape_keys, shape_star, shape_stst), data_w - - def _rawshape(self, nextra=0): - assert not self.combine_has_happened - shape_cnt = len(self.arguments_w) + nextra # Number of positional args - if self.keywords: - shape_keys = self.keywords[:] # List of keywords (strings) - shape_keys.sort() - else: - shape_keys = [] - shape_star = self.w_stararg is not None # Flag: presence of *arg - shape_stst = self.w_starstararg is not None # Flag: presence of **kwds - return shape_cnt, tuple(shape_keys), shape_star, shape_stst # shape_keys are sorted - - -def rawshape(args, nextra=0): - return args._rawshape(nextra) - - -# -# ArgErr family of exceptions raised in case of argument mismatch. -# We try to give error messages following CPython's, which are very informative. -# - -class ArgErr(Exception): - def getmsg(self): - raise NotImplementedError - - -class ArgErrCount(ArgErr): - def __init__(self, got_nargs, nkwds, signature, - defaults_w, missing_args): - self.signature = signature - - self.num_defaults = 0 if defaults_w is None else len(defaults_w) - self.missing_args = missing_args - self.num_args = got_nargs - self.num_kwds = nkwds - - def getmsg(self): - n = self.signature.num_argnames() - if n == 0: - msg = "takes no arguments (%d given)" % ( - self.num_args + self.num_kwds) - else: - defcount = self.num_defaults - has_kwarg = self.signature.has_kwarg() - num_args = self.num_args - num_kwds = self.num_kwds - if defcount == 0 and not self.signature.has_vararg(): - msg1 = "exactly" - if not has_kwarg: - num_args += num_kwds - num_kwds = 0 - elif not self.missing_args: - msg1 = "at most" - else: - msg1 = "at least" - has_kwarg = False - n -= defcount - if n == 1: - plural = "" - else: - plural = "s" - if has_kwarg or num_kwds > 0: - msg2 = " non-keyword" - else: - msg2 = "" - msg = "takes %s %d%s argument%s (%d given)" % ( - msg1, - n, - msg2, - plural, - num_args) - return msg - - -class ArgErrMultipleValues(ArgErr): - def __init__(self, argname): - self.argname = argname - - def getmsg(self): - msg = "got multiple values for keyword argument '%s'" % ( - self.argname) - return msg - - -class ArgErrUnknownKwds(ArgErr): - def __init__(self, space, num_remainingkwds, keywords, kwds_mapping, - keyword_names_w): - name = '' - self.num_kwds = num_remainingkwds - if num_remainingkwds == 1: - for i in range(len(keywords)): - if i not in kwds_mapping: - name = keywords[i] - if name is None: - # We'll assume it's unicode. Encode it. - # Careful, I *think* it should not be possible to - # get an IndexError here but you never know. - try: - if keyword_names_w is None: - raise IndexError - # note: negative-based indexing from the end - w_name = keyword_names_w[i - len(keywords)] - except IndexError: - name = '?' - else: - w_enc = space.wrap(space.sys.defaultencoding) - w_err = space.wrap("replace") - w_name = space.call_method(w_name, "encode", w_enc, - w_err) - name = space.str_w(w_name) - break - self.kwd_name = name - - def getmsg(self): - if self.num_kwds == 1: - msg = "got an unexpected keyword argument '%s'" % ( - self.kwd_name) - else: - msg = "got %d unexpected keyword arguments" % ( - self.num_kwds) - return msg diff --git a/rpython/flowspace/bytecode.py b/rpython/flowspace/bytecode.py --- a/rpython/flowspace/bytecode.py +++ b/rpython/flowspace/bytecode.py @@ -36,7 +36,6 @@ code, consts, names, varnames, filename, name, firstlineno, lnotab, freevars): """Initialize a new code object""" - self.co_name = name assert nlocals >= 0 self.co_argcount = argcount self.co_nlocals = nlocals diff --git a/rpython/flowspace/flowcontext.py b/rpython/flowspace/flowcontext.py --- a/rpython/flowspace/flowcontext.py +++ b/rpython/flowspace/flowcontext.py @@ -7,13 +7,14 @@ from rpython.tool.error import source_lines from rpython.tool.stdlib_opcode import host_bytecode_spec -from rpython.flowspace.argument import ArgumentsForTranslation +from rpython.flowspace.argument import CallSpec from rpython.flowspace.model import (Constant, Variable, Block, Link, - c_last_exception) + c_last_exception, SpaceOperation) from rpython.flowspace.framestate import (FrameState, recursively_unflatten, recursively_flatten) from rpython.flowspace.specialcase import (rpython_print_item, rpython_print_newline) +from rpython.flowspace.operation import implicit_exceptions class FlowingError(Exception): @@ -361,11 +362,6 @@ "peek past the bottom of the stack") return self.locals_stack_w[index] - def pushrevvalues(self, n, values_w): # n should be len(values_w) - assert len(values_w) == n - for i in range(n - 1, -1, -1): - self.pushvalue(values_w[i]) - def settopvalue(self, w_object, index_from_top=0): index = self.valuestackdepth + ~index_from_top assert index >= self.pycode.co_nlocals, ( @@ -377,16 +373,6 @@ values_w.reverse() return values_w - def peekvalues(self, n): - values_w = [None] * n - base = self.valuestackdepth - n - while True: - n -= 1 - if n < 0: - break - values_w[n] = self.locals_stack_w[base + n] - return values_w - def dropvalues(self, n): finaldepth = self.valuestackdepth - n for n in range(finaldepth, self.valuestackdepth): @@ -473,6 +459,17 @@ def guessbool(self, w_condition, **kwds): return self.recorder.guessbool(self, w_condition, **kwds) + def do_operation(self, name, *args_w): + spaceop = SpaceOperation(name, args_w, Variable()) + spaceop.offset = self.last_instr + self.record(spaceop) + return spaceop.result + + def do_operation_with_implicit_exceptions(self, name, *args_w): + w_result = self.do_operation(name, *args_w) + self.handle_implicit_exceptions(implicit_exceptions.get(name)) + return w_result + def handle_implicit_exceptions(self, exceptions): """ Catch possible exceptions implicitly. @@ -742,7 +739,7 @@ def YIELD_VALUE(self, _, next_instr): assert self.pycode.is_generator w_result = self.popvalue() - self.space.do_operation('yield', w_result) + self.do_operation('yield', w_result) # XXX yield expressions not supported. This will blow up if the value # isn't popped straightaway. self.pushvalue(None) @@ -753,7 +750,7 @@ def PRINT_ITEM(self, oparg, next_instr): w_item = self.popvalue() - w_s = self.space.do_operation('str', w_item) + w_s = self.do_operation('str', w_item) self.space.appcall(rpython_print_item, w_s) def PRINT_NEWLINE(self, oparg, next_instr): @@ -961,26 +958,18 @@ self.pushvalue(last_val) def call_function(self, oparg, w_star=None, w_starstar=None): + if w_starstar is not None: + raise FlowingError(self, "Dict-unpacking is not RPython") n_arguments = oparg & 0xff n_keywords = (oparg >> 8) & 0xff - if n_keywords: - keywords = [None] * n_keywords - keywords_w = [None] * n_keywords - while True: - n_keywords -= 1 - if n_keywords < 0: - break - w_value = self.popvalue() - w_key = self.popvalue() - key = self.space.str_w(w_key) - keywords[n_keywords] = key - keywords_w[n_keywords] = w_value - else: - keywords = None - keywords_w = None + keywords = {} + for _ in range(n_keywords): + w_value = self.popvalue() + w_key = self.popvalue() + key = self.space.str_w(w_key) + keywords[key] = w_value arguments = self.popvalues(n_arguments) - args = ArgumentsForTranslation(self.space, arguments, keywords, - keywords_w, w_star, w_starstar) + args = CallSpec(arguments, keywords, w_star, w_starstar) w_function = self.popvalue() w_result = self.space.call_args(w_function, args) self.pushvalue(w_result) @@ -1017,8 +1006,9 @@ def UNPACK_SEQUENCE(self, itemcount, next_instr): w_iterable = self.popvalue() - items = self.space.unpackiterable(w_iterable, itemcount) - self.pushrevvalues(itemcount, items) + items = self.space.unpack_sequence(w_iterable, itemcount) + for w_item in reversed(items): + self.pushvalue(w_item) def slice(self, w_start, w_end): w_obj = self.popvalue() diff --git a/rpython/flowspace/objspace.py b/rpython/flowspace/objspace.py --- a/rpython/flowspace/objspace.py +++ b/rpython/flowspace/objspace.py @@ -7,9 +7,9 @@ import types from inspect import CO_NEWLOCALS -from rpython.flowspace.argument import ArgumentsForTranslation +from rpython.flowspace.argument import CallSpec from rpython.flowspace.model import (Constant, Variable, WrapException, - UnwrapException, checkgraph, SpaceOperation) + UnwrapException, checkgraph) from rpython.flowspace.bytecode import HostCode from rpython.flowspace import operation from rpython.flowspace.flowcontext import (FlowSpaceFrame, fixeggblocks, @@ -84,6 +84,9 @@ # objects which should keep their SomeObjectness not_really_const = NOT_REALLY_CONST + def build_flow(self, func): + return build_flow(func, self) + def is_w(self, w_one, w_two): return self.is_true(self.is_(w_one, w_two)) @@ -91,21 +94,20 @@ id = None # real version added by add_operations() def newdict(self, module="ignored"): - return self.do_operation('newdict') + return self.frame.do_operation('newdict') def newtuple(self, args_w): - try: - content = [self.unwrap(w_arg) for w_arg in args_w] - except UnwrapException: - return self.do_operation('newtuple', *args_w) + if all(isinstance(w_arg, Constant) for w_arg in args_w): + content = [w_arg.value for w_arg in args_w] + return Constant(tuple(content)) else: - return Constant(tuple(content)) + return self.frame.do_operation('newtuple', *args_w) def newlist(self, args_w, sizehint=None): - return self.do_operation('newlist', *args_w) + return self.frame.do_operation('newlist', *args_w) def newslice(self, w_start, w_stop, w_step): - return self.do_operation('newslice', w_start, w_stop, w_step) + return self.frame.do_operation('newslice', w_start, w_stop, w_step) def newbool(self, b): if b: @@ -262,59 +264,29 @@ w_type = w_instclass return FSException(w_type, w_value) - def build_flow(self, func): - """ - """ - _assert_rpythonic(func) - code = HostCode._from_code(func.func_code) - if (code.is_generator and - not hasattr(func, '_generator_next_method_of_')): - graph = PyGraph(func, code) - block = graph.startblock - for name, w_value in zip(code.co_varnames, block.framestate.mergeable): - if isinstance(w_value, Variable): - w_value.rename(name) - return bootstrap_generator(graph) - graph = PyGraph(func, code) - frame = self.frame = FlowSpaceFrame(self, graph, code) - frame.build_flow() - fixeggblocks(graph) - checkgraph(graph) - if code.is_generator: - tweak_generator_graph(graph) - return graph + def unpackiterable(self, w_iterable): + if isinstance(w_iterable, Constant): + l = w_iterable.value + return [self.wrap(x) for x in l] + else: + raise UnwrapException("cannot unpack a Variable iterable ") - def unpackiterable(self, w_iterable, expected_length=None): - if not isinstance(w_iterable, Variable): + def unpack_sequence(self, w_iterable, expected_length): + if isinstance(w_iterable, Constant): l = list(self.unwrap(w_iterable)) - if expected_length is not None and len(l) != expected_length: + if len(l) != expected_length: raise ValueError return [self.wrap(x) for x in l] - elif expected_length is None: - raise UnwrapException("cannot unpack a Variable iterable " - "without knowing its length") else: w_len = self.len(w_iterable) w_correct = self.eq(w_len, self.wrap(expected_length)) if not self.is_true(w_correct): e = self.exc_from_raise(self.w_ValueError, self.w_None) raise e - return [self.do_operation('getitem', w_iterable, self.wrap(i)) + return [self.frame.do_operation('getitem', w_iterable, self.wrap(i)) for i in range(expected_length)] # ____________________________________________________________ - def do_operation(self, name, *args_w): - spaceop = SpaceOperation(name, args_w, Variable()) - spaceop.offset = self.frame.last_instr - self.frame.record(spaceop) - return spaceop.result - - def do_operation_with_implicit_exceptions(self, name, *args_w): - w_result = self.do_operation(name, *args_w) - self.frame.handle_implicit_exceptions( - operation.implicit_exceptions.get(name)) - return w_result - def not_(self, w_obj): return self.wrap(not self.is_true(w_obj)) @@ -325,27 +297,21 @@ pass else: return bool(obj) - w_truthvalue = self.do_operation('is_true', w_obj) + w_truthvalue = self.frame.do_operation('is_true', w_obj) return self.frame.guessbool(w_truthvalue) def iter(self, w_iterable): - try: - iterable = self.unwrap(w_iterable) - except UnwrapException: - pass - else: + if isinstance(w_iterable, Constant): + iterable = w_iterable.value if isinstance(iterable, unrolling_iterable): return self.wrap(iterable.get_unroller()) - w_iter = self.do_operation("iter", w_iterable) + w_iter = self.frame.do_operation("iter", w_iterable) return w_iter def next(self, w_iter): frame = self.frame - try: - it = self.unwrap(w_iter) - except UnwrapException: - pass - else: + if isinstance(w_iter, Constant): + it = w_iter.value if isinstance(it, _unroller): try: v, next_unroller = it.step() @@ -354,7 +320,7 @@ else: frame.replace_in_stack(it, next_unroller) return self.wrap(v) - w_item = self.do_operation("next", w_iter) + w_item = frame.do_operation("next", w_iter) frame.handle_implicit_exceptions([StopIteration, RuntimeError]) return w_item @@ -363,8 +329,8 @@ if w_obj is self.frame.w_globals: raise FlowingError(self.frame, "Attempting to modify global variable %r." % (w_key)) - return self.do_operation_with_implicit_exceptions('setitem', w_obj, - w_key, w_val) + return self.frame.do_operation_with_implicit_exceptions('setitem', + w_obj, w_key, w_val) def setitem_str(self, w_obj, key, w_value): return self.setitem(w_obj, self.wrap(key), w_value) @@ -375,7 +341,7 @@ if w_obj in self.not_really_const: const_w = self.not_really_const[w_obj] if w_name not in const_w: - return self.do_operation_with_implicit_exceptions('getattr', + return self.frame.do_operation_with_implicit_exceptions('getattr', w_obj, w_name) try: obj = self.unwrap_for_computation(w_obj) @@ -394,7 +360,7 @@ return self.wrap(result) except WrapException: pass - return self.do_operation_with_implicit_exceptions('getattr', + return self.frame.do_operation_with_implicit_exceptions('getattr', w_obj, w_name) def isinstance_w(self, w_obj, w_type): @@ -414,7 +380,7 @@ if w_module in self.not_really_const: const_w = self.not_really_const[w_obj] if w_name not in const_w: - return self.do_operation_with_implicit_exceptions('getattr', + return self.frame.do_operation_with_implicit_exceptions('getattr', w_obj, w_name) try: return self.wrap(getattr(w_module.value, w_name.value)) @@ -427,39 +393,42 @@ return self.call_function(w_meth, *arg_w) def call_function(self, w_func, *args_w): - args = ArgumentsForTranslation(self, list(args_w)) + args = CallSpec(list(args_w)) return self.call_args(w_func, args) def appcall(self, func, *args_w): """Call an app-level RPython function directly""" w_func = self.wrap(func) - return self.do_operation('simple_call', w_func, *args_w) + return self.frame.do_operation('simple_call', w_func, *args_w) def call_args(self, w_callable, args): - try: - fn = self.unwrap(w_callable) + if isinstance(w_callable, Constant): + fn = w_callable.value if hasattr(fn, "_flowspace_rewrite_directly_as_"): fn = fn._flowspace_rewrite_directly_as_ w_callable = self.wrap(fn) - sc = self.specialcases[fn] # TypeError if 'fn' not hashable - except (UnwrapException, KeyError, TypeError): - pass + try: + sc = self.specialcases[fn] # TypeError if 'fn' not hashable + except (KeyError, TypeError): + pass + else: + assert args.keywords == {}, "should not call %r with keyword arguments" % (fn,) + if args.w_stararg is not None: + args_w = args.arguments_w + self.unpackiterable(args.w_stararg) + else: + args_w = args.arguments_w + return sc(self, fn, args_w) + + if args.keywords or isinstance(args.w_stararg, Variable): + shape, args_w = args.flatten() + w_res = self.frame.do_operation('call_args', w_callable, + Constant(shape), *args_w) else: - return sc(self, fn, args) - - try: - args_w, kwds_w = args.copy().unpack() - except UnwrapException: - args_w, kwds_w = '?', '?' - # NOTE: annrpython needs to know about the following two operations! - if not kwds_w: - # simple case - w_res = self.do_operation('simple_call', w_callable, *args_w) - else: - # general case - shape, args_w = args.flatten() - w_res = self.do_operation('call_args', w_callable, Constant(shape), - *args_w) + if args.w_stararg is not None: + args_w = args.arguments_w + self.unpackiterable(args.w_stararg) + else: + args_w = args.arguments_w + w_res = self.frame.do_operation('simple_call', w_callable, *args_w) # maybe the call has generated an exception (any one) # but, let's say, not if we are calling a built-in class or function @@ -562,11 +531,34 @@ # type cannot sanely appear in flow graph, # store operation with variable result instead pass - w_result = self.do_operation_with_implicit_exceptions(name, *args_w) + w_result = self.frame.do_operation_with_implicit_exceptions(name, *args_w) return w_result setattr(FlowObjSpace, name, generic_operator) - for (name, symbol, arity, specialnames) in operation.MethodTable: make_op(name, arity) + + +def build_flow(func, space=FlowObjSpace()): + """ + Create the flow graph for the function. + """ + _assert_rpythonic(func) + code = HostCode._from_code(func.func_code) + if (code.is_generator and + not hasattr(func, '_generator_next_method_of_')): + graph = PyGraph(func, code) + block = graph.startblock + for name, w_value in zip(code.co_varnames, block.framestate.mergeable): + if isinstance(w_value, Variable): + w_value.rename(name) + return bootstrap_generator(graph) + graph = PyGraph(func, code) + frame = space.frame = FlowSpaceFrame(space, graph, code) + frame.build_flow() + fixeggblocks(graph) + checkgraph(graph) + if code.is_generator: + tweak_generator_graph(graph) + return graph diff --git a/rpython/flowspace/specialcase.py b/rpython/flowspace/specialcase.py --- a/rpython/flowspace/specialcase.py +++ b/rpython/flowspace/specialcase.py @@ -3,22 +3,18 @@ from rpython.rlib.rarithmetic import r_uint from rpython.rlib.objectmodel import we_are_translated -def sc_import(space, fn, args): - args_w, kwds_w = args.unpack() - assert kwds_w == {}, "should not call %r with keyword arguments" % (fn,) +def sc_import(space, fn, args_w): assert len(args_w) > 0 and len(args_w) <= 5, 'import needs 1 to 5 arguments' args = [space.unwrap(arg) for arg in args_w] return space.import_name(*args) -def sc_operator(space, fn, args): - args_w, kwds_w = args.unpack() - assert kwds_w == {}, "should not call %r with keyword arguments" % (fn,) +def sc_operator(space, fn, args_w): opname = OperationName[fn] if len(args_w) != Arity[opname]: if opname == 'pow' and len(args_w) == 2: args_w = args_w + [Constant(None)] elif opname == 'getattr' and len(args_w) == 3: - return space.do_operation('simple_call', Constant(getattr), *args_w) + return space.frame.do_operation('simple_call', Constant(getattr), *args_w) else: raise Exception("should call %r with exactly %d arguments" % ( fn, Arity[opname])) @@ -51,18 +47,16 @@ # _________________________________________________________________________ -def sc_r_uint(space, r_uint, args): +def sc_r_uint(space, r_uint, args_w): # special case to constant-fold r_uint(32-bit-constant) # (normally, the 32-bit constant is a long, and is not allowed to # show up in the flow graphs at all) - args_w, kwds_w = args.unpack() - assert not kwds_w [w_value] = args_w if isinstance(w_value, Constant): return Constant(r_uint(w_value.value)) - return space.do_operation('simple_call', space.wrap(r_uint), w_value) + return space.frame.do_operation('simple_call', space.wrap(r_uint), w_value) -def sc_we_are_translated(space, we_are_translated, args): +def sc_we_are_translated(space, we_are_translated, args_w): return Constant(True) def sc_locals(space, locals, args): diff --git a/rpython/flowspace/test/test_argument.py b/rpython/flowspace/test/test_argument.py --- a/rpython/flowspace/test/test_argument.py +++ b/rpython/flowspace/test/test_argument.py @@ -1,7 +1,6 @@ # -*- coding: utf-8 -*- import py -from rpython.flowspace.argument import (ArgumentsForTranslation, rawshape, - Signature) +from rpython.flowspace.argument import Signature class TestSignature(object): @@ -50,277 +49,3 @@ assert x == ["a", "b", "c"] assert y == "d" assert z == "e" - -class dummy_wrapped_dict(dict): - def __nonzero__(self): - raise NotImplementedError - -class kwargsdict(dict): - pass - -class DummySpace(object): - def newtuple(self, items): - return tuple(items) - - def is_true(self, obj): - if isinstance(obj, dummy_wrapped_dict): - return bool(dict(obj)) - return bool(obj) - - def fixedview(self, it): - return list(it) - - def listview(self, it): - return list(it) - - def unpackiterable(self, it): - return list(it) - - def view_as_kwargs(self, x): - if len(x) == 0: - return [], [] - return None, None - - def newdict(self): - return {} - - def newlist(self, l=[]): - return l - - def setitem(self, obj, key, value): - obj[key] = value - - def getitem(self, obj, key): - return obj[key] - - def wrap(self, obj): - return obj - - def str_w(self, s): - return str(s) - - def len(self, x): - return len(x) - - def int_w(self, x): - return x - - def eq_w(self, x, y): - return x == y - - def isinstance(self, obj, cls): - return isinstance(obj, cls) - isinstance_w = isinstance - - def exception_match(self, w_type1, w_type2): - return issubclass(w_type1, w_type2) - - def call_method(self, obj, name, *args): - method = getattr(obj, name) - return method(*args) - - def type(self, obj): - class Type: - def getname(self, space, default='?'): - return type(obj).__name__ - return Type() - - - w_TypeError = TypeError - w_AttributeError = AttributeError - w_UnicodeEncodeError = UnicodeEncodeError - w_dict = dict - w_str = str - -def make_arguments_for_translation(space, args_w, keywords_w={}, - w_stararg=None, w_starstararg=None): - return ArgumentsForTranslation(space, args_w, keywords_w.keys(), - keywords_w.values(), w_stararg, - w_starstararg) - -class TestArgumentsForTranslation(object): - - def test_prepend(self): - space = DummySpace() - args = ArgumentsForTranslation(space, ["0"]) - args1 = args.prepend("thingy") - assert args1 is not args - assert args1.arguments_w == ["thingy", "0"] - assert args1.keywords is args.keywords - assert args1.keywords_w is args.keywords_w - - def test_fixedunpacked(self): - space = DummySpace() - - args = ArgumentsForTranslation(space, [], ["k"], [1]) - py.test.raises(ValueError, args.fixedunpack, 1) - - args = ArgumentsForTranslation(space, ["a", "b"]) - py.test.raises(ValueError, args.fixedunpack, 0) - py.test.raises(ValueError, args.fixedunpack, 1) - py.test.raises(ValueError, args.fixedunpack, 3) - py.test.raises(ValueError, args.fixedunpack, 4) - - assert args.fixedunpack(2) == ['a', 'b'] - - def test_unmatch_signature(self): - space = DummySpace() - args = make_arguments_for_translation(space, [1,2,3]) - sig = Signature(['a', 'b', 'c'], None, None) - data = args.match_signature(sig, []) - new_args = args.unmatch_signature(sig, data) - assert args.unpack() == new_args.unpack() - - args = make_arguments_for_translation(space, [1]) - sig = Signature(['a', 'b', 'c'], None, None) - data = args.match_signature(sig, [2, 3]) - new_args = args.unmatch_signature(sig, data) - assert args.unpack() == new_args.unpack() - - args = make_arguments_for_translation(space, [1,2,3,4,5]) - sig = Signature(['a', 'b', 'c'], 'r', None) - data = args.match_signature(sig, []) - new_args = args.unmatch_signature(sig, data) - assert args.unpack() == new_args.unpack() - - args = make_arguments_for_translation(space, [1], {'c': 3, 'b': 2}) - sig = Signature(['a', 'b', 'c'], None, None) - data = args.match_signature(sig, []) - new_args = args.unmatch_signature(sig, data) - assert args.unpack() == new_args.unpack() - - args = make_arguments_for_translation(space, [1], {'c': 5}) - sig = Signature(['a', 'b', 'c'], None, None) - data = args.match_signature(sig, [2, 3]) - new_args = args.unmatch_signature(sig, data) - assert args.unpack() == new_args.unpack() - - args = make_arguments_for_translation(space, [1], {'c': 5, 'd': 7}) - sig = Signature(['a', 'b', 'c'], None, 'kw') - py.test.raises(TypeError, args.match_signature, sig, [2, 3]) - - def test_rawshape(self): - space = DummySpace() - args = make_arguments_for_translation(space, [1,2,3]) - assert rawshape(args) == (3, (), False, False) - - args = make_arguments_for_translation(space, [1]) - assert rawshape(args, 2) == (3, (), False, False) - - args = make_arguments_for_translation(space, [1,2,3,4,5]) - assert rawshape(args) == (5, (), False, False) - - args = make_arguments_for_translation(space, [1], {'c': 3, 'b': 2}) - assert rawshape(args) == (1, ('b', 'c'), False, False) - - args = make_arguments_for_translation(space, [1], {'c': 5}) - assert rawshape(args) == (1, ('c', ), False, False) - - args = make_arguments_for_translation(space, [1], {'c': 5, 'd': 7}) - assert rawshape(args) == (1, ('c', 'd'), False, False) - - args = make_arguments_for_translation(space, [1,2,3,4,5], {'e': 5, 'd': 7}) - assert rawshape(args) == (5, ('d', 'e'), False, False) - - args = make_arguments_for_translation(space, [], {}, - w_stararg=[1], - w_starstararg={'c': 5, 'd': 7}) - assert rawshape(args) == (0, (), True, True) - - args = make_arguments_for_translation(space, [1,2], {'g': 9}, - w_stararg=[3,4,5], - w_starstararg={'e': 5, 'd': 7}) - assert rawshape(args) == (2, ('g', ), True, True) - - def test_copy_and_shape(self): - space = DummySpace() - args = ArgumentsForTranslation(space, ['a'], ['x'], [1], - ['w1'], {'y': 'w2'}) - args1 = args.copy() - args.combine_if_necessary() - assert rawshape(args1) == (1, ('x',), True, True) - - - def test_flatten(self): - space = DummySpace() - args = make_arguments_for_translation(space, [1,2,3]) - assert args.flatten() == ((3, (), False, False), [1, 2, 3]) - - args = make_arguments_for_translation(space, [1]) - assert args.flatten() == ((1, (), False, False), [1]) - - args = make_arguments_for_translation(space, [1,2,3,4,5]) - assert args.flatten() == ((5, (), False, False), [1,2,3,4,5]) - - args = make_arguments_for_translation(space, [1], {'c': 3, 'b': 2}) - assert args.flatten() == ((1, ('b', 'c'), False, False), [1, 2, 3]) - - args = make_arguments_for_translation(space, [1], {'c': 5}) - assert args.flatten() == ((1, ('c', ), False, False), [1, 5]) - - args = make_arguments_for_translation(space, [1], {'c': 5, 'd': 7}) - assert args.flatten() == ((1, ('c', 'd'), False, False), [1, 5, 7]) - - args = make_arguments_for_translation(space, [1,2,3,4,5], {'e': 5, 'd': 7}) - assert args.flatten() == ((5, ('d', 'e'), False, False), [1, 2, 3, 4, 5, 7, 5]) - - args = make_arguments_for_translation(space, [], {}, - w_stararg=[1], - w_starstararg={'c': 5, 'd': 7}) - assert args.flatten() == ((0, (), True, True), [[1], {'c': 5, 'd': 7}]) - - args = make_arguments_for_translation(space, [1,2], {'g': 9}, - w_stararg=[3,4,5], - w_starstararg={'e': 5, 'd': 7}) - assert args.flatten() == ((2, ('g', ), True, True), [1, 2, 9, [3, 4, 5], {'e': 5, 'd': 7}]) - - def test_stararg_flowspace_variable(self): - space = DummySpace() - var = object() - shape = ((2, ('g', ), True, False), [1, 2, 9, var]) - args = make_arguments_for_translation(space, [1,2], {'g': 9}, - w_stararg=var) - assert args.flatten() == shape - - args = ArgumentsForTranslation.fromshape(space, *shape) - assert args.flatten() == shape - - - def test_fromshape(self): - space = DummySpace() - shape = ((3, (), False, False), [1, 2, 3]) - args = ArgumentsForTranslation.fromshape(space, *shape) - assert args.flatten() == shape - - shape = ((1, (), False, False), [1]) - args = ArgumentsForTranslation.fromshape(space, *shape) - assert args.flatten() == shape - - shape = ((5, (), False, False), [1,2,3,4,5]) - args = ArgumentsForTranslation.fromshape(space, *shape) - assert args.flatten() == shape - - shape = ((1, ('b', 'c'), False, False), [1, 2, 3]) - args = ArgumentsForTranslation.fromshape(space, *shape) - assert args.flatten() == shape - - shape = ((1, ('c', ), False, False), [1, 5]) - args = ArgumentsForTranslation.fromshape(space, *shape) - assert args.flatten() == shape - - shape = ((1, ('c', 'd'), False, False), [1, 5, 7]) - args = ArgumentsForTranslation.fromshape(space, *shape) - assert args.flatten() == shape - - shape = ((5, ('d', 'e'), False, False), [1, 2, 3, 4, 5, 7, 5]) - args = ArgumentsForTranslation.fromshape(space, *shape) - assert args.flatten() == shape - - shape = ((0, (), True, True), [[1], {'c': 5, 'd': 7}]) - args = ArgumentsForTranslation.fromshape(space, *shape) - assert args.flatten() == shape - - shape = ((2, ('g', ), True, True), [1, 2, 9, [3, 4, 5], {'e': 5, 'd': 7}]) - args = ArgumentsForTranslation.fromshape(space, *shape) - assert args.flatten() == shape - diff --git a/rpython/flowspace/test/test_framestate.py b/rpython/flowspace/test/test_framestate.py --- a/rpython/flowspace/test/test_framestate.py +++ b/rpython/flowspace/test/test_framestate.py @@ -6,9 +6,6 @@ from rpython.flowspace.pygraph import PyGraph class TestFrameState: - def setup_class(cls): - cls.space = FlowObjSpace() - def getframe(self, func): try: func = func.im_func @@ -16,7 +13,7 @@ pass code = HostCode._from_code(func.func_code) graph = PyGraph(func, code) - frame = FlowSpaceFrame(self.space, graph, code) + frame = FlowSpaceFrame(FlowObjSpace(), graph, code) # hack the frame frame.setstate(graph.startblock.framestate) frame.locals_stack_w[frame.pycode.co_nlocals-1] = Constant(None) diff --git a/rpython/flowspace/test/test_generator.py b/rpython/flowspace/test/test_generator.py --- a/rpython/flowspace/test/test_generator.py +++ b/rpython/flowspace/test/test_generator.py @@ -1,5 +1,5 @@ from rpython.conftest import option -from rpython.flowspace.objspace import FlowObjSpace +from rpython.flowspace.objspace import build_flow from rpython.flowspace.model import Variable from rpython.flowspace.generator import (make_generatoriterator_class, replace_graph_with_bootstrap, get_variable_names, attach_next_method) @@ -67,7 +67,7 @@ yield n yield n # - graph = FlowObjSpace().build_flow(func) + graph = build_flow(func) if option.view: graph.show() block = graph.startblock @@ -93,8 +93,7 @@ yield n + 1 z -= 10 # - space = FlowObjSpace() - graph = space.build_flow(f) + graph = build_flow(f) GeneratorIterator = make_generatoriterator_class(graph) replace_graph_with_bootstrap(GeneratorIterator, graph) func1 = attach_next_method(GeneratorIterator, graph) @@ -104,12 +103,12 @@ assert func1._generator_next_method_of_ is GeneratorIterator assert hasattr(GeneratorIterator, 'next') # - graph_next = space.build_flow(GeneratorIterator.next.im_func) + graph_next = build_flow(GeneratorIterator.next.im_func) join_blocks(graph_next) if option.view: graph_next.show() # - graph1 = space.build_flow(func1) + graph1 = build_flow(func1) if option.view: graph1.show() @@ -119,7 +118,7 @@ yield n + 1 z -= 10 # - graph = FlowObjSpace().build_flow(f) + graph = build_flow(f) if option.view: graph.show() block = graph.startblock diff --git a/rpython/flowspace/test/test_objspace.py b/rpython/flowspace/test/test_objspace.py --- a/rpython/flowspace/test/test_objspace.py +++ b/rpython/flowspace/test/test_objspace.py @@ -5,7 +5,7 @@ from rpython.flowspace.model import Constant, mkentrymap, c_last_exception from rpython.translator.simplify import simplify_graph -from rpython.flowspace.objspace import FlowObjSpace +from rpython.flowspace.objspace import build_flow from rpython.flowspace.flowcontext import FlowingError, FlowSpaceFrame from rpython.conftest import option from rpython.tool.stdlib_opcode import host_bytecode_spec @@ -34,7 +34,7 @@ except AttributeError: pass #name = func.func_name - graph = self.space.build_flow(func, **kwds) + graph = build_flow(func, **kwds) graph.source = inspect.getsource(func) self.show(graph) return graph @@ -43,9 +43,6 @@ if option.view: graph.show() - def setup_class(cls): - cls.space = FlowObjSpace() - def all_operations(self, graph): result = {} for node in graph.iterblocks(): @@ -702,6 +699,35 @@ for op in block.operations: assert not op.opname == "call_args" + def test_starstar_call(self): + """Check that CALL_FUNCTION_KW and CALL_FUNCTION_VAR_KW raise a + useful error. + """ + def g(a, b, c): + return a*b*c + def f1(): + return g(**{'a':0}) + with py.test.raises(FlowingError) as excinfo: + graph = self.codetest(f1) + assert 'Dict-unpacking' in str(excinfo.value) + def f2(): + return g(*(0,), **{'c':3}) + with py.test.raises(FlowingError) as excinfo: + graph = self.codetest(f2) + assert 'Dict-unpacking' in str(excinfo.value) + + def test_kwarg_call(self): + def g(x): + return x + def f(): + return g(x=2) + graph = self.codetest(f) + for block in graph.iterblocks(): + for op in block.operations: + assert op.opname == "call_args" + assert op.args == map(Constant, + [g, (0, ('x',), False, False), 2]) + def test_catch_importerror_1(self): def f(): try: @@ -740,7 +766,7 @@ def test_relative_import(self): def f(): - from ..test.test_objspace import FlowObjSpace + from ..objspace import build_flow # Check that the function works in Python assert f() is None self.codetest(f) diff --git a/rpython/rlib/test/test_nonconst.py b/rpython/rlib/test/test_nonconst.py --- a/rpython/rlib/test/test_nonconst.py +++ b/rpython/rlib/test/test_nonconst.py @@ -4,7 +4,6 @@ from rpython.rlib.nonconst import NonConstant -from rpython.flowspace.objspace import FlowObjSpace from rpython.annotator.annrpython import RPythonAnnotator from rpython.conftest import option from rpython.annotator.model import SomeInstance @@ -13,20 +12,20 @@ def nonconst_f(): a = NonConstant(3) return a - + a = RPythonAnnotator() s = a.build_types(nonconst_f, []) assert s.knowntype is int assert not hasattr(s, 'const') #rtyper = a.translator.buildrtyper(type_system="ootype") #rtyper.specialize() - + def test_nonconst_list(): def nonconst_l(): a = NonConstant([1, 2, 3]) return a[0] - + a = RPythonAnnotator() s = a.build_types(nonconst_l, []) From noreply at buildbot.pypy.org Wed Feb 27 21:08:07 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Wed, 27 Feb 2013 21:08:07 +0100 (CET) Subject: [pypy-commit] pypy py3k: fix an obscure issue I broke in 894b0fa3245b Message-ID: <20130227200807.E99E31C0084@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61865:06fa7f1e52c2 Date: 2013-02-27 12:06 -0800 http://bitbucket.org/pypy/pypy/changeset/06fa7f1e52c2/ Log: fix an obscure issue I broke in 894b0fa3245b diff --git a/pypy/interpreter/app_main.py b/pypy/interpreter/app_main.py --- a/pypy/interpreter/app_main.py +++ b/pypy/interpreter/app_main.py @@ -640,7 +640,7 @@ except SystemExit as e: status = e.code if inspect_requested(): - display_exception() + display_exception(e) else: status = not success diff --git a/pypy/interpreter/test2/test_app_main.py b/pypy/interpreter/test2/test_app_main.py --- a/pypy/interpreter/test2/test_app_main.py +++ b/pypy/interpreter/test2/test_app_main.py @@ -351,6 +351,11 @@ child.sendline('sys.last_type.__name__') child.expect(re.escape(repr('NameError'))) + def test_options_i_c_sysexit(self): + child = self.spawn(['-i', '-c', 'import sys; sys.exit(1)']) + child.expect('SystemExit: 1') + child.expect('>>>') + def test_atexit(self): skip("Python3 atexit is a builtin module") child = self.spawn([]) From noreply at buildbot.pypy.org Wed Feb 27 22:56:24 2013 From: noreply at buildbot.pypy.org (stefanor) Date: Wed, 27 Feb 2013 22:56:24 +0100 (CET) Subject: [pypy-commit] pypy sqlite-cffi: Remove temporary hacks Message-ID: <20130227215624.9CAA31C0084@cobra.cs.uni-duesseldorf.de> Author: Stefano Rivera Branch: sqlite-cffi Changeset: r61866:d63fb74a68e1 Date: 2013-02-27 22:55 +0200 http://bitbucket.org/pypy/pypy/changeset/d63fb74a68e1/ Log: Remove temporary hacks diff --git a/lib-python/2.7/test/test_sqlite.py b/lib-python/2.7/test/test_sqlite.py --- a/lib-python/2.7/test/test_sqlite.py +++ b/lib-python/2.7/test/test_sqlite.py @@ -1,7 +1,7 @@ from test.test_support import run_unittest, import_module # Skip test if _sqlite3 module was not built. -#import_module('_sqlite3') +import_module('_sqlite3') from sqlite3.test import (dbapi, types, userfunctions, py25tests, factory, transactions, hooks, regression, diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -758,7 +758,7 @@ from sqlite3.dump import _iterdump return _iterdump(self) - if False and lib.HAS_LOAD_EXTENSION: + if lib.HAS_LOAD_EXTENSION: def enable_load_extension(self, enabled): self._check_thread() self._check_closed() From noreply at buildbot.pypy.org Wed Feb 27 22:56:25 2013 From: noreply at buildbot.pypy.org (stefanor) Date: Wed, 27 Feb 2013 22:56:25 +0100 (CET) Subject: [pypy-commit] pypy sqlite-cffi: Probe for sqlite3_enable_load_extension with dlopen() Message-ID: <20130227215625.DAF741C0084@cobra.cs.uni-duesseldorf.de> Author: Stefano Rivera Branch: sqlite-cffi Changeset: r61867:66403f3ff51d Date: 2013-02-27 23:54 +0200 http://bitbucket.org/pypy/pypy/changeset/66403f3ff51d/ Log: Probe for sqlite3_enable_load_extension with dlopen() diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -231,6 +231,21 @@ int sqlite3_value_numeric_type(sqlite3_value*); """) + +def _has_load_extension(): + """Only available since 3.3.6""" + unverified_ffi = FFI() + unverified_ffi.cdef(""" + typedef ... sqlite3; + int sqlite3_enable_load_extension(sqlite3 *db, int onoff); + """) + unverified_lib = unverified_ffi.dlopen('sqlite3') + return hasattr(unverified_lib, 'sqlite3_enable_load_extension') + + +if _has_load_extension(): + ffi.cdef("int sqlite3_enable_load_extension(sqlite3 *db, int onoff);") + lib = ffi.verify(""" #include """, libraries=['sqlite3']) @@ -272,7 +287,6 @@ for symbol in exported_sqlite_symbols: globals()[symbol] = getattr(lib, symbol) - _SQLITE_TRANSIENT = ffi.cast('void *', lib.SQLITE_TRANSIENT) @@ -758,7 +772,7 @@ from sqlite3.dump import _iterdump return _iterdump(self) - if lib.HAS_LOAD_EXTENSION: + if hasattr(lib, 'sqlite3_enable_load_extension'): def enable_load_extension(self, enabled): self._check_thread() self._check_closed() From noreply at buildbot.pypy.org Wed Feb 27 22:56:27 2013 From: noreply at buildbot.pypy.org (stefanor) Date: Wed, 27 Feb 2013 22:56:27 +0100 (CET) Subject: [pypy-commit] pypy sqlite-cffi: Indent headers to taste Message-ID: <20130227215627.1CB871C0084@cobra.cs.uni-duesseldorf.de> Author: Stefano Rivera Branch: sqlite-cffi Changeset: r61868:1529ba50273d Date: 2013-02-27 23:55 +0200 http://bitbucket.org/pypy/pypy/changeset/1529ba50273d/ Log: Indent headers to taste diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -118,19 +118,19 @@ typedef uint64_t sqlite3_uint64; int sqlite3_open( - const char *filename, /* Database filename (UTF-8) */ - sqlite3 **ppDb /* OUT: SQLite db handle */ + const char *filename, /* Database filename (UTF-8) */ + sqlite3 **ppDb /* OUT: SQLite db handle */ ); int sqlite3_close(sqlite3 *); int sqlite3_busy_timeout(sqlite3*, int ms); int sqlite3_prepare_v2( - sqlite3 *db, /* Database handle */ - const char *zSql, /* SQL statement, UTF-8 encoded */ - int nByte, /* Maximum length of zSql in bytes. */ - sqlite3_stmt **ppStmt, /* OUT: Statement handle */ - const char **pzTail /* OUT: Pointer to unused portion of zSql */ + sqlite3 *db, /* Database handle */ + const char *zSql, /* SQL statement, UTF-8 encoded */ + int nByte, /* Maximum length of zSql in bytes. */ + sqlite3_stmt **ppStmt, /* OUT: Statement handle */ + const char **pzTail /* OUT: Pointer to unused portion of zSql */ ); int sqlite3_finalize(sqlite3_stmt *pStmt); int sqlite3_column_count(sqlite3_stmt *pStmt); @@ -164,26 +164,26 @@ void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); int sqlite3_create_collation( - sqlite3*, - const char *zName, - int eTextRep, - void*, - int(*xCompare)(void*,int,const void*,int,const void*) + sqlite3*, + const char *zName, + int eTextRep, + void*, + int(*xCompare)(void*,int,const void*,int,const void*) ); int sqlite3_set_authorizer( - sqlite3*, - int (*xAuth)(void*,int,const char*,const char*,const char*,const char*), - void *pUserData + sqlite3*, + int (*xAuth)(void*,int,const char*,const char*,const char*,const char*), + void *pUserData ); int sqlite3_create_function( - sqlite3 *db, - const char *zFunctionName, - int nArg, - int eTextRep, - void *pApp, - void (*xFunc)(sqlite3_context*,int,sqlite3_value**), - void (*xStep)(sqlite3_context*,int,sqlite3_value**), - void (*xFinal)(sqlite3_context*) + sqlite3 *db, + const char *zFunctionName, + int nArg, + int eTextRep, + void *pApp, + void (*xFunc)(sqlite3_context*,int,sqlite3_value**), + void (*xStep)(sqlite3_context*,int,sqlite3_value**), + void (*xFinal)(sqlite3_context*) ); void *sqlite3_aggregate_context(sqlite3_context*, int nBytes); @@ -193,11 +193,11 @@ int sqlite3_total_changes(sqlite3*); int sqlite3_prepare( - sqlite3 *db, /* Database handle */ - const char *zSql, /* SQL statement, UTF-8 encoded */ - int nByte, /* Maximum length of zSql in bytes. */ - sqlite3_stmt **ppStmt, /* OUT: Statement handle */ - const char **pzTail /* OUT: Pointer to unused portion of zSql */ + sqlite3 *db, /* Database handle */ + const char *zSql, /* SQL statement, UTF-8 encoded */ + int nByte, /* Maximum length of zSql in bytes. */ + sqlite3_stmt **ppStmt, /* OUT: Statement handle */ + const char **pzTail /* OUT: Pointer to unused portion of zSql */ ); void sqlite3_result_blob(sqlite3_context*, const void*, int, void(*)(void*)); From noreply at buildbot.pypy.org Wed Feb 27 22:59:33 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Wed, 27 Feb 2013 22:59:33 +0100 (CET) Subject: [pypy-commit] pypy py3k: revert 54d5f5238df9 and import latin_1 additionally as cpython does guarantee Message-ID: <20130227215933.6AE991C0084@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61869:9047e5093a5f Date: 2013-02-27 13:58 -0800 http://bitbucket.org/pypy/pypy/changeset/9047e5093a5f/ Log: revert 54d5f5238df9 and import latin_1 additionally as cpython does guarantee these have already been imported at startup diff --git a/pypy/module/imp/test/test_import.py b/pypy/module/imp/test/test_import.py --- a/pypy/module/imp/test/test_import.py +++ b/pypy/module/imp/test/test_import.py @@ -1095,6 +1095,13 @@ (mydir): import sys sys.path.append(mydir) + + # Obscure: manually bootstrap the utf-8/latin1 codecs + # for TextIOs opened by imp.find_module. It's not + # otherwise loaded by the test infrastructure but would + # have been by app_main + import encodings.utf_8 + import encodings.latin_1 """) def teardown_class(cls): From noreply at buildbot.pypy.org Wed Feb 27 22:59:34 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Wed, 27 Feb 2013 22:59:34 +0100 (CET) Subject: [pypy-commit] pypy py3k: avoid recursion issues at startup by pre-importing the utf-8/latin1 encodings Message-ID: <20130227215934.C2AFD1C0084@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61870:7939f83e15e5 Date: 2013-02-27 13:58 -0800 http://bitbucket.org/pypy/pypy/changeset/7939f83e15e5/ Log: avoid recursion issues at startup by pre-importing the utf-8/latin1 encodings (like cpython does) diff --git a/pypy/interpreter/app_main.py b/pypy/interpreter/app_main.py --- a/pypy/interpreter/app_main.py +++ b/pypy/interpreter/app_main.py @@ -233,20 +233,34 @@ def initstdio(encoding=None, unbuffered=False): if hasattr(sys, 'stdin'): return # already initialized - if not encoding: - encoding = sys.getfilesystemencoding() - if ':' in encoding: - encoding, errors = encoding.split(':', 1) - else: - errors = None - sys.stdin = sys.__stdin__ = create_stdio( - 0, False, "", encoding, errors, unbuffered) - sys.stdout = sys.__stdout__ = create_stdio( - 1, True, "", encoding, errors, unbuffered) - sys.stderr = sys.__stderr__ = create_stdio( - 2, True, "", encoding, 'backslashreplace', unbuffered) + # Hack to avoid recursion issues during bootstrapping: pre-import + # the utf-8 and latin-1 codecs + encerr = None + try: + import encodings.utf_8 + import encodings.latin_1 + except ImportError as e: + encerr = e + try: + if not encoding: + encoding = sys.getfilesystemencoding() + if ':' in encoding: + encoding, errors = encoding.split(':', 1) + else: + errors = None + + sys.stdin = sys.__stdin__ = create_stdio( + 0, False, "", encoding, errors, unbuffered) + sys.stdout = sys.__stdout__ = create_stdio( + 1, True, "", encoding, errors, unbuffered) + sys.stderr = sys.__stderr__ = create_stdio( + 2, True, "", encoding, 'backslashreplace', unbuffered) + finally: + if encerr: + display_exception(encerr) + del encerr def create_stdio(fd, writing, name, encoding, errors, unbuffered): import io From noreply at buildbot.pypy.org Thu Feb 28 01:18:09 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Thu, 28 Feb 2013 01:18:09 +0100 (CET) Subject: [pypy-commit] pypy py3k: add a 'locale' codec for use by fsdecode/encode during interpreter bootstrap, Message-ID: <20130228001809.280BD1C123E@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61871:1c77bd032140 Date: 2013-02-27 16:11 -0800 http://bitbucket.org/pypy/pypy/changeset/1c77bd032140/ Log: add a 'locale' codec for use by fsdecode/encode during interpreter bootstrap, works via POSIX wcstombs/mbrtowc (and a chunk of C from cpython) diff --git a/pypy/module/_codecs/locale.c b/pypy/module/_codecs/locale.c new file mode 100644 --- /dev/null +++ b/pypy/module/_codecs/locale.c @@ -0,0 +1,517 @@ +/* From CPython 3.2.3's fileutils.c, and _Py_normalize_encoding from + unicodeobject.c +*/ +/* +#include "Python.h" +*/ +#include +#include +#include +#define PyMem_Malloc malloc +#define PyMem_Free free +/* C99 but recent Windows has it */ +#define HAVE_MBRTOWC 1 + +#ifdef MS_WINDOWS +# include +#endif + +#ifdef HAVE_LANGINFO_H +#include +#include +#endif + +#if 0 && defined(__APPLE__) +extern wchar_t* _Py_DecodeUTF8_surrogateescape(const char *s, Py_ssize_t size); +#endif + +#if !defined(__APPLE__) && !defined(MS_WINDOWS) +#if 0 +extern int _pypy_normalize_encoding(const char *, char *, size_t); +#endif + +/* Workaround FreeBSD and OpenIndiana locale encoding issue with the C locale. + On these operating systems, nl_langinfo(CODESET) announces an alias of the + ASCII encoding, whereas mbstowcs() and wcstombs() functions use the + ISO-8859-1 encoding. The problem is that os.fsencode() and os.fsdecode() use + locale.getpreferredencoding() codec. For example, if command line arguments + are decoded by mbstowcs() and encoded back by os.fsencode(), we get a + UnicodeEncodeError instead of retrieving the original byte string. + + The workaround is enabled if setlocale(LC_CTYPE, NULL) returns "C", + nl_langinfo(CODESET) announces "ascii" (or an alias to ASCII), and at least + one byte in range 0x80-0xff can be decoded from the locale encoding. The + workaround is also enabled on error, for example if getting the locale + failed. + + Values of locale_is_ascii: + + 1: the workaround is used: _Py_wchar2char() uses + encode_ascii_surrogateescape() and _Py_char2wchar() uses + decode_ascii_surrogateescape() + 0: the workaround is not used: _Py_wchar2char() uses wcstombs() and + _Py_char2wchar() uses mbstowcs() + -1: unknown, need to call check_force_ascii() to get the value +*/ +static int force_ascii = -1; + +static int +_pypy_check_force_ascii(void) +{ + char *loc; +#if defined(HAVE_LANGINFO_H) && defined(CODESET) + char *codeset, **alias; + char encoding[100]; + int is_ascii; + unsigned int i; + char* ascii_aliases[] = { + "ascii", + "646", + "ansi-x3.4-1968", + "ansi-x3-4-1968", + "ansi-x3.4-1986", + "cp367", + "csascii", + "ibm367", + "iso646-us", + "iso-646.irv-1991", + "iso-ir-6", + "us", + "us-ascii", + NULL + }; +#endif + + loc = setlocale(LC_CTYPE, NULL); + if (loc == NULL) + goto error; + if (strcmp(loc, "C") != 0) { + /* the LC_CTYPE locale is different than C */ + return 0; + } + +#if defined(HAVE_LANGINFO_H) && defined(CODESET) + codeset = nl_langinfo(CODESET); + if (!codeset || codeset[0] == '\0') { + /* CODESET is not set or empty */ + goto error; + } + if (!_pypy_normalize_encoding(codeset, encoding, sizeof(encoding))) + goto error; + + is_ascii = 0; + for (alias=ascii_aliases; *alias != NULL; alias++) { + if (strcmp(encoding, *alias) == 0) { + is_ascii = 1; + break; + } + } + if (!is_ascii) { + /* nl_langinfo(CODESET) is not "ascii" or an alias of ASCII */ + return 0; + } + + for (i=0x80; i<0xff; i++) { + unsigned char ch; + wchar_t wch; + size_t res; + + ch = (unsigned char)i; + res = mbstowcs(&wch, (char*)&ch, 1); + if (res != (size_t)-1) { + /* decoding a non-ASCII character from the locale encoding succeed: + the locale encoding is not ASCII, force ASCII */ + return 1; + } + } + /* None of the bytes in the range 0x80-0xff can be decoded from the locale + encoding: the locale encoding is really ASCII */ + return 0; +#else + /* nl_langinfo(CODESET) is not available: always force ASCII */ + return 1; +#endif + +error: + /* if an error occured, force the ASCII encoding */ + return 1; +} + +static char* +_pypy_encode_ascii_surrogateescape(const wchar_t *text, size_t *error_pos) +{ + char *result = NULL, *out; + size_t len, i; + wchar_t ch; + + if (error_pos != NULL) + *error_pos = (size_t)-1; + + len = wcslen(text); + + result = PyMem_Malloc(len + 1); /* +1 for NUL byte */ + if (result == NULL) + return NULL; + + out = result; + for (i=0; i 0xdfff); tmp++) + ; + if (*tmp == 0) { + if (size != NULL) + *size = count; + return res; + } + } + PyMem_Free(res); + } + /* Conversion failed. Fall back to escaping with surrogateescape. */ +#ifdef HAVE_MBRTOWC + /* Try conversion with mbrtwoc (C99), and escape non-decodable bytes. */ + + /* Overallocate; as multi-byte characters are in the argument, the + actual output could use less memory. */ + argsize = strlen(arg) + 1; + res = (wchar_t*)PyMem_Malloc(argsize*sizeof(wchar_t)); + if (!res) + goto oom; + in = (unsigned char*)arg; + out = res; + memset(&mbs, 0, sizeof mbs); + while (argsize) { + size_t converted = mbrtowc(out, (char*)in, argsize, &mbs); + if (converted == 0) + /* Reached end of string; null char stored. */ + break; + if (converted == (size_t)-2) { + /* Incomplete character. This should never happen, + since we provide everything that we have - + unless there is a bug in the C library, or I + misunderstood how mbrtowc works. */ + fprintf(stderr, "unexpected mbrtowc result -2\n"); + PyMem_Free(res); + return NULL; + } + if (converted == (size_t)-1) { + /* Conversion error. Escape as UTF-8b, and start over + in the initial shift state. */ + *out++ = 0xdc00 + *in++; + argsize--; + memset(&mbs, 0, sizeof mbs); + continue; + } + if (*out >= 0xd800 && *out <= 0xdfff) { + /* Surrogate character. Escape the original + byte sequence with surrogateescape. */ + argsize -= converted; + while (converted--) + *out++ = 0xdc00 + *in++; + continue; + } + /* successfully converted some bytes */ + in += converted; + argsize -= converted; + out++; + } + if (size != NULL) + *size = out - res; +#else /* HAVE_MBRTOWC */ + /* Cannot use C locale for escaping; manually escape as if charset + is ASCII (i.e. escape all bytes > 128. This will still roundtrip + correctly in the locale's charset, which must be an ASCII superset. */ + res = _pypy_decode_ascii_surrogateescape(arg, size); + if (res == NULL) + goto oom; +#endif /* HAVE_MBRTOWC */ + return res; +oom: + fprintf(stderr, "out of memory\n"); + return NULL; +#endif /* __APPLE__ */ +} + +/* Encode a (wide) character string to the locale encoding with the + surrogateescape error handler (characters in range U+DC80..U+DCFF are + converted to bytes 0x80..0xFF). + + This function is the reverse of _Py_char2wchar(). + + Return a pointer to a newly allocated byte string (use PyMem_Free() to free + the memory), or NULL on conversion or memory allocation error. + + If error_pos is not NULL: *error_pos is the index of the invalid character + on conversion error, or (size_t)-1 otherwise. */ +char* +pypy_wchar2char(const wchar_t *text, size_t *error_pos) +{ +#if 0 && defined(__APPLE__) + Py_ssize_t len; + PyObject *unicode, *bytes = NULL; + char *cpath; + + unicode = PyUnicode_FromWideChar(text, wcslen(text)); + if (unicode == NULL) + return NULL; + + bytes = PyUnicode_EncodeUTF8(PyUnicode_AS_UNICODE(unicode), + PyUnicode_GET_SIZE(unicode), + "surrogateescape"); + Py_DECREF(unicode); + if (bytes == NULL) { + PyErr_Clear(); + if (error_pos != NULL) + *error_pos = (size_t)-1; + return NULL; + } + + len = PyBytes_GET_SIZE(bytes); + cpath = PyMem_Malloc(len+1); + if (cpath == NULL) { + PyErr_Clear(); + Py_DECREF(bytes); + if (error_pos != NULL) + *error_pos = (size_t)-1; + return NULL; + } + memcpy(cpath, PyBytes_AsString(bytes), len + 1); + Py_DECREF(bytes); + return cpath; +#else /* __APPLE__ */ + const size_t len = wcslen(text); + char *result = NULL, *bytes = NULL; + size_t i, size, converted; + wchar_t c, buf[2]; + +#if !defined(__APPLE__) && !defined(MS_WINDOWS) +/*#ifndef MS_WINDOWS*/ + if (force_ascii == -1) + force_ascii = _pypy_check_force_ascii(); + + if (force_ascii) + return _pypy_encode_ascii_surrogateescape(text, error_pos); +#endif + + /* The function works in two steps: + 1. compute the length of the output buffer in bytes (size) + 2. outputs the bytes */ + size = 0; + buf[1] = 0; + while (1) { + for (i=0; i < len; i++) { + c = text[i]; + if (c >= 0xdc80 && c <= 0xdcff) { + /* UTF-8b surrogate */ + if (bytes != NULL) { + *bytes++ = c - 0xdc00; + size--; + } + else + size++; + continue; + } + else { + buf[0] = c; + if (bytes != NULL) + converted = wcstombs(bytes, buf, size); + else + converted = wcstombs(NULL, buf, 0); + if (converted == (size_t)-1) { + if (result != NULL) + PyMem_Free(result); + if (error_pos != NULL) + *error_pos = i; + return NULL; + } + if (bytes != NULL) { + bytes += converted; + size -= converted; + } + else + size += converted; + } + } + if (result != NULL) { + *bytes = '\0'; + break; + } + + size += 1; /* nul byte at the end */ + result = PyMem_Malloc(size); + if (result == NULL) { + if (error_pos != NULL) + *error_pos = (size_t)-1; + return NULL; + } + bytes = result; + } + return result; +#endif /* __APPLE__ */ +} + +void +pypy_char2wchar_free(wchar_t *text) +{ + PyMem_Free(text); +} + +void +pypy_wchar2char_free(char *bytes) +{ + PyMem_Free(bytes); +} + +#define Py_ISUPPER isupper +#define Py_TOLOWER tolower + +/* Convert encoding to lower case and replace '_' with '-' in order to + catch e.g. UTF_8. Return 0 on error (encoding is longer than lower_len-1), + 1 on success. */ +int +_pypy_normalize_encoding(const char *encoding, + char *lower, + size_t lower_len) +{ + const char *e; + char *l; + char *l_end; + + e = encoding; + l = lower; + l_end = &lower[lower_len - 1]; + while (*e) { + if (l == l_end) + return 0; + if (Py_ISUPPER(*e)) { + *l++ = Py_TOLOWER(*e++); + } + else if (*e == '_') { + *l++ = '-'; + e++; + } + else { + *l++ = *e++; + } + } + *l = '\0'; + return 1; +} diff --git a/pypy/module/_codecs/locale.py b/pypy/module/_codecs/locale.py new file mode 100644 --- /dev/null +++ b/pypy/module/_codecs/locale.py @@ -0,0 +1,153 @@ +""" +Provides internal 'locale' codecs (via POSIX wcstombs/mbrtowc) for use +by PyUnicode_Decode/EncodeFSDefault during interpreter bootstrap +""" +import os +import py +import sys +from rpython.rlib.objectmodel import we_are_translated +from rpython.rlib.rstring import UnicodeBuilder, assert_str0 +from rpython.rlib.runicode import (code_to_unichr, + default_unicode_error_decode, default_unicode_error_encode) +from rpython.rtyper.lltypesystem import lltype, rffi +from rpython.translator.tool.cbuild import ExternalCompilationInfo + +if we_are_translated(): + UNICHAR_SIZE = rffi.sizeof(lltype.UniChar) +else: + UNICHAR_SIZE = 2 if sys.maxunicode == 0xFFFF else 4 +MERGE_SURROGATES = UNICHAR_SIZE == 2 and rffi.sizeof(rffi.WCHAR_T) == 4 + + +cwd = py.path.local(__file__).dirpath() +eci = ExternalCompilationInfo( + separate_module_files=[cwd.join('locale.c')], + export_symbols=['pypy_char2wchar', 'pypy_char2wchar_free', + 'pypy_wchar2char', 'pypy_wchar2char_free']) + +def llexternal(*args, **kwargs): + kwargs.setdefault('compilation_info', eci) + kwargs.setdefault('sandboxsafe', True) + kwargs.setdefault('_nowrapper', True) + return rffi.llexternal(*args, **kwargs) + +# An actual wchar_t*, rffi.CWCHARP is an array of UniChar (possibly on a +# narrow build) +RAW_WCHARP = lltype.Ptr(lltype.Array(rffi.WCHAR_T, hints={'nolength': True})) +pypy_char2wchar = llexternal('pypy_char2wchar', [rffi.CCHARP, rffi.SIZE_TP], + RAW_WCHARP) +pypy_char2wchar_free = llexternal('pypy_char2wchar_free', [RAW_WCHARP], + lltype.Void) +pypy_wchar2char = llexternal('pypy_wchar2char', [RAW_WCHARP, rffi.SIZE_TP], + rffi.CCHARP) +pypy_wchar2char_free = llexternal('pypy_wchar2char_free', [rffi.CCHARP], + lltype.Void) + + +def unicode_encode_locale_surrogateescape(u, errorhandler=None): + """Encode unicode via the locale codecs (POSIX wcstombs) with the + surrogateescape handler. + + The optional errorhandler is only called in the case of fatal + errors. + """ + if errorhandler is None: + errorhandler = default_unicode_error_encode + + with lltype.scoped_alloc(rffi.SIZE_TP.TO, 1) as errorposp: + with scoped_unicode2rawwcharp(u) as ubuf: + sbuf = pypy_wchar2char(ubuf, errorposp) + try: + if sbuf is None: + errorpos = rffi.cast(lltype.Signed, errorposp[0]) + if errorpos == -1: + raise MemoryError + errmsg = _errmsg("pypy_wchar2char") + errorhandler('strict', 'filesystemencoding', errmsg, u, + errorpos, errorpos + 1) + return rffi.charp2str(sbuf) + finally: + pypy_wchar2char_free(sbuf) + + +def unicode_decode_locale_surrogateescape(s, errorhandler=None): + """Decode strs via the locale codecs (POSIX mrbtowc) with the + surrogateescape handler. + + The optional errorhandler is only called in the case of fatal + errors. + """ + if errorhandler is None: + errorhandler = default_unicode_error_decode + + with lltype.scoped_alloc(rffi.SIZE_TP.TO, 1) as sizep: + with rffi.scoped_str2charp(s) as sbuf: + ubuf = pypy_char2wchar(sbuf, sizep) + try: + if ubuf is None: + errmsg = _errmsg("pypy_char2wchar") + errorhandler('strict', 'filesystemencoding', errmsg, s, 0, 1) + size = rffi.cast(lltype.Signed, sizep[0]) + return rawwcharp2unicoden(ubuf, size) + finally: + pypy_char2wchar_free(ubuf) + + +def _errmsg(what): + from rpython.rlib import rposix + errmsg = os.strerror(rposix.get_errno()) + return "%s failed" % what if errmsg is None else errmsg + + +class scoped_unicode2rawwcharp: + def __init__(self, value): + if value is not None: + self.buf = unicode2rawwcharp(value) + else: + self.buf = lltype.nullptr(RAW_WCHARP.TO) + def __enter__(self): + return self.buf + def __exit__(self, *args): + if self.buf: + lltype.free(self.buf, flavor='raw') + +def unicode2rawwcharp(u): + """unicode -> raw wchar_t*""" + size = _unicode2cwcharp_loop(u, None) if MERGE_SURROGATES else len(u) + array = lltype.malloc(RAW_WCHARP.TO, size + 1, flavor='raw') + array[size] = rffi.cast(rffi.WCHAR_T, u'\x00') + _unicode2cwcharp_loop(u, array) + return array +unicode2rawwcharp._annenforceargs_ = [unicode] + +def _unicode2cwcharp_loop(u, array): + write = array is not None + ulen = len(u) + count = i = 0 + while i < ulen: + oc = ord(u[i]) + if (MERGE_SURROGATES and + 0xD800 <= oc <= 0xDBFF and i + 1 < ulen and + 0xDC00 <= ord(u[i + 1]) <= 0xDFFF): + if write: + merged = (((oc & 0x03FF) << 10) | + (ord(u[i + 1]) & 0x03FF)) + 0x10000 + array[count] = rffi.cast(rffi.WCHAR_T, merged) + i += 2 + else: + if write: + array[count] = rffi.cast(rffi.WCHAR_T, oc) + i += 1 + count += 1 + return count +unicode2rawwcharp._annenforceargs_ = [unicode, None] + + +def rawwcharp2unicoden(wcp, maxlen): + b = UnicodeBuilder(maxlen) + i = 0 + while i < maxlen and wcp[i] != u'\x00': + b.append(code_to_unichr(wcp[i])) + i += 1 + return assert_str0(b.build()) +unicode2rawwcharp._annenforceargs_ = [None, int] diff --git a/pypy/module/_codecs/test/test_locale.py b/pypy/module/_codecs/test/test_locale.py new file mode 100644 --- /dev/null +++ b/pypy/module/_codecs/test/test_locale.py @@ -0,0 +1,71 @@ +# coding: utf-8 +import py +from pypy.module._codecs import interp_codecs +from pypy.module._codecs.locale import ( + unicode_decode_locale_surrogateescape, + unicode_encode_locale_surrogateescape) +from rpython.rlib import rlocale, runicode + +class TestLocaleCodec(object): + + def setup_class(cls): + from rpython.rlib import rlocale + cls.oldlocale = rlocale.setlocale(rlocale.LC_ALL, None) + + def teardown_class(cls): + if hasattr(cls, 'oldlocale'): + from rpython.rlib import rlocale + rlocale.setlocale(rlocale.LC_ALL, cls.oldlocale) + + def getdecoder(self, encoding): + return getattr(runicode, "str_decode_%s" % encoding.replace("-", "_")) + + def getencoder(self, encoding): + return getattr(runicode, + "unicode_encode_%s" % encoding.replace("-", "_")) + + def getstate(self): + return self.space.fromcache(interp_codecs.CodecState) + + def setlocale(self, locale): + from rpython.rlib import rlocale + try: + rlocale.setlocale(rlocale.LC_ALL, locale) + except rlocale.LocaleError: + py.test.skip("%s locale unsupported" % locale) + + def test_encode_locale(self): + self.setlocale("en_US.UTF-8") + locale_encoder = unicode_encode_locale_surrogateescape + utf8_encoder = self.getencoder('utf-8') + for val in u'foo', u' 日本', u'\U0001320C': + assert (locale_encoder(val) == + utf8_encoder(val, len(val), None)) + + def test_encode_locale_errorhandler(self): + self.setlocale("en_US.UTF-8") + locale_encoder = unicode_encode_locale_surrogateescape + utf8_encoder = self.getencoder('utf-8') + encode_error_handler = self.getstate().encode_error_handler + for val in u'foo\udc80bar', u'\udcff\U0001320C': + expected = utf8_encoder(val, len(val), 'surrogateescape', + encode_error_handler) + assert locale_encoder(val) == expected + + def test_decode_locale(self): + self.setlocale("en_US.UTF-8") + locale_decoder = unicode_decode_locale_surrogateescape + utf8_decoder = self.getdecoder('utf-8') + for val in 'foo', ' \xe6\x97\xa5\xe6\x9c\xac', '\xf0\x93\x88\x8c': + assert (locale_decoder(val) == + utf8_decoder(val, len(val), None)[0]) + + def test_decode_locale_errorhandler(self): + self.setlocale("en_US.UTF-8") + locale_decoder = unicode_decode_locale_surrogateescape + utf8_decoder = self.getdecoder('utf-8') + decode_error_handler = self.getstate().decode_error_handler + val = 'foo\xe3bar' + expected = utf8_decoder(val, len(val), 'surrogateescape', True, + decode_error_handler)[0] + assert locale_decoder(val) == expected From noreply at buildbot.pypy.org Thu Feb 28 02:28:14 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Thu, 28 Feb 2013 02:28:14 +0100 (CET) Subject: [pypy-commit] pypy py3k: hopefully fix compilation/defines on most platforms Message-ID: <20130228012814.486601C0084@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61872:f722b05bf117 Date: 2013-02-27 17:27 -0800 http://bitbucket.org/pypy/pypy/changeset/f722b05bf117/ Log: hopefully fix compilation/defines on most platforms diff --git a/pypy/module/_codecs/locale.c b/pypy/module/_codecs/locale.c --- a/pypy/module/_codecs/locale.c +++ b/pypy/module/_codecs/locale.c @@ -4,13 +4,20 @@ /* #include "Python.h" */ +#include #include +#include #include #include +#ifdef _MSC_VER +#define MS_WINDOWS +#endif #define PyMem_Malloc malloc #define PyMem_Free free /* C99 but recent Windows has it */ #define HAVE_MBRTOWC 1 +/* Hopefully? */ +#define HAVE_LANGINFO_H #ifdef MS_WINDOWS # include From noreply at buildbot.pypy.org Thu Feb 28 03:07:04 2013 From: noreply at buildbot.pypy.org (bdkearns) Date: Thu, 28 Feb 2013 03:07:04 +0100 (CET) Subject: [pypy-commit] pypy default: fix whatsnew Message-ID: <20130228020704.15B641C0084@cobra.cs.uni-duesseldorf.de> Author: Brian Kearns Branch: Changeset: r61873:5c244127af74 Date: 2013-02-27 21:05 -0500 http://bitbucket.org/pypy/pypy/changeset/5c244127af74/ Log: fix whatsnew diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst --- a/pypy/doc/whatsnew-head.rst +++ b/pypy/doc/whatsnew-head.rst @@ -79,3 +79,6 @@ .. branch: cleanup-numpypy-namespace Cleanup _numpypy and numpypy namespaces to more closely resemble numpy. + +.. branch: kill-flowobjspace +Random cleanups to hide FlowObjSpace from public view. From noreply at buildbot.pypy.org Thu Feb 28 05:57:47 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Thu, 28 Feb 2013 05:57:47 +0100 (CET) Subject: [pypy-commit] pypy py3k: the caret location is an impl detail (reapplied from 2.7) Message-ID: <20130228045747.B0FAC1C088E@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61874:1007f010c8cd Date: 2013-02-27 20:56 -0800 http://bitbucket.org/pypy/pypy/changeset/1007f010c8cd/ Log: the caret location is an impl detail (reapplied from 2.7) diff --git a/lib-python/3.2/test/test_traceback.py b/lib-python/3.2/test/test_traceback.py --- a/lib-python/3.2/test/test_traceback.py +++ b/lib-python/3.2/test/test_traceback.py @@ -7,6 +7,7 @@ import re from test.support import run_unittest, Error, captured_output from test.support import TESTFN, unlink +from test.support import check_impl_detail import traceback @@ -57,8 +58,11 @@ IndentationError) self.assertEqual(len(err), 4) self.assertEqual(err[1].strip(), "print(2)") - self.assertIn("^", err[2]) - self.assertEqual(err[1].find(")"), err[2].find("^")) + if check_impl_detail(): + # on CPython, there is a "^" at the end of the line on PyPy, + # there is a "^" too, but at the start, more logically + self.assertIn("^", err[2]) + self.assertEqual(err[1].find(")"), err[2].find("^")) def test_base_exception(self): # Test that exceptions derived from BaseException are formatted right From noreply at buildbot.pypy.org Thu Feb 28 06:06:57 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Thu, 28 Feb 2013 06:06:57 +0100 (CET) Subject: [pypy-commit] pypy py3k: reapply probably the last couple of check_impl_detail workarounds from 2.7 Message-ID: <20130228050657.09B441C088E@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61875:f9424c217f7d Date: 2013-02-27 21:06 -0800 http://bitbucket.org/pypy/pypy/changeset/f9424c217f7d/ Log: reapply probably the last couple of check_impl_detail workarounds from 2.7 diff --git a/lib-python/3.2/test/test_isinstance.py b/lib-python/3.2/test/test_isinstance.py --- a/lib-python/3.2/test/test_isinstance.py +++ b/lib-python/3.2/test/test_isinstance.py @@ -272,7 +272,15 @@ # Make sure that calling isinstance with a deeply nested tuple for its # argument will raise RuntimeError eventually. tuple_arg = (compare_to,) - for cnt in range(sys.getrecursionlimit()+5): + + if support.check_impl_detail(cpython=True): + RECURSION_LIMIT = sys.getrecursionlimit() + else: + # on non-CPython implementations, the maximum actual recursion + # limit might be higher, but probably not higher than 99999 + RECURSION_LIMIT = 99999 + + for cnt in range(RECURSION_LIMIT + 5): tuple_arg = (tuple_arg,) fxn(arg, tuple_arg) diff --git a/lib-python/3.2/test/test_unicodedata.py b/lib-python/3.2/test/test_unicodedata.py --- a/lib-python/3.2/test/test_unicodedata.py +++ b/lib-python/3.2/test/test_unicodedata.py @@ -234,10 +234,11 @@ # been loaded in this process. popen = subprocess.Popen(args, stderr=subprocess.PIPE) popen.wait() - self.assertEqual(popen.returncode, 1) - error = "SyntaxError: (unicode error) \\N escapes not supported " \ - "(can't load unicodedata module)" - self.assertIn(error, popen.stderr.read().decode("ascii")) + self.assertIn(popen.returncode, [0, 1]) # at least it did not segfault + if test.support.check_impl_detail(): + error = "SyntaxError: (unicode error) \\N escapes not supported " \ + "(can't load unicodedata module)" + self.assertIn(error, popen.stderr.read().decode("ascii")) popen.stderr.close() def test_decimal_numeric_consistent(self): From noreply at buildbot.pypy.org Thu Feb 28 09:08:24 2013 From: noreply at buildbot.pypy.org (stefanor) Date: Thu, 28 Feb 2013 09:08:24 +0100 (CET) Subject: [pypy-commit] cffi default: That could have been simpler Message-ID: <20130228080824.8F6641C0CA3@cobra.cs.uni-duesseldorf.de> Author: Stefano Rivera Branch: Changeset: r1172:25579465c12b Date: 2013-02-23 14:49 +0200 http://bitbucket.org/cffi/cffi/changeset/25579465c12b/ Log: That could have been simpler diff --git a/cffi/verifier.py b/cffi/verifier.py --- a/cffi/verifier.py +++ b/cffi/verifier.py @@ -73,9 +73,9 @@ # kill both the .so extension and the other .'s, as introduced # by Python 3: 'basename.cpython-33m.so' basename = basename.split('.', 1)[0] - # kill the _d added in Python 2 debug builds + # and the _d added in Python 2 debug builds if basename.endswith('_d'): - basename = basename.rsplit('_', 1)[0] + basename = basename[:-2] return basename def get_extension(self): From noreply at buildbot.pypy.org Thu Feb 28 09:08:23 2013 From: noreply at buildbot.pypy.org (stefanor) Date: Thu, 28 Feb 2013 09:08:23 +0100 (CET) Subject: [pypy-commit] cffi default: Kill the _d added in Python 2 debug builds Message-ID: <20130228080823.843451C01A7@cobra.cs.uni-duesseldorf.de> Author: Stefano Rivera Branch: Changeset: r1171:6a7602c93197 Date: 2013-02-23 14:29 +0200 http://bitbucket.org/cffi/cffi/changeset/6a7602c93197/ Log: Kill the _d added in Python 2 debug builds diff --git a/cffi/verifier.py b/cffi/verifier.py --- a/cffi/verifier.py +++ b/cffi/verifier.py @@ -72,7 +72,11 @@ basename = os.path.basename(self.modulefilename) # kill both the .so extension and the other .'s, as introduced # by Python 3: 'basename.cpython-33m.so' - return basename.split('.', 1)[0] + basename = basename.split('.', 1)[0] + # kill the _d added in Python 2 debug builds + if basename.endswith('_d'): + basename = basename.rsplit('_', 1)[0] + return basename def get_extension(self): if not self._has_source: From noreply at buildbot.pypy.org Thu Feb 28 09:08:25 2013 From: noreply at buildbot.pypy.org (arigo) Date: Thu, 28 Feb 2013 09:08:25 +0100 (CET) Subject: [pypy-commit] cffi default: Merged in stefanor/cffi (pull request #8) Message-ID: <20130228080825.9EC551C01A7@cobra.cs.uni-duesseldorf.de> Author: arigo Branch: Changeset: r1173:ac6e8b7a5317 Date: 2013-02-28 09:08 +0100 http://bitbucket.org/cffi/cffi/changeset/ac6e8b7a5317/ Log: Merged in stefanor/cffi (pull request #8) Strip _d from cpython 2.x debug build extension names diff --git a/cffi/verifier.py b/cffi/verifier.py --- a/cffi/verifier.py +++ b/cffi/verifier.py @@ -72,7 +72,11 @@ basename = os.path.basename(self.modulefilename) # kill both the .so extension and the other .'s, as introduced # by Python 3: 'basename.cpython-33m.so' - return basename.split('.', 1)[0] + basename = basename.split('.', 1)[0] + # and the _d added in Python 2 debug builds + if basename.endswith('_d'): + basename = basename[:-2] + return basename def get_extension(self): if not self._has_source: From noreply at buildbot.pypy.org Thu Feb 28 09:14:07 2013 From: noreply at buildbot.pypy.org (arigo) Date: Thu, 28 Feb 2013 09:14:07 +0100 (CET) Subject: [pypy-commit] cffi default: More careful, even if it looks more brittle in theory Message-ID: <20130228081407.DEB241C07C6@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r1174:8bb28002f9d4 Date: 2013-02-28 09:13 +0100 http://bitbucket.org/cffi/cffi/changeset/8bb28002f9d4/ Log: More careful, even if it looks more brittle in theory diff --git a/cffi/verifier.py b/cffi/verifier.py --- a/cffi/verifier.py +++ b/cffi/verifier.py @@ -73,8 +73,9 @@ # kill both the .so extension and the other .'s, as introduced # by Python 3: 'basename.cpython-33m.so' basename = basename.split('.', 1)[0] - # and the _d added in Python 2 debug builds - if basename.endswith('_d'): + # and the _d added in Python 2 debug builds --- but try to be + # conservative and not kill a legitimate _d + if basename.endswith('_d') and hasattr(sys, 'gettotalrefcount'): basename = basename[:-2] return basename From noreply at buildbot.pypy.org Thu Feb 28 16:16:46 2013 From: noreply at buildbot.pypy.org (arigo) Date: Thu, 28 Feb 2013 16:16:46 +0100 (CET) Subject: [pypy-commit] cffi default: Python 3 fixes. Message-ID: <20130228151646.48CF91C00A8@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r1175:1620fee43bde Date: 2013-02-28 16:14 +0100 http://bitbucket.org/cffi/cffi/changeset/1620fee43bde/ Log: Python 3 fixes. diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c --- a/c/_cffi_backend.c +++ b/c/_cffi_backend.c @@ -54,6 +54,7 @@ #if PY_MAJOR_VERSION >= 3 # define PyInt_FromLong PyLong_FromLong # define PyInt_FromSsize_t PyLong_FromSsize_t +# define PyInt_AsSsize_t PyLong_AsSsize_t #endif #if PY_MAJOR_VERSION >= 3 diff --git a/testing/test_parsing.py b/testing/test_parsing.py --- a/testing/test_parsing.py +++ b/testing/test_parsing.py @@ -210,11 +210,12 @@ assert str(e.value).startswith('cannot parse "int(*)(foobarbazunknown)"') def test_redefine_common_type(): + prefix = "" if sys.version_info < (3,) else "b" ffi = FFI() ffi.cdef("typedef char FILE;") - assert repr(ffi.cast("FILE", 123)) == "" + assert repr(ffi.cast("FILE", 123)) == "" % prefix ffi.cdef("typedef char int32_t;") - assert repr(ffi.cast("int32_t", 123)) == "" + assert repr(ffi.cast("int32_t", 123)) == "" % prefix def test_bool(): ffi = FFI() diff --git a/testing/test_verify.py b/testing/test_verify.py --- a/testing/test_verify.py +++ b/testing/test_verify.py @@ -1563,7 +1563,7 @@ return (x == NULL); } """) - assert lib.seeme1("foo") == 0 + assert lib.seeme1(b"foo") == 0 assert lib.seeme1(None) == 1 assert lib.seeme2([42, 43]) == 0 assert lib.seeme2(None) == 1 From noreply at buildbot.pypy.org Thu Feb 28 17:28:08 2013 From: noreply at buildbot.pypy.org (fijal) Date: Thu, 28 Feb 2013 17:28:08 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: a test and a fix Message-ID: <20130228162808.A86E51C00A8@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61876:cf9ed3344df9 Date: 2013-02-28 18:27 +0200 http://bitbucket.org/pypy/pypy/changeset/cf9ed3344df9/ Log: a test and a fix diff --git a/rpython/jit/backend/llsupport/jitframe.py b/rpython/jit/backend/llsupport/jitframe.py --- a/rpython/jit/backend/llsupport/jitframe.py +++ b/rpython/jit/backend/llsupport/jitframe.py @@ -47,7 +47,14 @@ i += 1 return frame -JITFRAME = lltype.GcStruct( +def jitframe_resolve(frame): + while frame.jf_forward: + frame = frame.jf_forward + return frame + +JITFRAME = lltype.GcForwardReference() + +JITFRAME.become(lltype.GcStruct( 'JITFRAME', ('jf_frame_info', lltype.Ptr(JITFRAMEINFO)), # Once the execute_token() returns, the field 'jf_descr' stores the @@ -68,6 +75,8 @@ # RPython code that finishes the function with an exception, the # exception is not stored there, but is simply kept as a variable there) ('jf_guard_exc', llmemory.GCREF), + # in case the frame got reallocated, we have to forward it somewhere + ('jf_forward', lltype.Ptr(JITFRAME)), # absolutely useless field used to make up for tracing hooks inflexibilities ('jf_gc_trace_state', lltype.Signed), # the actual frame @@ -76,9 +85,10 @@ # about GCrefs here and not in frame info which might change adtmeths = { 'allocate': jitframe_allocate, + 'resolve': jitframe_resolve, }, rtti = True, -) +)) @specialize.memo() def getofs(name): diff --git a/rpython/jit/backend/llsupport/llmodel.py b/rpython/jit/backend/llsupport/llmodel.py --- a/rpython/jit/backend/llsupport/llmodel.py +++ b/rpython/jit/backend/llsupport/llmodel.py @@ -89,6 +89,7 @@ frame.jf_frame_info.set_frame_depth(base_ofs, size) new_frame = jitframe.JITFRAME.allocate(frame.jf_frame_info, self.JITFRAME_FIXED_SIZE) + frame.jf_forward = new_frame i = 0 while i < len(frame.jf_frame): new_frame.jf_frame[i] = frame.jf_frame[i] @@ -193,6 +194,7 @@ def force(self, addr_of_force_token): frame = rffi.cast(jitframe.JITFRAMEPTR, addr_of_force_token) + frame = frame.resolve() frame.jf_descr = frame.jf_force_descr return lltype.cast_opaque_ptr(llmemory.GCREF, frame) diff --git a/rpython/jit/backend/test/runner_test.py b/rpython/jit/backend/test/runner_test.py --- a/rpython/jit/backend/test/runner_test.py +++ b/rpython/jit/backend/test/runner_test.py @@ -3732,7 +3732,7 @@ def test_compile_bridge_while_running(self): def func(): bridge = parse(""" - [i1, i2] + [i1, i2, px] i3 = int_add(i1, i2) i4 = int_add(i1, i3) i5 = int_add(i1, i4) @@ -3750,7 +3750,7 @@ force_spill(i8) force_spill(i9) call(ConstClass(func2_ptr), 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, descr=calldescr2) - guard_true(i1, descr=guarddescr) [i1, i2, i3, i4, i5, i6, i7, i8, i9] + guard_true(i1, descr=guarddescr) [i1, i2, i3, i4, i5, i6, i7, i8, i9, px] finish(i1, descr=finaldescr) """, namespace={'finaldescr': finaldescr, 'calldescr2': calldescr2, 'guarddescr': guarddescr, 'func2_ptr': func2_ptr}) @@ -3783,7 +3783,8 @@ loop = parse(""" [i0, i1, i2] call(ConstClass(func_ptr), descr=calldescr) - guard_true(i0, descr=faildescr) [i1, i2] + px = force_token() + guard_true(i0, descr=faildescr) [i1, i2, px] finish(i2, descr=finaldescr2) """, namespace=locals()) self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) @@ -3796,6 +3797,11 @@ frame = lltype.cast_opaque_ptr(jitframe.JITFRAMEPTR, frame) assert len(frame.jf_frame) == frame.jf_frame_info.jfi_frame_depth + ref = self.cpu.get_ref_value(frame, 9) + token = lltype.cast_opaque_ptr(jitframe.JITFRAMEPTR, ref) + assert token != frame + token = token.resolve() + assert token == frame def test_compile_bridge_while_running_guard_no_exc(self): xtp = lltype.malloc(rclass.OBJECT_VTABLE, immortal=True) From noreply at buildbot.pypy.org Thu Feb 28 17:32:11 2013 From: noreply at buildbot.pypy.org (arigo) Date: Thu, 28 Feb 2013 17:32:11 +0100 (CET) Subject: [pypy-commit] cffi default: Change the hack: instead of passing None for NULL pointers, we pass 0. Message-ID: <20130228163211.37F681C0084@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: Changeset: r1176:d37c1ddac94c Date: 2013-02-28 17:31 +0100 http://bitbucket.org/cffi/cffi/changeset/d37c1ddac94c/ Log: Change the hack: instead of passing None for NULL pointers, we pass 0. This is more compatible with C. Also accept 0 at other places that expect a pointer. diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c --- a/c/_cffi_backend.c +++ b/c/_cffi_backend.c @@ -1120,6 +1120,11 @@ CTypeDescrObject *ctinit; if (!CData_Check(init)) { + if (PyIntOrLong_Check(init) && !PyObject_IsTrue(init)) { + /* convert 0 to NULL */ + *(char **)data = NULL; + return 0; + } expected = "cdata pointer"; goto cannot_convert; } @@ -1604,16 +1609,26 @@ char *v_cdata, *w_cdata; assert(CData_Check(v)); - if (!CData_Check(w)) - goto Unimplemented; - v_cdata = ((CDataObject *)v)->c_data; - w_cdata = ((CDataObject *)w)->c_data; + + if (!CData_Check(w)) { + if (PyIntOrLong_Check(w) && !PyObject_IsTrue(w) && + !(((CDataObject *)v)->c_type->ct_flags & CT_PRIMITIVE_ANY)) { + /* comparing a non-primitive with 0 */ + w_cdata = NULL; + goto compare; + } + pyres = Py_NotImplemented; + goto done; + } + if ((op != Py_EQ && op != Py_NE) && ((((CDataObject *)v)->c_type->ct_flags & CT_PRIMITIVE_ANY) || (((CDataObject *)w)->c_type->ct_flags & CT_PRIMITIVE_ANY))) goto Error; + w_cdata = ((CDataObject *)w)->c_data; + compare: switch (op) { case Py_EQ: res = (v_cdata == w_cdata); break; case Py_NE: res = (v_cdata != w_cdata); break; @@ -1628,10 +1643,6 @@ Py_INCREF(pyres); return pyres; - Unimplemented: - pyres = Py_NotImplemented; - goto done; - Error: PyErr_SetString(PyExc_TypeError, "cannot do comparison on a primitive cdata"); @@ -2067,7 +2078,12 @@ ctitem = ctptr->ct_itemdescr; /* XXX some code duplication, how to avoid it? */ - if (init == Py_None) { + if (PyIntOrLong_Check(init) && !PyObject_IsTrue(init)) { + /* Convert 0 to NULL. Note that passing 0 is not ambigous, + despite the potential confusion: as a 'T*' argument, 0 means + NULL, but as a 'T[]' argument it would mean "array of size 0" + --- except that we specifically refuse to interpret numbers + as the array size when passing arguments. */ *output_data = NULL; return 0; } diff --git a/c/test_c.py b/c/test_c.py --- a/c/test_c.py +++ b/c/test_c.py @@ -399,6 +399,19 @@ assert (x == ["hello"]) is False assert (x != ["hello"]) is True +def test_cmp_pointer_with_0(): + p = new_pointer_type(new_primitive_type("int")) + x = cast(p, 0) + assert (x == 0) is True + assert (x != 0) is False + assert (0 == x) is True + assert (0 != x) is False + y = cast(p, 42) + assert (y == 0) is False + assert (y != 0) is True + assert (0 == y) is False + assert (0 != y) is True + def test_invalid_indexing(): p = new_primitive_type("int") x = cast(p, 42) @@ -777,6 +790,7 @@ assert s.a2 == 456 assert s.a3 == 0 assert s.p4 == cast(BVoidP, 0) + assert s.p4 == 0 # s = newp(BStructPtr, {'a2': 41122, 'a3': -123}) assert s.a1 == 0 @@ -791,6 +805,9 @@ assert s.p4 == p # s = newp(BStructPtr, [12, 34, 56, cast(BVoidP, 0)]) + assert s.p4 == 0 + # + s = newp(BStructPtr, [12, 34, 56, 0]) assert s.p4 == cast(BVoidP, 0) # py.test.raises(TypeError, newp, BStructPtr, [12, 34, 56, None]) @@ -1009,8 +1026,12 @@ f = cast(BFunc23, _testfunc(23)) res = f(b"foo") assert res == 1000 * ord(b'f') - res = f(None) + res = f(0) # NULL assert res == -42 + res = f(long(0)) # NULL + assert res == -42 + py.test.raises(TypeError, f, None) + py.test.raises(TypeError, f, 0.0) def test_call_function_23_bis(): # declaring the function as int(unsigned char*) diff --git a/doc/source/index.rst b/doc/source/index.rst --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -1304,13 +1304,14 @@ | | a compatible type (i.e.| |``+``, ``-``, | | | same type or ``char*`` | |bool() | | | or ``void*``, or as an | | | -| | array instead) `(*)` | | | +| | array instead) `(*)`; | | | +| | or ``0`` `(******)` | | | +---------------+------------------------+ | | | ``void *``, | another with | | | | ``char *`` | any pointer or array | | | -| | type | | | +| | type; or ``0`` | | | +---------------+------------------------+ +----------------+ -| pointers to | same as pointers `(*)` | | ``[]``, ``+``, | +| pointers to | same as pointers | | ``[]``, ``+``, | | structure or | | | ``-``, bool(), | | union | | | and read/write | | | | | struct fields | @@ -1350,9 +1351,6 @@ you need to specify it in a list of length 1; for example, a ``struct foo *`` argument might be passed as ``[[field1, field2...]]``. -.. versionadded:: 0.6 - You can also pass None to ``item *`` arguments (meaning NULL). - As an optimization, the CPython version of CFFI assumes that a function with a ``char *`` argument to which you pass a Python string will not actually modify the array of characters passed in, and so passes directly @@ -1391,6 +1389,11 @@ If you really want to get their value as a string, use ``ffi.string(ffi.cast("the_enum_type", x.field))``. +.. versionadded:: 0.6 + `(******)` ``0`` is interpreted like ``ffi.NULL`` in most places. + It is the way both gcc and MSVC work. (Of course non-null integers + are not transparently interpreted as pointers; only ``0`` is.) + Reference: verifier ------------------- diff --git a/testing/test_verify.py b/testing/test_verify.py --- a/testing/test_verify.py +++ b/testing/test_verify.py @@ -1552,7 +1552,7 @@ p = ffi.new("char[]", b'\x10\x20\x30') assert lib.sum3chars(p) == b'\x60' -def test_passing_None(): +def test_passing_0_for_NULL(): ffi = FFI() ffi.cdef("int seeme1(char *); int seeme2(int *);") lib = ffi.verify(""" @@ -1564,6 +1564,12 @@ } """) assert lib.seeme1(b"foo") == 0 - assert lib.seeme1(None) == 1 + assert lib.seeme1(0) == 1 + assert lib.seeme1(long(0)) == 1 assert lib.seeme2([42, 43]) == 0 - assert lib.seeme2(None) == 1 + assert lib.seeme2(0) == 1 + assert lib.seeme2(long(0)) == 1 + py.test.raises(TypeError, lib.seeme1, None) + py.test.raises(TypeError, lib.seeme2, None) + py.test.raises(TypeError, lib.seeme1, 0.0) + py.test.raises(TypeError, lib.seeme2, 0.0) From noreply at buildbot.pypy.org Thu Feb 28 18:06:04 2013 From: noreply at buildbot.pypy.org (fijal) Date: Thu, 28 Feb 2013 18:06:04 +0100 (CET) Subject: [pypy-commit] pypy jitframe-on-heap: kill this hack Message-ID: <20130228170604.775571C07C6@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61877:912c74f224e9 Date: 2013-02-28 19:05 +0200 http://bitbucket.org/pypy/pypy/changeset/912c74f224e9/ Log: kill this hack diff --git a/rpython/jit/backend/llsupport/gc.py b/rpython/jit/backend/llsupport/gc.py --- a/rpython/jit/backend/llsupport/gc.py +++ b/rpython/jit/backend/llsupport/gc.py @@ -132,10 +132,10 @@ """ This functions retuns an arraydescr of type for the JITFRAME""" raise NotImplementedError - def malloc_jitframe(self, frame_info, staticsize): + def malloc_jitframe(self, frame_info): """ Allocate a new frame, overwritten by tests """ - frame = jitframe.JITFRAME.allocate(frame_info, staticsize) + frame = jitframe.JITFRAME.allocate(frame_info) llop.gc_assume_young_pointers(lltype.Void, frame) return frame diff --git a/rpython/jit/backend/llsupport/jitframe.py b/rpython/jit/backend/llsupport/jitframe.py --- a/rpython/jit/backend/llsupport/jitframe.py +++ b/rpython/jit/backend/llsupport/jitframe.py @@ -38,13 +38,9 @@ # the JITFRAME that's stored on the heap. See backend//arch.py for # detailed explanation how it is on your architecture -def jitframe_allocate(frame_info, staticsize): +def jitframe_allocate(frame_info): frame = lltype.malloc(JITFRAME, frame_info.jfi_frame_depth, zero=True) frame.jf_frame_info = frame_info - i = 0 - while i < staticsize: - frame.jf_frame[i] = 13 - i += 1 return frame def jitframe_resolve(frame): diff --git a/rpython/jit/backend/llsupport/llmodel.py b/rpython/jit/backend/llsupport/llmodel.py --- a/rpython/jit/backend/llsupport/llmodel.py +++ b/rpython/jit/backend/llsupport/llmodel.py @@ -87,8 +87,7 @@ # update the frame_info size, which is for whatever reason # not up to date frame.jf_frame_info.set_frame_depth(base_ofs, size) - new_frame = jitframe.JITFRAME.allocate(frame.jf_frame_info, - self.JITFRAME_FIXED_SIZE) + new_frame = jitframe.JITFRAME.allocate(frame.jf_frame_info) frame.jf_forward = new_frame i = 0 while i < len(frame.jf_frame): @@ -213,8 +212,7 @@ func = rffi.cast(FUNCPTR, addr) #llop.debug_print(lltype.Void, ">>>> Entering", addr) frame_info = clt.frame_info - frame = self.gc_ll_descr.malloc_jitframe(frame_info, - self.JITFRAME_FIXED_SIZE) + frame = self.gc_ll_descr.malloc_jitframe(frame_info) ll_frame = lltype.cast_opaque_ptr(llmemory.GCREF, frame) locs = executable_token.compiled_loop_token._ll_initial_locs prev_interpreter = None # help flow space diff --git a/rpython/jit/backend/llsupport/test/test_gc_integration.py b/rpython/jit/backend/llsupport/test/test_gc_integration.py --- a/rpython/jit/backend/llsupport/test/test_gc_integration.py +++ b/rpython/jit/backend/llsupport/test/test_gc_integration.py @@ -450,7 +450,7 @@ self.frames[-1].hdr |= 1 self.init_nursery() - def malloc_jitframe(self, frame_info, ignored): + def malloc_jitframe(self, frame_info): """ Allocate a new frame, overwritten by tests """ frame = JITFRAME.allocate(frame_info) From noreply at buildbot.pypy.org Thu Feb 28 18:27:47 2013 From: noreply at buildbot.pypy.org (fijal) Date: Thu, 28 Feb 2013 18:27:47 +0100 (CET) Subject: [pypy-commit] extradoc extradoc: add blog draft Message-ID: <20130228172747.B6A941C00A8@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: extradoc Changeset: r4943:a30a098ca596 Date: 2013-02-28 18:28 +0100 http://bitbucket.org/pypy/extradoc/changeset/a30a098ca596/ Log: add blog draft diff --git a/blog/draft/10years.rst b/blog/draft/10years.rst new file mode 100644 --- /dev/null +++ b/blog/draft/10years.rst @@ -0,0 +1,38 @@ +"From a software engineering perspective, 10 years is indistinguishable +from infinity, so I don't care what happens 10 years from now -- as +long as you don't blame me. :-)" - Guido van Rossum, Python creator. + +10 years is indeed a long time. PyPy was created approximately 10 years ago, +with the exact date being lost in the annals of the version control system. +We've come a long way during those 10 years, from a "minimal Python" that +was supposed to serve mostly as an educational tool, through to a vehicle for +academic research to a high performance VM for Python and beyond. + +Some facts from the PyPy timeline: + +* In 2007, at the end of the EU funding period, we promised the JIT was just around the corner. + It turned out we misjudged it pretty badly -- the first usable PyPy was released in 2010. + +* At some point we decided to have a JavaScript backend so one could compile RPython programs + to JavaScript and run them in a browser. Turned out it was a horrible idea. + +* Another option for using RPython was to write CPython C extensions. Again, turned out RPython + is a bad language and instead we made a fast JIT, so you don't have to write C extensions. + +* We made N attempts to use LLVM. Seriously, N is 4 or 5. But we haven't fully given up yet :-) + They all run into issues one way or another. + +* We were huge fans of ctypes from the beginning. Up to the point where we tried to make + a restricted subset with static types, called rctypes for RPython. Turned out to be horrible. + Twice. + +* We were very hopeful about JIT generator from the beginning. But the first one failed miserably, + generating too much assembler. The second failed too. The third first burned down and then failed. + However, we managed to release a working JIT in 2010, against all odds. + +* Martijn Faassen used to ask us "how fast is PyPy" so we decided to name an option enabling all + optimizations --faassen. --no-faassen was added automatically doing nothing. Then we + decided to grow up and renamed it to -O2 and -Ojit. + +Cheers, +fijal, arigo and the pypy team. From noreply at buildbot.pypy.org Thu Feb 28 18:30:27 2013 From: noreply at buildbot.pypy.org (fijal) Date: Thu, 28 Feb 2013 18:30:27 +0100 (CET) Subject: [pypy-commit] extradoc extradoc: add an item from cfbolz Message-ID: <20130228173027.4F8491C0084@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: extradoc Changeset: r4944:9fffdbec141b Date: 2013-02-28 19:30 +0200 http://bitbucket.org/pypy/extradoc/changeset/9fffdbec141b/ Log: add an item from cfbolz diff --git a/blog/draft/10years.rst b/blog/draft/10years.rst --- a/blog/draft/10years.rst +++ b/blog/draft/10years.rst @@ -34,5 +34,7 @@ optimizations --faassen. --no-faassen was added automatically doing nothing. Then we decided to grow up and renamed it to -O2 and -Ojit. +* the first time the Python interpreter successfully compiled to C, it segfaulted because the code generator used signed chars instead of unsigned chars + Cheers, fijal, arigo and the pypy team. From noreply at buildbot.pypy.org Thu Feb 28 18:30:28 2013 From: noreply at buildbot.pypy.org (fijal) Date: Thu, 28 Feb 2013 18:30:28 +0100 (CET) Subject: [pypy-commit] extradoc extradoc: add cfbolz Message-ID: <20130228173028.8367F1C0084@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: extradoc Changeset: r4945:be5782b4560a Date: 2013-02-28 19:30 +0200 http://bitbucket.org/pypy/extradoc/changeset/be5782b4560a/ Log: add cfbolz diff --git a/blog/draft/10years.rst b/blog/draft/10years.rst --- a/blog/draft/10years.rst +++ b/blog/draft/10years.rst @@ -37,4 +37,4 @@ * the first time the Python interpreter successfully compiled to C, it segfaulted because the code generator used signed chars instead of unsigned chars Cheers, -fijal, arigo and the pypy team. +fijal, arigo, cfbolz and the pypy team. From noreply at buildbot.pypy.org Thu Feb 28 18:37:03 2013 From: noreply at buildbot.pypy.org (lwassermann) Date: Thu, 28 Feb 2013 18:37:03 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: added two more bootstrappedimage tests, one of which will not work until #allInstancesDo: works Message-ID: <20130228173703.45B471C00A8@cobra.cs.uni-duesseldorf.de> Author: Lars Wassermann Branch: Changeset: r105:34f9ef52753a Date: 2013-02-27 15:02 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/34f9ef52753a/ Log: added two more bootstrappedimage tests, one of which will not work until #allInstancesDo: works diff --git a/spyvm/test/test_bootstrappedimage.py b/spyvm/test/test_bootstrappedimage.py --- a/spyvm/test/test_bootstrappedimage.py +++ b/spyvm/test/test_bootstrappedimage.py @@ -6,7 +6,7 @@ testhelper.setup_module(testhelper, filename='bootstrapped.image') -def test_retrieve_symbol(): +def test_symbol_asSymbol(): w_result = perform(testhelper.image.w_asSymbol, "asSymbol") assert w_result is testhelper.image.w_asSymbol @@ -14,11 +14,21 @@ w_result = perform(w("someString"), "asSymbol") assert w_result is not None assert w_result.as_string() == "someString" - -#def test_hazelnut(): -# from spyvm.test import test_miniimage -# setup_module(test_miniimage, filename='bootstrapped.image') -# test_miniimage.test_all_pointers_are_valid() -# test_miniimage.test_become() - #test_miniimage.test_special_classes0() +def test_retrieve_symbol(): + py.test.skip("This implementation is based on a working allInstancesDo -> implement primitive 77 and such") + """asSymbol + "This is the only place that new Symbols are created. A Symbol is created + if and only if there is not already a Symbol with its contents in existance." + Symbol + allInstancesDo: [ :sym | + self = sym + ifTrue: [ ^ sym ] ]. + ^ (Symbol basicNew: self size) initFrom: self""" + w_result = perform(w("someString"), "asSymbol") + w_anotherSymbol = perform(w("someString"), "asSymbol") + assert w_result is w_anotherSymbol + + +def test_all_pointers_are_valid(): + testhelper.test_all_pointers_are_valid() \ No newline at end of file From noreply at buildbot.pypy.org Thu Feb 28 18:37:04 2013 From: noreply at buildbot.pypy.org (lwassermann) Date: Thu, 28 Feb 2013 18:37:04 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: (tfel, lwassermann): added someInstance and nextInstance primitives Message-ID: <20130228173704.68BDD1C07C6@cobra.cs.uni-duesseldorf.de> Author: Lars Wassermann Branch: Changeset: r106:9aed68db55d8 Date: 2013-02-28 16:36 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/9aed68db55d8/ Log: (tfel, lwassermann): added someInstance and nextInstance primitives iterating over all instances works in test_bootstrappedimage>>#test_create_new_symbol diff --git a/spyvm/interpreter.py b/spyvm/interpreter.py --- a/spyvm/interpreter.py +++ b/spyvm/interpreter.py @@ -90,12 +90,20 @@ w_new_context = self.step(s_active_context) if w_new_context is not None: s_active_context = w_new_context.as_context_get_shadow(self.space) + # m = s_active_context.w_method() + # try: + # print m.literals[-1]._vars[-1], ">>", m._likely_methodname + # except IndexError, AttributeError: + # print "? >>", m._likely_methodname def perform(self, w_receiver, selector, *arguments_w): - if selector == "asSymbol": - w_selector = self.image.w_asSymbol + if isinstance(selector, str): + if selector == "asSymbol": + w_selector = self.image.w_asSymbol + else: + w_selector = self.perform(self.space.wrap_string(selector), "asSymbol") else: - w_selector = self.perform(self.space.wrap_string(selector), "asSymbol") + w_selector = selector w_method = model.W_CompiledMethod() w_method.setbytes([chr(124)]) #returnTopFromMethod diff --git a/spyvm/model.py b/spyvm/model.py --- a/spyvm/model.py +++ b/spyvm/model.py @@ -103,6 +103,12 @@ def clone(self, space): raise NotImplementedError + def has_class(self): + """All Smalltalk objects should have classes. Unfortuantely for + bootstrapping the metaclass-cycle and during testing, that is not + true for some W_PointersObjects""" + return True + class W_SmallInteger(W_Object): """Boxed integer value""" # TODO can we tell pypy that its never larger then 31-bit? @@ -210,7 +216,7 @@ Float).""" def __init__(self, w_class): - if w_class is not None: # it's None only for testing + if w_class is not None: # it's None only for testing and space generation assert isinstance(w_class, W_PointersObject) self.w_class = w_class @@ -237,6 +243,9 @@ def _become(self, w_other): self.w_class, w_other.w_class = w_other.w_class, self.w_class W_AbstractObjectWithIdentityHash._become(self, w_other) + + def has_class(self): + return self.w_class is not None class W_PointersObject(W_AbstractObjectWithClassReference): diff --git a/spyvm/primitives.py b/spyvm/primitives.py --- a/spyvm/primitives.py +++ b/spyvm/primitives.py @@ -445,13 +445,41 @@ # This primitive returns some instance of the class on the stack. # Not sure quite how to do this; maintain a weak list of all # existing instances or something? - raise PrimitiveNotYetWrittenError() + from rpython.rlib import rgc + + match_w = [] + roots = [gcref for gcref in rgc.get_rpy_roots() if gcref] + pending = roots[:] + while pending: + gcref = pending.pop() + if not rgc.get_gcflag_extra(gcref): + rgc.toggle_gcflag_extra(gcref) + w_obj = rgc.try_cast_gcref_to_instance(model.W_Object, gcref) + if (w_obj is not None and w_obj.has_class() + and w_obj.getclass(interp.space) is w_class): + match_w.append(w_obj) + pending.extend(rgc.get_rpy_referents(gcref)) + + while pending: + gcref = pending.pop() + if rgc.get_gcflag_extra(gcref): + rgc.toggle_gcflag_extra(gcref) + pending.extend(rgc.get_rpy_referents(gcref)) + + s_frame.store_instances_array(match_w) + try: + return match_w.pop() + except IndexError: + raise PrimitiveFailedError() @expose_primitive(NEXT_INSTANCE, unwrap_spec=[object]) def func(interp, s_frame, w_obj): # This primitive is used to iterate through all instances of a class: # it returns the "next" instance after w_obj. - raise PrimitiveNotYetWrittenError() + try: + return s_frame.instances_array().pop() + except IndexError: + raise PrimitiveFailedError() @expose_primitive(NEW_METHOD, unwrap_spec=[object, int, int]) def func(interp, s_frame, w_class, bytecount, header): diff --git a/spyvm/shadow.py b/spyvm/shadow.py --- a/spyvm/shadow.py +++ b/spyvm/shadow.py @@ -529,6 +529,13 @@ def tempsize(self): raise NotImplementedError() + def store_instances_array(self, list_w): + # used for primitives 77 & 78 + self.instances_w = list_w + + def instances_array(self): + return self.instances_w + class BlockContextShadow(ContextPartShadow): @staticmethod diff --git a/spyvm/test/test_bootstrappedimage.py b/spyvm/test/test_bootstrappedimage.py --- a/spyvm/test/test_bootstrappedimage.py +++ b/spyvm/test/test_bootstrappedimage.py @@ -1,22 +1,38 @@ import py from spyvm import squeakimage, model, constants from spyvm import interpreter, shadow, objspace -from spyvm.test import test_miniimage as testhelper +from spyvm.test import test_miniimage as tools from spyvm.test.test_miniimage import perform, w -testhelper.setup_module(testhelper, filename='bootstrapped.image') +tools.setup_module(tools, filename='bootstrapped.image') + +def find_symbol_in_methoddict_of(string, s_class): + methoddict_w = s_class.s_methoddict().methoddict + for each in methoddict_w.keys(): + if each.as_string() == string: + return each + +def initialize_class(w_class): + initialize_symbol = find_symbol_in_methoddict_of("initialize", + w_class.shadow_of_my_class(tools.space)) + perform(w_class, initialize_symbol) + def test_symbol_asSymbol(): - w_result = perform(testhelper.image.w_asSymbol, "asSymbol") - assert w_result is testhelper.image.w_asSymbol + w_result = perform(tools.image.w_asSymbol, "asSymbol") + assert w_result is tools.image.w_asSymbol def test_create_new_symbol(): - w_result = perform(w("someString"), "asSymbol") + string = w("someString") + # initialize String class + initialize_class(string.getclass(tools.space)) + + w_result = perform(string, "asSymbol") assert w_result is not None assert w_result.as_string() == "someString" def test_retrieve_symbol(): - py.test.skip("This implementation is based on a working allInstancesDo -> implement primitive 77 and such") + py.test.skip("unknown stack error") """asSymbol "This is the only place that new Symbols are created. A Symbol is created if and only if there is not already a Symbol with its contents in existance." @@ -25,10 +41,10 @@ self = sym ifTrue: [ ^ sym ] ]. ^ (Symbol basicNew: self size) initFrom: self""" + initialize_class(w("ab").getclass(tools.space)) w_result = perform(w("someString"), "asSymbol") w_anotherSymbol = perform(w("someString"), "asSymbol") assert w_result is w_anotherSymbol - def test_all_pointers_are_valid(): - testhelper.test_all_pointers_are_valid() \ No newline at end of file + tools.test_all_pointers_are_valid() diff --git a/spyvm/test/test_primitives.py b/spyvm/test/test_primitives.py --- a/spyvm/test/test_primitives.py +++ b/spyvm/test/test_primitives.py @@ -18,6 +18,7 @@ s_self.reset_stack() s_self.push_all(stack) s_self.store_expected_argument_count(0) + self.w_class = space.w_MethodContext def as_blockcontext_get_shadow(self): self._shadow = shadow.BlockContextShadow(space, self) @@ -509,6 +510,29 @@ assert s_new_context.gettemp(1) == "second arg" assert s_new_context.gettemp(2) == "some value" +def test_primitive_some_instance(): + someInstance = map(space.wrap_list, [[1], [2]]) + w_r = prim(primitives.SOME_INSTANCE, [space.w_Array]) + assert w_r.getclass(space) is space.w_Array + +def test_primitive_next_instance(): + someInstances = map(space.wrap_list, [[2], [3]]) + from test_interpreter import new_frame + w_frame, s_context = new_frame("", + space=space) + + s_context.push(space.w_Array) + interp = interpreter.Interpreter(space) + prim_table[primitives.SOME_INSTANCE](interp, s_context, 0) + w_1 = s_context.pop() + assert w_1.getclass(space) is space.w_Array + + s_context.push(w_1) + prim_table[primitives.NEXT_INSTANCE](interp, s_context, 0) + w_2 = s_context.pop() + assert w_2.getclass(space) is space.w_Array + assert w_1 is not w_2 + # Note: # primitives.NEXT is unimplemented as it is a performance optimization # primitives.NEXT_PUT is unimplemented as it is a performance optimization From noreply at buildbot.pypy.org Thu Feb 28 18:37:05 2013 From: noreply at buildbot.pypy.org (lwassermann) Date: Thu, 28 Feb 2013 18:37:05 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: fixed a problem with nonlockal returns due to the new context-handling Message-ID: <20130228173705.772821C00A8@cobra.cs.uni-duesseldorf.de> Author: Lars Wassermann Branch: Changeset: r107:43d730a9efde Date: 2013-02-28 18:36 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/43d730a9efde/ Log: fixed a problem with nonlockal returns due to the new context- handling moved the tests around, because for an unknown reason, they will not work in the other order... factored out MethodContextShadow>>is_closure_context added some printing help refactored kronos tracing code (Interpreter>>loop) diff --git a/spyvm/interpreter.py b/spyvm/interpreter.py --- a/spyvm/interpreter.py +++ b/spyvm/interpreter.py @@ -90,11 +90,8 @@ w_new_context = self.step(s_active_context) if w_new_context is not None: s_active_context = w_new_context.as_context_get_shadow(self.space) - # m = s_active_context.w_method() - # try: - # print m.literals[-1]._vars[-1], ">>", m._likely_methodname - # except IndexError, AttributeError: - # print "? >>", m._likely_methodname + #method = s_active_context.w_method() + #print method.get_identifier_string() def perform(self, w_receiver, selector, *arguments_w): if isinstance(selector, str): diff --git a/spyvm/model.py b/spyvm/model.py --- a/spyvm/model.py +++ b/spyvm/model.py @@ -504,7 +504,7 @@ def as_string(self, markBytecode=0): from spyvm.interpreter import BYTECODE_TABLE j = 1 - retval = "\nMethodname: " + self._likely_methodname + retval = "\nMethodname: " + self.get_identifier_string() retval += "\nBytecode:------------\n" for i in self.bytes: retval += '->' if j is markBytecode else ' ' @@ -512,6 +512,13 @@ j += 1 return retval + "---------------------\n" + def get_identifier_string(self): + try: + classname = self.literals[-1]._shadow.getname() + except (IndexError, AttributeError): + classname = "" + return "%s>>#%s" % (classname, self._likely_methodname) + def invariant(self): return (W_Object.invariant(self) and hasattr(self, 'literals') and diff --git a/spyvm/shadow.py b/spyvm/shadow.py --- a/spyvm/shadow.py +++ b/spyvm/shadow.py @@ -701,7 +701,7 @@ ContextPartShadow.attach_shadow(self) def tempsize(self): - if self.w_closure_or_nil == self.space.w_nil: + if not self.is_closure_context(): return self.method().tempsize else: return wrapper.BlockClosureWrapper(self.space, @@ -743,18 +743,21 @@ return self.size() - self.tempsize() def returnTopFromMethod(self, interp, current_bytecode): - if self.w_closure_or_nil is not self.space.w_nil: + if self.is_closure_context(): # this is a context for a blockClosure s_outerContext = self.w_closure_or_nil.fetch(self.space, constants.BLKCLSR_OUTER_CONTEXT).get_shadow(self.space) # XXX check whether we can actually return from that context if s_outerContext.pc() == -1: raise error.BlockCannotReturnError() - s_outerContext._return(self.top(), interp, + return s_outerContext._return(self.top(), interp, s_outerContext.s_home().w_sender()) else: return self._return(self.top(), interp, self.s_home().w_sender()) + def is_closure_context(self): + return self.w_closure_or_nil is not self.space.w_nil + def __str__(self): retval = '\nMethodContext of:' retval += self.w_method().as_string(markBytecode=self.pc() + 1) diff --git a/spyvm/test/test_bootstrappedimage.py b/spyvm/test/test_bootstrappedimage.py --- a/spyvm/test/test_bootstrappedimage.py +++ b/spyvm/test/test_bootstrappedimage.py @@ -17,22 +17,14 @@ w_class.shadow_of_my_class(tools.space)) perform(w_class, initialize_symbol) +#initialize String class, because equality testing requires a class var set. +initialize_class(w("string").getclass(tools.space)) def test_symbol_asSymbol(): w_result = perform(tools.image.w_asSymbol, "asSymbol") assert w_result is tools.image.w_asSymbol -def test_create_new_symbol(): - string = w("someString") - # initialize String class - initialize_class(string.getclass(tools.space)) - - w_result = perform(string, "asSymbol") - assert w_result is not None - assert w_result.as_string() == "someString" - def test_retrieve_symbol(): - py.test.skip("unknown stack error") """asSymbol "This is the only place that new Symbols are created. A Symbol is created if and only if there is not already a Symbol with its contents in existance." @@ -41,10 +33,14 @@ self = sym ifTrue: [ ^ sym ] ]. ^ (Symbol basicNew: self size) initFrom: self""" - initialize_class(w("ab").getclass(tools.space)) w_result = perform(w("someString"), "asSymbol") w_anotherSymbol = perform(w("someString"), "asSymbol") assert w_result is w_anotherSymbol +def test_create_new_symbol(): + w_result = perform(w("someString"), "asSymbol") + assert w_result is not None + assert w_result.as_string() == "someString" + def test_all_pointers_are_valid(): tools.test_all_pointers_are_valid() From noreply at buildbot.pypy.org Thu Feb 28 18:49:28 2013 From: noreply at buildbot.pypy.org (arigo) Date: Thu, 28 Feb 2013 18:49:28 +0100 (CET) Subject: [pypy-commit] extradoc extradoc: A conclusion that talks about the future. Message-ID: <20130228174928.2F64C1C0084@cobra.cs.uni-duesseldorf.de> Author: Armin Rigo Branch: extradoc Changeset: r4946:c13df8eae420 Date: 2013-02-28 18:49 +0100 http://bitbucket.org/pypy/extradoc/changeset/c13df8eae420/ Log: A conclusion that talks about the future. diff --git a/blog/draft/10years.rst b/blog/draft/10years.rst --- a/blog/draft/10years.rst +++ b/blog/draft/10years.rst @@ -22,7 +22,7 @@ * We made N attempts to use LLVM. Seriously, N is 4 or 5. But we haven't fully given up yet :-) They all run into issues one way or another. -* We were huge fans of ctypes from the beginning. Up to the point where we tried to make +* We were huge fans of ctypes at the beginning. Up to the point where we tried to make a restricted subset with static types, called rctypes for RPython. Turned out to be horrible. Twice. @@ -31,10 +31,16 @@ However, we managed to release a working JIT in 2010, against all odds. * Martijn Faassen used to ask us "how fast is PyPy" so we decided to name an option enabling all - optimizations --faassen. --no-faassen was added automatically doing nothing. Then we - decided to grow up and renamed it to -O2 and -Ojit. + optimizations "--faassen". Then "--no-faassen" was naturally added too. Then we + decided to grow up and renamed it to "-O2", and now "-Ojit". -* the first time the Python interpreter successfully compiled to C, it segfaulted because the code generator used signed chars instead of unsigned chars +* the first time the Python interpreter successfully compiled to C, it segfaulted because the code generator used signed chars instead of unsigned chars... + +Overall, it was a really long road. However, 10 years later we are in +good shape. A quick look on the immediate future: we are approaching +PyPy 2.0, the support for Python 3 is taking shape, non-standard +extensions like STM are slowly getting ready (more soon), and there are +several non-Python interpreters around the corner (Topaz and more). Cheers, fijal, arigo, cfbolz and the pypy team. From noreply at buildbot.pypy.org Thu Feb 28 18:57:28 2013 From: noreply at buildbot.pypy.org (hodgestar) Date: Thu, 28 Feb 2013 18:57:28 +0100 (CET) Subject: [pypy-commit] extradoc extradoc: Tweak language a bit. Message-ID: <20130228175728.852221C00A8@cobra.cs.uni-duesseldorf.de> Author: Simon Cross Branch: extradoc Changeset: r4947:b28691743c94 Date: 2013-02-28 19:53 +0200 http://bitbucket.org/pypy/extradoc/changeset/b28691743c94/ Log: Tweak language a bit. diff --git a/blog/draft/10years.rst b/blog/draft/10years.rst --- a/blog/draft/10years.rst +++ b/blog/draft/10years.rst @@ -16,7 +16,7 @@ * At some point we decided to have a JavaScript backend so one could compile RPython programs to JavaScript and run them in a browser. Turned out it was a horrible idea. -* Another option for using RPython was to write CPython C extensions. Again, turned out RPython +* Another option we tried was using RPython to write CPython C extensions. Again, it turned out RPython is a bad language and instead we made a fast JIT, so you don't have to write C extensions. * We made N attempts to use LLVM. Seriously, N is 4 or 5. But we haven't fully given up yet :-) @@ -26,15 +26,15 @@ a restricted subset with static types, called rctypes for RPython. Turned out to be horrible. Twice. -* We were very hopeful about JIT generator from the beginning. But the first one failed miserably, +* We were very hopeful about creating a JIT generator from the beginning. But the first one failed miserably, generating too much assembler. The second failed too. The third first burned down and then failed. However, we managed to release a working JIT in 2010, against all odds. * Martijn Faassen used to ask us "how fast is PyPy" so we decided to name an option enabling all - optimizations --faassen. --no-faassen was added automatically doing nothing. Then we + optimizations --faassen. --no-faassen was added automatically doing nothing. Later we decided to grow up and renamed it to -O2 and -Ojit. -* the first time the Python interpreter successfully compiled to C, it segfaulted because the code generator used signed chars instead of unsigned chars +* The first time the Python interpreter successfully compiled to C, it segfaulted because the code generator used signed chars instead of unsigned chars. Cheers, fijal, arigo, cfbolz and the pypy team. From noreply at buildbot.pypy.org Thu Feb 28 18:57:29 2013 From: noreply at buildbot.pypy.org (hodgestar) Date: Thu, 28 Feb 2013 18:57:29 +0100 (CET) Subject: [pypy-commit] extradoc extradoc: Merge changes. Message-ID: <20130228175729.B84E51C00A8@cobra.cs.uni-duesseldorf.de> Author: Simon Cross Branch: extradoc Changeset: r4948:11c4aa1b3954 Date: 2013-02-28 19:57 +0200 http://bitbucket.org/pypy/extradoc/changeset/11c4aa1b3954/ Log: Merge changes. diff --git a/blog/draft/10years.rst b/blog/draft/10years.rst --- a/blog/draft/10years.rst +++ b/blog/draft/10years.rst @@ -22,7 +22,7 @@ * We made N attempts to use LLVM. Seriously, N is 4 or 5. But we haven't fully given up yet :-) They all run into issues one way or another. -* We were huge fans of ctypes from the beginning. Up to the point where we tried to make +* We were huge fans of ctypes at the beginning. Up to the point where we tried to make a restricted subset with static types, called rctypes for RPython. Turned out to be horrible. Twice. @@ -31,10 +31,16 @@ However, we managed to release a working JIT in 2010, against all odds. * Martijn Faassen used to ask us "how fast is PyPy" so we decided to name an option enabling all - optimizations --faassen. --no-faassen was added automatically doing nothing. Later we - decided to grow up and renamed it to -O2 and -Ojit. + optimizations "--faassen". Then "--no-faassen" was naturally added too. Later we + decided to grow up and renamed it to "-O2", and now "-Ojit". -* The first time the Python interpreter successfully compiled to C, it segfaulted because the code generator used signed chars instead of unsigned chars. +* The first time the Python interpreter successfully compiled to C, it segfaulted because the code generator used signed chars instead of unsigned chars... + +Overall, it was a really long road. However, 10 years later we are in +good shape. A quick look on the immediate future: we are approaching +PyPy 2.0, the support for Python 3 is taking shape, non-standard +extensions like STM are slowly getting ready (more soon), and there are +several non-Python interpreters around the corner (Topaz and more). Cheers, fijal, arigo, cfbolz and the pypy team. From noreply at buildbot.pypy.org Thu Feb 28 18:57:43 2013 From: noreply at buildbot.pypy.org (fijal) Date: Thu, 28 Feb 2013 18:57:43 +0100 (CET) Subject: [pypy-commit] jitviewer default: a bit more robustness Message-ID: <20130228175743.5C9081C00A8@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r212:8bfab62f5e3b Date: 2013-02-28 19:55 +0200 http://bitbucket.org/pypy/jitviewer/changeset/8bfab62f5e3b/ Log: a bit more robustness diff --git a/_jitviewer/app.py b/_jitviewer/app.py --- a/_jitviewer/app.py +++ b/_jitviewer/app.py @@ -44,7 +44,10 @@ import inspect import threading import time -from rpython.tool.logparser import extract_category +try: + from rpython.tool.logparser import extract_category +except ImportError: + from pypy.tool.logparser import extract_category from pypy.tool.jitlogparser.storage import LoopStorage from pypy.tool.jitlogparser.parser import adjust_bridges, import_log,\ parse_log_counts From noreply at buildbot.pypy.org Thu Feb 28 18:57:44 2013 From: noreply at buildbot.pypy.org (fijal) Date: Thu, 28 Feb 2013 18:57:44 +0100 (CET) Subject: [pypy-commit] jitviewer default: update the info Message-ID: <20130228175744.6190F1C00A8@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: Changeset: r213:9c394673f2d7 Date: 2013-02-28 19:57 +0200 http://bitbucket.org/pypy/jitviewer/changeset/9c394673f2d7/ Log: update the info diff --git a/README b/README --- a/README +++ b/README @@ -6,13 +6,13 @@ On Mac OSX you will also need to install binutils, to make objdump available. -To create a virtualenv: +To create a virtualenv (note that mkvirtualenv only accepts absolute paths): mkvirtualenv --python=/path/to/pypy pypy-viewer Now install the dependencies: - pip install flask pygments simplejson + pip install -r requirements.txt or From noreply at buildbot.pypy.org Thu Feb 28 19:03:12 2013 From: noreply at buildbot.pypy.org (fijal) Date: Thu, 28 Feb 2013 19:03:12 +0100 (CET) Subject: [pypy-commit] pypy.org extradoc: update info about stackless Message-ID: <20130228180312.146B31C01A7@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: extradoc Changeset: r377:e762a2552cb6 Date: 2013-02-28 20:02 +0200 http://bitbucket.org/pypy/pypy.org/changeset/e762a2552cb6/ Log: update info about stackless diff --git a/features.html b/features.html --- a/features.html +++ b/features.html @@ -90,7 +90,9 @@

Support for Stackless and greenlets are now integrated in the normal PyPy. More detailed information is available here.

Note that there is still an important performance hit for programs using -Stackless features.

+Stackless features. Also, as of 2.0 beta 1 (and any previous version), +there are known crashes of stackless features. We're working on improving +the situation for 2.0 final and enabling the JIT.

Other features

diff --git a/source/features.txt b/source/features.txt --- a/source/features.txt +++ b/source/features.txt @@ -75,7 +75,9 @@ PyPy. More detailed information is available here__. Note that there is still an important performance hit for programs using -Stackless features. +Stackless features. Also, as of 2.0 beta 1 (and any previous version), +there are known crashes of stackless features. We're working on improving +the situation for 2.0 final and enabling the JIT. .. _Stackless: http://www.stackless.com/ .. __: http://doc.pypy.org/en/latest/stackless.html From noreply at buildbot.pypy.org Thu Feb 28 19:03:13 2013 From: noreply at buildbot.pypy.org (fijal) Date: Thu, 28 Feb 2013 19:03:13 +0100 (CET) Subject: [pypy-commit] pypy.org extradoc: merge Message-ID: <20130228180313.403901C01A7@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: extradoc Changeset: r378:b505e6f833ef Date: 2013-02-28 20:03 +0200 http://bitbucket.org/pypy/pypy.org/changeset/b505e6f833ef/ Log: merge diff --git a/download.html b/download.html --- a/download.html +++ b/download.html @@ -79,7 +79,9 @@
  • Linux binary (64bit) (libc 2.13)
  • Linux ARM binary
  • Mac OS/X binary (64bit)
  • -
  • Windows binary (32bit) (you need the VS 2008 runtime library installer vcredist_x86.exe. Updated: the previous version required another runtime)
  • +
  • Windows binary (32bit) (you need the VS 2008 runtime library +installer vcredist_x86.exe. Updated again: the previous version +required two runtime libs)
  • @@ -148,10 +150,12 @@
  • Enter the goal directory:

    -cd pypy/pypy/translator/goal
    +cd pypy/pypy/translator/goal      # release 2.0-beta-1
    +cd pypy/pypy/goal                 # current trunk
     
  • -
  • Run the translate.py script. Here are the common combinations +

  • Run the translate.py script (called rpython.py in the current +trunk). Here are the common combinations of options (works also with python instead of pypy):

     pypy translate.py -Ojit                # get the JIT version
    @@ -159,6 +163,10 @@
     pypy translate.py -O2 --sandbox        # get the sandbox version
     pypy translate.py -Ojit --backend=cli  # only for branch/cli-jit
     
    +

    Or with the current trunk:

    +
    +../../rpython/bin/rpython -Ojit        # or -O2, etc.
    +
  • Enjoy Mandelbrot :-) It takes on the order of half an hour to finish the translation, and 2.x GB of RAM on a 32-bit system @@ -209,7 +217,7 @@ a1505520c063c591b218e5cd3436b111 pypy-2.0-beta1-linux-armel.tar.bz2 5aa2e4eee1c3dab86e5cec237776ced3 pypy-2.0-beta1-linux.tar.bz2 2802a06cd19ac86930b63afdd837c32f pypy-2.0-beta1-osx64.tar.bz2 -e46e1c20da6a2d15e34a6ef9afca311f pypy-2.0-beta1-win32.zip +a34dcd53537aaba0bed69d47f492ac73 pypy-2.0-beta1.1-win32.zip 201d2cce2557e40c784473b471ee1b6b pypy-1.9-linux64.tar.bz2 1a08c88642434fc2e0e4256d351f48db pypy-1.9-linux.tar.bz2 aad9c4b7b827583e37fe8ae0f7cfe0ff pypy-1.9-osx64.tar.bz2 @@ -223,7 +231,7 @@ 5682358c775e90dbc3636dbb0f6158675ecf5357 pypy-2.0-beta1-linux-armel.tar.bz2 ede5788f282072bc410019fb26c732f55f0b33ff pypy-2.0-beta1-linux.tar.bz2 e4938fdf33072e457fee6cb22798ec08b5a01978 pypy-2.0-beta1-osx64.tar.bz2 -d456efdbe2e66cff8410d9e69dda88b16e212c9e pypy-2.0-beta1-win32.zip +152ab10da55ed9f8c8a21b5cb4e67ee2ff4005fa pypy-2.0-beta1.1-win32.zip 51be6b7b802a5239a759e04ae9595082e17c4c70 pypy-1.9-linux64.tar.bz2 1bc5d2467039b954f9b7395b3ee1b8407ce1c057 pypy-1.9-linux.tar.bz2 825e15724419fbdb6fe215eeea044f9181883c90 pypy-1.9-osx64.tar.bz2 diff --git a/source/download.txt b/source/download.txt --- a/source/download.txt +++ b/source/download.txt @@ -52,14 +52,16 @@ * `Linux binary (64bit) (libc 2.13)`__ * `Linux ARM binary`__ * `Mac OS/X binary (64bit)`__ -* `Windows binary (32bit)`__ (you need the `VS 2008 runtime library installer vcredist_x86.exe`_. *Updated:* the previous version required another runtime) +* `Windows binary (32bit)`__ (you need the `VS 2008 runtime library + installer vcredist_x86.exe`_. *Updated again:* the previous version + required two runtime libs) .. __: https://bitbucket.org/pypy/pypy/downloads/pypy-2.0-beta1-linux.tar.bz2 .. __: https://bitbucket.org/pypy/pypy/downloads/pypy-2.0-beta1-linux64-libc2.15.tar.bz2 .. __: https://bitbucket.org/pypy/pypy/downloads/pypy-2.0-beta1-linux64-libc2.13.tar.bz2 .. __: https://bitbucket.org/pypy/pypy/downloads/pypy-2.0-beta1-linux-armel.tar.bz2 .. __: https://bitbucket.org/pypy/pypy/downloads/pypy-2.0-beta1-osx64.tar.bz2 -.. __: https://bitbucket.org/pypy/pypy/downloads/pypy-2.0-beta1-win32.zip +.. __: https://bitbucket.org/pypy/pypy/downloads/pypy-2.0-beta1.1-win32.zip .. _`VS 2008 runtime library installer vcredist_x86.exe`: http://www.microsoft.com/en-us/download/details.aspx?id=5582 1.9 @@ -154,9 +156,11 @@ 3. Enter the ``goal`` directory:: - cd pypy/pypy/translator/goal + cd pypy/pypy/translator/goal # release 2.0-beta-1 + cd pypy/pypy/goal # current trunk -4. Run the ``translate.py`` script. Here are the common combinations +4. Run the ``translate.py`` script (called ``rpython.py`` in the current + trunk). Here are the common combinations of options (works also with ``python`` instead of ``pypy``):: pypy translate.py -Ojit # get the JIT version @@ -164,6 +168,10 @@ pypy translate.py -O2 --sandbox # get the sandbox version pypy translate.py -Ojit --backend=cli # only for branch/cli-jit + Or with the current trunk:: + + ../../rpython/bin/rpython -Ojit # or -O2, etc. + 5. Enjoy Mandelbrot ``:-)`` It takes on the order of half an hour to finish the translation, and 2.x GB of RAM on a 32-bit system and 4.x GB on 64-bit systems. (Do not start a translation on a @@ -222,7 +230,7 @@ a1505520c063c591b218e5cd3436b111 pypy-2.0-beta1-linux-armel.tar.bz2 5aa2e4eee1c3dab86e5cec237776ced3 pypy-2.0-beta1-linux.tar.bz2 2802a06cd19ac86930b63afdd837c32f pypy-2.0-beta1-osx64.tar.bz2 - e46e1c20da6a2d15e34a6ef9afca311f pypy-2.0-beta1-win32.zip + a34dcd53537aaba0bed69d47f492ac73 pypy-2.0-beta1.1-win32.zip 201d2cce2557e40c784473b471ee1b6b pypy-1.9-linux64.tar.bz2 1a08c88642434fc2e0e4256d351f48db pypy-1.9-linux.tar.bz2 aad9c4b7b827583e37fe8ae0f7cfe0ff pypy-1.9-osx64.tar.bz2 @@ -237,7 +245,7 @@ 5682358c775e90dbc3636dbb0f6158675ecf5357 pypy-2.0-beta1-linux-armel.tar.bz2 ede5788f282072bc410019fb26c732f55f0b33ff pypy-2.0-beta1-linux.tar.bz2 e4938fdf33072e457fee6cb22798ec08b5a01978 pypy-2.0-beta1-osx64.tar.bz2 - d456efdbe2e66cff8410d9e69dda88b16e212c9e pypy-2.0-beta1-win32.zip + 152ab10da55ed9f8c8a21b5cb4e67ee2ff4005fa pypy-2.0-beta1.1-win32.zip 51be6b7b802a5239a759e04ae9595082e17c4c70 pypy-1.9-linux64.tar.bz2 1bc5d2467039b954f9b7395b3ee1b8407ce1c057 pypy-1.9-linux.tar.bz2 825e15724419fbdb6fe215eeea044f9181883c90 pypy-1.9-osx64.tar.bz2 From noreply at buildbot.pypy.org Thu Feb 28 19:18:34 2013 From: noreply at buildbot.pypy.org (lwassermann) Date: Thu, 28 Feb 2013 19:18:34 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: added benchFib test Message-ID: <20130228181834.292981C4843@cobra.cs.uni-duesseldorf.de> Author: Lars Wassermann Branch: Changeset: r108:e905c7889e43 Date: 2013-02-28 19:18 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/e905c7889e43/ Log: added benchFib test diff --git a/spyvm/test/test_bootstrappedimage.py b/spyvm/test/test_bootstrappedimage.py --- a/spyvm/test/test_bootstrappedimage.py +++ b/spyvm/test/test_bootstrappedimage.py @@ -44,3 +44,13 @@ def test_all_pointers_are_valid(): tools.test_all_pointers_are_valid() + tools.test_lookup_abs_in_integer() + +def test_tinyBenchmarks(): + # we can't find PCSystem, because Smalltalkdict is nil... + import time + t0 = time.time() + sends = perform(w(20), 'benchFib') + t1 = time.time() + t = t1 - t0 + print str(tools.space.unwrap_int(sends)/t) + " sends per second" \ No newline at end of file From noreply at buildbot.pypy.org Thu Feb 28 19:32:11 2013 From: noreply at buildbot.pypy.org (pjenvey) Date: Thu, 28 Feb 2013 19:32:11 +0100 (CET) Subject: [pypy-commit] pypy py3k: merge default Message-ID: <20130228183211.35E871C01A7@cobra.cs.uni-duesseldorf.de> Author: Philip Jenvey Branch: py3k Changeset: r61878:f42187637524 Date: 2013-02-28 10:31 -0800 http://bitbucket.org/pypy/pypy/changeset/f42187637524/ Log: merge default diff too long, truncating to 2000 out of 8850 lines diff --git a/.hgignore b/.hgignore --- a/.hgignore +++ b/.hgignore @@ -35,39 +35,43 @@ ^pypy/doc/config/.+\.rst$ ^pypy/doc/basicblock\.asc$ ^pypy/doc/.+\.svninfo$ -^pypy/translator/c/src/libffi_msvc/.+\.obj$ -^pypy/translator/c/src/libffi_msvc/.+\.dll$ -^pypy/translator/c/src/libffi_msvc/.+\.lib$ -^pypy/translator/c/src/libffi_msvc/.+\.exp$ -^pypy/translator/c/src/cjkcodecs/.+\.o$ -^pypy/translator/c/src/cjkcodecs/.+\.obj$ -^pypy/translator/jvm/\.project$ -^pypy/translator/jvm/\.classpath$ -^pypy/translator/jvm/eclipse-bin$ -^pypy/translator/jvm/src/pypy/.+\.class$ -^pypy/translator/benchmark/docutils$ -^pypy/translator/benchmark/templess$ -^pypy/translator/benchmark/gadfly$ -^pypy/translator/benchmark/mako$ -^pypy/translator/benchmark/bench-custom\.benchmark_result$ -^pypy/translator/benchmark/shootout_benchmarks$ -^pypy/translator/goal/pypy-translation-snapshot$ -^pypy/translator/goal/pypy-c -^pypy/translator/goal/pypy-jvm -^pypy/translator/goal/pypy-jvm.jar -^pypy/translator/goal/.+\.exe$ -^pypy/translator/goal/.+\.dll$ -^pypy/translator/goal/target.+-c$ +^rpython/translator/c/src/libffi_msvc/.+\.obj$ +^rpython/translator/c/src/libffi_msvc/.+\.dll$ +^rpython/translator/c/src/libffi_msvc/.+\.lib$ +^rpython/translator/c/src/libffi_msvc/.+\.exp$ +^rpython/translator/c/src/cjkcodecs/.+\.o$ +^rpython/translator/c/src/cjkcodecs/.+\.obj$ +^rpython/translator/c/src/stacklet/.+\.o$ +^rpython/translator/c/src/.+\.o$ +^rpython/translator/jvm/\.project$ +^rpython/translator/jvm/\.classpath$ +^rpython/translator/jvm/eclipse-bin$ +^rpython/translator/jvm/src/pypy/.+\.class$ +^rpython/translator/benchmark/docutils$ +^rpython/translator/benchmark/templess$ +^rpython/translator/benchmark/gadfly$ +^rpython/translator/benchmark/mako$ +^rpython/translator/benchmark/bench-custom\.benchmark_result$ +^rpython/translator/benchmark/shootout_benchmarks$ +^rpython/translator/goal/target.+-c$ +^rpython/translator/goal/.+\.exe$ +^rpython/translator/goal/.+\.dll$ +^pypy/goal/pypy-translation-snapshot$ +^pypy/goal/pypy-c +^pypy/goal/pypy-jvm +^pypy/goal/pypy-jvm.jar +^pypy/goal/.+\.exe$ +^pypy/goal/.+\.dll$ ^pypy/_cache$ ^pypy/doc/statistic/.+\.html$ ^pypy/doc/statistic/.+\.eps$ ^pypy/doc/statistic/.+\.pdf$ -^pypy/translator/cli/src/pypylib\.dll$ -^pypy/translator/cli/src/query\.exe$ -^pypy/translator/cli/src/main\.exe$ +^rpython/translator/cli/src/pypylib\.dll$ +^rpython/translator/cli/src/query\.exe$ +^rpython/translator/cli/src/main\.exe$ ^lib_pypy/ctypes_config_cache/_.+_cache\.py$ ^lib_pypy/ctypes_config_cache/_.+_.+_\.py$ -^pypy/translator/cli/query-descriptions$ +^rpython/translator/cli/query-descriptions$ ^pypy/doc/discussion/.+\.html$ ^include/.+\.h$ ^include/.+\.inl$ diff --git a/lib_pypy/numpypy/core/__init__.py b/lib_pypy/numpypy/core/__init__.py --- a/lib_pypy/numpypy/core/__init__.py +++ b/lib_pypy/numpypy/core/__init__.py @@ -1,18 +1,14 @@ -import _numpypy -from _numpypy import * import numeric from numeric import * import fromnumeric from fromnumeric import * import shape_base from shape_base import * -import multiarray from fromnumeric import amax as max, amin as min -from _numpypy import absolute as abs +from numeric import absolute as abs __all__ = [] -__all__ += _numpypy.__all__ __all__ += numeric.__all__ __all__ += fromnumeric.__all__ __all__ += shape_base.__all__ diff --git a/lib_pypy/numpypy/core/_methods.py b/lib_pypy/numpypy/core/_methods.py --- a/lib_pypy/numpypy/core/_methods.py +++ b/lib_pypy/numpypy/core/_methods.py @@ -1,11 +1,9 @@ # Array methods which are called by the both the C-code for the method # and the Python code for the NumPy-namespace function -#from numpy.core import multiarray as mu -#from numpy.core import umath as um -import _numpypy as mu -um = mu -from numpy.core.numeric import asanyarray +import multiarray as mu +import umath as um +from numeric import asanyarray def _amax(a, axis=None, out=None, keepdims=False): return um.maximum.reduce(a, axis=axis, diff --git a/lib_pypy/numpypy/core/arrayprint.py b/lib_pypy/numpypy/core/arrayprint.py --- a/lib_pypy/numpypy/core/arrayprint.py +++ b/lib_pypy/numpypy/core/arrayprint.py @@ -13,9 +13,9 @@ # and by Travis Oliphant 2005-8-22 for numpy import sys -import _numpypy as _nt -from _numpypy import maximum, minimum, absolute, not_equal, isnan, isinf -#from _numpypy import format_longfloat, datetime_as_string, datetime_data +import numerictypes as _nt +from umath import maximum, minimum, absolute, not_equal, isnan, isinf +#from multiarray import format_longfloat, datetime_as_string, datetime_data from fromnumeric import ravel @@ -294,12 +294,12 @@ #else: format_function = formatdict['int'] elif issubclass(dtypeobj, _nt.floating): - if issubclass(dtypeobj, _nt.longfloat): + if hasattr(_nt, 'longfloat') and issubclass(dtypeobj, _nt.longfloat): format_function = formatdict['longfloat'] else: format_function = formatdict['float'] elif issubclass(dtypeobj, _nt.complexfloating): - if issubclass(dtypeobj, _nt.clongfloat): + if hasattr(_nt, 'clongfloat') and issubclass(dtypeobj, _nt.clongfloat): format_function = formatdict['longcomplexfloat'] else: format_function = formatdict['complexfloat'] diff --git a/lib_pypy/numpypy/core/fromnumeric.py b/lib_pypy/numpypy/core/fromnumeric.py --- a/lib_pypy/numpypy/core/fromnumeric.py +++ b/lib_pypy/numpypy/core/fromnumeric.py @@ -16,6 +16,7 @@ ###################################################################### import numpypy +import _numpypy # Module containing non-deprecated functions borrowed from Numeric. __docformat__ = "restructuredtext en" @@ -274,7 +275,7 @@ [-1, -2, -3, -4, -5]]]) """ - raise NotImplementedError('Waiting on interp level method') + return _numpypy.choose(a, choices, out, mode) def repeat(a, repeats, axis=None): @@ -316,7 +317,7 @@ [3, 4]]) """ - raise NotImplementedError('Waiting on interp level method') + return _numpypy.repeat(a, repeats, axis) def put(a, ind, v, mode='raise'): diff --git a/lib_pypy/numpypy/core/multiarray.py b/lib_pypy/numpypy/core/multiarray.py --- a/lib_pypy/numpypy/core/multiarray.py +++ b/lib_pypy/numpypy/core/multiarray.py @@ -1,1 +1,1 @@ -from _numpypy import set_string_function, typeinfo +from _numpypy.multiarray import * diff --git a/lib_pypy/numpypy/core/numeric.py b/lib_pypy/numpypy/core/numeric.py --- a/lib_pypy/numpypy/core/numeric.py +++ b/lib_pypy/numpypy/core/numeric.py @@ -1,16 +1,40 @@ -__all__ = ['asanyarray', 'base_repr', +__all__ = [ + 'newaxis', 'ufunc', + 'asarray', 'asanyarray', 'base_repr', 'array_repr', 'array_str', 'set_string_function', - 'array_equal', 'asarray', 'outer', 'identity'] + 'array_equal', 'outer', 'identity', 'little_endian', + 'Inf', 'inf', 'infty', 'Infinity', 'nan', 'NaN', 'False_', 'True_', + ] -from _numpypy import array, ndarray, int_, float_, bool_, flexible #, complex_# , longlong -from _numpypy import concatenate -from .fromnumeric import any -import math import sys import multiarray -from numpypy.core.arrayprint import array2string +from multiarray import * +del set_string_function +del typeinfo +import umath +from umath import * +import numerictypes +from numerictypes import * + +def extend_all(module): + adict = {} + for a in __all__: + adict[a] = 1 + try: + mall = getattr(module, '__all__') + except AttributeError: + mall = [k for k in module.__dict__.keys() if not k.startswith('_')] + for a in mall: + if a not in adict: + __all__.append(a) + +extend_all(multiarray) +__all__.remove('typeinfo') +extend_all(umath) +extend_all(numerictypes) newaxis = None +ufunc = type(sin) # XXX this file to be reviewed def seterr(**args): @@ -121,6 +145,10 @@ res.append('-') return ''.join(reversed(res or '0')) + +#Use numarray's printing function +from arrayprint import array2string + _typelessdata = [int_, float_]#, complex_] # XXX #if issubclass(intc, int): @@ -306,6 +334,11 @@ else: return multiarray.set_string_function(f, repr) +set_string_function(array_str, 0) +set_string_function(array_repr, 1) + +little_endian = (sys.byteorder == 'little') + def array_equal(a1, a2): """ True if two arrays have the same shape and elements, False otherwise. @@ -417,21 +450,6 @@ """ return array(a, dtype, copy=False, order=order) -set_string_function(array_str, 0) -set_string_function(array_repr, 1) - -little_endian = (sys.byteorder == 'little') - -Inf = inf = infty = Infinity = PINF = float('inf') -NINF = float('-inf') -PZERO = 0.0 -NZERO = -0.0 -nan = NaN = NAN = float('nan') -False_ = bool_(False) -True_ = bool_(True) -e = math.e -pi = math.pi - def outer(a,b): """ Compute the outer product of two vectors. @@ -535,3 +553,12 @@ """ from numpy import eye return eye(n, dtype=dtype) + +Inf = inf = infty = Infinity = PINF +nan = NaN = NAN +False_ = bool_(False) +True_ = bool_(True) + +import fromnumeric +from fromnumeric import * +extend_all(fromnumeric) diff --git a/lib_pypy/numpypy/core/numerictypes.py b/lib_pypy/numpypy/core/numerictypes.py new file mode 100644 --- /dev/null +++ b/lib_pypy/numpypy/core/numerictypes.py @@ -0,0 +1,1 @@ +from _numpypy.numerictypes import * diff --git a/lib_pypy/numpypy/core/shape_base.py b/lib_pypy/numpypy/core/shape_base.py --- a/lib_pypy/numpypy/core/shape_base.py +++ b/lib_pypy/numpypy/core/shape_base.py @@ -1,6 +1,6 @@ __all__ = ['atleast_1d', 'atleast_2d', 'atleast_3d', 'vstack', 'hstack'] -import _numpypy +import numeric as _nx from numeric import array, asanyarray, newaxis def atleast_1d(*arys): @@ -223,7 +223,7 @@ [4]]) """ - return _numpypy.concatenate(map(atleast_2d,tup),0) + return _nx.concatenate(map(atleast_2d,tup),0) def hstack(tup): """ @@ -270,6 +270,6 @@ arrs = map(atleast_1d,tup) # As a special case, dimension 0 of 1-dimensional arrays is "horizontal" if arrs[0].ndim == 1: - return _numpypy.concatenate(arrs, 0) + return _nx.concatenate(arrs, 0) else: - return _numpypy.concatenate(arrs, 1) + return _nx.concatenate(arrs, 1) diff --git a/lib_pypy/numpypy/core/umath.py b/lib_pypy/numpypy/core/umath.py new file mode 100644 --- /dev/null +++ b/lib_pypy/numpypy/core/umath.py @@ -0,0 +1,12 @@ +from _numpypy.umath import * + +import math +e = math.e +pi = math.pi +del math + +PZERO = 0.0 +NZERO = -0.0 +PINF = float('inf') +NINF = float('-inf') +NAN = float('nan') diff --git a/lib_pypy/numpypy/lib/function_base.py b/lib_pypy/numpypy/lib/function_base.py --- a/lib_pypy/numpypy/lib/function_base.py +++ b/lib_pypy/numpypy/lib/function_base.py @@ -1,6 +1,6 @@ __all__ = ['average'] -from _numpypy import array +from ..core.numeric import array def average(a): # This implements a weighted average, for now we don't implement the diff --git a/lib_pypy/numpypy/lib/shape_base.py b/lib_pypy/numpypy/lib/shape_base.py --- a/lib_pypy/numpypy/lib/shape_base.py +++ b/lib_pypy/numpypy/lib/shape_base.py @@ -1,7 +1,7 @@ __all__ = ['dstack'] -import numpypy.core.numeric as _nx -from numpypy.core import atleast_3d +from ..core import numeric as _nx +from ..core import atleast_3d def dstack(tup): """ diff --git a/lib_pypy/numpypy/lib/twodim_base.py b/lib_pypy/numpypy/lib/twodim_base.py --- a/lib_pypy/numpypy/lib/twodim_base.py +++ b/lib_pypy/numpypy/lib/twodim_base.py @@ -1,6 +1,6 @@ __all__ = ['eye'] -from _numpypy import zeros +from ..core.numeric import zeros def eye(N, M=None, k=0, dtype=float): """ diff --git a/pypy/doc/cpython_differences.rst b/pypy/doc/cpython_differences.rst --- a/pypy/doc/cpython_differences.rst +++ b/pypy/doc/cpython_differences.rst @@ -134,7 +134,7 @@ ``ReferenceError`` at any place that uses them. (Or, better yet, don't use ``weakref.proxy()`` at all; use ``weakref.ref()``.) -There are a few extra implications for the difference in the GC. Most +There are a few extra implications from the difference in the GC. Most notably, if an object has a ``__del__``, the ``__del__`` is never called more than once in PyPy; but CPython will call the same ``__del__`` several times if the object is resurrected and dies again. The ``__del__`` methods are @@ -156,7 +156,7 @@ .. __: http://bugs.pypy.org/issue736 -Using the default GC called ``minimark``, the built-in function ``id()`` +Using the default GC (called ``minimark``), the built-in function ``id()`` works like it does in CPython. With other GCs it returns numbers that are not real addresses (because an object can move around several times) and calling it a lot can lead to performance problem. @@ -286,7 +286,7 @@ ------------- * Hash randomization (``-R``) is ignored in PyPy. As documented in - http://bugs.python.org/issue14621 , some of us believe it has no + http://bugs.python.org/issue14621, some of us believe it has no purpose in CPython either. * ``sys.setrecursionlimit(n)`` sets the limit only approximately, diff --git a/pypy/doc/faq.rst b/pypy/doc/faq.rst --- a/pypy/doc/faq.rst +++ b/pypy/doc/faq.rst @@ -202,20 +202,20 @@ Be sure to enable it again if you need it! -The PyPy translation tool chain -=============================== +The RPython translation tool chain +=================================== ---------------------------------------------- -Can PyPy compile normal Python programs to C? ---------------------------------------------- +------------------------------------------------ +Can RPython compile normal Python programs to C? +------------------------------------------------ -No, PyPy is not a Python compiler. +No, RPython is not a Python compiler. In Python, it is mostly impossible to *prove* anything about the types that a program will manipulate by doing a static analysis. It should be clear if you are familiar with Python, but if in doubt see [BRETT]_. -If you want a fast Python program, please use our JIT_ instead. +If you want a fast Python program, please use the PyPy JIT_ instead. .. _JIT: jit/index.html @@ -300,8 +300,8 @@ Do I have to rewrite my programs in RPython? -------------------------------------------- -No. And you shouldn't try. First and foremost, RPython is a language -that is designed to write interpreters in. It is a restricted subset of +No, and you shouldn't try. First and foremost, RPython is a language +designed for writing interpreters. It is a restricted subset of Python. If you program is not an interpreter but tries to do "real things", like use *any* part of the standard Python library or *any* 3rd-party library, then it is not RPython to start with. You should @@ -381,8 +381,8 @@ No, you have to rebuild the entire interpreter. This means two things: -* It is imperative to use test-driven development. You have to test - exhaustively your module in pure Python, before even attempting to +* It is imperative to use test-driven development. You have to exhaustively + test your module in pure Python, before even attempting to translate it. Once you translate it, you should have only a few typing issues left to fix, but otherwise the result should work out of the box. diff --git a/pypy/doc/getting-started-dev.rst b/pypy/doc/getting-started-dev.rst --- a/pypy/doc/getting-started-dev.rst +++ b/pypy/doc/getting-started-dev.rst @@ -20,7 +20,7 @@ To start the interactive translator shell do:: - cd pypy + cd rpython python bin/translatorshell.py Test snippets of translatable code are provided in the file diff --git a/pypy/doc/interpreter.rst b/pypy/doc/interpreter.rst --- a/pypy/doc/interpreter.rst +++ b/pypy/doc/interpreter.rst @@ -25,7 +25,7 @@ compact bytecode format as CPython 2.7, with minor differences in the bytecode set. Our bytecode compiler is implemented as a chain of flexible passes (tokenizer, lexer, parser, -abstract syntax tree builder, bytecode generator). The latter passes +abstract syntax tree builder and bytecode generator). The latter passes are based on the ``compiler`` package from the standard library of CPython, with various improvements and bug fixes. The bytecode compiler (living under `pypy/interpreter/astcompiler/`_) is now integrated and is @@ -38,8 +38,8 @@ calling its ``frame.eval()`` method. This main entry point initialize appropriate namespaces and then interprets each bytecode instruction. Python's standard library contains -the `lib-python/2.7/dis.py`_ module which allows to view -the Virtual's machine bytecode instructions:: +the `lib-python/2.7/dis.py`_ module which allows to inspection +of the virtual machine's bytecode instructions:: >>> import dis >>> def f(x): @@ -50,10 +50,10 @@ 6 BINARY_ADD 7 RETURN_VALUE -CPython as well as PyPy are stack-based virtual machines, i.e. -they don't have registers but put object to and pull objects +CPython and PyPy are stack-based virtual machines, i.e. +they don't have registers but instead push object to and pull objects from a stack. The bytecode interpreter is only responsible -for implementing control flow and putting and pulling black +for implementing control flow and pushing and pulling black box objects to and from this value stack. The bytecode interpreter does not know how to perform operations on those black box (`wrapped`_) objects for which it delegates to the `object @@ -75,8 +75,8 @@ on ``OperationErrors``. The interpreter implementation offers mechanisms to allow a -caller to be unaware if a particular function invocation leads -to bytecode interpretation or is executed directly at +caller to be unaware of whether a particular function invocation +leads to bytecode interpretation or is executed directly at interpreter-level. The two basic kinds of `Gateway classes`_ expose either an interpreter-level function to application-level execution (``interp2app``) or allow diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst --- a/pypy/doc/whatsnew-head.rst +++ b/pypy/doc/whatsnew-head.rst @@ -18,6 +18,9 @@ .. branch: numpypy-longdouble Long double support for numpypy +.. branch: numpypy-disable-longdouble +Since r_longdouble support is missing, disable all longdouble and derivative +dtypes using ENABLED_LONG_DOUBLE = False .. branch: numpypy-real-as-view Convert real, imag from ufuncs to views. This involves the beginning of view() functionality @@ -36,6 +39,7 @@ .. branch: task-decorator .. branch: fix-e4fa0b2 .. branch: win32-fixes +.. branch: numpy-unify-methods .. branch: fix-version-tool .. branch: popen2-removal @@ -72,3 +76,9 @@ .. branch: enumerate-rstr Support enumerate() over rstr types. + +.. branch: cleanup-numpypy-namespace +Cleanup _numpypy and numpypy namespaces to more closely resemble numpy. + +.. branch: kill-flowobjspace +Random cleanups to hide FlowObjSpace from public view. diff --git a/pypy/goal/multibuild.py b/pypy/goal/multibuild.py deleted file mode 100644 --- a/pypy/goal/multibuild.py +++ /dev/null @@ -1,127 +0,0 @@ -from pypy.config.pypyoption import get_pypy_config -from rpython.translator.goal import translate -from rpython.translator.goal import targetpypystandalone -from rpython.translator.driver import TranslationDriver -import os, sys, traceback, random - -def longoptfromname(config, name): - from pypy.config.makerestdoc import get_cmdline - # begin horror - h, n = config._cfgimpl_get_home_by_path(name) - opt = getattr(h._cfgimpl_descr, n) - # end horror - cmdline = get_cmdline(opt.cmdline, name) - assert cmdline is not None - shortest_long_option = 'X'*1000 - for cmd in cmdline.split(): - if cmd.startswith('--') and len(cmd) < len(shortest_long_option): - shortest_long_option = cmd - return shortest_long_option - -def exe_name_from_options(config, opts): - from pypy.module.sys.version import svn_revision - - backend = config.translation.backend - if not backend: - backend = 'c' - rev = svn_revision() - - nameparts = [] - - for opt, v in opts.iteritems(): - if opt == 'translation.backend': - backend = v - optname = longoptfromname(config, opt).strip('-') - if v is False: - optname = 'no-' + optname - elif v is not True: - optname += '=' + str(v) - nameparts.append(optname) - - suffix = '' - if nameparts: - def k(s): - if s.startswith('no-'): - return s[3:] - else: - return s - nameparts.sort(key=k) - suffix = '-' + '-'.join(nameparts) - - return 'pypy-%s-%d%s'%(backend, rev, suffix) - -def _build(config, exe_name): - driver = TranslationDriver.from_targetspec( - targetpypystandalone.__dict__, - config=config) - driver.exe_name = exe_name - driver.compile() - -def build_pypy_with_options(basedir, opts): - config = get_pypy_config(translate.OVERRIDES, translating=True) - - try: - config.set(**opts) - except: - return exe_name_from_options(config, opts), "didn't configure" - - exe_name = os.path.join(basedir, exe_name_from_options(config, opts)) - - print exe_name, - sys.stdout.flush() - - pid = os.fork() - - if pid == 0: - logfile = open(exe_name + '-log', 'w') - davenull = os.open('/dev/null', os.O_RDONLY) - os.dup2(davenull, 0) - os.dup2(logfile.fileno(), 1) - os.dup2(logfile.fileno(), 2) - try: - try: - r = _build(config, exe_name) - finally: - logfile.close() - except: - os._exit(1) - else: - os._exit(0) - else: - pid, status = os.waitpid(pid, 0) - if status: - r = 'failed' - else: - r = 'succeeded' - print r - return exe_name, r - -def get_options(fname): - def gen_opts(sofar, remaining): - if not remaining: - yield sofar - else: - for (k, v) in remaining[0]: - d2 = sofar.copy() - d2[k] = v - for d in gen_opts(d2, remaining[1:]): - yield d - options = [] - for line in open(fname): - l = [] - optname, options_ = line.split(':') - options.append([(optname.strip(), eval(optval.strip())) for optval in options_.split(',')]) - return gen_opts({}, options) - - -if __name__ == '__main__': - basedir = sys.argv[1] - optionsfile = sys.argv[2] - results = [] - options = list(get_options(optionsfile)) - random.shuffle(options) - for opts in options: - results.append(build_pypy_with_options(basedir, opts)) - out = open(os.path.join(basedir, 'results'), 'w') - for exe, r in results: - print >>out, exe, r diff --git a/pypy/module/micronumpy/__init__.py b/pypy/module/micronumpy/__init__.py --- a/pypy/module/micronumpy/__init__.py +++ b/pypy/module/micronumpy/__init__.py @@ -1,14 +1,12 @@ from pypy.interpreter.mixedmodule import MixedModule -from pypy.module.micronumpy.interp_boxes import long_double_size +from pypy.module.micronumpy.interp_boxes import long_double_size, ENABLED_LONG_DOUBLE -class Module(MixedModule): - applevel_name = '_numpypy' - +class MultiArrayModule(MixedModule): + appleveldefs = {'arange': 'app_numpy.arange'} interpleveldefs = { 'ndarray': 'interp_numarray.W_NDimArray', 'dtype': 'interp_dtype.W_Dtype', - 'ufunc': 'interp_ufuncs.W_Ufunc', 'array': 'interp_numarray.array', 'zeros': 'interp_numarray.zeros', @@ -18,17 +16,17 @@ 'fromstring': 'interp_support.fromstring', 'flatiter': 'interp_flatiter.W_FlatIterator', 'concatenate': 'interp_arrayops.concatenate', - 'repeat': 'interp_arrayops.repeat', 'where': 'interp_arrayops.where', 'count_nonzero': 'interp_arrayops.count_nonzero', 'set_string_function': 'appbridge.set_string_function', + 'typeinfo': 'interp_dtype.get_dtype_cache(space).w_typeinfo', + } - 'True_': 'types.Bool.True', - 'False_': 'types.Bool.False', - 'typeinfo': 'interp_dtype.get_dtype_cache(space).w_typeinfo', - +class NumericTypesModule(MixedModule): + appleveldefs = {} + interpleveldefs = { 'generic': 'interp_boxes.W_GenericBox', 'number': 'interp_boxes.W_NumberBox', 'integer': 'interp_boxes.W_IntegerBox', @@ -59,8 +57,6 @@ 'float16': 'interp_boxes.W_Float16Box', 'float32': 'interp_boxes.W_Float32Box', 'float64': 'interp_boxes.W_Float64Box', - 'longdouble': 'interp_boxes.W_LongDoubleBox', - 'longfloat': 'interp_boxes.W_LongDoubleBox', 'intp': 'types.IntP.BoxType', 'uintp': 'types.UIntP.BoxType', 'flexible': 'interp_boxes.W_FlexibleBox', @@ -73,10 +69,31 @@ 'complex_': 'interp_boxes.W_Complex128Box', 'complex128': 'interp_boxes.W_Complex128Box', 'complex64': 'interp_boxes.W_Complex64Box', - 'clongdouble': 'interp_boxes.W_CLongDoubleBox', - 'clongfloat': 'interp_boxes.W_CLongDoubleBox', } + if ENABLED_LONG_DOUBLE: + long_double_dtypes = [ + ('longdouble', 'interp_boxes.W_LongDoubleBox'), + ('longfloat', 'interp_boxes.W_LongDoubleBox'), + ('clongdouble', 'interp_boxes.W_CLongDoubleBox'), + ('clongfloat', 'interp_boxes.W_CLongDoubleBox'), + ] + if long_double_size == 16: + long_double_dtypes += [ + ('float128', 'interp_boxes.W_Float128Box'), + ('complex256', 'interp_boxes.W_Complex256Box'), + ] + elif long_double_size == 12: + long_double_dtypes += [ + ('float96', 'interp_boxes.W_Float96Box'), + ('complex192', 'interp_boxes.W_Complex192Box'), + ] + for dt, box in long_double_dtypes: + interpleveldefs[dt] = box + +class UMathModule(MixedModule): + appleveldefs = {} + interpleveldefs = {} # ufuncs for exposed, impl in [ ("absolute", "absolute"), @@ -158,22 +175,16 @@ ]: interpleveldefs[exposed] = "interp_ufuncs.get(space).%s" % impl - appleveldefs = { - 'arange': 'app_numpy.arange', + +class Module(MixedModule): + applevel_name = '_numpypy' + appleveldefs = {} + interpleveldefs = { + 'choose': 'interp_arrayops.choose', + 'repeat': 'interp_arrayops.repeat', } - def setup_after_space_initialization(self): - space = self.space - all_list = sorted(Module.interpleveldefs.keys() + \ - Module.appleveldefs.keys()) - # found by set(numpypy.__all__) - set(numpy.__all__) - all_list.remove('set_string_function') - all_list.remove('typeinfo') - w_all = space.wrap(all_list) - space.setitem(self.w_dict, space.new_interned_str('__all__'), w_all) - -if long_double_size == 16: - Module.interpleveldefs['float128'] = 'interp_boxes.W_Float128Box' - Module.interpleveldefs['complex256'] = 'interp_boxes.W_Complex256Box' -elif long_double_size == 12: - Module.interpleveldefs['float96'] = 'interp_boxes.W_Float96Box' - Module.interpleveldefs['complex192'] = 'interp_boxes.W_Complex192Box' + submodules = { + 'multiarray': MultiArrayModule, + 'numerictypes': NumericTypesModule, + 'umath': UMathModule, + } diff --git a/pypy/module/micronumpy/app_numpy.py b/pypy/module/micronumpy/app_numpy.py --- a/pypy/module/micronumpy/app_numpy.py +++ b/pypy/module/micronumpy/app_numpy.py @@ -10,9 +10,9 @@ stop = start start = 0 if dtype is None: - test = _numpypy.array([start, stop, step, 0]) + test = _numpypy.multiarray.array([start, stop, step, 0]) dtype = test.dtype - arr = _numpypy.zeros(int(math.ceil((stop - start) / step)), dtype=dtype) + arr = _numpypy.multiarray.zeros(int(math.ceil((stop - start) / step)), dtype=dtype) i = start for j in range(arr.size): arr[j] = i diff --git a/pypy/module/micronumpy/interp_arrayops.py b/pypy/module/micronumpy/interp_arrayops.py --- a/pypy/module/micronumpy/interp_arrayops.py +++ b/pypy/module/micronumpy/interp_arrayops.py @@ -106,33 +106,36 @@ args_w = [convert_to_array(space, w_arg) for w_arg in args_w] dtype = args_w[0].get_dtype() shape = args_w[0].get_shape()[:] - if len(shape) <= axis: + _axis = axis + if axis < 0: + _axis = len(shape) + axis + if _axis < 0 or len(shape) <= _axis: raise operationerrfmt(space.w_IndexError, "axis %d out of bounds [0, %d)", axis, len(shape)) for arr in args_w[1:]: dtype = interp_ufuncs.find_binop_result_dtype(space, dtype, arr.get_dtype()) - if len(arr.get_shape()) <= axis: + if _axis < 0 or len(arr.get_shape()) <= _axis: raise operationerrfmt(space.w_IndexError, "axis %d out of bounds [0, %d)", axis, len(shape)) for i, axis_size in enumerate(arr.get_shape()): - if len(arr.get_shape()) != len(shape) or (i != axis and axis_size != shape[i]): + if len(arr.get_shape()) != len(shape) or (i != _axis and axis_size != shape[i]): raise OperationError(space.w_ValueError, space.wrap( "all the input arrays must have same number of dimensions")) - elif i == axis: + elif i == _axis: shape[i] += axis_size res = W_NDimArray.from_shape(shape, dtype, 'C') chunks = [Chunk(0, i, 1, i) for i in shape] axis_start = 0 for arr in args_w: - if arr.get_shape()[axis] == 0: + if arr.get_shape()[_axis] == 0: continue - chunks[axis] = Chunk(axis_start, axis_start + arr.get_shape()[axis], 1, - arr.get_shape()[axis]) + chunks[_axis] = Chunk(axis_start, axis_start + arr.get_shape()[_axis], 1, + arr.get_shape()[_axis]) Chunks(chunks).apply(res).implementation.setslice(space, arr) - axis_start += arr.get_shape()[axis] + axis_start += arr.get_shape()[_axis] return res @unwrap_spec(repeats=int) -def repeat(space, w_arr, repeats, w_axis=None): +def repeat(space, w_arr, repeats, w_axis): arr = convert_to_array(space, w_arr) if space.is_none(w_axis): arr = arr.descr_flatten(space) @@ -158,14 +161,21 @@ def count_nonzero(space, w_obj): return space.wrap(loop.count_all_true(convert_to_array(space, w_obj))) -def choose(space, arr, w_choices, out, mode): + at unwrap_spec(mode=str) +def choose(space, w_arr, w_choices, w_out, mode): + arr = convert_to_array(space, w_arr) choices = [convert_to_array(space, w_item) for w_item in space.listview(w_choices)] if not choices: raise OperationError(space.w_ValueError, space.wrap("choices list cannot be empty")) - shape = shape_agreement_multiple(space, choices + [out]) - out = interp_dtype.dtype_agreement(space, choices, shape, out) + if space.is_none(w_out): + w_out = None + elif not isinstance(w_out, W_NDimArray): + raise OperationError(space.w_TypeError, space.wrap( + "return arrays must be of ArrayType")) + shape = shape_agreement_multiple(space, choices + [w_out]) + out = interp_dtype.dtype_agreement(space, choices, shape, w_out) dtype = out.get_dtype() if mode not in MODES: raise OperationError(space.w_ValueError, diff --git a/pypy/module/micronumpy/interp_boxes.py b/pypy/module/micronumpy/interp_boxes.py --- a/pypy/module/micronumpy/interp_boxes.py +++ b/pypy/module/micronumpy/interp_boxes.py @@ -16,10 +16,12 @@ MIXIN_64 = (int_typedef,) if LONG_BIT == 64 else () # Is this the proper place for this? +ENABLED_LONG_DOUBLE = False long_double_size = rffi.sizeof_c_type('long double', ignore_errors=True) + import os if long_double_size == 8 and os.name == 'nt': - # this is a lie, or maybe a wish + # this is a lie, or maybe a wish, MS fakes longdouble math with double long_double_size = 12 @@ -335,7 +337,7 @@ descr__new__, _get_dtype = new_dtype_getter("complex128") _COMPONENTS_BOX = W_Float64Box -if long_double_size == 12: +if ENABLED_LONG_DOUBLE and long_double_size == 12: class W_Float96Box(W_FloatingBox, PrimitiveBox): descr__new__, _get_dtype = new_dtype_getter("float96") @@ -347,7 +349,7 @@ W_CLongDoubleBox = W_Complex192Box -elif long_double_size == 16: +elif ENABLED_LONG_DOUBLE and long_double_size == 16: class W_Float128Box(W_FloatingBox, PrimitiveBox): descr__new__, _get_dtype = new_dtype_getter("float128") W_LongDoubleBox = W_Float128Box @@ -358,7 +360,7 @@ W_CLongDoubleBox = W_Complex256Box -else: +elif ENABLED_LONG_DOUBLE: W_LongDoubleBox = W_Float64Box W_CLongDoubleBox = W_Complex64Box @@ -526,7 +528,7 @@ __new__ = interp2app(W_Float64Box.descr__new__.im_func), ) -if long_double_size == 12: +if ENABLED_LONG_DOUBLE and long_double_size == 12: W_Float96Box.typedef = TypeDef("float96", (W_FloatingBox.typedef), __module__ = "numpypy", @@ -540,7 +542,7 @@ imag = GetSetProperty(W_ComplexFloatingBox.descr_get_imag), ) -elif long_double_size == 16: +elif ENABLED_LONG_DOUBLE and long_double_size == 16: W_Float128Box.typedef = TypeDef("float128", (W_FloatingBox.typedef), __module__ = "numpypy", diff --git a/pypy/module/micronumpy/interp_dtype.py b/pypy/module/micronumpy/interp_dtype.py --- a/pypy/module/micronumpy/interp_dtype.py +++ b/pypy/module/micronumpy/interp_dtype.py @@ -164,8 +164,11 @@ def is_record_type(self): return self.fields is not None + def is_str_or_unicode(self): + return (self.num == 18 or self.num == 19) + def is_flexible_type(self): - return (self.num == 18 or self.num == 19 or self.num == 20) + return (self.is_str_or_unicode() or self.is_record_type()) def __repr__(self): if self.fields is not None: @@ -416,6 +419,7 @@ w_box_type=space.gettypefor(interp_boxes.W_ULongBox), alternate_constructors=[ space.gettypefor(interp_boxes.W_UnsignedIntegerBox), ], + aliases=['uint'], ) self.w_int64dtype = W_Dtype( types.Int64(), @@ -474,7 +478,7 @@ aliases=["complex"], float_type = self.w_float64dtype, ) - if interp_boxes.long_double_size == 12: + if interp_boxes.ENABLED_LONG_DOUBLE and interp_boxes.long_double_size == 12: self.w_float96dtype = W_Dtype( types.Float96(), num=13, @@ -497,7 +501,7 @@ ) self.w_longdouble = self.w_float96dtype self.w_clongdouble = self.w_complex192dtype - elif interp_boxes.long_double_size == 16: + elif interp_boxes.ENABLED_LONG_DOUBLE and interp_boxes.long_double_size == 16: self.w_float128dtype = W_Dtype( types.Float128(), num=13, @@ -520,13 +524,13 @@ ) self.w_longdouble = self.w_float128dtype self.w_clongdouble = self.w_complex256dtype - else: + elif interp_boxes.ENABLED_LONG_DOUBLE: self.w_float64dtype.aliases += ["longdouble", "longfloat"] self.w_complex128dtype.aliases += ["clongdouble", "clongfloat"] self.w_longdouble = self.w_float64dtype self.w_clongdouble = self.w_complex128dtype self.w_stringdtype = W_Dtype( - types.StringType(1), + types.StringType(0), num=18, kind=STRINGLTR, name='string', @@ -596,23 +600,27 @@ char=UINTPLTR, w_box_type = space.gettypefor(uintp_box), ) + float_dtypes = [self.w_float16dtype, + self.w_float32dtype, self.w_float64dtype, + ] + complex_dtypes = [self.w_complex64dtype, self.w_complex128dtype] + if interp_boxes.ENABLED_LONG_DOUBLE: + float_dtypes.append(self.w_longdouble) + complex_dtypes.append(self.w_clongdouble) self.builtin_dtypes = [ self.w_booldtype, self.w_int8dtype, self.w_uint8dtype, self.w_int16dtype, self.w_uint16dtype, self.w_longdtype, self.w_ulongdtype, self.w_int32dtype, self.w_uint32dtype, - self.w_int64dtype, self.w_uint64dtype, - self.w_float16dtype, - self.w_float32dtype, self.w_float64dtype, self.w_longdouble, - self.w_complex64dtype, self.w_complex128dtype, self.w_clongdouble, + self.w_int64dtype, self.w_uint64dtype] + \ + float_dtypes + complex_dtypes + [ self.w_stringdtype, self.w_unicodedtype, self.w_voiddtype, self.w_intpdtype, self.w_uintpdtype, ] self.float_dtypes_by_num_bytes = sorted( (dtype.itemtype.get_element_size(), dtype) - for dtype in [self.w_float16dtype, self.w_float32dtype, - self.w_float64dtype, self.w_longdouble] + for dtype in float_dtypes ) self.dtypes_by_num = {} self.dtypes_by_name = {} @@ -655,7 +663,6 @@ 'LONGLONG': self.w_int64dtype, 'SHORT': self.w_int16dtype, 'VOID': self.w_voiddtype, - 'LONGDOUBLE': self.w_longdouble, 'UBYTE': self.w_uint8dtype, 'UINTP': self.w_ulongdtype, 'ULONG': self.w_ulongdtype, @@ -678,8 +685,11 @@ 'USHORT': self.w_uint16dtype, 'FLOAT': self.w_float32dtype, 'BOOL': self.w_booldtype, - 'CLONGDOUBLE': self.w_clongdouble, } + if interp_boxes.ENABLED_LONG_DOUBLE: + typeinfo_full['LONGDOUBLE'] = self.w_longdouble + typeinfo_full['CLONGDOUBLE'] = self.w_clongdouble + typeinfo_partial = { 'Generic': interp_boxes.W_GenericBox, 'Character': interp_boxes.W_CharacterBox, diff --git a/pypy/module/micronumpy/interp_numarray.py b/pypy/module/micronumpy/interp_numarray.py --- a/pypy/module/micronumpy/interp_numarray.py +++ b/pypy/module/micronumpy/interp_numarray.py @@ -14,7 +14,7 @@ from pypy.module.micronumpy.appbridge import get_appbridge_cache from pypy.module.micronumpy import loop from pypy.module.micronumpy.dot import match_dot_shapes -from pypy.module.micronumpy.interp_arrayops import repeat +from pypy.module.micronumpy.interp_arrayops import repeat, choose from rpython.tool.sourcetools import func_with_new_name from rpython.rlib import jit from rpython.rlib.rstring import StringBuilder @@ -452,13 +452,8 @@ return res @unwrap_spec(mode=str) - def descr_choose(self, space, w_choices, mode='raise', w_out=None): - if space.is_none(w_out): - w_out = None - elif not isinstance(w_out, W_NDimArray): - raise OperationError(space.w_TypeError, space.wrap( - "return arrays must be of ArrayType")) - return interp_arrayops.choose(space, self, w_choices, w_out, mode) + def descr_choose(self, space, w_choices, w_out=None, mode='raise'): + return choose(space, self, w_choices, w_out, mode) def descr_clip(self, space, w_min, w_max, w_out=None): if space.is_none(w_out): @@ -932,7 +927,8 @@ return w_object shape, elems_w = find_shape_and_elems(space, w_object, dtype) - if dtype is None: + if dtype is None or ( + dtype.is_str_or_unicode() and dtype.itemtype.get_size() < 1): for w_elem in elems_w: dtype = interp_ufuncs.find_dtype_for_scalar(space, w_elem, dtype) @@ -941,6 +937,9 @@ if dtype is None: dtype = interp_dtype.get_dtype_cache(space).w_float64dtype + if dtype.is_str_or_unicode() and dtype.itemtype.get_size() < 1: + # promote S0 -> S1, U0 -> U1 + dtype = interp_dtype.variable_dtype(space, dtype.char + '1') if ndmin > len(shape): shape = [1] * (ndmin - len(shape)) + shape arr = W_NDimArray.from_shape(shape, dtype, order=order) diff --git a/pypy/module/micronumpy/interp_ufuncs.py b/pypy/module/micronumpy/interp_ufuncs.py --- a/pypy/module/micronumpy/interp_ufuncs.py +++ b/pypy/module/micronumpy/interp_ufuncs.py @@ -258,6 +258,9 @@ if w_obj.get_dtype().is_flexible_type(): raise OperationError(space.w_TypeError, space.wrap('Not implemented for this type')) + if self.int_only and not w_obj.get_dtype().is_int_type(): + raise OperationError(space.w_TypeError, space.wrap( + "ufunc %s not supported for the input type" % self.name)) calc_dtype = find_unaryop_result_dtype(space, w_obj.get_dtype(), promote_to_float=self.promote_to_float, @@ -337,6 +340,9 @@ promote_bools=self.promote_bools, allow_complex=self.allow_complex, ) + if self.int_only and not calc_dtype.is_int_type(): + raise OperationError(space.w_TypeError, space.wrap( + "ufunc '%s' not supported for the input types" % self.name)) if space.is_none(w_out): out = None elif not isinstance(w_out, W_NDimArray): @@ -400,7 +406,7 @@ return interp_dtype.get_dtype_cache(space).w_complex64dtype elif dt2.num == 15: return interp_dtype.get_dtype_cache(space).w_complex128dtype - elif dt2.num == 16: + elif interp_boxes.ENABLED_LONG_DOUBLE and dt2.num == 16: return interp_dtype.get_dtype_cache(space).w_clongdouble else: raise OperationError(space.w_TypeError, space.wrap("Unsupported types")) diff --git a/pypy/module/micronumpy/test/test_arrayops.py b/pypy/module/micronumpy/test/test_arrayops.py --- a/pypy/module/micronumpy/test/test_arrayops.py +++ b/pypy/module/micronumpy/test/test_arrayops.py @@ -3,26 +3,26 @@ class AppTestNumSupport(BaseNumpyAppTest): def test_where(self): - from _numpypy import where, ones, zeros, array + from numpypy import where, ones, zeros, array a = [1, 2, 3, 0, -3] a = where(array(a) > 0, ones(5), zeros(5)) assert (a == [1, 1, 1, 0, 0]).all() def test_where_differing_dtypes(self): - from _numpypy import array, ones, zeros, where + from numpypy import array, ones, zeros, where a = [1, 2, 3, 0, -3] a = where(array(a) > 0, ones(5, dtype=int), zeros(5, dtype=float)) assert (a == [1, 1, 1, 0, 0]).all() def test_where_broadcast(self): - from _numpypy import array, where + from numpypy import array, where a = where(array([[1, 2, 3], [4, 5, 6]]) > 3, [1, 1, 1], 2) assert (a == [[2, 2, 2], [1, 1, 1]]).all() a = where(True, [1, 1, 1], 2) assert (a == [1, 1, 1]).all() def test_where_errors(self): - from _numpypy import where, array + from numpypy import where, array raises(ValueError, "where([1, 2, 3], [3, 4, 5])") raises(ValueError, "where([1, 2, 3], [3, 4, 5], [6, 7])") assert where(True, 1, 2) == array(1) @@ -35,7 +35,7 @@ # xxx def test_where_invalidates(self): - from _numpypy import where, ones, zeros, array + from numpypy import where, ones, zeros, array a = array([1, 2, 3, 0, -3]) b = where(a > 0, ones(5), zeros(5)) a[0] = 0 @@ -43,7 +43,7 @@ def test_dot(self): - from _numpypy import array, dot, arange + from numpypy import array, dot, arange a = array(range(5)) assert dot(a, a) == 30.0 @@ -74,7 +74,7 @@ assert (dot([[1,2],[3,4]],[5,6]) == [17, 39]).all() def test_dot_constant(self): - from _numpypy import array, dot + from numpypy import array, dot a = array(range(5)) b = a.dot(2.5) for i in xrange(5): @@ -85,19 +85,21 @@ assert c == 12.0 def test_choose_basic(self): - from _numpypy import array + from numpypy import array, choose a, b, c = array([1, 2, 3]), array([4, 5, 6]), array([7, 8, 9]) r = array([2, 1, 0]).choose([a, b, c]) assert (r == [7, 5, 3]).all() + r = choose(array([2, 1, 0]), [a, b, c]) + assert (r == [7, 5, 3]).all() def test_choose_broadcast(self): - from _numpypy import array + from numpypy import array a, b, c = array([1, 2, 3]), [4, 5, 6], 13 r = array([2, 1, 0]).choose([a, b, c]) assert (r == [13, 5, 3]).all() def test_choose_out(self): - from _numpypy import array + from numpypy import array a, b, c = array([1, 2, 3]), [4, 5, 6], 13 r = array([2, 1, 0]).choose([a, b, c], out=None) assert (r == [13, 5, 3]).all() @@ -107,10 +109,10 @@ assert (a == [13, 5, 3]).all() def test_choose_modes(self): - from _numpypy import array + from numpypy import array a, b, c = array([1, 2, 3]), [4, 5, 6], 13 raises(ValueError, "array([3, 1, 0]).choose([a, b, c])") - raises(ValueError, "array([3, 1, 0]).choose([a, b, c], 'raises')") + raises(ValueError, "array([3, 1, 0]).choose([a, b, c], mode='raises')") raises(ValueError, "array([3, 1, 0]).choose([])") raises(ValueError, "array([-1, -2, -3]).choose([a, b, c])") r = array([4, 1, 0]).choose([a, b, c], mode='clip') @@ -119,13 +121,13 @@ assert (r == [4, 5, 3]).all() def test_choose_dtype(self): - from _numpypy import array + from numpypy import array a, b, c = array([1.2, 2, 3]), [4, 5, 6], 13 r = array([2, 1, 0]).choose([a, b, c]) assert r.dtype == float def test_choose_dtype_out(self): - from _numpypy import array + from numpypy import array a, b, c = array([1, 2, 3]), [4, 5, 6], 13 x = array([0, 0, 0], dtype='i2') r = array([2, 1, 0]).choose([a, b, c], out=x) diff --git a/pypy/module/micronumpy/test/test_base.py b/pypy/module/micronumpy/test/test_base.py --- a/pypy/module/micronumpy/test/test_base.py +++ b/pypy/module/micronumpy/test/test_base.py @@ -17,7 +17,6 @@ if '__pypy__' not in sys.builtin_module_names: import numpy sys.modules['numpypy'] = numpy - sys.modules['_numpypy'] = numpy cls.w_non_native_prefix = cls.space.wrap(nonnative_byteorder_prefix) cls.w_native_prefix = cls.space.wrap(byteorder_prefix) diff --git a/pypy/module/micronumpy/test/test_complex.py b/pypy/module/micronumpy/test/test_complex.py --- a/pypy/module/micronumpy/test/test_complex.py +++ b/pypy/module/micronumpy/test/test_complex.py @@ -132,13 +132,13 @@ cls.w_c_pow = cls.space.wrap(interp2app(cls_c_pow)) def test_fabs(self): - from _numpypy import fabs, complex128 + from numpypy import fabs, complex128 a = complex128(complex(-5., 5.)) raises(TypeError, fabs, a) def test_fmax(self): - from _numpypy import fmax, array + from numpypy import fmax, array nnan, nan, inf, ninf = float('-nan'), float('nan'), float('inf'), float('-inf') a = array((complex(ninf, 10), complex(10, ninf), complex( inf, 10), complex(10, inf), @@ -165,7 +165,7 @@ assert (fmax(a, b) == res).all() def test_fmin(self): - from _numpypy import fmin, array + from numpypy import fmin, array nnan, nan, inf, ninf = float('-nan'), float('nan'), float('inf'), float('-inf') a = array((complex(ninf, 10), complex(10, ninf), complex( inf, 10), complex(10, inf), @@ -192,12 +192,17 @@ assert (fmin(a, b) == res).all() def test_signbit(self): - from _numpypy import signbit + from numpypy import signbit raises(TypeError, signbit, complex(1,1)) def test_reciprocal(self): - from _numpypy import array, reciprocal, complex64, complex128, clongdouble - + from numpypy import array, reciprocal, complex64, complex128 + c_and_relerr = [(complex64, 2e-7), (complex128, 2e-15)] + try: + from numpypy import clongdouble + c_and_relerr.append((clongdouble, 2e-30)) + except: + pass # no longdouble yet inf = float('inf') nan = float('nan') #complex @@ -212,32 +217,38 @@ complex(-r, i), -0j, 0j, cnan, cnan, cnan, cnan] - for c, rel_err in ((complex64, 2e-7), (complex128, 2e-15), (clongdouble, 2e-15)): + for c, rel_err in c_and_relerr: actual = reciprocal(array([orig], dtype=c)) for b, a, e in zip(orig, actual, expected): assert (a[0].real - e.real) < rel_err assert (a[0].imag - e.imag) < rel_err def test_floorceiltrunc(self): - from _numpypy import array, floor, ceil, trunc + from numpypy import array, floor, ceil, trunc a = array([ complex(-1.4, -1.4), complex(-1.5, -1.5)]) raises(TypeError, floor, a) raises(TypeError, ceil, a) raises(TypeError, trunc, a) def test_copysign(self): - from _numpypy import copysign, complex128 + from numpypy import copysign, complex128 a = complex128(complex(-5., 5.)) b = complex128(complex(0., 0.)) raises(TypeError, copysign, a, b) def test_exp2(self): - from _numpypy import array, exp2, complex128, complex64, clongfloat + from numpypy import array, exp2, complex128, complex64 + c_and_relerr = [(complex64, 2e-7), (complex128, 2e-15)] + try: + from numpypy import clongdouble + c_and_relerr.append((clongdouble, 2e-30)) + except: + pass # no longdouble yet inf = float('inf') ninf = -float('inf') nan = float('nan') cmpl = complex - for c,rel_err in ((complex128, 2e-15), (complex64, 1e-7), (clongfloat, 2e-15)): + for c,rel_err in c_and_relerr: a = [cmpl(-5., 0), cmpl(-5., -5.), cmpl(-5., 5.), cmpl(0., -5.), cmpl(0., 0.), cmpl(0., 5.), cmpl(-0., -5.), cmpl(-0., 0.), cmpl(-0., 5.), @@ -268,7 +279,7 @@ def test_expm1(self): import math, cmath - from _numpypy import array, expm1, complex128, complex64 + from numpypy import array, expm1, complex128, complex64 inf = float('inf') ninf = -float('inf') nan = float('nan') @@ -307,7 +318,7 @@ self.rAlmostEqual(t1, t2, rel_err=rel_err, msg=msg) def test_not_complex(self): - from _numpypy import (radians, deg2rad, degrees, rad2deg, + from numpypy import (radians, deg2rad, degrees, rad2deg, isneginf, isposinf, logaddexp, logaddexp2, fmod, arctan2) raises(TypeError, radians, complex(90,90)) @@ -322,7 +333,7 @@ raises (TypeError, fmod, complex(90,90), 3) def test_isnan_isinf(self): - from _numpypy import isnan, isinf, array + from numpypy import isnan, isinf, array assert (isnan(array([0.2+2j, complex(float('inf'),0), complex(0,float('inf')), complex(0,float('nan')), complex(float('nan'), 0)], dtype=complex)) == \ @@ -335,7 +346,7 @@ def test_square(self): - from _numpypy import square + from numpypy import square assert square(complex(3, 4)) == complex(3,4) * complex(3, 4) def test_power_complex(self): @@ -344,7 +355,7 @@ nan = float('nan') cmpl = complex from math import copysign - from _numpypy import power, array, complex128, complex64 + from numpypy import power, array, complex128, complex64 # note: in some settings (namely a x86-32 build without the JIT), # gcc optimizes the code in rlib.rcomplex.c_pow() to not truncate # the 10-byte values down to 8-byte values. It ends up with more @@ -381,7 +392,7 @@ self.rAlmostEqual(t1, t2, rel_err=rel_err, msg=msg) def test_conjugate(self): - from _numpypy import conj, conjugate, complex128, complex64 + from numpypy import conj, conjugate, complex128, complex64 import numpypy as np c0 = complex128(complex(2.5, 0)) @@ -405,7 +416,7 @@ def test_logn(self): import math, cmath # log and log10 are tested in math (1:1 from rcomplex) - from _numpypy import log2, array, complex128, complex64, log1p + from numpypy import log2, array, complex128, complex64, log1p inf = float('inf') ninf = -float('inf') nan = float('nan') @@ -462,7 +473,7 @@ self.rAlmostEqual(t1, t2, rel_err=rel_err, msg=msg) def test_logical_ops(self): - from _numpypy import logical_and, logical_or, logical_xor, logical_not + from numpypy import logical_and, logical_or, logical_xor, logical_not c1 = complex(1, 1) c3 = complex(3, 0) @@ -476,7 +487,7 @@ assert (logical_not([c1, c0]) == [False, True]).all() def test_minimum(self): - from _numpypy import array, minimum + from numpypy import array, minimum a = array([-5.0+5j, -5.0-5j, -0.0-10j, 1.0+10j]) b = array([ 3.0+10.0j, 3.0, -2.0+2.0j, -3.0+4.0j]) @@ -485,7 +496,7 @@ assert c[i] == min(a[i], b[i]) def test_maximum(self): - from _numpypy import array, maximum + from numpypy import array, maximum a = array([-5.0+5j, -5.0-5j, -0.0-10j, 1.0+10j]) b = array([ 3.0+10.0j, 3.0, -2.0+2.0j, -3.0+4.0j]) @@ -494,17 +505,23 @@ assert c[i] == max(a[i], b[i]) def test_basic(self): - from _numpypy import (complex128, complex64, add, array, dtype, + from numpypy import (complex128, complex64, add, array, dtype, subtract as sub, multiply, divide, negative, absolute as abs, - floor_divide, real, imag, sign, clongfloat) - from _numpypy import (equal, not_equal, greater, greater_equal, less, + floor_divide, real, imag, sign) + from numpypy import (equal, not_equal, greater, greater_equal, less, less_equal, isnan) + complex_dtypes = [complex64, complex128] + try: + from numpypy import clongfloat + complex_dtypes.append(clongfloat) + except: + pass assert real(4.0) == 4.0 assert imag(0.0) == 0.0 a = array([complex(3.0, 4.0)]) b = a.real assert b.dtype == dtype(float) - for complex_ in complex64, complex128, clongfloat: + for complex_ in complex_dtypes: O = complex(0, 0) c0 = complex_(complex(2.5, 0)) @@ -571,15 +588,15 @@ inf_c = complex_(complex(float('inf'), 0.)) assert repr(abs(inf_c)) == 'inf' assert repr(abs(complex(float('nan'), float('nan')))) == 'nan' - # numpy actually raises an AttributeError, - # but _numpypy raises a TypeError + # numpy actually raises an AttributeError, + # but numpypy raises a TypeError raises((TypeError, AttributeError), 'c2.real = 10.') raises((TypeError, AttributeError), 'c2.imag = 10.') assert(real(c2) == 3.0) assert(imag(c2) == 4.0) def test_conj(self): - from _numpypy import array + from numpypy import array a = array([1 + 2j, 1 - 2j]) assert (a.conj() == [1 - 2j, 1 + 2j]).all() @@ -588,7 +605,7 @@ if self.isWindows: skip('windows does not support c99 complex') import sys - import _numpypy as np + import numpypy as np rAlmostEqual = self.rAlmostEqual for complex_, abs_err, testcases in (\ diff --git a/pypy/module/micronumpy/test/test_dtypes.py b/pypy/module/micronumpy/test/test_dtypes.py --- a/pypy/module/micronumpy/test/test_dtypes.py +++ b/pypy/module/micronumpy/test/test_dtypes.py @@ -14,10 +14,10 @@ from rpython.rtyper.lltypesystem import rffi ptr_size = rffi.sizeof(rffi.CCHARP) cls.w_ptr_size = cls.space.wrap(ptr_size) - + class AppTestDtypes(BaseAppTestDtypes): def test_dtype(self): - from _numpypy import dtype + from numpypy import dtype d = dtype('?') assert d.num == 0 @@ -36,22 +36,15 @@ raises(KeyError, 'dtype(int)["asdasd"]') def test_dtype_eq(self): - from _numpypy import dtype + from numpypy import dtype assert dtype("int8") == "int8" assert "int8" == dtype("int8") raises(TypeError, lambda: dtype("int8") == 3) assert dtype(bool) == bool - def test_dtype_aliases(self): - from _numpypy import dtype - assert dtype('longfloat').num in (12, 13) - assert dtype('longdouble').num in (12, 13) - assert dtype('clongfloat').num in (15, 16) - assert dtype('clongdouble').num in (15, 16) - def test_dtype_with_types(self): - from _numpypy import dtype + from numpypy import dtype assert dtype(bool).num == 0 if self.ptr_size == 4: @@ -69,16 +62,20 @@ assert dtype('int64').num == 7 assert dtype('uint64').num == 8 assert dtype(int).num == 7 + assert dtype('int').num == 7 + assert dtype('uint').num == 8 assert dtype(float).num == 12 + assert dtype('float').num == 12 + assert dtype('complex').num == 15 def test_array_dtype_attr(self): - from _numpypy import array, dtype + from numpypy import array, dtype a = array(list(range(5)), int) assert a.dtype is dtype(int) def test_repr_str(self): - from _numpypy import dtype + from numpypy import dtype assert '.dtype' in repr(dtype) d = dtype('?') @@ -86,7 +83,7 @@ assert str(d) == "bool" def test_bool_array(self): - from _numpypy import array, False_, True_ + from numpypy import array, False_, True_ a = array([0, 1, 2, 2.5], dtype='?') assert a[0] is False_ @@ -94,7 +91,7 @@ assert a[i] is True_ def test_copy_array_with_dtype(self): - from _numpypy import array, False_, longlong + from numpypy import array, longlong, False_ a = array([0, 1, 2, 3], dtype=int) # int on 64-bit, long in 32-bit @@ -108,35 +105,35 @@ assert b[0] is False_ def test_zeros_bool(self): - from _numpypy import zeros, False_ + from numpypy import zeros, False_ a = zeros(10, dtype=bool) for i in range(10): assert a[i] is False_ def test_ones_bool(self): - from _numpypy import ones, True_ + from numpypy import ones, True_ a = ones(10, dtype=bool) for i in range(10): assert a[i] is True_ def test_zeros_long(self): - from _numpypy import zeros, longlong + from numpypy import zeros, longlong a = zeros(10, dtype=int) for i in range(10): assert isinstance(a[i], longlong) assert a[1] == 0 def test_ones_long(self): - from _numpypy import ones, longlong + from numpypy import ones, longlong a = ones(10, dtype=int) for i in range(10): assert isinstance(a[i], longlong) assert a[1] == 1 def test_overflow(self): - from _numpypy import array, dtype + from numpypy import array, dtype assert array([128], 'b')[0] == -128 assert array([256], 'B')[0] == 0 assert array([32768], 'h')[0] == -32768 @@ -148,19 +145,17 @@ raises(OverflowError, "array([2**64], 'Q')") def test_bool_binop_types(self): - from _numpypy import array, dtype + from numpypy import array, dtype types = [ '?', 'b', 'B', 'h', 'H', 'i', 'I', 'l', 'L', 'q', 'Q', 'f', 'd', 'e' ] - if array([0], dtype='longdouble').itemsize > 8: - types += ['g', 'G'] a = array([True], '?') for t in types: assert (a + array([0], t)).dtype is dtype(t) def test_binop_types(self): - from _numpypy import array, dtype + from numpypy import array, dtype tests = [('b','B','h'), ('b','h','h'), ('b','H','i'), ('b','i','i'), ('b','l','l'), ('b','q','q'), ('b','Q','d'), ('B','h','h'), ('B','H','H'), ('B','i','i'), ('B','I','I'), ('B','l','l'), @@ -184,7 +179,7 @@ assert (d1, d2) == (d1, d2) and d3 is dtype(dout) def test_add_int8(self): - from _numpypy import array, dtype + from numpypy import array, dtype a = array(list(range(5)), dtype="int8") b = a + a @@ -193,7 +188,7 @@ assert b[i] == i * 2 def test_add_int16(self): - from _numpypy import array, dtype + from numpypy import array, dtype a = array(list(range(5)), dtype="int16") b = a + a @@ -202,7 +197,7 @@ assert b[i] == i * 2 def test_add_uint32(self): - from _numpypy import array, dtype + from numpypy import array, dtype a = array(list(range(5)), dtype="I") b = a + a @@ -211,49 +206,49 @@ assert b[i] == i * 2 def test_shape(self): - from _numpypy import dtype + from numpypy import dtype assert dtype(int).shape == () def test_cant_subclass(self): - from _numpypy import dtype + from numpypy import dtype # You can't subclass dtype raises(TypeError, type, "Foo", (dtype,), {}) def test_can_subclass(self): - import _numpypy - class xyz(_numpypy.void): + import numpypy + class xyz(numpypy.void): pass assert True def test_aliases(self): - from _numpypy import dtype + from numpypy import dtype assert dtype("float") is dtype(float) def test_index_int8(self): - from _numpypy import array, int8 + from numpypy import array, int8 a = array(range(10), dtype=int8) b = array([0] * 10, dtype=int8) for idx in b: a[idx] += 1 def test_index_int16(self): - from _numpypy import array, int16 + from numpypy import array, int16 a = array(range(10), dtype=int16) b = array([0] * 10, dtype=int16) for idx in b: a[idx] += 1 def test_index_int32(self): - from _numpypy import array, int32 + from numpypy import array, int32 a = array(range(10), dtype=int32) b = array([0] * 10, dtype=int32) for idx in b: a[idx] += 1 def test_index_int64(self): - from _numpypy import array, int64 + from numpypy import array, int64 a = array(range(10), dtype=int64) b = array([0] * 10, dtype=int64) @@ -261,7 +256,7 @@ a[idx] += 1 def test_hash(self): - import _numpypy as numpy + import numpypy as numpy for tp, value in [ (numpy.int8, 4), (numpy.int16, 5), @@ -270,14 +265,13 @@ (numpy.float16, 10.), (numpy.float32, 2.0), (numpy.float64, 4.32), - (numpy.longdouble, 4.32), ]: assert hash(tp(value)) == hash(value) class AppTestTypes(BaseAppTestDtypes): def test_abstract_types(self): - import _numpypy as numpy + import numpypy as numpy raises(TypeError, numpy.generic, 0) raises(TypeError, numpy.number, 0) @@ -317,16 +311,16 @@ #assert a.dtype is numpy.dtype('|V4') def test_new(self): - import _numpypy as np + import numpypy as np assert np.int_(4) == 4 assert np.float_(3.4) == 3.4 def test_pow(self): - from _numpypy import int_ + from numpypy import int_ assert int_(4) ** 2 == 16 def test_bool(self): - import _numpypy as numpy + import numpypy as numpy assert numpy.bool_.mro() == [numpy.bool_, numpy.generic, object] assert numpy.bool_(3) is numpy.True_ @@ -341,7 +335,7 @@ assert numpy.bool_("False") is numpy.True_ def test_int8(self): - import _numpypy as numpy + import numpypy as numpy assert numpy.int8.mro() == [numpy.int8, numpy.signedinteger, numpy.integer, numpy.number, @@ -365,7 +359,7 @@ assert numpy.int8('128') == -128 def test_uint8(self): - import _numpypy as numpy + import numpypy as numpy assert numpy.uint8.mro() == [numpy.uint8, numpy.unsignedinteger, numpy.integer, numpy.number, @@ -390,7 +384,7 @@ assert numpy.uint8('256') == 0 def test_int16(self): - import _numpypy as numpy + import numpypy as numpy x = numpy.int16(3) assert x == 3 @@ -400,7 +394,7 @@ assert numpy.int16('32768') == -32768 def test_uint16(self): - import _numpypy as numpy + import numpypy as numpy assert numpy.uint16(65535) == 65535 assert numpy.uint16(65536) == 0 @@ -409,7 +403,7 @@ def test_int32(self): import sys - import _numpypy as numpy + import numpypy as numpy x = numpy.int32(23) assert x == 23 @@ -425,7 +419,7 @@ def test_uint32(self): import sys - import _numpypy as numpy + import numpypy as numpy assert numpy.uint32(10) == 10 @@ -436,7 +430,7 @@ assert numpy.uint32('4294967296') == 0 def test_int_(self): - import _numpypy as numpy + import numpypy as numpy assert numpy.int_ is numpy.dtype(int).type assert numpy.int_.mro() == [numpy.int_, numpy.signedinteger, @@ -445,7 +439,7 @@ def test_int64(self): import sys - import _numpypy as numpy + import numpypy as numpy if sys.maxsize == 2 ** 63 -1: assert numpy.int64.mro() == [numpy.int64, numpy.signedinteger, @@ -467,7 +461,7 @@ def test_uint64(self): import sys - import _numpypy as numpy + import numpypy as numpy assert numpy.uint64.mro() == [numpy.uint64, numpy.unsignedinteger, numpy.integer, numpy.number, @@ -484,7 +478,7 @@ raises(OverflowError, numpy.uint64(18446744073709551616)) def test_float16(self): - import _numpypy as numpy + import numpypy as numpy assert numpy.float16.mro() == [numpy.float16, numpy.floating, numpy.inexact, numpy.number, numpy.generic, object] @@ -495,7 +489,7 @@ def test_float32(self): - import _numpypy as numpy + import numpypy as numpy assert numpy.float32.mro() == [numpy.float32, numpy.floating, numpy.inexact, numpy.number, @@ -506,7 +500,7 @@ raises(ValueError, numpy.float32, '23.2df') def test_float64(self): - import _numpypy as numpy + import numpypy as numpy assert numpy.float64.mro() == [numpy.float64, numpy.floating, numpy.inexact, numpy.number, @@ -523,34 +517,20 @@ raises(ValueError, numpy.float64, '23.2df') def test_float_None(self): - import _numpypy as numpy + import numpypy as numpy from math import isnan assert isnan(numpy.float32(None)) assert isnan(numpy.float64(None)) - assert isnan(numpy.longdouble(None)) - - def test_longfloat(self): - import _numpypy as numpy - # it can be float96 or float128 - if numpy.longfloat != numpy.float64: - assert numpy.longfloat.mro()[1:] == [numpy.floating, - numpy.inexact, numpy.number, - numpy.generic, object] - a = numpy.array([1, 2, 3], numpy.longdouble) - assert type(a[1]) is numpy.longdouble - assert numpy.float64(12) == numpy.longdouble(12) - assert numpy.float64(12) == numpy.longfloat(12) - raises(ValueError, numpy.longfloat, '23.2df') def test_complex_floating(self): - import _numpypy as numpy + import numpypy as numpy assert numpy.complexfloating.__mro__ == (numpy.complexfloating, numpy.inexact, numpy.number, numpy.generic, object) def test_complex_format(self): import sys - import _numpypy as numpy + import numpypy as numpy for complex_ in (numpy.complex128, numpy.complex64,): for real, imag, should in [ @@ -590,7 +570,7 @@ assert "{:g}".format(numpy.complex_(0.5+1.5j)) == '{:g}'.format(0.5+1.5j) def test_complex(self): - import _numpypy as numpy + import numpypy as numpy assert numpy.complex_ is numpy.complex128 assert numpy.complex64.__mro__ == (numpy.complex64, @@ -608,7 +588,7 @@ assert d.char == 'F' def test_subclass_type(self): - import _numpypy as numpy + import numpypy as numpy class X(numpy.float64): def m(self): @@ -619,12 +599,12 @@ assert b.m() == 12 def test_long_as_index(self): - from _numpypy import int_, float64 + from numpypy import int_, float64 assert (1, 2, 3)[int_(1)] == 2 raises(TypeError, lambda: (1, 2, 3)[float64(1)]) def test_int(self): - from _numpypy import int32, int64, int_ + from numpypy import int32, int64, int_ import sys assert issubclass(int_, int) if sys.maxsize == (1<<31) - 1: @@ -635,7 +615,7 @@ assert int_ is int64 def test_various_types(self): - import _numpypy as numpy + import numpypy as numpy assert numpy.int16 is numpy.short assert numpy.int8 is numpy.byte @@ -648,7 +628,7 @@ assert numpy.uintp is numpy.uint64 def test_mro(self): - import _numpypy as numpy + import numpypy as numpy assert numpy.int16.__mro__ == (numpy.int16, numpy.signedinteger, numpy.integer, numpy.number, @@ -657,7 +637,7 @@ def test_operators(self): from operator import truediv - from _numpypy import float64, int_, True_, False_ + from numpypy import float64, int_, True_, False_ assert 5 / int_(2) == int_(2) assert truediv(int_(3), int_(2)) == float64(1.5) assert truediv(3, int_(2)) == float64(1.5) @@ -682,7 +662,7 @@ raises(TypeError, lambda: float64(3) & 1) def test_alternate_constructs(self): From noreply at buildbot.pypy.org Thu Feb 28 21:20:46 2013 From: noreply at buildbot.pypy.org (lwassermann) Date: Thu, 28 Feb 2013 21:20:46 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: fixed the error causing test-sequence impact Message-ID: <20130228202046.500D01C00A8@cobra.cs.uni-duesseldorf.de> Author: Lars Wassermann Branch: Changeset: r109:05d2c1f89455 Date: 2013-02-28 21:18 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/05d2c1f89455/ Log: fixed the error causing test-sequence impact test_bootstrappedimage now takes twice as long :) diff --git a/spyvm/primitives.py b/spyvm/primitives.py --- a/spyvm/primitives.py +++ b/spyvm/primitives.py @@ -460,11 +460,11 @@ match_w.append(w_obj) pending.extend(rgc.get_rpy_referents(gcref)) - while pending: - gcref = pending.pop() + while roots: + gcref = roots.pop() if rgc.get_gcflag_extra(gcref): rgc.toggle_gcflag_extra(gcref) - pending.extend(rgc.get_rpy_referents(gcref)) + roots.extend(rgc.get_rpy_referents(gcref)) s_frame.store_instances_array(match_w) try: @@ -472,14 +472,22 @@ except IndexError: raise PrimitiveFailedError() +def next_instance(space, list_of_objects, w_obj): + try: + retval = list_of_objects.pop() + # just in case, that one of the objects in the list changes its class + if retval.getclass(space).is_same_object(w_obj.getclass(space)): + return retval + else: + return next_instance(space, list_of_objects, w_obj) + except IndexError: + raise PrimitiveFailedError() + @expose_primitive(NEXT_INSTANCE, unwrap_spec=[object]) def func(interp, s_frame, w_obj): # This primitive is used to iterate through all instances of a class: # it returns the "next" instance after w_obj. - try: - return s_frame.instances_array().pop() - except IndexError: - raise PrimitiveFailedError() + return next_instance(interp.space, s_frame.instances_array(), w_obj) @expose_primitive(NEW_METHOD, unwrap_spec=[object, int, int]) def func(interp, s_frame, w_class, bytecount, header): diff --git a/spyvm/test/test_bootstrappedimage.py b/spyvm/test/test_bootstrappedimage.py --- a/spyvm/test/test_bootstrappedimage.py +++ b/spyvm/test/test_bootstrappedimage.py @@ -24,6 +24,11 @@ w_result = perform(tools.image.w_asSymbol, "asSymbol") assert w_result is tools.image.w_asSymbol +def test_create_new_symbol(): + w_result = perform(w("someString"), "asSymbol") + assert w_result is not None + assert w_result.as_string() == "someString" + def test_retrieve_symbol(): """asSymbol "This is the only place that new Symbols are created. A Symbol is created @@ -37,11 +42,6 @@ w_anotherSymbol = perform(w("someString"), "asSymbol") assert w_result is w_anotherSymbol -def test_create_new_symbol(): - w_result = perform(w("someString"), "asSymbol") - assert w_result is not None - assert w_result.as_string() == "someString" - def test_all_pointers_are_valid(): tools.test_all_pointers_are_valid() tools.test_lookup_abs_in_integer() From noreply at buildbot.pypy.org Thu Feb 28 22:14:21 2013 From: noreply at buildbot.pypy.org (fijal) Date: Thu, 28 Feb 2013 22:14:21 +0100 (CET) Subject: [pypy-commit] extradoc extradoc: more stuff Message-ID: <20130228211421.279C11C00A8@cobra.cs.uni-duesseldorf.de> Author: Maciej Fijalkowski Branch: extradoc Changeset: r4949:b3e503b87cfc Date: 2013-02-28 23:14 +0200 http://bitbucket.org/pypy/extradoc/changeset/b3e503b87cfc/ Log: more stuff diff --git a/blog/draft/10years.rst b/blog/draft/10years.rst --- a/blog/draft/10years.rst +++ b/blog/draft/10years.rst @@ -36,11 +36,18 @@ * The first time the Python interpreter successfully compiled to C, it segfaulted because the code generator used signed chars instead of unsigned chars... +* To make it more likely to be accepted, the proposal for the EU project contained basically every feature under the sun a language could have. This proved to be annoying, because we had to actually implement all that stuff. Then we had to do a cleanup sprint where we deleted 30% of codebase and 70% of features. + +* At one sprint someone proposed a new software development methodology: 'Terminology-Driven Programming' means to pick a fancy name, then discuss what it could mean, then implement it. Examples: timeshifter, rainbow interpreter, meta-space bubble, hint annotations (all but one of these really existed). + +* There is a conspiracy theory that the reason why translation is so slow is because time is stored away during it, which is later retrieved when an actual program runs to make them appear faster + Overall, it was a really long road. However, 10 years later we are in good shape. A quick look on the immediate future: we are approaching -PyPy 2.0, the support for Python 3 is taking shape, non-standard +PyPy 2.0 with stackless+JIT and cffi support, +the support for Python 3 is taking shape, non-standard extensions like STM are slowly getting ready (more soon), and there are -several non-Python interpreters around the corner (Topaz and more). +several non-Python interpreters around the corner (Hippy, Topaz and more). Cheers, fijal, arigo, cfbolz and the pypy team. From noreply at buildbot.pypy.org Thu Feb 28 22:50:23 2013 From: noreply at buildbot.pypy.org (lwassermann) Date: Thu, 28 Feb 2013 22:50:23 +0100 (CET) Subject: [pypy-commit] lang-smalltalk default: Reviewed all method in a squeak 4.3 which contain 'Essential' in it's source. Message-ID: <20130228215023.2CA0B1C00A8@cobra.cs.uni-duesseldorf.de> Author: Lars Wassermann Branch: Changeset: r110:20ee370e3cca Date: 2013-02-28 22:49 +0100 http://bitbucket.org/pypy/lang-smalltalk/changeset/20ee370e3cca/ Log: Reviewed all method in a squeak 4.3 which contain 'Essential' in it's source. Updated todo.txt to include the information I gathered diff --git a/spyvm/primitives.py b/spyvm/primitives.py --- a/spyvm/primitives.py +++ b/spyvm/primitives.py @@ -181,7 +181,7 @@ raise PrimitiveFailedError() return interp.space.wrap_int(receiver % argument) -# #// -- return the result of a division, rounded towards negative zero +# #// -- return the result of a division, rounded towards negative infinity @expose_primitive(DIV, unwrap_spec=[int, int]) def func(interp, s_frame, receiver, argument): if argument == 0: @@ -220,6 +220,7 @@ # Float Primitives _FLOAT_OFFSET = 40 +SMALLINT_AS_FLOAT = 40 FLOAT_ADD = 41 FLOAT_SUBTRACT = 42 # NB: 43 ... 48 are implemented above @@ -1049,6 +1050,13 @@ return activateClosure(interp, s_frame, w_block_closure, [w_a0], mayContextSwitch=False) # ___________________________________________________________________________ +# Override the default primitive to give latitude to the VM in context management. + +CTXT_AT = 210 +CTXT_AT_PUT = 211 +CTXT_SIZE = 212 + +# ___________________________________________________________________________ # PrimitiveLoadInstVar # # These are some wacky bytecodes in squeak. They are defined to do diff --git a/spyvm/todo.txt b/spyvm/todo.txt --- a/spyvm/todo.txt +++ b/spyvm/todo.txt @@ -5,10 +5,32 @@ [ ] SPECIAL_OBJECTS_ARRAY = 129 [ ] LOW_SPACE_SEMAPHORE = 124 [ ] INTERRUPT_SEMAPHORE = 134 +[ ] SIGNAL_AT_MILLISECONDS = 136 [ ] SIGNAL_AT_BYTES_LEFT = 125 [ ] IMAGE_NAME = 121 -[ ] BE_CURSOR = 101 +[ ] EXIT_TO_DEBUGGER = 114 # essential +[ ] QUIT = 113 # essential +[ ] PERFORM_IN_SUPERCLASS = 100 # essential, for the debugger +[ ] SNAPSHOT = 97 # essential, see also comment in only sender (as of Squeak 4.3) +[ ] SMALLINT_AS_FLOAT = 40 # essential +# the following are for graphics +[ ] BE_CURSOR = 101 # this primitive has two different implementations, dependent on the argument count [ ] BE_DISPLAY = 102 +[ ] GET_NEXT_EVENT = 94 + +ReValidate primitives +[ ] FLUSH_CACHE = 89 # ignored at the moment +[ ] VALUE_NO_CONTEXT_SWITCH = 221/222 # no context switch flag is ignored +[ ] STRING_AT = 63 # see comment there +[ ] OBJECT_AT_PUT = 69 # uncomment assert? +[ ] AT_PUT, SIZE 61/62 # because of its use in LargePositiveInteger>>#digitAt:put: and WideSymbol + +Primitives in Question +[ ] FLOAT_AT = 38 +[ ] FLOAT_AT_PUT = 39 + +Plugins +[ ] BitBlt Interpreter: [ ] Replace hardcoded fallback selectors with selectors from SpecialSelectorsArray