@@ -2810,79 +2810,33 @@ _PyBytes_FromBuffer(PyObject *x)
28102810}
28112811
28122812static PyObject *
2813- _PyBytes_FromList (PyObject * x )
2813+ _PyBytes_FromSequence (PyObject * x )
28142814{
2815- Py_ssize_t i , size = PyList_GET_SIZE (x );
2816- Py_ssize_t value ;
2817- char * str ;
2818- PyObject * item ;
2819- _PyBytesWriter writer ;
2820-
2821- _PyBytesWriter_Init (& writer );
2822- str = _PyBytesWriter_Alloc (& writer , size );
2823- if (str == NULL )
2824- return NULL ;
2825- writer .overallocate = 1 ;
2826- size = writer .allocated ;
2827-
2828- for (i = 0 ; i < PyList_GET_SIZE (x ); i ++ ) {
2829- item = PyList_GET_ITEM (x , i );
2830- Py_INCREF (item );
2831- value = PyNumber_AsSsize_t (item , NULL );
2832- Py_DECREF (item );
2833- if (value == -1 && PyErr_Occurred ())
2834- goto error ;
2835-
2836- if (value < 0 || value >= 256 ) {
2837- PyErr_SetString (PyExc_ValueError ,
2838- "bytes must be in range(0, 256)" );
2839- goto error ;
2840- }
2841-
2842- if (i >= size ) {
2843- str = _PyBytesWriter_Resize (& writer , str , size + 1 );
2844- if (str == NULL )
2845- return NULL ;
2846- size = writer .allocated ;
2847- }
2848- * str ++ = (char ) value ;
2849- }
2850- return _PyBytesWriter_Finish (& writer , str );
2851-
2852- error :
2853- _PyBytesWriter_Dealloc (& writer );
2854- return NULL ;
2855- }
2856-
2857- static PyObject *
2858- _PyBytes_FromTuple (PyObject * x )
2859- {
2860- PyObject * bytes ;
2861- Py_ssize_t i , size = PyTuple_GET_SIZE (x );
2862- Py_ssize_t value ;
2863- char * str ;
2864- PyObject * item ;
2865-
2866- bytes = PyBytes_FromStringAndSize (NULL , size );
2815+ Py_ssize_t size = PySequence_Fast_GET_SIZE (x );
2816+ PyObject * bytes = PyBytes_FromStringAndSize (NULL , size );
28672817 if (bytes == NULL )
28682818 return NULL ;
2869- str = ((PyBytesObject * )bytes )-> ob_sval ;
2870-
2871- for (i = 0 ; i < size ; i ++ ) {
2872- item = PyTuple_GET_ITEM (x , i );
2873- value = PyNumber_AsSsize_t (item , NULL );
2874- if (value == -1 && PyErr_Occurred ())
2819+ char * s = PyBytes_AS_STRING (bytes );
2820+ PyObject * * items = PySequence_Fast_ITEMS (x );
2821+ for (Py_ssize_t i = 0 ; i < size ; i ++ ) {
2822+ if (!PyLong_CheckExact (items [i ])) {
2823+ Py_DECREF (bytes );
2824+ return Py_None ; // None as fallback sentinel to the slow path
2825+ }
2826+ int overflow ;
2827+ long value = PyLong_AsLongAndOverflow (items [i ], & overflow );
2828+ if (value == -1 && PyErr_Occurred ()) {
28752829 goto error ;
2876-
2830+ }
28772831 if (value < 0 || value >= 256 ) {
2832+ /* this includes an overflow in converting to C long */
28782833 PyErr_SetString (PyExc_ValueError ,
28792834 "bytes must be in range(0, 256)" );
28802835 goto error ;
28812836 }
2882- * str ++ = ( char ) value ;
2837+ s [ i ] = value ;
28832838 }
28842839 return bytes ;
2885-
28862840 error :
28872841 Py_DECREF (bytes );
28882842 return NULL ;
@@ -2968,11 +2922,12 @@ PyBytes_FromObject(PyObject *x)
29682922 if (PyObject_CheckBuffer (x ))
29692923 return _PyBytes_FromBuffer (x );
29702924
2971- if (PyList_CheckExact (x ))
2972- return _PyBytes_FromList (x );
2973-
2974- if (PyTuple_CheckExact (x ))
2975- return _PyBytes_FromTuple (x );
2925+ if (PyList_CheckExact (x ) || PyTuple_CheckExact (x )) {
2926+ PyObject * bytes = _PyBytes_FromSequence (x );
2927+ if (bytes != Py_None ) {
2928+ return bytes ;
2929+ }
2930+ }
29762931
29772932 if (!PyUnicode_Check (x )) {
29782933 it = PyObject_GetIter (x );
0 commit comments