Skip to content

[Feature Request] Officially support the runtime-hostile @typer.Typer.command decorator 🥹  #436

@leycec

Description

@leycec

Let's officially support typer, an increasingly popular annotations-centric CLI framework. Sadly, typer violates PEP standards in a few obvious ways. But... who really cares!? typer is nifty. Nifty packages deserve our support. Let's do this when we get a spare free moment.

@taranlu-houzz over at discussion #434 has all the spicy deets:

As far as the typer issue goes, it mainly has to do with how one turns normal functions into typer commands. Since typer also does validation and some other complex work based on your function params, it is often necessary to use the typer.Option or typer.Argument objects, which triggers beartype if you try to use the function (that had been decorated by typer) with that actual expected values that would be passed to the function.

@APP.command()
def sync(
    targets: list[int] = typer.Argument(
        ...,
        metavar="PID [PID [...]]",
        help="Target PIDs to sync tile data for.",
    ),
    submit_change: bool = typer.Option(
        False,
        rich_help_panel="Perforce Options",
        help="Whether or not to submit the changelist with the downloaded tile data (if any).",
    ),
) -> None:
    ...

So, for example, the submit_change param expects a typer.Option object as far as beartype is concerned, even though it would be reasonable to call this function by passing a bool directly.

What Can Be Done Until @leycec Does Something, Though?

Thankfully, you don't have to wait for @leycec to finally do something. Instead, just tell @beartype that it should ignore all @APP.command()-decorated callables like so:

from typing import no_type_check

@APP.command()
@no_type_check
def sync(
    targets: list[int] = typer.Argument(
        ...,
        metavar="PID [PID [...]]",
        help="Target PIDs to sync tile data for.",
    ),
    submit_change: bool = typer.Option(
        False,
        rich_help_panel="Perforce Options",
        help="Whether or not to submit the changelist with the downloaded tile data (if any).",
    ),
) -> None:
    ...

Like all runtime type-checkers (e.g., typeguard) and static type-checkers (e.g., mypy, pyright), @beartype silently ignores all callables and classes decorated by the standard @typing.no_type_check decorator. Since typer kinda violates PEP standards, ...sad! it's helpful to notify type-checkers that they should ignore typer-based callables.

@beartype + typer: soon to be a match made in CLI heaven. 👼

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions