diff --git a/dev_tools/autogenerate-bloqs-notebooks-v2.py b/dev_tools/autogenerate-bloqs-notebooks-v2.py
index aba1b9c0e4..66d89998f6 100644
--- a/dev_tools/autogenerate-bloqs-notebooks-v2.py
+++ b/dev_tools/autogenerate-bloqs-notebooks-v2.py
@@ -43,7 +43,7 @@
python dev_tools/autogenerate-bloqs-notebooks-v2.py
"""
-from typing import Iterable, List
+from collections.abc import Iterable
from qualtran_dev_tools.bloq_finder import get_bloqdocspecs
from qualtran_dev_tools.jupyter_autogen import NotebookSpecV2, render_notebook
@@ -85,7 +85,7 @@ def render_notebooks():
render_notebook(nbspec)
-def _get_toc_section_lines(caption: str, entries: List[str], maxdepth: int = 2) -> List[str]:
+def _get_toc_section_lines(caption: str, entries: list[str], maxdepth: int = 2) -> list[str]:
"""Helper function to get the lines for a section of the table-of-contents."""
return (
['.. toctree::', f' :maxdepth: {maxdepth}', f' :caption: {caption}:', '']
diff --git a/dev_tools/bloq-method-overrides-report.py b/dev_tools/bloq-method-overrides-report.py
index 6f106bfc2f..f4d3530be5 100644
--- a/dev_tools/bloq-method-overrides-report.py
+++ b/dev_tools/bloq-method-overrides-report.py
@@ -11,14 +11,14 @@
# 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.
-from typing import ForwardRef, Set, Type
+from typing import ForwardRef
from qualtran_dev_tools.bloq_finder import get_bloq_classes
from qualtran import Bloq
-def _call_graph(bc: Type[Bloq]):
+def _call_graph(bc: type[Bloq]):
"""Check that a bloq class overrides the right call graph methods.
- Override `build_call_graph` with canonical type annotations.
@@ -42,7 +42,7 @@ def _call_graph(bc: Type[Bloq]):
)
if annot['ssa'] != 'SympySymbolAllocator':
print(f"{bc}.build_call_graph `ssa: 'SympySymbolAllocator'`")
- if annot['return'] != Set[ForwardRef('BloqCountT')]: # type: ignore[misc]
+ if annot['return'] != set[ForwardRef('BloqCountT')]: # type: ignore[misc]
print(f"{bc}.build_call_graph -> 'BloqCountT'")
diff --git a/dev_tools/bloq-quickstarter.html b/dev_tools/bloq-quickstarter.html
index fed8cda3ee..7ae2240a78 100644
--- a/dev_tools/bloq-quickstarter.html
+++ b/dev_tools/bloq-quickstarter.html
@@ -215,7 +215,7 @@
Code
signature += "\n ])"
const template = `from functools import cached_property
-from typing import Dict, Optional, Set, Union
+from typing import Optional, Union
from attrs import frozen
@@ -238,10 +238,10 @@ Code
def signature(self) -> 'Signature':
${signature}
- def build_composite_bloq(self, bb: 'BloqBuilder'${build_sig}) -> Dict[str, 'SoquetT']:
+ def build_composite_bloq(self, bb: 'BloqBuilder'${build_sig}) -> dict[str, 'SoquetT']:
raise NotImplementedError("Implement or delete.")
- def bloq_counts(self, ssa: Optional['SympySymbolAllocator'] = None) -> Set['BloqCountT']:
+ def bloq_counts(self, ssa: Optional['SympySymbolAllocator'] = None) -> set['BloqCountT']:
raise NotImplementedError("Implement or delete.")
def short_name(self) -> str:
diff --git a/dev_tools/qualtran_dev_tools/all_call_graph.py b/dev_tools/qualtran_dev_tools/all_call_graph.py
index 8154423c26..56b5fe530e 100644
--- a/dev_tools/qualtran_dev_tools/all_call_graph.py
+++ b/dev_tools/qualtran_dev_tools/all_call_graph.py
@@ -15,7 +15,7 @@
"""Generate the library-wide call graph from all bloq examples."""
import logging
import warnings
-from typing import Iterable
+from collections.abc import Iterable
import networkx as nx
diff --git a/dev_tools/qualtran_dev_tools/bloq_finder.py b/dev_tools/qualtran_dev_tools/bloq_finder.py
index e0b0d12b49..b4d5ca9017 100644
--- a/dev_tools/qualtran_dev_tools/bloq_finder.py
+++ b/dev_tools/qualtran_dev_tools/bloq_finder.py
@@ -14,15 +14,15 @@
import importlib
import inspect
import subprocess
+from collections.abc import Callable, Iterable
from pathlib import Path
-from typing import Callable, Iterable, List, Tuple, Type
from qualtran import Bloq, BloqDocSpec, BloqExample
from .git_tools import get_git_root
-def _get_paths(bloqs_root: Path, filter_func: Callable[[Path], bool]) -> List[Path]:
+def _get_paths(bloqs_root: Path, filter_func: Callable[[Path], bool]) -> list[Path]:
"""Get *.py files based on `filter_func`."""
cp = subprocess.run(
['git', 'ls-files', '*.py'],
@@ -38,7 +38,7 @@ def _get_paths(bloqs_root: Path, filter_func: Callable[[Path], bool]) -> List[Pa
return paths
-def get_bloq_module_paths(bloqs_root: Path) -> List[Path]:
+def get_bloq_module_paths(bloqs_root: Path) -> list[Path]:
"""Get *.py files for non-test, non-init modules under `bloqs_root`."""
def is_module_path(path: Path) -> bool:
@@ -53,7 +53,7 @@ def is_module_path(path: Path) -> bool:
return _get_paths(bloqs_root, is_module_path)
-def get_bloq_test_module_paths(bloqs_root: Path) -> List[Path]:
+def get_bloq_test_module_paths(bloqs_root: Path) -> list[Path]:
"""Get *_test.py files under `bloqs_root`."""
def is_test_module_path(path: Path) -> bool:
@@ -70,7 +70,7 @@ def _bloq_modpath_to_modname(path: Path) -> str:
return 'qualtran.bloqs.' + str(path)[: -len('.py')].replace('/', '.')
-def modpath_to_bloqs(path: Path) -> Iterable[Type[Bloq]]:
+def modpath_to_bloqs(path: Path) -> Iterable[type[Bloq]]:
"""Given a module path, return all the `Bloq` classes defined within."""
modname = _bloq_modpath_to_modname(path)
mod = importlib.import_module(modname)
@@ -88,7 +88,7 @@ def modpath_to_bloqs(path: Path) -> Iterable[Type[Bloq]]:
yield cls
-def modpath_to_bloq_exs(path: Path) -> Iterable[Tuple[str, str, BloqExample]]:
+def modpath_to_bloq_exs(path: Path) -> Iterable[tuple[str, str, BloqExample]]:
"""Given a module path, return all the `BloqExample`s defined within."""
modname = _bloq_modpath_to_modname(path)
mod = importlib.import_module(modname)
@@ -97,7 +97,7 @@ def modpath_to_bloq_exs(path: Path) -> Iterable[Tuple[str, str, BloqExample]]:
yield modname, name, obj
-def modpath_to_bloqdocspecs(path: Path) -> Iterable[Tuple[str, str, BloqDocSpec]]:
+def modpath_to_bloqdocspecs(path: Path) -> Iterable[tuple[str, str, BloqDocSpec]]:
"""Given a module path, return all the `BloqDocSpec`s defined within."""
modname = _bloq_modpath_to_modname(path)
mod = importlib.import_module(modname)
@@ -106,22 +106,22 @@ def modpath_to_bloqdocspecs(path: Path) -> Iterable[Tuple[str, str, BloqDocSpec]
yield modname, name, obj
-def get_bloq_classes() -> List[Type[Bloq]]:
+def get_bloq_classes() -> list[type[Bloq]]:
reporoot = get_git_root()
bloqs_root = reporoot / 'qualtran/bloqs'
paths = get_bloq_module_paths(bloqs_root)
- bloq_clss: List[Type[Bloq]] = []
+ bloq_clss: list[type[Bloq]] = []
for path in paths:
bloq_clss.extend(modpath_to_bloqs(path))
return bloq_clss
-def get_bloq_examples() -> List[BloqExample]:
+def get_bloq_examples() -> list[BloqExample]:
reporoot = get_git_root()
bloqs_root = reporoot / 'qualtran/bloqs'
paths = get_bloq_module_paths(bloqs_root)
- bexamples: List[BloqExample] = []
+ bexamples: list[BloqExample] = []
for path in paths:
for modname, name, be in modpath_to_bloq_exs(path):
bexamples.append(be)
@@ -129,12 +129,12 @@ def get_bloq_examples() -> List[BloqExample]:
return bexamples
-def get_bloqdocspecs() -> List[BloqDocSpec]:
+def get_bloqdocspecs() -> list[BloqDocSpec]:
reporoot = get_git_root()
bloqs_root = reporoot / 'qualtran/bloqs'
paths = get_bloq_module_paths(bloqs_root)
- bdspecs: List[BloqDocSpec] = []
+ bdspecs: list[BloqDocSpec] = []
for path in paths:
for modname, name, bds in modpath_to_bloqdocspecs(path):
bdspecs.append(bds)
diff --git a/dev_tools/qualtran_dev_tools/bloq_report_card.py b/dev_tools/qualtran_dev_tools/bloq_report_card.py
index 4d26c7ffbc..1a82f086f7 100644
--- a/dev_tools/qualtran_dev_tools/bloq_report_card.py
+++ b/dev_tools/qualtran_dev_tools/bloq_report_card.py
@@ -13,7 +13,8 @@
# limitations under the License.
import time
import warnings
-from typing import Any, Dict, Iterable, List, Optional, Set, Type
+from collections.abc import Iterable
+from typing import Any, Optional
import pandas as pd
import pandas.io.formats.style
@@ -31,7 +32,7 @@
from .bloq_finder import get_bloq_classes, get_bloq_examples
-def _get_package(bloq_cls: Type[Bloq]) -> str:
+def _get_package(bloq_cls: type[Bloq]) -> str:
"""The package name for a bloq class"""
return '.'.join(bloq_cls.__module__.split('.')[:-1])
@@ -56,8 +57,8 @@ def format_status(v: BloqCheckResult):
def bloq_classes_with_no_examples(
- bclasses: Iterable[Type[Bloq]], bexamples: Iterable[BloqExample]
-) -> Set[Type[Bloq]]:
+ bclasses: Iterable[type[Bloq]], bexamples: Iterable[BloqExample]
+) -> set[type[Bloq]]:
ks = set(bclasses)
for be in bexamples:
try:
@@ -72,13 +73,13 @@ def bloq_classes_with_no_examples(
CHECKCOLS = ['make', 'decomp', 'counts', 'serialize', 'qtyping']
-def record_for_class_with_no_examples(k: Type[Bloq]) -> Dict[str, Any]:
+def record_for_class_with_no_examples(k: type[Bloq]) -> dict[str, Any]:
return {'bloq_cls': k.__name__, 'package': _get_package(k), 'name': '-'} | {
check_name: BloqCheckResult.MISSING for check_name in CHECKCOLS
}
-def record_for_bloq_example(be: BloqExample) -> Dict[str, Any]:
+def record_for_bloq_example(be: BloqExample) -> dict[str, Any]:
start = time.perf_counter()
record = {
'bloq_cls': be.bloq_cls.__name__,
@@ -101,7 +102,7 @@ def show_bloq_report_card(df: pd.DataFrame) -> pandas.io.formats.style.Styler:
def get_bloq_report_card(
- bclasses: Optional[Iterable[Type[Bloq]]] = None,
+ bclasses: Optional[Iterable[type[Bloq]]] = None,
bexamples: Optional[Iterable[BloqExample]] = None,
package_prefix: str = 'qualtran.bloqs.',
) -> pd.DataFrame:
@@ -115,7 +116,7 @@ def get_bloq_report_card(
skips = ['qubitization_qpe_hubbard_model_small', 'qubitization_qpe_hubbard_model_large']
bexamples = [bex for bex in bexamples if bex.name not in skips]
- records: List[Dict[str, Any]] = []
+ records: list[dict[str, Any]] = []
missing_bclasses = bloq_classes_with_no_examples(bclasses, bexamples)
records.extend(record_for_class_with_no_examples(k) for k in missing_bclasses)
records.extend(record_for_bloq_example(be) for be in bexamples)
diff --git a/dev_tools/qualtran_dev_tools/clean_notebooks.py b/dev_tools/qualtran_dev_tools/clean_notebooks.py
index a5d31baf1c..83871ade6d 100644
--- a/dev_tools/qualtran_dev_tools/clean_notebooks.py
+++ b/dev_tools/qualtran_dev_tools/clean_notebooks.py
@@ -15,13 +15,13 @@
import subprocess
from pathlib import Path
from tempfile import NamedTemporaryFile
-from typing import Any, List
+from typing import Any
import nbformat
from nbconvert.preprocessors import ClearMetadataPreprocessor, ClearOutputPreprocessor
-def get_nb_rel_paths(rootdir) -> List[Path]:
+def get_nb_rel_paths(rootdir) -> list[Path]:
"""List all checked-in *.ipynb files within `rootdir`."""
cp = subprocess.run(
['git', 'ls-files', '*.ipynb'],
diff --git a/dev_tools/qualtran_dev_tools/incremental_coverage.py b/dev_tools/qualtran_dev_tools/incremental_coverage.py
index e13357eec6..8f7b060b00 100644
--- a/dev_tools/qualtran_dev_tools/incremental_coverage.py
+++ b/dev_tools/qualtran_dev_tools/incremental_coverage.py
@@ -14,7 +14,7 @@
import os.path
import re
-from typing import cast, Dict, List, Optional, Set, Tuple
+from typing import cast, Optional
from . import shell_tools
from .prepared_env import PreparedEnv
@@ -57,7 +57,7 @@
EXPLICIT_OPT_OUT_COMMENT = "#coverage:ignore"
-def diff_to_new_interesting_lines(unified_diff_lines: List[str]) -> Dict[int, str]:
+def diff_to_new_interesting_lines(unified_diff_lines: list[str]) -> dict[int, str]:
"""Extracts a set of 'interesting' lines out of a GNU unified diff format.
Format:
@@ -124,7 +124,7 @@ def fix_line_from_coverage_file(line):
def get_incremental_uncovered_lines(
abs_path: str, base_commit: str, actual_commit: Optional[str]
-) -> List[Tuple[int, str, str]]:
+) -> list[tuple[int, str, str]]:
"""Find touched but uncovered lines in the given file.
Uses git diff and the annotation files created by `pytest --cov-report annotate` to find
@@ -190,9 +190,9 @@ def line_content_counts_as_uncovered_manual(content: str) -> bool:
return True
-def determine_ignored_lines(content: str) -> Set[int]:
+def determine_ignored_lines(content: str) -> set[int]:
lines = content.split("\n")
- result: List[int] = []
+ result: list[int] = []
i = 0
while i < len(lines):
@@ -222,7 +222,7 @@ def determine_ignored_lines(content: str) -> Set[int]:
return {e + 1 for e in result}
-def naive_find_end_of_scope(lines: List[str], i: int) -> int:
+def naive_find_end_of_scope(lines: list[str], i: int) -> int:
# TODO: deal with line continuations, which may be less indented.
# Github issue: https://github.com/quantumlib/Cirq/issues/2968
line = lines[i]
diff --git a/dev_tools/qualtran_dev_tools/jupyter_autogen.py b/dev_tools/qualtran_dev_tools/jupyter_autogen.py
index fb7dd8cfe8..8b9c6e9124 100644
--- a/dev_tools/qualtran_dev_tools/jupyter_autogen.py
+++ b/dev_tools/qualtran_dev_tools/jupyter_autogen.py
@@ -21,7 +21,7 @@
import textwrap
from pathlib import Path
from types import ModuleType
-from typing import List, Optional, Tuple
+from typing import Optional
import nbformat
from attrs import field, frozen
@@ -66,7 +66,7 @@ class NotebookSpecV2:
title: str
module: ModuleType
- bloq_specs: List[BloqDocSpec]
+ bloq_specs: list[BloqDocSpec]
directory: str = field()
_path_stem: Optional[str] = None
@@ -87,7 +87,7 @@ def path(self) -> Path:
return Path(self.directory) / f'{self.path_stem}.ipynb'
-def _get_bloq_example_source_lines(bloq_ex: 'BloqExample') -> List[str]:
+def _get_bloq_example_source_lines(bloq_ex: 'BloqExample') -> list[str]:
"""Parse out the source code from a factory function, so we can render it into a cell.
Args:
@@ -158,7 +158,7 @@ class _PyCell(_Cell):
cell_id: str
-def get_bloq_doc_cells(bloqdoc: BloqDocSpec, cid_prefix: str) -> List[_Cell]:
+def get_bloq_doc_cells(bloqdoc: BloqDocSpec, cid_prefix: str) -> list[_Cell]:
"""Cells introducing the `bloq_cls`"""
md_doc: str = '\n'.join(get_markdown_docstring_lines(bloqdoc.bloq_cls))
@@ -178,19 +178,19 @@ def _get_one_ex_instance_cell(bloq_ex: BloqExample, cid_prefix):
)
-def get_example_instances_cells(bloqdoc: BloqDocSpec, cid_prefix: str) -> List[_Cell]:
+def get_example_instances_cells(bloqdoc: BloqDocSpec, cid_prefix: str) -> list[_Cell]:
"""Cells constructing example instances of the bloq class."""
examples = bloqdoc.examples
if not examples:
return []
- cells: List[_Cell] = [
+ cells: list[_Cell] = [
_MarkdownCell('### Example Instances', cell_id=f'{cid_prefix}.example_instances.md')
]
return cells + [_get_one_ex_instance_cell(ex, cid_prefix) for ex in examples]
-def get_graphical_signature_cells(bloqdoc: BloqDocSpec, cid_prefix: str) -> List[_Cell]:
+def get_graphical_signature_cells(bloqdoc: BloqDocSpec, cid_prefix: str) -> list[_Cell]:
"""Cells showing a 'graphical signature' for the bloq examples."""
if not bloqdoc.examples:
return []
@@ -209,7 +209,7 @@ def get_graphical_signature_cells(bloqdoc: BloqDocSpec, cid_prefix: str) -> List
]
-def get_call_graph_cells(bloqdoc: BloqDocSpec, cid_prefix: str) -> List[_Cell]:
+def get_call_graph_cells(bloqdoc: BloqDocSpec, cid_prefix: str) -> list[_Cell]:
"""Cells showing a call graph for one of the bloq examples."""
if bloqdoc.call_graph_example is None:
return []
@@ -231,8 +231,8 @@ def get_call_graph_cells(bloqdoc: BloqDocSpec, cid_prefix: str) -> List[_Cell]:
]
-def get_cells(bloqdoc: BloqDocSpec) -> List[_Cell]:
- cells: List[_Cell] = []
+def get_cells(bloqdoc: BloqDocSpec) -> list[_Cell]:
+ cells: list[_Cell] = []
cid_prefix = f'{bloqdoc.bloq_cls.__name__}'
cells += get_bloq_doc_cells(bloqdoc, cid_prefix)
cells += get_example_instances_cells(bloqdoc, cid_prefix)
@@ -261,7 +261,7 @@ def _cell_to_nbnode(cell: _Cell) -> nbformat.NotebookNode:
raise ValueError()
-def _get_title_lines(title: str, mod: ModuleType) -> List[str]:
+def _get_title_lines(title: str, mod: ModuleType) -> list[str]:
"""Return markdown lines for the title cell.
This consists of the specified title as well as the associated module's docstring.
@@ -278,7 +278,7 @@ def _get_title_lines(title: str, mod: ModuleType) -> List[str]:
def _init_notebook(
path_stem: str, overwrite=False, directory: str = '.'
-) -> Tuple[nbformat.NotebookNode, Path]:
+) -> tuple[nbformat.NotebookNode, Path]:
"""Initialize a jupyter notebook.
If one already exists: load it in. Otherwise, create a new one.
@@ -404,7 +404,7 @@ def render_notebook(nbspec: NotebookSpecV2) -> None:
# 3. Merge rendered cells into the existing notebook.
# -> we use the cells metadata field to match up cells.
- cqids_to_render: List[str] = list(cells.keys())
+ cqids_to_render: list[str] = list(cells.keys())
for i in range(len(nb.cells)):
nb_node = nb.cells[i]
if _K_CQ_AUTOGEN in nb_node.metadata:
diff --git a/dev_tools/qualtran_dev_tools/notebook_execution.py b/dev_tools/qualtran_dev_tools/notebook_execution.py
index 52a7cfbc5d..d6b344fb14 100644
--- a/dev_tools/qualtran_dev_tools/notebook_execution.py
+++ b/dev_tools/qualtran_dev_tools/notebook_execution.py
@@ -16,7 +16,7 @@
import subprocess
import sys
from pathlib import Path
-from typing import List, Optional, Tuple
+from typing import Optional
import filelock
import nbconvert
@@ -28,7 +28,7 @@
from .git_tools import get_git_root
-def get_nb_rel_paths(sourceroot: Path) -> List[Path]:
+def get_nb_rel_paths(sourceroot: Path) -> list[Path]:
"""List all checked-in *.ipynb files within `sourceroot`."""
cp = subprocess.run(
['git', 'ls-files', '*.ipynb'],
@@ -97,7 +97,7 @@ def needs_reexport(self):
return self.html_needs_reexport() or self.nb_needs_reexport()
-def _make_link_replacements() -> List[Tuple[str, str]]:
+def _make_link_replacements() -> list[tuple[str, str]]:
"""Helper function to make a list of link replacements."""
top_level = [
'Bloq',
@@ -188,7 +188,7 @@ def __init__(self, reporoot: Path, output_nbs: bool, output_html: bool, only_out
self.output_html = output_html
self.only_out_of_date = only_out_of_date
- def __call__(self, nb_rel_path: Path) -> Tuple[Path, Optional[Exception]]:
+ def __call__(self, nb_rel_path: Path) -> tuple[Path, Optional[Exception]]:
paths = _NBInOutPaths.from_nb_rel_path(
nb_rel_path, self.reporoot, output_html=self.output_html, output_nbs=self.output_nbs
)
diff --git a/dev_tools/qualtran_dev_tools/notebook_specs.py b/dev_tools/qualtran_dev_tools/notebook_specs.py
index eb2c113c2b..ae5fc9ad8e 100644
--- a/dev_tools/qualtran_dev_tools/notebook_specs.py
+++ b/dev_tools/qualtran_dev_tools/notebook_specs.py
@@ -27,8 +27,6 @@
3. Update the `NotebookSpec` `bloq_specs` field to include the `BloqDocSpec` for your new bloq.
"""
-from typing import List
-
from qualtran_dev_tools.git_tools import get_git_root
import qualtran.bloqs.arithmetic.addition
@@ -144,7 +142,7 @@
# --------------------------------------------------------------------------
# ----- Basic Gates ----------------------------------------------------
# --------------------------------------------------------------------------
-BASIC_GATES: List[NotebookSpecV2] = [
+BASIC_GATES: list[NotebookSpecV2] = [
NotebookSpecV2(
title='T Gate',
module=qualtran.bloqs.basic_gates.t_gate,
@@ -270,7 +268,7 @@
# --------------------------------------------------------------------------
# ----- Chemistry ------------------------------------------------------
# --------------------------------------------------------------------------
-CHEMISTRY: List[NotebookSpecV2] = [
+CHEMISTRY: list[NotebookSpecV2] = [
NotebookSpecV2(
title='Sparse',
module=qualtran.bloqs.chemistry.sparse,
@@ -769,7 +767,7 @@
# --------------------------------------------------------------------------
# ----- Block Encoding ----------------------------------------------------------
# --------------------------------------------------------------------------
-BLOCK_ENCODING: List[NotebookSpecV2] = [
+BLOCK_ENCODING: list[NotebookSpecV2] = [
NotebookSpecV2(
title='Block Encoding Interface',
module=qualtran.bloqs.block_encoding,
@@ -837,7 +835,7 @@
# --------------------------------------------------------------------------
# ----- Optimization ---------------------------------------------------
# --------------------------------------------------------------------------
-OPTIMIZATION: List[NotebookSpecV2] = [
+OPTIMIZATION: list[NotebookSpecV2] = [
NotebookSpecV2(
title='Planted Noisy kXOR - Kikuchi Guiding State',
module=qualtran.bloqs.optimization.k_xor_sat.kikuchi_guiding_state,
@@ -851,7 +849,7 @@
# --------------------------------------------------------------------------
# ----- Other ----------------------------------------------------------
# --------------------------------------------------------------------------
-OTHER: List[NotebookSpecV2] = [
+OTHER: list[NotebookSpecV2] = [
NotebookSpecV2(
title='Prepare Uniform Superposition',
module=qualtran.bloqs.state_preparation.prepare_uniform_superposition,
diff --git a/dev_tools/qualtran_dev_tools/parse_docstrings.py b/dev_tools/qualtran_dev_tools/parse_docstrings.py
index b296c64193..fdb675eb38 100644
--- a/dev_tools/qualtran_dev_tools/parse_docstrings.py
+++ b/dev_tools/qualtran_dev_tools/parse_docstrings.py
@@ -14,7 +14,7 @@
import inspect
import re
-from typing import List, Type, Union
+from typing import Union
from attrs import frozen
from sphinx.ext.napoleon import Config, GoogleDocstring
@@ -63,14 +63,14 @@ class _GoogleDocstringToMarkdown(GoogleDocstring):
"""Subclass of sphinx's parser to emit Markdown from Google-style docstrings."""
def __init__(self, *args, **kwargs):
- self.references: List[ReferenceT] = []
+ self.references: list[ReferenceT] = []
super().__init__(*args, **kwargs)
def _load_custom_sections(self) -> None:
super()._load_custom_sections()
self._sections['registers'] = self._parse_registers_section
- def _parse_parameters_section(self, section: str) -> List[str]:
+ def _parse_parameters_section(self, section: str) -> list[str]:
"""Sphinx method to emit a 'Parameters' section."""
def _template(name, desc_lines):
@@ -83,7 +83,7 @@ def _template(name, desc_lines):
'',
]
- def _parse_references_section(self, section: str) -> List[str]:
+ def _parse_references_section(self, section: str) -> list[str]:
"""Sphinx method to emit a 'References' section."""
lines = self._dedent(self._consume_to_next_section())
@@ -97,7 +97,7 @@ def _parse_references_section(self, section: str) -> List[str]:
self.references.extend(my_refs)
return ['#### References', '\n'.join(f' - {ref.text}' for ref in my_refs), '']
- def _parse_registers_section(self, section: str) -> List[str]:
+ def _parse_registers_section(self, section: str) -> list[str]:
def _template(name, desc_lines):
desc = ' '.join(desc_lines)
return f' - `{name}`: {desc}'
@@ -109,7 +109,7 @@ def _template(name, desc_lines):
]
-def get_markdown_docstring(cls: Type) -> List[str]:
+def get_markdown_docstring(cls: type) -> list[str]:
"""From a class `cls`, return its docstring as Markdown lines."""
# 1. Sphinx incantation
@@ -123,7 +123,7 @@ def get_markdown_docstring(cls: Type) -> List[str]:
return lines
-def get_markdown_docstring_lines(cls: Type) -> List[str]:
+def get_markdown_docstring_lines(cls: type) -> list[str]:
"""From a class `cls`, return its docstring as Markdown lines with a header."""
# 1. Get documentation lines
@@ -135,7 +135,7 @@ def get_markdown_docstring_lines(cls: Type) -> List[str]:
return lines
-def get_references(cls: Type) -> List[ReferenceT]:
+def get_references(cls: type) -> list[ReferenceT]:
"""Get reference information for a class from the References section of its docstring."""
config = Config()
docstring = cls.__doc__ if cls.__doc__ else ""
diff --git a/dev_tools/qualtran_dev_tools/prepared_env.py b/dev_tools/qualtran_dev_tools/prepared_env.py
index 8dfa56b257..3dff97fc5f 100644
--- a/dev_tools/qualtran_dev_tools/prepared_env.py
+++ b/dev_tools/qualtran_dev_tools/prepared_env.py
@@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-from typing import List, Optional
+from typing import Optional
from . import shell_tools
@@ -47,11 +47,11 @@ def __init__(
self.destination_directory = destination_directory
- def get_changed_files(self) -> List[str]:
+ def get_changed_files(self) -> list[str]:
"""Get the files changed on one git branch vs another.
Returns:
- List[str]: File paths of changed files, relative to the git repo
+ list[str]: File paths of changed files, relative to the git repo
root.
"""
optional_actual_commit_id = [] if self.actual_commit_id is None else [self.actual_commit_id]
diff --git a/dev_tools/qualtran_dev_tools/reference_docs.py b/dev_tools/qualtran_dev_tools/reference_docs.py
index a0a6d59a44..e792355c9b 100644
--- a/dev_tools/qualtran_dev_tools/reference_docs.py
+++ b/dev_tools/qualtran_dev_tools/reference_docs.py
@@ -14,8 +14,8 @@
import re
from collections import defaultdict
+from collections.abc import Iterable
from pathlib import Path
-from typing import Dict, Iterable, List, Type
import jinja2
import tensorflow_docs.api_generator.parser
@@ -65,7 +65,7 @@ def filter_type_aliases_in_the_wrong_place(path, parent, children):
return ret
-def _filter_and_sort_members(py_object: object, members: Iterable[MemberInfo]) -> List[MemberInfo]:
+def _filter_and_sort_members(py_object: object, members: Iterable[MemberInfo]) -> list[MemberInfo]:
"""Sort `members` according to their order in the source definition.
For example: you can order class methods according to their order of definition
@@ -79,7 +79,7 @@ def _filter_and_sort_members(py_object: object, members: Iterable[MemberInfo]) -
return sorted(fmembs, key=lambda m: ordering[m.short_name])
-def mixin_custom_template(template_name: str) -> Type:
+def mixin_custom_template(template_name: str) -> type:
"""Return a mixin for using a custom jinja template in TemplatePageBuilder classes."""
class _CustomTemplateMixin:
@@ -382,7 +382,7 @@ def generate_ref_toc(reporoot: Path):
page_paths = output_dir.glob('qualtran/**/*.md')
# Group according to module
- grouped_paths: Dict[Path, List] = defaultdict(list)
+ grouped_paths: dict[Path, list] = defaultdict(list)
for path in page_paths:
grouped_paths[path.parent].append(path)
diff --git a/dev_tools/qualtran_dev_tools/shell_tools.py b/dev_tools/qualtran_dev_tools/shell_tools.py
index ef02ed8e05..79a4efb5b0 100644
--- a/dev_tools/qualtran_dev_tools/shell_tools.py
+++ b/dev_tools/qualtran_dev_tools/shell_tools.py
@@ -14,7 +14,7 @@
import subprocess
import sys
-from typing import List, Tuple, Union
+from typing import Union
BOLD = 1
DIM = 2
@@ -37,7 +37,7 @@ def highlight(text: str, color_code: int, bold: bool = False) -> str:
return "{}\033[{}m{}\033[0m".format("\033[1m" if bold else "", color_code, text)
-def abbreviate_command_arguments_after_switches(cmd: Tuple[str, ...]) -> Tuple[str, ...]:
+def abbreviate_command_arguments_after_switches(cmd: tuple[str, ...]) -> tuple[str, ...]:
result = [cmd[0]]
for i in range(1, len(cmd)):
if not cmd[i].startswith("-"):
@@ -48,7 +48,7 @@ def abbreviate_command_arguments_after_switches(cmd: Tuple[str, ...]) -> Tuple[s
def run(
- args: Union[str, List[str]],
+ args: Union[str, list[str]],
*,
log_run_to_stderr: bool = True,
abbreviate_non_option_arguments: bool = False,
@@ -87,14 +87,14 @@ def run(
# setup our default for subprocess.run flag arguments
subprocess_run_kwargs.update(check=check, text=text)
if log_run_to_stderr:
- cmd_desc: Tuple[str, ...] = (args,) if isinstance(args, str) else tuple(args)
+ cmd_desc: tuple[str, ...] = (args,) if isinstance(args, str) else tuple(args)
if abbreviate_non_option_arguments:
cmd_desc = abbreviate_command_arguments_after_switches(cmd_desc)
print("run:", cmd_desc, file=sys.stderr)
return subprocess.run(args, **subprocess_run_kwargs) # pylint: disable=subprocess-run-check
-def output_of(args: Union[str, List[str]], **kwargs) -> str:
+def output_of(args: Union[str, list[str]], **kwargs) -> str:
"""Invokes a subprocess and returns its output as a string.
Args:
diff --git a/dev_tools/qualtran_dev_tools/tensor_report_card.py b/dev_tools/qualtran_dev_tools/tensor_report_card.py
index c2e3fa2df3..cd3284185d 100644
--- a/dev_tools/qualtran_dev_tools/tensor_report_card.py
+++ b/dev_tools/qualtran_dev_tools/tensor_report_card.py
@@ -13,7 +13,8 @@
# limitations under the License.
import multiprocessing.connection
import time
-from typing import Any, Callable, Dict, List, Optional, Tuple
+from collections.abc import Callable
+from typing import Any, Optional
from attrs import define
@@ -28,7 +29,7 @@ class _Pending:
p: multiprocessing.Process
recv: multiprocessing.connection.Connection
start_time: float
- kwargs: Dict[str, Any]
+ kwargs: dict[str, Any]
class ExecuteWithTimeout:
@@ -42,15 +43,15 @@ def __init__(self, timeout: float, max_workers: int):
self.timeout = timeout
self.max_workers = max_workers
- self.queued: List[Tuple[Callable, Dict[str, Any]]] = []
- self.pending: List[_Pending] = []
+ self.queued: list[tuple[Callable, dict[str, Any]]] = []
+ self.pending: list[_Pending] = []
@property
def work_to_be_done(self) -> int:
"""The number of tasks currently executing or queued."""
return len(self.queued) + len(self.pending)
- def submit(self, func: Callable, kwargs: Dict[str, Any]) -> None:
+ def submit(self, func: Callable, kwargs: dict[str, Any]) -> None:
"""Add a task to the queue.
`func` must be a callable that can accept `kwargs` in addition to
@@ -92,7 +93,7 @@ def _scan_pendings(self) -> Optional[_Pending]:
return None
- def next_result(self) -> Tuple[Dict[str, Any], Optional[Any]]:
+ def next_result(self) -> tuple[dict[str, Any], Optional[Any]]:
"""Get the next available result.
This call is blocking, but should never take longer than `self.timeout`. This should
@@ -131,7 +132,7 @@ def report_on_tensors(name: str, cls_name: str, bloq: Bloq, cxn) -> None:
This should be used with `ExecuteWithTimeout`. The resultant
record dictionary is sent over `cxn`.
"""
- record: Dict[str, Any] = {'name': name, 'cls': cls_name}
+ record: dict[str, Any] = {'name': name, 'cls': cls_name}
try:
start = time.perf_counter()
diff --git a/qualtran/_infra/adjoint.py b/qualtran/_infra/adjoint.py
index 0601a6248e..e07cea3fdf 100644
--- a/qualtran/_infra/adjoint.py
+++ b/qualtran/_infra/adjoint.py
@@ -14,7 +14,7 @@
from collections import Counter
from functools import cached_property
-from typing import Dict, List, Optional, Tuple, TYPE_CHECKING
+from typing import Optional, TYPE_CHECKING
from attrs import frozen
@@ -31,7 +31,7 @@
from qualtran.resource_counting import BloqCountDictT, SympySymbolAllocator
-def _adjoint_final_soqs(cbloq: 'CompositeBloq', new_signature: Signature) -> Dict[str, 'SoquetT']:
+def _adjoint_final_soqs(cbloq: 'CompositeBloq', new_signature: Signature) -> dict[str, 'SoquetT']:
"""`CompositeBloq.final_soqs()` but backwards."""
if LeftDangle not in cbloq._binst_graph:
return {}
@@ -59,7 +59,7 @@ def _adjoint_cbloq(cbloq: 'CompositeBloq') -> 'CompositeBloq':
new_signature = cbloq.signature.adjoint()
old_i_soqs = [_reg_to_soq(RightDangle, reg) for reg in old_signature.rights()]
new_i_soqs = [_reg_to_soq(LeftDangle, reg) for reg in new_signature.lefts()]
- soq_map: List[Tuple[SoquetT, SoquetT]] = list(zip(old_i_soqs, new_i_soqs))
+ soq_map: list[tuple[SoquetT, SoquetT]] = list(zip(old_i_soqs, new_i_soqs))
# Then we reverse the order of subbloqs
bloqnections = reversed(list(cbloq.iter_bloqnections()))
@@ -175,7 +175,7 @@ def __str__(self) -> str:
return f'{str(self.subbloq)}†'
def wire_symbol(
- self, reg: Optional['Register'], idx: Tuple[int, ...] = tuple()
+ self, reg: Optional['Register'], idx: tuple[int, ...] = tuple()
) -> 'WireSymbol':
# Note: since we pass are passed a soquet which has the 'new' side, we flip it before
# delegating and then flip back. Subbloqs only have to answer this protocol
diff --git a/qualtran/_infra/binst_graph_iterators.py b/qualtran/_infra/binst_graph_iterators.py
index d22ebbcc5a..51105dc6e5 100644
--- a/qualtran/_infra/binst_graph_iterators.py
+++ b/qualtran/_infra/binst_graph_iterators.py
@@ -12,7 +12,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-from typing import Iterator, TYPE_CHECKING
+from collections.abc import Iterator
+from typing import TYPE_CHECKING
import networkx as nx
diff --git a/qualtran/_infra/bloq.py b/qualtran/_infra/bloq.py
index 8572718445..47ddb35b9f 100644
--- a/qualtran/_infra/bloq.py
+++ b/qualtran/_infra/bloq.py
@@ -16,18 +16,8 @@
"""Contains the main interface for defining `Bloq`s."""
import abc
-from typing import (
- Callable,
- Dict,
- List,
- Mapping,
- Optional,
- Sequence,
- Set,
- Tuple,
- TYPE_CHECKING,
- Union,
-)
+from collections.abc import Callable, Mapping, Sequence
+from typing import Optional, TYPE_CHECKING, Union
if TYPE_CHECKING:
import cirq
@@ -129,7 +119,7 @@ def signature(self) -> 'Signature':
about this bloq.
"""
- def build_composite_bloq(self, bb: 'BloqBuilder', **soqs: 'SoquetT') -> Dict[str, 'SoquetT']:
+ def build_composite_bloq(self, bb: 'BloqBuilder', **soqs: 'SoquetT') -> dict[str, 'SoquetT']:
"""Override this method to define a Bloq in terms of its constituent parts.
Bloq authors should override this method. If you already have an instance of a `Bloq`,
@@ -241,7 +231,7 @@ def basis_state_phase(self, **vals: 'ClassicalValT') -> Union[complex, None]:
def call_classically(
self, **vals: Union['sympy.Symbol', 'ClassicalValT']
- ) -> Tuple['ClassicalValT', ...]:
+ ) -> tuple['ClassicalValT', ...]:
"""Call this bloq on classical data.
Bloq users can call this function to apply bloqs to classical data. If you're
@@ -300,8 +290,8 @@ def tensor_contract(self, superoperator: bool = False) -> 'NDArray':
return bloq_to_dense(self, superoperator=superoperator)
def my_tensors(
- self, incoming: Dict[str, 'ConnectionT'], outgoing: Dict[str, 'ConnectionT']
- ) -> List[Union['qtn.Tensor', 'DiscardInd']]:
+ self, incoming: dict[str, 'ConnectionT'], outgoing: dict[str, 'ConnectionT']
+ ) -> list[Union['qtn.Tensor', 'DiscardInd']]:
"""Override this method to support native quimb simulation of this Bloq.
This method is responsible for returning tensors corresponding to the unitary, state, or
@@ -335,7 +325,7 @@ def my_tensors(
def build_call_graph(
self, ssa: 'SympySymbolAllocator'
- ) -> Union['BloqCountDictT', Set['BloqCountT']]:
+ ) -> Union['BloqCountDictT', set['BloqCountT']]:
"""Override this method to build the bloq call graph.
This method must return a set of `(bloq, n)` tuples where `bloq` is called `n` times in
@@ -371,7 +361,7 @@ def call_graph(
generalizer: Optional[Union['GeneralizerT', Sequence['GeneralizerT']]] = None,
keep: Optional[Callable[['Bloq'], bool]] = None,
max_depth: Optional[int] = None,
- ) -> Tuple['nx.DiGraph', Dict['Bloq', Union[int, 'sympy.Expr']]]:
+ ) -> tuple['nx.DiGraph', dict['Bloq', Union[int, 'sympy.Expr']]]:
"""Get the bloq call graph and call totals.
The call graph has edges from a parent bloq to each of the bloqs that it calls in
@@ -400,7 +390,7 @@ def call_graph(
def bloq_counts(
self, generalizer: Optional[Union['GeneralizerT', Sequence['GeneralizerT']]] = None
- ) -> Dict['Bloq', Union[int, 'sympy.Expr']]:
+ ) -> dict['Bloq', Union[int, 'sympy.Expr']]:
"""The number of subbloqs directly called by this bloq.
This corresponds to one level of the call graph, see `Bloq.call_graph()`.
@@ -420,7 +410,7 @@ def bloq_counts(
return dict(get_bloq_callee_counts(self, generalizer=generalizer))
- def get_ctrl_system(self, ctrl_spec: 'CtrlSpec') -> Tuple['Bloq', 'AddControlledT']:
+ def get_ctrl_system(self, ctrl_spec: 'CtrlSpec') -> tuple['Bloq', 'AddControlledT']:
"""Get a controlled version of this bloq and a function to wire it up correctly.
Users should likely call `Bloq.controlled(...)` which uses this method behind-the-scenes.
@@ -441,8 +431,8 @@ def get_ctrl_system(self, ctrl_spec: 'CtrlSpec') -> Tuple['Bloq', 'AddControlled
It must have the following signature:
def _my_add_controlled(
- bb: 'BloqBuilder', ctrl_soqs: Sequence['SoquetT'], in_soqs: Dict[str, 'SoquetT']
- ) -> Tuple[Iterable['SoquetT'], Iterable['SoquetT']]:
+ bb: 'BloqBuilder', ctrl_soqs: Sequence['SoquetT'], in_soqs: dict[str, 'SoquetT']
+ ) -> tuple[Iterable['SoquetT'], Iterable['SoquetT']]:
Which takes a bloq builder (for adding the controlled bloq), the new control soquets,
input soquets for the existing registers; and returns a sequence of the output control
@@ -494,7 +484,7 @@ def t_complexity(self) -> 'TComplexity':
def as_cirq_op(
self, qubit_manager: 'cirq.QubitManager', **cirq_quregs: 'CirqQuregT'
- ) -> Tuple[Union['cirq.Operation', None], Dict[str, 'CirqQuregT']]:
+ ) -> tuple[Union['cirq.Operation', None], dict[str, 'CirqQuregT']]:
"""Override this method to support conversion to a Cirq operation.
If this method is not overriden, the default implementation will wrap this bloq
@@ -591,7 +581,7 @@ def on_registers(
return self.on(*merge_qubits(self.signature, **qubit_regs))
def wire_symbol(
- self, reg: Optional['Register'], idx: Tuple[int, ...] = tuple()
+ self, reg: Optional['Register'], idx: tuple[int, ...] = tuple()
) -> 'WireSymbol':
"""On a musical score visualization, use this `WireSymbol` to represent `soq`.
diff --git a/qualtran/_infra/bloq_example.py b/qualtran/_infra/bloq_example.py
index 18abbba75b..143c7e9266 100644
--- a/qualtran/_infra/bloq_example.py
+++ b/qualtran/_infra/bloq_example.py
@@ -11,8 +11,9 @@
# 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.
-import typing
-from typing import Any, Callable, Generic, Iterable, Optional, Sequence, Type, TypeVar, Union
+
+from collections.abc import Callable, Iterable, Sequence
+from typing import Any, Generic, Optional, overload, TypeVar, Union
from attrs import field, frozen
@@ -44,7 +45,7 @@ class BloqExample(Generic[_BloqType]):
_func: Callable[[], _BloqType] = field(repr=False, hash=False)
name: str
- bloq_cls: Type[Bloq]
+ bloq_cls: type[Bloq]
generalizer: _GeneralizerType = field(
converter=lambda x: tuple(x) if isinstance(x, Sequence) else x, default=lambda x: x
)
@@ -68,7 +69,7 @@ def _name_from_func_name(func: Callable[[], _BloqType]) -> str:
return func.__name__.lstrip('_')
-def _bloq_cls_from_func_annotation(func: Callable[[], _BloqType]) -> Type[_BloqType]:
+def _bloq_cls_from_func_annotation(func: Callable[[], _BloqType]) -> type[_BloqType]:
"""Use the function return type annotation as the `BloqExample.bloq_cls` with the decorator."""
anno = func.__annotations__
if 'return' not in anno:
@@ -79,11 +80,11 @@ def _bloq_cls_from_func_annotation(func: Callable[[], _BloqType]) -> Type[_BloqT
return cls
-@typing.overload
+@overload
def bloq_example(_func: Callable[[], _BloqType], **kwargs: Any) -> BloqExample[_BloqType]: ...
-@typing.overload
+@overload
def bloq_example(
_func: None = None, *, generalizer: _GeneralizerType = lambda x: x
) -> Callable[[Callable[[], _BloqType]], BloqExample[_BloqType]]: ...
@@ -147,7 +148,7 @@ class BloqDocSpec:
graph. Note that this example must be included in `examples`.
"""
- bloq_cls: Type
+ bloq_cls: type
examples: Sequence[BloqExample] = field(converter=_to_tuple, factory=tuple)
import_line: str = field()
call_graph_example: Union[BloqExample, None] = field()
diff --git a/qualtran/_infra/composite_bloq.py b/qualtran/_infra/composite_bloq.py
index 9832b9ffaa..fd5e59dc94 100644
--- a/qualtran/_infra/composite_bloq.py
+++ b/qualtran/_infra/composite_bloq.py
@@ -13,26 +13,9 @@
# limitations under the License.
"""Classes for building and manipulating `CompositeBloq`."""
-from collections.abc import Hashable
+from collections.abc import Callable, Hashable, Iterable, Iterator, Mapping, Sequence
from functools import cached_property
-from typing import (
- Callable,
- cast,
- Dict,
- FrozenSet,
- Iterable,
- Iterator,
- List,
- Mapping,
- Optional,
- overload,
- Sequence,
- Set,
- Tuple,
- TYPE_CHECKING,
- TypeVar,
- Union,
-)
+from typing import cast, FrozenSet, Optional, overload, TYPE_CHECKING, TypeVar, Union
import attrs
import networkx as nx
@@ -106,7 +89,7 @@ class CompositeBloq(Bloq):
should correspond to the dangling `Soquets` in the `cxns`.
"""
- connections: Tuple[Connection, ...] = attrs.field(converter=_to_tuple)
+ connections: tuple[Connection, ...] = attrs.field(converter=_to_tuple)
signature: Signature
bloq_instances: FrozenSet[BloqInstance] = attrs.field(converter=_to_set)
@@ -142,7 +125,7 @@ def _binst_graph(self) -> nx.DiGraph:
def as_cirq_op(
self, qubit_manager: 'cirq.QubitManager', **cirq_quregs: 'CirqQuregT'
- ) -> Tuple['cirq.Operation', Dict[str, 'CirqQuregT']]:
+ ) -> tuple['cirq.Operation', dict[str, 'CirqQuregT']]:
"""Return a cirq.CircuitOperation containing a cirq-exported version of this cbloq."""
import cirq
@@ -153,7 +136,7 @@ def as_cirq_op(
def to_cirq_circuit_and_quregs(
self, qubit_manager: Optional['cirq.QubitManager'] = None, **cirq_quregs
- ) -> Tuple['cirq.FrozenCircuit', Dict[str, 'CirqQuregT']]:
+ ) -> tuple['cirq.FrozenCircuit', dict[str, 'CirqQuregT']]:
"""Convert this CompositeBloq to a `cirq.Circuit` and output qubit registers.
Args:
@@ -214,14 +197,14 @@ def from_cirq_circuit(cls, circuit: 'cirq.Circuit') -> 'CompositeBloq':
def on_classical_vals(
self, **vals: Union[sympy.Symbol, 'ClassicalValT']
- ) -> Dict[str, 'ClassicalValT']:
+ ) -> dict[str, 'ClassicalValT']:
"""Support classical data by recursing into the composite bloq."""
from qualtran.simulation.classical_sim import call_cbloq_classically
out_vals, _ = call_cbloq_classically(self.signature, vals, self._binst_graph)
return out_vals
- def call_classically(self, **vals: 'ClassicalValT') -> Tuple['ClassicalValT', ...]:
+ def call_classically(self, **vals: 'ClassicalValT') -> tuple['ClassicalValT', ...]:
"""Support classical data by recursing into the composite bloq."""
from qualtran.simulation.classical_sim import call_cbloq_classically
@@ -246,7 +229,7 @@ def build_call_graph(self, ssa: Optional['SympySymbolAllocator']) -> 'BloqCountD
def iter_bloqnections(
self,
- ) -> Iterator[Tuple[BloqInstance, List[Connection], List[Connection]]]:
+ ) -> Iterator[tuple[BloqInstance, list[Connection], list[Connection]]]:
"""Iterate over Bloqs and their connections in topological order.
Yields:
@@ -267,7 +250,7 @@ def iter_bloqnections(
def iter_bloqsoqs(
self,
- ) -> Iterator[Tuple[BloqInstance, Dict[str, SoquetT], Tuple[SoquetT, ...]]]:
+ ) -> Iterator[tuple[BloqInstance, dict[str, SoquetT], tuple[SoquetT, ...]]]:
"""Iterate over bloq instances and their input soquets.
This method is helpful for "adding from" this existing composite bloq. You must
@@ -275,7 +258,7 @@ def iter_bloqsoqs(
new bloq.
>>> bb, _ = BloqBuilder.from_signature(self.signature)
- >>> soq_map: List[Tuple[SoquetT, SoquetT]] = []
+ >>> soq_map: list[tuple[SoquetT, SoquetT]] = []
>>> for binst, in_soqs, old_out_soqs in self.iter_bloqsoqs():
>>> in_soqs = bb.map_soqs(in_soqs, soq_map)
>>> new_out_soqs = bb.add_t(binst.bloq, **in_soqs)
@@ -300,7 +283,7 @@ def iter_bloqsoqs(
out_soqs = tuple(_reg_to_soq(binst, reg) for reg in binst.bloq.signature.rights())
yield binst, in_soqs, out_soqs
- def final_soqs(self) -> Dict[str, SoquetT]:
+ def final_soqs(self) -> dict[str, SoquetT]:
"""Return the final output soquets.
This method is helpful for finalizing an "add from" operation, see `iter_bloqsoqs`.
@@ -318,7 +301,7 @@ def final_soqs(self) -> Dict[str, SoquetT]:
def copy(self) -> 'CompositeBloq':
"""Create a copy of this composite bloq by re-building it."""
bb, _ = BloqBuilder.from_signature(self.signature)
- soq_map: List[Tuple[SoquetT, SoquetT]] = []
+ soq_map: list[tuple[SoquetT, SoquetT]] = []
for binst, in_soqs, old_out_soqs in self.iter_bloqsoqs():
in_soqs = _map_soqs(in_soqs, soq_map)
new_out_soqs = bb.add_t(binst.bloq, **in_soqs)
@@ -364,8 +347,8 @@ def flatten_once(
# pylint: disable=protected-access
bb._i = max(binst.i for binst in self.bloq_instances) + 1
- soq_map: List[Tuple[SoquetT, SoquetT]] = []
- new_out_soqs: Tuple[SoquetT, ...]
+ soq_map: list[tuple[SoquetT, SoquetT]] = []
+ new_out_soqs: tuple[SoquetT, ...]
did_work = False
for binst, in_soqs, old_out_soqs in self.iter_bloqsoqs():
in_soqs = _map_soqs(in_soqs, soq_map) # update `in_soqs` from old to new.
@@ -432,7 +415,7 @@ def adjoint(self) -> 'CompositeBloq':
return _adjoint_cbloq(self)
@staticmethod
- def _debug_binst(g: nx.DiGraph, binst: BloqInstance) -> List[str]:
+ def _debug_binst(g: nx.DiGraph, binst: BloqInstance) -> list[str]:
"""Helper method used in `debug_text`"""
lines = [f'{binst}']
pred_cxns, succ_cxns = _binst_to_cxns(binst, binst_graph=g)
@@ -499,13 +482,13 @@ def _create_binst_graph(
def _binst_to_cxns(
binst: Union[BloqInstance, DanglingT], binst_graph: nx.DiGraph
-) -> Tuple[List[Connection], List[Connection]]:
+) -> tuple[list[Connection], list[Connection]]:
"""Helper method to extract all predecessor and successor Connections for a binst."""
- pred_cxns: List[Connection] = []
+ pred_cxns: list[Connection] = []
for pred in binst_graph.pred[binst]:
pred_cxns.extend(binst_graph.edges[pred, binst]['cxns'])
- succ_cxns: List[Connection] = []
+ succ_cxns: list[Connection] = []
for succ in binst_graph.succ[binst]:
succ_cxns.extend(binst_graph.edges[binst, succ]['cxns'])
@@ -517,7 +500,7 @@ def _cxns_to_soq_dict(
cxns: Iterable[Connection],
get_me: Callable[[Connection], Soquet],
get_assign: Callable[[Connection], Soquet],
-) -> Dict[str, SoquetT]:
+) -> dict[str, SoquetT]:
"""Helper function to get a dictionary of soquets from a list of connections.
Args:
@@ -534,7 +517,7 @@ def _cxns_to_soq_dict(
Returns:
soqdict: A dictionary mapping register name to the selected soquets.
"""
- soqdict: Dict[str, SoquetT] = {}
+ soqdict: dict[str, SoquetT] = {}
# Initialize multi-dimensional dictionary values.
for reg in regs:
@@ -557,7 +540,7 @@ def _cxns_to_soq_dict(
def _cxns_to_cxn_dict(
regs: Iterable[Register], cxns: Iterable[Connection], get_me: Callable[[Connection], Soquet]
-) -> Dict[str, ConnectionT]:
+) -> dict[str, ConnectionT]:
"""Helper function to get a dictionary of connections from a list of connections
Args:
@@ -571,7 +554,7 @@ def _cxns_to_cxn_dict(
Returns:
cxndict: A dictionary mapping register name to the selected connections.
"""
- cxndict: Dict[str, ConnectionT] = {}
+ cxndict: dict[str, ConnectionT] = {}
# Initialize multi-dimensional dictionary values.
for reg in regs:
@@ -590,7 +573,7 @@ def _cxns_to_cxn_dict(
return cxndict
-def _get_dangling_soquets(signature: Signature, right: bool = True) -> Dict[str, SoquetT]:
+def _get_dangling_soquets(signature: Signature, right: bool = True) -> dict[str, SoquetT]:
"""Get instantiated dangling soquets from a `Signature`.
Args:
@@ -610,14 +593,14 @@ def _get_dangling_soquets(signature: Signature, right: bool = True) -> Dict[str,
regs = signature.lefts()
dang = LeftDangle
- all_soqs: Dict[str, SoquetT] = {}
+ all_soqs: dict[str, SoquetT] = {}
soqs: SoquetT
for reg in regs:
all_soqs[reg.name] = _reg_to_soq(dang, reg)
return all_soqs
-def _flatten_soquet_collection(vals: Iterable[SoquetT]) -> List[Soquet]:
+def _flatten_soquet_collection(vals: Iterable[SoquetT]) -> list[Soquet]:
"""Flatten SoquetT into a flat list of Soquet.
SoquetT is either a unit Soquet or an ndarray thereof.
@@ -631,7 +614,7 @@ def _flatten_soquet_collection(vals: Iterable[SoquetT]) -> List[Soquet]:
return soqvals
-def _get_flat_dangling_soqs(signature: Signature, right: bool) -> List[Soquet]:
+def _get_flat_dangling_soqs(signature: Signature, right: bool) -> list[Soquet]:
"""Flatten out the values of the soquet dictionaries from `_get_dangling_soquets`."""
soqdict = _get_dangling_soquets(signature, right=right)
return _flatten_soquet_collection(soqdict.values())
@@ -660,7 +643,7 @@ def add(self, x: Hashable):
def _reg_to_soq(
binst: Union[BloqInstance, DanglingT],
reg: Register,
- available: Union[Set[Soquet], _IgnoreAvailable] = _IgnoreAvailable(),
+ available: Union[set[Soquet], _IgnoreAvailable] = _IgnoreAvailable(),
) -> SoquetT:
"""Create the soquet or array of soquets for a register.
@@ -696,7 +679,7 @@ def _process_soquets(
registers: Iterable[Register],
in_soqs: Mapping[str, SoquetInT],
debug_str: str,
- func: Callable[[Soquet, Register, Tuple[int, ...]], None],
+ func: Callable[[Soquet, Register, tuple[int, ...]], None],
) -> None:
"""Process and validate `in_soqs` in the context of `registers`.
@@ -719,7 +702,7 @@ def _process_soquets(
the incoming, indexed soquet as well as the register and (left-)index it
has been mapped to.
"""
- unchecked_names: Set[str] = set(in_soqs.keys())
+ unchecked_names: set[str] = set(in_soqs.keys())
for reg in registers:
try:
# if we want fancy indexing (which we do), we need numpy
@@ -746,8 +729,8 @@ def _process_soquets(
def _map_soqs(
- soqs: Dict[str, SoquetT], soq_map: Iterable[Tuple[SoquetT, SoquetT]]
-) -> Dict[str, SoquetT]:
+ soqs: dict[str, SoquetT], soq_map: Iterable[tuple[SoquetT, SoquetT]]
+) -> dict[str, SoquetT]:
"""Map `soqs` according to `soq_map`.
See `CompositeBloq.iter_bloqsoqs` for example code. The public entry-point
@@ -765,7 +748,7 @@ def _map_soqs(
"""
# First: flatten out any numpy arrays
- flat_soq_map: Dict[Soquet, Soquet] = {}
+ flat_soq_map: dict[Soquet, Soquet] = {}
for old_soqs, new_soqs in soq_map:
if isinstance(old_soqs, Soquet):
assert isinstance(new_soqs, Soquet), new_soqs
@@ -818,15 +801,15 @@ class BloqBuilder:
def __init__(self, add_registers_allowed: bool = True):
# To be appended to:
- self._cxns: List[Connection] = []
- self._regs: List[Register] = []
- self._binsts: Set[BloqInstance] = set()
+ self._cxns: list[Connection] = []
+ self._regs: list[Register] = []
+ self._binsts: set[BloqInstance] = set()
# Initialize our BloqInstance counter
self._i = 0
# Bookkeeping for linear types; Soquets must be used exactly once.
- self._available: Set[Soquet] = set()
+ self._available: set[Soquet] = set()
# Whether we can call `add_register` and do non-strict `finalize()`.
self.add_register_allowed = add_registers_allowed
@@ -926,7 +909,7 @@ def add_register(
@classmethod
def from_signature(
cls, signature: Signature, add_registers_allowed: bool = False
- ) -> Tuple['BloqBuilder', Dict[str, SoquetT]]:
+ ) -> tuple['BloqBuilder', dict[str, SoquetT]]:
"""Construct a BloqBuilder with a pre-specified signature.
This is safer if e.g. you're decomposing an existing Bloq and need the signatures
@@ -935,7 +918,7 @@ def from_signature(
# Initial construction: allow register addition for the following loop.
bb = cls(add_registers_allowed=True)
- initial_soqs: Dict[str, SoquetT] = {}
+ initial_soqs: dict[str, SoquetT] = {}
for reg in signature:
if reg.side & Side.LEFT:
register = bb.add_register_from_dtype(reg)
@@ -951,8 +934,8 @@ def from_signature(
@staticmethod
def map_soqs(
- soqs: Dict[str, SoquetT], soq_map: Iterable[Tuple[SoquetT, SoquetT]]
- ) -> Dict[str, SoquetT]:
+ soqs: dict[str, SoquetT], soq_map: Iterable[tuple[SoquetT, SoquetT]]
+ ) -> dict[str, SoquetT]:
"""Map `soqs` according to `soq_map`.
See `CompositeBloq.iter_bloqsoqs` for example code.
@@ -979,7 +962,7 @@ def _add_cxn(
binst: Union[BloqInstance, DanglingT],
idxed_soq: Soquet,
reg: Register,
- idx: Tuple[int, ...],
+ idx: tuple[int, ...],
) -> None:
"""Helper function to be used as the base for the `func` argument of `_process_soquets`.
@@ -996,7 +979,7 @@ def _add_cxn(
cxn = Connection(idxed_soq, Soquet(binst, reg, idx))
self._cxns.append(cxn)
- def add_t(self, bloq: Bloq, **in_soqs: SoquetInT) -> Tuple[SoquetT, ...]:
+ def add_t(self, bloq: Bloq, **in_soqs: SoquetInT) -> tuple[SoquetT, ...]:
"""Add a new bloq instance to the compute graph and always return a tuple of soquets.
This method will always return a tuple of soquets. See `BloqBuilder.add_d(..)` for a
@@ -1018,7 +1001,7 @@ def add_t(self, bloq: Bloq, **in_soqs: SoquetInT) -> Tuple[SoquetT, ...]:
binst = BloqInstance(bloq, i=self._new_binst_i())
return tuple(soq for _, soq in self._add_binst(binst, in_soqs=in_soqs))
- def add_d(self, bloq: Bloq, **in_soqs: SoquetInT) -> Dict[str, SoquetT]:
+ def add_d(self, bloq: Bloq, **in_soqs: SoquetInT) -> dict[str, SoquetT]:
"""Add a new bloq instance to the compute graph and return new soquets as a dictionary.
This method returns a dictionary of soquets. See `BloqBuilder.add_t(..)` for a method
@@ -1040,7 +1023,7 @@ def add_d(self, bloq: Bloq, **in_soqs: SoquetInT) -> Dict[str, SoquetT]:
def add_and_partition(
self,
bloq: Bloq,
- partitions: Sequence[Tuple[Register, Sequence[Union[str, 'Unused']]]],
+ partitions: Sequence[tuple[Register, Sequence[Union[str, 'Unused']]]],
left_only: bool = False,
**in_soqs: SoquetInT,
):
@@ -1103,7 +1086,7 @@ def add(self, bloq: Bloq, **in_soqs: SoquetInT):
def _add_binst(
self, binst: BloqInstance, in_soqs: Mapping[str, SoquetInT]
- ) -> Iterator[Tuple[str, SoquetT]]:
+ ) -> Iterator[tuple[str, SoquetT]]:
"""Add a bloq instance.
Warning! Do not use this function externally! Untold bad things will happen if
@@ -1113,7 +1096,7 @@ def _add_binst(
bloq = binst.bloq
- def _add(idxed_soq: Soquet, reg: Register, idx: Tuple[int, ...]):
+ def _add(idxed_soq: Soquet, reg: Register, idx: tuple[int, ...]):
# close over `binst`
return self._add_cxn(binst, idxed_soq, reg, idx)
@@ -1125,7 +1108,7 @@ def _add(idxed_soq: Soquet, reg: Register, idx: Tuple[int, ...]):
for reg in bloq.signature.rights()
)
- def add_from(self, bloq: Bloq, **in_soqs: SoquetInT) -> Tuple[SoquetT, ...]:
+ def add_from(self, bloq: Bloq, **in_soqs: SoquetInT) -> tuple[SoquetT, ...]:
"""Add all the sub-bloqs from `bloq` to the composite bloq under construction.
Args:
@@ -1146,7 +1129,7 @@ def add_from(self, bloq: Bloq, **in_soqs: SoquetInT) -> Tuple[SoquetT, ...]:
in_soqs[k] = np.asarray(v)
# Initial mapping of LeftDangle according to user-provided in_soqs.
- soq_map: List[Tuple[SoquetT, SoquetT]] = [
+ soq_map: list[tuple[SoquetT, SoquetT]] = [
(_reg_to_soq(LeftDangle, reg), cast(SoquetT, in_soqs[reg.name]))
for reg in cbloq.signature.lefts()
]
@@ -1207,7 +1190,7 @@ def _finalize_strict(self, **final_soqs: SoquetT) -> CompositeBloq:
"""
signature = Signature(self._regs)
- def _fin(idxed_soq: Soquet, reg: Register, idx: Tuple[int, ...]):
+ def _fin(idxed_soq: Soquet, reg: Register, idx: tuple[int, ...]):
# close over `RightDangle`
return self._add_cxn(RightDangle, idxed_soq, reg, idx)
diff --git a/qualtran/_infra/composite_bloq_test.py b/qualtran/_infra/composite_bloq_test.py
index 114b55083f..98fbe59437 100644
--- a/qualtran/_infra/composite_bloq_test.py
+++ b/qualtran/_infra/composite_bloq_test.py
@@ -13,7 +13,6 @@
# limitations under the License.
from functools import cached_property
-from typing import Dict, List, Tuple
import attrs
import networkx as nx
@@ -75,7 +74,7 @@ def signature(self) -> Signature:
def build_composite_bloq(
self, bb: 'BloqBuilder', q1: 'Soquet', q2: 'Soquet'
- ) -> Dict[str, SoquetT]:
+ ) -> dict[str, SoquetT]:
q1, q2 = bb.add(CNOT(), ctrl=q1, target=q2)
q1, q2 = bb.add(CNOT(), ctrl=q2, target=q1)
return {'q1': q1, 'q2': q2}
@@ -138,7 +137,7 @@ def test_map_soqs():
bb, _ = BloqBuilder.from_signature(cbloq.signature)
bb._i = 100 # pylint: disable=protected-access
- soq_map: List[Tuple[SoquetT, SoquetT]] = []
+ soq_map: list[tuple[SoquetT, SoquetT]] = []
for binst, in_soqs, old_out_soqs in cbloq.iter_bloqsoqs():
if binst.i == 0:
assert in_soqs == bb.map_soqs(in_soqs, soq_map)
@@ -339,7 +338,7 @@ def signature(self) -> Signature:
def build_composite_bloq(
self, bb: 'BloqBuilder', control: 'Soquet', target: NDArray['Soquet'] # type: ignore[type-var]
- ) -> Dict[str, SoquetT]:
+ ) -> dict[str, SoquetT]:
for i in range(2):
for j in range(3):
control, target[i, j] = bb.add(CNOT(), ctrl=control, target=target[i, j])
diff --git a/qualtran/_infra/controlled.py b/qualtran/_infra/controlled.py
index 0e99500728..1711e8f28f 100644
--- a/qualtran/_infra/controlled.py
+++ b/qualtran/_infra/controlled.py
@@ -13,21 +13,9 @@
# limitations under the License.
import abc
from collections import Counter
+from collections.abc import Iterable, Mapping, Sequence
from functools import cached_property
-from typing import (
- Any,
- Dict,
- Iterable,
- List,
- Mapping,
- Optional,
- Protocol,
- Sequence,
- Tuple,
- TYPE_CHECKING,
- TypeAlias,
- Union,
-)
+from typing import Any, Optional, Protocol, TYPE_CHECKING, TypeAlias, Union
import attrs
import numpy as np
@@ -63,7 +51,7 @@ def _cvs_convert(
Sequence[Sequence[Union[int, np.integer]]],
Sequence[Union[NDArray[np.integer], Shaped]],
]
-) -> Tuple[Union[NDArray[np.integer], Shaped], ...]:
+) -> tuple[Union[NDArray[np.integer], Shaped], ...]:
if isinstance(cvs, Shaped):
return (cvs,)
if isinstance(cvs, (int, np.integer)):
@@ -118,10 +106,10 @@ class CtrlSpec:
of the ctrl register is implied to be `cv.shape`).
"""
- qdtypes: Tuple[QCDType, ...] = attrs.field(
+ qdtypes: tuple[QCDType, ...] = attrs.field(
default=QBit(), converter=lambda qt: (qt,) if isinstance(qt, QCDType) else tuple(qt)
)
- cvs: Tuple[Union[NDArray[np.integer], Shaped], ...] = attrs.field(
+ cvs: tuple[Union[NDArray[np.integer], Shaped], ...] = attrs.field(
default=1, converter=_cvs_convert
)
@@ -133,7 +121,7 @@ def num_ctrl_reg(self) -> int:
return len(self.qdtypes)
@cached_property
- def shapes(self) -> Tuple[Tuple[SymbolicInt, ...], ...]:
+ def shapes(self) -> tuple[tuple[SymbolicInt, ...], ...]:
"""Tuple of shapes of control registers represented by this CtrlSpec."""
return tuple(cv.shape for cv in self.cvs)
@@ -165,7 +153,7 @@ def num_cbits(self) -> SymbolicInt:
def is_symbolic(self):
return is_symbolic(*self.qdtypes) or is_symbolic(*self.cvs)
- def activation_function_dtypes(self) -> Sequence[Tuple[QCDType, Tuple[SymbolicInt, ...]]]:
+ def activation_function_dtypes(self) -> Sequence[tuple[QCDType, tuple[SymbolicInt, ...]]]:
"""The data types that serve as input to the 'activation function'.
The activation function takes in (quantum) inputs of these types and shapes and determines
@@ -209,7 +197,7 @@ def is_active(self, *vals: 'ClassicalValT') -> bool:
return False
return True
- def wire_symbol(self, i: int, reg: Register, idx: Tuple[int, ...] = tuple()) -> 'WireSymbol':
+ def wire_symbol(self, i: int, reg: Register, idx: tuple[int, ...] = tuple()) -> 'WireSymbol':
from qualtran.drawing import Circle, TextBox
cvs = self.cvs[i]
@@ -226,7 +214,7 @@ def wire_symbol(self, i: int, reg: Register, idx: Tuple[int, ...] = tuple()) ->
return TextBox(f'{cv}')
@cached_property
- def __cvs_tuple(self) -> Tuple[Union[tuple[int, ...], Shaped], ...]:
+ def __cvs_tuple(self) -> tuple[Union[tuple[int, ...], Shaped], ...]:
"""Serialize the control values for hashing and equality checking."""
def _serialize(cvs) -> Union[tuple[int, ...], Shaped]:
@@ -273,7 +261,7 @@ def from_cirq_cv(
cirq_cv: 'cirq.ops.AbstractControlValues',
*,
qdtypes: Optional[Sequence[QCDType]] = None,
- shapes: Optional[Sequence[Tuple[int, ...]]] = None,
+ shapes: Optional[Sequence[tuple[int, ...]]] = None,
) -> 'CtrlSpec':
"""Construct a CtrlSpec from cirq.SumOfProducts representation of control values."""
conjunctions = [*cirq_cv.expand()]
@@ -336,11 +324,11 @@ class AddControlledT(Protocol):
"""
def __call__(
- self, bb: 'BloqBuilder', ctrl_soqs: Sequence['SoquetT'], in_soqs: Dict[str, 'SoquetT']
- ) -> Tuple[Iterable['SoquetT'], Iterable['SoquetT']]: ...
+ self, bb: 'BloqBuilder', ctrl_soqs: Sequence['SoquetT'], in_soqs: dict[str, 'SoquetT']
+ ) -> tuple[Iterable['SoquetT'], Iterable['SoquetT']]: ...
-def _get_nice_ctrl_reg_names(reg_names: List[str], n: int) -> Tuple[str, ...]:
+def _get_nice_ctrl_reg_names(reg_names: list[str], n: int) -> tuple[str, ...]:
"""Get `n` names for the ctrl registers that don't overlap with (existing) `reg_names`."""
if n == 1 and 'ctrl' not in reg_names:
# Special case for nicer register name if we just have one control register
@@ -351,7 +339,7 @@ def _get_nice_ctrl_reg_names(reg_names: List[str], n: int) -> Tuple[str, ...]:
i = 1
else:
i = 0
- names: List[str] = []
+ names: list[str] = []
while len(names) < n:
while True:
i += 1
@@ -386,7 +374,7 @@ def _thru_registers_only(self) -> bool:
return True
@staticmethod
- def _make_ctrl_system(cb: '_ControlledBase') -> Tuple['_ControlledBase', 'AddControlledT']:
+ def _make_ctrl_system(cb: '_ControlledBase') -> tuple['_ControlledBase', 'AddControlledT']:
"""A static method to create the adder function from an implementation of this class.
Classes implementing this interface can use this static method to create a factory
@@ -397,8 +385,8 @@ class method to construct both the controlled bloq and its adder function.
ctrl_reg_names = cb.ctrl_reg_names
def add_controlled(
- bb: 'BloqBuilder', ctrl_soqs: Sequence['SoquetT'], in_soqs: Dict[str, 'SoquetT']
- ) -> Tuple[Iterable['SoquetT'], Iterable['SoquetT']]:
+ bb: 'BloqBuilder', ctrl_soqs: Sequence['SoquetT'], in_soqs: dict[str, 'SoquetT']
+ ) -> tuple[Iterable['SoquetT'], Iterable['SoquetT']]:
in_soqs |= dict(zip(ctrl_reg_names, ctrl_soqs))
new_out_d = bb.add_d(cb, **in_soqs)
@@ -421,7 +409,7 @@ def ctrl_reg_names(self) -> Sequence[str]:
return _get_nice_ctrl_reg_names(reg_names, n)
@cached_property
- def ctrl_regs(self) -> Tuple[Register, ...]:
+ def ctrl_regs(self) -> tuple[Register, ...]:
return tuple(
Register(name=self.ctrl_reg_names[i], dtype=qdtype, shape=shape, side=Side.THRU)
for i, (qdtype, shape) in enumerate(self.ctrl_spec.activation_function_dtypes())
@@ -517,8 +505,8 @@ def _unitary_(self):
raise ValueError(f"Cannot handle non-thru registers in {self}.")
def my_tensors(
- self, incoming: Dict[str, 'ConnectionT'], outgoing: Dict[str, 'ConnectionT']
- ) -> List['qtn.Tensor']:
+ self, incoming: dict[str, 'ConnectionT'], outgoing: dict[str, 'ConnectionT']
+ ) -> list['qtn.Tensor']:
import quimb.tensor as qtn
from qualtran.simulation.tensor._dense import _order_incoming_outgoing_indices
@@ -529,7 +517,7 @@ def my_tensors(
data = self._tensor_data().reshape((2,) * len(inds))
return [qtn.Tensor(data=data, inds=inds, tags=[str(self)])]
- def wire_symbol(self, reg: Optional[Register], idx: Tuple[int, ...] = tuple()) -> 'WireSymbol':
+ def wire_symbol(self, reg: Optional[Register], idx: tuple[int, ...] = tuple()) -> 'WireSymbol':
from qualtran.drawing import Text
if reg is None:
@@ -549,7 +537,7 @@ def __str__(self) -> str:
def as_cirq_op(
self, qubit_manager: 'cirq.QubitManager', **cirq_quregs: 'CirqQuregT'
- ) -> Tuple[Union['cirq.Operation', None], Dict[str, 'CirqQuregT']]:
+ ) -> tuple[Union['cirq.Operation', None], dict[str, 'CirqQuregT']]:
ctrl_regs = {reg_name: cirq_quregs.pop(reg_name) for reg_name in self.ctrl_reg_names}
ctrl_qubits = [q for reg in ctrl_regs.values() for q in reg.reshape(-1)]
sub_op, cirq_quregs = self.subbloq.as_cirq_op(qubit_manager, **cirq_quregs)
@@ -611,7 +599,7 @@ def __attrs_post_init__(self):
@classmethod
def make_ctrl_system(
cls, bloq: 'Bloq', ctrl_spec: 'CtrlSpec'
- ) -> Tuple['_ControlledBase', 'AddControlledT']:
+ ) -> tuple['_ControlledBase', 'AddControlledT']:
"""A factory method for creating both the Controlled and the adder function.
See `Bloq.get_ctrl_system`.
@@ -624,7 +612,7 @@ def decompose_bloq(self) -> 'CompositeBloq':
def build_composite_bloq(
self, bb: 'BloqBuilder', **initial_soqs: 'SoquetT'
- ) -> Dict[str, 'SoquetT']:
+ ) -> dict[str, 'SoquetT']:
if not self._thru_registers_only:
raise DecomposeTypeError(f"Cannot handle non-thru registers in {self.subbloq}")
@@ -636,9 +624,9 @@ def build_composite_bloq(
else:
cbloq = self.subbloq.decompose_bloq()
- ctrl_soqs: List['SoquetT'] = [initial_soqs[creg_name] for creg_name in self.ctrl_reg_names]
+ ctrl_soqs: list['SoquetT'] = [initial_soqs[creg_name] for creg_name in self.ctrl_reg_names]
- soq_map: List[Tuple[SoquetT, SoquetT]] = []
+ soq_map: list[tuple[SoquetT, SoquetT]] = []
for binst, in_soqs, old_out_soqs in cbloq.iter_bloqsoqs():
in_soqs = bb.map_soqs(in_soqs, soq_map)
new_bloq, adder = binst.bloq.get_ctrl_system(self.ctrl_spec)
@@ -676,7 +664,7 @@ def adjoint(self) -> 'Bloq':
def make_ctrl_system_with_correct_metabloq(
bloq: 'Bloq', ctrl_spec: 'CtrlSpec'
-) -> Tuple['_ControlledBase', 'AddControlledT']:
+) -> tuple['_ControlledBase', 'AddControlledT']:
"""The default fallback for `Bloq.make_ctrl_system.
This intelligently selects the correct implemetation of `_ControlledBase` based
diff --git a/qualtran/_infra/controlled_test.py b/qualtran/_infra/controlled_test.py
index 0a909d79ef..e9bb43b0b4 100644
--- a/qualtran/_infra/controlled_test.py
+++ b/qualtran/_infra/controlled_test.py
@@ -11,7 +11,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.
-from typing import List, TYPE_CHECKING
+from typing import TYPE_CHECKING
import numpy as np
import pytest
@@ -317,7 +317,7 @@ def test_bit_vector_ctrl():
bloq = Controlled(subbloq=TestAtom(), ctrl_spec=CtrlSpec(QBit(), cvs=(1, 0, 1)))
msd = get_musical_score_data(bloq)
# select SoqData for the 0th moment, sorted top to bottom
- soqdatas: List[SoqData] = sorted(
+ soqdatas: list[SoqData] = sorted(
(sd for sd in msd.soqs if sd.rpos.seq_x == 0), key=lambda sd: sd.rpos.y
)
diff --git a/qualtran/_infra/data_types.py b/qualtran/_infra/data_types.py
index 1b12cd1371..01e97167f8 100644
--- a/qualtran/_infra/data_types.py
+++ b/qualtran/_infra/data_types.py
@@ -15,9 +15,10 @@
import abc
+from collections.abc import Iterable, Sequence
from enum import Enum
from functools import cached_property
-from typing import Any, Iterable, List, Optional, Sequence, Union
+from typing import Any, Optional, Union
import attrs
import galois
@@ -51,7 +52,7 @@ def get_classical_domain(self) -> Iterable[Any]:
by this type."""
@abc.abstractmethod
- def to_bits(self, x) -> List[int]:
+ def to_bits(self, x) -> list[int]:
"""Yields individual bits corresponding to binary representation of x"""
def to_bits_array(self, x_array: NDArray[Any]) -> NDArray[np.uint8]:
@@ -165,7 +166,7 @@ def assert_valid_classical_val(self, val: int, debug_str: str = 'val'):
def is_symbolic(self) -> bool:
return False
- def to_bits(self, x) -> List[int]:
+ def to_bits(self, x) -> list[int]:
"""Yields individual bits corresponding to binary representation of x"""
self.assert_valid_classical_val(x)
return [int(x)]
@@ -223,7 +224,7 @@ def num_qubits(self):
def get_classical_domain(self) -> Iterable[Any]:
raise TypeError(f"Ambiguous domain for {self}. Please use a more specific type.")
- def to_bits(self, x) -> List[int]:
+ def to_bits(self, x) -> list[int]:
# TODO: Raise an error once usage of `QAny` is minimized across the library
return QUInt(self.bitsize).to_bits(x)
@@ -267,7 +268,7 @@ def get_classical_domain(self) -> Iterable[int]:
max_val = 1 << (self.bitsize - 1)
return range(-max_val, max_val)
- def to_bits(self, x: int) -> List[int]:
+ def to_bits(self, x: int) -> list[int]:
"""Yields individual bits corresponding to binary representation of x"""
if is_symbolic(self.bitsize):
raise ValueError(f"cannot compute bits with symbolic {self.bitsize=}")
@@ -333,7 +334,7 @@ def num_qubits(self):
def is_symbolic(self) -> bool:
return is_symbolic(self.bitsize)
- def to_bits(self, x: int) -> List[int]:
+ def to_bits(self, x: int) -> list[int]:
"""Yields individual bits corresponding to binary representation of x"""
self.assert_valid_classical_val(x)
return [int(x < 0)] + [y ^ int(x < 0) for y in QUInt(self.bitsize - 1).to_bits(abs(x))]
@@ -383,7 +384,7 @@ def is_symbolic(self) -> bool:
def get_classical_domain(self) -> Iterable[Any]:
return range(2**self.bitsize)
- def to_bits(self, x: int) -> List[int]:
+ def to_bits(self, x: int) -> list[int]:
"""Yields individual bits corresponding to binary representation of x"""
self.assert_valid_classical_val(x)
return [int(x) for x in f'{int(x):0{self.bitsize}b}']
@@ -536,7 +537,7 @@ def assert_valid_classical_val(self, val: int, debug_str: str = 'val'):
if val >= self.iteration_length:
raise ValueError(f"Too-large classical value encountered in {debug_str}")
- def to_bits(self, x: int) -> List[int]:
+ def to_bits(self, x: int) -> list[int]:
"""Yields individual bits corresponding to binary representation of x"""
self.assert_valid_classical_val(x, debug_str='val')
return QUInt(self.bitsize).to_bits(x)
@@ -640,7 +641,7 @@ def get_classical_domain(self) -> Iterable[int]:
"""
yield from self._int_qdtype.get_classical_domain()
- def to_bits(self, x) -> List[int]:
+ def to_bits(self, x) -> list[int]:
"""Use the underlying raw integer type.
See class docstring section on "Classical Simulation" for more details.
@@ -750,7 +751,7 @@ def _get_classical_domain_fxp(self) -> Iterable[Fxp]:
def _fxp_to_bits(
self, x: Union[float, Fxp], require_exact: bool = True, complement: bool = True
- ) -> List[int]:
+ ) -> list[int]:
"""Yields individual bits corresponding to binary representation of `x`.
Args:
@@ -837,7 +838,7 @@ def get_classical_domain(self) -> Iterable[Any]:
return range(2**self.bitsize)
return range(1, int(self.modulus))
- def to_bits(self, x: int) -> List[int]:
+ def to_bits(self, x: int) -> list[int]:
self.assert_valid_classical_val(x)
return [int(x) for x in f'{int(x):0{self.bitsize}b}']
@@ -997,7 +998,7 @@ def gf_type(self):
compile='python-calculate',
)
- def to_bits(self, x) -> List[int]:
+ def to_bits(self, x) -> list[int]:
"""Returns individual bits corresponding to binary representation of x"""
self.assert_valid_classical_val(x)
return self._quint_equivalent.to_bits(int(x))
@@ -1117,7 +1118,7 @@ def from_gf_coefficients(self, f_x: galois.Array) -> galois.Poly:
"""Expects a big-endian array of coefficients that represent a polynomial f(x)."""
return galois.Poly(f_x, field=self.qgf.gf_type)
- def to_bits(self, x) -> List[int]:
+ def to_bits(self, x) -> list[int]:
"""Returns individual bits corresponding to binary representation of x"""
self.assert_valid_classical_val(x)
assert isinstance(x, galois.Poly)
diff --git a/qualtran/_infra/data_types_test.py b/qualtran/_infra/data_types_test.py
index 577ab9a524..f3be9e0c39 100644
--- a/qualtran/_infra/data_types_test.py
+++ b/qualtran/_infra/data_types_test.py
@@ -13,7 +13,8 @@
# limitations under the License.
import math
import random
-from typing import Any, Sequence, Union
+from collections.abc import Sequence
+from typing import Any, Union
import galois
import numpy as np
diff --git a/qualtran/_infra/gate_with_registers.py b/qualtran/_infra/gate_with_registers.py
index 99026c66a1..a1c7da50d4 100644
--- a/qualtran/_infra/gate_with_registers.py
+++ b/qualtran/_infra/gate_with_registers.py
@@ -13,19 +13,8 @@
# limitations under the License.
import abc
-from typing import (
- cast,
- Collection,
- Dict,
- Iterable,
- List,
- Optional,
- overload,
- Sequence,
- Tuple,
- TYPE_CHECKING,
- Union,
-)
+from collections.abc import Collection, Iterable, Sequence
+from typing import cast, Optional, overload, TYPE_CHECKING, Union
import cirq
import numpy as np
@@ -50,7 +39,7 @@ def total_bits(registers: Iterable[Register]) -> int:
def split_qubits(
registers: Iterable[Register], qubits: Sequence['cirq.Qid']
-) -> Dict[str, NDArray['cirq.Qid']]: # type: ignore[type-var]
+) -> dict[str, NDArray['cirq.Qid']]: # type: ignore[type-var]
"""Splits the flat list of qubits into a dictionary of appropriately shaped qubit arrays."""
qubit_regs = {}
@@ -66,10 +55,10 @@ def split_qubits(
def merge_qubits(
registers: Iterable[Register],
**qubit_regs: Union['cirq.Qid', Sequence['cirq.Qid'], NDArray['cirq.Qid']],
-) -> List['cirq.Qid']:
+) -> list['cirq.Qid']:
"""Merges the dictionary of appropriately shaped qubit arrays into a flat list of qubits."""
- ret: List['cirq.Qid'] = []
+ ret: list['cirq.Qid'] = []
for reg in registers:
if reg.name not in qubit_regs:
raise ValueError(f"All qubit registers must be present. {reg.name} not in qubit_regs")
@@ -84,7 +73,7 @@ def merge_qubits(
return ret
-def get_named_qubits(registers: Iterable[Register]) -> Dict[str, NDArray['cirq.Qid']]:
+def get_named_qubits(registers: Iterable[Register]) -> dict[str, NDArray['cirq.Qid']]:
"""Returns a dictionary of appropriately shaped named qubit signature for input `signature`."""
def _qubit_array(reg: Register):
@@ -115,8 +104,8 @@ def _qubits_for_reg(reg: Register):
def _get_all_and_output_quregs_from_input(
registers: Iterable[Register],
qubit_manager: 'cirq.QubitManager',
- in_quregs: Dict[str, 'CirqQuregT'],
-) -> Tuple[Dict[str, 'CirqQuregT'], Dict[str, 'CirqQuregT']]:
+ in_quregs: dict[str, 'CirqQuregT'],
+) -> tuple[dict[str, 'CirqQuregT'], dict[str, 'CirqQuregT']]:
"""Takes care of necessary (de-/)allocations to obtain output & all qubit registers from input.
For every register `reg` in `registers`, this method checks:
@@ -141,8 +130,8 @@ def _get_all_and_output_quregs_from_input(
Returns:
A tuple of `(all_quregs, out_quregs)`
"""
- all_quregs: Dict[str, 'CirqQuregT'] = {}
- out_quregs: Dict[str, 'CirqQuregT'] = {}
+ all_quregs: dict[str, 'CirqQuregT'] = {}
+ out_quregs: dict[str, 'CirqQuregT'] = {}
for reg in registers:
full_shape = reg.shape + (reg.bitsize,)
if reg.side & Side.LEFT:
@@ -170,7 +159,7 @@ def _get_all_and_output_quregs_from_input(
def _get_cirq_cv(
num_controls: Optional[int] = None,
control_values=None,
- control_qid_shape: Optional[Tuple[int, ...]] = None,
+ control_qid_shape: Optional[tuple[int, ...]] = None,
) -> 'cirq.ops.AbstractControlValues':
"""Logic copied from `cirq.ControlledGate` to help convert cirq-style spec to `CtrlSpec`"""
if isinstance(control_values, cirq.SumOfProducts) and len(control_values._conjunctions) == 1:
@@ -294,7 +283,7 @@ def decompose_bloq(self) -> 'CompositeBloq':
def as_cirq_op(
self, qubit_manager: 'cirq.QubitManager', **in_quregs: 'CirqQuregT'
- ) -> Tuple[Union['cirq.Operation', None], Dict[str, 'CirqQuregT']]:
+ ) -> tuple[Union['cirq.Operation', None], dict[str, 'CirqQuregT']]:
"""Allocates/Deallocates qubits for RIGHT/LEFT only registers to construct a Cirq operation
Args:
@@ -310,7 +299,7 @@ def as_cirq_op(
)
return self.on_registers(**all_quregs), out_quregs
- def wire_symbol(self, reg: Optional[Register], idx: Tuple[int, ...] = tuple()) -> 'WireSymbol':
+ def wire_symbol(self, reg: Optional[Register], idx: tuple[int, ...] = tuple()) -> 'WireSymbol':
from qualtran.cirq_interop._cirq_to_bloq import _wire_symbol_from_gate
from qualtran.drawing import Text
@@ -378,7 +367,7 @@ def _get_ctrl_spec(
cls,
num_controls: Union[Optional[int], 'CtrlSpec'] = None,
control_values=None,
- control_qid_shape: Optional[Tuple[int, ...]] = None,
+ control_qid_shape: Optional[tuple[int, ...]] = None,
*,
ctrl_spec: Optional['CtrlSpec'] = None,
) -> 'CtrlSpec':
@@ -443,7 +432,7 @@ def controlled(
control_values: Optional[
Union['cirq.ops.AbstractControlValues', Sequence[Union[int, Collection[int]]]]
] = None,
- control_qid_shape: Optional[Tuple[int, ...]] = None,
+ control_qid_shape: Optional[tuple[int, ...]] = None,
) -> 'GateWithRegisters':
"""Cirq-style API to construct a controlled gate. See `cirq.Gate.controlled()`"""
@@ -458,7 +447,7 @@ def controlled(
control_values: Optional[
Union['cirq.ops.AbstractControlValues', Sequence[Union[int, Collection[int]]]]
] = None,
- control_qid_shape: Optional[Tuple[int, ...]] = None,
+ control_qid_shape: Optional[tuple[int, ...]] = None,
*,
ctrl_spec: Optional['CtrlSpec'] = None,
) -> 'Bloq':
@@ -509,8 +498,8 @@ def _unitary_(self):
return NotImplemented
def my_tensors(
- self, incoming: Dict[str, 'ConnectionT'], outgoing: Dict[str, 'ConnectionT']
- ) -> List['qtn.Tensor']:
+ self, incoming: dict[str, 'ConnectionT'], outgoing: dict[str, 'ConnectionT']
+ ) -> list['qtn.Tensor']:
if not self._unitary_.__qualname__.startswith('GateWithRegisters.'):
from qualtran.cirq_interop._cirq_to_bloq import _my_tensors_from_gate
diff --git a/qualtran/_infra/gate_with_registers_test.py b/qualtran/_infra/gate_with_registers_test.py
index 31fd6f8635..3119c0f8d3 100644
--- a/qualtran/_infra/gate_with_registers_test.py
+++ b/qualtran/_infra/gate_with_registers_test.py
@@ -12,7 +12,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-from typing import Dict, Iterator, TYPE_CHECKING
+from collections.abc import Iterator
+from typing import TYPE_CHECKING
import cirq
import numpy as np
@@ -125,7 +126,7 @@ def signature(self) -> 'Signature':
def build_composite_bloq(
self, bb: 'BloqBuilder', l: 'SoquetT', t: 'SoquetT'
- ) -> Dict[str, 'SoquetT']:
+ ) -> dict[str, 'SoquetT']:
l = bb.add(XGate(), q=l)
bb.free(l)
t = bb.add(YGate(), q=t)
diff --git a/qualtran/_infra/quantum_graph.py b/qualtran/_infra/quantum_graph.py
index 62d2e5567c..37690564cc 100644
--- a/qualtran/_infra/quantum_graph.py
+++ b/qualtran/_infra/quantum_graph.py
@@ -14,7 +14,7 @@
"""Plumbing for bloq-to-bloq `Connection`s."""
from functools import cached_property
-from typing import Tuple, TYPE_CHECKING, Union
+from typing import TYPE_CHECKING, Union
from attrs import field, frozen
@@ -72,7 +72,7 @@ def bloq_is(self, t) -> bool:
return False
-def _to_tuple(x: Union[int, Tuple[int, ...]]) -> Tuple[int, ...]:
+def _to_tuple(x: Union[int, tuple[int, ...]]) -> tuple[int, ...]:
if isinstance(x, int):
return (x,)
return x
@@ -101,7 +101,7 @@ class Soquet:
binst: Union[BloqInstance, DanglingT]
reg: 'Register'
- idx: Tuple[int, ...] = field(converter=_to_tuple, default=tuple())
+ idx: tuple[int, ...] = field(converter=_to_tuple, default=tuple())
@idx.validator
def _check_idx(self, attribute, value):
diff --git a/qualtran/_infra/registers.py b/qualtran/_infra/registers.py
index bfeb8578d0..0bba84d889 100644
--- a/qualtran/_infra/registers.py
+++ b/qualtran/_infra/registers.py
@@ -16,7 +16,8 @@
import enum
import itertools
from collections import defaultdict
-from typing import cast, Dict, Iterable, Iterator, List, overload, Tuple, Union
+from collections.abc import Iterable, Iterator
+from typing import cast, overload, Union
import attrs
import sympy
@@ -63,7 +64,7 @@ class Register:
name: str
dtype: QCDType
- _shape: Tuple[SymbolicInt, ...] = field(
+ _shape: tuple[SymbolicInt, ...] = field(
default=tuple(), converter=lambda v: (v,) if isinstance(v, int) else tuple(v)
)
side: Side = Side.THRU
@@ -76,20 +77,20 @@ def is_symbolic(self) -> bool:
return is_symbolic(self.dtype, *self._shape)
@property
- def shape_symbolic(self) -> Tuple[SymbolicInt, ...]:
+ def shape_symbolic(self) -> tuple[SymbolicInt, ...]:
return self._shape
@property
- def shape(self) -> Tuple[int, ...]:
+ def shape(self) -> tuple[int, ...]:
if is_symbolic(*self._shape):
raise ValueError(f"{self} is symbolic. Cannot get real-valued shape.")
- return cast(Tuple[int, ...], self._shape)
+ return cast(tuple[int, ...], self._shape)
@property
def bitsize(self) -> int:
return self.dtype.num_bits
- def all_idxs(self) -> Iterable[Tuple[int, ...]]:
+ def all_idxs(self) -> Iterable[tuple[int, ...]]:
"""Iterate over all possible indices of a multidimensional register."""
yield from itertools.product(*[range(sh) for sh in self.shape])
@@ -127,7 +128,7 @@ def adjoint(self) -> 'Register':
raise ValueError(f"Unknown side {self.side}")
-def _dedupe(kv_iter: Iterable[Tuple[str, Register]]) -> Dict[str, Register]:
+def _dedupe(kv_iter: Iterable[tuple[str, Register]]) -> dict[str, Register]:
"""Construct a dictionary, but check that there are no duplicate keys."""
# throw ValueError if duplicate keys are provided.
d = {}
@@ -195,7 +196,7 @@ def get_right(self, name: str) -> Register:
"""Get a right register by name."""
return self._rights[name]
- def groups(self) -> Iterable[Tuple[str, List[Register]]]:
+ def groups(self) -> Iterable[tuple[str, list[Register]]]:
"""Iterate over register groups by name.
Registers with shared names (but differing `side` attributes) can be implicitly grouped.
@@ -257,7 +258,7 @@ def __getitem__(self, key: int) -> Register:
pass
@overload
- def __getitem__(self, key: slice) -> Tuple[Register, ...]:
+ def __getitem__(self, key: slice) -> tuple[Register, ...]:
pass
def __getitem__(self, key):
diff --git a/qualtran/bloqs/arithmetic/addition.py b/qualtran/bloqs/arithmetic/addition.py
index d249031816..7eee22eca0 100644
--- a/qualtran/bloqs/arithmetic/addition.py
+++ b/qualtran/bloqs/arithmetic/addition.py
@@ -12,8 +12,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from collections import Counter
+from collections.abc import Iterator, Sequence
from functools import cached_property
-from typing import Dict, Iterator, List, Optional, Sequence, Tuple, TYPE_CHECKING, Union
+from typing import Optional, TYPE_CHECKING, Union
import cirq
import numpy as np
@@ -115,7 +116,7 @@ def decompose_bloq(self) -> 'CompositeBloq':
def on_classical_vals(
self, a: 'ClassicalValT', b: 'ClassicalValT'
- ) -> Dict[str, 'ClassicalValT']:
+ ) -> dict[str, 'ClassicalValT']:
unsigned = isinstance(self.a_dtype, (QUInt, QMontgomeryUInt))
b_bitsize = self.b_dtype.bitsize
return {
@@ -128,7 +129,7 @@ def _circuit_diagram_info_(self, _) -> cirq.CircuitDiagramInfo:
wire_symbols += ["In(y)/Out(x+y)"] * int(self.b_dtype.bitsize)
return cirq.CircuitDiagramInfo(wire_symbols=wire_symbols)
- def wire_symbol(self, reg: Optional[Register], idx: Tuple[int, ...] = tuple()) -> 'WireSymbol':
+ def wire_symbol(self, reg: Optional[Register], idx: tuple[int, ...] = tuple()) -> 'WireSymbol':
if reg is None:
return Text("")
if reg.name == 'a':
@@ -202,7 +203,7 @@ def build_call_graph(self, ssa: 'SympySymbolAllocator') -> 'BloqCountDictT':
n_cnot = (n - 2) * 6 + 3
return {And(): n - 1, And().adjoint(): n - 1, CNOT(): n_cnot}
- def get_ctrl_system(self, ctrl_spec: 'CtrlSpec') -> Tuple['Bloq', 'AddControlledT']:
+ def get_ctrl_system(self, ctrl_spec: 'CtrlSpec') -> tuple['Bloq', 'AddControlledT']:
from qualtran.bloqs.arithmetic import CAdd
return get_ctrl_system_1bit_cv(
@@ -294,7 +295,7 @@ def registers(self) -> Sequence[Union[int, Sequence[int]]]:
raise ValueError(f'Symbolic bitsize {self.bitsize} not supported')
return [2] * self.bitsize, [2] * self.bitsize, [2] * self.out_bitsize
- def apply(self, a: int, b: int, c: int) -> Tuple[int, int, int]:
+ def apply(self, a: int, b: int, c: int) -> tuple[int, int, int]:
return a, b, c + a + b
def adjoint(self) -> 'OutOfPlaceAdder':
@@ -302,7 +303,7 @@ def adjoint(self) -> 'OutOfPlaceAdder':
def on_classical_vals(
self, *, a: 'ClassicalValT', b: 'ClassicalValT', c: Optional['ClassicalValT'] = None
- ) -> Dict[str, 'ClassicalValT']:
+ ) -> dict[str, 'ClassicalValT']:
if isinstance(self.bitsize, sympy.Expr):
raise ValueError(f'Classical simulation is not support for symbolic bloq {self}')
if self.is_adjoint:
@@ -324,7 +325,7 @@ def decompose_from_registers(
if not isinstance(self.bitsize, int):
raise ValueError(f'Symbolic bitsize {self.bitsize} not supported')
a, b, c = quregs['a'][::-1], quregs['b'][::-1], quregs['c'][::-1]
- optree: List[List[cirq.Operation]] = [
+ optree: list[list[cirq.Operation]] = [
[
cirq.CX(a[i], b[i]),
cirq.CX(a[i], c[i]),
@@ -354,7 +355,7 @@ def __pow__(self, power: int):
return OutOfPlaceAdder(self.bitsize, is_adjoint=not self.is_adjoint)
raise NotImplementedError("OutOfPlaceAdder.__pow__ defined only for +1/-1.")
- def wire_symbol(self, reg: Optional[Register], idx: Tuple[int, ...] = tuple()) -> 'WireSymbol':
+ def wire_symbol(self, reg: Optional[Register], idx: tuple[int, ...] = tuple()) -> 'WireSymbol':
if reg is None:
return Text('c=a+b')
return super().wire_symbol(reg, idx)
@@ -427,7 +428,7 @@ def signature(self) -> 'Signature':
def on_classical_vals(
self, x: 'ClassicalValT', **vals: 'ClassicalValT'
- ) -> Dict[str, 'ClassicalValT']:
+ ) -> dict[str, 'ClassicalValT']:
if is_symbolic(self.k) or is_symbolic(self.dtype):
raise ValueError(f"Classical simulation isn't supported for symbolic block {self}")
@@ -447,7 +448,7 @@ def _load_k_bloq(self) -> Bloq:
return XorK(self.dtype, k)
- def build_composite_bloq(self, bb: 'BloqBuilder', x: Soquet) -> Dict[str, 'SoquetT']:
+ def build_composite_bloq(self, bb: 'BloqBuilder', x: Soquet) -> dict[str, 'SoquetT']:
if is_symbolic(self.k) or is_symbolic(self.dtype):
raise DecomposeTypeError(f"Cannot decompose symbolic {self}.")
diff --git a/qualtran/bloqs/arithmetic/bitwise.py b/qualtran/bloqs/arithmetic/bitwise.py
index 87dc2d84b2..cf454ac39a 100644
--- a/qualtran/bloqs/arithmetic/bitwise.py
+++ b/qualtran/bloqs/arithmetic/bitwise.py
@@ -11,8 +11,9 @@
# 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.
+from collections.abc import Sequence
from functools import cached_property
-from typing import Dict, Optional, Sequence, TYPE_CHECKING
+from typing import Optional, TYPE_CHECKING
import numpy as np
import sympy
@@ -222,7 +223,7 @@ def wire_symbol(
return TextBox("~x")
- def on_classical_vals(self, x: 'ClassicalValT') -> Dict[str, 'ClassicalValT']:
+ def on_classical_vals(self, x: 'ClassicalValT') -> dict[str, 'ClassicalValT']:
x = -x - 1
if isinstance(self.dtype, (QUInt, QMontgomeryUInt)):
x %= 2**self.dtype.bitsize
diff --git a/qualtran/bloqs/arithmetic/comparison.py b/qualtran/bloqs/arithmetic/comparison.py
index 044d80ed8d..d38ce69bcc 100644
--- a/qualtran/bloqs/arithmetic/comparison.py
+++ b/qualtran/bloqs/arithmetic/comparison.py
@@ -14,8 +14,9 @@
import abc
from collections import defaultdict
+from collections.abc import Iterable, Iterator, Sequence
from functools import cached_property
-from typing import Dict, Iterable, Iterator, List, Optional, Sequence, Tuple, TYPE_CHECKING, Union
+from typing import Optional, TYPE_CHECKING, Union
import attrs
import cirq
@@ -77,7 +78,7 @@ def signature(self) -> Signature:
return Signature.build_from_dtypes(x=QUInt(self.bitsize), target=QBit())
def wire_symbol(
- self, reg: Optional['Register'], idx: Tuple[int, ...] = tuple()
+ self, reg: Optional['Register'], idx: tuple[int, ...] = tuple()
) -> 'WireSymbol':
if reg is None:
return Text("")
@@ -97,7 +98,7 @@ def apply(self, *register_vals: int) -> Union[int, Iterable[int]]:
input_val, less_than_val, target_register_val = register_vals
return input_val, less_than_val, target_register_val ^ (input_val < less_than_val)
- def on_classical_vals(self, *, x: int, target: int) -> Dict[str, 'ClassicalValT']:
+ def on_classical_vals(self, *, x: int, target: int) -> dict[str, 'ClassicalValT']:
return {'x': x, 'target': target ^ (x < self.less_than_val)}
def _circuit_diagram_info_(self, _) -> cirq.CircuitDiagramInfo:
@@ -461,7 +462,7 @@ def apply(self, *register_vals: int) -> Union[int, int, Iterable[int]]:
return x_val, y_val, target_val ^ (x_val <= y_val)
def wire_symbol(
- self, reg: Optional['Register'], idx: Tuple[int, ...] = tuple()
+ self, reg: Optional['Register'], idx: tuple[int, ...] = tuple()
) -> 'WireSymbol':
if reg is None:
return Text('')
@@ -473,7 +474,7 @@ def wire_symbol(
return TextBox('z∧(x<=y)')
raise ValueError(f'Unknown register name {reg.name}')
- def on_classical_vals(self, *, x: int, y: int, target: int) -> Dict[str, 'ClassicalValT']:
+ def on_classical_vals(self, *, x: int, y: int, target: int) -> dict[str, 'ClassicalValT']:
return {'x': x, 'y': y, 'target': target ^ (x <= y)}
def _circuit_diagram_info_(self, _) -> cirq.CircuitDiagramInfo:
@@ -516,7 +517,7 @@ def decompose_from_registers(
n = min(len(lhs), len(rhs))
prefix_equality = None
- adjoint: List[cirq.Operation] = []
+ adjoint: list[cirq.Operation] = []
# if one of the registers is longer than the other store equality with |0--0>
# into `prefix_equality` using d = |len(P) - len(Q)| And operations => 4d T.
@@ -582,7 +583,7 @@ def build_call_graph(self, ssa: 'SympySymbolAllocator') -> 'BloqCountDictT':
n = min(self.x_bitsize, self.y_bitsize)
d = max(self.x_bitsize, self.y_bitsize) - n
is_second_longer = self.y_bitsize > self.x_bitsize
- ret: Dict['Bloq', int] = defaultdict(lambda: 0)
+ ret: dict['Bloq', int] = defaultdict(lambda: 0)
if d > 0:
if d == 1:
ret[CNOT()] += 2
@@ -666,7 +667,7 @@ def signature(self):
a=QUInt(self.a_bitsize), b=QUInt(self.b_bitsize), target=QBit()
)
- def wire_symbol(self, reg: Optional[Register], idx: Tuple[int, ...] = tuple()) -> WireSymbol:
+ def wire_symbol(self, reg: Optional[Register], idx: tuple[int, ...] = tuple()) -> WireSymbol:
if reg is None:
return Text("a>b")
if reg.name == 'a':
@@ -679,7 +680,7 @@ def wire_symbol(self, reg: Optional[Register], idx: Tuple[int, ...] = tuple()) -
def build_composite_bloq(
self, bb: 'BloqBuilder', a: 'Soquet', b: 'Soquet', target: 'Soquet'
- ) -> Dict[str, 'SoquetT']:
+ ) -> dict[str, 'SoquetT']:
a, b, target = bb.add(
LessThanEqual(self.a_bitsize, self.b_bitsize), x=a, y=b, target=target
)
@@ -739,7 +740,7 @@ def signature(self):
def on_classical_vals(
self, a: 'ClassicalValT', b: 'ClassicalValT', target: 'ClassicalValT'
- ) -> Dict[str, 'ClassicalValT']:
+ ) -> dict[str, 'ClassicalValT']:
# target is a 1-bit register so we assert that it's classical value is binary.
assert target == (target % 2)
@@ -750,7 +751,7 @@ def on_classical_vals(
def build_composite_bloq(
self, bb: 'BloqBuilder', a: Soquet, b: Soquet, target: SoquetT
- ) -> Dict[str, 'SoquetT']:
+ ) -> dict[str, 'SoquetT']:
if isinstance(self.bitsize, sympy.Expr):
raise DecomposeTypeError(f"Cannot decompose symbolic {self}.")
@@ -767,7 +768,7 @@ def build_composite_bloq(
# Allocate lists to store ancillas generated by the logical-and and control pairs input
# into logical-ands.
- ancillas: List[SoquetT] = []
+ ancillas: list[SoquetT] = []
and_ctrls = []
# If the input registers are unsigned we need to append a sign bit to them in order to use
@@ -868,7 +869,7 @@ def build_composite_bloq(
return {'a': a, 'b': b, 'target': target}
def wire_symbol(
- self, reg: Optional['Register'], idx: Tuple[int, ...] = tuple()
+ self, reg: Optional['Register'], idx: tuple[int, ...] = tuple()
) -> 'WireSymbol':
if reg is None:
return Text('')
@@ -927,7 +928,7 @@ class GreaterThanConstant(Bloq):
def signature(self) -> Signature:
return Signature.build_from_dtypes(x=QUInt(self.bitsize), target=QBit())
- def wire_symbol(self, reg: Optional[Register], idx: Tuple[int, ...] = tuple()) -> WireSymbol:
+ def wire_symbol(self, reg: Optional[Register], idx: tuple[int, ...] = tuple()) -> WireSymbol:
if reg is None:
return Text("")
if reg.name == 'x':
@@ -975,7 +976,7 @@ def bitsize(self) -> SymbolicInt:
def is_symbolic(self):
return is_symbolic(self.dtype)
- def wire_symbol(self, reg: Optional[Register], idx: Tuple[int, ...] = tuple()) -> WireSymbol:
+ def wire_symbol(self, reg: Optional[Register], idx: tuple[int, ...] = tuple()) -> WireSymbol:
if reg is None:
return Text("")
if reg.name == 'x':
@@ -988,7 +989,7 @@ def wire_symbol(self, reg: Optional[Register], idx: Tuple[int, ...] = tuple()) -
def build_composite_bloq(
self, bb: 'BloqBuilder', x: 'Soquet', y: 'Soquet', target: 'Soquet'
- ) -> Dict[str, 'SoquetT']:
+ ) -> dict[str, 'SoquetT']:
if is_symbolic(self.bitsize):
raise DecomposeTypeError(f"Cannot decompose {self} with symbolic `bitsize`.")
@@ -1014,7 +1015,7 @@ def build_call_graph(self, ssa: 'SympySymbolAllocator') -> 'BloqCountDictT':
cvs = HasLength(self.bitsize)
return {Xor(self.dtype): 2, MultiControlX(cvs=cvs): 1}
- def on_classical_vals(self, x: int, y: int, target: int) -> Dict[str, 'ClassicalValT']:
+ def on_classical_vals(self, x: int, y: int, target: int) -> dict[str, 'ClassicalValT']:
return {'x': x, 'y': y, 'target': target ^ (x == y)}
@@ -1050,7 +1051,7 @@ class EqualsAConstant(Bloq):
def signature(self) -> Signature:
return Signature.build_from_dtypes(x=QUInt(self.bitsize), target=QBit())
- def wire_symbol(self, reg: Optional[Register], idx: Tuple[int, ...] = tuple()) -> WireSymbol:
+ def wire_symbol(self, reg: Optional[Register], idx: tuple[int, ...] = tuple()) -> WireSymbol:
if reg is None:
return Text("")
if reg.name == 'x':
@@ -1071,7 +1072,7 @@ def bits_k(self) -> Union[tuple[int, ...], HasLength]:
def build_composite_bloq(
self, bb: 'BloqBuilder', x: 'Soquet', target: 'Soquet'
- ) -> Dict[str, 'SoquetT']:
+ ) -> dict[str, 'SoquetT']:
if is_symbolic(self.bitsize):
raise DecomposeTypeError(f"Cannot decompose {self} with symbolic {self.bitsize=}")
@@ -1138,7 +1139,7 @@ def signature(self) -> Signature:
return Signature.build_from_dtypes(ctrl=QBit(), a=self.dtype, b=self.dtype, target=QBit())
def wire_symbol(
- self, reg: Optional['Register'], idx: Tuple[int, ...] = tuple()
+ self, reg: Optional['Register'], idx: tuple[int, ...] = tuple()
) -> 'WireSymbol':
if reg is None:
return Text('')
@@ -1154,7 +1155,7 @@ def wire_symbol(
def build_composite_bloq(
self, bb: 'BloqBuilder', ctrl: 'Soquet', a: 'Soquet', b: 'Soquet', target: 'Soquet'
- ) -> Dict[str, 'SoquetT']:
+ ) -> dict[str, 'SoquetT']:
if is_symbolic(self.dtype.bitsize):
raise DecomposeTypeError(f"Cannot decompose {self} with symbolic `bitsize`.")
@@ -1204,7 +1205,7 @@ def build_composite_bloq(
def on_classical_vals(
self, ctrl: int, a: int, b: int, target: int
- ) -> Dict[str, 'ClassicalValT']:
+ ) -> dict[str, 'ClassicalValT']:
if ctrl == self.cv:
return {'ctrl': ctrl, 'a': a, 'b': b, 'target': target ^ (a > b)}
return {'ctrl': ctrl, 'a': a, 'b': b, 'target': target}
@@ -1276,7 +1277,7 @@ def signature(self) -> Signature:
def adjoint(self) -> '_HalfLinearDepthGreaterThan':
return attrs.evolve(self, uncompute=self.uncompute ^ True)
- def _compute(self, bb: 'BloqBuilder', a: 'Soquet', b: 'Soquet') -> Dict[str, 'SoquetT']:
+ def _compute(self, bb: 'BloqBuilder', a: 'Soquet', b: 'Soquet') -> dict[str, 'SoquetT']:
if isinstance(self.dtype, QInt):
a = bb.add(SignExtend(self.dtype, QInt(self.dtype.bitsize + 1)), x=a)
b = bb.add(SignExtend(self.dtype, QInt(self.dtype.bitsize + 1)), x=b)
@@ -1317,7 +1318,7 @@ def _compute(self, bb: 'BloqBuilder', a: 'Soquet', b: 'Soquet') -> Dict[str, 'So
def _uncompute(
self, bb: 'BloqBuilder', a: 'Soquet', b: 'Soquet', c: 'Soquet', target: 'Soquet'
- ) -> Dict[str, 'SoquetT']:
+ ) -> dict[str, 'SoquetT']:
if isinstance(self.dtype, QInt):
a = bb.add(SignExtend(self.dtype, QInt(self.dtype.bitsize + 1)), x=a)
b = bb.add(SignExtend(self.dtype, QInt(self.dtype.bitsize + 1)), x=b)
@@ -1365,7 +1366,7 @@ def build_composite_bloq(
b: 'Soquet',
c: Optional['Soquet'] = None,
target: Optional['Soquet'] = None,
- ) -> Dict[str, 'SoquetT']:
+ ) -> dict[str, 'SoquetT']:
if is_symbolic(self.dtype.bitsize):
raise DecomposeTypeError(f"Cannot decompose {self} with symbolic `bitsize`.")
@@ -1470,7 +1471,7 @@ def on_classical_vals(
b: 'ClassicalValT',
c: Optional['ClassicalValT'] = None,
target: Optional['ClassicalValT'] = None,
- ) -> Dict[str, 'ClassicalValT']:
+ ) -> dict[str, 'ClassicalValT']:
if self._op_symbol in ('>', '<='):
c_val = add_ints(-int(a), int(b), num_bits=self.dtype.bitsize + 1, is_signed=False)
else:
@@ -1483,7 +1484,7 @@ def on_classical_vals(
assert target is None
return {'a': a, 'b': b, 'c': c_val, 'target': int(self._classical_comparison(a, b))}
- def _compute(self, bb: 'BloqBuilder', a: 'Soquet', b: 'Soquet') -> Dict[str, 'SoquetT']:
+ def _compute(self, bb: 'BloqBuilder', a: 'Soquet', b: 'Soquet') -> dict[str, 'SoquetT']:
if self._op_symbol in ('>', '<='):
a, b, c, target = bb.add_from(self._half_greater_than_bloq, a=a, b=b) # type: ignore
else:
@@ -1496,7 +1497,7 @@ def _compute(self, bb: 'BloqBuilder', a: 'Soquet', b: 'Soquet') -> Dict[str, 'So
def _uncompute(
self, bb: 'BloqBuilder', a: 'Soquet', b: 'Soquet', c: 'Soquet', target: 'Soquet'
- ) -> Dict[str, 'SoquetT']:
+ ) -> dict[str, 'SoquetT']:
if self._op_symbol in ('<=', '>='):
target = bb.add(XGate(), q=target)
@@ -1514,7 +1515,7 @@ def build_composite_bloq(
b: 'Soquet',
c: Optional['Soquet'] = None,
target: Optional['Soquet'] = None,
- ) -> Dict[str, 'SoquetT']:
+ ) -> dict[str, 'SoquetT']:
if self.uncompute:
assert c is not None
assert target is not None
diff --git a/qualtran/bloqs/arithmetic/controlled_addition.py b/qualtran/bloqs/arithmetic/controlled_addition.py
index dc6751d23a..c861b684ac 100644
--- a/qualtran/bloqs/arithmetic/controlled_addition.py
+++ b/qualtran/bloqs/arithmetic/controlled_addition.py
@@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-from typing import Dict, TYPE_CHECKING, Union
+from typing import TYPE_CHECKING, Union
import numpy as np
import sympy
@@ -102,7 +102,7 @@ def signature(self):
[Register("ctrl", QBit()), Register("a", self.a_dtype), Register("b", self.b_dtype)]
)
- def on_classical_vals(self, **kwargs) -> Dict[str, 'ClassicalValT']:
+ def on_classical_vals(self, **kwargs) -> dict[str, 'ClassicalValT']:
a, b = kwargs['a'], kwargs['b']
ctrl = kwargs['ctrl']
if ctrl != self.cv:
@@ -135,7 +135,7 @@ def wire_symbol(self, soq: 'Soquet') -> 'WireSymbol':
def build_composite_bloq(
self, bb: 'BloqBuilder', ctrl: 'Soquet', a: 'Soquet', b: 'Soquet'
- ) -> Dict[str, 'SoquetT']:
+ ) -> dict[str, 'SoquetT']:
if is_symbolic(self.a_dtype.bitsize, self.b_dtype.bitsize):
raise DecomposeTypeError(f"Cannot decompose {self} with symbolic `bitsize`.")
diff --git a/qualtran/bloqs/arithmetic/conversions/contiguous_index.py b/qualtran/bloqs/arithmetic/conversions/contiguous_index.py
index 79f552805b..f5caeac6ed 100644
--- a/qualtran/bloqs/arithmetic/conversions/contiguous_index.py
+++ b/qualtran/bloqs/arithmetic/conversions/contiguous_index.py
@@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from functools import cached_property
-from typing import Dict, Optional, Tuple, TYPE_CHECKING
+from typing import Optional, TYPE_CHECKING
from attrs import frozen
@@ -66,10 +66,10 @@ def signature(self) -> Signature:
def on_classical_vals(
self, mu: 'ClassicalValT', nu: 'ClassicalValT'
- ) -> Dict[str, 'ClassicalValT']:
+ ) -> dict[str, 'ClassicalValT']:
return {'mu': mu, 'nu': nu, 's': nu * (nu + 1) // 2 + mu}
- def wire_symbol(self, reg: Optional[Register], idx: Tuple[int, ...] = tuple()) -> WireSymbol:
+ def wire_symbol(self, reg: Optional[Register], idx: tuple[int, ...] = tuple()) -> WireSymbol:
if reg is None:
return Text('')
if reg.name == 'mu':
diff --git a/qualtran/bloqs/arithmetic/hamming_weight.py b/qualtran/bloqs/arithmetic/hamming_weight.py
index 2322fd8404..79789bc717 100644
--- a/qualtran/bloqs/arithmetic/hamming_weight.py
+++ b/qualtran/bloqs/arithmetic/hamming_weight.py
@@ -12,8 +12,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+from collections.abc import Iterator
from functools import cached_property
-from typing import Iterator, List, TYPE_CHECKING
+from typing import TYPE_CHECKING
import cirq
from attrs import frozen
@@ -87,7 +88,7 @@ def _three_to_two_adder(self, a, b, c, out) -> cirq.OP_TREE:
]
def _decompose_using_three_to_two_adders(
- self, x: List[cirq.Qid], junk: List[cirq.Qid], out: List[cirq.Qid]
+ self, x: list[cirq.Qid], junk: list[cirq.Qid], out: list[cirq.Qid]
) -> Iterator[cirq.OP_TREE]:
for out_idx in range(len(out)):
y = []
@@ -109,9 +110,9 @@ def decompose_from_registers(
) -> Iterator[cirq.OP_TREE]:
# Qubit order needs to be reversed because the registers store Big Endian representation
# of integers.
- x: List[cirq.Qid] = [*quregs['x'][::-1]]
- junk: List[cirq.Qid] = [*quregs['junk'][::-1]]
- out: List[cirq.Qid] = [*quregs['out'][::-1]]
+ x: list[cirq.Qid] = [*quregs['x'][::-1]]
+ junk: list[cirq.Qid] = [*quregs['junk'][::-1]]
+ out: list[cirq.Qid] = [*quregs['out'][::-1]]
yield self._decompose_using_three_to_two_adders(x, junk, out)
def build_call_graph(self, ssa: 'SympySymbolAllocator') -> 'BloqCountDictT':
diff --git a/qualtran/bloqs/arithmetic/multiplication.py b/qualtran/bloqs/arithmetic/multiplication.py
index efed2d6652..35e3587d71 100644
--- a/qualtran/bloqs/arithmetic/multiplication.py
+++ b/qualtran/bloqs/arithmetic/multiplication.py
@@ -12,7 +12,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-from typing import Dict, Iterable, List, Optional, Sequence, Tuple, TYPE_CHECKING, Union
+from collections.abc import Iterable, Sequence
+from typing import Optional, TYPE_CHECKING, Union
import cirq
import numpy as np
@@ -73,7 +74,7 @@ def __attrs_post_init__(self):
f"bitsizes {self.a_bitsize} + {self.b_bitsize}"
)
- def wire_symbol(self, reg: Optional[Register], idx: Tuple[int, ...] = tuple()) -> 'WireSymbol':
+ def wire_symbol(self, reg: Optional[Register], idx: tuple[int, ...] = tuple()) -> 'WireSymbol':
if reg is None:
return Text("result -= a*b") if self.is_adjoint else Text("result += a*b")
return super().wire_symbol(reg, idx)
@@ -112,7 +113,7 @@ def apply(self, a: int, b: int, result: int) -> Union[int, Iterable[int]]:
def with_registers(self, *new_registers: Union[int, Sequence[int]]):
raise NotImplementedError("Not needed.")
- def on_classical_vals(self, a: int, b: int, result: int) -> Dict[str, 'ClassicalValT']:
+ def on_classical_vals(self, a: int, b: int, result: int) -> dict[str, 'ClassicalValT']:
result_out = (result + a * b * ((-1) ** self.is_adjoint)) % (2**self.result_bitsize)
return {'a': a, 'b': b, 'result': result_out}
@@ -128,8 +129,8 @@ def _circuit_diagram_info_(self, args: cirq.CircuitDiagramInfoArgs) -> cirq.Circ
return cirq.CircuitDiagramInfo(wire_symbols=wire_symbols)
def my_tensors(
- self, incoming: Dict[str, 'ConnectionT'], outgoing: Dict[str, 'ConnectionT']
- ) -> List['qtn.Tensor']:
+ self, incoming: dict[str, 'ConnectionT'], outgoing: dict[str, 'ConnectionT']
+ ) -> list['qtn.Tensor']:
from qualtran.cirq_interop._cirq_to_bloq import _my_tensors_from_gate
return _my_tensors_from_gate(self, self.signature, incoming=incoming, outgoing=outgoing)
@@ -181,7 +182,7 @@ def signature(self):
]
)
- def on_classical_vals(self, **vals: int) -> Dict[str, 'ClassicalValT']:
+ def on_classical_vals(self, **vals: int) -> dict[str, 'ClassicalValT']:
if self.uncompute:
a, result = vals["a"], vals["result"]
assert result == a**2
@@ -189,7 +190,7 @@ def on_classical_vals(self, **vals: int) -> Dict[str, 'ClassicalValT']:
a = vals["a"]
return {'a': a, 'result': a**2}
- def wire_symbol(self, reg: Optional[Register], idx: Tuple[int, ...] = tuple()) -> 'WireSymbol':
+ def wire_symbol(self, reg: Optional[Register], idx: tuple[int, ...] = tuple()) -> 'WireSymbol':
if reg is None:
return Text("a^2")
return super().wire_symbol(reg, idx)
@@ -202,8 +203,8 @@ def build_call_graph(self, ssa: 'SympySymbolAllocator') -> 'BloqCountDictT':
return {Toffoli(): num_toff}
def my_tensors(
- self, incoming: Dict[str, 'ConnectionT'], outgoing: Dict[str, 'ConnectionT']
- ) -> List['qtn.Tensor']:
+ self, incoming: dict[str, 'ConnectionT'], outgoing: dict[str, 'ConnectionT']
+ ) -> list['qtn.Tensor']:
import quimb.tensor as qtn
if is_symbolic(self.bitsize):
@@ -277,7 +278,7 @@ def signature(self):
]
)
- def wire_symbol(self, reg: Optional[Register], idx: Tuple[int, ...] = tuple()) -> 'WireSymbol':
+ def wire_symbol(self, reg: Optional[Register], idx: tuple[int, ...] = tuple()) -> 'WireSymbol':
if reg is None:
return Text('SOS')
return super().wire_symbol(reg, idx)
@@ -332,7 +333,7 @@ def signature(self):
]
)
- def wire_symbol(self, reg: Optional[Register], idx: Tuple[int, ...] = tuple()) -> 'WireSymbol':
+ def wire_symbol(self, reg: Optional[Register], idx: tuple[int, ...] = tuple()) -> 'WireSymbol':
if reg is None:
return Text('a*b')
return super().wire_symbol(reg, idx)
@@ -395,7 +396,7 @@ def signature(self):
]
)
- def wire_symbol(self, reg: Optional[Register], idx: Tuple[int, ...] = tuple()) -> 'WireSymbol':
+ def wire_symbol(self, reg: Optional[Register], idx: tuple[int, ...] = tuple()) -> 'WireSymbol':
if reg is None:
return Text('r*i')
return super().wire_symbol(reg, idx)
@@ -454,7 +455,7 @@ def signature(self):
]
)
- def wire_symbol(self, reg: Optional[Register], idx: Tuple[int, ...] = tuple()) -> 'WireSymbol':
+ def wire_symbol(self, reg: Optional[Register], idx: tuple[int, ...] = tuple()) -> 'WireSymbol':
if reg is None:
return Text('a*b')
return super().wire_symbol(reg, idx)
@@ -515,7 +516,7 @@ def signature(self):
]
)
- def wire_symbol(self, reg: Optional[Register], idx: Tuple[int, ...] = tuple()) -> 'WireSymbol':
+ def wire_symbol(self, reg: Optional[Register], idx: tuple[int, ...] = tuple()) -> 'WireSymbol':
if reg is None:
return Text('a^2')
return super().wire_symbol(reg, idx)
@@ -573,7 +574,7 @@ def signature(self):
]
)
- def wire_symbol(self, reg: Optional[Register], idx: Tuple[int, ...] = tuple()) -> 'WireSymbol':
+ def wire_symbol(self, reg: Optional[Register], idx: tuple[int, ...] = tuple()) -> 'WireSymbol':
if reg is None:
return Text('1/a')
return super().wire_symbol(reg, idx)
diff --git a/qualtran/bloqs/arithmetic/permutation.py b/qualtran/bloqs/arithmetic/permutation.py
index 8c294d5934..d5507fdd22 100644
--- a/qualtran/bloqs/arithmetic/permutation.py
+++ b/qualtran/bloqs/arithmetic/permutation.py
@@ -23,8 +23,9 @@
# 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.
+from collections.abc import Iterable, Sequence
from functools import cached_property
-from typing import cast, Iterable, Sequence, Set, TYPE_CHECKING, TypeAlias, Union
+from typing import cast, TYPE_CHECKING, TypeAlias, Union
from attrs import field, frozen
@@ -126,7 +127,7 @@ def build_composite_bloq(self, bb: 'BloqBuilder', x: 'SoquetT') -> dict[str, 'So
def build_call_graph(
self, ssa: 'SympySymbolAllocator'
- ) -> Union['BloqCountDictT', Set['BloqCountT']]:
+ ) -> Union['BloqCountDictT', set['BloqCountT']]:
if is_symbolic(self.cycle):
x = ssa.new_symbol('x')
cycle_len = slen(self.cycle)
@@ -275,7 +276,7 @@ def build_composite_bloq(self, bb: 'BloqBuilder', x: 'Soquet') -> dict[str, 'Soq
def build_call_graph(
self, ssa: 'SympySymbolAllocator'
- ) -> Union['BloqCountDictT', Set['BloqCountT']]:
+ ) -> Union['BloqCountDictT', set['BloqCountT']]:
if is_symbolic(self.cycles):
# worst case cost: single cycle of length N
cycle = Shaped((self.N,))
diff --git a/qualtran/bloqs/arithmetic/sorting.py b/qualtran/bloqs/arithmetic/sorting.py
index 5014d74bc1..f6247de40d 100644
--- a/qualtran/bloqs/arithmetic/sorting.py
+++ b/qualtran/bloqs/arithmetic/sorting.py
@@ -12,7 +12,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from functools import cached_property
-from typing import Dict
import numpy as np
import sympy
@@ -152,7 +151,7 @@ def num_comparisons(self) -> SymbolicInt:
rest = self.k % (2 * self.offset)
return full + max(rest - self.offset, 0)
- def build_composite_bloq(self, bb: 'BloqBuilder', xs: 'SoquetT') -> Dict[str, 'SoquetT']:
+ def build_composite_bloq(self, bb: 'BloqBuilder', xs: 'SoquetT') -> dict[str, 'SoquetT']:
if is_symbolic(self.k) or is_symbolic(self.offset):
raise DecomposeTypeError(f"Cannot decompose symbolic {self=}")
diff --git a/qualtran/bloqs/arithmetic/subtraction.py b/qualtran/bloqs/arithmetic/subtraction.py
index f062557083..441030bfe4 100644
--- a/qualtran/bloqs/arithmetic/subtraction.py
+++ b/qualtran/bloqs/arithmetic/subtraction.py
@@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-from typing import Dict, Optional, Tuple, TYPE_CHECKING, Union
+from typing import Optional, TYPE_CHECKING, Union
import numpy as np
import sympy
@@ -121,7 +121,7 @@ def b_dtype_as_unsigned(self):
def on_classical_vals(
self, a: 'ClassicalValT', b: 'ClassicalValT'
- ) -> Dict[str, 'ClassicalValT']:
+ ) -> dict[str, 'ClassicalValT']:
unsigned = isinstance(self.a_dtype, (QUInt, QMontgomeryUInt))
b_bitsize = self.b_dtype.bitsize
N = 2**b_bitsize
@@ -138,7 +138,7 @@ def on_classical_vals(
return {'a': a, 'b': int((a - b + half_n) % N) - half_n}
def wire_symbol(
- self, reg: Optional['Register'], idx: Tuple[int, ...] = tuple()
+ self, reg: Optional['Register'], idx: tuple[int, ...] = tuple()
) -> 'WireSymbol':
from qualtran.drawing import directional_text_box
@@ -164,7 +164,7 @@ def build_call_graph(self, ssa: 'SympySymbolAllocator') -> 'BloqCountDictT':
costs[MultiTargetCNOT(delta)] = 2
return costs
- def build_composite_bloq(self, bb: 'BloqBuilder', a: Soquet, b: Soquet) -> Dict[str, 'SoquetT']:
+ def build_composite_bloq(self, bb: 'BloqBuilder', a: Soquet, b: Soquet) -> dict[str, 'SoquetT']:
delta = self.b_dtype.bitsize - self.a_dtype.bitsize
n_bits = self.b_dtype.bitsize
if delta:
@@ -269,7 +269,7 @@ def signature(self):
def on_classical_vals(
self, a: 'ClassicalValT', b: 'ClassicalValT'
- ) -> Dict[str, 'ClassicalValT']:
+ ) -> dict[str, 'ClassicalValT']:
return {
'a': a,
'b': add_ints(
@@ -281,7 +281,7 @@ def on_classical_vals(
}
def wire_symbol(
- self, reg: Optional['Register'], idx: Tuple[int, ...] = tuple()
+ self, reg: Optional['Register'], idx: tuple[int, ...] = tuple()
) -> 'WireSymbol':
from qualtran.drawing import directional_text_box
@@ -297,7 +297,7 @@ def wire_symbol(
def build_call_graph(self, ssa: 'SympySymbolAllocator') -> 'BloqCountDictT':
return {BitwiseNot(self.dtype): 2, Add(self.dtype, self.dtype): 1}
- def build_composite_bloq(self, bb: 'BloqBuilder', a: Soquet, b: Soquet) -> Dict[str, 'SoquetT']:
+ def build_composite_bloq(self, bb: 'BloqBuilder', a: Soquet, b: Soquet) -> dict[str, 'SoquetT']:
b = bb.add(BitwiseNot(self.dtype), x=b) # a, -1 - b
a, b = bb.add_t(Add(self.dtype, self.dtype), a=a, b=b) # a, a - 1 - b
b = bb.add(BitwiseNot(self.dtype), x=b) # a, -1 - (a - 1 - b) = a, -a + b
diff --git a/qualtran/bloqs/arithmetic/trigonometric/arcsin.py b/qualtran/bloqs/arithmetic/trigonometric/arcsin.py
index 2405e65efa..bb6365b374 100644
--- a/qualtran/bloqs/arithmetic/trigonometric/arcsin.py
+++ b/qualtran/bloqs/arithmetic/trigonometric/arcsin.py
@@ -12,8 +12,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-from typing import Dict
-
import numpy as np
from attrs import frozen
@@ -74,7 +72,7 @@ def signature(self):
def on_classical_vals(
self, x: ClassicalValT, result: ClassicalValT
- ) -> Dict[str, ClassicalValT]:
+ ) -> dict[str, ClassicalValT]:
if is_symbolic(self.bitsize):
raise ValueError(f"Symbolic bitsize {self.bitsize} not supported")
x_fxp: float = _fxp(x / 2**self.bitsize, self.bitsize).astype(float)
diff --git a/qualtran/bloqs/arithmetic/trigonometric/arctan.py b/qualtran/bloqs/arithmetic/trigonometric/arctan.py
index 746411d9f4..8fb10d09d3 100644
--- a/qualtran/bloqs/arithmetic/trigonometric/arctan.py
+++ b/qualtran/bloqs/arithmetic/trigonometric/arctan.py
@@ -11,8 +11,9 @@
# 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.
+from collections.abc import Iterable, Sequence
from functools import cached_property
-from typing import Iterable, Sequence, Union
+from typing import Union
import attrs
import cirq
diff --git a/qualtran/bloqs/basic_gates/cnot.py b/qualtran/bloqs/basic_gates/cnot.py
index d2c2002a22..c25d4157ac 100644
--- a/qualtran/bloqs/basic_gates/cnot.py
+++ b/qualtran/bloqs/basic_gates/cnot.py
@@ -13,8 +13,9 @@
# limitations under the License.
import itertools
+from collections.abc import Iterable, Sequence
from functools import cached_property
-from typing import Dict, Iterable, List, Optional, Sequence, Tuple, TYPE_CHECKING
+from typing import Optional, TYPE_CHECKING
import numpy as np
from attrs import frozen
@@ -72,8 +73,8 @@ def adjoint(self) -> 'Bloq':
return self
def my_tensors(
- self, incoming: Dict[str, 'ConnectionT'], outgoing: Dict[str, 'ConnectionT']
- ) -> List['qtn.Tensor']:
+ self, incoming: dict[str, 'ConnectionT'], outgoing: dict[str, 'ConnectionT']
+ ) -> list['qtn.Tensor']:
# This bloq uses the factored form of CNOT composed of a COPY and XOR tensor joined
# by an internal index.
# [Lectures on Quantum Tensor Networks](https://arxiv.org/abs/1912.10049). Biamonte 2019.
@@ -93,10 +94,10 @@ def my_tensors(
),
]
- def on_classical_vals(self, ctrl: int, target: int) -> Dict[str, 'ClassicalValT']:
+ def on_classical_vals(self, ctrl: int, target: int) -> dict[str, 'ClassicalValT']:
return {'ctrl': ctrl, 'target': (ctrl + target) % 2}
- def get_ctrl_system(self, ctrl_spec: 'CtrlSpec') -> Tuple['Bloq', 'AddControlledT']:
+ def get_ctrl_system(self, ctrl_spec: 'CtrlSpec') -> tuple['Bloq', 'AddControlledT']:
from qualtran.bloqs.basic_gates.toffoli import Toffoli
if ctrl_spec != CtrlSpec():
@@ -105,8 +106,8 @@ def get_ctrl_system(self, ctrl_spec: 'CtrlSpec') -> Tuple['Bloq', 'AddControlled
bloq = Toffoli()
def add_controlled(
- bb: 'BloqBuilder', ctrl_soqs: Sequence['SoquetT'], in_soqs: Dict[str, 'SoquetT']
- ) -> Tuple[Iterable['SoquetT'], Iterable['SoquetT']]:
+ bb: 'BloqBuilder', ctrl_soqs: Sequence['SoquetT'], in_soqs: dict[str, 'SoquetT']
+ ) -> tuple[Iterable['SoquetT'], Iterable['SoquetT']]:
(new_ctrl,) = ctrl_soqs
(new_ctrl, existing_ctrl), target = bb.add(
bloq, ctrl=np.array([new_ctrl, in_soqs['ctrl']]), target=in_soqs['target']
@@ -117,7 +118,7 @@ def add_controlled(
def as_cirq_op(
self, qubit_manager: 'cirq.QubitManager', ctrl: 'CirqQuregT', target: 'CirqQuregT' # type: ignore[type-var]
- ) -> Tuple['cirq.Operation', Dict[str, 'CirqQuregT']]: # type: ignore[type-var]
+ ) -> tuple['cirq.Operation', dict[str, 'CirqQuregT']]: # type: ignore[type-var]
import cirq
(ctrl,) = ctrl
@@ -129,7 +130,7 @@ def as_pl_op(self, wires: 'Wires') -> 'Operation':
return qml.CNOT(wires=wires)
- def wire_symbol(self, reg: Optional[Register], idx: Tuple[int, ...] = tuple()) -> 'WireSymbol':
+ def wire_symbol(self, reg: Optional[Register], idx: tuple[int, ...] = tuple()) -> 'WireSymbol':
if reg is None:
return Text('')
if reg.name == 'ctrl':
diff --git a/qualtran/bloqs/basic_gates/global_phase.py b/qualtran/bloqs/basic_gates/global_phase.py
index 08e0273e6e..af991b420f 100644
--- a/qualtran/bloqs/basic_gates/global_phase.py
+++ b/qualtran/bloqs/basic_gates/global_phase.py
@@ -11,8 +11,9 @@
# 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.
+from collections.abc import Iterable, Sequence
from functools import cached_property
-from typing import Dict, Iterable, List, Sequence, Tuple, TYPE_CHECKING
+from typing import TYPE_CHECKING
import attrs
import cirq
@@ -93,13 +94,13 @@ def adjoint(self) -> 'GlobalPhase':
return attrs.evolve(self, exponent=-self.exponent)
def my_tensors(
- self, incoming: Dict[str, 'ConnectionT'], outgoing: Dict[str, 'ConnectionT']
- ) -> List['qtn.Tensor']:
+ self, incoming: dict[str, 'ConnectionT'], outgoing: dict[str, 'ConnectionT']
+ ) -> list['qtn.Tensor']:
import quimb.tensor as qtn
return [qtn.Tensor(data=self.coefficient, inds=[], tags=[str(self)])]
- def get_ctrl_system(self, ctrl_spec: 'CtrlSpec') -> Tuple['Bloq', 'AddControlledT']:
+ def get_ctrl_system(self, ctrl_spec: 'CtrlSpec') -> tuple['Bloq', 'AddControlledT']:
# Delegate to superclass logic for more than one control.
if ctrl_spec != CtrlSpec():
return super().get_ctrl_system(ctrl_spec=ctrl_spec)
@@ -109,8 +110,8 @@ def get_ctrl_system(self, ctrl_spec: 'CtrlSpec') -> Tuple['Bloq', 'AddControlled
bloq = ZPowGate(exponent=self.exponent, eps=self.eps)
def _add_ctrled(
- bb: 'BloqBuilder', ctrl_soqs: Sequence['SoquetT'], in_soqs: Dict[str, 'SoquetT']
- ) -> Tuple[Iterable['SoquetT'], Iterable['SoquetT']]:
+ bb: 'BloqBuilder', ctrl_soqs: Sequence['SoquetT'], in_soqs: dict[str, 'SoquetT']
+ ) -> tuple[Iterable['SoquetT'], Iterable['SoquetT']]:
(ctrl,) = ctrl_soqs
ctrl = bb.add(bloq, q=ctrl)
return [ctrl], []
diff --git a/qualtran/bloqs/basic_gates/hadamard.py b/qualtran/bloqs/basic_gates/hadamard.py
index 371672f6e3..4be0681d99 100644
--- a/qualtran/bloqs/basic_gates/hadamard.py
+++ b/qualtran/bloqs/basic_gates/hadamard.py
@@ -12,8 +12,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+from collections.abc import Iterable, Sequence
from functools import cached_property
-from typing import Dict, Iterable, List, Optional, Sequence, Tuple, TYPE_CHECKING, Union
+from typing import Optional, TYPE_CHECKING, Union
import numpy as np
from attrs import frozen
@@ -74,8 +75,8 @@ def decompose_bloq(self) -> 'CompositeBloq':
raise DecomposeTypeError(f"{self} is atomic")
def my_tensors(
- self, incoming: Dict[str, 'ConnectionT'], outgoing: Dict[str, 'ConnectionT']
- ) -> List['qtn.Tensor']:
+ self, incoming: dict[str, 'ConnectionT'], outgoing: dict[str, 'ConnectionT']
+ ) -> list['qtn.Tensor']:
import quimb.tensor as qtn
return [
@@ -84,15 +85,15 @@ def my_tensors(
)
]
- def get_ctrl_system(self, ctrl_spec: 'CtrlSpec') -> Tuple['Bloq', 'AddControlledT']:
+ def get_ctrl_system(self, ctrl_spec: 'CtrlSpec') -> tuple['Bloq', 'AddControlledT']:
if ctrl_spec != CtrlSpec():
return super().get_ctrl_system(ctrl_spec=ctrl_spec)
bloq = CHadamard()
def _add_ctrled(
- bb: 'BloqBuilder', ctrl_soqs: Sequence['SoquetT'], in_soqs: Dict[str, 'SoquetT']
- ) -> Tuple[Iterable['SoquetT'], Iterable['SoquetT']]:
+ bb: 'BloqBuilder', ctrl_soqs: Sequence['SoquetT'], in_soqs: dict[str, 'SoquetT']
+ ) -> tuple[Iterable['SoquetT'], Iterable['SoquetT']]:
(ctrl,) = ctrl_soqs
ctrl, q = bb.add(bloq, ctrl=ctrl, target=in_soqs['q'])
return ((ctrl,), (q,))
@@ -101,7 +102,7 @@ def _add_ctrled(
def as_cirq_op(
self, qubit_manager: 'cirq.QubitManager', q: 'CirqQuregT' # type: ignore[type-var]
- ) -> Tuple['cirq.Operation', Dict[str, 'CirqQuregT']]: # type: ignore[type-var]
+ ) -> tuple['cirq.Operation', dict[str, 'CirqQuregT']]: # type: ignore[type-var]
import cirq
(q,) = q
@@ -112,7 +113,7 @@ def as_pl_op(self, wires: 'Wires') -> 'Operation':
return qml.Hadamard(wires=wires)
- def wire_symbol(self, reg: Optional[Register], idx: Tuple[int, ...] = tuple()) -> 'WireSymbol':
+ def wire_symbol(self, reg: Optional[Register], idx: tuple[int, ...] = tuple()) -> 'WireSymbol':
if reg is None:
return Text('')
return TextBox('H')
@@ -150,8 +151,8 @@ def adjoint(self) -> 'Bloq':
return self
def my_tensors(
- self, incoming: Dict[str, 'ConnectionT'], outgoing: Dict[str, 'ConnectionT']
- ) -> List['qtn.Tensor']:
+ self, incoming: dict[str, 'ConnectionT'], outgoing: dict[str, 'ConnectionT']
+ ) -> list['qtn.Tensor']:
import quimb.tensor as qtn
unitary = np.eye(4, dtype=np.complex128).reshape((2, 2, 2, 2))
@@ -168,7 +169,7 @@ def my_tensors(
def as_cirq_op(
self, qubit_manager: 'cirq.QubitManager', ctrl: 'CirqQuregT', target: 'CirqQuregT'
- ) -> Tuple[Union['cirq.Operation', None], Dict[str, 'CirqQuregT']]:
+ ) -> tuple[Union['cirq.Operation', None], dict[str, 'CirqQuregT']]:
import cirq
(ctrl,) = ctrl
@@ -191,7 +192,7 @@ def my_static_costs(self, cost_key: 'CostKey'):
return NotImplemented
- def wire_symbol(self, reg: Optional[Register], idx: Tuple[int, ...] = tuple()) -> 'WireSymbol':
+ def wire_symbol(self, reg: Optional[Register], idx: tuple[int, ...] = tuple()) -> 'WireSymbol':
if reg is None:
return Text('')
if reg.name == 'ctrl':
diff --git a/qualtran/bloqs/basic_gates/identity.py b/qualtran/bloqs/basic_gates/identity.py
index 379717e0ec..4451a511f9 100644
--- a/qualtran/bloqs/basic_gates/identity.py
+++ b/qualtran/bloqs/basic_gates/identity.py
@@ -12,8 +12,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+from collections.abc import Iterable, Sequence
from functools import cached_property
-from typing import Dict, Iterable, List, Optional, Sequence, Tuple, TYPE_CHECKING
+from typing import Optional, TYPE_CHECKING
import numpy as np
from attrs import frozen
@@ -69,8 +70,8 @@ def decompose_bloq(self) -> 'CompositeBloq':
raise DecomposeTypeError(f"{self} is atomic")
def my_tensors(
- self, incoming: Dict[str, 'ConnectionT'], outgoing: Dict[str, 'ConnectionT']
- ) -> List['qtn.Tensor']:
+ self, incoming: dict[str, 'ConnectionT'], outgoing: dict[str, 'ConnectionT']
+ ) -> list['qtn.Tensor']:
import quimb.tensor as qtn
return [
@@ -82,7 +83,7 @@ def my_tensors(
def as_cirq_op(
self, qubit_manager: 'cirq.QubitManager', q: 'CirqQuregT' # type: ignore[type-var]
- ) -> Tuple['cirq.Operation', Dict[str, 'CirqQuregT']]: # type: ignore[type-var]
+ ) -> tuple['cirq.Operation', dict[str, 'CirqQuregT']]: # type: ignore[type-var]
import cirq
if is_symbolic(self.bitsize):
@@ -95,12 +96,12 @@ def as_pl_op(self, wires: 'Wires') -> 'Operation':
return qml.Identity(wires=wires)
- def wire_symbol(self, reg: Optional[Register], idx: Tuple[int, ...] = tuple()) -> 'WireSymbol':
+ def wire_symbol(self, reg: Optional[Register], idx: tuple[int, ...] = tuple()) -> 'WireSymbol':
if reg is None:
return Text('')
return TextBox('I')
- def on_classical_vals(self, q: int) -> Dict[str, 'ClassicalValT']:
+ def on_classical_vals(self, q: int) -> dict[str, 'ClassicalValT']:
return {'q': q}
def __str__(self) -> str:
@@ -113,8 +114,8 @@ def get_ctrl_system(self, ctrl_spec: 'CtrlSpec') -> tuple['Bloq', 'AddControlled
ctrl_I = Identity(ctrl_spec.num_qubits + self.bitsize)
def ctrl_adder(
- bb: 'BloqBuilder', ctrl_soqs: Sequence['SoquetT'], in_soqs: Dict[str, 'SoquetT']
- ) -> Tuple[Iterable['SoquetT'], Iterable['SoquetT']]:
+ bb: 'BloqBuilder', ctrl_soqs: Sequence['SoquetT'], in_soqs: dict[str, 'SoquetT']
+ ) -> tuple[Iterable['SoquetT'], Iterable['SoquetT']]:
parts = [
(Register(f'ctrl_{i}', dtype=dtype, shape=shape), 'q')
for i, (dtype, shape) in enumerate(ctrl_spec.activation_function_dtypes())
diff --git a/qualtran/bloqs/basic_gates/on_each.py b/qualtran/bloqs/basic_gates/on_each.py
index 0d8a190709..fb7d19fdc3 100644
--- a/qualtran/bloqs/basic_gates/on_each.py
+++ b/qualtran/bloqs/basic_gates/on_each.py
@@ -14,7 +14,7 @@
"""Classes to apply single qubit bloq to multiple qubits."""
from functools import cached_property
-from typing import Dict, Optional, Tuple
+from typing import Optional
import attrs
import sympy
@@ -70,7 +70,7 @@ def signature(self) -> Signature:
)
return Signature([reg])
- def build_composite_bloq(self, bb: BloqBuilder, *, q: Soquet) -> Dict[str, SoquetT]:
+ def build_composite_bloq(self, bb: BloqBuilder, *, q: Soquet) -> dict[str, SoquetT]:
if isinstance(self.n, sympy.Expr):
raise DecomposeTypeError(f'Cannote decompose {self} with symbolic bitsize {self.n}')
qs = bb.split(q)
@@ -81,7 +81,7 @@ def build_composite_bloq(self, bb: BloqBuilder, *, q: Soquet) -> Dict[str, Soque
def build_call_graph(self, ssa: 'SympySymbolAllocator') -> 'BloqCountDictT':
return {self.gate: self.n}
- def wire_symbol(self, reg: Optional[Register], idx: Tuple[int, ...] = tuple()) -> WireSymbol:
+ def wire_symbol(self, reg: Optional[Register], idx: tuple[int, ...] = tuple()) -> WireSymbol:
one_reg = self.gate.wire_symbol(reg=reg, idx=idx)
if isinstance(one_reg, TextBox):
new_text = f'{one_reg.text}⨂{self.n}'
diff --git a/qualtran/bloqs/basic_gates/power.py b/qualtran/bloqs/basic_gates/power.py
index 5331c3afd2..b8e1888fec 100644
--- a/qualtran/bloqs/basic_gates/power.py
+++ b/qualtran/bloqs/basic_gates/power.py
@@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from functools import cached_property
-from typing import Dict, TYPE_CHECKING
+from typing import TYPE_CHECKING
import numpy as np
from attrs import frozen
@@ -59,7 +59,7 @@ def adjoint(self) -> 'Bloq':
def signature(self) -> Signature:
return self.bloq.signature
- def build_composite_bloq(self, bb: 'BloqBuilder', **soqs: 'SoquetT') -> Dict[str, 'SoquetT']:
+ def build_composite_bloq(self, bb: 'BloqBuilder', **soqs: 'SoquetT') -> dict[str, 'SoquetT']:
if not isinstance(self.power, int):
raise ValueError(f'Symbolic power {self.power} not supported')
for _ in range(self.power):
diff --git a/qualtran/bloqs/basic_gates/rotation.py b/qualtran/bloqs/basic_gates/rotation.py
index 3acb1681db..1d573f58b2 100644
--- a/qualtran/bloqs/basic_gates/rotation.py
+++ b/qualtran/bloqs/basic_gates/rotation.py
@@ -42,9 +42,9 @@
Barenco et. al. 1995.
"""
-
+from collections.abc import Iterable, Sequence
from functools import cached_property
-from typing import Dict, Iterable, Optional, Sequence, Tuple, TYPE_CHECKING, Union
+from typing import Optional, TYPE_CHECKING, Union
import attrs
import cirq
@@ -135,15 +135,15 @@ def decompose_bloq(self) -> 'CompositeBloq':
def cirq_gate(self) -> cirq.Gate:
return cirq.ZPowGate(exponent=self.exponent, global_shift=0)
- def get_ctrl_system(self, ctrl_spec: 'CtrlSpec') -> Tuple['Bloq', 'AddControlledT']:
+ def get_ctrl_system(self, ctrl_spec: 'CtrlSpec') -> tuple['Bloq', 'AddControlledT']:
if ctrl_spec != CtrlSpec():
return super().get_ctrl_system(ctrl_spec)
ctrl_bloq = CZPowGate(exponent=self.exponent, eps=self.eps)
def add_ctrled(
- bb: 'BloqBuilder', ctrl_soqs: Sequence['SoquetT'], in_soqs: Dict[str, 'SoquetT']
- ) -> Tuple[Iterable['SoquetT'], Iterable['SoquetT']]:
+ bb: 'BloqBuilder', ctrl_soqs: Sequence['SoquetT'], in_soqs: dict[str, 'SoquetT']
+ ) -> tuple[Iterable['SoquetT'], Iterable['SoquetT']]:
(ctrl_soq,) = ctrl_soqs
ctrl_soq, q = bb.add(ctrl_bloq, q=np.array([ctrl_soq, in_soqs['q']]))
return (ctrl_soq,), (q,)
@@ -157,7 +157,7 @@ def __pow__(self, power):
def adjoint(self) -> 'ZPowGate':
return attrs.evolve(self, exponent=-self.exponent)
- def wire_symbol(self, reg: Optional[Register], idx: Tuple[int, ...] = tuple()) -> 'WireSymbol':
+ def wire_symbol(self, reg: Optional[Register], idx: tuple[int, ...] = tuple()) -> 'WireSymbol':
if reg is None:
return Text('')
return TextBox(f'Z^{self.exponent}')
@@ -215,7 +215,7 @@ class CZPowGate(Bloq):
def signature(self) -> 'Signature':
return Signature([Register('q', QBit(), shape=(2,))])
- def build_composite_bloq(self, bb: 'BloqBuilder', q: 'SoquetT') -> Dict[str, 'SoquetT']:
+ def build_composite_bloq(self, bb: 'BloqBuilder', q: 'SoquetT') -> dict[str, 'SoquetT']:
from qualtran.bloqs.mcmt import And
q1, q2 = q # type: ignore
@@ -299,7 +299,7 @@ def cirq_gate(self) -> cirq.Gate:
def adjoint(self) -> 'XPowGate':
return attrs.evolve(self, exponent=-self.exponent)
- def wire_symbol(self, reg: Optional[Register], idx: Tuple[int, ...] = tuple()) -> 'WireSymbol':
+ def wire_symbol(self, reg: Optional[Register], idx: tuple[int, ...] = tuple()) -> 'WireSymbol':
if reg is None:
return Text('')
return TextBox(f'X^{self.exponent}')
@@ -373,7 +373,7 @@ def cirq_gate(self) -> cirq.Gate:
def adjoint(self) -> 'YPowGate':
return attrs.evolve(self, exponent=-self.exponent)
- def wire_symbol(self, reg: Optional[Register], idx: Tuple[int, ...] = tuple()) -> 'WireSymbol':
+ def wire_symbol(self, reg: Optional[Register], idx: tuple[int, ...] = tuple()) -> 'WireSymbol':
if reg is None:
return Text('')
return TextBox(f'Y^{self.exponent}')
@@ -449,7 +449,7 @@ def as_pl_op(self, wires: 'Wires') -> 'Operation':
return qml.RZ(phi=self.angle, wires=wires)
- def get_ctrl_system(self, ctrl_spec: 'CtrlSpec') -> Tuple['Bloq', 'AddControlledT']:
+ def get_ctrl_system(self, ctrl_spec: 'CtrlSpec') -> tuple['Bloq', 'AddControlledT']:
if ctrl_spec != CtrlSpec():
return super().get_ctrl_system(ctrl_spec)
@@ -466,7 +466,7 @@ def get_ctrl_system(self, ctrl_spec: 'CtrlSpec') -> Tuple['Bloq', 'AddControlled
def adjoint(self) -> 'Rz':
return attrs.evolve(self, angle=-self.angle)
- def wire_symbol(self, reg: Optional[Register], idx: Tuple[int, ...] = tuple()) -> 'WireSymbol':
+ def wire_symbol(self, reg: Optional[Register], idx: tuple[int, ...] = tuple()) -> 'WireSymbol':
if reg is None:
return Text('')
return TextBox(str(self))
@@ -527,7 +527,7 @@ def signature(self) -> 'Signature':
def build_composite_bloq(
self, bb: 'BloqBuilder', ctrl: 'Soquet', q: 'Soquet'
- ) -> Dict[str, 'SoquetT']:
+ ) -> dict[str, 'SoquetT']:
from qualtran.bloqs.basic_gates import CNOT
t = self.angle / np.pi
@@ -607,7 +607,7 @@ def as_pl_op(self, wires: 'Wires') -> 'Operation':
def adjoint(self) -> 'Rx':
return attrs.evolve(self, angle=-self.angle)
- def wire_symbol(self, reg: Optional[Register], idx: Tuple[int, ...] = tuple()) -> 'WireSymbol':
+ def wire_symbol(self, reg: Optional[Register], idx: tuple[int, ...] = tuple()) -> 'WireSymbol':
if reg is None:
return Text('')
return TextBox(str(self))
@@ -671,7 +671,7 @@ def as_pl_op(self, wires: 'Wires') -> 'Operation':
def adjoint(self) -> 'Ry':
return attrs.evolve(self, angle=-self.angle)
- def wire_symbol(self, reg: Optional[Register], idx: Tuple[int, ...] = tuple()) -> 'WireSymbol':
+ def wire_symbol(self, reg: Optional[Register], idx: tuple[int, ...] = tuple()) -> 'WireSymbol':
if reg is None:
return Text('')
return TextBox(str(self))
diff --git a/qualtran/bloqs/basic_gates/s_gate.py b/qualtran/bloqs/basic_gates/s_gate.py
index 6111677a1e..3c9217ee50 100644
--- a/qualtran/bloqs/basic_gates/s_gate.py
+++ b/qualtran/bloqs/basic_gates/s_gate.py
@@ -13,7 +13,7 @@
# limitations under the License.
from functools import cached_property
-from typing import Dict, List, Optional, Tuple, TYPE_CHECKING
+from typing import Optional, TYPE_CHECKING
import attrs
import numpy as np
@@ -59,8 +59,8 @@ def signature(self) -> 'Signature':
return Signature.build(q=1)
def my_tensors(
- self, incoming: Dict[str, 'ConnectionT'], outgoing: Dict[str, 'ConnectionT']
- ) -> List['qtn.Tensor']:
+ self, incoming: dict[str, 'ConnectionT'], outgoing: dict[str, 'ConnectionT']
+ ) -> list['qtn.Tensor']:
import quimb.tensor as qtn
data = _SMATRIX.conj().T if self.is_adjoint else _SMATRIX
@@ -70,7 +70,7 @@ def my_tensors(
def as_cirq_op(
self, qubit_manager: 'cirq.QubitManager', q: 'CirqQuregT' # type:ignore[type-var]
- ) -> Tuple['cirq.Operation', Dict[str, 'CirqQuregT']]: # type:ignore[type-var]
+ ) -> tuple['cirq.Operation', dict[str, 'CirqQuregT']]: # type:ignore[type-var]
import cirq
(q,) = q
@@ -86,7 +86,7 @@ def __str__(self) -> str:
maybe_dag = '†' if self.is_adjoint else ''
return f'S{maybe_dag}'
- def wire_symbol(self, reg: Optional[Register], idx: Tuple[int, ...] = tuple()) -> 'WireSymbol':
+ def wire_symbol(self, reg: Optional[Register], idx: tuple[int, ...] = tuple()) -> 'WireSymbol':
if reg is None:
return Text('')
return TextBox(str(self))
diff --git a/qualtran/bloqs/basic_gates/su2_rotation.py b/qualtran/bloqs/basic_gates/su2_rotation.py
index 91283ba182..5b043a24ff 100644
--- a/qualtran/bloqs/basic_gates/su2_rotation.py
+++ b/qualtran/bloqs/basic_gates/su2_rotation.py
@@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from functools import cached_property
-from typing import Dict, List, Optional, Tuple, TYPE_CHECKING
+from typing import Optional, TYPE_CHECKING
import numpy as np
import sympy
@@ -147,8 +147,8 @@ def from_euler_zxz_angles(
return cls(su2_theta, su2_phi, su2_lambd, su2_global_shift)
def my_tensors(
- self, incoming: Dict[str, 'ConnectionT'], outgoing: Dict[str, 'ConnectionT']
- ) -> List['qtn.Tensor']:
+ self, incoming: dict[str, 'ConnectionT'], outgoing: dict[str, 'ConnectionT']
+ ) -> list['qtn.Tensor']:
import quimb.tensor as qtn
return [
@@ -164,7 +164,7 @@ def _unitary_(self):
return None
return self.rotation_matrix
- def build_composite_bloq(self, bb: 'BloqBuilder', q: 'SoquetT') -> Dict[str, 'SoquetT']:
+ def build_composite_bloq(self, bb: 'BloqBuilder', q: 'SoquetT') -> dict[str, 'SoquetT']:
# TODO implement controlled version, and pass eps/4 to each rotation (incl. global phase)
# https://github.com/quantumlib/Qualtran/issues/1330
bb.add(
@@ -209,7 +209,7 @@ def __str__(self):
return f'SU_2({self.theta},{self.phi},{self.lambd},{self.global_shift})'
return f'SU_2({self.theta:.2f},{self.phi:.2f},{self.lambd:.2f},{self.global_shift:.2f})'
- def wire_symbol(self, reg: Optional[Register], idx: Tuple[int, ...] = tuple()) -> 'WireSymbol':
+ def wire_symbol(self, reg: Optional[Register], idx: tuple[int, ...] = tuple()) -> 'WireSymbol':
if reg is None:
if self.is_symbolic():
return Text(f'({self.theta},{self.phi},{self.lambd},{self.global_shift})')
diff --git a/qualtran/bloqs/basic_gates/swap.py b/qualtran/bloqs/basic_gates/swap.py
index 5c2481f7a1..cdc0b37afd 100644
--- a/qualtran/bloqs/basic_gates/swap.py
+++ b/qualtran/bloqs/basic_gates/swap.py
@@ -12,8 +12,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+from collections.abc import Iterable, Sequence
from functools import cached_property
-from typing import Dict, Iterable, List, Optional, Sequence, Tuple, TYPE_CHECKING, Union
+from typing import Optional, TYPE_CHECKING, Union
import numpy as np
import sympy
@@ -81,7 +82,7 @@ def decompose_bloq(self) -> 'CompositeBloq':
def as_cirq_op(
self, qubit_manager: 'cirq.QubitManager', x: 'CirqQuregT', y: 'CirqQuregT' # type: ignore[type-var]
- ) -> Tuple['cirq.Operation', Dict[str, 'CirqQuregT']]: # type: ignore[type-var]
+ ) -> tuple['cirq.Operation', dict[str, 'CirqQuregT']]: # type: ignore[type-var]
(x,) = x
(y,) = y
import cirq
@@ -94,8 +95,8 @@ def as_pl_op(self, wires: 'Wires') -> 'Operation':
return qml.SWAP(wires=wires)
def my_tensors(
- self, incoming: Dict[str, 'ConnectionT'], outgoing: Dict[str, 'ConnectionT']
- ) -> List['qtn.Tensor']:
+ self, incoming: dict[str, 'ConnectionT'], outgoing: dict[str, 'ConnectionT']
+ ) -> list['qtn.Tensor']:
import quimb.tensor as qtn
matrix = _swap_matrix()
@@ -105,7 +106,7 @@ def my_tensors(
def on_classical_vals(
self, x: 'ClassicalValT', y: 'ClassicalValT'
- ) -> Dict[str, 'ClassicalValT']:
+ ) -> dict[str, 'ClassicalValT']:
return {'x': y, 'y': x}
def adjoint(self) -> 'Bloq':
@@ -175,8 +176,8 @@ def to_clifford_t_circuit(self) -> 'cirq.FrozenCircuit':
return circuit.freeze()
def my_tensors(
- self, incoming: Dict[str, 'ConnectionT'], outgoing: Dict[str, 'ConnectionT']
- ) -> List['qtn.Tensor']:
+ self, incoming: dict[str, 'ConnectionT'], outgoing: dict[str, 'ConnectionT']
+ ) -> list['qtn.Tensor']:
import quimb.tensor as qtn
matrix = _controlled_swap_matrix()
@@ -186,7 +187,7 @@ def my_tensors(
def on_classical_vals(
self, ctrl: 'ClassicalValT', x: 'ClassicalValT', y: 'ClassicalValT'
- ) -> Dict[str, 'ClassicalValT']:
+ ) -> dict[str, 'ClassicalValT']:
if ctrl == 0:
return {'ctrl': 0, 'x': x, 'y': y}
if ctrl == 1:
@@ -201,7 +202,7 @@ def as_pl_op(self, wires: 'Wires') -> 'Operation':
return qml.CSWAP(wires=wires)
- def wire_symbol(self, reg: Optional['Register'], idx: Tuple[int, ...] = ()) -> 'WireSymbol':
+ def wire_symbol(self, reg: Optional['Register'], idx: tuple[int, ...] = ()) -> 'WireSymbol':
if reg is None:
return Text('')
if reg.name == 'ctrl':
@@ -250,7 +251,7 @@ def signature(self) -> 'Signature':
def build_composite_bloq(
self, bb: 'BloqBuilder', x: 'Soquet', y: 'Soquet'
- ) -> Dict[str, 'SoquetT']:
+ ) -> dict[str, 'SoquetT']:
if isinstance(self.bitsize, sympy.Expr):
raise DecomposeTypeError("`bitsize` must be a concrete value.")
@@ -267,10 +268,10 @@ def build_call_graph(self, ssa: 'SympySymbolAllocator') -> 'BloqCountDictT':
def on_classical_vals(
self, x: 'ClassicalValT', y: 'ClassicalValT'
- ) -> Dict[str, 'ClassicalValT']:
+ ) -> dict[str, 'ClassicalValT']:
return {'x': y, 'y': x}
- def wire_symbol(self, reg: Optional['Register'], idx: Tuple[int, ...] = ()) -> 'WireSymbol':
+ def wire_symbol(self, reg: Optional['Register'], idx: tuple[int, ...] = ()) -> 'WireSymbol':
if reg is None:
return Text('')
if reg.name == 'x':
@@ -289,8 +290,8 @@ def get_ctrl_system(self, ctrl_spec: 'CtrlSpec') -> tuple['Bloq', 'AddControlled
cswap = CSwap(self.bitsize)
def adder(
- bb: 'BloqBuilder', ctrl_soqs: Sequence['SoquetT'], in_soqs: Dict[str, 'SoquetT']
- ) -> Tuple[Iterable['SoquetT'], Iterable['SoquetT']]:
+ bb: 'BloqBuilder', ctrl_soqs: Sequence['SoquetT'], in_soqs: dict[str, 'SoquetT']
+ ) -> tuple[Iterable['SoquetT'], Iterable['SoquetT']]:
(ctrl,) = ctrl_soqs
ctrl, x, y = bb.add(cswap, ctrl=ctrl, x=in_soqs['x'], y=in_soqs['y'])
return [ctrl], [x, y]
@@ -344,7 +345,7 @@ def signature(self) -> Signature:
def build_composite_bloq(
self, bb: 'BloqBuilder', ctrl: 'SoquetT', x: 'Soquet', y: 'Soquet'
- ) -> Dict[str, 'SoquetT']:
+ ) -> dict[str, 'SoquetT']:
if isinstance(self.bitsize, sympy.Expr):
raise DecomposeTypeError("`bitsize` must be a concrete value.")
@@ -361,7 +362,7 @@ def build_call_graph(self, ssa: 'SympySymbolAllocator') -> 'BloqCountDictT':
def on_classical_vals(
self, ctrl: 'ClassicalValT', x: 'ClassicalValT', y: 'ClassicalValT'
- ) -> Dict[str, 'ClassicalValT']:
+ ) -> dict[str, 'ClassicalValT']:
if ctrl == 0:
return {'ctrl': 0, 'x': x, 'y': y}
if ctrl == 1:
@@ -386,7 +387,7 @@ def _circuit_diagram_info_(
)
return cirq.CircuitDiagramInfo(("@",) + ("×(x)",) * self.bitsize + ("×(y)",) * self.bitsize)
- def wire_symbol(self, reg: Optional[Register], idx: Tuple[int, ...] = tuple()) -> 'WireSymbol':
+ def wire_symbol(self, reg: Optional[Register], idx: tuple[int, ...] = tuple()) -> 'WireSymbol':
if reg is None:
return Text('')
if reg.name == 'x':
diff --git a/qualtran/bloqs/basic_gates/t_gate.py b/qualtran/bloqs/basic_gates/t_gate.py
index 77cc66bbed..dac98af48e 100644
--- a/qualtran/bloqs/basic_gates/t_gate.py
+++ b/qualtran/bloqs/basic_gates/t_gate.py
@@ -13,7 +13,7 @@
# limitations under the License.
from functools import cached_property
-from typing import Dict, List, Optional, Tuple, TYPE_CHECKING
+from typing import Optional, TYPE_CHECKING
import attrs
import numpy as np
@@ -77,8 +77,8 @@ def signature(self) -> 'Signature':
return Signature.build(q=1)
def my_tensors(
- self, incoming: Dict[str, 'ConnectionT'], outgoing: Dict[str, 'ConnectionT']
- ) -> List['qtn.Tensor']:
+ self, incoming: dict[str, 'ConnectionT'], outgoing: dict[str, 'ConnectionT']
+ ) -> list['qtn.Tensor']:
import quimb.tensor as qtn
data = _TMATRIX.conj().T if self.is_adjoint else _TMATRIX
@@ -91,7 +91,7 @@ def adjoint(self) -> 'Bloq':
def as_cirq_op(
self, qubit_manager: 'cirq.QubitManager', q: 'CirqQuregT' # type: ignore[type-var]
- ) -> Tuple['cirq.Operation', Dict[str, 'CirqQuregT']]: # type: ignore[type-var]
+ ) -> tuple['cirq.Operation', dict[str, 'CirqQuregT']]: # type: ignore[type-var]
import cirq
(q,) = q
@@ -107,7 +107,7 @@ def __str__(self):
maybe_dag = '†' if self.is_adjoint else ''
return f'T{maybe_dag}'
- def wire_symbol(self, reg: Optional[Register], idx: Tuple[int, ...] = tuple()) -> 'WireSymbol':
+ def wire_symbol(self, reg: Optional[Register], idx: tuple[int, ...] = tuple()) -> 'WireSymbol':
if reg is None:
return Text('')
maybe_dag = '†' if self.is_adjoint else ''
diff --git a/qualtran/bloqs/basic_gates/t_gate_test.py b/qualtran/bloqs/basic_gates/t_gate_test.py
index 3bfc107c31..6caff3a717 100644
--- a/qualtran/bloqs/basic_gates/t_gate_test.py
+++ b/qualtran/bloqs/basic_gates/t_gate_test.py
@@ -12,7 +12,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from functools import cached_property
-from typing import Dict
import cirq
import numpy as np
@@ -71,7 +70,7 @@ class TestTStateMaker(Bloq):
def signature(self) -> 'Signature':
return Signature.build(x=1)
- def build_composite_bloq(self, bb: 'BloqBuilder', x: 'SoquetT') -> Dict[str, 'SoquetT']:
+ def build_composite_bloq(self, bb: 'BloqBuilder', x: 'SoquetT') -> dict[str, 'SoquetT']:
x = bb.add(Hadamard(), q=x)
x = bb.add(TGate(), q=x)
return {'x': x}
diff --git a/qualtran/bloqs/basic_gates/toffoli.py b/qualtran/bloqs/basic_gates/toffoli.py
index 65733ee460..9cff9e15f8 100644
--- a/qualtran/bloqs/basic_gates/toffoli.py
+++ b/qualtran/bloqs/basic_gates/toffoli.py
@@ -12,8 +12,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import itertools
+from collections.abc import Iterable, Sequence
from functools import cached_property
-from typing import cast, Dict, Iterable, List, Optional, Sequence, Tuple, TYPE_CHECKING, Union
+from typing import cast, Optional, TYPE_CHECKING, Union
import numpy as np
from attrs import frozen
@@ -71,9 +72,9 @@ def decompose_bloq(self) -> 'CompositeBloq':
def my_tensors(
self,
- incoming: Dict[str, NDArray[Connection]], # type: ignore[type-var]
- outgoing: Dict[str, NDArray[Connection]], # type: ignore[type-var]
- ) -> List['qtn.Tensor']:
+ incoming: dict[str, NDArray[Connection]], # type: ignore[type-var]
+ outgoing: dict[str, NDArray[Connection]], # type: ignore[type-var]
+ ) -> list['qtn.Tensor']:
import quimb.tensor as qtn
from qualtran.bloqs.basic_gates.cnot import XOR
@@ -104,7 +105,7 @@ def my_tensors(
def on_classical_vals(
self, ctrl: NDArray[np.integer], target: 'ClassicalValT'
- ) -> Dict[str, 'ClassicalValT']:
+ ) -> dict[str, 'ClassicalValT']:
assert target in [0, 1]
if ctrl[0] == 1 and ctrl[1] == 1:
target = (target + 1) % 2
@@ -113,7 +114,7 @@ def on_classical_vals(
def as_cirq_op(
self, qubit_manager: 'cirq.QubitManager', ctrl: 'CirqQuregT', target: 'CirqQuregT' # type: ignore[type-var]
- ) -> Tuple[Union['cirq.Operation', None], Dict[str, 'CirqQuregT']]: # type: ignore[type-var]
+ ) -> tuple[Union['cirq.Operation', None], dict[str, 'CirqQuregT']]: # type: ignore[type-var]
import cirq
(trg,) = target
@@ -124,7 +125,7 @@ def as_pl_op(self, wires: 'Wires') -> 'Operation':
return qml.Toffoli(wires=wires)
- def wire_symbol(self, reg: Optional[Register], idx: Tuple[int, ...] = tuple()) -> 'WireSymbol':
+ def wire_symbol(self, reg: Optional[Register], idx: tuple[int, ...] = tuple()) -> 'WireSymbol':
from qualtran.drawing import Circle, ModPlus, Text
if reg is None:
@@ -136,7 +137,7 @@ def wire_symbol(self, reg: Optional[Register], idx: Tuple[int, ...] = tuple()) -
return ModPlus()
raise ValueError(f'Unknown wire symbol register name: {reg.name}')
- def get_ctrl_system(self, ctrl_spec: 'CtrlSpec') -> Tuple['Bloq', 'AddControlledT']:
+ def get_ctrl_system(self, ctrl_spec: 'CtrlSpec') -> tuple['Bloq', 'AddControlledT']:
from qualtran.bloqs.basic_gates import CNOT
from qualtran.bloqs.mcmt import ControlledViaAnd
diff --git a/qualtran/bloqs/basic_gates/x_basis.py b/qualtran/bloqs/basic_gates/x_basis.py
index 5b50f5da8d..c40b1c94ba 100644
--- a/qualtran/bloqs/basic_gates/x_basis.py
+++ b/qualtran/bloqs/basic_gates/x_basis.py
@@ -12,8 +12,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+from collections.abc import Iterable, Sequence
from functools import cached_property
-from typing import Dict, Iterable, List, Optional, Sequence, Tuple, TYPE_CHECKING, Union
+from typing import Optional, TYPE_CHECKING, Union
import numpy as np
from attrs import frozen
@@ -75,8 +76,8 @@ def signature(self) -> 'Signature':
return Signature([Register('q', QBit(), side=Side.RIGHT if self.state else Side.LEFT)])
def my_tensors(
- self, incoming: Dict[str, 'ConnectionT'], outgoing: Dict[str, 'ConnectionT']
- ) -> List['qtn.Tensor']:
+ self, incoming: dict[str, 'ConnectionT'], outgoing: dict[str, 'ConnectionT']
+ ) -> list['qtn.Tensor']:
import quimb.tensor as qtn
side = outgoing if self.state else incoming
@@ -86,7 +87,7 @@ def my_tensors(
def as_cirq_op(
self, qubit_manager: 'cirq.QubitManager', **cirq_quregs: 'CirqQuregT' # type: ignore[type-var]
- ) -> Tuple[Union['cirq.Operation', None], Dict[str, 'CirqQuregT']]: # type: ignore[type-var]
+ ) -> tuple[Union['cirq.Operation', None], dict[str, 'CirqQuregT']]: # type: ignore[type-var]
if not self.state:
raise ValueError(f"There is no Cirq equivalent for {self}")
@@ -106,7 +107,7 @@ def __str__(self) -> str:
return f'|{s}>' if self.state else f'<{s}|'
def wire_symbol(
- self, reg: Optional['Register'], idx: Tuple[int, ...] = tuple()
+ self, reg: Optional['Register'], idx: tuple[int, ...] = tuple()
) -> 'WireSymbol':
if reg is None:
return Text('')
@@ -216,8 +217,8 @@ def adjoint(self) -> 'Bloq':
return self
def my_tensors(
- self, incoming: Dict[str, 'ConnectionT'], outgoing: Dict[str, 'ConnectionT']
- ) -> List['qtn.Tensor']:
+ self, incoming: dict[str, 'ConnectionT'], outgoing: dict[str, 'ConnectionT']
+ ) -> list['qtn.Tensor']:
import quimb.tensor as qtn
return [
@@ -226,7 +227,7 @@ def my_tensors(
)
]
- def get_ctrl_system(self, ctrl_spec: 'CtrlSpec') -> Tuple['Bloq', 'AddControlledT']:
+ def get_ctrl_system(self, ctrl_spec: 'CtrlSpec') -> tuple['Bloq', 'AddControlledT']:
from qualtran.bloqs.basic_gates import CNOT, Toffoli
if ctrl_spec == CtrlSpec():
@@ -237,20 +238,20 @@ def get_ctrl_system(self, ctrl_spec: 'CtrlSpec') -> Tuple['Bloq', 'AddControlled
return super().get_ctrl_system(ctrl_spec)
def add_controlled(
- bb: 'BloqBuilder', ctrl_soqs: Sequence['SoquetT'], in_soqs: Dict[str, 'SoquetT']
- ) -> Tuple[Iterable['SoquetT'], Iterable['SoquetT']]:
+ bb: 'BloqBuilder', ctrl_soqs: Sequence['SoquetT'], in_soqs: dict[str, 'SoquetT']
+ ) -> tuple[Iterable['SoquetT'], Iterable['SoquetT']]:
(ctrl_soq,) = ctrl_soqs
ctrl_soq, target = bb.add(bloq, ctrl=ctrl_soq, target=in_soqs['q'])
return (ctrl_soq,), (target,)
return bloq, add_controlled
- def on_classical_vals(self, q: int) -> Dict[str, 'ClassicalValT']:
+ def on_classical_vals(self, q: int) -> dict[str, 'ClassicalValT']:
return {'q': (q + 1) % 2}
def as_cirq_op(
self, qubit_manager: 'cirq.QubitManager', **cirq_quregs: 'CirqQuregT'
- ) -> Tuple['cirq.Operation', Dict[str, 'CirqQuregT']]:
+ ) -> tuple['cirq.Operation', dict[str, 'CirqQuregT']]:
import cirq
q = cirq_quregs.pop('q')
@@ -263,7 +264,7 @@ def as_pl_op(self, wires: 'Wires') -> 'Operation':
return qml.PauliX(wires=wires)
- def wire_symbol(self, reg: Register, idx: Tuple[int, ...] = tuple()) -> 'WireSymbol':
+ def wire_symbol(self, reg: Register, idx: tuple[int, ...] = tuple()) -> 'WireSymbol':
from qualtran.drawing import ModPlus
if reg is None:
diff --git a/qualtran/bloqs/basic_gates/y_gate.py b/qualtran/bloqs/basic_gates/y_gate.py
index a3b3056796..d9c8c87428 100644
--- a/qualtran/bloqs/basic_gates/y_gate.py
+++ b/qualtran/bloqs/basic_gates/y_gate.py
@@ -12,8 +12,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+from collections.abc import Iterable, Sequence
from functools import cached_property
-from typing import Dict, Iterable, List, Optional, Sequence, Tuple, TYPE_CHECKING, Union
+from typing import Optional, TYPE_CHECKING, Union
import numpy as np
from attrs import frozen
@@ -66,8 +67,8 @@ def adjoint(self) -> 'Bloq':
return self
def my_tensors(
- self, incoming: Dict[str, 'ConnectionT'], outgoing: Dict[str, 'ConnectionT']
- ) -> List['qtn.Tensor']:
+ self, incoming: dict[str, 'ConnectionT'], outgoing: dict[str, 'ConnectionT']
+ ) -> list['qtn.Tensor']:
import quimb.tensor as qtn
return [
@@ -76,15 +77,15 @@ def my_tensors(
)
]
- def get_ctrl_system(self, ctrl_spec: 'CtrlSpec') -> Tuple['Bloq', 'AddControlledT']:
+ def get_ctrl_system(self, ctrl_spec: 'CtrlSpec') -> tuple['Bloq', 'AddControlledT']:
if ctrl_spec != CtrlSpec():
return super().get_ctrl_system(ctrl_spec=ctrl_spec)
bloq = CYGate()
def _add_ctrled(
- bb: 'BloqBuilder', ctrl_soqs: Sequence['SoquetT'], in_soqs: Dict[str, 'SoquetT']
- ) -> Tuple[Iterable['SoquetT'], Iterable['SoquetT']]:
+ bb: 'BloqBuilder', ctrl_soqs: Sequence['SoquetT'], in_soqs: dict[str, 'SoquetT']
+ ) -> tuple[Iterable['SoquetT'], Iterable['SoquetT']]:
(ctrl,) = ctrl_soqs
ctrl, q = bb.add(bloq, ctrl=ctrl, target=in_soqs['q'])
return ((ctrl,), (q,))
@@ -93,7 +94,7 @@ def _add_ctrled(
def as_cirq_op(
self, qubit_manager: 'cirq.QubitManager', q: 'CirqQuregT'
- ) -> Tuple['cirq.Operation', Dict[str, 'CirqQuregT']]:
+ ) -> tuple['cirq.Operation', dict[str, 'CirqQuregT']]:
import cirq
(q,) = q
@@ -105,7 +106,7 @@ def as_pl_op(self, wires: 'Wires') -> 'Operation':
return qml.PauliY(wires=wires)
def wire_symbol(
- self, reg: Optional['Register'], idx: Tuple[int, ...] = tuple()
+ self, reg: Optional['Register'], idx: tuple[int, ...] = tuple()
) -> 'WireSymbol':
if reg is None:
return Text('')
@@ -141,8 +142,8 @@ def adjoint(self) -> 'Bloq':
return self
def my_tensors(
- self, incoming: Dict[str, 'ConnectionT'], outgoing: Dict[str, 'ConnectionT']
- ) -> List['qtn.Tensor']:
+ self, incoming: dict[str, 'ConnectionT'], outgoing: dict[str, 'ConnectionT']
+ ) -> list['qtn.Tensor']:
import quimb.tensor as qtn
unitary = np.eye(4, dtype=np.complex128).reshape((2, 2, 2, 2))
@@ -159,7 +160,7 @@ def my_tensors(
def as_cirq_op(
self, qubit_manager: 'cirq.QubitManager', ctrl: 'CirqQuregT', target: 'CirqQuregT'
- ) -> Tuple[Union['cirq.Operation', None], Dict[str, 'CirqQuregT']]:
+ ) -> tuple[Union['cirq.Operation', None], dict[str, 'CirqQuregT']]:
import cirq
(ctrl,) = ctrl
@@ -175,7 +176,7 @@ def as_pl_op(self, wires: 'Wires') -> 'Operation':
return qml.CY(wires=wires)
def wire_symbol(
- self, reg: Optional['Register'], idx: Tuple[int, ...] = tuple()
+ self, reg: Optional['Register'], idx: tuple[int, ...] = tuple()
) -> 'WireSymbol':
if reg is None:
return Text('')
@@ -185,7 +186,7 @@ def wire_symbol(
return TextBox('Y')
raise ValueError(f"Unknown register {reg}.")
- def get_ctrl_system(self, ctrl_spec: 'CtrlSpec') -> Tuple['Bloq', 'AddControlledT']:
+ def get_ctrl_system(self, ctrl_spec: 'CtrlSpec') -> tuple['Bloq', 'AddControlledT']:
from qualtran.bloqs.mcmt.specialized_ctrl import get_ctrl_system_1bit_cv_from_bloqs
return get_ctrl_system_1bit_cv_from_bloqs(
diff --git a/qualtran/bloqs/basic_gates/z_basis.py b/qualtran/bloqs/basic_gates/z_basis.py
index b5e5a73844..3aa0175703 100644
--- a/qualtran/bloqs/basic_gates/z_basis.py
+++ b/qualtran/bloqs/basic_gates/z_basis.py
@@ -12,19 +12,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+from collections.abc import Iterable, Mapping, Sequence
from functools import cached_property
-from typing import (
- cast,
- Dict,
- Iterable,
- List,
- Mapping,
- Optional,
- Sequence,
- Tuple,
- TYPE_CHECKING,
- Union,
-)
+from typing import cast, Optional, TYPE_CHECKING, Union
import attrs
import numpy as np
@@ -101,8 +91,8 @@ def decompose_bloq(self) -> CompositeBloq:
raise DecomposeTypeError(f"{self} is atomic")
def my_tensors(
- self, incoming: Dict[str, 'ConnectionT'], outgoing: Dict[str, 'ConnectionT']
- ) -> List['qtn.Tensor']:
+ self, incoming: dict[str, 'ConnectionT'], outgoing: dict[str, 'ConnectionT']
+ ) -> list['qtn.Tensor']:
import quimb.tensor as qtn
side = outgoing if self.state else incoming
@@ -110,7 +100,7 @@ def my_tensors(
qtn.Tensor(data=_ONE if self.bit else _ZERO, inds=[(side['q'], 0)], tags=[str(self)])
]
- def on_classical_vals(self, *, q: Optional[int] = None) -> Dict[str, int]:
+ def on_classical_vals(self, *, q: Optional[int] = None) -> dict[str, int]:
"""Return or consume 1 or 0 depending on `self.state` and `self.bit`.
If `self.state`, we return a bit in the `q` register. Otherwise,
@@ -126,7 +116,7 @@ def on_classical_vals(self, *, q: Optional[int] = None) -> Dict[str, int]:
def as_cirq_op(
self, qubit_manager: 'cirq.QubitManager', **cirq_quregs: 'CirqQuregT' # type: ignore[type-var]
- ) -> Tuple[Union['cirq.Operation', None], Dict[str, 'CirqQuregT']]: # type: ignore[type-var]
+ ) -> tuple[Union['cirq.Operation', None], dict[str, 'CirqQuregT']]: # type: ignore[type-var]
if not self.state:
raise ValueError(f"There is no Cirq equivalent for {self}")
@@ -145,7 +135,7 @@ def __str__(self) -> str:
return f'|{s}>' if self.state else f'<{s}|'
def wire_symbol(
- self, reg: Optional['Register'], idx: Tuple[int, ...] = tuple()
+ self, reg: Optional['Register'], idx: tuple[int, ...] = tuple()
) -> 'WireSymbol':
if reg is None:
return Text('')
@@ -258,8 +248,8 @@ def decompose_bloq(self) -> 'CompositeBloq':
raise DecomposeTypeError(f"{self} is atomic")
def my_tensors(
- self, incoming: Dict[str, 'ConnectionT'], outgoing: Dict[str, 'ConnectionT']
- ) -> List['qtn.Tensor']:
+ self, incoming: dict[str, 'ConnectionT'], outgoing: dict[str, 'ConnectionT']
+ ) -> list['qtn.Tensor']:
import quimb.tensor as qtn
return [
@@ -268,7 +258,7 @@ def my_tensors(
)
]
- def get_ctrl_system(self, ctrl_spec: 'CtrlSpec') -> Tuple['Bloq', 'AddControlledT']:
+ def get_ctrl_system(self, ctrl_spec: 'CtrlSpec') -> tuple['Bloq', 'AddControlledT']:
if ctrl_spec != CtrlSpec():
# Delegate to the general superclass behavior
return super().get_ctrl_system(ctrl_spec=ctrl_spec)
@@ -276,8 +266,8 @@ def get_ctrl_system(self, ctrl_spec: 'CtrlSpec') -> Tuple['Bloq', 'AddControlled
bloq = CZ()
def add_controlled(
- bb: 'BloqBuilder', ctrl_soqs: Sequence['SoquetT'], in_soqs: Dict[str, 'SoquetT']
- ) -> Tuple[Iterable['SoquetT'], Iterable['SoquetT']]:
+ bb: 'BloqBuilder', ctrl_soqs: Sequence['SoquetT'], in_soqs: dict[str, 'SoquetT']
+ ) -> tuple[Iterable['SoquetT'], Iterable['SoquetT']]:
(ctrl_soq,) = ctrl_soqs
ctrl_soq, q2 = bb.add(bloq, q1=ctrl_soq, q2=in_soqs['q'])
return (ctrl_soq,), (q2,)
@@ -286,7 +276,7 @@ def add_controlled(
def as_cirq_op(
self, qubit_manager: 'cirq.QubitManager', q: 'CirqQuregT'
- ) -> Tuple['cirq.Operation', Dict[str, 'CirqQuregT']]:
+ ) -> tuple['cirq.Operation', dict[str, 'CirqQuregT']]:
import cirq
(q,) = q
@@ -298,7 +288,7 @@ def as_pl_op(self, wires: 'Wires') -> 'Operation':
return qml.Z(wires=wires)
def wire_symbol(
- self, reg: Optional['Register'], idx: Tuple[int, ...] = tuple()
+ self, reg: Optional['Register'], idx: tuple[int, ...] = tuple()
) -> 'WireSymbol':
if reg is None:
return Text('')
@@ -335,8 +325,8 @@ def adjoint(self) -> 'Bloq':
return self
def my_tensors(
- self, incoming: Dict[str, 'ConnectionT'], outgoing: Dict[str, 'ConnectionT']
- ) -> List['qtn.Tensor']:
+ self, incoming: dict[str, 'ConnectionT'], outgoing: dict[str, 'ConnectionT']
+ ) -> list['qtn.Tensor']:
import quimb.tensor as qtn
unitary = np.diag(np.array([1, 1, 1, -1], dtype=np.complex128)).reshape((2, 2, 2, 2))
@@ -346,7 +336,7 @@ def my_tensors(
def as_cirq_op(
self, qubit_manager: 'cirq.QubitManager', q1: 'CirqQuregT', q2: 'CirqQuregT'
- ) -> Tuple['cirq.Operation', Dict[str, 'CirqQuregT']]:
+ ) -> tuple['cirq.Operation', dict[str, 'CirqQuregT']]:
import cirq
(q1,) = q1
@@ -358,21 +348,21 @@ def as_pl_op(self, wires: 'Wires') -> 'Operation':
return qml.CZ(wires=wires)
- def wire_symbol(self, reg: Optional[Register], idx: Tuple[int, ...] = tuple()) -> 'WireSymbol':
+ def wire_symbol(self, reg: Optional[Register], idx: tuple[int, ...] = tuple()) -> 'WireSymbol':
if reg is None:
return Text('')
if reg.name == 'q1' or reg.name == 'q2':
return Circle()
raise ValueError(f'Unknown wire symbol register name: {reg.name}')
- def get_ctrl_system(self, ctrl_spec: 'CtrlSpec') -> Tuple['Bloq', 'AddControlledT']:
+ def get_ctrl_system(self, ctrl_spec: 'CtrlSpec') -> tuple['Bloq', 'AddControlledT']:
from qualtran.bloqs.mcmt.specialized_ctrl import get_ctrl_system_1bit_cv_from_bloqs
return get_ctrl_system_1bit_cv_from_bloqs(
self, ctrl_spec, current_ctrl_bit=1, bloq_with_ctrl=self, ctrl_reg_name='q1'
)
- def on_classical_vals(self, **vals: 'ClassicalValT') -> Dict[str, 'ClassicalValT']:
+ def on_classical_vals(self, **vals: 'ClassicalValT') -> dict[str, 'ClassicalValT']:
# Diagonal, but causes phases: see `basis_state_phase`
return vals
@@ -410,8 +400,8 @@ def on_classical_vals(self, q: int) -> Mapping[str, 'ClassicalValRetT']:
return {'c': q}
def my_tensors(
- self, incoming: Dict[str, 'ConnectionT'], outgoing: Dict[str, 'ConnectionT']
- ) -> List['qtn.Tensor']:
+ self, incoming: dict[str, 'ConnectionT'], outgoing: dict[str, 'ConnectionT']
+ ) -> list['qtn.Tensor']:
import quimb.tensor as qtn
from qualtran.simulation.tensor import DiscardInd
@@ -469,7 +459,7 @@ def signature(self) -> Signature:
return Signature([Register('val', self.dtype, side=side)])
@staticmethod
- def _build_composite_state(bb: 'BloqBuilder', bits: NDArray[np.uint8]) -> Dict[str, 'SoquetT']:
+ def _build_composite_state(bb: 'BloqBuilder', bits: NDArray[np.uint8]) -> dict[str, 'SoquetT']:
states = [ZeroState(), OneState()]
xs = []
for bit in bits:
@@ -482,14 +472,14 @@ def _build_composite_state(bb: 'BloqBuilder', bits: NDArray[np.uint8]) -> Dict[s
@staticmethod
def _build_composite_effect(
bb: 'BloqBuilder', val: 'Soquet', bits: NDArray[np.uint8]
- ) -> Dict[str, 'SoquetT']:
+ ) -> dict[str, 'SoquetT']:
xs = bb.split(val)
effects = [ZeroEffect(), OneEffect()]
for i, bit in enumerate(bits):
bb.add(effects[bit], q=xs[i])
return {}
- def build_composite_bloq(self, bb: 'BloqBuilder', **val: 'SoquetT') -> Dict[str, 'SoquetT']:
+ def build_composite_bloq(self, bb: 'BloqBuilder', **val: 'SoquetT') -> dict[str, 'SoquetT']:
if isinstance(self.bitsize, sympy.Expr):
raise DecomposeTypeError(f'Symbolic bitsize {self.bitsize} not supported')
bits = np.asarray(self.dtype.to_bits(self.val))
@@ -499,7 +489,7 @@ def build_composite_bloq(self, bb: 'BloqBuilder', **val: 'SoquetT') -> Dict[str,
else:
return self._build_composite_effect(bb, cast(Soquet, val['val']), bits)
- def on_classical_vals(self, *, val: Optional[int] = None) -> Dict[str, Union[int, sympy.Expr]]:
+ def on_classical_vals(self, *, val: Optional[int] = None) -> dict[str, Union[int, sympy.Expr]]:
if self.state:
assert val is None
return {'val': self.val}
@@ -514,7 +504,7 @@ def __str__(self) -> str:
s = f'{self.val}'
return f'|{s}>' if self.state else f'<{s}|'
- def wire_symbol(self, reg: Optional[Register], idx: Tuple[int, ...] = tuple()) -> 'WireSymbol':
+ def wire_symbol(self, reg: Optional[Register], idx: tuple[int, ...] = tuple()) -> 'WireSymbol':
if reg is None:
return Text('')
diff --git a/qualtran/bloqs/block_encoding/chebyshev_polynomial.py b/qualtran/bloqs/block_encoding/chebyshev_polynomial.py
index 327d0ace4b..38728f98b9 100644
--- a/qualtran/bloqs/block_encoding/chebyshev_polynomial.py
+++ b/qualtran/bloqs/block_encoding/chebyshev_polynomial.py
@@ -13,7 +13,7 @@
# limitations under the License.
from collections import Counter
from functools import cached_property
-from typing import Dict, Tuple, TYPE_CHECKING, Union
+from typing import TYPE_CHECKING, Union
import attrs
import numpy as np
@@ -123,7 +123,7 @@ def reflection_bloq(self):
bitsizes=(self.ancilla_bitsize,), global_phase=-1
)
- def build_composite_bloq(self, bb: BloqBuilder, **soqs: SoquetT) -> Dict[str, SoquetT]:
+ def build_composite_bloq(self, bb: BloqBuilder, **soqs: SoquetT) -> dict[str, SoquetT]:
if is_symbolic(self.ancilla_bitsize):
raise DecomposeTypeError(f"Cannot decompose symbolic {self=}")
for _ in range(self.order // 2):
@@ -233,15 +233,15 @@ def epsilon(self) -> SymbolicFloat:
return self.linear_combination.epsilon
@property
- def target_registers(self) -> Tuple[Register, ...]:
+ def target_registers(self) -> tuple[Register, ...]:
return tuple(self.signature.rights())
@property
- def junk_registers(self) -> Tuple[Register, ...]:
+ def junk_registers(self) -> tuple[Register, ...]:
return (self.signature.get_right("resource"),) if self.resource_bitsize > 0 else ()
@property
- def selection_registers(self) -> Tuple[Register, ...]:
+ def selection_registers(self) -> tuple[Register, ...]:
return (self.signature.get_right("ancilla"),) if self.ancilla_bitsize > 0 else ()
@property
@@ -264,7 +264,7 @@ def linear_combination(self) -> Union[LinearCombination, ChebyshevPolynomial]:
self.lambd_bits,
)
- def build_composite_bloq(self, bb: BloqBuilder, **soqs: SoquetT) -> Dict[str, SoquetT]:
+ def build_composite_bloq(self, bb: BloqBuilder, **soqs: SoquetT) -> dict[str, SoquetT]:
return bb.add_d(self.linear_combination, **soqs)
def __str__(self) -> str:
diff --git a/qualtran/bloqs/block_encoding/chebyshev_polynomial_test.py b/qualtran/bloqs/block_encoding/chebyshev_polynomial_test.py
index 2bc29ea862..9ace3a038b 100644
--- a/qualtran/bloqs/block_encoding/chebyshev_polynomial_test.py
+++ b/qualtran/bloqs/block_encoding/chebyshev_polynomial_test.py
@@ -13,7 +13,6 @@
# limitations under the License.
from functools import cached_property
-from typing import Dict, Tuple
import numpy as np
import pytest
@@ -180,7 +179,7 @@ class TestBlockEncoding(BlockEncoding):
"""Instance of `BlockEncoding` to block encode a matrix with one system qubit by adding one
ancilla qubit and one resource qubit."""
- matrix: Tuple[Tuple[complex, ...], ...] = field(
+ matrix: tuple[tuple[complex, ...], ...] = field(
converter=lambda mat: tuple(tuple(row) for row in mat)
)
alpha: SymbolicFloat = 1
@@ -210,7 +209,7 @@ def signal_state(self) -> BlackBoxPrepare:
def build_composite_bloq(
self, bb: BloqBuilder, system: Soquet, ancilla: Soquet, resource: Soquet
- ) -> Dict[str, SoquetT]:
+ ) -> dict[str, SoquetT]:
bits = bb.join(np.array([system, ancilla, resource]))
bits = bb.add(MatrixGate(3, self.matrix, atol=3e-8), q=bits)
system, ancilla, resource = bb.split(bits)
diff --git a/qualtran/bloqs/block_encoding/lcu_block_encoding.py b/qualtran/bloqs/block_encoding/lcu_block_encoding.py
index 679ac7964b..1996a4138e 100644
--- a/qualtran/bloqs/block_encoding/lcu_block_encoding.py
+++ b/qualtran/bloqs/block_encoding/lcu_block_encoding.py
@@ -13,7 +13,7 @@
# limitations under the License.
from functools import cached_property
-from typing import Dict, Optional, Tuple, Union
+from typing import Optional, Union
import attrs
@@ -40,7 +40,7 @@
from qualtran.symbolics import SymbolicFloat
-def _total_bits(registers: Union[Tuple[Register, ...], Signature]) -> int:
+def _total_bits(registers: Union[tuple[Register, ...], Signature]) -> int:
"""Get the bitsize of a collection of registers"""
return sum(r.total_bits() for r in registers)
@@ -111,15 +111,15 @@ def system_bitsize(self) -> int:
return _total_bits(self.select.target_registers)
@cached_property
- def selection_registers(self) -> Tuple[Register, ...]:
+ def selection_registers(self) -> tuple[Register, ...]:
return self.select.selection_registers
@cached_property
- def junk_registers(self) -> Tuple[Register, ...]:
+ def junk_registers(self) -> tuple[Register, ...]:
return ()
@cached_property
- def target_registers(self) -> Tuple[Register, ...]:
+ def target_registers(self) -> tuple[Register, ...]:
return self.select.target_registers
@property
@@ -139,12 +139,12 @@ def signature(self) -> Signature:
def signal_state(self) -> Union[BlackBoxPrepare, PrepareOracle]:
return self.prepare
- def build_composite_bloq(self, bb: 'BloqBuilder', **soqs: SoquetT) -> Dict[str, 'SoquetT']:
+ def build_composite_bloq(self, bb: 'BloqBuilder', **soqs: SoquetT) -> dict[str, 'SoquetT']:
select_reg = {reg.name: soqs[reg.name] for reg in self.select.signature}
soqs |= bb.add_d(self.select, **select_reg)
return soqs
- def wire_symbol(self, reg: Optional[Register], idx: Tuple[int, ...] = tuple()) -> 'WireSymbol':
+ def wire_symbol(self, reg: Optional[Register], idx: tuple[int, ...] = tuple()) -> 'WireSymbol':
if reg is None:
return Text('')
else:
@@ -205,7 +205,7 @@ class LCUBlockEncoding(BlockEncoding):
control_val: Optional[int] = None
@cached_property
- def control_registers(self) -> Tuple[Register, ...]:
+ def control_registers(self) -> tuple[Register, ...]:
return () if self.control_val is None else (Register('ctrl', QBit()),)
@cached_property
@@ -221,15 +221,15 @@ def system_bitsize(self) -> int:
return _total_bits(self.select.target_registers)
@cached_property
- def selection_registers(self) -> Tuple[Register, ...]:
+ def selection_registers(self) -> tuple[Register, ...]:
return self.prepare.selection_registers
@cached_property
- def junk_registers(self) -> Tuple[Register, ...]:
+ def junk_registers(self) -> tuple[Register, ...]:
return tuple(reg for reg in self.prepare.junk_registers if reg.side == Side.THRU)
@cached_property
- def target_registers(self) -> Tuple[Register, ...]:
+ def target_registers(self) -> tuple[Register, ...]:
return self.select.target_registers
@property
@@ -257,8 +257,8 @@ def signature(self) -> Signature:
def signal_state(self) -> Union[BlackBoxPrepare, PrepareOracle]:
return PrepareIdentity(self.selection_registers)
- def build_composite_bloq(self, bb: 'BloqBuilder', **soqs: SoquetT) -> Dict[str, 'SoquetT']:
- def _extract_soqs(bloq: Bloq) -> Dict[str, 'SoquetT']:
+ def build_composite_bloq(self, bb: 'BloqBuilder', **soqs: SoquetT) -> dict[str, 'SoquetT']:
+ def _extract_soqs(bloq: Bloq) -> dict[str, 'SoquetT']:
return {reg.name: soqs.pop(reg.name) for reg in bloq.signature.lefts()}
soqs |= bb.add_d(self.prepare, **_extract_soqs(self.prepare))
@@ -276,7 +276,7 @@ def _extract_soqs(bloq: Bloq) -> Dict[str, 'SoquetT']:
return soqs
- def wire_symbol(self, reg: Optional[Register], idx: Tuple[int, ...] = tuple()) -> 'WireSymbol':
+ def wire_symbol(self, reg: Optional[Register], idx: tuple[int, ...] = tuple()) -> 'WireSymbol':
if reg is None:
return Text('')
if reg.name == 'control':
diff --git a/qualtran/bloqs/block_encoding/linear_combination.py b/qualtran/bloqs/block_encoding/linear_combination.py
index 48c93ef48d..37890f5b80 100644
--- a/qualtran/bloqs/block_encoding/linear_combination.py
+++ b/qualtran/bloqs/block_encoding/linear_combination.py
@@ -13,7 +13,7 @@
# limitations under the License.
from functools import cached_property
-from typing import cast, Dict, List, Optional, Tuple, Union
+from typing import cast, Optional, Union
import numpy as np
from attrs import evolve, field, frozen, validators
@@ -83,10 +83,10 @@ class LinearCombination(BlockEncoding):
Dalzell et al. (2023). Ch. 10.2.
"""
- _block_encodings: Tuple[BlockEncoding, ...] = field(
+ _block_encodings: tuple[BlockEncoding, ...] = field(
converter=lambda x: x if isinstance(x, tuple) else tuple(x), validator=validators.min_len(2)
)
- _lambd: Tuple[float, ...] = field(converter=lambda x: x if isinstance(x, tuple) else tuple(x))
+ _lambd: tuple[float, ...] = field(converter=lambda x: x if isinstance(x, tuple) else tuple(x))
lambd_bits: SymbolicInt
_prepare: Optional[BlackBoxPrepare] = None
@@ -121,7 +121,7 @@ def __attrs_post_init__(self):
)
@classmethod
- def of_terms(cls, *terms: Tuple[float, BlockEncoding], lambd_bits: SymbolicInt = 1) -> Self:
+ def of_terms(cls, *terms: tuple[float, BlockEncoding], lambd_bits: SymbolicInt = 1) -> Self:
"""Construct a `LinearCombination` from pairs of (coefficient, block encoding)."""
return cls(tuple(t[1] for t in terms), tuple(t[0] for t in terms), lambd_bits)
@@ -232,11 +232,11 @@ def select(self) -> BlackBoxSelect:
assert not is_symbolic(be.ancilla_bitsize)
assert not is_symbolic(be.resource_bitsize)
- partitions: List[Tuple[Register, List[Union[str, Unused]]]] = [
+ partitions: list[tuple[Register, list[Union[str, Unused]]]] = [
(Register("system", QAny(self.system_bitsize)), ["system"])
]
if self.be_ancilla_bitsize > 0:
- regs: List[Union[str, Unused]] = []
+ regs: list[Union[str, Unused]] = []
if be.ancilla_bitsize > 0:
regs.append("ancilla")
if self.be_ancilla_bitsize > be.ancilla_bitsize:
@@ -259,7 +259,7 @@ def select(self) -> BlackBoxSelect:
def build_composite_bloq(
self, bb: BloqBuilder, system: Soquet, ancilla: Soquet, **soqs: SoquetT
- ) -> Dict[str, SoquetT]:
+ ) -> dict[str, SoquetT]:
if (
is_symbolic(self.system_bitsize)
or is_symbolic(self.ancilla_bitsize)
@@ -272,7 +272,7 @@ def build_composite_bloq(
assert not is_symbolic(self.select.system_bitsize)
# partition ancilla register
- be_system_soqs: Dict[str, SoquetT] = {"system": system}
+ be_system_soqs: dict[str, SoquetT] = {"system": system}
anc_regs = [Register("selection", QAny(self.prepare.selection_bitsize))]
if self.be_ancilla_bitsize > 0:
anc_regs.append(Register("ancilla", QAny(self.be_ancilla_bitsize)))
@@ -331,7 +331,7 @@ def build_composite_bloq(
# partition system register of Select into system, ancilla, resource of block encoding
be_soqs = bb.add_d(be_part, x=select_out_soqs.pop("system"))
- out: Dict[str, SoquetT] = {"system": be_soqs.pop("system")}
+ out: dict[str, SoquetT] = {"system": be_soqs.pop("system")}
if self.is_controlled:
out["ctrl"] = select_out_soqs.pop("ctrl")
diff --git a/qualtran/bloqs/block_encoding/phase.py b/qualtran/bloqs/block_encoding/phase.py
index d7e6b03237..f6cc0955af 100644
--- a/qualtran/bloqs/block_encoding/phase.py
+++ b/qualtran/bloqs/block_encoding/phase.py
@@ -13,7 +13,6 @@
# limitations under the License.
from functools import cached_property
-from typing import Dict
from attrs import frozen
@@ -82,7 +81,7 @@ def signal_state(self) -> BlackBoxPrepare:
def build_call_graph(self, ssa: SympySymbolAllocator) -> BloqCountDictT:
return {self.block_encoding: 1, GlobalPhase(exponent=self.phi, eps=self.eps): 1}
- def build_composite_bloq(self, bb: BloqBuilder, **soqs: SoquetT) -> Dict[str, SoquetT]:
+ def build_composite_bloq(self, bb: BloqBuilder, **soqs: SoquetT) -> dict[str, SoquetT]:
bb.add(GlobalPhase(exponent=self.phi, eps=self.eps))
return bb.add_d(self.block_encoding, **soqs)
diff --git a/qualtran/bloqs/block_encoding/product.py b/qualtran/bloqs/block_encoding/product.py
index 6a28762a12..3879c27ee9 100644
--- a/qualtran/bloqs/block_encoding/product.py
+++ b/qualtran/bloqs/block_encoding/product.py
@@ -13,8 +13,9 @@
# limitations under the License.
from collections import Counter
+from collections.abc import Sequence
from functools import cached_property
-from typing import cast, Dict, List, Sequence, Tuple, Union
+from typing import cast, Union
from attrs import field, frozen, validators
from numpy.typing import NDArray
@@ -85,7 +86,7 @@ class Product(BlockEncoding):
Dalzell et al. (2023). Ch. 10.2.
"""
- block_encodings: Tuple[BlockEncoding, ...] = field(
+ block_encodings: tuple[BlockEncoding, ...] = field(
converter=lambda x: x if isinstance(x, tuple) else tuple(x), validator=validators.min_len(1)
)
@@ -151,11 +152,11 @@ def constituents(self) -> Sequence[Bloq]:
anc_bits = self.ancilla_bitsize - (n - 1)
ret = []
for u in reversed(self.block_encodings):
- partition: List[Tuple[Register, List[Union[str, Unused]]]] = [
+ partition: list[tuple[Register, list[Union[str, Unused]]]] = [
(Register("system", dtype=QAny(u.system_bitsize)), ["system"])
]
if is_symbolic(u.ancilla_bitsize) or u.ancilla_bitsize > 0:
- regs: List[Union[str, Unused]] = ["ancilla"]
+ regs: list[Union[str, Unused]] = ["ancilla"]
if (
is_symbolic(anc_bits)
or is_symbolic(u.ancilla_bitsize)
@@ -184,7 +185,7 @@ def build_call_graph(self, ssa: SympySymbolAllocator) -> BloqCountDictT:
def build_composite_bloq(
self, bb: BloqBuilder, system: SoquetT, **soqs: SoquetT
- ) -> Dict[str, SoquetT]:
+ ) -> dict[str, SoquetT]:
if (
is_symbolic(self.system_bitsize)
or is_symbolic(self.ancilla_bitsize)
@@ -242,7 +243,7 @@ def build_composite_bloq(
if self.resource_bitsize > 0:
out["resource"] = res_soq
if self.ancilla_bitsize > 0:
- anc_soqs: Dict[str, SoquetT] = dict()
+ anc_soqs: dict[str, SoquetT] = dict()
if n - 1 > 0:
anc_soqs["flag_bits"] = flag_bits_soq
if anc_bits > 0:
diff --git a/qualtran/bloqs/block_encoding/product_test.py b/qualtran/bloqs/block_encoding/product_test.py
index 389ffb997e..fc98b83929 100644
--- a/qualtran/bloqs/block_encoding/product_test.py
+++ b/qualtran/bloqs/block_encoding/product_test.py
@@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-from typing import cast, Tuple
+from typing import cast
import cirq
import numpy as np
@@ -71,11 +71,11 @@ def test_product_signature():
@frozen
class TestPrepareOracle(PrepareOracle):
@property
- def selection_registers(self) -> Tuple[Register, ...]:
+ def selection_registers(self) -> tuple[Register, ...]:
return (Register('z', QBit()),)
@property
- def junk_registers(self) -> Tuple[Register, ...]:
+ def junk_registers(self) -> tuple[Register, ...]:
return (Register('a', QAny(5)),)
diff --git a/qualtran/bloqs/block_encoding/rewrites.py b/qualtran/bloqs/block_encoding/rewrites.py
index 209c5aad53..028e3068e7 100644
--- a/qualtran/bloqs/block_encoding/rewrites.py
+++ b/qualtran/bloqs/block_encoding/rewrites.py
@@ -15,7 +15,6 @@
r"""Rewrite rules to optimize the construction of block encodings."""
from collections import defaultdict
-from typing import Dict
from qualtran.bloqs.block_encoding import (
BlockEncoding,
@@ -57,7 +56,7 @@ def collect_like_terms(x: BlockEncoding) -> BlockEncoding:
if isinstance(x, Product):
return Product(tuple(collect_like_terms(y) for y in x.block_encodings))
if isinstance(x, LinearCombination):
- block_encodings: Dict[BlockEncoding, float] = defaultdict(float)
+ block_encodings: dict[BlockEncoding, float] = defaultdict(float)
terms = tuple(collect_like_terms(y) for y in x._block_encodings)
lambd_bits = x.lambd_bits
for y, l in zip(terms, x._lambd):
diff --git a/qualtran/bloqs/block_encoding/sparse_matrix.py b/qualtran/bloqs/block_encoding/sparse_matrix.py
index 7c126c77a9..dc461a50cc 100644
--- a/qualtran/bloqs/block_encoding/sparse_matrix.py
+++ b/qualtran/bloqs/block_encoding/sparse_matrix.py
@@ -13,8 +13,8 @@
# limitations under the License.
import abc
+from collections.abc import Iterable
from functools import cached_property
-from typing import Dict, Iterable, Tuple
import numpy as np
import sympy
@@ -233,7 +233,7 @@ def build_call_graph(self, ssa: SympySymbolAllocator) -> BloqCountDictT:
def build_composite_bloq(
self, bb: BloqBuilder, system: SoquetT, ancilla: SoquetT
- ) -> Dict[str, SoquetT]:
+ ) -> dict[str, SoquetT]:
if is_symbolic(self.system_bitsize) or is_symbolic(self.row_oracle.num_nonzero):
raise DecomposeTypeError(f"Cannot decompose symbolic {self=}")
@@ -281,7 +281,7 @@ def _num_nonzero_default(self):
def num_nonzero(self) -> SymbolicInt:
return self._num_nonzero
- def build_composite_bloq(self, bb: BloqBuilder, **soqs: SoquetT) -> Dict[str, SoquetT]:
+ def build_composite_bloq(self, bb: BloqBuilder, **soqs: SoquetT) -> dict[str, SoquetT]:
# the l-th non-zero entry is at position l, so do nothing
return soqs
@@ -319,7 +319,7 @@ def __attrs_post_init__(self):
f"bandsize={self.bandsize} too large for system_bitsize={self.system_bitsize}"
)
- def call_classically(self, l: ClassicalValT, i: ClassicalValT) -> Tuple[ClassicalValT, ...]:
+ def call_classically(self, l: ClassicalValT, i: ClassicalValT) -> tuple[ClassicalValT, ...]:
if (
is_symbolic(self.bandsize)
or is_symbolic(self.system_bitsize)
@@ -338,7 +338,7 @@ def build_call_graph(self, ssa: 'SympySymbolAllocator') -> BloqCountDictT:
AddK(QInt(self.system_bitsize), -self.bandsize): 1,
}
- def build_composite_bloq(self, bb: BloqBuilder, l: SoquetT, i: SoquetT) -> Dict[str, SoquetT]:
+ def build_composite_bloq(self, bb: BloqBuilder, l: SoquetT, i: SoquetT) -> dict[str, SoquetT]:
if is_symbolic(self.system_bitsize) or is_symbolic(self.bandsize):
raise DecomposeTypeError(f"Cannot decompose symbolic {self=}")
@@ -357,7 +357,7 @@ class UniformEntryOracle(EntryOracle):
def build_composite_bloq(
self, bb: BloqBuilder, q: Soquet, **soqs: SoquetT
- ) -> Dict[str, SoquetT]:
+ ) -> dict[str, SoquetT]:
# Either Rx or Ry work here; Rx would induce a phase on the subspace with non-zero ancilla
# See https://arxiv.org/abs/2302.10949 for reference that uses Rx
soqs["q"] = bb.add(Ry(2 * np.arccos(self.entry)), q=q)
@@ -404,7 +404,7 @@ def __attrs_post_init__(self):
def build_composite_bloq(
self, bb: BloqBuilder, q: SoquetT, i: SoquetT, j: SoquetT
- ) -> Dict[str, SoquetT]:
+ ) -> dict[str, SoquetT]:
if is_symbolic(self.entry_bitsize):
raise DecomposeTypeError(f"Cannot decompose symbolic {self=}")
# load from QROM
diff --git a/qualtran/bloqs/block_encoding/tensor_product.py b/qualtran/bloqs/block_encoding/tensor_product.py
index d1a01a8ecc..3efa7dff71 100644
--- a/qualtran/bloqs/block_encoding/tensor_product.py
+++ b/qualtran/bloqs/block_encoding/tensor_product.py
@@ -14,7 +14,6 @@
from collections import Counter
from functools import cached_property
-from typing import Dict, Tuple
from attrs import evolve, field, frozen, validators
from typing_extensions import Self
@@ -61,7 +60,7 @@ class TensorProduct(BlockEncoding):
[Quantum algorithms: A survey of applications and end-to-end complexities](https://arxiv.org/abs/2310.03011). Dalzell et al. (2023). Ch. 10.2.
"""
- block_encodings: Tuple[BlockEncoding, ...] = field(
+ block_encodings: tuple[BlockEncoding, ...] = field(
converter=lambda x: x if isinstance(x, tuple) else tuple(x), validator=validators.min_len(1)
)
@@ -111,7 +110,7 @@ def build_call_graph(self, ssa: SympySymbolAllocator) -> BloqCountDictT:
def build_composite_bloq(
self, bb: BloqBuilder, system: SoquetT, **soqs: SoquetT
- ) -> Dict[str, SoquetT]:
+ ) -> dict[str, SoquetT]:
if (
is_symbolic(self.system_bitsize)
or is_symbolic(self.ancilla_bitsize)
diff --git a/qualtran/bloqs/block_encoding/unitary.py b/qualtran/bloqs/block_encoding/unitary.py
index bbcff63d78..1cd795a10e 100644
--- a/qualtran/bloqs/block_encoding/unitary.py
+++ b/qualtran/bloqs/block_encoding/unitary.py
@@ -13,7 +13,6 @@
# limitations under the License.
from functools import cached_property
-from typing import Dict
from attrs import frozen
@@ -79,7 +78,7 @@ def build_call_graph(self, ssa: SympySymbolAllocator) -> BloqCountDictT:
def build_composite_bloq(
self, bb: BloqBuilder, system: SoquetT, **soqs: SoquetT
- ) -> Dict[str, SoquetT]:
+ ) -> dict[str, SoquetT]:
partitions = [(self.signature.get_left("system"), tuple(r.name for r in self.U.signature))]
return {
"system": bb.add_and_partition(self.U, partitions=partitions, system=system),
diff --git a/qualtran/bloqs/bookkeeping/_bookkeeping_bloq.py b/qualtran/bloqs/bookkeeping/_bookkeeping_bloq.py
index 32b9b74984..3217fc57eb 100644
--- a/qualtran/bloqs/bookkeeping/_bookkeeping_bloq.py
+++ b/qualtran/bloqs/bookkeeping/_bookkeeping_bloq.py
@@ -13,7 +13,8 @@
# limitations under the License.
import abc
-from typing import Dict, Iterable, Optional, Sequence, Tuple, TYPE_CHECKING
+from collections.abc import Iterable, Sequence
+from typing import Optional, TYPE_CHECKING
from qualtran import Bloq, BloqBuilder, SoquetT
@@ -32,10 +33,10 @@ class _BookkeepingBloq(Bloq, metaclass=abc.ABCMeta):
def get_ctrl_system(
self, ctrl_spec: Optional['CtrlSpec'] = None
- ) -> Tuple['Bloq', 'AddControlledT']:
+ ) -> tuple['Bloq', 'AddControlledT']:
def add_controlled(
- bb: 'BloqBuilder', ctrl_soqs: Sequence['SoquetT'], in_soqs: Dict[str, 'SoquetT']
- ) -> Tuple[Iterable['SoquetT'], Iterable['SoquetT']]:
+ bb: 'BloqBuilder', ctrl_soqs: Sequence['SoquetT'], in_soqs: dict[str, 'SoquetT']
+ ) -> tuple[Iterable['SoquetT'], Iterable['SoquetT']]:
# ignore `ctrl_soq` and pass it through for bookkeeping operation.
out_soqs = bb.add_t(self, **in_soqs)
return ctrl_soqs, out_soqs
diff --git a/qualtran/bloqs/bookkeeping/allocate.py b/qualtran/bloqs/bookkeeping/allocate.py
index e459095285..74df4525be 100644
--- a/qualtran/bloqs/bookkeeping/allocate.py
+++ b/qualtran/bloqs/bookkeeping/allocate.py
@@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from functools import cached_property
-from typing import Dict, List, Tuple, TYPE_CHECKING, Union
+from typing import TYPE_CHECKING, Union
import numpy as np
import sympy
@@ -70,12 +70,12 @@ def adjoint(self) -> 'Bloq':
return Free(self.dtype, self.dirty)
- def on_classical_vals(self) -> Dict[str, int]:
+ def on_classical_vals(self) -> dict[str, int]:
return {'reg': self.dtype.from_bits([0] * self.dtype.num_qubits)}
def my_tensors(
- self, incoming: Dict[str, 'ConnectionT'], outgoing: Dict[str, 'ConnectionT']
- ) -> List['qtn.Tensor']:
+ self, incoming: dict[str, 'ConnectionT'], outgoing: dict[str, 'ConnectionT']
+ ) -> list['qtn.Tensor']:
import quimb.tensor as qtn
from qualtran.bloqs.basic_gates.z_basis import _ZERO
@@ -85,7 +85,7 @@ def my_tensors(
for i in range(self.dtype.num_qubits)
]
- def wire_symbol(self, reg: Register, idx: Tuple[int, ...] = tuple()) -> 'WireSymbol':
+ def wire_symbol(self, reg: Register, idx: tuple[int, ...] = tuple()) -> 'WireSymbol':
if reg is None:
return Text('')
assert reg.name == 'reg'
@@ -93,7 +93,7 @@ def wire_symbol(self, reg: Register, idx: Tuple[int, ...] = tuple()) -> 'WireSym
def as_cirq_op(
self, qubit_manager: 'cirq.QubitManager'
- ) -> Tuple[Union['cirq.Operation', None], Dict[str, 'CirqQuregT']]:
+ ) -> tuple[Union['cirq.Operation', None], dict[str, 'CirqQuregT']]:
shape = (*self.signature[0].shape, self.signature[0].bitsize)
qubits = (
qubit_manager.qborrow(self.signature.n_qubits())
diff --git a/qualtran/bloqs/bookkeeping/always.py b/qualtran/bloqs/bookkeeping/always.py
index 070e34eaf9..c297bc8c62 100644
--- a/qualtran/bloqs/bookkeeping/always.py
+++ b/qualtran/bloqs/bookkeeping/always.py
@@ -11,7 +11,8 @@
# 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.
-from typing import Iterable, Optional, Sequence
+from collections.abc import Iterable, Sequence
+from typing import Optional
import attrs
diff --git a/qualtran/bloqs/bookkeeping/auto_partition.py b/qualtran/bloqs/bookkeeping/auto_partition.py
index 93cddd9cbb..cc65abe662 100644
--- a/qualtran/bloqs/bookkeeping/auto_partition.py
+++ b/qualtran/bloqs/bookkeeping/auto_partition.py
@@ -11,9 +11,10 @@
# 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.
+from collections.abc import Sequence
from functools import cached_property
from itertools import chain
-from typing import Dict, Sequence, Tuple, Union
+from typing import Union
from attrs import evolve, field, frozen
@@ -70,7 +71,7 @@ class AutoPartition(Bloq):
"""
bloq: Bloq
- partitions: Sequence[Tuple[Register, Sequence[Union[str, Unused]]]] = field(
+ partitions: Sequence[tuple[Register, Sequence[Union[str, Unused]]]] = field(
converter=lambda s: tuple((r, tuple(rs)) for r, rs in s)
)
left_only: bool = False
@@ -99,10 +100,10 @@ def signature(self) -> Signature:
else:
return Signature(r for r, _ in self.partitions)
- def build_composite_bloq(self, bb: BloqBuilder, **soqs: SoquetT) -> Dict[str, SoquetT]:
- parts: Dict[str, Partition] = dict()
- in_regs: Dict[str, SoquetT] = dict()
- unused_regs: Dict[str, SoquetT] = dict()
+ def build_composite_bloq(self, bb: BloqBuilder, **soqs: SoquetT) -> dict[str, SoquetT]:
+ parts: dict[str, Partition] = dict()
+ in_regs: dict[str, SoquetT] = dict()
+ unused_regs: dict[str, SoquetT] = dict()
for parti, (out_reg, bloq_regs) in enumerate(self.partitions):
part = Partition(
out_reg.bitsize,
diff --git a/qualtran/bloqs/bookkeeping/cast.py b/qualtran/bloqs/bookkeeping/cast.py
index 9fd7bee565..c42c8d71c5 100644
--- a/qualtran/bloqs/bookkeeping/cast.py
+++ b/qualtran/bloqs/bookkeeping/cast.py
@@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from functools import cached_property
-from typing import Dict, List, Tuple, TYPE_CHECKING
+from typing import TYPE_CHECKING
import attrs
import numpy as np
@@ -67,7 +67,7 @@ class Cast(_BookkeepingBloq):
inp_dtype: QCDType
out_dtype: QCDType
- shape: Tuple[int, ...] = attrs.field(
+ shape: tuple[int, ...] = attrs.field(
default=tuple(), converter=lambda v: (v,) if isinstance(v, int) else tuple(v)
)
allow_quantum_to_classical: bool = attrs.field(default=False, kw_only=True)
@@ -108,8 +108,8 @@ def adjoint(self) -> 'Bloq':
return Cast(inp_dtype=self.out_dtype, out_dtype=self.inp_dtype)
def my_tensors(
- self, incoming: Dict[str, 'ConnectionT'], outgoing: Dict[str, 'ConnectionT']
- ) -> List['qtn.Tensor']:
+ self, incoming: dict[str, 'ConnectionT'], outgoing: dict[str, 'ConnectionT']
+ ) -> list['qtn.Tensor']:
import quimb.tensor as qtn
return [
@@ -119,11 +119,11 @@ def my_tensors(
for j in range(self.out_dtype.num_bits)
]
- def on_classical_vals(self, reg: int) -> Dict[str, 'ClassicalValT']:
+ def on_classical_vals(self, reg: int) -> dict[str, 'ClassicalValT']:
res = self.out_dtype.from_bits(self.inp_dtype.to_bits(reg))
return {'reg': res}
- def as_cirq_op(self, qubit_manager, reg: 'CirqQuregT') -> Tuple[None, Dict[str, 'CirqQuregT']]:
+ def as_cirq_op(self, qubit_manager, reg: 'CirqQuregT') -> tuple[None, dict[str, 'CirqQuregT']]:
return None, {'reg': reg}
def as_pl_op(self, wires: 'Wires') -> 'Operation':
diff --git a/qualtran/bloqs/bookkeeping/free.py b/qualtran/bloqs/bookkeeping/free.py
index 8a0c73db71..611240ea94 100644
--- a/qualtran/bloqs/bookkeeping/free.py
+++ b/qualtran/bloqs/bookkeeping/free.py
@@ -13,7 +13,7 @@
# limitations under the License.
from functools import cached_property
-from typing import Dict, List, Tuple, TYPE_CHECKING, Union
+from typing import TYPE_CHECKING, Union
import sympy
from attrs import frozen
@@ -78,14 +78,14 @@ def adjoint(self) -> 'Bloq':
return Allocate(self.dtype, self.dirty)
- def on_classical_vals(self, reg: int) -> Dict[str, 'ClassicalValT']:
+ def on_classical_vals(self, reg: int) -> dict[str, 'ClassicalValT']:
if reg != 0 and not self.dirty:
raise ValueError(f"Tried to free a non-zero register: {reg} with {self.dirty=}")
return {}
def my_tensors(
- self, incoming: Dict[str, 'ConnectionT'], outgoing: Dict[str, 'ConnectionT']
- ) -> List['qtn.Tensor']:
+ self, incoming: dict[str, 'ConnectionT'], outgoing: dict[str, 'ConnectionT']
+ ) -> list['qtn.Tensor']:
import quimb.tensor as qtn
from qualtran.bloqs.basic_gates.z_basis import _ZERO
@@ -95,7 +95,7 @@ def my_tensors(
for i in range(self.dtype.num_qubits)
]
- def wire_symbol(self, reg: Register, idx: Tuple[int, ...] = tuple()) -> 'WireSymbol':
+ def wire_symbol(self, reg: Register, idx: tuple[int, ...] = tuple()) -> 'WireSymbol':
if reg is None:
return Text('')
assert reg.name == 'reg'
@@ -103,7 +103,7 @@ def wire_symbol(self, reg: Register, idx: Tuple[int, ...] = tuple()) -> 'WireSym
def as_cirq_op(
self, qubit_manager: 'cirq.QubitManager', reg: 'CirqQuregT'
- ) -> Tuple[Union['cirq.Operation', None], Dict[str, 'CirqQuregT']]:
+ ) -> tuple[Union['cirq.Operation', None], dict[str, 'CirqQuregT']]:
qubit_manager.qfree(reg.flatten().tolist())
return (None, {})
diff --git a/qualtran/bloqs/bookkeeping/join.py b/qualtran/bloqs/bookkeeping/join.py
index b194add90d..8fa8d24c29 100644
--- a/qualtran/bloqs/bookkeeping/join.py
+++ b/qualtran/bloqs/bookkeeping/join.py
@@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from functools import cached_property
-from typing import cast, Dict, List, Optional, Tuple, TYPE_CHECKING
+from typing import cast, Optional, TYPE_CHECKING
import numpy as np
from attrs import field, frozen
@@ -79,15 +79,15 @@ def adjoint(self) -> 'Bloq':
return Split(dtype=self.dtype)
- def as_cirq_op(self, qubit_manager, reg: 'CirqQuregT') -> Tuple[None, Dict[str, 'CirqQuregT']]:
+ def as_cirq_op(self, qubit_manager, reg: 'CirqQuregT') -> tuple[None, dict[str, 'CirqQuregT']]:
return None, {'reg': reg.reshape(self.dtype.num_qubits)}
def as_pl_op(self, wires: 'Wires') -> 'Operation':
return None
def my_tensors(
- self, incoming: Dict[str, 'ConnectionT'], outgoing: Dict[str, 'ConnectionT']
- ) -> List['qtn.Tensor']:
+ self, incoming: dict[str, 'ConnectionT'], outgoing: dict[str, 'ConnectionT']
+ ) -> list['qtn.Tensor']:
import quimb.tensor as qtn
eye = np.eye(2)
@@ -98,10 +98,10 @@ def my_tensors(
for i in range(self.dtype.num_qubits)
]
- def on_classical_vals(self, reg: 'NDArray[np.uint]') -> Dict[str, int]:
+ def on_classical_vals(self, reg: 'NDArray[np.uint]') -> dict[str, int]:
return {'reg': self.dtype.from_bits(reg.tolist())}
- def wire_symbol(self, reg: Optional[Register], idx: Tuple[int, ...] = tuple()) -> 'WireSymbol':
+ def wire_symbol(self, reg: Optional[Register], idx: tuple[int, ...] = tuple()) -> 'WireSymbol':
if reg is None:
return Text('')
if reg.shape:
diff --git a/qualtran/bloqs/bookkeeping/partition.py b/qualtran/bloqs/bookkeeping/partition.py
index 5c2d44881b..af5333ebb2 100644
--- a/qualtran/bloqs/bookkeeping/partition.py
+++ b/qualtran/bloqs/bookkeeping/partition.py
@@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from functools import cached_property
-from typing import Dict, List, Tuple, TYPE_CHECKING
+from typing import TYPE_CHECKING
import numpy as np
from attrs import evolve, field, frozen, validators
@@ -58,7 +58,7 @@ class Partition(_BookkeepingBloq):
"""
n: SymbolicInt
- regs: Tuple[Register, ...] = field(
+ regs: tuple[Register, ...] = field(
converter=lambda x: x if isinstance(x, tuple) else tuple(x), validator=validators.min_len(1)
)
partition: bool = True
@@ -89,7 +89,7 @@ def decompose_bloq(self) -> 'CompositeBloq':
def adjoint(self):
return evolve(self, partition=not self.partition)
- def as_cirq_op(self, qubit_manager, **cirq_quregs) -> Tuple[None, Dict[str, 'CirqQuregT']]:
+ def as_cirq_op(self, qubit_manager, **cirq_quregs) -> tuple[None, dict[str, 'CirqQuregT']]:
if self.partition:
outregs = {}
start = 0
@@ -106,8 +106,8 @@ def as_pl_op(self, wires: 'Wires') -> 'Operation':
return None
def my_tensors(
- self, incoming: Dict[str, 'ConnectionT'], outgoing: Dict[str, 'ConnectionT']
- ) -> List['qtn.Tensor']:
+ self, incoming: dict[str, 'ConnectionT'], outgoing: dict[str, 'ConnectionT']
+ ) -> list['qtn.Tensor']:
import quimb.tensor as qtn
if is_symbolic(self.n):
@@ -131,7 +131,7 @@ def my_tensors(
for j in range(self.n)
]
- def _classical_partition(self, x: 'ClassicalValT') -> Dict[str, 'ClassicalValT']:
+ def _classical_partition(self, x: 'ClassicalValT') -> dict[str, 'ClassicalValT']:
out_vals = {}
xbits = self.lumped_dtype.to_bits(x)
start = 0
@@ -155,7 +155,7 @@ def _classical_unpartition_to_bits(self, **vals: 'ClassicalValT') -> NDArray[np.
out_vals.append(bitstrings.ravel())
return np.concatenate(out_vals)
- def on_classical_vals(self, **vals: 'ClassicalValT') -> Dict[str, 'ClassicalValT']:
+ def on_classical_vals(self, **vals: 'ClassicalValT') -> dict[str, 'ClassicalValT']:
if self.partition:
return self._classical_partition(vals['x'])
else:
@@ -163,7 +163,7 @@ def on_classical_vals(self, **vals: 'ClassicalValT') -> Dict[str, 'ClassicalValT
big_int = self.lumped_dtype.from_bits(big_int_bits.tolist())
return {'x': big_int}
- def wire_symbol(self, reg: Register, idx: Tuple[int, ...] = tuple()) -> 'WireSymbol':
+ def wire_symbol(self, reg: Register, idx: tuple[int, ...] = tuple()) -> 'WireSymbol':
if reg is None:
return Text('')
if reg.shape:
diff --git a/qualtran/bloqs/bookkeeping/partition_test.py b/qualtran/bloqs/bookkeeping/partition_test.py
index 42dce656ea..a97a0cfc4e 100644
--- a/qualtran/bloqs/bookkeeping/partition_test.py
+++ b/qualtran/bloqs/bookkeeping/partition_test.py
@@ -13,7 +13,6 @@
# limitations under the License.
from functools import cached_property
-from typing import Dict
import cirq
import numpy as np
@@ -55,7 +54,7 @@ def bitsize(self):
def signature(self) -> Signature:
return Signature.build(test_regs=self.bitsize)
- def build_composite_bloq(self, bb: 'BloqBuilder', test_regs: 'SoquetT') -> Dict[str, 'Soquet']:
+ def build_composite_bloq(self, bb: 'BloqBuilder', test_regs: 'SoquetT') -> dict[str, 'Soquet']:
bloq_regs = self.test_bloq.signature
partition = Partition(self.bitsize, bloq_regs) # type: ignore[arg-type]
out_regs = bb.add(partition, x=test_regs)
diff --git a/qualtran/bloqs/bookkeeping/split.py b/qualtran/bloqs/bookkeeping/split.py
index ab02e2e6f4..4ed8ad9c0b 100644
--- a/qualtran/bloqs/bookkeeping/split.py
+++ b/qualtran/bloqs/bookkeeping/split.py
@@ -13,7 +13,7 @@
# limitations under the License.
from functools import cached_property
-from typing import cast, Dict, List, Optional, Tuple, TYPE_CHECKING
+from typing import cast, Optional, TYPE_CHECKING
import numpy as np
from attrs import field, frozen
@@ -85,18 +85,18 @@ def adjoint(self) -> 'Bloq':
return Join(dtype=self.dtype)
- def as_cirq_op(self, qubit_manager, reg: 'CirqQuregT') -> Tuple[None, Dict[str, 'CirqQuregT']]:
+ def as_cirq_op(self, qubit_manager, reg: 'CirqQuregT') -> tuple[None, dict[str, 'CirqQuregT']]:
return None, {'reg': reg.reshape((self.dtype.num_qubits, 1))}
def as_pl_op(self, wires: 'Wires') -> 'Operation':
return None
- def on_classical_vals(self, reg: int) -> Dict[str, 'ClassicalValT']:
+ def on_classical_vals(self, reg: int) -> dict[str, 'ClassicalValT']:
return {'reg': np.asarray(self.dtype.to_bits(reg))}
def my_tensors(
- self, incoming: Dict[str, 'ConnectionT'], outgoing: Dict[str, 'ConnectionT']
- ) -> List['qtn.Tensor']:
+ self, incoming: dict[str, 'ConnectionT'], outgoing: dict[str, 'ConnectionT']
+ ) -> list['qtn.Tensor']:
import quimb.tensor as qtn
eye = np.eye(2)
@@ -107,7 +107,7 @@ def my_tensors(
for i in range(self.dtype.num_qubits)
]
- def wire_symbol(self, reg: Optional[Register], idx: Tuple[int, ...] = tuple()) -> 'WireSymbol':
+ def wire_symbol(self, reg: Optional[Register], idx: tuple[int, ...] = tuple()) -> 'WireSymbol':
if reg is None:
return Text('')
if reg.shape:
diff --git a/qualtran/bloqs/chemistry/black_boxes.py b/qualtran/bloqs/chemistry/black_boxes.py
index f9670a2eba..032870579a 100644
--- a/qualtran/bloqs/chemistry/black_boxes.py
+++ b/qualtran/bloqs/chemistry/black_boxes.py
@@ -16,7 +16,7 @@
These are for temporary convenience to lock-in the quoted literature costs.
"""
from functools import cached_property
-from typing import Optional, Tuple, TYPE_CHECKING
+from typing import Optional, TYPE_CHECKING
import attrs
import numpy as np
@@ -190,7 +190,7 @@ class ApplyControlledZs(Bloq):
system: system register
"""
- cvs: Tuple[int, ...] = field(converter=lambda v: (v,) if isinstance(v, int) else tuple(v))
+ cvs: tuple[int, ...] = field(converter=lambda v: (v,) if isinstance(v, int) else tuple(v))
bitsize: int
@cached_property
@@ -202,7 +202,7 @@ def signature(self) -> Signature:
]
)
- def wire_symbol(self, reg: Optional[Register], idx: Tuple[int, ...] = tuple()) -> 'WireSymbol':
+ def wire_symbol(self, reg: Optional[Register], idx: tuple[int, ...] = tuple()) -> 'WireSymbol':
if reg is None:
return Text("C" * len(self.cvs) + "Z")
if reg.name == 'system':
diff --git a/qualtran/bloqs/chemistry/chem_tutorials.py b/qualtran/bloqs/chemistry/chem_tutorials.py
index e2ae163c0e..18e3d6f14e 100644
--- a/qualtran/bloqs/chemistry/chem_tutorials.py
+++ b/qualtran/bloqs/chemistry/chem_tutorials.py
@@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
"""Some utility functions for chemistry tutorials"""
-from typing import Optional, Tuple
+from typing import Optional
import matplotlib.pyplot as plt
import numpy as np
@@ -34,7 +34,7 @@ def linear(x: NDArray[np.float64], a: float, c: float) -> NDArray[np.float64]:
return a * x + c
-def fit_linear(x: NDArray[np.float64], y: NDArray[np.float64]) -> Tuple[float, float]:
+def fit_linear(x: NDArray[np.float64], y: NDArray[np.float64]) -> tuple[float, float]:
"""Fit a line given x and y values.
Args:
diff --git a/qualtran/bloqs/chemistry/df/double_factorization.py b/qualtran/bloqs/chemistry/df/double_factorization.py
index e83b385240..c1f8b236a2 100644
--- a/qualtran/bloqs/chemistry/df/double_factorization.py
+++ b/qualtran/bloqs/chemistry/df/double_factorization.py
@@ -30,8 +30,9 @@
$$
where $\Xi^{(l)} $ is the rank of second factorization.
"""
+from collections.abc import Iterable
from functools import cached_property
-from typing import Dict, Iterable, TYPE_CHECKING
+from typing import TYPE_CHECKING
import numpy as np
from attrs import frozen
@@ -193,7 +194,7 @@ def build_composite_bloq(
rot: SoquetT,
rotations: SoquetT,
sys: NDArray[Soquet], # type: ignore[type-var]
- ) -> Dict[str, 'SoquetT']:
+ ) -> dict[str, 'SoquetT']:
# 1st half
in_prep = InnerPrepareDoubleFactorization(
num_aux=self.num_aux,
@@ -438,7 +439,7 @@ def build_composite_bloq(
rot: SoquetT,
rotations: SoquetT,
sys: SoquetT,
- ) -> Dict[str, 'SoquetT']:
+ ) -> dict[str, 'SoquetT']:
succ_l, l_ne_zero, theta, succ_p = ctrl
n_n = (self.num_spin_orb // 2 - 1).bit_length() # C14
outer_prep = OuterPrepareDoubleFactorization(
diff --git a/qualtran/bloqs/chemistry/hubbard_model/qubitization/prepare_hubbard.py b/qualtran/bloqs/chemistry/hubbard_model/qubitization/prepare_hubbard.py
index cfdbf20b0b..0b60b3b29f 100644
--- a/qualtran/bloqs/chemistry/hubbard_model/qubitization/prepare_hubbard.py
+++ b/qualtran/bloqs/chemistry/hubbard_model/qubitization/prepare_hubbard.py
@@ -12,8 +12,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+from collections.abc import Iterator
from functools import cached_property
-from typing import Iterator, Tuple, TYPE_CHECKING
+from typing import TYPE_CHECKING
import attrs
import cirq
@@ -79,7 +80,7 @@ def __attrs_post_init__(self):
raise NotImplementedError("Currently only supports the case where x_dim=y_dim.")
@cached_property
- def selection_registers(self) -> Tuple[Register, ...]:
+ def selection_registers(self) -> tuple[Register, ...]:
return (
Register('U', BQUInt(1, 2)),
Register('V', BQUInt(1, 2)),
@@ -92,7 +93,7 @@ def selection_registers(self) -> Tuple[Register, ...]:
)
@cached_property
- def junk_registers(self) -> Tuple[Register, ...]:
+ def junk_registers(self) -> tuple[Register, ...]:
return (Register('temp', QAny(2)),)
@cached_property
diff --git a/qualtran/bloqs/chemistry/hubbard_model/qubitization/select_hubbard.py b/qualtran/bloqs/chemistry/hubbard_model/qubitization/select_hubbard.py
index 66a123fa5b..8d968134ac 100644
--- a/qualtran/bloqs/chemistry/hubbard_model/qubitization/select_hubbard.py
+++ b/qualtran/bloqs/chemistry/hubbard_model/qubitization/select_hubbard.py
@@ -12,8 +12,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+from collections.abc import Iterator
from functools import cached_property
-from typing import Iterator, Optional, Tuple
+from typing import Optional
import attrs
import cirq
@@ -96,11 +97,11 @@ def __attrs_post_init__(self):
)
@cached_property
- def control_registers(self) -> Tuple[Register, ...]:
+ def control_registers(self) -> tuple[Register, ...]:
return () if self.control_val is None else (Register('control', QBit()),)
@cached_property
- def selection_registers(self) -> Tuple[Register, ...]:
+ def selection_registers(self) -> tuple[Register, ...]:
return (
Register('U', BQUInt(1, 2)),
Register('V', BQUInt(1, 2)),
@@ -113,7 +114,7 @@ def selection_registers(self) -> Tuple[Register, ...]:
)
@cached_property
- def target_registers(self) -> Tuple[Register, ...]:
+ def target_registers(self) -> tuple[Register, ...]:
return (Register('target', QAny(self.x_dim * self.y_dim * 2)),)
@cached_property
@@ -194,7 +195,7 @@ def __str__(self):
return f'C{s}'
return s
- def get_ctrl_system(self, ctrl_spec: 'CtrlSpec') -> Tuple['Bloq', 'AddControlledT']:
+ def get_ctrl_system(self, ctrl_spec: 'CtrlSpec') -> tuple['Bloq', 'AddControlledT']:
from qualtran.bloqs.mcmt.specialized_ctrl import get_ctrl_system_1bit_cv_from_bloqs
return get_ctrl_system_1bit_cv_from_bloqs(
diff --git a/qualtran/bloqs/chemistry/ising/hamiltonian.py b/qualtran/bloqs/chemistry/ising/hamiltonian.py
index e71db3d184..b979b7a154 100644
--- a/qualtran/bloqs/chemistry/ising/hamiltonian.py
+++ b/qualtran/bloqs/chemistry/ising/hamiltonian.py
@@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
"""Functions for specifying the Ising model and building LCU coefficients."""
-from typing import List, Sequence
+from collections.abc import Sequence
import cirq
import numpy as np
@@ -39,8 +39,8 @@ def get_1d_ising_pauli_terms(
x_terms: The list of PauliStrings for the X terms.
"""
n_sites = len(qubits)
- zz_terms: List[cirq.PauliString] = []
- x_terms: List[cirq.PauliString] = []
+ zz_terms: list[cirq.PauliString] = []
+ x_terms: list[cirq.PauliString] = []
for k in range(n_sites):
zz_terms.append(
cirq.PauliString(
diff --git a/qualtran/bloqs/chemistry/pbc/first_quantization/prepare_nu.py b/qualtran/bloqs/chemistry/pbc/first_quantization/prepare_nu.py
index ae1e4e6bc2..e0487a655b 100644
--- a/qualtran/bloqs/chemistry/pbc/first_quantization/prepare_nu.py
+++ b/qualtran/bloqs/chemistry/pbc/first_quantization/prepare_nu.py
@@ -13,7 +13,7 @@
# limitations under the License.
r"""Bloqs for preparation of the U and V parts of the first quantized chemistry Hamiltonian."""
from functools import cached_property
-from typing import Dict, Optional, Tuple, TYPE_CHECKING
+from typing import Optional, TYPE_CHECKING
from attrs import evolve, frozen
@@ -63,7 +63,7 @@ def build_call_graph(self, ssa: 'SympySymbolAllocator') -> 'BloqCountDictT':
return {Toffoli(): (self.num_bits_p - 1)}
def wire_symbol(
- self, reg: Optional['Register'], idx: Tuple[int, ...] = tuple()
+ self, reg: Optional['Register'], idx: tuple[int, ...] = tuple()
) -> 'WireSymbol':
if reg is None:
return Text(r'PREP √(2^μ)|μ⟩')
@@ -115,7 +115,7 @@ def build_call_graph(self, ssa: 'SympySymbolAllocator') -> 'BloqCountDictT':
return {Toffoli(): (3 * (self.num_bits_p - 1))}
def wire_symbol(
- self, reg: Optional['Register'], idx: Tuple[int, ...] = tuple()
+ self, reg: Optional['Register'], idx: tuple[int, ...] = tuple()
) -> 'WireSymbol':
if reg is None:
return Text(r'PREP (2^-μ)|μ⟩|ν⟩')
@@ -165,7 +165,7 @@ def build_call_graph(self, ssa: 'SympySymbolAllocator') -> 'BloqCountDictT':
return {Toffoli(): (3 * self.num_bits_p + 2)}
def wire_symbol(
- self, reg: Optional['Register'], idx: Tuple[int, ...] = tuple()
+ self, reg: Optional['Register'], idx: tuple[int, ...] = tuple()
) -> 'WireSymbol':
if reg is None:
return Text(r'ν≠−0')
@@ -215,7 +215,7 @@ def build_call_graph(self, ssa: 'SympySymbolAllocator') -> 'BloqCountDictT':
return {Toffoli(): 3 * self.num_bits_p}
def wire_symbol(
- self, reg: Optional['Register'], idx: Tuple[int, ...] = tuple()
+ self, reg: Optional['Register'], idx: tuple[int, ...] = tuple()
) -> 'WireSymbol':
if reg is None:
return Text(r'ν<2^(μ−2)')
@@ -298,7 +298,7 @@ def build_call_graph(self, ssa: 'SympySymbolAllocator') -> 'BloqCountDictT':
return dict([cost_1, cost_2, cost_3, cost_4])
def wire_symbol(
- self, reg: Optional['Register'], idx: Tuple[int, ...] = tuple()
+ self, reg: Optional['Register'], idx: tuple[int, ...] = tuple()
) -> 'WireSymbol':
if reg is None:
return Text(r'(2^(μ-2))^2 M > m ν^2')
@@ -368,7 +368,7 @@ def signature(self) -> Signature:
def build_composite_bloq(
self, bb: BloqBuilder, mu: SoquetT, nu: SoquetT, m: SoquetT, flag_nu: SoquetT
- ) -> Dict[str, 'SoquetT']:
+ ) -> dict[str, 'SoquetT']:
mu, flag_mu = bb.add(PrepareMuUnaryEncodedOneHot(self.num_bits_p), mu=mu)
mu, nu = bb.add(PrepareNuSuperPositionState(self.num_bits_p), mu=mu, nu=nu)
nu, flag_zero = bb.add(FlagZeroAsFailure(self.num_bits_p), nu=nu)
@@ -404,7 +404,7 @@ def build_call_graph(self, ssa: 'SympySymbolAllocator') -> 'BloqCountDictT':
return dict([cost_1, cost_2, cost_3, cost_4, cost_6])
def wire_symbol(
- self, reg: Optional['Register'], idx: Tuple[int, ...] = tuple()
+ self, reg: Optional['Register'], idx: tuple[int, ...] = tuple()
) -> 'WireSymbol':
if reg is None:
return Text(r"PREP 1/‖ν‖ ∣ν⟩")
diff --git a/qualtran/bloqs/chemistry/pbc/first_quantization/prepare_t.py b/qualtran/bloqs/chemistry/pbc/first_quantization/prepare_t.py
index cb69fc70b1..fb666699f8 100644
--- a/qualtran/bloqs/chemistry/pbc/first_quantization/prepare_t.py
+++ b/qualtran/bloqs/chemistry/pbc/first_quantization/prepare_t.py
@@ -13,7 +13,7 @@
# limitations under the License.
r"""Bloqs for PREPARE T for the first quantized chemistry Hamiltonian."""
from functools import cached_property
-from typing import Dict, Optional, Tuple, TYPE_CHECKING
+from typing import Optional, TYPE_CHECKING
from attrs import frozen
@@ -61,7 +61,7 @@ def build_call_graph(self, ssa: 'SympySymbolAllocator') -> 'BloqCountDictT':
return {Toffoli(): (self.bitsize - 2)}
def wire_symbol(
- self, reg: Optional['Register'], idx: Tuple[int, ...] = tuple()
+ self, reg: Optional['Register'], idx: tuple[int, ...] = tuple()
) -> 'WireSymbol':
if reg is None:
return Text(r'PREP 2^(r/2) |r⟩')
@@ -109,7 +109,7 @@ def signature(self) -> Signature:
def build_composite_bloq(
self, bb: BloqBuilder, w: SoquetT, r: SoquetT, s: SoquetT
- ) -> Dict[str, 'SoquetT']:
+ ) -> dict[str, 'SoquetT']:
w = bb.add(PrepareUniformSuperposition(3), target=w)
r = bb.add(PreparePowerTwoState(self.num_bits_p), r=r)
s = bb.add(PreparePowerTwoState(self.num_bits_p), r=s)
@@ -124,7 +124,7 @@ def build_call_graph(self, ssa: 'SympySymbolAllocator') -> 'BloqCountDictT':
return {Toffoli(): 13, PreparePowerTwoState(bitsize=self.num_bits_p): 2}
def wire_symbol(
- self, reg: Optional['Register'], idx: Tuple[int, ...] = tuple()
+ self, reg: Optional['Register'], idx: tuple[int, ...] = tuple()
) -> 'WireSymbol':
if reg is None:
return Text(r'PREP T')
diff --git a/qualtran/bloqs/chemistry/pbc/first_quantization/prepare_uv.py b/qualtran/bloqs/chemistry/pbc/first_quantization/prepare_uv.py
index 2c5e79f0c5..0132fd447e 100644
--- a/qualtran/bloqs/chemistry/pbc/first_quantization/prepare_uv.py
+++ b/qualtran/bloqs/chemistry/pbc/first_quantization/prepare_uv.py
@@ -13,7 +13,7 @@
# limitations under the License.
r"""PREPARE the potential energy terms of the first quantized chemistry Hamiltonian."""
from functools import cached_property
-from typing import Dict, Optional, Tuple, TYPE_CHECKING
+from typing import Optional, TYPE_CHECKING
from attrs import frozen
@@ -85,7 +85,7 @@ def signature(self) -> Signature:
def build_composite_bloq(
self, bb: BloqBuilder, mu: SoquetT, nu: SoquetT, m: SoquetT, l: SoquetT, flag_nu: SoquetT
- ) -> Dict[str, 'SoquetT']:
+ ) -> dict[str, 'SoquetT']:
mu, nu, m, flag_nu = bb.add(
PrepareNuState(self.num_bits_p, self.m_param), mu=mu, nu=nu, m=m, flag_nu=flag_nu
)
@@ -101,7 +101,7 @@ def build_call_graph(self, ssa: 'SympySymbolAllocator') -> 'BloqCountDictT':
}
def wire_symbol(
- self, reg: Optional['Register'], idx: Tuple[int, ...] = tuple()
+ self, reg: Optional['Register'], idx: tuple[int, ...] = tuple()
) -> 'WireSymbol':
if reg is None:
return Text('PREP UV')
diff --git a/qualtran/bloqs/chemistry/pbc/first_quantization/projectile/prepare_nu.py b/qualtran/bloqs/chemistry/pbc/first_quantization/projectile/prepare_nu.py
index 682ab3c654..6f3c864d71 100644
--- a/qualtran/bloqs/chemistry/pbc/first_quantization/projectile/prepare_nu.py
+++ b/qualtran/bloqs/chemistry/pbc/first_quantization/projectile/prepare_nu.py
@@ -13,7 +13,7 @@
# limitations under the License.
r"""Bloqs for preparing the $\nu$ state for the first quantized chemistry Hamiltonian."""
from functools import cached_property
-from typing import Dict, TYPE_CHECKING
+from typing import TYPE_CHECKING
from attrs import evolve, frozen
@@ -135,7 +135,7 @@ def signature(self) -> Signature:
def build_composite_bloq(
self, bb: BloqBuilder, mu: SoquetT, nu: SoquetT, m: SoquetT, flag_nu: SoquetT
- ) -> Dict[str, 'SoquetT']:
+ ) -> dict[str, 'SoquetT']:
mu, flag_mu = bb.add(
PrepareMuUnaryEncodedOneHotWithProj(self.num_bits_n, self.num_bits_p), mu=mu
)
diff --git a/qualtran/bloqs/chemistry/pbc/first_quantization/projectile/prepare_uv.py b/qualtran/bloqs/chemistry/pbc/first_quantization/projectile/prepare_uv.py
index f66875a9c0..95b4ee8a65 100644
--- a/qualtran/bloqs/chemistry/pbc/first_quantization/projectile/prepare_uv.py
+++ b/qualtran/bloqs/chemistry/pbc/first_quantization/projectile/prepare_uv.py
@@ -11,10 +11,9 @@
# 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.
-r"""PREPARE the potential energy terms of the first quantized chemistry Hamiltonian with projectile.
-"""
+r"""PREPARE the potential energy terms of the first quantized chemistry Hamiltonian with projectile."""
from functools import cached_property
-from typing import Dict, Optional, Tuple, TYPE_CHECKING
+from typing import Optional, TYPE_CHECKING
from attrs import frozen
@@ -77,14 +76,14 @@ def signature(self) -> Signature:
]
)
- def wire_symbol(self, reg: Optional[Register], idx: Tuple[int, ...] = tuple()) -> 'WireSymbol':
+ def wire_symbol(self, reg: Optional[Register], idx: tuple[int, ...] = tuple()) -> 'WireSymbol':
if reg is None:
return Text("PREP UV")
return super().wire_symbol(reg, idx)
def build_composite_bloq(
self, bb: BloqBuilder, mu: SoquetT, nu: SoquetT, m: SoquetT, l: SoquetT, flag_nu: SoquetT
- ) -> Dict[str, 'SoquetT']:
+ ) -> dict[str, 'SoquetT']:
mu, nu, m, flag_nu = bb.add(
PrepareNuStateWithProj(self.num_bits_p, self.num_bits_n, self.m_param),
mu=mu,
diff --git a/qualtran/bloqs/chemistry/pbc/first_quantization/projectile/select_and_prepare.py b/qualtran/bloqs/chemistry/pbc/first_quantization/projectile/select_and_prepare.py
index dde8e7eb6c..7ba76c5991 100644
--- a/qualtran/bloqs/chemistry/pbc/first_quantization/projectile/select_and_prepare.py
+++ b/qualtran/bloqs/chemistry/pbc/first_quantization/projectile/select_and_prepare.py
@@ -13,7 +13,7 @@
# limitations under the License.
r"""SELECT and PREPARE for the first quantized chemistry Hamiltonian with a quantum projectile."""
from functools import cached_property
-from typing import Dict, Optional, Tuple, TYPE_CHECKING
+from typing import Optional, TYPE_CHECKING
import numpy as np
from attrs import evolve, field, frozen
@@ -104,7 +104,7 @@ def signature(self) -> Signature:
def adjoint(self) -> 'Bloq':
return evolve(self, is_adjoint=not self.is_adjoint)
- def wire_symbol(self, reg: Optional[Register], idx: Tuple[int, ...] = tuple()) -> 'WireSymbol':
+ def wire_symbol(self, reg: Optional[Register], idx: tuple[int, ...] = tuple()) -> 'WireSymbol':
if reg is None:
return Text("PREP TUV")
return super().wire_symbol(reg, idx)
@@ -127,7 +127,7 @@ class ControlledMultiplexedCSwap3D(MultiplexedCSwap3D):
num_bits_p: int
num_bits_n: int
eta: int
- cvs: Tuple[int, ...] = field(converter=lambda v: (v,) if isinstance(v, int) else tuple(v))
+ cvs: tuple[int, ...] = field(converter=lambda v: (v,) if isinstance(v, int) else tuple(v))
@cached_property
def signature(self) -> Signature:
@@ -141,7 +141,7 @@ def signature(self) -> Signature:
]
)
- def wire_symbol(self, reg: Optional[Register], idx: Tuple[int, ...] = tuple()) -> 'WireSymbol':
+ def wire_symbol(self, reg: Optional[Register], idx: tuple[int, ...] = tuple()) -> 'WireSymbol':
if reg is None:
return Text('MultiSwap')
if reg.name == 'sel':
@@ -158,7 +158,7 @@ def wire_symbol(self, reg: Optional[Register], idx: Tuple[int, ...] = tuple()) -
def build_composite_bloq(
self, bb: BloqBuilder, ctrl: SoquetT, sel: SoquetT, targets: SoquetT, junk: SoquetT
- ) -> Dict[str, 'SoquetT']:
+ ) -> dict[str, 'SoquetT']:
flat_sys = self._reshape_reg(bb, targets, (self.eta,), bitsize=3 * self.num_bits_p)
# we need to extract first n_p bits of each n_n sized ancilla register (i.e. pad with zeros).
# This is not a contiguous chunk of qubits so we need to first flatten,
@@ -247,7 +247,7 @@ class PrepareFirstQuantizationWithProj(PrepareOracle):
num_bits_rot_aa: int = 8
@property
- def selection_registers(self) -> Tuple[Register, ...]:
+ def selection_registers(self) -> tuple[Register, ...]:
n_nu = self.num_bits_n + 1
n_eta = (self.eta - 1).bit_length()
n_at = (self.num_atoms - 1).bit_length()
@@ -277,14 +277,14 @@ def selection_registers(self) -> Tuple[Register, ...]:
)
@cached_property
- def junk_registers(self) -> Tuple[Register, ...]:
+ def junk_registers(self) -> tuple[Register, ...]:
return (
Register("succ_nu", QBit()),
Register("plus_t", QBit()),
Register('flags', QBit(), shape=(4,)),
)
- def wire_symbol(self, reg: Optional[Register], idx: Tuple[int, ...] = tuple()) -> 'WireSymbol':
+ def wire_symbol(self, reg: Optional[Register], idx: tuple[int, ...] = tuple()) -> 'WireSymbol':
if reg is None:
return Text("PREP")
return super().wire_symbol(reg, idx)
@@ -310,7 +310,7 @@ def build_composite_bloq(
succ_nu: SoquetT,
l: SoquetT,
flags: SoquetT,
- ) -> Dict[str, 'SoquetT']:
+ ) -> dict[str, 'SoquetT']:
prep_tuv = PrepareTUVSuperpositions(
self.num_bits_t, self.eta, self.lambda_zeta, self.num_bits_rot_aa
)
@@ -422,7 +422,7 @@ class SelectFirstQuantizationWithProj(SelectOracle):
num_bits_rot_aa: int = 8
@cached_property
- def control_registers(self) -> Tuple[Register, ...]:
+ def control_registers(self) -> tuple[Register, ...]:
return (
# flags for which component of Hamiltonian to apply.
Register("ham_ctrl", QBit(), shape=(4,)),
@@ -431,7 +431,7 @@ def control_registers(self) -> Tuple[Register, ...]:
)
@cached_property
- def selection_registers(self) -> Tuple[Register, ...]:
+ def selection_registers(self) -> tuple[Register, ...]:
n_nu = self.num_bits_n + 1
n_eta = (self.eta - 1).bit_length()
n_at = (self.num_atoms - 1).bit_length()
@@ -452,7 +452,7 @@ def selection_registers(self) -> Tuple[Register, ...]:
)
@cached_property
- def target_registers(self) -> Tuple[Register, ...]:
+ def target_registers(self) -> tuple[Register, ...]:
return (
Register("sys", QAny(bitsize=self.num_bits_p), shape=(self.eta, 3)),
Register('proj', QAny(bitsize=self.num_bits_n), shape=(3,)),
@@ -464,7 +464,7 @@ def signature(self) -> Signature:
[*self.control_registers, *self.selection_registers, *self.target_registers]
)
- def wire_symbol(self, reg: Optional[Register], idx: Tuple[int, ...] = tuple()) -> 'WireSymbol':
+ def wire_symbol(self, reg: Optional[Register], idx: tuple[int, ...] = tuple()) -> 'WireSymbol':
if reg is None:
return Text("SELECT")
return super().wire_symbol(reg, idx)
@@ -489,7 +489,7 @@ def build_composite_bloq(
l: SoquetT,
sys: SoquetT,
proj: NDArray[Soquet], # type: ignore[type-var]
- ) -> Dict[str, 'SoquetT']:
+ ) -> dict[str, 'SoquetT']:
# ancilla for swaps from electronic and projectile system registers.
# we assume these are left in a clean state after SELECT operations
# We only need one of the ancilla registers to be of the size of the projectile's register.
diff --git a/qualtran/bloqs/chemistry/pbc/first_quantization/projectile/select_t.py b/qualtran/bloqs/chemistry/pbc/first_quantization/projectile/select_t.py
index efa2e943f7..20982a7552 100644
--- a/qualtran/bloqs/chemistry/pbc/first_quantization/projectile/select_t.py
+++ b/qualtran/bloqs/chemistry/pbc/first_quantization/projectile/select_t.py
@@ -13,7 +13,7 @@
# limitations under the License.
r"""Bloqs for SELECT T for the first quantized chemistry Hamiltonian with a quantum projectile."""
from functools import cached_property
-from typing import Optional, Tuple, TYPE_CHECKING
+from typing import Optional, TYPE_CHECKING
from attrs import frozen
@@ -71,7 +71,7 @@ def signature(self) -> Signature:
]
)
- def wire_symbol(self, reg: Optional[Register], idx: Tuple[int, ...] = tuple()) -> 'WireSymbol':
+ def wire_symbol(self, reg: Optional[Register], idx: tuple[int, ...] = tuple()) -> 'WireSymbol':
if reg is None:
return Text("SEL T")
return super().wire_symbol(reg, idx)
diff --git a/qualtran/bloqs/chemistry/pbc/first_quantization/projectile/select_uv.py b/qualtran/bloqs/chemistry/pbc/first_quantization/projectile/select_uv.py
index 6ef6283cfb..6683e66629 100644
--- a/qualtran/bloqs/chemistry/pbc/first_quantization/projectile/select_uv.py
+++ b/qualtran/bloqs/chemistry/pbc/first_quantization/projectile/select_uv.py
@@ -14,7 +14,7 @@
r"""Bloqs for SELECT for the U and V parts of the first quantized chemistry Hamiltonian."""
from collections import Counter
from functools import cached_property
-from typing import Optional, Tuple, TYPE_CHECKING
+from typing import Optional, TYPE_CHECKING
from attrs import frozen
@@ -76,7 +76,7 @@ def signature(self) -> Signature:
]
)
- def wire_symbol(self, reg: Optional[Register], idx: Tuple[int, ...] = tuple()) -> 'WireSymbol':
+ def wire_symbol(self, reg: Optional[Register], idx: tuple[int, ...] = tuple()) -> 'WireSymbol':
if reg is None:
return Text('SEL UV')
return super().wire_symbol(reg, idx)
diff --git a/qualtran/bloqs/chemistry/pbc/first_quantization/select_and_prepare.py b/qualtran/bloqs/chemistry/pbc/first_quantization/select_and_prepare.py
index 5f5001c60a..d36d80a4ee 100644
--- a/qualtran/bloqs/chemistry/pbc/first_quantization/select_and_prepare.py
+++ b/qualtran/bloqs/chemistry/pbc/first_quantization/select_and_prepare.py
@@ -13,7 +13,7 @@
# limitations under the License.
r"""SELECT and PREPARE for the first quantized chemistry Hamiltonian."""
from functools import cached_property
-from typing import Dict, Optional, Tuple, TYPE_CHECKING
+from typing import Optional, TYPE_CHECKING
import numpy as np
from attrs import frozen
@@ -74,7 +74,7 @@ class PrepareTUVSuperpositions(Bloq):
def signature(self) -> Signature:
return Signature.build(tuv=1, uv=1)
- def wire_symbol(self, reg: Optional[Register], idx: Tuple[int, ...] = tuple()) -> 'WireSymbol':
+ def wire_symbol(self, reg: Optional[Register], idx: tuple[int, ...] = tuple()) -> 'WireSymbol':
if reg is None:
return Text("PREP TUV")
return super().wire_symbol(reg, idx)
@@ -138,7 +138,7 @@ def signature(self) -> Signature:
@staticmethod
def _reshape_reg(
- bb: BloqBuilder, in_reg: SoquetT, out_shape: Tuple[int, ...], bitsize: int
+ bb: BloqBuilder, in_reg: SoquetT, out_shape: tuple[int, ...], bitsize: int
) -> NDArray[Soquet]: # type: ignore[type-var]
"""Reshape registers allocated as a big register.
@@ -163,7 +163,7 @@ def _reshape_reg(
)
return merged_qubits.reshape(out_shape)
- def wire_symbol(self, reg: Optional[Register], idx: Tuple[int, ...] = tuple()) -> 'WireSymbol':
+ def wire_symbol(self, reg: Optional[Register], idx: tuple[int, ...] = tuple()) -> 'WireSymbol':
if reg is None:
return Text('MultiSwap')
if reg.name == 'sel':
@@ -176,7 +176,7 @@ def wire_symbol(self, reg: Optional[Register], idx: Tuple[int, ...] = tuple()) -
def build_composite_bloq(
self, bb: BloqBuilder, sel: SoquetT, targets: SoquetT, junk: SoquetT
- ) -> Dict[str, 'SoquetT']:
+ ) -> dict[str, 'SoquetT']:
flat_sys = self._reshape_reg(bb, targets, (self.eta,), bitsize=3 * self.num_bits_p)
flat_p = self._reshape_reg(bb, junk, (), bitsize=3 * self.num_bits_p)
sel, flat_sys, flat_p = bb.add(
@@ -244,7 +244,7 @@ class PrepareFirstQuantization(PrepareOracle):
sum_of_l1_coeffs: Optional[SymbolicFloat] = None
@property
- def selection_registers(self) -> Tuple[Register, ...]:
+ def selection_registers(self) -> tuple[Register, ...]:
n_nu = self.num_bits_p + 1
n_eta = (self.eta - 1).bit_length()
n_at = (self.num_atoms - 1).bit_length()
@@ -272,7 +272,7 @@ def selection_registers(self) -> Tuple[Register, ...]:
)
@cached_property
- def junk_registers(self) -> Tuple[Register, ...]:
+ def junk_registers(self) -> tuple[Register, ...]:
return (Register("succ_nu", QBit()), Register("plus_t", QBit()))
@property
@@ -283,7 +283,7 @@ def l1_norm_coeffs(self) -> SymbolicFloat:
)
return self.sum_of_l1_coeffs
- def wire_symbol(self, reg: Optional[Register], idx: Tuple[int, ...] = tuple()) -> 'WireSymbol':
+ def wire_symbol(self, reg: Optional[Register], idx: tuple[int, ...] = tuple()) -> 'WireSymbol':
if reg is None:
return Text("PREP")
return super().wire_symbol(reg, idx)
@@ -306,7 +306,7 @@ def build_composite_bloq(
m: SoquetT,
succ_nu: SoquetT,
l: SoquetT,
- ) -> Dict[str, 'SoquetT']:
+ ) -> dict[str, 'SoquetT']:
tuv, uv = bb.add(
PrepareTUVSuperpositions(
self.num_bits_t, self.eta, self.lambda_zeta, self.num_bits_rot_aa
@@ -412,7 +412,7 @@ class SelectFirstQuantization(SelectOracle):
num_bits_rot_aa: int = 8
@cached_property
- def control_registers(self) -> Tuple[Register, ...]:
+ def control_registers(self) -> tuple[Register, ...]:
return (
Register("tuv", QBit()),
Register("uv", QBit()),
@@ -421,7 +421,7 @@ def control_registers(self) -> Tuple[Register, ...]:
)
@cached_property
- def selection_registers(self) -> Tuple[Register, ...]:
+ def selection_registers(self) -> tuple[Register, ...]:
n_nu = self.num_bits_p + 1
n_eta = (self.eta - 1).bit_length()
n_at = (self.num_atoms - 1).bit_length()
@@ -441,7 +441,7 @@ def selection_registers(self) -> Tuple[Register, ...]:
)
@cached_property
- def target_registers(self) -> Tuple[Register, ...]:
+ def target_registers(self) -> tuple[Register, ...]:
return (Register("sys", QAny(bitsize=self.num_bits_p), shape=(self.eta, 3)),)
@cached_property
@@ -450,7 +450,7 @@ def signature(self) -> Signature:
[*self.control_registers, *self.selection_registers, *self.target_registers]
)
- def wire_symbol(self, reg: Optional[Register], idx: Tuple[int, ...] = tuple()) -> 'WireSymbol':
+ def wire_symbol(self, reg: Optional[Register], idx: tuple[int, ...] = tuple()) -> 'WireSymbol':
if reg is None:
return Text("SELECT")
return super().wire_symbol(reg, idx)
@@ -474,7 +474,7 @@ def build_composite_bloq(
m: SoquetT,
l: SoquetT,
sys: SoquetT,
- ) -> Dict[str, 'SoquetT']:
+ ) -> dict[str, 'SoquetT']:
# ancilla for swaps from electronic system registers.
# we assume these are left in a clean state after SELECT operations
p = [bb.allocate(self.num_bits_p) for _ in range(3)]
diff --git a/qualtran/bloqs/chemistry/pbc/first_quantization/select_t.py b/qualtran/bloqs/chemistry/pbc/first_quantization/select_t.py
index ca7938daa3..3b6de7438d 100644
--- a/qualtran/bloqs/chemistry/pbc/first_quantization/select_t.py
+++ b/qualtran/bloqs/chemistry/pbc/first_quantization/select_t.py
@@ -13,7 +13,7 @@
# limitations under the License.
r"""Bloqs for SELECT T for the first quantized chemistry Hamiltonian."""
from functools import cached_property
-from typing import Optional, Tuple, TYPE_CHECKING
+from typing import Optional, TYPE_CHECKING
from attrs import frozen
@@ -59,7 +59,7 @@ def signature(self) -> Signature:
]
)
- def wire_symbol(self, reg: Optional[Register], idx: Tuple[int, ...] = tuple()) -> 'WireSymbol':
+ def wire_symbol(self, reg: Optional[Register], idx: tuple[int, ...] = tuple()) -> 'WireSymbol':
if reg is None:
return Text("SEL T")
return super().wire_symbol(reg, idx)
diff --git a/qualtran/bloqs/chemistry/pbc/first_quantization/select_uv.py b/qualtran/bloqs/chemistry/pbc/first_quantization/select_uv.py
index 86bd0fdb40..f08c8ed186 100644
--- a/qualtran/bloqs/chemistry/pbc/first_quantization/select_uv.py
+++ b/qualtran/bloqs/chemistry/pbc/first_quantization/select_uv.py
@@ -13,7 +13,7 @@
# limitations under the License.
r"""Bloqs for SELECT for the U and V parts of the first quantized chemistry Hamiltonian."""
from functools import cached_property
-from typing import Optional, Tuple, TYPE_CHECKING
+from typing import Optional, TYPE_CHECKING
from attrs import frozen
@@ -57,7 +57,7 @@ def signature(self) -> Signature:
]
)
- def wire_symbol(self, reg: Optional[Register], idx: Tuple[int, ...] = tuple()) -> 'WireSymbol':
+ def wire_symbol(self, reg: Optional[Register], idx: tuple[int, ...] = tuple()) -> 'WireSymbol':
if reg is None:
return Text(r'-e^(-k_ν⋅R_l)')
return super().wire_symbol(reg, idx)
@@ -114,7 +114,7 @@ def signature(self) -> Signature:
]
)
- def wire_symbol(self, reg: Optional[Register], idx: Tuple[int, ...] = tuple()) -> 'WireSymbol':
+ def wire_symbol(self, reg: Optional[Register], idx: tuple[int, ...] = tuple()) -> 'WireSymbol':
if reg is None:
return Text("SEL UV")
return super().wire_symbol(reg, idx)
diff --git a/qualtran/bloqs/chemistry/quad_fermion/givens_bloq.py b/qualtran/bloqs/chemistry/quad_fermion/givens_bloq.py
index 8546f518da..563fc420f5 100644
--- a/qualtran/bloqs/chemistry/quad_fermion/givens_bloq.py
+++ b/qualtran/bloqs/chemistry/quad_fermion/givens_bloq.py
@@ -46,7 +46,6 @@
"""
from functools import cached_property
-from typing import Dict
from attrs import frozen
@@ -120,7 +119,7 @@ def build_composite_bloq(
target_j: SoquetT,
rom_data: SoquetT,
phase_gradient: SoquetT,
- ) -> Dict[str, SoquetT]:
+ ) -> dict[str, SoquetT]:
# clifford block
target_i = bb.add(XGate(), q=target_i)
target_j = bb.add(SGate(), q=target_j)
@@ -214,7 +213,7 @@ def build_composite_bloq(
real_rom_data: SoquetT,
cplx_rom_data: SoquetT,
phase_gradient: SoquetT,
- ) -> Dict[str, SoquetT]:
+ ) -> dict[str, SoquetT]:
real_givens_gate = RealGivensRotationByPhaseGradient(
phasegrad_bitsize=self.phasegrad_bitsize
)
diff --git a/qualtran/bloqs/chemistry/sf/prepare.py b/qualtran/bloqs/chemistry/sf/prepare.py
index 1ad5861baa..6671f2bff1 100644
--- a/qualtran/bloqs/chemistry/sf/prepare.py
+++ b/qualtran/bloqs/chemistry/sf/prepare.py
@@ -13,7 +13,7 @@
# limitations under the License.
from functools import cached_property
-from typing import Optional, Tuple, TYPE_CHECKING
+from typing import Optional, TYPE_CHECKING
from attrs import frozen
@@ -70,7 +70,7 @@ class InnerPrepareSingleFactorization(Bloq):
kp1: int = 1
kp2: int = 1
- def wire_symbol(self, reg: Optional[Register], idx: Tuple[int, ...] = tuple()) -> 'WireSymbol':
+ def wire_symbol(self, reg: Optional[Register], idx: tuple[int, ...] = tuple()) -> 'WireSymbol':
if reg is None:
return Text("In-Prep")
return super().wire_symbol(reg, idx)
@@ -136,7 +136,7 @@ class OuterPrepareSingleFactorization(Bloq):
num_bits_state_prep: int
num_bits_rot_aa: int = 8
- def wire_symbol(self, reg: Optional[Register], idx: Tuple[int, ...] = tuple()) -> 'WireSymbol':
+ def wire_symbol(self, reg: Optional[Register], idx: tuple[int, ...] = tuple()) -> 'WireSymbol':
if reg is None:
return Text("OuterPrep")
return super().wire_symbol(reg, idx)
diff --git a/qualtran/bloqs/chemistry/sf/single_factorization.py b/qualtran/bloqs/chemistry/sf/single_factorization.py
index 5e1104df8a..cf39c70f36 100644
--- a/qualtran/bloqs/chemistry/sf/single_factorization.py
+++ b/qualtran/bloqs/chemistry/sf/single_factorization.py
@@ -22,8 +22,9 @@
electron repulsion integrals.
"""
+from collections.abc import Iterable
from functools import cached_property
-from typing import Dict, Iterable, TYPE_CHECKING
+from typing import TYPE_CHECKING
import numpy as np
from attrs import evolve, frozen
@@ -203,7 +204,7 @@ def build_composite_bloq(
swap_pq: SoquetT,
spin: SoquetT,
sys: SoquetT,
- ) -> Dict[str, 'SoquetT']:
+ ) -> dict[str, 'SoquetT']:
iprep = InnerPrepareSingleFactorization(
self.num_aux,
self.num_spin_orb,
@@ -394,7 +395,7 @@ def build_composite_bloq(
swap_pq: SoquetT,
spin: SoquetT,
sys: SoquetT,
- ) -> Dict[str, 'SoquetT']:
+ ) -> dict[str, 'SoquetT']:
succ_l, l_ne_zero, succ_pq = ctrl
p, q = pq
# prepare_l
diff --git a/qualtran/bloqs/chemistry/sparse/prepare.py b/qualtran/bloqs/chemistry/sparse/prepare.py
index 02e4b38109..5a90926f0d 100644
--- a/qualtran/bloqs/chemistry/sparse/prepare.py
+++ b/qualtran/bloqs/chemistry/sparse/prepare.py
@@ -15,7 +15,7 @@
import itertools
from functools import cached_property
-from typing import Dict, Optional, Tuple, TYPE_CHECKING
+from typing import Optional, TYPE_CHECKING
import attrs
import numpy as np
@@ -173,19 +173,19 @@ class PrepareSparse(PrepareOracle):
num_spin_orb: int
num_non_zero: int
num_bits_state_prep: int
- alt_pqrs: Tuple[Tuple[int, ...], ...] = attrs.field(repr=False)
- alt_theta: Tuple[int, ...] = attrs.field(repr=False)
- alt_one_body: Tuple[int, ...] = attrs.field(repr=False)
- ind_pqrs: Tuple[Tuple[int, ...], ...] = attrs.field(repr=False)
- theta: Tuple[int, ...] = attrs.field(repr=False)
- one_body: Tuple[int, ...] = attrs.field(repr=False)
- keep: Tuple[int, ...] = attrs.field(repr=False)
+ alt_pqrs: tuple[tuple[int, ...], ...] = attrs.field(repr=False)
+ alt_theta: tuple[int, ...] = attrs.field(repr=False)
+ alt_one_body: tuple[int, ...] = attrs.field(repr=False)
+ ind_pqrs: tuple[tuple[int, ...], ...] = attrs.field(repr=False)
+ theta: tuple[int, ...] = attrs.field(repr=False)
+ one_body: tuple[int, ...] = attrs.field(repr=False)
+ keep: tuple[int, ...] = attrs.field(repr=False)
num_bits_rot_aa: int = 8
sum_of_l1_coeffs: SymbolicFloat = 0.0
log_block_size: SymbolicInt = 1
@cached_property
- def selection_registers(self) -> Tuple[Register, ...]:
+ def selection_registers(self) -> tuple[Register, ...]:
return (
Register(
"d",
@@ -203,12 +203,12 @@ def selection_registers(self) -> Tuple[Register, ...]:
)
@cached_property
- def junk_registers(self) -> Tuple[Register, ...]:
+ def junk_registers(self) -> tuple[Register, ...]:
extra_junk = (Register("less_than", QBit()),)
return extra_junk + self.qroam_target_registers + self.qroam_extra_target_registers
@cached_property
- def qroam_target_registers(self) -> Tuple[Register, ...]:
+ def qroam_target_registers(self) -> tuple[Register, ...]:
"""Target registers for QROAMClean."""
bs = (self.num_spin_orb // 2 - 1).bit_length()
return (
@@ -228,7 +228,7 @@ def qroam_target_registers(self) -> Tuple[Register, ...]:
)
@cached_property
- def qroam_extra_target_registers(self) -> Tuple[Register, ...]:
+ def qroam_extra_target_registers(self) -> tuple[Register, ...]:
"""Extra registers required for QROAMClean."""
if self.log_block_size == 0:
return ()
@@ -345,12 +345,12 @@ def build_qrom_bloq(self) -> 'Bloq':
)
return qrom
- def add_qrom(self, bb: 'BloqBuilder', **soqs: 'SoquetT') -> Dict[str, 'SoquetT']:
+ def add_qrom(self, bb: 'BloqBuilder', **soqs: 'SoquetT') -> dict[str, 'SoquetT']:
qrom = self.build_qrom_bloq()
# The qroam_junk_regs won't be present initially when building the
# composite bloq as they're RIGHT registers.
qroam_out_soqs = bb.add_d(qrom, selection=soqs['d'])
- out_soqs: Dict[str, 'SoquetT'] = {'d': qroam_out_soqs.pop('selection')}
+ out_soqs: dict[str, 'SoquetT'] = {'d': qroam_out_soqs.pop('selection')}
# map output soqs to Prepare junk registers names
out_soqs |= {
reg.name: qroam_out_soqs.pop(f'target{i}_')
@@ -362,7 +362,7 @@ def add_qrom(self, bb: 'BloqBuilder', **soqs: 'SoquetT') -> Dict[str, 'SoquetT']
}
return soqs | out_soqs
- def build_composite_bloq(self, bb: 'BloqBuilder', **soqs: 'SoquetT') -> Dict[str, 'SoquetT']:
+ def build_composite_bloq(self, bb: 'BloqBuilder', **soqs: 'SoquetT') -> dict[str, 'SoquetT']:
n_n = self.num_bits_spat_orb
# 1. Prepare \sum_d |d\rangle
soqs['d'] = bb.add(PrepareUniformSuperposition(self.num_non_zero), target=soqs['d'])
diff --git a/qualtran/bloqs/chemistry/sparse/select_bloq.py b/qualtran/bloqs/chemistry/sparse/select_bloq.py
index 1c7fd5595a..43f8b0ddc7 100644
--- a/qualtran/bloqs/chemistry/sparse/select_bloq.py
+++ b/qualtran/bloqs/chemistry/sparse/select_bloq.py
@@ -14,7 +14,7 @@
"""SELECT for the sparse chemistry Hamiltonian in second quantization."""
from functools import cached_property
-from typing import Dict, Optional, Tuple, TYPE_CHECKING
+from typing import Optional, TYPE_CHECKING
import attrs
import cirq
@@ -71,11 +71,11 @@ class SelectSparse(SelectOracle):
control_val: Optional[int] = None
@cached_property
- def control_registers(self) -> Tuple[Register, ...]:
+ def control_registers(self) -> tuple[Register, ...]:
return () if self.control_val is None else (Register('control', QBit()),)
@cached_property
- def selection_registers(self) -> Tuple[Register, ...]:
+ def selection_registers(self) -> tuple[Register, ...]:
return (
Register(
"p",
@@ -111,10 +111,10 @@ def selection_registers(self) -> Tuple[Register, ...]:
)
@cached_property
- def target_registers(self) -> Tuple[Register, ...]:
+ def target_registers(self) -> tuple[Register, ...]:
return (Register("sys", QAny(bitsize=self.num_spin_orb)),)
- def build_composite_bloq(self, bb: 'BloqBuilder', **soqs: 'SoquetT') -> Dict[str, 'SoquetT']:
+ def build_composite_bloq(self, bb: 'BloqBuilder', **soqs: 'SoquetT') -> dict[str, 'SoquetT']:
p, q, r, s = soqs['p'], soqs['q'], soqs['r'], soqs['s']
alpha, beta = soqs['alpha'], soqs['beta']
flag_1b = soqs['flag_1b']
@@ -169,7 +169,7 @@ def build_call_graph(self, ssa: 'SympySymbolAllocator') -> 'BloqCountDictT':
c_maj_y = SelectedMajoranaFermion(sel_pa, target_gate=cirq.Y)
return {SGate(): 1, maj_x: 1, c_maj_x: 1, maj_y: 1, c_maj_y: 1}
- def get_ctrl_system(self, ctrl_spec: 'CtrlSpec') -> Tuple['Bloq', 'AddControlledT']:
+ def get_ctrl_system(self, ctrl_spec: 'CtrlSpec') -> tuple['Bloq', 'AddControlledT']:
from qualtran.bloqs.mcmt.specialized_ctrl import get_ctrl_system_1bit_cv
return get_ctrl_system_1bit_cv(
diff --git a/qualtran/bloqs/chemistry/thc/prepare.py b/qualtran/bloqs/chemistry/thc/prepare.py
index f93891e727..d367ebc424 100644
--- a/qualtran/bloqs/chemistry/thc/prepare.py
+++ b/qualtran/bloqs/chemistry/thc/prepare.py
@@ -13,7 +13,7 @@
# limitations under the License.
"""PREPARE for the molecular tensor hypercontraction (THC) hamiltonian"""
from functools import cached_property
-from typing import Dict, Optional, Tuple, TYPE_CHECKING
+from typing import Optional, TYPE_CHECKING
import numpy as np
from attrs import field, frozen
@@ -110,7 +110,7 @@ def signature(self) -> Signature:
def __str__(self) -> str:
return r'$\sum_{\mu < \nu} |\mu\nu\rangle$'
- def wire_symbol(self, reg: Optional[Register], idx: Tuple[int, ...] = tuple()) -> 'WireSymbol':
+ def wire_symbol(self, reg: Optional[Register], idx: tuple[int, ...] = tuple()) -> 'WireSymbol':
if reg is None:
return Text('Σ |μν>')
return super().wire_symbol(reg, idx)
@@ -123,7 +123,7 @@ def build_composite_bloq(
succ: SoquetT,
nu_eq_mp1: SoquetT,
rot: SoquetT,
- ) -> Dict[str, 'SoquetT']:
+ ) -> dict[str, 'SoquetT']:
# If we introduce comparators using out of place adders these will be left/right registers.
# See: https://github.com/quantumlib/Qualtran/issues/390
lte_mu_nu, lte_nu_mp1, gt_mu_n, junk = bb.split(bb.allocate(4))
@@ -260,11 +260,11 @@ class PrepareTHC(PrepareOracle):
num_mu: int
num_spin_orb: int
- alt_mu: Tuple[int, ...] = field(repr=False)
- alt_nu: Tuple[int, ...] = field(repr=False)
- alt_theta: Tuple[int, ...] = field(repr=False)
- theta: Tuple[int, ...] = field(repr=False)
- keep: Tuple[int, ...] = field(repr=False)
+ alt_mu: tuple[int, ...] = field(repr=False)
+ alt_nu: tuple[int, ...] = field(repr=False)
+ alt_theta: tuple[int, ...] = field(repr=False)
+ theta: tuple[int, ...] = field(repr=False)
+ keep: tuple[int, ...] = field(repr=False)
keep_bitsize: int
sum_of_l1_coeffs: SymbolicFloat
log_block_size: SymbolicInt = 0
@@ -348,7 +348,7 @@ def l1_norm_of_coeffs(self) -> SymbolicFloat:
return self.sum_of_l1_coeffs
@cached_property
- def selection_registers(self) -> Tuple[Register, ...]:
+ def selection_registers(self) -> tuple[Register, ...]:
return (
Register(
"mu", BQUInt(bitsize=(self.num_mu).bit_length(), iteration_length=self.num_mu + 1)
@@ -366,7 +366,7 @@ def selection_registers(self) -> Tuple[Register, ...]:
)
@cached_property
- def junk_registers(self) -> Tuple[Register, ...]:
+ def junk_registers(self) -> tuple[Register, ...]:
data_size = self.num_spin_orb // 2 + self.num_mu * (self.num_mu + 1) // 2
junk = (
Register('s', QAny(bitsize=(data_size - 1).bit_length())),
@@ -376,7 +376,7 @@ def junk_registers(self) -> Tuple[Register, ...]:
return junk + self.qroam_target_registers + self.qroam_extra_target_registers
@cached_property
- def qroam_target_registers(self) -> Tuple[Register, ...]:
+ def qroam_target_registers(self) -> tuple[Register, ...]:
"""Target registers for QROAMClean."""
return (
Register('theta', QBit(), side=Side.RIGHT),
@@ -387,7 +387,7 @@ def qroam_target_registers(self) -> Tuple[Register, ...]:
)
@cached_property
- def qroam_extra_target_registers(self) -> Tuple[Register, ...]:
+ def qroam_extra_target_registers(self) -> tuple[Register, ...]:
"""Extra registers required for QROAMClean."""
return tuple(
Register(
@@ -412,12 +412,12 @@ def build_qrom_bloq(self) -> 'Bloq':
)
return qroam
- def add_qrom(self, bb: 'BloqBuilder', **soqs: 'SoquetT') -> Dict[str, 'SoquetT']:
+ def add_qrom(self, bb: 'BloqBuilder', **soqs: 'SoquetT') -> dict[str, 'SoquetT']:
qrom = self.build_qrom_bloq()
# The qroam_junk_regs won't be present initially when building the
# composite bloq as they're RIGHT registers.
qroam_out_soqs = bb.add_d(qrom, selection=soqs['s'])
- out_soqs: Dict[str, 'SoquetT'] = {'s': qroam_out_soqs.pop('selection')}
+ out_soqs: dict[str, 'SoquetT'] = {'s': qroam_out_soqs.pop('selection')}
# map output soqs to Prepare junk registers names
out_soqs |= {
reg.name: qroam_out_soqs.pop(f'target{i}_')
@@ -429,7 +429,7 @@ def add_qrom(self, bb: 'BloqBuilder', **soqs: 'SoquetT') -> Dict[str, 'SoquetT']
}
return soqs | out_soqs
- def build_composite_bloq(self, bb: 'BloqBuilder', **soqs: 'SoquetT') -> Dict[str, 'SoquetT']:
+ def build_composite_bloq(self, bb: 'BloqBuilder', **soqs: 'SoquetT') -> dict[str, 'SoquetT']:
# 1. Prepare THC uniform superposition over mu, nu. succ flags success.
soqs['mu'], soqs['nu'], soqs['succ'], soqs['nu_eq_mp1'], soqs['rot'] = bb.add(
UniformSuperpositionTHC(num_mu=self.num_mu, num_spin_orb=self.num_spin_orb),
diff --git a/qualtran/bloqs/chemistry/thc/select_bloq.py b/qualtran/bloqs/chemistry/thc/select_bloq.py
index a3b825950f..9bf8679778 100644
--- a/qualtran/bloqs/chemistry/thc/select_bloq.py
+++ b/qualtran/bloqs/chemistry/thc/select_bloq.py
@@ -14,7 +14,7 @@
"""SELECT for the molecular tensor hypercontraction (THC) hamiltonian"""
from functools import cached_property
-from typing import Dict, Optional, Tuple, TYPE_CHECKING
+from typing import Optional, TYPE_CHECKING
import numpy as np
from attrs import evolve, frozen
@@ -163,11 +163,11 @@ class SelectTHC(SelectOracle):
control_val: Optional[int] = None
@cached_property
- def control_registers(self) -> Tuple[Register, ...]:
+ def control_registers(self) -> tuple[Register, ...]:
return () if self.control_val is None else (Register('control', QBit()),)
@cached_property
- def selection_registers(self) -> Tuple[Register, ...]:
+ def selection_registers(self) -> tuple[Register, ...]:
return (
Register("succ", BQUInt(bitsize=1)),
Register("nu_eq_mp1", BQUInt(bitsize=1)),
@@ -185,13 +185,13 @@ def selection_registers(self) -> Tuple[Register, ...]:
)
@cached_property
- def target_registers(self) -> Tuple[Register, ...]:
+ def target_registers(self) -> tuple[Register, ...]:
return (
Register("sys_a", QAny(bitsize=self.num_spin_orb // 2)),
Register("sys_b", QAny(bitsize=self.num_spin_orb // 2)),
)
- def build_composite_bloq(self, bb: 'BloqBuilder', **soqs: 'SoquetT') -> Dict[str, 'SoquetT']:
+ def build_composite_bloq(self, bb: 'BloqBuilder', **soqs: 'SoquetT') -> dict[str, 'SoquetT']:
succ = soqs['succ']
nu_eq_mp1 = soqs['nu_eq_mp1']
mu = soqs['mu']
@@ -314,7 +314,7 @@ def build_composite_bloq(self, bb: 'BloqBuilder', **soqs: 'SoquetT') -> Dict[str
return out_soqs
- def get_ctrl_system(self, ctrl_spec: 'CtrlSpec') -> Tuple['Bloq', 'AddControlledT']:
+ def get_ctrl_system(self, ctrl_spec: 'CtrlSpec') -> tuple['Bloq', 'AddControlledT']:
from qualtran.bloqs.mcmt.specialized_ctrl import get_ctrl_system_1bit_cv
return get_ctrl_system_1bit_cv(
diff --git a/qualtran/bloqs/chemistry/trotter/grid_ham/inverse_sqrt.py b/qualtran/bloqs/chemistry/trotter/grid_ham/inverse_sqrt.py
index d9beebf871..c888946367 100644
--- a/qualtran/bloqs/chemistry/trotter/grid_ham/inverse_sqrt.py
+++ b/qualtran/bloqs/chemistry/trotter/grid_ham/inverse_sqrt.py
@@ -13,7 +13,7 @@
# limitations under the License.
"""Bloqs for computing the inverse Square root of a fixed point number."""
from functools import cached_property
-from typing import Optional, Tuple, TYPE_CHECKING
+from typing import Optional, TYPE_CHECKING
import numpy as np
from attrs import frozen
@@ -27,7 +27,7 @@
from qualtran.resource_counting import BloqCountDictT, SympySymbolAllocator
-def get_inverse_square_root_poly_coeffs() -> Tuple[NDArray, NDArray]:
+def get_inverse_square_root_poly_coeffs() -> tuple[NDArray, NDArray]:
"""Polynomial coefficients for approximating inverse square root.
This function returns the coefficients of a piecewise cubic polynomial
@@ -59,7 +59,7 @@ def get_inverse_square_root_poly_coeffs() -> Tuple[NDArray, NDArray]:
def build_qrom_data_for_poly_fit(
- selection_bitsize: int, target_bitsize: int, poly_coeffs: Tuple[NDArray, NDArray]
+ selection_bitsize: int, target_bitsize: int, poly_coeffs: tuple[NDArray, NDArray]
) -> NDArray:
"""Build QROM data from polynomial coefficients from the referenence.
@@ -165,7 +165,7 @@ def signature(self) -> Signature:
]
)
- def wire_symbol(self, reg: Optional[Register], idx: Tuple[int, ...] = tuple()) -> 'WireSymbol':
+ def wire_symbol(self, reg: Optional[Register], idx: tuple[int, ...] = tuple()) -> 'WireSymbol':
if reg is None:
return Text("y=x^{-1/2}")
return super().wire_symbol(reg, idx)
@@ -217,7 +217,7 @@ def signature(self) -> Signature:
]
)
- def wire_symbol(self, reg: Optional[Register], idx: Tuple[int, ...] = tuple()) -> 'WireSymbol':
+ def wire_symbol(self, reg: Optional[Register], idx: tuple[int, ...] = tuple()) -> 'WireSymbol':
if reg is None:
return Text("y~x^{-1/2}")
return super().wire_symbol(reg, idx)
diff --git a/qualtran/bloqs/chemistry/trotter/grid_ham/kinetic.py b/qualtran/bloqs/chemistry/trotter/grid_ham/kinetic.py
index 50dd860c59..5c7a7a4088 100644
--- a/qualtran/bloqs/chemistry/trotter/grid_ham/kinetic.py
+++ b/qualtran/bloqs/chemistry/trotter/grid_ham/kinetic.py
@@ -13,7 +13,7 @@
# limitations under the License.
from functools import cached_property
-from typing import Dict, Optional, Tuple
+from typing import Optional
from attrs import frozen
from numpy.typing import NDArray
@@ -66,12 +66,12 @@ def signature(self) -> Signature:
]
)
- def wire_symbol(self, reg: Optional[Register], idx: Tuple[int, ...] = tuple()) -> 'WireSymbol':
+ def wire_symbol(self, reg: Optional[Register], idx: tuple[int, ...] = tuple()) -> 'WireSymbol':
if reg is None:
return Text("U_T(dt)")
return super().wire_symbol(reg, idx)
- def build_composite_bloq(self, bb: BloqBuilder, *, system: NDArray[Soquet]) -> Dict[str, SoquetT]: # type: ignore[type-var]
+ def build_composite_bloq(self, bb: BloqBuilder, *, system: NDArray[Soquet]) -> dict[str, SoquetT]: # type: ignore[type-var]
bitsize = (self.num_grid - 1).bit_length() + 1
for i in range(self.num_elec):
system[i], sos = bb.add(SumOfSquares(bitsize=bitsize, k=3), input=system[i])
diff --git a/qualtran/bloqs/chemistry/trotter/grid_ham/potential.py b/qualtran/bloqs/chemistry/trotter/grid_ham/potential.py
index 6fd2fae98f..4749d93270 100644
--- a/qualtran/bloqs/chemistry/trotter/grid_ham/potential.py
+++ b/qualtran/bloqs/chemistry/trotter/grid_ham/potential.py
@@ -14,7 +14,7 @@
"""Bloqs for the Potential energy of a 3D grid based Hamiltonian."""
from functools import cached_property
-from typing import Dict, Optional, Tuple
+from typing import Optional
import numpy as np
from attrs import field, frozen
@@ -67,7 +67,7 @@ class PairPotential(Bloq):
"""
bitsize: int
- qrom_data: Tuple[Tuple[int], ...] = field(
+ qrom_data: tuple[tuple[int], ...] = field(
repr=False, converter=lambda d: tuple(tuple(x) for x in d)
)
poly_bitsize: int = 15
@@ -84,7 +84,7 @@ def signature(self) -> Signature:
)
def wire_symbol(
- self, reg: Optional['Register'], idx: Tuple[int, ...] = tuple()
+ self, reg: Optional['Register'], idx: tuple[int, ...] = tuple()
) -> 'WireSymbol':
if reg is None:
return Text(f'U_{self.label}(dt)_ij')
@@ -92,7 +92,7 @@ def wire_symbol(
def build_composite_bloq(
self, bb: BloqBuilder, *, system_i: SoquetT, system_j: SoquetT
- ) -> Dict[str, SoquetT]:
+ ) -> dict[str, SoquetT]:
if isinstance(system_i, Soquet) or isinstance(system_j, Soquet):
raise ValueError("system_i and system_j must be numpy arrays of Soquet")
# compute r_i - r_j
@@ -220,13 +220,13 @@ def signature(self) -> Signature:
)
def wire_symbol(
- self, reg: Optional['Register'], idx: Tuple[int, ...] = tuple()
+ self, reg: Optional['Register'], idx: tuple[int, ...] = tuple()
) -> 'WireSymbol':
if reg is None:
return Text(f'U_{self.label}(dt)')
return super().wire_symbol(reg, idx)
- def build_composite_bloq(self, bb: BloqBuilder, *, system: SoquetT) -> Dict[str, SoquetT]:
+ def build_composite_bloq(self, bb: BloqBuilder, *, system: SoquetT) -> dict[str, SoquetT]:
if isinstance(system, Soquet):
raise ValueError("system must be a numpy array of Soquet")
bitsize = (self.num_grid - 1).bit_length() + 1
diff --git a/qualtran/bloqs/chemistry/trotter/grid_ham/qvr.py b/qualtran/bloqs/chemistry/trotter/grid_ham/qvr.py
index 0809fd98bc..9c0eb4349c 100644
--- a/qualtran/bloqs/chemistry/trotter/grid_ham/qvr.py
+++ b/qualtran/bloqs/chemistry/trotter/grid_ham/qvr.py
@@ -14,7 +14,7 @@
"""Quantum Variable Rotation."""
from functools import cached_property
-from typing import Optional, Tuple, TYPE_CHECKING
+from typing import Optional, TYPE_CHECKING
from attrs import frozen
@@ -54,7 +54,7 @@ class QuantumVariableRotation(Bloq):
def signature(self) -> Signature:
return Signature([Register('phi', QAny(bitsize=self.phi_bitsize))])
- def wire_symbol(self, reg: Optional[Register], idx: Tuple[int, ...] = tuple()) -> 'WireSymbol':
+ def wire_symbol(self, reg: Optional[Register], idx: tuple[int, ...] = tuple()) -> 'WireSymbol':
if reg is None:
return Text("e^{i*phi}")
return super().wire_symbol(reg, idx)
diff --git a/qualtran/bloqs/chemistry/trotter/hubbard/hopping.py b/qualtran/bloqs/chemistry/trotter/hubbard/hopping.py
index 7e9a93856c..78cd57c880 100644
--- a/qualtran/bloqs/chemistry/trotter/hubbard/hopping.py
+++ b/qualtran/bloqs/chemistry/trotter/hubbard/hopping.py
@@ -13,7 +13,7 @@
# limitations under the License.
"""Bloqs implementing unitary evolution under the one-body hopping Hamiltonian in 2D."""
from functools import cached_property
-from typing import Optional, Tuple, TYPE_CHECKING
+from typing import Optional, TYPE_CHECKING
from attrs import frozen
@@ -121,7 +121,7 @@ def __attrs_post_init__(self):
if isinstance(self.length, int) and self.length % 2 != 0:
raise ValueError('Only even length lattices are supported')
- def wire_symbol(self, reg: Optional[Register], idx: Tuple[int, ...] = tuple()) -> 'WireSymbol':
+ def wire_symbol(self, reg: Optional[Register], idx: tuple[int, ...] = tuple()) -> 'WireSymbol':
if reg is None:
l = 'p' if self.pink else 'g'
return Text(f'H_h^{l}')
diff --git a/qualtran/bloqs/chemistry/trotter/hubbard/trotter_step.py b/qualtran/bloqs/chemistry/trotter/hubbard/trotter_step.py
index 807d1bbe6f..78fa885cb8 100644
--- a/qualtran/bloqs/chemistry/trotter/hubbard/trotter_step.py
+++ b/qualtran/bloqs/chemistry/trotter/hubbard/trotter_step.py
@@ -21,7 +21,7 @@
$$
"""
-from typing import Sequence
+from collections.abc import Sequence
from qualtran.bloqs.chemistry.trotter.hubbard.hopping import HoppingTile, HoppingTileHWP
from qualtran.bloqs.chemistry.trotter.hubbard.interaction import Interaction, InteractionHWP
diff --git a/qualtran/bloqs/chemistry/trotter/ising/unitaries.py b/qualtran/bloqs/chemistry/trotter/ising/unitaries.py
index c9f9b14ce5..0a401d0d44 100644
--- a/qualtran/bloqs/chemistry/trotter/ising/unitaries.py
+++ b/qualtran/bloqs/chemistry/trotter/ising/unitaries.py
@@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from functools import cached_property
-from typing import Dict, Optional, Tuple
+from typing import Optional
import attrs
@@ -42,12 +42,12 @@ class IsingXUnitary(Bloq):
def signature(self) -> Signature:
return Signature.build(system=self.nsites)
- def wire_symbol(self, reg: Optional[Register], idx: Tuple[int, ...] = tuple()) -> 'WireSymbol':
+ def wire_symbol(self, reg: Optional[Register], idx: tuple[int, ...] = tuple()) -> 'WireSymbol':
if reg is None:
return Text("U_X")
return super().wire_symbol(reg, idx)
- def build_composite_bloq(self, bb: 'BloqBuilder', system: 'Soquet') -> Dict[str, 'Soquet']:
+ def build_composite_bloq(self, bb: 'BloqBuilder', system: 'Soquet') -> dict[str, 'Soquet']:
system = bb.split(system)
for iq in range(self.nsites):
system[iq] = bb.add(Rx(self.angle), q=system[iq])
@@ -75,12 +75,12 @@ class IsingZZUnitary(Bloq):
def signature(self) -> Signature:
return Signature.build(system=self.nsites)
- def wire_symbol(self, reg: Optional[Register], idx: Tuple[int, ...] = tuple()) -> 'WireSymbol':
+ def wire_symbol(self, reg: Optional[Register], idx: tuple[int, ...] = tuple()) -> 'WireSymbol':
if reg is None:
return Text("U_ZZ")
return super().wire_symbol(reg, idx)
- def build_composite_bloq(self, bb: 'BloqBuilder', system: 'Soquet') -> Dict[str, 'Soquet']:
+ def build_composite_bloq(self, bb: 'BloqBuilder', system: 'Soquet') -> dict[str, 'Soquet']:
system = bb.split(system)
for iq_a in range(self.nsites):
iq_b = (iq_a + 1) % self.nsites
diff --git a/qualtran/bloqs/chemistry/trotter/trotterized_unitary.py b/qualtran/bloqs/chemistry/trotter/trotterized_unitary.py
index f362ad22ed..39f561875b 100644
--- a/qualtran/bloqs/chemistry/trotter/trotterized_unitary.py
+++ b/qualtran/bloqs/chemistry/trotter/trotterized_unitary.py
@@ -13,8 +13,8 @@
# limitations under the License.
"""Bloq for building a Trotterized unitary"""
+from collections.abc import Sequence
from functools import cached_property
-from typing import Dict, Sequence
import attrs
@@ -102,7 +102,7 @@ def __attrs_post_init__(self):
def signature(self) -> Signature:
return self.bloqs[0].signature
- def build_composite_bloq(self, bb: 'BloqBuilder', **soqs: SoquetT) -> Dict[str, 'SoquetT']:
+ def build_composite_bloq(self, bb: 'BloqBuilder', **soqs: SoquetT) -> dict[str, 'SoquetT']:
for i, a in zip(self.indices, self.coeffs):
# Bloqs passed in are supposed to be attrs dataclasses per docs
# It would be nice to somehow specify that self.bloqs are both bloqs and AttrsInstance
diff --git a/qualtran/bloqs/cryptography/_factoring_shims.py b/qualtran/bloqs/cryptography/_factoring_shims.py
index 1bc32a5c6d..6ed5d47834 100644
--- a/qualtran/bloqs/cryptography/_factoring_shims.py
+++ b/qualtran/bloqs/cryptography/_factoring_shims.py
@@ -13,7 +13,7 @@
# limitations under the License.
from functools import cached_property
-from typing import Dict, Optional, Tuple
+from typing import Optional
import numpy as np
import sympy
@@ -46,7 +46,7 @@ class MeasureQFT(Bloq):
def signature(self) -> 'Signature':
return Signature([Register('x', QBit(), shape=(self.n,), side=Side.LEFT)])
- def build_composite_bloq(self, bb: 'BloqBuilder', x: Soquet) -> Dict[str, 'SoquetT']:
+ def build_composite_bloq(self, bb: 'BloqBuilder', x: Soquet) -> dict[str, 'SoquetT']:
if isinstance(self.n, sympy.Expr):
raise DecomposeTypeError("Cannot decompose symbolic `n`.")
@@ -63,7 +63,7 @@ def build_call_graph(self, ssa: 'SympySymbolAllocator') -> 'BloqCountDictT':
return {QFTTextBook(self.n): 1, Measure(): self.n}
def wire_symbol(
- self, reg: Optional['Register'], idx: Tuple[int, ...] = tuple()
+ self, reg: Optional['Register'], idx: tuple[int, ...] = tuple()
) -> 'WireSymbol':
if reg is None:
return Text('MeasureQFT')
diff --git a/qualtran/bloqs/cryptography/ecc/ec_add.py b/qualtran/bloqs/cryptography/ecc/ec_add.py
index 0401890bdf..8c48f89898 100644
--- a/qualtran/bloqs/cryptography/ecc/ec_add.py
+++ b/qualtran/bloqs/cryptography/ecc/ec_add.py
@@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from functools import cached_property
-from typing import Dict, Union
+from typing import Union
import numpy as np
import sympy
@@ -102,7 +102,7 @@ def signature(self) -> 'Signature':
def on_classical_vals(
self, a: 'ClassicalValT', b: 'ClassicalValT', x: 'ClassicalValT', y: 'ClassicalValT'
- ) -> Dict[str, 'ClassicalValT']:
+ ) -> dict[str, 'ClassicalValT']:
f1 = int(a == x)
f2 = int(b == (-y % self.mod))
f3 = int(a == b == 0)
@@ -122,7 +122,7 @@ def on_classical_vals(
def build_composite_bloq(
self, bb: 'BloqBuilder', a: Soquet, b: Soquet, x: Soquet, y: Soquet
- ) -> Dict[str, 'SoquetT']:
+ ) -> dict[str, 'SoquetT']:
if is_symbolic(self.n):
raise DecomposeTypeError(f"Cannot decompose {self} with symbolic `n`.")
@@ -249,7 +249,7 @@ def on_classical_vals(
x: 'ClassicalValT',
y: 'ClassicalValT',
lam_r: 'ClassicalValT',
- ) -> Dict[str, 'ClassicalValT']:
+ ) -> dict[str, 'ClassicalValT']:
x = (x - a) % self.mod
if ctrl == 1:
y = (y - b) % self.mod
@@ -274,7 +274,7 @@ def build_composite_bloq(
x: Soquet,
y: Soquet,
lam_r: Soquet,
- ) -> Dict[str, 'SoquetT']:
+ ) -> dict[str, 'SoquetT']:
if is_symbolic(self.n):
raise DecomposeTypeError(f"Cannot decompose {self} with symbolic `n`.")
@@ -429,7 +429,7 @@ def on_classical_vals(
x: 'ClassicalValT',
y: 'ClassicalValT',
lam: 'ClassicalValT',
- ) -> Dict[str, 'ClassicalValT']:
+ ) -> dict[str, 'ClassicalValT']:
if ctrl == 1:
x = (x + 3 * a) % self.mod
y = 0
@@ -444,7 +444,7 @@ def build_composite_bloq(
x: Soquet,
y: Soquet,
lam: Soquet,
- ) -> Dict[str, 'SoquetT']:
+ ) -> dict[str, 'SoquetT']:
if is_symbolic(self.n):
raise DecomposeTypeError(f"Cannot decompose {self} with symbolic `n`.")
@@ -557,7 +557,7 @@ def signature(self) -> 'Signature':
def on_classical_vals(
self, x: 'ClassicalValT', y: 'ClassicalValT', lam: 'ClassicalValT'
- ) -> Dict[str, 'ClassicalValT']:
+ ) -> dict[str, 'ClassicalValT']:
x = (
x - QMontgomeryUInt(self.n, self.mod).montgomery_product(int(lam), int(lam))
) % self.mod
@@ -567,7 +567,7 @@ def on_classical_vals(
def build_composite_bloq(
self, bb: 'BloqBuilder', x: Soquet, y: Soquet, lam: Soquet
- ) -> Dict[str, 'SoquetT']:
+ ) -> dict[str, 'SoquetT']:
if is_symbolic(self.n):
raise DecomposeTypeError(f"Cannot decompose {self} with symbolic `n`.")
@@ -715,7 +715,7 @@ def on_classical_vals(
y: 'ClassicalValT',
lam_r: 'ClassicalValT',
lam: 'ClassicalValT',
- ) -> Dict[str, 'ClassicalValT']:
+ ) -> dict[str, 'ClassicalValT']:
if ctrl == 1:
x = (a - x) % self.mod
y = (y - b) % self.mod
@@ -733,7 +733,7 @@ def build_composite_bloq(
y: Soquet,
lam_r: Soquet,
lam: Soquet,
- ) -> Dict[str, 'SoquetT']:
+ ) -> dict[str, 'SoquetT']:
if is_symbolic(self.n):
raise DecomposeTypeError(f"Cannot decompose {self} with symbolic `n`.")
@@ -885,7 +885,7 @@ def on_classical_vals(
b: 'ClassicalValT',
x: 'ClassicalValT',
y: 'ClassicalValT',
- ) -> Dict[str, 'ClassicalValT']:
+ ) -> dict[str, 'ClassicalValT']:
if f4 == 1:
x = a
y = b
@@ -906,7 +906,7 @@ def build_composite_bloq(
b: Soquet,
x: Soquet,
y: Soquet,
- ) -> Dict[str, 'SoquetT']:
+ ) -> dict[str, 'SoquetT']:
if is_symbolic(self.n):
raise DecomposeTypeError(f"Cannot decompose {self} with symbolic `n`.")
@@ -1076,7 +1076,7 @@ def signature(self) -> 'Signature':
def build_composite_bloq(
self, bb: 'BloqBuilder', a: Soquet, b: Soquet, x: Soquet, y: Soquet, lam_r: Soquet
- ) -> Dict[str, 'SoquetT']:
+ ) -> dict[str, 'SoquetT']:
f1, f2, f3, f4, ctrl, a, b, x, y = bb.add(
_ECAddStepOne(n=self.n, mod=self.mod), a=a, b=b, x=x, y=y
)
@@ -1127,7 +1127,7 @@ def build_composite_bloq(
return {'a': a, 'b': b, 'x': x, 'y': y, 'lam_r': lam_r}
- def on_classical_vals(self, a, b, x, y, lam_r) -> Dict[str, Union['ClassicalValT', sympy.Expr]]:
+ def on_classical_vals(self, a, b, x, y, lam_r) -> dict[str, Union['ClassicalValT', sympy.Expr]]:
dtype = QMontgomeryUInt(self.n, self.mod)
curve_a = (
dtype.montgomery_to_uint(lam_r) * 2 * dtype.montgomery_to_uint(b)
diff --git a/qualtran/bloqs/cryptography/ecc/ec_add_r.py b/qualtran/bloqs/cryptography/ecc/ec_add_r.py
index 195654d5b4..076f87f2b0 100644
--- a/qualtran/bloqs/cryptography/ecc/ec_add_r.py
+++ b/qualtran/bloqs/cryptography/ecc/ec_add_r.py
@@ -13,7 +13,7 @@
# limitations under the License.
from functools import cached_property
-from typing import Dict, Optional, Tuple, Union
+from typing import Optional, Union
import numpy as np
import sympy
@@ -83,7 +83,7 @@ def signature(self) -> 'Signature':
[Register('ctrl', QBit()), Register('x', QUInt(self.n)), Register('y', QUInt(self.n))]
)
- def on_classical_vals(self, ctrl, x, y) -> Dict[str, Union['ClassicalValT', sympy.Expr]]:
+ def on_classical_vals(self, ctrl, x, y) -> dict[str, Union['ClassicalValT', sympy.Expr]]:
if ctrl == 0:
return {'ctrl': ctrl, 'x': x, 'y': y}
@@ -91,7 +91,7 @@ def on_classical_vals(self, ctrl, x, y) -> Dict[str, Union['ClassicalValT', symp
result: ECPoint = A + self.R
return {'ctrl': 1, 'x': result.x, 'y': result.y}
- def wire_symbol(self, reg: 'Register', idx: Tuple[int, ...] = tuple()) -> 'WireSymbol':
+ def wire_symbol(self, reg: 'Register', idx: tuple[int, ...] = tuple()) -> 'WireSymbol':
if reg is None:
return Text('')
if reg.name == 'ctrl':
@@ -199,7 +199,7 @@ def qrom(self) -> QROAMClean:
def build_composite_bloq(
self, bb: 'BloqBuilder', ctrl: 'SoquetT', x: 'Soquet', y: 'Soquet'
- ) -> Dict[str, 'SoquetT']:
+ ) -> dict[str, 'SoquetT']:
ctrl = bb.join(np.array(ctrl))
ctrl, a, b, lam_r, *junk = bb.add(self.qrom, selection=ctrl)
@@ -241,7 +241,7 @@ def build_call_graph(self, ssa: 'SympySymbolAllocator') -> 'BloqCountDictT':
self.qrom.adjoint(): 1,
}
- def on_classical_vals(self, ctrl, x, y) -> Dict[str, Union['ClassicalValT', sympy.Expr]]:
+ def on_classical_vals(self, ctrl, x, y) -> dict[str, Union['ClassicalValT', sympy.Expr]]:
# TODO(https://github.com/quantumlib/Qualtran/issues/1476): make ECAdd accept SymbolicInt.
dtype = QMontgomeryUInt(self.n, self.R.mod)
A = ECPoint(
@@ -259,7 +259,7 @@ def on_classical_vals(self, ctrl, x, y) -> Dict[str, Union['ClassicalValT', symp
}
def wire_symbol(
- self, reg: Optional['Register'], idx: Tuple[int, ...] = tuple()
+ self, reg: Optional['Register'], idx: tuple[int, ...] = tuple()
) -> 'WireSymbol':
if reg is None:
return Text(f'ECWindowAddR({self.n=})')
diff --git a/qualtran/bloqs/cryptography/ecc/ec_phase_estimate_r.py b/qualtran/bloqs/cryptography/ecc/ec_phase_estimate_r.py
index eb991c19ab..e2e79261a4 100644
--- a/qualtran/bloqs/cryptography/ecc/ec_phase_estimate_r.py
+++ b/qualtran/bloqs/cryptography/ecc/ec_phase_estimate_r.py
@@ -14,7 +14,7 @@
import functools
from functools import cached_property
-from typing import Dict, Union
+from typing import Union
import numpy as np
import sympy
@@ -83,7 +83,7 @@ def ec_add(self) -> Union[functools.partial[ECAddR], functools.partial[ECWindowA
def num_windows(self) -> int:
return self.n // self.add_window_size
- def build_composite_bloq(self, bb: 'BloqBuilder', x: Soquet, y: Soquet) -> Dict[str, 'SoquetT']:
+ def build_composite_bloq(self, bb: 'BloqBuilder', x: Soquet, y: Soquet) -> dict[str, 'SoquetT']:
if isinstance(self.n, sympy.Expr):
raise DecomposeTypeError("Cannot decompose symbolic `n`.")
ctrl = [bb.add(PlusState()) for _ in range(self.n)]
diff --git a/qualtran/bloqs/cryptography/ecc/find_ecc_private_key.py b/qualtran/bloqs/cryptography/ecc/find_ecc_private_key.py
index f6129af801..d0df45817b 100644
--- a/qualtran/bloqs/cryptography/ecc/find_ecc_private_key.py
+++ b/qualtran/bloqs/cryptography/ecc/find_ecc_private_key.py
@@ -14,7 +14,6 @@
import functools
from functools import cached_property
-from typing import Dict
import sympy
from attrs import frozen
@@ -106,7 +105,7 @@ def ec_pe_r(self) -> functools.partial[ECPhaseEstimateR]:
mul_window_size=self.mul_window_size,
)
- def build_composite_bloq(self, bb: 'BloqBuilder') -> Dict[str, 'SoquetT']:
+ def build_composite_bloq(self, bb: 'BloqBuilder') -> dict[str, 'SoquetT']:
x = bb.add(IntState(bitsize=self.n, val=self.base_point.x))
y = bb.add(IntState(bitsize=self.n, val=self.base_point.y))
diff --git a/qualtran/bloqs/cryptography/rsa/rsa_mod_exp.py b/qualtran/bloqs/cryptography/rsa/rsa_mod_exp.py
index 280bc11da4..0176271de6 100644
--- a/qualtran/bloqs/cryptography/rsa/rsa_mod_exp.py
+++ b/qualtran/bloqs/cryptography/rsa/rsa_mod_exp.py
@@ -13,7 +13,7 @@
# limitations under the License.
import math
from functools import cached_property
-from typing import cast, Dict, Optional, Tuple, Union
+from typing import cast, Optional, Union
import attrs
import numpy as np
@@ -121,7 +121,7 @@ def _CtrlModMul(self, k: 'SymbolicInt'):
"""Helper method to return a `CModMulK` with attributes forwarded."""
return CModMulK(QUInt(self.x_bitsize), k=k, mod=self.mod)
- def build_composite_bloq(self, bb: 'BloqBuilder', exponent: 'Soquet') -> Dict[str, 'SoquetT']:
+ def build_composite_bloq(self, bb: 'BloqBuilder', exponent: 'Soquet') -> dict[str, 'SoquetT']:
if is_symbolic(self.exp_bitsize):
raise DecomposeTypeError(f"Cannot decompose {self} with symbolic `exp_bitsize`.")
# https://en.wikipedia.org/wiki/Modular_exponentiation#Right-to-left_binary_method
@@ -139,11 +139,11 @@ def build_call_graph(self, ssa: 'SympySymbolAllocator') -> 'BloqCountDictT':
k = ssa.new_symbol('k')
return {self._CtrlModMul(k=k): self.exp_bitsize, IntState(val=1, bitsize=self.x_bitsize): 1}
- def on_classical_vals(self, exponent) -> Dict[str, Union['ClassicalValT', sympy.Expr]]:
+ def on_classical_vals(self, exponent) -> dict[str, Union['ClassicalValT', sympy.Expr]]:
return {'exponent': exponent, 'x': (self.base**exponent) % self.mod}
def wire_symbol(
- self, reg: Optional['Register'], idx: Tuple[int, ...] = tuple()
+ self, reg: Optional['Register'], idx: tuple[int, ...] = tuple()
) -> 'WireSymbol':
if reg is None:
return Text(f'{self.base}^e % {self.mod}')
diff --git a/qualtran/bloqs/cryptography/rsa/rsa_phase_estimate.py b/qualtran/bloqs/cryptography/rsa/rsa_phase_estimate.py
index 9416620d05..4737768cde 100644
--- a/qualtran/bloqs/cryptography/rsa/rsa_phase_estimate.py
+++ b/qualtran/bloqs/cryptography/rsa/rsa_phase_estimate.py
@@ -14,7 +14,7 @@
import math
from functools import cached_property
-from typing import Dict, Optional
+from typing import Optional
import attrs
import numpy as np
@@ -104,7 +104,7 @@ def _CtrlModMul(self, k: 'SymbolicInt'):
"""Helper method to return a `CModMulK` with attributes forwarded."""
return CModMulK(QUInt(self.n), k=k, mod=self.mod)
- def build_composite_bloq(self, bb: 'BloqBuilder') -> Dict[str, 'SoquetT']:
+ def build_composite_bloq(self, bb: 'BloqBuilder') -> dict[str, 'SoquetT']:
if is_symbolic(self.n):
raise DecomposeTypeError(f"Cannot decompose {self} with symbolic `n`.")
exponent = [bb.add(PlusState()) for _ in range(2 * self.n)]
diff --git a/qualtran/bloqs/data_loading/qroam_clean.py b/qualtran/bloqs/data_loading/qroam_clean.py
index ab53dc58b9..9c80b0fec9 100644
--- a/qualtran/bloqs/data_loading/qroam_clean.py
+++ b/qualtran/bloqs/data_loading/qroam_clean.py
@@ -14,7 +14,7 @@
import numbers
from collections import defaultdict
from functools import cached_property
-from typing import cast, Dict, List, Optional, Tuple, Type, TYPE_CHECKING, Union
+from typing import cast, Optional, Type, TYPE_CHECKING, Union
import attrs
import numpy as np
@@ -45,7 +45,7 @@
def _alloc_anc_for_reg_except_first(
- bb: 'BloqBuilder', dtype: 'QDType', shape: Tuple[int, ...], dirty: bool
+ bb: 'BloqBuilder', dtype: 'QDType', shape: tuple[int, ...], dirty: bool
) -> 'SoquetT':
if not shape:
return bb.allocate(dtype=dtype, dirty=dirty)
@@ -119,7 +119,7 @@ class QROAMCleanAdjoint(QROMBase, GateWithRegisters): # type: ignore[misc]
Berry et al. (2019). Appendix C.
"""
- log_block_sizes: Tuple[SymbolicInt, ...] = attrs.field(
+ log_block_sizes: tuple[SymbolicInt, ...] = attrs.field(
converter=lambda x: tuple(x.tolist() if isinstance(x, np.ndarray) else x)
)
@@ -131,10 +131,10 @@ def _target_reg_side(self) -> Side:
def build_from_data(
cls: Type['QROAMCleanAdjoint'],
*data: ArrayLike,
- target_bitsizes: Optional[Union[SymbolicInt, Tuple[SymbolicInt, ...]]] = None,
- target_shapes: Tuple[Tuple[SymbolicInt, ...], ...] = (),
+ target_bitsizes: Optional[Union[SymbolicInt, tuple[SymbolicInt, ...]]] = None,
+ target_shapes: tuple[tuple[SymbolicInt, ...], ...] = (),
num_controls: SymbolicInt = 0,
- log_block_sizes: Optional[Union[SymbolicInt, Tuple[SymbolicInt, ...]]] = None,
+ log_block_sizes: Optional[Union[SymbolicInt, tuple[SymbolicInt, ...]]] = None,
) -> 'QROAMCleanAdjoint':
qroam: 'QROAMCleanAdjoint' = cls._build_from_data(
*data,
@@ -147,13 +147,13 @@ def build_from_data(
@classmethod
def build_from_bitsize(
cls: Type['QROAMCleanAdjoint'],
- data_len_or_shape: Union[SymbolicInt, Tuple[SymbolicInt, ...]],
- target_bitsizes: Union[SymbolicInt, Tuple[SymbolicInt, ...]],
+ data_len_or_shape: Union[SymbolicInt, tuple[SymbolicInt, ...]],
+ target_bitsizes: Union[SymbolicInt, tuple[SymbolicInt, ...]],
*,
- target_shapes: Tuple[Tuple[SymbolicInt, ...], ...] = (),
- selection_bitsizes: Tuple[SymbolicInt, ...] = (),
+ target_shapes: tuple[tuple[SymbolicInt, ...], ...] = (),
+ selection_bitsizes: tuple[SymbolicInt, ...] = (),
num_controls: SymbolicInt = 0,
- log_block_sizes: Optional[Union[SymbolicInt, Tuple[SymbolicInt, ...]]] = None,
+ log_block_sizes: Optional[Union[SymbolicInt, tuple[SymbolicInt, ...]]] = None,
) -> 'QROAMCleanAdjoint':
qroam: 'QROAMCleanAdjoint' = cls._build_from_bitsize(
data_len_or_shape,
@@ -165,7 +165,7 @@ def build_from_bitsize(
return qroam.with_log_block_sizes(log_block_sizes=log_block_sizes)
@log_block_sizes.default
- def _default_log_block_sizes(self) -> Tuple[SymbolicInt, ...]:
+ def _default_log_block_sizes(self) -> tuple[SymbolicInt, ...]:
target_bitsize = sum(
bs * prod(shape) for (bs, shape) in zip(self.target_bitsizes, self.target_shapes)
)
@@ -175,7 +175,7 @@ def _default_log_block_sizes(self) -> Tuple[SymbolicInt, ...]:
)
def with_log_block_sizes(
- self, log_block_sizes: Optional[Union[SymbolicInt, Tuple[SymbolicInt, ...]]] = None
+ self, log_block_sizes: Optional[Union[SymbolicInt, tuple[SymbolicInt, ...]]] = None
) -> 'QROAMCleanAdjoint':
if log_block_sizes is None:
return self
@@ -202,7 +202,7 @@ def signature(self) -> Signature:
def adjoint(self) -> 'QROAMClean':
return QROAMClean(**attrs.asdict(self))
- def wire_symbol(self, reg: Optional[Register], idx: Tuple[int, ...] = tuple()) -> 'WireSymbol':
+ def wire_symbol(self, reg: Optional[Register], idx: tuple[int, ...] = tuple()) -> 'WireSymbol':
if reg is None:
return Text('QROAM').adjoint()
name = reg.name
@@ -223,7 +223,7 @@ class QROAMCleanAdjointWrapper(Bloq):
"""Wrapper bloq with signature matching Adjoint(QROAMClean). Delegates to QROAMCleanAdjoint"""
qroam_clean: 'QROAMClean'
- log_block_sizes: Tuple[SymbolicInt, ...] = attrs.field(
+ log_block_sizes: tuple[SymbolicInt, ...] = attrs.field(
converter=lambda x: (
x if x is None else tuple(x.tolist() if isinstance(x, np.ndarray) else x)
)
@@ -234,7 +234,7 @@ def signature(self) -> 'Signature':
return self.qroam_clean.signature.adjoint()
@log_block_sizes.default
- def _log_block_sizes(self) -> Tuple[SymbolicInt, ...]:
+ def _log_block_sizes(self) -> tuple[SymbolicInt, ...]:
# Note: Target bitsize does not matter for adjoint, so setting to 0.
return tuple(
get_optimal_log_block_size_clean_ancilla(ilen, 0, adjoint=True)
@@ -262,8 +262,8 @@ def qroam_clean_adjoint_bloq(self) -> 'QROAMCleanAdjoint':
num_controls=self.qroam_clean.num_controls,
)
- def build_composite_bloq(self, bb: 'BloqBuilder', **soqs: 'SoquetT') -> Dict[str, 'SoquetT']:
- block_sizes = cast(Tuple[int, ...], self.qroam_clean.block_sizes)
+ def build_composite_bloq(self, bb: 'BloqBuilder', **soqs: 'SoquetT') -> dict[str, 'SoquetT']:
+ block_sizes = cast(tuple[int, ...], self.qroam_clean.block_sizes)
for target, adj_target in zip(
self.qroam_clean.target_registers, self.qroam_clean_adjoint_bloq.target_registers
):
@@ -288,11 +288,11 @@ def adjoint(self) -> 'QROAMClean':
return self.qroam_clean
def with_log_block_sizes(
- self, log_block_sizes: Optional[Union[SymbolicInt, Tuple[SymbolicInt, ...]]] = None
+ self, log_block_sizes: Optional[Union[SymbolicInt, tuple[SymbolicInt, ...]]] = None
) -> 'QROAMCleanAdjointWrapper':
return attrs.evolve(self, log_block_sizes=log_block_sizes)
- def wire_symbol(self, reg: Optional[Register], idx: Tuple[int, ...] = tuple()) -> 'WireSymbol':
+ def wire_symbol(self, reg: Optional[Register], idx: tuple[int, ...] = tuple()) -> 'WireSymbol':
if reg is None:
return Text('QROAM').adjoint()
name = reg.name
@@ -357,7 +357,7 @@ class QROAMClean(SelectSwapQROM):
Berry et al. (2019). Appendix A. and B.
"""
- log_block_sizes: Tuple[SymbolicInt, ...] = attrs.field(
+ log_block_sizes: tuple[SymbolicInt, ...] = attrs.field(
converter=lambda x: tuple(x.tolist() if isinstance(x, np.ndarray) else x)
)
use_dirty_ancilla: bool = attrs.field(init=False, default=False, repr=False)
@@ -367,7 +367,7 @@ def _target_reg_side(self) -> Side:
return Side.RIGHT
@log_block_sizes.default
- def _default_log_block_sizes(self) -> Tuple[SymbolicInt, ...]:
+ def _default_log_block_sizes(self) -> tuple[SymbolicInt, ...]:
target_bitsize = sum(
bs * prod(shape) for (bs, shape) in zip(self.target_bitsizes, self.target_shapes)
)
@@ -380,9 +380,9 @@ def _default_log_block_sizes(self) -> Tuple[SymbolicInt, ...]:
def build_from_data(
cls: Type['QROAMClean'],
*data: ArrayLike,
- target_bitsizes: Optional[Union[SymbolicInt, Tuple[SymbolicInt, ...]]] = None,
+ target_bitsizes: Optional[Union[SymbolicInt, tuple[SymbolicInt, ...]]] = None,
num_controls: SymbolicInt = 0,
- log_block_sizes: Optional[Union[SymbolicInt, Tuple[SymbolicInt, ...]]] = None,
+ log_block_sizes: Optional[Union[SymbolicInt, tuple[SymbolicInt, ...]]] = None,
) -> 'QROAMClean':
qroam: 'QROAMClean' = cls._build_from_data(
*data, target_bitsizes=target_bitsizes, num_controls=num_controls
@@ -392,12 +392,12 @@ def build_from_data(
@classmethod
def build_from_bitsize(
cls: Type['QROAMClean'],
- data_len_or_shape: Union[SymbolicInt, Tuple[SymbolicInt, ...]],
- target_bitsizes: Union[SymbolicInt, Tuple[SymbolicInt, ...]],
+ data_len_or_shape: Union[SymbolicInt, tuple[SymbolicInt, ...]],
+ target_bitsizes: Union[SymbolicInt, tuple[SymbolicInt, ...]],
*,
- selection_bitsizes: Tuple[SymbolicInt, ...] = (),
+ selection_bitsizes: tuple[SymbolicInt, ...] = (),
num_controls: SymbolicInt = 0,
- log_block_sizes: Optional[Union[SymbolicInt, Tuple[SymbolicInt, ...]]] = None,
+ log_block_sizes: Optional[Union[SymbolicInt, tuple[SymbolicInt, ...]]] = None,
) -> 'QROAMClean':
qroam: 'QROAMClean' = cls._build_from_bitsize(
data_len_or_shape,
@@ -419,16 +419,16 @@ def signature(self) -> Signature:
)
@cached_property
- def batched_data_permuted(self) -> List[np.ndarray]:
+ def batched_data_permuted(self) -> list[np.ndarray]:
if is_symbolic(*self.block_sizes):
raise ValueError(
f"Cannot decompose SelectSwapQROM bloq with symbolic block sizes. Found {self.block_sizes=}"
)
- block_sizes = cast(Tuple[int, ...], self.block_sizes)
+ block_sizes = cast(tuple[int, ...], self.block_sizes)
ret = []
for data, swz in zip(self.batched_data, self.swap_with_zero_bloqs):
permuted_batched_data = np.zeros(data.shape + block_sizes, dtype=data.dtype)
- for sel_l in np.ndindex(cast(Tuple[int, ...], self.batched_qrom_shape)):
+ for sel_l in np.ndindex(cast(tuple[int, ...], self.batched_qrom_shape)):
for sel_k in np.ndindex(block_sizes):
sel_kwargs = {reg.name: sel for reg, sel in zip(swz.selection_registers, sel_k)}
curr_data = swz.call_classically(**sel_kwargs, targets=np.copy(data[sel_l]))[-1]
@@ -449,7 +449,7 @@ def batched_data_permuted(self) -> List[np.ndarray]:
return ret
@cached_property
- def junk_registers(self) -> Tuple[Register, ...]:
+ def junk_registers(self) -> tuple[Register, ...]:
# The newly allocated registers should be kept around for measurement based uncomputation.
junk_regs = []
block_size = prod(self.block_sizes)
@@ -460,7 +460,7 @@ def junk_registers(self) -> Tuple[Register, ...]:
return tuple(junk_regs)
def build_call_graph(self, ssa: 'SympySymbolAllocator') -> 'BloqCountDictT':
- ret: Dict[Bloq, SymbolicInt] = defaultdict(lambda: 0)
+ ret: dict[Bloq, SymbolicInt] = defaultdict(lambda: 0)
ret[self.qrom_bloq] += 1
for swz in self.swap_with_zero_bloqs:
if any(is_symbolic(s) or s > 0 for s in swz.selection_bitsizes):
@@ -479,17 +479,17 @@ def my_static_costs(self, cost_key: "CostKey"):
def _build_composite_bloq_with_swz_clean(
self,
bb: 'BloqBuilder',
- ctrl: List['SoquetT'],
- selection: List['SoquetT'],
- qrom_targets: List['SoquetT'],
- ) -> Tuple[List['SoquetT'], List['SoquetT'], List['SoquetT']]:
+ ctrl: list['SoquetT'],
+ selection: list['SoquetT'],
+ qrom_targets: list['SoquetT'],
+ ) -> tuple[list['SoquetT'], list['SoquetT'], list['SoquetT']]:
sel_l, sel_k = self._partition_sel_register(bb, selection)
ctrl, sel_l, qrom_targets = self._add_qrom_bloq(bb, ctrl, sel_l, qrom_targets)
sel_k, qrom_targets = self._add_swap_with_zero_bloq(bb, sel_k, qrom_targets)
selection = self._unpartition_sel_register(bb, sel_l, sel_k)
return ctrl, selection, qrom_targets
- def build_composite_bloq(self, bb: 'BloqBuilder', **soqs: 'SoquetT') -> Dict[str, 'SoquetT']:
+ def build_composite_bloq(self, bb: 'BloqBuilder', **soqs: 'SoquetT') -> dict[str, 'SoquetT']:
# Get the ctrl and target register for the SelectSwapQROM.
ctrl = [soqs.pop(reg.name) for reg in self.control_registers]
selection = [soqs.pop(reg.name) for reg in self.selection_registers]
@@ -497,7 +497,7 @@ def build_composite_bloq(self, bb: 'BloqBuilder', **soqs: 'SoquetT') -> Dict[str
raise ValueError(
f"Cannot decompose QROAM bloq with symbolic block sizes. Found {self.block_sizes=}"
)
- block_sizes = cast(Tuple[int, ...], self.block_sizes)
+ block_sizes = cast(tuple[int, ...], self.block_sizes)
# Allocate intermediate clean/dirty ancilla for the underlying QROM call.
qrom_targets = []
for reg in self.target_registers:
@@ -526,9 +526,9 @@ def build_composite_bloq(self, bb: 'BloqBuilder', **soqs: 'SoquetT') -> Dict[str
def on_classical_vals(
self, **vals: Union['sympy.Symbol', 'ClassicalValT']
- ) -> Dict[str, 'ClassicalValT']:
+ ) -> dict[str, 'ClassicalValT']:
vals_without_junk = super().on_classical_vals(**vals)
- selection = cast(Tuple[int, ...], tuple(vals[reg.name] for reg in self.selection_registers))
+ selection = cast(tuple[int, ...], tuple(vals[reg.name] for reg in self.selection_registers))
for d, junk_reg in zip(self.batched_data_permuted, self.junk_registers):
vals_without_junk[junk_reg.name] = d[selection].flat[1:]
return vals_without_junk
@@ -536,7 +536,7 @@ def on_classical_vals(
def adjoint(self) -> 'QROAMCleanAdjointWrapper':
return QROAMCleanAdjointWrapper(self)
- def wire_symbol(self, reg: Optional[Register], idx: Tuple[int, ...] = tuple()) -> 'WireSymbol':
+ def wire_symbol(self, reg: Optional[Register], idx: tuple[int, ...] = tuple()) -> 'WireSymbol':
if reg is None:
return Text('QROAM')
name = reg.name
diff --git a/qualtran/bloqs/data_loading/qrom.py b/qualtran/bloqs/data_loading/qrom.py
index 51b8bcacaa..ad10c2a63d 100644
--- a/qualtran/bloqs/data_loading/qrom.py
+++ b/qualtran/bloqs/data_loading/qrom.py
@@ -14,7 +14,8 @@
"""Quantum read-only memory."""
import numbers
-from typing import cast, Iterable, Iterator, Optional, Sequence, Set, Tuple, TYPE_CHECKING, Union
+from collections.abc import Iterable, Iterator, Sequence
+from typing import cast, Optional, TYPE_CHECKING, Union
import attrs
import cirq
@@ -85,8 +86,8 @@ class QROM(QROMBase, UnaryIterationGate): # type: ignore[misc]
def build_from_data(
cls,
*data: ArrayLike,
- target_bitsizes: Optional[Union[SymbolicInt, Tuple[SymbolicInt, ...]]] = None,
- target_shapes: Tuple[Tuple[SymbolicInt, ...], ...] = (),
+ target_bitsizes: Optional[Union[SymbolicInt, tuple[SymbolicInt, ...]]] = None,
+ target_shapes: tuple[tuple[SymbolicInt, ...], ...] = (),
num_controls: SymbolicInt = 0,
) -> 'QROM':
return cls._build_from_data(
@@ -99,11 +100,11 @@ def build_from_data(
@classmethod
def build_from_bitsize(
cls,
- data_len_or_shape: Union[SymbolicInt, Tuple[SymbolicInt, ...]],
- target_bitsizes: Union[SymbolicInt, Tuple[SymbolicInt, ...]],
+ data_len_or_shape: Union[SymbolicInt, tuple[SymbolicInt, ...]],
+ target_bitsizes: Union[SymbolicInt, tuple[SymbolicInt, ...]],
*,
- target_shapes: Tuple[Tuple[SymbolicInt, ...], ...] = (),
- selection_bitsizes: Tuple[SymbolicInt, ...] = (),
+ target_shapes: tuple[tuple[SymbolicInt, ...], ...] = (),
+ selection_bitsizes: tuple[SymbolicInt, ...] = (),
num_controls: SymbolicInt = 0,
) -> 'QROM':
return cls._build_from_bitsize(
@@ -116,15 +117,15 @@ def build_from_bitsize(
def _load_nth_data(
self,
- selection_idx: Tuple[int, ...],
- ctrl_qubits: Tuple[cirq.Qid, ...] = (),
+ selection_idx: tuple[int, ...],
+ ctrl_qubits: tuple[cirq.Qid, ...] = (),
**target_regs: NDArray[cirq.Qid], # type: ignore[type-var]
) -> Iterator[cirq.OP_TREE]:
for i, d in enumerate(self.data):
target = target_regs.get(f'target{i}_', np.array([]))
target_bitsize, target_shape = self.target_bitsizes[i], self.target_shapes[i]
assert all(isinstance(x, (int, numbers.Integral)) for x in target_shape)
- for idx in np.ndindex(cast(Tuple[int, ...], target_shape)):
+ for idx in np.ndindex(cast(tuple[int, ...], target_shape)):
data_to_load = int(d[selection_idx + idx])
yield XorK(QUInt(target_bitsize), data_to_load).on(*target[idx]).controlled_by(
*ctrl_qubits
@@ -160,7 +161,7 @@ def decompose_from_registers(
return super().decompose_from_registers(context=context, **quregs)
raise DecomposeTypeError(f"Cannot decompose symbolic {self} with no data.")
- def _break_early(self, selection_index_prefix: Tuple[int, ...], l: int, r: int):
+ def _break_early(self, selection_index_prefix: tuple[int, ...], l: int, r: int):
if not self.has_data():
return False
@@ -195,7 +196,7 @@ def my_static_costs(self, cost_key: "CostKey"):
def __str__(self):
return f'QROM({self.data_shape}, {self.target_shapes}, {self.target_bitsizes})'
- def wire_symbol(self, reg: Optional[Register], idx: Tuple[int, ...] = tuple()) -> 'WireSymbol':
+ def wire_symbol(self, reg: Optional[Register], idx: tuple[int, ...] = tuple()) -> 'WireSymbol':
if reg is None:
return Text('QROM')
name = reg.name
@@ -215,20 +216,20 @@ def wire_symbol(self, reg: Optional[Register], idx: Tuple[int, ...] = tuple()) -
return Circle()
raise ValueError(f'Unrecognized register name {name}')
- def nth_operation_callgraph(self, **kwargs: int) -> Set['BloqCountT']:
+ def nth_operation_callgraph(self, **kwargs: int) -> set['BloqCountT']:
selection_idx = tuple(kwargs[reg.name] for reg in self.selection_registers)
ret = 0
for i, d in enumerate(self.data):
target_bitsize, target_shape = self.target_bitsizes[i], self.target_shapes[i]
assert all(isinstance(x, (int, numbers.Integral)) for x in target_shape)
- for idx in np.ndindex(cast(Tuple[int, ...], target_shape)):
+ for idx in np.ndindex(cast(tuple[int, ...], target_shape)):
data_to_load = int(d[selection_idx + idx])
ret += data_to_load.bit_count()
return {(CNOT(), ret)}
def build_call_graph(
self, ssa: 'SympySymbolAllocator'
- ) -> Union['BloqCountDictT', Set['BloqCountT']]:
+ ) -> Union['BloqCountDictT', set['BloqCountT']]:
if self.has_data():
return super().build_call_graph(ssa=ssa)
n_and = prod(self.data_shape) - 2 + self.num_controls
diff --git a/qualtran/bloqs/data_loading/qrom_base.py b/qualtran/bloqs/data_loading/qrom_base.py
index efe1c5e230..4eba8a4599 100644
--- a/qualtran/bloqs/data_loading/qrom_base.py
+++ b/qualtran/bloqs/data_loading/qrom_base.py
@@ -16,7 +16,7 @@
import abc
import numbers
from functools import cached_property
-from typing import cast, Dict, Optional, Tuple, Type, TypeVar, Union
+from typing import cast, Optional, Type, TypeVar, Union
import attrs
import numpy as np
@@ -30,7 +30,7 @@
QROM_T = TypeVar('QROM_T', bound='QROMBase')
-def _data_or_shape_to_tuple(data_or_shape: Tuple[Union[NDArray, Shaped], ...]) -> Tuple:
+def _data_or_shape_to_tuple(data_or_shape: tuple[Union[NDArray, Shaped], ...]) -> tuple:
return tuple(tuple(d.flatten()) if isinstance(d, np.ndarray) else d for d in data_or_shape)
@@ -150,17 +150,17 @@ class QROMBase(metaclass=abc.ABCMeta):
num_controls: The number of controls to instanstiate a controlled version of this bloq.
"""
- data_or_shape: Tuple[Union[NDArray, Shaped], ...] = attrs.field(
+ data_or_shape: tuple[Union[NDArray, Shaped], ...] = attrs.field(
converter=lambda x: tuple(np.array(y) if isinstance(y, (list, tuple)) else y for y in x),
eq=_data_or_shape_to_tuple,
)
- selection_bitsizes: Tuple[SymbolicInt, ...] = attrs.field(
+ selection_bitsizes: tuple[SymbolicInt, ...] = attrs.field(
converter=lambda x: tuple(x.tolist() if isinstance(x, np.ndarray) else x)
)
- target_bitsizes: Tuple[SymbolicInt, ...] = attrs.field(
+ target_bitsizes: tuple[SymbolicInt, ...] = attrs.field(
converter=lambda x: tuple(x.tolist() if isinstance(x, np.ndarray) else x)
)
- target_shapes: Tuple[Tuple[SymbolicInt, ...], ...] = attrs.field(
+ target_shapes: tuple[tuple[SymbolicInt, ...], ...] = attrs.field(
converter=lambda x: tuple(tuple(y) for y in x)
)
num_controls: SymbolicInt = 0
@@ -179,8 +179,8 @@ def _default_target_shapes(self):
return ((),) * len(self.data_or_shape)
@cached_property
- def data_shape(self) -> Tuple[SymbolicInt, ...]:
- ret: Tuple[SymbolicInt, ...] = ()
+ def data_shape(self) -> tuple[SymbolicInt, ...]:
+ ret: tuple[SymbolicInt, ...] = ()
for data_or_shape, target_shape in zip(self.data_or_shape, self.target_shapes):
data_shape = shape(data_or_shape)
if target_shape:
@@ -195,11 +195,11 @@ def has_data(self) -> bool:
return all(isinstance(d, np.ndarray) for d in self.data_or_shape)
@property
- def data(self) -> Tuple[np.ndarray, ...]:
+ def data(self) -> tuple[np.ndarray, ...]:
if not self.has_data():
raise ValueError(f"Data not available for symbolic QROM {self}")
assert all(isinstance(d, np.ndarray) for d in self.data_or_shape)
- return cast(Tuple[np.ndarray, ...], self.data_or_shape)
+ return cast(tuple[np.ndarray, ...], self.data_or_shape)
def __attrs_post_init__(self):
assert all([is_symbolic(s) or isinstance(s, int) for s in self.selection_bitsizes])
@@ -220,8 +220,8 @@ def __attrs_post_init__(self):
def _build_from_data(
cls: Type[QROM_T],
*data: ArrayLike,
- target_bitsizes: Optional[Union[SymbolicInt, Tuple[SymbolicInt, ...]]] = None,
- target_shapes: Tuple[Tuple[SymbolicInt, ...], ...] = (),
+ target_bitsizes: Optional[Union[SymbolicInt, tuple[SymbolicInt, ...]]] = None,
+ target_shapes: tuple[tuple[SymbolicInt, ...], ...] = (),
num_controls: SymbolicInt = 0,
) -> QROM_T:
_data = [np.array(d, dtype=int) for d in data]
@@ -250,14 +250,14 @@ def with_data(self: QROM_T, *data: ArrayLike) -> QROM_T:
@classmethod
def _build_from_bitsize(
cls: Type[QROM_T],
- data_len_or_shape: Union[SymbolicInt, Tuple[SymbolicInt, ...]],
- target_bitsizes: Union[SymbolicInt, Tuple[SymbolicInt, ...]],
+ data_len_or_shape: Union[SymbolicInt, tuple[SymbolicInt, ...]],
+ target_bitsizes: Union[SymbolicInt, tuple[SymbolicInt, ...]],
*,
- target_shapes: Tuple[Tuple[SymbolicInt, ...], ...] = (),
- selection_bitsizes: Tuple[SymbolicInt, ...] = (),
+ target_shapes: tuple[tuple[SymbolicInt, ...], ...] = (),
+ selection_bitsizes: tuple[SymbolicInt, ...] = (),
num_controls: SymbolicInt = 0,
) -> QROM_T:
- data_shape: Tuple[SymbolicInt, ...] = (
+ data_shape: tuple[SymbolicInt, ...] = (
(data_len_or_shape,)
if isinstance(data_len_or_shape, (int, numbers.Number, sympy.Basic))
else data_len_or_shape
@@ -279,11 +279,11 @@ def _build_from_bitsize(
)
@cached_property
- def control_registers(self) -> Tuple[Register, ...]:
+ def control_registers(self) -> tuple[Register, ...]:
return () if not self.num_controls else (Register('control', QAny(self.num_controls)),)
@cached_property
- def selection_registers(self) -> Tuple[Register, ...]:
+ def selection_registers(self) -> tuple[Register, ...]:
types = [
BQUInt(sb, l)
for l, sb in zip(self.data_shape, self.selection_bitsizes)
@@ -298,7 +298,7 @@ def _target_reg_side(self) -> Side:
return Side.THRU
@cached_property
- def target_registers(self) -> Tuple[Register, ...]:
+ def target_registers(self) -> tuple[Register, ...]:
return tuple(
Register(f'target{i}_', QAny(l), shape=sh, side=self._target_reg_side)
for i, (l, sh) in enumerate(zip(self.target_bitsizes, self.target_shapes))
@@ -307,10 +307,10 @@ def target_registers(self) -> Tuple[Register, ...]:
def on_classical_vals(
self, **vals: Union['sympy.Symbol', 'ClassicalValT']
- ) -> Dict[str, 'ClassicalValT']:
+ ) -> dict[str, 'ClassicalValT']:
if not self.has_data():
raise NotImplementedError(f'Symbolic {self} does not support classical simulation')
- vals = cast(Dict[str, 'ClassicalValT'], vals)
+ vals = cast(dict[str, 'ClassicalValT'], vals)
if self.num_controls > 0:
control = vals['control']
if control != 2**self.num_controls - 1:
@@ -321,7 +321,7 @@ def on_classical_vals(
n_dim = len(self.selection_registers)
if n_dim == 0:
- idx: Union[int, Tuple[int, ...]] = 0
+ idx: Union[int, tuple[int, ...]] = 0
selections = {}
elif n_dim == 1:
idx = int(vals.pop('selection', 0))
diff --git a/qualtran/bloqs/data_loading/select_swap_qrom.py b/qualtran/bloqs/data_loading/select_swap_qrom.py
index 6d1d5407d7..38f8205593 100644
--- a/qualtran/bloqs/data_loading/select_swap_qrom.py
+++ b/qualtran/bloqs/data_loading/select_swap_qrom.py
@@ -14,7 +14,7 @@
import numbers
from collections import defaultdict
from functools import cached_property
-from typing import cast, Dict, List, Optional, Tuple, Type, TYPE_CHECKING, TypeVar, Union
+from typing import cast, Optional, Type, TYPE_CHECKING, TypeVar, Union
import attrs
import cirq
@@ -68,14 +68,14 @@ def find_optimal_log_block_size(
if k < 0:
return 0
- def value(kk: List[int]):
+ def value(kk: list[int]):
return iteration_length / np.power(2, kk) + target_bitsize * (np.power(2, kk) - 1)
k_int = [np.floor(k), np.ceil(k)] # restrict optimal k to integers
return int(k_int[np.argmin(value(k_int))]) # obtain optimal k
-def _find_optimal_log_block_size_helper(qrom: 'SelectSwapQROM') -> Tuple[SymbolicInt, ...]:
+def _find_optimal_log_block_size_helper(qrom: 'SelectSwapQROM') -> tuple[SymbolicInt, ...]:
target_bitsize = sum(qrom.target_bitsizes) * sum(prod(shape) for shape in qrom.target_shapes)
return tuple(
find_optimal_log_block_size(ilen, target_bitsize, qrom.use_dirty_ancilla)
@@ -84,7 +84,7 @@ def _find_optimal_log_block_size_helper(qrom: 'SelectSwapQROM') -> Tuple[Symboli
def _alloc_anc_for_reg(
- bb: 'BloqBuilder', dtype: 'QDType', shape: Tuple[int, ...], dirty: bool
+ bb: 'BloqBuilder', dtype: 'QDType', shape: tuple[int, ...], dirty: bool
) -> 'SoquetT':
if not shape:
return bb.allocate(dtype=dtype, dirty=dirty)
@@ -139,7 +139,7 @@ class SelectSwapQROM(QROMBase, GateWithRegisters): # type: ignore[misc]
Berry et al. 2019. Appendix A. and B.
"""
- log_block_sizes: Tuple[SymbolicInt, ...] = attrs.field(
+ log_block_sizes: tuple[SymbolicInt, ...] = attrs.field(
converter=lambda x: (
tuple(x.tolist() if isinstance(x, np.ndarray) else x) if x is not None else x
),
@@ -170,9 +170,9 @@ def is_symbolic(self) -> bool:
def build_from_data(
cls: Type['SelectSwapQROM'],
*data: ArrayLike,
- target_bitsizes: Optional[Union[SymbolicInt, Tuple[SymbolicInt, ...]]] = None,
+ target_bitsizes: Optional[Union[SymbolicInt, tuple[SymbolicInt, ...]]] = None,
num_controls: SymbolicInt = 0,
- log_block_sizes: Optional[Union[SymbolicInt, Tuple[SymbolicInt, ...]]] = None,
+ log_block_sizes: Optional[Union[SymbolicInt, tuple[SymbolicInt, ...]]] = None,
use_dirty_ancilla: bool = True,
) -> 'SelectSwapQROM':
qroam: 'SelectSwapQROM' = cls._build_from_data(
@@ -186,12 +186,12 @@ def build_from_data(
@classmethod
def build_from_bitsize(
cls: Type['SelectSwapQROM'],
- data_len_or_shape: Union[SymbolicInt, Tuple[SymbolicInt, ...]],
- target_bitsizes: Union[SymbolicInt, Tuple[SymbolicInt, ...]],
+ data_len_or_shape: Union[SymbolicInt, tuple[SymbolicInt, ...]],
+ target_bitsizes: Union[SymbolicInt, tuple[SymbolicInt, ...]],
*,
- selection_bitsizes: Tuple[SymbolicInt, ...] = (),
+ selection_bitsizes: tuple[SymbolicInt, ...] = (),
num_controls: SymbolicInt = 0,
- log_block_sizes: Optional[Union[SymbolicInt, Tuple[SymbolicInt, ...]]] = None,
+ log_block_sizes: Optional[Union[SymbolicInt, tuple[SymbolicInt, ...]]] = None,
use_dirty_ancilla: bool = True,
) -> 'SelectSwapQROM':
qroam: 'SelectSwapQROM' = cls._build_from_bitsize(
@@ -207,7 +207,7 @@ def build_from_bitsize(
def with_log_block_sizes(
self: SelSwapQROM_T,
- log_block_sizes: Optional[Union[SymbolicInt, Tuple[SymbolicInt, ...]]] = None,
+ log_block_sizes: Optional[Union[SymbolicInt, tuple[SymbolicInt, ...]]] = None,
) -> 'SelSwapQROM_T':
if log_block_sizes is None:
return self
@@ -218,30 +218,30 @@ def with_log_block_sizes(
return attrs.evolve(self, log_block_sizes=log_block_sizes)
@cached_property
- def block_sizes(self) -> Tuple[SymbolicInt, ...]:
+ def block_sizes(self) -> tuple[SymbolicInt, ...]:
return tuple(2**log_K for log_K in self.log_block_sizes)
@cached_property
- def batched_qrom_shape(self) -> Tuple[SymbolicInt, ...]:
+ def batched_qrom_shape(self) -> tuple[SymbolicInt, ...]:
return tuple(ceil(N / K) for N, K in zip(self.data_shape, self.block_sizes))
@cached_property
- def batched_qrom_selection_bitsizes(self) -> Tuple[SymbolicInt, ...]:
+ def batched_qrom_selection_bitsizes(self) -> tuple[SymbolicInt, ...]:
return tuple(s - log_K for s, log_K in zip(self.selection_bitsizes, self.log_block_sizes))
@cached_property
- def padded_data(self) -> List[np.ndarray]:
+ def padded_data(self) -> list[np.ndarray]:
pad_width = tuple(
(0, ceil(N / K) * K - N) for N, K in zip(self.data_shape, self.block_sizes)
)
return [np.pad(d, pad_width) for d in self.data]
@cached_property
- def batched_data_shape(self) -> Tuple[int, ...]:
- return cast(Tuple[int, ...], self.batched_qrom_shape + self.block_sizes)
+ def batched_data_shape(self) -> tuple[int, ...]:
+ return cast(tuple[int, ...], self.batched_qrom_shape + self.block_sizes)
@cached_property
- def batched_data(self) -> List[np.ndarray]:
+ def batched_data(self) -> list[np.ndarray]:
# In SelectSwapQROM, for N-dimensional data (one or more datasets), you pick block sizes for
# each dimension and load a batched N-dimensional output "at-once" using a traditional QROM read
# followed by an N-dimensional SwapWithZero swap.
@@ -251,7 +251,7 @@ def batched_data(self) -> List[np.ndarray]:
batched_data = [np.zeros(self.batched_data_shape, dtype=int) for _ in self.target_bitsizes]
block_slices = [slice(0, k) for k in self.block_sizes]
for i, data in enumerate(self.padded_data):
- for batch_idx in np.ndindex(cast(Tuple[int, ...], self.batched_qrom_shape)):
+ for batch_idx in np.ndindex(cast(tuple[int, ...], self.batched_qrom_shape)):
data_idx = [slice(x * k, (x + 1) * k) for x, k in zip(batch_idx, self.block_sizes)]
batched_data[i][(*batch_idx, *block_slices)] = data[tuple(data_idx)]
return batched_data
@@ -268,7 +268,7 @@ def qrom_bloq(self) -> QROM:
return qrom if is_symbolic(self) else qrom.with_data(*self.batched_data)
@cached_property
- def swap_with_zero_bloqs(self) -> List[SwapWithZero]:
+ def swap_with_zero_bloqs(self) -> list[SwapWithZero]:
return [
SwapWithZero(
self.log_block_sizes,
@@ -279,7 +279,7 @@ def swap_with_zero_bloqs(self) -> List[SwapWithZero]:
]
def build_call_graph(self, ssa: 'SympySymbolAllocator') -> 'BloqCountDictT':
- ret: Dict[Bloq, SymbolicInt] = defaultdict(lambda: 0)
+ ret: dict[Bloq, SymbolicInt] = defaultdict(lambda: 0)
toggle_overhead = 2 if self.use_dirty_ancilla else 1
ret[self.qrom_bloq] += 1
ret[self.qrom_bloq.adjoint()] += 1
@@ -294,11 +294,11 @@ def build_call_graph(self, ssa: 'SympySymbolAllocator') -> 'BloqCountDictT':
def _add_qrom_bloq(
self,
bb: 'BloqBuilder',
- ctrls: List['SoquetT'],
- sel_l: List['SoquetT'],
- targets: List['SoquetT'],
+ ctrls: list['SoquetT'],
+ sel_l: list['SoquetT'],
+ targets: list['SoquetT'],
uncompute: bool = False,
- ) -> Tuple[List['SoquetT'], List['SoquetT'], List['SoquetT']]:
+ ) -> tuple[list['SoquetT'], list['SoquetT'], list['SoquetT']]:
in_soqs = {reg.name: soq for reg, soq in zip(self.qrom_bloq.control_registers, ctrls)}
in_soqs |= {reg.name: soq for reg, soq in zip(self.qrom_bloq.selection_registers, sel_l)}
in_soqs |= {reg.name: soq for reg, soq in zip(self.qrom_bloq.target_registers, targets)}
@@ -311,15 +311,15 @@ def _add_qrom_bloq(
def _add_swap_with_zero_bloq(
self,
bb: 'BloqBuilder',
- selection: List['SoquetT'],
- targets: List['SoquetT'],
+ selection: list['SoquetT'],
+ targets: list['SoquetT'],
uncompute: bool = False,
- ) -> Tuple[List['SoquetT'], List['SoquetT']]:
+ ) -> tuple[list['SoquetT'], list['SoquetT']]:
# Get soquets for SwapWithZero
assert len(targets) == len(self.swap_with_zero_bloqs)
sel_names = [reg.name for reg in self.swap_with_zero_bloqs[0].selection_registers]
soqs = {sel_name: soq for sel_name, soq in zip(sel_names, selection)}
- out_targets: List['SoquetT'] = []
+ out_targets: list['SoquetT'] = []
for target, swz in zip(targets, self.swap_with_zero_bloqs):
soqs['targets'] = target
soqs = bb.add_d(swz.adjoint() if uncompute else swz, **soqs)
@@ -327,8 +327,8 @@ def _add_swap_with_zero_bloq(
return [soqs[reg_name] for reg_name in sel_names], out_targets
def _add_cnot(
- self, bb: 'BloqBuilder', qrom_targets: List['SoquetT'], target: List['SoquetT']
- ) -> Tuple[List['SoquetT'], List['SoquetT']]:
+ self, bb: 'BloqBuilder', qrom_targets: list['SoquetT'], target: list['SoquetT']
+ ) -> tuple[list['SoquetT'], list['SoquetT']]:
for i, qrom_reg in enumerate(qrom_targets):
assert isinstance(qrom_reg, np.ndarray) # Make mypy happy.
idx = np.unravel_index(0, qrom_reg.shape)
@@ -338,7 +338,7 @@ def _add_cnot(
return qrom_targets, target
@cached_property
- def _partition_selection_reg_bloqs(self) -> List[Partition]:
+ def _partition_selection_reg_bloqs(self) -> list[Partition]:
partition_bloqs = []
for reg, k in zip(self.selection_registers, self.log_block_sizes):
preg = (
@@ -349,8 +349,8 @@ def _partition_selection_reg_bloqs(self) -> List[Partition]:
return partition_bloqs
def _partition_sel_register(
- self, bb: 'BloqBuilder', selection: List['SoquetT']
- ) -> Tuple[List['SoquetT'], List['SoquetT']]:
+ self, bb: 'BloqBuilder', selection: list['SoquetT']
+ ) -> tuple[list['SoquetT'], list['SoquetT']]:
sel_l, sel_k = [], []
for sel, pbloq in zip(selection, self._partition_selection_reg_bloqs):
sl, sk = bb.add(pbloq, x=sel)
@@ -359,8 +359,8 @@ def _partition_sel_register(
return sel_l, sel_k
def _unpartition_sel_register(
- self, bb: 'BloqBuilder', sel_l: List['SoquetT'], sel_k: List['SoquetT']
- ) -> List['SoquetT']:
+ self, bb: 'BloqBuilder', sel_l: list['SoquetT'], sel_k: list['SoquetT']
+ ) -> list['SoquetT']:
selection = []
for l, k, pbloq in zip(sel_l, sel_k, self._partition_selection_reg_bloqs):
selection.append(bb.add(pbloq.adjoint(), l=l, k=k))
@@ -369,11 +369,11 @@ def _unpartition_sel_register(
def _build_composite_bloq_with_swz(
self,
bb: 'BloqBuilder',
- ctrl: List['SoquetT'],
- selection: List['SoquetT'],
- target: List['SoquetT'],
- qrom_targets: List['SoquetT'],
- ) -> Tuple[List['SoquetT'], List['SoquetT'], List['SoquetT'], List['SoquetT']]:
+ ctrl: list['SoquetT'],
+ selection: list['SoquetT'],
+ target: list['SoquetT'],
+ qrom_targets: list['SoquetT'],
+ ) -> tuple[list['SoquetT'], list['SoquetT'], list['SoquetT'], list['SoquetT']]:
sel_l, sel_k = self._partition_sel_register(bb, selection)
# Partition selection registers into l & k
ctrl, sel_l, qrom_targets = self._add_qrom_bloq(bb, ctrl, sel_l, qrom_targets)
@@ -396,11 +396,11 @@ def _build_composite_bloq_with_swz(
def _build_composite_bloq_without_swz(
self,
bb: 'BloqBuilder',
- ctrl: List['SoquetT'],
- selection: List['SoquetT'],
- target: List['SoquetT'],
- qrom_targets: List['SoquetT'],
- ) -> Tuple[List['SoquetT'], List['SoquetT'], List['SoquetT'], List['SoquetT']]:
+ ctrl: list['SoquetT'],
+ selection: list['SoquetT'],
+ target: list['SoquetT'],
+ qrom_targets: list['SoquetT'],
+ ) -> tuple[list['SoquetT'], list['SoquetT'], list['SoquetT'], list['SoquetT']]:
ctrl, selection, qrom_targets = self._add_qrom_bloq(bb, ctrl, selection, qrom_targets)
qrom_targets, target = self._add_cnot(bb, qrom_targets, target)
ctrl, selection, qrom_targets = self._add_qrom_bloq(
@@ -410,7 +410,7 @@ def _build_composite_bloq_without_swz(
qrom_targets, target = self._add_cnot(bb, qrom_targets, target)
return ctrl, selection, target, qrom_targets
- def build_composite_bloq(self, bb: 'BloqBuilder', **soqs: 'SoquetT') -> Dict[str, 'SoquetT']:
+ def build_composite_bloq(self, bb: 'BloqBuilder', **soqs: 'SoquetT') -> dict[str, 'SoquetT']:
# Get the ctrl and target register for the SelectSwapQROM.
ctrl = [soqs.pop(reg.name) for reg in self.control_registers]
selection = [soqs.pop(reg.name) for reg in self.selection_registers]
@@ -420,7 +420,7 @@ def build_composite_bloq(self, bb: 'BloqBuilder', **soqs: 'SoquetT') -> Dict[str
raise DecomposeTypeError(
f"Cannot decompose SelectSwapQROM bloq with symbolic block sizes. Found {self.block_sizes=}"
)
- block_sizes = cast(Tuple[int, ...], self.block_sizes)
+ block_sizes = cast(tuple[int, ...], self.block_sizes)
qrom_targets = [
_alloc_anc_for_reg(bb, QAny(reg.dtype.num_qubits), block_sizes, self.use_dirty_ancilla)
for reg in self.target_registers
@@ -469,7 +469,7 @@ def my_static_costs(self, cost_key: "CostKey"):
return NotImplemented
- def wire_symbol(self, reg: Optional[Register], idx: Tuple[int, ...] = tuple()) -> 'WireSymbol':
+ def wire_symbol(self, reg: Optional[Register], idx: tuple[int, ...] = tuple()) -> 'WireSymbol':
if reg is None:
return Text('QROAM')
name = reg.name
diff --git a/qualtran/bloqs/for_testing/atom.py b/qualtran/bloqs/for_testing/atom.py
index 210ede7e84..096a4ec56e 100644
--- a/qualtran/bloqs/for_testing/atom.py
+++ b/qualtran/bloqs/for_testing/atom.py
@@ -13,7 +13,7 @@
# limitations under the License.
from functools import cached_property
-from typing import Dict, List, Optional, TYPE_CHECKING
+from typing import Optional, TYPE_CHECKING
import attrs
import numpy as np
@@ -54,8 +54,8 @@ def decompose_bloq(self) -> 'CompositeBloq':
raise DecomposeTypeError(f"{self} is atomic")
def my_tensors(
- self, incoming: Dict[str, 'ConnectionT'], outgoing: Dict[str, 'ConnectionT']
- ) -> List['qtn.Tensor']:
+ self, incoming: dict[str, 'ConnectionT'], outgoing: dict[str, 'ConnectionT']
+ ) -> list['qtn.Tensor']:
import quimb.tensor as qtn
return [
@@ -93,8 +93,8 @@ def decompose_bloq(self) -> 'CompositeBloq':
raise DecomposeTypeError(f"{self} is atomic")
def my_tensors(
- self, incoming: Dict[str, 'ConnectionT'], outgoing: Dict[str, 'ConnectionT']
- ) -> List['qtn.Tensor']:
+ self, incoming: dict[str, 'ConnectionT'], outgoing: dict[str, 'ConnectionT']
+ ) -> list['qtn.Tensor']:
import quimb.tensor as qtn
_I = [[1, 0], [0, 1]]
@@ -138,8 +138,8 @@ def decompose_bloq(self) -> 'CompositeBloq':
raise DecomposeTypeError(f"{self} is atomic")
def my_tensors(
- self, incoming: Dict[str, 'ConnectionT'], outgoing: Dict[str, 'ConnectionT']
- ) -> List['qtn.Tensor']:
+ self, incoming: dict[str, 'ConnectionT'], outgoing: dict[str, 'ConnectionT']
+ ) -> list['qtn.Tensor']:
from qualtran.cirq_interop._cirq_to_bloq import _my_tensors_from_gate
return _my_tensors_from_gate(self, self.signature, incoming=incoming, outgoing=outgoing)
diff --git a/qualtran/bloqs/for_testing/casting.py b/qualtran/bloqs/for_testing/casting.py
index d78863d361..a739220f4a 100644
--- a/qualtran/bloqs/for_testing/casting.py
+++ b/qualtran/bloqs/for_testing/casting.py
@@ -13,7 +13,6 @@
# limitations under the License.
from functools import cached_property
-from typing import Dict
from attrs import frozen
@@ -44,7 +43,7 @@ def signature(self) -> Signature:
def build_composite_bloq(
self, bb: 'BloqBuilder', *, a: 'Soquet', b: 'Soquet'
- ) -> Dict[str, 'Soquet']:
+ ) -> dict[str, 'Soquet']:
cast = Cast(b.reg.dtype, a.reg.dtype)
b = bb.add(cast, reg=b)
assert isinstance(a.reg.dtype, (QInt, QUInt, QMontgomeryUInt))
diff --git a/qualtran/bloqs/for_testing/costing.py b/qualtran/bloqs/for_testing/costing.py
index bef3826962..efacdfad54 100644
--- a/qualtran/bloqs/for_testing/costing.py
+++ b/qualtran/bloqs/for_testing/costing.py
@@ -11,7 +11,8 @@
# 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.
-from typing import Any, Sequence, Tuple
+from collections.abc import Sequence
+from typing import Any
from attrs import field, frozen
@@ -19,14 +20,14 @@
from qualtran.resource_counting import BloqCountDictT, BloqCountT, CostKey, SympySymbolAllocator
-def _convert_callees(callees: Sequence[BloqCountT]) -> Tuple[BloqCountT, ...]:
+def _convert_callees(callees: Sequence[BloqCountT]) -> tuple[BloqCountT, ...]:
# Convert to tuples in a type-checked way.
return tuple(callees)
def _convert_static_costs(
- static_costs: Sequence[Tuple[CostKey, Any]]
-) -> Tuple[Tuple[CostKey, Any], ...]:
+ static_costs: Sequence[tuple[CostKey, Any]]
+) -> tuple[tuple[CostKey, Any], ...]:
# Convert to tuples in a type-checked way.
return tuple(static_costs)
@@ -38,7 +39,7 @@ class CostingBloq(Bloq):
name: str
num_qubits: int
callees: Sequence[BloqCountT] = field(converter=_convert_callees, factory=tuple)
- static_costs: Sequence[Tuple[CostKey, Any]] = field(
+ static_costs: Sequence[tuple[CostKey, Any]] = field(
converter=_convert_static_costs, factory=tuple
)
diff --git a/qualtran/bloqs/for_testing/interior_alloc.py b/qualtran/bloqs/for_testing/interior_alloc.py
index 1a25add1c9..5bf45e7397 100644
--- a/qualtran/bloqs/for_testing/interior_alloc.py
+++ b/qualtran/bloqs/for_testing/interior_alloc.py
@@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from functools import cached_property
-from typing import Dict, Union
+from typing import Union
import sympy
from attrs import frozen
@@ -34,7 +34,7 @@ class InteriorAlloc(Bloq):
def signature(self) -> 'Signature':
return Signature.build(x=self.n, y=self.n)
- def build_composite_bloq(self, bb: 'BloqBuilder', x: Soquet, y: Soquet) -> Dict[str, 'SoquetT']:
+ def build_composite_bloq(self, bb: 'BloqBuilder', x: Soquet, y: Soquet) -> dict[str, 'SoquetT']:
middle = bb.allocate(self.n)
x, middle = bb.add(Swap(self.n), x=x, y=middle)
middle, y = bb.add(Swap(self.n), x=middle, y=y)
diff --git a/qualtran/bloqs/for_testing/large_bloq.py b/qualtran/bloqs/for_testing/large_bloq.py
index 810a9d4e35..1d4ee89738 100644
--- a/qualtran/bloqs/for_testing/large_bloq.py
+++ b/qualtran/bloqs/for_testing/large_bloq.py
@@ -12,8 +12,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-from typing import Dict, List
-
import numpy as np
from attrs import frozen
@@ -31,9 +29,9 @@ class LargeBloq(Bloq):
def signature(self) -> 'Signature':
return Signature.build(select=self.n_select, target=1)
- def build_composite_bloq(self, bb: 'BloqBuilder', select, target) -> Dict[str, 'SoquetT']:
+ def build_composite_bloq(self, bb: 'BloqBuilder', select, target) -> dict[str, 'SoquetT']:
sel = bb.split(select)
- ancs: List[Soquet] = [None] * self.n_select # type: ignore
+ ancs: list[Soquet] = [None] * self.n_select # type: ignore
ancs[0] = sel[0]
cvs = QUInt(self.n_select - 1).to_bits_array(np.arange(self.n_ops) % (self.n_select - 1))
diff --git a/qualtran/bloqs/for_testing/many_registers.py b/qualtran/bloqs/for_testing/many_registers.py
index 99f89f1589..4f2db2d7af 100644
--- a/qualtran/bloqs/for_testing/many_registers.py
+++ b/qualtran/bloqs/for_testing/many_registers.py
@@ -13,7 +13,6 @@
# limitations under the License.
from functools import cached_property
-from typing import Dict
import numpy as np
from attrs import frozen
@@ -54,7 +53,7 @@ def signature(self) -> Signature:
def build_composite_bloq(
self, bb: 'BloqBuilder', xx: 'SoquetT', yy: NDArray['Soquet'], zz: Soquet # type: ignore[type-var]
- ) -> Dict[str, 'SoquetT']:
+ ) -> dict[str, 'SoquetT']:
xx = bb.add(TestAtom(), q=xx)
for i in range(2):
for j in range(2):
@@ -106,7 +105,7 @@ def signature(self) -> Signature:
def build_composite_bloq(
self, bb: 'BloqBuilder', a: 'SoquetT', b: 'SoquetT', c: 'SoquetT', d: 'Soquet'
- ) -> Dict[str, 'Soquet']:
+ ) -> dict[str, 'Soquet']:
a, b = bb.add(TestBoundedQUInt(), xx=a, yy=d)
b, c = bb.add(TestQFxp(), xx=b, yy=c)
return {'a': a, 'b': b, 'c': c, 'd': d}
diff --git a/qualtran/bloqs/for_testing/matrix_gate.py b/qualtran/bloqs/for_testing/matrix_gate.py
index 7665416abd..7415508877 100644
--- a/qualtran/bloqs/for_testing/matrix_gate.py
+++ b/qualtran/bloqs/for_testing/matrix_gate.py
@@ -11,7 +11,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.
-from typing import Dict, List, Tuple, TYPE_CHECKING
+from typing import TYPE_CHECKING
import numpy as np
from attrs import field, frozen
@@ -36,7 +36,7 @@ class MatrixGate(GateWithRegisters):
"""
bitsize: int
- matrix: Tuple[Tuple[complex, ...], ...] = field(
+ matrix: tuple[tuple[complex, ...], ...] = field(
converter=lambda mat: tuple(tuple(row) for row in mat)
)
atol: float = 1e-10
@@ -64,8 +64,8 @@ def random(cls, bitsize: int, *, random_state=None) -> 'MatrixGate':
return cls(bitsize, matrix)
def my_tensors(
- self, incoming: Dict[str, 'ConnectionT'], outgoing: Dict[str, 'ConnectionT']
- ) -> List['qtn.Tensor']:
+ self, incoming: dict[str, 'ConnectionT'], outgoing: dict[str, 'ConnectionT']
+ ) -> list['qtn.Tensor']:
import quimb.tensor as qtn
data = np.array(self.matrix).reshape((2,) * (self.bitsize * 2))
diff --git a/qualtran/bloqs/for_testing/qubitization_walk_test.py b/qualtran/bloqs/for_testing/qubitization_walk_test.py
index d1c0fdb5e6..66dbdb4d9e 100644
--- a/qualtran/bloqs/for_testing/qubitization_walk_test.py
+++ b/qualtran/bloqs/for_testing/qubitization_walk_test.py
@@ -11,8 +11,8 @@
# 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.
+from collections.abc import Iterator
from functools import cached_property
-from typing import Iterator, Tuple
import attrs
import cirq
@@ -31,17 +31,17 @@
@attrs.frozen
class PrepareUniformSuperpositionTest(PrepareOracle):
n: int
- cvs: Tuple[int, ...] = attrs.field(
+ cvs: tuple[int, ...] = attrs.field(
converter=lambda v: (v,) if isinstance(v, int) else tuple(v), default=()
)
qlambda: float = 0.0
@cached_property
- def selection_registers(self) -> Tuple[Register, ...]:
+ def selection_registers(self) -> tuple[Register, ...]:
return (Register('selection', BQUInt((self.n - 1).bit_length(), self.n)),)
@cached_property
- def junk_registers(self) -> Tuple[Register, ...]:
+ def junk_registers(self) -> tuple[Register, ...]:
return ()
@cached_property
diff --git a/qualtran/bloqs/for_testing/random_select_and_prepare.py b/qualtran/bloqs/for_testing/random_select_and_prepare.py
index 6e1a607f5a..81fdd20f86 100644
--- a/qualtran/bloqs/for_testing/random_select_and_prepare.py
+++ b/qualtran/bloqs/for_testing/random_select_and_prepare.py
@@ -11,8 +11,9 @@
# 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.
+from collections.abc import Iterator
from functools import cached_property
-from typing import Iterator, Optional, Tuple
+from typing import Optional
import attrs
import cirq
@@ -123,15 +124,15 @@ def random(
return cls(select_bitsize, target_bitsize, dps)
@property
- def control_registers(self) -> Tuple[Register, ...]:
+ def control_registers(self) -> tuple[Register, ...]:
return () if self.control_val is None else (Register('control', QBit()),)
@property
- def selection_registers(self) -> Tuple[Register, ...]:
+ def selection_registers(self) -> tuple[Register, ...]:
return (Register('selection', BQUInt(bitsize=self.select_bitsize)),)
@property
- def target_registers(self) -> Tuple[Register, ...]:
+ def target_registers(self) -> tuple[Register, ...]:
return (Register('target', BQUInt(bitsize=self.target_bitsize)),)
def decompose_from_registers(
@@ -149,7 +150,7 @@ def decompose_from_registers(
op = op.controlled_by(*quregs['control'], control_values=[self.control_val])
yield op
- def get_ctrl_system(self, ctrl_spec: 'CtrlSpec') -> Tuple['Bloq', 'AddControlledT']:
+ def get_ctrl_system(self, ctrl_spec: 'CtrlSpec') -> tuple['Bloq', 'AddControlledT']:
from qualtran.bloqs.mcmt.specialized_ctrl import get_ctrl_system_1bit_cv
return get_ctrl_system_1bit_cv(
diff --git a/qualtran/bloqs/for_testing/with_decomposition.py b/qualtran/bloqs/for_testing/with_decomposition.py
index 9a790ef29c..d581e44017 100644
--- a/qualtran/bloqs/for_testing/with_decomposition.py
+++ b/qualtran/bloqs/for_testing/with_decomposition.py
@@ -13,7 +13,7 @@
# limitations under the License.
from functools import cached_property
-from typing import Dict, TYPE_CHECKING
+from typing import TYPE_CHECKING
from attrs import frozen
@@ -32,7 +32,7 @@ class TestSerialCombo(Bloq):
def signature(self) -> Signature:
return Signature.build(reg=1)
- def build_composite_bloq(self, bb: 'BloqBuilder', reg: 'SoquetT') -> Dict[str, 'SoquetT']:
+ def build_composite_bloq(self, bb: 'BloqBuilder', reg: 'SoquetT') -> dict[str, 'SoquetT']:
for i in range(3):
reg = bb.add(TestAtom(tag=f'atom{i}'), q=reg)
return {'reg': reg}
@@ -46,7 +46,7 @@ class TestParallelCombo(Bloq):
def signature(self) -> Signature:
return Signature.build(reg=3)
- def build_composite_bloq(self, bb: 'BloqBuilder', reg: 'SoquetT') -> Dict[str, 'SoquetT']:
+ def build_composite_bloq(self, bb: 'BloqBuilder', reg: 'SoquetT') -> dict[str, 'SoquetT']:
assert isinstance(reg, Soquet)
reg = bb.split(reg)
for i in range(len(reg)):
@@ -63,7 +63,7 @@ class TestIndependentParallelCombo(Bloq):
def signature(self) -> Signature:
return Signature.build()
- def build_composite_bloq(self, bb: 'BloqBuilder', **soqs: 'SoquetT') -> Dict[str, 'SoquetT']:
+ def build_composite_bloq(self, bb: 'BloqBuilder', **soqs: 'SoquetT') -> dict[str, 'SoquetT']:
for _ in range(3):
reg = bb.allocate(1)
reg = bb.add(TestAtom(), q=reg)
diff --git a/qualtran/bloqs/gf_arithmetic/gf2_add_k.py b/qualtran/bloqs/gf_arithmetic/gf2_add_k.py
index 41e380ea8b..b2c90b515e 100644
--- a/qualtran/bloqs/gf_arithmetic/gf2_add_k.py
+++ b/qualtran/bloqs/gf_arithmetic/gf2_add_k.py
@@ -11,8 +11,9 @@
# 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.
+from collections.abc import Sequence
from functools import cached_property
-from typing import Dict, Sequence, TYPE_CHECKING
+from typing import TYPE_CHECKING
import attrs
@@ -66,7 +67,7 @@ def _bits_k(self) -> Sequence[int]:
def is_symbolic(self):
return is_symbolic(self.k, self.bitsize)
- def build_composite_bloq(self, bb: 'BloqBuilder', *, x: 'Soquet') -> Dict[str, 'Soquet']:
+ def build_composite_bloq(self, bb: 'BloqBuilder', *, x: 'Soquet') -> dict[str, 'Soquet']:
if self.is_symbolic():
raise DecomposeTypeError(f"Cannot decompose symbolic {self}")
xs = bb.split(x)
@@ -83,7 +84,7 @@ def build_call_graph(self, ssa: 'SympySymbolAllocator') -> 'BloqCountDictT':
num_flips = self.bitsize if self.is_symbolic() else sum(self._bits_k)
return {XGate(): num_flips}
- def on_classical_vals(self, *, x) -> Dict[str, 'ClassicalValT']:
+ def on_classical_vals(self, *, x) -> dict[str, 'ClassicalValT']:
assert isinstance(x, self.qgf.gf_type)
return {'x': x + self.qgf.gf_type(self.k)}
diff --git a/qualtran/bloqs/gf_arithmetic/gf2_addition.py b/qualtran/bloqs/gf_arithmetic/gf2_addition.py
index e316e0c582..b42785359b 100644
--- a/qualtran/bloqs/gf_arithmetic/gf2_addition.py
+++ b/qualtran/bloqs/gf_arithmetic/gf2_addition.py
@@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from functools import cached_property
-from typing import Dict, Set, TYPE_CHECKING, Union
+from typing import TYPE_CHECKING, Union
import attrs
@@ -59,7 +59,7 @@ def qgf(self) -> QGF:
def build_composite_bloq(
self, bb: 'BloqBuilder', *, x: 'Soquet', y: 'Soquet'
- ) -> Dict[str, 'Soquet']:
+ ) -> dict[str, 'Soquet']:
if is_symbolic(self.bitsize):
raise DecomposeTypeError(f"Cannot decompose symbolic {self}")
x, y = bb.split(x), bb.split(y)
@@ -71,10 +71,10 @@ def build_composite_bloq(
def build_call_graph(
self, ssa: 'SympySymbolAllocator'
- ) -> Union['BloqCountDictT', Set['BloqCountT']]:
+ ) -> Union['BloqCountDictT', set['BloqCountT']]:
return {CNOT(): self.bitsize}
- def on_classical_vals(self, *, x, y) -> Dict[str, 'ClassicalValT']:
+ def on_classical_vals(self, *, x, y) -> dict[str, 'ClassicalValT']:
assert isinstance(x, self.qgf.gf_type) and isinstance(y, self.qgf.gf_type)
return {'x': x, 'y': x + y}
diff --git a/qualtran/bloqs/gf_arithmetic/gf2_inverse.py b/qualtran/bloqs/gf_arithmetic/gf2_inverse.py
index e792dacbe8..27eaade3f5 100644
--- a/qualtran/bloqs/gf_arithmetic/gf2_inverse.py
+++ b/qualtran/bloqs/gf_arithmetic/gf2_inverse.py
@@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from functools import cached_property
-from typing import Dict, Set, TYPE_CHECKING, Union
+from typing import TYPE_CHECKING, Union
import attrs
import numpy as np
@@ -129,7 +129,7 @@ def my_static_costs(self, cost_key: 'CostKey'):
return NotImplemented
- def build_composite_bloq(self, bb: 'BloqBuilder', *, x: 'Soquet') -> Dict[str, 'SoquetT']:
+ def build_composite_bloq(self, bb: 'BloqBuilder', *, x: 'Soquet') -> dict[str, 'SoquetT']:
if is_symbolic(self.bitsize):
raise DecomposeTypeError(f"Cannot decompose symbolic {self}")
@@ -172,7 +172,7 @@ def build_composite_bloq(self, bb: 'BloqBuilder', *, x: 'Soquet') -> Dict[str, '
def build_call_graph(
self, ssa: 'SympySymbolAllocator'
- ) -> Union['BloqCountDictT', Set['BloqCountT']]:
+ ) -> Union['BloqCountDictT', set['BloqCountT']]:
if not is_symbolic(self.bitsize) and self.bitsize == 1:
return {GF2Addition(self.bitsize): 1}
square_count = self.bitsize + 2 ** ceil(log2(self.bitsize)) - 1
@@ -187,7 +187,7 @@ def build_call_graph(
- 1,
}
- def on_classical_vals(self, *, x) -> Dict[str, 'ClassicalValT']:
+ def on_classical_vals(self, *, x) -> dict[str, 'ClassicalValT']:
assert isinstance(x, self.qgf.gf_type)
junk = []
bitsize_minus_one = int(self.bitsize - 1)
diff --git a/qualtran/bloqs/gf_arithmetic/gf2_multiplication.py b/qualtran/bloqs/gf_arithmetic/gf2_multiplication.py
index 80c2f87450..8d32b68b16 100644
--- a/qualtran/bloqs/gf_arithmetic/gf2_multiplication.py
+++ b/qualtran/bloqs/gf_arithmetic/gf2_multiplication.py
@@ -11,8 +11,9 @@
# 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.
+from collections.abc import Sequence
from functools import cached_property
-from typing import Dict, Optional, Sequence, Set, TYPE_CHECKING, Union
+from typing import Optional, TYPE_CHECKING, Union
import attrs
import galois
@@ -72,7 +73,7 @@ def signature(self) -> 'Signature':
n, _ = self.matrix.shape
return Signature([Register('q', QBit(), shape=(n,))])
- def on_classical_vals(self, *, q: 'ClassicalValT') -> Dict[str, 'ClassicalValT']:
+ def on_classical_vals(self, *, q: 'ClassicalValT') -> dict[str, 'ClassicalValT']:
if is_symbolic(self.matrix):
raise ValueError(f"Cannot do classical simulation on symbolic {self}")
matrix = GF(2)(self.matrix.astype(int))
@@ -87,7 +88,7 @@ def on_classical_vals(self, *, q: 'ClassicalValT') -> Dict[str, 'ClassicalValT']
def build_call_graph(
self, ssa: 'SympySymbolAllocator'
- ) -> Union['BloqCountDictT', Set['BloqCountT']]:
+ ) -> Union['BloqCountDictT', set['BloqCountT']]:
n = self.matrix.shape[0]
return {CNOT(): ceil(n**2 / log2(n))}
@@ -180,7 +181,7 @@ def synthesize_reduction_matrix_q(self) -> SynthesizeLRCircuit:
else SynthesizeLRCircuit(self.reduction_matrix_q)
)
- def build_composite_bloq(self, bb: 'BloqBuilder', **soqs: 'Soquet') -> Dict[str, 'Soquet']:
+ def build_composite_bloq(self, bb: 'BloqBuilder', **soqs: 'Soquet') -> dict[str, 'Soquet']:
if is_symbolic(self.bitsize):
raise DecomposeTypeError(f"Cannot decompose symbolic {self}")
x, y = soqs['x'], soqs['y']
@@ -219,14 +220,14 @@ def build_composite_bloq(self, bb: 'BloqBuilder', **soqs: 'Soquet') -> Dict[str,
def build_call_graph(
self, ssa: 'SympySymbolAllocator'
- ) -> Union['BloqCountDictT', Set['BloqCountT']]:
+ ) -> Union['BloqCountDictT', set['BloqCountT']]:
m = self.bitsize
plus_equal_prod = (
{self.synthesize_reduction_matrix_q.adjoint(): 1} if self.plus_equal_prod else {}
)
return {Toffoli(): m**2, self.synthesize_reduction_matrix_q: 1} | plus_equal_prod
- def on_classical_vals(self, **vals) -> Dict[str, 'ClassicalValT']:
+ def on_classical_vals(self, **vals) -> dict[str, 'ClassicalValT']:
assert all(isinstance(val, self.qgf.gf_type) for val in vals.values())
x, y = vals['x'], vals['y']
result = vals['result'] if self.plus_equal_prod else self.qgf.gf_type(0)
@@ -327,10 +328,10 @@ def signature(self) -> 'Signature':
def _const(self) -> galois.FieldArray:
return self.galois_field(self.const)
- def on_classical_vals(self, g) -> Dict[str, 'ClassicalValT']:
+ def on_classical_vals(self, g) -> dict[str, 'ClassicalValT']:
return {'g': g * self._const}
- def build_composite_bloq(self, bb: 'BloqBuilder', g: 'Soquet') -> Dict[str, 'SoquetT']:
+ def build_composite_bloq(self, bb: 'BloqBuilder', g: 'Soquet') -> dict[str, 'SoquetT']:
L, U, P = self.lup
if is_symbolic(self.n):
raise DecomposeTypeError(f"Symbolic decomposition isn't supported for {self}")
@@ -359,7 +360,7 @@ def build_composite_bloq(self, bb: 'BloqBuilder', g: 'Soquet') -> Dict[str, 'Soq
def build_call_graph(
self, ssa: 'SympySymbolAllocator'
- ) -> Union['BloqCountDictT', Set['BloqCountT']]:
+ ) -> Union['BloqCountDictT', set['BloqCountT']]:
L, U, _ = self.lup
# The number of cnots is the number of non zero off-diagnoal entries in L and U.
cnots = np.sum(L) + np.sum(U) - 2 * self.n
@@ -446,7 +447,7 @@ def signature(self) -> 'Signature':
def on_classical_vals(
self, f: 'ClassicalValT', g: 'ClassicalValT', h: 'ClassicalValT'
- ) -> Dict[str, 'ClassicalValT']:
+ ) -> dict[str, 'ClassicalValT']:
if is_symbolic(self.k):
raise TypeError(f'classical action is not supported for {self=}')
assert isinstance(f, np.ndarray)
@@ -464,7 +465,7 @@ def on_classical_vals(
def build_composite_bloq(
self, bb: 'BloqBuilder', f: 'SoquetT', g: 'SoquetT', h: 'SoquetT'
- ) -> Dict[str, 'SoquetT']:
+ ) -> dict[str, 'SoquetT']:
n = self.n
k = self.k
l = self.l
@@ -499,7 +500,7 @@ def build_composite_bloq(
def build_call_graph(
self, ssa: 'SympySymbolAllocator'
- ) -> Union['BloqCountDictT', Set['BloqCountT']]:
+ ) -> Union['BloqCountDictT', set['BloqCountT']]:
if not is_symbolic(self.n) and self.n == 1:
return {CNOT(): 2, Toffoli(): 1}
return {CNOT(): 2 * (self.l + self.k), BinaryPolynomialMultiplication(self.n): 1}
@@ -557,7 +558,7 @@ def signature(self) -> 'Signature':
def on_classical_vals(
self, f: 'ClassicalValT', g: 'ClassicalValT', h: 'ClassicalValT'
- ) -> Dict[str, 'ClassicalValT']:
+ ) -> dict[str, 'ClassicalValT']:
assert isinstance(f, np.ndarray)
assert isinstance(g, np.ndarray)
assert isinstance(h, np.ndarray)
@@ -578,7 +579,7 @@ def k(self) -> 'SymbolicInt':
def build_composite_bloq(
self, bb: 'BloqBuilder', f: 'SoquetT', g: 'SoquetT', h: 'SoquetT'
- ) -> Dict[str, 'SoquetT']:
+ ) -> dict[str, 'SoquetT']:
k, n = self.k, self.n
if is_symbolic(n) or is_symbolic(k):
raise DecomposeTypeError(f"symbolic decomposition is not supported for {self}")
@@ -628,7 +629,7 @@ def build_composite_bloq(
def build_call_graph(
self, ssa: 'SympySymbolAllocator'
- ) -> Union['BloqCountDictT', Set['BloqCountT']]:
+ ) -> Union['BloqCountDictT', set['BloqCountT']]:
if not is_symbolic(self.n) and self.n == 1:
return {Toffoli(): 1}
if not is_symbolic(self.n) and 2 * self.k == self.n:
@@ -712,7 +713,7 @@ def gf(self):
def _power_2(self):
return self.gf(2) ** self.k
- def on_classical_vals(self, f: 'ClassicalValT') -> Dict[str, 'ClassicalValT']:
+ def on_classical_vals(self, f: 'ClassicalValT') -> dict[str, 'ClassicalValT']:
k = self.k
if is_symbolic(k):
raise TypeError(f'classical action is not supported for {self}')
@@ -721,7 +722,7 @@ def on_classical_vals(self, f: 'ClassicalValT') -> Dict[str, 'ClassicalValT']:
return {'f': f}
return {'f': f * self._power_2}
- def build_composite_bloq(self, bb: 'BloqBuilder', f: 'Soquet') -> Dict[str, 'SoquetT']:
+ def build_composite_bloq(self, bb: 'BloqBuilder', f: 'Soquet') -> dict[str, 'SoquetT']:
if is_symbolic(self.k):
raise DecomposeTypeError(f'symbolic decomposition is not supported for {self}')
f_arr = bb.split(f)[::-1]
@@ -736,7 +737,7 @@ def build_composite_bloq(self, bb: 'BloqBuilder', f: 'Soquet') -> Dict[str, 'Soq
def build_call_graph(
self, ssa: 'SympySymbolAllocator'
- ) -> Union['BloqCountDictT', Set['BloqCountT']]:
+ ) -> Union['BloqCountDictT', set['BloqCountT']]:
if self.k == 0 or self.n == 1:
return {}
return {CNOT(): max(len(self.degrees) - 2, 0) * self.k}
@@ -785,7 +786,7 @@ def m_x(self):
def build_composite_bloq(
self, bb: 'BloqBuilder', f: 'Soquet', g: 'Soquet', h: 'Soquet'
- ) -> Dict[str, 'Soquet']:
+ ) -> dict[str, 'Soquet']:
if is_symbolic(self.k, self.n):
raise DecomposeTypeError(f"Symbolic Decomposition is not supported for {self}")
@@ -925,7 +926,7 @@ def _GF2MulViaKaratsubamod_impl(self) -> Bloq:
def build_composite_bloq(
self, bb: 'BloqBuilder', x: 'Soquet', y: 'Soquet', **soqs: 'SoquetT'
- ) -> Dict[str, 'SoquetT']:
+ ) -> dict[str, 'SoquetT']:
if is_symbolic(self.k, self.n):
raise DecomposeTypeError(f"Symbolic Decomposition is not supported for {self}")
@@ -944,7 +945,7 @@ def build_composite_bloq(
def build_call_graph(
self, ssa: 'SympySymbolAllocator'
- ) -> Union['BloqCountDictT', Set['BloqCountT']]:
+ ) -> Union['BloqCountDictT', set['BloqCountT']]:
if self.n == 1:
return {Toffoli(): 1}
if not is_symbolic(self.n) and 2 * self.k == self.n:
@@ -966,7 +967,7 @@ def build_call_graph(
def on_classical_vals(
self, x: 'SymbolicInt', y: 'SymbolicInt', result: Optional['SymbolicInt'] = None
- ) -> Dict[str, 'ClassicalValT']:
+ ) -> dict[str, 'ClassicalValT']:
assert isinstance(x, self.gf)
assert isinstance(y, self.gf)
if self.uncompute:
diff --git a/qualtran/bloqs/gf_arithmetic/gf2_square.py b/qualtran/bloqs/gf_arithmetic/gf2_square.py
index 140895e923..fb778d9c8c 100644
--- a/qualtran/bloqs/gf_arithmetic/gf2_square.py
+++ b/qualtran/bloqs/gf_arithmetic/gf2_square.py
@@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from functools import cached_property
-from typing import Dict, Set, TYPE_CHECKING, Union
+from typing import TYPE_CHECKING, Union
import attrs
import numpy as np
@@ -89,7 +89,7 @@ def synthesize_squaring_matrix(self) -> SynthesizeLRCircuit:
else SynthesizeLRCircuit(self.squaring_matrix)
)
- def build_composite_bloq(self, bb: 'BloqBuilder', *, x: 'Soquet') -> Dict[str, 'Soquet']:
+ def build_composite_bloq(self, bb: 'BloqBuilder', *, x: 'Soquet') -> dict[str, 'Soquet']:
if is_symbolic(self.bitsize):
raise DecomposeTypeError(f"Cannot decompose symbolic {self}")
x = bb.split(x)[::-1]
@@ -99,10 +99,10 @@ def build_composite_bloq(self, bb: 'BloqBuilder', *, x: 'Soquet') -> Dict[str, '
def build_call_graph(
self, ssa: 'SympySymbolAllocator'
- ) -> Union['BloqCountDictT', Set['BloqCountT']]:
+ ) -> Union['BloqCountDictT', set['BloqCountT']]:
return {self.synthesize_squaring_matrix: 1}
- def on_classical_vals(self, *, x) -> Dict[str, 'ClassicalValT']:
+ def on_classical_vals(self, *, x) -> dict[str, 'ClassicalValT']:
assert isinstance(x, self.qgf.gf_type)
return {'x': x**2}
diff --git a/qualtran/bloqs/gf_poly_arithmetic/gf2_poly_add.py b/qualtran/bloqs/gf_poly_arithmetic/gf2_poly_add.py
index 7f8d8a351a..c8c83395eb 100644
--- a/qualtran/bloqs/gf_poly_arithmetic/gf2_poly_add.py
+++ b/qualtran/bloqs/gf_poly_arithmetic/gf2_poly_add.py
@@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from functools import cached_property
-from typing import Dict, Set, TYPE_CHECKING, Union
+from typing import TYPE_CHECKING, Union
import attrs
@@ -71,7 +71,7 @@ def is_symbolic(self):
def build_composite_bloq(
self, bb: 'BloqBuilder', *, f_x: 'Soquet', g_x: 'Soquet'
- ) -> Dict[str, 'Soquet']:
+ ) -> dict[str, 'Soquet']:
if self.is_symbolic():
raise DecomposeTypeError(f"Cannot decompose symbolic {self}")
f_x = bb.add(GFPolySplit(self.qgf_poly), reg=f_x)
@@ -85,10 +85,10 @@ def build_composite_bloq(
def build_call_graph(
self, ssa: 'SympySymbolAllocator'
- ) -> Union['BloqCountDictT', Set['BloqCountT']]:
+ ) -> Union['BloqCountDictT', set['BloqCountT']]:
return {GF2Addition(self.qgf_poly.qgf.bitsize): self.qgf_poly.degree + 1}
- def on_classical_vals(self, *, f_x, g_x) -> Dict[str, 'ClassicalValT']:
+ def on_classical_vals(self, *, f_x, g_x) -> dict[str, 'ClassicalValT']:
return {'f_x': f_x, 'g_x': f_x + g_x}
diff --git a/qualtran/bloqs/gf_poly_arithmetic/gf2_poly_add_k.py b/qualtran/bloqs/gf_poly_arithmetic/gf2_poly_add_k.py
index b8d6f8c52c..4e239db8ec 100644
--- a/qualtran/bloqs/gf_poly_arithmetic/gf2_poly_add_k.py
+++ b/qualtran/bloqs/gf_poly_arithmetic/gf2_poly_add_k.py
@@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from functools import cached_property
-from typing import Dict, Set, TYPE_CHECKING, Union
+from typing import TYPE_CHECKING, Union
import attrs
import galois
@@ -81,7 +81,7 @@ def _validate_g_x(self, attribute, value):
def is_symbolic(self):
return is_symbolic(self.qgf_poly.degree)
- def build_composite_bloq(self, bb: 'BloqBuilder', *, f_x: 'Soquet') -> Dict[str, 'Soquet']:
+ def build_composite_bloq(self, bb: 'BloqBuilder', *, f_x: 'Soquet') -> dict[str, 'Soquet']:
if self.is_symbolic():
raise DecomposeTypeError(f"Cannot decompose symbolic {self}")
f_x = bb.add(GFPolySplit(self.qgf_poly), reg=f_x)
@@ -94,13 +94,13 @@ def build_composite_bloq(self, bb: 'BloqBuilder', *, f_x: 'Soquet') -> Dict[str,
def build_call_graph(
self, ssa: 'SympySymbolAllocator'
- ) -> Union['BloqCountDictT', Set['BloqCountT']]:
+ ) -> Union['BloqCountDictT', set['BloqCountT']]:
if self.is_symbolic():
k = ssa.new_symbol('g_x')
return {GF2AddK(self.qgf_poly.qgf.bitsize, k): self.qgf_poly.degree + 1}
return super().build_call_graph(ssa)
- def on_classical_vals(self, *, f_x) -> Dict[str, 'ClassicalValT']:
+ def on_classical_vals(self, *, f_x) -> dict[str, 'ClassicalValT']:
return {'f_x': f_x + self.g_x}
diff --git a/qualtran/bloqs/gf_poly_arithmetic/gf_poly_split_and_join.py b/qualtran/bloqs/gf_poly_arithmetic/gf_poly_split_and_join.py
index 966e38d607..08f4bd2dc6 100644
--- a/qualtran/bloqs/gf_poly_arithmetic/gf_poly_split_and_join.py
+++ b/qualtran/bloqs/gf_poly_arithmetic/gf_poly_split_and_join.py
@@ -13,7 +13,7 @@
# limitations under the License.
from functools import cached_property
-from typing import cast, Dict, List, Optional, Tuple, TYPE_CHECKING
+from typing import cast, Optional, TYPE_CHECKING
import galois
import numpy as np
@@ -96,7 +96,7 @@ def decompose_bloq(self) -> 'CompositeBloq':
def adjoint(self) -> 'Bloq':
return GFPolyJoin(dtype=self.dtype)
- def as_cirq_op(self, qubit_manager, reg: 'CirqQuregT') -> Tuple[None, Dict[str, 'CirqQuregT']]:
+ def as_cirq_op(self, qubit_manager, reg: 'CirqQuregT') -> tuple[None, dict[str, 'CirqQuregT']]:
return None, {
'reg': reg.reshape((int(self.dtype.degree) + 1, int(self.dtype.qgf.num_qubits)))
}
@@ -104,12 +104,12 @@ def as_cirq_op(self, qubit_manager, reg: 'CirqQuregT') -> Tuple[None, Dict[str,
def as_pl_op(self, wires: 'Wires') -> 'Operation':
return None
- def on_classical_vals(self, reg: galois.Poly) -> Dict[str, 'ClassicalValT']:
+ def on_classical_vals(self, reg: galois.Poly) -> dict[str, 'ClassicalValT']:
return {'reg': self.dtype.to_gf_coefficients(reg)}
def my_tensors(
- self, incoming: Dict[str, 'ConnectionT'], outgoing: Dict[str, 'ConnectionT']
- ) -> List['qtn.Tensor']:
+ self, incoming: dict[str, 'ConnectionT'], outgoing: dict[str, 'ConnectionT']
+ ) -> list['qtn.Tensor']:
import quimb.tensor as qtn
incoming = incoming['reg']
@@ -127,7 +127,7 @@ def my_tensors(
for i in range(int(self.dtype.num_qubits))
]
- def wire_symbol(self, reg: Optional[Register], idx: Tuple[int, ...] = tuple()) -> 'WireSymbol':
+ def wire_symbol(self, reg: Optional[Register], idx: tuple[int, ...] = tuple()) -> 'WireSymbol':
if reg is None:
return Text('')
if reg.shape:
@@ -203,15 +203,15 @@ def decompose_bloq(self) -> 'CompositeBloq':
def adjoint(self) -> 'Bloq':
return GFPolySplit(dtype=self.dtype)
- def as_cirq_op(self, qubit_manager, reg: 'CirqQuregT') -> Tuple[None, Dict[str, 'CirqQuregT']]:
+ def as_cirq_op(self, qubit_manager, reg: 'CirqQuregT') -> tuple[None, dict[str, 'CirqQuregT']]:
return None, {'reg': reg.reshape(int(self.dtype.num_qubits))}
def as_pl_op(self, wires: 'Wires') -> 'Operation':
return None
def my_tensors(
- self, incoming: Dict[str, 'ConnectionT'], outgoing: Dict[str, 'ConnectionT']
- ) -> List['qtn.Tensor']:
+ self, incoming: dict[str, 'ConnectionT'], outgoing: dict[str, 'ConnectionT']
+ ) -> list['qtn.Tensor']:
import quimb.tensor as qtn
incoming = cast(NDArray, incoming['reg'])
@@ -230,10 +230,10 @@ def my_tensors(
for i in range(int(self.dtype.num_qubits))
]
- def on_classical_vals(self, reg: 'galois.Array') -> Dict[str, galois.Poly]:
+ def on_classical_vals(self, reg: 'galois.Array') -> dict[str, galois.Poly]:
return {'reg': self.dtype.from_gf_coefficients(reg)}
- def wire_symbol(self, reg: Optional[Register], idx: Tuple[int, ...] = tuple()) -> 'WireSymbol':
+ def wire_symbol(self, reg: Optional[Register], idx: tuple[int, ...] = tuple()) -> 'WireSymbol':
if reg is None:
return Text('')
if reg.shape:
diff --git a/qualtran/bloqs/hamiltonian_simulation/hamiltonian_simulation_by_gqsp.py b/qualtran/bloqs/hamiltonian_simulation/hamiltonian_simulation_by_gqsp.py
index 21c3ee41f1..84821414d8 100644
--- a/qualtran/bloqs/hamiltonian_simulation/hamiltonian_simulation_by_gqsp.py
+++ b/qualtran/bloqs/hamiltonian_simulation/hamiltonian_simulation_by_gqsp.py
@@ -13,7 +13,7 @@
# limitations under the License.
from collections import Counter
from functools import cached_property
-from typing import cast, Dict, Tuple, TYPE_CHECKING, Union
+from typing import cast, TYPE_CHECKING, Union
import numpy as np
from attrs import field, frozen
@@ -145,11 +145,11 @@ def signature(self) -> 'Signature':
def __add_prepare(
self,
bb: 'BloqBuilder',
- gqsp_soqs: Dict[str, 'SoquetT'],
- state_prep_ancilla_soqs: Dict[str, 'SoquetT'],
+ gqsp_soqs: dict[str, 'SoquetT'],
+ state_prep_ancilla_soqs: dict[str, 'SoquetT'],
*,
adjoint: bool = False,
- ) -> Tuple[Dict[str, 'SoquetT'], Dict[str, 'SoquetT']]:
+ ) -> tuple[dict[str, 'SoquetT'], dict[str, 'SoquetT']]:
prepare = self.walk_operator.prepare
selection_registers = {reg.name: gqsp_soqs[reg.name] for reg in prepare.selection_registers}
@@ -163,8 +163,8 @@ def __add_prepare(
}
return gqsp_soqs, prepare_out_soqs
- def build_composite_bloq(self, bb: 'BloqBuilder', **soqs: 'SoquetT') -> Dict[str, 'SoquetT']:
- state_prep_ancilla: Dict[str, 'SoquetT'] = {
+ def build_composite_bloq(self, bb: 'BloqBuilder', **soqs: 'SoquetT') -> dict[str, 'SoquetT']:
+ state_prep_ancilla: dict[str, 'SoquetT'] = {
reg.name: bb.allocate(reg.total_bits())
for reg in self.walk_operator.prepare.junk_registers
}
diff --git a/qualtran/bloqs/mcmt/and_bloq.py b/qualtran/bloqs/mcmt/and_bloq.py
index 486bb3e49b..0d1fdba2bf 100644
--- a/qualtran/bloqs/mcmt/and_bloq.py
+++ b/qualtran/bloqs/mcmt/and_bloq.py
@@ -22,8 +22,9 @@
to the and of its control registers. `And` will output the result into a fresh register.
"""
import itertools
+from collections.abc import Iterable, Iterator
from functools import cached_property
-from typing import cast, Dict, Iterable, Iterator, List, Optional, Tuple, TYPE_CHECKING, Union
+from typing import cast, Optional, TYPE_CHECKING, Union
import attrs
import cirq
@@ -97,7 +98,7 @@ def decompose_bloq(self) -> 'CompositeBloq':
def on_classical_vals(
self, *, ctrl: NDArray[np.uint8], target: Optional[int] = None
- ) -> Dict[str, ClassicalValT]:
+ ) -> dict[str, ClassicalValT]:
out = 1 if tuple(ctrl) == (self.cv1, self.cv2) else 0
if not self.uncompute:
return {'ctrl': ctrl, 'target': out}
@@ -107,8 +108,8 @@ def on_classical_vals(
return {'ctrl': ctrl}
def my_tensors(
- self, incoming: Dict[str, 'ConnectionT'], outgoing: Dict[str, 'ConnectionT']
- ) -> List['qtn.Tensor']:
+ self, incoming: dict[str, 'ConnectionT'], outgoing: dict[str, 'ConnectionT']
+ ) -> list['qtn.Tensor']:
import quimb.tensor as qtn
# Fill in our tensor using "and" logic.
@@ -138,7 +139,7 @@ def my_tensors(
)
]
- def wire_symbol(self, reg: Optional[Register], idx: Tuple[int, ...] = tuple()) -> 'WireSymbol':
+ def wire_symbol(self, reg: Optional[Register], idx: tuple[int, ...] = tuple()) -> 'WireSymbol':
if reg is None:
return Text('')
if reg.name == 'target':
@@ -237,7 +238,7 @@ def _and_bloq() -> And:
def _to_tuple_or_has_length(
x: Union[HasLength, Iterable[SymbolicInt]]
-) -> Union[HasLength, Tuple[SymbolicInt, ...]]:
+) -> Union[HasLength, tuple[SymbolicInt, ...]]:
if isinstance(x, HasLength):
if is_symbolic(x.n):
return x
@@ -262,7 +263,7 @@ class MultiAnd(Bloq):
target [right]: The output bit.
"""
- cvs: Union[HasLength, Tuple[SymbolicInt, ...]] = field(converter=_to_tuple_or_has_length)
+ cvs: Union[HasLength, tuple[SymbolicInt, ...]] = field(converter=_to_tuple_or_has_length)
@cvs.validator
def _validate_cvs(self, field, val):
@@ -274,7 +275,7 @@ def n_ctrls(self) -> SymbolicInt:
return self.cvs.n if isinstance(self.cvs, HasLength) else len(self.cvs)
@property
- def concrete_cvs(self) -> Tuple[SymbolicInt, ...]:
+ def concrete_cvs(self) -> tuple[SymbolicInt, ...]:
if isinstance(self.cvs, HasLength):
raise ValueError(f"{self.cvs} is symbolic")
return self.cvs
@@ -289,7 +290,7 @@ def signature(self) -> Signature:
]
)
- def on_classical_vals(self, ctrl: NDArray[np.uint8]) -> Dict[str, NDArray[np.uint8]]:
+ def on_classical_vals(self, ctrl: NDArray[np.uint8]) -> dict[str, NDArray[np.uint8]]:
accumulate_and = np.bitwise_and.accumulate(
np.equal(ctrl, np.asarray(self.cvs)).astype(np.uint8)
)
@@ -306,7 +307,7 @@ def __pow__(self, power: int) -> "Bloq":
def _decompose_via_tree(
self,
controls: NDArray[cirq.Qid],
- control_values: Tuple[SymbolicInt, ...],
+ control_values: tuple[SymbolicInt, ...],
ancillas: NDArray[cirq.Qid],
target: cirq.Qid,
) -> cirq.ops.op_tree.OpTree:
@@ -335,7 +336,7 @@ def decompose_from_registers(
def decompose_bloq(self) -> 'CompositeBloq':
return decompose_from_cirq_style_method(self)
- def wire_symbol(self, reg: Optional[Register], idx: Tuple[int, ...] = tuple()) -> 'WireSymbol':
+ def wire_symbol(self, reg: Optional[Register], idx: tuple[int, ...] = tuple()) -> 'WireSymbol':
if reg is None:
return Text('')
if reg.name == 'ctrl':
diff --git a/qualtran/bloqs/mcmt/and_bloq_test.py b/qualtran/bloqs/mcmt/and_bloq_test.py
index 70d853579f..1d5e385abc 100644
--- a/qualtran/bloqs/mcmt/and_bloq_test.py
+++ b/qualtran/bloqs/mcmt/and_bloq_test.py
@@ -14,7 +14,6 @@
import itertools
from functools import cached_property
-from typing import Dict
import cirq
import numpy as np
@@ -196,7 +195,7 @@ def signature(self) -> 'Signature':
def build_composite_bloq(
self, bb: 'BloqBuilder', q0: 'SoquetT', q1: 'SoquetT'
- ) -> Dict[str, 'SoquetT']:
+ ) -> dict[str, 'SoquetT']:
assert isinstance(q0, Soquet)
assert isinstance(q1, Soquet)
qs, trg = bb.add(And(), ctrl=[q0, q1])
diff --git a/qualtran/bloqs/mcmt/controlled_via_and.py b/qualtran/bloqs/mcmt/controlled_via_and.py
index 3947ddf86b..00f0357d05 100644
--- a/qualtran/bloqs/mcmt/controlled_via_and.py
+++ b/qualtran/bloqs/mcmt/controlled_via_and.py
@@ -12,8 +12,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from collections import Counter
+from collections.abc import Iterable, Sequence
from functools import cached_property
-from typing import Iterable, Sequence, Tuple, TYPE_CHECKING
+from typing import TYPE_CHECKING
import numpy as np
from attrs import frozen
@@ -66,7 +67,7 @@ def __attrs_post_init__(self):
@classmethod
def make_ctrl_system(
cls, bloq: 'Bloq', ctrl_spec: 'CtrlSpec'
- ) -> Tuple['_ControlledBase', 'AddControlledT']:
+ ) -> tuple['_ControlledBase', 'AddControlledT']:
"""A factory method for creating both the Controlled and the adder function.
See `Bloq.get_ctrl_system`.
diff --git a/qualtran/bloqs/mcmt/multi_control_pauli.py b/qualtran/bloqs/mcmt/multi_control_pauli.py
index aceff0c99d..89a8865c28 100644
--- a/qualtran/bloqs/mcmt/multi_control_pauli.py
+++ b/qualtran/bloqs/mcmt/multi_control_pauli.py
@@ -13,7 +13,7 @@
# limitations under the License.
import warnings
from functools import cached_property
-from typing import Dict, Optional, Tuple, TYPE_CHECKING, Union
+from typing import Optional, TYPE_CHECKING, Union
import numpy as np
import sympy
@@ -61,7 +61,7 @@ class MultiControlPauli(GateWithRegisters):
[Constructing Large Controlled Nots](https://algassert.com/circuits/2015/06/05/Constructing-Large-Controlled-Nots.html)
"""
- cvs: Union[HasLength, Tuple[int, ...]] = field(converter=_to_tuple_or_has_length)
+ cvs: Union[HasLength, tuple[int, ...]] = field(converter=_to_tuple_or_has_length)
target_bloq: Bloq
def __attrs_post_init__(self):
@@ -86,7 +86,7 @@ def n_ctrls(self) -> SymbolicInt:
return slen(self.cvs)
@property
- def concrete_cvs(self) -> Tuple[int, ...]:
+ def concrete_cvs(self) -> tuple[int, ...]:
if isinstance(self.cvs, HasLength):
raise ValueError(f"{self.cvs} is symbolic")
return self.cvs
@@ -99,7 +99,7 @@ def _multi_ctrl_bloq(self) -> ControlledViaAnd:
ctrl_spec = CtrlSpec(cvs=(cvs,))
return ControlledViaAnd(self.target_bloq, ctrl_spec)
- def build_composite_bloq(self, bb: 'BloqBuilder', **soqs: 'SoquetT') -> Dict[str, 'SoquetT']:
+ def build_composite_bloq(self, bb: 'BloqBuilder', **soqs: 'SoquetT') -> dict[str, 'SoquetT']:
if is_symbolic(self.cvs):
raise DecomposeTypeError(f"cannot decompose {self} with symbolic {self.cvs=}")
@@ -127,7 +127,7 @@ def __str__(self) -> str:
ctrl = f'C^{n}' if is_symbolic(n) or n > 2 else ['', 'C', 'CC'][int(n)]
return f'{ctrl}{self.target_bloq!s}'
- def wire_symbol(self, reg: Optional[Register], idx: Tuple[int, ...] = tuple()) -> 'WireSymbol':
+ def wire_symbol(self, reg: Optional[Register], idx: tuple[int, ...] = tuple()) -> 'WireSymbol':
if reg is None:
return TextBox(str(self))
if reg.name == 'target':
diff --git a/qualtran/bloqs/mcmt/multi_target_cnot.py b/qualtran/bloqs/mcmt/multi_target_cnot.py
index c4df15202f..72e1a9d3a7 100644
--- a/qualtran/bloqs/mcmt/multi_target_cnot.py
+++ b/qualtran/bloqs/mcmt/multi_target_cnot.py
@@ -11,8 +11,8 @@
# 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.
+from collections.abc import Iterator
from functools import cached_property
-from typing import Dict, Iterator
import cirq
import sympy
@@ -67,7 +67,7 @@ def _circuit_diagram_info_(self, _) -> cirq.CircuitDiagramInfo:
def on_classical_vals(
self, control: 'ClassicalValT', targets: 'ClassicalValT'
- ) -> Dict[str, 'ClassicalValT']:
+ ) -> dict[str, 'ClassicalValT']:
if control:
targets = (2**self.bitsize - 1) ^ targets
return {'control': control, 'targets': targets}
diff --git a/qualtran/bloqs/mcmt/specialized_ctrl.py b/qualtran/bloqs/mcmt/specialized_ctrl.py
index 98b6499501..a8f25e3cc9 100644
--- a/qualtran/bloqs/mcmt/specialized_ctrl.py
+++ b/qualtran/bloqs/mcmt/specialized_ctrl.py
@@ -12,8 +12,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import enum
+from collections.abc import Callable, Iterable, Sequence
from functools import cached_property
-from typing import Callable, cast, Iterable, Optional, Sequence, TYPE_CHECKING
+from typing import cast, Optional, TYPE_CHECKING
import attrs
import numpy as np
diff --git a/qualtran/bloqs/mcmt/specialized_ctrl_test.py b/qualtran/bloqs/mcmt/specialized_ctrl_test.py
index 8ed8dd515d..86bfdf885e 100644
--- a/qualtran/bloqs/mcmt/specialized_ctrl_test.py
+++ b/qualtran/bloqs/mcmt/specialized_ctrl_test.py
@@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import itertools
-from typing import Optional, Sequence, Tuple
+from typing import Optional, Sequence
from unittest.mock import ANY
import attrs
@@ -52,7 +52,7 @@ def signature(self) -> 'Signature':
reg_name_map = {self.ctrl_reg_name: n_ctrl, self.target_reg_name: 2}
return Signature.build(**reg_name_map)
- def get_ctrl_system(self, ctrl_spec: 'CtrlSpec') -> Tuple['Bloq', 'AddControlledT']:
+ def get_ctrl_system(self, ctrl_spec: 'CtrlSpec') -> tuple['Bloq', 'AddControlledT']:
return get_ctrl_system_1bit_cv(
self,
ctrl_spec,
@@ -130,7 +130,7 @@ class TestAtom(Bloq):
def signature(self) -> 'Signature':
return Signature.build(q=2)
- def get_ctrl_system(self, ctrl_spec: 'CtrlSpec') -> Tuple['Bloq', 'AddControlledT']:
+ def get_ctrl_system(self, ctrl_spec: 'CtrlSpec') -> tuple['Bloq', 'AddControlledT']:
return get_ctrl_system_1bit_cv_from_bloqs(
self,
ctrl_spec,
@@ -151,7 +151,7 @@ class CTestAtom(Bloq):
def signature(self) -> 'Signature':
return Signature.build(ctrl=1, q=2)
- def get_ctrl_system(self, ctrl_spec: 'CtrlSpec') -> Tuple['Bloq', 'AddControlledT']:
+ def get_ctrl_system(self, ctrl_spec: 'CtrlSpec') -> tuple['Bloq', 'AddControlledT']:
return get_ctrl_system_1bit_cv_from_bloqs(
self, ctrl_spec, current_ctrl_bit=1, bloq_with_ctrl=self, ctrl_reg_name='ctrl'
)
diff --git a/qualtran/bloqs/mean_estimation/complex_phase_oracle.py b/qualtran/bloqs/mean_estimation/complex_phase_oracle.py
index 6abd4c2811..91a325d16d 100644
--- a/qualtran/bloqs/mean_estimation/complex_phase_oracle.py
+++ b/qualtran/bloqs/mean_estimation/complex_phase_oracle.py
@@ -12,8 +12,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+from collections.abc import Iterator
from functools import cached_property
-from typing import Iterator, Tuple
import attrs
import cirq
@@ -40,11 +40,11 @@ class ComplexPhaseOracle(GateWithRegisters):
arctan_bitsize: int = 32
@cached_property
- def control_registers(self) -> Tuple[Register, ...]:
+ def control_registers(self) -> tuple[Register, ...]:
return self.encoder.control_registers
@cached_property
- def selection_registers(self) -> Tuple[Register, ...]:
+ def selection_registers(self) -> tuple[Register, ...]:
return self.encoder.selection_registers
@cached_property
diff --git a/qualtran/bloqs/mean_estimation/complex_phase_oracle_test.py b/qualtran/bloqs/mean_estimation/complex_phase_oracle_test.py
index ab6dc2af63..00b48776e1 100644
--- a/qualtran/bloqs/mean_estimation/complex_phase_oracle_test.py
+++ b/qualtran/bloqs/mean_estimation/complex_phase_oracle_test.py
@@ -14,7 +14,7 @@
import math
from functools import cached_property
-from typing import Optional, Tuple
+from typing import Optional
import cirq
import numpy as np
@@ -34,15 +34,15 @@ class ExampleSelect(SelectOracle):
control_val: Optional[int] = None
@cached_property
- def control_registers(self) -> Tuple[Register, ...]:
+ def control_registers(self) -> tuple[Register, ...]:
return () if self.control_val is None else (Register('control', QBit()),)
@cached_property
- def selection_registers(self) -> Tuple[Register, ...]:
+ def selection_registers(self) -> tuple[Register, ...]:
return (Register('selection', QAny(self.bitsize)),)
@cached_property
- def target_registers(self) -> Tuple[Register, ...]:
+ def target_registers(self) -> tuple[Register, ...]:
return (Register('target', QAny(self.bitsize)),)
def decompose_from_registers(self, context, selection, target):
diff --git a/qualtran/bloqs/mean_estimation/mean_estimation_operator.py b/qualtran/bloqs/mean_estimation/mean_estimation_operator.py
index 1e5b5d7db7..767a03a651 100644
--- a/qualtran/bloqs/mean_estimation/mean_estimation_operator.py
+++ b/qualtran/bloqs/mean_estimation/mean_estimation_operator.py
@@ -12,8 +12,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+from collections.abc import Iterator
from functools import cached_property
-from typing import Iterator, Tuple, TYPE_CHECKING
+from typing import TYPE_CHECKING
import attrs
from numpy.typing import NDArray
@@ -95,7 +96,7 @@ def select(self) -> ComplexPhaseOracle:
return ComplexPhaseOracle(self.code.encoder, self.arctan_bitsize)
@cached_property
- def selection_registers(self) -> Tuple[Register, ...]:
+ def selection_registers(self) -> tuple[Register, ...]:
return self.code.encoder.selection_registers
@cached_property
diff --git a/qualtran/bloqs/mean_estimation/mean_estimation_operator_test.py b/qualtran/bloqs/mean_estimation/mean_estimation_operator_test.py
index bbc6d9ff32..ec4f06b441 100644
--- a/qualtran/bloqs/mean_estimation/mean_estimation_operator_test.py
+++ b/qualtran/bloqs/mean_estimation/mean_estimation_operator_test.py
@@ -12,8 +12,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+from collections.abc import Iterator, Sequence
from functools import cached_property
-from typing import Iterator, Optional, Sequence, Tuple
+from typing import Optional
import cirq
import numpy as np
@@ -39,7 +40,7 @@ class BernoulliSynthesizer(PrepareOracle):
nqubits: int
@cached_property
- def selection_registers(self) -> Tuple[Register, ...]:
+ def selection_registers(self) -> tuple[Register, ...]:
return (Register('q', BQUInt(self.nqubits, 2)),)
def decompose_from_registers( # type:ignore[override]
@@ -55,21 +56,21 @@ class BernoulliEncoder(SelectOracle):
r"""Encodes Bernoulli random variable y0/y1 as $Enc|ii..i>|0> = |ii..i>|y_{i}>$ where i=0/1."""
p: float
- y: Tuple[int, int]
+ y: tuple[int, int]
selection_bitsize: int
target_bitsize: int
control_val: Optional[int] = None
@cached_property
- def control_registers(self) -> Tuple[Register, ...]:
+ def control_registers(self) -> tuple[Register, ...]:
return ()
@cached_property
- def selection_registers(self) -> Tuple[Register, ...]:
+ def selection_registers(self) -> tuple[Register, ...]:
return (Register('q', BQUInt(self.selection_bitsize, 2)),)
@cached_property
- def target_registers(self) -> Tuple[Register, ...]:
+ def target_registers(self) -> tuple[Register, ...]:
return (Register('t', QAny(self.target_bitsize)),)
def decompose_from_registers( # type:ignore[override]
@@ -179,7 +180,7 @@ class GroverSynthesizer(PrepareOracle):
n: int
@cached_property
- def selection_registers(self) -> Tuple[Register, ...]:
+ def selection_registers(self) -> tuple[Register, ...]:
return (Register('selection', QAny(self.n)),)
def decompose_from_registers( # type:ignore[override]
@@ -202,15 +203,15 @@ class GroverEncoder(SelectOracle):
marked_val: int
@cached_property
- def control_registers(self) -> Tuple[Register, ...]:
+ def control_registers(self) -> tuple[Register, ...]:
return ()
@cached_property
- def selection_registers(self) -> Tuple[Register, ...]:
+ def selection_registers(self) -> tuple[Register, ...]:
return (Register('selection', QAny(self.n)),)
@cached_property
- def target_registers(self) -> Tuple[Register, ...]:
+ def target_registers(self) -> tuple[Register, ...]:
return (Register('target', QAny(self.marked_val.bit_length())),)
def decompose_from_registers( # type:ignore[override]
diff --git a/qualtran/bloqs/mod_arithmetic/mod_addition.py b/qualtran/bloqs/mod_arithmetic/mod_addition.py
index 0a167e84fe..2b6e166285 100644
--- a/qualtran/bloqs/mod_arithmetic/mod_addition.py
+++ b/qualtran/bloqs/mod_arithmetic/mod_addition.py
@@ -13,7 +13,7 @@
# limitations under the License.
from functools import cached_property
-from typing import Dict, Optional, Tuple, TYPE_CHECKING, Union
+from typing import Optional, TYPE_CHECKING, Union
import numpy as np
import sympy
@@ -86,7 +86,7 @@ def signature(self) -> 'Signature':
def on_classical_vals(
self, x: 'ClassicalValT', y: 'ClassicalValT'
- ) -> Dict[str, 'ClassicalValT']:
+ ) -> dict[str, 'ClassicalValT']:
# The construction still works when at most one of inputs equals `mod`.
special_case = (x == self.mod) ^ (y == self.mod)
if not (0 <= x < self.mod or special_case):
@@ -101,7 +101,7 @@ def on_classical_vals(
y = (x + y) % self.mod
return {'x': x, 'y': y}
- def build_composite_bloq(self, bb: 'BloqBuilder', x: Soquet, y: Soquet) -> Dict[str, 'SoquetT']:
+ def build_composite_bloq(self, bb: 'BloqBuilder', x: Soquet, y: Soquet) -> dict[str, 'SoquetT']:
if is_symbolic(self.bitsize):
raise DecomposeTypeError(f"Cannot decompose {self} with symbolic `bitsize`.")
# Allocate ancilla bits for use in addition.
@@ -197,7 +197,7 @@ class ModAddK(GateWithRegisters):
bitsize: int
mod: int = field()
add_val: int = 1
- cvs: Tuple[int, ...] = field(
+ cvs: tuple[int, ...] = field(
converter=lambda v: (v,) if isinstance(v, int) else tuple(v), default=()
)
@@ -226,7 +226,7 @@ def _classical_unctrled(self, target_val: int):
def on_classical_vals(
self, *, x: int, ctrl: Optional[int] = None
- ) -> Dict[str, 'ClassicalValT']:
+ ) -> dict[str, 'ClassicalValT']:
out = self._classical_unctrled(x)
if self.cvs:
assert ctrl is not None
@@ -306,7 +306,7 @@ def signature(self) -> 'Signature':
def build_composite_bloq(
self, bb: 'BloqBuilder', ctrl: 'Soquet', x: 'Soquet'
- ) -> Dict[str, 'SoquetT']:
+ ) -> dict[str, 'SoquetT']:
k = bb.add(IntState(bitsize=self.bitsize, val=self.k))
ctrl, k, x = bb.add(CModAdd(QUInt(self.bitsize), mod=self.mod), ctrl=ctrl, x=k, y=x)
bb.add(IntEffect(bitsize=self.bitsize, val=self.k), val=k)
@@ -314,7 +314,7 @@ def build_composite_bloq(
def on_classical_vals(
self, ctrl: 'ClassicalValT', x: 'ClassicalValT'
- ) -> Dict[str, 'ClassicalValT']:
+ ) -> dict[str, 'ClassicalValT']:
if ctrl == 0:
return {'ctrl': 0, 'x': x}
@@ -332,7 +332,7 @@ def build_call_graph(self, ssa: 'SympySymbolAllocator') -> 'BloqCountDictT':
return {CModAdd(QUInt(self.bitsize), mod=self.mod): 1}
def wire_symbol(
- self, reg: Optional['Register'], idx: Tuple[int, ...] = tuple()
+ self, reg: Optional['Register'], idx: tuple[int, ...] = tuple()
) -> 'WireSymbol':
if reg is None:
return Text(f"mod {self.mod}")
@@ -396,7 +396,7 @@ def signature(self) -> 'Signature':
def build_composite_bloq(
self, bb: 'BloqBuilder', ctrl: 'Soquet', x: 'Soquet', y: 'Soquet'
- ) -> Dict[str, 'SoquetT']:
+ ) -> dict[str, 'SoquetT']:
if is_symbolic(self.bitsize):
raise DecomposeTypeError(f"Cannot decompose {self} with symbolic `bitsize`.")
x_split = bb.split(x)
@@ -429,7 +429,7 @@ def build_call_graph(self, ssa: 'SympySymbolAllocator') -> 'BloqCountDictT':
def on_classical_vals(
self, ctrl: 'ClassicalValT', x: 'ClassicalValT', y: 'ClassicalValT'
- ) -> Dict[str, 'ClassicalValT']:
+ ) -> dict[str, 'ClassicalValT']:
if ctrl == 0:
return {'ctrl': 0, 'x': x, 'y': y}
@@ -438,7 +438,7 @@ def on_classical_vals(
return {'ctrl': ctrl, 'x': x, 'y': y_out}
def wire_symbol(
- self, reg: Optional['Register'], idx: Tuple[int, ...] = tuple()
+ self, reg: Optional['Register'], idx: tuple[int, ...] = tuple()
) -> 'WireSymbol':
if reg is None:
return Text(f"mod {self.mod}")
@@ -506,7 +506,7 @@ def signature(self) -> 'Signature':
def on_classical_vals(
self, ctrl: 'ClassicalValT', x: 'ClassicalValT', y: 'ClassicalValT'
- ) -> Dict[str, 'ClassicalValT']:
+ ) -> dict[str, 'ClassicalValT']:
if ctrl != self.cv:
return {'ctrl': ctrl, 'x': x, 'y': y}
@@ -526,7 +526,7 @@ def on_classical_vals(
def build_composite_bloq(
self, bb: 'BloqBuilder', ctrl, x: Soquet, y: Soquet
- ) -> Dict[str, 'SoquetT']:
+ ) -> dict[str, 'SoquetT']:
if is_symbolic(self.dtype.bitsize):
raise DecomposeTypeError(f'symbolic decomposition is not supported for {self}')
y_arr = bb.split(y)
diff --git a/qualtran/bloqs/mod_arithmetic/mod_division.py b/qualtran/bloqs/mod_arithmetic/mod_division.py
index 947f40eb5d..96ea3f4dce 100644
--- a/qualtran/bloqs/mod_arithmetic/mod_division.py
+++ b/qualtran/bloqs/mod_arithmetic/mod_division.py
@@ -13,7 +13,7 @@
# limitations under the License.
from functools import cached_property
-from typing import cast, Dict, List, Optional, Tuple, TYPE_CHECKING, Union
+from typing import cast, Optional, TYPE_CHECKING, Union
import numpy as np
import sympy
@@ -68,7 +68,7 @@ def signature(self) -> 'Signature':
def on_classical_vals(
self, v: int, m: int, f: int, is_terminal: int
- ) -> Dict[str, 'ClassicalValT']:
+ ) -> dict[str, 'ClassicalValT']:
m ^= f & (v == 0)
assert is_terminal == 0
is_terminal ^= m
@@ -77,7 +77,7 @@ def on_classical_vals(
def build_composite_bloq(
self, bb: 'BloqBuilder', v: Soquet, m: Soquet, f: Soquet, is_terminal: Soquet
- ) -> Dict[str, 'SoquetT']:
+ ) -> dict[str, 'SoquetT']:
if is_symbolic(self.bitsize):
raise DecomposeTypeError(f'symbolic decomposition is not supported for {self}')
v_arr = bb.split(v)
@@ -96,7 +96,7 @@ def build_composite_bloq(
def build_call_graph(self, ssa: 'SympySymbolAllocator') -> 'BloqCountDictT':
if is_symbolic(self.bitsize):
- cvs: Union[HasLength, List[int]] = HasLength(self.bitsize + 1)
+ cvs: Union[HasLength, list[int]] = HasLength(self.bitsize + 1)
else:
cvs = [0] * int(self.bitsize) + [1]
return {MultiAnd(cvs=cvs): 1, MultiAnd(cvs=cvs).adjoint(): 1, CNOT(): 3}
@@ -123,7 +123,7 @@ def signature(self) -> 'Signature':
def on_classical_vals(
self, u: int, v: int, b: int, a: int, m: int, f: int
- ) -> Dict[str, 'ClassicalValT']:
+ ) -> dict[str, 'ClassicalValT']:
a ^= ((u & 1) == 0) & f
m ^= ((v & 1) == 0) & (a == 0) & f
b ^= a
@@ -132,7 +132,7 @@ def on_classical_vals(
def build_composite_bloq(
self, bb: 'BloqBuilder', u: Soquet, v: Soquet, b: Soquet, a: Soquet, m: Soquet, f: Soquet
- ) -> Dict[str, 'SoquetT']:
+ ) -> dict[str, 'SoquetT']:
if is_symbolic(self.bitsize):
raise DecomposeTypeError(f"Cannot decompose {self} with symbolic `bitsize`.")
@@ -186,7 +186,7 @@ def signature(self) -> 'Signature':
def on_classical_vals(
self, u: int, v: int, b: int, a: int, m: int, f: int
- ) -> Dict[str, 'ClassicalValT']:
+ ) -> dict[str, 'ClassicalValT']:
c = (u > v) & (b == 0) & f
a ^= c
m ^= c
@@ -194,7 +194,7 @@ def on_classical_vals(
def build_composite_bloq(
self, bb: 'BloqBuilder', u: Soquet, v: Soquet, b: Soquet, a: Soquet, m: Soquet, f: Soquet
- ) -> Dict[str, 'SoquetT']:
+ ) -> dict[str, 'SoquetT']:
u, v, junk_c, greater_than = bb.add(
LinearDepthHalfGreaterThan(QMontgomeryUInt(self.bitsize)), a=u, b=v
)
@@ -248,7 +248,7 @@ def signature(self) -> 'Signature':
def on_classical_vals(
self, u: int, v: int, r: int, s: int, a: int
- ) -> Dict[str, 'ClassicalValT']:
+ ) -> dict[str, 'ClassicalValT']:
if a:
u, v = v, u
r, s = s, r
@@ -256,7 +256,7 @@ def on_classical_vals(
def build_composite_bloq(
self, bb: 'BloqBuilder', u: Soquet, v: Soquet, r: Soquet, s: Soquet, a: Soquet
- ) -> Dict[str, 'SoquetT']:
+ ) -> dict[str, 'SoquetT']:
a, u, v = bb.add(CSwap(self.bitsize), ctrl=a, x=u, y=v)
a, r, s = bb.add(CSwap(self.bitsize), ctrl=a, x=r, y=s)
return {'u': u, 'v': v, 'r': r, 's': s, 'a': a}
@@ -286,7 +286,7 @@ def signature(self) -> 'Signature':
def on_classical_vals(
self, u: int, v: int, r: int, s: int, b: int, f: int
- ) -> Dict[str, 'ClassicalValT']:
+ ) -> dict[str, 'ClassicalValT']:
if f and b == 0:
v -= u
s += r
@@ -294,7 +294,7 @@ def on_classical_vals(
def build_composite_bloq(
self, bb: 'BloqBuilder', u: Soquet, v: Soquet, r: Soquet, s: Soquet, b: Soquet, f: Soquet
- ) -> Dict[str, 'SoquetT']:
+ ) -> dict[str, 'SoquetT']:
(f, b), c = bb.add(And(1, 0), ctrl=(f, b))
v = bb.add(BitwiseNot(QMontgomeryUInt(self.bitsize)), x=v)
c, u, v = bb.add(CAdd(QMontgomeryUInt(self.bitsize)), ctrl=c, a=u, b=v)
@@ -336,7 +336,7 @@ def signature(self) -> 'Signature':
def on_classical_vals(
self, u: int, v: int, r: int, s: int, b: int, a: int, m: int, f: int
- ) -> Dict[str, 'ClassicalValT']:
+ ) -> dict[str, 'ClassicalValT']:
b ^= m
b ^= a
if f:
@@ -360,7 +360,7 @@ def build_composite_bloq(
a: Soquet,
m: Soquet,
f: Soquet,
- ) -> Dict[str, 'SoquetT']:
+ ) -> dict[str, 'SoquetT']:
if is_symbolic(self.bitsize, self.mod):
raise DecomposeTypeError(f'symbolic decomposition is not supported for {self}')
m, b = bb.add(CNOT(), ctrl=m, target=b)
@@ -426,7 +426,7 @@ def build_composite_bloq(
m: Soquet,
f: Soquet,
is_terminal: Soquet,
- ) -> Dict[str, 'SoquetT']:
+ ) -> dict[str, 'SoquetT']:
a = bb.allocate(1)
b = bb.allocate(1)
@@ -463,7 +463,7 @@ def build_call_graph(self, ssa: 'SympySymbolAllocator') -> 'BloqCountDictT':
def on_classical_vals(
self, u: int, v: int, r: int, s: int, m: int, f: int, is_terminal: int
- ) -> Dict[str, 'ClassicalValT']:
+ ) -> dict[str, 'ClassicalValT']:
"""This is the Kaliski algorithm as described in Fig7 of https://arxiv.org/pdf/2001.09580.
The following implementation merges together the pseudocode from Fig7 of https://arxiv.org/pdf/2001.09580
@@ -539,7 +539,7 @@ def build_composite_bloq(
m: Soquet,
f: Soquet,
terminal_condition: Soquet,
- ) -> Dict[str, 'SoquetT']:
+ ) -> dict[str, 'SoquetT']:
if is_symbolic(self.bitsize):
raise DecomposeTypeError(f"Cannot decompose {self} with symbolic `bitsize`.")
@@ -664,7 +664,7 @@ def signature(self) -> 'Signature':
def build_composite_bloq(
self, bb: 'BloqBuilder', x: Soquet, junk: Optional[Soquet] = None
- ) -> Dict[str, 'SoquetT']:
+ ) -> dict[str, 'SoquetT']:
if is_symbolic(self.bitsize):
raise DecomposeTypeError(f"Cannot decompose {self} with symbolic `bitsize`.")
@@ -679,7 +679,7 @@ def build_composite_bloq(
m = bb.join(junk_arr[: 2 * self.bitsize])
terminal_condition = bb.join(junk_arr[2 * self.bitsize :])
u, x, r, s, m, f, terminal_condition = cast(
- Tuple[Soquet, Soquet, Soquet, Soquet, Soquet, Soquet, Soquet],
+ tuple[Soquet, Soquet, Soquet, Soquet, Soquet, Soquet, Soquet],
bb.add_from(
_KaliskiModInverseImpl(self.bitsize, self.mod).adjoint(),
u=u,
@@ -702,7 +702,7 @@ def build_composite_bloq(
m = bb.allocate(2 * self.bitsize)
terminal_condition = bb.allocate(2 * self.bitsize)
u, v, x, s, m, f, terminal_condition = cast(
- Tuple[Soquet, Soquet, Soquet, Soquet, Soquet, Soquet, Soquet],
+ tuple[Soquet, Soquet, Soquet, Soquet, Soquet, Soquet, Soquet],
bb.add_from(
_KaliskiModInverseImpl(self.bitsize, self.mod),
u=u,
@@ -728,7 +728,7 @@ def adjoint(self) -> 'KaliskiModInverse':
def build_call_graph(self, ssa: 'SympySymbolAllocator') -> 'BloqCountDictT':
return _KaliskiModInverseImpl(self.bitsize, self.mod).build_call_graph(ssa)
- def on_classical_vals(self, x: int, junk: int = 0) -> Dict[str, 'ClassicalValT']:
+ def on_classical_vals(self, x: int, junk: int = 0) -> dict[str, 'ClassicalValT']:
mod = int(self.mod)
u, v, r, s, f = mod, x, 0, 1, 1
terminal_condition = m = 0
diff --git a/qualtran/bloqs/mod_arithmetic/mod_multiplication.py b/qualtran/bloqs/mod_arithmetic/mod_multiplication.py
index c0242f9735..7dadba1ed5 100644
--- a/qualtran/bloqs/mod_arithmetic/mod_multiplication.py
+++ b/qualtran/bloqs/mod_arithmetic/mod_multiplication.py
@@ -14,8 +14,9 @@
import math
import numbers
+from collections.abc import Sequence
from functools import cached_property
-from typing import cast, Dict, Optional, Sequence, Set, Tuple, TYPE_CHECKING, Union
+from typing import cast, Optional, TYPE_CHECKING, Union
import attrs
import numpy as np
@@ -86,12 +87,12 @@ def _validate_mod(self, attribute, value):
def signature(self) -> 'Signature':
return Signature([Register('x', self.dtype)])
- def on_classical_vals(self, x: 'ClassicalValT') -> Dict[str, 'ClassicalValT']:
+ def on_classical_vals(self, x: 'ClassicalValT') -> dict[str, 'ClassicalValT']:
if x < self.mod:
x = (x + x) % self.mod
return {'x': x}
- def build_composite_bloq(self, bb: 'BloqBuilder', x: Soquet) -> Dict[str, 'SoquetT']:
+ def build_composite_bloq(self, bb: 'BloqBuilder', x: Soquet) -> dict[str, 'SoquetT']:
if is_symbolic(self.dtype.bitsize):
raise DecomposeTypeError(f'symbolic decomposition is not supported for {self}')
@@ -140,7 +141,7 @@ def build_composite_bloq(self, bb: 'BloqBuilder', x: Soquet) -> Dict[str, 'Soque
return {'x': x}
def wire_symbol(
- self, reg: Optional['Register'], idx: Tuple[int, ...] = tuple()
+ self, reg: Optional['Register'], idx: tuple[int, ...] = tuple()
) -> 'WireSymbol':
if reg is None:
return Text(f'x = 2 * x mod {self.mod}')
@@ -207,7 +208,7 @@ def _Add(self, k: Union[int, sympy.Expr]):
def build_composite_bloq(
self, bb: 'BloqBuilder', ctrl: 'SoquetT', x: 'SoquetT'
- ) -> Dict[str, 'SoquetT']:
+ ) -> dict[str, 'SoquetT']:
k = self.k
if isinstance(self.mod, sympy.Expr) or isinstance(k, sympy.Expr):
neg_k_inv = sympy.Mod(sympy.Pow(k, -1), self.mod)
@@ -235,12 +236,12 @@ def build_call_graph(self, ssa: SympySymbolAllocator) -> BloqCountDictT:
k = ssa.new_symbol('k')
return {self._Add(k=k): 2, CSwap(self.dtype.bitsize): 1}
- def on_classical_vals(self, ctrl, x) -> Dict[str, ClassicalValT]:
+ def on_classical_vals(self, ctrl, x) -> dict[str, ClassicalValT]:
if ctrl and x < self.mod:
return {'ctrl': ctrl, 'x': (x * self.k) % self.mod}
return {'ctrl': ctrl, 'x': x}
- def wire_symbol(self, reg: Optional[Register], idx: Tuple[int, ...] = tuple()) -> 'WireSymbol':
+ def wire_symbol(self, reg: Optional[Register], idx: tuple[int, ...] = tuple()) -> 'WireSymbol':
if reg is None:
return Text(f'x *= {self.k} % {self.mod}')
if reg.name == 'ctrl':
@@ -494,7 +495,7 @@ def build_composite_bloq(
target: Soquet,
qrom_indices: Soquet,
reduced: Soquet,
- ) -> Dict[str, 'SoquetT']:
+ ) -> dict[str, 'SoquetT']:
if is_symbolic(self.window_size) or is_symbolic(self.bitsize) or is_symbolic(self.mod):
raise DecomposeNotImplementedError(f'symbolic decomposition not supported for {self}')
x_arr = bb.split(x)
@@ -650,7 +651,7 @@ def on_classical_vals(
target: Optional['ClassicalValT'] = None,
qrom_indices: Optional['ClassicalValT'] = None,
reduced: Optional['ClassicalValT'] = None,
- ) -> Dict[str, ClassicalValT]:
+ ) -> dict[str, ClassicalValT]:
if is_symbolic(self.bitsize) or is_symbolic(self.window_size) or is_symbolic(self.mod):
raise ValueError(f'classical action is not supported for {self}')
if self.uncompute:
@@ -697,7 +698,7 @@ def build_composite_bloq(
target: Optional[Soquet] = None,
qrom_indices: Optional[Soquet] = None,
reduced: Optional[Soquet] = None,
- ) -> Dict[str, 'SoquetT']:
+ ) -> dict[str, 'SoquetT']:
if self.uncompute:
assert target is not None
assert qrom_indices is not None
@@ -731,7 +732,7 @@ def build_composite_bloq(
def build_call_graph(
self, ssa: 'SympySymbolAllocator'
- ) -> Union[Set['BloqCountT'], BloqCountDictT]:
+ ) -> Union[set['BloqCountT'], BloqCountDictT]:
return self._mod_mul_impl.build_call_graph(ssa)
diff --git a/qualtran/bloqs/mod_arithmetic/mod_subtraction.py b/qualtran/bloqs/mod_arithmetic/mod_subtraction.py
index e0d0fbf81a..7a3fae6100 100644
--- a/qualtran/bloqs/mod_arithmetic/mod_subtraction.py
+++ b/qualtran/bloqs/mod_arithmetic/mod_subtraction.py
@@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from functools import cached_property
-from typing import Dict, Optional, Tuple, TYPE_CHECKING, Union
+from typing import Optional, TYPE_CHECKING, Union
import sympy
from attrs import frozen
@@ -73,7 +73,7 @@ class ModNeg(Bloq):
def signature(self) -> 'Signature':
return Signature([Register('x', self.dtype)])
- def build_composite_bloq(self, bb: 'BloqBuilder', x: Soquet) -> Dict[str, 'SoquetT']:
+ def build_composite_bloq(self, bb: 'BloqBuilder', x: Soquet) -> dict[str, 'SoquetT']:
if not isinstance(self.dtype.bitsize, int):
raise DecomposeTypeError(f'symbolic decomposition is not supported for {self}')
@@ -106,7 +106,7 @@ def build_call_graph(self, ssa: 'SympySymbolAllocator') -> 'BloqCountDictT':
}
def wire_symbol(
- self, reg: Optional['Register'], idx: Tuple[int, ...] = tuple()
+ self, reg: Optional['Register'], idx: tuple[int, ...] = tuple()
) -> 'WireSymbol':
if reg is None:
return Text("")
@@ -114,7 +114,7 @@ def wire_symbol(
return TextBox('$-x$')
raise ValueError(f'Unrecognized register name {reg.name}')
- def on_classical_vals(self, x: 'ClassicalValT') -> Dict[str, 'ClassicalValT']:
+ def on_classical_vals(self, x: 'ClassicalValT') -> dict[str, 'ClassicalValT']:
if 0 < x < self.mod:
x = self.mod - x
return {'x': x}
@@ -153,7 +153,7 @@ def signature(self) -> 'Signature':
def build_composite_bloq(
self, bb: 'BloqBuilder', ctrl: Soquet, x: Soquet
- ) -> Dict[str, 'SoquetT']:
+ ) -> dict[str, 'SoquetT']:
if not isinstance(self.dtype.bitsize, int):
raise DecomposeTypeError(f'symbolic decomposition is not supported for {self}')
@@ -199,7 +199,7 @@ def build_call_graph(self, ssa: 'SympySymbolAllocator') -> 'BloqCountDictT':
}
def wire_symbol(
- self, reg: Optional['Register'], idx: Tuple[int, ...] = tuple()
+ self, reg: Optional['Register'], idx: tuple[int, ...] = tuple()
) -> 'WireSymbol':
if reg is None:
return Text("")
@@ -211,7 +211,7 @@ def wire_symbol(
def on_classical_vals(
self, ctrl: 'ClassicalValT', x: 'ClassicalValT'
- ) -> Dict[str, 'ClassicalValT']:
+ ) -> dict[str, 'ClassicalValT']:
if ctrl == self.cv and 0 < x < self.mod:
x = self.mod - x
return {'ctrl': ctrl, 'x': x}
@@ -265,7 +265,7 @@ class ModSub(Bloq):
def signature(self) -> 'Signature':
return Signature([Register('x', self.dtype), Register('y', self.dtype)])
- def build_composite_bloq(self, bb: 'BloqBuilder', x: Soquet, y: Soquet) -> Dict[str, 'SoquetT']:
+ def build_composite_bloq(self, bb: 'BloqBuilder', x: Soquet, y: Soquet) -> dict[str, 'SoquetT']:
x = bb.add(BitwiseNot(self.dtype), x=x)
x = bb.add(AddK(self.dtype, self.mod + 1), x=x)
x, y = bb.add(ModAdd(self.dtype.bitsize, self.mod), x=x, y=y)
@@ -282,7 +282,7 @@ def build_call_graph(self, ssa: 'SympySymbolAllocator') -> 'BloqCountDictT':
}
def wire_symbol(
- self, reg: Optional['Register'], idx: Tuple[int, ...] = tuple()
+ self, reg: Optional['Register'], idx: tuple[int, ...] = tuple()
) -> 'WireSymbol':
if reg is None:
return Text("")
@@ -294,7 +294,7 @@ def wire_symbol(
def on_classical_vals(
self, x: 'ClassicalValT', y: 'ClassicalValT'
- ) -> Dict[str, 'ClassicalValT']:
+ ) -> dict[str, 'ClassicalValT']:
if 0 <= x < self.mod and 0 <= y < self.mod:
y -= x
if y < 0:
@@ -345,7 +345,7 @@ def signature(self) -> 'Signature':
def build_composite_bloq(
self, bb: 'BloqBuilder', ctrl: Soquet, x: Soquet, y: Soquet
- ) -> Dict[str, 'SoquetT']:
+ ) -> dict[str, 'SoquetT']:
x = bb.add(BitwiseNot(self.dtype), x=x)
x = bb.add(AddK(self.dtype, self.mod + 1), x=x)
ctrl, x, y = bb.add(CModAdd(self.dtype, self.mod, self.cv), ctrl=ctrl, x=x, y=y)
@@ -362,7 +362,7 @@ def build_call_graph(self, ssa: 'SympySymbolAllocator') -> 'BloqCountDictT':
}
def wire_symbol(
- self, reg: Optional['Register'], idx: Tuple[int, ...] = tuple()
+ self, reg: Optional['Register'], idx: tuple[int, ...] = tuple()
) -> 'WireSymbol':
if reg is None:
return Text("")
@@ -376,7 +376,7 @@ def wire_symbol(
def on_classical_vals(
self, ctrl: 'ClassicalValT', x: 'ClassicalValT', y: 'ClassicalValT'
- ) -> Dict[str, 'ClassicalValT']:
+ ) -> dict[str, 'ClassicalValT']:
if ctrl == self.cv and 0 <= x < self.mod and 0 <= y < self.mod:
y -= x
if y < 0:
diff --git a/qualtran/bloqs/multiplexers/apply_gate_to_lth_target.ipynb b/qualtran/bloqs/multiplexers/apply_gate_to_lth_target.ipynb
index 7b733722e6..215fca97bc 100644
--- a/qualtran/bloqs/multiplexers/apply_gate_to_lth_target.ipynb
+++ b/qualtran/bloqs/multiplexers/apply_gate_to_lth_target.ipynb
@@ -70,7 +70,7 @@
"`selection`-th qubit of `target` all controlled by the `control` register.\n",
"\n",
"#### Parameters\n",
- " - `selection_regs`: Indexing `select` signature of type Tuple[`Register`, ...]. It also contains information about the iteration length of each selection register.\n",
+ " - `selection_regs`: Indexing `select` signature of type tuple[`Register`, ...]. It also contains information about the iteration length of each selection register.\n",
" - `nth_gate`: A function mapping the composite selection index to a single-qubit gate.\n",
" - `control_regs`: Control signature for constructing a controlled version of the gate. \n",
"\n",
diff --git a/qualtran/bloqs/multiplexers/apply_gate_to_lth_target.py b/qualtran/bloqs/multiplexers/apply_gate_to_lth_target.py
index 77f70157ce..d9476f1420 100644
--- a/qualtran/bloqs/multiplexers/apply_gate_to_lth_target.py
+++ b/qualtran/bloqs/multiplexers/apply_gate_to_lth_target.py
@@ -13,8 +13,8 @@
# limitations under the License.
import itertools
+from collections.abc import Callable, Sequence
from functools import cached_property
-from typing import Callable, Sequence, Tuple
import attrs
import cirq
@@ -40,7 +40,7 @@ class ApplyGateToLthQubit(UnaryIterationGate):
`selection`-th qubit of `target` all controlled by the `control` register.
Args:
- selection_regs: Indexing `select` signature of type Tuple[`Register`, ...].
+ selection_regs: Indexing `select` signature of type tuple[`Register`, ...].
It also contains information about the iteration length of each selection register.
nth_gate: A function mapping the composite selection index to a single-qubit gate.
control_regs: Control signature for constructing a controlled version of the gate.
@@ -50,11 +50,11 @@ class ApplyGateToLthQubit(UnaryIterationGate):
Babbush et al. (2018). Section III.A. and Figure 7.
"""
- selection_regs: Tuple[Register, ...] = attrs.field(
+ selection_regs: tuple[Register, ...] = attrs.field(
converter=lambda v: (v,) if isinstance(v, Register) else tuple(v)
)
nth_gate: Callable[..., cirq.Gate]
- control_regs: Tuple[Register, ...] = attrs.field(
+ control_regs: tuple[Register, ...] = attrs.field(
converter=lambda v: (v,) if isinstance(v, Register) else tuple(v),
default=(Register('control', QBit()),),
)
@@ -71,15 +71,15 @@ def make_on(
).on_registers(**quregs)
@cached_property
- def control_registers(self) -> Tuple[Register, ...]:
+ def control_registers(self) -> tuple[Register, ...]:
return self.control_regs
@cached_property
- def selection_registers(self) -> Tuple[Register, ...]:
+ def selection_registers(self) -> tuple[Register, ...]:
return self.selection_regs
@cached_property
- def target_registers(self) -> Tuple[Register, ...]:
+ def target_registers(self) -> tuple[Register, ...]:
if any(
isinstance(reg.dtype.iteration_length_or_zero(), sympy.Expr)
for reg in self.selection_registers
diff --git a/qualtran/bloqs/multiplexers/apply_lth_bloq.py b/qualtran/bloqs/multiplexers/apply_lth_bloq.py
index 57ea79336c..5cf51dbd57 100644
--- a/qualtran/bloqs/multiplexers/apply_lth_bloq.py
+++ b/qualtran/bloqs/multiplexers/apply_lth_bloq.py
@@ -12,8 +12,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+from collections.abc import Iterable, Sequence
from functools import cached_property
-from typing import cast, Iterable, Optional, Sequence, Set, Tuple, Union
+from typing import cast, Optional, Union
import cirq
import numpy as np
@@ -69,7 +70,7 @@ class ApplyLthBloq(UnaryIterationGate, SelectOracle): # type: ignore[misc]
converter=lambda x: np.array(x) if isinstance(x, Iterable) else x,
eq=lambda d: tuple(d.flat),
)
- selection_regs: Optional[Tuple[Register, ...]] = None
+ selection_regs: Optional[tuple[Register, ...]] = None
control_val: Optional[int] = None
def __attrs_post_init__(self):
@@ -81,11 +82,11 @@ def __attrs_post_init__(self):
raise ValueError("All ops must have only THRU registers.")
@cached_property
- def control_registers(self) -> Tuple[Register, ...]:
+ def control_registers(self) -> tuple[Register, ...]:
return () if self.control_val is None else (Register('control', QBit()),)
@cached_property
- def selection_registers(self) -> Tuple[Register, ...]:
+ def selection_registers(self) -> tuple[Register, ...]:
if self.selection_regs is None:
return tuple(
Register(
@@ -97,10 +98,10 @@ def selection_registers(self) -> Tuple[Register, ...]:
return self.selection_regs
@cached_property
- def target_registers(self) -> Tuple[Register, ...]:
+ def target_registers(self) -> tuple[Register, ...]:
return tuple(self.ops.flat[0].signature) # type: ignore
- def nth_operation_callgraph(self, **kwargs: int) -> Set[BloqCountT]:
+ def nth_operation_callgraph(self, **kwargs: int) -> set[BloqCountT]:
return {(self.ops[tuple(kwargs.values())].controlled(), 1)}
def nth_operation(
@@ -117,7 +118,7 @@ def nth_operation(
target_qubits = merge_qubits(bloq.signature, **targets)
return bloq.controlled().on(control, *target_qubits)
- def get_ctrl_system(self, ctrl_spec: 'CtrlSpec') -> Tuple['Bloq', 'AddControlledT']:
+ def get_ctrl_system(self, ctrl_spec: 'CtrlSpec') -> tuple['Bloq', 'AddControlledT']:
from qualtran.bloqs.mcmt.specialized_ctrl import get_ctrl_system_1bit_cv
return get_ctrl_system_1bit_cv(
diff --git a/qualtran/bloqs/multiplexers/black_box_select.py b/qualtran/bloqs/multiplexers/black_box_select.py
index 8cb8d402b1..cb68d9af6e 100644
--- a/qualtran/bloqs/multiplexers/black_box_select.py
+++ b/qualtran/bloqs/multiplexers/black_box_select.py
@@ -13,7 +13,6 @@
# limitations under the License.
from functools import cached_property
-from typing import Dict, Tuple
from attr import frozen
@@ -60,15 +59,15 @@ def __str__(self) -> str:
return 'SELECT'
@cached_property
- def selection_registers(self) -> Tuple[Register, ...]:
+ def selection_registers(self) -> tuple[Register, ...]:
return (Register(name='selection', dtype=QAny(self.selection_bitsize)),)
@cached_property
- def control_registers(self) -> Tuple[Register, ...]:
+ def control_registers(self) -> tuple[Register, ...]:
return self.select.control_registers
@cached_property
- def target_registers(self) -> Tuple[Register, ...]:
+ def target_registers(self) -> tuple[Register, ...]:
return (Register(name='system', dtype=QAny(self.system_bitsize)),)
@cached_property
@@ -83,7 +82,7 @@ def selection_bitsize(self) -> SymbolicInt:
def system_bitsize(self) -> SymbolicInt:
return ssum(r.total_bits() for r in self.select.target_registers)
- def build_composite_bloq(self, bb: BloqBuilder, **soqs: SoquetT) -> Dict[str, SoquetT]:
+ def build_composite_bloq(self, bb: BloqBuilder, **soqs: SoquetT) -> dict[str, SoquetT]:
partitions = (
(self.selection_registers[0], [r.name for r in self.select.selection_registers]),
(self.target_registers[0], [r.name for r in self.select.target_registers]),
diff --git a/qualtran/bloqs/multiplexers/black_box_select_test.py b/qualtran/bloqs/multiplexers/black_box_select_test.py
index 6bd3dd68d3..97a90c0eea 100644
--- a/qualtran/bloqs/multiplexers/black_box_select_test.py
+++ b/qualtran/bloqs/multiplexers/black_box_select_test.py
@@ -12,8 +12,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-from typing import Tuple
-
from attr import frozen
from qualtran import QAny, QBit, Register
@@ -28,15 +26,15 @@ def test_black_box_select(bloq_autotester):
@frozen
class TestSelectOracle(SelectOracle):
@property
- def control_registers(self) -> Tuple[Register, ...]:
+ def control_registers(self) -> tuple[Register, ...]:
return ()
@property
- def selection_registers(self) -> Tuple[Register, ...]:
+ def selection_registers(self) -> tuple[Register, ...]:
return (Register('z', QBit()),)
@property
- def target_registers(self) -> Tuple[Register, ...]:
+ def target_registers(self) -> tuple[Register, ...]:
return (Register('a', QAny(5)),)
diff --git a/qualtran/bloqs/multiplexers/select_base.py b/qualtran/bloqs/multiplexers/select_base.py
index dc72bbc1a4..fd621eca37 100644
--- a/qualtran/bloqs/multiplexers/select_base.py
+++ b/qualtran/bloqs/multiplexers/select_base.py
@@ -14,7 +14,6 @@
import abc
from functools import cached_property
-from typing import Tuple
from qualtran import BloqDocSpec, GateWithRegisters, Register, Signature
@@ -39,15 +38,15 @@ class SelectOracle(GateWithRegisters):
@property
@abc.abstractmethod
- def control_registers(self) -> Tuple[Register, ...]: ...
+ def control_registers(self) -> tuple[Register, ...]: ...
@property
@abc.abstractmethod
- def selection_registers(self) -> Tuple[Register, ...]: ...
+ def selection_registers(self) -> tuple[Register, ...]: ...
@property
@abc.abstractmethod
- def target_registers(self) -> Tuple[Register, ...]: ...
+ def target_registers(self) -> tuple[Register, ...]: ...
@cached_property
def signature(self) -> Signature:
diff --git a/qualtran/bloqs/multiplexers/select_pauli_lcu.py b/qualtran/bloqs/multiplexers/select_pauli_lcu.py
index 41e2f8ddb3..be65d0a261 100644
--- a/qualtran/bloqs/multiplexers/select_pauli_lcu.py
+++ b/qualtran/bloqs/multiplexers/select_pauli_lcu.py
@@ -14,8 +14,9 @@
"""Bloqs for applying SELECT unitary for LCU of Pauli Strings."""
+from collections.abc import Iterable, Iterator, Sequence
from functools import cached_property
-from typing import Iterable, Iterator, Optional, Sequence, Tuple
+from typing import Optional
import attrs
import cirq
@@ -71,7 +72,7 @@ class SelectPauliLCU(SelectOracle, UnaryIterationGate): # type: ignore[misc]
selection_bitsize: int
target_bitsize: int
- select_unitaries: Tuple[cirq.DensePauliString, ...] = attrs.field(converter=_to_tuple)
+ select_unitaries: tuple[cirq.DensePauliString, ...] = attrs.field(converter=_to_tuple)
control_val: Optional[int] = None
def __attrs_post_init__(self):
@@ -87,15 +88,15 @@ def __attrs_post_init__(self):
)
@cached_property
- def control_registers(self) -> Tuple[Register, ...]:
+ def control_registers(self) -> tuple[Register, ...]:
return () if self.control_val is None else (Register('control', QBit()),)
@cached_property
- def selection_registers(self) -> Tuple[Register, ...]:
+ def selection_registers(self) -> tuple[Register, ...]:
return (Register('selection', BQUInt(self.selection_bitsize, len(self.select_unitaries))),)
@cached_property
- def target_registers(self) -> Tuple[Register, ...]:
+ def target_registers(self) -> tuple[Register, ...]:
return (Register('target', QAny(self.target_bitsize)),)
def decompose_from_registers(
@@ -126,7 +127,7 @@ def nth_operation( # type: ignore[override]
ps = self.select_unitaries[selection].on(*target)
return ps.with_coefficient(np.sign(complex(ps.coefficient).real)).controlled_by(control)
- def get_ctrl_system(self, ctrl_spec: 'CtrlSpec') -> Tuple['Bloq', 'AddControlledT']:
+ def get_ctrl_system(self, ctrl_spec: 'CtrlSpec') -> tuple['Bloq', 'AddControlledT']:
from qualtran.bloqs.mcmt.specialized_ctrl import get_ctrl_system_1bit_cv
return get_ctrl_system_1bit_cv(
diff --git a/qualtran/bloqs/multiplexers/select_pauli_lcu_test.py b/qualtran/bloqs/multiplexers/select_pauli_lcu_test.py
index c075593269..a50692086a 100644
--- a/qualtran/bloqs/multiplexers/select_pauli_lcu_test.py
+++ b/qualtran/bloqs/multiplexers/select_pauli_lcu_test.py
@@ -11,7 +11,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.
-from typing import Sequence
+from collections.abc import Sequence
import cirq
import numpy as np
diff --git a/qualtran/bloqs/multiplexers/selected_majorana_fermion.py b/qualtran/bloqs/multiplexers/selected_majorana_fermion.py
index fd5a94952e..317c06a5a7 100644
--- a/qualtran/bloqs/multiplexers/selected_majorana_fermion.py
+++ b/qualtran/bloqs/multiplexers/selected_majorana_fermion.py
@@ -12,8 +12,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+from collections.abc import Iterator, Sequence
from functools import cached_property
-from typing import Iterator, Sequence, Tuple, Union
+from typing import Union
import attrs
import cirq
@@ -47,10 +48,10 @@ class SelectedMajoranaFermion(UnaryIterationGate):
Fig 9.
"""
- selection_regs: Tuple[Register, ...] = attrs.field(
+ selection_regs: tuple[Register, ...] = attrs.field(
converter=lambda v: (v,) if isinstance(v, Register) else tuple(v)
)
- control_regs: Tuple[Register, ...] = attrs.field(
+ control_regs: tuple[Register, ...] = attrs.field(
converter=lambda v: (v,) if isinstance(v, Register) else tuple(v),
default=(Register('control', QBit()),),
)
@@ -72,15 +73,15 @@ def make_on(
).on_registers(**quregs)
@cached_property
- def control_registers(self) -> Tuple[Register, ...]:
+ def control_registers(self) -> tuple[Register, ...]:
return self.control_regs
@cached_property
- def selection_registers(self) -> Tuple[Register, ...]:
+ def selection_registers(self) -> tuple[Register, ...]:
return self.selection_regs
@cached_property
- def target_registers(self) -> Tuple[Register, ...]:
+ def target_registers(self) -> tuple[Register, ...]:
if any(
isinstance(reg.dtype.iteration_length_or_zero(), sympy.Expr)
for reg in self.selection_registers
@@ -93,7 +94,7 @@ def target_registers(self) -> Tuple[Register, ...]:
return (Register('target', QAny(int(total_iteration_size))),)
@cached_property
- def extra_registers(self) -> Tuple[Register, ...]:
+ def extra_registers(self) -> tuple[Register, ...]:
return (Register('accumulator', QBit()),)
def decompose_from_registers(
diff --git a/qualtran/bloqs/multiplexers/unary_iteration_bloq.py b/qualtran/bloqs/multiplexers/unary_iteration_bloq.py
index 1c75868a0f..787737a858 100644
--- a/qualtran/bloqs/multiplexers/unary_iteration_bloq.py
+++ b/qualtran/bloqs/multiplexers/unary_iteration_bloq.py
@@ -14,8 +14,9 @@
import abc
from collections import defaultdict
+from collections.abc import Callable, Iterator, Sequence
from functools import cached_property
-from typing import Callable, Dict, Iterator, List, Sequence, Set, Tuple, TYPE_CHECKING, Union
+from typing import TYPE_CHECKING, Union
import cirq
import numpy as np
@@ -35,7 +36,7 @@
def _unary_iteration_segtree(
- ops: List[cirq.Operation],
+ ops: list[cirq.Operation],
control: cirq.Qid,
selection: Sequence[cirq.Qid],
ancilla: Sequence[cirq.Qid],
@@ -45,7 +46,7 @@ def _unary_iteration_segtree(
l_iter: int,
r_iter: int,
break_early: Callable[[int, int], bool],
-) -> Iterator[Tuple[cirq.OP_TREE, cirq.Qid, int]]:
+) -> Iterator[tuple[cirq.OP_TREE, cirq.Qid, int]]:
"""Constructs a unary iteration circuit by iterating over nodes of an implicit Segment Tree.
Args:
@@ -71,7 +72,7 @@ def _unary_iteration_segtree(
`(OP_TREE, control_qubit, l)` for all integers in the range `[l, r)`.
Yields:
- One `Tuple[cirq.OP_TREE, cirq.Qid, int]` for each leaf node in the segment tree. The i'th
+ One `tuple[cirq.OP_TREE, cirq.Qid, int]` for each leaf node in the segment tree. The i'th
yielded element corresponds to the i'th leaf node which represents the `l_iter + i`'th
integer. The tuple corresponds to:
- cirq.OP_TREE: Operations to be inserted in the circuit in between the last leaf node
@@ -116,13 +117,13 @@ def _unary_iteration_segtree(
def _unary_iteration_zero_control(
- ops: List[cirq.Operation],
+ ops: list[cirq.Operation],
selection: Sequence[cirq.Qid],
ancilla: Sequence[cirq.Qid],
l_iter: int,
r_iter: int,
break_early: Callable[[int, int], bool],
-) -> Iterator[Tuple[cirq.OP_TREE, cirq.Qid, int]]:
+) -> Iterator[tuple[cirq.OP_TREE, cirq.Qid, int]]:
sl, l, r = 0, 0, 2 ** len(selection)
m = (l + r) >> 1
if r_iter <= m:
@@ -141,14 +142,14 @@ def _unary_iteration_zero_control(
def _unary_iteration_single_control(
- ops: List[cirq.Operation],
+ ops: list[cirq.Operation],
control: cirq.Qid,
selection: Sequence[cirq.Qid],
ancilla: Sequence[cirq.Qid],
l_iter: int,
r_iter: int,
break_early: Callable[[int, int], bool],
-) -> Iterator[Tuple[cirq.OP_TREE, cirq.Qid, int]]:
+) -> Iterator[tuple[cirq.OP_TREE, cirq.Qid, int]]:
sl, l, r = 0, 0, 2 ** len(selection)
yield from _unary_iteration_segtree(
ops, control, selection, ancilla, sl, l, r, l_iter, r_iter, break_early
@@ -156,14 +157,14 @@ def _unary_iteration_single_control(
def _unary_iteration_multi_controls(
- ops: List[cirq.Operation],
+ ops: list[cirq.Operation],
controls: Sequence[cirq.Qid],
selection: Sequence[cirq.Qid],
ancilla: Sequence[cirq.Qid],
l_iter: int,
r_iter: int,
break_early: Callable[[int, int], bool],
-) -> Iterator[Tuple[cirq.OP_TREE, cirq.Qid, int]]:
+) -> Iterator[tuple[cirq.OP_TREE, cirq.Qid, int]]:
num_controls = len(controls)
and_ancilla = ancilla[: num_controls - 2]
and_target = ancilla[num_controls - 2]
@@ -188,12 +189,12 @@ def _unary_iteration_multi_controls(
def unary_iteration(
l_iter: int,
r_iter: int,
- flanking_ops: List[cirq.Operation],
+ flanking_ops: list[cirq.Operation],
controls: Sequence[cirq.Qid],
selection: Sequence[cirq.Qid],
qubit_manager: cirq.QubitManager,
break_early: Callable[[int, int], bool] = lambda l, r: False,
-) -> Iterator[Tuple[cirq.OP_TREE, cirq.Qid, int]]:
+) -> Iterator[tuple[cirq.OP_TREE, cirq.Qid, int]]:
"""The method performs unary iteration on `selection` integer in `range(l_iter, r_iter)`.
Unary iteration is a coherent for loop that can be used to conditionally perform a different
@@ -244,7 +245,7 @@ def unary_iteration(
(r_iter - l_iter) different tuples, each corresponding to an integer in range
[l_iter, r_iter).
Each returned tuple also corresponds to a unique leaf in the unary iteration tree.
- The values of yielded `Tuple[cirq.OP_TREE, cirq.Qid, int]` correspond to:
+ The values of yielded `tuple[cirq.OP_TREE, cirq.Qid, int]` correspond to:
- cirq.OP_TREE: The op-tree to be inserted in the circuit to get to the current leaf.
- cirq.Qid: Control qubit used to conditionally apply operations on the target conditioned
on the returned integer.
@@ -274,8 +275,8 @@ def _unary_iteration_callgraph_segtree(
l_range: int,
r_range: int,
break_early: Callable[[int, int], bool],
- bloq_counts: Dict['Bloq', Union[int, 'sympy.Expr']],
-) -> List[int]:
+ bloq_counts: dict['Bloq', Union[int, 'sympy.Expr']],
+) -> list[int]:
"""Iterative segment tree used to construct call graph for Unary iteration.
See https://codeforces.com/blog/entry/18051 for an explanation of how iterative
@@ -310,7 +311,7 @@ def _unary_iteration_callgraph_segtree(
n_levels = n.bit_length()
marked = np.zeros(2 * n, dtype=bool)
num_ands = 0
- ret: List[int] = []
+ ret: list[int] = []
step_size = n
for lvl in range(1, n_levels + 1):
r = l_range
@@ -350,7 +351,7 @@ def _unary_iteration_callgraph(
selection_bitsize: int,
control_bitsize: int,
break_early: Callable[[int, int], bool],
- bloq_counts: Dict['Bloq', Union[int, 'sympy.Expr']],
+ bloq_counts: dict['Bloq', Union[int, 'sympy.Expr']],
) -> Sequence[int]:
"""Helper to compute the call graph for unary iteration.
@@ -409,17 +410,17 @@ class UnaryIterationGate(GateWithRegisters):
@cached_property
@abc.abstractmethod
- def control_registers(self) -> Tuple[Register, ...]:
+ def control_registers(self) -> tuple[Register, ...]:
pass
@cached_property
@abc.abstractmethod
- def selection_registers(self) -> Tuple[Register, ...]:
+ def selection_registers(self) -> tuple[Register, ...]:
pass
@cached_property
@abc.abstractmethod
- def target_registers(self) -> Tuple[Register, ...]:
+ def target_registers(self) -> tuple[Register, ...]:
pass
@cached_property
@@ -429,7 +430,7 @@ def signature(self) -> Signature:
)
@cached_property
- def extra_registers(self) -> Tuple[Register, ...]:
+ def extra_registers(self) -> tuple[Register, ...]:
return ()
@abc.abstractmethod
@@ -479,7 +480,7 @@ def decompose_zero_selection(
raise NotImplementedError("Selection register must not be empty.")
def _break_early(
- self, selection_index_prefix: Tuple[int, ...], l: 'SymbolicInt', r: 'SymbolicInt'
+ self, selection_index_prefix: tuple[int, ...], l: 'SymbolicInt', r: 'SymbolicInt'
) -> bool:
"""Derived classes should override this method to specify an early termination condition.
@@ -520,7 +521,7 @@ def decompose_from_registers(
def unary_iteration_loops(
nested_depth: int,
- selection_reg_name_to_val: Dict[str, int],
+ selection_reg_name_to_val: dict[str, int],
controls: Sequence[cirq.Qid],
) -> Iterator[cirq.OP_TREE]:
"""Recursively write any number of nested coherent for-loops using unary iteration.
@@ -553,7 +554,7 @@ def unary_iteration_loops(
)
return
# Use recursion to write `num_loops` nested loops using unary_iteration().
- ops: List[cirq.Operation] = []
+ ops: list[cirq.Operation] = []
selection_index_prefix = tuple(selection_reg_name_to_val.values())
ith_for_loop = unary_iteration(
l_iter=0,
@@ -586,23 +587,23 @@ def _circuit_diagram_info_(self, args: cirq.CircuitDiagramInfoArgs) -> cirq.Circ
wire_symbols += [self.__class__.__name__] * total_bits(self.target_registers)
return cirq.CircuitDiagramInfo(wire_symbols=wire_symbols)
- def nth_operation_callgraph(self, **selection_regs_name_to_val) -> Set['BloqCountT']:
+ def nth_operation_callgraph(self, **selection_regs_name_to_val) -> set['BloqCountT']:
raise NotImplementedError(
f"Derived class {type(self)} does not implement `nth_operation_callgraph`."
)
def build_call_graph(
self, ssa: 'SympySymbolAllocator'
- ) -> Union['BloqCountDictT', Set['BloqCountT']]:
+ ) -> Union['BloqCountDictT', set['BloqCountT']]:
if total_bits(self.selection_registers) == 0 or self._break_early(
(), 0, self.selection_registers[0].dtype.iteration_length_or_zero()
):
return self.decompose_bloq().build_call_graph(ssa)
num_loops = len(self.selection_registers)
- bloq_counts: Dict['Bloq', Union[int, 'sympy.Expr']] = defaultdict(lambda: 0)
+ bloq_counts: dict['Bloq', Union[int, 'sympy.Expr']] = defaultdict(lambda: 0)
def unary_iteration_loops(
- nested_depth: int, selection_reg_name_to_val: Dict[str, int], num_controls: int
+ nested_depth: int, selection_reg_name_to_val: dict[str, int], num_controls: int
) -> None:
if nested_depth == num_loops:
for bloq, count in self.nth_operation_callgraph(**selection_reg_name_to_val):
diff --git a/qualtran/bloqs/multiplexers/unary_iteration_bloq_test.py b/qualtran/bloqs/multiplexers/unary_iteration_bloq_test.py
index 529640770d..9c4b2ea524 100644
--- a/qualtran/bloqs/multiplexers/unary_iteration_bloq_test.py
+++ b/qualtran/bloqs/multiplexers/unary_iteration_bloq_test.py
@@ -13,8 +13,9 @@
# limitations under the License.
import itertools
+from collections.abc import Iterator, Sequence
from functools import cached_property
-from typing import Iterator, List, Sequence, Set, Tuple, TYPE_CHECKING
+from typing import TYPE_CHECKING
import cirq
import pytest
@@ -40,17 +41,17 @@ def __init__(self, selection_bitsize: int, target_bitsize: int, control_bitsize:
self._control_bitsize = control_bitsize
@cached_property
- def control_registers(self) -> Tuple[Register, ...]:
+ def control_registers(self) -> tuple[Register, ...]:
return (
(Register('control', QAny(self._control_bitsize)),) if self._control_bitsize > 0 else ()
)
@cached_property
- def selection_registers(self) -> Tuple[Register, ...]:
+ def selection_registers(self) -> tuple[Register, ...]:
return (Register('selection', BQUInt(self._selection_bitsize, self._target_bitsize)),)
@cached_property
- def target_registers(self) -> Tuple[Register, ...]:
+ def target_registers(self) -> tuple[Register, ...]:
return (Register('target', QAny(self._target_bitsize)),)
def nth_operation( # type: ignore[override]
@@ -62,7 +63,7 @@ def nth_operation( # type: ignore[override]
) -> cirq.OP_TREE:
return cirq.CNOT(control, target[-(selection + 1)])
- def nth_operation_callgraph(self, **selection_regs_name_to_val) -> Set['BloqCountT']:
+ def nth_operation_callgraph(self, **selection_regs_name_to_val) -> set['BloqCountT']:
return {(CNOT(), 1)}
@@ -91,15 +92,15 @@ def test_unary_iteration_gate(selection_bitsize, target_bitsize, control_bitsize
class ApplyXToIJKthQubit(UnaryIterationGate):
- def __init__(self, target_shape: Tuple[int, int, int]):
+ def __init__(self, target_shape: tuple[int, int, int]):
self._target_shape = target_shape
@cached_property
- def control_registers(self) -> Tuple[Register, ...]:
+ def control_registers(self) -> tuple[Register, ...]:
return ()
@cached_property
- def selection_registers(self) -> Tuple[Register, ...]:
+ def selection_registers(self) -> tuple[Register, ...]:
return tuple(
Register(
'ijk'[i], BQUInt((self._target_shape[i] - 1).bit_length(), self._target_shape[i])
@@ -108,7 +109,7 @@ def selection_registers(self) -> Tuple[Register, ...]:
)
@cached_property
- def target_registers(self) -> Tuple[Register, ...]:
+ def target_registers(self) -> tuple[Register, ...]:
return tuple(
Signature.build(
t1=self._target_shape[0], t2=self._target_shape[1], t3=self._target_shape[2]
@@ -128,13 +129,13 @@ def nth_operation( # type: ignore[override]
) -> Iterator[cirq.OP_TREE]:
yield [cirq.CNOT(control, t1[i]), cirq.CNOT(control, t2[j]), cirq.CNOT(control, t3[k])]
- def nth_operation_callgraph(self, **selection_regs_name_to_val) -> Set['BloqCountT']:
+ def nth_operation_callgraph(self, **selection_regs_name_to_val) -> set['BloqCountT']:
return {(CNOT(), 3)}
@pytest.mark.slow
@pytest.mark.parametrize("target_shape", [(2, 3, 2), (2, 2, 2)])
-def test_multi_dimensional_unary_iteration_gate(target_shape: Tuple[int, int, int]):
+def test_multi_dimensional_unary_iteration_gate(target_shape: tuple[int, int, int]):
greedy_mm = cirq.GreedyQubitManager(prefix="_a", maximize_reuse=True)
gate = ApplyXToIJKthQubit(target_shape)
g = GateHelper(gate, context=cirq.DecompositionContext(greedy_mm))
@@ -166,13 +167,13 @@ def test_unary_iteration_loop():
target = {(n, m): cirq.q(f't({n}, {m})') for n in range(*n_range) for m in range(*m_range)}
qm = cirq.GreedyQubitManager("ancilla", maximize_reuse=True)
circuit = cirq.Circuit()
- i_ops: List[cirq.Operation] = []
+ i_ops: list[cirq.Operation] = []
# Build the unary iteration circuit
for i_optree, i_ctrl, i in unary_iteration(
n_range[0], n_range[1], i_ops, [], list(selection['n']), qm
):
circuit.append(i_optree)
- j_ops: List[cirq.Operation] = []
+ j_ops: list[cirq.Operation] = []
for j_optree, j_ctrl, j in unary_iteration(
m_range[0], m_range[1], j_ops, [i_ctrl], list(selection['m']), qm
):
@@ -225,7 +226,7 @@ def test_bloq_has_consistent_decomposition(selection_bitsize, target_bitsize, co
@pytest.mark.parametrize("target_shape", [(2, 3, 2), (2, 2, 2)])
-def test_multi_dimensional_bloq_has_consistent_decomposition(target_shape: Tuple[int, int, int]):
+def test_multi_dimensional_bloq_has_consistent_decomposition(target_shape: tuple[int, int, int]):
bloq = ApplyXToIJKthQubit(target_shape)
assert_valid_bloq_decomposition(bloq)
verify_bloq_has_consistent_build_callgraph(bloq)
diff --git a/qualtran/bloqs/optimization/k_xor_sat/kxor_instance.py b/qualtran/bloqs/optimization/k_xor_sat/kxor_instance.py
index 913ae06ae0..4ce0e90bc7 100644
--- a/qualtran/bloqs/optimization/k_xor_sat/kxor_instance.py
+++ b/qualtran/bloqs/optimization/k_xor_sat/kxor_instance.py
@@ -25,8 +25,9 @@
# limitations under the License.
import itertools
from collections import defaultdict
+from collections.abc import Sequence
from functools import cached_property
-from typing import cast, Sequence, TypeAlias, Union
+from typing import cast, TypeAlias, Union
import numpy as np
import sympy
diff --git a/qualtran/bloqs/phase_estimation/kaiser_window_state.py b/qualtran/bloqs/phase_estimation/kaiser_window_state.py
index 38e851f815..ad9ae6de94 100644
--- a/qualtran/bloqs/phase_estimation/kaiser_window_state.py
+++ b/qualtran/bloqs/phase_estimation/kaiser_window_state.py
@@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from functools import cached_property
-from typing import Dict, List, TYPE_CHECKING
+from typing import TYPE_CHECKING
import attrs
import numpy as np
@@ -106,8 +106,8 @@ def from_precision_and_delta(
return KaiserWindowState(bitsize=m_bits, alpha=alpha)
def my_tensors(
- self, incoming: Dict[str, 'ConnectionT'], outgoing: Dict[str, 'ConnectionT']
- ) -> List['qtn.Tensor']:
+ self, incoming: dict[str, 'ConnectionT'], outgoing: dict[str, 'ConnectionT']
+ ) -> list['qtn.Tensor']:
import quimb.tensor as qtn
return [
diff --git a/qualtran/bloqs/phase_estimation/lp_resource_state.py b/qualtran/bloqs/phase_estimation/lp_resource_state.py
index 55466291ab..5462c16521 100644
--- a/qualtran/bloqs/phase_estimation/lp_resource_state.py
+++ b/qualtran/bloqs/phase_estimation/lp_resource_state.py
@@ -15,7 +15,7 @@
"""Resource states proposed by A. Luis and J. Peřina (1996) for optimal phase measurements"""
from collections import Counter
from functools import cached_property
-from typing import Dict, Optional, Tuple, TYPE_CHECKING
+from typing import Optional, TYPE_CHECKING
import attrs
import numpy as np
@@ -56,14 +56,14 @@ class LPRSInterimPrep(GateWithRegisters):
def signature(self) -> 'Signature':
return Signature.build(m=self.bitsize, anc=1)
- def wire_symbol(self, reg: Optional[Register], idx: Tuple[int, ...] = tuple()) -> 'WireSymbol':
+ def wire_symbol(self, reg: Optional[Register], idx: tuple[int, ...] = tuple()) -> 'WireSymbol':
if reg is None:
return Text('LPRS')
return super().wire_symbol(reg, idx)
def build_composite_bloq(
self, bb: 'BloqBuilder', *, m: 'SoquetT', anc: 'Soquet'
- ) -> Dict[str, 'SoquetT']:
+ ) -> dict[str, 'SoquetT']:
if isinstance(self.bitsize, sympy.Expr):
raise ValueError(f'Symbolic bitsize {self.bitsize} not supported')
m = bb.add(OnEach(self.bitsize, Hadamard()), q=m)
@@ -140,7 +140,7 @@ def from_standard_deviation_eps(cls, eps: SymbolicFloat) -> 'LPResourceState':
def m_bits(self) -> SymbolicInt:
return self.bitsize
- def build_composite_bloq(self, bb: 'BloqBuilder', **soqs: 'SoquetT') -> Dict[str, 'SoquetT']:
+ def build_composite_bloq(self, bb: 'BloqBuilder', **soqs: 'SoquetT') -> dict[str, 'SoquetT']:
qpe_reg = bb.allocate(dtype=self.m_qdtype)
anc, flag = bb.allocate(dtype=QBit()), bb.allocate(dtype=QBit())
diff --git a/qualtran/bloqs/phase_estimation/qpe_window_state.py b/qualtran/bloqs/phase_estimation/qpe_window_state.py
index 075147c04e..fe548ca5e7 100644
--- a/qualtran/bloqs/phase_estimation/qpe_window_state.py
+++ b/qualtran/bloqs/phase_estimation/qpe_window_state.py
@@ -13,7 +13,7 @@
# limitations under the License.
import abc
from functools import cached_property
-from typing import Dict, TYPE_CHECKING
+from typing import TYPE_CHECKING
import attrs
@@ -99,7 +99,7 @@ def from_standard_deviation_eps(cls, eps: SymbolicFloat):
"""
return cls(ceil(2 * log2(pi(eps) / eps)))
- def build_composite_bloq(self, bb: 'BloqBuilder') -> Dict[str, 'SoquetT']:
+ def build_composite_bloq(self, bb: 'BloqBuilder') -> dict[str, 'SoquetT']:
qpe_reg = bb.allocate(dtype=self.m_qdtype)
qpe_reg = bb.add(OnEach(self.m_bits, Hadamard()), q=qpe_reg)
return {'qpe_reg': qpe_reg}
diff --git a/qualtran/bloqs/phase_estimation/qubitization_qpe.py b/qualtran/bloqs/phase_estimation/qubitization_qpe.py
index 39b608ea57..0d86e887da 100644
--- a/qualtran/bloqs/phase_estimation/qubitization_qpe.py
+++ b/qualtran/bloqs/phase_estimation/qubitization_qpe.py
@@ -11,8 +11,9 @@
# 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.
+from collections.abc import Iterator
from functools import cached_property
-from typing import Iterator, Tuple, TYPE_CHECKING
+from typing import TYPE_CHECKING
import attrs
import cirq
@@ -95,11 +96,11 @@ def m_bits(self) -> SymbolicInt:
return self.ctrl_state_prep.m_bits
@cached_property
- def target_registers(self) -> Tuple[Register, ...]:
+ def target_registers(self) -> tuple[Register, ...]:
return tuple(self.walk.signature)
@cached_property
- def phase_registers(self) -> Tuple[Register, ...]:
+ def phase_registers(self) -> tuple[Register, ...]:
return tuple(self.ctrl_state_prep.signature)
@cached_property
diff --git a/qualtran/bloqs/phase_estimation/text_book_qpe.py b/qualtran/bloqs/phase_estimation/text_book_qpe.py
index 9349ca3290..aed8f17486 100644
--- a/qualtran/bloqs/phase_estimation/text_book_qpe.py
+++ b/qualtran/bloqs/phase_estimation/text_book_qpe.py
@@ -11,8 +11,9 @@
# 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.
+from collections.abc import Iterator
from functools import cached_property
-from typing import Iterator, Tuple, TYPE_CHECKING
+from typing import TYPE_CHECKING
import attrs
import cirq
@@ -157,11 +158,11 @@ def m_bits(self) -> SymbolicInt:
return self.ctrl_state_prep.m_bits
@cached_property
- def target_registers(self) -> Tuple[Register, ...]:
+ def target_registers(self) -> tuple[Register, ...]:
return tuple(self.unitary.signature)
@cached_property
- def phase_registers(self) -> Tuple[Register, ...]:
+ def phase_registers(self) -> tuple[Register, ...]:
return tuple(self.ctrl_state_prep.signature)
@cached_property
diff --git a/qualtran/bloqs/qft/approximate_qft.py b/qualtran/bloqs/qft/approximate_qft.py
index e6dfcee861..4837fe2e4e 100644
--- a/qualtran/bloqs/qft/approximate_qft.py
+++ b/qualtran/bloqs/qft/approximate_qft.py
@@ -12,8 +12,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from collections import defaultdict
+from collections.abc import Iterator
from functools import cached_property
-from typing import Iterator, TYPE_CHECKING
+from typing import TYPE_CHECKING
import attrs
import cirq
diff --git a/qualtran/bloqs/qft/approximate_qft_test.py b/qualtran/bloqs/qft/approximate_qft_test.py
index 7dd0b10f8d..b4b02adb42 100644
--- a/qualtran/bloqs/qft/approximate_qft_test.py
+++ b/qualtran/bloqs/qft/approximate_qft_test.py
@@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import math
-from typing import Dict, TYPE_CHECKING
+from typing import TYPE_CHECKING
import attrs
import cirq
@@ -43,7 +43,7 @@ class TestApproximateQFT(GateWithRegisters):
def signature(self) -> 'Signature':
return Signature.build(q=self.bitsize)
- def build_composite_bloq(self, bb: 'BloqBuilder', *, q: 'SoquetT') -> Dict[str, 'SoquetT']:
+ def build_composite_bloq(self, bb: 'BloqBuilder', *, q: 'SoquetT') -> dict[str, 'SoquetT']:
phase_grad = bb.add(PhaseGradientState(self.phase_bitsize, exponent=-1))
q, phase_grad = bb.add(
diff --git a/qualtran/bloqs/qft/qft_phase_gradient.py b/qualtran/bloqs/qft/qft_phase_gradient.py
index 6597eba42b..efa7d7ac53 100644
--- a/qualtran/bloqs/qft/qft_phase_gradient.py
+++ b/qualtran/bloqs/qft/qft_phase_gradient.py
@@ -11,8 +11,8 @@
# 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.
+from collections.abc import Iterator
from functools import cached_property
-from typing import Iterator
import attrs
import cirq
diff --git a/qualtran/bloqs/qft/qft_phase_gradient_test.py b/qualtran/bloqs/qft/qft_phase_gradient_test.py
index d6fee8c159..680e62ddab 100644
--- a/qualtran/bloqs/qft/qft_phase_gradient_test.py
+++ b/qualtran/bloqs/qft/qft_phase_gradient_test.py
@@ -11,7 +11,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.
-from typing import Dict, TYPE_CHECKING
+from typing import TYPE_CHECKING
import attrs
import cirq
@@ -38,7 +38,7 @@ class TestQFTWithPhaseGradient(GateWithRegisters):
def signature(self) -> 'Signature':
return Signature.build(q=self.bitsize)
- def build_composite_bloq(self, bb: 'BloqBuilder', *, q: 'SoquetT') -> Dict[str, 'SoquetT']:
+ def build_composite_bloq(self, bb: 'BloqBuilder', *, q: 'SoquetT') -> dict[str, 'SoquetT']:
phase_grad = bb.add(PhaseGradientState(self.bitsize))
q, phase_grad = bb.add(
QFTPhaseGradient(self.bitsize, self.with_reverse), q=q, phase_grad=phase_grad
diff --git a/qualtran/bloqs/qft/qft_text_book.py b/qualtran/bloqs/qft/qft_text_book.py
index c560deab20..cd1bb2bcbc 100644
--- a/qualtran/bloqs/qft/qft_text_book.py
+++ b/qualtran/bloqs/qft/qft_text_book.py
@@ -11,8 +11,8 @@
# 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.
+from collections.abc import Iterator
from functools import cached_property
-from typing import Iterator
import attrs
import cirq
diff --git a/qualtran/bloqs/qft/two_bit_ffft.py b/qualtran/bloqs/qft/two_bit_ffft.py
index a707f9c802..a4a395a5b5 100644
--- a/qualtran/bloqs/qft/two_bit_ffft.py
+++ b/qualtran/bloqs/qft/two_bit_ffft.py
@@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from functools import cached_property
-from typing import Dict, List, Optional, Tuple, TYPE_CHECKING
+from typing import Optional, TYPE_CHECKING
import numpy as np
from attrs import frozen
@@ -87,14 +87,14 @@ def __attrs_post_init__(self):
def signature(self) -> Signature:
return Signature([Register('x', QBit()), Register('y', QBit())])
- def wire_symbol(self, reg: Optional[Register], idx: Tuple[int, ...] = tuple()) -> 'WireSymbol':
+ def wire_symbol(self, reg: Optional[Register], idx: tuple[int, ...] = tuple()) -> 'WireSymbol':
if reg is None:
return Text('F(k, n)')
return super().wire_symbol(reg, idx)
def my_tensors(
- self, incoming: Dict[str, 'ConnectionT'], outgoing: Dict[str, 'ConnectionT']
- ) -> List['qtn.Tensor']:
+ self, incoming: dict[str, 'ConnectionT'], outgoing: dict[str, 'ConnectionT']
+ ) -> list['qtn.Tensor']:
import quimb.tensor as qtn
# TODO: https://github.com/quantumlib/Qualtran/issues/873. This tensor definition
@@ -119,7 +119,7 @@ def build_call_graph(self, ssa: 'SympySymbolAllocator') -> 'BloqCountDictT':
def build_composite_bloq(
self, bb: 'BloqBuilder', x: 'Soquet', y: 'Soquet'
- ) -> Dict[str, 'SoquetT']:
+ ) -> dict[str, 'SoquetT']:
x = bb.add(Rz(2 * np.pi * self.k / self.n, eps=self.eps), q=x)
y = bb.add(SGate(), q=y)
x = bb.add(Hadamard(), q=x)
diff --git a/qualtran/bloqs/qsp/fast_qsp.py b/qualtran/bloqs/qsp/fast_qsp.py
index eada77ac61..62ea067cd6 100644
--- a/qualtran/bloqs/qsp/fast_qsp.py
+++ b/qualtran/bloqs/qsp/fast_qsp.py
@@ -11,7 +11,8 @@
# 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.
-from typing import Sequence, Union
+from collections.abc import Sequence
+from typing import Union
import numpy as np
from numpy.typing import NDArray
diff --git a/qualtran/bloqs/qsp/fft_qsp.py b/qualtran/bloqs/qsp/fft_qsp.py
index 855d7a61b3..0265e5fe93 100644
--- a/qualtran/bloqs/qsp/fft_qsp.py
+++ b/qualtran/bloqs/qsp/fft_qsp.py
@@ -11,7 +11,8 @@
# 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.
-from typing import Sequence, Union
+from collections.abc import Sequence
+from typing import Union
import numpy as np
diff --git a/qualtran/bloqs/qsp/generalized_qsp.py b/qualtran/bloqs/qsp/generalized_qsp.py
index 04cc75184d..9612529df9 100644
--- a/qualtran/bloqs/qsp/generalized_qsp.py
+++ b/qualtran/bloqs/qsp/generalized_qsp.py
@@ -12,8 +12,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from collections import Counter
+from collections.abc import Iterable, Iterator, Sequence
from functools import cached_property
-from typing import Iterable, Iterator, Sequence, Tuple, TYPE_CHECKING, Union
+from typing import TYPE_CHECKING, Union
import numpy as np
from attrs import field, frozen
@@ -165,7 +166,7 @@ def assert_is_permutation(A, B):
def qsp_phase_factors(
P: Union[NDArray[np.number], Sequence[complex]], Q: Union[NDArray[np.number], Sequence[complex]]
-) -> Tuple[NDArray[np.floating], NDArray[np.floating], int]:
+) -> tuple[NDArray[np.floating], NDArray[np.floating], int]:
"""Computes the QSP signal rotations for a given pair of polynomials.
The QSP transformation is described in Theorem 3, and the algorithm for computing
@@ -216,7 +217,7 @@ def safe_angle(x):
return theta, phi, lambd
-def _to_tuple(x: Union[Iterable[complex], Shaped]) -> Union[Tuple[complex, ...], Shaped]:
+def _to_tuple(x: Union[Iterable[complex], Shaped]) -> Union[tuple[complex, ...], Shaped]:
"""mypy-compatible attrs converter for GeneralizedQSP.P and Q"""
if isinstance(x, Shaped):
return x
@@ -283,8 +284,8 @@ class GeneralizedQSP(GateWithRegisters):
"""
U: 'Bloq'
- P: Union[Tuple[complex, ...], Shaped] = field(converter=_to_tuple)
- Q: Union[Tuple[complex, ...], Shaped] = field(converter=_to_tuple)
+ P: Union[tuple[complex, ...], Shaped] = field(converter=_to_tuple)
+ Q: Union[tuple[complex, ...], Shaped] = field(converter=_to_tuple)
negative_power: SymbolicInt = field(default=0, kw_only=True)
precision: SymbolicFloat = field(default=1e-11, kw_only=True)
@@ -319,7 +320,7 @@ def from_qsp_polynomial(
return GeneralizedQSP(U, P, Q, negative_power=negative_power, precision=precision)
@cached_property
- def _qsp_phases(self) -> Tuple[NDArray[np.floating], NDArray[np.floating], float]:
+ def _qsp_phases(self) -> tuple[NDArray[np.floating], NDArray[np.floating], float]:
if isinstance(self.P, Shaped) or isinstance(self.Q, Shaped):
raise ValueError(
'Cannot compute phases for symbolic GQSP polynomials {self.P=}, {self.Q=}'
diff --git a/qualtran/bloqs/qsp/generalized_qsp_test.py b/qualtran/bloqs/qsp/generalized_qsp_test.py
index c925da2a85..ea9ee1ae7c 100644
--- a/qualtran/bloqs/qsp/generalized_qsp_test.py
+++ b/qualtran/bloqs/qsp/generalized_qsp_test.py
@@ -11,8 +11,9 @@
# 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.
+from collections.abc import Sequence
from functools import cached_property
-from typing import Dict, Optional, Sequence
+from typing import Optional
import cirq
import numpy as np
@@ -160,7 +161,7 @@ def catch_rotations(bloq: Bloq) -> Bloq:
g, sigma = gsqp_U.call_graph(max_depth=1, generalizer=catch_rotations)
- expected_counts: Dict[Bloq, int] = {arbitrary_rotation: 3}
+ expected_counts: dict[Bloq, int] = {arbitrary_rotation: 3}
if negative_power < 2:
expected_counts[U.controlled(control_values=[0])] = 2 - negative_power
if negative_power > 0:
diff --git a/qualtran/bloqs/qubitization/qubitization_walk_operator.py b/qualtran/bloqs/qubitization/qubitization_walk_operator.py
index 9e270d8ec3..ae1c9fd8dd 100644
--- a/qualtran/bloqs/qubitization/qubitization_walk_operator.py
+++ b/qualtran/bloqs/qubitization/qubitization_walk_operator.py
@@ -27,7 +27,7 @@
"""
from functools import cached_property
-from typing import Tuple, Union
+from typing import Union
import attrs
import cirq
@@ -93,7 +93,7 @@ class QubitizationWalkOperator(GateWithRegisters):
block_encoding: Union[SelectBlockEncoding, LCUBlockEncoding]
@cached_property
- def selection_registers(self) -> Tuple[Register, ...]:
+ def selection_registers(self) -> tuple[Register, ...]:
regs = tuple(
set(self.block_encoding.selection_registers + self.reflect.selection_registers)
)
@@ -107,11 +107,11 @@ def selection_registers(self) -> Tuple[Register, ...]:
return regs
@cached_property
- def target_registers(self) -> Tuple[Register, ...]:
+ def target_registers(self) -> tuple[Register, ...]:
return self.block_encoding.target_registers
@cached_property
- def junk_registers(self) -> Tuple[Register, ...]:
+ def junk_registers(self) -> tuple[Register, ...]:
return self.block_encoding.junk_registers
@cached_property
diff --git a/qualtran/bloqs/reflections/prepare_identity.py b/qualtran/bloqs/reflections/prepare_identity.py
index cbd8eb35d8..3279641771 100644
--- a/qualtran/bloqs/reflections/prepare_identity.py
+++ b/qualtran/bloqs/reflections/prepare_identity.py
@@ -12,8 +12,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+from collections.abc import Sequence
from functools import cached_property
-from typing import Dict, Sequence, Tuple, TYPE_CHECKING
+from typing import TYPE_CHECKING
from attrs import field, frozen
@@ -41,7 +42,7 @@ class PrepareIdentity(PrepareOracle):
selection_registers: The selection registers.
"""
- selection_regs: Tuple[Register, ...] = field(
+ selection_regs: tuple[Register, ...] = field(
converter=lambda v: (v,) if isinstance(v, Register) else tuple(v)
)
@@ -55,14 +56,14 @@ def from_bitsizes(cls, bitsizes: Sequence[SymbolicInt]) -> 'PrepareIdentity':
return cls(tuple(Register(f'reg{i}_', QAny(b)) for i, b in enumerate(bitsizes)))
@cached_property
- def selection_registers(self) -> Tuple[Register, ...]:
+ def selection_registers(self) -> tuple[Register, ...]:
return self.selection_regs
@cached_property
- def junk_registers(self) -> Tuple[Register, ...]:
+ def junk_registers(self) -> tuple[Register, ...]:
return ()
- def build_composite_bloq(self, bb: 'BloqBuilder', **soqs: Soquet) -> Dict[str, Soquet]:
+ def build_composite_bloq(self, bb: 'BloqBuilder', **soqs: Soquet) -> dict[str, Soquet]:
for label, soq in soqs.items():
soqs[label] = bb.add(Identity(soq.reg.bitsize), q=soq)
return soqs
diff --git a/qualtran/bloqs/reflections/reflection_using_prepare.py b/qualtran/bloqs/reflections/reflection_using_prepare.py
index 4a8467fde1..473f447ea4 100644
--- a/qualtran/bloqs/reflections/reflection_using_prepare.py
+++ b/qualtran/bloqs/reflections/reflection_using_prepare.py
@@ -12,8 +12,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+from collections.abc import Iterator, Sequence
from functools import cached_property
-from typing import Iterator, Optional, Sequence, Tuple, TYPE_CHECKING, Union
+from typing import Optional, TYPE_CHECKING, Union
import attrs
import cirq
@@ -93,11 +94,11 @@ class ReflectionUsingPrepare(GateWithRegisters):
eps: float = 1e-11
@cached_property
- def control_registers(self) -> Tuple[Register, ...]:
+ def control_registers(self) -> tuple[Register, ...]:
return () if self.control_val is None else (Register('control', QBit()),)
@cached_property
- def selection_registers(self) -> Tuple[Register, ...]:
+ def selection_registers(self) -> tuple[Register, ...]:
return self.prepare_gate.selection_registers
@cached_property
@@ -196,7 +197,7 @@ def build_call_graph(self, ssa: 'SympySymbolAllocator') -> 'BloqCountDictT':
def adjoint(self) -> 'ReflectionUsingPrepare':
return self
- def get_ctrl_system(self, ctrl_spec: 'CtrlSpec') -> Tuple['Bloq', 'AddControlledT']:
+ def get_ctrl_system(self, ctrl_spec: 'CtrlSpec') -> tuple['Bloq', 'AddControlledT']:
from qualtran.bloqs.mcmt.specialized_ctrl import get_ctrl_system_1bit_cv
return get_ctrl_system_1bit_cv(
diff --git a/qualtran/bloqs/rotations/hamming_weight_phasing.py b/qualtran/bloqs/rotations/hamming_weight_phasing.py
index 2c55d84b5b..3df6a6ce87 100644
--- a/qualtran/bloqs/rotations/hamming_weight_phasing.py
+++ b/qualtran/bloqs/rotations/hamming_weight_phasing.py
@@ -13,7 +13,7 @@
# limitations under the License.
from functools import cached_property
-from typing import Dict, Optional, Tuple, TYPE_CHECKING
+from typing import Optional, TYPE_CHECKING
import attrs
import numpy as np
@@ -80,7 +80,7 @@ class HammingWeightPhasing(GateWithRegisters):
def signature(self) -> 'Signature':
return Signature.build_from_dtypes(x=QUInt(self.bitsize))
- def build_composite_bloq(self, bb: 'BloqBuilder', **soqs: 'SoquetT') -> Dict[str, 'SoquetT']:
+ def build_composite_bloq(self, bb: 'BloqBuilder', **soqs: 'SoquetT') -> dict[str, 'SoquetT']:
soqs['x'], junk, out = bb.add(HammingWeightCompute(self.bitsize), x=soqs['x'])
out = bb.split(out)
for i in range(len(out)):
@@ -93,7 +93,7 @@ def build_composite_bloq(self, bb: 'BloqBuilder', **soqs: 'SoquetT') -> Dict[str
)
return soqs
- def wire_symbol(self, reg: Optional[Register], idx: Tuple[int, ...] = tuple()) -> 'WireSymbol':
+ def wire_symbol(self, reg: Optional[Register], idx: tuple[int, ...] = tuple()) -> 'WireSymbol':
if reg is None:
return Text(f'HWP_{self.bitsize}(Z^{self.exponent})')
return super().wire_symbol(reg, idx)
@@ -186,13 +186,13 @@ def gamma_dtype(self) -> QFxp:
def build_composite_bloq(
self, bb: 'BloqBuilder', *, x: 'SoquetT', phase_grad: 'SoquetT'
- ) -> Dict[str, 'SoquetT']:
+ ) -> dict[str, 'SoquetT']:
x, junk, out = bb.add(HammingWeightCompute(self.bitsize), x=x)
out, phase_grad = bb.add(self.phase_oracle, out=out, phase_grad=phase_grad)
x = bb.add(HammingWeightCompute(self.bitsize).adjoint(), x=x, junk=junk, out=out)
return {'x': x, 'phase_grad': phase_grad}
- def wire_symbol(self, reg: Optional[Register], idx: Tuple[int, ...] = tuple()) -> 'WireSymbol':
+ def wire_symbol(self, reg: Optional[Register], idx: tuple[int, ...] = tuple()) -> 'WireSymbol':
if reg is None:
return Text(f'HWPG_{self.bitsize}(Z^{self.exponent})')
return super().wire_symbol(reg, idx)
diff --git a/qualtran/bloqs/rotations/hamming_weight_phasing_test.py b/qualtran/bloqs/rotations/hamming_weight_phasing_test.py
index 33dc216268..2a0527c49a 100644
--- a/qualtran/bloqs/rotations/hamming_weight_phasing_test.py
+++ b/qualtran/bloqs/rotations/hamming_weight_phasing_test.py
@@ -11,7 +11,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.
-from typing import Dict, TYPE_CHECKING
+from typing import TYPE_CHECKING
import attrs
import cirq
@@ -85,7 +85,7 @@ def signature(self) -> 'Signature':
def b_grad(self) -> SymbolicInt:
return HammingWeightPhasingViaPhaseGradient(self.bitsize, self.exponent, self.eps).b_grad
- def build_composite_bloq(self, bb: 'BloqBuilder', *, x: 'SoquetT') -> Dict[str, 'SoquetT']:
+ def build_composite_bloq(self, bb: 'BloqBuilder', *, x: 'SoquetT') -> dict[str, 'SoquetT']:
b_grad = self.b_grad
phase_grad = bb.add(PhaseGradientState(b_grad))
x, phase_grad = bb.add(
diff --git a/qualtran/bloqs/rotations/phase_gradient.py b/qualtran/bloqs/rotations/phase_gradient.py
index 0a6dded656..1a5e7d2e27 100644
--- a/qualtran/bloqs/rotations/phase_gradient.py
+++ b/qualtran/bloqs/rotations/phase_gradient.py
@@ -11,8 +11,9 @@
# 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.
+from collections.abc import Iterator, Sequence
from functools import cached_property
-from typing import Dict, Iterator, List, Optional, Sequence, Tuple, TYPE_CHECKING, Union
+from typing import Optional, TYPE_CHECKING, Union
import attrs
import cirq
@@ -261,7 +262,7 @@ class AddIntoPhaseGrad(GateWithRegisters, cirq.ArithmeticGate): # type: ignore[
sign: int = +1
controlled_by: Optional[int] = None
- def wire_symbol(self, reg: Optional[Register], idx: Tuple[int, ...] = tuple()) -> 'WireSymbol':
+ def wire_symbol(self, reg: Optional[Register], idx: tuple[int, ...] = tuple()) -> 'WireSymbol':
sign = '+' if self.sign > 0 else '-'
if reg is None:
return Text(f'pg{sign}=x>>{self.right_shift}' if self.right_shift else f'pg{sign}=x')
@@ -302,7 +303,7 @@ def scaled_val(self, x: int) -> int:
x_fxp = _fxp(x / 2**x_width, x_width).like(_fxp(0, self.phase_bitsize)).astype(float)
return int(x_fxp.astype(float) * 2**self.phase_bitsize)
- def apply(self, *args) -> Tuple[Union[int, np.integer, NDArray[np.integer]], ...]:
+ def apply(self, *args) -> tuple[Union[int, np.integer, NDArray[np.integer]], ...]:
if self.controlled_by is not None:
ctrl, x, phase_grad = args
out = self.on_classical_vals(ctrl=ctrl, x=x, phase_grad=phase_grad)
@@ -312,7 +313,7 @@ def apply(self, *args) -> Tuple[Union[int, np.integer, NDArray[np.integer]], ...
out = self.on_classical_vals(x=x, phase_grad=phase_grad)
return out['x'], out['phase_grad']
- def on_classical_vals(self, **kwargs) -> Dict[str, 'ClassicalValT']:
+ def on_classical_vals(self, **kwargs) -> dict[str, 'ClassicalValT']:
x, phase_grad = kwargs['x'], kwargs['phase_grad']
if self.controlled_by is not None:
ctrl = kwargs['ctrl']
@@ -338,8 +339,8 @@ def adjoint(self) -> 'AddIntoPhaseGrad':
return attrs.evolve(self, sign=-self.sign)
def my_tensors(
- self, incoming: Dict[str, 'ConnectionT'], outgoing: Dict[str, 'ConnectionT']
- ) -> List['qtn.Tensor']:
+ self, incoming: dict[str, 'ConnectionT'], outgoing: dict[str, 'ConnectionT']
+ ) -> list['qtn.Tensor']:
from qualtran.cirq_interop._cirq_to_bloq import _my_tensors_from_gate
return _my_tensors_from_gate(self, self.signature, incoming=incoming, outgoing=outgoing)
@@ -507,13 +508,13 @@ def decompose_from_registers(
def apply(
self, x: int, phase_grad: int
- ) -> Tuple[
+ ) -> tuple[
Union[int, np.integer, NDArray[np.integer]], Union[int, np.integer, NDArray[np.integer]]
]:
out = self.on_classical_vals(x=x, phase_grad=phase_grad)
return out['x'], out['phase_grad']
- def on_classical_vals(self, x: int, phase_grad: int) -> Dict[str, 'ClassicalValT']:
+ def on_classical_vals(self, x: int, phase_grad: int) -> dict[str, 'ClassicalValT']:
phase_grad_out = (phase_grad + self.scaled_val(x)) % 2**self.phase_bitsize
return {'x': x, 'phase_grad': phase_grad_out}
diff --git a/qualtran/bloqs/rotations/phasing_via_cost_function.py b/qualtran/bloqs/rotations/phasing_via_cost_function.py
index 7e4204a0dc..59790e957a 100644
--- a/qualtran/bloqs/rotations/phasing_via_cost_function.py
+++ b/qualtran/bloqs/rotations/phasing_via_cost_function.py
@@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from functools import cached_property
-from typing import Dict, TYPE_CHECKING
+from typing import TYPE_CHECKING
import attrs
@@ -85,8 +85,8 @@ def signature(self) -> 'Signature':
registers = [*self.cost_eval_oracle.signature.lefts(), *self.phase_oracle.extra_registers]
return Signature(registers)
- def build_composite_bloq(self, bb: 'BloqBuilder', **soqs: 'SoquetT') -> Dict[str, 'SoquetT']:
- def _extract_soqs(bloq: Bloq) -> Dict[str, 'SoquetT']:
+ def build_composite_bloq(self, bb: 'BloqBuilder', **soqs: 'SoquetT') -> dict[str, 'SoquetT']:
+ def _extract_soqs(bloq: Bloq) -> dict[str, 'SoquetT']:
return {reg.name: soqs.pop(reg.name) for reg in bloq.signature.lefts()}
soqs |= bb.add_d(self.cost_eval_oracle, **_extract_soqs(self.cost_eval_oracle))
diff --git a/qualtran/bloqs/rotations/phasing_via_cost_function_test.py b/qualtran/bloqs/rotations/phasing_via_cost_function_test.py
index a554f98fa0..0218894b96 100644
--- a/qualtran/bloqs/rotations/phasing_via_cost_function_test.py
+++ b/qualtran/bloqs/rotations/phasing_via_cost_function_test.py
@@ -11,8 +11,6 @@
# 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.
-from typing import Dict
-
import attrs
import cirq
import numpy as np
@@ -80,7 +78,7 @@ def phase_oracle(self) -> QvrInterface:
def cost_eval_oracle(self) -> Bloq:
return HammingWeightCompute(self.bitsize)
- def build_composite_bloq(self, bb: 'BloqBuilder', **soqs: 'SoquetT') -> Dict[str, 'SoquetT']:
+ def build_composite_bloq(self, bb: 'BloqBuilder', **soqs: 'SoquetT') -> dict[str, 'SoquetT']:
if self.use_phase_gradient:
soqs['phase_grad'] = bb.add(PhaseGradientState(int(self.phase_gradient_oracle.b_grad)))
soqs = bb.add_d(PhasingViaCostFunction(self.cost_eval_oracle, self.phase_oracle), **soqs)
@@ -157,7 +155,7 @@ def phase_oracle(self) -> QvrInterface:
def cost_eval_oracle(self) -> Bloq:
return Square(self.bitsize)
- def build_composite_bloq(self, bb: 'BloqBuilder', **soqs: 'SoquetT') -> Dict[str, 'SoquetT']:
+ def build_composite_bloq(self, bb: 'BloqBuilder', **soqs: 'SoquetT') -> dict[str, 'SoquetT']:
if self.use_phase_gradient:
soqs['phase_grad'] = bb.add(PhaseGradientState(int(self.phase_gradient_oracle.b_grad)))
soqs = bb.add_d(PhasingViaCostFunction(self.cost_eval_oracle, self.phase_oracle), **soqs)
diff --git a/qualtran/bloqs/rotations/programmable_rotation_gate_array.py b/qualtran/bloqs/rotations/programmable_rotation_gate_array.py
index c7c8967938..5d86efbe5c 100644
--- a/qualtran/bloqs/rotations/programmable_rotation_gate_array.py
+++ b/qualtran/bloqs/rotations/programmable_rotation_gate_array.py
@@ -13,8 +13,8 @@
# limitations under the License.
import abc
+from collections.abc import Iterator, Sequence
from functools import cached_property
-from typing import Iterator, Sequence, Tuple
import cirq
import numpy as np
@@ -95,7 +95,7 @@ def kappa(self) -> int:
return self._kappa
@property
- def angles(self) -> Tuple[Tuple[int, ...], ...]:
+ def angles(self) -> tuple[tuple[int, ...], ...]:
return self._angles
@cached_method
@@ -111,20 +111,20 @@ def interleaved_unitary(
pass
@cached_property
- def selection_registers(self) -> Tuple[Register, ...]:
+ def selection_registers(self) -> tuple[Register, ...]:
return (Register('selection', BQUInt(self._selection_bitsize, len(self.angles[0]))),)
@cached_property
- def kappa_load_target(self) -> Tuple[Register, ...]:
+ def kappa_load_target(self) -> tuple[Register, ...]:
return (Register('kappa_load_target', QAny(self.kappa)),)
@cached_property
- def rotations_target(self) -> Tuple[Register, ...]:
+ def rotations_target(self) -> tuple[Register, ...]:
return (Register('rotations_target', QAny(self._target_bitsize)),)
@property
@abc.abstractmethod
- def interleaved_unitary_target(self) -> Tuple[Register, ...]:
+ def interleaved_unitary_target(self) -> tuple[Register, ...]:
pass
@cached_property
@@ -212,7 +212,7 @@ def interleaved_unitary(self, index: int, **qubit_regs: NDArray[cirq.Qid]) -> ci
return self._interleaved_unitaries[index].on(*qubit_regs['rotations_target'])
@cached_property
- def interleaved_unitary_target(self) -> Tuple[Register, ...]:
+ def interleaved_unitary_target(self) -> tuple[Register, ...]:
return ()
diff --git a/qualtran/bloqs/rotations/programmable_rotation_gate_array_test.py b/qualtran/bloqs/rotations/programmable_rotation_gate_array_test.py
index f3486cab51..1063112cf6 100644
--- a/qualtran/bloqs/rotations/programmable_rotation_gate_array_test.py
+++ b/qualtran/bloqs/rotations/programmable_rotation_gate_array_test.py
@@ -12,8 +12,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+from collections.abc import Iterator
from functools import cached_property
-from typing import Iterator, Tuple
import cirq
import numpy as np
@@ -41,7 +41,7 @@ def interleaved_unitary(
return two_qubit_ops_factory[index % 2]
@cached_property
- def interleaved_unitary_target(self) -> Tuple[Register, ...]:
+ def interleaved_unitary_target(self) -> tuple[Register, ...]:
return tuple(Signature.build(unrelated_target=1))
diff --git a/qualtran/bloqs/rotations/quantum_variable_rotation.py b/qualtran/bloqs/rotations/quantum_variable_rotation.py
index 8177ea80e8..26630f7f09 100644
--- a/qualtran/bloqs/rotations/quantum_variable_rotation.py
+++ b/qualtran/bloqs/rotations/quantum_variable_rotation.py
@@ -55,8 +55,9 @@
"""
import abc
+from collections.abc import Sequence
from functools import cached_property
-from typing import cast, Dict, Sequence, TYPE_CHECKING
+from typing import cast, TYPE_CHECKING
import attrs
import numpy as np
@@ -177,7 +178,7 @@ def num_frac_rotations(self) -> SymbolicInt:
def num_rotations(self) -> SymbolicInt:
return self.cost_dtype.num_int + self.num_frac_rotations + int(self.cost_dtype.signed)
- def build_composite_bloq(self, bb: 'BloqBuilder', **soqs: 'SoquetT') -> Dict[str, 'SoquetT']:
+ def build_composite_bloq(self, bb: 'BloqBuilder', **soqs: 'SoquetT') -> dict[str, 'SoquetT']:
if isinstance(self.cost_dtype.bitsize, sympy.Expr):
raise ValueError(f'Unsupported symbolic {self.cost_dtype.bitsize} bitsize')
out = cast(Soquet, soqs[self.cost_reg.name])
@@ -470,7 +471,7 @@ def gamma_dtype(self) -> QFxp:
n_frac = self.cost_dtype.num_int + self.b_phase
return QFxp(bitsize=n_int + n_frac, num_frac=n_frac, signed=False)
- def build_composite_bloq(self, bb: 'BloqBuilder', **soqs: 'SoquetT') -> Dict[str, 'SoquetT']:
+ def build_composite_bloq(self, bb: 'BloqBuilder', **soqs: 'SoquetT') -> dict[str, 'SoquetT']:
add_scaled_val = AddScaledValIntoPhaseReg(
self.cost_dtype, self.b_grad, self.gamma, self.gamma_dtype
)
diff --git a/qualtran/bloqs/rotations/quantum_variable_rotation_test.py b/qualtran/bloqs/rotations/quantum_variable_rotation_test.py
index 864b904866..81c4137cf4 100644
--- a/qualtran/bloqs/rotations/quantum_variable_rotation_test.py
+++ b/qualtran/bloqs/rotations/quantum_variable_rotation_test.py
@@ -11,7 +11,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.
-from typing import Iterator
+from collections.abc import Iterator
import attrs
import cirq
diff --git a/qualtran/bloqs/state_preparation/black_box_prepare.py b/qualtran/bloqs/state_preparation/black_box_prepare.py
index 42aacba78e..91f24d1439 100644
--- a/qualtran/bloqs/state_preparation/black_box_prepare.py
+++ b/qualtran/bloqs/state_preparation/black_box_prepare.py
@@ -13,7 +13,6 @@
# limitations under the License.
from functools import cached_property
-from typing import Dict, Tuple
from attr import frozen
@@ -51,11 +50,11 @@ class BlackBoxPrepare(Bloq):
prepare: PrepareOracle
@cached_property
- def selection_registers(self) -> Tuple[Register, ...]:
+ def selection_registers(self) -> tuple[Register, ...]:
return (Register(name='selection', dtype=QAny(self.selection_bitsize)),)
@cached_property
- def junk_registers(self) -> Tuple[Register, ...]:
+ def junk_registers(self) -> tuple[Register, ...]:
return (Register(name='junk', dtype=QAny(self.junk_bitsize)),)
@cached_property
@@ -74,7 +73,7 @@ def l1_norm_of_coeffs(self) -> SymbolicFloat:
def signature(self) -> Signature:
return Signature.build(selection=self.selection_bitsize, junk=self.junk_bitsize)
- def build_composite_bloq(self, bb: BloqBuilder, **soqs: SoquetT) -> Dict[str, SoquetT]:
+ def build_composite_bloq(self, bb: BloqBuilder, **soqs: SoquetT) -> dict[str, SoquetT]:
if self.selection_bitsize == 0:
return soqs
partitions = [
diff --git a/qualtran/bloqs/state_preparation/black_box_prepare_test.py b/qualtran/bloqs/state_preparation/black_box_prepare_test.py
index 8dc0acab59..30a7fafbc6 100644
--- a/qualtran/bloqs/state_preparation/black_box_prepare_test.py
+++ b/qualtran/bloqs/state_preparation/black_box_prepare_test.py
@@ -12,8 +12,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-from typing import Tuple
-
from attr import frozen
from qualtran import QAny, QBit, Register
@@ -28,11 +26,11 @@ def test_black_box_prepare(bloq_autotester):
@frozen
class TestPrepareOracle(PrepareOracle):
@property
- def selection_registers(self) -> Tuple[Register, ...]:
+ def selection_registers(self) -> tuple[Register, ...]:
return (Register('z', QBit()),)
@property
- def junk_registers(self) -> Tuple[Register, ...]:
+ def junk_registers(self) -> tuple[Register, ...]:
return (Register('a', QAny(5)),)
diff --git a/qualtran/bloqs/state_preparation/prepare_base.py b/qualtran/bloqs/state_preparation/prepare_base.py
index 6870d7752a..df60aa562d 100644
--- a/qualtran/bloqs/state_preparation/prepare_base.py
+++ b/qualtran/bloqs/state_preparation/prepare_base.py
@@ -14,7 +14,6 @@
import abc
from functools import cached_property
-from typing import Tuple
from qualtran import BloqDocSpec, GateWithRegisters, Register, Signature
from qualtran.symbolics import SymbolicFloat
@@ -38,10 +37,10 @@ class PrepareOracle(GateWithRegisters):
@property
@abc.abstractmethod
- def selection_registers(self) -> Tuple[Register, ...]: ...
+ def selection_registers(self) -> tuple[Register, ...]: ...
@cached_property
- def junk_registers(self) -> Tuple[Register, ...]:
+ def junk_registers(self) -> tuple[Register, ...]:
return ()
@cached_property
diff --git a/qualtran/bloqs/state_preparation/prepare_uniform_superposition.py b/qualtran/bloqs/state_preparation/prepare_uniform_superposition.py
index c3a7002bc7..16988eaa59 100644
--- a/qualtran/bloqs/state_preparation/prepare_uniform_superposition.py
+++ b/qualtran/bloqs/state_preparation/prepare_uniform_superposition.py
@@ -12,8 +12,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+from collections.abc import Iterator
from functools import cached_property
-from typing import cast, Iterator, Optional, Set, Tuple, TYPE_CHECKING, Union
+from typing import cast, Optional, TYPE_CHECKING, Union
import attrs
import cirq
@@ -64,7 +65,7 @@ class PrepareUniformSuperposition(GateWithRegisters):
"""
n: SymbolicInt
- cvs: Union[HasLength, Tuple[SymbolicInt, ...]] = attrs.field(
+ cvs: Union[HasLength, tuple[SymbolicInt, ...]] = attrs.field(
converter=_to_tuple_or_has_length, default=()
)
@@ -73,17 +74,17 @@ def signature(self) -> Signature:
return Signature.build(ctrl=slen(self.cvs), target=bit_length(self.n - 1))
def wire_symbol(
- self, reg: Optional['Register'], idx: Tuple[int, ...] = tuple()
+ self, reg: Optional['Register'], idx: tuple[int, ...] = tuple()
) -> 'WireSymbol':
if reg is None:
return Text('Σ |l>')
return super().wire_symbol(reg, idx)
@property
- def concrete_cvs(self) -> Tuple[int, ...]:
+ def concrete_cvs(self) -> tuple[int, ...]:
if isinstance(self.cvs, HasLength):
raise ValueError(f"{self.cvs} is symbolic")
- return cast(Tuple[int, ...], self.cvs)
+ return cast(tuple[int, ...], self.cvs)
def _circuit_diagram_info_(self, args: cirq.CircuitDiagramInfoArgs) -> cirq.CircuitDiagramInfo:
control_symbols = ["@" if cv else "@(0)" for cv in self.concrete_cvs]
@@ -91,7 +92,7 @@ def _circuit_diagram_info_(self, args: cirq.CircuitDiagramInfoArgs) -> cirq.Circ
target_symbols[0] = f"UNIFORM({self.n})"
return cirq.CircuitDiagramInfo(wire_symbols=control_symbols + target_symbols)
- def k_l_logL(self) -> Tuple[SymbolicInt, SymbolicInt, SymbolicInt]:
+ def k_l_logL(self) -> tuple[SymbolicInt, SymbolicInt, SymbolicInt]:
# Find K and L as per https://arxiv.org/abs/1805.03662 Fig 12.
k, n, logL = 0, self.n, bit_length(self.n - 1)
if is_symbolic(n):
@@ -150,7 +151,7 @@ def decompose_from_registers(
def build_call_graph(
self, ssa: 'SympySymbolAllocator'
- ) -> Union['BloqCountDictT', Set['BloqCountT']]:
+ ) -> Union['BloqCountDictT', set['BloqCountT']]:
if not is_symbolic(self.n, self.cvs):
# build from decomposition
return super().build_call_graph(ssa)
diff --git a/qualtran/bloqs/state_preparation/sparse_state_preparation_via_rotations.py b/qualtran/bloqs/state_preparation/sparse_state_preparation_via_rotations.py
index e5d631263c..2cfa0d52bd 100644
--- a/qualtran/bloqs/state_preparation/sparse_state_preparation_via_rotations.py
+++ b/qualtran/bloqs/state_preparation/sparse_state_preparation_via_rotations.py
@@ -11,7 +11,8 @@
# 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.
-from typing import Sequence, TYPE_CHECKING, Union
+from collections.abc import Sequence
+from typing import TYPE_CHECKING, Union
import attrs
import numpy as np
diff --git a/qualtran/bloqs/state_preparation/state_preparation_alias_sampling.py b/qualtran/bloqs/state_preparation/state_preparation_alias_sampling.py
index 4850ef95d9..39bc98353f 100644
--- a/qualtran/bloqs/state_preparation/state_preparation_alias_sampling.py
+++ b/qualtran/bloqs/state_preparation/state_preparation_alias_sampling.py
@@ -19,8 +19,9 @@
database) with a number of T gates scaling as 4L + O(log(1/eps)) where eps is the
largest absolute error that one can tolerate in the prepared amplitudes.
"""
+from collections.abc import Sequence
from functools import cached_property
-from typing import Sequence, Tuple, TYPE_CHECKING, Union
+from typing import TYPE_CHECKING, Union
import attrs
import numpy as np
@@ -51,7 +52,7 @@
from qualtran.resource_counting import BloqCountDictT, SympySymbolAllocator
-def _data_or_shape_to_tuple(data_or_shape: Union[NDArray, Shaped]) -> Tuple:
+def _data_or_shape_to_tuple(data_or_shape: Union[NDArray, Shaped]) -> tuple:
return (
tuple(data_or_shape.flatten())
if isinstance(data_or_shape, np.ndarray)
@@ -113,7 +114,7 @@ class StatePreparationAliasSampling(PrepareOracle):
Babbush et al. (2018). Section III.D. and Figure 11.
"""
- selection_registers: Tuple[Register, ...] = attrs.field(
+ selection_registers: tuple[Register, ...] = attrs.field(
converter=lambda v: (v,) if isinstance(v, Register) else tuple(v)
)
alt: Union[Shaped, NDArray[np.int_]] = attrs.field(eq=_data_or_shape_to_tuple)
@@ -223,7 +224,7 @@ def selection_bitsize(self) -> SymbolicInt:
return total_bits(self.selection_registers)
@cached_property
- def junk_registers(self) -> Tuple[Register, ...]:
+ def junk_registers(self) -> tuple[Register, ...]:
return tuple(
Signature.build(
sigma_mu=self.sigma_mu_bitsize,
@@ -355,7 +356,7 @@ class SparseStatePreparationAliasSampling(PrepareOracle):
Babbush et al. (2018). Section III.D. and Figure 11.
"""
- selection_registers: Tuple[Register, ...] = attrs.field(
+ selection_registers: tuple[Register, ...] = attrs.field(
converter=lambda v: (v,) if isinstance(v, Register) else tuple(v)
)
index: Union[Shaped, NDArray[np.int_]] = attrs.field(eq=_data_or_shape_to_tuple)
@@ -369,7 +370,7 @@ def __attrs_post_init__(self):
raise ValueError(f"{self.mu=} must be at least 1")
@cached_property
- def junk_registers(self) -> Tuple[Register, ...]:
+ def junk_registers(self) -> tuple[Register, ...]:
return tuple(
Signature.build(
sigma_mu=self.mu,
diff --git a/qualtran/bloqs/state_preparation/state_preparation_via_rotation.py b/qualtran/bloqs/state_preparation/state_preparation_via_rotation.py
index 2466a11c33..f27cd68b0f 100644
--- a/qualtran/bloqs/state_preparation/state_preparation_via_rotation.py
+++ b/qualtran/bloqs/state_preparation/state_preparation_via_rotation.py
@@ -74,7 +74,8 @@
"""
from collections import Counter
-from typing import cast, Dict, Iterable, List, Tuple, TYPE_CHECKING, Union
+from collections.abc import Iterable
+from typing import cast, TYPE_CHECKING, Union
import attrs
import numpy as np
@@ -104,7 +105,7 @@
def _to_tuple_or_has_length(
x: Union[HasLength, Iterable[complex]]
-) -> Union[HasLength, Tuple[complex, ...]]:
+) -> Union[HasLength, tuple[complex, ...]]:
if isinstance(x, HasLength):
return x
return tuple(x)
@@ -134,7 +135,7 @@ class StatePreparationViaRotations(GateWithRegisters):
Low, Kliuchnikov, Schaeffer. 2018.
"""
- state_coefficients: Union[HasLength, Tuple[complex, ...]] = attrs.field(
+ state_coefficients: Union[HasLength, tuple[complex, ...]] = attrs.field(
converter=_to_tuple_or_has_length
)
phase_bitsize: SymbolicInt
@@ -176,7 +177,7 @@ def rotation_tree(self) -> 'RotationTree':
return RotationTree(np.asarray(self.state_coefficients), self.phase_bitsize, self.uncompute)
@property
- def prga_prepare_amplitude(self) -> List['PRGAViaPhaseGradient']:
+ def prga_prepare_amplitude(self) -> list['PRGAViaPhaseGradient']:
if is_symbolic(self.state_coefficients, self.phase_bitsize):
return [
PRGAViaPhaseGradient(
@@ -200,7 +201,7 @@ def prga_prepare_amplitude(self) -> List['PRGAViaPhaseGradient']:
@property
def prga_prepare_phases(self) -> 'PRGAViaPhaseGradient':
- data_or_shape: Union[Shaped, Tuple[int, ...]] = (
+ data_or_shape: Union[Shaped, tuple[int, ...]] = (
Shaped((slen(self.state_coefficients),))
if is_symbolic(self.state_coefficients) or is_symbolic(self.phase_bitsize)
else tuple(self.rotation_tree.get_rom_vals()[1])
@@ -212,7 +213,7 @@ def prga_prepare_phases(self) -> 'PRGAViaPhaseGradient':
control_bitsize=self.control_bitsize + 1,
)
- def build_composite_bloq(self, bb: BloqBuilder, **soqs: SoquetT) -> Dict[str, SoquetT]:
+ def build_composite_bloq(self, bb: BloqBuilder, **soqs: SoquetT) -> dict[str, SoquetT]:
r"""Parameters:
* prepare_control: only if control_bitsize != 0
* target_state: register where the state is written
@@ -239,7 +240,7 @@ def build_call_graph(self, ssa: 'SympySymbolAllocator') -> 'BloqCountDictT':
ret[bloq] += 1
return ret
- def _prepare_amplitudes(self, bb: BloqBuilder, **soqs: SoquetT) -> Dict[str, SoquetT]:
+ def _prepare_amplitudes(self, bb: BloqBuilder, **soqs: SoquetT) -> dict[str, SoquetT]:
r"""Parameters into soqs:
* prepare_control: only if control_bitsize != 0
* target_state: register where the state is written
@@ -279,7 +280,7 @@ def _prepare_amplitudes(self, bb: BloqBuilder, **soqs: SoquetT) -> Dict[str, Soq
soqs["target_state"] = bb.join(state_qubits)
return soqs
- def _prepare_phases(self, bb: BloqBuilder, **soqs: SoquetT) -> Dict[str, SoquetT]:
+ def _prepare_phases(self, bb: BloqBuilder, **soqs: SoquetT) -> dict[str, SoquetT]:
"""Encodes the phase of each coefficient.
Takes into account both the phase of the original coefficient and offsets caused by the
@@ -410,7 +411,7 @@ class PRGAViaPhaseGradient(Bloq):
selection_bitsize: SymbolicInt
phase_bitsize: SymbolicInt
- rom_values: Union[Shaped, Tuple[int, ...]]
+ rom_values: Union[Shaped, tuple[int, ...]]
control_bitsize: SymbolicInt
@property
@@ -434,7 +435,7 @@ def qrom_bloq(self) -> QROM:
def add_into_phase_grad(self) -> AddIntoPhaseGrad:
return AddIntoPhaseGrad(self.phase_bitsize, self.phase_bitsize)
- def build_composite_bloq(self, bb: BloqBuilder, **soqs: SoquetT) -> Dict[str, SoquetT]:
+ def build_composite_bloq(self, bb: BloqBuilder, **soqs: SoquetT) -> dict[str, SoquetT]:
"""Parameters:
* control
* selection (not necessary if selection_bitsize == 0)
@@ -490,7 +491,7 @@ def __init__(self, state: NDArray, phase_bitsize: int, uncompute: bool = False):
self._calc_amplitude_angles_and_rv(state, phase_bitsize, uncompute)
self._calc_phase_rom_values(state, phase_bitsize, uncompute)
- def get_rom_vals(self) -> Tuple[List[List[int]], List[int]]:
+ def get_rom_vals(self) -> tuple[list[list[int]], list[int]]:
return self.amplitude_rom_values, self.phase_rom_values
def _calc_amplitude_angles_and_rv(
@@ -507,9 +508,9 @@ def _calc_amplitude_angles_and_rv(
self.sum_total[i + slen] = abs(state[i]) ** 2
for i in range(slen - 1, 0, -1):
self.sum_total[i] = self.sum_total[i << 1] + self.sum_total[(i << 1) | 1]
- self.amplitude_rom_values: List[List[int]] = []
+ self.amplitude_rom_values: list[list[int]] = []
for i in range(self.state_bitsize):
- rom_vals_this_layer: List[int] = []
+ rom_vals_this_layer: list[int] = []
for node in range(1 << i, 1 << (i + 1)):
angle = self._angle_0(node)
if uncompute:
@@ -536,7 +537,7 @@ def _calc_phase_rom_values(self, state: NDArray, phase_bitsize: int, uncompute:
angles = np.array([np.angle(c) for c in state])
# flip angle if uncompute
angles = [(1 - 2 * uncompute) * (a - o) for a, o in zip(angles, offsets)]
- self.phase_rom_values: List[int] = [
+ self.phase_rom_values: list[int] = [
RotationTree._angle_to_rom_value(a, phase_bitsize) for a in angles
]
diff --git a/qualtran/bloqs/state_preparation/state_preparation_via_rotation_test.py b/qualtran/bloqs/state_preparation/state_preparation_via_rotation_test.py
index 6b7a770579..fe8147f6e9 100644
--- a/qualtran/bloqs/state_preparation/state_preparation_via_rotation_test.py
+++ b/qualtran/bloqs/state_preparation/state_preparation_via_rotation_test.py
@@ -11,8 +11,6 @@
# 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.
-from typing import Tuple
-
import cirq
import numpy as np
import pytest
@@ -119,7 +117,7 @@ def test_state_prep_via_rotation_symb():
],
],
)
-def test_exact_state_prep_via_rotation_(phase_bitsize: int, state_coefs: Tuple[complex, ...]):
+def test_exact_state_prep_via_rotation_(phase_bitsize: int, state_coefs: tuple[complex, ...]):
# https://github.com/python/mypy/issues/5313
qsp = StatePreparationViaRotations(
phase_bitsize=phase_bitsize, state_coefficients=state_coefs # type: ignore[arg-type]
@@ -157,7 +155,7 @@ def test_exact_state_prep_via_rotation_(phase_bitsize: int, state_coefs: Tuple[c
],
)
def test_state_prep_via_rotation_adjoint(
- phase_bitsize: int, state_coefs: Tuple[complex, ...]
+ phase_bitsize: int, state_coefs: tuple[complex, ...]
) -> None:
# https://github.com/python/mypy/issues/5313
qsp = StatePreparationViaRotations(
@@ -201,7 +199,7 @@ def test_state_prep_via_rotation_adjoint(
],
],
)
-def test_approximate_state_prep_via_rotation(phase_bitsize: int, state_coefs: Tuple[complex, ...]):
+def test_approximate_state_prep_via_rotation(phase_bitsize: int, state_coefs: tuple[complex, ...]):
qsp = StatePreparationViaRotations(
phase_bitsize=phase_bitsize, state_coefficients=state_coefs # type: ignore[arg-type]
)
@@ -231,7 +229,7 @@ def test_approximate_state_prep_via_rotation(phase_bitsize: int, state_coefs: Tu
],
)
def test_controlled_state_preparation_via_rotation_do_not_prepare(
- phase_bitsize: int, state_coefs: Tuple[complex, ...]
+ phase_bitsize: int, state_coefs: tuple[complex, ...]
):
qsp = StatePreparationViaRotations(
phase_bitsize=phase_bitsize, state_coefficients=state_coefs, control_bitsize=1 # type: ignore[arg-type]
@@ -255,7 +253,7 @@ def test_controlled_state_preparation_via_rotation_do_not_prepare(
@pytest.mark.parametrize("phase_bitsize, state_coefs", [[2, ((-0.5 - 0.5j), 0, 0.5, -0.5)]])
def test_state_preparation_via_rotation_superposition_ctrl(
- phase_bitsize: int, state_coefs: Tuple[complex, ...]
+ phase_bitsize: int, state_coefs: tuple[complex, ...]
):
qsp = StatePreparationViaRotations(
phase_bitsize=phase_bitsize, state_coefficients=state_coefs, control_bitsize=1 # type: ignore[arg-type]
@@ -282,7 +280,7 @@ def test_state_preparation_via_rotation_superposition_ctrl(
@pytest.mark.parametrize("phase_bitsize, state_coefs", [[2, ((-0.5 - 0.5j), 0, 0.5, -0.5)]])
def test_state_preparation_via_rotation_multi_qubit_ctrl(
- phase_bitsize: int, state_coefs: Tuple[complex, ...]
+ phase_bitsize: int, state_coefs: tuple[complex, ...]
):
qsp = StatePreparationViaRotations(
phase_bitsize=phase_bitsize, state_coefficients=state_coefs, control_bitsize=2 # type: ignore[arg-type]
diff --git a/qualtran/bloqs/swap_network/cswap_approx.py b/qualtran/bloqs/swap_network/cswap_approx.py
index 0629511b30..70899de751 100644
--- a/qualtran/bloqs/swap_network/cswap_approx.py
+++ b/qualtran/bloqs/swap_network/cswap_approx.py
@@ -12,8 +12,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+from collections.abc import Iterator
from functools import cached_property
-from typing import Dict, Iterator, Optional, Tuple, TYPE_CHECKING
+from typing import Optional, TYPE_CHECKING
import cirq
import sympy
@@ -88,14 +89,14 @@ def g(q: cirq.Qid, adjoint=False) -> cirq.ops.op_tree.OpTree:
def on_classical_vals(
self, ctrl: 'ClassicalValT', x: 'ClassicalValT', y: 'ClassicalValT'
- ) -> Dict[str, 'ClassicalValT']:
+ ) -> dict[str, 'ClassicalValT']:
if ctrl == 0:
return {'ctrl': 0, 'x': x, 'y': y}
if ctrl == 1:
return {'ctrl': 1, 'x': y, 'y': x}
raise ValueError("Bad control value for CSwap classical simulation.")
- def wire_symbol(self, reg: Optional[Register], idx: Tuple[int, ...] = tuple()) -> 'WireSymbol':
+ def wire_symbol(self, reg: Optional[Register], idx: tuple[int, ...] = tuple()) -> 'WireSymbol':
if reg is None:
return Text('~swap')
return super().wire_symbol(reg, idx)
diff --git a/qualtran/bloqs/swap_network/cswap_approx_test.py b/qualtran/bloqs/swap_network/cswap_approx_test.py
index 665e1cb122..e70ddfe811 100644
--- a/qualtran/bloqs/swap_network/cswap_approx_test.py
+++ b/qualtran/bloqs/swap_network/cswap_approx_test.py
@@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import random
-from typing import Dict, Tuple, Union
+from typing import Union
import cirq
import numpy as np
@@ -59,8 +59,8 @@ def test_approx_cswap_t_count(n):
def get_t_count_and_clifford(
- bc: Dict[Bloq, Union[int, sympy.Expr]]
-) -> Tuple[Union[int, sympy.Expr], Union[int, sympy.Expr]]:
+ bc: dict[Bloq, Union[int, sympy.Expr]]
+) -> tuple[Union[int, sympy.Expr], Union[int, sympy.Expr]]:
"""Get the t count and clifford cost from bloq count."""
cliff_cost = sum([v for k, v in bc.items() if isinstance(k, ArbitraryClifford)])
t_cost = sum([v for k, v in bc.items() if isinstance(k, TGate)])
diff --git a/qualtran/bloqs/swap_network/multiplexed_cswap.py b/qualtran/bloqs/swap_network/multiplexed_cswap.py
index d41e2bb20c..c927e89275 100644
--- a/qualtran/bloqs/swap_network/multiplexed_cswap.py
+++ b/qualtran/bloqs/swap_network/multiplexed_cswap.py
@@ -13,7 +13,6 @@
# limitations under the License.
from functools import cached_property
-from typing import Tuple
import cirq
from attrs import field, frozen
@@ -41,14 +40,14 @@ class MultiplexedCSwap(UnaryIterationGate):
the registers to swap, and $n_c$ is the number of controls.
Args:
- selection_regs: Indexing `select` signature of type Tuple[`Register`, ...].
+ selection_regs: Indexing `select` signature of type tuple[`Register`, ...].
It also contains information about the iteration length of each selection register.
target_bitsize: The size of the registers we want to swap.
control_regs: Control registers for constructing a controlled version of the gate.
Registers:
control_registers: Control registers
- selection_regs: Indexing `select` signature of type Tuple[`Register`, ...].
+ selection_regs: Indexing `select` signature of type tuple[`Register`, ...].
It also contains information about the iteration length of each selection register.
target_registers: Target registers to swap. We swap FROM registers
labelled x`i`, where i is an integer and TO a single register called y
@@ -58,24 +57,24 @@ class MultiplexedCSwap(UnaryIterationGate):
page 20 paragraph 2.
"""
- selection_regs: Tuple[Register, ...] = field(
+ selection_regs: tuple[Register, ...] = field(
converter=lambda v: (v,) if isinstance(v, Register) else tuple(v)
)
target_bitsize: int
- control_regs: Tuple[Register, ...] = field(
+ control_regs: tuple[Register, ...] = field(
converter=lambda v: (v,) if isinstance(v, Register) else tuple(v), default=()
)
@cached_property
- def control_registers(self) -> Tuple[Register, ...]:
+ def control_registers(self) -> tuple[Register, ...]:
return self.control_regs
@cached_property
- def selection_registers(self) -> Tuple[Register, ...]:
+ def selection_registers(self) -> tuple[Register, ...]:
return self.selection_regs
@cached_property
- def target_registers(self) -> Tuple[Register, ...]:
+ def target_registers(self) -> tuple[Register, ...]:
target_shape = tuple(
sreg.dtype.iteration_length_or_zero() for sreg in self.selection_registers
)
diff --git a/qualtran/bloqs/swap_network/swap_network.ipynb b/qualtran/bloqs/swap_network/swap_network.ipynb
index 13d0a58fb5..f8a9e86028 100644
--- a/qualtran/bloqs/swap_network/swap_network.ipynb
+++ b/qualtran/bloqs/swap_network/swap_network.ipynb
@@ -323,13 +323,13 @@
"the registers to swap, and $n_c$ is the number of controls.\n",
"\n",
"#### Parameters\n",
- " - `selection_regs`: Indexing `select` signature of type Tuple[`Register`, ...]. It also contains information about the iteration length of each selection register.\n",
+ " - `selection_regs`: Indexing `select` signature of type tuple[`Register`, ...]. It also contains information about the iteration length of each selection register.\n",
" - `target_bitsize`: The size of the registers we want to swap.\n",
" - `control_regs`: Control registers for constructing a controlled version of the gate. \n",
"\n",
"#### Registers\n",
" - `control_registers`: Control registers\n",
- " - `selection_regs`: Indexing `select` signature of type Tuple[`Register`, ...]. It also contains information about the iteration length of each selection register.\n",
+ " - `selection_regs`: Indexing `select` signature of type tuple[`Register`, ...]. It also contains information about the iteration length of each selection register.\n",
" - `target_registers`: Target registers to swap. We swap FROM registers labelled x`i`, where i is an integer and TO a single register called y \n",
"\n",
"#### References\n",
diff --git a/qualtran/bloqs/swap_network/swap_with_zero.py b/qualtran/bloqs/swap_network/swap_with_zero.py
index 756704c796..4d066c1aa6 100644
--- a/qualtran/bloqs/swap_network/swap_with_zero.py
+++ b/qualtran/bloqs/swap_network/swap_with_zero.py
@@ -12,8 +12,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+from collections.abc import Iterable, Iterator
from functools import cached_property
-from typing import cast, Dict, Iterable, Iterator, Tuple, TYPE_CHECKING, Union
+from typing import cast, TYPE_CHECKING, Union
import attrs
import cirq
@@ -42,7 +43,7 @@
from qualtran.simulation.classical_sim import ClassicalValT
-def _to_tuple(x: Union[SymbolicInt, Iterable[SymbolicInt]]) -> Tuple[SymbolicInt, ...]:
+def _to_tuple(x: Union[SymbolicInt, Iterable[SymbolicInt]]) -> tuple[SymbolicInt, ...]:
if isinstance(x, np.ndarray):
return _to_tuple(x.tolist())
if isinstance(x, Iterable):
@@ -51,8 +52,8 @@ def _to_tuple(x: Union[SymbolicInt, Iterable[SymbolicInt]]) -> Tuple[SymbolicInt
def _swap_with_zero_swap_sequence(
- selection_bitsizes: Tuple[int, ...], target_shape: Tuple[int, ...], idx: Tuple[int, ...] = ()
-) -> Iterator[Tuple[int, int, Tuple[int, ...], Tuple[int, ...]]]:
+ selection_bitsizes: tuple[int, ...], target_shape: tuple[int, ...], idx: tuple[int, ...] = ()
+) -> Iterator[tuple[int, int, tuple[int, ...], tuple[int, ...]]]:
"""Yields tuples of indices that should be swapped in that order to realize a swap with zero.
The method recursively iterates over all combinations of `S = np.prod(selection_bitsizes)`
@@ -124,16 +125,16 @@ class SwapWithZero(GateWithRegisters):
Low, Kliuchnikov, Schaeffer. 2018.
"""
- selection_bitsizes: Tuple[SymbolicInt, ...] = attrs.field(converter=_to_tuple)
+ selection_bitsizes: tuple[SymbolicInt, ...] = attrs.field(converter=_to_tuple)
target_bitsize: SymbolicInt
- n_target_registers: Tuple[SymbolicInt, ...] = attrs.field(converter=_to_tuple)
+ n_target_registers: tuple[SymbolicInt, ...] = attrs.field(converter=_to_tuple)
uncompute: bool = False
def __attrs_post_init__(self):
assert len(self.n_target_registers) == len(self.selection_bitsizes)
@cached_property
- def selection_registers(self) -> Tuple[Register, ...]:
+ def selection_registers(self) -> tuple[Register, ...]:
types = [
BQUInt(sb, l)
for sb, l in zip(self.selection_bitsizes, self.n_target_registers)
@@ -144,7 +145,7 @@ def selection_registers(self) -> Tuple[Register, ...]:
return tuple(Register(f'selection{i}_', qdtype) for i, qdtype in enumerate(types))
@cached_property
- def target_registers(self) -> Tuple[Register, ...]:
+ def target_registers(self) -> tuple[Register, ...]:
return (
Register('targets', QAny(bitsize=self.target_bitsize), shape=self.n_target_registers),
)
@@ -158,17 +159,17 @@ def cswap_n(self) -> 'CSwapApprox':
return CSwapApprox(self.target_bitsize)
@cached_property
- def _swap_sequence(self) -> Tuple[Tuple[int, int, Tuple[int, ...], Tuple[int, ...]], ...]:
+ def _swap_sequence(self) -> tuple[tuple[int, int, tuple[int, ...], tuple[int, ...]], ...]:
if is_symbolic(*self.selection_bitsizes) or is_symbolic(*self.n_target_registers):
raise ValueError(f"Cannot produce swap sequence for symbolic {self=}")
- selection_bitsizes = cast(Tuple[int, ...], self.selection_bitsizes)
- n_target_registers = cast(Tuple[int, ...], self.n_target_registers)
+ selection_bitsizes = cast(tuple[int, ...], self.selection_bitsizes)
+ n_target_registers = cast(tuple[int, ...], self.n_target_registers)
ret = [*_swap_with_zero_swap_sequence(selection_bitsizes, n_target_registers)]
return tuple(ret[::-1] if self.uncompute else ret)
def build_composite_bloq(
self, bb: 'BloqBuilder', targets: NDArray['Soquet'], **sel: 'Soquet' # type: ignore[type-var]
- ) -> Dict[str, 'SoquetT']:
+ ) -> dict[str, 'SoquetT']:
sel_soqs = [bb.split(sel[reg.name]) for reg in self.selection_registers]
for i, sel_idx_small, idx_one, idx_two in self._swap_sequence:
sel_idx_big = self.selection_bitsizes[i] - sel_idx_small - 1
@@ -189,7 +190,7 @@ def _circuit_diagram_info_(self, args) -> cirq.CircuitDiagramInfo:
return _wire_symbol_to_cirq_diagram_info(self, args)
- def wire_symbol(self, reg: Register, idx: Tuple[int, ...] = tuple()) -> 'WireSymbol':
+ def wire_symbol(self, reg: Register, idx: tuple[int, ...] = tuple()) -> 'WireSymbol':
if reg is None:
return super().wire_symbol(reg, idx)
name = reg.name
@@ -202,7 +203,7 @@ def wire_symbol(self, reg: Register, idx: Tuple[int, ...] = tuple()) -> 'WireSym
def on_classical_vals(
self, *, targets: 'ClassicalValT', **selection: 'ClassicalValT'
- ) -> Dict[str, 'ClassicalValT']:
+ ) -> dict[str, 'ClassicalValT']:
assert isinstance(targets, np.ndarray)
selection_idx = tuple(selection.values())
for i, sel_idx_small, idx_one, idx_two in self._swap_sequence:
diff --git a/qualtran/cirq_interop/_bloq_to_cirq.py b/qualtran/cirq_interop/_bloq_to_cirq.py
index 3a03f65639..cf08268e9c 100644
--- a/qualtran/cirq_interop/_bloq_to_cirq.py
+++ b/qualtran/cirq_interop/_bloq_to_cirq.py
@@ -14,7 +14,8 @@
"""Qualtran Bloqs to Cirq gates/circuits conversion."""
-from typing import Dict, Iterable, List, Optional, Sequence, Tuple
+from collections.abc import Iterable, Sequence
+from typing import Optional
import cirq
import networkx as nx
@@ -95,8 +96,8 @@ def bloq(self) -> Bloq:
@classmethod
def bloq_on(
- cls, bloq: Bloq, cirq_quregs: Dict[str, 'CirqQuregT'], qubit_manager: cirq.QubitManager # type: ignore[type-var]
- ) -> Tuple['cirq.Operation', Dict[str, 'CirqQuregT']]: # type: ignore[type-var]
+ cls, bloq: Bloq, cirq_quregs: dict[str, 'CirqQuregT'], qubit_manager: cirq.QubitManager # type: ignore[type-var]
+ ) -> tuple['cirq.Operation', dict[str, 'CirqQuregT']]: # type: ignore[type-var]
"""Shim `bloq` into a cirq gate and call it on `cirq_quregs`.
This is used as a default implementation for `Bloq.as_cirq_op` if a native
@@ -191,7 +192,7 @@ def __repr__(self) -> str:
return f'BloqAsCirqGate({self.bloq})'
-def _track_soq_name_changes(cxns: Iterable[Connection], qvar_to_qreg: Dict[Soquet, _QReg]):
+def _track_soq_name_changes(cxns: Iterable[Connection], qvar_to_qreg: dict[Soquet, _QReg]):
"""Track inter-Bloq name changes across the two ends of a connection."""
for cxn in cxns:
qvar_to_qreg[cxn.right] = qvar_to_qreg[cxn.left]
@@ -202,11 +203,11 @@ def _bloq_to_cirq_op(
bloq: Bloq,
pred_cxns: Iterable[Connection],
succ_cxns: Iterable[Connection],
- qvar_to_qreg: Dict[Soquet, _QReg],
+ qvar_to_qreg: dict[Soquet, _QReg],
qubit_manager: cirq.QubitManager,
) -> Optional[cirq.Operation]:
_track_soq_name_changes(pred_cxns, qvar_to_qreg)
- in_quregs: Dict[str, CirqQuregT] = {
+ in_quregs: dict[str, CirqQuregT] = {
reg.name: np.empty((*reg.shape, reg.bitsize), dtype=object)
for reg in bloq.signature.lefts()
}
@@ -234,10 +235,10 @@ def _bloq_to_cirq_op(
def _cbloq_to_cirq_circuit(
signature: Signature,
- cirq_quregs: Dict[str, 'CirqQuregInT'],
+ cirq_quregs: dict[str, 'CirqQuregInT'],
binst_graph: nx.DiGraph,
qubit_manager: cirq.QubitManager,
-) -> Tuple[cirq.FrozenCircuit, Dict[str, 'CirqQuregT']]:
+) -> tuple[cirq.FrozenCircuit, dict[str, 'CirqQuregT']]:
"""Propagate `as_cirq_op` calls through a composite bloq's contents to export a `cirq.Circuit`.
Args:
@@ -250,16 +251,16 @@ def _cbloq_to_cirq_circuit(
circuit: The cirq.FrozenCircuit version of this composite bloq.
cirq_quregs: The output mapping from right register names to Cirq qubit arrays.
"""
- cirq_quregs: Dict[str, 'CirqQuregInT'] = {
+ cirq_quregs: dict[str, 'CirqQuregInT'] = {
k: np.apply_along_axis(_QReg, -1, *(v, signature.get_left(k).dtype)) # type: ignore
for k, v in cirq_quregs.items()
}
- qvar_to_qreg: Dict[Soquet, _QReg] = {
+ qvar_to_qreg: dict[Soquet, _QReg] = {
Soquet(LeftDangle, idx=idx, reg=reg): np.asarray(cirq_quregs[reg.name])[idx]
for reg in signature.lefts()
for idx in reg.all_idxs()
}
- ops: List[cirq.Operation] = []
+ ops: list[cirq.Operation] = []
for binst in greedy_topological_sort(binst_graph):
if binst is LeftDangle:
continue
diff --git a/qualtran/cirq_interop/_bloq_to_cirq_test.py b/qualtran/cirq_interop/_bloq_to_cirq_test.py
index eb2d9e6204..91dc6cc3d3 100644
--- a/qualtran/cirq_interop/_bloq_to_cirq_test.py
+++ b/qualtran/cirq_interop/_bloq_to_cirq_test.py
@@ -11,7 +11,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.
-from typing import Dict, List, Tuple, TYPE_CHECKING
+from typing import TYPE_CHECKING
import cirq
import numpy as np
@@ -39,14 +39,14 @@ def signature(self):
def as_cirq_op(
self, qubit_manager: cirq.QubitManager, x: CirqQuregT, y: CirqQuregT
- ) -> Tuple[cirq.Operation, Dict[str, CirqQuregT]]:
+ ) -> tuple[cirq.Operation, dict[str, CirqQuregT]]:
(x,) = x
(y,) = y
return cirq.SWAP(x, y), {'x': np.array([x]), 'y': np.array([y])}
def my_tensors(
- self, incoming: Dict[str, 'ConnectionT'], outgoing: Dict[str, 'ConnectionT']
- ) -> List['qtn.Tensor']:
+ self, incoming: dict[str, 'ConnectionT'], outgoing: dict[str, 'ConnectionT']
+ ) -> list['qtn.Tensor']:
from qualtran.bloqs.basic_gates import TwoBitSwap
return TwoBitSwap().my_tensors(incoming=incoming, outgoing=outgoing)
@@ -73,7 +73,7 @@ def signature(self):
def build_composite_bloq(
self, bb: 'BloqBuilder', x: Soquet, y: Soquet, **kwargs
- ) -> Dict[str, SoquetT]:
+ ) -> dict[str, SoquetT]:
xs = bb.split(x)
ys = bb.split(y)
for i in range(self.n):
@@ -90,8 +90,8 @@ def signature(self):
return Signature.build(x=self.n, y=self.n)
def my_tensors(
- self, incoming: Dict[str, 'ConnectionT'], outgoing: Dict[str, 'ConnectionT']
- ) -> List['qtn.Tensor']:
+ self, incoming: dict[str, 'ConnectionT'], outgoing: dict[str, 'ConnectionT']
+ ) -> list['qtn.Tensor']:
import quimb.tensor as qtn
from qualtran.simulation.tensor._dense import _order_incoming_outgoing_indices
diff --git a/qualtran/cirq_interop/_cirq_to_bloq.py b/qualtran/cirq_interop/_cirq_to_bloq.py
index d2977e4339..8cf4282d21 100644
--- a/qualtran/cirq_interop/_cirq_to_bloq.py
+++ b/qualtran/cirq_interop/_cirq_to_bloq.py
@@ -17,8 +17,9 @@
import itertools
import numbers
import warnings
+from collections.abc import Sequence
from functools import cached_property
-from typing import Any, Dict, List, Optional, Sequence, Tuple, TYPE_CHECKING, TypeVar, Union
+from typing import Any, Optional, TYPE_CHECKING, TypeVar, Union
import cirq
import numpy as np
@@ -114,15 +115,15 @@ def decompose_from_registers(
raise DecomposeNotImplementedError(f"{self} does not declare a decomposition.") from e
def my_tensors(
- self, incoming: Dict[str, 'ConnectionT'], outgoing: Dict[str, 'ConnectionT']
- ) -> List['qtn.Tensor']:
+ self, incoming: dict[str, 'ConnectionT'], outgoing: dict[str, 'ConnectionT']
+ ) -> list['qtn.Tensor']:
return _my_tensors_from_gate(
self.cirq_gate, self.signature, incoming=incoming, outgoing=outgoing
)
def as_cirq_op(
self, qubit_manager: 'cirq.QubitManager', **in_quregs: 'CirqQuregT'
- ) -> Tuple[Union['cirq.Operation', None], Dict[str, 'CirqQuregT']]:
+ ) -> tuple[Union['cirq.Operation', None], dict[str, 'CirqQuregT']]:
qubits = in_quregs.get('q', np.array([])).flatten()
return self.cirq_gate.on(*qubits), in_quregs
@@ -188,7 +189,7 @@ def _cirq_wire_symbol_to_qualtran_wire_symbol(symbol: str, side: Side) -> 'WireS
def _wire_symbol_from_gate(
- gate: cirq.Gate, signature: Signature, wire_reg: Register, idx: Tuple[int, ...] = tuple()
+ gate: cirq.Gate, signature: Signature, wire_reg: Register, idx: tuple[int, ...] = tuple()
) -> 'WireSymbol':
wire_symbols = cirq.circuit_diagram_info(gate).wire_symbols
begin = 0
@@ -220,9 +221,9 @@ def _my_tensors_from_gate(
gate: cirq.Gate,
signature: Signature,
*,
- incoming: Dict[str, 'ConnectionT'],
- outgoing: Dict[str, 'ConnectionT'],
-) -> List['qtn.Tensor']:
+ incoming: dict[str, 'ConnectionT'],
+ outgoing: dict[str, 'ConnectionT'],
+) -> list['qtn.Tensor']:
import quimb.tensor as qtn
from qualtran.simulation.tensor._dense import _order_incoming_outgoing_indices
@@ -247,7 +248,7 @@ class _QReg:
of qubits that together form a quantum register.
"""
- qubits: Tuple[cirq.Qid, ...] = field(
+ qubits: tuple[cirq.Qid, ...] = field(
converter=lambda v: (v,) if isinstance(v, cirq.Qid) else tuple(v)
)
dtype: QDType
@@ -268,13 +269,13 @@ def __hash__(self):
def _ensure_in_reg_exists(
- bb: BloqBuilder, in_reg: _QReg, qreg_to_qvar: Dict[_QReg, Soquet]
+ bb: BloqBuilder, in_reg: _QReg, qreg_to_qvar: dict[_QReg, Soquet]
) -> None:
"""Takes care of qubit allocations, split and joins to ensure `qreg_to_qvar[in_reg]` exists."""
from qualtran.bloqs.bookkeeping import Cast
all_mapped_qubits = {q for qreg in qreg_to_qvar for q in qreg.qubits}
- qubits_to_allocate: List[cirq.Qid] = [q for q in in_reg.qubits if q not in all_mapped_qubits]
+ qubits_to_allocate: list[cirq.Qid] = [q for q in in_reg.qubits if q not in all_mapped_qubits]
if qubits_to_allocate:
n_alloc = len(qubits_to_allocate)
qreg_to_qvar[_QReg(qubits_to_allocate, dtype=QBit() if n_alloc == 1 else QAny(n_alloc))] = (
@@ -288,7 +289,7 @@ def _ensure_in_reg_exists(
# a. Split all registers containing at-least one qubit corresponding to `in_reg`.
in_reg_qubits = set(in_reg.qubits)
- new_qreg_to_qvar: Dict[_QReg, Soquet] = {}
+ new_qreg_to_qvar: dict[_QReg, Soquet] = {}
for qreg, soq in qreg_to_qvar.items():
if len(qreg.qubits) > 1 and any(q in qreg.qubits for q in in_reg_qubits):
new_qreg_to_qvar |= {
@@ -299,7 +300,7 @@ def _ensure_in_reg_exists(
qreg_to_qvar.clear()
# b. Join all 1-bit registers, corresponding to individual qubits, that make up `in_reg`.
- soqs_to_join: Dict[cirq.Qid, Soquet] = {}
+ soqs_to_join: dict[cirq.Qid, Soquet] = {}
for qreg, soq in new_qreg_to_qvar.items():
if len(in_reg_qubits) > 1 and qreg.qubits and qreg.qubits[0] in in_reg_qubits:
assert len(qreg.qubits) == 1, "Individual qubits should have been split by now."
@@ -330,11 +331,11 @@ def _ensure_in_reg_exists(
def _gather_input_soqs(
- bb: BloqBuilder, op_quregs: Dict[str, NDArray[_QReg]], qreg_to_qvar: Dict[_QReg, Soquet] # type: ignore[type-var]
-) -> Dict[str, NDArray[Soquet]]: # type: ignore[type-var]
- qvars_in: Dict[str, NDArray[Soquet]] = {} # type: ignore[type-var]
+ bb: BloqBuilder, op_quregs: dict[str, NDArray[_QReg]], qreg_to_qvar: dict[_QReg, Soquet] # type: ignore[type-var]
+) -> dict[str, NDArray[Soquet]]: # type: ignore[type-var]
+ qvars_in: dict[str, NDArray[Soquet]] = {} # type: ignore[type-var]
for reg_name, quregs in op_quregs.items():
- flat_soqs: List[Soquet] = []
+ flat_soqs: list[Soquet] = []
for qureg in quregs.flatten():
_ensure_in_reg_exists(bb, qureg, qreg_to_qvar)
flat_soqs.append(qreg_to_qvar[qureg])
@@ -457,8 +458,8 @@ def cirq_optree_to_cbloq(
optree: cirq.OP_TREE,
*,
signature: Optional[Signature] = None,
- in_quregs: Optional[Dict[str, 'CirqQuregT']] = None,
- out_quregs: Optional[Dict[str, 'CirqQuregT']] = None,
+ in_quregs: Optional[dict[str, 'CirqQuregT']] = None,
+ out_quregs: Optional[dict[str, 'CirqQuregT']] = None,
) -> CompositeBloq:
"""Convert a Cirq OP-TREE into a `CompositeBloq` with signature `signature`.
@@ -500,11 +501,11 @@ def cirq_optree_to_cbloq(
elif in_quregs is None or out_quregs is None:
raise ValueError("`signature` requires specifying both `in_quregs` and `out_quregs`.")
- in_quregs: Dict[str, NDArray] = {
+ in_quregs: dict[str, NDArray] = {
k: np.apply_along_axis(_QReg, -1, *(v, signature.get_left(k).dtype)) # type: ignore
for k, v in in_quregs.items()
}
- out_quregs: Dict[str, NDArray] = {
+ out_quregs: dict[str, NDArray] = {
k: np.apply_along_axis(_QReg, -1, *(v, signature.get_right(k).dtype)) # type: ignore
for k, v in out_quregs.items()
}
@@ -512,7 +513,7 @@ def cirq_optree_to_cbloq(
bb, initial_soqs = BloqBuilder.from_signature(signature, add_registers_allowed=False)
# 1. Compute qreg_to_qvar for input qubits in the LEFT signature.
- qreg_to_qvar: Dict[_QReg, Soquet] = {}
+ qreg_to_qvar: dict[_QReg, Soquet] = {}
for reg in signature.lefts():
if reg.name not in in_quregs:
raise ValueError(f"Register {reg.name} from signature must be present in in_quregs.")
@@ -535,12 +536,12 @@ def cirq_optree_to_cbloq(
reg_dtypes = [r.dtype for r in bloq.signature]
# 3.1 Find input / output registers.
- all_op_quregs: Dict[str, NDArray[_QReg]] = {
+ all_op_quregs: dict[str, NDArray[_QReg]] = {
k: np.apply_along_axis(_QReg, -1, *(v, reg_dtypes[i])) # type: ignore
for i, (k, v) in enumerate(split_qubits(bloq.signature, op.qubits).items())
}
- in_op_quregs: Dict[str, NDArray[_QReg]] = {
+ in_op_quregs: dict[str, NDArray[_QReg]] = {
reg.name: all_op_quregs[reg.name] for reg in bloq.signature.lefts()
}
# 3.2 Find input Soquets, by potentially allocating new Bloq registers corresponding to
diff --git a/qualtran/cirq_interop/_cirq_to_bloq_test.py b/qualtran/cirq_interop/_cirq_to_bloq_test.py
index 7df2f0a8ec..042b86ab21 100644
--- a/qualtran/cirq_interop/_cirq_to_bloq_test.py
+++ b/qualtran/cirq_interop/_cirq_to_bloq_test.py
@@ -11,7 +11,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.
-from typing import Dict, Iterator, List, Tuple
+from collections.abc import Iterator
import attr
import cirq
@@ -50,7 +50,7 @@ class TestCNOT(Bloq):
def signature(self) -> Signature:
return Signature.build(control=1, target=1)
- def build_composite_bloq(self, bb: 'BloqBuilder', **soqs: 'SoquetT') -> Dict[str, 'SoquetT']:
+ def build_composite_bloq(self, bb: 'BloqBuilder', **soqs: 'SoquetT') -> dict[str, 'SoquetT']:
ctrl, target = soqs['control'], soqs['target']
assert isinstance(ctrl, Soquet)
assert isinstance(target, Soquet)
@@ -59,7 +59,7 @@ def build_composite_bloq(self, bb: 'BloqBuilder', **soqs: 'SoquetT') -> Dict[str
def as_cirq_op(
self, qubit_manager: cirq.QubitManager, **cirq_quregs: 'CirqQuregT'
- ) -> Tuple['cirq.Operation', Dict[str, 'CirqQuregT']]:
+ ) -> tuple['cirq.Operation', dict[str, 'CirqQuregT']]:
(control,) = cirq_quregs['control']
(target,) = cirq_quregs['target']
return cirq.CNOT(control, target), cirq_quregs
@@ -256,7 +256,7 @@ def decompose_from_registers(self, *, context, junk) -> Iterator[cirq.OP_TREE]:
# Using InteropQubitManager enables support for LeftOnlyGate's in CirqGateAsBloq.
cbloq = qlt_testing.assert_valid_bloq_decomposition(LeftOnlyGate())
- bloqs_list: List[Bloq] = [binst.bloq for binst in cbloq.bloq_instances]
+ bloqs_list: list[Bloq] = [binst.bloq for binst in cbloq.bloq_instances]
assert bloqs_list.count(Split(QAny(2))) == 1
assert bloqs_list.count(Free(QBit())) == 2
assert bloqs_list.count(CNOT()) == 1
diff --git a/qualtran/cirq_interop/_interop_qubit_manager.py b/qualtran/cirq_interop/_interop_qubit_manager.py
index da3e8d2ee9..152da604dd 100644
--- a/qualtran/cirq_interop/_interop_qubit_manager.py
+++ b/qualtran/cirq_interop/_interop_qubit_manager.py
@@ -13,7 +13,8 @@
# limitations under the License.
"""Qubit Manager to use when converting Cirq gates to/from Bloqs."""
-from typing import Iterable, List, Optional, Set
+from collections.abc import Iterable
+from typing import Optional
import cirq
@@ -25,11 +26,11 @@ def __init__(self, qm: Optional[cirq.QubitManager] = None):
if qm is None:
qm = cirq.SimpleQubitManager()
self._qm = qm
- self._managed_qubits: Set[cirq.Qid] = set()
+ self._managed_qubits: set[cirq.Qid] = set()
- def qalloc(self, n: int, dim: int = 2) -> List['cirq.Qid']:
- ret: List['cirq.Qid'] = []
- qubits_to_free: List['cirq.Qid'] = []
+ def qalloc(self, n: int, dim: int = 2) -> list['cirq.Qid']:
+ ret: list['cirq.Qid'] = []
+ qubits_to_free: list['cirq.Qid'] = []
while len(ret) < n:
new_alloc = self._qm.qalloc(n - len(ret), dim)
for q in new_alloc:
@@ -40,9 +41,9 @@ def qalloc(self, n: int, dim: int = 2) -> List['cirq.Qid']:
self._qm.qfree(qubits_to_free)
return ret
- def qborrow(self, n: int, dim: int = 2) -> List['cirq.Qid']:
- ret: List['cirq.Qid'] = []
- qubits_to_free: List['cirq.Qid'] = []
+ def qborrow(self, n: int, dim: int = 2) -> list['cirq.Qid']:
+ ret: list['cirq.Qid'] = []
+ qubits_to_free: list['cirq.Qid'] = []
while len(ret) < n:
new_alloc = self._qm.qborrow(n - len(ret), dim)
for q in new_alloc:
diff --git a/qualtran/cirq_interop/jupyter_tools.py b/qualtran/cirq_interop/jupyter_tools.py
index fab86169ce..d5db181831 100644
--- a/qualtran/cirq_interop/jupyter_tools.py
+++ b/qualtran/cirq_interop/jupyter_tools.py
@@ -12,8 +12,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+from collections.abc import Iterable
from pathlib import Path
-from typing import Iterable
import cirq
import cirq.contrib.svg.svg as ccsvg
diff --git a/qualtran/cirq_interop/t_complexity_protocol.py b/qualtran/cirq_interop/t_complexity_protocol.py
index 64e3da56f3..e0ebe954d1 100644
--- a/qualtran/cirq_interop/t_complexity_protocol.py
+++ b/qualtran/cirq_interop/t_complexity_protocol.py
@@ -11,7 +11,8 @@
# 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.
-from typing import Any, Callable, Iterable, Optional, Union
+from collections.abc import Callable, Iterable
+from typing import Any, Optional, Union
import attrs
import cachetools
diff --git a/qualtran/cirq_interop/testing.py b/qualtran/cirq_interop/testing.py
index 203207f759..00ab8e714f 100644
--- a/qualtran/cirq_interop/testing.py
+++ b/qualtran/cirq_interop/testing.py
@@ -12,9 +12,10 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+from collections.abc import Sequence
from dataclasses import dataclass
from functools import cached_property
-from typing import Any, Dict, List, Sequence, Tuple
+from typing import Any
import cirq
import numpy as np
@@ -46,12 +47,12 @@ def r(self) -> Signature:
return self.gate.signature
@cached_property
- def quregs(self) -> Dict[str, NDArray[cirq.Qid]]: # type: ignore[type-var]
+ def quregs(self) -> dict[str, NDArray[cirq.Qid]]: # type: ignore[type-var]
"""A dictionary of named qubits appropriate for the signature for the gate."""
return get_named_qubits(self.r)
@cached_property
- def all_qubits(self) -> List[cirq.Qid]:
+ def all_qubits(self) -> list[cirq.Qid]:
"""All qubits in Register order."""
merged_qubits = merge_qubits(self.r, **self.quregs)
decomposed_qubits = self.decomposed_circuit.all_qubits()
@@ -101,7 +102,7 @@ def get_circuit_inp_out_cirqsim(
inputs: Sequence[int],
outputs: Sequence[int],
decimals: int = 2,
-) -> Tuple[str, str]:
+) -> tuple[str, str]:
"""Use a Cirq simulator to get a outputs of a `circuit`.
Args:
diff --git a/qualtran/cirq_interop/testing_test.py b/qualtran/cirq_interop/testing_test.py
index cc35f145ea..b12fe081fe 100644
--- a/qualtran/cirq_interop/testing_test.py
+++ b/qualtran/cirq_interop/testing_test.py
@@ -11,7 +11,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.
-from typing import Iterator
+from collections.abc import Iterator
import cirq
import numpy as np
diff --git a/qualtran/drawing/_show_funcs.py b/qualtran/drawing/_show_funcs.py
index 932a78ad69..23e3dda336 100644
--- a/qualtran/drawing/_show_funcs.py
+++ b/qualtran/drawing/_show_funcs.py
@@ -15,7 +15,8 @@
"""Convenience functions for showing rich displays in Jupyter notebook."""
import os
-from typing import Dict, Optional, overload, Sequence, TYPE_CHECKING, Union
+from collections.abc import Sequence
+from typing import Optional, overload, TYPE_CHECKING, Union
import IPython.display
import ipywidgets
@@ -123,7 +124,7 @@ def show_call_graph(
IPython.display.display(GraphvizCallGraph(item).get_svg())
-def show_counts_sigma(sigma: Dict['Bloq', Union[int, 'sympy.Expr']]):
+def show_counts_sigma(sigma: dict['Bloq', Union[int, 'sympy.Expr']]):
"""Display nicely formatted bloq counts sums `sigma`."""
IPython.display.display(IPython.display.Markdown(format_counts_sigma(sigma)))
diff --git a/qualtran/drawing/bloq_counts_graph.py b/qualtran/drawing/bloq_counts_graph.py
index bfbeea4cab..78de6ba734 100644
--- a/qualtran/drawing/bloq_counts_graph.py
+++ b/qualtran/drawing/bloq_counts_graph.py
@@ -16,7 +16,8 @@
import abc
import html
import warnings
-from typing import Any, cast, Dict, Mapping, Optional, TYPE_CHECKING, Union
+from collections.abc import Mapping
+from typing import Any, cast, Optional, TYPE_CHECKING, Union
import IPython.display
import networkx as nx
@@ -33,7 +34,7 @@
class _CallGraphDrawerBase(metaclass=abc.ABCMeta):
def __init__(self, g: nx.DiGraph):
self.g = g
- self._ids: Dict[Bloq, str] = {}
+ self._ids: dict[Bloq, str] = {}
self._i = 0
def get_id(self, b: Bloq) -> str:
@@ -126,7 +127,7 @@ class GraphvizCallGraph(_CallGraphDrawerBase):
in each node. The keys and values must support `str()`.
"""
- def __init__(self, g: nx.DiGraph, bloq_data: Optional[Dict['Bloq', Dict[Any, Any]]] = None):
+ def __init__(self, g: nx.DiGraph, bloq_data: Optional[dict['Bloq', dict[Any, Any]]] = None):
super().__init__(g)
if bloq_data is None:
@@ -135,7 +136,7 @@ def __init__(self, g: nx.DiGraph, bloq_data: Optional[Dict['Bloq', Dict[Any, Any
self.bloq_data = bloq_data
@classmethod
- def format_qubit_count(cls, val: SymbolicInt) -> Dict[str, str]:
+ def format_qubit_count(cls, val: SymbolicInt) -> dict[str, str]:
"""Format `QubitCount` cost values as a string.
Args:
@@ -147,7 +148,7 @@ def format_qubit_count(cls, val: SymbolicInt) -> Dict[str, str]:
return {'Qubits': f'{val}'}
@classmethod
- def format_qec_gates_cost(cls, val: 'GateCounts', agg: Optional[str] = None) -> Dict[str, str]:
+ def format_qec_gates_cost(cls, val: 'GateCounts', agg: Optional[str] = None) -> dict[str, str]:
"""Format `QECGatesCost` cost values as a string.
Args:
@@ -191,9 +192,9 @@ def format_qec_gates_cost(cls, val: 'GateCounts', agg: Optional[str] = None) ->
@classmethod
def format_cost_data(
cls,
- cost_data: Dict['Bloq', Dict['CostKey', 'CostValT']],
+ cost_data: dict['Bloq', dict['CostKey', 'CostValT']],
agg_gate_counts: Optional[str] = None,
- ) -> Dict['Bloq', Dict[str, str]]:
+ ) -> dict['Bloq', dict[str, str]]:
"""Format `cost_data` as human-readable strings.
Args:
@@ -211,9 +212,9 @@ class method will delegate to `format_qubit_count` and `format_qec_gates_cost`
"""
from qualtran.resource_counting import GateCounts, QECGatesCost, QubitCount
- disp_data: Dict['Bloq', Dict[str, str]] = {}
+ disp_data: dict['Bloq', dict[str, str]] = {}
for bloq in cost_data.keys():
- bloq_disp: Dict[str, str] = {}
+ bloq_disp: dict[str, str] = {}
for cost_key, cost_val in cost_data[bloq].items():
if isinstance(cost_key, QubitCount):
bloq_disp |= cls.format_qubit_count(cast(SymbolicInt, cost_val))
@@ -258,7 +259,7 @@ def from_bloq(
from qualtran.resource_counting import QECGatesCost, QubitCount, query_costs
call_graph, _ = bloq.call_graph(max_depth=max_depth)
- cost_data: Dict['Bloq', Dict[CostKey, Any]] = query_costs(
+ cost_data: dict['Bloq', dict[CostKey, Any]] = query_costs(
bloq, [QubitCount(), QECGatesCost()]
)
formatted_cost_data = cls.format_cost_data(cost_data, agg_gate_counts=agg_gate_counts)
@@ -314,7 +315,7 @@ def format_counts_graph_markdown(graph: nx.DiGraph) -> str:
return m
-def format_counts_sigma(sigma: Dict[Bloq, Union[int, sympy.Expr]]) -> str:
+def format_counts_sigma(sigma: dict[Bloq, Union[int, sympy.Expr]]) -> str:
"""Format `sigma` as markdown."""
lines = [f' - {_format_bloq_expr_markdown(bloq, expr)}' for bloq, expr in sigma.items()]
lines.sort()
diff --git a/qualtran/drawing/bloq_counts_graph_test.py b/qualtran/drawing/bloq_counts_graph_test.py
index e95e9f194f..2d3b6fa8e8 100644
--- a/qualtran/drawing/bloq_counts_graph_test.py
+++ b/qualtran/drawing/bloq_counts_graph_test.py
@@ -12,7 +12,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import random
-from typing import List
import networkx as nx
@@ -46,7 +45,7 @@ def test_format_counts_graph_markdown():
)
-def _get_node_labels_from_pydot_graph(drawer: _CallGraphDrawerBase) -> List[str]:
+def _get_node_labels_from_pydot_graph(drawer: _CallGraphDrawerBase) -> list[str]:
graph = drawer.get_graph()
node_labels = [node.get_label() for node in graph.get_node_list()] # type: ignore[attr-defined]
random.shuffle(node_labels) # don't rely on order of graphviz nodes
diff --git a/qualtran/drawing/classical_sim_graph.py b/qualtran/drawing/classical_sim_graph.py
index a816c62cee..f465369250 100644
--- a/qualtran/drawing/classical_sim_graph.py
+++ b/qualtran/drawing/classical_sim_graph.py
@@ -14,7 +14,7 @@
"""Classes for drawing classical data flows with Graphviz."""
-from typing import Dict, TYPE_CHECKING
+from typing import TYPE_CHECKING
import pydot
@@ -36,7 +36,7 @@ class ClassicalSimGraphDrawer(PrettyGraphDrawer):
vals: Input classical values to propogate through the composite bloq.
"""
- def __init__(self, bloq: Bloq, vals: Dict[str, 'ClassicalValT']):
+ def __init__(self, bloq: Bloq, vals: dict[str, 'ClassicalValT']):
super().__init__(bloq=bloq)
from qualtran.simulation.classical_sim import call_cbloq_classically
diff --git a/qualtran/drawing/flame_graph.py b/qualtran/drawing/flame_graph.py
index 7546f69912..a583491b05 100644
--- a/qualtran/drawing/flame_graph.py
+++ b/qualtran/drawing/flame_graph.py
@@ -17,7 +17,8 @@
import pathlib
import subprocess
import tempfile
-from typing import Any, Callable, List, Optional, Union
+from collections.abc import Callable
+from typing import Any, Optional, Union
import networkx as nx
import numpy as np
@@ -71,7 +72,7 @@ def _keep_if_small(bloq: Bloq) -> bool:
return False
-def _is_leaf_node(callees: List[Bloq]) -> bool:
+def _is_leaf_node(callees: list[Bloq]) -> bool:
from qualtran.bloqs.basic_gates import TGate
return len(callees) == 0 or (
@@ -80,8 +81,8 @@ def _is_leaf_node(callees: List[Bloq]) -> bool:
def _populate_flame_graph_data(
- bloq: Bloq, graph: nx.DiGraph, graph_t: nx.DiGraph, prefix: List[str]
-) -> List[str]:
+ bloq: Bloq, graph: nx.DiGraph, graph_t: nx.DiGraph, prefix: list[str]
+) -> list[str]:
"""Populates data for the flame graph.
Args:
@@ -128,7 +129,7 @@ def get_flame_graph_data(
file_path: Union[None, pathlib.Path, str] = None,
keep: Optional[Callable[['Bloq'], bool]] = _keep_if_small,
**kwargs,
-) -> List[str]:
+) -> list[str]:
"""Get the flame graph data for visualizing T-costs distribution of a sequence of bloqs.
For each bloq in the input, this will do a DFS ordering over all edges in the DAG and
diff --git a/qualtran/drawing/graphviz.py b/qualtran/drawing/graphviz.py
index 64f4faee09..faeba6bc85 100644
--- a/qualtran/drawing/graphviz.py
+++ b/qualtran/drawing/graphviz.py
@@ -15,7 +15,8 @@
"""Classes for drawing bloqs with Graphviz."""
import html
import itertools
-from typing import Any, Dict, Iterable, List, Optional, Set, Tuple
+from collections.abc import Iterable
+from typing import Any, Optional
import IPython.display
import pydot
@@ -38,7 +39,7 @@
def _assign_ids_to_bloqs_and_soqs(
bloq_instances: Iterable[BloqInstance], all_soquets: Iterable[Soquet]
-) -> Dict[Any, str]:
+) -> dict[Any, str]:
"""Assign unique identifiers to bloq instances, soquets, and register groups.
Graphviz is very forgiving in its input format. If you accidentally introduce a new id (e.g.
@@ -53,8 +54,8 @@ def _assign_ids_to_bloqs_and_soqs(
shared names (but differing `side` attributes) are implicitly grouped. 3) Each
Soquet in `all_soquets`.
"""
- to_id: Dict[Any, str] = {}
- ids: Set[str] = set()
+ to_id: dict[Any, str] = {}
+ ids: set[str] = set()
disambiguator = 0
def add(item: Any, desired_id: str):
@@ -85,7 +86,7 @@ def add(item: Any, desired_id: str):
def _parition_registers_in_a_group(
regs: Iterable[Register], binst: BloqInstance
-) -> Tuple[List[Soquet], List[Soquet], List[Soquet]]:
+) -> tuple[list[Soquet], list[Soquet], list[Soquet]]:
"""Construct and sort the expected Soquets for a given register group.
Since we expect the input registers to be in a group, we assert that
diff --git a/qualtran/drawing/musical_score.py b/qualtran/drawing/musical_score.py
index 065f2312c4..042e6f3a94 100644
--- a/qualtran/drawing/musical_score.py
+++ b/qualtran/drawing/musical_score.py
@@ -21,8 +21,9 @@
import abc
import heapq
import json
+from collections.abc import Callable, Iterable
from enum import Enum
-from typing import Any, Callable, cast, Dict, Iterable, List, Optional, Set, Tuple, Union
+from typing import Any, cast, Optional, Union
import attrs
import networkx as nx
@@ -102,7 +103,7 @@ class HLine:
seq_x_end: Optional[int] = None
flavor: HLineFlavor = HLineFlavor.QUANTUM
- def json_dict(self) -> Dict[str, Any]:
+ def json_dict(self) -> dict[str, Any]:
d = attrs.asdict(self)
d['flavor'] = str(d['flavor'])
return d
@@ -114,8 +115,8 @@ class LineManager:
def __init__(self, max_n_lines: int = 100):
self.available = list(range(max_n_lines))
heapq.heapify(self.available)
- self.hlines: Set[HLine] = set()
- self._reserved: List[Tuple[List[int], Callable]] = []
+ self.hlines: set[HLine] = set()
+ self._reserved: list[tuple[list[int], Callable]] = []
def new_y(self, binst: BloqInstance, reg: Register, idx=None):
"""Allocate a new y position (i.e. a new qubit or register)."""
@@ -145,7 +146,7 @@ def unreserve(self, binst: BloqInstance, reg: Register):
self._reserved = kept
def maybe_reserve(
- self, binst: Union[DanglingT, BloqInstance], reg: Register, idx: Tuple[int, ...]
+ self, binst: Union[DanglingT, BloqInstance], reg: Register, idx: tuple[int, ...]
):
"""Override this method to provide custom control over line allocation.
@@ -218,7 +219,7 @@ def free(
def _get_in_vals(
- binst: Union[DanglingT, BloqInstance], reg: Register, soq_assign: Dict[Soquet, RegPosition]
+ binst: Union[DanglingT, BloqInstance], reg: Register, soq_assign: dict[Soquet, RegPosition]
) -> Union[RegPosition, NDArray[RegPosition]]:
"""Pluck out the correct values from `soq_assign` for `reg` on `binst`."""
if not reg.shape:
@@ -235,8 +236,8 @@ def _get_in_vals(
def _update_assign_from_vals(
regs: Iterable[Register],
binst: Union[DanglingT, BloqInstance],
- vals: Dict[str, RegPosition],
- soq_assign: Dict[Soquet, RegPosition],
+ vals: dict[str, RegPosition],
+ soq_assign: dict[Soquet, RegPosition],
seq_x: int,
topo_gen: int,
manager: LineManager,
@@ -274,7 +275,7 @@ def _update_assign_from_vals(
def _binst_assign_line(
binst: BloqInstance,
pred_cxns: Iterable[Connection],
- soq_assign: Dict[Soquet, RegPosition],
+ soq_assign: dict[Soquet, RegPosition],
seq_x: int,
topo_gen: int,
manager: LineManager,
@@ -324,7 +325,7 @@ def _in_vals(reg: Register):
def _cbloq_musical_score(
signature: Signature, binst_graph: nx.DiGraph, manager: Optional[LineManager] = None
-) -> Tuple[Dict[str, RegPosition], Dict[Soquet, RegPosition], LineManager]:
+) -> tuple[dict[str, RegPosition], dict[Soquet, RegPosition], LineManager]:
"""Assign musical score positions through a composite bloq's contents.
Args:
@@ -341,7 +342,7 @@ def _cbloq_musical_score(
# Keep track of each soquet's position. Initialize by implicitly allocating new positions.
# We introduce the convention that `LeftDangle`s are a seq_x=-1 and topo_gen=0
- soq_assign: Dict[Soquet, RegPosition] = {}
+ soq_assign: dict[Soquet, RegPosition] = {}
topo_gen = 0
_update_assign_from_vals(
signature.lefts(), LeftDangle, {}, soq_assign, seq_x=-1, topo_gen=topo_gen, manager=manager
@@ -392,7 +393,7 @@ def adjoint(self) -> 'WireSymbol':
"""Return a symbol that is the adjoint of this."""
return self
- def json_dict(self) -> Dict[str, Any]:
+ def json_dict(self) -> dict[str, Any]:
return {'symb_cls': self.__class__.__name__, 'symb_attributes': attrs.asdict(self)}
@@ -572,9 +573,9 @@ class MusicalScoreData:
max_x: int
max_y: int
- soqs: List[SoqData]
- hlines: List[HLine]
- vlines: List[VLine]
+ soqs: list[SoqData]
+ hlines: list[HLine]
+ vlines: list[VLine]
def json_dict(self):
return attrs.asdict(self, recurse=False)
diff --git a/qualtran/drawing/qpic_diagram.py b/qualtran/drawing/qpic_diagram.py
index 389876fa3f..263af3579c 100644
--- a/qualtran/drawing/qpic_diagram.py
+++ b/qualtran/drawing/qpic_diagram.py
@@ -24,7 +24,7 @@
import subprocess
import tempfile
from collections import defaultdict
-from typing import Dict, List, Optional, Set, Tuple, TYPE_CHECKING, Union
+from typing import Optional, TYPE_CHECKING, Union
from qualtran import DanglingT, LeftDangle, QBit, RightDangle, Side, Soquet
from qualtran.drawing.musical_score import (
@@ -99,16 +99,16 @@ class QpicWireManager:
"""
def __init__(self):
- self._soq_to_wire_name_tuple: Dict[Soquet, Tuple[str, int]] = {}
- self._alloc_wires_with_prefix: Dict[str, Set[int]] = defaultdict(set)
+ self._soq_to_wire_name_tuple: dict[Soquet, tuple[str, int]] = {}
+ self._alloc_wires_with_prefix: dict[str, set[int]] = defaultdict(set)
- def _wire_name_tuple_for_soq(self, soq: Soquet) -> Tuple[str, int]:
+ def _wire_name_tuple_for_soq(self, soq: Soquet) -> tuple[str, int]:
prefix = _wire_name_prefix_for_soq(soq)
allocated_suffixes = self._alloc_wires_with_prefix[prefix]
next_i = next(i for i in range(len(allocated_suffixes) + 1) if i not in allocated_suffixes)
return prefix, next_i
- def _wire_name_tuple_to_str(self, wire_name: Tuple[str, int]) -> str:
+ def _wire_name_tuple_to_str(self, wire_name: tuple[str, int]) -> str:
prefix, i = wire_name
return prefix + '_' + str(i) if i else prefix
@@ -169,10 +169,10 @@ def add_right_wires_for_signature(self, signature: 'Signature') -> None:
self.gates += ['LABEL length=10']
@property
- def data(self) -> List[str]:
+ def data(self) -> list[str]:
return self.wires + self.gates
- def _add_soq(self, soq: Soquet) -> Tuple[str, Optional[str]]:
+ def _add_soq(self, soq: Soquet) -> tuple[str, Optional[str]]:
symbol = _soq_to_symb(soq)
suffix = ''
wire = self.wire_manager.soq_to_wirename(self.soq_map[soq])
@@ -200,7 +200,7 @@ def _dealloc_wire_for_soq(self, soq: Soquet) -> None:
self.soq_map.pop(soq)
@classmethod
- def _dtype_label_for_wire(cls, wire_name: str, dtype: 'QCDType') -> List[str]:
+ def _dtype_label_for_wire(cls, wire_name: str, dtype: 'QCDType') -> list[str]:
if dtype != QBit():
dtype_str = _format_label_text(str(dtype), scale=0.5)
return [f'{wire_name} / {dtype_str}']
@@ -241,7 +241,7 @@ def _add_bloq_with_no_wire(self, bloq: 'Bloq'):
width = _gate_width_for_text(gate_text)
self.gates += [f'{self.empty_wire} G:width={width}:shape=8 {gate_text}']
- def add_bloq(self, bloq: 'Bloq', pred: List['Connection'], succ: List['Connection']) -> None:
+ def add_bloq(self, bloq: 'Bloq', pred: list['Connection'], succ: list['Connection']) -> None:
controls, targets, wire_dtype_labels = [], [], []
if not (pred or succ):
@@ -270,7 +270,7 @@ def add_soq(soq: Soquet):
self.gates += wire_dtype_labels
-def get_qpic_data(bloq: 'Bloq', file_path: Union[None, pathlib.Path, str] = None) -> List[str]:
+def get_qpic_data(bloq: 'Bloq', file_path: Union[None, pathlib.Path, str] = None) -> list[str]:
"""Get the input data that can be used to draw a latex diagram for `bloq` using `qpic`.
Args:
diff --git a/qualtran/linalg/lcu_util.py b/qualtran/linalg/lcu_util.py
index fea17c03d3..b21fe05df4 100644
--- a/qualtran/linalg/lcu_util.py
+++ b/qualtran/linalg/lcu_util.py
@@ -15,7 +15,8 @@
"""Utility methods for LCU circuits as implemented in https://github.com/quantumlib/OpenFermion"""
import math
-from typing import Optional, overload, Sequence
+from collections.abc import Sequence
+from typing import Optional, overload
from qualtran.symbolics import ceil, is_symbolic, log2, SymbolicFloat, SymbolicInt
diff --git a/qualtran/linalg/permutation.py b/qualtran/linalg/permutation.py
index 2655f6e612..fee5e60fdc 100644
--- a/qualtran/linalg/permutation.py
+++ b/qualtran/linalg/permutation.py
@@ -11,7 +11,8 @@
# 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.
-from typing import Iterator, Sequence, TypeAlias
+from collections.abc import Iterator, Sequence
+from typing import TypeAlias
CycleT: TypeAlias = tuple[int, ...]
diff --git a/qualtran/linalg/polynomial/basic.py b/qualtran/linalg/polynomial/basic.py
index 2251b9c733..17013cf9af 100644
--- a/qualtran/linalg/polynomial/basic.py
+++ b/qualtran/linalg/polynomial/basic.py
@@ -11,7 +11,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.
-from typing import Sequence
+from collections.abc import Sequence
import numpy as np
from numpy.typing import NDArray
diff --git a/qualtran/linalg/polynomial/qsp_testing.py b/qualtran/linalg/polynomial/qsp_testing.py
index 496822c4e2..a4a0c52641 100644
--- a/qualtran/linalg/polynomial/qsp_testing.py
+++ b/qualtran/linalg/polynomial/qsp_testing.py
@@ -11,7 +11,8 @@
# 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.
-from typing import Sequence, Union
+from collections.abc import Sequence
+from typing import Union
import numpy as np
from numpy.polynomial import Polynomial
diff --git a/qualtran/protos/bloq_pb2.pyi b/qualtran/protos/bloq_pb2.pyi
index b3481a7aab..6b06b48a9e 100644
--- a/qualtran/protos/bloq_pb2.pyi
+++ b/qualtran/protos/bloq_pb2.pyi
@@ -18,6 +18,7 @@ limitations under the License.
"""
import builtins
import collections.abc
+import typing
import google.protobuf.descriptor
import google.protobuf.internal.containers
import google.protobuf.message
@@ -28,16 +29,10 @@ import qualtran.protos.data_types_pb2
import qualtran.protos.ec_point_pb2
import qualtran.protos.registers_pb2
import qualtran.protos.sympy_pb2
-import sys
-
-if sys.version_info >= (3, 8):
- import typing as typing_extensions
-else:
- import typing_extensions
DESCRIPTOR: google.protobuf.descriptor.FileDescriptor
-@typing_extensions.final
+@typing.final
class BloqArg(google.protobuf.message.Message):
DESCRIPTOR: google.protobuf.descriptor.Descriptor
@@ -104,13 +99,13 @@ class BloqArg(google.protobuf.message.Message):
complex_val: qualtran.protos.args_pb2.Complex | None = ...,
ec_point: qualtran.protos.ec_point_pb2.ECPoint | None = ...,
) -> None: ...
- def HasField(self, field_name: typing_extensions.Literal["cirq_json_gzip", b"cirq_json_gzip", "complex_val", b"complex_val", "ctrl_spec", b"ctrl_spec", "ec_point", b"ec_point", "float_val", b"float_val", "int_val", b"int_val", "ndarray", b"ndarray", "qdata_type", b"qdata_type", "register", b"register", "registers", b"registers", "string_val", b"string_val", "subbloq", b"subbloq", "sympy_expr", b"sympy_expr", "val", b"val"]) -> builtins.bool: ...
- def ClearField(self, field_name: typing_extensions.Literal["cirq_json_gzip", b"cirq_json_gzip", "complex_val", b"complex_val", "ctrl_spec", b"ctrl_spec", "ec_point", b"ec_point", "float_val", b"float_val", "int_val", b"int_val", "name", b"name", "ndarray", b"ndarray", "qdata_type", b"qdata_type", "register", b"register", "registers", b"registers", "string_val", b"string_val", "subbloq", b"subbloq", "sympy_expr", b"sympy_expr", "val", b"val"]) -> None: ...
- def WhichOneof(self, oneof_group: typing_extensions.Literal["val", b"val"]) -> typing_extensions.Literal["int_val", "float_val", "string_val", "sympy_expr", "ndarray", "subbloq", "cirq_json_gzip", "qdata_type", "register", "registers", "ctrl_spec", "complex_val", "ec_point"] | None: ...
+ def HasField(self, field_name: typing.Literal["cirq_json_gzip", b"cirq_json_gzip", "complex_val", b"complex_val", "ctrl_spec", b"ctrl_spec", "ec_point", b"ec_point", "float_val", b"float_val", "int_val", b"int_val", "ndarray", b"ndarray", "qdata_type", b"qdata_type", "register", b"register", "registers", b"registers", "string_val", b"string_val", "subbloq", b"subbloq", "sympy_expr", b"sympy_expr", "val", b"val"]) -> builtins.bool: ...
+ def ClearField(self, field_name: typing.Literal["cirq_json_gzip", b"cirq_json_gzip", "complex_val", b"complex_val", "ctrl_spec", b"ctrl_spec", "ec_point", b"ec_point", "float_val", b"float_val", "int_val", b"int_val", "name", b"name", "ndarray", b"ndarray", "qdata_type", b"qdata_type", "register", b"register", "registers", b"registers", "string_val", b"string_val", "subbloq", b"subbloq", "sympy_expr", b"sympy_expr", "val", b"val"]) -> None: ...
+ def WhichOneof(self, oneof_group: typing.Literal["val", b"val"]) -> typing.Literal["int_val", "float_val", "string_val", "sympy_expr", "ndarray", "subbloq", "cirq_json_gzip", "qdata_type", "register", "registers", "ctrl_spec", "complex_val", "ec_point"] | None: ...
global___BloqArg = BloqArg
-@typing_extensions.final
+@typing.final
class BloqLibrary(google.protobuf.message.Message):
"""A library of Bloqs. BloqLibrary should be used to represent both primitive Bloqs and
composite Bloqs; i.e. Bloqs consisting of other subbloqs, like `CompositeBloq`,
@@ -119,13 +114,13 @@ class BloqLibrary(google.protobuf.message.Message):
DESCRIPTOR: google.protobuf.descriptor.Descriptor
- @typing_extensions.final
+ @typing.final
class BloqWithDecomposition(google.protobuf.message.Message):
"""Decompositions are specified using integer IDs referencing other Bloqs within this library."""
DESCRIPTOR: google.protobuf.descriptor.Descriptor
- @typing_extensions.final
+ @typing.final
class BloqCountsEntry(google.protobuf.message.Message):
DESCRIPTOR: google.protobuf.descriptor.Descriptor
@@ -140,8 +135,8 @@ class BloqLibrary(google.protobuf.message.Message):
key: builtins.int = ...,
value: qualtran.protos.args_pb2.IntOrSympy | None = ...,
) -> None: ...
- def HasField(self, field_name: typing_extensions.Literal["value", b"value"]) -> builtins.bool: ...
- def ClearField(self, field_name: typing_extensions.Literal["key", b"key", "value", b"value"]) -> None: ...
+ def HasField(self, field_name: typing.Literal["value", b"value"]) -> builtins.bool: ...
+ def ClearField(self, field_name: typing.Literal["key", b"key", "value", b"value"]) -> None: ...
BLOQ_ID_FIELD_NUMBER: builtins.int
DECOMPOSITION_FIELD_NUMBER: builtins.int
@@ -166,8 +161,8 @@ class BloqLibrary(google.protobuf.message.Message):
bloq_counts: collections.abc.Mapping[builtins.int, qualtran.protos.args_pb2.IntOrSympy] | None = ...,
bloq: global___Bloq | None = ...,
) -> None: ...
- def HasField(self, field_name: typing_extensions.Literal["bloq", b"bloq"]) -> builtins.bool: ...
- def ClearField(self, field_name: typing_extensions.Literal["bloq", b"bloq", "bloq_counts", b"bloq_counts", "bloq_id", b"bloq_id", "decomposition", b"decomposition"]) -> None: ...
+ def HasField(self, field_name: typing.Literal["bloq", b"bloq"]) -> builtins.bool: ...
+ def ClearField(self, field_name: typing.Literal["bloq", b"bloq", "bloq_counts", b"bloq_counts", "bloq_id", b"bloq_id", "decomposition", b"decomposition"]) -> None: ...
NAME_FIELD_NUMBER: builtins.int
TABLE_FIELD_NUMBER: builtins.int
@@ -181,11 +176,11 @@ class BloqLibrary(google.protobuf.message.Message):
name: builtins.str = ...,
table: collections.abc.Iterable[global___BloqLibrary.BloqWithDecomposition] | None = ...,
) -> None: ...
- def ClearField(self, field_name: typing_extensions.Literal["name", b"name", "table", b"table"]) -> None: ...
+ def ClearField(self, field_name: typing.Literal["name", b"name", "table", b"table"]) -> None: ...
global___BloqLibrary = BloqLibrary
-@typing_extensions.final
+@typing.final
class Bloq(google.protobuf.message.Message):
"""Messages to enable efficient description of a BloqLibrary, including Bloq decompositions in
terms of other simpler bloqs.
@@ -218,12 +213,12 @@ class Bloq(google.protobuf.message.Message):
registers: qualtran.protos.registers_pb2.Registers | None = ...,
t_complexity: qualtran.protos.annotations_pb2.TComplexity | None = ...,
) -> None: ...
- def HasField(self, field_name: typing_extensions.Literal["registers", b"registers", "t_complexity", b"t_complexity"]) -> builtins.bool: ...
- def ClearField(self, field_name: typing_extensions.Literal["args", b"args", "name", b"name", "registers", b"registers", "t_complexity", b"t_complexity"]) -> None: ...
+ def HasField(self, field_name: typing.Literal["registers", b"registers", "t_complexity", b"t_complexity"]) -> builtins.bool: ...
+ def ClearField(self, field_name: typing.Literal["args", b"args", "name", b"name", "registers", b"registers", "t_complexity", b"t_complexity"]) -> None: ...
global___Bloq = Bloq
-@typing_extensions.final
+@typing.final
class BloqInstance(google.protobuf.message.Message):
"""Specific instance of a Bloq."""
@@ -239,11 +234,11 @@ class BloqInstance(google.protobuf.message.Message):
instance_id: builtins.int = ...,
bloq_id: builtins.int = ...,
) -> None: ...
- def ClearField(self, field_name: typing_extensions.Literal["bloq_id", b"bloq_id", "instance_id", b"instance_id"]) -> None: ...
+ def ClearField(self, field_name: typing.Literal["bloq_id", b"bloq_id", "instance_id", b"instance_id"]) -> None: ...
global___BloqInstance = BloqInstance
-@typing_extensions.final
+@typing.final
class Soquet(google.protobuf.message.Message):
"""One half of a connection."""
@@ -268,13 +263,13 @@ class Soquet(google.protobuf.message.Message):
register: qualtran.protos.registers_pb2.Register | None = ...,
index: collections.abc.Iterable[builtins.int] | None = ...,
) -> None: ...
- def HasField(self, field_name: typing_extensions.Literal["binst", b"binst", "bloq_instance", b"bloq_instance", "dangling_t", b"dangling_t", "register", b"register"]) -> builtins.bool: ...
- def ClearField(self, field_name: typing_extensions.Literal["binst", b"binst", "bloq_instance", b"bloq_instance", "dangling_t", b"dangling_t", "index", b"index", "register", b"register"]) -> None: ...
- def WhichOneof(self, oneof_group: typing_extensions.Literal["binst", b"binst"]) -> typing_extensions.Literal["bloq_instance", "dangling_t"] | None: ...
+ def HasField(self, field_name: typing.Literal["binst", b"binst", "bloq_instance", b"bloq_instance", "dangling_t", b"dangling_t", "register", b"register"]) -> builtins.bool: ...
+ def ClearField(self, field_name: typing.Literal["binst", b"binst", "bloq_instance", b"bloq_instance", "dangling_t", b"dangling_t", "index", b"index", "register", b"register"]) -> None: ...
+ def WhichOneof(self, oneof_group: typing.Literal["binst", b"binst"]) -> typing.Literal["bloq_instance", "dangling_t"] | None: ...
global___Soquet = Soquet
-@typing_extensions.final
+@typing.final
class Connection(google.protobuf.message.Message):
"""A connection between two Soquets. Quantum compute graph can be represented as a list of
connections.
@@ -294,7 +289,7 @@ class Connection(google.protobuf.message.Message):
left: global___Soquet | None = ...,
right: global___Soquet | None = ...,
) -> None: ...
- def HasField(self, field_name: typing_extensions.Literal["left", b"left", "right", b"right"]) -> builtins.bool: ...
- def ClearField(self, field_name: typing_extensions.Literal["left", b"left", "right", b"right"]) -> None: ...
+ def HasField(self, field_name: typing.Literal["left", b"left", "right", b"right"]) -> builtins.bool: ...
+ def ClearField(self, field_name: typing.Literal["left", b"left", "right", b"right"]) -> None: ...
global___Connection = Connection
diff --git a/qualtran/protos/ec_point_pb2.pyi b/qualtran/protos/ec_point_pb2.pyi
index ac82158cd6..bfe37949c1 100644
--- a/qualtran/protos/ec_point_pb2.pyi
+++ b/qualtran/protos/ec_point_pb2.pyi
@@ -14,19 +14,14 @@ See the License for the specific language governing permissions and
limitations under the License.
"""
import builtins
+import typing
import google.protobuf.descriptor
import google.protobuf.message
import qualtran.protos.args_pb2
-import sys
-
-if sys.version_info >= (3, 8):
- import typing as typing_extensions
-else:
- import typing_extensions
DESCRIPTOR: google.protobuf.descriptor.FileDescriptor
-@typing_extensions.final
+@typing.final
class ECPoint(google.protobuf.message.Message):
DESCRIPTOR: google.protobuf.descriptor.Descriptor
@@ -50,8 +45,8 @@ class ECPoint(google.protobuf.message.Message):
mod: qualtran.protos.args_pb2.IntOrSympy | None = ...,
curve_a: qualtran.protos.args_pb2.IntOrSympy | None = ...,
) -> None: ...
- def HasField(self, field_name: typing_extensions.Literal["_curve_a", b"_curve_a", "curve_a", b"curve_a", "mod", b"mod", "x", b"x", "y", b"y"]) -> builtins.bool: ...
- def ClearField(self, field_name: typing_extensions.Literal["_curve_a", b"_curve_a", "curve_a", b"curve_a", "mod", b"mod", "x", b"x", "y", b"y"]) -> None: ...
- def WhichOneof(self, oneof_group: typing_extensions.Literal["_curve_a", b"_curve_a"]) -> typing_extensions.Literal["curve_a"] | None: ...
+ def HasField(self, field_name: typing.Literal["_curve_a", b"_curve_a", "curve_a", b"curve_a", "mod", b"mod", "x", b"x", "y", b"y"]) -> builtins.bool: ...
+ def ClearField(self, field_name: typing.Literal["_curve_a", b"_curve_a", "curve_a", b"curve_a", "mod", b"mod", "x", b"x", "y", b"y"]) -> None: ...
+ def WhichOneof(self, oneof_group: typing.Literal["_curve_a", b"_curve_a"]) -> typing.Literal["curve_a"] | None: ...
global___ECPoint = ECPoint
diff --git a/qualtran/protos/registers_pb2.pyi b/qualtran/protos/registers_pb2.pyi
index e51a9bf096..b3e3f1823b 100644
--- a/qualtran/protos/registers_pb2.pyi
+++ b/qualtran/protos/registers_pb2.pyi
@@ -19,19 +19,13 @@ limitations under the License.
import builtins
import collections.abc
+import typing
import google.protobuf.descriptor
import google.protobuf.internal.containers
import google.protobuf.internal.enum_type_wrapper
import google.protobuf.message
import qualtran.protos.args_pb2
import qualtran.protos.data_types_pb2
-import sys
-import typing
-
-if sys.version_info >= (3, 10):
- import typing as typing_extensions
-else:
- import typing_extensions
DESCRIPTOR: google.protobuf.descriptor.FileDescriptor
@@ -41,7 +35,7 @@ class Register(google.protobuf.message.Message):
class _Side:
ValueType = typing.NewType("ValueType", builtins.int)
- V: typing_extensions.TypeAlias = ValueType
+ V: typing.TypeAlias = ValueType
class _SideEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[Register._Side.ValueType], builtins.type):
DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor
diff --git a/qualtran/protos/sympy_pb2.pyi b/qualtran/protos/sympy_pb2.pyi
index 868aae3c3f..48931283ec 100644
--- a/qualtran/protos/sympy_pb2.pyi
+++ b/qualtran/protos/sympy_pb2.pyi
@@ -19,23 +19,17 @@ limitations under the License.
import builtins
import collections.abc
+import typing
import google.protobuf.descriptor
import google.protobuf.internal.containers
import google.protobuf.internal.enum_type_wrapper
import google.protobuf.message
-import sys
-import typing
-
-if sys.version_info >= (3, 10):
- import typing as typing_extensions
-else:
- import typing_extensions
DESCRIPTOR: google.protobuf.descriptor.FileDescriptor
class _Function:
ValueType = typing.NewType("ValueType", builtins.int)
- V: typing_extensions.TypeAlias = ValueType
+ V: typing.TypeAlias = ValueType
class _FunctionEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_Function.ValueType], builtins.type):
DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor
@@ -81,7 +75,7 @@ global___Function = Function
class _ConstSymbol:
ValueType = typing.NewType("ValueType", builtins.int)
- V: typing_extensions.TypeAlias = ValueType
+ V: typing.TypeAlias = ValueType
class _ConstSymbolEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_ConstSymbol.ValueType], builtins.type):
DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor
diff --git a/qualtran/qref_interop/_bloq_to_qref.py b/qualtran/qref_interop/_bloq_to_qref.py
index aab3422ba1..0480a6335e 100644
--- a/qualtran/qref_interop/_bloq_to_qref.py
+++ b/qualtran/qref_interop/_bloq_to_qref.py
@@ -24,8 +24,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+from collections.abc import Iterable
from functools import singledispatch
-from typing import Any, cast, Iterable, Optional, Union
+from typing import Any, cast, Optional, Union
import networkx as nx
import sympy
diff --git a/qualtran/resource_counting/_bloq_counts.py b/qualtran/resource_counting/_bloq_counts.py
index 3ed9a4a10a..1c680a2232 100644
--- a/qualtran/resource_counting/_bloq_counts.py
+++ b/qualtran/resource_counting/_bloq_counts.py
@@ -14,7 +14,8 @@
import logging
import warnings
from collections import defaultdict
-from typing import Callable, cast, Dict, Sequence, Tuple, TYPE_CHECKING
+from collections.abc import Callable, Sequence
+from typing import cast, TYPE_CHECKING
import attrs
import networkx as nx
@@ -38,10 +39,10 @@
logger = logging.getLogger(__name__)
-BloqCountDict = Dict['Bloq', int]
+BloqCountDict = dict['Bloq', int]
-def _gateset_bloqs_to_tuple(bloqs: Sequence['Bloq']) -> Tuple['Bloq', ...]:
+def _gateset_bloqs_to_tuple(bloqs: Sequence['Bloq']) -> tuple['Bloq', ...]:
return tuple(bloqs)
@@ -74,7 +75,7 @@ def for_gateset(cls, gateset_name: str):
"""
from qualtran.bloqs.basic_gates import TGate, Toffoli, TwoBitCSwap
- bloqs: Tuple['Bloq', ...]
+ bloqs: tuple['Bloq', ...]
if gateset_name == 't':
bloqs = (TGate(), TGate(is_adjoint=True))
elif gateset_name == 't+tof':
@@ -172,7 +173,7 @@ def __str__(self):
return ', '.join(strs)
return '-'
- def asdict(self) -> Dict[str, int]:
+ def asdict(self) -> dict[str, int]:
d = attrs.asdict(self)
def _is_nonzero(v):
@@ -206,7 +207,7 @@ def total_t_count(
+ ts_per_rotation * self.rotation
)
- def total_t_and_ccz_count(self, ts_per_rotation: int = 11) -> Dict[str, SymbolicInt]:
+ def total_t_and_ccz_count(self, ts_per_rotation: int = 11) -> dict[str, SymbolicInt]:
n_ccz = self.toffoli + self.cswap + self.and_bloq
n_t = self.t + ts_per_rotation * self.rotation
return {'n_t': n_t, 'n_ccz': n_ccz}
@@ -257,7 +258,7 @@ def to_legacy_t_complexity(
+ cliffords_per_cswap * self.cswap,
)
- def total_beverland_count(self) -> Dict[str, SymbolicInt]:
+ def total_beverland_count(self) -> dict[str, SymbolicInt]:
r"""Counts used by Beverland et al. using notation from the reference.
- $M_\mathrm{meas}$ is the number of measurements.
diff --git a/qualtran/resource_counting/_call_graph.py b/qualtran/resource_counting/_call_graph.py
index 8c1a6debd8..79ebebe0bd 100644
--- a/qualtran/resource_counting/_call_graph.py
+++ b/qualtran/resource_counting/_call_graph.py
@@ -14,30 +14,17 @@
"""Functionality for the `Bloq.call_graph()` protocol."""
-import collections.abc
import warnings
from collections import defaultdict
-from typing import (
- Callable,
- cast,
- Dict,
- Iterable,
- List,
- Mapping,
- MutableMapping,
- Optional,
- Sequence,
- Set,
- Tuple,
- Union,
-)
+from collections.abc import Callable, Iterable, Mapping, MutableMapping, Sequence
+from typing import cast, Optional, Union
import networkx as nx
import sympy
from qualtran import Bloq, CompositeBloq, DecomposeNotImplementedError, DecomposeTypeError
-BloqCountT = Tuple[Bloq, Union[int, sympy.Expr]]
+BloqCountT = tuple[Bloq, Union[int, sympy.Expr]]
BloqCountDictT = Mapping[Bloq, Union[int, sympy.Expr]]
MutableBloqCountDictT = MutableMapping[Bloq, Union[int, sympy.Expr]]
from ._generalization import _make_composite_generalizer, GeneralizerT
@@ -60,7 +47,7 @@ class SympySymbolAllocator:
"""
def __init__(self):
- self._idxs: Dict[str, int] = defaultdict(lambda: 0)
+ self._idxs: dict[str, int] = defaultdict(lambda: 0)
def new_symbol(self, prefix: str) -> sympy.Symbol:
"""Return a unique symbol beginning with _prefix."""
@@ -77,7 +64,7 @@ def build_cbloq_call_graph(cbloq: CompositeBloq) -> BloqCountDictT:
Args:
cbloq: The composite bloq.
"""
- counts: Dict[Bloq, int] = defaultdict(lambda: 0)
+ counts: dict[Bloq, int] = defaultdict(lambda: 0)
for binst in cbloq.bloq_instances:
counts[binst.bloq] += 1
@@ -85,14 +72,14 @@ def build_cbloq_call_graph(cbloq: CompositeBloq) -> BloqCountDictT:
def _generalize_callees(
- raw_callee_counts: Union[BloqCountDictT, Set[BloqCountT]], generalizer: GeneralizerT
-) -> List[BloqCountT]:
+ raw_callee_counts: Union[BloqCountDictT, set[BloqCountT]], generalizer: GeneralizerT
+) -> list[BloqCountT]:
"""Apply `generalizer` to the results of `bloq.build_call_graph`.
This calls `generalizer` on each of the callees returned from that function,
and filters out cases where `generalizer` returns `None`.
"""
- callee_counts: Dict[Bloq, Union[int, sympy.Expr]] = defaultdict(lambda: 0)
+ callee_counts: dict[Bloq, Union[int, sympy.Expr]] = defaultdict(lambda: 0)
if isinstance(raw_callee_counts, set):
raw_callee_iterator: Iterable[BloqCountT] = raw_callee_counts
warnings.warn(
@@ -116,7 +103,7 @@ def get_bloq_callee_counts(
generalizer: Optional[Union['GeneralizerT', Sequence['GeneralizerT']]] = None,
ssa: Optional[SympySymbolAllocator] = None,
ignore_decomp_failure: bool = True,
-) -> List[BloqCountT]:
+) -> list[BloqCountT]:
"""Get the direct callees of a bloq and the number of times they are called.
This calls `bloq.build_call_graph()` with the correct configuration options.
@@ -203,9 +190,9 @@ def _build_call_graph(
g.add_edge(bloq, callee, n=n)
-def _compute_sigma(root_bloq: Bloq, g: nx.DiGraph) -> Dict[Bloq, Union[int, sympy.Expr]]:
+def _compute_sigma(root_bloq: Bloq, g: nx.DiGraph) -> dict[Bloq, Union[int, sympy.Expr]]:
"""Iterate over nodes to sum up the counts of leaf bloqs."""
- bloq_sigmas: Dict[Bloq, Dict[Bloq, Union[int, sympy.Expr]]] = defaultdict(
+ bloq_sigmas: dict[Bloq, dict[Bloq, Union[int, sympy.Expr]]] = defaultdict(
lambda: defaultdict(lambda: 0)
)
for bloq in reversed(list(nx.topological_sort(g))):
@@ -232,7 +219,7 @@ def get_bloq_call_graph(
ssa: Optional[SympySymbolAllocator] = None,
keep: Optional[Callable[[Bloq], bool]] = None,
max_depth: Optional[int] = None,
-) -> Tuple[nx.DiGraph, Dict[Bloq, Union[int, sympy.Expr]]]:
+) -> tuple[nx.DiGraph, dict[Bloq, Union[int, sympy.Expr]]]:
"""Recursively build the bloq call graph and call totals.
See `Bloq.call_graph()` as a convenient way of calling this function.
@@ -263,7 +250,7 @@ def get_bloq_call_graph(
keep = lambda b: False
if generalizer is None:
generalizer = lambda b: b
- if isinstance(generalizer, collections.abc.Sequence):
+ if isinstance(generalizer, Sequence):
generalizer = _make_composite_generalizer(*generalizer)
g = nx.DiGraph()
diff --git a/qualtran/resource_counting/_call_graph_test.py b/qualtran/resource_counting/_call_graph_test.py
index af540e50c0..ac5ff11181 100644
--- a/qualtran/resource_counting/_call_graph_test.py
+++ b/qualtran/resource_counting/_call_graph_test.py
@@ -13,8 +13,9 @@
# limitations under the License.
from collections import defaultdict
+from collections.abc import Iterable, Sequence
from functools import cached_property
-from typing import Dict, Iterable, Optional, Sequence, Tuple
+from typing import Optional
import attrs
import networkx as nx
@@ -58,7 +59,7 @@ class DecompBloq(Bloq):
def signature(self) -> 'Signature':
return Signature.build(x=self.bitsize)
- def build_composite_bloq(self, bb: 'BloqBuilder', x: 'Soquet') -> Dict[str, 'SoquetT']:
+ def build_composite_bloq(self, bb: 'BloqBuilder', x: 'Soquet') -> dict[str, 'SoquetT']:
qs = bb.split(x)
for i in range(self.bitsize):
qs[i] = bb.add(SubBloq(unrelated_param=i / 12), q=qs[i])
@@ -78,7 +79,7 @@ def build_call_graph(self, ssa: 'SympySymbolAllocator') -> 'BloqCountDictT':
return {TGate(): 3}
-def get_big_bloq_counts_graph_1(bloq: Bloq) -> Tuple[nx.DiGraph, Dict[Bloq, SymbolicInt]]:
+def get_big_bloq_counts_graph_1(bloq: Bloq) -> tuple[nx.DiGraph, dict[Bloq, SymbolicInt]]:
ss = SympySymbolAllocator()
n_c = ss.new_symbol('n_c')
diff --git a/qualtran/resource_counting/_costing.py b/qualtran/resource_counting/_costing.py
index 4200b0acad..627b49dedb 100644
--- a/qualtran/resource_counting/_costing.py
+++ b/qualtran/resource_counting/_costing.py
@@ -13,21 +13,11 @@
# limitations under the License.
import abc
-import collections
import logging
import time
from collections import defaultdict
-from typing import (
- Callable,
- Dict,
- Generic,
- Iterable,
- Optional,
- Sequence,
- TYPE_CHECKING,
- TypeVar,
- Union,
-)
+from collections.abc import Callable, Iterable, Sequence
+from typing import Generic, Optional, TYPE_CHECKING, TypeVar, Union
from qualtran import CompositeBloq
@@ -102,7 +92,7 @@ def _get_cost_value(
bloq: 'Bloq',
cost_key: CostKey[CostValT],
*,
- costs_cache: Dict['Bloq', CostValT],
+ costs_cache: dict['Bloq', CostValT],
generalizer: 'GeneralizerT',
) -> CostValT:
"""Helper function for getting costs.
@@ -154,7 +144,7 @@ def _get_cost_val_internal(callee: 'Bloq'):
def get_cost_value(
bloq: 'Bloq',
cost_key: CostKey[CostValT],
- costs_cache: Optional[Dict['Bloq', CostValT]] = None,
+ costs_cache: Optional[dict['Bloq', CostValT]] = None,
generalizer: Optional[Union['GeneralizerT', Sequence['GeneralizerT']]] = None,
) -> CostValT:
"""Compute the specified cost of the provided bloq.
@@ -177,7 +167,7 @@ def get_cost_value(
costs_cache = {}
if generalizer is None:
generalizer = lambda b: b
- if isinstance(generalizer, collections.abc.Sequence):
+ if isinstance(generalizer, Sequence):
generalizer = _make_composite_generalizer(*generalizer)
cost_val = _get_cost_value(bloq, cost_key, costs_cache=costs_cache, generalizer=generalizer)
@@ -187,9 +177,9 @@ def get_cost_value(
def get_cost_cache(
bloq: 'Bloq',
cost_key: CostKey[CostValT],
- costs_cache: Optional[Dict['Bloq', CostValT]] = None,
+ costs_cache: Optional[dict['Bloq', CostValT]] = None,
generalizer: Optional[Union['GeneralizerT', Sequence['GeneralizerT']]] = None,
-) -> Dict['Bloq', CostValT]:
+) -> dict['Bloq', CostValT]:
"""Build a cache of cost values for the bloq and its callees.
This can be useful to inspect how callees' costs flow upwards in a given cost computation.
@@ -214,7 +204,7 @@ def get_cost_cache(
costs_cache = {}
if generalizer is None:
generalizer = lambda b: b
- if isinstance(generalizer, collections.abc.Sequence):
+ if isinstance(generalizer, Sequence):
generalizer = _make_composite_generalizer(*generalizer)
_get_cost_value(bloq, cost_key, costs_cache=costs_cache, generalizer=generalizer)
@@ -225,7 +215,7 @@ def query_costs(
bloq: 'Bloq',
cost_keys: Iterable[CostKey],
generalizer: Optional[Union['GeneralizerT', Sequence['GeneralizerT']]] = None,
-) -> Dict['Bloq', Dict[CostKey, CostValT]]:
+) -> dict['Bloq', dict[CostKey, CostValT]]:
"""Compute a selection of costs for a bloq and its callees.
This function can be used to annotate a call graph diagram with multiple costs
@@ -244,7 +234,7 @@ def query_costs(
A dictionary of dictionaries forming a table of multiple costs for multiple bloqs.
This is indexed by bloq, then cost key.
"""
- costs: Dict['Bloq', Dict[CostKey, CostValT]] = defaultdict(dict)
+ costs: dict['Bloq', dict[CostKey, CostValT]] = defaultdict(dict)
for cost_key in cost_keys:
cost_for_bloqs = get_cost_cache(bloq, cost_key, generalizer=generalizer)
for bloq, val in cost_for_bloqs.items():
diff --git a/qualtran/resource_counting/_costing_test.py b/qualtran/resource_counting/_costing_test.py
index 9ea0f97d2b..f7bb601b7c 100644
--- a/qualtran/resource_counting/_costing_test.py
+++ b/qualtran/resource_counting/_costing_test.py
@@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-from typing import Callable, List
+from collections.abc import Callable
import attrs
@@ -31,7 +31,7 @@
class TestCostKey(CostKey[int]):
def __init__(self):
# For testing, keep a log of all the bloqs for which we called 'compute' on.
- self._log: List[Bloq] = []
+ self._log: list[Bloq] = []
def compute(self, bloq: 'Bloq', get_callee_cost: Callable[['Bloq'], int]) -> int:
self._log.append(bloq)
diff --git a/qualtran/resource_counting/_generalization.py b/qualtran/resource_counting/_generalization.py
index 67b8fee061..a6aa3bdc02 100644
--- a/qualtran/resource_counting/_generalization.py
+++ b/qualtran/resource_counting/_generalization.py
@@ -11,7 +11,8 @@
# 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.
-from typing import Callable, Optional, TYPE_CHECKING
+from collections.abc import Callable
+from typing import Optional, TYPE_CHECKING
if TYPE_CHECKING:
from qualtran import Bloq
diff --git a/qualtran/resource_counting/_qubit_counts.py b/qualtran/resource_counting/_qubit_counts.py
index cfa748073e..bb7a4ee31c 100644
--- a/qualtran/resource_counting/_qubit_counts.py
+++ b/qualtran/resource_counting/_qubit_counts.py
@@ -13,7 +13,7 @@
# limitations under the License.
import logging
-from typing import Callable, Set
+from collections.abc import Callable
import networkx as nx
from attrs import frozen
@@ -51,7 +51,7 @@ def _cbloq_max_width(
independently.
"""
max_width: SymbolicInt = 0
- in_play: Set[Connection] = set()
+ in_play: set[Connection] = set()
for cc in nx.weakly_connected_components(binst_graph):
for binst in greedy_topological_sort(binst_graph.subgraph(cc)):
diff --git a/qualtran/resource_counting/_success_prob.py b/qualtran/resource_counting/_success_prob.py
index 4aab783bdd..9f94aaa9d1 100644
--- a/qualtran/resource_counting/_success_prob.py
+++ b/qualtran/resource_counting/_success_prob.py
@@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import logging
-from typing import Callable
+from collections.abc import Callable
from attrs import frozen
diff --git a/qualtran/resource_counting/classify_bloqs.py b/qualtran/resource_counting/classify_bloqs.py
index b6016e8f06..f56e17b659 100644
--- a/qualtran/resource_counting/classify_bloqs.py
+++ b/qualtran/resource_counting/classify_bloqs.py
@@ -13,7 +13,8 @@
# limitations under the License.
import collections.abc as abc
from collections import defaultdict
-from typing import cast, Dict, List, Optional, Sequence, TYPE_CHECKING, Union
+from collections.abc import Sequence
+from typing import cast, Optional, TYPE_CHECKING, Union
import numpy as np
import sympy
@@ -30,7 +31,7 @@
from qualtran.resource_counting import GeneralizerT
-def _get_basic_bloq_classification() -> Dict[str, str]:
+def _get_basic_bloq_classification() -> dict[str, str]:
"""High level classification of bloqs by the module name."""
bloq_classifier = {
'qualtran.bloqs.arithmetic': 'arithmetic',
@@ -49,7 +50,7 @@ def _get_basic_bloq_classification() -> Dict[str, str]:
return bloq_classifier
-def classify_bloq(bloq: Bloq, bloq_classification: Dict[str, str]) -> str:
+def classify_bloq(bloq: Bloq, bloq_classification: dict[str, str]) -> str:
"""Classify a bloq given a bloq_classification.
Args:
@@ -71,9 +72,9 @@ def classify_bloq(bloq: Bloq, bloq_classification: Dict[str, str]) -> str:
def classify_t_count_by_bloq_type(
bloq: Bloq,
- bloq_classification: Optional[Dict[str, str]] = None,
+ bloq_classification: Optional[dict[str, str]] = None,
generalizer: Optional[Union['GeneralizerT', Sequence['GeneralizerT']]] = None,
-) -> Dict[str, Union[int, sympy.Expr]]:
+) -> dict[str, Union[int, sympy.Expr]]:
"""Classify (bin) the T count of a bloq's call graph by type of operation.
Args:
@@ -92,7 +93,7 @@ def classify_t_count_by_bloq_type(
if bloq_classification is None:
bloq_classification = _get_basic_bloq_classification()
keeper = lambda bloq: classify_bloq(bloq, bloq_classification) != 'other'
- basic_generalizer: List['GeneralizerT'] = [
+ basic_generalizer: list['GeneralizerT'] = [
ignore_split_join,
ignore_alloc_free,
ignore_cliffords,
@@ -103,7 +104,7 @@ def classify_t_count_by_bloq_type(
else:
basic_generalizer.append(generalizer)
_, sigma = bloq.call_graph(generalizer=basic_generalizer, keep=keeper)
- classified_bloqs: Dict[str, Union[int, sympy.Expr]] = defaultdict(int)
+ classified_bloqs: dict[str, Union[int, sympy.Expr]] = defaultdict(int)
for k, v in sigma.items():
classification = classify_bloq(k, bloq_classification)
t_counts = get_cost_value(k, QECGatesCost()).total_t_count()
diff --git a/qualtran/resource_counting/classify_bloqs_test.py b/qualtran/resource_counting/classify_bloqs_test.py
index 753a8c2c3b..5e671c7800 100644
--- a/qualtran/resource_counting/classify_bloqs_test.py
+++ b/qualtran/resource_counting/classify_bloqs_test.py
@@ -12,7 +12,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from functools import cached_property
-from typing import Tuple
import attrs
import numpy as np
@@ -50,7 +49,7 @@
class TestBundleOfBloqs(Bloq):
"""A fake bloq which just defines a call graph"""
- bloqs: Tuple[BloqCountT, ...]
+ bloqs: tuple[BloqCountT, ...]
@cached_property
def signature(self) -> 'Signature':
diff --git a/qualtran/resource_counting/generalizers.py b/qualtran/resource_counting/generalizers.py
index 4948411d90..ec5f2b2595 100644
--- a/qualtran/resource_counting/generalizers.py
+++ b/qualtran/resource_counting/generalizers.py
@@ -19,7 +19,8 @@
into one, more general bloq. The functions in this module can be used as generalizers
for this argument.
"""
-from typing import Callable, Optional
+from collections.abc import Callable
+from typing import Optional
import attrs
import sympy
diff --git a/qualtran/resource_counting/t_counts_from_sigma.py b/qualtran/resource_counting/t_counts_from_sigma.py
index eb4578e362..0e8367eb0f 100644
--- a/qualtran/resource_counting/t_counts_from_sigma.py
+++ b/qualtran/resource_counting/t_counts_from_sigma.py
@@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import warnings
-from typing import Mapping
+from collections.abc import Mapping
from qualtran import Bloq, Controlled
from qualtran.symbolics import ceil, SymbolicInt
diff --git a/qualtran/serialization/bloq.py b/qualtran/serialization/bloq.py
index 132930b280..d9a3781275 100644
--- a/qualtran/serialization/bloq.py
+++ b/qualtran/serialization/bloq.py
@@ -14,7 +14,8 @@
import dataclasses
import inspect
-from typing import Any, Callable, Dict, List, Optional, Tuple, Union
+from collections.abc import Callable
+from typing import Any, Optional, Union
import attrs
import cirq
@@ -82,7 +83,7 @@ def arg_to_proto(*, name: str, val: Any) -> bloq_pb2.BloqArg:
raise ValueError(f"Cannot serialize {val} of unknown type {type(val)}")
-def arg_from_proto(arg: bloq_pb2.BloqArg) -> Dict[str, Any]:
+def arg_from_proto(arg: bloq_pb2.BloqArg) -> dict[str, Any]:
if arg.HasField("int_val"):
return {arg.name: arg.int_val}
if arg.HasField("float_val"):
@@ -112,10 +113,10 @@ def arg_from_proto(arg: bloq_pb2.BloqArg) -> Dict[str, Any]:
class _BloqLibDeserializer:
def __init__(self, lib: bloq_pb2.BloqLibrary):
- self.id_to_proto: Dict[int, bloq_pb2.BloqLibrary.BloqWithDecomposition] = {
+ self.id_to_proto: dict[int, bloq_pb2.BloqLibrary.BloqWithDecomposition] = {
b.bloq_id: b for b in lib.table
}
- self.id_to_bloq: Dict[int, Bloq] = {}
+ self.id_to_bloq: dict[int, Bloq] = {}
self.dangling_to_singleton = {"LeftDangle": LeftDangle, "RightDangle": RightDangle}
def bloq_id_to_bloq(self, bloq_id: int):
@@ -169,7 +170,7 @@ def _soquet_from_proto(self, soq: bloq_pb2.Soquet) -> Soquet:
)
-def bloqs_from_proto(lib: bloq_pb2.BloqLibrary) -> List[Bloq]:
+def bloqs_from_proto(lib: bloq_pb2.BloqLibrary) -> list[Bloq]:
"""Deserializes a BloqLibrary as a list of Bloqs."""
deserializer = _BloqLibDeserializer(lib)
return [deserializer.bloq_id_to_bloq(bloq.bloq_id) for bloq in lib.table]
@@ -200,7 +201,7 @@ def bloqs_to_proto(
# Set up this mapping and populate it by recursively searching for subbloqs.
# Each value is an (id: bool, shallow: bool) tuple, where the second entry can be set to
# `True` for bloqs that need to be referred to but do not need a full serialization.
- bloq_to_id_ext: Dict[Bloq, Tuple[int, bool]] = {}
+ bloq_to_id_ext: dict[Bloq, tuple[int, bool]] = {}
for bloq in bloqs:
_assign_bloq_an_id(bloq, bloq_to_id_ext, shallow=True)
_search_for_subbloqs(bloq, bloq_to_id_ext, pred, max_depth)
@@ -267,13 +268,13 @@ def _iter_fields(bloq: Bloq):
yield field
-def _connection_to_proto(cxn: Connection, bloq_to_id: Dict[Bloq, int]):
+def _connection_to_proto(cxn: Connection, bloq_to_id: dict[Bloq, int]):
return bloq_pb2.Connection(
left=_soquet_to_proto(cxn.left, bloq_to_id), right=_soquet_to_proto(cxn.right, bloq_to_id)
)
-def _soquet_to_proto(soq: Soquet, bloq_to_id: Dict[Bloq, int]) -> bloq_pb2.Soquet:
+def _soquet_to_proto(soq: Soquet, bloq_to_id: dict[Bloq, int]) -> bloq_pb2.Soquet:
if isinstance(soq.binst, DanglingT):
return bloq_pb2.Soquet(
dangling_t=repr(soq.binst), register=registers.register_to_proto(soq.reg), index=soq.idx
@@ -287,12 +288,12 @@ def _soquet_to_proto(soq: Soquet, bloq_to_id: Dict[Bloq, int]) -> bloq_pb2.Soque
def _bloq_instance_to_proto(
- binst: BloqInstance, bloq_to_id: Dict[Bloq, int]
+ binst: BloqInstance, bloq_to_id: dict[Bloq, int]
) -> bloq_pb2.BloqInstance:
return bloq_pb2.BloqInstance(instance_id=binst.i, bloq_id=bloq_to_id[binst.bloq])
-def _assign_bloq_an_id(bloq: Bloq, bloq_to_id: Dict[Bloq, Tuple[int, bool]], shallow: bool = False):
+def _assign_bloq_an_id(bloq: Bloq, bloq_to_id: dict[Bloq, tuple[int, bool]], shallow: bool = False):
"""Assigns a new index for `bloq` and records it into the `bloq_to_id` mapping."""
if bloq in bloq_to_id:
# Keep the same id, but if anyone requests a non-shallow serialization; do it.
@@ -303,7 +304,7 @@ def _assign_bloq_an_id(bloq: Bloq, bloq_to_id: Dict[Bloq, Tuple[int, bool]], sha
bloq_to_id[bloq] = next_idx, shallow
-def _cbloq_ordered_bloq_instances(cbloq: CompositeBloq) -> List[BloqInstance]:
+def _cbloq_ordered_bloq_instances(cbloq: CompositeBloq) -> list[BloqInstance]:
"""Equivalent to `cbloq.bloq_instances`, but preserves insertion order among bloq instances."""
ret = {}
for cxn in cbloq.connections:
@@ -315,7 +316,7 @@ def _cbloq_ordered_bloq_instances(cbloq: CompositeBloq) -> List[BloqInstance]:
def _search_for_subbloqs(
bloq: Bloq,
- bloq_to_id: Dict[Bloq, Tuple[int, bool]],
+ bloq_to_id: dict[Bloq, tuple[int, bool]],
pred: Callable[[BloqInstance], bool],
max_depth: int,
) -> None:
@@ -372,7 +373,7 @@ def _search_for_subbloqs(
def _bloq_to_proto(
- bloq: Bloq, *, bloq_to_id: Dict[Bloq, int], shallow: bool = False
+ bloq: Bloq, *, bloq_to_id: dict[Bloq, int], shallow: bool = False
) -> bloq_pb2.Bloq:
if shallow:
t_complexity = None
@@ -392,8 +393,8 @@ def _bloq_to_proto(
def _bloq_args_to_proto(
- bloq: Bloq, *, bloq_to_id: Dict[Bloq, int]
-) -> Optional[List[bloq_pb2.BloqArg]]:
+ bloq: Bloq, *, bloq_to_id: dict[Bloq, int]
+) -> Optional[list[bloq_pb2.BloqArg]]:
if isinstance(bloq, CompositeBloq):
return None
@@ -405,7 +406,7 @@ def _bloq_args_to_proto(
return ret if ret else None
-def _bloq_arg_to_proto(name: str, val: Any, bloq_to_id: Dict[Bloq, int]) -> bloq_pb2.BloqArg:
+def _bloq_arg_to_proto(name: str, val: Any, bloq_to_id: dict[Bloq, int]) -> bloq_pb2.BloqArg:
if isinstance(val, Bloq):
return bloq_pb2.BloqArg(name=name, subbloq=bloq_to_id[val])
return arg_to_proto(name=name, val=val)
diff --git a/qualtran/serialization/registers.py b/qualtran/serialization/registers.py
index 8f449a4877..9e47fae330 100644
--- a/qualtran/serialization/registers.py
+++ b/qualtran/serialization/registers.py
@@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-from typing import Iterable, Tuple
+from collections.abc import Iterable
from qualtran import Register, Side
from qualtran.protos import registers_pb2
@@ -24,7 +24,7 @@ def registers_to_proto(registers: Iterable[Register]) -> registers_pb2.Registers
return registers_pb2.Registers(registers=[register_to_proto(reg) for reg in registers])
-def registers_from_proto(registers: registers_pb2.Registers) -> Tuple[Register, ...]:
+def registers_from_proto(registers: registers_pb2.Registers) -> tuple[Register, ...]:
return tuple(register_from_proto(reg) for reg in registers.registers)
diff --git a/qualtran/serialization/sympy_to_proto.py b/qualtran/serialization/sympy_to_proto.py
index 277f88a625..fd91df0878 100644
--- a/qualtran/serialization/sympy_to_proto.py
+++ b/qualtran/serialization/sympy_to_proto.py
@@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-from typing import Any, cast, Dict, Union
+from typing import Any, cast, Union
import sympy
import sympy.codegen.cfunctions
@@ -63,7 +63,7 @@ def _get_sympy_function_from_enum(enum: int) -> Any:
Sympy functions are represented as a sympy_pb2.Function enum. This method converts
this int enum.
"""
- enum_to_sympy: Dict[int, Any] = {
+ enum_to_sympy: dict[int, Any] = {
sympy_pb2.Function.Mul: sympy.core.mul.Mul,
sympy_pb2.Function.Add: sympy.core.add.Add,
sympy_pb2.Function.Pow: sympy.core.power.Pow,
@@ -89,7 +89,7 @@ def _get_sympy_const_from_enum(enum: int) -> Any:
Symbolic constants are serialzed as an enum of type sympy_pb2.ConstSymbol. This method converts the
enum representation back to its original sympy representation.
"""
- enum_to_sympy: Dict[int, Any] = {
+ enum_to_sympy: dict[int, Any] = {
sympy_pb2.ConstSymbol.Pi: sympy.pi,
sympy_pb2.ConstSymbol.E: sympy.E,
sympy_pb2.ConstSymbol.EulerGamma: sympy.EulerGamma,
diff --git a/qualtran/simulation/classical_sim.py b/qualtran/simulation/classical_sim.py
index 927c93e00a..546f263dfe 100644
--- a/qualtran/simulation/classical_sim.py
+++ b/qualtran/simulation/classical_sim.py
@@ -14,19 +14,8 @@
"""Functionality for the `Bloq.call_classically(...)` protocol."""
import itertools
-from typing import (
- Any,
- Dict,
- Iterable,
- List,
- Mapping,
- Optional,
- Sequence,
- Tuple,
- Type,
- TYPE_CHECKING,
- Union,
-)
+from collections.abc import Iterable, Mapping, Sequence
+from typing import Any, Optional, Type, TYPE_CHECKING, Union
import networkx as nx
import numpy as np
@@ -92,7 +81,7 @@ def _empty_ndarray_from_reg(reg: Register) -> np.ndarray:
def _get_in_vals(
- binst: Union[DanglingT, BloqInstance], reg: Register, soq_assign: Dict[Soquet, ClassicalValT]
+ binst: Union[DanglingT, BloqInstance], reg: Register, soq_assign: dict[Soquet, ClassicalValT]
) -> ClassicalValT:
"""Pluck out the correct values from `soq_assign` for `reg` on `binst`."""
if not reg.shape:
@@ -144,7 +133,7 @@ def __init__(
self._binst_iter = nx.topological_sort(self._binst_graph)
# Keep track of each soquet's bit array. Initialize with LeftDangle
- self.soq_assign: Dict[Soquet, ClassicalValT] = {}
+ self.soq_assign: dict[Soquet, ClassicalValT] = {}
self._update_assign_from_vals(self._signature.lefts(), LeftDangle, dict(vals))
self.last_binst: Optional['BloqInstance'] = None
@@ -170,7 +159,7 @@ def _update_assign_from_vals(
self,
regs: Iterable[Register],
binst: Union[DanglingT, BloqInstance],
- vals: Union[Dict[str, Union[sympy.Symbol, ClassicalValT]], Dict[str, ClassicalValT]],
+ vals: Union[dict[str, Union[sympy.Symbol, ClassicalValT]], dict[str, ClassicalValT]],
) -> None:
"""Update `self.soq_assign` using `vals`.
@@ -265,7 +254,7 @@ def _in_vals(reg: Register):
self._binst_basis_state_phase(binst, in_vals)
return self
- def finalize(self) -> Dict[str, 'ClassicalValT']:
+ def finalize(self) -> dict[str, 'ClassicalValT']:
"""Finish simulating a composite bloq and extract final values.
Returns:
@@ -289,7 +278,7 @@ def _f_vals(reg: Register):
final_vals = {reg.name: _f_vals(reg) for reg in self._signature.rights()}
return final_vals
- def simulate(self) -> Dict[str, 'ClassicalValT']:
+ def simulate(self) -> dict[str, 'ClassicalValT']:
"""Simulate the composite bloq and return the final values."""
try:
while True:
@@ -371,7 +360,7 @@ def call_cbloq_classically(
signature: Signature,
vals: Mapping[str, Union[sympy.Symbol, ClassicalValT]],
binst_graph: nx.DiGraph,
-) -> Tuple[Dict[str, ClassicalValT], Dict[Soquet, ClassicalValT]]:
+) -> tuple[dict[str, ClassicalValT], dict[Soquet, ClassicalValT]]:
"""Propagate `on_classical_vals` calls through a composite bloq's contents.
While we're handling the plumbing, we also do error checking on the arguments; see
@@ -422,7 +411,7 @@ def do_phased_classical_simulation(bloq: 'Bloq', vals: Mapping[str, 'ClassicalVa
def get_classical_truth_table(
bloq: 'Bloq',
-) -> Tuple[List[str], List[str], List[Tuple[Sequence[Any], Sequence[Any]]]]:
+) -> tuple[list[str], list[str], list[tuple[Sequence[Any], Sequence[Any]]]]:
"""Get a 'truth table' for a classical-reversible bloq.
Args:
@@ -441,14 +430,14 @@ def get_classical_truth_table(
if reg.shape:
raise NotImplementedError()
- in_names: List[str] = []
+ in_names: list[str] = []
iters = []
for reg in bloq.signature.lefts():
in_names.append(reg.name)
iters.append(reg.dtype.get_classical_domain())
- out_names: List[str] = [reg.name for reg in bloq.signature.rights()]
+ out_names: list[str] = [reg.name for reg in bloq.signature.rights()]
- truth_table: List[Tuple[Sequence[Any], Sequence[Any]]] = []
+ truth_table: list[tuple[Sequence[Any], Sequence[Any]]] = []
for in_val_tuple in itertools.product(*iters):
in_val_d = {name: val for name, val in zip(in_names, in_val_tuple)}
out_val_tuple = bloq.call_classically(**in_val_d)
@@ -460,7 +449,7 @@ def get_classical_truth_table(
def format_classical_truth_table(
in_names: Sequence[str],
out_names: Sequence[str],
- truth_table: Sequence[Tuple[Sequence[Any], Sequence[Any]]],
+ truth_table: Sequence[tuple[Sequence[Any], Sequence[Any]]],
) -> str:
"""Get a formatted tabular representation of the classical truth table."""
heading = ' '.join(in_names) + ' | ' + ' '.join(out_names) + '\n'
diff --git a/qualtran/simulation/classical_sim_test.py b/qualtran/simulation/classical_sim_test.py
index 582f5057a1..4e4ef8e80a 100644
--- a/qualtran/simulation/classical_sim_test.py
+++ b/qualtran/simulation/classical_sim_test.py
@@ -13,7 +13,6 @@
# limitations under the License.
import itertools
-from typing import Dict
import networkx as nx
import numpy as np
@@ -93,7 +92,7 @@ def signature(self) -> 'Signature':
[Register('x', QBit(), shape=(5,)), Register('z', QBit(), shape=(5,), side=Side.RIGHT)]
)
- def on_classical_vals(self, *, x: NDArray[np.uint8]) -> Dict[str, NDArray[np.uint8]]:
+ def on_classical_vals(self, *, x: NDArray[np.uint8]) -> dict[str, NDArray[np.uint8]]:
const = np.array([1, 0, 1, 0, 1], dtype=np.uint8)
z = np.logical_xor(x, const).astype(np.uint8)
return {'x': x, 'z': z}
diff --git a/qualtran/simulation/tensor/_dense.py b/qualtran/simulation/tensor/_dense.py
index f4e630ddb0..3cb0dba500 100644
--- a/qualtran/simulation/tensor/_dense.py
+++ b/qualtran/simulation/tensor/_dense.py
@@ -14,7 +14,7 @@
import logging
from collections import defaultdict
-from typing import Dict, List, Tuple, TYPE_CHECKING
+from typing import TYPE_CHECKING
from numpy.typing import NDArray
@@ -30,8 +30,8 @@
def _order_incoming_outgoing_indices(
- signature: Signature, incoming: Dict[str, 'ConnectionT'], outgoing: Dict[str, 'ConnectionT']
-) -> List[Tuple[Connection, int]]:
+ signature: Signature, incoming: dict[str, 'ConnectionT'], outgoing: dict[str, 'ConnectionT']
+) -> list[tuple[Connection, int]]:
"""Order incoming and outgoing indices provided by the tensor protocol according to `signature`.
This can be used if you have a well-ordered, dense numpy array.
@@ -41,7 +41,7 @@ def _order_incoming_outgoing_indices(
>>> return [qtn.Tensor(data=data, inds=inds)]
"""
- inds: List[Tuple[Connection, int]] = []
+ inds: list[tuple[Connection, int]] = []
# Nested for loops:
# reg: each register in the signature
@@ -67,7 +67,7 @@ def _order_incoming_outgoing_indices(
def _group_outer_inds(
tn: 'qtn.TensorNetwork', signature: Signature, superoperator: bool = False
-) -> List[List[_IndT]]:
+) -> list[list[_IndT]]:
"""Group outer indices of a tensor network.
This is used by 'bloq_to_dense` and `quimb_to_dense` to return a 1-, 2-, or 4-dimensional
@@ -80,17 +80,17 @@ def _group_outer_inds(
superoperator: Whether `tn` is a pure-state or open-system tensor network.
"""
reg_name: str
- idx: Tuple[int, ...]
+ idx: tuple[int, ...]
j: int
group: str
- _KeyT = Tuple[str, Tuple[int, ...], int]
- ind_groups_d: Dict[str, Dict[_KeyT, _IndT]] = defaultdict(dict)
+ _KeyT = tuple[str, tuple[int, ...], int]
+ ind_groups_d: dict[str, dict[_KeyT, _IndT]] = defaultdict(dict)
for ind in tn.outer_inds():
reg_name, idx, j, group = ind
ind_groups_d[group][reg_name, idx, j] = ind
- ind_groups_l: Dict[str, List[_IndT]] = defaultdict(list)
+ ind_groups_l: dict[str, list[_IndT]] = defaultdict(list)
def _sort_group(regs, group_name):
for reg in regs:
diff --git a/qualtran/simulation/tensor/_dense_test.py b/qualtran/simulation/tensor/_dense_test.py
index 45f1e42238..4104556e36 100644
--- a/qualtran/simulation/tensor/_dense_test.py
+++ b/qualtran/simulation/tensor/_dense_test.py
@@ -13,7 +13,6 @@
# limitations under the License.
from functools import cached_property
-from typing import Dict, List
import numpy as np
import pytest
@@ -51,8 +50,8 @@ def signature(self) -> 'Signature':
)
def my_tensors(
- self, incoming: Dict[str, 'ConnectionT'], outgoing: Dict[str, 'ConnectionT']
- ) -> List['qtn.Tensor']:
+ self, incoming: dict[str, 'ConnectionT'], outgoing: dict[str, 'ConnectionT']
+ ) -> list['qtn.Tensor']:
assert sorted(incoming.keys()) == ['qubits', 'x']
in_qubits = incoming['qubits']
assert isinstance(in_qubits, np.ndarray)
@@ -104,7 +103,7 @@ class XNest(Bloq):
def signature(self) -> 'Signature':
return Signature.build(r=1)
- def build_composite_bloq(self, bb: 'BloqBuilder', r: 'SoquetT') -> Dict[str, 'SoquetT']:
+ def build_composite_bloq(self, bb: 'BloqBuilder', r: 'SoquetT') -> dict[str, 'SoquetT']:
r = bb.add(XGate(), q=r)
return {'r': r}
@@ -115,7 +114,7 @@ class XDoubleNest(Bloq):
def signature(self) -> 'Signature':
return Signature.build(s=1)
- def build_composite_bloq(self, bb: 'BloqBuilder', s: 'SoquetT') -> Dict[str, 'SoquetT']:
+ def build_composite_bloq(self, bb: 'BloqBuilder', s: 'SoquetT') -> dict[str, 'SoquetT']:
s = bb.add(XNest(), r=s)
return {'s': s}
@@ -144,7 +143,7 @@ def signature(self) -> 'Signature':
def build_composite_bloq(
self, bb: 'BloqBuilder', q0: Soquet, q1: Soquet
- ) -> Dict[str, 'SoquetT']:
+ ) -> dict[str, 'SoquetT']:
q0 = bb.add(XGate(), q=q0)
q0, q1 = bb.add(CNOT(), ctrl=q0, target=q1)
q1 = bb.add(ZGate(), q=q1)
@@ -172,15 +171,15 @@ def __init__(self):
def signature(self) -> 'Signature':
return Signature.build(a=1, b=1)
- def build_composite_bloq(self, bb: 'BloqBuilder', a: Soquet, b: Soquet) -> Dict[str, 'SoquetT']:
+ def build_composite_bloq(self, bb: 'BloqBuilder', a: Soquet, b: Soquet) -> dict[str, 'SoquetT']:
self.called_build_composite_bloq = True
a, b = bb.add(CNOT(), ctrl=a, target=b)
a, b = bb.add(CNOT(), ctrl=a, target=b)
return {'a': a, 'b': b}
def my_tensors(
- self, incoming: Dict[str, 'ConnectionT'], outgoing: Dict[str, 'ConnectionT']
- ) -> List['qtn.Tensor']:
+ self, incoming: dict[str, 'ConnectionT'], outgoing: dict[str, 'ConnectionT']
+ ) -> list['qtn.Tensor']:
self.called_my_tensors = True
return [
qtn.Tensor(
diff --git a/qualtran/simulation/tensor/_quimb.py b/qualtran/simulation/tensor/_quimb.py
index 7a4583fdc4..789fce75c7 100644
--- a/qualtran/simulation/tensor/_quimb.py
+++ b/qualtran/simulation/tensor/_quimb.py
@@ -12,7 +12,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import logging
-from typing import Any, cast, Dict, Iterable, Tuple, TypeAlias, Union
+from collections.abc import Iterable
+from typing import Any, cast, TypeAlias, Union
import attrs
import numpy as np
@@ -111,12 +112,12 @@ def _get_placeholder_tensors(cxn):
)
-_OuterIndT = Tuple[str, Tuple[int, ...], int, str]
+_OuterIndT = tuple[str, tuple[int, ...], int, str]
def _get_outer_indices(
tn: 'qtn.TensorNetwork', friendly_indices: bool = False
-) -> Dict[_IndT, Union[str, _OuterIndT]]:
+) -> dict[_IndT, Union[str, _OuterIndT]]:
"""Provide a mapping for a tensor network's outer indices.
Internal indices effectively use `qualtran.Connection` objects as their indices. The
@@ -131,7 +132,7 @@ def _get_outer_indices(
This function is called at the end of `cbloq_to_quimb` as part of a `tn.reindex(...) operation.
"""
- ind_name_map: Dict[_IndT, Union[str, _OuterIndT]] = {}
+ ind_name_map: dict[_IndT, Union[str, _OuterIndT]] = {}
# Each index is a (cxn: Connection, j: int) tuple.
cxn: Connection
@@ -179,7 +180,7 @@ class DiscardInd:
individual bits.
"""
- ind_tuple: Tuple['ConnectionT', int]
+ ind_tuple: tuple['ConnectionT', int]
def make_forward_tensor(t: qtn.Tensor):
@@ -266,12 +267,12 @@ def cbloq_to_superquimb(cbloq: CompositeBloq, friendly_indices: bool = False) ->
return tn.reindex(_get_outer_superindices(tn, friendly_indices=friendly_indices))
-_SuperOuterIndT = Tuple[str, Tuple[int, ...], int, str]
+_SuperOuterIndT = tuple[str, tuple[int, ...], int, str]
def _get_outer_superindices(
tn: 'qtn.TensorNetwork', friendly_indices: bool = False
-) -> Dict[_IndT, Union[str, _SuperOuterIndT]]:
+) -> dict[_IndT, Union[str, _SuperOuterIndT]]:
"""Provide a mapping for a super-tensor network's outer indices.
Internal indices effectively use `qualtran.Connection` objects as their indices. The
@@ -293,7 +294,7 @@ def _get_outer_superindices(
j: int
forward: bool
- ind_name_map: Dict[_IndT, Union[str, _SuperOuterIndT]] = {}
+ ind_name_map: dict[_IndT, Union[str, _SuperOuterIndT]] = {}
for ind in tn.outer_inds():
cxn, j, forward = ind
if cxn.left.binst is LeftDangle:
@@ -317,12 +318,12 @@ def _get_outer_superindices(
return ind_name_map
-def _add_classical_kets(bb: BloqBuilder, registers: Iterable[Register]) -> Dict[str, 'SoquetT']:
+def _add_classical_kets(bb: BloqBuilder, registers: Iterable[Register]) -> dict[str, 'SoquetT']:
"""Use `bb` to add `IntState(0)` for all the `vals`."""
from qualtran.bloqs.basic_gates import IntState
- soqs: Dict[str, 'SoquetT'] = {}
+ soqs: dict[str, 'SoquetT'] = {}
for reg in registers:
if reg.shape:
reg_vals = np.zeros(reg.shape, dtype=int)
diff --git a/qualtran/simulation/tensor/_quimb_test.py b/qualtran/simulation/tensor/_quimb_test.py
index ceb9a347a0..079e012e2b 100644
--- a/qualtran/simulation/tensor/_quimb_test.py
+++ b/qualtran/simulation/tensor/_quimb_test.py
@@ -13,7 +13,6 @@
# limitations under the License.
from functools import cached_property
-from typing import Dict, List
import numpy as np
import quimb.tensor as qtn
@@ -31,8 +30,8 @@ def signature(self) -> 'Signature':
return Signature.build(x=1)
def my_tensors(
- self, incoming: Dict[str, 'ConnectionT'], outgoing: Dict[str, 'ConnectionT']
- ) -> List['qtn.Tensor']:
+ self, incoming: dict[str, 'ConnectionT'], outgoing: dict[str, 'ConnectionT']
+ ) -> list['qtn.Tensor']:
assert list(incoming.keys()) == ['x']
assert list(outgoing.keys()) == ['x']
return [qtn.Tensor(data=np.eye(2), inds=[(incoming['x'], 0), (outgoing['x'], 0)])]
diff --git a/qualtran/simulation/tensor/_tensor_data_manipulation.py b/qualtran/simulation/tensor/_tensor_data_manipulation.py
index 5029ae22e5..98851bdf68 100644
--- a/qualtran/simulation/tensor/_tensor_data_manipulation.py
+++ b/qualtran/simulation/tensor/_tensor_data_manipulation.py
@@ -14,7 +14,7 @@
"""Utility methods to generate and manipulate tensor data for Bloqs."""
import itertools
-from typing import List, Tuple, Union
+from typing import Union
import attrs
import numpy as np
@@ -24,7 +24,7 @@
def tensor_out_inp_shape_from_signature(
signature: Signature,
-) -> Tuple[Tuple[int, ...], Tuple[int, ...]]:
+) -> tuple[tuple[int, ...], tuple[int, ...]]:
"""Returns a tuple for tensor data corresponding to signature.
Tensor data for a bloq with a given `signature` can be expressed as a ndarray of
@@ -42,7 +42,7 @@ def tensor_out_inp_shape_from_signature(
return tuple(out_indices_shape), tuple(inp_indices_shape)
-def tensor_shape_from_signature(signature: Signature) -> Tuple[int, ...]:
+def tensor_shape_from_signature(signature: Signature) -> tuple[int, ...]:
"""Returns a tuple for tensor data corresponding to signature.
Tensor data for a bloq with a given `signature` can be expressed as a ndarray of
@@ -61,7 +61,7 @@ def tensor_shape_from_signature(signature: Signature) -> Tuple[int, ...]:
def active_space_for_ctrl_spec(
signature: Signature, ctrl_spec: CtrlSpec
-) -> Tuple[Union[int, slice], ...]:
+) -> tuple[Union[int, slice], ...]:
"""Returns the "active" subspace corresponding to `signature` and `ctrl_spec`.
Assumes first n-registers for `signature` are control registers corresponding to `ctrl_spec`.
@@ -73,7 +73,7 @@ def active_space_for_ctrl_spec(
out_ind, inp_ind = tensor_out_inp_shape_from_signature(signature)
data_shape = out_ind + inp_ind
- active_idx: List[Union[int, slice]] = [slice(x) for x in data_shape]
+ active_idx: list[Union[int, slice]] = [slice(x) for x in data_shape]
ctrl_idx = 0
for cv in ctrl_spec.cvs:
assert isinstance(cv, np.ndarray)
@@ -117,7 +117,7 @@ def tensor_data_from_unitary_and_signature(unitary: np.ndarray, signature: Signa
unitary = unitary.reshape(unitary_shape)
# Find the subspace corresponding to registers with sides.
- idx: List[Union[int, slice]] = [slice(x) for x in unitary_shape]
+ idx: list[Union[int, slice]] = [slice(x) for x in unitary_shape]
curr_idx = 0
for reg in signature:
if reg.side == Side.LEFT:
diff --git a/qualtran/simulation/tensor/_tensor_from_classical.py b/qualtran/simulation/tensor/_tensor_from_classical.py
index bf87b44b32..5c3814cc30 100644
--- a/qualtran/simulation/tensor/_tensor_from_classical.py
+++ b/qualtran/simulation/tensor/_tensor_from_classical.py
@@ -12,7 +12,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import itertools
-from typing import Iterable, TYPE_CHECKING
+from collections.abc import Iterable
+from typing import TYPE_CHECKING
import numpy as np
from numpy.typing import NDArray
diff --git a/qualtran/simulation/xcheck_classical_quimb.py b/qualtran/simulation/xcheck_classical_quimb.py
index 9b644d67b7..21b2452c37 100644
--- a/qualtran/simulation/xcheck_classical_quimb.py
+++ b/qualtran/simulation/xcheck_classical_quimb.py
@@ -11,7 +11,8 @@
# 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.
-from typing import cast, Dict, Iterable, Optional, TYPE_CHECKING
+from collections.abc import Iterable
+from typing import cast, Optional, TYPE_CHECKING
import numpy as np
@@ -23,10 +24,10 @@
def _add_classical_kets(
- bb: BloqBuilder, registers: Iterable[Register], vals: Dict[str, 'ClassicalValT']
-) -> Dict[str, 'SoquetT']:
+ bb: BloqBuilder, registers: Iterable[Register], vals: dict[str, 'ClassicalValT']
+) -> dict[str, 'SoquetT']:
"""Use `bb` to add `IntState` for all the `vals`."""
- soqs: Dict[str, 'SoquetT'] = {}
+ soqs: dict[str, 'SoquetT'] = {}
for reg in registers:
if reg.shape:
reg_vals = np.asarray(vals[reg.name])
@@ -43,8 +44,8 @@ def _add_classical_kets(
def _add_classical_bras(
bb: BloqBuilder,
registers: Iterable[Register],
- vals: Dict[str, 'ClassicalValT'],
- soqs: Dict[str, 'SoquetT'],
+ vals: dict[str, 'ClassicalValT'],
+ soqs: dict[str, 'SoquetT'],
) -> None:
"""Use `bb` to add `IntEffect` on `soqs` for all the `vals`."""
for reg in registers:
@@ -63,8 +64,8 @@ def _add_classical_bras(
def flank_with_classical_vectors(
bloq: 'Bloq',
- in_vals: Dict[str, 'ClassicalValT'],
- out_vals: Optional[Dict[str, 'ClassicalValT']] = None,
+ in_vals: dict[str, 'ClassicalValT'],
+ out_vals: Optional[dict[str, 'ClassicalValT']] = None,
) -> 'CompositeBloq':
"""Surround `bloq` with computational basis vectors according to the provided values.
diff --git a/qualtran/surface_code/gidney_fowler_model.py b/qualtran/surface_code/gidney_fowler_model.py
index 3452b58e02..0877031217 100644
--- a/qualtran/surface_code/gidney_fowler_model.py
+++ b/qualtran/surface_code/gidney_fowler_model.py
@@ -13,7 +13,8 @@
# limitations under the License.
import math
-from typing import Callable, cast, Iterable, Iterator, Optional, Tuple, TYPE_CHECKING
+from collections.abc import Callable, Iterable, Iterator
+from typing import cast, Optional, TYPE_CHECKING
from .algorithm_summary import AlgorithmSummary
from .ccz2t_factory import CCZ2TFactory
@@ -189,7 +190,7 @@ def get_ccz2t_costs_from_grid_search(
factory_iter: Iterable[MagicStateFactory] = tuple(iter_ccz2t_factories()),
data_block_iter: Iterable[DataBlock] = tuple(iter_simple_data_blocks()),
cost_function: Callable[[PhysicalCostsSummary], float] = (lambda pc: pc.qubit_hours),
-) -> Tuple[PhysicalCostsSummary, MagicStateFactory, SimpleDataBlock]:
+) -> tuple[PhysicalCostsSummary, MagicStateFactory, SimpleDataBlock]:
"""Grid search over parameters to minimize the space-time volume.
Args:
@@ -213,7 +214,7 @@ def get_ccz2t_costs_from_grid_search(
version of the spreadsheet from https://arxiv.org/abs/1812.01238
"""
best_cost: Optional[PhysicalCostsSummary] = None
- best_params: Optional[Tuple[MagicStateFactory, SimpleDataBlock]] = None
+ best_params: Optional[tuple[MagicStateFactory, SimpleDataBlock]] = None
for factory in factory_iter:
for data_block in data_block_iter:
cost = get_ccz2t_costs(
diff --git a/qualtran/surface_code/physical_cost_model.py b/qualtran/surface_code/physical_cost_model.py
index 4134fe0c77..f1aae7e4f8 100644
--- a/qualtran/surface_code/physical_cost_model.py
+++ b/qualtran/surface_code/physical_cost_model.py
@@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from functools import cached_property, lru_cache
-from typing import Tuple, TYPE_CHECKING
+from typing import TYPE_CHECKING
from attrs import frozen
@@ -159,7 +159,7 @@ def make_gidney_fowler(cls, data_d: int):
@classmethod
def make_beverland_et_al(
- cls, data_d: int, data_block_name: str = 'compact', factory_ds: Tuple = (9, 3, 3)
+ cls, data_d: int, data_block_name: str = 'compact', factory_ds: tuple = (9, 3, 3)
):
from qualtran.surface_code import (
CompactDataBlock,
diff --git a/qualtran/surface_code/t_factory_utils.py b/qualtran/surface_code/t_factory_utils.py
index 934703ab8d..382ed1fc64 100644
--- a/qualtran/surface_code/t_factory_utils.py
+++ b/qualtran/surface_code/t_factory_utils.py
@@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-from typing import Sequence
+from collections.abc import Sequence
import cirq
import numpy as np
diff --git a/qualtran/surface_code/ui.py b/qualtran/surface_code/ui.py
index 85f4010c42..d0e81e88fd 100644
--- a/qualtran/surface_code/ui.py
+++ b/qualtran/surface_code/ui.py
@@ -12,7 +12,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-from typing import Any, Dict, List, Sequence, Tuple
+from collections.abc import Sequence
+from typing import Any
import numpy as np
import pandas as pd
@@ -411,7 +412,7 @@ def create_qubit_pie_chart(
return fig
-def format_duration(duration: Sequence[float]) -> Tuple[str, Sequence[float]]:
+def format_duration(duration: Sequence[float]) -> tuple[str, Sequence[float]]:
"""Returns a tuple of the format (unit, duration)
Finds the best unit to report `duration` and assumes that `duration` is initially in us.
@@ -445,7 +446,7 @@ def create_runtime_plot(
magic_count: int,
rotation_model: rotation_cost_model.RotationCostModel,
n_logical_gates: 'GateCounts',
-) -> Tuple[Dict[str, Any], go.Figure]:
+) -> tuple[dict[str, Any], go.Figure]:
"""Creates the runtime figure and decides whether to display it or not.
Currently displays the runtime plot for the Beverland model only.
@@ -589,7 +590,7 @@ def update(
)
-def total_magic(estimation_model: str, n_logical_gates: 'GateCounts') -> Tuple[List[str], str]:
+def total_magic(estimation_model: str, n_logical_gates: 'GateCounts') -> tuple[list[str], str]:
"""Compute the number of magic states needed for the algorithm and their type."""
total_t = n_logical_gates.total_t_count()
total_ccz = total_t / 4
@@ -607,7 +608,7 @@ def min_num_factories(
rotation_model: rotation_cost_model.RotationCostModel,
magic_factory: MagicStateFactory,
n_logical_gates: 'GateCounts',
-) -> Tuple[Dict[str, Any], int]:
+) -> tuple[dict[str, Any], int]:
if estimation_model == _GIDNEY_FOWLER_MODEL:
return {'display': 'none'}, 1
c_min = beverland_et_al_model.minimum_time_steps(
@@ -631,7 +632,7 @@ def compute_duration(
rotation_model: rotation_cost_model.RotationCostModel,
magic_count: int,
n_logical_gates: 'GateCounts',
-) -> Tuple[Dict[str, Any], str]:
+) -> tuple[dict[str, Any], str]:
"""Compute the duration of running the algorithm and whether to display the result or not.
Currently displays the result only for GidneyFowler (arxiv:1812.01238).
diff --git a/qualtran/symbolics/math_funcs.py b/qualtran/symbolics/math_funcs.py
index e55c1725b2..512caa094a 100644
--- a/qualtran/symbolics/math_funcs.py
+++ b/qualtran/symbolics/math_funcs.py
@@ -12,7 +12,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import math
-from typing import cast, Iterable, overload, TypeVar
+from collections.abc import Iterable
+from typing import cast, overload, TypeVar
import numpy as np
import sympy
diff --git a/qualtran/testing.py b/qualtran/testing.py
index 646d4887c7..87778fa2ec 100644
--- a/qualtran/testing.py
+++ b/qualtran/testing.py
@@ -16,9 +16,10 @@
import itertools
import traceback
+from collections.abc import Sequence
from enum import Enum
from pathlib import Path
-from typing import Dict, List, Optional, Sequence, Tuple, Union
+from typing import Optional, Union
import numpy as np
import sympy
@@ -236,7 +237,7 @@ def assert_valid_bloq_decomposition(bloq: Optional[Bloq]) -> CompositeBloq:
return cbloq
-def assert_wire_symbols_match_expected(bloq: Bloq, expected_ws: List[Union[str, WireSymbol]]):
+def assert_wire_symbols_match_expected(bloq: Bloq, expected_ws: list[Union[str, WireSymbol]]):
"""Assert a bloq's wire symbols match the expected ones.
For multi-dimensional registers (with a shape), this will iterate
@@ -376,7 +377,7 @@ def assert_bloq_example_make(bloq_ex: BloqExample) -> None:
return
-def check_bloq_example_make(bloq_ex: BloqExample) -> Tuple[BloqCheckResult, str]:
+def check_bloq_example_make(bloq_ex: BloqExample) -> tuple[BloqCheckResult, str]:
"""Check that the BloqExample returns the desired bloq.
Returns:
@@ -418,7 +419,7 @@ def assert_bloq_example_decompose(bloq_ex: BloqExample) -> None:
raise BloqCheckException.fail(str(e)) from e
-def check_bloq_example_decompose(bloq_ex: BloqExample) -> Tuple[BloqCheckResult, str]:
+def check_bloq_example_decompose(bloq_ex: BloqExample) -> tuple[BloqCheckResult, str]:
"""Check that the BloqExample has a valid decomposition.
This will use `assert_valid_decomposition` which has a variety of sub-checks. A failure
@@ -462,8 +463,8 @@ def assert_equivalent_bloq_example_counts(bloq_ex: BloqExample) -> None:
has_manual_counts: bool
has_decomp_counts: bool
- manual_counts: Dict['Bloq', Union[int, 'sympy.Expr']] = {}
- decomp_counts: Dict['Bloq', Union[int, 'sympy.Expr']] = {}
+ manual_counts: dict['Bloq', Union[int, 'sympy.Expr']] = {}
+ decomp_counts: dict['Bloq', Union[int, 'sympy.Expr']] = {}
# Notable implementation detail: since `bloq.build_call_graph` has a default fallback
# that uses the decomposition, we could accidentally be comparing two identical code paths
@@ -530,7 +531,7 @@ def assert_equivalent_bloq_counts(
)
-def check_equivalent_bloq_example_counts(bloq_ex: BloqExample) -> Tuple[BloqCheckResult, str]:
+def check_equivalent_bloq_example_counts(bloq_ex: BloqExample) -> tuple[BloqCheckResult, str]:
"""Check that the BloqExample has consistent bloq counts.
Bloq counts can be annotated directly via the `Bloq.build_call_graph` override.
@@ -594,7 +595,7 @@ def assert_bloq_example_serializes(bloq_ex: BloqExample) -> None:
return None
-def check_bloq_example_serializes(bloq_ex: BloqExample) -> Tuple[BloqCheckResult, str]:
+def check_bloq_example_serializes(bloq_ex: BloqExample) -> tuple[BloqCheckResult, str]:
"""Check that the BloqExample has consistent serialization.
This function checks that the given bloq can be serialized to a proto format and the
@@ -619,7 +620,7 @@ def check_bloq_example_serializes(bloq_ex: BloqExample) -> Tuple[BloqCheckResult
return BloqCheckResult.PASS, ''
-def assert_bloq_example_qtyping(bloq_ex: BloqExample) -> Tuple[BloqCheckResult, str]:
+def assert_bloq_example_qtyping(bloq_ex: BloqExample) -> tuple[BloqCheckResult, str]:
"""Assert that the bloq example has valid quantum data types throughout its decomposition.
If the bloq has no decomposition, this check is not applicable. Otherwise: we check the
@@ -669,7 +670,7 @@ def assert_bloq_example_qtyping(bloq_ex: BloqExample) -> Tuple[BloqCheckResult,
return BloqCheckResult.PASS, ''
-def check_bloq_example_qtyping(bloq_ex: BloqExample) -> Tuple[BloqCheckResult, str]:
+def check_bloq_example_qtyping(bloq_ex: BloqExample) -> tuple[BloqCheckResult, str]:
"""Check that the bloq example has valid quantum data types throughout its decomposition.
If the bloq has no decomposition, this check is not applicable. Otherwise: we check the