You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
We should avoid importing from subpackages within the subpackage itself, since it is likely to generate circular imports (if not immediately, later on).
Consequently, importing directly from qibolab (without further qualifications) should never appear within the whole package.
Moreover, if #790 is not fully applied, we should check that no import is making use of accidental re-exports (i.e. places where an object is actually imported, but to be used, not as an intentional export - as it should happen in the various __init__.py only).
I'll try to establish a few rules (more guidelines) to how importing things
never import from a place which is not supposed to export
the export should be contained in __all__, but we won't be strict on that, not immediately, so the "export places" are either those where the objects are initially defined, or on-purpose re-exports from the various __init__.py
example: if an object is defined in a.b.c.d.e, you should import it from there, or from: a.b.c.d, a.b.c, a.b
never import from any of your own __init__.py
__init__.py is meant for the export, the first thing encountered by anyone looking at the (sub)package from the outside, and it could contain re-exports -> high chance of circular imports
example: if you are a.b.c, never import from a.b nor a -> no one in Qibolab should import from qibolab itself
if importing from another subpackage, import at the top-most level possible
at least the internals can be changed at will, the compatibility towards the outside has only to be honored in a single place
example: if you are a.b, and import from a.c.d.e, then import from a.c, if it exports it
* imports are recommended for re-exporting the content of the modules in the __init__.py above, but they should be avoided for internal usage
re-exports should be accompanied by the parent __all__ update, e.g.
since it seems that the majority of tools understand the __all__ += submodule.__all__ idiom, but not all the list methods (like .extend()), and not even list comprehension, the redundant syntax above is suggested, namely:
* export the content of all the submodules
import all the submodules as module objects, to access their .__all__ attributes
extend the parent __all__ with += statements, one at a time
it is definitely redundant, since modules are listed three times, but this is to ensure the widest compatibility possible with external static tools (i.e. not executing the code in a Python interpreter, e.g. linters as pylint & ruff, type checkers as mypy & pyright, and others as pycln)
The text was updated successfully, but these errors were encountered:
@stavros11 I was thinking to keep the guide above in some file in the repo. We could eventually export to general Qibo developer docs, but for the time being this will only be used in Qibolab, so I'd keep it here (for as long as we do not decide we like this public API definition, and start exporting it to the other packages).
I was thinking to CONTRIBUTING.md, but we can even add a developers' section to the Qibolab docs (additional to the link to Qibo's)
We should avoid importing from subpackages within the subpackage itself, since it is likely to generate circular imports (if not immediately, later on).
Consequently, importing directly
from qibolab
(without further qualifications) should never appear within the whole package.Moreover, if #790 is not fully applied, we should check that no import is making use of accidental re-exports (i.e. places where an object is actually imported, but to be used, not as an intentional export - as it should happen in the various
__init__.py
only).I'll try to establish a few rules (more guidelines) to how
import
ing things__all__
, but we won't be strict on that, not immediately, so the "export places" are either those where the objects are initially defined, or on-purpose re-exports from the various__init__.py
a.b.c.d.e
, you should import it from there, or from:a.b.c.d
,a.b.c
,a.b
__init__.py
__init__.py
is meant for the export, the first thing encountered by anyone looking at the (sub)package from the outside, and it could contain re-exports -> high chance of circular importsa.b.c
, never import froma.b
nora
-> no one in Qibolab should importfrom qibolab
itselfa.b
, and import froma.c.d.e
, then import froma.c
, if it exports it*
imports are recommended for re-exporting the content of the modules in the__init__.py
above, but they should be avoided for internal usage__all__
update, e.g.qibolab/src/qibolab/instruments/qm/components/__init__.py
Lines 1 to 5 in 95eab21
__all__ += submodule.__all__
idiom, but not all the list methods (like.extend()
), and not even list comprehension, the redundant syntax above is suggested, namely:*
export the content of all the submodules.__all__
attributes__all__
with+=
statements, one at a timeThe text was updated successfully, but these errors were encountered: