@@ -3023,6 +3023,8 @@ PyDoc_STRVAR(bytes_doc,
30233023\n\
30243024If an argument is given it must be an iterable yielding ints in range(256)." );
30253025
3026+ static PyObject * bytes_iter (PyObject * seq );
3027+
30263028PyTypeObject PyBytes_Type = {
30273029 PyVarObject_HEAD_INIT (& PyType_Type , 0 )
30283030 "bytes" ,
@@ -3050,7 +3052,7 @@ PyTypeObject PyBytes_Type = {
30503052 0 , /* tp_clear */
30513053 (richcmpfunc )bytes_richcompare , /* tp_richcompare */
30523054 0 , /* tp_weaklistoffset */
3053- 0 , /* tp_iter */
3055+ bytes_iter , /* tp_iter */
30543056 0 , /* tp_iternext */
30553057 bytes_methods , /* tp_methods */
30563058 0 , /* tp_members */
@@ -3065,3 +3067,121 @@ PyTypeObject PyBytes_Type = {
30653067 PyType_GenericNew , /* tp_new */
30663068 PyObject_Del , /* tp_free */
30673069};
3070+
3071+ /*********************** Bytes Iterator ****************************/
3072+
3073+ typedef struct {
3074+ PyObject_HEAD
3075+ Py_ssize_t it_index ;
3076+ PyBytesObject * it_seq ; /* Set to NULL when iterator is exhausted */
3077+ } bytesiterobject ;
3078+
3079+ static void
3080+ bytesiter_dealloc (bytesiterobject * it )
3081+ {
3082+ _PyObject_GC_UNTRACK (it );
3083+ Py_XDECREF (it -> it_seq );
3084+ PyObject_GC_Del (it );
3085+ }
3086+
3087+ static int
3088+ bytesiter_traverse (bytesiterobject * it , visitproc visit , void * arg )
3089+ {
3090+ Py_VISIT (it -> it_seq );
3091+ return 0 ;
3092+ }
3093+
3094+ static PyObject *
3095+ bytesiter_next (bytesiterobject * it )
3096+ {
3097+ PyBytesObject * seq ;
3098+ PyObject * item ;
3099+
3100+ assert (it != NULL );
3101+ seq = it -> it_seq ;
3102+ if (seq == NULL )
3103+ return NULL ;
3104+ assert (PyBytes_Check (seq ));
3105+
3106+ if (it -> it_index < PyBytes_GET_SIZE (seq )) {
3107+ item = PyInt_FromLong (
3108+ (unsigned char )seq -> ob_bytes [it -> it_index ]);
3109+ if (item != NULL )
3110+ ++ it -> it_index ;
3111+ return item ;
3112+ }
3113+
3114+ Py_DECREF (seq );
3115+ it -> it_seq = NULL ;
3116+ return NULL ;
3117+ }
3118+
3119+ static PyObject *
3120+ bytesiter_length_hint (bytesiterobject * it )
3121+ {
3122+ Py_ssize_t len = 0 ;
3123+ if (it -> it_seq )
3124+ len = PyBytes_GET_SIZE (it -> it_seq ) - it -> it_index ;
3125+ return PyInt_FromSsize_t (len );
3126+ }
3127+
3128+ PyDoc_STRVAR (length_hint_doc ,
3129+ "Private method returning an estimate of len(list(it))." );
3130+
3131+ static PyMethodDef bytesiter_methods [] = {
3132+ {"__length_hint__" , (PyCFunction )bytesiter_length_hint , METH_NOARGS ,
3133+ length_hint_doc },
3134+ {NULL , NULL } /* sentinel */
3135+ };
3136+
3137+ PyTypeObject PyBytesIter_Type = {
3138+ PyVarObject_HEAD_INIT (& PyType_Type , 0 )
3139+ "bytesiterator" , /* tp_name */
3140+ sizeof (bytesiterobject ), /* tp_basicsize */
3141+ 0 , /* tp_itemsize */
3142+ /* methods */
3143+ (destructor )bytesiter_dealloc , /* tp_dealloc */
3144+ 0 , /* tp_print */
3145+ 0 , /* tp_getattr */
3146+ 0 , /* tp_setattr */
3147+ 0 , /* tp_compare */
3148+ 0 , /* tp_repr */
3149+ 0 , /* tp_as_number */
3150+ 0 , /* tp_as_sequence */
3151+ 0 , /* tp_as_mapping */
3152+ 0 , /* tp_hash */
3153+ 0 , /* tp_call */
3154+ 0 , /* tp_str */
3155+ PyObject_GenericGetAttr , /* tp_getattro */
3156+ 0 , /* tp_setattro */
3157+ 0 , /* tp_as_buffer */
3158+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC , /* tp_flags */
3159+ 0 , /* tp_doc */
3160+ (traverseproc )bytesiter_traverse , /* tp_traverse */
3161+ 0 , /* tp_clear */
3162+ 0 , /* tp_richcompare */
3163+ 0 , /* tp_weaklistoffset */
3164+ PyObject_SelfIter , /* tp_iter */
3165+ (iternextfunc )bytesiter_next , /* tp_iternext */
3166+ bytesiter_methods , /* tp_methods */
3167+ 0 ,
3168+ };
3169+
3170+ static PyObject *
3171+ bytes_iter (PyObject * seq )
3172+ {
3173+ bytesiterobject * it ;
3174+
3175+ if (!PyBytes_Check (seq )) {
3176+ PyErr_BadInternalCall ();
3177+ return NULL ;
3178+ }
3179+ it = PyObject_GC_New (bytesiterobject , & PyBytesIter_Type );
3180+ if (it == NULL )
3181+ return NULL ;
3182+ it -> it_index = 0 ;
3183+ Py_INCREF (seq );
3184+ it -> it_seq = (PyBytesObject * )seq ;
3185+ _PyObject_GC_TRACK (it );
3186+ return (PyObject * )it ;
3187+ }
0 commit comments