@@ -21,6 +21,9 @@ use itertools::Itertools;
21
21
use malachite_bigint:: BigInt ;
22
22
use num_traits:: ToPrimitive ;
23
23
24
+ const STRING_WITHOUT_ENCODING : & str = "string argument without an encoding" ;
25
+ const ENCODING_WITHOUT_STRING : & str = "encoding without a string argument" ;
26
+
24
27
#[ derive( Debug , Default , Clone ) ]
25
28
pub struct PyBytesInner {
26
29
pub ( super ) elements : Vec < u8 > ,
@@ -75,6 +78,18 @@ impl ByteInnerNewOptions {
75
78
Ok ( vec ! [ 0 ; size] . into ( ) )
76
79
}
77
80
81
+ fn handle_object_fallback ( obj : PyObjectRef , vm : & VirtualMachine ) -> PyResult < PyBytesInner > {
82
+ match_class ! ( match obj {
83
+ i @ PyInt => {
84
+ Self :: get_value_from_size( i, vm)
85
+ }
86
+ _s @ PyStr => Err ( vm. new_type_error( STRING_WITHOUT_ENCODING . to_owned( ) ) ) ,
87
+ obj => {
88
+ Self :: get_value_from_source( obj, vm)
89
+ }
90
+ } )
91
+ }
92
+
78
93
pub fn get_bytes ( self , cls : PyTypeRef , vm : & VirtualMachine ) -> PyResult < PyBytesRef > {
79
94
let inner = match ( & self . source , & self . encoding , & self . errors ) {
80
95
( OptionalArg :: Present ( obj) , OptionalArg :: Missing , OptionalArg :: Missing ) => {
@@ -113,40 +128,48 @@ impl ByteInnerNewOptions {
113
128
}
114
129
115
130
pub fn get_bytearray_inner ( self , vm : & VirtualMachine ) -> PyResult < PyBytesInner > {
116
- const STRING_WITHOUT_ENCODING : & str = "string argument without an encoding" ;
117
- const ENCODING_WITHOUT_STRING : & str = "encoding without a string argument" ;
118
-
119
131
match ( self . source , self . encoding , self . errors ) {
120
132
( OptionalArg :: Present ( obj) , OptionalArg :: Missing , OptionalArg :: Missing ) => {
121
- match_class ! ( match obj {
122
- i @ PyInt => {
123
- Ok ( Self :: get_value_from_size( i, vm) ?)
124
- }
125
- _s @ PyStr => Err ( STRING_WITHOUT_ENCODING ) ,
126
- obj => {
127
- Ok ( Self :: get_value_from_source( obj, vm) ?)
133
+ // Try __index__ first to handle int-like objects that might raise custom exceptions
134
+ if let Some ( index_result) = obj. try_index_opt ( vm) {
135
+ match index_result {
136
+ Ok ( index) => Self :: get_value_from_size ( index, vm) ,
137
+ Err ( e) => {
138
+ // Only propagate non-TypeError exceptions
139
+ // TypeError means the object doesn't support __index__, so fall back
140
+ if e. fast_isinstance ( vm. ctx . exceptions . type_error ) {
141
+ // Fall back to treating as buffer-like object
142
+ Self :: handle_object_fallback ( obj, vm)
143
+ } else {
144
+ // Propagate other exceptions (e.g., ZeroDivisionError)
145
+ Err ( e)
146
+ }
147
+ }
128
148
}
129
- } )
149
+ } else {
150
+ Self :: handle_object_fallback ( obj, vm)
151
+ }
130
152
}
131
153
( OptionalArg :: Present ( obj) , OptionalArg :: Present ( encoding) , errors) => {
132
154
if let Ok ( s) = obj. downcast :: < PyStr > ( ) {
133
- Ok ( Self :: get_value_from_string ( s, encoding, errors, vm) ? )
155
+ Self :: get_value_from_string ( s, encoding, errors, vm)
134
156
} else {
135
- Err ( ENCODING_WITHOUT_STRING )
157
+ Err ( vm . new_type_error ( ENCODING_WITHOUT_STRING . to_owned ( ) ) )
136
158
}
137
159
}
138
160
( OptionalArg :: Missing , OptionalArg :: Missing , OptionalArg :: Missing ) => {
139
161
Ok ( PyBytesInner :: default ( ) )
140
162
}
141
- ( OptionalArg :: Missing , OptionalArg :: Present ( _) , _) => Err ( ENCODING_WITHOUT_STRING ) ,
163
+ ( OptionalArg :: Missing , OptionalArg :: Present ( _) , _) => {
164
+ Err ( vm. new_type_error ( ENCODING_WITHOUT_STRING . to_owned ( ) ) )
165
+ }
142
166
( OptionalArg :: Missing , _, OptionalArg :: Present ( _) ) => {
143
- Err ( "errors without a string argument" )
167
+ Err ( vm . new_type_error ( "errors without a string argument" . to_owned ( ) ) )
144
168
}
145
169
( OptionalArg :: Present ( _) , OptionalArg :: Missing , OptionalArg :: Present ( _) ) => {
146
- Err ( STRING_WITHOUT_ENCODING )
170
+ Err ( vm . new_type_error ( STRING_WITHOUT_ENCODING . to_owned ( ) ) )
147
171
}
148
172
}
149
- . map_err ( |e| vm. new_type_error ( e. to_owned ( ) ) )
150
173
}
151
174
}
152
175
0 commit comments