Skip to content

feat(extras): add Verbosity type for -v/-q count flags#445

Merged
brentyi merged 7 commits intobrentyi:mainfrom
jRimbault:feat/verbosity-extra
Mar 31, 2026
Merged

feat(extras): add Verbosity type for -v/-q count flags#445
brentyi merged 7 commits intobrentyi:mainfrom
jRimbault:feat/verbosity-extra

Conversation

@jRimbault
Copy link
Copy Markdown
Contributor

@jRimbault jRimbault commented Mar 19, 2026

Following up on our Reddit thread, here's the actual proposal.

We have a Verbosity dataclass we keep reusing across internal tools (we've already packaged it internally to not repeat ourselves though, so this doesn't need to be upstreamed, I just think it'd be nice in the ecosystem). It bundles mutually exclusive --verbose/-v and --quiet/-q count flags and exposes a log_level() method mapping them to Python logging levels. Since it's built on UseCounterAction and create_mutex_group, it's entirely composed from existing tyro primitives.

Usage

import dataclasses
import logging
from pathlib import Path
from typing import Annotated

import tyro
from tyro.conf import OmitArgPrefixes
from tyro.extras import Verbosity

@dataclasses.dataclass
class Args:
    path: Path = dataclasses.field(default_factory=Path.cwd)
    verbosity: Annotated[Verbosity, OmitArgPrefixes] = dataclasses.field(
        default_factory=Verbosity
    )
    """Log verbosity."""

args = tyro.cli(Args)
logging.basicConfig(level=args.verbosity.log_level())

OmitArgPrefixes promotes the flags to the top level (--verbose, --quiet). Without it, they're prefixed as usual (--verbosity.verbose, --verbosity.quiet), but the -v/-q short aliases always work regardless.

Default level mapping (baseline: WARNING):

Flags Level
(none) WARNING
-v INFO
-vv DEBUG
-q ERROR
-qq CRITICAL

Values are clamped to DEBUG..CRITICAL.

Prior art

The pattern is borrowed from clap-verbosity-flag, maintained by the clap maintainers, which provides the same type for Rust CLIs.


A few things I'm unsure about before you review:

  • Is that something you'd like in tyro itself? Or would you rather that I make a third party package kinda like the clap ecosystem
  • Whether tyro.extras is the right home, or if it belongs closer to tyro.conf
  • Whether baking OmitArgPrefixes into the type automatically (via a custom struct rule) would be preferred over leaving it explicit

Happy to adjust either. Let me know what you think.

Loving the library by the way, it's a staple in our internal tooling.

Adds tyro.extras.Verbosity, a frozen dataclass that wires up mutually
exclusive --verbose/-v and --quiet/-q count flags and exposes a
log_level() method mapping them to Python logging levels.

Inspired by clap-verbosity-flag from the Rust/clap ecosystem.
@jRimbault jRimbault force-pushed the feat/verbosity-extra branch from ac49aae to 968d933 Compare March 19, 2026 07:44
@brentyi
Copy link
Copy Markdown
Owner

brentyi commented Mar 23, 2026

Hi @jRimbault thanks for taking the time to make this PR, and also for your nice words!

This feels generally useful enough to include in tyro.extras. It'll also be a nice real world thing to cover in the tests. I'll find time this week to take a proper look and merge 🙂

jRimbault added a commit to jRimbault/fixture-graph that referenced this pull request Mar 30, 2026
Adapted from tyro PR #445 (brentyi/tyro#445). Provides a Verbosity
dataclass that maps counter flags to Python logging levels.
Copy link
Copy Markdown
Owner

@brentyi brentyi left a comment

Choose a reason for hiding this comment

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

Thanks @jRimbault!!

@brentyi brentyi merged commit 1da233b into brentyi:main Mar 31, 2026
15 of 16 checks passed
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