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

Reply via email to