diff -r aaf2ad84ae1c Lib/test/test_mmap.py --- a/Lib/test/test_mmap.py Thu Apr 28 14:47:33 2016 -0500 +++ b/Lib/test/test_mmap.py Fri Apr 29 15:50:05 2016 +0800 @@ -54,6 +54,17 @@ self.assertRaises(IndexError, m.__getitem__, len(m)) self.assertRaises(IndexError, m.__setitem__, len(m), b'\0') + # Iteration returns int instead of bytes + for byte in m: + self.assertIsInstance(byte, int) + + # Test in operator behaviour + self.assertTrue(102 in m) + self.assertTrue(b'f' in m) + self.assertTrue(b'foo' in m) + self.assertRaises(TypeError, lambda: 'foo' in m) + self.assertRaises(ValueError, lambda: -1 in m) + # Modify the file's content m[0] = b'3'[0] m[PAGESIZE +3: PAGESIZE +3+3] = b'bar' diff -r aaf2ad84ae1c Modules/mmapmodule.c --- a/Modules/mmapmodule.c Thu Apr 28 14:47:33 2016 -0500 +++ b/Modules/mmapmodule.c Fri Apr 29 15:50:05 2016 +0800 @@ -790,7 +790,7 @@ PyErr_SetString(PyExc_IndexError, "mmap index out of range"); return NULL; } - return PyBytes_FromStringAndSize(self->data + i, 1); + return PyLong_FromLong(Py_CHARMASK(self->data[i])); } static PyObject * @@ -866,6 +866,45 @@ } static int +mmap_contains(PyObject *mmap, PyObject *arg) +{ + Py_ssize_t ival; + mmap_object *self = (mmap_object *)mmap; + + CHECK_VALID(-1); + ival = PyNumber_AsSsize_t(arg, PyExc_ValueError); + if (ival == -1 && PyErr_Occurred()) { + Py_buffer view; + Py_ssize_t i, len; + const char *p, *end, *needle; + + PyErr_Clear(); + if (PyObject_GetBuffer(arg, &view, PyBUF_SIMPLE) != 0) + return -1; + + len = view.len; + needle = view.buf; + end = self->data + self->size; + for (p = self->data; p + len <= end; ++p) { + for (i = 0; i < len && needle[i] == p[i]; ++i) + ; + if (i == len) { + PyBuffer_Release(&view); + return 1; + } + } + PyBuffer_Release(&view); + return 0; + } + if (ival < 0 || ival >= 256) { + PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)"); + return -1; + } + + return memchr(self->data, (int)ival, self->size) != NULL; +} + +static int mmap_ass_item(mmap_object *self, Py_ssize_t i, PyObject *v) { const char *buf; @@ -991,6 +1030,7 @@ 0, /*sq_slice*/ (ssizeobjargproc)mmap_ass_item, /*sq_ass_item*/ 0, /*sq_ass_slice*/ + (objobjproc)mmap_contains, /*sq_contains*/ }; static PyMappingMethods mmap_as_mapping = {