[pypy-commit] pypy cpyext-ext: merge;

fijal pypy.commits at gmail.com
Fri Dec 18 15:07:44 EST 2015


Author: fijal
Branch: cpyext-ext
Changeset: r81387:8ec857f8797e
Date: 2015-12-18 22:06 +0200
http://bitbucket.org/pypy/pypy/changeset/8ec857f8797e/

Log:	merge;

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
@@ -1074,8 +1074,7 @@
     import pypy.module.cpyext.ndarrayobject 
     global GLOBALS, SYMBOLS_C, separate_module_files
     GLOBALS["PyArray_Type#"]= ('PyTypeObject*', "space.gettypeobject(W_NDimArray.typedef)")
-    SYMBOLS_C += ['PyArray_Type', '_PyArray_FILLWBYTE', '_PyArray_ZEROS',
-                  '_PyArray_CopyInto']
+    SYMBOLS_C += ['PyArray_Type', '_PyArray_FILLWBYTE', '_PyArray_ZEROS']
     separate_module_files.append(source_dir / "ndarrayobject.c")
     return use_micronumpy
 
diff --git a/pypy/module/cpyext/include/numpy/arrayobject.h b/pypy/module/cpyext/include/numpy/arrayobject.h
--- a/pypy/module/cpyext/include/numpy/arrayobject.h
+++ b/pypy/module/cpyext/include/numpy/arrayobject.h
@@ -197,11 +197,9 @@
 
 PyAPI_FUNC(void) _PyArray_FILLWBYTE(PyObject* obj, int val);
 PyAPI_FUNC(PyObject *) _PyArray_ZEROS(int nd, npy_intp* dims, int type_num, int fortran);
-PyAPI_FUNC(int) _PyArray_CopyInto(PyArrayObject* dest, PyArrayObject* src);
 
 #define PyArray_FILLWBYTE _PyArray_FILLWBYTE
 #define PyArray_ZEROS _PyArray_ZEROS
-#define PyArray_CopyInto _PyArray_CopyInto
 
 #define PyArray_Resize(self, newshape, refcheck, fortran) (NULL)
 
diff --git a/pypy/module/cpyext/ndarrayobject.py b/pypy/module/cpyext/ndarrayobject.py
--- a/pypy/module/cpyext/ndarrayobject.py
+++ b/pypy/module/cpyext/ndarrayobject.py
@@ -170,13 +170,13 @@
     return w_array
 
 @cpython_api([Py_ssize_t], PyObject)
-def _PyArray_DescrFromType(space, typenum):
+def PyArray_DescrFromType(space, typenum):
     try:
         dtype = get_dtype_cache(space).dtypes_by_num[typenum]
         return dtype
     except KeyError:
         raise OperationError(space.w_ValueError, space.wrap(
-            '_PyArray_DescrFromType called with invalid dtype %d' % typenum))
+            'PyArray_DescrFromType called with invalid dtype %d' % typenum))
 
 @cpython_api([PyObject, Py_ssize_t, Py_ssize_t, Py_ssize_t], PyObject)
 def _PyArray_FromObject(space, w_obj, typenum, min_depth, max_depth):
@@ -250,6 +250,16 @@
         return simple_new(space, nd, dims, typenum,
             order=order, owning=owning, w_subtype=w_subtype)
 
+ at cpython_api([PyObject, PyObject], rffi.INT_real, error=-1)
+def PyArray_CopyInto(space, w_dest, w_src):
+    assert isinstance(w_dest, W_NDimArray)
+    assert isinstance(w_src, W_NDimArray)
+    space.appexec([w_dest, w_src], """(dest, src):
+        dest[:] = src
+        """ )
+    return 0
+    
+
 gufunctype = lltype.Ptr(ufuncs.GenericUfunc)
 # XXX single rffi.CArrayPtr(gufunctype) does not work, this does, is there
 # a problem with casting function pointers?
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
@@ -16,10 +16,3 @@
     return arr;
 }
 
-int 
-_PyArray_CopyInto(PyArrayObject* dest, PyArrayObject* src)
-{
-    memcpy(PyArray_DATA(dest), PyArray_DATA(src), PyArray_NBYTES(dest));
-    return 0;
-}
-
diff --git a/pypy/module/cpyext/test/test_cpyext.py b/pypy/module/cpyext/test/test_cpyext.py
--- a/pypy/module/cpyext/test/test_cpyext.py
+++ b/pypy/module/cpyext/test/test_cpyext.py
@@ -47,7 +47,7 @@
         assert 'PyModule_Check' in api.FUNCTIONS
         assert api.FUNCTIONS['PyModule_Check'].argtypes == [api.PyObject]
 
-def compile_extension_module(space, modname, **kwds):
+def compile_extension_module(space, modname, include_dirs=[], **kwds):
     """
     Build an extension module and return the filename of the resulting native
     code file.
@@ -73,11 +73,11 @@
     else:
         kwds["link_files"] = [str(api_library + '.so')]
         if sys.platform.startswith('linux'):
-            kwds["compile_extra"]=["-Werror=implicit-function-declaration"]
+            kwds["compile_extra"]=["-g", "-Werror=implicit-function-declaration"]
 
     modname = modname.split('.')[-1]
     eci = ExternalCompilationInfo(
-        include_dirs=api.include_dirs,
+        include_dirs=api.include_dirs + include_dirs,
         **kwds
         )
     eci = eci.convert_sources_to_files()
@@ -91,7 +91,7 @@
     soname.rename(pydname)
     return str(pydname)
 
-def compile_extension_module_applevel(space, modname, **kwds):
+def compile_extension_module_applevel(space, modname, include_dirs=[], **kwds):
     """
     Build an extension module and return the filename of the resulting native
     code file.
@@ -107,11 +107,11 @@
     elif sys.platform == 'darwin':
         pass
     elif sys.platform.startswith('linux'):
-            kwds["compile_extra"]=["-Werror=implicit-function-declaration"]
+            kwds["compile_extra"]=["-g","-Werror=implicit-function-declaration"]
 
     modname = modname.split('.')[-1]
     eci = ExternalCompilationInfo(
-        include_dirs = [space.include_dir],
+        include_dirs = [space.include_dir] + include_dirs,
         **kwds
         )
     eci = eci.convert_sources_to_files()
@@ -277,10 +277,10 @@
             return space.wrap(pydname)
 
         @gateway.unwrap_spec(name=str, init='str_or_None', body=str,
-                     load_it=bool, filename='str_or_None',
+                     load_it=bool, filename='str_or_None', 
                      PY_SSIZE_T_CLEAN=bool)
