0

I have a GitHub repo (here) which is extremely basic and only meant to reproduce a problem I had with another repo (CPU Health Checks also in my public repos)

It consists on a package called rtdtest which locally is a rtdtest/ folder with an empty __init__.py. This file has two simple modules cpu_health.py and utilities.py where cpu_health.py imports utilities.py with the statement

import rtdtest.utilities as utilities

In this case making a package is not that necessary but in my "real" repo I need it to access modules in subfolders within the proyect's root folder

My problem is that even though I am able to produce the documentation I want locally with sphinx which includes DocString generated documentation created with automodule statements in index.rst, when creating the documentation in Read The Docs the build passes but with warning messages

WARNING: autodoc: failed to import module 'cpu_health' from module 'rtdtest'; the following exception was raised: No module named 'rtdtest' WARNING: autodoc: failed to import module 'utilities' from module 'rtdtest'; the following exception was raised: No module named 'rtdtest'

Saying the modules from the package were not imported and suggesting to me that RTD is not recognizing rtdtest as a package but as a module (although I could be wrong there)

Locally the package is found with the line

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

In file conf.py (conf.py is 2 folders ahead of the root folder of the project in docs/sphinx/)

My (minimalistic) configuration files requirements.txt, .readthedocs.yml, setup.py, docs/sphinx/conf.py, and docs/sphinx/requirements.txt are included in the GitHub repo (couldn't put specific links because stackoverflow called the message spam)

And my main documentation file is: index.rst

In the admin Advance Settings section of my repo I have checked the "Install Project" box to "Install your project inside a virtualenv using setup.py install" but I haven't checked other one. For documentation type I chose "Sphinx HTML"

I tried multiple times to edit my conf.py file to add folders to the path using sys.path.insert but no combination of current and parent folders worked.

I also tried replicating the solution proposed in this previous post who apparently had a very similar problem and was able to solve it, but even trying to mimic their configuration files didn't work

Does anyone now what might be the problem? I am sorry in advance if this is clearly stated in the RTD documentation but this is my first time using the tool and I couldn't find a solution there

Please let me know if there is any additional information I should provide to help solving the problem

Cheers and thanks Felipe

sinoroc
  • 18,409
  • 2
  • 39
  • 70
  • but I tried adding line sys.path.insert(0, Path(os.path.abspath(__file__)).parent.parent.parent.parent.absolute()) To conf.py which should give me the directory above rtdtest/ and actually does it locally (considering that conf.py is located in rtdtest/docs/sphinx) and I got the same problem. I also tried to add different folders based on the current folder but didn't work as well. Should I be adding that folder to path in some other way? – Felipe Santana Jun 16 '23 at 17:28
  • sorry about the bold "file" word in the previous comment, it should be \_\_file\_\_ – Felipe Santana Jun 16 '23 at 17:40
  • You can not have `setup.py` in the same `directory` as `__init__.py`. You use `find_packages()` in `setup.py`, and as far as I know this function will not find the import package (the directory containing the `__init__.py`), if the `setup.py` is inside the import package. -- Check this [packaging tutorial](https://packaging.python.org/en/latest/tutorials/packaging-projects/) for a good and modern project directory structure. -- Usually if you have to do `sys.path` or `PYTHONPATH` modifications it is a red flag that the packaging is not correct. – sinoroc Jun 17 '23 at 07:55
  • Thanks a lot @sinoroc! I simply shifted the modules and the __init__.py file into a src/ folder, updated the new package name in the modules and the .rst file and then the documentation worked with no problems :) – Felipe Santana Jun 18 '23 at 17:12
  • @FelipeSantana Having `src/__init__.py` is another red flag. If you want `rtdtest` to be the top level import package, then you shoud have `src/rtdtest/__init__.py`. I recommend you look again more carefully at the project directory structure in the [packaging turoial](https://packaging.python.org/en/latest/tutorials/packaging-projects/). – sinoroc Jun 18 '23 at 17:44
  • You are right @sinorc, I just modified the package structure and put the modules inside a src/rtdtest/ folder. I also added lines "packages=find_packages('src')" and "package_dir={'':'src'}" to setup.py (I am using that instead of pyproject.toml) and modified the .readthedocs.yml file to contain python: version: 3.8 install: - method: pip path: . extra_requirements: - rtdtest Now the documentation works locally and in ReadTheDocs and I don't need the lines to modify the path in the conf.py Do you think this is appropriate? If you do I will update my answer – Felipe Santana Jun 19 '23 at 17:28
  • Yes, this seems the correct way. This is more or less how I do it in my projects. – sinoroc Jun 19 '23 at 17:57

1 Answers1

1

The problem was solved thanks to @sinoroc suggestion and the project structure suggested presented in this packaging tutorial. The structure of the project was causing problems because I had the __init__.py file in the root of the project along with setup.py.

Apparently that also produced problems for installing the package in some computers so it was extremely important to fix it.

I just created a /src/rtdtest folder within the root of the package and shifted the .py files there. Then I updated the new package name in the module's import statement and .rst files, I also added lines "packages=find_packages('src')" and "package_dir={'':'src'}" to setup.py, and modified the .readthedocs.yml file to contain:

python:
  version: 3.8
  install:
    - method: pip
      path: .
      extra_requirements:
        - rtdtest

Now the build in ReadTheDocs worked fine, creating documentation from the module's DocStrings as expected

  • Having `src/__init__.py` is another red flag. If you want `rtdtest` to be the top level import package, then you shoud have `src/rtdtest/__init__.py`. I recommend you look again more carefully at the project directory structure in the [packaging turoial](https://packaging.python.org/en/latest/tutorials/packaging-projects/). – sinoroc Jun 18 '23 at 17:43
  • Just edited this answer to reflect the new structure. Thanks again! – Felipe Santana Jun 20 '23 at 14:43