[pypy-commit] pypy python-numpy: merge default into branch

mattip noreply at buildbot.pypy.org
Sun Oct 21 00:36:51 CEST 2012


Author: Matti Picus <matti.picus at gmail.com>
Branch: python-numpy
Changeset: r58289:87d26a2a5f73
Date: 2012-10-20 21:30 +0200
http://bitbucket.org/pypy/pypy/changeset/87d26a2a5f73/

Log:	merge default into branch

diff --git a/pypy/module/_cffi_backend/ctypefunc.py b/pypy/module/_cffi_backend/ctypefunc.py
--- a/pypy/module/_cffi_backend/ctypefunc.py
+++ b/pypy/module/_cffi_backend/ctypefunc.py
@@ -4,8 +4,9 @@
 
 import sys
 from pypy.interpreter.error import OperationError, operationerrfmt
+from pypy.interpreter.error import wrap_oserror
 from pypy.rpython.lltypesystem import lltype, llmemory, rffi
-from pypy.rlib import jit, clibffi, jit_libffi
+from pypy.rlib import jit, clibffi, jit_libffi, rposix
 from pypy.rlib.jit_libffi import CIF_DESCRIPTION, CIF_DESCRIPTION_P
 from pypy.rlib.jit_libffi import FFI_TYPE, FFI_TYPE_P, FFI_TYPE_PP
 from pypy.rlib.jit_libffi import SIZE_OF_FFI_ARG
@@ -147,9 +148,13 @@
                 argtype = self.fargs[i]
                 if isinstance(argtype, W_CTypePointer):
                     data = rffi.ptradd(buffer, cif_descr.exchange_args[i])
-                    if get_mustfree_flag(data):
+                    flag = get_mustfree_flag(data)
+                    if flag == 1:
                         raw_string = rffi.cast(rffi.CCHARPP, data)[0]
                         lltype.free(raw_string, flavor='raw')
+                    elif flag == 2:
+                        file = rffi.cast(rffi.CCHARPP, data)[0]
+                        rffi_fclose(file)
             lltype.free(buffer, flavor='raw')
         return w_res
 
@@ -164,6 +169,27 @@
     assert isinstance(abi, int)
     return space.wrap(abi)
 
+rffi_fdopen = rffi.llexternal("fdopen", [rffi.INT, rffi.CCHARP], rffi.CCHARP)
+rffi_fclose = rffi.llexternal("fclose", [rffi.CCHARP], rffi.INT)
+
+def prepare_file_call_argument(fileobj):
+    import os
+    space = fileobj.space
+    fileobj.direct_flush()
+    fd = fileobj.direct_fileno()
+    if fd < 0:
+        raise OperationError(space.w_ValueError,
+                             space.wrap("file has no OS file descriptor"))
+    try:
+        fd2 = os.dup(fd)
+        f = rffi_fdopen(fd2, fileobj.mode)
+        if not f:
+            os.close(fd2)
+            raise OSError(rposix.get_errno(), "fdopen failed")
+    except OSError, e:
+        raise wrap_oserror(space, e)
+    return f
+
 # ____________________________________________________________
 
 
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
@@ -157,7 +157,7 @@
         space = self.space
         ob = space.interpclass_w(w_ob)
         if not isinstance(ob, cdataobj.W_CData):
-            raise self._convert_error("compatible pointer", w_ob)
+            raise self._convert_error("cdata pointer", w_ob)
         other = ob.ctype
         if not isinstance(other, W_CTypePtrBase):
             from pypy.module._cffi_backend import ctypearray
@@ -177,7 +177,8 @@
 
 
 class W_CTypePointer(W_CTypePtrBase):
-    _attrs_ = []
+    _attrs_ = ['is_file']
+    _immutable_fields_ = ['is_file']
 
     def __init__(self, space, ctitem):
         from pypy.module._cffi_backend import ctypearray
@@ -186,6 +187,7 @@
             extra = "(*)"    # obscure case: see test_array_add
         else:
             extra = " *"
+        self.is_file = (ctitem.name == "struct _IO_FILE")
         W_CTypePtrBase.__init__(self, space, size, extra, 2, ctitem)
 
     def newp(self, w_init):
@@ -234,7 +236,7 @@
         p = rffi.ptradd(cdata, i * self.ctitem.size)
         return cdataobj.W_CData(space, p, self)
 
-    def _prepare_pointer_call_argument(self, w_init):
+    def _prepare_pointer_call_argument(self, w_init, cdata):
         space = self.space
         if (space.isinstance_w(w_init, space.w_list) or
             space.isinstance_w(w_init, space.w_tuple)):
@@ -242,10 +244,19 @@
         elif space.isinstance_w(w_init, space.w_basestring):
             # from a string, we add the null terminator
             length = space.int_w(space.len(w_init)) + 1
+        elif self.is_file:
+            from pypy.module._file.interp_file import W_File
+            from pypy.module._cffi_backend import ctypefunc
+            ob = space.interpclass_w(w_init)
+            if isinstance(ob, W_File):
+                result = ctypefunc.prepare_file_call_argument(ob)
+                rffi.cast(rffi.CCHARPP, cdata)[0] = result
+                return 2
+            return 0
         else:
-            return lltype.nullptr(rffi.CCHARP.TO)
+            return 0
         if self.ctitem.size <= 0:
-            return lltype.nullptr(rffi.CCHARP.TO)
+            return 0
         try:
             datasize = ovfcheck(length * self.ctitem.size)
         except OverflowError:
@@ -258,25 +269,19 @@
         except Exception:
             lltype.free(result, flavor='raw')
             raise
-        return result
+        rffi.cast(rffi.CCHARPP, cdata)[0] = result
+        return 1
 
     def convert_argument_from_object(self, cdata, w_ob):
         from pypy.module._cffi_backend.ctypefunc import set_mustfree_flag
         space = self.space
         ob = space.interpclass_w(w_ob)
-        if isinstance(ob, cdataobj.W_CData):
-            buffer = lltype.nullptr(rffi.CCHARP.TO)
-        else:
-            buffer = self._prepare_pointer_call_argument(w_ob)
-        #
-        if buffer:
-            rffi.cast(rffi.CCHARPP, cdata)[0] = buffer
-            set_mustfree_flag(cdata, True)
-            return True
-        else:
-            set_mustfree_flag(cdata, False)
+        result = (not isinstance(ob, cdataobj.W_CData) and
+                  self._prepare_pointer_call_argument(w_ob, cdata))
+        if result == 0:
             self.convert_from_object(cdata, w_ob)
-            return False
+        set_mustfree_flag(cdata, result)
+        return result
 
     def getcfield(self, attr):
         return self.ctitem.getcfield(attr)
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
@@ -2211,3 +2211,56 @@
     buffer(p)[:] = bytearray(b"foo\x00")
     assert len(p) == 4
     assert list(p) == [b"f", b"o", b"o", b"\x00"]
+
+def test_FILE():
+    if sys.platform == "win32":
+        py.test.skip("testing FILE not implemented")
+    #
+    BFILE = new_struct_type("_IO_FILE")
+    BFILEP = new_pointer_type(BFILE)
+    BChar = new_primitive_type("char")
+    BCharP = new_pointer_type(BChar)
+    BInt = new_primitive_type("int")
+    BFunc = new_function_type((BCharP, BFILEP), BInt, False)
+    BFunc2 = new_function_type((BFILEP, BCharP), BInt, True)
+    ll = find_and_load_library('c')
+    fputs = ll.load_function(BFunc, "fputs")
+    fscanf = ll.load_function(BFunc2, "fscanf")
+    #
+    import posix
+    fdr, fdw = posix.pipe()
+    fr1 = posix.fdopen(fdr, 'r', 256)
+    fw1 = posix.fdopen(fdw, 'w', 256)
+    #
+    fw1.write(b"X")
+    res = fputs(b"hello world\n", fw1)
+    assert res >= 0
+    fw1.close()
+    #
+    p = newp(new_array_type(BCharP, 100), None)
+    res = fscanf(fr1, b"%s\n", p)
+    assert res == 1
+    assert string(p) == b"Xhello"
+    fr1.close()
+
+def test_FILE_only_for_FILE_arg():
+    if sys.platform == "win32":
+        py.test.skip("testing FILE not implemented")
+    #
+    B_NOT_FILE = new_struct_type("NOT_FILE")
+    B_NOT_FILEP = new_pointer_type(B_NOT_FILE)
+    BChar = new_primitive_type("char")
+    BCharP = new_pointer_type(BChar)
+    BInt = new_primitive_type("int")
+    BFunc = new_function_type((BCharP, B_NOT_FILEP), BInt, False)
+    ll = find_and_load_library('c')
+    fputs = ll.load_function(BFunc, "fputs")
+    #
+    import posix
+    fdr, fdw = posix.pipe()
+    fr1 = posix.fdopen(fdr, 'r')
+    fw1 = posix.fdopen(fdw, 'w')
+    #
+    e = py.test.raises(TypeError, fputs, b"hello world\n", fw1)
+    assert str(e.value) == ("initializer for ctype 'struct NOT_FILE *' must "
+                            "be a cdata pointer, not file")
diff --git a/pypy/objspace/std/floatobject.py b/pypy/objspace/std/floatobject.py
--- a/pypy/objspace/std/floatobject.py
+++ b/pypy/objspace/std/floatobject.py
@@ -98,12 +98,13 @@
     try:
         return W_LongObject.fromfloat(space, w_floatobj.floatval)
     except OverflowError:
