Ejemplo n.º 1
0
def main_sl():
    """ Applies the PnnMethod in a SL Setting. """
    parser = ArgumentParser(description=__doc__,
                            add_dest_to_option_strings=False)

    # Add arguments for the Setting
    # TODO: PNN is coded for the DomainIncrementalSetting, where the action space
    # is the same for each task.
    # parser.add_arguments(DomainIncrementalSetting, dest="setting")
    parser.add_arguments(TaskIncrementalSLSetting, dest="setting")
    # TaskIncrementalSLSetting.add_argparse_args(parser, dest="setting")
    Config.add_argparse_args(parser, dest="config")

    # Add arguments for the Method:
    PnnMethod.add_argparse_args(parser, dest="method")

    args = parser.parse_args()

    # setting: TaskIncrementalSLSetting = args.setting
    setting: TaskIncrementalSLSetting = TaskIncrementalSLSetting.from_argparse_args(
        # setting: DomainIncrementalSetting = DomainIncrementalSetting.from_argparse_args(
        args,
        dest="setting",
    )
    config: Config = Config.from_argparse_args(args, dest="config")

    method: PnnMethod = PnnMethod.from_argparse_args(args, dest="method")

    method.config = config

    results = setting.apply(method, config=config)
    print(results.summary())
    return results
Ejemplo n.º 2
0
 def add_argparse_args(cls,
                       parser: ArgumentParser,
                       dest: str = None) -> None:
     """Add the command-line arguments for this Method to the given parser.
     
     Override this if you don't use simple-parsing to add the args.
     
     Parameters
     ----------
     parser : ArgumentParser
         The ArgumentParser. 
     dest : str, optional
         The 'base' destination where the arguments should be set on the
         namespace, by default None, in which case the arguments can be at
         the "root" level on the namespace.
     """
     if is_dataclass(cls):
         dest = dest or camel_case(cls.__qualname__)
         parser.add_arguments(cls, dest=dest)
     elif issubclass(cls, LightningDataModule):
         # TODO: Test this case out (using a LightningDataModule as a Setting).
         super().add_argparse_args(parser)  # type: ignore
     else:
         raise NotImplementedError(
             f"Don't know how to add command-line arguments for class "
             f"{cls}, since it isn't a dataclass and doesn't override the "
             f"`add_argparse_args` method!\n"
             f"Either make class {cls} a dataclass and add command-line "
             f"arguments as fields, or add an implementation for the "
             f"`add_argparse_args` and `from_argparse_args` classmethods.")
Ejemplo n.º 3
0
def test_passing_instance():
    @dataclass
    class Foo:
        a: int = 123

    parser = ArgumentParser()
    parser.add_arguments(Foo(456), dest="foo")
    args = parser.parse_args("")
    assert args.foo.a == 456, vars(args)
Ejemplo n.º 4
0
def main():
    parser = ArgumentParser()
    parser.add_arguments(Settings, dest='opts')
    argcomplete.autocomplete(parser)
    opts = parser.parse_args().opts
    if opts.train:
        train(opts)
    else:
        test(opts)
Ejemplo n.º 5
0
def test_multiple_at_same_dest_throws_error():
    @dataclass
    class SomeClass:
        a: int = 123

    parser = ArgumentParser()
    parser.add_arguments(SomeClass, "some_class")
    with raises(argparse.ArgumentError):
        parser.add_arguments(SomeClass, "some_class")
def parse_hparams_and_config() -> Tuple[HParams, MnistConfig]:
    # Training settings
    parser = ArgumentParser(description='PyTorch MNIST Example')
    parser.add_arguments(HParams, "hparams", default=HParams())
    parser.add_arguments(MnistConfig, "config", default=MnistConfig())
    args, _ = parser.parse_known_args()
    hparams: HParams = args.hparams
    config: MnistConfig = args.config
    return hparams, config
Ejemplo n.º 7
0
def test_arg_and_dataclass_with_same_name(silent):
    @dataclass
    class SomeClass:
        a: int = 1  # some docstring for attribute 'a'

    parser = ArgumentParser()
    parser.add_argument("--a", default=123)
    with raises(argparse.ArgumentError):
        parser.add_arguments(SomeClass, dest="some_class")
        args = parser.parse_args("")
