[configuration] Have a stable order for sections (closes #298658)

Useful when generating a default configuration file, like pylint's.

Fix provided by Craig Hobbs <craigahobbs@gmail.com>

authorRémi Cardona <remi.cardona@logilab.fr>
changeset687b0d3e2aaa
branchdefault
phasepublic
hiddenno
parent revision#5eda1d32011d Added tag 1.0.2, debian/1.0.2-1, centos/1.0.2-1 for changeset 8ca88714c899
child revision#2432940f1e7e [testlib] Remove old TestCase.assertRaises code, #f6e12d3f9fff [testlib] Remove old TestCase.assertRaises code
files modified by this revision
logilab/common/configuration.py
test/unittest_configuration.py
# HG changeset patch
# User Rémi Cardona <remi.cardona@logilab.fr>
# Date 1437669094 -7200
# Thu Jul 23 18:31:34 2015 +0200
# Node ID 687b0d3e2aaab81cbfd36ba49830ff6f92618deb
# Parent 5eda1d32011d62c381ff80bb79d43ecce58c3bcd
[configuration] Have a stable order for sections (closes #298658)

Useful when generating a default configuration file, like pylint's.

Fix provided by Craig Hobbs <craigahobbs@gmail.com>

diff --git a/logilab/common/configuration.py b/logilab/common/configuration.py
@@ -907,11 +907,11 @@
1          for optname, optdict in self.options:
2              sections.setdefault(optdict.get('group'), []).append(
3                  (optname, optdict, self.option_value(optname)))
4          if None in sections:
5              yield None, sections.pop(None)
6 -        for section, options in sections.items():
7 +        for section, options in sorted(sections.items()):
8              yield section.upper(), options
9 
10      def options_and_values(self, options=None):
11          if options is None:
12              options = self.options
diff --git a/test/unittest_configuration.py b/test/unittest_configuration.py
@@ -49,10 +49,12 @@
13             ('diffgroup', {'type':'string', 'default':'pouet', 'metavar': '<key=val>',
14                            'group': 'agroup'}),
15             ('reset-value', {'type': 'string', 'metavar': '<string>', 'short': 'r',
16                              'dest':'value'}),
17 
18 +           ('opt-b-1', {'type': 'string', 'metavar': '<string>', 'group': 'bgroup'}),
19 +           ('opt-b-2', {'type': 'string', 'metavar': '<string>', 'group': 'bgroup'}),
20             ]
21 
22  class MyConfiguration(Configuration):
23      """test configuration"""
24      def get_named(self):
@@ -208,11 +210,18 @@
25  #reset-value=
26 
27 
28  [AGROUP]
29 
30 -diffgroup=pouet""")
31 +diffgroup=pouet
32 +
33 +
34 +[BGROUP]
35 +
36 +#opt-b-1=
37 +
38 +#opt-b-2=""")
39 
40      def test_generate_config_with_space_string(self):
41          self.cfg['value'] = '    '
42          stream = StringIO()
43          self.cfg.generate_config(stream)
@@ -237,11 +246,18 @@
44  reset-value='    '
45 
46 
47  [AGROUP]
48 
49 -diffgroup=pouet""")
50 +diffgroup=pouet
51 +
52 +
53 +[BGROUP]
54 +
55 +#opt-b-1=
56 +
57 +#opt-b-2=""")
58 
59 
60      def test_roundtrip(self):
61          cfg = self.cfg
62          f = tempfile.mktemp()
@@ -293,10 +309,14 @@
63    -r <string>, --reset-value=<string>
64 
65    Agroup:
66      --diffgroup=<key=val>
67 
68 +  Bgroup:
69 +    --opt-b-1=<string>
70 +    --opt-b-2=<string>
71 +
72    Bonus:
73      a nice additional help"""
74          if version_info < (2, 5):
75              # 'usage' header is not capitalized in this version
76              USAGE = USAGE.replace('Usage: ', 'usage: ')
@@ -354,11 +374,18 @@
77  reset-value='    '
78 
79 
80  [AGROUP]
81 
82 -diffgroup=pouet""")
83 +diffgroup=pouet
84 +
85 +
86 +[BGROUP]
87 +
88 +#opt-b-1=
89 +
90 +#opt-b-2=""")
91 
92  class Linter(OptionsManagerMixIn, OptionsProviderMixIn):
93      options = (
94          ('profile', {'type' : 'yn', 'metavar' : '<y_or_n>',
95                       'default': False,