Skip to content

Commit

Permalink
fix: Only show_default on --*/--no-* pair bool arguments for the ac…
Browse files Browse the repository at this point in the history
…tual default.
  • Loading branch information
DanCardin committed Oct 23, 2024
1 parent 5c11df5 commit 761bf41
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 2 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ s.
- feat: User defined parsers can access the `TypeView` by accepting it as an argument.
- feat: Add new API for defining subcommands as methods.
- feat: Add Arg.show_default option to optionally avoid displaying default in help text.
- fix: Only show_default on `--*/--no-*` pair bool arguments for the actual default.

## 0.23

Expand Down
11 changes: 9 additions & 2 deletions src/cappa/arg.py
Original file line number Diff line number Diff line change
Expand Up @@ -621,11 +621,18 @@ def explode_negated_bool_args(args: typing.Sequence[Arg]) -> typing.Iterable[Arg
positives = [item for item in long if "--no-" not in item]
if negatives and positives:
positive_arg = dataclasses.replace(
arg, long=positives, action=ArgAction.store_true
arg,
long=positives,
action=ArgAction.store_true,
show_default=arg.default is True,
)
negative_arg = dataclasses.replace(
arg, long=negatives, action=ArgAction.store_false
arg,
long=negatives,
action=ArgAction.store_false,
show_default=arg.default is False,
)

yield positive_arg
yield negative_arg
yielded = True
Expand Down
71 changes: 71 additions & 0 deletions tests/arg/test_show_default.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
from __future__ import annotations

from dataclasses import dataclass

import pytest
from typing_extensions import Annotated

import cappa
from tests.utils import TestOutput, backends, parse


@backends
def test_show_default_default_true(backend, capsys):
@dataclass
class Command:
foo: bool = False

assert parse(Command, backend=backend).foo is False

with pytest.raises(cappa.HelpExit):
parse(Command, "--help", backend=backend)

output = TestOutput.from_capsys(capsys)
assert "(Default: False)" in output.stdout


@backends
def test_show_default_set_false(backend, capsys):
@dataclass
class Command:
foo: Annotated[bool, cappa.Arg(show_default=False)] = False

assert parse(Command, backend=backend).foo is False

with pytest.raises(cappa.HelpExit):
parse(Command, "--help", backend=backend)

output = TestOutput.from_capsys(capsys)
assert "(Default: False)" not in output.stdout


@backends
def test_show_default_no_option_shows_for_false_default(backend, capsys):
@dataclass
class Command:
foo: Annotated[bool, cappa.Arg(long="--foo/--no-foo")] = False

assert parse(Command, backend=backend).foo is False

with pytest.raises(cappa.HelpExit):
parse(Command, "--help", backend=backend)

stdout = TestOutput.from_capsys(capsys).stdout.replace(" ", "")
assert "[--foo](Default:True)" not in stdout
assert "[--no-foo](Default:False)" in stdout


@backends
def test_show_default_no_option_shows_for_true_default(backend, capsys):
@dataclass
class Command:
foo: Annotated[bool, cappa.Arg(long="--foo/--no-foo")] = True

assert parse(Command, backend=backend).foo is True

with pytest.raises(cappa.HelpExit):
parse(Command, "--help", backend=backend)

stdout = TestOutput.from_capsys(capsys).stdout.replace(" ", "")
assert "[--foo](Default:True)" in stdout
assert "[--no-foo](Default:False)" not in stdout
15 changes: 15 additions & 0 deletions tests/utils.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import contextlib
from dataclasses import dataclass
from typing import Union
from unittest.mock import patch

Expand Down Expand Up @@ -57,3 +58,17 @@ def ignore_docstring_parser(monkeypatch):

def strip_trailing_whitespace(text):
return "\n".join([line.rstrip() for line in text.split("\n")])


@dataclass
class TestOutput:
stdout: str
stderr: str

@classmethod
def from_capsys(cls, capsys):
outerr = capsys.readouterr()

out = strip_trailing_whitespace(outerr.out)
err = strip_trailing_whitespace(outerr.err)
return cls(out, err)

0 comments on commit 761bf41

Please sign in to comment.