[pypy-commit] pypy py3k: merge default

pjenvey noreply at buildbot.pypy.org
Tue Nov 26 01:24:13 CET 2013


Author: Philip Jenvey <pjenvey at underboss.org>
Branch: py3k
Changeset: r68324:0e2516a31328
Date: 2013-11-25 15:08 -0800
http://bitbucket.org/pypy/pypy/changeset/0e2516a31328/

Log:	merge default

diff --git a/lib-python/2.7/socket.py b/lib-python/2.7/socket.py
--- a/lib-python/2.7/socket.py
+++ b/lib-python/2.7/socket.py
@@ -335,9 +335,10 @@
             s = self._sock
             self._sock = None
             if s is not None:
-                s._drop()
                 if self._close:
                     s.close()
+                else:
+                    s._drop()
 
     def __del__(self):
         try:
diff --git a/lib_pypy/pyrepl/simple_interact.py b/lib_pypy/pyrepl/simple_interact.py
--- a/lib_pypy/pyrepl/simple_interact.py
+++ b/lib_pypy/pyrepl/simple_interact.py
@@ -67,3 +67,6 @@
         except KeyboardInterrupt:
             console.write("\nKeyboardInterrupt\n")
             console.resetbuffer()
+        except MemoryError:
+            console.write("\nMemoryError\n")
+            console.resetbuffer()
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
@@ -15,3 +15,6 @@
 
 .. branch: armhf-singlefloat
 JIT support for singlefloats on ARM using the hardfloat ABI
+
+.. branch: voidtype_strformat
+Better support for record numpy arrays
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
@@ -25,6 +25,7 @@
 from pypy.objspace.std.sliceobject import W_SliceObject
 from pypy.module.__builtin__.descriptor import W_Property
 from pypy.module.__builtin__.interp_memoryview import W_MemoryView
+from pypy.module.micronumpy.base import W_NDimArray
 from rpython.rlib.entrypoint import entrypoint_lowlevel
 from rpython.rlib.rposix import is_valid_fd, validate_fd
 from rpython.rlib.unroll import unrolling_iterable
@@ -470,6 +471,7 @@
         "Complex": "space.w_complex",
         "ByteArray": "space.w_bytearray",
         "MemoryView": "space.gettypeobject(W_MemoryView.typedef)",
+        "Array": "space.gettypeobject(W_NDimArray.typedef)",
         "BaseObject": "space.w_object",
         'None': 'space.type(space.w_None)',
         'NotImplemented': 'space.type(space.w_NotImplemented)',
diff --git a/pypy/module/cpyext/include/pyconfig.h b/pypy/module/cpyext/include/pyconfig.h
--- a/pypy/module/cpyext/include/pyconfig.h
+++ b/pypy/module/cpyext/include/pyconfig.h
@@ -29,6 +29,22 @@
 #define VA_LIST_IS_ARRAY
 #endif
 
+#ifndef Py_BUILD_CORE /* not building the core - must be an ext */
+#    if defined(_MSC_VER)
+     /* So MSVC users need not specify the .lib file in
+      * their Makefile (other compilers are generally
+      * taken care of by distutils.) */
+#        ifdef _DEBUG
+#            error("debug first with cpython")    
+#            pragma comment(lib,"python27.lib")
+#        else
+#            pragma comment(lib,"python27.lib")
+#        endif /* _DEBUG */
+#    endif
+#endif /* _MSC_VER */
+
+
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/pypy/module/cpyext/src/ndarrayobject.c b/pypy/module/cpyext/src/ndarrayobject.c
--- a/pypy/module/cpyext/src/ndarrayobject.c
+++ b/pypy/module/cpyext/src/ndarrayobject.c
@@ -3,8 +3,6 @@
 #include "numpy/arrayobject.h"
 #include <string.h>   /* memset, memcpy */
 
