@@ -19,6 +19,7 @@ struct Compiler {
1919 nxt_label : usize ,
2020 source_path : Option < String > ,
2121 current_source_location : ast:: Location ,
22+ current_qualified_path : Option < String > ,
2223 in_loop : bool ,
2324 in_function_def : bool ,
2425}
@@ -75,6 +76,7 @@ impl Compiler {
7576 nxt_label : 0 ,
7677 source_path : None ,
7778 current_source_location : ast:: Location :: default ( ) ,
79+ current_qualified_path : None ,
7880 in_loop : false ,
7981 in_function_def : false ,
8082 }
@@ -610,6 +612,10 @@ impl Compiler {
610612 self . in_loop = false ;
611613 self . in_function_def = true ;
612614
615+ let old_qualified_path = self . current_qualified_path . clone ( ) ;
616+ let qualified_name = self . create_qualified_name ( name, "" ) ;
617+ self . current_qualified_path = Some ( self . create_qualified_name ( name, ".<locals>" ) ) ;
618+
613619 self . prepare_decorators ( decorator_list) ?;
614620
615621 let mut flags = self . enter_function ( name, args) ?;
@@ -668,7 +674,7 @@ impl Compiler {
668674 } ) ;
669675 self . emit ( Instruction :: LoadConst {
670676 value : bytecode:: Constant :: String {
671- value : name . to_string ( ) ,
677+ value : qualified_name ,
672678 } ,
673679 } ) ;
674680
@@ -681,6 +687,7 @@ impl Compiler {
681687 name : name. to_string ( ) ,
682688 } ) ;
683689
690+ self . current_qualified_path = old_qualified_path;
684691 self . in_loop = was_in_loop;
685692 self . in_function_def = was_in_function_def;
686693 Ok ( ( ) )
@@ -696,6 +703,11 @@ impl Compiler {
696703 ) -> Result < ( ) , CompileError > {
697704 let was_in_loop = self . in_loop ;
698705 self . in_loop = false ;
706+
707+ let old_qualified_path = self . current_qualified_path . clone ( ) ;
708+ let qualified_name = self . create_qualified_name ( name, "" ) ;
709+ self . current_qualified_path = Some ( qualified_name. clone ( ) ) ;
710+
699711 self . prepare_decorators ( decorator_list) ?;
700712 self . emit ( Instruction :: LoadBuildClass ) ;
701713 let line_number = self . get_source_line_number ( ) ;
@@ -711,6 +723,12 @@ impl Compiler {
711723
712724 let ( new_body, doc_str) = get_doc ( body) ;
713725
726+ self . emit ( Instruction :: LoadName {
727+ name : "__name__" . to_string ( ) ,
728+ } ) ;
729+ self . emit ( Instruction :: StoreName {
730+ name : "__module__" . to_string ( ) ,
731+ } ) ;
714732 self . compile_statements ( new_body) ?;
715733 self . emit ( Instruction :: LoadConst {
716734 value : bytecode:: Constant :: None ,
@@ -737,7 +755,7 @@ impl Compiler {
737755
738756 self . emit ( Instruction :: LoadConst {
739757 value : bytecode:: Constant :: String {
740- value : name . to_string ( ) ,
758+ value : qualified_name ,
741759 } ,
742760 } ) ;
743761
@@ -779,6 +797,7 @@ impl Compiler {
779797 self . emit ( Instruction :: StoreName {
780798 name : name. to_string ( ) ,
781799 } ) ;
800+ self . current_qualified_path = old_qualified_path;
782801 self . in_loop = was_in_loop;
783802 Ok ( ( ) )
784803 }
@@ -1604,6 +1623,14 @@ impl Compiler {
16041623 self . current_source_location . get_row ( )
16051624 }
16061625
1626+ fn create_qualified_name ( & self , name : & str , suffix : & str ) -> String {
1627+ if let Some ( ref qualified_path) = self . current_qualified_path {
1628+ format ! ( "{}.{}{}" , qualified_path, name, suffix)
1629+ } else {
1630+ format ! ( "{}{}" , name, suffix)
1631+ }
1632+ }
1633+
16071634 fn mark_generator ( & mut self ) {
16081635 self . current_code_object ( ) . is_generator = true ;
16091636 }
0 commit comments