Use structural subtyping for defining interfaces to the different parts of Kwant
Problem definition
In principle Kwant has several more or less independent components separated by interfaces: Builder, System, solvers, plotter
In practice the specific interfaces that are used are only loosely defined, and it is quite challenging (even for one well-versed in the internals of Kwant) to create new classes which adhere to the correct interface.
Take, for example kwant.system.FiniteSystem
which can, in principle, be plotted by kwant.plot
if it provides a pos
method (this is not even documented in the docstring of plot
; it just says that the sys
parameter may be a Builder
or system.Finitesystem
). However, if the leads do not provide a symmetry
attribute that has the interface of a kwant.lattice.TranslationalSymmetry
then they are simply not plotted.
This is not documented in plot
. Even if it were, having ad-hoc interfaces defined in docstrings is probably not the way to go.
In practice people use Kwant as a monolithic package, and it is often unacceptable to e.g. be able to define custom system classes but be unable to plot them properly.
Proposed Solution
I propose to use structural subtyping a la PEP 544 to allow use to more precisely specify the interfaces required by the different parts of Kwant.
We can either wait until we can rely on Python 3.8, and make use of typing.Protocol
or roll our own with __subclass_hook__
.