@@ -8,7 +8,9 @@ use clap::{App, AppSettings, Arg, ArgMatches};
8
8
use rustpython_compiler:: { compile, error:: CompileError , error:: CompileErrorType } ;
9
9
use rustpython_parser:: error:: ParseErrorType ;
10
10
use rustpython_vm:: {
11
- import, print_exception,
11
+ import, match_class,
12
+ obj:: { objint:: PyInt , objtuple:: PyTuple , objtype} ,
13
+ print_exception,
12
14
pyobject:: { ItemProtocol , PyObjectRef , PyResult } ,
13
15
scope:: Scope ,
14
16
util, PySettings , VirtualMachine ,
@@ -30,17 +32,47 @@ fn main() {
30
32
let vm = VirtualMachine :: new ( settings) ;
31
33
32
34
let res = run_rustpython ( & vm, & matches) ;
33
- // See if any exception leaked out:
34
- handle_exception ( & vm, res) ;
35
35
36
36
#[ cfg( feature = "flame-it" ) ]
37
37
{
38
38
main_guard. end ( ) ;
39
39
if let Err ( e) = write_profile ( & matches) {
40
40
error ! ( "Error writing profile information: {}" , e) ;
41
- process:: exit ( 1 ) ;
42
41
}
43
42
}
43
+
44
+ // See if any exception leaked out:
45
+ if let Err ( err) = res {
46
+ if objtype:: isinstance ( & err, & vm. ctx . exceptions . system_exit ) {
47
+ let args = vm. get_attribute ( err. clone ( ) , "args" ) . unwrap ( ) ;
48
+ let args = args. downcast :: < PyTuple > ( ) . expect ( "'args' must be a tuple" ) ;
49
+ match args. elements . len ( ) {
50
+ 0 => return ,
51
+ 1 => match_class ! ( match args. elements[ 0 ] . clone( ) {
52
+ i @ PyInt => {
53
+ use num_traits:: cast:: ToPrimitive ;
54
+ process:: exit( i. as_bigint( ) . to_i32( ) . unwrap( ) ) ;
55
+ }
56
+ arg => {
57
+ if vm. is_none( & arg) {
58
+ return ;
59
+ }
60
+ if let Ok ( s) = vm. to_str( & arg) {
61
+ println!( "{}" , s) ;
62
+ }
63
+ }
64
+ } ) ,
65
+ _ => {
66
+ if let Ok ( r) = vm. to_repr ( args. as_object ( ) ) {
67
+ println ! ( "{}" , r) ;
68
+ }
69
+ }
70
+ }
71
+ } else {
72
+ print_exception ( & vm, & err) ;
73
+ }
74
+ process:: exit ( 1 ) ;
75
+ }
44
76
}
45
77
46
78
fn parse_arguments < ' a > ( app : App < ' a , ' _ > ) -> ArgMatches < ' a > {
@@ -349,13 +381,6 @@ fn _run_string(vm: &VirtualMachine, scope: Scope, source: &str, source_path: Str
349
381
vm. run_code_obj ( code_obj, scope)
350
382
}
351
383
352
- fn handle_exception < T > ( vm : & VirtualMachine , result : PyResult < T > ) {
353
- if let Err ( err) = result {
354
- print_exception ( vm, & err) ;
355
- process:: exit ( 1 ) ;
356
- }
357
- }
358
-
359
384
fn run_command ( vm : & VirtualMachine , scope : Scope , source : String ) -> PyResult < ( ) > {
360
385
debug ! ( "Running command {}" , source) ;
361
386
_run_string ( vm, scope, & source, "<stdin>" . to_string ( ) ) ?;
@@ -560,6 +585,10 @@ fn run_shell(vm: &VirtualMachine, scope: Scope) -> PyResult<()> {
560
585
} ;
561
586
562
587
if let Err ( exc) = result {
588
+ if objtype:: isinstance ( & exc, & vm. ctx . exceptions . system_exit ) {
589
+ repl. save_history ( & repl_history_path) . unwrap ( ) ;
590
+ return Err ( exc) ;
591
+ }
563
592
print_exception ( vm, & exc) ;
564
593
}
565
594
}
0 commit comments