isaacsultan
isaacsultan

Reputation: 3974

ReadTheDocs Import Error from __init__.py

I am having trouble with readthedocs autodocs - the build completes but my documentation is empty for each class.

Looking at the build information, seem to be getting a Syntax Error which causes a few warning:

print(clean_sample, file=open(new_fname, 'w'))

However, this does not seem like a bug to me at all.

Here is the build information https://readthedocs.org/projects/medembed/builds/7108142/

My file structure is:

MedEmbed/
  docs/
    build/
    source/
      code.rst
      conf.py
      index.rst
  medembed/
    __init.py
    main.py
    transformer.py
    dataset.py
    embedding.py

As such I added within conf.py:

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

I could really appreciate some advice please

EDIT: Python3 Sphinx solved the above.

Now, I am importing a constant DIR_PROCESSED from init.py

For some reason Sphinx does not like this:

from medembed import DIR_PROCESSED
ImportError: No module named 'medembed

The build failed: https://readthedocs.org/projects/medembed/builds/7108602/

Upvotes: 2

Views: 796

Answers (1)

julienc
julienc

Reputation: 20305

There were multiple things that were not working correctly with Sphinx.

  • code.rst: you should indicate the package name for every module you want to run autodoc on:

    .. automodule:: medembed.main
       :members:
    
    .. automodule:: medembed.dataset
       :members:
    
    .. automodule:: medembed.embedding
       :members:
    
    .. automodule:: medembed.transformer
       :members:
    
  • conf.py: the path you want to add to SYSPATH is the path to the package's parent directory, not the package itself:

    sys.path.insert(0, os.path.abspath('../../'))
    
  • main.py, dataset.py, embedding.py, transformer.py: you should use relative imports instead of absolute ones, when importing stuff from within your package:

    -from transformer import Transformer
    +from .transformer import Transformer
    
    -from medembed import DIR_PROCESSED
    +from . import DIR_PROCESSED
    
    -from dataset import TxtDataset, XMLDataset
    -from embedding import Embedding
    +from .dataset import TxtDataset, XMLDataset
    +from .embedding import Embedding
    
  • main.py: don't add if __name__ == "__main__" directive: the code would be executed when analyzed by Sphinx, and this is not what you want (see this post). In fact, sphinx forbids this and returns a warning if you try:

    WARNING: autodoc: failed to import module 'medembed.main'; the module executes module level statement and it might call sys.exit().
    

    What you should do instead is create a main.py in the parent directory that won't be analyzed by sphinx:

    from medembed.main import main
    
    if __name__ == '__main__':
        main()
    

    I'm using an absolute import here as this main.py file is not in the medembed package.

I created a pull request on your repo with all these changes: https://github.com/isaacsultan/MedEmbed/pull/4

Upvotes: 4

Related Questions