astropy / sphinx-automodapi

Sphinx extension for generating API documentation
https://sphinx-automodapi.readthedocs.io
BSD 3-Clause "New" or "Revised" License
63 stars 45 forks source link

Disable inclusion of imported functions and classes #95

Closed seanjkanderson closed 4 years ago

seanjkanderson commented 4 years ago

I'm guessing that I'm missing something more fundamental than just an option in the toctree, but I'm wondering how I exclude imported functions (hopefully I don't need to specify all imports with skip) being documented in a module. I believe this is similar to this issue https://github.com/sphinx-doc/sphinx/issues/1061 on the main sphinx-doc repo.

I'm new to doc generation in general, so I may be coming at this the wrong way. Any tips appreciated!

barry-gallagher commented 4 years ago

I'm having the same issue.

barry-gallagher commented 4 years ago

I just changed Automodsumm.run( ) in automodsumm.py to remove the imported names. I abused a skip-member call (which autodoc supports) which I could then check and see if the modname (current module being parsed) matches fqnm (fully qualified name). Once that worked by adding a handler in conf.py, I decided to just do to everything in the automodsumm.py by adding to the content creation loops so I wouldn't have to have the handler in conf.py -- since I don't see me wanting to ever document imported names. No promises on stability, but it's working for me so far.

This plus handler code

            skipnames = []
            for localnm, fqnm, obj in zip(localnames, fqns, objs):
                # print("checkign ion", localnm)
                keep = True
                skip_user = self.env.app.emit_firstresult('autodoc-skip-member', [obj, modname], localnm, fqnm, False, {"meth":"run", "funcs":funconly, "cls":clsonly, "vars":varonly})
                if skip_user is not None:
                    if skip_user:
                        skipnames.append(localnm)

            if 'skip' in self.options:
                option_skipnames = set(self.options['skip'])
                for lnm in localnames:
                    if lnm in option_skipnames:
                        option_skipnames.remove(lnm)
                        skipnames.append(lnm)
                if len(option_skipnames) > 0:
                    self.warn('Tried to skip objects {objs} in module {mod}, '
                              'but they were not present.  Ignoring.'
                              .format(objs=option_skipnames, mod=modname))

or

            if funconly:
                cont = []
                for nm, fqnm, obj in zip(localnames, fqns, objs):
                    if nm not in skipnames and inspect.isroutine(obj):
                        if modname not in fqnm:
                            continue
                        cont.append(nm)
            elif clsonly:
                cont = []
                for nm, fqnm, obj in zip(localnames, fqns, objs):
                    if nm not in skipnames and inspect.isclass(obj):
                        if modname not in fqnm:
                            continue
                        cont.append(nm)
            elif varonly:
                cont = []
                for nm, fqnm, obj in zip(localnames, fqns, objs):
                    if nm not in skipnames and not (inspect.isclass(obj) or
                                                    inspect.isroutine(obj)):
                        if modname not in fqnm:
                            continue
                        cont.append(nm)
            else:
                cont = [nm for nm in localnames if nm not in skipnames]
jonathansick commented 4 years ago

The way that I deal with this is by adding an __all__ to my modules. This is a Pythonic way of declaring what classes, functions, and variables your modules are exporting. See https://docs.python.org/3/tutorial/modules.html#importing-from-a-package

bsipocz commented 4 years ago

I'm closing this, as @jonathansick's answer should address this issue. Feel free to reopen if you run into any issues with that approach.