tkem/cachetools

Intersphinx looks for implementation modules

Closed this issue · 2 comments

In my project I have:
mymod.py:

class MyCache(cachetools.LRUCache): ...

mymod.rst:

.. autoclass:: mymod.MyCache
   :members:
   :undoc-members:
   :show-inheritance:

sphinx-build -W fails with:

mymod.py:docstring of mymod.MyCache:1: WARNING: 
py:class reference target not found: cachetools.lru.LRUCache

The problem is that, in objects.inv, the object appears (correctly) under its public module, but LRUCache.__module__ points to the implementation module:

$ python -m sphinx.ext.intersphinx https://cachetools.readthedocs.io/en/latest/objects.inv| grep LRUCache
        cachetools.LRUCache                      index.html#cachetools.LRUCache

Workaround

In conf.py:

import cachetools
cachetools.LRUCache.__module__ = "cachetools"

Solution

The __module__ hack above should be in cachetools.__init__.

External references

This issue is very common. Here's the exact same problem in two other projects:

Starting from Sphinx 3, this extends to anything that declares LRUCache in a type annotation.

tkem commented

@crusaderky: Good point, and thanks for your efforts analyzing this!
I already thought about "flattening" this module, i.e. putting all the cache classes and decorators of the cachetools modules in a single file, as is usually done by the Python standard library. However, this also has some drawbacks ;-)
Your "workaround" sounds somewhat reasonable, but I'll keep watching how other packages decide to handle this for a while.