Skip to content

Commit e8b4ecb

Browse files
committed
Don't special-case user_value for choice symbols set to y
Previously, setting a choice symbol to y would only update user_selection on the parent choice and not the symbol's own user_value. Now both are updated. The point of the old behavior was to remember the m mode selections of a choice when it was switched back and forth between m and y mode, which was a feature I thought the C implementation had. On closer inspection, the C implementation never had that feature, though it might appear like it if you only make "lucky" changes (if you never select any symbols in y mode that were n in m mode). The new behavior is simpler and easier to understand: Symbol.user_value now always matches the value assigned in a .config file or via set_value(), provided the value was well-formed. This might avoid some special-casing in scripts too. The loss in usability is pretty minimal.
1 parent 2abc0bb commit e8b4ecb

2 files changed

Lines changed: 29 additions & 33 deletions

File tree

kconfiglib.py

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2700,9 +2700,8 @@ def set_value(self, value):
27002700
'assignable' will cause Symbol.user_value to differ from
27012701
Symbol.str/tri_value (be truncated down or up).
27022702
2703-
Setting a choice symbol to 2 (y) only updates Choice.user_selection on
2704-
the parent choice and not Symbol.user_value itself. This gives the
2705-
expected behavior when a choice is switched between different modes.
2703+
Setting a choice symbol to 2 (y) sets Choice.user_selection to the
2704+
choice symbol in addition to setting Symbol.user_value.
27062705
Choice.user_selection is considered when the choice is in y mode (the
27072706
"normal" mode).
27082707
@@ -2727,9 +2726,14 @@ def set_value(self, value):
27272726
value of the symbol. For other symbol types, check whether the
27282727
visibility is non-n.
27292728
"""
2730-
if value == self.user_value:
2731-
# We know the value must be valid if it was successfully set
2732-
# previously
2729+
# If the new user value matches the old, nothing changes, and we can
2730+
# save some work.
2731+
#
2732+
# This optimization is skipped for choice symbols: Setting a choice
2733+
# symbol's user value to y might change the state of the choice, so it
2734+
# wouldn't be safe (symbol user values always match the values set in a
2735+
# .config file or via set_value(), and are never implicitly updated).
2736+
if value == self.user_value and not self.choice:
27332737
self._was_set = True
27342738
return True
27352739

@@ -2763,16 +2767,17 @@ def set_value(self, value):
27632767
if self.orig_type in (BOOL, TRISTATE) and value in ("n", "m", "y"):
27642768
value = STR_TO_TRI[value]
27652769

2770+
self.user_value = value
2771+
27662772
if self.choice and value == 2:
2767-
# Remember this as a choice selection only. Makes switching back
2768-
# and forth between choice modes work as expected, and makes the
2769-
# check for whether the user value is the same as before above
2770-
# safe.
2773+
# Setting a choice symbol to y makes it the user selection of the
2774+
# choice. Like for symbol user values, the user selection is not
2775+
# guaranteed to match the actual selection of the choice, as
2776+
# dependencies come into play.
27712777
self.choice.user_selection = self
27722778
self.choice._was_set = True
27732779
self.choice._rec_invalidate()
27742780
else:
2775-
self.user_value = value
27762781
self._was_set = True
27772782
self._rec_invalidate_if_has_prompt()
27782783

testsuite.py

Lines changed: 13 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1550,12 +1550,10 @@ def select_and_verify(sym):
15501550
sym.name + " should be the user selection of the choice")
15511551

15521552
verify(sym.tri_value == 2,
1553-
sym.name + " should be y when selected")
1553+
sym.name + " should have value y when selected")
15541554

1555-
verify(sym.user_value != 2,
1556-
sym.name + " should not have user value y, because choice "
1557-
"y mode selections are remembered on the choice "
1558-
"itself")
1555+
verify(sym.user_value == 2,
1556+
sym.name + " should have user value y when selected")
15591557

15601558
for sibling in choice.syms:
15611559
if sibling is not sym:
@@ -1628,28 +1626,21 @@ def verify_mode(choice_name, no_modules_mode, modules_mode):
16281626
# Test m mode selection
16291627

16301628
c.named_choices["TRISTATE"].set_value(1)
1629+
1630+
verify(c.named_choices["TRISTATE"].tri_value == 1,
1631+
"TRISTATE choice should have mode m after explicit mode assignment")
1632+
1633+
assign_and_verify_value("T_1", 0, 0)
1634+
assign_and_verify_value("T_2", 0, 0)
16311635
assign_and_verify_value("T_1", 1, 1)
16321636
assign_and_verify_value("T_2", 1, 1)
1637+
assign_and_verify_value("T_1", 2, 1)
1638+
assign_and_verify_value("T_2", 2, 1)
16331639

1634-
c.syms["T_1"].set_value(0) # Check that this is remembered later
1635-
1636-
# Switching to y mode should cause T_1 to become selected
1640+
# Switching to y mode should cause T_2 to become selected
16371641
c.named_choices["TRISTATE"].set_value(2)
1638-
verify_value("T_1", 2)
1639-
verify_value("T_2", 0)
1640-
1641-
# Switching back to m mode should restore the old values
1642-
c.named_choices["TRISTATE"].set_value(1)
16431642
verify_value("T_1", 0)
1644-
verify_value("T_2", 1)
1645-
1646-
assign_and_verify_value("TM_1", 1, 1)
1647-
assign_and_verify_value("TM_1", 2, 1) # Ignored
1648-
verify(c.named_choices["TRISTATE"].tri_value == 1,
1649-
"m-visible choice got invalid mode")
1650-
1651-
assign_and_verify_value("TM_1", 0, 0)
1652-
assign_and_verify_value("TM_1", 2, 0) # Ignored
1643+
verify_value("T_2", 2)
16531644

16541645
# Verify that choices with no explicitly specified type get the type of the
16551646
# first contained symbol with a type

0 commit comments

Comments
 (0)