2

I am trying to use ..autosummary to document a module that replaces itself with a class upon import (lazy importing). Without lazy imports the module looks like this:

""" The demp_project package

The demp_project consists of the following classes

.. autosummary::
    :toctree: _autosummary

    demp_project.Foo
    demp_project.Bar

"""


class Foo:
    """ Summary of class Foo
    
    Here comes extensive documentation.
    
    """


class Bar:
    """ Summary of class Bar

    even more extensive documentation.
    
    """

Sphinx enters the above via .. automodule:: demp_project. However, when I now add the lazy importing hook, building the documentation breaks on python 3.9 and 3.10 (python 3.7 and 3.8 work fine), i.e., the documentation for the classes Foo and Bar is not generated anymore. Instead I get the following warning:

docstring of demp_project:5:autosummary: stub file not found 'demp_project.Foo'. Check your autosummary_generate setting.

This is how the module looks like after modifying it for lazy importing:

import sys

class Foo:
    """ Summary of class Foo
    
    Here comes extensive documentation.
    
    """


class Bar:
    """ Summary of class Bar

    even more extensive documentation.
    
    """

class LazyImporter:
    """ The demp_project package

    The demp_project consists of the following classes:

    .. autosummary::
        :toctree: _autosummary

        demp_project.Foo
        demp_project.Bar

    """

    __name__ = __name__

    def __getattr__(self, name):
        """Lazy-Import Awesome Things

        Note: this doesn't actually lazy import here, because everything is in
        the same file for demo purposes. In the real world, this calls
        importlib.import_module to make the magic happen.

        """

        if name == "Foo":
            return Foo
        elif name == "Bar":
            return Bar
        else:
            raise AttributeError(f"module '{__name__}' has no attribute '{name}'")

sys.modules[__name__] = LazyImporter()

Could somebody explain to me why this breaks? Also, why does it work for python <= 3.8?

For reference, I made a repo containing the full demo project. The main branch builds the docs normally (first code block), and the PR introduces lazy importing (second code block).

Note: the repo has CI that builds the docs on python 3.7 - 3.10 to demo the problem with different python versions.

mzjn
  • 48,958
  • 13
  • 128
  • 248
FirefoxMetzger
  • 2,880
  • 1
  • 18
  • 32
  • 1
    @mzjn Sorry, I meant odd in that you can't reproduce it, which would indicate that we are doing something different. I added the line that you suggested to `conf.py` and tried it on python 3.10.0 (Windows 11) and it produces above warning (on python 3.8 it works fine). I also have the CI (link in the question) that runs on ubuntu 20.04 and produces the warning for python 3.9 and python 3.10. What could the difference between our setups be? – FirefoxMetzger Feb 04 '22 at 18:44
  • I agree that is is very odd that it works in CI with Python 3.7 and 3.8, but not with 3.9 and 3.10. – mzjn Feb 04 '22 at 18:59
  • I have now tried this on two other platforms (Python 3.6.8 & Sphinx 4.3.1 on RHEL8; Python 3.8.10 & Sphinx 4.4.0 on Ubuntu 20.04), and it works on both. – mzjn Feb 07 '22 at 14:33
  • @mzjn Yes, that matches my results. It works fine up until python 3.8 but breaks on 3.9 and above – FirefoxMetzger Feb 08 '22 at 18:16

0 Answers0