Author: Philip Jenvey <pjen...@underboss.org> Branch: py3k Changeset: r60436:38b9fe11e79d Date: 2013-01-24 16:52 -0800 http://bitbucket.org/pypy/pypy/changeset/38b9fe11e79d/
Log: merge default 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/conftest.py b/lib-python/conftest.py --- a/lib-python/conftest.py +++ b/lib-python/conftest.py @@ -258,7 +258,7 @@ RegrTest('test_ioctl.py'), RegrTest('test_isinstance.py', core=True), RegrTest('test_iter.py', core=True), - RegrTest('test_iterlen.py'), + RegrTest('test_iterlen.py', core=True, usemodules="_collections itertools"), RegrTest('test_itertools.py', core=True, usemodules="itertools struct"), RegrTest('test_json.py'), RegrTest('test_keywordonlyarg.py'), diff --git a/pypy/doc/getting-started-python.rst b/pypy/doc/getting-started-python.rst --- a/pypy/doc/getting-started-python.rst +++ b/pypy/doc/getting-started-python.rst @@ -86,8 +86,8 @@ 4. Run:: - cd pypy/translator/goal - python translate.py --opt=jit targetpypystandalone.py + cd pypy/goal + python ../../rpython/bin/rpython --opt=jit targetpypystandalone.py possibly replacing ``--opt=jit`` with another `optimization level`_ of your choice like ``--opt=2`` if you do not want to include the JIT 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 @@ -521,7 +521,11 @@ return self.space.wrap(self.counter) def next(self): - self.deque.checklock(self.lock) + if self.lock is not self.deque.lock: + self.counter = 0 + raise OperationError( + self.space.w_RuntimeError, + self.space.wrap("deque mutated during iteration")) if self.counter == 0: raise OperationError(self.space.w_StopIteration, self.space.w_None) self.counter -= 1 @@ -560,7 +564,11 @@ return self.space.wrap(self.counter) def next(self): - self.deque.checklock(self.lock) + if self.lock is not self.deque.lock: + self.counter = 0 + raise OperationError( + self.space.w_RuntimeError, + self.space.wrap("deque mutated during iteration")) if self.counter == 0: raise OperationError(self.space.w_StopIteration, self.space.w_None) self.counter -= 1 diff --git a/pypy/module/pypyjit/test_pypy_c/test_thread.py b/pypy/module/pypyjit/test_pypy_c/test_thread.py --- a/pypy/module/pypyjit/test_pypy_c/test_thread.py +++ b/pypy/module/pypyjit/test_pypy_c/test_thread.py @@ -26,3 +26,25 @@ --THREAD-TICK-- jump(..., descr=...) """) + + def test_tls(self): + def main(n): + import thread + local = thread._local() + local.x = 1 + i = 0 + while i < n: + i += local.x + return 0 + log = self.run(main, [500]) + assert round(log.result, 6) == round(main(500), 6) + loop, = log.loops_by_filename(self.filepath) + assert loop.match(""" + i53 = int_lt(i48, i27) + guard_true(i53, descr=...) + i54 = int_add_ovf(i48, i47) + guard_no_overflow(descr=...) + --TICK-- + i58 = arraylen_gc(p43, descr=...) + jump(p0, p1, p3, p5, p10, p12, p14, i54, i27, i47, p45, p43, descr=...) + """) 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 @@ -447,6 +447,12 @@ space.warn("Century info guessed for a 2-digit year.", space.w_DeprecationWarning) + # 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 OperationError(space.w_ValueError, + space.wrap("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) @@ -455,12 +461,6 @@ rffi.setintfield(glob_buf, 'c_tm_yday', rffi.getintfield(glob_buf, 'c_tm_yday') - 1) - # 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') < 0: - raise OperationError(space.w_ValueError, - space.wrap("day of week out of range")) - return glob_buf def time(space): 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 @@ -30,6 +30,9 @@ w_dict = space.newdict(instance=True) 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 def _register_in_ec(self, ec): if not ec.space.config.translation.rweakref: @@ -60,10 +63,14 @@ def getdict(self, space): ec = space.getexecutioncontext() + 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) + self.last_ec = ec + self.last_dict = w_dict return w_dict def descr_local__new__(space, w_subtype, __args__): @@ -91,3 +98,5 @@ local = wref() if local is not None: del local.dicts[ec] + local.last_dict = None + local.last_ec = None 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 @@ -107,3 +107,54 @@ gc.collect() assert done == ['ok', 'del'] done.append('shutdown') + +def test_local_caching(): + from pypy.module.thread.os_local import Local + class FakeSpace: + def getexecutioncontext(self): + return self.ec + + def getattr(*args): + pass + def call_obj_args(*args): + pass + def newdict(*args, **kwargs): + return {} + def wrap(self, obj): + return obj + def type(self, obj): + return type(obj) + class config: + class translation: + rweakref = True + + class FakeEC: + def __init__(self, space): + self.space = space + self._thread_local_objs = None + space = FakeSpace() + ec1 = FakeEC(space) + space.ec = ec1 + + l = Local(space, None) + assert l.last_dict is l.dicts[ec1] + assert l.last_ec is ec1 + d1 = l.getdict(space) + assert d1 is l.last_dict + + ec2 = space.ec = FakeEC(space) + d2 = l.getdict(space) + assert l.last_dict is d2 + assert d2 is l.dicts[ec2] + assert l.last_ec is ec2 + dicts = l.dicts + l.dicts = "nope" + assert l.getdict(space) is d2 + l.dicts = dicts + + space.ec = ec1 + assert l.getdict(space) is d1 + l.dicts = "nope" + assert l.getdict(space) is d1 + l.dicts = dicts + 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 @@ -82,8 +82,7 @@ import unicodedata raises(TypeError, unicodedata.normalize, 'x') - @py.test.mark.skipif("sys.maxunicode < 0x10ffff", - reason="requires a 'wide' python build.") + @py.test.mark.skipif("sys.maxunicode < 0x10ffff") def test_normalize_wide(self): import unicodedata assert unicodedata.normalize('NFC', '\U000110a5\U000110ba') == u'\U000110ab' 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 @@ -54,6 +54,9 @@ # every module needs its own strategy, because the strategy stores # the version tag strategy = ModuleDictStrategy(space) + elif space.config.objspace.std.withmapdict and instance: + from pypy.objspace.std.mapdict import MapDictStrategy + strategy = space.fromcache(MapDictStrategy) # elif instance or strdict or module: # assert w_type is None @@ -352,7 +355,7 @@ self.pos = 0 def length(self): - if self.dictimplementation is not None: + if self.dictimplementation is not None and self.len != -1: return self.len - self.pos return 0 diff --git a/pypy/objspace/std/mapdict.py b/pypy/objspace/std/mapdict.py --- a/pypy/objspace/std/mapdict.py +++ b/pypy/objspace/std/mapdict.py @@ -591,6 +591,9 @@ # ____________________________________________________________ # dict implementation +def get_terminator_for_dicts(space): + return DictTerminator(space, None) + class MapDictStrategy(DictStrategy): erase, unerase = rerased.new_erasing_pair("map") @@ -600,13 +603,19 @@ def __init__(self, space): self.space = space + def get_empty_storage(self): + w_result = Object() + terminator = self.space.fromcache(get_terminator_for_dicts) + w_result._init_empty(terminator) + return self.erase(w_result) + def switch_to_object_strategy(self, w_dict): w_obj = self.unerase(w_dict.dstorage) strategy = self.space.fromcache(ObjectDictStrategy) dict_w = strategy.unerase(strategy.get_empty_storage()) w_dict.strategy = strategy w_dict.dstorage = strategy.erase(dict_w) - assert w_obj.getdict(self.space) is w_dict + assert w_obj.getdict(self.space) is w_dict or w_obj._get_mapdict_map().terminator.w_cls is None materialize_r_dict(self.space, w_obj, dict_w) def getitem(self, w_dict, w_key): diff --git a/pypy/objspace/std/setobject.py b/pypy/objspace/std/setobject.py --- a/pypy/objspace/std/setobject.py +++ b/pypy/objspace/std/setobject.py @@ -888,7 +888,7 @@ raise NotImplementedError def length(self): - if self.setimplementation is not None: + if self.setimplementation is not None and self.len != -1: return self.len - self.pos return 0 diff --git a/pypy/objspace/std/stringtype.py b/pypy/objspace/std/stringtype.py --- a/pypy/objspace/std/stringtype.py +++ b/pypy/objspace/std/stringtype.py @@ -4,7 +4,7 @@ from pypy.objspace.std.register_all import register_all from sys import maxint -from rpython.rlib.objectmodel import specialize +from rpython.rlib.objectmodel import newlist_hint, resizelist_hint, specialize from rpython.rlib.jit import we_are_jitted def wrapstr(space, s): @@ -306,8 +306,10 @@ space.wrap("cannot convert unicode object to bytes")) # sequence of bytes - data = [] w_iter = space.iter(w_source) + length_hint = space.length_hint(w_source, 0) + data = newlist_hint(length_hint) + extended = 0 while True: try: w_item = space.next(w_iter) @@ -317,6 +319,9 @@ break value = getbytevalue(space, w_item) data.append(value) + extended += 1 + if extended < length_hint: + resizelist_hint(data, extended) return data @unwrap_spec(encoding='str_or_None', errors='str_or_None') 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 @@ -1118,6 +1118,7 @@ withcelldict = False withmethodcache = False withidentitydict = False + withmapdict = False FakeSpace.config = Config() diff --git a/pypy/objspace/std/test/test_lengthhint.py b/pypy/objspace/std/test/test_lengthhint.py --- a/pypy/objspace/std/test/test_lengthhint.py +++ b/pypy/objspace/std/test/test_lengthhint.py @@ -6,7 +6,7 @@ SIZE = 4 ITEMS = range(SIZE) - def _test_length_hint(self, w_obj): + def _test_length_hint(self, w_obj, w_mutate=None): space = self.space assert space.length_hint(w_obj, 8) == self.SIZE @@ -18,6 +18,13 @@ space.next(w_iter) assert space.length_hint(w_iter, 8) == self.SIZE - 1 + if w_mutate is not None: + # Test handling of collections that enforce length + # immutability during iteration + space.call_function(w_mutate) + space.raises_w(space.w_RuntimeError, space.next, w_iter) + assert space.length_hint(w_iter, 8) == 0 + def test_bytearray(self): space = self.space w_bytearray = space.call_function(space.w_bytearray, @@ -31,16 +38,20 @@ self._test_length_hint(w_dict) def test_dict_iterkeys(self): - w_iterkeys = self.space.appexec([], """(): - return dict.fromkeys(%r).iterkeys() - """ % self.ITEMS) - self._test_length_hint(w_iterkeys) + space = self.space + w_iterkeys, w_mutate = space.fixedview(space.appexec([], """(): + d = dict.fromkeys(%r) + return d.iterkeys(), d.popitem + """ % self.ITEMS), 2) + self._test_length_hint(w_iterkeys, w_mutate) def test_dict_values(self): - w_itervalues = self.space.appexec([], """(): - return dict.fromkeys(%r).itervalues() - """ % self.ITEMS) - self._test_length_hint(w_itervalues) + space = self.space + w_itervalues, w_mutate = space.fixedview(space.appexec([], """(): + d = dict.fromkeys(%r) + return d.itervalues(), d.popitem + """ % self.ITEMS), 2) + self._test_length_hint(w_itervalues, w_mutate) def test_frozenset(self): space = self.space @@ -50,7 +61,8 @@ def test_set(self): space = self.space w_set = space.call_function(space.w_set, space.wrap(self.ITEMS)) - self._test_length_hint(w_set) + w_mutate = space.getattr(w_set, space.wrap('pop')) + self._test_length_hint(w_set, w_mutate) def test_list(self): self._test_length_hint(self.space.wrap(self.ITEMS)) @@ -107,12 +119,19 @@ self._test_length_hint(W_Repeat(space, space.wrap(22), space.wrap(self.SIZE))) - def test_collections_deque(self): + def _setup_deque(self): space = self.space w_deque = W_Deque(space) space.call_method(w_deque, '__init__', space.wrap(self.ITEMS)) - self._test_length_hint(w_deque) - self._test_length_hint(w_deque.reviter()) + w_mutate = space.getattr(w_deque, space.wrap('pop')) + return w_deque, w_mutate + + def test_collections_deque(self): + self._test_length_hint(*self._setup_deque()) + + def test_collections_deque_rev(self): + w_deque, w_mutate = self._setup_deque() + self._test_length_hint(w_deque.reviter(), w_mutate) def test_default(self): space = self.space diff --git a/pypy/objspace/std/test/test_mapdict.py b/pypy/objspace/std/test/test_mapdict.py --- a/pypy/objspace/std/test/test_mapdict.py +++ b/pypy/objspace/std/test/test_mapdict.py @@ -1,7 +1,17 @@ from pypy.objspace.std.test.test_dictmultiobject import FakeSpace, W_DictMultiObject from pypy.objspace.std.mapdict import * +class Config: + class objspace: + class std: + withsmalldicts = False + withcelldict = False + withmethodcache = False + withidentitydict = False + withmapdict = True + space = FakeSpace() +space.config = Config class Class(object): def __init__(self, hasdict=True): @@ -1069,3 +1079,11 @@ return A() """) assert w_dict.user_overridden_class + +def test_newdict_instance(): + w_dict = space.newdict(instance=True) + assert type(w_dict.strategy) is MapDictStrategy + +class TestMapDictImplementationUsingnewdict(BaseTestRDictImplementation): + StrategyClass = MapDictStrategy + # NB: the get_impl method is not overwritten here, as opposed to above _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit