Skip to content

Conversation

@kbarbary
Copy link
Member

Motivation

I've run into the problem recently that I point a user to an API documentation page, say
http://astropy.readthedocs.org/en/stable/api/astropy.stats.funcs.sigma_clip.html
to pick a random example, and the user sees the path to the function as being astropy.stats.funcs.sigma_clip rather than astropy.stats.sigma_clip. As a result, it is not entirely clear what is the correct way to import the function or class. This problem exists throughout the documentation: in most cases we import module objects into a higher-level namespace and intend for users to only use the higher-level namespace.

What it does

This PR changes the automodsumm sphinx extension so that built stub pages have the API that users should use. It does this by using the .. currentmodule:: directive and then supplying the .. autosummary:: directive with the local, rather than fully qualified object names. A built set of docs can be found here. See for instance http://www.hep.anl.gov/kbarbary/astropy-docs/api/astropy.stats.sigma_clip.html

Related changes

In conjunction, there are a few other necessary changes:

  • Include a patched version of the viewcode extension, as the current version in sphinx fails to link to code correctly under this usage of autosummary. The patch comes from this issue in the sphinx issue tracker: https://bitbucket.org/birkenfeld/sphinx/issue/623/ so hopefully it will be merged into Sphinx proper, at which point this patched version can be removed from astropy.

  • I had to change an automodsumm table in the convolution/kernels.rst documentation to an explicit autosummary table. It should be possible to simply do

    .. automodsumm:: astropy.convolution
       :classes-only:

    there, but that wasn't working and I couldn't figure out why not. Help making that work would be appreciated.

  • Third, I noticed I missing __all__ in convolution/core.py. The omission has been resulting in AstropyUserWarning being included in the API docs for convolution, which was not intended.

Remaining issues

There are some remaining issues before this PR is merged:

  • Class attribute stubs are no longer linked to their source code, but I don't think this is a big loss. This is probably part of the viewcode bug that isn't fixed by the patch.
  • The base classes in class docs are no longer linked correctly. I looked at the numpy/scipy docs to see their solution to this problem. It seems to be simply omitting the line telling you the base classes. I think thats probably OK to do as this info can be found easily by clicking to the source code. However, this hasn't been done yet.
  • There are some scattered object references in the docs that will need to be fixed. I can do that if we want to move forward with this PR.
  • We probably want to update the part of automodapi that creates inheritance diagrams as well.
  • Sticking a bunch of .. currentmodule:: directives in the docs (which is what this does) may have unintended consequences, particularly if the directive is already used somewhere on the page and an .. automodsumm:: or
    .. automodapi:: directive is given mid-page. Fortunately the later is typically used at the bottom of the page, so this might not be a big issue.

@eteq
Copy link
Member

eteq commented Nov 25, 2013

Thanks for doing this @kbarbary - I'd been hoping someone would take a crack at this! I'm definitely 👍 for this.

For a few more specific items:

  • Is :classes-only: not working at all, or just for astropy.convolution?
  • Did you see Change models to one doc section #1801 ? In theory that shouldn't intersect with this, but it included some subtle changes that might, particularly for the :classes-only: bit.
  • Why do you say there might be a problem with using .. currentmodule::? I was under the impression that can be done multiple times and it just affects what comes next, but I may be misunderstanding.

@kbarbary
Copy link
Member Author

@eteq

  • I doubt that it is specific to astropy.convolution, and it may not be due to using :classes-only: either, but let me do a test and get back to you on that.
  • Ah I hadn't seen Change models to one doc section #1801. Our changes to automodsumm don't seem to intersect, but I'll have to rebase this once that's merged in.
  • You're right that .. currentmodule:: can be used multiple times. The problem scenario I'm envisioning is where the author of the rst file uses currentmodule directly (say, at the top), writes the docs assuming that context, and uses automodsumm in the middle, like this:
.. currentmodule:: foo

(content)            # current module is foo

.. automodsumm:: bar

(content)           # current module has been changed to bar, unbeknownst to author.
                    # Broken links ensue.

@kbarbary
Copy link
Member Author

kbarbary commented Dec 1, 2013

@eteq More specifics on the automodsumm failure I'm seeing:

This works:

.. currentmodule:: astropy.convolution

.. autosummary::
   AiryDisk2DKernel
   Box2DKernel
   [etc]

But this does not:

.. automodsumm:: astropy.convolution
   :classes-only:

This is surprising to me because I thought that the latter is basically turned into the former during processing. When doing the latter, I get warnings like

