From c94825f5205f7f7143a2646640725a86afdd53b8 Mon Sep 17 00:00:00 2001 From: mhucka Date: Thu, 12 Mar 2026 21:57:06 +0000 Subject: [PATCH 01/10] Fix #481: add mocking of Pubchem network calls In order to avoid failures in CI, this follows a [recommendation from Pavol Juhas on PR #1113]( https://github.com/quantumlib/OpenFermion/pull/1113#pullrequestreview-3166162349) about using mocking to avoid flaky test behavior in `pubchem_test.py`. --- src/openfermion/chem/pubchem_test.py | 149 +++++++++++++++++++++++++++ 1 file changed, 149 insertions(+) diff --git a/src/openfermion/chem/pubchem_test.py b/src/openfermion/chem/pubchem_test.py index 5c3cbbffb..36bc2d01e 100644 --- a/src/openfermion/chem/pubchem_test.py +++ b/src/openfermion/chem/pubchem_test.py @@ -11,13 +11,58 @@ # limitations under the License. """Tests for pubchem.py.""" +import time import unittest +from unittest.mock import patch + import numpy import pytest from openfermion.chem.pubchem import geometry_from_pubchem from openfermion.testing.testing_utils import module_importable + +class MockCompound: + def __init__(self, atoms): + self._atoms = atoms + + def to_dict(self, properties): + return {'atoms': self._atoms} + + +def mock_get_compounds(name, searchtype, record_type='2d'): + if name == 'water' and record_type == '3d': + return [ + MockCompound( + [ + {'aid': 1, 'number': 8, 'element': 'O', 'y': 0, 'z': 0, 'x': 0}, + {'aid': 2, 'number': 1, 'element': 'H', 'y': 0.8929, 'z': 0.2544, 'x': 0.2774}, + { + 'aid': 3, + 'number': 1, + 'element': 'H', + 'y': -0.2383, + 'z': -0.7169, + 'x': 0.6068, + }, + ] + ) + ] + if name == 'water' and record_type == '2d': + return [ + MockCompound( + [ + {'aid': 1, 'number': 8, 'element': 'O', 'y': -0.155, 'x': 2.5369}, + {'aid': 2, 'number': 1, 'element': 'H', 'y': 0.155, 'x': 3.0739}, + {'aid': 3, 'number': 1, 'element': 'H', 'y': 0.155, 'x': 2}, + ] + ) + ] + if name == 'helium' and record_type == '2d': + return [MockCompound([{'aid': 1, 'number': 2, 'element': 'He', 'y': 0, 'x': 2}])] + return [] + + using_pubchempy = pytest.mark.skipif( module_importable('pubchempy') is False, reason='Not detecting `pubchempy`.' ) @@ -25,6 +70,21 @@ @using_pubchempy class OpenFermionPubChemTest(unittest.TestCase): + def _get_geometry_with_retries(self, name): + import pubchempy + import urllib.error + + max_retries = 3 + delay = 2 + for attempt in range(max_retries): + try: + return geometry_from_pubchem(name) + except (pubchempy.PubChemHTTPError, urllib.error.URLError): + if attempt == max_retries - 1: + raise + time.sleep(delay) + + @patch('pubchempy.get_compounds', mock_get_compounds) def test_water(self): water_geometry = geometry_from_pubchem('water') self.water_natoms = len(water_geometry) @@ -64,6 +124,7 @@ def test_water(self): self.assertTrue(water_bond_angle_low <= self.water_bond_angle) self.assertTrue(water_bond_angle_high >= self.water_bond_angle) + @patch('pubchempy.get_compounds', mock_get_compounds) def test_helium(self): helium_geometry = geometry_from_pubchem('helium') self.helium_natoms = len(helium_geometry) @@ -71,11 +132,13 @@ def test_helium(self): helium_natoms = 1 self.assertEqual(helium_natoms, self.helium_natoms) + @patch('pubchempy.get_compounds', mock_get_compounds) def test_none(self): none_geometry = geometry_from_pubchem('none') self.assertIsNone(none_geometry) + @patch('pubchempy.get_compounds', mock_get_compounds) def test_water_2d(self): water_geometry = geometry_from_pubchem('water', structure='2d') self.water_natoms = len(water_geometry) @@ -91,3 +154,89 @@ def test_water_2d(self): with pytest.raises(ValueError, match='Incorrect value for the argument structure'): _ = geometry_from_pubchem('water', structure='foo') + + def test_geometry_from_pubchem_live_api(self): + try: + import pubchempy + except ImportError: # pragma: no cover + return + + water_geometry = self._get_geometry_with_retries('water') + self.assertEqual(len(water_geometry), 3) + + @patch('time.sleep', return_value=None) + @patch('pubchempy.get_compounds') + def test_geometry_from_pubchem_retry_success(self, mock_get_compounds, mock_sleep): + try: + import pubchempy + except ImportError: # pragma: no cover + return + + # Simulate HTTP error with proper code attribute for the first 2 calls, then succeed + class FakeHTTPError(Exception): + def __init__(self, code, msg): + self.code = code + self.reason = msg + + def read(self): + return b'{"Fault": {"Details": ["busy"]}}' + + mock_get_compounds.side_effect = [ + pubchempy.PubChemHTTPError(FakeHTTPError(503, 'Server Busy')), + pubchempy.PubChemHTTPError(FakeHTTPError(503, 'Server Busy')), + [ + MockCompound( + [ + {'aid': 1, 'number': 8, 'element': 'O', 'y': 0, 'z': 0, 'x': 0}, + { + 'aid': 2, + 'number': 1, + 'element': 'H', + 'y': 0.8929, + 'z': 0.2544, + 'x': 0.2774, + }, + { + 'aid': 3, + 'number': 1, + 'element': 'H', + 'y': -0.2383, + 'z': -0.7169, + 'x': 0.6068, + }, + ] + ) + ], + ] + + water_geometry = self._get_geometry_with_retries('water') + + self.assertEqual(len(water_geometry), 3) + self.assertEqual(mock_get_compounds.call_count, 3) + self.assertEqual(mock_sleep.call_count, 2) + + @patch('time.sleep', return_value=None) + @patch('pubchempy.get_compounds') + def test_geometry_from_pubchem_retry_failure(self, mock_get_compounds, mock_sleep): + try: + import pubchempy + except ImportError: # pragma: no cover + return + + class FakeHTTPError(Exception): + def __init__(self, code, msg): + self.code = code + self.reason = msg + + def read(self): + return b'{"Fault": {"Details": ["busy"]}}' + + mock_get_compounds.side_effect = pubchempy.PubChemHTTPError( + FakeHTTPError(503, 'Server Busy') + ) + + with self.assertRaises(pubchempy.PubChemHTTPError): + self._get_geometry_with_retries('water') + + self.assertEqual(mock_get_compounds.call_count, 3) + self.assertEqual(mock_sleep.call_count, 2) From 3e4414433c5edc15292e9fa5a11487633c90d2fa Mon Sep 17 00:00:00 2001 From: mhucka Date: Sat, 14 Mar 2026 03:59:44 +0000 Subject: [PATCH 02/10] Many fixes --- src/openfermion/chem/pubchem_test.py | 30 +++++++--------------------- 1 file changed, 7 insertions(+), 23 deletions(-) diff --git a/src/openfermion/chem/pubchem_test.py b/src/openfermion/chem/pubchem_test.py index 36bc2d01e..5ed7b155d 100644 --- a/src/openfermion/chem/pubchem_test.py +++ b/src/openfermion/chem/pubchem_test.py @@ -9,6 +9,7 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. + """Tests for pubchem.py.""" import time @@ -71,9 +72,10 @@ def mock_get_compounds(name, searchtype, record_type='2d'): @using_pubchempy class OpenFermionPubChemTest(unittest.TestCase): def _get_geometry_with_retries(self, name): - import pubchempy import urllib.error + import pubchempy + max_retries = 3 delay = 2 for attempt in range(max_retries): @@ -155,6 +157,7 @@ def test_water_2d(self): with pytest.raises(ValueError, match='Incorrect value for the argument structure'): _ = geometry_from_pubchem('water', structure='foo') + @pytest.mark.integration def test_geometry_from_pubchem_live_api(self): try: import pubchempy @@ -172,18 +175,9 @@ def test_geometry_from_pubchem_retry_success(self, mock_get_compounds, mock_slee except ImportError: # pragma: no cover return - # Simulate HTTP error with proper code attribute for the first 2 calls, then succeed - class FakeHTTPError(Exception): - def __init__(self, code, msg): - self.code = code - self.reason = msg - - def read(self): - return b'{"Fault": {"Details": ["busy"]}}' - mock_get_compounds.side_effect = [ - pubchempy.PubChemHTTPError(FakeHTTPError(503, 'Server Busy')), - pubchempy.PubChemHTTPError(FakeHTTPError(503, 'Server Busy')), + pubchempy.PubChemHTTPError(503, 'Server Busy', 'Testing'), + pubchempy.PubChemHTTPError(503, 'Server Busy', 'Testing'), [ MockCompound( [ @@ -223,17 +217,7 @@ def test_geometry_from_pubchem_retry_failure(self, mock_get_compounds, mock_slee except ImportError: # pragma: no cover return - class FakeHTTPError(Exception): - def __init__(self, code, msg): - self.code = code - self.reason = msg - - def read(self): - return b'{"Fault": {"Details": ["busy"]}}' - - mock_get_compounds.side_effect = pubchempy.PubChemHTTPError( - FakeHTTPError(503, 'Server Busy') - ) + mock_get_compounds.side_effect = pubchempy.PubChemHTTPError(503, 'Server Busy', 'Testing') with self.assertRaises(pubchempy.PubChemHTTPError): self._get_geometry_with_retries('water') From 63ddd11aa4f181ba8e5de9206de50dbda77db4a6 Mon Sep 17 00:00:00 2001 From: mhucka Date: Sat, 14 Mar 2026 05:25:39 +0000 Subject: [PATCH 03/10] Define pytest marker "integration" --- dev_tools/conf/pytest.ini | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/dev_tools/conf/pytest.ini b/dev_tools/conf/pytest.ini index 5f7e1fb2d..af1177aaf 100644 --- a/dev_tools/conf/pytest.ini +++ b/dev_tools/conf/pytest.ini @@ -15,6 +15,10 @@ [pytest] markers = slow: marks tests as slow (deselect with '-m "not slow"') + integration: marks tests of integrations with other systems filterwarnings = ignore:Skipped assert_qasm_is_consistent_with_unitary because qiskit.*:UserWarning + +# Add this line to always exclude tests marked as 'integration' by default +addopts = -m "not integration" From 89d7c69cc63be9c0a1b977e77f71edf6b1ecfbda Mon Sep 17 00:00:00 2001 From: mhucka Date: Sat, 14 Mar 2026 05:25:59 +0000 Subject: [PATCH 04/10] Remove unnecessary try-except Gemini Code Assist is right; they're not needed. --- src/openfermion/chem/pubchem_test.py | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/src/openfermion/chem/pubchem_test.py b/src/openfermion/chem/pubchem_test.py index 5ed7b155d..df46d6db0 100644 --- a/src/openfermion/chem/pubchem_test.py +++ b/src/openfermion/chem/pubchem_test.py @@ -159,21 +159,13 @@ def test_water_2d(self): @pytest.mark.integration def test_geometry_from_pubchem_live_api(self): - try: - import pubchempy - except ImportError: # pragma: no cover - return - water_geometry = self._get_geometry_with_retries('water') self.assertEqual(len(water_geometry), 3) @patch('time.sleep', return_value=None) @patch('pubchempy.get_compounds') def test_geometry_from_pubchem_retry_success(self, mock_get_compounds, mock_sleep): - try: - import pubchempy - except ImportError: # pragma: no cover - return + import pubchempy mock_get_compounds.side_effect = [ pubchempy.PubChemHTTPError(503, 'Server Busy', 'Testing'), @@ -212,10 +204,7 @@ def test_geometry_from_pubchem_retry_success(self, mock_get_compounds, mock_slee @patch('time.sleep', return_value=None) @patch('pubchempy.get_compounds') def test_geometry_from_pubchem_retry_failure(self, mock_get_compounds, mock_sleep): - try: - import pubchempy - except ImportError: # pragma: no cover - return + import pubchempy mock_get_compounds.side_effect = pubchempy.PubChemHTTPError(503, 'Server Busy', 'Testing') From 95558d6da1b3ecfb733390aa07e16060871d0c4d Mon Sep 17 00:00:00 2001 From: mhucka Date: Sat, 14 Mar 2026 05:43:34 +0000 Subject: [PATCH 05/10] Add pragma no cover for 2 lines This is test code. This just doesn't seem worth doing more. --- src/openfermion/chem/pubchem_test.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/openfermion/chem/pubchem_test.py b/src/openfermion/chem/pubchem_test.py index df46d6db0..75045c89a 100644 --- a/src/openfermion/chem/pubchem_test.py +++ b/src/openfermion/chem/pubchem_test.py @@ -159,8 +159,8 @@ def test_water_2d(self): @pytest.mark.integration def test_geometry_from_pubchem_live_api(self): - water_geometry = self._get_geometry_with_retries('water') - self.assertEqual(len(water_geometry), 3) + water_geometry = self._get_geometry_with_retries('water') # pragma: no cover + self.assertEqual(len(water_geometry), 3) # pragma: no cover @patch('time.sleep', return_value=None) @patch('pubchempy.get_compounds') From e8a796ff12d0c65ca9e9c47019218e0c692cb49f Mon Sep 17 00:00:00 2001 From: mhucka Date: Thu, 26 Mar 2026 04:52:29 +0000 Subject: [PATCH 06/10] Use Python `match` statement instead of many `if` --- src/openfermion/chem/pubchem_test.py | 69 ++++++++++++++++------------ 1 file changed, 39 insertions(+), 30 deletions(-) diff --git a/src/openfermion/chem/pubchem_test.py b/src/openfermion/chem/pubchem_test.py index 75045c89a..1528c3306 100644 --- a/src/openfermion/chem/pubchem_test.py +++ b/src/openfermion/chem/pubchem_test.py @@ -32,36 +32,45 @@ def to_dict(self, properties): def mock_get_compounds(name, searchtype, record_type='2d'): - if name == 'water' and record_type == '3d': - return [ - MockCompound( - [ - {'aid': 1, 'number': 8, 'element': 'O', 'y': 0, 'z': 0, 'x': 0}, - {'aid': 2, 'number': 1, 'element': 'H', 'y': 0.8929, 'z': 0.2544, 'x': 0.2774}, - { - 'aid': 3, - 'number': 1, - 'element': 'H', - 'y': -0.2383, - 'z': -0.7169, - 'x': 0.6068, - }, - ] - ) - ] - if name == 'water' and record_type == '2d': - return [ - MockCompound( - [ - {'aid': 1, 'number': 8, 'element': 'O', 'y': -0.155, 'x': 2.5369}, - {'aid': 2, 'number': 1, 'element': 'H', 'y': 0.155, 'x': 3.0739}, - {'aid': 3, 'number': 1, 'element': 'H', 'y': 0.155, 'x': 2}, - ] - ) - ] - if name == 'helium' and record_type == '2d': - return [MockCompound([{'aid': 1, 'number': 2, 'element': 'He', 'y': 0, 'x': 2}])] - return [] + match (name, record_type): + case ('water', '3d'): + return [ + MockCompound( + [ + {'aid': 1, 'number': 8, 'element': 'O', 'y': 0, 'z': 0, 'x': 0}, + { + 'aid': 2, + 'number': 1, + 'element': 'H', + 'y': 0.8929, + 'z': 0.2544, + 'x': 0.2774, + }, + { + 'aid': 3, + 'number': 1, + 'element': 'H', + 'y': -0.2383, + 'z': -0.7169, + 'x': 0.6068, + }, + ] + ) + ] + case ('water', '2d'): + return [ + MockCompound( + [ + {'aid': 1, 'number': 8, 'element': 'O', 'y': -0.155, 'x': 2.5369}, + {'aid': 2, 'number': 1, 'element': 'H', 'y': 0.155, 'x': 3.0739}, + {'aid': 3, 'number': 1, 'element': 'H', 'y': 0.155, 'x': 2}, + ] + ) + ] + case ('helium', '2d'): + return [MockCompound([{'aid': 1, 'number': 2, 'element': 'He', 'y': 0, 'x': 2}])] + case _: + return [] using_pubchempy = pytest.mark.skipif( From 552ab23f85e3d3a8febb3af4227cbed63c638b43 Mon Sep 17 00:00:00 2001 From: mhucka Date: Thu, 26 Mar 2026 05:15:23 +0000 Subject: [PATCH 07/10] Add pytest-retry package to pytest requirements --- dev_tools/requirements/deps/pytest.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/dev_tools/requirements/deps/pytest.txt b/dev_tools/requirements/deps/pytest.txt index f5a405353..5ee378fbf 100644 --- a/dev_tools/requirements/deps/pytest.txt +++ b/dev_tools/requirements/deps/pytest.txt @@ -1,6 +1,7 @@ pytest pytest-asyncio pytest-cov +pytest-retry pytest-xdist nbformat From 5bafc2ed27fe02fb74780753e00d5f9c78c9d9b7 Mon Sep 17 00:00:00 2001 From: mhucka Date: Thu, 26 Mar 2026 05:15:39 +0000 Subject: [PATCH 08/10] Remove no-longer-used integration marker --- dev_tools/conf/pytest.ini | 4 ---- 1 file changed, 4 deletions(-) diff --git a/dev_tools/conf/pytest.ini b/dev_tools/conf/pytest.ini index af1177aaf..5f7e1fb2d 100644 --- a/dev_tools/conf/pytest.ini +++ b/dev_tools/conf/pytest.ini @@ -15,10 +15,6 @@ [pytest] markers = slow: marks tests as slow (deselect with '-m "not slow"') - integration: marks tests of integrations with other systems filterwarnings = ignore:Skipped assert_qasm_is_consistent_with_unitary because qiskit.*:UserWarning - -# Add this line to always exclude tests marked as 'integration' by default -addopts = -m "not integration" From b8ccb5f10a9b967ee9c4d6aebfb17f0983e4ecf5 Mon Sep 17 00:00:00 2001 From: mhucka Date: Thu, 26 Mar 2026 05:28:53 +0000 Subject: [PATCH 09/10] Remove the pubchem retry code Per review comments, removing the retry code. --- src/openfermion/chem/pubchem_test.py | 70 +--------------------------- 1 file changed, 2 insertions(+), 68 deletions(-) diff --git a/src/openfermion/chem/pubchem_test.py b/src/openfermion/chem/pubchem_test.py index 1528c3306..3ef81f432 100644 --- a/src/openfermion/chem/pubchem_test.py +++ b/src/openfermion/chem/pubchem_test.py @@ -80,20 +80,6 @@ def mock_get_compounds(name, searchtype, record_type='2d'): @using_pubchempy class OpenFermionPubChemTest(unittest.TestCase): - def _get_geometry_with_retries(self, name): - import urllib.error - - import pubchempy - - max_retries = 3 - delay = 2 - for attempt in range(max_retries): - try: - return geometry_from_pubchem(name) - except (pubchempy.PubChemHTTPError, urllib.error.URLError): - if attempt == max_retries - 1: - raise - time.sleep(delay) @patch('pubchempy.get_compounds', mock_get_compounds) def test_water(self): @@ -166,59 +152,7 @@ def test_water_2d(self): with pytest.raises(ValueError, match='Incorrect value for the argument structure'): _ = geometry_from_pubchem('water', structure='foo') - @pytest.mark.integration + @pytest.mark.flaky(retries=3, delay=2) def test_geometry_from_pubchem_live_api(self): - water_geometry = self._get_geometry_with_retries('water') # pragma: no cover + water_geometry = geometry_from_pubchem('water') # pragma: no cover self.assertEqual(len(water_geometry), 3) # pragma: no cover - - @patch('time.sleep', return_value=None) - @patch('pubchempy.get_compounds') - def test_geometry_from_pubchem_retry_success(self, mock_get_compounds, mock_sleep): - import pubchempy - - mock_get_compounds.side_effect = [ - pubchempy.PubChemHTTPError(503, 'Server Busy', 'Testing'), - pubchempy.PubChemHTTPError(503, 'Server Busy', 'Testing'), - [ - MockCompound( - [ - {'aid': 1, 'number': 8, 'element': 'O', 'y': 0, 'z': 0, 'x': 0}, - { - 'aid': 2, - 'number': 1, - 'element': 'H', - 'y': 0.8929, - 'z': 0.2544, - 'x': 0.2774, - }, - { - 'aid': 3, - 'number': 1, - 'element': 'H', - 'y': -0.2383, - 'z': -0.7169, - 'x': 0.6068, - }, - ] - ) - ], - ] - - water_geometry = self._get_geometry_with_retries('water') - - self.assertEqual(len(water_geometry), 3) - self.assertEqual(mock_get_compounds.call_count, 3) - self.assertEqual(mock_sleep.call_count, 2) - - @patch('time.sleep', return_value=None) - @patch('pubchempy.get_compounds') - def test_geometry_from_pubchem_retry_failure(self, mock_get_compounds, mock_sleep): - import pubchempy - - mock_get_compounds.side_effect = pubchempy.PubChemHTTPError(503, 'Server Busy', 'Testing') - - with self.assertRaises(pubchempy.PubChemHTTPError): - self._get_geometry_with_retries('water') - - self.assertEqual(mock_get_compounds.call_count, 3) - self.assertEqual(mock_sleep.call_count, 2) From e3ad6e7e4ecc53e6c9870810d3d4d779fbc9639f Mon Sep 17 00:00:00 2001 From: mhucka Date: Thu, 26 Mar 2026 05:33:08 +0000 Subject: [PATCH 10/10] Regenerate requirements files This is the result of running the pip-compile script, to account for the addition of `pytest-retry` to `dev_tools/requirements/deps/pytest.txt`. --- dev_tools/requirements/envs/dev.env.txt | 23 +++++++++++-------- dev_tools/requirements/envs/format.env.txt | 8 +++---- dev_tools/requirements/envs/mypy.env.txt | 12 +++++----- dev_tools/requirements/envs/pip-tools.env.txt | 4 ++-- dev_tools/requirements/envs/pylint.env.txt | 19 +++++++++------ .../requirements/envs/pytest-extra.env.txt | 19 +++++++++------ dev_tools/requirements/envs/pytest.env.txt | 17 +++++++++----- dev_tools/requirements/max_compat/dev.env.txt | 15 +++++++----- .../max_compat/pytest-max-compat.env.txt | 17 +++++++++----- 9 files changed, 80 insertions(+), 54 deletions(-) diff --git a/dev_tools/requirements/envs/dev.env.txt b/dev_tools/requirements/envs/dev.env.txt index d07a9e609..7a6169385 100644 --- a/dev_tools/requirements/envs/dev.env.txt +++ b/dev_tools/requirements/envs/dev.env.txt @@ -4,11 +4,11 @@ # # pip-compile --output-file=envs/dev.env.txt deps/format.txt deps/mypy.txt deps/pip-tools.txt deps/pylint.txt deps/pytest.txt deps/resource_estimates_runtime.txt deps/runtime.txt # -ase==3.27.0 +ase==3.28.0 # via -r deps/resource_estimates_runtime.txt astroid==3.3.11 # via pylint -attrs==25.4.0 +attrs==26.1.0 # via # cirq-core # jsonschema @@ -19,11 +19,11 @@ backports-asyncio-runner==1.2.0 ; python_full_version < "3.11" # pytest-asyncio black==26.3.1 # via -r deps/format.txt -build==1.4.0 +build==1.4.2 # via pip-tools certifi==2026.2.25 # via requests -charset-normalizer==3.4.5 +charset-normalizer==3.4.6 # via requests cirq-core==1.5.0 # via -r deps/runtime.txt @@ -35,7 +35,7 @@ contourpy==1.3.2 # via # -r deps/runtime.txt # matplotlib -coverage[toml]==7.13.4 +coverage[toml]==7.13.5 # via pytest-cov cycler==0.12.1 # via matplotlib @@ -51,7 +51,7 @@ execnet==2.1.2 # via pytest-xdist fastjsonschema==2.21.2 # via nbformat -fonttools==4.62.0 +fonttools==4.62.1 # via matplotlib h5py==3.16.0 # via @@ -169,10 +169,13 @@ pytest==9.0.2 # -r deps/pytest.txt # pytest-asyncio # pytest-cov + # pytest-retry # pytest-xdist pytest-asyncio==1.3.0 # via -r deps/pytest.txt -pytest-cov==7.0.0 +pytest-cov==7.1.0 + # via -r deps/pytest.txt +pytest-retry==1.7.0 # via -r deps/pytest.txt pytest-xdist==3.8.0 # via -r deps/pytest.txt @@ -210,7 +213,7 @@ sympy==1.14.0 # via # -r deps/runtime.txt # cirq-core -tomli==2.4.0 +tomli==2.4.1 # via # black # build @@ -227,11 +230,11 @@ traitlets==5.14.3 # via # jupyter-core # nbformat -types-networkx==3.6.1.20260303 +types-networkx==3.6.1.20260321 # via -r deps/mypy.txt types-pytz==2026.1.1.20260304 # via pandas-stubs -types-requests==2.32.4.20260107 +types-requests==2.32.4.20260324 # via -r deps/mypy.txt types-setuptools==82.0.0.20260210 # via -r deps/mypy.txt diff --git a/dev_tools/requirements/envs/format.env.txt b/dev_tools/requirements/envs/format.env.txt index 9125ec0fa..29ca5d1ac 100644 --- a/dev_tools/requirements/envs/format.env.txt +++ b/dev_tools/requirements/envs/format.env.txt @@ -4,7 +4,7 @@ # # pip-compile --constraint=envs/dev.env.txt --output-file=envs/format.env.txt deps/format.txt deps/runtime.txt # -attrs==25.4.0 +attrs==26.1.0 # via # -c envs/dev.env.txt # cirq-core @@ -20,7 +20,7 @@ certifi==2026.2.25 # via # -c envs/dev.env.txt # requests -charset-normalizer==3.4.5 +charset-normalizer==3.4.6 # via # -c envs/dev.env.txt # requests @@ -49,7 +49,7 @@ duet==0.2.9 # via # -c envs/dev.env.txt # cirq-core -fonttools==4.62.0 +fonttools==4.62.1 # via # -c envs/dev.env.txt # matplotlib @@ -157,7 +157,7 @@ sympy==1.14.0 # -c envs/dev.env.txt # -r deps/runtime.txt # cirq-core -tomli==2.4.0 +tomli==2.4.1 # via # -c envs/dev.env.txt # black diff --git a/dev_tools/requirements/envs/mypy.env.txt b/dev_tools/requirements/envs/mypy.env.txt index fa7ce7edd..a5388395d 100644 --- a/dev_tools/requirements/envs/mypy.env.txt +++ b/dev_tools/requirements/envs/mypy.env.txt @@ -4,7 +4,7 @@ # # pip-compile --constraint=envs/dev.env.txt --output-file=envs/mypy.env.txt deps/mypy.txt deps/runtime.txt # -attrs==25.4.0 +attrs==26.1.0 # via # -c envs/dev.env.txt # cirq-core @@ -16,7 +16,7 @@ certifi==2026.2.25 # via # -c envs/dev.env.txt # requests -charset-normalizer==3.4.5 +charset-normalizer==3.4.6 # via # -c envs/dev.env.txt # requests @@ -41,7 +41,7 @@ duet==0.2.9 # via # -c envs/dev.env.txt # cirq-core -fonttools==4.62.0 +fonttools==4.62.1 # via # -c envs/dev.env.txt # matplotlib @@ -154,7 +154,7 @@ sympy==1.14.0 # -c envs/dev.env.txt # -r deps/runtime.txt # cirq-core -tomli==2.4.0 +tomli==2.4.1 # via # -c envs/dev.env.txt # mypy @@ -162,7 +162,7 @@ tqdm==4.67.3 # via # -c envs/dev.env.txt # cirq-core -types-networkx==3.6.1.20260303 +types-networkx==3.6.1.20260321 # via # -c envs/dev.env.txt # -r deps/mypy.txt @@ -170,7 +170,7 @@ types-pytz==2026.1.1.20260304 # via # -c envs/dev.env.txt # pandas-stubs -types-requests==2.32.4.20260107 +types-requests==2.32.4.20260324 # via # -c envs/dev.env.txt # -r deps/mypy.txt diff --git a/dev_tools/requirements/envs/pip-tools.env.txt b/dev_tools/requirements/envs/pip-tools.env.txt index ca7ffceb3..6b7167b2a 100644 --- a/dev_tools/requirements/envs/pip-tools.env.txt +++ b/dev_tools/requirements/envs/pip-tools.env.txt @@ -4,7 +4,7 @@ # # pip-compile --constraint=envs/dev.env.txt --output-file=envs/pip-tools.env.txt deps/pip-tools.txt # -build==1.4.0 +build==1.4.2 # via # -c envs/dev.env.txt # pip-tools @@ -26,7 +26,7 @@ pyproject-hooks==1.2.0 # -c envs/dev.env.txt # build # pip-tools -tomli==2.4.0 +tomli==2.4.1 # via # -c envs/dev.env.txt # build diff --git a/dev_tools/requirements/envs/pylint.env.txt b/dev_tools/requirements/envs/pylint.env.txt index 3793ae366..54ec7be6e 100644 --- a/dev_tools/requirements/envs/pylint.env.txt +++ b/dev_tools/requirements/envs/pylint.env.txt @@ -4,7 +4,7 @@ # # pip-compile --constraint=envs/dev.env.txt --output-file=envs/pylint.env.txt deps/pylint.txt deps/runtime.txt # -ase==3.27.0 +ase==3.28.0 # via # -c envs/dev.env.txt # -r deps/resource_estimates_runtime.txt @@ -12,7 +12,7 @@ astroid==3.3.11 # via # -c envs/dev.env.txt # pylint -attrs==25.4.0 +attrs==26.1.0 # via # -c envs/dev.env.txt # cirq-core @@ -27,7 +27,7 @@ certifi==2026.2.25 # via # -c envs/dev.env.txt # requests -charset-normalizer==3.4.5 +charset-normalizer==3.4.6 # via # -c envs/dev.env.txt # requests @@ -40,7 +40,7 @@ contourpy==1.3.2 # -c envs/dev.env.txt # -r deps/runtime.txt # matplotlib -coverage[toml]==7.13.4 +coverage[toml]==7.13.5 # via # -c envs/dev.env.txt # pytest-cov @@ -72,7 +72,7 @@ fastjsonschema==2.21.2 # via # -c envs/dev.env.txt # nbformat -fonttools==4.62.0 +fonttools==4.62.1 # via # -c envs/dev.env.txt # matplotlib @@ -214,12 +214,17 @@ pytest==9.0.2 # -r deps/pytest.txt # pytest-asyncio # pytest-cov + # pytest-retry # pytest-xdist pytest-asyncio==1.3.0 # via # -c envs/dev.env.txt # -r deps/pytest.txt -pytest-cov==7.0.0 +pytest-cov==7.1.0 + # via + # -c envs/dev.env.txt + # -r deps/pytest.txt +pytest-retry==1.7.0 # via # -c envs/dev.env.txt # -r deps/pytest.txt @@ -272,7 +277,7 @@ sympy==1.14.0 # -c envs/dev.env.txt # -r deps/runtime.txt # cirq-core -tomli==2.4.0 +tomli==2.4.1 # via # -c envs/dev.env.txt # coverage diff --git a/dev_tools/requirements/envs/pytest-extra.env.txt b/dev_tools/requirements/envs/pytest-extra.env.txt index fddc6a2c0..abc7f42a6 100644 --- a/dev_tools/requirements/envs/pytest-extra.env.txt +++ b/dev_tools/requirements/envs/pytest-extra.env.txt @@ -4,11 +4,11 @@ # # pip-compile --constraint=envs/dev.env.txt --output-file=envs/pytest-extra.env.txt deps/pytest.txt deps/resource_estimates_runtime.txt deps/runtime.txt # -ase==3.27.0 +ase==3.28.0 # via # -c envs/dev.env.txt # -r deps/resource_estimates_runtime.txt -attrs==25.4.0 +attrs==26.1.0 # via # -c envs/dev.env.txt # cirq-core @@ -23,7 +23,7 @@ certifi==2026.2.25 # via # -c envs/dev.env.txt # requests -charset-normalizer==3.4.5 +charset-normalizer==3.4.6 # via # -c envs/dev.env.txt # requests @@ -36,7 +36,7 @@ contourpy==1.3.2 # -c envs/dev.env.txt # -r deps/runtime.txt # matplotlib -coverage[toml]==7.13.4 +coverage[toml]==7.13.5 # via # -c envs/dev.env.txt # pytest-cov @@ -64,7 +64,7 @@ fastjsonschema==2.21.2 # via # -c envs/dev.env.txt # nbformat -fonttools==4.62.0 +fonttools==4.62.1 # via # -c envs/dev.env.txt # matplotlib @@ -193,12 +193,17 @@ pytest==9.0.2 # -r deps/pytest.txt # pytest-asyncio # pytest-cov + # pytest-retry # pytest-xdist pytest-asyncio==1.3.0 # via # -c envs/dev.env.txt # -r deps/pytest.txt -pytest-cov==7.0.0 +pytest-cov==7.1.0 + # via + # -c envs/dev.env.txt + # -r deps/pytest.txt +pytest-retry==1.7.0 # via # -c envs/dev.env.txt # -r deps/pytest.txt @@ -251,7 +256,7 @@ sympy==1.14.0 # -c envs/dev.env.txt # -r deps/runtime.txt # cirq-core -tomli==2.4.0 +tomli==2.4.1 # via # -c envs/dev.env.txt # coverage diff --git a/dev_tools/requirements/envs/pytest.env.txt b/dev_tools/requirements/envs/pytest.env.txt index 7a036467e..b8da4c496 100644 --- a/dev_tools/requirements/envs/pytest.env.txt +++ b/dev_tools/requirements/envs/pytest.env.txt @@ -4,7 +4,7 @@ # # pip-compile --constraint=envs/dev.env.txt --output-file=envs/pytest.env.txt deps/pytest.txt deps/runtime.txt # -attrs==25.4.0 +attrs==26.1.0 # via # -c envs/dev.env.txt # cirq-core @@ -19,7 +19,7 @@ certifi==2026.2.25 # via # -c envs/dev.env.txt # requests -charset-normalizer==3.4.5 +charset-normalizer==3.4.6 # via # -c envs/dev.env.txt # requests @@ -32,7 +32,7 @@ contourpy==1.3.2 # -c envs/dev.env.txt # -r deps/runtime.txt # matplotlib -coverage[toml]==7.13.4 +coverage[toml]==7.13.5 # via # -c envs/dev.env.txt # pytest-cov @@ -60,7 +60,7 @@ fastjsonschema==2.21.2 # via # -c envs/dev.env.txt # nbformat -fonttools==4.62.0 +fonttools==4.62.1 # via # -c envs/dev.env.txt # matplotlib @@ -160,12 +160,17 @@ pytest==9.0.2 # -r deps/pytest.txt # pytest-asyncio # pytest-cov + # pytest-retry # pytest-xdist pytest-asyncio==1.3.0 # via # -c envs/dev.env.txt # -r deps/pytest.txt -pytest-cov==7.0.0 +pytest-cov==7.1.0 + # via + # -c envs/dev.env.txt + # -r deps/pytest.txt +pytest-retry==1.7.0 # via # -c envs/dev.env.txt # -r deps/pytest.txt @@ -214,7 +219,7 @@ sympy==1.14.0 # -c envs/dev.env.txt # -r deps/runtime.txt # cirq-core -tomli==2.4.0 +tomli==2.4.1 # via # -c envs/dev.env.txt # coverage diff --git a/dev_tools/requirements/max_compat/dev.env.txt b/dev_tools/requirements/max_compat/dev.env.txt index 357f9c990..46542c807 100644 --- a/dev_tools/requirements/max_compat/dev.env.txt +++ b/dev_tools/requirements/max_compat/dev.env.txt @@ -4,7 +4,7 @@ # # pip-compile --constraint=deps/oldest-versions.txt --output-file=max_compat/dev.env.txt deps/pytest.txt deps/runtime.txt # -attrs==25.4.0 +attrs==26.1.0 # via # cirq-core # jsonschema @@ -15,7 +15,7 @@ backports-asyncio-runner==1.2.0 ; python_full_version < "3.11" # pytest-asyncio certifi==2026.2.25 # via requests -charset-normalizer==3.4.5 +charset-normalizer==3.4.6 # via requests cirq-core==1.4.1 # via @@ -25,7 +25,7 @@ contourpy==1.3.2 # via # -r deps/runtime.txt # matplotlib -coverage[toml]==7.13.4 +coverage[toml]==7.13.5 # via pytest-cov cycler==0.12.1 # via matplotlib @@ -39,7 +39,7 @@ execnet==2.1.2 # via pytest-xdist fastjsonschema==2.21.2 # via nbformat -fonttools==4.62.0 +fonttools==4.62.1 # via matplotlib h5py==3.16.0 # via -r deps/runtime.txt @@ -100,10 +100,13 @@ pytest==9.0.2 # -r deps/pytest.txt # pytest-asyncio # pytest-cov + # pytest-retry # pytest-xdist pytest-asyncio==1.3.0 # via -r deps/pytest.txt -pytest-cov==7.0.0 +pytest-cov==7.1.0 + # via -r deps/pytest.txt +pytest-retry==1.7.0 # via -r deps/pytest.txt pytest-xdist==3.8.0 # via -r deps/pytest.txt @@ -135,7 +138,7 @@ sympy==1.14.0 # via # -r deps/runtime.txt # cirq-core -tomli==2.4.0 +tomli==2.4.1 # via # coverage # pytest diff --git a/dev_tools/requirements/max_compat/pytest-max-compat.env.txt b/dev_tools/requirements/max_compat/pytest-max-compat.env.txt index 7de7a5993..779e27904 100644 --- a/dev_tools/requirements/max_compat/pytest-max-compat.env.txt +++ b/dev_tools/requirements/max_compat/pytest-max-compat.env.txt @@ -4,7 +4,7 @@ # # pip-compile --constraint=deps/oldest-versions.txt --constraint=max_compat/dev.env.txt --output-file=max_compat/pytest-max-compat.env.txt deps/pytest.txt deps/runtime.txt # -attrs==25.4.0 +attrs==26.1.0 # via # -c max_compat/dev.env.txt # cirq-core @@ -19,7 +19,7 @@ certifi==2026.2.25 # via # -c max_compat/dev.env.txt # requests -charset-normalizer==3.4.5 +charset-normalizer==3.4.6 # via # -c max_compat/dev.env.txt # requests @@ -33,7 +33,7 @@ contourpy==1.3.2 # -c max_compat/dev.env.txt # -r deps/runtime.txt # matplotlib -coverage[toml]==7.13.4 +coverage[toml]==7.13.5 # via # -c max_compat/dev.env.txt # pytest-cov @@ -61,7 +61,7 @@ fastjsonschema==2.21.2 # via # -c max_compat/dev.env.txt # nbformat -fonttools==4.62.0 +fonttools==4.62.1 # via # -c max_compat/dev.env.txt # matplotlib @@ -161,12 +161,17 @@ pytest==9.0.2 # -r deps/pytest.txt # pytest-asyncio # pytest-cov + # pytest-retry # pytest-xdist pytest-asyncio==1.3.0 # via # -c max_compat/dev.env.txt # -r deps/pytest.txt -pytest-cov==7.0.0 +pytest-cov==7.1.0 + # via + # -c max_compat/dev.env.txt + # -r deps/pytest.txt +pytest-retry==1.7.0 # via # -c max_compat/dev.env.txt # -r deps/pytest.txt @@ -215,7 +220,7 @@ sympy==1.14.0 # -c max_compat/dev.env.txt # -r deps/runtime.txt # cirq-core -tomli==2.4.0 +tomli==2.4.1 # via # -c max_compat/dev.env.txt # coverage