Skip to content

Fix mypy annotations in fermion_partitioning (#1282)#1349

Open
rosspeili wants to merge 2 commits into
quantumlib:mainfrom
rosspeili:fix/issue-1282-mypy
Open

Fix mypy annotations in fermion_partitioning (#1282)#1349
rosspeili wants to merge 2 commits into
quantumlib:mainfrom
rosspeili:fix/issue-1282-mypy

Conversation

@rosspeili

Copy link
Copy Markdown
Contributor

First slice for #1282: correct generator return types and local variable annotations in measurements/fermion_partitioning.py. No runtime or API behavior changes.

First slice for quantumlib#1282: correct generator return types and local variable annotations in measurements/fermion_partitioning.py. No runtime or API behavior changes.

@gemini-code-assist gemini-code-assist Bot 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.

Code Review

This pull request adds type annotations to several functions in src/openfermion/measurements/fermion_partitioning.py to improve type safety and code readability. Since there are no review comments, I have no feedback to provide.

@mhucka mhucka left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thank you for doing this!

There is one change I would recommend. Although Any is valid, it is better to define so-called generic parameter types, along the following lines:

from typing import TypeVar

T = TypeVar('T')

def pair_within(labels: list[T]) -> Generator[tuple[T, ...], None, None]:
    """Generates pairings of labels that contain each pair at least once."""
    ...

Applying this across other matching functions (like pair_between and pair_within_simultaneously) allows static analyzers to check that the output tuples contain elements of the exact same type as the input.

Would you be able to try to make the appropriate changes to this PR?

Replace Any with generic T and a Pairing type alias that matches runtime: tuples of (T, T) pairs (plus occasional bare T leftovers). Internal iterator combiners stay on Any. No behavior changes.
@rosspeili

Copy link
Copy Markdown
Contributor Author

@mhucka reworked based on suggestion, mypy is clean on this file and all tests pass. Let me know how it looks, and thanks for the tip. <3

@mhucka mhucka left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I'm not done with the review on the update, but here's a start for a minor detail.



def pair_within(labels: list) -> list:
def pair_within(labels: list[T]) -> Generator[Pairing, None, None]:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Here, the declaration should be changed to Pairing[T].

Suggested change
def pair_within(labels: list[T]) -> Generator[Pairing, None, None]:
def pair_within(labels: list[T]) -> Generator[Pairing[T], None, None]:

Using Pairing without its type argument causes static type checkers like mypy to treat it as Pairing[Any], which often passes the type check, but does not give us the real benefits of the type declarations. The lack of the subscript T breaks the connection between the type T of the input list labels and the yielded element types.



def pair_within_simultaneously(labels: list) -> tuple:
def pair_within_simultaneously(labels: list[T]) -> Generator[Pairing, None, None]:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change
def pair_within_simultaneously(labels: list[T]) -> Generator[Pairing, None, None]:
def pair_within_simultaneously(labels: list[T]) -> Generator[Pairing[T], None, None]:

def pair_within_simultaneously_binned(binned_majoranas: list) -> tuple:
def pair_within_simultaneously_binned(
binned_majoranas: list[list[T]],
) -> Generator[Pairing, None, None]:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change
) -> Generator[Pairing, None, None]:
) -> Generator[Pairing[T], None, None]:

def pair_within_simultaneously_symmetric(num_fermions: int, num_symmetries: int) -> tuple:
def pair_within_simultaneously_symmetric(
num_fermions: int, num_symmetries: int
) -> Generator[Pairing, None, None]:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This one is not a T but instead, an int:

Suggested change
) -> Generator[Pairing, None, None]:
) -> Generator[Pairing[int], None, None]:

generator_list = [_loop_iterator(pair_within, partition[j]) for j in range(len(partition))]
for dummy1 in range(len(partition[-2]) - 1 + len(partition[-2]) % 2):
pairing = tuple()
pairing: Pairing = ()

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change
pairing: Pairing = ()
pairing: Pairing[T] = ()

num_pairs = min(len(frag1), len(frag2))

for index_offset in range(start_offset, num_iter):
pairing: Pairing

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change
pairing: Pairing
pairing: Pairing[T]

def pair_between(frag1: list, frag2: list, start_offset: int = 0) -> tuple:
def pair_between(
frag1: list[T], frag2: list[T], start_offset: int = 0
) -> Generator[Pairing, None, None]:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change
) -> Generator[Pairing, None, None]:
) -> Generator[Pairing[T], None, None]:

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants