Skip to content

Fix get_parameter_source() returning None in type.convert() and callbacks#3477

Closed
Priyanshu-byte-coder wants to merge 1 commit into
pallets:mainfrom
Priyanshu-byte-coder:fix/get-parameter-source-none-in-callbacks
Closed

Fix get_parameter_source() returning None in type.convert() and callbacks#3477
Priyanshu-byte-coder wants to merge 1 commit into
pallets:mainfrom
Priyanshu-byte-coder:fix/get-parameter-source-none-in-callbacks

Conversation

@Priyanshu-byte-coder
Copy link
Copy Markdown

Summary

Fixes #3458

In 8.4.0, handle_parse_result() was refactored to support feature-switch group arbitration (#3403). As part of that refactor, ctx.set_parameter_source() was moved to after process_value() completes. This broke any ParamType.convert() implementation or option callback that calls ctx.get_parameter_source(param.name) — they received None instead of the actual source.

This also causes pallets/flask#6025 (FLASK_DEBUG env var stopped working in click 8.4), where Flask's _set_debug callback relies on get_parameter_source() to distinguish default values from user-set ones.

Root cause

consume_value()              ← source determined here
process_value()              ← type.convert() / callback called here
  └─ type.convert(value, param, ctx)
       └─ ctx.get_parameter_source(param.name)  ← returns None! ❌
ctx.set_parameter_source()  ← source registered here (too late)

Fix

Set the source immediately after consume_value(), before process_value() is called. If the parameter subsequently loses feature-switch arbitration (another parameter with a more explicit source already claimed the slot), restore the winner's source.

consume_value()              ← source determined here
ctx.set_parameter_source()  ← registered early ✅
process_value()
  └─ type.convert(value, param, ctx)
       └─ ctx.get_parameter_source(param.name)  ← returns correct source ✅
arbitration                 ← restore winner's source if we lose

The arbitration semantics for ctx.params are unchanged.

Test plan

  • test_get_parameter_source_available_in_type_convert — asserts convert() sees DEFAULT for default invocation and COMMANDLINE for CLI invocation
  • test_get_parameter_source_available_in_callback — same check for option callbacks
  • All existing test_parameter_source parametrized cases still pass
  • Feature-switch group tests (if any) still pass

…acks

In 8.4.0, handle_parse_result() was refactored to defer
ctx.set_parameter_source() until after process_value() to support
feature-switch group arbitration (pallets#3403). This meant that
ParamType.convert() and option callbacks called during process_value()
saw None from ctx.get_parameter_source(), breaking any code that uses
the source to distinguish user-set values from defaults.

Fix: set the source early (immediately after consume_value), before
process_value() is called. If the parameter subsequently loses the
feature-switch arbitration, restore the winning parameter's source.
This preserves the arbitration semantics while making the source
queryable at the right time.

Fixes pallets#3458
@davidism davidism closed this May 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

get_parameter_source() returns None in 8.4

2 participants