Skip to content

Type annotations for the baseobjs - #733

Open
nkoskelo wants to merge 13 commits into
developfrom
type_annotations_baseobj
Open

Type annotations for the baseobjs#733
nkoskelo wants to merge 13 commits into
developfrom
type_annotations_baseobj

Conversation

@nkoskelo

@nkoskelo nkoskelo commented Apr 3, 2026

Copy link
Copy Markdown
Contributor

Add type annotations to baseobjs to improve the maintainability of the code.

@nkoskelo
nkoskelo requested review from a team as code owners April 3, 2026 19:37
@nkoskelo
nkoskelo requested a review from coreyostrove April 3, 2026 19:37
@nkoskelo
nkoskelo marked this pull request as draft April 3, 2026 19:37
@nkoskelo
nkoskelo marked this pull request as ready for review May 26, 2026 20:45
@nkoskelo
nkoskelo requested a review from rileyjmurray as a code owner May 26, 2026 20:45

@ndsieki ndsieki left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I've indicated where type annotations are missing and also where existing type annotations may need modified.

Comment thread pygsti/baseobjs/errorgenlabel.py Outdated
Comment thread pygsti/baseobjs/errorgenspace.py
Comment thread pygsti/baseobjs/errorgenspace.py Outdated

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

It appears that the parameter name has been changed from elemgen_basis to basis; the docstring should be updated accordingly.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Since an ElementaryErrorgenBasis is a specific basis, I am updating the parameter to have the elemgen_basis name. I do not see any calls to create an ErrorgenSpace(vec, basis=foo) so this is an allowed change.

Comment thread pygsti/baseobjs/protectedarray.py Outdated
def __init__(self, input_array, indices_to_protect=None, protected_index_mask= None):
def __init__(self, input_array: _np.ndarray,
indices_to_protect: Optional[Union[int, Iterable[Union[list[int], tuple]]]]=None,
protected_index_mask: _np.ndarray= None):

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Shouldn't the type annotation for protected_index_mask be Optional[_np.ndarray] if None is an acceptable value?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yes, you are correct. One does need to be careful though when checking for None when the object can be a numpy array.

def check(foo):
    if foo:
        print(True)
    else:
         print(False)

check(None) will print False but check(np.arange(12)) will through a ValueError about checking the truth value of an array. One needs to check directly against None with an is None or is not None condition. That is already included in this code but I am writing this down for future reference.

Comment thread pygsti/baseobjs/qubitgraph.py Outdated

