Skip to content

Instantly share code, notes, and snippets.

@sirosen
Last active January 2, 2023 15:29
Show Gist options
  • Save sirosen/a4788d0adae067d6e196c791594674eb to your computer and use it in GitHub Desktop.
Save sirosen/a4788d0adae067d6e196c791594674eb to your computer and use it in GitHub Desktop.
click annotation validation
import typing as t
import click
def deco(f):
f = click.option("--foo")(f)
f = click.option("--bar", type=int)(f)
return f
@click.command
@deco
def frobulate(*, foo: str | None, bar: int | None) -> None:
pass
@deco
@click.command
def demuddle(*, foo: str | None, bar: int | None) -> None:
pass
# art deco args are arg_deco?
def assert_is_arg_deco(f):
if isinstance(f, click.Command):
hints = t.get_type_hints(f.callback)
else:
hints = t.get_type_hints(f)
assert "foo" in hints
assert "bar" in hints
assert hints["foo"] == t.Union[str, None]
assert hints["bar"] == t.Union[None, int]
assert_is_arg_deco(frobulate)
assert_is_arg_deco(demuddle)
import random
import typing as t
def foo(x: int, y: str | bool) -> t.Any:
if random.random() < 0.5:
return x
return y
def bar(x: int) -> str:
return str(x)
def takes_y_arg(c) -> bool:
annotations = t.get_type_hints(c)
if "y" not in annotations:
return False
if annotations["y"] != t.Union[bool, str]:
return False
return True
print(takes_y_arg(foo))
print(takes_y_arg(bar))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment