[pypy-commit] pypy PyTuple_Type-subclass: merge default into branch

mattip pypy.commits at gmail.com
Thu Jun 23 10:32:03 EDT 2016


Author: Matti Picus <matti.picus at gmail.com>
Branch: PyTuple_Type-subclass
Changeset: r85352:ea8fefb608c9
Date: 2016-06-23 17:30 +0300
http://bitbucket.org/pypy/pypy/changeset/ea8fefb608c9/

Log:	merge default into branch

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
@@ -42,3 +42,9 @@
 Allow rw access to the char* returned from PyString_AS_STRING, also refactor
 PyStringObject to look like cpython's and allow subclassing PyString_Type and
 PyUnicode_Type
+
+.. branch: save_socket_errno
+
+Bug fix: if ``socket.socket()`` failed, the ``socket.error`` did not show
+the errno of the failing system call, but instead some random previous
+errno.
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
@@ -800,6 +800,21 @@
         pypy_debug_catch_fatal_exception()
         assert False
 
+def _restore_gil_state(pygilstate_release, gilstate, gil_release, _gil_auto, tid):
+    from rpython.rlib import rgil
+    # see "Handling of the GIL" above
+    assert cpyext_glob_tid_ptr[0] == 0
+    if pygilstate_release:
+        from pypy.module.cpyext import pystate
+        unlock = (gilstate == pystate.PyGILState_UNLOCKED)
+    else:
+        unlock = gil_release or _gil_auto
+    if unlock:
+        rgil.release()
+    else:
+        cpyext_glob_tid_ptr[0] = tid
+
+
 def make_wrapper_second_level(space, argtypesw, restype,
                               result_kind, error_value, gil):
     from rpython.rlib import rgil
@@ -827,6 +842,7 @@
     def wrapper_second_level(callable, pname, *args):
         from pypy.module.cpyext.pyobject import make_ref, from_ref, is_pyobj
         from pypy.module.cpyext.pyobject import as_pyobj
+        from pypy.module.cpyext import pystate
         # we hope that malloc removal removes the newtuple() that is
         # inserted exactly here by the varargs specializer
 
@@ -839,7 +855,6 @@
             rgil.acquire()
             assert cpyext_glob_tid_ptr[0] == 0
         elif pygilstate_ensure:
-            from pypy.module.cpyext import pystate
             if cpyext_glob_tid_ptr[0] == tid:
                 cpyext_glob_tid_ptr[0] = 0
                 args += (pystate.PyGILState_LOCKED,)
@@ -850,6 +865,10 @@
             if cpyext_glob_tid_ptr[0] != tid:
                 no_gil_error(pname)
             cpyext_glob_tid_ptr[0] = 0
+        if pygilstate_release:
+            gilstate = rffi.cast(lltype.Signed, args[-1])
+        else:
+            gilstate = pystate.PyGILState_IGNORE
 
         rffi.stackcounter.stacks_counter += 1
         llop.gc_stack_bottom(lltype.Void)   # marker for trackgcroot.py
@@ -919,24 +938,13 @@
 
         except Exception as e:
             unexpected_exception(pname, e, tb)
+            _restore_gil_state(pygilstate_release, gilstate, gil_release, _gil_auto, tid)
             return fatal_value
 
         assert lltype.typeOf(retval) == restype
         rffi.stackcounter.stacks_counter -= 1
 
-        # see "Handling of the GIL" above
-        assert cpyext_glob_tid_ptr[0] == 0
-        if pygilstate_release:
-            from pypy.module.cpyext import pystate
-            arg = rffi.cast(lltype.Signed, args[-1])
-            unlock = (arg == pystate.PyGILState_UNLOCKED)
-        else:
-            unlock = gil_release or _gil_auto
-        if unlock:
-            rgil.release()
-        else:
-            cpyext_glob_tid_ptr[0] = tid
-
+        _restore_gil_state(pygilstate_release, gilstate, gil_release, _gil_auto, tid)
         return retval
 
     wrapper_second_level._dont_inline_ = True
diff --git a/pypy/module/cpyext/pystate.py b/pypy/module/cpyext/pystate.py
--- a/pypy/module/cpyext/pystate.py
+++ b/pypy/module/cpyext/pystate.py
@@ -207,6 +207,7 @@
 PyGILState_STATE = rffi.INT
 PyGILState_LOCKED = 0
 PyGILState_UNLOCKED = 1
+PyGILState_IGNORE = 2
 
 ExecutionContext.cpyext_gilstate_counter_noleave = 0
 
diff --git a/pypy/module/cpyext/test/conftest.py b/pypy/module/cpyext/test/conftest.py
--- a/pypy/module/cpyext/test/conftest.py
+++ b/pypy/module/cpyext/test/conftest.py
@@ -1,4 +1,4 @@
-import py
+import os
 import pytest
 
 def pytest_configure(config):
@@ -21,3 +21,14 @@
 def pytest_funcarg__api(request):
     return request.cls.api
 
