@@ -92,15 +92,64 @@ pub(crate) fn init(context: &Context) {
9292}
9393
9494impl Constructor for PyBytes {
95- type Args = ByteInnerNewOptions ;
95+ type Args = Vec < u8 > ;
9696
9797 fn slot_new ( cls : PyTypeRef , args : FuncArgs , vm : & VirtualMachine ) -> PyResult {
98- let options: Self :: Args = args. bind ( vm) ?;
99- options. get_bytes ( cls, vm) . to_pyresult ( vm)
98+ let options: ByteInnerNewOptions = args. bind ( vm) ?;
99+
100+ // Optimizations for exact bytes type
101+ if cls. is ( vm. ctx . types . bytes_type ) {
102+ // Return empty bytes singleton
103+ if options. source . is_missing ( )
104+ && options. encoding . is_missing ( )
105+ && options. errors . is_missing ( )
106+ {
107+ return Ok ( vm. ctx . empty_bytes . clone ( ) . into ( ) ) ;
108+ }
109+
110+ // Return exact bytes as-is
111+ if let OptionalArg :: Present ( ref obj) = options. source
112+ && options. encoding . is_missing ( )
113+ && options. errors . is_missing ( )
114+ && let Ok ( b) = obj. clone ( ) . downcast_exact :: < PyBytes > ( vm)
115+ {
116+ return Ok ( b. into_pyref ( ) . into ( ) ) ;
117+ }
118+ }
119+
120+ // Handle __bytes__ method - may return PyBytes directly
121+ if let OptionalArg :: Present ( ref obj) = options. source
122+ && options. encoding . is_missing ( )
123+ && options. errors . is_missing ( )
124+ && let Some ( bytes_method) = vm. get_method ( obj. clone ( ) , identifier ! ( vm, __bytes__) )
125+ {
126+ let bytes = bytes_method?. call ( ( ) , vm) ?;
127+ // If exact bytes type and __bytes__ returns bytes, use it directly
128+ if cls. is ( vm. ctx . types . bytes_type )
129+ && let Ok ( b) = bytes. clone ( ) . downcast :: < PyBytes > ( )
130+ {
131+ return Ok ( b. into ( ) ) ;
132+ }
133+ // Otherwise convert to Vec<u8>
134+ let inner = PyBytesInner :: try_from_borrowed_object ( vm, & bytes) ?;
135+ let payload = Self :: py_new ( & cls, inner. elements , vm) ?;
136+ return payload. into_ref_with_type ( vm, cls) . map ( Into :: into) ;
137+ }
138+
139+ // Fallback to get_bytearray_inner
140+ let elements = options. get_bytearray_inner ( vm) ?. elements ;
141+
142+ // Return empty bytes singleton for exact bytes types
143+ if elements. is_empty ( ) && cls. is ( vm. ctx . types . bytes_type ) {
144+ return Ok ( vm. ctx . empty_bytes . clone ( ) . into ( ) ) ;
145+ }
146+
147+ let payload = Self :: py_new ( & cls, elements, vm) ?;
148+ payload. into_ref_with_type ( vm, cls) . map ( Into :: into)
100149 }
101150
102- fn py_new ( _cls : & Py < PyType > , _args : Self :: Args , _vm : & VirtualMachine ) -> PyResult < Self > {
103- unreachable ! ( "use slot_new" )
151+ fn py_new ( _cls : & Py < PyType > , elements : Self :: Args , _vm : & VirtualMachine ) -> PyResult < Self > {
152+ Ok ( Self :: from ( elements ) )
104153 }
105154}
106155
0 commit comments