Skip to content

conflict when short option does not match first letter of long option #233

Description

@sswam

Summary

The bug happens when:

  1. An option has a short name (-n) that doesn't match its long name (--user-name).
  2. Another option is added with a long name (--note) starting with the same letter as the first option's short name.
  3. Even if the second option has its own short name (-N), argh tries to create another short name (-n) based on its long name.
  4. This causes a conflict with the first option's short name (-n), resulting in an exception.

The issue stems from argh attempting to automatically generate short names for long options, even when explicit short names are provided.

The error message is:

argh.exceptions.AssemblingError: query: cannot add 'note' as -n/--note/-N: argument -n/--note/-N: conflicting option string: -n

To Reproduce

Python script:

import argh

@argh.arg("-n", "--user-name")
@argh.arg("-N", "--note")
def hello(user_name="world", note=""):
    return f"hello, {name}! {note}"

if __name__ == "__main__":
    argh.dispatch_command(hello)

Command line input/output:

$ python bug.py
Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/argh/assembling.py", line 454, in set_default_command
    action = parser.add_argument(
             ^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/argparse.py", line 1507, in add_argument
    return self._add_action(action)
           ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/argparse.py", line 1889, in _add_action
    self._optionals._add_action(action)
  File "/usr/lib/python3.12/argparse.py", line 1709, in _add_action
    action = super(_ArgumentGroup, self)._add_action(action)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/argparse.py", line 1521, in _add_action
    self._check_conflict(action)
  File "/usr/lib/python3.12/argparse.py", line 1658, in _check_conflict
    conflict_handler(action, confl_optionals)
  File "/usr/lib/python3.12/argparse.py", line 1667, in _handle_conflict_error
    raise ArgumentError(action, message % conflict_string)
argparse.ArgumentError: argument -n/--note/-N: conflicting option string: -n

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/tmp/bug.py", line 30, in <module>
    argh.dispatch_command(hello)
  File "/usr/lib/python3/dist-packages/argh/dispatching.py", line 470, in dispatch_command
    set_default_command(parser, function, name_mapping_policy=name_mapping_policy)
  File "/usr/lib/python3/dist-packages/argh/assembling.py", line 460, in set_default_command
    raise AssemblingError(
argh.exceptions.AssemblingError: hello: cannot add 'note' as -n/--note/-N: argument -n/--note/-N: conflicting option string: -n

Expected behavior

Not raise an exception.

Environment

  • OS: Linux
  • Python version: Python 3.12.5
  • Argh version: 0.31.3

Additional context

I'm using argh for a lot of AI-related tools. This problem has occured a few times.

I asked OpenAI o1-preview to fix it, and it didn't quite manage it,
but I figured it out eventually, see PR #234

Activity

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

Metadata

Metadata

Assignees

Labels

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions