quantumlib / Qualtran

Qᴜᴀʟᴛʀᴀɴ is a Python library for expressing and analyzing Fault Tolerant Quantum algorithms.
https://qualtran.readthedocs.io/en/latest/
Apache License 2.0
173 stars 40 forks source link

Mypy issues in QROM / SelectSwapQROM #995

Open tanujkhattar opened 4 months ago

tanujkhattar commented 4 months ago

https://github.com/quantumlib/Qualtran/pull/986 adds 3 type ignores to qrom bloqs to make mypy happy; but its not clear why these issues arise in the first place.

Run check/mypy
qualtran/bloqs/data_loading/qrom.py:56: error: Definition of "controlled" in base class "Bloq" is incompatible with definition in base class "Gate"  [misc]
qualtran/bloqs/data_loading/select_swap_qrom.py:65: error: Definition of "controlled" in base class "Bloq" is incompatible with definition in base class "Gate"  [misc]
qualtran/bloqs/data_loading/select_swap_qrom.py:253: error: Missing return statement  [return]
Found 3 errors in 2 files (checked 436 source files)

This issue is to unblock the PR and track the potential fixes of these mypy issues at a later point.

cc @dstrain115

dstrain115 commented 4 months ago

For any subclasses of GateWithRegisters, you will need to add a #type: ignore[misc]. This is because Bloq and cirq.Gate have conflicting definitions for the controlled method, so the double inheritance is not 100% valid accoridng to type checking.

For the third one, you probably need to change the return type to Iterator or Generator.

Let me know if you need help with this.

tanujkhattar commented 4 months ago

I thought cirq.OP_TREE is defined to be a union of Operation and an iterator over OpTree so we shouldn't nee to change the return type to an iterator?

https://github.com/quantumlib/Cirq/blob/e4b6ab2f1f01b3c2d06456eb7244430e691474ef/cirq-core/cirq/ops/op_tree.py#L56

Either way, it looks like https://github.com/python/mypy/issues/731 is now fixed so we should update the definition of cirq.OP_TREE to be a recursive type (cc @pavoljuhas can we do this before the next release?)

pavoljuhas commented 4 months ago

Either way, it looks like python/mypy#731 is now fixed so we should update the definition of cirq.OP_TREE to be a recursive type (cc @pavoljuhas can we do this before the next release?)

The problem with OP_TREE, whether defined as the current Union[Operation, OpTree] or a recursive Union[Operation, Iterable[OP_TREE]] type, is that it does not guarantee such types are iterable. You would need to add isinstance(optree, Iterable) to pass mypy for every iteration over values that are returned as OP_TREE-s.

A proper way would be to redefine OP_TREE as Union[Iterable[Operation], Iterable[OP_TREE]], but I suspect that would necessitate a lot of changes to the cirq code and would be a breaking API change.

If I check cirq with mypy-1.10.0 as in qualtran I get a similar "Missing return statement" error for functions that yield after declaring an OP_TREE return type.

I suggest to change the return type of SelectSwapQROM.decompose_from_registers to Iterator[cirq.OP_TREE], there are already similar constructs in qualtran for example in TwoBitCSwap.decompose_from_registers.