Author: Armin Rigo <ar...@tunes.org> Branch: Changeset: r55072:b7d876adf124 Date: 2012-05-13 17:04 +0200 http://bitbucket.org/pypy/pypy/changeset/b7d876adf124/
Log: merge heads diff --git a/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py b/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py --- a/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py +++ b/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py @@ -5068,6 +5068,7 @@ self.optimize_strunicode_loop(ops, expected) def test_call_pure_vstring_const(self): + py.test.skip("implement me") ops = """ [] p0 = newstr(3) 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 @@ -312,22 +312,28 @@ class W_XRange(Wrappable): - def __init__(self, space, start, len, step): + def __init__(self, space, start, len, step, promote_step=False): self.space = space self.start = start self.len = len self.step = step + self.promote_step = promote_step - def descr_new(space, w_subtype, w_start, w_stop=None, w_step=1): + def descr_new(space, w_subtype, w_start, w_stop=None, w_step=None): start = _toint(space, w_start) - step = _toint(space, w_step) + if space.is_w(w_step, space.w_None): # no step argument provided + step = 1 + promote_step = True + else: + step = _toint(space, w_step) + promote_step = False if space.is_w(w_stop, space.w_None): # only 1 argument provided start, stop = 0, start else: stop = _toint(space, w_stop) howmany = get_len_of_range(space, start, stop, step) obj = space.allocate_instance(W_XRange, w_subtype) - W_XRange.__init__(obj, space, start, howmany, step) + W_XRange.__init__(obj, space, start, howmany, step, promote_step) return space.wrap(obj) def descr_repr(self): @@ -356,8 +362,14 @@ space.wrap("xrange object index out of range")) def descr_iter(self): - return self.space.wrap(W_XRangeIterator(self.space, self.start, - self.len, self.step)) + if self.promote_step and self.step == 1: + stop = self.start + self.len + return self.space.wrap(W_XRangeStepOneIterator(self.space, + self.start, + stop)) + else: + return self.space.wrap(W_XRangeIterator(self.space, self.start, + self.len, self.step)) def descr_reversed(self): lastitem = self.start + (self.len-1) * self.step @@ -399,6 +411,9 @@ return self.space.wrap(self) def descr_next(self): + return self.next() + + def next(self): if self.remaining > 0: item = self.current self.current = item + self.step @@ -418,9 +433,12 @@ w = space.wrap nt = space.newtuple - tup = [w(self.current), w(self.remaining), w(self.step)] + tup = [w(self.current), w(self.get_remaining()), w(self.step)] return nt([new_inst, nt(tup)]) + def get_remaining(self): + return self.remaining + W_XRangeIterator.typedef = TypeDef("rangeiterator", __iter__ = interp2app(W_XRangeIterator.descr_iter), # XXX __length_hint__() @@ -428,3 +446,20 @@ next = interp2app(W_XRangeIterator.descr_next), __reduce__ = interp2app(W_XRangeIterator.descr_reduce), ) + +class W_XRangeStepOneIterator(W_XRangeIterator): + def __init__(self, space, start, stop): + self.space = space + self.current = start + self.stop = stop + self.step = 1 + + def next(self): + if self.current < self.stop: + item = self.current + self.current = item + 1 + return self.space.wrap(item) + raise OperationError(self.space.w_StopIteration, self.space.w_None) + + def get_remaining(self): + return self.stop - self.current diff --git a/pypy/module/__builtin__/test/test_functional.py b/pypy/module/__builtin__/test/test_functional.py --- a/pypy/module/__builtin__/test/test_functional.py +++ b/pypy/module/__builtin__/test/test_functional.py @@ -164,6 +164,25 @@ y = callable(*args) assert list(y) == list(x) + def test_xrange_iter_reduce(self): + x = iter(xrange(2, 9, 3)) + x.next() + callable, args = x.__reduce__() + y = callable(*args) + assert list(y) == list(x) + + def test_xrange_iter_reduce_one(self): + x = iter(xrange(2, 9)) + x.next() + callable, args = x.__reduce__() + y = callable(*args) + assert list(y) == list(x) + + def test_lib_python_xrange_optimization(self): + x = xrange(1) + assert type(reversed(x)) == type(iter(x)) + + class AppTestReversed: def test_reversed(self): r = reversed("hello") diff --git a/pypy/module/pypyjit/test_pypy_c/test_misc.py b/pypy/module/pypyjit/test_pypy_c/test_misc.py --- a/pypy/module/pypyjit/test_pypy_c/test_misc.py +++ b/pypy/module/pypyjit/test_pypy_c/test_misc.py @@ -131,6 +131,36 @@ jump(..., descr=...) """) + def test_xrange_iter(self): + def main(n): + def g(n): + return xrange(n) + s = 0 + for i in xrange(n): # ID: for + tmp = g(n) + s += tmp[i] # ID: getitem + a = 0 + return s + # + log = self.run(main, [1000]) + assert log.result == 1000 * 999 / 2 + loop, = log.loops_by_filename(self.filepath) + assert loop.match(""" + i15 = int_lt(i10, i11) + guard_true(i15, descr=...) + i17 = int_add(i10, 1) + i18 = force_token() + setfield_gc(p9, i17, descr=<.* .*W_XRangeIterator.inst_current .*>) + guard_not_invalidated(descr=...) + i21 = int_lt(i10, 0) + guard_false(i21, descr=...) + i22 = int_lt(i10, i14) + guard_true(i22, descr=...) + i23 = int_add_ovf(i6, i10) + guard_no_overflow(descr=...) + --TICK-- + jump(..., descr=...) + """) def test_range_iter(self): def main(n): 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 @@ -7,7 +7,8 @@ from pypy.interpreter import gateway #XXX # the release serial 42 is not in range(16) -CPYTHON_VERSION = (2, 7, 2, "final", 42) #XXX # sync patchlevel.h +CPYTHON_VERSION = (2, 7, 2, "final", 42) +#XXX # sync CPYTHON_VERSION with patchlevel.h, package.py CPYTHON_API_VERSION = 1013 #XXX # sync with include/modsupport.h PYPY_VERSION = (1, 9, 1, "dev", 0) #XXX # sync patchlevel.h diff --git a/pypy/rpython/lltypesystem/rdict.py b/pypy/rpython/lltypesystem/rdict.py --- a/pypy/rpython/lltypesystem/rdict.py +++ b/pypy/rpython/lltypesystem/rdict.py @@ -502,8 +502,6 @@ raise KeyError _ll_dict_del(d, i) -# XXX: Move the size checking and resize into a single call which is opauqe to -# the JIT when the dict isn't virtual, to avoid extra branches. @jit.look_inside_iff(lambda d, i: jit.isvirtual(d) and jit.isconstant(i)) def _ll_dict_del(d, i): d.entries.mark_deleted(i) @@ -516,18 +514,32 @@ entry.key = lltype.nullptr(ENTRY.key.TO) if ENTRIES.must_clear_value: entry.value = lltype.nullptr(ENTRY.value.TO) - num_entries = len(d.entries) - if num_entries > DICT_INITSIZE and d.num_items < num_entries / 4: - ll_dict_resize(d) + # + # The rest is commented out: like CPython we no longer shrink the + # dictionary here. It may shrink later if we try to append a number + # of new items to it. Unsure if this behavior was designed in + # CPython or is accidental. A design reason would be that if you + # delete all items in a dictionary (e.g. with a series of + # popitem()), then CPython avoids shrinking the table several times. + #num_entries = len(d.entries) + #if num_entries > DICT_INITSIZE and d.num_items <= num_entries / 4: + # ll_dict_resize(d) + # A previous xxx: move the size checking and resize into a single + # call which is opaque to the JIT when the dict isn't virtual, to + # avoid extra branches. def ll_dict_resize(d): old_entries = d.entries old_size = len(old_entries) # make a 'new_size' estimate and shrink it if there are many - # deleted entry markers - new_size = old_size * 2 - while new_size > DICT_INITSIZE and d.num_items < new_size / 4: - new_size /= 2 + # deleted entry markers. See CPython for why it is a good idea to + # quadruple the dictionary size as long as it's not too big. + if d.num_items > 50000: new_estimate = d.num_items * 2 + else: new_estimate = d.num_items * 4 + new_size = DICT_INITSIZE + while new_size <= new_estimate: + new_size *= 2 + # d.entries = lltype.typeOf(old_entries).TO.allocate(new_size) d.num_items = 0 d.resize_counter = new_size * 2 diff --git a/pypy/rpython/module/ll_os.py b/pypy/rpython/module/ll_os.py --- a/pypy/rpython/module/ll_os.py +++ b/pypy/rpython/module/ll_os.py @@ -977,7 +977,7 @@ os_lseek = self.llexternal(funcname, [rffi.INT, rffi.LONGLONG, rffi.INT], - rffi.LONGLONG) + rffi.LONGLONG, macro=True) def lseek_llimpl(fd, pos, how): rposix.validate_fd(fd) diff --git a/pypy/rpython/test/test_llinterp.py b/pypy/rpython/test/test_llinterp.py --- a/pypy/rpython/test/test_llinterp.py +++ b/pypy/rpython/test/test_llinterp.py @@ -137,7 +137,7 @@ info = py.test.raises(LLException, "interp.eval_graph(graph, values)") try: got = interp.find_exception(info.value) - except ValueError as message: + except ValueError, message: got = 'None %r' % message assert got is exc, "wrong exception type, expected %r got %r" % (exc, got) diff --git a/pypy/rpython/test/test_rdict.py b/pypy/rpython/test/test_rdict.py --- a/pypy/rpython/test/test_rdict.py +++ b/pypy/rpython/test/test_rdict.py @@ -749,13 +749,20 @@ assert count_frees >= 3 def test_dict_resize(self): + # XXX we no longer automatically resize on 'del'. We need to + # hack a bit in this test to trigger a resize by continuing to + # fill the dict's table while keeping the actual size very low + # in order to force a resize to shrink the table back def func(want_empty): d = {} - for i in range(rdict.DICT_INITSIZE): + for i in range(rdict.DICT_INITSIZE << 1): d[chr(ord('a') + i)] = i if want_empty: - for i in range(rdict.DICT_INITSIZE): + for i in range(rdict.DICT_INITSIZE << 1): del d[chr(ord('a') + i)] + for i in range(rdict.DICT_INITSIZE << 3): + d[chr(ord('A') - i)] = i + del d[chr(ord('A') - i)] return d res = self.interpret(func, [0]) assert len(res.entries) > rdict.DICT_INITSIZE 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 @@ -21,6 +21,8 @@ USE_ZIPFILE_MODULE = sys.platform == 'win32' +STDLIB_VER = "2.7" + def ignore_patterns(*patterns): """Function that can be used as copytree() ignore parameter. @@ -77,8 +79,8 @@ pypydir = builddir.ensure(name, dir=True) # Careful: to copy lib_pypy, copying just the svn-tracked files # would not be enough: there are also ctypes_config_cache/_*_cache.py. - shutil.copytree(str(basedir.join('lib-python')), - str(pypydir.join('lib-python')), + shutil.copytree(str(basedir.join('lib-python').join(STDLIB_VER)), + str(pypydir.join('lib-python').join(STDLIB_VER)), ignore=ignore_patterns('.svn', 'py', '*.pyc', '*~')) shutil.copytree(str(basedir.join('lib_pypy')), str(pypydir.join('lib_pypy')), diff --git a/pypy/tool/test/test_package.py b/pypy/tool/test/test_package.py new file mode 100644 --- /dev/null +++ b/pypy/tool/test/test_package.py @@ -0,0 +1,6 @@ +from pypy.tool.release import package +from pypy.module.sys import version + +def test_version(): + assert package.STDLIB_VER == '%d.%d' % (version.CPYTHON_VERSION[0], + version.CPYTHON_VERSION[1]) diff --git a/pypy/translator/c/test/test_extfunc.py b/pypy/translator/c/test/test_extfunc.py --- a/pypy/translator/c/test/test_extfunc.py +++ b/pypy/translator/c/test/test_extfunc.py @@ -134,6 +134,13 @@ res = os.lseek(fd, -r5200000000, 2) assert res == r4800000000 os.close(fd) + try: + os.lseek(fd, 0, 0) + except OSError: + pass + else: + print "DID NOT RAISE" + raise AssertionError st = os.stat(filename) assert st.st_size == r10000000000 does_stuff() diff --git a/pypy/translator/goal/win32/gc_patch_windows.py b/pypy/translator/goal/win32/gc_patch_windows.py deleted file mode 100644 --- a/pypy/translator/goal/win32/gc_patch_windows.py +++ /dev/null @@ -1,129 +0,0 @@ -# patches for the Boehm GC for PyPy under Windows - -""" -This file is obsolete now since gc-7.0 / gc-7.1 . -Please use the instructions in pypy\doc\windows.rst . - -How to build a pypy compatible version of the Boehm collector -for Windows and Visual Studio .net 2003. - -First of all, download the official Boehm collector suite -from http://www.hpl.hp.com/personal/Hans_Boehm/gc/gc_source/gc.tar.gz -At the time of writing (2005-10-06) this contains version gc6.5 . - -Unpack this folder somewhere, for instance to "d:\tmp". -Change to this folder using - -d: -cd \tmp\gc6.5 - -Then copy the file NT_THREADS_MAKEFILE to Makefile: - -copy NT_THREADS_MAKEFILE Makefile - -This file is the general-purpose gc dll makefile. For some internal -reasons, this file's defaults are bad for PyPy. The early initialisation -in DllMain() inhibits the changes necessary for PyPy. Use this script to -do a patch: (assuming that you have d:\pypy\dist\pypy\translator\goal) - -python d:\pypy\dist\pypy\translator\goal\win32\gc_patch_windows.py - -Now, your makefile is patched a little bit. In particular, - -ALL_INTERIOR_POINTERS is now undefined, which PyPy wants to have -NO_GETENV is specified, since we don't want dependencies - -and the name of the .lib and .dll files is changed to gc_pypy.??? - -Now you need to build your gc, either as a debug or as a release -build. First of all, make sure that you have your environment prepared. -Please note that you will need to use Microsoft's cmd, as cygwin bash -doesn't correctly handle the batch file in the next step. - -With my setup, I have to do - -"e:\Programme\Microsoft Visual Studio .NET 2003\Vc7\bin\vcvars32.bat" - -After that, you can either build a release or a debug gc. - -After a successful build, you need to enable gc_pypy.dll for your compiler. -There are many ways to install this. The following recommendation just -works without changing your environment variables. I think this is the -easiest way possible, but this is a matter of taste. What I did is: - -nmake CFG="gc - Win32 Release" - -After the build, you will find a gc_pypy.dll file in the Release folder. -Copy this file to c:\windows\system32 or any other folder that is always -in your PATH variable. - -Also, copy Release\gc_pypy.lib to (in my case) -"e:\Programme\Microsoft Visual Studio .NET 2003\Vc7\lib"; - -finally, copy d:\tmp\gc6.5\include to -"e:\Programme\Microsoft Visual Studio .NET 2003\Vc7\include" -and rename this folder to "gc", so that "gc/gc.h" is valid. - -That's all, folks! - -In case of a debug build, replace "Release" by "Debug", and also copy -gc_pypy.pdb to your lib folder. This allows you to use source-level -debugging. Please note: If you want to both build the default gc.dll -and gc_pypy.dll, please delete the Debug resp. Release folders in -between. The generated .sbr files are in the way. - -Please use the above recipe and report any bugs to me. -In case of trouble, I also can provide you with pre-built dlls. -Note: We also could have solved this by including the gc source -into the PyPy build. This may or may not become necessary if something -changes dramatically, again. As long as this is not needed, I prefer -this simple solution. - -Summary transcript of the steps involved: (please adjust paths) - -d: -cd \tmp\gc6.5 -copy NT_THREADS_MAKEFILE Makefile -python d:\pypy\dist\pypy\translator\goal\win32\gc_patch_windows.py -"e:\Programme\Microsoft Visual Studio .NET 2003\Vc7\bin\vcvars32.bat" -nmake CFG="gc - Win32 Release" -copy Release\gc_pypy.dll c:\windows\system32 -copy Release\gc_pypy.lib "e:\Programme\Microsoft Visual Studio .NET 2003\Vc7\lib" -mkdir "e:\Programme\Microsoft Visual Studio .NET 2003\Vc7\include\gc" -copy include "e:\Programme\Microsoft Visual Studio .NET 2003\Vc7\include\gc" - -cheers - chris -""" - -REPLACE = { - '"ALL_INTERIOR_POINTERS"': '"NO_GETENV"', - } - -for ending in "lib exp map pdb bsc dll pch".split(): - REPLACE["gc.%s" % ending] = "gc_pypy.%s" % ending - -def change_settings(src): - for old, new in REPLACE.items(): - newsrc = src.replace(old, new) - if newsrc == src: - raise ValueError, "this makefile does not contain %s" % old - src = newsrc - return src - -def find_file(): - import os - for name in os.listdir("."): - if name.lower() == 'makefile': - return name - else: - raise ValueError, 'Makefile not found' - -try: - name = find_file() - source = change_settings(file(name).read()) - file(name, "w").write(source) - print "Updated your Makefile to fit PyPy's needs. Your lib will be named gc_pypy.dll" - print "and gc_pypy.lib. Please put them into appropriate places, see __doc__." -except: - print __doc__ - raise _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit