All Cython extensions in Finesse must be structured in the same way as the Python sub-modules. This means that if your extension requires a definition file (.pxd) then it should exist in its own directory / sub-package within the code, where this directory then contains a __init__.pxd file if other Cython extensions need to interact with it and a file if the Python code requires access to the extension.

Additionally, similarly to the Python code, if your Cython extension is comprised of multiple .pyx files then it should also exist in a separate directory (even if no .pxd files are needed).

For a brief summary on why it is important to follow the same structure as the Python package itself, see this FAQ answer on the Cython GitHub Wiki pages.


The name given to an extension in is important as it determines the location at which the resultant .so file is generated. All names are relative to the top-level finesse module, so the name you give to an extension should correspond to its location in the package.

For example, we have the following package structure (simplified):

├── cmath
│   ├── __init__.pxd
│   ├──
│   ├── cmath.pxd
│   └── cmath.pyx
├── utilities
│   ├──
│   ├── maths.pyx
│   └── ...
├── cmatrix.pyx
├── knm.pyx
└── ...

Here finesse.cmath is a Cython extension module, finesse.utilities.maths is a Cython extension which is part of the finesse.utilities sub-module and finesse.cmatrix and finesse.knm are Cython extensions which are part of the top-level Finesse package directory. The names then given to these extensions in are correspondingly:

  • finesse.cmath extension — name = "cmath.cmath"

  • finesse.utilities.maths extension — name = "utilities.maths"

  • finesse.cmatrix extension — name = "cmatrix"

  • finesse.knm extension — name = "knm"