diff -r 3e41c0449b9c Lib/sre_compile.py --- a/Lib/sre_compile.py Wed Aug 31 16:55:24 2016 -0700 +++ b/Lib/sre_compile.py Wed Aug 31 17:50:58 2016 -0700 @@ -249,7 +249,7 @@ # internal: optimize character set out = [] tail = [] - charmap = bytearray(256) + charmap = bytearray.zeros(256) for op, av in charset: while True: try: @@ -351,7 +351,7 @@ charmap = bytes(charmap) # should be hashable comps = {} - mapping = bytearray(256) + mapping = bytearray.zeros(256) block = 0 data = bytearray() for i in range(0, 65536, 256): diff -r 3e41c0449b9c Lib/test/test_bytes.py --- a/Lib/test/test_bytes.py Wed Aug 31 16:55:24 2016 -0700 +++ b/Lib/test/test_bytes.py Wed Aug 31 17:50:58 2016 -0700 @@ -82,15 +82,31 @@ self.assertRaises(ValueError, self.type2test, [Indexable(256)]) def test_from_ssize(self): - self.assertEqual(self.type2test(0), b'') - self.assertEqual(self.type2test(1), b'\x00') - self.assertEqual(self.type2test(5), b'\x00\x00\x00\x00\x00') + with self.assertWarns(DeprecationWarning): + self.assertEqual(self.type2test(0), b'') + with self.assertWarns(DeprecationWarning): + self.assertEqual(self.type2test(1), b'\x00') + with self.assertWarns(DeprecationWarning): + self.assertEqual(self.type2test(5), b'\x00\x00\x00\x00\x00') self.assertRaises(ValueError, self.type2test, -1) self.assertEqual(self.type2test('0', 'ascii'), b'0') self.assertEqual(self.type2test(b'0'), b'0') self.assertRaises(OverflowError, self.type2test, sys.maxsize + 1) + def test_zeros(self): + self.assertEqual(self.type2test.zeros(0), b'') + self.assertEqual(self.type2test.zeros(1), b'\x00') + self.assertEqual(self.type2test.zeros(5), b'\x00\x00\x00\x00\x00') + self.assertRaises(ValueError, self.type2test.zeros, -1) + + def test_single_byte(self): + self.assertEqual(self.type2test.byte(0), b'\x00') + self.assertEqual(self.type2test.byte(65), b'A') + self.assertEqual(self.type2test.byte(255), b'\xff') + self.assertRaises(ValueError, self.type2test.byte, 256) + self.assertRaises(ValueError, self.type2test.byte, -1) + def test_constructor_type_errors(self): self.assertRaises(TypeError, self.type2test, 0.0) class C: @@ -230,11 +246,14 @@ self.assertEqual(self.type2test(b'\xe2\x98\x83').decode(), '\u2603') def test_from_int(self): - b = self.type2test(0) + with self.assertWarns(DeprecationWarning): + b = self.type2test(0) self.assertEqual(b, self.type2test()) - b = self.type2test(10) + with self.assertWarns(DeprecationWarning): + b = self.type2test(10) self.assertEqual(b, self.type2test([0]*10)) - b = self.type2test(10000) + with self.assertWarns(DeprecationWarning): + b = self.type2test(10000) self.assertEqual(b, self.type2test([0]*10000)) def test_concat(self): @@ -729,7 +748,7 @@ self.assertEqual(c, b'hllo') -class BytesTest(BaseBytesTest, unittest.TestCase): +class BytesTest(BaseBytesTest): type2test = bytes def test_getitem_error(self): diff -r 3e41c0449b9c Lib/test/test_doctest.py --- a/Lib/test/test_doctest.py Wed Aug 31 16:55:24 2016 -0700 +++ b/Lib/test/test_doctest.py Wed Aug 31 17:50:58 2016 -0700 @@ -659,7 +659,7 @@ >>> import builtins >>> tests = doctest.DocTestFinder().find(builtins) - >>> 790 < len(tests) < 810 # approximate number of objects with docstrings + >>> 800 < len(tests) < 850 # approximate number of objects with docstrings True >>> real_tests = [t for t in tests if len(t.examples) > 0] >>> len(real_tests) # objects that actually have doctests diff -r 3e41c0449b9c Objects/bytearrayobject.c --- a/Objects/bytearrayobject.c Wed Aug 31 16:55:24 2016 -0700 +++ b/Objects/bytearrayobject.c Wed Aug 31 17:50:58 2016 -0700 @@ -804,6 +804,13 @@ PyErr_SetString(PyExc_ValueError, "negative count"); return -1; } + if (count >= 0) { + if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1, + "Passing an integer to the bytearray " + "constructor is deprecated. Use " + "bytearray.zeros(%zd) instead.\n", count) < 0) + return NULL; + } if (count > 0) { if (PyByteArray_Resize((PyObject *)self, count)) return -1; @@ -1991,6 +1998,67 @@ return result; } +/*[clinic input] +@classmethod +bytearray.zeros + + size: int + / + +Create a bytearray object of size given by the parameter initialized with null bytes. + +Parameter must be 0 or a positive integer. +Example: bytearray.zeros(3) -> bytearray(b\'\\x00\\x00\\x00') +[clinic start generated code]*/ + +static PyObject * +bytearray_zeros_impl(PyTypeObject *type, int size) +/*[clinic end generated code: output=483e961ce69e50dc input=b6e4556bd3095de2]*/ +{ + if (size == -1 && PyErr_Occurred()) { + return NULL; + } + if (size < 0) { + PyErr_SetString(PyExc_ValueError, "negative count"); + return NULL; + } + if (size >= 0) { + PyObject *result = PyByteArray_FromStringAndSize(NULL, size); + if (PyByteArray_Resize((PyObject *)result, size)) + return NULL; + memset(PyByteArray_AS_STRING(result), 0, size); + return result; + } +} + +/*[clinic input] +@classmethod +bytearray.byte + + x: int + / + +Create a bytearray object, consisting of a single byte. + +Parameter must be in range(0, 256) +bytearray.byte(x) is equivalent to bytearray([x]) +Example: bytearray.byte(3) -> bytearray(b'\x03') +[clinic start generated code]*/ + +static PyObject * +bytearray_byte_impl(PyTypeObject *type, int x) +/*[clinic end generated code: output=756fefaafb00a523 input=d36148c99214b551]*/ +{ + char byte; + if (x < 0 || x > 255) { + PyErr_Format(PyExc_ValueError, "bytes must be in range(0, 256)"); + return NULL; + } + byte = (char)x; + return PyByteArray_FromStringAndSize(&byte, 1); +} + + PyDoc_STRVAR(hex__doc__, "B.hex() -> string\n\ \n\ @@ -2118,6 +2186,7 @@ BYTEARRAY_REDUCE_EX_METHODDEF BYTEARRAY_SIZEOF_METHODDEF BYTEARRAY_APPEND_METHODDEF + BYTEARRAY_BYTE_METHODDEF {"capitalize", (PyCFunction)stringlib_capitalize, METH_NOARGS, _Py_capitalize__doc__}, {"center", (PyCFunction)stringlib_center, METH_VARARGS, _Py_center__doc__}, @@ -2179,6 +2248,7 @@ {"title", (PyCFunction)stringlib_title, METH_NOARGS, _Py_title__doc__}, BYTEARRAY_TRANSLATE_METHODDEF {"upper", (PyCFunction)stringlib_upper, METH_NOARGS, _Py_upper__doc__}, + BYTEARRAY_ZEROS_METHODDEF {"zfill", (PyCFunction)stringlib_zfill, METH_VARARGS, _Py_zfill__doc__}, {NULL} }; diff -r 3e41c0449b9c Objects/bytesobject.c --- a/Objects/bytesobject.c Wed Aug 31 16:55:24 2016 -0700 +++ b/Objects/bytesobject.c Wed Aug 31 17:50:58 2016 -0700 @@ -2384,6 +2384,58 @@ return NULL; } +/*[clinic input] +@classmethod +bytes.zeros + + size: int + / + +Create a bytes object of size given by the parameter initialized with null bytes. + +Parameter must be 0 or a positive integer. +Example: bytes.zeros(3) -> b\'\\x00\\x00\\x00' +[clinic start generated code]*/ + +static PyObject * +bytes_zeros_impl(PyTypeObject *type, int size) +/*[clinic end generated code: output=ae545bb17865f2a1 input=12e0adfbb086d92d]*/ +{ + if (size == -1 && PyErr_Occurred()) { + return NULL; + } + if (size < 0) { + PyErr_SetString(PyExc_ValueError, "negative count"); + return NULL; + } + return _PyBytes_FromSize(size, 1); +} + +/*[clinic input] +@classmethod +bytes.byte + + x: int + / + +Create a bytes object, consisting of a single byte. + +Parameter must be in range(0, 256) +bytes.byte(x) is equivalent to bytes([x]) +Example: bytes.byte(3) -> b'\x03' +[clinic start generated code]*/ + +static PyObject * +bytes_byte_impl(PyTypeObject *type, int x) +/*[clinic end generated code: output=9045f894ce311daa input=eb583448446d0edd]*/ +{ + if (x < 0 || x > 255) { + PyErr_Format(PyExc_ValueError, "bytes must be in range(0, 256)"); + return NULL; + } + return Py_BuildValue("c", x); +} + PyDoc_STRVAR(hex__doc__, "B.hex() -> string\n\ \n\ @@ -2410,6 +2462,7 @@ static PyMethodDef bytes_methods[] = { {"__getnewargs__", (PyCFunction)bytes_getnewargs, METH_NOARGS}, + BYTES_BYTE_METHODDEF {"capitalize", (PyCFunction)stringlib_capitalize, METH_NOARGS, _Py_capitalize__doc__}, {"center", (PyCFunction)stringlib_center, METH_VARARGS, @@ -2465,6 +2518,7 @@ {"title", (PyCFunction)stringlib_title, METH_NOARGS, _Py_title__doc__}, BYTES_TRANSLATE_METHODDEF {"upper", (PyCFunction)stringlib_upper, METH_NOARGS, _Py_upper__doc__}, + BYTES_ZEROS_METHODDEF {"zfill", (PyCFunction)stringlib_zfill, METH_VARARGS, _Py_zfill__doc__}, {NULL, NULL} /* sentinel */ }; @@ -2577,6 +2631,11 @@ new = _PyBytes_FromSize(size, 1); if (new == NULL) return NULL; + if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1, + "Passing an integer to the bytes constructor is " + "deprecated. Use bytes.zeros(%zd) instead.\n", + size) < 0) + return NULL; return new; } diff -r 3e41c0449b9c Objects/clinic/bytearrayobject.c.h --- a/Objects/clinic/bytearrayobject.c.h Wed Aug 31 16:55:24 2016 -0700 +++ b/Objects/clinic/bytearrayobject.c.h Wed Aug 31 17:50:58 2016 -0700 @@ -648,6 +648,67 @@ return return_value; } +PyDoc_STRVAR(bytearray_zeros__doc__, +"zeros($type, size, /)\n" +"--\n" +"\n" +"Create a bytearray object of size given by the parameter initialized with null bytes.\n" +"\n" +"Parameter must be 0 or a positive integer.\n" +"Example: bytearray.zeros(3) -> bytearray(b\\\'\\\\x00\\\\x00\\\\x00\')"); + +#define BYTEARRAY_ZEROS_METHODDEF \ + {"zeros", (PyCFunction)bytearray_zeros, METH_O|METH_CLASS, bytearray_zeros__doc__}, + +static PyObject * +bytearray_zeros_impl(PyTypeObject *type, int size); + +static PyObject * +bytearray_zeros(PyTypeObject *type, PyObject *arg) +{ + PyObject *return_value = NULL; + int size; + + if (!PyArg_Parse(arg, "i:zeros", &size)) { + goto exit; + } + return_value = bytearray_zeros_impl(type, size); + +exit: + return return_value; +} + +PyDoc_STRVAR(bytearray_byte__doc__, +"byte($type, x, /)\n" +"--\n" +"\n" +"Create a bytearray object, consisting of a single byte.\n" +"\n" +"Parameter must be in range(0, 256)\n" +"bytearray.byte(x) is equivalent to bytearray([x])\n" +"Example: bytearray.byte(3) -> bytearray(b\'\\x03\')"); + +#define BYTEARRAY_BYTE_METHODDEF \ + {"byte", (PyCFunction)bytearray_byte, METH_O|METH_CLASS, bytearray_byte__doc__}, + +static PyObject * +bytearray_byte_impl(PyTypeObject *type, int x); + +static PyObject * +bytearray_byte(PyTypeObject *type, PyObject *arg) +{ + PyObject *return_value = NULL; + int x; + + if (!PyArg_Parse(arg, "i:byte", &x)) { + goto exit; + } + return_value = bytearray_byte_impl(type, x); + +exit: + return return_value; +} + PyDoc_STRVAR(bytearray_reduce__doc__, "__reduce__($self, /)\n" "--\n" @@ -711,4 +772,4 @@ { return bytearray_sizeof_impl(self); } -/*[clinic end generated code: output=59a0c86b29ff06d1 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=42bdbffd9f162866 input=a9049054013a1b77]*/ diff -r 3e41c0449b9c Objects/clinic/bytesobject.c.h --- a/Objects/clinic/bytesobject.c.h Wed Aug 31 16:55:24 2016 -0700 +++ b/Objects/clinic/bytesobject.c.h Wed Aug 31 17:50:58 2016 -0700 @@ -499,4 +499,66 @@ exit: return return_value; } -/*[clinic end generated code: output=5618c05c24c1e617 input=a9049054013a1b77]*/ + +PyDoc_STRVAR(bytes_zeros__doc__, +"zeros($type, size, /)\n" +"--\n" +"\n" +"Create a bytes object of size given by the parameter initialized with null bytes.\n" +"\n" +"Parameter must be 0 or a positive integer.\n" +"Example: bytes.zeros(3) -> b\\\'\\\\x00\\\\x00\\\\x00\'"); + +#define BYTES_ZEROS_METHODDEF \ + {"zeros", (PyCFunction)bytes_zeros, METH_O|METH_CLASS, bytes_zeros__doc__}, + +static PyObject * +bytes_zeros_impl(PyTypeObject *type, int size); + +static PyObject * +bytes_zeros(PyTypeObject *type, PyObject *arg) +{ + PyObject *return_value = NULL; + int size; + + if (!PyArg_Parse(arg, "i:zeros", &size)) { + goto exit; + } + return_value = bytes_zeros_impl(type, size); + +exit: + return return_value; +} +/*[clinic end generated code: output=bb6252dfe230df90 input=a9049054013a1b77]*/ + +PyDoc_STRVAR(bytes_byte__doc__, +"byte($type, x, /)\n" +"--\n" +"\n" +"Create a bytes object, consisting of a single byte.\n" +"\n" +"Parameter must be in range(0, 256)\n" +"bytes.byte(x) is equivalent to bytes([x])\n" +"Example: bytes.byte(3) -> b\'\\x03\'"); + +#define BYTES_BYTE_METHODDEF \ + {"byte", (PyCFunction)bytes_byte, METH_O|METH_CLASS, bytes_byte__doc__}, + +static PyObject * +bytes_byte_impl(PyTypeObject *type, int x); + +static PyObject * +bytes_byte(PyTypeObject *type, PyObject *arg) +{ + PyObject *return_value = NULL; + int x; + + if (!PyArg_Parse(arg, "i:byte", &x)) { + goto exit; + } + return_value = bytes_byte_impl(type, x); + +exit: + return return_value; +} +/*[clinic end generated code: output=08e0d63b0e0453d7 input=a9049054013a1b77]*/