Подтвердить что ты не робот

Как правильно писать перекрестные ссылки на внешнюю документацию с помощью intersphinx?

Я пытаюсь добавить перекрестные ссылки на внешний API в мою документацию, но у меня есть три разных поведения.

Я использую sphinx (1.3.1) с Python (2.7.3), а мое межфиксное отображение настраивается как:

{
'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)
}

Мне не трудно написать перекрестную ссылку на numpy API с :class:`numpy.ndarray` или :func:`numpy.array`, которая дает мне, как и ожидалось, что-то вроде numpy.ndarray.

Однако, с h5py, единственный способ, которым я могу создать ссылку, - это опустить имя модуля. Например, :class:`Group` (или :class:`h5py:Group`) дает мне Group, но :class:`h5py.Group` не удается создать ссылку.

Наконец, я не могу найти способ написания рабочей перекрестной ссылки на API OpenCV, ни одна из них не работает:

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

Как правильно писать перекрестные ссылки на внешний API или настраивать interphinx, чтобы иметь сгенерированную ссылку, как в случае с numpy?

4b9b3361

Ответ 1

Я еще раз попытался понять содержимое файла objects.inv и, надеюсь, на этот раз я осмотрел numpy и h5py, а не только OpenCV.

Как прочитать файл инвентаря interphinx

Несмотря на то, что я не мог найти ничего полезного в чтении содержимого файла object.inv, на самом деле это очень просто с помощью модуля interphinx.

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 one вы можете видеть, что ключи являются доменами:

[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'-'),
 ...}

Вот почему я не мог заставить его работать как многозначные ссылки. Таким образом, хороший способ их форматирования будет :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 с этим файлом...

Заключение

Я думал, что interphinx генерирует objects.inv на основе содержимого проекта документации стандартным образом, что, похоже, не так. В результате кажется, что правильный способ записи перекрестных ссылок зависит от API, и нужно проверить конкретный объект инвентаризации, чтобы фактически увидеть, что доступно.

Ответ 2

В дополнение к подробному ответу от @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#L390

Ответ 3

Как использовать 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#$ -

Таким образом, предположительно вы связываетесь с документами OpenCV с :ocv:pyfunction:`cv2.imread` вместо :py:function:`cv2.imread`. Sphinx ему не нравится:

ПРЕДУПРЕЖДЕНИЕ: Неизвестная интерпретированная текстовая роль "ocv: pyfunction".

Немного Googling показал, что проект OpenCV имеет собственный домен "ocv" sphinx: https://github.com/opencv/opencv/blob/2.4/doc/ocv.py - предположительно потому, что им нужно для документирования API C, С++ и Python в одно и то же время.

Чтобы использовать его, сохраните ocv.py рядом с вашим Sphinx 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` (not :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.imread. Вы можете отредактировать ocv.py и удалить строку, которая печатает это предупреждение.

Ответ 4

Принятый ответ больше не работает в новой версии (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)