Skip to content

Fix get_parameter_source() during type conversion and eager callbacks#3484

Merged
davidism merged 2 commits into
pallets:stablefrom
yurishevtsov:fix-parameter-source-before-process-value
May 21, 2026
Merged

Fix get_parameter_source() during type conversion and eager callbacks#3484
davidism merged 2 commits into
pallets:stablefrom
yurishevtsov:fix-parameter-source-before-process-value

Conversation

@yurishevtsov
Copy link
Copy Markdown

@yurishevtsov yurishevtsov commented May 20, 2026

Summary

Click 8.4.0 moved set_parameter_source() to after process_value() when fixing flag-group arbitration (#3403, #3404). That broke a case wasn't meant to change: anything that calls get_parameter_source() during type conversion or in an eager callback saw None, even though consume_value() had already figured out where the value came from (#3458).

This is affecting Flask: with Click 8.4.0, FLASK_DEBUG=1 in the environment was ignored because _set_debug runs as an eager callback and could no longer see that the --debug flag was only at its default (pallets/flask#6025).

The fix is to record the source right after consume_value() and before process_value(), matching 8.3.3 timing for callbacks and custom types. Flag-group arbitration is the same as today.

There is a second, narrower issue on the same code path: recording the source early means a losing option in a feature-switch group briefly overwrites _parameter_source before arbitration runs. I am solving it by restoring the previous source when an option loses the slot. That path is easy to miss in tests (shared opts may give the loser the same source as the winner), so there is a dedicated case in test_bool_flag_group_parameter_source. More detail is in the comments around handle_parse_result.

fixes #3458

Tests added / updated

  • tests/test_defaults.py — issue repro (ParamType.convert), eager callback, Flask-style _set_debug guard
  • tests/test_options.pytest_bool_flag_group_parameter_source (includes a loser-restore case with envvar, not only CLI + default_map)

@Rowlando13 Rowlando13 requested a review from kdeldycke May 20, 2026 00:10
Comment thread src/click/core.py
Comment thread src/click/core.py
Comment thread src/click/core.py
@davidism davidism added this to the 8.4.1 milestone May 21, 2026
@kdeldycke kdeldycke changed the base branch from main to stable May 21, 2026 12:03
@kdeldycke kdeldycke changed the title Fix get_parameter_source() during type conversion and eager callbacks Fix get_parameter_source() during type conversion and eager callbacks May 21, 2026
yurishevtsov and others added 2 commits May 21, 2026 14:43
Record parameter source on the context immediately after consume_value(),
before process_value() runs. In 8.4.0, set_parameter_source() was deferred
until after type conversion and flag-group arbitration (0f71fe7, pallets#3403), so
get_parameter_source() returned None inside ParamType.convert() and eager
callbacks (pallets#3458).

When several options share one parameter name, the losing option still sets a
provisional source before process_value(); restore the previous source if
arbitration rejects it so the winner's origin is not replaced unintentionally.
@kdeldycke kdeldycke force-pushed the fix-parameter-source-before-process-value branch from 547d9a4 to 0baa8db Compare May 21, 2026 13:06
Copy link
Copy Markdown
Collaborator

@kdeldycke kdeldycke left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This fix is more generic than my own fix in Click Extra at: kdeldycke/click-extra@9fe4e8b

Tests are good to me and checks all variations. One thing I realized: in https://click.palletsprojects.com/en/stable/advanced/#parameter-modifications , we document the overriding of one parameter from the callback of another. I didn't know how the get_parameter_source would react in that case so I added a unittest to lockdown the current behavior. Also used the opportunity to add an admonition in the docs to highlight the danger of that kind of bypass.

Also added a reference to the PR in the changelog.

@kdeldycke
Copy link
Copy Markdown
Collaborator

An alternative, long term solution would be to restructure the pipeline and the parameter loop that is happening above. But that is a bigger refactor for later. So this PR is a good local minimal patch for 8.4.1.

@kdeldycke kdeldycke added bug f:parameters feature: input parameter types labels May 21, 2026
@davidism davidism merged commit d42f15b into pallets:stable May 21, 2026
12 checks passed
@kdeldycke
Copy link
Copy Markdown
Collaborator

Thanks @davidism for the merge! :)

kdeldycke added a commit to kdeldycke/click-extra that referenced this pull request May 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug f:parameters feature: input parameter types

Projects

None yet

Development

Successfully merging this pull request may close these issues.

get_parameter_source() returns None in 8.4.0

3 participants