Skip to content

Streamline option flag management - #3641

Merged
Rowlando13 merged 1 commit into
pallets:mainfrom
kdeldycke:option-flag-management-refactor
Jul 16, 2026
Merged

Rowlando13 merged 1 commit into
pallets:mainfrom
kdeldycke:option-flag-management-refactor

Conversation

@kdeldycke

@kdeldycke kdeldycke commented Jun 27, 2026 •

Copy link
Copy Markdown
Collaborator

This refactor is an attempt in streamlining the code around flag management in Option.

I hope this is not too big to digest. I did not went too far and just focused on Option internals and flag-management. My goal is to colocate decision code by domain. Like having all prompt-related code in the same block. Or all type-resolution code together. Sometimes in the same code block, sometimes under a private utility function. My heuristic is mostly driven by the number of lines and the content of the docstring.

Another idiom I introduced was using @property for is_bool_flag. I didn't see that much propoerties used in Click, but these are easier to reason about for me.

I also used the oportunity to introduce a type inference point in _pick_type which is a small step echoing what @sirosen was proposing last year about having a separation between "data which is stored (where you might have UNSET) from the data which is viewed". That also resurface the infamous UNSET a bit, but hidden into a new flag_activation_value property. And _hide_unset is a way to delimit the internals state from the presetation state.

This also contains some small syntax cleanups that were flagged by my linters.

Proof that this is the right time to introduce this refactor: after accumulating a lot of unitetsts over the past few years, I did not break any. And I did not discovered any new blind spot in the test suite.

I hope this will make code easier to read and maintain. But I need other eyes to check that.

My initial goal was way too ambitious as I want to create a FlagOption subclass of Option. But this is way too big and not sure I can pull it yet. So this is like a first step in that general direction.

@kdeldycke kdeldycke added this to the 8.5.0 milestone Jun 27, 2026
@kdeldycke
kdeldycke force-pushed the option-flag-management-refactor branch 2 times, most recently from 3a9316a to 3b743b8 Compare June 27, 2026 08:20
@kdeldycke
kdeldycke changed the base branch from main to stable July 1, 2026 04:24
@kdeldycke
kdeldycke changed the base branch from stable to main July 1, 2026 04:55
@Rowlando13

Copy link
Copy Markdown
Member

@kdeldycke This looks good. @davidism Can you take a look?

@kdeldycke
kdeldycke requested review from Rowlando13 and davidism July 6, 2026 07:07
@Rowlando13 Rowlando13 modified the milestones: 8.5.0, 9.0.0 Jul 8, 2026
@kdeldycke

Copy link
Copy Markdown
Collaborator Author

Given #3676 , I guess the milestone change to 9.0.0 is just the blast radius of the recent main <-> stable dance. So I retarget this to 8.5.0 unless an explicit decision is made.

@kdeldycke kdeldycke modified the milestones: 9.0.0, 8.5.0 Jul 8, 2026
@kdeldycke
kdeldycke force-pushed the option-flag-management-refactor branch 2 times, most recently from 5f080f8 to 4e99c30 Compare July 8, 2026 16:22
@kdeldycke
kdeldycke force-pushed the option-flag-management-refactor branch from 4e99c30 to 8f30085 Compare July 11, 2026 14:01
@Rowlando13
Rowlando13 merged commit b551fe8 into pallets:main Jul 16, 2026
12 checks passed
@kdeldycke
kdeldycke deleted the option-flag-management-refactor branch July 16, 2026 05:00
kdeldycke added a commit to kdeldycke/click-extra that referenced this pull request Jul 16, 2026
Click's main branch (pallets/click#3641) stopped materializing an
option's flag_value at construction: plain options and counters now
carry the UNSET sentinel instead of None, and boolean flags carry it
instead of True, the effective value moving to the new lazy
flag_activation_value property.

That sentinel leaked into two readers. option_value_kind() classified
every plain option as taking an optional value (UNSET is not None), so
generated Carapace specs marked required values with "?" instead of "="
and man pages dropped value metavars. And the --show-params table
rendered the raw sentinel in its flag_value column instead of the value
released Click materializes.

Treat UNSET as "no declared flag value" in the classifier, and read
flag_activation_value as the fallback in the table renderer, mirroring
released Click's materialized values byte for byte on every supported
version.

Co-Authored-By: Claude <noreply@anthropic.com>
@github-actions github-actions Bot locked as resolved and limited conversation to collaborators Jul 31, 2026
@kdeldycke kdeldycke added parsing Parsing, parameters, commands, chaining, context and removed f:parameters labels Aug 8, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

parsing Parsing, parameters, commands, chaining, context

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants