@@ -1040,7 +1040,7 @@ pub(super) mod types {
10401040 builtins:: { traceback:: PyTracebackRef , PyInt , PyTupleRef , PyTypeRef } ,
10411041 convert:: ToPyResult ,
10421042 function:: FuncArgs ,
1043- PyObjectRef , PyRef , PyResult , VirtualMachine ,
1043+ AsObject , PyObjectRef , PyPayload , PyRef , PyResult , VirtualMachine ,
10441044 } ;
10451045 use crossbeam_utils:: atomic:: AtomicCell ;
10461046 #[ cfg_attr( target_arch = "wasm32" , allow( unused_imports) ) ]
@@ -1240,8 +1240,9 @@ pub(super) mod types {
12401240 os_error,
12411241 "Base class for I/O related errors." ,
12421242 os_error_new,
1243- base_exception_init ,
1243+ os_error_init ,
12441244 }
1245+
12451246 #[ cfg( not( target_arch = "wasm32" ) ) ]
12461247 fn os_error_optional_new (
12471248 args : Vec < PyObjectRef > ,
@@ -1261,25 +1262,78 @@ pub(super) mod types {
12611262 }
12621263 #[ cfg( not( target_arch = "wasm32" ) ) ]
12631264 fn os_error_new ( cls : PyTypeRef , args : FuncArgs , vm : & VirtualMachine ) -> PyResult {
1264- // We need this method, because of how `CPython` copies `init`
1265- // from `BaseException` in `SimpleExtendsException` macro.
1266- // See: `BaseException_new`
1267- if cls. name ( ) . deref ( ) == vm. ctx . exceptions . os_error . name ( ) . deref ( ) {
1268- match os_error_optional_new ( args. args . to_vec ( ) , vm) {
1269- Some ( error) => error. to_pyresult ( vm) ,
1270- None => PyBaseException :: slot_new ( cls, args, vm) ,
1271- }
1272- } else {
1273- PyBaseException :: slot_new ( cls, args, vm)
1274- }
1265+ let exc_self: PyBaseExceptionRef =
1266+ if cls. name ( ) . deref ( ) == vm. ctx . exceptions . os_error . name ( ) . deref ( ) {
1267+ match os_error_optional_new ( args. args . to_vec ( ) , vm) {
1268+ Some ( error) => error,
1269+ None => PyBaseException :: new ( args. args . to_vec ( ) , vm)
1270+ . into_ref_with_type ( vm, cls)
1271+ . unwrap ( ) ,
1272+ }
1273+ } else {
1274+ PyBaseException :: new ( args. args . to_vec ( ) , vm)
1275+ . into_ref_with_type ( vm, cls)
1276+ . unwrap ( )
1277+ } ;
1278+
1279+ os_error_parse_args ( & exc_self, & args, vm) ?;
1280+ exc_self. to_pyresult ( vm)
12751281 }
12761282 #[ cfg( target_arch = "wasm32" ) ]
12771283 fn os_error_new ( cls : PyTypeRef , args : FuncArgs , vm : & VirtualMachine ) -> PyResult {
1278- PyBaseException :: slot_new ( cls, args, vm)
1284+ let exc_self = PyBaseException :: new ( args. args . to_vec ( ) , vm)
1285+ . into_ref_with_type ( vm, cls)
1286+ . unwrap ( ) ;
1287+ os_error_parse_args ( & exc_self, & args, vm) ?;
1288+ exc_self. into_pyresult ( vm)
12791289 }
12801290
1281- fn base_exception_init ( zelf : PyObjectRef , args : FuncArgs , vm : & VirtualMachine ) -> PyResult < ( ) > {
1282- PyBaseException :: init ( zelf, args, vm)
1291+ fn os_error_parse_args (
1292+ exc_self : & PyBaseExceptionRef ,
1293+ args : & FuncArgs ,
1294+ vm : & VirtualMachine ,
1295+ ) -> PyResult < ( ) > {
1296+ os_error_set_attr ( exc_self, args, vm, "errno" , 0 ) ?;
1297+ os_error_set_attr ( exc_self, args, vm, "strerror" , 1 ) ?;
1298+
1299+ os_error_set_attr ( exc_self, args, vm, "filename" , 2 ) ?;
1300+ #[ cfg( windows) ]
1301+ os_error_set_attr ( exc_self, args, vm, "winerror" , 3 ) ?;
1302+ os_error_set_attr ( exc_self, args, vm, "filename2" , 4 ) ?;
1303+ Ok ( ( ) )
1304+ }
1305+
1306+ fn os_error_set_attr (
1307+ exc_self : & PyBaseExceptionRef ,
1308+ args : & FuncArgs ,
1309+ vm : & VirtualMachine ,
1310+ attr_name : & str ,
1311+ arg_idx : usize ,
1312+ ) -> PyResult < ( ) > {
1313+ let exc_self = exc_self. as_object ( ) ;
1314+
1315+ if let Some ( arg) = args. args . as_slice ( ) . get ( arg_idx) . cloned ( ) {
1316+ exc_self. set_attr ( attr_name, arg, vm) ?;
1317+ } else {
1318+ exc_self. set_attr ( attr_name, vm. ctx . none ( ) , vm) ?;
1319+ }
1320+
1321+ Ok ( ( ) )
1322+ }
1323+
1324+ fn os_error_init ( zelf : PyObjectRef , args : FuncArgs , vm : & VirtualMachine ) -> PyResult < ( ) > {
1325+ PyBaseException :: init ( zelf. clone ( ) , args. clone ( ) , vm) ?;
1326+
1327+ let zelf: PyRef < PyBaseException > = zelf. try_into_value ( vm) ?;
1328+ if zelf. class ( ) . name ( ) . deref ( ) == "BlockingIOError" {
1329+ os_error_set_attr ( & zelf, & args, vm, "errno" , 0 ) ?;
1330+ os_error_set_attr ( & zelf, & args, vm, "strerror" , 1 ) ?;
1331+ os_error_set_attr ( & zelf, & args, vm, "characters_written" , 2 ) ?;
1332+ } else {
1333+ os_error_parse_args ( & zelf, & args, vm) ?;
1334+ }
1335+
1336+ Ok ( ( ) )
12831337 }
12841338
12851339 define_exception ! {
@@ -1288,6 +1342,7 @@ pub(super) mod types {
12881342 blocking_io_error,
12891343 "I/O operation would block."
12901344 }
1345+
12911346 define_exception ! {
12921347 PyChildProcessError ,
12931348 PyOSError ,
0 commit comments