Ejemplo n.º 8
0
def test_store_false_action():
    parser = ArgumentParser(add_option_string_dash_variants=True)
    parser.add_arguments(Foo, "foo")

    args = parser.parse_args("--no-cache".split())
    foo: Foo = args.foo
    assert foo.no_cache == False

    args = parser.parse_args("".split())
    foo: Foo = args.foo
    assert foo.no_cache == True
Ejemplo n.º 9
0
def test_issue_29():
    from simple_parsing import ArgumentParser

    @dataclass
    class MyCli:
        asdf: Tuple[str, ...]

    parser = ArgumentParser()
    parser.add_arguments(MyCli, dest="args")
    args = parser.parse_args("--asdf asdf fgfh".split())
    assert args.args == MyCli(asdf=("asdf", "fgfh"))
Ejemplo n.º 10
0
 def add_argparse_args(cls, parser: ArgumentParser, dest: str = ""):
     """Adds command-line arguments for this Method to an argument parser.
     
     NOTE: This doesn't do anything differently than the base implementation,
     but it's included here just for illustration purposes.
     """
     # 'dest' is where the arguments will be stored on the namespace.
     dest = dest or camel_case(cls.__qualname__)
     # Add all command-line arguments. This adds arguments for all fields of
     # this dataclass.
     parser.add_arguments(cls, dest=dest)
Ejemplo n.º 11
0
def test_parsing_twice():
    @dataclass
    class Foo:
        a: int = 123

    parser = ArgumentParser()
    parser.add_arguments(Foo, dest="foo")
    args = parser.parse_args("")
    assert args.foo.a == 123, vars(args)
    args = parser.parse_args("--a 456".split())
    assert args.foo.a == 456, vars(args)
Ejemplo n.º 12
0
    def test_reproduce(self):
        parser = ArgumentParser()
        parser.add_arguments(MyConfig, dest="cfg")
        args_none, _ = parser.parse_known_args([])
        args, extra = parser.parse_known_args(["--values", "3", "4"])
        values = args.cfg.values
        # This is what we'd expect:
        # assert values == (3, 4)
        # assert extra == []

        # But instead we get this:
        assert values == (3)
        assert extra == ["4"]
Ejemplo n.º 13
0
    def test_optional_list(self, passed_arg: str, expected_value: Any):
        parser = ArgumentParser()

        @dataclass
        class MyConfig:
            foo: Optional[List[str]] = None

        parser.add_arguments(MyConfig, dest="config")

        if passed_arg is DONT_PASS:
            args = parser.parse_args("")
        else:
            args = parser.parse_args(shlex.split("--foo " + passed_arg))
        assert args.config.foo == expected_value
Ejemplo n.º 14
0
def test_issue62():
    import enum
    from simple_parsing.helpers import list_field
    from typing import List
    parser = ArgumentParser()

    class Color(enum.Enum):
        RED = "red"
        ORANGE = "orange"
        BLUE = "blue"

    class Temperature(enum.Enum):
        HOT = 1
        WARM = 0
        COLD = -1
        MONTREAL = -35

    @dataclass
    class MyPreferences(TestSetup):
        """You can use Enums"""

        color: Color = Color.BLUE  # my favorite colour
        # a list of colors
        color_list: List[Color] = list_field(Color.ORANGE)
        # Some floats.
        floats: List[float] = list_field(1.1, 2.2, 3.3)
        # pick a temperature
        temp: Temperature = Temperature.WARM
        # a list of temperatures
        temp_list: List[Temperature] = list_field(Temperature.COLD, Temperature.WARM)

    parser.add_arguments(MyPreferences, "my_preferences")
    assert MyPreferences.setup(
        "--color ORANGE --color_list RED BLUE --temp MONTREAL"
    ) == MyPreferences(
        color=Color.ORANGE,
        color_list=[Color.RED, Color.BLUE],
        temp=Temperature.MONTREAL,
        temp_list=[Temperature.COLD, Temperature.WARM],
    )
    assert MyPreferences.setup(
        "--color ORANGE --color_list RED BLUE --temp MONTREAL --temp_list MONTREAL HOT"
    ) == MyPreferences(
        color=Color.ORANGE,
        color_list=[Color.RED, Color.BLUE],
        temp=Temperature.MONTREAL,
        temp_list=[Temperature.MONTREAL, Temperature.HOT],
    )
    assert Temperature["MONTREAL"] is Temperature.MONTREAL
    assert Temperature(-35) is Temperature.MONTREAL
