Sphinx 和 autodoc:numpy.core.multiarray 导入失败 + mock 具有不受支持的操作数类型
Sphinx and autodoc: numpy.core.multiarray failed to import + mock has unsupported operand type
我正在尝试为我的项目构建文档 (https://github.com/pyMatJ/S4Utils) using sphinx and autodoc, targeting RtD eventually (https://s4utils.readthedocs.io/en/latest/)。
到目前为止,我设法使整个项目可安装,我认为我的 setup.py 是正确的。但是,我无法让 sphinx 使用 autodoc 正确生成文档。我使用 virtualenvwrapper 设置了一个干净的 python3.6 venv,只安装了 sphinx 和我的包并尝试编译文档 (make html
)。带有手动输入(安装等)的页面以及一个自动记录的模块(https://s4utils.readthedocs.io/en/latest/epsInterpolator.html)工作正常。
但是,大部分 autodoc 作业仍然缺失(应该记录另外两个模块),并且我收到一堆关于 autodoc 无法导入模块的警告。最终看起来它归结为两个主要错误:
hbar_eV = h_eV/(2*np.pi)
TypeError: unsupported operand type(s) for *: 'int' and 'Mock'
从一个模块在其序言中导入 numpy 并使用它来定义变量
以及
numpy.core.multiarray failed to import
for both modules.
RtD 和干净的 venv 都重现了错误。我检查过只安装了一个版本的 numpy(最新版本,1.19.1)。我使用 conf.py
文件导入模拟,并模拟相关的(我想)模块:
from unittest.mock import Mock as MagicMock
MOCK_MODULES = ['numpy', 'matplotlib.pyplot', 'matplotlib.gridspec', 'matplotlib.widgets', 'pyvista']
for mod_name in MOCK_MODULES:
sys.modules[mod_name] = MagicMock()
我将文件路径添加到 sys.path
以允许 autodoc 相对于 docs 目录找到它们 (sys.path.insert(0, os.path.abspath('../../'))
)
关于失败的 numpy 导入:我有点困惑,因为它在一个自动记录的文件中得到了正确处理。那么,为什么只有三分之二的导入失败(它们在序言中都有相同的 import numpy as np
语句)?我花了几个小时寻找类似的问题,但只找到了有关 numpy 安装冲突的答案,我相信我没有。我该如何解决这个问题?
关于Mock报错,我试着按照https://github.com/seb-m/pyinotify/issues/110的思路,重新定义了几个mock函数,让它接受乘法运算:
class Mock(MagicMock):
@classmethod
def __getattr__(cls, name):
return Mock()
def __mul__(self, other):
return Mock()
def __rmul__(self, other):
return Mock()
def __pow__(self, other):
return Mock()
def __div__(self, other):
return Mock()
没有任何效果。我可以通过将此操作放在 class 中或在需要的地方定义它来消除错误,但这很烦人,它定义了一个物理常量,该常量可能在整个模块的多个 classes/functions 中使用稍后的。如何让 mock
接受乘法?
如果这可能有帮助,这里是目录结构的相关部分:
--moduleroot/
|--docs/
| |--requirements.txt
| |--Makefile
| |--make.bat
| |--source/
| | |--conf.py
| | |--rstfiles-for-doc
| |--build/
|--module/
| |--__init__.py (probably useless?)
| |--Module1.py
| |--Module2.py
| |--Module3.py
|--setup.py
|--Manifest.in
提前谢谢你,在这一点上任何帮助将不胜感激,因为我不知道我做错了什么......(如果这太长,我很抱歉,因为我不知道出了什么问题我尽量提供尽可能多的相关信息)。
这解决了以下问题:
使用 autodoc_mock_imports
配置变量指定要模拟的模块。
当模拟 NumPy 时,np.pi
不起作用。 hbar_eV = h_eV/(2*np.pi)
是每次 Sphinx 运行时执行的模块级代码。要解决这个问题,请改用 math.pi
。
我正在尝试为我的项目构建文档 (https://github.com/pyMatJ/S4Utils) using sphinx and autodoc, targeting RtD eventually (https://s4utils.readthedocs.io/en/latest/)。
到目前为止,我设法使整个项目可安装,我认为我的 setup.py 是正确的。但是,我无法让 sphinx 使用 autodoc 正确生成文档。我使用 virtualenvwrapper 设置了一个干净的 python3.6 venv,只安装了 sphinx 和我的包并尝试编译文档 (make html
)。带有手动输入(安装等)的页面以及一个自动记录的模块(https://s4utils.readthedocs.io/en/latest/epsInterpolator.html)工作正常。
但是,大部分 autodoc 作业仍然缺失(应该记录另外两个模块),并且我收到一堆关于 autodoc 无法导入模块的警告。最终看起来它归结为两个主要错误:
hbar_eV = h_eV/(2*np.pi)
TypeError: unsupported operand type(s) for *: 'int' and 'Mock'
从一个模块在其序言中导入 numpy 并使用它来定义变量
以及
numpy.core.multiarray failed to import for both modules.
RtD 和干净的 venv 都重现了错误。我检查过只安装了一个版本的 numpy(最新版本,1.19.1)。我使用 conf.py
文件导入模拟,并模拟相关的(我想)模块:
from unittest.mock import Mock as MagicMock
MOCK_MODULES = ['numpy', 'matplotlib.pyplot', 'matplotlib.gridspec', 'matplotlib.widgets', 'pyvista']
for mod_name in MOCK_MODULES:
sys.modules[mod_name] = MagicMock()
我将文件路径添加到 sys.path
以允许 autodoc 相对于 docs 目录找到它们 (sys.path.insert(0, os.path.abspath('../../'))
)
关于失败的 numpy 导入:我有点困惑,因为它在一个自动记录的文件中得到了正确处理。那么,为什么只有三分之二的导入失败(它们在序言中都有相同的
import numpy as np
语句)?我花了几个小时寻找类似的问题,但只找到了有关 numpy 安装冲突的答案,我相信我没有。我该如何解决这个问题?关于Mock报错,我试着按照https://github.com/seb-m/pyinotify/issues/110的思路,重新定义了几个mock函数,让它接受乘法运算:
class Mock(MagicMock):
@classmethod
def __getattr__(cls, name):
return Mock()
def __mul__(self, other):
return Mock()
def __rmul__(self, other):
return Mock()
def __pow__(self, other):
return Mock()
def __div__(self, other):
return Mock()
没有任何效果。我可以通过将此操作放在 class 中或在需要的地方定义它来消除错误,但这很烦人,它定义了一个物理常量,该常量可能在整个模块的多个 classes/functions 中使用稍后的。如何让 mock
接受乘法?
如果这可能有帮助,这里是目录结构的相关部分:
--moduleroot/
|--docs/
| |--requirements.txt
| |--Makefile
| |--make.bat
| |--source/
| | |--conf.py
| | |--rstfiles-for-doc
| |--build/
|--module/
| |--__init__.py (probably useless?)
| |--Module1.py
| |--Module2.py
| |--Module3.py
|--setup.py
|--Manifest.in
提前谢谢你,在这一点上任何帮助将不胜感激,因为我不知道我做错了什么......(如果这太长,我很抱歉,因为我不知道出了什么问题我尽量提供尽可能多的相关信息)。
这解决了以下问题:
使用
autodoc_mock_imports
配置变量指定要模拟的模块。当模拟 NumPy 时,
np.pi
不起作用。hbar_eV = h_eV/(2*np.pi)
是每次 Sphinx 运行时执行的模块级代码。要解决这个问题,请改用math.pi
。