+if os.name == 'nt':
+    @pytest.yield_fixture(autouse=True, scope='session')
+    def prevent_dialog_box():
+        """Do not open dreaded dialog box on segfault on Windows"""
+        import ctypes
+        SEM_NOGPFAULTERRORBOX = 0x0002  # From MSDN
+        old_err_mode = ctypes.windll.kernel32.GetErrorMode()
+        new_err_mode = old_err_mode | SEM_NOGPFAULTERRORBOX
+        ctypes.windll.kernel32.SetErrorMode(new_err_mode)
+        yield
+        ctypes.windll.kernel32.SetErrorMode(old_err_mode)
diff --git a/pypy/module/cpyext/test/support.py b/pypy/module/cpyext/test/support.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/cpyext/test/support.py
@@ -0,0 +1,68 @@
+import os
+import py
+from sys import platform
+
+if os.name != 'nt':
+    so_ext = 'so'
+else:
+    so_ext = 'dll'
+
+def c_compile(cfilenames, outputfilename,
+        compile_extra=None, link_extra=None,
+        include_dirs=None, libraries=None, library_dirs=None):
+    compile_extra = compile_extra or []
+    link_extra = link_extra or []
+    include_dirs = include_dirs or []
+    libraries = libraries or []
+    library_dirs = library_dirs or []
+    if platform == 'win32':
+        link_extra = link_extra + ['/DEBUG'] # generate .pdb file
+    if platform == 'darwin':
+        # support Fink & Darwinports
+        for s in ('/sw/', '/opt/local/'):
+            if (s + 'include' not in include_dirs
+                    and os.path.exists(s + 'include')):
+                include_dirs.append(s + 'include')
+            if s + 'lib' not in library_dirs and os.path.exists(s + 'lib'):
+                library_dirs.append(s + 'lib')
+
+    outputfilename = py.path.local(outputfilename).new(ext=so_ext)
+    saved_environ = os.environ.copy()
+    try:
+        _build(
+            cfilenames, outputfilename,
+            compile_extra, link_extra,
+            include_dirs, libraries, library_dirs)
+    finally:
+        # workaround for a distutils bugs where some env vars can
+        # become longer and longer every time it is used
+        for key, value in saved_environ.items():
+            if os.environ.get(key) != value:
+                os.environ[key] = value
+    return outputfilename
+
+def _build(cfilenames, outputfilename, compile_extra, link_extra,
+        include_dirs, libraries, library_dirs):
+    from distutils.ccompiler import new_compiler
+    from distutils import sysconfig
+    compiler = new_compiler(force=1)
+    sysconfig.customize_compiler(compiler) # XXX
+    objects = []
+    for cfile in cfilenames:
+        cfile = py.path.local(cfile)
+        old = cfile.dirpath().chdir()
+        try:
+            res = compiler.compile([cfile.basename],
+                include_dirs=include_dirs, extra_preargs=compile_extra)
+            assert len(res) == 1
+            cobjfile = py.path.local(res[0])
+            assert cobjfile.check()
+            objects.append(str(cobjfile))
+        finally:
+            old.chdir()
+
+    compiler.link_shared_object(
+        objects, str(outputfilename),
+        libraries=libraries,
+        extra_preargs=link_extra,
+        library_dirs=library_dirs)
diff --git a/pypy/module/cpyext/test/test_bytearrayobject.py b/pypy/module/cpyext/test/test_bytearrayobject.py
--- a/pypy/module/cpyext/test/test_bytearrayobject.py
+++ b/pypy/module/cpyext/test/test_bytearrayobject.py
@@ -1,5 +1,6 @@
 from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase
 
