From 59980bcecd584c971d316b3b2742aca37ef61997 Mon Sep 17 00:00:00 2001 From: Dan Nicholson Date: Fri, 22 Nov 2024 09:32:24 -0700 Subject: [PATCH] ImageConfigParser: Don't sort merged values The order of configuration values may be significant, so the parser should not sort them. To do that, use a single counter for add and del variants and emit the values that have positive counts without sorting. This relies on the Python dict stable order, which has been the case since Python 3.6. --- lib/eib.py | 12 +++++------- tests/eib/test_image_config_parser.py | 8 ++++---- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/lib/eib.py b/lib/eib.py index 0496c47a..2baaf010 100644 --- a/lib/eib.py +++ b/lib/eib.py @@ -242,25 +242,23 @@ def _merge_option(self, section_pattern, option): opt) yield (section, opt) else: - add_vals = Counter() + values = Counter() for opt in add_opts: logger.debug('Adding %s %s values from %s', section, option, opt) - add_vals.update(sect[opt].split()) + values.update(sect[opt].split()) yield (section, opt) - del_vals = Counter() for opt in del_opts: logger.debug('Removing %s %s values from %s', section, option, opt) - del_vals.update(sect[opt].split()) + values.subtract(sect[opt].split()) yield (section, opt) - # Set the option to the difference of the counters. + # Set the option to the keys that have positive values. # Merge the values together with newlines like they were # in the original configuration. - vals = add_vals - del_vals - sect[option] = '\n'.join(sorted(vals.keys())) + sect[option] = '\n'.join(k for k, v in values.items() if v > 0) def copy(self): """Create a new instance from this one""" diff --git a/tests/eib/test_image_config_parser.py b/tests/eib/test_image_config_parser.py index c44ddf48..1015d1b2 100644 --- a/tests/eib/test_image_config_parser.py +++ b/tests/eib/test_image_config_parser.py @@ -119,8 +119,8 @@ def test_merged_option(config): assert set(sect) == {'opt'} - # The values will be sorted and newline separated - assert sect['opt'] == 'baz\nfoo' + # The values will be newline separated in the order they appeared. + assert sect['opt'] == 'foo\nbaz' # Now that the merged option exists, it will override any further # add/del. @@ -129,7 +129,7 @@ def test_merged_option(config): config.merge() assert set(sect) == {'opt'} - assert sect['opt'] == 'baz\nfoo' + assert sect['opt'] == 'foo\nbaz' def test_merged_option_interpolation(config): @@ -277,7 +277,7 @@ def test_merged_files(tmp_path, config): config.merge() assert set(config['sect']) == {'opt'} - assert config['sect']['opt'] == 'baz\nfoo' + assert config['sect']['opt'] == 'foo\nbaz' assert set(config['sect-a']) == {'opt'} assert config['sect-a']['opt'] == '' assert set(config['sect-b']) == {'opt'}