4
4
5
5
use std:: cell:: Cell ;
6
6
use std:: char;
7
- use std:: io:: { self , Write } ;
8
7
use std:: str;
9
8
10
9
use num_bigint:: Sign ;
@@ -607,6 +606,11 @@ fn builtin_pow(
607
606
}
608
607
}
609
608
609
+ pub fn builtin_exit ( exit_code_arg : OptionalArg < PyObjectRef > , vm : & VirtualMachine ) -> PyResult {
610
+ let code = exit_code_arg. unwrap_or_else ( || vm. new_int ( 0 ) ) ;
611
+ Err ( vm. new_exception ( vm. ctx . exceptions . system_exit . clone ( ) , vec ! [ code] ) )
612
+ }
613
+
610
614
#[ derive( Debug , FromArgs ) ]
611
615
pub struct PrintOptions {
612
616
#[ pyarg( keyword_only, default = "None" ) ]
@@ -619,48 +623,14 @@ pub struct PrintOptions {
619
623
file : Option < PyObjectRef > ,
620
624
}
621
625
622
- trait Printer {
623
- fn write ( & mut self , vm : & VirtualMachine , obj : PyStringRef ) -> PyResult < ( ) > ;
624
- fn flush ( & mut self , vm : & VirtualMachine ) -> PyResult < ( ) > ;
625
- }
626
-
627
- impl Printer for & ' _ PyObjectRef {
628
- fn write ( & mut self , vm : & VirtualMachine , obj : PyStringRef ) -> PyResult < ( ) > {
629
- vm. call_method ( self , "write" , vec ! [ obj. into_object( ) ] ) ?;
630
- Ok ( ( ) )
631
- }
632
-
633
- fn flush ( & mut self , vm : & VirtualMachine ) -> PyResult < ( ) > {
634
- vm. call_method ( self , "flush" , vec ! [ ] ) ?;
635
- Ok ( ( ) )
636
- }
637
- }
638
-
639
- impl Printer for std:: io:: StdoutLock < ' _ > {
640
- fn write ( & mut self , _vm : & VirtualMachine , s : PyStringRef ) -> PyResult < ( ) > {
641
- write ! ( self , "{}" , s) . unwrap ( ) ;
642
- Ok ( ( ) )
643
- }
644
-
645
- fn flush ( & mut self , _vm : & VirtualMachine ) -> PyResult < ( ) > {
646
- <Self as io:: Write >:: flush ( self ) . unwrap ( ) ;
647
- Ok ( ( ) )
648
- }
649
- }
650
-
651
- pub fn builtin_exit ( exit_code_arg : OptionalArg < PyObjectRef > , vm : & VirtualMachine ) -> PyResult {
652
- let code = exit_code_arg. unwrap_or_else ( || vm. new_int ( 0 ) ) ;
653
- Err ( vm. new_exception ( vm. ctx . exceptions . system_exit . clone ( ) , vec ! [ code] ) )
654
- }
655
-
656
626
pub fn builtin_print ( objects : Args , options : PrintOptions , vm : & VirtualMachine ) -> PyResult < ( ) > {
657
- let stdout = io :: stdout ( ) ;
627
+ // Trick so that we don't have to allocate to have a trait object
658
628
659
- let mut printer: Box < dyn Printer > = if let Some ( file) = & options. file {
660
- Box :: new ( file)
661
- } else {
662
- Box :: new ( stdout. lock ( ) )
629
+ let file = match options. file {
630
+ Some ( f) => f,
631
+ None => vm. get_attribute ( vm. sys_module . clone ( ) , "stdout" ) ?,
663
632
} ;
633
+ let write = |obj : PyStringRef | vm. call_method ( & file, "write" , vec ! [ obj. into_object( ) ] ) ;
664
634
665
635
let sep = options
666
636
. sep
@@ -671,19 +641,19 @@ pub fn builtin_print(objects: Args, options: PrintOptions, vm: &VirtualMachine)
671
641
if first {
672
642
first = false ;
673
643
} else {
674
- printer . write ( vm , sep. clone ( ) ) ?;
644
+ write ( sep. clone ( ) ) ?;
675
645
}
676
646
677
- printer . write ( vm , vm. to_str ( & object) ?) ?;
647
+ write ( vm. to_str ( & object) ?) ?;
678
648
}
679
649
680
650
let end = options
681
651
. end
682
652
. unwrap_or_else ( || PyString :: from ( "\n " ) . into_ref ( vm) ) ;
683
- printer . write ( vm , end) ?;
653
+ write ( end) ?;
684
654
685
655
if options. flush . to_bool ( ) {
686
- printer . flush ( vm ) ?;
656
+ vm . call_method ( & file , "flush" , vec ! [ ] ) ?;
687
657
}
688
658
689
659
Ok ( ( ) )
0 commit comments