With Python 3, Cython is pickier about circular dependencies. This is all well and good, but sometimes lower level objects (e.g. ``Subdevice`` instances) need pointers from higher level objects (e.g. ``Device`` instances). How does that work? All of the C types used in the library are defined in library-specific ``_*_h.pxd`` files at the bottom of the dependency tree. The low-level objects don't really need the higher level objects (which would create a circular import), they need the *pointers* held by the higher level object. The solution is create minimal wrappers (e.g. ``DeviceHolder``), holding only the typed attributes (``DeviceHolder.device``) and basic methods. These minimal classes can be subclassed by the full-fledged class (``Device``), but they can *also* be imported by the lower level modules and used to define attributes (``Subdevice.device``) that can then hold either the minimal (``DeviceHolder``) or the full-fledged (``Device``) version of the higher level object. For clarity in the above, I discussed the ``Device`` / ``Subdevice`` relationship, but the same logic holds for similar high- / low-level relationships (e.g. ``Subdevice`` / ``Channel``, etc.).