-        def import_module(space, name, init=None, body='',
-                          load_it=True, filename=None,
+        def import_module(space, name, init=None, body='', load_it=True,
+                          filename=None, w_include_dirs=None,
                           PY_SSIZE_T_CLEAN=False):
             """
             init specifies the overall template of the module.
@@ -291,6 +291,10 @@
             if filename is None, the module name will be used to construct the
             filename.
             """
+            if w_include_dirs is None:
+                include_dirs = []
+            else:
+                include_dirs = [space.str_w(s) for s in space.listview(w_include_dirs)]
             if init is not None:
                 code = """
                 %(PY_SSIZE_T_CLEAN)s
@@ -317,7 +321,7 @@
                 filename = py.path.local(pypydir) / 'module' \
                         / 'cpyext'/ 'test' / (filename + ".c")
                 kwds = dict(separate_module_files=[filename])
-
+            kwds['include_dirs'] = include_dirs
             mod = self.compile_extension_module(space, name, **kwds)
 
             if load_it:
@@ -340,9 +344,10 @@
                 space.sys.get('modules'),
                 space.wrap(name))
 
-        @gateway.unwrap_spec(modname=str, prologue=str, more_init=str, PY_SSIZE_T_CLEAN=bool)
+        @gateway.unwrap_spec(modname=str, prologue=str,
+                             more_init=str, PY_SSIZE_T_CLEAN=bool)
         def import_extension(space, modname, w_functions, prologue="",
-                             more_init="", PY_SSIZE_T_CLEAN=False):
+                             w_include_dirs=None, more_init="", PY_SSIZE_T_CLEAN=False):
             functions = space.unwrap(w_functions)
             methods_table = []
             codes = []
@@ -368,6 +373,7 @@
             if more_init:
                 init += more_init
             return import_module(space, name=modname, init=init, body=body,
+                                 w_include_dirs=w_include_dirs,
                                  PY_SSIZE_T_CLEAN=PY_SSIZE_T_CLEAN)
 
         @gateway.unwrap_spec(name=str)
@@ -388,12 +394,23 @@
             def interp2app(func):
                 from distutils.sysconfig import get_python_inc
                 class FakeSpace(object):
+                    def passthrough(self, arg):
+                        return arg
+                    listview = passthrough
+                    str_w = passthrough
                     def unwrap(self, args):
-                        return args
+                        try:
+                            return args.str_w(None)
+                        except:
+                            return args
                 fake = FakeSpace()
                 fake.include_dir = get_python_inc()
                 fake.config = self.space.config
                 def run(*args, **kwargs):
+                    for k in kwargs.keys():
+                        if k not in func.unwrap_spec and not k.startswith('w_'):
+                            v = kwargs.pop(k)
+                            kwargs['w_' + k] = v
                     return func(fake, *args, **kwargs)
                 return run
             def wrap(func):
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
@@ -226,11 +226,19 @@
         '''
 
 class AppTestNDArray(AppTestCpythonExtensionBase):
-    if self.runappdirect:
-        try:
-            import numpy
-        except:
-            skip('numpy not importable')
+
+    def setup_class(cls):
+        AppTestCpythonExtensionBase.setup_class.im_func(cls)
+        if cls.runappdirect:
+            try:
+                import numpy
+                cls.w_numpy_include = [numpy.get_include()]
+            except:
+                skip('numpy not importable')
+        else:
+            cls.w_numpy_include = cls.space.wrap([])
+            
+
     def test_ndarray_object_c(self):
         mod = self.import_extension('foo', [
                 ("test_simplenew", "METH_NOARGS",
@@ -244,7 +252,7 @@
                 '''
                 npy_intp dims[2] ={2, 3};
                 PyObject * obj = PyArray_SimpleNew(2, dims, 1);
-                PyArray_FILLWBYTE(obj, 42);
+                PyArray_FILLWBYTE((PyArrayObject*)obj, 42);
                 return obj;
                 '''
                 ),
@@ -252,20 +260,27 @@
                 '''
                 npy_intp dims1[2] ={2, 3};
                 npy_intp dims2[2] ={3, 2};
+                int ok;
                 PyObject * obj1 = PyArray_ZEROS(2, dims1, 11, 0);
                 PyObject * obj2 = PyArray_ZEROS(2, dims2, 11, 0);
-                PyArray_FILLWBYTE(obj2, 42);
-                PyArray_CopyInto(obj2, obj1);
-                Py_DECREF(obj1);
-                return obj2;
+                PyArray_FILLWBYTE((PyArrayObject*)obj2, 42);
+                ok = PyArray_CopyInto((PyArrayObject*)obj2, (PyArrayObject*)obj1);
+                Py_DECREF(obj2);
+                if (ok < 0)
+                {
+                    /* Should have failed */
+                    Py_DECREF(obj1);
+                    return NULL; 
+                }
+                return obj1;
                 '''
                 ),
                 ("test_FromAny", "METH_NOARGS",
                 '''
                 npy_intp dims[2] ={2, 3};
                 PyObject * obj2, * obj1 = PyArray_SimpleNew(2, dims, 1);
-                PyArray_FILLWBYTE(obj1, 42);
-                obj2 = _PyArray_FromAny(obj1, NULL, 0, 0, 0, NULL);
+                PyArray_FILLWBYTE((PyArrayObject*)obj1, 42);
+                obj2 = PyArray_FromAny(obj1, NULL, 0, 0, 0, NULL);
                 Py_DECREF(obj1);
                 return obj2;
                 '''
@@ -274,8 +289,8 @@
                 '''
                 npy_intp dims[2] ={2, 3};
                 PyObject  * obj2, * obj1 = PyArray_SimpleNew(2, dims, 1);
-                PyArray_FILLWBYTE(obj1, 42);
-                obj2 = _PyArray_FromObject(obj1, 12, 0, 0);
+                PyArray_FILLWBYTE((PyArrayObject*)obj1, 42);
+                obj2 = PyArray_FromObject(obj1, 12, 0, 0);
                 Py_DECREF(obj1);
                 return obj2;
                 '''
@@ -283,10 +298,19 @@
                 ("test_DescrFromType", "METH_O",
                 """
                     Signed typenum = PyInt_AsLong(args);
-                    return _PyArray_DescrFromType(typenum);
+                    return PyArray_DescrFromType(typenum);
                 """
                 ),
-                ], prologue='#include <numpy/arrayobject.h>')
+                ], include_dirs=self.numpy_include, 
+                   prologue='''
+                #define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
+                #include <numpy/arrayobject.h>
+                ''', 
+                    more_init = '''
+                #ifndef PYPY_VER
+                    import_array();
+                #endif
+                ''')
         arr = mod.test_simplenew()
         assert arr.shape == (2, 3)
         assert arr.dtype.num == 11 #float32 dtype
@@ -294,17 +318,18 @@
         assert arr.shape == (2, 3)
         assert arr.dtype.num == 1 #int8 dtype
         assert (arr == 42).all()
-        arr = mod.test_copy()
-        assert (arr == 0).all()
+        raises(ValueError, mod.test_copy)
         #Make sure these work without errors
         arr = mod.test_FromAny()
         arr = mod.test_FromObject()
         dt = mod.test_DescrFromType(11)
         assert dt.num == 11
 
-
     def test_pass_ndarray_object_to_c(self):
-        from _numpypy.multiarray import ndarray
+        if self.runappdirect:
+            from numpy import ndarray
+        else:
+            from _numpypy.multiarray import ndarray
         mod = self.import_extension('foo', [
                 ("check_array", "METH_VARARGS",
                 '''
@@ -314,13 +339,25 @@
                     Py_INCREF(obj);
                     return obj;
                 '''),
-                ], prologue='#include <numpy/arrayobject.h>')
+                ], include_dirs=self.numpy_include, 
+                   prologue='''
+                #define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
+                #include <numpy/arrayobject.h>
+                ''', 
+                    more_init = '''
+                #ifndef PYPY_VER
+                    import_array();
+                #endif
+                ''')
         array = ndarray((3, 4), dtype='d')
         assert mod.check_array(array) is array
         raises(TypeError, "mod.check_array(42)")
 
     def test_ufunc(self):
-        from _numpypy.multiarray import arange
+        if self.runappdirect:
+            py.test.xfail('why does this segfault on cpython?')
+        else:
+            from _numpypy.multiarray import arange
         mod = self.import_extension('foo', [
                 ("create_ufunc_basic",  "METH_NOARGS",
                 """
@@ -356,9 +393,13 @@
                                     "a ufunc that tests a more complicated signature", 
                                     0, "(m,m)->(m,m)");
                 """),
-                ], prologue='''
-                #include "numpy/ndarraytypes.h"
-                /*#include <numpy/ufuncobject.h> generated by numpy setup.py*/
+                ], include_dirs=self.numpy_include, 
+                   prologue='''
+                #define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
+                #include <numpy/arrayobject.h>
+                #ifndef PYPY_VERSION
+                #include <numpy/ufuncobject.h> /*generated by numpy setup.py*/
+                #endif
                 typedef void (*PyUFuncGenericFunction)
                             (char **args,
                              npy_intp *dimensions,
@@ -423,6 +464,10 @@
                     *((float *)args[1]) = res;
                 };
                             
+                ''',  more_init = '''
+                #ifndef PYPY_VER
+                    import_array();
+                #endif
                 ''')
         sq = arange(18, dtype="float32").reshape(2,3,3)
         float_ufunc = mod.create_float_ufunc_3x3()


More information about the pypy-commit mailing list