+
 class AppTestStringObject(AppTestCpythonExtensionBase):
     def test_basic(self):
         module = self.import_extension('foo', [
@@ -31,7 +32,7 @@
                  if(s->ob_type->tp_basicsize != expected_size)
                  {
                      printf("tp_basicsize==%ld\\n",
-                            (long)s->ob_type->tp_basicsize); 
+                            (long)s->ob_type->tp_basicsize);
                      result = 0;
                  }
                  Py_DECREF(s);
@@ -53,7 +54,6 @@
              """
                  PyObject *s, *t;
                  char* c;
-                 Py_ssize_t len;
 
                  s = PyByteArray_FromStringAndSize(NULL, 4);
                  if (s == NULL)
@@ -84,11 +84,10 @@
             ("mutable", "METH_NOARGS",
              """
                 PyObject *base;
-                char * p_str;
                 base = PyByteArray_FromStringAndSize("test", 10);
                 if (PyByteArray_GET_SIZE(base) != 10)
                     return PyLong_FromLong(-PyByteArray_GET_SIZE(base));
-                memcpy(PyByteArray_AS_STRING(base), "works", 6); 
+                memcpy(PyByteArray_AS_STRING(base), "works", 6);
                 Py_INCREF(base);
                 return base;
              """),
@@ -115,6 +114,7 @@
         assert s == 'test'
 
     def test_manipulations(self):
+        import sys
         module = self.import_extension('foo', [
             ("bytearray_from_string", "METH_VARARGS",
              '''
@@ -141,9 +141,9 @@
             ("concat", "METH_VARARGS",
              """
                 PyObject * ret, *right, *left;
-                PyObject *ba1, *ba2; 
+                PyObject *ba1, *ba2;
                 if (!PyArg_ParseTuple(args, "OO", &left, &right)) {
-                    return PyString_FromString("parse failed"); 
+                    return PyString_FromString("parse failed");
                 }
                 ba1 = PyByteArray_FromObject(left);
                 ba2 = PyByteArray_FromObject(right);
@@ -157,7 +157,9 @@
              """)])
         assert module.bytearray_from_string("huheduwe") == "huhe"
         assert module.str_from_bytearray(bytearray('abc')) == 'abc'
-        raises(ValueError, module.str_from_bytearray, 4.0)
+        if '__pypy__' in sys.builtin_module_names:
+            # CPython only makes an assert.
+            raises(ValueError, module.str_from_bytearray, 4.0)
         ret = module.concat('abc', 'def')
         assert ret == 'abcdef'
         assert not isinstance(ret, str)
@@ -171,9 +173,9 @@
              PyObject *obj, *ba;
              int newsize, oldsize, ret;
              if (!PyArg_ParseTuple(args, "Oi", &obj, &newsize)) {
-                 return PyString_FromString("parse failed"); 
+                 return PyString_FromString("parse failed");
              }
-             
+
              ba = PyByteArray_FromObject(obj);
              if (ba == NULL)
                  return NULL;
@@ -187,7 +189,7 @@
              {
                   printf("ret, oldsize, newsize= %d, %d, %d\\n", ret, oldsize, newsize);
                   return NULL;
-             } 
+             }
              return ba;
              '''
             )])
diff --git a/pypy/module/cpyext/test/test_bytesobject.py b/pypy/module/cpyext/test/test_bytesobject.py
--- a/pypy/module/cpyext/test/test_bytesobject.py
+++ b/pypy/module/cpyext/test/test_bytesobject.py
@@ -29,7 +29,7 @@
                  size_t expected_size;
 
                  result = PyString_Size(s);
-                
+
                  #ifdef PYPY_VERSION
                     expected_size = 48;
                  #elif defined Py_DEBUG
@@ -39,7 +39,7 @@
                  #endif
                  if(s->ob_type->tp_basicsize != expected_size)
                  {
-                     printf("tp_basicsize==%zd\\n", s->ob_type->tp_basicsize); 
+                     printf("tp_basicsize==%zd\\n", s->ob_type->tp_basicsize);
                      result = 0;
                  }
                  Py_DECREF(s);
@@ -48,7 +48,7 @@
             ("test_Size_exception", "METH_NOARGS",
              """
                  PyObject* f = PyFloat_FromDouble(1.0);
-                 Py_ssize_t size = PyString_Size(f);
+                 PyString_Size(f);
 
                  Py_DECREF(f);
                  return NULL;
@@ -71,7 +71,6 @@
              """
                  PyObject *s, *t;
                  char* c;
-                 Py_ssize_t len;
 
                  s = PyString_FromStringAndSize(NULL, 4);
                  if (s == NULL)
@@ -99,7 +98,6 @@
                 PyObject *base;
                 PyTypeObject * type;
                 PyStringObject *obj;
-                char * p_str;
                 base = PyString_FromString("test");
                 if (PyString_GET_SIZE(base) != 4)
                     return PyLong_FromLong(-PyString_GET_SIZE(base));
@@ -117,7 +115,6 @@
             ('alloc_rw', "METH_NOARGS",
              '''
                 PyObject *obj = _PyObject_NewVar(&PyString_Type, 10);
-                char * buf = PyString_AS_STRING(obj);
                 memcpy(PyString_AS_STRING(obj), "works", 6);
                 return (PyObject*)obj;
              '''),
@@ -320,17 +317,17 @@
              '''
                 PyObject* obj = (PyTuple_GetItem(args, 0));
                 long hash = ((PyStringObject*)obj)->ob_shash;
-                return PyLong_FromLong(hash);  
+                return PyLong_FromLong(hash);
              '''
              ),
             ("test_sstate", "METH_NOARGS",
              '''
                 PyObject *s = PyString_FromString("xyz");
-                int sstate = ((PyStringObject*)s)->ob_sstate;
-                /*printf("sstate now %d\\n", sstate);*/
+                /*int sstate = ((PyStringObject*)s)->ob_sstate;
+                printf("sstate now %d\\n", sstate);*/
                 PyString_InternInPlace(&s);
-                sstate = ((PyStringObject*)s)->ob_sstate;
-                /*printf("sstate now %d\\n", sstate);*/
+                /*sstate = ((PyStringObject*)s)->ob_sstate;
+                printf("sstate now %d\\n", sstate);*/
                 Py_DECREF(s);
                 return PyBool_FromLong(1);
              '''),
@@ -349,7 +346,7 @@
                 char * data;
                 int len;
                 PyType_Ready(&PyStringArrType_Type);
-                
+
                 data = PyString_AS_STRING(args);
                 len = PyString_GET_SIZE(args);
                 if (data == NULL || len < 1)
@@ -373,7 +370,6 @@
                         const char *dptr, *ip;
                         int len;
                         PyObject *new;
-                        PyObject *ret;
 
                         ip = dptr = PyString_AS_STRING(self);
                         len = PyString_GET_SIZE(self);
@@ -394,7 +390,6 @@
                         const char *dptr, *ip;
                         int len;
                         PyObject *new;
-                        PyObject *ret;
 
                         ip = dptr = PyString_AS_STRING(self);
                         len = PyString_GET_SIZE(self);
@@ -415,7 +410,6 @@
                         PyTypeObject *type = &PyStringArrType_Type;
                         PyObject *obj;
                         void *destptr;
-                        int type_num;
                         int itemsize = n;
                         obj = type->tp_alloc(type, itemsize);
                         if (obj == NULL) {
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
@@ -7,8 +7,6 @@
 from pypy import pypydir
 from pypy.interpreter import gateway
 from rpython.rtyper.lltypesystem import lltype, ll2ctypes
-from rpython.translator.tool.cbuild import ExternalCompilationInfo
-from rpython.translator import platform
 from rpython.translator.gensupp import uniquemodulename
 from rpython.tool.udir import udir
 from pypy.module.cpyext import api
@@ -18,20 +16,7 @@
 from rpython.tool import leakfinder
 from rpython.rlib import rawrefcount
 
-def setup_module(module):
-    if os.name == 'nt':
-        # Do not open dreaded dialog box on segfault
-        import ctypes
-        SEM_NOGPFAULTERRORBOX = 0x0002 # From MSDN
-        old_err_mode = ctypes.windll.kernel32.GetErrorMode()
-        new_err_mode = old_err_mode | SEM_NOGPFAULTERRORBOX
-        ctypes.windll.kernel32.SetErrorMode(new_err_mode)
-        module.old_err_mode = old_err_mode
-
-def teardown_module(module):
-    if os.name == 'nt':
-        import ctypes
-        ctypes.windll.kernel32.SetErrorMode(module.old_err_mode)
+from .support import c_compile
 
 @api.cpython_api([], api.PyObject)
 def PyPy_Crash1(space):
@@ -46,7 +31,30 @@
         assert 'PyModule_Check' in api.FUNCTIONS
         assert api.FUNCTIONS['PyModule_Check'].argtypes == [api.PyObject]
 
-def compile_extension_module(space, modname, include_dirs=[], **kwds):
+def convert_sources_to_files(sources, dirname):
+    files = []
+    for i, source in enumerate(sources):
+        filename = dirname / ('source_%d.c' % i)
+        with filename.open('w') as f:
+            f.write(str(source))
+        files.append(filename)
+    return files
+
+def create_so(modname, include_dirs, source_strings=None, source_files=None,
+        compile_extra=None, link_extra=None, libraries=None):
+    dirname = (udir/uniquemodulename('module')).ensure(dir=1)
+    if source_strings:
+        assert not source_files
+        files = convert_sources_to_files(source_strings, dirname)
+        source_files = files
+    soname = c_compile(source_files, outputfilename=str(dirname/modname),
+        compile_extra=compile_extra, link_extra=link_extra,
+        include_dirs=include_dirs,
+        libraries=libraries)
+    return soname
+
+def compile_extension_module(space, modname, include_dirs=[],
+        source_files=None, source_strings=None):
     """
     Build an extension module and return the filename of the resulting native
     code file.
@@ -60,38 +68,36 @@
     state = space.fromcache(State)
     api_library = state.api_lib
     if sys.platform == 'win32':
-        kwds["libraries"] = [api_library]
+        libraries = [api_library]
         # '%s' undefined; assuming extern returning int
-        kwds["compile_extra"] = ["/we4013"]
+        compile_extra = ["/we4013"]
         # prevent linking with PythonXX.lib
         w_maj, w_min = space.fixedview(space.sys.get('version_info'), 5)[:2]
-        kwds["link_extra"] = ["/NODEFAULTLIB:Python%d%d.lib" %
+        link_extra = ["/NODEFAULTLIB:Python%d%d.lib" %
                               (space.int_w(w_maj), space.int_w(w_min))]
-    elif sys.platform == 'darwin':
-        kwds["link_files"] = [str(api_library + '.dylib')]
     else:
-        kwds["link_files"] = [str(api_library + '.so')]
+        libraries = []
         if sys.platform.startswith('linux'):
-            kwds["compile_extra"]=["-Werror", "-g", "-O0"]
-            kwds["link_extra"]=["-g"]
+            compile_extra = ["-Werror", "-g", "-O0", "-fPIC"]
+            link_extra = ["-g"]
+        else:
+            compile_extra = link_extra = None
 
     modname = modname.split('.')[-1]
-    eci = ExternalCompilationInfo(
-        include_dirs=api.include_dirs + include_dirs,
-        **kwds
-        )
-    eci = eci.convert_sources_to_files()
-    dirname = (udir/uniquemodulename('module')).ensure(dir=1)
-    soname = platform.platform.compile(
-        [], eci,
-        outputfilename=str(dirname/modname),
-        standalone=False)
+    soname = create_so(modname,
+            include_dirs=api.include_dirs + include_dirs,
+            source_files=source_files,
+            source_strings=source_strings,
+            compile_extra=compile_extra,
+            link_extra=link_extra,
+            libraries=libraries)
     from pypy.module.imp.importing import get_so_extension
     pydname = soname.new(purebasename=modname, ext=get_so_extension(space))
     soname.rename(pydname)
     return str(pydname)
 
-def compile_extension_module_applevel(space, modname, include_dirs=[], **kwds):
+def compile_extension_module_applevel(space, modname, include_dirs=[],
+        source_files=None, source_strings=None):
     """
     Build an extension module and return the filename of the resulting native
     code file.
@@ -103,24 +109,23 @@
     build the module (so specify your source with one of those).
     """
     if sys.platform == 'win32':
-        kwds["compile_extra"] = ["/we4013"]
-        kwds["link_extra"] = ["/LIBPATH:" + os.path.join(sys.exec_prefix, 'libs')]
+        compile_extra = ["/we4013"]
+        link_extra = ["/LIBPATH:" + os.path.join(sys.exec_prefix, 'libs')]
     elif sys.platform == 'darwin':
+        compile_extra = link_extra = None
         pass
     elif sys.platform.startswith('linux'):
-            kwds["compile_extra"]=["-O0", "-g","-Werror=implicit-function-declaration"]
+        compile_extra = [
+            "-O0", "-g", "-Werror=implicit-function-declaration", "-fPIC"]
+        link_extra = None
 
     modname = modname.split('.')[-1]
-    eci = ExternalCompilationInfo(
-        include_dirs = [space.include_dir] + include_dirs,
-        **kwds
-        )
-    eci = eci.convert_sources_to_files()
-    dirname = (udir/uniquemodulename('module')).ensure(dir=1)
-    soname = platform.platform.compile(
-        [], eci,
-        outputfilename=str(dirname/modname),
-        standalone=False)
+    soname = create_so(modname,
+            include_dirs=[space.include_dir] + include_dirs,
+            source_files=source_files,
+            source_strings=source_strings,
+            compile_extra=compile_extra,
+            link_extra=link_extra)
     return str(soname)
 
 def freeze_refcnts(self):
@@ -285,8 +290,8 @@
                 separate_module_sources = []
             pydname = self.compile_extension_module(
                 space, name,
-                separate_module_files=separate_module_files,
-                separate_module_sources=separate_module_sources)
+                source_files=separate_module_files,
+                source_strings=separate_module_sources)
             return space.wrap(pydname)
 
         @gateway.unwrap_spec(name=str, init='str_or_None', body=str,
@@ -315,6 +320,11 @@
                 /* fix for cpython 2.7 Python.h if running tests with -A
                    since pypy compiles with -fvisibility-hidden */
                 #undef PyMODINIT_FUNC
+                #ifdef __GNUC__
+                #  define RPY_EXPORTED extern __attribute__((visibility("default")))
+                #else
+                #  define RPY_EXPORTED extern __declspec(dllexport)
+                #endif
                 #define PyMODINIT_FUNC RPY_EXPORTED void
 
                 %(body)s
@@ -326,16 +336,16 @@
                 """ % dict(name=name, init=init, body=body,
                            PY_SSIZE_T_CLEAN='#define PY_SSIZE_T_CLEAN'
                                             if PY_SSIZE_T_CLEAN else '')
-                kwds = dict(separate_module_sources=[code])
+                kwds = dict(source_strings=[code])
             else:
                 assert not PY_SSIZE_T_CLEAN
                 if filename is None:
                     filename = name
                 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)
+                kwds = dict(source_files=[filename])
+            mod = self.compile_extension_module(space, name,
+                    include_dirs=include_dirs, **kwds)
 
             if load_it:
                 if self.runappdirect:
@@ -975,7 +985,7 @@
             ('bar', 'METH_NOARGS',
              '''
              /* reuse a name that is #defined in structmember.h */
-             int RO;
+             int RO = 0; (void)RO;
              Py_RETURN_NONE;
              '''
              ),
diff --git a/pypy/module/cpyext/test/test_datetime.py b/pypy/module/cpyext/test/test_datetime.py
--- a/pypy/module/cpyext/test/test_datetime.py
+++ b/pypy/module/cpyext/test/test_datetime.py
@@ -142,7 +142,7 @@
                     2000, 6, 6, 6, 6, 6, 6, Py_None,
                     PyDateTimeAPI->DateTimeType);
              """),
-        ])
+        ], prologue='#include "datetime.h"\n')
         import datetime
         assert module.new_date() == datetime.date(2000, 6, 6)
         assert module.new_time() == datetime.time(6, 6, 6, 6)
