Dual-option value arbitrage: first vs. last vs. most explicit policy#3404
Open
kdeldycke wants to merge 15 commits intopallets:mainfrom
Open
Dual-option value arbitrage: first vs. last vs. most explicit policy#3404kdeldycke wants to merge 15 commits intopallets:mainfrom
first vs. last vs. most explicit policy#3404kdeldycke wants to merge 15 commits intopallets:mainfrom
Conversation
first vs. last vs. most explicit policy
Collaborator
Author
|
This PR is ready to be reviewed. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
WIP PR to address value arbitrage regressions from the 8.3.x series, as reported in #3403.
Explanation
Since Click inception, and up to the 8.2.x series, we did
ctx.params[self.name] = value. Options sharing the same parameter ID were processed sequentially, and always overwriting each other. Which means the last write was always winning. This is an accident: a policy that was never enforced, explained or checked against.In #3030, I changed
consume_value/get_defaultso that the absence of a value became a real manageableUNSETstate.But then the naive dual-options tests started failing: #3030 (comment) . The less intrusive fix for these tests was implemented and made the first of a dual option win. Which changed the implicit behavior.
The underlying policy or principle governing the dual options arbitrage was never noticed, debated or documented. Because it's been a silent side-effect of the code for 12 years.
The need for arbitraging dual-options were more or less known since the unit tests that were flapping in #3030 existed. But they were never deep enough to highlight and enforce the implicit last write wins policy. The regression escaped us because the test were not covering boolean
flag_values.Solution: enforce policy
Re-introduce the last write win policy from pre-8.3.x series.
On tie, the most explicit source wins. For competing defaults, an explicit default beats an auto-derived one.
For the implementation, we can not rely on the natural processing order of dual-options. We need to actively manage and track their state so we have a place to explicitly implement the policies.
Plan
Context
The lack of distinction between the absence of value and value of absence, that was fixed by #3030, also add semantic implication for defaults on boolean flags.
It was anticipated by @janluke in #1992 (comment) which proposed stricter validation.
Even @ldionne independently proposed to raise an error on the nonsensical
flag_value=False+default=Truecombinations in its original #3111 report that started the chain.In both cases I deferred these aggressive changes to a future 9.x release to not change Click internals too much.