Skip to content

Instantly share code, notes, and snippets.

@laundmo
Created November 15, 2022 10:10
Show Gist options
  • Save laundmo/e65deb2d7515f83447735ce611d87a8c to your computer and use it in GitHub Desktop.
Save laundmo/e65deb2d7515f83447735ce611d87a8c to your computer and use it in GitHub Desktop.
click python FirstOf ParamType
class FirstOf(click.ParamType):
def __init__(
self,
*param_types: click.ParamType,
name: Optional[str] = None,
return_param: bool = False,
):
self.param_types = param_types
self.return_param = return_param
if not getattr(self, "name", None):
if name:
self.name = name
else:
# Set name to union representation of individual params.
# Using bitwise-or operator as thats used by python sets for union.
self.name = "(" + " | ".join(p.name for p in self.param_types) + ")"
def convert(
self, value: str, param: Optional[click.Parameter], ctx: Optional[click.Context]
) -> Any:
# Collect failure messages to emit later.
fails: List[Tuple[click.ParamType, str]] = []
for param_type in self.param_types:
try:
result = param_type.convert(value, param, ctx)
return (param_type, result) if self.return_param else result
except click.BadParameter as e:
fails.append((param_type, str(e)))
self.fail(
"All possible options exhausted without any successful conversion:\n - "
+ "\n - ".join(
[
indent(
f"{getattr(f[0], 'name', f[0].__class__.__name__).upper()}:"
f" {f[1]}",
" ",
)
for f in fails
]
)
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment