-
-
Notifications
You must be signed in to change notification settings - Fork 8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
print argument string #302
Comments
you could call You could then iterate over it, maybe something like: def pytest_addoption(parser):
app = App()
app.default(cli_args)
argument_collection = app.assemble_argument_collection()
for argument in argument_collection:
parser.addoption(argument.name, ...) # will have to figure out how to translate the other fields. Perhaps concatenating helps might be easier. You can make your own help-handler: @app.command(name=("--help", "-h")):
def custom_help():
# TODO: somehow pass in pytest's parser and print that help here too.
app.help_print(sys.argv[1:]) |
Ooh, splendid. pytest adds the options to their own help, so this might be just what I'm looking for. thanks! |
As ugly as this is, I'm just going to leave this here for future internet travellers. It's ugly and hackish and no-one should use this. But for the simple things it seems to work. Parameters in nested dataclasses don't work yet. _ScopeName = Literal["session", "package", "module", "class", "function"]
@dataclass
class CliParams:
images: Path
device: DeviceOptions,
def cyclopts_fixture(
description: str = "",
scope: _ScopeName | Callable[[str, pytest.Config], _ScopeName] = "function",
params: Iterable[object] | None = None,
autouse: bool = False,
ids: Sequence[object | None] | Callable[[Any], object | None] | None = None,
name: str | None = None,
):
def _cli_args(func: Callable) -> Callable:
fname = name if name is not None else func.__name__
type_hints = get_type_hints(func)
return_type = type_hints.get("return", None)
app = App()
app.default(return_type)
cli_args_app = getattr(pytest, "_cli_args_app", {})
cli_args_app[fname] = {"app": app, "description": description}
setattr(pytest, f"_cli_args_app", cli_args_app)
@wraps(func)
def wrapper(*args, **kwargs):
cli_args = getattr(pytest, "_cli_args", {}).get(fname, None)
return cli_args
return pytest.fixture(wrapper, scope=scope, params=params, autouse=autouse, ids=ids, name=name)
return _cli_args
def flatten_arguments(root: Argument) -> list[Argument]:
if root.children:
return root.children
return [root]
def unique(args: list[Argument]) -> list[Argument]:
res: dict[str, Argument] = {}
for arg in args:
res[arg.name] = arg
return list(res.values())
def pytest_addoption(parser: pytest.Parser):
for name, appdef in getattr(pytest, "_cli_args_app", {}).items():
app = appdef["app"]
description = appdef["description"]
group = parser.getgroup(name, description)
args: list[Argument] = []
argument_collection = app.assemble_argument_collection()
for argument in argument_collection:
args.extend(flatten_arguments(argument))
for arg in unique(args):
dest = arg.name.replace(".", "_").strip("-")
group.addoption(arg.name, dest=dest, type=arg.hint, help=arg.parameter.help)
def pytest_configure(config: pytest.Config):
for name, appdef in getattr(pytest, "_cli_args_app", {}).items():
app = appdef["app"]
_, bound, _, _ = app.parse_known_args(sys.argv)
args = bound.args[0]
cli_args = getattr(pytest, "_cli_args", {})
cli_args[name] = args
setattr(pytest, f"_cli_args", cli_args)
@cyclopts_fixture()
def cli(request) -> CliParams: ... |
So, not content with how pytest uses argparse while there are clearly much better alternatives around, I am trying to hack cyclopts into conftest.py :).
No, this isn't a feature request at all :)
This is what I came up with:
It's not pretty to say the least, but at this point I don't really care :)
What bugs me is that
pytest --help
obviously does not print these with its help message.An alternative is a launcher script that uses cyclopts and then passes the remainder of the arguments to
pytest.main(...)
. This has other drawbacks. Mainly that you have to remember you can't just runpytest
.Now what would be absolutely
uglyideal is to serialize what cyclopts can parse and shove it intopytest_addoption
. This is a terrible idea. That makes it fun 😄 . Any ideas on how I could hack this together?The text was updated successfully, but these errors were encountered: