[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