From 037f27260a9090ac40799a991d43983b1695e158 Mon Sep 17 00:00:00 2001 From: viiccwen Date: Mon, 12 Jan 2026 05:40:22 +0000 Subject: [PATCH 1/2] feat: enhance backend configuration validation in QuMat class - Added checks to ensure `backend_config` is a dictionary and includes required keys: `backend_name` and `backend_options`. - Updated tests to validate these new error conditions, ensuring appropriate exceptions are raised for invalid configurations. - Refactored test code to utilize a centralized `get_backend_config` function for cleaner backend configuration retrieval. --- qumat/qumat.py | 18 +++++++++++ testing/test_create_circuit.py | 57 ++++++++++++++++------------------ 2 files changed, 45 insertions(+), 30 deletions(-) diff --git a/qumat/qumat.py b/qumat/qumat.py index f5135ecd3a..5910170527 100644 --- a/qumat/qumat.py +++ b/qumat/qumat.py @@ -40,8 +40,26 @@ def __init__(self, backend_config): - ``backend_options``: Dictionary with backend-specific options :type backend_config: dict :raises ImportError: If the specified backend module cannot be imported. + :raises ValueError: If backend_config is not a dictionary. :raises KeyError: If required configuration keys are missing. """ + if not isinstance(backend_config, dict): + raise ValueError( + f"backend_config must be a dictionary, got {type(backend_config).__name__}" + ) + + if "backend_name" not in backend_config: + raise KeyError( + "backend_config is missing required key 'backend_name'. " + "Please provide a backend name (e.g., 'qiskit', 'cirq', 'amazon_braket')" + ) + + if "backend_options" not in backend_config: + raise KeyError( + "backend_config is missing required key 'backend_options'. " + "Please provide a dictionary with backend-specific options " + ) + self.backend_config = backend_config self.backend_name = backend_config["backend_name"] self.backend_module = import_module( diff --git a/testing/test_create_circuit.py b/testing/test_create_circuit.py index e6cea46e66..f9305b3d8e 100644 --- a/testing/test_create_circuit.py +++ b/testing/test_create_circuit.py @@ -17,7 +17,7 @@ import pytest -from .utils import TESTING_BACKENDS +from .utils import TESTING_BACKENDS, get_backend_config from qumat import QuMat @@ -25,36 +25,9 @@ class TestCreateCircuit: """Test class for create_empty_circuit functionality.""" - def get_backend_config(self, backend_name): - """Helper method to get backend configuration.""" - if backend_name == "qiskit": - return { - "backend_name": backend_name, - "backend_options": { - "simulator_type": "aer_simulator", - "shots": 1000, - }, - } - elif backend_name == "cirq": - return { - "backend_name": backend_name, - "backend_options": { - "simulator_type": "default", - "shots": 1000, - }, - } - elif backend_name == "amazon_braket": - return { - "backend_name": backend_name, - "backend_options": { - "simulator_type": "local", - "shots": 1000, - }, - } - def test_create_empty_circuit(self, backend_name): """Test that create_empty_circuit works""" - backend_config = self.get_backend_config(backend_name) + backend_config = get_backend_config(backend_name) qumat = QuMat(backend_config) qumat.create_empty_circuit() @@ -63,7 +36,7 @@ def test_create_empty_circuit(self, backend_name): @pytest.mark.parametrize("num_qubits", [0, 1, 3, 5]) def test_create_circuit_initializes_to_zero(self, backend_name, num_qubits): """Test that create_empty_circuit properly initializes all qubits to |0⟩.""" - backend_config = self.get_backend_config(backend_name) + backend_config = get_backend_config(backend_name) qumat = QuMat(backend_config) # Create circuit with specified number of qubits @@ -90,3 +63,27 @@ def test_create_circuit_initializes_to_zero(self, backend_name, num_qubits): assert zero_state_count > 0.95 * total_shots, ( f"Expected |0...0⟩ state, got {zero_state_count}/{total_shots}" ) + + +class TestBackendConfigValidation: + """Test class for backend configuration validation.""" + + @pytest.mark.parametrize("invalid_config", [None, "not a dict"]) + def test_invalid_type_raises_valueerror(self, invalid_config): + """Test that non-dictionary backend_config raises ValueError.""" + with pytest.raises(ValueError, match="backend_config must be a dictionary"): + QuMat(invalid_config) + + def test_missing_backend_name_raises_keyerror(self): + """Test that missing backend_name raises KeyError with helpful message.""" + config = {"backend_options": {"simulator_type": "aer_simulator", "shots": 1024}} + + with pytest.raises(KeyError, match="missing required key.*backend_name"): + QuMat(config) + + def test_missing_backend_options_raises_keyerror(self): + """Test that missing backend_options raises KeyError with helpful message.""" + config = {"backend_name": "qiskit"} + + with pytest.raises(KeyError, match="missing required key.*backend_options"): + QuMat(config) From 1fcfaa1662af86265ed7888a7c04029fb6e6f7ca Mon Sep 17 00:00:00 2001 From: viiccwen Date: Mon, 12 Jan 2026 08:14:15 +0000 Subject: [PATCH 2/2] fix: lint issue --- qumat/qumat.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/qumat/qumat.py b/qumat/qumat.py index 5910170527..59c74313b1 100644 --- a/qumat/qumat.py +++ b/qumat/qumat.py @@ -47,19 +47,19 @@ def __init__(self, backend_config): raise ValueError( f"backend_config must be a dictionary, got {type(backend_config).__name__}" ) - + if "backend_name" not in backend_config: raise KeyError( "backend_config is missing required key 'backend_name'. " "Please provide a backend name (e.g., 'qiskit', 'cirq', 'amazon_braket')" ) - + if "backend_options" not in backend_config: raise KeyError( "backend_config is missing required key 'backend_options'. " "Please provide a dictionary with backend-specific options " ) - + self.backend_config = backend_config self.backend_name = backend_config["backend_name"] self.backend_module = import_module(