0

I have the following project structure with my code and documentation:

├───docs
│   ├───_build
│   ├───_static
│   ├───...
│   ├───conf.py
│   ├───index.srt
│   ├───make.bat
|   └───Makefile   
├───source
│   ├───script1.py
│   ├───script2.py
|   └───script3.py

my conf.py:

import os
import sys
sys.path.insert(0, os.path.abspath('../source'))
...
extensions = ['sphinx.ext.autodoc']

I am running sphinx-apidoc -o . ../source inside the docs folder. It generates a new file .rst file for each of my scripts.

And I am adding modules to the index.rst file

After that I'm running make html to generate my documentation. But it's raising a warning and not generating docs for an specific file:

WARNING: autodoc: failed to import module 'script3'; the following exception was raised:
No module named 'source'

I isolate the problem to an import statement made inside script3.py code:

  • from source.scripts2 import MyClass

So it seems that since the folder is not a module is raising the error. But I am not sure how to fix it.

I have tried to create empty __init__.py file in the project and in the source folder, but the error persist

How could I fix it?

bad_coder
  • 11,289
  • 20
  • 44
  • 72
Matheus Oliveira
  • 587
  • 3
  • 10
  • 33
  • You aren't giving enough information. Your file layout isn't standard. When you ran `sphinx-quickstart` you should have choosen "separate sources from build" option. Normally, `/docs/sources` is where your `.rst` are placed, and your `.py` modules are placed in a directory called `/src`. Check [this answer](https://stackoverflow.com/a/60159862) for how to use the `/src` layout. – bad_coder Oct 05 '20 at 18:06
  • 2
    If you want to see it working with your current layout, use the `__init__.py` in `/sources` and afterwards set `os.path.abspath('..')`. It should work, however your layout would still be different from what most users are using. – bad_coder Oct 05 '20 at 18:18
  • I tried to use separated directories (I was not sure what it would change) but still no luck. I will retry with question, thnks – Matheus Oliveira Oct 05 '20 at 18:18
  • Delete everything inside `/docs` folder and try those steps in the answer I linked (in the first comment) exactly like they are written. (Separate directories changes everything, because you are import modules and setting paths, so it's all about directories...) – bad_coder Oct 05 '20 at 18:21
  • because `parent/source/` is on your path and not `parent/`, when you `import source.script2` in `script3.py` python is like "I haven't heard of this module called source". You could use relative imports: `from . import script2` and I believe that will fix your issue. Alternatively if you add the parent directory to your path, I believe that will also work. – alkasm Oct 05 '20 at 18:25
  • If you want to locally poke around without running sphinx every time to see the problems, fire up the python interpreter _inside the docs directory_. Then run your path insert code, and try to import your modules. This is what Sphinx will do, so you can see if you've fixed it or not as you're playing around. – alkasm Oct 05 '20 at 18:26
  • Point setting `os.path.abspath('..')` worked! Thank you I will refact the project strucutre for a more standard layout – Matheus Oliveira Oct 05 '20 at 18:33
  • @MatheusOliveira one more thing, when you refactor to a `/src` layout (widely considered the *"best practice"* today) you'll need to development install using `install -e` and "activate your venv", check [this answer](https://stackoverflow.com/questions/62498127) on how to do it. (That's basically all there is to know about the subject of layouts...) – bad_coder Oct 05 '20 at 19:16
  • @bad_coder Coincidentally I found another very nice answer about this setup with very nice explanations: [answer](https://stackoverflow.com/questions/714063/importing-modules-from-parent-folder/50194143#50194143) Thanks again! – Matheus Oliveira Oct 12 '20 at 09:48
  • @MatheusOliveira that answer you linked *"seems to work"* but it doesn't have any of the concrete details that are needed. – bad_coder Oct 12 '20 at 14:32
  • Also, for a flat layout see https://stackoverflow.com/q/59903051 – bad_coder Nov 25 '22 at 20:41

1 Answers1

0

I had the same error with similar structure

making output directory... done
building [mo]: targets for 0 po files that are out of date
building [html]: targets for 3 source files that are out of date
updating environment: [new config] 3 added, 0 changed, 0 removed
reading sources... [100%] source                                                                                                      
WARNING: autodoc: failed to import module 'my_python_file' from module 'source'; the following exception was raised:
No module named 'source'
...
WARNING: autodoc: failed to import module 'source'; the following exception was raised:
No module named 'source'
looking for now-outdated files... none found
...

The solution was to change the sys.path.insert() at conf.py to point one directory up (project root)

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

And also don't forget to add __init__.py file to ./source/

Yogev Neumann
  • 2,099
  • 2
  • 13
  • 24