qiboteam / qibolab

Quantum hardware module and drivers for Qibo.
https://qibo.science
Apache License 2.0
41 stars 10 forks source link

Public API #790

Open alecandido opened 6 months ago

alecandido commented 6 months ago

Since Qibolab is now being used, and we transitioned to proper releases, in order to make the semver conversion even more meaningful we should define what is part of the public API of Qibolab.

The convention in Python is that everything that is accessible passing through a chain of non-underscore-led identifiers is public, i.e.:

# public
ciao
ciao.come
ciao.come.va

# private
_ciao
ciao._come
ciao.come._va
# and so also:
ciao._come.va
# as parte of `ciao._come`

However, if you use ciao._come.va inside ciao, importing directly the identifier, i.e.

# src/ciao.py
from ._come import va

this becomes accessible as ciao.va, and thus public again.

In general, the idea is to keep all the definitions internal, and exports only the public API through suitable __init__.py and modules imported by that, as a restricted hierarchy within the package, just made for re-exports. Often, a _core subpackage, or something like that, is used to separate what is internal from the public API.

To simplify the management of the public API, there are different tools available in Python's module system:

NumPy is quite a full-fledged example of how all of these are used to define the public API. It is also over-complicate for us, since they have decades of legacy code and users to support, but it's interesting to navigate their __init__.py structure.

This will help to identify which changes are actually breaking, and which are not.

(In principle, whatever is not part of the public API should also be kept internal, and not documented in Sphinx - I guess this should work automatically, ensuring meaningful __dir__ values - and it should not be an incentive to avoid docstrings, even for internal elements)