Skip to content

Fix shell completion for --option=value format#3237

Open
Simon99 wants to merge 3 commits intopallets:stablefrom
Simon99:fix/option-equals-completion
Open

Fix shell completion for --option=value format#3237
Simon99 wants to merge 3 commits intopallets:stablefrom
Simon99:fix/option-equals-completion

Conversation

@Simon99
Copy link

@Simon99 Simon99 commented Mar 1, 2026

Summary

Fixes #2847

When using --option=value style completion in bash/zsh, the shell passes --option=partial as the incomplete value. After resolving completions, the code was returning plain values (e.g., auto) without the option prefix. This caused the shell to replace --option= with just auto, resulting in command auto instead of command --option=auto.

The Problem

# User types:
command --color=<TAB>

# Before fix: Shell receives 'auto', replaces '--color=' with 'auto'
# Result: 'command auto' ❌

# After fix: Shell receives '--color=auto'  
# Result: 'command --color=auto' ✅

The Fix

In ShellComplete.complete(), detect when the incomplete value is in --option=... format and prepend the --option= prefix to each completion value.

Testing

  • Added test cases for bash and zsh completion with --option= format
  • All 56 existing tests pass
  • Verified manually that --option value (space) format still works correctly

Simon99 and others added 2 commits March 1, 2026 20:42
Fixes pallets#2847

When using `--option=value` style completion in bash/zsh, the shell passes
`--option=partial` as the incomplete value. After resolving completions,
the code was returning plain values (e.g., `auto`) without the option prefix.
This caused the shell to replace `--option=` with just `auto`, resulting in
`command auto` instead of `command --option=auto`.

The fix detects when the incomplete value is in `--option=...` format and
prepends the `--option=` prefix to each completion value.
@kdeldycke
Copy link
Collaborator

I like the extensive test_option_equals_completion test cases which prove the fix is working. That's good enough for me to be merged upstream and target 8.3.2.

@kdeldycke kdeldycke added this to the 8.3.2 milestone Mar 1, 2026
@kdeldycke kdeldycke added bug f:completion feature: shell completion labels Mar 1, 2026
@kdeldycke kdeldycke changed the title Fix shell completion for --option=value format Fix shell completion for --option=value format Mar 1, 2026
@kdeldycke kdeldycke changed the base branch from main to stable March 1, 2026 16:40
@pytest.mark.parametrize(
("shell", "env", "expect"),
[
# Test --option= format (issue #2847)
Copy link
Member

Choose a reason for hiding this comment

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

Don't mention the issue number, all information should be in the comment if it's needed at all.

{"COMP_WORDS": "cli --color=r", "COMP_CWORD": "1"},
"plain,--color=red\n",
),
# Space format should still work without prefix
Copy link
Member

Choose a reason for hiding this comment

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

This test is redundant. It's the default behavior already tested by other cases.

{"COMP_WORDS": "cli --color ", "COMP_CWORD": "2"},
"plain,red\nplain,green\nplain,blue\n",
),
# Zsh tests
Copy link
Member

Choose a reason for hiding this comment

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

The fix doesn't differ based on shell type so this test is unnecessary.

def test_option_equals_completion(runner, shell, env, expect):
"""Test that --option=value style completion works correctly.

Fixes https://github.com/pallets/click/issues/2847
Copy link
Member

Choose a reason for hiding this comment

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

Don't include issues all information should be in the comment if needed at all.

"""
args, incomplete = self.get_completion_args()

# Fix #2847: When completing ``--option=value`` style, the shell
Copy link
Member

Choose a reason for hiding this comment

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

Don't include the issue all information should be in the comment.

This comment is extremely verbose for what it's actually saying don't use AI to write comments

option_prefix = ""
if "=" in incomplete:
name, _, _ = incomplete.partition("=")
if name.startswith("-"):
Copy link
Member

Choose a reason for hiding this comment

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

Why is this check here?

if option_prefix:
for item in completions:
# Only add prefix to values, not to option names
if not str(item.value).startswith("-"):
Copy link
Member

Choose a reason for hiding this comment

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

Why does the value need to be converted to a string here?

if "=" in incomplete:
name, _, _ = incomplete.partition("=")
if name.startswith("-"):
option_prefix = name + "="
Copy link
Member

Choose a reason for hiding this comment

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

Use F strings not concatenation.

if name.startswith("-"):
option_prefix = name + "="

completions = self.get_completions(args, incomplete)
Copy link
Member

Choose a reason for hiding this comment

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

How is this working? Shouldn't we need to add the modified option token to the arguments list?

@davidism
Copy link
Member

davidism commented Mar 1, 2026

@kdeldycke this looks like AI junk to me. We shouldn't merge this.

@kdeldycke
Copy link
Collaborator

@kdeldycke this looks like AI junk to me. We shouldn't merge this.

Oh yes you are right. I did not evaluate the fix, I was just looking at the tests and compared them to the problem described in #2847. Which looked good enough to me. Should have been more explicit in my previous comment.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug f:completion feature: shell completion

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Long option completion with = broken

3 participants