Mikhail Genkin
Mikhail Genkin

Reputation: 3460

Sphinx python: autodoc does not import class methods defined in other source files

In my project, I have a class EnergyModel defined in energymodel.py. There is also generate_data class method imported from another source file:

#energy_model.py

from .energy_model_data_generation import generate_data
class EnergyModel(BaseEstimator):
    def __init__(...):
        EnergyModel.generate_data=generate_data

And there is another source file where the method is defined:

#energy_model_data_generation.py

def generate_data(self, ...):
     ...

I separated methods into different source files to keep the files sufficiently small - this is convenient for me. Now, I want to generate class documentation with Sphinx. My implementation.rst is the following:

Implementation
==============

.. _Energymodel_class:

Energymodel class
-----------------

.. autoclass:: neuralflow.EnergyModel
     :members:

Where neuralflow is the name of the package (imported in conf.py). This does not generate documentation for generate_data methods. I did not find how to include it, I only found how you can cross-refence methods, which is not what I want.

Edit: There is also __init__.py file in my directory with the source file, so it is a package. It looks like this:

from .energy_model import EnergyModel
# Also import other modules/packages that are not part of EnergyModel class

__all__ = ['EnergyModel', ...(other stuff that are not part of EnergyModel)]

Also I've added root directory to the path in conf.py file

Upvotes: 0

Views: 355

Answers (1)

Kale Kundert
Kale Kundert

Reputation: 1494

The problem is that the generate_data() method is added dynamically to the class in the constructor. Because Sphinx nevers call the constructor (as @mzjn points out), this method is simply not part of the class when Sphinx is building the documentation. The solution is to define the method at the class level:

import energy_model_generation as emg

class EnergyModel(BaseEstimator):
    generate_data = emg.generate_data

As more of a code-review type comment, it doesn't really make sense to dynamically create methods in the constructor like this. Methods should only be defined once, but the constructor can be called many times—once for each instance of the class. It's easy to imagine this being the source of obscure bugs.

Upvotes: 1

Related Questions