[...]/astropy/docs/convolution/kernels.rst:191: WARNING: failed to import AiryDisk2DKernel

(and similar for other classes)

@eteq
Copy link
Member

eteq commented Jan 17, 2014

@kbarbary - sorry I lost track of this, but I've done some investigation. I'm still puzzled, but I have some things for you to try. At one point I was seeing the same error as you, but it has since disappeared and I can no longer reproduce it on master. So perhaps try on master? Or Sphinx 1.2 (recently released), if you were using 1.1.3 before?

Another thing that may be important: to get the behavior you want, you need a :toctree: directive in automodsumm. That tells sphinx that it should actually generate the api pages for everything instead of just the table of classes.

Also, I think you still want .. currentmodule:: astropy.convolution in there, even with automodsumm - the latter is only a replacement for autosummary, and doesn't set the current module (that's so that automodapi can document it just once at the top and let autosummary deal with subsets of tables).

So the following worked for me (and gave the same output I expected from autosummary:

.. currentmodule:: astropy.convolution

.. automodsumm:: astropy.convolution
    :classes-only:
    :toctree: ../api/


Does that work for you?

@eteq
Copy link
Member

eteq commented Jan 17, 2014

Oh, and I think that answers your concern above - automodsumm doesn't actually set the module (or, at least, it isn't supposed to).

Also, @kbarbary, you might want to check out #1975 to make debugging easier - that adds an option to let you see what automodapi generates.

@astrofrog
Copy link
Member

@kbarbary - what is the status of this? It'd be great to have this working for astropy.vo.samp, so I'm eager to see it merged in :)

@kbarbary
Copy link
Member Author

@astrofrog Taking a look now. Sorry I've been putting this off...

@kbarbary
Copy link
Member Author

@eteq Still looking at this, but curious about your comment:

Also, I think you still want .. currentmodule:: astropy.convolution in there,
even with automodsumm - the latter is only a replacement for autosummary,
and doesn't set the current module (that's so that automodapi can document it
just once at the top and let autosummary deal with subsets of tables).

I guess it isn't obvious, but this PR changes automodsumm so that it sets the current module before inserting the call to .. autosummary. (That's what I think I remember doing anyway!)

@kbarbary
Copy link
Member Author

@eteq, this does indeed work for me (now on Sphinx 1.2, rebased on astropy master):

.. currentmodule:: astropy.convolution

.. automodsumm:: astropy.convolution
    :classes-only:

(toctree directive not needed).

However, this is confusing. As I noted, I put .. currentmodule:: [modname] into automodsumm in this PR (see L278 of automodsumm.py) so I would expect this extra currentmodule call to do nothing (automodsumm should expand to a currentmodule call followed by an autosummary call). So it seems like the currentmodule call generated in automodsumm is being ignored. Any ideas?

It might be good to have something like #1975 for automodsumm.

@eteq
Copy link
Member

eteq commented Jan 30, 2014

I just added #2022, which does just as you suggest here, @kbarbary - it adds a automodsumm_writereprocessed sphinx configuration option. If that's true, automodsumm writes out whatever it replaces automodsumm directives with (before passing on to autosummary). That reveals that you are indeed getting .. currentmodule:: [modname] in there, so the behavior here is quite odd. Will experiment a bit more and see if I can figure out the deal.

@eteq
Copy link
Member

eteq commented Jan 30, 2014

@kbarbary - One thing I've figured out: at least for me, :toctree: ../api/ is necessary, but there's a confounding factor: If you run it with automodapi and then don't completely delete the doc _build directory (by doing e.g., python setup.py build_sphinx -l), then it will work even when toctree is absent. This is because the files autosummary generates when toctree is provided are seen by sphinx the second time through, even if they were only generated on the first run and not the second. So if you do python setup.py build_sphinx -l, do you find that you do in fact need toctree?

(still investigating why currentmodule is needed, though)

@eteq
Copy link
Member

eteq commented Jan 31, 2014

Ok, I'm still mystified as to why this happens. For some reason, Sphinx just refuses to acknowledge the currentmodule if you insert it in the extension, but it does see it if its in the original source. That shouldn't be the case, but for some reason it is.

I managed to hack together a work-around, though. See the PR kbarbary#3 I just issued against this branch. That actually forces sphinx's internal environment to do the same thing it does when currentmodule is run, but it does it directly in Automodsumm.run, so its always guaranteed to happen in automodsumm, now. Of course, this is flagrantly messing with sphinx's internal state, so who knows how reliable it will be... but it does seem to work. If you combine that with including the toctree directive, I get the output you want, now.

