@@ -17,7 +17,7 @@ use crate::{extract_spans, Diagnostic};
17
17
use bincode;
18
18
use proc_macro2:: { Span , TokenStream as TokenStream2 } ;
19
19
use quote:: quote;
20
- use rustpython_bytecode:: bytecode:: CodeObject ;
20
+ use rustpython_bytecode:: bytecode:: { CodeObject , FrozenModule } ;
21
21
use rustpython_compiler:: compile;
22
22
use std:: collections:: HashMap ;
23
23
use std:: env;
@@ -52,7 +52,7 @@ impl CompilationSource {
52
52
& self ,
53
53
mode : & compile:: Mode ,
54
54
module_name : String ,
55
- ) -> Result < HashMap < String , CodeObject > , Diagnostic > {
55
+ ) -> Result < HashMap < String , FrozenModule > , Diagnostic > {
56
56
Ok ( match & self . kind {
57
57
CompilationSourceKind :: File ( rel_path) => {
58
58
let mut path = PathBuf :: from (
@@ -65,10 +65,20 @@ impl CompilationSource {
65
65
format ! ( "Error reading file {:?}: {}" , path, err) ,
66
66
)
67
67
} ) ?;
68
- hashmap ! { module_name. clone( ) => self . compile_string( & source, mode, module_name. clone( ) ) ?}
68
+ hashmap ! {
69
+ module_name. clone( ) => FrozenModule {
70
+ code: self . compile_string( & source, mode, module_name. clone( ) ) ?,
71
+ package: false ,
72
+ } ,
73
+ }
69
74
}
70
75
CompilationSourceKind :: SourceCode ( code) => {
71
- hashmap ! { module_name. clone( ) => self . compile_string( code, mode, module_name. clone( ) ) ?}
76
+ hashmap ! {
77
+ module_name. clone( ) => FrozenModule {
78
+ code: self . compile_string( code, mode, module_name. clone( ) ) ?,
79
+ package: false ,
80
+ } ,
81
+ }
72
82
}
73
83
CompilationSourceKind :: Dir ( rel_path) => {
74
84
let mut path = PathBuf :: from (
@@ -85,7 +95,7 @@ impl CompilationSource {
85
95
path : & Path ,
86
96
parent : String ,
87
97
mode : & compile:: Mode ,
88
- ) -> Result < HashMap < String , CodeObject > , Diagnostic > {
98
+ ) -> Result < HashMap < String , FrozenModule > , Diagnostic > {
89
99
let mut code_map = HashMap :: new ( ) ;
90
100
let paths = fs:: read_dir ( & path) . map_err ( |err| {
91
101
Diagnostic :: spans_error ( self . span , format ! ( "Error listing dir {:?}: {}" , path, err) )
@@ -95,11 +105,13 @@ impl CompilationSource {
95
105
Diagnostic :: spans_error ( self . span , format ! ( "Failed to list file: {}" , err) )
96
106
} ) ?;
97
107
let path = path. path ( ) ;
98
- let file_name = path. file_name ( ) . unwrap ( ) . to_str ( ) . unwrap ( ) ;
108
+ let file_name = path. file_name ( ) . unwrap ( ) . to_str ( ) . ok_or_else ( || {
109
+ Diagnostic :: spans_error ( self . span , format ! ( "Invalid UTF-8 in file name {:?}" , path) )
110
+ } ) ?;
99
111
if path. is_dir ( ) {
100
112
code_map. extend ( self . compile_dir (
101
113
& path,
102
- format ! ( "{}{}. " , parent, file_name) ,
114
+ format ! ( "{}{}" , parent, file_name) ,
103
115
mode,
104
116
) ?) ;
105
117
} else if file_name. ends_with ( ".py" ) {
@@ -109,11 +121,21 @@ impl CompilationSource {
109
121
format ! ( "Error reading file {:?}: {}" , path, err) ,
110
122
)
111
123
} ) ?;
112
- let file_name_splitte: Vec < & str > = file_name. splitn ( 2 , '.' ) . collect ( ) ;
113
- let module_name = format ! ( "{}{}" , parent, file_name_splitte[ 0 ] ) ;
124
+ let stem = path. file_stem ( ) . unwrap ( ) . to_str ( ) . unwrap ( ) ;
125
+ let is_init = stem == "__init__" ;
126
+ let module_name = if is_init {
127
+ parent. clone ( )
128
+ } else if parent. is_empty ( ) {
129
+ stem. to_string ( )
130
+ } else {
131
+ format ! ( "{}.{}" , parent, stem)
132
+ } ;
114
133
code_map. insert (
115
134
module_name. clone ( ) ,
116
- self . compile_string ( & source, mode, module_name) ?,
135
+ FrozenModule {
136
+ code : self . compile_string ( & source, mode, module_name) ?,
137
+ package : is_init,
138
+ } ,
117
139
) ;
118
140
}
119
141
}
@@ -128,7 +150,7 @@ struct PyCompileInput {
128
150
}
129
151
130
152
impl PyCompileInput {
131
- fn compile ( & self ) -> Result < HashMap < String , CodeObject > , Diagnostic > {
153
+ fn compile ( & self ) -> Result < HashMap < String , FrozenModule > , Diagnostic > {
132
154
let mut module_name = None ;
133
155
let mut mode = None ;
134
156
let mut source: Option < CompilationSource > = None ;
@@ -225,13 +247,21 @@ pub fn impl_py_compile_bytecode(input: TokenStream2) -> Result<TokenStream2, Dia
225
247
226
248
let code_map = input. compile ( ) ?;
227
249
228
- let modules = code_map. iter ( ) . map ( |( module_name, code_obj) | {
229
- let module_name = LitStr :: new ( & module_name, Span :: call_site ( ) ) ;
230
- let bytes = bincode:: serialize ( & code_obj) . expect ( "Failed to serialize" ) ;
231
- let bytes = LitByteStr :: new ( & bytes, Span :: call_site ( ) ) ;
232
- quote ! { #module_name. into( ) => bincode:: deserialize:: <:: rustpython_vm:: bytecode:: CodeObject >( #bytes)
233
- . expect( "Deserializing CodeObject failed" ) }
234
- } ) ;
250
+ let modules = code_map
251
+ . into_iter ( )
252
+ . map ( |( module_name, FrozenModule { code, package } ) | {
253
+ let module_name = LitStr :: new ( & module_name, Span :: call_site ( ) ) ;
254
+ let bytes = bincode:: serialize ( & code) . expect ( "Failed to serialize" ) ;
255
+ let bytes = LitByteStr :: new ( & bytes, Span :: call_site ( ) ) ;
256
+ quote ! {
257
+ #module_name. into( ) => :: rustpython_vm:: bytecode:: FrozenModule {
258
+ code: bincode:: deserialize:: <:: rustpython_vm:: bytecode:: CodeObject >(
259
+ #bytes
260
+ ) . expect( "Deserializing CodeObject failed" ) ,
261
+ package: #package,
262
+ }
263
+ }
264
+ } ) ;
235
265
236
266
let output = quote ! {
237
267
( {
0 commit comments