From 66c897b63d7ed6e1c78b09b922b5d02b95e5d103 Mon Sep 17 00:00:00 2001 From: Jack Brown Date: Wed, 11 Oct 2023 12:03:47 -0400 Subject: [PATCH] handle edge cases --- pennylane/data/data_manager/foldermap.py | 23 +++++---- tests/data/data_manager/test_foldermap.py | 61 +++++++++++++++++++++-- 2 files changed, 70 insertions(+), 14 deletions(-) diff --git a/pennylane/data/data_manager/foldermap.py b/pennylane/data/data_manager/foldermap.py index d536130c74a..bf4c0cde4e0 100644 --- a/pennylane/data/data_manager/foldermap.py +++ b/pennylane/data/data_manager/foldermap.py @@ -119,6 +119,7 @@ def find( while curr: curr_description, curr_level = curr.pop() + if param_arg == ParamArg.FULL: next_params = curr_level elif param_arg == ParamArg.DEFAULT: @@ -131,29 +132,29 @@ def find( else: next_params = param_arg - next_ = [] for next_param in next_params: try: fmap_next = curr_level[next_param] except KeyError: continue - next_.append( + todo.append( ( Description((*curr_description.items(), (param_name, next_param))), fmap_next, ) ) - if len(next_) == 0: - params_list_fmt = ", ".join(f"'{val}'" for val in next_params) - param_value_slug = f"{param_name} value(s) {params_list_fmt} are not available" - - raise ValueError( - f"{param_value_slug}. Available values are: {list(curr_level)}" - ) - - todo.extend(next_) + if len(todo) == 0: + # None of the parameters matched + param_arg_repr = ( + repr([param_arg]) + if isinstance(param_arg, (str, ParamArg)) + else repr(list(param_arg)) + ) + raise ValueError( + f"{param_name} value(s) {param_arg_repr} are not available. Available values are: {list(curr_level)}" + ) curr, todo = todo, curr diff --git a/tests/data/data_manager/test_foldermap.py b/tests/data/data_manager/test_foldermap.py index 9a04b61d76e..5c9e3385e46 100644 --- a/tests/data/data_manager/test_foldermap.py +++ b/tests/data/data_manager/test_foldermap.py @@ -19,6 +19,7 @@ from pennylane.data.data_manager import DEFAULT, FULL, DataPath from pennylane.data.data_manager.foldermap import Description, FolderMapView +import re pytestmark = pytest.mark.data @@ -125,6 +126,38 @@ class TestFolderMapView: ), ], ), + ( + {"missing_default": DEFAULT, "molname": "O2", "basis": FULL, "bondlength": ["0.6"]}, + [ + ( + {"molname": "O2", "basis": "STO-3G", "bondlength": "0.6"}, + "qchem/O2/STO-3G/0.6.h5", + ), + ], + ), + ( + { + "missing_default": DEFAULT, + "molname": "O2", + "basis": FULL, + "bondlength": ["0.6", "200"], + }, + [ + ( + {"molname": "O2", "basis": "STO-3G", "bondlength": "0.6"}, + "qchem/O2/STO-3G/0.6.h5", + ), + ], + ), + ( + {"missing_default": FULL, "molname": "O2", "bondlength": ["0.6"]}, + [ + ( + {"molname": "O2", "basis": "STO-3G", "bondlength": "0.6"}, + "qchem/O2/STO-3G/0.6.h5", + ), + ], + ), ], ) def test_find(self, foldermap, kwds, expect): # pylint: disable=redefined-outer-name @@ -155,14 +188,36 @@ def test_find_missing_arg_no_default(self): with pytest.raises(ValueError, match="No default available for parameter 'molname'"): FolderMapView(FOLDERMAP).find("qchem") - def test_find_invalid_parameter(self): + @pytest.mark.parametrize( + "arg, error_fmt", [("Z3", repr(["Z3"])), (("Z3", "Z4"), repr(["Z3", "Z4"]))] + ) + def test_find_invalid_parameter(self, arg, error_fmt): """Test that a ValueError is raised when a parameter provided does not exist.""" with pytest.raises( - ValueError, match=r"molname value\(s\) 'Z3' is not available. Available values are: \['O2', 'H2'\]" + ValueError, + match=re.escape( + f"molname value(s) {error_fmt} are not available. Available values are: ['O2', 'H2']" + ), ): - FolderMapView(FOLDERMAP).find("qchem", molname="Z3") + FolderMapView(FOLDERMAP).find("qchem", molname=arg) + + @pytest.mark.parametrize("basis", [FULL, DEFAULT]) + def test_find_invalid_parameters_after_full_default(self, basis): + """Test that a ValueError is raised when a parameter provided + does not exist, after a 'full' or 'default' parameter has been provided for a + higher-priority parameter.""" + + with pytest.raises( + ValueError, + match=( + r"bondlength value\(s\) \['0.20', '200'\] are not available. Available values are: \['0.5', '0.6'\]" + ), + ): + FolderMapView(FOLDERMAP).find( + "qchem", molname="O2", basis=basis, bondlength=["0.20", "200"] + ) @pytest.mark.parametrize( "init, key, expect",