kbarbary and others added 5 commits February 17, 2014 13:16
Make it so that the stub pages generated with automodapi have the paths
to the function or class that a user should use. For example, the Table
class now appears as astropy.table.Table rather than
astropy.table.table.Table.
This is necessary under the revised automodsumm to correctly link
to already-created stub pages. It should be possible to use automodsumm with
the `:classes-only:` option, but that doesn't seem to be working.
Using local names in autosummary fails to link to raw code with the
current released version of the viewcode sphinx extension (Sphinx v1.1.3).
This patched version fixes the problem. It can be removed once the problem
is fixed in Sphinx proper (there is an issue open).
@kbarbary
Copy link
Member Author

Rebased and included @eteq's hack-fix. I've kinda gotten lost as to what the status of this is. I built the docs and they look fine, with the exception that stuff like ~astropy.cosmology.core.FlatLambdaCDM in the prose needs to be changed to ~astropy.cosmology.FlatLambdaCDM in order for it to link to the stub pages correctly.

@cdeil
Copy link
Member

cdeil commented Feb 20, 2014

@kbarbary Thanks for implementing this ... I think it's really important that the API docs show the locations that users are supposed to use for imports.

@astrofrog @eteq What remains to be done / checked before this can be merged?

(I just went through gammapy fixing all sphinx links and am willing to help fix all the links in astropy and affiliated packages, but this PR should be merged first.)

@eteq
Copy link
Member

eteq commented Feb 27, 2014

@cdeil @kbarbary - I finally managed to go through and do some spot-checks, and as far as I can tell, this is now good to go. I'll go ahead and just merge it manually because there's a minor conflict that isn't worth rebasing.

Thanks again for all your work on this @kbarbary, and @cdeil, feel free to start digging through the huge pile of nitpicky changes needed...

eteq added a commit that referenced this pull request Feb 27, 2014
Only required merging two changes to extensions in conf.py

Conflicts:
	astropy/sphinx/conf.py
@eteq eteq merged commit 584d8d1 into astropy:master Feb 27, 2014
@astrofrog
Copy link
Member

I guess that this will warrant a what's new entry because it might break a lot of API URLs. I don't think we need to be backward-compatible, but /stable/ URLs are going to change for the API docs, which is worth mentioning.

eteq added a commit that referenced this pull request Feb 27, 2014
@eteq eteq added this to the v0.4.0 milestone Feb 27, 2014
@eteq
Copy link
Member

eteq commented Feb 27, 2014

Ah, good point @astrofrog - I updated the changelog but not what's new. Will add that now directly in master.

@astrofrog astrofrog mentioned this pull request Feb 27, 2014
28 tasks
@astrofrog
Copy link
Member

@kbarbary @eteq @cdeil - if any of you want to fix some of the existing links, please say on #1221 which sub-package you are working on to avoid overlap with others.

@eteq
Copy link
Member

eteq commented Feb 27, 2014

Actually, I'm doing the what's new thing in #2147 because I just realized it requires making a new file.

@cdeil
Copy link
Member

cdeil commented Feb 27, 2014

I think there's still a problem for (at least some) sub-packages that have an extra layer in the hierarchy.
E.g. astropy.modeling.functional_models.Gaussian1D
should show up at astropy.modeling.models.Gaussian1D and I think e.g. astropy.io.votable.tree.VOTableFile should show up at astropy.io.votable.VOTableFile.

What needs to be done to changed so that these things show up at the location where users are supposed to import from?
Should I open a new issue?

@cdeil
Copy link
Member

cdeil commented Feb 27, 2014

Let's try and figure the issue I just mentioned in a new issue: #2148

mdmueller pushed a commit to mdmueller/astropy that referenced this pull request Apr 2, 2014
ktchrn pushed a commit to ktchrn/astropy that referenced this pull request Oct 28, 2014
astrofrog pushed a commit to astropy/sphinx-automodapi that referenced this pull request Jan 27, 2018
…dsumm-paths

Only required merging two changes to extensions in conf.py

Conflicts:
	astropy/sphinx/conf.py
astrofrog pushed a commit to astropy/sphinx-astropy that referenced this pull request Jan 29, 2018
…dsumm-paths

Only required merging two changes to extensions in conf.py

Conflicts:
	astropy/sphinx/conf.py
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants