lebrice / SimpleParsing

Simple, Elegant, Typed Argument Parsing with argparse
MIT License
410 stars 52 forks source link

Subparsers overwrite kwargs of original parser #310

Open bnorick opened 5 months ago

bnorick commented 5 months ago

Describe the bug When argparse creates a new simple_parsing.ArgumentParser in the call to parser.add_subparsers it doesn't pass the original kwargs (obviously), so the global class attributes on FieldWrapper like add_dash_variants get overwritten with the defaults.

Your refactor may address this, but in case you weren't aware I thought I'd raise the issue. Those globals seem not ideal.

Here's a workaround:

import inspect
import pathlib

FIRST_KWARGS = None

class ArgumentParser(simple_parsing.ArgumentParser):
    def __init__(self, *args, **kwargs):
        global FIRST_KWARGS
        if FIRST_KWARGS is None:
            FIRST_KWARGS = kwargs

        # only enforce FIRST_KWARGS when called by argparse
        caller = inspect.stack()[1]
        caller_path = pathlib.Path(caller.filename)
        if caller_path.match("*lib/**/argparse.py"):
            super().__init__(*args, **FIRST_KWARGS)
        else:
            super().__init__(*args, **kwargs)

To Reproduce Use subparsers with non-default kwargs on the top level parser, e.g., add_dash_variants.

Expected behavior Subparsers obey the kwargs used by the parent.

Actual behavior Subparsers use default kwargs.

Desktop (please complete the following information):

lebrice commented 5 months ago

Hey there @bnorick, thanks for posting!

Those globals seem not ideal.

Totally agree. I definitely need to remove those global vars. One idea could be to preserve the kwargs on the ArgumentParser so that parser.add_subparsers transfers them. I'll have to try that out.