From 961d0b85f726d669ebbd48f97feb709dc32ac9b9 Mon Sep 17 00:00:00 2001 From: Irina Truong Date: Fri, 26 Feb 2021 15:38:11 -0800 Subject: [PATCH] Preserve comments on merge. --- dev-requirements.txt | 4 ++-- src/configobj/__init__.py | 8 ++++++++ src/tests/test_configobj.py | 30 ++++++++++++++++++++++++++++++ 3 files changed, 40 insertions(+), 2 deletions(-) diff --git a/dev-requirements.txt b/dev-requirements.txt index a2419b7..877af12 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -2,8 +2,8 @@ # Development requirements # -invoke==0.12.2 -#rituals==0.3.0 +# invoke==0.12.2 +# rituals==0.3.0 -e git+https://github.com/jhermann/rituals.git#egg=rituals Sphinx==1.3.4 diff --git a/src/configobj/__init__.py b/src/configobj/__init__.py index 928c208..bc4911b 100644 --- a/src/configobj/__init__.py +++ b/src/configobj/__init__.py @@ -760,6 +760,14 @@ def merge(self, indict, decoupled=False): >>> c2 ConfigObj({'section1': {'option1': 'False', 'subsection': {'more_options': 'False'}}}) """ + if hasattr(indict, "initial_comment") and indict.initial_comment: + self.initial_comment = indict.initial_comment + if hasattr(indict, "final_comment") and indict.final_comment: + self.final_comment = indict.final_comment + if hasattr(indict, "comments") and indict.comments: + for k, comment_lines in indict.comments.items(): + if comment_lines: + self.comments[k] = comment_lines for key, val in indict.items(): if decoupled: val = copy.deepcopy(val) diff --git a/src/tests/test_configobj.py b/src/tests/test_configobj.py index c72e364..bc6ffc0 100644 --- a/src/tests/test_configobj.py +++ b/src/tests/test_configobj.py @@ -1299,6 +1299,36 @@ def test_merge_coupling(self, data): c1['sect']['val'] = 42 assert c2['sect']['val'] == data[1] + @pytest.mark.parametrize( + "lines1,lines2,expected_lines", + [ + ( + # both c1 and c2 have comments + ["# c1 before config", "[main]", "# c1 for foo", "foo = a", "# c1 after config"], + ["# c2 before config", "[main]", "# c2 for foo", "foo = b", "# c2 after config"], + ["# c2 before config", "[main]", "# c2 for foo", "foo = b", "# c2 after config"], + ), + ( + # c1 has comments, c2 does not + ["# c1 before config", "[main]", "# c1 for foo", "foo = a", "# c1 after config"], + ["[main]", "foo = b"], + ["# c1 before config", "[main]", "# c1 for foo", "foo = b", "# c1 after config"], + ), + ( + # c2 has comments, c1 does not + ["[main]", "foo = a"], + ["# c2 before config", "[main]", "# c2 for foo", "foo = b", "# c2 after config"], + ["# c2 before config", "[main]", "# c2 for foo", "foo = b", "# c2 after config"], + ), + ] + ) + def test_merge_comments(self, lines1, lines2, expected_lines): + c1 = ConfigObj(lines1) + c2 = ConfigObj(lines2) + c1.merge(c2) + # comments and values from c2 should win + actual_lines = c1.write() + assert actual_lines == expected_lines class TestErrorReporting(object): MULTI_ERROR = [