web-dev-qa-db-ja.com

intersphinxを使用して外部ドキュメントへの相互参照を適切に作成するにはどうすればよいですか?

外部APIへの相互参照をドキュメントに追加しようとしていますが、3つの異なる動作に直面しています。

Python(2.7.3)でsphinx(1.3.1)を使用しており、sphinx間マッピングは次のように構成されています。

{
'python': ('https://docs.python.org/2.7', None),
'numpy': ('http://docs.scipy.org/doc/numpy/', None),
'cv2' : ('http://docs.opencv.org/2.4/', None),
'h5py' : ('http://docs.h5py.org/en/latest/', None)
}

:class:`numpy.ndarray`または:func:`numpy.array`を使用してnumpyAPIへの相互参照を記述しても問題はありません。これにより、予想どおり、 numpy.ndarray のようになります。

ただし、h5pyを使用する場合、リンクを生成する唯一の方法は、モジュール名を省略した場合です。たとえば、:class:`Group`(または:class:`h5py:Group`)は私に Group を与えますが、:class:`h5py.Group`はリンクの生成に失敗します。

最後に、OpenCV APIへの有効な相互参照を作成する方法が見つかりません。これらはいずれも機能していないようです:

:func:`cv2.convertScaleAbs`
:func:`cv2:cv2.convertScaleAbs`
:func:`cv2:convertScaleAbs`
:func:`convertScaleAbs`

Numpyの場合のように生成されたリンクを持つように、外部APIへの相互参照を適切に書き込むか、intersphinxを構成する方法は?

23
Gall

objects.invファイルの内容を理解するためにもう一度試してみましたが、今回はOpenCVだけでなくnumpyとh5pyを調べたといいのですが。

Sphinx間インベントリファイルの読み方

object.invファイルの内容を読み取るのに役立つものが見つからなかったという事実にもかかわらず、intersphinxモジュールを使用すると実際には非常に簡単です。

from sphinx.ext import intersphinx
import warnings


def fetch_inventory(uri):
    """Read a Sphinx inventory file into a dictionary."""
    class MockConfig(object):
        intersphinx_timeout = None  # type: int
        tls_verify = False

    class MockApp(object):
        srcdir = ''
        config = MockConfig()

        def warn(self, msg):
            warnings.warn(msg)

    return intersphinx.fetch_inventory(MockApp(), '', uri)


uri = 'http://docs.python.org/2.7/objects.inv'

# Read inventory into a dictionary
inv = fetch_inventory(uri)
# Or just print it
intersphinx.debug(['', uri])

ファイル構造(numpy)

Numpyのものを調べた後、キーがドメインであることがわかります。

[u'np-c:function',
 u'std:label',
 u'c:member',
 u'np:classmethod',
 u'np:data',
 u'py:class',
 u'np-c:member',
 u'c:var',
 u'np:class',
 u'np:function',
 u'py:module',
 u'np-c:macro',
 u'np:exception',
 u'py:method',
 u'np:method',
 u'np-c:var',
 u'py:exception',
 u'np:staticmethod',
 u'py:staticmethod',
 u'c:type',
 u'np-c:type',
 u'c:macro',
 u'c:function',
 u'np:module',
 u'py:data',
 u'np:attribute',
 u'std:term',
 u'py:function',
 u'py:classmethod',
 u'py:attribute']

特定のドメインのコンテンツを見ると、相互参照をどのように記述できるかがわかります。例:py:class

{u'numpy.DataSource': (u'NumPy',
  u'1.9',
  u'http://docs.scipy.org/doc/numpy/reference/generated/numpy.DataSource.html#numpy.DataSource',
  u'-'),
 u'numpy.MachAr': (u'NumPy',
  u'1.9',
  u'http://docs.scipy.org/doc/numpy/reference/generated/numpy.MachAr.html#numpy.MachAr',
  u'-'),
 u'numpy.broadcast': (u'NumPy',
  u'1.9',
  u'http://docs.scipy.org/doc/numpy/reference/generated/numpy.broadcast.html#numpy.broadcast',
  u'-'),
  ...}

したがって、ここでは、:class:`numpy.DataSource`は期待どおりに機能します。

h5py

H5pyの場合、ドメインは次のとおりです。

[u'py:attribute', u'std:label', u'py:method', u'py:function', u'py:class']

py:classドメインを見ると:

{u'AttributeManager': (u'h5py',
  u'2.5',
  u'http://docs.h5py.org/en/latest/high/attr.html#AttributeManager',
  u'-'),
 u'Dataset': (u'h5py',
  u'2.5',
  u'http://docs.h5py.org/en/latest/high/dataset.html#Dataset',
  u'-'),
 u'ExternalLink': (u'h5py',
  u'2.5',
  u'http://docs.h5py.org/en/latest/high/group.html#ExternalLink',
  u'-'),
 ...}

そのため、Numpyリファレンスとして機能させることができませんでした。したがって、それらをフォーマットする良い方法は:class:`h5py:Dataset`です。

