Skip to content

fix: callable flag_value being invoked when used as default#1

Draft
daniell-olaitan wants to merge 2 commits into
mainfrom
fix/issue-3121
Draft

fix: callable flag_value being invoked when used as default#1
daniell-olaitan wants to merge 2 commits into
mainfrom
fix/issue-3121

Conversation

@daniell-olaitan

@daniell-olaitan daniell-olaitan commented Jan 24, 2026

Copy link
Copy Markdown
Owner

What was broken

When a callable (class, function, or lambda) was used as flag_value with default=True, Click was incorrectly calling/instantiating the callable when retrieving the default value. This caused classes to be instantiated instead of being returned as class objects.

Example of the bug:

@click.command()                                                              
@click.option("--foo", "ty", flag_value=Foo, type=click.UNPROCESSED, default=True)                                                                 
def main(ty):                                                                 
    click.echo(repr(ty))  # Expected: <class '__main__.Foo'>                  
                          # Actual: <__main__.Foo object at 0x...>           

How it's fixed

The fix introduces a three-component solution across multiple files:

  1. New _FlagValueDefault wrapper class (src/click/_utils.py):
  • Wraps callable flag_values to mark them as "don't call me"
  • Preserves the original callable for use by Option.consume_value()
  1. Modified Option.init() (src/click/core.py:2829):
  • When default=True aligns with a callable flag_value, wraps it in _FlagValueDefault
  • Non-callable flag_values are not wrapped
  1. Modified Parameter.get_default() (src/click/core.py:2283):
  • Detects _FlagValueDefault wrapper and unwraps without calling
  • Normal callable defaults continue to work as expected
  • Works correctly with both call=True and call=False modes

This ensures the fix works across all code paths (default retrieval, help generation, callbacks, etc.) while maintaining backward compatibility with normal callable defaults.

What tests were added

  • New comprehensive test file tests/test_flag_value_callable_fix.py
  • Updated existing test in tests/test_options.py:2978:
    • Changed expectation from instance to class object

Fixes pallets#3121

@daniell-olaitan daniell-olaitan changed the title fix: callable flag_value being invoked when used as default (#3121) fix: callable flag_value being invoked when used as default Jan 24, 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.

Using a class as a flag_value causes the default to be instantiated in click 8.3.0

1 participant