diff --git a/CHANGES.md b/CHANGES.md index 178ce8d6..1aedf511 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed +- Fix CLI object parsing for string keyword values containing `=`. - `ValidSplit` now raises a clear error when it receives an `IterableDataset`, instead of an opaque `TypeError` about a missing length (#594) - `Checkpoint`'s sink message now reports the epoch the checkpoint was actually taken in, instead of the following one - Fix pickling a net with an `LRScheduler` callback dragging along a reference to the (potentially CUDA-resident) optimizer, which could prevent loading nets trained on CUDA on a CPU-only machine (#1096) diff --git a/skorch/cli.py b/skorch/cli.py index ebf00727..fb758f7b 100644 --- a/skorch/cli.py +++ b/skorch/cli.py @@ -94,7 +94,7 @@ def _parse_args_kwargs(params): if '=' not in param: args += (DefaultParseValue(param),) else: - k, v = param.split('=') + k, v = param.split('=', 1) kwargs[k.strip()] = DefaultParseValue(v) return args, kwargs diff --git a/skorch/tests/test_cli.py b/skorch/tests/test_cli.py index a224f3ab..656da53f 100644 --- a/skorch/tests/test_cli.py +++ b/skorch/tests/test_cli.py @@ -50,22 +50,25 @@ def parse_net_kwargs(self): from skorch.cli import parse_net_kwargs return parse_net_kwargs - def test_parse_net_kwargs(self, parse_net_kwargs): + @pytest.mark.parametrize('label', ['epoch', 'epoch=1', 'epoch=1=best']) + def test_parse_net_kwargs(self, parse_net_kwargs, label): kwargs = { 'lr': 0.05, 'max_epochs': 5, 'module__num_units': 10, 'module__nonlin': 'torch.nn.RReLU(0.123, upper=0.456)', + 'module__config': f'builtins.dict(label="{label}")', } parsed_kwargs = parse_net_kwargs(kwargs) - assert len(parsed_kwargs) == 4 + assert len(parsed_kwargs) == 5 assert np.isclose(parsed_kwargs['lr'], 0.05) assert parsed_kwargs['max_epochs'] == 5 assert parsed_kwargs['module__num_units'] == 10 assert isinstance(parsed_kwargs['module__nonlin'], RReLU) assert np.isclose(parsed_kwargs['module__nonlin'].lower, 0.123) assert np.isclose(parsed_kwargs['module__nonlin'].upper, 0.456) + assert parsed_kwargs['module__config'] == {'label': label} @pytest.fixture def net_cls(self):