Python 重构模块并保持向后兼容性,包括intersphinx

Python 重构模块并保持向后兼容性,包括intersphinx,python,python-sphinx,api-design,Python,Python Sphinx,Api Design,给定一个python包pack提供pack.foo.Bar类: pack/ __init__.py # empty foo.py   # content of foo.py """ This module does stuff using the :class:`pack.foo.Bar` class. """ class Bar(object): pass

给定一个python包
pack
提供
pack.foo.Bar
类:

pack/
    __init__.py  # empty
    foo.py
        # content of foo.py
        """
        This module does stuff using the :class:`pack.foo.Bar` class.
        """

        class Bar(object):
            pass

        # much more code here
我想将
pack.foo
模块重构成一个包,以便
Bar
类被移动到
pack/foo/Bar.py
文件中。为了保持向后兼容性,我可以在
pack/foo/\uuuu init\uuuu.py
文件中添加以下内容:

"""
This module does stuff using the :class:`pack.foo.Bar` class.
"""

from pack.foo.bar import Bar
__all__ = ['Bar']
API用户仍然可以使用pack.foo导入栏中的

还有一个问题:使用sphinx时的引用。sphinx在
pack/foo/\uuuuu init\uuuuuu.py
中解析docstring时,找不到目标:

WARNING: py:class reference target not found pack.foo.bar.Bar
这将破坏用户在使用扩展时制作的文档


重构包结构并保持完全向后兼容性(包括sphinx对象清单)的正确方法是什么?

以下是我自己的答案和一些发现

在这种情况下没有什么灵丹妙药

首先,生成的代码文档将从文件布局推断模块布局。这意味着在
pack/foo.py
中定义的
Bar
类将被记录为
pack.foo.Bar
,无论在
pack/\uuuuu init\uuuuuu.py
中发生什么导入损坏

第二,我们仍然可以使用。Autodoc只是尝试正常导入文档化符号,因为它们是在重新构造的文本中定义的。这样,您就可以使用

.. autoclass:: pack.Bar
    :members:
不过有一个陷阱。任何记录的符号(以及它们的每个依赖项,以传递方式)都必须与打算记录的名称空间完全相同。考虑我们例子中的一个变体,提供一个附加类<代码> Baz < /代码>:

pack/
    __init__.py
        # content of __init__.py
        from pack.foo.bar import Bar, Baz
        __all__ = ['Bar', 'Baz']

    foo.py
        # content of foo.py
        """
        This module does stuff using the :class:`pack.foo.Bar` class.
        """

        class Bar(object):
            pass

        class Baz(Bar):  # Here, sphinx thinks that Baz inherits from
            pass         # pack.foo.Bar because Bar.__module__ is
                         # pack.foo in this context.
Sphinx将无法导入
pack.foo.Bar
,因为它只能作为
pack.Bar
导入,因为
pack/\uu init\uuuuuuuuuuuuupy
的内容

为了实现这一点,必须找到一种方法,在API代码本身中只使用包的API提供的精确导入布局。例如,在我们的示例中,可以通过在单独的文件中定义
Bar
Baz
类来实现这一点。祝你好运,小心循环进口