Conversation
|
One or more of the following people are relevant to this code:
|
|
|
|
I'd probably just leave We've not needed to touch that file in forever, so it's not like it's hurting us all that much. |
Supported by Claude 3.2 Sonnet to try and generate the __all__ lists (which was somewhat successful but needed tweaking afterwards)
There was a problem hiding this comment.
Can you undo these formatting changes to the TOML file - if we're going to apply a formatter to our TOML files, we should be consistent about it and enforce it in CI.
There was a problem hiding this comment.
ah crap -- I usually remember to save w/o formatting but here it snuck in 🙂 thanks!
jakelishman
left a comment
There was a problem hiding this comment.
I haven't really looked at this in depth, but I will say that in its current form, I'm not wild about the amount of busy-work it's implying to write simple code in non-public modules, or to work with the code organisation that Qiskit has for historical reasons.
Can we look into whether there's better ways to handle __all__ in the presence of nested imports, and see if we can collapse some of it to * imports where appropriate (since having __all__ makes star-imports in the import system much safer).
| from .overlap import UnitaryOverlap, unitary_overlap | ||
| from .standard_gates import get_standard_gate_name_mapping | ||
|
|
||
| __all__ = [ |
There was a problem hiding this comment.
Will Ruff accept a form that's like this:
from .boolean_logic import *
from .n_local import *
# ...
__all__ = [
*boolean_logic.__all__,
*n_local.__all__,
# ...
]so we can actually semantically specify what the import structure is, rather than making it so a simple addition requires modifications to the import system in dozens of places?
There was a problem hiding this comment.
Ruff is unhappy in two places about the above:
It's true it would be nice to avoid this redundancy, but in practice this redundancy already exists right now since we have to re-import the objects explicitly from the submodule. One way to avoid this would be to only import them in the __init__.py we actually want users to import the object from and stop having multiple valid locations
There was a problem hiding this comment.
If PLE0604 is triggering, then Ruff is incorrect - my __all__ does contain only strings.
For F403: the defence Ruff gives of that is partly "it's against PEP8", but an actual reading of PEP8 says (emphasis mine):
Wildcard imports (
from <module> import *) should be avoided, as they make it unclear which names are present in the namespace, confusing both readers and many automated tools. There is one defensible use case for a wildcard import, which is to republish an internal interface as part of a public API.
which is consistent with what we're doing here.
My preference would be to find a way to do this - the (imo unnecessarily, but that ship sailed) nested internal module structure of Qiskit means we're going to have to duplicate so many lists that literally are just intended to be re-exports. Can we file-level disable Ruff's F403 on __init__.py files, and work out how we get Ruff to learn that __all__ = [*x.__all__] should be fine too?
There was a problem hiding this comment.
One way to avoid this would be to only import them in the
__init__.pywe actually want users to import the object from and stop having multiple valid locations.
I'm ok with this as a second preference, but given how deeply nested some of our modules are, it might turn pretty ugly pretty fast, and it might cause some gross circular dependencies with the current Qiskit structure.
There was a problem hiding this comment.
The situation is actually better: if we star-import, ruff doesn't complain about the exports not being listed in __all__, so something like
from .boolean_logic import *
from .n_local import *
from .somewhere import SpecificThingWithoutStarImport
__all__ = ["SpecificThingWithoutStarImport"]
works (with an F403 ignore on __init__.py files)
There was a problem hiding this comment.
Ah haha, but that's a logical problem that Ruff is simply failing to detect now. Those star imports are part of the public API, and they should be listed in the __all__.
Will Ruff complain if you tack
__all__ += boolean_logic.__all__
__all__ += n_local.__all__onto your example?
Summary
Enables unused import checks (
F401) inruff.Details and comments
This was triggered since we have a bunch of unused imports in the code right now. We still allow unused imports in all
__init__.pyfiles (the alternative would be listing all imports explicitly in__all__, but that was decided against).This has 3 increasing levels of invasiveness:
F401qiskit.quantum_info.random_unitaryoverqiskit.quantum_info.operators.random.random_unitary)I think it would be nice to have at least steps 1 and 2, but we can also drop step 3 which might make reviewing this PR a bit tough since it touches lots of lines (albeit rather trivially).