@@ -269,19 +269,62 @@ bytes_getitem(PyBytesObject *self, Py_ssize_t i)
269269}
270270
271271static PyObject *
272- bytes_getslice (PyBytesObject * self , Py_ssize_t lo , Py_ssize_t hi )
272+ bytes_subscript (PyBytesObject * self , PyObject * item )
273273{
274- if (lo < 0 )
275- lo = 0 ;
276- if (hi > self -> ob_size )
277- hi = self -> ob_size ;
278- if (lo >= hi )
279- lo = hi = 0 ;
280- return PyBytes_FromStringAndSize (self -> ob_bytes + lo , hi - lo );
281- }
274+ if (PyIndex_Check (item )) {
275+ Py_ssize_t i = PyNumber_AsSsize_t (item , PyExc_IndexError );
282276
277+ if (i == -1 && PyErr_Occurred ())
278+ return NULL ;
279+
280+ if (i < 0 )
281+ i += PyBytes_GET_SIZE (self );
282+
283+ if (i < 0 || i >= self -> ob_size ) {
284+ PyErr_SetString (PyExc_IndexError , "bytes index out of range" );
285+ return NULL ;
286+ }
287+ return PyInt_FromLong ((unsigned char )(self -> ob_bytes [i ]));
288+ }
289+ else if (PySlice_Check (item )) {
290+ Py_ssize_t start , stop , step , slicelength , cur , i ;
291+ if (PySlice_GetIndicesEx ((PySliceObject * )item ,
292+ PyBytes_GET_SIZE (self ),
293+ & start , & stop , & step , & slicelength ) < 0 ) {
294+ return NULL ;
295+ }
296+
297+ if (slicelength <= 0 )
298+ return PyBytes_FromStringAndSize ("" , 0 );
299+ else if (step == 1 ) {
300+ return PyBytes_FromStringAndSize (self -> ob_bytes + start ,
301+ slicelength );
302+ }
303+ else {
304+ char * source_buf = PyBytes_AS_STRING (self );
305+ char * result_buf = (char * )PyMem_Malloc (slicelength );
306+ PyObject * result ;
307+
308+ if (result_buf == NULL )
309+ return PyErr_NoMemory ();
310+
311+ for (cur = start , i = 0 ; i < slicelength ;
312+ cur += step , i ++ ) {
313+ result_buf [i ] = source_buf [cur ];
314+ }
315+ result = PyBytes_FromStringAndSize (result_buf , slicelength );
316+ PyMem_Free (result_buf );
317+ return result ;
318+ }
319+ }
320+ else {
321+ PyErr_SetString (PyExc_TypeError , "bytes indices must be integers" );
322+ return NULL ;
323+ }
324+ }
325+
283326static int
284- bytes_setslice (PyBytesObject * self , Py_ssize_t lo , Py_ssize_t hi ,
327+ bytes_setslice (PyBytesObject * self , Py_ssize_t lo , Py_ssize_t hi ,
285328 PyObject * values )
286329{
287330 int avail ;
@@ -330,7 +373,7 @@ bytes_setslice(PyBytesObject *self, Py_ssize_t lo, Py_ssize_t hi,
330373 memmove (self -> ob_bytes + lo + needed , self -> ob_bytes + hi ,
331374 self -> ob_size - hi );
332375 }
333- if (PyBytes_Resize ((PyObject * )self ,
376+ if (PyBytes_Resize ((PyObject * )self ,
334377 self -> ob_size + needed - avail ) < 0 )
335378 return -1 ;
336379 if (avail < needed ) {
@@ -380,6 +423,164 @@ bytes_setitem(PyBytesObject *self, Py_ssize_t i, PyObject *value)
380423 return 0 ;
381424}
382425
426+ static int
427+ bytes_ass_subscript (PyBytesObject * self , PyObject * item , PyObject * values )
428+ {
429+ Py_ssize_t start , stop , step , slicelen , needed ;
430+ char * bytes ;
431+
432+ if (PyIndex_Check (item )) {
433+ Py_ssize_t i = PyNumber_AsSsize_t (item , PyExc_IndexError );
434+
435+ if (i == -1 && PyErr_Occurred ())
436+ return -1 ;
437+
438+ if (i < 0 )
439+ i += PyBytes_GET_SIZE (self );
440+
441+ if (i < 0 || i >= self -> ob_size ) {
442+ PyErr_SetString (PyExc_IndexError , "bytes index out of range" );
443+ return -1 ;
444+ }
445+
446+ if (values == NULL ) {
447+ /* Fall through to slice assignment */
448+ start = i ;
449+ stop = i + 1 ;
450+ step = 1 ;
451+ slicelen = 1 ;
452+ }
453+ else {
454+ Py_ssize_t ival = PyNumber_AsSsize_t (values , PyExc_ValueError );
455+ if (ival == -1 && PyErr_Occurred ())
456+ return -1 ;
457+ if (ival < 0 || ival >= 256 ) {
458+ PyErr_SetString (PyExc_ValueError ,
459+ "byte must be in range(0, 256)" );
460+ return -1 ;
461+ }
462+ self -> ob_bytes [i ] = (char )ival ;
463+ return 0 ;
464+ }
465+ }
466+ else if (PySlice_Check (item )) {
467+ if (PySlice_GetIndicesEx ((PySliceObject * )item ,
468+ PyBytes_GET_SIZE (self ),
469+ & start , & stop , & step , & slicelen ) < 0 ) {
470+ return -1 ;
471+ }
472+ }
473+ else {
474+ PyErr_SetString (PyExc_TypeError , "bytes indices must be integer" );
475+ return -1 ;
476+ }
477+
478+ if (values == NULL ) {
479+ bytes = NULL ;
480+ needed = 0 ;
481+ }
482+ else if (values == (PyObject * )self || !PyBytes_Check (values )) {
483+ /* Make a copy an call this function recursively */
484+ int err ;
485+ values = PyBytes_FromObject (values );
486+ if (values == NULL )
487+ return -1 ;
488+ err = bytes_ass_subscript (self , item , values );
489+ Py_DECREF (values );
490+ return err ;
491+ }
492+ else {
493+ assert (PyBytes_Check (values ));
494+ bytes = ((PyBytesObject * )values )-> ob_bytes ;
495+ needed = ((PyBytesObject * )values )-> ob_size ;
496+ }
497+ /* Make sure b[5:2] = ... inserts before 5, not before 2. */
498+ if ((step < 0 && start < stop ) ||
499+ (step > 0 && start > stop ))
500+ stop = start ;
501+ if (step == 1 ) {
502+ if (slicelen != needed ) {
503+ if (slicelen > needed ) {
504+ /*
505+ 0 start stop old_size
506+ | |<---slicelen--->|<-----tomove------>|
507+ | |<-needed->|<-----tomove------>|
508+ 0 lo new_hi new_size
509+ */
510+ memmove (self -> ob_bytes + start + needed , self -> ob_bytes + stop ,
511+ self -> ob_size - stop );
512+ }
513+ if (PyBytes_Resize ((PyObject * )self ,
514+ self -> ob_size + needed - slicelen ) < 0 )
515+ return -1 ;
516+ if (slicelen < needed ) {
517+ /*
518+ 0 lo hi old_size
519+ | |<-avail->|<-----tomove------>|
520+ | |<----needed---->|<-----tomove------>|
521+ 0 lo new_hi new_size
522+ */
523+ memmove (self -> ob_bytes + start + needed , self -> ob_bytes + stop ,
524+ self -> ob_size - start - needed );
525+ }
526+ }
527+
528+ if (needed > 0 )
529+ memcpy (self -> ob_bytes + start , bytes , needed );
530+
531+ return 0 ;
532+ }
533+ else {
534+ if (needed == 0 ) {
535+ /* Delete slice */
536+ Py_ssize_t cur , i ;
537+
538+ if (step < 0 ) {
539+ stop = start + 1 ;
540+ start = stop + step * (slicelen - 1 ) - 1 ;
541+ step = - step ;
542+ }
543+ for (cur = start , i = 0 ;
544+ i < slicelen ; cur += step , i ++ ) {
545+ Py_ssize_t lim = step - 1 ;
546+
547+ if (cur + step >= PyBytes_GET_SIZE (self ))
548+ lim = PyBytes_GET_SIZE (self ) - cur - 1 ;
549+
550+ memmove (self -> ob_bytes + cur - i ,
551+ self -> ob_bytes + cur + 1 , lim );
552+ }
553+ /* Move the tail of the bytes, in one chunk */
554+ cur = start + slicelen * step ;
555+ if (cur < PyBytes_GET_SIZE (self )) {
556+ memmove (self -> ob_bytes + cur - slicelen ,
557+ self -> ob_bytes + cur ,
558+ PyBytes_GET_SIZE (self ) - cur );
559+ }
560+ if (PyBytes_Resize ((PyObject * )self ,
561+ PyBytes_GET_SIZE (self ) - slicelen ) < 0 )
562+ return -1 ;
563+
564+ return 0 ;
565+ }
566+ else {
567+ /* Assign slice */
568+ Py_ssize_t cur , i ;
569+
570+ if (needed != slicelen ) {
571+ PyErr_Format (PyExc_ValueError ,
572+ "attempt to assign bytes of size %zd "
573+ "to extended slice of size %zd" ,
574+ needed , slicelen );
575+ return -1 ;
576+ }
577+ for (cur = start , i = 0 ; i < slicelen ; cur += step , i ++ )
578+ self -> ob_bytes [cur ] = bytes [i ];
579+ return 0 ;
580+ }
581+ }
582+ }
583+
383584static int
384585bytes_init (PyBytesObject * self , PyObject * args , PyObject * kwds )
385586{
@@ -776,18 +977,18 @@ static PySequenceMethods bytes_as_sequence = {
776977 (binaryfunc )bytes_concat , /*sq_concat*/
777978 (ssizeargfunc )bytes_repeat , /*sq_repeat*/
778979 (ssizeargfunc )bytes_getitem , /*sq_item*/
779- ( ssizessizeargfunc ) bytes_getslice , /*sq_slice*/
980+ 0 , /*sq_slice*/
780981 (ssizeobjargproc )bytes_setitem , /*sq_ass_item*/
781- ( ssizessizeobjargproc ) bytes_setslice , /* sq_ass_slice */
982+ 0 , /* sq_ass_slice */
782983 (objobjproc )bytes_contains , /* sq_contains */
783984 (binaryfunc )bytes_iconcat , /* sq_inplace_concat */
784985 (ssizeargfunc )bytes_irepeat , /* sq_inplace_repeat */
785986};
786987
787988static PyMappingMethods bytes_as_mapping = {
788989 (lenfunc )bytes_length ,
789- (binaryfunc )0 ,
790- 0 ,
990+ (binaryfunc )bytes_subscript ,
991+ ( objobjargproc ) bytes_ass_subscript ,
791992};
792993
793994static PyBufferProcs bytes_as_buffer = {
@@ -833,7 +1034,7 @@ PyTypeObject PyBytes_Type = {
8331034 PyObject_GenericGetAttr , /* tp_getattro */
8341035 0 , /* tp_setattro */
8351036 & bytes_as_buffer , /* tp_as_buffer */
836- Py_TPFLAGS_DEFAULT , /* tp_flags */
1037+ Py_TPFLAGS_DEFAULT , /* tp_flags */
8371038 /* bytes is 'final' or 'sealed' */
8381039 bytes_doc , /* tp_doc */
8391040 0 , /* tp_traverse */
0 commit comments