@@ -3730,7 +3730,7 @@ mod _io {
3730
3730
mod fileio {
3731
3731
use super :: { Offset , _io:: * } ;
3732
3732
use crate :: {
3733
- builtins:: { PyStr , PyStrRef } ,
3733
+ builtins:: { PyBaseExceptionRef , PyStr , PyStrRef } ,
3734
3734
common:: crt_fd:: Fd ,
3735
3735
convert:: ToPyException ,
3736
3736
function:: { ArgBytesLike , ArgMemoryBuffer , OptionalArg , OptionalOption } ,
@@ -3947,6 +3947,20 @@ mod fileio {
3947
3947
flags( BASETYPE , HAS_DICT )
3948
3948
) ]
3949
3949
impl FileIO {
3950
+ fn io_error (
3951
+ zelf : & Py < Self > ,
3952
+ error : std:: io:: Error ,
3953
+ vm : & VirtualMachine ,
3954
+ ) -> PyBaseExceptionRef {
3955
+ let exc = error. to_pyexception ( vm) ;
3956
+ if let Ok ( name) = zelf. as_object ( ) . get_attr ( "name" , vm) {
3957
+ exc. as_object ( )
3958
+ . set_attr ( "filename" , name, vm)
3959
+ . expect ( "OSError.filename set must success" ) ;
3960
+ }
3961
+ exc
3962
+ }
3963
+
3950
3964
#[ pygetset]
3951
3965
fn closed ( & self ) -> bool {
3952
3966
self . fd . load ( ) < 0
@@ -4006,79 +4020,87 @@ mod fileio {
4006
4020
}
4007
4021
4008
4022
#[ pymethod]
4009
- fn read ( & self , read_byte : OptionalSize , vm : & VirtualMachine ) -> PyResult < Vec < u8 > > {
4010
- if !self . mode . load ( ) . contains ( Mode :: READABLE ) {
4023
+ fn read (
4024
+ zelf : & Py < Self > ,
4025
+ read_byte : OptionalSize ,
4026
+ vm : & VirtualMachine ,
4027
+ ) -> PyResult < Vec < u8 > > {
4028
+ if !zelf. mode . load ( ) . contains ( Mode :: READABLE ) {
4011
4029
return Err ( new_unsupported_operation (
4012
4030
vm,
4013
4031
"File or stream is not readable" . to_owned ( ) ,
4014
4032
) ) ;
4015
4033
}
4016
- let mut handle = self . get_fd ( vm) ?;
4034
+ let mut handle = zelf . get_fd ( vm) ?;
4017
4035
let bytes = if let Some ( read_byte) = read_byte. to_usize ( ) {
4018
4036
let mut bytes = vec ! [ 0 ; read_byte] ;
4019
4037
let n = handle
4020
4038
. read ( & mut bytes)
4021
- . map_err ( |err| err . to_pyexception ( vm) ) ?;
4039
+ . map_err ( |err| Self :: io_error ( zelf , err , vm) ) ?;
4022
4040
bytes. truncate ( n) ;
4023
4041
bytes
4024
4042
} else {
4025
4043
let mut bytes = vec ! [ ] ;
4026
4044
handle
4027
4045
. read_to_end ( & mut bytes)
4028
- . map_err ( |err| err . to_pyexception ( vm) ) ?;
4046
+ . map_err ( |err| Self :: io_error ( zelf , err , vm) ) ?;
4029
4047
bytes
4030
4048
} ;
4031
4049
4032
4050
Ok ( bytes)
4033
4051
}
4034
4052
4035
4053
#[ pymethod]
4036
- fn readinto ( & self , obj : ArgMemoryBuffer , vm : & VirtualMachine ) -> PyResult < usize > {
4037
- if !self . mode . load ( ) . contains ( Mode :: READABLE ) {
4054
+ fn readinto ( zelf : & Py < Self > , obj : ArgMemoryBuffer , vm : & VirtualMachine ) -> PyResult < usize > {
4055
+ if !zelf . mode . load ( ) . contains ( Mode :: READABLE ) {
4038
4056
return Err ( new_unsupported_operation (
4039
4057
vm,
4040
4058
"File or stream is not readable" . to_owned ( ) ,
4041
4059
) ) ;
4042
4060
}
4043
4061
4044
- let handle = self . get_fd ( vm) ?;
4062
+ let handle = zelf . get_fd ( vm) ?;
4045
4063
4046
4064
let mut buf = obj. borrow_buf_mut ( ) ;
4047
4065
let mut f = handle. take ( buf. len ( ) as _ ) ;
4048
- let ret = f. read ( & mut buf) . map_err ( |e| e. to_pyexception ( vm) ) ?;
4066
+ let ret = f
4067
+ . read ( & mut buf)
4068
+ . map_err ( |err| Self :: io_error ( zelf, err, vm) ) ?;
4049
4069
4050
4070
Ok ( ret)
4051
4071
}
4052
4072
4053
4073
#[ pymethod]
4054
- fn write ( & self , obj : ArgBytesLike , vm : & VirtualMachine ) -> PyResult < usize > {
4055
- if !self . mode . load ( ) . contains ( Mode :: WRITABLE ) {
4074
+ fn write ( zelf : & Py < Self > , obj : ArgBytesLike , vm : & VirtualMachine ) -> PyResult < usize > {
4075
+ if !zelf . mode . load ( ) . contains ( Mode :: WRITABLE ) {
4056
4076
return Err ( new_unsupported_operation (
4057
4077
vm,
4058
4078
"File or stream is not writable" . to_owned ( ) ,
4059
4079
) ) ;
4060
4080
}
4061
4081
4062
- let mut handle = self . get_fd ( vm) ?;
4082
+ let mut handle = zelf . get_fd ( vm) ?;
4063
4083
4064
4084
let len = obj
4065
4085
. with_ref ( |b| handle. write ( b) )
4066
- . map_err ( |err| err . to_pyexception ( vm) ) ?;
4086
+ . map_err ( |err| Self :: io_error ( zelf , err , vm) ) ?;
4067
4087
4068
4088
//return number of bytes written
4069
4089
Ok ( len)
4070
4090
}
4071
4091
4072
4092
#[ pymethod]
4073
- fn close ( zelf : PyRef < Self > , vm : & VirtualMachine ) -> PyResult < ( ) > {
4093
+ fn close ( zelf : & Py < Self > , vm : & VirtualMachine ) -> PyResult < ( ) > {
4074
4094
let res = iobase_close ( zelf. as_object ( ) , vm) ;
4075
4095
if !zelf. closefd . load ( ) {
4076
4096
zelf. fd . store ( -1 ) ;
4077
4097
return res;
4078
4098
}
4079
4099
let fd = zelf. fd . swap ( -1 ) ;
4080
4100
if fd >= 0 {
4081
- Fd ( fd) . close ( ) . map_err ( |e| e. to_pyexception ( vm) ) ?;
4101
+ Fd ( fd)
4102
+ . close ( )
4103
+ . map_err ( |err| Self :: io_error ( zelf, err, vm) ) ?;
4082
4104
}
4083
4105
res
4084
4106
}
0 commit comments