@@ -241,6 +241,9 @@
                  PyObject* obj = PyDelta_FromDSU(6, 6, 6);
                  PyDateTime_Delta* delta = (PyDateTime_Delta*)obj;
 
+#if defined(PYPY_VERSION) || PY_VERSION_HEX >= 0x03030000
+                 // These macros are only defined in CPython 3.x and PyPy.
+                 // See: http://bugs.python.org/issue13727
                  PyDateTime_DELTA_GET_DAYS(obj);
                  PyDateTime_DELTA_GET_DAYS(delta);
 
@@ -249,10 +252,10 @@
 
                  PyDateTime_DELTA_GET_MICROSECONDS(obj);
                  PyDateTime_DELTA_GET_MICROSECONDS(delta);
-
+#endif
                  return obj;
              """),
-            ])
+            ], prologue='#include "datetime.h"\n')
         import datetime
         assert module.test_date_macros() == datetime.date(2000, 6, 6)
         assert module.test_datetime_macros() == datetime.datetime(
diff --git a/pypy/module/cpyext/test/test_frameobject.py b/pypy/module/cpyext/test/test_frameobject.py
--- a/pypy/module/cpyext/test/test_frameobject.py
+++ b/pypy/module/cpyext/test/test_frameobject.py
@@ -13,7 +13,7 @@
                  PyObject *empty_string = PyString_FromString("");
                  PyObject *empty_tuple = PyTuple_New(0);
                  PyCodeObject *py_code;
-                 PyFrameObject *py_frame;
+                 PyFrameObject *py_frame = NULL;
 
                  py_code = PyCode_New(
                      0,            /*int argcount,*/
@@ -75,7 +75,7 @@
              """
                  int check;
                  PyObject *type, *value, *tb;
