From d951e4d7a924eacac0c84c7d2af54b9ddd722f66 Mon Sep 17 00:00:00 2001
From: Karl-Hermann Wieners <karl-hermann.wieners@mpimet.mpg.de>
Date: Thu, 25 Nov 2021 10:37:27 +0100
Subject: [PATCH] Config: fixed job config corruption while overriding
 namelists in another job

---
 CHANGES.txt |  5 +++++
 mkexp       |  7 ++++---
 test.py     | 49 +++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 58 insertions(+), 3 deletions(-)

diff --git a/CHANGES.txt b/CHANGES.txt
index f208dcb..7c08132 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -14,6 +14,11 @@ Global
 
 * TODO: Porting to python3
 
+Configuration
+-------------
+
+* Fixed job config corruption while overriding namelists in another job
+
 Templates
 ---------
 
diff --git a/mkexp b/mkexp
index fa2c4a2..1874008 100755
--- a/mkexp
+++ b/mkexp
@@ -6,6 +6,7 @@
 #
 
 import codecs
+import copy
 import os
 import re
 import stat
@@ -477,7 +478,7 @@ def extend(subjob, jobs_config, extended_jobs):
 
         # Add parent config
         if extended_job:
-            pre_config.merge(jobs_config[extended_job])
+            pre_config.merge(copy.deepcopy(jobs_config[extended_job]))
 
         # Add actual subjob config
         pre_config.merge(subconfig)
@@ -534,8 +535,8 @@ for subjob, subconfig in jobs_config.iteritems():
         # Prepare namelists for inclusion in scripts
         var_format = job_config['JOB'].get('.var_format', '${%s}')
         var_list = set()
-        job_config['jobs'] = {}
-        job_config['jobs'].merge(jobs_config.dict())
+        del job_config['jobs']
+        job_config['jobs'] = copy.deepcopy(jobs_config)
         job_config.walk(format_vars, log=var_list, fmt=var_format)
         job_config['VARIABLES_'] = var_list
         for namelist, groups in job_config['namelists'].iteritems():
diff --git a/test.py b/test.py
index 11dc24f..c06e83a 100644
--- a/test.py
+++ b/test.py
@@ -1173,6 +1173,55 @@ class InheritanceTestCase(MkexpSimpleTestCase):
             result = align(result)
             self.assertMultiLineEqual(expecteds[i-1], result)
 
+    def test_namelist_override(self):
+        writeconfig(self.exp_id, """
+            EXP_TYPE =
+            [namelists]
+              [[namelist]]
+                [[[group]]]
+                  var = 999
+            [jobs]
+              [[job]]
+              [[job1]]
+                .extends = job
+                [[[namelists]]]
+                  [[[[namelist]]]]
+                    [[[[[group]]]]]
+                      var = 1
+              [[job2]]
+                .extends = job1
+                [[[namelists]]]
+                  [[[[namelist]]]]
+                    [[[[[group]]]]]
+                      var = 2
+        """)
+        writetemplate(self.exp_id, 'job', """
+            %{NAMELIST}
+        """)
+        expecteds = {
+            'job':  align("""
+                        &group
+                            var = 999
+                        /
+                    """),
+            'job1': align("""
+                        &group
+                            var = 1
+                        /
+                    """),
+            'job2': align("""
+                        &group
+                            var = 2
+                        /
+                    """)
+        }
+        ignore = output(script("mkexp "+self.exp_id+".config"))
+        for i in ('job', 'job1', 'job2'):
+            result = readfile(join("test", "experiments", self.exp_id,
+                                   self.exp_id+"."+i))
+            result = align(result)
+            self.assertMultiLineEqual(expecteds[i], result)
+
 class JobSiblingsTestCase(MkexpSimpleTestCase):
 
     def test_sibling_lookup(self):
-- 
GitLab