@@ -78,7 +78,6 @@ struct Compiler<'src> {
7878 done_with_future_stmts : DoneWithFuture ,
7979 future_annotations : bool ,
8080 ctx : CompileContext ,
81- class_name : Option < String > ,
8281 opts : CompileOpts ,
8382 in_annotation : bool ,
8483}
@@ -312,6 +311,7 @@ impl<'src> Compiler<'src> {
312311 first_line_number : OneIndexed :: MIN ,
313312 obj_name : code_name. clone ( ) ,
314313 qualname : Some ( code_name) ,
314+ private : None ,
315315 blocks : vec ! [ ir:: Block :: default ( ) ] ,
316316 current_block : ir:: BlockIdx ( 0 ) ,
317317 constants : IndexSet :: default ( ) ,
@@ -334,7 +334,6 @@ impl<'src> Compiler<'src> {
334334 in_class : false ,
335335 func : FunctionContext :: NoFunction ,
336336 } ,
337- class_name : None ,
338337 opts,
339338 in_annotation : false ,
340339 }
@@ -409,6 +408,9 @@ impl Compiler<'_> {
409408 Some ( self . qualified_path . join ( "." ) )
410409 } ;
411410
411+ // Get the private name from current scope if exists
412+ let private = self . code_stack . last ( ) . and_then ( |info| info. private . clone ( ) ) ;
413+
412414 let info = ir:: CodeInfo {
413415 flags,
414416 posonlyarg_count,
@@ -418,6 +420,7 @@ impl Compiler<'_> {
418420 first_line_number,
419421 obj_name,
420422 qualname,
423+ private,
421424
422425 blocks : vec ! [ ir:: Block :: default ( ) ] ,
423426 current_block : ir:: BlockIdx ( 0 ) ,
@@ -587,7 +590,12 @@ impl Compiler<'_> {
587590 }
588591
589592 fn mangle < ' a > ( & self , name : & ' a str ) -> Cow < ' a , str > {
590- symboltable:: mangle_name ( self . class_name . as_deref ( ) , name)
593+ // Use u_private from current code unit for name mangling
594+ let private = self
595+ . code_stack
596+ . last ( )
597+ . and_then ( |info| info. private . as_deref ( ) ) ;
598+ symboltable:: mangle_name ( private, name)
591599 }
592600
593601 fn check_forbidden_name ( & mut self , name : & str , usage : NameUsage ) -> CompileResult < ( ) > {
@@ -1709,8 +1717,6 @@ impl Compiler<'_> {
17091717 loop_data : None ,
17101718 } ;
17111719
1712- let prev_class_name = self . class_name . replace ( name. to_owned ( ) ) ;
1713-
17141720 // Check if the class is declared global
17151721 let symbol_table = self . symbol_table_stack . last ( ) . unwrap ( ) ;
17161722 let symbol = unwrap_internal (
@@ -1729,8 +1735,14 @@ impl Compiler<'_> {
17291735 // If there are type params, we need to push a special symbol table just for them
17301736 if let Some ( type_params) = type_params {
17311737 self . push_symbol_table ( ) ;
1738+ // Save current private name to restore later
1739+ let saved_private = self . code_stack . last ( ) . and_then ( |info| info. private . clone ( ) ) ;
17321740 // Compile type parameters and store as .type_params
17331741 self . compile_type_params ( type_params) ?;
1742+ // Restore private name after type param scope
1743+ if let Some ( private) = saved_private {
1744+ self . code_stack . last_mut ( ) . unwrap ( ) . private = Some ( private) ;
1745+ }
17341746 let dot_type_params = self . name ( ".type_params" ) ;
17351747 emit ! ( self , Instruction :: StoreLocal ( dot_type_params) ) ;
17361748 }
@@ -1740,6 +1752,9 @@ impl Compiler<'_> {
17401752 // Update the qualname in the current code info
17411753 self . code_stack . last_mut ( ) . unwrap ( ) . qualname = Some ( qualified_name. clone ( ) ) ;
17421754
1755+ // For class scopes, set u_private to the class name for name mangling
1756+ self . code_stack . last_mut ( ) . unwrap ( ) . private = Some ( name. to_owned ( ) ) ;
1757+
17431758 let ( doc_str, body) = split_doc ( body, & self . opts ) ;
17441759
17451760 let dunder_name = self . name ( "__name__" ) ;
@@ -1793,7 +1808,6 @@ impl Compiler<'_> {
17931808
17941809 let code = self . pop_code_object ( ) ;
17951810
1796- self . class_name = prev_class_name;
17971811 self . qualified_path . pop ( ) ;
17981812 self . qualified_path . append ( global_path_prefix. as_mut ( ) ) ;
17991813 self . ctx = prev_ctx;
0 commit comments