-                 PyObject *ret = PyRun_String("XXX", Py_eval_input, 
+                 PyObject *ret = PyRun_String("XXX", Py_eval_input,
                                               Py_None, Py_None);
                  if (ret) {
                      Py_DECREF(ret);
diff --git a/pypy/module/cpyext/test/test_getargs.py b/pypy/module/cpyext/test/test_getargs.py
--- a/pypy/module/cpyext/test/test_getargs.py
+++ b/pypy/module/cpyext/test/test_getargs.py
@@ -149,7 +149,6 @@
         pybuffer = self.import_parser(
             '''
             Py_buffer buf1, buf2, buf3;
-            PyObject *result;
             if (!PyArg_ParseTuple(args, "s*s*s*", &buf1, &buf2, &buf3)) {
                 return NULL;
             }
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
@@ -5,7 +5,7 @@
 from rpython.rtyper.lltypesystem import rffi, lltype
 from pypy.module.micronumpy.ndarray import W_NDimArray
 from pypy.module.micronumpy.descriptor import get_dtype_cache
-import pypy.module.micronumpy.constants as NPY 
+import pypy.module.micronumpy.constants as NPY
 
 def scalar(space):
     dtype = get_dtype_cache(space).w_float64dtype
@@ -237,7 +237,7 @@
             except:
                 skip('numpy not importable')
         else:
-            numpy_incl = os.path.abspath(os.path.dirname(__file__) + 
+            numpy_incl = os.path.abspath(os.path.dirname(__file__) +
                                          '/../include/_numpypy')
             assert os.path.exists(numpy_incl)
             cls.w_numpy_include = cls.space.wrap([numpy_incl])
@@ -273,7 +273,7 @@
                 {
                     /* Should have failed */
                     Py_DECREF(obj1);
-                    return NULL; 
+                    return NULL;
                 }
                 return obj1;
                 '''
@@ -300,14 +300,14 @@
                 ),
                 ("test_DescrFromType", "METH_O",
                 """
-                    Signed typenum = PyInt_AsLong(args);
+                    long typenum = PyInt_AsLong(args);
                     return PyArray_DescrFromType(typenum);
                 """
                 ),
-                ], include_dirs=self.numpy_include, 
+                ], include_dirs=self.numpy_include,
                    prologue='''
                 #ifdef PYPY_VERSION
-                    #include <pypy_numpy.h>    
+                    #include <pypy_numpy.h>
                 #endif
                 #define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
                 #include <numpy/arrayobject.h>
@@ -315,7 +315,7 @@
                     #define PyArray_FromObject _PyArray_FromObject
                     #define PyArray_FromAny _PyArray_FromAny
                 #endif
-                ''', 
+                ''',
                     more_init = '''
                 #ifndef PYPY_VERSION
                     import_array();
@@ -349,14 +349,14 @@
                     Py_INCREF(obj);
                     return obj;
                 '''),
-                ], include_dirs=self.numpy_include, 
+                ], include_dirs=self.numpy_include,
                    prologue='''
                 #ifdef PYPY_VERSION
-                    #include <pypy_numpy.h>    
+                    #include <pypy_numpy.h>
                 #endif
                 #define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
                 #include <numpy/arrayobject.h>
-                ''', 
+                ''',
                     more_init = '''
                 #ifndef PYPY_VERSION
                     import_array();
@@ -403,14 +403,14 @@
                 void *array_data[] = {NULL, NULL};
                 return PyUFunc_FromFuncAndDataAndSignature(funcs,
                                     array_data, types, 1, 1, 1, PyUFunc_None,
-                                    "float_3x3", 
-                                    "a ufunc that tests a more complicated signature", 
+                                    "float_3x3",
+                                    "a ufunc that tests a more complicated signature",
                                     0, "(m,m)->(m,m)");
                 """),
-                ], include_dirs=self.numpy_include, 
+                ], include_dirs=self.numpy_include,
                    prologue='''
                 #ifdef PYPY_VERSION
-                    #include <pypy_numpy.h>    
+                    #include <pypy_numpy.h>
                 #endif
                 #define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
                 #include <numpy/arrayobject.h>
