@@ -785,6 +785,22 @@ fn text_io_wrapper_seekable(_self: PyObjectRef) -> bool {
785785 true
786786}
787787
788+ fn text_io_wrapper_seek (
789+ instance : PyObjectRef ,
790+ offset : PyObjectRef ,
791+ how : OptionalArg ,
792+ vm : & VirtualMachine ,
793+ ) -> PyResult {
794+ let raw = vm. get_attribute ( instance, "buffer" ) ?;
795+ let args: Vec < _ > = std:: iter:: once ( offset) . chain ( how. into_option ( ) ) . collect ( ) ;
796+ vm. invoke ( & vm. get_attribute ( raw, "seek" ) ?, args)
797+ }
798+
799+ fn text_io_wrapper_tell ( instance : PyObjectRef , vm : & VirtualMachine ) -> PyResult {
800+ let raw = vm. get_attribute ( instance, "buffer" ) ?;
801+ vm. invoke ( & vm. get_attribute ( raw, "tell" ) ?, vec ! [ ] )
802+ }
803+
788804fn text_io_wrapper_read (
789805 instance : PyObjectRef ,
790806 size : OptionalOption < PyObjectRef > ,
@@ -930,16 +946,21 @@ fn split_mode_string(mode_string: &str) -> Result<(String, String), String> {
930946 Ok ( ( mode, typ. to_string ( ) ) )
931947}
932948
933- pub fn io_open ( vm : & VirtualMachine , args : PyFuncArgs ) -> PyResult {
934- arg_check ! (
935- vm,
936- args,
937- required = [ ( file, None ) ] ,
938- optional = [ ( mode, Some ( vm. ctx. str_type( ) ) ) ]
939- ) ;
949+ fn io_open_wrapper (
950+ file : PyObjectRef ,
951+ mode : OptionalArg < PyStringRef > ,
952+ vm : & VirtualMachine ,
953+ ) -> PyResult {
954+ io_open ( file, mode. as_ref ( ) . into_option ( ) . map ( |s| s. as_str ( ) ) , vm)
955+ }
956+ fn io_open_code ( file : PyObjectRef , vm : & VirtualMachine ) -> PyResult {
957+ // TODO: lifecycle hooks or something?
958+ io_open ( file, Some ( "rb" ) , vm)
959+ }
940960
961+ pub fn io_open ( file : PyObjectRef , mode : Option < & str > , vm : & VirtualMachine ) -> PyResult {
941962 // mode is optional: 'rt' is the default mode (open from reading text)
942- let mode_string = mode. map_or ( "rt" , objstr :: borrow_value ) ;
963+ let mode_string = mode. unwrap_or ( "rt" ) ;
943964
944965 let ( mode, typ) = match split_mode_string ( mode_string) {
945966 Ok ( ( mode, typ) ) => ( mode, typ) ,
@@ -1061,6 +1082,8 @@ pub fn make_module(vm: &VirtualMachine) -> PyObjectRef {
10611082 let text_io_wrapper = py_class ! ( ctx, "TextIOWrapper" , text_io_base. clone( ) , {
10621083 "__init__" => ctx. new_method( text_io_wrapper_init) ,
10631084 "seekable" => ctx. new_method( text_io_wrapper_seekable) ,
1085+ "seek" => ctx. new_method( text_io_wrapper_seek) ,
1086+ "tell" => ctx. new_method( text_io_wrapper_tell) ,
10641087 "read" => ctx. new_method( text_io_wrapper_read) ,
10651088 "write" => ctx. new_method( text_io_wrapper_write) ,
10661089 "readline" => ctx. new_method( text_io_wrapper_readline) ,
@@ -1098,7 +1121,8 @@ pub fn make_module(vm: &VirtualMachine) -> PyObjectRef {
10981121 } ) ;
10991122
11001123 let module = py_module ! ( vm, "_io" , {
1101- "open" => ctx. new_function( io_open) ,
1124+ "open" => ctx. new_function( io_open_wrapper) ,
1125+ "open_code" => ctx. new_function( io_open_code) ,
11021126 "_IOBase" => io_base,
11031127 "_RawIOBase" => raw_io_base. clone( ) ,
11041128 "_BufferedIOBase" => buffered_io_base,
0 commit comments