@@ -11,44 +11,47 @@ use crate::pyobject::{ItemProtocol, PyResult};
11
11
use crate :: util;
12
12
use crate :: vm:: VirtualMachine ;
13
13
14
- fn import_uncached_module ( vm : & VirtualMachine , current_path : PathBuf , module : & str ) -> PyResult {
15
- // Check for Rust-native modules
16
- if let Some ( module) = vm. stdlib_inits . borrow ( ) . get ( module) {
17
- return Ok ( module ( vm) . clone ( ) ) ;
18
- }
14
+ pub fn import_module ( vm : & VirtualMachine , current_path : PathBuf , module_name : & str ) -> PyResult {
15
+ // Cached modules:
16
+ let sys_modules = vm. get_attribute ( vm. sys_module . clone ( ) , "modules" ) . unwrap ( ) ;
19
17
20
- let notfound_error = vm. context ( ) . exceptions . module_not_found_error . clone ( ) ;
21
- let import_error = vm. context ( ) . exceptions . import_error . clone ( ) ;
18
+ // First, see if we already loaded the module:
19
+ if let Ok ( module) = sys_modules. get_item ( module_name. to_string ( ) , vm) {
20
+ Ok ( module)
21
+ } else if let Some ( make_module_func) = vm. stdlib_inits . borrow ( ) . get ( module_name) {
22
+ let module = make_module_func ( vm) ;
23
+ sys_modules. set_item ( module_name, module. clone ( ) , vm) ?;
24
+ Ok ( module)
25
+ } else {
26
+ let notfound_error = vm. context ( ) . exceptions . module_not_found_error . clone ( ) ;
27
+ let import_error = vm. context ( ) . exceptions . import_error . clone ( ) ;
22
28
23
- // Time to search for module in any place:
24
- let file_path = find_source ( vm, current_path, module )
25
- . map_err ( |e| vm. new_exception ( notfound_error. clone ( ) , e) ) ?;
26
- let source = util:: read_file ( file_path. as_path ( ) )
27
- . map_err ( |e| vm. new_exception ( import_error. clone ( ) , e. to_string ( ) ) ) ?;
28
- let code_obj = compile:: compile (
29
- vm,
30
- & source,
31
- & compile:: Mode :: Exec ,
32
- file_path. to_str ( ) . unwrap ( ) . to_string ( ) ,
33
- )
34
- . map_err ( |err| vm. new_syntax_error ( & err) ) ?;
35
- // trace!("Code object: {:?}", code_obj);
29
+ // Time to search for module in any place:
30
+ let file_path = find_source ( vm, current_path, module_name )
31
+ . map_err ( |e| vm. new_exception ( notfound_error. clone ( ) , e) ) ?;
32
+ let source = util:: read_file ( file_path. as_path ( ) )
33
+ . map_err ( |e| vm. new_exception ( import_error. clone ( ) , e. to_string ( ) ) ) ?;
34
+ let code_obj = compile:: compile (
35
+ vm,
36
+ & source,
37
+ & compile:: Mode :: Exec ,
38
+ file_path. to_str ( ) . unwrap ( ) . to_string ( ) ,
39
+ )
40
+ . map_err ( |err| vm. new_syntax_error ( & err) ) ?;
41
+ // trace!("Code object: {:?}", code_obj);
36
42
37
- let attrs = vm. ctx . new_dict ( ) ;
38
- attrs. set_item ( "__name__" , vm. new_str ( module. to_string ( ) ) , vm) ?;
39
- vm. run_code_obj ( code_obj, Scope :: new ( None , attrs. clone ( ) ) ) ?;
40
- Ok ( vm. ctx . new_module ( module, attrs) )
41
- }
43
+ let attrs = vm. ctx . new_dict ( ) ;
44
+ attrs. set_item ( "__name__" , vm. new_str ( module_name. to_string ( ) ) , vm) ?;
45
+ let module = vm. ctx . new_module ( module_name, attrs. clone ( ) ) ;
42
46
43
- pub fn import_module ( vm : & VirtualMachine , current_path : PathBuf , module_name : & str ) -> PyResult {
44
- // First, see if we already loaded the module:
45
- let sys_modules = vm. get_attribute ( vm. sys_module . clone ( ) , "modules" ) ?;
46
- if let Ok ( module) = sys_modules. get_item ( module_name. to_string ( ) , vm) {
47
- return Ok ( module) ;
47
+ // Store module in cache to prevent infinite loop with mutual importing libs:
48
+ sys_modules. set_item ( module_name, module. clone ( ) , vm) ?;
49
+
50
+ // Execute main code in module:
51
+ vm. run_code_obj ( code_obj, Scope :: new ( None , attrs) ) ?;
52
+
53
+ Ok ( module)
48
54
}
49
- let module = import_uncached_module ( vm, current_path, module_name) ?;
50
- sys_modules. set_item ( module_name, module. clone ( ) , vm) ?;
51
- Ok ( module)
52
55
}
53
56
54
57
fn find_source ( vm : & VirtualMachine , current_path : PathBuf , name : & str ) -> Result < PathBuf , String > {
0 commit comments