@classmethod
def common_graph(cls, num_qubits=0, geometry="line", directed=True, qubit_labels=None, all_directions=False):
def common_graph(cls, num_qubits=0, geometry: Literal['line','ring','grid','torus']="line", directed=True,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Please consider adding type annotations for num_qubits, directed, and all_directions.

Comment thread pygsti/data/rpedata.py Outdated


def make_rpe_data_set(model_or_dataset, string_list_d, num_samples, sample_error='binomial', seed=None):
def make_rpe_data_set(model_or_dataset, string_list_d,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Please add a type annotation for model_or_dataset and string_list_d.

Comment thread pygsti/drivers/bootstrap.py Outdated
def create_bootstrap_dataset(input_data_set, generation_method, input_model=None,
seed=None, outcome_labels=None, verbosity=1):
def create_bootstrap_dataset(input_data_set: _DataSet, generation_method: Literal["nonparametric", "parametric"],
input_model=None, seed: Optional[int]=None, outcome_labels:Optional[list[_Label]]=None,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Please add a type annotation for input_model.

Comment thread pygsti/drivers/bootstrap.py Outdated
generation_method: Literal["nonparametric", "parametric"],
fiducial_prep: list[_Circuit], fiducial_measure: list[_Circuit],
germs: list[_Circuit], max_lengths: list[int],
input_model=None, target_model=None, start_seed: int=0,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Please add a type annotation for input_model and target_model.

Comment thread pygsti/drivers/bootstrap.py Outdated
input_model=None, target_model=None, start_seed: int=0,
outcome_labels: Optional[list[_Label]]=None,
lsgst_lists: Optional[list[list[_Circuit]]]=None,
return_data=False, verbosity=2):

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Please add a type annotation for verbosity. Please consider adding a type annotation for return_data.

Comment thread pygsti/baseobjs/protectedarray.py Outdated

def __init__(self, input_array, indices_to_protect=None, protected_index_mask= None):
def __init__(self, input_array: _np.ndarray,
indices_to_protect: Optional[Union[int, Iterable[Union[list[int], tuple]]]]=None,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This type annotation appears incorrect. For instance, indices_to_protect=(0,1) is handled properly by the __init__ function, but is not covered by the type annotation. The type annotation also does not include slice, even though slice is allowed in line 75. Also, although you have list[int], there is no parameterization specified for tuple.

You could consider something akin to baseobjs/qubitgraph.py as follows (not sure if the suggestion is exactly right since it is based on an LLM):

_IndexSpec = Sequence[Union[int, slice]]

 indices_to_protect: Optional[Union[int, _IndexSpec, Iterable[_IndexSpec]]] = None

@ndsieki ndsieki left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

While reviewing #720 I realized that I wasn't paying attention to type annotations for the returned object. I've marked five places in this PR where this return type annotation is missing, but there are many other functions/methods where it is missing; please review all functions that have been changed in this PR and ensure that they contain a return type annotation.

Comment thread pygsti/baseobjs/qubitgraph.py Outdated
return sorted(list(ret))

def radius(self, base_nodes, max_hops):
def radius(self, base_nodes: Iterable[QubitLabel_in_Graph], max_hops: int):

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Please also annotate the return type of the function.

Comment thread pygsti/baseobjs/qubitgraph.py Outdated
return sorted(list(ret))

def connected_combos(self, possible_nodes, size):
def connected_combos(self, possible_nodes: list[QubitLabel_in_Graph], size: int):

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Please also annotate the return type of the function.

Comment thread pygsti/baseobjs/qubitgraph.py Outdated
return bool(self._connectivity[j, i])

def is_connected(self, node1, node2):
def is_connected(self, node1: QubitLabel_in_Graph, node2: QubitLabel_in_Graph):

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Please also annotate the return type of the function.

Comment thread pygsti/baseobjs/qubitgraph.py Outdated
return self._predecessors[i, j] >= 0

def has_edge(self, edge):
def has_edge(self, edge: tuple[QubitLabel_in_Graph, QubitLabel_in_Graph]):

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Please also annotate the return type of the function.

Comment thread pygsti/baseobjs/qubitgraph.py Outdated
return self.is_directly_connected(edge[0], edge[1])

def is_directly_connected(self, node1, node2):
def is_directly_connected(self, node1: QubitLabel_in_Graph, node2: QubitLabel_in_Graph):

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Please also annotate the return type of the function.

- errorgenlabel.py: annotate mapper param in map_state_space_labels
- qubitgraph.py: annotate common_graph params and add missing return
  type annotations across changed methods (radius, connected_combos,
  is_connected, has_edge, is_directly_connected, add_edge(s),
  remove_edge, shortest_path*, subgraph, resolve_relative_nodelabel,
  move_in_direction(s), is_connected_subgraph, etc.)
- protectedarray.py: fix indices_to_protect and protected_index_mask
  annotations to match actual accepted inputs, and document the new
  behavior that in-place operators always raise ValueError
- rpedata.py: annotate model_or_dataset and string_list_d in
  make_rpe_data_set
- bootstrap.py: annotate input_model/target_model/verbosity/return_data
  in create_bootstrap_dataset and create_bootstrap_models; fix grammar
  in gauge_optimize_models docstring (determining -> determine)
- errorgenspace.py: fix normalize()'s norm_order type hint (was
  Union[int, Literal['inf','-inf']], which doesn't match what
  numpy.linalg.norm accepts); also fix stale elemgen_basis/basis
  docstring parameter name mismatch in ErrorgenSpace.__init__

@ndsieki ndsieki left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Looks good to me. There are some return type annotations that could be added, but all of the provided type annotations appear to be correct.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants