@@ -4,7 +4,7 @@ extern crate env_logger;
4
4
#[ macro_use]
5
5
extern crate log;
6
6
7
- use clap:: { App , Arg , ArgMatches } ;
7
+ 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:: {
@@ -47,17 +47,38 @@ fn main() {
47
47
48
48
fn parse_arguments < ' a > ( app : App < ' a , ' _ > ) -> ArgMatches < ' a > {
49
49
let app = app
50
+ . setting ( AppSettings :: TrailingVarArg )
50
51
. version ( crate_version ! ( ) )
51
52
. author ( crate_authors ! ( ) )
52
53
. about ( "Rust implementation of the Python language" )
53
54
. usage ( "rustpython [OPTIONS] [-c CMD | -m MODULE | FILE | -] [PYARGS]..." )
54
55
. arg (
55
56
Arg :: with_name ( "script" )
56
57
. required ( false )
58
+ . allow_hyphen_values ( true )
59
+ . multiple ( true )
60
+ . value_name ( "script, args" )
61
+ . min_values ( 1 ) ,
62
+ )
63
+ . arg (
64
+ Arg :: with_name ( "c" )
65
+ . short ( "c" )
66
+ . takes_value ( true )
67
+ . allow_hyphen_values ( true )
57
68
. multiple ( true )
69
+ . value_name ( "cmd, args" )
58
70
. min_values ( 1 )
71
+ . help ( "run the given string as a program" ) ,
72
+ )
73
+ . arg (
74
+ Arg :: with_name ( "m" )
75
+ . short ( "m" )
76
+ . takes_value ( true )
59
77
. allow_hyphen_values ( true )
60
- . value_names ( & [ "script" , "args..." ] ) ,
78
+ . multiple ( true )
79
+ . value_name ( "module, args" )
80
+ . min_values ( 1 )
81
+ . help ( "run library module as script" ) ,
61
82
)
62
83
. arg (
63
84
Arg :: with_name ( "optimize" )
@@ -101,22 +122,6 @@ fn parse_arguments<'a>(app: App<'a, '_>) -> ArgMatches<'a> {
101
122
Arg :: with_name ( "ignore-environment" )
102
123
. short ( "E" )
103
124
. help ( "Ignore environment variables PYTHON* such as PYTHONPATH" ) ,
104
- )
105
- . arg (
106
- Arg :: with_name ( "c" )
107
- . short ( "c" )
108
- . takes_value ( true )
109
- . help ( "run the given string as a program" ) ,
110
- )
111
- . arg (
112
- Arg :: with_name ( "m" )
113
- . short ( "m" )
114
- . takes_value ( true )
115
- . allow_hyphen_values ( true )
116
- . multiple ( true )
117
- // .value
118
- . value_names ( & [ "module" , "args..." ] )
119
- . help ( "run library module as script" ) ,
120
125
) ;
121
126
#[ cfg( feature = "flame-it" ) ]
122
127
let app = app
@@ -142,6 +147,9 @@ fn create_settings(matches: &ArgMatches) -> PySettings {
142
147
let mut settings: PySettings = Default :: default ( ) ;
143
148
settings. ignore_environment = ignore_environment;
144
149
150
+ // add the current directory to sys.path
151
+ settings. path_list . push ( "" . to_owned ( ) ) ;
152
+
145
153
if !ignore_environment {
146
154
settings. path_list . append ( & mut get_paths ( "RUSTPYTHONPATH" ) ) ;
147
155
settings. path_list . append ( & mut get_paths ( "PYTHONPATH" ) ) ;
@@ -193,32 +201,20 @@ fn create_settings(matches: &ArgMatches) -> PySettings {
193
201
settings. dont_write_bytecode = true ;
194
202
}
195
203
196
- let mut argv = if let Some ( script) = matches. values_of ( "script" ) {
204
+ let argv = if let Some ( script) = matches. values_of ( "script" ) {
197
205
script. map ( ToOwned :: to_owned) . collect ( )
198
- } else if let Some ( mut module) = matches. values_of ( "m" ) {
199
- let argv0 = if let Ok ( module_path) = std:: fs:: canonicalize ( module. next ( ) . unwrap ( ) ) {
200
- module_path
201
- . into_os_string ( )
202
- . into_string ( )
203
- . expect ( "invalid utf8 in module path" )
204
- } else {
205
- // if it's not a real file/don't have permissions it'll probably fail anyway
206
- String :: new ( )
207
- } ;
208
- std:: iter:: once ( argv0)
209
- . chain ( module. map ( ToOwned :: to_owned) )
206
+ } else if let Some ( module) = matches. values_of ( "m" ) {
207
+ std:: iter:: once ( "PLACEHOLEDER" . to_owned ( ) )
208
+ . chain ( module. skip ( 1 ) . map ( ToOwned :: to_owned) )
209
+ . collect ( )
210
+ } else if let Some ( cmd) = matches. values_of ( "c" ) {
211
+ std:: iter:: once ( "-c" . to_owned ( ) )
212
+ . chain ( cmd. skip ( 1 ) . map ( ToOwned :: to_owned) )
210
213
. collect ( )
211
214
} else {
212
215
vec ! [ ]
213
216
} ;
214
217
215
- argv. extend (
216
- matches
217
- . values_of ( "pyargs" )
218
- . unwrap_or_default ( )
219
- . map ( ToOwned :: to_owned) ,
220
- ) ;
221
-
222
218
settings. argv = argv;
223
219
224
220
settings
@@ -357,6 +353,17 @@ fn run_command(vm: &VirtualMachine, source: String) -> PyResult<()> {
357
353
358
354
fn run_module ( vm : & VirtualMachine , module : & str ) -> PyResult < ( ) > {
359
355
debug ! ( "Running module {}" , module) ;
356
+ let importlib = vm. import ( "_frozen_importlib" , & vm. ctx . new_tuple ( vec ! [ ] ) , 0 ) ?;
357
+ let find_spec = vm. get_attribute ( importlib, "_find_spec" ) ?;
358
+ let spec = vm. invoke (
359
+ find_spec,
360
+ vec ! [ vm. ctx. new_str( module. to_owned( ) ) , vm. get_none( ) ] ,
361
+ ) ?;
362
+ if !vm. is_none ( & spec) {
363
+ let origin = vm. get_attribute ( spec, "origin" ) ?;
364
+ let sys_path = vm. get_attribute ( vm. sys_module . clone ( ) , "argv" ) ?;
365
+ sys_path. set_item ( 0 , origin, vm) ?;
366
+ }
360
367
vm. import ( module, & vm. ctx . new_tuple ( vec ! [ ] ) , 0 ) ?;
361
368
Ok ( ( ) )
362
369
}
0 commit comments