@@ -560,7 +560,7 @@ impl PyBaseException {
560560}
561561
562562#[ pyclass(
563- with( PyRef , Constructor , Initializer , Representable ) ,
563+ with( Py , PyRef , Constructor , Initializer , Representable ) ,
564564 flags( BASETYPE , HAS_DICT )
565565) ]
566566impl PyBaseException {
@@ -633,15 +633,18 @@ impl PyBaseException {
633633 fn set_suppress_context ( & self , suppress_context : bool ) {
634634 self . suppress_context . store ( suppress_context) ;
635635 }
636+ }
636637
638+ #[ pyclass]
639+ impl Py < PyBaseException > {
637640 #[ pymethod]
638- pub ( super ) fn __str__ ( & self , vm : & VirtualMachine ) -> PyStrRef {
641+ pub ( super ) fn __str__ ( & self , vm : & VirtualMachine ) -> PyResult < PyStrRef > {
639642 let str_args = vm. exception_args_as_string ( self . args ( ) , true ) ;
640- match str_args. into_iter ( ) . exactly_one ( ) {
643+ Ok ( match str_args. into_iter ( ) . exactly_one ( ) {
641644 Err ( i) if i. len ( ) == 0 => vm. ctx . empty_str . to_owned ( ) ,
642645 Ok ( s) => s,
643646 Err ( i) => PyStr :: from ( format ! ( "({})" , i. format( ", " ) ) ) . into_ref ( & vm. ctx ) ,
644- }
647+ } )
645648 }
646649}
647650
@@ -1527,16 +1530,16 @@ pub(super) mod types {
15271530 #[ pyexception]
15281531 impl PyKeyError {
15291532 #[ pymethod]
1530- fn __str__ ( exc : PyBaseExceptionRef , vm : & VirtualMachine ) -> PyStrRef {
1531- let args = exc . args ( ) ;
1532- if args. len ( ) == 1 {
1533+ fn __str__ ( zelf : & Py < PyBaseException > , vm : & VirtualMachine ) -> PyResult < PyStrRef > {
1534+ let args = zelf . args ( ) ;
1535+ Ok ( if args. len ( ) == 1 {
15331536 vm. exception_args_as_string ( args, false )
15341537 . into_iter ( )
15351538 . exactly_one ( )
15361539 . unwrap ( )
15371540 } else {
1538- exc . __str__ ( vm)
1539- }
1541+ zelf . __str__ ( vm) ?
1542+ } )
15401543 }
15411544 }
15421545
@@ -1731,8 +1734,8 @@ pub(super) mod types {
17311734 #[ pyexception( with( Constructor , Initializer ) ) ]
17321735 impl PyOSError {
17331736 #[ pymethod]
1734- fn __str__ ( exc : PyBaseExceptionRef , vm : & VirtualMachine ) -> PyResult < PyStrRef > {
1735- let obj = exc . as_object ( ) . to_owned ( ) ;
1737+ fn __str__ ( zelf : & Py < PyBaseException > , vm : & VirtualMachine ) -> PyResult < PyStrRef > {
1738+ let obj = zelf . as_object ( ) ;
17361739
17371740 // Get OSError fields directly
17381741 let errno_field = obj. get_attr ( "errno" , vm) . ok ( ) . filter ( |v| !vm. is_none ( v) ) ;
@@ -1819,7 +1822,7 @@ pub(super) mod types {
18191822 }
18201823
18211824 // fallback to BaseException.__str__
1822- Ok ( exc . __str__ ( vm) )
1825+ zelf . __str__ ( vm)
18231826 }
18241827
18251828 #[ pymethod]
@@ -2026,7 +2029,7 @@ pub(super) mod types {
20262029 #[ pyexception( with( Initializer ) ) ]
20272030 impl PySyntaxError {
20282031 #[ pymethod]
2029- fn __str__ ( exc : PyBaseExceptionRef , vm : & VirtualMachine ) -> PyStrRef {
2032+ fn __str__ ( zelf : & Py < PyBaseException > , vm : & VirtualMachine ) -> PyResult < PyStrRef > {
20302033 fn basename ( filename : & str ) -> & str {
20312034 let splitted = if cfg ! ( windows) {
20322035 filename. rsplit ( & [ '/' , '\\' ] ) . next ( )
@@ -2036,24 +2039,24 @@ pub(super) mod types {
20362039 splitted. unwrap_or ( filename)
20372040 }
20382041
2039- let maybe_lineno = exc . as_object ( ) . get_attr ( "lineno" , vm) . ok ( ) . map ( |obj| {
2042+ let maybe_lineno = zelf . as_object ( ) . get_attr ( "lineno" , vm) . ok ( ) . map ( |obj| {
20402043 obj. str ( vm)
20412044 . unwrap_or_else ( |_| vm. ctx . new_str ( "<lineno str() failed>" ) )
20422045 } ) ;
2043- let maybe_filename = exc . as_object ( ) . get_attr ( "filename" , vm) . ok ( ) . map ( |obj| {
2046+ let maybe_filename = zelf . as_object ( ) . get_attr ( "filename" , vm) . ok ( ) . map ( |obj| {
20442047 obj. str ( vm)
20452048 . unwrap_or_else ( |_| vm. ctx . new_str ( "<filename str() failed>" ) )
20462049 } ) ;
20472050
2048- let args = exc . args ( ) ;
2051+ let args = zelf . args ( ) ;
20492052
20502053 let msg = if args. len ( ) == 1 {
20512054 vm. exception_args_as_string ( args, false )
20522055 . into_iter ( )
20532056 . exactly_one ( )
20542057 . unwrap ( )
20552058 } else {
2056- return exc . __str__ ( vm) ;
2059+ return zelf . __str__ ( vm) ;
20572060 } ;
20582061
20592062 let msg_with_location_info: String = match ( maybe_lineno, maybe_filename) {
@@ -2069,7 +2072,7 @@ pub(super) mod types {
20692072 ( None , None ) => msg. to_string ( ) ,
20702073 } ;
20712074
2072- vm. ctx . new_str ( msg_with_location_info)
2075+ Ok ( vm. ctx . new_str ( msg_with_location_info) )
20732076 }
20742077 }
20752078
@@ -2178,29 +2181,32 @@ pub(super) mod types {
21782181 #[ pyexception( with( Initializer ) ) ]
21792182 impl PyUnicodeDecodeError {
21802183 #[ pymethod]
2181- fn __str__ ( exc : PyBaseExceptionRef , vm : & VirtualMachine ) -> PyResult < String > {
2182- let Ok ( object) = exc . as_object ( ) . get_attr ( "object" , vm) else {
2183- return Ok ( "" . to_owned ( ) ) ;
2184+ fn __str__ ( zelf : & Py < PyBaseException > , vm : & VirtualMachine ) -> PyResult < PyStrRef > {
2185+ let Ok ( object) = zelf . as_object ( ) . get_attr ( "object" , vm) else {
2186+ return Ok ( vm . ctx . empty_str . to_owned ( ) ) ;
21842187 } ;
21852188 let object: ArgBytesLike = object. try_into_value ( vm) ?;
2186- let encoding: PyStrRef = exc
2189+ let encoding: PyStrRef = zelf
21872190 . as_object ( )
21882191 . get_attr ( "encoding" , vm) ?
21892192 . try_into_value ( vm) ?;
2190- let start: usize = exc. as_object ( ) . get_attr ( "start" , vm) ?. try_into_value ( vm) ?;
2191- let end: usize = exc. as_object ( ) . get_attr ( "end" , vm) ?. try_into_value ( vm) ?;
2192- let reason: PyStrRef = exc. as_object ( ) . get_attr ( "reason" , vm) ?. try_into_value ( vm) ?;
2193- if start < object. len ( ) && end <= object. len ( ) && end == start + 1 {
2193+ let start: usize = zelf. as_object ( ) . get_attr ( "start" , vm) ?. try_into_value ( vm) ?;
2194+ let end: usize = zelf. as_object ( ) . get_attr ( "end" , vm) ?. try_into_value ( vm) ?;
2195+ let reason: PyStrRef = zelf
2196+ . as_object ( )
2197+ . get_attr ( "reason" , vm) ?
2198+ . try_into_value ( vm) ?;
2199+ Ok ( vm. ctx . new_str ( if start < object. len ( ) && end <= object. len ( ) && end == start + 1 {
21942200 let b = object. borrow_buf ( ) [ start] ;
2195- Ok ( format ! (
2201+ format ! (
21962202 "'{encoding}' codec can't decode byte {b:#02x} in position {start}: {reason}"
2197- ) )
2203+ )
21982204 } else {
2199- Ok ( format ! (
2205+ format ! (
22002206 "'{encoding}' codec can't decode bytes in position {start}-{}: {reason}" ,
22012207 end - 1 ,
2202- ) )
2203- }
2208+ )
2209+ } ) )
22042210 }
22052211 }
22062212
@@ -2232,30 +2238,33 @@ pub(super) mod types {
22322238 #[ pyexception( with( Initializer ) ) ]
22332239 impl PyUnicodeEncodeError {
22342240 #[ pymethod]
2235- fn __str__ ( exc : PyBaseExceptionRef , vm : & VirtualMachine ) -> PyResult < String > {
2236- let Ok ( object) = exc . as_object ( ) . get_attr ( "object" , vm) else {
2237- return Ok ( "" . to_owned ( ) ) ;
2241+ fn __str__ ( zelf : & Py < PyBaseException > , vm : & VirtualMachine ) -> PyResult < PyStrRef > {
2242+ let Ok ( object) = zelf . as_object ( ) . get_attr ( "object" , vm) else {
2243+ return Ok ( vm . ctx . empty_str . to_owned ( ) ) ;
22382244 } ;
22392245 let object: PyStrRef = object. try_into_value ( vm) ?;
2240- let encoding: PyStrRef = exc
2246+ let encoding: PyStrRef = zelf
22412247 . as_object ( )
22422248 . get_attr ( "encoding" , vm) ?
22432249 . try_into_value ( vm) ?;
2244- let start: usize = exc. as_object ( ) . get_attr ( "start" , vm) ?. try_into_value ( vm) ?;
2245- let end: usize = exc. as_object ( ) . get_attr ( "end" , vm) ?. try_into_value ( vm) ?;
2246- let reason: PyStrRef = exc. as_object ( ) . get_attr ( "reason" , vm) ?. try_into_value ( vm) ?;
2247- if start < object. char_len ( ) && end <= object. char_len ( ) && end == start + 1 {
2250+ let start: usize = zelf. as_object ( ) . get_attr ( "start" , vm) ?. try_into_value ( vm) ?;
2251+ let end: usize = zelf. as_object ( ) . get_attr ( "end" , vm) ?. try_into_value ( vm) ?;
2252+ let reason: PyStrRef = zelf
2253+ . as_object ( )
2254+ . get_attr ( "reason" , vm) ?
2255+ . try_into_value ( vm) ?;
2256+ Ok ( vm. ctx . new_str ( if start < object. char_len ( ) && end <= object. char_len ( ) && end == start + 1 {
22482257 let ch = object. as_wtf8 ( ) . code_points ( ) . nth ( start) . unwrap ( ) ;
2249- Ok ( format ! (
2258+ format ! (
22502259 "'{encoding}' codec can't encode character '{}' in position {start}: {reason}" ,
22512260 UnicodeEscapeCodepoint ( ch)
2252- ) )
2261+ )
22532262 } else {
2254- Ok ( format ! (
2263+ format ! (
22552264 "'{encoding}' codec can't encode characters in position {start}-{}: {reason}" ,
22562265 end - 1 ,
2257- ) )
2258- }
2266+ )
2267+ } ) )
22592268 }
22602269 }
22612270
@@ -2286,26 +2295,31 @@ pub(super) mod types {
22862295 #[ pyexception( with( Initializer ) ) ]
22872296 impl PyUnicodeTranslateError {
22882297 #[ pymethod]
2289- fn __str__ ( exc : PyBaseExceptionRef , vm : & VirtualMachine ) -> PyResult < String > {
2290- let Ok ( object) = exc . as_object ( ) . get_attr ( "object" , vm) else {
2291- return Ok ( "" . to_owned ( ) ) ;
2298+ fn __str__ ( zelf : & Py < PyBaseException > , vm : & VirtualMachine ) -> PyResult < PyStrRef > {
2299+ let Ok ( object) = zelf . as_object ( ) . get_attr ( "object" , vm) else {
2300+ return Ok ( vm . ctx . empty_str . to_owned ( ) ) ;
22922301 } ;
22932302 let object: PyStrRef = object. try_into_value ( vm) ?;
2294- let start: usize = exc. as_object ( ) . get_attr ( "start" , vm) ?. try_into_value ( vm) ?;
2295- let end: usize = exc. as_object ( ) . get_attr ( "end" , vm) ?. try_into_value ( vm) ?;
2296- let reason: PyStrRef = exc. as_object ( ) . get_attr ( "reason" , vm) ?. try_into_value ( vm) ?;
2297- if start < object. char_len ( ) && end <= object. char_len ( ) && end == start + 1 {
2298- let ch = object. as_wtf8 ( ) . code_points ( ) . nth ( start) . unwrap ( ) ;
2299- Ok ( format ! (
2300- "can't translate character '{}' in position {start}: {reason}" ,
2301- UnicodeEscapeCodepoint ( ch)
2302- ) )
2303- } else {
2304- Ok ( format ! (
2305- "can't translate characters in position {start}-{}: {reason}" ,
2306- end - 1 ,
2307- ) )
2308- }
2303+ let start: usize = zelf. as_object ( ) . get_attr ( "start" , vm) ?. try_into_value ( vm) ?;
2304+ let end: usize = zelf. as_object ( ) . get_attr ( "end" , vm) ?. try_into_value ( vm) ?;
2305+ let reason: PyStrRef = zelf
2306+ . as_object ( )
2307+ . get_attr ( "reason" , vm) ?
2308+ . try_into_value ( vm) ?;
2309+ Ok ( vm. ctx . new_str (
2310+ if start < object. char_len ( ) && end <= object. char_len ( ) && end == start + 1 {
2311+ let ch = object. as_wtf8 ( ) . code_points ( ) . nth ( start) . unwrap ( ) ;
2312+ format ! (
2313+ "can't translate character '{}' in position {start}: {reason}" ,
2314+ UnicodeEscapeCodepoint ( ch)
2315+ )
2316+ } else {
2317+ format ! (
2318+ "can't translate characters in position {start}-{}: {reason}" ,
2319+ end - 1 ,
2320+ )
2321+ } ,
2322+ ) )
23092323 }
23102324 }
23112325
0 commit comments