Skip to content

Commit a6a54f2

Browse files
committed
fix: Destructured args to inherit default_long and default_short.
1 parent e097fc5 commit a6a54f2

4 files changed

Lines changed: 61 additions & 2 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
- fix: Precalculate implicit deps during class construction rather than traversing the output shape.
1414
- fix: Thread `output` into `parse_result.instance` resolution in `parse`/`parse_async`/`invoke`/`invoke_async`, so `cappa.Exit` raised from `Arg(parse=...)` callbacks renders an error message instead of silently exiting non-zero.
1515
- refactor: Destructured implementation to be more like Arg handling to fix default and helptext behavior.
16+
- fix: Destructured args to inherit `default_long` and `default_short`.
1617

1718
## 0.31
1819

src/cappa/arg.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -522,7 +522,12 @@ def normalize(
522522
)
523523

524524
destructure = Destructure.collect(
525-
field_name, default, destructure or self.destructure, type_view
525+
field_name,
526+
default,
527+
destructure or self.destructure,
528+
type_view,
529+
default_short=default_short,
530+
default_long=default_long,
526531
)
527532
result: FinalArg[Any] = FinalArg(
528533
# preserved from self

src/cappa/destructure.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ def collect(
2424
default: Default,
2525
destructure: Destructure | bool | None,
2626
type_view: TypeView[Any],
27+
default_short: bool = False,
28+
default_long: bool = False,
2729
) -> FinalDestructure[Any] | None:
2830
if not destructure:
2931
return None
@@ -37,7 +39,13 @@ def collect(
3739
"Destructured arguments currently only support singular concrete types."
3840
)
3941

40-
command: FinalCommand[Any] = Command.get(annotation).collect() # pyright: ignore
42+
inner: Command[Any] = Command.get(annotation) # pyright: ignore
43+
inner = replace(
44+
inner,
45+
default_short=inner.default_short or default_short,
46+
default_long=inner.default_long or default_long,
47+
)
48+
command: FinalCommand[Any] = inner.collect()
4149
return FinalDestructure(
4250
field_name=field_name,
4351
command=command,
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
from __future__ import annotations
2+
3+
from dataclasses import dataclass
4+
5+
import cappa
6+
from tests.utils import parse
7+
8+
9+
@dataclass
10+
class Args:
11+
foo: int = 4
12+
bar: int = 5
13+
14+
15+
@cappa.command(default_long=True, default_short=True)
16+
@dataclass
17+
class Command:
18+
args: cappa.Destructured[Args]
19+
20+
21+
@cappa.command(default_long=True)
22+
@dataclass
23+
class InnerOverrideArgs:
24+
foo: int = 4
25+
26+
27+
@cappa.command(default_long=False)
28+
@dataclass
29+
class InnerOverrideCommand:
30+
args: cappa.Destructured[InnerOverrideArgs]
31+
32+
33+
def test_default_long_propagates():
34+
test = parse(Command, "--foo", "1", "--bar", "2")
35+
assert test == Command(Args(1, 2))
36+
37+
38+
def test_default_short_propagates():
39+
test = parse(Command, "-f", "1", "-b", "2")
40+
assert test == Command(Args(1, 2))
41+
42+
43+
def test_inner_command_setting_takes_precedence():
44+
test = parse(InnerOverrideCommand, "--foo", "1")
45+
assert test == InnerOverrideCommand(InnerOverrideArgs(1))

0 commit comments

Comments
 (0)