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/dump-bloq-manifest.py b/dev_tools/dump-bloq-manifest.py
index a7006a610c..eb83ea0450 100644
--- a/dev_tools/dump-bloq-manifest.py
+++ b/dev_tools/dump-bloq-manifest.py
@@ -23,7 +23,6 @@
"""
from functools import cached_property
-from typing import List, Tuple
from attrs import frozen
from qualtran_dev_tools.bloq_finder import get_bloq_classes, get_bloq_examples
@@ -70,7 +69,7 @@ def objectstring(self) -> str:
"""Returns the canonical string representation of the CObjectNode."""
return self.cobject_node.canonical_str()
- def maybe_commented_out(self, be_column_width: int = 30) -> Tuple[str, str, str]:
+ def maybe_commented_out(self, be_column_width: int = 30) -> tuple[str, str, str]:
"""Generates a string representation for the manifest, potentially commented out.
This method checks if the object string is too long, unparsable, unloadable, or
@@ -121,7 +120,7 @@ def main():
names = sorted(bc._class_name_in_pkg_() for bc in bcs)
bes = get_bloq_examples()
- items: List[BloqExampleListItem] = []
+ items: list[BloqExampleListItem] = []
for be in bes:
bloq = be.make()
try:
diff --git a/dev_tools/qualtran_dev_tools/all_call_graph.py b/dev_tools/qualtran_dev_tools/all_call_graph.py
index 3c42912442..24fa00cb40 100644
--- a/dev_tools/qualtran_dev_tools/all_call_graph.py
+++ b/dev_tools/qualtran_dev_tools/all_call_graph.py
@@ -16,7 +16,7 @@
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 63de6f3eeb..ea3e58c374 100644
--- a/dev_tools/qualtran_dev_tools/bloq_finder.py
+++ b/dev_tools/qualtran_dev_tools/bloq_finder.py
@@ -14,15 +14,16 @@
import importlib
import inspect
import subprocess
+from collections.abc import Callable, Iterable
from pathlib import Path
-from typing import Callable, Iterable, List, Optional, Tuple, Type
+from typing import Optional
from qualtran import Bloq, BloqDocSpec, BloqExample
from .git_tools import get_git_root
-def _get_git_paths(bloqs_root: Path, filter_func: Callable[[Path], bool]) -> List[Path]:
+def _get_git_paths(bloqs_root: Path, filter_func: Callable[[Path], bool]) -> list[Path]:
"""Get only git-tracked *.py files based on `filter_func`."""
cp = subprocess.run(
['git', 'ls-files', '*.py'],
@@ -40,7 +41,7 @@ def _get_git_paths(bloqs_root: Path, filter_func: Callable[[Path], bool]) -> Lis
def _get_paths(
bloqs_root: Path, filter_func: Callable[[Path], bool], committed_only: bool = True
-) -> List[Path]:
+) -> list[Path]:
"""Get *.py files based on `filter_func`."""
if committed_only:
return _get_git_paths(bloqs_root, filter_func)
@@ -50,7 +51,7 @@ def _get_paths(
]
-def get_bloq_module_paths(bloqs_root: Path, committed_only: bool = True) -> List[Path]:
+def get_bloq_module_paths(bloqs_root: Path, committed_only: bool = True) -> list[Path]:
"""Get *.py files for non-test, non-init modules under `bloqs_root`."""
def is_module_path(path: Path) -> bool:
@@ -65,7 +66,7 @@ def is_module_path(path: Path) -> bool:
return _get_paths(bloqs_root, is_module_path, committed_only=committed_only)
-def get_bloq_test_module_paths(bloqs_root: Path, committed_only: bool = True) -> List[Path]:
+def get_bloq_test_module_paths(bloqs_root: Path, committed_only: bool = True) -> list[Path]:
"""Get *_test.py files under `bloqs_root`."""
def is_test_module_path(path: Path) -> bool:
@@ -82,7 +83,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)
@@ -100,7 +101,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)
@@ -109,7 +110,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)
@@ -118,20 +119,20 @@ def modpath_to_bloqdocspecs(path: Path) -> Iterable[Tuple[str, str, BloqDocSpec]
yield modname, name, obj
-def get_bloq_classes(bloqs_root: Optional[Path] = None) -> List[Type[Bloq]]:
+def get_bloq_classes(bloqs_root: Optional[Path] = None) -> list[type[Bloq]]:
committed_only = bloqs_root is None
if bloqs_root is None:
reporoot = get_git_root()
bloqs_root = reporoot / 'qualtran/bloqs'
paths = get_bloq_module_paths(bloqs_root, committed_only=committed_only)
- 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(bloqs_root: Optional[Path] = None) -> List[BloqExample]:
+def get_bloq_examples(bloqs_root: Optional[Path] = None) -> list[BloqExample]:
committed_only = bloqs_root is None
if bloqs_root is None:
reporoot = get_git_root()
@@ -139,7 +140,7 @@ def get_bloq_examples(bloqs_root: Optional[Path] = None) -> List[BloqExample]:
paths = get_bloq_module_paths(bloqs_root, committed_only=committed_only)
- bexamples: List[BloqExample] = []
+ bexamples: list[BloqExample] = []
for path in paths:
for modname, name, be in modpath_to_bloq_exs(path):
bexamples.append(be)
@@ -147,7 +148,7 @@ def get_bloq_examples(bloqs_root: Optional[Path] = None) -> List[BloqExample]:
return bexamples
-def get_bloqdocspecs(bloqs_root: Optional[Path] = None) -> List[BloqDocSpec]:
+def get_bloqdocspecs(bloqs_root: Optional[Path] = None) -> list[BloqDocSpec]:
committed_only = bloqs_root is None
if bloqs_root is None:
reporoot = get_git_root()
@@ -155,7 +156,7 @@ def get_bloqdocspecs(bloqs_root: Optional[Path] = None) -> List[BloqDocSpec]:
paths = get_bloq_module_paths(bloqs_root, committed_only=committed_only)
- 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 5d002d6c5e..0b35c76719 100644
--- a/dev_tools/qualtran_dev_tools/jupyter_autogen.py
+++ b/dev_tools/qualtran_dev_tools/jupyter_autogen.py
@@ -20,7 +20,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.
@@ -326,7 +326,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/make_reference_docs/_components/aliases.py b/dev_tools/qualtran_dev_tools/make_reference_docs/_components/aliases.py
index 2170b9aaa1..576c7dcad7 100644
--- a/dev_tools/qualtran_dev_tools/make_reference_docs/_components/aliases.py
+++ b/dev_tools/qualtran_dev_tools/make_reference_docs/_components/aliases.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.
-from typing import Dict
-def get_aliases_str(pref_dotpath: str, *, aliases_d: Dict[str, str]) -> str:
+def get_aliases_str(pref_dotpath: str, *, aliases_d: dict[str, str]) -> str:
"""From a complete dictionary of aliases, return a formatted string with our aliases.
This will return just `pref_dotpath` if there are none,
diff --git a/dev_tools/qualtran_dev_tools/make_reference_docs/_components/render_docstring.py b/dev_tools/qualtran_dev_tools/make_reference_docs/_components/render_docstring.py
index a763321f87..d920f410b5 100644
--- a/dev_tools/qualtran_dev_tools/make_reference_docs/_components/render_docstring.py
+++ b/dev_tools/qualtran_dev_tools/make_reference_docs/_components/render_docstring.py
@@ -13,7 +13,7 @@
# limitations under the License.
import re
import warnings
-from typing import List, Literal, Tuple, TYPE_CHECKING
+from typing import Literal, TYPE_CHECKING
from griffe import (
DocstringSection,
@@ -37,7 +37,7 @@
PARSER: Literal['google'] = 'google'
-def split_docstring(obj: 'griffe.Object') -> Tuple[str, List[DocstringSection]]:
+def split_docstring(obj: 'griffe.Object') -> tuple[str, list[DocstringSection]]:
"""Extract the first, summary line of a docstring from an object.
Returns:
@@ -47,7 +47,7 @@ def split_docstring(obj: 'griffe.Object') -> Tuple[str, List[DocstringSection]]:
if obj.docstring is None:
first_line = ""
- rest: List[DocstringSection] = []
+ rest: list[DocstringSection] = []
return first_line, rest
dp0, *dparts = obj.docstring.parse(PARSER)
@@ -193,7 +193,7 @@ def _write_unknown(f, part: DocstringSection, level: int):
}
-def write_docstring_parts(f, parts: List[DocstringSection], level: int):
+def write_docstring_parts(f, parts: list[DocstringSection], level: int):
for part in parts:
_write = _DISPATCH.get(part.kind, _write_unknown)
_write(f, part, level) # type: ignore
diff --git a/dev_tools/qualtran_dev_tools/make_reference_docs/_linking_writer.py b/dev_tools/qualtran_dev_tools/make_reference_docs/_linking_writer.py
index 5476406c35..d9be38ce49 100644
--- a/dev_tools/qualtran_dev_tools/make_reference_docs/_linking_writer.py
+++ b/dev_tools/qualtran_dev_tools/make_reference_docs/_linking_writer.py
@@ -13,14 +13,15 @@
# limitations under the License.
import re
from collections import defaultdict
+from collections.abc import MutableMapping
from pathlib import Path
-from typing import Dict, MutableMapping, Optional, Protocol, Set, Tuple
+from typing import Optional, Protocol
from mdit_py_plugins.anchors.index import slugify
from ._page import Page
-_CACHE: MutableMapping[str, Dict[str, Optional[str]]] = defaultdict(dict)
+_CACHE: MutableMapping[str, dict[str, Optional[str]]] = defaultdict(dict)
class Writable(Protocol):
@@ -43,12 +44,12 @@ def __init__(
self,
f: Writable,
*,
- link_aliases: Dict[str, str],
- link_d: Dict[str, Tuple[Page, Optional[str]]],
+ link_aliases: dict[str, str],
+ link_d: dict[str, tuple[Page, Optional[str]]],
refdoc_relpath: Path,
):
self._f: Writable = f
- self._linked: Set[str] = set()
+ self._linked: set[str] = set()
self._link_aliases = link_aliases
self._link_d = link_d
self._reference_relpath = refdoc_relpath
diff --git a/dev_tools/qualtran_dev_tools/make_reference_docs/_make.py b/dev_tools/qualtran_dev_tools/make_reference_docs/_make.py
index 9addcfd04b..deb051bae9 100644
--- a/dev_tools/qualtran_dev_tools/make_reference_docs/_make.py
+++ b/dev_tools/qualtran_dev_tools/make_reference_docs/_make.py
@@ -16,8 +16,9 @@
import ast
import warnings
from collections import defaultdict
+from collections.abc import Sequence
from pathlib import Path
-from typing import Any, cast, Dict, List, Optional, Sequence, Set, Tuple, Union
+from typing import Any, cast, Optional, Union
import attrs
import griffe
@@ -86,7 +87,7 @@
]
-def _get_all_aliases(obj: Union[griffe.Object, griffe.Alias]) -> Set[str]:
+def _get_all_aliases(obj: Union[griffe.Object, griffe.Alias]) -> set[str]:
"""Get all the valid aliases for `obj`."""
# First, try to use the aliases griffe has found
@@ -125,7 +126,7 @@ def is_valid_alias(alias: str) -> bool:
return valid_aliases
-def _get_preferred_dotpath(all_aliases: Set[str]):
+def _get_preferred_dotpath(all_aliases: set[str]):
"""From a list of candidates, select the best "dotpath".
A "dotpath" is a string path of the form "foo.bar.X", i.e. with dots. It is in contrast
@@ -146,18 +147,18 @@ class _PackageWalker:
The public entry point is via the function `get_pages`.
"""
- seen: Set[str] = attrs.field(factory=set, kw_only=True)
+ seen: set[str] = attrs.field(factory=set, kw_only=True)
"""A set of seen canonical dotpaths. Griffe uses canonical dotpaths to uniquely
identify things, so we do too for `seen`. Afterwards, the doc system will use only our
preferred path."""
- pages_d: Dict[str, Page] = attrs.field(factory=lambda: defaultdict(ModulePage), kw_only=True)
+ pages_d: dict[str, Page] = attrs.field(factory=lambda: defaultdict(ModulePage), kw_only=True)
"""Mapping of preferred dotpath to `Page`."""
- aliases_d: Dict[str, str] = attrs.field(factory=dict, kw_only=True)
+ aliases_d: dict[str, str] = attrs.field(factory=dict, kw_only=True)
"""Mapping from each alias to the preferred dotpath (many-to-one)."""
- link_d: Dict[str, Tuple[Page, Optional[str]]] = attrs.field(factory=dict, kw_only=True)
+ link_d: dict[str, tuple[Page, Optional[str]]] = attrs.field(factory=dict, kw_only=True)
"""Mapping from preferred dotpath to a doc location."""
def _walk_table_of_contents(self, obj: Union[griffe.Alias, griffe.Object]):
@@ -251,7 +252,7 @@ def _walk_table_of_contents(self, obj: Union[griffe.Alias, griffe.Object]):
def get_pages(
root_mod: griffe.Module,
-) -> Tuple[List[Page], Dict[str, str], Dict[str, Tuple[Page, Optional[str]]]]:
+) -> tuple[list[Page], dict[str, str], dict[str, tuple[Page, Optional[str]]]]:
"""Walk down from `root_mod`."""
assert root_mod.is_module
assert root_mod.is_init_module
@@ -276,8 +277,8 @@ def walk_and_configure(
refdoc_relpath: Path,
top_sections: Sequence[str],
fake_sections: Sequence[str],
- addtl_linkable: Dict[str, str],
-) -> Tuple[List[Page], RenderContext]:
+ addtl_linkable: dict[str, str],
+) -> tuple[list[Page], RenderContext]:
"""Organize things or whatever."""
# Incantation to get `griffe` set up.
diff --git a/dev_tools/qualtran_dev_tools/make_reference_docs/_pages/render_major_class.py b/dev_tools/qualtran_dev_tools/make_reference_docs/_pages/render_major_class.py
index b085698ecc..adf9484917 100644
--- a/dev_tools/qualtran_dev_tools/make_reference_docs/_pages/render_major_class.py
+++ b/dev_tools/qualtran_dev_tools/make_reference_docs/_pages/render_major_class.py
@@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from pathlib import Path
-from typing import cast, Dict, TYPE_CHECKING
+from typing import cast, TYPE_CHECKING
import griffe
from griffe import Kind
@@ -56,7 +56,7 @@ def write_major_class_member(f: 'Writable', obj: griffe.Class, obj2: griffe.Obje
def write_major_class(
- f: LinkingWriter, obj: griffe.Class, pref_dotpath: str, aliases_d: Dict[str, str]
+ f: LinkingWriter, obj: griffe.Class, pref_dotpath: str, aliases_d: dict[str, str]
):
# Title
f.write(f"# {obj.name}\n\n")
diff --git a/dev_tools/qualtran_dev_tools/make_reference_docs/_pages/render_module.py b/dev_tools/qualtran_dev_tools/make_reference_docs/_pages/render_module.py
index 5f4f048aa6..71f76ac430 100644
--- a/dev_tools/qualtran_dev_tools/make_reference_docs/_pages/render_module.py
+++ b/dev_tools/qualtran_dev_tools/make_reference_docs/_pages/render_module.py
@@ -13,8 +13,9 @@
# limitations under the License.
+from collections.abc import Sequence
from pathlib import Path
-from typing import cast, Dict, Sequence
+from typing import cast
import griffe
from griffe import Kind
@@ -69,7 +70,7 @@ def write_module(
obj: griffe.Module,
pref_path: str,
members: Sequence[ModulePageMember],
- aliases_d: Dict[str, str],
+ aliases_d: dict[str, str],
):
# Title
title_dotpath = '.'.join(pref_path.split('.')[-2:])
diff --git a/dev_tools/qualtran_dev_tools/make_reference_docs/_pages/render_toc.py b/dev_tools/qualtran_dev_tools/make_reference_docs/_pages/render_toc.py
index e7367e3d5b..02ba2dc6a4 100644
--- a/dev_tools/qualtran_dev_tools/make_reference_docs/_pages/render_toc.py
+++ b/dev_tools/qualtran_dev_tools/make_reference_docs/_pages/render_toc.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 Callable, List, Sequence
+from collections.abc import Callable, Sequence
from .._page import ModulePage, Page
from .._render_context import RenderContext
@@ -28,7 +28,7 @@ def write_toc(toc_f, pages, _page_in_section, _pages_sort_key, render_context: R
toc_f.write(f' :caption: {section}\n')
toc_f.write(' :maxdepth: 2\n\n')
- spages: List[Page] = sorted(
+ spages: list[Page] = sorted(
(p for p in pages if _page_in_section(p, section)), key=_pages_sort_key
)
diff --git a/dev_tools/qualtran_dev_tools/make_reference_docs/_render_context.py b/dev_tools/qualtran_dev_tools/make_reference_docs/_render_context.py
index 62a268d1b1..d299844f5d 100644
--- a/dev_tools/qualtran_dev_tools/make_reference_docs/_render_context.py
+++ b/dev_tools/qualtran_dev_tools/make_reference_docs/_render_context.py
@@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from pathlib import Path
-from typing import Dict, List, Optional, Tuple
+from typing import Optional
import attrs
@@ -52,16 +52,16 @@ class RenderContext:
refdoc_relpath: Path
"""Relative subdirectory of where the reference docs go (opposed to the other docs)"""
- sections: List[str]
+ sections: list[str]
"""Ordered list of section names (to organize pages)"""
- aliases_d: Dict[str, str]
+ aliases_d: dict[str, str]
"""Returned by `get_pages`, see `_PackageWalker.aliases_d`"""
- link_d: Dict[str, Tuple[Page, Optional[str]]]
+ link_d: dict[str, tuple[Page, Optional[str]]]
"""Returned by `get_pages`, see `_PackageWalker.link_d`"""
- linkable_to_prefpath: Dict[str, str]
+ linkable_to_prefpath: dict[str, str]
"""Similar to aliases_d, but can have arbitrary keys that map to preferred dotpaths."""
def get_linking_writer(self, f: Writable) -> LinkingWriter:
diff --git a/dev_tools/qualtran_dev_tools/notebook_execution.py b/dev_tools/qualtran_dev_tools/notebook_execution.py
index 58146f27ad..e346c93ea0 100644
--- a/dev_tools/qualtran_dev_tools/notebook_execution.py
+++ b/dev_tools/qualtran_dev_tools/notebook_execution.py
@@ -18,7 +18,7 @@
import sys
import time
from pathlib import Path
-from typing import List, Optional, Tuple
+from typing import Optional
import attrs
import filelock
@@ -31,7 +31,7 @@
from .git_tools import get_git_root
-def get_nb_rel_paths(sourceroot: Path) -> List[Tuple[Path, Path]]:
+def get_nb_rel_paths(sourceroot: Path) -> list[tuple[Path, Path]]:
"""List all checked-in *.ipynb files within `sourceroot`.
Returns a tuple of the relative path and the path it's relative to (aka sourceroot)
@@ -101,7 +101,7 @@ def needs_reexport(self):
return self.md_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',
diff --git a/dev_tools/qualtran_dev_tools/notebook_specs.py b/dev_tools/qualtran_dev_tools/notebook_specs.py
index c65508a9e1..82abb930e8 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
@@ -146,7 +144,7 @@
# --------------------------------------------------------------------------
# ----- Basic Gates ----------------------------------------------------
# --------------------------------------------------------------------------
-BASIC_GATES: List[NotebookSpecV2] = [
+BASIC_GATES: list[NotebookSpecV2] = [
NotebookSpecV2(
title='T Gate',
module=qualtran.bloqs.basic_gates.t_gate,
@@ -267,7 +265,7 @@
# --------------------------------------------------------------------------
# ----- Chemistry ------------------------------------------------------
# --------------------------------------------------------------------------
-CHEMISTRY: List[NotebookSpecV2] = [
+CHEMISTRY: list[NotebookSpecV2] = [
NotebookSpecV2(
title='Sparse',
module=qualtran.bloqs.chemistry.sparse,
@@ -785,7 +783,7 @@
# --------------------------------------------------------------------------
# ----- Block Encoding ----------------------------------------------------------
# --------------------------------------------------------------------------
-BLOCK_ENCODING: List[NotebookSpecV2] = [
+BLOCK_ENCODING: list[NotebookSpecV2] = [
NotebookSpecV2(
title='Block Encoding Interface',
module=qualtran.bloqs.block_encoding,
@@ -853,7 +851,7 @@
# --------------------------------------------------------------------------
# ----- Optimization ---------------------------------------------------
# --------------------------------------------------------------------------
-OPTIMIZATION: List[NotebookSpecV2] = [
+OPTIMIZATION: list[NotebookSpecV2] = [
# ----- Algorithm ------------------------------------------
NotebookSpecV2(
title='kXOR: Instance load Oracles',
@@ -898,7 +896,7 @@
),
]
-BOOKKEEPING: List[NotebookSpecV2] = [
+BOOKKEEPING: list[NotebookSpecV2] = [
NotebookSpecV2(
title='Split / Join',
module=qualtran.bloqs.bookkeeping.split,
@@ -947,7 +945,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 9958c96d92..b5662154e6 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
@@ -59,7 +59,7 @@ def parse_reference(ref_text: str) -> ReferenceT:
return UnparsedReference(ref_text)
-def parse_references(full_reference_text: str) -> List[ReferenceT]:
+def parse_references(full_reference_text: str) -> list[ReferenceT]:
reference_texts = re.split(r'\n\n', full_reference_text)
my_refs = []
for ref_text in reference_texts:
@@ -72,14 +72,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):
@@ -92,7 +92,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())
@@ -101,7 +101,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}'
@@ -113,7 +113,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
@@ -127,7 +127,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
@@ -139,7 +139,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 eeffc569f6..07a901e458 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:
@@ -383,7 +383,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 701ddfa269..f2218d5efc 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,7 +87,7 @@ 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)
@@ -96,7 +96,7 @@ def run(
)
-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/Adjoint.ipynb b/qualtran/Adjoint.ipynb
index d063fb12c9..8d0e982df6 100644
--- a/qualtran/Adjoint.ipynb
+++ b/qualtran/Adjoint.ipynb
@@ -228,7 +228,7 @@
" def signature(self) -> 'Signature':\n",
" return Signature.build(x=1)\n",
"\n",
- " def build_composite_bloq(self, bb: 'BloqBuilder', x: 'SoquetT') -> Dict[str, 'SoquetT']:\n",
+ " def build_composite_bloq(self, bb: 'BloqBuilder', x: 'SoquetT') -> dict[str, 'SoquetT']:\n",
" x = bb.add(Hadamard(), q=x)\n",
" x = bb.add(TGate(), q=x)\n",
" return {'x': x}\n",
diff --git a/qualtran/_infra/Bloqs-Tutorial.ipynb b/qualtran/_infra/Bloqs-Tutorial.ipynb
index 89419aa389..d0809b051f 100644
--- a/qualtran/_infra/Bloqs-Tutorial.ipynb
+++ b/qualtran/_infra/Bloqs-Tutorial.ipynb
@@ -548,7 +548,7 @@
"\n",
" def build_composite_bloq(\n",
" self, bb: BloqBuilder, *, x: SoquetT, y: SoquetT\n",
- " ) -> Dict[str, SoquetT]:\n",
+ " ) -> dict[str, SoquetT]:\n",
" # THIS WON'T ACTUALLY WORK! Read on.\n",
" for i in range(self.n):\n",
" x[i], y[i] = bb.add(SwapTwoBits(), x=x[i], y=y[i])\n",
@@ -682,7 +682,7 @@
"\n",
" def build_composite_bloq(\n",
" self, bb: BloqBuilder, *, x: SoquetT, y: SoquetT\n",
- " ) -> Dict[str, SoquetT]:\n",
+ " ) -> dict[str, SoquetT]:\n",
" for i in range(self.n):\n",
" x[i], y[i] = bb.add(SwapTwoBits(), x=x[i], y=y[i])\n",
" return {'x': x, 'y': y}"
@@ -758,7 +758,7 @@
"\n",
" def build_composite_bloq(\n",
" self, bb: BloqBuilder, *, x: SoquetT, y: SoquetT\n",
- " ) -> Dict[str, SoquetT]:\n",
+ " ) -> dict[str, SoquetT]:\n",
" xs = bb.split(x)\n",
" ys = bb.split(y)\n",
"\n",
@@ -935,7 +935,7 @@
"metadata": {},
"outputs": [],
"source": [
- "def build_composite_bloq(self, bb: 'BloqBuilder', exponent: 'SoquetT') -> Dict[str, 'SoquetT']:\n",
+ "def build_composite_bloq(self, bb: 'BloqBuilder', exponent: 'SoquetT') -> dict[str, 'SoquetT']:\n",
" x = bb.add(IntState(val=1, bitsize=self.x_bitsize))\n",
" exponent = bb.split(exponent)\n",
"\n",
diff --git a/qualtran/_infra/adjoint.py b/qualtran/_infra/adjoint.py
index b011268912..91207d3af3 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
@@ -39,7 +39,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 {}
@@ -73,7 +73,7 @@ def _adjoint_cbloq(cbloq: 'CompositeBloq') -> 'CompositeBloq':
bb, _ = BloqBuilder.from_signature(new_signature)
old_i_soqs = [_reg_to_soq(RightDangle, reg) for reg in old_signature.rights()]
new_i_soqs = [bb._reg_to_qvar(LeftDangle, reg) for reg in new_signature.lefts()]
- soq_map: List[Tuple[_SoquetT, QVarT]] = list(zip(old_i_soqs, new_i_soqs))
+ soq_map: list[tuple[_SoquetT, QVarT]] = list(zip(old_i_soqs, new_i_soqs))
for binst, preds, succs in bloqnections:
# Instead of get_me returning the right element of a predecessor connection,
# it's the left element of a successor connection.
@@ -187,7 +187,7 @@ def _pkg_(cls) -> str:
return 'qualtran'
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 08519c2cf9..9ba8626237 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
@@ -162,7 +152,7 @@ def signature(self) -> 'Signature':
`qualtran.Signature` for details on how to construct a 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']:
"""Override this method to define a bloq as a composition of sub-bloqs.
Bloq authors should override this method. If you already have an instantiated bloq object,
@@ -299,7 +289,7 @@ def basis_state_phase(
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
@@ -358,8 +348,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
@@ -393,7 +383,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
@@ -429,7 +419,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
@@ -458,7 +448,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()`.
@@ -478,7 +468,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.
@@ -499,8 +489,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
@@ -552,7 +542,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
@@ -656,7 +646,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 the register.
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.ipynb b/qualtran/_infra/composite_bloq.ipynb
index 4e0f4d798c..f9275006fd 100644
--- a/qualtran/_infra/composite_bloq.ipynb
+++ b/qualtran/_infra/composite_bloq.ipynb
@@ -106,7 +106,7 @@
"\n",
" def build_composite_bloq(\n",
" self, bb: 'BloqBuilder', q1: 'Soquet', q2: 'Soquet'\n",
- " ) -> Dict[str, 'Soquet']:\n",
+ " ) -> dict[str, 'Soquet']:\n",
" q1, q2 = bb.add(CNOT(), ctrl=q1, target=q2)\n",
" q1, q2 = bb.add(CNOT(), ctrl=q2, target=q1)\n",
" return {'q1': q1, 'q2': q2}"
@@ -469,7 +469,7 @@
"\n",
" def build_composite_bloq(\n",
" self, bb: 'BloqBuilder', stuff: 'SoquetT'\n",
- " ) -> Dict[str, 'SoquetT']:\n",
+ " ) -> dict[str, 'SoquetT']:\n",
" stuff = bb.add(TestParallelCombo(), reg=stuff)\n",
" stuff = bb.add(TestParallelCombo(), reg=stuff)\n",
" stuff = bb.add(TestParallelCombo(), reg=stuff)\n",
@@ -512,7 +512,7 @@
"# Go through and decompose each subbloq\n",
"# We'll manually code this up in this notebook since this isn't a useful operation.\n",
"bb, _ = BloqBuilder.from_signature(flat_three_p.signature)\n",
- "soq_map: List[Tuple[SoquetT, SoquetT]] = bb.initial_soq_map(flat_three_p.signature.lefts())\n",
+ "soq_map: list[tuple[SoquetT, SoquetT]] = bb.initial_soq_map(flat_three_p.signature.lefts())\n",
"\n",
"for binst, in_soqs, old_out_soqs in flat_three_p.iter_bloqsoqs():\n",
" in_soqs = bb.map_soqs(in_soqs, soq_map)\n",
diff --git a/qualtran/_infra/composite_bloq.py b/qualtran/_infra/composite_bloq.py
index 2439e107dd..6a67a38ea6 100644
--- a/qualtran/_infra/composite_bloq.py
+++ b/qualtran/_infra/composite_bloq.py
@@ -14,24 +14,15 @@
"""Classes for building and manipulating `CompositeBloq`."""
import warnings
-from collections.abc import Hashable
+from collections.abc import Callable, Hashable, Iterable, Iterator, Mapping, Sequence
from functools import cached_property
from typing import (
_ProtocolMeta,
- Callable,
cast,
- Dict,
FrozenSet,
- Iterable,
- Iterator,
- List,
- Mapping,
Optional,
overload,
Protocol,
- Sequence,
- Set,
- Tuple,
TYPE_CHECKING,
TypeAlias,
TypeGuard,
@@ -119,7 +110,7 @@ def __new__(cls, *args, **kwargs):
return _Soquet(*args, **kwargs)
@property
- def shape(self) -> Tuple[int, ...]: ...
+ def shape(self) -> tuple[int, ...]: ...
def item(self, *args) -> _QVar: ...
@@ -138,7 +129,7 @@ class _SoquetT(Protocol):
"""Either an actual _Soquet or an array thereof."""
@property
- def shape(self) -> Tuple[int, ...]: ...
+ def shape(self) -> tuple[int, ...]: ...
def item(self, *args) -> _Soquet: ...
@@ -160,7 +151,7 @@ class QVarT(Protocol):
"""
@property
- def shape(self) -> Tuple[int, ...]: ...
+ def shape(self) -> tuple[int, ...]: ...
def item(self, *args) -> _QVar: ...
@@ -239,7 +230,7 @@ class CompositeBloq(Bloq):
error reporting, but is never used for deriving any properties.
"""
- 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)
@@ -278,7 +269,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` version of this cbloq."""
import cirq
@@ -289,7 +280,7 @@ def as_cirq_op(
def to_cirq_circuit_and_quregs(
self, qubit_manager: Optional['cirq.QubitManager'] = None, **cirq_quregs: 'CirqQuregInT'
- ) -> Tuple['cirq.FrozenCircuit', Dict[str, 'CirqQuregT']]:
+ ) -> tuple['cirq.FrozenCircuit', dict[str, 'CirqQuregT']]:
"""Convert this CompositeBloq to a `cirq.Circuit` and output qubit registers.
Args:
@@ -352,7 +343,7 @@ 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']:
"""`CompositeBloq` implementation of `Bloq.on_classical_vals`.
This override determines the classical action of this composite bloq by correctly
@@ -392,7 +383,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:
@@ -413,7 +404,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
@@ -452,7 +443,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`.
@@ -518,7 +509,7 @@ def flatten_once(
bb._i = max(binst.i for binst in self.bloq_instances) + 1
soq_map = bb.initial_soq_map(self.signature.lefts())
- new_out_soqs: Tuple[QVarT, ...]
+ new_out_soqs: tuple[QVarT, ...]
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.
@@ -585,7 +576,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)
@@ -625,7 +616,7 @@ def debug_text(self) -> str:
return delimited_gens
def wire_symbol(
- self, reg: Optional['Register'], idx: Tuple[int, ...] = tuple()
+ self, reg: Optional['Register'], idx: tuple[int, ...] = tuple()
) -> 'WireSymbol':
from qualtran.drawing import Text
@@ -673,16 +664,16 @@ 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."""
if binst not in binst_graph.nodes:
return [], []
- 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'])
@@ -693,7 +684,7 @@ def _get_soquet(
binst: 'BloqInstance',
reg_name: str,
right: bool = False,
- idx: Tuple[int, ...] = (),
+ idx: tuple[int, ...] = (),
*,
binst_graph: nx.DiGraph,
) -> '_Soquet':
@@ -730,7 +721,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:
@@ -747,7 +738,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:
@@ -770,7 +761,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:
@@ -784,7 +775,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:
@@ -803,7 +794,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:
@@ -823,14 +814,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.
@@ -845,7 +836,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())
@@ -901,7 +892,7 @@ def _process_soquets(
registers: Iterable[Register],
in_soqs: Mapping[str, SoquetInT],
debug_str: str,
- func: Callable[[_QVar, Register, Tuple[int, ...]], None],
+ func: Callable[[_QVar, Register, tuple[int, ...]], None],
) -> None:
"""Process and validate `in_soqs` in the context of `registers`.
@@ -926,7 +917,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
@@ -950,8 +941,8 @@ def _process_soquets(
def _map_soqs(
- soqs: Dict[str, _SoquetT], soq_map: Iterable[Tuple[_SoquetT, QVarT]]
-) -> Dict[str, QVarT]:
+ soqs: dict[str, _SoquetT], soq_map: Iterable[tuple[_SoquetT, QVarT]]
+) -> dict[str, QVarT]:
"""Map `soqs` according to `soq_map`.
See `CompositeBloq.iter_bloqsoqs` for example code. The public entry-point
@@ -969,7 +960,7 @@ def _map_soqs(
"""
# First: flatten out any numpy arrays
- flat_soq_map: Dict[_Soquet, _QVar] = {}
+ flat_soq_map: dict[_Soquet, _QVar] = {}
for old_soqs, new_soqs in soq_map:
if BloqBuilder.is_single(old_soqs):
assert BloqBuilder.is_single(new_soqs), new_soqs
@@ -1007,8 +998,8 @@ def _map_soqs(soqs: _SoquetT) -> 'QVarT':
def _map_flat_soqs(
- soqs: Dict[str, SoquetT], flat_soq_map: Dict[Soquet, Soquet]
-) -> Dict[str, SoquetT]:
+ soqs: dict[str, SoquetT], flat_soq_map: dict[Soquet, Soquet]
+) -> dict[str, SoquetT]:
# use vectorize to use the flat mapping.
def _map_soq(soq: Soquet) -> Soquet:
@@ -1027,7 +1018,7 @@ def _map_soqs(soqs: SoquetT) -> SoquetT:
def _update_flat_soq_map(
- soq_map: Iterable[Tuple[SoquetT, SoquetT]], flat_soq_map: Dict[Soquet, Soquet]
+ soq_map: Iterable[tuple[SoquetT, SoquetT]], flat_soq_map: dict[Soquet, Soquet]
):
"""Flatten SoquetT into a flat_soq_map. This function mutates `flat_soq_map`."""
for old_soqs, new_soqs in soq_map:
@@ -1107,15 +1098,15 @@ def build_composite_bloq(self, bb: BloqBuilder, q0, q1):
def __init__(self, add_registers_allowed: bool = True, *, bloq_key: Optional[str] = None):
# 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
@@ -1222,7 +1213,7 @@ def from_signature(
add_registers_allowed: bool = False,
*,
bloq_key: Optional[str] = None,
- ) -> Tuple['BloqBuilder', Dict[str, QVarT]]:
+ ) -> tuple['BloqBuilder', dict[str, QVarT]]:
"""Construct a BloqBuilder with a pre-specified signature.
This is safer if e.g. you're decomposing an existing Bloq and need the signatures
@@ -1231,7 +1222,7 @@ def from_signature(
# Initial construction: allow register addition for the following loop.
bb = cls(add_registers_allowed=True, bloq_key=bloq_key)
- initial_soqs: Dict[str, QVarT] = {}
+ initial_soqs: dict[str, QVarT] = {}
for reg in signature:
if reg.side & Side.LEFT:
register = bb.add_register_from_dtype(reg)
@@ -1281,8 +1272,8 @@ def is_ndarray(x):
@staticmethod
def map_soqs(
- soqs: Dict[str, _SoquetT], soq_map: Iterable[Tuple[_SoquetT, QVarT]]
- ) -> Dict[str, QVarT]:
+ soqs: dict[str, _SoquetT], soq_map: Iterable[tuple[_SoquetT, QVarT]]
+ ) -> dict[str, QVarT]:
"""Map `soqs` according to `soq_map`.
See `CompositeBloq.iter_bloqsoqs` for example code.
@@ -1305,7 +1296,7 @@ def _new_binst_i(self) -> int:
return i
def _make_qvar(
- self, binst: Union[BloqInstance, DanglingT], reg: Register, idx: Tuple[int, ...] = ()
+ self, binst: Union[BloqInstance, DanglingT], reg: Register, idx: tuple[int, ...] = ()
):
return _QVar(_Soquet(binst, reg, idx), bb=self)
@@ -1346,7 +1337,7 @@ def _add_cxn(
binst: Union[BloqInstance, DanglingT],
idxed_soq: _QVar,
reg: Register,
- idx: Tuple[int, ...],
+ idx: tuple[int, ...],
) -> None:
"""Helper function to be used as the base for the `func` argument of `_process_soquets`.
@@ -1366,7 +1357,7 @@ def _add_cxn(
cxn = Connection(idxed_soq.soquet, self._make_qvar(binst, reg, idx).soquet)
self._cxns.append(cxn)
- def add_t(self, bloq: Bloq, **in_soqs: SoquetInT) -> Tuple[QVarT, ...]:
+ def add_t(self, bloq: Bloq, **in_soqs: SoquetInT) -> tuple[QVarT, ...]:
"""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
@@ -1388,7 +1379,7 @@ def add_t(self, bloq: Bloq, **in_soqs: SoquetInT) -> Tuple[QVarT, ...]:
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
@@ -1410,7 +1401,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,
):
@@ -1480,7 +1471,7 @@ def add(self, bloq: Bloq, **in_soqs: SoquetInT):
def _add_binst(
self, binst: BloqInstance, in_soqs: Mapping[str, SoquetInT]
- ) -> Iterator[Tuple[str, QVarT]]:
+ ) -> Iterator[tuple[str, QVarT]]:
"""Add a bloq instance.
Warning! Do not use this function externally! Untold bad things will happen if
@@ -1490,7 +1481,7 @@ def _add_binst(
bloq = binst.bloq
- def _add(idxed_soq: _QVar, reg: Register, idx: Tuple[int, ...]):
+ def _add(idxed_soq: _QVar, reg: Register, idx: tuple[int, ...]):
# close over `binst`
return self._add_cxn(binst, idxed_soq, reg, idx)
@@ -1504,18 +1495,18 @@ def _add(idxed_soq: _QVar, reg: Register, idx: Tuple[int, ...]):
(reg.name, self._reg_to_qvar(binst, reg, track=True)) for reg in bloq.signature.rights()
)
- def initial_soq_map(self, lefts: Iterable[Register]) -> List[Tuple['_SoquetT', 'QVarT']]:
+ def initial_soq_map(self, lefts: Iterable[Register]) -> list[tuple['_SoquetT', 'QVarT']]:
"""The initial mapping from old soquets to new soquets known to this bloq builder.
This is used in patterns when you plan on calling `BloqBuilder.map_soqs` to add
connections from an "old" composite bloq to the "new" bloq we're currently building.
"""
- soq_map: List[Tuple['_SoquetT', 'QVarT']] = [
+ soq_map: list[tuple['_SoquetT', 'QVarT']] = [
(_reg_to_soq(LeftDangle, reg), self._reg_to_qvar(LeftDangle, reg)) for reg in lefts
]
return soq_map
- def add_from(self, bloq: Bloq, **in_soqs: SoquetInT) -> Tuple['QVarT', ...]:
+ def add_from(self, bloq: Bloq, **in_soqs: SoquetInT) -> tuple['QVarT', ...]:
"""Add all the sub-bloqs from `bloq` to the compute graph.
This is useful for adding multiple bloq instances at once in a "flat" or "unrolled" way.
@@ -1541,10 +1532,10 @@ def add_from(self, bloq: Bloq, **in_soqs: SoquetInT) -> Tuple['QVarT', ...]:
for k, v in in_soqs.items():
in_soqs[k] = np.asarray(v)
- in_soqs = cast(Dict[str, QVarT], in_soqs)
+ in_soqs = cast(dict[str, QVarT], in_soqs)
# Initial mapping of LeftDangle according to user-provided in_soqs.
- soq_map: List[Tuple[_SoquetT, QVarT]] = [
+ soq_map: list[tuple[_SoquetT, QVarT]] = [
(_reg_to_soq(LeftDangle, reg), in_soqs[reg.name]) for reg in cbloq.signature.lefts()
]
@@ -1614,7 +1605,7 @@ def finalize(self, **final_soqs: SoquetInT) -> CompositeBloq:
# If items from `final_soqs` don't already exist in `_regs`, add RIGHT registers
# for them. Then call `_finalize_strict` where the actual dangling connections are added.
- def _infer_shaped_dtype(soq: SoquetT) -> Tuple['QCDType', Tuple[int, ...]]:
+ def _infer_shaped_dtype(soq: SoquetT) -> tuple['QCDType', tuple[int, ...]]:
"""Extract (dtype, shape) from SoquetT"""
if BloqBuilder.is_single(soq):
return soq.item().dtype, ()
@@ -1647,7 +1638,7 @@ def _finalize_strict(self, **final_soqs: SoquetInT) -> CompositeBloq:
"""
signature = Signature(self._regs)
- def _fin(idxed_soq: _QVar, reg: Register, idx: Tuple[int, ...]):
+ def _fin(idxed_soq: _QVar, 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 65cbda8c09..a1e3aab142 100644
--- a/qualtran/_infra/composite_bloq_test.py
+++ b/qualtran/_infra/composite_bloq_test.py
@@ -13,7 +13,7 @@
# limitations under the License.
from functools import cached_property
-from typing import Any, cast, Dict
+from typing import Any, cast
import attrs
import networkx as nx
@@ -82,7 +82,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}
@@ -369,7 +369,7 @@ def build_composite_bloq(
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 61578226ad..ba2cf779f5 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
@@ -57,7 +45,7 @@
_CVInType: TypeAlias = Union[_CVInLeafT, Sequence['_CVInType']]
-def _cvs_convert(cvs: _CVInType) -> Tuple[Union[NDArray[np.integer], Shaped], ...]:
+def _cvs_convert(cvs: _CVInType) -> tuple[Union[NDArray[np.integer], Shaped], ...]:
if isinstance(cvs, Shaped):
return (cvs,)
if isinstance(cvs, (int, np.integer)):
@@ -112,10 +100,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
)
@@ -127,7 +115,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)
@@ -159,7 +147,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
@@ -203,7 +191,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]
@@ -220,7 +208,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]:
@@ -267,7 +255,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()]
@@ -334,11 +322,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
@@ -349,7 +337,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
@@ -381,7 +369,7 @@ def _thru_registers_only(self) -> bool:
return self.signature.thru_registers_only
@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
@@ -392,8 +380,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)
@@ -416,7 +404,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())
@@ -515,8 +503,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
@@ -527,7 +515,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:
@@ -555,7 +543,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)
@@ -617,7 +605,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`.
@@ -630,7 +618,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}")
@@ -642,7 +630,7 @@ 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 = bb.initial_soq_map(cbloq.signature.lefts())
for binst, _in_soqs, old_out_soqs in cbloq.iter_bloqsoqs():
@@ -686,7 +674,7 @@ def _pkg_(cls) -> str:
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 implementation 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_test.py b/qualtran/_infra/data_types_test.py
index aadbe3d24c..6bd6018d44 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, Iterable, List, Sequence, Union
+from collections.abc import Iterable, Sequence
+from typing import Any, Union
import attrs
import galois
@@ -628,7 +629,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)
diff --git a/qualtran/_infra/gate_with_registers.py b/qualtran/_infra/gate_with_registers.py
index 80af5763ce..193b936a80 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']], # type: ignore[type-var]
-) -> 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']]: # type: ignore[type-var]
+def get_named_qubits(registers: Iterable[Register]) -> dict[str, NDArray['cirq.Qid']]: # type: ignore[type-var]
"""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:
@@ -296,7 +285,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:
@@ -312,7 +301,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
@@ -384,7 +373,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':
@@ -449,7 +438,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()`"""
@@ -464,7 +453,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':
@@ -515,8 +504,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 d79a66d1ec..f1e8920bfc 100644
--- a/qualtran/_infra/quantum_graph.py
+++ b/qualtran/_infra/quantum_graph.py
@@ -15,7 +15,7 @@
"""Plumbing for bloq-to-bloq `Connection`s."""
import warnings
from functools import cached_property
-from typing import Optional, Tuple, TYPE_CHECKING, Union
+from typing import Optional, TYPE_CHECKING, Union
import attrs
import numpy as np
@@ -71,7 +71,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
@@ -100,7 +100,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):
@@ -116,7 +116,7 @@ def dtype(self) -> 'QCDType':
return self.reg.dtype
@property
- def shape(self) -> Tuple[int, ...]:
+ def shape(self) -> tuple[int, ...]:
return ()
def item(self, *args) -> '_Soquet':
@@ -152,7 +152,7 @@ def dtype(self) -> 'QCDType':
return self.soquet.dtype
@property
- def shape(self) -> Tuple[int, ...]:
+ def shape(self) -> tuple[int, ...]:
return ()
def item(self, *args):
diff --git a/qualtran/_infra/registers.py b/qualtran/_infra/registers.py
index e25146afcf..c1a323a8d9 100644
--- a/qualtran/_infra/registers.py
+++ b/qualtran/_infra/registers.py
@@ -17,8 +17,9 @@
import enum
import itertools
from collections import defaultdict
+from collections.abc import Iterable, Iterator
from functools import cached_property
-from typing import cast, Dict, Iterable, Iterator, List, overload, Tuple, Union
+from typing import cast, overload, Union
import attrs
from attrs import field, frozen
@@ -78,7 +79,7 @@ class Register:
name: str
dtype: QCDType = field(converter=_consume_register_dtype)
- _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
@@ -107,20 +108,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])
@@ -158,7 +159,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 = {}
@@ -372,7 +373,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.
@@ -433,7 +434,7 @@ def __repr__(self):
def __getitem__(self, key: int) -> Register: ...
@overload
- def __getitem__(self, key: slice) -> Tuple[Register, ...]: ...
+ def __getitem__(self, key: slice) -> tuple[Register, ...]: ...
def __getitem__(self, key):
return self._registers[key]
diff --git a/qualtran/bloqify_syntax/_infra.py b/qualtran/bloqify_syntax/_infra.py
index 257219e000..70ad7eecc3 100644
--- a/qualtran/bloqify_syntax/_infra.py
+++ b/qualtran/bloqify_syntax/_infra.py
@@ -13,7 +13,8 @@
# limitations under the License.
# pylint: disable=keyword-arg-before-vararg
import inspect
-from typing import Any, Dict, Optional, Protocol, Sequence, Set, TYPE_CHECKING
+from collections.abc import Sequence
+from typing import Any, Optional, Protocol, TYPE_CHECKING
import attrs
import numpy as np
@@ -30,7 +31,7 @@ class _TracingBloqFuncT(Protocol):
__name__: str
- def __call__(self, bb: 'BloqBuilder', *args: Any, **kwargs: Any) -> Dict[str, Any]:
+ def __call__(self, bb: 'BloqBuilder', *args: Any, **kwargs: Any) -> dict[str, Any]:
"""the structure of the function.
During normal operation
@@ -56,8 +57,8 @@ class _BloqifyPrepResult:
"""Container for the results of tracing a function to build a Bloq."""
cbloq: 'CompositeBloq'
- in_qargnames: Set[str]
- out_qargnames: Set[str]
+ in_qargnames: set[str]
+ out_qargnames: set[str]
explicit_bb: Optional['BloqBuilder'] = None
found_bb: Optional['BloqBuilder'] = None
diff --git a/qualtran/bloqify_syntax/_infra_test.py b/qualtran/bloqify_syntax/_infra_test.py
index 4e4a0ea6a1..4604cbd1ee 100644
--- a/qualtran/bloqify_syntax/_infra_test.py
+++ b/qualtran/bloqify_syntax/_infra_test.py
@@ -12,7 +12,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import inspect
-from typing import Dict
import pytest
@@ -42,7 +41,7 @@ def test_inspect():
@qlt.bloqify
-def minimal_bloq(bb: 'BloqBuilder', x: 'QVar') -> Dict[str, 'QVar']:
+def minimal_bloq(bb: 'BloqBuilder', x: 'QVar') -> dict[str, 'QVar']:
return {'x': x}
@@ -60,7 +59,7 @@ def test_bloqify_make():
def test_bloqify_call():
@qlt.bloqify
- def outer_program(bb: 'BloqBuilder', x: 'QVar') -> Dict[str, 'QVar']:
+ def outer_program(bb: 'BloqBuilder', x: 'QVar') -> dict[str, 'QVar']:
x = minimal_bloq(bb, x=x)
return {'x': x}
@@ -71,7 +70,7 @@ def outer_program(bb: 'BloqBuilder', x: 'QVar') -> Dict[str, 'QVar']:
def test_bloqify_inline():
@qlt.bloqify
- def outer_program(bb: 'BloqBuilder', x: 'QVar') -> Dict[str, 'QVar']:
+ def outer_program(bb: 'BloqBuilder', x: 'QVar') -> dict[str, 'QVar']:
x_out = minimal_bloq.inline(bb, x=x)
return {'x': x_out[0]}
@@ -92,7 +91,7 @@ def bad_bloq(bb: 'BloqBuilder', x: 'QVar'):
return x # Not a dict
@qlt.bloqify
- def outer_program(bb: 'BloqBuilder', x: 'QVar') -> Dict[str, 'QVar']:
+ def outer_program(bb: 'BloqBuilder', x: 'QVar') -> dict[str, 'QVar']:
x = bad_bloq(bb, x=x)
return {'x': x}
diff --git a/qualtran/bloqs/arithmetic/addition.py b/qualtran/bloqs/arithmetic/addition.py
index 96a80a8f90..4c6cce9e80 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
@@ -117,7 +118,7 @@ def decompose_bloq(self) -> 'CompositeBloq':
def on_classical_vals(
self, a: 'ClassicalValT', b: 'ClassicalValT'
- ) -> Dict[str, 'ClassicalValT']:
+ ) -> dict[str, 'ClassicalValT']:
unsigned = isinstance(self.b_dtype, (QUInt, QMontgomeryUInt))
b_bitsize = self.b_dtype.bitsize
return {
@@ -130,7 +131,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':
@@ -207,7 +208,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(
@@ -299,7 +300,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':
@@ -307,7 +308,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:
@@ -329,7 +330,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]),
@@ -359,7 +360,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)
@@ -432,7 +433,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}")
@@ -452,7 +453,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 6b3d696dfe..c13f1a6081 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
@@ -225,7 +226,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 450b8951c9..2158744351 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:
@@ -464,7 +465,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('')
@@ -476,7 +477,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:
@@ -519,7 +520,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.
@@ -585,7 +586,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
@@ -669,7 +670,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':
@@ -682,7 +683,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
)
@@ -742,7 +743,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)
@@ -753,7 +754,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}.")
@@ -770,7 +771,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
@@ -871,7 +872,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('')
@@ -930,7 +931,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':
@@ -978,7 +979,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':
@@ -991,7 +992,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`.")
@@ -1017,7 +1018,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)}
@@ -1053,7 +1054,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':
@@ -1074,7 +1075,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=}")
@@ -1141,7 +1142,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('')
@@ -1157,7 +1158,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`.")
@@ -1207,7 +1208,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}
@@ -1279,7 +1280,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)
@@ -1320,7 +1321,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)
@@ -1368,7 +1369,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`.")
@@ -1473,7 +1474,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:
@@ -1486,7 +1487,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:
@@ -1499,7 +1500,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)
@@ -1517,7 +1518,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 35ea8b6334..50cac474cd 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
@@ -104,7 +104,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:
@@ -137,7 +137,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 c5cbb4b829..adfe2af08e 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 = []
@@ -112,9 +113,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 65e37bcaac..201a36e4a5 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
@@ -124,7 +125,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)
@@ -278,7 +279,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 88ae04a25d..b0747a4116 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/t_complexity_of_comparison_gates.ipynb b/qualtran/bloqs/arithmetic/t_complexity_of_comparison_gates.ipynb
index 9ff6e0d10c..10b5e6ca99 100644
--- a/qualtran/bloqs/arithmetic/t_complexity_of_comparison_gates.ipynb
+++ b/qualtran/bloqs/arithmetic/t_complexity_of_comparison_gates.ipynb
@@ -75,7 +75,7 @@
"metadata": {},
"outputs": [],
"source": [
- "from typing import Sequence\n",
+ "from collections.abc import Sequence\n",
"\n",
"import cirq\n",
"from qualtran.cirq_interop.t_complexity_protocol import t_complexity_compat\n",
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 81153529a4..691435a0f3 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']
@@ -120,7 +121,7 @@ def as_cirq_op(
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
@@ -132,7 +133,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/discard.py b/qualtran/bloqs/basic_gates/discard.py
index 90df55c367..02a7f22f89 100644
--- a/qualtran/bloqs/basic_gates/discard.py
+++ b/qualtran/bloqs/basic_gates/discard.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
from attrs import frozen
@@ -34,12 +34,12 @@ class Discard(Bloq):
def signature(self) -> 'Signature':
return Signature([Register('c', CBit(), side=Side.LEFT)])
- def on_classical_vals(self, c: int) -> Dict[str, 'ClassicalValT']:
+ def on_classical_vals(self, c: int) -> dict[str, 'ClassicalValT']:
return {}
def my_tensors(
- self, incoming: Dict[str, 'ConnectionT'], outgoing: Dict[str, 'ConnectionT']
- ) -> List['DiscardInd']:
+ self, incoming: dict[str, 'ConnectionT'], outgoing: dict[str, 'ConnectionT']
+ ) -> list['DiscardInd']:
from qualtran.simulation.tensor import DiscardInd
@@ -60,8 +60,8 @@ def signature(self) -> 'Signature':
return Signature([Register('q', QBit(), side=Side.LEFT)])
def my_tensors(
- self, incoming: Dict[str, 'ConnectionT'], outgoing: Dict[str, 'ConnectionT']
- ) -> List['DiscardInd']:
+ self, incoming: dict[str, 'ConnectionT'], outgoing: dict[str, 'ConnectionT']
+ ) -> list['DiscardInd']:
from qualtran.simulation.tensor import DiscardInd
diff --git a/qualtran/bloqs/basic_gates/global_phase.py b/qualtran/bloqs/basic_gates/global_phase.py
index db47d13507..076d2cb592 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 a78c6c7d91..ecb6cf1f7d 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
@@ -70,8 +71,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 [
@@ -83,7 +84,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):
@@ -96,12 +97,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:
@@ -114,8 +115,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)
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 53e55533d5..5cc643c137 100644
--- a/qualtran/bloqs/basic_gates/on_each.py
+++ b/qualtran/bloqs/basic_gates/on_each.py
@@ -15,7 +15,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
@@ -71,7 +71,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)
@@ -82,7 +82,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 0328d29ff4..e295257e82 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, Optional, Tuple, TYPE_CHECKING
+from typing import Optional, TYPE_CHECKING
import attrs
import numpy as np
@@ -61,7 +61,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):
@@ -89,7 +89,7 @@ def _circuit_diagram_info_(
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:
sub_title = self.bloq.wire_symbol(None, idx)
diff --git a/qualtran/bloqs/basic_gates/rotation.py b/qualtran/bloqs/basic_gates/rotation.py
index d136e7f124..9e12a6e78b 100644
--- a/qualtran/bloqs/basic_gates/rotation.py
+++ b/qualtran/bloqs/basic_gates/rotation.py
@@ -42,8 +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, TYPE_CHECKING, Union
+from typing import Optional, Type, TYPE_CHECKING, Union
import attrs
import cirq
@@ -135,15 +136,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 +158,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}')
@@ -216,7 +217,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), anc = bb.add(And(), ctrl=q)
@@ -300,7 +301,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}')
@@ -375,7 +376,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}')
@@ -452,7 +453,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)
@@ -469,7 +470,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))
@@ -499,7 +500,7 @@ def _controlled_rp_circuit(
eps: SymbolicFloat,
ctrl: 'Soquet',
q: 'Soquet',
-) -> Dict[str, 'SoquetT']:
+) -> dict[str, 'SoquetT']:
from qualtran.bloqs.basic_gates import CNOT
t = angle / np.pi
@@ -554,7 +555,7 @@ def signature(self) -> 'Signature':
def build_composite_bloq(
self, bb: 'BloqBuilder', ctrl: 'Soquet', q: 'Soquet'
- ) -> Dict[str, 'SoquetT']:
+ ) -> dict[str, 'SoquetT']:
return _controlled_rp_circuit(
bb, single_q_pow_cls=ZPowGate, angle=self.angle, eps=self.eps, ctrl=ctrl, q=q
)
@@ -629,7 +630,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))
@@ -694,7 +695,7 @@ def as_pl_op(self, wires: 'Wires') -> 'Operation':
def adjoint(self) -> 'Ry':
return attrs.evolve(self, angle=-self.angle)
- 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)
@@ -708,7 +709,7 @@ def get_ctrl_system(self, ctrl_spec: 'CtrlSpec') -> Tuple['Bloq', 'AddControlled
ctrl_reg_name='ctrl',
)
- 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))
@@ -753,7 +754,7 @@ def signature(self) -> 'Signature':
def build_composite_bloq(
self, bb: 'BloqBuilder', ctrl: 'Soquet', q: 'Soquet'
- ) -> Dict[str, 'SoquetT']:
+ ) -> dict[str, 'SoquetT']:
return _controlled_rp_circuit(
bb, single_q_pow_cls=YPowGate, angle=self.angle, eps=self.eps, ctrl=ctrl, q=q
)
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 294c905cdb..2805908f06 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
@@ -84,7 +85,7 @@ def as_cirq_op(
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
@@ -97,8 +98,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()
@@ -108,7 +109,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':
@@ -178,8 +179,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()
@@ -189,7 +190,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:
@@ -204,7 +205,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':
@@ -253,7 +254,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.")
@@ -270,10 +271,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':
@@ -292,8 +293,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]
@@ -347,7 +348,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.")
@@ -364,7 +365,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:
@@ -389,7 +390,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 dd3ea05cad..3c5fdbc7c9 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 Dict, Iterable, List, Optional, Sequence, Tuple, TYPE_CHECKING, Union
+from typing import Optional, TYPE_CHECKING, Union
import numpy as np
from attrs import frozen
@@ -73,9 +74,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
@@ -106,7 +107,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
@@ -118,7 +119,7 @@ def as_cirq_op(
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
@@ -129,7 +130,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:
@@ -141,7 +142,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 XGate
# Perform the Logical-AND of `ctrl_spec` with Toffoli's implicit XGate ctrl spec
@@ -154,8 +155,8 @@ def get_ctrl_system(self, ctrl_spec: 'CtrlSpec') -> Tuple['Bloq', 'AddControlled
# We have to wire up the *new* ctrl registers vs Toffoli's *existing* ctrl register
# while also translating between Toffoli() and ControlledViaAnd(XGate(), cvs=(1,1)).
def adder2(
- 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']]:
# Note: in adder2, `ctrl_soqs` matches the requested `ctrl_spec`
# in adder1, `ctrl_soqs` matches `anded_ctrl_spec`
# Note: in adder2 `in_soqs` matches the signature of Toffoli
diff --git a/qualtran/bloqs/basic_gates/x_basis.py b/qualtran/bloqs/basic_gates/x_basis.py
index 3cf6b6d7e2..2ff25e988a 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
@@ -81,8 +82,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
@@ -94,7 +95,7 @@ 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}")
@@ -114,7 +115,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('')
@@ -224,8 +225,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 [
@@ -234,7 +235,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():
@@ -245,20 +246,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')
@@ -271,7 +272,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:
@@ -298,7 +299,7 @@ def signature(self) -> 'Signature':
[Register('q', QBit(), side=Side.LEFT), Register('c', CBit(), side=Side.RIGHT)]
)
- def on_classical_vals(self, q: int) -> Dict[str, 'ClassicalValRetT']:
+ def on_classical_vals(self, q: int) -> dict[str, 'ClassicalValRetT']:
if q not in [0, 1]:
raise ValueError(f"Invalid classical value encountered in {self}: {q}")
return {'c': ClassicalValDistribution(2)}
@@ -311,8 +312,8 @@ def basis_state_phase(self, q: int) -> Union[complex, MeasurementPhase]:
raise ValueError(f"Invalid classical value encountered in {self}: {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
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 eabe43cc35..9cfa88d12c 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,
@@ -128,7 +118,7 @@ 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}")
@@ -147,7 +137,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('')
@@ -260,8 +250,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 [
@@ -270,7 +260,7 @@ def my_tensors(
)
]
- 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
@@ -279,7 +269,7 @@ def basis_state_phase(self, q: int) -> Optional[complex]:
return -1
return 1
- 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)
@@ -287,8 +277,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,)
@@ -297,7 +287,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
@@ -309,7 +299,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('')
@@ -346,8 +336,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))
@@ -357,7 +347,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
@@ -369,21 +359,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
@@ -421,8 +411,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
@@ -489,7 +479,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:
@@ -502,14 +492,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))
@@ -519,7 +509,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}
@@ -534,7 +524,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 1d36f66986..fd0cd39519 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
@@ -126,7 +126,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)
@@ -237,11 +237,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:
@@ -264,7 +264,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)
@@ -277,7 +277,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)))
@@ -336,7 +336,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 1533ffaf67..ebb4da16b4 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)
@@ -214,7 +215,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)
@@ -267,7 +268,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 1d9750ac07..2c06e716d3 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
@@ -75,11 +75,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 b6726b35d2..f2598ccff0 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
@@ -238,7 +238,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=}")
@@ -285,7 +285,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
@@ -323,7 +323,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)
@@ -342,7 +342,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=}")
@@ -361,7 +361,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)
@@ -408,7 +408,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 f714c3e619..8d319dbcf1 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
@@ -31,10 +32,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 905f79a2fe..3887685a0a 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, Union
+from collections.abc import Iterable, Sequence
+from typing import Optional, Union
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 9c73726f35..e6d9119232 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
@@ -77,14 +77,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
@@ -94,7 +94,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'
@@ -102,7 +102,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 8cebbb5809..d7bb9e5647 100644
--- a/qualtran/bloqs/bookkeeping/partition.py
+++ b/qualtran/bloqs/bookkeeping/partition.py
@@ -12,8 +12,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import abc
+from collections.abc import Sequence
from functools import cached_property
-from typing import Dict, List, Sequence, Tuple, TYPE_CHECKING
+from typing import TYPE_CHECKING
import numpy as np
import sympy
@@ -76,7 +77,7 @@ def _validate(self):
def decompose_bloq(self) -> 'CompositeBloq':
raise DecomposeTypeError(f'{self} is atomic')
- 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']]:
self._validate()
if self.partition:
outregs = {}
@@ -94,8 +95,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):
@@ -119,7 +120,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
@@ -143,7 +144,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:
@@ -151,7 +152,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('')
@@ -176,7 +177,7 @@ class Partition(_PartitionBase):
"""
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
diff --git a/qualtran/bloqs/bookkeeping/partition_test.py b/qualtran/bloqs/bookkeeping/partition_test.py
index c6c3236332..cf769d62c4 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 785ae65bfd..1726e0e48a 100644
--- a/qualtran/bloqs/chemistry/black_boxes.py
+++ b/qualtran/bloqs/chemistry/black_boxes.py
@@ -17,7 +17,7 @@
"""
from functools import cached_property
-from typing import Optional, Tuple, TYPE_CHECKING
+from typing import Optional, TYPE_CHECKING
import attrs
import numpy as np
@@ -191,7 +191,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
@@ -203,7 +203,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 0fcccd7290..f509f2aad7 100644
--- a/qualtran/bloqs/chemistry/chem_tutorials.py
+++ b/qualtran/bloqs/chemistry/chem_tutorials.py
@@ -13,7 +13,7 @@
# 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
@@ -35,7 +35,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 8afec09924..241a1ff995 100644
--- a/qualtran/bloqs/chemistry/df/double_factorization.py
+++ b/qualtran/bloqs/chemistry/df/double_factorization.py
@@ -31,8 +31,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
@@ -194,7 +195,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,
@@ -439,7 +440,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 b28bdbbe54..1224a99f07 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 6d912f2ae1..d1529a0ff5 100644
--- a/qualtran/bloqs/chemistry/hubbard_model/qubitization/select_hubbard.py
+++ b/qualtran/bloqs/chemistry/hubbard_model/qubitization/select_hubbard.py
@@ -38,8 +38,9 @@
- $p>q$, YZY term.
"""
+from collections.abc import Iterator
from functools import cached_property
-from typing import Dict, Iterator, Optional, Set, Tuple, Union
+from typing import Optional, Union
import attrs
import cirq
@@ -139,11 +140,11 @@ def log_m(self) -> SymbolicInt:
return ceil(log2(self.x_dim))
@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)),
@@ -156,7 +157,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
@@ -203,7 +204,7 @@ def decompose_from_registers(
x_dim=self.x_dim, y_dim=self.y_dim, control_val=self.control_val
).on_registers(x=q_x, y=q_y, V=V, control=control, target=target)
- 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(
@@ -282,11 +283,11 @@ def N(self):
return 2 * self.x_dim * self.y_dim
@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('x', BQUInt(self.log_m, self.x_dim)),
Register('y', BQUInt(self.log_m, self.y_dim)),
@@ -294,7 +295,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.N)),)
@cached_property
@@ -314,7 +315,7 @@ def _target_cirq_gate(self):
def build_composite_bloq(
self, bb: 'BloqBuilder', x, y, spin, target, control=None
- ) -> Dict[str, 'SoquetT']:
+ ) -> dict[str, 'SoquetT']:
if is_symbolic(self.x_dim, self.y_dim):
raise DecomposeTypeError(f"Cannot decompose symbolic x_dim, y_dim in {self}")
@@ -338,7 +339,7 @@ def build_composite_bloq(
def build_call_graph(
self, ssa: 'SympySymbolAllocator'
- ) -> Union['BloqCountDictT', Set['BloqCountT']]:
+ ) -> Union['BloqCountDictT', set['BloqCountT']]:
count = self.N - 1
if self.control_val is None:
@@ -346,7 +347,7 @@ def build_call_graph(
return {And(): count, And().adjoint(): count}
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 TextBox("")
@@ -420,11 +421,11 @@ def log_m(self) -> SymbolicInt:
return ceil(log2(self.x_dim))
@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('V', BQUInt(1, 2)),
Register('x', BQUInt(self.log_m, self.x_dim)),
@@ -432,7 +433,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
@@ -443,7 +444,7 @@ def signature(self) -> Signature:
def build_composite_bloq(
self, bb: 'BloqBuilder', V, x, y, target, control=None
- ) -> Dict[str, 'SoquetT']:
+ ) -> dict[str, 'SoquetT']:
if is_symbolic(self.x_dim, self.y_dim):
raise DecomposeTypeError(f"Cannot decompose symbolic x_dim, y_dim in {self}")
@@ -490,7 +491,7 @@ def build_composite_bloq(
def build_call_graph(
self, ssa: 'SympySymbolAllocator'
- ) -> Union['BloqCountDictT', Set['BloqCountT']]:
+ ) -> Union['BloqCountDictT', set['BloqCountT']]:
half_N = self.x_dim * self.y_dim
count = half_N
if self.control_val is None:
@@ -498,7 +499,7 @@ def build_call_graph(
return {And(): count, And().adjoint(): count, CNOT(): half_N - 1, CZ(): half_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 TextBox('')
diff --git a/qualtran/bloqs/chemistry/ising/hamiltonian.py b/qualtran/bloqs/chemistry/ising/hamiltonian.py
index d99acc9f28..e511b71c79 100644
--- a/qualtran/bloqs/chemistry/ising/hamiltonian.py
+++ b/qualtran/bloqs/chemistry/ising/hamiltonian.py
@@ -13,7 +13,7 @@
# 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
@@ -40,8 +40,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 5ad3c214a5..f67a94123d 100644
--- a/qualtran/bloqs/chemistry/pbc/first_quantization/prepare_nu.py
+++ b/qualtran/bloqs/chemistry/pbc/first_quantization/prepare_nu.py
@@ -14,7 +14,7 @@
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
@@ -64,7 +64,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^μ)|μ⟩')
@@ -116,7 +116,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^-μ)|μ⟩|ν⟩')
@@ -166,7 +166,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')
@@ -216,7 +216,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)')
@@ -299,7 +299,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')
@@ -369,7 +369,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)
@@ -405,7 +405,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 03f2c20113..792301009a 100644
--- a/qualtran/bloqs/chemistry/pbc/first_quantization/prepare_t.py
+++ b/qualtran/bloqs/chemistry/pbc/first_quantization/prepare_t.py
@@ -14,7 +14,7 @@
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
@@ -62,7 +62,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⟩')
@@ -110,7 +110,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)
@@ -125,7 +125,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 f1ce48e799..813a1d0da3 100644
--- a/qualtran/bloqs/chemistry/pbc/first_quantization/prepare_uv.py
+++ b/qualtran/bloqs/chemistry/pbc/first_quantization/prepare_uv.py
@@ -14,7 +14,7 @@
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
@@ -86,7 +86,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
)
@@ -102,7 +102,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 2637603b2b..92ca53016f 100644
--- a/qualtran/bloqs/chemistry/pbc/first_quantization/projectile/prepare_nu.py
+++ b/qualtran/bloqs/chemistry/pbc/first_quantization/projectile/prepare_nu.py
@@ -14,7 +14,7 @@
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
@@ -136,7 +136,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 35949bab8c..95b4ee8a65 100644
--- a/qualtran/bloqs/chemistry/pbc/first_quantization/projectile/prepare_uv.py
+++ b/qualtran/bloqs/chemistry/pbc/first_quantization/projectile/prepare_uv.py
@@ -12,9 +12,8 @@
# 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."""
-
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 0038941620..9b235c0dbb 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
@@ -14,7 +14,7 @@
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
@@ -105,7 +105,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)
@@ -128,7 +128,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:
@@ -142,7 +142,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':
@@ -159,7 +159,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,
@@ -248,7 +248,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()
@@ -278,14 +278,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)
@@ -311,7 +311,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
)
@@ -423,7 +423,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,)),
@@ -432,7 +432,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()
@@ -453,7 +453,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,)),
@@ -465,7 +465,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)
@@ -490,7 +490,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 5d8734b08e..93b444a9f6 100644
--- a/qualtran/bloqs/chemistry/pbc/first_quantization/projectile/select_t.py
+++ b/qualtran/bloqs/chemistry/pbc/first_quantization/projectile/select_t.py
@@ -14,7 +14,7 @@
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
@@ -72,7 +72,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 9505d95c88..337b07a57c 100644
--- a/qualtran/bloqs/chemistry/pbc/first_quantization/projectile/select_uv.py
+++ b/qualtran/bloqs/chemistry/pbc/first_quantization/projectile/select_uv.py
@@ -15,7 +15,7 @@
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
@@ -77,7 +77,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 ab44f020c2..d713b1ffa3 100644
--- a/qualtran/bloqs/chemistry/pbc/first_quantization/select_and_prepare.py
+++ b/qualtran/bloqs/chemistry/pbc/first_quantization/select_and_prepare.py
@@ -14,7 +14,7 @@
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
@@ -75,7 +75,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)
@@ -139,7 +139,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.
@@ -164,7 +164,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':
@@ -177,7 +177,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(
@@ -245,7 +245,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()
@@ -273,7 +273,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
@@ -284,7 +284,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)
@@ -307,7 +307,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
@@ -413,7 +413,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()),
@@ -422,7 +422,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()
@@ -442,7 +442,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
@@ -451,7 +451,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)
@@ -475,7 +475,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 9876b07993..c4ac2acd5e 100644
--- a/qualtran/bloqs/chemistry/pbc/first_quantization/select_t.py
+++ b/qualtran/bloqs/chemistry/pbc/first_quantization/select_t.py
@@ -14,7 +14,7 @@
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
@@ -60,7 +60,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 69ee1af0d7..f6ceb07e74 100644
--- a/qualtran/bloqs/chemistry/pbc/first_quantization/select_uv.py
+++ b/qualtran/bloqs/chemistry/pbc/first_quantization/select_uv.py
@@ -14,7 +14,7 @@
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
@@ -58,7 +58,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)
@@ -115,7 +115,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 22a2dc360b..4916191836 100644
--- a/qualtran/bloqs/chemistry/quad_fermion/givens_bloq.py
+++ b/qualtran/bloqs/chemistry/quad_fermion/givens_bloq.py
@@ -47,7 +47,6 @@
"""
from functools import cached_property
-from typing import Dict
from attrs import frozen
@@ -121,7 +120,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)
@@ -215,7 +214,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 69423731e6..99c3e9037a 100644
--- a/qualtran/bloqs/chemistry/thc/prepare.py
+++ b/qualtran/bloqs/chemistry/thc/prepare.py
@@ -14,7 +14,7 @@
"""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
@@ -111,7 +111,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)
@@ -124,7 +124,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))
@@ -261,11 +261,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
@@ -349,7 +349,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)
@@ -367,7 +367,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())),
@@ -377,7 +377,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),
@@ -388,7 +388,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(
@@ -413,12 +413,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}_')
@@ -430,7 +430,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 a98c0d6851..9977cff2c8 100644
--- a/qualtran/bloqs/chemistry/thc/select_bloq.py
+++ b/qualtran/bloqs/chemistry/thc/select_bloq.py
@@ -15,7 +15,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
@@ -164,11 +164,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)),
@@ -186,13 +186,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']
@@ -315,7 +315,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 526aa6556e..d74a32c6da 100644
--- a/qualtran/bloqs/chemistry/trotter/grid_ham/inverse_sqrt.py
+++ b/qualtran/bloqs/chemistry/trotter/grid_ham/inverse_sqrt.py
@@ -14,7 +14,7 @@
"""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
@@ -28,7 +28,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
@@ -60,7 +60,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.
@@ -166,7 +166,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)
@@ -218,7 +218,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 0438e19650..92d511a59a 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,14 +66,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("U_T(dt)")
return super().wire_symbol(reg, idx)
def build_composite_bloq(
self, bb: BloqBuilder, *, system: NDArray[Soquet] # type: ignore[type-var]
- ) -> Dict[str, SoquetT]:
+ ) -> dict[str, SoquetT]:
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 de71563f8c..c27dff1049 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
@@ -66,7 +66,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
@@ -83,7 +83,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')
@@ -91,7 +91,7 @@ def wire_symbol(
def build_composite_bloq(
self, bb: BloqBuilder, *, system_i: SoquetT, system_j: SoquetT
- ) -> Dict[str, SoquetT]:
+ ) -> dict[str, SoquetT]:
if not (BloqBuilder.is_ndarray(system_i) and BloqBuilder.is_ndarray(system_j)):
raise ValueError("system_i and system_j must be numpy arrays of Soquet")
# compute r_i - r_j
@@ -219,13 +219,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 not BloqBuilder.is_ndarray(system):
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 1631ab319b..f13ee6cc07 100644
--- a/qualtran/bloqs/chemistry/trotter/hubbard/hopping.py
+++ b/qualtran/bloqs/chemistry/trotter/hubbard/hopping.py
@@ -14,7 +14,7 @@
"""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
@@ -122,7 +122,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/qpe_cost_optimization.ipynb b/qualtran/bloqs/chemistry/trotter/hubbard/qpe_cost_optimization.ipynb
index 2d266cbc48..f1cc6e7af3 100644
--- a/qualtran/bloqs/chemistry/trotter/hubbard/qpe_cost_optimization.ipynb
+++ b/qualtran/bloqs/chemistry/trotter/hubbard/qpe_cost_optimization.ipynb
@@ -106,8 +106,6 @@
"metadata": {},
"outputs": [],
"source": [
- "from typing import Tuple\n",
- "\n",
"import numpy as np\n",
"import sympy\n",
"import attrs\n",
@@ -116,7 +114,7 @@
"from qualtran.resource_counting import get_cost_value, QECGatesCost\n",
"\n",
"\n",
- "def t_and_rot_counts_from_bloq(bloq) -> Tuple[int, int]:\n",
+ "def t_and_rot_counts_from_bloq(bloq) -> tuple[int, int]:\n",
" costs = get_cost_value(bloq, QECGatesCost())\n",
" n_rot = costs.rotation\n",
" n_t = costs.total_t_count(ts_per_rotation=0)\n",
diff --git a/qualtran/bloqs/chemistry/trotter/hubbard/trotter_step.py b/qualtran/bloqs/chemistry/trotter/hubbard/trotter_step.py
index 24d8affd26..78fa885cb8 100644
--- a/qualtran/bloqs/chemistry/trotter/hubbard/trotter_step.py
+++ b/qualtran/bloqs/chemistry/trotter/hubbard/trotter_step.py
@@ -21,8 +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/chemistry/writing_algorithms.ipynb b/qualtran/bloqs/chemistry/writing_algorithms.ipynb
index 262f4e1c4e..b8e6820cc1 100644
--- a/qualtran/bloqs/chemistry/writing_algorithms.ipynb
+++ b/qualtran/bloqs/chemistry/writing_algorithms.ipynb
@@ -67,7 +67,6 @@
"outputs": [],
"source": [
"from functools import cached_property\n",
- "from typing import Tuple\n",
"from attrs import frozen\n",
"from qualtran import Register, BQUInt, QBit, QAny\n",
"\n",
@@ -80,7 +79,7 @@
" num_spin_orb: int\n",
"\n",
" @cached_property\n",
- " def selection_registers(self) -> Tuple[Register, ...]:\n",
+ " def selection_registers(self) -> tuple[Register, ...]:\n",
" bitsize = (self.num_spin_orb // 2 - 1).bit_length()\n",
" return (\n",
" Register('p', BQUInt(bitsize=bitsize, iteration_length=self.num_spin_orb//2)),\n",
@@ -115,7 +114,7 @@
"metadata": {},
"outputs": [],
"source": [
- "from typing import Set, Optional\n",
+ "from typing import Optional\n",
"from qualtran.bloqs.arithmetic.comparison import LessThanEqual\n",
"from qualtran.bloqs.basic_gates.swap import CSwap\n",
"from qualtran.resource_counting import SympySymbolAllocator, BloqCountT\n",
@@ -131,7 +130,7 @@
" qroam_block_size: Optional[int] = None\n",
"\n",
" @cached_property\n",
- " def selection_registers(self) -> Tuple[Register, ...]:\n",
+ " def selection_registers(self) -> tuple[Register, ...]:\n",
" bitsize = (self.num_spin_orb // 2 - 1).bit_length()\n",
" return (\n",
" Register('p', BQUInt(bitsize=bitsize, iteration_length=self.num_spin_orb // 2)),\n",
@@ -143,7 +142,7 @@
" Register('sign', BQUInt(1)),\n",
" )\n",
"\n",
- " def build_call_graph(self, ssa: 'SympySymbolAllocator') -> Set['BloqCountT']:\n",
+ " def build_call_graph(self, ssa: 'SympySymbolAllocator') -> set['BloqCountT']:\n",
" # 1. Prepare a uniform superposition over p, q, r and s\n",
" bitsize = (self.num_spin_orb // 2 - 1).bit_length()\n",
" # a factor of 4 here for p, q, r, and s\n",
@@ -289,7 +288,7 @@
" def t_complexity(self) -> TComplexity:\n",
" return TComplexity(t=4 * (3 * (self.bitsize**2 - self.bitsize) + 4 * (self.bitsize - 1))) \n",
"\n",
- " def build_call_graph(self, ssa: 'SympySymbolAllocator') -> Set['BloqCountT']:\n",
+ " def build_call_graph(self, ssa: 'SympySymbolAllocator') -> set['BloqCountT']:\n",
" # Exercise: Use existing bloqs in qualtran to give this call graph a little more spice.\n",
" cost = 3 * (self.bitsize**2 - self.bitsize) + 4 * (self.bitsize - 1)\n",
" return {(Toffoli(), cost)}"
@@ -309,7 +308,6 @@
"outputs": [],
"source": [
"from attrs import field\n",
- "from typing import Dict\n",
"from qualtran import SoquetT, BloqBuilder, Register\n",
"\n",
"from qualtran.bloqs.data_loading.select_swap_qrom import SelectSwapQROM, find_optimal_log_block_size\n",
@@ -320,13 +318,13 @@
"class PrepareSecondQuantizationDetailed(PrepareOracle):\n",
"\n",
" num_spin_orb: int\n",
- " alt_pqrs: Tuple[int, ...] = field(repr=False)\n",
- " keep: Tuple[int, ...] = field(repr=False)\n",
+ " alt_pqrs: tuple[int, ...] = field(repr=False)\n",
+ " keep: tuple[int, ...] = field(repr=False)\n",
" num_bits_state_prep: int = 16\n",
" qroam_block_size: Optional[int] = None\n",
"\n",
" @cached_property\n",
- " def selection_registers(self) -> Tuple[Register, ...]:\n",
+ " def selection_registers(self) -> tuple[Register, ...]:\n",
" ns = self.num_spin_orb // 2\n",
" bitsize = (ns - 1).bit_length()\n",
" data_size = (ns ** 2 + ns**4)\n",
@@ -345,7 +343,7 @@
" )\n",
"\n",
" @cached_property\n",
- " def junk_registers(self) -> Tuple[Register, ...]:\n",
+ " def junk_registers(self) -> tuple[Register, ...]:\n",
" alt_bitsize = (self.num_spin_orb // 2 - 1).bit_length()\n",
" return (\n",
" Register('alt_pqrs', QAny(alt_bitsize), shape=(4,)),\n",
@@ -367,7 +365,7 @@
" alt_pqrs: 'SoquetT',\n",
" keep: 'SoquetT',\n",
" less_than: 'SoquetT',\n",
- " ) -> Dict[str, 'SoquetT']:\n",
+ " ) -> dict[str, 'SoquetT']:\n",
" # 1. Prepare \\sum_d |d\\rangle\n",
" p = bb.add(PrepareUniformSuperposition(self.num_spin_orb // 2), target=p)\n",
" q = bb.add(PrepareUniformSuperposition(self.num_spin_orb // 2), target=q)\n",
diff --git a/qualtran/bloqs/cryptography/_factoring_shims.py b/qualtran/bloqs/cryptography/_factoring_shims.py
index 29f46f6381..ac284b1990 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, MeasureZ(): 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 2caf4f0021..532098d9e6 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`.")
@@ -251,7 +251,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
@@ -276,7 +276,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`.")
@@ -431,7 +431,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
@@ -446,7 +446,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`.")
@@ -559,7 +559,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
@@ -569,7 +569,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`.")
@@ -719,7 +719,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
@@ -737,7 +737,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`.")
@@ -895,7 +895,7 @@ def on_classical_vals(
b: 'ClassicalValT',
x: 'ClassicalValT',
y: 'ClassicalValT',
- ) -> Dict[str, 'ClassicalValT']:
+ ) -> dict[str, 'ClassicalValT']:
if f4 == 1:
x = a
y = b
@@ -916,7 +916,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`.")
@@ -1090,7 +1090,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
)
@@ -1141,7 +1141,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 4ca244d6ed..45b18613ee 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 f3783f3cc8..8847f0164d 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 529f30a4b3..2bac939a2f 100644
--- a/qualtran/bloqs/data_loading/qrom.py
+++ b/qualtran/bloqs/data_loading/qrom.py
@@ -15,7 +15,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
@@ -86,8 +87,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(
@@ -100,11 +101,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(
@@ -117,15 +118,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)
@@ -163,7 +164,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
@@ -198,7 +199,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
@@ -218,20 +219,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 e3c8c8ed84..81f5a1bbcb 100644
--- a/qualtran/bloqs/data_loading/qrom_base.py
+++ b/qualtran/bloqs/data_loading/qrom_base.py
@@ -17,7 +17,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
@@ -31,7 +31,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)
@@ -151,17 +151,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
@@ -180,8 +180,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:
@@ -196,11 +196,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])
@@ -221,8 +221,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]
@@ -251,14 +251,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
@@ -280,11 +280,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)
@@ -299,7 +299,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))
@@ -308,10 +308,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:
@@ -322,7 +322,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 0bfc92876f..3d05458a65 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)] # type: ignore[index]
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 39fb6b2b13..b828d59b0a 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 049d1bf56d..2783202c48 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
@@ -53,7 +52,7 @@ def signature(self) -> Signature:
def build_composite_bloq(
self, bb: 'BloqBuilder', xx: 'SoquetT', yy: 'SoquetT', 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):
@@ -105,7 +104,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/qubit_count_many_alloc.py b/qualtran/bloqs/for_testing/qubit_count_many_alloc.py
index 5289e849fc..18a783d218 100644
--- a/qualtran/bloqs/for_testing/qubit_count_many_alloc.py
+++ b/qualtran/bloqs/for_testing/qubit_count_many_alloc.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
from qualtran import Bloq, BloqBuilder, Signature, Soquet, SoquetT
@@ -75,7 +73,7 @@ class _Inner(Bloq):
def signature(self) -> Signature:
return Signature.build(x=1)
- def build_composite_bloq(self, bb: 'BloqBuilder', *, x: 'Soquet') -> Dict[str, 'SoquetT']:
+ def build_composite_bloq(self, bb: 'BloqBuilder', *, x: 'Soquet') -> dict[str, 'SoquetT']:
anc = bb.allocate()
x, anc = bb.add(CNOT(), ctrl=x, target=anc)
anc = bb.add(TGate(), q=anc)
diff --git a/qualtran/bloqs/for_testing/qubitization_walk_test.py b/qualtran/bloqs/for_testing/qubitization_walk_test.py
index f6058eaafc..1593e7230f 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 7d2d105115..df32da2ca4 100644
--- a/qualtran/bloqs/for_testing/with_decomposition.py
+++ b/qualtran/bloqs/for_testing/with_decomposition.py
@@ -13,7 +13,6 @@
# limitations under the License.
from functools import cached_property
-from typing import Dict
from attrs import frozen
@@ -29,7 +28,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}
@@ -43,7 +42,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 BloqBuilder.is_single(reg)
reg = bb.split(reg)
for i in range(len(reg)):
@@ -60,7 +59,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 c63b50340b..ddb9d2e7a5 100644
--- a/qualtran/bloqs/gf_arithmetic/gf2_addition.py
+++ b/qualtran/bloqs/gf_arithmetic/gf2_addition.py
@@ -13,7 +13,7 @@
# limitations under the License.
import warnings
from functools import cached_property
-from typing import Dict, Set, TYPE_CHECKING, Union
+from typing import TYPE_CHECKING, Union
import attrs
@@ -74,7 +74,7 @@ def bitsize(self) -> SymbolicInt:
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)
@@ -86,10 +86,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 0cabf787ad..f6dfcd64f1 100644
--- a/qualtran/bloqs/gf_arithmetic/gf2_inverse.py
+++ b/qualtran/bloqs/gf_arithmetic/gf2_inverse.py
@@ -13,7 +13,7 @@
# limitations under the License.
import warnings
from functools import cached_property
-from typing import cast, Dict, Set, TYPE_CHECKING, Union
+from typing import cast, TYPE_CHECKING, Union
import attrs
import numpy as np
@@ -158,7 +158,7 @@ def _bits(self) -> list[int]:
def gf2_multiplier(self) -> Bloq:
return GF2MulViaKaratsuba(self.qgf)
- 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}")
@@ -200,7 +200,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.qgf): 1}
k1 = bit_length(self.bitsize - 1) - 1
@@ -230,7 +230,7 @@ def build_call_graph(
bloq_counts[GF2Addition(self.qgf)] = add_count
return bloq_counts
- 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)
t = (self.bitsize - 1).bit_count()
k1 = bit_length(self.bitsize - 1) - 1
diff --git a/qualtran/bloqs/gf_arithmetic/gf2_multiplication.py b/qualtran/bloqs/gf_arithmetic/gf2_multiplication.py
index ac45329078..e6122eece7 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 Mapping, Sequence
from functools import cached_property
-from typing import Dict, Mapping, Optional, Sequence, Set, TYPE_CHECKING, Union
+from typing import Optional, TYPE_CHECKING, Union
import attrs
import galois
@@ -90,7 +91,7 @@ def lup(self) -> tuple[np.ndarray, np.ndarray, np.ndarray]:
P, L, U = GF(2)(self.matrix).plu_decompose()
return np.asarray(L, dtype=int), np.asarray(U, dtype=int), np.asarray(P, dtype=int)
- def build_composite_bloq(self, bb: 'BloqBuilder', *, q: 'SoquetT') -> Dict[str, 'SoquetT']:
+ def build_composite_bloq(self, bb: 'BloqBuilder', *, q: 'SoquetT') -> dict[str, 'SoquetT']:
assert isinstance(q, np.ndarray) # make mypy happy
L, U, P = self.lup
if is_symbolic(self.n):
@@ -114,7 +115,7 @@ def build_composite_bloq(self, bb: 'BloqBuilder', *, q: 'SoquetT') -> Dict[str,
column[i], column[j] = column[j], column[i]
return {'q': q}
- 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))
@@ -129,7 +130,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]
if isinstance(self.matrix, Shaped):
return {CNOT(): n**2 - n}
@@ -208,7 +209,7 @@ def signature(self) -> 'Signature':
def bitsize(self) -> SymbolicInt:
return self.qgf.bitsize
- 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']
@@ -250,12 +251,12 @@ 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 = {GF2ShiftRight(self.qgf, m).adjoint(): 1} if self.plus_equal_prod else {}
return {Toffoli(): m**2, GF2ShiftRight(self.qgf, m): 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)
@@ -346,7 +347,7 @@ def reduction_matrix_q(self) -> np.ndarray:
alpha += [0]
return np.transpose(M)
- 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, result = soqs['x'], soqs['y'], soqs['result']
@@ -378,7 +379,7 @@ 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
return {CZ(): m**2}
@@ -454,10 +455,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']:
g_arr = bb.split(g)
g_arr = g_arr[::-1]
g_arr = bb.add(SynthesizeLRCircuit(self.reduction_matrix_q), q=g_arr)
@@ -467,7 +468,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']]:
return {SynthesizeLRCircuit(self.reduction_matrix_q): 1}
@@ -549,7 +550,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)
@@ -567,7 +568,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
@@ -602,7 +603,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}
@@ -660,7 +661,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)
@@ -681,7 +682,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}")
@@ -731,7 +732,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:
@@ -802,7 +803,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}')
@@ -811,7 +812,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]
@@ -826,7 +827,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 is_symbolic(self.n):
w = 5 # Assume a pentanomial is used.
return {CNOT(): (w - 2) * self.k}
@@ -895,7 +896,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}')
@@ -904,7 +905,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]
@@ -919,7 +920,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 is_symbolic(self.n):
w = 5 # Assume a pentanomial is used.
return {CNOT(): (w - 2) * self.k}
@@ -974,7 +975,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}")
@@ -1108,7 +1109,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}")
@@ -1120,7 +1121,7 @@ def build_composite_bloq(
def build_call_graph(
self, ssa: 'SympySymbolAllocator'
- ) -> Union['BloqCountDictT', Set['BloqCountT']]:
+ ) -> Union['BloqCountDictT', set['BloqCountT']]:
if is_symbolic(self.n):
return {Toffoli(): self.n ** (log2(3)), CNOT(): self.n**2}
@@ -1145,7 +1146,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)
return {'x': x, 'y': y, 'result': x * y}
diff --git a/qualtran/bloqs/gf_arithmetic/gf2_square.py b/qualtran/bloqs/gf_arithmetic/gf2_square.py
index 5dae828b6d..b1e6253466 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
@@ -104,7 +104,7 @@ def synthesize_squaring_matrix(self) -> SynthesizeLRCircuit:
ret = ret.adjoint()
return ret
- 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]
@@ -114,13 +114,13 @@ 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 adjoint(self):
return attrs.evolve(self, uncompute=not self.uncompute)
- 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)
if self.uncompute:
for _ in range(self.k):
diff --git a/qualtran/bloqs/gf_arithmetic/gf_utils.py b/qualtran/bloqs/gf_arithmetic/gf_utils.py
index 3ecc74fb26..722b6bcb7f 100644
--- a/qualtran/bloqs/gf_arithmetic/gf_utils.py
+++ b/qualtran/bloqs/gf_arithmetic/gf_utils.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
from galois import Poly
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 20566d1f17..2c36657a46 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 24caae0362..2f4d920f08 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
@@ -144,11 +144,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}
@@ -162,8 +162,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 7c043dd92b..78b7ab9696 100644
--- a/qualtran/bloqs/mcmt/and_bloq.py
+++ b/qualtran/bloqs/mcmt/and_bloq.py
@@ -23,8 +23,9 @@
"""
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
@@ -110,7 +111,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}
@@ -123,8 +124,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.
@@ -154,7 +155,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':
@@ -256,7 +257,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
@@ -281,7 +282,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):
@@ -293,7 +294,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
@@ -308,7 +309,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)
)
@@ -325,7 +326,7 @@ def __pow__(self, power: int) -> "Bloq":
def _decompose_via_tree(
self,
controls: NDArray[cirq.Qid], # type: ignore[type-var]
- control_values: Tuple[SymbolicInt, ...],
+ control_values: tuple[SymbolicInt, ...],
ancillas: NDArray[cirq.Qid], # type: ignore[type-var]
target: cirq.Qid,
) -> Iterator[cirq.OP_TREE]:
@@ -354,7 +355,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 56603141bf..1b0362e378 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
@@ -194,7 +193,7 @@ def signature(self) -> 'Signature':
def build_composite_bloq(
self, bb: 'BloqBuilder', q0: 'SoquetT', q1: 'SoquetT'
- ) -> Dict[str, 'SoquetT']:
+ ) -> dict[str, 'SoquetT']:
assert BloqBuilder.is_single(q0)
assert BloqBuilder.is_single(q1)
qs, trg = bb.add(And(), ctrl=[q0, q1])
diff --git a/qualtran/bloqs/mcmt/classically_controlled.py b/qualtran/bloqs/mcmt/classically_controlled.py
index a4236872f6..d63c051711 100644
--- a/qualtran/bloqs/mcmt/classically_controlled.py
+++ b/qualtran/bloqs/mcmt/classically_controlled.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 attrs
from qualtran import AddControlledT, Bloq, CDType, CtrlSpec, QCDType
@@ -41,6 +39,6 @@ def __attrs_post_init__(self):
@classmethod
def make_ctrl_system(
cls, bloq: 'Bloq', ctrl_spec: 'CtrlSpec'
- ) -> Tuple['_ControlledBase', 'AddControlledT']:
+ ) -> tuple['_ControlledBase', 'AddControlledT']:
cb = cls(subbloq=bloq, ctrl_spec=ctrl_spec)
return cls._make_ctrl_system(cb)
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 839a9355ef..63ef53c837 100644
--- a/qualtran/bloqs/mcmt/multi_control_pauli.py
+++ b/qualtran/bloqs/mcmt/multi_control_pauli.py
@@ -14,7 +14,7 @@
import abc
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
@@ -51,7 +51,7 @@ class MultiControlPauliBase(GateWithRegisters, metaclass=abc.ABCMeta):
@property
@abc.abstractmethod
- def cvs(self) -> Union[HasLength, Tuple[int, ...]]: ...
+ def cvs(self) -> Union[HasLength, tuple[int, ...]]: ...
@property
@abc.abstractmethod
@@ -70,7 +70,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
@@ -83,7 +83,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=}")
@@ -111,7 +111,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':
@@ -164,7 +164,7 @@ class MultiControlPauli(MultiControlPauliBase):
[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):
@@ -194,7 +194,7 @@ class MultiControlX(MultiControlPauliBase):
target: single qubit target register.
"""
- cvs: Union[HasLength, Tuple[int, ...]] = field(converter=_to_tuple_or_has_length)
+ cvs: Union[HasLength, tuple[int, ...]] = field(converter=_to_tuple_or_has_length)
@cached_property
def target_bloq(self) -> 'Bloq':
@@ -241,7 +241,7 @@ class MultiControlZ(MultiControlPauliBase):
target: single qubit target register.
"""
- cvs: Union[HasLength, Tuple[int, ...]] = field(converter=_to_tuple_or_has_length)
+ cvs: Union[HasLength, tuple[int, ...]] = field(converter=_to_tuple_or_has_length)
@cached_property
def target_bloq(self) -> 'Bloq':
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 f78f8345a8..58ee4453e5 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..c3124ae339 100644
--- a/qualtran/bloqs/mcmt/specialized_ctrl_test.py
+++ b/qualtran/bloqs/mcmt/specialized_ctrl_test.py
@@ -12,7 +12,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import itertools
-from typing import Optional, Sequence, Tuple
+from collections.abc import Sequence
+from typing import Optional
from unittest.mock import ANY
import attrs
@@ -52,7 +53,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 +131,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 +152,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 605878b0eb..c59063d6b2 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 411d66131f..5718ab667b 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':
@@ -499,7 +500,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)
@@ -655,7 +656,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:
@@ -702,7 +703,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
@@ -736,7 +737,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 438ae361b6..af24015635 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 81ccdd543c..76bd58a088 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 7420f19cc9..ccc5c5a275 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 Dict, Iterator, Sequence, Tuple, Union
+from typing import Union
import attrs
import cirq
@@ -48,10 +49,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()),),
)
@@ -73,15 +74,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
@@ -94,7 +95,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(
@@ -138,7 +139,7 @@ def nth_operation( # type: ignore[override]
yield self.target_gate(target[target_idx]).controlled_by(control)
yield cirq.CZ(*accumulator, target[target_idx])
- def on_classical_vals(self, **vals) -> Dict[str, 'ClassicalValT']:
+ def on_classical_vals(self, **vals) -> dict[str, 'ClassicalValT']:
if self.target_gate != cirq.X and self.target_gate != cirq.Z:
return NotImplemented
if len(self.control_registers) != 1 or len(self.selection_registers) != 1:
diff --git a/qualtran/bloqs/multiplexers/unary_iteration.ipynb b/qualtran/bloqs/multiplexers/unary_iteration.ipynb
index b0a18619c0..dafd04c7d0 100644
--- a/qualtran/bloqs/multiplexers/unary_iteration.ipynb
+++ b/qualtran/bloqs/multiplexers/unary_iteration.ipynb
@@ -483,15 +483,15 @@
" self._control_bitsize = control_bitsize\n",
"\n",
" @cached_property\n",
- " def control_registers(self) -> Tuple[Register, ...]:\n",
+ " def control_registers(self) -> tuple[Register, ...]:\n",
" return (Register('control', QAny(self._control_bitsize)),)\n",
"\n",
" @cached_property\n",
- " def selection_registers(self) -> Tuple[Register, ...]:\n",
+ " def selection_registers(self) -> tuple[Register, ...]:\n",
" return (Register('selection', BQUInt(self._selection_bitsize, self._target_bitsize)),)\n",
"\n",
" @cached_property\n",
- " def target_registers(self) -> Tuple[Register, ...]:\n",
+ " def target_registers(self) -> tuple[Register, ...]:\n",
" return (Register('target', QAny(self._target_bitsize)),)\n",
"\n",
" def nth_operation(\n",
diff --git a/qualtran/bloqs/multiplexers/unary_iteration_bloq.py b/qualtran/bloqs/multiplexers/unary_iteration_bloq.py
index d1f689a99e..0b68f9d5ce 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 70f08821a6..11590cceef 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/optimization/k_xor_sat/load_kxor_instance.py b/qualtran/bloqs/optimization/k_xor_sat/load_kxor_instance.py
index 0cec9b2d67..6b910d260c 100644
--- a/qualtran/bloqs/optimization/k_xor_sat/load_kxor_instance.py
+++ b/qualtran/bloqs/optimization/k_xor_sat/load_kxor_instance.py
@@ -32,8 +32,9 @@
Theorem 4.17, proof para 2 for $U_j$.
"""
+from collections.abc import Sequence
from functools import cached_property
-from typing import Counter, Sequence, Union
+from typing import Counter, Union
import attrs
import numpy as np
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 c00ad0bb8a..06989df686 100644
--- a/qualtran/bloqs/phase_estimation/lp_resource_state.py
+++ b/qualtran/bloqs/phase_estimation/lp_resource_state.py
@@ -16,7 +16,7 @@
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
@@ -57,14 +57,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)
@@ -141,7 +141,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 f3b8b3bf82..56ac56c1c7 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 5303a7c36b..198e992707 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 83c5295d00..fa54a152b6 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 567411150b..657d9c7f49 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 117515efb1..f235e8269e 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
@@ -94,7 +94,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)
)
@@ -108,11 +108,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 bad2b4c5b0..43c7ee6d33 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
@@ -95,7 +95,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 d410c80c11..644808dfc4 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
@@ -264,7 +265,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')
@@ -305,7 +306,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)
@@ -315,7 +316,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']
@@ -341,8 +342,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)
@@ -510,13 +511,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 959d1c2e1b..cfe1a6c253 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)
@@ -163,7 +161,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 7c6b33d091..c662af7c9f 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
@@ -214,7 +214,7 @@ def interleaved_unitary(
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 298c89138c..b22f4bfc71 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 c516594c86..20ca6074dd 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
@@ -50,11 +49,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
@@ -73,7 +72,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 is_zero(self.selection_bitsize):
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 e567c913bf..17632cb9d0 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 63311ef3b5..342be63f0a 100644
--- a/qualtran/bloqs/state_preparation/state_preparation_alias_sampling.py
+++ b/qualtran/bloqs/state_preparation/state_preparation_alias_sampling.py
@@ -20,8 +20,9 @@
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
@@ -52,7 +53,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)
@@ -114,7 +115,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)
@@ -224,7 +225,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,
@@ -356,7 +357,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)
@@ -370,7 +371,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 e56c4cdefb..95acfe06c6 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(
@@ -203,7 +201,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]
)
@@ -233,7 +231,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,
@@ -259,7 +257,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,
@@ -288,7 +286,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,
diff --git a/qualtran/bloqs/swap_network/cswap_approx.py b/qualtran/bloqs/swap_network/cswap_approx.py
index e09e3a0ea2..78e5401099 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
@@ -91,14 +92,14 @@ def g(q: cirq.Qid, adjoint=False) -> Iterator[cirq.OP_TREE]:
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 e8f04d0282..461610cda4 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,11 +159,11 @@ 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)
@@ -171,7 +172,7 @@ def build_composite_bloq(
bb: 'BloqBuilder',
targets: NDArray['Soquet'], # type: ignore[type-var]
**sel: 'Soquet',
- ) -> 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
@@ -192,7 +193,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
@@ -205,7 +206,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 949abc48b9..0d530b3a3f 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
@@ -97,9 +98,9 @@ def bloq(self) -> Bloq:
def bloq_on(
cls,
bloq: Bloq,
- cirq_quregs: Dict[str, 'CirqQuregT'],
+ cirq_quregs: dict[str, 'CirqQuregT'],
qubit_manager: cirq.QubitManager, # type: ignore[type-var]
- ) -> Tuple['cirq.Operation', Dict[str, 'CirqQuregT']]: # 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
@@ -186,7 +187,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]
@@ -197,11 +198,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()
}
@@ -229,10 +230,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:
@@ -245,16 +246,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]).item(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 6b2ab24b21..f023cb7e60 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 attrs
import cirq
@@ -40,14 +40,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)
@@ -74,7 +74,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):
@@ -91,8 +91,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 d0cdabafa8..e3e6795b5c 100644
--- a/qualtran/cirq_interop/_cirq_to_bloq.py
+++ b/qualtran/cirq_interop/_cirq_to_bloq.py
@@ -17,19 +17,9 @@
import abc
import itertools
import warnings
+from collections.abc import Callable, Sequence
from functools import cached_property
-from typing import (
- Any,
- Callable,
- Dict,
- List,
- Optional,
- Sequence,
- Tuple,
- TYPE_CHECKING,
- TypeVar,
- Union,
-)
+from typing import Any, Optional, TYPE_CHECKING, TypeVar, Union
import cirq
import numpy as np
@@ -136,15 +126,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
@@ -210,7 +200,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
@@ -242,9 +232,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
@@ -269,7 +259,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
@@ -289,12 +279,12 @@ def __hash__(self):
return hash(self.qubits)
-def _ensure_in_reg_exists(bb: BloqBuilder, in_reg: _QReg, qreg_to_qvar: Dict[_QReg, QVar]) -> None:
+def _ensure_in_reg_exists(bb: BloqBuilder, in_reg: _QReg, qreg_to_qvar: dict[_QReg, QVar]) -> 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))] = (
@@ -308,7 +298,7 @@ def _ensure_in_reg_exists(bb: BloqBuilder, in_reg: _QReg, qreg_to_qvar: Dict[_QR
# 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, QVar] = {}
+ new_qreg_to_qvar: dict[_QReg, QVar] = {}
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 |= {
@@ -319,7 +309,7 @@ def _ensure_in_reg_exists(bb: BloqBuilder, in_reg: _QReg, qreg_to_qvar: Dict[_QR
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, QVar] = {}
+ soqs_to_join: dict[cirq.Qid, QVar] = {}
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."
@@ -347,11 +337,11 @@ def _ensure_in_reg_exists(bb: BloqBuilder, in_reg: _QReg, qreg_to_qvar: Dict[_QR
def _gather_input_soqs(
- bb: BloqBuilder, op_quregs: Dict[str, NDArray[_QReg]], qreg_to_qvar: Dict[_QReg, QVar] # 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, QVar] # 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[QVar] = []
+ flat_soqs: list[QVar] = []
for qureg in quregs.flatten():
_ensure_in_reg_exists(bb, qureg, qreg_to_qvar)
flat_soqs.append(qreg_to_qvar[qureg])
@@ -474,8 +464,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,
op_conversion_method: Optional[Callable[[cirq.Operation], Bloq]] = None,
) -> CompositeBloq:
"""Convert a Cirq OP-TREE into a `CompositeBloq` with signature `signature`.
@@ -529,11 +519,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()
}
@@ -541,7 +531,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, QVar] = {}
+ qreg_to_qvar: dict[_QReg, QVar] = {}
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.")
@@ -566,12 +556,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]] = { # type: ignore[type-var]
+ all_op_quregs: dict[str, NDArray[_QReg]] = { # type: ignore[type-var]
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]] = { # type: ignore[type-var]
+ in_op_quregs: dict[str, NDArray[_QReg]] = { # type: ignore[type-var]
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 da3d92f760..713dd5599a 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 BloqBuilder.is_single(ctrl)
assert BloqBuilder.is_single(target)
@@ -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
@@ -192,7 +192,7 @@ def signature(self) -> Signature:
qualtran.Register('yy', QBit(), shape=(2, 3)),
]
)
- cirq_quregs: Dict[str, NDArray] = {
+ cirq_quregs: dict[str, NDArray] = {
'xx': np.asarray(qubits[:18]).reshape((3, 2, 3)),
'yy': np.asarray(qubits[18:]).reshape((2, 3, 1)),
}
@@ -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 dfe50198ad..99f09abce9 100644
--- a/qualtran/cirq_interop/_interop_qubit_manager.py
+++ b/qualtran/cirq_interop/_interop_qubit_manager.py
@@ -14,7 +14,8 @@
"""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
@@ -26,11 +27,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:
@@ -41,9 +42,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/cirq_interop.ipynb b/qualtran/cirq_interop/cirq_interop.ipynb
index bc9c7e175f..acdef990c8 100644
--- a/qualtran/cirq_interop/cirq_interop.ipynb
+++ b/qualtran/cirq_interop/cirq_interop.ipynb
@@ -212,7 +212,7 @@
" \n",
" def as_cirq_op(\n",
" self, qubit_manager, x: CirqQuregT, y: CirqQuregT\n",
- " ) -> Tuple[cirq.Operation, Dict[str, CirqQuregT]]:\n",
+ " ) -> tuple[cirq.Operation, dict[str, CirqQuregT]]:\n",
" x, = x # each is an array of length one\n",
" y, = y\n",
" op = cirq.SWAP(x, y)\n",
@@ -310,7 +310,7 @@
"\n",
" def build_composite_bloq(\n",
" self, bb: 'BloqBuilder', *, x: 'SoquetT', y: 'SoquetT'\n",
- " ) -> Dict[str, 'SoquetT']:\n",
+ " ) -> dict[str, 'SoquetT']:\n",
" xs = bb.split(x)\n",
" ys = bb.split(y)\n",
" for i in range(self.n):\n",
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 c0c45548d0..d610b51a8b 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 93b1a6b6cd..fe703f6244 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
@@ -124,7 +125,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 82ecc90ddf..140efad6b8 100644
--- a/qualtran/drawing/bloq_counts_graph.py
+++ b/qualtran/drawing/bloq_counts_graph.py
@@ -17,7 +17,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
@@ -34,7 +35,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:
@@ -127,7 +128,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:
@@ -136,7 +137,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:
@@ -148,7 +149,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:
@@ -192,9 +193,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:
@@ -212,9 +213,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))
@@ -259,7 +260,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)
@@ -315,7 +316,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 de7ed9bc4a..ee484169ea 100644
--- a/qualtran/drawing/flame_graph.py
+++ b/qualtran/drawing/flame_graph.py
@@ -18,7 +18,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
@@ -72,7 +73,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 (
@@ -81,8 +82,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:
@@ -129,7 +130,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 7504e7d698..f2275c74c1 100644
--- a/qualtran/drawing/graphviz.py
+++ b/qualtran/drawing/graphviz.py
@@ -16,7 +16,8 @@
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
@@ -39,7 +40,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.
@@ -54,8 +55,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):
@@ -86,7 +87,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 5724aaa3b5..cb76edbeaa 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
@@ -104,7 +105,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
@@ -116,8 +117,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)."""
@@ -147,7 +148,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.
@@ -220,7 +221,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]]: # type: ignore[type-var]
"""Pluck out the correct values from `soq_assign` for `reg` on `binst`."""
if not reg.shape:
@@ -237,8 +238,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,
@@ -276,7 +277,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,
@@ -326,7 +327,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:
@@ -343,7 +344,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
@@ -394,7 +395,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)}
@@ -574,9 +575,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 0def8a7ba3..10b8a80f47 100644
--- a/qualtran/drawing/qpic_diagram.py
+++ b/qualtran/drawing/qpic_diagram.py
@@ -25,7 +25,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
from qualtran._infra.quantum_graph import _Soquet
@@ -101,16 +101,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
@@ -171,10 +171,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])
@@ -202,7 +202,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}']
@@ -243,7 +243,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):
@@ -272,7 +272,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/dtype/_any.py b/qualtran/dtype/_any.py
index 428e4122c5..6ab7ee5188 100644
--- a/qualtran/dtype/_any.py
+++ b/qualtran/dtype/_any.py
@@ -12,7 +12,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-from typing import Any, Iterable
+from collections.abc import Iterable
+from typing import Any
import attrs
from numpy.typing import NDArray
diff --git a/qualtran/dtype/_base.py b/qualtran/dtype/_base.py
index b889fced93..048921f570 100644
--- a/qualtran/dtype/_base.py
+++ b/qualtran/dtype/_base.py
@@ -14,7 +14,8 @@
import abc
import warnings
-from typing import cast, Generic, Iterable, List, Sequence, Tuple, TypeVar
+from collections.abc import Iterable, Sequence
+from typing import cast, Generic, TypeVar
import attrs
import numpy as np
@@ -36,7 +37,7 @@ def get_domain(self) -> Iterable[T]:
by this type."""
@abc.abstractmethod
- def to_bits(self, x: T) -> List[int]:
+ def to_bits(self, x: T) -> list[int]:
"""Yields individual bits corresponding to binary representation of x"""
def to_bits_array(self, x_array: NDArray) -> NDArray[np.uint8]:
@@ -114,7 +115,7 @@ def bitsize(self) -> SymbolicInt:
def get_domain(self) -> Iterable[T]:
yield from self.qdtype.get_classical_domain()
- def to_bits(self, x: T) -> List[int]:
+ def to_bits(self, x: T) -> list[int]:
return self.qdtype.to_bits(x)
def to_bits_array(self, x_array: NDArray) -> NDArray[np.uint8]:
@@ -139,7 +140,7 @@ def assert_valid_val_array(self, val_array: NDArray, debug_str: str = 'val') ->
@attrs.frozen
class ShapedQCDType:
qcdtype: 'QCDType'
- shape: Tuple[int, ...] = attrs.field(
+ shape: tuple[int, ...] = attrs.field(
default=tuple(), converter=lambda v: (v,) if isinstance(v, int) else tuple(v)
)
@@ -173,7 +174,7 @@ def get_classical_domain(self) -> Iterable[T]:
by this type."""
yield from self._bit_encoding.get_domain()
- def to_bits(self, x: T) -> List[int]:
+ def to_bits(self, x: T) -> list[int]:
"""Yields individual bits corresponding to binary representation of x"""
return self._bit_encoding.to_bits(x)
diff --git a/qualtran/dtype/_base_test.py b/qualtran/dtype/_base_test.py
index f8a8ceef16..39fc30c90f 100644
--- a/qualtran/dtype/_base_test.py
+++ b/qualtran/dtype/_base_test.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, Iterable, List, Sequence
+from collections.abc import Iterable, Sequence
+from typing import Any
import attrs
import galois
@@ -120,7 +121,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)
diff --git a/qualtran/dtype/_bit.py b/qualtran/dtype/_bit.py
index 8baa9e1c67..cd481d48c8 100644
--- a/qualtran/dtype/_bit.py
+++ b/qualtran/dtype/_bit.py
@@ -12,8 +12,8 @@
# 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, List, Sequence
import attrs
import numpy as np
@@ -40,7 +40,7 @@ def assert_valid_val(self, val: int, debug_str: str = 'val'):
if not (val == 0 or val == 1):
raise ValueError(f"Bad bit value: {val} 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_val(x)
return [int(x)]
diff --git a/qualtran/dtype/_buint.py b/qualtran/dtype/_buint.py
index ef1d9cc00b..75c0538914 100644
--- a/qualtran/dtype/_buint.py
+++ b/qualtran/dtype/_buint.py
@@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-from typing import Iterable, List, Sequence
+from collections.abc import Iterable, Sequence
import attrs
import numpy as np
@@ -59,7 +59,7 @@ def assert_valid_val(self, val: int, debug_str: str = 'val') -> None:
if val >= self.bound:
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_val(x)
return _UInt(self.bitsize).to_bits(x)
@@ -83,7 +83,7 @@ class BQUInt(QDType[int]):
LCU methods often make use of coherent for-loops via UnaryIteration, iterating over a range
of values stored as a superposition over the `SELECT` register. Such (nested) coherent
- for-loops can be represented using a `Tuple[Register(dtype=BQUInt), ...]` where the
+ for-loops can be represented using a `tuple[Register(dtype=BQUInt), ...]` where the
i'th entry stores the bitsize and iteration length of i'th
nested for-loop.
diff --git a/qualtran/dtype/_fxp.py b/qualtran/dtype/_fxp.py
index ce165a64c4..9b83121752 100644
--- a/qualtran/dtype/_fxp.py
+++ b/qualtran/dtype/_fxp.py
@@ -12,7 +12,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-from typing import Iterable, List, Sequence, TYPE_CHECKING, Union
+from collections.abc import Iterable, Sequence
+from typing import TYPE_CHECKING, Union
import attrs
@@ -74,7 +75,7 @@ def get_domain(self) -> Iterable[int]:
# Use the classical domain for the underlying raw integer encoding.
yield from self._int_encoding.get_domain()
- def to_bits(self, x: int) -> List[int]:
+ def to_bits(self, x: int) -> list[int]:
# Use the underlying raw integer encoding.
return self._int_encoding.to_bits(x)
@@ -170,7 +171,7 @@ def _get_domain_fxp(self) -> Iterable['fxpmath.Fxp']:
def _fxp_to_bits(
self, x: Union[float, 'fxpmath.Fxp'], require_exact: bool = True, complement: bool = True
- ) -> List[int]:
+ ) -> list[int]:
"""Yields individual bits corresponding to binary representation of `x`.
Args:
diff --git a/qualtran/dtype/_int.py b/qualtran/dtype/_int.py
index c4b4750f2f..416a018e34 100644
--- a/qualtran/dtype/_int.py
+++ b/qualtran/dtype/_int.py
@@ -12,8 +12,8 @@
# 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, List, Sequence
import attrs
import numpy as np
@@ -42,7 +42,7 @@ def get_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]:
if is_symbolic(self.bitsize):
raise ValueError(f"cannot compute bits with symbolic {self.bitsize=}")
diff --git a/qualtran/dtype/_int_ones_complement.py b/qualtran/dtype/_int_ones_complement.py
index cde4e42cbc..f8b9ad4963 100644
--- a/qualtran/dtype/_int_ones_complement.py
+++ b/qualtran/dtype/_int_ones_complement.py
@@ -12,8 +12,8 @@
# 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, List, Sequence
import attrs
import numpy as np
@@ -41,7 +41,7 @@ def __attrs_post_init__(self):
if self.bitsize == 1:
raise ValueError("bitsize must be > 1.")
- def to_bits(self, x: int) -> List[int]:
+ def to_bits(self, x: int) -> list[int]:
self.assert_valid_val(x)
return [int(x < 0)] + [y ^ int(x < 0) for y in _UInt(self.bitsize - 1).to_bits(abs(x))]
diff --git a/qualtran/dtype/_int_signmag.py b/qualtran/dtype/_int_signmag.py
index c28ad3b091..61b41e0902 100644
--- a/qualtran/dtype/_int_signmag.py
+++ b/qualtran/dtype/_int_signmag.py
@@ -12,8 +12,8 @@
# 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, List, Sequence
import attrs
import numpy as np
@@ -38,7 +38,7 @@ def get_domain(self) -> Iterable[int]:
max_val = 1 << (self.bitsize - 1)
return range(-max_val + 1, max_val)
- def to_bits(self, x: int) -> List[int]:
+ def to_bits(self, x: int) -> list[int]:
if is_symbolic(self.bitsize):
raise ValueError(f"cannot compute bits with symbolic {self.bitsize=}")
self.assert_valid_val(x)
diff --git a/qualtran/dtype/_montgomery_uint.py b/qualtran/dtype/_montgomery_uint.py
index df6612d1b8..768e09231e 100644
--- a/qualtran/dtype/_montgomery_uint.py
+++ b/qualtran/dtype/_montgomery_uint.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 Iterable, List, Optional, Sequence
+from typing import Optional
import attrs
import numpy as np
@@ -42,7 +43,7 @@ def get_domain(self) -> Iterable[int]:
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_val(x)
return [int(x) for x in f'{int(x):0{self.bitsize}b}']
diff --git a/qualtran/dtype/_uint.py b/qualtran/dtype/_uint.py
index 3f022536fe..93df0cc8c5 100644
--- a/qualtran/dtype/_uint.py
+++ b/qualtran/dtype/_uint.py
@@ -12,8 +12,8 @@
# 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, List, Sequence
import attrs
import numpy as np
@@ -37,7 +37,7 @@ class _UInt(BitEncoding[int]):
def get_domain(self) -> Iterable[int]:
return range(2**self.bitsize)
- def to_bits(self, x: int) -> List[int]:
+ def to_bits(self, x: int) -> list[int]:
self.assert_valid_val(x)
return [int(x) for x in f'{int(x):0{self.bitsize}b}']
diff --git a/qualtran/dtype/gf/_gf.py b/qualtran/dtype/gf/_gf.py
index ccb2e86f7b..165521e3b0 100644
--- a/qualtran/dtype/gf/_gf.py
+++ b/qualtran/dtype/gf/_gf.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 Any, Iterable, List, Optional, Sequence, TYPE_CHECKING, Union
+from typing import Any, Optional, TYPE_CHECKING, Union
import attrs
import numpy as np
@@ -89,7 +90,7 @@ def gf_type(self):
compile='python-calculate',
)
- def to_bits(self, x) -> List[int]:
+ def to_bits(self, x) -> list[int]:
self.assert_valid_val(x)
return self._uint_encoder.to_bits(int(x))
diff --git a/qualtran/dtype/gf/_gf_poly.py b/qualtran/dtype/gf/_gf_poly.py
index 8187fe84a5..c6cd1db509 100644
--- a/qualtran/dtype/gf/_gf_poly.py
+++ b/qualtran/dtype/gf/_gf_poly.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 Any, Iterable, List, Sequence, TYPE_CHECKING
+from typing import Any, TYPE_CHECKING
import attrs
import numpy as np
@@ -68,7 +69,7 @@ def from_gf_coefficients(self, f_x: 'galois.Array') -> 'galois.Poly':
return galois.Poly(f_x, field=self.gf.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"""
import galois
diff --git a/qualtran/dtype/testing.py b/qualtran/dtype/testing.py
index a5ab3e61e2..c4848cf2ea 100644
--- a/qualtran/dtype/testing.py
+++ b/qualtran/dtype/testing.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 enum import Enum
-from typing import Any, Sequence, Union
+from typing import Any, Union
import numpy as np
from numpy.typing import NDArray
diff --git a/qualtran/l1/_ast_visitor_base.py b/qualtran/l1/_ast_visitor_base.py
index a1d9d01352..942edb2b69 100644
--- a/qualtran/l1/_ast_visitor_base.py
+++ b/qualtran/l1/_ast_visitor_base.py
@@ -14,7 +14,7 @@
import abc
import functools
-from typing import Any, cast, Dict
+from typing import Any, cast
import attrs
@@ -36,7 +36,7 @@
class L1VisitorBase(metaclass=abc.ABCMeta):
@functools.singledispatchmethod
- def visit(self, node: L1ASTNode) -> Dict[str, Any]:
+ def visit(self, node: L1ASTNode) -> dict[str, Any]:
record = attrs.asdict(cast(Any, node), recurse=False)
record = {k: self.visit(v) if isinstance(v, L1ASTNode) else v for k, v in record.items()}
return record
@@ -48,7 +48,7 @@ def _(self, node: L1Module):
@visit.register
def _(self, node: QDefImplNode):
- record: Dict[str, Any] = {'bloq_key': node.bloq_key}
+ record: dict[str, Any] = {'bloq_key': node.bloq_key}
record['qsignature'] = [self.visit(sig_entry) for sig_entry in node.qsignature]
record['body'] = [self.visit(stmt) for stmt in node.body]
@@ -59,14 +59,14 @@ def _(self, node: QDefImplNode):
@visit.register
def _(self, node: QDefExternNode):
- record: Dict[str, Any] = {'bloq_key': node.bloq_key}
+ record: dict[str, Any] = {'bloq_key': node.bloq_key}
record['qsignature'] = [self.visit(sig_entry) for sig_entry in node.qsignature]
record['cobject_from'] = self.visit(node.cobject_from)
return record
@visit.register
def _(self, node: QSignatureEntry):
- record: Dict[str, Any] = {'name': node.name}
+ record: dict[str, Any] = {'name': node.name}
if isinstance(node.dtype, QDTypeNode):
record['dtype'] = self.visit(node.dtype)
else:
@@ -78,14 +78,14 @@ def _(self, node: QSignatureEntry):
@visit.register
def _(self, node: QDTypeNode):
- record: Dict[str, Any] = {'dtype': self.visit(node.dtype)}
+ record: dict[str, Any] = {'dtype': self.visit(node.dtype)}
if node.shape is not None:
record['shape'] = node.shape
return record
@visit.register
def _(self, node: QCallNode):
- record: Dict[str, Any] = {
+ record: dict[str, Any] = {
'bloq_key': node.bloq_key,
'lvalues': [lv for lv in node.lvalues],
'qargs': [self.visit(qa) for qa in node.qargs],
@@ -94,7 +94,7 @@ def _(self, node: QCallNode):
@visit.register
def _(self, node: QReturnNode):
- record: Dict[str, Any] = {'ret_mapping': [self.visit(qa) for qa in node.ret_mapping]}
+ record: dict[str, Any] = {'ret_mapping': [self.visit(qa) for qa in node.ret_mapping]}
return record
def visit_nested_qarg_value(self, v):
@@ -104,7 +104,7 @@ def visit_nested_qarg_value(self, v):
@visit.register
def _(self, node: QArgNode):
- record: Dict[str, Any] = {'key': node.key}
+ record: dict[str, Any] = {'key': node.key}
if isinstance(node.value, QArgValueNode):
record['value'] = self.visit(node.value)
else:
@@ -113,7 +113,7 @@ def _(self, node: QArgNode):
@visit.register
def _(self, node: CObjectNode):
- record: Dict[str, Any] = {
+ record: dict[str, Any] = {
'name': node.name,
'cargs': [self.visit(carg) for carg in node.cargs],
}
@@ -121,5 +121,5 @@ def _(self, node: CObjectNode):
@visit.register
def _(self, node: TupleNode):
- record: Dict[str, Any] = {'items': [self.visit(i) for i in node.items]}
+ record: dict[str, Any] = {'items': [self.visit(i) for i in node.items]}
return record
diff --git a/qualtran/l1/_dtypes.py b/qualtran/l1/_dtypes.py
index ae23fd6305..c960cc9e73 100644
--- a/qualtran/l1/_dtypes.py
+++ b/qualtran/l1/_dtypes.py
@@ -13,7 +13,7 @@
# limitations under the License.
from functools import lru_cache
-from typing import cast, Dict, Tuple, Type
+from typing import cast, Type
import qualtran as qlt
import qualtran.dtype as qdt
@@ -22,7 +22,7 @@
@lru_cache
-def get_builtin_qdtype_mapping() -> Dict[str, Type['qdt.QCDType']]:
+def get_builtin_qdtype_mapping() -> dict[str, Type['qdt.QCDType']]:
"""Datatypes that are available without namespacing and with `safe=True`."""
from qualtran.dtype import BQUInt, CBit, QAny, QBit, QFxp, QInt, QMontgomeryUInt, QUInt
@@ -33,7 +33,7 @@ def get_builtin_qdtype_mapping() -> Dict[str, Type['qdt.QCDType']]:
@lru_cache
-def get_builtin_qdtypes() -> Tuple[Type['qdt.QCDType'], ...]:
+def get_builtin_qdtypes() -> tuple[Type['qdt.QCDType'], ...]:
return tuple(get_builtin_qdtype_mapping().values())
diff --git a/qualtran/l1/_eval.py b/qualtran/l1/_eval.py
index 0f7516fd54..dce9244e45 100644
--- a/qualtran/l1/_eval.py
+++ b/qualtran/l1/_eval.py
@@ -13,21 +13,9 @@
# limitations under the License.
import importlib
import logging
+from collections.abc import Mapping, Sequence
from functools import lru_cache
-from typing import (
- Any,
- cast,
- Dict,
- List,
- Mapping,
- Optional,
- Protocol,
- Sequence,
- Tuple,
- TYPE_CHECKING,
- TypeAlias,
- Union,
-)
+from typing import Any, cast, Optional, Protocol, TYPE_CHECKING, TypeAlias, Union
import attrs
import numpy as np
@@ -77,14 +65,14 @@
@lru_cache
-def _get_custom_dtypes() -> Dict[str, type[QCDType]]:
+def _get_custom_dtypes() -> dict[str, type[QCDType]]:
# TODO: Custom data types.
- dtypes: Dict[str, type[QCDType]] = {f'{k._pkg_()}.{k.__name__}': k for k in []} # type: ignore
+ dtypes: dict[str, type[QCDType]] = {f'{k._pkg_()}.{k.__name__}': k for k in []} # type: ignore
return dtypes
@lru_cache
-def _get_safe_loadables() -> Dict[str, type[Any]]:
+def _get_safe_loadables() -> dict[str, type[Any]]:
from qualtran import CtrlSpec, Register
return {'CtrlSpec': CtrlSpec, 'Register': Register}
@@ -92,7 +80,7 @@ def _get_safe_loadables() -> Dict[str, type[Any]]:
def eval_carg_nodes(
cargs: Sequence[CArgNode], *, safe: bool = True
-) -> Tuple[List[Any], Dict[str, Any]]:
+) -> tuple[list[Any], dict[str, Any]]:
"""Evaluate a sequence of `CArgNode`
Returns:
@@ -101,8 +89,8 @@ def eval_carg_nodes(
"""
if len(cargs) > 1_000 and safe:
raise ValueError("Too many arguments for safe=True loading.")
- args: List[Any] = []
- kwargs: Dict[str, Any] = {}
+ args: list[Any] = []
+ kwargs: dict[str, Any] = {}
kwarg_only = False
for arg in cargs:
if arg.key is None:
@@ -172,7 +160,7 @@ def _eval_node(node: CObjectNode, *, safe: bool) -> object:
return _eval_node
-_CVALUE_EVALUATORS: Dict[str, _EvalProtocol] = {
+_CVALUE_EVALUATORS: dict[str, _EvalProtocol] = {
'True': _get_singleton_evaluator(True),
'False': _get_singleton_evaluator(False),
'None': _get_singleton_evaluator(None),
@@ -186,12 +174,12 @@ def _eval_node(node: CObjectNode, *, safe: bool) -> object:
@attrs.frozen
class UnevaluatedCValue:
name: str
- cargs: Sequence[Tuple[Optional[str], Any]] = attrs.field(
- converter=tuple[Tuple[Optional[str], Any]]
+ cargs: Sequence[tuple[Optional[str], Any]] = attrs.field(
+ converter=tuple[tuple[Optional[str], Any]]
)
-def _eval_imported(name: str, args: Sequence[Any], kwargs: Dict[str, Any]):
+def _eval_imported(name: str, args: Sequence[Any], kwargs: dict[str, Any]):
name_parts = name.split('.')
package = '.'.join(name_parts[:-1])
logger.debug("importing %s", package)
@@ -243,7 +231,7 @@ def eval_cvalue_node(node: CValueNode, *, safe: bool = True) -> Any:
raise TypeError(f"Unknown AST node type: {type(node)}")
-def eval_qdtype_node(dt: QDTypeNode) -> Tuple['qualtran.QCDType', Sequence[int]]:
+def eval_qdtype_node(dt: QDTypeNode) -> tuple['qualtran.QCDType', Sequence[int]]:
context = get_builtin_qdtype_mapping() | _get_custom_dtypes()
try:
dt_cls = context[dt.dtype.name]
@@ -307,9 +295,9 @@ def eval_qdef_extern_node(qdef: QDefExternNode, *, safe: bool = True) -> 'qualtr
def eval_bloq_maybe_aliased(
key: BloqKey,
- qdefs: Dict[BloqKey, QDefNode],
+ qdefs: dict[BloqKey, QDefNode],
qlocals: Mapping[BloqKey, Union[BloqKey, 'SoquetT']],
- bloqs: Dict[BloqKey, Bloq],
+ bloqs: dict[BloqKey, Bloq],
) -> 'qualtran.Bloq':
"""Recursively load bloqs.
@@ -369,7 +357,7 @@ def eval_qarg_nodes(qargs: Sequence[QArgNode], qlocals: Mapping[str, 'qualtran.S
def _eval_qdef_impl_node(
- qdef: QDefImplNode, qdefs: Dict[BloqKey, QDefNode], bloqs: Dict[BloqKey, Bloq], *, safe: bool
+ qdef: QDefImplNode, qdefs: dict[BloqKey, QDefNode], bloqs: dict[BloqKey, Bloq], *, safe: bool
) -> 'qualtran.CompositeBloq':
"""Evaluate a QDefImplNode, which defines a bloq implementation through a series of statements.
@@ -394,7 +382,7 @@ def _eval_qdef_impl_node(
signature: Signature = eval_qsignature(qdef.qsignature)
qlocals: Mapping[str, Union['SoquetT', BloqKey]]
bb, qlocals = BloqBuilder.from_signature(signature)
- subbloq_aliases: Dict[Bloq, str] = {}
+ subbloq_aliases: dict[Bloq, str] = {}
stmt: StatementNode
cbloq: Optional[CompositeBloq] = None # filled in on QReturnNode
@@ -453,8 +441,8 @@ def _eval_qdef_impl_node(
def eval_qdef_impl_node(
qdef: QDefImplNode,
- qdefs: Dict[BloqKey, QDefNode],
- bloqs: Dict[BloqKey, Bloq],
+ qdefs: dict[BloqKey, QDefNode],
+ bloqs: dict[BloqKey, Bloq],
*,
safe: bool = True,
) -> 'qualtran.CompositeBloq':
@@ -468,7 +456,7 @@ def eval_qdef_impl_node(
raise e
-def eval_module(m: L1Module, *, safe: bool = True) -> Dict[BloqKey, 'qualtran.Bloq']:
+def eval_module(m: L1Module, *, safe: bool = True) -> dict[BloqKey, 'qualtran.Bloq']:
"""Evaluate a parsed L1Module.
This will call `eval_qdef_impl_node` or `eval_qdef_extern_node` on each qdef in the
@@ -476,8 +464,8 @@ def eval_module(m: L1Module, *, safe: bool = True) -> Dict[BloqKey, 'qualtran.Bl
in a depth-first traversal.
"""
- qdefs: Dict[BloqKey, QDefNode] = {qdef.bloq_key: qdef for qdef in m.qdefs}
- bloqs: Dict[BloqKey, Bloq] = {}
+ qdefs: dict[BloqKey, QDefNode] = {qdef.bloq_key: qdef for qdef in m.qdefs}
+ bloqs: dict[BloqKey, Bloq] = {}
for qdef in m.qdefs:
bk = qdef.bloq_key
diff --git a/qualtran/l1/_parse.py b/qualtran/l1/_parse.py
index 6fa9012c6b..23638074c4 100644
--- a/qualtran/l1/_parse.py
+++ b/qualtran/l1/_parse.py
@@ -16,7 +16,6 @@
import json
import logging
import re
-from typing import List
import attrs
@@ -53,7 +52,7 @@ class Token:
column: int
-def tokenize(code: str) -> List[Token]:
+def tokenize(code: str) -> list[Token]:
"""Turn a string into a list of tokens."""
token_specification = [
('NUMBER', r'(\-)?\d+(\.\d*)?(e[+\-]\d+)?'),
@@ -106,7 +105,7 @@ def tokenize(code: str) -> List[Token]:
class QualtranL1Parser:
"""A recursive-descent parser for bloq strings."""
- def __init__(self, tokens: List[Token]):
+ def __init__(self, tokens: list[Token]):
self.tokens = tokens
self.pos = 0
@@ -181,7 +180,7 @@ def parse_module(self) -> L1Module:
self.consume('EOF', "Expected EOF")
return L1Module(qdefs=qdefs)
- def parse_qdefs(self) -> List[QDefNode]:
+ def parse_qdefs(self) -> list[QDefNode]:
"""Parse a sequence of quantum definitions.
Reads zero or more `qdef` or `extern qdef` keywords and parses them
@@ -243,7 +242,7 @@ def parse_qdef_from(self) -> CObjectNode:
bobj_cval = self.parse_cobject_node()
return bobj_cval
- def parse_qdef_signature(self) -> List[QSignatureEntry]:
+ def parse_qdef_signature(self) -> list[QSignatureEntry]:
self.consume('LBRACK', "quantum signature must start with [")
if self.check('RBRACK'):
@@ -251,7 +250,7 @@ def parse_qdef_signature(self) -> List[QSignatureEntry]:
self.advance()
return []
- qsig: List[QSignatureEntry] = []
+ qsig: list[QSignatureEntry] = []
while True:
qsig_entry = self.parse_qsig_entry()
qsig.append(qsig_entry)
@@ -305,14 +304,14 @@ def parse_qsig_dtype(self) -> QDTypeNode:
return QDTypeNode(dtype=cls, shape=shape)
return QDTypeNode(dtype=cls, shape=None)
- def parse_shape_list(self) -> List[int]:
+ def parse_shape_list(self) -> list[int]:
"""[1, 2, 3]"""
self.consume('LBRACK', "datatype shapes must begin with '['")
if self.check('RBRACK'):
self.advance()
return []
- items: List[int] = []
+ items: list[int] = []
while True:
item = self.parse_int_literal(err_ctx='datatype shape list')
items.append(item)
@@ -321,7 +320,7 @@ def parse_shape_list(self) -> List[int]:
if done:
return items
- def parse_qdef_body(self) -> List[StatementNode]:
+ def parse_qdef_body(self) -> list[StatementNode]:
"""Curly-brace delimited sequence of statements."""
self.consume('LCURLY', 'qdef body must start with {')
if self.check('RCURLY'):
@@ -363,7 +362,7 @@ def parse_return_statement(self) -> QReturnNode:
qargs = self.parse_qargs()
return QReturnNode(qargs)
- def parse_lvalues(self) -> List[str]:
+ def parse_lvalues(self) -> list[str]:
"""Parse a comma-separated list of l-values.
L-values are the targets of an assignment statement, typically
@@ -390,7 +389,7 @@ def parse_lvalues(self) -> List[str]:
if done:
return lvalues
- def parse_qargs(self) -> List[QArgNode]:
+ def parse_qargs(self) -> list[QArgNode]:
"""[ctrl=[qvar[0], qvar[1]], target=trg]"""
self.consume('LBRACK', 'qargs must start with [')
if self.check('RBRACK'):
@@ -421,12 +420,12 @@ def parse_qarg(self) -> QArgNode:
return QArgNode(key=key, value=val)
- def parse_qarg_value_list(self) -> List[NestedQArgValue]:
+ def parse_qarg_value_list(self) -> list[NestedQArgValue]:
"""[qvar[0], qvar[1]].
Lists can be arbitrarily nested.
"""
- qarg_value_list: List[NestedQArgValue] = []
+ qarg_value_list: list[NestedQArgValue] = []
self.consume('LBRACK', 'qarg value list must start with [')
while True:
if self.check('LBRACK'):
diff --git a/qualtran/l1/_parse_eval.py b/qualtran/l1/_parse_eval.py
index be94d067c5..734658d22d 100644
--- a/qualtran/l1/_parse_eval.py
+++ b/qualtran/l1/_parse_eval.py
@@ -12,7 +12,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import logging
-from typing import Dict
import qualtran as qlt
from qualtran.l1._eval import BloqKey, eval_module
@@ -29,7 +28,7 @@ def load_objectstring(objectstring: str, *, safe: bool = True) -> object:
return eval_cvalue_node(cobject_node, safe=safe)
-def load_module(l1_code: str, *, safe: bool = True) -> Dict[BloqKey, 'qlt.Bloq']:
+def load_module(l1_code: str, *, safe: bool = True) -> dict[BloqKey, 'qlt.Bloq']:
m = parse_module(l1_code)
return eval_module(m, safe=safe)
diff --git a/qualtran/l1/_to_cobject_node.py b/qualtran/l1/_to_cobject_node.py
index 95310c31b0..ae7a648bc3 100644
--- a/qualtran/l1/_to_cobject_node.py
+++ b/qualtran/l1/_to_cobject_node.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, List, Optional, Sequence
+from collections.abc import Sequence
+from typing import Any, Optional
import attrs
import numpy as np
@@ -71,8 +72,8 @@ def object_to_object_node(
kwonlys = tuple(a.kw_only for a in attrs.fields(o.__class__))
pos = True # State machine: whether positional arguments are permitted.
- args: List[CArgNode] = []
- kwargs: List[CArgNode] = []
+ args: list[CArgNode] = []
+ kwargs: list[CArgNode] = []
for fieldname, kwonly in zip(fieldnames, kwonlys):
v = getattr(o, fieldname)
v = to_cobject_node(v)
diff --git a/qualtran/l1/_to_l1.py b/qualtran/l1/_to_l1.py
index dfd156ca0a..5ab1d20294 100644
--- a/qualtran/l1/_to_l1.py
+++ b/qualtran/l1/_to_l1.py
@@ -15,19 +15,8 @@
import itertools
import logging
import uuid
-from typing import (
- Callable,
- cast,
- Container,
- Dict,
- List,
- Optional,
- Sequence,
- Set,
- Tuple,
- TypeAlias,
- Union,
-)
+from collections.abc import Callable, Container, Sequence
+from typing import cast, Optional, TypeAlias, Union
import attrs
import numpy as np
@@ -75,9 +64,9 @@ def bloq_key(self) -> BloqKey:
class Locals:
"""Handles assigning variable names for our variable *objects*, i.e. soquets and bloqs."""
- soqvars: Dict[_Soquet, QArgValueNode] = attrs.field(factory=dict)
- bloqvars: Dict[qlt.Bloq, BloqKey] = attrs.field(factory=dict)
- varnames: Set[str] = attrs.field(factory=set)
+ soqvars: dict[_Soquet, QArgValueNode] = attrs.field(factory=dict)
+ bloqvars: dict[qlt.Bloq, BloqKey] = attrs.field(factory=dict)
+ varnames: set[str] = attrs.field(factory=set)
def get_unique_name(self, prefix: str) -> str:
"""Get and register a unique name."""
@@ -111,11 +100,11 @@ def assign_bloq(self, bloq: qlt.Bloq, prefix: str) -> str:
class QDefBuilder:
bloq: qlt.Bloq
bloq_key: str
- qglobals: Dict[qlt.Bloq, str]
+ qglobals: dict[qlt.Bloq, str]
qlocals: Locals = attrs.field(factory=Locals)
- _sig_entries: List[QSignatureEntry] = attrs.field(factory=list)
- _stmnts: List[StatementNode] = attrs.field(factory=list)
+ _sig_entries: list[QSignatureEntry] = attrs.field(factory=list)
+ _stmnts: list[StatementNode] = attrs.field(factory=list)
def _get_sig_entry(self, reg_name: str, regs: Sequence['qlt.Register']) -> QSignatureEntry:
if len(regs) not in [1, 2]:
@@ -201,7 +190,7 @@ def add_bloqnection(
self.qlocals.soqvars[suc.left] = v
return
- kwargs: List[QArgNode] = []
+ kwargs: list[QArgNode] = []
# Case: this bloqnection represents an output from self.bloq to the outside world.
if binst is qlt.RightDangle:
@@ -252,7 +241,7 @@ def add_bloqnection(
get_me=lambda cxn: cxn.left,
get_assign=lambda cxn: cxn.left,
)
- rets: List[str] = []
+ rets: list[str] = []
for reg in binst.bloq.signature.rights():
regname = reg.name
soqs = retsoqs[regname]
@@ -295,8 +284,8 @@ def finalize(self, extern_only_from: bool):
)
# qlocals: Locals = attrs.field(factory=Locals)
- # calls: List[FormattedCall] = attrs.field(factory=list)
- # aliases: List[Alias] = attrs.field(factory=list)
+ # calls: list[FormattedCall] = attrs.field(factory=list)
+ # aliases: list[Alias] = attrs.field(factory=list)
# ret_qargs: str = ''
# implemented: bool = True
# extern_only_from: bool = False
@@ -304,11 +293,11 @@ def finalize(self, extern_only_from: bool):
def bloq_to_code(
bloq: qlt.Bloq,
- qglobals: Dict[qlt.Bloq, BloqKey],
+ qglobals: dict[qlt.Bloq, BloqKey],
*,
extern_only_from: bool,
force_extern: bool = False,
-) -> Tuple[QDefWithContext, List['qlt.Bloq']]:
+) -> tuple[QDefWithContext, list['qlt.Bloq']]:
"""Turn a bloq into Qualtran-L1 code.
Generally just calls the right methods on `SubroutineFormatter`.
@@ -364,11 +353,11 @@ def bloq_to_code(
class L1ModuleBuilder:
"""Format and export a Qualtran-L1 'module': a collection of 'qdef' bloq definitions."""
- qglobals: Dict[qlt.Bloq, BloqKey] = attrs.field(factory=dict)
- done: Set[qlt.Bloq] = attrs.field(factory=set)
- qdefs: List[QDefWithContext] = attrs.field(factory=list)
- extern_qdefs: List[QDefWithContext] = attrs.field(factory=list)
- # all_costs: Dict['CostKey', Dict] = attrs.field(factory=dict)
+ qglobals: dict[qlt.Bloq, BloqKey] = attrs.field(factory=dict)
+ done: set[qlt.Bloq] = attrs.field(factory=set)
+ qdefs: list[QDefWithContext] = attrs.field(factory=list)
+ extern_qdefs: list[QDefWithContext] = attrs.field(factory=list)
+ # all_costs: dict['CostKey', dict] = attrs.field(factory=dict)
def add_bloqs(
self,
diff --git a/qualtran/l1/_vm.py b/qualtran/l1/_vm.py
index d325f79ae5..ff1798d37e 100644
--- a/qualtran/l1/_vm.py
+++ b/qualtran/l1/_vm.py
@@ -13,7 +13,8 @@
# limitations under the License.
import abc
from collections import Counter
-from typing import Any, Dict, Iterable, List
+from collections.abc import Iterable
+from typing import Any
import attrs
import numpy as np
@@ -23,7 +24,7 @@
def _mock_return_values(regs: Iterable[Register]):
- soqdict: Dict[str, Any] = {}
+ soqdict: dict[str, Any] = {}
# Initialize multi-dimensional dictionary values.
for reg in regs:
@@ -41,7 +42,7 @@ def _mock_return_values(regs: Iterable[Register]):
@attrs.mutable
class StackFrame:
bloq_str: str
- qlocals: Dict[str, Any] = attrs.field(factory=dict)
+ qlocals: dict[str, Any] = attrs.field(factory=dict)
class Problem(metaclass=abc.ABCMeta):
@@ -59,8 +60,8 @@ def get_summary(self) -> str:
@attrs.mutable(kw_only=True)
class StandardQualtranArchitectureAgnosticVirtualMachine:
- frames: List[StackFrame] = attrs.field(factory=list)
- problems: List[Problem] = attrs.field(factory=list)
+ frames: list[StackFrame] = attrs.field(factory=list)
+ problems: list[Problem] = attrs.field(factory=list)
n_calls: int = 0
n_atoms: int = 0
diff --git a/qualtran/l1/nodes.py b/qualtran/l1/nodes.py
index 334e303ae2..c79d8eb1ad 100644
--- a/qualtran/l1/nodes.py
+++ b/qualtran/l1/nodes.py
@@ -14,7 +14,8 @@
"""The Qualtran-L1 AST Nodes."""
import abc
-from typing import Optional, Sequence, Tuple, TypeAlias, Union
+from collections.abc import Sequence
+from typing import Optional, TypeAlias, Union
import attrs
@@ -110,7 +111,7 @@ class QSignatureEntry(L1ASTNode):
"""A quantum signature entry."""
name: str
- dtype: Union[QDTypeNode, Tuple[Optional[QDTypeNode], Optional[QDTypeNode]]]
+ dtype: Union[QDTypeNode, tuple[Optional[QDTypeNode], Optional[QDTypeNode]]]
class StatementNode(L1ASTNode, metaclass=abc.ABCMeta):
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 3644fe9f63..57391179ef 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 cd084a3b88..899241ed8d 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 226e6db045..c6acb03724 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 80af708395..8438480670 100644
--- a/qualtran/resource_counting/_call_graph.py
+++ b/qualtran/resource_counting/_call_graph.py
@@ -14,23 +14,10 @@
"""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
@@ -39,7 +26,7 @@
from ._generalization import _make_composite_generalizer, GeneralizerT
-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]]
@@ -61,7 +48,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."""
@@ -78,7 +65,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
@@ -86,14 +73,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(
@@ -117,7 +104,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.
@@ -204,9 +191,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))):
@@ -233,7 +220,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.
@@ -264,7 +251,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 cc5e491987..873a026a0f 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/call_graph.ipynb b/qualtran/resource_counting/call_graph.ipynb
index 8c6d5e894f..f28f68b765 100644
--- a/qualtran/resource_counting/call_graph.ipynb
+++ b/qualtran/resource_counting/call_graph.ipynb
@@ -170,7 +170,7 @@
"outputs": [],
"source": [
"from functools import cached_property\n",
- "from typing import Dict, Optional, Set, Union\n",
+ "from typing import Union\n",
"\n",
"from attrs import frozen\n",
"\n",
@@ -189,7 +189,7 @@
" def signature(self) -> 'Signature':\n",
" return Signature.build(x=self.n)\n",
"\n",
- " def build_call_graph(self, ssa: 'SympySymbolAllocator') -> Set['BloqCountT']:\n",
+ " def build_call_graph(self, ssa: 'SympySymbolAllocator') -> set['BloqCountT']:\n",
" return {\n",
" (And(), 2*self.n),\n",
" (CNOT(), 5),\n",
diff --git a/qualtran/resource_counting/classify_bloqs.py b/qualtran/resource_counting/classify_bloqs.py
index 88c7ce31f1..8e79ad26db 100644
--- a/qualtran/resource_counting/classify_bloqs.py
+++ b/qualtran/resource_counting/classify_bloqs.py
@@ -18,7 +18,8 @@
"""
from collections import abc, 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
@@ -35,7 +36,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',
@@ -54,7 +55,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:
@@ -76,9 +77,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:
@@ -97,7 +98,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,
@@ -108,7 +109,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 b20e3952fd..2069404ab2 100644
--- a/qualtran/resource_counting/generalizers.py
+++ b/qualtran/resource_counting/generalizers.py
@@ -20,7 +20,8 @@
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/rotation_synthesis/_math_config.py b/qualtran/rotation_synthesis/_math_config.py
index ea435fa802..1b06773c20 100644
--- a/qualtran/rotation_synthesis/_math_config.py
+++ b/qualtran/rotation_synthesis/_math_config.py
@@ -15,7 +15,8 @@
"""A module that defines various mathematical config"""
import math
-from typing import Callable, cast
+from collections.abc import Callable
+from typing import cast
import attrs
import mpmath
diff --git a/qualtran/rotation_synthesis/channels/_channel.py b/qualtran/rotation_synthesis/channels/_channel.py
index 14417a222e..daeb3842ee 100644
--- a/qualtran/rotation_synthesis/channels/_channel.py
+++ b/qualtran/rotation_synthesis/channels/_channel.py
@@ -15,7 +15,8 @@
from __future__ import annotations
import abc
-from typing import Optional, Sequence, Union
+from collections.abc import Sequence
+from typing import Optional, Union
import attrs
import cirq
diff --git a/qualtran/rotation_synthesis/lattice/_ipe.py b/qualtran/rotation_synthesis/lattice/_ipe.py
index fb54fb68cc..2046837045 100644
--- a/qualtran/rotation_synthesis/lattice/_ipe.py
+++ b/qualtran/rotation_synthesis/lattice/_ipe.py
@@ -14,7 +14,7 @@
"""Contains methods for integer point enumeration."""
-from typing import Iterator
+from collections.abc import Iterator
import numpy as np
diff --git a/qualtran/rotation_synthesis/lattice/_test_utils.py b/qualtran/rotation_synthesis/lattice/_test_utils.py
index e2e23df593..7c5d394071 100644
--- a/qualtran/rotation_synthesis/lattice/_test_utils.py
+++ b/qualtran/rotation_synthesis/lattice/_test_utils.py
@@ -12,7 +12,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-from typing import Iterator, Optional
+from collections.abc import Iterator
+from typing import Optional
import numpy as np
diff --git a/qualtran/rotation_synthesis/matrix/_clifford_t_repr.py b/qualtran/rotation_synthesis/matrix/_clifford_t_repr.py
index 2b82da75a3..2acf1bbc5a 100644
--- a/qualtran/rotation_synthesis/matrix/_clifford_t_repr.py
+++ b/qualtran/rotation_synthesis/matrix/_clifford_t_repr.py
@@ -13,7 +13,8 @@
# limitations under the License.
import math
-from typing import cast, Mapping, Optional
+from collections.abc import Mapping
+from typing import cast, Optional
import cirq
import numpy as np
diff --git a/qualtran/rotation_synthesis/matrix/_generation.py b/qualtran/rotation_synthesis/matrix/_generation.py
index 10822bf2ef..4270262d08 100644
--- a/qualtran/rotation_synthesis/matrix/_generation.py
+++ b/qualtran/rotation_synthesis/matrix/_generation.py
@@ -13,7 +13,8 @@
# limitations under the License.
import functools
-from typing import cast, Iterator, Sequence
+from collections.abc import Iterator, Sequence
+from typing import cast
from tqdm import tqdm
diff --git a/qualtran/rotation_synthesis/matrix/_su2_ct.py b/qualtran/rotation_synthesis/matrix/_su2_ct.py
index caeac6ca1c..141600cb45 100644
--- a/qualtran/rotation_synthesis/matrix/_su2_ct.py
+++ b/qualtran/rotation_synthesis/matrix/_su2_ct.py
@@ -14,7 +14,8 @@
import functools
import itertools
-from typing import cast, Mapping, Optional, Sequence, Union
+from collections.abc import Mapping, Sequence
+from typing import cast, Optional, Union
import attrs
import numpy as np
diff --git a/qualtran/rotation_synthesis/protocols/_diagonal.py b/qualtran/rotation_synthesis/protocols/_diagonal.py
index 32362fde00..3eecf3678e 100644
--- a/qualtran/rotation_synthesis/protocols/_diagonal.py
+++ b/qualtran/rotation_synthesis/protocols/_diagonal.py
@@ -14,7 +14,8 @@
from __future__ import annotations
-from typing import Callable, Iterator, Optional, TYPE_CHECKING
+from collections.abc import Callable, Iterator
+from typing import Optional, TYPE_CHECKING
if TYPE_CHECKING:
import matplotlib.pyplot as plt
diff --git a/qualtran/rotation_synthesis/protocols/_fallback.py b/qualtran/rotation_synthesis/protocols/_fallback.py
index 330ff3201f..8a57c3f438 100644
--- a/qualtran/rotation_synthesis/protocols/_fallback.py
+++ b/qualtran/rotation_synthesis/protocols/_fallback.py
@@ -15,7 +15,8 @@
from __future__ import annotations
import functools
-from typing import Callable, Iterator, Optional, TYPE_CHECKING
+from collections.abc import Callable, Iterator
+from typing import Optional, TYPE_CHECKING
if TYPE_CHECKING:
import matplotlib.pyplot as plt
diff --git a/qualtran/rotation_synthesis/protocols/_mixed_diagonal.py b/qualtran/rotation_synthesis/protocols/_mixed_diagonal.py
index ac3b5a49eb..332e9ef55b 100644
--- a/qualtran/rotation_synthesis/protocols/_mixed_diagonal.py
+++ b/qualtran/rotation_synthesis/protocols/_mixed_diagonal.py
@@ -14,7 +14,8 @@
from __future__ import annotations
-from typing import Callable, Iterator, Optional, TYPE_CHECKING
+from collections.abc import Callable, Iterator
+from typing import Optional, TYPE_CHECKING
if TYPE_CHECKING:
import matplotlib.pyplot as plt
diff --git a/qualtran/rotation_synthesis/protocols/_protocol.py b/qualtran/rotation_synthesis/protocols/_protocol.py
index 5082ab37b7..4eaacd9763 100644
--- a/qualtran/rotation_synthesis/protocols/_protocol.py
+++ b/qualtran/rotation_synthesis/protocols/_protocol.py
@@ -15,7 +15,8 @@
from __future__ import annotations
import abc
-from typing import Callable, Iterator, Optional, TYPE_CHECKING
+from collections.abc import Callable, Iterator
+from typing import Optional, TYPE_CHECKING
if TYPE_CHECKING:
import matplotlib.pyplot as plt
diff --git a/qualtran/rotation_synthesis/rings/_zw.py b/qualtran/rotation_synthesis/rings/_zw.py
index 1211d381f1..d2a53f1927 100644
--- a/qualtran/rotation_synthesis/rings/_zw.py
+++ b/qualtran/rotation_synthesis/rings/_zw.py
@@ -15,7 +15,8 @@
"""The ring Z[w] where w = e^{i pi/4}"""
import itertools
-from typing import Sequence, Union
+from collections.abc import Sequence
+from typing import Union
import attrs
import numpy as np
diff --git a/qualtran/serialization/bloq.py b/qualtran/serialization/bloq.py
index eb603b8791..8e01d5d32d 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.Soqu
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 eefe901f04..40d2d2d323 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
@@ -67,7 +67,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,
@@ -93,7 +93,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.ipynb b/qualtran/simulation/classical_sim.ipynb
index 9f99d7e8d8..a84e25ee0c 100644
--- a/qualtran/simulation/classical_sim.ipynb
+++ b/qualtran/simulation/classical_sim.ipynb
@@ -208,7 +208,7 @@
"\n",
" def on_classical_vals(\n",
" self, ctrl: NDArray[np.uint8], target: NDArray[np.uint8]\n",
- " ) -> Dict[str, NDArray[np.uint8]]:\n",
+ " ) -> dict[str, NDArray[np.uint8]]:\n",
" target_out = (ctrl + target) % 2\n",
" return {'ctrl': ctrl, 'target': target_out}"
]
diff --git a/qualtran/simulation/classical_sim.py b/qualtran/simulation/classical_sim.py
index c2fdc0a9e8..f1626e75fc 100644
--- a/qualtran/simulation/classical_sim.py
+++ b/qualtran/simulation/classical_sim.py
@@ -16,19 +16,8 @@
import abc
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 attrs
import networkx as nx
@@ -98,7 +87,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:
@@ -160,7 +149,7 @@ class _FixedClassicalValHandler(_ClassicalValHandler):
to the fixed classical value.
"""
- def __init__(self, binst_i_to_val: Dict[int, Any]):
+ def __init__(self, binst_i_to_val: dict[int, Any]):
self._binst_i_to_val = binst_i_to_val
def get(self, binst, distribution: ClassicalValDistribution):
@@ -190,7 +179,7 @@ class MeasurementPhase:
"""
reg_name: str
- idx: Tuple[int, ...] = ()
+ idx: tuple[int, ...] = ()
class ClassicalSimState:
@@ -235,7 +224,7 @@ def __init__(
self._random_handler = random_handler
# 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
@@ -261,7 +250,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`.
@@ -396,7 +385,7 @@ def _in_vals(reg: Register):
return self
- def finalize(self) -> Dict[str, 'ClassicalValT']:
+ def finalize(self) -> dict[str, 'ClassicalValT']:
"""Finish simulating a composite bloq and extract final values.
Returns:
@@ -420,7 +409,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:
@@ -477,7 +466,7 @@ def from_cbloq(
cbloq: 'CompositeBloq',
vals: Mapping[str, Union[sympy.Symbol, ClassicalValT]],
rng: Optional['np.random.Generator'] = None,
- fixed_random_vals: Optional[Dict[int, Any]] = None,
+ fixed_random_vals: Optional[dict[int, Any]] = None,
) -> 'PhasedClassicalSimState':
"""Initiate a classical simulation from a CompositeBloq.
@@ -553,7 +542,7 @@ def call_cbloq_classically(
random_handler: '_ClassicalValHandler' = _RandomClassicalValHandler(
rng=np.random.default_rng()
),
-) -> 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
@@ -586,8 +575,8 @@ def do_phased_classical_simulation(
bloq: 'Bloq',
vals: Mapping[str, 'ClassicalValT'],
rng: Optional['np.random.Generator'] = None,
- fixed_random_vals: Optional[Dict[int, Any]] = None,
-) -> Tuple[Dict[str, 'ClassicalValT'], complex]:
+ fixed_random_vals: Optional[dict[int, Any]] = None,
+) -> tuple[dict[str, 'ClassicalValT'], complex]:
"""Do a phased classical simulation of the bloq.
This provides a simple interface to `PhasedClassicalSimState`. Advanced users
@@ -618,7 +607,7 @@ def do_phased_classical_simulation(
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:
@@ -637,14 +626,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)
@@ -656,7 +645,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 a4209d4ad0..f59ebeeb22 100644
--- a/qualtran/simulation/classical_sim_test.py
+++ b/qualtran/simulation/classical_sim_test.py
@@ -13,7 +13,7 @@
# limitations under the License.
import itertools
-from typing import Dict, Union
+from typing import Union
import attrs
import networkx as nx
@@ -100,7 +100,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}
@@ -281,7 +281,7 @@ def signature(self) -> 'Signature':
[Register('q', QBit(), side=Side.LEFT), Register('c', CBit(), side=Side.RIGHT)]
)
- def on_classical_vals(self, *, q: int) -> Dict[str, ClassicalValRetT]:
+ def on_classical_vals(self, *, q: int) -> dict[str, ClassicalValRetT]:
return {'c': ClassicalValDistribution(2)}
@@ -351,7 +351,7 @@ class ComposedPhasing(Bloq):
def signature(self) -> 'Signature':
return Signature([Register('x', QBit(), side=Side.RIGHT)])
- def build_composite_bloq(self, bb: 'BloqBuilder') -> Dict[str, 'SoquetT']:
+ def build_composite_bloq(self, bb: 'BloqBuilder') -> dict[str, 'SoquetT']:
from qualtran.bloqs.basic_gates import OneState, ZGate
x = bb.add(OneState())
diff --git a/qualtran/simulation/tensor.ipynb b/qualtran/simulation/tensor.ipynb
index d91373e7d8..be05b81923 100644
--- a/qualtran/simulation/tensor.ipynb
+++ b/qualtran/simulation/tensor.ipynb
@@ -266,7 +266,7 @@
"outputs": [],
"source": [
"from functools import cached_property\n",
- "from typing import Any, Dict, Tuple, List\n",
+ "from typing import *\n",
"\n",
"import numpy as np\n",
"import quimb.tensor as qtn\n",
@@ -281,8 +281,8 @@
" return Signature.build(ctrl=1, target=1)\n",
"\n",
" def my_tensors(\n",
- " self, incoming: Dict[str, 'ConnectionT'], outgoing: Dict[str, 'ConnectionT']\n",
- " ) -> List['qtn.Tensor']:\n",
+ " self, incoming: dict[str, 'ConnectionT'], outgoing: dict[str, 'ConnectionT']\n",
+ " ) -> list['qtn.Tensor']:\n",
" # The familiar CNOT matrix. We make sure to\n",
" # cast this to np.complex128 so we don't accidentally\n",
" # lose precision anywhere else in the contraction.\n",
diff --git a/qualtran/simulation/tensor/_dense.py b/qualtran/simulation/tensor/_dense.py
index 13aa81f506..4afef3b7a6 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 122b1fa1dd..a72203d1d1 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 e2b3a8e3f1..9425ea7625 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 a76d290792..9809c35e1e 100644
--- a/qualtran/simulation/tensor/_tensor_data_manipulation.py
+++ b/qualtran/simulation/tensor/_tensor_data_manipulation.py
@@ -15,7 +15,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
@@ -25,7 +25,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
@@ -43,7 +43,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
@@ -62,7 +62,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`.
@@ -74,7 +74,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)
@@ -118,7 +118,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 7e44df0b79..d6b3b9657f 100644
--- a/qualtran/simulation/xcheck_classical_quimb.py
+++ b/qualtran/simulation/xcheck_classical_quimb.py
@@ -14,7 +14,8 @@
"""Tools to cross-check classical and quimb tensor network simulations of bloqs."""
-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
@@ -25,12 +26,12 @@
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`."""
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.asarray(vals[reg.name])
@@ -47,8 +48,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`."""
from qualtran.bloqs.basic_gates import IntEffect
@@ -69,8 +70,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 6a10d4c0a8..973fa344c3 100644
--- a/qualtran/symbolics/math_funcs.py
+++ b/qualtran/symbolics/math_funcs.py
@@ -15,7 +15,8 @@
"""Mathematical functions that support either symbolic or concrete values."""
import math
-from typing import Any, cast, Iterable, overload, TypeVar
+from collections.abc import Iterable
+from typing import Any, cast, overload, TypeVar
import numpy as np
import sympy
diff --git a/qualtran/testing.py b/qualtran/testing.py
index 253f7a1c16..c180590541 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, TYPE_CHECKING, Union
+from typing import Optional, TYPE_CHECKING, Union
import numpy as np
import sympy
@@ -240,7 +241,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
@@ -378,7 +379,7 @@ def assert_bloq_example_make(bloq_ex: BloqExample) -> None:
raise BloqCheckException.fail(f'{bloq} is not an instance of {bloq_ex.bloq_cls}')
-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:
@@ -420,7 +421,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
@@ -464,8 +465,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
@@ -532,7 +533,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.
@@ -595,7 +596,7 @@ def assert_bloq_example_serializes(bloq_ex: BloqExample) -> None:
) from e
-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
@@ -620,7 +621,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
@@ -670,7 +671,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