Skip to content

Complete values attached to unquoted short options - #564

Open
codeofwxz wants to merge 2 commits into
kislyuk:mainfrom
codeofwxz:fix-attached-short-option-values
Open

codeofwxz wants to merge 2 commits into
kislyuk:mainfrom
codeofwxz:fix-attached-short-option-values

Conversation

@codeofwxz

@codeofwxz codeofwxz commented Sep 12, 2026

Copy link
Copy Markdown

Related #563.

Unquoted attached values such as -oo and -boo currently return no completions for -o with choices one, two, and three. This change resolves the current word using argparse's option lookup, walks valid leading switches, and completes the value with its original option prefix (-oone or -boone). It also handles a cluster ending in a value-taking option, such as -bo.

Exact option names and ambiguous abbreviations retain argparse's precedence. The lookup respects nargs and mutual exclusion; leading switches contribute to the completer's local namespace only when their action class is already in safe_actions. Custom value completers receive the value prefix, and completion descriptions retain the reconstructed option prefix.

This is a partial fix: completion inside an unclosed quote, including the quoted examples in #563, remains on the existing path. Shell replacement boundaries for those examples are not addressed here.

Initial revision validation on Windows with Python 3.12.14 and 3.14.4:

  • Nine new unittest methods covering 28 cases pass, including choices, clusters, nargs, option precedence, custom completers, unsafe actions, subparsers, mutual exclusion, and negative attached values. Fourteen cases fail against the unchanged production baseline.
  • Ruff check, Ruff format check, mypy, and wheel build pass.
  • The full upstream unittest suite was attempted on both Python versions. The baseline has 191 tests and this branch 200; both report the same 2 failures, 131 errors, 12 skips, and 1 expected failure. The failing/error test identities and exception categories match. These are not full-suite passes.
  • A local wrapper resolves only the test module's import-time Bash version probe to existing Git Bash, since bare bash selects an unavailable Windows launcher. The wrapper is not part of this patch. Real interactive Bash/Zsh/pexpect Tab insertion and the Linux/macOS CI matrix have not been validated locally.

Review revision: attached values now also complete when ExclusiveCompletionFinder has already seen the option in an earlier word. The change retains custom finder constraints, mutual exclusion, and the current cluster's count context. Thirteen targeted unittest methods pass on Python 3.14, with Ruff lint/format checks passing. This revision was not rerun through the full suite or an interactive shell Tab test; the initial validation and limitations above remain historical results for the initial revision.

Copilot AI lite review requested due to automatic review settings September 12, 2026 15:18

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Changes recommended

Fix attached-value dispatch so exclusive completion supports valid attached values.

Get a fresh assessment by requesting another Copilot review.

Pull request overview

Adds completion for values attached to unquoted short-option clusters while preserving argparse precedence and context.

Changes:

  • Implements attached-value parsing and reconstructed completion prefixes.
  • Handles nargs, conflicts, subparsers, custom completers, and safety rules.
  • Adds regression coverage for clustered options and edge cases.
File summaries
File Summary
test/test.py Adds regression tests for attached values and clusters.
argcomplete/finders.py Implements attached-option completion. A moderate issue remains: ExclusiveCompletionFinder rejects attached actions for inputs such as -oo at lines 437 and 445.
Review details

Suppressed comments (1)

argcomplete/finders.py:448

  • The parser has already executed each safe leading action while parsing this token (the introspection hook calls _orig_callable for safe_actions before the attached value is completed). Replaying them here increments or appends their state a second time; for example, -bvvoo leaves parsed_args.v == 2 after parsing but this loop changes the copied namespace to 4, so the new cluster-context test fails. Keep the copied namespace, but do not invoke the leading actions again.
                parsed_args = argparse.Namespace(**vars(parsed_args))
                for action, option_string in leading_options:
                    if action._orig_class in safe_actions:
                        action._orig_callable(parser, parsed_args, [], option_string=option_string)
  • Files reviewed: 2/2 changed files
  • Comments generated: 1
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread argcomplete/finders.py Outdated
attached_action, optional_prefix, cword_prefix, leading_options = attached
seen_actions = set()
for action in [item[0] for item in leading_options] + [attached_action]:
if not self._action_allowed(action, parser) or any(
@codeofwxz

Copy link
Copy Markdown
Author

Thanks for calling out the ExclusiveCompletionFinder interaction. The first-use prog -oo case already completes successfully: the current word is excluded from the words passed to parse_known_args, so that action has not been recorded as seen yet.

There was a related gap when an option had appeared in an earlier word: prog -o one -oo and prog -v -bvvoo returned no attached completion with ExclusiveCompletionFinder, although their separated-value equivalents worked. This revision fixes those cases by relaxing only the seen-option suggestion filter while checking an explicitly typed attached value. It still dispatches through the finder override and preserves mutual exclusion. The new regressions fail on those two cases before the fix and pass afterward.

The count replay should remain: switches in the current word have not been parsed. Protocol tests confirm prog -bvvoo supplies v=2, and prog -v -bvvoo supplies v=3. Removing that replay would lose the current cluster's count and boolean context.

Validation: 13 targeted unittest methods passed on Python 3.14, plus Ruff lint/format checks. This revision was tested through the completion protocol, without a full suite run or interactive shell Tab test.

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.

2 participants