Author: Armin Rigo <[email protected]>
Branch: 
Changeset: r2702:4d6671385e08
Date: 2016-06-03 13:59 +0200
http://bitbucket.org/cffi/cffi/changeset/4d6671385e08/

Log:    Slice assignment with bytearray as source

diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c
--- a/c/_cffi_backend.c
+++ b/c/_cffi_backend.c
@@ -2155,21 +2155,34 @@
         }
     }
 
-    /* A fast path for <char[]>[0:N] = b"somestring", which also adds
-       support for Python 3: otherwise, you get integers while enumerating
-       the string, and you can't set them to characters :-/
+    /* A fast path for <char[]>[0:N] = b"somestring" or bytearray, which
+       also adds support for Python 3: otherwise, you get integers while
+       enumerating the string, and you can't set them to characters :-/
     */
-    if (PyBytes_Check(v) && (ct->ct_flags & CT_PRIMITIVE_CHAR)
-            && itemsize == sizeof(char)) {
-        if (PyBytes_GET_SIZE(v) != length) {
+    if ((ct->ct_flags & CT_PRIMITIVE_CHAR) && itemsize == sizeof(char)) {
+        char *src;
+        Py_ssize_t srclen;
+        if (PyBytes_Check(v)) {
+            srclen = PyBytes_GET_SIZE(v);
+            src = PyBytes_AS_STRING(v);
+        }
+        else if (PyByteArray_Check(v)) {
+            srclen = PyByteArray_GET_SIZE(v);
+            src = PyByteArray_AS_STRING(v);
+        }
+        else
+            goto other_types;
+
+        if (srclen != length) {
             PyErr_Format(PyExc_ValueError,
                          "need a string of length %zd, got %zd",
-                         length, PyBytes_GET_SIZE(v));
+                         length, srclen);
             return -1;
         }
-        memcpy(cdata, PyBytes_AS_STRING(v), length);
+        memcpy(cdata, src, length);
         return 0;
     }
+   other_types:
 
     it = PyObject_GetIter(v);
     if (it == NULL)
diff --git a/c/test_c.py b/c/test_c.py
--- a/c/test_c.py
+++ b/c/test_c.py
@@ -2697,10 +2697,12 @@
     BCharArray = new_array_type(
         new_pointer_type(new_primitive_type("char")), None)
     py.test.raises(TypeError, newp, BCharArray, bytearray(b"foo"))
-    p = newp(BCharArray, 4)
-    buffer(p)[:] = bytearray(b"foo\x00")
-    assert len(p) == 4
-    assert list(p) == [b"f", b"o", b"o", b"\x00"]
+    p = newp(BCharArray, 5)
+    buffer(p)[:] = bytearray(b"foo.\x00")
+    assert len(p) == 5
+    assert list(p) == [b"f", b"o", b"o", b".", b"\x00"]
+    p[1:3] = bytearray(b"XY")
+    assert list(p) == [b"f", b"X", b"Y", b".", b"\x00"]
 
 # XXX hack
 if sys.version_info >= (3,):
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to