Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[unitaryhack] Start working on mypy errors #8187

Closed
wants to merge 38 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
2bde3a2
Start fixing mypy errors
Randl Jun 16, 2022
ca78f08
lint
Randl Jun 16, 2022
fecd5df
more type fixes, fix import error
Randl Jun 16, 2022
b07acd0
more type fixes, fix another import error
Randl Jun 16, 2022
ae1987a
additional type fixes
Randl Jun 16, 2022
517011e
lint and additional type fixes
Randl Jun 16, 2022
6a8adf7
more type fixes
Randl Jun 16, 2022
77fd960
lint and type fixes
Randl Jun 16, 2022
39bfeca
add typevar for basepass
Randl Jun 16, 2022
2b6119a
lint andadditional fixes
Randl Jun 16, 2022
e98a6a1
more fixes
Randl Jun 17, 2022
0c19518
more type fixes
Randl Jun 17, 2022
680d54f
lint and circular import fixes
Randl Jun 17, 2022
74cdcca
Add more annotations
Randl Jun 17, 2022
c3995cd
Return import
Randl Jun 17, 2022
44b401d
Additional fixes
Randl Jun 17, 2022
06a7fa3
Ignore decorated properties (https://github.com/python/mypy/issues/1362)
Randl Jun 17, 2022
27e225c
small fix
Randl Jun 17, 2022
aa34e08
Ignore signature where it is already different for pylint
Randl Jun 17, 2022
d6c3f96
More fixes
Randl Jun 17, 2022
f448848
lint
Randl Jun 17, 2022
7538012
further type fixes
Randl Jun 17, 2022
b07fef7
Ignore assiignment to attributes
Randl Jun 18, 2022
ed92f01
More type annotations
Randl Jun 18, 2022
26922da
More type annotations
Randl Jun 18, 2022
e6e1281
Lint
Randl Jun 18, 2022
f78f0c0
floating
Randl Jun 18, 2022
5001146
multiple fixes.
Randl Jun 18, 2022
99b055f
lint
Randl Jun 18, 2022
b43dec0
remove circular import
Randl Jun 18, 2022
5f656e0
Fixes after rebase
Randl Jun 22, 2022
4fc7899
Lint
Randl Jun 22, 2022
2b11c74
Lint 2
Randl Jun 22, 2022
34cc559
Fix after rebase
Randl Jun 23, 2022
657fc57
Fix after rebase 2
Randl Jun 24, 2022
0d2f065
Fixes from review
Randl Jun 24, 2022
2d56f46
Fixes from review 2
Randl Jun 24, 2022
505c2ed
Remove asserts
Randl Jun 24, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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]:
Expand Down
4 changes: 2 additions & 2 deletions qiskit/algorithms/amplitude_amplifiers/grover.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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

Expand Down
20 changes: 11 additions & 9 deletions qiskit/algorithms/amplitude_estimators/ae.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Comment on lines -394 to +392
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems to be a common change here. Both algorithms and opflow used to run against mypy in Aqua before they were migrated to Terra here. Since then mypy has not been run here and some code has been added so I would have expected some issues. But mypy always internally figured the type of instance variables based on its usage so unless things were more complicated around the types, where it locked in one aspect and it was used with a different type later, in general this was not needed. @manoelmarques since you dealt more directly with mypy in this area any comment.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I went with error messages, somehow mypy couldn't figure out that it's Optional[int] rather than NoneType, and thus assignment of int to this variable is leading to type error

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What version of mypy are you running with? I know mypy has put out new versions since we ran the code when it was in Aqua. Here for instance is a mypy ini file, for code that was migrated from Aqua, where in the applications repos we run mypy, and is updated from what we used to do in Aqua. For instance we have strict_optional set False, which allows None to be any type. What settings are you running this with. I assume you are doing this all locally since I do not see requirements-dev.txt nor CI updated to run this here yet. Maybe its too soon.

Copy link
Contributor Author

@Randl Randl Jun 26, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm running mypy 0.970 with following command dmypy run -- --ignore-missing-imports --no-strict-optional --allow-untyped-globals --allow-redefinition --show-error-codes qiskit taken from #6905 (comment)
I'm indeed doing it locally, since there are still ~1000 mypy errors after this PR (and ~1400 before). Fixing everything in one PR is too much, and even this PR will probably be broken into a couple of smaller ones, as discussed a bit earlier here.

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:
Expand Down Expand Up @@ -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:
Expand All @@ -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:
Expand Down
16 changes: 8 additions & 8 deletions qiskit/algorithms/amplitude_estimators/amplitude_estimator.py
Original file line number Diff line number Diff line change
Expand Up @@ -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]]]:
Expand Down
11 changes: 6 additions & 5 deletions qiskit/algorithms/amplitude_estimators/fae.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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?
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should check the code to see if the int type hints need changing. This PR is the right place to resolve such potentially false hints - if we're not resolving the "TODO" here, we'll probably always forget to do it.

return self._success_probability

@success_probability.setter
Expand Down
18 changes: 9 additions & 9 deletions qiskit/algorithms/amplitude_estimators/iae.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
28 changes: 15 additions & 13 deletions qiskit/algorithms/amplitude_estimators/mlae.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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):
Expand All @@ -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,
Expand Down Expand Up @@ -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:
Expand All @@ -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

Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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]]:
Expand All @@ -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
Expand Down
6 changes: 3 additions & 3 deletions qiskit/algorithms/eigen_solvers/eigen_solver.py
Original file line number Diff line number Diff line change
Expand Up @@ -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]:
Expand Down
17 changes: 10 additions & 7 deletions qiskit/algorithms/eigen_solvers/vqd.py
Original file line number Diff line number Diff line change
Expand Up @@ -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())
Expand Down Expand Up @@ -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.
Expand Down
4 changes: 2 additions & 2 deletions qiskit/algorithms/evolvers/evolution_problem.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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())
Expand Down
4 changes: 2 additions & 2 deletions qiskit/algorithms/factorizers/shor.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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

Expand Down
13 changes: 8 additions & 5 deletions qiskit/algorithms/linear_solvers/hhl.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)
Expand Down