[Python] How to use Python argparse to have lazily loaded subcommands

Discussão em 'Python' iniciado por Stack, Setembro 29, 2024.

  1. Stack

    Stack Membro Participativo

    I have a python package with a lot of sub commands and sub-sub commands. It is organized somewhat like this:

    main.py

    import argparse

    from sum import prepare_arg_parser as prepare_sum_parser
    from sub import prepare_arg_parser as prepare_sub_parser

    parser = argparse.ArgumentParser()
    sub_parsers = parser.add_subparsers(dest="command", required=True)

    prepare_sum_parser(sub_parsers.add_parser("sum"))
    prepare_sub_parser(sub_parsers.add_parser("sub"))

    args = parser.parse_args()
    args.func(args)


    sum.py

    import argparse


    def prepare_arg_parser(parser):
    parser.set_defaults(func=do_sum)
    parser.add_argument("a", type=int)
    parser.add_argument("b", type=int)


    def do_sum(args):
    print(f"{args.a} + {args.b} = {args.a + args.b}")


    and so on.

    However, as the list of module grows, the startup time also loads. I would like to lazily load each sub commands, so it only loads what's needed for the selected command.

    I tried something like this:

    import argparse

    def do_sum(args):
    from sum import prepare_arg_parser
    parser = argparse.ArgumentParser()
    prepare_arg_parser(parser)
    sum_args = parser.parse_args(args)
    sum_args.func(sum_args)

    parser = argparse.ArgumentParser()
    sub_parsers = parser.add_subparsers(dest="command", required=True)

    sub_parsers.add_parser("sum").set_defaults(func=do_sum)

    args, rest = parser.parse_known_args()
    args.func(rest)


    But then the help and error texts are not right.

    Another way would be to split each sub commands into a "prepare argparse" module which would know all the args but lazily call the do_sum function for example, but I don't like it as it separate the argument declaration from their use. Also it would still load a lot of unnecessary files.

    Is there have lazily-loaded sub commands?

    Continue reading...

Compartilhe esta Página