diff --git a/qiskit/algorithms/amplitude_amplifiers/amplification_problem.py b/qiskit/algorithms/amplitude_amplifiers/amplification_problem.py index c2908a86aa90..459dd888d939 100644 --- a/qiskit/algorithms/amplitude_amplifiers/amplification_problem.py +++ b/qiskit/algorithms/amplitude_amplifiers/amplification_problem.py @@ -63,7 +63,7 @@ def __init__( if is_good_state is not None: self._is_good_state = is_good_state elif hasattr(oracle, "evaluate_bitstring"): - self._is_good_state = oracle.evaluate_bitstring + self._is_good_state = oracle.evaluate_bitstring # type: ignore[union-attr] else: self._is_good_state = None @@ -167,14 +167,17 @@ def is_good_state(self) -> Callable[[str], bool]: return self._is_good_state # returns None if no is_good_state arg has been set elif isinstance(self._is_good_state, list): if all(isinstance(good_bitstr, str) for good_bitstr in self._is_good_state): - return lambda bitstr: bitstr in self._is_good_state + return lambda bitstr: bitstr in self._is_good_state # type:ignore[operator] else: return lambda bitstr: all( - bitstr[good_index] == "1" # type:ignore - for good_index in self._is_good_state + bitstr[good_index] == "1" # type:ignore[index] + for good_index in self._is_good_state # type:ignore[union-attr] ) - return lambda bitstr: bitstr in self._is_good_state.probabilities_dict() + return ( + lambda bitstr: bitstr + in self._is_good_state.probabilities_dict() # type:ignore[union-attr] + ) @is_good_state.setter def is_good_state( diff --git a/qiskit/algorithms/amplitude_amplifiers/amplitude_amplifier.py b/qiskit/algorithms/amplitude_amplifiers/amplitude_amplifier.py index 5759fe377f3b..36c660a5d1fe 100644 --- a/qiskit/algorithms/amplitude_amplifiers/amplitude_amplifier.py +++ b/qiskit/algorithms/amplitude_amplifiers/amplitude_amplifier.py @@ -43,9 +43,9 @@ class AmplitudeAmplifierResult(AlgorithmResult): def __init__(self) -> None: super().__init__() - self._top_measurement = None + self._top_measurement: Optional[str] = None self._assignment = None - self._oracle_evaluation = None + self._oracle_evaluation: Optional[bool] = None @property def top_measurement(self) -> Optional[str]: diff --git a/qiskit/algorithms/amplitude_amplifiers/grover.py b/qiskit/algorithms/amplitude_amplifiers/grover.py index bc9a729a691b..b44c1156d0bd 100644 --- a/qiskit/algorithms/amplitude_amplifiers/grover.py +++ b/qiskit/algorithms/amplitude_amplifiers/grover.py @@ -156,7 +156,7 @@ def __init__( else: self._iterations = iterations - self._quantum_instance = None + self._quantum_instance: Optional[QuantumInstance] = None if quantum_instance is not None: self.quantum_instance = quantum_instance @@ -340,7 +340,7 @@ class GroverResult(AmplitudeAmplifierResult): def __init__(self) -> None: super().__init__() - self._iterations = None + self._iterations: Optional[List[int]] = None self._circuit_results = None self._shots = None diff --git a/qiskit/algorithms/amplitude_estimators/ae.py b/qiskit/algorithms/amplitude_estimators/ae.py index 4d4c89873235..f96418d1bd20 100644 --- a/qiskit/algorithms/amplitude_estimators/ae.py +++ b/qiskit/algorithms/amplitude_estimators/ae.py @@ -386,13 +386,13 @@ class AmplitudeEstimationResult(AmplitudeEstimatorResult): def __init__(self) -> None: super().__init__() - self._num_evaluation_qubits = None - self._mle = None - self._mle_processed = None - self._samples = None - self._samples_processed = None - self._y_measurements = None - self._max_probability = None + self._num_evaluation_qubits: Optional[int] = None + self._mle: Optional[float] = None + self._mle_processed: Optional[float] = None + self._samples: Optional[Dict[float, float]] = None + self._samples_processed: Optional[Dict[float, float]] = None + self._y_measurements: Optional[Dict[int, float]] = None + self._max_probability: Optional[float] = None @property def num_evaluation_qubits(self) -> int: @@ -500,7 +500,7 @@ def integrand(x): def _fisher_confint( result: AmplitudeEstimationResult, alpha: float, observed: bool = False -) -> List[float]: +) -> Tuple[float, float]: """Compute the Fisher information confidence interval for the MLE of the previous run. Args: @@ -520,7 +520,9 @@ def _fisher_confint( return tuple(result.post_processing(bound) for bound in confint) -def _likelihood_ratio_confint(result: AmplitudeEstimationResult, alpha: float) -> List[float]: +def _likelihood_ratio_confint( + result: AmplitudeEstimationResult, alpha: float +) -> Tuple[float, float]: """Compute the likelihood ratio confidence interval for the MLE of the previous run. Args: diff --git a/qiskit/algorithms/amplitude_estimators/amplitude_estimator.py b/qiskit/algorithms/amplitude_estimators/amplitude_estimator.py index 93136b034737..32c2fe93be19 100644 --- a/qiskit/algorithms/amplitude_estimators/amplitude_estimator.py +++ b/qiskit/algorithms/amplitude_estimators/amplitude_estimator.py @@ -39,14 +39,14 @@ class AmplitudeEstimatorResult(AlgorithmResult): def __init__(self) -> None: super().__init__() - self._circuit_results = None - self._shots = None - self._estimation = None - self._estimation_processed = None - self._num_oracle_queries = None - self._post_processing = None - self._confidence_interval = None - self._confidence_interval_processed = None + self._circuit_results: Optional[Union[np.ndarray, Dict[str, int]]] = None + self._shots: Optional[int] = None + self._estimation: Optional[float] = None + self._estimation_processed: Optional[float] = None + self._num_oracle_queries: Optional[int] = None + self._post_processing: Optional[Callable[[float], float]] = None + self._confidence_interval: Optional[Tuple[float, float]] = None + self._confidence_interval_processed: Optional[Tuple[float, float]] = None @property def circuit_results(self) -> Optional[Union[np.ndarray, Dict[str, int]]]: diff --git a/qiskit/algorithms/amplitude_estimators/fae.py b/qiskit/algorithms/amplitude_estimators/fae.py index db8ee9151d50..0702d2d6bf13 100644 --- a/qiskit/algorithms/amplitude_estimators/fae.py +++ b/qiskit/algorithms/amplitude_estimators/fae.py @@ -234,7 +234,7 @@ def cos_estimate(power, shots): theta = np.mean(theta_ci) rescaling = 4 if self._rescale else 1 value = (rescaling * np.sin(theta)) ** 2 - value_ci = [(rescaling * np.sin(x)) ** 2 for x in theta_ci] + value_ci = [(rescaling * np.sin(x)) ** 2 for x in theta_ci] # TODO should be tuple? result = FasterAmplitudeEstimationResult() result.num_oracle_queries = self._num_oracle_calls @@ -261,14 +261,15 @@ class FasterAmplitudeEstimationResult(AmplitudeEstimatorResult): def __init__(self) -> None: super().__init__() - self._success_probability = None - self._num_steps = None - self._num_first_state_steps = None - self._theta_intervals = None + self._success_probability: Optional[int] = None + self._num_steps: Optional[int] = None + self._num_first_state_steps: Optional[int] = None + self._theta_intervals: Optional[List[List[float]]] = None @property def success_probability(self) -> int: """Return the success probability of the algorithm.""" + # TODO: should be float? return self._success_probability @success_probability.setter diff --git a/qiskit/algorithms/amplitude_estimators/iae.py b/qiskit/algorithms/amplitude_estimators/iae.py index 42727cc5aea0..c11538db343e 100644 --- a/qiskit/algorithms/amplitude_estimators/iae.py +++ b/qiskit/algorithms/amplitude_estimators/iae.py @@ -432,15 +432,15 @@ class IterativeAmplitudeEstimationResult(AmplitudeEstimatorResult): def __init__(self) -> None: super().__init__() - self._alpha = None - self._epsilon_target = None - self._epsilon_estimated = None - self._epsilon_estimated_processed = None - self._estimate_intervals = None - self._theta_intervals = None - self._powers = None - self._ratios = None - self._confidence_interval_processed = None + self._alpha: Optional[float] = None + self._epsilon_target: Optional[float] = None + self._epsilon_estimated: Optional[float] = None + self._epsilon_estimated_processed: Optional[float] = None + self._estimate_intervals: Optional[List[List[float]]] = None + self._theta_intervals: Optional[List[List[float]]] = None + self._powers: Optional[List[int]] = None + self._ratios: Optional[List[float]] = None + self._confidence_interval_processed: Optional[Tuple[float, float]] = None @property def alpha(self) -> float: diff --git a/qiskit/algorithms/amplitude_estimators/mlae.py b/qiskit/algorithms/amplitude_estimators/mlae.py index 21ca0cb35d1a..e27cf26a19a9 100644 --- a/qiskit/algorithms/amplitude_estimators/mlae.py +++ b/qiskit/algorithms/amplitude_estimators/mlae.py @@ -12,7 +12,7 @@ """The Maximum Likelihood Amplitude Estimation algorithm.""" -from typing import Optional, List, Union, Tuple, Dict, Callable +from typing import Optional, List, Union, Tuple, Dict, Callable, Sequence import numpy as np from scipy.optimize import brute from scipy.stats import norm, chi2 @@ -191,7 +191,7 @@ def compute_confidence_interval( AlgorithmError: If `run()` hasn't been called yet. NotImplementedError: If the method `kind` is not supported. """ - interval = None + interval: Optional[Tuple[float, float]] = None # if statevector simulator the estimate is exact if all(isinstance(data, (list, np.ndarray)) for data in result.circuit_results): @@ -216,7 +216,7 @@ def compute_confidence_interval( def compute_mle( self, - circuit_results: Union[List[Dict[str, int]], List[np.ndarray]], + circuit_results: List[Union[Dict[str, int], np.ndarray]], estimation_problem: EstimationProblem, num_state_qubits: Optional[int] = None, return_counts: bool = False, @@ -326,11 +326,11 @@ class MaximumLikelihoodAmplitudeEstimationResult(AmplitudeEstimatorResult): def __init__(self) -> None: super().__init__() - self._theta = None - self._minimizer = None - self._good_counts = None - self._evaluation_schedule = None - self._fisher_information = None + self._theta: Optional[float] = None + self._minimizer: Optional[Callable] = None + self._good_counts: Optional[List[float]] = None + self._evaluation_schedule: Optional[List[int]] = None + self._fisher_information: Optional[float] = None @property def theta(self) -> float: @@ -343,12 +343,12 @@ def theta(self, value: float) -> None: self._theta = value @property - def minimizer(self) -> callable: + def minimizer(self) -> Callable: """Return the minimizer used for the search of the likelihood function.""" return self._minimizer @minimizer.setter - def minimizer(self, value: callable) -> None: + def minimizer(self, value: Callable) -> None: """Set the number minimizer used for the search of the likelihood function.""" self._minimizer = value @@ -490,7 +490,7 @@ def _likelihood_ratio_confint( result: MaximumLikelihoodAmplitudeEstimationResult, alpha: float = 0.05, nevals: Optional[int] = None, -) -> List[float]: +) -> Tuple[float, float]: """Compute the likelihood-ratio confidence interval. Args: @@ -538,7 +538,7 @@ def loglikelihood(theta, one_counts, all_counts): def _get_counts( - circuit_results: List[Union[np.ndarray, List[float], Dict[str, int]]], + circuit_results: Sequence[Union[np.ndarray, List[float], Dict[str, int]]], estimation_problem: EstimationProblem, num_state_qubits: int, ) -> Tuple[List[float], List[int]]: @@ -551,7 +551,9 @@ def _get_counts( AlgorithmError: If self.run() has not been called yet. """ one_hits = [] # h_k: how often 1 has been measured, for a power Q^(m_k) - all_hits = [] # shots_k: how often has been measured at a power Q^(m_k) + all_hits: Union[ + np.ndarray, List[float] + ] = [] # shots_k: how often has been measured at a power Q^(m_k) if all(isinstance(data, (list, np.ndarray)) for data in circuit_results): probabilities = [] num_qubits = int(np.log2(len(circuit_results[0]))) # the total number of qubits diff --git a/qiskit/algorithms/eigen_solvers/eigen_solver.py b/qiskit/algorithms/eigen_solvers/eigen_solver.py index 28ca3e9d1f8b..07b6799f7655 100644 --- a/qiskit/algorithms/eigen_solvers/eigen_solver.py +++ b/qiskit/algorithms/eigen_solvers/eigen_solver.py @@ -67,9 +67,9 @@ class EigensolverResult(AlgorithmResult): def __init__(self) -> None: super().__init__() - self._eigenvalues = None - self._eigenstates = None - self._aux_operator_eigenvalues = None + self._eigenvalues: Optional[np.ndarray] = None + self._eigenstates: Optional[np.ndarray] = None + self._aux_operator_eigenvalues: Optional[List[ListOrDict[Tuple[complex, complex]]]] = None @property def eigenvalues(self) -> Optional[np.ndarray]: diff --git a/qiskit/algorithms/eigen_solvers/vqd.py b/qiskit/algorithms/eigen_solvers/vqd.py index d5070fad4367..6bd69bb92a79 100644 --- a/qiskit/algorithms/eigen_solvers/vqd.py +++ b/qiskit/algorithms/eigen_solvers/vqd.py @@ -158,27 +158,27 @@ def __init__( # set ansatz -- still supporting pre 0.18.0 sorting - self._ansatz = None + self._ansatz: Optional[QuantumCircuit] = None self.ansatz = ansatz self.k = k self.betas = betas - self._optimizer = None + self._optimizer: Optional[Optimizer] = None self.optimizer = optimizer - self._initial_point = None + self._initial_point: Optional[np.ndarray] = None self.initial_point = initial_point - self._gradient = None + self._gradient: Optional[Union[GradientBase, Callable]] = None self.gradient = gradient - self._quantum_instance = None + self._quantum_instance: Optional[QuantumInstance] = None if quantum_instance is not None: self.quantum_instance = quantum_instance self._eval_time = None self._eval_count = 0 - self._callback = None + self._callback: Optional[Callable[[int, np.ndarray, float, float], None]] = None self.callback = callback logger.info(self.print_settings()) @@ -643,7 +643,10 @@ def get_energy_evaluation( operator: OperatorBase, return_expectation: bool = False, prev_states: Optional[List[np.ndarray]] = None, - ) -> Callable[[np.ndarray], Union[float, List[float]]]: + ) -> Union[ + Callable[[np.ndarray], Union[float, List[float]]], + Tuple[Callable[[np.ndarray], Union[float, List[float]]], ExpectationBase], + ]: """Returns a function handle to evaluates the energy at given parameters for the ansatz. This return value is the objective function to be passed to the optimizer for evaluation. diff --git a/qiskit/algorithms/evolvers/evolution_problem.py b/qiskit/algorithms/evolvers/evolution_problem.py index b069effe1747..9879896006dc 100644 --- a/qiskit/algorithms/evolvers/evolution_problem.py +++ b/qiskit/algorithms/evolvers/evolution_problem.py @@ -12,7 +12,7 @@ """Evolution problem class.""" -from typing import Union, Optional, Dict +from typing import Union, Optional, Dict, Set from qiskit import QuantumCircuit from qiskit.circuit import Parameter @@ -92,7 +92,7 @@ def validate_params(self) -> None: t_param_set = set() if self.t_param is not None: t_param_set.add(self.t_param) - hamiltonian_dict_param_set = set() + hamiltonian_dict_param_set: Set[Parameter] = set() if self.hamiltonian_value_dict is not None: hamiltonian_dict_param_set = hamiltonian_dict_param_set.union( set(self.hamiltonian_value_dict.keys()) diff --git a/qiskit/algorithms/factorizers/shor.py b/qiskit/algorithms/factorizers/shor.py index 1030747ae89f..1b7c0786ad96 100644 --- a/qiskit/algorithms/factorizers/shor.py +++ b/qiskit/algorithms/factorizers/shor.py @@ -56,7 +56,7 @@ def __init__(self, quantum_instance: Optional[Union[QuantumInstance, Backend]] = quantum_instance: Quantum Instance or Backend """ - self._quantum_instance = None + self._quantum_instance: Optional[QuantumInstance] = None if quantum_instance: self.quantum_instance = quantum_instance @@ -484,7 +484,7 @@ class ShorResult(AlgorithmResult): def __init__(self) -> None: super().__init__() - self._factors = [] + self._factors: Optional[List[List[int]]] = [] self._total_counts = 0 self._successful_counts = 0 diff --git a/qiskit/algorithms/linear_solvers/hhl.py b/qiskit/algorithms/linear_solvers/hhl.py index 71b954148de2..b72f95d456f0 100644 --- a/qiskit/algorithms/linear_solvers/hhl.py +++ b/qiskit/algorithms/linear_solvers/hhl.py @@ -368,14 +368,14 @@ def construct_circuit( # Set the tolerance for the matrix approximation if hasattr(matrix_circuit, "tolerance"): - matrix_circuit.tolerance = self._epsilon_a + matrix_circuit.tolerance = self._epsilon_a # type: ignore[attr-defined] # check if the matrix can calculate the condition number and store the upper bound if ( hasattr(matrix_circuit, "condition_bounds") - and matrix_circuit.condition_bounds() is not None + and matrix_circuit.condition_bounds() is not None # type: ignore[attr-defined] ): - kappa = matrix_circuit.condition_bounds()[1] + kappa = matrix_circuit.condition_bounds()[1] # type: ignore[attr-defined] else: kappa = 1 # Update the number of qubits required to represent the eigenvalues @@ -384,8 +384,11 @@ def construct_circuit( nl = max(nb + 1, int(np.ceil(np.log2(kappa + 1)))) + neg_vals # check if the matrix can calculate bounds for the eigenvalues - if hasattr(matrix_circuit, "eigs_bounds") and matrix_circuit.eigs_bounds() is not None: - lambda_min, lambda_max = matrix_circuit.eigs_bounds() + if ( + hasattr(matrix_circuit, "eigs_bounds") + and matrix_circuit.eigs_bounds() is not None # type: ignore[attr-defined] + ): + lambda_min, lambda_max = matrix_circuit.eigs_bounds() # type: ignore[attr-defined] # Constant so that the minimum eigenvalue is represented exactly, since it contributes # the most to the solution of the system. -1 to take into account the sign qubit delta = self._get_delta(nl - neg_vals, lambda_min, lambda_max) diff --git a/qiskit/algorithms/linear_solvers/linear_solver.py b/qiskit/algorithms/linear_solvers/linear_solver.py index 093d8cd30e93..96e7f7c6b965 100644 --- a/qiskit/algorithms/linear_solvers/linear_solver.py +++ b/qiskit/algorithms/linear_solvers/linear_solver.py @@ -13,7 +13,7 @@ """An abstract class for linear systems solvers.""" from abc import ABC, abstractmethod -from typing import Union, Optional, List, Callable +from typing import Union, Optional, List, Callable, SupportsFloat import numpy as np from qiskit import QuantumCircuit @@ -35,10 +35,10 @@ def __init__(self) -> None: super().__init__() # Set the default to None, if the algorithm knows how to calculate it can override it. - self._state = None - self._observable = None - self._euclidean_norm = None - self._circuit_results = None + self._state: Optional[Union[QuantumCircuit, np.ndarray]] = None + self._observable: Optional[Union[float, List[float]]] = None + self._euclidean_norm: Optional[SupportsFloat] = None + self._circuit_results: Optional[Union[List[float], List[Result]]] = None @property def observable(self) -> Union[float, List[float]]: @@ -69,12 +69,12 @@ def state(self, state: Union[QuantumCircuit, np.ndarray]) -> None: self._state = state @property - def euclidean_norm(self) -> float: + def euclidean_norm(self) -> SupportsFloat: """return the euclidean norm if the algorithm knows how to calculate it""" return self._euclidean_norm @euclidean_norm.setter - def euclidean_norm(self, norm: float) -> None: + def euclidean_norm(self, norm: SupportsFloat) -> None: """Set the euclidean norm of the solution. Args: diff --git a/qiskit/algorithms/linear_solvers/matrices/linear_system_matrix.py b/qiskit/algorithms/linear_solvers/matrices/linear_system_matrix.py index 745fdca2b4f2..55c591d42945 100644 --- a/qiskit/algorithms/linear_solvers/matrices/linear_system_matrix.py +++ b/qiskit/algorithms/linear_solvers/matrices/linear_system_matrix.py @@ -13,7 +13,7 @@ """An abstract class for matrices input to the linear systems solvers in Qiskit.""" from abc import ABC, abstractmethod -from typing import Tuple +from typing import Tuple, Optional from qiskit import QuantumCircuit from qiskit.circuit.library import BlueprintCircuit @@ -39,9 +39,10 @@ def __init__( super().__init__(name=name) # define internal parameters - self._num_state_qubits = None - self._tolerance = None - self._evolution_time = None # makes sure the eigenvalues are contained in [0,1) + self._num_state_qubits: Optional[int] = None + self._tolerance: Optional[float] = None + # makes sure the eigenvalues are contained in [0,1) + self._evolution_time: Optional[float] = None # store parameters self.num_state_qubits = num_state_qubits diff --git a/qiskit/algorithms/linear_solvers/matrices/numpy_matrix.py b/qiskit/algorithms/linear_solvers/matrices/numpy_matrix.py index 1fc94893c6ab..20b3cc3c0eee 100644 --- a/qiskit/algorithms/linear_solvers/matrices/numpy_matrix.py +++ b/qiskit/algorithms/linear_solvers/matrices/numpy_matrix.py @@ -12,7 +12,7 @@ """Hamiltonian simulation of matrices given as numpy arrays.""" -from typing import Tuple +from typing import Tuple, Optional import numpy as np import scipy as sp @@ -60,9 +60,11 @@ def __init__( """ # define internal parameters - self._num_state_qubits = None - self._tolerance = None - self._evolution_time = None # makes sure the eigenvalues are contained in [0,1) + self._num_state_qubits: Optional[int] = None + self._tolerance: Optional[float] = None + self._evolution_time: Optional[ + float + ] = None # makes sure the eigenvalues are contained in [0,1) self._matrix = None super().__init__( @@ -210,5 +212,5 @@ def power(self, power: int, matrix_power: bool = False) -> QuantumCircuit: """ qc = QuantumCircuit(self.num_state_qubits) evolved = sp.linalg.expm(1j * self.matrix * self.evolution_time) - qc.unitary(evolved, qc.qubits) + qc.unitary(evolved, qc.qubits) # type: ignore[attr-defined] return qc.power(power) diff --git a/qiskit/algorithms/linear_solvers/matrices/tridiagonal_toeplitz.py b/qiskit/algorithms/linear_solvers/matrices/tridiagonal_toeplitz.py index 6dfbd0ad3c8a..8d6189e41f71 100644 --- a/qiskit/algorithms/linear_solvers/matrices/tridiagonal_toeplitz.py +++ b/qiskit/algorithms/linear_solvers/matrices/tridiagonal_toeplitz.py @@ -12,7 +12,7 @@ """Hamiltonian simulation of tridiagonal Toeplitz symmetric matrices.""" -from typing import Tuple +from typing import Tuple, Optional import numpy as np from scipy.sparse import diags @@ -77,11 +77,13 @@ def __init__( name: The name of the object. """ # define internal parameters - self._num_state_qubits = None + self._num_state_qubits: Optional[int] = None self._main_diag = None self._off_diag = None - self._tolerance = None - self._evolution_time = None # makes sure the eigenvalues are contained in [0,1) + self._tolerance: Optional[float] = None + self._evolution_time: Optional[ + float + ] = None # makes sure the eigenvalues are contained in [0,1) self._trotter_steps = None # store parameters @@ -299,7 +301,7 @@ def control(num_ctrl_qubits=1, label=None, ctrl_state=None): qc_control.p(theta, 0) return qc_control - qc.control = control + qc.control = control # type: ignore[assignment] return qc def _off_diag_circ(self, theta: float = 1) -> QuantumCircuit: @@ -397,7 +399,7 @@ def control(num_ctrl_qubits=1, label=None, ctrl_state=None): qc_control.cx(qr[i], qr[i + 1]) return qc_control - qc.control = control + qc.control = control # type: ignore[assignment] return qc def inverse(self): @@ -475,5 +477,5 @@ def control(num_ctrl_qubits=1, label=None, ctrl_state=None): ) return qc - qc_raw.control = control + qc_raw.control = control # type: ignore[assignment] return qc_raw diff --git a/qiskit/algorithms/linear_solvers/observables/absolute_average.py b/qiskit/algorithms/linear_solvers/observables/absolute_average.py index 9c9f644dd571..29f63b6b7409 100644 --- a/qiskit/algorithms/linear_solvers/observables/absolute_average.py +++ b/qiskit/algorithms/linear_solvers/observables/absolute_average.py @@ -108,7 +108,7 @@ def post_processing( return np.real(np.sqrt(solution / (2**num_qubits)) / scaling) - def evaluate_classically(self, solution: Union[np.array, QuantumCircuit]) -> float: + def evaluate_classically(self, solution: Union[np.ndarray, QuantumCircuit]) -> float: """Evaluates the given observable on the solution to the linear system. Args: diff --git a/qiskit/algorithms/linear_solvers/observables/linear_system_observable.py b/qiskit/algorithms/linear_solvers/observables/linear_system_observable.py index 048291d3d96d..2a369d82c13e 100644 --- a/qiskit/algorithms/linear_solvers/observables/linear_system_observable.py +++ b/qiskit/algorithms/linear_solvers/observables/linear_system_observable.py @@ -64,7 +64,7 @@ def post_processing( raise NotImplementedError @abstractmethod - def evaluate_classically(self, solution: Union[np.array, QuantumCircuit]) -> float: + def evaluate_classically(self, solution: Union[np.ndarray, QuantumCircuit]) -> float: """Calculates the analytical value of the given observable from the solution vector to the linear system. diff --git a/qiskit/algorithms/linear_solvers/observables/matrix_functional.py b/qiskit/algorithms/linear_solvers/observables/matrix_functional.py index 8611620377e2..bdfe0ccd77cf 100644 --- a/qiskit/algorithms/linear_solvers/observables/matrix_functional.py +++ b/qiskit/algorithms/linear_solvers/observables/matrix_functional.py @@ -151,13 +151,13 @@ def post_processing( raise ValueError("Solution probabilities must be given in list form.") # Calculate the value from the off-diagonal elements - off_val = 0 + off_val = 0.0 for i in range(1, len(solution), 2): off_val += (solution[i] - solution[i + 1]) / (scaling**2) main_val = solution[0] / (scaling**2) return np.real(self._main_diag * main_val + self._off_diag * off_val) - def evaluate_classically(self, solution: Union[np.array, QuantumCircuit]) -> float: + def evaluate_classically(self, solution: Union[np.ndarray, QuantumCircuit]) -> float: """Evaluates the given observable on the solution to the linear system. Args: diff --git a/qiskit/algorithms/minimum_eigen_solvers/minimum_eigen_solver.py b/qiskit/algorithms/minimum_eigen_solvers/minimum_eigen_solver.py index 7cdd245b7076..33a96c22dbf7 100644 --- a/qiskit/algorithms/minimum_eigen_solvers/minimum_eigen_solver.py +++ b/qiskit/algorithms/minimum_eigen_solvers/minimum_eigen_solver.py @@ -71,9 +71,9 @@ class MinimumEigensolverResult(AlgorithmResult): def __init__(self) -> None: super().__init__() - self._eigenvalue = None - self._eigenstate = None - self._aux_operator_eigenvalues = None + self._eigenvalue: Optional[complex] = None + self._eigenstate: Optional[np.ndarray] = None + self._aux_operator_eigenvalues: Optional[ListOrDict[Tuple[complex, complex]]] = None @property def eigenvalue(self) -> Optional[complex]: diff --git a/qiskit/algorithms/minimum_eigen_solvers/qaoa.py b/qiskit/algorithms/minimum_eigen_solvers/qaoa.py index d537f5a892e7..bb06b764f4cf 100644 --- a/qiskit/algorithms/minimum_eigen_solvers/qaoa.py +++ b/qiskit/algorithms/minimum_eigen_solvers/qaoa.py @@ -112,7 +112,7 @@ def __init__( self._reps = reps self._mixer = mixer self._initial_state = initial_state - self._cost_operator = None + self._cost_operator: Optional[OperatorBase] = None super().__init__( ansatz=None, @@ -127,6 +127,7 @@ def __init__( ) def _check_operator_ansatz(self, operator: OperatorBase) -> OperatorBase: + # TODO: should return something? # Recreates a circuit based on operator parameter. if operator != self._cost_operator: self._cost_operator = operator diff --git a/qiskit/algorithms/minimum_eigen_solvers/vqe.py b/qiskit/algorithms/minimum_eigen_solvers/vqe.py index 29d10b7be31e..777c6ec5ee3e 100755 --- a/qiskit/algorithms/minimum_eigen_solvers/vqe.py +++ b/qiskit/algorithms/minimum_eigen_solvers/vqe.py @@ -179,30 +179,30 @@ def __init__( self.expectation = expectation self._include_custom = include_custom - self._ansatz = None + self._ansatz: Optional[QuantumCircuit] = None self.ansatz = ansatz - self._optimizer = None + self._optimizer: Optional[Optimizer] = None self.optimizer = optimizer - self._initial_point = None + self._initial_point: Optional[np.ndarray] = None self.initial_point = initial_point - self._gradient = None + self._gradient: Optional[Union[GradientBase, Callable]] = None self.gradient = gradient - self._quantum_instance = None + self._quantum_instance: Optional[QuantumInstance] = None if quantum_instance is not None: self.quantum_instance = quantum_instance self._eval_time = None self._eval_count = 0 - self._callback = None + self._callback: Optional[Callable[[int, np.ndarray, float, float], None]] = None self.callback = callback logger.info(self.print_settings()) # TODO remove this once the stateful methods are deleted - self._ret = None + self._ret: Optional[VQEResult] = None @property def ansatz(self) -> QuantumCircuit: @@ -566,7 +566,10 @@ def get_energy_evaluation( self, operator: OperatorBase, return_expectation: bool = False, - ) -> Callable[[np.ndarray], Union[float, List[float]]]: + ) -> Union[ + Callable[[np.ndarray], Union[float, List[float]]], + Tuple[Callable[[np.ndarray], Union[float, List[float]]], ExpectationBase], + ]: """Returns a function handle to evaluates the energy at given parameters for the ansatz. This is the objective function to be passed to the optimizer that is used for evaluation. @@ -645,7 +648,7 @@ class VQEResult(VariationalResult, MinimumEigensolverResult): def __init__(self) -> None: super().__init__() - self._cost_function_evals = None + self._cost_function_evals: Optional[int] = None @property def cost_function_evals(self) -> Optional[int]: diff --git a/qiskit/algorithms/optimizers/aqgd.py b/qiskit/algorithms/optimizers/aqgd.py index 5ffb0f849599..36affa5e68c1 100644 --- a/qiskit/algorithms/optimizers/aqgd.py +++ b/qiskit/algorithms/optimizers/aqgd.py @@ -98,7 +98,7 @@ def __init__( # state self._avg_objval = None - self._prev_param = None + self._prev_param: Optional[np.ndarray] = None self._eval_count = 0 # function evaluations self._prev_loss = [] # type: List[float] self._prev_grad = [] # type: List[List[float]] @@ -128,8 +128,8 @@ def settings(self) -> Dict[str, Any]: } def _compute_objective_fn_and_gradient( - self, params: List[float], obj: Callable - ) -> Tuple[float, np.array]: + self, params: Union[np.ndarray, List[float]], obj: Callable + ) -> Tuple[float, np.ndarray]: """ Obtains the objective function value for params and the analytical quantum derivatives of the objective function with respect to each parameter. Requires @@ -172,7 +172,7 @@ def _update( mprev: np.ndarray, step_size: float, momentum_coeff: float, - ) -> Tuple[List[float], List[float]]: + ) -> Tuple[np.ndarray, np.ndarray]: """ Updates full parameter array based on a step that is a convex combination of the gradient and previous momentum @@ -232,7 +232,7 @@ def _converged_objective(self, objval: float, tol: float, window_size: int) -> b return True return False - def _converged_parameter(self, parameter: List[float], tol: float) -> bool: + def _converged_parameter(self, parameter: np.ndarray, tol: float) -> bool: """ Tests convergence based on change in parameter diff --git a/qiskit/algorithms/optimizers/gradient_descent.py b/qiskit/algorithms/optimizers/gradient_descent.py index 5ca2e0f8cad8..4a069c87671d 100644 --- a/qiskit/algorithms/optimizers/gradient_descent.py +++ b/qiskit/algorithms/optimizers/gradient_descent.py @@ -12,14 +12,14 @@ """A standard gradient descent optimizer.""" -from typing import Iterator, Optional, Union, Callable, Dict, Any, List, Tuple +from typing import Iterator, Optional, Union, Callable, Dict, Any, List, Tuple, SupportsFloat from functools import partial import numpy as np from .optimizer import Optimizer, OptimizerSupportLevel, OptimizerResult, POINT -CALLBACK = Callable[[int, np.ndarray, float, float], None] +CALLBACK = Callable[[int, np.ndarray, float, SupportsFloat], None] class GradientDescent(Optimizer): @@ -137,7 +137,9 @@ def settings(self) -> Dict[str, Any]: # if learning rate or perturbation are custom iterators expand them if callable(self.learning_rate): iterator = self.learning_rate() - learning_rate = np.array([next(iterator) for _ in range(self.maxiter)]) + learning_rate: Union[float, np.ndarray] = np.array( + [next(iterator) for _ in range(self.maxiter)] + ) else: learning_rate = self.learning_rate diff --git a/qiskit/algorithms/optimizers/gsls.py b/qiskit/algorithms/optimizers/gsls.py index 2649037f4170..56ee4cc0b077 100644 --- a/qiskit/algorithms/optimizers/gsls.py +++ b/qiskit/algorithms/optimizers/gsls.py @@ -12,7 +12,7 @@ """Line search with Gaussian-smoothed samples on a sphere.""" -from typing import Dict, Optional, Tuple, List, Callable, Any +from typing import Dict, Optional, Tuple, List, Callable, Any, SupportsFloat import numpy as np from qiskit.utils import algorithm_globals @@ -169,7 +169,7 @@ def ls_optimize( prev_directions, prev_sample_set_x, prev_sample_set_y = None, None, None consecutive_fail_iter = 0 alpha = self._options["initial_step_size"] - grad_norm = np.inf + grad_norm: SupportsFloat = np.inf sample_set_size = int(round(self._options["sample_size_factor"] * n)) # Initial point diff --git a/qiskit/algorithms/optimizers/l_bfgs_b.py b/qiskit/algorithms/optimizers/l_bfgs_b.py index d017d08e1d77..4d97e402b3b8 100644 --- a/qiskit/algorithms/optimizers/l_bfgs_b.py +++ b/qiskit/algorithms/optimizers/l_bfgs_b.py @@ -13,7 +13,7 @@ """Limited-memory BFGS Bound optimizer.""" import warnings -from typing import Optional +from typing import Optional, SupportsFloat import numpy as np @@ -54,7 +54,7 @@ def __init__( self, maxfun: int = 1000, maxiter: int = 15000, - ftol: float = 10 * np.finfo(float).eps, + ftol: SupportsFloat = 10 * np.finfo(float).eps, factr: Optional[float] = None, iprint: int = -1, epsilon: float = 1e-08, diff --git a/qiskit/algorithms/optimizers/optimizer.py b/qiskit/algorithms/optimizers/optimizer.py index b8acefbf9d2c..eaa4e3ed80d9 100644 --- a/qiskit/algorithms/optimizers/optimizer.py +++ b/qiskit/algorithms/optimizers/optimizer.py @@ -41,12 +41,12 @@ class OptimizerResult(AlgorithmResult): def __init__(self) -> None: super().__init__() - self._x = None # pylint: disable=invalid-name - self._fun = None - self._jac = None - self._nfev = None - self._njev = None - self._nit = None + self._x: Optional[POINT] = None # pylint: disable=invalid-name + self._fun: Optional[float] = None + self._jac: Optional[POINT] = None + self._nfev: Optional[int] = None + self._njev: Optional[int] = None + self._nit: Optional[int] = None @property def x(self) -> Optional[POINT]: diff --git a/qiskit/algorithms/optimizers/p_bfgs.py b/qiskit/algorithms/optimizers/p_bfgs.py index e3aa811a4184..e0129cfe1c1c 100644 --- a/qiskit/algorithms/optimizers/p_bfgs.py +++ b/qiskit/algorithms/optimizers/p_bfgs.py @@ -16,7 +16,7 @@ import multiprocessing import platform import sys -from typing import Optional, List, Tuple, Callable +from typing import Optional, List, Tuple, Callable, SupportsFloat import numpy as np @@ -49,7 +49,7 @@ class P_BFGS(SciPyOptimizer): # pylint: disable=invalid-name def __init__( self, maxfun: int = 1000, - ftol: float = 10 * np.finfo(float).eps, + ftol: SupportsFloat = 10 * np.finfo(float).eps, iprint: int = -1, max_processes: Optional[int] = None, options: Optional[dict] = None, diff --git a/qiskit/algorithms/optimizers/spsa.py b/qiskit/algorithms/optimizers/spsa.py index 6634c98dfdcb..ee82512a4758 100644 --- a/qiskit/algorithms/optimizers/spsa.py +++ b/qiskit/algorithms/optimizers/spsa.py @@ -15,7 +15,7 @@ This implementation allows both, standard first-order as well as second-order SPSA. """ -from typing import Iterator, Optional, Union, Callable, Tuple, Dict, List, Any +from typing import Iterator, Optional, Union, Callable, Tuple, Dict, List, Any, SupportsFloat import logging import warnings from time import time @@ -30,8 +30,8 @@ from .optimizer import Optimizer, OptimizerSupportLevel, OptimizerResult, POINT # number of function evaluations, parameters, loss, stepsize, accepted -CALLBACK = Callable[[int, np.ndarray, float, float, bool], None] -TERMINATIONCHECKER = Callable[[int, np.ndarray, float, float, bool], bool] +CALLBACK = Callable[[int, np.ndarray, float, SupportsFloat, bool], None] +TERMINATIONCHECKER = Callable[[int, np.ndarray, float, SupportsFloat, bool], bool] logger = logging.getLogger(__name__) @@ -133,8 +133,8 @@ def __init__( blocking: bool = False, allowed_increase: Optional[float] = None, trust_region: bool = False, - learning_rate: Optional[Union[float, np.array, Callable[[], Iterator]]] = None, - perturbation: Optional[Union[float, np.array, Callable[[], Iterator]]] = None, + learning_rate: Optional[Union[float, np.ndarray, Callable[[], Iterator]]] = None, + perturbation: Optional[Union[float, np.ndarray, Callable[[], Iterator]]] = None, last_avg: int = 1, resamplings: Union[int, Dict[int, int]] = 1, perturbation_dims: Optional[int] = None, @@ -275,8 +275,8 @@ def __call__(self, nfev, parameters, value, stepsize, accepted) -> bool: self.initial_hessian = initial_hessian # runtime arguments - self._nfev = None # the number of function evaluations - self._smoothed_hessian = None # smoothed average of the Hessians + self._nfev: Optional[int] = None # the number of function evaluations + self._smoothed_hessian: Optional[np.ndarray] = None # smoothed average of the Hessians @staticmethod def calibrate( @@ -289,7 +289,7 @@ def calibrate( gamma: float = 0.101, modelspace: bool = False, max_evals_grouped: int = 1, - ) -> Tuple[Iterator[float], Iterator[float]]: + ) -> Tuple[Callable, Callable]: r"""Calibrate SPSA parameters with a powerseries as learning rate and perturbation coeffs. The powerseries are: @@ -332,7 +332,7 @@ def calibrate( losses = _batch_evaluate(loss, points, max_evals_grouped) - avg_magnitudes = 0 + avg_magnitudes = 0.0 for i in range(steps): delta = losses[2 * i] - losses[2 * i + 1] avg_magnitudes += np.abs(delta / (2 * c)) diff --git a/qiskit/algorithms/optimizers/umda.py b/qiskit/algorithms/optimizers/umda.py index b93df1b86e4f..ef65dbbcd0ef 100644 --- a/qiskit/algorithms/optimizers/umda.py +++ b/qiskit/algorithms/optimizers/umda.py @@ -131,22 +131,22 @@ def __init__(self, maxiter: int = 100, size_gen: int = 20, alpha: float = 0.5) - self.size_gen = size_gen self.maxiter = maxiter self.alpha = alpha - self._vector = None + self._vector: Optional[np.ndarray] = None # initialization of generation - self._generation = None + self._generation: Optional[np.ndarray] = None self._dead_iter = int(self._maxiter / 5) self._truncation_length = int(size_gen * alpha) super().__init__() - self._best_cost_global = None - self._best_ind_global = None - self._evaluations = None + self._best_cost_global: Optional[float] = None + self._best_ind_global: Optional[int] = None + self._evaluations: Optional[np.ndarray] = None - self._n_variables = None + self._n_variables: Optional[int] = None - def _initialization(self): + def _initialization(self) -> np.ndarray: vector = np.zeros((4, self._n_variables)) vector[0, :] = np.pi # mu @@ -203,7 +203,7 @@ def minimize( not_better_count = 0 result = OptimizerResult() - self._n_variables = len(x0) + self._n_variables = len(x0) # TODO: what if x0 is float? self._best_cost_global = 999999999999 self._best_ind_global = 9999999 history = [] @@ -221,7 +221,7 @@ def minimize( self._truncation() self._update_vector() - best_mae_local = min(self._evaluations) + best_mae_local: float = min(self._evaluations) history.append(best_mae_local) best_ind_local = np.where(self._evaluations == best_mae_local)[0][0] diff --git a/qiskit/algorithms/phase_estimators/hamiltonian_phase_estimation.py b/qiskit/algorithms/phase_estimators/hamiltonian_phase_estimation.py index d84d262249a6..536b42792e31 100644 --- a/qiskit/algorithms/phase_estimators/hamiltonian_phase_estimation.py +++ b/qiskit/algorithms/phase_estimators/hamiltonian_phase_estimation.py @@ -100,7 +100,7 @@ def __init__( num_evaluation_qubits=num_evaluation_qubits, quantum_instance=quantum_instance ) - def _get_scale(self, hamiltonian, bound=None) -> None: + def _get_scale(self, hamiltonian, bound=None) -> PhaseEstimationScale: if bound is None: return PhaseEstimationScale.from_pauli_sum(hamiltonian) diff --git a/qiskit/algorithms/phase_estimators/phase_estimation_result.py b/qiskit/algorithms/phase_estimators/phase_estimation_result.py index d9606fe03f65..d66811ab2e1c 100644 --- a/qiskit/algorithms/phase_estimators/phase_estimation_result.py +++ b/qiskit/algorithms/phase_estimators/phase_estimation_result.py @@ -67,7 +67,7 @@ def circuit_result(self) -> Result: """ return self._circuit_result - @property + @property # type: ignore @deprecate_function( """The 'PhaseEstimationResult.most_likely_phase' attribute is deprecated as of 0.18.0 and will be removed no earlier than 3 months diff --git a/qiskit/algorithms/phase_estimators/phase_estimator.py b/qiskit/algorithms/phase_estimators/phase_estimator.py index 3ea7618b5046..fa8cb1bf3d64 100644 --- a/qiskit/algorithms/phase_estimators/phase_estimator.py +++ b/qiskit/algorithms/phase_estimators/phase_estimator.py @@ -44,7 +44,7 @@ def estimate( class PhaseEstimatorResult(AlgorithmResult): """Phase Estimator Result.""" - @property + @property # type: ignore @abstractmethod def phase(self) -> float: r"""Return the estimated phase as a number in :math:`[0.0, 1.0)`. diff --git a/qiskit/algorithms/variational_algorithm.py b/qiskit/algorithms/variational_algorithm.py index 92d8976ffc9f..38c14824ac35 100644 --- a/qiskit/algorithms/variational_algorithm.py +++ b/qiskit/algorithms/variational_algorithm.py @@ -36,13 +36,13 @@ class VariationalAlgorithm(ABC): """The Variational Algorithm Base Class.""" - @property + @property # type: ignore @abstractmethod def initial_point(self) -> Optional[np.ndarray]: """Returns initial point.""" pass - @initial_point.setter + @initial_point.setter # type: ignore @abstractmethod def initial_point(self, initial_point: Optional[np.ndarray]) -> None: """Sets initial point.""" @@ -54,11 +54,11 @@ class VariationalResult(AlgorithmResult): def __init__(self) -> None: super().__init__() - self._optimizer_evals = None - self._optimizer_time = None - self._optimal_value = None - self._optimal_point = None - self._optimal_parameters = None + self._optimizer_evals: Optional[int] = None + self._optimizer_time: Optional[float] = None + self._optimal_value: Optional[float] = None + self._optimal_point: Optional[np.ndarray] = None + self._optimal_parameters: Optional[Dict] = None @property def optimizer_evals(self) -> Optional[int]: diff --git a/qiskit/assembler/assemble_circuits.py b/qiskit/assembler/assemble_circuits.py index bf2261453147..85bd4b662604 100644 --- a/qiskit/assembler/assemble_circuits.py +++ b/qiskit/assembler/assemble_circuits.py @@ -188,7 +188,7 @@ def _assemble_pulse_gates( if not hasattr(run_config, "parametric_pulses"): run_config.parametric_pulses = [] calibrations = [] - pulse_library = {} + pulse_library: Dict[str, List[complex]] = {} for gate, cals in circuit.calibrations.items(): for (qubits, params), schedule in cals.items(): qobj_instructions, _ = _assemble_schedule( diff --git a/qiskit/assembler/assemble_schedules.py b/qiskit/assembler/assemble_schedules.py index 7987c92d3f73..ee0e9bddaea2 100644 --- a/qiskit/assembler/assemble_schedules.py +++ b/qiskit/assembler/assemble_schedules.py @@ -103,7 +103,7 @@ def _assemble_experiments( formatted_schedules = [transforms.target_qobj_transform(sched) for sched in schedules] compressed_schedules = transforms.compress_pulses(formatted_schedules) - user_pulselib = {} + user_pulselib: Dict[str, List[complex]] = {} experiments = [] for idx, sched in enumerate(compressed_schedules): qobj_instructions, max_memory_slot = _assemble_instructions( diff --git a/qiskit/circuit/controlflow/control_flow.py b/qiskit/circuit/controlflow/control_flow.py index f33077bd1f1d..64fb7b3365fb 100644 --- a/qiskit/circuit/controlflow/control_flow.py +++ b/qiskit/circuit/controlflow/control_flow.py @@ -21,7 +21,7 @@ class ControlFlowOp(Instruction, ABC): """Abstract class to encapsulate all control flow operations.""" - @property + @property # type: ignore @abstractmethod def blocks(self) -> Tuple[QuantumCircuit, ...]: """Tuple of QuantumCircuits which may be executed as part of the diff --git a/qiskit/circuit/controlledgate.py b/qiskit/circuit/controlledgate.py index 6ab1c3a414b5..03cac3d3101d 100644 --- a/qiskit/circuit/controlledgate.py +++ b/qiskit/circuit/controlledgate.py @@ -97,7 +97,7 @@ def __init__( self.num_ctrl_qubits = num_ctrl_qubits self.definition = copy.deepcopy(definition) self._ctrl_state = None - self.ctrl_state = ctrl_state + self.ctrl_state: Optional[Union[int, str]] = ctrl_state self._name = name @property diff --git a/qiskit/circuit/gate.py b/qiskit/circuit/gate.py index b271aa161c82..83195adf96ef 100644 --- a/qiskit/circuit/gate.py +++ b/qiskit/circuit/gate.py @@ -12,7 +12,7 @@ """Unitary gate.""" -from typing import List, Optional, Union, Tuple +from typing import List, Optional, Union, Tuple, Any, Iterator import numpy as np from qiskit.circuit.parameterexpression import ParameterExpression @@ -52,7 +52,7 @@ def to_matrix(self) -> np.ndarray: """ if hasattr(self, "__array__"): # pylint: disable=no-member - return self.__array__(dtype=complex) + return self.__array__(dtype=complex) # type: ignore[attr-defined] raise CircuitError(f"to_matrix not defined for this {type(self)}") def power(self, exponent: float): @@ -118,7 +118,7 @@ def control( return add_control(self, num_ctrl_qubits, label, ctrl_state) @staticmethod - def _broadcast_single_argument(qarg: List) -> List: + def _broadcast_single_argument(qarg: List) -> Iterator[Tuple[List[Any], List[Any]]]: """Expands a single argument. For example: [q[0], q[1]] -> [q[0]], [q[1]] @@ -129,7 +129,7 @@ def _broadcast_single_argument(qarg: List) -> List: yield [arg0], [] @staticmethod - def _broadcast_2_arguments(qarg0: List, qarg1: List) -> List: + def _broadcast_2_arguments(qarg0: List, qarg1: List) -> Iterator[Tuple[List[Any], List[Any]]]: if len(qarg0) == len(qarg1): # [[q[0], q[1]], [r[0], r[1]]] -> [q[0], r[0]] # -> [q[1], r[1]] @@ -151,7 +151,7 @@ def _broadcast_2_arguments(qarg0: List, qarg1: List) -> List: ) @staticmethod - def _broadcast_3_or_more_args(qargs: List) -> List: + def _broadcast_3_or_more_args(qargs: List) -> Iterator[Tuple[List[Any], List[Any]]]: if all(len(qarg) == len(qargs[0]) for qarg in qargs): for arg in zip(*qargs): yield list(arg), [] diff --git a/qiskit/circuit/instructionset.py b/qiskit/circuit/instructionset.py index c15161229b9f..aab0dc97dc53 100644 --- a/qiskit/circuit/instructionset.py +++ b/qiskit/circuit/instructionset.py @@ -16,7 +16,7 @@ import functools import warnings -from typing import Callable, Optional, Tuple, Union +from typing import Callable, Optional, Tuple, Union, List from qiskit.circuit.exceptions import CircuitError from .instruction import Instruction @@ -124,7 +124,7 @@ def __init__(self, circuit_cregs=None, *, resource_requester: Optional[Callable] CircuitError: if both ``resource_requester`` and ``circuit_cregs`` are passed. Only one of these may be passed, and it should be ``resource_requester``. """ - self._instructions = [] + self._instructions: List[CircuitInstruction] = [] if circuit_cregs is not None: if resource_requester is not None: raise CircuitError("Cannot pass both 'circuit_cregs' and 'resource_requester'.") diff --git a/qiskit/circuit/library/arithmetic/piecewise_chebyshev.py b/qiskit/circuit/library/arithmetic/piecewise_chebyshev.py index 27bd25ec6cef..dfd80c9a4b48 100644 --- a/qiskit/circuit/library/arithmetic/piecewise_chebyshev.py +++ b/qiskit/circuit/library/arithmetic/piecewise_chebyshev.py @@ -82,7 +82,7 @@ def __init__( self._degree = degree if degree is not None else 1 self._breakpoints = breakpoints if breakpoints is not None else [0] - self._polynomials = None + self._polynomials: Optional[List[List[float]]] = None self.num_state_qubits = num_state_qubits diff --git a/qiskit/circuit/library/arithmetic/piecewise_linear_pauli_rotations.py b/qiskit/circuit/library/arithmetic/piecewise_linear_pauli_rotations.py index d9c7f622e9b0..98a70f6fe22b 100644 --- a/qiskit/circuit/library/arithmetic/piecewise_linear_pauli_rotations.py +++ b/qiskit/circuit/library/arithmetic/piecewise_linear_pauli_rotations.py @@ -13,7 +13,7 @@ """Piecewise-linearly-controlled rotation.""" -from typing import List, Optional +from typing import List, Optional, Union import numpy as np from qiskit.circuit import QuantumRegister, AncillaRegister, QuantumCircuit @@ -48,8 +48,8 @@ def __init__( self, num_state_qubits: Optional[int] = None, breakpoints: Optional[List[int]] = None, - slopes: Optional[List[float]] = None, - offsets: Optional[List[float]] = None, + slopes: Optional[Union[List[float], np.ndarray]] = None, + offsets: Optional[Union[List[float], np.ndarray]] = None, basis: str = "Y", name: str = "pw_lin", ) -> None: @@ -96,7 +96,7 @@ def breakpoints(self, breakpoints: List[int]) -> None: self._reset_registers(self.num_state_qubits) @property - def slopes(self) -> List[int]: + def slopes(self) -> List[float]: """The breakpoints of the piecewise linear function. The function is linear in the intervals ``[point_i, point_{i+1}]`` where the last @@ -134,7 +134,7 @@ def offsets(self, offsets: List[float]) -> None: self._offsets = offsets @property - def mapped_slopes(self) -> List[float]: + def mapped_slopes(self) -> np.ndarray: """The slopes mapped to the internal representation. Returns: @@ -147,7 +147,7 @@ def mapped_slopes(self) -> List[float]: return mapped_slopes @property - def mapped_offsets(self) -> List[float]: + def mapped_offsets(self) -> np.ndarray: """The offsets mapped to the internal representation. Returns: diff --git a/qiskit/circuit/library/arithmetic/polynomial_pauli_rotations.py b/qiskit/circuit/library/arithmetic/polynomial_pauli_rotations.py index b38c1e282f64..8c1be2b3e39e 100644 --- a/qiskit/circuit/library/arithmetic/polynomial_pauli_rotations.py +++ b/qiskit/circuit/library/arithmetic/polynomial_pauli_rotations.py @@ -14,7 +14,7 @@ """Polynomially controlled Pauli-rotations.""" import warnings -from typing import List, Optional, Dict, Sequence +from typing import List, Optional, Dict, Tuple from itertools import product @@ -255,7 +255,7 @@ def _check_configuration(self, raise_on_failure: bool = True) -> bool: return valid - def _get_rotation_coefficients(self) -> Dict[Sequence[int], float]: + def _get_rotation_coefficients(self) -> Dict[Tuple[int, ...], float]: """Compute the coefficient of each monomial. Returns: @@ -269,7 +269,7 @@ def _get_rotation_coefficients(self) -> Dict[Sequence[int], float]: if 0 < sum(combination) <= self.degree: valid_combinations += [combination] - rotation_coeffs = {control_state: 0 for control_state in valid_combinations} + rotation_coeffs = {control_state: 0.0 for control_state in valid_combinations} # compute the coefficients for the control states for i, coeff in enumerate(self.coeffs[1:]): @@ -277,7 +277,7 @@ def _get_rotation_coefficients(self) -> Dict[Sequence[int], float]: # iterate over the multinomial coefficients for comb, num_combs in _multinomial_coefficients(self.num_state_qubits, i).items(): - control_state = () + control_state: Tuple[int, ...] = () power = 1 for j, qubit in enumerate(comb): if qubit > 0: # means we control on qubit i diff --git a/qiskit/circuit/library/arithmetic/quadratic_form.py b/qiskit/circuit/library/arithmetic/quadratic_form.py index 36f226d6dcfb..bd0bca1664a3 100644 --- a/qiskit/circuit/library/arithmetic/quadratic_form.py +++ b/qiskit/circuit/library/arithmetic/quadratic_form.py @@ -182,7 +182,7 @@ def required_result_qubits( bounds = [] # bounds = [minimum value, maximum value] for condition in [lambda x: x < 0, lambda x: x > 0]: - bound = 0 + bound = 0.0 bound += sum(sum(q_ij for q_ij in q_i if condition(q_ij)) for q_i in quadratic) bound += sum(l_i for l_i in linear if condition(l_i)) bound += offset if condition(offset) else 0 diff --git a/qiskit/circuit/library/blueprintcircuit.py b/qiskit/circuit/library/blueprintcircuit.py index da2d6348c720..1eb086f91270 100644 --- a/qiskit/circuit/library/blueprintcircuit.py +++ b/qiskit/circuit/library/blueprintcircuit.py @@ -12,9 +12,10 @@ """Blueprint circuit object.""" -from typing import Optional +from typing import Optional, List from abc import ABC, abstractmethod -from qiskit.circuit import QuantumCircuit + +from qiskit.circuit import QuantumCircuit, QuantumRegister, ClassicalRegister from qiskit.circuit.parametertable import ParameterTable, ParameterView @@ -32,8 +33,8 @@ class BlueprintCircuit(QuantumCircuit, ABC): def __init__(self, *regs, name: Optional[str] = None) -> None: """Create a new blueprint circuit.""" super().__init__(*regs, name=name) - self._qregs = [] - self._cregs = [] + self._qregs: List[QuantumRegister] = [] + self._cregs: List[ClassicalRegister] = [] self._qubits = [] self._qubit_indices = {} self._is_built = False diff --git a/qiskit/circuit/library/generalized_gates/diagonal.py b/qiskit/circuit/library/generalized_gates/diagonal.py index 99e5662230af..929a83be65ec 100644 --- a/qiskit/circuit/library/generalized_gates/diagonal.py +++ b/qiskit/circuit/library/generalized_gates/diagonal.py @@ -73,7 +73,7 @@ class Diagonal(QuantumCircuit): `arXiv:0406176 `_ """ - def __init__(self, diag: Union[List, np.array]) -> None: + def __init__(self, diag: Union[List, np.ndarray]) -> None: """Create a new Diagonal circuit. Args: diff --git a/qiskit/circuit/library/generalized_gates/mcmt.py b/qiskit/circuit/library/generalized_gates/mcmt.py index 6907ac31c521..754f23443d95 100644 --- a/qiskit/circuit/library/generalized_gates/mcmt.py +++ b/qiskit/circuit/library/generalized_gates/mcmt.py @@ -282,6 +282,7 @@ def _ccx_v_chain_rule( Raises: QiskitError: If an insufficient number of ancilla qubits was provided. """ + # TODO: should it actually return anyting? if len(ancilla_qubits) == 0: return diff --git a/qiskit/circuit/library/generalized_gates/permutation.py b/qiskit/circuit/library/generalized_gates/permutation.py index 042ebee2635b..83e2639b1acc 100644 --- a/qiskit/circuit/library/generalized_gates/permutation.py +++ b/qiskit/circuit/library/generalized_gates/permutation.py @@ -12,7 +12,7 @@ """Permutation circuit.""" -from typing import List, Optional +from typing import List, Optional, Union import numpy as np @@ -26,7 +26,7 @@ class Permutation(QuantumCircuit): def __init__( self, num_qubits: int, - pattern: Optional[List[int]] = None, + pattern: Optional[Union[List[int], np.ndarray]] = None, seed: Optional[int] = None, ) -> None: """Return an n_qubit permutation circuit implemented using SWAPs. diff --git a/qiskit/circuit/library/graph_state.py b/qiskit/circuit/library/graph_state.py index f811bea83f73..d15441ccef39 100644 --- a/qiskit/circuit/library/graph_state.py +++ b/qiskit/circuit/library/graph_state.py @@ -57,7 +57,7 @@ class GraphState(QuantumCircuit): `arXiv:1512.07892 `_ """ - def __init__(self, adjacency_matrix: Union[List, np.array]) -> None: + def __init__(self, adjacency_matrix: Union[List, np.ndarray]) -> None: """Create graph state preparation circuit. Args: diff --git a/qiskit/circuit/library/iqp.py b/qiskit/circuit/library/iqp.py index 95215c613dfa..1d5047c4e779 100644 --- a/qiskit/circuit/library/iqp.py +++ b/qiskit/circuit/library/iqp.py @@ -63,7 +63,7 @@ class IQP(QuantumCircuit): `arXiv:1504.07999 `_ """ - def __init__(self, interactions: Union[List, np.array]) -> None: + def __init__(self, interactions: Union[List, np.ndarray]) -> None: """Create IQP circuit. Args: diff --git a/qiskit/circuit/library/n_local/n_local.py b/qiskit/circuit/library/n_local/n_local.py index 64217fa0221c..e798ef18d252 100644 --- a/qiskit/circuit/library/n_local/n_local.py +++ b/qiskit/circuit/library/n_local/n_local.py @@ -12,7 +12,7 @@ """The n-local circuit class.""" -from typing import Union, Optional, List, Any, Tuple, Sequence, Set, Callable +from typing import Union, Optional, List, Any, Tuple, Sequence, Set, Callable, Mapping from itertools import combinations import warnings @@ -119,12 +119,12 @@ def __init__( self._num_qubits = None self._insert_barriers = insert_barriers self._reps = reps - self._entanglement_blocks = [] - self._rotation_blocks = [] - self._prepended_blocks = [] - self._prepended_entanglement = [] - self._appended_blocks = [] - self._appended_entanglement = [] + self._entanglement_blocks: List[Instruction] = [] + self._rotation_blocks: List[Instruction] = [] + self._prepended_blocks: List[QuantumCircuit] = [] + self._prepended_entanglement: List[List[int]] = [] + self._appended_blocks: List[QuantumCircuit] = [] + self._appended_entanglement: List[List[int]] = [] self._entanglement = None self._entangler_maps = None self._ordered_parameters = ParameterVector(name=parameter_prefix) @@ -784,7 +784,10 @@ def add_layer( def assign_parameters( self, - parameters: Union[dict, List[float], List[Parameter], ParameterVector], + parameters: Union[ + Mapping[Parameter, Union[ParameterExpression, float]], + Sequence[Union[ParameterExpression, float]], + ], inplace: bool = False, ) -> Optional[QuantumCircuit]: """Assign parameters to the n-local circuit. @@ -982,7 +985,7 @@ def get_parameters(block: Union[QuantumCircuit, Instruction]) -> List[Parameter] def get_entangler_map( num_block_qubits: int, num_circuit_qubits: int, entanglement: str, offset: int = 0 -) -> List[Sequence[int]]: +) -> List[Tuple[int, ...]]: """Get an entangler map for an arbitrary number of qubits. Args: diff --git a/qiskit/circuit/library/n_local/pauli_two_design.py b/qiskit/circuit/library/n_local/pauli_two_design.py index 77bb94916fd9..a02f5c8f409d 100644 --- a/qiskit/circuit/library/n_local/pauli_two_design.py +++ b/qiskit/circuit/library/n_local/pauli_two_design.py @@ -12,7 +12,7 @@ """The Random Pauli circuit class.""" -from typing import Optional +from typing import Optional, List, Dict import numpy as np from qiskit.circuit import QuantumCircuit @@ -81,7 +81,7 @@ def __init__( self._rng = np.random.default_rng(seed) # store a dict to keep track of the random gates - self._gates = {} + self._gates: Dict[int, List[str]] = {} super().__init__( num_qubits, diff --git a/qiskit/circuit/library/n_local/qaoa_ansatz.py b/qiskit/circuit/library/n_local/qaoa_ansatz.py index cc6d531f6663..4808b94bfd93 100644 --- a/qiskit/circuit/library/n_local/qaoa_ansatz.py +++ b/qiskit/circuit/library/n_local/qaoa_ansatz.py @@ -59,11 +59,11 @@ def __init__( self._cost_operator = None self._reps = reps - self._initial_state = initial_state + self._initial_state: Optional[QuantumCircuit] = initial_state self._mixer = mixer_operator # set this circuit as a not-built circuit - self._bounds = None + self._bounds: Optional[List[Tuple[Optional[float], Optional[float]]]] = None # store cost operator and set the registers if the operator is not None self.cost_operator = cost_operator diff --git a/qiskit/circuit/library/standard_gates/multi_control_rotation_gates.py b/qiskit/circuit/library/standard_gates/multi_control_rotation_gates.py index 1e420185176e..ab70f27ba989 100644 --- a/qiskit/circuit/library/standard_gates/multi_control_rotation_gates.py +++ b/qiskit/circuit/library/standard_gates/multi_control_rotation_gates.py @@ -239,6 +239,6 @@ def mcrz( ) -QuantumCircuit.mcrx = mcrx -QuantumCircuit.mcry = mcry -QuantumCircuit.mcrz = mcrz +QuantumCircuit.mcrx = mcrx # type: ignore[attr-defined] +QuantumCircuit.mcry = mcry # type: ignore[attr-defined] +QuantumCircuit.mcrz = mcrz # type: ignore[attr-defined] diff --git a/qiskit/circuit/library/standard_gates/x.py b/qiskit/circuit/library/standard_gates/x.py index c3d050bee5e2..4945f6ff8b0e 100644 --- a/qiskit/circuit/library/standard_gates/x.py +++ b/qiskit/circuit/library/standard_gates/x.py @@ -12,7 +12,7 @@ """X, CX, CCX and multi-controlled X gates.""" -from typing import Optional, Union +from typing import Optional, Union, Dict, Type from math import ceil import numpy from qiskit.circuit.controlledgate import ControlledGate @@ -895,7 +895,7 @@ def __new__( """ # The CXGate and CCXGate will be implemented for all modes of the MCX, and # the C3XGate and C4XGate will be implemented in the MCXGrayCode class. - explicit = {1: CXGate, 2: CCXGate} + explicit: Dict[int, Type[ControlledGate]] = {1: CXGate, 2: CCXGate} if num_ctrl_qubits in explicit: gate_class = explicit[num_ctrl_qubits] gate = gate_class.__new__(gate_class, label=label, ctrl_state=ctrl_state) diff --git a/qiskit/circuit/library/templates/rzx/rzx_cy.py b/qiskit/circuit/library/templates/rzx/rzx_cy.py index 2ca641ab8ede..5f2e42225ab5 100644 --- a/qiskit/circuit/library/templates/rzx/rzx_cy.py +++ b/qiskit/circuit/library/templates/rzx/rzx_cy.py @@ -19,12 +19,15 @@ q_1: ┤ X ├┤ RY(ϴ) ├┤ X ├┤ RY(-ϴ) ├┤ RZ(-π/2) ├┤ RX(ϴ) ├┤1 ├┤ RZ(π/2) ├ └───┘└───────┘└───┘└────────┘└──────────┘└───────┘└──────────┘└─────────┘ """ +from typing import Optional import numpy as np + from qiskit.circuit import Parameter, QuantumCircuit +from qiskit.circuit.parameterexpression import ParameterValueType -def rzx_cy(theta: float = None): +def rzx_cy(theta: Optional[ParameterValueType] = None): """Template for CX - RYGate - CX.""" if theta is None: theta = Parameter("ϴ") diff --git a/qiskit/circuit/library/templates/rzx/rzx_xz.py b/qiskit/circuit/library/templates/rzx/rzx_xz.py index 4def8657e9aa..634e7d9be216 100644 --- a/qiskit/circuit/library/templates/rzx/rzx_xz.py +++ b/qiskit/circuit/library/templates/rzx/rzx_xz.py @@ -25,11 +25,15 @@ « """ +from typing import Optional + import numpy as np + from qiskit.circuit import Parameter, QuantumCircuit +from qiskit.circuit.parameterexpression import ParameterValueType -def rzx_xz(theta: float = None): +def rzx_xz(theta: Optional[ParameterValueType] = None): """Template for CX - RXGate - CX.""" if theta is None: theta = Parameter("ϴ") diff --git a/qiskit/circuit/library/templates/rzx/rzx_yz.py b/qiskit/circuit/library/templates/rzx/rzx_yz.py index 96c4655f6d5e..f83b1de6bceb 100644 --- a/qiskit/circuit/library/templates/rzx/rzx_yz.py +++ b/qiskit/circuit/library/templates/rzx/rzx_yz.py @@ -19,12 +19,15 @@ q_1: ┤ X ├──────────┤ X ├───────────┤1 ├──────────── └───┘ └───┘ └─────────┘ """ +from typing import Optional import numpy as np + from qiskit.circuit import Parameter, QuantumCircuit +from qiskit.circuit.parameterexpression import ParameterValueType -def rzx_yz(theta: float = None): +def rzx_yz(theta: Optional[ParameterValueType] = None): """Template for CX - RYGate - CX.""" if theta is None: theta = Parameter("ϴ") diff --git a/qiskit/circuit/library/templates/rzx/rzx_zz1.py b/qiskit/circuit/library/templates/rzx/rzx_zz1.py index 8eb715c3bcbc..ebeb6b3c48de 100644 --- a/qiskit/circuit/library/templates/rzx/rzx_zz1.py +++ b/qiskit/circuit/library/templates/rzx/rzx_zz1.py @@ -29,12 +29,15 @@ «q_1: ┤ RZ(π/2) ├ « └─────────┘ """ +from typing import Optional import numpy as np + from qiskit.circuit import Parameter, QuantumCircuit +from qiskit.circuit.parameterexpression import ParameterValueType -def rzx_zz1(theta: float = None): +def rzx_zz1(theta: Optional[ParameterValueType] = None): """Template for CX - RZGate - CX.""" if theta is None: theta = Parameter("ϴ") diff --git a/qiskit/circuit/library/templates/rzx/rzx_zz2.py b/qiskit/circuit/library/templates/rzx/rzx_zz2.py index cd6774b337c2..5008d2d38941 100644 --- a/qiskit/circuit/library/templates/rzx/rzx_zz2.py +++ b/qiskit/circuit/library/templates/rzx/rzx_zz2.py @@ -25,11 +25,15 @@ « └──────────┘└─────────┘└─────────┘└─────────┘ """ +from typing import Optional + import numpy as np + from qiskit.circuit import Parameter, QuantumCircuit +from qiskit.circuit.parameterexpression import ParameterValueType -def rzx_zz2(theta: float = None): +def rzx_zz2(theta: Optional[ParameterValueType] = None): """Template for CX - RZGate - CX.""" if theta is None: theta = Parameter("ϴ") diff --git a/qiskit/circuit/library/templates/rzx/rzx_zz3.py b/qiskit/circuit/library/templates/rzx/rzx_zz3.py index b1e117367f73..5da965295437 100644 --- a/qiskit/circuit/library/templates/rzx/rzx_zz3.py +++ b/qiskit/circuit/library/templates/rzx/rzx_zz3.py @@ -24,12 +24,15 @@ «q_1: ┤1 ├┤ RZ(π/2) ├┤ RX(π/2) ├┤ RZ(π/2) ├ « └──────────┘└─────────┘└─────────┘└─────────┘ """ +from typing import Optional import numpy as np + from qiskit.circuit import Parameter, QuantumCircuit +from qiskit.circuit.parameterexpression import ParameterValueType -def rzx_zz3(theta: float = None): +def rzx_zz3(theta: Optional[ParameterValueType] = None): """Template for CX - RZGate - CX.""" if theta is None: theta = Parameter("ϴ") diff --git a/qiskit/circuit/operation.py b/qiskit/circuit/operation.py index f2e898c069f9..e7f4f6bfd5f6 100644 --- a/qiskit/circuit/operation.py +++ b/qiskit/circuit/operation.py @@ -42,19 +42,19 @@ class Operation(ABC): __slots__ = () - @property + @property # type: ignore @abstractmethod def name(self): """Unique string identifier for operation type.""" raise NotImplementedError - @property + @property # type: ignore @abstractmethod def num_qubits(self): """Number of qubits.""" raise NotImplementedError - @property + @property # type: ignore @abstractmethod def num_clbits(self): """Number of classical bits.""" diff --git a/qiskit/circuit/parameterexpression.py b/qiskit/circuit/parameterexpression.py index 641a7404c553..26c0638321fb 100644 --- a/qiskit/circuit/parameterexpression.py +++ b/qiskit/circuit/parameterexpression.py @@ -12,7 +12,7 @@ """ ParameterExpression Class to enable creating simple expressions of Parameters. """ -from typing import Callable, Dict, Set, Union +from typing import Callable, Dict, Set, Union, Optional import numbers import operator @@ -48,7 +48,7 @@ def __init__(self, symbol_map: Dict, expr): self._parameter_symbols = symbol_map self._parameters = set(self._parameter_symbols) self._symbol_expr = expr - self._name_map = None + self._name_map: Optional[Dict] = None @property def parameters(self) -> Set: @@ -538,4 +538,4 @@ def sympify(self): # Redefine the type so external imports get an evaluated reference; Sphinx needs this to understand # the type hints. -ParameterValueType = Union[ParameterExpression, float] +ParameterValueType = Union[ParameterExpression, float] # TODO: should include ParameterVector? diff --git a/qiskit/circuit/quantumcircuit.py b/qiskit/circuit/quantumcircuit.py index 6ad3b3d8f589..d948f1b1a977 100644 --- a/qiskit/circuit/quantumcircuit.py +++ b/qiskit/circuit/quantumcircuit.py @@ -20,6 +20,7 @@ import multiprocessing as mp import string import re +import typing from collections import OrderedDict, defaultdict, namedtuple from typing import ( Union, @@ -34,8 +35,9 @@ Mapping, Set, Iterable, + Any, + DefaultDict, ) -import typing import numpy as np from qiskit.exceptions import QiskitError, MissingOptionalLibraryError from qiskit.utils.multiprocessing import is_main_process @@ -241,7 +243,7 @@ def __init__( # Data contains a list of instructions and their contexts, # in the order they were applied. - self._data = [] + self._data: List[CircuitInstruction] = [] self._op_start_times = None # A stack to hold the instruction sets that are being built up during for-, if- and @@ -250,22 +252,24 @@ def __init__( # builder interfaces need to wait until they are completed before they can fill in things # like `break` and `continue`. This is because these instructions need to "operate" on the # full width of bits, but the builder interface won't know what bits are used until the end. - self._control_flow_scopes = [] + self._control_flow_scopes: List[ + "qiskit.circuit.controlflow.builder.ControlFlowBuilderBlock" + ] = [] - self.qregs = [] - self.cregs = [] - self._qubits = [] - self._clbits = [] + self.qregs: List[QuantumRegister] = [] + self.cregs: List[ClassicalRegister] = [] + self._qubits: List[Qubit] = [] + self._clbits: List[Clbit] = [] # Dict mapping Qubit or Clbit instances to tuple comprised of 0) the # corresponding index in circuit.{qubits,clbits} and 1) a list of # Register-int pairs for each Register containing the Bit and its index # within that register. - self._qubit_indices = {} - self._clbit_indices = {} + self._qubit_indices: Dict[Qubit, BitLocations] = {} + self._clbit_indices: Dict[Clbit, BitLocations] = {} - self._ancillas = [] - self._calibrations = defaultdict(dict) + self._ancillas: List[AncillaQubit] = [] + self._calibrations: DefaultDict[str, Dict[Tuple, Any]] = defaultdict(dict) self.add_register(*regs) # Parameter table tracks instructions with variable parameters. @@ -294,27 +298,6 @@ def data(self) -> QuantumCircuitData: """ return QuantumCircuitData(self) - @property - def op_start_times(self) -> List[int]: - """Return a list of operation start times. - - This attribute is enabled once one of scheduling analysis passes - runs on the quantum circuit. - - Returns: - List of integers representing instruction start times. - The index corresponds to the index of instruction in :attr:`QuantumCircuit.data`. - - Raises: - AttributeError: When circuit is not scheduled. - """ - if self._op_start_times is None: - raise AttributeError( - "This circuit is not scheduled. " - "To schedule it run the circuit through one of the transpiler scheduling passes." - ) - return self._op_start_times - @data.setter def data(self, data_input: Iterable): """Sets the circuit data from a list of instructions and context. @@ -341,6 +324,27 @@ def data(self, data_input: Iterable): for instruction, qargs, cargs in data_input: self.append(instruction, qargs, cargs) + @property + def op_start_times(self) -> List[int]: + """Return a list of operation start times. + + This attribute is enabled once one of scheduling analysis passes + runs on the quantum circuit. + + Returns: + List of integers representing instruction start times. + The index corresponds to the index of instruction in :attr:`QuantumCircuit.data`. + + Raises: + AttributeError: When circuit is not scheduled. + """ + if self._op_start_times is None: + raise AttributeError( + "This circuit is not scheduled. " + "To schedule it run the circuit through one of the transpiler scheduling passes." + ) + return self._op_start_times + @property def calibrations(self) -> dict: """Return calibration dictionary. @@ -934,7 +938,7 @@ def compose( edge_map = {**qubit_map, **clbit_map} or {**identity_qubit_map, **identity_clbit_map} - mapped_instrs = [] + mapped_instrs: List[CircuitInstruction] = [] for instr in instrs: n_qargs = [edge_map[qarg] for qarg in instr.qubits] n_cargs = [edge_map[carg] for carg in instr.clbits] @@ -1245,6 +1249,7 @@ def append( else: operation = instruction # Convert input to instruction + # TODO: define type SupportsInstruction? if not isinstance(operation, Instruction) and not hasattr(operation, "to_instruction"): if issubclass(operation, Instruction): raise CircuitError( @@ -1377,11 +1382,11 @@ def add_register(self, *regs: Union[Register, int, Sequence[Bit]]) -> None: elif len(regs) == 2 and all(isinstance(reg, int) for reg in regs): # QuantumCircuit with anonymous wires e.g. QuantumCircuit(2, 3) if regs[0] == 0: - qregs = tuple() + qregs: Tuple[QuantumRegister, ...] = tuple() else: qregs = (QuantumRegister(regs[0], "q"),) if regs[1] == 0: - cregs = tuple() + cregs: Tuple[ClassicalRegister, ...] = tuple() else: cregs = (ClassicalRegister(regs[1], "c"),) regs = qregs + cregs @@ -1677,7 +1682,7 @@ def qasm( "c4x", ] - existing_composite_circuits = [] + existing_composite_circuits: List[Instruction] = [] string_temp = self.header + "\n" string_temp += self.extension_lib + "\n" @@ -1786,7 +1791,7 @@ def draw( fold: Optional[int] = None, # The type of ax is matplotlib.axes.Axes, but this is not a fixed dependency, so cannot be # safely forward-referenced. - ax: Optional[typing.Any] = None, + ax: Optional[Any] = None, initial_state: bool = False, cregbundle: bool = True, ): @@ -1924,7 +1929,7 @@ def draw( ) def size( - self, filter_function: Optional[callable] = lambda x: not x.operation._directive + self, filter_function: Optional[typing.Callable] = lambda x: not x.operation._directive ) -> int: """Returns total number of instructions in circuit. @@ -1939,7 +1944,7 @@ def size( return sum(map(filter_function, self._data)) def depth( - self, filter_function: Optional[callable] = lambda x: not x.operation._directive + self, filter_function: Optional[typing.Callable] = lambda x: not x.operation._directive ) -> int: """Return circuit depth (i.e., length of critical path). @@ -1957,7 +1962,9 @@ def depth( """ # Assign each bit in the circuit a unique integer # to index into op_stack. - bit_indices = {bit: idx for idx, bit in enumerate(self.qubits + self.clbits)} + bit_indices: Dict[Union[Qubit, Clbit], int] = { + bit: idx for idx, bit in enumerate(self.qubits + self.clbits) + } # If no bits, return 0 if not bit_indices: @@ -2078,7 +2085,7 @@ def num_connected_components(self, unitary_only: bool = False) -> int: """ # Convert registers to ints (as done in depth). bits = self.qubits if unitary_only else (self.qubits + self.clbits) - bit_indices = {bit: idx for idx, bit in enumerate(bits)} + bit_indices: Dict[Union[Qubit, Clbit], int] = {bit: idx for idx, bit in enumerate(bits)} # Start with each qubit or cbit being its own subgraph. sub_graphs = [[bit] for bit in range(len(bit_indices))] @@ -2812,7 +2819,9 @@ def delay( instructions = InstructionSet(resource_requester=self._resolve_classical_resource) for q in qubits: - inst = (Delay(duration, unit), [q], []) + inst: Tuple[ + Instruction, Optional[Sequence[QubitSpecifier]], Optional[Sequence[ClbitSpecifier]] + ] = (Delay(duration, unit), [q], []) self.append(*inst) instructions.add(*inst) return instructions @@ -4209,7 +4218,7 @@ def _update_parameter_table_on_instruction_removal(self, instruction: CircuitIns :meth:`.QuantumCircuit.append`, so this should be safe. Trying to account for it would involve adding a potentially quadratic-scaling loop to check each entry in ``data``. """ - atomic_parameters = [] + atomic_parameters: List[Tuple[Parameter, int]] = [] for index, parameter in enumerate(instruction.operation.params): if isinstance(parameter, (ParameterExpression, QuantumCircuit)): atomic_parameters.extend((p, index) for p in parameter.parameters) @@ -4874,7 +4883,7 @@ def _insert_composite_gate_definition_qasm( # Generate gate definition string for instruction in existing_composite_circuits: if hasattr(instruction, "_qasm_definition"): - qasm_string = instruction._qasm_definition + qasm_string = instruction._qasm_definition # type: ignore[attr-defined] else: qasm_string = _get_composite_circuit_qasm_from_instruction(instruction) gate_definition_string += "\n" + qasm_string diff --git a/qiskit/compiler/transpiler.py b/qiskit/compiler/transpiler.py index ac9ccc7c0db4..c1f4442dcfc4 100644 --- a/qiskit/compiler/transpiler.py +++ b/qiskit/compiler/transpiler.py @@ -254,7 +254,7 @@ def callback_func(**kwargs): or errors in passes """ arg_circuits_list = isinstance(circuits, list) - circuits = circuits if arg_circuits_list else [circuits] + circuits = circuits if arg_circuits_list else [circuits] # type: ignore[list-item] if not circuits: return [] @@ -313,7 +313,7 @@ def callback_func(**kwargs): ) # Get transpile_args to configure the circuit transpilation job(s) if coupling_map in unique_transpile_args: - cmap_conf = unique_transpile_args["coupling_map"] + cmap_conf = unique_transpile_args["coupling_map"] # TODO: unique_transpile_args is a list else: cmap_conf = [shared_args["coupling_map"]] * len(circuits) _check_circuits_coupling_map(circuits, cmap_conf, backend) diff --git a/qiskit/dagcircuit/dagcircuit.py b/qiskit/dagcircuit/dagcircuit.py index 60f6085a9241..b6fe89f1e2ee 100644 --- a/qiskit/dagcircuit/dagcircuit.py +++ b/qiskit/dagcircuit/dagcircuit.py @@ -24,6 +24,7 @@ import copy import itertools import math +from typing import Generator, Any, List import numpy as np import retworkx as rx @@ -83,8 +84,8 @@ def __init__(self): self.cregs = OrderedDict() # List of Qubit/Clbit wires that the DAG acts on. - self.qubits = [] - self.clbits = [] + self.qubits: List[Qubit] = [] + self.clbits: List[Clbit] = [] self._global_phase = 0 self._calibrations = defaultdict(dict) @@ -1025,7 +1026,7 @@ def _key(x): return iter(rx.lexicographical_topological_sort(self._multi_graph, key=key)) - def topological_op_nodes(self, key=None): + def topological_op_nodes(self, key=None) -> Generator[DAGOpNode, Any, Any]: """ Yield op nodes in topological order. diff --git a/qiskit/dagcircuit/dagnode.py b/qiskit/dagcircuit/dagnode.py index b0ead7b4cbd8..043f41b4767c 100644 --- a/qiskit/dagcircuit/dagnode.py +++ b/qiskit/dagcircuit/dagnode.py @@ -15,6 +15,9 @@ """Objects to represent the information at a node in the DAGCircuit.""" import warnings +from typing import Optional, Tuple + +from qiskit.circuit import Qubit, Clbit class DAGNode: @@ -100,8 +103,8 @@ def __init__(self, op, qargs=(), cargs=()): """Create an Instruction node""" super().__init__() self.op = op - self.qargs = tuple(qargs) - self.cargs = tuple(cargs) + self.qargs: Optional[Tuple[Qubit, ...]] = tuple(qargs) + self.cargs: Optional[Tuple[Clbit, ...]] = tuple(cargs) self.sort_key = str(self.qargs) @property diff --git a/qiskit/extensions/hamiltonian_gate.py b/qiskit/extensions/hamiltonian_gate.py index b35c09ca4ece..81730ef15d4a 100644 --- a/qiskit/extensions/hamiltonian_gate.py +++ b/qiskit/extensions/hamiltonian_gate.py @@ -134,4 +134,4 @@ def hamiltonian(self, operator, time, qubits, label=None): return self.append(HamiltonianGate(data=operator, time=time, label=label), qubits, []) -QuantumCircuit.hamiltonian = hamiltonian +QuantumCircuit.hamiltonian = hamiltonian # type: ignore[attr-defined] diff --git a/qiskit/extensions/quantum_initializer/diagonal.py b/qiskit/extensions/quantum_initializer/diagonal.py index b4c24fc41b61..69c9a0f42588 100644 --- a/qiskit/extensions/quantum_initializer/diagonal.py +++ b/qiskit/extensions/quantum_initializer/diagonal.py @@ -154,4 +154,4 @@ def diagonal(self, diag, qubit): return self.append(DiagonalGate(diag), qubit) -QuantumCircuit.diagonal = diagonal +QuantumCircuit.diagonal = diagonal # type: ignore[attr-defined] diff --git a/qiskit/extensions/quantum_initializer/initializer.py b/qiskit/extensions/quantum_initializer/initializer.py index 8382fa62f846..700734bf153f 100644 --- a/qiskit/extensions/quantum_initializer/initializer.py +++ b/qiskit/extensions/quantum_initializer/initializer.py @@ -188,4 +188,4 @@ class to prepare the qubits in a specified state. return self.append(Initialize(params, num_qubits), qubits) -QuantumCircuit.initialize = initialize +QuantumCircuit.initialize = initialize # type: ignore[attr-defined] diff --git a/qiskit/extensions/quantum_initializer/isometry.py b/qiskit/extensions/quantum_initializer/isometry.py index cb3bb1f12311..1dc1acb886ff 100644 --- a/qiskit/extensions/quantum_initializer/isometry.py +++ b/qiskit/extensions/quantum_initializer/isometry.py @@ -611,5 +611,5 @@ def iso( # support both QuantumCircuit.iso and QuantumCircuit.isometry -QuantumCircuit.iso = iso -QuantumCircuit.isometry = iso +QuantumCircuit.iso = iso # type: ignore[attr-defined] +QuantumCircuit.isometry = iso # type: ignore[attr-defined] diff --git a/qiskit/extensions/quantum_initializer/squ.py b/qiskit/extensions/quantum_initializer/squ.py index 480f6443d5c4..3543ece6c49b 100644 --- a/qiskit/extensions/quantum_initializer/squ.py +++ b/qiskit/extensions/quantum_initializer/squ.py @@ -201,4 +201,4 @@ def squ( return self.append(SingleQubitUnitary(unitary_matrix, mode, up_to_diagonal), [qubit], []) -QuantumCircuit.squ = squ +QuantumCircuit.squ = squ # type: ignore[attr-defined] diff --git a/qiskit/extensions/quantum_initializer/uc.py b/qiskit/extensions/quantum_initializer/uc.py index f432a7ebd082..074a48b155e7 100644 --- a/qiskit/extensions/quantum_initializer/uc.py +++ b/qiskit/extensions/quantum_initializer/uc.py @@ -350,4 +350,4 @@ def uc(self, gate_list, q_controls, q_target, up_to_diagonal=False): return self.append(UCGate(gate_list, up_to_diagonal), [q_target] + q_controls) -QuantumCircuit.uc = uc +QuantumCircuit.uc = uc # type: ignore[attr-defined] diff --git a/qiskit/extensions/quantum_initializer/ucrx.py b/qiskit/extensions/quantum_initializer/ucrx.py index 5d412f1e0bc8..3e91b125beaa 100644 --- a/qiskit/extensions/quantum_initializer/ucrx.py +++ b/qiskit/extensions/quantum_initializer/ucrx.py @@ -94,4 +94,4 @@ def ucrx(self, angle_list, q_controls, q_target): return self.append(UCRXGate(angle_list), [q_target] + q_controls, []) -QuantumCircuit.ucrx = ucrx +QuantumCircuit.ucrx = ucrx # type: ignore[attr-defined] diff --git a/qiskit/extensions/quantum_initializer/ucry.py b/qiskit/extensions/quantum_initializer/ucry.py index b8642bac0cc7..5b5c81b5813c 100644 --- a/qiskit/extensions/quantum_initializer/ucry.py +++ b/qiskit/extensions/quantum_initializer/ucry.py @@ -91,4 +91,4 @@ def ucry(self, angle_list, q_controls, q_target): return self.append(UCRYGate(angle_list), [q_target] + q_controls, []) -QuantumCircuit.ucry = ucry +QuantumCircuit.ucry = ucry # type: ignore[attr-defined] diff --git a/qiskit/extensions/quantum_initializer/ucrz.py b/qiskit/extensions/quantum_initializer/ucrz.py index 7cead50c79ce..83be9257a80e 100644 --- a/qiskit/extensions/quantum_initializer/ucrz.py +++ b/qiskit/extensions/quantum_initializer/ucrz.py @@ -92,4 +92,4 @@ def ucrz(self, angle_list, q_controls, q_target): return self.append(UCRZGate(angle_list), [q_target] + q_controls, []) -QuantumCircuit.ucrz = ucrz +QuantumCircuit.ucrz = ucrz # type: ignore[attr-defined] diff --git a/qiskit/extensions/unitary.py b/qiskit/extensions/unitary.py index 6a36e630dd3f..5ea2d2780a63 100644 --- a/qiskit/extensions/unitary.py +++ b/qiskit/extensions/unitary.py @@ -260,4 +260,4 @@ def unitary(self, obj, qubits, label=None): return self.append(gate, qubits, []) -QuantumCircuit.unitary = unitary +QuantumCircuit.unitary = unitary # type: ignore[attr-defined] diff --git a/qiskit/opflow/gradients/circuit_gradients/lin_comb.py b/qiskit/opflow/gradients/circuit_gradients/lin_comb.py index 366fb59fd497..f68d4e0dcc6c 100644 --- a/qiskit/opflow/gradients/circuit_gradients/lin_comb.py +++ b/qiskit/opflow/gradients/circuit_gradients/lin_comb.py @@ -100,7 +100,7 @@ class LinComb(CircuitGradient): } # pylint: disable=signature-differs, arguments-differ - def __init__(self, aux_meas_op: OperatorBase = Z): + def __init__(self, aux_meas_op: OperatorBase = Z): # type: ignore[override] """ Args: aux_meas_op: The operator that the auxiliary qubit is measured with respect to. @@ -751,7 +751,7 @@ def _gradient_states( # compute the correct coefficient and append to list of circuits coeff = np.sqrt(np.abs(grad_coeff)) * state_op.coeff - state = CircuitStateFn(grad_circuit, coeff=coeff) + state: OperatorBase = CircuitStateFn(grad_circuit, coeff=coeff) # apply the chain rule if the parameter expression if required param_expression = gate.params[idx] diff --git a/qiskit/opflow/gradients/circuit_gradients/param_shift.py b/qiskit/opflow/gradients/circuit_gradients/param_shift.py index 435914f9f342..3e9521148d20 100644 --- a/qiskit/opflow/gradients/circuit_gradients/param_shift.py +++ b/qiskit/opflow/gradients/circuit_gradients/param_shift.py @@ -92,7 +92,7 @@ def convert( Tuple[ParameterExpression, ParameterExpression], List[Tuple[ParameterExpression, ParameterExpression]], ], - ) -> OperatorBase: + ) -> OperatorBase: # type: ignore[override] """ Args: operator: The operator corresponding to our quantum state we are taking the diff --git a/qiskit/opflow/gradients/circuit_qfis/lin_comb_full.py b/qiskit/opflow/gradients/circuit_qfis/lin_comb_full.py index 81865180881f..d966a7a28edb 100644 --- a/qiskit/opflow/gradients/circuit_qfis/lin_comb_full.py +++ b/qiskit/opflow/gradients/circuit_qfis/lin_comb_full.py @@ -40,7 +40,7 @@ def __init__( self, aux_meas_op: OperatorBase = Z, phase_fix: bool = True, - ): + ): # type: ignore[override] """ Args: aux_meas_op: The operator that the auxiliary qubit is measured with respect to. diff --git a/qiskit/opflow/operator_base.py b/qiskit/opflow/operator_base.py index 719a8fe99f5a..8d97d6404243 100644 --- a/qiskit/opflow/operator_base.py +++ b/qiskit/opflow/operator_base.py @@ -47,7 +47,7 @@ class OperatorBase(StarAlgebraMixin, TensorMixin, ABC): def __init__(self) -> None: self._instance_id = next(self._count) - @property + @property # type: ignore @abstractmethod def settings(self) -> Dict: """Return settings of this object in a dictionary. @@ -66,7 +66,7 @@ def instance_id(self) -> int: """Return the unique instance id.""" return self._instance_id - @property + @property # type: ignore @abstractmethod def num_qubits(self) -> int: r"""The number of qubits over which the Operator is defined. If @@ -309,7 +309,7 @@ def tensorpower(self, other: int) -> Union["OperatorBase", int]: """ raise NotImplementedError - @property + @property # type: ignore @abstractmethod def parameters(self): r"""Return a set of Parameter objects contained in the Operator.""" diff --git a/qiskit/opflow/primitive_ops/pauli_op.py b/qiskit/opflow/primitive_ops/pauli_op.py index 7b5e57a4b4e0..9990cb0872a7 100644 --- a/qiskit/opflow/primitive_ops/pauli_op.py +++ b/qiskit/opflow/primitive_ops/pauli_op.py @@ -287,7 +287,7 @@ def exp_i(self) -> OperatorBase: return PauliOp(self.primitive) if np.sum(sig_qubits) == 1: sig_qubit_index = sig_qubits.tolist().index(True) - coeff = ( + coeff: Union[float, ParameterExpression] = ( np.real(self.coeff) if not isinstance(self.coeff, ParameterExpression) else self.coeff diff --git a/qiskit/opflow/state_fns/circuit_state_fn.py b/qiskit/opflow/state_fns/circuit_state_fn.py index 9f959e8718c8..021173664a65 100644 --- a/qiskit/opflow/state_fns/circuit_state_fn.py +++ b/qiskit/opflow/state_fns/circuit_state_fn.py @@ -11,8 +11,7 @@ # that they have been altered from the originals. """ CircuitStateFn Class """ - - +import typing from typing import Dict, List, Optional, Set, Union, cast import numpy as np @@ -47,7 +46,7 @@ class CircuitStateFn(StateFn): def __init__( self, primitive: Union[QuantumCircuit, Instruction] = None, - coeff: Union[complex, ParameterExpression] = 1.0, + coeff: Union[typing.SupportsComplex, ParameterExpression] = 1.0, is_measurement: bool = False, from_operator: bool = False, ) -> None: diff --git a/qiskit/primitives/base_estimator.py b/qiskit/primitives/base_estimator.py index 2c71da55835a..f28ef2198b24 100644 --- a/qiskit/primitives/base_estimator.py +++ b/qiskit/primitives/base_estimator.py @@ -113,6 +113,7 @@ from abc import ABC, abstractmethod from collections.abc import Iterable, Sequence from copy import copy +from typing import List import numpy as np @@ -163,8 +164,8 @@ def __init__( # To guarantee that they exist as instance variable. # With only dynamic set, the python will not know if the attribute exists or not. - self._circuit_ids = self._circuit_ids - self._observable_ids = self._observable_ids + self._circuit_ids: List[int] = self._circuit_ids + self._observable_ids: List[int] = self._observable_ids if parameters is None: self._parameters = tuple(circ.parameters for circ in self._circuits) @@ -296,7 +297,7 @@ def __call__( if not isinstance(circuit, (int, np.integer)) else circuit for circuit in circuits - ] + ] # TODO: typed as list of int after this operations except StopIteration as err: raise QiskitError( "The circuits passed when calling estimator is not one of the circuits used to " @@ -308,7 +309,7 @@ def __call__( if not isinstance(observable, (int, np.integer)) else observable for observable in observables - ] + ] # TODO: typed as list of int after this operations except StopIteration as err: raise QiskitError( "The observables passed when calling estimator is not one of the observables used to " diff --git a/qiskit/primitives/base_sampler.py b/qiskit/primitives/base_sampler.py index 12c2cba371ce..46fe18ba76ba 100644 --- a/qiskit/primitives/base_sampler.py +++ b/qiskit/primitives/base_sampler.py @@ -100,6 +100,7 @@ from abc import ABC, abstractmethod from collections.abc import Iterable, Sequence from copy import copy +from typing import List import numpy as np @@ -138,7 +139,7 @@ def __init__( # To guarantee that they exist as instance variable. # With only dynamic set, the python will not know if the attribute exists or not. - self._circuit_ids = self._circuit_ids + self._circuit_ids: List[int] = self._circuit_ids if parameters is None: self._parameters = tuple(circ.parameters for circ in self._circuits) diff --git a/qiskit/providers/backend.py b/qiskit/providers/backend.py index 2690583bd575..2aea1023d7a5 100644 --- a/qiskit/providers/backend.py +++ b/qiskit/providers/backend.py @@ -362,7 +362,7 @@ def operation_names(self) -> List[str]: logger.warning(msg) return list(self.target.operation_names) - @property + @property # type: ignore @abstractmethod def target(self): """A :class:`qiskit.transpiler.Target` object for the backend. @@ -386,7 +386,7 @@ def instruction_durations(self): """Return the :class:`~qiskit.transpiler.InstructionDurations` object.""" return self.target.durations() - @property + @property # type: ignore @abstractmethod def max_circuits(self): """The maximum number of circuits (or Pulse schedules) that can be diff --git a/qiskit/providers/basicaer/basicaertools.py b/qiskit/providers/basicaer/basicaertools.py index dfba59e7c36f..dcfd937f0abd 100644 --- a/qiskit/providers/basicaer/basicaertools.py +++ b/qiskit/providers/basicaer/basicaertools.py @@ -15,11 +15,12 @@ """ from string import ascii_uppercase, ascii_lowercase -from typing import List, Optional +from typing import List, Optional, Type import numpy as np import qiskit.circuit.library.standard_gates as gates +from qiskit.circuit import Gate from qiskit.exceptions import QiskitError # Single qubit gates supported by ``single_gate_params``. @@ -41,6 +42,7 @@ def single_gate_matrix(gate: str, params: Optional[List[float]] = None): if params is None: params = [] + gc: Type[Gate] if gate == "U": gc = gates.UGate elif gate == "u3": diff --git a/qiskit/providers/fake_provider/utils/backend_converter.py b/qiskit/providers/fake_provider/utils/backend_converter.py index c58881c1257c..ed9704262152 100644 --- a/qiskit/providers/fake_provider/utils/backend_converter.py +++ b/qiskit/providers/fake_provider/utils/backend_converter.py @@ -14,6 +14,7 @@ Utilities for constructing Target object from configuration, properties and pulse defaults json files """ +from typing import Dict, List from qiskit.transpiler.target import Target, InstructionProperties from qiskit.providers.backend import QubitProperties @@ -47,7 +48,7 @@ def convert_to_target(conf_dict: dict, props_dict: dict = None, defs_dict: dict # Parse from properties if it exsits if props_dict is not None: # Parse instructions - gates = {} + gates: Dict[str, Dict] = {} for gate in props_dict["gates"]: name = gate["gate"] if name in name_mapping: @@ -130,7 +131,7 @@ def convert_to_target(conf_dict: dict, props_dict: dict = None, defs_dict: dict return target -def qubit_props_from_props(properties: dict) -> list: +def qubit_props_from_props(properties: dict) -> List[QubitProperties]: """Returns a dictionary of `qiskit.providers.backend.QubitProperties` using a backend properties dictionary created by loading props.json payload. """ diff --git a/qiskit/providers/models/backendconfiguration.py b/qiskit/providers/models/backendconfiguration.py index 899fe6dc0f48..6a29538f9dd7 100644 --- a/qiskit/providers/models/backendconfiguration.py +++ b/qiskit/providers/models/backendconfiguration.py @@ -951,7 +951,7 @@ def describe(self, channel: ControlChannel) -> Dict[DriveChannel, complex]: result[DriveChannel(u_chan_lo.q)] = u_chan_lo.scale return result - def _parse_channels(self, channels: Dict[set, Any]) -> Dict[Any, Any]: + def _parse_channels(self, channels: Dict[str, Any]) -> Dict[Any, Any]: r""" Generates a dictionaries of ``Channel``\s, and tuple of qubit(s) they operate on. @@ -985,7 +985,7 @@ def _parse_channels(self, channels: Dict[set, Any]) -> Dict[Any, Any]: control_channels[qubits].append(channel_type(index)) return dict(qubit_channel_map), dict(channel_qubit_map), dict(control_channels) - def _get_channel_prefix_index(self, channel: str) -> str: + def _get_channel_prefix_index(self, channel: str) -> Tuple[Union[str, Any], int]: """Return channel prefix and index from the given ``channel``. Args: diff --git a/qiskit/providers/models/backendproperties.py b/qiskit/providers/models/backendproperties.py index 46e30c79fe5f..c92212451dc4 100644 --- a/qiskit/providers/models/backendproperties.py +++ b/qiskit/providers/models/backendproperties.py @@ -14,7 +14,7 @@ import copy import datetime -from typing import Any, Iterable, Tuple, Union +from typing import Any, Iterable, Tuple, Union, Dict, List import dateutil.parser from qiskit.providers.exceptions import BackendPropertyError @@ -31,7 +31,7 @@ class Nduv: value: value. """ - def __init__(self, date, name, unit, value): + def __init__(self, date, name: str, unit: str, value): """Initialize a new name-date-unit-value object Args: @@ -94,7 +94,7 @@ class Gate: _data = {} - def __init__(self, qubits, gate, parameters, **kwargs): + def __init__(self, qubits, gate: str, parameters: List[Nduv], **kwargs): """Initialize a new Gate object Args: @@ -166,7 +166,14 @@ class BackendProperties: _data = {} def __init__( - self, backend_name, backend_version, last_update_date, qubits, gates, general, **kwargs + self, + backend_name, + backend_version, + last_update_date, + qubits, + gates: List[Gate], + general, + **kwargs, ): """Initialize a BackendProperties instance. @@ -201,7 +208,7 @@ def __init__( formatted_props[prop.name] = (value, prop.date) self._qubits[qubit] = formatted_props - self._gates = {} + self._gates: Dict[str, Dict[Tuple, Dict[str, Tuple]]] = {} for gate in gates: if gate.gate not in self._gates: self._gates[gate.gate] = {} @@ -277,7 +284,7 @@ def __eq__(self, other): def gate_property( self, gate: str, qubits: Union[int, Iterable[int]] = None, name: str = None - ) -> Tuple[Any, datetime.datetime]: + ) -> Union[Tuple[Any, datetime.datetime], Dict[str, Tuple]]: """ Return the property of the given gate. @@ -366,7 +373,9 @@ def gate_length(self, gate: str, qubits: Union[int, Iterable[int]]) -> float: """ return self.gate_property(gate, qubits, "gate_length")[0] # Throw away datetime at index 1 - def qubit_property(self, qubit: int, name: str = None) -> Tuple[Any, datetime.datetime]: + def qubit_property( + self, qubit: int, name: str = None + ) -> Union[Tuple[Any, datetime.datetime], Dict[str, Tuple]]: """ Return the property of the given qubit. diff --git a/qiskit/pulse/builder.py b/qiskit/pulse/builder.py index ab556e47ecfb..1e191222d5d4 100644 --- a/qiskit/pulse/builder.py +++ b/qiskit/pulse/builder.py @@ -653,7 +653,7 @@ def get_context(self) -> ScheduleBlock: """ return self._context_stack[-1] - @property + @property # type: ignore @_requires_backend def num_qubits(self): """Get the number of qubits in the backend.""" @@ -664,7 +664,7 @@ def transpiler_settings(self) -> Mapping: """The builder's transpiler settings.""" return self._transpiler_settings - @transpiler_settings.setter + @transpiler_settings.setter # type: ignore @_compile_lazy_circuit_before def transpiler_settings(self, settings: Mapping): self._compile_lazy_circuit() @@ -675,7 +675,7 @@ def circuit_scheduler_settings(self) -> Mapping: """The builder's circuit to pulse scheduler settings.""" return self._circuit_scheduler_settings - @circuit_scheduler_settings.setter + @circuit_scheduler_settings.setter # type: ignore @_compile_lazy_circuit_before def circuit_scheduler_settings(self, settings: Mapping): self._compile_lazy_circuit() @@ -808,7 +808,7 @@ def call_subroutine( self.append_instruction(call_def) @_requires_backend - def call_gate(self, gate: circuit.Gate, qubits: Tuple[int, ...], lazy: bool = True): + def call_gate(self, gate: circuit.Gate, qubits: Union[int, Tuple[int, ...]], lazy: bool = True): """Call the circuit ``gate`` in the pulse program. The qubits are assumed to be defined on physical qubits. @@ -2273,7 +2273,7 @@ def delay_qubits(duration: int, *qubits: Union[int, Iterable[int]]): # Gate instructions -def call_gate(gate: circuit.Gate, qubits: Tuple[int, ...], lazy: bool = True): +def call_gate(gate: circuit.Gate, qubits: Union[int, Tuple[int, ...]], lazy: bool = True): """Call a gate and lazily schedule it to its corresponding pulse instruction. diff --git a/qiskit/pulse/channels.py b/qiskit/pulse/channels.py index 175d93ef8e87..a687a46f19eb 100644 --- a/qiskit/pulse/channels.py +++ b/qiskit/pulse/channels.py @@ -50,7 +50,7 @@ .. autoclass:: Channel """ from abc import ABCMeta -from typing import Any, Set, Union +from typing import Any, Set, Union, Optional import numpy as np @@ -143,7 +143,7 @@ def name(self) -> str: def __repr__(self): return f"{self.__class__.__name__}({self._index})" - def __eq__(self, other: "Channel") -> bool: + def __eq__(self, other: object) -> bool: """Return True iff self and other are equal, specifically, iff they have the same type and the same index. @@ -153,6 +153,8 @@ def __eq__(self, other: "Channel") -> bool: Returns: True iff equal. """ + if not isinstance(other, Channel): + return NotImplemented return type(self) is type(other) and self._index == other._index def __hash__(self): diff --git a/qiskit/pulse/configuration.py b/qiskit/pulse/configuration.py index 8383fa2f1e82..90aa286b871b 100644 --- a/qiskit/pulse/configuration.py +++ b/qiskit/pulse/configuration.py @@ -15,7 +15,7 @@ """ from typing import Dict, Union, Tuple, Optional -from .channels import PulseChannel, DriveChannel, MeasureChannel +from .channels import DriveChannel, MeasureChannel from .exceptions import PulseError @@ -118,8 +118,10 @@ class LoConfig: def __init__( self, - channel_los: Optional[Dict[PulseChannel, float]] = None, - lo_ranges: Optional[Dict[PulseChannel, Union[LoRange, Tuple[int]]]] = None, + channel_los: Optional[Dict[Union[DriveChannel, MeasureChannel], float]] = None, + lo_ranges: Optional[ + Dict[Union[DriveChannel, MeasureChannel], Union[LoRange, Tuple[int]]] + ] = None, ): """Lo channel configuration data structure. @@ -131,9 +133,9 @@ def __init__( PulseError: If channel is not configurable or set lo is out of range. """ - self._q_lo_freq = {} - self._m_lo_freq = {} - self._lo_ranges = {} + self._q_lo_freq: Dict[Union[DriveChannel, MeasureChannel], float] = {} + self._m_lo_freq: Dict[Union[DriveChannel, MeasureChannel], float] = {} + self._lo_ranges: Dict[Union[DriveChannel, MeasureChannel], LoRange] = {} lo_ranges = lo_ranges if lo_ranges else {} for channel, freq in lo_ranges.items(): @@ -176,12 +178,15 @@ def check_lo(self, channel: Union[DriveChannel, MeasureChannel], freq: float) -> freq: lo frequency Raises: PulseError: If freq is outside of channels range + Returns: + True if lo is valid for channel """ lo_ranges = self._lo_ranges if channel in lo_ranges: lo_range = lo_ranges[channel] if not lo_range.includes(freq): raise PulseError(f"Specified LO freq {freq:f} is out of range {lo_range}") + return True def channel_lo(self, channel: Union[DriveChannel, MeasureChannel]) -> float: """Return channel lo. diff --git a/qiskit/pulse/instructions/call.py b/qiskit/pulse/instructions/call.py index 4f209f3d1a81..b3943abdccad 100644 --- a/qiskit/pulse/instructions/call.py +++ b/qiskit/pulse/instructions/call.py @@ -156,7 +156,7 @@ def _get_arg_hash(self): """A helper function to generate hash of parameters.""" return hash(tuple(self.arguments.items())) - def __eq__(self, other: "Instruction") -> bool: + def __eq__(self, other: object) -> bool: """Check if this instruction is equal to the `other` instruction. Instructions are equal if they share the same type, operands, and channels. diff --git a/qiskit/pulse/instructions/instruction.py b/qiskit/pulse/instructions/instruction.py index 5ddffab05e82..53e8fdb93bf7 100644 --- a/qiskit/pulse/instructions/instruction.py +++ b/qiskit/pulse/instructions/instruction.py @@ -52,9 +52,9 @@ def __init__( PulseError: If the input ``channels`` are not all of type :class:`Channel`. """ - self._operands = operands + self._operands: Tuple = operands self._name = name - self._hash = None + self._hash: Optional[int] = None for channel in self.channels: if not isinstance(channel, Channel): @@ -75,7 +75,7 @@ def operands(self) -> Tuple: """Return instruction operands.""" return self._operands - @property + @property # type: ignore @abstractmethod def channels(self) -> Tuple[Channel]: """Returns the channels that this schedule uses.""" @@ -97,12 +97,12 @@ def duration(self) -> int: raise NotImplementedError @property - def _children(self) -> Tuple["Instruction"]: + def _children(self) -> Tuple["Instruction", ...]: """Instruction has no child nodes.""" return () @property - def instructions(self) -> Tuple[Tuple[int, "Instruction"]]: + def instructions(self) -> Tuple[Tuple[int, "Instruction"], ...]: """Iterable for getting instructions from Schedule tree.""" return tuple(self._instructions()) @@ -262,11 +262,13 @@ def draw( channels=channels, ) - def __eq__(self, other: "Instruction") -> bool: + def __eq__(self, other: object) -> bool: """Check if this Instruction is equal to the `other` instruction. Equality is determined by the instruction sharing the same operands and channels. """ + if not isinstance(other, Instruction): + return NotImplemented return isinstance(other, type(self)) and self.operands == other.operands def __hash__(self) -> int: diff --git a/qiskit/pulse/library/continuous.py b/qiskit/pulse/library/continuous.py index 52f05470635c..b184df2176d0 100644 --- a/qiskit/pulse/library/continuous.py +++ b/qiskit/pulse/library/continuous.py @@ -105,14 +105,14 @@ def sin(times: np.ndarray, amp: complex, freq: float, phase: float = 0) -> np.nd def _fix_gaussian_width( - gaussian_samples, - amp: float, + gaussian_samples: np.ndarray, + amp: complex, center: float, sigma: float, zeroed_width: Optional[float] = None, rescale_amp: bool = False, ret_scale_factor: bool = False, -) -> np.ndarray: +) -> Union[np.ndarray, Tuple[np.ndarray, float]]: r"""Enforce that the supplied gaussian pulse is zeroed at a specific width. This is achieved by subtracting $\Omega_g(center \pm zeroed_width/2)$ from all samples. @@ -132,7 +132,7 @@ def _fix_gaussian_width( zero_offset = gaussian(np.array([zeroed_width / 2]), amp, 0, sigma) gaussian_samples -= zero_offset - amp_scale_factor = 1.0 + amp_scale_factor: Union[complex, float, np.ndarray] = 1.0 if rescale_amp: amp_scale_factor = amp / (amp - zero_offset) if amp - zero_offset != 0 else 1.0 gaussian_samples *= amp_scale_factor @@ -198,7 +198,7 @@ def gaussian_deriv( ret_gaussian: bool = False, zeroed_width: Optional[float] = None, rescale_amp: bool = False, -) -> np.ndarray: +) -> Union[np.ndarray, Tuple[np.ndarray, np.ndarray]]: r"""Continuous unnormalized gaussian derivative pulse. Args: @@ -229,14 +229,14 @@ def gaussian_deriv( def _fix_sech_width( - sech_samples, - amp: float, + sech_samples: np.ndarray, + amp: complex, center: float, sigma: float, zeroed_width: Optional[float] = None, rescale_amp: bool = False, ret_scale_factor: bool = False, -) -> np.ndarray: +) -> Union[np.ndarray, Tuple[np.ndarray, float]]: r"""Enforce that the supplied sech pulse is zeroed at a specific width. This is achieved by subtracting $\Omega_g(center \pm zeroed_width/2)$ from all samples. @@ -256,7 +256,7 @@ def _fix_sech_width( zero_offset = sech(np.array([zeroed_width / 2]), amp, 0, sigma) sech_samples -= zero_offset - amp_scale_factor = 1.0 + amp_scale_factor: Union[complex, float, np.ndarray] = 1.0 if rescale_amp: amp_scale_factor = amp / (amp - zero_offset) if amp - zero_offset != 0 else 1.0 sech_samples *= amp_scale_factor @@ -316,7 +316,7 @@ def sech( def sech_deriv( times: np.ndarray, amp: complex, center: float, sigma: float, ret_sech: bool = False -) -> np.ndarray: +) -> Union[np.ndarray, Tuple[np.ndarray, np.ndarray]]: """Continuous unnormalized sech derivative pulse. Args: diff --git a/qiskit/pulse/library/parametric_pulses.py b/qiskit/pulse/library/parametric_pulses.py index 201478193a4c..14c823a4150f 100644 --- a/qiskit/pulse/library/parametric_pulses.py +++ b/qiskit/pulse/library/parametric_pulses.py @@ -110,7 +110,9 @@ def is_parameterized(self) -> bool: """Return True iff the instruction is parameterized.""" return any(_is_parameterized(val) for val in self.parameters.values()) - def __eq__(self, other: Pulse) -> bool: + def __eq__(self, other: object) -> bool: + if not isinstance(other, Pulse): + return NotImplemented return super().__eq__(other) and self.parameters == other.parameters def __hash__(self) -> int: diff --git a/qiskit/pulse/library/pulse.py b/qiskit/pulse/library/pulse.py index 82d826915df3..8bb88bc83b9a 100644 --- a/qiskit/pulse/library/pulse.py +++ b/qiskit/pulse/library/pulse.py @@ -55,7 +55,7 @@ def id(self) -> int: # pylint: disable=invalid-name """Unique identifier for this pulse.""" return id(self) - @property + @property # type: ignore @abstractmethod def parameters(self) -> Dict[str, Any]: """Return a dictionary containing the pulse's parameters.""" @@ -123,7 +123,9 @@ def draw( ) @abstractmethod - def __eq__(self, other: "Pulse") -> bool: + def __eq__(self, other: object) -> bool: + if not isinstance(other, Pulse): + return NotImplemented return isinstance(other, type(self)) @abstractmethod diff --git a/qiskit/pulse/library/symbolic_pulses.py b/qiskit/pulse/library/symbolic_pulses.py index a839dd45ca81..dcba2db3cace 100644 --- a/qiskit/pulse/library/symbolic_pulses.py +++ b/qiskit/pulse/library/symbolic_pulses.py @@ -101,7 +101,9 @@ def _is_amplitude_valid(symbolic_pulse: "SymbolicPulse") -> bool: return False -def _get_expression_args(expr: sym.Expr, params: Dict[str, float]) -> List[float]: +def _get_expression_args( + expr: sym.Expr, params: Dict[str, float] +) -> List[Union[np.ndarray, float]]: """A helper function to get argument to evaluate expression. Args: @@ -114,7 +116,7 @@ def _get_expression_args(expr: sym.Expr, params: Dict[str, float]) -> List[float Raises: PulseError: When a free symbol value is not defined in the pulse instance parameters. """ - args = [] + args: List[Union[np.ndarray, float]] = [] for symbol in sorted(expr.free_symbols, key=lambda s: s.name): if symbol.name == "t": # 't' is a special parameter to represent time vector. @@ -156,7 +158,7 @@ def __init__(self, attribute: str): the target expression to evaluate. """ self.attribute = attribute - self.lambda_funcs = dict() + self.lambda_funcs: Dict[int, Callable] = dict() def __get__(self, instance, owner) -> Callable: expr = getattr(instance, self.attribute, None) @@ -543,11 +545,11 @@ def is_parameterized(self) -> bool: @property def parameters(self) -> Dict[str, Any]: - params = {"duration": self.duration} + params: Dict[str, Union[ParameterExpression, complex, int]] = {"duration": self.duration} params.update(self._params) return params - def __eq__(self, other: "SymbolicPulse") -> bool: + def __eq__(self, other: object) -> bool: if not isinstance(other, SymbolicPulse): return NotImplemented diff --git a/qiskit/pulse/library/waveform.py b/qiskit/pulse/library/waveform.py index b7ddb27a9d44..51efab945376 100644 --- a/qiskit/pulse/library/waveform.py +++ b/qiskit/pulse/library/waveform.py @@ -113,7 +113,9 @@ def parameters(self) -> Dict[str, Any]: """Return a dictionary containing the pulse's parameters.""" return {} - def __eq__(self, other: Pulse) -> bool: + def __eq__(self, other: object) -> bool: + if not isinstance(other, Pulse): + return NotImplemented return ( super().__eq__(other) and self.samples.shape == other.samples.shape @@ -121,7 +123,7 @@ def __eq__(self, other: Pulse) -> bool: ) def __hash__(self) -> int: - return hash(self.samples.tostring()) + return hash(self.samples.tobytes()) def __repr__(self) -> str: opt = np.get_printoptions() diff --git a/qiskit/pulse/macros.py b/qiskit/pulse/macros.py index 81e32e4a8b5b..bd6458415002 100644 --- a/qiskit/pulse/macros.py +++ b/qiskit/pulse/macros.py @@ -12,7 +12,7 @@ """Module for common pulse programming macros.""" -from typing import Dict, List, Optional, Union +from typing import Dict, List, Optional, Union, Sequence from qiskit.pulse import channels, exceptions, instructions, utils from qiskit.pulse.instruction_schedule_map import InstructionScheduleMap @@ -20,7 +20,7 @@ def measure( - qubits: List[int], + qubits: Sequence[int], backend=None, inst_map: Optional[InstructionScheduleMap] = None, meas_map: Optional[Union[List[List[int]], Dict[int, List[int]]]] = None, diff --git a/qiskit/pulse/parser.py b/qiskit/pulse/parser.py index 7ceb9dd54e2a..3aebcf97bfca 100644 --- a/qiskit/pulse/parser.py +++ b/qiskit/pulse/parser.py @@ -13,7 +13,7 @@ # pylint: disable=invalid-name """Parser for mathematical string expressions returned by backends.""" -from typing import Dict, List, Union +from typing import Dict, List, Union, Callable, Any, Set import ast import copy import operator @@ -27,7 +27,7 @@ class PulseExpression(ast.NodeTransformer): """Expression parser to evaluate parameter values.""" - _math_ops = { + _math_ops: Dict[str, Union[Callable, float]] = { "acos": cmath.acos, "acosh": cmath.acosh, "asin": cmath.asin, @@ -72,8 +72,8 @@ def __init__(self, source: Union[str, ast.Expression], partial_binding: bool = F PulseError: When invalid string is specified. """ self._partial_binding = partial_binding - self._locals_dict = {} - self._params = set() + self._locals_dict: Dict[str, Any] = {} + self._params: Set[str] = set() if isinstance(source, ast.Expression): self._tree = source @@ -296,7 +296,7 @@ def generic_visit(self, node): raise PulseError("Unsupported node: %s" % node.__class__.__name__) -def parse_string_expr(source: str, partial_binding: bool = False): +def parse_string_expr(source: str, partial_binding: bool = False) -> PulseExpression: """Safe parsing of string expression. Args: diff --git a/qiskit/pulse/schedule.py b/qiskit/pulse/schedule.py index 843e6030ebf3..51751d9e201e 100644 --- a/qiskit/pulse/schedule.py +++ b/qiskit/pulse/schedule.py @@ -150,8 +150,8 @@ def __init__( self._duration = 0 # These attributes are populated by ``_mutable_insert`` - self._timeslots = {} - self._children = [] + self._timeslots: TimeSlots = {} + self._children: List[Tuple[int, "ScheduleComponent"]] = [] for sched_pair in schedules: try: time, sched = sched_pair @@ -235,7 +235,7 @@ def stop_time(self) -> int: return self.duration @property - def channels(self) -> Tuple[Channel]: + def channels(self) -> Tuple[Channel, ...]: """Returns channels that this schedule uses.""" return tuple(self._timeslots.keys()) @@ -256,7 +256,7 @@ def children(self) -> Tuple[Tuple[int, "ScheduleComponent"], ...]: return tuple(self._children) @property - def instructions(self) -> Tuple[Tuple[int, Instruction]]: + def instructions(self) -> Tuple[Tuple[int, Instruction], ...]: """Get the time-ordered instructions from self.""" def key(time_inst_pair): @@ -756,7 +756,7 @@ def __lshift__(self, time: int) -> "Schedule": """Return a new schedule which is shifted forward by ``time``.""" return self.shift(time) - def __eq__(self, other: "ScheduleComponent") -> bool: + def __eq__(self, other: object) -> bool: """Test if two Schedule are equal. Equality is checked by verifying there is an equal instruction at every time @@ -915,7 +915,7 @@ def __init__( self._metadata = metadata or {} self._alignment_context = alignment_context or AlignLeft() - self._blocks = [] + self._blocks: List["BlockComponent"] = [] # get parameters from context self._parameter_manager.update_parameter_table(self._alignment_context) @@ -1001,14 +1001,14 @@ def is_schedulable(self) -> bool: return False return True - @property + @property # type: ignore @_require_schedule_conversion def duration(self) -> int: """Duration of this schedule block.""" return self.duration @property - def channels(self) -> Tuple[Channel]: + def channels(self) -> Tuple[Channel, ...]: """Returns channels that this schedule clock uses.""" chans = set() for block in self.blocks: @@ -1016,7 +1016,7 @@ def channels(self) -> Tuple[Channel]: chans.add(chan) return tuple(chans) - @property + @property # type: ignore @_require_schedule_conversion def instructions(self) -> Tuple[Tuple[int, Instruction]]: """Get the time-ordered instructions from self.""" @@ -1245,7 +1245,7 @@ def __len__(self) -> int: """Return number of instructions in the schedule.""" return len(self.blocks) - def __eq__(self, other: "ScheduleBlock") -> bool: + def __eq__(self, other: object) -> bool: """Test if two ScheduleBlocks are equal. Equality is checked by verifying there is an equal instruction at every time diff --git a/qiskit/pulse/transforms/canonicalization.py b/qiskit/pulse/transforms/canonicalization.py index a019de2eda27..26d27f5874db 100644 --- a/qiskit/pulse/transforms/canonicalization.py +++ b/qiskit/pulse/transforms/canonicalization.py @@ -23,6 +23,7 @@ from qiskit.pulse.instruction_schedule_map import InstructionScheduleMap from qiskit.pulse.instructions import directives from qiskit.pulse.schedule import Schedule, ScheduleBlock, ScheduleComponent +from qiskit.pulse.library import Pulse def block_to_schedule(block: ScheduleBlock) -> Schedule: @@ -85,7 +86,7 @@ def compress_pulses(schedules: List[Schedule]) -> List[Schedule]: Returns: Compressed schedules. """ - existing_pulses = [] + existing_pulses: List[Pulse] = [] new_schedules = [] for schedule in schedules: diff --git a/qiskit/pulse/transforms/dag.py b/qiskit/pulse/transforms/dag.py index e533740ece02..79cf8029fe4d 100644 --- a/qiskit/pulse/transforms/dag.py +++ b/qiskit/pulse/transforms/dag.py @@ -10,9 +10,11 @@ # copyright notice, and modified files need to carry a notice indicating # that they have been altered from the originals. """A collection of functions to convert ScheduleBlock to DAG representation.""" +from typing import List, Tuple, Dict import retworkx as rx +from qiskit.pulse.channels import Channel from qiskit.pulse.schedule import ScheduleBlock @@ -73,7 +75,7 @@ def _sequential_allocation(block: ScheduleBlock) -> rx.PyDAG: dag_blocks = rx.PyDAG() prev_node = None - edges = [] + edges: List[Tuple[int, int]] = [] for inst in block.blocks: current_node = dag_blocks.add_node(inst) if prev_node is not None: @@ -88,8 +90,8 @@ def _parallel_allocation(block: ScheduleBlock) -> rx.PyDAG: """A helper function to create a DAG of a parallel alignment context.""" dag_blocks = rx.PyDAG() - slots = {} - edges = [] + slots: Dict[Channel, int] = {} + edges: List[Tuple[int, int]] = [] for inst in block.blocks: current_node = dag_blocks.add_node(inst) for chan in inst.channels: diff --git a/qiskit/qpy/formats.py b/qiskit/qpy/formats.py index 07e121f67705..5ed2578389a4 100644 --- a/qiskit/qpy/formats.py +++ b/qiskit/qpy/formats.py @@ -17,7 +17,6 @@ import struct from collections import namedtuple - # FILE_HEADER FILE_HEADER = namedtuple( "FILE_HEADER", @@ -27,7 +26,7 @@ FILE_HEADER_SIZE = struct.calcsize(FILE_HEADER_PACK) # CIRCUIT_HEADER_V2 -CIRCUIT_HEADER_V2 = namedtuple( +CIRCUIT_HEADER_V2 = namedtuple( # type: ignore[name-match] "HEADER", [ "name_size", @@ -44,7 +43,7 @@ CIRCUIT_HEADER_V2_SIZE = struct.calcsize(CIRCUIT_HEADER_V2_PACK) # CIRCUIT_HEADER -CIRCUIT_HEADER = namedtuple( +CIRCUIT_HEADER = namedtuple( # type: ignore[name-match] "HEADER", [ "name_size", @@ -60,7 +59,9 @@ CIRCUIT_HEADER_SIZE = struct.calcsize(CIRCUIT_HEADER_PACK) # REGISTER -REGISTER_V4 = namedtuple("REGISTER", ["type", "standalone", "size", "name_size", "in_circuit"]) +REGISTER_V4 = namedtuple( # type: ignore[name-match] + "REGISTER", ["type", "standalone", "size", "name_size", "in_circuit"] +) REGISTER_V4_PACK = "!1c?IH?" REGISTER_V4_SIZE = struct.calcsize(REGISTER_V4_PACK) @@ -86,7 +87,7 @@ CIRCUIT_INSTRUCTION_SIZE = struct.calcsize(CIRCUIT_INSTRUCTION_PACK) # CIRCUIT_INSTRUCTION_V2 -CIRCUIT_INSTRUCTION_V2 = namedtuple( +CIRCUIT_INSTRUCTION_V2 = namedtuple( # type: ignore[name-match] "CIRCUIT_INSTRUCTION", [ "name_size", @@ -111,7 +112,9 @@ CIRCUIT_INSTRUCTION_ARG_SIZE = struct.calcsize(CIRCUIT_INSTRUCTION_ARG_PACK) # SparsePauliOp List -SPARSE_PAULI_OP_LIST_ELEM = namedtuple("SPARSE_PAULI_OP_LIST_ELEMENT", ["size"]) +SPARSE_PAULI_OP_LIST_ELEM = namedtuple( # type: ignore[name-match] + "SPARSE_PAULI_OP_LIST_ELEMENT", ["size"] +) SPARSE_PAULI_OP_LIST_ELEM_PACK = "!Q" SPARSE_PAULI_OP_LIST_ELEM_SIZE = struct.calcsize(SPARSE_PAULI_OP_LIST_ELEM_PACK) @@ -129,7 +132,7 @@ CUSTOM_CIRCUIT_DEF_HEADER_SIZE = struct.calcsize(CUSTOM_CIRCUIT_DEF_HEADER_PACK) # CUSTOM_CIRCUIT_INST_DEF_V2 -CUSTOM_CIRCUIT_INST_DEF_V2 = namedtuple( +CUSTOM_CIRCUIT_INST_DEF_V2 = namedtuple( # type: ignore[name-match] "CUSTOM_CIRCUIT_INST_DEF", [ "gate_name_size", @@ -165,7 +168,7 @@ CALIBRATION_DEF_SIZE = struct.calcsize(CALIBRATION_DEF_PACK) # SCHEDULE_BLOCK binary format -SCHEDULE_BLOCK_HEADER = namedtuple( +SCHEDULE_BLOCK_HEADER = namedtuple( # type: ignore[name-match] "SCHEDULE_BLOCK", [ "name_size", @@ -223,12 +226,16 @@ PARAMETER_EXPR_SIZE = struct.calcsize(PARAMETER_EXPR_PACK) # PARAMETER_EXPR_MAP_ELEM_V3 -PARAM_EXPR_MAP_ELEM_V3 = namedtuple("PARAMETER_EXPR_MAP_ELEM", ["symbol_type", "type", "size"]) +PARAM_EXPR_MAP_ELEM_V3 = namedtuple( # type: ignore[name-match] + "PARAMETER_EXPR_MAP_ELEM", ["symbol_type", "type", "size"] +) PARAM_EXPR_MAP_ELEM_V3_PACK = "!ccQ" PARAM_EXPR_MAP_ELEM_V3_SIZE = struct.calcsize(PARAM_EXPR_MAP_ELEM_V3_PACK) # PARAMETER_EXPR_MAP_ELEM -PARAM_EXPR_MAP_ELEM = namedtuple("PARAMETER_EXPR_MAP_ELEM", ["type", "size"]) +PARAM_EXPR_MAP_ELEM = namedtuple( # type: ignore[name-match] + "PARAMETER_EXPR_MAP_ELEM", ["type", "size"] +) PARAM_EXPR_MAP_ELEM_PACK = "!cQ" PARAM_EXPR_MAP_ELEM_SIZE = struct.calcsize(PARAM_EXPR_MAP_ELEM_PACK) diff --git a/qiskit/quantum_info/operators/symplectic/sparse_pauli_op.py b/qiskit/quantum_info/operators/symplectic/sparse_pauli_op.py index 93416dbb80bd..e901978cc2d7 100644 --- a/qiskit/quantum_info/operators/symplectic/sparse_pauli_op.py +++ b/qiskit/quantum_info/operators/symplectic/sparse_pauli_op.py @@ -172,7 +172,7 @@ def __len__(self): # pylint: disable=bad-docstring-quotes - @property + @property # type: ignore @deprecate_function( "The SparsePauliOp.table method is deprecated as of Qiskit Terra 0.19.0 " "and will be removed no sooner than 3 months after the releasedate. " @@ -182,7 +182,7 @@ def table(self): """DEPRECATED - Return the the PauliTable.""" return PauliTable(np.column_stack((self.paulis.x, self.paulis.z))) - @table.setter + @table.setter # type: ignore @deprecate_function( "The SparsePauliOp.table method is deprecated as of Qiskit Terra 0.19.0 " "and will be removed no sooner than 3 months after the releasedate. " diff --git a/qiskit/quantum_info/states/statevector.py b/qiskit/quantum_info/states/statevector.py index 618d866097a6..226570b40e6e 100644 --- a/qiskit/quantum_info/states/statevector.py +++ b/qiskit/quantum_info/states/statevector.py @@ -74,7 +74,7 @@ def __init__(self, data, dims=None): if isinstance(data, (list, np.ndarray)): # Finally we check if the input is a raw vector in either a # python list or numpy array format. - self._data = np.asarray(data, dtype=complex) + self._data: np.ndarray = np.asarray(data, dtype=complex) elif isinstance(data, Statevector): self._data = data._data if dims is None: @@ -225,7 +225,7 @@ def __len__(self): return len(self._data) @property - def data(self): + def data(self) -> np.ndarray: """Return data.""" return self._data @@ -238,7 +238,7 @@ def is_valid(self, atol=None, rtol=None): norm = np.linalg.norm(self.data) return np.allclose(norm, 1, rtol=rtol, atol=atol) - def to_operator(self): + def to_operator(self) -> Operator: """Convert state to a rank-1 projector operator""" mat = np.outer(self.data, np.conj(self.data)) return Operator(mat, input_dims=self.dims(), output_dims=self.dims()) diff --git a/qiskit/result/mitigation/correlated_readout_mitigator.py b/qiskit/result/mitigation/correlated_readout_mitigator.py index a2d4fd359676..985c2b2d3ee9 100644 --- a/qiskit/result/mitigation/correlated_readout_mitigator.py +++ b/qiskit/result/mitigation/correlated_readout_mitigator.py @@ -13,7 +13,7 @@ Readout mitigator class based on the A-matrix inversion method """ -from typing import Optional, List, Tuple, Iterable, Callable, Union, Dict +from typing import Optional, List, Tuple, Iterable, Callable, Union, Dict, Collection import numpy as np from qiskit.exceptions import QiskitError @@ -33,7 +33,7 @@ class CorrelatedReadoutMitigator(BaseReadoutMitigator): :math:`2^N x 2^N` so the mitigation complexity is :math:`O(4^N)`. """ - def __init__(self, assignment_matrix: np.ndarray, qubits: Optional[Iterable[int]] = None): + def __init__(self, assignment_matrix: np.ndarray, qubits: Optional[Collection[int]] = None): """Initialize a CorrelatedReadoutMitigator Args: @@ -60,7 +60,7 @@ def __init__(self, assignment_matrix: np.ndarray, qubits: Optional[Iterable[int] self._num_qubits = len(self._qubits) self._qubit_index = dict(zip(self._qubits, range(self._num_qubits))) self._assignment_mat = assignment_matrix - self._mitigation_mats = {} + self._mitigation_mats: Dict[Tuple[int, ...], np.ndarray] = {} @property def settings(self) -> Dict: @@ -133,7 +133,7 @@ def quasi_probabilities( data: Counts, qubits: Optional[List[int]] = None, clbits: Optional[List[int]] = None, - shots: Optional[bool] = False, + shots: Optional[bool] = False, # TODO: unused? ) -> QuasiDistribution: """Compute mitigated quasi probabilities value. diff --git a/qiskit/result/mitigation/local_readout_mitigator.py b/qiskit/result/mitigation/local_readout_mitigator.py index 3d55ed0887ba..d81dcd7c9fc6 100644 --- a/qiskit/result/mitigation/local_readout_mitigator.py +++ b/qiskit/result/mitigation/local_readout_mitigator.py @@ -14,7 +14,7 @@ """ -from typing import Optional, List, Tuple, Iterable, Callable, Union, Dict +from typing import Optional, List, Tuple, Callable, Union, Dict, Collection, Sequence import numpy as np from qiskit.exceptions import QiskitError @@ -39,7 +39,7 @@ class LocalReadoutMitigator(BaseReadoutMitigator): def __init__( self, assignment_matrices: Optional[List[np.ndarray]] = None, - qubits: Optional[Iterable[int]] = None, + qubits: Optional[Collection[int]] = None, backend=None, ): """Initialize a LocalReadoutMitigator @@ -100,7 +100,7 @@ def expectation_value( self, data: Counts, diagonal: Union[Callable, dict, str, np.ndarray] = None, - qubits: Iterable[int] = None, + qubits: Optional[Collection[int]] = None, clbits: Optional[List[int]] = None, shots: Optional[int] = None, ) -> Tuple[float, float]: @@ -167,9 +167,9 @@ def expectation_value( def quasi_probabilities( self, data: Counts, - qubits: Optional[List[int]] = None, - clbits: Optional[List[int]] = None, - shots: Optional[bool] = False, + qubits: Optional[Sequence[int]] = None, + clbits: Optional[Sequence[int]] = None, + shots: Optional[bool] = False, # TODO: unused? ) -> QuasiDistribution: """Compute mitigated quasi probabilities value. @@ -274,7 +274,7 @@ def _compute_gamma(self, qubits=None): gammas = self._gammas[qubit_indices] return np.product(gammas) - def stddev_upper_bound(self, shots: int, qubits: List[int] = None): + def stddev_upper_bound(self, shots: int, qubits: Optional[Collection[int]] = None): """Return an upper bound on standard deviation of expval estimator. Args: diff --git a/qiskit/result/mitigation/utils.py b/qiskit/result/mitigation/utils.py index 085ffebe0872..f15b2389a893 100644 --- a/qiskit/result/mitigation/utils.py +++ b/qiskit/result/mitigation/utils.py @@ -32,7 +32,7 @@ def z_diagonal(dim, dtype=float): return (-1) ** np.mod(parity, 2) -def expval_with_stddev(coeffs: np.ndarray, probs: np.ndarray, shots: int) -> Tuple[float, float]: +def expval_with_stddev(coeffs: np.ndarray, probs: np.ndarray, shots: int) -> List[float]: """Compute expectation value and standard deviation. Args: coeffs: array of diagonal operator coefficients. diff --git a/qiskit/scheduler/lowering.py b/qiskit/scheduler/lowering.py index 4eb4b14b1078..fc80091f11da 100644 --- a/qiskit/scheduler/lowering.py +++ b/qiskit/scheduler/lowering.py @@ -60,7 +60,7 @@ def lower_gates(circuit: QuantumCircuit, schedule_config: ScheduleConfig) -> Lis circ_pulse_defs = [] inst_map = schedule_config.inst_map - qubit_mem_slots = {} # Map measured qubit index to classical bit index + qubit_mem_slots: Dict[int, int] = {} # Map measured qubit index to classical bit index # convert the unit of durations from SI to dt before lowering circuit = convert_durations_to_dt(circuit, dt_in_sec=schedule_config.dt, inplace=False) @@ -69,7 +69,7 @@ def get_measure_schedule(qubit_mem_slots: Dict[int, int]) -> CircuitPulseDef: """Create a schedule to measure the qubits queued for measuring.""" sched = Schedule() # Exclude acquisition on these qubits, since they are handled by the user calibrations - acquire_excludes = {} + acquire_excludes: Dict[int, int] = {} if Measure().name in circuit.calibrations.keys(): qubits = tuple(sorted(qubit_mem_slots.keys())) params = () diff --git a/qiskit/transpiler/basepasses.py b/qiskit/transpiler/basepasses.py index 5e006d16c8da..a39dcdb86185 100644 --- a/qiskit/transpiler/basepasses.py +++ b/qiskit/transpiler/basepasses.py @@ -15,6 +15,8 @@ from abc import abstractmethod from collections.abc import Hashable from inspect import signature +from typing import TypeVar + from .propertyset import PropertySet @@ -149,6 +151,9 @@ def __call__(self, circuit, property_set=None): return result_circuit +TBasePass = TypeVar("TBasePass", bound=BasePass) + + class AnalysisPass(BasePass): # pylint: disable=abstract-method """An analysis pass: change property set, not DAG.""" diff --git a/qiskit/transpiler/instruction_durations.py b/qiskit/transpiler/instruction_durations.py index a13d6e6e5629..15bf6d4a66ae 100644 --- a/qiskit/transpiler/instruction_durations.py +++ b/qiskit/transpiler/instruction_durations.py @@ -12,7 +12,7 @@ """Durations of instructions, one of transpiler configurations.""" import warnings -from typing import Optional, List, Tuple, Union, Iterable, Set +from typing import Optional, List, Tuple, Union, Iterable, Set, Dict from qiskit.circuit import Barrier, Delay from qiskit.circuit import Instruction, Qubit, ParameterExpression @@ -37,9 +37,11 @@ class InstructionDurations: def __init__( self, instruction_durations: Optional["InstructionDurationsType"] = None, dt: float = None ): - self.duration_by_name = {} - self.duration_by_name_qubits = {} - self.duration_by_name_qubits_params = {} + self.duration_by_name: Dict[str, Tuple[float, str]] = {} + self.duration_by_name_qubits: Dict[Tuple[str, Tuple[int, ...]], Tuple[float, str]] = {} + self.duration_by_name_qubits_params: Dict[ + Tuple[str, Tuple[int, ...], Tuple[float, ...]], Tuple[float, str] + ] = {} self.dt = dt if instruction_durations: self.update(instruction_durations) @@ -161,7 +163,7 @@ def update(self, inst_durations: Optional["InstructionDurationsType"], dt: float def get( self, inst: Union[str, Instruction], - qubits: Union[int, List[int], Qubit, List[Qubit]], + qubits: Union[int, List[int], Qubit, List[Qubit], List[Union[int, Qubit]]], unit: str = "dt", parameters: Optional[List[float]] = None, ) -> float: diff --git a/qiskit/transpiler/layout.py b/qiskit/transpiler/layout.py index 139b566734d4..64e9ebcf115f 100644 --- a/qiskit/transpiler/layout.py +++ b/qiskit/transpiler/layout.py @@ -17,6 +17,7 @@ Virtual (qu)bits are tuples, e.g. `(QuantumRegister(3, 'qr'), 2)` or simply `qr[2]`. Physical (qu)bits are integers. """ +from typing import List from qiskit.circuit.quantumregister import Qubit, QuantumRegister from qiskit.transpiler.exceptions import LayoutError @@ -251,7 +252,7 @@ def combine_into_edge_map(self, another_layout): return edge_map - def reorder_bits(self, bits): + def reorder_bits(self, bits) -> List[int]: """Given an ordered list of bits, reorder them according to this layout. The list of bits must exactly match the virtual bits in this layout. diff --git a/qiskit/transpiler/passes/basis/decompose.py b/qiskit/transpiler/passes/basis/decompose.py index 10eff7252b0e..253c11e3bca9 100644 --- a/qiskit/transpiler/passes/basis/decompose.py +++ b/qiskit/transpiler/passes/basis/decompose.py @@ -46,7 +46,7 @@ def __init__( self.gates_to_decompose = gates_to_decompose @property - def gate(self) -> Gate: + def gate(self) -> Type[Gate]: """Returns the gate""" warnings.warn( "The gate argument is deprecated as of qiskit-terra 0.19.0, and " diff --git a/qiskit/transpiler/passes/calibration/builders.py b/qiskit/transpiler/passes/calibration/builders.py index 29af85f17d55..ba8e940b65c7 100644 --- a/qiskit/transpiler/passes/calibration/builders.py +++ b/qiskit/transpiler/passes/calibration/builders.py @@ -13,7 +13,7 @@ """Calibration creators.""" from abc import abstractmethod -from typing import List, Union +from typing import List, Union, Tuple import math import numpy as np @@ -313,7 +313,7 @@ class RZXCalibrationBuilderNoEcho(RZXCalibrationBuilder): """ @staticmethod - def _filter_control(inst: (int, Union["Schedule", PulseInst])) -> bool: + def _filter_control(inst: Tuple[int, Union["Schedule", PulseInst]]) -> bool: """ Looks for Gaussian square pulses applied to control channels. @@ -333,7 +333,7 @@ def _filter_control(inst: (int, Union["Schedule", PulseInst])) -> bool: return False @staticmethod - def _filter_drive(inst: (int, Union["Schedule", PulseInst])) -> bool: + def _filter_drive(inst: Tuple[int, Union["Schedule", PulseInst]]) -> bool: """ Looks for Gaussian square pulses applied to drive channels. diff --git a/qiskit/transpiler/passes/optimization/_gate_extension.py b/qiskit/transpiler/passes/optimization/_gate_extension.py index 71e1d6f1f205..52364d6a4c3d 100644 --- a/qiskit/transpiler/passes/optimization/_gate_extension.py +++ b/qiskit/transpiler/passes/optimization/_gate_extension.py @@ -29,52 +29,56 @@ # FLIP GATES # # XGate - XGate._postconditions = lambda self, x1, y1: y1 == z3.Not(x1) - CXGate._postconditions = lambda self, x1, y1: y1 == z3.Not(x1) - CCXGate._postconditions = lambda self, x1, y1: y1 == z3.Not(x1) + XGate._postconditions = lambda self, x1, y1: y1 == z3.Not(x1) # type: ignore[attr-defined] + CXGate._postconditions = lambda self, x1, y1: y1 == z3.Not(x1) # type: ignore[attr-defined] + CCXGate._postconditions = lambda self, x1, y1: y1 == z3.Not(x1) # type: ignore[attr-defined] # YGate - YGate._postconditions = lambda self, x1, y1: y1 == z3.Not(x1) - CYGate._postconditions = lambda self, x1, y1: y1 == z3.Not(x1) + YGate._postconditions = lambda self, x1, y1: y1 == z3.Not(x1) # type: ignore[attr-defined] + CYGate._postconditions = lambda self, x1, y1: y1 == z3.Not(x1) # type: ignore[attr-defined] # PHASE GATES # # IdGate - IGate._postconditions = lambda self, x1, y1: y1 == x1 + IGate._postconditions = lambda self, x1, y1: y1 == x1 # type: ignore[attr-defined] # ZGate - ZGate._trivial_if = lambda self, x1: True - ZGate._postconditions = lambda self, x1, y1: y1 == x1 - CZGate._trivial_if = lambda self, x1: True - CZGate._postconditions = lambda self, x1, y1: y1 == x1 + ZGate._trivial_if = lambda self, x1: True # type: ignore[attr-defined] + ZGate._postconditions = lambda self, x1, y1: y1 == x1 # type: ignore[attr-defined] + CZGate._trivial_if = lambda self, x1: True # type: ignore[attr-defined] + CZGate._postconditions = lambda self, x1, y1: y1 == x1 # type: ignore[attr-defined] # SGate - SGate._trivial_if = lambda self, x1: True - SGate._postconditions = lambda self, x1, y1: y1 == x1 - SdgGate._trivial_if = lambda self, x1: True - SdgGate._postconditions = lambda self, x1, y1: y1 == x1 + SGate._trivial_if = lambda self, x1: True # type: ignore[attr-defined] + SGate._postconditions = lambda self, x1, y1: y1 == x1 # type: ignore[attr-defined] + SdgGate._trivial_if = lambda self, x1: True # type: ignore[attr-defined] + SdgGate._postconditions = lambda self, x1, y1: y1 == x1 # type: ignore[attr-defined] # TGate - TGate._trivial_if = lambda self, x1: True - TGate._postconditions = lambda self, x1, y1: y1 == x1 - TdgGate._trivial_if = lambda self, x1: True - TdgGate._postconditions = lambda self, x1, y1: y1 == x1 + TGate._trivial_if = lambda self, x1: True # type: ignore[attr-defined] + TGate._postconditions = lambda self, x1, y1: y1 == x1 # type: ignore[attr-defined] + TdgGate._trivial_if = lambda self, x1: True # type: ignore[attr-defined] + TdgGate._postconditions = lambda self, x1, y1: y1 == x1 # type: ignore[attr-defined] # RzGate - RZGate._trivial_if = lambda self, x1: True - RZGate._postconditions = lambda self, x1, y1: y1 == x1 - CRZGate._postconditions = lambda self, x1, y1: y1 == x1 + RZGate._trivial_if = lambda self, x1: True # type: ignore[attr-defined] + RZGate._postconditions = lambda self, x1, y1: y1 == x1 # type: ignore[attr-defined] + CRZGate._postconditions = lambda self, x1, y1: y1 == x1 # type: ignore[attr-defined] # U1Gate - U1Gate._trivial_if = lambda self, x1: True - U1Gate._postconditions = lambda self, x1, y1: y1 == x1 - CU1Gate._trivial_if = lambda self, x1: True - CU1Gate._postconditions = lambda self, x1, y1: y1 == x1 - MCU1Gate._trivial_if = lambda self, x1: True - MCU1Gate._postconditions = lambda self, x1, y1: y1 == x1 + U1Gate._trivial_if = lambda self, x1: True # type: ignore[attr-defined] + U1Gate._postconditions = lambda self, x1, y1: y1 == x1 # type: ignore[attr-defined] + CU1Gate._trivial_if = lambda self, x1: True # type: ignore[attr-defined] + CU1Gate._postconditions = lambda self, x1, y1: y1 == x1 # type: ignore[attr-defined] + MCU1Gate._trivial_if = lambda self, x1: True # type: ignore[attr-defined] + MCU1Gate._postconditions = lambda self, x1, y1: y1 == x1 # type: ignore[attr-defined] # MULTI-QUBIT GATES # # SwapGate - SwapGate._trivial_if = lambda self, x1, x2: x1 == x2 - SwapGate._postconditions = lambda self, x1, x2, y1, y2: z3.And(x1 == y2, x2 == y1) - CSwapGate._trivial_if = lambda self, x1, x2: x1 == x2 - CSwapGate._postconditions = lambda self, x1, x2, y1, y2: z3.And(x1 == y2, x2 == y1) + SwapGate._trivial_if = lambda self, x1, x2: x1 == x2 # type: ignore[attr-defined] + SwapGate._postconditions = lambda self, x1, x2, y1, y2: z3.And( # type: ignore[attr-defined] + x1 == y2, x2 == y1 + ) + CSwapGate._trivial_if = lambda self, x1, x2: x1 == x2 # type: ignore[attr-defined] + CSwapGate._postconditions = lambda self, x1, x2, y1, y2: z3.And( # type: ignore[attr-defined] + x1 == y2, x2 == y1 + ) diff --git a/qiskit/transpiler/passes/routing/algorithms/util.py b/qiskit/transpiler/passes/routing/algorithms/util.py index 096b9fd11f03..1670fdb6cfbf 100644 --- a/qiskit/transpiler/passes/routing/algorithms/util.py +++ b/qiskit/transpiler/passes/routing/algorithms/util.py @@ -26,7 +26,7 @@ """Utility functions shared between permutation functionality.""" -from typing import List, TypeVar, Iterable, MutableMapping +from typing import List, TypeVar, Iterable, MutableMapping, Optional from qiskit.circuit import QuantumRegister from qiskit.dagcircuit import DAGCircuit diff --git a/qiskit/transpiler/passes/routing/commuting_2q_gate_routing/commuting_2q_gate_router.py b/qiskit/transpiler/passes/routing/commuting_2q_gate_routing/commuting_2q_gate_router.py index eb1c3bbcfa98..1560672f8cb0 100644 --- a/qiskit/transpiler/passes/routing/commuting_2q_gate_routing/commuting_2q_gate_router.py +++ b/qiskit/transpiler/passes/routing/commuting_2q_gate_routing/commuting_2q_gate_router.py @@ -11,9 +11,8 @@ # that they have been altered from the originals. """A swap strategy pass for blocks of commuting gates.""" - from collections import defaultdict -from typing import Dict, List, Optional, Tuple +from typing import Any, Dict, List, Optional, Tuple from qiskit.circuit import Gate, QuantumCircuit from qiskit.converters import circuit_to_dag @@ -114,7 +113,7 @@ def __init__(self, swap_strategy: Optional[SwapStrategy] = None) -> None: """ super().__init__() self._swap_strategy = swap_strategy - self._bit_indices = None + self._bit_indices: Dict[Any, Any] = None def run(self, dag: DAGCircuit) -> DAGCircuit: """Run the pass by decomposing the nodes it applies on. @@ -192,7 +191,7 @@ def _compose_non_swap_nodes( """ # Add all the non-swap strategy nodes that we have accumulated up to now. order = layout.reorder_bits(new_dag.qubits) - order_bits = [None] * len(layout) + order_bits: List[Optional[int]] = [None] * len(layout) for idx, val in enumerate(order): order_bits[val] = idx @@ -310,7 +309,7 @@ def _make_op_layers( ) -> Dict[int, Dict[tuple, Gate]]: """Creates layers of two-qubit gates based on the distance in the swap strategy.""" - gate_layers = defaultdict(dict) + gate_layers: Dict[int, Dict[tuple, Gate]] = defaultdict(dict) for node in op.node_block: edge = (self._bit_indices[node.qargs[0]], self._bit_indices[node.qargs[1]]) diff --git a/qiskit/transpiler/passes/routing/commuting_2q_gate_routing/swap_strategy.py b/qiskit/transpiler/passes/routing/commuting_2q_gate_routing/swap_strategy.py index 5870d2ca3f64..35f9f96acc33 100644 --- a/qiskit/transpiler/passes/routing/commuting_2q_gate_routing/swap_strategy.py +++ b/qiskit/transpiler/passes/routing/commuting_2q_gate_routing/swap_strategy.py @@ -66,9 +66,9 @@ def __init__( self._coupling_map = coupling_map self._num_vertices = coupling_map.size() self._swap_layers = swap_layers - self._distance_matrix = None - self._possible_edges = None - self._missing_couplings = None + self._distance_matrix: Optional[np.ndarray] = None + self._possible_edges: Optional[Set[Tuple[int, int]]] = None + self._missing_couplings: Optional[Set[Tuple[int, int]]] = None self._inverse_composed_permutation = {0: list(range(self._num_vertices))} edge_set = set(self._coupling_map.get_edges()) @@ -164,7 +164,7 @@ def swap_layer(self, idx: int) -> List[Tuple[int, int]]: return list(self._swap_layers[idx]) @property - def distance_matrix(self) -> np.array: + def distance_matrix(self) -> np.ndarray: """A matrix describing when qubits become adjacent in the swap strategy. Returns: diff --git a/qiskit/transpiler/passes/routing/layout_transformation.py b/qiskit/transpiler/passes/routing/layout_transformation.py index 3898d2f8256c..cf5f116ee55c 100644 --- a/qiskit/transpiler/passes/routing/layout_transformation.py +++ b/qiskit/transpiler/passes/routing/layout_transformation.py @@ -11,7 +11,7 @@ # that they have been altered from the originals. """Map (with minimum effort) a DAGCircuit onto a `coupling_map` adding swap gates.""" -from typing import Union +from typing import Union, Optional import numpy as np @@ -33,7 +33,7 @@ def __init__( coupling_map: CouplingMap, from_layout: Union[Layout, str], to_layout: Union[Layout, str], - seed: Union[int, np.random.default_rng] = None, + seed: Optional[Union[int, np.random.Generator]] = None, trials=4, ): """LayoutTransformation initializer. @@ -50,7 +50,7 @@ def __init__( The final layout of qubits on physical qubits. If the type is str, look up `property_set` when this pass runs. - seed (Union[int, np.random.default_rng]): + seed (Optional[Union[int, np.random.Generator]]): Seed to use for random trials. trials (int): diff --git a/qiskit/transpiler/passes/scheduling/alignments/align_measures.py b/qiskit/transpiler/passes/scheduling/alignments/align_measures.py index 73ecf3e19de7..925619a71dac 100644 --- a/qiskit/transpiler/passes/scheduling/alignments/align_measures.py +++ b/qiskit/transpiler/passes/scheduling/alignments/align_measures.py @@ -14,7 +14,9 @@ import itertools import warnings from collections import defaultdict -from typing import List, Union +from typing import List, Union, Dict + +from qiskit.circuit.quantumcircuit import ClbitSpecifier, QubitSpecifier from qiskit.circuit.delay import Delay from qiskit.circuit.instruction import Instruction @@ -139,10 +141,12 @@ def run(self, dag: DAGCircuit): # * pad_with_delay is called only with non-delay node to avoid consecutive delay new_dag = dag.copy_empty_like() - qubit_time_available = defaultdict(int) # to track op start time - qubit_stop_times = defaultdict(int) # to track delay start time for padding - clbit_readable = defaultdict(int) - clbit_writeable = defaultdict(int) + qubit_time_available: Dict[QubitSpecifier, int] = defaultdict(int) # to track op start time + qubit_stop_times: Dict[QubitSpecifier, int] = defaultdict( + int + ) # to track delay start time for padding + clbit_readable: Dict[ClbitSpecifier, int] = defaultdict(int) + clbit_writeable: Dict[ClbitSpecifier, int] = defaultdict(int) def pad_with_delays(qubits: List[int], until, unit) -> None: """Pad idle time-slots in ``qubits`` with delays in ``unit`` until ``until``.""" diff --git a/qiskit/transpiler/passes/scheduling/padding/dynamical_decoupling.py b/qiskit/transpiler/passes/scheduling/padding/dynamical_decoupling.py index d19727d469a1..edaa842e288f 100644 --- a/qiskit/transpiler/passes/scheduling/padding/dynamical_decoupling.py +++ b/qiskit/transpiler/passes/scheduling/padding/dynamical_decoupling.py @@ -12,7 +12,7 @@ """Dynamical Decoupling insertion pass.""" -from typing import List, Optional +from typing import List, Optional, Dict import numpy as np from qiskit.circuit import Qubit, Gate @@ -158,7 +158,7 @@ def __init__( self._spacing = spacing self._extra_slack_distribution = extra_slack_distribution - self._dd_sequence_lengths = dict() + self._dd_sequence_lengths: Dict[Qubit, List[float]] = dict() self._sequence_phase = 0 def _pre_runhook(self, dag: DAGCircuit): diff --git a/qiskit/transpiler/passes/synthesis/plugin.py b/qiskit/transpiler/passes/synthesis/plugin.py index 33f168319ced..071bd8702a58 100644 --- a/qiskit/transpiler/passes/synthesis/plugin.py +++ b/qiskit/transpiler/passes/synthesis/plugin.py @@ -184,7 +184,7 @@ class UnitarySynthesisPlugin(abc.ABC): This abstract class defines the interface for unitary synthesis plugins. """ - @property + @property # type: ignore @abc.abstractmethod def max_qubits(self): """Return the maximum number of qubits the unitary synthesis plugin supports. @@ -196,7 +196,7 @@ def max_qubits(self): """ pass - @property + @property # type: ignore @abc.abstractmethod def min_qubits(self): """Return the minimum number of qubits the unitary synthesis plugin supports. @@ -208,7 +208,7 @@ def min_qubits(self): """ pass - @property + @property # type: ignore @abc.abstractmethod def supports_basis_gates(self): """Return whether the plugin supports taking ``basis_gates`` @@ -218,7 +218,7 @@ def supports_basis_gates(self): backend supports. For example, ``['sx', 'x', 'cx', 'id', 'rz']``.""" pass - @property + @property # type: ignore @abc.abstractmethod def supports_coupling_map(self): """Return whether the plugin supports taking ``coupling_map`` @@ -234,7 +234,7 @@ def supports_coupling_map(self): """ pass - @property + @property # type: ignore @abc.abstractmethod def supports_natural_direction(self): """Return whether the plugin supports a toggle for considering @@ -245,7 +245,7 @@ def supports_natural_direction(self): """ pass - @property + @property # type: ignore @abc.abstractmethod def supports_pulse_optimize(self): """Return whether the plugin supports a toggle to optimize pulses @@ -256,7 +256,7 @@ def supports_pulse_optimize(self): """ pass - @property + @property # type: ignore @abc.abstractmethod def supports_gate_lengths(self): """Return whether the plugin supports taking ``gate_lengths`` @@ -277,7 +277,7 @@ def supports_gate_lengths(self): """ pass - @property + @property # type: ignore @abc.abstractmethod def supports_gate_errors(self): """Return whether the plugin supports taking ``gate_errors`` @@ -298,7 +298,7 @@ def supports_gate_errors(self): """ pass - @property + @property # type: ignore @abc.abstractmethod def supported_bases(self): """Returns a dictionary of supported bases for synthesis diff --git a/qiskit/transpiler/passes/synthesis/unitary_synthesis.py b/qiskit/transpiler/passes/synthesis/unitary_synthesis.py index 752515c7bd77..569e1278c8f4 100644 --- a/qiskit/transpiler/passes/synthesis/unitary_synthesis.py +++ b/qiskit/transpiler/passes/synthesis/unitary_synthesis.py @@ -13,7 +13,7 @@ """Synthesize UnitaryGates.""" from math import pi, inf -from typing import List, Union +from typing import List, Union, Collection, Dict from copy import deepcopy from itertools import product @@ -35,6 +35,7 @@ RZXGate, ECRGate, ) +from qiskit.circuit.quantumregister import Qubit from qiskit.transpiler.passes.synthesis import plugin from qiskit.providers.models import BackendProperties @@ -146,7 +147,7 @@ def __init__( backend_props: BackendProperties = None, pulse_optimize: Union[bool, None] = None, natural_direction: Union[bool, None] = None, - synth_gates: Union[List[str], None] = None, + synth_gates: Union[Collection[str], None] = None, method: str = "default", min_qubits: int = None, plugin_config: dict = None, @@ -259,7 +260,7 @@ def run(self, dag: DAGCircuit) -> DAGCircuit: plugin_method = DefaultUnitarySynthesis() plugin_kwargs = {"config": self._plugin_config} _gate_lengths = _gate_errors = None - dag_bit_indices = {} + dag_bit_indices: Dict[Qubit, int] = {} if self.method == "default": # If the method is the default, we only need to evaluate one set of keyword arguments. diff --git a/qiskit/transpiler/passmanager.py b/qiskit/transpiler/passmanager.py index 064579624c91..68786b292432 100644 --- a/qiskit/transpiler/passmanager.py +++ b/qiskit/transpiler/passmanager.py @@ -20,7 +20,7 @@ from qiskit.tools.parallel import parallel_map from qiskit.circuit import QuantumCircuit -from .basepasses import BasePass +from .basepasses import BasePass, TBasePass from .exceptions import TranspilerError from .runningpassmanager import RunningPassManager, FlowController @@ -28,7 +28,7 @@ class PassManager: """Manager for a set of Passes and their scheduling during transpilation.""" - def __init__(self, passes: Union[BasePass, List[BasePass]] = None, max_iteration: int = 1000): + def __init__(self, passes: Union[BasePass, List[TBasePass]] = None, max_iteration: int = 1000): """Initialize an empty `PassManager` object (with no passes scheduled). Args: @@ -40,7 +40,7 @@ def __init__(self, passes: Union[BasePass, List[BasePass]] = None, max_iteration # the pass manager's schedule of passes, including any control-flow. # Populated via PassManager.append(). - self._pass_sets = [] + self._pass_sets: List[Dict[str, Any]] = [] if passes is not None: self.append(passes) self.max_iteration = max_iteration @@ -48,7 +48,7 @@ def __init__(self, passes: Union[BasePass, List[BasePass]] = None, max_iteration def append( self, - passes: Union[BasePass, List[BasePass]], + passes: Union[BasePass, List[TBasePass]], max_iteration: int = None, **flow_controller_conditions: Any, ) -> None: @@ -81,7 +81,7 @@ def append( def replace( self, index: int, - passes: Union[BasePass, List[BasePass]], + passes: Union[BasePass, List[TBasePass]], max_iteration: int = None, **flow_controller_conditions: Any, ) -> None: @@ -161,8 +161,8 @@ def __add__(self, other): @staticmethod def _normalize_passes( - passes: Union[BasePass, List[BasePass], FlowController] - ) -> List[BasePass]: + passes: Union[BasePass, List[TBasePass], FlowController] + ) -> Union[List[TBasePass], FlowController]: if isinstance(passes, FlowController): return passes if isinstance(passes, BasePass): diff --git a/qiskit/transpiler/preset_passmanagers/level0.py b/qiskit/transpiler/preset_passmanagers/level0.py index 37aadc1c4452..acc1f61ee46f 100644 --- a/qiskit/transpiler/preset_passmanagers/level0.py +++ b/qiskit/transpiler/preset_passmanagers/level0.py @@ -14,6 +14,7 @@ Level 0 pass manager: no explicit optimization other than mapping to backend. """ +from qiskit.transpiler.basepasses import BasePass from qiskit.transpiler.passmanager_config import PassManagerConfig from qiskit.transpiler.timing_constraints import TimingConstraints @@ -78,7 +79,7 @@ def _choose_layout_condition(property_set): return not property_set["layout"] if layout_method == "trivial": - _choose_layout = TrivialLayout(coupling_map) + _choose_layout: BasePass = TrivialLayout(coupling_map) elif layout_method == "dense": _choose_layout = DenseLayout(coupling_map, backend_properties, target=target) elif layout_method == "noise_adaptive": @@ -91,7 +92,7 @@ def _choose_layout_condition(property_set): toqm_pass = False # Choose routing pass if routing_method == "basic": - routing_pass = BasicSwap(coupling_map) + routing_pass: BasePass = BasicSwap(coupling_map) elif routing_method == "stochastic": routing_pass = StochasticSwap(coupling_map, trials=20, seed=seed_transpiler) elif routing_method == "lookahead": diff --git a/qiskit/transpiler/preset_passmanagers/level1.py b/qiskit/transpiler/preset_passmanagers/level1.py index 5da52fb23052..fca62e45cf24 100644 --- a/qiskit/transpiler/preset_passmanagers/level1.py +++ b/qiskit/transpiler/preset_passmanagers/level1.py @@ -14,7 +14,7 @@ Level 1 pass manager: light optimization by simple adjacent gate collapsing. """ - +from qiskit.transpiler.basepasses import BasePass from qiskit.transpiler.passmanager_config import PassManagerConfig from qiskit.transpiler.timing_constraints import TimingConstraints from qiskit.transpiler.passmanager import PassManager @@ -136,7 +136,7 @@ def _vf2_match_not_found(property_set): ) if layout_method == "trivial": - _improve_layout = TrivialLayout(coupling_map) + _improve_layout: BasePass = TrivialLayout(coupling_map) elif layout_method == "dense": _improve_layout = DenseLayout(coupling_map, backend_properties, target=target) elif layout_method == "noise_adaptive": @@ -148,7 +148,7 @@ def _vf2_match_not_found(property_set): toqm_pass = False if routing_method == "basic": - routing_pass = BasicSwap(coupling_map) + routing_pass: BasePass = BasicSwap(coupling_map) elif routing_method == "stochastic": routing_pass = StochasticSwap(coupling_map, trials=20, seed=seed_transpiler) elif routing_method == "lookahead": diff --git a/qiskit/transpiler/preset_passmanagers/level2.py b/qiskit/transpiler/preset_passmanagers/level2.py index c2ee13ad8500..c1fda642e624 100644 --- a/qiskit/transpiler/preset_passmanagers/level2.py +++ b/qiskit/transpiler/preset_passmanagers/level2.py @@ -15,7 +15,7 @@ Level 2 pass manager: medium optimization by noise adaptive qubit mapping and gate cancellation using commutativity rules. """ - +from qiskit.transpiler.basepasses import BasePass from qiskit.transpiler.passmanager_config import PassManagerConfig from qiskit.transpiler.timing_constraints import TimingConstraints from qiskit.transpiler.passmanager import PassManager @@ -119,7 +119,7 @@ def _vf2_match_not_found(property_set): ) if layout_method == "trivial": - _choose_layout_1 = TrivialLayout(coupling_map) + _choose_layout_1: BasePass = TrivialLayout(coupling_map) elif layout_method == "dense": _choose_layout_1 = DenseLayout(coupling_map, backend_properties, target=target) elif layout_method == "noise_adaptive": @@ -131,7 +131,7 @@ def _vf2_match_not_found(property_set): toqm_pass = False if routing_method == "basic": - routing_pass = BasicSwap(coupling_map) + routing_pass: BasePass = BasicSwap(coupling_map) elif routing_method == "stochastic": routing_pass = StochasticSwap(coupling_map, trials=20, seed=seed_transpiler) elif routing_method == "lookahead": diff --git a/qiskit/transpiler/preset_passmanagers/level3.py b/qiskit/transpiler/preset_passmanagers/level3.py index 7a0f22319ecb..e5c923083a57 100644 --- a/qiskit/transpiler/preset_passmanagers/level3.py +++ b/qiskit/transpiler/preset_passmanagers/level3.py @@ -15,8 +15,9 @@ Level 3 pass manager: heavy optimization by noise adaptive qubit mapping and gate cancellation using commutativity rules and unitary synthesis. """ +from typing import List - +from qiskit.transpiler.basepasses import TBasePass, BasePass from qiskit.transpiler.passmanager_config import PassManagerConfig from qiskit.transpiler.timing_constraints import TimingConstraints from qiskit.transpiler.passmanager import PassManager @@ -126,7 +127,7 @@ def _vf2_match_not_found(property_set): ) # 2b. if VF2 didn't converge on a solution use layout_method (dense). if layout_method == "trivial": - _choose_layout_1 = TrivialLayout(coupling_map) + _choose_layout_1: BasePass = TrivialLayout(coupling_map) elif layout_method == "dense": _choose_layout_1 = DenseLayout(coupling_map, backend_properties, target=target) elif layout_method == "noise_adaptive": @@ -138,7 +139,7 @@ def _vf2_match_not_found(property_set): toqm_pass = False if routing_method == "basic": - routing_pass = BasicSwap(coupling_map) + routing_pass: BasePass = BasicSwap(coupling_map) elif routing_method == "stochastic": routing_pass = StochasticSwap(coupling_map, trials=200, seed=seed_transpiler) elif routing_method == "lookahead": @@ -174,8 +175,8 @@ def _vf2_match_not_found(property_set): # 8. Optimize iteratively until no more change in depth. Removes useless gates # after reset and before measure, commutes gates and optimizes contiguous blocks. - _depth_check = [Depth(), FixedPoint("depth")] - _size_check = [Size(), FixedPoint("size")] + _depth_check: List[TBasePass] = [Depth(), FixedPoint("depth")] + _size_check: List[TBasePass] = [Size(), FixedPoint("size")] def _opt_control(property_set): return (not property_set["depth_fixed_point"]) or (not property_set["size_fixed_point"]) diff --git a/qiskit/transpiler/runningpassmanager.py b/qiskit/transpiler/runningpassmanager.py index 6cff16cb2c03..28eb1e08ba35 100644 --- a/qiskit/transpiler/runningpassmanager.py +++ b/qiskit/transpiler/runningpassmanager.py @@ -17,10 +17,11 @@ from collections import OrderedDict import logging from time import time +from typing import List from qiskit.dagcircuit import DAGCircuit from qiskit.converters import circuit_to_dag, dag_to_circuit -from qiskit.transpiler.basepasses import BasePass +from qiskit.transpiler.basepasses import BasePass, TBasePass from .propertyset import PropertySet from .fencedobjs import FencedPropertySet, FencedDAGCircuit from .exceptions import TranspilerError @@ -57,11 +58,11 @@ def __init__(self, max_iteration): self.count = 0 - def append(self, passes, **flow_controller_conditions): + def append(self, passes: List[TBasePass], **flow_controller_conditions): """Append a Pass to the schedule of passes. Args: - passes (list[BasePass]): passes to be added to schedule + passes (List[TBasePass]): passes to be added to schedule flow_controller_conditions (kwargs): See add_flow_controller(): Dictionary of control flow plugins. Default: @@ -306,7 +307,7 @@ def controller_factory(cls, passes, options, **partial_controller): """Constructs a flow controller based on the partially evaluated controller arguments. Args: - passes (list[BasePass]): passes to add to the flow controller. + passes (List[TBasePass]): passes to add to the flow controller. options (dict): PassManager options. **partial_controller (dict): Partially evaluated controller arguments in the form `{name:partial}` diff --git a/qiskit/transpiler/synthesis/aqc/approximate.py b/qiskit/transpiler/synthesis/aqc/approximate.py index 418d766dc356..eadffec09abb 100644 --- a/qiskit/transpiler/synthesis/aqc/approximate.py +++ b/qiskit/transpiler/synthesis/aqc/approximate.py @@ -29,7 +29,7 @@ def __init__(self, num_qubits: int, name: Optional[str] = None) -> None: """ super().__init__(num_qubits, name=name) - @property + @property # type: ignore @abstractmethod def thetas(self) -> np.ndarray: """ @@ -61,7 +61,7 @@ class ApproximatingObjective(ABC): def __init__(self) -> None: # must be set before optimization - self._target_matrix = None + self._target_matrix: Optional[np.ndarray] = None @abstractmethod def objective(self, param_values: np.ndarray) -> float: @@ -105,7 +105,7 @@ def target_matrix(self, target_matrix: np.ndarray) -> None: """ self._target_matrix = target_matrix - @property + @property # type: ignore @abstractmethod def num_thetas(self) -> int: """ diff --git a/qiskit/transpiler/synthesis/aqc/cnot_unit_circuit.py b/qiskit/transpiler/synthesis/aqc/cnot_unit_circuit.py index bfa59bef82e8..e3cdcaf12080 100644 --- a/qiskit/transpiler/synthesis/aqc/cnot_unit_circuit.py +++ b/qiskit/transpiler/synthesis/aqc/cnot_unit_circuit.py @@ -53,7 +53,7 @@ def __init__( self._tol = tol # Thetas to be optimizer by the AQC algorithm - self._thetas = None + self._thetas: Optional[np.ndarray] = None @property def thetas(self) -> np.ndarray: diff --git a/qiskit/transpiler/synthesis/aqc/cnot_unit_objective.py b/qiskit/transpiler/synthesis/aqc/cnot_unit_objective.py index bcf3590ad7cb..989d3d2e0dab 100644 --- a/qiskit/transpiler/synthesis/aqc/cnot_unit_objective.py +++ b/qiskit/transpiler/synthesis/aqc/cnot_unit_objective.py @@ -13,7 +13,9 @@ A definition of the approximate circuit compilation optimization problem based on CNOT unit definition. """ +import typing from abc import ABC +from typing import Optional import numpy as np from numpy import linalg as la @@ -68,13 +70,13 @@ def __init__(self, num_qubits: int, cnots: np.ndarray) -> None: super().__init__(num_qubits, cnots) # last objective computations to be re-used by gradient - self._last_thetas = None - self._cnot_right_collection = None - self._cnot_left_collection = None - self._rotation_matrix = None - self._cnot_matrix = None + self._last_thetas: Optional[np.ndarray] = None + self._cnot_right_collection: Optional[np.ndarray] = None + self._cnot_left_collection: Optional[np.ndarray] = None + self._rotation_matrix: Optional[typing.Union[int, np.ndarray]] = None + self._cnot_matrix: Optional[np.ndarray] = None - def objective(self, param_values: np.ndarray) -> float: + def objective(self, param_values: np.ndarray) -> typing.SupportsFloat: # rename parameters just to make shorter and make use of our dictionary thetas = param_values n = self._num_qubits @@ -143,7 +145,7 @@ def objective(self, param_values: np.ndarray) -> float: # this is the matrix corresponding to the initial rotations # we start with 1 and kronecker product each qubit's rotations - rotation_matrix = 1 + rotation_matrix: typing.Union[int, np.ndarray] = 1 for q in range(n): theta_index = 4 * num_cnots + 3 * q rz0 = rz_matrix(thetas[0 + theta_index]) @@ -268,7 +270,7 @@ def gradient(self, param_values: np.ndarray) -> np.ndarray: # now we compute the partial derivatives in the rotation part # we start with 1 and kronecker product each qubit's rotations for i in range(3 * n): - der_rotation_matrix = 1 + der_rotation_matrix: typing.Union[int, np.ndarray] = 1 for q in range(n): theta_index = 4 * num_cnots + 3 * q rz0 = rz_matrix(thetas[0 + theta_index]) diff --git a/qiskit/utils/measurement_error_mitigation.py b/qiskit/utils/measurement_error_mitigation.py index 9fca4f783921..67d18942738a 100644 --- a/qiskit/utils/measurement_error_mitigation.py +++ b/qiskit/utils/measurement_error_mitigation.py @@ -48,7 +48,7 @@ def get_measured_qubits( QiskitError: invalid qubit mapping """ qubit_index = None - qubit_mappings = {} + qubit_mappings: Dict[str, List[int]] = {} for idx, qc in enumerate(transpiled_circuits): measured_qubits = [] for instruction in qc.data: @@ -91,7 +91,7 @@ def get_measured_qubits_from_qobj(qobj: QasmQobj) -> Tuple[List[int], Dict[str, """ qubit_index = None - qubit_mappings = {} + qubit_mappings: Dict[str, List[int]] = {} for idx, exp in enumerate(qobj.experiments): measured_qubits = [] diff --git a/qiskit/utils/mitigation/_filters.py b/qiskit/utils/mitigation/_filters.py index 5fff37e230c9..7c2e1f7600c5 100644 --- a/qiskit/utils/mitigation/_filters.py +++ b/qiskit/utils/mitigation/_filters.py @@ -22,7 +22,7 @@ """ -from typing import List +from typing import List, Dict, Any from copy import deepcopy import numpy as np @@ -60,6 +60,11 @@ def cal_matrix(self): """Return cal_matrix.""" return self._cal_matrix + @cal_matrix.setter + def cal_matrix(self, new_cal_matrix): + """Set cal_matrix.""" + self._cal_matrix = new_cal_matrix + @property def state_labels(self): """return the state label ordering of the cal matrix""" @@ -70,11 +75,6 @@ def state_labels(self, new_state_labels): """set the state label ordering of the cal matrix""" self._state_labels = new_state_labels - @cal_matrix.setter - def cal_matrix(self, new_cal_matrix): - """Set cal_matrix.""" - self._cal_matrix = new_cal_matrix - def apply(self, raw_data, method="least_squares"): """Apply the calibration matrix to results. @@ -220,7 +220,7 @@ class TensoredFilter: to data. """ - def __init__(self, cal_matrices: np.matrix, substate_labels_list: list, mit_pattern: list): + def __init__(self, cal_matrices: np.matrix, substate_labels_list: List[str], mit_pattern: list): """ Initialize a tensored measurement error mitigation filter using the cal_matrices from a tensored measurement calibration fitter. @@ -236,9 +236,9 @@ def __init__(self, cal_matrices: np.matrix, substate_labels_list: list, mit_patt """ self._cal_matrices = cal_matrices - self._qubit_list_sizes = [] - self._indices_list = [] - self._substate_labels_list = [] + self._qubit_list_sizes: List[int] = [] + self._indices_list: List[Dict[Any, Any]] = [] + self._substate_labels_list: List[str] = [] self.substate_labels_list = substate_labels_list self._mit_pattern = mit_pattern diff --git a/qiskit/utils/mitigation/circuits.py b/qiskit/utils/mitigation/circuits.py index af62d1c36fa5..9be03d3d5f4b 100644 --- a/qiskit/utils/mitigation/circuits.py +++ b/qiskit/utils/mitigation/circuits.py @@ -18,7 +18,7 @@ Measurement calibration circuits. To apply the measurement mitigation use the fitters to produce a filter. """ -from typing import List, Tuple, Union +from typing import List, Tuple, Union, Any, Optional, Collection def count_keys(num_qubits: int) -> List[str]: @@ -36,11 +36,11 @@ def count_keys(num_qubits: int) -> List[str]: def complete_meas_cal( - qubit_list: List[int] = None, - qr: Union[int, List["QuantumRegister"]] = None, - cr: Union[int, List["ClassicalRegister"]] = None, + qubit_list: Optional[List[int]] = None, + qr: Optional[Union[int, List[Any]]] = None, + cr: Optional[Union[int, List[Any]]] = None, circlabel: str = "", -) -> Tuple[List["QuantumCircuit"], List[str]]: +) -> Tuple[List[Any], List[str]]: """ Return a list of measurement calibration circuits for the full Hilbert space. @@ -113,11 +113,11 @@ def complete_meas_cal( def tensored_meas_cal( - mit_pattern: List[List[int]] = None, - qr: Union[int, List["QuantumRegister"]] = None, - cr: Union[int, List["ClassicalRegister"]] = None, + mit_pattern: Optional[List[List[int]]] = None, + qr: Optional[Union[int, Collection[Any]]] = None, + cr: Optional[Union[int, Collection[Any]]] = None, circlabel: str = "", -) -> Tuple[List["QuantumCircuit"], List[List[int]]]: +) -> Tuple[List[Any], List[List[int]]]: """ Return a list of calibration circuits @@ -153,7 +153,7 @@ def tensored_meas_cal( QiskitError: if a qubit appears more than once in `mit_pattern`. """ - # Runtime imports to avoid circular imports causeed by QuantumInstance + # Runtime imports to avoid circular imports caused by QuantumInstance # getting initialized by imported utils/__init__ which is imported # by qiskit.circuit from qiskit.circuit.quantumregister import QuantumRegister diff --git a/qiskit/utils/mitigation/fitters.py b/qiskit/utils/mitigation/fitters.py index 2839f9771bcc..05468b69e2d8 100644 --- a/qiskit/utils/mitigation/fitters.py +++ b/qiskit/utils/mitigation/fitters.py @@ -18,7 +18,7 @@ """ Measurement correction fitters. """ -from typing import List +from typing import List, Any, Dict, Optional, Sequence import copy import re @@ -38,7 +38,7 @@ def __init__( self, results, state_labels: List[str], - qubit_list: List[int] = None, + qubit_list: Optional[Sequence[int]] = None, circlabel: str = "", ): """ @@ -89,16 +89,16 @@ def state_labels(self): """Return state_labels.""" return self._tens_fitt.substate_labels_list[0] - @property - def qubit_list(self): - """Return list of qubits.""" - return self._qubit_list - @state_labels.setter def state_labels(self, new_state_labels): """Set state label.""" self._tens_fitt.substate_labels_list[0] = new_state_labels + @property + def qubit_list(self): + """Return list of qubits.""" + return self._qubit_list + @property def filter(self): """Return a measurement filter using the cal matrix.""" @@ -217,7 +217,7 @@ class TensoredMeasFitter: def __init__( self, results, - mit_pattern: List[List[int]], + mit_pattern: List[Sequence[int]], substate_labels_list: List[List[str]] = None, circlabel: str = "", ): @@ -254,14 +254,14 @@ def __init__( substate_labels_list """ - self._result_list = [] + self._result_list: List[Any] = [] self._cal_matrices = None self._circlabel = circlabel self._mit_pattern = mit_pattern self._qubit_list_sizes = [len(qubit_list) for qubit_list in mit_pattern] - self._indices_list = [] + self._indices_list: List[Dict[Any, Any]] = [] if substate_labels_list is None: self._substate_labels_list = [] for list_size in self._qubit_list_sizes: diff --git a/qiskit/utils/quantum_instance.py b/qiskit/utils/quantum_instance.py index 5982ac0ec5c8..1149b5761686 100644 --- a/qiskit/utils/quantum_instance.py +++ b/qiskit/utils/quantum_instance.py @@ -12,7 +12,7 @@ """ Quantum Instance module """ -from typing import Optional, List, Union, Dict, Callable, Tuple +from typing import Optional, List, Union, Dict, Callable, Tuple, Any from enum import Enum import copy import logging @@ -250,7 +250,7 @@ def __init__( if isinstance(backend, Backend): if hasattr(backend, "options"): # should always be true for V1 - backend_shots = backend.options.get("shots", 1024) + backend_shots = backend.options.get("shots", 1024) # type: ignore[attr-defined] if shots != backend_shots: logger.info( "Overwriting the number of shots in the quantum instance with " @@ -332,7 +332,7 @@ def __init__( ) else: self._meas_error_mitigation_cls = measurement_error_mitigation_cls - self._meas_error_mitigation_fitters: Dict[str, Tuple[np.ndarray, float]] = {} + self._meas_error_mitigation_fitters: Dict[str, Tuple[Any, float]] = {} # TODO: support different fitting method in error mitigation? self._meas_error_mitigation_method = "least_squares" self._cals_matrix_refresh_period = cals_matrix_refresh_period diff --git a/qiskit/utils/units.py b/qiskit/utils/units.py index 76f300805c6c..e708f4caad22 100644 --- a/qiskit/utils/units.py +++ b/qiskit/utils/units.py @@ -19,7 +19,9 @@ from qiskit.circuit.parameterexpression import ParameterExpression -def apply_prefix(value: Union[float, ParameterExpression], unit: str) -> float: +def apply_prefix( + value: Union[float, ParameterExpression], unit: str +) -> Union[float, ParameterExpression]: """ Given a SI unit prefix and value, apply the prefix to convert to standard SI unit. diff --git a/qiskit/visualization/pulse/interpolation.py b/qiskit/visualization/pulse/interpolation.py index 0bb3617b65e9..3268720c6b34 100644 --- a/qiskit/visualization/pulse/interpolation.py +++ b/qiskit/visualization/pulse/interpolation.py @@ -70,7 +70,7 @@ def step_wise( samples_ = np.repeat(samples, 2) re_y_ = np.real(samples_) im_y_ = np.imag(samples_) - time__ = np.concatenate(([time[0]], np.repeat(time[1:-1], 2), [time[-1]])) + time__: np.ndarray = np.concatenate(([time[0]], np.repeat(time[1:-1], 2), [time[-1]])) return time__, re_y_, im_y_ diff --git a/qiskit/visualization/pulse/matplotlib.py b/qiskit/visualization/pulse/matplotlib.py index 06cec2a75473..0c0f24428781 100644 --- a/qiskit/visualization/pulse/matplotlib.py +++ b/qiskit/visualization/pulse/matplotlib.py @@ -15,7 +15,7 @@ """Matplotlib classes for pulse visualization.""" import collections -from typing import Dict, List, Tuple, Callable, Union, Any +from typing import Dict, List, Tuple, Callable, Union, Any, Optional, Set import numpy as np @@ -58,11 +58,11 @@ def __init__(self, t0: int, tf: int): t0: starting time of plot tf: ending time of plot """ - self.pulses = {} + self.pulses: Dict[int, Instruction] = {} self.t0 = t0 self.tf = tf - self._waveform = None + self._waveform: Optional[np.ndarray] = None self._framechanges = None self._setphase = None self._frequencychanges = None @@ -420,7 +420,7 @@ def _build_channels( control_channels = collections.OrderedDict() acquire_channels = collections.OrderedDict() snapshot_channels = collections.OrderedDict() - _channels = set() + _channels: Set[Channel] = set() if show_framechange_channels: _channels.update(schedule.channels) # take channels that do not only contain framechanges @@ -502,7 +502,7 @@ def _scale_channels( scale_dict: Scale factor of each channel. """ # count numbers of valid waveform - scale_dict = {chan: 0 for chan in output_channels.keys()} + scale_dict: Dict[Channel, float] = {chan: 0.0 for chan in output_channels.keys()} for channel, events in output_channels.items(): v_max = 0 if channels: @@ -581,7 +581,7 @@ def _draw_table(self, figure, channels: Dict[Channel, EventsOutputChannels], dt: # pylint: enable=unbalanced-tuple-unpacking time, ch_name, data_str = data # item - cell_value[r][3 * c + 0] = "t = %s" % time * dt + cell_value[r][3 * c + 0] = "t = %s" % time * dt # TODO: worng operator priority? cell_value[r][3 * c + 1] = "ch %s" % ch_name cell_value[r][3 * c + 2] = data_str table = tb.table( @@ -640,6 +640,7 @@ def _draw_framechanges(self, ax, fcs: Dict[int, ShiftPhase], y0: float) -> bool: ha="center", va="center", ) + # TODO: doesn't return anyting? def _draw_frequency_changes(self, ax, sf: Dict[int, SetFrequency], y0: float) -> bool: """Draw set frequency of given channel to given mpl axis. @@ -659,6 +660,7 @@ def _draw_frequency_changes(self, ax, sf: Dict[int, SetFrequency], y0: float) -> va="center", rotation=90, ) + # TODO: doesn't return anyting? def _get_channel_color(self, channel: Channel) -> str: """Lookup table for waveform color. @@ -769,7 +771,7 @@ def _draw_channels( Value of final vertical axis of canvas. """ y0 = 0 - prev_labels = [] + prev_labels: List[Dict[int, Union[Waveform, Acquire]]] = [] for channel, events in output_channels.items(): if events.enable: # scaling value of this channel diff --git a/qiskit/visualization/pulse/qcstyle.py b/qiskit/visualization/pulse/qcstyle.py index 678eaa1e1174..a7e7e03c19ec 100644 --- a/qiskit/visualization/pulse/qcstyle.py +++ b/qiskit/visualization/pulse/qcstyle.py @@ -44,12 +44,12 @@ def __init__( label_ch_linestyle: str = "--", label_ch_color: str = "#222222", label_ch_alpha: float = 0.3, - d_ch_color: ComplexColors = ("#648fff", "#002999"), - u_ch_color: ComplexColors = ("#ffb000", "#994A00"), - m_ch_color: ComplexColors = ("#dc267f", "#760019"), + d_ch_color: ComplexColors = ComplexColors("#648fff", "#002999"), + u_ch_color: ComplexColors = ComplexColors("#ffb000", "#994A00"), + m_ch_color: ComplexColors = ComplexColors("#dc267f", "#760019"), s_ch_color: str = "#7da781", s_ch_linestyle: str = "-", - table_color: SchedTableColors = ("#e0e0e0", "#f6f6f6", "#f6f6f6"), + table_color: SchedTableColors = SchedTableColors("#e0e0e0", "#f6f6f6", "#f6f6f6"), bg_color: str = "#f2f3f4", num_points: int = 1000, dpi: Optional[int] = 150, @@ -178,7 +178,7 @@ def __init__( self, figsize: Optional[Tuple[float, float]] = (7.0, 5.0), title_font_size: Optional[int] = 18, - wave_color: ComplexColors = ("#ff0000", "#0000ff"), + wave_color: ComplexColors = ComplexColors("#ff0000", "#0000ff"), bg_color: str = "#f2f3f4", num_points: int = 1000, dpi: Optional[int] = None, diff --git a/qiskit/visualization/pulse_v2/core.py b/qiskit/visualization/pulse_v2/core.py index b46090317e4b..202f912e16a4 100644 --- a/qiskit/visualization/pulse_v2/core.py +++ b/qiskit/visualization/pulse_v2/core.py @@ -69,7 +69,7 @@ from enum import Enum from functools import partial from itertools import chain -from typing import Union, List, Tuple, Iterator, Optional +from typing import Union, List, Tuple, Iterator, Optional, Set, Dict import numpy as np from qiskit import pulse @@ -108,18 +108,26 @@ def __init__(self, stylesheet: QiskitPulseStyle, device: device_info.DrawerBacke # chart self.global_charts = Chart(parent=self, name="global") - self.charts = [] + self.charts: List[Chart] = [] # visible controls - self.disable_chans = set() - self.disable_types = set() + self.disable_chans: Set[pulse.channels.Channel] = set() + self.disable_types: Set[str] = set() # data scaling - self.chan_scales = {} + self.chan_scales: Dict[ + Union[ + pulse.channels.DriveChannel, + pulse.channels.MeasureChannel, + pulse.channels.ControlChannel, + pulse.channels.AcquireChannel, + ], + Dict, + ] = {} # global time self._time_range = (0, 0) - self._time_breaks = [] + self._time_breaks: List[Tuple[int, int]] = [] # title self.fig_title = "" @@ -445,13 +453,13 @@ def __init__(self, parent: DrawerCanvas, name: Optional[str] = None): self.parent = parent # data stored in this channel - self._collections = {} - self._output_dataset = {} + self._collections: Dict[str, drawings.ElementaryData] = {} + self._output_dataset: Dict[str, drawings.ElementaryData] = {} # channel metadata self.index = self._cls_index() self.name = name or "" - self._channels = set() + self._channels: Set[pulse.channels.Channel] = set() # vertical axis information self.vmax = 0 diff --git a/qiskit/visualization/pulse_v2/drawings.py b/qiskit/visualization/pulse_v2/drawings.py index d6cd873dc8df..9a04f24fd245 100644 --- a/qiskit/visualization/pulse_v2/drawings.py +++ b/qiskit/visualization/pulse_v2/drawings.py @@ -101,7 +101,7 @@ def __init__( self.data_type = str(data_type) self.xvals = np.array(xvals, dtype=object) self.yvals = np.array(yvals, dtype=object) - self.channels = channels or [] + self.channels: List[Channel] = channels or [] self.meta = meta or {} self.ignore_scaling = ignore_scaling self.styles = styles or {} diff --git a/qiskit/visualization/pulse_v2/events.py b/qiskit/visualization/pulse_v2/events.py index 5e250ae62996..ecc1a062645a 100644 --- a/qiskit/visualization/pulse_v2/events.py +++ b/qiskit/visualization/pulse_v2/events.py @@ -158,6 +158,7 @@ def set_config(self, dt: float, init_frequency: float, init_phase: float): init_frequency: Modulation frequency in Hz. init_phase: Initial phase in rad. """ + # TODO: should be float? self._dt = dt or 1 self._init_frequency = init_frequency or 0 self._init_phase = init_phase or 0 diff --git a/qiskit/visualization/pulse_v2/generators/waveform.py b/qiskit/visualization/pulse_v2/generators/waveform.py index c398a26a6c20..9e552df7d0df 100644 --- a/qiskit/visualization/pulse_v2/generators/waveform.py +++ b/qiskit/visualization/pulse_v2/generators/waveform.py @@ -350,11 +350,11 @@ def _draw_shaped_waveform( resolution = formatter["general.vertical_resolution"] # stepwise interpolation - xdata = np.concatenate((xdata, [xdata[-1] + 1])) + xdata: np.ndarray = np.concatenate((xdata, [xdata[-1] + 1])) ydata = np.repeat(ydata, 2) re_y = np.real(ydata) im_y = np.imag(ydata) - time = np.concatenate(([xdata[0]], np.repeat(xdata[1:-1], 2), [xdata[-1]])) + time: np.ndarray = np.concatenate(([xdata[0]], np.repeat(xdata[1:-1], 2), [xdata[-1]])) # setup style options style = { diff --git a/qiskit/visualization/pulse_v2/types.py b/qiskit/visualization/pulse_v2/types.py index 232f295fc713..ca263595ef96 100644 --- a/qiskit/visualization/pulse_v2/types.py +++ b/qiskit/visualization/pulse_v2/types.py @@ -33,7 +33,7 @@ class PhaseFreqTuple(NamedTuple): PhaseFreqTuple.freq.__doc__ = "Frequency value in Hz." -PulseInstruction = NamedTuple( +PulseInstruction = NamedTuple( # type: ignore[name-match] "InstructionTuple", [ ("t0", int), @@ -51,7 +51,7 @@ class PhaseFreqTuple(NamedTuple): PulseInstruction.is_opaque.__doc__ = "If there is any unbound parameters." -BarrierInstruction = NamedTuple( +BarrierInstruction = NamedTuple( # type: ignore[name-match] "Barrier", [("t0", int), ("dt", Optional[float]), ("channels", List[pulse.channels.Channel])] ) BarrierInstruction.__doc__ = "Data to represent special pulse instruction of barrier." @@ -60,7 +60,7 @@ class PhaseFreqTuple(NamedTuple): BarrierInstruction.channels.__doc__ = "A list of channel associated with this barrier." -SnapshotInstruction = NamedTuple( +SnapshotInstruction = NamedTuple( # type: ignore[name-match] "Snapshots", [("t0", int), ("dt", Optional[float]), ("inst", pulse.instructions.Snapshot)] ) SnapshotInstruction.__doc__ = "Data to represent special pulse instruction of snapshot." diff --git a/qiskit/visualization/timeline/core.py b/qiskit/visualization/timeline/core.py index 5cecfcdb9a65..dbb3a54f6761 100644 --- a/qiskit/visualization/timeline/core.py +++ b/qiskit/visualization/timeline/core.py @@ -51,7 +51,7 @@ import warnings from copy import deepcopy from functools import partial -from typing import Tuple, Iterator, Dict +from typing import Tuple, Iterator, Dict, Set, List from enum import Enum import numpy as np @@ -73,16 +73,16 @@ def __init__(self, stylesheet: QiskitTimelineStyle): self.layout = stylesheet.layout # drawings - self._collections = {} - self._output_dataset = {} + self._collections: Dict[str, drawings.ElementaryData] = {} + self._output_dataset: Dict[str, drawings.ElementaryData] = {} # vertical offset of bits - self.bits = [] - self.assigned_coordinates = {} + self.bits: List[types.Bits] = [] + self.assigned_coordinates: Dict[types.Bits, float] = {} # visible controls - self.disable_bits = set() - self.disable_types = set() + self.disable_bits: Set[types.Bits] = set() + self.disable_types: Set[str] = set() # time self._time_range = (0, 0) @@ -108,6 +108,11 @@ def time_range(self) -> Tuple[int, int]: return new_t0, new_t1 + @time_range.setter + def time_range(self, new_range: Tuple[int, int]): + """Update time range to draw.""" + self._time_range = new_range + @property def collections(self) -> Iterator[Tuple[str, drawings.ElementaryData]]: """Return currently active entries from drawing data collection. @@ -118,11 +123,6 @@ def collections(self) -> Iterator[Tuple[str, drawings.ElementaryData]]: """ yield from self._output_dataset.items() - @time_range.setter - def time_range(self, new_range: Tuple[int, int]): - """Update time range to draw.""" - self._time_range = new_range - def add_data(self, data: drawings.ElementaryData): """Add drawing to collections. @@ -409,7 +409,7 @@ def y_coords(link: drawings.GateLinkData): return np.array([self.assigned_coordinates.get(bit, np.nan) for bit in link.bits]) # group overlapped links - overlapped_group = [] + overlapped_group: List[List[str]] = [] data_keys = list(links.keys()) while len(data_keys) > 0: ref_key = data_keys.pop()