Ejemplo n.º 15
0
def test_works_fine_with_other_argparse_arguments(simple_attribute, silent):
    some_type, passed_value, expected_value = simple_attribute

    @dataclass
    class SomeClass:
        a: some_type  # type: ignore
        """some docstring for attribute 'a'"""

    parser = ArgumentParser()
    parser.add_argument("--x", type=int)
    parser.add_arguments(SomeClass, dest="some_class")

    x = 123
    args = parser.parse_args(shlex.split(f"--x {x} --a {passed_value}"))
    assert args == argparse.Namespace(some_class=SomeClass(a=expected_value), x=x)
Ejemplo n.º 16
0
def test_optional_seed():
    """Test that a value marked as Optional works fine.

    (Reproduces https://github.com/lebrice/SimpleParsing/issues/14#issue-562538623)
    """
    parser = ArgumentParser()
    parser.add_arguments(Config, dest="config")

    args = parser.parse_args("".split())
    config: Config = args.config
    assert config == Config()

    args = parser.parse_args("--seed 123".split())
    config: Config = args.config
    assert config == Config(123)
Ejemplo n.º 17
0
def test_arg_and_dataclass_with_same_name_after_prefixing(silent):
    @dataclass
    class SomeClass:
        a: int = 1  # some docstring for attribute 'a'

    @dataclass
    class Parent:
        pre: SomeClass = SomeClass()
        bla: SomeClass = SomeClass()

    parser = ArgumentParser()
    parser.add_argument("--pre.a", default=123, type=int)
    with raises(argparse.ArgumentError):
        parser.add_arguments(Parent, dest="some_class")
        args = parser.parse_args("--pre.a 123 --pre.a 456".split())
Ejemplo n.º 18
0
def to_simple_parsing_args(some_dataclass_type):
    """
        Add this as a classmethod to some dataclass in order to make its arguments accessible from commandline
        Example:

        @classmethod
        def get_args(cls):
            args: cls = to_simple_parsing_args(cls)
            return args

    """
    from simple_parsing import ArgumentParser, ConflictResolution
    parser = ArgumentParser(conflict_resolution=ConflictResolution.NONE)
    parser.add_arguments(some_dataclass_type, dest='cfg')
    args: some_dataclass_type = parser.parse_args().cfg
    return args
Ejemplo n.º 19
0
def test_experiments():
    from abc import ABC

    @dataclass
    class Experiment(ABC):
        dataset: str
        iid: bool = True

    @dataclass
    class Mnist(Experiment):
        dataset: str = "mnist"
        iid: bool = True

    @dataclass
    class MnistContinual(Experiment):
        dataset: str = "mnist"
        iid: bool = False

    @dataclass
    class Config:
        experiment: Experiment = subparsers({
            "mnist": Mnist,
            "mnist_continual": MnistContinual,
        })

    for field in dataclasses.fields(Config):
        assert simple_parsing.utils.is_subparser_field(field), field

    parser = ArgumentParser()
    parser.add_arguments(Config, "config")

    with raises(SystemExit):
        args = parser.parse_args()

    args = parser.parse_args("mnist".split())
    experiment = args.config.experiment
    assert isinstance(experiment, Mnist)
    assert experiment.dataset == "mnist"
    assert experiment.iid == True

    args = parser.parse_args("mnist_continual".split())
    experiment = args.config.experiment
    assert isinstance(experiment, MnistContinual)
    assert experiment.dataset == "mnist"
    assert experiment.iid == False
Ejemplo n.º 20
0
def main():
    parser = ArgumentParser()

    parser.add_arguments(Options, dest="options")

    # Equivalent to:
    # subparsers = parser.add_subparsers(title="config", required=False)
    # parser.set_defaults(config=AConfig())
    # a_parser = subparsers.add_parser("a", help="A help.")
    # a_parser.add_arguments(AConfig, dest="config")
    # b_parser = subparsers.add_parser("b", help="B help.")
    # b_parser.add_arguments(BConfig, dest="config")

    args = parser.parse_args()

    print(args)
    options: Options = args.options
    print(options)
