diff --git a/Cython/Compiler/Buffer.py b/Cython/Compiler/Buffer.py
index aaf1b6f8bee0b93c69a87228da68d5b4abbc41a0..2cb30279f64d99980943d176c84ba59a383f76a1 100644
--- a/Cython/Compiler/Buffer.py
+++ b/Cython/Compiler/Buffer.py
@@ -681,7 +681,10 @@ def get_type_information_cname(code, dtype, maxdepth=None):
 
         flags = "0"
         is_unsigned = "0"
-        if dtype.is_int:
+        if dtype is PyrexTypes.c_char_type:
+            is_unsigned = "IS_UNSIGNED(%s)" % declcode
+            typegroup = "'H'"
+        elif dtype.is_int:
             is_unsigned = "IS_UNSIGNED(%s)" % declcode
             typegroup = "%s ? 'U' : 'I'" % is_unsigned
         elif complex_possible or dtype.is_complex:
@@ -695,7 +698,7 @@ def get_type_information_cname(code, dtype, maxdepth=None):
         elif dtype.is_pyobject:
             typegroup = "'O'"
         else:
-            assert False
+            assert False, dtype
 
         typeinfo = ('static __Pyx_TypeInfo %s = '
                         '{ "%s", %s, sizeof(%s), { %s }, %s, %s, %s, %s };')
diff --git a/Cython/Utility/Buffer.c b/Cython/Utility/Buffer.c
index 008fd95a9059a8d6a2b597364c8da2d8df47231d..8327d407a6bc1dd321ff7038656d23bf3766d847 100644
--- a/Cython/Utility/Buffer.c
+++ b/Cython/Utility/Buffer.c
@@ -66,7 +66,7 @@ typedef struct {
   size_t size;     /* sizeof(type) */
   size_t arraysize[8]; /* length of array in each dimension */
   int ndim;
-  char typegroup; /* _R_eal, _C_omplex, Signed _I_nt, _U_nsigned int, _S_truct, _P_ointer, _O_bject */
+  char typegroup; /* _R_eal, _C_omplex, Signed _I_nt, _U_nsigned int, _S_truct, _P_ointer, _O_bject, c_H_ar */
   char is_unsigned;
   int flags;
 } __Pyx_TypeInfo;
@@ -290,7 +290,8 @@ static void __Pyx_BufFmt_RaiseUnexpectedChar(char ch) {
 
 static const char* __Pyx_BufFmt_DescribeTypeChar(char ch, int is_complex) {
   switch (ch) {
-    case 'b': return "'char'";
+    case 'c': return "'char'";
+    case 'b': return "'signed char'";
     case 'B': return "'unsigned char'";
     case 'h': return "'short'";
     case 'H': return "'unsigned short'";
@@ -417,7 +418,9 @@ static size_t __Pyx_BufFmt_TypeCharToPadding(char ch, CYTHON_UNUSED int is_compl
 
 static char __Pyx_BufFmt_TypeCharToGroup(char ch, int is_complex) {
   switch (ch) {
-    case 'c': case 'b': case 'h': case 'i':
+    case 'c':
+        return 'H';
+    case 'b': case 'h': case 'i':
     case 'l': case 'q': case 's': case 'p':
         return 'I';
     case 'B': case 'H': case 'I': case 'L': case 'Q':
@@ -530,8 +533,12 @@ static int __Pyx_BufFmt_ProcessTypeChunk(__Pyx_BufFmt_Context* ctx) {
         continue;
       }
 
-      __Pyx_BufFmt_RaiseExpected(ctx);
-      return -1;
+      if ((type->typegroup == 'H' || group == 'H') && type->size == size) {
+          /* special case -- chars don't care about sign */
+      } else {
+          __Pyx_BufFmt_RaiseExpected(ctx);
+          return -1;
+      }
     }
 
     offset = ctx->head->parent_offset + field->offset;
@@ -837,8 +844,14 @@ __pyx_typeinfo_cmp(__Pyx_TypeInfo *a, __Pyx_TypeInfo *b)
         return 1;
 
     if (a->size != b->size || a->typegroup != b->typegroup ||
-            a->is_unsigned != b->is_unsigned || a->ndim != b->ndim)
-        return 0;
+            a->is_unsigned != b->is_unsigned || a->ndim != b->ndim) {
+        if (a->typegroup == 'H' || b->typegroup == 'H') {
+            /* Special case for chars */
+            return a->size == b->size;
+        } else {
+            return 0;
+        }
+    }
 
     if (a->ndim) {
         /* Verify multidimensional C arrays */
@@ -893,6 +906,9 @@ static struct __pyx_typeinfo_string __Pyx_TypeInfoToFormat(__Pyx_TypeInfo *type)
     size_t size = type->size;
 
     switch (type->typegroup) {
+        case 'H':
+            *buf = 'c';
+            break;
         case 'I':
         case 'U':
             if (size == 1)
diff --git a/tests/buffers/bufaccess.pyx b/tests/buffers/bufaccess.pyx
index 4c4ff4d7b0ca1c5607abe3ea37f8b11da1d63707..3418804708d01fd81c64f6df0080184277ccef15 100644
--- a/tests/buffers/bufaccess.pyx
+++ b/tests/buffers/bufaccess.pyx
@@ -1034,7 +1034,7 @@ def basic_struct(object[MyStruct] buf):
 
     >>> basic_struct(MyStructMockBuffer(None, [(1, 2, 3, 4, 5)]))
     1 2 3 4 5
-    >>> basic_struct(MyStructMockBuffer(None, [(1, 2, 3, 4, 5)], format="bbqii"))
+    >>> basic_struct(MyStructMockBuffer(None, [(1, 2, 3, 4, 5)], format="ccqii"))
     1 2 3 4 5
     """
     print buf[0].a, buf[0].b, buf[0].c, buf[0].d, buf[0].e
diff --git a/tests/buffers/buffmt.pyx b/tests/buffers/buffmt.pyx
index 8ffaad26d563c8650265df40674f8eb750d97e16..86f31fb782dfe545ba52437718a5412f0a54d7c0 100644
--- a/tests/buffers/buffmt.pyx
+++ b/tests/buffers/buffmt.pyx
@@ -63,7 +63,7 @@ def _int(fmt):
     >>> _int("b")
     Traceback (most recent call last):
        ...
-    ValueError: Buffer dtype mismatch, expected 'int' but got 'char'
+    ValueError: Buffer dtype mismatch, expected 'int' but got 'signed char'
 
     >>> _int("if")
     Traceback (most recent call last):
@@ -184,13 +184,13 @@ def char3int(fmt):
 def unpacked_struct(fmt):
     """
     Native formats:
-    >>> unpacked_struct("biZffbiii")
-    >>> unpacked_struct("@bi3fb3i")
-    >>> unpacked_struct("@biZffbi2i")
-    >>> unpacked_struct("biZffT{biii}")
-    >>> unpacked_struct("bT{ifffb2i}i")
-    >>> unpacked_struct("biZffb3T{i}")
-    >>> unpacked_struct("T{b}T{T{iZffT{bi}}}2T{T{i}}")
+    >>> unpacked_struct("ciZffciii")
+    >>> unpacked_struct("@ci3fc3i")
+    >>> unpacked_struct("@ciZffci2i")
+    >>> unpacked_struct("ciZffT{ciii}")
+    >>> unpacked_struct("cT{ifffc2i}i")
+    >>> unpacked_struct("ciZffc3T{i}")
+    >>> unpacked_struct("T{c}T{T{iZffT{ci}}}2T{T{i}}")
     """
 
     assert (sizeof(UnpackedStruct1) == sizeof(UnpackedStruct2)
@@ -303,7 +303,7 @@ def packed_struct(fmt):
     Assuming int is four bytes:
 
     >>> packed_struct("^cici")
-    >>> packed_struct("=cibi")
+    >>> packed_struct("=cici")
 
     However aligned access won't work:
 
diff --git a/tests/buffers/mockbuffers.pxi b/tests/buffers/mockbuffers.pxi
index fcb596262608a082ed2a471e1ca8c00d862fee98..bf145b1504ced838674f1505b6c70bcd14c6f931 100644
--- a/tests/buffers/mockbuffers.pxi
+++ b/tests/buffers/mockbuffers.pxi
@@ -280,7 +280,7 @@ cdef class MyStructMockBuffer(MockBuffer):
         return 0
 
     cdef get_itemsize(self): return sizeof(MyStruct)
-    cdef get_default_format(self): return b"2bq2i"
+    cdef get_default_format(self): return b"2cq2i"
 
 cdef class NestedStructMockBuffer(MockBuffer):
     cdef int write(self, char* buf, object value) except -1:
diff --git a/tests/memoryview/memoryview.pyx b/tests/memoryview/memoryview.pyx
index db560cd0d98a554d1c620eb20a4a9496e91c4810..00e0427ae31c759ea05c20e91e531b1bf86fa428 100644
--- a/tests/memoryview/memoryview.pyx
+++ b/tests/memoryview/memoryview.pyx
@@ -237,7 +237,7 @@ def basic_struct(MyStruct[:] mslice):
 
     >>> basic_struct(MyStructMockBuffer(None, [(1, 2, 3, 4, 5)]))
     [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5)]
-    >>> basic_struct(MyStructMockBuffer(None, [(1, 2, 3, 4, 5)], format="bbqii"))
+    >>> basic_struct(MyStructMockBuffer(None, [(1, 2, 3, 4, 5)], format="ccqii"))
     [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5)]
     """
     buf = mslice
diff --git a/tests/memoryview/memoryviewattrs.pyx b/tests/memoryview/memoryviewattrs.pyx
index 772b23e74bd0d87c2a70d4011b87ec31c2282504..b2ce03a68de7c0fad2abe56e17513d1dc89f450b 100644
--- a/tests/memoryview/memoryviewattrs.pyx
+++ b/tests/memoryview/memoryviewattrs.pyx
@@ -30,13 +30,13 @@ def test_shape_stride_suboffset():
     77 11 1
     -1 -1 -1
     '''
-    cdef char[:,:,:] larr = array((5,7,11), 1, 'b')
+    cdef char[:,:,:] larr = array((5,7,11), 1, 'c')
     print larr.shape[0], larr.shape[1], larr.shape[2]
     print larr.strides[0], larr.strides[1], larr.strides[2]
     print larr.suboffsets[0], larr.suboffsets[1], larr.suboffsets[2]
     print
 
-    larr = array((5,7,11), 1, 'b', mode='fortran')
+    larr = array((5,7,11), 1, 'c', mode='fortran')
     print larr.shape[0], larr.shape[1], larr.shape[2]
     print larr.strides[0], larr.strides[1], larr.strides[2]
     print larr.suboffsets[0], larr.suboffsets[1], larr.suboffsets[2]
diff --git a/tests/memoryview/memslice.pyx b/tests/memoryview/memslice.pyx
index a32e63902d916d3d074fdc0c397ad90c906a08f9..e459fdbc9905d8f7691d6c92471403e5c417cb65 100644
--- a/tests/memoryview/memslice.pyx
+++ b/tests/memoryview/memslice.pyx
@@ -1008,7 +1008,7 @@ def basic_struct(MyStruct[:] buf):
 
     >>> basic_struct(MyStructMockBuffer(None, [(1, 2, 3, 4, 5)]))
     1 2 3 4 5
-    >>> basic_struct(MyStructMockBuffer(None, [(1, 2, 3, 4, 5)], format="bbqii"))
+    >>> basic_struct(MyStructMockBuffer(None, [(1, 2, 3, 4, 5)], format="ccqii"))
     1 2 3 4 5
     """
     print buf[0].a, buf[0].b, buf[0].c, buf[0].d, buf[0].e