Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sphinx 4.x + :any: + autodoc + aliasing objects = warning #10088

Closed
ewjoachim opened this issue Jan 11, 2022 · 3 comments · Fixed by #10089
Closed

Sphinx 4.x + :any: + autodoc + aliasing objects = warning #10088

ewjoachim opened this issue Jan 11, 2022 · 3 comments · Fixed by #10089
Labels

Comments

@ewjoachim
Copy link
Contributor

ewjoachim commented Jan 11, 2022

Describe the bug

Let's say you have a module:

# mypackage/module.py
class A:
    pass

And expose it in your __init__.py:

from .module import A
__all__ = ["A"]

In your doc, you want to expose the "official" api:

.. autoclass:: mypackage.A

And reference it:

Use the :any:`A` class

Alternatively, in conf.py use default_role = "any" and in your doc:

Use the `A` class

Then autodoc will output an warning:

more than one target found for 'any' cross-reference 'A': could be :py:class:`mypackage.A` or :py:class:`myackage.module.A`

And if building with -W, this warning will be an error.
I believe there's no way to avoid this warning without abandoning :any: altogether.

How to Reproduce

$ git clone git@github.com:ewjoachim/sphinx-bug-any-canonical.git
$ cd sphinx-bug-any-canonical
$ pip install -r requirements.txt
$ cd docs
$ make SPHINX_OPTS=-W html
<build fails>

Expected behavior

There used to be a way for me to simultaneously:

  • Use :any:
  • Define the API of my project in __init__.py while having the real classes live elsewhere
  • use autodoc
  • build with -W

without the combination of those things failing the build. I can probably rewrite a lot of documentation to use explicit py:obj: classes instead of any but it would be a lot of work, and I'm not sure it would make my doc more readable.

Your project

https://github.com/ewjoachim/sphinx-bug-any-canonical

Screenshots

No response

OS

Linux

Python version

3.8, 3.9, 3.10

Sphinx version

latest stable: 4.3.2

Sphinx extensions

sphinx.ext.autodoc

Extra tools

No response

Additional context

I believe what happens is that:

  • sphinx/ext/autodoc/__init__.py ClassDocumenter.add_directive_header we have
        canonical_fullname = self.get_canonical_fullname()
        if not self.doc_as_attr and canonical_fullname and self.fullname != canonical_fullname:
            self.add_line('   :canonical: %s' % canonical_fullname, sourcename)

This means that the py:class directive that will be generated by autodoc will have a :canonical: option

  • sphinx/domains/python.py PyObject.add_target_and_index
        canonical_name = self.options.get('canonical')
        if canonical_name:
            domain.note_object(canonical_name, self.objtype, node_id, aliased=True,
                               location=signode)

If an object has a canonical option, both names will be added to the known objects.

This means that :any:`Class` will always end up confused, and issue a warning.

I don't know how I can solve this.

@ewjoachim ewjoachim changed the title Sphinx 4.x + :any: + autodoc + friendly API Sphinx 4.x + :any: + autodoc + aliasing objects Jan 11, 2022
@ewjoachim ewjoachim changed the title Sphinx 4.x + :any: + autodoc + aliasing objects Sphinx 4.x + :any: + autodoc + aliasing objects = warning Jan 11, 2022
@ewjoachim
Copy link
Contributor Author

This might actually be a duplicate of #9577

@ewjoachim
Copy link
Contributor Author

I believe I have a fix, working to make a proper PR (writing a test)

@ewjoachim
Copy link
Contributor Author

Ok, closing as duplicate of #9577

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant