[pypy-commit] pypy py3k: The Grand renaming: PyString->PyBytes

amauryfa noreply at buildbot.pypy.org
Thu Nov 22 23:50:09 CET 2012


Author: Amaury Forgeot d'Arc <amauryfa at gmail.com>
Branch: py3k
Changeset: r59059:53ef7831e3c4
Date: 2012-11-22 23:28 +0100
http://bitbucket.org/pypy/pypy/changeset/53ef7831e3c4/

Log:	The Grand renaming: PyString->PyBytes

diff --git a/pypy/module/cpyext/__init__.py b/pypy/module/cpyext/__init__.py
--- a/pypy/module/cpyext/__init__.py
+++ b/pypy/module/cpyext/__init__.py
@@ -36,7 +36,6 @@
 import pypy.module.cpyext.pyerrors
 import pypy.module.cpyext.typeobject
 import pypy.module.cpyext.object
-import pypy.module.cpyext.stringobject
 import pypy.module.cpyext.bytesobject
 import pypy.module.cpyext.tupleobject
 import pypy.module.cpyext.setobject
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
@@ -356,7 +356,6 @@
     'Py_FatalError', 'PyOS_snprintf', 'PyOS_vsnprintf', 'PyArg_Parse',
     'PyArg_ParseTuple', 'PyArg_UnpackTuple', 'PyArg_ParseTupleAndKeywords',
     'PyArg_VaParse', 'PyArg_VaParseTupleAndKeywords', '_PyArg_NoKeywords',
-    'PyString_FromFormat', 'PyString_FromFormatV',
     'PyUnicode_FromFormat', 'PyUnicode_FromFormatV', 'PyUnicode_AsWideCharString',
     'PyModule_AddObject', 'PyModule_AddIntConstant', 'PyModule_AddStringConstant',
     'Py_BuildValue', 'Py_VaBuildValue', 'PyTuple_Pack',
diff --git a/pypy/module/cpyext/bytesobject.py b/pypy/module/cpyext/bytesobject.py
--- a/pypy/module/cpyext/bytesobject.py
+++ b/pypy/module/cpyext/bytesobject.py
@@ -1,5 +1,251 @@
-from pypy.module.cpyext.pyobject import PyObject
-from pypy.module.cpyext.api import cpython_api
+from pypy.interpreter.error import OperationError
+from pypy.rpython.lltypesystem import rffi, lltype
+from pypy.module.cpyext.api import (
+    cpython_api, cpython_struct, bootstrap_function, build_type_checkers,
+    PyObjectFields, Py_ssize_t, CONST_STRING, CANNOT_FAIL)
+from pypy.module.cpyext.pyerrors import PyErr_BadArgument
+from pypy.module.cpyext.pyobject import (
+    PyObject, PyObjectP, Py_DecRef, make_ref, from_ref, track_reference,
+    make_typedescr, get_typedescr)
+
+
+##
+## Implementation of PyBytesObject
+## ================================
+##
+## The problem
+## -----------
+##
+## PyBytes_AsString() must return a (non-movable) pointer to the underlying
+## buffer, whereas pypy strings are movable.  C code may temporarily store
+## this address and use it, as long as it owns a reference to the PyObject.
+## There is no "release" function to specify that the pointer is not needed
+## any more.
+##
+## Also, the pointer may be used to fill the initial value of string. This is
+## valid only when the string was just allocated, and is not used elsewhere.
+##
+## Solution
+## --------
+##
+## PyBytesObject contains two additional members: the size and a pointer to a
+## char buffer; it may be NULL.
+##
+## - A string allocated by pypy will be converted into a PyBytesObject with a
+##   NULL buffer.  The first time PyBytes_AsString() is called, memory is
+##   allocated (with flavor='raw') and content is copied.
+##
+## - A string allocated with PyBytes_FromStringAndSize(NULL, size) will
+##   allocate a PyBytesObject structure, and a buffer with the specified
+##   size, but the reference won't be stored in the global map; there is no
+##   corresponding object in pypy.  When from_ref() or Py_INCREF() is called,
+##   the pypy string is created, and added to the global map of tracked
+##   objects.  The buffer is then supposed to be immutable.
+##
+## - _PyBytes_Resize() works only on not-yet-pypy'd strings, and returns a
+##   similar object.
+##
+## - PyBytes_Size() doesn't need to force the object.
+##
+## - There could be an (expensive!) check in from_ref() that the buffer still
+##   corresponds to the pypy gc-managed string.
+##
+
+PyBytesObjectStruct = lltype.ForwardReference()
+PyBytesObject = lltype.Ptr(PyBytesObjectStruct)
+PyBytesObjectFields = PyObjectFields + \
+    (("buffer", rffi.CCHARP), ("size", Py_ssize_t))
+cpython_struct("PyBytesObject", PyBytesObjectFields, PyBytesObjectStruct)
+
+ at bootstrap_function
+def init_bytesobject(space):
+    "Type description of PyBytesObject"
+    make_typedescr(space.w_str.instancetypedef,
+                   basestruct=PyBytesObject.TO,
+                   attach=bytes_attach,
+                   dealloc=bytes_dealloc,
+                   realize=bytes_realize)
+
+PyBytes_Check, PyBytes_CheckExact = build_type_checkers("Bytes", "w_bytes")
+
+def new_empty_str(space, length):
+    """
+    Allocates a PyBytesObject and its buffer, but without a corresponding
+    interpreter object.  The buffer may be mutated, until bytes_realize() is
+    called.
+    """
+    typedescr = get_typedescr(space.w_bytes.instancetypedef)
+    py_obj = typedescr.allocate(space, space.w_bytes)
+    py_str = rffi.cast(PyBytesObject, py_obj)
+
+    buflen = length + 1
+    py_str.c_size = length
+    py_str.c_buffer = lltype.malloc(rffi.CCHARP.TO, buflen,
+                                    flavor='raw', zero=True)
+    return py_str
+
+def bytes_attach(space, py_obj, w_obj):
+    """
+    Fills a newly allocated PyBytesObject with the given string object. The
+    buffer must not be modified.
+    """
+    py_str = rffi.cast(PyBytesObject, py_obj)
+    py_str.c_size = len(space.bytes_w(w_obj))
+    py_str.c_buffer = lltype.nullptr(rffi.CCHARP.TO)
+
+def bytes_realize(space, py_obj):
+    """
+    Creates the string in the interpreter. The PyBytesObject buffer must not
+    be modified after this call.
+    """
+    py_str = rffi.cast(PyBytesObject, py_obj)
+    s = rffi.charpsize2str(py_str.c_buffer, py_str.c_size)
+    w_obj = space.wrap(s)
+    track_reference(space, py_obj, w_obj)
+    return w_obj
+
+ at cpython_api([PyObject], lltype.Void, external=False)
+def bytes_dealloc(space, py_obj):
+    """Frees allocated PyBytesObject resources.
+    """
+    py_str = rffi.cast(PyBytesObject, py_obj)
+    if py_str.c_buffer:
+        lltype.free(py_str.c_buffer, flavor="raw")
+    from pypy.module.cpyext.object import PyObject_dealloc
+    PyObject_dealloc(space, py_obj)
+
+#_______________________________________________________________________
+
+ at cpython_api([CONST_STRING, Py_ssize_t], PyObject)
+def PyBytes_FromStringAndSize(space, char_p, length):
+    if char_p:
+        s = rffi.charpsize2str(char_p, length)
+        return make_ref(space, space.wrapbytes(s))
+    else:
+        return rffi.cast(PyObject, new_empty_str(space, length))
+
+ at cpython_api([CONST_STRING], PyObject)
+def PyBytes_FromString(space, char_p):
+    s = rffi.charp2str(char_p)
+    return space.wrapbytes(s)
+
+ at cpython_api([PyObject], rffi.CCHARP, error=0)
+def PyBytes_AsString(space, ref):
+    if from_ref(space, rffi.cast(PyObject, ref.c_ob_type)) is space.w_str:
+        pass    # typecheck returned "ok" without forcing 'ref' at all
+    elif not PyBytes_Check(space, ref):   # otherwise, use the alternate way
+        raise OperationError(space.w_TypeError, space.wrap(
+            "PyBytes_AsString only support strings"))
+    ref_str = rffi.cast(PyBytesObject, ref)
+    if not ref_str.c_buffer:
+        # copy string buffer
+        w_str = from_ref(space, ref)
+        s = space.bytes_w(w_str)
+        ref_str.c_buffer = rffi.str2charp(s)
+    return ref_str.c_buffer
+
+#_______________________________________________________________________
+
+ at cpython_api([PyObject, rffi.CCHARPP, rffi.CArrayPtr(Py_ssize_t)], rffi.INT_real, error=-1)
+def PyBytes_AsStringAndSize(space, ref, buffer, length):
+    if not PyBytes_Check(space, ref):
+        raise OperationError(space.w_TypeError, space.wrap(
+            "PyBytes_AsStringAndSize only support strings"))
+    ref_str = rffi.cast(PyBytesObject, ref)
+    if not ref_str.c_buffer:
+        # copy string buffer
+        w_str = from_ref(space, ref)
+        s = space.bytes_w(w_str)
+        ref_str.c_buffer = rffi.str2charp(s)
+    buffer[0] = ref_str.c_buffer
+    if length:
+        length[0] = ref_str.c_size
+    else:
+        i = 0
+        while ref_str.c_buffer[i] != '\0':
+            i += 1
+        if i != ref_str.c_size:
+            raise OperationError(space.w_TypeError, space.wrap(
+                "expected string without null bytes"))
+    return 0
+
+ at cpython_api([PyObject], Py_ssize_t, error=-1)
+def PyBytes_Size(space, ref):
+    if from_ref(space, rffi.cast(PyObject, ref.c_ob_type)) is space.w_str:
+        ref = rffi.cast(PyBytesObject, ref)
+        return ref.c_size
+    else:
+        w_obj = from_ref(space, ref)
+        return space.len_w(w_obj)
+
+ at cpython_api([PyObjectP, Py_ssize_t], rffi.INT_real, error=-1)
+def _PyBytes_Resize(space, ref, newsize):
+    """A way to resize a string object even though it is "immutable". Only use this to
+    build up a brand new string object; don't use this if the string may already be
+    known in other parts of the code.  It is an error to call this function if the
+    refcount on the input string object is not one. Pass the address of an existing
+    string object as an lvalue (it may be written into), and the new size desired.
+    On success, *string holds the resized string object and 0 is returned;
+    the address in *string may differ from its input value.  If the reallocation
+    fails, the original string object at *string is deallocated, *string is
+    set to NULL, a memory exception is set, and -1 is returned.
+    """
+    # XXX always create a new string so far
+    py_str = rffi.cast(PyBytesObject, ref[0])
+    if not py_str.c_buffer:
+        raise OperationError(space.w_SystemError, space.wrap(
+            "_PyBytes_Resize called on already created string"))
+    try:
+        py_newstr = new_empty_str(space, newsize)
+    except MemoryError:
+        Py_DecRef(space, ref[0])
+        ref[0] = lltype.nullptr(PyObject.TO)
+        raise
+    to_cp = newsize
+    oldsize = py_str.c_size
+    if oldsize < newsize:
+        to_cp = oldsize
+    for i in range(to_cp):
+        py_newstr.c_buffer[i] = py_str.c_buffer[i]
+    Py_DecRef(space, ref[0])
+    ref[0] = rffi.cast(PyObject, py_newstr)
+    return 0
+
+ at cpython_api([PyObject, PyObject], rffi.INT, error=CANNOT_FAIL)
+def _PyBytes_Eq(space, w_str1, w_str2):
+    return space.eq_w(w_str1, w_str2)
+
+ at cpython_api([PyObjectP, PyObject], lltype.Void)
+def PyBytes_Concat(space, ref, w_newpart):
+    """Create a new string object in *string containing the contents of newpart
+    appended to string; the caller will own the new reference.  The reference to
+    the old value of string will be stolen.  If the new string cannot be created,
+    the old reference to string will still be discarded and the value of
+    *string will be set to NULL; the appropriate exception will be set."""
+
+    if not ref[0]:
+        return
+
+    if w_newpart is None or not PyBytes_Check(space, ref[0]) or \
+            not PyBytes_Check(space, w_newpart):
+         Py_DecRef(space, ref[0])
+         ref[0] = lltype.nullptr(PyObject.TO)
+         return
+    w_str = from_ref(space, ref[0])
+    w_newstr = space.add(w_str, w_newpart)
+    Py_DecRef(space, ref[0])
+    ref[0] = make_ref(space, w_newstr)
+
+ at cpython_api([PyObjectP, PyObject], lltype.Void)
+def PyBytes_ConcatAndDel(space, ref, newpart):
+    """Create a new string object in *string containing the contents of newpart
+    appended to string.  This version decrements the reference count of newpart."""
+    PyBytes_Concat(space, ref, newpart)
+    Py_DecRef(space, newpart)
+
+ at cpython_api([PyObject, PyObject], PyObject)
+def _PyBytes_Join(space, w_sep, w_seq):
+    return space.call_method(w_sep, 'join', w_seq)
 
 @cpython_api([PyObject], PyObject)
 def PyBytes_FromObject(space, w_obj):
diff --git a/pypy/module/cpyext/include/Python.h b/pypy/module/cpyext/include/Python.h
--- a/pypy/module/cpyext/include/Python.h
+++ b/pypy/module/cpyext/include/Python.h
@@ -104,7 +104,6 @@
 #include "pythonrun.h"
 #include "pyerrors.h"
 #include "sysmodule.h"
-#include "stringobject.h"
 #include "descrobject.h"
 #include "tupleobject.h"
 #include "dictobject.h"
diff --git a/pypy/module/cpyext/include/bytesobject.h b/pypy/module/cpyext/include/bytesobject.h
--- a/pypy/module/cpyext/include/bytesobject.h
+++ b/pypy/module/cpyext/include/bytesobject.h
@@ -1,30 +1,25 @@
-#define PyBytesObject PyStringObject
-#define PyBytes_Type PyString_Type
 
-#define PyBytes_Check PyString_Check
-#define PyBytes_CheckExact PyString_CheckExact 
-#define PyBytes_CHECK_INTERNED PyString_CHECK_INTERNED
-#define PyBytes_AS_STRING PyString_AS_STRING
-#define PyBytes_GET_SIZE PyString_GET_SIZE
-#define Py_TPFLAGS_BYTES_SUBCLASS Py_TPFLAGS_STRING_SUBCLASS
+/* String object interface */
 
-#define PyBytes_FromStringAndSize PyString_FromStringAndSize
-#define PyBytes_FromString PyString_FromString
-#define PyBytes_FromFormatV PyString_FromFormatV
-#define PyBytes_FromFormat PyString_FromFormat
-#define PyBytes_Size PyString_Size
-#define PyBytes_AsString PyString_AsString
-#define PyBytes_Repr PyString_Repr
-#define PyBytes_Concat PyString_Concat
-#define PyBytes_ConcatAndDel PyString_ConcatAndDel
-#define _PyBytes_Resize _PyString_Resize
-#define _PyBytes_Eq _PyString_Eq
-#define PyBytes_Format PyString_Format
-#define _PyBytes_FormatLong _PyString_FormatLong
-#define PyBytes_DecodeEscape PyString_DecodeEscape
-#define _PyBytes_Join _PyString_Join
-#define PyBytes_AsStringAndSize PyString_AsStringAndSize
-#define _PyBytes_InsertThousandsGrouping _PyString_InsertThousandsGrouping
+#ifndef Py_BYTESOBJECT_H
+#define Py_BYTESOBJECT_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define PyBytes_GET_SIZE(op) PyBytes_Size(op)
+#define PyBytes_AS_STRING(op) PyBytes_AsString(op)
+
+typedef struct {
+    PyObject_HEAD
+    char* buffer;
+    Py_ssize_t size;
+} PyBytesObject;
 
 #define PyByteArray_Check(obj) \
     PyObject_IsInstance(obj, (PyObject *)&PyByteArray_Type)
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/pypy/module/cpyext/include/stringobject.h b/pypy/module/cpyext/include/stringobject.h
deleted file mode 100644
--- a/pypy/module/cpyext/include/stringobject.h
+++ /dev/null
@@ -1,22 +0,0 @@
-
-/* String object interface */
-
-#ifndef Py_STRINGOBJECT_H
-#define Py_STRINGOBJECT_H
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define PyString_GET_SIZE(op) PyString_Size(op)
-#define PyString_AS_STRING(op) PyString_AsString(op)
-
-typedef struct {
-    PyObject_HEAD
-    char* buffer;
-    Py_ssize_t size;
-} PyStringObject;
-
-#ifdef __cplusplus
-}
-#endif
-#endif
diff --git a/pypy/module/cpyext/pyobject.py b/pypy/module/cpyext/pyobject.py
--- a/pypy/module/cpyext/pyobject.py
+++ b/pypy/module/cpyext/pyobject.py
@@ -303,7 +303,7 @@
 def from_ref(space, ref):
     """
     Finds the interpreter object corresponding to the given reference.  If the
-    object is not yet realized (see stringobject.py), creates it.
+    object is not yet realized (see bytesobject.py), creates it.
     """
     assert lltype.typeOf(ref) == PyObject
     if not ref:
diff --git a/pypy/module/cpyext/sliceobject.py b/pypy/module/cpyext/sliceobject.py
--- a/pypy/module/cpyext/sliceobject.py
+++ b/pypy/module/cpyext/sliceobject.py
@@ -38,7 +38,7 @@
 
 @cpython_api([PyObject], lltype.Void, external=False)
 def slice_dealloc(space, py_obj):
-    """Frees allocated PyStringObject resources.
+    """Frees allocated PySliceObject resources.
     """
     py_slice = rffi.cast(PySliceObject, py_obj)
     Py_DecRef(space, py_slice.c_start)
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
@@ -1592,6 +1592,7 @@
     case 'z': /* string or None */
     case 'y': /* bytes */
     case 'u': /* unicode string */
+    case 'Z': /* unicode string or None */
     case 'w': /* buffer, read-write */
         {
             (void) va_arg(*p_va, char **);
@@ -1683,6 +1684,7 @@
     assert(min >= 0);
     assert(min <= max);
     if (!PyTuple_Check(args)) {
+        va_end(vargs);
         PyErr_SetString(PyExc_SystemError,
             "PyArg_UnpackTuple() argument list is not a tuple");
         return 0;
diff --git a/pypy/module/cpyext/stringobject.py b/pypy/module/cpyext/stringobject.py
deleted file mode 100644
--- a/pypy/module/cpyext/stringobject.py
+++ /dev/null
@@ -1,274 +0,0 @@
-from pypy.interpreter.error import OperationError
-from pypy.rpython.lltypesystem import rffi, lltype
-from pypy.module.cpyext.api import (
-    cpython_api, cpython_struct, bootstrap_function, build_type_checkers,
-    PyObjectFields, Py_ssize_t, CONST_STRING, CANNOT_FAIL)
-from pypy.module.cpyext.pyerrors import PyErr_BadArgument
-from pypy.module.cpyext.pyobject import (
-    PyObject, PyObjectP, Py_DecRef, make_ref, from_ref, track_reference,
-    make_typedescr, get_typedescr)
-
-##
-## Implementation of PyStringObject
-## ================================
-##
-## The problem
-## -----------
-##
-## PyString_AsString() must return a (non-movable) pointer to the underlying
-## buffer, whereas pypy strings are movable.  C code may temporarily store
-## this address and use it, as long as it owns a reference to the PyObject.
-## There is no "release" function to specify that the pointer is not needed
-## any more.
-##
-## Also, the pointer may be used to fill the initial value of string. This is
-## valid only when the string was just allocated, and is not used elsewhere.
-##
-## Solution
-## --------
-##
-## PyStringObject contains two additional members: the size and a pointer to a
-## char buffer; it may be NULL.
-##
-## - A string allocated by pypy will be converted into a PyStringObject with a
-##   NULL buffer.  The first time PyString_AsString() is called, memory is
-##   allocated (with flavor='raw') and content is copied.
-##
-## - A string allocated with PyString_FromStringAndSize(NULL, size) will
-##   allocate a PyStringObject structure, and a buffer with the specified
-##   size, but the reference won't be stored in the global map; there is no
-##   corresponding object in pypy.  When from_ref() or Py_INCREF() is called,
-##   the pypy string is created, and added to the global map of tracked
-##   objects.  The buffer is then supposed to be immutable.
-##
-## - _PyString_Resize() works only on not-yet-pypy'd strings, and returns a
-##   similar object.
-##
-## - PyString_Size() doesn't need to force the object.
-##
-## - There could be an (expensive!) check in from_ref() that the buffer still
-##   corresponds to the pypy gc-managed string.
-##
-
-PyStringObjectStruct = lltype.ForwardReference()
-PyStringObject = lltype.Ptr(PyStringObjectStruct)
-PyStringObjectFields = PyObjectFields + \
-    (("buffer", rffi.CCHARP), ("size", Py_ssize_t))
-cpython_struct("PyStringObject", PyStringObjectFields, PyStringObjectStruct)
-
- at bootstrap_function
-def init_stringobject(space):
-    "Type description of PyStringObject"
-    make_typedescr(space.w_str.instancetypedef,
-                   basestruct=PyStringObject.TO,
-                   attach=string_attach,
-                   dealloc=string_dealloc,
-                   realize=string_realize)
-
-PyString_Check, PyString_CheckExact = build_type_checkers("String", "w_str")
-
-def new_empty_str(space, length):
-    """
-    Allocatse a PyStringObject and its buffer, but without a corresponding
-    interpreter object.  The buffer may be mutated, until string_realize() is
-    called.
-    """
-    typedescr = get_typedescr(space.w_bytes.instancetypedef)
-    py_obj = typedescr.allocate(space, space.w_bytes)
-    py_str = rffi.cast(PyStringObject, py_obj)
-
-    buflen = length + 1
-    py_str.c_size = length
-    py_str.c_buffer = lltype.malloc(rffi.CCHARP.TO, buflen,
-                                    flavor='raw', zero=True)
-    return py_str
-
-def string_attach(space, py_obj, w_obj):
-    """
-    Fills a newly allocated PyStringObject with the given string object. The
-    buffer must not be modified.
-    """
-    py_str = rffi.cast(PyStringObject, py_obj)
-    py_str.c_size = len(space.bytes_w(w_obj))
-    py_str.c_buffer = lltype.nullptr(rffi.CCHARP.TO)
-
-def string_realize(space, py_obj):
-    """
-    Creates the string in the interpreter. The PyStringObject buffer must not
-    be modified after this call.
-    """
-    py_str = rffi.cast(PyStringObject, py_obj)
-    s = rffi.charpsize2str(py_str.c_buffer, py_str.c_size)
-    w_obj = space.wrap(s)
-    track_reference(space, py_obj, w_obj)
-    return w_obj
-
- at cpython_api([PyObject], lltype.Void, external=False)
-def string_dealloc(space, py_obj):
-    """Frees allocated PyStringObject resources.
-    """
-    py_str = rffi.cast(PyStringObject, py_obj)
-    if py_str.c_buffer:
-        lltype.free(py_str.c_buffer, flavor="raw")
-    from pypy.module.cpyext.object import PyObject_dealloc
-    PyObject_dealloc(space, py_obj)
-
-#_______________________________________________________________________
-
- at cpython_api([CONST_STRING, Py_ssize_t], PyObject)
-def PyString_FromStringAndSize(space, char_p, length):
-    if char_p:
-        s = rffi.charpsize2str(char_p, length)
-        return make_ref(space, space.wrapbytes(s))
-    else:
-        return rffi.cast(PyObject, new_empty_str(space, length))
-
- at cpython_api([CONST_STRING], PyObject)
-def PyString_FromString(space, char_p):
-    s = rffi.charp2str(char_p)
-    return space.wrapbytes(s)
-
- at cpython_api([PyObject], rffi.CCHARP, error=0)
-def PyString_AsString(space, ref):
-    if from_ref(space, rffi.cast(PyObject, ref.c_ob_type)) is space.w_str:
-        pass    # typecheck returned "ok" without forcing 'ref' at all
-    elif not PyString_Check(space, ref):   # otherwise, use the alternate way
-        raise OperationError(space.w_TypeError, space.wrap(
-            "PyString_AsString only support strings"))
-    ref_str = rffi.cast(PyStringObject, ref)
-    if not ref_str.c_buffer:
-        # copy string buffer
-        w_str = from_ref(space, ref)
-        s = space.bytes_w(w_str)
-        ref_str.c_buffer = rffi.str2charp(s)
-    return ref_str.c_buffer
-
- at cpython_api([PyObject, rffi.CCHARPP, rffi.CArrayPtr(Py_ssize_t)], rffi.INT_real, error=-1)
-def PyString_AsStringAndSize(space, ref, buffer, length):
-    if not PyString_Check(space, ref):
-        raise OperationError(space.w_TypeError, space.wrap(
-            "PyString_AsStringAndSize only support strings"))
-    ref_str = rffi.cast(PyStringObject, ref)
-    if not ref_str.c_buffer:
-        # copy string buffer
-        w_str = from_ref(space, ref)
-        s = space.bytes_w(w_str)
-        ref_str.c_buffer = rffi.str2charp(s)
-    buffer[0] = ref_str.c_buffer
-    if length:
-        length[0] = ref_str.c_size
-    else:
-        i = 0
-        while ref_str.c_buffer[i] != '\0':
-            i += 1
-        if i != ref_str.c_size:
-            raise OperationError(space.w_TypeError, space.wrap(
-                "expected string without null bytes"))
-    return 0
-
- at cpython_api([PyObject], Py_ssize_t, error=-1)
-def PyString_Size(space, ref):
-    if from_ref(space, rffi.cast(PyObject, ref.c_ob_type)) is space.w_str:
-        ref = rffi.cast(PyStringObject, ref)
-        return ref.c_size
-    else:
-        w_obj = from_ref(space, ref)
-        return space.len_w(w_obj)
-
- at cpython_api([PyObjectP, Py_ssize_t], rffi.INT_real, error=-1)
-def _PyString_Resize(space, ref, newsize):
-    """A way to resize a string object even though it is "immutable". Only use this to
-    build up a brand new string object; don't use this if the string may already be
-    known in other parts of the code.  It is an error to call this function if the
-    refcount on the input string object is not one. Pass the address of an existing
-    string object as an lvalue (it may be written into), and the new size desired.
-    On success, *string holds the resized string object and 0 is returned;
-    the address in *string may differ from its input value.  If the reallocation
-    fails, the original string object at *string is deallocated, *string is
-    set to NULL, a memory exception is set, and -1 is returned.
-    """
-    # XXX always create a new string so far
-    py_str = rffi.cast(PyStringObject, ref[0])
-    if not py_str.c_buffer:
-        raise OperationError(space.w_SystemError, space.wrap(
-            "_PyString_Resize called on already created string"))
-    try:
-        py_newstr = new_empty_str(space, newsize)
-    except MemoryError:
-        Py_DecRef(space, ref[0])
-        ref[0] = lltype.nullptr(PyObject.TO)
-        raise
-    to_cp = newsize
-    oldsize = py_str.c_size
-    if oldsize < newsize:
-        to_cp = oldsize
-    for i in range(to_cp):
-        py_newstr.c_buffer[i] = py_str.c_buffer[i]
-    Py_DecRef(space, ref[0])
-    ref[0] = rffi.cast(PyObject, py_newstr)
-    return 0
-
- at cpython_api([PyObject, PyObject], rffi.INT, error=CANNOT_FAIL)
-def _PyString_Eq(space, w_str1, w_str2):
-    return space.eq_w(w_str1, w_str2)
-
- at cpython_api([PyObjectP, PyObject], lltype.Void)
-def PyString_Concat(space, ref, w_newpart):
-    """Create a new string object in *string containing the contents of newpart
-    appended to string; the caller will own the new reference.  The reference to
-    the old value of string will be stolen.  If the new string cannot be created,
-    the old reference to string will still be discarded and the value of
-    *string will be set to NULL; the appropriate exception will be set."""
-
-    if not ref[0]:
-        return
-
-    if w_newpart is None or not PyString_Check(space, ref[0]) or \
-            not PyString_Check(space, w_newpart):
-         Py_DecRef(space, ref[0])
-         ref[0] = lltype.nullptr(PyObject.TO)
-         return
-    w_str = from_ref(space, ref[0])
-    w_newstr = space.add(w_str, w_newpart)
-    Py_DecRef(space, ref[0])
-    ref[0] = make_ref(space, w_newstr)
-
- at cpython_api([PyObjectP, PyObject], lltype.Void)
-def PyString_ConcatAndDel(space, ref, newpart):
-    """Create a new string object in *string containing the contents of newpart
-    appended to string.  This version decrements the reference count of newpart."""
-    PyString_Concat(space, ref, newpart)
-    Py_DecRef(space, newpart)
-
- at cpython_api([CONST_STRING], PyObject)
-def PyString_InternFromString(space, string):
-    """A combination of PyString_FromString() and
-    PyString_InternInPlace(), returning either a new string object that has
-    been interned, or a new ("owned") reference to an earlier interned string
-    object with the same value."""
-    s = rffi.charp2str(string)
-    return space.new_interned_str(s)
-
- at cpython_api([PyObjectP], lltype.Void)
-def PyString_InternInPlace(space, string):
-    """Intern the argument *string in place.  The argument must be the
-    address of a pointer variable pointing to a Python string object.
-    If there is an existing interned string that is the same as
-    *string, it sets *string to it (decrementing the reference count
-    of the old string object and incrementing the reference count of
-    the interned string object), otherwise it leaves *string alone and
-    interns it (incrementing its reference count).  (Clarification:
-    even though there is a lot of talk about reference counts, think
-    of this function as reference-count-neutral; you own the object
-    after the call if and only if you owned it before the call.)
-
-    This function is not available in 3.x and does not have a PyBytes
-    alias."""
-    w_str = from_ref(space, string[0])
-    w_str = space.new_interned_w_str(w_str)
-    Py_DecRef(space, string[0])
-    string[0] = make_ref(space, w_str)
-
- at cpython_api([PyObject, PyObject], PyObject)
-def _PyString_Join(space, w_sep, w_seq):
-    return space.call_method(w_sep, 'join', w_seq)
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
@@ -1,6 +1,217 @@
+from pypy.rpython.lltypesystem import rffi, lltype
 from pypy.module.cpyext.test.test_api import BaseApiTest
+from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase
+from pypy.module.cpyext.bytesobject import new_empty_str, PyBytesObject
+from pypy.module.cpyext.api import PyObjectP, PyObject, Py_ssize_tP
+from pypy.module.cpyext.pyobject import Py_DecRef, from_ref, make_ref
+
+import py
+import sys
+
+class AppTestBytesObject(AppTestCpythonExtensionBase):
+    def test_bytesobject(self):
+        module = self.import_extension('foo', [
+            ("get_hello1", "METH_NOARGS",
+             """
+                 return PyBytes_FromStringAndSize(
+                     "Hello world<should not be included>", 11);
+             """),
+            ("get_hello2", "METH_NOARGS",
+             """
+                 return PyBytes_FromString("Hello world");
+             """),
+            ("test_Size", "METH_NOARGS",
+             """
+                 PyObject* s = PyBytes_FromString("Hello world");
+                 int result = 0;
+
+                 if(PyBytes_Size(s) == 11) {
+                     result = 1;
+                 }
+                 if(s->ob_type->tp_basicsize != sizeof(void*)*4)
+                     result = 0;
+                 Py_DECREF(s);
+                 return PyBool_FromLong(result);
+             """),
+            ("test_Size_exception", "METH_NOARGS",
+             """
+                 PyObject* f = PyFloat_FromDouble(1.0);
+                 Py_ssize_t size = PyBytes_Size(f);
+
+                 Py_DECREF(f);
+                 return NULL;
+             """),
+             ("test_is_bytes", "METH_VARARGS",
+             """
+                return PyBool_FromLong(PyBytes_Check(PyTuple_GetItem(args, 0)));
+             """)])
+        assert module.get_hello1() == b'Hello world'
+        assert module.get_hello2() == b'Hello world'
+        assert module.test_Size()
+        raises(TypeError, module.test_Size_exception)
+
+        assert module.test_is_bytes(b"")
+        assert not module.test_is_bytes(())
+
+    def test_bytes_buffer_init(self):
+        module = self.import_extension('foo', [
+            ("getbytes", "METH_NOARGS",
+             """
+                 PyObject *s, *t;
+                 char* c;
+                 Py_ssize_t len;
+
+                 s = PyBytes_FromStringAndSize(NULL, 4);
+                 if (s == NULL)
+                    return NULL;
+                 t = PyBytes_FromStringAndSize(NULL, 3);
+                 if (t == NULL)
+                    return NULL;
+                 Py_DECREF(t);
+                 c = PyBytes_AsString(s);
+                 c[0] = 'a';
+                 c[1] = 'b';
+                 c[3] = 'c';
+                 return s;
+             """),
+            ])
+        s = module.getbytes()
+        assert len(s) == 4
+        assert s == 'ab\x00c'
+
+
+
+    def test_AsString(self):
+        module = self.import_extension('foo', [
+            ("getbytes", "METH_NOARGS",
+             """
+                 PyObject* s1 = PyBytes_FromStringAndSize("test", 4);
+                 char* c = PyBytes_AsString(s1);
+                 PyObject* s2 = PyBytes_FromStringAndSize(c, 4);
+                 Py_DECREF(s1);
+                 return s2;
+             """),
+            ])
+        s = module.getbytes()
+        assert s == b'test'
+
+    def test_py_bytes_as_string(self):
+        module = self.import_extension('foo', [
+            ("bytes_as_string", "METH_VARARGS",
+             '''
+             return PyBytes_FromStringAndSize(PyBytes_AsString(
+                       PyTuple_GetItem(args, 0)), 4);
+             '''
+            )])
+        assert module.bytes_as_string(b"huheduwe") == b"huhe"
+
+    def test_py_bytes_as_string_None(self):
+        module = self.import_extension('foo', [
+            ("string_None", "METH_VARARGS",
+             '''
+             return PyBytes_AsString(Py_None);
+             '''
+            )])
+        raises(TypeError, module.string_None)
+
+    def test_AsStringAndSize(self):
+        module = self.import_extension('foo', [
+            ("getbytes", "METH_NOARGS",
+             """
+                 PyObject* s1 = PyBytes_FromStringAndSize("te\\0st", 5);
+                 char *buf;
+                 Py_ssize_t len;
+                 if (PyBytes_AsStringAndSize(s1, &buf, &len) < 0)
+                     return NULL;
+                 if (len != 5) {
+                     PyErr_SetString(PyExc_AssertionError, "Bad Length");
+                     return NULL;
+                 }
+                 if (PyBytes_AsStringAndSize(s1, &buf, NULL) >= 0) {
+                     PyErr_SetString(PyExc_AssertionError, "Should Have failed");
+                     return NULL;
+                 }
+                 PyErr_Clear();
+                 Py_DECREF(s1);
+                 Py_INCREF(Py_None);
+                 return Py_None;
+             """),
+            ])
+        module.getbytes()
+
 
 class TestBytes(BaseApiTest):
+    def test_bytes_resize(self, space, api):
+        py_str = new_empty_str(space, 10)
+        ar = lltype.malloc(PyObjectP.TO, 1, flavor='raw')
+        py_str.c_buffer[0] = 'a'
+        py_str.c_buffer[1] = 'b'
+        py_str.c_buffer[2] = 'c'
+        ar[0] = rffi.cast(PyObject, py_str)
+        api._PyBytes_Resize(ar, 3)
+        py_str = rffi.cast(PyBytesObject, ar[0])
+        assert py_str.c_size == 3
+        assert py_str.c_buffer[1] == 'b'
+        assert py_str.c_buffer[3] == '\x00'
+        # the same for growing
+        ar[0] = rffi.cast(PyObject, py_str)
+        api._PyBytes_Resize(ar, 10)
+        py_str = rffi.cast(PyBytesObject, ar[0])
+        assert py_str.c_size == 10
+        assert py_str.c_buffer[1] == 'b'
+        assert py_str.c_buffer[10] == '\x00'
+        Py_DecRef(space, ar[0])
+        lltype.free(ar, flavor='raw')
+
+    def test_Concat(self, space, api):
+        ref = make_ref(space, space.wrapbytes('abc'))
+        ptr = lltype.malloc(PyObjectP.TO, 1, flavor='raw')
+        ptr[0] = ref
+        api.PyBytes_Concat(ptr, space.wrapbytes('def'))
+        assert space.bytes_w(from_ref(space, ptr[0])) == 'abcdef'
+        api.PyBytes_Concat(ptr, space.w_None)
+        assert not ptr[0]
+        ptr[0] = lltype.nullptr(PyObject.TO)
+        api.PyBytes_Concat(ptr, space.wrapbytes('def')) # should not crash
+        lltype.free(ptr, flavor='raw')
+
+    def test_ConcatAndDel(self, space, api):
+        ref1 = make_ref(space, space.wrapbytes('abc'))
+        ref2 = make_ref(space, space.wrapbytes('def'))
+        ptr = lltype.malloc(PyObjectP.TO, 1, flavor='raw')
+        ptr[0] = ref1
+        api.PyBytes_ConcatAndDel(ptr, ref2)
+        assert space.bytes_w(from_ref(space, ptr[0])) == 'abcdef'
+        assert ref2.c_ob_refcnt == 0
+        Py_DecRef(space, ptr[0])
+        ptr[0] = lltype.nullptr(PyObject.TO)
+        ref2 = make_ref(space, space.wrapbytes('foo'))
+        api.PyBytes_ConcatAndDel(ptr, ref2) # should not crash
+        assert ref2.c_ob_refcnt == 0
+        lltype.free(ptr, flavor='raw')
+
+    def test_asbuffer(self, space, api):
+        bufp = lltype.malloc(rffi.CCHARPP.TO, 1, flavor='raw')
+        lenp = lltype.malloc(Py_ssize_tP.TO, 1, flavor='raw')
+
+        w_text = space.wrapbytes("text")
+        assert api.PyObject_AsCharBuffer(w_text, bufp, lenp) == 0
+        assert lenp[0] == 4
+        assert rffi.charp2str(bufp[0]) == 'text'
+
+        lltype.free(bufp, flavor='raw')
+        lltype.free(lenp, flavor='raw')
+
+    def test_eq(self, space, api):
+        assert 1 == api._PyBytes_Eq(space.wrapbytes("hello"), space.wrapbytes("hello"))
+        assert 0 == api._PyBytes_Eq(space.wrapbytes("hello"), space.wrapbytes("world"))
+
+    def test_join(self, space, api):
+        w_sep = space.wrapbytes('<sep>')
+        w_seq = space.newtuple([space.wrapbytes('a'), space.wrapbytes('b')])
+        w_joined = api._PyBytes_Join(w_sep, w_seq)
+        assert space.bytes_w(w_joined) == 'a<sep>b'
+
     def test_FromObject(self, space, api):
         w_obj = space.wrapbytes("test")
         assert space.eq_w(w_obj, api.PyBytes_FromObject(w_obj))
diff --git a/pypy/module/cpyext/test/test_floatobject.py b/pypy/module/cpyext/test/test_floatobject.py
--- a/pypy/module/cpyext/test/test_floatobject.py
+++ b/pypy/module/cpyext/test/test_floatobject.py
@@ -36,7 +36,7 @@
         module = self.import_extension('foo', [
             ("from_string", "METH_NOARGS",
              """
-                 PyObject* str = PyString_FromString("1234.56");
+                 PyObject* str = PyUnicode_FromString("1234.56");
                  PyObject* res = PyFloat_FromString(str, NULL);
                  Py_DECREF(str);
                  return res;
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
@@ -9,7 +9,7 @@
                  PyObject *py_srcfile = PyUnicode_FromString("filename");
                  PyObject *py_funcname = PyUnicode_FromString("funcname");
                  PyObject *py_globals = PyDict_New();
-                 PyObject *empty_bytes = PyString_FromString("");
+                 PyObject *empty_bytes = PyBytes_FromString("");
                  PyObject *empty_tuple = PyTuple_New(0);
                  PyCodeObject *py_code;
                  PyFrameObject *py_frame;
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
@@ -122,7 +122,7 @@
             if (!PyArg_ParseTuple(args, "s*", &buf)) {
                 return NULL;
             }
-            result = PyString_FromStringAndSize(buf.buf, buf.len);
+            result = PyBytes_FromStringAndSize(buf.buf, buf.len);
             PyBuffer_Release(&buf);
             return result;
             ''')
@@ -164,7 +164,7 @@
             if (!PyArg_ParseTuple(args, "s#", &buf, &len)) {
                 return NULL;
             }
-            return PyString_FromStringAndSize(buf, len);
+            return PyBytes_FromStringAndSize(buf, len);
             ''')
         raises(TypeError, "charbuf(10)")
         assert b'foo\0bar\0baz' == charbuf(b'foo\0bar\0baz')
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
@@ -229,16 +229,16 @@
                 ("fillinfo", "METH_VARARGS",
                  """
     Py_buffer buf;
-    PyObject *str = PyString_FromString("hello, world.");
+    PyObject *str = PyBytes_FromString("hello, world.");
     PyObject *result;
 
-    if (PyBuffer_FillInfo(&buf, NULL, PyString_AsString(str), 13, 0, 0)) {
+    if (PyBuffer_FillInfo(&buf, NULL, PyBytes_AsString(str), 13, 0, 0)) {
         return NULL;
     }
 
     /* Check a few things we want to have happened.
      */
-    if (buf.buf != PyString_AsString(str)) {
+    if (buf.buf != PyBytes_AsString(str)) {
         PyErr_SetString(PyExc_ValueError, "buf field not initialized");
         return NULL;
     }
@@ -256,7 +256,7 @@
     /* Give back a new string to the caller, constructed from data in the
      * Py_buffer.
      */
-    if (!(result = PyString_FromStringAndSize(buf.buf, buf.len))) {
+    if (!(result = PyBytes_FromStringAndSize(buf.buf, buf.len))) {
         return NULL;
     }
 
@@ -281,10 +281,10 @@
                 ("fillinfo", "METH_VARARGS",
                  """
     Py_buffer buf;
-    PyObject *str = PyString_FromString("hello, world.");
+    PyObject *str = PyBytes_FromString("hello, world.");
     PyObject *result;
 
-    if (PyBuffer_FillInfo(&buf, str, PyString_AsString(str), 13, 0, 0)) {
+    if (PyBuffer_FillInfo(&buf, str, PyBytes_AsString(str), 13, 0, 0)) {
         return NULL;
     }
 
@@ -296,7 +296,7 @@
     /* Give back a new string to the caller, constructed from data in the
      * Py_buffer.  It better still be valid.
      */
-    if (!(result = PyString_FromStringAndSize(buf.buf, buf.len))) {
+    if (!(result = PyBytes_FromStringAndSize(buf.buf, buf.len))) {
         return NULL;
     }
 
@@ -327,10 +327,10 @@
                 ("fillinfo", "METH_VARARGS",
                  """
     Py_buffer buf;
-    PyObject *str = PyString_FromString("hello, world.");
+    PyObject *str = PyBytes_FromString("hello, world.");
     PyObject *result;
 
-    if (PyBuffer_FillInfo(&buf, str, PyString_AsString(str), 13,
+    if (PyBuffer_FillInfo(&buf, str, PyBytes_AsString(str), 13,
                           1, PyBUF_WRITABLE)) {
         Py_DECREF(str);
         return NULL;
@@ -355,9 +355,9 @@
                 ("release", "METH_VARARGS",
                  """
     Py_buffer buf;
-    buf.obj = PyString_FromString("release me!");
-    buf.buf = PyString_AsString(buf.obj);
-    buf.len = PyString_Size(buf.obj);
+    buf.obj = PyBytes_FromString("release me!");
+    buf.buf = PyBytes_AsString(buf.obj);
+    buf.len = PyBytes_Size(buf.obj);
 
     /* The Py_buffer owns the only reference to that string.  Release the
      * Py_buffer and the string should be released as well.
diff --git a/pypy/module/cpyext/test/test_stringobject.py b/pypy/module/cpyext/test/test_stringobject.py
deleted file mode 100644
--- a/pypy/module/cpyext/test/test_stringobject.py
+++ /dev/null
@@ -1,233 +0,0 @@
-from pypy.rpython.lltypesystem import rffi, lltype
-from pypy.module.cpyext.test.test_api import BaseApiTest
-from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase
-from pypy.module.cpyext.stringobject import new_empty_str, PyStringObject
-from pypy.module.cpyext.api import PyObjectP, PyObject, Py_ssize_tP
-from pypy.module.cpyext.pyobject import Py_DecRef, from_ref, make_ref
-
-import py
-import sys
-
-class AppTestStringObject(AppTestCpythonExtensionBase):
-    def test_stringobject(self):
-        module = self.import_extension('foo', [
-            ("get_hello1", "METH_NOARGS",
-             """
-                 return PyString_FromStringAndSize(
-                     "Hello world<should not be included>", 11);
-             """),
-            ("get_hello2", "METH_NOARGS",
-             """
-                 return PyString_FromString("Hello world");
-             """),
-            ("test_Size", "METH_NOARGS",
-             """
-                 PyObject* s = PyString_FromString("Hello world");
-                 int result = 0;
-
-                 if(PyString_Size(s) == 11) {
-                     result = 1;
-                 }
-                 if(s->ob_type->tp_basicsize != sizeof(void*)*4)
-                     result = 0;
-                 Py_DECREF(s);
-                 return PyBool_FromLong(result);
-             """),
-            ("test_Size_exception", "METH_NOARGS",
-             """
-                 PyObject* f = PyFloat_FromDouble(1.0);
-                 Py_ssize_t size = PyString_Size(f);
-
-                 Py_DECREF(f);
-                 return NULL;
-             """),
-             ("test_is_string", "METH_VARARGS",
-             """
-                return PyBool_FromLong(PyString_Check(PyTuple_GetItem(args, 0)));
-             """)])
-        assert module.get_hello1() == b'Hello world'
-        assert module.get_hello2() == b'Hello world'
-        assert module.test_Size()
-        raises(TypeError, module.test_Size_exception)
-
-        assert module.test_is_string(b"")
-        assert not module.test_is_string(())
-
-    def test_string_buffer_init(self):
-        module = self.import_extension('foo', [
-            ("getstring", "METH_NOARGS",
-             """
-                 PyObject *s, *t;
-                 char* c;
-                 Py_ssize_t len;
-
-                 s = PyString_FromStringAndSize(NULL, 4);
-                 if (s == NULL)
-                    return NULL;
-                 t = PyString_FromStringAndSize(NULL, 3);
-                 if (t == NULL)
-                    return NULL;
-                 Py_DECREF(t);
-                 c = PyString_AsString(s);
-                 c[0] = 'a';
-                 c[1] = 'b';
-                 c[3] = 'c';
-                 return s;
-             """),
-            ])
-        s = module.getstring()
-        assert len(s) == 4
-        assert s == 'ab\x00c'
-
-
-
-    def test_AsString(self):
-        module = self.import_extension('foo', [
-            ("getstring", "METH_NOARGS",
-             """
-                 PyObject* s1 = PyString_FromStringAndSize("test", 4);
-                 char* c = PyString_AsString(s1);
-                 PyObject* s2 = PyString_FromStringAndSize(c, 4);
-                 Py_DECREF(s1);
-                 return s2;
-             """),
-            ])
-        s = module.getstring()
-        assert s == b'test'
-
-    def test_py_string_as_string(self):
-        module = self.import_extension('foo', [
-            ("string_as_string", "METH_VARARGS",
-             '''
-             return PyString_FromStringAndSize(PyString_AsString(
-                       PyTuple_GetItem(args, 0)), 4);
-             '''
-            )])
-        assert module.string_as_string(b"huheduwe") == b"huhe"
-
-    def test_py_string_as_string_None(self):
-        module = self.import_extension('foo', [
-            ("string_None", "METH_VARARGS",
-             '''
-             return PyString_AsString(Py_None);
-             '''
-            )])
-        raises(TypeError, module.string_None)
-
-    def test_AsStringAndSize(self):
-        module = self.import_extension('foo', [
-            ("getstring", "METH_NOARGS",
-             """
-                 PyObject* s1 = PyString_FromStringAndSize("te\\0st", 5);
-                 char *buf;
-                 Py_ssize_t len;
-                 if (PyString_AsStringAndSize(s1, &buf, &len) < 0)
-                     return NULL;
-                 if (len != 5) {
-                     PyErr_SetString(PyExc_AssertionError, "Bad Length");
-                     return NULL;
-                 }
-                 if (PyString_AsStringAndSize(s1, &buf, NULL) >= 0) {
-                     PyErr_SetString(PyExc_AssertionError, "Should Have failed");
-                     return NULL;
-                 }
-                 PyErr_Clear();
-                 Py_DECREF(s1);
-                 Py_INCREF(Py_None);
-                 return Py_None;
-             """),
-            ])
-        module.getstring()
-
-    def test_intern_inplace(self):
-        module = self.import_extension('foo', [
-            ("test_intern_inplace", "METH_O",
-             '''
-                 PyObject *s = args;
-                 Py_INCREF(s);
-                 PyString_InternInPlace(&s);
-                 return s;
-             '''
-             )
-            ])
-        # This does not test much, but at least the refcounts are checked.
-        assert module.test_intern_inplace('s') == 's'
-
-class TestString(BaseApiTest):
-    def test_string_resize(self, space, api):
-        py_str = new_empty_str(space, 10)
-        ar = lltype.malloc(PyObjectP.TO, 1, flavor='raw')
-        py_str.c_buffer[0] = 'a'
-        py_str.c_buffer[1] = 'b'
-        py_str.c_buffer[2] = 'c'
-        ar[0] = rffi.cast(PyObject, py_str)
-        api._PyString_Resize(ar, 3)
-        py_str = rffi.cast(PyStringObject, ar[0])
-        assert py_str.c_size == 3
-        assert py_str.c_buffer[1] == 'b'
-        assert py_str.c_buffer[3] == '\x00'
-        # the same for growing
-        ar[0] = rffi.cast(PyObject, py_str)
-        api._PyString_Resize(ar, 10)
-        py_str = rffi.cast(PyStringObject, ar[0])
-        assert py_str.c_size == 10
-        assert py_str.c_buffer[1] == 'b'
-        assert py_str.c_buffer[10] == '\x00'
-        Py_DecRef(space, ar[0])
-        lltype.free(ar, flavor='raw')
-
-    def test_Concat(self, space, api):
-        ref = make_ref(space, space.wrapbytes('abc'))
-        ptr = lltype.malloc(PyObjectP.TO, 1, flavor='raw')
-        ptr[0] = ref
-        api.PyString_Concat(ptr, space.wrapbytes('def'))
-        assert space.bytes_w(from_ref(space, ptr[0])) == 'abcdef'
-        api.PyString_Concat(ptr, space.w_None)
-        assert not ptr[0]
-        ptr[0] = lltype.nullptr(PyObject.TO)
-        api.PyString_Concat(ptr, space.wrapbytes('def')) # should not crash
-        lltype.free(ptr, flavor='raw')
-
-    def test_ConcatAndDel(self, space, api):
-        ref1 = make_ref(space, space.wrapbytes('abc'))
-        ref2 = make_ref(space, space.wrapbytes('def'))
-        ptr = lltype.malloc(PyObjectP.TO, 1, flavor='raw')
-        ptr[0] = ref1
-        api.PyString_ConcatAndDel(ptr, ref2)
-        assert space.bytes_w(from_ref(space, ptr[0])) == 'abcdef'
-        assert ref2.c_ob_refcnt == 0
-        Py_DecRef(space, ptr[0])
-        ptr[0] = lltype.nullptr(PyObject.TO)
-        ref2 = make_ref(space, space.wrapbytes('foo'))
-        api.PyString_ConcatAndDel(ptr, ref2) # should not crash
-        assert ref2.c_ob_refcnt == 0
-        lltype.free(ptr, flavor='raw')
-
-    def test_asbuffer(self, space, api):
-        bufp = lltype.malloc(rffi.CCHARPP.TO, 1, flavor='raw')
-        lenp = lltype.malloc(Py_ssize_tP.TO, 1, flavor='raw')
-
-        w_text = space.wrapbytes("text")
-        assert api.PyObject_AsCharBuffer(w_text, bufp, lenp) == 0
-        assert lenp[0] == 4
-        assert rffi.charp2str(bufp[0]) == 'text'
-
-        lltype.free(bufp, flavor='raw')
-        lltype.free(lenp, flavor='raw')
-
-    def test_intern(self, space, api):
-        buf = rffi.str2charp("test")
-        w_s1 = api.PyString_InternFromString(buf)
-        w_s2 = api.PyString_InternFromString(buf)
-        rffi.free_charp(buf)
-        assert w_s1 is w_s2
-
-    def test_eq(self, space, api):
-        assert 1 == api._PyString_Eq(space.wrapbytes("hello"), space.wrapbytes("hello"))
-        assert 0 == api._PyString_Eq(space.wrapbytes("hello"), space.wrapbytes("world"))
-
-    def test_join(self, space, api):
-        w_sep = space.wrapbytes('<sep>')
-        w_seq = space.newtuple([space.wrapbytes('a'), space.wrapbytes('b')])
-        w_joined = api._PyString_Join(w_sep, w_seq)
-        assert space.bytes_w(w_joined) == 'a<sep>b'
diff --git a/pypy/module/cpyext/test/test_structseq.py b/pypy/module/cpyext/test/test_structseq.py
--- a/pypy/module/cpyext/test/test_structseq.py
+++ b/pypy/module/cpyext/test/test_structseq.py
@@ -35,8 +35,8 @@
                  if (!seq) return NULL;
                  PyStructSequence_SET_ITEM(seq, 0, PyInt_FromLong(42));
                  PyStructSequence_SET_ITEM(seq, 1, PyInt_FromLong(43));
-                 PyStructSequence_SET_ITEM(seq, 2, PyString_FromString("hello"));
-                 PyStructSequence_SET_ITEM(seq, 3, PyString_FromString("other"));
+                 PyStructSequence_SET_ITEM(seq, 2, PyUnicode_FromString("hello"));
+                 PyStructSequence_SET_ITEM(seq, 3, PyUnicode_FromString("other"));
                  Py_DECREF(&PyDatatype);
                  return seq;
              """)])
diff --git a/pypy/module/cpyext/typeobject.py b/pypy/module/cpyext/typeobject.py
--- a/pypy/module/cpyext/typeobject.py
+++ b/pypy/module/cpyext/typeobject.py
@@ -388,19 +388,19 @@
 
 @cpython_api([PyObject, lltype.Ptr(Py_buffer), rffi.INT_real], rffi.INT_real,
               external=False, error=-1)
-def str_getbuffer(space, w_str, view, flags):
-    from pypy.module.cpyext.stringobject import PyString_AsString
+def bytes_getbuffer(space, w_str, view, flags):
+    from pypy.module.cpyext.bytesobject import PyBytes_AsString
     view.c_obj = make_ref(space, w_str)
-    view.c_buf = rffi.cast(rffi.VOIDP, PyString_AsString(space, view.c_obj))
+    view.c_buf = rffi.cast(rffi.VOIDP, PyBytes_AsString(space, view.c_obj))
     view.c_len = space.len_w(w_str)
     return 0
 
-def setup_string_buffer_procs(space, pto):
+def setup_bytes_buffer_procs(space, pto):
     c_buf = lltype.malloc(PyBufferProcs, flavor='raw', zero=True)
     lltype.render_immortal(c_buf)
     c_buf.c_bf_getbuffer = llhelper(
-        str_getbuffer.api_func.functype,
-        str_getbuffer.api_func.get_wrapper(space))
+        bytes_getbuffer.api_func.functype,
+        bytes_getbuffer.api_func.get_wrapper(space))
     pto.c_tp_as_buffer = c_buf
     pto.c_tp_flags |= Py_TPFLAGS_HAVE_GETCHARBUFFER
 
@@ -458,7 +458,7 @@
     pto.c_tp_dealloc = typedescr.get_dealloc(space)
     # buffer protocol
     if space.is_w(w_type, space.w_str):
-        setup_string_buffer_procs(space, pto)
+        setup_bytes_buffer_procs(space, pto)
 
     pto.c_tp_free = llhelper(PyObject_Del.api_func.functype,
             PyObject_Del.api_func.get_wrapper(space))
diff --git a/pypy/module/cpyext/unicodeobject.py b/pypy/module/cpyext/unicodeobject.py
--- a/pypy/module/cpyext/unicodeobject.py
+++ b/pypy/module/cpyext/unicodeobject.py
@@ -10,8 +10,7 @@
 from pypy.module.cpyext.pyobject import (
     PyObject, PyObjectP, Py_DecRef, make_ref, from_ref, track_reference,
     make_typedescr, get_typedescr)
-from pypy.module.cpyext.stringobject import PyString_Check
-from pypy.module.cpyext.bytesobject import PyBytes_FromObject
+from pypy.module.cpyext.bytesobject import PyBytes_Check, PyBytes_FromObject
 from pypy.module._codecs.interp_codecs import CodecState
 from pypy.module.posix.interp_posix import fsencode, fsdecode
 from pypy.objspace.std import unicodeobject, unicodetype, stringtype
@@ -19,7 +18,7 @@
 from pypy.tool.sourcetools import func_renamer
 import sys
 
-## See comment in stringobject.py.
+## See comment in bytesobject.py.
 
 PyUnicodeObjectStruct = lltype.ForwardReference()
 PyUnicodeObject = lltype.Ptr(PyUnicodeObjectStruct)
@@ -310,9 +309,9 @@
     the Python codec registry. Return NULL if an exception was raised by the
     codec."""
     w_str = PyUnicode_AsEncodedObject(space, w_unicode, llencoding, llerrors)
-    if not PyString_Check(space, w_str):
+    if not PyBytes_Check(space, w_str):
         raise OperationError(space.w_TypeError, space.wrap(
-            "encoder did not return a string object"))
+            "encoder did not return a bytes object"))
     return w_str
 
 @cpython_api([PyObject], PyObject)


More information about the pypy-commit mailing list