@@ -480,7 +480,7 @@
                             res += +10;
                     *((float *)args[1]) = res;
                 };
-                            
+
                 ''',  more_init = '''
                 #ifndef PYPY_VERSION
                     import_array();
diff --git a/pypy/module/cpyext/test/test_object.py b/pypy/module/cpyext/test/test_object.py
--- a/pypy/module/cpyext/test/test_object.py
+++ b/pypy/module/cpyext/test/test_object.py
@@ -127,12 +127,12 @@
         test_compare(1, 2)
         test_compare(2, 2)
         test_compare('2', '1')
-        
+
         w_i = space.wrap(1)
         assert api.PyObject_RichCompareBool(w_i, w_i, 123456) == -1
         assert api.PyErr_Occurred() is space.w_SystemError
         api.PyErr_Clear()
-        
+
     def test_IsInstance(self, space, api):
         assert api.PyObject_IsInstance(space.wrap(1), space.w_int) == 1
         assert api.PyObject_IsInstance(space.wrap(1), space.w_float) == 0
@@ -165,7 +165,7 @@
             return File""")
         w_f = space.call_function(w_File)
         assert api.PyObject_AsFileDescriptor(w_f) == 42
-    
+
     def test_hash(self, space, api):
         assert api.PyObject_Hash(space.wrap(72)) == 72
         assert api.PyObject_Hash(space.wrap(-1)) == -1
@@ -250,7 +250,7 @@
                  if (copy != orig)
                      PyObject_Free(copy);
                  PyObject_Free(orig);
-                 return ret;  
+                 return ret;
              """)])
         x = module.realloctest()
         assert x == 'hello world\x00'
@@ -425,7 +425,6 @@
                  """
     Py_buffer buf;
     PyObject *str = PyString_FromString("hello, world.");
-    PyObject *result;
 
     if (PyBuffer_FillInfo(&buf, str, PyString_AsString(str), 13,
                           1, PyBUF_WRITABLE)) {
diff --git a/pypy/module/cpyext/test/test_tupleobject.py b/pypy/module/cpyext/test/test_tupleobject.py
--- a/pypy/module/cpyext/test/test_tupleobject.py
+++ b/pypy/module/cpyext/test/test_tupleobject.py
@@ -130,7 +130,7 @@
         module = self.import_extension('foo', [
             ("run", "METH_NOARGS",
              """
-                long prev, next;
+                long prev;
                 PyObject *t = PyTuple_New(1);
                 prev = Py_True->ob_refcnt;
                 Py_INCREF(Py_True);
diff --git a/pypy/module/cpyext/test/test_typeobject.py b/pypy/module/cpyext/test/test_typeobject.py
--- a/pypy/module/cpyext/test/test_typeobject.py
+++ b/pypy/module/cpyext/test/test_typeobject.py
@@ -5,8 +5,6 @@
 from pypy.module.cpyext.pyobject import make_ref, from_ref
 from pypy.module.cpyext.typeobject import PyTypeObjectPtr
 
-import sys
-
 class AppTestTypeObject(AppTestCpythonExtensionBase):
     def test_typeobject(self):
         import sys
@@ -737,7 +735,6 @@
              """
                 IntLikeObject *intObj;
                 int intval;
-                PyObject *name;
 
                 if (!PyArg_ParseTuple(args, "i", &intval))
                     return NULL;
@@ -897,7 +894,7 @@
         module.footype("X", (object,), {})
 
     def test_app_subclass_of_c_type(self):
-        # on cpython, the size changes (6 bytes added)
+        import sys
         module = self.import_module(name='foo')
         size = module.size_of_instances(module.fooType)
         class f1(object):
@@ -907,7 +904,11 @@
         class bar(f1, f2):
             pass
         assert bar.__base__ is f2
-        assert module.size_of_instances(bar) == size
+        # On cpython, the size changes.
+        if '__pypy__' in sys.builtin_module_names:
+            assert module.size_of_instances(bar) == size
+        else:
+            assert module.size_of_instances(bar) >= size
 
     def test_app_cant_subclass_two_types(self):
         module = self.import_module(name='foo')
@@ -1058,7 +1059,6 @@
         module = self.import_extension('foo', [
            ("getMetaClass", "METH_NOARGS",
             '''
-                PyObject *obj;
                 FooType_Type.tp_flags = Py_TPFLAGS_DEFAULT;
                 FooType_Type.tp_base = &PyType_Type;
                 if (PyType_Ready(&FooType_Type) < 0) return NULL;
diff --git a/pypy/module/cpyext/test/test_unicodeobject.py b/pypy/module/cpyext/test/test_unicodeobject.py
--- a/pypy/module/cpyext/test/test_unicodeobject.py
+++ b/pypy/module/cpyext/test/test_unicodeobject.py
@@ -35,7 +35,7 @@
             ("test_GetSize_exception", "METH_NOARGS",
              """
                  PyObject* f = PyFloat_FromDouble(1.0);
-                 Py_ssize_t size = PyUnicode_GetSize(f);
+                 PyUnicode_GetSize(f);
 
                  Py_DECREF(f);
                  return NULL;
@@ -57,7 +57,6 @@
              """
                  PyObject *s, *t;
                  Py_UNICODE* c;
-                 Py_ssize_t len;
 
                  s = PyUnicode_FromUnicode(NULL, 4);
                  if (s == NULL)
@@ -84,7 +83,7 @@
              '''
                 PyObject* obj = (PyTuple_GetItem(args, 0));
                 long hash = ((PyUnicodeObject*)obj)->hash;
-                return PyLong_FromLong(hash);  
+                return PyLong_FromLong(hash);
              '''
              ),
             ])
@@ -234,13 +233,13 @@
         w_res = api.PyUnicode_AsUTF8String(w_u)
         assert space.type(w_res) is space.w_str
         assert space.unwrap(w_res) == 'sp\tm'
-    
+
     def test_decode_utf8(self, space, api):
         u = rffi.str2charp(u'sp\x134m'.encode("utf-8"))
         w_u = api.PyUnicode_DecodeUTF8(u, 5, None)
         assert space.type(w_u) is space.w_unicode
         assert space.unwrap(w_u) == u'sp\x134m'
-        
+
         w_u = api.PyUnicode_DecodeUTF8(u, 2, None)
         assert space.type(w_u) is space.w_unicode
         assert space.unwrap(w_u) == 'sp'
@@ -405,7 +404,7 @@
         ustr = "abcdef"
         w_ustr = space.wrap(ustr.decode("ascii"))
         result = api.PyUnicode_AsASCIIString(w_ustr)
-        
+
         assert space.eq_w(space.wrap(ustr), result)
 
         w_ustr = space.wrap(u"abcd\xe9f")
diff --git a/rpython/jit/metainterp/optimizeopt/virtualstate.py b/rpython/jit/metainterp/optimizeopt/virtualstate.py
--- a/rpython/jit/metainterp/optimizeopt/virtualstate.py
+++ b/rpython/jit/metainterp/optimizeopt/virtualstate.py
@@ -478,7 +478,7 @@
             self.intbound = info
 
     def _generate_guards_unkown(self, other, box, runtime_box, extra_guards,
-                                optimizer):
+                                state):
         other_intbound = None
         if isinstance(other, NotVirtualStateInfoInt):
             other_intbound = other.intbound
@@ -490,7 +490,7 @@
             self.intbound.contains(runtime_box.getint())):
             # this may generate a few more guards than needed, but they are
             # optimized away when emitting them
-            self.intbound.make_guards(box, extra_guards, optimizer)
+            self.intbound.make_guards(box, extra_guards, state.optimizer)
             return
         raise VirtualStatesCantMatch("intbounds don't match")
 
diff --git a/rpython/rlib/_rsocket_rffi.py b/rpython/rlib/_rsocket_rffi.py
--- a/rpython/rlib/_rsocket_rffi.py
+++ b/rpython/rlib/_rsocket_rffi.py
@@ -487,7 +487,9 @@
 #hstrerror.argtypes = [c_int]
 #hstrerror.restype = c_char_p
 
-socket = external('socket', [rffi.INT, rffi.INT, rffi.INT], socketfd_type)
+socket = external('socket', [rffi.INT, rffi.INT, rffi.INT], socketfd_type,
+                  save_err=SAVE_ERR)
+
 
 if WIN32:
     socketclosename = 'closesocket'
diff --git a/rpython/rlib/test/test_rsocket.py b/rpython/rlib/test/test_rsocket.py
--- a/rpython/rlib/test/test_rsocket.py
+++ b/rpython/rlib/test/test_rsocket.py
@@ -589,3 +589,15 @@
         return 0
     fc = compile(f, [], thread=True)
     assert fc() == 0
+
+def test_socket_saves_errno(tmpdir):
+    # ensure errno is set to a known value...
+    unconnected_sock = RSocket()
+    e = py.test.raises(CSocketError, unconnected_sock.recv, 1024)
+    # ...which is ENOTCONN
+    assert e.value.errno == errno.ENOTCONN
+
+    e = py.test.raises(CSocketError,
+                       RSocket,
+                       family=AF_INET, type=SOCK_STREAM, proto=SOL_UDP)
+    assert e.value.errno in (errno.EPROTOTYPE, errno.EPROTONOSUPPORT)


More information about the pypy-commit mailing list