Repository: facebookresearch/hydra

Issue:
[Bug] The nevergrad sweeper is not properly handling quoted strings
# 🐛 Bug
## Description

The nevergrad sweeper does not properly handle quoted strings (this also manifests in other problems, e.g., with `null` values).


## Checklist
- [X] I checked on the latest version of Hydra
- [X] I created a minimal repro (See [this](https://stackoverflow.com/help/minimal-reproducible-example) for tips).

## To reproduce

** Minimal Code/Config snippet to reproduce **

```bash
python example/my_app.py -m hydra.sweeper.optim.budget=1 hydra.sweeper.optim.num_workers=1 +key="'a&b'"
```

** Stack trace/error message **
```
[2023-03-15 13:01:58,886][HYDRA] NevergradSweeper(optimizer=OnePlusOne, budget=1, num_workers=1) minimization
[2023-03-15 13:01:58,886][HYDRA] with parametrization Dict(+key=a&b,batch_size=Scalar{Cl(4,16,b),Int}[sigma=Scalar{exp=2.03}],db=Choice(choices=Tuple(mnist,cifar),indices=Array{(1,2),SoftmaxSampling}),dropout=Scalar{Cl(0,1,b)}[sigma=Scalar{exp=2.03}],lr=Log{exp=2.00}):{'db': 'mnist', 'lr': 0.020000000000000004, 'dropout': 0.5, 'batch_size': 10, '+key': 'a&b'}
[2023-03-15 13:01:58,888][HYDRA] Sweep output dir: multirun/2023-03-15/13-01-57
LexerNoViableAltException: +key=a&b
```

## Expected Behavior
It should work, passing the override `+key='a&b'` to the job being launched.

## System information
- **Hydra Version** :  latest master
- **Python version** : Python 3.9


Discussion:

Resolving patch:
diff --git a/plugins/hydra_nevergrad_sweeper/hydra_plugins/hydra_nevergrad_sweeper/_impl.py b/plugins/hydra_nevergrad_sweeper/hydra_plugins/hydra_nevergrad_sweeper/_impl.py
--- a/plugins/hydra_nevergrad_sweeper/hydra_plugins/hydra_nevergrad_sweeper/_impl.py
+++ b/plugins/hydra_nevergrad_sweeper/hydra_plugins/hydra_nevergrad_sweeper/_impl.py
@@ -60,7 +60,7 @@ def create_nevergrad_param_from_config(
 def create_nevergrad_parameter_from_override(override: Override) -> Any:
     val = override.value()
     if not override.is_sweep_override():
-        return val
+        return override.get_value_element_as_str()
     if override.is_choice_sweep():
         assert isinstance(val, ChoiceSweep)
         vals = [x for x in override.sweep_iterator(transformer=Transformer.encode)]


Test patch:
diff --git a/plugins/hydra_nevergrad_sweeper/tests/test_nevergrad_sweeper_plugin.py b/plugins/hydra_nevergrad_sweeper/tests/test_nevergrad_sweeper_plugin.py
--- a/plugins/hydra_nevergrad_sweeper/tests/test_nevergrad_sweeper_plugin.py
+++ b/plugins/hydra_nevergrad_sweeper/tests/test_nevergrad_sweeper_plugin.py
@@ -36,6 +36,8 @@ def assert_ng_param_equals(expected: Any, actual: Any) -> None:
     elif isinstance(actual, ng.p.Log) or isinstance(actual, ng.p.Scalar):
         assert expected.bounds == actual.bounds
         assert expected.integer == actual.integer
+    elif isinstance(actual, str):
+        assert expected == actual
     else:
         assert False, f"Unexpected type: {type(actual)}"
 
@@ -95,6 +97,13 @@ def test_create_nevergrad_parameter_from_config(
             "key=tag(log, int(interval(1,12)))",
             get_scalar_with_integer_bounds(lower=1, upper=12, type=ng.p.Log),
         ),
+        ("key=abc", "abc"),
+        ("key='a&c'", "'a&c'"),
+        ("key='${f:${x}}'", "'${f:${x}}'"),
+        (r"key=$\{f\:$\{x\}\}", r"$\{f\:$\{x\}\}"),
+        ("key=0", "0"),
+        ("key=true", "True"),
+        ("key=null", "null"),
     ],
 )
 def test_create_nevergrad_parameter_from_override(