Skip to content

Commit

Permalink
Add ruff check to CI and clean up Python (#1661)
Browse files Browse the repository at this point in the history
  • Loading branch information
cqc-alec authored Nov 8, 2024
1 parent 9b31e67 commit c52838b
Show file tree
Hide file tree
Showing 85 changed files with 1,565 additions and 1,604 deletions.
8 changes: 6 additions & 2 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ jobs:
uses: actions/setup-python@v5
with:
python-version: '3.x'
- name: Install black and pylint
run: pip install black pylint
- name: Install black, pylint and ruff
run: pip install black pylint ruff
- name: Check files are formatted with black
run: |
# Paths specified to avoid formatting submodules
Expand All @@ -25,3 +25,7 @@ jobs:
run: |
cd pytket
pylint --ignore-paths=pytket/_tket pytket/
- name: ruff check
run: |
cd pytket
ruff check .
2 changes: 1 addition & 1 deletion pytket/conanfile.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from conan import ConanFile
from conan.tools.cmake import CMakeToolchain, CMake, cmake_layout, CMakeDeps
from conan.tools.cmake import CMake, CMakeDeps, CMakeToolchain, cmake_layout


class pytketRecipe(ConanFile):
Expand Down
2 changes: 1 addition & 1 deletion pytket/docs/check_circuit_class_docs.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
# This script is used to check that no methods or properties of
# the Circuit class are left out in the circuit_class.rst file.

with open("circuit_class.rst", "r", encoding="utf-8") as file:
with open("circuit_class.rst", encoding="utf-8") as file:
rst = file.read()

in_methods = {p[0] for p in inspect.getmembers(Circuit)}
Expand Down
12 changes: 6 additions & 6 deletions pytket/pytket/__init__.py
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,20 @@

"""Python Interface to tket
"""
import pytket.architecture # noqa: I001
from pytket.circuit import (
Circuit,
OpType,
)
from pytket.unit_id import (
Qubit,
Bit,
)
import pytket.mapping
import pytket.architecture
import pytket.placement
import pytket.transform
from pytket.config import PytketConfig, get_config_file_path
from pytket._version import __version__
from pytket.config import PytketConfig, get_config_file_path
from pytket.unit_id import (
Bit,
Qubit,
)

# Create pytket config file if it does not exist:
pytket_config_file = get_config_file_path()
Expand Down
2 changes: 1 addition & 1 deletion pytket/pytket/backends/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,6 @@
__path__ = __import__("pkgutil").extend_path(__path__, __name__)

from .backend import Backend
from .backend_exceptions import CircuitNotRunError, CircuitNotValidError
from .resulthandle import ResultHandle
from .status import CircuitStatus, StatusEnum
from .backend_exceptions import CircuitNotRunError, CircuitNotValidError
80 changes: 34 additions & 46 deletions pytket/pytket/backends/backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,40 +15,29 @@
""" Abstract base class for all Backend encapsulations."""
import warnings
from abc import ABC, abstractmethod
from typing import (
Dict,
Iterable,
List,
Optional,
Sequence,
Union,
Any,
cast,
overload,
)
from collections.abc import Iterable, Sequence
from importlib import import_module
from types import ModuleType

from typing_extensions import Literal
from typing import Any, Literal, cast, overload

from pytket.circuit import Bit, Circuit, OpType
from pytket.passes import BasePass
from pytket.pauli import QubitPauliString
from pytket.predicates import Predicate
from pytket.utils import QubitPauliOperator
from pytket.utils.outcomearray import OutcomeArray
from pytket.utils.results import KwargTypes
from pytket.utils import QubitPauliOperator

from .backend_exceptions import (
CircuitNotValidError,
CircuitNotRunError,
CircuitNotValidError,
)
from .backendinfo import BackendInfo
from .backendresult import BackendResult
from .resulthandle import ResultHandle, _ResultIdTuple
from .status import CircuitStatus

ResultCache = Dict[str, Any]
ResultCache = dict[str, Any]


class ResultHandleTypeError(Exception):
Expand All @@ -73,7 +62,7 @@ class Backend(ABC):
_persistent_handles = False

def __init__(self) -> None:
self._cache: Dict[ResultHandle, ResultCache] = {}
self._cache: dict[ResultHandle, ResultCache] = {}

@staticmethod
def empty_result(circuit: Circuit, n_shots: int) -> BackendResult:
Expand All @@ -85,7 +74,7 @@ def empty_result(circuit: Circuit, n_shots: int) -> BackendResult:

@property
@abstractmethod
def required_predicates(self) -> List[Predicate]:
def required_predicates(self) -> list[Predicate]:
"""
The minimum set of predicates that a circuit must satisfy before it can
be successfully run on this backend.
Expand All @@ -107,7 +96,7 @@ def valid_circuit(self, circuit: Circuit) -> bool:
return all(pred.verify(circuit) for pred in self.required_predicates)

def _check_all_circuits(
self, circuits: Iterable[Circuit], nomeasure_warn: Optional[bool] = None
self, circuits: Iterable[Circuit], nomeasure_warn: bool | None = None
) -> bool:
if nomeasure_warn is None:
nomeasure_warn = not (
Expand Down Expand Up @@ -185,7 +174,7 @@ def get_compiled_circuit(

def get_compiled_circuits(
self, circuits: Sequence[Circuit], optimisation_level: int = 2
) -> List[Circuit]:
) -> list[Circuit]:
"""Compile a sequence of circuits with :py:meth:`default_compilation_pass`
and return the list of compiled circuits (does not act in place).
Expand Down Expand Up @@ -237,15 +226,14 @@ def _check_handle_type(self, reshandle: ResultHandle) -> None:
isinstance(idval, ty) for idval, ty in zip(reshandle, self._result_id_type)
):
raise ResultHandleTypeError(
"{0!r} does not match expected identifier types {1}".format(
reshandle, self._result_id_type
)
f"{reshandle!r} does not match expected "
f"identifier types {self._result_id_type}"
)

def process_circuit(
self,
circuit: Circuit,
n_shots: Optional[int] = None,
n_shots: int | None = None,
valid_check: bool = True,
**kwargs: KwargTypes,
) -> ResultHandle:
Expand All @@ -262,10 +250,10 @@ def process_circuit(
def process_circuits(
self,
circuits: Sequence[Circuit],
n_shots: Optional[Union[int, Sequence[int]]] = None,
n_shots: int | Sequence[int] | None = None,
valid_check: bool = True,
**kwargs: KwargTypes,
) -> List[ResultHandle]:
) -> list[ResultHandle]:
"""
Submit circuits to the backend for running. The results will be stored
in the backend's result cache to be retrieved by the corresponding
Expand Down Expand Up @@ -316,7 +304,7 @@ def empty_cache(self) -> None:
"""Manually empty the result cache on the backend."""
self._cache = {}

def pop_result(self, handle: ResultHandle) -> Optional[ResultCache]:
def pop_result(self, handle: ResultHandle) -> ResultCache | None:
"""Remove cache entry corresponding to handle from the cache and return.
:param handle: ResultHandle object
Expand Down Expand Up @@ -348,7 +336,7 @@ def get_result(self, handle: ResultHandle, **kwargs: KwargTypes) -> BackendResul

def get_results(
self, handles: Iterable[ResultHandle], **kwargs: KwargTypes
) -> List[BackendResult]:
) -> list[BackendResult]:
"""Return results corresponding to handles.
:param handles: Iterable of handles
Expand All @@ -372,7 +360,7 @@ def get_results(
def run_circuit(
self,
circuit: Circuit,
n_shots: Optional[int] = None,
n_shots: int | None = None,
valid_check: bool = True,
**kwargs: KwargTypes,
) -> BackendResult:
Expand All @@ -396,10 +384,10 @@ def run_circuit(
def run_circuits(
self,
circuits: Sequence[Circuit],
n_shots: Optional[Union[int, Sequence[int]]] = None,
n_shots: int | Sequence[int] | None = None,
valid_check: bool = True,
**kwargs: KwargTypes,
) -> List[BackendResult]:
) -> list[BackendResult]:
"""
Submits circuits to the backend and returns results
Expand Down Expand Up @@ -430,7 +418,7 @@ def cancel(self, handle: ResultHandle) -> None:
raise NotImplementedError("Backend does not support job cancellation.")

@property
def backend_info(self) -> Optional[BackendInfo]:
def backend_info(self) -> BackendInfo | None:
"""Retrieve all Backend properties in a BackendInfo object, including
device architecture, supported gate set, gate errors and other hardware-specific
information.
Expand All @@ -441,7 +429,7 @@ def backend_info(self) -> Optional[BackendInfo]:
raise NotImplementedError("Backend does not provide any device properties.")

@classmethod
def available_devices(cls, **kwargs: Any) -> List[BackendInfo]:
def available_devices(cls, **kwargs: Any) -> list[BackendInfo]:
"""Retrieve all available devices as a list of BackendInfo objects, including
device name, architecture, supported gate set, gate errors,
and other hardware-specific information.
Expand Down Expand Up @@ -516,7 +504,7 @@ def supports_contextual_optimisation(self) -> bool:
See :py:meth:`process_circuits`."""
return self._supports_contextual_optimisation

def _get_extension_module(self) -> Optional[ModuleType]:
def _get_extension_module(self) -> ModuleType | None:
"""Return the extension module of the backend if it belongs to a
pytket-extension package.
Expand All @@ -530,7 +518,7 @@ def _get_extension_module(self) -> Optional[ModuleType]:
return import_module(".".join(mod_parts))

@property
def __extension_name__(self) -> Optional[str]:
def __extension_name__(self) -> str | None:
"""Retrieve the extension name of the backend if it belongs to a
pytket-extension package.
Expand All @@ -544,7 +532,7 @@ def __extension_name__(self) -> Optional[str]:
return None

@property
def __extension_version__(self) -> Optional[str]:
def __extension_version__(self) -> str | None:
"""Retrieve the extension version of the backend if it belongs to a
pytket-extension package.
Expand All @@ -560,36 +548,36 @@ def __extension_version__(self) -> Optional[str]:
@overload
@staticmethod
def _get_n_shots_as_list(
n_shots: Union[None, int, Sequence[Optional[int]]],
n_shots: None | int | Sequence[int | None],
n_circuits: int,
optional: Literal[False],
) -> List[int]: ...
) -> list[int]: ...

@overload
@staticmethod
def _get_n_shots_as_list(
n_shots: Union[None, int, Sequence[Optional[int]]],
n_shots: None | int | Sequence[int | None],
n_circuits: int,
optional: Literal[True],
set_zero: Literal[True],
) -> List[int]: ...
) -> list[int]: ...

@overload
@staticmethod
def _get_n_shots_as_list(
n_shots: Union[None, int, Sequence[Optional[int]]],
n_shots: None | int | Sequence[int | None],
n_circuits: int,
optional: bool = True,
set_zero: bool = False,
) -> Union[List[Optional[int]], List[int]]: ...
) -> list[int | None] | list[int]: ...

@staticmethod
def _get_n_shots_as_list(
n_shots: Union[None, int, Sequence[Optional[int]]],
n_shots: None | int | Sequence[int | None],
n_circuits: int,
optional: bool = True,
set_zero: bool = False,
) -> Union[List[Optional[int]], List[int]]:
) -> list[int | None] | list[int]:
"""
Convert any admissible n_shots value into List[Optional[int]] format.
Expand All @@ -609,9 +597,9 @@ def _get_n_shots_as_list(
:return: a list of length `n_circuits`, the converted argument
"""

n_shots_list: List[Optional[int]] = []
n_shots_list: list[int | None] = []

def validate_n_shots(n: Optional[int]) -> bool:
def validate_n_shots(n: int | None) -> bool:
return optional or (n is not None and n > 0)

if set_zero and not optional:
Expand Down
11 changes: 4 additions & 7 deletions pytket/pytket/backends/backend_exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,13 @@
# See the License for the specific language governing permissions and
# limitations under the License.

from typing import Union, Optional
from .resulthandle import ResultHandle


class CircuitNotValidError(Exception):
"""Raised when a submitted circuit does not satisfy all predicates"""

def __init__(self, message: Union[str, int], failed_pred: Optional[str] = None):
def __init__(self, message: str | int, failed_pred: str | None = None):
if isinstance(message, int):
message = (
"Circuit with index {0} in submitted does not satisfy "
Expand All @@ -34,15 +33,13 @@ class CircuitNotRunError(Exception):

def __init__(self, handle: ResultHandle):
super().__init__(
"Circuit corresponding to {0!r} ".format(handle)
+ "has not been run by this backend instance."
f"Circuit corresponding to {handle!r} "
"has not been run by this backend instance."
)


class InvalidResultType(Exception):
"""Raised when a BackendResult instance cannot produce the required result type."""

def __init__(self, result_type: str):
super().__init__(
"BackendResult cannot produce result of type {}.".format(result_type)
)
super().__init__(f"BackendResult cannot produce result of type {result_type}.")
Loading

0 comments on commit c52838b

Please sign in to comment.