readthedocs / sphinx-autoapi

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

AutoAPI identifies imported class as an ambiguous cross-reference target in v3.1.0 and v3.1.1 #452

Closed zaneselvans closed 1 week ago

zaneselvans commented 2 weeks ago

Since AutoAPI 3.1.0 I have started getting a warning about multiple targets for a cross-reference, in which one is the definition of a class, and the other is that class being imported in another module. E.g. in this CI run.

Warning, treated as error:
/home/runner/work/ferc-xbrl-extractor/ferc-xbrl-extractor/docs/autoapi/ferc_xbrl_extractor/xbrl/index.rst:183:more than one target found for cross-reference 'LinkRole': ferc_xbrl_extractor.datapackage.LinkRole, ferc_xbrl_extractor.taxonomy.LinkRole

See this comment

Forcing the environment to use sphinx-autoapi>=3,<3.1 avoids the problem, but it seems like it shouldn't be an issue in either version.

mfncooper commented 2 weeks ago

I just ran across this same issue when my builds started failing on readthedocs.io. I've pinned the sphinx-autoapi version for now, as mentioned by @zaneselvans, but it would be nice to not have to do that.

If a test case is needed, my project is here: https://github.com/mfncooper/pyham_pe (but to reproduce the error, remember to unpin sphinx-autoapi in requirements-docs.txt before building the docs).

AWhetter commented 1 week ago

As documented here (https://sphinx-autoapi.readthedocs.io/en/latest/how_to.html#how-to-customise-what-gets-documented), this is the correct behaviour:

AutoAPI will document everything that is publicly accessible through the actual package when loaded in Python. For example if a function is imported from a submodule into a package then that function is documented in both the submodule and the package.

That section describes how to control what's documented. Or you could change the xref to use the full path to the class.

mfncooper commented 1 week ago

My situation is the opposite of what you're pointing out, though. I have module A that defines class C. Then I have submodule B that imports class C. Why would it be "correct" for the importing module - module B - to document the class it's importing from module A?

Specifically, my top level module defines the class ReceiveHandler: https://github.com/mfncooper/pyham_pe/blob/main/pe/__init__.py#L48

and a submodule imports that class: https://github.com/mfncooper/pyham_pe/blob/main/pe/handler.py#L17

so that it can use it as a base class: https://github.com/mfncooper/pyham_pe/blob/main/pe/handler.py#L23

It makes no sense for the documentation for the handler submodule to duplicate the documentation for the ReceiveHandler class that's defined in the parent module.

AWhetter commented 1 week ago

I didn't realise that was the situation. You're right that a module that's importing from another module shouldn't be documenting the class, so this sounds like a regression.

mfncooper commented 1 week ago

Thanks for taking another look. In case it's helpful, the log for the failed build on readthedocs.io is here.