Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 14 additions & 2 deletions cmd2/annotated.py
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,8 @@ def do_paint(
Any,
ClassVar,
Literal,
ParamSpec,
Protocol,
TypedDict,
TypeVar,
Union,
Expand Down Expand Up @@ -2136,8 +2138,18 @@ def handler(self_arg: Any, ns: Any) -> Any:
return handler, subcmd_name, parser_builder


_CommandParams = ParamSpec("_CommandParams")

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Recommend adding a brief bug fix blurb to the CHANGELOG.md file about fixing type hinting for this stuff.

_CommandReturn = TypeVar("_CommandReturn")


class _WithAnnotatedDecorator(Protocol):
"""The signature-preserving decorator ``with_annotated(...)`` returns (generic per call)."""

def __call__(self, fn: "Callable[_CommandParams, _CommandReturn]", /) -> "Callable[_CommandParams, _CommandReturn]": ...

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Unnecessary string annotations for Callable can cause type variable binding issues.

Since Callable, _CommandParams, and _CommandReturn are already defined, there is no need to use string forward references here. Unquoted types ensure better compatibility and correct type variable binding across different type checkers (like mypy or pyright).

Recommend:

def __call__(self, fn: Callable[_CommandParams, _CommandReturn], /) -> Callable[_CommandParams, _CommandReturn]:



@overload
def with_annotated(func: Callable[..., Any]) -> Callable[..., Any]: ...
def with_annotated(func: Callable[_CommandParams, _CommandReturn]) -> Callable[_CommandParams, _CommandReturn]: ...


@overload
Expand All @@ -2160,7 +2172,7 @@ def with_annotated(
subcommand_title: str | None = ...,
subcommand_description: str | None = ...,
**parser_kwargs: Unpack[Cmd2ParserKwargs],
) -> Callable[[Callable[..., Any]], Callable[..., Any]]: ...
) -> _WithAnnotatedDecorator: ...


def with_annotated(
Expand Down
Loading