Search code examples
pythonbuildpython-sphinxread-the-docsautodoc

Readthedocs ModuleNotFoundError from the init in a requirements library


I wonder if anyone could help me with this issue:

I am trying to upload my library documentation to readthedocs. The sphinx documentation fully compiles on my computer. However, the build fails at the readthedocs dashboard. This is the error:

Processing /home/docs/checkouts/readthedocs.org/user_builds/specsy/checkouts/latest
  Preparing metadata (setup.py): started
  Preparing metadata (setup.py): finished with status 'done'
Collecting numpy
  Downloading numpy-1.23.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (17.1 MB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 17.1/17.1 MB 142.8 MB/s eta 0:00:00
Collecting matplotlib
  Downloading matplotlib-3.5.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl (11.3 MB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 11.3/11.3 MB 144.7 MB/s eta 0:00:00
Collecting pandas
  Downloading pandas-1.4.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (11.7 MB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 11.7/11.7 MB 141.7 MB/s eta 0:00:00
Collecting astropy
  Downloading astropy-5.1-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl (11.1 MB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 11.1/11.1 MB 146.2 MB/s eta 0:00:00
Collecting lime
  Downloading lime-0.2.0.1.tar.gz (275 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 275.7/275.7 kB 252.6 MB/s eta 0:00:00
  Preparing metadata (setup.py): started
  Preparing metadata (setup.py): finished with status 'done'
Collecting pyneb
  Downloading PyNeb-1.1.15.tar.gz (25.1 MB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 25.1/25.1 MB 141.3 MB/s eta 0:00:00
  Preparing metadata (setup.py): started
  Preparing metadata (setup.py): finished with status 'error'
  error: subprocess-exited-with-error
  
  × python setup.py egg_info did not run successfully.
  │ exit code: 1
  ╰─> [15 lines of output]
      Traceback (most recent call last):
        File "/tmp/pip-install-ly67tghn/pyneb_2849cf71307b466b98eb4ad9a85cdddb/pyneb/__init__.py", line 21, in <module>
          from numpy.version import version as numpy_version
      ModuleNotFoundError: No module named 'numpy'
      
      During handling of the above exception, another exception occurred:
      
      Traceback (most recent call last):
        File "<string>", line 2, in <module>
        File "<pip-setuptools-caller>", line 34, in <module>
        File "/tmp/pip-install-ly67tghn/pyneb_2849cf71307b466b98eb4ad9a85cdddb/setup.py", line 14, in <module>
          from pyneb.version import __version__
        File "/tmp/pip-install-ly67tghn/pyneb_2849cf71307b466b98eb4ad9a85cdddb/pyneb/__init__.py", line 25, in <module>
          log_.warn('I do not understand what is your version of numpy: {0}, report this to PyNeb group'.format(numpy_version), calling='PyNeb')
      NameError: name 'numpy_version' is not defined
      [end of output]
  
  note: This error originates from a subprocess, and is likely not a problem with pip.
error: metadata-generation-failed

× Encountered error while generating package metadata.
╰─> See above for output.

note: This is an issue with the package mentioned above, not pip.
hint: See above for details.

If I undersand the issue correctly, one of my requirements library (pyneb) is failing to find another of my requirements libraries (numpy). If I remove the first library, the requirements are collected properly (but the build fails eventually while trying to build the documentation with the autodoc).

So I think this has to do on how this library tries to import the first library (numpy) from its init. This is the begining of the file:

"""
PyNeb - python package for the analysis of emission lines
"""

__all__ = []
from .version import __version__

import sys
__pyversion__ = sys.version_info[0]

from .utils.Config import _Config
config = _Config()
log_ = config.log_
log_.message('Starting PyNeb version %s' % __version__, calling='PyNeb')


if sys.version_info[0:2] < (2, 6):
    log_.warn('Python version >= 2.6 needed, seems you have {0}'.format(sys.version_info), calling='PyNeb')

try:
    from numpy.version import version as numpy_version    
    if [int(n) for n in (numpy_version.split('.')[:3])] < [1, 5, 1] :
        log_.warn('Numpy version >= 1.5.1 needed, seems you have {0}'.format(numpy_version), calling='PyNeb')
except:
    log_.warn('I do not understand what is your version of numpy: {0}, report this to PyNeb group'.format(numpy_version), calling='PyNeb')

What should I do to make sure the second library uses a former requirement library during the readthedocs build?


Solution

  • This looks like PyNeb has not declared NumPy as an install-time dependency. Nowadays this is done in the build-system.requires key of pyproject.toml, following PEP 518:

    [build-system]
    requires = ["wheel", "setuptools", "oldest-supported-numpy"]
    build-backend = "setuptools.build_meta"
    

    (see oldest-supported-numpy docs)

    The new pyproject.toml file is compatible with existing setup.py-based setuptools packages. There's a small probability that the presence of the file affects you negatively, please keep an eye on this thread about the effects of pyproject.toml on legacy projects.

    Having said that, it's very clear that the goal is to deprecate and abandon setup.py files. So, the sooner you migrate your project metadata to pyproject.toml, the better. You can keep using setuptools.