@@ -101,23 +101,38 @@ impl PyBytes {
101101 PyRef :: new_ref ( Self :: from ( data) , ctx. types . bytes_type . to_owned ( ) , None )
102102 }
103103
104- fn repeat ( zelf : PyRef < Self > , count : isize , vm : & VirtualMachine ) -> PyResult < PyRef < Self > > {
105- if count == 1 && zelf. class ( ) . is ( vm. ctx . types . bytes_type ) {
104+ fn _getitem ( & self , needle : & PyObject , vm : & VirtualMachine ) -> PyResult {
105+ match SequenceIndex :: try_from_borrowed_object ( vm, needle, "byte" ) ? {
106+ SequenceIndex :: Int ( i) => self
107+ . getitem_by_index ( vm, i)
108+ . map ( |x| vm. ctx . new_int ( x) . into ( ) ) ,
109+ SequenceIndex :: Slice ( slice) => self
110+ . getitem_by_slice ( vm, slice)
111+ . map ( |x| vm. ctx . new_bytes ( x) . into ( ) ) ,
112+ }
113+ }
114+ }
115+
116+ impl PyRef < PyBytes > {
117+ fn repeat ( self , count : isize , vm : & VirtualMachine ) -> PyResult < PyRef < PyBytes > > {
118+ if count == 1 && self . class ( ) . is ( vm. ctx . types . bytes_type ) {
106119 // Special case: when some `bytes` is multiplied by `1`,
107120 // nothing really happens, we need to return an object itself
108121 // with the same `id()` to be compatible with CPython.
109122 // This only works for `bytes` itself, not its subclasses.
110- return Ok ( zelf ) ;
123+ return Ok ( self ) ;
111124 }
112- zelf . inner
125+ self . inner
113126 . mul ( count, vm)
114- . map ( |x| Self :: from ( x) . into_ref ( vm) )
127+ . map ( |x| PyBytes :: from ( x) . into_ref ( vm) )
115128 }
116129}
117130
118131#[ pyclass(
119132 flags( BASETYPE ) ,
120133 with(
134+ Py ,
135+ PyRef ,
121136 AsMapping ,
122137 AsSequence ,
123138 Hashable ,
@@ -146,15 +161,6 @@ impl PyBytes {
146161 self . inner . as_bytes ( )
147162 }
148163
149- #[ pymethod( magic) ]
150- fn bytes ( zelf : PyRef < Self > , vm : & VirtualMachine ) -> PyRef < Self > {
151- if zelf. is ( vm. ctx . types . bytes_type ) {
152- zelf
153- } else {
154- PyBytes :: from ( zelf. inner . clone ( ) ) . into_ref ( vm)
155- }
156- }
157-
158164 #[ pymethod( magic) ]
159165 fn sizeof ( & self ) -> usize {
160166 size_of :: < Self > ( ) + self . len ( ) * size_of :: < u8 > ( )
@@ -179,17 +185,6 @@ impl PyBytes {
179185 PyBytesInner :: maketrans ( from, to, vm)
180186 }
181187
182- fn _getitem ( & self , needle : & PyObject , vm : & VirtualMachine ) -> PyResult {
183- match SequenceIndex :: try_from_borrowed_object ( vm, needle, "byte" ) ? {
184- SequenceIndex :: Int ( i) => self
185- . getitem_by_index ( vm, i)
186- . map ( |x| vm. ctx . new_int ( x) . into ( ) ) ,
187- SequenceIndex :: Slice ( slice) => self
188- . getitem_by_slice ( vm, slice)
189- . map ( |x| vm. ctx . new_bytes ( x) . into ( ) ) ,
190- }
191- }
192-
193188 #[ pymethod( magic) ]
194189 fn getitem ( & self , needle : PyObjectRef , vm : & VirtualMachine ) -> PyResult {
195190 self . _getitem ( & needle, vm)
@@ -371,53 +366,11 @@ impl PyBytes {
371366 self . inner . strip ( chars) . into ( )
372367 }
373368
374- #[ pymethod]
375- fn lstrip (
376- zelf : PyRef < Self > ,
377- chars : OptionalOption < PyBytesInner > ,
378- vm : & VirtualMachine ,
379- ) -> PyRef < Self > {
380- let stripped = zelf. inner . lstrip ( chars) ;
381- if stripped == zelf. as_bytes ( ) {
382- zelf
383- } else {
384- vm. ctx . new_bytes ( stripped. to_vec ( ) )
385- }
386- }
387-
388- #[ pymethod]
389- fn rstrip (
390- zelf : PyRef < Self > ,
391- chars : OptionalOption < PyBytesInner > ,
392- vm : & VirtualMachine ,
393- ) -> PyRef < Self > {
394- let stripped = zelf. inner . rstrip ( chars) ;
395- if stripped == zelf. as_bytes ( ) {
396- zelf
397- } else {
398- vm. ctx . new_bytes ( stripped. to_vec ( ) )
399- }
400- }
401-
402- /// removeprefix($self, prefix, /)
403- ///
404- ///
405- /// Return a bytes object with the given prefix string removed if present.
406- ///
407- /// If the bytes starts with the prefix string, return string[len(prefix):]
408- /// Otherwise, return a copy of the original bytes.
409369 #[ pymethod]
410370 fn removeprefix ( & self , prefix : PyBytesInner ) -> Self {
411371 self . inner . removeprefix ( prefix) . into ( )
412372 }
413373
414- /// removesuffix(self, prefix, /)
415- ///
416- ///
417- /// Return a bytes object with the given suffix string removed if present.
418- ///
419- /// If the bytes ends with the suffix string, return string[:len(suffix)]
420- /// Otherwise, return a copy of the original bytes.
421374 #[ pymethod]
422375 fn removesuffix ( & self , suffix : PyBytesInner ) -> Self {
423376 self . inner . removesuffix ( suffix) . into ( )
@@ -508,7 +461,7 @@ impl PyBytes {
508461 #[ pymethod( name = "__rmul__" ) ]
509462 #[ pymethod( magic) ]
510463 fn mul ( zelf : PyRef < Self > , value : ArgIndex , vm : & VirtualMachine ) -> PyResult < PyRef < Self > > {
511- Self :: repeat ( zelf , value. try_to_primitive ( vm) ?, vm)
464+ zelf . repeat ( value. try_to_primitive ( vm) ?, vm)
512465 }
513466
514467 #[ pymethod( name = "__mod__" ) ]
@@ -522,47 +475,79 @@ impl PyBytes {
522475 vm. ctx . not_implemented ( )
523476 }
524477
525- /// Return a string decoded from the given bytes.
526- /// Default encoding is 'utf-8'.
527- /// Default errors is 'strict', meaning that encoding errors raise a UnicodeError.
528- /// Other possible values are 'ignore', 'replace'
529- /// For a list of possible encodings,
530- /// see https://docs.python.org/3/library/codecs.html#standard-encodings
531- /// currently, only 'utf-8' and 'ascii' emplemented
532- #[ pymethod]
533- fn decode ( zelf : PyRef < Self > , args : DecodeArgs , vm : & VirtualMachine ) -> PyResult < PyStrRef > {
534- bytes_decode ( zelf. into ( ) , args, vm)
535- }
536-
537478 #[ pymethod( magic) ]
538479 fn getnewargs ( & self , vm : & VirtualMachine ) -> PyTupleRef {
539480 let param: Vec < PyObjectRef > = self . elements ( ) . map ( |x| x. to_pyobject ( vm) ) . collect ( ) ;
540481 PyTuple :: new_ref ( param, & vm. ctx )
541482 }
483+ }
542484
485+ #[ pyclass]
486+ impl Py < PyBytes > {
543487 #[ pymethod( magic) ]
544488 fn reduce_ex (
545- zelf : PyRef < Self > ,
489+ & self ,
546490 _proto : usize ,
547491 vm : & VirtualMachine ,
548492 ) -> ( PyTypeRef , PyTupleRef , Option < PyDictRef > ) {
549- Self :: reduce ( zelf , vm)
493+ Self :: reduce ( self , vm)
550494 }
551495
552496 #[ pymethod( magic) ]
553- fn reduce (
554- zelf : PyRef < Self > ,
555- vm : & VirtualMachine ,
556- ) -> ( PyTypeRef , PyTupleRef , Option < PyDictRef > ) {
557- let bytes = PyBytes :: from ( zelf. to_vec ( ) ) . to_pyobject ( vm) ;
497+ fn reduce ( & self , vm : & VirtualMachine ) -> ( PyTypeRef , PyTupleRef , Option < PyDictRef > ) {
498+ let bytes = PyBytes :: from ( self . to_vec ( ) ) . to_pyobject ( vm) ;
558499 (
559- zelf . class ( ) . to_owned ( ) ,
500+ self . class ( ) . to_owned ( ) ,
560501 PyTuple :: new_ref ( vec ! [ bytes] , & vm. ctx ) ,
561- zelf . as_object ( ) . dict ( ) ,
502+ self . as_object ( ) . dict ( ) ,
562503 )
563504 }
564505}
565506
507+ #[ pyclass]
508+ impl PyRef < PyBytes > {
509+ #[ pymethod( magic) ]
510+ fn bytes ( self , vm : & VirtualMachine ) -> PyRef < PyBytes > {
511+ if self . is ( vm. ctx . types . bytes_type ) {
512+ self
513+ } else {
514+ PyBytes :: from ( self . inner . clone ( ) ) . into_ref ( vm)
515+ }
516+ }
517+
518+ #[ pymethod]
519+ fn lstrip ( self , chars : OptionalOption < PyBytesInner > , vm : & VirtualMachine ) -> PyRef < PyBytes > {
520+ let stripped = self . inner . lstrip ( chars) ;
521+ if stripped == self . as_bytes ( ) {
522+ self
523+ } else {
524+ vm. ctx . new_bytes ( stripped. to_vec ( ) )
525+ }
526+ }
527+
528+ #[ pymethod]
529+ fn rstrip ( self , chars : OptionalOption < PyBytesInner > , vm : & VirtualMachine ) -> PyRef < PyBytes > {
530+ let stripped = self . inner . rstrip ( chars) ;
531+ if stripped == self . as_bytes ( ) {
532+ self
533+ } else {
534+ vm. ctx . new_bytes ( stripped. to_vec ( ) )
535+ }
536+ }
537+
538+ /// Return a string decoded from the given bytes.
539+ /// Default encoding is 'utf-8'.
540+ /// Default errors is 'strict', meaning that encoding errors raise a UnicodeError.
541+ /// Other possible values are 'ignore', 'replace'
542+ /// For a list of possible encodings,
543+ /// see https://docs.python.org/3/library/codecs.html#standard-encodings
544+ /// currently, only 'utf-8' and 'ascii' emplemented
545+ #[ pymethod]
546+ fn decode ( self , args : DecodeArgs , vm : & VirtualMachine ) -> PyResult < PyStrRef > {
547+ bytes_decode ( self . into ( ) , args, vm)
548+ }
549+ }
550+
566551static BUFFER_METHODS : BufferMethods = BufferMethods {
567552 obj_bytes : |buffer| buffer. obj_as :: < PyBytes > ( ) . as_bytes ( ) . into ( ) ,
568553 obj_bytes_mut : |_| panic ! ( ) ,
@@ -605,11 +590,10 @@ impl AsSequence for PyBytes {
605590 . map( |x| vm. ctx. new_bytes( x) . into( ) )
606591 } ) ,
607592 repeat : atomic_func ! ( |seq, n, vm| {
608- if let Ok ( zelf) = seq. obj. to_owned( ) . downcast:: <PyBytes >( ) {
609- PyBytes :: repeat( zelf, n, vm) . to_pyresult( vm)
610- } else {
611- Err ( vm. new_type_error( "bad argument type for built-in operation" . to_owned( ) ) )
612- }
593+ let zelf = seq. obj. to_owned( ) . downcast:: <PyBytes >( ) . map_err( |_| {
594+ vm. new_type_error( "bad argument type for built-in operation" . to_owned( ) )
595+ } ) ?;
596+ zelf. repeat( n, vm) . to_pyresult( vm)
613597 } ) ,
614598 item : atomic_func ! ( |seq, i, vm| {
615599 PyBytes :: sequence_downcast( seq)
0 commit comments