-        if isnan(w_floatobj.floatval):
-            raise OperationError(
-                space.w_ValueError,
-                space.wrap("cannot convert float NaN to integer"))
-        raise OperationError(space.w_OverflowError,
-                             space.wrap("cannot convert float infinity to long"))
+        raise OperationError(
+            space.w_OverflowError,
+            space.wrap("cannot convert float infinity to integer"))
+    except ValueError:
+        raise OperationError(space.w_ValueError,
+                             space.wrap("cannot convert float NaN to integer"))
+
 def trunc__Float(space, w_floatobj):
     whole = math.modf(w_floatobj.floatval)[1]
     try:
@@ -308,7 +309,7 @@
             # Convert to long and use its hash.
             try:
                 w_lval = W_LongObject.fromfloat(space, v)
-            except OverflowError:
+            except (OverflowError, ValueError):
                 # can't convert to long int -- arbitrary
                 if v < 0:
                     return -271828
diff --git a/pypy/rlib/rbigint.py b/pypy/rlib/rbigint.py
--- a/pypy/rlib/rbigint.py
+++ b/pypy/rlib/rbigint.py
@@ -1,7 +1,7 @@
 from pypy.rlib.rarithmetic import LONG_BIT, intmask, longlongmask, r_uint, r_ulonglong, r_longlonglong
 from pypy.rlib.rarithmetic import ovfcheck, r_longlong, widen, is_valid_int
 from pypy.rlib.rarithmetic import most_neg_value_of_same_type
-from pypy.rlib.rfloat import isfinite
+from pypy.rlib.rfloat import isinf, isnan
 from pypy.rlib.debug import make_sure_not_resized, check_regular_int
 from pypy.rlib.objectmodel import we_are_translated, specialize
 from pypy.rlib import jit
@@ -207,10 +207,11 @@
     def fromfloat(dval):
         """ Create a new bigint object from a float """
         # This function is not marked as pure because it can raise
-        if isfinite(dval):
-            return rbigint._fromfloat_finite(dval)
-        else:
-            raise OverflowError
+        if isinf(dval):
+            raise OverflowError("cannot convert float infinity to integer")
+        if isnan(dval):
+            raise ValueError("cannot convert float NaN to integer")
+        return rbigint._fromfloat_finite(dval)
 
     @staticmethod
     @jit.elidable
diff --git a/pypy/rlib/test/test_rbigint.py b/pypy/rlib/test/test_rbigint.py
--- a/pypy/rlib/test/test_rbigint.py
+++ b/pypy/rlib/test/test_rbigint.py
@@ -4,6 +4,7 @@
 from random import random, randint, sample
 from pypy.rlib.rbigint import rbigint, SHIFT, MASK, KARATSUBA_CUTOFF
 from pypy.rlib.rbigint import _store_digit, _mask_digit
+from pypy.rlib.rfloat import NAN
 from pypy.rlib import rbigint as lobj
 from pypy.rlib.rarithmetic import r_uint, r_longlong, r_ulonglong, intmask
 from pypy.rpython.test.test_llinterp import interpret
@@ -266,6 +267,7 @@
         x = 12345.6789e200
         x *= x
         assert raises(OverflowError, rbigint.fromfloat, x)
+        assert raises(ValueError, rbigint.fromfloat, NAN)
         #
         f1 = rbigint.fromfloat(9007199254740991.0)
         assert f1.tolong() == 9007199254740991
diff --git a/pypy/translator/goal/query.py b/pypy/translator/goal/query.py
--- a/pypy/translator/goal/query.py
+++ b/pypy/translator/goal/query.py
@@ -49,7 +49,7 @@
         s_ev = annotator.binding(ev, None)
         if s_et:
             if s_et.knowntype == type:
-                if s_et.__class__ == annmodel.SomeObject:
+                if s_et.__class__ == annmodel.SomeType:
                     if hasattr(s_et, 'is_type_of') and  s_et.is_type_of == [ev]:
                         continue
                 else:


More information about the pypy-commit mailing list