Author: Manuel Jacob <m...@manueljacob.de>
Branch: py3k
Changeset: r78397:2ac10a3a0884
Date: 2015-07-02 01:54 +0200
http://bitbucket.org/pypy/pypy/changeset/2ac10a3a0884/

Log:    hg merge default

diff --git a/lib-python/2.7/test/test_urllib2.py 
b/lib-python/2.7/test/test_urllib2.py
--- a/lib-python/2.7/test/test_urllib2.py
+++ b/lib-python/2.7/test/test_urllib2.py
@@ -291,6 +291,7 @@
         self.req_headers = []
         self.data = None
         self.raise_on_endheaders = False
+        self.sock = None
         self._tunnel_headers = {}
 
     def __call__(self, host, timeout=socket._GLOBAL_DEFAULT_TIMEOUT):
diff --git a/lib-python/2.7/urllib2.py b/lib-python/2.7/urllib2.py
--- a/lib-python/2.7/urllib2.py
+++ b/lib-python/2.7/urllib2.py
@@ -1200,6 +1200,12 @@
                 r = h.getresponse(buffering=True)
             except TypeError: # buffering kw not supported
                 r = h.getresponse()
+            # If the server does not send us a 'Connection: close' header,
+            # HTTPConnection assumes the socket should be left open. Manually
+            # mark the socket to be closed when this response object goes away.
+            if h.sock:
+                h.sock.close()
+                h.sock = None
 
         # Pick apart the HTTPResponse object to get the addinfourl
         # object initialized properly.
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
@@ -135,7 +135,7 @@
 Here are some more technical details.  This issue affects the precise
 time at which ``__del__`` methods are called, which
 is not reliable in PyPy (nor Jython nor IronPython).  It also means that
-weak references may stay alive for a bit longer than expected.  This
+**weak references** may stay alive for a bit longer than expected.  This
 makes "weak proxies" (as returned by ``weakref.proxy()``) somewhat less
 useful: they will appear to stay alive for a bit longer in PyPy, and
 suddenly they will really be dead, raising a ``ReferenceError`` on the
@@ -143,6 +143,24 @@
 ``ReferenceError`` at any place that uses them.  (Or, better yet, don't use
 ``weakref.proxy()`` at all; use ``weakref.ref()``.)
 
+Note a detail in the `documentation for weakref callbacks`__:
+
+    If callback is provided and not None, *and the returned weakref
+    object is still alive,* the callback will be called when the object
+    is about to be finalized.
+
+There are cases where, due to CPython's refcount semantics, a weakref
+dies immediately before or after the objects it points to (typically
+with some circular reference).  If it happens to die just after, then
+the callback will be invoked.  In a similar case in PyPy, both the
+object and the weakref will be considered as dead at the same time,
+and the callback will not be invoked.  (Issue `#2030`__)
+
+.. __: https://docs.python.org/2/library/weakref.html
+.. __: https://bitbucket.org/pypy/pypy/issue/2030/
+
+---------------------------------
+
 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
@@ -321,9 +339,8 @@
 Miscellaneous
 -------------
 
-* Hash randomization (``-R``) is ignored in PyPy.  As documented in
-  http://bugs.python.org/issue14621, some of us believe it has no
-  purpose in CPython either.
+* Hash randomization (``-R``) `is ignored in PyPy`_.  In CPython
+  before 3.4 it has `little point`_.
 
 * You can't store non-string keys in type objects.  For example::
 
@@ -338,7 +355,8 @@
   for about 1400 calls.
 
 * since the implementation of dictionary is different, the exact number
-  which ``__hash__`` and ``__eq__`` are called is different. Since CPython
+  of times that ``__hash__`` and ``__eq__`` are called is different. 
+  Since CPython
   does not give any specific guarantees either, don't rely on it.
 
 * assignment to ``__class__`` is limited to the cases where it
@@ -395,3 +413,12 @@
   interactive mode. In a released version, this behaviour is suppressed, but
   setting the environment variable PYPY_IRC_TOPIC will bring it back. Note that
   downstream package providers have been known to totally disable this feature.
+
+* PyPy's readline module was rewritten from scratch: it is not GNU's
+  readline.  It should be mostly compatible, and it adds multiline
+  support (see ``multiline_input()``).  On the other hand,
+  ``parse_and_bind()`` calls are ignored (issue `#2072`_).
+
+.. _`is ignored in PyPy`: http://bugs.python.org/issue14621
+.. _`little point`: 
http://events.ccc.de/congress/2012/Fahrplan/events/5152.en.html
+.. _`#2072`: https://bitbucket.org/pypy/pypy/issue/2072/
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
@@ -225,9 +225,13 @@
         if (isinstance(w_cdata, cdataobj.W_CDataNewOwning) or
             isinstance(w_cdata, cdataobj.W_CDataPtrToStructOrUnion)):
             if i != 0:
-                space = self.space
-                raise oefmt(space.w_IndexError,
+                raise oefmt(self.space.w_IndexError,
                             "cdata '%s' can only be indexed by 0", self.name)
+        else:
+            if not w_cdata.unsafe_escaping_ptr():
+                raise oefmt(self.space.w_RuntimeError,
+                            "cannot dereference null pointer from cdata '%s'",
+                            self.name)
         return self
 
     def _check_slice_index(self, w_cdata, start, stop):
diff --git a/pypy/module/_cffi_backend/lib_obj.py 
b/pypy/module/_cffi_backend/lib_obj.py
--- a/pypy/module/_cffi_backend/lib_obj.py
+++ b/pypy/module/_cffi_backend/lib_obj.py
@@ -175,6 +175,8 @@
                     return self.dir1(ignore_type=cffi_opcode.OP_GLOBAL_VAR)
                 if is_getattr and attr == '__dict__':
                     return self.full_dict_copy()
+                if is_getattr and attr == '__name__':
+                    return self.descr_repr()
                 raise oefmt(self.space.w_AttributeError,
                             "cffi library '%s' has no function, constant "
                             "or global variable named '%s'",
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
@@ -2099,8 +2099,7 @@
     p = cast(BVoidP, 123456)
     py.test.raises(TypeError, "p[0]")
     p = cast(BVoidP, 0)
-    if 'PY_DOT_PY' in globals(): py.test.skip("NULL crashes early on py.py")
-    py.test.raises(TypeError, "p[0]")
+    py.test.raises((TypeError, RuntimeError), "p[0]")
 
 def test_iter():
     BInt = new_primitive_type("int")
@@ -3333,6 +3332,15 @@
     check(4 | 8,  "CHB", "GTB")
     check(4 | 16, "CHB", "ROB")
 
+def test_dereference_null_ptr():
+    BInt = new_primitive_type("int")
+    BIntPtr = new_pointer_type(BInt)
+    p = cast(BIntPtr, 0)
+    py.test.raises(RuntimeError, "p[0]")
+    py.test.raises(RuntimeError, "p[0] = 42")
+    py.test.raises(RuntimeError, "p[42]")
+    py.test.raises(RuntimeError, "p[42] = -1")
+
 def test_version():
     # this test is here mostly for PyPy
     assert __version__ == "1.1.2"
diff --git a/pypy/module/_cffi_backend/test/test_recompiler.py 
b/pypy/module/_cffi_backend/test/test_recompiler.py
--- a/pypy/module/_cffi_backend/test/test_recompiler.py
+++ b/pypy/module/_cffi_backend/test/test_recompiler.py
@@ -1011,3 +1011,4 @@
         assert MYFOO == 42
         assert hasattr(lib, '__dict__')
         assert lib.__all__ == ['MYFOO', 'mybar']   # but not 'myvar'
+        assert lib.__name__ == repr(lib)
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
@@ -457,6 +457,8 @@
                 {"mode": "w+", "buffering": 2},
                 {"mode": "w+b", "buffering": 0},
             ]:
+            if "b" not in kwargs["mode"]:
+                kwargs["encoding"] = "ascii"
             f = _io.open(self.tmpfile, **kwargs)
             f.close()
             raises(ValueError, f.flush)
diff --git a/pypy/module/_rawffi/callback.py b/pypy/module/_rawffi/callback.py
--- a/pypy/module/_rawffi/callback.py
+++ b/pypy/module/_rawffi/callback.py
@@ -27,8 +27,10 @@
     callback_ptr = global_counter.get(userdata.addarg)
     w_callable = callback_ptr.w_callable
     argtypes = callback_ptr.argtypes
+    must_leave = False
     space = callback_ptr.space
     try:
+        must_leave = space.threadlocals.try_enter_thread(space)
         args_w = [None] * len(argtypes)
         for i in range(len(argtypes)):
             argtype = argtypes[i]
@@ -50,6 +52,8 @@
             resshape = letter2tp(space, callback_ptr.result)
             for i in range(resshape.size):
                 ll_res[i] = '\x00'
+    if must_leave:
+        space.threadlocals.leave_thread(space)
 
 class W_CallbackPtr(W_DataInstance):
 
@@ -75,6 +79,14 @@
         if tracker.DO_TRACING:
             addr = rffi.cast(lltype.Signed, self.ll_callback.ll_closure)
             tracker.trace_allocation(addr, self)
+        #
+        # We must setup the GIL here, in case the callback is invoked in
+        # some other non-Pythonic thread.  This is the same as ctypes on
+        # CPython (but only when creating a callback; on CPython it occurs
+        # as soon as we import _ctypes)
+        if space.config.translation.thread:
+            from pypy.module.thread.os_thread import setup_threads
+            setup_threads(space)
 
     def free(self):
         if tracker.DO_TRACING:
diff --git a/pypy/module/_ssl/interp_ssl.py b/pypy/module/_ssl/interp_ssl.py
--- a/pypy/module/_ssl/interp_ssl.py
+++ b/pypy/module/_ssl/interp_ssl.py
@@ -141,7 +141,7 @@
     def __init__(self, ctx, protos):
         self.protos = protos
         self.buf, self.pinned, self.is_raw = rffi.get_nonmovingbuffer(protos)
-        NPN_STORAGE.set(r_uint(rffi.cast(rffi.UINT, self.buf)), self)
+        NPN_STORAGE.set(rffi.cast(lltype.Unsigned, self.buf), self)
 
         # set both server and client callbacks, because the context
         # can be used to create both types of sockets
@@ -156,7 +156,7 @@
 
     @staticmethod
     def advertiseNPN_cb(s, data_ptr, len_ptr, args):
-        npn = NPN_STORAGE.get(r_uint(rffi.cast(rffi.UINT, args)))
+        npn = NPN_STORAGE.get(rffi.cast(lltype.Unsigned, args))
         if npn and npn.protos:
             data_ptr[0] = npn.buf
             len_ptr[0] = rffi.cast(rffi.UINT, len(npn.protos))
@@ -168,7 +168,7 @@
 
     @staticmethod
     def selectNPN_cb(s, out_ptr, outlen_ptr, server, server_len, args):
-        npn = NPN_STORAGE.get(r_uint(rffi.cast(rffi.UINT, args)))
+        npn = NPN_STORAGE.get(rffi.cast(lltype.Unsigned, args))
         if npn and npn.protos:
             client = npn.buf
             client_len = len(npn.protos)
@@ -187,7 +187,7 @@
     def __init__(self, ctx, protos):
         self.protos = protos
         self.buf, self.pinned, self.is_raw = rffi.get_nonmovingbuffer(protos)
-        ALPN_STORAGE.set(r_uint(rffi.cast(rffi.UINT, self.buf)), self)
+        ALPN_STORAGE.set(rffi.cast(lltype.Unsigned, self.buf), self)
 
         with rffi.scoped_str2charp(protos) as protos_buf:
             if libssl_SSL_CTX_set_alpn_protos(
@@ -202,7 +202,7 @@
 
     @staticmethod
     def selectALPN_cb(s, out_ptr, outlen_ptr, client, client_len, args):
-        alpn = ALPN_STORAGE.get(r_uint(rffi.cast(rffi.UINT, args)))
+        alpn = ALPN_STORAGE.get(rffi.cast(lltype.Unsigned, args))
         if alpn and alpn.protos:
             server = alpn.buf
             server_len = len(alpn.protos)
diff --git a/pypy/module/_vmprof/interp_vmprof.py 
b/pypy/module/_vmprof/interp_vmprof.py
--- a/pypy/module/_vmprof/interp_vmprof.py
+++ b/pypy/module/_vmprof/interp_vmprof.py
@@ -26,7 +26,7 @@
 eci_kwds = dict(
     include_dirs = [SRC],
     includes = ['vmprof.h', 'trampoline.h'],
-    separate_module_files = [SRC.join('trampoline.asmgcc.s')],
+    separate_module_files = [SRC.join('trampoline.vmprof.s')],
     libraries = ['dl'],
     
     post_include_bits=["""
diff --git a/pypy/module/_vmprof/src/trampoline.asmgcc.s 
b/pypy/module/_vmprof/src/trampoline.asmgcc.s
deleted file mode 100644
--- a/pypy/module/_vmprof/src/trampoline.asmgcc.s
+++ /dev/null
@@ -1,16 +0,0 @@
-// NOTE: you need to use TABs, not spaces!
-        
-       .text
-       .p2align 4,,-1
-       .globl  pypy_execute_frame_trampoline
-       .type   pypy_execute_frame_trampoline, @function
-pypy_execute_frame_trampoline:
-       .cfi_startproc
-       pushq   %rcx
-       .cfi_def_cfa_offset 16
-       call pypy_pyframe_execute_frame@PLT
-       popq    %rcx
-       .cfi_def_cfa_offset 8
-       ret
-       .cfi_endproc
-       .size   pypy_execute_frame_trampoline, .-pypy_execute_frame_trampoline
diff --git a/pypy/module/_vmprof/src/trampoline.vmprof.s 
b/pypy/module/_vmprof/src/trampoline.vmprof.s
new file mode 100644
--- /dev/null
+++ b/pypy/module/_vmprof/src/trampoline.vmprof.s
@@ -0,0 +1,15 @@
+// NOTE: you need to use TABs, not spaces!
+        
+       .text
+       .globl  pypy_execute_frame_trampoline
+       .type   pypy_execute_frame_trampoline, @function
+pypy_execute_frame_trampoline:
+       .cfi_startproc
+       pushq   %rcx
+       .cfi_def_cfa_offset 16
+       call pypy_pyframe_execute_frame@PLT
+       popq    %rcx
+       .cfi_def_cfa_offset 8
+       ret
+       .cfi_endproc
+       .size   pypy_execute_frame_trampoline, .-pypy_execute_frame_trampoline
diff --git a/pypy/module/_vmprof/src/vmprof.c b/pypy/module/_vmprof/src/vmprof.c
--- a/pypy/module/_vmprof/src/vmprof.c
+++ b/pypy/module/_vmprof/src/vmprof.c
@@ -305,7 +305,6 @@
 
 static int remove_sigprof_timer(void) {
     static struct itimerval timer;
-    last_period_usec = 0;
     timer.it_interval.tv_sec = 0;
     timer.it_interval.tv_usec = 0;
     timer.it_value.tv_sec = 0;
@@ -317,11 +316,15 @@
 }
 
 static void atfork_disable_timer(void) {
-    remove_sigprof_timer();
+    if (last_period_usec) {
+        remove_sigprof_timer();
+    }
 }
 
 static void atfork_enable_timer(void) {
-    install_sigprof_timer(last_period_usec);
+    if (last_period_usec) {
+        install_sigprof_timer(last_period_usec);
+    }
 }
 
 static int install_pthread_atfork_hooks(void) {
@@ -412,6 +415,7 @@
     if (remove_sigprof_timer() == -1) {
                return -1;
        }
+    last_period_usec = 0;
     if (remove_sigprof_handler() == -1) {
                return -1;
        }
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
@@ -338,9 +338,11 @@
                 w_all = try_getattr(space, w_mod, space.wrap('__all__'))
                 if w_all is not None:
                     fromlist_w = space.fixedview(w_all)
-            for w_name in fromlist_w:
-                if try_getattr(space, w_mod, w_name) is None:
-                    return None
+            else:
+                # this only runs if fromlist_w != ['*']
+                for w_name in fromlist_w:
+                    if try_getattr(space, w_mod, w_name) is None:
+                        return None
         return w_mod
     return first
 
@@ -378,10 +380,12 @@
                 w_all = try_getattr(space, w_mod, w('__all__'))
                 if w_all is not None:
                     fromlist_w = space.fixedview(w_all)
-            for w_name in fromlist_w:
-                if try_getattr(space, w_mod, w_name) is None:
-                    load_part(space, w_path, prefix, space.str0_w(w_name),
-                              w_mod, tentative=1)
+            else:
+                # this only runs if fromlist_w != ['*']
+                for w_name in fromlist_w:
+                    if try_getattr(space, w_mod, w_name) is None:
+                        load_part(space, w_path, prefix, space.str0_w(w_name),
+                                  w_mod, tentative=1)
         return w_mod
     else:
         return first
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
@@ -1373,6 +1373,53 @@
         finally:
             sys.path_hooks.pop()
 
+    def test_meta_path_import_error_1(self):
+        # as far as I can tell, the problem is that in CPython, if you
+        # use an import hook that doesn't update sys.modules, then the
+        # import succeeds; but at the same time, you can have the same
+        # result without an import hook (see test_del_from_sys_modules)
+        # and then the import fails.  This looks like even more mess
+        # to replicate, so we ignore it until someone really hits this
+        # case...
+        skip("looks like an inconsistency in CPython")
+
+        class ImportHook(object):
+            def find_module(self, fullname, path=None):
+                assert not fullname.endswith('*')
+                if fullname == 'meta_path_pseudo_module':
+                    return self
+            def load_module(self, fullname):
+                assert fullname == 'meta_path_pseudo_module'
+                # we "forget" to update sys.modules
+                return new.module('meta_path_pseudo_module')
+
+        import sys, new
+        sys.meta_path.append(ImportHook())
+        try:
+            import meta_path_pseudo_module
+        finally:
+            sys.meta_path.pop()
+
+    def test_meta_path_import_star_2(self):
+        class ImportHook(object):
+            def find_module(self, fullname, path=None):
+                if fullname.startswith('meta_path_2_pseudo_module'):
+                    return self
+            def load_module(self, fullname):
+                assert fullname == 'meta_path_2_pseudo_module'
+                m = new.module('meta_path_2_pseudo_module')
+                m.__path__ = ['/some/random/dir']
+                sys.modules['meta_path_2_pseudo_module'] = m
+                return m
+
+        import sys, new
+        sys.meta_path.append(ImportHook())
+        try:
+            exec "from meta_path_2_pseudo_module import *" in {}
+        finally:
+            sys.meta_path.pop()
+
+
 class AppTestPyPyExtension(object):
     spaceconfig = dict(usemodules=['imp', 'zipimport', '__pypy__'])
 
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
@@ -645,7 +645,7 @@
     next_item = _new_next('item')
 
 
-def create_iterator_classes(dictimpl, override_next_item=None):
+def create_iterator_classes(dictimpl):
     if not hasattr(dictimpl, 'wrapkey'):
         wrapkey = lambda space, key: key
     else:
@@ -688,15 +688,12 @@
             self.iterator = strategy.getiteritems(impl)
             BaseIteratorImplementation.__init__(self, space, strategy, impl)
 
-        if override_next_item is not None:
-            next_item_entry = override_next_item
-        else:
-            def next_item_entry(self):
-                for key, value in self.iterator:
-                    return (wrapkey(self.space, key),
-                            wrapvalue(self.space, value))
-                else:
-                    return None, None
+        def next_item_entry(self):
+            for key, value in self.iterator:
+                return (wrapkey(self.space, key),
+                        wrapvalue(self.space, value))
+            else:
+                return None, None
 
     class IterClassReversed(BaseKeyIterator):
         def __init__(self, space, strategy, impl):
@@ -729,22 +726,7 @@
     def rev_update1_dict_dict(self, w_dict, w_updatedict):
         # the logic is to call prepare_dict_update() after the first setitem():
         # it gives the w_updatedict a chance to switch its strategy.
-        if override_next_item is not None:
-            # this is very similar to the general version, but the difference
-            # is that it is specialized to call a specific next_item()
-            iteritems = IterClassItems(self.space, self, w_dict)
-            w_key, w_value = iteritems.next_item()
-            if w_key is None:
-                return
-            w_updatedict.setitem(w_key, w_value)
-            w_updatedict.strategy.prepare_update(w_updatedict,
-                                                 w_dict.length() - 1)
-            while True:
-                w_key, w_value = iteritems.next_item()
-                if w_key is None:
-                    return
-                w_updatedict.setitem(w_key, w_value)
-        else:
+        if 1:     # (preserve indentation)
             iteritems = self.getiteritems(w_dict)
             if not same_strategy(self, w_updatedict):
                 # Different strategy.  Try to copy one item of w_dict
diff --git a/pypy/objspace/std/kwargsdict.py b/pypy/objspace/std/kwargsdict.py
--- a/pypy/objspace/std/kwargsdict.py
+++ b/pypy/objspace/std/kwargsdict.py
@@ -167,19 +167,26 @@
         return iter(self.unerase(w_dict.dstorage)[1])
 
     def getiteritems(self, w_dict):
-        keys = self.unerase(w_dict.dstorage)[0]
-        return iter(range(len(keys)))
+        return Zip(*self.unerase(w_dict.dstorage))
 
     wrapkey = _wrapkey
 
 
-def next_item(self):
-    strategy = self.strategy
-    assert isinstance(strategy, KwargsDictStrategy)
-    for i in self.iterator:
-        keys, values_w = strategy.unerase(self.dictimplementation.dstorage)
-        return _wrapkey(self.space, keys[i]), values_w[i]
-    else:
-        return None, None
+class Zip(object):
+    def __init__(self, list1, list2):
+        assert len(list1) == len(list2)
+        self.list1 = list1
+        self.list2 = list2
+        self.i = 0
 
-create_iterator_classes(KwargsDictStrategy, override_next_item=next_item)
+    def __iter__(self):
+        return self
+
+    def next(self):
+        i = self.i
+        if i >= len(self.list1):
+            raise StopIteration
+        self.i = i + 1
+        return (self.list1[i], self.list2[i])
+
+create_iterator_classes(KwargsDictStrategy)
diff --git a/pypy/objspace/std/listobject.py b/pypy/objspace/std/listobject.py
--- a/pypy/objspace/std/listobject.py
+++ b/pypy/objspace/std/listobject.py
@@ -193,9 +193,9 @@
 
     def switch_to_object_strategy(self):
         list_w = self.getitems()
-        self.strategy = self.space.fromcache(ObjectListStrategy)
-        # XXX this is quite indirect
-        self.init_from_list_w(list_w)
+        object_strategy = self.space.fromcache(ObjectListStrategy)
+        self.strategy = object_strategy
+        object_strategy.init_from_list_w(self, list_w)
 
     def _temporarily_as_objects(self):
         if self.strategy is self.space.fromcache(ObjectListStrategy):
diff --git a/pypy/objspace/std/test/test_kwargsdict.py 
b/pypy/objspace/std/test/test_kwargsdict.py
--- a/pypy/objspace/std/test/test_kwargsdict.py
+++ b/pypy/objspace/std/test/test_kwargsdict.py
@@ -160,6 +160,14 @@
         assert a == 3
         assert "KwargsDictStrategy" in self.get_strategy(d)
 
+    def test_iteritems_bug(self):
+        def f(**args):
+            return args
+
+        d = f(a=2, b=3, c=4)
+        for key, value in d.items():
+            None in d
+
     def test_unicode(self):
         """
         def f(**kwargs):
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
@@ -187,7 +187,12 @@
         [i0]
         jump(i0)
         """
-        self.optimize_loop(ops, expected)
+        short = """
+        [i2]
+        p3 = cast_int_to_ptr(i2)
+        jump(i2)
+        """
+        self.optimize_loop(ops, expected, expected_short=short)
 
     def test_reverse_of_cast_2(self):
         ops = """
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
@@ -439,8 +439,8 @@
 
             mk.definition('PYTHON', get_recent_cpython_executable())
 
-            mk.definition('GCMAPFILES', '$(subst .asmgcc.s,.gcmap,$(subst 
.c,.gcmap,$(SOURCES)))')
-            mk.definition('OBJECTS1', '$(subst .asmgcc.s,.o,$(subst 
.c,.o,$(SOURCES)))')
+            mk.definition('GCMAPFILES', '$(subst .vmprof.s,.gcmap,$(subst 
.c,.gcmap,$(SOURCES)))')
+            mk.definition('OBJECTS1', '$(subst .vmprof.s,.o,$(subst 
.c,.o,$(SOURCES)))')
             mk.definition('OBJECTS', '$(OBJECTS1) gcmaptable.s')
 
             # the CFLAGS passed to gcc when invoked to assembler the .s file
@@ -462,12 +462,12 @@
                 'rm $*.s $*.lbl.s'])
 
             # this is for manually written assembly files which needs to be 
parsed by asmgcc
-            mk.rule('%.o %.gcmap', '%.asmgcc.s', [
+            mk.rule('%.o %.gcmap', '%.vmprof.s', [
                 '$(PYTHON) $(RPYDIR)/translator/c/gcc/trackgcroot.py '
-                    '-t $*.asmgcc.s > $*.gctmp',
-                '$(CC) -o $*.o -c $*.asmgcc.lbl.s',
+                    '-t $*.vmprof.s > $*.gctmp',
+                '$(CC) -o $*.o -c $*.vmprof.lbl.s',
                 'mv $*.gctmp $*.gcmap',
-                'rm $*.asmgcc.lbl.s'])
+                'rm $*.vmprof.lbl.s'])
             
             # the rule to compute gcmaptable.s
             mk.rule('gcmaptable.s', '$(GCMAPFILES)',
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to