Ejemplo n.º 21
0
    def test_arg_options_created(self, field_type: Type,
                                 expected_options: Dict[str, Any]):
        """Check the 'arg_options' that get created for different types of tuple
        fields.
        """
        parser = ArgumentParser()

        @dataclass
        class MyConfig:
            values: field_type

        parser.add_arguments(MyConfig, dest="config")
        parser._preprocessing()
        field_wrapper = parser._wrappers[0].fields[0]
        generated_options = field_wrapper.arg_options
        for option, expected_value in expected_options.items():
            actual_value = generated_options[option]
            assert actual_value == expected_value
Ejemplo n.º 22
0
    def test_issue_47_is_fixed(
        self,
        field_type: Type,
        passed_arg: Union[str, object],
        expected_value: Any,
    ):
        parser = ArgumentParser()

        @dataclass
        class MyConfig:
            values: field_type

        parser.add_arguments(MyConfig, dest="config")
        if passed_arg is DONT_PASS:
            args = parser.parse_args([])
        else:
            args = parser.parse_args(shlex.split("--values " + passed_arg))
        actual_values = args.config.values
        assert actual_values == expected_value
Ejemplo n.º 23
0
def demo_command_line():
    """ Run the same demo as above, but customizing the Setting and Method from
    the command-line.
    
    NOTE: Remember to uncomment the function call below to use this instead of
    demo_simple!
    """
    ## Create the `Setting` and the `Config` from the command-line, like in
    ## the other examples.
    parser = ArgumentParser(description=__doc__)

    ## Add command-line arguments for any Setting in the tree:
    from sequoia.settings import TaskIncrementalRLSetting, TaskIncrementalSLSetting

    # parser.add_arguments(TaskIncrementalSLSetting, dest="setting")
    parser.add_arguments(TaskIncrementalRLSetting, dest="setting")
    parser.add_arguments(Config, dest="config")

    # Add the command-line arguments for our CustomMethod (including the
    # arguments for our simple regularization aux task).
    CustomMethod.add_argparse_args(parser, dest="method")

    args = parser.parse_args()

    setting: ClassIncrementalSetting = args.setting
    config: Config = args.config

    # Create the BaselineMethod:
    base_method = BaselineMethod.from_argparse_args(args, dest="method")
    # Get the results of the BaselineMethod:
    base_results = setting.apply(base_method, config=config)

    ## Create the CustomMethod:
    new_method = CustomMethod.from_argparse_args(args, dest="method")
    # Get the results for the CustomMethod:
    new_results = setting.apply(new_method, config=config)

    print(f"\n\nComparison: BaselineMethod vs CustomMethod:")
    print(base_results.summary())
    print(new_results.summary())
Ejemplo n.º 24
0
def update_settings(opts: dataclass, argv: List[str] = None):
    """
    Update given settings from command line arguments.
    Uses `argparse`, `argcomplete` and `simple_parsing` under the hood.
    """
    if not is_dataclass(opts):
        raise ValueError('Cannot update args on non-dataclass class')

    # Use default system argv if not supplied.
    argv = sys.argv[1:] if argv is None else argv

    # Update from config file, if applicable.
    parser_parents = []
    if isinstance(opts, Serializable):
        opts, argv, parser_parents = _update_settings_from_file(opts, argv)

    parser = ArgumentParser(parents=parser_parents)
    parser.add_arguments(type(opts), dest='opts', default=opts)
    if use_argcomplete:
        argcomplete.autocomplete(parser)
    args = parser.parse_args(argv)
    return args.opts
Ejemplo n.º 25
0
def demo_command_line():
    """ Run this quick demo from the command-line. """
    parser = ArgumentParser(description=__doc__)
    # Add command-line arguments for the Method and the Setting.
    DemoMethod.add_argparse_args(parser)
    # Add command-line arguments for the Setting and the Config (an object with
    # options like log_dir, debug, etc, which are not part of the Setting or the
    # Method) using simple-parsing.
    parser.add_arguments(DomainIncrementalSLSetting, "setting")
    parser.add_arguments(Config, "config")
    args = parser.parse_args()

    # Create the Method from the parsed arguments
    method: DemoMethod = DemoMethod.from_argparse_args(args)
    # Extract the Setting and Config from the args.
    setting: DomainIncrementalSLSetting = args.setting
    config: Config = args.config

    # Run the demo, applying that DemoMethod on the given setting.
    results: Results = setting.apply(method, config=config)
    print(results.summary())
    print(f"objective: {results.objective}")
