8

I am trying to create autosummary using sphinx-autosummary for my python code which looks like as follows:

main
├───modA
|   ├───__init__.py
|   ├───modA.py
├───modB
|   ├───__init__.py
|   ├───modB.py
├───docs
|   ├───build
|   └───source
|       ├───refs
|       |   |───_autosummary
|       |   |───index.rst
|       |   |───modA.rst
|       |   |───modB.rst
|       ├───index.rst
|       ├───conf.py

As mentioned in Sphinx documentation, I inserted the abspath of my working directory, added sphinx.ext.autodoc to the list of extensions, and set autosummary_generate to True in conf.py.

import os
import sys
sys.path.insert(0, os.path.abspath('../..'))

# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
    'sphinx.ext.autodoc',
    "sphinx.ext.autosummary", 
    'sphinx.ext.coverage', 
    'sphinx.ext.napoleon'
]

autosummary_generate = True

Next, within docs/index.rst, I added a reference to the refs/ folder.

.. toctree::
   :maxdepth: 2

   refs/index

The refs/index.rst has reference to modA.rst and modB.rst.

.. toctree::
   :maxdepth: 2

   modA
   modB

In modA.rst and modB.rst, I am trying to create autosummaries.

modA.rst

Attributes
~~~~~~~~~~
.. autosummary::
   :toctree: _autosummary

   modA.modA.create_job

modB.rst

Attributes
~~~~~~~~~~
.. autosummary::
   :toctree: _autosummary

   modB.modB.get_jobs

While the code is working for modA.rst, it fails for modB.rst. The error says,

failed to import 'modB.modB.get_jobs': no module named modB.modB.get_jobs

I tried putting .. currentmodule::modB and .. currentmodule::main before the autosummary, but with no success. I even tried putting .. module::modB and .. module::main before autosummary, but even that is not working. I searched a lot on the internet, but unable to understand why it's not working.

Edit-1: Added __init__.py in both the folders.

mzjn
  • 48,958
  • 13
  • 128
  • 248
Milan Jain
  • 459
  • 7
  • 17
  • I don't see any `__init__.py` files in your directories that you want to be Python packages. Sphinx requires it, unless you use the option [`--implicit-namespaces`](https://www.sphinx-doc.org/en/master/man/sphinx-apidoc.html#cmdoption-sphinx-apidoc-implicit-namespaces). – Steve Piercy Jun 06 '20 at 05:03
  • I added an empty `__init__.py` in both the folders but no success. – Milan Jain Jun 06 '20 at 05:35
  • What is that file `_autosummary`? It has no file suffix. – Steve Piercy Jun 06 '20 at 06:36
  • It is a folder that stores autogenerated rst which gets generated by setting `autosummary_generate=True`. – Milan Jain Jun 06 '20 at 23:18
  • I don't see an `__init__.py` in your `main` directory. Try that. Finally double check that `modB.modB.get_jobs` actually exists in your Python source, as the error message from Sphinx says it is unable to find it and import it. – Steve Piercy Jun 07 '20 at 09:42
  • I don't see anything obviously wrong in your setup. Can you show us what's in modA.py and modB.py? – mzjn Jun 09 '20 at 06:32
  • 4
    Did you ever find a solution? I'm running in circles on this as well it keeps telling me my module is not found even if I have an `__init__.py` in both my folder and subfolder. These things should be made easy to use instead of making us waste hours – Guillaume Dec 14 '20 at 17:11

3 Answers3

10

I had similar issue in using Sphinx.

After some experiments, I suspect that the error message like failed to import XXX: no module named XXX does not necessarily mean the module XXX cannot be found. Instead, in my experiment, there is some error in importing XXX.

In my case, the module XXX itself is importing some package YYY that has not been installed. Since Sphinx import XXX in order to extract docstring, it found an error in this import attempt. After I removed that import YYY statement, I can successfully build the documentation.

Jianing
  • 168
  • 1
  • 8
  • 1
    Another option is to mock the YYY module: https://www.sphinx-doc.org/en/master/usage/extensions/autodoc.html#confval-autodoc_mock_imports – mzjn Apr 16 '21 at 15:17
  • @mzjn very interesting, thanks for bringing this forward – Jianing Apr 17 '21 at 06:16
3

It seems that when Sphinx can't handle a python import it will show the generic module import warning (".. no module named ...") as you mentioned. It seems that this warning can even occur when all imported python package are correctly installed in the environment and it just means that something could not be imported.

A workaround to get rid of this warnings is to mock external python libraries by using the autodoc_mock_imports in the conf.py file of Sphinx.

For example:

import flask
import mongoengine
...
# your python code

Example conf.py with mocking flask: autodoc_mock_imports = ["flask", "mongoengine"]

In this case Sphinx will ignore these imports and autosummary may be able to build the summary correctly without any errors.

To be more specific to your case: It could be that your python file 'modB.modB' contains an import statement that Sphinx can't handle and that you either need to install the python package correctly or to mock the specific libraries imported in the modB.modB file.

Me7e0r
  • 67
  • 1
  • 9
  • This does not really answer the question. If you have a different question, you can ask it by clicking [Ask Question](https://stackoverflow.com/questions/ask). To get notified when this question gets new answers, you can [follow this question](https://meta.stackexchange.com/q/345661). Once you have enough [reputation](https://stackoverflow.com/help/whats-reputation), you can also [add a bounty](https://stackoverflow.com/help/privileges/set-bounties) to draw more attention to this question. - [From Review](/review/late-answers/30229898) – dsillman2000 Nov 01 '21 at 13:14
  • @dsillman this doesn't look like a question. It's a suggestion for a workaround which is a valid answer – Tomerikoo Nov 01 '21 at 13:23
  • As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Nov 01 '21 at 13:46
  • Sorry if my answer wasn't clear enough. I changed it and added an example to hopefully make it more understandable. – Me7e0r Nov 02 '21 at 15:09
2

I had a similar issue.

My reason of failed import error was that the module modA.modA, specified under .. autosummary:: directive, had imports of not installed libraries.

Attributes
~~~~~~~~~~
.. autosummary::
   :toctree: _autosummary

   modA.modA.create_job

But in general your reason for failed to import error can be different, because the function that imports modules from .. autosummary:: directive catches all errors and autosummary prints to output the same error message.

Here is the related issue on github https://github.com/sphinx-doc/sphinx/issues/7989

I suggest to import your modules modA.modA, modB.modB and see if there are any errors during importing.

vilozio
  • 111
  • 1
  • 8