-PyTypeObject PyArray_Type;
-
 void 
 _PyArray_FILLWBYTE(PyObject* obj, int val) {
     memset(PyArray_DATA(obj), val, PyArray_NBYTES(obj));
diff --git a/pypy/module/cpyext/test/test_ndarrayobject.py b/pypy/module/cpyext/test/test_ndarrayobject.py
--- a/pypy/module/cpyext/test/test_ndarrayobject.py
+++ b/pypy/module/cpyext/test/test_ndarrayobject.py
@@ -286,3 +286,19 @@
         assert dt.num == 11
 
 
+    def test_pass_ndarray_object_to_c(self):
+        from _numpypy.multiarray import ndarray
+        mod = self.import_extension('foo', [
+                ("check_array", "METH_VARARGS",
+                '''
+                    PyObject* obj;
+                    if (!PyArg_ParseTuple(args, "O!", &PyArray_Type, &obj))
+                        return NULL;
+                    Py_INCREF(obj);
+                    return obj;
+                '''),
+                ], prologue='#include <numpy/arrayobject.h>')
+        array = ndarray((3, 4), dtype='d')
+        assert mod.check_array(array) is array
+        raises(TypeError, "mod.check_array(42)")
+        
diff --git a/pypy/module/itertools/interp_itertools.py b/pypy/module/itertools/interp_itertools.py
--- a/pypy/module/itertools/interp_itertools.py
+++ b/pypy/module/itertools/interp_itertools.py
@@ -288,10 +288,8 @@
             if space.is_w(w_startstop, space.w_None):
                 start = 0
             else:
-                start = space.int_w(w_startstop)
-                if start < 0:
-                    raise OperationError(space.w_ValueError, space.wrap(
-                       "Indicies for islice() must be non-negative integers."))
+                start = self.arg_int_w(w_startstop, 0,
+                 "Indicies for islice() must be None or non-negative integers")
             w_stop = args_w[0]
         else:
             raise OperationError(space.w_TypeError, space.wrap("islice() takes at most 4 arguments (" + str(num_args) + " given)"))
@@ -299,10 +297,8 @@
         if space.is_w(w_stop, space.w_None):
             stop = -1
         else:
-            stop = space.int_w(w_stop)
-            if stop < 0:
-                raise OperationError(space.w_ValueError, space.wrap(
-                    "Stop argument must be a non-negative integer or None."))
+            stop = self.arg_int_w(w_stop, 0,
+                "Stop argument must be a non-negative integer or None.")
             stop = max(start, stop)    # for obscure CPython compatibility
 
         if num_args == 2:
@@ -310,10 +306,8 @@
             if space.is_w(w_step, space.w_None):
                 step = 1
             else:
-                step = space.int_w(w_step)
-                if step < 1:
-                    raise OperationError(space.w_ValueError, space.wrap(
-                        "Step must be one or lager for islice()."))
+                step = self.arg_int_w(w_step, 1,
+                    "Step for islice() must be a positive integer or None")
         else:
             step = 1
 
@@ -321,6 +315,18 @@
         self.start = start
         self.stop = stop
 
+    def arg_int_w(self, w_obj, minimum, errormsg):
+        space = self.space
+        try:
+            result = space.int_w(w_obj)
+        except OperationError, e:
+            if e.async(space):
+                raise
+            result = -1
+        if result < minimum:
+            raise OperationError(space.w_ValueError, space.wrap(errormsg))
+        return result
+
     def iter_w(self):
         return self.space.wrap(self)
 
diff --git a/pypy/module/itertools/test/test_itertools.py b/pypy/module/itertools/test/test_itertools.py
--- a/pypy/module/itertools/test/test_itertools.py
+++ b/pypy/module/itertools/test/test_itertools.py
@@ -277,6 +277,11 @@
 
         raises(TypeError, itertools.islice, [], 0, 0, 0, 0)
 
+        # why not TypeError? Because CPython
+        raises(ValueError, itertools.islice, [], "a", 1, 2)
+        raises(ValueError, itertools.islice, [], 0, "a", 2)
+        raises(ValueError, itertools.islice, [], 0, 1, "a")
+
     def test_chain(self):
         import itertools
         
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
@@ -56,6 +56,8 @@
         self.aliases = aliases
         self.float_type = float_type
         self.fields = fields
+        if fieldnames is None:
+            fieldnames = []
         self.fieldnames = fieldnames
         self.shape = list(shape)
         self.subdtype = subdtype
@@ -214,15 +216,15 @@
             self.name = "void" + str(8 * self.get_size())
 
     def descr_get_names(self, space):
-        if self.fieldnames is None:
+        if len(self.fieldnames) == 0:
             return space.w_None
         return space.newtuple([space.wrap(name) for name in self.fieldnames])
 
     def set_names(self, space, w_names):
+        self.fieldnames = []
         if w_names == space.w_None:
-            self.fieldnames = None
+            return
         else:
-            self.fieldnames = []
             iter = space.iter(w_names)
             while True:
                 try:
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
@@ -249,12 +249,13 @@
             return space.wrap(self.dump_data())
         return space.call_function(cache.w_array_str, self)
 
-    def dump_data(self):
+    def dump_data(self, prefix='array(', suffix=')'):
         i = self.create_iter()
         first = True
         dtype = self.get_dtype()
         s = StringBuilder()
-        s.append('array([')
+        s.append(prefix)
+        s.append('[')
         while not i.done():
             if first:
                 first = False
@@ -262,7 +263,8 @@
                 s.append(', ')
             s.append(dtype.itemtype.str_format(i.getitem()))
             i.next()
-        s.append('])')
+        s.append(']')
+        s.append(suffix)
         return s.build()
 
     def create_iter(self, shape=None, backward_broadcast=False, require_index=False):
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
@@ -61,10 +61,22 @@
     def apply(self, space, 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(space, arr.start + ofs, arr.get_strides(),
-                                     arr.get_backstrides(),
-                                     arr.shape, arr, orig_arr, subdtype)
+        # ofs only changes start
+        # create a view of the original array by extending
+        # the shape, strides, backstrides of the array
+        from pypy.module.micronumpy.support import calc_strides
+        strides, backstrides = calc_strides(subdtype.shape,
+                                            subdtype.subdtype, arr.order)
+        final_shape = arr.shape + subdtype.shape
+        final_strides = arr.get_strides() + strides
+        final_backstrides = arr.get_backstrides() + backstrides
+        final_dtype = subdtype
+        print self.name,'strides',arr.get_strides(),strides
+        if subdtype.subdtype:
+            final_dtype = subdtype.subdtype
+        return W_NDimArray.new_slice(space, arr.start + ofs, final_strides,
+                                     final_backstrides,
+                                     final_shape, arr, orig_arr, final_dtype)
 
 class Chunks(BaseChunk):
     def __init__(self, l):
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
@@ -3088,7 +3088,9 @@
             ]
         h = np.array(buf, dtype=descr)
         assert len(h) == 2
-        skip('broken')  # XXX
+        assert h['x'].shape == (2, 2)
+        assert h['y'].strides == (41, 16, 8)
+        assert h['z'].shape == (2,)
         for v in (h, h[0], h['x']):
             repr(v)  # check for crash in repr
         assert (h['x'] == np.array([buf[0][0],
@@ -3119,6 +3121,22 @@
 
         assert len(list(a[0])) == 2
 
+    def test_3d_record(self):
+        from numpypy import dtype, array
+        dt = dtype([('name', 'S4'), ('x', float), ('y', float),
+                    ('block', int, (2, 2, 3))])
+        a = array([('aaaa', 1.0, 8.0, [[[1, 2, 3], [4, 5, 6]],
+                                       [[7, 8, 9], [10, 11, 12]]])],
+                  dtype=dt)
+        s = str(a)
+        i = a.item()
+        assert isinstance(i, tuple)
+        assert len(i) == 4
+        skip('incorrect formatting via dump_data')
+        assert s.endswith("[('aaaa', 1.0, 8.0, [[[1, 2, 3], [4, 5, 6]], "
+                          "[[7, 8, 9], [10, 11, 12]]])]")
+
+
     def test_issue_1589(self):
         import numpypy as numpy
         c = numpy.array([[(1, 2, 'a'), (3, 4, 'b')], [(5, 6, 'c'), (7, 8, 'd')]],
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
@@ -1789,6 +1789,40 @@
                                     dtype.subdtype)
         return W_NDimArray(implementation)
 
+    def read(self, arr, i, offset, dtype=None):
+        if dtype is None:
+            dtype = arr.dtype
+        return interp_boxes.W_VoidBox(arr, i + offset, dtype)
+
+    @jit.unroll_safe
+    def str_format(self, box):
+        assert isinstance(box, interp_boxes.W_VoidBox)
+        arr = self.readarray(box.arr, box.ofs, 0, box.dtype)
+        return arr.dump_data(prefix='', suffix='')
+
+    def to_builtin_type(self, space, item):
+        ''' From the documentation of ndarray.item():
+        "Void arrays return a buffer object for item(),
+         unless fields are defined, in which case a tuple is returned."
+        '''
+        assert isinstance(item, interp_boxes.W_VoidBox)
+        dt = item.arr.dtype
+        ret_unwrapped = []
+        for name in dt.fieldnames:
+            ofs, dtype = dt.fields[name]
+            if isinstance(dtype.itemtype, VoidType):
+                read_val = dtype.itemtype.readarray(item.arr, ofs, 0, dtype)
+            else:
+                read_val = dtype.itemtype.read(item.arr, ofs, 0, dtype)
+            if isinstance (read_val, interp_boxes.W_StringBox):
+                # StringType returns a str
+                read_val = space.wrap(dtype.itemtype.to_str(read_val))
+            ret_unwrapped = ret_unwrapped + [read_val,]
+        if len(ret_unwrapped) == 0:
+            raise OperationError(space.w_NotImplementedError, space.wrap(
+                    "item() for Void aray with no fields not implemented"))
+        return space.newtuple(ret_unwrapped)
+
 class RecordType(FlexibleType):
     T = lltype.Char
 
@@ -1848,7 +1882,8 @@
                 first = False
             else:
                 pieces.append(", ")
-            pieces.append(tp.str_format(tp.read(box.arr, box.ofs, ofs)))
+            val = tp.read(box.arr, box.ofs, ofs, subdtype)
+            pieces.append(tp.str_format(val))
         pieces.append(")")
         return "".join(pieces)
 
diff --git a/rpython/annotator/bookkeeper.py b/rpython/annotator/bookkeeper.py
--- a/rpython/annotator/bookkeeper.py
+++ b/rpython/annotator/bookkeeper.py
@@ -371,15 +371,19 @@
                     listdef.generalize(self.immutablevalue(e, False))
                 result = SomeList(listdef)
         elif tp is dict or tp is r_dict or tp is SomeOrderedDict.knowntype:
+            if tp is SomeOrderedDict.knowntype:
+                cls = SomeOrderedDict
+            else:
+                cls = SomeDict
             if need_const:
                 key = Constant(x)
                 try:
                     return self.immutable_cache[key]
                 except KeyError:
-                    result = SomeDict(DictDef(self,
-                                              s_ImpossibleValue,
-                                              s_ImpossibleValue,
-                                              is_r_dict = tp is r_dict))
+                    result = cls(DictDef(self,
+                                         s_ImpossibleValue,
+                                         s_ImpossibleValue,
+                                         is_r_dict = tp is r_dict))
                     self.immutable_cache[key] = result
                     if tp is r_dict:
                         s_eqfn = self.immutablevalue(x.key_eq)
@@ -412,10 +416,7 @@
                     dictdef.generalize_key(self.immutablevalue(ek, False))
                     dictdef.generalize_value(self.immutablevalue(ev, False))
                     dictdef.seen_prebuilt_key(ek)
-                if tp is SomeOrderedDict.knowntype:
-                    result = SomeOrderedDict(dictdef)
-                else:
-                    result = SomeDict(dictdef)
+                result = cls(dictdef)
         elif tp is weakref.ReferenceType:
             x1 = x()
             if x1 is None:
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
@@ -4148,6 +4148,19 @@
             a.build_types(f, [str, str])
         assert ("format() is not RPython" in exc.value.msg)
 
+    def test_prebuilt_ordered_dict(self):
+        try:
+            from collections import OrderedDict
+        except ImportError:
+            py.test.skip("Please upgrade to python 2.7")
+        d = OrderedDict([("aa", 1)])
+
+        def f():
+            return d
+
+        a = self.RPythonAnnotator()
+        assert isinstance(a.build_types(f, []), annmodel.SomeOrderedDict)
+
 
 def g(n):
     return [0, 1, 2, n]
diff --git a/rpython/jit/backend/x86/test/test_ztranslation_basic.py b/rpython/jit/backend/x86/test/test_ztranslation_basic.py
--- a/rpython/jit/backend/x86/test/test_ztranslation_basic.py
+++ b/rpython/jit/backend/x86/test/test_ztranslation_basic.py
@@ -1,11 +1,11 @@
 from rpython.jit.backend.llsupport.test.ztranslation_test import TranslationTest
 from rpython.jit.backend.x86.arch import WORD
+import sys
 
 
 class TestTranslationX86(TranslationTest):
     def _check_cbuilder(self, cbuilder):
-        # We assume here that we have sse2.  If not, the CPUClass
-        # needs to be changed to CPU386_NO_SSE2, but well.
-        if WORD == 4:
+        # msse2 and sse are always on on x86-64
+        if WORD == 4 and sys.platform != 'win32':
             assert '-msse2' in cbuilder.eci.compile_extra
             assert '-mfpmath=sse' in cbuilder.eci.compile_extra
diff --git a/rpython/jit/backend/x86/test/test_ztranslation_call_assembler.py b/rpython/jit/backend/x86/test/test_ztranslation_call_assembler.py
--- a/rpython/jit/backend/x86/test/test_ztranslation_call_assembler.py
+++ b/rpython/jit/backend/x86/test/test_ztranslation_call_assembler.py
@@ -1,11 +1,13 @@
 from rpython.jit.backend.llsupport.test.ztranslation_test import TranslationTestCallAssembler
 from rpython.translator.translator import TranslationContext
 from rpython.config.translationoption import DEFL_GC
-
+from rpython.jit.backend.x86.arch import WORD
+import sys
 
 class TestTranslationCallAssemblerX86(TranslationTestCallAssembler):
     def _check_cbuilder(self, cbuilder):
-        # We assume here that we have sse2.  If not, the CPUClass
+        #We assume here that we have sse2.  If not, the CPUClass
         # needs to be changed to CPU386_NO_SSE2, but well.
-        assert '-msse2' in cbuilder.eci.compile_extra
-        assert '-mfpmath=sse' in cbuilder.eci.compile_extra
\ No newline at end of file
+        if WORD == 4 and sys.platform != 'win32':
+            assert '-msse2' in cbuilder.eci.compile_extra
+            assert '-mfpmath=sse' in cbuilder.eci.compile_extra
diff --git a/rpython/jit/backend/x86/test/test_ztranslation_jit_stats.py b/rpython/jit/backend/x86/test/test_ztranslation_jit_stats.py
--- a/rpython/jit/backend/x86/test/test_ztranslation_jit_stats.py
+++ b/rpython/jit/backend/x86/test/test_ztranslation_jit_stats.py
@@ -1,11 +1,14 @@
 from rpython.jit.backend.llsupport.test.ztranslation_test import TranslationTestJITStats
 from rpython.translator.translator import TranslationContext
 from rpython.config.translationoption import DEFL_GC
+from rpython.jit.backend.x86.arch import WORD
+import sys
 
 
 class TestTranslationJITStatsX86(TranslationTestJITStats):
     def _check_cbuilder(self, cbuilder):
-        # We assume here that we have sse2.  If not, the CPUClass
+        #We assume here that we have sse2.  If not, the CPUClass
         # needs to be changed to CPU386_NO_SSE2, but well.
-        assert '-msse2' in cbuilder.eci.compile_extra
-        assert '-mfpmath=sse' in cbuilder.eci.compile_extra
\ No newline at end of file
+        if WORD == 4 and sys.platform != 'win32':
+            assert '-msse2' in cbuilder.eci.compile_extra
+            assert '-mfpmath=sse' in cbuilder.eci.compile_extra
diff --git a/rpython/rlib/rdtoa.py b/rpython/rlib/rdtoa.py
--- a/rpython/rlib/rdtoa.py
+++ b/rpython/rlib/rdtoa.py
@@ -38,6 +38,10 @@
                       ],
     )
 
+# dtoa.c is limited to 'int', so we refuse to pass it
+# strings or integer arguments bigger than ~2GB
+_INT_LIMIT = 0x7ffff000
+
 dg_strtod = rffi.llexternal(
     '_PyPy_dg_strtod', [rffi.CCHARP, rffi.CCHARPP], rffi.DOUBLE,
     compilation_info=eci, sandboxsafe=True)
@@ -52,6 +56,8 @@
     compilation_info=eci, sandboxsafe=True)
 
 def strtod(input):
+    if len(input) > _INT_LIMIT:
+        raise MemoryError
     end_ptr = lltype.malloc(rffi.CCHARPP.TO, 1, flavor='raw')
     try:
         ll_input = rffi.str2charp(input)
@@ -232,6 +238,8 @@
 
 def dtoa(value, code='r', mode=0, precision=0, flags=0,
          special_strings=lower_special_strings, upper=False):
+    if precision > _INT_LIMIT:
+        raise MemoryError
     decpt_ptr = lltype.malloc(rffi.INTP.TO, 1, flavor='raw')
     try:
         sign_ptr = lltype.malloc(rffi.INTP.TO, 1, flavor='raw')
diff --git a/rpython/rtyper/test/test_runicode.py b/rpython/rtyper/test/test_runicode.py
--- a/rpython/rtyper/test/test_runicode.py
+++ b/rpython/rtyper/test/test_runicode.py
@@ -282,6 +282,7 @@
     test_int_valueerror = unsupported
     test_float = unsupported
     test_hlstr = unsupported
+    test_strip_multiple_chars = unsupported
 
     def test_hash_via_type(self):
         from rpython.rlib.objectmodel import compute_hash
diff --git a/rpython/translator/c/src/dtoa.c b/rpython/translator/c/src/dtoa.c
--- a/rpython/translator/c/src/dtoa.c
+++ b/rpython/translator/c/src/dtoa.c
@@ -2329,7 +2329,7 @@
 
 static char *
 __Py_dg_dtoa(double dd, int mode, int ndigits,
-            Signed *decpt, Signed *sign, char **rve)
+             int *decpt, int *sign, char **rve)
 {
     /*  Arguments ndigits, decpt, sign are similar to those
         of ecvt and fcvt; trailing zeros are suppressed from
@@ -2952,7 +2952,7 @@
 }
 
 char * _PyPy_dg_dtoa(double dd, int mode, int ndigits,
-                   Signed *decpt, Signed *sign, char **rve)
+                     int *decpt, int *sign, char **rve)
 {
     char* result;
     _PyPy_SET_53BIT_PRECISION_HEADER;
diff --git a/rpython/translator/c/src/dtoa.h b/rpython/translator/c/src/dtoa.h
--- a/rpython/translator/c/src/dtoa.h
+++ b/rpython/translator/c/src/dtoa.h
@@ -2,6 +2,6 @@
 
 double _PyPy_dg_strtod(const char *str, char **ptr);
 char * _PyPy_dg_dtoa(double d, int mode, int ndigits,
-		     Signed *decpt, Signed *sign, char **rve);
+		     int *decpt, int *sign, char **rve);
 void _PyPy_dg_freedtoa(char *s);
 
diff --git a/rpython/translator/c/test/test_exception.py b/rpython/translator/c/test/test_exception.py
--- a/rpython/translator/c/test/test_exception.py
+++ b/rpython/translator/c/test/test_exception.py
@@ -156,3 +156,20 @@
     assert res == 42
     res = f1(0)
     assert res == 100
+
+def test_dict_keyerror_inside_try_finally():
+    class CtxMgr:
+        def __enter__(self):
+            return 42
+        def __exit__(self, *args):
+            pass
+    def fn(x):
+        d = {5: x}
+        with CtxMgr() as forty_two:
+            try:
+                return d[x]
+            except KeyError:
+                return forty_two
+    f1 = getcompiledopt(fn, [int])
+    res = f1(100)
+    assert res == 42
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
@@ -574,6 +574,22 @@
     fn = compile(chooser, [bool])
     assert fn(True)
 
+def test_ordered_dict():
+    try:
+        from collections import OrderedDict
+    except ImportError:
+        py.test.skip("Please update to Python 2.7")
+
+    expected = [('ea', 1), ('bb', 2), ('c', 3), ('d', 4), ('e', 5),
+                ('ef', 6)]
+    d = OrderedDict(expected)
+
+    def f():
+        assert d.items() == expected
+
+    fn = compile(f, [])
+    fn()
+
 def test_inhibit_tail_call():
     def foobar_fn(n):
         return 42
diff --git a/rpython/translator/platform/darwin.py b/rpython/translator/platform/darwin.py
--- a/rpython/translator/platform/darwin.py
+++ b/rpython/translator/platform/darwin.py
@@ -49,6 +49,18 @@
             response_file = relto.bestrelpath(response_file)
         return ["-Wl,-exported_symbols_list,%s" % (response_file,)]
 
+    def gen_makefile(self, cfiles, eci, exe_name=None, path=None,
+                     shared=False):
+        # ensure frameworks are passed in the Makefile
+        fs = self._frameworks(eci.frameworks)
+        if len(fs) > 0:
+            # concat (-framework, FrameworkName) pairs
+            self.extra_libs += tuple(map(" ".join, zip(fs[::2], fs[1::2])))
+        mk = super(Darwin, self).gen_makefile(cfiles, eci, exe_name, path,
+                                              shared)
+        return mk
+
+
 class Darwin_i386(Darwin):
     name = "darwin_i386"
     link_flags = ('-arch', 'i386', '-mmacosx-version-min=10.4')
diff --git a/rpython/translator/platform/test/test_darwin.py b/rpython/translator/platform/test/test_darwin.py
--- a/rpython/translator/platform/test/test_darwin.py
+++ b/rpython/translator/platform/test/test_darwin.py
@@ -16,9 +16,14 @@
         host_factory = Darwin_i386
     else:
         host_factory = Darwin_x86_64
+elif platform.machine() == 'x86_64':
+    host_factory = Darwin_x86_64
 else:
     host_factory = Darwin_PowerPC
 
+def is_x86():
+    return platform.machine() == 'i386' or platform.machine() == 'x86_64'
+
 class TestDarwin(BasicTest):
     platform = host_factory()
 
@@ -47,8 +52,39 @@
         res = self.platform.execute(executable)
         self.check_res(res)
 
+    def test_frameworks_with_makefile(self):
+        from StringIO import StringIO
+        tmpdir = udir.join('fw_mk' + self.__class__.__name__).ensure(dir=1)
+        objcfile = tmpdir.join('test_simple.m')
+        objcfile.write(r'''
+        #import <Foundation/Foundation.h>
+        int main (int argc, const char * argv[]) {
+            NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+            NSArray *args = [[NSProcessInfo processInfo] arguments];
+            NSCountedSet *cset = [[NSCountedSet alloc] initWithArray:args];
+
+            printf("%d\n", 23);
+
+            [cset release];
+            [pool release];
+            return 0;
+        }
+        ''')
+        eci = ExternalCompilationInfo(frameworks=('Cocoa',))
+        mk = self.platform.gen_makefile([objcfile], eci, path=tmpdir)
+        # The framework should end up in the Makefile
+        out = StringIO()
+        mk.write(out)
+        assert "-framework Cocoa" in out.getvalue()
+        # check that it actually works
+        mk.write()
+        self.platform.execute_makefile(mk)
+        res = self.platform.execute(tmpdir.join('test_simple'))
+        self.check_res(res, expected="23\n")
+
+
     def test_64_32_results(self):
-        if platform.machine() != 'i386':
+        if not is_x86():
             py.test.skip("i386 only")
         plat32 = Darwin_i386()
         plat64 = Darwin_x86_64()
@@ -72,7 +108,7 @@
             self.check_res(res, '1\n')
 
     def test_longsize(self):
-        if platform.machine() != 'i386':
+        if not is_x86():
             py.test.skip("i386 only")
         cfile = udir.join('test_int_size.c')
         cfile.write(r'''
@@ -88,9 +124,9 @@
         executable = self.platform.compile([cfile], eci)
         res = self.platform.execute(executable)
         self.check_res(res, str(sys.maxint) + '\n')
-        
+
     def test_32bit_makefile(self):
-        if platform.machine() != 'i386':
+        if not is_x86():
             py.test.skip("i386 only")
         plat32 = Darwin_i386()
         plat64 = Darwin_x86_64()
@@ -124,4 +160,3 @@
             plat64.execute_makefile(mk)
             res = plat64.execute(tmpdir.join('test_int_size'))
             self.check_res(res, '1\n')
-


More information about the pypy-commit mailing list