readthedocs / sphinx-autoapi

A new approach to API documentation in Sphinx.
https://sphinx-autoapi.readthedocs.io/
MIT License
431 stars 126 forks source link

Error 'TreeRebuilder' object has no attribute 'visit_typealias' #474

Open rlaugier opened 1 month ago

rlaugier commented 1 month ago

Hi, I am trying to use autoapi to document my new package nifits, but it seems to fail spectacularly.

Error message is

Extension error (autoapi.extension):
Handler <function run_autoapi at 0x7f40209360c0> for event 'builder-inited' threw an exception (exception: 'TreeRebuilder' object has no attribute 'visit_typealias')

I have no idea what gives rise to this. I tried many things:

Here is the output I obtained.

$sphinx-build -b html -E ./source _build
Running Sphinx v7.3.7
WARNING: VerifyWarning: Keyword name 'MOD_PHAS_UNITS' is greater than 8 characters or contains characters not allowed by the FITS standard; a HIERARCH card will be created. [astropy.io.fits.card]
WARNING: VerifyWarning: Keyword name 'ARRCOL_UNITS' is greater than 8 characters or contains characters not allowed by the FITS standard; a HIERARCH card will be created. [astropy.io.fits.card]
WARNING: VerifyWarning: Keyword name 'FOV_offset' is greater than 8 characters or contains characters not allowed by the FITS standard; a HIERARCH card will be created. [astropy.io.fits.card]
WARNING: VerifyWarning: Keyword name 'FOV_TELDIAM' is greater than 8 characters or contains characters not allowed by the FITS standard; a HIERARCH card will be created. [astropy.io.fits.card]
WARNING: VerifyWarning: Keyword name 'FOV_TELDIAM_UNIT' is greater than 8 characters or contains characters not allowed by the FITS standard; a HIERARCH card will be created. [astropy.io.fits.card]
WARNING: VerifyWarning: Keyword name 'WL_SHIFT_MODE' is greater than 8 characters or contains characters not allowed by the FITS standard; a HIERARCH card will be created. [astropy.io.fits.card]
/lhome/romain/miniconda3/envs/aiitec2/lib/python3.12/site-packages/sphinxcontrib/applehelp/__init__.py:24: RemovedInSphinx80Warning: The alias 'sphinx.util.SkipProgressMessage' is deprecated, use 'sphinx.util.display.SkipProgressMessage' instead. Check CHANGES for Sphinx API modifications.
  from sphinx.util import SkipProgressMessage, progress_message
/lhome/romain/miniconda3/envs/aiitec2/lib/python3.12/site-packages/sphinxcontrib/applehelp/__init__.py:24: RemovedInSphinx80Warning: The alias 'sphinx.util.progress_message' is deprecated, use 'sphinx.util.display.progress_message' instead. Check CHANGES for Sphinx API modifications.
  from sphinx.util import SkipProgressMessage, progress_message
/lhome/romain/miniconda3/envs/aiitec2/lib/python3.12/site-packages/sphinxcontrib/htmlhelp/__init__.py:26: RemovedInSphinx80Warning: The alias 'sphinx.util.progress_message' is deprecated, use 'sphinx.util.display.progress_message' instead. Check CHANGES for Sphinx API modifications.
  from sphinx.util import progress_message
<unknown>:126: SyntaxWarning: invalid escape sequence '\c'i5/aiitec/nifits/nifits/nifits/io/oifits.py

Extension error (autoapi.extension):
Handler <function run_autoapi at 0x7f40209360c0> for event 'builder-inited' threw an exception (exception: 'TreeRebuilder' object has no attribute 'visit_typealias')

I concluded that autoapi has problems with my source base, but I have no idea of what sort. Could you help me figure it out based on the error I obtain? Thanks in advance.

rlaugier commented 1 month ago

Hi all, I think I have narrowed it down to a bug.

(correction in my next comment: it is actually more subtle)

Basically when giving type hints to a dataclass, autoapi gets thrown off by some types. In my case the type hings: numpy.typing.ArrayLike and numpy.typing.NDArray. These hings are of type typing._UnionGenericAlias and type.GenericAlias respectively autoapi crashes if it finds them in a dataclass (althouogh it is ok with them in regular classes and methods). Example here:

from numpy.typing import ArrayLike, NDArray

@dataclass
class mydata(object):
    """
    This is my data class

    Args:
        anin : One integer for you
        barray : This is now an array
    """
    anin : int = 0
    barray : ArrayLike = None

For now, I will use type numpy.ndarray so that I can get back on line, but I hope this gets solved at some point, because I would like to use those generic types. Thanks in advance. Romain

rlaugier commented 1 month ago

Actually, the problem is more subtle, because this compiles correcly:

import numpy as np
ArrayLike = np.typing.ArrayLike

@dataclass
class mydata(object):
    """
    This is my data class

    Args:
        anin : One integer for you
        barray : This is now an array
    """
    anin: int = 0
    barray: ArrayLike = None

So basically you cannot import just the class from a module, you must reference the type directly through the namespace of its submodule. If you import the type directly, it will not work. (it will crash the autoapi without helpful messages.)

I have also seen this from types of other modules.

Again, I hope this helped, and I hope we can improve this.