如何在 readthedocs 上正确设置 PyQt5 导入?
How to correctly setup for PyQt5 imports on readthedocs?
使用
构建 project importing PyQt5 fails (build log) 的 sphinx 文档
QStandardPaths: XDG_RUNTIME_DIR not set, defaulting to '/tmp/runtime-docs'
qt.qpa.screen: QXcbConnection: Could not connect to display
Could not connect to any X display.
在 tox.ini
中需要以下内容:
[testenv:docs]
# avoid QStandardPaths: XDG_RUNTIME_DIR not set
passenv = XDG_RUNTIME_DIR
# xvfb-run prevents Could not connect to any X display
commands = /usr/bin/xvfb-run sphinx-build --color -W -b html -d {envtmpdir}/doctrees . {envtmpdir}/html
如何在 readthedocs 上做到这一点?
这与PyQt 4 import in read-the-docs密切相关,
不幸的是,它不包含错误消息。并且 PyQt5 是 可从 pip 安装。
备注:
- 在高级设置中,
Install your project inside a virtualenv using setup.py install
被选中(但取消选中没有帮助)。
- 以下暂定的参考 geoptics 快照是
f33d233bf67bd7922ec864635e7589e7f4feb40f
暂定
1。使用模拟模块
也许mocking PyQT5 could work. But this seems a bit .
改编自 this answer,添加
import mock
MOCK_MODULES = ['sip', 'PyQt5', 'PyQt5.QtGui', 'PyQt5.QtCore', 'PyQt5.QtWidgets']
sys.modules.update((mod_name, mock.MagicMock()) for mod_name in MOCK_MODULES)
到conf.py
产量
class _GRay(GCounterPart, QGraphicsPathItem):
TypeError: metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases
2。使用内置的狮身人面像 autodoc_mock_imports
同样的错误与更简单的(只添加了一行 conf.py
)
autodoc_mock_imports = ['sip', 'PyQt5', 'PyQt5.QtGui', 'PyQt5.QtCore', 'PyQt5.QtWidgets']
3。使用自定义 Mock
使用julen's custom Mock class
class Mock(object):
def __init__(self, *args, **kwargs):
pass
def __call__(self, *args, **kwargs):
return Mock()
@classmethod
def __getattr__(cls, name):
if name in ('__file__', '__path__'):
return '/dev/null'
elif name[0] == name[0].upper():
mockType = type(name, (), {})
mockType.__module__ = __name__
return mockType
else:
return Mock()
MOCK_MODULES = ['sip', 'PyQt5', 'PyQt5.QtGui', 'PyQt5.QtCore', 'PyQt5.QtWidgets']
for mod_name in MOCK_MODULES:
sys.modules[mod_name] = Mock()
产量
File ".../geoptics/guis/qt/main.py", line 59, in <module>
app = QCoreApplication.instance()
AttributeError: type object 'QCoreApplication' has no attribute 'instance'
应该可以将 app
definition/retrieval 内容从模块级别移动到函数体,而不是在模块导入时执行。
4。 autodoc_mock_imports
没有多重继承
autodoc_mock_imports = ['sip', 'PyQt5', 'PyQt5.QtGui', 'PyQt5.QtCore', 'PyQt5.QtWidgets']
在conf.py
中,与第二个暂定的一样,但多重继承被装饰器取代了。 pull request.
中描述了更改
现在错误是
geoptics.guis.qt.handles.LineHandle.reset_move:1:term not in glossary: move restrictions
因为定义该术语的地理光学 class _GScene(QGraphicsScene)
已被 sphinx 模拟掉,其文档丢失。
相关问题留下的评论:
autodoc_mock_imports
已经 fixed in sphinx-1.7.5。
在 docs/conf.py
中添加以下行:
autodoc_mock_imports = ['sip', 'PyQt5', 'PyQt5.QtGui', 'PyQt5.QtCore', 'PyQt5.QtWidgets']
然后,用一行
创建一个docs/requirements.txt
sphinx>=1.7.5
并在 readthedocs 项目中声明 docs/requirements.txt
admin>advanced settings>Requirements file
.
幸运的是,这并没有绕过 setup.py,它只是添加了 sphinx-1.7.5 版本要求。
使用
构建 project importing PyQt5 fails (build log) 的 sphinx 文档QStandardPaths: XDG_RUNTIME_DIR not set, defaulting to '/tmp/runtime-docs'
qt.qpa.screen: QXcbConnection: Could not connect to display
Could not connect to any X display.
在 tox.ini
中需要以下内容:
[testenv:docs]
# avoid QStandardPaths: XDG_RUNTIME_DIR not set
passenv = XDG_RUNTIME_DIR
# xvfb-run prevents Could not connect to any X display
commands = /usr/bin/xvfb-run sphinx-build --color -W -b html -d {envtmpdir}/doctrees . {envtmpdir}/html
如何在 readthedocs 上做到这一点?
这与PyQt 4 import in read-the-docs密切相关, 不幸的是,它不包含错误消息。并且 PyQt5 是 可从 pip 安装。
备注:
- 在高级设置中,
Install your project inside a virtualenv using setup.py install
被选中(但取消选中没有帮助)。 - 以下暂定的参考 geoptics 快照是
f33d233bf67bd7922ec864635e7589e7f4feb40f
暂定
1。使用模拟模块
也许mocking PyQT5 could work. But this seems a bit
改编自 this answer,添加
import mock
MOCK_MODULES = ['sip', 'PyQt5', 'PyQt5.QtGui', 'PyQt5.QtCore', 'PyQt5.QtWidgets']
sys.modules.update((mod_name, mock.MagicMock()) for mod_name in MOCK_MODULES)
到conf.py
产量
class _GRay(GCounterPart, QGraphicsPathItem):
TypeError: metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases
2。使用内置的狮身人面像 autodoc_mock_imports
同样的错误与更简单的(只添加了一行 conf.py
)
autodoc_mock_imports = ['sip', 'PyQt5', 'PyQt5.QtGui', 'PyQt5.QtCore', 'PyQt5.QtWidgets']
3。使用自定义 Mock
使用julen's custom Mock class
class Mock(object):
def __init__(self, *args, **kwargs):
pass
def __call__(self, *args, **kwargs):
return Mock()
@classmethod
def __getattr__(cls, name):
if name in ('__file__', '__path__'):
return '/dev/null'
elif name[0] == name[0].upper():
mockType = type(name, (), {})
mockType.__module__ = __name__
return mockType
else:
return Mock()
MOCK_MODULES = ['sip', 'PyQt5', 'PyQt5.QtGui', 'PyQt5.QtCore', 'PyQt5.QtWidgets']
for mod_name in MOCK_MODULES:
sys.modules[mod_name] = Mock()
产量
File ".../geoptics/guis/qt/main.py", line 59, in <module>
app = QCoreApplication.instance()
AttributeError: type object 'QCoreApplication' has no attribute 'instance'
应该可以将 app
definition/retrieval 内容从模块级别移动到函数体,而不是在模块导入时执行。
4。 autodoc_mock_imports
没有多重继承
autodoc_mock_imports = ['sip', 'PyQt5', 'PyQt5.QtGui', 'PyQt5.QtCore', 'PyQt5.QtWidgets']
在conf.py
中,与第二个暂定的一样,但多重继承被装饰器取代了。 pull request.
现在错误是
geoptics.guis.qt.handles.LineHandle.reset_move:1:term not in glossary: move restrictions
因为定义该术语的地理光学 class _GScene(QGraphicsScene)
已被 sphinx 模拟掉,其文档丢失。
相关问题留下的评论:
autodoc_mock_imports
已经 fixed in sphinx-1.7.5。
在 docs/conf.py
中添加以下行:
autodoc_mock_imports = ['sip', 'PyQt5', 'PyQt5.QtGui', 'PyQt5.QtCore', 'PyQt5.QtWidgets']
然后,用一行
创建一个docs/requirements.txtsphinx>=1.7.5
并在 readthedocs 项目中声明 docs/requirements.txt
admin>advanced settings>Requirements file
.
幸运的是,这并没有绕过 setup.py,它只是添加了 sphinx-1.7.5 版本要求。