From 6b52b48ac27ab246013e3f6ba5ed32df85f562cc Mon Sep 17 00:00:00 2001 From: Eric Smith Date: Fri, 2 Oct 2020 11:21:10 -0400 Subject: [PATCH] Allow missing args when using `--init-opt` (#3112) * Allow missing init opt opts * Add part of unit test * Work on unit test * Test fixes * Fix second test * Fix test * Check obsolete arg does not exist --- parlai/core/params.py | 21 +++++++++++++++--- tests/test_opt.py | 51 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+), 3 deletions(-) diff --git a/parlai/core/params.py b/parlai/core/params.py index e8c738ba6c1..f453bbb74db 100644 --- a/parlai/core/params.py +++ b/parlai/core/params.py @@ -642,6 +642,15 @@ def add_parlai_args(self, args=None): help='Path to json file of options. ' 'Note: Further Command-line arguments override file-based options.', ) + parlai.add_argument( + '--allow-missing-init-opts', + type='bool', + default=False, + help=( + 'Warn instead of raising if an argument passed in with --init-opt is ' + 'not in the target opt.' + ), + ) parlai.add_argument( '-t', '--task', help='ParlAI task(s), e.g. "babi:Task1" or "babi,cbt"' ) @@ -927,9 +936,15 @@ def _load_opts(self, opt): for key, value in new_opt.items(): # existing command line parameters take priority. if key not in opt: - raise RuntimeError( - 'Trying to set opt from file that does not exist: ' + str(key) - ) + if opt.get('allow_missing_init_opts', False): + logging.warn( + f'The "{key}" key in {optfile} will not be loaded, because it ' + f'does not exist in the target opt.' + ) + else: + raise RuntimeError( + 'Trying to set opt from file that does not exist: ' + str(key) + ) if key not in opt['override']: opt[key] = value opt['override'][key] = value diff --git a/tests/test_opt.py b/tests/test_opt.py index deaf5d142ae..8f31fca95d6 100644 --- a/tests/test_opt.py +++ b/tests/test_opt.py @@ -10,6 +10,7 @@ import parlai.utils.testing as testing_utils from parlai.core.opt import Opt +from parlai.core.params import ParlaiParser from parlai.scripts.compare_opts import compare_opts """ @@ -126,3 +127,53 @@ def test_compare_opts_load_raw(self): \t\tIn opt 1: \t\tIn opt 2: no""" self.assertEqual(output, desired_output) + + +class TestInitOpt(unittest.TestCase): + """ + Test functionality related to --init-opt. + """ + + def test_init_opt(self): + """ + Test --init-opt. + """ + + with testing_utils.tempdir() as temp_dir: + + init_opt_path = os.path.join(temp_dir, 'init_opt.opt') + test_model_file = '/test_model_path/model' + + # Save a test opt file + init_opt = Opt({'model_file': test_model_file}) + init_opt.save(init_opt_path) + + # Load the opt back in with --init-opt and make sure it's been set + # correctly + opt = ParlaiParser(True, True).parse_kwargs(init_opt=init_opt_path) + self.assertEqual(opt['model_file'], test_model_file) + + def test_allow_missing_init_opts(self): + """ + Test --allow-missing-init-opts. + """ + + with testing_utils.tempdir() as temp_dir: + + init_opt_path = os.path.join(temp_dir, 'init_opt.opt') + + # Save a test opt file with an argument that doesn't exist + init_opt = Opt({'made_up_arg': 'foo'}) + init_opt.save(init_opt_path) + + # Assert that the opt file normally can't be loaded in + with self.assertRaises(RuntimeError): + _ = ParlaiParser(True, True).parse_kwargs(init_opt=init_opt_path) + + # Assert that the opt file *can* be loaded in if we set + # --allow-missing-init-opts, and assert that the made-up arg does not exist + # in the opt + opt = ParlaiParser(True, True).parse_kwargs( + init_opt=init_opt_path, allow_missing_init_opts=True + ) + self.assertFalse(hasattr(opt, 'made_up_arg'))