Sphinx autodo c не отображает все типы или циклическую ошибку импорта - PullRequest
0 голосов
/ 16 апреля 2020

Я пытаюсь автоматически документировать типы документов с помощью sphinx autodo c, napoleon и autodoc_typehints, но у меня возникают проблемы, так как он не работает с большинством моих типов. Я использую пакет deap для выполнения некоторого алгоритма оптимизации geneti c, благодаря которому у меня есть несколько очень специфических c типов, которые, я думаю, sphinx не может обработать.

Мой conf.py файл выглядит следующим образом :

import os
import sys
sys.path.insert(0, os.path.abspath('../python'))

extensions = [
    'sphinx.ext.autodoc',
    'sphinx.ext.viewcode',
    'sphinx.ext.napoleon',
    'sphinx_autodoc_typehints'
]


set_type_checking_flag = False
always_document_param_types = False

У меня есть файл Algo.rst с:

.. automodule:: python.algo.algo
     :members: crossover_worker,
               test

, и мой модуль python.algo.algo выглядит следующим образом (я добавил фиктивную функцию тестирования, чтобы показать, что она работает всякий раз, когда у меня не указаны специальные типы):

# Type hinting imports
from config.config import Config
from typing import List, Set, Dict, NamedTuple, Union, Tuple
from types import ModuleType
from numpy import ndarray
from numpy import float64
from multiprocessing.pool import MapResult
from deap.tools.support import Logbook, ParetoFront
from deap.base import Toolbox
from pandas.core.frame import DataFrame
from deap import creator

...

def crossover_worker(sindices: List[creator.Individual, creator.Individual]) -> Tuple[creator.Individual, creator.Individual]:
    """
    Uniform crossover using fixed threshold

    Args:
        sindices: list of two individuals on which we want to perform crossover

    Returns:
        tuple of the two individuals with crossover applied
    """
    ind1, ind2 = sindices
    size = len(ind1)
    for i in range(size):
        if random.random() < 0.4:
            ind1[i], ind2[i] = ind2[i], ind1[i]
    return ind1, ind2


def test(a: DataFrame, b: List[int]) -> float:
    """
    test funcition

    Args:
        a: something
        b: something

    Returns:
        something
    """
    return b

Когда настройки в conf.py такие же, как указано выше, у меня нет ошибок, типы для моей функции test правильные, но типы для моей функции crossover_worker отсутствуют: enter image description here

Однако, когда я устанавливаю set_type_checking_flag= True для принудительного использования всех типов, у меня появляется круговая ошибка импорта:

reading sources... [100%] index
WARNING: autodoc: failed to import module 'algo' from module 'python.algo'; the following exception was raised:
cannot import name 'ArrayLike' from partially initialized module 'pandas._typing' (most likely due to a circular import) (/usr/local/lib/python3.8/site-packages/pandas/_typing.py)
looking for now-outdated files... none found

И Я никогда не импортирую ArrayLike, поэтому я не получаю его оттуда и как это решить? Или как заставить импортировать также типы creator.Individual, которые встречаются повсюду в моем коде?

Мои версии sphinx:

sphinx==3.0.1
sphinx-autodoc-typehints==1.10.3

1 Ответ

0 голосов
/ 24 апреля 2020

После некоторого поиска были некоторые fl aws с моим подходом:

  • Во-первых, список "- это однородная структура, содержащая значения одного типа. Таким образом, только List принимает один тип, и каждый элемент этого списка должен иметь этот тип. " ( источник ) . Следовательно, я не могу сделать что-то вроде List[creator.Individual, creator.Individual], но должен преобразовать его в List[creator.Individual] или, если у вас есть несколько типов в списке, вы должны использовать оператор объединения, такой как List[Union[int,float]]
  • Во-вторых, тип creator.Individual не распознается sphinx как допустимый тип. Вместо этого я должен определить это, используя TypeVar следующим образом:
from typing import TypeVar, List
CreatorIndividual = TypeVar("CreatorIndividual", bound=List[int])

Таким образом, преобразовав мою функцию crossover_worker в это, все это заработало:

def crossover_worker(sindices: List[CreatorIndividual]) -> Tuple[CreatorIndividual, CreatorIndividual]:

Примечание: "Напротив, кортеж является примером типа продукта, типа, состоящего из фиксированного набора типов, значения которого являются коллекцией значений, по одному от каждого типа в типе продукта. Tuple[int,int,int], Tuple[str,int] и Tuple[int,str] - это все отдельные типы, различающиеся как количеством типов в продукте, так и порядком их появления. "( source )

...