How can I write a Cython function that takes a byte string object (a normal string, a bytearray, or another object that follows the buffer protocol) as a typed memoryview?
This issue was fixed in Cython 0.28, released 2018-03-13 (PR #1869). The changelog says:
The const modifier can be applied to memoryview declarations to allow read-only buffers as input.
There is also a new section in the documentation.
The example you gave will work in Cython 0.28 if you write your function like this:
cpdef object printbuf(const unsigned char[:] buf):
chars = [chr(x) for x in buf]
print repr(''.join(chars))