@@ -1458,9 +1458,23 @@ public static void InitializeForFinalization(CodeContext/*!*/ context, object ne
14581458 }
14591459 } // else metaclass is expected to be a callable and overrides any inherited metaclass through any bases
14601460
1461+ // Prepare class context
1462+ // The class context is like the parent context but with its own attribute dict.
1463+ // Or another way: the class context is like the local context of the class lambda but without the __class__ variable.
1464+ var attrStorage = new CommonDictionaryStorage ( ) ;
1465+ PythonDictionary attrDict = parentContext . Dict . _storage switch {
1466+ // If the parent context dict is backed by RuntimeVariablesDictionaryStorage,
1467+ // the class context dict also has to be backed by RuntimeVariablesDictionaryStorage so that the closure is preserved.
1468+ RuntimeVariablesDictionaryStorage parentStorage =>
1469+ new PythonDictionary ( new RuntimeVariablesDictionaryStorage ( parentStorage , attrStorage ) ) ,
1470+ // Otherwise a standard dict suffices.
1471+ _ => new PythonDictionary ( attrStorage ) ,
1472+ } ;
1473+ CodeContext classContext = new CodeContext ( attrDict , parentContext . ModuleContext ) ;
1474+
14611475 // Call class body lambda
1462- CodeContext classContext = func ( parentContext ) ;
1463- PythonDictionary vars = classContext . Dict ;
1476+ CodeContext localContext = func ( classContext ) ;
1477+ PythonDictionary vars = localContext . Dict ;
14641478
14651479 // Prepare classdict
14661480 // TODO: prepared classdict should be used by `func` (PEP 3115)
@@ -3622,10 +3636,19 @@ public static object SetName(CodeContext/*!*/ context, string name, object value
36223636
36233637 #region Global Access
36243638
3625- public static CodeContext /*!*/ CreateLocalContext ( CodeContext /*!*/ outerContext , MutableTuple boxes , string [ ] args , int numFreeVars , int arg0Idx ) {
3639+ public static CodeContext /*!*/ CreateLocalContext ( CodeContext /*!*/ outerContext , MutableTuple boxes , string [ ] args , int numFreeVars , int arg0Idx , bool newAttribStorage ) {
3640+ CommonDictionaryStorage ? attribs = null ;
3641+ if ( ! newAttribStorage ) {
3642+ attribs = outerContext . Dict . _storage switch {
3643+ CustomDictionaryStorage vars => vars . Storage ,
3644+ CommonDictionaryStorage commonStorage => commonStorage ,
3645+ _ => new ( )
3646+ } ;
3647+ }
3648+
36263649 return new CodeContext (
36273650 new PythonDictionary (
3628- new RuntimeVariablesDictionaryStorage ( boxes , args , numFreeVars , arg0Idx )
3651+ new RuntimeVariablesDictionaryStorage ( boxes , args , numFreeVars , arg0Idx , attribs ?? new ( ) )
36293652 ) ,
36303653 outerContext . ModuleContext
36313654 ) ;
0 commit comments