OpenCV

OpenCVのインベントリオブジェクトの形式が正しくないようです。ドメインを見つけることを期待するところには、実際には902の関数シグネチャがあります。

[u':',
 u'AdjusterAdapter::create(const',
 u'AdjusterAdapter::good()',
 u'AdjusterAdapter::tooFew(int',
 u'AdjusterAdapter::tooMany(int',
 u'Algorithm::create(const',
 u'Algorithm::getList(vector<string>&',
 u'Algorithm::name()',
 u'Algorithm::read(const',
 u'Algorithm::set(const'
 ...]

そして、最初の値を取る場合:

{u'Ptr<AdjusterAdapter>': (u'OpenCV',
  u'2.4',
  u'http://docs.opencv.org/2.4/detectorType)',
  u'ocv:function 1 modules/features2d/doc/common_interfaces_of_feature_detectors.html#$ -')}

その場合、このファイルでOpenCV相互参照を書き込むことは不可能であると確信しています...

結論

Intersphinxは、ドキュメントプロジェクトの内容に基づいて標準の方法でobjects.invを生成したと思いましたが、そうではないようです。その結果、相互参照を記述する適切な方法はAPIに依存しているようであり、特定のインベントリオブジェクトを調べて、実際に何が利用できるかを確認する必要があります。

24
Gall

@gallからの詳細な回答に加えて、intersphinxもモジュールとして実行できることを発見しました。

python -m sphinx.ext.intersphinx 'http://python-eve.org/objects.inv'

これにより、適切にフォーマットされた情報が出力されます。参考: https://github.com/sphinx-doc/sphinx/blob/master/sphinx/ext/intersphinx.py#L39

22
lingfish

OpenCV 2.4(cv2)intersphinxの使用方法

@Gallの回答に触発されて、OpenCVとnumpyインベントリファイルの内容を比較したいと思いました。 sphinx.ext.intersphinx.fetch_inventoryをipythonから機能させることができませんでしたが、以下は機能します。

curl http://docs.opencv.org/2.4/objects.inv | tail -n +5 | zlib-flate -uncompress > cv2.inv
curl https://docs.scipy.org/doc/numpy/objects.inv | tail -n +5 | zlib-flate -uncompress > numpy.inv

numpy.invには次のような行があります:

numpy.ndarray py:class 1 reference/generated/numpy.ndarray.html#$ -

一方、cv2.invには次のような行があります。

cv2.imread ocv:pyfunction 1 modules/highgui/doc/reading_and_writing_images_and_video.html#$ -

したがって、おそらく、:ocv:pyfunction:`cv2.imread`ではなく:py:function:`cv2.imread`を使用してOpenCVドキュメントにリンクします。 Sphinxはそれが好きではありません:

警告:不明な解釈済みテキストロール「ocv:pyfunction」。

少しグーグルすると、OpenCVプロジェクトには独自の「ocv」スフィンクスドメインがあることが明らかになりました: https://github.com/opencv/opencv/blob/2.4/doc/ocv.py -おそらくC、C++、Python APIをすべて同時に文書化する必要があります。

これを使用するには、Sphinx ocv.pyの横にconf.pyを保存し、conf.pyを変更します。

sys.path.insert(0, os.path.abspath('.'))
import ocv
extensions = [
    'ocv',
]
intersphinx_mapping = {
    'cv2': ('http://docs.opencv.org/2.4/', None),
}

最初のファイルでは、:ocv:pyfunc:`cv2.imread`:ocv:pyfunction:ではありません)と言う必要があります。

Sphinxはいくつかの警告(unparseable C++ definition: u'cv2.imread')を出力しますが、生成されたhtmlドキュメントは実際には http://docs.opencv.org/2.4/modules/highgui/doc/reading_and_writing_images_and_video.html#cv2)へのリンクで問題ないように見えます。 .imreadocv.pyを編集して、その警告を出力する行を削除できます。

objects.invファイルを検査する追加の方法は、 sphobjinv モジュールを使用することです。

ローカルまたはリモートのインベントリファイルを検索できます(あいまい一致を使用)。たとえば、scipyの場合:

$ sphobjinv suggest -t 90 -u https://docs.scipy.org/doc/scipy/reference/objects.inv "signal.convolve2d"

Remote inventory found.

:py:function:`scipy.signal.convolve2d`
:std:doc:`generated/scipy.signal.convolve2d`

:py:func:ではなく:py:function:を使用する必要がある場合があることに注意してください(理由を知っていただければ幸いです)。

2
Francis Colas

受け入れられた回答は、新しいバージョン(1.5.x)では機能しなくなりました...

import requests
import posixpath
from sphinx.ext.intersphinx import read_inventory

uri = 'http://docs.python.org/2.7/'

r = requests.get(uri + 'objects.inv', stream=True)
r.raise_for_status()

inv = read_inventory(r.raw, uri, posixpath.join)
1
Eric