python-3.xtypespython-sphinxautodocdeap

Sphinx autodoc does not display all types or circular import error


I am trying to auto document types with sphinx autodoc, napoleon and autodoc_typehints but I am having problems as it does not work with most of my types. I am using the deap package to do some genetic optimization algorithm, which makes that I have some very specific types I guess sphinx cannot handle.

My conf.py file looks like this:

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

I have an Algo.rst file with:

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

and my python.algo.algo module looks like this (I've added a dummy test function to show it works whenever I have no special types specified):

# 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

When settings in conf.py are like above I have no error, types for my test function are correct, but types for my crossover_worker function are missing: enter image description here

However, when I set the set_type_checking_flag= True to force using all types, I have a circular import error:

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

And I never import ArrayLike so I don't get it from where it comes or how to solve it? Or how to force to import also the creator.Individual types that appear everywhere in my code?

My sphinx versions:

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

Solution

  • After some searching there were some flaws with my approach:

    from typing import TypeVar, List
    CreatorIndividual = TypeVar("CreatorIndividual", bound=List[int])
    

    So by transforming my crossover_worker function to this, it all worked:

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

    Note: "By contrast, a tuple is an example of a product type, a type consisting of a fixed set of types, and whose values are a collection of values, one from each type in the product type. Tuple[int,int,int], Tuple[str,int] and Tuple[int,str] are all distinct types, distinguished both by the number of types in the product and the order in which they appear."(source)