Ejemplo n.º 26
0
def test_cmd_false_doesnt_create_conflicts():
    @dataclass
    class A:
        batch_size: int = field(default=10, cmd=False)

    @dataclass
    class B:
        batch_size: int = 20

    # @dataclass
    # class Foo(TestSetup):
    #     a: A = mutable_field(A)
    #     b: B = mutable_field(B)

    parser = ArgumentParser(conflict_resolution=ConflictResolution.NONE)
    parser.add_arguments(A, "a")
    parser.add_arguments(B, "b")
    args = parser.parse_args("--batch_size 32".split())
    a: A = args.a
    b: B = args.b
    assert a == A()
    assert b == B(batch_size=32)
Ejemplo n.º 27
0
def demo():
    """ Runs the EwcMethod on a simple setting, just to check that it works fine.
    """

    # Adding arguments for each group directly:
    parser = ArgumentParser(description=__doc__)

    EwcMethod.add_argparse_args(parser, dest="method")
    parser.add_arguments(Config, "config")

    args = parser.parse_args()

    method = EwcMethod.from_argparse_args(args, dest="method")
    config: Config = args.config
    task_schedule = {
        0: {
            "gravity": 10,
            "length": 0.2
        },
        1000: {
            "gravity": 100,
            "length": 1.2
        },
        # 2000:   {"gravity": 10, "length": 0.2},
    }
    setting = TaskIncrementalRLSetting(
        dataset="cartpole",
        train_task_schedule=task_schedule,
        test_task_schedule=task_schedule,
        observe_state_directly=True,
        # max_steps=1000,
    )

    # from sequoia.settings import TaskIncrementalSetting, ClassIncrementalSetting
    # setting = ClassIncrementalSetting(dataset="mnist", nb_tasks=5)
    # setting = TaskIncrementalSetting(dataset="mnist", nb_tasks=5)
    results = setting.apply(method, config=config)
    print(results.summary())
Ejemplo n.º 28
0
def test_issue_48():
    parser = ArgumentParser("Prepare input data for training")
    parser.add_arguments(InputArgs, dest="args")
    s = StringIO()
    parser.print_help(file=s)
    s.seek(0)
    assert s.read().replace(" ", "") == textwrap.dedent("""\
        usage: Prepare input data for training [-h] -s str -e str

        optional arguments:
          -h, --help            show this help message and exit
        
        InputArgs ['args']:
          InputArgs(start_date:str, end_date:str)
        
          -s str, --start_date str
                                Start date from which to collect data about base
                                users. Input in iso format (YYYY-MM-DD). The date is
                                included in the data (default: None)
          -e str, --end_date str
                                End date for collecting base users. Input in iso
                                format (YYYY-MM-DD). The date is included in the data.
                                Should not be before `start_date` (default: None)
        """).replace(" ", "")
Ejemplo n.º 29
0
def test_solved_issue64():
    """test that shows that Issue 64 is solved now, by adding a single space as the
    'help' argument, the help formatter can then add the "(default: bbb)" after the
    argument.
    """
    parser = ArgumentParser("issue64")
    parser.add_arguments(Options, dest="options")

    s = StringIO()
    parser.print_help(file=s)
    s.seek(0)

    assert s.read() == textwrap.dedent("""\
    usage: issue64 [-h] [--foo str] [--bar str]

    optional arguments:
      -h, --help  show this help message and exit

    Options ['options']:
      These are the options

      --foo str   Description (default: aaa)
      --bar str   (default: bbb)
    """)
Ejemplo n.º 30
0
def test_reproduce_issue64():

    parser = ArgumentParser("issue64")

    parser.add_arguments(Options, dest="options")

    # args = parser.parse_args(["--help"])

    s = StringIO()
    parser.print_help(file=s)
    s.seek(0)

    assert s.read() == textwrap.dedent("""\
    usage: issue64 [-h] [--foo str] [--bar str]

    optional arguments:
      -h, --help  show this help message and exit

    Options ['options']:
      These are the options

      --foo str   Description (default: aaa)
      --bar str
    """)