[pypy-commit] pypy py3k: update cpyext src directory with CPython 3.2 source code

amauryfa noreply at buildbot.pypy.org
Wed May 2 01:04:00 CEST 2012


Author: Amaury Forgeot d'Arc <amauryfa at gmail.com>
Branch: py3k
Changeset: r54856:da56b5415d72
Date: 2012-04-28 23:11 +0200
http://bitbucket.org/pypy/pypy/changeset/da56b5415d72/

Log:	update cpyext src directory with CPython 3.2 source code

diff --git a/pypy/module/cpyext/src/getargs.c b/pypy/module/cpyext/src/getargs.c
--- a/pypy/module/cpyext/src/getargs.c
+++ b/pypy/module/cpyext/src/getargs.c
@@ -94,15 +94,7 @@
 {
     va_list lva;
 
-#ifdef VA_LIST_IS_ARRAY
-    memcpy(lva, va, sizeof(va_list));
-#else
-#ifdef __va_copy
-    __va_copy(lva, va);
-#else
-    lva = va;
-#endif
-#endif
+        Py_VA_COPY(lva, va);
 
     return vgetargs1(args, format, &lva, 0);
 }
@@ -112,15 +104,7 @@
 {
     va_list lva;
 
-#ifdef VA_LIST_IS_ARRAY
-    memcpy(lva, va, sizeof(va_list));
-#else
-#ifdef __va_copy
-    __va_copy(lva, va);
-#else
-    lva = va;
-#endif
-#endif
+        Py_VA_COPY(lva, va);
 
     return vgetargs1(args, format, &lva, FLAG_SIZE_T);
 }
@@ -130,13 +114,14 @@
 
 #define GETARGS_CAPSULE_NAME_CLEANUP_PTR "getargs.cleanup_ptr"
 #define GETARGS_CAPSULE_NAME_CLEANUP_BUFFER "getargs.cleanup_buffer"
+#define GETARGS_CAPSULE_NAME_CLEANUP_CONVERT "getargs.cleanup_convert"
 
 static void
 cleanup_ptr(PyObject *self)
 {
     void *ptr = PyCapsule_GetPointer(self, GETARGS_CAPSULE_NAME_CLEANUP_PTR);
     if (ptr) {
-      PyMem_FREE(ptr);
+        PyMem_FREE(ptr);
     }
 }
 
@@ -150,10 +135,19 @@
 }
 
 static int
-addcleanup(void *ptr, PyObject **freelist, PyCapsule_Destructor destr)
+addcleanup(void *ptr, PyObject **freelist, int is_buffer)
 {
     PyObject *cobj;
     const char *name;
+    PyCapsule_Destructor destr;
+
+    if (is_buffer) {
+        destr = cleanup_buffer;
+        name = GETARGS_CAPSULE_NAME_CLEANUP_BUFFER;
+    } else {
+        destr = cleanup_ptr;
+        name = GETARGS_CAPSULE_NAME_CLEANUP_PTR;
+    }
 
     if (!*freelist) {
         *freelist = PyList_New(0);
@@ -163,13 +157,6 @@
         }
     }
 
-    if (destr == cleanup_ptr) {
-        name = GETARGS_CAPSULE_NAME_CLEANUP_PTR;
-    } else if (destr == cleanup_buffer) {
-        name = GETARGS_CAPSULE_NAME_CLEANUP_BUFFER;
-    } else {
-        return -1;
-    }
     cobj = PyCapsule_New(ptr, name, destr);
     if (!cobj) {
         destr(ptr);
@@ -183,6 +170,46 @@
     return 0;
 }
 
+static void
+cleanup_convert(PyObject *self)
+{
+    typedef int (*destr_t)(PyObject *, void *);
+    destr_t destr = (destr_t)PyCapsule_GetContext(self);
+    void *ptr = PyCapsule_GetPointer(self,
+                                     GETARGS_CAPSULE_NAME_CLEANUP_CONVERT);
+    if (ptr && destr)
+        destr(NULL, ptr);
+}
+
+static int
+addcleanup_convert(void *ptr, PyObject **freelist, int (*destr)(PyObject*,void*))
+{
+    PyObject *cobj;
+    if (!*freelist) {
+        *freelist = PyList_New(0);
+        if (!*freelist) {
+            destr(NULL, ptr);
+            return -1;
+        }
+    }
+    cobj = PyCapsule_New(ptr, GETARGS_CAPSULE_NAME_CLEANUP_CONVERT,
+                         cleanup_convert);
+    if (!cobj) {
+        destr(NULL, ptr);
+        return -1;
+    }
+    if (PyCapsule_SetContext(cobj, destr) == -1) {
+        /* This really should not happen. */
+        Py_FatalError("capsule refused setting of context.");
+    }
+    if (PyList_Append(*freelist, cobj)) {
+        Py_DECREF(cobj); /* This will also call destr. */
+        return -1;
+    }
+    Py_DECREF(cobj);
+    return 0;
+}
+
 static int
 cleanreturn(int retval, PyObject *freelist)
 {
@@ -437,7 +464,7 @@
             n++;
     }
 
-    if (!PySequence_Check(arg) || PyString_Check(arg)) {
+    if (!PySequence_Check(arg) || PyBytes_Check(arg)) {
         levels[0] = 0;
         PyOS_snprintf(msgbuf, bufsize,
                       toplevel ? "expected %d arguments, not %.50s" :
@@ -531,27 +558,14 @@
 
 #define CONV_UNICODE "(unicode conversion error)"
 
-/* explicitly check for float arguments when integers are expected.  For now
- * signal a warning.  Returns true if an exception was raised. */
-static int
-float_argument_warning(PyObject *arg)
-{
-    if (PyFloat_Check(arg) &&
-        PyErr_Warn(PyExc_DeprecationWarning,
-                   "integer argument expected, got float" ))
-        return 1;
-    else
-        return 0;
-}
-
-/* explicitly check for float arguments when integers are expected.  Raises
-   TypeError and returns true for float arguments. */
+/* Explicitly check for float arguments when integers are expected.
+   Return 1 for error, 0 if ok. */
 static int
 float_argument_error(PyObject *arg)
 {
     if (PyFloat_Check(arg)) {
         PyErr_SetString(PyExc_TypeError,
-                        "integer argument expected, got float");
+                        "integer argument expected, got float" );
         return 1;
     }
     else
@@ -587,12 +601,11 @@
         *q=s; \
     }
 #define BUFFER_LEN      ((flags & FLAG_SIZE_T) ? *q2:*q)
+#define RETURN_ERR_OCCURRED return msgbuf
 
     const char *format = *p_format;
     char c = *format++;
-#ifdef Py_USING_UNICODE
     PyObject *uarg;
-#endif
 
     switch (c) {
 
@@ -600,19 +613,19 @@
         char *p = va_arg(*p_va, char *);
         long ival;
         if (float_argument_error(arg))
-            return converterr("integer<b>", arg, msgbuf, bufsize);
-        ival = PyInt_AsLong(arg);
+            RETURN_ERR_OCCURRED;
+        ival = PyLong_AsLong(arg);
         if (ival == -1 && PyErr_Occurred())
-            return converterr("integer<b>", arg, msgbuf, bufsize);
+            RETURN_ERR_OCCURRED;
         else if (ival < 0) {
             PyErr_SetString(PyExc_OverflowError,
-            "unsigned byte integer is less than minimum");
-            return converterr("integer<b>", arg, msgbuf, bufsize);
+                            "unsigned byte integer is less than minimum");
+            RETURN_ERR_OCCURRED;
         }
         else if (ival > UCHAR_MAX) {
             PyErr_SetString(PyExc_OverflowError,
-            "unsigned byte integer is greater than maximum");
-            return converterr("integer<b>", arg, msgbuf, bufsize);
+                            "unsigned byte integer is greater than maximum");
+            RETURN_ERR_OCCURRED;
         }
         else
             *p = (unsigned char) ival;
@@ -624,10 +637,10 @@
         char *p = va_arg(*p_va, char *);
         long ival;
         if (float_argument_error(arg))
-            return converterr("integer<B>", arg, msgbuf, bufsize);
-        ival = PyInt_AsUnsignedLongMask(arg);
+            RETURN_ERR_OCCURRED;
+        ival = PyLong_AsUnsignedLongMask(arg);
         if (ival == -1 && PyErr_Occurred())
-            return converterr("integer<B>", arg, msgbuf, bufsize);
+            RETURN_ERR_OCCURRED;
         else
             *p = (unsigned char) ival;
         break;
@@ -637,19 +650,19 @@
         short *p = va_arg(*p_va, short *);
         long ival;
         if (float_argument_error(arg))
-            return converterr("integer<h>", arg, msgbuf, bufsize);
-        ival = PyInt_AsLong(arg);
+            RETURN_ERR_OCCURRED;
+        ival = PyLong_AsLong(arg);
         if (ival == -1 && PyErr_Occurred())
-            return converterr("integer<h>", arg, msgbuf, bufsize);
+            RETURN_ERR_OCCURRED;
         else if (ival < SHRT_MIN) {
             PyErr_SetString(PyExc_OverflowError,
-            "signed short integer is less than minimum");
-            return converterr("integer<h>", arg, msgbuf, bufsize);
+                            "signed short integer is less than minimum");
+            RETURN_ERR_OCCURRED;
         }
         else if (ival > SHRT_MAX) {
             PyErr_SetString(PyExc_OverflowError,
-            "signed short integer is greater than maximum");
-            return converterr("integer<h>", arg, msgbuf, bufsize);
+                            "signed short integer is greater than maximum");
+            RETURN_ERR_OCCURRED;
         }
         else
             *p = (short) ival;
@@ -661,10 +674,10 @@
         unsigned short *p = va_arg(*p_va, unsigned short *);
         long ival;
         if (float_argument_error(arg))
-            return converterr("integer<H>", arg, msgbuf, bufsize);
-        ival = PyInt_AsUnsignedLongMask(arg);
+            RETURN_ERR_OCCURRED;
+        ival = PyLong_AsUnsignedLongMask(arg);
         if (ival == -1 && PyErr_Occurred())
-            return converterr("integer<H>", arg, msgbuf, bufsize);
+            RETURN_ERR_OCCURRED;
         else
             *p = (unsigned short) ival;
         break;
@@ -674,19 +687,19 @@
         int *p = va_arg(*p_va, int *);
         long ival;
         if (float_argument_error(arg))
-            return converterr("integer<i>", arg, msgbuf, bufsize);
-        ival = PyInt_AsLong(arg);
+            RETURN_ERR_OCCURRED;
+        ival = PyLong_AsLong(arg);
         if (ival == -1 && PyErr_Occurred())
-            return converterr("integer<i>", arg, msgbuf, bufsize);
+            RETURN_ERR_OCCURRED;
         else if (ival > INT_MAX) {
             PyErr_SetString(PyExc_OverflowError,
-                "signed integer is greater than maximum");
-            return converterr("integer<i>", arg, msgbuf, bufsize);
+                            "signed integer is greater than maximum");
+            RETURN_ERR_OCCURRED;
         }
         else if (ival < INT_MIN) {
             PyErr_SetString(PyExc_OverflowError,
-                "signed integer is less than minimum");
-            return converterr("integer<i>", arg, msgbuf, bufsize);
+                            "signed integer is less than minimum");
+            RETURN_ERR_OCCURRED;
         }
         else
             *p = ival;
@@ -698,38 +711,40 @@
         unsigned int *p = va_arg(*p_va, unsigned int *);
         unsigned int ival;
         if (float_argument_error(arg))
-            return converterr("integer<I>", arg, msgbuf, bufsize);
-        ival = (unsigned int)PyInt_AsUnsignedLongMask(arg);
+            RETURN_ERR_OCCURRED;
+        ival = (unsigned int)PyLong_AsUnsignedLongMask(arg);
         if (ival == (unsigned int)-1 && PyErr_Occurred())
-            return converterr("integer<I>", arg, msgbuf, bufsize);
+            RETURN_ERR_OCCURRED;
         else
             *p = ival;
         break;
     }
 
     case 'n': /* Py_ssize_t */
-#if SIZEOF_SIZE_T != SIZEOF_LONG
     {
+        PyObject *iobj;
         Py_ssize_t *p = va_arg(*p_va, Py_ssize_t *);
-        Py_ssize_t ival;
+        Py_ssize_t ival = -1;
         if (float_argument_error(arg))
-            return converterr("integer<n>", arg, msgbuf, bufsize);
-        ival = PyInt_AsSsize_t(arg);
+            RETURN_ERR_OCCURRED;
+        iobj = PyNumber_Index(arg);
+        if (iobj != NULL) {
+            ival = PyLong_AsSsize_t(iobj);
+            Py_DECREF(iobj);
+        }
         if (ival == -1 && PyErr_Occurred())
-            return converterr("integer<n>", arg, msgbuf, bufsize);
+            RETURN_ERR_OCCURRED;
         *p = ival;
         break;
     }
-#endif
-    /* Fall through from 'n' to 'l' if Py_ssize_t is int */
     case 'l': {/* long int */
         long *p = va_arg(*p_va, long *);
         long ival;
         if (float_argument_error(arg))
-            return converterr("integer<l>", arg, msgbuf, bufsize);
-        ival = PyInt_AsLong(arg);
+            RETURN_ERR_OCCURRED;
+        ival = PyLong_AsLong(arg);
         if (ival == -1 && PyErr_Occurred())
-            return converterr("integer<l>", arg, msgbuf, bufsize);
+            RETURN_ERR_OCCURRED;
         else
             *p = ival;
         break;
@@ -738,9 +753,7 @@
     case 'k': { /* long sized bitfield */
         unsigned long *p = va_arg(*p_va, unsigned long *);
         unsigned long ival;
-        if (PyInt_Check(arg))
-            ival = PyInt_AsUnsignedLongMask(arg);
-        else if (PyLong_Check(arg))
+        if (PyLong_Check(arg))
             ival = PyLong_AsUnsignedLongMask(arg);
         else
             return converterr("integer<k>", arg, msgbuf, bufsize);
@@ -752,23 +765,20 @@
     case 'L': {/* PY_LONG_LONG */
         PY_LONG_LONG *p = va_arg( *p_va, PY_LONG_LONG * );
         PY_LONG_LONG ival;
-        if (float_argument_warning(arg))
-            return converterr("long<L>", arg, msgbuf, bufsize);
+        if (float_argument_error(arg))
+            RETURN_ERR_OCCURRED;
         ival = PyLong_AsLongLong(arg);
-        if (ival == (PY_LONG_LONG)-1 && PyErr_Occurred() ) {
-            return converterr("long<L>", arg, msgbuf, bufsize);
-        } else {
+        if (ival == (PY_LONG_LONG)-1 && PyErr_Occurred())
+            RETURN_ERR_OCCURRED;
+        else
             *p = ival;
-        }
         break;
     }
 
     case 'K': { /* long long sized bitfield */
         unsigned PY_LONG_LONG *p = va_arg(*p_va, unsigned PY_LONG_LONG *);
         unsigned PY_LONG_LONG ival;
-        if (PyInt_Check(arg))
-            ival = PyInt_AsUnsignedLongMask(arg);
-        else if (PyLong_Check(arg))
+        if (PyLong_Check(arg))
             ival = PyLong_AsUnsignedLongLongMask(arg);
         else
             return converterr("integer<K>", arg, msgbuf, bufsize);
@@ -781,7 +791,7 @@
         float *p = va_arg(*p_va, float *);
         double dval = PyFloat_AsDouble(arg);
         if (PyErr_Occurred())
-            return converterr("float<f>", arg, msgbuf, bufsize);
+            RETURN_ERR_OCCURRED;
         else
             *p = (float) dval;
         break;
@@ -791,84 +801,124 @@
         double *p = va_arg(*p_va, double *);
         double dval = PyFloat_AsDouble(arg);
         if (PyErr_Occurred())
-            return converterr("float<d>", arg, msgbuf, bufsize);
+            RETURN_ERR_OCCURRED;
         else
             *p = dval;
         break;
     }
 
-#ifndef WITHOUT_COMPLEX
     case 'D': {/* complex double */
         Py_complex *p = va_arg(*p_va, Py_complex *);
         Py_complex cval;
         cval = PyComplex_AsCComplex(arg);
         if (PyErr_Occurred())
-            return converterr("complex<D>", arg, msgbuf, bufsize);
+            RETURN_ERR_OCCURRED;
         else
             *p = cval;
         break;
     }
-#endif /* WITHOUT_COMPLEX */
 
     case 'c': {/* char */
         char *p = va_arg(*p_va, char *);
-        if (PyString_Check(arg) && PyString_Size(arg) == 1)
-            *p = PyString_AS_STRING(arg)[0];
+        if (PyBytes_Check(arg) && PyBytes_Size(arg) == 1)
+            *p = PyBytes_AS_STRING(arg)[0];
         else
-            return converterr("char", arg, msgbuf, bufsize);
+            return converterr("a byte string of length 1", arg, msgbuf, bufsize);
         break;
     }
 
-    case 's': {/* string */
+    case 'C': {/* unicode char */
+        int *p = va_arg(*p_va, int *);
+        if (PyUnicode_Check(arg) &&
+            PyUnicode_GET_SIZE(arg) == 1)
+            *p = PyUnicode_AS_UNICODE(arg)[0];
+        else
+            return converterr("a unicode character", arg, msgbuf, bufsize);
+        break;
+    }
+
+    /* XXX WAAAAH!  's', 'y', 'z', 'u', 'Z', 'e', 'w' codes all
+       need to be cleaned up! */
+
+    case 'y': {/* any buffer-like object, but not PyUnicode */
+        void **p = (void **)va_arg(*p_va, char **);
+        char *buf;
+        Py_ssize_t count;
         if (*format == '*') {
+            if (getbuffer(arg, (Py_buffer*)p, &buf) < 0)
+                return converterr(buf, arg, msgbuf, bufsize);
+            format++;
+            if (addcleanup(p, freelist, 1)) {
+                return converterr(
+                    "(cleanup problem)",
+                    arg, msgbuf, bufsize);
+            }
+            break;
+        }
+        count = convertbuffer(arg, p, &buf);
+        if (count < 0)
+            return converterr(buf, arg, msgbuf, bufsize);
+        if (*format == '#') {
+            FETCH_SIZE;
+            STORE_SIZE(count);
+            format++;
+        } else {
+            if (strlen(*p) != count)
+                return converterr(
+                    "bytes without null bytes",
+                    arg, msgbuf, bufsize);
+        }
+        break;
+    }
+
+    case 's': /* text string */
+    case 'z': /* text string or None */
+    {
+        if (*format == '*') {
+            /* "s*" or "z*" */
             Py_buffer *p = (Py_buffer *)va_arg(*p_va, Py_buffer *);
 
-            if (PyString_Check(arg)) {
-                PyBuffer_FillInfo(p, arg,
-                                  PyString_AS_STRING(arg), PyString_GET_SIZE(arg),
-                                  1, 0);
-            }
-#ifdef Py_USING_UNICODE
+            if (c == 'z' && arg == Py_None)
+                PyBuffer_FillInfo(p, NULL, NULL, 0, 1, 0);
             else if (PyUnicode_Check(arg)) {
                 uarg = UNICODE_DEFAULT_ENCODING(arg);
                 if (uarg == NULL)
                     return converterr(CONV_UNICODE,
                                       arg, msgbuf, bufsize);
                 PyBuffer_FillInfo(p, arg,
-                                  PyString_AS_STRING(uarg), PyString_GET_SIZE(uarg),
+                                  PyBytes_AS_STRING(uarg), PyBytes_GET_SIZE(uarg),
                                   1, 0);
             }
-#endif
             else { /* any buffer-like object */
                 char *buf;
                 if (getbuffer(arg, p, &buf) < 0)
                     return converterr(buf, arg, msgbuf, bufsize);
             }
-            if (addcleanup(p, freelist, cleanup_buffer)) {
+            if (addcleanup(p, freelist, 1)) {
                 return converterr(
                     "(cleanup problem)",
                     arg, msgbuf, bufsize);
             }
             format++;
-        } else if (*format == '#') {
+        } else if (*format == '#') { /* any buffer-like object */
+            /* "s#" or "z#" */
             void **p = (void **)va_arg(*p_va, char **);
             FETCH_SIZE;
 
-            if (PyString_Check(arg)) {
-                *p = PyString_AS_STRING(arg);
-                STORE_SIZE(PyString_GET_SIZE(arg));
+            if (c == 'z' && arg == Py_None) {
+                *p = NULL;
+                STORE_SIZE(0);
             }
-#ifdef Py_USING_UNICODE
             else if (PyUnicode_Check(arg)) {
                 uarg = UNICODE_DEFAULT_ENCODING(arg);
                 if (uarg == NULL)
                     return converterr(CONV_UNICODE,
                                       arg, msgbuf, bufsize);
-                *p = PyString_AS_STRING(uarg);
-                STORE_SIZE(PyString_GET_SIZE(uarg));
+                *p = PyBytes_AS_STRING(uarg);
+                STORE_SIZE(PyBytes_GET_SIZE(uarg));
             }
-#endif
             else { /* any buffer-like object */
+                /* XXX Really? */
                 char *buf;
                 Py_ssize_t count = convertbuffer(arg, p, &buf);
                 if (count < 0)
@@ -877,125 +927,66 @@
             }
             format++;
         } else {
+            /* "s" or "z" */
             char **p = va_arg(*p_va, char **);
+            uarg = NULL;
 
-            if (PyString_Check(arg))
-                *p = PyString_AS_STRING(arg);
-#ifdef Py_USING_UNICODE
+            if (c == 'z' && arg == Py_None)
+                *p = NULL;
             else if (PyUnicode_Check(arg)) {
                 uarg = UNICODE_DEFAULT_ENCODING(arg);
                 if (uarg == NULL)
                     return converterr(CONV_UNICODE,
                                       arg, msgbuf, bufsize);
-                *p = PyString_AS_STRING(uarg);
+                *p = PyBytes_AS_STRING(uarg);
             }
-#endif
             else
-                return converterr("string", arg, msgbuf, bufsize);
-            if ((Py_ssize_t)strlen(*p) != PyString_Size(arg))
-                return converterr("string without null bytes",
+                return converterr(c == 'z' ? "str or None" : "str",
                                   arg, msgbuf, bufsize);
+            if (*p != NULL && uarg != NULL &&
+                (Py_ssize_t) strlen(*p) != PyBytes_GET_SIZE(uarg))
+                return converterr(
+                    c == 'z' ? "str without null bytes or None"
+                             : "str without null bytes",
+                    arg, msgbuf, bufsize);
         }
         break;
     }
 
-    case 'z': {/* string, may be NULL (None) */
-        if (*format == '*') {
-            Py_buffer *p = (Py_buffer *)va_arg(*p_va, Py_buffer *);
-
-            if (arg == Py_None)
-                PyBuffer_FillInfo(p, NULL, NULL, 0, 1, 0);
-            else if (PyString_Check(arg)) {
-                PyBuffer_FillInfo(p, arg,
-                                  PyString_AS_STRING(arg), PyString_GET_SIZE(arg),
-                                  1, 0);
-            }
-#ifdef Py_USING_UNICODE
-            else if (PyUnicode_Check(arg)) {
-                uarg = UNICODE_DEFAULT_ENCODING(arg);
-                if (uarg == NULL)
-                    return converterr(CONV_UNICODE,
-                                      arg, msgbuf, bufsize);
-                PyBuffer_FillInfo(p, arg,
-                                  PyString_AS_STRING(uarg), PyString_GET_SIZE(uarg),
-                                  1, 0);
-            }
-#endif
-            else { /* any buffer-like object */
-                char *buf;
-                if (getbuffer(arg, p, &buf) < 0)
-                    return converterr(buf, arg, msgbuf, bufsize);
-            }
-            if (addcleanup(p, freelist, cleanup_buffer)) {
-                return converterr(
-                    "(cleanup problem)",
-                    arg, msgbuf, bufsize);
-            }
-            format++;
-        } else if (*format == '#') { /* any buffer-like object */
-            void **p = (void **)va_arg(*p_va, char **);
+    case 'u': /* raw unicode buffer (Py_UNICODE *) */
+    case 'Z': /* raw unicode buffer or None */
+    {
+        if (*format == '#') { /* any buffer-like object */
+            /* "s#" or "Z#" */
+            Py_UNICODE **p = va_arg(*p_va, Py_UNICODE **);
             FETCH_SIZE;
 
-            if (arg == Py_None) {
-                *p = 0;
+            if (c == 'Z' && arg == Py_None) {
+                *p = NULL;
                 STORE_SIZE(0);
             }
-            else if (PyString_Check(arg)) {
-                *p = PyString_AS_STRING(arg);
-                STORE_SIZE(PyString_GET_SIZE(arg));
+            else if (PyUnicode_Check(arg)) {
+                *p = PyUnicode_AS_UNICODE(arg);
+                STORE_SIZE(PyUnicode_GET_SIZE(arg));
             }
-#ifdef Py_USING_UNICODE
-            else if (PyUnicode_Check(arg)) {
-                uarg = UNICODE_DEFAULT_ENCODING(arg);
-                if (uarg == NULL)
-                    return converterr(CONV_UNICODE,
-                                      arg, msgbuf, bufsize);
-                *p = PyString_AS_STRING(uarg);
-                STORE_SIZE(PyString_GET_SIZE(uarg));
-            }
-#endif
-            else { /* any buffer-like object */
-                char *buf;
-                Py_ssize_t count = convertbuffer(arg, p, &buf);
-                if (count < 0)
-                    return converterr(buf, arg, msgbuf, bufsize);
-                STORE_SIZE(count);
-            }
+            else
+                return converterr("str or None", arg, msgbuf, bufsize);
             format++;
         } else {
-            char **p = va_arg(*p_va, char **);
+            /* "s" or "Z" */
+            Py_UNICODE **p = va_arg(*p_va, Py_UNICODE **);
 
-            if (arg == Py_None)
-                *p = 0;
-            else if (PyString_Check(arg))
-                *p = PyString_AS_STRING(arg);
-#ifdef Py_USING_UNICODE
+            if (c == 'Z' && arg == Py_None)
+                *p = NULL;
             else if (PyUnicode_Check(arg)) {
-                uarg = UNICODE_DEFAULT_ENCODING(arg);
-                if (uarg == NULL)
-                    return converterr(CONV_UNICODE,
-                                      arg, msgbuf, bufsize);
-                *p = PyString_AS_STRING(uarg);
-            }
-#endif
-            else
-                return converterr("string or None",
+                *p = PyUnicode_AS_UNICODE(arg);
+                if (Py_UNICODE_strlen(*p) != PyUnicode_GET_SIZE(arg))
+                    return converterr(
+                        "str without null character or None",
+                        arg, msgbuf, bufsize);
+            } else
+                return converterr(c == 'Z' ? "str or None" : "str",
                                   arg, msgbuf, bufsize);
-            if (*format == '#') {
-                FETCH_SIZE;
-                assert(0); /* XXX redundant with if-case */
-                if (arg == Py_None) {
-                    STORE_SIZE(0);
-                } else {
-                    STORE_SIZE(PyString_Size(arg));
-                }
-                format++;
-            }
-            else if (*p != NULL &&
-                     (Py_ssize_t)strlen(*p) != PyString_Size(arg))
-                return converterr(
-                    "string without null bytes or None",
-                    arg, msgbuf, bufsize);
         }
         break;
     }
@@ -1004,15 +995,14 @@
         char **buffer;
         const char *encoding;
         PyObject *s;
+        int recode_strings;
         Py_ssize_t size;
-        int recode_strings;
+        const char *ptr;
 
         /* Get 'e' parameter: the encoding name */
         encoding = (const char *)va_arg(*p_va, const char *);
-#ifdef Py_USING_UNICODE
         if (encoding == NULL)
             encoding = PyUnicode_GetDefaultEncoding();
-#endif
 
         /* Get output buffer parameter:
            's' (recode all objects via Unicode) or
@@ -1033,12 +1023,15 @@
                               arg, msgbuf, bufsize);
 
         /* Encode object */
-        if (!recode_strings && PyString_Check(arg)) {
+        if (!recode_strings &&
+            (PyBytes_Check(arg) || PyByteArray_Check(arg))) {
             s = arg;
             Py_INCREF(s);
+            if (PyObject_AsCharBuffer(s, &ptr, &size) < 0)
+                return converterr("(AsCharBuffer failed)",
+                                  arg, msgbuf, bufsize);
         }
         else {
-#ifdef Py_USING_UNICODE
             PyObject *u;
 
             /* Convert object to Unicode */
@@ -1056,17 +1049,17 @@
             if (s == NULL)
                 return converterr("(encoding failed)",
                                   arg, msgbuf, bufsize);
-            if (!PyString_Check(s)) {
+            if (!PyBytes_Check(s)) {
                 Py_DECREF(s);
                 return converterr(
-                    "(encoder failed to return a string)",
+                    "(encoder failed to return bytes)",
                     arg, msgbuf, bufsize);
             }
-#else
-            return converterr("string<e>", arg, msgbuf, bufsize);
-#endif
+            size = PyBytes_GET_SIZE(s);
+            ptr = PyBytes_AS_STRING(s);
+            if (ptr == NULL)
+                ptr = "";
         }
-        size = PyString_GET_SIZE(s);
 
         /* Write output; output is guaranteed to be 0-terminated */
         if (*format == '#') {
@@ -1104,11 +1097,10 @@
                 *buffer = PyMem_NEW(char, size + 1);
                 if (*buffer == NULL) {
                     Py_DECREF(s);
-                    return converterr(
-                        "(memory error)",
-                        arg, msgbuf, bufsize);
+                    PyErr_NoMemory();
+                    RETURN_ERR_OCCURRED;
                 }
-                if (addcleanup(*buffer, freelist, cleanup_ptr)) {
+                if (addcleanup(*buffer, freelist, 0)) {
                     Py_DECREF(s);
                     return converterr(
                         "(cleanup problem)",
@@ -1122,9 +1114,7 @@
                         arg, msgbuf, bufsize);
                 }
             }
-            memcpy(*buffer,
-                   PyString_AS_STRING(s),
-                   size + 1);
+            memcpy(*buffer, ptr, size+1);
             STORE_SIZE(size);
         } else {
             /* Using a 0-terminated buffer:
@@ -1140,8 +1130,7 @@
                PyMem_Free()ing it after usage
 
             */
-            if ((Py_ssize_t)strlen(PyString_AS_STRING(s))
-                                                    != size) {
+            if ((Py_ssize_t)strlen(ptr) != size) {
                 Py_DECREF(s);
                 return converterr(
                     "encoded string without NULL bytes",
@@ -1150,66 +1139,46 @@
             *buffer = PyMem_NEW(char, size + 1);
             if (*buffer == NULL) {
                 Py_DECREF(s);
-                return converterr("(memory error)",
-                                  arg, msgbuf, bufsize);
+                PyErr_NoMemory();
+                RETURN_ERR_OCCURRED;
             }
-            if (addcleanup(*buffer, freelist, cleanup_ptr)) {
+            if (addcleanup(*buffer, freelist, 0)) {
                 Py_DECREF(s);
                 return converterr("(cleanup problem)",
                                 arg, msgbuf, bufsize);
             }
-            memcpy(*buffer,
-                   PyString_AS_STRING(s),
-                   size + 1);
+            memcpy(*buffer, ptr, size+1);
         }
         Py_DECREF(s);
         break;
     }
 
-#ifdef Py_USING_UNICODE
-    case 'u': {/* raw unicode buffer (Py_UNICODE *) */
-        if (*format == '#') { /* any buffer-like object */
-            void **p = (void **)va_arg(*p_va, char **);
-            FETCH_SIZE;
-            if (PyUnicode_Check(arg)) {
-                *p = PyUnicode_AS_UNICODE(arg);
-                STORE_SIZE(PyUnicode_GET_SIZE(arg));
-            }
-            else {
-                return converterr("cannot convert raw buffers",
-                                  arg, msgbuf, bufsize);
-            }
-            format++;
-        } else {
-            Py_UNICODE **p = va_arg(*p_va, Py_UNICODE **);
-            if (PyUnicode_Check(arg))
-                *p = PyUnicode_AS_UNICODE(arg);
-            else
-                return converterr("unicode", arg, msgbuf, bufsize);
-        }
-        break;
-    }
-#endif
-
-    case 'S': { /* string object */
+    case 'S': { /* PyBytes object */
         PyObject **p = va_arg(*p_va, PyObject **);
-        if (PyString_Check(arg))
+        if (PyBytes_Check(arg))
             *p = arg;
         else
-            return converterr("string", arg, msgbuf, bufsize);
+            return converterr("bytes", arg, msgbuf, bufsize);
         break;
     }
 
-#ifdef Py_USING_UNICODE
-    case 'U': { /* Unicode object */
+    case 'Y': { /* PyByteArray object */
+        PyObject **p = va_arg(*p_va, PyObject **);
+        if (PyByteArray_Check(arg))
+            *p = arg;
+        else
+            return converterr("bytearray", arg, msgbuf, bufsize);
+        break;
+    }
+
+    case 'U': { /* PyUnicode object */
         PyObject **p = va_arg(*p_va, PyObject **);
         if (PyUnicode_Check(arg))
             *p = arg;
         else
-            return converterr("unicode", arg, msgbuf, bufsize);
+            return converterr("str", arg, msgbuf, bufsize);
         break;
     }
-#endif
 
     case 'O': { /* object */
         PyTypeObject *type;
@@ -1224,25 +1193,19 @@
                 return converterr(type->tp_name, arg, msgbuf, bufsize);
 
         }
-        else if (*format == '?') {
-            inquiry pred = va_arg(*p_va, inquiry);
-            p = va_arg(*p_va, PyObject **);
-            format++;
-            if ((*pred)(arg))
-                *p = arg;
-            else
-                return converterr("(unspecified)",
-                                  arg, msgbuf, bufsize);
-
-        }
         else if (*format == '&') {
             typedef int (*converter)(PyObject *, void *);
             converter convert = va_arg(*p_va, converter);
             void *addr = va_arg(*p_va, void *);
+            int res;
             format++;
-            if (! (*convert)(arg, addr))
+            if (! (res = (*convert)(arg, addr)))
                 return converterr("(unspecified)",
                                   arg, msgbuf, bufsize);
+            if (res == Py_CLEANUP_SUPPORTED &&
+                addcleanup_convert(addr, freelist, convert) == -1)
+                return converterr("(cleanup problem)",
+                                arg, msgbuf, bufsize);
         }
         else {
             p = va_arg(*p_va, PyObject **);
@@ -1252,92 +1215,29 @@
     }
 
 
-    case 'w': { /* memory buffer, read-write access */
+    case 'w': { /* "w*": memory buffer, read-write access */
         void **p = va_arg(*p_va, void **);
-        void *res;
-        PyBufferProcs *pb = arg->ob_type->tp_as_buffer;
-        Py_ssize_t count;
 
-        if (pb && pb->bf_releasebuffer && *format != '*')
-            /* Buffer must be released, yet caller does not use
-               the Py_buffer protocol. */
-            return converterr("pinned buffer", arg, msgbuf, bufsize);
+        if (*format != '*')
+            return converterr(
+                "invalid use of 'w' format character",
+                arg, msgbuf, bufsize);
+        format++;
 
-        if (pb && pb->bf_getbuffer && *format == '*') {
-            /* Caller is interested in Py_buffer, and the object
-               supports it directly. */
-            format++;
-            if (pb->bf_getbuffer(arg, (Py_buffer*)p, PyBUF_WRITABLE) < 0) {
-                PyErr_Clear();
-                return converterr("read-write buffer", arg, msgbuf, bufsize);
-            }
-            if (addcleanup(p, freelist, cleanup_buffer)) {
-                return converterr(
-                    "(cleanup problem)",
-                    arg, msgbuf, bufsize);
-            }
-            if (!PyBuffer_IsContiguous((Py_buffer*)p, 'C'))
-                return converterr("contiguous buffer", arg, msgbuf, bufsize);
-            break;
+        /* Caller is interested in Py_buffer, and the object
+           supports it directly. */
+        if (PyObject_GetBuffer(arg, (Py_buffer*)p, PyBUF_WRITABLE) < 0) {
+            PyErr_Clear();
+            return converterr("read-write buffer", arg, msgbuf, bufsize);
         }
-
-        if (pb == NULL ||
-            pb->bf_getwritebuffer == NULL ||
-            pb->bf_getsegcount == NULL)
-            return converterr("read-write buffer", arg, msgbuf, bufsize);
-        if ((*pb->bf_getsegcount)(arg, NULL) != 1)
-            return converterr("single-segment read-write buffer",
-                              arg, msgbuf, bufsize);
-        if ((count = pb->bf_getwritebuffer(arg, 0, &res)) < 0)
-            return converterr("(unspecified)", arg, msgbuf, bufsize);
-        if (*format == '*') {
-            PyBuffer_FillInfo((Py_buffer*)p, arg, res, count, 1, 0);
-            format++;
+        if (!PyBuffer_IsContiguous((Py_buffer*)p, 'C')) {
+            PyBuffer_Release((Py_buffer*)p);
+            return converterr("contiguous buffer", arg, msgbuf, bufsize);
         }
-        else {
-            *p = res;
-            if (*format == '#') {
-                FETCH_SIZE;
-                STORE_SIZE(count);
-                format++;
-            }
-        }
-        break;
-    }
-
-    case 't': { /* 8-bit character buffer, read-only access */
-        char **p = va_arg(*p_va, char **);
-        PyBufferProcs *pb = arg->ob_type->tp_as_buffer;
-        Py_ssize_t count;
-
-        if (*format++ != '#')
+        if (addcleanup(p, freelist, 1)) {
             return converterr(
-                "invalid use of 't' format character",
+                "(cleanup problem)",
                 arg, msgbuf, bufsize);
-        if (!PyType_HasFeature(arg->ob_type,
-                               Py_TPFLAGS_HAVE_GETCHARBUFFER) ||
-            pb == NULL || pb->bf_getcharbuffer == NULL ||
-            pb->bf_getsegcount == NULL)
-            return converterr(
-                "string or read-only character buffer",
-                arg, msgbuf, bufsize);
-
-        if (pb->bf_getsegcount(arg, NULL) != 1)
-            return converterr(
-                "string or single-segment read-only buffer",
-                arg, msgbuf, bufsize);
-
-        if (pb->bf_releasebuffer)
-            return converterr(
-                "string or pinned buffer",
-                arg, msgbuf, bufsize);
-
-        count = pb->bf_getcharbuffer(arg, 0, p);
-        if (count < 0)
-            return converterr("(unspecified)", arg, msgbuf, bufsize);
-        {
-            FETCH_SIZE;
-            STORE_SIZE(count);
         }
         break;
     }
@@ -1349,58 +1249,47 @@
 
     *p_format = format;
     return NULL;
+
+#undef FETCH_SIZE
+#undef STORE_SIZE
+#undef BUFFER_LEN
+#undef RETURN_ERR_OCCURRED
 }
 
 static Py_ssize_t
 convertbuffer(PyObject *arg, void **p, char **errmsg)
 {
-    PyBufferProcs *pb = arg->ob_type->tp_as_buffer;
+    PyBufferProcs *pb = Py_TYPE(arg)->tp_as_buffer;
     Py_ssize_t count;
-    if (pb == NULL ||
-        pb->bf_getreadbuffer == NULL ||
-        pb->bf_getsegcount == NULL ||
-        pb->bf_releasebuffer != NULL) {
-        *errmsg = "string or read-only buffer";
+    Py_buffer view;
+
+    *errmsg = NULL;
+    *p = NULL;
+    if (pb != NULL && pb->bf_releasebuffer != NULL) {
+        *errmsg = "read-only pinned buffer";
         return -1;
     }
-    if ((*pb->bf_getsegcount)(arg, NULL) != 1) {
-        *errmsg = "string or single-segment read-only buffer";
+
+    if (getbuffer(arg, &view, errmsg) < 0)
         return -1;
-    }
-    if ((count = (*pb->bf_getreadbuffer)(arg, 0, p)) < 0) {
-        *errmsg = "(unspecified)";
-    }
+    count = view.len;
+    *p = view.buf;
+    PyBuffer_Release(&view);
     return count;
 }
 
 static int
 getbuffer(PyObject *arg, Py_buffer *view, char **errmsg)
 {
-    void *buf;
-    Py_ssize_t count;
-    PyBufferProcs *pb = arg->ob_type->tp_as_buffer;
-    if (pb == NULL) {
-        *errmsg = "string or buffer";
+    if (PyObject_GetBuffer(arg, view, PyBUF_SIMPLE) != 0) {
+        *errmsg = "bytes or buffer";
         return -1;
     }
-    if (pb->bf_getbuffer) {
-        if (pb->bf_getbuffer(arg, view, 0) < 0) {
-            *errmsg = "convertible to a buffer";
-            return -1;
-        }
-        if (!PyBuffer_IsContiguous(view, 'C')) {
-            *errmsg = "contiguous buffer";
-            return -1;
-        }
-        return 0;
+    if (!PyBuffer_IsContiguous(view, 'C')) {
+        PyBuffer_Release(view);
+        *errmsg = "contiguous buffer";
+        return -1;
     }
-
-    count = convertbuffer(arg, &buf, errmsg);
-    if (count < 0) {
-        *errmsg = "convertible to a buffer";
-        return count;
-    }
-    PyBuffer_FillInfo(view, arg, buf, count, 1, 0);
     return 0;
 }
 
@@ -1476,15 +1365,7 @@
         return 0;
     }
 
-#ifdef VA_LIST_IS_ARRAY
-    memcpy(lva, va, sizeof(va_list));
-#else
-#ifdef __va_copy
-    __va_copy(lva, va);
-#else
-    lva = va;
-#endif
-#endif
+        Py_VA_COPY(lva, va);
 
     retval = vgetargskeywords(args, keywords, format, kwlist, &lva, 0);
     return retval;
@@ -1508,21 +1389,28 @@
         return 0;
     }
 
-#ifdef VA_LIST_IS_ARRAY
-    memcpy(lva, va, sizeof(va_list));
-#else
-#ifdef __va_copy
-    __va_copy(lva, va);
-#else
-    lva = va;
-#endif
-#endif
+        Py_VA_COPY(lva, va);
 
     retval = vgetargskeywords(args, keywords, format,
                               kwlist, &lva, FLAG_SIZE_T);
     return retval;
 }
 
+int
+PyArg_ValidateKeywordArguments(PyObject *kwargs)
+{
+    if (!PyDict_Check(kwargs)) {
+        PyErr_BadInternalCall();
+        return 0;
+    }
+    if (!_PyDict_HasOnlyStringKeys(kwargs)) {
+        PyErr_SetString(PyExc_TypeError,
+                        "keyword arguments must be strings");
+        return 0;
+    }
+    return 1;
+}
+
 #define IS_END_OF_FORMAT(c) (c == '\0' || c == ';' || c == ':')
 
 static int
@@ -1651,23 +1539,26 @@
         while (PyDict_Next(keywords, &pos, &key, &value)) {
             int match = 0;
             char *ks;
-            if (!PyString_Check(key)) {
+            if (!PyUnicode_Check(key)) {
                 PyErr_SetString(PyExc_TypeError,
                                 "keywords must be strings");
                 return cleanreturn(0, freelist);
             }
-            ks = PyString_AsString(key);
-            for (i = 0; i < len; i++) {
-                if (!strcmp(ks, kwlist[i])) {
-                    match = 1;
-                    break;
+            /* check that _PyUnicode_AsString() result is not NULL */
+            ks = _PyUnicode_AsString(key);
+            if (ks != NULL) {
+                for (i = 0; i < len; i++) {
+                    if (!strcmp(ks, kwlist[i])) {
+                        match = 1;
+                        break;
+                    }
                 }
             }
             if (!match) {
                 PyErr_Format(PyExc_TypeError,
-                             "'%s' is an invalid keyword "
+                             "'%U' is an invalid keyword "
                              "argument for this function",
-                             ks);
+                             key);
                 return cleanreturn(0, freelist);
             }
         }
@@ -1702,10 +1593,9 @@
 #endif
     case 'f': /* float */
     case 'd': /* double */
-#ifndef WITHOUT_COMPLEX
     case 'D': /* complex double */
-#endif
     case 'c': /* char */
+    case 'C': /* unicode char */
         {
             (void) va_arg(*p_va, void *);
             break;
@@ -1731,10 +1621,8 @@
 
     case 's': /* string */
     case 'z': /* string or None */
-#ifdef Py_USING_UNICODE
+    case 'y': /* bytes */
     case 'u': /* unicode string */
-#endif
-    case 't': /* buffer, read-only */
     case 'w': /* buffer, read-write */
         {
             (void) va_arg(*p_va, char **);
@@ -1744,7 +1632,7 @@
                 else
                     (void) va_arg(*p_va, int *);
                 format++;
-            } else if ((c == 's' || c == 'z') && *format == '*') {
+            } else if ((c == 's' || c == 'z' || c == 'y') && *format == '*') {
                 format++;
             }
             break;
@@ -1753,9 +1641,8 @@
     /* object codes */
 
     case 'S': /* string object */
-#ifdef Py_USING_UNICODE
+    case 'Y': /* string object */
     case 'U': /* unicode string object */
-#endif
         {
             (void) va_arg(*p_va, PyObject **);
             break;
diff --git a/pypy/module/cpyext/src/modsupport.c b/pypy/module/cpyext/src/modsupport.c
--- a/pypy/module/cpyext/src/modsupport.c
+++ b/pypy/module/cpyext/src/modsupport.c
@@ -11,23 +11,6 @@
 /* Package context -- the full module name for package imports */
 char *_Py_PackageContext = NULL;
 
-/* Py_InitModule4() parameters:
-   - name is the module name
-   - methods is the list of top-level functions
-   - doc is the documentation string
-   - passthrough is passed as self to functions defined in the module
-   - api_version is the value of PYTHON_API_VERSION at the time the
-     module was compiled
-
-   Return value is a borrowed reference to the module object; or NULL
-   if an error occurred (in Python 1.4 and before, errors were fatal).
-   Errors may still leak memory.
-*/
-
-static char api_version_warning[] =
-"Python C API version mismatch for module %.100s:\
- This Python has API version %d, module %.100s has version %d.";
-
 /* Helper for mkvalue() to scan the length of a format */
 
 static int
@@ -165,7 +148,6 @@
     return v;
 }
 
-#ifdef Py_USING_UNICODE
 static int
 _ustrlen(Py_UNICODE *u)
 {
@@ -174,7 +156,6 @@
     while (*v != 0) { i++; v++; }
     return i;
 }
-#endif
 
 static PyObject *
 do_mktuple(const char **p_format, va_list *p_va, int endchar, int n, int flags)
@@ -234,37 +215,31 @@
         case 'B':
         case 'h':
         case 'i':
-            return PyInt_FromLong((long)va_arg(*p_va, int));
+            return PyLong_FromLong((long)va_arg(*p_va, int));
 
         case 'H':
-            return PyInt_FromLong((long)va_arg(*p_va, unsigned int));
+            return PyLong_FromLong((long)va_arg(*p_va, unsigned int));
 
         case 'I':
         {
             unsigned int n;
             n = va_arg(*p_va, unsigned int);
-            if (n > (unsigned long)PyInt_GetMax())
-                return PyLong_FromUnsignedLong((unsigned long)n);
-            else
-                return PyInt_FromLong(n);
+            return PyLong_FromUnsignedLong(n);
         }
 
         case 'n':
 #if SIZEOF_SIZE_T!=SIZEOF_LONG
-            return PyInt_FromSsize_t(va_arg(*p_va, Py_ssize_t));
+            return PyLong_FromSsize_t(va_arg(*p_va, Py_ssize_t));
 #endif
             /* Fall through from 'n' to 'l' if Py_ssize_t is long */
         case 'l':
-            return PyInt_FromLong(va_arg(*p_va, long));
+            return PyLong_FromLong(va_arg(*p_va, long));
 
         case 'k':
         {
             unsigned long n;
             n = va_arg(*p_va, unsigned long);
-            if (n > (unsigned long)PyInt_GetMax())
-                return PyLong_FromUnsignedLong(n);
-            else
-                return PyInt_FromLong(n);
+            return PyLong_FromUnsignedLong(n);
         }
 
 #ifdef HAVE_LONG_LONG
@@ -274,7 +249,6 @@
         case 'K':
             return PyLong_FromUnsignedLongLong((PY_LONG_LONG)va_arg(*p_va, unsigned PY_LONG_LONG));
 #endif
-#ifdef Py_USING_UNICODE
         case 'u':
         {
             PyObject *v;
@@ -300,27 +274,35 @@
             }
             return v;
         }
-#endif
         case 'f':
         case 'd':
             return PyFloat_FromDouble(
                 (double)va_arg(*p_va, va_double));
 
-#ifndef WITHOUT_COMPLEX
         case 'D':
             return PyComplex_FromCComplex(
                 *((Py_complex *)va_arg(*p_va, Py_complex *)));
-#endif /* WITHOUT_COMPLEX */
 
         case 'c':
         {
             char p[1];
             p[0] = (char)va_arg(*p_va, int);
-            return PyString_FromStringAndSize(p, 1);
+            return PyBytes_FromStringAndSize(p, 1);
+        }
+        case 'C':
+        {
+            int i = va_arg(*p_va, int);
+            if (i < 0 || i > PyUnicode_GetMax()) {
+                PyErr_SetString(PyExc_OverflowError,
+                                "%c arg not in range(0x110000)");
+                return NULL;
+            }
+            return PyUnicode_FromOrdinal(i);
         }
 
         case 's':
         case 'z':
+        case 'U':   /* XXX deprecated alias */
         {
             PyObject *v;
             char *str = va_arg(*p_va, char *);
@@ -348,7 +330,40 @@
                     }
                     n = (Py_ssize_t)m;
                 }
-                v = PyString_FromStringAndSize(str, n);
+                v = PyUnicode_FromStringAndSize(str, n);
+            }
+            return v;
+        }
+
+        case 'y':
+        {
+            PyObject *v;
+            char *str = va_arg(*p_va, char *);
+            Py_ssize_t n;
+            if (**p_format == '#') {
+                ++*p_format;
+                if (flags & FLAG_SIZE_T)
+                    n = va_arg(*p_va, Py_ssize_t);
+                else
+                    n = va_arg(*p_va, int);
+            }
+            else
+                n = -1;
+            if (str == NULL) {
+                v = Py_None;
+                Py_INCREF(v);
+            }
+            else {
+                if (n < 0) {
+                    size_t m = strlen(str);
+                    if (m > PY_SSIZE_T_MAX) {
+                        PyErr_SetString(PyExc_OverflowError,
+                            "string too long for Python bytes");
+                        return NULL;
+                    }
+                    n = (Py_ssize_t)m;
+                }
+                v = PyBytes_FromStringAndSize(str, n);
             }
             return v;
         }
@@ -441,15 +456,7 @@
     int n = countformat(f, '\0');
     va_list lva;
 
-#ifdef VA_LIST_IS_ARRAY
-    memcpy(lva, va, sizeof(va_list));
-#else
-#ifdef __va_copy
-    __va_copy(lva, va);
-#else
-    lva = va;
-#endif
-#endif
+        Py_VA_COPY(lva, va);
 
     if (n < 0)
         return NULL;
@@ -564,7 +571,7 @@
 PyModule_AddIntConstant(PyObject *m, const char *name, long value)
 {
     int result;
-    PyObject *o = PyInt_FromLong(value);
+    PyObject *o = PyLong_FromLong(value);
     if (!o)
         return -1;
     result = _PyModule_AddObject_NoConsumeRef(m, name, o);
@@ -576,7 +583,7 @@
 PyModule_AddStringConstant(PyObject *m, const char *name, const char *value)
 {
     int result;
-    PyObject *o = PyString_FromString(value);
+    PyObject *o = PyUnicode_FromString(value);
     if (!o)
         return -1;
     result = _PyModule_AddObject_NoConsumeRef(m, name, o);
diff --git a/pypy/module/cpyext/src/mysnprintf.c b/pypy/module/cpyext/src/mysnprintf.c
--- a/pypy/module/cpyext/src/mysnprintf.c
+++ b/pypy/module/cpyext/src/mysnprintf.c
@@ -1,5 +1,4 @@
 #include "Python.h"
-#include <ctype.h>
 
 /* snprintf() wrappers.  If the platform has vsnprintf, we use it, else we
    emulate it in a half-hearted way.  Even if the platform has it, we wrap
diff --git a/pypy/module/cpyext/src/pyerrors.c b/pypy/module/cpyext/src/pyerrors.c
--- a/pypy/module/cpyext/src/pyerrors.c
+++ b/pypy/module/cpyext/src/pyerrors.c
@@ -25,7 +25,7 @@
 PyObject *
 PyErr_NewException(const char *name, PyObject *base, PyObject *dict)
 {
-    char *dot;
+    const char *dot;
     PyObject *modulename = NULL;
     PyObject *classname = NULL;
     PyObject *mydict = NULL;
diff --git a/pypy/module/cpyext/src/pysignals.c b/pypy/module/cpyext/src/pysignals.c
--- a/pypy/module/cpyext/src/pysignals.c
+++ b/pypy/module/cpyext/src/pysignals.c
@@ -48,6 +48,11 @@
 #endif
 }
 
+/*
+ * All of the code in this function must only use async-signal-safe functions,
+ * listed at `man 7 signal` or
+ * http://www.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_04.html.
+ */
 PyOS_sighandler_t
 PyOS_setsig(int sig, PyOS_sighandler_t handler)
 {
diff --git a/pypy/module/cpyext/src/pythonrun.c b/pypy/module/cpyext/src/pythonrun.c
--- a/pypy/module/cpyext/src/pythonrun.c
+++ b/pypy/module/cpyext/src/pythonrun.c
@@ -11,7 +11,9 @@
 {
     fprintf(stderr, "Fatal Python error: %s\n", msg);
     fflush(stderr); /* it helps in Windows debug build */
-
+    if (PyErr_Occurred()) {
+        PyErr_PrintEx(0);
+    }
 #ifdef MS_WINDOWS
     {
         size_t len = strlen(msg);
diff --git a/pypy/module/cpyext/src/structseq.c b/pypy/module/cpyext/src/structseq.c
--- a/pypy/module/cpyext/src/structseq.c
+++ b/pypy/module/cpyext/src/structseq.c
@@ -14,14 +14,14 @@
 char *PyStructSequence_UnnamedField = "unnamed field";
 
 #define VISIBLE_SIZE(op) Py_SIZE(op)
-#define VISIBLE_SIZE_TP(tp) PyInt_AsLong( \
+#define VISIBLE_SIZE_TP(tp) PyLong_AsLong( \
                       PyDict_GetItemString((tp)->tp_dict, visible_length_key))
 
-#define REAL_SIZE_TP(tp) PyInt_AsLong( \
+#define REAL_SIZE_TP(tp) PyLong_AsLong( \
                       PyDict_GetItemString((tp)->tp_dict, real_length_key))
 #define REAL_SIZE(op) REAL_SIZE_TP(Py_TYPE(op))
 
-#define UNNAMED_FIELDS_TP(tp) PyInt_AsLong( \
+#define UNNAMED_FIELDS_TP(tp) PyLong_AsLong( \
                       PyDict_GetItemString((tp)->tp_dict, unnamed_fields_key))
 #define UNNAMED_FIELDS(op) UNNAMED_FIELDS_TP(Py_TYPE(op))
 
@@ -30,113 +30,42 @@
 PyStructSequence_New(PyTypeObject *type)
 {
     PyStructSequence *obj;
+    Py_ssize_t size = REAL_SIZE_TP(type), i;
 
-    obj = PyObject_New(PyStructSequence, type);
+    obj = PyObject_GC_NewVar(PyStructSequence, type, size);
     if (obj == NULL)
         return NULL;
+    /* Hack the size of the variable object, so invisible fields don't appear
+     to Python code. */
     Py_SIZE(obj) = VISIBLE_SIZE_TP(type);
+    for (i = 0; i < size; i++)
+        obj->ob_item[i] = NULL;
 
-    return (PyObject*) obj;
+    return (PyObject*)obj;
+}
+
+void
+PyStructSequence_SetItem(PyObject* op, Py_ssize_t i, PyObject* v)
+{
+    PyStructSequence_SET_ITEM(op, i, v);
+}
+
+PyObject*
+PyStructSequence_GetItem(PyObject* op, Py_ssize_t i)
+{
+    return PyStructSequence_GET_ITEM(op, i);
 }
 
 static void
 structseq_dealloc(PyStructSequence *obj)
 {
     Py_ssize_t i, size;
-
+    
     size = REAL_SIZE(obj);
     for (i = 0; i < size; ++i) {
         Py_XDECREF(obj->ob_item[i]);
     }
-    PyObject_Del(obj);
-}
-
-static Py_ssize_t
-structseq_length(PyStructSequence *obj)
-{
-    return VISIBLE_SIZE(obj);
-}
-
-static PyObject*
-structseq_item(PyStructSequence *obj, Py_ssize_t i)
-{
-    if (i < 0 || i >= VISIBLE_SIZE(obj)) {
-        PyErr_SetString(PyExc_IndexError, "tuple index out of range");
-        return NULL;
-    }
-    Py_INCREF(obj->ob_item[i]);
-    return obj->ob_item[i];
-}
-
-static PyObject*
-structseq_slice(PyStructSequence *obj, Py_ssize_t low, Py_ssize_t high)
-{
-    PyTupleObject *np;
-    Py_ssize_t i;
-
-    if (low < 0)
-        low = 0;
-    if (high > VISIBLE_SIZE(obj))
-        high = VISIBLE_SIZE(obj);
-    if (high < low)
-        high = low;
-    np = (PyTupleObject *)PyTuple_New(high-low);
-    if (np == NULL)
-        return NULL;
-    for(i = low; i < high; ++i) {
-        PyObject *v = obj->ob_item[i];
-        Py_INCREF(v);
-        PyTuple_SET_ITEM(np, i-low, v);
-    }
-    return (PyObject *) np;
-}
-
-static PyObject *
-structseq_subscript(PyStructSequence *self, PyObject *item)
-{
-    if (PyIndex_Check(item)) {
-        Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
-        if (i == -1 && PyErr_Occurred())
-            return NULL;
-
-        if (i < 0)
-            i += VISIBLE_SIZE(self);
-
-        if (i < 0 || i >= VISIBLE_SIZE(self)) {
-            PyErr_SetString(PyExc_IndexError,
-                "tuple index out of range");
-            return NULL;
-        }
-        Py_INCREF(self->ob_item[i]);
-        return self->ob_item[i];
-    }
-    else if (PySlice_Check(item)) {
-        Py_ssize_t start, stop, step, slicelen, cur, i;
-        PyObject *result;
-
-        if (PySlice_GetIndicesEx((PySliceObject *)item,
-                                 VISIBLE_SIZE(self), &start, &stop,
-                                 &step, &slicelen) < 0) {
-            return NULL;
-        }
-        if (slicelen <= 0)
-            return PyTuple_New(0);
-        result = PyTuple_New(slicelen);
-        if (result == NULL)
-            return NULL;
-        for (cur = start, i = 0; i < slicelen;
-             cur += step, i++) {
-            PyObject *v = self->ob_item[cur];
-            Py_INCREF(v);
-            PyTuple_SET_ITEM(result, i, v);
-        }
-        return result;
-    }
-    else {
-        PyErr_SetString(PyExc_TypeError,
-                        "structseq index must be integer");
-        return NULL;
-    }
+    PyObject_GC_Del(obj);
 }
 
 static PyObject *
@@ -175,33 +104,32 @@
     if (min_len != max_len) {
         if (len < min_len) {
             PyErr_Format(PyExc_TypeError,
-                "%.500s() takes an at least %zd-sequence (%zd-sequence given)",
-                type->tp_name, min_len, len);
-            Py_DECREF(arg);
-            return NULL;
+           "%.500s() takes an at least %zd-sequence (%zd-sequence given)",
+                                 type->tp_name, min_len, len);
+                    Py_DECREF(arg);
+                    return NULL;
         }
 
         if (len > max_len) {
             PyErr_Format(PyExc_TypeError,
-                         "%.500s() takes an at most %zd-sequence (%zd-sequence given)",
-                         type->tp_name, max_len, len);
-            Py_DECREF(arg);
-            return NULL;
+           "%.500s() takes an at most %zd-sequence (%zd-sequence given)",
+                                 type->tp_name, max_len, len);
+                    Py_DECREF(arg);
+                    return NULL;
         }
     }
     else {
         if (len != min_len) {
             PyErr_Format(PyExc_TypeError,
-                         "%.500s() takes a %zd-sequence (%zd-sequence given)",
-                         type->tp_name, min_len, len);
-            Py_DECREF(arg);
-            return NULL;
+           "%.500s() takes a %zd-sequence (%zd-sequence given)",
+                                 type->tp_name, min_len, len);
+                    Py_DECREF(arg);
+                    return NULL;
         }
     }
 
     res = (PyStructSequence*) PyStructSequence_New(type);
     if (res == NULL) {
-        Py_DECREF(arg);
         return NULL;
     }
     for (i = 0; i < len; ++i) {
@@ -224,11 +152,6 @@
     return (PyObject*) res;
 }
 
-static PyObject *
-make_tuple(PyStructSequence *obj)
-{
-    return structseq_slice(obj, 0, VISIBLE_SIZE(obj));
-}
 
 static PyObject *
 structseq_repr(PyStructSequence *obj)
@@ -237,7 +160,6 @@
 #define REPR_BUFFER_SIZE 512
 #define TYPE_MAXSIZE 100
 
-    PyObject *tup;
     PyTypeObject *typ = Py_TYPE(obj);
     int i, removelast = 0;
     Py_ssize_t len;
@@ -247,10 +169,6 @@
     /* pointer to end of writeable buffer; safes space for "...)\0" */
     endofbuf= &buf[REPR_BUFFER_SIZE-5];
 
-    if ((tup = make_tuple(obj)) == NULL) {
-        return NULL;
-    }
-
     /* "typename(", limited to  TYPE_MAXSIZE */
     len = strlen(typ->tp_name) > TYPE_MAXSIZE ? TYPE_MAXSIZE :
                             strlen(typ->tp_name);
@@ -263,19 +181,17 @@
         char *cname, *crepr;
 
         cname = typ->tp_members[i].name;
-
-        val = PyTuple_GetItem(tup, i);
-        if (cname == NULL || val == NULL) {
+        if (cname == NULL) {
+            PyErr_Format(PyExc_SystemError, "In structseq_repr(), member %d name is NULL"
+                         " for type %.500s", i, typ->tp_name);
             return NULL;
         }
+        val = PyStructSequence_GET_ITEM(obj, i);
         repr = PyObject_Repr(val);
-        if (repr == NULL) {
-            Py_DECREF(tup);
+        if (repr == NULL)
             return NULL;
-        }
-        crepr = PyString_AsString(repr);
+        crepr = _PyUnicode_AsString(repr);
         if (crepr == NULL) {
-            Py_DECREF(tup);
             Py_DECREF(repr);
             return NULL;
         }
@@ -301,7 +217,6 @@
             break;
         }
     }
-    Py_DECREF(tup);
     if (removelast) {
         /* overwrite last ", " */
         pbuf-=2;
@@ -309,63 +224,7 @@
     *pbuf++ = ')';
     *pbuf = '\0';
 
-    return PyString_FromString(buf);
-}
-
-static PyObject *
-structseq_concat(PyStructSequence *obj, PyObject *b)
-{
-    PyObject *tup, *result;
-    tup = make_tuple(obj);
-    result = PySequence_Concat(tup, b);
-    Py_DECREF(tup);
-    return result;
-}
-
-static PyObject *
-structseq_repeat(PyStructSequence *obj, Py_ssize_t n)
-{
-    PyObject *tup, *result;
-    tup = make_tuple(obj);
-    result = PySequence_Repeat(tup, n);
-    Py_DECREF(tup);
-    return result;
-}
-
-static int
-structseq_contains(PyStructSequence *obj, PyObject *o)
-{
-    PyObject *tup;
-    int result;
-    tup = make_tuple(obj);
-    if (!tup)
-        return -1;
-    result = PySequence_Contains(tup, o);
-    Py_DECREF(tup);
-    return result;
-}
-
-static long
-structseq_hash(PyObject *obj)
-{
-    PyObject *tup;
-    long result;
-    tup = make_tuple((PyStructSequence*) obj);
-    if (!tup)
-        return -1;
-    result = PyObject_Hash(tup);
-    Py_DECREF(tup);
-    return result;
-}
-
-static PyObject *
-structseq_richcompare(PyObject *obj, PyObject *o2, int op)
-{
-    PyObject *tup, *result;
-    tup = make_tuple((PyStructSequence*) obj);
-    result = PyObject_RichCompare(tup, o2, op);
-    Py_DECREF(tup);
-    return result;
+    return PyUnicode_FromString(buf);
 }
 
 static PyObject *
@@ -410,53 +269,36 @@
     return result;
 }
 
-static PySequenceMethods structseq_as_sequence = {
-    (lenfunc)structseq_length,
-    (binaryfunc)structseq_concat,           /* sq_concat */
-    (ssizeargfunc)structseq_repeat,         /* sq_repeat */
-    (ssizeargfunc)structseq_item,               /* sq_item */
-    (ssizessizeargfunc)structseq_slice,         /* sq_slice */
-    0,                                          /* sq_ass_item */
-    0,                                          /* sq_ass_slice */
-    (objobjproc)structseq_contains,             /* sq_contains */
-};
-
-static PyMappingMethods structseq_as_mapping = {
-    (lenfunc)structseq_length,
-    (binaryfunc)structseq_subscript,
-};
-
 static PyMethodDef structseq_methods[] = {
-    {"__reduce__", (PyCFunction)structseq_reduce,
-     METH_NOARGS, NULL},
+    {"__reduce__", (PyCFunction)structseq_reduce, METH_NOARGS, NULL},
     {NULL, NULL}
 };
 
 static PyTypeObject _struct_sequence_template = {
     PyVarObject_HEAD_INIT(&PyType_Type, 0)
     NULL,                                       /* tp_name */
-    0,                                          /* tp_basicsize */
-    0,                                          /* tp_itemsize */
+    sizeof(PyStructSequence) - sizeof(PyObject *), /* tp_basicsize */
+    sizeof(PyObject *),                         /* tp_itemsize */
     (destructor)structseq_dealloc,              /* tp_dealloc */
     0,                                          /* tp_print */
     0,                                          /* tp_getattr */
     0,                                          /* tp_setattr */
-    0,                                          /* tp_compare */
+    0,                                          /* tp_reserved */
     (reprfunc)structseq_repr,                   /* tp_repr */
     0,                                          /* tp_as_number */
-    &structseq_as_sequence,                     /* tp_as_sequence */
-    &structseq_as_mapping,                      /* tp_as_mapping */
-    structseq_hash,                             /* tp_hash */
+    0,                                          /* tp_as_sequence */
+    0,                                          /* tp_as_mapping */
+    0,                                          /* tp_hash */
     0,                                          /* tp_call */
     0,                                          /* tp_str */
     0,                                          /* tp_getattro */
     0,                                          /* tp_setattro */
     0,                                          /* tp_as_buffer */
-    Py_TPFLAGS_DEFAULT,                     /* tp_flags */
+    Py_TPFLAGS_DEFAULT,                         /* tp_flags */
     NULL,                                       /* tp_doc */
     0,                                          /* tp_traverse */
     0,                                          /* tp_clear */
-    structseq_richcompare,                      /* tp_richcompare */
+    0,                                          /* tp_richcompare */
     0,                                          /* tp_weaklistoffset */
     0,                                          /* tp_iter */
     0,                                          /* tp_iternext */
@@ -483,7 +325,7 @@
 #ifdef Py_TRACE_REFS
     /* if the type object was chained, unchain it first
        before overwriting its storage */
-    if (type->_ob_next) {
+    if (type->ob_base.ob_base._ob_next) {
         _Py_ForgetReference((PyObject*)type);
     }
 #endif
@@ -495,11 +337,9 @@
     n_members = i;
 
     memcpy(type, &_struct_sequence_template, sizeof(PyTypeObject));
+    type->tp_base = &PyTuple_Type;
     type->tp_name = desc->name;
     type->tp_doc = desc->doc;
-    type->tp_basicsize = sizeof(PyStructSequence)+
-        sizeof(PyObject*)*(n_members-1);
-    type->tp_itemsize = 0;
 
     members = PyMem_NEW(PyMemberDef, n_members-n_unnamed_members+1);
     if (members == NULL)
@@ -527,7 +367,7 @@
     dict = type->tp_dict;
 #define SET_DICT_FROM_INT(key, value)                           \
     do {                                                        \
-        PyObject *v = PyInt_FromLong((long) value);             \
+        PyObject *v = PyLong_FromLong((long) value);            \
         if (v != NULL) {                                        \
             PyDict_SetItemString(dict, key, v);                 \
             Py_DECREF(v);                                       \
@@ -538,3 +378,11 @@
     SET_DICT_FROM_INT(real_length_key, n_members);
     SET_DICT_FROM_INT(unnamed_fields_key, n_unnamed_members);
 }
+
+PyTypeObject*
+PyStructSequence_NewType(PyStructSequence_Desc *desc)
+{
+    PyTypeObject *result = (PyTypeObject*)PyType_GenericAlloc(&PyType_Type, 0);
+    PyStructSequence_InitType(result, desc);
+    return result;
+}
diff --git a/pypy/module/cpyext/src/sysmodule.c b/pypy/module/cpyext/src/sysmodule.c
--- a/pypy/module/cpyext/src/sysmodule.c
+++ b/pypy/module/cpyext/src/sysmodule.c
@@ -68,7 +68,7 @@
 
     PyErr_Fetch(&error_type, &error_value, &error_traceback);
     file = PySys_GetObject(name);
-    written = vsnprintf(buffer, sizeof(buffer), format, va);
+    written = PyOS_vsnprintf(buffer, sizeof(buffer), format, va);
     if (sys_pyfile_write(buffer, file) != 0) {
         PyErr_Clear();
         fputs(buffer, fp);
diff --git a/pypy/module/cpyext/src/unicodeobject.c b/pypy/module/cpyext/src/unicodeobject.c
--- a/pypy/module/cpyext/src/unicodeobject.c
+++ b/pypy/module/cpyext/src/unicodeobject.c
@@ -504,6 +504,8 @@
     return NULL;
 }
 
+#undef appendstring
+
 PyObject *
 PyUnicode_FromFormat(const char *format, ...)
 {


More information about the pypy-commit mailing list